

MariaDB Server Documentation
=============================

   Documentation on using MariaDB Server.

 
A PDF version of the documentation is available for download at <https://mariadb.org/download/>.

   

| Title | Description |
| --- | --- |

 ###   [Using MariaDB Server](using-mariadb-server/index)

 

| Title | Description |
| --- | --- |
|  [SQL Statements & Structure](sql-statements-structure/index) |  SQL statements, structure, and rules.  |
|  [Built-in Functions](built-in-functions/index) |  Functions and procedures in MariaDB.  |
|  [Clients & Utilities](clients-utilities/index) |  Client and utility programs for MariaDB.  |

 ###   [MariaDB Administration](mariadb-administration/index)

 

| Title | Description |
| --- | --- |
|  [Getting, Installing, and Upgrading MariaDB](getting-installing-and-upgrading-mariadb/index) |  Getting, installing, and upgrading MariaDB Server and related software.  |
|  [User & Server Security](user-server-security/index) |  Creating users, granting privileges, and encryption.  |
|  [Backing Up and Restoring Databases](backing-up-and-restoring-databases/index) |  Tools and methods for backing up and restoring databases.  |
|  [Server Monitoring & Logs](server-monitoring-logs/index) |  Monitoring MariaDB Server and enabling and using logs.  |
|  [Partitioning Tables](partitioning-tables/index) |  Splitting huge tables into multiple table files.  |
|  [MariaDB Audit Plugin](mariadb-audit-plugin/index) |  Logging user activity with the MariaDB Audit Plugin.  |
|  [Variables and Modes](variables-and-modes/index) |  Server variables and SQL modes.  |
|  [Copying Tables Between Different MariaDB Databases and MariaDB Servers](copying-tables-between-different-mariadb-databases-and-mariadb-servers/index) |  Copy table files.  |

 ###   [High Availability & Performance Tuning](replication-cluster-multi-master/index)

 

| Title | Description |
| --- | --- |
|  [MariaDB Replication](standard-replication/index) |  Documentation on standard primary and replica replication.  |
|  [MariaDB Galera Cluster](galera-cluster/index) |  MariaDB Galera Cluster is a virtually synchronous multi-master cluster.  |
|  [Optimization and Tuning](optimization-and-tuning/index) |  Using indexes, writing better queries and adjusting variables for better performance.  |
|  [Multi Master in maria db](multi-master-in-maria-db/index) |  Can we configure Multi Master in Maria Db. I have testing three node A, B, ...  |
|  [Multi master replication and deadlock detection in Galera with Mariadbs](multi-master-replication-and-deadlock-detection-in-galera-with-mariadbs/index) |  Hi, We have multi master Galera replication setup where three master maria...  |

 ###   [Columns, Storage Engines, and Plugins](columns-storage-engines-and-plugins/index)

 

| Title | Description |
| --- | --- |
|  [Data Types](data-types/index) |  Data types for columns in MariaDB tables.  |
|  [Character Sets and Collations](character-sets/index) |  Setting character set and collation for a language.  |
|  [Storage Engines](storage-engines/index) |  Various storage engines available for MariaDB.  |
|  [Plugins](plugins/index) |  Documentation on MariaDB Server plugins.  |

 ###   [Programming & Customizing MariaDB](programming-customizing-mariadb/index)

 

| Title | Description |
| --- | --- |
|  [Programmatic & Compound Statements](programmatic-compound-statements/index) |  Compound SQL statements for stored routines and in general.  |
|  [Stored Routines](stored-routines/index) |  Stored procedures and functions.  |
|  [Triggers & Events](triggers-events/index) |  Creating triggers and scheduled events within MariaDB.  |
|  [Views](views/index) |  Stored queries for generating a virtual table.  |
|  [User-Defined Functions](user-defined-functions/index) |  Extending MariaDB with custom functions.  |
|  [assertion](assertion/index) |  how to create assertion in mariadb?  |

 ### Other MariaDB Server Documentation Articles

 

| Title | Description |
| --- | --- |
|  [MariaDB Platform X3](mariadb-platform-x3/index) |  MariaDB Platform X3 integrates MariaDB Server, MariaDB ColumnStore, and Mar...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/documentation/>

Partitioning Tables
====================

   A huge table can be split into smaller subsets. Both data and indexes are partitioned.

  

| Title | Description |
| --- | --- |
|  [Partitioning Overview](../partitioning-overview/index) |  A table partitioning overview  |
|  [Partitioning Types](../partitioning-types/index) |  A partitioning type determines how a table rows are distributed across partitions.  |
|  [Partition Pruning and Selection](../partition-pruning-and-selection/index) |  Partition pruning is when the optimizer knows which partitions are relevant for the query.  |
|  [Partition Maintenance](../partition-maintenance/index) |  For time series (includes list of PARTITION uses)  |
|  [Partitioning Limitations](../partitioning-limitations/index) |  Limitations applying to partitioning in MariaDB.  |
|  [Partitions Files](../partitions-files/index) |  A partitioned table is stored in multiple files  |
|  [Partitions Metadata](../partitions-metadata/index) |  How to obtain information about partitions definition  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitioning-tables/>

Using MariaDB Server
=====================

   Documentation on using MariaDB Server.

  

| Title | Description |
| --- | --- |
|  [SQL Statements & Structure](../sql-statements-structure/index) |  SQL statements, structure, and rules.  |
|  [Built-in Functions](../built-in-functions/index) |  Functions and procedures in MariaDB.  |
|  [Clients & Utilities](../clients-utilities/index) |  Client and utility programs for MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-server/>

Getting, Installing, and Upgrading MariaDB
===========================================

  

| Title | Description |
| --- | --- |
|  [Where to Download MariaDB](../where-to-download-mariadb/index) |  Downloading tarballs, binaries, packages, and the source code for MariaDB.  |
|  [MariaDB Binary Packages](../binary-packages/index) |  Instructions on installing MariaDB binaries and packages.  |
|  [Upgrading MariaDB](../upgrading/index) |  Upgrading from an earlier version, or from MySQL  |
|  [Downgrading between Major Versions of MariaDB](../downgrading-between-major-versions-of-mariadb/index) |  Downgrading MariaDB is not officially supported between major versions.  |
|  [Compiling MariaDB From Source](../compiling-mariadb-from-source/index) |  Articles on compiling MariaDB from source  |
|  [Starting and Stopping MariaDB](../starting-and-stopping-mariadb/index) |  Articles related to starting and stopping MariaDB Server.  |
|  [MariaDB Performance & Advanced Configurations](../mariadb-performance-advanced-configurations/index) |  Articles of how to setup your MariaDB optimally on different systems  |
|  [Troubleshooting Installation Issues](../troubleshooting-installation-issues/index) |  Articles relating to installation issues users might run into  |
|  [Installing System Tables (mariadb-install-db)](../installing-system-tables-mariadb-install-db/index) |  Using mariadb-install-db to create the system tables in the 'mysql' database directory.  |
|  [mysql\_install\_db.exe](../mysql_install_dbexe/index) |  Windows equivalent of mysql\_install\_db for creating the system tables etc.  |
|  [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index) |  Configuring MariaDB with my.cnf and other option files.  |
|  [MariaDB Environment Variables](../mariadb-environment-variables/index) |  List of environment variables used by MariaDB.  |
|  [Puppet and MariaDB](../puppet-and-mariadb/index) |  Puppet modules that allow you to use MariaDB.  |
|  [MariaDB on Amazon RDS](../mariadb-on-amazon-rds/index) |  Getting started with MariaDB on Amazon RDS  |
|  [Obsolete Installation Information](../obsolete-installation-information/index) |  Installation-related items that are obsolete  |
|  [Migrating to MariaDB](../migrating-to-mariadb/index) |  Migrating to MariaDB from another DBMS.  |
|  [Installing MariaDB on IBM Cloud](../installing-mariadb-on-ibm-cloud/index) |  Get MariaDB on IBM Cloud You should have an IBM Cloud account, otherwise ...  |
|  [mysqld Configuration Files and Groups](../mysqld-configuration-files-and-groups/index) |  Which configuration files and groups mysqld reads.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/getting-installing-and-upgrading-mariadb/>

Variables and Modes
====================

   The different variables and modes to use to affect how MariaDB works.

  

| Title | Description |
| --- | --- |
|  [Full List of MariaDB Options, System and Status Variables](../full-list-of-mariadb-options-system-and-status-variables/index) |  Complete alphabetical list of all MariaDB options as well as system and status variables.  |
|  [Server Status Variables](../server-status-variables/index) |  List and description of the Server Status Variables.  |
|  [Server System Variables](../server-system-variables/index) |  List of system variables.  |
|  [OLD\_MODE](../old-mode/index) |  Used to emulate behavior from older MariaDB and MySQL versions.  |
|  [SQL\_MODE](../sql-mode/index) |  Used to emulate behavior from other SQL servers.  |
|  [SQL\_MODE=MSSQL](../sql_modemssql/index) |  Microsoft SQL Server compatibility mode.  |
|  [SQL\_MODE=ORACLE](../sql_modeoracle/index) |  MariaDB understands a subset of Oracle's PL/SQL language.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/variables-and-modes/>

High Availability & Performance Tuning
=======================================

   Information on replication, clustering, and multi-master solutions for MariaDB, as well as performance tuning.

  

| Title | Description |
| --- | --- |
|  [MariaDB Replication](../standard-replication/index) |  Documentation on standard primary and replica replication.  |
|  [MariaDB Galera Cluster](../galera-cluster/index) |  MariaDB Galera Cluster is a virtually synchronous multi-master cluster.  |
|  [Optimization and Tuning](../optimization-and-tuning/index) |  Using indexes, writing better queries and adjusting variables for better performance.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-cluster-multi-master/>

User & Server Security
=======================

  

| Title | Description |
| --- | --- |
|  [Securing MariaDB](../securing-mariadb/index) |  Securing your MariaDB installation  |
|  [User Account Management](../user-account-management/index) |  Administering user accounts in MariaDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-server-security/>

MariaDB Administration
=======================

   There are many tasks that database administrators (DBAs) have to perform. This section of the MariaDB Documentation provides information on how to do these tasks.

  

| Title | Description |
| --- | --- |
|  [Getting, Installing, and Upgrading MariaDB](../getting-installing-and-upgrading-mariadb/index) |  Getting, installing, and upgrading MariaDB Server and related software.  |
|  [User & Server Security](../user-server-security/index) |  Creating users, granting privileges, and encryption.  |
|  [Backing Up and Restoring Databases](../backing-up-and-restoring-databases/index) |  Tools and methods for backing up and restoring databases.  |
|  [Server Monitoring & Logs](../server-monitoring-logs/index) |  Monitoring MariaDB Server and enabling and using logs.  |
|  [Partitioning Tables](../partitioning-tables/index) |  Splitting huge tables into multiple table files.  |
|  [MariaDB Audit Plugin](../mariadb-audit-plugin/index) |  Logging user activity with the MariaDB Audit Plugin.  |
|  [Variables and Modes](../variables-and-modes/index) |  Server variables and SQL modes.  |
|  [Copying Tables Between Different MariaDB Databases and MariaDB Servers](../copying-tables-between-different-mariadb-databases-and-mariadb-servers/index) |  Copy table files.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-administration/>

Built-in Functions
===================

   Functions and procedures in MariaDB

  

| Title | Description |
| --- | --- |
|  [Function and Operator Reference](../function-and-operator-reference/index) |  A complete list of MariaDB functions and operators in alphabetical order.  |
|  [String Functions](../string-functions/index) |  Built-In functions for the handling of strings and columns containing string values.  |
|  [Date & Time Functions](../date-time-functions/index) |  Built-In functions for the handling of dates and times.  |
|  [Aggregate Functions](../aggregate-functions/index) |  Aggregate functions used with GROUP BY clauses.  |
|  [Numeric Functions](../numeric-functions/index) |  Numeric and arithmetic related functions in MariaDB.  |
|  [Control Flow Functions](../control-flow-functions/index) |  Built-In functions for assessing data to determine what results to return.  |
|  [Pseudo Columns](../pseudo-columns/index) |  MariaDB has pseudo columns that can be used for different purposes.  |

 ###   [Secondary Functions](../secondary-functions/index)

 

| Title | Description |
| --- | --- |
|  [Bit Functions and Operators](../bit-functions-and-operators/index) |  Operators for comparison and setting of values, and related functions.  |
|  [Encryption, Hashing and Compression Functions](../encryption-hashing-and-compression-functions/index) |  Functions used for encryption, hashing and compression.  |
|  [Information Functions](../information-functions/index) |  Functions which return information on the server, the user, or a given query.  |
|  [Miscellaneous Functions](../miscellaneous-functions/index) |  Functions for very singular and specific needs.  |

 ###   [Special Functions](../special-functions/index)

 

| Title | Description |
| --- | --- |
|  [Dynamic Columns Functions](../dynamic-columns-functions/index) |  Functions for storing key/value pairs of data within a column.  |
|  [Galera Functions](../galera-functions/index) |  Built-in functions related to Galera.  |
|  [Geographic Functions](../geographic-functions/index) |  Geographic, as well as geometric functions.  |
|  [JSON Functions](../json-functions/index) |  Built-in functions related to JSON.  |
|  [SEQUENCE Functions](../sequence-functions/index) |  Functions that can be used on SEQUENCEs.  |
|  [Spider Functions](../spider-functions/index) |  User-defined functions available with the Spider storage engine.  |
|  [Window Functions](../window-functions/index) |  Window functions for performing calculations on a set of rows related to the current row.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/built-in-functions/>

MariaDB Replication
====================

   
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 Replication is a feature allowing the contents of one or more primary servers to be mirrored on one or more replica servers.

  

| Title | Description |
| --- | --- |
|  [Replication Overview](../replication-overview/index) |  Allow the contents of one or more primary servers to be mirrored on one or more replicas.  |
|  [Replication Commands](../replication-commands/index) |  List of replication-related commands.  |
|  [Setting Up Replication](../setting-up-replication/index) |  Getting replication working involves steps on both the primary server/s and the replica server/s.  |
|  [Setting up a Replica with Mariabackup](../setting-up-a-replica-with-mariabackup/index) |  Setting up a replica with Mariabackup.  |
|  [Read-Only Replicas](../read-only-replicas/index) |  Making replicas read-only.  |
|  [Replication as a Backup Solution](../replication-as-a-backup-solution/index) |  Replication can be used to support the backup strategy.  |
|  [Multi-Source Replication](../multi-source-replication/index) |  Using replication with many masters.  |
|  [Replication Threads](../replication-threads/index) |  Types of threads that are used to enable replication.  |
|  [Global Transaction ID](../gtid/index) |  Improved replication using global transaction IDs.  |
|  [Parallel Replication](../parallel-replication/index) |  Executing queries replicated from the primary in parallel on the replica.  |
|  [Replication and Binary Log System Variables](../replication-and-binary-log-system-variables/index) |  Replication and binary log system variables.  |
|  [Replication and Binary Log Status Variables](../replication-and-binary-log-status-variables/index) |  Replication and binary log status variables.  |
|  [Binary Log](../binary-log/index) |  Contains a record of all changes to the databases, both data and structure  |
|  [Unsafe Statements for Statement-based Replication](../unsafe-statements-for-statement-based-replication/index) |  Statements that are not safe for statement-based replication.  |
|  [Replication and Foreign Keys](../replication-and-foreign-keys/index) |  Cascading deletes or updates based on foreign key relations are not written to the binary log  |
|  [Relay Log](../relay-log/index) |  Event log created by the replica from the primary binary log.  |
|  [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index) |  Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.  |
|  [Group Commit for the Binary Log](../group-commit-for-the-binary-log/index) |  Optimization when the server is run with innodb\_flush\_logs\_at\_trx\_commit or sync\_binlog.  |
|  [Selectively Skipping Replication of Binlog Events](../selectively-skipping-replication-of-binlog-events/index) |  @@skip\_replication and --replicate-events-marked-for-skip.  |
|  [Binlog Event Checksums](../binlog-event-checksums/index) |  Including a checksum in binlog events.  |
|  [Binlog Event Checksum Interoperability](../binlog-event-checksum-interoperability/index) |  Replicating between servers with differing binlog checksum availability  |
|  [Annotate\_rows\_log\_event](../annotate_rows_log_event/index) |  Annotate\_rows events accompany row events and describe the query which caused the row event.  |
|  [Row-based Replication With No Primary Key](../row-based-replication-with-no-primary-key/index) |  MariaDB improves on row-based replication of tables with no primary key  |
|  [Replication Filters](../replication-filters/index) |  Replication filters allow users to configure replicas to intentionally skip certain events.  |
|  [Running Triggers on the Replica for Row-based Events](../running-triggers-on-the-replica-for-row-based-events/index) |  Running triggers on the replica for row-based events.  |
|  [Semisynchronous Replication](../semisynchronous-replication/index) |  Semisynchronous replication.  |
|  [Using MariaDB Replication with MariaDB Galera Cluster](../using-mariadb-replication-with-mariadb-galera-cluster/index) |  Information on using MariaDB replication with MariaDB Galera Cluster.  |
|  [Delayed Replication](../delayed-replication/index) |  Specify that a replica should lag behind the primary by (at least) a specified amount of time.  |
|  [Replication When the Primary and Replica Have Different Table Definitions](../replication-when-the-primary-and-replica-have-different-table-definitions/index) |  Slave and the primary table definitions can differ while replicating.  |
|  [Restricting Speed of Reading Binlog from Primary by a Replica](../restricting-speed-of-reading-binlog-from-primary-by-a-replica/index) |  The read\_binlog\_speed\_limit option can be used to reduce load on the primary.  |
|  [Changing a Replica to Become the Primary](../changing-a-replica-to-become-the-primary/index) |  How to change a replica to primary and old primary as a replica for the new primary.  |
|  [Replication with Secure Connections](../replication-with-secure-connections/index) |  Enabling TLS encryption in transit for MariaDB replication.  |
|  [Obsolete Replication Information](../obsolete-replication-information/index) |  This section is for replication-related items that are obsolete  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/standard-replication/>

Server Monitoring & Logs
=========================

   MariaDB can keep a number of log files, including the error log, the binary log, the general query log and the slow query log.

  

| Title | Description |
| --- | --- |
|  [Overview of MariaDB Logs](../overview-of-mariadb-logs/index) |  What to log and what not to log.  |
|  [Error Log](../error-log/index) |  Record of critical errors that occurred during the server's operation.  |
|  [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) |  Specifying the language for the server error messages.  |
|  [General Query Log](../general-query-log/index) |  Log of every SQL query received from a client, as well as connects/disconnects.  |
|  [Slow Query Log](../slow-query-log/index) |  Logging slow queries  |
|  [Rotating Logs on Unix and Linux](../rotating-logs-on-unix-and-linux/index) |  Rotating logs on Unix and Linux with logrotate.  |
|  [Binary Log](../binary-log/index) |  Contains a record of all changes to the databases, both data and structure  |
|  [InnoDB Redo Log](../innodb-redo-log/index) |  The redo log is used by InnoDB during crash recovery.  |
|  [InnoDB Undo Log](../innodb-undo-log/index) |  InnoDB Undo log.  |
|  [MyISAM Log](../myisam-log/index) |  Records all changes to MyISAM tables  |
|  [Transaction Coordinator Log](../transaction-coordinator-log/index) |  The transaction coordinator log (tc\_log) is used to coordinate transactions...  |
|  [SQL Error Log Plugin](../sql-error-log-plugin/index) |  Records SQL-level errors to a log file.  |
|  [Writing Logs Into Tables](../writing-logs-into-tables/index) |  The general query log and the slow query log can be written into system tables  |
|  [Performance Schema](../performance-schema/index) |  Monitoring server performance.  |
|  [MariaDB Audit Plugin](../mariadb-audit-plugin/index) |  Logging user activity with the MariaDB Audit Plugin.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/server-monitoring-logs/>

Optimization and Tuning
========================

   Articles on how to get the most out of MariaDB, including new features.

  

| Title | Description |
| --- | --- |
|  [Hardware Optimization](../hardware-optimization/index) |  Better performance with hardware improvements  |
|  [Operating System Optimizations](../operating-system-optimizations/index) |  Optimizations at the OS level  |
|  [Optimization and Indexes](../optimization-and-indexes/index) |  Using indexes to improve query performance  |
|  [Query Optimizations](../query-optimizations/index) |  Getting queries running more optimally  |
|  [Optimizing Tables](../optimizing-tables/index) |  Different ways to optimize tables and data on disk  |
|  [MariaDB Memory Allocation](../mariadb-memory-allocation/index) |  Basic issues in RAM allocation for MariaDB.  |
|  [System Variables](../system-variables/index) |  Understanding, optimizing and tuning the server system variables  |
|  [Buffers, Caches and Threads](../buffers-caches-and-threads/index) |  Buffering, caching, thread pool to improve performance  |
|  [Optimizing Data Structure](../optimizing-data-structure/index) |  Designing the most optimal schemas, tables, and columns  |
|  [MariaDB Internal Optimizations](../mariadb-internal-optimizations/index) |  Different optimizations strategies done internally in MariaDB  |
|  [Benchmarking](../benchmarking/index) |  Various benchmark results for MariaDB.  |
|  [Compression](../optimization-and-tuning-compression/index) |  Types of compression in MariaDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimization-and-tuning/>

Backing Up and Restoring Databases
===================================

   There are a number of ways to backup a MariaDB server.

  

| Title | Description |
| --- | --- |
|  [Backup and Restore Overview](../backup-and-restore-overview/index) |  Backing up and restoring MariaDB.  |
|  [Replication as a Backup Solution](../replication-as-a-backup-solution/index) |  Replication can be used to support the backup strategy.  |
|  [mariadb-dump](../mariadb-dump/index) |  Dump a database or a collection of databases in a portable format.  |
|  [Mariabackup](../mariabackup/index) |  Physical backups, supports Data-at-Rest and InnoDB compression.  |
|  [Backup and Restore via dbForge Studio](../backup-and-restore-via-dbforge-studio/index) |  The fastest and easiest way to perform these operations with MariaDB databases.  |
|  [mariadb-hotcopy](../mariadb-hotcopy/index) |  Fast backup program on local machine. Deprecated.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backing-up-and-restoring-databases/>

MariaDB Galera Cluster
=======================

   MariaDB Galera Cluster is a [virtually synchronous](../about-galera-replication/index) multi-master cluster that runs on Linux only. It has been a standard part of the server since [MariaDB 10.1](../what-is-mariadb-101/index).

  

| Title | Description |
| --- | --- |
|  [What is MariaDB Galera Cluster?](../what-is-mariadb-galera-cluster/index) |  Basic information on MariaDB Galera Cluster.  |
|  [About Galera Replication](../about-galera-replication/index) |  About Galera replication.  |
|  [Galera Use Cases](../galera-use-cases/index) |  Common use cases for Galera replication.  |
|  [MariaDB Galera Cluster - Known Limitations](../mariadb-galera-cluster-known-limitations/index) |  Describing the known limitations of MariaDB Galera Cluster.  |
|  [Tips on Converting to Galera](../tips-on-converting-to-galera/index) |  Best/required practices when using Galera for High-availability  |
|  [Getting Started with MariaDB Galera Cluster](../getting-started-with-mariadb-galera-cluster/index) |  Synchronous multi-master cluster for Linux supporting InnoDB storage engines.  |
|  [Configuring MariaDB Galera Cluster](../configuring-mariadb-galera-cluster/index) |  Details on how to configure MariaDB Galera Cluster.  |
|  [State Snapshot Transfers (SSTs) in Galera Cluster](../state-snapshot-transfers-ssts-in-galera-cluster/index) |  In an SST, the cluster provisions nodes by transferring a full data copy from one node to another.  |
|  [Galera Cluster Status Variables](../galera-cluster-status-variables/index) |  Galera Cluster status variables.  |
|  [Galera Cluster System Variables](../galera-cluster-system-variables/index) |  Listing and description of Galera Cluster system variables.  |
|  [Building the Galera wsrep Package on Ubuntu and Debian](../building-the-galera-wsrep-package-on-ubuntu-and-debian/index) |  Short how-to on building the galera package on Debian  |
|  [Building the Galera wsrep Package on Fedora](../building-the-galera-wsrep-package-on-fedora/index) |  Short how-to on building the galera package on Fedora  |
|  [Installing Galera from Source](../installing-galera-from-source/index) |  Building Galera from source.  |
|  [Galera Test Repositories](../galera-test-repositories/index) |  To facilitate development and QA, we have created some test repos for the Galera wsrep provider.  |
|  [wsrep\_provider\_options](../wsrep_provider_options/index) |  Galera options set with the wsrep\_provider\_options variable.  |
|  [Galera Cluster Address](../galera-cluster-address/index) |  Galera URLs  |
|  [Galera Load Balancer](../galera-load-balancer/index) |  A load balancer specifically designed for Galera Cluster  |
|  [MariaDB Galera Cluster Releases](../mariadb-galera-cluster-releases/index) |  Galera Cluster release notes and changelogs.  |
|  [Upgrading Galera Cluster](../upgrading-galera-cluster/index) |  Upgrading MariaDB Galera Cluster.  |
|  [Using MariaDB Replication with MariaDB Galera Cluster](../using-mariadb-replication-with-mariadb-galera-cluster/index) |  Information on using MariaDB replication with MariaDB Galera Cluster.  |
|  [Securing Communications in Galera Cluster](../securing-communications-in-galera-cluster/index) |  Enabling TLS encryption in transit for Galera Cluster.  |
|  [Installing MariaDB Galera on IBM Cloud](../installing-mariadb-galera-on-ibm-cloud/index) |  Get MariaDB Galera on IBM Cloud You should have an IBM Cloud account, oth...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-cluster/>

SQL Statements & Structure
===========================

   The letters *SQL* stand for Structured Query Language. As with all languages—even computer languages—there are grammar rules. This includes a certain structure to statements, acceptable punctuation (i.e., operators and delimiters), and a vocabulary (i.e., reserve words).

  

| Title | Description |
| --- | --- |
|  [SQL Statements](../sql-statements/index) |  Explanations of all of the MariaDB SQL statements.  |
|  [SQL Language Structure](../sql-language-structure/index) |  Explanation of SQL grammar rules, including reserved words and literals.  |
|  [Geographic & Geometric Features](../geographic-geometric-features/index) |  Spatial extensions for geographic and geometric features.  |
|  [NoSQL](../nosql/index) |  NoSQL-related commands and interfaces  |
|  [Operators](../operators/index) |  Operators for comparing and assigning values.  |
|  [Sequences](../sequences/index) |  Sequence objects, an alternative to AUTO\_INCREMENT.  |
|  [Temporal Tables](../temporal-tables/index) |  MariaDB supports system-versioning, application-time periods and bitemporal tables.  |
|  [Unleashing the Power of Advanced SQL: Joins, Subqueries, and Set Operations](../unleashing-the-power-of-advanced-sql-joins-subqueries-and-set-operations/index) |  SQL (Structured Query Language) is a highly potent language used in the rea...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-statements-structure/>

Multi Master in maria db
========================

    Can we configure Multi Master in Maria Db. I have testing three node A, B, C in Maria DB in Galera cluster. This 3 node belongs to one site. I want to configure HA with another site having the same setting as A1,B1, C1. Now i want to make A and B as master of C1. A,B,C, A1,B1,and C1 will have same db. Will it maintain the txId while replication?

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multi-master-in-maria-db/>

Copying Tables Between Different MariaDB Databases and MariaDB Servers
======================================================================

     With MariaDB it's very easy to copy tables between different MariaDB databases and different MariaDB servers. This works for tables created with the [Archive](../archive/index), [Aria](../aria/index), [CSV](../csv/index), [InnoDB](../innodb/index), [MyISAM](../myisam/index), [MERGE](../merge/index), and [XtraDB](../innodb/index) engines.

 The normal procedures to copy a table is:

 
```
FLUSH TABLES db_name.table_name FOR EXPORT

# Copy the relevant files associated with the table

UNLOCK TABLES;

```

The table files can be found in [datadir](../server-system-variables/index#datadir)/databasename (you can execute `SELECT @@datadir` to find the correct directory). When copying the files, you should copy all files with the same table\_name + various extensions. For example, for an Aria table of name foo, you will have files foo.frm, foo.MAI, foo.MAD and possibly foo.TRG if you have [triggers](../triggers/index).

 If one wants to distribute a table to a user that doesn't need write access to the table and one wants to minimize the storage size of the table, the recommended engine to use is Aria or MyISAM as one can pack the table with [aria\_pack](../aria_pack/index) or [myisampack](../myisampack/index) respectively to make it notablly smaller. MyISAM is the most portable format as it's not dependent on whether the server settings are different. Aria and InnoDB require the same block size on both servers.

 Copying Tables When the MariaDB Server is Down
----------------------------------------------

 The following storage engines support export without `FLUSH TABLES ... FOR EXPORT`, assuming the source server is down and the receiving server is not accessing the files during the copy.

 


| Engine | Comment |
| --- | --- |
| [Archive](../archive/index) |  |
| [Aria](../aria/index) | Requires clean shutdown. Table will automatically be fixed on the receiving server if `aria_chk --zerofill` was not run. If `aria_chk --zerofill` is run, then the table is immediately usable without any delays |
| [CSV](../csv/index) |  |
| [MyISAM](../myisam/index) |  |
| [MERGE](../merge/index) | .MRG files can be copied even while server is running as the file only contains a list of tables that are part of merge. |

 
Copying Tables Live From a Running MariaDB Server
-------------------------------------------------

 For all of the above storage engines (Archive, Aria, CSV, MyISAM and MERGE), one can copy tables even from a live server under the following circumstances:

 * You have done a `FLUSH TABLES` or `FLUSH TABLE table_name` for the specific table.
* The server is not accessing the tables during the copy process.

 The advantage of [FLUSH TABLES table\_name FOR EXPORT](../flush-tables-for-export/index) is that the table is read locked until [UNLOCK TABLES](https://mariadb.com/lock-tables-and-unlock-tables) is executed.

 **Warning**: If you do the above live copy, you are doing this on **your own risk** as if you do something wrong, the copied table is very likely to be corrupted. The original table will of course be fine.

 An Efficient Way to Give Someone Else Access to a Read Only Table
-----------------------------------------------------------------

 If you want to give a user access to some data in a table for the user to use in their MariaDB server, you can do the following:

 First let's create the table we want to export. To speed up things, we create this without any indexes. We use `TRANSACTIONAL=0
ROW_FORMAT=DYNAMIC` for Aria to use the smallest possible row format.

 
```
CREATE TABLE new_table ... ENGINE=ARIA TRANSACTIONAL=0;
ALTER TABLE new_table DISABLE_KEYS;
# Fill the table with data:
INSERT INTO new_table SELECT * ...
FLUSH TABLE new_table WITH READ LOCK;

# Copy table data to some external location, like /tmp with something
# like cp /my/data/test/new_table.* /tmp/

UNLOCK TABLES;

```

Then we pack it and generate the indexes. We use a big sort buffer to speed up generating the index.

 
```
> ls -l /tmp/new_table.*
-rw-rw---- 1 mysql my 42396148 Sep 21 17:58 /tmp/new_table.MAD
-rw-rw---- 1 mysql my     8192 Sep 21 17:58 /tmp/new_table.MAI
-rw-rw---- 1 mysql my     1039 Sep 21 17:58 /tmp/new_table.frm
> aria_pack /tmp/new_table
Compressing /tmp/new_table.MAD: (922666 records)
- Calculating statistics
- Compressing file
46.07%
> aria_chk -rq --ignore-control-file --sort_buffer_size=1G /tmp/new_table
Recreating table '/tmp/new_table'
- check record delete-chain
- recovering (with sort) Aria-table '/tmp/new_table'
Data records: 922666
- Fixing index 1
State updated
> ls -l /tmp/new_table.*
-rw-rw---- 1 mysql my 26271608 Sep 21 17:58 /tmp/new_table.MAD
-rw-rw---- 1 mysql my 10207232 Sep 21 17:58 /tmp/new_table.MAI
-rw-rw---- 1 mysql my     1039 Sep 21 17:58 /tmp/new_table.frm

```

The procedure for MyISAM tables is identical, except that [myisamchk](../myisamchk/index) doesn't have the `--ignore-control-file` option.

 Copying InnoDB's Transportable Tablespaces
------------------------------------------

 InnoDB's file-per-table tablespaces are transportable, which means that you can copy a file-per-table tablespace from one MariaDB Server to another server. See [Copying Transportable Tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) for more information.

 Importing Tables
----------------

 Tables that use most storage engines are immediately usable when their files are copied to the new `[datadir](../server-system-variables/index#datadir)`.

 However, this is not true for tables that use [InnoDB](../innodb/index). InnoDB tables have to be imported with [ALTER TABLE ... IMPORT TABLESPACE](../alter-table/index#import-tablespace). See [Copying Transportable Tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) for more information.

 See Also
--------

 * [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index)
* [FLUSH TABLES](../flush/index)
* [myisampack](../myisampack/index) - Compressing the MyISAM data file for easier distribution.
* [aria\_pack](../aria_pack/index) - Compressing the Aria data file for easier distribution
* [mariadb-dump](../mariadb-dump/index) - Copying tables to other SQL servers. You can use the `--tab` to create a CSV file of your table content.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/copying-tables-between-different-mariadb-databases-and-mariadb-servers/>

Multi master replication and deadlock detection in Galera with Mariadbs
=======================================================================

    Hi, 

 We have multi master Galera replication setup where three master mariadbs are continuously updated. 1. Because of which occasionally a transaction encounters deadlock. 2. The JDBC queries slow down their executions if we allow continuous table updates. 

 Add to the mix an event that purges the tables and we noticed a deletion of more than 200000 entries held the lock for more than 15 seconds. 

 How can we rectify this problem? Is there a way to improve DB performance in replication setup? We also used non replicated setup and the portal does not encounter any JDBC connection errors. 

 Your insights are much appreciated. 

 Thanks

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multi-master-replication-and-deadlock-detection-in-galera-with-mariadbs/>

Columns, Storage Engines, and Plugins
======================================

   MariaDB allows for a variety of column data types, characters and collations.

  

| Title | Description |
| --- | --- |
|  [Data Types](../data-types/index) |  Data types for columns in MariaDB tables.  |
|  [Character Sets and Collations](../character-sets/index) |  Setting character set and collation for a language.  |
|  [Storage Engines](../storage-engines/index) |  Various storage engines available for MariaDB.  |
|  [Plugins](../plugins/index) |  Documentation on MariaDB Server plugins.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/columns-storage-engines-and-plugins/>

Storage Engines
================

   Information on storage engines available for MariaDB.

  

| Title | Description |
| --- | --- |
|  [Choosing the Right Storage Engine](../choosing-the-right-storage-engine/index) |  Quickly choose the most suitable storage engine for your needs.  |
|  [InnoDB](../innodb/index) |  The general-purpose InnoDB storage engine.  |
|  [MariaDB ColumnStore](../mariadb-columnstore/index) |  Uses a massively parallel architecture, ideal for systems that scale to petabytes of data.  |
|  [Aria](../aria/index) |  Aria is a crash safe MyISAM and more.  |
|  [Archive](../archive/index) |  Stores data in compressed (gzip) format.  |
|  [BLACKHOLE](../blackhole/index) |  Storage engine that accepts data without storing it.  |
|  [CONNECT](../connect/index) |  The CONNECT storage engine enables MariaDB to access external local or remote data.  |
|  [CSV](../csv/index) |  Works with files stored in CSV (comma-separated-values) format.  |
|  [FederatedX](../federatedx-storage-engine/index) |  Allows you to access tables in other MariaDB or MySQL servers.  |
|  [MEMORY Storage Engine](../memory-storage-engine/index) |  Storage engine stored in memory rather than on disk.  |
|  [MERGE](../merge/index) |  Allows you to access a collection of identical MyISAM tables as one.  |
|  [Mroonga](../mroonga/index) |  Provides fast CJK-ready full text searching using column store.  |
|  [MyISAM](../myisam-storage-engine/index) |  Non-transactional storage engine with good performance and small data footprint.  |
|  [MyRocks](../myrocks/index) |  Adds RocksDB, an LSM database with a great compression ratio that is optimized for flash storage.  |
|  [OQGRAPH](../oqgraph-storage-engine/index) |  Open Query GRAPH computation engine for handling hierarchies (tree structures) and complex graphs.  |
|  [S3 Storage Engine](../s3-storage-engine/index) |  A read-only storage engine that stores its data in Amazon S3.  |
|  [Sequence Storage Engine](../sequence-storage-engine/index) |  Allows ascending or descending sequences of numbers.  |
|  [SphinxSE](../sphinx-storage-engine/index) |  Storage engine that talks to searchd to enable text searching.  |
|  [Spider](../spider/index) |  Supports partitioning and xa transactions and allows tables of different in...  |
|  [TokuDB](../tokudb/index) |  For use in high-performance and write-intensive environments.  |
|  [Information Schema ENGINES Table](../information-schema-engines-table/index) |  Storage engine information.  |
|  [PERFORMANCE\_SCHEMA Storage Engine](../performance_schema-storage-engine/index) |  PERFORMANCE\_SCHEMA storage engine, a mechanism for implementing the feature.  |
|  [Legacy Storage Engines](../legacy-storage-engines/index) |  Storage engines that are no longer maintained.  |
|  [Storage Engine Development](../storage-engines-storage-engine-development/index) |  Storage Engine Development.  |
|  [Converting Tables from MyISAM to InnoDB](../converting-tables-from-myisam-to-innodb/index) |  Issues when converting tables from MyISAM to InnoDB.  |
|  [Machine Learning with MindsDB](../machine-learning-with-mindsdb/index) |  A 3rd-party tool interfacing with MariaDB Server to provide Machine Learning capabilities.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engines/>

Plugins
========

   MariaDB supports the use of plugins, software components that may be added to the core software without having to rebuild the MariaDB server from source code. Therefore, plugins can be loaded at start-up, or loaded and unloaded while the server is running without interruption. Plugins are commonly used for adding desired storage engines, additional security requirements, and logging special information about the server.

  

| Title | Description |
| --- | --- |
|  [Plugin Overview](../plugin-overview/index) |  Basics of listing, installing and uninstalling plugins.  |
|  [Information on Plugins](../information-on-plugins/index) |  Information on installed and disabled plugins on a MariaDB Server.  |
|  [Plugin SQL Statements](../plugin-sql-statements/index) |  List of SQL statements related to plugins.  |
|  [Creating and Building Plugins](../creating-and-building-plugins/index) |  Documentation on how to create new plugins and build existing ones.  |
|  [MariaDB Audit Plugin](../mariadb-audit-plugin/index) |  Logging user activity with the MariaDB Audit Plugin.  |
|  [Authentication Plugins](../authentication-plugins/index) |  Authentication plugins allow various authentication methods to be used, and new ones developed.  |
|  [Password Validation Plugins](../password-validation-plugins/index) |  Ensuring that user passwords meet certain minimal security requirements.  |
|  [Key Management and Encryption Plugins](../key-management-and-encryption-plugins/index) |  MariaDB uses plugins to handle key management and encryption of data.  |
|  [MariaDB Replication & Cluster Plugins](../mariadb-replication-cluster-plugins/index) |  Plugins related to MariaDB replication and other replication cluster systems.  |
|  [Storage Engines](../storage-engines/index) |  Various storage engines available for MariaDB.  |
|  [Other Plugins](../other-plugins/index) |  Information on installing and using other plugins.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plugins/>

Programming & Customizing MariaDB
==================================

   Ways to add simple code to SQL statements, or create your own functions or stored procedures.

  

| Title | Description |
| --- | --- |
|  [Programmatic & Compound Statements](../programmatic-compound-statements/index) |  Compound SQL statements for stored routines and in general.  |
|  [Stored Routines](../stored-routines/index) |  Stored procedures and functions.  |
|  [Triggers & Events](../triggers-events/index) |  Creating triggers and scheduled events within MariaDB.  |
|  [Views](../views/index) |  Stored queries for generating a virtual table.  |
|  [User-Defined Functions](../user-defined-functions/index) |  Extending MariaDB with custom functions.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/programming-customizing-mariadb/>

Stored Routines
================

   Stored procedures and stored functions.

  

| Title | Description |
| --- | --- |
|  [Stored Procedures](../stored-procedures/index) |  Routine invoked with a CALL statement.  |
|  [Stored Functions](../stored-functions/index) |  Defined functions for use with SQL statements.  |
|  [Stored Routine Statements](../stored-routine-statements/index) |  SQL statements related to creating and using stored routines.  |
|  [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) |  Stored routines require extra consideration when binary logging.  |
|  [Stored Routine Limitations](../stored-routine-limitations/index) |  SQL statements not permitted in stored programs.  |
|  [Stored Routine Privileges](../stored-routine-privileges/index) |  Privileges associated with stored functions and stored procedures.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-routines/>

MariaDB Audit Plugin
=====================

   MariaDB and MySQL are used in a broad range of environments, but if you needed to record user access to be in compliance with auditing regulations for your organization, you would previously have had to use other database solutions. To meet this need, though, MariaDB has developed the MariaDB Audit Plugin. Although the MariaDB Audit Plugin has some unique features available only for MariaDB, it can be used also with MySQL.

 Basically, the purpose of the MariaDB Audit Plugin is to log the server's activity. For each client session, it records who connected to the server (i.e., user name and host), what queries were executed, and which tables were accessed and server variables that were changed. This information is stored in a rotating log file or it may be sent to the local `syslogd`.

 The MariaDB Audit Plugin works with MariaDB, MySQL (as of, version 5.5.34 and 10.0.7) and Percona Server. MariaDB started including by default the Audit Plugin from versions 10.0.10 and 5.5.37, and it can be installed in any version from [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/). 

 #### Additional documentation

 Below are links to additional documentation on the MariaDB Audit Plugin. They explain in detail how to install, configure and use the Audit Plugin.

 * [Installation](../mariadb-audit-plugin-installation/index)
* [Configuration](../mariadb-audit-plugin-configuration/index)
* [Log Settings](../mariadb-audit-plugin-log-settings/index)
* [Log Location & Rotation](../mariadb-audit-plugin-location-and-rotation-of-logs/index)
* [Log Format](../mariadb-audit-plugin-log-format/index)
* [Status Variables](../mariadb-audit-plugin-status-variables/index)
* [System Variables](../mariadb-audit-plugin-system-variables/index)
* [Release Notes](../release-notes-mariadb-audit-plugin/index)

 #### Tutorials

 Below are links to some tutorials on MariaDB's site and other sites. They may help you to get more out of the MariaDB Audit Plugin.

 * [Introducing the MariaDB Audit Plugin](https://mariadb.com/resources/blog/introducing-mariadb-audit-plugin)   
 by Anatoliy Dimitrov, September 2, 2014

 * [Activating MariaDB Audit Log](https://tunnelix.com/activating-mariadb-audit-log/) by Jaykishan Mutkawoa, May 30, 2016

 * [Installing MariaDB Audit Plugin on Amazon RDS](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.MySQL.Options.AuditPlugin.html)   
 Amazon RDS supports using the MariaDB Audit Plugin on MySQL and MariaDB database instances.

 #### Web Log Articles

 Below are links to web log articles on the MariaDB Audit Plugin. You may find them useful in understanding better how to use the Audit Plugin. Since some of these articles are older, they won't include changes and improvements in newer versions. You can rely on the documentation pages listed above for the most current information.

 * [Activating Auditing for MariaDB in 5 Minutes](https://mariadb.com/resources/blog/activating-auditing-mariadb-and-mysql-5-minutes)   
 by Ralf Gebhardt, September 29, 2013

 * [Query and Password Filtering with the MariaDB Audit Plugin](https://mariadb.com/resources/blog/query-and-password-filtering-mariadb-audit-plugin)   
 by Ralf Gebhardt, May 4, 2015

 * [Set Up a Remote Log File using rsyslog](https://mariadb.com/resources/blog/mariadb-audit-plugin-set-remote-log-file-using-rsyslog)   
 by Ralf Gebhardt, December 16, 2013

 * [MySQL Auditing with MariaDB Auditing Plugin](https://planet.mysql.com/entry/?id=5994184) by Peter Zeitsev, February 15, 2016

 #### Sub-Documents

  

| Title | Description |
| --- | --- |
|  [MariaDB Audit Plugin - Installation](../mariadb-audit-plugin-installation/index) |  Installing the MariaDB Audit Plugin.  |
|  [MariaDB Audit Plugin - Configuration](../mariadb-audit-plugin-configuration/index) |  Audit Plugin global variables within MariaDB  |
|  [MariaDB Audit Plugin - Log Settings](../mariadb-audit-plugin-log-settings/index) |  Log audit events to a file or syslog.  |
|  [MariaDB Audit Plugin - Location and Rotation of Logs](../mariadb-audit-plugin-location-and-rotation-of-logs/index) |  Logs can be written to a separate file or to the system logs  |
|  [MariaDB Audit Plugin - Log Format](../mariadb-audit-plugin-log-format/index) |  The audit log is a set of records written as a list of fields to a file in plain‐text format.  |
|  [MariaDB Audit Plugin - Versions](../mariadb-audit-plugin-versions/index) |  Releases of the MariaDB Audit Plugin, and in which versions of MariaDB each...  |
|  [MariaDB Audit Plugin Options and System Variables](../mariadb-audit-plugin-options-and-system-variables/index) |  Description of Server\_Audit plugin options and system variables.  |
|  [MariaDB Audit Plugin - Status Variables](../mariadb-audit-plugin-status-variables/index) |  Server Audit plugin status variables  |
|  [Release Notes - MariaDB Audit Plugin](../release-notes-mariadb-audit-plugin/index) |  MariaDB Audit Plugin release notes  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin/>

Programmatic & Compound Statements
===================================

   Compound statements in MariaDB can be used both inside and outside of [stored programs](../stored-programs-and-views/index).

  

| Title | Description |
| --- | --- |
|  [Using Compound Statements Outside of Stored Programs](../using-compound-statements-outside-of-stored-programs/index) |  Compound statements are not just for stored programs.  |
|  [BEGIN END](../begin-end/index) |  How to write compound statements.  |
|  [CASE Statement](../case-statement/index) |  Conditional construct with multiple choices.  |
|  [DECLARE CONDITION](../declare-condition/index) |  For declaring a named error condition (SQLSTATE or error code).  |
|  [DECLARE HANDLER](../declare-handler/index) |  Construct to declare how errors are handled.  |
|  [DECLARE Variable](../declare-variable/index) |  Declare local variables within stored programs.  |
|  [FOR](../for/index) |  FOR loops allow code to be executed a fixed number of times.  |
|  [GOTO](../goto/index) |  Jump to the given label.  |
|  [IF](../if/index) |  A basic conditional construct statement.  |
|  [ITERATE](../iterate/index) |  Used to repeat the execution of the current loop.  |
|  [Labels](../labels/index) |  Identifiers used to identify a BEGIN ... END construct.  |
|  [LEAVE](../leave/index) |  Used to exit a code block.  |
|  [LOOP](../loop/index) |  Used to loop within a code block without a condition.  |
|  [REPEAT LOOP](../repeat-loop/index) |  Used to repeat statements until a search condition is true.  |
|  [RESIGNAL](../resignal/index) |  Used to send a SIGNAL again for the previous error.  |
|  [RETURN](../return/index) |  Statement to terminate execution of a stored function and return a value.  |
|  [SELECT INTO](../selectinto/index) |  SQL statement for inserting values into variables.  |
|  [SET Variable](../set-variable/index) |  Used to insert a value into a variable with a code block.  |
|  [SIGNAL](../signal/index) |  May be used to produce a custom error message.  |
|  [WHILE](../while/index) |  Used to repeat a block of SQL statements while a search condition is true.  |
|  [Cursors](../programmatic-compound-statements-cursors/index) |  Structure for traversing and processing results, sequentially.  |
|  [Diagnostics](../programmatic-compound-statements-diagnostics/index) |  Error conditions and statement information.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/programmatic-compound-statements/>

Clients & Utilities
====================

  

| Title | Description |
| --- | --- |
|  [mariadb Client](../mariadb-client/index) |  The mariadb command-line client.  |
|  [Aria Clients and Utilities](../aria-clients-and-utilities/index) |  Clients and utilities for working with Aria tables  |
|  [Backup, Restore and Import Clients](../backup-restore-and-import-clients/index) |  Clients for taking backups or importing/restoring data  |
|  [Graphical and Enhanced Clients](../graphical-and-enhanced-clients/index) |  Incomplete list of graphical clients  |
|  [MyISAM Clients and Utilities](../myisam-clients-and-utilities/index) |  Clients and utilities for working with MyISAM tables  |
|  [dbdeployer](../dbdeployer/index) |  Installing and testing multiple MariaDB versions in isolation.  |
|  [dbForge Studio for MySQL/MariaDB](../dbforge-studio-for-mysqlmariadb/index) |  IDE for the development, management, and administration of MariaDB & MySQL databases.  |
|  [EXPLAIN Analyzer](../explain-analyzer/index) |  The EXPLAIN Analyzer is no longer active. The EXPLAIN Analyzer was an onlin...  |
|  [EXPLAIN Analyzer API](../explain-analyzer-api/index) |  The online EXPLAIN Analyzer tool has an open API to allow client applicatio...  |
|  [innochecksum](../innochecksum/index) |  Tool for printing checksums for InnoDB files.  |
|  [msql2mysql](../msql2mysql/index) |  Description Initially, the MySQL C API was developed to be very similar to ...  |
|  [my\_print\_defaults](../my_print_defaults/index) |  Displays the options from option groups of option files  |
|  [mariadb-binlog](../mariadb-binlog/index) |  mariadb-binlog utility for processing binary log files.  |
|  [mariadb-stress-test](../mariadb-stress-test/index) |  Perl script that performs stress-testing of the MariaDB server  |
|  [mariadb-test](../mariadb-test/index) |  Testing utility  |
|  [perror](../perror/index) |  Display descriptions for system or storage engine error codes  |
|  [replace Utility](../replace-utility/index) |  The replace utility program changes strings in place infiles or on the standard input  |
|  [resolveip](../resolveip/index) |  Resolves IP addresses to host names and vice versa  |
|  [resolve\_stack\_dump](../resolve_stack_dump/index) |  Resolve numeric stack strace dump into symbols  |
|  [xtstat](../xtstat/index) |  Used to monitor all internal activity of PBXT  |
|  [mariadb-access](../mariadb-access/index) |  Tool for checking access privileges.  |
|  [mariadb-admin](../mariadb-admin/index) |  Admin tool for monitoring, creating/dropping databases, stopping MariaDB etc.  |
|  [mariadb-check](../mariadb-check/index) |  Tool for checking, repairing, analyzing and optimizing tables.  |
|  [mariadb-conv](../mariadb-conv/index) |  Character set conversion utility for MariaDB.  |
|  [mariadb-convert-table-format](../mariadb-convert-table-format/index) |  Convert tables to use a particular storage engine by default.  |
|  [mariadb-dumpslow](../mariadb-dumpslow/index) |  Display data from the slow query log.  |
|  [mariadb-embedded](../mariadb-embedded/index) |  mariadb client statically linked to libmariadbd, the embedded server.  |
|  [mariadb-find-rows](../mariadb-find-rows/index) |  Read files containing SQL statements and extract statements that match a pattern.  |
|  [mariadb-fix-extensions](../mariadb-fix-extensions/index) |  Converts the extensions for MyISAM (or ISAM) table files to their canonical forms.  |
|  [mariadb-install-db](../mariadb-install-db/index) |  Tool for creating the system tables in the mysql database.  |
|  [mariadb-plugin](../mariadb-plugin/index) |  Tool for enabling or disabling plugins.  |
|  [mariadb-report](../mariadb-report/index) |  Creates a friendly report of important MariaDB status values.  |
|  [mariadb-secure-installation](../mariadb-secure-installation/index) |  Improve the security of a MariaDB installation.  |
|  [mariadb-setpermission](../mariadb-setpermission/index) |  Helps add users or databases or change passwords in MariaDB.  |
|  [mariadb-show](../mariadb-show/index) |  Shows database structure.  |
|  [mariadb-slap](../mariadb-slap/index) |  Tool for load-testing MariaDB.  |
|  [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) |  Load time zones into the time zone tables.  |
|  [mariadb-upgrade](../mariadb-upgrade/index) |  Update to the latest MariaDB Server version.  |
|  [mariadb-waitpid](../mariadb-waitpid/index) |  Terminate processes.  |
|  [Legacy Clients and Utilities](../legacy-clients-and-utilities/index) |  Removed, deprecated or unmaintained MariaDB clients and utilities.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/clients-utilities/>

User-Defined Functions
=======================

   A user-defined function (UDF) is a way to extend MariaDB with a new function that works like a native (built-in) MariaDB function such as [ABS( )](../abs/index) or [CONCAT( )](../concat/index).

 Statements making use of user-defined functions are not [safe for replication](../unsafe-statements-for-replication/index).

 For an example, see `sql/udf_example.cc` in the source tree. For a collection of existing UDFs go to the [UDF Repository on GitHub](https://github.com/orgs/mysqludf/repositories).

 There are alternative ways to add a new function: writing a native function, which requires modifying and compiling the server source code; or writing a [stored function](../stored-functions/index).

  

| Title | Description |
| --- | --- |
|  [Creating User-Defined Functions](../creating-user-defined-functions/index) |  How to create user-defined functions in C/C++.  |
|  [User-Defined Functions Calling Sequences](../user-defined-functions-calling-sequences/index) |  Declaring the functions required in a user-defined function.  |
|  [User-Defined Functions Security](../user-defined-functions-security/index) |  MariaDB imposes a number of limitations on user-defined functions for security purposes.  |
|  [CREATE FUNCTION UDF](../create-function-udf/index) |  Create a user-defined function.  |
|  [DROP FUNCTION UDF](../drop-function-udf/index) |  Drop a user-defined function.  |
|  [mysql.func Table](../mysqlfunc-table/index) |  User-defined function information  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-defined-functions/>

Character Sets and Collations
==============================

   Simply put, a character set defines how and which characters are stored to support a particular language or languages. A collation, on the other hand, defines the order used when comparing strings (i.e. the position of any given character within the alphabet of that language)

  

| Title | Description |
| --- | --- |
|  [Character Set and Collation Overview](../character-set-and-collation-overview/index) |  Introduction to character sets and collations.  |
|  [Supported Character Sets and Collations](../supported-character-sets-and-collations/index) |  MariaDB supports the following character sets and collations.  |
|  [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) |  Changing from the default character set and collation.  |
|  [Unicode](../unicode/index) |  Unicode support.  |
|  [SHOW CHARACTER SET](../show-character-set/index) |  Available character sets.  |
|  [SHOW COLLATION](../show-collation/index) |  Supported collations.  |
|  [Information Schema CHARACTER\_SETS Table](../information-schema-character_sets-table/index) |  Supported character sets.  |
|  [Information Schema COLLATIONS Table](../information-schema-collations-table/index) |  Supported collations.  |
|  [Internationalization and Localization](../internationalization-and-localization/index) |  Character sets, collations, time zones and locales.  |
|  [SET CHARACTER SET](../set-character-set/index) |  Maps all strings sent between the current client and the server with the given mapping.  |
|  [SET NAMES](../set-names/index) |  The character set used to send statements to the server, and results back to the client.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/character-sets/>

Triggers & Events
==================

  

| Title | Description |
| --- | --- |
|  [Triggers](../triggers/index) |  Set of statements that run when an event occurs on a table.  |
|  [Event Scheduler](../event-scheduler/index) |  Named database objects containing SQL statements to be executed at a later stage.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/triggers-events/>

Views
======

   Views are stored queries that act as a virtual table.

  

| Title | Description |
| --- | --- |
|  [Creating & Using Views](../creating-using-views/index) |  A tutorial on creating and using views.  |
|  [CREATE VIEW](../create-view/index) |  Create or replace a view.  |
|  [ALTER VIEW](../alter-view/index) |  Change a view definition.  |
|  [DROP VIEW](../drop-view/index) |  Removes one or more views.  |
|  [SHOW CREATE VIEW](../show-create-view/index) |  Show the CREATE VIEW statement that created a view.  |
|  [Inserting and Updating with Views](../inserting-and-updating-with-views/index) |  Views can be used for inserting or updating with certain limitations.  |
|  [RENAME TABLE](../rename-table/index) |  Change a table's name.  |
|  [View Algorithms](../view-algorithms/index) |  Optional ALGORITHM clause when creating views  |
|  [Information Schema VIEWS Table](../information-schema-views-table/index) |  Information about views.  |
|  [SHOW TABLES](../show-tables/index) |  List of non-temporary tables, views or sequences.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/views/>

MariaDB Platform X3
====================

   **MariaDB Platform X3** responds to business design challenges by integrating:

 * MariaDB Server, the leading enterprise open source database;
* MariaDB ColumnStore, a columnar database for on-demand analytical processing; and
* MariaDB MaxScale, the world's most advanced database proxy.

 MariaDB Server powers website and application workloads as a modern RDBMS. MariaDB Platform X3 extends MariaDB Server's capabilities to include:

 * Transactional workloads (OLTP);
* Analytical workloads (OLAP); and
* the combination of the two as Hybrid Transactional and Analytical Processing (HTAP) queries.

  

| Title | Description |
| --- | --- |
|  [Sample Platform X3 implementation for Transactional and Analytical Workloads](../sample-platform-x3-implementation-for-transactional-and-analytical-workloads/index) |  MariaDB Platform X3 responds to business design challenges by integrating:...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-platform-x3/>

Training & Tutorials
=====================

   This section provides tutorials for those who want to learn about MariaDB and related software.

  

| Title | Description |
| --- | --- |
|  [Beginner MariaDB Articles](../beginner-mariadb-articles/index) |  Tutorials for newcomers and beginners to MariaDB.  |
|  [Basic MariaDB Articles](../basic-mariadb-articles/index) |  Basic tutorials -- more advanced than beginner.  |
|  [Intermediate MariaDB Articles](../intermediate-mariadb-articles/index) |  Intermediate level tutorials for MariaDB developers and administrators.  |
|  [Advanced MariaDB Articles](../advanced-mariadb-articles/index) |  Tutorial articles for advanced MariaDB developers and administrators.  |

 ###   [Books on MariaDB](../books/index)

 

| Title | Description |
| --- | --- |
|  [Beginner Books](../beginner-books/index) |  List of books on MariaDB for newcomers and beginners.  |
|  [Intermediate and Advanced Books](../intermediate-and-advanced-books/index) |  List of books on MariaDB for intermediate and advanced developers and administrators.  |
|  [Books on MariaDB Code](../books-on-mariadb-code/index) |  List of books on coding MariaDB Server and plugins.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/training-tutorials/>

Data Types
===========

   Data Types in MariaDB

  

| Title | Description |
| --- | --- |

 ###   [Numeric Data Types](../data-types-numeric-data-types/index)

 

| Title | Description |
| --- | --- |
|  [Numeric Data Type Overview](../numeric-data-type-overview/index) |  Overview and usage of the numeric data types.  |
|  [TINYINT](../tinyint/index) |  Tiny integer, -128 to 127 signed.  |
|  [BOOLEAN](../boolean/index) |  Synonym for TINYINT(1).  |
|  [SMALLINT](../smallint/index) |  Small integer from -32768 to 32767 signed.  |
|  [MEDIUMINT](../mediumint/index) |  Medium integer from -8388608 to 8388607 signed.  |
|  [INT](../int/index) |  Integer from -2147483648 to 2147483647 signed.  |
|  [INTEGER](../integer/index) |  Synonym for INT  |
|  [BIGINT](../bigint/index) |  Large integer.  |
|  [DECIMAL](../decimal/index) |  A packed "exact" fixed-point number.  |
|  [DEC, NUMERIC, FIXED](../dec-numeric-fixed/index) |  Synonyms for DECIMAL  |
|  [NUMBER](../number/index) |  Synonym for DECIMAL in Oracle mode.  |
|  [FLOAT](../float/index) |  Single-precision floating-point number  |
|  [DOUBLE](../double/index) |  Normal-size (double-precision) floating-point number  |
|  [DOUBLE PRECISION](../double-precision/index) |  REAL and DOUBLE PRECISION are synonyms for DOUBLE.  |
|  [BIT](../bit/index) |  Bit field type.  |
|  [Floating-point Accuracy](../floating-point-accuracy/index) |  Not all floating-point numbers can be stored with exact precision  |
|  [INT1](../int1/index) |  A synonym for TINYINT.  |
|  [INT2](../int2/index) |  Synonym for SMALLINT.  |
|  [INT3](../int3/index) |  Synonym for MEDIUMINT.  |
|  [INT4](../int4/index) |  Synonym for INT.  |
|  [INT8](../int8/index) |  Synonym for BIGINT.  |

 ###   [String Data Types](../string-data-types/index)

 

| Title | Description |
| --- | --- |
|  [String Literals](../string-literals/index) |  Strings are sequences of characters and are enclosed with quotes.  |
|  [BINARY](../binary/index) |  Fixed-length binary byte string.  |
|  [BLOB](../blob/index) |  Binary large object up to 65,535 bytes.  |
|  [BLOB and TEXT Data Types](../blob-and-text-data-types/index) |  Binary large object data types and the corresponding TEXT types.  |
|  [CHAR](../char/index) |  Fixed-length string.  |
|  [CHAR BYTE](../char-byte/index) |  Alias for BINARY.  |
|  [ENUM](../enum/index) |  Enumeration, or string object that can have one value chosen from a list of values.  |
|  [INET4](../inet4/index) |  For storage of IPv4 addresses.  |
|  [INET6](../inet6/index) |  For storage of IPv6 addresses.  |
|  [JSON Data Type](../json-data-type/index) |  Compatibility data type that is an alias for LONGTEXT.  |
|  [MEDIUMBLOB](../mediumblob/index) |  Medium binary large object up to 16,777,215 bytes.  |
|  [MEDIUMTEXT](../mediumtext/index) |  A TEXT column with a maximum length of 16,777,215 characters.  |
|  [LONGBLOB](../longblob/index) |  Long BLOB holding up to 4GB.  |
|  [LONG and LONG VARCHAR](../long-and-long-varchar/index) |  LONG and LONG VARCHAR are synonyms for MEDIUMTEXT.  |
|  [LONGTEXT](../longtext/index) |  A TEXT column with a maximum length of 4,294,967,295 characters.  |
|  [ROW](../row/index) |  Data type for stored procedure variables.  |
|  [TEXT](../text/index) |  A TEXT column with a maximum length of 65,535 characters.  |
|  [TINYBLOB](../tinyblob/index) |  Tiny binary large object up to 255 bytes.  |
|  [TINYTEXT](../tinytext/index) |  A TEXT column with a maximum length of 255 characters.  |
|  [VARBINARY](../varbinary/index) |  Variable-length binary byte string.  |
|  [VARCHAR](../varchar/index) |  Variable-length string.  |
|  [SET Data Type](../set-data-type/index) |  Set, or string object that can have 0 or more values chosen from a list of values.  |
|  [UUID Data Type](../uuid-data-type/index) |  Data type intended for the storage of UUID data.  |
|  [Data Type Storage Requirements](../data-type-storage-requirements/index) |  Storage requirements for the various data types.  |
|  [Supported Character Sets and Collations](../supported-character-sets-and-collations/index) |  MariaDB supports the following character sets and collations.  |
|  [Character Sets and Collations](../character-sets/index) |  Setting character set and collation for a language.  |

 ###   [Date and Time Data Types](../date-and-time-data-types/index)

 

| Title | Description |
| --- | --- |
|  [DATE](../date/index) |  The date type YYYY-MM-DD.  |
|  [TIME](../time/index) |  Time format HH:MM:SS.ssssss  |
|  [DATETIME](../datetime/index) |  Date and time combination displayed as YYYY-MM-DD HH:MM:SS.  |
|  [TIMESTAMP](../timestamp/index) |  YYYY-MM-DD HH:MM:SS  |
|  [YEAR Data Type](../year-data-type/index) |  A four-digit year.  |
|  [Future developments for temporal types](../future-developments-for-temporal-types/index) |  My current project is a forecasting application with dates going out to 263...  |
|  [How to define a date in order to import an empty date from a CSV file?](../how-to-define-a-date-in-order-to-import-an-empty-date-from-a-csv-file/index) |  I have a CSV file containing amongst other things a couple of date columns....  |
|  [Which datatypes are supported by MariaDB](../which-datatypes-are-supported-by-mariadb/index) |  I would like to know which datatypes are supported by MariaDB. I'm asking s...  |

 ### Other Data Types Articles

 

| Title | Description |
| --- | --- |
|  [Geometry Types](../geometry-types/index) |  Supported geometry types.  |
|  [AUTO\_INCREMENT](../auto_increment/index) |  Automatic increment.  |
|  [Data Type Storage Requirements](../data-type-storage-requirements/index) |  Storage requirements for the various data types.  |
|  [AUTO\_INCREMENT FAQ](../auto_increment-faq/index) |  Frequently-asked questions about auto\_increment.  |
|  [NULL Values](../null-values/index) |  NULL represents an unknown value.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-types/>

Partitioning Overview
=====================

     In MariaDB, a table can be split in smaller subsets. Both data and indexes are partitioned.

 Uses for partitioning
---------------------

 There can be several reasons to use this feature:

 * Very big tables and indexes can be slow even with optimized queries. But if the target table is partitioned, queries that read a small number of partitions can be much faster.
* Partitioning allows one to distribute files over multiple storage devices. For example, we can have historical data on slower, larger disks (historical data are not supposed to be frequently read); and current data can be on faster disks, or SSD devices.
* In case we separate historical data from recent data, we will probably need to take regular backups of one partition, not the whole table.

 ### Partitioning for specific storage engines

 Some MariaDB [storage engines](../storage-engines/index) allow more interesting uses for partitioning.

 [SPIDER](../spider/index) allows one to:

 * Move partitions of the same table on different servers. In this way, the workload can be distributed on more physical or virtual machines (*data sharding*).
* All partitions of a SPIDER table can also live on the same machine. In this case there will be a small overhead (SPIDER will use connections to localhost), but queries that read multiple partitions will use parallel threads.

 [CONNECT](../connect/index) allows one to:

 * Build a table whose partitions are tables using different storage engines (like InnoDB, MyISAM, or even engines that do not support partitioning).
* Build an indexable, writeable table on several data files. These files can be in different formats.

 See also: [Using CONNECT - Partitioning and Sharding](../using-connect-partitioning-and-sharding/index)

 Partitioning types
------------------

 When partitioning a table, the use should decide:

 * a *partitioning type*;
* a *partitioning expression*.

 A partitioning type is the method used by MariaDB to decide how rows are distributed over existing partitions. Choosing the proper partitioning type is important to distribute rows over partitions in an efficient way.

 With some partitioning types, a partitioning expression is also required. A partitioning function is an SQL expression returning an integer or temporal value, used to determine which row will contain a given row. The partitioning expression is used for all reads and writes on involving the partitioned table, thus it should be fast.

 See [Partioning Types](../partitioning-types/index) for a detailed description.

 How to use partitioning
-----------------------

 By default, MariaDB permits partitioning. You can determine this by using the [SHOW PLUGINS](../show-plugins/index) statement, for example:

 
```
SHOW PLUGINS;
...
| Aria                          | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| FEEDBACK                      | DISABLED | INFORMATION SCHEMA | NULL    | GPL     |
| partition                     | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
+-------------------------------+----------+--------------------+---------+---------+

```

If partition is listed as DISABLED:

 
```
| partition                     | DISABLED | STORAGE ENGINE     | NULL    | GPL     |
+-------------------------------+----------+--------------------+---------+---------+

```

MariaDB has either been built without partitioning support, or has been started with the the [--skip-partition](../mysqld-options/index#-skip-partition) option, or one of its variants:

 
```
--skip-partition
--disable-partition
--partition=OFF

```

and you will not be able to create partitions.

 It is possible to create a new partitioned table using [CREATE TABLE](../create-table/index).

 [ALTER TABLE](../alter-table/index) allows one to:

 * Partition an existing table;
* Remove partitions from a partitioned table (**with all data in the partition**);
* Add/remove partitions, or reorganize them, as long as the partitioning function allows these operations (see below);
* Exchange a partition with a table;
* Perform administrative operations on some or all partitions (analyze, optimize, check, repair).

 The [INFORMATION\_SCHEMA.PARTITIONS](../information-schema-partitions-table/index) table contains information about existing partitions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitioning-overview/>

Partitioning Types
===================

  

| Title | Description |
| --- | --- |
|  [Partitioning Types Overview](../partitioning-types-overview/index) |  A partition type determines how a partitioned table rows are distributed across partitions  |
|  [LIST Partitioning Type](../list-partitioning-type/index) |  LIST partitioning is used to assign each partition a list of values  |
|  [RANGE Partitioning Type](../range-partitioning-type/index) |  The RANGE partitioning type is used to assign each partition a range of values.  |
|  [HASH Partitioning Type](../hash-partitioning-type/index) |  Form of partitioning in which the server takes care of the partition in which to place the data.  |
|  [KEY Partitioning Type](../key-partitioning-type/index) |  Used to have the server assign the distribution of rows across partitions.  |
|  [RANGE COLUMNS and LIST COLUMNS Partitioning Types](../range-columns-and-list-columns-partitioning-types/index) |  Used to assign each partition a range or a list of values  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitioning-types/>

Partition Pruning and Selection
===============================

    When a WHERE clause is related to the partitioning expression, the optimizer knows which partitions are relevant for the query. Other partitions will not be read. This optimization is called *partition pruning*.

 [EXPLAIN PARTITIONS](../explain/index) can be used to know which partitions will be read for a given query. A column called `partitions` will contain a comma-separated list of the accessed partitions. For example:

 
```
EXPLAIN PARTITIONS SELECT * FROM orders WHERE id < 15000000;
+------+-------------+--------+------------+-------+---------------+---------+---------+------+------+-------------+
| id   | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+------+-------------+--------+------------+-------+---------------+---------+---------+------+------+-------------+
|    1 | SIMPLE      | orders | p0,p1      | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+------+-------------+--------+------------+-------+---------------+---------+---------+------+------+-------------+

```

Sometimes the WHERE clause does not contain the necessary information to use partition pruning, or the optimizer cannot infer this information. However, we may know which partitions are relevant for the query. Since [MariaDB 10.0](../what-is-mariadb-100/index), we can force MariaDB to only access the specified partitions by adding a PARTITION clause. This feature is called *partition selection*. For example:

 
```
SELECT * FROM orders PARTITION (p3) WHERE user_id = 50;
SELECT * FROM orders PARTITION (p2,p3) WHERE user_id >= 40;

```

The PARTITION clause is supported for all DML statements:

 * [SELECT](../select/index)
* [INSERT](../insert/index)
* [UPDATE](../update/index)
* [DELETE](../delete/index)
* [REPLACE](../replace/index)

 Partition Pruning and Triggers
------------------------------

 In general, partition pruning is applied to statements contained in [triggers](../triggers/index).

 However, note that if a `BEFORE INSERT` or `BEFORE UPDATE` trigger is defined on a table, MariaDB doesn't know in advance if the columns used in the partitioning expression will be changed. For this reason, it is forced to lock all partitions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partition-pruning-and-selection/>

Partition Maintenance
=====================

    Preface
-------

 This article covers

 * PARTITIONing uses and non-uses
* How to Maintain a time-series PARTITIONed table
* AUTO\_INCREMENT secrets

 First, my Opinions on PARTITIONing

 Taken from [Rick's RoTs - Rules of Thumb](http://mysql.rjweb.org/doc.php/ricksrots)

 * #1: Don't use [PARTITIONing](../managing-mariadb-partitioning/index) until you know how and why it will help.
* Don't use PARTITION unless you will have >1M rows
* No more than 50 PARTITIONs on a table (open, show table status, etc, are impacted) (fixed in MySQL 5.6.6?; a better fix coming eventually in 5.7)
* PARTITION BY RANGE is the only useful method.
* SUBPARTITIONs are not useful.
* The partition field should not be the field first in any key.
* It is OK to have an [AUTO\_INCREMENT](../auto_increment/index) as the first part of a compound key, or in a non-UNIQUE index.

 It is so tempting to believe that PARTITIONing will solve performance problems. But it is so often wrong.

 PARTITIONing splits up one table into several smaller tables. But table size is rarely a performance issue. Instead, I/O time and indexes are the issues.

 A common fallacy: "Partitioning will make my queries run faster". It won't. Ponder what it takes for a 'point query'. Without partitioning, but with an appropriate index, there is a BTree (the index) to drill down to find the desired row. For a billion rows, this might be 5 levels deep. With partitioning, first the partition is chosen and "opened", then a smaller BTree (of say 4 levels) is drilled down. Well, the savings of the shallower BTree is consumed by having to open the partition. Similarly, if you look at the disk blocks that need to be touched, and which of those are likely to be cached, you come to the conclusion that about the same number of disk hits is likely. Since disk hits are the main cost in a query, Partitioning does not gain any performance (at least for this typical case). The 2D case (below) gives the main contradiction to this discussion.

 Use Cases for PARTITIONing
--------------------------

 **Use case #1 -- time series**. Perhaps the most common use case where PARTITIONing shines is in a dataset where "old" data is periodically deleted from the table. RANGE PARTITIONing by day (or other unit of time) lets you do a nearly instantaneous DROP PARTITION plus REORGANIZE PARTITION instead of a much slower DELETE. Much of this blog is focused on this use case. This use case is also discussed in [Big DELETEs](../big-deletes/index)

 The big win for Case #1: DROP PARTITION is a lot faster than DELETEing a lot of rows.

 **Use case #2 -- 2-D index**. INDEXes are inherently one-dimensional. If you need two "ranges" in the WHERE clause, try to migrate one of them to PARTITIONing.

 Finding the nearest 10 pizza parlors on a map needs a 2D index. Partition pruning sort of gives a second dimension. See Latitude/Longitude Indexing That uses PARTITION BY RANGE(latitude) together with PRIMARY KEY(longitude, ...)

 The big win for Case #2: Scanning fewer rows.

 **Use case #3 -- hot spot**. This is a bit complicated to explain. Given this combination:

 * A table's index is too big to be cached, but the index for one partition is cacheable, and
* The index is randomly accessed, and
* Data ingestion would normally be I/O bound due to updating the index Partitioning can keep all the index "hot" in RAM, thereby avoiding a lot of I/O.

 The big win for Case #3: Improving caching to decrease I/O to speed up operations.

 AUTO\_INCREMENT in PARTITION
----------------------------

 * For [AUTO\_INCREMENT](../auto_increment/index) to work (in any table), it must be the first field in some index. Period. There are no other requirements on indexing it.
* Being the first field in some index lets the engine find the 'next' value when opening the table.
* AUTO\_INCREMENT need not be UNIQUE. What you lose: prevention of explicitly inserting a duplicate id. (This is rarely needed, anyway.)

 Examples (where id is AUTO\_INCREMENT):

 * PRIMARY KEY (...), INDEX(id)
* PRIMARY KEY (...), UNIQUE(id, partition\_key) -- not useful
* INDEX(id), INDEX(...) (but no UNIQUE keys)
* PRIMARY KEY(id), ... -- works only if id is the partition key (not very useful)

 PARTITION maintenance for the time-series case
----------------------------------------------

 Let's focus on the maintenance task involved in Case #1, as described above.

 You have a large table that is growing on one end and being pruned on the other. Examples include news, logs, and other transient information. PARTITION BY RANGE is an excellent vehicle for such a table.

 * DROP PARTITION is much faster than DELETE. (This is the big reason for doing this flavor of partitioning.)
* Queries often limit themselves to 'recent' data, thereby taking advantage of "partition pruning".

 Depending on the type of data, and how long before it expires, you might have daily or weekly or hourly (etc) partitions.

 There is no simple SQL statement to "drop partitions older than 30 days" or "add a new partition for tomorrow". It would be tedious to do this by hand every day.

 High level view of the code
---------------------------

 
```
ALTER TABLE tbl
    DROP PARTITION from20120314;
ALTER TABLE tbl
    REORGANIZE PARTITION future INTO (
        PARTITION from20120415 VALUES LESS THAN (TO_DAYS('2012-04-16')),
        PARTITION future     VALUES LESS THAN MAXVALUE);

```

After which you have...

 
```
    CREATE TABLE tbl (
        dt DATETIME NOT NULL,  -- or DATE
        ...
        PRIMARY KEY (..., dt),
        UNIQUE KEY (..., dt),
        ...
    )
    PARTITION BY RANGE (TO_DAYS(dt)) (
        PARTITION start        VALUES LESS THAN (0),
        PARTITION from20120315 VALUES LESS THAN (TO_DAYS('2012-03-16')),
        PARTITION from20120316 VALUES LESS THAN (TO_DAYS('2012-03-17')),
        ...
        PARTITION from20120414 VALUES LESS THAN (TO_DAYS('2012-04-15')),
        PARTITION from20120415 VALUES LESS THAN (TO_DAYS('2012-04-16')),
        PARTITION future       VALUES LESS THAN MAXVALUE
    );

```

Why?
----

 Perhaps you noticed some odd things in the example. Let me explain them.

 * Partition naming: Make them useful.
* from20120415 ... 04-16: Note that the LESS THAN is the next day's date
* The "start" partition: See paragraph below.
* The "future" partition: This is normally empty, but it can catch overflows; more later.
* The range key (dt) must be included in any PRIMARY or UNIQUE key.
* The range key (dt) should be last in any keys it is in -- You have already "pruned" with it; it is almost useless in the index, especially at the beginning.
* DATETIME, etc -- I picked this datatype because it is typical for a time series. Newer MySQL versions allow TIMESTAMP. INT could be used; etc.
* There is an extra day (03-16 thru 04-16): The latest day is only partially full.

 Why the bogus "start" partition? If an invalid datetime (Feb 31) were to be used, the datetime would turn into NULL. NULLs are put into the first partition. Since any SELECT could have an invalid date (yeah, this stretching things), the partition pruner always includes the first partition in the resulting set of partitions to search. So, if the SELECT must scan the first partition, it would be slightly more efficient if that partition were empty. Hence the bogus "start" partition. Longer discussion, by The Data Charmer 5.5 eliminates the bogus check, but only if you switch to a new syntax:

 
```
    PARTITION BY RANGE COLUMNS(dt) (
    PARTITION day_20100226 VALUES LESS THAN ('2010-02-27'), ...

```

More on the "future" partition. Sooner or later the cron/EVENT to add tomorrow's partition will fail to run. The worst that could happen is for tomorrow's data to be lost. The easiest way to prevent that is to have a partition ready to catch it, even if this partition is normally always empty.

 Having the "future" partition makes the ADD PARTITION script a little more complex. Instead, it needs to take tomorrow's data from "future" and put it into a new partition. This is done with the REORGANIZE command shown. Normally nothing need be moved, and the ALTER takes virtually zero time.

 When to do the ALTERs?
----------------------

 * DROP if the oldest partition is "too old".
* Add 'tomorrow' near the end of today, but don't try to add it twice.
* Do not count partitions -- there are two extra ones. Use the partition names or information\_schema.PARTITIONS.PARTITION\_DESCRIPTION.
* DROP/Add only once in the script. Rerun the script if you need more.
* Run the script more often than necessary. For daily partitions, run the script twice a day, or even hourly. Why? Automatic repair.

 Variants
--------

 As I have said many times, in many places, BY RANGE is perhaps the only useful variant. And a time series is the most common use for PARTITIONing.

 * (as discussed here) DATETIME/DATE with TO\_DAYS()
* DATETIME/DATE with TO\_DAYS(), but with 7-day intervals
* TIMESTAMP with TO\_DAYS(). (version 5.1.43 or later)
* PARTITION BY RANGE COLUMNS(DATETIME) (5.5.0)
* PARTITION BY RANGE(TIMESTAMP) (version 5.5.15 / 5.6.3)
* PARTITION BY RANGE(TO\_SECONDS()) (5.6.0)
* INT UNSIGNED with constants computed as unix timestamps.
* INT UNSIGNED with constants for some non-time-based series.
* MEDIUMINT UNSIGNED containing an "hour id": FLOOR(FROM\_UNIXTIME(timestamp) / 3600)
* Months, Quarters, etc: Concoct a notation that works.

 How many partitions?

 * Under, say, 5 partitions -- you get very little of the benefits.
* Over, say, 50 partitions, and you hit inefficiencies elsewhere.
* Certain operations (SHOW TABLE STATUS, opening the table, etc) open every partition.
* [MyISAM](../myisam/index), before version 5.6.6, would lock all partitions before pruning!
* Partition pruning does not happen on INSERTs (until Version 5.6.7), so INSERT needs to open all the partitions.
* A possible 2-partition use case: <http://forums.mysql.com/read.php?24,633179,633179>
* 8192 partitions is a hard limit (1024 before 5.6.7).
* Before "native partitions" (5.7.6), each partition consumed a chunk of memory.

 Detailed code
-------------

 [Reference implementation, in Perl, with demo of daily partitions](http://mysql.rjweb.org/demo_part_maint.pl.txt)

 The complexity of the code is in the discovery of the PARTITION names, especially of the oldest and the 'next'.

 To run the demo,

 * Install Perl and DBIx::DWIW (from CPAN).
* copy the txt file (link above) to demo\_part\_maint.pl
* execute perl demo\_part\_maint.pl to get the rest of the instructions

 The program will generate and execute (when needed) either of these:

 
```
   ALTER TABLE tbl REORGANIZE PARTITION
        future
   INTO (
        PARTITION from20150606 VALUES LESS THAN (736121),
        PARTITION future VALUES LESS THAN MAXVALUE
   )

   ALTER TABLE tbl
                    DROP PARTITION from20150603

```

Postlog
-------

 Original writing -- Oct, 2012; Use cases added: Oct, 2014; Refreshed: June, 2015; 8.0: Sep, 2016 

 [Slides from Percona Amsterdam 2015](http://mysql.rjweb.org/slides/Partition.pdf)

 PARTITIONing requires at least MySQL 5.1

 The tips in this document apply to MySQL, MariaDB, and Percona.

 * [More on PARTITIONing](http://www.mysqlperformanceblog.com/2010/12/11/mysql-partitioning-can-save-you-or-kill-you/)
* [LinkedIn discussion](http://www.linkedin.com/groups/MySql-Horizontal-partitioning-ProsCons-78638.S.5861525157444595715?qid=0d54d3f9-21d7-43e8-9b75-dbc0270c7236&trk=groups_guest_most_popular-0-b-ttl&goback=%2Egmp_78638)
* [Why NOT Partition](http://dba.stackexchange.com/questions/107408/why-not-partition)
* [Geoff Montee's Stored Proc](http://www.geoffmontee.com/automatically-dropping-old-partitions-in-mysql-and-mariadb-part-2/)

 Future (as envisioned in 2016):

 * MySQL 5.7.6 has "native partitioning for InnoDB".
* FOREIGN KEY support, perhaps in a later 8.0.xx.
* "GLOBAL INDEX" -- this would avoid the need for putting the partition key in every unique index, but make DROP PARTITION costly. This will be farther into the future.

 MySQL 8.0, released Sep, 2016, not yet GA)

 * Only InnoDB tables can be partitioned -- MariaDB is likely to continue maintaining Partitioning on non-InnoDB tables, but Oracle is clearly not.
* Some of the problems having lots of partitions are lessened by the Data-Dictionary-in-a-table.

 Native partitioning will give:

 * This will improve performance slightly by combining two "handlers" into one.
* Decreased memory usage, especially when using a large number of partitions.

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/partitionmaint>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partition-maintenance/>

Partitioning Limitations with MariaDB
=====================================

    The following limitations apply to partitioning in MariaDB:

 * Each table can contain a maximum of 8192 partitions (from [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/)). In [MariaDB 5.5](../what-is-mariadb-55/index) and until 10.0.3, the limit was 1024.
* Currently, queries are never parallelized, even when they involve multiple partitions.
* A table can only be partitioned if the storage engine supports partitioning.
* All partitions must use the same storage engine. For a workaround, see [Using CONNECT - Partitioning and Sharding](../using-connect-partitioning-and-sharding/index).
* A partitioned table cannot contain, or be referenced by, [foreign keys](../foreign-keys/index).
* The [query cache](../query-cache/index) is not aware of partitioning and partition pruning. Modifying a partition will invalidate the entries related to the whole table.
* Updates can run more slowly when binlog\_format=ROW and a partitioned table is updated than an equivalent update of a non-partitioned table.
* All columns used in the partitioning expression for a partitioned table must be part of every unique key that the table may have.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitioning-limitations/>

Partitions Metadata
===================

    The [PARTITIONS](../information-schema-partitions-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database contains information about partitions.

 The [SHOW TABLE STATUS](../show-table-status/index) statement contains a `Create_options` column, that contains the string 'partitioned' for partitioned tables.

 The [SHOW CREATE TABLE](../show-create-table/index) statement returns the [CREATE TABLE](../create-table/index) statement that can be used to re-create a table, including the partitions definition.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitions-metadata/>

Partitions Files
================

    A partitioned table is stored in multiple files. By default, these files are stored in the MariaDB (or InnoDB) data directory. It is possible to keep them in different paths by specifying [DATA\_DIRECTORY and INDEX\_DIRECTORY](../create-table/index#data-directoryindex-directory) table options. This is useful to store different partitions on different devices.

 
Note that, if the [innodb\_file\_per\_table](../xtradbinnodb-server-system-variables/index#innodb_file_per_table) server system variable is set to 0 at the time of the table creation, all partitions will be stored in the system tablespace.

 
The following files exist for each partitioned tables:

 


| File name | Notes |
| --- | --- |
| table\_name.frm | Contains the table definition. Non-partitioned tables have this file, too. |
| table\_name.par | Contains the partitions definitions. |
| table\_name#P#partition\_name.ext | Normal files created by the storage engine use this pattern for names. The extension depends on the storage engine. |

 
For example, an InnoDB table with 4 partitions will have the following files:

 
```
orders.frm
orders.par
orders#P#p0.ibd
orders#P#p1.ibd
orders#P#p2.ibd
orders#P#p3.ibd

```

If we convert the table to MyISAM, we will have these files:

 
```
orders.frm
orders.par
orders#P#p0.MYD
orders#P#p0.MYI
orders#P#p1.MYD
orders#P#p1.MYI
orders#P#p2.MYD
orders#P#p2.MYI
orders#P#p3.MYD
orders#P#p3.MYI

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitions-files/>

MariaDB Performance & Advanced Configurations
==============================================

   Articles of how to setup your MariaDB optimally on different systems

  

| Title | Description |
| --- | --- |
|  [Fusion-io](../fusion-io/index) |  This category contains information about Fusion-io support in MariaDB  |
|  [Atomic Write Support](../atomic-write-support/index) |  Enabling atomic writes to speed up InnoDB on selected SSD cards.  |
|  [Configuring Linux for MariaDB](../configuring-linux-for-mariadb/index) |  Linux kernel settings IO scheduler For optimal IO performance running a da...  |
|  [Configuring MariaDB for Optimal Performance](../configuring-mariadb-for-optimal-performance/index) |  How to get optimal performance.  |
|  [Configuring Swappiness](../configuring-swappiness/index) |  Setting Linux swappiness.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-performance-advanced-configurations/>

Downgrading between Major Versions of MariaDB
=============================================

    Downgrading MariaDB is not officially supported between major versions.

 For minor versions, upgrade is supported to an earlier [gamma/RC/GA](../release-criteria/index#commitment-for-gammarc-releases) version as we do not change the storage format after [Alpha](../release-criteria/index#commitment-for-alpha-releases) and very rarely during [Beta](../release-criteria/index#commitment-for-beta-releases) (it has to be a very critical bug to require such a change). There are a few very rare cases when incompatible changes happen on a GA version, for example [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) fixed a file format incompatibility bug that prevents a downgrade to earlier [MariaDB 10.1](../what-is-mariadb-101/index) releases. After [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) this has not happened in a GA release.

 The main reason why downgrades between major versions do not work are:

 * Changes in the privilege/status tables in the [mysql schema](../the-mysql-database-tables/index). These changes happen between most major versions as we are continuously improving the privilege system.
* Changes that affect how data is stored on disk. This happens more rarely and is usually table specific. For example, if one has used [Instant add column](../instant-add-column-for-innodb/index) on a table in [MariaDB 10.3](../what-is-mariadb-103/index), that table cannot be opened in [MariaDB 10.2](../what-is-mariadb-102/index).
* Between major releases there are often substantial changes, even if none of the new features are used. For example, both [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index) introduce new versions of the redo log.

 The only reliable way to downgrade is to [restore from a full backup](../backing-up-and-restoring-databases/index) made before upgrading, and start the old version of MariaDB. At least one should take a backup of the [mysql](../the-mysql-database-tables/index) schema as most upgrade changes happens in this directory. This may be of help if one needs to downgrade to an earlier MariaDB version. More about this later.

 Some people have reported successfully downgrading, but there are many possible things that can go wrong, and downgrading between two major versions is not tested in any way by the MariaDB developers.

 In general, one can downgrade a major version to an earlier version if one has not yet run [mariadb-upgrade](../mariadb-upgrade/index) on the new version. Note however that it's recommended that one always uses [mariadb-upgrade](../mariadb-upgrade/index) after upgrading to a new major version as otherwise some security features in the new server may not work and tables that have indexes using a character collation that has changed may not work properly.

 Assuming one **must** downgrade to an earlier major version, here is a list of things one has to do:

 * MariaDB **must** be shut down cleanly. This means that:
	+ One should ensure that [innodb\_fast\_shutdown is set to 0](../innodb-system-variables/index#innodb_fast_shutdown).
	+ One uses the [SHUTDOWN](../shutdown/index) command, [mariadb-admin shutdown](../mariadb-admin/index) or the operating system official commands, like [systemctl stop mariadb.service](../systemd/index#stopping-the-mariadb-server-process).
* Start the old server with [--skip-privilege-tables](../mariadbd-options/index#-skip-grant-tables).
* Use ALTER TABLE to restore the [mysql schema tables](../the-mysql-database-tables/index) to their original definition or drop and recreate the mysql tables. One can find the old definition by using [mariadb-install-db](../mariadb-install-db/index) to create a separate temporary data directory. Starting the MariaDB server on the temporary directory will allow you to use [SHOW CREATE TABLE](../show-create-table/index) to find the old definition.
* Execute [FLUSH PRIVILEGES](../flush/index) to reload the old tables.

 The cases when the above will not work are when the table format has changed in an incompatible manner. In this case the affected tables may not be usable in the earlier version.

 The following is an incomplete list of when one will not be able to use a table in an earlier major version:

 * [MariaDB 10.4](../what-is-mariadb-104/index) -> [MariaDB 10.3](../what-is-mariadb-103/index)
	+ Any InnoDB table where one has used `ALTER TABLE ALGORITHM=INSTANT DROP COLUMN`
	+ In [MariaDB 10.4](../what-is-mariadb-104/index), the MariaDB mysql.user table was replaced by [mysql.global\_priv table](../mysql-user-table/index) which may cause problems if ones wants to downgrade to 10.3.
* [MariaDB 10.3](../what-is-mariadb-103/index) -> [MariaDB 10.2](../what-is-mariadb-102/index)
	+ Any InnoDB table where one has used `ALTER TABLE ALGORITHM=INSTANT ADD COLUMN`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/downgrading-between-major-versions-of-mariadb/>

Installing System Tables (mariadb-install-db)
=============================================

    `mariadb-install-db` initializes the MariaDB data directory and creates the [system tables](../system-tables/index) in the [mysql](../the-mysql-database-tables/index) database, if they do not exist. MariaDB uses these tables to manage [privileges](../grant/index#privilege-levels), [roles](../roles/index), and [plugins](../plugins/index). It also uses them to provide the data for the [help](../help-command/index) command in the [mariadb](../mariadb-command-line-client/index) client.

 [mariadb-install-db](../mariadb-install-db/index) works by starting MariaDB Server's `mysqld` process in [--bootstrap](../mysqld-options/index#-bootstrap) mode and sending commands to create the [system tables](../system-tables/index) and their content.

 There is a version specifically for Windows, [mysql\_install\_db.exe](../mysql_install_dbexe/index).

 To invoke `mariadb-install-db`, use the following syntax:

 
```
mariadb-install-db --user=mysql

```

For the options supported by [mariadb-install-db](../mariadb-install-db/index), see [mariadb-install-db: Options](../mariadb-install-db/index#options).

 For the option groups read by [mariadb-install-db](../mariadb-install-db/index), see [mariadb-install-db: Option Groups](../mariadb-install-db/index#option-groups).

 See [mariadb-install-db: Installing System Tables](../mariadb-install-db/index#installing-system-tables) for information on the installation process.

 See [mariadb-install-db: Troubleshooting Issues](../mariadb-install-db/index#troubleshooting-issues) for information on how to troubleshoot the installation process.

 See Also
--------

 * [mariadb-install-db](../mariadb-install-db/index)
* The Windows version of `mariadb-install-db`: [mysql\_install\_db.exe](../mysql_install_dbexe/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-system-tables-mariadb-install-db/>

Starting and Stopping MariaDB
==============================

  

| Title | Description |
| --- | --- |
|  [Starting and Stopping MariaDB Server](../starting-and-stopping-mariadb-automatically/index) |  Starting MariaDB, including details on service managers.  |
|  [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index) |  Configuring MariaDB with my.cnf and other option files.  |
|  [mysqld Configuration Files and Groups](../mysqld-configuration-files-and-groups/index) |  Which configuration files and groups mysqld reads.  |
|  [mariadbd Options](../mariadbd-options/index) |  Lists of all the options for mariadbd (previously called mysqld).  |
|  [What to Do if MariaDB Doesn't Start](../what-to-do-if-mariadb-doesnt-start/index) |  Troubleshooting MariaDB when it fails to start.  |
|  [Running MariaDB from the Build Directory](../running-mariadb-from-the-build-directory/index) |  Running mariadbd (mysqld) directly from the source directory without make install.  |
|  [mysql.server](../mysqlserver/index) |  Startup script included in MariaDB distributions on Unix  |
|  [mysqld\_safe](../mysqld_safe/index) |  Recommended way to start a mysqld server on a non-systemd Unix.  |
|  [mysqladmin](../mysqladmin/index) |  Old name or symlink for mariadb-admin.  |
|  [Switching Between Different Installed MariaDB Versions](../switching-between-different-installed-mariadb-versions/index) |  Managing different installed MariaDB versions and running them one at a time  |
|  [Running Multiple MariaDB Server Processes](../running-multiple-mariadb-server-processes/index) |  Running multiple MariaDB Server processes on the same server.  |
|  [Specifying Permissions for Schema (Data) Directories and Tables](../specifying-permissions-for-schema-data-directories-and-tables/index) |  MariaDB uses the following modes for creating directories and files  |
|  [mysqld\_multi](../mysqld_multi/index) |  Manage several mysqld processes.  |
|  [launchd](../launchd/index) |  launchd is the startup service used in MacOS X.  |
|  [systemd](../systemd/index) |  How systemd is configured on MariaDB packages and how to alter its configuration.  |
|  [sysVinit](../sysvinit/index) |  sysVinit is one of the most common service managers for Linux and Unix.  |
|  [mariadb-admin](../mariadb-admin/index) |  Admin tool for monitoring, creating/dropping databases, stopping MariaDB etc.  |
|  [mariadbd](../mariadbd/index) |  Symlink or new name for mysqld.  |
|  [mariadbd-multi](../mariadbd-multi/index) |  Symlink or new name for mysqld\_multi.  |
|  [mariadbd-safe](../mariadbd-safe/index) |  Symlink or new name for mysqld\_safe.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/starting-and-stopping-mariadb/>

Troubleshooting Installation Issues
====================================

   Articles relating to installation issues users might run into.

  

| Title | Description |
| --- | --- |
|  [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index) |  Common problems when trying to connect to MariaDB.  |
|  [Installation issues on Windows](../installation-issues-on-windows/index) |  Issues people have encountered when installing MariaDB on Windows  |
|  [Troubleshooting MariaDB Installs on Red Hat/CentOS](../troubleshooting-mariadb-installs-on-red-hatcentos/index) |  Issues people have encountered when installing MariaDB on Red Hat / CentOS  |
|  [Installation issues on Debian and Ubuntu](../installation-issues-on-debian-and-ubuntu/index) |  Solutions to different installation issues on Debian and Ubuntu  |
|  [What to Do if MariaDB Doesn't Start](../what-to-do-if-mariadb-doesnt-start/index) |  Troubleshooting MariaDB when it fails to start.  |
|  [Installing on an Old Linux Version](../installing-on-an-old-linux-version/index) |  Typical errors from using an incompatible MariaDB binary on a linux system  |
|  [Error: symbol mysql\_get\_server\_name, version libmysqlclient\_16 not defined](../error-symbol-mysql_get_server_name-version-libmysqlclient_16-not-defined/index) |  Error from using MariaDB's mysql command-line client with MySQL's libmysqlclient.so  |
|  [Installation Issues with PHP5](../installation-issues-with-php5/index) |  PHP5 may give an error if used with the old connect method  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/troubleshooting-installation-issues/>

mysql\_install\_db.exe
======================

     The `mysql_install_db.exe` utility is the Windows equivalent of [mysql\_install\_db](../mysql_install_db/index).

 Functionality
-------------

 The functionality of `mysql_install_db.exe` is comparable with the shell script `mysql_install_db` used on Unix, however it has been extended with both Windows specific functionality (creating a Windows service) and to generally useful functionality. For example, it can set the 'root' user password during database creation. It also creates the `my.ini` configuration file in the data directory and adds most important parameters to it (e.g port).

 `mysql_install_db.exe` is used by the MariaDB installer for Windows if the "Database instance" feature is selected. It obsoletes similar utilities and scripts that were used in the past such as `mysqld.exe` ``--`install`, `mysql_install_db.pl`, and `mysql_secure_installation.pl`.

 


| Parameter | Description |
| --- | --- |
| `-?`, ``--`help` | Display help message and exit |
| `-d`, ``--`datadir=name` | Data directory of the new database |
| `-S`, ``--`service=name` | Name of the Windows service |
| `-p`, ``--`password=name` | Password of the root user |
| `-P`, ``--`port=#`  | `mysqld` port |
| `-W`, ``--`socket=name` | named pipe name |
| `-D`, ``--`default-user` | Create default user |
| `-R`, ``--`allow-remote-root-access` | Allow remote access from network for user root |
| `-N`, ``--`skip-networking` | Do not use TCP connections, use pipe instead |
| `-i`, ``--`innodb-page-size` | Innodb page size, since [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) |
| `-s`,``--`silent` | Print less information |
| `-o`,``--`verbose-bootstrap` | Include mysqld bootstrap output |
| `-l`,``--`large-pages` | Use large pages, since [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) |
| `-c`,``--`config` | my.ini config template file, since [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) |

 
**Note** : to create a Windows service, `mysql_install_db.exe` should be run by a user with full administrator privileges (which means elevated command prompt on systems with UAC). For example, if you are running it on Windows 7, make sure that your command prompt was launched via 'Run as Administrator' option.

 Example
-------

 
```
  mysql_install_db.exe --datadir=C:\db --service=MyDB --password=secret

```

will create the database in the directory C:\db, register the auto-start Windows service "MyDB", and set the root password to 'secret'.

 To start the service from the command line, execute

 
```
sc start MyDB

```

Removing Database Instances
---------------------------

 If you run your database instance as service, to remove it completely from the command line, use

 
```
sc stop <servicename>
sc delete <servicename>
rmdir /s /q <path-to-datadir>

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_install_dbexe/>

Compiling MariaDB From Source
==============================

  

| Title | Description |
| --- | --- |
|  [Get, Build and Test Latest MariaDB the Lazy Way](../get-build-and-test-latest-mariadb-the-lazy-way/index) |  Instructions for people who don't have time to read the whole manual.  |
|  [MariaDB Source Code](../getting-the-mariadb-source-code/index) |  How to get the source code for MariaDB from GitHub.  |
|  [Build Environment Setup for Linux](../build_environment_setup_for_linux/index) |  Requirements and build environment setup for Linux.  |
|  [Generic Build Instructions](../generic-build-instructions/index) |  Instructions to help compile MariaDB from source.  |
|  [Compiling MariaDB with Extra Modules/Options](../compiling-mariadb-with-extra-modulesoptions/index) |  Articles on compiling MariaDB with extra modules and options  |
|  [Creating the MariaDB Source Tarball](../creating_the_mariadb_source_tarball/index) |  How to create a source tar.gz file  |
|  [Creating the MariaDB Binary Tarball](../creating-the-mariadb-binary-tarball/index) |  How to generate binary tar.gz files.  |
|  [Build Environment Setup for Mac](../build_environment_setup_for_mac/index) |  Setting up the build environment for Mac  |
|  [Building MariaDB from a Source RPM](../building-mariadb-from-a-source-rpm/index) |  How to build MariaDB from a source RPM (SRPM).  |
|  [Building MariaDB on CentOS](../source-building-mariadb-on-centos/index) |  CentOS build requirements and steps.  |
|  [Building MariaDB on Fedora](../building-mariadb-on-fedora/index) |  Guide to building MariaDB from source code on Fedora Linux.  |
|  [Building MariaDB on Debian](../building-mariadb-on-debian/index) |  Steps to compiling MariaDB on Debian Linux.  |
|  [Building MariaDB on FreeBSD](../building-mariadb-on-freebsd/index) |  How to build MariaDB on FreeBSD.  |
|  [Building MariaDB on Gentoo](../building_mariadb_on_gentoo/index) |  Steps to build MariaDB on Gentoo  |
|  [Building MariaDB on Solaris and OpenSolaris](../building-mariadb-on-solaris-and-opensolaris/index) |  Links and notes for building MariaDB on Solaris and OpenSolaris  |
|  [Building MariaDB on Ubuntu](../building-mariadb-on-ubuntu/index) |  Requirements and steps for building MariaDB on Ubuntu.  |
|  [Building MariaDB on Windows](../building_mariadb_on_windows/index) |  Instructions for building MariaDB on Windows.  |
|  [Installing MariaDB Server on macOS Using Homebrew](../installing-mariadb-on-macos-using-homebrew/index) |  Installing MariaDB on macOS via the Homebrew package manager, the "missing ...  |
|  [Compiling with the InnoDB Plugin from Oracle](../compiling-with-the-innodb-plugin-from-oracle/index) |  Compiling MariaDB with the InnoDB plugin from Oracle.  |
|  [Creating a Debian Repository](../creating_a_debian_repository/index) |  Instructions for creating your own Debian repository  |
|  [Building MariaDB From Source Using musl-based GNU/Linux](../building-mariadb-from-source-using-musl-based-gnulinux/index) |  Instructions on compiling MariaDB on musl-based operating systems (Alpine)  |
|  [Compiling MariaDB for Debugging](../compiling-mariadb-for-debugging/index) |  Passing -DCMAKE\_BUILD\_TYPE=Debug to cmake to compile with debug information.  |
|  [Cross-compiling MariaDB](../cross-compiling-mariadb/index) |  To cross-compile with cmake you will need a toolchain file  |
|  [MariaDB Source Configuration Options](../compiling-mariadb-from-source-mariadb-source-configuration-options/index) |  Options for configuring a MariaDB source distribution.  |
|  [Building RPM Packages From Source](../building-rpm-packages-from-source/index) |  Building MariaDB RPM packages with CMake and CPackRPM.  |
|  [Compile and Using MariaDB with Sanitizers (ASAN, UBSAN, TSAN, MSAN)](../compile-and-using-mariadb-with-sanitizers-asan-ubsan-tsan-msan/index) |  How to compile and use MariaDB with AddressSanitizer (ASAN).  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-from-source/>

Puppet and MariaDB
==================

    See the [Puppet and MariaDB](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index) category.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/puppet-and-mariadb/>

MariaDB Binary Packages
========================

   This section contains information on and installation instructions for [MariaDB binaries and packages](https://downloads.mariadb.org/mariadb/).

  

| Title | Description |
| --- | --- |
|  [Installing MariaDB RPM Files](../rpm/index) |  Information and instructions on using the RPM packages and the related repositories.  |
|  [Installing MariaDB .deb Files](../installing-mariadb-deb-files/index) |  Installing MariaDB .deb Files.  |
|  [Installing MariaDB MSI Packages on Windows](../installing-mariadb-msi-packages-on-windows/index) |  MSI packages are available for both x86 (32 bit) and x64 (64 bit) processor architectures  |
|  [Installing MariaDB Server PKG packages on macOS](../installing-mariadb-server-pkg-packages-on-macos/index) |  MariaDB Server does not currently provide a .pkg installer for macOS  |
|  [Installing MariaDB Binary Tarballs](../installing-mariadb-binary-tarballs/index) |  Installing MariaDB binary tarballs, systemd, and glibc-2.14.  |
|  [Installing MariaDB Server on macOS Using Homebrew](../installing-mariadb-on-macos-using-homebrew/index) |  Installing MariaDB on macOS via the Homebrew package manager, the "missing ...  |
|  [Installing MariaDB Windows ZIP Packages](../installing-mariadb-windows-zip-packages/index) |  Getting started with ZIP packages on Windows.  |
|  [Compiling MariaDB From Source](../compiling-mariadb-from-source/index) |  Articles on compiling MariaDB from source  |
|  [Distributions Which Include MariaDB](../distributions-which-include-mariadb/index) |  Distributions including MariaDB.  |
|  [Running Multiple MariaDB Server Processes](../running-multiple-mariadb-server-processes/index) |  Running multiple MariaDB Server processes on the same server.  |
|  [Installing MariaDB Alongside MySQL](../installing-mariadb-alongside-mysql/index) |  MariaDB was designed as a drop in place replacement for MySQL, but you can ...  |
|  [GPG](../gpg/index) |  The MariaDB project signs their MariaDB packages for Debian, Ubuntu, Fedora, CentOS, and Red Hat  |
|  [MariaDB Deprecation Policy](../deprecation-policy/index) |  Information on MariaDB's Software Deprecation Policy and Schedule.  |
|  [Automated MariaDB Deployment and Administration](../automated-mariadb-deployment-and-administration/index) |  Tools for automating deployment and management of MariaDB servers.  |
|  [MariaDB Package Repository Setup and Usage](../mariadb-package-repository-setup-and-usage/index) |  Executing and using a convenient shell script to set up the MariaDB Package Repository.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-packages/>

Upgrading MariaDB
==================

  

| Title | Description |
| --- | --- |
|  [Upgrading Between Major MariaDB Versions](../upgrading-between-major-mariadb-versions/index) |  MariaDB is designed for easy upgrades.  |
|  [Upgrading Between Minor Versions on Linux](../upgrading-between-minor-versions-on-linux/index) |  Upgrading between minor versions of MariaDB, e.g. from MariaDB 10.4.12 to MariaDB 10.4.13  |
|  [Downgrading between Major Versions of MariaDB](../downgrading-between-major-versions-of-mariadb/index) |  Downgrading MariaDB is not officially supported between major versions.  |
|  [Upgrading from MariaDB 10.11 to MariaDB 11.0](../upgrading-from-mariadb-10-11-to-mariadb-11-0/index) |  How to upgrade from MariaDB 10.11 to MariaDB 11.0.  |
|  [Upgrading from MariaDB 10.6 to MariaDB 10.11](../upgrading-from-mariadb-10-6-to-mariadb-10-11/index) |  How to upgrade from MariaDB 10.6 to MariaDB 10.11  |
|  [Upgrading from MariaDB 10.7 to MariaDB 10.8](../upgrading-from-mariadb-10-7-to-mariadb-10-8/index) |  How to upgrade from MariaDB 10.7 to MariaDB 10.8.  |
|  [Upgrading from MariaDB 10.6 to MariaDB 10.7](../upgrading-from-mariadb-10-6-to-mariadb-10-7/index) |  How to upgrade from MariaDB 10.6 to MariaDB 10.7.  |
|  [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-10-5-to-mariadb-10-6/index) |  How to upgrade from MariaDB 10.5 to MariaDB 10.6.  |
|  [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index) |  How to upgrade from MariaDB 10.4 to MariaDB 10.5.  |
|  [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index) |  How to upgrade from MariaDB 10.3 to MariaDB 10.4.  |
|  [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index) |  How to upgrade from MariaDB 10.2 to MariaDB 10.3.  |
|  [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) |  Upgrading MariaDB on Windows.  |
|  [Upgrading Galera Cluster](../upgrading-galera-cluster/index) |  Upgrading MariaDB Galera Cluster.  |
|  [Upgrading from MySQL to MariaDB](../upgrading-mariadb-upgrading-from-mysql-to-mariadb/index) |  Upgrading from MySQL to MariaDB.  |
|  [Upgrading to Unmaintained MariaDB Releases](../upgrading-to-unmaintained-mariadb-releases/index) |  Upgrading to unmaintained MariaDB releases  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading/>

MariaDB Environment Variables
=============================

    MariaDB makes use of numerous environment variables that may be set on your system. Environment variables have the lowest precedence, so any options set on the command line or in an option file will take precedence.

 It's usually better not to rely on environment variables, and to rather set the options you need directly, as this makes the system a little more robust and easy to administer.

 Here is a list of environment variables used by MariaDB.

 


| Environment Variable | Description |
| --- | --- |
| CXX | Name of the C++ compiler, used for running CMake. |
| CC | Name of the C compiler, used for running CMake. |
| DBI\_USER | Perl DBI default username. |
| DBI\_TRACE | Perl DBI trace options. |
| HOME | Default directory for the [mysql\_history file](../mariadb-command-line-client/index#the-mysql_history-file). |
| MYSQL\_DEBUG | Debug trace options used when debugging. |
| MYSQL\_GROUP\_SUFFIX | In addition to the given option groups, also read groups with this suffix. |
| MYSQL\_HISTFILE | Path to the [mysql\_history file](../mariadb-command-line-client/index#the-mysql_history-file), overriding the $HOME/.mysql\_history setting. |
| MYSQL\_HOME | Path to the directory containing the [my.cnf file](../configuring-mariadb-with-mycnf/index) used by the server. |
| MYSQL\_HOST | Default host name used by the [mariadb command line client](../mariadb-client/index). |
| MYSQL\_PS1 | Command prompt for use by the [mariadb command line client](../mariadb-client/index). |
| MYSQL\_PWD | Default password when connecting to mysqld. It is strongly recommended to use a more secure method of sending the password to the server. |
| MYSQL\_TCP\_PORT | Default TCP/IP port number. |
| MYSQL\_UNIX\_PORT | On Unix, default socket file used for localhost connections. |
| PATH | Path to directories that hold executable programs (such as the [mariadb client](../mariadb-client/index), [mariadb-admin](../mariadb-admin/index)), so that these can be run from any location. |
| TMPDIR | Directory where temporary files are created. |
| TZ | Local [time zone](../time-zones/index). |
| UMASK | Creation mode when creating files. See [Specifying Permissions for Schema (Data) Directories and Tables](../specifying-permissions-for-schema-data-directories-and-tables/index). |
| UMASK\_DIR | Creation mode when creating directories. See [Specifying Permissions for Schema (Data) Directories and Tables](../specifying-permissions-for-schema-data-directories-and-tables/index). |
| USER | On Windows, up to [MariaDB 5.5](../what-is-mariadb-55/index), the default user name when connecting to the mysqld server. API GetUserName() is used in later versions. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-environment-variables/>

MariaDB on Amazon AWS
=====================

    MariaDB is available on Amazon AWS through MariaDB SkySQL, as one of the database options when using Amazon's RDS service, or using a MariaDB AMI on Amazon EC2 from the AWS Marketplace.

 MariaDB SkySQL
--------------

 Cloud database service is available through MariaDB SkySQL on Amazon AWS. MariaDB SkySQL delivers MariaDB with enterprise features for mission-critical workloads. Support is provided directly by MariaDB. Refer to [SkySQL Documentation](https://mariadb.com/products/skysql/docs/) for complete details. [Get started](https://mariadb.com/products/skysql/get-started/) to launch a MariaDB database on AWS in minutes.

 Amazon RDS
----------

 To get started with MariaDB on Amazon's RDS service, click on the RDS link in the Database section of the [AWS console](https://console.aws.amazon.com/console/home).

 
![rds-link]

 
Next, click on the **Get Started Now** button. Alternatively, you can click on the **Launch DB Instance** button from the [Instances section of the RDS Dashboard](https://console.aws.amazon.com/rds/home#dbinstances:).

 In either case, you will be brought to the page where you can select the database engine you want to use. Click on the **MariaDB** logo and then click on the **Select** button.

 
![]

 
You will then move to step 2 where you choose whether or not you want to use your MariaDB instance for production or non-production usage. Amazon has links on this page to documentation on the various options.

 After selecting the choice you want you will move to step 3 where you specify the details for your database, including setting up an admin user in the database.

 
![]

 
You will then move to step 4 where you can configure advanced settings, including security settings, various options, backup settings, maintenance defaults, and so on. 

 
Refer to [Amazon's RDS documentation](https://aws.amazon.com/documentation/rds/) for complete documentation on all the various settings and for information on connecting to and using your RDS MariaDB instances.

 
AMI on EC2
----------

 MariaDB AMIs (Amazon Machine Images) are available in the AWS Marketplace. These AMIs, kept up-to-date with the most recently released versions of MariaDB, are a great way to try out the newest MariaDB versions before they make it to RDS and/or to use MariaDB in a more traditional server environment.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-on-amazon-rds/>

Configuring MariaDB with Option Files
=====================================

    You can configure MariaDB to run the way you want by configuring the server with MariaDB's option files. The default MariaDB option file is called `my.cnf` (or `mariadb.cnf`) on Unix-like operating systems and `my.ini` on Windows. Depending on how you've [installed](../getting-installing-and-upgrading-mariadb/index) MariaDB, the default option file may be in a number of places, or it may not exist at all.

 Global Options Related to Option Files
--------------------------------------

 The following options relate to how MariaDB handles option files. These options can be used with most of MariaDB's command-line tools, not just [mysqld](../mysqld-options/index). They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `[--print-defaults](../mysqld-options/index#-print-defaults)` | Read options from option files, print all option values, and then exit the program. |
| `[--no-defaults](../mysqld-options/index#-no-defaults)` | Don't read options from any option file. |
| `[--defaults-file](../mysqld-options/index#-defaults-file)` `=path` | Only read options from the given option file. |
| `[--defaults-extra-file](../mysqld-options/index#-defaults-extra-file)` `=path` | Read this extra option file after all other option files are read. |
| `[--defaults-group-suffix](../mysqld-options/index#-defaults-group-suffix)` `=suffix` | In addition to the default option groups, also read option groups with the given suffix. |

 
Default Option File Locations
-----------------------------

 MariaDB reads option files from many different directories by default. See the sections below to find out which directories are checked for which system.

 For an exact list of option files read on your system by a specific program, you can execute:

 
```
$program --help --verbose

```

For example:

 
```
$ mysqld --help --verbose
mysqld  Ver 10.3.13-MariaDB-log for Linux on x86_64 (MariaDB Server)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Starts the MariaDB database server.

Usage: mysqld [OPTIONS]

Default options are read from the following files in the given order:
/etc/my.cnf ~/.my.cnf
The following groups are read: mysqld server mysqld-10.3 mariadb mariadb-10.3 client-server galera
....

```

The option files are each scanned once, in the order given by `--help --verbose`. The effect of the configuration options are as if they would have been given as command line options in the order they are found.

 ### Default Option File Locations on Linux, Unix, Mac

 On Linux, Unix, or Mac OS X, the default option file is called `my.cnf`. MariaDB looks for the MariaDB option file in the locations and orders listed below.

 The locations are dependent on whether the `DEFAULT_SYSCONFDIR` `[cmake](../generic-build-instructions/index#using-cmake)` option was defined when MariaDB was built. This option is usually defined as `/etc` when building [RPM packages](../rpm/index), but it is usually not defined when building [DEB packages](../installing-mariadb-deb-files/index) or [binary tarballs](../installing-mariadb-binary-tarballs/index).

 * When the `DEFAULT_SYSCONFDIR` `[cmake](../generic-build-instructions/index#using-cmake)` option was **not** defined, MariaDB looks for the MariaDB option file in the following locations in the following order:

 


| Location | Scope |
| --- | --- |
| `/etc/my.cnf` | Global |
| `/etc/mysql/my.cnf` | Global |
| `$MARIADB_HOME/my.cnf` | Server |
| `$MYSQL_HOME/my.cnf` | Server |
| defaults-extra-file | File specified with `[--defaults-extra-file](../mysqld-options/index#-defaults-extra-file)`, if any |
| `~/.my.cnf` | User |

 
* When the `DEFAULT_SYSCONFDIR` `[cmake](../generic-build-instructions/index#using-cmake)` option was defined, MariaDB looks for the MariaDB option file in the following locations in the following order:

 


| Location | Scope |
| --- | --- |
| `DEFAULT_SYSCONFDIR/my.cnf` | Global |
| `$MARIADB_HOME/my.cnf` | Server (from [MariaDB 10.6](../what-is-mariadb-106/index)) |
| `$MYSQL_HOME/my.cnf` | Server |
| defaults-extra-file | File specified with `[--defaults-extra-file](../mysqld-options/index#-defaults-extra-file)`, if any |
| `~/.my.cnf` | User |

 
* `MARIADB_HOME` (from [MariaDB 10.6](../what-is-mariadb-106/index)) or `MYSQL_HOME` is the [environment variable](../mariadb-environment-variables/index) containing the path to the directory holding the server-specific `my.cnf` file. If `MYSQL_HOME` is not set, and the server is started with [mysqld\_safe](../mysqld_safe/index), `MYSQL_HOME` is set as follows:
	+ If there is a `my.cnf` file in the MariaDB data directory, but not in the MariaDB base directory, `MYSQL_HOME` is set to the MariaDB data directory.
	+ Else, `MYSQL_HOME` is set to the MariaDB base directory.
* Note that if `MARIADB_HOME` is set (from [MariaDB 10.6](../what-is-mariadb-106/index)), `MYSQL_HOME` will not be used, even if set.

 ### Default Option File Locations on Windows

 On Windows, the option file can be called either `my.ini` or `my.cnf`. MariaDB looks for the MariaDB option file in the following locations in the following order:

 


| Location | Scope |
| --- | --- |
| `System Windows Directory\my.ini` | Global |
| `System Windows Directory\my.cnf` | Global |
| `Windows Directory\my.ini` | Global |
| `Windows Directory\my.cnf` | Global |
| `C:\my.ini` | Global |
| `C:\my.cnf` | Global |
| `INSTALLDIR\my.ini` | Server |
| `INSTALLDIR\my.cnf` | Server |
| `INSTALLDIR\data\my.ini` | Server |
| `INSTALLDIR\data\my.cnf` | Server |
| `%MARIADB_HOME%\my.ini` | Server (from [MariaDB 10.6](../what-is-mariadb-106/index)) |
| `%MARIADB_HOME%\my.cnf` | Server (from [MariaDB 10.6](../what-is-mariadb-106/index)) |
| `%MYSQL_HOME%\my.ini` | Server |
| `%MYSQL_HOME%\my.cnf` | Server |
| defaults-extra-file | File specified with `[--defaults-extra-file](../mysqld-options/index#-defaults-extra-file)`, if any |

 
* The `System Windows Directory` is the directory returned by the `[GetSystemWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemwindowsdirectorya)` function. The value is usually `C:\Windows`. To find its specific value on your system, open `[cmd.exe](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/cmd)` and execute: 
```
echo %WINDIR%
```
* The `Windows Directory` is the directory returned by the `[GetWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getwindowsdirectorya)` function. The value may be a private `Windows Directory` for the application, or it may be the same as the `System Windows Directory` returned by the `[GetSystemWindowsDirectory](https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemwindowsdirectorya)` function.
* `INSTALLDIR` is the parent directory of the directory where `mysqld.exe` is located. For example, if `mysqld.exe` is in `C:\Program Files\[MariaDB 10.3](../what-is-mariadb-103/index)\bin`, then `INSTALLDIR` would be `C:\Program Files\[MariaDB 10.3](../what-is-mariadb-103/index)`.
* `MARIADB_HOME` (from [MariaDB 10.6](../what-is-mariadb-106/index)) or `MYSQL_HOME` is the [environment variable](../mariadb-environment-variables/index) containing the path to the directory holding the server-specific `my.cnf` file.
* Note that if `MARIADB_HOME` is set (from [MariaDB 10.6](../what-is-mariadb-106/index)), `MYSQL_HOME` will not be used, even if set.

 ### Default Option File Hierarchy

 MariaDB will look in all of the above locations, in order, even if has already found an option file, and it's possible for more than one option file to exist. For example, you could have an option file in `/etc/my.cnf` with global settings for all servers, and then you could another option file in `~/.my.cnf` (i.e.your user account's home directory) which will specify additional settings (or override previously specified setting) that are specific only to that user.

 Option files are usually optional. However, if the `[--defaults-file](../mysqld-options/index#-defaults-file)` option is set, and if the file does not exist, then MariaDB will raise an error. If the `[--defaults-file](../mysqld-options/index#-defaults-file)` option is set, then MariaDB will *only* read the option file referred to by this option.

 If an option or system variable is not explicitly set, then it will be set to its default value. See [Server System Variables](../server-system-variables/index) for a full list of all server system variables and their default values.

 Custom Option File Locations
----------------------------

 MariaDB can be configured to read options from custom options files with the following command-line arguments. These command-line arguments can be used with most of MariaDB's command-line tools, not just `[mysqld](../mysqld-options/index)`. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `[--defaults-file](../mysqld-options/index#-defaults-file)` `=path` | Only read options from the given option file. |
| `[--defaults-extra-file](../mysqld-options/index#-defaults-extra-file)` `=path` | Read this extra option file after all other option files are read. |

 
Option File Syntax
------------------

 The syntax of the MariaDB option files are:

 * Lines starting with # are comments.
* Empty lines are ignored.
* Option groups use the syntax `[group-name]`. See the [Option Groups](#option-groups) section below for more information on available option groups.
* The same option group can appear multiple times.
* The `!include` directive can be used to include other option files. See the [Including Option Files](#including-option-files) section below for more information on this syntax.
* The `!includedir` directive can be used to include all `.cnf` files (and potentially `.ini` files) in a given directory. The option files within the directory are read in alphabetical order. See the [Including Option File Directories](#including-option-file-directories) section below for more information on this syntax.
* Dashes (`-`) and underscores (`_`) in options are interchangeable.
* Double quotes can be used to quote values
* `\n`, `\r`, `\t`, `\b`, `\s`, `\"`, `\'`, and `\\` are recognized as character escapes for new line, carriage return, tab, backspace, space, double quote, single quote, and backslash respectively.
* Certain option prefixes are supported. See the [Option Prefixes](#option-prefixes) section below for information about available option prefixes.
* See the [Options](#options) section below for information about available options.

 Option Groups
-------------

 A MariaDB program can read options from one or many option groups. For an exact list of option groups read on your system by a specific program, you can execute:

 
```
$program --help --verbose

```

For example:

 
```
$ mysqld --help --verbose
mysqld  Ver 10.3.13-MariaDB-log for Linux on x86_64 (MariaDB Server)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Starts the MariaDB database server.

Usage: mysqld [OPTIONS]

Default options are read from the following files in the given order:
/etc/my.cnf ~/.my.cnf
The following groups are read: mysqld server mysqld-10.3 mariadb mariadb-10.3 client-server galera
....

```

### Server Option Groups

 MariaDB programs reads server options from the following server option groups:

 


| Group | Description |
| --- | --- |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[server]` | Options read by MariaDB Server. |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-10.4]`. |
| `[mariadb]` | Options read by MariaDB Server. |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. For example, `[mariadb-10.4]`. |
| `[mariadbd]` | Options read by MariaDB Server. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mariadbd-X.Y]` | Options read by a specific version of MariaDB Server. For example, `[mariadbd-10.4]`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[galera]` |  Options read by MariaDB Server, but only if it is compiled with [Galera Cluster](../galera/index) support. In [MariaDB 10.1](../what-is-mariadb-101/index) and later, all builds on Linux are compiled with [Galera Cluster](../galera/index) support. When using one of these builds, options from this option group are read even if the [Galera Cluster](../galera/index) functionality is not enabled. |

 
*X.Y* in the examples above refer to the base (major.minor) version of the server. For example, [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) would read from `[mariadb-10.3]`. By using the `mariadb-X.Y` syntax, one can create option files that have MariaDB-only options in the MariaDB-specific option groups. That would allow the option file to work for both MariaDB and MySQL.

 ### Client Option Groups

 MariaDB programs reads client options from the following option groups:

 


| Group | Description |
| --- | --- |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
### Tool-Specific Option Groups

 Many MariaDB tools reads options from their own option groups as well. Many of them are listed below:

 


| Group | Description |
| --- | --- |
| `[mysqld_safe]` | Options read by [mysqld\_safe](../mysqld_safe/index), which includes both MariaDB Server and MySQL Server. |
| `[safe_mysqld]` | Options read by [mysqld\_safe](../mysqld_safe/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb_safe]` | Options read by [mysqld\_safe](../mysqld_safe/index) from MariaDB Server. |
| `[mariadb-safe]` | Options read by [mysqld\_safe](../mysqld_safe/index) from MariaDB Server. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mariabackup]` | Options read by [Mariabackup](../mariabackup/index). Available starting with [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/). |
| `[xtrabackup]` | Options read by [Mariabackup](../mariabackup/index) and [Percona XtraBackup](../percona-xtrabackup-overview/index). |
| `[mysql_upgrade]` | Options read by [mysql\_upgrade](../mysql_upgrade/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-upgrade]` | Options read by [mariadb-upgrade](../mariadb-upgrade/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[sst]` | Specific options read by the [mariabackup SST method](../mariabackup-sst-method/index) and the [xtrabackup-v2 SST method](../xtrabackup-v2-sst-method/index). |
| `[mysql]` | Options read by [mysql](../mysql-client/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-client]` | Options read by [mariadb](../mariadb-client/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqldump]` | Options read by [mysqldump](../mysqldump/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-dump]` | Options read by [mariadb-dump](../mariadb-dump/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqlimport]` | Options read by [mysqlimport](../mysqlimport/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-import]` | Options read by [mariadb-import](../mariadb-import/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqlbinlog]` | Options read by [mysqlbinlog](../mysqlbinlog/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-binlog]` | Options read by [mariadb-binlog](../mariadb-binlog/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqladmin]` | Options read by [mysqladmin](../mysqladmin/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-admin]` | Options read by [mariadb-admin](../mariadb-admin/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqlshow]` | Options read by [mysqlshow](../mysqlshow/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-show]` | Options read by [mariadb-show](../mariadb-show/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqlcheck]` | Options read by [mariadb-check](../mariadb-check/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-check]` | Options read by [mariadb-check](../mariadb-check/index). Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[mysqlslap]` | Options read by [mysqlslap](../mysqlslap/index), which includes both MariaDB Server and MySQL Server. |
| `[mariadb-slap]` | Options read by `[mariadb-slap](../mariadb-slap/index)`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[odbc]` | Options read by [MariaDB Connector/ODBC](../mariadb-connector-odbc/index), but only if the `[USE\_MYCNF](../about-mariadb-connector-odbc/index#general-connection-parameters)` parameter has been set. |

 
### Custom Option Group Suffixes

 MariaDB can be configured to read options from option groups with a custom suffix by providing the following command-line argument. This command-line argument can be used with most of MariaDB's command-line tools, not just `[mysqld](../mysqld-options/index)`. It must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `[--defaults-group-suffix](../mysqld-options/index#-defaults-group-suffix)` `=suffix` | In addition to the default option groups, also read option groups with the given suffix. |

 
The default group suffix can also be specified via the `MYSQL_GROUP_SUFFIX` [environment variable](../mariadb-environment-variables/index).

 Including Option Files
----------------------

 It is possible to include additional option files from another option file. For example, to include `/etc/mysql/dbserver1.cnf`, an option file could contain:

 
```
[mariadb]
...
!include /etc/mysql/dbserver1.cnf

```

Including Option File Directories
---------------------------------

 It is also possible to include all option files in a directory from another option file. For example, to include all option files in `/etc/my.cnf.d/`, an option file could contain:

 
```
[mariadb]
...
!includedir /etc/my.cnf.d/

```

The option files within the directory are read in alphabetical order.

 All option file names must end in `.cnf` on Unix-like operating systems. On Windows, all option file names must end in `.cnf` or `.ini`.

 Checking Program Options
------------------------

 You can check which options a given program is going to use by using the `[--print-defaults](../mysqld-options/index#-print-defaults)` command-line argument:

 


| Option | Description |
| --- | --- |
| `[--print-defaults](../mysqld-options/index#-print-defaults)` | Read options from option files, print all option values, and then exit the program. |

 
This command-line argument can be used with most of MariaDB's command-line tools, not just `[mysqld](../mysqld-options/index)`. It must be given as the first argument on the command-line. For example:

 
```
$ mariadb-dump --print-defaults
mariadb-dump would have been started with the following arguments:
--ssl_cert=/etc/my.cnf.d/certificates/client-cert.pem --ssl_key=/etc/my.cnf.d/certificates/client-key.pem --ssl_ca=/etc/my.cnf.d/certificates/ca.pem --ssl-verify-server-cert --max_allowed_packet=1GB

```

You can also check which options a given program is going to use by using the `[my\_print\_defaults](../my_print_defaults/index)` utility and providing the names of the option groups that the program reads. For example:

 
```
$ my_print_defaults mariadb-dump client client-server client-mariadb
--ssl_cert=/etc/my.cnf.d/certificates/client-cert.pem
--ssl_key=/etc/my.cnf.d/certificates/client-key.pem
--ssl_ca=/etc/my.cnf.d/certificates/ca.pem
--ssl-verify-server-cert
--max_allowed_packet=1GB

```

The `[my\_print\_defaults](../my_print_defaults/index)` utility's `--mysqld` command-line option provides a shortcut to refer to all of the [server option groups](#server-option-groups):

 
```
$ my_print_defaults --mysqld
--log_bin=mariadb-bin
--log_slave_updates=ON
--ssl_cert=/etc/my.cnf.d/certificates/server-cert.pem
--ssl_key=/etc/my.cnf.d/certificates/server-key.pem
--ssl_ca=/etc/my.cnf.d/certificates/ca.pem

```

MySQL 5.6 Obfuscated Authentication Credential Option File
----------------------------------------------------------

 MySQL 5.6 and above support an obfuscated authentication credential option file called `.mylogin.cnf` that is created with `[mysql\_config\_editor](https://dev.mysql.com/doc/refman/5.6/en/mysql-config-editor.html)`.

 MariaDB does not support this. The passwords in MySQL's `.mylogin.cnf` are only obfuscated, rather than encrypted, so the feature does not really add much from a security perspective. It is more likely to give users a false sense of security, rather than to seriously protect them.

 Option Prefixes
---------------

 MariaDB supports certain prefixes that can be used with options. The supported option prefixes are:

 


| Option Prefix | Description |
| --- | --- |
| `[autoset](../mysqld-options/index#-autoset-)` | Sets the option value automatically. Only supported for certain options. Available in [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) and later. |
| `[disable](../mysqld-options/index#-disable-)` | For all boolean options, disables the setting (equivalent to setting it to `0`). Same as `skip`. |
| `[enable](../mysqld-options/index#-enable-)` | For all boolean options, enables the setting (equivalent to setting it to `1`). |
| `[loose](../mysqld-options/index#-loose-)` | Don't produce an error if the option doesn't exist. |
| `[maximum](../mysqld-options/index#-maximum-)` | Sets the maximum value for the option. |
| `[skip](../mysqld-options/index#-skip-)` | For all boolean options, disables the setting (equivalent to setting it to `0`). Same as `disable`. |

 
For example:

 
```
[mariadb]
...
# determine a good value for open_files_limit automatically
autoset_open_files_limit

# disable the unix socket plugin
disable_unix_socket

# enable the slow query log
enable_slow_query_log

# don't produce an error if these options don't exist
loose_file_key_management_filename = /etc/mysql/encryption/keyfile.enc
loose_file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
loose_file_key_management_encryption_algorithm = AES_CTR

# set max_allowed_packet to maximum value
maximum_max_allowed_packet

# disable external locking for MyISAM
skip_external_locking

```

Options
-------

 Dashes (`-`) and underscores (`_`) in options are interchangeable.

 If an option is not explicitly set, then the server or client will simply use the default value for that option.

 ### MariaDB Server Options

 MariaDB Server options can be set in [server option groups](#server-option-groups).

 For a list of options that can be set for MariaDB Server, see the list of options available for `[mysqld](../mysqld-options/index)`.

 Most of the [server system variables](../server-system-variables/index) can also be set in MariaDB's option file.

 ### MariaDB Client Options

 MariaDB client options can be set in [client option groups](#client-option-groups).

 See the specific page for each [client program](../clients-utilities/index) to determine what options are available for that program.

 Example Option Files
--------------------

 Most MariaDB installations include a sample MariaDB option file called `my-default.cnf`. On older releases, you would have also found the following option files:

 * `my-small.cnf`
* `my-medium.cnf`
* `my-large.cnf`
* `my-huge.cnf`

 However, these option files are now very dated for modern servers, so they were removed in [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/).

 In source distributions, the sample option files are usually found in the `support-files` directory, and in other distributions, the option files are usually found in the `share/mysql` directory that is relative to the MariaDB base installation directory.

 You can copy one of these sample MariaDB option files and use it as the basis for building your server's primary MariaDB option file.

 ### Example Minimal Option File

 The following is a minimal my.cnf file that you can use to test MariaDB.

 
```
[client-server]
# Uncomment these if you want to use a nonstandard connection to MariaDB
#socket=/tmp/mysql.sock
#port=3306

# This will be passed to all MariaDB clients
[client]
#password=my_password

# The MariaDB server
[mysqld]
# Directory where you want to put your data
data=/usr/local/mysql/var
# Directory for the errmsg.sys file in the language you want to use
language=/usr/local/share/mysql/english

# This is the prefix name to be used for all log, error and replication files
log-basename=mysqld

# Enable logging by default to help find problems
general-log
log-slow-queries

```

### Example Hybrid Option File

 The following is an extract of an option file that one can use if one wants to work with both MySQL and MariaDB.

 
```
# Example mysql config file.

[client-server]
socket=/tmp/mysql-dbug.sock
port=3307

# This will be passed to all mariadb clients
[client]
password=my_password

# Here are entries for some specific programs
# The following values assume you have at least 32M ram

# The MariaDB server
[mysqld]
temp-pool
key_buffer_size=16M
datadir=/my/mysqldata
loose-innodb_file_per_table

[mariadb]
datadir=/my/data
default-storage-engine=aria
loose-mutex-deadlock-detector
max-connections=20

[mariadb-5.5]
language=/my/maria-5.5/sql/share/english/
socket=/tmp/mysql-dbug.sock
port=3307

[mariadb-10.1]
language=/my/maria-10.1/sql/share/english/
socket=/tmp/mysql2-dbug.sock

[mysqldump]
quick
max_allowed_packet=16M

[mysql]
no-auto-rehash
loose-abort-source-on-error

```

See Also
--------

 * [Configuring MariaDB Connector/C with Option Files](../configuring-mariadb-connectorc-with-option-files/index)
* [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index)
* [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index)
* [MySQL 5.6: Security through Complacency?](https://mariadb.com/resources/blog/mysql-5-6-security-through-complacency)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-mariadb-with-option-files/>

Obsolete Installation Information
==================================

   This section is for installation-related items that are obsolete.

  

| Title | Description |
| --- | --- |
|  [MariaDB Debian Live Images](../mariadb-debian-live-images/index) |  Debian live iso images with pre-installed MariaDB (obsolete)  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/obsolete-installation-information/>

Migrating to MariaDB
=====================

   Migrating to MariaDB from another DBMS.

  

| Title | Description |
| --- | --- |
|  [Migrating to MariaDB from MySQL](../moving-from-mysql/index) |  Help with moving from MySQL to MariaDB, features and compatibility  |
|  [Migrating to MariaDB from SQL Server](../migrating-to-mariadb-from-sql-server/index) |  Guide to help you migrate from SQL Server to MariaDB.  |
|  [Migrating to MariaDB from PostgreSQL](../migrating-to-mariadb-from-postgresql/index) |  Information on migrating from PostgreSQL to MariaDB.  |
|  [Migrating to MariaDB from Oracle](../migrating-to-mariadb-from-oracle/index) |  Help with migrating to MariaDB from Oracle  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/migrating-to-mariadb/>

Installing MariaDB on IBM Cloud
===============================

     Get MariaDB on IBM Cloud

 You should have an IBM Cloud account, otherwise you can [register here](https://cloud.ibm.com/registration). At the end of the tutorial you will have a cluster with MariaDB up and running. IBM Cloud uses Bitnami charts to deploy MariaDB on with helm

 1. We will provision a new Kubernetes Cluster for you if, you already have one skip to step **2**

 2. We will deploy the IBM Cloud Block Storage plug-in, if already have it skip to step **3**

 3. MariaDB deployment

 Step 1 provision Kubernetes Cluster
-----------------------------------

 * Click the **Catalog** button on the top
* Select **Service** from the catalog
* Search for **Kubernetes Service** and click on it

 ![kubernetes-select]

 * You are now at the Kubernetes deployment page, you need to specify some details about the cluster
* Choose a plan **standard** or **free**, the free plan only has one worker node and no subnet, to provision a standard cluster, you will need to upgrade you account to Pay-As-You-Go
* To upgrade to a Pay-As-You-Go account, complete the following steps:

 * In the console, go to Manage > Account.
* Select Account settings, and click Add credit card.
* Enter your payment information, click Next, and submit your information
* Choose **classic** or **VPC**, read the [docs](https://cloud.ibm.com/docs/containers?topic=containers-infrastructure_providers) and choose the most suitable type for yourself

 ![infra-select]

 * Now choose your location settings, for more information please visit [Locations](https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones)
* Choose **Geography** (continent)

 ![location-geo]

 * Choose **Single** or **Multizone**, in single zone your data is only kept in on datacenter, on the other hand with Multizone it is distributed to multiple zones, thus safer in an unforseen zone failure

 ![location-avail]

 * Choose a **Worker Zone** if using Single zones or **Metro** if Multizone

  ![location-worker]

 * If you wish to use Multizone please set up your account with [VRF](https://cloud.ibm.com/docs/dl?topic=dl-overview-of-virtual-routing-and-forwarding-vrf-on-ibm-cloud) or [enable Vlan spanning](https://cloud.ibm.com/docs/vlans?topic=vlans-vlan-spanning#vlan-spanning)
* If at your current location selection, there is no available Virtual LAN, a new Vlan will be created for you

 * Choose a **Worker node setup** or use the preselected one, set **Worker node amount per zone**

 ![worker-pool]

 * Choose **Master Service Endpoint**, In VRF-enabled accounts, you can choose private-only to make your master accessible on the private network or via VPN tunnel. Choose public-only to make your master publicly accessible. When you have a VRF-enabled account, your cluster is set up by default to use both private and public endpoints. For more information visit [endpoints](https://cloud.ibm.com/docs/account?topic=account-service-endpoints-overview).

 ![endpoints]

 * Give cluster a **name**

 ![name-new]

 * Give desired **tags** to your cluster, for more information visit [tags](https://cloud.ibm.com/docs/account?topic=account-tag)

 ![tasg-new]

 * Click **create**

 ![create-new]

 * Wait for you cluster to be provisioned

 ![cluster-prepare]

 * Your cluster is ready for usage

 ![cluster-done]

 Step 2 deploy IBM Cloud Block Storage plug-in
---------------------------------------------

 The Block Storage plug-in is a persistent, high-performance iSCSI storage that you can add to your apps by using Kubernetes Persistent Volumes (PVs).

 * Click the **Catalog** button on the top
* Select **Software** from the catalog
* Search for **IBM Cloud Block Storage plug-in** and click on it

 ![block-search]

 * On the application page Click in the dot next to the cluster, you wish to use
* Click on **Enter or Select Namespace** and choose the default Namespace or use a custom one (if you get error please wait 30 minutes for the cluster to finalize)

 ![block-cluster]

 * Give a **name** to this workspace
* Click **install** and wait for the deployment

 ![block-storage-create]

 Step 3 deploy MariaDB
---------------------

 We will deploy MariaDB on our cluster 

 * Click the **Catalog** button on the top
* Select **Software** from the catalog
* Search for **MariaDB** and click on it

 ![search]

 * Please select IBM Kubernetes Service

 ![target-select]

 * On the application page Click in the dot next to the cluster, you wish to use

 ![cluster-select]

 * Click on **Enter or Select Namespace** and choose the default Namespace or use a custom one

 ![details-namespace]

 * Give a unique **name** to workspace, which you can easily recognize

 ![details-name]

 * Select which resource group you want to use, it's for access controll and billing purposes. For more information please visit [resource groups](https://cloud.ibm.com/docs/account?topic=account-account_setup#bp_resourcegroups)

 ![details-resource]

 * Give **tags** to your MariaDB, for more information visit [tags](https://cloud.ibm.com/docs/account?topic=account-tag)

 ![details-tags]

 * Click on **Parameters with default values**, You can set deployment values or use the default ones

 ![parameters]

 * Please set the MariaDB root password in the parameters

 ![root-password]

 * After finishing everything, **tick** the box next to the agreements and click **install**

 ![aggreement-create]

 * The MariaDB workspace will start installing, wait a couple of minutes

 ![in-progress]

 * Your MariaDB workspace has been successfully deployed

 ![done]

 Verify MariaDB installation
---------------------------

 * Go to [Resources](http://cloud.ibm.com/resources) in your browser
* Click on **Clusters**
* Click on your Cluster

 ![resource-select]

 * Now you are at you clusters overview, here Click on **Actions** and **Web terminal** from the dropdown menu

 ![cluster-main]

 * Click **install** - wait couple of minutes

 ![terminal-install]

 * Click on **Actions**
* Click **Web terminal** --> a terminal will open up

 * **Type** in the terminal, please change NAMESPACE to the namespace you choose at the deployment setup:

 
```
$ kubectl get ns

```

![get-ns]

 
```
$ kubectl get pod -n NAMESPACE -o wide 

```

![get-pods]

 
```
$ kubectl get service -n NAMESPACE

```

![get-service]

 * Enter your pod with bash , please replace PODNAME with your mariadb pod's name

 
```
$ kubectl exec --stdin --tty PODNAME -n NAMESPACE -- /bin/bash

```

![bash]

 * After you are in your pod please enter enter Mariadb and enter your root password after the prompt

 
```
$ mysql -u root -p

```

![welcome]

 You have succesfully deployed MariaDB IBM Cloud!

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-on-ibm-cloud/>

mysqld Configuration Files and Groups
=====================================

    For all about configuring mysqld, see [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqld-configuration-files-and-groups/>

OLD\_MODE
=========

    The [old\_mode](../server-system-variables/index#old_mode) system variable was introduced in [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5535-release-notes/) to replace the [old](../server-system-variables/index#old) variable with a new one with better granularity.

 MariaDB supports several different modes which allow you to tune it to suit your needs.

 The most important ways for doing this are with [SQL\_MODE](../sql-mode/index) and `OLD_MODE`.

 [SQL\_MODE](../sql-mode/index) is used for getting MariaDB to emulate behavior from other SQL servers, while `OLD_MODE` is used for emulating behavior from older MariaDB or MySQL versions.

 `OLD_MODE` is a string with different options separated by commas ('`,`') without spaces. The options are case insensitive.

 Normally `OLD_MODE` should be empty. It's mainly used to get old behavior when switching to MariaDB or to a new major version of MariaDB, until you have time to fix your application.

 Between major versions of MariaDB various options supported by `OLD_MODE` may be removed. This is intentional as we assume that the application will be fixed to conform with the new MariaDB behavior between releases.

 You can check the local and global value of it with:

 
```
SELECT @@OLD_MODE, @@GLOBAL.OLD_MODE;

```

You can set the `OLD\_MODE` either from the [command line](../mysqld-options-full-list/index) (option `--old-mode`) or by setting the [old\_mode](../server-system-variables/index#old_mode) system variable.

 The different values of `OLD_MODE` are:

 


| Option | Description |
| --- | --- |
| `NO_DUP_KEY_WARNINGS_WITH_IGNORE` | Don't print duplicate key warnings when using INSERT [IGNORE](../ignore/index). |
| `NO_PROGRESS_INFO` | Don't show progress information in [SHOW PROCESSLIST](../show-processlist/index). |
| `UTF8_IS_UTF8MB3` | From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), the main name of the previous 3 byte `utf` [character set](../character-sets/index) has been changed to `utf8mb3`. If set, the default, `utf8` is an alias for `utf8mb3`. If not set, `utf8` would be an alias for `utf8mb4`. |
| `ZERO_DATE_TIME_CAST` | When a [TIME](../time/index) value is cast to a [DATETIME](../datetime/index), the date part will be `0000-00-00`, not [CURRENT\_DATE](../curdate/index) (as dictated by the SQL standard). |
| `IGNORE_INDEX_ONLY_FOR_JOIN` | From [MariaDB 10.9](../what-is-mariadb-109/index), --old option is deprecated. This option allows behaviour of --old option for disabling the index only for joins, but allow it for ORDER BY. |
| `COMPAT_5_1_CHECKSUM` | From [MariaDB 10.9](../what-is-mariadb-109/index), --old option is deprecated. This option allows behaviour of --old option for enabling old-style checksum for `CHECKSUM TABLE` that MySQL 5.1 supports |

 
OLD\_MODE and Stored Programs
-----------------------------

 In contrast to [SQL\_MODE](../sql-mode/index), [stored programs](../stored-programs-and-views/index) use the current user's `OLD_MODE`value.

 Changes to `OLD_MODE` are not sent to replicas.

 Examples
--------

 This example shows how to get a readable list of enabled OLD\_MODE flags:

 
```
SELECT REPLACE(@@OLD_MODE, ',', '\n');
+---------------------------------------------------+
| REPLACE(@@OLD_MODE, ',', '\n')                    |
+---------------------------------------------------+
| NO_DUP_KEY_WARNINGS_WITH_IGNORE                   |
| NO_PROGRESS_INFO                                  |
+---------------------------------------------------+

```

Adding a new flag:

 
```
SET @@OLD_MODE = CONCAT(@@OLD_MODE, ',NO_PROGRESS_INFO');

```

If the specified flag is already ON, the above example has no effect but does not produce an error.

 How to unset a flag:

 
```
SET @@OLD_MODE = REPLACE(@@OLD_MODE, 'NO_PROGRESS_INFO', '');

```

How to check if a flag is set:

 
```
SELECT @@OLD_MODE LIKE '%NO_PROGRESS_INFO';
+------------------------------------+
| @@OLD_MODE LIKE '%NO_PROGESS_INFO' |
+------------------------------------+
|                                  1 |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/old-mode/>

SQL\_MODE
=========

     MariaDB supports several different modes which allow you to tune it to suit your needs.

 The most important ways for doing this are using `SQL_MODE` (controlled by the [sql\_mode](../server-system-variables/index#sql_mode) system variable) and [OLD\_MODE](../old_mode/index) (the [old\_mode](../server-system-variables/index#old_mode) system variable). `SQL_MODE` is used for getting MariaDB to emulate behavior from other SQL servers, while [OLD\_MODE](../old_mode/index) is used for emulating behavior from older MariaDB or MySQL versions.

 `SQL_MODE`is a string with different options separated by commas ('`,`') without spaces. The options are case insensitive.

 You can check the local and global value of it with:

 
```
SELECT @@SQL_MODE, @@GLOBAL.SQL_MODE;

```

Setting SQL\_MODE
-----------------

 ### Defaults

 


| From version | Default sql\_mode setting |
| --- | --- |
| [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) | STRICT\_TRANS\_TABLES, ERROR\_FOR\_DIVISION\_BY\_ZERO , NO\_AUTO\_CREATE\_USER, NO\_ENGINE\_SUBSTITUTION |
| [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) | NO\_ENGINE\_SUBSTITUTION, NO\_AUTO\_CREATE\_USER |
| <= [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) | No value |

 
You can set the `SQL\_MODE` either from the [command line](../mysqld-options-full-list/index) (the `--sql-mode` option) or by setting the [sql\_mode](../server-system-variables/index#sql_mode) system variable.

 
```
SET sql_mode = 'modes';
SET GLOBAL sql_mode = 'modes';

```

The session value only affects the current client, and can be changed by the client when required. To set the global value, the SUPER privilege is required, and the change affects any clients that connect from that point on.

 SQL\_MODE Values
----------------

 The different `SQL_MODE` values are:

 #### ALLOW\_INVALID\_DATES

 Allow any day between 1-31 in the day part. This is convenient when you want to read in all (including wrong data) into the database and then manipulate it there.

 #### ANSI

 Changes the SQL syntax to be closer to ANSI SQL. 

 Sets: [REAL\_AS\_FLOAT](#real_as_float), [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes), [IGNORE\_SPACE](#ignore_space).

 It also adds a restriction: an error will be returned if a subquery uses an [aggregating function](../functions-and-modifiers-for-use-with-group-by/index) with a reference to a column from an outer query in a way that cannot be resolved.

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### ANSI\_QUOTES

 Changes `"` to be treated as ```, the identifier quote character. This may break old MariaDB applications which assume that `"` is used as a string quote character.

 #### DB2

 Same as: [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes) , [IGNORE\_SPACE](#ignore_space), [DB2](#db2), [NO\_KEY\_OPTIONS](#no_key_options), [NO\_TABLE\_OPTIONS](#no_table_options), [NO\_FIELD\_OPTIONS](#no_field_options)

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### EMPTY\_STRING\_IS\_NULL

 Oracle-compatibility option that translates Item\_string created in the parser to Item\_null, and translates binding an empty string as prepared statement parameters to binding NULL. For example, `SELECT '' IS NULL` returns TRUE, `INSERT INTO t1 VALUES ('')` inserts NULL. Since [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 #### ERROR\_FOR\_DIVISION\_BY\_ZERO

 If not set, division by zero returns NULL. If set returns an error if one tries to update a column with 1/0 and returns a warning as well. Also see [MDEV-8319](https://jira.mariadb.org/browse/MDEV-8319). Default since [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/).

 #### HIGH\_NOT\_PRECEDENCE

 Compatibility option for MySQL 5.0.1 and before; This changes `NOT a BETWEEN b AND c` to be parsed as `(NOT a) BETWEEN b AND c`

 #### IGNORE\_BAD\_TABLE\_OPTIONS

 If this is set generate a warning (not an error) for wrong table option in CREATE TABLE. Also, since 10.0.13, do not comment out these wrong table options in [SHOW CREATE TABLE](../show-create-table/index).

 #### IGNORE\_SPACE

 Allow one to have spaces (including tab characters and new line characters) between function name and '('. The drawback is that this causes built in functions to become [reserved words](../reserved-words/index).

 #### MAXDB

 Same as: [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes), [IGNORE\_SPACE](#ignore_space), [MAXDB](#maxdb), [NO\_KEY\_OPTIONS](#no_key_options), [NO\_TABLE\_OPTIONS](#no_table_options), [NO\_FIELD\_OPTIONS](#no_field_options), [NO\_AUTO\_CREATE\_USER](#no_auto_create_user).

 Also has the effect of silently converting [TIMESTAMP](../timestamp/index) fields into [DATETIME](../datetime/index) fields when created or modified.

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### MSSQL

 Additionally implies the following: [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes), [IGNORE\_SPACE](#ignore_space), [NO\_KEY\_OPTIONS](#no_key_options), [NO\_TABLE\_OPTIONS](#no_table_options), [NO\_FIELD\_OPTIONS](#no_field_options).

 Additionally from [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), implements a limited subset of Microsoft SQL Server's language. See [SQL\_MODE=MSSQL](../sql_modemssql/index) for more.

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### MYSQL323

 Same as: [NO\_FIELD\_OPTIONS](#no_field_options), [HIGH\_NOT\_PRECEDENCE](#high_not_precedence).

 #### MYSQL40

 Same as: [NO\_FIELD\_OPTIONS](#no_field_options), [HIGH\_NOT\_PRECEDENCE](#high_not_precedence).

 #### NO\_AUTO\_CREATE\_USER

 Don't automatically create users with `GRANT` unless authentication information is specified. If none is provided, will produce a 1133 error: "Can't find any matching row in the user table". Default since [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/).

 #### NO\_AUTO\_VALUE\_ON\_ZERO

 If set, don't generate an [AUTO\_INCREMENT](../auto_increment/index) on [INSERT](../insert/index) of zero in an `AUTO_INCREMENT` column, or when adding an [AUTO\_INCREMENT](../auto_increment/index) attribute with the [ALTER TABLE](../alter-table/index) statement. Normally both `zero` and `NULL` generate new `AUTO_INCREMENT` values.

 #### NO\_BACKSLASH\_ESCAPES

 Disables using the backslash character `\` as an escape character within strings, making it equivalent to an ordinary character.

 #### NO\_DIR\_IN\_CREATE

 Ignore all INDEX DIRECTORY and DATA DIRECTORY directives when creating a table. Can be useful on slave [replication](../replication/index) servers.

 #### NO\_ENGINE\_SUBSTITUTION

 If not set, if the available storage engine specified by a CREATE TABLE is not available, a warning is given and the default storage engine is used instead. If set, generate a 1286 error when creating a table if the specified [storage engine](../storage-engines/index) is not available. See also [enforce\_storage\_engine](../server-system-variables/index#enforce_storage_engine). Default since [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/).

 #### NO\_FIELD\_OPTIONS

 Remove MariaDB-specific column options from the output of [SHOW CREATE TABLE](../show-create-table/index). This is also used by the portability mode of [mariadb-dump](../mariadb-dump/index).

 #### NO\_KEY\_OPTIONS

 Remove MariaDB-specific index options from the output of [SHOW CREATE TABLE](../show-create-table/index). This is also used by the portability mode of [mariadb-dump](../mariadb-dump/index).

 #### NO\_TABLE\_OPTIONS

 Remove MariaDB-specific table options from the output of [SHOW CREATE TABLE](../show-create-table/index). This is also used by the portability mode of [mariadb-dump](../mariadb-dump/index).

 #### NO\_UNSIGNED\_SUBTRACTION

 When enabled, subtraction results are signed even if the operands are unsigned.

 #### NO\_ZERO\_DATE

 Don't allow '0000-00-00' as a valid date in strict mode (produce a 1525 error). Zero dates can be inserted with [IGNORE](../ignore/index). If not in strict mode, a warning is generated.

 #### NO\_ZERO\_IN\_DATE

 Don't allow dates where the year is not zero but the month or day parts of the date *are* zero (produce a 1525 error). For example, with this set, '0000-00-00' is allowed, but '1970-00-10' or '1929-01-00' are not. If the ignore option is used, MariaDB will insert '0000-00-00' for those types of dates. If not in strict mode, a warning is generated instead.

 #### ONLY\_FULL\_GROUP\_BY

 For [SELECT ... GROUP BY](../select/index#group-by) queries, disallow [SELECTing](../select/index) columns which are not referred to in the GROUP BY clause, unless they are passed to an aggregate function like [COUNT()](../count/index) or [MAX()](../max/index). Produce a 1055 error.

 #### ORACLE

 In all versions of MariaDB up to [MariaDB 10.2](../what-is-mariadb-102/index), this sets `sql_mode` that is equivalent to: [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes), [IGNORE\_SPACE](#ignore_space), [NO\_KEY\_OPTIONS](#no_key_options), [NO\_TABLE\_OPTIONS](#no_table_options), [NO\_FIELD\_OPTIONS](#no_field_options), [NO\_AUTO\_CREATE\_USER](#no_auto_create_user)

 From [MariaDB 10.3](../what-is-mariadb-103/index), this mode also sets [SIMULTANEOUS\_ASSIGNMENT](#simultaneous_assignment) and configures the server to understand a large subset of Oracle's PL/SQL language instead of MariaDB's traditional syntax for stored routines. See [SQL\_MODE=ORACLE From MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index).

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### PAD\_CHAR\_TO\_FULL\_LENGTH

 Trailing spaces in [CHAR](../char/index) columns are by default trimmed upon retrieval. With PAD\_CHAR\_TO\_FULL\_LENGTH enabled, no trimming occurs. Does not apply to [VARCHARs](../varchar/index).

 #### PIPES\_AS\_CONCAT

 Allows using the pipe character (ASCII 124) as string concatenation operator. This means that `"A" || "B"` can be used in place of `CONCAT("A", "B")`.

 #### POSTGRESQL

 Same as: [PIPES\_AS\_CONCAT](#pipes_as_concat), [ANSI\_QUOTES](#ansi_quotes), [IGNORE\_SPACE](#ignore_space), [POSTGRESQL](#postgresql), [NO\_KEY\_OPTIONS](#no_key_options), [NO\_TABLE\_OPTIONS](#no_table_options), [NO\_FIELD\_OPTIONS](#no_field_options).

 If set, [SHOW CREATE TABLE](../show-create-table/index) output will not display MariaDB-specific table attributes.

 #### REAL\_AS\_FLOAT

 `REAL` is a synonym for [FLOAT](../float/index) rather than [DOUBLE](../double/index).

 #### SIMULTANEOUS\_ASSIGNMENT

 Setting this makes the SET part of the [UPDATE](../update/index) statement evaluate all assignments simultaneously, not left-to-right. From [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 #### STRICT\_ALL\_TABLES

 Strict mode. Statements with invalid or missing data are aborted and rolled back. For a non-transactional storage engine with a statement affecting multiple rows, this may mean a partial insert or update if the error is found in a row beyond the first.

 #### STRICT\_TRANS\_TABLES

 Strict mode. Statements with invalid or missing data are aborted and rolled back, except that for non-transactional storage engines and statements affecting multiple rows where the invalid or missing data is not the first row, MariaDB will convert the invalid value to the closest valid value, or, if a value is missing, insert the column default value. Default since [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/).

 #### TIME\_ROUND\_FRACTIONAL

 With this mode unset, MariaDB truncates fractional seconds when changing precision to smaller. When set, MariaDB will round when converting to TIME, DATETIME and TIMESTAMP, and truncate when converting to DATE. Since [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)

 #### TRADITIONAL

 Makes MariaDB work like a traditional SQL server. Same as: [STRICT\_TRANS\_TABLES](#strict_trans_tables), [STRICT\_ALL\_TABLES](#strict_all_tables), [NO\_ZERO\_IN\_DATE](#no_zero_in_date), [NO\_ZERO\_DATE](#no_zero_date), [ERROR\_FOR\_DIVISION\_BY\_ZERO](#error_for_division_by_zero), [TRADITIONAL](#traditional), [NO\_AUTO\_CREATE\_USER](#no_auto_create_user).

 Strict Mode
-----------

 A mode where at least one of `STRICT_TRANS_TABLES` or `STRICT_ALL_TABLES` is enabled is called *strict mode*.

 With strict mode set (default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)), statements that modify tables (either transactional for `STRICT_TRANS_TABLES` or all for `STRICT_ALL_TABLES`) will fail, and an error will be returned instead. The IGNORE keyword can be used when strict mode is set to convert the error to a warning.

 With strict mode not set (default in version <= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)), MariaDB will automatically adjust invalid values, for example, truncating strings that are too long, or adjusting numeric values that are out of range, and produce a warning. 

 Statements that don't modify data will return a warning when adjusted regardless of mode.

 SQL\_MODE and Stored Programs
-----------------------------

 [Stored programs and views](../stored-programs-and-views/index) always use the SQL\_MODE that was active when they were created. This means that users can safely change session or global SQL\_MODE; the stored programs they use will still work as usual.

 It is possible to change session SQL\_MODE within a stored program. In this case, the new SQL\_MODE will be in effect only in the body of the current stored program. If it calls some stored procedures, they will not be affected by the change.

 Some Information Schema tables (such as [ROUTINES](../information-schema-routines-table/index)) and SHOW CREATE statements such as [SHOW CREATE PROCEDURE](../show-create-procedure/index) show the SQL\_MODE used by the stored programs.

 Examples
--------

 This example shows how to get a readable list of enabled SQL\_MODE flags:

 
```
SELECT REPLACE(@@SQL_MODE, ',', '\n');
+-------------------------------------------------------------------------+
| REPLACE(@@SQL_MODE, ',', '\n')                                          |
+-------------------------------------------------------------------------+
| STRICT_TRANS_TABLES
NO_ZERO_IN_DATE
NO_ZERO_DATE
NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------+

```

Adding a new flag:

 
```
SET @@SQL_MODE = CONCAT(@@SQL_MODE, ',NO_ENGINE_SUBSTITUTION');

```

If the specified flag is already ON, the above example has no effect but does not produce an error.

 How to unset a flag:

 
```
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ENGINE_SUBSTITUTION', '');

```

How to check if a flag is set:

 
```
SELECT @@SQL_MODE LIKE '%NO_ZERO_DATE%';
+----------------------------------+
| @@SQL_MODE LIKE '%NO_ZERO_DATE%' |
+----------------------------------+
|                                1 |
+----------------------------------+

```

Without and with strict mode:

 
```
CREATE TABLE strict (s CHAR(5), n TINYINT);

INSERT INTO strict VALUES ('MariaDB', '128');
Query OK, 1 row affected, 2 warnings (0.14 sec)

SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1265 | Data truncated for column 's' at row 1     |
| Warning | 1264 | Out of range value for column 'n' at row 1 |
+---------+------+--------------------------------------------+
2 rows in set (0.00 sec)

SELECT * FROM strict;
+-------+------+
| s     | n    |
+-------+------+
| Maria |  127 |
+-------+------+

SET sql_mode='STRICT_TRANS_TABLES';

INSERT INTO strict VALUES ('MariaDB', '128');
ERROR 1406 (22001): Data too long for column 's' at row 1

```

Overriding strict mode with the IGNORE keyword:

 
```
INSERT IGNORE INTO strict VALUES ('MariaDB', '128');
Query OK, 1 row affected, 2 warnings (0.15 sec)

```

See Also
--------

 * [SQL\_MODE=MSSQL](../sql_modemssql/index)
* [SQL\_MODE=ORACLE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-mode/>

Securing MariaDB
=================

   
This section is about securing your MariaDB installation. If you are looking for the list of security vulnerabilities fixed in MariaDB, see [Security Vulnerabilities Fixed in MariaDB](../cve/index).

 
There are a number of issues to consider when looking at improving the security of your MariaDB installation. These include:

  

| Title | Description |
| --- | --- |
|  [Encryption](../securing-mariadb-encryption/index) |  MariaDB supports encryption for data while at rest and while in transit.  |
|  [Running mysqld as root](../running-mysqld-as-root/index) |  MariaDB should never normally be run as root  |
|  [mysql\_secure\_installation](../mysql_secure_installation/index) |  Symlink or old name for mariadb-secure-installation.  |
|  [SecuRich](../securich/index) |  Library of security-related stored procedures.  |
|  [SELinux](../selinux/index) |  Security-Enhanced Linux (SELinux) is a Linux kernel module that provides a ...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/securing-mariadb/>

User Account Management
========================

   Administering user accounts in MariaDB

  

| Title | Description |
| --- | --- |
|  [Account Management SQL Commands](../account-management-sql-commands/index) |  CREATE/DROP USER, GRANT, REVOKE, SET PASSWORD etc.  |
|  [Data-in-Transit Encryption](../data-in-transit-encryption/index) |  Data can be encrypted in transit using the Transport Layer Security (TLS) protocol.  |
|  [Roles](../roles/index) |  Roles bundle privileges together to ease account management.  |
|  [Catalogs](../catalogs/index) |  Catalogs permit several unrelated users or customers to share a single MariaDB Server instance.  |
|  [Account Locking](../account-locking/index) |  Account locking permits privileged administrators to lock/unlock user accounts.  |
|  [Authentication from MariaDB 10.4](../authentication-from-mariadb-10-4/index) |  Authentication changes from MariaDB 10.4.  |
|  [User Password Expiry](../user-password-expiry/index) |  Password expiry permits administrators to expire user passwords.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-account-management/>

SQL Statements
===============

   Complete list of SQL statements for data definition, data manipulation, etc.

  

| Title | Description |
| --- | --- |
|  [Account Management SQL Commands](../account-management-sql-commands/index) |  CREATE/DROP USER, GRANT, REVOKE, SET PASSWORD etc.  |
|  [Administrative SQL Statements](../administrative-sql-statements/index) |  SQL statements for setting, flushing and displaying server variables and resources.  |
|  [Data Definition](../data-definition/index) |  SQL commands for defining data, such as ALTER, CREATE, DROP, RENAME etc.  |
|  [Data Manipulation](../data-manipulation/index) |  SQL commands for querying and manipulating data, such as SELECT, UPDATE, DELETE etc.  |
|  [Prepared Statements](../prepared-statements/index) |  Prepared statements from any client using the text based prepared statement interface.  |
|  [Programmatic & Compound Statements](../programmatic-compound-statements/index) |  Compound SQL statements for stored routines and in general.  |
|  [Stored Routine Statements](../stored-routine-statements/index) |  SQL statements related to creating and using stored routines.  |
|  [Table Statements](../table-statements/index) |  Documentation on creating, altering, analyzing and maintaining tables.  |
|  [Transactions](../transactions/index) |  Sequence of statements that are either completely successful, or have no effect on any schemas  |
|  [HELP Command](../help-command/index) |  The HELP command will retrieve syntax and help within the mariadb client.  |
|  [Comment Syntax](../comment-syntax/index) |  Comment syntax and style.  |
|  [Built-in Functions](../built-in-functions/index) |  Functions and procedures in MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-statements/>

Function and Operator Reference
===============================

    


| Name | Description | Added |
| --- | --- | --- |
| [+](../addition-operator/index) | Addition operator |  |
| [/](../division-operator/index) | Division operator |  |
| [\*](../multiplication-operator/index) | Multiplication operator |  |
| [%](../modulo-operator/index) | Modulo operator. Returns the remainder of N divided by M |  |
| [-](../subtraction-operator-/index) | Subtraction operator |  |
| [!=](../not-equal/index) | Not equals |  |
| [<](../less-than/index) | Less than |  |
| [<=](../less-than-or-equal/index) | Less than or equal |  |
| [<=>](../null-safe-equal/index) | NULL-safe equal |  |
| [=](../equal/index) | Equal |  |
| [>](../greater-than/index) | Greater than |  |
| [>=](../greater-than-or-equal/index) | Greater than or equal |  |
| [&](../bitwise_and/index) | Bitwise AND |  |
| [<<](../shift-left/index) | Shift left |  |
| [>>](../shift-right/index) | Shift right |  |
| [^](../bitwise-xor/index) | Bitwise XOR |  |
| [!](../not/index) | Logical NOT |  |
| [&&](../and/index) | Logical AND |  |
| [XOR](../xor/index) | Logical XOR |  |
| `||` | Logical OR |  |
| `|` | [Bitwise OR](../bitwise-or/index) |  |
| [:=](../assignment-operator/index) | Assignment operator |  |
| [=](../assignment-operators-assignment-operator/index) | Assignment and comparison operator |  |
| ~ | [Bitwise NOT](../bitwise-not/index) |  |
| [ABS](../abs/index) | Returns an absolute value |  |
| [ACOS](../acos/index) | Returns an arc cosine |  |
| [ADD\_MONTHS](../add_months/index) | Add months to a date |  |
| [ADDDATE](../adddate/index) | Add days or another interval to a date |  |
| [ADDTIME](../addtime/index) | Adds a time to a time or datetime |  |
| [AES\_DECRYPT](../aes_decrypt/index) | Decryption data encrypted with AES\_ENCRYPT |  |
| [AES\_ENCRYPT](../aes_encrypt/index) | Encrypts a string with the AES algorithm |  |
| [AREA](../area/index) | Synonym for ST\_AREA |  |
| [AsBinary](../asbinary/index) | Synonym for ST\_AsBinary |  |
| [ASCII](../ascii/index) | Numeric ASCII value of leftmost character |  |
| [ASIN](../asin/index) | Returns the arc sine |  |
| [AsText](../astext/index) | Synonym for ST\_AsText |  |
| [AsWKB](../aswkb/index) | Synonym for ST\_AsBinary |  |
| [AsWKT](../aswkt/index) | Synonym for ST\_AsText |  |
| [ATAN](../atan/index) | Returns the arc tangent |  |
| [ATAN2](../atan2/index) | Returns the arc tangent of two variables |  |
| [AVG](../avg/index) | Returns the average value |  |
| [BENCHMARK](../benchmark/index) | Executes an expression repeatedly |  |
| [BETWEEN AND](../between-and/index) | True if expression between two values |  |
| [BIN](../bin/index) | Returns binary value |  |
| [BINARY OPERATOR](../binary-operator/index) | Casts to a binary string |  |
| [BINLOG\_GTID\_POS](../binlog_gtid_pos/index) | Returns a string representation of the corresponding GTID position |
| [BIT\_AND](../bit_and/index) | Bitwise AND |  |
| [BIT\_COUNT](../bit_count/index) | Returns the number of set bits |  |
| [BIT\_LENGTH](../bit_length/index) | Returns the length of a string in bits |  |
| [BIT\_OR](../bit_or/index) | Bitwise OR |  |
| [BIT\_XOR](../bit_xor/index) | Bitwise XOR |  |
| [BOUNDARY](../boundary/index) | Synonym for ST\_BOUNDARY |  |
| [BUFFER](../buffer/index) | Synonym for ST\_BUFFER |  |
| [CASE](../case-operator/index) | Returns the result where value=compare\_value or for the first condition that is true |  |
| [CAST](../cast/index) | Casts a value of one type to another type |  |
| [CEIL](../ceil/index) | Synonym for CEILING() |  |
| [CEILING](../ceiling/index) | Returns the smallest integer not less than X |  |
| [CENTROID](../centroid/index) | Synonym for ST\_CENTROID |  |
| [CHAR Function](../char-function/index) | Returns string based on the integer values for the individual characters |  |
| [CHARACTER\_LENGTH](../character_length/index) | Synonym for CHAR\_LENGTH() |  |
| [CHAR\_LENGTH](../char_length/index) | Length of the string in characters |  |
| [CHARSET](../charset/index) | Returns the character set |  |
| [CHR](../chr/index) | Returns a string consisting of the character given by the code values of the integer |  |
| [COALESCE](../coalesce/index) | Returns the first non-NULL parameter |  |
| [COERCIBILITY](../coercibility/index) | Returns the collation coercibility value |  |
| [COLLATION](../collation/index) | Collation of the string argument |  |
| [COLUMN\_ADD](../column_add/index) | Adds or updates dynamic columns |  |
| [COLUMN\_CHECK](../column_check/index) | Checks if a dynamic column blob is valid |  |
| [COLUMN\_CREATE](../column_create/index) | Returns a dynamic columns blob |  |
| [COLUMN\_DELETE](../column_delete/index) | Deletes a dynamic column |  |
| [COLUMN\_EXISTS](../column_exists/index) | Checks is a column exists |  |
| [COLUMN\_GET](../column_get/index) | Gets a dynamic column value by name |  |
| [COLUMN\_JSON](../column_json/index) | Returns a JSON representation of dynamic column blob data |  |
| [COLUMN\_LIST](../column_list/index) | Returns comma-separated list |  |
| [COMPRESS](../compress/index) | Returns a binary, compressed string |  |
| [CONCAT](../concat/index) | Returns concatenated string |  |
| [CONCAT\_WS](../concat_ws/index) | Concatenate with separator |  |
| [CONNECTION\_ID](../connection_id/index) | Connection thread ID |  |
| [CONTAINS](../contains/index) | Whether one geometry contains another |  |
| [CONVERT](../convert/index) | Convert a value from one type to another type |  |
| [CONV](../conv/index) | Converts numbers between different number bases |  |
| [CONVERT\_TZ](../convert_tz/index) | Converts a datetime from on time zone to another |  |
| [CONVEXHULL](../convexhull/index) | Synonym for ST\_CONVEXHULL |  |
| [COS](../cos/index) | Returns the cosine |  |
| [COT](../cot/index) | Returns the cotangent |  |
| [COUNT](../count/index) | Returns count of non-null values |  |
| [COUNT DISTINCT](../count-distinct/index) | Returns count of number of different non-NULL values |  |
| [CRC32](../crc32/index) | Computes a cyclic redundancy check value |  |
| [CRC32C](../crc32c/index) | Computes a cyclic redundancy check value | [MariaDB 10.8](../what-is-mariadb-108/index) |
| [CROSSES](../crosses/index) | Whether two geometries spatially cross |  |
| [CUME\_DIST](../cume_dist/index) | Window function that returns the cumulative distribution of a given row |  |
| [CURDATE](../curdate/index) | Returns the current date |  |
| [CURRENT\_DATE](../current_date/index) | Synonym for CURDATE() |  |
| [CURRENT\_ROLE](../current_role/index) | Current role name |  |
| [CURRENT\_TIME](../current_time/index) | Synonym for CURTIME() |  |
| [CURRENT\_TIMESTAMP](../current_timestamp/index) | Synonym for NOW() |  |
| [CURRENT\_USER](../current_user/index) | Username/host that authenicated the current client |  |
| [CURTIME](../curtime/index) | Returns the current time |  |
| [DATABASE](../database/index) | Current default database |  |
| [DATE FUNCTION](../date-function/index) | Extracts the date portion of a datetime |  |
| [DATEDIFF](../datediff/index) | Difference in days between two date/time values |  |
| [DATE\_ADD](../date_add/index) | Date arithmetic - addition |  |
| [DATE\_FORMAT](../date_format/index) | Formats the date value according to the format string |  |
| [DATE\_SUB](../date_sub/index) | Date arithmetic - subtraction |  |
| [DAY](../day/index) | Synonym for DAYOFMONTH() |  |
| [DAYNAME](../dayname/index) | Return the name of the weekday |  |
| [DAYOFMONTH](../dayofmonth/index) | Returns the day of the month |  |
| [DAYOFWEEK](../dayofweek/index) | Returns the day of the week index |  |
| [DAYOFYEAR](../dayofyear/index) | Returns the day of the year |  |
| [DECODE](../decode/index) | Decrypts a string encoded with ENCODE() |  |
| [DECODE\_HISTOGRAM](../decode_histogram/index) | Returns comma separated numerics corresponding to a probability distribution represented by a histogram |  |
| [DEFAULT](../default/index) | Returns column default |  |
| [DEGREES](../degrees/index) | Converts from radians to degrees |  |
| [DENSE\_RANK](../dense_rank/index) | Rank of a given row with identical values receiving the same result, no skipping |  |
| [DES\_DECRYPT](../des_decrypt/index) | Decrypts a string encrypted with DES\_ENCRYPT() |  |
| [DES\_ENCRYPT](../des_encrypt/index) | Encrypts a string using the Triple-DES algorithm |  |
| [DIMENSION](../dimension/index) | Synonym for ST\_DIMENSION |  |
| [DISJOINT](../disjoint/index) | Whether the two elements do not intersect |  |
| [DIV](../div/index) | Integer division |  |
| [ELT](../elt/index) | Returns the N'th element from a set of strings |  |
| [ENCODE](../encode/index) | Encrypts a string |  |
| [ENCRYPT](../encrypt/index) | Encrypts a string with Unix crypt() |  |
| [ENDPOINT](../endpoint/index) | Synonym for ST\_ENDPOINT |  |
| [ENVELOPE](../envelope/index) | Synonym for ST\_ENVELOPE |  |
| [EQUALS](../equals/index) | Indicates whether two geometries are spatially equal |  |
| [EXP](../exp/index) | e raised to the power of the argument |  |
| [EXPORT\_SET](../export_set/index) | Returns an on string for every bit set, an off string for every bit not set |  |
| [ExteriorRing](../exteriorring/index) | Synonym for ST\_ExteriorRing |  |
| [EXTRACT](../extract/index) | Extracts a portion of the date |  |
| [EXTRACTVALUE](../extractvalue/index) | Returns the text of the first text node matched by the XPath expression |  |
| [FIELD](../field/index) | Returns the index position of a string in a list |  |
| [FIND\_IN\_SET](../find_in_set/index) | Returns the position of a string in a set of strings |  |
| [FLOOR](../floor/index) | Largest integer value not greater than the argument |  |
| [FORMAT](../format/index) | Formats a number |  |
| [FORMAT\_PICO\_TIME](../format_pico_time/index) | Given a time in picoseconds, returns a human-readable time value and unit indicator | [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/) |
| [FOUND\_ROWS](../found_rows/index) | Number of (potentially) returned rows |  |
| [FROM\_BASE64](../from_base64/index) | Given a base-64 encoded string, returns the decoded result as a binary string |  |
| [FROM\_DAYS](../from_days/index) | Returns a date given a day |  |
| [FROM\_UNIXTIME](../from_unixtime/index) | Returns a datetime from a Unix timestamp |  |
| [GeomCollFromText](../geomcollfromtext/index) | Synonym for ST\_GeomCollFromText |  |
| [GeomCollFromWKB](../geomcollfromwkb/index) | Synonym for ST\_GeomCollFromWKB |  |
| [GeometryCollectionFromText](../geometrycollectionfromtext/index) | Synonym for ST\_GeomCollFromText |  |
| [GeometryCollectionFromWKB](../geometrycollectionfromwkb/index) | Synonym for ST\_GeomCollFromWKB |  |
| [GeometryFromText](../geometryfromtext/index) | Synonym for ST\_GeomFromText |  |
| [GeometryFromWKB](../geometryfromwkb/index) | Synonym for ST\_GeomFromWKB |  |
| [GeomFromText](../geomfromtext/index) | Synonym for ST\_GeomFromText |  |
| [GeomFromWKB](../geomfromwkb/index) | Synonym for ST\_GeomFromWKB |  |
| [GeometryN](../geometryn/index) | Synonym for ST\_GeometryN |  |
| [GEOMETRYCOLLECTION](../geometrycollection/index) | Constructs a WKB GeometryCollection |  |
| [GeometryType](../geometrytype/index) | Synonym for ST\_GeometryType |  |
| [GET\_FORMAT](../get_format/index) | Returns a format string |  |
| [GET\_LOCK](../get_lock/index) | Obtain LOCK |  |
| [GLENGTH](../glength/index) | Length of a LineString value |  |
| [GREATEST](../greatest/index) | Returns the largest argument |  |
| [GROUP\_CONCAT](../group_concat/index) | Returns string with concatenated values from a group |  |
| [HEX](../hex/index) | Returns hexadecimal value |  |
| [HOUR](../hour/index) | Returns the hour |  |
| [IF](../if-function/index) | If expr1 is TRUE, returns expr2; otherwise returns expr3 |  |
| [IFNULL](../ifnull/index) | Check whether an expression is NULL |  |
| [IN](../in/index) | True if expression equals any of the values in the list |  |
| [INTERVAL](../interval/index) | Index of the argument that is less than the first argument |  |
| [INET6\_ATON](../inet6_aton/index) | Given an IPv6 or IPv4 network address, returns a VARBINARY numeric value |  |
| [INET6\_NTOA](../inet6_ntoa/index) | Given an IPv6 or IPv4 network address, returns the address as a nonbinary string |  |
| [INET\_ATON](../inet_aton/index) | Returns numeric value of IPv4 address |  |
| [INET\_NTOA](../inet_ntoa/index) | Returns dotted-quad representation of IPv4 address |  |
| [INSERT Function](../insert-function/index) | Replaces a part of a string with another string |  |
| [INSTR](../instr/index) | Returns the position of a string withing a string |  |
| [InteriorRingN](../interiorringn/index) | Synonym for ST\_InteriorRingN |  |
| [INTERSECTS](../intersects/index) | Indicates whether two geometries spatially intersect |  |
| [IS](../is/index) | Tests whether a boolean is TRUE, FALSE, or UNKNOWN |  |
| [IsClosed](../isclosed/index) | Synonym for ST\_IsClosed |  |
| [IsEmpty](../isempty/index) | Synonym for ST\_IsEmpty |  |
| [IS\_FREE\_LOCK](../is_free_lock/index) | Checks whether lock is free to use |  |
| [IS\_IPV4](../is_ipv4/index) | Whether or not an expression is a valid IPv4 address |  |
| [IS\_IPV4\_COMPAT](../is_ipv4_compat/index) | Whether or not an IPv6 address is IPv4-compatible |  |
| [IS\_IPV4\_MAPPED](../is_ipv4_mapped/index) | Whether an IPv6 address is a valid IPv4-mapped address |  |
| [IS\_IPV6](../is_ipv6/index) | Whether or not an expression is a valid IPv6 address |  |
| [IS NOT](../is-not/index) | Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN |  |
| [IS NOT NULL](../is-not-null/index) | Tests whether a value is not NULL |  |
| [IS NULL](../is-null/index) | Tests whether a value is NULL |  |
| [ISNULL](../isnull/index) | Checks if an expression is NULL |  |
| [IsRing](../isring/index) | Synonym for ST\_IsRing |  |
| [IsSimple](../geometry-properties-issimple/index) | Synonym for ST\_IsSimple |  |
| [IS\_USED\_LOCK](../is_used_lock/index) | Check if lock is in use |  |
| [JSON\_ARRAY](../json_array/index) | Returns a JSON array containing the listed values |  |
| [JSON\_ARRAY\_INTERSECT](../json_array_intersect/index) |  | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [JSON\_ARRAY\_APPEND](../json_array_append/index) | Appends values to the end of the given arrays within a JSON document |  |
| [JSON\_ARRAY\_INSERT](../json_array_insert/index) | Inserts a value into a JSON document |  |
| [JSON\_COMPACT](../json_compact/index) | Removes all unnecessary spaces so the json document is as short as possible |  |
| [JSON\_CONTAINS](../json_contains/index) | Whether a value is found in a given JSON document or at a specified path within the document |  |
| [JSON\_CONTAINS\_PATH](../json_contains_path/index) | Indicates whether the given JSON document contains data at the specified path or paths |  |
| [JSON\_DEPTH](../json_depth/index) | Maximum depth of a JSON document |  |
| [JSON\_DETAILED](../json_detailed/index) | Represents JSON in the most understandable way emphasizing nested structures |  |
| [JSON\_EQUALS](../json_equals/index) | Check for equality between JSON objects. |  |
| [JSON\_EXISTS](../json_exists/index) | Determines whether a specified JSON value exists in the given data |  |
| [JSON\_EXTRACT](../json_extract/index) | Extracts data from a JSON document. |  |
| [JSON\_INSERT](../json_insert/index) | Inserts data into a JSON document |  |
| [JSON\_KEYS](../json_keys/index) | Returns keys from top-level value of a JSON object or top-level keys from the path |  |
| [JSON\_LENGTH](../json_length/index) | Returns the length of a JSON document, or the length of a value within the document |  |
| [JSON\_LOOSE](../json_loose/index) | Adds spaces to a JSON document to make it look more readable |  |
| [JSON\_MERGE](../json_merge/index) | Merges the given JSON documents |  |
| [JSON\_MERGE\_PATCH](../json_merge/index) | RFC 7396-compliant merge of the given JSON documents |  |
| [JSON\_MERGE\_PRESERVE](../json_merge/index) | Synonym for [JSON\_MERGE\_PATCH](../json_merge/index). |  |
| [JSON\_NORMALIZE](../json_normalize/index) | Recursively sorts keys and removes spaces, allowing comparison of json documents for equality |  |
| [JSON\_OBJECT](../json_object/index) | Returns a JSON object containing the given key/value pairs |  |
| [JSON\_OBJECT\_FILTER\_KEYS](../json_object_filter_keys/index) |  | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [JSON\_OBJECT\_TO\_ARRAY](../json_object_to_array/index) |  | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [JSON\_OBJECTAGG](../json_objectagg/index) | Returns a JSON object containing key-value pairs |  |
| [JSON\_OVERLAPS](../json_overlaps/index) | Compares two json documents for overlaps |  |
| [JSON\_PRETTY](../json_pretty/index) | Alias for [json\_detailed](../json_detailed/index) | [MariaDB 10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), [MariaDB 10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [MariaDB 10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [MariaDB 10.7.8](https://mariadb.com/kb/en/mariadb-1078-release-notes/), [MariaDB 10.6.12](https://mariadb.com/kb/en/mariadb-10612-release-notes/), [MariaDB 10.5.19](https://mariadb.com/kb/en/mariadb-10519-release-notes/) and [MariaDB 10.4.28](https://mariadb.com/kb/en/mariadb-10428-release-notes/) |
| [JSON\_QUERY](../json_query/index) | Given a JSON document, returns an object or array specified by the path |  |
| [JSON\_QUOTE](../json_quote/index) | Quotes a string as a JSON value |  |
| [JSON\_REMOVE](../json_remove/index) | Removes data from a JSON document |  |
| [JSON\_REPLACE](../json_replace/index) | Replaces existing values in a JSON document |  |
| [JSON\_SCHEMA\_VALID](../json_schema_valid/index) | Validates a JSON schema | [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/) |
| [JSON\_SEARCH](../json_search/index) | Returns the path to the given string within a JSON document |  |
| [JSON\_SET](../json_set/index) | Updates or inserts data into a JSON document |  |
| [JSON\_TABLE](../json_table/index) | Returns a representation of a JSON document as a relational table |  |
| [JSON\_TYPE](../json_type/index) | Returns the type of a JSON value |  |
| [JSON\_UNQUOTE](../json_unquote/index) | Unquotes a JSON value, returning a string |  |
| [JSON\_VALID](../json_valid/index) | Whether a value is a valid JSON document or not |  |
| [JSON\_VALUE](../json_value/index) | Given a JSON document, returns the specified scalar |  |
| [LAST\_DAY](../last_day/index) | Returns the last day of the month |  |
| [LAST\_INSERT\_ID](../last_insert_id/index) | Last inserted autoinc value |  |
| [LAST\_VALUE](../last_value/index) | Returns the last value in a list |  |
| [LASTVAL](../previous-value-for-sequence_name/index) | Get last value generated from a sequence |  |
| [LCASE](../lcase/index) | Synonym for [LOWER() |  |
| [LEAST](../least/index) | Returns the smallest argument |  |
| [LEFT](../left/index) | Returns the leftmost characters from a string |  |
| [LENGTH](../length/index) | Length of the string in bytes |  |
| [LIKE](../like/index) | Whether expression matches a pattern |  |
| [LineFromText](../linefromtext/index) | Synonym for ST\_LineFromText |  |
| [LineFromWKB](../linefromwkb/index) | Synonym for ST\_LineFromWKB |  |
| [LINESTRING](../linestring/index) | Constructs a WKB LineString value from a number of WKB Point arguments |  |
| [LineStringFromText](../linestringfromtext/index) | Synonym for ST\_LineFromText |  |
| [LineStringFromWKB](../linestringfromwkb/index) | Synonym for ST\_LineFromWKB |  |
| [LN](../ln/index) | Returns natural logarithm |  |
| [LOAD\_FILE](../load_file/index) | Returns file contents as a string |  |
| [LOCALTIME](../localtime/index) | Synonym for NOW() |  |
| [LOCALTIMESTAMP](../localtimestamp/index) | Synonym for NOW() |  |
| [LOCATE](../locate/index) | Returns the position of a substring in a string |  |
| [LOG](../log/index) | Returns the natural logarithm |  |
| [LOG10](../log10/index) | Returns the base-10 logarithm |  |
| [LOG2](../log2/index) | Returns the base-2 logarithm |  |
| [LOWER](../lower/index) | Returns a string with all characters changed to lowercase |  |
| [LPAD](../lpad/index) | Returns the string left-padded with another string to a given length |  |
| [LTRIM](../ltrim/index) | Returns the string with leading space characters removed |  |
| [MAKE\_SET](../make_set/index) | Make a set of strings that matches a bitmask |  |
| [MAKEDATE](../makedate/index) | Returns a date given a year and day |  |
| [MAKETIME](../maketime/index) | Returns a time |  |
| [MASTER\_GTID\_WAIT](../master_gtid_wait/index) | Wait until slave reaches the GTID position |  |
| [MASTER\_POS\_WAIT](../master_pos_wait/index) | Blocks until the slave has applied all specified updates |  |
| [MATCH AGAINST](../match-against/index) | Perform a fulltext search on a fulltext index |  |
| [MAX](../max/index) | Returns the maximum value |  |
| [MBRContains](../mbrcontains/index) | Indicates one Minimum Bounding Rectangle contains another |  |
| [MBRDisjoint](../mbrdisjoint/index) | Indicates whether the Minimum Bounding Rectangles of two geometries are disjoint |  |
| [MBREqual](../mbrequal/index) | Whether the Minimum Bounding Rectangles of two geometries are the same. |  |
| [MBRIntersects](../mbrintersects/index) | Indicates whether the Minimum Bounding Rectangles of the two geometries intersect |  |
| [MBROverlaps](../mbroverlaps/index) | Whether the Minimum Bounding Rectangles of two geometries overlap |  |
| [MBRTouches](../mbrtouches/index) | Whether the Minimum Bounding Rectangles of two geometries touch. |  |
| [MBRWithin](../mbrwithin/index) | Indicates whether one Minimum Bounding Rectangle is within another |  |
| [MD5](../md5/index) | MD5 checksum |  |
| [MEDIAN](../median/index) | Window function that returns the median value of a range of values |  |
| [MICROSECOND](../microsecond/index) | Returns microseconds from a date or datetime |  |
| [MID](../mid/index) | Synonym for SUBSTRING(str,pos,len) |  |
| [MIN](../min/index) | Returns the minimum value |  |
| [MINUTE](../minute/index) | Returns a minute from 0 to 59 |  |
| [MLineFromText](../mlinefromtext/index) | Constructs MULTILINESTRING using its WKT representation and SRID |  |
| [MLineFromWKB](../mlinefromwkb/index) | Constructs a MULTILINESTRING |  |
| [MOD](../mod/index) | Modulo operation. Remainder of N divided by M |  |
| [MONTH](../month/index) | Returns a month from 1 to 12 |  |
| [MONTHNAME](../monthname/index) | Returns the full name of the month |  |
| [MPointFromText](../mpointfromtext/index) | Constructs a MULTIPOINT value using its WKT and SRID |  |
| [MPointFromWKB](../mpointfromwkb/index) | Constructs a MULTIPOINT value using its WKB representation and SRID |  |
| [MPolyFromText](../mpolyfromtext/index) | Constructs a MULTIPOLYGON value |  |
| [MPolyFromWKB](../mpolyfromwkb/index) | Constructs a MULTIPOLYGON value using its WKB representation and SRID |  |
| [MultiLineStringFromText](../multilinestringfromtext/index) | Synonym for MLineFromText |  |
| [MultiLineStringFromWKB](../multilinestringfromwkb/index) | A synonym for MLineFromWKB |  |
| [MULTIPOINT](../multipoint/index) | Constructs a WKB MultiPoint value |  |
| [MultiPointFromText](../multipointfromtext/index) | Synonym for MPointFromText |  |
| [MultiPointFromWKB](../multipointfromwkb/index) | Synonym for MPointFromWKB |  |
| [MULTIPOLYGON](../multipolygon/index) | Constructs a WKB MultiPolygon |  |
| [MultiPolygonFromText](../multipolygonfromtext/index) | Synonym for MPolyFromText |  |
| [MultiPolygonFromWKB](../multipolygonfromwkb/index) | Synonym for MPolyFromWKB |  |
| [MULTILINESTRING](../multilinestring/index) | Constructs a MultiLineString value |  |
| [NAME\_CONST](../name_const/index) | Returns the given value |  |
| [NATURAL\_SORT\_KEY](../natural_sort_key/index) | Sorting that is more more similar to natural human sorting |  |
| [NOT LIKE](../not-like/index) | Same as NOT(expr LIKE pat [ESCAPE 'escape\_char']) |  |
| [NOT REGEXP](../not-regexp/index) | Same as NOT (expr REGEXP pat) |  |
| [NULLIF](../nullif/index) | Returns NULL if expr1 = expr2 |  |
| [NEXTVAL](../next-value-for-sequence_name/index) | Generate next value for sequence |  |
| [NOT BETWEEN](../not-between/index) | Same as NOT (expr BETWEEN min AND max) |  |
| [NOT IN](../not-in/index) | Same as NOT (expr IN (value,...)) |  |
| [NOW](../now/index) | Returns the current date and time |  |
| [NTILE](../ntile/index) | Returns an integer indicating which group a given row falls into |  |
| [NumGeometries](../numgeometries/index) | Synonym for ST\_NumGeometries |  |
| [NumInteriorRings](../numinteriorrings/index) | Synonym for NumInteriorRings |  |
| [NumPoints](../numpoints/index) | Synonym for ST\_NumPoints |  |
| [OCT](../oct/index) | Returns octal value |  |
| [OCTET\_LENGTH](../octet_length/index) | Synonym for LENGTH() |  |
| [OLD\_PASSWORD](../old_password/index) | Pre MySQL 4.1 password implementation |  |
| [ORD](../ord/index) | Return ASCII or character code |  |
| [OVERLAPS](../overlaps/index) | Indicates whether two elements spatially overlap |  |
| [PASSWORD](../password/index) | Calculates a password string |  |
| [PERCENT\_RANK](../percent_rank/index) | Window function that returns the relative percent rank of a given row |  |
| [PERCENTILE\_CONT](../percentile_cont/index) | Returns a value which corresponds to the given fraction in the sort order. |  |
| [PERCENTILE\_DISC](../percentile_disc/index) | Returns the first value in the set whose ordered position is the same or more than the specified fraction. |  |
| [PERIOD\_ADD](../period_add/index) | Add months to a period |  |
| [PERIOD\_DIFF](../period_diff/index) | Number of months between two periods |  |
| [PI](../pi/index) | Returns the value of π (pi) |  |
| [POINT](../point/index) | Constructs a WKB Point |  |
| [PointFromText](../pointfromtext/index) | Synonym for ST\_PointFromText |  |
| [PointFromWKB](../pointfromwkb/index) | Synonym for PointFromWKB |  |
| [PointN](../pointn/index) | Synonym for PointN |  |
| [PointOnSurface](../pointonsurface/index) | Synonym for ST\_PointOnSurface |  |
| [POLYGON](../polygon/index) | Constructs a WKB Polygon value from a number of WKB LineString arguments |  |
| [PolyFromText](../polyfromtext/index) | Synonym for ST\_PolyFromText |  |
| [PolyFromWKB](../polyfromwkb/index) | Synonym for ST\_PolyFromWKB |  |
| [PolygonFromText](../polygonfromtext/index) | Synonym for ST\_PolyFromText |  |
| [PolygonFromWKB](../polygonfromwkb/index) | Synonym for ST\_PolyFromWKB |  |
| [POSITION](../position/index) | Returns the position of a substring in a string |  |
| [POW](../pow/index) | Returns X raised to the power of Y |  |
| [POWER](../power/index) | Synonym for POW() |  |
| [QUARTER](../quarter/index) | Returns year quarter from 1 to 4 |  |
| [QUOTE](../quote/index) | Returns quoted, properly escaped string |  |
| [RADIANS](../radians/index) | Converts from degrees to radians |  |
| [RAND](../rand/index) | Random floating-point value |  |
| [RANK](../rank/index) | Rank of a given row with identical values receiving the same result |  |
| [REGEXP](../regexp/index) | Performs pattern matching |  |
| [REGEXP\_INSTR](../regexp_instr/index) | Position of the first appearance of a regex |  |
| [REGEXP\_REPLACE](../regexp_replace/index) | Replaces all occurrences of a pattern |  |
| [REGEXP\_SUBSTR](../regexp_substr/index) | Returns the matching part of a string |  |
| [RELEASE\_LOCK](../release_lock/index) | Releases lock obtained with GET\_LOCK() |  |
| [REPEAT Function](../repeat-function/index) | Returns a string repeated a number of times |  |
| [REPLACE Function](../replace-function/index) | Replace occurrences of a string |  |
| [REVERSE](../reverse/index) | Reverses the order of a string |  |
| [RIGHT](../right/index) | Returns the rightmost N characters from a string |  |
| [RLIKE](../rlike/index) | Synonym for REGEXP() |  |
| [RPAD](../rpad/index) | Returns the string right-padded with another string to a given length |  |
| [ROUND](../round/index) | Rounds a number |  |
| [ROW\_COUNT](../row_count/index) | Number of rows affected by previous statement |  |
| [ROW\_NUMBER](../row_number/index) | Row number of a given row with identical values receiving a different result |  |
| [RTRIM](../rtrim/index) | Returns the string with trailing space characters removed |  |
| [SCHEMA](../schema/index) | Synonym for DATABASE() |  |
| [SECOND](../second/index) | Returns the second of a time |  |
| [SEC\_TO\_TIME](../sec_to_time/index) | Converts a second to a time |  |
| [SETVAL](../setval/index) | Set the next value to be returned by a sequence |  |
| [SESSION\_USER](../session_user/index) | Synonym for USER() |  |
| [SHA](sha) | Synonym for SHA1() |  |
| [SHA1](../sha1/index) | Calculates an SHA-1 checksum |  |
| [SHA2](../sha2/index) | Calculates an SHA-2 checksum |  |
| [SIGN](../sign/index) | Returns 1, 0 or -1 |  |
| [SIN](../sin/index) | Returns the sine |  |
| [SLEEP](../sleep/index) | Pauses for the given number of seconds |  |
| [SOUNDEX](../soundex/index) | Returns a string based on how the string sounds |  |
| [SOUNDS LIKE](../sounds-like/index) | SOUNDEX(expr1) = SOUNDEX(expr2) |  |
| [SPACE](../space/index) | Returns a string of space characters |  |
| [SPIDER\_BG\_DIRECT\_SQL](../spider_bg_direct_sql/index) | Background SQL execution |  |
| [SPIDER\_COPY\_TABLES](../spider_copy_tables/index) | Copy table data |  |
| [SPIDER\_DIRECT\_SQL](../spider_direct_sql/index) | Execute SQL on the remote server |  |
| [SPIDER\_FLUSH\_TABLE\_MON\_CACHE](../spider_flush_table_mon_cache/index) | Refreshing Spider monitoring server information |  |
| [SQRT](../sqrt/index) | Square root |  |
| [SRID](../srid/index) | Synonym for ST\_SRID |  |
| [ST\_AREA](../st_area/index) | Area of a Polygon |  |
| [ST\_AsBinary](../st_asbinary/index) | Converts a value to its WKB representation |  |
| [ST\_AsText](../st_astext/index) | Converts a value to its WKT-Definition |  |
| [ST\_AsWKB](../st_aswkb/index) | Synonym for ST\_AsBinary |  |
| [ST\_ASWKT](../st_aswkt/index) | Synonym for ST\_ASTEXT() |  |
| [ST\_BOUNDARY](../st_boundary/index) | Returns a geometry that is the closure of a combinatorial boundary |  |
| [ST\_BUFFER](../st_buffer/index) | A new geometry with a buffer added to the original geometry |  |
| [ST\_CENTROID](../st_centroid/index) | The mathematical centroid (geometric center) for a MultiPolygon |  |
| [ST\_CONTAINS](../st_contains/index) | Whether one geometry is contained by another |  |
| [ST\_CONVEXHULL](../st_convexhull/index) | The minimum convex geometry enclosing all geometries within the set |  |
| [ST\_CROSSES](../st_crosses/index) | Whether two geometries spatially cross |  |
| [ST\_DIFFERENCE](../st_difference/index) | Point set difference |  |
| [ST\_DIMENSION](../st_dimension/index) | Inherent dimension of a geometry value |  |
| [ST\_DISJOINT](../st_disjoint/index) | Whether one geometry is spatially disjoint from another |  |
| [ST\_DISTANCE](../st_distance/index) | The distance between two geometries |  |
| [ST\_DISTANCE\_SPHERE](../st_distance_sphere/index) | The spherical distance between two geometries |  |
| [ST\_ENDPOINT](../st_endpoint/index) | Returns the endpoint of a LineString |  |
| [ST\_ENVELOPE](../st_envelope/index) | Returns the Minimum Bounding Rectangle for a geometry value |  |
| [ST\_EQUALS](../st_equals/index) | Whether two geometries are spatoially equal |  |
| [ST\_ExteriorRing](../st_exteriorring/index) | Returns the exterior ring of a Polygon as a LineString |  |
| [ST\_GeomCollFromText](../st_geomcollfromtext/index) | Constructs a GEOMETRYCOLLECTION value |  |
| [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index) | Constructs a GEOMETRYCOLLECTION value from a WKB |  |
| [ST\_GeometryCollectionFromText](../st_geometrycollectionfromtext/index) | Synonym for ST\_GeomCollFromText |  |
| [ST\_GeometryCollectionFromWKB](../st_geometrycollectionfromwkb/index) | Synonym for ST\_GeomCollFromWKB |  |
| [ST\_GeometryFromText](../st_geometryfromtext/index) | Synonym for ST\_GeomFromText |  |
| [ST\_GeometryFromWKB](../st_geometryfromwkb/index) | Synonym for ST\_GeomFromWKB |  |
| [ST\_GEOMETRYN](../st_geometryn/index) | Returns the N-th geometry in a GeometryCollection |  |
| [ST\_GEOMETRYTYPE](../st_geometrytype/index) | Returns name of the geometry type of which a given geometry instance is a member |  |
| [ST\_GeomFromText](../st_geomfromtext/index) | Constructs a geometry value using its WKT and SRID |  |
| [ST\_GeomFromWKB](../st_geomfromwkb/index) | Constructs a geometry value using its WKB representation and SRID |  |
| [ST\_InteriorRingN](../st_interiorringn/index) | Returns the N-th interior ring for a Polygon |  |
| [ST\_INTERSECTION](../st_intersection/index) | The intersection, or shared portion, of two geometries |  |
| [ST\_INTERSECTS](../st_intersects/index) | Whether two geometries spatially intersect |  |
| [ST\_ISCLOSED](../st_isclosed/index) | Returns true if a given LINESTRING's start and end points are the same |  |
| [ST\_ISEMPTY](../st_isempty/index) | Indicated validity of geometry value |  |
| [ST\_IsRing](../st_isring/index) | Returns true if a given LINESTRING is both ST\_IsClosed and ST\_IsSimple |  |
| [ST\_IsSimple](../st_issimple/index) | Returns true if the given Geometry has no anomalous geometric points |  |
| [ST\_LENGTH](../st_length/index) | Length of a LineString value |  |
| [ST\_LineFromText](../st_linefromtext/index) | Creates a linestring value |  |
| [ST\_LineFromWKB](../st_linefromwkb/index) | Constructs a LINESTRING using its WKB and SRID |  |
| [ST\_LineStringFromText](../st_linestringfromtext/index) | Synonym for ST\_LineFromText |  |
| [ST\_LineStringFromWKB](../st_linestringfromwkb/index) | Synonym for ST\_LineFromWKB |  |
| [ST\_NUMGEOMETRIES](../st_numgeometries/index) | Number of geometries in a GeometryCollection |  |
| [ST\_NumInteriorRings](../st_numinteriorrings/index) | Number of interior rings in a Polygon |  |
| [ST\_NUMPOINTS](../st_numpoints/index) | Returns the number of Point objects in a LineString |  |
| [ST\_OVERLAPS](../st_overlaps/index) | Whether two geometries overlap |  |
| [ST\_PointFromText](../st_pointfromtext/index) | Constructs a POINT value |  |
| [ST\_PointFromWKB](../st_pointfromwkb/index) | Constructs POINT using its WKB and SRID |  |
| [ST\_POINTN](../st_pointn/index) | Returns the N-th Point in the LineString |  |
| [ST\_POINTONSURFACE](../st_pointonsurface/index) | Returns a POINT guaranteed to intersect a surface |  |
| [ST\_PolyFromText](../st_polyfromtext/index) | Constructs a POLYGON value |  |
| [ST\_PolyFromWKB](../st_polyfromwkb/index) | Constructs POLYGON value using its WKB representation and SRID |  |
| [ST\_PolygonFromText](../st_polygonfromtext/index) | Synonym for ST\_PolyFromText |  |
| [ST\_PolygonFromWKB](../st_polygonfromwkb/index) | Synonym for ST\_PolyFromWKB |  |
| [ST\_RELATE](../st_relate/index) | Returns true if two geometries are related |  |
| [ST\_SRID](../st_srid/index) | Returns a Spatial Reference System ID |  |
| [ST\_STARTPOINT](../st_startpoint/index) | Returns the start point of a LineString |  |
| [ST\_SYMDIFFERENCE](../st_symdifference/index) | Portions of two geometries that don't intersect |  |
| [ST\_TOUCHES](../st_touches/index) | Whether one geometry g1 spatially touches another |  |
| [ST\_UNION](../st_union/index) | Union of two geometries |  |
| [ST\_WITHIN](../st_within/index) | Whether one geometry is within another |  |
| [ST\_X](../st_x/index) | X-coordinate value for a point |  |
| [ST\_Y](../st_y/index) | Y-coordinate for a point |  |
| [STARTPOINT](../startpoint/index) | Synonym for ST\_StartPoint |  |
| [STD](../std/index) | Population standard deviation |  |
| [STDDEV](../stddev/index) | Population standard deviation |  |
| [STDDEV\_POP](../stddev_pop/index) | Returns the population standard deviation |  |
| [STDDEV\_SAMP](../stddev_samp/index) | Standard deviation |  |
| [STR\_TO\_DATE](../str_to_date/index) | Converts a string to date |  |
| [STRCMP](../strcmp/index) | Compares two strings in sort order |  |
| [SUBDATE](../subdate/index) | Subtract a date unit or number of days |  |
| [SUBSTR](../substr/index) | Returns a substring from string starting at a given position |  |
| [SUBSTRING](../substring/index) | Returns a substring from string starting at a given position |  |
| [SUBSTRING\_INDEX](../substring_index/index) | Returns the substring from string before count occurrences of a delimiter |  |
| [SUBTIME](../subtime/index) | Subtracts a time from a date/time |  |
| [SUM](../sum/index) | Sum total |  |
| [SYS.EXTRACT\_SCHEMA\_FROM\_FILE\_NAME](../extract_schema_from_file_name/index) | Given a file path, returns the schema (database) name | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.EXTRACT\_TABLE\_FROM\_FILE\_NAME](../extract_table_from_file_name/index) | Given a file path, returns the table name | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.FORMAT\_BYTES](../format_bytes/index) | Returns a string consisting of a value and the units in a human-readable format | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.FORMAT\_PATH](../format_path/index) | Returns a modified path after replacing subpaths matching the values of various system variables with the variable name | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.FORMAT\_STATEMENT](../format_statement/index) | Returns a reduced length string | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.FORMAT\_TIME](../format_time/index) | Returns a human-readable time value and unit indicator | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.LIST\_ADD](../list_add/index) | Adds a value to a given list | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.LIST\_DROP](../list_drop/index) | Drops a value from a given list | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_IS\_ACCOUNT\_ENABLED](../ps_is_account_enabled/index) | Whether Performance Schema instrumentation for the given account is enabled | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_IS\_CONSUMER\_ENABLED](../ps_is_consumer_enabled/index) | Whether Performance Schema instrumentation for the given consumer is enabled | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_IS\_INSTRUMENT\_DEFAULT\_ENABLED](../ps_is_instrument_default_enabled/index) | Whether a given Performance Schema instrument is enabled by default | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_IS\_INSTRUMENT\_DEFAULT\_TIMED](../ps_is_instrument_default_timed/index) | Returns whether a given Performance Schema instrument is timed by default | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_IS\_THREAD\_INSTRUMENTED](../ps_is_thread_instrumented/index) | Returns whether or not Performance Schema instrumentation for the given connection\_id is enabled | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_THREAD\_ACCOUNT](../ps_thread_account/index) | Returns the account (username@hostname) associated with the given thread\_id | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_THREAD\_ID](../ps_thread_id/index) | Returns the thread\_id associated with the given connection\_id | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_THREAD\_STACK](../ps_thread_stack/index) | Returns all statements, stages, and events within the Performance Schema for a given thread\_id | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.PS\_THREAD\_TRX\_INFO](../ps_thread_trx_info/index) | Returns a JSON object with information about the thread specified by the given thread\_id | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.QUOTE\_IDENTIFIER](../quote_identifier/index) | Quotes a string to produce a result that can be used as an identifier in an SQL statement | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.SYS\_GET\_CONFIG](../sys_get_config/index) | Returns a configuration option value from the sys\_config table | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.VERSION\_MAJOR](../version_major/index) | Returns the MariaDB Server major release version | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.VERSION\_MINOR](../version_minor/index) | Returns the MariaDB Server minor release version | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS.VERSION\_PATCH](../version_patch/index) | Returns the MariaDB Server patch release version | [MariaDB 10.6](../what-is-mariadb-106/index) |
| [SYS\_GUID](../sys_guid/index) | Generates a globally unique identifier |  |
| [SYSDATE](../sysdate/index) | Returns the current date and time |  |
| [SYSTEM\_USER](../system_user/index) | Synonym for USER() |  |
| [TAN](../tan/index) | Returns the tangent |  |
| [TIME function](../time-function/index) | Extracts the time |  |
| [TIMEDIFF](../timediff/index) | Returns the difference between two date/times |  |
| [TIMESTAMP FUNCTION](../timestamp-function/index) | Return the datetime, or add a time to a date/time |  |
| [TIMESTAMPADD](../timestampadd/index) | Add interval to a date or datetime |  |
| [TIMESTAMPDIFF](../timestampdiff/index) | Difference between two datetimes |  |
| [TIME\_FORMAT](../time_format/index) | Formats the time value according to the format string |  |
| [TIME\_TO\_SEC](../time_to_sec/index) | Returns the time argument, converted to seconds |  |
| [TO\_BASE64](../to_base64/index) | Converts a string to its base-64 encoded form |  |
| [TO\_CHAR](../to_char/index) | Converts a date/time type to a char |  |
| [TO\_DAYS](../to_days/index) | Number of days since year 0 |  |
| [TO\_SECONDS](../to_seconds/index) | Number of seconds since year 0 |  |
| [TOUCHES](../touches/index) | Whether two geometries spatially touch |  |
| [TRIM](../trim/index) | Returns a string with all given prefixes or suffixes removed |  |
| [TRUNCATE](../truncate/index) | Truncates X to D decimal places |  |
| [UCASE](../ucase/index) | Synonym for UPPER]]() |  |
| [UNHEX](../unhex/index) | Interprets pairs of hex digits as a number and converts to the character represented by the number |  |
| [UNCOMPRESS](../uncompress/index) | Uncompresses string compressed with COMPRESS() |  |
| [UNCOMPRESSED\_LENGTH](../uncompressed_length/index) | Returns length of a string before being compressed with COMPRESS() |  |
| [UNIX\_TIMESTAMP](../unix_timestamp/index) | Returns a Unix timestamp |  |
| [UPDATEXML](../updatexml/index) | Replace XML |  |
| [UPPER](../upper/index) | Changes string to uppercase |  |
| [USER](../user/index) | Current user/host |  |
| [UTC\_DATE](../utc_date/index) | Returns the current UTC date |  |
| [UTC\_TIME](../utc_time/index) | Returns the current UTC time |  |
| [UTC\_TIMESTAMP](../utc_timestamp/index) | Returns the current UTC date and time |  |
| [UUID](../uuid/index) | Returns a Universal Unique Identifier |  |
| [UUID\_SHORT](../uuid_short/index) | Return short universal identifier |  |
| [VALUES or VALUE](../values-value/index) | Refer to columns in INSERT ... ON DUPLICATE KEY UPDATE |  |
| [VAR\_POP](../var_pop/index) | Population standard variance |  |
| [VAR\_SAMP](../var_samp/index) | Returns the sample variance |  |
| [VARIANCE](../variance/index) | Population standard variance |  |
| [VERSION](../version/index) | MariaDB server version |  |
| [WEEK](../week/index) | Returns the week number |  |
| [WEEKDAY](../weekday/index) | Returns the weekday index |  |
| [WEEKOFYEAR](../weekofyear/index) | Returns the calendar week of the date as a number in the range from 1 to 53 |  |
| [WEIGHT\_STRING](../weight_string/index) | Weight of the input string |  |
| [WITHIN](../within/index) | Indicate whether a geographic element is spacially within another |  |
| [WSREP\_LAST\_SEEN\_GTID](../wsrep_last_seen_gtid/index) | Returns the Global Transaction ID of the most recent write transaction observed by the client. |  |
| [WSREP\_LAST\_WRITTEN\_GTID](../wsrep_last_written_gtid/index) | Returns the Global Transaction ID of the most recent write transaction performed by the client. |  |
| [WSREP\_SYNC\_WAIT\_UPTO\_GTID](../wsrep_sync_wait_upto_gtid/index) | Blocks the client until the transaction specified by the given Global Transaction ID is applied and committed by the node |  |
| [X](../x/index) | Synonym for ST\_X |  |
| [Y](../y/index) | Synonym for ST\_Y |  |
| [YEAR](../year/index) | Returns the year for the given date |  |
| [YEARWEEK](../yearweek/index) | Returns year and week for a date |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/function-and-operator-reference/>

String Functions
=================

   Functions dealing with strings, such as CHAR, CONVERT, CONCAT, PAD, REGEXP, TRIM, etc.

  

| Title | Description |
| --- | --- |
|  [Regular Expressions Functions](../regular-expressions-functions/index) |  Functions for dealing with regular expressions  |
|  [Dynamic Columns Functions](../dynamic-columns-functions/index) |  Functions for storing key/value pairs of data within a column.  |
|  [ASCII](../ascii/index) |  Numeric ASCII value of leftmost character.  |
|  [BIN](../bin/index) |  Returns binary value.  |
|  [BINARY Operator](../binary-operator/index) |  Casts to a binary string.  |
|  [BIT\_LENGTH](../bit_length/index) |  Returns the length of a string in bits.  |
|  [CAST](../cast/index) |  Casts a value of one type to another type.  |
|  [CHAR Function](../char-function/index) |  Returns string based on the integer values for the individual characters.  |
|  [CHARACTER\_LENGTH](../character_length/index) |  Synonym for CHAR\_LENGTH().  |
|  [CHAR\_LENGTH](../char_length/index) |  Length of the string in characters.  |
|  [CHR](../chr/index) |  Returns string based on integer values of the individual characters.  |
|  [CONCAT](../concat/index) |  Returns concatenated string.  |
|  [CONCAT\_WS](../concat_ws/index) |  Concatenate with separator.  |
|  [CONVERT](../convert/index) |  Convert a value from one type to another type.  |
|  [ELT](../elt/index) |  Returns the N'th element from a set of strings.  |
|  [EXPORT\_SET](../export_set/index) |  Returns an on string for every bit set, an off string for every bit not set.  |
|  [EXTRACTVALUE](../extractvalue/index) |  Returns the text of the first text node matched by the XPath expression.  |
|  [FIELD](../field/index) |  Returns the index position of a string in a list.  |
|  [FIND\_IN\_SET](../find_in_set/index) |  Returns the position of a string in a set of strings.  |
|  [FORMAT](../format/index) |  Formats a number.  |
|  [FROM\_BASE64](../from_base64/index) |  Given a base-64 encoded string, returns the decoded result as a binary string.  |
|  [HEX](../hex/index) |  Returns hexadecimal value.  |
|  [INSERT Function](../insert-function/index) |  Replaces a part of a string with another string.  |
|  [INSTR](../instr/index) |  Returns the position of a string within a string.  |
|  [LCASE](../lcase/index) |  Synonym for LOWER().  |
|  [LEFT](../left/index) |  Returns the leftmost characters from a string.  |
|  [LENGTH](../length/index) |  Length of the string in bytes.  |
|  [LENGTHB](../lengthb/index) |  Length of the given string, in bytes.  |
|  [LIKE](../like/index) |  Whether expression matches a pattern.  |
|  [LOAD\_FILE](../load_file/index) |  Returns file contents as a string.  |
|  [LOCATE](../locate/index) |  Returns the position of a substring in a string.  |
|  [LOWER](../lower/index) |  Returns a string with all characters changed to lowercase.  |
|  [LPAD](../lpad/index) |  Returns the string left-padded with another string to a given length.  |
|  [LTRIM](../ltrim/index) |  Returns the string with leading space characters removed.  |
|  [MAKE\_SET](../make_set/index) |  Make a set of strings that matches a bitmask.  |
|  [MATCH AGAINST](../match-against/index) |  Perform a fulltext search on a fulltext index.  |
|  [Full-Text Index Stopwords](../full-text-index-stopwords/index) |  Default list of full-text stopwords used by MATCH...AGAINST.  |
|  [MID](../mid/index) |  Synonym for SUBSTRING(str,pos,len).  |
|  [NATURAL\_SORT\_KEY](../natural_sort_key/index) |  Sorting that is closer to natural human sorting.  |
|  [NOT LIKE](../not-like/index) |  Same as NOT(expr LIKE pat [ESCAPE 'escape\_char']).  |
|  [NOT REGEXP](../not-regexp/index) |  Same as NOT (expr REGEXP pat).  |
|  [OCTET\_LENGTH](../octet_length/index) |  Returns the length of the given string, in bytes.  |
|  [ORD](../ord/index) |  Return ASCII or character code.  |
|  [POSITION](../position/index) |  Returns the position of a substring in a string.  |
|  [QUOTE](../quote/index) |  Returns quoted, properly escaped string.  |
|  [REPEAT Function](../repeat-function/index) |  Returns a string repeated a number of times.  |
|  [REPLACE Function](../replace-function/index) |  Replace occurrences of a string.  |
|  [REVERSE](../reverse/index) |  Reverses the order of a string.  |
|  [RIGHT](../right/index) |  Returns the rightmost N characters from a string.  |
|  [RPAD](../rpad/index) |  Returns the string right-padded with another string to a given length.  |
|  [RTRIM](../rtrim/index) |  Returns the string with trailing space characters removed.  |
|  [SFORMAT](../sformat/index) |  Given a string and a formatting specification, returns a formatted string.  |
|  [SOUNDEX](../soundex/index) |  Returns a string based on how the string sounds.  |
|  [SOUNDS LIKE](../sounds-like/index) |  SOUNDEX(expr1) = SOUNDEX(expr2).  |
|  [SPACE](../space/index) |  Returns a string of space characters.  |
|  [STRCMP](../strcmp/index) |  Compares two strings in sort order.  |
|  [SUBSTR](../substr/index) |  Returns a substring from string starting at a given position.  |
|  [SUBSTRING](../substring/index) |  Returns a substring from string starting at a given position.  |
|  [SUBSTRING\_INDEX](../substring_index/index) |  Returns the substring from string before count occurrences of a delimiter.  |
|  [TO\_BASE64](../to_base64/index) |  Converts a string to its base-64 encoded form.  |
|  [TO\_CHAR](../to_char/index) |  Converts a date/time/timestamp type expression to a string.  |
|  [TRIM](../trim/index) |  Returns a string with all given prefixes or suffixes removed.  |
|  [TRIM\_ORACLE](../trim_oracle/index) |  Synonym for the Oracle mode version of TRIM().  |
|  [UCASE](../ucase/index) |  Synonym for UPPER().  |
|  [UNCOMPRESS](../uncompress/index) |  Uncompresses string compressed with COMPRESS().  |
|  [UNCOMPRESSED\_LENGTH](../uncompressed_length/index) |  Returns length of a string before being compressed with COMPRESS().  |
|  [UNHEX](../unhex/index) |  Interprets pairs of hex digits as numbers and converts to the character represented by the number.  |
|  [UPDATEXML](../updatexml/index) |  Replace XML.  |
|  [UPPER](../upper/index) |  Changes string to uppercase.  |
|  [WEIGHT\_STRING](../weight_string/index) |  Weight of the input string.  |
|  [Type Conversion](../type-conversion/index) |  When implicit type conversion takes place.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/string-functions/>

Date & Time Functions
======================

   Functions for handling date and time, e.g. TIME, DATE, DAYNAME etc.

  

| Title | Description |
| --- | --- |
|  [Microseconds in MariaDB](../microseconds-in-mariadb/index) |  Microseconds have been supported since MariaDB 5.3.  |
|  [Date and Time Units](../date-and-time-units/index) |  Date or time units  |
|  [ADD\_MONTHS](../add_months/index) |  Adds a number of months to a date.  |
|  [ADDDATE](../adddate/index) |  Add days or another interval to a date.  |
|  [ADDTIME](../addtime/index) |  Adds a time to a time or datetime.  |
|  [CONVERT\_TZ](../convert_tz/index) |  Converts a datetime from one time zone to another.  |
|  [CURDATE](../curdate/index) |  Returns the current date.  |
|  [CURRENT\_DATE](../current_date/index) |  Synonym for CURDATE().  |
|  [CURRENT\_TIME](../current_time/index) |  Synonym for CURTIME().  |
|  [CURRENT\_TIMESTAMP](../current_timestamp/index) |  Synonym for NOW().  |
|  [CURTIME](../curtime/index) |  Returns the current time.  |
|  [DATE FUNCTION](../date-function/index) |  Extracts the date portion of a datetime.  |
|  [DATEDIFF](../datediff/index) |  Difference in days between two date/time values.  |
|  [DATE\_ADD](../date_add/index) |  Date arithmetic - addition.  |
|  [DATE\_FORMAT](../date_format/index) |  Formats the date value according to the format string.  |
|  [DATE\_SUB](../date_sub/index) |  Date arithmetic - subtraction.  |
|  [DAY](../day/index) |  Synonym for DAYOFMONTH().  |
|  [DAYNAME](../dayname/index) |  Return the name of the weekday.  |
|  [DAYOFMONTH](../dayofmonth/index) |  Returns the day of the month.  |
|  [DAYOFWEEK](../dayofweek/index) |  Returns the day of the week index.  |
|  [DAYOFYEAR](../dayofyear/index) |  Returns the day of the year.  |
|  [EXTRACT](../extract/index) |  Extracts a portion of the date.  |
|  [FORMAT\_PICO\_TIME](../format_pico_time/index) |  Given a time in picoseconds, returns a human-readable time value and unit indicator.  |
|  [FROM\_DAYS](../from_days/index) |  Returns a date given a day.  |
|  [FROM\_UNIXTIME](../from_unixtime/index) |  Returns a datetime from a Unix timestamp.  |
|  [GET\_FORMAT](../get_format/index) |  Returns a format string.  |
|  [HOUR](../hour/index) |  Returns the hour.  |
|  [LAST\_DAY](../last_day/index) |  Returns the last day of the month.  |
|  [LOCALTIME](../localtime/index) |  Synonym for NOW().  |
|  [LOCALTIMESTAMP](../localtimestamp/index) |  Synonym for NOW().  |
|  [MAKEDATE](../makedate/index) |  Returns a date given a year and day.  |
|  [MAKETIME](../maketime/index) |  Returns a time.  |
|  [MICROSECOND](../microsecond/index) |  Returns microseconds from a date or datetime.  |
|  [MINUTE](../minute/index) |  Returns a minute from 0 to 59.  |
|  [MONTH](../month/index) |  Returns a month from 1 to 12.  |
|  [MONTHNAME](../monthname/index) |  Returns the full name of the month.  |
|  [NOW](../now/index) |  Returns the current date and time.  |
|  [PERIOD\_ADD](../period_add/index) |  Add months to a period.  |
|  [PERIOD\_DIFF](../period_diff/index) |  Number of months between two periods.  |
|  [QUARTER](../quarter/index) |  Returns year quarter from 1 to 4.  |
|  [SECOND](../second/index) |  Returns the second of a time.  |
|  [SEC\_TO\_TIME](../sec_to_time/index) |  Converts a second to a time.  |
|  [STR\_TO\_DATE](../str_to_date/index) |  Converts a string to date.  |
|  [SUBDATE](../subdate/index) |  Subtract a date unit or number of days.  |
|  [SUBTIME](../subtime/index) |  Subtracts a time from a date/time.  |
|  [SYSDATE](../sysdate/index) |  Returns the current date and time.  |
|  [TIME Function](../time-function/index) |  Extracts the time.  |
|  [TIMEDIFF](../timediff/index) |  Returns the difference between two date/times.  |
|  [TIMESTAMP FUNCTION](../timestamp-function/index) |  Return the datetime, or add a time to a date/time.  |
|  [TIMESTAMPADD](../timestampadd/index) |  Add interval to a date or datetime.  |
|  [TIMESTAMPDIFF](../timestampdiff/index) |  Difference between two datetimes.  |
|  [TIME\_FORMAT](../time_format/index) |  Formats the time value according to the format string.  |
|  [TIME\_TO\_SEC](../time_to_sec/index) |  Returns the time argument, converted to seconds.  |
|  [TO\_DAYS](../to_days/index) |  Number of days since year 0.  |
|  [TO\_SECONDS](../to_seconds/index) |  Number of seconds since year 0.  |
|  [UNIX\_TIMESTAMP](../unix_timestamp/index) |  Returns a Unix timestamp.  |
|  [UTC\_DATE](../utc_date/index) |  Returns the current UTC date.  |
|  [UTC\_TIME](../utc_time/index) |  Returns the current UTC time.  |
|  [UTC\_TIMESTAMP](../utc_timestamp/index) |  Returns the current UTC date and time.  |
|  [WEEK](../week/index) |  Returns the week number.  |
|  [WEEKDAY](../weekday/index) |  Returns the weekday index.  |
|  [WEEKOFYEAR](../weekofyear/index) |  Returns the calendar week of the date as a number in the range from 1 to 53.  |
|  [YEAR](../year/index) |  Returns the year for the given date.  |
|  [YEARWEEK](../yearweek/index) |  Returns year and week for a date.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date-time-functions/>

Aggregate Functions
====================

   The following functions (also called aggregate functions) can be used with the [GROUP BY](../group-by/index) clause:

  

| Title | Description |
| --- | --- |
|  [Stored Aggregate Functions](../stored-aggregate-functions/index) |  Custom aggregate functions.  |
|  [AVG](../avg/index) |  Returns the average value.  |
|  [BIT\_AND](../bit_and/index) |  Bitwise AND.  |
|  [BIT\_OR](../bit_or/index) |  Bitwise OR.  |
|  [BIT\_XOR](../bit_xor/index) |  Bitwise XOR.  |
|  [COUNT](../count/index) |  Returns count of non-null values.  |
|  [COUNT DISTINCT](../count-distinct/index) |  Returns count of number of different non-NULL values.  |
|  [GROUP\_CONCAT](../group_concat/index) |  Returns string with concatenated values from a group.  |
|  [JSON\_ARRAYAGG](../json_arrayagg/index) |  Returns a JSON array containing an element for each value in a given set of JSON or SQL values.  |
|  [JSON\_OBJECTAGG](../json_objectagg/index) |  Returns a JSON object containing key-value pairs.  |
|  [MAX](../max/index) |  Returns the maximum value.  |
|  [MIN](../min/index) |  Returns the minimum value.  |
|  [STD](../std/index) |  Population standard deviation.  |
|  [STDDEV](../stddev/index) |  Population standard deviation.  |
|  [STDDEV\_POP](../stddev_pop/index) |  Returns the population standard deviation.  |
|  [STDDEV\_SAMP](../stddev_samp/index) |  Standard deviation.  |
|  [SUM](../sum/index) |  Sum total.  |
|  [VARIANCE](../variance/index) |  Population standard variance.  |
|  [VAR\_POP](../var_pop/index) |  Population standard variance.  |
|  [VAR\_SAMP](../var_samp/index) |  Returns the sample variance.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aggregate-functions/>

Full List of MariaDB Options, System and Status Variables
=========================================================

    Alphabetical list of all [mariadbd Options](../mariadbd-options-full-list/index), [Server System Variables](../server-system-variables/index) and [Server Status Variables](../server-status-variables/index). The convention used is that variable names are listed with '\_' and options with '-'. If a variable and option both exist, both versions are listed for easy searching.

 


| Name |
| --- |
| [-a (--ansii)](../mysqld-options/index#-a-ansi) |
| [--abort-slave-event-count](../mysqld-options/index#-abort-slave-event-count) |
| [Aborted\_clients](../server-status-variables/index#aborted_clients) |
| [Aborted\_connects](../server-status-variables/index#aborted_connects) |
| [Aborted\_connects\_preauth](../server-status-variables/index#aborted_connects) |
| [Access\_denied\_errors](../server-status-variables/index#access_denied_errors) |
| [Acl\_column\_grants](../server-status-variables/index#acl_column_grants) |
| [Acl\_database\_grants](../server-status-variables/index#acl_database_grants) |
| [Acl\_function\_grants](../server-status-variables/index#acl_function_grants) |
| [Acl\_package\_body\_grants](../server-status-variables/index#acl_package_body_grants) |
| [Acl\_package\_spec\_grants](../server-status-variables/index#acl_package_spec_grants) |
| [Acl\_procedure\_grants](../server-status-variables/index#acl_procedure_grants) |
| [Acl\_proxy\_users](../server-status-variables/index#acl_proxy_users) |
| [Acl\_role\_grants](../server-status-variables/index#acl_role_grants) |
| [Acl\_roles](../server-status-variables/index#acl_roles) |
| [Acl\_table\_grants](../server-status-variables/index#acl_table_grants) |
| [Acl\_users](../server-status-variables/index#acl_users) |
| --[allow-suspicious-udfs](../mysqld-options/index#-allow-suspicious-udfs) |
| --[alter-algorithm](../server-system-variables/index#alter_algorithm), [alter\_algorithm](../server-system-variables/index#alter_algorithm) |
| --[analyze-sample-percentage](../server-system-variables/index#analyze_sample_percentage), [analyze\_sample\_percentage](../server-system-variables/index#analyze_sample_percentage) |
| --[ansii](../mysqld-options/index#-a-ansi) |
| --[aria-block-size](../aria-server-system-variables/index#aria_block_size), [aria\_block\_size](../aria-server-system-variables/index#aria_block_size) |
| --[aria-checkpoint-interval](../aria-server-system-variables/index#aria_checkpoint_interval), [aria\_checkpoint\_interval](../aria-server-system-variables/index#aria_checkpoint_interval) |
| --[aria-checkpoint-log-activity](../aria-server-system-variables/index#aria_checkpoint_log_activity), [aria\_checkpoint\_log\_activity](../aria-server-system-variables/index#aria_checkpoint_log_activity) |
| --[aria-encrypt-tables](../aria-server-system-variables/index#aria_encrypt_tables), [aria\_encrypt\_tables](../aria-server-system-variables/index#aria_encrypt_tables) |
| --[aria-force-start-after-recovery-failures](../aria-server-system-variables/index#aria_force_start_after_recovery_failures), [aria\_force\_start\_after\_recovery\_failures](../aria-server-system-variables/index#aria_force_start_after_recovery_failures) |
| --[aria-group-commit](../aria-server-system-variables/index#aria_group_commit), [aria\_group\_commit](../aria-server-system-variables/index#aria_group_commit) |
| --[aria-group-commit-interval](../aria-server-system-variables/index#aria_group_commit_interval), [aria\_group\_commit\_interval](../aria-server-system-variables/index#aria_group_commit_interval) |
| --[aria-log-dir-path](../mysqld-options/index#-aria-log-dir-path) |
| --[aria-log-file-size](../aria-server-system-variables/index#aria_log_file_size), [aria\_log\_file\_size](../aria-server-system-variables/index#aria_log_file_size) |
| --[aria-log-purge-type](../aria-server-system-variables/index#aria_log_purge_type), [aria\_log\_purge\_type](../aria-server-system-variables/index#aria_log_purge_type) |
| --[aria-max-sort-file-size](../aria-server-system-variables/index#aria_max_sort_file_size), [aria\_max\_sort\_file\_size](../aria-server-system-variables/index#aria_max_sort_file_size) |
| --[aria-page-checksum](../aria-server-system-variables/index#aria_page_checksum), [aria\_page\_checksum](../aria-server-system-variables/index#aria_page_checksum) |
| --[aria-pagecache-age-threshold](../aria-server-system-variables/index#aria_pagecache_age_threshold), [aria\_pagecache\_age\_threshold](../aria-server-system-variables/index#aria_pagecache_age_threshold) |
| [Aria\_pagecache\_blocks\_not\_flushed](../aria-server-status-variables/index#aria_pagecache_blocks_not_flushed) |
| [Aria\_pagecache\_blocks\_unused](../aria-server-status-variables/index#aria_pagecache_blocks_unused) |
| [Aria\_pagecache\_blocks\_used](../aria-server-status-variables/index#aria_pagecache_blocks_used) |
| --[aria-pagecache-buffer-size](../aria-server-system-variables/index#aria_pagecache_buffer_size), [aria\_pagecache\_buffer\_size](../aria-server-system-variables/index#aria_pagecache_buffer_size) |
| --[aria-pagecache-division-limit](../aria-server-system-variables/index#aria_pagecache_division_limit), [aria\_pagecache\_division\_limit](../aria-server-system-variables/index#aria_pagecache_division_limit) |
| --[aria-pagecache-file-hash-size](../aria-server-system-variables/index#aria_pagecache_file_hash_size), [aria\_pagecache\_file\_hash\_size](../aria-server-system-variables/index#aria_pagecache_file_hash_size) |
| [Aria\_pagecache\_read\_requests](../aria-server-status-variables/index#aria_pagecache_read_requests) |
| [Aria\_pagecache\_reads](../aria-server-status-variables/index#aria_pagecache_reads) |
| [Aria\_pagecache\_write\_requests](../aria-server-status-variables/index#aria_pagecache_write_requests) |
| [Aria\_pagecache\_writes](../aria-server-status-variables/index#aria_pagecache_writes) |
| --[aria-recover](../aria-server-system-variables/index#aria_recover), [aria\_recover](../aria-server-system-variables/index#aria_recover) |
| --[aria-recover-options](../aria-server-system-variables/index#aria_recover_options), [aria\_recover\_options](../aria-server-system-variables/index#aria_recover_options) |
| --[aria-repair-threads](../aria-server-system-variables/index#aria_repair_threads), [aria\_repair\_threads](../aria-server-system-variables/index#aria_repair_threads) |
| --[aria-sort-buffer-size](../aria-server-system-variables/index#aria_sort_buffer_size), [aria\_sort\_buffer\_size](../aria-server-system-variables/index#aria_sort_buffer_size) |
| --[aria-stats-method](../aria-server-system-variables/index#aria_stats_method), [aria\_stats\_method](../aria-server-system-variables/index#aria_stats_method) |
| --[aria-sync-log-dir](../aria-server-system-variables/index#aria_sync_log_dir), [aria\_sync\_log\_dir](../aria-server-system-variables/index#aria_sync_log_dir) |
| [Aria\_transaction\_log\_syncs](../aria-server-status-variables/index#aria_transaction_log_syncs) |
| [aria\_used\_for\_temp\_tables](../aria-server-system-variables/index#aria_used_for_temp_tables) |
| --[autocommit](../server-system-variables/index#autocommit), [autocommit](../server-system-variables/index#autocommit) |
| --[auto-increment-increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment), [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) |
| --[auto-increment-offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset), [auto\_increment\_offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset) |
| --[automatic-sp-privileges](../server-system-variables/index#automatic_sp_privileges), [automatic\_sp\_privileges](../server-system-variables/index#automatic_sp_privileges) |
| [aws\_key\_management\_key\_spec](../aws-key-management-encryption-plugin/index#aws_key_management_key_spec) |
| [aws\_key\_management\_log\_level](../aws-key-management-encryption-plugin/index#aws_key_management_log_level) |
| [aws\_key\_management\_master\_key\_id](../aws-key-management-encryption-plugin/index#aws_key_management_master_key_id) |
| [aws\_key\_management\_mock](../aws-key-management-encryption-plugin/index#aws_key_management_mock) |
| [aws\_key\_management\_region](../aws-key-management-encryption-plugin/index#aws_key_management_region) |
| [aws\_key\_management\_request\_timeout](../aws-key-management-encryption-plugin/index#aws_key_management_request_timeout) |
| [aws\_key\_management\_rotate\_key](../aws-key-management-encryption-plugin/index#aws_key_management_rotate_key) |
| --[back-log](../server-system-variables/index#back_log), [back\_log](../server-system-variables/index#back_log) |
| -b, --[basedir](../server-system-variables/index#basedir), [basedir](../server-system-variables/index#basedir) |
| --[big-tables](../server-system-variables/index#big_tables), [big\_tables](../server-system-variables/index#big_tables) |
| --[bind-address](../server-system-variables/index#bind_address), [bind\_address](../server-system-variables/index#bind_address) |
| --[binlog-alter-two-phase](../replication-and-binary-log-system-variables/index#binlog_alter_two_phase), [binlog\_alter\_two\_phase](../replication-and-binary-log-system-variables/index#binlog_alter_two_phase) |
| --[binlog-annotate-row-events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events), [binlog\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events) |
| [Binlog\_bytes\_written](../replication-and-binary-log-server-status-variables/index#binlog_bytes_written) |
| [Binlog\_cache\_disk\_use](../replication-and-binary-log-server-status-variables/index#binlog_cache_disk_use) |
| --[binlog-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_cache_size), [binlog\_cache\_size](../replication-and-binary-log-server-system-variables/index#binlog_cache_size) |
| [Binlog\_cache\_use](../replication-and-binary-log-server-status-variables/index#binlog_cache_use) |
| --[binlog-checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum), [binlog\_checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum) |
| --[binlog-commit-wait-count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count), [binlog\_commit\_wait\_count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count) |
| --[binlog-commit-wait-count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_usec), [binlog\_commit\_wait\_usec](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count) |
| [Binlog\_commits](../replication-and-binary-log-server-status-variables/index#binlog_commits) |
| --[binlog-direct-non-transactional-updates](../replication-and-binary-log-server-system-variables/index#binlog_direct_non_transactional_updates), [binlog\_direct\_non\_transactional\_updates](../replication-and-binary-log-server-system-variables/index#binlog_direct_non_transactional_updates) |
| --[binlog-do-db](../mysqld-options/index#-binlog-do-db), [binlog\_do\_db](../replication-and-binary-log-server-system-variables/index#binlog_do_db) |
| --[binlog-expire-logs-seconds](../replication-and-binary-log-server-system-variables/index#binlog_expire_logs_seconds), [binlog\_expire\_logs\_seconds](../replication-and-binary-log-server-system-variables/index#binlog_expire_logs_seconds) |
| --[binlog-file-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_file_cache_size), [binlog\_file\_cache\_size](../replication-and-binary-log-server-system-variables/index#binlog_file_cache_size) |
| --[binlog-format](../replication-and-binary-log-server-system-variables/index#binlog_format), [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) |
| [Binlog\_group\_commits](../replication-and-binary-log-server-status-variables/index#binlog_group_commits) |
| [Binlog\_group\_commit\_trigger\_count](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_count) |
| [Binlog\_group\_commit\_trigger\_lock\_wait](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_lock_wait) |
| [Binlog\_group\_commit\_trigger\_timeout](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_timeout) |
| --[binlog-ignore-db](../mysqld-options/index#-binlog-ignore-db), [binlog\_ignore\_db](../replication-and-binary-log-server-system-variables/index#binlog_ignore_db) |
| --[binlog-optimize-thread-scheduling](../replication-and-binary-log-server-system-variables/index#binlog_optimize_thread_scheduling), [binlog\_optimize\_thread\_scheduling](../replication-and-binary-log-server-system-variables/index#binlog_optimize_thread_scheduling) |
| --[binlog-row-image](../replication-and-binary-log-server-system-variables/index#binlog_row_image), [binlog\_row\_image](../replication-and-binary-log-server-system-variables/index#binlog_row_image) |
| --[binlog-row-metadata](../replication-and-binary-log-server-system-variables/index#binlog_row_metadata), [binlog\_row\_metadata](../replication-and-binary-log-server-system-variables/index#binlog_row_metadata) |
| --[binlog-row-event-max-size](../mysqld-options/index#-binlog-row-event-max-size) |
| [Binlog\_snapshot\_file](../replication-and-binary-log-server-status-variables/index#binlog_snapshot_file) |
| [Binlog\_snapshot\_position](../replication-and-binary-log-server-status-variables/index#binlog_snapshot_position) |
| [Binlog\_stmt\_cache\_disk\_use](../replication-and-binary-log-server-status-variables/index#binlog_stmt_cache_disk_use) |
| [Binlog\_stmt\_cache\_use](../replication-and-binary-log-server-status-variables/index#binlog_stmt_cache_use) |
| --[binlog-stmt-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_stmt_cache_size), [binlog\_stmt\_cache\_size](../replication-and-binary-log-server-system-variables/index#binlog_stmt_cache_size) |
| --[block-encryption-mode](../server-system-variables/index#block_encryption_mode), [block\_encryption\_mode](../server-system-variables/index#block_encryption_mode) |
| --[bootstrap](../mysqld-options/index#-bootstrap) |
| --[bulk-insert-buffer-size](../server-system-variables/index#bulk_insert_buffer_size), [bulk\_insert\_buffer\_size](../server-system-variables/index#bulk_insert_buffer_size) |
| [Busy\_time](../server-status-variables/index#busy_time) |
| [Bytes\_received](../server-status-variables/index#bytes_received) |
| [Bytes\_sent](../server-status-variables/index#bytes_sent) |
| [cassandra\_default\_thrift\_host](../cassandra-system-variables/index#cassandra_default_thrift_host) |
| [cassandra\_failure\_retries](../cassandra-system-variables/index#cassandra_failure_retries) |
| [cassandra\_insert\_batch\_size](../cassandra-system-variables/index#cassandra_insert_batch_size) |
| [cassandra\_multiget\_batch\_size](../cassandra-system-variables/index#cassandra_multiget_batch_size) |
| [Cassandra\_multiget\_keys\_scanned](../cassandra-status-variables/index#cassandra_multiget_keys_scanned) |
| [Cassandra\_multiget\_reads](../cassandra-status-variables/index#cassandra_multiget_reads) |
| [Cassandra\_multiget\_rows\_read](../cassandra-status-variables/index#cassandra_multiget_rows_read) |
| [Cassandra\_network\_exceptions](../cassandra-status-variables/index#cassandra_network_exceptions) |
| [cassandra\_read\_consistency](../cassandra-system-variables/index#cassandra_read_consistency) |
| [cassandra\_rnd\_batch\_size](../cassandra-system-variables/index#cassandra_rnd_batch_size) |
| [Cassandra\_row\_inserts](../cassandra-status-variables/index#cassandra_row_inserts) |
| [Cassandra\_row\_insert\_batches](../cassandra-status-variables/index#cassandra_row_insert_batches) |
| [Cassandra\_timeout\_exceptions](../cassandra-status-variables/index#cassandra_timeout_exceptions) |
| [Cassandra\_unavailable\_exceptions](../cassandra-status-variables/index#cassandra_unavailable_exceptions) |
| [cassandra\_write\_consistency](../cassandra-system-variables/index#cassandra_write_consistency) |
| [character\_set\_client](../server-system-variables/index#character_set_client) |
| --[character-set-client-handshake](../mysqld-options/index#-character-set-client-handshake) |
| [character\_set\_connection](../server-system-variables/index#character_set_connection) |
| [character\_set\_database](../server-system-variables/index#character_set_database) |
| --[character-set-filesystem](../server-system-variables/index#character_set_filesystem), [character\_set\_filesystem](../server-system-variables/index#character_set_filesystem) |
| [character\_set\_results](../server-system-variables/index#character_set_results) |
| -C, --[character-set-server](../server-system-variables/index#character_set_server), [character\_set\_server](../server-system-variables/index#character_set_server) |
| [character\_set\_system](../server-system-variables/index#character_set_system) |
| --[character-sets-dir](../server-system-variables/index#character_sets_dir), [character\_sets\_dir](../server-system-variables/index#character_sets_dir) |
| --[check-constraint-checks](../server-system-variables/index#check_constraint_checks), [check\_constraint\_checks](../server-system-variables/index#check_constraint_checks) |
| -r, --[chroot](../mysqld-options/index#-chroot) |
| [collation\_connection](../server-system-variables/index#collation_connection) |
| [collation\_database](../server-system-variables/index#collation_database) |
| --[collation-server](../server-system-variables/index#collation_server), [collation\_server](../server-system-variables/index#collation_server) |
| [Column\_compressions](../storage-engine-independent-column-compression/index#column_compressions) |
| --[column-compression-threshold](../storage-engine-independent-column-compression/index#column_compression_threshold), [column\_compression\_threshold](../storage-engine-independent-column-compression/index#column_compression_threshold) |
| --[column-compression-zlib-level](../storage-engine-independent-column-compression/index#column_compression_zlib_level), [column\_compression\_zlib\_level](../storage-engine-independent-column-compression/index#column_compression_zlib_level) |
| --[column-compression-zlib-strategy](../storage-engine-independent-column-compression/index#column_compression_zlib_strategy), [column\_compression\_zlib\_strategy](../storage-engine-independent-column-compression/index#column_compression_zlib_strategy) |
| --[column-compression-zlib-wrap](../storage-engine-independent-column-compression/index#column_compression_zlib_wrap), [column\_compression\_zlib\_wrap](../storage-engine-independent-column-compression/index#column_compression_zlib_wrap) |
| [Column\_decompressions](../storage-engine-independent-column-compression/index#column_compressions) |
| [Com\_admin\_commands](../server-status-variables/index#com_admin_commands) |
| [Com\_alter\_db](../server-status-variables/index#com_alter_db) |
| [Com\_alter\_db\_upgrade](../server-status-variables/index#com_alter_db_upgrade) |
| [Com\_alter\_event](../server-status-variables/index#com_alter_event) |
| [Com\_alter\_function](../server-status-variables/index#com_alter_function) |
| [Com\_alter\_procedure](../server-status-variables/index#com_alter_procedure) |
| [Com\_alter\_sequence](../server-status-variables/index#com_alter_sequence) |
| [Com\_alter\_server](../server-status-variables/index#com_alter_server) |
| [Com\_alter\_table](../server-status-variables/index#com_alter_table) |
| [Com\_alter\_tablespace](../server-status-variables/index#com_alter_tablespace) |
| [Com\_alter\_user](../server-status-variables/index#com_alter_user) |
| [Com\_analyze](../server-status-variables/index#com_analyze) |
| [Com\_assign\_to\_keycache](../server-status-variables/index#com_assign_to_keycache) |
| [Com\_backup](../server-status-variables/index#com_backup) |
| [Com\_backup\_lock](../server-status-variables/index#com_backup_lock) |
| [Com\_backup\_table](../server-status-variables/index#com_backup_table) |
| [Com\_begin](../server-status-variables/index#com_begin) |
| [Com\_binlog](../server-status-variables/index#com_binlog) |
| [Com\_call\_procedure](../server-status-variables/index#com_call_procedure) |
| [Com\_change\_db](../server-status-variables/index#com_change_db) |
| [Com\_change\_master](../replication-and-binary-log-server-status-variables/index#com_change_master) |
| [Com\_check](../server-status-variables/index#com_check) |
| [Com\_checksum](../server-status-variables/index#com_checksum) |
| [Com\_commit](../server-status-variables/index#com_commit) |
| [Com\_compound\_sql](../server-status-variables/index#com_compound_sql) |
| [Com\_create\_db](../server-status-variables/index#com_create_db) |
| [Com\_create\_event](../server-status-variables/index#com_create_event) |
| [Com\_create\_function](../server-status-variables/index#com_create_function) |
| [Com\_create\_index](../server-status-variables/index#com_create_index) |
| [Com\_create\_package](../server-status-variables/index#com_create_package) |
| [Com\_create\_package\_body](../server-status-variables/index#com_create_package_body) |
| [Com\_create\_procedure](../server-status-variables/index#com_create_procedure) |
| [Com\_create\_role](../server-status-variables/index#com_create_role) |
| [Com\_create\_sequence](../server-status-variables/index#com_create_sequence) |
| [Com\_create\_server](../server-status-variables/index#com_create_server) |
| [Com\_create\_table](../server-status-variables/index#com_create_table) |
| [Com\_create\_temporary\_table](../server-status-variables/index#com_create_temporary_table) |
| [Com\_create\_trigger](../server-status-variables/index#com_create_trigger) |
| [Com\_create\_udf](../server-status-variables/index#com_create_udf) |
| [Com\_create\_user](../server-status-variables/index#com_create_user) |
| [Com\_create\_view](../server-status-variables/index#com_create_view) |
| [Com\_dealloc\_sql](../server-status-variables/index#com_dealloc_sql) |
| [Com\_delete](../server-status-variables/index#com_delete) |
| [Com\_delete\_multi](../server-status-variables/index#com_delete_multi) |
| [Com\_do](../server-status-variables/index#com_do) |
| [Com\_drop\_db](../server-status-variables/index#com_drop_db) |
| [Com\_drop\_event](../server-status-variables/index#com_drop_event) |
| [Com\_drop\_function](../server-status-variables/index#com_drop_function) |
| [Com\_drop\_index](../server-status-variables/index#com_drop_index) |
| [Com\_drop\_package](../server-status-variables/index#com_drop_package) |
| [Com\_drop\_package\_body](../server-status-variables/index#com_drop_package_body) |
| [Com\_drop\_procedure](../server-status-variables/index#com_drop_procedure) |
| [Com\_drop\_role](../server-status-variables/index#com_drop_role) |
| [Com\_drop\_sequence](../server-status-variables/index#com_drop_sequence) |
| [Com\_drop\_server](../server-status-variables/index#com_drop_server) |
| [Com\_drop\_table](../server-status-variables/index#com_drop_table) |
| [Com\_drop\_temporary\_table](../server-status-variables/index#com_drop_temporary_table) |
| [Com\_drop\_trigger](../server-status-variables/index#com_drop_trigger) |
| [Com\_drop\_user](../server-status-variables/index#com_drop_user) |
| [Com\_drop\_user](../server-status-variables/index#com_drop_user) |
| [Com\_drop\_view](../server-status-variables/index#com_drop_view) |
| [Com\_empty\_query](../server-status-variables/index#com_empty_query) |
| [Com\_execute\_immediate](../server-status-variables/index#com_execute_immediate) |
| [Com\_execute\_sql](../server-status-variables/index#com_execute_sql) |
| [Com\_flush](../server-status-variables/index#com_flush) |
| [Com\_get\_diagnostics](../server-status-variables/index#com_get_diagnostics) |
| [Com\_grant](../server-status-variables/index#com_grant) |
| [Com\_grant\_role](../server-status-variables/index#com_grant_role) |
| [Com\_ha\_close](../server-status-variables/index#com_ha_close) |
| [Com\_ha\_open](../server-status-variables/index#com_ha_open) |
| [Com\_ha\_read](../server-status-variables/index#com_ha_read) |
| [Com\_help](../server-status-variables/index#com_help) |
| [Com\_insert](../server-status-variables/index#com_insert) |
| [Com\_insert\_select](../server-status-variables/index#com_insert_select) |
| [Com\_install\_plugin](../server-status-variables/index#com_install_plugin) |
| [Com\_kill](../server-status-variables/index#com_kill) |
| [Com\_load](../server-status-variables/index#com_load) |
| [Com\_load\_master\_data](../server-status-variables/index#com_load_master_data) |
| [Com\_load\_master\_table](../server-status-variables/index#com_load_master_table) |
| [Com\_lock\_tables](../server-status-variables/index#com_lock_tables) |
| [Com\_multi](../server-status-variables/index#com_multi) |
| [Com\_optimize](../server-status-variables/index#com_optimize) |
| [Com\_preload\_keys](../server-status-variables/index#com_preload_keys) |
| [Com\_prepare\_sql](../server-status-variables/index#com_prepare_sql) |
| [Com\_purge](../server-status-variables/index#com_purge) |
| [Com\_purge\_before\_date](../server-status-variables/index#com_purge_before_date) |
| [Com\_release\_savepoint](../server-status-variables/index#com_release_savepoint) |
| [Com\_rename\_table](../server-status-variables/index#com_rename_table) |
| [Com\_rename\_user](../server-status-variables/index#com_rename_user) |
| [Com\_repair](../server-status-variables/index#com_repair) |
| [Com\_replace](../server-status-variables/index#com_replace) |
| [Com\_replace\_select](../server-status-variables/index#com_replace_select) |
| [Com\_reset](../server-status-variables/index#com_reset) |
| [Com\_resignal](../server-status-variables/index#com_resignal) |
| [Com\_restore\_table](../server-status-variables/index#com_restore_table) |
| [Com\_revoke](../server-status-variables/index#com_revoke) |
| [Com\_revoke\_all](../server-status-variables/index#com_revoke_all) |
| [Com\_revoke\_grant](../server-status-variables/index#com_revoke_grant) |
| [Com\_rollback](../server-status-variables/index#com_rollback) |
| [Com\_rollback\_to\_savepoint](../server-status-variables/index#com_rollback_to_savepoint) |
| [Com\_savepoint](../server-status-variables/index#com_savepoint) |
| [Com\_select](../server-status-variables/index#com_select) |
| [Com\_set\_option](../server-status-variables/index#com_set_option) |
| [Com\_show\_authors](../server-status-variables/index#com_show_authors) |
| [Com\_show\_binlog\_events](../server-status-variables/index#com_show_binlog_events) |
| [Com\_show\_binlogs](../server-status-variables/index#com_show_binlogs) |
| [Com\_show\_charsets](../server-status-variables/index#com_show_charsets) |
| [Com\_show\_client\_statistics](../server-status-variables/index#com_show_client_statistics) |
| [Com\_show\_collations](../server-status-variables/index#com_show_collations) |
| [Com\_show\_column\_types](../server-status-variables/index#com_show_column_types) |
| [Com\_show\_contributors](../server-status-variables/index#com_show_contributors) |
| [Com\_show\_create\_db](../server-status-variables/index#com_show_create_db) |
| [Com\_show\_create\_event](../server-status-variables/index#com_show_create_event) |
| [Com\_show\_create\_func](../server-status-variables/index#com_show_create_func) |
| [Com\_show\_create\_package](../server-status-variables/index#com_show_create_package) |
| [Com\_show\_create\_package\_body](../server-status-variables/index#com_show_create_package_body) |
| [Com\_show\_create\_proc](../server-status-variables/index#com_show_create_proc) |
| [Com\_show\_create\_table](../server-status-variables/index#com_show_create_table) |
| [Com\_show\_create\_trigger](../server-status-variables/index#com_show_create_trigger) |
| [Com\_show\_create\_user](../server-status-variables/index#com_show_create_user) |
| [Com\_show\_databases](../server-status-variables/index#com_show_databases) |
| [Com\_show\_engine\_logs](../server-status-variables/index#com_show_engine_logs) |
| [Com\_show\_engine\_mutex](../server-status-variables/index#com_show_engine_mutex) |
| [Com\_show\_engine\_status](../server-status-variables/index#com_show_engine_status) |
| [Com\_show\_events](../server-status-variables/index#com_show_events) |
| [Com\_show\_errors](../server-status-variables/index#com_show_errors) |
| [Com\_show\_explain](../server-status-variables/index#com_show_explain) |
| [Com\_show\_fields](../server-status-variables/index#com_show_fields) |
| [Com\_show\_function\_status](../server-status-variables/index#com_show_function_status) |
| [Com\_show\_generic](../server-status-variables/index#com_show_generic) |
| [Com\_show\_grants](../server-status-variables/index#com_show_grants) |
| [Com\_show\_keys](../server-status-variables/index#com_show_keys) |
| [Com\_show\_index\_statistics](../server-status-variables/index#com_show_index_statistics) |
| [Com\_show\_binlog\_status](../replication-and-binary-log-server-status-variables/index#com_show_binlog_status) |
| [Com\_show\_master\_status](../replication-and-binary-log-server-status-variables/index#com_show_master_status) |
| [Com\_show\_new\_master](../replication-and-binary-log-server-status-variables/index#com_show_new_master) |
| [Com\_show\_open\_tables](../server-status-variables/index#com_show_open_tables) |
| [Com\_show\_package\_status](../server-status-variables/index#com_show_package_status) |
| [Com\_show\_package\_body\_status](../server-status-variables/index#com_show_package_body_status) |
| [Com\_show\_plugins](../server-status-variables/index#com_show_plugins) |
| [Com\_show\_privileges](../server-status-variables/index#com_show_privileges) |
| [Com\_show\_procedure\_status](../server-status-variables/index#com_show_procedure_status) |
| [Com\_show\_processlist](../server-status-variables/index#com_show_processlist) |
| [Com\_show\_profile](../server-status-variables/index#com_show_profile) |
| [Com\_show\_profiles](../server-status-variables/index#com_show_profiles) |
| [Com\_show\_relaylog\_events](../server-status-variables/index#com_show_relaylog_events) |
| [Com\_show\_slave\_hosts](../replication-and-binary-log-server-status-variables/index#com_show_slave_hosts) |
| [Com\_show\_slave\_status](../replication-and-binary-log-server-status-variables/index#com_show_slave_status) |
| [Com\_show\_status](../server-status-variables/index#com_show_status) |
| [Com\_show\_storage\_engines](../server-status-variables/index#com_show_storage_engines) |
| [Com\_show\_table\_statistics](../server-status-variables/index#com_show_table_statistics) |
| [Com\_show\_table\_status](../server-status-variables/index#com_show_table_status) |
| [Com\_show\_tables](../server-status-variables/index#com_show_tables) |
| [Com\_show\_triggers](../server-status-variables/index#com_show_triggers) |
| [Com\_show\_user\_statistics](../server-status-variables/index#com_show_user_statistics) |
| [Com\_show\_variable](../server-status-variables/index#com_show_variable) |
| [Com\_show\_warnings](../server-status-variables/index#com_show_warnings) |
| [Com\_shutdown](../server-status-variables/index#com_shutdown) |
| [Com\_signal](../server-status-variables/index#com_signal) |
| [Com\_slave\_start](../replication-and-binary-log-server-status-variables/index#com_slave_start) |
| [Com\_slave\_stop](../replication-and-binary-log-server-status-variables/index#com_slave_stop) |
| [Com\_start\_all\_slaves](../replication-and-binary-log-server-status-variables/index#com_start_all_slaves) |
| [Com\_start\_slave](../replication-and-binary-log-server-status-variables/index#com_start_slave) |
| [Com\_stop\_all\_slaves](../replication-and-binary-log-server-status-variables/index#com_stop_all_slaves) |
| [Com\_stop\_slave](../replication-and-binary-log-server-status-variables/index#com_stop_slave) |
| [Com\_stmt\_close](../server-status-variables/index#com_stmt_close) |
| [Com\_stmt\_execute](../server-status-variables/index#com_stmt_execute) |
| [Com\_stmt\_fetch](../server-status-variables/index#com_stmt_fetch) |
| [Com\_stmt\_prepare](../server-status-variables/index#com_stmt_prepare) |
| [Com\_stmt\_reprepare](../server-status-variables/index#com_stmt_reprepare) |
| [Com\_stmt\_reset](../server-status-variables/index#com_stmt_reset) |
| [Com\_stmt\_send\_long\_data](../server-status-variables/index#com_stmt_send_long_data) |
| [Com\_truncate](../server-status-variables/index#com_truncate) |
| [Com\_uninstall\_plugin](../server-status-variables/index#com_uninstall_plugin) |
| [Com\_unlock\_tables](../server-status-variables/index#com_unlock_tables) |
| [Com\_update](../server-status-variables/index#com_update) |
| [Com\_update\_multi](../server-status-variables/index#com_update_multi) |
| [Com\_xa\_commit](../server-status-variables/index#com_xa_commit) |
| [Com\_xa\_end](../server-status-variables/index#com_xa_end) |
| [Com\_xa\_prepare](../server-status-variables/index#com_xa_prepare) |
| [Com\_xa\_recover](../server-status-variables/index#com_xa_recover) |
| [Com\_xa\_rollback](../server-status-variables/index#com_xa_rollback) |
| [Com\_xa\_start](../server-status-variables/index#com_xa_start) |
| --[completion-type](../server-system-variables/index#completion_type), [completion\_type](../server-system-variables/index#completion_type) |
| [Compression](../server-status-variables/index#compression) |
| --[concurrent-insert](../server-system-variables/index#concurrent_insert), [concurrent\_insert](../server-system-variables/index#concurrent_insert) |
| --[connect-class-path](../connect-system-variables/index#connect_class_path), [connect\_class\_path](../connect-system-variables/index#connect_class_path) |
| --[connect-cond-push](../connect-system-variables/index#connect_cond_push), [connect\_cond\_push](../connect-system-variables/index#connect_cond_push) |
| --[connect-conv-size](../connect-system-variables/index#connect_conv_size), [connect\_conv\_size](../connect-system-variables/index#connect_conv_size) |
| --[connect-default-depth](../connect-system-variables/index#connect_default_depth), [connect\_default\_depth](../connect-system-variables/index#connect_default_depth) |
| --[connect-default-prec](../connect-system-variables/index#connect_default_prec), [connect\_default\_prec](../connect-system-variables/index#connect_default_prec) |
| --[connect-enable-mongo](../connect-system-variables/index#connect_enable_mongo), [connect\_enable\_mongo](../connect-system-variables/index#connect_enable_mongo) |
| --[connect-exact-info](../connect-system-variables/index#connect_exact_info), [connect\_exact\_info](../connect-system-variables/index#connect_exact_info) |
| --[connect-force-bson](../connect-system-variables/index#connect_force_bson), [connect\_force\_bson](../connect-system-variables/index#connect_force_bson) |
| --[connect-indx-map](../connect-system-variables/index#connect_indx_map), [connect\_indx\_map](../connect-system-variables/index#connect_indx_map) |
| --[connect-java-wrapper](../connect-system-variables/index#connect_java_wrapper), [connect\_java\_wrapper](../connect-system-variables/index#connect_java_wrapper) |
| --[connect-json-all-path](../connect-system-variables/index#connect_json_all_path), [connect\_json\_all\_path](../connect-system-variables/index#connect_json_all_path) |
| --[connect-json-grp-size](../connect-system-variables/index#connect_json_grp_size), [connect\_json\_grp\_size](../connect-system-variables/index#connect_json_grp_size) |
| --[connect-json-null](../connect-system-variables/index#connect_json_null), [connect\_json\_null](../connect-system-variables/index#connect_json_null) |
| --[connect-jvm-path](../connect-system-variables/index#connect_jvm_path), [connect\_jvm\_path](../connect-system-variables/index#connect_jvm_path) |
| --[connect-timeout](../server-system-variables/index#connect_timeout), [connect\_timeout](../server-system-variables/index#connect_timeout) |
| --[connect-type-conv](../connect-system-variables/index#connect_type_conv), [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) |
| --[connect-use-tempfile](../connect-system-variables/index#connect_use_tempfile), [connect\_use\_tempfile](../connect-system-variables/index#connect_use_tempfile) |
| --[connect-work-size](../connect-system-variables/index#connect_work_size), [connect\_work\_size](../connect-system-variables/index#connect_work_size) |
| --[connect-xtrace](../connect-system-variables/index#connect_xtrace), [connect\_xtrace](../connect-system-variables/index#connect_xtrace) |
| [Connection\_errors\_accept](../server-status-variables/index#connection_errors_accept) |
| [Connection\_errors\_internal](../server-status-variables/index#connection_errors_internal) |
| [Connection\_errors\_max\_connections](../server-status-variables/index#connection_errors_max_connections) |
| [Connection\_errors\_peer\_address](../server-status-variables/index#connection_errors_peer_address) |
| [Connection\_errors\_select](../server-status-variables/index#connection_errors_select) |
| [Connection\_errors\_tcpwrap](../server-status-variables/index#connection_errors_tcpwrap) |
| [Connections](../server-status-variables/index#connections) |
| [--console](../mysqld-options/index#-console) |
| [--core-file](../server-system-variables/index#core_file), [core\_file](../server-system-variables/index#core_file) |
| [Cpu\_time](../server-status-variables/index#cpu_time) |
| --[cracklib-password-check](../cracklib_password_check/index#cracklib_password_check) |
| --[cracklib-password-check-dictionary](../cracklib_password_check/index#cracklib_password_check_dictionary), [cracklib\_password\_check-dictionary](../cracklib_password_check/index#cracklib_password_check_dictionary) |
| [Created\_tmp\_disk\_tables](../server-status-variables/index#created_tmp_disk_tables) |
| [Created\_tmp\_files](../server-status-variables/index#created_tmp_files) |
| [Created\_tmp\_tables](../server-status-variables/index#created_tmp_tables) |
| -h, --[datadir](../server-system-variables/index#datadir), [datadir](../server-system-variables/index#datadir) |
| --[date-format](../server-system-variables/index#date_format), [date\_format](../server-system-variables/index#date_format) |
| --[datetime-format](../server-system-variables/index#datetime_format), [datetime\_format](../server-system-variables/index#datetime_format) |
| --[deadlock-search-depth-long](../aria-server-system-variables/index#deadlock_search_depth_long), [deadlock\_search\_depth\_long](../aria-server-system-variables/index#deadlock_search_depth_long) |
| --[deadlock-search-depth-short](../aria-server-system-variables/index#deadlock_search_depth_short), [deadlock\_search\_depth\_short](../aria-server-system-variables/index#deadlock_search_depth_short) |
| --[deadlock-timeout-long](../aria-server-system-variables/index#deadlock_timeout_long), [deadlock\_timeout\_long](../aria-server-system-variables/index#deadlock_timeout_long) |
| --[deadlock-timeout-short](../aria-server-system-variables/index#deadlock_timeout_short), [deadlock\_timeout\_short](../aria-server-system-variables/index#deadlock_timeout_short) |
| -#, --[debug](../server-system-variables/index#debug), [debug](../server-system-variables/index#debug) |
| [--debug-assert-if-crashed-table](../mysqld-options/index#-debug-assert-if-crashed-table) |
| [--debug-binlog-fsync-sleep](../mysqld-options/index#-debug-binlog-fsync-sleep) |
| [--debug-crc-break](../mysqld-options/index#-debug-crc-break) |
| [--debug-flush](../mysqld-options/index#-debug-flush) |
| [--debug-no-sync](../mysqld-options/index#-debug-no-sync) |
| --[debug-no-thread-alarm](../server-system-variables/index#debug_no_thread_alarm), [debug\_no\_thread\_alarm](../server-system-variables/index#debug_no_thread_alarm) |
| [debug\_sync](../server-system-variables/index#debug_sync) |
| [--debug-sync-timeout](../mysqld-options/index#-debug-sync-timeout) |
| --[default-character-set](../mysqld-options/index#-default-character-set) |
| --[default-master-connection](../replication-and-binary-log-server-system-variables/index#default_master_connection), [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) |
| --[default-password-lifetime](../server-system-variables/index#default_password_lifetime), [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime) |
| --[default-regex-flags](../server-system-variables/index#default_regex_flags), [default\_regex\_flags](../server-system-variables/index#default_regex_flags) |
| --[default-storage-engine](../server-system-variables/index#default_storage_engine), [default\_storage\_engine](../server-system-variables/index#default_storage_engine) |
| --[default-table-type](../server-system-variables/index#default_table_type), [default\_table\_type](../server-system-variables/index#default_table_type) |
| --[default-tmp-storage-engine](../server-system-variables/index#default_tmp_storage_engine), [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine) |
| --[default-time-zone](../server-system-variables/index#time_zone) |
| --[default-week-format](../server-system-variables/index#default_week_format), [default\_week\_format](../server-system-variables/index#default_week_format) |
| --[defaults-extra-file](../mysqld-options/index#-defaults-extra-file) |
| --[defaults-file](../mysqld-options/index#-defaults-file) |
| --[delay-key-write](../server-system-variables/index#delay_key_write), [delay\_key\_write](../server-system-variables/index#delay_key_write) |
| [Delayed\_errors](../server-status-variables/index#delayed_errors) |
| --[delayed-insert-limit](../server-system-variables/index#delayed_insert_limit), [delayed\_insert\_limit](../server-system-variables/index#delayed_insert_limit) |
| [Delayed\_insert\_threads](../server-status-variables/index#delayed_insert_threads) |
| --[delayed-insert-timeout](../server-system-variables/index#delayed_insert_timeout), [delayed\_insert\_timeout](../server-system-variables/index#delayed_insert_timeout) |
| --[delayed-queue-size](../server-system-variables/index#delayed_queue_size), [delayed\_queue\_size](../server-system-variables/index#delayed_queue_size) |
| [Delayed\_writes](../server-status-variables/index#delayed_writes) |
| [Delete\_scan](../server-status-variables/index#delete_scan) |
| --[des-key-file](../mysqld-options/index#-des-key-file) |
| --[disconnect-on-expired-password](../server-system-variables/index#disconnect_on_expired_password), [disconnect\_on\_expired\_password](../server-system-variables/index#disconnect_on_expired_password) |
| --[disconnect-slave-event-count](../mysqld-options-full-list/index#-disconnect-slave-event-count) |
| --[disks](../disks-plugin/index#disks) |
| --[div-precision-increment](../server-system-variables/index#div_precision_increment), [div\_precision\_increment](../server-system-variables/index#div_precision_increment) |
| [Empty\_queries](../server-status-variables/index#empty_queries) |
| --[encrypt-binlog](../server-system-variables/index#encrypt_binlog), [encrypt\_binlog](../server-system-variables/index#encrypt_binlog) |
| --[encrypt-tmp-disk-tables](../server-system-variables/index#encrypt_tmp_disk_tables), [encrypt\_tmp\_disk\_tables](../server-system-variables/index#encrypt_tmp_disk_tables) |
| --[encrypt-tmp-files](../server-system-variables/index#encrypt_tmp_files), [encrypt\_tmp\_files](../server-system-variables/index#encrypt_tmp_files) |
| --[encryption-algorithm](../server-system-variables/index#encryption_algorithm), [encryption\_algorithm](../server-system-variables/index#encryption_algorithm) |
| [enforce\_storage\_engine](../server-system-variables/index#enforce_storage_engine) |
| --[engine-condition-pushdown](../server-system-variables/index#engine_condition_pushdown), [engine\_condition\_pushdown](../server-system-variables/index#engine_condition_pushdown) |
| --[eq-range-index-dive-limit](../server-system-variables/index#eq_range_index_dive_limit), [eq\_range\_index\_dive\_limit](../server-system-variables/index#eq_range_index_dive_limit) |
| [error\_count](../server-system-variables/index#error_count) |
| --[event-scheduler](../server-system-variables/index#event_scheduler), [event\_scheduler](../server-system-variables/index#event_scheduler) |
| [Executed\_events](../server-status-variables/index#executed_events) |
| [Executed\_triggers](../server-status-variables/index#executed_triggers) |
| -T, --[exit-info](../mysqld-options-full-list/index#-exit-info) |
| --[expensive-subquery-limit](../server-system-variables/index#expensive_subquery_limit), [expensive\_subquery\_limit](../server-system-variables/index#expensive_subquery_limit) |
| --[expire-logs-days](../replication-and-binary-log-system-variables/index#expire_logs_days), [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days) |
| --[explicit-defaults-for-timestamp](../server-system-variables/index#explicit_defaults_for_timestamp), [explicit\_defaults\_for\_timestamp](../server-system-variables/index#explicit_defaults_for_timestamp) |
| --[external-locking](../mysqld-options-full-list/index#-external-locking) |
| [external\_user](../server-system-variables/index#external_user) |
| --[extra-max-connections](../thread-pool-system-and-status-variables/index#extra_max_connections), [extra\_max\_connections](../thread-pool-system-and-status-variables/index#extra_max_connections) |
| --[extra-port](../thread-pool-system-and-status-variables/index#extra_port), [extra\_port](../thread-pool-system-and-status-variables/index#extra_port) |
| [Feature\_application\_time\_periods](../server-status-variables/index#feature_application_time_periods) |
| [Feature\_check\_constraint](../server-status-variables/index#feature_check_constraint) |
| [Feature\_custom\_aggregate\_functions](../server-status-variables/index#feature_custom_aggregate_functions) |
| [Feature\_delay\_key\_write](../server-status-variables/index#feature_delay_key_write) |
| [Feature\_dynamic\_columns](../server-status-variables/index#feature_dynamic_columns) |
| [Feature\_fulltext](../server-status-variables/index#feature_fulltext) |
| [Feature\_gis](../server-status-variables/index#feature_gis) |
| [Feature\_insert\_returning](../server-status-variables/index#feature_insert_returning) |
| [Feature\_invisible\_columns](../server-status-variables/index#feature_invisible_columns) |
| [Feature\_json](../server-status-variables/index#feature_json) |
| [Feature\_locale](../server-status-variables/index#feature_locale) |
| [Feature\_subquery](../server-status-variables/index#feature_subquery) |
| [Feature\_timezone](../server-status-variables/index#feature_timezone) |
| [Feature\_trigger](../server-status-variables/index#feature_trigger) |
| [Feature\_window\_functions](../server-status-variables/index#feature_window_functions) |
| [Feature\_xml](../server-status-variables/index#feature_xml) |
| --[feedback](../feedback-plugin/index#feedback) |
| --[feedback-http-proxy](../feedback-plugin/index#feedback_http_proxy), [feedback\_http\_proxy](../feedback-plugin/index#feedback_http_proxy) |
| --[feedback-send-retry-wait](../feedback-plugin/index#feedback_send_retry_wait), [feedback\_send\_retry\_wait](../feedback-plugin/index#feedback_send_retry_wait) |
| --[feedback-send-timeout](../feedback-plugin/index#feedback_send_timeout), [feedback\_send\_timeout](../feedback-plugin/index#feedback_send_timeout) |
| [feedback\_server\_uid](../feedback-plugin/index#feedback_server_uid) |
| --[feedback-url](../feedback-plugin/index#feedback_url), [feedback\_url](../feedback-plugin/index#feedback_url) |
| --[feedback-user-info](../feedback-plugin/index#feedback_user_info), [feedback\_user\_info](../feedback-plugin/index#feedback_user_info) |
| --[file-key-management-encryption-algorithm](../file-key-management-encryption-plugin/index#file_key_management_encryption_algorithm), [file\_key\_management\_encryption\_algorithm](../file-key-management-encryption-plugin/index#file_key_management_encryption_algorithm) |
| --[file-key-management-filekey](../file-key-management-encryption-plugin/index#file_key_management_filekey), [file\_key\_management\_filekey](../file-key-management-encryption-plugin/index#file_key_management_filekey) |
| --[file-key-management-filename](../file-key-management-encryption-plugin/index#file_key_management_filename), [file\_key\_management\_filename](../file-key-management-encryption-plugin/index#file_key_management_filename) |
| --[flashback](../mysqld-options/index#-flashback) |
| --[flush](../server-system-variables/index#flush), [flush](../server-system-variables/index#flush) |
| [Flush\_commands](../server-status-variables/index#flush_commands) |
| --[flush-time](../server-system-variables/index#flush_time), [flush\_time](../server-system-variables/index#flush_time) |
| [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) |
| --[ft-boolean-syntax](../server-system-variables/index#ft_boolean_syntax), [ft\_boolean\_syntax](../server-system-variables/index#ft_boolean_syntax) |
| --[ft-max-word-len](../server-system-variables/index#ft_max_word_len), [ft\_max\_word\_len](../server-system-variables/index#ft_max_word_len) |
| --[ft-min-word-len](../server-system-variables/index#ft_min_word_len), [ft\_min\_word\_len](../server-system-variables/index#ft_min_word_len) |
| --[ft-query-expansion-limit](../server-system-variables/index#ft_query_expansion_limit), [ft\_query\_expansion\_limit](../server-system-variables/index#ft_query_expansion_limit) |
| --[ft-stopword-file](../server-system-variables/index#ft_stopword_file), [ft\_stopword\_file](../server-system-variables/index#ft_stopword_file) |
| --[gdb](../mysqld-options/index#-gdb) |
| --[general-log](../server-system-variables/index#general_log), [general\_log](../server-system-variables/index#general_log) |
| --[general-log-file](../server-system-variables/index#general_log_file), [general\_log\_file](../server-system-variables/index#general_log_file) |
| --[getopt-prefix-matching](../mysqld-options/index#-getopt-prefix-matching) |
| --[group-concat-max-len](../server-system-variables/index#group_concat_max_len), [group\_concat\_max\_len](../server-system-variables/index#group_concat_max_len) |
| --[gssapi-keytab-path](../authentication-plugin-gssapi/index#gssapi_keytab_path), [gssapi\_keytab\_path](../authentication-plugin-gssapi/index#gssapi_keytab_path) |
| --[gssapi-principal-name](../authentication-plugin-gssapi/index#gssapi_principal_name), [gssapi\_principal\_name](../authentication-plugin-gssapi/index#gssapi_principal_name) |
| --[gssapi-mech-name](../authentication-plugin-gssapi/index#gssapi_mech_name), [gssapi\_mech\_name](../authentication-plugin-gssapi/index#gssapi_mech_name) |
| [gtid\_binlog\_pos](../global-transaction-id/index#gtid_binlog_pos) |
| [gtid\_binlog\_state](../global-transaction-id/index#gtid_binlog_state) |
| --[gtid-cleanup-batch-size](../global-transaction-id/index#gtid_cleanup_batch_size), [gtid\_cleanup\_batch\_size](../gtid/index#gtid_cleanup_batch_size) |
| [gtid\_current\_pos](../global-transaction-id/index#gtid_current_pos) |
| --[gtid-domain-id](../global-transaction-id/index#gtid_domain_id), [gtid\_domain\_id](../global-transaction-id/index#gtid_domain_id) |
| --[gtid-ignore-duplicates](../global-transaction-id/index#gtid_ignore_duplicates), [gtid\_ignore\_duplicates](../global-transaction-id/index#gtid_ignore_duplicates) |
| [gtid\_pos\_auto\_engines](../gtid/index#gtid_pos_auto_engines) |
| [gtid\_seq\_no](../global-transaction-id/index#gtid_seq_no) |
| [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) |
| --[gtid-strict-mode](../global-transaction-id/index#gtid_strict_mode), [gtid\_strict\_mode](../global-transaction-id/index#gtid_strict_mode) |
|  |
| -h, --[datadir](../server-system-variables/index#datadir), [datadir](../server-system-variables/index#datadir) |
| [Handler\_commit](../server-status-variables/index#handler_commit) |
| [Handler\_delete](../server-status-variables/index#handler_delete) |
| [Handler\_discover](../server-status-variables/index#handler_discover) |
| [Handler\_external\_lock](../server-status-variables/index#handler_external_lock) |
| [Handler\_icp\_attempts](../server-status-variables/index#handler_icp_attempts) |
| [Handler\_icp\_match](../server-status-variables/index#handler_icp_match) |
| [Handler\_mrr\_init](../server-status-variables/index#handler_mrr_init) |
| [Handler\_mrr\_key\_refills](../server-status-variables/index#handler_mrr_key_refills) |
| [Handler\_mrr\_rowid\_refills](../server-status-variables/index#handler_mrr_rowid_refills) |
| [Handler\_prepare](../server-status-variables/index#handler_prepare) |
| [Handler\_read\_first](../server-status-variables/index#handler_read_first) |
| [Handler\_read\_key](../server-status-variables/index#handler_read_key) |
| [Handler\_read\_last](../server-status-variables/index#handler_read_last) |
| [Handler\_read\_next](../server-status-variables/index#handler_read_next) |
| [Handler\_read\_prev](../server-status-variables/index#handler_read_prev) |
| [Handler\_read\_retry](../server-status-variables/index#handler_read_retry) |
| [Handler\_read\_rnd](../server-status-variables/index#handler_read_rnd) |
| [Handler\_read\_rnd\_deleted](../server-status-variables/index#handler_read_rnd_deleted) |
| [Handler\_read\_rnd\_next](../server-status-variables/index#handler_read_rnd_next) |
| [Handler\_rollback](../server-status-variables/index#handler_rollback) |
| [Handler\_savepoint](../server-status-variables/index#handler_savepoint) |
| [Handler\_savepoint\_rollback](../server-status-variables/index#handler_savepoint_rollback) |
| [Handler\_tmp\_delete](../server-status-variables/index#handler_tmp_delete) |
| [Handler\_tmp\_update](../server-status-variables/index#handler_tmp_update) |
| [Handler\_tmp\_write](../server-status-variables/index#handler_tmp_write) |
| [Handler\_update](../server-status-variables/index#handler_update) |
| [Handler\_write](../server-status-variables/index#handler_write) |
| --[handlersocket-accept-balance](../handlersocket-configuration-options/index#handlersocket_accept_balance), [handlersocket\_accept\_balance](../handlersocket-configuration-options/index#handlersocket_accept_balance) |
| --[handlersocket-address](../handlersocket-configuration-options/index#handlersocket_address), [handlersocket\_address](../handlersocket-configuration-options/index#handlersocket_address) |
| --[handlersocket-backlog](../handlersocket-configuration-options/index#handlersocket_backlog), [handlersocket\_backlog](../handlersocket-configuration-options/index#handlersocket_backlog) |
| --[handlersocket-epoll](../handlersocket-configuration-options/index#handlersocket_epoll), [handlersocket\_epoll](../handlersocket-configuration-options/index#handlersocket_epoll) |
| --[handlersocket-plain-secret](../handlersocket-configuration-options/index#handlersocket_plain_secret), [handlersocket\_plain\_secret](../handlersocket-configuration-options/index#handlersocket_plain_secret) |
| --[handlersocket-plain-secret-wr](../handlersocket-configuration-options/index#handlersocket_plain_secret_wr), [handlersocket\_plain\_secret\_wr](../handlersocket-configuration-options/index#handlersocket_plain_secret_wr) |
| --[handlersocket-port](../handlersocket-configuration-options/index#handlersocket_port), [handlersocket\_port](../handlersocket-configuration-options/index#handlersocket_port) |
| --[handlersocket-port-wr](../handlersocket-configuration-options/index#handlersocket_port_wr), [handlersocket\_port\_wr](../handlersocket-configuration-options/index#handlersocket_port_wr) |
| --[handlersocket-rcvbuf](../handlersocket-configuration-options/index#handlersocket_rcvbuf), [handlersocket\_rcvbuf](../handlersocket-configuration-options/index#handlersocket_rcvbuf) |
| --[handlersocket-readsize](../handlersocket-configuration-options/index#handlersocket_readsize), [handlersocket\_readsize](../handlersocket-configuration-options/index#handlersocket_readsize) |
| --[handlersocket-sndbuf](../handlersocket-configuration-options/index#handlersocket_sndbuf), [handlersocket\_sndbuf](../handlersocket-configuration-options/index#handlersocket_sndbuf) |
| --[handlersocket-threads](../handlersocket-configuration-options/index#handlersocket_threads), [handlersocket\_threads](../handlersocket-configuration-options/index#handlersocket_threads) |
| --[handlersocket-threads\_wr](../handlersocket-configuration-options/index#handlersocket_threads_wr), [handlersocket\_threads\_wr](../handlersocket-configuration-options/index#handlersocket_threads_wr) |
| --[handlersocket-timeout](../handlersocket-configuration-options/index#handlersocket_timeout), [handlersocket\_timeout](../handlersocket-configuration-options/index#handlersocket_timeout) |
| --[handlersocket-verbose](../handlersocket-configuration-options/index#handlersocket_verbose), [handlersocket\_verbose](../handlersocket-configuration-options/index#handlersocket_verbose) |
| --[handlersocket-wrlock-timeout](../handlersocket-configuration-options/index#handlersocket_wrlock_timeout), [handlersocket\_wrlock\_timeout](../handlersocket-configuration-options/index#handlersocket_wrlock_timeout) |
| [hashicorp-key-management-cache-timeout](../hashicorp-key-management-plugin/index#hashicorp-key-management-cache-timeout) |
| [hashicorp-key-management-cache-version-timeout](../hashicorp-key-management-plugin/index#hashicorp-key-management-cache-version-timeout) |
| [hashicorp-key-management-caching-enabled](../hashicorp-key-management-plugin/index#hashicorp-key-management-caching-enabled) |
| [hashicorp-key-management-check-kv-version](../hashicorp-key-management-plugin/index#hashicorp-key-management-check-kv-version) |
| [hashicorp-key-management-retries](../hashicorp-key-management-plugin/index#hashicorp-key-management-retries) |
| [hashicorp-key-management-timeout](../hashicorp-key-management-plugin/index#hashicorp-key-management-timeout) |
| [hashicorp-key-management-token](../hashicorp-key-management-plugin/index#hashicorp-key-management-token) |
| [hashicorp-key-management-use-cache-on-timeout](../hashicorp-key-management-plugin/index#hashicorp-key-management-use-cache-on-timeout) |
| [hashicorp-key-management-vault-ca](../hashicorp-key-management-plugin/index#hashicorp-key-management-vault-ca) |
| [hashicorp-key-management-vault-url](../hashicorp-key-management-plugin/index#hashicorp-key-management-vault-url) |
| [have\_compress](../server-system-variables/index#have_compress) |
| [have\_crypt](../server-system-variables/index#have_crypt) |
| [have\_csv](../server-system-variables/index#have_csv) |
| [have\_dynamic\_loading](../server-system-variables/index#have_dynamic_loading) |
| [have\_geometry](../server-system-variables/index#have_geometry) |
| [have\_innodb](../innodb-system-variables/index#have_innodb) |
| [have\_ndbcluster](../server-system-variables/index#have_ndbcluster) |
| [have\_openssl](../ssl-server-system-variables/index#have_openssl) |
| [have\_partitioning](../server-system-variables/index#have_partitioning) |
| [have\_profiling](../server-system-variables/index#have_profiling) |
| [have\_query\_cache](../server-system-variables/index#have_query_cache) |
| [have\_rtree\_keys](../server-system-variables/index#have_rtree_keys) |
| [have\_ssl](../ssl-server-system-variables/index#have_ssl) |
| [have\_symlink](../server-system-variables/index#have_symlink) |
| --[help](../mysqld-options/index#-help) |
| --[histogram-size](../server-system-variables/index#histogram_size), [histogram\_size](../server-system-variables/index#histogram_size) |
| --[histogram-type](../server-system-variables/index#histogram_type), [histogram\_type](../server-system-variables/index#histogram_type) |
| --[host-cache-size](../server-system-variables/index#host_cache_size), [host\_cache\_size](../server-system-variables/index#host_cache_size) |
| [hostname](../server-system-variables/index#hostname) |
| [identity](../server-system-variables/index#identity) |
| --[idle-readonly-transaction-timeout](../server-system-variables/index#idle_readonly_transaction_timeout), [idle\_readonly\_transaction\_timeout](../server-system-variables/index#idle_readonly_transaction_timeout) |
| --[idle-transaction-timeout](../server-system-variables/index#idle_transaction_timeout), [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout) |
| --[idle-write-transaction-timeout](../server-system-variables/index#idle_write_transaction_timeout), [idle\_write\_transaction\_timeout](../server-system-variables/index#idle_write_transaction_timeout) |
| --[ignore-db-dirs](../server-system-variables/index#ignore_db_dirs), [ignore\_db\_dirs](../server-system-variables/index#ignore_db_dirs) |
| --[ignore-builtin-innodb](../innodb-system-variables/index#ignore_builtin_innodb), [ignore\_builtin\_innodb](../innodb-system-variables/index#ignore_builtin_innodb) |
| --[in-predicate-conversion-threshold](../server-system-variables/index#in_predicate_conversion_threshold), [in\_predicate\_conversion\_threshold](../server-system-variables/index#in_predicate_conversion_threshold) |
| [in\_transaction](../server-system-variables/index#in_transaction) |
| --[init-connect](../server-system-variables/index#init_connect), [init\_connect](../server-system-variables/index#init_connect) |
| --[init-file](../server-system-variables/index#init_file), [init\_file](../server-system-variables/index#init_file) |
| --[init-rpl-role](../mysqld-options-full-list/index#-init-rpl-role) |
| --[init-slave](../replication-and-binary-log-server-system-variables/index#init_slave), [init\_slave](../replication-and-binary-log-server-system-variables/index#init_slave) |
| --[innodb](../mysqld-options/index#-innodb) |
| --[innodb-adaptive-checkpoint](../innodb-system-variables/index#innodb_adaptive_checkpoint), [innodb\_adaptive\_checkpoint](../innodb-system-variables/index#innodb_adaptive_checkpoint) |
| --[innodb-adaptive-flushing](../innodb-system-variables/index#innodb_adaptive_flushing), [innodb\_adaptive\_flushing](../innodb-system-variables/index#innodb_adaptive_flushing) |
| --[innodb-adaptive-flushing-lwm](../innodb-system-variables/index#innodb_adaptive_flushing_lwm), [innodb\_adaptive\_flushing\_lwm](../innodb-system-variables/index#innodb_adaptive_flushing_lwm) |
| --[innodb\_adaptive-flushing-method](../innodb-system-variables/index#innodb_adaptive_flushing_method), [innodb\_adaptive\_flushing\_method](../innodb-system-variables/index#innodb_adaptive_flushing_method) |
| [Innodb\_adaptive\_hash\_cells](../innodb-status-variables/index#innodb_adaptive_hash_cells) |
| [Innodb\_adaptive\_hash\_hash\_searches](../innodb-status-variables/index#innodb_adaptive_hash_hash_searches) |
| [Innodb\_adaptive\_hash\_heap\_buffers](../innodb-status-variables/index#innodb_adaptive_hash_heap_buffers) |
| --[innodb-adaptive-hash-index](../innodb-system-variables/index#innodb_adaptive_hash_index), [innodb\_adaptive\_hash\_index](../innodb-system-variables/index#innodb_adaptive_hash_index) |
| --[innodb-adaptive-hash-index-partitions](../innodb-system-variables/index#innodb_adaptive_hash_index_partitions), [innodb\_adaptive\_hash\_index\_partitions](../innodb-system-variables/index#innodb_adaptive_hash_index_partitions) |
| --[innodb-adaptive-hash-index-parts](../innodb-system-variables/index#innodb_adaptive_hash_index_parts), [innodb\_adaptive\_hash\_index\_parts](../innodb-system-variables/index#innodb_adaptive_hash_index_parts) |
| [Innodb\_adaptive\_hash\_non\_hash\_searches](../innodb-status-variables/index#innodb_adaptive_hash_non_hash_searches) |
| --[innodb-adaptive-max-sleep-delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay), [innodb\_adaptive\_max\_sleep\_delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay) |
| --[innodb-additional-mem-pool-size](../innodb-system-variables/index#innodb_additional_mem_pool_size), [innodb\_additional\_mem\_pool\_size](../innodb-system-variables/index#innodb_additional_mem_pool_size) |
| --[innodb-api-bk-commit\_interval](../innodb-system-variables/index#innodb_api_bk_commit_interval), [innodb\_api\_bk\_commit\_interval](../innodb-system-variables/index#innodb_api_bk_commit_interval) |
| --[innodb-api-disable-rowlock](../innodb-system-variables/index#innodb_api_disable_rowlock), [innodb\_api\_disable\_rowlock](../innodb-system-variables/index#innodb_api_disable_rowlock) |
| --[innodb\_api\_enable\_binlog](../innodb-system-variables/index#innodb_api_enable_binlog), [innodb\_api\_enable\_binlog](../innodb-system-variables/index#innodb_api_enable_binlog) |
| --[innodb-api-enable-mdl](../innodb-system-variables/index#innodb_api_enable_mdl), [innodb\_api\_enable\_mdl](../innodb-system-variables/index#innodb_api_enable_mdl) |
| --[innodb-api-trx-level](../innodb-system-variables/index#innodb_api_trx_level), [innodb\_api\_trx\_level](../innodb-system-variables/index#innodb_api_trx_level) |
| --[innodb-auto-lru-dump](../innodb-system-variables/index#innodb_auto_lru_dump), [innodb-auto-lru-dump](../innodb-system-variables/index#innodb_auto_lru_dump) |
| --[innodb-autoextend-increment](../innodb-system-variables/index#innodb_autoextend_increment), [innodb\_autoextend\_increment](../innodb-system-variables/index#innodb_autoextend_increment) |
| --[innodb-autoinc-lock-mode](../innodb-system-variables/index#innodb_autoinc_lock_mode), [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) |
| [Innodb\_available\_undo\_logs](../innodb-status-variables/index#innodb_available_undo_logs) |
| [Innodb\_background\_log\_sync](../innodb-status-variables/index#innodb_background_log_sync) |
| --[innodb-background-scrub-data-check-interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval), [innodb\_background\_scrub\_data\_check\_interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval) |
| --[innodb-background-scrub-data-compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed), [innodb\_background\_scrub\_data\_compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed) |
| --[innodb-background-scrub-data-interval](../innodb-system-variables/index#innodb_background_scrub_data_interval), [innodb\_background\_scrub\_data\_interval](../innodb-system-variables/index#innodb_background_scrub_data_interval) |
| --[innodb-background-scrub-data-uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed), [innodb\_background\_scrub\_data\_uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed) |
| --[innodb-blocking-buffer-pool-restore](../innodb-system-variables/index#innodb_blocking_buffer_pool_restore), [innodb\_blocking\_buffer\_pool\_restore](../innodb-system-variables/index#innodb_blocking_buffer_pool_restore) |
| --[innodb-buf-dump-status-frequency](../innodb-system-variables/index#innodb_buf_dump_status_frequency), [innodb\_buf\_dump\_status\_frequency](../innodb-system-variables/index#innodb_buf_dump_status_frequency) |
| [Innodb\_buffer\_pool\_bytes\_data](../innodb-status-variables/index#innodb_buffer_pool_bytes_data) |
| [Innodb\_buffer\_pool\_bytes\_dirty](../innodb-status-variables/index#innodb_buffer_pool_bytes_dirty) |
| --[innodb-buffer-pool-chunk-size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size), [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) |
| --[innodb-buffer-pool-dump-at-shutdown](../innodb-system-variables/index#innodb_buffer_pool_dump_at_shutdown), [innodb\_buffer\_pool\_dump\_at\_shutdown](../innodb-system-variables/index#innodb_buffer_pool_dump_at_shutdown) |
| --[innodb-buffer-pool-dump-now](../innodb-system-variables/index#innodb_buffer_pool_dump_now), [innodb\_buffer\_pool\_dump\_now](../innodb-system-variables/index#innodb_buffer_pool_dump_now) |
| --[innodb-buffer-pool-dump-pct](../innodb-system-variables/index#innodb_buffer_pool_dump_pct), [innodb\_buffer\_pool\_dump\_pct](../innodb-system-variables/index#innodb_buffer_pool_dump_pct) |
| [Innodb\_buffer\_pool\_dump\_status](../innodb-status-variables/index#innodb_buffer_pool_dump_status) |
| --[innodb-buffer-pool-evict](../innodb-system-variables/index#innodb_buffer_pool_evict), [innodb\_buffer\_pool\_evict](../innodb-system-variables/index#innodb_buffer_pool_evict) |
| --[innodb-buffer-pool-filename](../innodb-system-variables/index#innodb_buffer_pool_filename), [innodb\_buffer\_pool\_filename](../innodb-system-variables/index#innodb_buffer_pool_filename) |
| --[innodb-buffer-pool-instances](../innodb-system-variables/index#innodb_buffer_pool_instances), [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) |
| --[innodb-buffer-pool-load-abort](../innodb-system-variables/index#innodb_buffer_pool_load_abort), [innodb\_buffer\_pool\_load\_abort](../innodb-system-variables/index#innodb_buffer_pool_load_abort) |
| --[innodb-buffer-pool-load-at-startup](../innodb-system-variables/index#innodb_buffer_pool_load_at_startup), [innodb\_buffer\_pool\_load\_at\_startup](../innodb-system-variables/index#innodb_buffer_pool_load_at_startup) |
| --[innodb-buffer-pool-load-now](../innodb-system-variables/index#innodb_buffer_pool_load_now), [innodb\_buffer\_pool\_load\_now](../innodb-system-variables/index#innodb_buffer_pool_load_now) |
| [Innodb\_buffer\_pool\_load\_incomplete](../innodb-status-variables/index#innodb_buffer_pool_load_pagesincomplete) |
| --[innodb-buffer-pool-load-pages-abort](../innodb-system-variables/index#innodb_buffer_pool_load_pages_abort), [innodb\_buffer\_pool\_load\_pages\_abort](../innodb-system-variables/index#innodb_buffer_pool_load_pages_abort) |
| [Innodb\_buffer\_pool\_load\_status](../innodb-status-variables/index#innodb_buffer_pool_load_status) |
| [Innodb\_buffer\_pool\_pages\_data](../innodb-status-variables/index#innodb_buffer_pool_pages_data) |
| [Innodb\_buffer\_pool\_pages\_dirty](../innodb-status-variables/index#innodb_buffer_pool_pages_dirty) |
| [Innodb\_buffer\_pool\_pages\_flushed](../innodb-status-variables/index#innodb_buffer_pool_pages_flushed) |
| [Innodb\_buffer\_pool\_pages\_LRU\_flushed](../innodb-status-variables/index#innodb_buffer_pool_pages_lru_flushed) |
| [Innodb\_buffer\_pool\_pages\_LRU\_freed](../innodb-status-variables/index#innodb_buffer_pool_pages_lru_freed) |
| [Innodb\_buffer\_pool\_pages\_free](../innodb-status-variables/index#innodb_buffer_pool_pages_free) |
| [Innodb\_buffer\_pool\_pages\_made\_not\_young](../innodb-status-variables/index#innodb_buffer_pool_pages_made_not_young) |
| [Innodb\_buffer\_pool\_pages\_made\_young](../innodb-status-variables/index#innodb_buffer_pool_pages_made_young) |
| [Innodb\_buffer\_pool\_pages\_misc](../innodb-status-variables/index#innodb_buffer_pool_pages_misc) |
| [Innodb\_buffer\_pool\_pages\_old](../innodb-status-variables/index#innodb_buffer_pool_pages_old) |
| [Innodb\_buffer\_pool\_pages\_total](../innodb-status-variables/index#innodb_buffer_pool_pages_total) |
| --[innodb-buffer-pool-populate](../innodb-system-variables/index#innodb_buffer_pool_populate), [innodb\_buffer\_pool\_populate](../innodb-system-variables/index#innodb_buffer_pool_populate) |
| [Innodb\_buffer\_pool\_read\_ahead](../innodb-status-variables/index#innodb_buffer_pool_read_ahead) |
| [Innodb\_buffer\_pool\_read\_ahead\_evicted](../innodb-status-variables/index#innodb_buffer_pool_read_ahead_evicted) |
| [Innodb\_buffer\_pool\_read\_ahead\_rnd](../innodb-status-variables/index#innodb_buffer_pool_read_ahead_rnd) |
| [Innodb\_buffer\_pool\_read\_requests](../innodb-status-variables/index#innodb_buffer_pool_read_requests) |
| [Innodb\_buffer\_pool\_reads](../innodb-status-variables/index#innodb_buffer_pool_reads) |
| [Innodb\_buffer\_pool\_resize\_status](../innodb-status-variables/index#innodb_buffer_pool_resize_status) |
| --[innodb-buffer-pool-restore-at-startup](../innodb-system-variables/index#innodb_buffer_pool_restore_at_startup), [innodb\_buffer\_pool\_restore\_at\_startup](../innodb-system-variables/index#innodb_buffer_pool_restore_at_startup) |
| --[innodb-buffer-pool-shm-checksum](../innodb-system-variables/index#innodb_buffer_pool_shm_checksum), [innodb\_buffer\_pool\_shm\_checksum](../innodb-system-variables/index#innodb_buffer_pool_shm_checksum) |
| --[innodb-buffer-pool-shm-key](../innodb-system-variables/index#innodb_buffer_pool_shm_key), [innodb\_buffer\_pool\_shm\_key](../innodb-system-variables/index#innodb_buffer_pool_shm_key) |
| --[innodb-buffer-pool-size](../innodb-system-variables/index#innodb_buffer_pool_size), [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) |
| [Innodb\_buffer\_pool\_wait\_free](../innodb-status-variables/index#innodb_buffer_pool_wait_free) |
| [Innodb\_buffer\_pool\_write\_requests](../innodb-status-variables/index#innodb_buffer_pool_write_requests) |
| [Innodb\_buffered\_aio\_submitted](../innodb-status-variables/index#innodb_buffered_aio_submitted) |
| --[innodb-change-buffer-dump](../innodb-system-variables/index#innodb_change_buffer_dump), [innodb\_change\_buffer\_dump](../innodb-system-variables/index#innodb_change_buffer_dump) |
| --[innodb-change-buffer-max-size](../innodb-system-variables/index#innodb_change_buffer_max_size), [innodb\_change\_buffer\_max\_size](../innodb-system-variables/index#innodb_change_buffer_max_size) |
| --[innodb-change-buffering](../innodb-system-variables/index#innodb_change_buffering), [innodb\_change\_buffering](../innodb-system-variables/index#innodb_change_buffering) |
| --[innodb-change-buffering-debug](../innodb-system-variables/index#innodb_change_buffering_debug), [innodb\_change\_buffering\_debug](../innodb-system-variables/index#innodb_change_buffering_debug) |
| [Innodb\_checkpoint\_age](../innodb-status-variables/index#innodb_checkpoint_age) |
| --[innodb-checkpoint-age-target](../innodb-system-variables/index#innodb_checkpoint_age_target), [innodb\_checkpoint\_age\_target](../innodb-system-variables/index#innodb_checkpoint_age_target) |
| [Innodb\_checkpoint\_max\_age](../innodb-status-variables/index#innodb_checkpoint_max_age) |
| [Innodb\_checkpoint\_target\_age](../innodb-status-variables/index#innodb_checkpoint_target_age) |
| --[innodb-checksum-algorithm](../innodb-system-variables/index#innodb_checksum_algorithm), [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) |
| --[innodb-checksums](../innodb-system-variables/index#innodb_checksums), [innodb\_checksums](../innodb-system-variables/index#innodb_checksums) |
| --[innodb-cleaner-lsn-age-factor](../innodb-system-variables/index#innodb_cleaner_lsn_age_factor), [innodb\_cleaner\_lsn\_age\_factor](../innodb-system-variables/index#innodb_cleaner_lsn_age_factor) |
| --[innodb-cmp](../mysqld-options-full-list/index#-innodb-cmp) |
| --[innodb-cmp-per-index-enabled](../innodb-system-variables/index#innodb_cmp_per_index_enabled), [innodb\_cmp\_per\_index\_enabled](../innodb-system-variables/index#innodb_cmp_per_index_enabled) |
| --[innodb-cmp-reset](../mysqld-options-full-list/index#-innodb-cmp-reset) |
| --[innodb-cmpmem](../mysqld-options-full-list/index#-innodb-cmpmem) |
| --[innodb-cmpmem-reset](../mysqld-options-full-list/index#-innodb-cmpmem-reset) |
| --[innodb-commit-concurrency](../innodb-system-variables/index#innodb_commit_concurrency), [innodb\_commit\_concurrency](../innodb-system-variables/index#innodb_commit_concurrency) |
| --[innodb-compression-algorithm](../innodb-system-variables/index#innodb_compression_algorithm), [innodb\_compression\_algorithm](../innodb-system-variables/index#innodb_compression_algorithm) |
| --[innodb-compression-default](../innodb-system-variables/index#innodb_compression_default), [innodb\_compression\_default](../innodb-system-variables/index#innodb_compression_default) |
| --[innodb-compression-failure-threshold-pct](../innodb-system-variables/index#innodb_compression_failure_threshold_pct), [innodb\_compression\_failure\_threshold\_pct](../innodb-system-variables/index#innodb_compression_failure_threshold_pct) |
| --[innodb-compression-level](../innodb-system-variables/index#innodb_compression_level), [innodb\_compression\_level](../innodb-system-variables/index#innodb_compression_level) |
| --[innodb-compression-pad-pct-max](../innodb-system-variables/index#innodb_compression_pad_pct_max), [innodb\_compression\_pad\_pct\_max](../innodb-system-variables/index#innodb_compression_pad_pct_max) |
| --[innodb-concurrency-tickets](../innodb-system-variables/index#innodb_concurrency_tickets), [innodb\_concurrency\_tickets](../innodb-system-variables/index#innodb_concurrency_tickets) |
| --[innodb-corrupt-table-action](../innodb-system-variables/index#innodb_corrupt_table_action), [innodb\_corrupt\_table\_action](../innodb-system-variables/index#innodb_corrupt_table_action) |
| [Innodb\_current\_row\_locks](../innodb-status-variables/index#innodb_current_row_locks) |
| --[innodb-data-file-buffering](../innodb-system-variables/index#innodb_data_file_buffering), [innodb\_data\_file\_buffering](../innodb-system-variables/index#innodb_data_file_buffering) |
| --[innodb-data-file-path](../innodb-system-variables/index#innodb_data_file_path), [innodb\_data\_file\_path](../innodb-system-variables/index#innodb_data_file_path) |
| --[innodb-data-file-write\_through](../innodb-system-variables/index#innodb_data_file_write_through), [innodb\_data\_file\_write\_through](../innodb-system-variables/index#innodb_data_file_write_through) |
| [Innodb\_data\_fsyncs](../innodb-status-variables/index#innodb_data_fsyncs) |
| --[innodb-data-home-dir](../innodb-system-variables/index#innodb_data_home_dir), [innodb\_data\_home\_dir](../innodb-system-variables/index#innodb_data_home_dir) |
| [Innodb\_data\_pending\_fsyncs](../innodb-status-variables/index#innodb_data_pending_fsyncs) |
| [Innodb\_data\_pending\_reads](../innodb-status-variables/index#innodb_data_pending_reads) |
| [Innodb\_data\_pending\_writes](../innodb-status-variables/index#innodb_data_pending_writes) |
| [Innodb\_data\_read](../innodb-status-variables/index#innodb_data_read) |
| [Innodb\_data\_reads](../innodb-status-variables/index#innodb_data_reads) |
| [Innodb\_data\_writes](../innodb-status-variables/index#innodb_data_writes) |
| [Innodb\_data\_written](../innodb-status-variables/index#innodb_data_written) |
| [Innodb\_dblwr\_pages\_written](../innodb-status-variables/index#innodb_dblwr_pages_written) |
| [Innodb\_dblwr\_writes](../innodb-status-variables/index#innodb_dblwr_writes) |
| --[innodb-deadlock-detect](../innodb-system-variables/index#innodb_deadlock_detect), [innodb\_deadlock\_detect](../innodb-system-variables/index#innodb_deadlock_detect) |
| --[innodb-deadlock-report](../innodb-system-variables/index#innodb_deadlock_report), [innodb\_deadlock\_report](../innodb-system-variables/index#innodb_deadlock_report) |
| [Innodb\_deadlocks](../innodb-status-variables/index#innodb_deadlocks) |
| --[innodb-default-encryption-key-id](../innodb-system-variables/index#innodb_default_encryption_key_id), [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) |
| --[innodb-default-page-encryption-key](../innodb-system-variables/index#innodb_default_page_encryption_key), [innodb\_default\_page\_encryption\_key](../innodb-system-variables/index#innodb_default_page_encryption_key) |
| --[innodb-default-row-format](../innodb-system-variables/index#innodb_default_row_format), [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) |
| --[innodb-defragment](../innodb-system-variables/index#innodb_defragment), [innodb\_defragment](../innodb-system-variables/index#innodb_defragment) |
| [Innodb\_defragment\_compression\_failures](../innodb-status-variables/index#innodb_defragment_compression_failures) |
| [Innodb\_defragment\_count](../innodb-status-variables/index#innodb_defragment_count) |
| [Innodb\_defragment\_failures](../innodb-status-variables/index#innodb_defragment_failures) |
| --[innodb-defragment-fill-factor](../innodb-system-variables/index#innodb_defragment_fill_factor), [innodb\_defragment\_fill\_factor](../innodb-system-variables/index#innodb_defragment_fill_factor) |
| --[innodb-defragment-fill-factor-n-recs](../innodb-system-variables/index#innodb_defragment_fill_factor_n_recs), [innodb\_defragment\_fill\_factor\_n\_recs](../innodb-system-variables/index#innodb_defragment_fill_factor_n_recs) |
| --[innodb-defragment-frequency](../innodb-system-variables/index#innodb_defragment_frequency), [innodb\_defragment\_frequency](../innodb-system-variables/index#innodb_defragment_frequency) |
| --[innodb-defragment-n-pages](../innodb-system-variables/index#innodb_defragment_n_pages), [innodb\_defragment\_n\_pages](../innodb-system-variables/index#innodb_defragment_n_pages) |
| --[innodb-defragment-stats-accuracy](../innodb-system-variables/index#innodb_defragment_stats_accuracy), [innodb\_defragment\_stats\_accuracy](../innodb-system-variables/index#innodb_defragment_stats_accuracy) |
| --[innodb-dict-size-limit](../innodb-system-variables/index#innodb_dict_size_limit), [innodb\_dict\_size\_limit](../innodb-system-variables/index#innodb_dict_size_limit) |
| [Innodb\_dict\_tables](../innodb-status-variables/index#innodb_dict_tables) |
| --[innodb-disable-sort-file-cache](../innodb-system-variables/index#innodb_disable_sort_file_cache), [innodb\_disable\_sort\_file\_cache](../innodb-system-variables/index#innodb_disable_sort_file_cache) |
| [innodb\_disallow\_writes](../innodb-system-variables/index#innodb_disallow_writes) |
| --[innodb-doublewrite](../innodb-system-variables/index#innodb_doublewrite), [innodb\_doublewrite](../innodb-system-variables/index#innodb_doublewrite) |
| --[innodb-doublewrite-file](../innodb-system-variables/index#innodb_doublewrite_file), [innodb\_doublewrite\_file](../innodb-system-variables/index#innodb_doublewrite_file) |
| --[innodb\_empty-free-list-algorithm](../innodb-system-variables/index#innodb_empty_free_list_algorithm), [innodb\_empty\_free\_list\_algorithm](../innodb-system-variables/index#innodb_empty_free_list_algorithm) |
| --[innodb-enable-unsafe-group-commit](../innodb-system-variables/index#innodb_enable_unsafe_group_commit), [innodb\_enable\_unsafe\_group\_commit](../innodb-system-variables/index#innodb_enable_unsafe_group_commit) |
| --[innodb-encrypt-log](../innodb-system-variables/index#innodb_encrypt_log), [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) |
| --[innodb-encrypt-tables](../innodb-system-variables/index#innodb_encrypt_tables), [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) |
| --[innodb-encrypt-temporary-tables](../innodb-system-variables/index#innodb_encrypt_temporary_tables), [innodb\_encrypt\_temporary\_tables](../innodb-system-variables/index#innodb_encrypt_temporary_tables) |
| [Innodb\_encryption\_n\_merge\_blocks\_decrypted](../innodb-status-variables/index#innodb_encryption_n_merge_blocks_decrypted) |
| [Innodb\_encryption\_n\_merge\_blocks\_encrypted](../innodb-status-variables/index#innodb_encryption_n_merge_blocks_encrypted) |
| [Innodb\_encryption\_n\_rowlog\_blocks\_decrypted](../innodb-status-variables/index#innodb_encryption_n_rowlog_blocks_decrypted) |
| [Innodb\_encryption\_n\_rowlog\_blocks\_encrypted](../innodb-status-variables/index#innodb_encryption_n_rowlog_blocks_encrypted) |
| [Innodb\_encryption\_n\_temp\_blocks\_decrypted](../innodb-status-variables/index#innodb_encryption_n_temp_blocks_decrypted) |
| [Innodb\_encryption\_n\_temp\_blocks\_encrypted](../innodb-status-variables/index#innodb_encryption_n_temp_blocks_encrypted) |
| [Innodb\_encryption\_num\_key\_requests](../innodb-status-variables/index#innodb_encryption_num_key_requests) |
| --[innodb-encryption-rotate-key-age](../innodb-system-variables/index#innodb_encryption_rotate_key_age), [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) |
| [Innodb\_encryption\_rotation\_estimated\_iops](../innodb-status-variables/index#innodb_encryption_rotation_estimated_iops) |
| --[innodb-encryption-rotation-iops](../innodb-system-variables/index#innodb_encryption_rotation_iops), [innodb\_encryption\_rotation\_iops](../innodb-system-variables/index#innodb_encryption_rotation_iops) |
| [Innodb\_encryption\_rotation\_pages\_flushed](../innodb-status-variables/index#innodb_encryption_rotation_pages_flushed) |
| [Innodb\_encryption\_rotation\_pages\_modified](../innodb-status-variables/index#innodb_encryption_rotation_pages_modified) |
| [Innodb\_encryption\_rotation\_pages\_read\_from\_cache](../innodb-status-variables/index#innodb_encryption_rotation_pages_read_from_cache) |
| [Innodb\_encryption\_rotation\_pages\_read\_from\_disk](../innodb-status-variables/index#innodb_encryption_rotation_pages_read_from_disk) |
| --[innodb-encryption-threads](../innodb-system-variables/index#innodb_encryption_threads), [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) |
| --[innodb-extra-rsegments](../innodb-system-variables/index#innodb_extra_rsegments), [innodb\_extra\_rsegments](../innodb-system-variables/index#innodb_extra_rsegments) |
| --[innodb-extra-undoslots](../innodb-system-variables/index#innodb_extra_undoslots), [innodb\_extra\_undoslots](../innodb-system-variables/index#innodb_extra_undoslots) |
| --[innodb-fake-changes](../innodb-system-variables/index#innodb_fake_changes), [innodb\_fake\_changes](../innodb-system-variables/index#innodb_fake_changes) |
| --[innodb-fast-checksum](../innodb-system-variables/index#innodb_fast_checksum), [innodb\_fast\_checksum](../innodb-system-variables/index#innodb_fast_checksum) |
| --[innodb-fast-shutdown](../innodb-system-variables/index#innodb_fast_shutdown), [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) |
| --[innodb-fatal-semaphore-wait-threshold](../innodb-system-variables/index#innodb_fatal_semaphore_wait_threshold), [innodb\_fatal\_semaphore\_wait\_threshold](../innodb-system-variables/index#innodb_fatal_semaphore_wait_threshold) |
| --[innodb-file-format](../innodb-system-variables/index#innodb_file_format), [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) |
| --[innodb-file-format-check](../innodb-system-variables/index#innodb_file_format_check), [innodb\_file\_format\_check](../innodb-system-variables/index#innodb_file_format_check) |
| --[innodb-file-format-max](../innodb-system-variables/index#innodb_file_format_max), [innodb\_file\_format\_max](../innodb-system-variables/index#innodb_file_format_max) |
| --[innodb-file-io-threads](../mysqld-options-full-list/index#-innodb-file-io-threads) |
| --[innodb-file-per-table](../innodb-system-variables/index#innodb_file_per_table), [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) |
| --[innodb-fill-factor](../innodb-system-variables/index#innodb_fill_factor), [innodb\_fill\_factor](../innodb-system-variables/index#innodb_fill_factor) |
| --[innodb-flush-log-at-timeout](../innodb-system-variables/index#innodb_flush_log_at_timeout), [innodb\_flush\_log\_at\_timeout](../innodb-system-variables/index#innodb_flush_log_at_timeout) |
| --[innodb-flush-log-at-trx-commit](../innodb-system-variables/index#innodb_flush_log_at_trx_commit), [innodb\_flush\_log\_at\_trx\_commit](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) |
| --[innodb-flush-method](../innodb-system-variables/index#innodb_flush_method), [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method) |
| --[innodb-flush-neighbor-pages](../innodb-system-variables/index#innodb_flush_neighbor_pages), [innodb\_flush\_neighbor\_pages](../innodb-system-variables/index#innodb_flush_neighbor_pages) |
| --[innodb-flush-neighbors](../innodb-system-variables/index#innodb_flush_neighbors), [innodb\_flush\_neighbors](../innodb-system-variables/index#innodb_flush_neighbors) |
| --[innodb-flush-sync](../innodb-system-variables/index#innodb_flush_sync), [innodb\_flush\_sync](../innodb-system-variables/index#innodb_flush_sync) |
| --[innodb-flushing-avg-loops](../innodb-system-variables/index#innodb_flushing_avg_loops), [innodb\_flushing\_avg\_loops](../innodb-system-variables/index#innodb_flushing_avg_loops) |
| --[innodb-force-load-corrupted](../innodb-system-variables/index#innodb_force_load_corrupted), [innodb\_force\_load\_corrupted](../innodb-system-variables/index#innodb_force_load_corrupted) |
| --[innodb-force-primary-key](../innodb-system-variables/index#innodb_force_primary_key), [innodb\_force\_primary\_key](../innodb-system-variables/index#innodb_force_primary_key) |
| --[innodb-force-recovery](../innodb-system-variables/index#innodb_force_recovery), [innodb\_force\_recovery](../innodb-system-variables/index#innodb_force_recovery) |
| --[innodb-foreground-preflush](../innodb-system-variables/index#innodb_foreground_preflush), [innodb\_foreground\_preflush](../innodb-system-variables/index#innodb_foreground_preflush) |
| --[innodb-ft-aux-table](../innodb-system-variables/index#innodb_ft_aux_table), [innodb\_ft\_aux\_table](../innodb-system-variables/index#innodb_ft_aux_table) |
| --[innodb-ft-cache-size](../innodb-system-variables/index#innodb_ft_cache_size), [innodb\_ft\_cache\_size](../innodb-system-variables/index#innodb_ft_cache_size) |
| --[innodb-ft-enable-diag-print](../innodb-system-variables/index#innodb_ft_enable_diag_print), [innodb\_ft\_enable\_diag\_print](../innodb-system-variables/index#innodb_ft_enable_diag_print) |
| --[innodb-ft-enable-stopword](../innodb-system-variables/index#innodb_ft_enable_stopword), [innodb\_ft\_enable\_stopword](../innodb-system-variables/index#innodb_ft_enable_stopword) |
| --[innodb-ft-max-token-size](../innodb-system-variables/index#innodb_ft_max_token_size), [innodb\_ft\_max\_token\_size](../innodb-system-variables/index#innodb_ft_max_token_size) |
| --[innodb-ft-min-token-size](../innodb-system-variables/index#innodb_ft_min_token_size), [innodb\_ft\_min\_token\_size](../innodb-system-variables/index#innodb_ft_min_token_size) |
| --[innodb-ft-num-word-optimize](../innodb-system-variables/index#innodb_ft_num_word_optimize), [innodb\_ft\_num\_word\_optimize](../innodb-system-variables/index#innodb_ft_num_word_optimize) |
| --[innodb-ft-result-cache-limit](../innodb-system-variables/index#innodb_ft_result_cache_limit), [innodb\_ft\_result\_cache\_limit](../innodb-system-variables/index#innodb_ft_result_cache_limit) |
| --[innodb-ft-server-stopword-table](../innodb-system-variables/index#innodb_ft_server_stopword_table), [innodb\_ft\_server\_stopword\_table](../innodb-system-variables/index#innodb_ft_server_stopword_table) |
| --[innodb-ft-sort-pll-degree](../innodb-system-variables/index#innodb_ft_sort_pll_degree), [innodb\_ft\_sort\_pll\_degree](../innodb-system-variables/index#innodb_ft_sort_pll_degree) |
| --[innodb-ft-total-cache-size](../innodb-system-variables/index#innodb_ft_total_cache_size), [innodb\_ft\_total\_cache\_size](../innodb-system-variables/index#innodb_ft_total_cache_size) |
| --[innodb-ft-user-stopword-table](../innodb-system-variables/index#innodb_ft_user_stopword_table), [innodb\_ft\_user\_stopword\_table](../innodb-system-variables/index#innodb_ft_user_stopword_table) |
| [Innodb\_have\_atomic\_builtins](../innodb-status-variables/index#innodb_have_atomic_builtins) |
| [Innodb\_have\_bzip2](../innodb-status-variables/index#innodb_have_bzip2) |
| [Innodb\_have\_lz4](../innodb-status-variables/index#innodb_have_lz4) |
| [Innodb\_have\_lzma](../innodb-status-variables/index#innodb_have_lzma) |
| [Innodb\_have\_lzo](../innodb-status-variables/index#innodb_have_lzo) |
| [Innodb\_have\_punch\_hole](../innodb-status-variables/index#innodb_have_punch_hole) |
| [Innodb\_have\_snappy](../innodb-status-variables/index#innodb_have_snappy) |
| [Innodb\_history\_list\_length](../innodb-status-variables/index#innodb_history_list_length) |
| --[innodb-ibuf-accel-rate](../innodb-system-variables/index#innodb_ibuf_accel_rate), [innodb\_ibuf\_accel\_rate](../innodb-system-variables/index#innodb_ibuf_accel_rate) |
| --[innodb-ibuf-active-contract](../innodb-system-variables/index#innodb_ibuf_active_contract), [innodb\_ibuf\_active\_contract](../innodb-system-variables/index#innodb_ibuf_active_contract) |
| [Innodb\_ibuf\_discarded\_delete\_marks](../innodb-status-variables/index#innodb_ibuf_discarded_delete_marks) |
| [Innodb\_ibuf\_discarded\_deletes](../innodb-status-variables/index#innodb_ibuf_discarded_deletes) |
| [Innodb\_ibuf\_discarded\_inserts](../innodb-status-variables/index#innodb_ibuf_discarded_inserts) |
| [Innodb\_ibuf\_free\_list](../innodb-status-variables/index#innodb_ibuf_free_list) |
| --[innodb-ibuf-max-size](../innodb-system-variables/index#innodb_ibuf_max_size), [innodb\_ibuf\_max\_size](../innodb-system-variables/index#innodb_ibuf_max_size) |
| [Innodb\_ibuf\_merged\_delete\_marks](../innodb-status-variables/index#innodb_ibuf_merged_delete_marks) |
| [Innodb\_ibuf\_merged\_deletes](../innodb-status-variables/index#innodb_ibuf_merged_deletes) |
| [Innodb\_ibuf\_merged\_inserts](../innodb-status-variables/index#innodb_ibuf_merged_inserts) |
| [Innodb\_ibuf\_merges](../innodb-status-variables/index#innodb_ibuf_merges) |
| [Innodb\_ibuf\_segment\_size](../innodb-status-variables/index#innodb_ibuf_segment_size) |
| [Innodb\_ibuf\_size](../innodb-status-variables/index#innodb_ibuf_size) |
| --[innodb-idle-flush-pct](../innodb-system-variables/index#innodb_idle_flush_pct), [innodb\_idle\_flush\_pct](../innodb-system-variables/index#innodb_idle_flush_pct) |
| --[innodb-immediate-scrub-data-uncompressed](../innodb-system-variables/index#innodb_immediate_scrub_data_uncompressed), [innodb\_immediate\_scrub\_data\_uncompressed](../innodb-system-variables/index#innodb_immediate_scrub_data_uncompressed) |
| --[innodb-import-table-from-xtrabackup](../innodb-system-variables/index#innodb_import_table_from_xtrabackup), [innodb\_import\_table\_from\_xtrabackup](../innodb-system-variables/index#innodb_import_table_from_xtrabackup) |
| --[innodb-index-stats](../mysqld-options-full-list/index#-innodb-index-stats) |
| [Innodb\_instant\_alter\_column](../innodb-status-variables/index#innodb_instant_alter_column) |
| --[innodb-instant-alter-column-allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed), [innodb\_instant\_alter\_column\_allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed) |
| --[innodb-instrument-semaphores](../innodb-system-variables/index#innodb_instrument_semaphores), [innodb\_instrument\_semaphores](../innodb-system-variables/index#innodb_instrument_semaphores) |
| --[innodb-io-capacity](../innodb-system-variables/index#innodb_io_capacity), [innodb\_io\_capacity](../innodb-system-variables/index#innodb_io_capacity) |
| --[innodb-io-capacity-max](../innodb-system-variables/index#innodb_io_capacity_max), [innodb\_io\_capacity\_max](../innodb-system-variables/index#innodb_io_capacity_max) |
| [innodb\_kill\_idle\_transaction](../innodb-system-variables/index#innodb_kill_idle_transaction) |
| --[innodb-large-prefix](../innodb-system-variables/index#innodb_large_prefix), [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) |
| --[innodb-lazy-drop-table](../innodb-system-variables/index#innodb_lazy_drop_table), [innodb\_lazy\_drop\_table](../innodb-system-variables/index#innodb_lazy_drop_table) |
| --[innodb-lock-schedule-algorithm](../innodb-system-variables/index#innodb_lock_schedule_algorithm), [innodb\_lock\_schedule\_algorithm](../innodb-system-variables/index#innodb_lock_schedule_algorithm) |
| --[innodb-lock-wait-timeout](../innodb-system-variables/index#innodb_lock_wait_timeout), [innodb\_lock\_wait\_timeout](../innodb-system-variables/index#innodb_lock_wait_timeout) |
| --[innodb-lock-waits](../mysqld-options-full-list/index#-innodb-lock-waits) |
| --[innodb-locking-fake-changes](../innodb-system-variables/index#innodb_locking_fake_changes), [innodb\_locking\_fake\_changes](../innodb-system-variables/index#innodb_locking_fake_changes) |
| --[innodb-locks](../mysqld-options-full-list/index#-innodb-locks) |
| --[innodb-locks-unsafe-for-binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog), [innodb\_locks\_unsafe\_for\_binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog) |
| --[innodb-log-arch-dir](../innodb-system-variables/index#innodb_log_arch_dir), [innodb\_log\_arch\_dir](../innodb-system-variables/index#innodb_log_arch_dir) |
| --[innodb-log-arch-expire-sec](../innodb-system-variables/index#innodb_log_arch_expire_sec), [innodb\_log\_arch\_expire\_sec](../innodb-system-variables/index#innodb_log_arch_expire_sec) |
| --[innodb-log-archive](../innodb-system-variables/index#innodb_log_archive), [innodb\_log\_archive](../innodb-system-variables/index#innodb_log_archive) |
| --[innodb-log-block-size](../innodb-system-variables/index#innodb_log_block_size), [innodb\_log\_block\_size](../innodb-system-variables/index#innodb_log_block_size) |
| --[innodb-log-buffer-size](../innodb-system-variables/index#innodb_log_buffer_size), [innodb\_log\_buffer\_size](../innodb-system-variables/index#innodb_log_buffer_size) |
| -- [innodb-log-checksum-algorithm](../innodb-system-variables/index#innodb_log_checksum_algorithm), [innodb\_log\_checksum\_algorithm](../innodb-system-variables/index#innodb_log_checksum_algorithm) |
| -- [innodb-log-checksums](../innodb-system-variables/index#innodb_log_checksums), [innodb\_log\_checksums](../innodb-system-variables/index#innodb_log_checksums) |
| -- [innodb-log-compressed-pages](../innodb-system-variables/index#innodb_log_compressed_pages), [innodb\_log\_compressed\_pages](../innodb-system-variables/index#innodb_log_compressed_pages) |
| --[innodb-log-file-buffering](../innodb-system-variables/index#innodb_log_file_buffering), [innodb\_log\_file\_buffering](../innodb-system-variables/index#innodb_log_file_buffering) |
| --[innodb-log-file-size](../innodb-system-variables/index#innodb_log_file_size), [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) |
| --[innodb-log-file-write\_through](../innodb-system-variables/index#innodb_log_file_write_through), [innodb\_log\_file\_write\_through](../innodb-system-variables/index#innodb_log_file_write_through) |
| --[innodb-log-files-in-group](../innodb-system-variables/index#innodb_log_files_in_group), [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group) |
| --[innodb-log-group-home-dir](../innodb-system-variables/index#innodb_log_group_home_dir), [innodb\_log\_group\_home\_dir](../innodb-system-variables/index#innodb_log_group_home_dir) |
| --[innodb-log-optimize-ddl](../innodb-system-variables/index#innodb_log_optimize_ddl), [innodb\_log\_optimize\_ddl](../innodb-system-variables/index#innodb_log_optimize_ddl) |
| [Innodb\_log\_waits](../innodb-status-variables/index#innodb_log_waits) |
| --[innodb-log-write-ahead-size](../innodb-system-variables/index#innodb_log_write_ahead_size), [innodb\_log\_write\_ahead\_size](../innodb-system-variables/index#innodb_log_write_ahead_size) |
| [Innodb\_log\_write\_requests](../innodb-status-variables/index#innodb_log_write_requests) |
| [Innodb\_log\_writes](../innodb-status-variables/index#innodb_log_writes) |
| --[innodb-lru-flush-size](../innodb-system-variables/index#innodb_lru_flush_size), [innodb\_lru\_flush\_size](../innodb-system-variables/index#innodb_lru_flush_size) |
| --[innodb-lru-scan-depth](../innodb-system-variables/index#innodb_lru_scan_depth), [innodb\_lru\_scan\_depth](../innodb-system-variables/index#innodb_lru_scan_depth) |
| [Innodb\_lsn\_current](../innodb-status-variables/index#innodb_lsn_current) |
| [Innodb\_lsn\_flushed](../innodb-status-variables/index#innodb_lsn_flushed) |
| [Innodb\_lsn\_last\_checkpoint](../innodb-status-variables/index#innodb_lsn_last_checkpoint) |
| [Innodb\_master\_thread\_1\_second\_loops](../innodb-status-variables/index#innodb_master_thread_1_second_loops) |
| [Innodb\_master\_thread\_10\_second\_loops](../innodb-status-variables/index#innodb_master_thread_10_second_loops) |
| [Innodb\_master\_thread\_active\_loops](../innodb-status-variables/index#innodb_master_thread_active_loops) |
| [Innodb\_master\_thread\_background\_loops](../innodb-status-variables/index#innodb_master_thread_background_loops) |
| [Innodb\_master\_thread\_idle\_loops](../innodb-status-variables/index#innodb_master_thread_idle_loops) |
| [Innodb\_master\_thread\_main\_flush\_loops](../innodb-status-variables/index#innodb_master_thread_main_flush_loops) |
| [Innodb\_master\_thread\_sleeps](../innodb-status-variables/index#innodb_master_thread_sleeps) |
| --[innodb-max-bitmap-file-size](../innodb-system-variables/index#innodb_max_bitmap_file_size), [innodb\_max\_bitmap\_file\_size](../innodb-system-variables/index#innodb_max_bitmap_file_size) |
| --[innodb-max-changed-pages](../innodb-system-variables/index#innodb_max_changed_pages), [innodb\_max\_changed\_pages](../innodb-system-variables/index#innodb_max_changed_pages) |
| --[innodb-max-dirty-pages-pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct), [innodb\_max\_dirty\_pages\_pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct) |
| --[innodb-max-dirty-pages-pct-lwm](../innodb-system-variables/index#innodb_max_dirty_pages_pct_lwm), [innodb\_max\_dirty\_pages\_pct\_lwm](../innodb-system-variables/index#innodb_max_dirty_pages_pct_lwm) |
| --[innodb-max-purge-lag](../innodb-system-variables/index#innodb_max_purge_lag), [innodb\_max\_purge\_lag](../innodb-system-variables/index#innodb_max_purge_lag) |
| --[innodb-max-purge-lag-delay](../innodb-system-variables/index#innodb_max_purge_lag_delay), [innodb\_max\_purge\_lag\_delay](../innodb-system-variables/index#innodb_max_purge_lag_delay) |
| --[innodb-max-purge-lag-wait](../innodb-system-variables/index#innodb_max_purge_lag_wait), [innodb\_max\_purge\_lag\_wait](../innodb-system-variables/index#innodb_max_purge_lag_wait) |
| [Innodb\_max\_trx\_id](../innodb-status-variables/index#innodb_max_trx_id) |
| --[innodb-max-undo-log-size](../innodb-system-variables/index#innodb_max_undo_log_size), [innodb\_max\_undo\_log\_size](../innodb-system-variables/index#innodb_max_undo_log_size) |
| [Innodb\_mem\_adaptive\_hash](../innodb-status-variables/index#innodb_mem_adaptive_hash) |
| [Innodb\_mem\_dictionary](../innodb-status-variables/index#innodb_mem_dictionary) |
| [Innodb\_mem\_total](../innodb-status-variables/index#innodb_mem_total) |
| --[innodb-merge-sort-block-size](../innodb-system-variables/index#innodb_merge_sort_block_size), [innodb\_merge\_sort\_block\_size](../innodb-system-variables/index#innodb_merge_sort_block_size) |
| --[innodb-mirrored-log-groups](../innodb-system-variables/index#innodb_mirrored_log_groups), [innodb\_mirrored\_log\_groups](../innodb-system-variables/index#innodb_mirrored_log_groups) |
| --[innodb-monitor-disable](../innodb-system-variables/index#innodb_monitor_disable), [innodb\_monitor\_disable](../innodb-system-variables/index#innodb_monitor_disable) |
| --[innodb-monitor-enable](../innodb-system-variables/index#innodb_monitor_enable), [innodb\_monitor\_enable](../innodb-system-variables/index#innodb_monitor_enable) |
| --[innodb-monitor-reset](../innodb-system-variables/index#innodb_monitor_reset), [innodb\_monitor\_reset](../innodb-system-variables/index#innodb_monitor_reset) |
| --[innodb-monitor-reset-all](../innodb-system-variables/index#innodb_monitor_reset_all), [innodb\_monitor\_reset\_all](../innodb-system-variables/index#innodb_monitor_reset_all) |
| --[innodb-mtflush-threads](../innodb-system-variables/index#innodb_mtflush_threads), [innodb\_mtflush\_threads](../innodb-system-variables/index#innodb_mtflush_threads) |
| [Innodb\_mutex\_os\_waits](../innodb-status-variables/index#innodb_mutex_os_waits) |
| [Innodb\_mutex\_spin\_rounds](../innodb-status-variables/index#innodb_mutex_spin_rounds) |
| [Innodb\_mutex\_spin\_waits](../innodb-status-variables/index#innodb_mutex_spin_waits) |
| [Innodb\_num\_index\_pages\_written](../innodb-status-variables/index#innodb_num_index_pages_written) |
| [Innodb\_num\_non\_index\_pages\_written](../innodb-status-variables/index#innodb_num_non_index_pages_written) |
| [Innodb\_num\_open\_files](../innodb-status-variables/index#innodb_num_open_files) |
| [Innodb\_num\_page\_compressed\_trim\_op](../innodb-status-variables/index#innodb_num_page_compressed_trim_op) |
| [Innodb\_num\_page\_compressed\_trim\_op\_saved](../innodb-status-variables/index#innodb_num_page_compressed_trim_op_saved) |
| [Innodb\_num\_pages\_encrypted](../innodb-status-variables/index#innodb_num_pages_encrypted) |
| [Innodb\_num\_pages\_page\_compressed](../innodb-status-variables/index#innodb_num_pages_page_compressed) |
| [Innodb\_num\_pages\_page\_compression\_error](../innodb-status-variables/index#innodb_num_pages_page_compression_error) |
| [Innodb\_num\_pages\_page\_decompressed](../innodb-status-variables/index#innodb_num_pages_page_decompressed) |
| [Innodb\_num\_pages\_page\_decrypted](../innodb-status-variables/index#innodb_num_pages_page_decrypted) |
| [Innodb\_num\_pages\_page\_encryption\_error](../innodb-status-variables/index#innodb_num_pages_page_encryption_error) |
| --[innodb-numa-interleave](../innodb-system-variables/index#innodb_numa_interleave), [innodb\_numa\_interleave](../innodb-system-variables/index#innodb_numa_interleave) |
| --[innodb-old-blocks-pct](../innodb-system-variables/index#innodb_old_blocks_pct), [innodb\_old\_blocks\_pct](../innodb-system-variables/index#innodb_old_blocks_pct) |
| --[innodb-old-blocks-time](../innodb-system-variables/index#innodb_old_blocks_time), [innodb\_old\_blocks\_time](../innodb-system-variables/index#innodb_old_blocks_time) |
| [Innodb\_oldest\_view\_low\_limit\_trx\_id](../innodb-status-variables/index#innodb_oldest_view_low_limit_trx_id) |
| --[innodb-online-alter-log-max-size](../innodb-system-variables/index#innodb_online_alter_log_max_size), [innodb\_online\_alter\_log\_max\_size](../innodb-system-variables/index#innodb_online_alter_log_max_size) |
| [Innodb\_onlineddl\_pct\_progress](../innodb-status-variables/index#innodb_onlineddl_pct_progress) |
| [Innodb\_onlineddl\_rowlog\_pct\_used](../innodb-status-variables/index#innodb_onlineddl_rowlog_pct_used) |
| [Innodb\_onlineddl\_rowlog\_rows](../innodb-status-variables/index#innodb_onlineddl_rowlog_rows) |
| --[innodb-open-files](../innodb-system-variables/index#innodb_open_files), [innodb\_open\_files](../innodb-system-variables/index#innodb_open_files) |
| --[innodb-optimize-fulltext-only](../innodb-system-variables/index#innodb_optimize_fulltext_only), [innodb\_optimize\_fulltext\_only](../innodb-system-variables/index#innodb_optimize_fulltext_only) |
| [Innodb\_os\_log\_fsyncs](../innodb-status-variables/index#innodb_os_log_fsyncs) |
| [Innodb\_os\_log\_pending\_fsyncs](../innodb-status-variables/index#innodb_os_log_pending_fsyncs) |
| [Innodb\_os\_log\_pending\_writes](../innodb-status-variables/index#innodb_os_log_pending_writes) |
| [Innodb\_os\_log\_written](../innodb-status-variables/index#innodb_os_log_written) |
| --[innodb-page-cleaners](../innodb-system-variables/index#innodb_page_cleaners), [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) |
| [Innodb\_page\_compression\_saved](../innodb-status-variables/index#innodb_page_compression_saved) |
| [Innodb\_page\_compression\_trim\_sect512](../innodb-status-variables/index#innodb_page_compression_trim_sect512) |
| [Innodb\_page\_compression\_trim\_sect1024](../innodb-status-variables/index#innodb_page_compression_trim_sect1024) |
| [Innodb\_page\_compression\_trim\_sect2048](../innodb-status-variables/index#innodb_page_compression_trim_sect2048) |
| [Innodb\_page\_compression\_trim\_sect4096](../innodb-status-variables/index#innodb_page_compression_trim_sect4096) |
| [Innodb\_page\_compression\_trim\_sect8192](../innodb-status-variables/index#innodb_page_compression_trim_sect8192) |
| [Innodb\_page\_compression\_trim\_sect16384](../innodb-status-variables/index#innodb_page_compression_trim_sect16384) |
| [Innodb\_page\_compression\_trim\_sect32768](../innodb-status-variables/index#innodb_page_compression_trim_sect32768) |
| --[innodb-page-size](../innodb-system-variables/index#innodb_page_size), [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) |
| [Innodb\_page\_size](../innodb-status-variables/index#innodb_page_size) |
| [Innodb\_pages\_created](../innodb-status-variables/index#innodb_pages_created) |
| [Innodb\_pages\_read](../innodb-status-variables/index#innodb_pages_read) |
| [Innodb\_pages0\_read](../innodb-status-variables/index#innodb_pages0_read) |
| [Innodb\_pages\_written](../innodb-status-variables/index#innodb_pages_written) |
| --[innodb-pass-corrupt-table](../innodb-system-variables/index#innodb_pass_corrupt_table), [innodb-pass-corrupt-table](../innodb-system-variables/index#innodb_pass_corrupt_table) |
| --[innodb-prefix-index-cluster-optimization](../innodb-system-variables/index#innodb_prefix_index_cluster_optimization), [innodb\_prefix\_index\_cluster\_optimization](../innodb-system-variables/index#innodb_prefix_index_cluster_optimization) |
| --[innodb-print-all-deadlocks](../innodb-system-variables/index#innodb_print_all_deadlocks), [innodb\_print\_all\_deadlocks](../innodb-system-variables/index#innodb_print_all_deadlocks) |
| --[innodb-purge-batch-size](../innodb-system-variables/index#innodb_purge_batch_size), [innodb\_purge\_batch\_size](../innodb-system-variables/index#innodb_purge_batch_size) |
| --[innodb-purge-rseg-truncate-frequency](../innodb-system-variables/index#innodb_purge_rseg_truncate_frequency), [innodb\_purge\_rseg\_truncate\_frequency](../innodb-system-variables/index#innodb_purge_rseg_truncate_frequency) |
| --[innodb-purge-threads](../innodb-system-variables/index#innodb_purge_threads), [innodb\_purge\_threads](../innodb-system-variables/index#innodb_purge_threads) |
| [Innodb\_purge\_trx\_id](../innodb-status-variables/index#innodb_purge_trx_id) |
| [Innodb\_purge\_undo\_no](../innodb-status-variables/index#innodb_purge_undo_no) |
| --[innodb-random-read-ahead](../innodb-system-variables/index#innodb_random_read_ahead), [innodb\_random\_read\_ahead](../innodb-system-variables/index#innodb_random_read_ahead) |
| --[innodb-read-ahead](../innodb-system-variables/index#innodb_read_ahead), [innodb\_read\_ahead](../innodb-system-variables/index#innodb_read_ahead) |
| --[innodb-read-ahead-threshold](../innodb-system-variables/index#innodb_read_ahead_threshold), [innodb\_read\_ahead\_threshold](../innodb-system-variables/index#innodb_read_ahead_threshold) |
| --[innodb-read-io-threads](../innodb-system-variables/index#innodb_read_io_threads), [innodb\_read\_io\_threads](../innodb-system-variables/index#innodb_read_io_threads) |
| --[innodb-read-only](../innodb-system-variables/index#innodb_read_only), [innodb\_read\_only](../innodb-system-variables/index#innodb_read_only) |
| [Innodb\_read\_views\_memory](../innodb-status-variables/index#innodb_read_views_memory) |
| --[innodb-recovery-stats](../innodb-system-variables/index#innodb_recovery_stats), [innodb\_recovery\_stats](../innodb-system-variables/index#innodb_recovery_stats) |
| --[innodb-recovery-update-relay-log](../innodb-system-variables/index#innodb_recovery_update_relay_log), [innodb-recovery-update-relay-log](../innodb-system-variables/index#innodb_recovery_update_relay_log) |
| --[innodb-replication-delay](../innodb-system-variables/index#innodb_replication_delay), [innodb\_replication\_delay](../innodb-system-variables/index#innodb_replication_delay) |
| --[innodb-rollback-on-timeout](../innodb-system-variables/index#innodb_rollback_on_timeout), [innodb\_rollback\_on\_timeout](../innodb-system-variables/index#innodb_rollback_on_timeout) |
| --[innodb-rollback-segments](../innodb-system-variables/index#innodb_rollback_segments), [innodb\_rollback\_segments](../innodb-system-variables/index#innodb_rollback_segments) |
| [Innodb\_row\_lock\_current\_waits](../innodb-status-variables/index#innodb_row_lock_current_waits) |
| [Innodb\_row\_lock\_numbers](../innodb-status-variables/index#innodb_row_lock_numbers) |
| [Innodb\_row\_lock\_time](../innodb-status-variables/index#innodb_row_lock_time) |
| [Innodb\_row\_lock\_time\_avg](../innodb-status-variables/index#innodb_row_lock_time_avg) |
| [Innodb\_row\_lock\_time\_max](../innodb-status-variables/index#innodb_row_lock_time_max) |
| [Innodb\_row\_lock\_waits](../innodb-status-variables/index#innodb_row_lock_waits) |
| [Innodb\_rows\_deleted](../innodb-status-variables/index#innodb_rows_deleted) |
| [Innodb\_rows\_inserted](../innodb-status-variables/index#innodb_rows_inserted) |
| [Innodb\_rows\_read](../innodb-status-variables/index#innodb_rows_read) |
| [Innodb\_rows\_updated](../innodb-status-variables/index#innodb_rows_updated) |
| --[innodb-rseg](../mysqld-options-full-list/index#-innodb-rseg) |
| [Innodb\_s\_lock\_os\_waits](../innodb-status-variables/index#innodb_s_lock_os_waits) |
| [Innodb\_s\_lock\_spin\_rounds](../innodb-status-variables/index#innodb_s_lock_spin_rounds) |
| [Innodb\_s\_lock\_spin\_waits](../innodb-status-variables/index#innodb_s_lock_spin_waits) |
| --[innodb\_safe\_truncate](../innodb-system-variables/index#innodb_safe_truncate), [innodb\_safe\_truncate](../innodb-system-variables/index#innodb_safe_truncate) |
| --[innodb-sched-priority-cleaner](../innodb-system-variables/index#innodb_sched_priority_cleaner), [innodb\_sched\_priority\_cleaner](../innodb-system-variables/index#innodb_sched_priority_cleaner) |
| [Innodb\_scrub\_background\_page\_reorganizations](../innodb-status-variables/index#innodb_scrub_background_page_reorganizations) |
| [Innodb\_scrub\_background\_page\_split\_failures\_missing\_index](../innodb-status-variables/index#innodb_scrub_background_page_split_failures_missing_index) |
| [Innodb\_scrub\_background\_page\_split\_failures\_out\_of\_filespace](../innodb-status-variables/index#innodb_scrub_background_page_split_failures_out_of_filespace) |
| [Innodb\_scrub\_background\_page\_split\_failures\_underflow](../innodb-status-variables/index#innodb_scrub_background_page_split_failures_underflow) |
| [Innodb\_scrub\_background\_page\_split\_failures\_unknown](../innodb-status-variables/index#innodb_scrub_background_page_split_failures_unknown) |
| [Innodb\_scrub\_background\_page\_splits](../innodb-status-variables/index#innodb_scrub_background_page_splits) |
| --[innodb-scrub-log](../innodb-system-variables/index#innodb_scrub_log), [innodb\_scrub\_log](../innodb-system-variables/index#innodb_scrub_log) |
| [Innodb\_scrub\_log](../innodb-status-variables/index#innodb_scrub_log) |
| --[innodb-scrub-log-interval](../innodb-system-variables/index#innodb_scrub_log_interval), [innodb\_scrub\_log\_interval](../innodb-system-variables/index#innodb_scrub_log_interval) |
| --[innodb-scrub-log-speed](../innodb-system-variables/index#innodb_scrub_log_speed), [innodb\_scrub\_log\_speed](../innodb-system-variables/index#innodb_scrub_log_speed) |
| [Innodb\_secondary\_index\_triggered\_cluster\_reads](../innodb-status-variables/index#innodb_secondary_index_triggered_cluster_reads) |
| [Innodb\_secondary\_index\_triggered\_cluster\_reads\_avoided](../innodb-status-variables/index#innodb_secondary_index_triggered_cluster_reads_avoided) |
| --[innodb-show-locks-held](../innodb-system-variables/index#innodb_show_locks_held), [innodb-show-locks-held](../innodb-system-variables/index#innodb_show_locks_held) |
| --[innodb-show-verbose-locks](../innodb-system-variables/index#innodb_show_verbose_locks), [innodb\_show\_verbose\_locks](../innodb-system-variables/index#innodb_show_verbose_locks) |
| [innodb\_simulate\_comp\_failures](../innodb-system-variables/index#innodb_simulate_comp_failures) |
| --[innodb-sort-buffer-size](../innodb-system-variables/index#innodb_sort_buffer_size), [innodb\_sort\_buffer\_size](../innodb-system-variables/index#innodb_sort_buffer_size) |
| --[innodb-spin-wait-delay](../innodb-system-variables/index#innodb_spin_wait_delay), [innodb\_spin\_wait\_delay](../innodb-system-variables/index#innodb_spin_wait_delay) |
| --[innodb-stats-auto-recalc](../innodb-system-variables/index#innodb_stats_auto_recalc), [innodb\_stats\_auto\_recalc](../innodb-system-variables/index#innodb_stats_auto_recalc) |
| --[innodb-stats-auto-update](../innodb-system-variables/index#innodb_stats_auto_update), [innodb\_stats\_auto\_update](../innodb-system-variables/index#innodb_stats_auto_update) |
| --[innodb-stats-include-delete-marked](../innodb-system-variables/index#innodb_stats_include_delete_marked), [innodb\_stats\_include\_delete\_marked](../innodb-system-variables/index#innodb_stats_include_delete_marked) |
| --[innodb-stats-method](../innodb-system-variables/index#innodb_stats_method), [innodb\_stats\_method](../innodb-system-variables/index#innodb_stats_method) |
| --[innodb-stats-modified-counter](../innodb-system-variables/index#innodb_stats_modified_counter), [innodb\_stats\_modified\_counter](../innodb-system-variables/index#innodb_stats_modified_counter) |
| --[innodb-stats-on-metadata](../innodb-system-variables/index#innodb_stats_on_metadata), [innodb-stats-on-metadata](../innodb-system-variables/index#innodb_stats_on_metadata) |
| --[innodb-stats-persistent](../innodb-system-variables/index#innodb_stats_persistent), [innodb\_stats\_persistent](../innodb-system-variables/index#innodb_stats_persistent) |
| --[innodb-stats-persistent-sample-pages](../innodb-system-variables/index#innodb_stats_persistent_sample_pages), [innodb\_stats\_persistent\_sample\_pages](../innodb-system-variables/index#innodb_stats_persistent_sample_pages) |
| --[innodb-stats-sample-pages](../innodb-system-variables/index#innodb_stats_sample_pages), [innodb\_stats\_sample\_pages](../innodb-system-variables/index#innodb_stats_sample_pages) |
| --[innodb-stats-traditional](../innodb-system-variables/index#innodb_stats_traditional), [innodb\_stats\_traditional](../innodb-system-variables/index#innodb_stats_traditional) |
| --[innodb-stats-transient-sample-pages](../innodb-system-variables/index#innodb_stats_transient_sample_pages), [innodb\_stats\_transient\_sample\_pages](../innodb-system-variables/index#innodb_stats_transient_sample_pages) |
| --[innodb-stats-update-need-lock](../innodb-system-variables/index#innodb_stats_update_need_lock), [innodb\_stats\_update\_need\_lock](../innodb-system-variables/index#innodb_stats_update_need_lock) |
| --[innodb-status-file](../mysqld-options/index#-innodb-status-file) |
| --[innodb-status-output](../innodb-system-variables/index#innodb_status_output), [innodb\_status\_output](../innodb-system-variables/index#innodb_status_output) |
| --[innodb-status-output-locks](../innodb-system-variables/index#innodb_status_output_locks), [innodb\_status\_output\_locks](../innodb-system-variables/index#innodb_status_output_locks) |
| --[innodb-strict-mode](../innodb-system-variables/index#innodb_strict_mode), [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) |
| --[innodb-support-xa](../innodb-system-variables/index#innodb_support_xa), [innodb\_support\_xa](../innodb-system-variables/index#innodb_support_xa) |
| --[innodb-sync-array-size](../innodb-system-variables/index#innodb_sync_array_size), [innodb\_sync\_array\_size](../innodb-system-variables/index#innodb_sync_array_size) |
| --[innodb-sync-spin-loops](../innodb-system-variables/index#innodb_sync_spin_loops), [innodb\_sync\_spin\_loops](../innodb-system-variables/index#innodb_support_xa) |
| --[innodb-sys-indexes](../mysqld-options/index#-innodb-sys-indexes) |
| --[innodb-sys-stats](../mysqld-options/index#-innodb-sys-stats) |
| --[innodb-sys-tables](../mysqld-options/index#-innodb-sys-tables) |
| [Innodb\_system\_rows\_deleted](../innodb-status-variables/index#innodb_system_rows_deleted) |
| [Innodb\_system\_rows\_inserted](../innodb-status-variables/index#innodb_system_rows_inserted) |
| [Innodb\_system\_rows\_read](../innodb-status-variables/index#innodb_system_rows_read) |
| [Innodb\_system\_rows\_updated](../innodb-status-variables/index#innodb_system_rows_updated) |
| --[innodb-table-locks](../innodb-system-variables/index#innodb_table_locks), [innodb\_table\_locks](../innodb-system-variables/index#innodb_table_locks) |
| --[innodb-table-stats](../mysqld-options/index#-innodb-table-stats) |
| --[innodb\_temp\_data\_file\_path](../innodb-system-variables/index#innodb_temp_data_file_path), [innodb\_temp\_data\_file\_path](../innodb-system-variables/index#innodb_temp_data_file_path) |
| --[innodb-thread-concurrency](../innodb-system-variables/index#innodb_thread_concurrency), [innodb\_thread\_concurrency](../innodb-system-variables/index#innodb_thread_concurrency) |
| --[innodb-thread-concurrency-timer-based](../innodb-system-variables/index#innodb_thread_concurrency_timer_based), [innodb\_thread\_concurrency\_timer\_based](../innodb-system-variables/index#innodb_thread_concurrency_timer_based) |
| --[innodb-thread-sleep-delay](../innodb-system-variables/index#innodb_thread_sleep_delay), [innodb\_thread\_sleep\_delay](../innodb-system-variables/index#innodb_thread_sleep_delay) |
| --[innodb-tmpdir](../innodb-system-variables/index#innodb_tmpdir), [innodb\_tmpdir](../innodb-system-variables/index#innodb_tmpdir) |
| --[innodb-track-changed-pages](../innodb-system-variables/index#innodb_track_changed_pages), [innodb\_track\_changed\_pages](../innodb-system-variables/index#innodb_track_changed_pages) |
| --[innodb-track-redo-log-now](../innodb-system-variables/index#innodb_track_redo_log_now), [innodb\_track\_redo\_log\_now](../innodb-system-variables/index#innodb_track_redo_log_now) |
| --[innodb-trx](../mysqld-options/index#-innodb-trx) |
| [Innodb\_truncated\_status\_writes](../innodb-status-variables/index#innodb_truncated_status_writes) |
| --[innodb-undo-directory](../innodb-system-variables/index#innodb_undo_directory), [innodb\_undo\_directory](../innodb-system-variables/index#innodb_undo_directory) |
| --[innodb-undo-log-truncate](../innodb-system-variables/index#innodb_undo_log_truncate), [innodb\_undo\_log\_truncate](../innodb-system-variables/index#innodb_undo_log_truncate) |
| --[innodb-undo-logs](../innodb-system-variables/index#innodb_undo_logs), [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) |
| --[innodb-undo-tablespaces](../innodb-system-variables/index#innodb_undo_tablespaces), [innodb\_undo\_tablespaces](../innodb-system-variables/index#innodb_undo_tablespaces) |
| [Innodb\_undo\_truncations](../innodb-status-variables/index#innodb_undo_truncations) |
| --[innodb-use-atomic-writes](../innodb-system-variables/index#innodb_use_atomic_writes), [innodb\_use\_atomic\_writes](../innodb-system-variables/index#innodb_use_atomic_writes) |
| --[innodb-use-fallocate](../innodb-system-variables/index#innodb_use_fallocate), [innodb\_use\_fallocate](../innodb-system-variables/index#innodb_use_fallocate) |
| --[innodb-use-global-flush-log-at-trx-commit](../innodb-system-variables/index#innodb_use_global_flush_log_at_trx_commit), [innodb\_use\_global\_flush\_log\_at\_trx\_commit](../innodb-system-variables/index#innodb_use_global_flush_log_at_trx_commit) |
| --[innodb-use-mtflush](../innodb-system-variables/index#innodb_use_mtflush), [innodb\_use\_mtflush](../innodb-system-variables/index#innodb_use_mtflush) |
| --[innodb-use-native\_aio](../innodb-system-variables/index#innodb_use_native_aio), [innodb\_use\_native\_aio](../innodb-system-variables/index#innodb_use_native_aio) |
| --[innodb-use-purge-thread](../innodb-system-variables/index#innodb_use_purge_thread), [innodb\_use\_purge\_thread](../innodb-system-variables/index#innodb_use_purge_thread) |
| --[innodb-use-stacktrace](../innodb-system-variables/index#innodb_use_stacktrace), [innodb\_use\_stacktrace](../innodb-system-variables/index#innodb_use_stacktrace) |
| --[innodb-use-sys-malloc](../innodb-system-variables/index#innodb_use_sys_malloc), [innodb\_use\_sys\_malloc](../innodb-system-variables/index#innodb_use_sys_malloc) |
| --[innodb-use-sys-stats-table](../innodb-system-variables/index#innodb_use_sys_stats_table), [innodb\_use\_sys\_stats\_table](../innodb-system-variables/index#innodb_use_sys_stats_table) |
| --[innodb-use-trim](../innodb-system-variables/index#innodb_use_trim), [innodb\_use\_trim](../innodb-system-variables/index#innodb_use_trim) |
| [innodb\_version](../innodb-system-variables/index#innodb_version) |
| --[innodb-write-io-threads](../innodb-system-variables/index#innodb_write_io_threads), [innodb\_write\_io\_threads](../innodb-system-variables/index#innodb_write_io_threads) |
| [Innodb\_x\_lock\_os\_waits](../innodb-status-variables/index#innodb_x_lock_os_waits) |
| [Innodb\_x\_lock\_spin\_rounds](../innodb-status-variables/index#innodb_x_lock_spin_rounds) |
| [Innodb\_x\_lock\_spin\_waits](../innodb-status-variables/index#innodb_x_lock_spin_waits) |
| --[insert\_id](../server-system-variables/index#insert_id) |
| --[install](../mysqld-options/index#-install) |
| --[install-manual](../mysqld-options/index#-install-manual) |
| --[interactive-timeout](../server-system-variables/index#interactive_timeout), [interactive\_timeout](../server-system-variables/index#interactive_timeout) |
| --[join-buffer-size](../server-system-variables/index#join_buffer_size), [join\_buffer\_size](../server-system-variables/index#join_buffer_size) |
| --[join-buffer-space-limit](../server-system-variables/index#join_buffer_space_limit), [join\_buffer\_space\_limit](../server-system-variables/index#join_buffer_space_limit) |
| --[join-cache-level](../server-system-variables/index#join_cache_level), [join\_cache\_level](../server-system-variables/index#join_cache_level) |
| --[keep-files-on-create](../server-system-variables/index#keep_files_on_create), [keep\_files\_on\_create](../server-system-variables/index#keep_files_on_create) |
| [Key\_blocks\_not\_flushed](../server-status-variables/index#key_blocks_not_flushed) |
| [Key\_blocks\_unused](../server-status-variables/index#key_blocks_unused) |
| [Key\_blocks\_used](../server-status-variables/index#key_blocks_used) |
| [Key\_blocks\_warm](../server-status-variables/index#key_blocks_warm) |
| --[key-buffer-size](../myisam-system-variables/index#key_buffer_size), [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) |
| --[key-cache-age-threshold](../myisam-system-variables/index#key_cache_age_threshold), [key\_cache\_age\_threshold](../myisam-system-variables/index#key_cache_age_threshold) |
| --[key-cache-block-size](../myisam-system-variables/index#key_cache_block_size), [key\_cache\_block\_size](../myisam-system-variables/index#key_cache_block_size) |
| --[key-cache-division-limit](../myisam-system-variables/index#key_cache_division_limit), [key\_cache\_division\_limit](../myisam-system-variables/index#key_cache_division_limit) |
| --[key-cache-file-hash-size](../myisam-system-variables/index#key_cache_file_hash_size), [key\_cache\_file\_hash\_size](../myisam-system-variables/index#key_cache_file_hash_size) |
| --[key-cache-segments](../myisam-system-variables/index#key_cache_segments), [key\_cache\_segments](../myisam-system-variables/index#key_cache_segments) |
| [Key\_read\_requests](../server-status-variables/index#key_read_requests) |
| [Key\_reads](../server-status-variables/index#key_reads) |
| [Key\_write\_requests](../server-status-variables/index#key_write_requests) |
| [Key\_writes](../server-status-variables/index#key_writes) |
| -L, --[language](../server-system-variables/index#language), [language](../server-system-variables/index#language) |
| [large\_files\_support](../server-system-variables/index#large_files_support) |
| [large\_page\_size](../server-system-variables/index#large_page_size) |
| --[large-pages](../server-system-variables/index#large_pages), [large\_pages](../server-system-variables/index#large_pages) |
| [last\_gtid](../gtid/index#last_gtid) |
| [last\_insert\_id](../server-system-variables/index#last_insert_id) |
| [Last\_query\_cost](../server-status-variables/index#last_query_cost) |
| --[lc-messages](../server-system-variables/index#lc_messages), [lc\_messages](../server-system-variables/index#lc_messages) |
| --[lc-messages-dir](../server-system-variables/index#lc_messages_dir), [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) |
| --[lc-time-names](../server-system-variables/index#lc_time_names), [lc\_time\_names](../server-system-variables/index#lc_time_names) |
| [license](../server-system-variables/index#license) |
| --[local-infile](../server-system-variables/index#local_infile), [local\_infile](../server-system-variables/index#local_infile) |
| --[lock-wait-timeout](../server-system-variables/index#lock_wait_timeout), [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) |
| [locked\_in\_memory](../server-system-variables/index#locked_in_memory) |
| -l, --[log](../server-system-variables/index#log), [log](../server-system-variables/index#log) |
| --[log-basename](../mysqld-options-full-list/index#-log-basename) |
| --[log-bin](../replication-and-binary-log-server-system-variables/index#log_bin), [log\_bin](../replication-and-binary-log-server-system-variables/index#log_bin) |
| [log\_bin\_basename](../replication-and-binary-log-server-system-variables/index#log_bin_basename) |
| --[log-bin-compress](../replication-and-binary-log-server-system-variables/index#log_bin_compress), [log\_bin\_compress](../replication-and-binary-log-server-system-variables/index#log_bin_compress) |
| --[log-bin-compress-min-len](../replication-and-binary-log-server-system-variables/index#log_bin_compress_min_len), [log\_bin\_compress\_min\_len](../replication-and-binary-log-server-system-variables/index#log_bin_compress_min_len) |
| --[log-bin-index](../replication-and-binary-log-server-system-variables/index#log_bin_index), [log\_bin\_index](../replication-and-binary-log-server-system-variables/index#log_bin_index) |
| --[log-bin-trust-function-creators](../replication-and-binary-log-server-system-variables/index#log_bin_trust_function_creators), [log\_bin\_trust\_function\_creators](../replication-and-binary-log-server-system-variables/index#log_bin_trust_function_creators) |
| --[log-bin-trust-routine-creators](../mysqld-options-full-list/index#-log-bin-trust-routine-creators) |
| --[log-ddl-recovery](../mysqld-options/index#-log-ddl-recovery) |
| --[log-disabled-statements](../server-system-variables/index#log_disabled_statements), [log\_disabled\_statements](../server-system-variables/index#log_disabled_statements) |
| --[log-error](../server-system-variables/index#log_error), [log\_error](../server-system-variables/index#log_error) |
| -0, --[log-long-format](../mysqld-options-full-list/index#-log-long-format) |
| --[log-output](../server-system-variables/index#log_output), [log\_output](../server-system-variables/index#log_output) |
| --[log-queries-not-using-indexes](../server-system-variables/index#log_queries_not_using_indexes), [log\_queries\_not\_using\_indexes](../server-system-variables/index#log_queries_not_using_indexes) |
| --[log-short-format](../mysqld-options-full-list/index#-log-short-format) |
| --[log-slave-updates](../replication-and-binary-log-server-system-variables/index#log_slave_updates), [log\_slave\_updates](../replication-and-binary-log-server-system-variables/index#log_slave_updates) |
| --[log-slow-admin-statements](../server-system-variables/index#log_slow_admin_statements), [log\_slow\_admin\_statements](../server-system-variables/index#log_slow_admin_statements) |
| --[log-slow-disabled-statements](../server-system-variables/index#log_slow_disabled_statements), [log\_slow\_disabled\_statements](../server-system-variables/index#log_slow_disabled_statements) |
| --[log-slow-file](../mysqld-options-full-list/index#-log-slow-file) |
| --[log-slow-filter](../server-system-variables/index#log_slow_filter), [log\_slow\_filter](../server-system-variables/index#log_slow_filter) |
| --[log-slow-min-examined-row-limit](../server-system-variables/index#log_slow_min_examined_row_limit), [log\_slow\_min\_examined\_row\_limit](../server-system-variables/index#log_slow_min_examined_row_limit) |
| --[log-slow-queries](../server-system-variables/index#log_slow_queries), [log\_slow\_queries](../server-system-variables/index#log_slow_queries) |
| --[log-slow-query](../server-system-variables/index#log_slow_query), [log\_slow\_query](../server-system-variables/index#log_slow_query) |
| --[log-slow-query-file](../server-system-variables/index#log_slow_query_file), [log\_slow\_query\_file](../server-system-variables/index#log_slow_query_file) |
| --[log-slow-query-time](../server-system-variables/index#log_slow_query_time), [log\_slow\_query\_time](../server-system-variables/index#log_slow_query_time) |
| --[log-slow-rate-limit](../server-system-variables/index#log_slow_rate_limit), [log\_slow\_rate\_limit](../server-system-variables/index#log_slow_rate_limit) |
| --[log-slow-slave-statements](../replication-and-binary-log-server-system-variables/index#log_slow_slave_statements), [log\_slow\_slave\_statements](../replication-and-binary-log-server-system-variables/index#log_slow_slave_statements) |
| --[log-slow-time](../mysqld-options-full-list/index#-log-slow-time) |
| --[log-slow-verbosity](../server-system-variables/index#log_slow_verbosity), [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity) |
| --[log-tc](../mysqld-options-full-list/index#-log-tc) |
| --[log-tc-size](../server-system-variables/index#log_tc_size), [log\_tc\_size](../server-system-variables/index#log_tc_size) |
| -W, --[log-warnings](../server-system-variables/index#log_warnings), [log\_warnings](../server-system-variables/index#log_warnings) |
| --[long-query-time](../server-system-variables/index#long_query_time), [long\_query\_time](../server-system-variables/index#long_query_time) |
| --[log-isam](../mysqld-options/index#-log-isam) |
| --[low-priority-updates](../server-system-variables/index#low_priority_updates), [low\_priority\_updates](../server-system-variables/index#low_priority_updates) |
| [lower\_case\_file\_system](../server-system-variables/index#lower_case_file_system) |
| --[lower-case-table-names](../server-system-variables/index#lower_case_table_names), [lower\_case\_table\_names](../server-system-variables/index#lower_case_table_names) |
| --[master-connect-retry](../mysqld-options/index#-master-connect-retry) |
| [Master\_gtid\_wait\_count](../replication-and-binary-log-status-variables/index#master_gtid_wait_count) |
| [Master\_gtid\_wait\_time](../replication-and-binary-log-status-variables/index#master_gtid_wait_time) |
| [Master\_gtid\_wait\_timeouts](../replication-and-binary-log-status-variables/index#master_gtid_wait_timeouts) |
| --[master-host](../mysqld-options/index#-master-host) |
| --[master-info-file](../mysqld-options/index#-master-info-file) |
| --[master-password](../mysqld-options/index#-master-password) |
| --[master-port](../mysqld-options/index#-master-port) |
| --[master-retry-count](../mysqld-options/index#-master-retry-count) |
| --[master-ssl](../mysqld-options/index#-master-ssl) |
| --[master-ssl-ca](../mysqld-options/index#-master-ssl-ca) |
| --[master-ssl-capath](../mysqld-options/index#-master-ssl-capath) |
| --[master-ssl-cert](../mysqld-options/index#-master-ssl-cert) |
| --[master-ssl-cipher](../mysqld-options/index#-master-ssl-cipher) |
| --[master-ssl-key](../mysqld-options/index#-master-ssl-key) |
| --[master-user](../mysqld-options/index#-master-user) |
| --[master-verify-checksum](../replication-and-binary-log-server-system-variables/index#master_verify_checksum), [master\_verify\_checksum](../replication-and-binary-log-server-system-variables/index#master_verify_checksum) |
| --[max-allowed-packet](../server-system-variables/index#max_allowed_packet), [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) |
| --[max-binlog-dump-events](../mysqld-options/index#-max-binlog-dump-events) |
| --[max-binlog-cache-size](../server-system-variables/index#max_binlog_cache_size), [max\_binlog\_cache\_size](../server-system-variables/index#max_binlog_cache_size) |
| --[max-binlog-size](../server-system-variables/index#max_binlog_size), [max\_binlog\_size](../server-system-variables/index#max_binlog_size) |
| --[max-binlog-stmt-cache-size](../server-system-variables/index#max_binlog_stmt_cache_size), [max\_binlog\_stmt\_cache\_size](../server-system-variables/index#max_binlog_stmt_cache_size) |
| --[max-connect-errors](../server-system-variables/index#max_connect_errors), [max\_connect\_errors](../server-system-variables/index#max_connect_errors) |
| --[max-connections](../server-system-variables/index#max_connections), [max\_connections](../server-system-variables/index#max_connections) |
| --[max-delayed-threads](../server-system-variables/index#max_delayed_threads), [max\_delayed\_threads](../server-system-variables/index#max_delayed_threads) |
| --[max-digest-length](../server-system-variables/index#max_digest_length), [max\_digest\_length](../server-system-variables/index#max_digest_length) |
| --[max-error-count](../server-system-variables/index#max_error_count), [max\_error\_count](../server-system-variables/index#max_error_count) |
| --[max-heap-table-size](../server-system-variables/index#max_heap_table_size), [max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size) |
| [max\_insert\_delayed\_threads](../server-system-variables/index#max_insert_delayed_threads) |
| --[max-join-size](../server-system-variables/index#max_join_size), [max\_join\_size](../server-system-variables/index#max_join_size) |
| --[max-length-for-sort-data](../server-system-variables/index#max_length_for_sort_data), [max\_length\_for\_sort\_data](../server-system-variables/index#max_length_for_sort_data) |
| --[max-long-data-size](../server-system-variables/index#max_long_data_size), [max\_long\_data\_size](../server-system-variables/index#max_long_data_size) |
| --[max-prepared-stmt-count](../server-system-variables/index#max_prepared_stmt_count), [max\_prepared\_stmt\_count](../server-system-variables/index#max_prepared_stmt_count) |
| --[max-password-errors](../server-system-variables/index#max_password_errors), [max\_password\_errors](../server-system-variables/index#max_password_errors) |
| --[max-recursive-iterations](../server-system-variables/index#max_recursive_iterations), [max\_recursive\_iterations](../server-system-variables/index#max_recursive_iterations) |
| --[max-relay-log-size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size), [max\_relay\_log\_size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size) |
| --[max-rowid-filter-size](../server-system-variables/index#max_rowid_filter_size), [max\_rowid\_filter\_size](../server-system-variables/index#max_rowid_filter_size) |
| --[max-seeks-for-key](../server-system-variables/index#max_seeks_for_key), [max\_seeks\_for\_key](../server-system-variables/index#max_seeks_for_key) |
| --[max-session-mem-used](../server-system-variables/index#max_session_mem_used), [max\_session\_mem\_used](../server-system-variables/index#max_session_mem_used) |
| --[max-sort-length](../server-system-variables/index#max_sort_length), [max\_sort\_length](../server-system-variables/index#max_sort_length) |
| --[max-sp-recursion-depth](../server-system-variables/index#max_sp_recursion_depth), [max\_sp\_recursion\_depth](../server-system-variables/index#max_sp_recursion_depth) |
| --[max-statement-time](../server-system-variables/index#max_statement_time), [max\_statement\_time](../server-system-variables/index#max_statement_time) |
| [Max\_statement\_time\_exceeded](../server-status-variables/index#max_statement_time_exceeded) |
| --[max-tmp-tables](../server-system-variables/index#max_tmp_tables), [max\_tmp\_tables](../server-system-variables/index#max_tmp_tables) |
| [Max\_used\_connection\_time](../server-status-variables/index#max_used_connection_time) |
| [Max\_used\_connections](../server-status-variables/index#max_used_connections) |
| --[max-user-connections](../server-system-variables/index#max_user_connections), [max\_user\_connections](../server-system-variables/index#max_user_connections) |
| --[max-write-lock-count](../server-system-variables/index#max_write_lock_count), [max\_write\_lock\_count](../server-system-variables/index#max_write_lock_count) |
| --[memlock](../mysqld-options/index#-memlock) |
| [Memory\_used](../server-status-variables/index#memory_used) |
| [Memory\_used\_initial](../server-status-variables/index#memory_used_initial) |
| --[metadata-locks-cache-size](../server-system-variables/index#metadata_locks_cache_size), [metadata\_locks\_cache\_size](../server-system-variables/index#metadata_locks_cache_size) |
| --[metadata-locks-hash-instances](../server-system-variables/index#metadata_locks_hash_instances), [metadata\_locks\_hash\_instances](../server-system-variables/index#metadata_locks_hash_instances) |
| --[min-examined-row-limit](../server-system-variables/index#min_examined_row_limit), [min-examined-row-limit](../server-system-variables/index#min_examined_row_limit) |
| [mroonga\_action\_on\_fulltext\_query\_error](../mroonga-system-variables/index#mroonga_action_on_fulltext_query_error) |
| [mroonga\_boolean\_mode\_syntax\_flags](../mroonga-system-variables/index#mroonga_boolean_mode_syntax_flags) |
| [Mroonga\_count\_skip](../mroonga-status-variables/index#mroonga_count_skip) |
| [mroonga\_database\_path\_prefix](../mroonga-system-variables/index#mroonga_database_path_prefix) |
| [mroonga\_default\_parser](../mroonga-system-variables/index#mroonga_default_parser) |
| [mroonga\_default\_tokenizer](../mroonga-system-variables/index#mroonga_default_tokenizer) |
| [mroonga\_default\_wrapper\_engine](../mroonga-system-variables/index#mroonga_default_wrapper_engine) |
| [mroonga\_dry\_write](../mroonga-system-variables/index#mroonga_dry_write) |
| [mroonga\_enable\_operations\_recording](../mroonga-system-variables/index#mroonga_enable_operations_recording) |
| [mroonga\_enable\_optimization](../mroonga-system-variables/index#mroonga_enable_optimization) |
| [Mroonga\_fast\_order\_limit](../mroonga-status-variables/index#mroonga_fast_order_limit) |
| [mroonga\_libgroonga\_embedded](../mroonga-system-variables/index#mroonga_libgroonga_embedded) |
| [mroonga\_libgroonga\_support\_zlib](../mroonga-system-variables/index#mroonga_libgroonga_support_zlib) |
| [mroonga\_libgroonga\_support\_zstd](../mroonga-system-variables/index#mroonga_libgroonga_support_zstd) |
| [mroonga\_libgroonga\_version](../mroonga-system-variables/index#mroonga_libgroonga_version) |
| [mroonga\_log\_file](../mroonga-system-variables/index#mroonga_log_file) |
| [mroonga\_log\_level](../mroonga-system-variables/index#mroonga_log_level) |
| [mroonga\_match\_escalation\_threshold](../mroonga-system-variables/index#mroonga_match_escalation_threshold) |
| [mroonga\_max\_n\_records\_for\_estimate](../mroonga-system-variables/index#mroonga_max_n_records_for_estimate) |
| [mroonga\_query\_log\_file](../mroonga-system-variables/index#mroonga_query_log_file) |
| [mroonga\_vector\_column\_delimiter](../mroonga-system-variables/index#mroonga_vector_column_delimiter) |
| [mroonga\_version](../mroonga-system-variables/index#mroonga_version) |
| --[mrr-buffer-size](../server-system-variables/index#mrr_buffer_size), [mrr\_buffer\_size](../server-system-variables/index#mrr_buffer_size) |
| --[multi-range-count](../server-system-variables/index#multi_range_count), [multi\_range\_count](../server-system-variables/index#multi_range_count) |
| --[myisam-block-size](../myisam-server-system-variables/index#myisam_block_size), [myisam\_block\_size](../myisam-server-system-variables/index#myisam_block_size) |
| --[myisam-data-pointer-size](../myisam-server-system-variables/index#myisam_data_pointer_size), [myisam\_data\_pointer\_size](../myisam-server-system-variables/index#myisam_data_pointer_size) |
| --[myisam-max-extra-sort-file-size](../myisam-server-system-variables/index#myisam_max_extra_sort_file_size), [myisam\_max\_extra\_sort\_file\_size](../myisam-server-system-variables/index#myisam_max_extra_sort_file_size) |
| --[myisam-max-sort-file-size](../myisam-server-system-variables/index#myisam_max_sort_file_size), [myisam\_max\_sort\_file\_size](../myisam-server-system-variables/index#myisam_max_sort_file_size) |
| --[myisam-mmap-size](../myisam-server-system-variables/index#myisam_mmap_size), [myisam\_mmap\_size](../myisam-server-system-variables/index#myisam_mmap_size) |
| --[myisam-recover-options](../myisam-server-system-variables/index#myisam_recover_options), [myisam\_recover\_options](../myisam-server-system-variables/index#myisam_recover_options) |
| --[myisam-repair-threads](../myisam-server-system-variables/index#myisam_repair_threads), [myisam\_repair\_threads](../myisam-server-system-variables/index#myisam_repair_threads) |
| --[myisam-sort-buffer-size](../myisam-server-system-variables/index#myisam_sort_buffer_size), [myisam\_sort\_buffer\_size](../myisam-server-system-variables/index#myisam_sort_buffer_size) |
| --[myisam-stats-method](../myisam-server-system-variables/index#myisam_stats_method), [myisam\_stats\_method](../myisam-server-system-variables/index#myisam_stats_method) |
| --[myisam-use-mmap](../myisam-server-system-variables/index#myisam_use_mmap), [myisam\_use\_mmap](../myisam-server-system-variables/index#myisam_use_mmap) |
| --[mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format), [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) |
| --[named-pipe](../server-system-variables/index#named_pipe), [named\_pipe](../server-system-variables/index#named_pipe) |
| --[ndb-use-copying-alter-table](../mysqld-options/index#-ndb-use-copying-alter-table) |
| --[net-buffer-length](../server-system-variables/index#net_buffer_length), [net\_buffer\_length](../server-system-variables/index#net_buffer_length) |
| --[net-read-timeout](../server-system-variables/index#net_read_timeout), [net\_read\_timeout](../server-system-variables/index#net_read_timeout) |
| --[net-retry-count](../server-system-variables/index#net_retry_count), [net\_retry\_count](../server-system-variables/index#net_retry_count) |
| --[net-write-timeout](../server-system-variables/index#net_write_timeout), [net\_write\_timeout](../server-system-variables/index#net_write_timeout) |
| [Not\_flushed\_delayed\_rows](../server-status-variables/index#not_flushed_delayed_rows) |
| --[new](../mysqld-options/index#-new) |
| --[old](../server-system-variables/index#old), [old](../server-system-variables/index#old) |
| --[old-alter-table](../server-system-variables/index#old_alter_table), [old\_alter\_table](../server-system-variables/index#old_alter_table) |
| --[old-mode](../server-system-variables/index#old_mode), [old\_mode](../server-system-variables/index#old_mode) |
| --[old-passwords](../server-system-variables/index#old_passwords), [old\_passwords](../server-system-variables/index#old_passwords) |
| --[old-style-user-limits](../mysqld-options/index#-old-style-user-limits) |
| --[one-thread](../mysqld-options/index#-one-thread) |
| [Open\_files](../server-status-variables/index#open_files) |
| --[open-files-limit](../server-system-variables/index#open_files_limit), [open\_files\_limit](../server-system-variables/index#open_files_limit) |
| [Open\_streams](../server-status-variables/index#open_streams) |
| [Open\_table\_definitions](../server-status-variables/index#open_table_definitions) |
| [Open\_tables](../server-status-variables/index#open_tables) |
| [Opened\_files](../server-status-variables/index#opened_files) |
| [Opened\_plugin\_libraries](../server-status-variables/index#opened_plugin_libraries) |
| [Opened\_table\_definitions](../server-status-variables/index#opened_table_definitions) |
| [Opened\_tables](../server-status-variables/index#opened_tables) |
| [Opened\_views](../server-status-variables/index#opened_views) |
| --[optimizer-extra-pruning-depth](../server-system-variables/index#optimizer_extra_pruning_depth) , [optimizer\_extra\_pruning\_depth](../server-system-variables/index#optimizer_extra_pruning_depth) |
| --[optimizer-max-sel-arg-weight](../server-system-variables/index#optimizer_max_sel_arg_weight) , [optimizer\_max\_sel\_arg\_weight](../server-system-variables/index#optimizer_max_sel_arg_weight) |
| --[optimizer-prune-level](../server-system-variables/index#optimizer_prune_level) , [optimizer\_prune\_level](../server-system-variables/index#optimizer_prune_level) |
| --[optimizer-search-depth](../server-system-variables/index#optimizer_search_depth), [optimizer\_search\_depth](../server-system-variables/index#optimizer_search_depth) |
| --[optimizer-selectivity-sampling-limit](../server-system-variables/index#optimizer_selectivity_sampling_limit), [optimizer\_selectivity\_sampling\_limit](../server-system-variables/index#optimizer_selectivity_sampling_limit) |
| --[optimizer-switch](../server-system-variables/index#optimizer_switch), [optimizer\_switch](../server-system-variables/index#optimizer_switch) |
| --[optimizer-trace](../server-system-variables/index#optimizer_trace), [optimizer\_trace](../server-system-variables/index#optimizer_trace) |
| --[optimizer-trace-max-mem-size](../server-system-variables/index#optimizer_trace_max_mem_size), [optimizer\_trace\_max\_mem\_size](../server-system-variables/index#optimizer_trace_max_mem_size) |
| --[optimizer-use-condition-selectivity](../server-system-variables/index#optimizer_use_condition_selectivity), [optimizer\_use\_condition\_selectivity](../server-system-variables/index#optimizer_use_condition_selectivity) |
| [oqgraph\_allow\_create\_integer\_latch](../oqgraph-system-and-status-variables/index#oqgraph_allow_create_integer_latch) |
| [Oqgraph\_boost\_version](../oqgraph-status-variables/index#oqgraph_boost_version) |
| [Oqgraph\_compat\_mode](../oqgraph-status-variables/index#oqgraph_compat_mode) |
| [Oqgraph\_verbose\_debug](../oqgraph-status-variables/index#oqgraph_verbose_debug) |
| --[pam-debug](../authentication-plugin-pam/index#pam_debug), [pam\_debug](../authentication-plugin-pam/index#pam_debug) |
| -P, --[port](../server-system-variables/index#port), [port](../server-system-variables/index#port) |
| --[pam-use-cleartext-plugin](../authentication-plugin-pam/index#pam_use_cleartext_plugin), [pam\_use\_cleartext\_plugin](../authentication-plugin-pam/index#pam_use_cleartext_plugin) |
| --[pam-windbind-workaround](../authentication-plugin-pam/index#pam_winbind_workaround), [pam\_windbind\_workaround](../authentication-plugin-pam/index#pam_winbind_workaround) |
| --[password-reuse-check-interval](../password_reuse_check_interval/index), [password\_reuse\_check\_interval](../password_reuse_check_interval/index) |
| --pbxt |
| --[pbxt-auto-increment-mode](../pbxt-system-variables/index#pbxt_auto_increment_mode) |
| --[pbxt-checkpoint-frequency](../pbxt-system-variables/index#pbxt_checkpoint_frequency) |
| --[pbxt-data-file-grow-size](../pbxt-system-variables/index#pbxt_data_file_grow_size) |
| --[pbxt-data-log-threshold](../pbxt-system-variables/index#pbxt_data_log_threshold) |
| --[pbxt-flush-log-at-trx-commit](../pbxt-system-variables/index#pbxt_flush_log_at_trx_commit) |
| --[pbxt-garbage-threshold](../pbxt-system-variables/index#pbxt_garbage_threshold) |
| --[pbxt-index-cache-size](../pbxt-system-variables/index#pbxt_index_cache_size) |
| --[pbxt-log-buffer-size](../pbxt-system-variables/index#pbxt_log_buffer_size) |
| --[pbxt-log-cache-size](../pbxt-system-variables/index#pbxt_log_cache_size) |
| --[pbxt-log-file-count](../pbxt-system-variables/index#pbxt_log_file_count) |
| --[pbxt-log-file-threshold](../pbxt-system-variables/index#pbxt_log_file_threshold) |
| --[pbxt-max-threads](../pbxt-system-variables/index#options-for-pbxt) |
| --[pbxt-offline-log-function](../pbxt-system-variables/index#pbxt_offline_log_function) |
| --[pbxt-record-cache-size](../pbxt-system-variables/index#pbxt_record_cache_size) |
| --[pbxt-row-file-grow-size](../pbxt-system-variables/index#pbxt_row_file_grow_size) |
| --[pbxt-statistics](../pbxt-system-variables/index#options-for-pbxt) |
| --[pbxt-sweeper-priority](../pbxt-system-variables/index#pbxt_sweeper_priority) |
| --[pbxt-support-xa](../pbxt-system-variables/index#pbxt_support_xa) |
| --[pbxt-transaction-buffer-size](../pbxt-system-variables/index#pbxt_transaction_buffer_size) |
| --[performance-schema](../performance-schema-system-variables/index#performance_schema), [performance\_schema](../performance-schema-system-variables/index#performance_schema) |
| [Performance\_schema\_accounts\_lost](../performance-schema-status-variables/index#performance_schema_accounts_lost) |
| --[performance-schema-accounts-size](../performance-schema-system-variables/index#performance_schema_accounts_size), [performance\_schema\_accounts\_size](../performance-schema-system-variables/index#performance_schema_accounts_size) |
| [Performance\_schema\_cond\_classes\_lost](../performance-schema-status-variables/index#performance_schema_cond_classes_lost) |
| [Performance\_schema\_cond\_instances\_lost](../performance-schema-status-variables/index#performance_schema_cond_instances_lost) |
| [--performance-schema-consumer-events-stages-current](../mysqld-options/index#-performance-schema-consumer-events-stages-current) |
| [--performance-schema-consumer-events-stages-history](../mysqld-options/index#-performance-schema-consumer-events-stages-history) |
| [--performance-schema-consumer-events-stages-history-long](../mysqld-options/index#-performance-schema-consumer-events-stages-history-long) |
| [--performance-schema-consumer-events-statements-current](../mysqld-options/index#-performance-schema-consumer-events-statements-current) |
| [--performance-schema-consumer-events-statements-history](../mysqld-options/index#-performance-schema-consumer-events-statements-history) |
| [--performance-schema-consumer-events-statements-history-long](../mysqld-options/index#-performance-schema-consumer-events-statements-history-long) |
| [--performance-schema-consumer-events-waits-current](../mysqld-options/index#-performance-schema-consumer-events-waits-current) |
| [--performance-schema-consumer-events-waits-history](../mysqld-options/index#-performance-schema-consumer-events-waits-history) |
| [--performance-schema-consumer-events-waits-history-long](../mysqld-options/index#-performance-schema-consumer-events-waits-history-long) |
| [--performance-schema-consumer-global-instrumentation](../mysqld-options/index#-performance-schema-consumer-global-instrumentation) |
| [--performance-schema-consumer-statements-digest](../mysqld-options/index#-performance-schema-consumer-statements-digest) |
| [--performance-schema-consumer-thread-instrumentation](../mysqld-options/index#-performance-schema-consumer-thread-instrumentation) |
| [Performance\_schema\_digest\_lost](../performance-schema-status-variables/index#performance_schema_digest_lost) |
| --[performance-schema-digests-size](../performance-schema-system-variables/index#performance_schema_digests_size), [performance\_schema\_digests\_size](../performance-schema-system-variables/index#performance_schema_digests_size) |
| --[performance-schema-events-stages-history-long-size](../performance-schema-system-variables/index#performance_schema_events_stages_history_long_size), [performance\_schema\_events\_stages\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_long_size) |
| --[performance-schema-events-stages-history-size](../performance-schema-system-variables/index#performance_schema_events_stages_history_size), [performance\_schema\_events\_stages\_history\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_size) |
| --[performance-schema-events-statements-history-long-size](../performance-schema-system-variables/index#performance_schema_events_statements_history_long_size), [performance\_schema\_events\_statements\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_long_size) |
| --[performance-schema-events-statements-history-size](../performance-schema-system-variables/index#performance_schema_events_statements_history_size), [performance\_schema\_events\_statements\_history\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_size) |
| --[performance-schema-events-transactions-history-long-size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_long_size), [performance\_schema\_events\_transactions\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_long_size) |
| --[performance-schema-events-transactions-history-size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_size), [performance\_schema\_events\_transactions\_history\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_size) |
| --[performance-schema-events-waits-history-long-size](../performance-schema-system-variables/index#performance_schema_events_waits_history_long_size), [performance\_schema\_events\_waits\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_waits_history_long_size) |
| --[performance-schema-events-waits-history-size](../performance-schema-system-variables/index#performance_schema_events_waits_history_size), [performance\_schema\_events\_waits\_history\_size](../performance-schema-system-variables/index#performance_schema_events_waits_history_size) |
| [Performance\_schema\_file\_classes\_lost](../performance-schema-status-variables/index#performance_schema_file_classes_lost) |
| [Performance\_schema\_file\_handles\_lost](../performance-schema-status-variables/index#performance_schema_file_handles_lost) |
| [Performance\_schema\_file\_instances\_lost](../performance-schema-status-variables/index#performance_schema_file_instances_lost) |
| [Performance\_schema\_hosts\_lost](../performance-schema-status-variables/index#performance_schema_accounts_lost) |
| --[performance-schema-hosts-size](../performance-schema-system-variables/index#performance_schema_hosts_size), [performance\_schema\_hosts\_size](../performance-schema-system-variables/index#performance_schema_hosts_size) |
| [Performance\_schema\_locker\_lost](../performance-schema-status-variables/index#performance_schema_locker_lost) |
| [Performance\_schema\_index\_stat\_lost](../performance-schema-status-variables/index#performance_schema_index_stat_lost) |
| --[performance-schema-max-cond-classes](../performance-schema-system-variables/index#performance_schema_max_cond_classes), [performance\_schema\_max\_cond\_classes](../performance-schema-system-variables/index#performance_schema_max_cond_classes) |
| --[performance-schema-max-cond-instances](../performance-schema-system-variables/index#performance_schema_max_cond_instances), [performance\_schema\_max\_cond\_instances](../performance-schema-system-variables/index#performance_schema_max_cond_instances) |
| --[performance-schema-max-digest-length](../performance-schema-system-variables/index#performance_schema_max_digest_length), [performance\_schema\_max\_digest\_length](../performance-schema-system-variables/index#performance_schema_max_digest_length) |
| --[performance-schema-max-file-classes](../performance-schema-system-variables/index#performance_schema_max_file_classes), [performance\_schema\_max\_file\_classes](../performance-schema-system-variables/index#performance_schema_max_file_classes) |
| --[performance-schema-max-file-handles](../performance-schema-system-variables/index#performance_schema_max_file_handles), [performance\_schema\_max\_file\_handles](../performance-schema-system-variables/index#performance_schema_max_file_handles) |
| --[performance-schema-max-file-instances](../performance-schema-system-variables/index#performance_schema_max_file_instances), [performance\_schema\_max\_file\_instances](../performance-schema-system-variables/index#performance_schema_max_file_instances) |
| --[performance-schema-max-index-stat](../performance-schema-system-variables/index#performance_schema_max_index_stat), [performance\_schema\_max\_index\_stat](../performance-schema-system-variables/index#performance_schema_max_index_stat) |
| --[performance-schema-max-memory-classes](../performance-schema-system-variables/index#performance_schema_max_memory_classes), [performance\_schema\_max\_memory\_classes](../performance-schema-system-variables/index#performance_schema_max_memory_classes) |
| --[performance-schema-max-metadata-locks](../performance-schema-system-variables/index#performance_schema_max_metadata_locks), [performance\_schema\_max\_metadata\_locks](../performance-schema-system-variables/index#performance_schema_max_metadata_locks) |
| --[performance-schema-max-mutex-classes](../performance-schema-system-variables/index#performance_schema_max_mutex_classes), [performance\_schema\_max\_mutex\_classes](../performance-schema-system-variables/index#performance_schema_max_mutex_classes) |
| --[performance-schema-max-mutex-instances](../performance-schema-system-variables/index#performance_schema_max_mutex_instances), [performance\_schema\_max\_mutex\_instances](../performance-schema-system-variables/index#performance_schema_max_mutex_instances) |
| --[performance-schema-max-prepared-statement-instances](../performance-schema-system-variables/index#performance_schema_max_prepared_statement_instances), [performance\_schema\_max\_prepared\_statement\_instances](../performance-schema-system-variables/index#performance_schema_max_prepared_statement_instances) |
| --[performance-schema-max-program-instances](../performance-schema-system-variables/index#performance_schema_max_program_instances), [performance\_schema\_max\_program\_instances](../performance-schema-system-variables/index#performance_schema_max_program_instances) |
| --[performance-schema-max-sql-text-length](../performance-schema-system-variables/index#performance_schema_max_sql_text_length), [performance\_schema\_max\_sql\_text\_length](../performance-schema-system-variables/index#performance_schema_max_sql_text_length) |
| --[performance-schema-max-rwlock-classes](../performance-schema-system-variables/index#performance_schema_max_rwlock_classes), [performance\_schema\_max\_rwlock\_classes](../performance-schema-system-variables/index#performance_schema_max_rwlock_classes) |
| --[performance-schema-max-rwlock-instances](../performance-schema-system-variables/index#performance_schema_max_rwlock_instances), [performance\_schema\_max\_rwlock\_instances](../performance-schema-system-variables/index#performance_schema_max_rwlock_instances) |
| --[performance-schema-max-socket-classes](../performance-schema-system-variables/index#performance_schema_max_socket_classes), [performance\_schema\_max\_socket\_classes](../performance-schema-system-variables/index#performance_schema_max_socket_classes) |
| --[performance-schema-max-socket-instances](../performance-schema-system-variables/index#performance_schema_max_socket_instances), [performance\_schema\_max\_socket\_instances](../performance-schema-system-variables/index#performance_schema_max_socket_instances) |
| --[performance-schema-max-stage-classes](../performance-schema-system-variables/index#performance_schema_max_stage_classes), [performance\_schema\_max\_stage\_classes](../performance-schema-system-variables/index#performance_schema_max_stage_classes) |
| --[performance-schema-max-statement-classes](../performance-schema-system-variables/index#performance_schema_max_statement_classes), [performance\_schema\_max\_statement\_classes](../performance-schema-system-variables/index#performance_schema_max_statement_classes) |
| --[performance-schema-max-statement-stack](../performance-schema-system-variables/index#performance_schema_max_statement_stack), [performance\_schema\_max\_statement\_stack](../performance-schema-system-variables/index#performance_schema_max_statement_stack) |
| --[performance-schema-max-table-handles](../performance-schema-system-variables/index#performance_schema_max_table_handles), [performance\_schema\_max\_table\_handles](../performance-schema-system-variables/index#performance_schema_max_table_handles) |
| --[performance-schema-max-table-instances](../performance-schema-system-variables/index#performance_schema_max_table_instances), [performance\_schema\_max\_table\_instances](../performance-schema-system-variables/index#performance_schema_max_table_instances) |
| --[performance-schema-max-table-lock-stat](../performance-schema-system-variables/index#performance_schema_max_table_lock_stat), [performance\_schema\_max\_table\_lock\_stat](../performance-schema-system-variables/index#performance_schema_max_table_lock_stat) |
| --[performance-schema-max-thread-classes](../performance-schema-system-variables/index#performance_schema_max_thread_classes), [performance\_schema\_max\_thread\_classes](../performance-schema-system-variables/index#performance_schema_max_thread_classes) |
| --[performance-schema-max-thread-instances](../performance-schema-system-variables/index#performance_schema_max_thread_instances), [performance\_schema\_max\_thread\_instances](../performance-schema-system-variables/index#performance_schema_max_thread_instances) |
| [Performance\_schema\_memory\_classes\_lost](../performance-schema-status-variables/index#performance_schema_memory_classes_lost) |
| [Performance\_schema\_metadata\_lock\_lost](../performance-schema-status-variables/index#performance_schema_metadata_lock_lost) |
| [Performance\_schema\_mutex\_classes\_lost](../performance-schema-status-variables/index#performance_schema_mutex_classes_lost) |
| [Performance\_schema\_mutex\_instances\_lost](../performance-schema-status-variables/index#performance_schema_mutex_instances_lost) |
| [Performance\_schema\_nested\_statement\_lost](../performance-schema-status-variables/index#performance_schema_nested_statement_lost) |
| [Performance\_schema\_prepared\_statements\_lost](../performance-schema-status-variables/index#performance_schema_prepared_statements_lost) |
| [Performance\_schema\_program\_lost](../performance-schema-status-variables/index#performance_schema_program_lost) |
| [Performance\_schema\_rwlock\_classes\_lost](../performance-schema-status-variables/index#performance_schema_rwlock_classes_lost) |
| [Performance\_schema\_rwlock\_instances\_lost](../performance-schema-status-variables/index#performance_schema_rwlock_instances_lost) |
| [Performance\_schema\_session\_connect\_attrs\_lost](../performance-schema-status-variables/index#performance_schema_session_connect_attrs_lost) |
| [Performance\_schema\_socket\_classes\_lost](../performance-schema-status-variables/index#performance_schema_socket_classes_lost) |
| [Performance\_schema\_socket\_instances\_lost](../performance-schema-status-variables/index#performance_schema_socket_instances_lost) |
| [Performance\_schema\_stage\_classes\_lost](../performance-schema-status-variables/index#performance_schema_stage_classes_lost) |
| [Performance\_schema\_stage\_classes\_lost](../performance-schema-status-variables/index#performance_schema_stage_classes_lost) |
| [Performance\_schema\_statement\_classes\_lost](../performance-schema-status-variables/index#performance_schema_statement_classes_lost) |
| --[performance-schema-session-connect-attrs-size](../performance-schema-system-variables/index#performance_schema_session_connect_attrs_size), [performance\_schema\_session\_connect\_attrs\_size](../performance-schema-system-variables/index#performance_schema_session_connect_attrs_size) |
| --[performance-schema-setup-actors-size](../performance-schema-system-variables/index#performance_schema_setup_actors_size), [performance\_schema\_setup\_actors\_size](../performance-schema-system-variables/index#performance_schema_setup_actors_size) |
| --[performance-schema-setup-objects-size](../performance-schema-system-variables/index#performance_schema_setup_objects_size), [performance\_schema\_setup\_objects\_size](../performance-schema-system-variables/index#performance_schema_setup_objects_size) |
| [Performance\_schema\_table\_handles\_lost](../performance-schema-status-variables/index#performance_schema_table_handles_lost) |
| [Performance\_schema\_table\_instances\_lost](../performance-schema-status-variables/index#performance_schema_table_instances_lost) |
| [Performance\_schema\_table\_lock\_stat\_lost](../performance-schema-status-variables/index#performance_schema_table_lock_stat_lost) |
| [Performance\_schema\_thread\_classes\_lost](../performance-schema-status-variables/index#performance_schema_thread_classes_lost) |
| [Performance\_schema\_thread\_instances\_lost](../performance-schema-status-variables/index#performance_schema_thread_instances_lost) |
| [Performance\_schema\_schema\_users\_lost](../performance-schema-status-variables/index#performance_schema_schema_users_lost) |
| --[performance\_schema\_users\_size](../performance-schema-system-variables/index#performance_schema_users_size), [performance\_schema\_users\_size](../performance-schema-system-variables/index#performance-schema-users-size) |
| --[pid-file](../server-system-variables/index#pid_file), [pid\_file](../server-system-variables/index#pid_file) |
| --[plugin-load](../mysqld-options/index#-plugin-load) |
| --[plugin-load-add](../mysqld-options/index#-plugin-load-add) |
| --[plugin-dir](../server-system-variables/index#plugin_dir), [plugin\_dir](../server-system-variables/index#plugin_dir) |
| --[plugin-maturity](../server-system-variables/index#plugin_maturity), [plugin\_maturity](../server-system-variables/index#plugin_maturity) |
| -P, --[port](../server-system-variables/index#port), [port](../server-system-variables/index#port) |
| --[port-open-timeout](../mysqld-options/index#-port-open-timeout) |
| --[preload-buffer-size](../server-system-variables/index#preload_buffer_size), [preload\_buffer\_size](../server-system-variables/index#preload_buffer_size) |
| [Prepared\_stmt\_count](../server-status-variables/index#prepared_stmt_count) |
| [profiling](../server-system-variables/index#profiling) |
| --[profiling-history-size](../server-system-variables/index#profiling_history_size), [profiling\_history\_size](../server-system-variables/index#profiling_history_size) |
| --[progress-report-time](../server-system-variables/index#progress_report_time), [progress\_report\_time](../server-system-variables/index#progress_report_time) |
| [protocol\_version](../server-system-variables/index#protocol_version) |
| --[proxy-protocol-networks](../server-system-variables/index#proxy_protocol_networks), [proxy\_protocol\_networks](../server-system-variables/index#proxy_protocol_networks) |
| [proxy\_user](../server-system-variables/index#proxy_user) |
| [pseudo\_slave\_mode](../server-system-variables/index#pseudo_slave_mode) |
| [pseudo\_thread\_id](../server-system-variables/index#pseudo_thread_id) |
| [Qcache\_free\_blocks](../server-status-variables/index#qcache_free_blocks) |
| [Qcache\_free\_memory](../server-status-variables/index#qcache_free_memory) |
| [Qcache\_hits](../server-status-variables/index#qcache_hits) |
| [Qcache\_inserts](../server-status-variables/index#qcache_inserts) |
| [Qcache\_lowmem\_prunes](../server-status-variables/index#qcache_lowmem_prunes) |
| [Qcache\_not\_cached](../server-status-variables/index#qcache_not_cached) |
| [Qcache\_queries\_in\_cache](../server-status-variables/index#qcache_queries_in_cache) |
| [Qcache\_total\_blocks](../server-status-variables/index#qcache_total_blocks) |
| [Queries](../server-status-variables/index#queries) |
| --[query-alloc-block-size](../server-system-variables/index#query_alloc_block_size), [query\_alloc\_block\_size](../server-system-variables/index#query_alloc_block_size) |
| --[query-cache-info](../query-cache-information-plugin/index#query_cache_info) |
| --[query-cache-limit](../server-system-variables/index#query_cache_limit), [query\_cache\_limit](../server-system-variables/index#query_cache_limit) |
| --[query-cache-min-res-unit](../server-system-variables/index#query_cache_min_res_unit), [query\_cache\_min\_res\_unit](../server-system-variables/index#query_cache_min_res_unit) |
| --[query-cache-size](../server-system-variables/index#query_cache_size), [query\_cache\_size](../server-system-variables/index#query_cache_size) |
| --[query-cache-strip-comments](../server-system-variables/index#query_cache_strip_comments), [query\_cache\_strip\_comments](../server-system-variables/index#query_cache_strip_comments) |
| --[query-cache-type](../server-system-variables/index#query_cache_type), [query\_cache\_type](../server-system-variables/index#query_cache_type) |
| --[query-cache-wlock-invalidate](../server-system-variables/index#query_cache_wlock_invalidate), [query\_cache\_wlock\_invalidate](../server-system-variables/index#query_cache_wlock_invalidate) |
| --[query-prealloc-size](../server-system-variables/index#query_prealloc_size), [query\_prealloc\_size](../server-system-variables/index#query_prealloc_size) |
| --[query-response-time](../query-response-time-plugin/index#query_response_time) |
| --[query-response-time-audit](../query-response-time-plugin/index#query_response_time_audit) |
| [query\_response\_time\_flush](../query_response_time-plugin/index#query_response_time_flush) |
| --[query-response-time-range-base](../query_response_time-plugin/index#query_response_time_range_base) , [query\_response\_time\_range\_base](../query_response_time-plugin/index#query_response_time_range_base) |
| [query\_response\_time\_exec\_time\_debug](../query_response_time-plugin/index#query_response_time_exec_time_debug) |
| --[query-response-time-stats](../query_response_time-plugin/index#query_response_time_stats), [query\_response\_time\_stats](../query_response_time-plugin/index#query_response_time_stats) |
| [Questions](../server-status-variables/index#questions) |
| -r, --[chroot](../mysqld-options/index#-chroot) |
| [rand\_seed1](../server-system-variables/index#rand_seed1) |
| [rand\_seed2](../server-system-variables/index#rand_seed2) |
| --[range-alloc-block-size](../server-system-variables/index#range_alloc_block_size), [range\_alloc\_block\_size](../server-system-variables/index#range_alloc_block_size) |
| --[read-buffer-size](../server-system-variables/index#read_buffer_size), [read\_buffer\_size](../server-system-variables/index#read_buffer_size) |
| --[read-binlog-speed-limit](../replication-and-binary-log-server-system-variables/index#read_binlog_speed_limit), [read\_binlog\_speed\_limit](../replication-and-binary-log-server-system-variables/index#read_binlog_speed_limit) |
| --[read-only](../server-system-variables/index#read_only), [read\_only](../server-system-variables/index#read_only) |
| --[read-rnd-buffer-size](../server-system-variables/index#read_rnd_buffer_size), [read\_rnd\_buffer\_size](../server-system-variables/index#read_rnd_buffer_size) |
| --[record-buffer](../mysqld-options/index#-record-buffer) |
| --[relay-log](../replication-and-binary-log-server-system-variables/index#relay_log), [relay\_log](../replication-and-binary-log-server-system-variables/index#relay_log) |
| [relay\_log\_basename](../replication-and-binary-log-server-system-variables/index#relay_log_basename) |
| --[relay-log-index](../replication-and-binary-log-server-system-variables/index#relay_log_index), [relay\_log\_index](../replication-and-binary-log-server-system-variables/index#relay_log_index) |
| --[relay-log-info-file](../replication-and-binary-log-server-system-variables/index#relay_log_info_file), [relay\_log\_info\_file](../replication-and-binary-log-server-system-variables/index#relay_log_info_file) |
| --[relay-log-purge](../replication-and-binary-log-server-system-variables/index#relay_log_purge), [relay\_log\_purge](../replication-and-binary-log-server-system-variables/index#relay_log_purge) |
| --[relay-log-recovery](../replication-and-binary-log-server-system-variables/index#relay_log_recovery), [relay\_log\_recovery](../replication-and-binary-log-server-system-variables/index#relay_log_recovery) |
| --[relay-log-space-limit](../replication-and-binary-log-server-system-variables/index#relay_log_space_limit), [relay\_log\_space\_limit](../replication-and-binary-log-server-system-variables/index#relay_log_space_limit) |
| --[remove](../mysqld-options/index#-remove) |
| --[replicate-annotate-row-events](../replication-and-binary-log-server-system-variables/index#replicate_annotate_row_events), [replicate\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#replicate_annotate_row_events) |
| --[replicate-do-db](../replication-and-binary-log-server-system-variables/index#replicate_do_db), [replicate\_do\_db](../replication-and-binary-log-server-system-variables/index#replicate_do_db) |
| --[replicate-do-table](../replication-and-binary-log-server-system-variables/index#replicate_do_table), [replicate\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_do_table) |
| --[replicate-events-marked-for-skip](../replication-and-binary-log-server-system-variables/index#replicate_events_marked_for_skip), [replicate\_events\_marked\_for\_skip](../replication-and-binary-log-server-system-variables/index#replicate_events_marked_for_skip) |
| --[replicate-ignore-db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db), [replicate\_ignore\_db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db) |
| --[replicate-ignore-table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table), [replicate\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table) |
| --[replicate-rewrite-db](../replication-and-binary-log-server-system-variables/index#replicate_rewrite_db), [replicate\_rewrite\_db](../replication-and-binary-log-server-system-variables/index#replicate_rewrite_db) |
| --[replicate-same-server-id](../mysqld-options/index#-replicate-same-server-id) |
| --[replicate-wild-do-table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table), [replicate\_wild\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table) |
| --[replicate-wild-ignore-table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table), [replicate\_wild\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table) |
| --[report-host](../replication-and-binary-log-server-system-variables/index#report_host), [report\_host](../replication-and-binary-log-server-system-variables/index#report_host) |
| --[report-password](../replication-and-binary-log-server-system-variables/index#report_password), [report\_password](../replication-and-binary-log-server-system-variables/index#report_password) |
| --[report-port](../replication-and-binary-log-server-system-variables/index#report_password), [report\_port](../replication-and-binary-log-server-system-variables/index#report_password) |
| --[report-user](../replication-and-binary-log-server-system-variables/index#report_user), [report\_user](../replication-and-binary-log-server-system-variables/index#report_user) |
| --[require-secure-transport](../server-system-variables/index#require_secure_transport), [require\_secure\_transport](../server-system-variables/index#require_secure_transport) |
| --[rocksdb-access-hint-on-compaction-start](../myrocks-system-variables/index#rocksdb_access_hint_on_compaction_start), [rocksdb\_access\_hint\_on\_compaction\_start](../myrocks-system-variables/index#rocksdb_access_hint_on_compaction_start) |
| --[rocksdb-advise-random-on-open](../myrocks-system-variables/index#rocksdb_advise_random_on_open), [rocksdb\_advise\_random\_on\_open](../myrocks-system-variables/index#rocksdb_advise_random_on_open) |
| --[rocksdb-allow-concurrent-memtable-write](../myrocks-system-variables/index#rocksdb_allow_concurrent_memtable_write), [rocksdb\_allow\_concurrent\_memtable\_write](../myrocks-system-variables/index#rocksdb_allow_concurrent_memtable_write) |
| --[rocksdb-allow-mmap-reads](../myrocks-system-variables/index#rocksdb_allow_mmap_reads), [rocksdb\_allow\_mmap\_reads](../myrocks-system-variables/index#rocksdb_allow_mmap_reads) |
| --[rocksdb-allow-mmap-writes](../myrocks-system-variables/index#rocksdb_allow_mmap_writes), [rocksdb\_allow\_mmap\_writes](../myrocks-system-variables/index#rocksdb_allow_mmap_writes) |
| --[rocksdb-allow-to-start-after-corruption](../myrocks-system-variables/index#rocksdb_allow_to_start_after_corruption), [rocksdb\_allow\_to\_start\_after\_corruption](../myrocks-system-variables/index#rocksdb_allow_to_start_after_corruption) |
| --[rocksdb-background-sync](../myrocks-system-variables/index#rocksdb_background_sync), [rocksdb\_background\_sync](../myrocks-system-variables/index#rocksdb_background_sync) |
| --[rocksdb\_base-background-compactions](../myrocks-system-variables/index#rocksdb_base_background_compactions), [rocksdb\_base\_background\_compactions](../myrocks-system-variables/index#rocksdb_base_background_compactions) |
| --[rocksdb-blind-delete-primary-key](../myrocks-system-variables/index#rocksdb_blind_delete_primary_key), [rocksdb\_blind\_delete\_primary\_key](../myrocks-system-variables/index#rocksdb_blind_delete_primary_key) |
| --[rocksdb-block-cache-size](../myrocks-system-variables/index#rocksdb_block_cache_size), [rocksdb\_block\_cache\_size](../myrocks-system-variables/index#rocksdb_block_cache_size) |
| --[rocksdb\_block\_restart\_interval](../myrocks-system-variables/index#rocksdb-block-restart-interval), [rocksdb\_block\_restart\_interval](../myrocks-system-variables/index#rocksdb_block_restart_interval) |
| [Rocksdb\_block\_cache\_add](../myrocks-status-variables/index#rocksdb_block_cache_add) |
| [Rocksdb\_block\_cache\_add\_failures](../myrocks-status-variables/index#rocksdb_block_cache_add_failures) |
| [Rocksdb\_block\_bytes\_read](../myrocks-status-variables/index#rocksdb_block_cache_bytes_read) |
| [Rocksdb\_block\_bytes\_write](../myrocks-status-variables/index#rocksdb_block_cache_bytes_write) |
| [Rocksdb\_block\_cache\_data\_add](../myrocks-status-variables/index#rocksdb_block_cache_data_add) |
| [Rocksdb\_block\_cache\_data\_bytes\_insert](../myrocks-status-variables/index#rocksdb_block_cache_data_bytes_insert) |
| [Rocksdb\_block\_cache\_data\_hit](../myrocks-status-variables/index#rocksdb_block_cache_data_hit) |
| [Rocksdb\_block\_cache\_data\_miss](../myrocks-status-variables/index#rocksdb_block_cache_data_miss) |
| [Rocksdb\_block\_cache\_filter\_add](../myrocks-status-variables/index#rocksdb_block_cache_filter_add) |
| [Rocksdb\_block\_cache\_filter\_bytes\_evict](../myrocks-status-variables/index#rocksdb_block_cache_filter_bytes_evict) |
| [Rocksdb\_block\_cache\_filter\_bytes\_insert](../myrocks-status-variables/index#rocksdb_block_cache_filter_bytes_insert) |
| [Rocksdb\_block\_cache\_filter\_hit](../myrocks-status-variables/index#rocksdb_block_cache_filter_hit) |
| [Rocksdb\_block\_cache\_filter\_miss](../myrocks-status-variables/index#rocksdb_block_cache_filter_miss) |
| [Rocksdb\_block\_cache\_hit](../myrocks-status-variables/index#rocksdb_block_cache_hit) |
| [Rocksdb\_block\_cache\_index\_add](../myrocks-status-variables/index#rocksdb_block_cache_index_add) |
| [Rocksdb\_block\_cache\_index\_bytes\_evict](../myrocks-status-variables/index#rocksdb_block_cache_index_bytes_evict) |
| [Rocksdb\_block\_cache\_index\_bytes\_insert](../myrocks-status-variables/index#rocksdb_block_cache_index_bytes_insert) |
| [Rocksdb\_block\_cache\_index\_hit](../myrocks-status-variables/index#rocksdb_block_cache_index_hit) |
| [Rocksdb\_block\_cache\_index\_miss](../myrocks-status-variables/index#rocksdb_block_cache_index_miss) |
| [Rocksdb\_block\_cache\_miss](../myrocks-status-variables/index#rocksdb_block_cache_miss) |
| [Rocksdb\_block\_cachecompressed\_hit](../myrocks-status-variables/index#rocksdb_block_cachecompressed_hit) |
| [Rocksdb\_block\_cachecompressed\_miss](../myrocks-status-variables/index#rocksdb_block_cachecompressed_miss) |
| --[rocksdb-block-size](../myrocks-system-variables/index#rocksdb_block_size), [rocksdb\_block\_size](../myrocks-system-variables/index#rocksdb_block_size) |
| --[rocksdb-block-size-deviation](../myrocks-system-variables/index#rocksdb_block_size_deviation), [rocksdb\_block\_size\_deviation](../myrocks-system-variables/index#rocksdb_block_size_deviation) |
| [Rocksdb\_bloom\_filter\_full\_positive](../myrocks-status-variables/index#rocksdb_bloom_filter_full_positive) |
| [Rocksdb\_bloom\_filter\_full\_true\_positive](../myrocks-status-variables/index#rocksdb_bloom_filter_full_true_positive) |
| [Rocksdb\_bloom\_filter\_prefix\_checked](../myrocks-status-variables/index#rocksdb_bloom_filter_prefix_checked) |
| [Rocksdb\_bloom\_filter\_prefix\_useful](../myrocks-status-variables/index#rocksdb_bloom_filter_prefix_useful) |
| [Rocksdb\_bloom\_filter\_useful](../myrocks-status-variables/index#rocksdb_bloom_filter_useful) |
| --[rocksdb-bulk-load](../myrocks-system-variables/index#rocksdb_bulk_load), [rocksdb\_bulk\_load](../myrocks-system-variables/index#rocksdb_bulk_load) |
| --[rocksdb-bulk-load\_allow\_sk](../myrocks-system-variables/index#rocksdb_bulk_load_allow_sk), [rocksdb\_bulk\_load\_allow\_sk](../myrocks-system-variables/index#rocksdb_bulk_load_allow_sk) |
| --[rocksdb-bulk-load\_allow\_unsorted](../myrocks-system-variables/index#rocksdb_bulk_load_allow_unsorted), [rocksdb\_bulk\_load\_allow\_unsorted](../myrocks-system-variables/index#rocksdb_bulk_load_allow_unsorted) |
| --[rocksdb-bulk-load-size](../myrocks-system-variables/index#rocksdb_bulk_load_size), [rocksdb\_bulk\_load\_size](../myrocks-system-variables/index#rocksdb_bulk_load_size) |
| --[rocksdb-bytes-per-sync](../myrocks-system-variables/index#rocksdb_bytes_per_sync), [rocksdb\_bytes\_per\_sync](../myrocks-system-variables/index#rocksdb_bytes_per_sync) |
| [Rocksdb\_bytes\_read](../myrocks-status-variables/index#rocksdb_bytes_read) |
| [Rocksdb\_bytes\_written](../myrocks-status-variables/index#rocksdb_bytes_written) |
| --[rocksdb-cache-dump](../myrocks-system-variables/index#rocksdb_cache_dump), [rocksdb\_cache\_dump](../myrocks-system-variables/index#rocksdb_cache_dump) |
| --[rocksdb-cache-high-pri-pool-ratio](../myrocks-system-variables/index#rocksdb_cache_high_pri_pool_ratio), [rocksdb\_cache\_high\_pri\_pool\_ratio](../myrocks-system-variables/index#rocksdb_cache_high_pri_pool_ratio) |
| --[rocksdb-cache-index-and-filter-blocks](../myrocks-system-variables/index#rocksdb_cache_index_and_filter_blocks), [rocksdb\_cache\_index\_and\_filter\_blocks](../myrocks-system-variables/index#rocksdb_cache_index_and_filter_blocks) |
| --[rocksdb-cache-index-and-filter-with-high-priority](../myrocks-system-variables/index#rocksdb_cache_index_and_filter_with_high_priority), [rocksdb\_cache\_index\_and\_filter\_with\_high\_priority](../myrocks-system-variables/index#rocksdb_cache_index_and_filter_with_high_priority) |
| --[rocksdb-checksums-pct](../myrocks-system-variables/index#rocksdb_checksums_pct), [rocksdb\_checksums\_pct](../myrocks-system-variables/index#rocksdb_checksums_pct) |
| --[rocksdb-collect-sst-properties](../myrocks-system-variables/index#rocksdb_collect_sst_properties), [rocksdb\_collect\_sst\_properties](../myrocks-system-variables/index#rocksdb_collect_sst_properties) |
| --[rocksdb-commit-in-the-middle](../myrocks-system-variables/index#rocksdb_commit_in_the_middle), [rocksdb\_commit\_in\_the\_middle](../myrocks-system-variables/index#rocksdb_commit_in_the_middle) |
| --[rocksdb-commit-time-batch-for-recovery](../myrocks-system-variables/index#rocksdb_commit_time_batch_for_recovery), [rocksdb\_commit\_time\_batch\_for\_recovery](../myrocks-system-variables/index#rocksdb_commit_time_batch_for_recovery) |
| --[rocksdb-compact-cf](../myrocks-system-variables/index#rocksdb_compact_cf), [rocksdb\_compact\_cf](../myrocks-system-variables/index#rocksdb_compact_cf) |
| [Rocksdb\_compact\_read\_bytes](../myrocks-status-variables/index#rocksdb_compact_read_bytes) |
| [Rocksdb\_compact\_write\_bytes](../myrocks-status-variables/index#rocksdb_compact_write_bytes) |
| [Rocksdb\_compaction\_key\_drop\_new](../myrocks-status-variables/index#rocksdb_compaction_key_drop_new) |
| [Rocksdb\_compaction\_key\_drop\_obsolete](../myrocks-status-variables/index#rocksdb_compaction_key_drop_obsolete) |
| [Rocksdb\_compaction\_key\_drop\_user](../myrocks-status-variables/index#rocksdb_compaction_key_drop_user) |
| --[rocksdb-compaction-readahead-size](../myrocks-system-variables/index#rocksdb_compaction_readahead_size), [rocksdb\_compaction\_readahead\_size](../myrocks-system-variables/index#rocksdb_compaction_readahead_size) |
| --[rocksdb-compaction-sequential-deletes](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes), [rocksdb\_compaction\_sequential\_deletes](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes) |
| --[rocksdb-compaction-sequential-deletes-count-sd](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_count_sd), [rocksdb\_compaction\_sequential\_deletes\_count\_sd](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_count_sd) |
| --[rocksdb-concurrent-prepare](../myrocks-system-variables/index#rocksdb_concurrent_prepare), [rocksdb\_concurrent\_prepare](../myrocks-system-variables/index#rocksdb_concurrent_prepare) |
| --[rocksdb-compaction-sequential-deletes-file-size](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_file_size), [rocksdb\_compaction\_sequential\_deletes\_file\_size](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_file_size) |
| --[rocksdb-compaction-sequential-deletes-window](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_window), [rocksdb\_compaction\_sequential\_deletes\_window](../myrocks-system-variables/index#rocksdb_compaction_sequential_deletes_window) |
| [Rocksdb\_covered\_secondary\_key\_lookups](../myrocks-status-variables/index#rocksdb_covered_secondary_key_lookups) |
| --[rocksdb-create-checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint), [rocksdb\_create\_checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint) |
| --[rocksdb-create-if-missing](../myrocks-system-variables/index#rocksdb_create_if_missing), [rocksdb\_create\_if\_missing](../myrocks-system-variables/index#rocksdb_create_if_missing) |
| --[rocksdb-create-missing-column-families](../myrocks-system-variables/index#rocksdb_create_missing_column_families), [rocksdb\_create\_missing\_column\_families](../myrocks-system-variables/index#rocksdb_create_missing_column_families) |
| --[rocksdb-datadir](../myrocks-system-variables/index#rocksdb_datadir), [rocksdb\_datadir](../myrocks-system-variables/index#rocksdb_datadir) |
| --[rocksdb-db-write-buffer-size](../myrocks-system-variables/index#rocksdb_db_write_buffer_size), [rocksdb\_db\_write\_buffer\_size](../myrocks-system-variables/index#rocksdb_db_write_buffer_size) |
| --[rocksdb-deadlock-detect](../myrocks-system-variables/index#rocksdb_deadlock_detect), [rocksdb\_deadlock\_detect](../myrocks-system-variables/index#rocksdb_deadlock_detect) |
| --[rocksdb-deadlock-detect-depth](../myrocks-system-variables/index#rocksdb_deadlock_detect_depth), [rocksdb\_deadlock\_detect\_depth](../myrocks-system-variables/index#rocksdb_deadlock_detect_depth) |
| --[rocksdb-debug-manual-compaction-delay](../myrocks-system-variables/index#rocksdb_debug_manual_compaction_delay), [rocksdb\_debug\_manual\_compaction\_delay](../myrocks-system-variables/index#rocksdb_debug_manual_compaction_delay) |
| --[rocksdb-debug-optimizer-no-zero-cardinality](../myrocks-system-variables/index#rocksdb_debug_optimizer_no_zero_cardinality), [rocksdb\_debug\_optimizer\_no\_zero\_cardinality](../myrocks-system-variables/index#rocksdb_debug_optimizer_no_zero_cardinality) |
| --[rocksdb-debug-ttl-ignore-pk](../myrocks-system-variables/index#rocksdb_debug_ttl_ignore_pk), [rocksdb\_debug\_ttl\_ignore\_pk](../myrocks-system-variables/index#rocksdb_debug_ttl_ignore_pk) |
| --[rocksdb-debug-ttl-read-filter-ts](../myrocks-system-variables/index#rocksdb_debug_ttl_read_filter_ts), [rocksdb\_debug\_ttl\_read\_filter\_ts](../myrocks-system-variables/index#rocksdb_debug_ttl_read_filter_ts) |
| --[rocksdb-debug-ttl-rec-ts](../myrocks-system-variables/index#rocksdb_debug_ttl_rec_ts), [rocksdb\_debug\_ttl\_rec\_ts](../myrocks-system-variables/index#rocksdb_debug_ttl_rec_ts) |
| --[rocksdb-debug-ttl-snapshot-ts](../myrocks-system-variables/index#rocksdb_debug_ttl_snapshot_ts), [rocksdb\_debug\_ttl\_snapshot\_ts](../myrocks-system-variables/index#rocksdb_debug_ttl_snapshot_ts) |
| --[rocksdb-default-cf-options](../myrocks-system-variables/index#rocksdb_default_cf_options), [rocksdb\_default\_cf\_options](../myrocks-system-variables/index#rocksdb_default_cf_options) |
| --[rocksdb-delayed-write-rate](../myrocks-system-variables/index#rocksdb_delayed_write_rate), [rocksdb\_delayed\_write\_rate](../myrocks-system-variables/index#rocksdb_delayed_write_rate) |
| --[rocksdb-delete-cf](../myrocks-system-variables/index#rocksdb_delete_cf), [rocksdb\_delete\_cf](../myrocks-system-variables/index#rocksdb_delete_cf) |
| --[rocksdb-delete-obsolete-files-period-micros](../myrocks-system-variables/index#rocksdb_delete_obsolete_files_period_micros), [rocksdb\_delete\_obsolete\_files\_period\_micros](../myrocks-system-variables/index#rocksdb_delete_obsolete_files_period_micros) |
| --[rocksdb-enable-2pc](../myrocks-system-variables/index#rocksdb_enable_2pc), [rocksdb\_enable\_2pc](../myrocks-system-variables/index#rocksdb_enable_2pc) |
| --[rocksdb-enable-bulk-load-api](../myrocks-system-variables/index#rocksdb_enable_bulk_load_api), [rocksdb\_enable\_bulk\_load\_api](../myrocks-system-variables/index#rocksdb_enable_bulk_load_api) |
| --[rocksdb-enable-insert-with-update-caching](../myrocks-system-variables/index#rocksdb_enable_insert_with_update_caching), [rocksdb\_enable\_insert\_with\_update\_caching](../myrocks-system-variables/index#rocksdb_enable_insert_with_update_caching) |
| --[rocksdb-enable-thread-tracking](../myrocks-system-variables/index#rocksdb_enable_thread_tracking), [rocksdb\_enable\_thread\_tracking](../myrocks-system-variables/index#rocksdb_enable_thread_tracking) |
| --[rocksdb-enable-ttl](../myrocks-system-variables/index#rocksdb_enable_ttl), [rocksdb\_enable\_ttl](../myrocks-system-variables/index#rocksdb_enable_ttl) |
| --[rocksdb-enable-ttl-read-filtering](../myrocks-system-variables/index#rocksdb_enable_ttl_read_filtering), [rocksdb\_enable\_ttl\_read\_filtering](../myrocks-system-variables/index#rocksdb_enable_ttl_read_filtering) |
| --[rocksdb-enable-write-thread-adaptive-yield](../myrocks-system-variables/index#rocksdb_enable_write_thread_adaptive_yield), [rocksdb\_enable\_write\_thread\_adaptive\_yield](../myrocks-system-variables/index#rocksdb_enable_write_thread_adaptive_yield) |
| --[rocksdb-error-if-exists](../myrocks-system-variables/index#rocksdb_error_if_exists), [rocksdb\_error\_if\_exists](../myrocks-system-variables/index#rocksdb_error_if_exists) |
| --[rocksdb-error-on-suboptimal-collation](../myrocks-system-variables/index#rocksdb_error_on_suboptimal_collation), [rocksdb\_on\_suboptimal\_collation](../myrocks-system-variables/index#rocksdb_error_on_suboptimal_collation) |
| --[rocksdb-flush-log-at-trx-commit](../myrocks-system-variables/index#rocksdb_flush_log_at_trx_commit), [rocksdb\_flush\_log\_at\_trx\_commit](../myrocks-system-variables/index#rocksdb_flush_log_at_trx_commit) |
| --[rocksdb-flush-memtable-on-analyze](../myrocks-system-variables/index#rocksdb_flush_memtable_on_analyze), [rocksdb\_flush\_memtable\_on\_analyze](../myrocks-system-variables/index#rocksdb_flush_memtable_on_analyze) |
| [Rocksdb\_flush\_write\_bytes](../myrocks-status-variables/index#rocksdb_flush_write_bytes) |
| --[rocksdb-force-compute-memtable-stats](../myrocks-system-variables/index#rocksdb_force_compute_memtable_stats), [rocksdb\_force\_compute\_memtable\_stats](../myrocks-system-variables/index#rocksdb_force_compute_memtable_stats) |
| --[rocksdb-force-compute-memtable-stats-cachetime](../myrocks-system-variables/index#rocksdb_force_compute_memtable_stats_cachetime), [rocksdb\_force\_compute\_memtable\_stats\_cachetime](../myrocks-system-variables/index#rocksdb_force_compute_memtable_stats_cachetime) |
| --[rocksdb-force-flush-memtable-and-lzero-now](../myrocks-system-variables/index#rocksdb_force_flush_memtable_and_lzero_now), [rocksdb\_force\_flush\_memtable\_and\_lzero\_now](../myrocks-system-variables/index#rocksdb_force_flush_memtable_and_lzero_now) |
| --[rocksdb-force-flush-memtable-now](../myrocks-system-variables/index#rocksdb_force_flush_memtable_now), [rocksdb\_force\_flush\_memtable\_now](../myrocks-system-variables/index#rocksdb_force_flush_memtable_now) |
| --[rocksdb-force-index-records-in-range](../myrocks-system-variables/index#rocksdb_force_index_records_in_range), [rocksdb\_force\_index\_records\_in\_range](../myrocks-system-variables/index#rocksdb_force_index_records_in_range) |
| [Rocksdb\_get\_hit\_l0](../myrocks-status-variables/index#rocksdb_get_hit_l0) |
| [Rocksdb\_get\_hit\_l1](../myrocks-status-variables/index#rocksdb_get_hit_l1) |
| [Rocksdb\_get\_hit\_l2\_and\_up](../myrocks-status-variables/index#rocksdb_get_hit_l2_and_up) |
| [Rocksdb\_getupdatessince\_calls](../myrocks-status-variables/index#rocksdb_getupdatessince_calls) |
| --[rocksdb-git-hash](../myrocks-system-variables/index#rocksdb_git_hash), [rocksdb\_git\_hash](../myrocks-system-variables/index#rocksdb_git_hash) |
| --[rocksdb-hash-index-allow-collision](../myrocks-system-variables/index#rocksdb_hash_index_allow_collision), [rocksdb\_hash\_index\_allow\_collision](../myrocks-system-variables/index#rocksdb_hash_index_allow_collision) |
| --[rocksdb-ignore-unknown-options](../myrocks-system-variables/index#rocksdb_ignore_unknown_options), [rocksdb\_ignore\_unknown\_options](../myrocks-system-variables/index#rocksdb_ignore_unknown_options) |
| --[rocksdb-index-type](../myrocks-system-variables/index#rocksdb_index_type), [rocksdb\_index\_type](../myrocks-system-variables/index#rocksdb_index_type) |
| --[rocksdb-info-log-level](../myrocks-system-variables/index#rocksdb_info_log_level), [rocksdb\_info\_log\_level](../myrocks-system-variables/index#rocksdb_info_log_level) |
| --[rocksdb-io-write-timeout](../myrocks-system-variables/index#rocksdb_io_write_timeout), [rocksdb\_io\_write\_timeout](../myrocks-system-variables/index#rocksdb_io_write_timeout) |
| --[rocksdb-is-fd-close-on-exec](../myrocks-system-variables/index#rocksdb_is_fd_close_on_exec), [rocksdb\_is\_fd\_close\_on\_exec](../myrocks-system-variables/index#rocksdb_is_fd_close_on_exec) |
| [Rocksdb\_iter\_bytes\_read](../myrocks-status-variables/index#rocksdb_iter_bytes_read) |
| --[rocksdb-keep-log-file-num](../myrocks-system-variables/index#rocksdb_keep_log_file_num), [rocksdb\_keep\_log\_file\_num](../myrocks-system-variables/index#rocksdb_keep_log_file_num) |
| [Rocksdb\_l0\_num\_files\_stall\_micros](../myrocks-status-variables/index#rocksdb_l0_num_files_stall_micros) |
| [Rocksdb\_l0\_slowdown\_micros](../myrocks-status-variables/index#rocksdb_l0_slowdown_micros) |
| --[rocksdb-large-prefix](../myrocks-system-variables/index#rocksdb_large_prefix), [rocksdb\_large\_prefix](../myrocks-system-variables/index#rocksdb_large_prefix) |
| --[rocksdb-lock-scanned-rows](../myrocks-system-variables/index#rocksdb_lock_scanned_rows), [rocksdb\_lock\_scanned\_rows](../myrocks-system-variables/index#rocksdb_lock_scanned_rows) |
| --[rocksdb-lock-wait-timeout](../myrocks-system-variables/index#rocksdb_lock_wait_timeout), [rocksdb\_lock\_wait\_timeout](../myrocks-system-variables/index#rocksdb_lock_wait_timeout) |
| --[rocksdb-log-dir](../myrocks-system-variables/index#rocksdb_log_dir), [rocksdb\_log\_dir](../myrocks-system-variables/index#rocksdb_log_dir) |
| --[rocksdb-log-file-time-to-roll](../myrocks-system-variables/index#rocksdb_log_file_time_to_roll), [rocksdb\_log\_file\_time\_to\_roll](../myrocks-system-variables/index#rocksdb_log_file_time_to_roll) |
| --[rocksdb-manifest-preallocation-size](../myrocks-system-variables/index#rocksdb_manifest_preallocation_size), [rocksdb\_manifest\_preallocation\_size](../myrocks-system-variables/index#rocksdb_manifest_preallocation_size) |
| --[rocksdb-manual-compaction-threads](../myrocks-system-variables/index#rocksdb_manual_compaction_threads), [rocksdb\_manual\_compaction\_threads](../myrocks-system-variables/index#rocksdb_manual_compaction_threads) |
| [Rocksdb\_manual\_compactions\_processed](../myrocks-status-variables/index#rocksdb_manual_compactions_processed) |
| [Rocksdb\_manual\_compactions\_running](../myrocks-status-variables/index#rocksdb_manual_compactions_running) |
| --[rocksdb-manual-wal-flush](../myrocks-system-variables/index#rocksdb_manual_wal_flush), [rocksdb\_manual\_wal\_flush](../myrocks-system-variables/index#rocksdb_manual_wal_flush) |
| --[rocksdb-master-skip-tx-api](../myrocks-system-variables/index#rocksdb_master_skip_tx_api), [rocksdb\_master\_skip\_tx\_api](../myrocks-system-variables/index#rocksdb_master_skip_tx_api) |
| --[rocksdb-max-background-compactions](../myrocks-system-variables/index#rocksdb_max_background_compactions), [rocksdb\_max\_background\_compactions](../myrocks-system-variables/index#rocksdb_max_background_compactions) |
| --[rocksdb-max-latest-deadlocks](../myrocks-system-variables/index#rocksdb_max_latest_deadlocks), [rocksdb\_max\_latest\_deadlocks](../myrocks-system-variables/index#rocksdb_max_latest_deadlocks) |
| --[rocksdb-max-background-flushes](../myrocks-system-variables/index#rocksdb_max_background_flushes), [rocksdb\_max\_background\_flushes](../myrocks-system-variables/index#rocksdb_max_background_flushes) |
| --[rocksdb-max-background-jobs](../myrocks-system-variables/index#rocksdb_max_background_jobs), [rocksdb\_max\_background\_jobs](../myrocks-system-variables/index#rocksdb_max_background_jobs) |
| --[rocksdb-max-log-file-size](../myrocks-system-variables/index#rocksdb_max_log_file_size), [rocksdb\_max\_log\_file\_size](../myrocks-system-variables/index#rocksdb_max_log_file_size) |
| --[rocksdb-max-manifest-file-size](../myrocks-system-variables/index#rocksdb_max_manifest_file_size), [rocksdb\_max\_manifest\_file\_size](../myrocks-system-variables/index#rocksdb_max_manifest_file_size) |
| --[rocksdb-max-manual-compactions](../myrocks-system-variables/index#rocksdb_max_manual_compactions), [rocksdb\_max\_manual\_compactions](../myrocks-system-variables/index#rocksdb_max_manual_compactions) |
| --[rocksdb-max-open-files](../myrocks-system-variables/index#rocksdb_max_open_files), [rocksdb\_max\_open\_files](../myrocks-system-variables/index#rocksdb_max_open_files) |
| --[rocksdb-max-row-locks](../myrocks-system-variables/index#rocksdb_max_row_locks), [rocksdb\_max\_row\_locks](../myrocks-system-variables/index#rocksdb_max_row_locks) |
| --[rocksdb-max-subcompactions](../myrocks-system-variables/index#rocksdb_max_subcompactions), [rocksdb\_max\_subcompactions](../myrocks-system-variables/index#rocksdb_max_subcompactions) |
| --[rocksdb-max-total-wal-size](../myrocks-system-variables/index#rocksdb_max_total_wal_size), [rocksdb\_max\_total\_wal\_size](../myrocks-system-variables/index#rocksdb_max_total_wal_size) |
| [Rocksdb\_memtable\_compaction\_micros](../myrocks-status-variables/index#rocksdb_memtable_compaction_micros) |
| [Rocksdb\_memtable\_hit](../myrocks-status-variables/index#rocksdb_memtable_hit) |
| [Rocksdb\_memtable\_miss](../myrocks-status-variables/index#rocksdb_memtable_miss) |
| [Rocksdb\_memtable\_total](../myrocks-status-variables/index#rocksdb_memtable_total) |
| [Rocksdb\_memtable\_unflushed](../myrocks-status-variables/index#rocksdb_memtable_unflushed) |
| --[rocksdb-merge-buf-size](../myrocks-system-variables/index#rocksdb_merge_buf_size), [rocksdb\_merge\_buf\_size](../myrocks-system-variables/index#rocksdb_merge_buf_size) |
| --[rocksdb-merge-combine-read-size](../myrocks-system-variables/index#rocksdb_merge_combine_read_size), [rocksdb\_merge\_combine\_read\_size](../myrocks-system-variables/index#rocksdb_merge_combine_read_size) |
| --[rocksdb-merge-tmp-file-removal-delay-ms](../myrocks-system-variables/index#rocksdb_merge_tmp_file_removal_delay_ms), [rocksdb\_merge\_tmp\_file\_removal\_delay\_ms](../myrocks-system-variables/index#rocksdb_merge_tmp_file_removal_delay_ms) |
| --[rocksdb-new-table-reader-for-compaction-inputs](../myrocks-system-variables/index#rocksdb_new_table_reader_for_compaction_inputs), [rocksdb\_new\_table\_reader\_for\_compaction\_inputs](../myrocks-system-variables/index#rocksdb_new_table_reader_for_compaction_inputs) |
| --[rocksdb-no-block-cache](../myrocks-system-variables/index#rocksdb_no_block_cache), [rocksdb\_no\_block\_cache](../myrocks-system-variables/index#rocksdb_no_block_cache) |
| [Rocksdb\_no\_file\_closes](../myrocks-status-variables/index#rocksdb_no_file_closes) |
| [Rocksdb\_no\_file\_errors](../myrocks-status-variables/index#rocksdb_no_file_errors) |
| [Rocksdb\_no\_file\_opens](../myrocks-status-variables/index#rocksdb_no_file_opens) |
| [Rocksdb\_num\_iterators](../myrocks-status-variables/index#rocksdb_num_iterators) |
| [Rocksdb\_number\_block\_not\_compressed](../myrocks-status-variables/index#rocksdb_number_block_not_compressed) |
| [Rocksdb\_db\_next](../myrocks-status-variables/index#rocksdb_number_db_next) |
| [Rocksdb\_db\_next\_found](../myrocks-status-variables/index#rocksdb_number_db_next_found) |
| [Rocksdb\_db\_prev](../myrocks-status-variables/index#rocksdb_number_db_prev) |
| [Rocksdb\_db\_prev\_found](../myrocks-status-variables/index#rocksdb_number_db_prev_found) |
| [Rocksdb\_db\_seek](../myrocks-status-variables/index#rocksdb_number_db_seek) |
| [Rocksdb\_db\_seek\_found](../myrocks-status-variables/index#rocksdb_number_db_seek_found) |
| [Rocksdb\_number\_deletes\_filtered](../myrocks-status-variables/index#rocksdb_number_deletes_filtered) |
| [Rocksdb\_number\_keys\_read](../myrocks-status-variables/index#rocksdb_number_keys_read) |
| [Rocksdb\_number\_keys\_updated](../myrocks-status-variables/index#rocksdb_number_keys_updated) |
| [Rocksdb\_number\_keys\_written](../myrocks-status-variables/index#rocksdb_number_keys_written) |
| [Rocksdb\_number\_merge\_failures](../myrocks-status-variables/index#rocksdb_number_merge_failures) |
| [Rocksdb\_number\_multiget\_bytes\_read](../myrocks-status-variables/index#rocksdb_number_multiget_bytes_read) |
| [Rocksdb\_number\_multiget\_get](../myrocks-status-variables/index#rocksdb_number_multiget_get) |
| [Rocksdb\_number\_multiget\_keys\_read](../myrocks-status-variables/index#rocksdb_number_multiget_keys_read) |
| [Rocksdb\_number\_reseeks\_iteration](../myrocks-status-variables/index#rocksdb_number_reseeks_iteration) |
| [Rocksdb\_number\_sst\_entry\_delete](../myrocks-status-variables/index#rocksdb_number_sst_entry_delete) |
| [Rocksdb\_number\_sst\_entry\_merge](../myrocks-status-variables/index#rocksdb_number_sst_entry_merge) |
| [Rocksdb\_number\_sst\_entry\_other](../myrocks-status-variables/index#rocksdb_number_sst_entry_other) |
| [Rocksdb\_number\_sst\_entry\_put](../myrocks-status-variables/index#rocksdb_number_sst_entry_put) |
| [Rocksdb\_number\_sst\_entry\_singledelete](../myrocks-status-variables/index#rocksdb_number_sst_entry_singledelete) |
| [Rocksdb\_number\_superversion\_acquires](../myrocks-status-variables/index#rocksdb_number_superversion_acquires) |
| [Rocksdb\_number\_superversion\_cleanups](../myrocks-status-variables/index#rocksdb_number_superversion_cleanups) |
| [Rocksdb\_number\_superversion\_releases](../myrocks-status-variables/index#rocksdb_number_superversion_releases) |
| --[rocksdb-override-cf-options](../myrocks-system-variables/index#rocksdb_override_cf_options), [rocksdb\_override\_cf\_options](../myrocks-system-variables/index#rocksdb_override_cf_options) |
| --[rocksdb-paranoid-checks](../myrocks-system-variables/index#rocksdb_paranoid_checks), [rocksdb\_paranoid\_checks](../myrocks-system-variables/index#rocksdb_paranoid_checks) |
| --[rocksdb-pause-background-work](../myrocks-system-variables/index#rocksdb_pause_background_work), [rocksdb\_pause\_background\_work](../myrocks-system-variables/index#rocksdb_pause_background_work) |
| --[rocksdb-perf-context-level](../myrocks-system-variables/index#rocksdb_perf_context_level), [rocksdb\_perf\_context\_level](../myrocks-system-variables/index#rocksdb_perf_context_level) |
| --[rocksdb-persistent-cache-path](../myrocks-system-variables/index#rocksdb_persistent_cache_path), [rocksdb\_persistent\_cache\_path](../myrocks-system-variables/index#rocksdb_persistent_cache_path) |
| --[rocksdb-persistent-cache-size-mb](../myrocks-system-variables/index#rocksdb_persistent_cache_size_mb), [rocksdb\_persistent\_cache\_size\_mb](../myrocks-system-variables/index#rocksdb_persistent_cache_size_mb) |
| --[rocksdb-pin-l0-filter-and-index-blocks-in-cache](../myrocks-system-variables/index#rocksdb_pin_l0_filter_and_index_blocks_in_cache), [rocksdb\_pin\_l0\_filter\_and\_index\_blocks\_in\_cache](../myrocks-system-variables/index#rocksdb_pin_l0_filter_and_index_blocks_in_cache) |
| --[rocksdb-print-snapshot-conflict-queries](../myrocks-system-variables/index#rocksdb_print_snapshot_conflict_queries), [rocksdb\_print\_snapshot\_conflict\_queries](../myrocks-system-variables/index#rocksdb_print_snapshot_conflict_queries) |
| [Rocksdb\_queries\_point](../myrocks-status-variables/index#rocksdb_queries_point) |
| [Rocksdb\_queries\_range](../myrocks-status-variables/index#rocksdb_queries_range) |
| --[rocksdb-rate-limiter-bytes-per-sec](../myrocks-system-variables/index#rocksdb_rate_limiter_bytes_per_sec), [rocksdb\_rate\_limiter\_bytes\_per\_sec](../myrocks-system-variables/index#rocksdb_rate_limiter_bytes_per_sec) |
| --[rocksdb-read-free-rpl-tables](../myrocks-system-variables/index#rocksdb_read_free_rpl_tables), [rocksdb\_read\_free\_rpl\_tables](../myrocks-system-variables/index#rocksdb_read_free_rpl_tables) |
| --[rocksdb-records-in-range](../myrocks-system-variables/index#rocksdb_records_in_range), [rocksdb\_records\_in\_range](../myrocks-system-variables/index#rocksdb_records_in_range) |
| --[rocksdb-remove-mariabackup-checkpoint](../myrocks-system-variables/index#rocksdb_remove_mariabackup_checkpoint), [rocksdb\_remove\_mariabackup\_checkpoint](../myrocks-system-variables/index#rocksdb_remove_mariabackup_checkpoint) |
| --[rocksdb-reset-stats](../myrocks-system-variables/index#rocksdb_reset_stats), [rocksdb\_reset\_stats](../myrocks-system-variables/index#rocksdb_reset_stats) |
| --[rocksdb-rollback-on-timeout](../myrocks-system-variables/index#rocksdb_rollback_on_timeout), [rocksdb\_rollback\_on\_timeout](../myrocks-system-variables/index#rocksdb_rollback_on_timeout) |
| [Rocksdb\_row\_lock\_deadlocks](../myrocks-status-variables/index#rocksdb_row_lock_deadlocks) |
| [Rocksdb\_row\_lock\_wait\_timeouts](../myrocks-status-variables/index#rocksdb_row_lock_wait_timeouts) |
| [Rocksdb\_rows\_deleted](../myrocks-status-variables/index#rocksdb_rows_deleted) |
| [Rocksdb\_rows\_deleted\_blind](../myrocks-status-variables/index#rocksdb_rows_deleted_blind) |
| [Rocksdb\_rows\_expired](../myrocks-status-variables/index#rocksdb_rows_expired) |
| [Rocksdb\_rows\_filtered](../myrocks-status-variables/index#rocksdb_rows_filtered) |
| [Rocksdb\_rows\_inserted](../myrocks-status-variables/index#rocksdb_rows_inserted) |
| [Rocksdb\_rows\_read](../myrocks-status-variables/index#rocksdb_rows_read) |
| [Rocksdb\_rows\_updated](../myrocks-status-variables/index#rocksdb_rows_updated) |
| --[rocksdb-seconds-between-stat-computes](../myrocks-system-variables/index#rocksdb_seconds_between_stat_computes), [rocksdb\_seconds\_between\_stat\_computes](../myrocks-system-variables/index#rocksdb_seconds_between_stat_computes) |
| --[rocksdb-signal-drop-index-thread](../myrocks-system-variables/index#rocksdb_signal_drop_index_thread), [rocksdb\_signal\_drop\_index\_thread](../myrocks-system-variables/index#rocksdb_signal_drop_index_thread) |
| --[rocksdb-sim-cache-size](../myrocks-system-variables/index#rocksdb_sim_cache_size), [rocksdb\_sim\_cache\_size](../myrocks-system-variables/index#rocksdb_sim_cache_size) |
| --[rocksdb-skip-bloom-filter-on-read](../myrocks-system-variables/index#rocksdb_skip_bloom_filter_on_read), [rocksdb\_skip\_bloom\_filter\_on\_read](../myrocks-system-variables/index#rocksdb_skip_bloom_filter_on_read) |
| --[rocksdb-skip-fill-cache](../myrocks-system-variables/index#rocksdb_skip_fill_cache), [rocksdb\_skip\_fill\_cache](../myrocks-system-variables/index#rocksdb_skip_fill_cache) |
| --[rocksdb-skip-unique-check-tables](../myrocks-system-variables/index#rocksdb_skip_unique_check_tables), [rocksdb\_skip\_unique\_check\_tables](../myrocks-system-variables/index#rocksdb_skip_unique_check_tables) |
| [Rocksdb\_snapshot\_conflict\_errors](../myrocks-status-variables/index#rocksdb_snapshot_conflict_errors) |
| --[rocksdb-sst-mgr-rate-bytes-per-sec](../myrocks-system-variables/index#rocksdb_sst_mgr_rate_bytes_per_sec), [rocksdb\_sst\_mgr\_rate\_bytes\_per\_sec](../myrocks-system-variables/index#rocksdb_sst_mgr_rate_bytes_per_sec) |
| [Rocksdb\_stall\_l0\_file\_count\_limit\_slowdowns](../myrocks-status-variables/index#rocksdb_stall_l0_file_count_limit_slowdowns) |
| [Rocksdb\_stall\_l0\_file\_count\_limit\_stops](../myrocks-status-variables/index#rocksdb_stall_l0_file_count_limit_stops) |
| [Rocksdb\_stall\_locked\_l0\_file\_count\_limit\_slowdowns](../myrocks-status-variables/index#rocksdb_stall_locked_l0_file_count_limit_slowdowns) |
| [Rocksdb\_stall\_locked\_l0\_file\_count\_limit\_stops](../myrocks-status-variables/index#rocksdb_stall_locked_l0_file_count_limit_stops) |
| [Rocksdb\_stall\_memtable\_limit\_slowdowns](../myrocks-status-variables/index#rocksdb_stall_memtable_limit_slowdowns) |
| [Rocksdb\_stall\_memtable\_limit\_stops](../myrocks-status-variables/index#rocksdb_stall_memtable_limit_stops) |
| [Rocksdb\_stall\_micros](../myrocks-status-variables/index#rocksdb_stall_micros) |
| [Rocksdb\_stall\_pending\_compaction\_limit\_slowdowns](../myrocks-status-variables/index#rocksdb_stall_pending_compaction_limit_slowdowns) |
| [Rocksdb\_stall\_pending\_compaction\_limit\_stops](../myrocks-status-variables/index#rocksdb_stall_pending_compaction_limit_stops) |
| [Rocksdb\_stall\_total\_slowdowns](../myrocks-status-variables/index#rocksdb_stall_total_slowdowns) |
| [Rocksdb\_stall\_total\_stops](../myrocks-status-variables/index#rocksdb_stall_total_stops) |
| --[rocksdb-stats-dump-period-sec](../myrocks-system-variables/index#rocksdb_stats_dump_period_sec), [rocksdb\_stats\_dump\_period\_sec](../myrocks-system-variables/index#rocksdb_stats_dump_period_sec) |
| --[rocksdb-stats-level](../myrocks-system-variables/index#rocksdb_stats_level), [rocksdb\_stats\_level](../myrocks-system-variables/index#rocksdb_stats_level) |
| --[rocksdb-stats-recalc-rate](../myrocks-system-variables/index#rocksdb_stats_recalc_rate), [rocksdb\_stats\_recalc\_rate](../myrocks-system-variables/index#rocksdb_stats_recalc_rate) |
| --[rocksdb-store-row-debug-checksums](../myrocks-system-variables/index#rocksdb_store_row_debug_checksums), [rocksdb\_store\_row\_debug\_checksums](../myrocks-system-variables/index#rocksdb_store_row_debug_checksums) |
| --[rocksdb-strict-collation-check](../myrocks-system-variables/index#rocksdb_strict_collation_check), [rocksdb\_strict\_collation\_check](../myrocks-system-variables/index#rocksdb_strict_collation_check) |
| --[rocksdb-strict-collation-exceptions](../myrocks-system-variables/index#rocksdb_strict_collation_exceptions), [rocksdb\_strict\_collation\_exceptions](../myrocks-system-variables/index#rocksdb_strict_collation_exceptions) |
| --[rocksdb-supported-compression-types](../myrocks-system-variables/index#rocksdb_supported_compression_types), [rocksdb\_supported\_compression\_types](../myrocks-system-variables/index#rocksdb_supported_compression_types) |
| [Rocksdb\_system\_rows\_deleted](../myrocks-status-variables/index#rocksdb_system_rows_deleted) |
| [Rocksdb\_system\_rows\_inserted](../myrocks-status-variables/index#rocksdb_system_rows_inserted) |
| [Rocksdb\_system\_rows\_read](../myrocks-status-variables/index#rocksdb_system_rows_read) |
| [Rocksdb\_system\_rows\_updated](../myrocks-status-variables/index#rocksdb_system_rows_updated) |
| --[rocksdb-table-cache-numshardbits](../myrocks-system-variables/index#rocksdb_table_cache_numshardbits), [rocksdb\_table\_cache\_numshardbits](../myrocks-system-variables/index#rocksdb_table_cache_numshardbits) |
| --[rocksdb-table-stats-sampling-pct](../myrocks-system-variables/index#rocksdb_table_stats_sampling_pct), [rocksdb\_table\_stats\_sampling\_pct](../myrocks-system-variables/index#rocksdb_table_stats_sampling_pct) |
| --[rocksdb-tmpdir](../myrocks-system-variables/index#rocksdb_tmpdir), [rocksdb\_tmpdir](../myrocks-system-variables/index#rocksdb_tmpdir) |
| --[rocksdb-trace-sst-api](../myrocks-system-variables/index#rocksdb_trace_sst_api), [rocksdb\_trace\_sst\_api](../myrocks-system-variables/index#rocksdb_trace_sst_api) |
| --[rocksdb-two-write-queues](../myrocks-system-variables/index#rocksdb_two_write_queues), [rocksdb\_two\_write\_queues](../myrocks-system-variables/index#rocksdb_two_write_queues) |
| --[rocksdb-unsafe-for-binlog](../myrocks-system-variables/index#rocksdb_unsafe_for_binlog), [rocksdb\_unsafe\_for\_binlog](../myrocks-system-variables/index#rocksdb_unsafe_for_binlog) |
| --[rocksdb-update-cf-options](../myrocks-system-variables/index#rocksdb_update_cf_options), [rocksdb\_update\_cf\_options](../myrocks-system-variables/index#rocksdb_update_cf_options) |
| --[rocksdb-use-adaptive-mutex](../myrocks-system-variables/index#rocksdb_use_adaptive_mutex), [rocksdb\_use\_adaptive\_mutex](../myrocks-system-variables/index#rocksdb_use_adaptive_mutex) |
| --[rocksdb-use-clock-cache](../myrocks-system-variables/index#rocksdb_use_clock_cache), [rocksdb\_use\_clock\_cache](../myrocks-system-variables/index#rocksdb_use_clock_cache) |
| --[rocksdb-use-direct-io-for-flush-and-compaction](../myrocks-system-variables/index#rocksdb_use_direct_io_for_flush_and_compaction), [rocksdb\_use\_direct\_io\_for\_flush\_and\_compaction](../myrocks-system-variables/index#rocksdb_use_direct_io_for_flush_and_compaction) |
| --[rocksdb-use-direct-reads](../myrocks-system-variables/index#rocksdb_use_direct_reads), [rocksdb\_use\_direct\_reads](../myrocks-system-variables/index#rocksdb_use_direct_reads) |
| --[rocksdb-use-fsync](../myrocks-system-variables/index#rocksdb_use_fsync), [rocksdb\_use\_fsync](../myrocks-system-variables/index#rocksdb_use_fsync) |
| --[rocksdb-validate-tables](../myrocks-system-variables/index#rocksdb_validate_tables), [rocksdb\_validate\_tables](../myrocks-system-variables/index#rocksdb_validate_tables) |
| --[rocksdb-verify-row-debug-checksums](../myrocks-system-variables/index#rocksdb_verify_row_debug_checksums), [rocksdb\_verify\_row\_debug\_checksums](../myrocks-system-variables/index#rocksdb_verify_row_debug_checksums) |
| [Rocksdb\_wal\_bytes](../myrocks-status-variables/index#rocksdb_wal_bytes) |
| --[rocksdb-wal-bytes-per-sync](../myrocks-system-variables/index#rocksdb_wal_bytes_per_sync), [rocksdb\_wal\_bytes\_per\_sync](../myrocks-system-variables/index#rocksdb_wal_bytes_per_sync) |
| --[rocksdb-wal-dir](../myrocks-system-variables/index#rocksdb_wal_dir), [rocksdb\_wal\_dir](../myrocks-system-variables/index#rocksdb_wal_dir) |
| [Rocksdb\_wal\_group\_syncs](../myrocks-status-variables/index#rocksdb_wal_group_syncs) |
| --[rocksdb-wal-recovery-mode](../myrocks-system-variables/index#rocksdb_wal_recovery_mode), [rocksdb\_wal\_recovery\_mode](../myrocks-system-variables/index#rocksdb_wal_recovery_mode) |
| --[rocksdb-wal-size-limit-mb](../myrocks-system-variables/index#rocksdb_wal_size_limit_mb), [rocksdb\_wal\_size\_limit\_mb](../myrocks-system-variables/index#rocksdb_wal_size_limit_mb) |
| [Rocksdb\_wal\_synced](../myrocks-status-variables/index#rocksdb_wal_synced) |
| --[rocksdb-wal-ttl-seconds](../myrocks-system-variables/index#rocksdb_wal_ttl_seconds), [rocksdb\_wal\_ttl\_seconds](../myrocks-system-variables/index#rocksdb_wal_ttl_seconds) |
| --[rocksdb-whole-key-filtering](../myrocks-system-variables/index#rocksdb_whole_key_filtering), [rocksdb\_whole\_key\_filtering](../myrocks-system-variables/index#rocksdb_whole_key_filtering) |
| --[rocksdb-write-batch-max-bytes](../myrocks-system-variables/index#rocksdb_write_batch_max_bytes), [rocksdb\_write\_batch\_max\_bytes](../myrocks-system-variables/index#rocksdb_write_batch_max_bytes) |
| --[rocksdb-write-disable-wal](../myrocks-system-variables/index#rocksdb_write_disable_wal), [rocksdb\_write\_disable\_wal](../myrocks-system-variables/index#rocksdb_write_disable_wal) |
| --[rocksdb-write-ignore-missing-column-families](../myrocks-system-variables/index#rocksdb_write_ignore_missing_column_families), [rocksdb\_write\_ignore\_missing\_column\_families](../myrocks-system-variables/index#rocksdb_write_ignore_missing_column_families) |
| --[rocksdb-write-policy](../myrocks-system-variables/index#rocksdb_write_policy), [rocksdb\_write\_policy](../myrocks-system-variables/index#rocksdb_write_policy) |
| [Rocksdb\_write\_other](../myrocks-status-variables/index#rocksdb_write_other) |
| [Rocksdb\_write\_self](../myrocks-status-variables/index#rocksdb_write_self) |
| [Rocksdb\_write\_timedout](../myrocks-status-variables/index#rocksdb_write_timedout) |
| [Rocksdb\_write\_wal](../myrocks-status-variables/index#rocksdb_write_wal) |
| --[rowid-merge-buff-size](../server-system-variables/index#rowid_merge_buff_size), [rowid\_merge\_buff\_size](../server-system-variables/index#rowid_merge_buff_size) |
| [Resultset\_metadata\_skipped](../server-status-variables/index#resultset_metadata_skipped) |
| [Rows\_read](../server-status-variables/index#rows_read) |
| [Rows\_sent](../server-status-variables/index#rows_sent) |
| [Rows\_tmp\_read](../server-status-variables/index#rows_tmp_read) |
| --[rpl-recovery-rank](../server-system-variables/index#rpl_recovery_rank), [rpl\_recovery\_rank](../server-system-variables/index#rpl_recovery_rank) |
| [Rpl\_semi\_sync\_master\_clients](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_clients) |
| [rpl-semi-sync-master-enabled](../semisynchronous-replication/index#rpl_semi_sync_master_enabled) [rpl\_semi\_sync\_master\_enabled](../semisynchronous-replication/index#rpl_semi_sync_master_enabled) |
| [Rpl\_semi\_sync\_master\_net\_avg\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_net_avg_wait_time) |
| [Rpl\_semi\_sync\_master\_net\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_net_wait_time) |
| [Rpl\_semi\_sync\_master\_net\_waits](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_net_waits) |
| [Rpl\_semi\_sync\_master\_no\_times](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_times) |
| [Rpl\_semi\_sync\_master\_no\_tx](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_tx) |
| [Rpl\_semi\_sync\_master\_status](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_status) |
| [Rpl\_semi\_sync\_master\_timefunc\_failures](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_timefunc_failures) |
| [rpl-semi-sync-master-timeout](../semisynchronous-replication/index#rpl_semi_sync_master_timeout), [rpl\_semi\_sync\_master\_timeout](../semisynchronous-replication/index#rpl_semi_sync_master_timeout) |
| [rpl-semi-sync-master-trace-level](../semisynchronous-replication/index#rpl_semi_sync_master_trace_level) , [rpl\_semi\_sync\_master\_trace\_level](../semisynchronous-replication/index#rpl_semi_sync_master_trace_level) |
| [Rpl\_semi\_sync\_master\_tx\_avg\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_tx_avg_wait_time) |
| [Rpl\_semi\_sync\_master\_tx\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_tx_wait_time) |
| [Rpl\_semi\_sync\_master\_tx\_waits](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_tx_waits) |
| [rpl-semi-sync-master-wait-no-slave](../semisynchronous-replication/index#rpl_semi_sync_master_wait_no_slave), [rpl\_semi\_sync\_master\_wait\_no\_slave](../semisynchronous-replication/index#rpl_semi_sync_master_wait_no_slave) |
| [rpl-semi-sync-master-wait-point](../semisynchronous-replication/index#rpl_semi_sync_master_wait_point), [rpl\_semi\_sync\_master\_wait\_point](../semisynchronous-replication/index#rpl_semi_sync_master_wait_point) |
| [Rpl\_semi\_sync\_master\_wait\_pos\_backtraverse](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_wait_pos_backtraverse) |
| [Rpl\_semi\_sync\_master\_wait\_sessions](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_wait_sessions) |
| [Rpl\_semi\_sync\_master\_yes\_tx](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_yes_tx) |
| [rpl-semi-sync-slave-delay-master](../semisynchronous-replication/index#rpl_semi_sync_slave_delay_master), [rpl\_semi\_sync\_slave\_delay\_master](../semisynchronous-replication/index#rpl_semi_sync_slave_delay_master) |
| [rpl-semi-sync-slave-enabled](../semisynchronous-replication/index#rpl_semi_sync_slave_enabled), [rpl\_semi\_sync\_slave\_enabled](../semisynchronous-replication/index#rpl_semi_sync_slave_enabled) |
| [rpl-semi-sync-slave-kill-conn-timeout](../semisynchronous-replication/index#rpl_semi_sync_slave_kill_conn_timeout), [rpl\_semi\_sync\_slave\_kill\_conn\_timeout](../semisynchronous-replication/index#rpl_semi_sync_slave_kill_conn_timeout) |
| [Rpl\_semi\_sync\_slave\_status](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_slave_status) |
| [rpl-semi-sync-slave-trace-level](../semisynchronous-replication/index#rpl_semi_sync_slave_trace_level), [rpl\_semi\_sync\_slave\_trace\_level](../semisynchronous-replication/index#rpl_semi_sync_slave_trace_level) |
| [Rpl\_status](../replication-and-binary-log-server-status-variables/index#rpl_status) |
| [Rpl\_transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#rpl_transactions_multi_engine) |
| -s, --[symbolic-links](../mysqld-options/index#-symbolic-links) |
| --[s3-access-key](../s3-storage-engine-system-variables/index#s3_access_key), [s3\_access\_key](../s3-storage-engine-system-variables/index#s3_access_key) |
| --[s3-block-size](../s3-storage-engine-system-variables/index#s3_block_size), [s3\_block\_size](../s3-storage-engine-system-variables/index#s3_block_size) |
| --[s3-bucket](../s3-storage-engine-system-variables/index#s3_bucket), [s3\_bucket](../s3-storage-engine-system-variables/index#s3_bucket) |
| --[s3-debug](../s3-storage-engine-system-variables/index#s3_debug), [s3\_debug](../s3-storage-engine-system-variables/index#s3_debug) |
| --[s3-host-name](../s3-storage-engine-system-variables/index#s3_host_name), [s3\_host\_name](../s3-storage-engine-system-variables/index#s3_host_name) |
| --[s3-pagecache-age-threshold](../s3-storage-engine-system-variables/index#s3_pagecache_age_threshold), [s3\_pagecache\_age\_threshold](../s3-storage-engine-system-variables/index#s3_pagecache_age_threshold) |
| --[s3-pagecache-buffer-size](../s3-storage-engine-system-variables/index#s3_pagecache_buffer_size), [s3\_pagecache\_buffer\_size](../s3-storage-engine-system-variables/index#s3_pagecache_buffer_size) |
| --[s3-pagecache-division-limit](../s3-storage-engine-system-variables/index#s3_pagecache_division_limit), [s3\_pagecache\_division\_limit](../s3-storage-engine-system-variables/index#s3_pagecache_division_limit) |
| --[s3-pagecache-file-hash-size](../s3-storage-engine-system-variables/index#s3_pagecache_file_hash_size), [s3\_pagecache\_file\_hash\_size](../s3-storage-engine-system-variables/index#s3_pagecache_file_hash_size) |
| --[s3-port](../s3-storage-engine-system-variables/index#s3_port), [s3\_port](../s3-storage-engine-system-variables/index#s3_port) |
| --[s3-protocol-version](../s3-storage-engine-system-variables/index#s3_protocol_version), [s3\_protocol\_version](../s3-storage-engine-system-variables/index#s3_protocol_version) |
| --[s3-region](../s3-storage-engine-system-variables/index#s3_region), [s3\_region](../s3-storage-engine-system-variables/index#s3_region) |
| --[s3-secret-key](../s3-storage-engine-system-variables/index#s3_secret_key), [s3\_secret\_key](../s3-storage-engine-system-variables/index#s3_secret_key) |
| --[s3-slave-ignore-updates](../s3-storage-engine-system-variables/index#s3_slave_ignore_updates), [s3\_slave\_ignore\_updates](../s3-storage-engine-system-variables/index#s3_slave_ignore_updates) |
| --[s3-use\_http](../s3-storage-engine-system-variables/index#s3_use_http), [s3\_use\_http](../s3-storage-engine-system-variables/index#s3_use_http) |
| --[safe-mode](../mysqld-options/index#-safe-mode) |
| --[safe-show-database](../server-system-variables/index#safe_show_database), [safe\_show\_database](../server-system-variables/index#safe_show_database) |
| --[safe-user-create](../mysqld-options/index#-safe-user-create) |
| --[safemalloc-mem-limit](../mysqld-options/index#-safemalloc-mem-limit) |
| --[secure-auth](../server-system-variables/index#secure_auth), [secure\_auth](../server-system-variables/index#secure_auth) |
| --[secure-file-priv](../server-system-variables/index#secure_file_priv), [secure\_file\_priv](../server-system-variables/index#secure_file_priv) |
| --[secure-timestamp](../server-system-variables/index#secure_timestamp), [secure\_timestamp](../server-system-variables/index#secure_timestamp) |
| [Select\_full\_join](../server-status-variables/index#select_full_join) |
| [Select\_full\_range\_join](../server-status-variables/index#select_full_range_join) |
| [Select\_range](../server-status-variables/index#select_range) |
| [Select\_range\_check](../server-status-variables/index#select_range_check) |
| [Select\_scan](../server-status-variables/index#select_scan) |
| --[server-audit](../mariadb-audit-plugin-options-and-system-variables/index#server_audit) |
| [Server\_audit\_active](../server_audit-status-variables/index#server_audit_active) |
| [Server\_audit\_current\_log](../server_audit-status-variables/index#server_audit_current_log) |
| --[server-audit-events](../server_audit-system-variables/index#server_audit_events), [server\_audit\_events](../server_audit-system-variables/index#server_audit_events) |
| --[server-audit-excl-users](../server_audit-system-variables/index#server_audit_excl_users), [server\_audit\_excl\_users](../server_audit-system-variables/index#server_audit_excl_users) |
| --[server-audit-file-path](../server_audit-system-variables/index#server_audit_file_path), [server\_audit\_file\_path](../server_audit-system-variables/index#server_audit_file_path) |
| [Server\_audit\_last\_error](../server_audit-status-variables/index#server_audit_last_error) |
| --[server-audit-file-rotate-now](../server_audit-system-variables/index#server_audit_file_rotate_now), [server\_audit\_file\_rotate\_now](../server_audit-system-variables/index#server_audit_file_rotate_now) |
| --[server-audit-file-rotate-size](../server_audit-system-variables/index#server_audit_file_rotate_size), [server\_audit\_file\_rotate\_size](../server_audit-system-variables/index#server_audit_file_rotate_size) |
| --[server-audit-file-rotations](../server_audit-system-variables/index#server_audit_file_rotations), [server\_audit\_file\_rotations](../server_audit-system-variables/index#server_audit_file_rotations) |
| --[server-audit-incl-users](../server_audit-system-variables/index#server_audit_incl_users), [server\_audit\_incl\_users](../server_audit-system-variables/index#server_audit_incl_users) |
| --[server-audit-loc-info](../server_audit-system-variables/index#server_audit_loc_info), [server\_audit\_loc\_info](../server_audit-system-variables/index#server_audit_loc_info) |
| --[server-audit-logging](../server_audit-system-variables/index#server_audit_logging), [server\_audit\_logging](../server_audit-system-variables/index#server_audit_logging) |
| --[server-audit-mode](../server_audit-system-variables/index#server_audit_mode), [server\_audit\_mode](../server_audit-system-variables/index#server_audit_mode) |
| --[server-audit-output-type](../server_audit-system-variables/index#server_audit_output_type), [server\_audit\_output\_type](../server_audit-system-variables/index#server_audit_output_type) |
| --[server-audit-query-limit](../server_audit-system-variables/index#server_audit_query_limit), [server\_audit\_query\_limit](../server_audit-system-variables/index#server_audit_query_limit) |
| --[server-audit-syslog-facility](../server_audit-system-variables/index#server_audit_syslog_facility), [server\_audit\_syslog\_facility](../server_audit-system-variables/index#server_audit_syslog_facility) |
| --[server-audit-syslog-ident](../server_audit-system-variables/index#server_audit_syslog_ident), [server\_audit\_syslog\_ident](../server_audit-system-variables/index#server_audit_syslog_ident) |
| --[server-audit-syslog-info](../server_audit-system-variables/index#server_audit_syslog_info), [server\_audit\_syslog\_info](../server_audit-system-variables/index#server_audit_syslog_info) |
| --[server-audit-syslog-priority](../server_audit-system-variables/index#server_audit_syslog_priority), [server\_audit\_syslog\_priority](../server_audit-system-variables/index#server_audit_syslog_priority) |
| [Server\_audit\_writes\_failed](../server_audit-status-variables/index#server_audit_writes_failed) |
| --[server-id](../replication-and-binary-log-server-system-variables/index#server_id), [server\_id](../replication-and-binary-log-server-system-variables/index#server_id) |
| --[session-track-schema](../server-system-variables/index#session_track_schema), [session\_track\_schema](../server-system-variables/index#session_track_schema) |
| --[session-track-state-change](../server-system-variables/index#session_track_state_change), [session\_track\_state\_change](../server-system-variables/index#session_track_state_change) |
| --[session-track-system-variables](../server-system-variables/index#session_track_system_variables), [session\_track\_system\_variables](../server-system-variables/index#session_track_system_variables) |
| --[session-track-transaction-info](../server-system-variables/index#session_track_transaction_info), [session\_track\_transaction\_info](../server-system-variables/index#session_track_transaction_info) |
| -O, --[set-variable](../mysqld-options/index#-set-variable) |
| [shared\_memory](../server-system-variables/index#shared_memory) |
| [shared\_memory\_base\_name](../server-system-variables/index#shared_memory_base_name) |
| --[show\_old\_temporals](../server-system-variables/index#show_old_temporals), [show\_old\_temporals](../server-system-variables/index#show_old_temporals) |
| --[show-slave-auth-info](../mysqld-options/index#-show-slave-auth-info) |
| --[silent-startup](../mysqld-options/index#-silent-startup) |
| --[simple-password-check-digits](../simple_password_check/index#simple_password_check_digits), [simple\_password\_check\_digits](../simple_password_check/index#simple_password_check_digits) |
| --[simple\_password-check-letters-same-case](../simple_password_check/index#simple_password_check_letters_same_case), [simple\_password\_check\_letters\_same\_case](../simple_password_check/index#simple_password_check_letters_same_case) |
| --[simple-password-check-minimal\_length](../simple_password_check/index#simple_password_check_minimal_length), [simple\_password\_check\_minimal\_length](../simple_password_check/index#simple_password_check_minimal_length) |
| --[simple\_password-check-other-characters](../simple_password_check/index#simple_password_check_other_characters), [simple\_password\_check\_other\_characters](../simple_password_check/index#simple_password_check_other_characters) |
| --[skip-automatic-sp-privileges](../server-system-variables/index#automatic_sp_privileges) |
| --[skip-bdb](../mysqld-options/index#-skip-bdb) |
| --[skip-external-locking](../server-system-variables/index#skip_external_locking), [skip\_external\_locking](../server-system-variables/index#skip_external_locking) |
| --[skip-grant-tables](../mysqld-options/index#-skip-grant-tables), [skip\_grant\_tables](../server-system-variables/index#skip_grant_tables) |
| --[skip-host-cache](../mysqld-options/index#-skip-host-cache) |
| --[skip-innodb](../mysqld-options/index#-innodb) |
| --[skip-innodb-checksums](../innodb-system-variables/index#innodb_checksums) |
| --[skip-innodb-doublewrite](../innodb-system-variables/index#innodb_doublewrite) |
| --[skip-large-pages](../server-system-variables/index#large_pages) |
| --[skip-log-error](../server-system-variables/index#log_error) |
| --[skip-name-resolve](../server-system-variables/index#skip_name_resolve), [skip\_name\_resolve](../server-system-variables/index#skip_name_resolve) |
| --[skip-new](../mysqld-options/index#-skip-new) |
| --[skip-networking](../server-system-variables/index#skip_networking), [skip\_networking](../server-system-variables/index#skip_networking) |
| [skip\_parallel\_replication](../replication-and-binary-log-server-system-variables/index#skip_parallel_replication) |
| --[skip-partition](../mysqld-options/index#-skip-partition) |
| [skip\_replication](../replication-and-binary-log-server-system-variables/index#skip_replication) |
| --[skip-show-database](../server-system-variables/index#skip_show_database), [skip\_show\_database](../server-system-variables/index#skip_show_database) |
| --[skip-slave-start](../mysqld-options/index#-skip-slave-start) |
| --[skip-ssl](../mysqld-options/index#-skip-ssl) |
| --[skip-stack-trace](../mysqld-options/index#-skip-stack-trace) |
| --[skip-symbolic-links](../mysqld-options/index#-skip-symbolic-links) |
| --[skip-symlink](../mysqld-options/index#-skip-symlink) |
| --[skip-thread-priority](../mysqld-options/index#-skip-thread-priority) |
| --[slave-compressed-protocol](../replication-and-binary-log-server-system-variables/index#slave_compressed_protocol), [slave\_compressed\_protocol](../replication-and-binary-log-server-system-variables/index#slave_compressed_protocol) |
| [Slave\_connections](../replication-and-binary-log-server-status-variables/index#slave_connections) |
| --[slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode), [slave\_ddl\_exec\_mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode) |
| --[slave-domain-parallel-threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads), [slave\_domain\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads) |
| --[slave-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_exec_mode), [slave\_exec\_mode](../replication-and-binary-log-server-system-variables/index#slave_exec_mode) |
| [Slave\_heartbeat\_period](../replication-and-binary-log-server-status-variables/index#slave_heartbeat_period) |
| --[slave-load-tmpdir](../replication-and-binary-log-server-system-variables/index#slave_load_tmpdir), [slave\_load\_tmpdir](../replication-and-binary-log-server-system-variables/index#slave_load_tmpdir) |
| --[slave-max-allowed-packet](../replication-and-binary-log-server-system-variables/index#slave_max_allowed_packet), [slave\_max\_allowed\_packet](../replication-and-binary-log-server-system-variables/index#slave_max_allowed_packet) |
| --[slave-net-timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout), [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) |
| [Slave\_open\_temp\_tables](../replication-and-binary-log-server-status-variables/index#slave_open_temp_tables) |
| --[slave-parallel-max-queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued), [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) |
| [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) |
| --[slave-parallel-threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads), [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) |
| --[slave-parallel-workers](../replication-and-binary-log-server-system-variables/index#slave_parallel_workers), [slave\_parallel\_workers](../replication-and-binary-log-server-system-variables/index#slave_parallel_workers) |
| [Slave\_received\_heartbeats](../replication-and-binary-log-server-status-variables/index#slave_received_heartbeats) |
| [Slave\_retried\_transactions](../replication-and-binary-log-server-status-variables/index#slave_retried_transactions) |
| [slave\_run\_triggers\_for\_rbr](../replication-and-binary-log-server-system-variables/index#slave_run_triggers_for_rbr), [slave-run-triggers-for-rbr](../replication-and-binary-log-server-system-variables/index#slave_run_triggers_for_rbr) |
| [Slave\_running](../replication-and-binary-log-server-status-variables/index#slave_running) |
| --[slave-skip-errors](../replication-and-binary-log-server-system-variables/index#slave_skip_errors), [slave\_skip\_errors](../replication-and-binary-log-server-system-variables/index#slave_skip_errors) |
| [Slave\_skipped\_errors](../replication-and-binary-log-server-status-variables/index#slave_skipped_errors) |
| --[slave-sql-verify-checksum](../replication-and-binary-log-server-system-variables/index#slave_sql_verify_checksum), [slave\_sql\_verify\_checksum](../replication-and-binary-log-server-system-variables/index#slave_sql_verify_checksum) |
| --[slave-transaction-retries](../replication-and-binary-log-server-system-variables/index#slave_transaction_retries), [slave\_transaction\_retries](../replication-and-binary-log-server-system-variables/index#slave_transaction_retries) |
| --[slave-transaction-retry-errors](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_errors), [slave\_transaction\_retry\_errors](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_errors) |
| --[slave-transaction-retry-interval](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_interval), [slave\_transaction\_retry\_interval](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_interval) |
| --[slave-type-conversions](../replication-and-binary-log-server-system-variables/index#slave_type_conversions), [slave\_type\_conversions](../replication-and-binary-log-server-system-variables/index#slave_type_conversions) |
| [Slaves\_connected](../replication-and-binary-log-server-status-variables/index#slaves_connected) |
| [Slaves\_running](../replication-and-binary-log-server-status-variables/index#slaves_running) |
| [Slow\_launch\_threads](../server-status-variables/index#slow_launch_threads) |
| --[slow-launch-time](../server-system-variables/index#slow_launch_time), [slow\_launch\_time](../server-system-variables/index#slow_launch_time) |
| [Slow\_queries](../server-status-variables/index#slow_queries) |
| --[slow-query-log](../server-system-variables/index#slow_query_log), [slow\_query\_log](../server-system-variables/index#slow_query_log) |
| --[slow-query-log-file](../server-system-variables/index#slow_query_log_file), [slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file) |
| --[slow-start-timeout](../mysqld-options/index#-slow-start-timeout) |
| --[socket](../server-system-variables/index#socket), [socket](../server-system-variables/index#socket) |
| --[sort-buffer-size](../server-system-variables/index#sort_buffer_size), [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size) |
| [Sort\_merge\_passes](../server-status-variables/index#sort_merge_passes) |
| [Sort\_priority\_queue\_sorts](../server-status-variables/index#sort_priority_queue_sorts) |
| [Sort\_range](../server-status-variables/index#sort_range) |
| [Sort\_rows](../server-status-variables/index#sort_rows) |
| [Sort\_scan](../server-status-variables/index#sort_scan) |
| [Sphinx\_error](../sphinx-status-variables/index#sphinx_error) |
| [Sphinx\_time](../sphinx-status-variables/index#sphinx_time) |
| [Sphinx\_total](../sphinx-status-variables/index#sphinx_total) |
| [Sphinx\_total\_found](../sphinx-status-variables/index#sphinx_total_found) |
| [Sphinx\_word\_count](../sphinx-status-variables/index#sphinx_word_count) |
| [Sphinx\_words](../sphinx-status-variables/index#sphinx_words) |
| [spider\_auto\_increment\_mode](../spider-server-system-variables/index#spider_auto_increment_mode) |
| [spider\_bgs\_first\_read](../spider-server-system-variables/index#spider_bgs_first_read) |
| [spider\_bgs\_mode](../spider-server-system-variables/index#spider_bgs_mode) |
| [spider\_bgs\_second\_read](../spider-server-system-variables/index#spider_bgs_second_read) |
| [spider\_bka\_engine](../spider-server-system-variables/index#spider_bka_engine) |
| [spider\_bka\_mode](../spider-server-system-variables/index#spider_bka_mode) |
| [spider\_block\_size](../spider-server-system-variables/index#spider_block_size) |
| [spider\_buffer\_size](../spider-server-system-variables/index#spider_buffer_size) |
| [spider\_bulk\_size](../spider-server-system-variables/index#spider_bulk_size) |
| [spider\_bulk\_update\_mode](../spider-server-system-variables/index#spider_bulk_update_mod) |
| [spider\_bulk\_update\_size](../spider-server-system-variables/index#spider_bulk_update_size) |
| [spider\_casual\_read](../spider-server-system-variables/index#spider_casual_read) |
| [spider\_conn\_recycle\_mode](../spider-server-system-variables/index#spider_conn_recycle_mode) |
| [spider\_conn\_recycle\_strict](../spider-server-system-variables/index#spider_conn_recycle_strict) |
| [spider\_conn\_wait\_timeout](../spider-server-system-variables/index#spider_conn_wait_timeout) |
| [spider\_connect\_error\_interval](../spider-server-system-variables/index#spider_connect_error_interval) |
| [spider\_connect\_mutex](../spider-server-system-variables/index#spider_connect_mutex) |
| [spider\_connect\_retry\_count](../spider-server-system-variables/index#spider_connect_retry_count) |
| [spider\_connect\_retry\_interval](../spider-server-system-variables/index#spider_connect_retry_interval) |
| [spider\_connect\_timeout](../spider-server-system-variables/index#spider_connect_timeout) |
| [spider\_crd\_bg\_mode](../spider-server-system-variables/index#spider_crd_bg_mode) |
| [spider\_crd\_interval](../spider-server-system-variables/index#spider_crd_interval) |
| [spider\_crd\_mode](../spider-server-system-variables/index#spider_crd_mode) |
| [spider\_crd\_sync](../spider-server-system-variables/index#spider_crd_sync) |
| [spider\_crd\_type](../spider-server-system-variables/index#spider_crd_type) |
| [spider\_crd\_weight](../spider-server-system-variables/index#spider_crd_weight) |
| [spider\_delete\_all\_rows\_type](../spider-server-system-variables/index#spider_delete_all_rows_type) |
| [Spider\_direct\_aggregate](../spider-server-status-variables/index#spider_direct_aggregate) |
| [Spider\_direct\_delete](../spider-server-status-variables/index#spider_direct_delete) |
| [spider\_direct\_dup\_insert](../spider-server-system-variables/index#spider_direct_dup_insert) |
| [spider\_direct\_order\_limit](../spider-server-system-variables/index#spider_direct_order_limit) |
| [Spider\_direct\_order\_limit](../spider-server-status-variables/index#spider_direct_order_limit) |
| [Spider\_direct\_update](../spider-server-status-variables/index#spider_direct_update) |
| [spider\_dry\_access](../spider-server-system-variables/index#spider_dry_access) |
| [spider\_error\_read\_mode](../spider-server-system-variables/index#spider_error_read_mode) |
| [spider\_error\_write\_mode](../spider-server-system-variables/index#spider_error_write_mode) |
| [spider\_first\_read](../spider-server-system-variables/index#spider_first_read) |
| [spider\_force\_commit](../spider-server-system-variables/index#spider_force_commit) |
| [spider\_general\_log](../spider-server-system-variables/index#spider_general_log) |
| [spider\_index\_hint\_pushdown](../spider-server-system-variables/index#spider_index_hint_pushdown) |
| [spider\_init\_sql\_alloc\_size](../spider-server-system-variables/index#spider_init_sql_alloc_size) |
| [spider\_internal\_limit](../spider-server-system-variables/index#spider_internal_limit) |
| [spider\_internal\_offset](../spider-server-system-variables/index#spider_internal_offset) |
| [spider\_internal\_optimize](../spider-server-system-variables/index#spider_internal_optimize) |
| [spider\_internal\_optimize\_local](../spider-server-system-variables/index#spider_internal_optimize_local) |
| [spider\_internal\_sql\_log\_off](../spider-server-system-variables/index#spider_internal_sql_log_off) |
| [spider\_internal\_unlock](../spider-server-system-variables/index#spider_internal_unlock) |
| [spider\_internal\_xa](../spider-server-system-variables/index#spider_internal_xa) |
| [spider\_internal\_xa\_id\_type](../spider-server-system-variables/index#spider_internal_xa_id_type) |
| [spider\_internal\_xa\_snapshot](../spider-server-system-variables/index#spider_internal_xa_snapshot) |
| [spider\_load\_crd\_at\_startup](../spider-server-system-variables/index#spider_load_crd_at_startup) |
| [spider\_load\_sts\_at\_startup](../spider-server-system-variables/index#spider_load_sts_at_startup) |
| [spider\_local\_lock\_table](../spider-server-system-variables/index#spider_local_lock_table) |
| [spider\_lock\_exchange](../spider-server-system-variables/index#spider_lock_exchange) |
| [spider\_log\_result\_error\_with\_sql](../spider-server-system-variables/index#spider_log_result_error_with_sql) |
| [spider\_log\_result\_errors](../spider-server-system-variables/index#spider_log_result_errors) |
| [spider\_low\_mem\_read](../spider-server-system-variables/index#spider_low_mem_read) |
| [spider\_max\_connections](../spider-server-system-variables/index#spider_max_connections) |
| [spider\_max\_order](../spider-server-system-variables/index#spider_max_order) |
| [Spider\_mon\_table\_cache\_version](../spider-server-status-variables/index#spider_mon_table_cache_version) |
| [Spider\_mon\_table\_cache\_version\_req](../spider-server-status-variables/index#spider_mon_table_cache_version_req) |
| [spider\_multi\_split\_read](../spider-server-system-variables/index#spider_multi_split_read) |
| [spider\_net\_read\_timeout](../spider-server-system-variables/index#spider_net_read_timeout) |
| [spider\_net\_write\_timeout](../spider-server-system-variables/index#spider_net_write_timeout) |
| [Spider\_parallel\_search](../spider-server-status-variables/index#spider_parallel_search) |
| [spider\_ping\_interval\_at\_trx\_start](../spider-server-system-variables/index#spider_ping_interval_at_trx_start) |
| [spider\_quick\_mode](../spider-server-system-variables/index#spider_quick_mode) |
| [spider\_quick\_page\_byte](../spider-server-system-variables/index#spider_quick_page_byte) |
| [spider\_quick\_page\_size](../spider-server-system-variables/index#spider_quick_page_size) |
| [spider\_read\_only\_mode](../spider-server-system-variables/index#spider_read_only_mode) |
| [spider\_remote\_access\_charset](../spider-server-system-variables/index#spider_remote_access_charse) |
| [spider\_remote\_autocommit](../spider-server-system-variables/index#spider_remote_autocommit) |
| [spider\_remote\_default\_database](../spider-server-system-variables/index#spider_remote_default_database) |
| [spider\_remote\_sql\_log\_off](../spider-server-system-variables/index#spider_remote_sql_log_off) |
| [spider\_remote\_time\_zone](../spider-server-system-variables/index#spider_remote_time_zone) |
| [spider\_remote\_trx\_isolation](../spider-server-system-variables/index#spider_remote_trx_isolation) |
| [spider\_remote\_wait\_timeout](../spider-server-system-variables/index#spider_remote_wait_timeout) |
| [spider\_reset\_sql\_alloc](../spider-server-system-variables/index#spider_reset_sql_alloc) |
| [spider\_same\_server\_link](../spider-server-system-variables/index#spider_same_server_link) |
| [spider\_second\_read](../spider-server-system-variables/index#spider_second_read) |
| [spider\_select\_column\_mode](../spider-server-system-variables/index#spider_select_column_mode) |
| [spider\_selupd\_lock\_mode](../spider-server-system-variables/index#spider_selupd_lock_mode) |
| [spider\_semi\_split\_read](../spider-server-system-variables/index#spider_semi_split_read) |
| [spider\_semi\_split\_read\_limit](../spider-server-system-variables/index#spider_semi_split_read_limit) |
| [spider\_semi\_table\_lock](../spider-server-system-variables/index#spider_semi_table_lock) |
| [spider\_semi\_table\_lock\_connection](../spider-server-system-variables/index#spider_semi_table_lock_connection) |
| [spider\_semi\_trx](../spider-server-system-variables/index#spider_semi_trx) |
| [spider\_semi\_trx\_isolation](../spider-server-system-variables/index#spider_semi_trx_isolation) |
| [spider\_skip\_default\_condition](../spider-server-system-variables/index#spider_skip_default_condition) |
| [spider\_skip\_parallel\_search](../spider-server-system-variables/index#spider_skip_parallel_search) |
| [spider\_slave\_trx\_isolation](../spider-server-system-variables/index#spider_slave_trx_isolation) |
| [spider\_split\_read](../spider-server-system-variables/index#spider_split_read) |
| [spider\_store\_last\_crd](../spider-server-system-variables/index#spider_store_last_crd) |
| [spider\_store\_last\_sts](../spider-server-system-variables/index#spider_store_last_sts) |
| [spider\_strict\_group\_by](../spider-server-system-variables/index#spider_strict_group_by) |
| [spider\_sts\_bg\_mode](../spider-server-system-variables/index#spider_sts_bg_mode) |
| [spider\_sts\_interval](../spider-server-system-variables/index#spider_sts_interval) |
| [spider\_sts\_mode](../spider-server-system-variables/index#spider_sts_mode) |
| [spider\_sts\_sync](../spider-server-system-variables/index#spider_sts_sync) |
| [spider\_support\_xa](../spider-server-system-variables/index#spider_support_xa) |
| [spider\_sync\_autocommit](../spider-server-system-variables/index#spider_sync_autocommit) |
| [spider\_sync\_sql\_mode](../spider-server-system-variables/index#spider_sync_sql_mode) |
| [spider\_sync\_time\_zone](../spider-server-system-variables/index#spider_sync_time_zone) |
| [spider\_sync\_trx\_isolation](../spider-server-system-variables/index#spider_sync_trx_isolation) |
| [spider\_table\_crd\_thread\_count](../spider-server-system-variables/index#spider_table_crd_thread_count) |
| [spider\_table\_init\_error\_interval](../spider-server-system-variables/index#spider_table_init_error_interval) |
| [spider\_table\_sts\_thread\_count](../spider-server-system-variables/index#spider_table_sts_thread_count) |
| [spider\_udf\_ct\_bulk\_insert\_interval](../spider-server-system-variables/index#spider_udf_ct_bulk_insert_interval) |
| [spider\_udf\_ct\_bulk\_insert\_rows](../spider-server-system-variables/index#spider_udf_ct_bulk_insert_rows) |
| [spider\_udf\_ds\_bulk\_insert\_rows](../spider-server-system-variables/index#spider_udf_ds_bulk_insert_rows) |
| [spider\_udf\_ds\_table\_loop\_mode](../spider-server-system-variables/index#spider_udf_ds_table_loop_mode) |
| [spider\_udf\_ds\_use\_real\_table](../spider-server-system-variables/index#spider_udf_ds_use_real_table) |
| [spider\_udf\_table\_lock\_mutex\_count](../spider-server-system-variables/index#spider_udf_table_lock_mutex_count) |
| [spider\_udf\_table\_mon\_mutex\_count](../spider-server-system-variables/index#spider_udf_table_mon_mutex_count) |
| [spider\_use\_all\_conns\_snapshot](../spider-server-system-variables/index#spider_use_all_conns_snapshot) |
| [spider\_use\_cond\_other\_than\_pk\_for\_update](../spider-server-system-variables/index#spider_use_cond_other_than_pk_for_update) |
| [spider\_use\_consistent\_snapshot](../spider-server-system-variables/index#spider_use_consistent_snapshot) |
| [spider\_use\_default\_database](../spider-server-system-variables/index#spider_use_default_database) |
| [spider\_use\_flash\_logs](../spider-server-system-variables/index#spider_use_flash_logs) |
| [spider\_use\_handler](../spider-server-system-variables/index#spider_use_handler) |
| [spider\_use\_pushdown\_udf](../spider-server-system-variables/index#spider_use_pushdown_udf) |
| [spider\_use\_table\_charset](../spider-server-system-variables/index#spider_use_table_charset) |
| [spider\_version](../spider-server-system-variables/index#spider_version) |
| [spider\_wait\_timeout](../spider-server-system-variables/index#spider_wait_timeout) |
| [spider\_xa\_register\_mode](../spider-server-system-variables/index#spider_xa_register_mode) |
| --[sporadic-binlog-dump-fail](../mysqld-options/index#-sporadic-binlog-dump-fail) |
| [sql\_auto\_is\_null](../server-system-variables/index#sql_auto_is_null) |
| [sql\_big\_selects](../server-system-variables/index#sql_big_selects) |
| [sql\_big\_tables](../server-system-variables/index#sql_big_tables) |
| [sql\_buffer\_result](../server-system-variables/index#sql_buffer_result) |
| --[sql-bin-update-same](../mysqld-options/index#-sql-bin-update-same) |
| --[sql-error-log-filename](../sql-error-log-plugin/index#sql_error_log_filename), [sql\_error\_log\_filename](../sql-error-log-plugin/index#sql_error_log_filename) |
| --[sql-error-log-rate](../sql-error-log-plugin/index#sql_error_log_rate), [sql\_error\_log\_rate](../sql-error-log-plugin/index#sql_error_log_rate) |
| --[sql-error-log-rotate](../sql-error-log-plugin/index#sql_error_log_rotate), [sql\_error\_log\_rotate](../sql-error-log-plugin/index#sql_error_log_rotate) |
| --[sql-error-log-rotations](../sql-error-log-plugin/index#sql_error_log_rotations), [sql\_error\_log\_rotations](../sql-error-log-plugin/index#sql_error_log_rotations) |
| --[sql-error-log-size-limit](../sql-error-log-plugin/index#sql_error_log_size_limit), [sql\_error\_log\_size\_limit](../sql-error-log-plugin/index#sql_error_log_size_limit) |
| --[sql-if-exists](../server-system-variables/index#sql_if_exists), [sql\_if\_exists](../server-system-variables/index#sql_if_exists) |
| [sql\_log\_bin](../replication-and-binary-log-server-system-variables/index#sql_log_bin) |
| [sql\_log\_off](../server-system-variables/index#sql_log_off) |
| [sql\_log\_update](../server-system-variables/index#sql_log_update) |
| [sql\_low\_priority\_updates](../server-system-variables/index#sql_low_priority_updates) |
| [sql\_max\_join\_size](../server-system-variables/index#sql_max_join_size) |
| --[sql-mode](../server-system-variables/index#sql_mode), [sql\_mode](../server-system-variables/index#sql_mode) |
| [sql\_notes](../server-system-variables/index#sql_notes) |
| [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) |
| --[sql-safe-updates](../server-system-variables/index#sql_safe_updates), [sql\_safe\_updates](../server-system-variables/index#sql_safe_updates) |
| [sql\_select\_limit](../server-system-variables/index#sql_select_limit) |
| [sql\_slave\_skip\_counter](../replication-and-binary-log-server-system-variables/index#sql_slave_skip_counter) |
| [sql\_warnings](../server-system-variables/index#sql_warnings) |
| --[ssl](../mysqld-options/index#-ssl) |
| [Ssl\_accept\_renegotiates](../ssl-status-variables/index#ssl_accept_renegotiates) |
| [Ssl\_accepts](../ssl-status-variables/index#ssl_accepts) |
| --[ssl-ca](../ssl-server-system-variables/index#ssl-ca), [ssl\_ca](../ssl-server-system-variables/index#ssl_ca) |
| [Ssl\_callback\_cache\_hits](../ssl-status-variables/index#ssl_callback_cache_hits) |
| --[ssl-capath](../ssl-server-system-variables/index#ssl_capath), [ssl\_capath](../ssl-server-system-variables/index#ssl_capath) |
| --[ssl-cert](../ssl-server-system-variables/index#ssl_cert), [ssl\_cert](../ssl-server-system-variables/index#ssl_cert) |
| --[ssl-cipher](../ssl-server-system-variables/index#ssl_cipher), [ssl\_cipher](../ssl-server-system-variables/index#ssl_cipher) |
| [Ssl\_cipher](../ssl-status-variables/index#ssl_cipher) |
| [Ssl\_cipher\_list](../ssl-status-variables/index#ssl_cipher_list) |
| [Ssl\_client\_connects](../ssl-status-variables/index#ssl_client_connects) |
| [Ssl\_connect\_renegotiates](../ssl-status-variables/index#ssl_connect_renegotiates) |
| --[ssl-crl](../ssl-server-system-variables/index#ssl_crl), [ssl\_crl](../ssl-server-system-variables/index#ssl_crl) |
| --[ssl-crlpath](../ssl-server-system-variables/index#ssl_crlpath), [ssl\_crlpath](../ssl-server-system-variables/index#ssl_crlpath) |
| [Ssl\_ctx\_verify\_depth](../ssl-status-variables/index#ssl_ctx_verify_depth) |
| [Ssl\_ctx\_verify\_mode](../ssl-status-variables/index#ssl_ctx_verify_mode) |
| [Ssl\_default\_timeout](../ssl-status-variables/index#ssl_default_timeout) |
| [Ssl\_finished\_accepts](../ssl-status-variables/index#ssl_finished_accepts) |
| [Ssl\_finished\_connects](../ssl-status-variables/index#ssl_finished_connects) |
| --[ssl-key](../ssl-server-system-variables/index#ssl_key), [ssl\_key](../ssl-server-system-variables/index#ssl_key) |
| [Ssl\_server\_not\_after](../ssl-status-variables/index#ssl_server_not_after) |
| [Ssl\_server\_not\_before](../ssl-status-variables/index#ssl_server_not_before) |
| [Ssl\_session\_cache\_hits](../ssl-status-variables/index#ssl_session_cache_hits) |
| [Ssl\_session\_cache\_misses](../ssl-status-variables/index#ssl_session_cache_misses) |
| [Ssl\_session\_cache\_mode](../ssl-status-variables/index#ssl_session_cache_mode) |
| [Ssl\_session\_cache\_overflows](../ssl-status-variables/index#ssl_session_cache_overflows) |
| [Ssl\_session\_cache\_size](../ssl-status-variables/index#ssl_session_cache_size) |
| [Ssl\_session\_cache\_timeouts](../ssl-status-variables/index#ssl_session_cache_timeouts) |
| [Ssl\_sessions\_reused](../ssl-status-variables/index#ssl_sessions_reused) |
| [Ssl\_used\_session\_cache\_entries](../ssl-status-variables/index#ssl_used_session_cache_entries) |
| [Ssl\_verify\_depth](../ssl-status-variables/index#ssl_verify_depth) |
| [Ssl\_verify\_mode](../ssl-status-variables/index#ssl_verify_mode) |
| --[standard-compliant-cte](../server-system-variables/index#standard_compliant_cte), [standard\_compliant\_cte](../server-system-variables/index#standard_compliant_cte) |
| --[stack-trace](../mysqld-options/index#-stack-trace) |
| --[standalone](../mysqld-options/index#-standalone) |
| [storage\_engine](../server-system-variables/index#storage_engine) |
| --[stored-program-cache](../server-system-variables/index#stored_program_cache), [stored\_program\_cache](../server-system-variables/index#stored_program_cache) |
| --[strict-password-validation](../server-system-variables/index#strict_password_validation), [strict\_password\_validation](../server-system-variables/index#strict_password_validation) |
| [Subquery\_cache\_hit](../server-status-variables/index#subquery_cache_hit) |
| [Subquery\_cache\_miss](../server-status-variables/index#subquery_cache_miss) |
| -s, --[symbolic-links](../mysqld-options/index#-symbolic-links) |
| --[sync-binlog](../replication-and-binary-log-server-system-variables/index#sync_binlog), [sync\_binlog](../replication-and-binary-log-server-system-variables/index#sync_binlog) |
| --[sync-frm](../server-system-variables/index#sync_frm), [sync\_frm](../server-system-variables/index#sync_frm) |
| --[sync-master-info](../replication-and-binary-log-server-system-variables/index#sync_master_info), [sync\_master\_info](../replication-and-binary-log-server-system-variables/index#sync_master_info) |
| --[sync-relay-log](../replication-and-binary-log-server-system-variables/index#sync_relay_log), [sync\_relay\_log](../replication-and-binary-log-server-system-variables/index#sync_relay_log) |
| --[sync-relay-log-info](../replication-and-binary-log-server-system-variables/index#sync_relay_log_info), [sync\_relay\_log\_info](../replication-and-binary-log-server-system-variables/index#sync_relay_log_info) |
| --[sync-sys](../mysqld-options/index#-sync-sys) |
| [Syncs](../server-status-variables/index#syncs) |
| --[sysdate-is-now](../mysqld-options/index#-sysdate-is-now) |
| -T, --[exit-info](../mysqld-options-full-list/index#-exit-info) |
| --[system\_time\_zone](../server-system-variables/index#system_time_zone) |
| --[system-versioning-alter-history](../system-versioned-tables/index#system_versioning_alter_history), [system\_versioning\_alter\_history](../system-versioned-tables/index#system_versioning_alter_history) |
| [system\_versioning\_asof](../system-versioned-tables/index#system_versioning_asof) |
| --[system-versioning-innodb-algorithm-simple](../system-versioned-tables/index#system_versioning_innodb_algorithm_simple), [system\_versioning\_innodb\_algorithm\_simple](../system-versioned-tables/index#system_versioning_innodb_algorithm_simple) |
| --[system-versioning-insert-history](../system-versioned-tables/index#system_versioning_insert_history), [system\_versioning\_insert\_history](../system-versioned-tables/index#system_versioning_insert_history) |
| --[table-cache](../mysqld-options/index#-table-cache) |
| --[table-definition-cache](../server-system-variables/index#table_definition_cache), [table\_definition\_cache](../server-system-variables/index#table_definition_cache) |
| --[table-lock-wait-timeout](../server-system-variables/index#table_lock_wait_timeout), [table\_lock\_wait\_timeout](../server-system-variables/index#table_lock_wait_timeout) |
| [Table\_locks\_immediate](../server-status-variables/index#table_locks_immediate) |
| [Table\_locks\_waited](../server-status-variables/index#table_locks_waited) |
| --[table-open-cache](../server-system-variables/index#table_open_cache), [table\_open\_cache](../server-system-variables/index#table_open_cache) |
| [Table\_open\_cache\_active\_instances](../server-status-variables/index#table_open_cache_active_instances) |
| [Table\_open\_cache\_hits](../server-status-variables/index#table_open_cache_hits) |
| --[table-open-cache-instances](../server-system-variables/index#table_open_cache_instances), [table\_open\_cache\_instances](../server-system-variables/index#table_open_cache_instances) |
| [Table\_open\_cache\_misses](../server-status-variables/index#table_open_cache_misses) |
| [Table\_open\_cache\_overflows](../server-status-variables/index#table_open_cache_overflows) |
| [table\_type](../server-system-variables/index#table_type) |
| --[tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover) |
| [Tc\_log\_max\_pages\_used](../server-status-variables/index#tc_log_max_pages_used) |
| [Tc\_log\_page\_size](../server-status-variables/index#tc_log_page_size) |
| [Tc\_log\_page\_waits](../server-status-variables/index#tc_log_page_waits) |
| --[tcp-keepalive-interval](../server-system-variables/index#tcp_keepalive_interval), [tcp\_keepalive\_interval](../server-system-variables/index#tcp_keepalive_interval) |
| --[tcp-keepalive-probes](../server-system-variables/index#tcp_keepalive_probes), [tcp\_keepalive\_probes](../server-system-variables/index#tcp_keepalive_probes) |
| --[tcp-keepalive-interval](../server-system-variables/index#tcp_keepalive_time), [tcp\_keepalive\_time](../server-system-variables/index#tcp_keepalive_time) |
| --[tcp-nodelay](../server-system-variables/index#tcp_nodelay), [tcp\_nodelay](../server-system-variables/index#tcp_nodelay) |
| --[temp-pool](../mysqld-options/index#-temp-pool) |
| --[test-expect-abort](../mysqld-options/index#-test-expect-abort) |
| --[test-ignore-wrong-options](../mysqld-options/index#-test-ignore-wrong-options) |
| --thread-alarm |
| --[thread-cache-size](../server-system-variables/index#thread_cache_size), [thread\_cache\_size](../server-system-variables/index#thread_cache_size) |
| --[thread-concurrency](../server-system-variables/index#thread_concurrency), [thread\_concurrency](../server-system-variables/index#thread_concurrency) |
| --[thread-handling](../thread-pool-system-and-status-variables/index#thread_handling), [thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling) |
| --[thread-pool-dedicated-listener](../thread-pool-system-and-status-variables/index#thread_pool_dedicated_listener), [thread\_pool\_dedicated\_listener](../thread-pool-system-and-status-variables/index#thread_pool_dedicated_listener) |
| --[thread-pool-exact-stats](../thread-pool-system-and-status-variables/index#thread_pool_exact_stats), [thread\_pool\_exact\_stats](../thread-pool-system-and-status-variables/index#thread_pool_exact_stats) |
| --[thread-pool-idle-timeout](../thread-pool-system-and-status-variables/index#thread_pool_idle_timeout), [thread\_pool\_idle\_timeout](../thread-pool-system-and-status-variables/index#thread_pool_idle_timeout) |
| --[thread-pool-max-threads](../thread-pool-system-and-status-variables/index#thread_pool_max_threads), [thread\_pool\_max\_threads](../thread-pool-system-and-status-variables/index#thread_pool_max_threads) |
| --[thread-pool-min-threads](../thread-pool-system-and-status-variables/index#thread_pool_min_threads), [thread\_pool\_min\_threads](../thread-pool-system-and-status-variables/index#thread_pool_min_threads) |
| [thread\_pool\_oversubscribe](../thread-pool-system-and-status-variables/index#thread_pool_oversubscribe) |
| --[thread-pool-prio-kickup-timer](../thread-pool-system-and-status-variables/index#thread_pool_prio_kickup_timer), [thread\_pool\_prio\_kickup\_timer](../thread-pool-system-and-status-variables/index#thread_pool_prio_kickup_timer) |
| --[thread-pool-priority](../thread-pool-system-and-status-variables/index#thread_pool_priority), [thread\_pool\_priority](../thread-pool-system-and-status-variables/index#thread_pool_priority) |
| --[thread-pool-size](../thread-pool-system-and-status-variables/index#thread_pool_size), [thread\_pool\_size](../thread-pool-system-and-status-variables/index#thread_pool_size) |
| --[thread-pool-stall-limit](../thread-pool-system-and-status-variables/index#thread_pool_stall_limit), [thread\_pool\_stall\_limit](../thread-pool-system-and-status-variables/index#thread_pool_stall_limit) |
| [Threadpool\_idle\_threads](../thread-pool-system-and-status-variables/index#threadpool_idle_threads) |
| [Threadpool\_threads](../thread-pool-system-and-status-variables/index#threadpool_threads) |
| --[thread-stack](../server-system-variables/index#thread_stack), [thread\_stack](../server-system-variables/index#thread_stack) |
| [Threads\_cached](../server-status-variables/index#threads_cached) |
| [Threads\_connected](../server-status-variables/index#threads_connected) |
| [Threads\_created](../server-status-variables/index#threads_created) |
| [Threads\_running](../server-status-variables/index#threads_running) |
| --[timed-mutexes](../server-system-variables/index#timed_mutexes), [timed\_mutexes](../server-system-variables/index#timed_mutexes) |
| [timestamp](../server-system-variables/index#timestamp) |
| --[time-format](../server-system-variables/index#time_format), [time-format](../server-system-variables/index#time_format) |
| [time\_zone](../server-system-variables/index#time_zone) |
| --[tls-version](../ssltls-system-variables/index#tls_version), [tls\_version](../ssltls-system-variables/index#tls_version) |
| --[tmp-disk-table-size](../server-system-variables/index#tmp_disk_table_size), [tmp\_disk\_table\_size](../server-system-variables/index#tmp_disk_table_size) |
| --[tmp-memory-table-size](../server-system-variables/index#tmp_memory_table_size), [tmp\_memory\_table\_size](../server-system-variables/index#tmp_memory_table_size) |
| --[tmp-table-size](../server-system-variables/index#tmp_table_size), [tmp\_table\_size](../server-system-variables/index#tmp_table_size) |
| -t, --[tmpdir](../server-system-variables/index#tmpdir), [tmpdir](../server-system-variables/index#tmpdir) |
| [tokudb\_alter\_print\_error](../tokudb-system-and-status-variables/index#tokudb_alter_print_error) |
| [tokudb\_analyze\_time](../tokudb-system-and-status-variables/index#tokudb_analyze_time) |
| [Tokudb\_basement\_deserialization\_fixed\_key](../tokudb-status-variables/index#tokudb_basement_deserialization_fixed_key) |
| [Tokudb\_basement\_deserialization\_variable\_key](../tokudb-status-variables/index#tokudb_basement_deserialization_variable_key) |
| [Tokudb\_basements\_decompressed\_for\_write](../tokudb-status-variables/index#tokudb_basements_decompressed_for_write) |
| [Tokudb\_basements\_decompressed\_prefetch](../tokudb-status-variables/index#tokudb_basements_decompressed_prefetch) |
| [Tokudb\_basements\_decompressed\_prelocked\_range](../tokudb-status-variables/index#tokudb_basements_decompressed_prelocked_range) |
| [Tokudb\_basements\_decompressed\_target\_query](../tokudb-status-variables/index#tokudb_basements_decompressed_target_query) |
| [Tokudb\_basements\_fetched\_for\_write](../tokudb-status-variables/index#tokudb_basements_fetched_for_write) |
| [Tokudb\_basements\_fetched\_for\_write\_bytes](../tokudb-status-variables/index#tokudb_basements_fetched_for_write_bytes) |
| [Tokudb\_basements\_fetched\_for\_write\_seconds](../tokudb-status-variables/index#tokudb_basements_fetched_for_write_seconds) |
| [Tokudb\_basements\_fetched\_prefetch](../tokudb-status-variables/index#tokudb_basements_fetched_prefetch) |
| [Tokudb\_basements\_fetched\_prefetch\_bytes](../tokudb-status-variables/index#tokudb_basements_fetched_prefetch_bytes) |
| [Tokudb\_basements\_fetched\_prefetch\_seconds](../tokudb-status-variables/index#tokudb_basements_fetched_prefetch_seconds) |
| [Tokudb\_basements\_fetched\_prelocked\_range](../tokudb-status-variables/index#tokudb_basements_fetched_prelocked_range) |
| [Tokudb\_basements\_fetched\_prelocked\_range\_bytes](../tokudb-status-variables/index#tokudb_basements_fetched_prelocked_range_bytes) |
| [Tokudb\_basements\_fetched\_prelocked\_range\_seconds](../tokudb-status-variables/index#tokudb_basements_fetched_prelocked_range_seconds) |
| [Tokudb\_basements\_fetched\_target\_query](../tokudb-status-variables/index#tokudb_basements_fetched_target_query) |
| [Tokudb\_basements\_fetched\_target\_query\_bytes](../tokudb-status-variables/index#tokudb_basements_fetched_target_query_bytes) |
| [Tokudb\_basements\_fetched\_target\_query\_seconds](../tokudb-status-variables/index#tokudb_basements_fetched_target_query_seconds) |
| [Tokudb\_broadcase\_messages\_injected\_at\_root](../tokudb-status-variables/index#tokudb_broadcase_messages_injected_at_root) |
| [Tokudb\_buffers\_decompressed\_prefetch](../tokudb-status-variables/index#tokudb_buffers_decompressed_prefetch) |
| [Tokudb\_buffers\_decompressed\_for\_write](../tokudb-status-variables/index#tokudb_buffers_decompressed_for_write) |
| [Tokudb\_buffers\_decompressed\_prelocked\_range](../tokudb-status-variables/index#tokudb_buffers_decompressed_prelocked_range) |
| [Tokudb\_buffers\_decompressed\_target\_query](../tokudb-status-variables/index#tokudb_buffers_decompressed_target_query) |
| [Tokudb\_buffers\_fetched\_for\_write](../tokudb-status-variables/index#tokudb_buffers_fetched_for_write) |
| [Tokudb\_buffers\_fetched\_for\_write\_bytes](../tokudb-status-variables/index#tokudb_buffers_fetched_for_write_bytes) |
| [Tokudb\_buffers\_fetched\_for\_write\_seconds](../tokudb-status-variables/index#tokudb_buffers_fetched_for_write_seconds) |
| [Tokudb\_buffers\_fetched\_prefetch](../tokudb-status-variables/index#tokudb_buffers_fetched_prefetch) |
| [Tokudb\_buffers\_fetched\_prefetch\_bytes](../tokudb-status-variables/index#tokudb_buffers_fetched_prefetch_bytes) |
| [Tokudb\_buffers\_fetched\_prefetch\_seconds](../tokudb-status-variables/index#tokudb_buffers_fetched_prefetch_seconds) |
| [Tokudb\_buffers\_fetched\_prelocked\_range](../tokudb-status-variables/index#tokudb_buffers_fetched_prelocked_range) |
| [Tokudb\_buffers\_fetched\_prelocked\_range\_bytes](../tokudb-status-variables/index#tokudb_buffers_fetched_prelocked_range_bytes) |
| [Tokudb\_buffers\_fetched\_prelocked\_range\_seconds](../tokudb-status-variables/index#tokudb_buffers_fetched_prelocked_range_seconds) |
| [Tokudb\_buffers\_fetched\_target\_query](../tokudb-status-variables/index#tokudb_buffers_fetched_target_query) |
| [Tokudb\_buffers\_fetched\_target\_query\_bytes](../tokudb-status-variables/index#tokudb_buffers_fetched_target_query_bytes) |
| [Tokudb\_buffers\_fetched\_target\_query\_seconds](../tokudb-status-variables/index#tokudb_buffers_fetched_target_query_seconds) |
| [tokudb\_bulk\_fetch](../tokudb-system-and-status-variables/index#tokudb_bulk_fetch) |
| [tokudb\_cache\_size](../tokudb-system-and-status-variables/index#tokudb_cache_size) |
| [Tokudb\_cachetable\_cleaner\_executions](../tokudb-status-variables/index#tokudb_cachetable_cleaner_executions) |
| [Tokudb\_cachetable\_cleaner\_iterations](../tokudb-status-variables/index#tokudb_cachetable_cleaner_iterations) |
| [Tokudb\_cachetable\_cleaner\_period](../tokudb-status-variables/index#tokudb_cachetable_cleaner_period) |
| [Tokudb\_cachetable\_evictions](../tokudb-status-variables/index#tokudb_cachetable_evictions) |
| [Tokudb\_cachetable\_long\_wait\_pressure\_count](../tokudb-status-variables/index#tokudb_cachetable_long_wait_pressure_count) |
| [Tokudb\_cachetable\_long\_wait\_pressure\_time](../tokudb-status-variables/index#tokudb_cachetable_long_wait_pressure_time) |
| [Tokudb\_cachetable\_miss](../tokudb-status-variables/index#tokudb_cachetable_miss) |
| [Tokudb\_cachetable\_miss\_time](../tokudb-status-variables/index#tokudb_cachetable_miss_time) |
| [Tokudb\_cachetable\_prefetches](../tokudb-status-variables/index#tokudb_cachetable_prefetches) |
| [Tokudb\_cachetable\_size\_cachepressure](../tokudb-status-variables/index#tokudb_cachetable_size_cachepressure) |
| [Tokudb\_cachetable\_size\_cloned](../tokudb-status-variables/index#tokudb_cachetable_size_cloned) |
| [Tokudb\_cachetable\_size\_current](../tokudb-status-variables/index#tokudb_cachetable_size_current) |
| [Tokudb\_cachetable\_size\_leaf](../tokudb-status-variables/index#tokudb_cachetable_size_leaf) |
| [Tokudb\_cachetable\_size\_limit](../tokudb-status-variables/index#tokudb_cachetable_size_limit) |
| [Tokudb\_cachetable\_size\_nonleaf](../tokudb-status-variables/index#tokudb_cachetable_size_nonleaf) |
| [Tokudb\_cachetable\_size\_rollback](../tokudb-status-variables/index#tokudb_cachetable_size_rollback) |
| [Tokudb\_cachetable\_size\_writing](../tokudb-status-variables/index#tokudb_cachetable_size_writing) |
| [Tokudb\_cachetable\_wait\_pressure\_count](../tokudb-status-variables/index#tokudb_cachetable_wait_pressure_count) |
| [Tokudb\_cachetable\_wait\_pressure\_time](../tokudb-status-variables/index#tokudb_cachetable_wait_pressure_time) |
| [tokudb\_check\_jemalloc](../tokudb-system-and-status-variables/index#tokudb_check_jemalloc) |
| [Tokudb\_checkpoint\_begin\_time](../tokudb-status-variables/index#tokudb_checkpoint_begin_time) |
| [Tokudb\_checkpoint\_duration](../tokudb-status-variables/index#tokudb_checkpoint_duration) |
| [Tokudb\_checkpoint\_duration\_last](../tokudb-status-variables/index#tokudb_checkpoint_duration_last) |
| [Tokudb\_checkpoint\_failed](../tokudb-status-variables/index#tokudb_checkpoint_failed) |
| [Tokudb\_checkpoint\_last\_began](../tokudb-status-variables/index#tokudb_checkpoint_last_began) |
| [Tokudb\_checkpoint\_last\_complete\_began](../tokudb-status-variables/index#tokudb_checkpoint_last_complete_began) |
| [Tokudb\_checkpoint\_last\_complete\_ended](../tokudb-status-variables/index#tokudb_checkpoint_last_complete_ended) |
| [tokudb\_checkpoint\_lock](../tokudb-system-and-status-variables/index#tokudb_checkpoint_lock) |
| [Tokudb\_checkpoint\_long\_begin\_count](../tokudb-status-variables/index#tokudb_checkpoint_long_begin_count) |
| [Tokudb\_checkpoint\_long\_begin\_time](../tokudb-status-variables/index#tokudb_checkpoint_long_begin_time) |
| [tokudb\_checkpoint\_on\_flush\_logs](../tokudb-system-and-status-variables/index#tokudb_checkpoint_on_flush_logs) |
| [Tokudb\_checkpoint\_period](../tokudb-status-variables/index#tokudb_checkpoint_period) |
| [Tokudb\_checkpoint\_taken](../tokudb-status-variables/index#tokudb_checkpoint_taken) |
| [tokudb\_checkpointing\_period](../tokudb-system-and-status-variables/index#tokudb_checkpointing_period) |
| [tokudb\_cleaner\_iterations](../tokudb-system-and-status-variables/index#tokudb_cleaner_iterations) |
| [tokudb\_cleaner\_period](../tokudb-system-and-status-variables/index#tokudb_cleaner_period) |
| [tokudb\_commit\_sync](../tokudb-system-and-status-variables/index#tokudb_commit_sync) |
| [tokudb\_create\_index\_online](../tokudb-system-and-status-variables/index#tokudb_create_index_online) |
| [Tokudb\_cursor\_skip\_deleted\_leaf\_entry](../tokudb-status-variables/index#tokudb_cursor_skip_deleted_leaf_entry) |
| [tokudb\_data\_dir](../tokudb-system-and-status-variables/index#tokudb_data_dir) |
| [Tokudb\_db\_closes](../tokudb-status-variables/index#tokudb_db_closes) |
| [Tokudb\_db\_open\_current](../tokudb-status-variables/index#tokudb_db_open_current) |
| [Tokudb\_db\_open\_max](../tokudb-status-variables/index#tokudb_db_open_max) |
| [Tokudb\_db\_opens](../tokudb-status-variables/index#tokudb_db_opens) |
| [tokudb\_debug](../tokudb-system-and-status-variables/index#tokudb_debug) |
| [Tokudb\_descriptor\_set](../tokudb-status-variables/index#tokudb_descriptor_set) |
| [Tokudb\_dictionary\_broadcast\_updates](../tokudb-status-variables/index#tokudb_dictionary_broadcast_updates) |
| [Tokudb\_dictionary\_updates](../tokudb-status-variables/index#tokudb_dictionary_updates) |
| [tokudb\_directio](../tokudb-system-and-status-variables/index#tokudb_directio) |
| [tokudb\_disable\_hot\_alter](../tokudb-system-and-status-variables/index#tokudb_disable_hot_alter) |
| [tokudb\_disable\_prefetching](../tokudb-system-and-status-variables/index#tokudb_disable_prefetching) |
| [tokudb\_disable\_slow\_alter](../tokudb-system-and-status-variables/index#tokudb_disable_slow_alter) |
| [tokudb\_empty\_scan](../tokudb-system-and-status-variables/index#tokudb_empty_scan) |
| [Tokudb\_filesystem\_fsync\_num](../tokudb-status-variables/index#tokudb_filesystem_fsync_num) |
| [Tokudb\_filesystem\_fsync\_time](../tokudb-status-variables/index#tokudb_filesystem_fsync_time) |
| [Tokudb\_filesystem\_long\_fsync\_num](../tokudb-status-variables/index#tokudb_filesystem_long_fsync_num) |
| [Tokudb\_filesystem\_long\_fsync\_time](../tokudb-status-variables/index#tokudb_filesystem_long_fsync_time) |
| [Tokudb\_filesystem\_threads\_blocked\_by\_full\_disk](../tokudb-status-variables/index#tokudb_filesystem_threads_blocked_by_full_disk) |
| [tokudb\_fs\_reserve\_percent](../tokudb-system-and-status-variables/index#tokudb_fs_reserve_percent) |
| [tokudb\_fsync\_log\_period](../tokudb-system-and-status-variables/index#tokudb_fsync_log_period) |
| [tokudb\_hide\_default\_row\_format](../tokudb-system-and-status-variables/index#tokudb_hide_default_row_format) |
| [tokudb\_killed\_time](../tokudb-system-and-status-variables/index#tokudb_killed_time) |
| [tokudb\_last\_lock\_timeout](../tokudb-system-and-status-variables/index#tokudb_last_lock_timeout) |
| [Tokudb\_leaf\_compression\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_leaf_compression_to_memory_seconds) |
| [Tokudb\_leaf\_decompression\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_leaf_decompression_to_memory_seconds) |
| [Tokudb\_leaf\_deserialization\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_leaf_deserialization_to_memory_seconds) |
| [Tokudb\_leaf\_node\_compression\_ratio](../tokudb-status-variables/index#tokudb_leaf_node_compression_ratio) |
| [Tokudb\_leaf\_node\_full\_evictions](../tokudb-status-variables/index#tokudb_leaf_node_full_evictions) |
| [Tokudb\_leaf\_node\_full\_evictions\_bytes](../tokudb-status-variables/index#tokudb_leaf_node_full_evictions_bytes) |
| [Tokudb\_leaf\_node\_partial\_evictions](../tokudb-status-variables/index#tokudb_leaf_node_partial_evictions) |
| [Tokudb\_leaf\_node\_partial\_evictions\_bytes](../tokudb-status-variables/index#tokudb_leaf_node_partial_evictions_bytes) |
| [Tokudb\_leaf\_nodes\_created](../tokudb-status-variables/index#tokudb_leaf_nodes_created) |
| [Tokudb\_leaf\_nodes\_destroyed](../tokudb-status-variables/index#tokudb_leaf_nodes_destroyed) |
| [Tokudb\_leaf\_nodes\_flushed\_checkpoint](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_checkpoint) |
| [Tokudb\_leaf\_nodes\_flushed\_checkpoint\_bytes](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_checkpoint_bytes) |
| [Tokudb\_leaf\_nodes\_flushed\_checkpoint\_seconds](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_checkpoint_seconds) |
| [Tokudb\_leaf\_nodes\_flushed\_checkpoint\_uncompressed\_bytes](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_checkpoint_uncompressed_bytes) |
| [Tokudb\_leaf\_nodes\_flushed\_not\_checkpoint](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_not_checkpoint) |
| [Tokudb\_leaf\_nodes\_flushed\_not\_checkpoint\_bytes](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_not_checkpoint_bytes) |
| [Tokudb\_leaf\_nodes\_flushed\_not\_checkpoint\_secondss](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_not_checkpoint_seconds) |
| [Tokudb\_leaf\_nodes\_flushed\_not\_checkpoint\_uncompressed\_bytes](../tokudb-status-variables/index#tokudb_leaf_nodes_flushed_not_checkpoint_uncompressed_bytes) |
| [Tokudb\_leaf\_serialization\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_leaf_serialization_to_memory_seconds) |
| [tokudb\_load\_save\_space](../tokudb-system-and-status-variables/index#tokudb_load_save_space) |
| [tokudb\_loader\_memory\_size](../tokudb-system-and-status-variables/index#tokudb_loader_memory_size) |
| [Tokudb\_loader\_num\_created](../tokudb-status-variables/index#tokudb_loader_num_created) |
| [Tokudb\_loader\_num\_current](../tokudb-status-variables/index#tokudb_loader_num_current) |
| [Tokudb\_loader\_num\_max](../tokudb-status-variables/index#tokudb_loader_num_max) |
| [tokudb\_lock\_timeout](../tokudb-system-and-status-variables/index#tokudb_lock_timeout) |
| [tokudb\_lock\_timeout\_debug](../tokudb-system-and-status-variables/index#tokudb_lock_timeout_debug) |
| [Tokudb\_locktree\_escalation\_num](../tokudb-status-variables/index#tokudb_locktree_escalation_num) |
| [Tokudb\_locktree\_escalation\_seconds](../tokudb-status-variables/index#tokudb_locktree_escalation_seconds) |
| [Tokudb\_locktree\_latest\_post\_escalation\_memory\_size](../tokudb-status-variables/index#tokudb_locktree_latest_post_escalation_memory_size) |
| [Tokudb\_locktree\_long\_wait\_count](../tokudb-status-variables/index#tokudb_locktree_long_wait_count) |
| [Tokudb\_locktree\_long\_wait\_escalation\_count](../tokudb-status-variables/index#tokudb_locktree_long_wait_escalation_count) |
| [Tokudb\_locktree\_long\_wait\_escalation\_time](../tokudb-status-variables/index#tokudb_locktree_long_wait_escalation_time) |
| [Tokudb\_locktree\_long\_wait\_time](../tokudb-status-variables/index#tokudb_locktree_long_wait_time) |
| [Tokudb\_locktree\_memory\_size](../tokudb-status-variables/index#tokudb_locktree_memory_size) |
| [Tokudb\_locktree\_memory\_size\_limit](../tokudb-status-variables/index#tokudb_locktree_memory_size_limit) |
| [Tokudb\_locktree\_open\_current](../tokudb-status-variables/index#tokudb_locktree_open_current) |
| [Tokudb\_locktree\_pending\_lock\_requests](../tokudb-status-variables/index#tokudb_locktree_pending_lock_requests) |
| [Tokudb\_locktree\_sto\_eligible\_num](../tokudb-status-variables/index#tokudb_locktree_sto_eligible_num) |
| [Tokudb\_locktree\_sto\_ended\_num](../tokudb-status-variables/index#tokudb_locktree_sto_ended_num) |
| [Tokudb\_locktree\_sto\_ended\_seconds](../tokudb-status-variables/index#tokudb_locktree_sto_ended_seconds) |
| [Tokudb\_locktree\_timeout\_count](../tokudb-status-variables/index#tokudb_locktree_timeout_count) |
| [Tokudb\_locktree\_wait\_count](../tokudb-status-variables/index#tokudb_locktree_wait_count) |
| [Tokudb\_locktree\_wait\_escalation\_count](../tokudb-status-variables/index#tokudb_locktree_wait_escalation_count) |
| [Tokudb\_locktree\_wait\_escalation\_time](../tokudb-status-variables/index#tokudb_locktree_wait_escalation_time) |
| [Tokudb\_locktree\_wait\_time](../tokudb-status-variables/index#tokudb_locktree_wait_time) |
| [tokudb\_log\_dir](../tokudb-system-and-status-variables/index#tokudb_log_dir) |
| [Tokudb\_logger\_wait\_long](../tokudb-status-variables/index#tokudb_logger_wait_long) |
| [Tokudb\_logger\_writes](../tokudb-status-variables/index#tokudb_logger_writes) |
| [Tokudb\_logger\_writes\_bytes](../tokudb-status-variables/index#tokudb_logger_writes_bytes) |
| [Tokudb\_logger\_writes\_seconds](../tokudb-status-variables/index#tokudb_logger_writes_seconds) |
| [Tokudb\_logger\_writes\_uncompressed\_bytes](../tokudb-status-variables/index#tokudb_logger_writes_uncompressed_bytes) |
| [tokudb\_max\_lock\_memory](../tokudb-system-and-status-variables/index#tokudb_max_lock_memory) |
| [Tokudb\_mem\_estimated\_maximum\_memory\_footprint](../tokudb-status-variables/index#tokudb_mem_estimated_maximum_memory_footprint) |
| [Tokudb\_messages\_flushed\_from\_h1\_to\_leaves\_bytes](../tokudb-status-variables/index#tokudb_messages_flushed_from_h1_to_leaves_bytes) |
| [Tokudb\_messages\_ignored\_by\_leaf\_due\_to\_msn](../tokudb-status-variables/index#tokudb_messages_ignored_by_leaf_due_to_msn) |
| [Tokudb\_messages\_in\_trees\_estimate\_bytes](../tokudb-status-variables/index#tokudb_messages_in_trees_estimate_bytes) |
| [Tokudb\_messages\_injected\_at\_root](../tokudb-status-variables/index#tokudb_messages_injected_at_root) |
| [Tokudb\_messages\_injected\_at\_root\_bytes](../tokudb-status-variables/index#tokudb_messages_injected_at_root_bytes) |
| [Tokudb\_nonleaf\_compression\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_compression_to_memory_seconds) |
| [Tokudb\_nonleaf\_decompression\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_decompression_to_memory_seconds) |
| [Tokudb\_nonleaf\_deserialization\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_deserialization_to_memory_seconds) |
| [Tokudb\_nonleaf\_node\_compression\_ratio](../tokudb-status-variables/index#tokudb_nonleaf_node_compression_ratio) |
| [Tokudb\_nonleaf\_node\_full\_evictions](../tokudb-status-variables/index#tokudb_nonleaf_node_full_evictions) |
| [Tokudb\_nonleaf\_node\_full\_evictions\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_node_full_evictions_bytes) |
| [Tokudb\_nonleaf\_node\_partial\_evictions](../tokudb-status-variables/index#tokudb_nonleaf_node_partial_evictions) |
| [Tokudb\_nonleaf\_node\_partial\_evictions\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_node_partial_evictions_bytes) |
| [Tokudb\_nonleaf\_nodes\_created](../tokudb-status-variables/index#tokudb_nonleaf_nodes_created) |
| [Tokudb\_nonleaf\_nodes\_destroyed](../tokudb-status-variables/index#tokudb_nonleaf_nodes_destroyed) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_checkpoint](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_checkpoint) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_checkpoint\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_bytes) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_checkpoint\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_seconds) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_checkpoint\_uncompressed\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_uncompressed_bytes) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_not\_checkpoint](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_not\_checkpoint\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_bytes) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_not\_checkpoint\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_seconds) |
| [Tokudb\_nonleaf\_nodes\_flushed\_to\_disk\_not\_checkpoint\_uncompressed\_bytes](../tokudb-status-variables/index#tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_uncompressed_bytes) |
| [Tokudb\_nonleaf\_serialization\_to\_memory\_seconds](../tokudb-status-variables/index#tokudb_nonleaf_serialization_to_memory_seconds) |
| [tokudb\_optimize\_index\_fraction](../tokudb-system-and-status-variables/index#tokudb_optimize_index_fraction) |
| [tokudb\_optimize\_index\_name](../tokudb-system-and-status-variables/index#tokudb_optimize_index_name) |
| [tokudb\_optimize\_throttle](../tokudb-system-and-status-variables/index#tokudb_optimize_throttle) |
| [Tokudb\_overall\_node\_compression\_ratio](../tokudb-status-variables/index#tokudb_overall_node_compression_ratio) |
| [Tokudb\_pivots\_fetched\_for\_query](../tokudb-status-variables/index#tokudb_pivots_fetched_for_query) |
| [Tokudb\_pivots\_fetched\_for\_query\_bytes](../tokudb-status-variables/index#tokudb_pivots_fetched_for_query_bytes) |
| [Tokudb\_pivots\_fetched\_for\_query\_seconds](../tokudb-status-variables/index#tokudb_pivots_fetched_for_query_seconds) |
| [Tokudb\_pivots\_fetched\_for\_prefetch](../tokudb-status-variables/index#tokudb_pivots_fetched_for_prefetch) |
| [Tokudb\_pivots\_fetched\_for\_prefetch\_bytes](../tokudb-status-variables/index#tokudb_pivots_fetched_for_prefetch_bytes) |
| [Tokudb\_pivots\_fetched\_for\_prefetch\_seconds](../tokudb-status-variables/index#tokudb_pivots_fetched_for_prefetch_seconds) |
| [Tokudb\_pivots\_fetched\_for\_write](../tokudb-status-variables/index#tokudb_pivots_fetched_for_write) |
| [Tokudb\_pivots\_fetched\_for\_write\_bytes](../tokudb-status-variables/index#tokudb_pivots_fetched_for_write_bytes) |
| [Tokudb\_pivots\_fetched\_for\_write\_seconds](../tokudb-status-variables/index#tokudb_pivots_fetched_for_write_seconds) |
| [tokudb\_pk\_insert\_mode](../tokudb-system-and-status-variables/index#tokudb_pk_insert_mode) |
| [tokudb\_prelock\_empty](../tokudb-system-and-status-variables/index#tokudb_prelock_empty) |
| [Tokudb\_promotion\_h1\_roots\_injected\_into](../tokudb-status-variables/index#tokudb_promotion_h1_roots_injected_into) |
| [Tokudb\_promotion\_injections\_at\_depth\_0](../tokudb-status-variables/index#tokudb_promotion_injections_at_depth_0) |
| [Tokudb\_promotion\_injections\_at\_depth\_1](../tokudb-status-variables/index#tokudb_promotion_injections_at_depth_1) |
| [Tokudb\_promotion\_injections\_at\_depth\_2](../tokudb-status-variables/index#tokudb_promotion_injections_at_depth_2) |
| [Tokudb\_promotion\_injections\_at\_depth\_3](../tokudb-status-variables/index#tokudb_promotion_injections_at_depth_3) |
| [Tokudb\_promotion\_injections\_lower\_than\_depth\_3](../tokudb-status-variables/index#tokudb_promotion_injections_lower_than_depth_3) |
| [Tokudb\_promotion\_leaf\_roots\_injected\_into](../tokudb-status-variables/index#tokudb_promotion_leaf_roots_injected_into) |
| [Tokudb\_promotion\_roots\_split](../tokudb-status-variables/index#tokudb_promotion_roots_split) |
| [Tokudb\_promotion\_stopped\_after\_locking\_child](../tokudb-status-variables/index#tokudb_promotion_stopped_after_locking_child) |
| [Tokudb\_promotion\_stopped\_at\_height\_1](../tokudb-status-variables/index#tokudb_promotion_stopped_at_height_1) |
| [Tokudb\_promotion\_stopped\_child\_locked\_or\_not\_in\_memory](../tokudb-status-variables/index#tokudb_promotion_stopped_child_locked_or_not_in_memory) |
| [Tokudb\_promotion\_stopped\_child\_not\_fully\_in\_memory](../tokudb-status-variables/index#tokudb_promotion_stopped_child_not_fully_in_memory) |
| [Tokudb\_promotion\_stopped\_nonempty\_buffer](../tokudb-status-variables/index#tokudb_promotion_stopped_nonempty_buffer) |
| [tokudb\_read\_block\_size](../tokudb-system-and-status-variables/index#tokudb_read_block_size) |
| [tokudb\_read\_buf\_size](../tokudb-system-and-status-variables/index#tokudb_read_buf_size) |
| [tokudb\_read\_status\_frequency](../tokudb-system-and-status-variables/index#tokudb_read_status_frequency) |
| [tokudb\_row\_format](../tokudb-system-and-status-variables/index#tokudb_row_format) |
| [tokudb\_rpl\_check\_readonly](../tokudb-system-and-status-variables/index#tokudb_rpl_check_readonly) |
| [tokudb\_rpl\_lookup\_rows](../tokudb-system-and-status-variables/index#tokudb_rpl_lookup_rows) |
| [tokudb\_rpl\_lookup\_rows\_delay](../tokudb-system-and-status-variables/index#tokudb_rpl_lookup_rows_delay) |
| [tokudb\_rpl\_unique\_checks](../tokudb-system-and-status-variables/index#tokudb_rpl_unique_checks) |
| [tokudb\_rpl\_unique\_checks\_delay](../tokudb-system-and-status-variables/index#tokudb_rpl_unique_checks_delay) |
| [tokudb\_support\_xa](../tokudb-system-and-status-variables/index#tokudb_support_xa) |
| [tokudb\_tmp\_dir](../tokudb-system-and-status-variables/index#tokudb_tmp_dir) |
| [Tokudb\_txn\_aborts](../tokudb-status-variables/index#tokudb_txn_aborts) |
| [Tokudb\_txn\_begin](../tokudb-status-variables/index#tokudb_txn_begin) |
| [Tokudb\_txn\_begin\_read\_only](../tokudb-status-variables/index#tokudb_txn_begin_read_only) |
| [Tokudb\_txn\_commits](../tokudb-status-variables/index#tokudb_txn_commits) |
| [tokudb\_version](../tokudb-system-and-status-variables/index#tokudb_version) |
| [tokudb\_write\_status\_frequency](../tokudb-system-and-status-variables/index#tokudb_write_status_frequency) |
| --[transaction-alloc-block-size](../server-system-variables/index#transaction_alloc_block_size), [transaction\_alloc\_block\_size](../server-system-variables/index#transaction_alloc_block_size) |
| --[transaction-isolation](../server-system-variables/index#transaction_isolation), [transaction\_isolation](../server-system-variables/index#transaction_isolation) |
| --[transaction-prealloc-size](../server-system-variables/index#transaction_prealloc_size), [transaction\_prealloc\_size](../server-system-variables/index#transaction_prealloc_size) |
| --[transaction-read-only](../server-system-variables/index#tx_read_only) |
| [Transactions\_gtid\_foreign\_engine](../replication-and-binary-log-server-status-variables/index#transactions_gtid_foreign_engine) |
| [Transactions\_multi\_engine](../replication-and-binary-log-server-status-variables/index#transactions_multi_engine) |
| [tx\_isolation](../server-system-variables/index#tx_isolation) |
| [tx\_read\_only](../server-system-variables/index#tx_read_only) |
| -u, --[user](../mysqld-options/index#-user) |
| [unique\_checks](../server-system-variables/index#unique_checks) |
| --[updatable-views-with-limit](../server-system-variables/index#updatable_views_with_limit), [updatable\_views\_with\_limit](../server-system-variables/index#updatable_views_with_limit) |
| [Update\_scan](../server-status-variables/index#update_scan) |
| [Uptime](../server-status-variables/index#uptime) |
| [Uptime\_since\_flush\_status](../server-status-variables/index#uptime_since_flush_status) |
| -u, --[user](../mysqld-options/index#-user) |
| --[use-stat-tables](../server-system-variables/index#use_stat_tables), [use\_stat\_tables](../server-system-variables/index#use_stat_tables) |
| --[userstat](../user-statistics/index#userstat), [userstat](../user-statistics/index#userstat) |
| -v, --[verbose](../mysqld-options/index#-verbose) |
| -V, --[version](../server-system-variables/index#version), [version](../server-system-variables/index#version) |
| [version\_comment](../server-system-variables/index#version_comment) |
| [version\_compile\_machine](../server-system-variables/index#version_compile_machine) |
| [version\_compile\_os](../server-system-variables/index#version_compile_os) |
| [version\_malloc\_library](../server-system-variables/index#version_malloc_library) |
| [version\_source\_revision](../server-system-variables/index#version_source_revision) |
| [version\_ssl\_library](../ssl-system-variables/index#version_ssl_library) |
| -W, --[log-warnings](../server-system-variables/index#log_warnings), [log\_warnings](../server-system-variables/index#log_warnings) |
| --[wait-timeout](../server-system-variables/index#wait_timeout), [wait\_timeout](../server-system-variables/index#wait_timeout) |
| [warning\_count](../server-system-variables/index#warning_count) |
| [wsrep](../mariadb-galera-cluster-status-variables/index#wsrep) |
| [wsrep\_allowlist](../galera-cluster-system-variables/index#wsrep_allowlist) |
| [wsrep\_applier\_thread\_count](../mariadb-galera-cluster-status-variables/index#wsrep_applier_thread_count) |
| [wsrep\_apply\_oooe](../mariadb-galera-cluster-status-variables/index#wsrep_apply_oooe) |
| [wsrep\_apply\_oool](../mariadb-galera-cluster-status-variables/index#wsrep_apply_oool) |
| [wsrep\_auto\_increment\_control](../galera-cluster-system-variables/index#wsrep_auto_increment_control) |
| [wsrep\_causal\_reads](../galera-cluster-system-variables/index#wsrep_causal_reads) |
| [wsrep\_cert\_deps\_distance](../mariadb-galera-cluster-status-variables/index#wsrep_cert_deps_distance) |
| [wsrep\_certification\_rules](../galera-cluster-system-variables/index#wsrep_certification_rules) |
| [wsrep\_certify\_nonPK](../galera-cluster-system-variables/index#wsrep_certify_nonpk) |
| [wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address) |
| [wsrep\_cluster\_capabilities](../mariadb-galera-cluster-status-variables/index#wsrep_cluster_capabilities) |
| [wsrep\_cluster\_conf\_id](../mariadb-galera-cluster-status-variables/index#wsrep_cluster_conf_id) |
| [wsrep\_cluster\_name](../galera-cluster-system-variables/index#wsrep_cluster_name) |
| [wsrep\_cluster\_size](../mariadb-galera-cluster-status-variables/index#wsrep_cluster_size) |
| [wsrep\_cluster\_state\_uuid](../mariadb-galera-cluster-status-variables/index#wsrep_cluster_state_uuid) |
| [wsrep\_cluster\_status](../mariadb-galera-cluster-status-variables/index#wsrep_cluster_status) |
| [wsrep\_connected](../mariadb-galera-cluster-status-variables/index#wsrep_connected) |
| [wsrep\_convert\_LOCK\_to\_trx](../galera-cluster-system-variables/index#wsrep_convert_lock_to_trx) |
| [wsrep\_data\_home\_dir](../galera-cluster-system-variables/index#wsrep_data_home_dir) |
| [wsrep\_dbug\_option](../galera-cluster-system-variables/index#wsrep_dbug_option) |
| [wsrep\_debug](../galera-cluster-system-variables/index#wsrep_debug) |
| [wsrep\_desync](../galera-cluster-system-variables/index#wsrep_desync) |
| [wsrep\_dirty\_reads](../galera-cluster-system-variables/index#wsrep_dirty_reads) |
| [wsrep\_drupal\_282555\_workaround](../galera-cluster-system-variables/index#wsrep_drupal_282555_workaround) |
| [wsrep\_flow\_control\_paused](../mariadb-galera-cluster-status-variables/index#wsrep_flow_control_paused) |
| [wsrep\_flow\_control\_recv](../mariadb-galera-cluster-status-variables/index#wsrep_flow_control_recv) |
| [wsrep\_flow\_control\_sent](../mariadb-galera-cluster-status-variables/index#wsrep_flow_control_sent) |
| [wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id) |
| [wsrep\_gtid\_mode](../galera-cluster-system-variables/index#wsrep_gtid_mode) |
| [wsrep\_gtid\_seq\_no](../galera-cluster-system-variables/index#wsrep_gtid_seq_no) |
| [wsrep\_forced\_binlog\_format](../galera-cluster-system-variables/index#wsrep_forced_binlog_format) |
| [wsrep\_ignore\_apply\_errors](../galera-cluster-system-variables/index#wsrep_ignore_apply_errors) |
| [wsrep\_last\_committed](../mariadb-galera-cluster-status-variables/index#wsrep_last_committed) |
| [wsrep\_load\_data\_splitting](../galera-cluster-system-variables/index#wsrep_load_data_splitting) |
| [wsrep\_local\_bf\_aborts](../mariadb-galera-cluster-status-variables/index#wsrep_local_bf_aborts) |
| [wsrep\_local\_cert\_failures](../mariadb-galera-cluster-status-variables/index#wsrep_local_cert_failures) |
| [wsrep\_local\_commits](../mariadb-galera-cluster-status-variables/index#wsrep_local_commits) |
| [wsrep\_local\_index](../mariadb-galera-cluster-status-variables/index#wsrep_local_index) |
| [wsrep\_local\_recv\_queue](../mariadb-galera-cluster-status-variables/index#wsrep_local_recv_queue) |
| [wsrep\_local\_recv\_queue\_avg](../mariadb-galera-cluster-status-variables/index#wsrep_local_recv_queue_avg) |
| [wsrep\_local\_replays](../mariadb-galera-cluster-status-variables/index#wsrep_local_replays) |
| [wsrep\_local\_send\_queue](../mariadb-galera-cluster-status-variables/index#wsrep_local_send_queue) |
| [wsrep\_local\_send\_queue\_avg](../mariadb-galera-cluster-status-variables/index#wsrep_local_send_queue_avg) |
| [wsrep\_local\_state](../mariadb-galera-cluster-status-variables/index#wsrep_local_state) |
| [wsrep\_local\_state\_comment](../mariadb-galera-cluster-status-variables/index#wsrep_local_state_comment) |
| [wsrep\_local\_state\_uuid](../mariadb-galera-cluster-status-variables/index#wsrep_local_state_uuid) |
| [wsrep\_log\_conflicts](../galera-cluster-system-variables/index#wsrep_log_conflicts) |
| [wsrep\_max\_ws\_rows](../galera-cluster-system-variables/index#wsrep_max_ws_rows) |
| [wsrep\_max\_ws\_size](../galera-cluster-system-variables/index#wsrep_max_ws_size) |
| [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) |
| [wsrep\_mysql\_replication\_bundle](../galera-cluster-system-variables/index#wsrep_mysql_replication_bundle) |
| --[wsrep-new-cluster](../mysqld-options-full-list/index#-wsrep-new-cluster) |
| [wsrep\_node\_address](../galera-cluster-system-variables/index#wsrep_node_address) |
| [wsrep\_node\_incoming\_address](../galera-cluster-system-variables/index#wsrep_node_incoming_address) |
| [wsrep\_node\_name](../galera-cluster-system-variables/index#wsrep_node_name) |
| [wsrep\_notify\_cmd](../galera-cluster-system-variables/index#wsrep_notify_cmd) |
| [wsrep\_on](../galera-cluster-system-variables/index#wsrep_on) |
| [wsrep\_OSU\_method](../galera-cluster-system-variables/index#wsrep_osu_method) |
| [wsrep\_protocol\_version](../mariadb-galera-cluster-status-variables/index#wsrep_protocol_version) |
| [wsrep\_provider\_name](../mariadb-galera-cluster-status-variables/index#wsrep_provider_name) |
| [wsrep\_patch\_version](../galera-cluster-system-variables/index#wsrep_patch_version) |
| [wsrep\_provider](../galera-cluster-system-variables/index#wsrep_provider) |
| [wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options) |
| [wsrep\_provider\_vendor](../mariadb-galera-cluster-status-variables/index#wsrep_provider_vendor) |
| [wsrep\_provider\_version](../mariadb-galera-cluster-status-variables/index#wsrep_provider_version) |
| [wsrep\_ready](../mariadb-galera-cluster-status-variables/index#wsrep_ready) |
| [wsrep\_received](../mariadb-galera-cluster-status-variables/index#wsrep_received) |
| [wsrep\_received\_bytes](../mariadb-galera-cluster-status-variables/index#wsrep_received_bytes) |
| [wsrep\_recover](../galera-cluster-system-variables/index#wsrep_recover) |
| [wsrep\_reject\_queries](../galera-cluster-system-variables/index#wsrep_reject_queries) |
| [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) |
| [wsrep\_replicated](../mariadb-galera-cluster-status-variables/index#wsrep_replicated) |
| [wsrep\_replicated\_bytes](../mariadb-galera-cluster-status-variables/index#wsrep_replicated_bytes) |
| [wsrep\_retry\_autocommit](../galera-cluster-system-variables/index#wsrep_retry_autocommit) |
| [wsrep\_rollbacker\_thread\_count](../mariadb-galera-cluster-status-variables/index#wsrep_rollbacker_thread_count) |
| [wsrep\_slave\_FK\_checks](../galera-cluster-system-variables/index#wsrep_slave_fk_checks) |
| [wsrep\_slave\_threads](../galera-cluster-system-variables/index#wsrep_slave_threads) |
| [wsrep\_slave\_UK\_checks](../galera-cluster-system-variables/index#wsrep_slave_uk_checks) |
| [wsrep\_sr\_store](../galera-cluster-system-variables/index#wsrep_sr_store_auth) |
| [wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth) |
| [wsrep\_sst\_donor](../galera-cluster-system-variables/index#wsrep_sst_donor) |
| [wsrep\_sst\_donor\_rejects\_queries](../galera-cluster-system-variables/index#wsrep_sst_donor_rejects_queries) |
| [wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method) |
| [wsrep\_sst\_receive\_address](../galera-cluster-system-variables/index#wsrep_sst_receive_address) |
| [wsrep\_start\_position](../galera-cluster-system-variables/index#wsrep_start_position) |
| [wsrep\_status\_file](../galera-cluster-system-variables/index#wsrep_status_file) |
| [wsrep\_strict\_ddl](../galera-cluster-system-variables/index#wsrep_strict_ddl) |
| [wsrep\_sync\_wait](../galera-cluster-system-variables/index#wsrep_sync_wait) |
| [wsrep-trx-fragment-size](../galera-cluster-system-variables/index#wsrep_trx_fragment_size) |
| [wsrep-trx-fragment-unit](../galera-cluster-system-variables/index#wsrep_trx_fragment_unit) |
| [wsrep\_thread\_count](../galera-cluster-system-variables/index#wsrep_thread_count) |

 
See Also
--------

 * [System and Status Variables Added By Major Release](../system-and-status-variables-added-by-major-release/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/full-list-of-mariadb-options-system-and-status-variables/>

Server Status Variables
=======================

    The full list of status variables are listed in the contents on this page; most are described on this page, but some are described elsewhere:

 * [Aria Status Variables](../aria-server-status-variables/index)
* [Galera Status Variables](../mariadb-galera-cluster-status-variables/index)
* [InnoDB Status Variables](../innodb-status-variables/index)
* [Mroonga Status Variables](../mroonga-status-variables/index)
* [MyRocks Status Variables](../myrocks-status-variables/index)
* [Performance Scheme Status Variables](../performance-schema-status-variables/index)
* [Replication and Binary Log Status Variables](../replication-and-binary-log-server-status-variables/index)
* [S3 Storage Engine Status Variables](../s3-storage-engine-status-variables/index)
* [Server\_Audit Status Variables](../server_audit-status-variables/index)
* [Sphinx Status Variables](../sphinx-status-variables/index)
* [Spider Status Variables](../spider-server-status-variables/index)
* [TokuDB Status Variables](../tokudb-status-variables/index)

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 Use the [SHOW STATUS](../show-status/index) statement to view status variables. This information also can be obtained using the [mariadb-admin extended-status](../mariadb-admin/index) command, or by querying the [Information Schema GLOBAL\_STATUS and SESSION\_STATUS](../information-schema-global_status-and-session_status-tables/index) tables.

 Issuing a [FLUSH STATUS](../flush/index) will reset many status variables to zero.

 List of Server Status Variables
-------------------------------

 #### `Aborted_clients`

 * **Description:** Number of aborted client connections. This can be due to the client not calling mysql\_close() before exiting, the client sleeping without issuing a request to the server for more seconds than specified by [wait\_timeout](../server-system-variables/index#wait_timeout) or [interactive\_timeout](../server-system-variables/index#interactive_timeout), or by the client program ending in the midst of transferring data. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aborted_connects`

 * **Description:** Number of failed server connection attempts. This can be due to a client using an incorrect password, a client not having privileges to connect to a database, a connection packet not containing the correct information, or if it takes more than [connect\_timeout](../server-system-variables/index#connect_timeout) seconds to get a connect packet. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aborted_connects_preauth`

 * **Description:** Number of connection attempts that were aborted prior to authentication (regardless of whether or not an error occured).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)

 

---

 #### `Access_denied_errors`

 * **Description:** Number of access denied errors.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_column_grants`

 * **Description:** Number of column permissions granted (rows in the [mysql.columns\_priv table](../mysqlcolumns_priv-table/index)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_database_grants`

 * **Description:** Number of database permissions granted (rows in the [mysql.db table](../mysqldb-table/index)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_function_grants`

 * **Description:** Number of function permissions granted (rows in the [mysql.procs\_priv table](../mysqlprocs_priv-table/index) with a routine type of `FUNCTION`).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_package_body_grants`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Acl_package_spec_grants`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Acl_procedure_grants`

 * **Description:** Number of procedure permissions granted (rows in the [mysql.procs\_priv table](../mysqlprocs_priv-table/index) with a routine type of `PROCEDURE`).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_proxy_users`

 * **Description:** Number of proxy permissions granted (rows in the [mysql.proxies\_priv table](../mysqlproxies_priv-table/index)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_role_grants`

 * **Description:** Number of role permissions granted (rows in the [mysql.roles\_mapping table](../mysqlroles_mapping-table/index)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_roles`

 * **Description:** Number of roles (rows in the [mysql.user table](../mysqluser-table/index) where `is_role='Y'`).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_table_grants`

 * **Description:** Number of table permissions granted (rows in the [mysql.tables\_priv table](mysql.tables_priv-table)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Acl_users`

 * **Description:** Number of users (rows in the [mysql.user table](../mysqluser-table/index) where `is_role='N'`).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Busy_time`

 * **Description:** Cumulative time in seconds of activity on connections.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Bytes_received`

 * **Description:** Total bytes received from all clients.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Bytes_sent`

 * **Description:** Total bytes sent to all clients.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_admin_commands`

 * **Description:** Number of admin commands executed. These include table dumps, change users, binary log dumps, shutdowns, pings and debugs.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_db`

 * **Description:** Number of [ALTER DATABASE](../alter-database/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_db_upgrade`

 * **Description:** Number of [ALTER DATABASE ... UPGRADE](../alter-database/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_event`

 * **Description:** Number of [ALTER EVENT](../alter-event/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_function`

 * **Description:** Number of [ALTER FUNCTION](../alter-function/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_procedure`

 * **Description:** Number of [ALTER PROCEDURE](../alter-procedure/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_sequence`

 * **Description:** Number of [ALTER SEQUENCE](../alter-sequence/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `Com_alter_server`

 * **Description:** Number of [ALTER SERVER](../alter-server/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_table`

 * **Description:** Number of [ALTER TABLE](../alter-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_alter_tablespace`

 * **Description:** Number of [ALTER TABLESPACE](../alter-tablespace/index) commands executed (unsupported by MariaDB).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)

 

---

 #### `Com_alter_user`

 * **Description:** Number of [ALTER USER](../alter-user/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/)

 

---

 #### `Com_analyze`

 * **Description:** Number of [ANALYZE](../analyze-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_assign_to_keycache`

 * **Description:** Number of assign to keycache commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_backup`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)

 

---

 #### `Com_backup_lock`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

 #### `Com_backup_table`

 * **Description:** Removed in [MariaDB 5.5](../what-is-mariadb-55/index). In older versions, Com\_backup\_table contains the number of [BACKUP TABLE](../backup-table-deprecated/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Com_begin`

 * **Description:** Number of [BEGIN](../begin-end/index) or [START TRANSACTION](../start-transaction/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_binlog`

 * **Description:** Number of [BINLOG](../binlog/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_call_procedure`

 * **Description:** Number of [CALL](../call/index) procedure\_name statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_change_db`

 * **Description:** Number of [USE](../use/index) database\_name commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_check`

 * **Description:** Number of [CHECK TABLE](../check-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_checksum`

 * **Description:** Number of [CHECKSUM TABLE](../checksum-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_commit`

 * **Description:** Number of [COMMIT](../transactions-commit-statement/index) commands executed. Differs from [Handler\_commit](#handler_commit), which counts internal commit statements.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_compound_sql`

 * **Description:** Number of [compund](../programmatic-and-compound-statements/index) sql statements.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_db`

 * **Description:** Number of [CREATE DATABASE](../create-database/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_event`

 * **Description:** Number of [CREATE EVENT](../create-event/index) commands executed. Differs from [Executed\_events](#executed_events) in that it is incremented when the CREATE EVENT is run, and not when the event executes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_function`

 * **Description:** Number of [CREATE FUNCTION](../create-function/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_index`

 * **Description:** Number of [CREATE INDEX](../create-index/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_package`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_create_package_body`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_create_procedure`

 * **Description:** Number of [CREATE PROCEDURE](../create-procedure/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_role`

 * **Description:** Number of [CREATE ROLE](../create-role/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_sequence`

 * **Description:** Number of [CREATE SEQUENCE](../create-sequence/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `Com_create_server`

 * **Description:** Number of [CREATE SERVER](../create-server/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_table`

 * **Description:** Number of [CREATE TABLE](../create-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_temporary_table`

 * **Description:** Number of [CREATE TEMPORARY TABLE](../create-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_trigger`

 * **Description:** Number of [CREATE TRIGGER](../create-trigger/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_udf`

 * **Description:** Number of [CREATE UDF](../create-function-udf/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_user`

 * **Description:** Number of [CREATE USER](../create-user/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_create_view`

 * **Description:** Number of [CREATE VIEW](../create-view/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_dealloc_sql`

 * **Description:** Number of [DEALLOCATE](../deallocate-drop-prepared-statement/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_delete`

 * **Description:** Number of [DELETE](../delete/index) commands executed. Differs from [Handler\_delete](#handler_delete), which counts the number of times rows have been deleted from tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_delete_multi`

 * **Description:** Number of multi-table [DELETE](../delete/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_do`

 * **Description:** Number of [DO](../do/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_db`

 * **Description:** Number of [DROP DATABASE](../drop-database/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_event`

 * **Description:** Number of [DROP EVENT](../drop-event/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_function`

 * **Description:** Number of [DROP FUNCTION](../drop-function/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_index`

 * **Description:** Number of [DROP INDEX](../drop-index/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_package`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_drop_package_body`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_drop_procedure`

 * **Description:** Number of [DROP PROCEDURE](../drop-procedure/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_role`

 * **Description:** Number of [DROP ROLE](../drop-role/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_sequence`

 * **Description:** Number of [DROP SEQUENCE](../drop-sequence/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `Com_drop_server`

 * **Description:** Number of [DROP SERVER](../drop-server/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_table`

 * **Description:** Number of [DROP TABLE](../drop-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_temporary_table`

 * **Description:** Number of [DROP TEMPORARY TABLE](../drop-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_trigger`

 * **Description:** Number of [DROP TRIGGER](../drop-trigger/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_user`

 * **Description:** Number of [DROP USER](../drop-user/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_drop_view`

 * **Description:** Number of [DROP VIEW](../drop-view/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_empty_query`

 * **Description:** Number of queries to the server that do not produce SQL queries. An SQL query simply returning no results does not increment `Com_empty_query` - see [Empty\_queries](#empty_queries) instead. An example of an empty query sent to the server is `mariadb --comments -e '-- sql comment'`
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_execute_immediate`

 * **Description:** Number of [EXECUTE IMMEDIATE](../execute-immediate/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)

 

---

 #### `Com_execute_sql`

 * **Description:** Number of [EXECUTE](../execute-statement/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_flush`

 * **Description:** Number of [FLUSH](../flush/index) commands executed. This differs from [Flush\_commands](#flush_commands), which also counts internal server flush requests.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_get_diagnostics`

 * **Description:** Number of [GET DIAGNOSTICS](../get-diagnostics/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_grant`

 * **Description:** Number of [GRANT](../grant/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_grant_role`

 * **Description:** Number of [GRANT](../grant/index#roles) role commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_ha_close`

 * **Description:** Number of [HANDLER](../handler-commands/index) table\_name CLOSE commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_ha_open`

 * **Description:** Number of [HANDLER](../handler-commands/index) table\_name OPEN commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_ha_read`

 * **Description:** Number of [HANDLER](../handler-commands/index) table\_name READ commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_help`

 * **Description:** Number of [HELP](../help-command/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_insert`

 * **Description:** Number of [INSERT](../insert/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_insert_select`

 * **Description:** Number of [INSERT ... SELECT](../insert-select/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_install_plugin`

 * **Description:** Number of [INSTALL PLUGIN](../install-plugin/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_kill`

 * **Description:** Number of [KILL](../kill/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_load`

 * **Description:** Number of LOAD commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_load_master_data`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Com_load_master_table`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Com_multi`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/)

 

---

 #### `Com_lock_tables`

 * **Description:** Number of [lock-tables|LOCK TABLES]] commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_optimize`

 * **Description:** Number of [OPTIMIZE](../optimize-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_preload_keys`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_prepare_sql`

 * **Description:** Number of [PREPARE](../prepare-statement/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_purge`

 * **Description:** Number of [PURGE](../sql-commands-purge-logs/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_purge_before_date`

 * **Description:** Number of [PURGE BEFORE](../sql-commands-purge-logs/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_release_savepoint`

 * **Description:** Number of [RELEASE SAVEPOINT](../savepoint/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_rename_table`

 * **Description:** Number of [RENAME TABLE](../rename-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_rename_user`

 * **Description:** Number of [RENAME USER](../rename-user/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_repair`

 * **Description:** Number of [REPAIR TABLE](../repair-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_replace`

 * **Description:** Number of [REPLACE](../replace/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_replace_select`

 * **Description:** Number of [REPLACE](../replace/index) ... [SELECT](../select/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_reset`

 * **Description:** Number of [RESET](../reset/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_resignal`

 * **Description:** Number of [RESIGNAL](../resignal/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_restore_table`

 * **Description:** Removed in [MariaDB 5.5](../what-is-mariadb-55/index). In older versions, Com\_restore\_table contains the number of [RESTORE TABLE](../restore-table-removed/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Com_revoke`

 * **Description:** Number of [REVOKE](../revoke/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_revoke_all`

 * **Description:** Number of [REVOKE ALL](../revoke/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_revoke_grant`

 * **Description:** Number of [REVOKE](../revoke/index#roles) role commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_rollback`

 * **Description:** Number of [ROLLBACK](../rollback/index) commands executed. Differs from [Handler\_rollback](#handler_rollback), which is the number of transaction rollback requests given to a storage engine.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_rollback_to_savepoint`

 * **Description:** Number of [ROLLBACK ... TO SAVEPOINT](../rollback/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_savepoint`

 * **Description:** Number of [SAVEPOINT](../savepoint/index) commands executed. Differs from [Handler\_savepoint](#handler_savepoint), which is the number of transaction savepoint creation requests.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_select`

 * **Description:** Number of [SELECT](../select/index) commands executed. Also includes queries that make use of the [query cache](../query-cache/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_set_option`

 * **Description:** Number of [SET OPTION](../set/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_signal`

 * **Description:** Number of [SIGNAL](../signal/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_authors`

 * **Description:** Number of [SHOW AUTHORS](../show-authors/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_binlog_events`

 * **Description:** Number of [SHOW BINLOG EVENTS](../show-binlog-events/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_binlogs`

 * **Description:** Number of [SHOW BINARY LOGS](../show-binary-logs/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_charsets`

 * **Description:** Number of [SHOW CHARACTER SET](../show-character-set/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_client_statistics`

 * **Description:** Number of [SHOW CLIENT STATISTICS](../show-client_statistics/index) commands executed. Removed in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) when that statement was replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Com_show_collations`

 * **Description:** Number of [SHOW COLLATION](../show-collation/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_column_types`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Com_show_contributors`

 * **Description:** Number of [SHOW CONTRIBUTORS](../show-contributors/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_db`

 * **Description:** Number of [SHOW CREATE DATABASE](../show-create-database/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_event`

 * **Description:** Number of [SHOW CREATE EVENT](../show-create-event/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_func`

 * **Description:** Number of [SHOW CREATE FUNCTION](../show-create-function/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_package`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_show_create_package_body`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_show_create_proc`

 * **Description:** Number of [SHOW CREATE PROCEDURE](../show-create-procedure/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_table`

 * **Description:** Number of [SHOW CREATE TABLE](../show-create-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_trigger`

 * **Description:** Number of [SHOW CREATE TRIGGER](../show-create-table/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_create_user`

 * **Description:** Number of [SHOW CREATE USER](../show-create-user/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/)

 

---

 #### `Com_show_databases`

 * **Description:** Number of [SHOW DATABASES](../show-databases/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_engine_logs`

 * **Description:** Number of [SHOW ENGINE LOGS](../show-engine/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_engine_mutex`

 * **Description:** Number of [SHOW ENGINE MUTEX](../show-engine/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_engine_status`

 * **Description:** Number of [SHOW ENGINE STATUS](../show-engine/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_events`

 * **Description:** Number of [SHOW EVENTS](../show-events/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_errors`

 * **Description:** Number of [SHOW ERRORS](../show-errors/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_explain`

 * **Description:** Number of [SHOW EXPLAIN](../show-explain/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_fields`

 * **Description:** Number of [SHOW COLUMNS](../show-columns/index) or SHOW FIELDS commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_function_status`

 * **Description:** Number of [SHOW FUNCTION STATUS](../show-function-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_generic`

 * **Description:** Number of generic [SHOW](../show/index) commands executed, such as [SHOW INDEX\_STATISTICS](../show-index_statistics/index) and [SHOW TABLE\_STATISTICS](../show-table_statistics/index)
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_grants`

 * **Description:** Number of [SHOW GRANTS](../show-grants/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_keys`

 * **Description:** Number of [SHOW INDEX](../show-index/index) or SHOW KEYS commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_index_statistics`

 * **Description:** Number of [SHOW INDEX\_STATISTICS](../show-index_statistics/index) commands executed. Removed in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) when that statement was replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Com_show_open_tables`

 * **Description:** Number of [SHOW OPEN TABLES](../show-open-tables/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_package_status`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_show_package_body_status`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Com_show_plugins`

 * **Description:** Number of [SHOW PLUGINS](../show-plugins/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_privileges`

 * **Description:** Number of [SHOW PRIVILEGES](../show-privileges/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_procedure_status`

 * **Description:** Number of [SHOW PROCEDURE STATUS](../show-procedure-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_processlist`

 * **Description:** Number of [SHOW PROCESSLIST](../show-processlist/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_profile`

 * **Description:** Number of [SHOW PROFILE](../show-profile/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_profiles`

 * **Description:** Number of [SHOW PROFILES](../show-profiles/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_relaylog_events`

 * **Description:** Number of [SHOW RELAYLOG EVENTS](../show-relaylog-events/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_status`

 * **Description:** Number of [SHOW STATUS](../show-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`st

 

---

 #### `Com_show_storage_engines`

 * **Description:** Number of [SHOW STORAGE ENGINES](../show-engines/index) - or `SHOW ENGINES` - commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_table_statistics`

 * **Description:** Number of [SHOW TABLE STATISTICS](../show-table_statistics/index) commands executed. Removed in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) when that statement was replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Com_show_table_status`

 * **Description:** Number of [SHOW TABLE STATUS](../show-table-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_tables`

 * **Description:** Number of [SHOW TABLES](../show-tables/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_triggers`

 * **Description:** Number of [SHOW TRIGGERS](../show-triggers/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_user_statistics`

 * **Description:** Number of [SHOW USER STATISTICS](../show-user_statistics/index) commands executed. Removed in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) when that statement was replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Com_show_variable`

 * **Description:** Number of [SHOW VARIABLES](../show-variables/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_warnings`

 * **Description:** Number of [SHOW WARNINGS](../show-warnings/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_shutdown`

 * **Description:** Number of [SHUTDOWN](../shutdown/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_close`

 * **Description:** Number of [prepared statements](../prepared-statements/index) closed ([deallocated or dropped](../deallocate-drop-prepared-statement/index)).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_execute`

 * **Description:** Number of [prepared statements](../prepared-statements/index) [executed](../execute-statement/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_fetch`

 * **Description:** Number of [prepared statements](../prepared-statements/index) fetched.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_prepare`

 * **Description:** Number of [prepared statements](../prepared-statements/index) [prepared](../prepare-statement/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_reprepare`

 * **Description:** Number of [prepared statements](../prepared-statements/index) reprepared.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_reset`

 * **Description:** Number of [prepared statements](../prepared-statements/index) where the data of a prepared statement which was accumulated in chunks by sending long data has been reset.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stmt_send_long_data`

 * **Description:** Number of [prepared statements](../prepared-statements/index) where the parameter data has been sent in chunks (long data).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_truncate`

 * **Description:** Number of [TRUNCATE](../truncate/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_uninstall_plugin`

 * **Description:** Number of [UNINSTALL PLUGIN](../uninstall-plugin/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_unlock_tables`

 * **Description:** Number of [UNLOCK TABLES](../transactions-lock/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_update`

 * **Description:** Number of [UPDATE](../update/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_update_multi`

 * **Description:** Number of multi-table [UPDATE](../update/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_commit`

 * **Description:** Number of XA statements committed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_end`

 * **Description:** Number of XA statements ended.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_prepare`

 * **Description:** Number of XA statements prepared.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_recover`

 * **Description:** Number of XA RECOVER statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_rollback`

 * **Description:** Number of XA statements rolled back.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_xa_start`

 * **Description:** Number of XA statements started.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Compression`

 * **Description:** Whether client-server traffic is compressed.
* **Scope:** Session
* **Data Type:** `boolean`

 

---

 #### `Connection_errors_accept`

 * **Description:** Number of errors that occurred during calls to accept() on the listening port. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connection_errors_internal`

 * **Description:** Number of refused connections due to internal server errors, for example out of memory errors, or failed thread starts. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connection_errors_max_connections`

 * **Description:** Number of refused connections due to the [max\_connections](../server-system-variables/index#max_connections) limit being reached. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connection_errors_peer_address`

 * **Description:** Number of errors while searching for the connecting client IP address. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connection_errors_select`

 * **Description:** Number of errors during calls to select() or poll() on the listening port. The client would not necessarily have been rejected in these cases. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connection_errors_tcpwrap`

 * **Description:** Number of connections the libwrap library refused. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Connections`

 * **Description:** Number of connection attempts (both successful and unsuccessful)
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Cpu_time`

 * **Description:** Total CPU time used.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Created_tmp_disk_tables`

 * **Description:** Number of on-disk temporary tables created.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Created_tmp_files`

 * **Description:** Number of temporary files created. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Created_tmp_tables`

 * **Description:** Number of in-memory temporary tables created.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Delayed_errors`

 * **Description:** Number of errors which occurred while doing [INSERT DELAYED](../insert-delayed/index). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Delayed_insert_threads`

 * **Description:** Number of [INSERT DELAYED](../insert-delayed/index) threads.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Delayed_writes`

 * **Description:** Number of [INSERT DELAYED](../insert-delayed/index) rows written. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Delete_scan`

 * **Description:** Number of [DELETE](../delete/index)s that required a full table scan.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Empty_queries`

 * **Description:** Number of queries returning no results. Note this is not the same as [Com\_empty\_query](#com_empty_query).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Executed_events`

 * **Description:** Number of times events created with [CREATE EVENT](../create-event/index) have executed. This differs from [Com\_create\_event](#com_create_event) in that it is only incremented when the event has run, not when it executes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Executed_triggers`

 * **Description:** Number of times triggers created with [CREATE TRIGGER](../create-trigger/index) have executed. This differs from [Com\_create\_trigger](#com_create_trigger) in that it is only incremented when the trigger has run, not when it executes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_application_time_periods`

 * **Description:** Number of times a table created with [periods](../create-table/index#periods) has been opened.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)

 

---

 #### `Feature_check_constraint`

 * **Description:** Number of times [constraints](../constraint/index) were checked. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `Feature_custom_aggregate_functions`

 * **Description:** Number of queries which make use of [custom aggregate functions](stored-aggregate-function).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)

 

---

 #### `Feature_delay_key_write`

 * **Description:** Number of tables opened that are using [delay\_key\_write](../server-system-variables/index#delay_key_write). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_dynamic_columns`

 * **Description:** Number of times the [COLUMN\_CREATE()](../column_create/index) function was used.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_fulltext`

 * **Description:** Number of times the [MATCH … AGAINST()](../match-against/index) function was used.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_gis`

 * **Description:** Number of times a table with a any of the [geometry](../geometry-types/index) columns was opened.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_insert_returning`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Feature_invisible_columns`

 * **Description:** Number of invisible columns in all opened tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Feature_json`

 * **Description:** Number of times JSON functionality has been used, such as one of the [JSON functions](../json-functions/index). Does not include the [CONNECT engine JSON type](../connect-json-table-type/index), or [EXPLAIN/ANALYZE FORMAT=JSON](../analyze-statement/index#analyze-formatjson).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Feature_locale`

 * **Description:** Number of times the [@@lc\_messages](../server-system-variables/index#lc_messages) variable was assigned into.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_subquery`

 * **Description:** Number of subqueries (excluding subqueries in the FROM clause) used.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_system_versioning`

 * **Description:** Number of times [system versioning](../system-versioned-tables/index) functionality has been used (opening a table WITH SYSTEM VERSIONING).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 #### `Feature_timezone`

 * **Description:** Number of times an explicit timezone (excluding [UTC](../coordinated-universal-time/index) and SYSTEM) was specified.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_trigger`

 * **Description:** Number of triggers loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Feature_window_functions`

 * **Description:** Number of times [window functions](../window-functions/index) were used.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `Feature_xml`

 * **Description:** Number of times XML functions ([EXTRACTVALUE()](../extractvalue/index) and [UPDATEXML()](../updatexml/index)) were used.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Flush_commands`

 * **Description:** Number of [FLUSH](../flush/index) statements executed, as well as due to internal server flush requests. This differs from [Com\_flush](#com_flush), which simply counts FLUSH statements, not internal server flush operations.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `Handler_commit`

 * **Description:** Number of internal [COMMIT](../commit/index) requests. Differs from [Com\_commit](#com_commit), which counts the number of [COMMIT](../commit/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_delete`

 * **Description:** Number of times rows have been deleted from tables. Differs from [Com\_delete](#com_delete), which counts [DELETE](../delete/index) statements.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_discover`

 * **Description:** Discovery is when the server asks the NDBCLUSTER storage engine if it knows about a table with a given name. Handler\_discover indicates the number of times that tables have been discovered in this way.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_external_lock`

 * **Description:** Incremented for each call to the external\_lock() function, which generally occurs at the beginning and end of access to a table instance.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_icp_attempts`

 * **Description:** Number of times pushed index condition was checked. The smaller the ratio of Handler\_icp\_attempts to [Handler\_icp\_match](#handler_icp_match) the better the filtering. See [Index Condition Pushdown](../index-condition-pushdown/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_icp_match`

 * **Description:** Number of times pushed index condition was matched. The smaller the ratio of [Handler\_icp\_attempts](#handler_icp_attempts) to Handler\_icp\_match the better the filtering. See See [Index Condition Pushdown](../index-condition-pushdown/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_mrr_init`

 * **Description:** Counts how many MRR (multi-range read) scans were performed. See [Multi Range Read optimization](../multi-range-read-optimization/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_mrr_key_refills`

 * **Description:** Number of times key buffer was refilled (not counting the initial fill). A non-zero value indicates there wasn't enough memory to do key sort-and-sweep passes in one go. See [Multi Range Read optimization](../multi-range-read-optimization/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_mrr_rowid_refills`

 * **Description:** Number of times rowid buffer was refilled (not counting the initial fill). A non-zero value indicates there wasn't enough memory to do rowid sort-and-sweep passes in one go. See [Multi Range Read optimization](../multi-range-read-optimization/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_prepare`

 * **Description:** Number of two-phase commit prepares.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_first`

 * **Description:** Number of requests to read the first row from an index. A high value indicates many full index scans, e.g. `SELECT a FROM table_name` where `a` is an indexed column.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_key`

 * **Description:** Number of row read requests based on an index value. A high value indicates indexes are regularly being used, which is usually positive.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_last`

 * **Description:** Number of requests to read the last row from an index. [ORDER BY DESC](../order-by/index) results in a last-key request followed by several previous-key requests.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_next`

 * **Description:** Number of requests to read the next row from an index (in order). Increments when doing an index scan or querying an index column with a range constraint.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_prev`

 * **Description:** Number of requests to read the previous row from an index (in order). Mostly used with [ORDER BY DESC](../select/index#order-by).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_retry`

 * **Description:** Number of read retrys triggered by semi\_consistent\_read (InnoDB feature).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Handler_read_rnd`

 * **Description:** Number of requests to read a row based on its position. If this value is high, you may not be using joins that don't use indexes properly, or be doing many full table scans.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_rnd_deleted`

 * **Description:** Number of requests to delete a row based on its position.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_read_rnd_next`

 * **Description:** Number of requests to read the next row. A large number of these may indicate many table scans and improperly used indexes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_rollback`

 * **Description:** Number of transaction rollback requests given to a storage engine. Differs from [Com\_rollback](#com_rollback), which is the number of [ROLLBACK](../rollback/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_savepoint`

 * **Description:** Number of transaction savepoint creation requests. Differs from [Com\_savepoint](#com_savepoint) which is the number of [SAVEPOINT](../savepoint/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_savepoint_rollback`

 * **Description:** Number of requests to rollback to a transaction [savepoint](../savepoint/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_tmp_delete`

 * **Description:** Number of requests to delete a row in a temporary table.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `Handler_tmp_update`

 * **Description:** Number of requests to update a row to a temporary table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_tmp_write`

 * **Description:** Number of requests to write a row to a temporary table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_update`

 * **Description:** Number of requests to update a row in a table. Since [MariaDB 5.3](../what-is-mariadb-53/index), this no longer counts temporary tables - see [Handler\_tmp\_update](#handler_tmp_update).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Handler_write`

 * **Description:** Number of requests to write a row to a table. Since [MariaDB 5.3](../what-is-mariadb-53/index), this no longer counts temporary tables - see [Handler\_tmp\_write](#handler_tmp_write).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Key_blocks_not_flushed`

 * **Description:** Number of key cache blocks which have been modified but not flushed to disk.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_blocks_unused`

 * **Description:** Number of unused key cache blocks.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_blocks_used`

 * **Description:** Max number of key cache blocks which have been used simultaneously.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_blocks_warm`

 * **Description:** Number of key cache blocks in the warm list.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_read_requests`

 * **Description:** Number of key cache block read requests. See [Optimizing key\_buffer\_size](../optimizing-key_buffer_size/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_reads`

 * **Description:** Number of physical index block reads. See [Optimizing key\_buffer\_size](../optimizing-key_buffer_size/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_write_requests`

 * **Description:** Number of requests to write a block to the key cache.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Key_writes`

 * **Description:** Number of key cache block write requests
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Last_query_cost`

 * **Description:** The most recent query optimizer query cost calculation. Can not be calculated for complex queries, such as subqueries or UNION. It will be set to 0 for complex queries.
* **Scope:** Session
* **Data Type:** `numeric`

 

---

 #### `Maria_*`

 * **Description:** When the Maria storage engine was renamed Aria, the Maria variables existing at the time were renamed at the same time. See [Aria Server Status Variables](../aria-server-status-variables/index).

 

---

 #### `Max_statement_time_exceeded`

 * **Description:** Number of queries that exceeded the execution time specified by [max\_statement\_time](../server-system-variables/index#max_statement_time). See [Aborting statements that take longer than a certain time to execute](../aborting-statements-that-take-longer-than-a-certain-time-to-execute/index).
* **Data Type:** `numeric`

 

---

 #### `Max_used_connection_time`

 * **Description:** The time at which the last change of [max\_used\_connection](#max_used_connections) occured. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global
* **Data Type:** `datetime`
* **Introduced:** [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/), [MariaDB 11.1.1](https://mariadb.com/kb/en/mariadb-11-1-1-release-notes/)

 

---

 #### `Max_used_connections`

 * **Description:** Max number of connections ever open at the same time. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Memory_used`

 * **Description:** Global or per-connection memory usage, in bytes. This includes all per-connection memory allocations, but excludes global allocations such as the key\_buffer, innodb\_buffer\_pool etc.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Memory_used_initial`

 * **Description:** Amount of memory that was used when the server started to service the user connections.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Not_flushed_delayed_rows`

 * **Description:** Number of [INSERT DELAYED](../insert-delayed/index) rows waiting to be written.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Open_files`

 * **Description:** Number of regular files currently opened by the server. Does not include sockets or pipes, or storage engines using internal functions.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Open_streams`

 * **Description:** Number of currently opened streams, usually log files.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Open_table_definitions`

 * **Description:** Number of currently cached .frm files.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Open_tables`

 * **Description:** Number of currently opened tables, excluding temporary tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Opened_files`

 * **Description:** Number of files the server has opened.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Opened_plugin_libraries`

 * **Description:** Number of shared libraries that the server has opened to load [plugins](../plugins/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Opened_table_definitions`

 * **Description:** Number of .frm files that have been cached.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Opened_tables`

 * **Description:** Number of tables the server has opened.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Opened_views`

 * **Description:** Number of views the server has opened.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Prepared_stmt_count`

 * **Description:** Current number of prepared statements.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_free_blocks`

 * **Description:** Number of free [query cache](../query-cache/index) memory blocks.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_free_memory`

 * **Description:** Amount of free [query cache](../query-cache/index) memory.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_hits`

 * **Description:** Number of requests served by the [query cache](../query-cache/index). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_inserts`

 * **Description:** Number of queries ever cached in the [query cache](../query-cache/index). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_lowmem_prunes`

 * **Description:** Number of pruning operations performed to remove old results to make space for new results in the [query cache](../query-cache/index). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_not_cached`

 * **Description:** Number of queries that are uncacheable by the [query cache](../query-cache/index), or use SQL\_NO\_CACHE. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_queries_in_cache`

 * **Description:** Number of queries currently cached by the [query cache](../query-cache/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Qcache_total_blocks`

 * **Description:** Number of blocks used by the [query cache](../query-cache/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Queries`

 * **Description:** Number of statements executed by the server, excluding COM\_PING and COM\_STATISTICS. Differs from [Questions](#questions) in that it also counts statements executed within [stored programs](../stored-programs-and-views/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Questions`

 * **Description:** Number of statements executed by the server, excluding COM\_PING, COM\_STATISTICS, COM\_STMT\_PREPARE, COM\_STMT\_CLOSE, and COM\_STMT\_RESET statements. Differs from [Queries](#queries) in that it doesn't count statements executed within [stored programs](../stored-programs-and-views/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Resultset_metadata_skipped`

 * **Description:** Number of times sending the metadata has been skipped. Metadata is not resent if metadata does not change between prepare and execute of prepared statement, or between executes.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `Rows_read`

 * **Description:** Number of requests to read a row (excluding temporary tables).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rows_sent`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rows_tmp_read`

 * **Description:** Number of requests to read a row in a temporary table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Select_full_join`

 * **Description:** Number of joins which did not use an index. If not zero, you may need to check table indexes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Select_full_range_join`

 * **Description:** Number of joins which used a range search of the first table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Select_range`

 * **Description:** Number of joins which used a range on the first table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Select_range_check`

 * **Description:** Number of joins without keys that check for key usage after each row. If not zero, you may need to check table indexes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Select_scan`

 * **Description:** Number of joins which used a full scan of the first table.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Slow_launch_threads`

 * **Description:** Number of threads which took longer than [slow\_launch\_time](../server-system-variables/index#slow_launch_time) to create. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Slow_queries`

 * **Description:** Number of queries which took longer than [long\_query\_time](../server-system-variables/index#long_query_time) to run. The [slow query log](../slow-query-log/index) does not need to be active for this to be recorded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sort_merge_passes`

 * **Description:** Number of merge passes performed by the sort algorithm. If too high, you may need to look at improving your query indexes, or increasing the [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sort_priority_queue_sorts`

 * **Description:** The number of times that sorting was done through a priority queue. (The total number of times sorting was done is a sum [Sort\_range](#sort_range) and [Sort\_scan](#sort_scan)). See [filesort with small LIMIT optimization](../filesort-with-small-limit-optimization/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sort_range`

 * **Description:** Number of sorts which used a range.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sort_rows`

 * **Description:** Number of rows sorted.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sort_scan`

 * **Description:** Number of sorts which used a full table scan.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Subquery_cache_hit`

 * **Description:** Counter for all [subquery cache](../subquery-cache/index) hits. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Subquery_cache_miss`

 * **Description:** Counter for all [subquery cache](../subquery-cache/index) misses. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Syncs`

 * **Description:** Number of times my\_sync() has been called, or the number of times the server has had to force data to disk. Covers the [binary log](../binary-log/index), .frm creation (if these operations are configured to sync) and some storage engines ([Archive](../archive/index), [CSV](../csv/index), [Aria](../aria/index)), but not [XtraDB/InnoDB](../innodb/index)).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Table_locks_immediate`

 * **Description:** Number of table locks which were completed immediately. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Table_locks_waited`

 * **Description:** Number of table locks which had to wait. Indicates table lock contention. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Table_open_cache_active_instances`

 * **Description:** Number of active instances for open tables cache lookups.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Table_open_cache_hits`

 * **Description:** Number of hits for open tables cache lookups.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Table_open_cache_misses`

 * **Description:** Number of misses for open tables cache lookups.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Table_open_cache_overflows`

 * **Description:** Number of overflows for open tables cache lookups.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Tc_log_max_pages_used`

 * **Description:** Max number of pages used by the memory-mapped file-based [transaction coordinator log](../transaction-coordinator-log/index). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Tc_log_page_size`

 * **Description:** Page size of the memory-mapped file-based [transaction coordinator log](../transaction-coordinator-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Tc_log_page_waits`

 * **Description:** Number of times a two-phase commit was forced to wait for a free memory-mapped file-based [transaction coordinator log](../transaction-coordinator-log/index) page. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Threads_cached`

 * **Description:** Number of threads cached in the thread cache. This value will be zero if the [thread pool](../thread-pool-in-mariadb/index) is in use.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Threads_connected`

 * **Description:** Number of clients connected to the server. See [Handling Too Many Connections](../handling-too-many-connections/index). The `Threads_connected` name is inaccurate when the [thread pool](../thread-pool-in-mariadb/index) is in use, since each client connection does not correspond to a dedicated thread in that case.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Threads_created`

 * **Description:** Number of threads created to respond to client connections. If too large, look at increasing [thread\_cache\_size](../server-system-variables/index#thread_cache_size).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Threads_running`

 * **Description:** Number of client connections that are actively running a command, and not just sleeping while waiting to receive the next command to execute. Some internal system threads also count towards this status variable if they would show up in the output of the `[SHOW PROCESSLIST](../show-processlist/index)` statement.
	+ In [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) and before, a global counter was updated each time a client connection dispatched a command. In these versions, the global and session status variable are always the same value.
	+ In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) and later, the global counter has been removed as a performance improvement. Instead, when the global status variable is queried, it is calculated dynamically by essentially adding up all the running client connections as they would appear in `[SHOW PROCESSLIST](../show-processlist/index)` output. A client connection is only considered to be running if its thread `[COMMAND](../thread-command-values/index)` value is not equal to `Sleep`. When the session status variable is queried, it always returns `1`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Update_scan`

 * **Description:** Number of updates that required a full table scan.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Uptime`

 * **Description:** Number of seconds the server has been running.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Uptime_since_flush_status`

 * **Description:** Number of seconds since the last [FLUSH STATUS](../flush/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/server-status-variables/>

Server System Variables
=======================

    About the Server System Variables
---------------------------------

 MariaDB has many system variables that can be changed to suit your needs.

 The full list of server variables are listed in the contents on this page, and most are described on this page, but some are described elsewhere:

 * [Aria System Variables](../aria-system-variables/index)
* [CONNECT System Variables](../connect-system-variables/index)
* [Galera System Variables](../mariadb-galera-cluster-configuration-variables/index)
* [Global Transaction ID System Variables](../gtid/index#system-variables-for-global-transaction-id)
* [HandlerSocket Plugin System Variables](../handlersocket-configuration-options/index)
* [InnoDB System Variables](../innodb-system-variables/index)
* [Mroonga System Variables](../mroonga-system-variables/index)
* [MyRocks System Variables](../myrocks-system-variables/index)
* [MyISAM System Variables](../myisam-server-system-variables/index)
* [Performance Schema System Variables](../performance-schema-system-variables/index)
* [Replication and Binary Log System Variables](../replication-and-binary-log-server-system-variables/index)
* [S3 Storage Engine System Variables](../s3-storage-engine-system-variables/index)
* [Server\_Audit System Variables](../server_audit-system-variables/index)
* [Spider System Variables](../spider-server-system-variables/index)
* [SQL\_ERROR\_LOG Plugin System Variables](../sql_error_log-plugin-system-variables/index)
* [SSL System Variables](../ssl-server-system-variables/index)
* [Threadpool System Variables](../thread-pool-system-and-status-variables/index)
* [TokuDB System Variables](../tokudb-system-variables/index)

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 Most of these can be set with [command line options](../mariadbd-options-full-list/index) and many of them can be changed at runtime. Variables that can be changed at runtime are described as "Dynamic" below, and elsewhere in the documentation.

 There are a few ways to see the full list of server system variables:

 * While in the mariadb client, run:

 
```
SHOW VARIABLES;

```

* See [SHOW VARIABLES](../show-variables/index) for instructions on using this command.

 * From your shell, run mariadbd like so:

 
```
mariadbd --verbose --help

```

* View the Information Schema [GLOBAL\_VARIABLES](../information-schema-global_variables-and-session_variables-tables/index), [SESSION\_VARIABLES](../information-schema-global_variables-and-session_variables-tables/index), and [SYSTEM\_VARIABLES](../information-schema-system_variables-table/index) tables.

 Setting Server System Variables
-------------------------------

 There are several ways to set server system variables:

 * Specify them on the command line:

 
```
shell> ./mysqld_safe --aria_group_commit="hard"

```

* Specify them in your my.cnf file (see [Configuring MariaDB with my.cnf](../configuring-mariadb-with-mycnf/index) for more information):

 
```
aria_group_commit = "hard"

```

* Set them from the mariadb client using the [SET](../set/index) command. Only variables that are dynamic can be set at runtime in this way. Note that variables set in this way will not persist after a restart.

 
```
SET GLOBAL aria_group_commit="hard";

```

By convention, server variables have usually been specified with an underscore in the configuration files, and a dash on the command line. You can however specify underscores as dashes - they are interchangeable.

 Variables that take a numeric size can either be specified in full, or with a suffix for easier readability. Valid suffixes are:

 


| Suffix | Description | Value |
| --- | --- | --- |
| K | kilobytes | 1024 |
| M | megabytes | 10242 |
| G | gigabytes | 10243 |
| T | terabytes | 10244 (from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)) |
| P | petabytes | 10245 (from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)) |
| E | exabytes | 10246 (from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)) |

 
The suffix can be upper or lower-case.

 List of Server System Variables
-------------------------------

 #### `alter_algorithm`

 * **Description:** The implied `ALGORITHM` for [ALTER TABLE](../alter-table/index) if no `ALGORITHM` clause is specified. The deprecated variable [old\_alter\_table](#old_alter_table) is an alias for this.
	+ `COPY` corresponds to the pre-MySQL 5.1 approach of creating an intermediate table, copying data one row at a time, and renaming and dropping tables.
	+ `INPLACE` requests that the operation be refused if it cannot be done natively inside a the storage engine.
	+ `DEFAULT` (the default) chooses `INPLACE` if available, and falls back to `COPY`.
	+ `NOCOPY` refuses to copy a table.
	+ `INSTANT` refuses an operation that would involve any other than metadata changes.
* **Commandline:** `--alter-algorithm=default`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumerated`
* **Default Value:** `DEFAULT`
* **Valid Values:** `DEFAULT`, `COPY`, `INPLACE`, `NOCOPY`, `INSTANT`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 #### `analyze_sample_percentage`

 * **Description:** Percentage of rows from the table [ANALYZE TABLE](../analyze-table/index) will sample to collect table statistics. Set to 0 to let MariaDB decide what percentage of rows to sample.
* **Commandline:** `--analyze-sample-percentage=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100.000000`
* **Range:** `0` to `100`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 #### `autocommit`

 * **Description:** If set to 1, the default, all queries are committed immediately. The [LOCK IN SHARE MODE](../lock-in-share-mode/index) and [FOR UPDATE](../for-update/index) clauses therefore have no effect. If set to 0, they are only committed upon a [COMMIT](../transactions-commit-statement/index) statement, or rolled back with a [ROLLBACK](../rollback-statement/index) statement. If autocommit is set to 0, and then changed to 1, all open transactions are immediately committed.
* **Commandline:** `--autocommit[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `automatic_sp_privileges`

 * **Description:** When set to 1, the default, when a stored routine is created, the creator is automatically granted permission to [ALTER](../alter-procedure/index) (which includes dropping) and to EXECUTE the routine. If set to 0, the creator is not automatically granted these privileges.
* **Commandline:** `--automatic-sp-privileges`, `--skip-automatic-sp-privileges`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `back_log`

 * **Description:** Connections take a small amount of time to start, and this setting determines the number of outstanding connection requests MariaDB can have, or the size of the listen queue for incoming TCP/IP requests. Requests beyond this will be refused. Increase if you expect short bursts of connections. Cannot be set higher than the operating system limit (see the Unix listen() man page). If not set, set to `0`, or the `--autoset-back-log` option is used, will be autoset to the lower of `900` and (50 + [max\_connections](#max_connections)/5).
* **Commandline:** `--back-log=#`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Default Value:**
	+ The lower of `900` and (50 + [max\_connections](#max_connections)/5)

 

---

 #### `basedir`

 * **Description:** Path to the MariaDB installation directory. Other paths are usually resolved relative to this base directory.
* **Commandline:** `--basedir=path` or `-b path`
* **Scope:** Global
* **Dynamic:** No
* **Type:** directory name

 

---

 #### `big_tables`

 * **Description:** If this system variable is set to 1, then temporary tables will be saved to disk intead of memory.
	+ This system variable's original intention was to allow result sets that were too big for memory-based temporary tables and to avoid the resulting 'table full' errors.
	+ This system variable is no longer needed, because the server can automatically convert large memory-based temporary tables into disk-based temporary tables when they exceed the value of the `[tmp\_memory\_table\_size](#tmp_memory_table_size)` system variable.
	+ To prevent memory-based temporary tables from being used at all, set the `[tmp\_memory\_table\_size](#tmp_memory_table_size)` system variable to `0`.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and earlier, `[sql\_big\_tables](#sql_big_tables)` is a synonym.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable is deprecated.
* **Commandline:** `--big-tables`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Deprecated:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `bind_address`

 * **Description:** By default, the MariaDB server listens for TCP/IP connections on all addresses. You can specify an alternative when the server starts using this option; either a host name, an IPv4 or an IPv6 address, "::" or "\*" (all addresses). In some systems, such as Debian and Ubuntu, the bind\_address is set to 127.0.0.1, which binds the server to listen on localhost only. `bind_address` has always been available as a [mariadbd option](../mariadbd-options/index); from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) its also available as a system variable. Before [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) "::" implied listening additionally on IPv4 addresses like "\*". From 10.6.0 onwards it refers to IPv6 stictly. See also [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index).
* **Commandline:** `--bind-address=addr`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty string)
* **Valid Values:** Host name, IPv4, IPv6, ::, \*
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) (as a system variable)

 

---

 #### `block_encryption_mode`

 * **Description:** Default block encryption mode for [AES\_ENCRYPT()](../aes_encrypt/index) and [AES\_DECRYPT()](../aes_decrypt/index) functions.
* **Commandline:** `--block-encryption-mode=val`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `aes-128-ecb`
* **Valid values:** `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`
* **Introduced:** [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 

---

 #### `bulk_insert_buffer_size`

 * **Description:** Size in bytes of the per-thread cache tree used to speed up bulk inserts into [MyISAM](../myisam/index) and [Aria](../aria/index) tables. A value of 0 disables the cache tree.
* **Commandline:** `--bulk-insert-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8388608`
* **Range - 32 bit:** `0` to `4294967295`
* **Range - 64 bit:** `0` to `18446744073709547520`

 

---

 #### `character_set_client`

 * **Description:** Determines the [character set](../data-types-character-sets-and-collations/index) for queries arriving from the client. It can be set per session by the client, although the server can be configured to ignore client requests with the `--skip-character-set-client-handshake` option. If the client does not request a character set, or requests a character set that the server does not support, the global value will be used. utf16, utf16le, utf32 and ucs2 cannot be used as client character sets. From [MariaDB 10.6](../what-is-mariadb-106/index), the `utf8` [character set](../character-sets/index) (and related collations) is by default an alias for `utf8mb3` rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](index#old_mode) system variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `utf8mb3` (>= [MariaDB 10.6](../what-is-mariadb-106/index)), `utf8` (<= [MariaDB 10.5](../what-is-mariadb-105/index))

 

---

 #### `character_set_connection`

 * **Description:** [Character set](../data-types-character-sets-and-collations/index) used for number to string conversion, as well as for literals that don't have a character set introducer. From [MariaDB 10.6](../what-is-mariadb-106/index), the `utf8` [character set](../character-sets/index) (and related collations) is by default an alias for `utf8mb3` rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](index#old_mode) system variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `utf8mb3` (>= [MariaDB 10.6](../what-is-mariadb-106/index)), `utf8` (<= [MariaDB 10.5](../what-is-mariadb-105/index))

 

---

 #### `character_set_database`

 * **Description:** [Character set](../data-types-character-sets-and-collations/index) used by the default database, and set by the server whenever the default database is changed. If there's no default database, character\_set\_database contains the same value as [character\_set\_server](#character_set_server). This variable is dynamic, but should not be set manually, only by the server.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `latin1`

 

---

 #### `character_set_filesystem`

 * **Description:** The [character set](../data-types-character-sets-and-collations/index) for the filesystem. Used for converting file names specified as a string literal from [character\_set\_client](#character_set_client) to character\_set\_filesystem before opening the file. By default set to `binary`, so no conversion takes place. This could be useful for statements such as [LOAD\_FILE()](../load_file/index) or [LOAD DATA INFILE](../load-data-infile/index) on system where multi-byte file names are use.
* **Commandline:** `--character-set-filesystem=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `binary`

 

---

 #### `character_set_results`

 * **Description:** [Character set](../data-types-character-sets-and-collations/index) used for results and error messages returned to the client. From [MariaDB 10.6](../what-is-mariadb-106/index), the `utf8` [character set](../character-sets/index) (and related collations) is by default an alias for `utf8mb3` rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](index#old_mode) system variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `utf8mb3` (>= [MariaDB 10.6](../what-is-mariadb-106/index)), `utf8` (<= [MariaDB 10.5](../what-is-mariadb-105/index))

 

---

 #### `character_set_server`

 * **Description:** Default [character set](../data-types-character-sets-and-collations/index) used by the server. See [character\_set\_database](#character_set_database) for character sets used by the default database. Defaults may be different on some systems, see for example [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index).
* **Commandline:** `--character-set-server`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `latin1`

 

---

 #### `character_set_system`

 * **Description:** [Character set](../data-types-character-sets-and-collations/index) used by the server to store identifiers, always set to utf8, or its synonym utf8mb3 starting with [MariaDB 10.6](../what-is-mariadb-106/index). From [MariaDB 10.6](../what-is-mariadb-106/index), the `utf8` [character set](../character-sets/index) (and related collations) is by default an alias for `utf8mb3` rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](index#old_mode) system variable.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `utf8mb3` (>= [MariaDB 10.6](../what-is-mariadb-106/index)), `utf8` (<= [MariaDB 10.5](../what-is-mariadb-105/index))

 

---

 #### `character_sets_dir`

 * **Description:** Directory where the [character sets](../data-types-character-sets-and-collations/index) are installed.
* **Commandline:** `--character-sets-dir=path`
* **Scope:** Global
* **Dynamic:** No
* **Type:** directory name

 

---

 #### `check_constraint_checks`

 * **Description:** If set to `0`, will disable [constraint checks](../constraint/index), for example when loading a table that violates some constraints that you plan to fix later.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** boolean
* **Default:** ON

 

---

 #### `collation_connection`

 * **Description:** Collation used for the connection [character set](../data-types-character-sets-and-collations/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `collation_database`

 * **Description:** [Collation used](../data-types-character-sets-and-collations/index) for the default database. Set by the server if the default database changes, if there is no default database the value from the `collation_server` variable is used. This variable is dynamic, but should not be set manually, only by the server.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `collation_server`

 * **Description:** Default [collation](../data-types-character-sets-and-collations/index) used by the server. This is set to the default collation for a given character set automatically when [character\_set\_server](#character_set_server) is changed, but it can also be set manually. Defaults may be different on some systems, see for example [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index).
* **Commandline:** `--collation-server=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `latin1_swedish_ci`

 

---

 #### `completion_type`

 * **Description:** The transaction completion type. If set to `NO_CHAIN` or `0` (the default), there is no effect on commits and rollbacks. If set to `CHAIN` or `1`, a [COMMIT](../transactions-commit-statement/index) statement is equivalent to COMMIT AND CHAIN, while a [ROLLBACK](../rollback-statement/index) is equivalent to ROLLBACK AND CHAIN, so a new transaction starts straight away with the same isolation level as transaction that's just finished. If set to `RELEASE` or `2`, a [COMMIT](../transactions-commit-statement/index) statement is equivalent to COMMIT RELEASE, while a [ROLLBACK](../rollback-statement/index) is equivalent to ROLLBACK RELEASE, so the server will disconnect after the transaction completes. Note that the transaction completion type only applies to explicit commits, not implicit commits.
* **Commandline:** `--completion-type=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumerated`
* **Default Value:** `NO_CHAIN`
* **Valid Values:** `0`, `1`, `2`, `NO_CHAIN`, `CHAIN`, `RELEASE`

 

---

 #### `concurrent_insert`

 * **Description:** If set to `AUTO` or `1`, the default, MariaDB allows [concurrent INSERTs](../concurrent-inserts/index) and SELECTs for [MyISAM](../myisam/index) tables with no free blocks in the data (deleted rows in the middle). If set to `NEVER` or `0`, concurrent inserts are disabled. If set to `ALWAYS` or `2`, concurrent inserts are permitted for all MyISAM tables, even those with holes, in which case new rows are added at the end of a table if the table is being used by another thread.   
  
If the [--skip-new](../mariadbd-options/index#-skip-new) option is used when starting the server, concurrent\_insert is set to `NEVER`.   
  
Changing the variable only affects new opened tables. Use [FLUSH TABLES](../flush/index) If you want it to also affect cached tables.   
  
See [Concurrent Inserts](../concurrent-inserts/index) for more.
* **Commandline:** `--concurrent-insert[=value]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumerated`
* **Default Value:** `AUTO`
* **Valid Values:** `0`, `1`, `2`, `AUTO`, `NEVER`, `ALWAYS`

 

---

 #### `connect_timeout`

 * **Description:** Time in seconds that the server waits for a connect packet before returning a 'Bad handshake'. Increasing may help if clients regularly encounter 'Lost connection to MySQL server at 'X', system error: error\_number' type-errors.
* **Commandline:** `--connect-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `10`

 

---

 #### `core_file`

 * **Description:** Write a core-file on crashes. The file name and location are system dependent. On Linux it is usually called `core.${PID}`, and it is usually written to the data directory. However, this can be changed.
	+ See [Enabling Core Dumps](../enabling-core-dumps/index) for more information.
	+ Previously this system variable existed only as an [option](../mariadbd-options/index), but it was also made into a read-only system variable starting with [MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/) and [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/).
	+ On Windows >= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), this option is set by default.
	+ Note that the option accepts no arguments; specifying `--core-file` sets the value to `ON`. It cannot be disabled in the case of Windows >= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).
* **Commandline:** `--core-file`
* **Scope:** Global
* **Dynamic:** No
* **Type:** boolean
* **Default Value:**
	+ Windows >= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/): `ON`
	+ All other systems: `OFF`

 

---

 #### `datadir`

 * **Description:** Directory where the data is stored.
* **Commandline:** `--datadir=path` or `-h path`
* **Scope:** Global
* **Dynamic:** No
* **Type:** directory name

 

---

 #### `date_format`

 * **Description:** Unused.

 

---

 #### `datetime_format`

 * **Description:** Unused.

 

---

 #### `debug/debug_dbug`

 * **Description:** Available in debug builds only (built with -DWITH\_DEBUG=1). Used in debugging through the DBUG library to write to a trace file. Just using `--debug` will write a trace of what mariadbd is doing to the default trace file.
* **Commandline:** `-#`, `--debug[=debug_options]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:**
	+ <= [MariaDB 10.4](../what-is-mariadb-104/index): `d:t:i:o,/tmp/mysqld.trace` (Unix) or `d:t:i:O,\mysqld.trace` (Windows)
	+ >= [MariaDB 10.5](../what-is-mariadb-105/index): `d:t:i:o,/tmp/mariadbd.trace` (Unix) or `d:t:i:O,\mariadbd.trace` (Windows)
* **Debug Options:** See the option flags on the [mysql\_debug](../mysql_debug/index) page

 

---

 #### `debug_no_thread_alarm`

 * **Description:** Disable system thread alarm calls. Disabling it may be useful in debugging or testing, never do it in production.
* **Commandline:** `--debug-no-thead-alarm=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** MariaDB

 

---

 #### `debug_sync`

 * **Description:** Used in debugging to show the interface to the [Debug Sync facility](../the-debug-sync-facility/index). MariaDB needs to be configured with -DENABLE\_DEBUG\_SYNC=1 for this variable to be available.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `OFF` or `ON - current signal *signal name*`

 

---

 #### `default_password_lifetime`

 * **Description:** This defines the global [password expiration policy](../user-password-expiry/index). 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](../alter-user/index).
* **Commandline:** `--default-password-lifetime=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `default_regex_flags`

 * **Description:** Introduced to address remaining incompatibilities between [PCRE](../pcre-regular-expressions/index) and the old regex library. Accepts a comma-separated list of zero or more of the following values:

 


|  |  |  |
| --- | --- | --- |
| Value | Pattern equivalent | Meaning |
| DOTALL | (?s) | . matches anything including NL |
| DUPNAMES | (?J) | Allow duplicate names for subpatterns |
| EXTENDED | (?x) | Ignore white space and # comments |
| EXTRA | (?X) | extra features (e.g. error on unknown escape character) |
| MULTILINE | (?m) | ^ and $ match newlines within data |
| UNGREEDY | (?U) | Invert greediness of quantifiers |

 
* **Commandline:** `--default-regex-flags=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** enumeration
* **Default Value:** empty
* **Valid Values:** `DOTALL`, `DUPNAMES`, `EXTENDED`, `EXTRA`, `MULTILINE`, `UNGREEDY`

 

---

 #### `default_storage_engine`

 * **Description:** The default [storage engine](../mariadb-storage-engines/index). The default storage engine must be enabled at server startup or the server won't start.
* **Commandline:** `--default-storage-engine=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** enumeration
* **Default Value:** `InnoDB`

 

---

 #### `default_table_type`

 * **Description:** A synonym for [default\_storage\_engine](#default_storage_engine). Removed in [MariaDB 5.5](../what-is-mariadb-55/index).
* **Commandline:** `--default-table-type=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `default_tmp_storage_engine`

 * **Description:** Default storage engine that will be used for tables created with [CREATE TEMPORARY TABLE](../create-table/index) where no engine is specified. For internal temporary tables see [aria\_used\_for\_temp\_tables](../aria-system-variables/index#aria_used_for_temp_tables)). The storage engine used must be active or the server will not start. See [default\_storage\_engine](#default_storage_engine) for the default for non-temporary tables. Defaults to NULL, in which case the value from [default\_storage\_engine](#default_storage_engine) is used. [ROCKSDB](../myrocks/index) temporary tables cannot be created. Before [MariaDB 10.7](../what-is-mariadb-107/index), attempting to do so would silently fail, and a MyISAM table would instead be created. From [MariaDB 10.7](../what-is-mariadb-107/index), an error is returned.
* **Commandline:** `--default-tmp-storage-engine=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** NULL

 

---

 #### `default_week_format`

 * **Description:** Default mode for the [WEEK()](../week/index) function. See that page for details on the different modes
* **Commandline:** `--default-week-format=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `7`

 

---

 #### `delay_key_write`

 * **Description:** Specifies how MyISAM tables handles [CREATE TABLE](../create-table/index) 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.
* **Commandline:** `--delay-key-write[=name]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `ON`
* **Valid Values:** `ON`, `OFF`, `ALL`

 

---

 #### `delayed_insert_limit`

 * **Description:** After this many rows have been inserted with [INSERT DELAYED](../insert-delayed/index), the handler will check for and execute any waiting [SELECT](../select/index) statements.
* **Commandline:** `--delayed-insert-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `1` to `4294967295`

 

---

 #### `delayed_insert_timeout`

 * **Description:** Time in seconds that the [INSERT DELAYED](../insert-delayed/index) handler will wait for INSERTs before terminating.
* **Commandline:** `--delayed-insert-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `300`

 

---

 #### `delayed_queue_size`

 * **Description:** Number of rows, per table, that can be queued when performing [INSERT DELAYED](../insert-delayed/index) statements. If the queue becomes full, clients attempting to perform INSERT DELAYED's will wait until the queue has room available again.
* **Commandline:** `--delayed-queue-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `1000`
* **Range:** `1 to 4294967295`

 

---

 #### `disconnect_on_expired_password`

 * **Description:** When a user password has expired (see [User Password Expiry](../user-password-expiry/index)), this variable controls how the server handles clients that are not aware of the sandbox mode. If enabled, the client is not permitted to connect, otherwise the server puts the client in a sandbox mode.
* **Commandline:** `--disconnect-on-expired-password[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Type:** boolean
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `div_precision_increment`

 * **Description:** The precision of the result of the decimal division will be the larger than the precision of the dividend by that number. By default it's `4`, so `SELECT 2/15` would return 0.1333 and `SELECT 2.0/15` would return 0.13333. After setting div\_precision\_increment to `6`, for example, the same operation would return 0.133333 and 0.1333333 respectively.

 
From [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/), `div_precision_increment` is taken into account in intermediate calculations. Previous versions did not, and the results were dependent on the optimizer, and therefore unpredictable.

  
 In [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10415-release-notes/), [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/) and [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/) only, the fix truncated decimal values after every division, resulting in lower precision in some cases for those versions only.

  
 From [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10148-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/) and [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), a different fix was implemented. Instead of truncating decimal values after every division, they are instead truncated for comparison purposes only.

  
 For example

  
 Versions other than [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10415-release-notes/), [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/) and [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/):

  
```
SELECT (55/23244*1000);
+-----------------+
| (55/23244*1000) |
+-----------------+
|          2.3662 |
+-----------------

```


 [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10415-release-notes/), [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/) and [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/) only:

  
```
SELECT (55/23244*1000);
+-----------------+
| (55/23244*1000) |
+-----------------+
|          2.4000 |
+-----------------+

```


 This is because the intermediate result, `SELECT 55/23244` takes into account `div_precision_increment` and results were truncated after every division in those versions only.

  * **Commandline:** `--div-precision-increment=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4`
* **Range:** `0` to `30`

 

---

 #### `encrypt_tmp_disk_tables`

 * **Description:** Enables automatic encryption of all internal on-disk temporary tables that are created during query execution if `[aria\_used\_for\_temp\_tables=ON](../aria-system-variables/index#aria_used_for_temp_tables)` is set. See [Data at Rest Encryption](../data-at-rest-encryption/index) and [Enabling Encryption for Internal On-disk Temporary Tables](../encrypting-data-for-aria/index#enabling-encryption-for-internal-on-disk-temporary-tables).
* **Commandline:** `--encrypt-tmp-disk-tables[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `encrypt_tmp_files`

 * **Description:** Enables automatic encryption of temporary files, such as those created for filesort operations, binary log file caches, etc. See [Data at Rest Encryption](../data-at-rest-encryption/index).
* **Commandline:** `--encrypt-tmp-files[={0|1}]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `encryption_algorithm`

 * **Description:** Which encryption algorithm to use for table encryption. `aes_cbc` is the recommended one. See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Commandline:** `--encryption-algorithm=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enum`
* **Default Value:** `none`
* **Valid Values:** `none`, `aes_ecb`, `aes_cbc`, `aes_ctr`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)

 

---

 #### `enforce_storage_engine`

 * **Description:** Force the use of a particular storage engine for new tables. Used to avoid unwanted creation of tables using another engine. For example, setting to [InnoDB](../innodb/index) will prevent any [MyISAM](../myisam/index) tables from being created. If another engine is specified in a [CREATE TABLE](../create-table/index) statement, the outcome depends on whether the `NO_ENGINE_SUBSTITUTION` [SQL\_MODE](../sql-mode/index) has been set or not. If set, the query will fail, while if not set, a warning will be returned and the table created according to the engine specified by this variable. The variable has a session scope, but is only modifiable by a user with the SUPER privilege.
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `none`

 

---

 #### `engine_condition_pushdown`

 * **Description:** Deprecated in [MariaDB 5.5](../what-is-mariadb-55/index) and removed and replaced by the [optimizer\_switch](#optimizer_switch) `engine_condition_pushdown={on|off}` flag in [MariaDB 10.0](../what-is-mariadb-100/index).. Specifies whether the engine condition pushdown optimization is enabled. Since [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), engine condition pushdown is enabled for all engines that support it.
* **Commandline:** `--engine-condition-pushdown`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `eq_range_index_dive_limit`

 * **Description:** Limit used for speeding up queries listed by long nested INs. 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` (unlimited, the default), index dives are always used.
* **Commandline:** `--eq-range-index-dive-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `200` (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), `0` (<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))
* **Range:** `0` to `4294967295`

 

---

 #### `error_count`

 * **Description:** Read-only variable denoting the number of errors from the most recent statement in the current session that generated errors. See [SHOW\_ERRORS()](../show-errors/index).
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`

 

---

 #### `event_scheduler`

 * **Description:** Status of the [Event](../events/index) Scheduler. Can be set to `ON` or `OFF`, while `DISABLED` means it cannot be set at runtime. Setting the variable will cause a load of events if they were not loaded at startup.
* **Commandline:** `--event-scheduler[=value]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `OFF`
* **Valid Values:** `ON` (or `1`), `OFF` (or `0`), `DISABLED`

 

---

 #### `expensive_subquery_limit`

 * **Description:** Number of rows to be examined for a query to be considered expensive, that is, maximum number of rows a subquery may examine in order to be executed during optimization and used for constant optimization.
* **Commandline:** `--expensive-subquery-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `0` upwards

 

---

 #### `explicit_defaults_for_timestamp`

 * **Description:** This option causes [CREATE TABLE](../create-table/index) to create all [TIMESTAMP](../timestamp/index) columns as [NULL](../null-values/index) with the DEFAULT NULL attribute, Without this option, TIMESTAMP columns are NOT NULL and have implicit DEFAULT clauses.
* **Commandline:** `--explicit-defaults-for-timestamp=[={0|1}]`
* **Scope:**
	+ Global, Session (>= [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-1075-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10517-release-notes/))
	+ Global (<= [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/), [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/))
* **Dynamic:**
	+ Yes (>= [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-1075-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10517-release-notes/))
	+ No (<= [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/), [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/))
* **Data Type:** `boolean`
* **Default Value:**`ON` (>= [MariaDB 10.10](../what-is-mariadb-1010/index)), `OFF` (<= [MariaDB 10.9](../what-is-mariadb-109/index))

 

---

 #### `external_user`

 * **Description:** External user name set by the plugin used to authenticate the client. `NULL` if native MariaDB authentication is used.
* **Scope:** Session
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `NULL`

 

---

 #### `flush`

 * **Description:** Usually, MariaDB writes changes to disk after each SQL statement, and the operating system handles synchronizing (flushing) it to disk. If set to `ON`, the server will synchronize all changes to disk after each statement.
* **Commandline:** `--flush`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `flush_time`

 * **Description:** Interval in seconds that tables are closed to synchronize (flush) data to disk and free up resources. If set to 0, the default, there is no automatic synchronizing tables and closing of tables. This option should not be necessary on systems with sufficient resources.
* **Commandline:** `--flush_time=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

 #### `foreign_key_checks`

 * **Description:** If set to 1 (the default) [foreign key constraints](../foreign-keys/index) (including ON UPDATE and ON DELETE behavior) [InnoDB](../innodb/index) tables are checked, while if set to 0, they are not checked. `0` is not recommended for normal use, though it can be useful in situations where you know the data is consistent, but want to reload data in a different order from that that specified by parent/child relationships. Setting this variable to 1 does not retrospectively check for inconsistencies introduced while set to 0.
* **Commandline:** None
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `ft_boolean_syntax`

 * **Description:** List of operators supported by an IN BOOLEAN MODE [full-text search](../full-text-indexes/index). If you wish to change, note that each character must be ASCII and non-alphanumeric, the full string must be 14 characters and the first or second character must be a space. Positions 10, 13 and 14 are reserved for future extensions. Also, no duplicates are permitted except for the phrase quoting characters in positions 11 and 12, which may be the same.
* **Commandline:** `--ft-boolean-syntax=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `+ -><()*:""&|`

 

---

 #### `ft_max_word_len`

 * **Description:** Maximum length for a word to be included in the [MyISAM](../myisam/index) [full-text index](../full-text-indexes/index). If this variable is changed, the full-text index must be rebuilt in order for the new value to take effect. The quickest way to do this is by issuing a `REPAIR TABLE table_name QUICK` statement. See [innodb\_ft\_max\_token\_size](../innodb-system-variables/index#innodb_ft_max_token_size) for the [InnoDB](../innodb/index) equivalent.
* **Commandline:** `--ft-max-word-len=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `84`
* **Minimum Value:** `10`

 

---

 #### `ft_min_word_len`

 * **Description:** Minimum length for a word to be included in the [MyISAM](../myisam/index) [full-text index](../full-text-indexes/index). If this variable is changed, the full-text index must be rebuilt in order for the new value to take effect. The quickest way to do this is by issuing a `REPAIR TABLE table_name QUICK` statement. See [innodb\_ft\_min\_token\_size](../innodb-system-variables/index#innodb_ft_min_token_size) for the [InnoDB](../innodb/index) equivalent.
* **Commandline:** `--ft-min-word-len=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `4`
* **Minimum Value:** `1`

 

---

 #### `ft_query_expansion_limit`

 * **Description:** For [full-text searches](../full-text-indexes/index), denotes the numer of top matches when using WITH QUERY EXPANSION.
* **Commandline:** `--ft-query-expansion-limit=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `0` to `1000`

 

---

 #### `ft_stopword_file`

 * **Description:** File containing a list of [stopwords](../stopwords/index) for use in [MyISAM](../myisam/index) [full-text searches](../full-text-indexes/index). Unless an absolute path is specified the file will be looked for in the data directory. The file is not parsed for comments, so all words found become stopwords. By default, a built-in list of words (built from `storage/myisam/ft_static.c file`) is used. Stopwords can be disabled by setting this variable to `''` (an empty string). If this variable is changed, the full-text index must be rebuilt. The quickest way to do this is by issuing a `REPAIR TABLE table_name QUICK` statement. See [innodb\_ft\_server\_stopword\_table](../innodb-system-variables/index#innodb_ft_server_stopword_table) for the [InnoDB](../innodb/index) equivalent.
* **Commandline:** `--ft-stopword-file=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** `(built-in)`

 

---

 #### `general_log`

 * **Description:** If set to 0, the default unless the --general-log option is used, the [general query log](../general-query-log/index) is disabled, while if set to 1, the general query log is enabled. See [log\_output](#log_output) for how log files are written. If that variable is set to `NONE`, no logs will be written even if general\_query\_log is set to `1`.
* **Commandline:** `--general-log`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `general_log_file`

 * **Description:** Name of the [general query log](../general-query-log/index) file. If this is not specified, the name is taken from the [log-basename](../mariadbd-options/index#-log-basename) setting or from your system hostname with `.log` as a suffix.
* **Commandline:** `--general-log-file=file_name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `file name`
* **Default Value:** `*host\_name*.log`

 

---

 #### `group_concat_max_len`

 * **Description:** Maximum length in bytes of the returned result for a [GROUP\_CONCAT()](../group_concat/index) function.
* **Commandline:** `--group-concat-max-len=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `1048576` (1M)
* **Range:** `4` to `4294967295`

 

---

  . 

 #### `have_compress`

 * **Description:** If the zlib compression library is accessible to the server, this will be set to `YES`, otherwise it will be `NO`. The [COMPRESS()](../compress/index) and [UNCOMPRESS()](../uncompress/index) functions will only be available if set to `YES`.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_crypt`

 * **Description:** If the crypt() system call is available this variable will be set to `YES`, otherwise it will be set to `NO`. If set to `NO`, the [ENCRYPT()](../encrypt/index) function cannot be used.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_csv`

 * **Description:** If the server supports [CSV tables](../csv/index), will be set to `YES`, otherwise will be set to `NO`. Removed in [MariaDB 10.0](../what-is-mariadb-100/index), use the [Information Schema PLUGINS](../information-schema-plugins-table/index) table or [SHOW ENGINES](../show-engines/index) instead.
* **Scope:** Global
* **Dynamic:** No
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `have_dynamic_loading`

 * **Description:** If the server supports dynamic loading of [plugins](../mariadb-plugins/index), will be set to `YES`, otherwise will be set to `NO`.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_geometry`

 * **Description:** If the server supports spatial data types, will be set to `YES`, otherwise will be set to `NO`.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_ndbcluster`

 * **Description:** If the server supports NDBCluster ([disabled in MariaDB](../ndb-disabled-in-mariadb/index)).
* **Scope:** Global
* **Dynamic:** No
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `have_partitioning`

 * **Description:** If the server supports partitioning, will be set to `YES`, unless the `--skip-partition` option is used, in which case will be set to `DISABLED`. Will be set to `NO` otherwise. Removed in [MariaDB 10.0](../what-is-mariadb-100/index) - [SHOW PLUGINS](../show-plugins/index) should be used instead.
* **Scope:** Global
* **Dynamic:** No
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `have_profiling`

 * **Description:** If statement profiling is available, will be set to `YES`, otherwise will be set to `NO`. See [SHOW PROFILES()](../show-profiles/index) and [SHOW PROFILE()](../show-profile/index).
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_query_cache`

 * **Description:** If the server supports the [query cache](../the-query-cache/index), will be set to `YES`, otherwise will be set to `NO`.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_rtree_keys`

 * **Description:** If RTREE indexes (used for [spatial indexes](../spatial-index/index)) are available, will be set to `YES`, otherwise will be set to `NO`.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_symlink`

 * **Description:** This system variable can be used to determine whether the server supports symbolic links (note that it has no meaning on Windows).
	+ If symbolic links are supported, then the value will be `YES`.
	+ If symbolic links are not supported, then the value will be `NO`.
	+ If symbolic links are disabled with the [--symbolic-links](../mariadbd-options/index#-symbolic-links) option and the `skip` [option prefix](../mariadbd-options/index#option-prefixes) (i.e. --skip-symbolic-links), then the value will be `DISABLED`.
	+ Symbolic link support is required for the [INDEX DIRECTORY](../create-table/index#data-directoryindex-directory) and [DATA DIRECTORY](../create-table/index#data-directoryindex-directory) table options.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `histogram_size`

 * **Description:** Number of bytes used for a [histogram](../histogram-based-statistics/index), or, from [MariaDB 10.7](../what-is-mariadb-107/index) when [histogram\_type](#histogram_type) is set to `JSON_HB`, number of buckets. If set to 0, no histograms are created by [ANALYZE](../analyze-table/index).
* **Commandline:** `--histogram-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `254` (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), `0` (<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))
* **Range:** `0` to `255`

 

---

 #### `histogram_type`

 * **Description:** Specifies the type of [histograms](../histogram-based-statistics/index) created by [ANALYZE](../analyze-table/index).
	+ `SINGLE_PREC_HB` - single precision height-balanced.
	+ `DOUBLE_PREC_HB` - double precision height-balanced.
	+ `JSON_HB` - JSON histograms (from [MariaDB 10.7](../what-is-mariadb-107/index))
* **Commandline:** `--histogram-type=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `DOUBLE_PREC_HB` (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), `SINGLE_PREC_HB`(<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))
* **Valid Values:**
	+ `SINGLE_PREC_HB`, `DOUBLE_PREC_HB` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
	+ `SINGLE_PREC_HB`, `DOUBLE_PREC_HB`, `JSON_HB` (>= [MariaDB 10.7](../what-is-mariadb-107/index))

 

---

 #### `host_cache_size`

 * **Description:** Number of host names that will be cached to avoid resolving. Setting to `0` disables the cache. Changing the value while the server is running causes an implicit [FLUSH HOSTS](../flush/index), clearing the host cache and truncating the [performance\_schema.host\_cache](../performance-schema-host_cache-table/index) table. If you are connecting from a lot of different machines you should consider increasing.
* **Commandline:** `--host-cache-size=#`.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `128`
* **Range:** `0` to `65536`

 

---

 #### `hostname`

 * **Description:** When the server starts, this variable is set to the server host name.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `identity`

 * **Description:** A synonym for [last\_insert\_id](#last_insert_id) variable.

 

---

 #### `idle_readonly_transaction_timeout`

 * **Description:** Time in seconds that the server waits for idle read-only transactions before killing the connection. If set to `0`, the default, connections are never killed. See also [idle\_transaction\_timeout](#idle_transaction_timeout), [idle\_write\_transaction\_timeout](#idle_write_transaction_timeout) and [Transaction Timeouts](../transaction-timeouts/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `31536000`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `idle_transaction_timeout`

 * **Description:** Time in seconds that the server waits for idle transactions before killing the connection. If set to `0`, the default, connections are never killed. See also [idle\_readonly\_transaction\_timeout](#idle_readonly_transaction_timeout), [idle\_write\_transaction\_timeout](#idle_write_transaction_timeout) and [Transaction Timeouts](../transaction-timeouts/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `31536000`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `idle_write_transaction_timeout`

 * **Description:** Time in seconds that the server waits for idle read-write transactions before killing the connection. If set to `0`, the default, connections are never killed. See also [idle\_transaction\_timeout](#idle_transaction_timeout), [idle\_readonly\_transaction\_timeout](#idle_readonly_transaction_timeout) and [Transaction Timeouts](../transaction-timeouts/index). Called `idle_readwrite_transaction_timeout` until [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `31536000`
* **Introduced:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `ignore_db_dirs`

 * **Description:** Tells the server that this directory can never be a database. That means two things - firstly it is ignored by the [SHOW DATABASES](../show-databases/index) command and [INFORMATION\_SCHEMA](../information-schema/index) tables. And secondly, USE, CREATE DATABASE and SELECT statements will return an error if the database from the ignored list specified. Use this option several times if you need to ignore more than one directory. To make the list empty set the void value to the option as --ignore-db-dir=. If the option or configuration is specified multiple times, viewing this value will list the ignore directories separated by a period.
* **Commandline:** `--ignore-db-dirs=dir`.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `in_predicate_conversion_threshold`

 * **Description:** The minimum number of scalar elements in the value list of an IN predicate that triggers its conversion to an IN subquery. Set to 0 to disable the conversion. See [Conversion of Big IN Predicates Into Subqueries](../conversion-of-big-in-predicates-into-subqueries/index).
* **Commandline:** `--in-predicate-conversion-threshold=#`
* **Scope:** Global, Session
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/) (previously debug builds only)

 

---

 #### `in_transaction`

 * **Description:** Session-only and read-only variable that is set to `1` if a transaction is in progress, `0` if not.
* **Commandline:** No
* **Scope:** Session
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `init_connect`

 * **Description:** String containing one or more SQL statements, separated by semicolons, that will be executed by the server for each client connecting. If there's a syntax error in the one of the statements, the client will fail to connect. For this reason, the statements are not executed for users with the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [CONNECTION ADMIN](../grant/index#connection-admin) privilege, who can then still connect and correct the error. See also [init\_file](#init_file).
* **Commandline:** `--init-connect=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `init_file`

 * **Description:** Name of a file containing SQL statements that will be executed by the server on startup. Each statement should be on a new line, and end with a semicolon. See also [init\_connect](#init_connect).
* **Commandline:** `init-file=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`

 

---

 #### `insert_id`

 * **Description:** Value to be used for the next statement inserting a new [AUTO\_INCREMENT](../auto_increment/index) value.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`

 

---

 #### `interactive_timeout`

 * **Description:** Time in seconds that the server waits for an interactive connection (one that connects with the mysql\_real\_connect() CLIENT\_INTERACTIVE option) to become active before closing it. See also [wait\_timeout](#wait_timeout).
* **Commandline:** `--interactive-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `28800`
* **Range: (Windows): `1` to `2147483`**
* **Range: (Other): `1` to `31536000`**

 

---

 #### `join_buffer_size`

 * **Description:** Minimum size in bytes of the buffer used for queries that cannot use an index, and instead perform a full table scan. Increase to get faster full joins when adding indexes is not possible, although be aware of memory issues, since joins will always allocate the minimum size. Best left low globally and set high in sessions that require large full joins. In 64-bit platforms, Windows truncates values above 4GB to 4GB with a warning. See also [Block-Based Join Algorithms - Size of Join Buffers](../block-based-join-algorithms/index#size-of-join-buffers).
* **Commandline:** `--join-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `262144` (256kB)
* **Range (non-Windows):** `128` to `18446744073709547520`
* **Range (Windows):** `8228` to `18446744073709547520`

 

---

 #### `join_buffer_space_limit`

 * **Description:** Maximum size in bytes of the query buffer, By default 1024\*128\*10. See [Block-based join algorithms](../block-based-join-algorithms/index#size-of-join-buffers).
* **Commandline:** `--join-buffer-space-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2097152`
* **Range:** `2048` to `99999999997952`

 

---

 #### `join_cache_level`

 * **Description:** Controls which of the eight block-based algorithms can be used for join operations. See [Block-based join algorithms](../block-based-join-algorithms/index) for more information.
	+ 1 – flat (Block Nested Loop) BNL
	+ 2 – incremental BNL
	+ 3 – flat Block Nested Loop Hash (BNLH)
	+ 4 – incremental BNLH
	+ 5 – flat Batch Key Access (BKA)
	+ 6 – incremental BKA
	+ 7 – flat Batch Key Access Hash (BKAH)
	+ 8 – incremental BKAH
* **Commandline:** `--join-cache-level=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2`
* **Range:** `0` to `8`

 

---

 #### `keep_files_on_create`

 * **Description:** If a [MyISAM](../myisam/index) table is created with no DATA DIRECTORY option, the .MYD file is stored in the database directory. When set to `0`, the default, if MariaDB finds another .MYD file in the database directory it will overwrite it. Setting this variable to `1` means that MariaDB will return an error instead, just as it usually does in the same situation outside of the database directory. The same applies for .MYI files and no INDEX DIRECTORY option. Deprecated in [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/).
* **Commandline:** `--keep-files-on-create=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/)

 

---

 #### `large_files_support`

 * **Description:** ON if the server if was compiled with large file support or not, else OFF
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `large_page_size`

 * **Description:** Indicates the size of memory page if large page support (Linux only) is enabled. The page size is determined from the Hugepagesize setting in `/proc/meminfo`. See [large\_pages](#large_pages). Deprecated and unused in [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/) since multiple page size support was added.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** Autosized (see description)
* **Deprecated:** [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/)

 

---

 #### `large_pages`

 * **Description:** Indicates whether large page support (prior to [MariaDB 10.5](../what-is-mariadb-105/index), Linux only, by now supported Windows and BSD distros, also called huge pages) is used. This is set with `--large-pages` or disabled with `--skip-large-pages`. Large pages are used for the [innodb buffer pool](../innodb-buffer-pool/index) and for online DDL (of size 3\* [innodb\_sort\_buffer\_size](../innodb-system-variables/index#innodb_sort_buffer_size) (or 6 when encryption is used)). To use large pages, the Linux `sysctl` variable `kernel.shmmax` must be large than the llocation. Also the `sysctl` variable `vm.nr_hugepages` multipled by [large-page](#large_page_size)) must be larger than the usage. The ulimit for locked memory must be sufficient to cover the amount used (`ulimit -l` and equalivent in /etc/security/limits.conf / or in systemd [LimitMEMLOCK](../systemd/index)). If these operating system controls or insufficient free huge pages are available, the allocation of large pages will fall back to conventional memory allocation and a warning will appear in the logs. Only allocations of the default `Hugepagesize` currently occur (see `/proc/meminfo`).
* **Commandline:** `--large-pages`, `--skip-large-pages`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `last_insert_id`

 * **Description:** Contains the same value as that returned by [LAST\_INSERT\_ID()](../last_insert_id/index). Note that setting this variable doen't update the value returned by the underlying function.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`

 

---

 #### `lc_messages`

 * **Description:** This system variable can be specified as a [locale](../server-locale/index) name. The language of the associated [locale](../server-locale/index) will be used for error messages. See [Server Locales](../server-locale/index) for a list of supported locales and their associated languages.
	+ This system variable is set to `en_US` by default, which means that error messages are in English by default.
	+ If this system variable is set to a valid [locale](../server-locale/index) name, but the server can't find an [error message file](../error-log/index#error-messages-file) for the language associated with the [locale](../server-locale/index), then the default language will be used instead.
	+ This system variable is used along with the `[lc\_messages\_dir](#lc_messages_dir)` system variable to construct the path to the [error messages file](../error-log/index#error-messages-file).
	+ See [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) for more information.
* **Commandline:** `--lc-messages=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `en_us`

 

---

 #### `lc_messages_dir`

 * **Description:** This system variable can be specified either as the path to the directory storing the server's [error message files](../error-log/index#error-messages-file) or as the path to the directory storing the specific language's [error message file](../error-log/index#error-messages-file). See [Server Locales](../server-locale/index) for a list of available locales and their related languages.
	+ The server initially tries to interpret the value of this system variable as a path to the directory storing the server's [error message files](../error-log/index#error-messages-file). Therefore, it constructs the path to the language's [error message file](../error-log/index#error-messages-file) by concatenating the value of this system variable with the language name of the [locale](../server-locale/index) specified by the `[lc\_messages](index#lc_messages)` system variable .
	+ If the server does not find the [error message file](../error-log/index#error-messages-file) for the language, then it tries to interpret the value of this system variable as a direct path to the directory storing the specific language's [error message file](../error-log/index#error-messages-file).
	+ See [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) for more information.
* **Commandline:** `--lc-messages-dir=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`

 

---

 #### `lc_time_names`

 * **Description:** The locale that determines the language used for the date and time functions [DAYNAME()](../dayname/index), [MONTHNAME()](../monthname/index) and [DATE\_FORMAT()](date-format). Locale names are language and region subtags, for example 'en\_ZA' (English - South Africa) or 'es\_US: Spanish - United States'. The default is always 'en-US' regardless of the system's locale setting. See [server locale](../server-locale/index) for a full list of supported locales.
* **Commandline:** `--lc-time-names=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `en_US`

 

---

 #### `license`

 * **Description:** Server license, for example `GPL`.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `local_infile`

 * **Description:** If set to `1`, LOCAL is supported for [LOAD DATA INFILE](../load-data-infile/index) statements. If set to `0`, usually for security reasons, attempts to perform a LOAD DATA LOCAL will fail with an error message.
* **Commandline:** `--local-infile=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `lock_wait_timeout`

 * **Description:** Timeout in seconds for attempts to acquire [metadata locks](../metadata-locking/index). Statements using metadata locks include [FLUSH TABLES WITH READ LOCK](../flush/index), [LOCK TABLES](../transactions-lock/index), HANDLER and DML and DDL operations on tables, [stored procedures](../stored-procedures/index) and [functions](../stored-functions/index), and [views](../views/index). The timeout is separate for each attempt, of which there may be multiple in a single statement. `0` (from [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)) means no wait. See [WAIT and NOWAIT](../wait-and-nowait/index).
* **Commandline:** `--lock-wait-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `86400` (1 day)
* **Range:**
	+ `0` to `31536000`

 

---

 #### `locked_in_memory`

 * **Description:** Indicates whether --memlock was used to lock mariadbd in memory.
* **Commandline:** `--memlock`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `log`

 * **Description:** Deprecated and removed in [MariaDB 10.0](../what-is-mariadb-100/index), use [general\_log](#general_log) instead.
* **Commandline:** `-l [filename]` or `--log[=filename]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `log_disabled_statements`

 * **Description:** If set, the specified type of statements (slave and/or stored procedure statements) will not be logged to the [general log](../general-query-log/index). Multiple values are comma-separated, without spaces.
* **Commandline:** `--log-disabled_statements=value`
* **Scope:** Global, Session
* **Dynamic:** No
* **Data Type:** `set`
* **Default Value:** `sp`
* **Valid Values:** `slave` and/or `sp`, or empty string for none
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `log_error`

 * **Description:** Specifies the name of the [error log](../error-log/index). If [--console](../mariadbd-options/index#-console) is specified later in the configuration (Windows only) or this option isn't specified, errors will be logged to stderr. If no name is provided, errors will still be logged to `hostname.err` in the `datadir` directory by default. If a configuration file sets `--log-error`, one can reset it with `--skip-log-error` (useful to override a system wide configuration file). MariaDB always writes its error log, but the destination is configurable. See [error log](../error-log/index) for details.
* **Commandline:** `--log-error[=name]`, `--skip-log-error`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** (empty string)

 

---

 #### `log_output`

 * **Description:** How the output for the [general query log](../general-query-log/index) and the [slow query log](../slow-query-log/index) is stored. By default written to file (`FILE`), it can also be stored in the [general\_log](../mysqlgeneral_log-table/index) and [slow\_log](../mysqlslow_log-table/index) tables in the mysql database (`TABLE`), or not stored at all (`NONE`). More than one option can be chosen at the same time, with `NONE` taking precedence if present. Logs will not be written if logging is not enabled. See [Writing logs into tables](../writing-logs-into-tables/index), and the [slow\_query\_log](#slow_query_log) and [general\_log](#general_log) server system variables.
* **Commandline:** `--log-output=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `set`
* **Default Value:** `FILE`
* **Valid Values:** `TABLE`, `FILE` or `NONE`

 

---

 #### `log_queries_not_using_indexes`

 * **Description:** Queries that don't use an index, or that perform a full index scan where the index doesn't limit the number of rows, will be logged to the [slow query log](../slow-query-log/index) (regardless of time taken). The slow query log needs to be enabled for this to have an effect. Mapped to `log_slow_filter='not_using_index'` from [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/).
* **Commandline:** `--log-queries-not-using-indexes`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `log_slow_admin_statements`

 * **Description:** Log slow [OPTIMIZE](../optimize-table/index), [ANALYZE](../analyze-table/index), [ALTER](../alter/index) and other [administrative](../slow-query-log-overview/index#logging-slow-administrative-statements) statements to the [slow log](../slow-query-log/index) if it is open. See also [log\_slow\_disabled\_statements](#log_slow_disabled_statements) and [log\_slow\_filter](#log_slow_filter). Deprecated, use [log\_slow\_filter](#log_slow_filter) without `admin`.
* **Commandline:** `--log-slow-admin-statements`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)

 

---

 #### `log_slow_disabled_statements`

 * **Description:** If set, the specified type of statements will not be logged to the [slow query log](../slow-query-log/index). See also [log\_slow\_admin\_statements](#log_slow_admin_statements) and [log\_slow\_filter](#log_slow_filter).
* **Commandline:** `--log-slow-disabled_statements=value`
* **Scope:** Global, Session
* **Dynamic:** No
* **Data Type:** `set`
* **Default Value:** `sp`
* **Valid Vales:** `admin`, `call`, `slave` and/or `sp`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `log_slow_filter`

 * **Description:** Comma-delimited string (without spaces) containing one or more settings for filtering what is logged to the [slow query log](../slow-query-log/index). If a query matches one of the types listed in the filter, and takes longer than [long\_query\_time](#long_query_time), it will be logged(except for 'not\_using\_index' which is always logged if enabled, regardless of the time). Sets [log-slow-admin-statements](#log_slow_admin_statements) to ON. See also [log\_slow\_disabled\_statements](#log_slow_disabled_statements).
	+ `admin` log [administrative](../slow-query-log-overview/index#logging-slow-administrative-statements) queries (create, optimize, drop etc...)
	+ `filesort` logs queries that use a filesort.
	+ `filesort_on_disk` logs queries that perform a a filesort on disk.
	+ `filesort_priority_queue` (from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/))
	+ `full_join` logs queries that perform a join without indexes.
	+ `full_scan` logs queries that perform full table scans.
	+ `not_using_index` logs queries that don't use an index, or that perform a full index scan where the index doesn't limit the number of rows. Disregards [long\_query\_time](#long_query_time), unlike other options. [log\_queries\_not\_using\_indexes](#log_queries_not_using_indexes) maps to this option. From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/).
	+ `query_cache` log queries that are resolved by the query cache.
	+ `query_cache_miss` logs queries that are not found in the [query cache](../query-cache/index).
	+ `tmp_table` logs queries that create an implicit temporary table.
	+ `tmp_table_on_disk` logs queries that create a temporary table on disk.
* **Commandline:** `log-slow-filter=value1[,value2...]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:**
	+ `admin`, `filesort`, `filesort_on_disk`, `full_join`, `full_scan`, `query_cache`, `query_cache_miss`, `tmp_table`, `tmp_table_on_disk` (<= [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/))
	+ `admin`, `filesort`, `filesort_on_disk`, `filesort_priority_queue`, `full_join`, `full_scan`, `query_cache`, `query_cache_miss`, `tmp_table`, `tmp_table_on_disk` (>= [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/))
* **Valid Values:** `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_min_examined_row_limit`

 * **Description:** If a query examines more than this number of rows, it is logged to the [slow query log](../slow-query-log/index). If set to `0`, the default, no row limit is used. `min_examined_row_limit` is an alias.
* **Commandline:** `--log-slow-min-examined-row-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0-4294967295`
* **Introduced:** [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/)

 

---

 #### `log_slow_queries`

 * **Description:** Deprecated and removed in [MariaDB 10.0](../what-is-mariadb-100/index), use [slow\_query\_log](#slow_query_log) instead.
* **Commandline:** `--log-slow-queries[=name]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `log_slow_query`

 * **Description:** If set to 0, the default unless the --slow-query-log option is used, the [slow query log](../slow-query-log/index) is disabled, while if set to 1 (both global and session variables), the slow query log is enabled. Named [slow\_query\_log](#slow_query_log) before [MariaDB 10.11.0](../mdb-10-11-0-rn/index), which is now an alias.
* **Commandline:** `--slow-query-log`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.11.0](../mdb-10-11-0-rn/index)
* **See also:** See [log\_output](#log_output) to see how log files are written. If that variable is set to `NONE`, no logs will be written even if log\_slow\_query is set to `1`.

 

---

 #### `log_slow_query_file`

 * **Description:** Name of the [slow query log](../slow-query-log/index) file. Before [MariaDB 10.11](../what-is-mariadb-1011/index), was named [slow\_query\_log\_file](#slow_query_log_file). This was named `log_slow_query_file_name` in the [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) preview release.
* **Commandline:** `--log-slow-query-file=file_name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `file name`
* **Default Value:** `*host\_name*-slow.log`
* **Introduced:** [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/)

 

---

 #### `log_slow_query_time`

 * **Description:** If a query takes longer than this many seconds to execute (microseconds can be specified too), the [Slow\_queries](../server-status-variables/index#slow_queries) status variable is incremented and, if enabled, the query is logged to the [slow query log](../slow-query-log/index). Before [MariaDB 10.11](../what-is-mariadb-1011/index), was named [long\_query\_time](#long_query_time).
* **Commandline:** `--log-slow-query-time=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10.000000`
* **Range:** `0` to `31536000`
* **Introduced:** [MariaDB 10.11.0](../mdb-10-11-0-rn/index)

 

---

 #### `log_slow_rate_limit`

 * **Description:** The [slow query log](../slow-query-log/index) will log every this many queries. The default is `1`, or every query, while setting it to `20` would log every 20 queries, or five percent. Aims to reduce I/O usage and excessively large slow query logs. See also [Slow Query Log Extended Statistics](../slow-query-log-extended-statistics/index).
* **Commandline:** `log-slow-rate-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` upwards

 

---

 #### `log_slow_verbosity`

 * **Description:** Controls information to be added to the [slow query log](../slow-query-log/index). Options are added in a comma-delimited string. See also [Slow Query Log Extended Statistics](../slow-query-log-extended-statistics/index). log\_slow\_verbosity is not supported when log\_output='TABLE'.
	+ `query_plan` logs query execution plan information
	+ `innodb` an unused Percona XtraDB option for logging XtraDB/InnoDB statistics.
	+ `explain` prints EXPLAIN output in the [slow query log](../slow-query-log/index). See [EXPLAIN in the Slow Query Log](../explain-in-the-slow-query-log/index).
* **Commandline:** `log-slow-verbosity=value1[,value2...]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** (Empty)
* **Valid Values:** (Empty), `query_plan`, `innodb`, `explain`

 

---

 #### `log_tc_size`

 * **Description:** Defines the size in bytes of the memory-mapped file-based transaction coordinator log, which is only used if the [binary log](../binary-log/index) is disabled. If you have two or more XA-capable storage engines enabled, then a transaction coordinator log must be available. This size is defined in multiples of 4096. See [Transaction Coordinator Log](../transaction-coordinator-log/index) for more information. Also see the `[--log-tc](../mariadbd-options/index#-log-tc)` server option and the `[--tc-heuristic-recover](#-tc-heuristic-recover)` option.
* **Commandline:** `log-tc-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `24576`
* **Range:** `12288` to `18446744073709551615`

 

---

 #### `log_warnings`

 * **Description:** Determines which additional warnings are logged. Setting to `0` disables additional warning logging. Note that this does not prevent all warnings, there is a core set of warnings that will always be written to the error log. The additional warnings are as follows:
	+ log\_warnings >= 1
		- [Event scheduler](../event-scheduler/index) information.
		- System signals
		- Wrong usage of `--user`
		- Failed setrlimit() and mlockall()
		- Changed limits
		- Wrong values of lower\_case\_table\_names and stack\_size
		- Wrong values for command line options
		- Start log position and some master information when starting slaves
		- Slave reconnects
		- Killed slaves
		- Error reading relay logs
		- [Unsafe statements for statement-based replication](../unsafe-statements-for-statement-based-replication/index). If this warning occurs frequently, it is throttled to prevent flooding the log.
		- Disabled [plugins](../mariadb-plugins/index) that one tried to enable or use.
		- UDF files that didn't include the required init functions.
		- DNS lookup failures.
	+ log\_warnings >= 2
		- Access denied errors.
		- Connections aborted or closed due to errors or timeouts.
		- Table handler errors
		- Messages related to the files used to [persist replication state](../change-master-to/index#option-persistence):
			* Either the default `master.info` file or the file that is configured by the `[master\_info\_file](../mariadbd-options/index#-master-info-file)` option.
			* Either the default `relay-log.info` file or the file that is configured by the `[relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file)` system variable.
		- Information about a master's [binary log dump thread](../replication-threads/index#binary-log-dump-thread).
	+ log\_warnings >= 3
		- All errors and warnings during [MyISAM](../myisam/index) repair and auto recover.
		- Information about old-style language options.
		- Information about [progress of InnoDB online DDL](https://mariadb.org/monitoring-progress-and-temporal-memory-usage-of-online-ddl-in-innodb/).
	+ log\_warnings >=4
		- Connections aborted due to "Too many connections" errors.
		- Connections closed normally.
		- Connections aborted due to `[KILL](../data-manipulation-kill-connection-query/index)`.
		- Connections closed due to released connections, such as when `[completion\_type](#completion_type)` is set to `RELEASE`.
	+ log\_warnings >=9
		- Information about initializing plugins.
* **Commandline:** `-W [level]` or `--log-warnings[=level]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `2`
* **Range:** `0` to `4294967295`

 

---

 #### `long_query_time`

 * **Description:** If a query takes longer than this many seconds to execute (microseconds can be specified too), the [Slow\_queries](../server-status-variables/index#slow_queries) status variable is incremented and, if enabled, the query is logged to the [slow query log](../slow-query-log/index). From [MariaDB 10.11.0](../mdb-10-11-0-rn/index), this is an alias for [log\_slow\_query\_time](#log_slow_query_time).
* **Commandline:** `--long-query-time=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10.000000`
* **Range:** `0` upwards

 

---

 #### `low_priority_updates`

 * **Description:** If set to 1 (0 is the default), for [storage engines](../storage-engines/index) that use only table-level locking ([Aria](../aria/index), [MyISAM](../myisam/index), [MEMORY](../memory-storage-engine/index) and [MERGE](../merge/index)), all INSERTs, UPDATEs, DELETEs and LOCK TABLE WRITEs will wait until there are no more SELECTs or LOCK TABLE READs pending on the relevant tables. Set this to 1 if reads are prioritized over writes.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and earlier, `[sql\_low\_priority\_updates](#sql_low_priority_updates)` is a synonym.
* **Commandline:** `--low-priority-updates`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `lower_case_file_system`

 * **Description:** Read-only variable describing whether the file system is case-sensitive. If set to `OFF`, file names are case-sensitive. If set to `ON`, they are not case-sensitive.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `##`

 

---

 #### `lower_case_table_names`

 * **Description:** If set to `0` (the default on Unix-based systems), table names and aliases and database names are compared in a case-sensitive manner. If set to `1` (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner. If set to `2` (the default on Mac OS X), names are stored as declared, but compared in lowercase. This system variable's value cannot be changed after the datadir has been initialized. lower\_case\_table\_names is set when a MariaDB instance starts, and it remains constant afterwards.

 * **Commandline:** `--lower-case-table-names[=#]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0` (Unix), `1` (Windows), `2` (Mac OS X)
* **Range:** `0` to `2`

 

---

 #### `max_allowed_packet`

 * **Description:** Maximum size in bytes of a packet or a generated/intermediate string. The packet message buffer is initialized with the value from [net\_buffer\_length](#net_buffer_length), but can grow up to max\_allowed\_packet bytes. Set as large as the largest BLOB, in multiples of 1024. If this value is changed, it should be changed on the client side as well. See [slave\_max\_allowed\_packet](../replication-and-binary-log-server-system-variables/index#slave_max_allowed_packet) for a specific limit for replication purposes.
* **Commandline:** `--max-allowed-packet=#`
* **Scope:** Global, Session
* **Dynamic:** Yes (Global), No (Session)
* **Data Type:** `numeric`
* **Default Value:**
	+ `16777216` (16M)
	+ `1073741824` (1GB) (client-side)
* **Range:** `1024` to `1073741824`

 

---

 #### `max_connect_errors`

 * **Description:** Limit to the number of successive failed connects from a host before the host is blocked from making further connections. The count for a host is reset to zero if they successfully connect. To unblock, flush the host cache with a [FLUSH HOSTS](../flush/index) statement or [mariadb-admin flush-hosts](../mariadb-admin/index). The [performance\_schema.host\_cache](../performance-schema-host_cache-table/index) table contains the status of the current hosts.
* **Commandline:** `--max-connect-errors=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `1` to `4294967295`

 

---

 #### `max_connections`

 * **Description:** The maximum number of simultaneous client connections. See also [Handling Too Many Connections](../handling-too-many-connections/index). Note that this value affects the number of file descriptors required on the operating system. Minimum was changed from `1` to `10` to avoid possible unexpected results for the user ([MDEV-18252](https://jira.mariadb.org/browse/MDEV-18252)).
* **Commandline:** `--max-connections=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `151`
* **Range:**
	+ `10` to `100000`

 

---

 #### `max_delayed_threads`

 * **Description:** Limits to the number of [INSERT DELAYED](../insert-delayed/index) threads. Once this limit is reached, the insert is handled as if there was no DELAYED attribute. If set to `0`, DELAYED is ignored entirely. The session value can only be set to `0` or to the same as the global value.
* **Commandline:** `--max-delayed-threads=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `0` to `16384`

 

---

 #### `max_digest_length`

 * **Description:** Maximum length considered for computing a statement digest, such as used by the [Performance Schema](../performance-schema/index) and query rewrite plugins. Statements that differ after this many bytes produce the same digest, and are aggregated for statistics purposes. The variable is allocated per session. Increasing will allow longer statements to be distinguished from each other, but increase memory use, while decreasing will reduce memory use, but more statements may become indistinguishable.
* **Commandline:** `--max-digest-length=#`
* **Scope:** Global,
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `0` to `1048576`

 

---

 #### `max_error_count`

 * **Description:** Specifies the maximum number of messages stored for display by [SHOW ERRORS](../show-errors/index) and [SHOW WARNINGS](../show-warnings/index) statements.
* **Commandline:** `--max-error-count=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `64`
* **Range:** `0` to `65535`

 

---

 #### `max_heap_table_size`

 * **Description:** Maximum size in bytes for user-created [MEMORY](../memory-storage-engine/index) tables. Setting the variable while the server is active has no effect on existing tables unless they are recreated or altered. The smaller of max\_heap\_table\_size and [tmp\_table\_size](#tmp_table_size) also limits internal in-memory tables. When the maximum size is reached, any further attempts to insert data will receive a "table ... is full" error. Temporary tables created with [CREATE TEMPORARY](../create-table/index) will not be converted to Aria, as occurs with internal temporary tables, but will also receive a table full error.
* **Commandline:** `--max-heap-table-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16777216`
* **Range :** `16384` to `4294966272`

 

---

 #### `max_insert_delayed_threads`

 * **Description:** Synonym for [max\_delayed\_threads](#max_delayed_threads).

 

---

 #### `max_join_size`

 * **Description:** Statements will not be performed if they are likely to need to examine more than this number of rows, row combinations or do more disk seeks. Can prevent poorly-formatted queries from taking server resources. Changing this value to anything other the default will reset [sql\_big\_selects](#sql_big_selects) to 0. If sql\_big\_selects is set again, max\_join\_size will be ignored. This limit is also ignored if the query result is sitting in the [query cache](../the-query-cache/index). Previously named [sql\_max\_join\_size](#sql_max_join_size), which is still a synonym.
* **Commandline:** `--max-join-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `18446744073709551615`
* **Range:** `1` to `18446744073709551615`

 

---

 #### `max_length_for_sort_data`

 * **Description:** Used to decide which algorithm to choose when sorting rows. If the total size of the column data, not including columns that are part of the sort, is less than `max_length_for_sort_data`, then we add these to the sort key. This can speed up the sort as we don't have to re-read the same row again later. Setting the value too high can slow things down as there will be a higher disk activity for doing the sort.
* **Commandline:** `--max-length-for-sort-data=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `4` to `8388608`

 

---

 #### `max_long_data_size`

 * **Description:** Maximum size for parameter values sent with mysql\_stmt\_send\_long\_data(). If not set, will default to the value of [max\_allowed\_packet](#max_allowed_packet). Deprecated in [MariaDB 5.5](../what-is-mariadb-55/index) and removed in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/); use [max\_allowed\_packet](#max_allowed_packet) instead.
* **Commandline:** `--max-long-data-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**
	+ `16777216` (16M)
* **Range:** `1024` to `4294967295`
* **Deprecated:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `max_password_errors`

 * **Description:** The maximum permitted number of failed connection attempts due to an invalid password before a user is blocked from further connections. [FLUSH\_PRIVILEGES](../flush/index) will permit the user to connect again. This limit is ignored for users with the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [CONNECTION ADMIN](../grant/index#connection-admin) privilege. The maximum also doesn't apply to users with a hostname of localhost, 127.0.0.1 or ::1.
* **Commandline:** `--max-password-errors=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4294967295`
* **Range:** `1` to `4294967295`
* **Introduced:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

 #### `max_prepared_stmt_count`

 * **Description:** Maximum number of prepared statements on the server. Can help prevent certain forms of denial-of-service attacks. If set to `0`, no prepared statements are permitted on the server.
* **Commandline:** `--max-prepared-stmt-count=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16382`
* **Range:** `0` to `4294967295` (>= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)), `0` to `1048576` (<= [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/))

 

---

 #### `max_recursive_iterations`

 * **Description:** Maximum number of iterations when executing recursive queries, used to prevent infinite loops in [recursive CTEs](../recursive-common-table-expressions-overview/index).
* **Commandline:** `--max-recursive-iterations=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000` (>= [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)), `4294967295` (<= [MariaDB 10.5](../what-is-mariadb-105/index))
* **Range:** `0` to `4294967295`

 

---

 #### `max_rowid_filter_size`

 * **Description:** The maximum size of the container of a rowid filter.
* **Commandline:** `--max-rowid-filter-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `131072`
* **Range:** `1024` to `18446744073709551615`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `max_seeks_for_key`

 * **Description:** The optimizer assumes that the number specified here is the most key seeks required when searching with an index, regardless of the actual index cardinality. If this value is set lower than its default and maximum, indexes will tend to be preferred over table scans.
* **Commandline:** `--max-seeks-for-key=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4294967295`
* **Range:** `1` to `4294967295`

 

---

 #### `max_session_mem_used`

 * **Description:** Amount of memory a single user session is allowed to allocate. This limits the value of the session variable [Memory\_used](../server-status-variables/index#memory_used).
* **Commandline:** `--max-session-mem-used=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `9223372036854775807` (8192 PB)
* **Range:** `8192` to `18446744073709551615`

 

---

 #### `max_sort_length`

 * **Description:** Maximum size in bytes used for sorting data values - anything exceeding this is ignored. The server uses only the first `max_sort_length` bytes of each value and ignores the rest.
* **Commandline:** `--max-sort-length=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:**
	+ `4` to `8388608` (<= [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/))
	+ `8` to `8388608` (>= [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/), [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))

 

---

 #### `max_sp_recursion_depth`

 * **Description:** Permitted number of recursive calls for a [stored procedure](../stored-procedures/index). `0`, the default, no recursion is permitted. Increasing this value increases the thread stack requirements, so you may need to increase [thread\_stack](#thread_stack) as well. This limit doesn't apply to [stored functions](../stored-functions/index).
* **Commandline:** `--max-sp-recursion-depth[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `255`

 

---

 #### `max_statement_time`

 * **Description:** Maximum time in seconds that a query can execute before being aborted. This includes all queries, not just [SELECT](../select/index) statements, but excludes statements in stored procedures. If set to 0, no limit is applied. See [Aborting statements that take longer than a certain time to execute](../aborting-statements-that-take-longer-than-a-certain-time-to-execute/index) for details and limitations. Useful when combined with [SET STATEMENT](../set-statement/index) for limiting the execution times of individual queries.
* **Commandline:** `--max-statement-time[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0.000000`
* **Range:** `0` upwards

 

---

 #### `max_tmp_tables`

 * **Description:** Unused.

 

---

 #### `max_user_connections`

 * **Description:** Maximum simultaneous connections permitted for each user account. When set to `0`, there is no per user limit. Setting it to `-1` stops users without the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [CONNECTION ADMIN](../grant/index#connection-admin) privilege, from connecting to the server. The session variable is always read-only and only privileged users can modify user limits. The session variable defaults to the global `max_user_connections` variable, unless the user's specific `[MAX\_USER\_CONNECTIONS](../create-user/index#max_user_connections)` resource option is non-zero. When both global variable and the user resource option are set, the user's [MAX\_USER\_CONNECTIONS](../create-user/index#max_user_connections) is used. Note: This variable does not affect users with the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [CONNECTION ADMIN](../grant/index#connection-admin) privilege.
* **Commandline:** `--max-user-connections=#`
* **Scope:** Global, Session
* **Dynamic:** Yes, (except when globally set to `0` or `-1`)
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-1` to `4294967295`

 

---

 #### `max_write_lock_count`

 * **Description:** Read lock requests will be permitted for processing after this many write locks. Applies only to storage engines that use table level locks (thr\_lock), so no effect with [InnoDB](../innodb/index) or [Archive](../archive/index).
* **Commandline:** `--max-write-lock-count=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `4294967295`
* **Range:** `0-4294967295`

 

---

 #### `metadata_locks_cache_size`

 * **Description:** Size of the metadata locks cache, used for reducing the need to create and destroy synchronization objects. It is particularly helpful on systems where this process is inefficient, such as Windows XP.
* **Commandline:** `--metadata-locks-cache-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `1` to `1048576`

 

---

 #### `metadata_locks_hash_instances`

 * **Description:** Number of hashes used by the set of metadata locks. The metadata locks are partitioned into separate hashes in order to reduce contention.
* **Commandline:** `--metadata-locks-hash-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `1` to `1024`

 

---

 #### `min_examined_row_limit`

 * **Description:** If a query examines more than this number of rows, it is logged to the [slow query log](../slow-query-log/index). If set to `0`, the default, no row limit is used. From [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/), this is an alias for [log\_slow\_min\_examined\_row\_limit](#log_slow_min_examined_row_limit).
* **Commandline:** `--min-examined-row-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0-4294967295`

 

---

 #### `mrr_buffer_size`

 * **Description:** Size of buffer to use when using multi-range read with range access. See [Multi Range Read optimization](../multi-range-read-optimization/index#range-access) for more information.
* **Commandline:** `--mrr-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `262144`
* **Range** `8192` to `2147483648`

 

---

 #### `multi_range_count`

 * **Description:** Ignored. Use [mrr\_buffer\_size](#mrr_buffer_size) instead.
* **Commandline:** `--multi-range-count=#`
* **Default Value:** `256`
* **Removed:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `mysql56_temporal_format`

 * **Description:** If set (the default), MariaDB uses the MySQL 5.6 low level formats for [TIME](../time/index), [DATETIME](../datetime/index) and [TIMESTAMP](../timestamp/index) instead of the [MariaDB 5.3](../what-is-mariadb-53/index) version. The version MySQL introduced in 5.6 requires more storage, but potentially allows negative dates and has some advantages in replication. There should be no reason to revert to the old [MariaDB 5.3](../what-is-mariadb-53/index) microsecond format. See also [MDEV-10723](https://jira.mariadb.org/browse/MDEV-10723).
* **Commandline:** `--mysql56-temporal-format`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `named_pipe`

 * **Description:** On Windows systems, determines whether connections over named pipes are permitted.
* **Commandline:** `--named-pipe`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `net_buffer_length`

 * **Description:** The starting size, in bytes, for the connection and thread buffers for each client thread. The size can grow to [max\_allowed\_packet](#max_allowed_packet). This variable's session value is read-only. Can be set to the expected length of client statements if memory is a limitation.
* **Commandline:** `--net-buffer-length=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16384`
* **Range:** `1024` to `1048576`

 

---

 #### `net_read_timeout`

 * **Description:** Time in seconds the server will wait for a client connection to send more data before aborting the read. See also [net\_write\_timeout](#net_write_timeout) and [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout)
* **Commandline:** `--net-read-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `30`
* **Range:** `1` upwards

 

---

 #### `net_retry_count`

 * **Description:** Permit this many retries before aborting when attempting to read or write on a communication port. On FreeBSD systems should be set higher as threads are sent internal interrupts..
* **Commandline:** `--net-retry-count=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `1` to `4294967295`

 

---

 #### `net_write_timeout`

 * **Description:** Time in seconds to wait on writing a block to a connection before aborting the write. See also [net\_read\_timeout](#net_read_timeout) and [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout).
* **Commandline:** `--net-write-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `60`
* **Range:** `1` upwards

 

---

 #### `old`

 * **Description:** Disabled by default, enabling it reverts index hints to those used before MySQL 5.1.17. Enabling may lead to replication errors. Deprecated and replaced by [old\_mode](#old_mode) from [MariaDB 10.9](../what-is-mariadb-109/index).
* **Commandline:** `--old`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.9](../what-is-mariadb-109/index)

 

---

 #### `old_alter_table`

 * **Description:** From [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), an alias for [alter\_algorithm](#alter_algorithm). Prior to that, if set to `1` (`0` is default), MariaDB reverts to the non-optimized, pre-MySQL 5.1, method of processing [ALTER TABLE](../alter-table/index) statements. A temporary table is created, the data is copied over, and then the temporary table is renamed to the original.
* **Commandline:** `--old-alter-table`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumerated` (>=[MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)), `boolean` (<= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/))
* **Default Value:** See [alter\_algorithm](#alter_algorithm) (>= [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)), `0` (<= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/))
* **Valid Values:** See [alter\_algorithm](#alter_algorithm) for the full list.
* **Deprecated:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) (superceded by [alter\_algorithm](#alter_algorithm))
* **Removed:** [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 

---

 #### `old_mode`

 * **Description:** Used for getting MariaDB to emulate behavior from an old version of MySQL or MariaDB. See [OLD Mode](../old_mode/index). Fully replaces the [old](#old) variable from [MariaDB 10.9](../what-is-mariadb-109/index).
* **Commandline:** `--old-mode`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `UTF8_IS_UTF8MB3` (>= [MariaDB 10.6](../what-is-mariadb-106/index)) `(empty string)` (<= [MariaDB 10.5](../what-is-mariadb-105/index))
* **Valid Values:** See [OLD Mode](../old_mode/index) for the full list.

 

---

 #### `old_passwords`

 * **Description:** If set to `1` (`0` is default), MariaDB reverts to using the `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` authentication plugin by default for newly created users and passwords, instead of the `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` authentication plugin.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `open_files_limit`

 * **Description:** The number of file descriptors available to MariaDB. If you are getting the `Too many open files` error, then you should increase this limit. If set to 0, then MariaDB will calculate a limit based on the following:   
   
 MAX([max\_connections](#max_connections)\*5, [max\_connections](#max_connections) +[table\_open\_cache](#table_open_cache)\*2)   
   
 MariaDB sets the limit with `[setrlimit](https://linux.die.net/man/2/setrlimit)`. MariaDB cannot set this to exceed the hard limit imposed by the operating system. Therefore, you may also need to change the hard limit. There are a few ways to do so.
	+ If you are using `[mysqld\_safe](../mysqld_safe/index)` to start `mariadbd`, then see the instructions at [mysqld\_safe: Configuring the Open Files Limit](../mysqld_safe/index#configuring-the-open-files-limit).
	+ If you are using `[systemd](../systemd/index)` to start `mysqld`, then see the instructions at [systemd: Configuring the Open Files Limit](../systemd/index#configuring-the-open-files-limit).
	+ Otherwise, you can change the hard limit for the `mysql` user account by modifying `[/etc/security/limits.conf](https://linux.die.net/man/5/limits.conf)`. See [Configuring Linux for MariaDB: Configuring the Open Files Limit](../configuring-linux-for-mariadb/index#configuring-the-open-files-limit) for more details.
* **Commandline:** `--open-files-limit=count`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** Autosized (see description)
* **Range:** `0` to `4294967295`

 

---

 #### `optimizer_extra_pruning_depth`

 * **Description:**If the optimizer needs to enumerate a join prefix of this size or larger, then it will try aggressively prune away the search space.
* **Commandline:** `--optimizer-extra-pruning-depthl[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `0` to `62`
* **Introduced:** [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10101-release-notes/)

 

---

 #### `optimizer_max_sel_arg_weight`

 * **Description:** The maximum weight of the SEL\_ARG graph. Set to 0 for no limit.
* **Commandline:** `--optimizer-max-sel-arg-weight=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32000`
* **Range:** `0` to `18446744073709551615`
* **Introduced:** [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/)

 

---

 #### `optimizer_prune_level`

 * **Description:**Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space.
	+ `0`: heuristics are disabled and an exhaustive search is performed
	+ `1`: the optimizer will use heuristics to prune less-promising partial plans from the optimizer search space
	+ `2`: tables using EQ\_REF will be joined together as 'one entity' and the different combinations of these tables will not be considered (from [MariaDB 10.10](../what-is-mariadb-1010/index))
* **Commandline:** `--optimizer-prune-level[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2` (>= [MariaDB 10.10](../what-is-mariadb-1010/index)), `1` (<= [MariaDB 10.9](../what-is-mariadb-109/index))

 

---

 #### `optimizer_search_depth`

 * **Description:** Maximum search depth by the query optimizer. Smaller values lead to less time spent on execution plans, but potentially less optimal results. If set to `0`, MariaDB will automatically choose a reasonable value. Since the better results from more optimal planning usually offset the longer time spent on planning, this is set as high as possible by default. `63` is a valid value, but its effects (switching to the original find\_best search) are deprecated.
* **Commandline:** `--optimizer-search-depth[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `62`
* **Range:** `0` to `63`

 

---

 #### `optimizer_selectivity_sampling_limit`

 * **Description:** Controls number of record samples to check condition selectivity. Only used if `[optimizer\_use\_condition\_selectivity](index#optimizer_use_condition_selectivity) > 4.`
* **Commandline:** `optimizer-selectivity-sampling-limit[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `10` upwards

 

---

 #### `optimizer_switch`

 * **Description:** A series of flags for controlling the query optimizer. See [Optimizer Switch](../optimizer-switch/index) for defaults, and a comparison to MySQL.
* **Commandline:** `--optimizer-switch=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Valid Values:**
	+ `condition_pushdown_for_derived={on|off}`
	+ `condition_pushdown_for_subquery={on|off}` (>=[MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/))
	+ `condition_pushdown_from_having={on|off}` (>=[MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/))
	+ `default` - set all optimizations to their default values.
	+ `derived_merge={on|off}` - see [Derived table merge optimization](../derived-table-merge-optimization/index)
	+ `derived_with_keys={on|off}` - see [Derived table with key optimization](../derived-table-with-key-optimization/index)
	+ `engine_condition_pushdown={on|off}`. Deprecated in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) as engine condition pushdown is now automatically enabled for all engines that support it.
	+ `exists_to_in={on|off}` - see [EXISTS-to-IN optimization](../exists-to-in-optimization/index)
	+ `extended_keys={on|off}` - see [Extended Keys](../extended-keys/index)
	+ `firstmatch={on|off}` - see [First Match Strategy](../firstmatch-strategy/index)
	+ `hash_join_cardinality={on|off}` - see [hash\_join\_cardinality-optimizer\_switch-flag](../hash_join_cardinality-optimizer_switch-flag/index) (>= [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/), [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/), [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/))
	+ `index_condition_pushdown={on|off}` - see [Index Condition Pushdown](../index-condition-pushdown/index)
	+ `index_merge={on|off}`
	+ `index_merge_intersection={on|off}`
	+ `index_merge_sort_intersection={on|off}` - [more details](../index_merge_sort_intersection/index)
	+ `index_merge_sort_union={on|off}`
	+ `index_merge_union={on|off}`
	+ `in_to_exists={on|off}` - see [IN-TO-EXISTS transformation](../non-semi-join-subquery-optimizations/index#the-in-to-exists-transformation)
	+ `join_cache_bka={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `join_cache_hashed={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `join_cache_incremental={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `loosescan={on|off}` - see [LooseScan strategy](../loosescan-strategy/index)
	+ `materialization={on|off}` - [Semi-join](../semi-join-materialization-strategy/index) and [non semi-join](../non-semi-join-subquery-optimizations/index#materialization-for-non-correlated-in-subqueries) materialization.
	+ `mrr={on|off}` - see [Multi Range Read optimization](../multi-range-read-optimization/index)
	+ `mrr_cost_based={on|off}` - see [Multi Range Read optimization](../multi-range-read-optimization/index)
	+ `mrr_sort_keys={on|off}` - see [Multi Range Read optimization](../multi-range-read-optimization/index)
	+ `not_null_range_scan={on|off}` - see [not\_null\_range\_scan optimization](../not_null_range_scan-optimization/index) ( >= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/))
	+ `optimize_join_buffer_size={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `orderby_uses_equalities={on|off}` - if not set, the optimizer ignores equality propagation. See [MDEV-8989](https://jira.mariadb.org/browse/MDEV-8989).
	+ `outer_join_with_cache={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `partial_match_rowid_merge={on|off}` - see [Non-semi-join subquery optimizations](../non-semi-join-subquery-optimizations/index)
	+ `partial_match_table_scan={on|off}` - see [Non-semi-join subquery optimizations](../non-semi-join-subquery-optimizations/index)
	+ `rowid_filter={on|off}` - see [Rowid Filtering Optimization](../rowid-filtering-optimization/index) (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) )
	+ `semijoin={on|off}` - see [Semi-join subquery optimizations](../semi-join-subquery-optimizations/index)
	+ `semijoin_with_cache={on|off}` - see [Block-Based Join Algorithms](../block-based-join-algorithms/index)
	+ `split_materialized={on|off}`
	+ `subquery_cache={on|off}` - see [subquery cache](../subquery-cache/index).
	+ `table_elimination={on|off}` - see [Table Elimination User Interface](../table-elimination-user-interface/index)

 

---

 #### `optimizer_trace`

 * **Description:** Controls [tracing of the optimizer](../optimizer-trace/index): optimizer\_trace=option=val[,option=val...], where option is one of {enabled} and val is one of {on, off, default}
* **Commandline:** `--optimizer-trace=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `enabled=off`
* **Valid Values:** `enabled={on|off|default}`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `optimizer_trace_max_mem_size`

 * **Description:** Limits the memory used while tracing a query by specifying the maximum allowed cumulated size, in bytes, of stored [optimizer traces](../optimizer-trace/index).
* **Commandline:** `--optimizer-trace-max-mem-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1048576`
* **Range:** `1` to `18446744073709551615`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `optimizer_use_condition_selectivity`

 * **Description:** Controls which statistics can be used by the optimizer when looking for the best query execution plan.
	+ `1` Use selectivity of predicates as in [MariaDB 5.5](../what-is-mariadb-55/index).
	+ `2` Use selectivity of all range predicates supported by indexes.
	+ `3` Use selectivity of all range predicates estimated without [histogram](../histogram-based-statistics/index).
	+ `4` Use selectivity of all range predicates estimated with [histogram](../histogram-based-statistics/index).
	+ `5` Additionally use selectivity of certain non-range predicates calculated on record sample.
* **Commandline:** `--optimizer-use-condition-selectivity=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4` (>= [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)), `1` (<= [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/))
* **Range:** `1` to `5`

 

---

 #### `pid_file`

 * **Description:** Full path of the process ID file.
* **Commandline:** `--pid-file=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`

 

---

 #### `plugin_dir`

 * **Description:** Path to the [plugin](../mariadb-plugins/index) directory. For security reasons, either make sure this directory can only be read by the server, or set [secure\_file\_priv](#secure_file_priv).
* **Commandline:** `--plugin-dir=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`
* **Default Value:** `BASEDIR/lib/plugin`

 

---

 #### `plugin_maturity`

 * **Description:** The lowest acceptable [plugin](../mariadb-plugins/index) maturity. MariaDB will not load plugins less mature than the specified level.
* **Commandline:** `--plugin-maturity=level`
* **Scope:** Global
* **Dynamic:** No
* **Type:** enum
* **Default Value:** One less than the server maturity (>= [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)), `unknown` (<= [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/))
* **Valid Values:** `unknown`, `experimental`, `alpha`, `beta`, `gamma`, `stable`

 

---

 #### `port`

 * **Description:** Port to listen for TCP/IP connections. If set to `0`, will default to, in order of preference, my.cnf, the MYSQL\_TCP\_PORT [environment variable](../mariadb-environment-variables/index), /etc/services, built-in default (3306).
* **Commandline:** `--port=#`, `-P`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `3306`
* **Range:** `0` to `65535`

 

---

 #### `preload_buffer_size`

 * **Description:** Size in bytes of the buffer allocated when indexes are preloaded.
* **Commandline:** `--preload-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32768`
* **Range:** `1024` to `1073741824`

 

---

 #### `profiling`

 * **Description:** If set to `1` (`0` is default), statement profiling will be enabled. See [SHOW PROFILES()](../show-profiles/index) and [SHOW PROFILE()](../show-profile/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `profiling_history_size`

 * **Description:** Number of statements about which profiling information is maintained. If set to `0`, no profiles are stored. See [SHOW PROFILES](../show-profiles/index).
* **Commandline:** `--profiling-history-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `15`
* **Range:** `0` to `100`

 

---

 #### `progress_report_time`

 * **Description:** Time in seconds between sending [progress reports](../progress-reporting/index) to the client for time-consuming statements. If set to `0`, progress reporting will be disabled.
* **Commandline:** `--progress-report-time=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `5`
* **Range:** `0` to `4294967295`

 

---

 #### `protocol_version`

 * **Description:** The version of the client/server protocol used by the MariaDB server.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `4294967295`

 

---

 #### `proxy_protocol_networks`

 * **Description:** Enable [proxy protocol](../proxy-protocol-support/index) for these source networks. The syntax is a comma separated list of IPv4 and IPv6 networks. If the network doesn't contain a mask, it is considered to be a single host. "\*" represents all networks and must be the only directive on the line. String "localhost" represents non-TCP local connections (Unix domain socket, Windows named pipe or shared memory). See [Proxy Protocol Support](../proxy-protocol-support/index).
* **Commandline:** `--proxy-protocol-networks=value`
* **Scope:** Global
* **Dynamic:** Yes (>= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)), No (<= [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/))
* **Data Type:** `string`
* **Default Value:** (empty)
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `proxy_user`

 * **Description:** Set to the proxy user account name if the current client is a proxy, else `NULL`.
* **Scope:** Session
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `pseudo_slave_mode`

 * **Description:** For internal use by the server.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `OFF`

 

---

 #### `pseudo_thread_id`

 * **Description:** For internal use only.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`

 

---

 #### `query_alloc_block_size`

 * **Description:** Size in bytes of the extra blocks allocated during query parsing and execution (after [query\_prealloc\_size](#query_prealloc_size) is used up).
* **Commandline:** `--query-alloc-block-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16384`
* **Range - 32 bit:** `1024` to `4294967295`
* **Range - 64 bit:** `1024` to `18446744073709547520`

 

---

 #### `query_cache_limit`

 * **Description:** Size in bytes for which results larger than this are not stored in the [query cache](../the-query-cache/index).
* **Commandline:** `--query-cache-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1048576` (1MB)
* **Range:** `0` to `4294967295`

 

---

 #### `query_cache_min_res_unit`

 * **Description:** Minimum size in bytes of the blocks allocated for [query cache](../the-query-cache/index) results.
* **Commandline:** `--query-cache-min-res-unit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4096` (4KB)
* **Range - 32 bit:** `1024` to `4294967295`
* **Range - 64 bit:** `1024` to `18446744073709547520`

 

---

 #### `query_cache_size`

 * **Description:** Size in bytes available to the [query cache](../the-query-cache/index). About 40KB is needed for query cache structures, so setting a size lower than this will result in a warning. `0`, the default before [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), effectively disables the query cache.

 
**Warning:** Starting from [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), [query\_cache\_type](#query_cache_type) is automatically set to ON if the server is started with the query\_cache\_size set to a non-zero (and non-default) value. This will happen even if [query\_cache\_type](#query_cache_type) is explicitly set to OFF in the configuration.

 
* **Commandline:** `--query-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1M` (although frequently given a default value in some setups)
* **Valid Values:** `0` upwards in units of 1024.

 

---

 #### `query_cache_strip_comments`

 * **Description:** If set to `1` (`0` is default), the server will strip any comments from the query before searching to see if it exists in the [query cache](../the-query-cache/index). Multiple space, line feeds, tab and other white space characters will also be removed.
* **Commandline:** `query-cache-strip-comments`
* **Scope:** Session, Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `query_cache_type`

 * **Description:** If set to `0`, the [query cache](../the-query-cache/index) is disabled (although a buffer of [query\_cache\_size](#query_cache_size) bytes is still allocated). If set to `1` all SELECT queries will be cached unless SQL\_NO\_CACHE is specified. If set to `2` (or `DEMAND`), only queries with the SQL CACHE clause will be cached. Note that if the server is started with the query cache disabled, it cannot be enabled at runtime.

 
**Warning:** Starting from [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), query\_cache\_type is automatically set to ON if the server is started with the [query\_cache\_size](#query_cache_size) set to a non-zero (and non-default) value. This will happen even if [query\_cache\_type](#query_cache_type) is explicitly set to OFF in the configuration.

 
* **Commandline:** `--query-cache-type=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `OFF`
* **Valid Values:** `0` or `OFF`, `1` or `ON`, `2` or `DEMAND`

 

---

 #### `query_cache_wlock_invalidate`

 * **Description:** If set to `0`, the default, results present in the [query cache](../the-query-cache/index) will be returned even if there's a write lock on the table. If set to `1`, the client will first have to wait for the lock to be released.
* **Commandline:** `--query-cache-wlock-invalidate`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `query_prealloc_size`

 * **Description:** Size in bytes of the persistent buffer for query parsing and execution, allocated on connect and freed on disconnect. Increasing may be useful if complex queries are being run, as this will reduce the need for more memory allocations during query operation. See also [query\_alloc\_block\_size](#query_alloc_block_size).
* **Commandline:** `--query-prealloc-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `24576`
* **Range:** `1024` to `4294967295`

 

---

 #### `rand_seed1`

 * **Description:** `rand_seed1` and `rand_seed2` facilitate replication of the [RAND()](../rand/index) function. The master passes the value of these to the slaves so that the random number generator is seeded in the same way, and generates the same value, on the slave as on the master. Until [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), the variable value could not be viewed, with the [SHOW VARIABLES](../show-variables/index) output always displaying zero.
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** Varies
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rand_seed2`

 * **Description:** See [rand\_seed1](#rand_seed1).

 

---

 #### `range_alloc_block_size`

 * **Description:** Size in bytes of blocks allocated during range optimization. The unit size in 1024.
* **Commandline:** `--range-alloc-block-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4096`
* **Range - 32 bit:** `4096` to `4294967295`
* **Range - 64 bit:** `4096` to `18446744073709547520`

 

---

 #### `read_buffer_size`

 * **Description:** Each thread performing a sequential scan (for MyISAM, Aria and MERGE tables) allocates a buffer of this size in bytes for each table scanned. Increase if you perform many sequential scans. If not in a multiple of 4KB, will be rounded down to the nearest multiple. Also used in ORDER BY's for caching indexes in a temporary file (not temporary table), for caching results of nested queries, for bulk inserts into partitions, and to determine the memory block size of [MEMORY](../memory-storage-engine/index) tables.
* **Commandline:** `--read-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `131072`
* **Range:** `8200 to 2147479552`

 

---

 #### `read_only`

 * **Description:** When set to `1` (`0` is default), no updates are permitted except from users with the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [READ ONLY ADMIN](../grant/index#read_only-admin) privilege, or replica servers updating from a primary. The `read_only` variable is useful for replica servers to ensure no updates are accidentally made outside of what are performed on the primary. Inserting rows to log tables, updates to temporary tables and [OPTIMIZE TABLE](../optimize-table/index) or [ANALYZE TABLE](../analyze-table/index) statements are excluded from this limitation. If `read_only` is set to `1`, then the [SET PASSWORD](../set-password/index) statement is limited only to users with the [SUPER](../grant/index#super) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) or [READ ONLY ADMIN](../grant/index#read_only-admin) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)). Attempting to set this variable to `1` will fail if the current session has table locks or transactions pending, while if other sessions hold table locks, the statement will wait until these locks are released before completing. While the attempt to set `read_only` is waiting, other requests for table locks or transactions will also wait until `read_only` has been set. See [Read-Only Replicas](../read-only-replicas/index) for more.
* **Commandline:** `--read-only`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `read_rnd_buffer_size`

 * **Description:** Size in bytes of the buffer used when reading rows from a [MyISAM](../myisam/index) table in sorted order after a key sort. Larger values improve ORDER BY performance, although rather increase the size by SESSION where the need arises to avoid excessive memory use.
* **Commandline:** `--read-rnd-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `262144`
* **Range:** `8200` to `2147483647`

 

---

 -

 -

 #### `require_secure_transport`

 * **Description:** When this option is enabled, connections attempted using insecure transport will be rejected. Secure transports are SSL/TLS, Unix sockets or named pipes. Note that [per-account requirements](../securing-connections-for-client-and-server/index#requiring-tls) take precedence.
* **Commandline:** `--require-secure-transport[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `rowid_merge_buff_size`

 * **Description:** The maximum size in bytes of the memory available to the Rowid-merge strategy. See [Non-semi-join subquery optimizations](../non-semi-join-subquery-optimizations/index#optimizer-control) for more information.
* **Commandline:** `--rowid-merge-buff-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8388608`
* **Range:** `0` to `2147483647`

 

---

 #### `rpl_recovery_rank`

 * **Description:** Unused.
* **Removed:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 

---

 #### `safe_show_database`

 * **Description:** This variable was removed in [MariaDB 5.5](../what-is-mariadb-55/index), and has been replaced by the more flexible [SHOW DATABASES](../show-databases/index) privilege.
* **Commandline:** `--safe-show-database` (until MySQL 4.1.1)
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `secure_auth`

 * **Description:** Connections will be blocked if they use the the `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` authentication plugin. The server will also fail to start if the privilege tables are in the old, pre-MySQL 4.1 format.
* **Commandline:** `--secure-auth`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `secure_file_priv`

 * **Description:** [LOAD DATA](../load-data-infile/index), [SELECT ... INTO](../select/index#into) and [LOAD FILE()](../load_file/index) will only work with files in the specified path. If not set, the default, or set to empty string, the statements will work with any files that can be accessed.
* **Commandline:** `--secure-file-priv=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `path name`
* **Default Value:** None

 

---

 #### `secure_timestamp`

 * **Description:** 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
* **Commandline:** `--secure-timestamp=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enum`
* **Default Value:** `NO`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `session_track_schema`

 * **Description:** Whether to track changes to the default schema within the current session.
* **Commandline:** `--session-track-schema={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `session_track_state_change`

 * **Description:** Whether to track changes to the session state.
* **Commandline:** `--session-track-state-change={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `session_track_system_variables`

 * **Description:** Comma-separated list of session system variables for which to track changes. In [MariaDB 10.2](../what-is-mariadb-102/index), by default no variables are tracked. For compatibility with MySQL defaults, this variable should be set to "autocommit, character\_set\_client, character\_set\_connection, character\_set\_results, time\_zone" (the default from [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)). The `*` character tracks all session variables.
* **Commandline:** `--session-track-system-variables=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `autocommit, character_set_client, character_set_connection, character_set_results, time_zone` (>= [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)), empty string (<= [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/))
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `session_track_transaction_info`

 * **Description:** 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).
* **Commandline:** `--session-track-transaction-info=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `OFF`
* **Valid Values:** `OFF`, `STATE`, `CHARACTERISTICS`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `shared_memory`

 * **Description:** Windows only, determines whether the server permits shared memory connections. See also [shared\_memory\_base\_name](#shared_memory_base_name).
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `shared_memory_base_name`

 * **Description:** Windows only, specifies the name of the shared memory to use for shared memory connection. Mainly used when running more than one instance on the same physical machine. By default the name is `MYSQL` and is case sensitive. See also [shared\_memory](#shared_memory).
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `MYSQL`

 

---

 #### `skip_external_locking`

 * **Description:** If this system variable is set, then some kinds of external table locks will be disabled for some [storage engines](../storage-engines/index).
	+ If this system variable is set, then the [MyISAM](../myisam-storage-engine/index) storage engine will not use file-based locks. Otherwise, it will use the `[fcntl()](https://linux.die.net/man/2/fcntl)` function with the `F_SETLK` option to get file-based locks on Unix, and it will use the `[LockFileEx()](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-lockfileex)` function to get file-based locks on Windows.
	+ If this system variable is set, then the [Aria](../aria/index) storage engine will not lock a table when it decrements the table's in-file counter that keeps track of how many connections currently have the table open. See [MDEV-19393](https://jira.mariadb.org/browse/MDEV-19393) for more information.
* **Commandline:** `--skip-external-locking`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `skip_grant_tables`

 * **Description:** Start without grant tables. This gives all users FULL ACCESS to all tables. Before [MariaDB 10.10](../what-is-mariadb-1010/index), available as an [option only](../mysqld-options/index#-skip-grant-tables). Use [mariadb-admin flush-privileges](../mysqladmin/index), [mariadb-admin reload](../mysqladmin/index) or [FLUSH PRIVILEGES](../flush/index) to resume using the grant tables.
* **Commandline:** `--skip-grant-tables`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `skip_name_resolve`

 * **Description:** If set to 1 (0 is the default), only IP addresses are used for connections. Host names are not resolved. All host values in the GRANT tables must be IP addresses (or localhost).
* **Commandline:** `--skip-name-resolve`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `skip_networking`

 * **Description:** If set to 1, (0 is the default), the server does not listen for TCP/IP connections. All interaction with the server will be through socket files (Unix) or named pipes or shared memory (Windows). It's recommended to use this option if only local clients are permitted to connect to the server.
* **Commandline:** `--skip-networking`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `skip_show_database`

 * **Description:** If set to 1, (0 is the default), only users with the [SHOW DATABASES](../show-databases/index) privilege can use the SHOW DATABASES statement to see all database names.
* **Commandline:** `--skip-show-database`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `slow_launch_time`

 * **Description:** Time in seconds. If a thread takes longer than this to launch, the `slow_launch_threads` [server status variable](../server-status-variables/index) is incremented.
* **Commandline:** `--slow-launch-time=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2`

 

---

 #### `slow_query_log`

 * **Description:** If set to 0, the default unless the --slow-query-log option is used, the [slow query log](../slow-query-log/index) is disabled, while if set to 1 (both global and session variables), the slow query log is enabled. From [MariaDB 10.11.0](../mdb-10-11-0-rn/index), an alias for [log\_slow\_query](#log_slow_query).
* **Commandline:** `--slow-query-log`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Data Type:** `boolean`
* **Default Value:** `0`
* **See also:** See [log\_output](#log_output) to see how log files are written. If that variable is set to `NONE`, no logs will be written even if slow\_query\_log is set to `1`.

 

---

 #### `slow_query_log_file`

 * **Description:** Name of the [slow query log](../slow-query-log/index) file. From [MariaDB 10.11](../what-is-mariadb-1011/index), an alias for [log\_slow\_query\_file](#log_slow_query_file).
* **Commandline:** `--slow-query-log-file=file_name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `file name`
* **Default Value:** `*host\_name*-slow.log`

 

---

 #### `socket`

 * **Description:** On Unix-like systems, this is the name of the socket file used for local client connections, by default `/tmp/mysql.sock`, often changed by the distribution, for example `/var/lib/mysql/mysql.sock`. On Windows, this is the name of the named pipe used for local client connections, by default `MySQL`. On Windows, this is not case-sensitive.
* **Commandline:** `--socket=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** `/tmp/mysql.sock` (Unix), `MySQL` (Windows)

 

---

 #### `sort_buffer_size`

 * **Description:** Each session performing a sort allocates a buffer with this amount of memory. Not specific to any storage engine. If the status variable [sort\_merge\_passes](../server-status-variables/index#sort_merge_passes) is too high, you may need to look at improving your query indexes, or increasing this. Consider reducing where there are many small sorts, such as OLTP, and increasing where needed by session. 16k is a suggested minimum.
* **Commandline:** `--sort-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `number`
* **Default Value:** `2M (2097152)` (some distributions increase the default)

 

---

 #### `sql_auto_is_null`

 * **Description:** If set to 1, the query `SELECT * FROM table_name WHERE auto_increment_column IS NULL` will return an auto-increment that has just been successfully inserted, the same as the LAST\_INSERT\_ID() function. Some ODBC programs make use of this IS NULL comparison.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `sql_big_selects`

 * **Description:** If set to 0, MariaDB will not perform large SELECTs. See [max\_join\_size](#max_join_size) for details. If max\_join\_size is set to anything but DEFAULT, sql\_big\_selects is automatically set to 0. If sql\_big\_selects is again set, max\_join\_size will be ignored.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `sql_big_tables`

 * **Description:** 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.
	+ This is a synonym for `[big\_tables](#big_tables)`.
* **Commandline:** `--sql-big-tables`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `sql_buffer_result`

 * **Description:** If set to 1 (0 is default), results from SELECT statements are always placed into temporary tables. This can help the server when it takes a long time to send the results to the client by allowing the table locks to be freed early.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `sql_if_exists`

 * **Description:** If set to 1, adds an implicit IF EXISTS to ALTER, RENAME and DROP of TABLES, VIEWS, FUNCTIONS and PACKAGES. This variable is mainly used in replication to tag DDLs that can be ignored on the slave if the target table doesn't exist.
* **Commandline:** `--sql-if-exists[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `sql_log_off`

 * **Description:** If set to 1 (0 is the default), no logging to the [general query log](../general-query-log/index) is done for the client. Only clients with the SUPER privilege can update this variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `sql_log_update`

 * **Description:** Removed. Use [sql\_log\_bin](#sql_log_bin) instead.
* **Removed:** MariaDB/MySQL 5.5

 

---

 #### `sql_low_priority_updates`

 * **Description:** If set to 1 (0 is the default), for [storage engines](../storage-engines/index) that use only table-level locking ([Aria](../aria/index), [MyISAM](../myisam/index), [MEMORY](../memory-storage-engine/index) and [MERGE](../merge/index)), all INSERTs, UPDATEs, DELETEs and LOCK TABLE WRITEs will wait until there are no more SELECTs or LOCK TABLE READs pending on the relevant tables. Set this to 1 if reads are prioritized over writes.
	+ This is a synonym for `[low\_priority\_updates](#low_priority_updates)`.
* **Commandline:** `--sql-low-priority-updates`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `sql_max_join_size`

 * **Description:** Synonym for [max\_join\_size](#max_join_size), the preferred name.
* **Deprecated:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `sql_mode`

 * **Description:** Sets the [SQL Mode](../sql-mode/index). Multiple modes can be set, separated by a comma.
* **Commandline:** `--sql-mode=value[,value[,value...]]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:**
	+ `STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION`
* **Valid Values:** See [SQL Mode](../sql-mode/index) for the full list.

 

---

 #### `sql_notes`

 * **Description:** If set to 1, the default, [warning\_count](#warning_count) is incremented each time a Note warning is encountered. If set to 0, Note warnings are not recorded. [mariadb-dump](../mariadb-dump/index) has outputs to set this variable to 0 so that no unnecessary increments occur when data is reloaded.
* **Commandline:** None
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `sql_quote_show_create`

 * **Description:** If set to 1, the default, the server will quote identifiers for [SHOW CREATE DATABASE](../show-create-database/index), [SHOW CREATE TABLE](../show-create-table/index) and [SHOW CREATE VIEW](../show-create-view/index) statements. Quoting is disabled if set to 0. Enable to ensure replications works when identifiers require quoting.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `sql_safe_updates`

 * **Description:** If set to 1, UPDATEs and DELETEs must be executed by using an index (simply mentioning an indexed column in a WHERE clause is not enough, optimizer must actually use it) or they must mention an indexed column and specify a LIMIT clause. Otherwise a statement will be aborted. Prevents the common mistake of accidentally deleting or updating every row in a table. Until [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10311-release-notes/), could not be set as a command-line option or in my.cnf.
* **Commandline:** `--sql-safe-updates[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `sql_select_limit`

 * **Description:** Maximum number of rows that can be returned from a SELECT query. Default is the maximum number of rows permitted per table by the server, usually 232-1 or 264-1. Can be restored to the default value after being changed by assigning it a value of DEFAULT.
* **Commandline:** None
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `18446744073709551615`

 

---

 #### `sql_warnings`

 * **Description:** If set to 1, single-row INSERTs will produce a string containing warning information if a warning occurs.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF (0)`

 

---

 #### `storage_engine`

 * **Description:** See [default\_storage\_engine](#default_storage_engine).
* **Deprecated:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `standard_compliant_cte`

 * **Description:** Allow only standard-compliant [common table expressions](../common-table-expressions/index). Prior to [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), this variable was named `standards_compliant_cte`.
* **Commandline:** `--standard-compliant-cte={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `stored_program_cache`

 * **Description:** Limit to the number of [stored routines](../stored-programs-and-views/index) held in the stored procedures and stored functions caches. Each time a stored routine is executed, this limit is first checked, and if the number held in the cache exceeds this, that cache is flushed and memory freed.
* **Commandline:** `--stored-program-cache=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `256`
* **Range:** `256` to `524288`

 

---

 #### `strict_password_validation`

 * **Description:** When [password validation](../password-validation/index) plugins are enabled, reject passwords that cannot be validated (passwords specified as a hash). This excludes direct updates to the privilege tables.
* **Commandline:** `--strict-password-validation`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `sync_frm`

 * **Description:** If set to 1, the default, each time a non-temporary table is created, its .frm definition file is synced to disk. Fractionally slower, but safer in case of a crash.
* **Commandline:** `--sync-frm`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `TRUE`

 

---

 #### `system_time_zone`

 * **Description:** The system time zone is determined when the server starts. The system [time zone](../time-zones/index) is usually read from the operating system's environment but can be overridden by setting the 'TZ' environment variable before starting the server. See [Time Zones: System Time Zone](../time-zones/index#system-time-zone) for the various ways to change the system time zone. This variable is not the same as the [time\_zone](#time_zone) system variable, which is the variable that actually controls a session's active time zone. The system time zone is used for a session when `time_zone` is set to the special value `SYSTEM`.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `table_definition_cache`

 * **Description:** Number of table definitions that can be cached. Table definitions are taken from the .frm files, and if there are a large number of tables increasing the cache size can speed up table opening. Unlike the [table\_open\_cache](#table_open_cache), as the table\_definition\_cache doesn't use file descriptors, and is much smaller.
* **Commandline:** `--table-definition-cache=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `400`
* **Range:**
	+ `400` to `2097152` (>= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/))
	+ `400` to `524288` (<= [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/), [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/), [MariaDB 10.2.21](https://mariadb.com/kb/en/mariadb-10221-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10137-release-notes/))

 

---

 #### `table_lock_wait_timeout`

 * **Description:** Unused, and removed.
* **Commandline:** `--table-lock-wait-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `50`
* **Range:** `1` to `1073741824`
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `table_open_cache`

 * **Description:** Maximum number of open tables cached in one table cache instance. See [Optimizing table\_open\_cache](../optimizing-table_open_cache/index) for suggestions on optimizing. Increasing table\_open\_cache increases the number of file descriptors required.
* **Commandline:** `--table-open-cache=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2000`
* **Range:**
	+ `1` to `1048576` (1024K)

 

---

 #### `table_open_cache_instances`

 * **Description:** This system variable specifies the maximum number of table cache instances. MariaDB Server initially creates just a single instance. However, whenever it detects contention on the existing instances, it will automatically create a new instance. When the number of instances has been increased due to contention, it does not decrease again. The default value of this system variable is `8`, which is expected to handle up to 100 CPU cores. If your system is larger than this, then you may benefit from increasing the value of this system variable.
	+ Depending on the ratio of actual available file handles, and `[table\_open\_cache](index#table_open_cache)` size, the max. instance count may be auto adjusted to a lower value on server startup.
	+ The implementation and behavior of this feature is different than the same feature in MySQL 5.6.
	+ See [Optimizing table\_open\_cache: Automatic Creation of New Table Open Cache Instances](../optimizing-table_open_cache/index#automatic-creation-of-new-table-open-cache-instances) for more information.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8` (>= [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/))
* **Range:** `1` to `64`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `table_type`

 * **Description:** Removed and replaced by [storage\_engine](#storage_engine). Use [default\_storage\_engine](#default_storage_engine) instead.

 

---

 #### `tcp_keepalive_interval`

 * **Description:** The interval, in seconds, between when successive keep-alive packets are sent if no acknowledgement is received. If set to 0, the system dependent default is used.
* **Commandline:** `--tcp-keepalive-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2147483`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `tcp_keepalive_probes`

 * **Description:** The number of unacknowledged probes to send before considering the connection dead and notifying the application layer. If set to 0, a system dependent default is used.
* **Commandline:** `--tcp-keepalive-probes=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2147483`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `tcp_keepalive_time`

 * **Description:** Timeout, in seconds, with no activity until the first TCP keep-alive packet is sent. If set to 0, a system dependent default is used.
* **Commandline:** `--tcp-keepalive-time=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2147483`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `tcp_nodelay`

 * **Description:** Set the TCP\_NODELAY option (disable Nagle's algorithm) on socket.
* **Commandline:** `--tcp-nodelay={0|1}`
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`
* **Introduced:** [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)

 

---

 #### `thread_cache_size`

 * **Description:** Number of threads server caches for re-use. If this limit hasn't been reached, when a client disconnects, its threads are put into the cache, and re-used where possible. In [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) and newer the threads are freed after 5 minutes of idle time. Normally this setting has little effect, as the other aspects of the thread implementation are more important, but increasing it can help servers with high volumes of connections per second so that most can use a cached, rather than a new, thread. The cache miss rate can be calculated as the [server status variables](../server-status-variables/index) threads\_created/connections. If the [thread pool](../thread-pool/index) is active, `thread_cache_size` is ignored. If `thread_cache_size` is set to greater than the value of [max\_connections](#max_connections), `thread_cache_size` will be set to the [max\_connections](#max_connections) value.
* **Commandline:** `--thread-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `256` (adjusted if thread pool is active)
* **Range:** `0` to `16384`

 

---

 #### `thread_concurrency`

 * **Description:** Allows applications to give the system a hint about the desired number of threads. Specific to Solaris only, invokes thr\_setconcurrency(). Deprecated and has no effect from [MariaDB 5.5](../what-is-mariadb-55/index).
* **Commandline:** `--thread-concurrency=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `1` to `512`
* **Deprecated:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `thread_stack`

 * **Description:** Stack size for each thread. If set too small, limits recursion depth of stored procedures and complexity of SQL statements the server can handle in memory. Also affects limits in the crash-me test.
* **Commandline:** `--thread-stack=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**
	+ `299008`
* **Range:** `131072` to `18446744073709551615`

 

---

 #### `time_format`

 * **Description:** Unused.

 

---

 #### `time_zone`

 * **Description:** The global value determines the default [time zone](../time-zones/index) for sessions that connect. The session value determines the session's active [time zone](../time-zones/index). When it is set to `SYSTEM`, the session's time zone is determined by the `[system\_time\_zone](#system_time_zone)` system variable.
* **Commandline:** `--default-time-zone=string`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `SYSTEM`

 

---

 #### `timed_mutexes`

 * **Description:** Determines whether [InnoDB](../innodb/index) mutexes are timed. `OFF`, the default, disables mutex timing, while `ON` enables it. See also [SHOW ENGINE](../show-engine/index) for more on mutex statistics. Deprecated and has no effect.
* **Commandline:** `--timed-mutexes`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5539-release-notes/)
* **Removed:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `timestamp`

 * **Description:** Sets the time for the client. This will affect the result returned by the [NOW()](../now/index) function, not the [SYSDATE()](../sysdate/index) function, unless the server is started with the [--sysdate-is-now](../mysqld-options/index#-sysdate-is-now) option, in which case SYSDATE becomes an alias of NOW, and will also be affected. Also used to get the original timestamp when restoring rows from the [binary log](../binary-log/index).
* **Scope:** Session
* **Dynamic:** Yes
* **Valid Values:** `timestamp_value` (Unix epoch timestamp, not MariaDB timestamp), `DEFAULT`

 

---

 #### `tmp_disk_table_size`

 * **Description:** Max size for data for an internal temporary on-disk [MyISAM](../myisam/index) or [Aria](../aria/index) table. These tables are created as part of complex queries when the result doesn't fit into the memory engine. You can set this variable if you want to limit the size of temporary tables created in your temporary directory [tmpdir](#tmpdir).
* **Commandline:** `--tmp-disk-table-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `18446744073709551615` (max unsigned integer, no limit)
* **Range:** `1024` to `18446744073709551615`
* **Introduced:** [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/)

 

---

 #### `tmp_memory_table_size`

 * **Description:** An alias for [tmp\_table\_size](#tmp_table_size).
* **Commandline:** `--tmp-memory-table-size=#`
* **Introduced:** [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/)

 

---

 #### `tmp_table_size`

 * **Description:** The largest size for temporary tables in memory (not [MEMORY](../memory-storage-engine/index) tables) although if [max\_heap\_table\_size](#max_heap_table_size) is smaller the lower limit will apply. You can see if it's necessary to increase by comparing the [status variables](../server-status-variables/index) `Created_tmp_disk_tables` and `Created_tmp_tables` to see how many temporary tables out of the total created needed to be converted to disk. Often complex GROUP BY queries are responsible for exceeding the limit. Defaults may be different on some systems, see for example [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index). From [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), [tmp\_memory\_table\_size](#tmp_memory_table_size) is an alias.
* **Commandline:** `--tmp-table-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16777216` (16MB)
* **Range:**
	+ `1024` to `4294967295` (< [MariaDB 10.5](../what-is-mariadb-105/index))
	+ `0` to `4294967295` (>= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/))

 

---

 #### `tmpdir`

 * **Description:** Directory for storing temporary tables and files. Can specify a list (separated by semicolons in Windows, and colons in Unix) that will then be used in round-robin fashion. This can be used for load balancing across several disks. Note that if the server is a [replication](../replication/index) replica, and [slave\_load\_tmpdir](../replication-and-binary-log-system-variables/index#slave_load_tmpdir), which overrides `tmpdir` for replicas, is not set, you should not set `tmpdir` to a directory that is cleared when the machine restarts, or else replication may fail.
* **Commandline:** `--tmpdir=path` or `-t path`
* **Scope:** Global
* **Dynamic:** No
* **Type:** directory name/s
* **Default:**
	+ `$TMPDIR` (environment variable) if set
	+ otherwise `$TEMP` if set and on Windows
	+ otherwise `$TMP` if set and on Windows
	+ otherwise `P_tmpdir` (`"/tmp"`) or `C:\TEMP` (unless overridden during buid time)

 

---

 #### `transaction_alloc_block_size`

 * **Description:** Size in bytes to increase the memory pool available to each transaction when the available pool is not large enough. See [transaction\_prealloc\_size](#transaction_prealloc_size).
* **Commandline:** `--transaction-alloc-block-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `8192`
* **Range:** `1024` to `4294967295`
* **Block Size:** `1024`

 

---

 #### `transaction_isolation`

 * **Description:** The transaction isolation level. See also [SET TRANSACTION ISOLATION LEVEL](../set-transaction-isolation-level/index). Introduced in [MariaDB 11.1.1](https://mariadb.com/kb/en/mariadb-11-1-1-release-notes/) to replace the [tx\_isolation](#tx_isolation) system variable and align the option and the system variable name.
* **Commandline:** `--transaction-isolation=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** enumeration
* **Default Value:** `REPEATABLE-READ`
* **Valid Values:** `READ-UNCOMMITTED`, `READ-COMMITTED`, `REPEATABLE-READ`, `SERIALIZABLE`
* **Introduced:** [MariaDB 11.1.1](https://mariadb.com/kb/en/mariadb-11-1-1-release-notes/)

 

---

 #### `transaction_prealloc_size`

 * **Description:** Initial size of a memory pool available to each transaction for various memory allocations. If the memory pool is not large enough for an allocation, it is increased by [transaction\_alloc\_block\_size](#transaction_alloc_block_size) bytes, and truncated back to transaction\_prealloc\_size bytes when the transaction is completed. If set large enough to contain all statements in a transaction, extra malloc() calls are avoided.
* **Commandline:** `--transaction-prealloc-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `4096`
* **Range:** `1024` to `4294967295`
* **Block Size:** `1024`

 

---

 #### `transaction_read_only`

 * **Description:** Default transaction access mode. If set to `OFF`, the default, access is read/write. If set to `ON`, access is read-only. The `SET TRANSACTION` statement can also change the value of this variable. See [SET TRANSACTION](../set-transaction/index) and [START TRANSACTION](../start-transaction/index).
* **Commandline:** `--transaction-read-only=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** boolean
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 11.1](../what-is-mariadb-111/index)

 

---

 #### `tx_isolation`

 * **Description:** The transaction isolation level. Setting this session variable via `set @@tx_isolation=` will take effect for only the subsequent transaction in the current session, much like [SET TRANSACTION ISOLATION LEVEL](../set-transaction-isolation-level/index). To set for a session, use `SET SESSION tx_isolation` or `SET @@session.tx_isolation`. See [MDEV-31751](https://jira.mariadb.org/browse/MDEV-31751). See also [SET TRANSACTION ISOLATION LEVEL](../set-transaction-isolation-level/index). In [MariaDB 11.1](../what-is-mariadb-111/index), this system variable is deprecated and replaced by [transaction\_isolation](#transaction_isolation).
* **Commandline:** `--transaction-isolation=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** enumeration
* **Default Value:** `REPEATABLE-READ`
* **Valid Values:** `READ-UNCOMMITTED`, `READ-COMMITTED`, `REPEATABLE-READ`, `SERIALIZABLE`
* **Deprecated:** [MariaDB 11.1](../what-is-mariadb-111/index)

 

---

 #### `tx_read_only`

 * **Description:** Default transaction access mode. If set to `OFF`, the default, access is read/write. If set to `ON`, access is read-only. The `SET TRANSACTION` statement can also change the value of this variable. See [SET TRANSACTION](../set-transaction/index) and [START TRANSACTION](../start-transaction/index). In [MariaDB 11.1](../what-is-mariadb-111/index), this system variable is deprecated and replaced by [transaction\_read\_only](#transaction_read_only).
* **Commandline:** `--transaction-read-only=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** boolean
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 11.1](../what-is-mariadb-111/index)

 

---

 #### `unique_checks`

 * **Description:** If set to 0, storage engines can (but are not required to) assume that duplicate keys are not present in input data. If set to 0, inserting duplicates into a `UNIQUE` index can succeed, causing the table to become corrupted. Set to 0 to speed up imports of large tables to InnoDB.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** boolean
* **Default Value:** `1`

 

---

 #### `updatable_views_with_limit`

 * **Description:** Determines whether view updates can be made with an UPDATE or DELETE statement with a LIMIT clause if the view does not contain all primary or not null unique key columns from the underlying table. `0` prohibits this, while `1` permits it while issuing a warning (the default).
* **Commandline:** `--updatable-views-with-limit=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** boolean
* **Default Value:** `1`

 

---

 #### `use_stat_tables`

 * **Description:** Controls the use of [engine-independent table statistics](../engine-independent-table-statistics/index).
	+ `never`: The optimizer will not use data from statistics tables.
	+ `complementary`: The optimizer uses data from statistics tables if the same kind of data is not provided by the storage engine.
	+ `preferably`: Prefer the data from statistics tables, if it's not available there, use the data from the storage engine.
	+ `complementary_for_queries`: Same as `complementary`, but for queries only (to avoid needlessly collecting for [ANALYZE TABLE](../analyze-table/index)). From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).
	+ `preferably_for_queries`: Same as `preferably`, but for queries only (to avoid needlessly collecting for [ANALYZE TABLE](../analyze-table/index)). From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).
* **Commandline:** `--use-stat-tables=mode`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `preferably_for_queries` (>= [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)), `never` (<= [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/))

 

---

 #### `version`

 * **Description:** Server version number. It may also include a suffix with configuration or build information. `-debug` indicates debugging support was enabled on the server, and `-log` indicates at least one of the binary log, general log or [slow query log](../slow-query-log/index) are enabled, for example `10.0.1-MariaDB-mariadb1precise-log`. Can be set at startup in order to fake the server version.
* **Commandline:**  `-V`, `--version[=name]`
* **Scope:** Global
* **Dynamic:** No
* **Type:** string

 

---

 #### `version_comment`

 * **Description:** Value of the COMPILATION\_COMMENT option specified by CMake when building MariaDB, for example `mariadb.org binary distribution`.
* **Scope:** Global
* **Dynamic:** No
* **Type:** string

 

---

 #### `version_compile_machine`

 * **Description:** The machine type or architecture MariaDB was built on, for example `i686`.
* **Scope:** Global
* **Dynamic:** No
* **Type:** string

 

---

 #### `version_compile_os`

 * **Description:** Operating system that MariaDB was built on, for example `debian-linux-gnu`.
* **Scope:** Global
* **Dynamic:** No
* **Type:** string

 

---

 #### `version_malloc_library`

 * **Description:** Version of the used malloc library.
* **Commandline:** No
* **Scope:** Global
* **Dynamic:** No
* **Type:** string

 

---

 #### `version_source_revision`

 * **Description:** Source control revision id for MariaDB source code, enabling one to see exactly which version of the source was used for a build.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Type:** string
* **Introduced:** [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `wait_timeout`

 * **Description:** Time in seconds that the server waits for a connection to become active before closing it. The session value is initialized when a thread starts up from either the global value, if the connection is non-interactive, or from the [interactive\_timeout](#interactive_timeout) value, if the connection is interactive.
* **Commandline:** `--wait-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `28800`
* **Range: (Windows): `1` to `2147483`**
* **Range: (Other): `1` to `31536000`**

 

---

 #### `warning_count`

 * **Description:** Read-only variable indicating the number of warnings, errors and notes resulting from the most recent statement that generated messages. See [SHOW WARNINGS](../show-warnings/index) for more. Note warnings will only be recorded if [sql\_notes](#sql_notes) is true (the default).
* **Scope:** Session
* **Dynamic:** No
* **Type:** numeric

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/server-system-variables/>

Numeric Functions
==================

   Functions dealing with numerals, including ABS, CEIL, DIV, EXP, PI, SIN, etc.

  

| Title | Description |
| --- | --- |
|  [Addition Operator (+)](../addition-operator/index) |  Addition.  |
|  [Subtraction Operator (-)](../subtraction-operator-/index) |  Subtraction and unary minus.  |
|  [Division Operator (/)](../division-operator/index) |  Division.  |
|  [Multiplication Operator (\*)](../multiplication-operator/index) |  Multiplication.  |
|  [Modulo Operator (%)](../modulo-operator/index) |  Modulo operator. Returns the remainder of N divided by M.  |
|  [DIV](../div/index) |  Integer division.  |
|  [ABS](../abs/index) |  Returns an absolute value.  |
|  [ACOS](../acos/index) |  Returns an arc cosine.  |
|  [ASIN](../asin/index) |  Returns the arc sine.  |
|  [ATAN](../atan/index) |  Returns the arc tangent.  |
|  [ATAN2](../atan2/index) |  Returns the arc tangent of two variables.  |
|  [CEIL](../ceil/index) |  Synonym for CEILING().  |
|  [CEILING](../ceiling/index) |  Returns the smallest integer not less than X.  |
|  [CONV](../conv/index) |  Converts numbers between different number bases.  |
|  [COS](../cos/index) |  Returns the cosine.  |
|  [COT](../cot/index) |  Returns the cotangent.  |
|  [CRC32](../crc32/index) |  Computes a cyclic redundancy check (CRC) value.  |
|  [CRC32C](../crc32c/index) |  Computes a cyclic redundancy check (CRC) value using the Castagnoli polynomial.  |
|  [DEGREES](../degrees/index) |  Converts from radians to degrees.  |
|  [EXP](../exp/index) |  e raised to the power of the argument.  |
|  [FLOOR](../floor/index) |  Largest integer value not greater than the argument.  |
|  [GREATEST](../greatest/index) |  Returns the largest argument.  |
|  [LEAST](../least/index) |  Returns the smallest argument.  |
|  [LN](../ln/index) |  Returns natural logarithm.  |
|  [LOG](../log/index) |  Returns the natural logarithm.  |
|  [LOG10](../log10/index) |  Returns the base-10 logarithm.  |
|  [LOG2](../log2/index) |  Returns the base-2 logarithm.  |
|  [MOD](../mod/index) |  Modulo operation. Remainder of N divided by M.  |
|  [OCT](../oct/index) |  Returns octal value.  |
|  [PI](../pi/index) |  Returns the value of π (pi).  |
|  [POW](../pow/index) |  Returns X raised to the power of Y.  |
|  [POWER](../power/index) |  Synonym for POW().  |
|  [RADIANS](../radians/index) |  Converts from degrees to radians.  |
|  [RAND](../rand/index) |  Random floating-point value.  |
|  [ROUND](../round/index) |  Rounds a number.  |
|  [SIGN](../sign/index) |  Returns 1, 0 or -1.  |
|  [SIN](../sin/index) |  Returns the sine.  |
|  [SQRT](../sqrt/index) |  Square root.  |
|  [TAN](../tan/index) |  Returns the tangent.  |
|  [TRUNCATE](../truncate/index) |  The TRUNCATE function truncates a number to a specified number of decimal places.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numeric-functions/>

Control Flow Functions
=======================

   Built-In functions for assessing data to determine what results to return.

  

| Title | Description |
| --- | --- |
|  [CASE OPERATOR](../case-operator/index) |  Returns the result where value=compare\_value or for the first condition that is true.  |
|  [DECODE](../decode/index) |  Decrypts a string encoded with ENCODE(), or, in Oracle mode, matches expressions.  |
|  [DECODE\_ORACLE](../decode_oracle/index) |  Synonym for the Oracle mode version of DECODE().  |
|  [IF Function](../if-function/index) |  If expr1 is TRUE, returns expr2; otherwise it returns expr3.  |
|  [IFNULL](../ifnull/index) |  Check whether an expression is NULL.  |
|  [NULLIF](../nullif/index) |  Returns NULL if expr1 = expr2.  |
|  [NVL](../nvl/index) |  Synonym for IFNULL.  |
|  [NVL2](../nvl2/index) |  Returns a value based on whether a specified expression is NULL or not.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/control-flow-functions/>

Pseudo Columns
===============

   MariaDB has pseudo columns that can be used for different purposes.

  

| Title | Description |
| --- | --- |
|  [\_rowid](../_rowid/index) |  \_rowid is an alias for the primary key column  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pseudo-columns/>

Secondary Functions
====================

   These are commonly used functions, but they are not primary functions.

  

| Title | Description |
| --- | --- |
|  [Bit Functions and Operators](../bit-functions-and-operators/index) |  Operators for comparison and setting of values, and related functions.  |
|  [Encryption, Hashing and Compression Functions](../encryption-hashing-and-compression-functions/index) |  Functions used for encryption, hashing and compression.  |
|  [Information Functions](../information-functions/index) |  Functions which return information on the server, the user, or a given query.  |
|  [Miscellaneous Functions](../miscellaneous-functions/index) |  Functions for very singular and specific needs.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/secondary-functions/>

Bit Functions and Operators
============================

   Operators for comparison and setting of values, and related functions. They all return a result of the `BIGINT UNSIGNED` type

  

| Title | Description |
| --- | --- |
|  [Operator Precedence](../operator-precedence/index) |  Precedence of SQL operators  |
|  [&](../bitwise_and/index) |  Bitwise AND  |
|  [<<](../shift-left/index) |  Left shift  |
|  [>>](../shift-right/index) |  Shift right  |
|  [BIT\_COUNT](../bit_count/index) |  Returns the number of set bits  |
|  [^](../bitwise-xor/index) |  Bitwise XOR  |
|  [|](../bitwise-or/index) |  Bitwise OR  |
|  [~](../bitwise-not/index) |  Bitwise NOT  |
|  [Parentheses](../parentheses/index) |  Parentheses modify the precedence of other operators in an expression  |
|  [TRUE FALSE](../true-false/index) |  TRUE and FALSE evaluate to 1 and 0  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit-functions-and-operators/>

Encryption, Hashing and Compression Functions
==============================================

   Encryption, hashing and compression functions, such as ENCRYPT, DECRYPT, COMPRESS, PASSWORD etc.

  

| Title | Description |
| --- | --- |
|  [AES\_DECRYPT](../aes_decrypt/index) |  Decryption data encrypted with AES\_ENCRYPT.  |
|  [AES\_ENCRYPT](../aes_encrypt/index) |  Encrypts a string with the AES algorithm.  |
|  [COMPRESS](../compress/index) |  Returns a binary, compressed string.  |
|  [DECODE](../decode/index) |  Decrypts a string encoded with ENCODE(), or, in Oracle mode, matches expressions.  |
|  [DES\_DECRYPT](../des_decrypt/index) |  Decrypts a string encrypted with DES\_ENCRYPT().  |
|  [DES\_ENCRYPT](../des_encrypt/index) |  Encrypts a string using the Triple-DES algorithm.  |
|  [ENCODE](../encode/index) |  Encrypts a string.  |
|  [ENCRYPT](../encrypt/index) |  Encrypts a string with Unix crypt().  |
|  [MD5](../md5/index) |  MD5 checksum.  |
|  [OLD\_PASSWORD](../old_password/index) |  Pre MySQL 4.1 password implementation.  |
|  [PASSWORD](../password/index) |  Calculates a password string.  |
|  [RANDOM\_BYTES](../random_bytes/index) |  Generates a binary string of random bytes.  |
|  [SHA1](../sha1/index) |  Calculates an SHA-1 checksum.  |
|  [SHA2](../sha2/index) |  Calculates an SHA-2 checksum.  |
|  [UNCOMPRESS](../uncompress/index) |  Uncompresses string compressed with COMPRESS().  |
|  [UNCOMPRESSED\_LENGTH](../uncompressed_length/index) |  Returns length of a string before being compressed with COMPRESS().  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encryption-hashing-and-compression-functions/>

Information Functions
======================

   General information functions, including BENCHMARK, CHARSET, DATABASE, USER, VERSION, etc.

  

| Title | Description |
| --- | --- |
|  [BENCHMARK](../benchmark/index) |  Executes an expression repeatedly.  |
|  [BINLOG\_GTID\_POS](../binlog_gtid_pos/index) |  Returns a string representation of the corresponding GTID position.  |
|  [CHARSET](../charset/index) |  Returns the character set.  |
|  [COERCIBILITY](../coercibility/index) |  Returns the collation coercibility value.  |
|  [COLLATION](../collation/index) |  Collation of the string argument.  |
|  [CONNECTION\_ID](../connection_id/index) |  Connection ID.  |
|  [CURRENT\_ROLE](../current_role/index) |  Current role name.  |
|  [CURRENT\_USER](../current_user/index) |  Username/host that authenticated the current client.  |
|  [DATABASE](../database/index) |  Current default database.  |
|  [DECODE\_HISTOGRAM](../decode_histogram/index) |  Returns comma separated numerics corresponding to a probability distribution.  |
|  [DEFAULT](../default/index) |  Returns column default.  |
|  [FOUND\_ROWS](../found_rows/index) |  Number of (potentially) returned rows.  |
|  [LAST\_INSERT\_ID](../last_insert_id/index) |  Last inserted auto\_increment value.  |
|  [LAST\_VALUE](../last_value/index) |  Returns the last value in a list or set of values.  |
|  [PROCEDURE ANALYSE](../procedure-analyse/index) |  Suggests optimal data types for each column.  |
|  [ROWNUM](../rownum/index) |  Function that returns the number of accepted rows so far.  |
|  [ROW\_COUNT](../row_count/index) |  Number of rows affected by previous statement.  |
|  [SCHEMA](../schema/index) |  Synonym for DATABASE().  |
|  [SESSION\_USER](../session_user/index) |  Synonym for USER().  |
|  [SYSTEM\_USER](../system_user/index) |  Synonym for USER().  |
|  [USER](../user/index) |  Current user/host.  |
|  [VERSION](../version/index) |  MariaDB server version.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-functions/>

Miscellaneous Functions
========================

   Miscellaneous functions include DEFAULT, GET\_LOCK, SLEEP, UUID, etc.

  

| Title | Description |
| --- | --- |
|  [GET\_LOCK](../get_lock/index) |  Obtain LOCK.  |
|  [INET6\_ATON](../inet6_aton/index) |  Given an IPv6 or IPv4 network address, returns a VARBINARY numeric value.  |
|  [INET6\_NTOA](../inet6_ntoa/index) |  Given an IPv6 or IPv4 network address, returns the address as a nonbinary string.  |
|  [INET\_ATON](../inet_aton/index) |  Returns numeric value of IPv4 address.  |
|  [INET\_NTOA](../inet_ntoa/index) |  Returns dotted-quad representation of IPv4 address.  |
|  [IS\_FREE\_LOCK](../is_free_lock/index) |  Checks whether lock is free to use.  |
|  [IS\_IPV4](../is_ipv4/index) |  Whether or not an expression is a valid IPv4 address.  |
|  [IS\_IPV4\_COMPAT](../is_ipv4_compat/index) |  Whether or not an IPv6 address is IPv4-compatible.  |
|  [IS\_IPV4\_MAPPED](../is_ipv4_mapped/index) |  Whether an IPv6 address is a valid IPv4-mapped address.  |
|  [IS\_IPV6](../is_ipv6/index) |  Whether or not an expression is a valid IPv6 address.  |
|  [IS\_USED\_LOCK](../is_used_lock/index) |  Check if lock is in use.  |
|  [MASTER\_GTID\_WAIT](../master_gtid_wait/index) |  Wait until slave reaches the GTID position.  |
|  [MASTER\_POS\_WAIT](../master_pos_wait/index) |  Blocks until the replica has applied all specified updates.  |
|  [NAME\_CONST](../name_const/index) |  Returns the given value.  |
|  [RELEASE\_ALL\_LOCKS](../release_all_locks/index) |  Releases all named locks held by the current session.  |
|  [RELEASE\_LOCK](../release_lock/index) |  Releases lock obtained with GET\_LOCK().  |
|  [SLEEP](../sleep/index) |  Pauses for the given number of seconds.  |
|  [SYS\_GUID](../sys_guid/index) |  Returns a globally unique identifier (GUID).  |
|  [UUID](../uuid/index) |  Returns a Universal Unique Identifier.  |
|  [UUID\_SHORT](../uuid_short/index) |  Return short universal identifier.  |
|  [VALUES / VALUE](../values-value/index) |  Refer to columns in INSERT ... ON DUPLICATE KEY UPDATE.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/miscellaneous-functions/>

Special Functions
==================

   There are many commonly used built-in functions. These are lesser used function for specific needs.

  

| Title | Description |
| --- | --- |
|  [Dynamic Columns Functions](../dynamic-columns-functions/index) |  Functions for storing key/value pairs of data within a column.  |
|  [Galera Functions](../galera-functions/index) |  Built-in functions related to Galera.  |
|  [Geographic Functions](../geographic-functions/index) |  Geographic, as well as geometric functions.  |
|  [JSON Functions](../json-functions/index) |  Built-in functions related to JSON.  |
|  [SEQUENCE Functions](../sequence-functions/index) |  Functions that can be used on SEQUENCEs.  |
|  [Spider Functions](../spider-functions/index) |  User-defined functions available with the Spider storage engine.  |
|  [Window Functions](../window-functions/index) |  Window functions for performing calculations on a set of rows related to the current row.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/special-functions/>

Dynamic Columns Functions
==========================

   [Dynamic columns](../dynamic-columns/index) is a feature that allows one to store different sets of columns for each row in a table. It works by storing a set of columns in a blob and having a small set of functions to manipulate it.

  

| Title | Description |
| --- | --- |
|  [COLUMN\_ADD](../column_add/index) |  Adds or updates dynamic columns.  |
|  [COLUMN\_CHECK](../column_check/index) |  Checks if a dynamic column blob is valid  |
|  [COLUMN\_CREATE](../column_create/index) |  Returns a dynamic columns blob.  |
|  [COLUMN\_DELETE](../column_delete/index) |  Deletes a dynamic column.  |
|  [COLUMN\_EXISTS](../column_exists/index) |  Checks is a column exists.  |
|  [COLUMN\_GET](../column_get/index) |  Gets a dynamic column value by name.  |
|  [COLUMN\_JSON](../column_json/index) |  Returns a JSON representation of dynamic column blob data  |
|  [COLUMN\_LIST](../column_list/index) |  Returns comma-separated list of columns names.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dynamic-columns-functions/>

Galera Functions
=================

   The following functions are for use with [Galera](../galera/index).

  

| Title | Description |
| --- | --- |
|  [WSREP\_LAST\_SEEN\_GTID](../wsrep_last_seen_gtid/index) |  Returns the Global Transaction ID of the most recent write transaction observed by the client.  |
|  [WSREP\_LAST\_WRITTEN\_GTID](../wsrep_last_written_gtid/index) |  Returns the Global Transaction ID of the most recent write transaction performed by the client.  |
|  [WSREP\_SYNC\_WAIT\_UPTO\_GTID](../wsrep_sync_wait_upto_gtid/index) |  Blocks the client until the transaction specified by the given GTID is applied and committed.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-functions/>

Geographic Functions
=====================

   Geographic and geometry functions. See [Geographic Features](../gis-functionality/index) for a full discussion of MariaDB's spatial extensions.

  

| Title | Description |
| --- | --- |
|  [Geometry Constructors](../geometry-constructors/index) |  Geometry constructors  |
|  [Geometry Properties](../geometry-properties/index) |  Geometry properties  |
|  [Geometry Relations](../geometry-relations/index) |  Geometry relations  |
|  [LineString Properties](../linestring-properties/index) |  LineString properties  |
|  [MBR (Minimum Bounding Rectangle)](../mbr-minimum-bounding-rectangle/index) |  |
|  [Point Properties](../point-properties/index) |  Point properties  |
|  [Polygon Properties](../polygon-properties/index) |  Polygon properties  |
|  [WKB](../wkb/index) |  Well-Known Binary format for geometric data  |
|  [WKT](../wkt/index) |  Well-Known Text geometry representation  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geographic-functions/>

JSON Functions
===============

   Functions relating to JSON, such as JSON\_VALUE, JSON\_ARRAY etc.

  

| Title | Description |
| --- | --- |
|  [Differences between JSON\_QUERY and JSON\_VALUE](../differences-between-json_query-and-json_value/index) |  Comparison between and examples with JSON\_QUERY and JSON\_VALUE.  |
|  [JSONPath Expressions](../jsonpath-expressions/index) |  MariaDB JSONPath description and definition.  |
|  [JSON\_ARRAY](../json_array/index) |  Returns a JSON array containing the listed values.  |
|  [JSON\_ARRAYAGG](../json_arrayagg/index) |  Returns a JSON array containing an element for each value in a given set of JSON or SQL values.  |
|  [JSON\_ARRAY\_APPEND](../json_array_append/index) |  Appends values to the end of the given arrays within a JSON document.  |
|  [JSON\_ARRAY\_INSERT](../json_array_insert/index) |  Inserts a value into a JSON document.  |
|  [JSON\_COMPACT](../json_compact/index) |  Removes all unnecessary spaces so the json document is as short as possible.  |
|  [JSON\_CONTAINS](../json_contains/index) |  Whether a value is found in a given JSON document or at a specified path within the document.  |
|  [JSON\_CONTAINS\_PATH](../json_contains_path/index) |  Indicates whether the given JSON document contains data at the specified path or paths.  |
|  [JSON\_DEPTH](../json_depth/index) |  Maximum depth of a JSON document.  |
|  [JSON\_DETAILED](../json_detailed/index) |  Represents JSON in the most understandable way emphasizing nested structures.  |
|  [JSON\_EQUALS](../json_equals/index) |  Checks if there is equality between two json objects.  |
|  [JSON\_EXISTS](../json_exists/index) |  Determines whether a specified JSON value exists in the given data.  |
|  [JSON\_EXTRACT](../json_extract/index) |  Extracts data from a JSON document.  |
|  [JSON\_INSERT](../json_insert/index) |  Inserts data into a JSON document.  |
|  [JSON\_KEYS](../json_keys/index) |  Returns keys from top-level value of a JSON object or top-level keys from the path.  |
|  [JSON\_LENGTH](../json_length/index) |  Returns the length of a JSON document, or the length of a value within the document.  |
|  [JSON\_LOOSE](../json_loose/index) |  Adds spaces to a JSON document to make it look more readable.  |
|  [JSON\_MERGE](../json_merge/index) |  Merges the given JSON documents.  |
|  [JSON\_MERGE\_PATCH](../json_merge_patch/index) |  RFC 7396-compliant merge of the given JSON documents.  |
|  [JSON\_MERGE\_PRESERVE](../json_merge_preserve/index) |  Synonym for JSON\_MERGE.  |
|  [JSON\_NORMALIZE](../json_normalize/index) |  Recursively sorts keys and removes spaces, allowing comparison of json documents for equality.  |
|  [JSON\_OBJECT](../json_object/index) |  Returns a JSON object containing the given key/value pairs.  |
|  [JSON\_OBJECTAGG](../json_objectagg/index) |  Returns a JSON object containing key-value pairs.  |
|  [JSON\_OVERLAPS](../json_overlaps/index) |  Returns true if two json documents have at least one key-value pair or array element in common.  |
|  [JSON\_PRETTY](../json_pretty/index) |  Alias for JSON\_DETAILED.  |
|  [JSON\_QUERY](../json_query/index) |  Given a JSON document, returns an object or array specified by the path.  |
|  [JSON\_QUOTE](../json_quote/index) |  Quotes a string as a JSON value.  |
|  [JSON\_REMOVE](../json_remove/index) |  Removes data from a JSON document.  |
|  [JSON\_REPLACE](../json_replace/index) |  Replaces existing values in a JSON document.  |
|  [JSON\_SCHEMA\_VALID](../json_schema_valid/index) |  JSON schema validation.  |
|  [JSON\_SEARCH](../json_search/index) |  Returns the path to the given string within a JSON document.  |
|  [JSON\_SET](../json_set/index) |  Updates or inserts data into a JSON document.  |
|  [JSON\_TABLE](../json_table/index) |  Given data from a JSON document, returns a representation of it as a relational table.  |
|  [JSON\_TYPE](../json_type/index) |  Returns the type of a JSON value.  |
|  [JSON\_UNQUOTE](../json_unquote/index) |  Unquotes a JSON value, returning a string.  |
|  [JSON\_VALID](../json_valid/index) |  Whether a value is a valid JSON document or not.  |
|  [JSON\_VALUE](../json_value/index) |  Given a JSON document, returns the specified scalar.  |
|  [JSON\_ARRAY\_INTERSECT](../json_array_intersect/index) |  MariaDB starting with [11.2.0](/kb/en/mariadb-1120-release-notes/) |
|  [JSON\_OBJECT\_FILTER\_KEYS](../json_object_filter_keys/index) |  MariaDB starting with [11.2.0](/kb/en/mariadb-1120-release-notes/) |
|  [JSON\_OBJECT\_TO\_ARRAY](../json_object_to_array/index) |  MariaDB starting with [11.2.0](/kb/en/mariadb-1120-release-notes/) |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json-functions/>

SEQUENCE Functions
===================

   Functions that can be used on SEQUENCEs

  

| Title | Description |
| --- | --- |
|  [LASTVAL](../lastval/index) |  Synonym for PREVIOUS VALUE for sequence\_name.  |
|  [NEXT VALUE for sequence\_name](../next-value-for-sequence_name/index) |  Generate next value for a SEQUENCE. Same as NEXTVAL().  |
|  [NEXTVAL](../nextval/index) |  Synonym for NEXT VALUE for sequence\_name.  |
|  [PREVIOUS VALUE FOR sequence\_name](../previous-value-for-sequence_name/index) |  Get last value generated from a SEQUENCE. Same as LASTVAL().  |
|  [SETVAL](../setval/index) |  Set the next value to be returned from a SEQUENCE.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sequence-functions/>

Spider Functions
=================

   The following [UDFs](../user-defined-functions/index) are available with the [Spider Storage Engine](../spider/index).

  

| Title | Description |
| --- | --- |
|  [SPIDER\_BG\_DIRECT\_SQL](../spider_bg_direct_sql/index) |  Background SQL execution  |
|  [SPIDER\_COPY\_TABLES](../spider_copy_tables/index) |  Copy table data  |
|  [SPIDER\_DIRECT\_SQL](../spider_direct_sql/index) |  Execute SQL on the remote server  |
|  [SPIDER\_FLUSH\_TABLE\_MON\_CACHE](../spider_flush_table_mon_cache/index) |  Refreshing Spider monitoring server information  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-functions/>

Window Functions
=================

   Window functions perform calculations across a set of rows related to the current row.

  

| Title | Description |
| --- | --- |
|  [Window Functions Overview](../window-functions-overview/index) |  Window functions perform calculations across a set of rows related to the current row.  |
|  [AVG](../avg/index) |  Returns the average value.  |
|  [BIT\_AND](../bit_and/index) |  Bitwise AND.  |
|  [BIT\_OR](../bit_or/index) |  Bitwise OR.  |
|  [BIT\_XOR](../bit_xor/index) |  Bitwise XOR.  |
|  [COUNT](../count/index) |  Returns count of non-null values.  |
|  [CUME\_DIST](../cume_dist/index) |  Window function that returns the cumulative distribution of a given row.  |
|  [DENSE\_RANK](../dense_rank/index) |  Rank of a given row with identical values receiving the same result, no skipping.  |
|  [FIRST\_VALUE](../first_value/index) |  Returns the first result from an ordered set.  |
|  [JSON\_ARRAYAGG](../json_arrayagg/index) |  Returns a JSON array containing an element for each value in a given set of JSON or SQL values.  |
|  [JSON\_OBJECTAGG](../json_objectagg/index) |  Returns a JSON object containing key-value pairs.  |
|  [LAG](../lag/index) |  Accesses data from a previous row in the same result set without the need for a self-join.  |
|  [LAST\_VALUE](../last_value/index) |  Returns the last value in a list or set of values.  |
|  [LEAD](../lead/index) |  Accesses data from a following row in the same result set without the need for a self-join.  |
|  [MAX](../max/index) |  Returns the maximum value.  |
|  [MEDIAN](../median/index) |  Window function that returns the median value of a range of values.  |
|  [MIN](../min/index) |  Returns the minimum value.  |
|  [NTH\_VALUE](../nth_value/index) |  Returns the value evaluated at the specified row number of the window frame.  |
|  [NTILE](../ntile/index) |  Returns an integer indicating which group a given row falls into.  |
|  [PERCENT\_RANK](../percent_rank/index) |  Window function that returns the relative percent rank of a given row.  |
|  [PERCENTILE\_CONT](../percentile_cont/index) |  Continuous percentile.  |
|  [PERCENTILE\_DISC](../percentile_disc/index) |  Discrete percentile.  |
|  [RANK](../rank/index) |  Rank of a given row with identical values receiving the same result.  |
|  [ROW\_NUMBER](../row_number/index) |  Row number of a given row with identical values receiving a different result.  |
|  [STD](../std/index) |  Population standard deviation.  |
|  [STDDEV](../stddev/index) |  Population standard deviation.  |
|  [STDDEV\_POP](../stddev_pop/index) |  Returns the population standard deviation.  |
|  [STDDEV\_SAMP](../stddev_samp/index) |  Standard deviation.  |
|  [SUM](../sum/index) |  Sum total.  |
|  [VAR\_POP](../var_pop/index) |  Population standard variance.  |
|  [VAR\_SAMP](../var_samp/index) |  Returns the sample variance.  |
|  [VARIANCE](../variance/index) |  Population standard variance.  |
|  [Aggregate Functions as Window Functions](../aggregate-functions-as-window-functions/index) |  It is possible to use aggregate functions as window functions.  |
|  [ColumnStore Window Functions](../window-functions-columnstore-window-functions/index) |  Summary of window function use with the ColumnStore engine  |
|  [Window Frames](../window-frames/index) |  Some window functions operate on window frames.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/window-functions/>

Comment Syntax
==============

    There are three supported comment styles in MariaDB:

 1. From a '`#`' to the end of a line:
```
SELECT * FROM users; # This is a comment

```
2. From a '`--` ' to the end of a line. The space after the two dashes is required (as in MySQL).
```
SELECT * FROM users; -- This is a comment

```
3. C style comments from an opening '`/*`' to a closing '`*/`'. Comments of this form can span multiple lines:
```
SELECT * FROM users; /* This is a
multi-line
comment */

```

 Nested comments are possible in some situations, but they are not supported or recommended.

 Executable Comments
-------------------

 As an aid to portability between different databases, MariaDB supports executable comments. These special comments allow you to embed SQL code which will not execute when run on other databases, but will execute when run on MariaDB.

 MariaDB supports both MySQL's executable comment format, and a slightly modified version specific to MariaDB. This way, if you have SQL code that works on MySQL and MariaDB, but not other databases, you can wrap it in a MySQL executable comment, and if you have code that specifically takes advantage of features only available in MariaDB you can use the MariaDB specific format to hide the code from MySQL.

 ### Executable Comment Syntax

 MySQL and MariaDB executable comment syntax:

 
```
/*! MySQL or MariaDB-specific code */

```

Code that should be executed only starting from a specific MySQL or MariaDB version:

 
```
/*!##### MySQL or MariaDB-specific code */

```

The numbers, represented by '`######`' in the syntax examples above specify the specific the minimum versions of MySQL and MariaDB that should execute the comment. The first number is the major version, the second 2 numbers are the minor version and the last 2 is the patch level.

 For example, if you want to embed some code that should only execute on MySQL or MariaDB starting from 5.1.0, you would do the following:

 
```
/*!50100 MySQL and MariaDB 5.1.0 (and above) code goes here. */

```

MariaDB-only executable comment syntax (starting from [MariaDB 5.3.1](https://mariadb.com/kb/en/mariadb-531-release-notes/)):

 
```
/*M! MariaDB-specific code */
/*M!###### MariaDB-specific code */

```

MariaDB ignores MySQL-style executable comments that have a version number in the range `50700..99999`. This is needed to skip features introduced in MySQL-5.7 that are not ported to MariaDB 10.x yet.

 
```
/*!50701 MariaDB-10.x ignores MySQL-5.7 specific code */

```

**Note:** comments which have a version number in the range `50700..99999` that use MariaDB-style executable comment syntax are still executed.

 
```
/*M!50701 MariaDB-10.x does not ignore this */

```

Statement delimiters cannot be used within executable comments.

 Examples
--------

 In MySQL all the following will return 2: In MariaDB, the last 2 queries would return 3.

 
```
SELECT 2 /* +1 */;
SELECT 1 /*! +1 */;
SELECT 1 /*!50101 +1 */;
SELECT 2 /*M! +1 */;
SELECT 2 /*M!50301 +1 */;

```

The following executable statement will not work due to the delimiter inside the executable portion:

 
```
/*M!100100 select 1 ; */
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1

```

Instead, the delimiter should be placed outside the executable portion:

 
```
/*M!100100 select 1 */;
+---+
| 1 |
+---+
| 1 |
+---+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/comment-syntax/>

Data Manipulation
==================

   SQL commands for querying and manipulating data, such as SELECT, UPDATE, DELETE etc.

  

| Title | Description |
| --- | --- |
|  [Selecting Data](../selecting-data/index) |  Documentation on the SELECT statement and related clauses.  |
|  [Inserting & Loading Data](../inserting-loading-data/index) |  Documentation on the INSERT statement and related clauses.  |
|  [Changing & Deleting Data](../changing-deleting-data/index) |  Documentation on the UPDATE, REPLACE, and DELETE Statements.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-manipulation/>

Data Definition
================

   SQL Commands for defining data, such as ALTER, CREATE, DROP, RENAME etc.

  

| Title | Description |
| --- | --- |
|  [CREATE](../create/index) |  Articles on the various CREATE statements.  |
|  [ALTER](../alter/index) |  The various ALTER statements in MariaDB.  |
|  [DROP](../drop/index) |  Articles on various DROP commands.  |
|  [Atomic DDL](../atomic-ddl/index) |  Making DDL Atomic/Crash-safe.  |
|  [CONSTRAINT](../constraint/index) |  Define a CHECK or FOREIGN KEY constraint.  |
|  [MERGE](../merge/index) |  Allows you to access a collection of identical MyISAM tables as one.  |
|  [RENAME TABLE](../rename-table/index) |  Change a table's name.  |
|  [TRUNCATE TABLE](../truncate-table/index) |  DROP and re-CREATE a table.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-definition/>

Account Management SQL Commands
================================

   CREATE/DROP USER, GRANT, REVOKE, SET PASSWORD etc.

  

| Title | Description |
| --- | --- |
|  [CREATE USER](../create-user/index) |  Create new MariaDB accounts.  |
|  [ALTER USER](../alter-user/index) |  Modify an existing MariaDB account.  |
|  [DROP USER](../drop-user/index) |  Remove one or more MariaDB accounts.  |
|  [GRANT](../grant/index) |  Create accounts and set privileges or roles.  |
|  [RENAME USER](../rename-user/index) |  Rename user account.  |
|  [REVOKE](../revoke/index) |  Remove privileges or roles.  |
|  [SET PASSWORD](../set-password/index) |  Assign password to an existing MariaDB user.  |
|  [CREATE ROLE](../create-role/index) |  Add new roles.  |
|  [DROP ROLE](../drop-role/index) |  Drop a role.  |
|  [SET ROLE](../set-role/index) |  Enable a role.  |
|  [SET DEFAULT ROLE](../set-default-role/index) |  Sets a default role for a specified (or current) user.  |
|  [SHOW GRANTS](../show-grants/index) |  View GRANT statements.  |
|  [SHOW CREATE USER](../show-create-user/index) |  Show the CREATE USER statement for a specified user.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/account-management-sql-commands/>

Administrative SQL Statements
==============================

   SQL statements for administering MariaDB.

  

| Title | Description |
| --- | --- |
|  [Table Statements](../table-statements/index) |  Documentation on creating, altering, analyzing and maintaining tables.  |
|  [ANALYZE and EXPLAIN Statements](../analyze-and-explain-statements/index) |  Articles on the ANALYZE and EXPLAIN statements  |
|  [BACKUP Commands](../backup-commands/index) |  Commands used by backup tools.  |
|  [FLUSH Commands](../flush-commands/index) |  Commands to flush or reset various caches in MariaDB.  |
|  [Replication Commands](../replication-commands/index) |  List of replication-related commands.  |
|  [Plugin SQL Statements](../plugin-sql-statements/index) |  List of SQL statements related to plugins.  |
|  [SET Commands](../set-commands/index) |  The SET commands  |
|  [SHOW](../show/index) |  Articles on the various SHOW commands.  |
|  [System Tables](../system-tables/index) |  |
|  [BINLOG](../binlog/index) |  Internal statement generated by mariadb-binlog.  |
|  [PURGE BINARY LOGS](../purge-binary-logs/index) |  PURGE BINARY LOGS removes all binary logs from the server, prior to the provided date or log file.  |
|  [CACHE INDEX](../cache-index/index) |  Caches MyISAM or Aria indexes  |
|  [DESCRIBE](../describe/index) |  Information about columns in a table.  |
|  [EXECUTE Statement](../execute-statement/index) |  Executes a previously PREPAREd statement  |
|  [HELP Command](../help-command/index) |  The HELP command will retrieve syntax and help within the mariadb client.  |
|  [KILL [CONNECTION | QUERY]](../kill/index) |  Kill connection by query or thread id.  |
|  [LOAD INDEX](../load-index/index) |  Loads one or more indexes from one or more MyISAM/Aria tables into a key buffer.  |
|  [RESET](../reset/index) |  Overall description of the different RESET commands  |
|  [SHUTDOWN](../shutdown/index) |  Shuts down the server.  |
|  [USE [DATABASE]](../use-database/index) |  Set the current default database.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/administrative-sql-statements/>

Stored Routine Statements
==========================

  

| Title | Description |
| --- | --- |
|  [CALL](../call/index) |  Invokes a stored procedure.  |
|  [DO](../do/index) |  Executes expressions without returning results.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-routine-statements/>

HELP Command
============

    Syntax
------

 
```
HELP search_string

```

Description
-----------

 The `HELP` command can be used in any MariaDB client, such as the [mariadb](../mariadb-command-line-client/index) command-line client, to get basic syntax help and a short description for most commands and functions. 

 If you provide an argument to the `HELP` command, the [mariadb](../mariadb-command-line-client/index) client uses it as a search string to access server-side help. The proper operation of this command requires that the help tables in the `mysql` database be initialized with help topic information.

 If there is no match for the search string, the search fails. Use `HELP contents` to see a list of the help categories:

 
```
HELP contents
You asked for help about help category: "Contents"
For more information, type 'help <item>', where <item> is one of the following
categories:
   Account Management
   Administration
   Compound Statements
   Data Definition
   Data Manipulation
   Data Types
   Functions
   Functions and Modifiers for Use with GROUP BY
   Geographic Features
   Help Metadata
   Language Structure
   Plugins
   Procedures
   Sequences
   Table Maintenance
   Transactions
   User-Defined Functions
   Utility

```

If a search string matches multiple items, MariaDB shows a list of matching topics:

 
```
HELP drop
Many help items for your request exist.
To make a more specific request, please type 'help <item>',
where <item> is one of the following
topics:
   ALTER TABLE
   DROP DATABASE
   DROP EVENT
   DROP FUNCTION
   DROP FUNCTION UDF
   DROP INDEX
   DROP PACKAGE
   DROP PACKAGE BODY
   DROP PROCEDURE
   DROP ROLE
   DROP SEQUENCE
   DROP SERVER
   DROP TABLE
   DROP TRIGGER
   DROP USER
   DROP VIEW

```

Then you can enter a topic as the search string to see the help entry for that topic.

 The help is provided with the MariaDB server and makes use of four help tables found in the `mysql` database: [help\_relation](../mysqlhelp_relation-table/index), [help\_topic](../mysqlhelp_topic-table/index), [help\_category](../mysqlhelp_category-table/index) and [help\_keyword](../mysqlhelp_keyword-table/index). These tables are populated by the [mariadb-install-db](../mariadb-install-db/index) or `fill_help_table.sql` scripts.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/help-command/>

Prepared Statements
====================

   In addition to using prepared statements from the libmysqld, you can also do prepared statements from any client by using the text based prepared statement interface.

 You first prepare the statement with [PREPARE](../prepare-statement/index), execute with [EXECUTE](../execute-statement/index), and release it with [DEALLOCATE](../deallocate-drop-prepared-statement/index).

  

| Title | Description |
| --- | --- |
|  [PREPARE Statement](../prepare-statement/index) |  Define a prepare statement.  |
|  [EXECUTE Statement](../execute-statement/index) |  Executes a previously PREPAREd statement  |
|  [DEALLOCATE / DROP PREPARE](../deallocate-drop-prepare/index) |  Deallocates a prepared statement.  |
|  [EXECUTE IMMEDIATE](../execute-immediate/index) |  Immediately execute a dynamic SQL statement  |
|  [Out Parameters in PREPARE](../out-parameters-in-prepare/index) |  Using question mark placeholders for out-parameters in the PREPARE statement  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/prepared-statements/>

Transactions
=============

   "An SQL-transaction (transaction) is a sequence of executions of SQL-statements that is atomic with respect to recovery. That is to say: either the execution result is completely successful, or it has no effect on any SQL-schemas or SQL-data."

 — The SQL Standard

 The [InnoDB](../xtradb-and-innodb/index) storage engine supports [ACID](../acid-concurrency-control-with-transactions/index)-compliant transactions.

 Transaction Articles
--------------------

  

| Title | Description |
| --- | --- |
|  [START TRANSACTION](../start-transaction/index) |  Basic transaction control statements.  |
|  [COMMIT](../commit/index) |  Ends a transaction, making changes visible to subsequent transactions  |
|  [ROLLBACK](../rollback/index) |  Cancel current transaction and the changes to data  |
|  [SET TRANSACTION](../set-transaction/index) |  Sets the transaction isolation level.  |
|  [LOCK TABLES](../lock-tables/index) |  Explicitly lock tables.  |
|  [SAVEPOINT](../savepoint/index) |  SAVEPOINT for a ROLLBACK.  |
|  [Metadata Locking](../metadata-locking/index) |  A lock which protects each transaction from external DDL statements.  |
|  [SQL statements That Cause an Implicit Commit](../sql-statements-that-cause-an-implicit-commit/index) |  List of statements which implicitly commit the current transaction  |
|  [Transaction Timeouts](../transaction-timeouts/index) |  Timing out idle transactions  |
|  [UNLOCK TABLES](../transactions-unlock-tables/index) |  Explicitly releases any table locks held by the current session.  |
|  [WAIT and NOWAIT](../wait-and-nowait/index) |  Extended syntax so that it is possible to set lock wait timeout for certain statements.  |
|  [XA Transactions](../xa-transactions/index) |  Transactions designed to allow distributed transactions.  |
|  [READ COMMITTED](../transactions-read-committed/index) |  Each consistent read, even within the same transaction, sets and reads its own fresh snapshot.  |
|  [READ UNCOMMITTED](../transactions-read-uncommitted/index) |  SELECT statements are performed in a non-locking fashion, but a possible ea...  |
|  [REPEATABLE READ](../transactions-repeatable-read/index) |  All consistent reads within the same transaction read the snapshot established by the first read.  |
|  [SERIALIZABLE](../transactions-serializable/index) |  Similar to REPEATABLE READ, with SELECT ... LOCK IN SHARE MODE if autocommit is disabled.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions/>

Setting Up Replication
======================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   Getting [replication](../replication/index) working involves steps on both the master server/s and steps on the slave server/s.

 
[MariaDB 10.0](../what-is-mariadb-100/index) introduced replication with [global transaction IDs](../global-transaction-id/index). These have a number of benefits, and it is generally recommended to use this feature from [MariaDB 10.0](../what-is-mariadb-100/index).

 
Setting up a Replication Slave with Mariabackup
-----------------------------------------------

 If you would like to use [Mariabackup](../mariabackup/index) to set up a replication slave, then you might find the information at [Setting up a Replication Slave with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index) helpful.

 Versions
--------

 In general, when replicating across different versions of MariaDB, it is best that the master is an older version than the slave. MariaDB versions are usually backward compatible, while of course older versions cannot always be forward compatible. See also [Replicating from MySQL Master to MariaDB Slave](#replicating-from-mysql-master-to-mariadb-slave).

 Configuring the Master
----------------------

 * Enable binary logging if it's not already enabled. See [Activating the Binary Log](../activating-the-binary-log/index) and [Binary log formats](../binary-log-formats/index) for details.
* Give the master a unique [server\_id](../replication-and-binary-log-system-variables/index#server_id). All slaves must also be given a server\_id. This can be a number from 1 to 232-1, and must be unique for each server in the replicating group.
* Specify a unique name for your replication logs with [--log-basename](../mysqld-options-full-list/index#-log-basename). If this is not specified your host name will be used and there will be problems if the hostname ever changes.
* Slaves will need permission to connect and start replicating from a server. Usually this is done by creating a dedicated slave user, and granting that user permission only to replicate (REPLICATION SLAVE permission).

 ### Example Enabling Replication for MariaDB

 Add the following into your [my.cnf](../configuring-mariadb-with-mycnf/index) file and restart the database.

 
```
[mariadb]
log-bin
server_id=1
log-basename=master1
binlog-format=mixed

```

The server id is a unique number for each MariaDB/MySQL server in your network. [binlog-format](../binary-log-formats/index) specifies how your statements are logged. This mainly affects the size of the [binary log](../binary-log/index) that is sent between the Master and the Slaves.

 Then execute the following SQL with the [`mysql`](../mysql-command-line-client/index) command line client:

 
```
CREATE USER 'replication_user'@'%' IDENTIFIED BY 'bigs3cret';
GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'%';

```

### Example Enabling Replication for MySQL

 If you want to enable replication from MySQL to MariaDB, you can do it in almost the same way as between MariaDB servers. The main difference is that MySQL doesn't support `log-basename`.

 
```
[mysqld]
log-bin
server_id=1

```

Settings to Check
-----------------

 There are a number of options that may impact or break replication. Check the following settings to avoid problems.

 * [skip-networking](../server-system-variables/index#skip_networking). If `skip-networking=1`, the server will limit connections to localhost only, and prevent all remote slaves from connecting.
* [bind-address](../server-system-variables/index#bind_address). Similarly, if the address the server listens for TCP/IP connections is 127.0.0.1 (localhost), remote slaves connections will fail.

 Configuring the Slave
---------------------

 * Give the slave a unique [server\_id](../replication-and-binary-log-server-system-variables/index#server_id). All servers, whether masters or slaves, are given a server\_id. This can be a number from 1 to 232-1, and must be unique for each server in the replicating group. The server will need to be restarted in order for a change in this option to take effect.

 Getting the Master's Binary Log Co-ordinates
--------------------------------------------

 Now you need prevent any changes to the data while you view the binary log position. You'll use this to tell the slave at exactly which point it should start replicating from.

 * On the master, flush and lock all tables by running `FLUSH TABLES WITH READ LOCK`. Keep this session running - exiting it will release the lock.
* Get the current position in the binary log by running `[SHOW MASTER STATUS](../show-master-status/index)`:

 
```
SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| master1-bin.000096 |      568 |              |                  |
+--------------------+----------+--------------+------------------+

```

* Record the *File* and *Position* details. If binary logging has just been enabled, these will be blank.
* Now, with the lock still in place, copy the data from the master to the slave. See [Backup, Restore and Import](../backup-restore-and-import/index) for details on how to do this.
* Note for live databases: You just need to make a local copy of the data, you don't need to keep the master locked until the slave has imported the data.
* Once the data has been copied, you can release the lock on the master by running [UNLOCK TABLES](../transactions-lock/index).

 
```
UNLOCK TABLES;

```

Start the Slave
---------------

 * Once the data has been imported, you are ready to start replicating. Begin by running a [CHANGE MASTER TO](../change-master-to/index), making sure that *MASTER\_LOG\_FILE* matches the file and *MASTER\_LOG\_POS* the position returned by the earlier SHOW MASTER STATUS. For example:

 
```
CHANGE MASTER TO
  MASTER_HOST='master.domain.com',
  MASTER_USER='replication_user',
  MASTER_PASSWORD='bigs3cret',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='master1-bin.000096',
  MASTER_LOG_POS=568,
  MASTER_CONNECT_RETRY=10;

```

If you are starting a slave against a fresh master that was configured for replication from the start, then you don't have to specify `MASTER_LOG_FILE` and `MASTER_LOG_POS`.

 ### Use Global Transaction Id (GTID)

 
**MariaDB starting with [10.0](../what-is-mariadb-100/index)**[MariaDB 10.0](../what-is-mariadb-100/index) introduced global transaction IDs (GTIDs) for replication. It is generally recommended to use (GTIDs) from [MariaDB 10.0](../what-is-mariadb-100/index), as this has a number of benefits. All that is needed is to add the `MASTER_USE_GTID` option to the `CHANGE MASTER` statement, for example:

 
```
CHANGE MASTER TO MASTER_USE_GTID = slave_pos

```

See [Global Transaction ID](../global-transaction-id/index) for a full description.

 
* Now start the slave with the [`START SLAVE`](../start-slave/index) command:

 
```
START SLAVE;

```

* Check that the replication is working by executing the [`SHOW SLAVE STATUS`](../show-slave-status/index) command:

 
```
SHOW SLAVE STATUS \G

```

* If replication is working correctly, both the values of `Slave_IO_Running` and `Slave_SQL_Running` should be `Yes`:

 
```
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

```

Replicating from MySQL Master to MariaDB Slave
----------------------------------------------

 * Replicating from MySQL 5.5 to [MariaDB 5.5](../what-is-mariadb-55/index)+ should just work. When using a [MariaDB 10.2](../what-is-mariadb-102/index)+ as a slave, it may be necessary to set [binlog\_checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum) to NONE.
* Replicating from MySQL 5.6 without GTID to MariaDB 10+ should work.
* Replication from MySQL 5.6 with GTID, binlog\_rows\_query\_log\_events and ignorable events works starting from [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) and [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). In this case MariaDB will remove the MySQL GTIDs and other unneeded events and instead adds its own GTIDs.

 See Also
--------

 * [Differences between Statement-based, mixed and row logging](../binary-log-formats/index)
* [Replication and Foreign Keys](../replication-and-foreign-keys/index)
* [Replication as a Backup Solution](../replication-as-a-backup-solution/index)
* [Multi-source Replication](../multi-source-replication/index)
* [Global Transaction ID](../global-transaction-id/index)
* [Parallel Replication](../parallel-replication/index)
* [Replication and Binary Log System Variables](../replication-and-binary-log-server-system-variables/index)
* [Replication and Binary Log Status Variables](../replication-and-binary-log-status-variables/index)
* [Semisynchronous Replication](../semisynchronous-replication/index)
* [Delayed Replication](../delayed-replication/index)
* [Replication Compatibility](../mariadb-vs-mysql-compatibility/index#replication-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-up-replication/>

Replication as a Backup Solution
================================

    [Replication](../replication/index) can be used to support the [backup](../backing-up-and-restoring/index) strategy.

 
Replication alone is *not* sufficient for backup. It assists in protecting against hardware failure on the primary server, but does not protect against data loss. An accidental or malicious `DROP DATABASE` or `TRUNCATE TABLE` statement will be replicated onto the replica as well. Care needs to be taken to prevent data getting out of sync between the primary and the replica.

 

The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Replication is most commonly used to support backups as follows:

 * A primary server replicates to a replica
* Backups are then run off the replica without any impact on the primary.

 Backups can have a significant effect on a server, and a high-availability primary may not be able to be stopped, locked or simply handle the extra load of a backup. Running the backup from a replica has the advantage of being able to shutdown or lock the replica and perform a backup without any impact on the primary server.

 Note that when backing up off a replica server, it is important to ensure that the servers keep the data in sync. See for example [Replication and Foreign Keys](../replication-and-foreign-keys/index) for a situation when identical statements can result in different data on a replica and a primary.

 See Also
--------

 * [Replication](../replication/index)
* [Replication Compatibility](../mariadb-vs-mysql-compatibility/index#replication-compatibility)
* [Backing Up and Restoring](../backing-up-and-restoring/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-as-a-backup-solution/>

Multi-Source Replication
========================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   Multi-source replication means that one server has many primaries from which it replicates.

 ![multi_source_replication_small]

 New Syntax
----------

 You specify which primary connection you want to work with by either specifying the connection name in the command or setting [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) to the connection you want to work with.

 The connection name may include any characters and should be less than 64 characters. Connection names are compared without regard to case (case insensitive). You should preferably keep the connection name short as it will be used as a suffix for relay logs and primary info index files.

 The new syntax introduced to handle many connections:

 * `[CHANGE MASTER ['connection\_name'] TO ...](../change-master-to/index)`. This creates or modifies a connection to a primary.
* `FLUSH RELAY LOGS ['connection_name']`
* `[MASTER\_POS\_WAIT(....,['connection\_name'])](../master_pos_wait/index)`
* `[RESET SLAVE ['connection\_name'] [ALL](../reset-slave/index)]`. This is used to reset a replica's replication position or to remove a replica permanently.
* `[SHOW RELAYLOG ['connection\_name'] EVENTS](../show-relaylog-events/index)`
* `[SHOW SLAVE ['connection\_name'] STATUS](../show-slave-status/index)`
* `[SHOW ALL SLAVES STATUS](../show-slave-status/index)`
* `[START SLAVE ['connection\_name'](../start-slave/index)...]]`
* `[START ALL SLAVES ...](../start-slave/index)`
* `[STOP SLAVE ['connection\_name'] ...](../stop-slave/index)`
* `[STOP ALL SLAVES ...](../stop-slave/index)`

 The original old-style connection is an empty string `''`. You don't have to use this connection if you don't want to.

 You create new primary connections with [CHANGE MASTER](../change-master-to/index).  
 You delete the connection permanently with [RESET SLAVE 'connection\_name' ALL](../reset-slave/index).

 Replication Variables for Multi-Source
--------------------------------------

 The new replication variable [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) specifies which connection will be used for commands and variables if you don't specify a connection. By default this is `''` (the default connection name).

 The following replication variables are local for the connection. (In other words, they show the value for the `@@default_master_connection` connection). We are working on making all the important ones local for the connection.

 


| Type | Name | Description |
| --- | --- | --- |
| Variable | [max\_relay\_log\_size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size) | Max size of relay log. Is set at startup to `max_binlog_size` if 0 |
| Variable | [replicate\_do\_db](../replication-and-binary-log-server-system-variables/index#replicate_do_db) | Tell the replica to restrict replication to updates of tables whose names appear in the comma-separated list. For statement-based replication, only the default database (that is, the one selected by USE) is considered, not any explicitly mentioned tables in the query. For row-based replication, the actual names of table(s) being updated are checked. |
| Variable | [replicate\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_do_table) | Tells the replica to restrict replication to tables in the comma-separated list |
| Variable | [replicate\_ignore\_db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db) | Tell the replica to restrict replication to updates of tables whose names do not appear in the comma-separated list. For statement-based replication, only the default database (that is, the one selected by USE) is considered, not any explicitly mentioned tables in the query. For row-based replication, the actual names of table(s) being updated are checked. |
| Variable | [replicate\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table) | Tells the replica thread to not replicate any statement that updates the specified table, even if any other tables might be updated by the same statement. |
| Variable | [replicate\_rewrite\_db](../replication-and-binary-log-system-variables/index#replicate_rewrite_db) | From [MariaDB 10.11](../what-is-mariadb-1011/index). Allows one to configure a replica to rewrite database names. It uses the format primary\_database->replica\_database. If a replica encounters a binary log event in which the default database (i.e. the one selected by the USE statement) is primary\_database, then the replica will apply the event in replica\_database instead. |
| Variable | [replicate\_wild\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table) | Tells the replica thread to restrict replication to statements where any of the updated tables match the specified database and table name patterns. |
| Variable | [replicate\_wild\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table) | Tells the replica thread to not replicate to the tables that match the given wildcard pattern. |
| Status | [Slave\_heartbeat\_period](../replication-and-binary-log-status-variables/index#slave_heartbeat_period) | How often to request a heartbeat packet from the primary (in seconds). |
| Status | [Slave\_received\_heartbeats](../replication-and-binary-log-status-variables/index#slave_received_heartbeats) | How many heartbeats we have got from the primary. |
| Status | [Slave\_running](../replication-and-binary-log-status-variables/index#slave_running) | Shows if the replica is running. YES means that the sql thread and the IO thread are active. No means either one is not running. '' means that `@@default_master_connection` doesn't exist. |
| Variable | [Sql\_slave\_skip\_counter](../replication-and-binary-log-server-system-variables/index#sql_slave_skip_counter) | How many entries in the replication log that should be skipped (mainly used in case of errors in the log). |

 
You can access all of the above variables with either `SESSION` or `GLOBAL`.

 Note that in contrast to MySQL, all variables always show the correct active value!

 Example:

 
```
set @@default_master_connection='';
show status like 'Slave_running';
set @@default_master_connection='other_connection';
show status like 'Slave_running';

```

If `@@default_master_connection` contains a non existing name, you will get a warning.

 All other primary-related variables are global and affect either only the '' connections or all connections. For example, [Slave\_retried\_transactions](../replication-and-binary-log-status-variables/index#slave_retried_transactions) now shows the total number of retried transactions over all replicas.

 If you need to set [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) you need to set this for all primaries at the same time.

 New status variables:

 


| Name | Description |
| --- | --- |
| `[Com\_start\_all\_slaves](../replication-and-binary-log-server-status-variables/index#com_start_all_slaves)` | Number of executed `START ALL SLAVES` commands. |
| `[Com\_start\_slave](../replication-and-binary-log-server-status-variables/index#com_start_slave)` | Number of executed `START SLAVE` commands. This replaces `Com_slave_start`. |
| `[Com\_stop\_slave](../replication-and-binary-log-server-status-variables/index#com_stop_slave)` | Number of executed `STOP SLAVE` commands. This replaces `Com_slave_stop`. |
| `[Com\_stop\_all\_slaves](../replication-and-binary-log-server-status-variables/index#com_stop_all_slaves)` | Number of executed `STOP ALL SLAVES` commands. |

 
`[SHOW ALL SLAVES STATUS](../show-slave-status/index)` has the following new columns:

 


| Name | Description |
| --- | --- |
| `Connection_name` | Name of the primary connection. This is the first variable. |
| `Slave_SQL_State` | State of SQL thread. |
| `Retried_transactions` | Number of retried transactions for this connection. |
| `Max_relay_log_size` | Max relay log size for this connection. |
| `Executed_log_entries` | How many log entries the replica has executed. |
| `Slave_received_heartbeats` | How many heartbeats we have got from the primary. |
| `Slave_heartbeat_period` | How often to request a heartbeat packet from the primary (in seconds). |

 
New Files
---------

 The basic principle of the new files used by multi source replication is that they have the same name as the original relay log files suffixed with `connection_name` before the extension. The main exception is the file that holds all connection is named as the normal `master-info-file` with a `multi-` prefix.

 When you are using multi source, the following new files are created:

 


| Name | Description |
| --- | --- |
| `multi-master-info-file` | The `master-info-file` (normally `master.info`) with a `multi-` prefix. This contains all primary connections in use. |
| `master-info-file`-connection\_name`.extension` | Contains the current primary position for what's applied to in the replica. Extension is normally `.info` |
| `relay-log`-connection\_name`.xxxxx` | The relay-log name with a connection\_name suffix. The xxxxx is the relay log number. This contains the replication data read from the primary. |
| `relay-log-index`-connection\_name`.extension` |  Contains the name of the active `relay-log`-connection\_name`.xxxxx` files. Extension is normally `.index` |
| `relay-log-info-file`-connection\_name`.extension` | Contains the current primary position for the relay log. Extension is normally `.info` |

 
When creating the file, the connection name is converted to lower case and all special characters in the connection name are converted, the same way as MySQL table names are converted. This is done to make the file name portable across different systems.

 Hint:

 Instead of specifying names for `mysqld` with [--relay-log](../replication-and-binary-log-system-variables/index#relay_log), [--relay-log-index](../replication-and-binary-log-system-variables/index#relay_log_index), [--general-log-file](../server-system-variables/index#general_log_file), [--slow-query-log-file](../server-system-variables/index#slow_query_log_file), [--log-bin](../replication-and-binary-log-system-variables/index#log_bin) and [--log-bin-index](../replication-and-binary-log-system-variables/index#log_bin_index), you can just specify [--log-basename](../mysqld-options/index#-log-basename) and all the other variables are set with this as a prefix.

 Other Things
------------

 * All error messages from a replica with a connection name, that are written to the error log, are prefixed with `Master 'connection_name':`. This makes it easy to see from where an error originated.
* Errors `ER_MASTER_INFO` and `WARN_NO_MASTER_INFO` now includes connection\_name.
* There is no conflict resolution. The assumption is that there are no conflicts in data between the different primaries.
* All executed commands are stored in the normal binary log (nothing new here).
* If the server variable `log_warnings` > 1 then you will get some information in the log about how the multi-master-info file is updated (mainly for debugging).
* The output of [SHOW ALL SLAVES STATUS](../show-slave-status/index) has one more column than `SHOW SLAVE STATUS`, since it includes the `connection_name` column.
* `[RESET SLAVE](../reset-slave/index)` now deletes all relay-log files.

 replicate-... Variables
-----------------------

 * One can set the values for the `replicate-...` variables from the command line or in `my.cnf` for a given connection by prefixing the variable with the connection name.
* If one doesn't use any connection name prefix for a `replicate..` variable, then the value will be used as the default value for all connections that don't have a value set for this variable.

 Example:

 
```
mysqld --main_connection.replicate_do_db=main_database --replicate_do_db=other_database

```

The have sets the `replicate_do_db` variable to `main_database` for the connection named `main_connection`. All other connections will use the value `other_database`.

 One can also use this syntax to set `replicate-rewrite-db` for a given connection.

 Typical Use Cases
-----------------

 * You are partitioning your data over many primaries and would like to get it all together on one machine to do analytical queries on all data.
* You have many databases spread over many MariaDB/MySQL servers and would like to have all of them on one machine as an extra backup.
* In a Galera cluster the default replication filter rules like `replicate-do-db` do not apply to replication connections, but also to Galera write set applier threads. By using a named multi-primary replication connection instead, even when replicating from just one primary into the cluster, the primary-replica replication rules can be kept separate from the Galera intra-node replication traffic.

 Limitations
-----------

 * Each active connection will create 2 threads (as is normal for MariaDB replication).
* You should ensure that all primaries have different `server-id`'s. If you don't do this, you will get into trouble if you try to replicate from the multi-source replica back to your primaries.
* One can change [max\_relay\_log\_size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size) for any active connection, but new connections will always use the server startup value for `max_relay_log_size`, which can't be changed at runtime.
* Option [innodb-recovery-update-relay-log](../innodb-system-variables/index#innodb_recovery_update_relay_log) (xtradb feature to store and restore relay log position for replicas) only works for the default connection ''. As this option is not really safe and can easily cause loss of data if you use storage engines other than InnoDB, we don't recommend this option be used.
* [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) affects all connections. We don't check anymore if it's less than [Slave\_heartbeat\_period](../replication-and-binary-log-server-status-variables/index#slave_heartbeat_period), as this doesn't make sense in a multi-source setup.

 Incompatibilities with MariaDB/MySQL 5.5
----------------------------------------

 * [max\_relay\_log\_size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size) is now (almost) a normal variable and not automatically changed if [max\_binlog\_size](../replication-and-binary-log-server-system-variables/index#max_binlog_size) is changed. To keep things compatible with old config files, we set it to `max_binlog_size` at startup if its value is 0.
* You can now access replication variables that depend on the active connection with either `GLOBAL` or `SESSION`.
* We only write information about relay log positions for recovery if [innodb-recovery-update-relay-log](../xtradbinnodb-server-system-variables/index#innodb_recovery_update_relay_log) is set.
* [Slave\_retried\_transactions](../replication-and-binary-log-status-variables/index#slave_retried_transactions) now shows the total count of retried transactions over all replicas.
* The status variable `Com_slave_start` is replaced with [Com\_start\_slave](../replication-and-binary-log-status-variables/index#com_start_slave).
* The status variable `Com_slave_stop` is replaced with [Com\_stop\_slave](../replication-and-binary-log-status-variables/index#com_stop_slave).
* `FLUSH RELAY LOGS` are not replicated anymore. This is not safe as connection names may be different on the replica.

 See Also
--------

 * Using multi-source with [global transaction id](../global-transaction-id/index#use-with-multi-source-replication-and-other-multi-master-setups)
* The work in MariaDB is based on the project description at [MDEV-253](https://jira.mariadb.org/browse/MDEV-253).
* The original code base comes from [Taobao, developed by Peng Lixun](http://mysql.taobao.org/index.php/Patch_source_code#Multi-master_replication). A big thanks to them for this important feature!

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multi-source-replication/>

Table Statements
=================

   Articles about creating, modifying, and maintaining tables in MariaDB.

  

| Title | Description |
| --- | --- |
|  [ALTER](../alter/index) |  The various ALTER statements in MariaDB.  |
|  [ANALYZE TABLE](../analyze-table/index) |  Store key distributions for a table.  |
|  [CHECK TABLE](../check-table/index) |  Check table for errors.  |
|  [CHECK VIEW](../check-view/index) |  Check whether the view algorithm is correct.  |
|  [CHECKSUM TABLE](../checksum-table/index) |  Report a table checksum.  |
|  [CREATE TABLE](../create-table/index) |  Creates a new table.  |
|  [DELETE](../delete/index) |  Delete rows from one or more tables.  |
|  [DROP TABLE](../drop-table/index) |  Removes definition and data from one or more tables.  |
|  [Installing System Tables (mariadb-install-db)](../installing-system-tables-mariadb-install-db/index) |  Using mariadb-install-db to create the system tables in the 'mysql' database directory.  |
|  [mysqlcheck](../mysqlcheck/index) |  Symlink or old name for mariadb-check.  |
|  [mysql\_upgrade](../mysql_upgrade/index) |  Symlink or old name for mariadb-upgrade.  |
|  [OPTIMIZE TABLE](../optimize-table/index) |  Reclaim unused space and defragment data.  |
|  [RENAME TABLE](../rename-table/index) |  Change a table's name.  |
|  [REPAIR TABLE](../repair-table/index) |  Repairs a table, if the storage engine supports this statement.  |
|  [REPAIR VIEW](../repair-view/index) |  Fix view if the algorithms are swapped.  |
|  [REPLACE](../replace/index) |  Equivalent to DELETE + INSERT, or just an INSERT if no rows are returned.  |
|  [SHOW COLUMNS](../show-columns/index) |  Column information.  |
|  [SHOW CREATE TABLE](../show-create-table/index) |  Shows the CREATE TABLE statement that created the table.  |
|  [SHOW INDEX](../show-index/index) |  Information about table indexes.  |
|  [TRUNCATE TABLE](../truncate-table/index) |  DROP and re-CREATE a table.  |
|  [UPDATE](../update/index) |  Modify rows in one or more tables.  |
|  [Obsolete Table Commands](../obsolete-table-commands/index) |  Table commands that have been removed from MariaDB  |
|  [IGNORE](../ignore/index) |  Suppress errors while trying to violate a UNIQUE constraint.  |
|  [System-Versioned Tables](../system-versioned-tables/index) |  System-versioned tables record the history of all changes to table data.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-statements/>

Replication Overview
====================

     Replication is a feature allowing the contents of one or more servers (called primaries) to be mirrored on one or more servers (called replicas).

 You can exert control over which data to replicate. All databases, one or more databases, or tables within a database can each be selectively replicated.

 The main mechanism used in replication is the [binary log](../binary-log/index). If binary logging is enabled, all updates to the database (data manipulation and data definition) are written into the binary log as binlog events. Replicas read the binary log from each primary in order to access the data to replicate. A [relay log](../relay-log/index) is created on the replica, using the same format as the binary log, and this is used to perform the replication. Old relay log files are removed when no longer needed.

 A replica server keeps track of the position in the primary's binlog of the last event applied on the replica. This allows the replica server to re-connect and resume from where it left off after replication has been temporarily stopped. It also allows a replica to disconnect, be cloned and then have the new replica resume replication from the same primary.

 Primaries and replicas do not need to be in constant communication with each other. It's quite possible to take servers offline or disconnect from the network, and when they come back, replication will continue where it left off.

 Replication Uses
----------------

 Replication is used in a number of common scenarios. Uses include:

 * Scalability. By having one or more replicas, reads can be spread over multiple servers, reducing the load on the primary. The most common scenario for a high-read, low-write environment is to have one primary, where all the writes occur, replicating to multiple replicas, which handle most of the reads.
* Data analysis. Analyzing data may have too much of an impact on a primary server, and this can similarly be handled on a replica, while the primary continues unaffected by the extra load.
* Backup assistance. [Backups](../backing-up-and-restoring/index) can more easily be run if a server is not actively changing the data. A common scenario is to replicate the data to a replica, which is then disconnected from the primary with the data in a stable state. Backup is then performed from this server. See [Replication as a Backup Solution](../replication-as-a-backup-solution/index).
* Distribution of data. Instead of being connected to a remote primary, it's possible to replicate the data locally and work from this data instead.

 Common Replication Setups
-------------------------

 ### Standard Replication

 ![standard_replication]

 * Provides infinite read scale out.
* Provides high-availability by upgrading replica to primary.

 ### Ring Replication

 ![ring_replication]

 * Provides read and write scaling.
* Doesn’t handle conflicts.
* If one primary fails, replication stops.

 ### Star Replication

 ![star_replication]

 * Provides read and write scaling.
* Doesn’t handle conflicts.
* Have to use replication filters to avoid duplication of data.

 ### Multi-Source Replication

 ![multi_source_replication]

 * Allows you to combine data from different sources.
* Different domains executed independently in parallel on all replicas.

 Cross-Version Replication Compatibility
---------------------------------------

 The following table describes replication compatibility between different MariaDB Server versions. In general, the replica should always be at least equivalent in version to the primary:

 


|  | Primary→ | [MariaDB 10.3](../what-is-mariadb-103/index) | [MariaDB 10.4](../what-is-mariadb-104/index) | [MariaDB 10.5](../what-is-mariadb-105/index) | [MariaDB 10.6](../what-is-mariadb-106/index) | [MariaDB 10.11](../what-is-mariadb-1011/index) |
| --- | --- | --- | --- | --- | --- | --- |
| Replica ↓ |  |  |  |  |  |  |
| [MariaDB 10.3](../what-is-mariadb-103/index) |  | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| [MariaDB 10.4](../what-is-mariadb-104/index) |  | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| [MariaDB 10.5](../what-is-mariadb-105/index) |  | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| [MariaDB 10.6](../what-is-mariadb-106/index) |  | ✅ | ✅ | ✅ | ✅ | ⛔ |
| [MariaDB 10.11](../what-is-mariadb-1011/index) |  | ✅ | ✅ | ✅ | ✅ | ✅ |

 
* ✅: This combination is supported.
* ⛔: This combination is **not** supported.

 For replication compatibility details between MariaDB and MySQL, see [MariaDB versus MySQL - Compatibility: Replication Compatibility](../mariadb-vs-mysql-compatibility/index#replication-compatibility).

 See Also
--------

 * [Setting Up Replication](../setting-up-replication/index)
* [MariaDB vs. MySQL Replication Compatibility](../mariadb-vs-mysql-compatibility/index#replication-compatibility)
* [MariaDB Galera Cluster and M/S replication](https://www.youtube.com/watch?v=Nd0nvltLPdQ) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-overview/>

Replication Commands
=====================

   
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 A list of replication-related commands. See [replication](../replication/index) for more replication-related information.

  

| Title | Description |
| --- | --- |
|  [CHANGE MASTER TO](../change-master-to/index) |  Set or change replica parameters for connecting to the primary.  |
|  [START SLAVE](../start-replica/index) |  Start replica threads.  |
|  [STOP SLAVE](../stop-replica/index) |  Stop replica threads.  |
|  [RESET REPLICA/SLAVE](../reset-replica/index) |  Forget replica connection information and start a new relay log file.  |
|  [SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER](../set-global-sql_slave_skip_counter/index) |  Skips a number of events from the primary.  |
|  [SHOW RELAYLOG EVENTS](../show-relaylog-events/index) |  Show events in the relay log.  |
|  [SHOW SLAVE STATUS](../show-replica-status/index) |  Show status for one or all primaries.  |
|  [SHOW MASTER STATUS](../show-binlog-status/index) |  Status information about the binary log.  |
|  [SHOW SLAVE HOSTS](../show-replica-hosts/index) |  Display replicas currently registered with the primary.  |
|  [RESET MASTER](../reset-master/index) |  Delete binary log files.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-commands/>

Setting up a Replica with Mariabackup
=====================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Mariabackup makes it very easy to set up a [replica](../high-availability-performance-tuning-mariadb-replication/index) using a [full backup](../full-backup-and-restore-with-mariabackup/index). This page documents how to set up a replica from a backup.

 If you are using [MariaDB Galera Cluster](../galera/index), then you may want to try one of the following pages instead:

 * [Configuring MariaDB Replication between MariaDB Galera Cluster and MariaDB Server](../using-mariadb-replication-with-mariadb-galera-cluster-configuring-mariadb-r/index)
* [Configuring MariaDB Replication between Two MariaDB Galera Clusters](../configuring-mariadb-replication-between-two-mariadb-galera-clusters/index)

 Backup the Database and Prepare It
----------------------------------

 The first step is to simply take and prepare a fresh [full backup](../full-backup-and-restore-with-mariabackup/index) of a database server in the [replication topology](../replication-overview/index#common-replication-setups). If the source database server is the desired replication primary, then we do not need to add any additional options when taking the full backup. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

If the source database server is a [replica](../high-availability-performance-tuning-mariadb-replication/index) of the desired primary, then we should add the [--slave-info](../mariabackup-options/index#-slave-info) option, and possibly the [--safe-slave-backup](../mariabackup-options/index#-safe-slave-backup) option. For example:

 
```
$ mariabackup --backup \
   --slave-info --safe-slave-backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

And then we would prepare the backup as you normally would. For example:

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup/

```

Copy the Backup to the New Replica
----------------------------------

 Once the backup is done and prepared, we can copy it to the new replica. For example:

 
```
$ rsync -avP /var/mariadb/backup dbserver2:/var/mariadb/backup

```

Restore the Backup on the New Replica
-------------------------------------

 At this point, we can restore the backup to the [datadir](../server-system-variables/index#datadir), as you normally would. For example:

 
```
$ mariabackup --copy-back \
   --target-dir=/var/mariadb/backup/

```

And adjusting file permissions, if necessary:

 
```
$ chown -R mysql:mysql /var/lib/mysql/

```

Create a Replication User on the Primary
----------------------------------------

 Before the new replica can begin replicating from the primary, we need to [create a user account](../create-user/index) on the primary that the replica can use to connect, and we need to [grant](../grant/index) the user account the [REPLICATION SLAVE](../grant/index#global-privileges) privilege. For example:

 
```
CREATE USER 'repl'@'dbserver2' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'dbserver2';

```

Configure the New Replica
-------------------------

 Before we start the server on the new replica, we need to configure it. At the very least, we need to ensure that it has a unique [server\_id](../replication-and-binary-log-system-variables/index#server_id) value. We also need to make sure other replication settings are what we want them to be, such as the various [GTID system variables](../gtid/index#system-variables-for-global-transaction-id), if those apply in the specific environment.

 Once configuration is done, we can [start the MariaDB Server process](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) on the new replica.

 Start Replication on the New Replica
------------------------------------

 At this point, we need to get the replication coordinates of the primary from the original backup directory.

 If we took the backup on the primary, then the coordinates will be in the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file. If we took the backup on another replica and if we provided the [--slave-info](../mariabackup-options/index#-slave-info) option, then the coordinates will be in the file [xtrabackup\_slave\_info](../files-created-by-mariabackup/index#xtrabackup_slave_info) file.

 Mariabackup dumps replication coordinates in two forms: [GTID](../gtid/index) coordinates and [binary log](../binary-log/index) file and position coordinates, like the ones you would normally see from [SHOW MASTER STATUS](../show-master-status/index) output. We can choose which set of coordinates we would like to use to set up replication.

 For example:

 
```
mariadb-bin.000096 568 0-1-2

```

Regardless of the coordinates we use, we will have to set up the primary connection using [CHANGE MASTER TO](../change-master-to/index) and then start the replication threads with [START SLAVE](../start-slave/index).

 ### GTIDs

 If we want to use GTIDs, then we will have to first set [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) to the [GTID](../gtid/index) coordinates that we pulled from either the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file or the [xtrabackup\_slave\_info](../files-created-by-mariabackup/index#xtrabackup_slave_info) file in the backup directory. For example:

 
```
$ cat xtrabackup_binlog_info
mariadb-bin.000096 568 0-1-2

```

And then we would set `MASTER_USE_GTID=slave_pos` in the [CHANGE MASTER TO](../change-master-to/index) command. For example:

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO 
   MASTER_HOST="dbserver1", 
   MASTER_PORT=3306, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

### File and Position

 If we want to use the [binary log](../binary-log/index) file and position coordinates, then we would set `MASTER_LOG_FILE` and `MASTER_LOG_POS` in the [CHANGE MASTER TO](../change-master-to/index) command to the file and position coordinates that we pulled; either the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file or the [xtrabackup\_slave\_info](../files-created-by-mariabackup/index#xtrabackup_slave_info) file in the backup directory, depending on whether the backup was taken from the primary or from a replica of the primary. For example:

 
```
CHANGE MASTER TO 
   MASTER_HOST="dbserver1", 
   MASTER_PORT=3306, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_LOG_FILE='mariadb-bin.000096',
   MASTER_LOG_POS=568;
START SLAVE;

```

Check the Status of the New Replica
-----------------------------------

 We should be done setting up the replica now, so we should check its status with [SHOW SLAVE STATUS](../show-slave-status/index). For example:

 
```
SHOW SLAVE STATUS\G

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-up-a-replica-with-mariabackup/>

Read-Only Replicas
==================

     A common [replication](../standard-replication/index) setup is to have the replicas [read-only](../server-system-variables/index#read_only) to ensure that no one accidentally updates them. If the replica has [binary logging enabled](../setting-up-replication/index) and [gtid\_strict\_mode](../gtid/index#gtid_strict_mode) is used, then any update that causes changes to the [binary log](../binary-log/index) will stop replication.

 When the variable `read_only` is set to 1, no updates are permitted except from users with the [SUPER](../grant/index#super) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) or [READ ONLY ADMIN](../grant/index#read_only-admin) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) or replica servers updating from a primary. Inserting rows to log tables, updates to temporary tables and [OPTIMIZE TABLE](../optimize-table/index) or [ANALYZE TABLE](../analyze-table/index) statements on temporary tables are excluded from this limitation.

 If read\_only is set to 1, then the [SET PASSWORD](../set-password/index) statement is limited only to users with the [SUPER](../grant/index#super) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) or [READ ONLY ADMIN](../grant/index#read_only-admin) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)).

 Attempting to set the `read_only` variable to 1 will fail if the current session has table locks or transactions pending.

 The statement will wait for other sessions that hold table locks. While the attempt to set read\_only is waiting, other requests for table locks or transactions will also wait until read\_only has been set.

 From [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), some issues related to read only replicas are fixed:

 * [CREATE](../create-table/index), [DROP](../drop-table/index), [ALTER](../alter-table/index), [INSERT](../insert/index) and [DELETE](../delete/index) of temporary tables are not logged to binary log, even in [statement](../binary-log-formats/index#statement-based-logging) or [mixed](../binary-log-formats/index#mixed-logging) mode. With earlier MariaDB versions, one can avoid the problem with temporary tables by using [binlog\_format=ROW](../binary-log-formats/index#row-based-logging) in which cases temporary tables are never logged.
* Changes to temporary tables created during `read_only` will not be logged even after `read_only` mode is disabled (for example if the replica is promoted to a primary).
* The admin statements [ANALYZE](../analyze-table/index), [CHECK](../check-table/index), [OPTIMIZE](../optimize-table/index) and [REPAIR](../repair-table/index) will not be logged to the binary log under read-only.

 ### Older MariaDB Versions

 If you are using an older MariaDB version with read-only replicas and binary logging enabled on the replica, and you need to do some changes but don't want to have them logged to the binary log, the easiest way to avoid the logging is to [disable binary logging](../activating-the-binary-log/index) while running as root during maintenance:

 
```
set sql_log_bin=0;
alter table test engine=rocksdb;

```

The above changes the test table on the replica to rocksdb without registering the change in the binary log.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/read-only-replicas/>

Replication Threads
===================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  MariaDB's [replication](../high-availability-performance-tuning-mariadb-replication/index) implementation requires several types of threads.

 Threads on the Primary
----------------------

 The primary usually only has one type of replication-related thread: the binary log dump thread.

 If [semisynchronous replication](../semisynchronous-replication/index) is enabled, then the primary also has an ACK receiver thread.

 ### Binary Log Dump Thread

 The binary log dump thread runs on the primary and dumps the [binary log](../binary-log/index) to the replica. This thread can be identified by running the [SHOW PROCESSLIST](../show-processlist/index) statement and finding the thread where the [thread command](../thread-command-values/index) is `"Binlog Dump"`.

 The primary creates a separate binary log dump thread for each replica connected to the primary. You can identify which replicas are connected to the primary by executing the [SHOW SLAVE HOSTS](../show-slave-hosts/index) statement.

 #### Binary Log Dump Threads and the Shutdown Process

 When a primary server is shutdown and it goes through the normal shutdown process, the primary kills client threads in random order. By default, the primary also considers its binary log dump threads to be regular client threads. As a consequence, the binary log dump threads can be killed while client threads still exist, and this means that data can be written on the primary during a normal shutdown that won't be replicated. This is true even if [semi-synchronous replication](../semisynchronous-replication/index) is being used.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this problem can be solved by shutting down the server using either the [mariadb-admin](../mariadb-admin/index) utility or the [SHUTDOWN](../shutdown/index) command, and providing a special option.

 For example, this problem can be solved by shutting down the server with the [mariadb-admin](../mariadb-admin/index) utility and by providing the `--wait-for-all-slaves` option to the utility and by executing the `shutdown` command with the utility:

 
```
mariadb-admin --wait-for-all-slaves shutdown

```

Or this problem can be solved by shutting down the server with the [SHUTDOWN](../shutdown/index) command and by providing the `WAIT FOR ALL SLAVES` option to the command:

 
```
SHUTDOWN WAIT FOR ALL SLAVES;

```

When one of these special options is provided, the server only kills its binary log dump threads after all client threads have been killed, and it only completes the shutdown after the last [binary log](../binary-log/index) has been sent to all connected replicas.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, it is still not possible to enable this behavior by default. This means that this behavior is currently inaccessible when shutting down the server using tools like [systemd](../systemd/index) or [sysVinit](../sysvinit/index).

 In [MariaDB 10.3](../what-is-mariadb-103/index) and before, it is recommended to manually switchover replicas to a new primary before shutting down the old primary.

 ### ACK Receiver Thread

 When [semisynchronous replication](../semisynchronous-replication/index) is enabled, semisynchronous replicas send acknowledgements (ACKs) to their primary to confirm that they have received some transaction. The primary creates an ACK receiver thread to receive these ACKs.

 Threads on the Replica
----------------------

 The replica has three types of replication-related threads: the replica I/O thread, the replica SQL thread, and worker threads, which are only applicable when [parallel replication](../parallel-replication/index) is in use.

 When [multi-source replication](../multi-source-replication/index) is in use, each independent replication connection has its own replica threads of each type.

 ### Replica I/O Thread

 The replica's I/O thread receives the [binary log](../binary-log/index) events from the primary and writes them to its [relay log](../relay-log/index).

 #### Binary Log Position

 The [binary log](../binary-log/index) position of the replica's I/O thread can be checked by executing the [SHOW SLAVE STATUS](../show-slave-status/index) statement. It will be shown as the `Master_Log_File` and `Read_Master_Log_Pos` columns.

 The [binary log](../binary-log/index) position of the replica's I/O thread can be set by setting the [MASTER\_LOG\_FILE](../change-master-to/index#master_log_file) and [MASTER\_LOG\_POS](../change-master-to/index#master_log_pos) options with the [CHANGE MASTER](../change-master-to/index) statement.

 The [binary log](../binary-log/index) position of the replica's I/O thread and the values of most other [CHANGE MASTER](../change-master-to/index) options are written to either the default `master.info` file or the file that is configured by the [master\_info\_file](../mysqld-options/index#-master-info-file) option. The replica's I/O thread keeps this [binary log](../binary-log/index) position updated as it downloads events only when the [MASTER\_USE\_GTID](#master_use_gtid) option is set to `NO`. Otherwise the file is not updated on a per event basis. See [CHANGE MASTER TO: Option Persistence](../change-master-to/index#option-persistence) for more information.

 ### Replica SQL Thread

 The replica's SQL thread reads events from the [relay log](../relay-log/index). What it does with them depends on whether [parallel replication](../parallel-replication/index) is in use. If [parallel replication](../parallel-replication/index) is not in use, then the SQL thread applies the events to its local copy of the data. If [parallel replication](../parallel-replication/index) is in use, then the SQL thread hands off the events to its worker threads to apply in parallel.

 #### Relay Log Position

 The [relay log](../relay-log/index) position of the replica's SQL thread can be checked by executing the [SHOW SLAVE STATUS](../show-slave-status/index) statement. It will be shown as the `Relay_Log_File` and `Relay_Log_Pos` columns.

 The [relay log](../relay-log/index) position of the replica's SQL thread can be set by setting the [RELAY\_LOG\_FILE](../change-master-to/index#relay_log_file) and [RELAY\_LOG\_POS](../change-master-to/index#relay_log_pos) options with the [CHANGE MASTER](../change-master-to/index) statement.

 The [relay log](../relay-log/index) position of the replica's SQL thread is written to either the default `relay-log.info` file or the file that is configured by the [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable. The replica's SQL thread keeps this [relay log](../relay-log/index) position updated as it applies events. See [CHANGE MASTER TO: Option Persistence](../change-master-to/index#option-persistence) for more information.

 #### Binary Log Position

 The corresponding [binary log](../binary-log/index) position of the current [relay log](../relay-log/index) position of the replica's SQL thread can be checked by executing the [SHOW SLAVE STATUS](../show-slave-status/index) statement. It will be shown as the `Relay_Master_Log_File` and `Exec_Master_Log_Pos` columns.

 #### GTID Position

 If the replica is replicating [binary log](../binary-log/index) events that contain [GTIDs](../gtid/index), then the [replica's's SQL thread](index#replica-sql-thread) will write every GTID that it applies to the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table. This GTID can be inspected and modified through the [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) system variable.

 If the replica has the [log\_slave\_updates](../replication-and-binary-log-system-variables/index#log_slave_updates) system variable enabled and if the replica has the [binary log](../binary-log/index) enabled, then every write by the [replica's SQL thread](index#replica-sql-thread) will also go into the replica's [binary log](../binary-log/index). This means that [GTIDs](../gtid/index) of replicated transactions would be reflected in the value of the [gtid\_binlog\_pos](../gtid/index#gtid_binlog_pos) system variable.

 See [CHANGE MASTER TO: GTID Persistence](../change-master-to/index#gtid-persistence) for more information.

 ### Worker Threads

 When [parallel replication](../parallel-replication/index) is in use, then the SQL thread hands off the events to its worker threads to apply in parallel.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-threads/>

Global Transaction ID
=====================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  
Note that MariaDB and MySQL have different GTID implementations, and that these are not compatible with each other. MariaDB can be a slave for a MySQL master but MySQL cannot be a slave for a MariaDB master.

 
Overview
--------

 MariaDB replication in general works as follows (see [Replication overview](../replication-overview/index) for more information):

 On a master server, all updates to the database (DML and DDL) are written into the [binary log](../binary-log/index) as binlog events. A replica server connects to the primary and reads the binlog events, then applies the events locally to replicate the same changes as done on the primary. A server can be both a primary and a replica at the same time, and it is thus possible for binlog events to replicated through multiple levels of servers.

 A replica server keeps track of the position in the primary's binlog of the last event applied on the replica. This allows the replica server to re-connect and resume from where it left off after replication has been temporarily stopped. It also allows a replica to disconnect, be cloned and then have the new replica resume replication from the same primary.

 Global transaction ID introduces a new event attached to each event group in the binlog. (An event group is a collection of events that are always applied as a unit. They are best thought of as a "transaction", though they also include non-transactional DML statements, as well as DDL). As an event group is replicated from primary server to replica server, the global transaction ID is preserved. Since the ID is globally unique across the entire group of servers, this makes it easy to uniquely identify the same binlog events on different servers that replicate each other (this was not easily possible before [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/)).

 Benefits
--------

 Using global transaction ID provides two main benefits:

 1. Easy to change a replica server to connect to and replicate from a different primary server.

  The replica remembers the global transaction ID of the last event group applied from the old primary. This makes it easy to know where to resume replication on the new primary, since the global transaction IDs are known throughout the entire replication hierarchy. This is not the case when using old-style replication; in this case the replica knows only the specific file name and offset of the old primary server of the last event applied. There is no simple way to guess from this the correct file name and offset on a new primary.

 2. The state of the replica is recorded in a crash-safe way.

  The replica keeps track of its current position (the global transaction ID of the last transaction applied) in the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) system table. If this table is using a transactional storage engine (such as InnoDB, which is the default), then updates to the state are done in the same transaction as the updates to the data. This makes the state crash-safe; if the replica server crashes, crash recovery on restart will make sure that the recorded replication position matches the changes that were actually replicated. This is not the case for old-style replication, where the state is recorded in a file relay-log.info, which is updated independently of the actual data changes and can easily get out of sync if the replica server crashes. (This works for DML to transactional tables; non-transactional tables and DDL in general are not crash-safe in MariaDB.)

 Because of these two benefits, it is generally recommended to use global transaction ID for any replication setups based on [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) or later. However, old-style replication continues to work as always, so there is no pressing need to change existing setups. Global transaction ID integrates smoothly with old-style replication, and the two can be used freely together in the same replication hierarchy. There is no special configuration needed of the server to start using global transaction ID. However, it must be explicitly set for a replica server with the appropriate [CHANGE MASTER](../change-master-to/index) option; by default old-style replication is used by a replication replica, to maintain backwards compatibility.

 Implementation
--------------

 A global transaction ID, or GTID for short, consists of three numbers separated with dashes '-'. For example:

 `0-1-10`

 * The first number 0 is the domain ID, which is specific for global transaction ID (more on this below). It is a 32-bit unsigned integer.
* The second number is the server ID, the same as is also used in old-style replication. It is a 32-bit unsigned integer.
* The third number is the sequence number. This is a 64-bit unsigned integer that is monotonically increasing for each new event group logged into the binlog.

 The server ID is set to the server ID of the server where the event group is first logged into the binlog. The sequence number is increased on a server for every event group logged. Since server IDs must be unique for every server, this makes the (server\_id, sequence\_number) pair, and hence the whole GTID, globally unique.

 Using a 64-bit number provides ample range that there should be no risk of it overflowing in the foreseeable future. However, one should not artificially (by setting `gtid_seq_no`) inject a GTID with a very high sequence number close to the limit of 64-bit.

 ### The Domain ID

 When events are replicated from a primary server to a replica server, the events are always logged into the replica's binlog in the same order that they were read from the primary's binlog. Thus, if there is only ever a single primary server receiving (non-replication) updates at a time, then the binlog order will be identical on every server in the replication hierarchy.

 This consistent binlog order is used by the replica to keep track of its current position in the replication. Basically, the replica remembers the GTID of the last event group replicated from the primary. When reconnecting to a primary, whether the same one or a new one, it sends this GTID position to the primary, and the primary starts sending events from the first event after the corresponding event group.

 However, if user updates are done independently on multiple servers at the same time, then in general it is not possible for binlog order to be identical across all servers. This can happen when using multi-source replication, with multi-primary ring topologies, or just if manual updates are done on a replica that is replicating from active primary. If the binlog order is different on the new primary from the order on the old primary, then it is not sufficient for the replica to keep track of a single GTID to completely record the current state.

 The domain ID, the first component of the GTID, is used to handle this.

 In general, the binlog is not a single ordered stream. Rather, it consists of a number of different streams, each one identified by its own domain ID. Within each stream, GTIDs always have the same order in every server binlog. However, different streams can be interleaved in different ways on different servers.

 A replica server then keeps track of its replication position by recording the last GTID applied within each replication stream. When connecting to a new primary, the replica can start replication from a different point in the binlog for each domain ID.

 For more details on using multi-primary setups and multiple domain IDs, see [Use with multi-source replication and other multi-primary setups](#use-with-multi-source-replication-and-other-multi-primary-setups).

 Simple replication setups only have a single primary being updated by the application at any one time. In such setups, there is only a single replication stream needed. Then domain ID can be ignored, and left as the default of 0 on all servers.

 Using Global Transaction IDs
----------------------------

 Global transaction ID is enabled automatically. Each event group logged to the binlog receives a GTID event, as can be seen with [mariadb-binlog](../mariadb-binlog/index) or [SHOW BINLOG EVENTS](../show-binlog-events/index).

 The replica automatically keeps track of the GTID of the last applied event group, as can be seen from the [gtid\_slave\_pos](#gtid_slave_pos) variable:

 
```
SELECT @@GLOBAL.gtid_slave_pos
0-1-1

```

When a replica connects to a primary, it can use either global transaction ID or old-style filename/offset to decide where in the primary binlogs to start replicating from. To use global transaction ID, use the [CHANGE MASTER](../change-master-to/index) *master\_use\_gtid* option:

 `CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no }`

 A replica is configured to use GTID by `CHANGE MASTER TO master_use_gtid=slave_pos`. When the replica connects to the primary, it will start replication at the position of the last GTID replicated to the replica, which can be seen in the variable [gtid\_slave\_pos](#gtid_slave_pos). Since GTIDs are the same across all replication servers, the replica can then be pointed to a different primary, and the correct position will be determined automatically.

 But suppose that we set up two servers A and B and let A be the primary and B the replica. It runs for a while. Then at some point we take down A, and B becomes the new primary. Then later we want to add A back, this time as a replica.

 Since A was never a replica before, it does not have any prior replicated GTIDs, and [gtid\_slave\_pos](#gtid_slave_pos) will be empty. To allow A to be added as a replica automatically, `master_use_gtid=current_pos` can be used. This will connect using the value of the variable [gtid\_current\_pos](#gtid_current_pos) instead of [gtid\_slave\_pos](#gtid_slave_pos), which also takes into account GTIDs written into the binlog when the server was a primary.

 When using `master_use_gtid=current_pos` there is no need to consider whether a server was a primary or a replica prior to using [CHANGE MASTER](../change-master-to/index). But care must be taken not to inject extra transactions into the binlog on the replica server that are not intended to be replicated to other servers. If such an extra transaction is the most recent when the replica starts, it will be used as the starting point of replication. This will probably fail because that transaction is not present on the primary. To avoid local changes on a replica server to go into the binlog, set [sql\_log\_bin](../replication-and-binary-log-system-variables/index#sql_log_bin) to 0.

 If it is undesirable that changes to the binlog on the replica affects the GTID replication position, then `master_use_gtid=slave_pos` should be used. Then the replica will always connect to the primary at the position of the last replicated GTID. This may avoid some surprises for users that expect behavior consistent with traditional replication, where the replication position is never changed by local changes done on a server.

 When [GTID strict mode](#gtid_strict_mode) is enabled (by setting `@@GLOBAL.gtid_strict_mode` to 1), it is normally best to use `current_pos`. In strict mode, extra transactions on the primary are disallowed.

 If a replica is configured with the binlog disabled, `current_pos` and `slave_pos` are equivalent.

 Even when a replica is configured to connect with the old-style binlog filename and offset (`CHANGE MASTER TO master_log_file=..., master_log_pos=...`), it will still keep track of the current GTID position in `@@GLOBAL.gtid_slave_pos`. This means that an existing replica previously configured and running can be changed to connect with GTID (to the same or a new master) simply with:

 `CHANGE MASTER TO master_use_gtid = slave_pos`

 The replica remembers that `master_use_gtid=slave_pos|master_pos` was specified and will use it also for subsequent connects, until it is explicitly changed by specifying `master_log_file/pos=...` or `master_use_gtid=no`. The current value can be seen as the field Using\_Gtid of SHOW SLAVE STATUS:

 
```
SHOW SLAVE STATUS\G
...
Using_Gtid: Slave_pos

```

The replica server internally uses the [mysql.gtid\_slave\_pos table](../mysqlgtid_slave_pos-table/index) to store the GTID position (and so preserve the value of `@@GLOBAL.gtid_slave_pos` across server restarts). After upgrading a server to 10.0, it is necessary to run [mysql\_upgrade](../mysql_upgrade/index) (as always) to get the table created.

 In order to be crash-safe, this table must use a transactional storage engine such as InnoDB. When MariaDB is first installed (or upgraded to 10.0.2+) the table is created using the default storage engine - which itself defaults to InnoDB. If there is a need to change the storage engine for this table (to make it transactional on a system configured with [MyISAM](../myisam/index) as the default storage engine, for example), use [ALTER TABLE](../alter-table/index):

 `ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB`

 The [mysql.gtid\_slave\_pos table](../mysqlgtid_slave_pos-table/index) should not be modified in any other way. In particular, do not try to update the rows in the table to change the replica's idea of the current GTID position; instead use

 `SET GLOBAL gtid_slave_pos = '0-1-1'`

 Starting from [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), the server variable [gtid\_pos\_auto\_engines](#gtid_pos_auto_engines) can preferably be set to make the server handle this automatically. See the description of the [mysql.gtid\_slave\_pos table](../mysqlgtid_slave_pos-table/index) for details.

 ### Using `current_pos` vs. `slave_pos`

 When setting the [MASTER\_USE\_GTID](../change-master-to/index#master_use_gtid) replication parameter, you have the option of enabling Global Transaction IDs to use either the `current_pos` or `slave_pos` values. 

 Using the value `current_pos` causes the replica to set its position based on the [gtid\_current\_pos](#gtid_current_pos) system variable, which is a union of [gtid\_binlog\_pos](#gtid_binlog_pos) and [gtid\_slave\_pos](#gtid_slave_pos). Using the value `slave_pos` causes the replica to instead set its position based on the [gtid\_slave\_pos](#gtid_slave_pos) system variable.

 You may run into issues when you use the value `current_pos` if you write any local transactions on the replica. For instance, if you issue an [INSERT](../insert/index) statement or otherwise write to a table while the [replica threads](../replication-threads/index#threads-on-the-slave) are stopped, then new local GTIDs may be generated in [gtid\_binlog\_pos](#gtid_binlog_pos), which will affect the replica's value of [gtid\_current\_pos](#gtid_current_pos). This may cause errors when the [replica threads](../replication-threads/index#threads-on-the-slave) are restarted, since the local GTIDs will be absent from the primary.

 You can correct this issue by setting the [MASTER\_USE\_GTID](../change-master-to/index#master_use_gtid) replication parameter to `slave_pos` instead of `current_pos`. For example:

 
```
CHANGE MASTER TO MASTER_USE_GTID = slave_pos;
START SLAVE;

```

### Using GTIDs with Parallel Replication

 If [parallel replication](../parallel-replication/index) is in use, then events that were logged with GTIDs with different [gtid\_domain\_id](index#gtid_domain_id) values can be applied in parallel in an [out-of-order](../parallel-replication/index#out-of-order-parallel-replication) manner. 

 ### Using GTIDs with MariaDB Galera Cluster

 Starting with [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), MariaDB Galera Cluster has limited support for GTIDs. See [Using MariaDB GTIDs with MariaDB Galera Cluster](../using-mariadb-gtids-with-mariadb-galera-cluster/index) for more information.

 Setting up a New Replica Server with Global Transaction ID
----------------------------------------------------------

 Setting up a new replica server with global transaction ID is not much different from setting up an old-style replica. The basic steps are:

 1. Setup the new server and load it with the initial data.

 2. Start the replica replicating from the appropriate point in the primary's binlog.

 ### Setting up a New Replica with an Empty Server

 The simplest way for testing purposes is probably to setup a new, empty replica server and replicate all of the primary's binlogs from the start (this is usually not feasible in a realistic production setup, as the initial binlog files will probably have been purged or take too long to apply).

 The replica server is installed in the normal way. By default, the GTID position for a newly installed server is empty, which makes the replica replicate from the start of the primary's binlogs. But if the replica was used for other purposes before, the initial position can be explicitly set to empty first:

 `SET GLOBAL gtid_slave_pos = "";`

 Next, point the replica to the master with [CHANGE MASTER](../change-master-to/index). Specify master\_host etc. as usual. But instead of specifying master\_log\_file and master\_log\_pos manually, use `master_use_gtid=current_pos` (or `slave_pos` to have GTID do it automatically:

 
```
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=current_pos;
START SLAVE;

```

### Setting up a New Replica From a Backup

 The normal way to set up a new replication replica is to take a backup from an existing server (either a primary or replica in the replication topology), and then restore that backup on the server acting as the new replica, and the configure it to start replicating from the appropriate position in the primary's binary log.

 It is important that the position at which replication is started corresponds exactly to the state of the data at the point in time that the backup was taken. Otherwise, the replica can end up with different data than the primary because of missing or duplicated transactions. Of course, if there are no writes to the server being backed up during the backup process, then a simple [SHOW MASTER STATUS](../show-master-status/index) will give the correct position.

 See the description of the specific backup tool to determine how to get the binary log position that corresponds to the backup.

 Once the current binary log position for the backup has been obtained, in the form of a binary log file name and position, the corresponding GTID position can be obtained from [BINLOG\_GTID\_POS()](../binlog_gtid_pos/index) on the server that was backed up:

 
```
SELECT BINLOG_GTID_POS("master-bin.000001", 600);

```

The new replica can then start replicating from the primary by setting the correct value for [gtid\_slave\_pos](#gtid_slave_pos), and then executing [CHANGE MASTER](../change-master-to/index) with the relevant values for the primary, and then starting the [replica threads](../replication-threads/index#threads-on-the-slave) by executing [START SLAVE](../start-slave/index). For example:

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=slave_pos;
START SLAVE;

```

This method is particularly useful when setting up a new replica from a backup of the primary. Remember to ensure that the value of [server\_id](../replication-and-binary-log-system-variables/index#server_id) configured on the new replica is different from that of any other server in the replication topology.

 If the backup was taken of an existing replica server, then the new replica should already have the correct GTID position stored in the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table. This is assuming that this table was backed up and that it was backed up in a consistent manner with changes to other tables. In this case, there is no need to explicitly look up the GTID position on the old server and set it on the new replica - it will be already correctly loaded from the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table. This however does not work if the backup was taken from the primary - because then the current GTID position is contained in the binary log, not in the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table or any other table.

 #### Setting up a New Replica with Mariabackup

 A new replica can easily be set up with [Mariabackup](../mariabackup/index), which is a fork of [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index). See [Setting up a Replica with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index) for more information.

 #### Setting up a New Replica with mariadb-dump

 A new replica can also be set up with [mariadb-dump](../mariadb-dump/index). 

 [mariadb-dump](../mariadb-dump/index) automatically includes the GTID position as a comment in the backup file if either the [--master-data](../mariadb-dump/index#options) or [--dump-slave](../mariadb-dump/index#options) option is used. It also automatically includes the commands to set [gtid\_slave\_pos](#gtid_slave_pos) and execute [CHANGE MASTER](../change-master-to/index) in the backup file if the [--gtid](../mariadb-dump/index#options) option is used with either the [--master-data](../mariadb-dump/index#options) or [--dump-slave](../mariadb-dump/index#options) option.

 ### Switching An Existing Old-Style Replica To Use GTID.

 If there is already an existing replica running using old-style binlog filename/offset position, then this can be changed to use GTID directly. This can be useful for upgrades for example, or where there are already tools to setup new replica using old-style binlog positions.

 When a replica connects to a primary using old-style binlog positions, and the primary supports GTID (i.e. is [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) or later), then the replica automatically downloads the GTID position at connect and updates it during replication. Thus, once a replica has connected to the GTID-aware primary at least once, it can be switched to using GTID without any other actions needed;

 
```
STOP SLAVE;
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=current_pos;
START SLAVE;

```

(A later version will probably add a way to setup the replica so that it will connect with old-style binlog file/offset the first time, and automatically switch to using GTID on subsequent connects.)

 Changing a Replica to Replicate From a Different Primary
--------------------------------------------------------

 Once replication is running with GTID (master\_use\_gtid=current\_pos|slave\_pos), the replica can be pointed to a new primary simply by specifying in CHANGE MASTER the new master\_host (and if required master\_port, master\_user, and master\_password):

 
```
STOP SLAVE;
CHANGE MASTER TO master_host='127.0.0.1', master_port=3312;
START SLAVE;

```

The replica has a record of the GTID of the last applied transaction from the old primary, and since GTIDs are identical across all servers in a replication hierarchy, the replica will just continue from the appropriate point in the new primary's binlog.

 It is important to understand how this change of primary work. The binlog is an ordered stream of events (or multiple streams, one per replication domain, (see [Use with multi-source replication and other multi-primary setups](#use-with-multi-source-replication-and-other-multi-master-setups)). Events within the stream are always applied in the same order on every replica that replicates it. The MariaDB GTID relies on this ordering, so that it is sufficient to remember just a single point within the stream. Since event order is the same on every server, switching to the point of the same GTID in the binlog of another server will give the same result.

 This translates into some responsibility for the user. The MariaDB GTID replication is fully asynchronous, and fully flexible in how it can be configured. This makes it possible to use it in ways where the assumption that binlog sequence is the same on all servers is violated. In such cases, when changing primary, GTID will still attempt to continue at the point of current GTID in the new binlog.

 The most common way that binlog sequence gets different between servers is when the user/DBA does updates directly on a replica server (and these updates are written into the replica's binlog). This results in events in the replica's binlog that are not present on the primary or any other replicas. This can be avoided by setting the session variable sql\_log\_bin false while doing such updates, so they do not go into the binlog.

 It is normally best to avoid any differences in binlogs between servers. That being said, MariaDB replication is designed for maximum flexibility, and there can be valid reasons for introducing such differences from time to time. It this case, it just needs to be understood that the GTID position is a single point in each binlog stream (one per replication domain), and how this affects the users particular setup.

 Differences can also occur when two primary are active at the same time in a replication hierarchy. This happens when using a multi-primary ring. But it can also occur in a simple primary-replica setup, during switch to a new primary, if changes on the old primary is not allowed to fully replicate to all replica servers before switching primary. Normally, to switch primary, first writes to the old primary should be stopped, then one should wait for all changes to be replicated to the new primary, and only then should writes begin on the new primary. Deliberately using multiple active primary is also supported, this is described in the next section.

 The [GTID strict mode](#gtid_strict_mode) can be used to enforce identical binlogs across servers. When it is enabled, most actions that would cause differences are rejected with an error.

 Use With Multi-Source Replication and Other Multi-Primary Setups
----------------------------------------------------------------

 MariaDB global transaction ID supports having multiple primarys active at the same time. Typically this happens with either multi-source replication or multi-primary ring setups.

 In such setups, each active primary must be configured with its own distinct replication domain ID, [gtid\_domain\_id](#gtid_domain_id). The binlog will then in effect consists of multiple independent streams, one per active primary. Within one replication domain, binlog order is always the same on every server. But two different streams can be interleaved differently in different server binlogs.

 The GTID position of a given replica is then not a single GTID. Rather, it becomes the GTID of the last event group applied for each value of domain ID, in effect the position reached in each binlog stream. When the replica connects to a primary, it can continue from one stream in a different binlog position than another stream. Since order within one stream is consistent across all servers, this is sufficient to always be able to continue replication at the correct point in any new primary server(s).

 Domain IDs are assigned by the DBA, according to the need of the application. The default value of @@GLOBAL.gtid\_domain\_id is 0. This is appropriate for most replication setups, where only a single primary is active at a time. The MariaDB server will never by itself introduce new domain\_id values into the binlog.

 When using multi-source replication, where a single replica connects to multiple primaries at the same time, each such primary should be configured with its own distinct domain ID.

 Similarly, in a multi-primary ring topology, where all primary in the ring are updated by the application concurrently (with some mechanism to avoid conflicts), a distinct domain ID should be configured for each server (In a multi-primary ring where the application is careful to only do updates on one primary at a time, a single domain ID is sufficient).

 Normally, a replica server should not receive direct updates (as this creates binlog differences compared to the primary). Thus it does not matter what value of gtid\_domain\_id is set on a replica, though it may make sense to make it the same as the primary (if not using multi-primary) to make it easy to promote the replica as a new primary. Of course, if a replica is itself an active primary, as in a multi-primary ring topology, the domain ID should be set according to the server's role as active primary.

 Note that domain ID and server ID are distinct concepts. It is possible to use a different domain ID on each server, but this is normally not desirable. It makes the current GTID position (@@global.gtid\_slave\_pos) more complicated to understand and work with, and loses the concept of a single ordered binlog stream across all servers. It is recommended only to configure as many domain IDs as there are primary servers actively being updated by the application at the same time.

 It is not an error in itself to configure domain IDs incorrectly (for example, not configuring them at all). For example, this will be typical in an upgrade scenario where a multi-primary ring using 5.5 is upgraded to 10.0. The ring will continue to work as before even though everything is configured to use the default domain ID 0. It is even possible to use GTID for replication between the servers. However, care must be taken when switching a replica to a different primary. If the binlog order between the old and the new primary differs, then a single GTID position to start replication from in the new primary's binlog may not be sufficient.

 ### Deleting Unused Domains

 `FLUSH BINARY LOGS DELETE_DOMAIN_ID=(list-of-domains)` can be used to discard obsolete GTID domains from the server's binary log state. In order for this to be successful, no event group from the listed GTID domains can be present in existing binary log files. If some still exist, then they must be purged prior to executing this command.

 If the command completes successfully, then it also rotates the binary log.

 The old domains will still appear in [gtid\_io\_pos](../show-replica-status/index). To get rid of these, you can stop the slave and execute on the slave:

 
```
SET gtid_slave_pos="<position with domains removed>"

```

New Syntax For Global Transaction ID
------------------------------------

 ### CHANGE MASTER

 [CHANGE MASTER](../change-master-to/index) has a new option, `master_use_gtid=[current_pos|slave_pos|no]`. When enabled (set to *current\_pos* or *slave\_pos*), the replica will connect to the master using the GTID position. When disabled (set to "no"), the old-style binlog filename/offset position is used to decide where to start replicating when connecting. Unlike in the old-style, when GTID is enabled, the values of the [MASTER\_LOG\_FILE](../change-master-to/index#master_log_file) and [MASTER\_LOG\_POS](../change-master-to/index#master_log_pos) options are not updated per received event in [master\_info\_file](../mysqld-options/index#-master-info-file) file.

 The value of `master_use_gtid` is saved across server restarts (in master.info). The current value can be seen as the field Using\_Gtid in the output of SHOW SLAVE STATUS.

 For a detailed look at the difference between the *current\_pos* and *slave\_pos* options, see [Using global transaction IDs](#using-global-transaction-ids)

 ### START SLAVE UNTIL master\_gtid\_pos=xxx

 When starting replication with [START SLAVE](../start-slave/index), it is possible to request the replica to run only until a specific GTID position is reached. Once that position is reached, the replica will stop.

 The syntax for this is:

  `START SLAVE UNTIL master_gtid_pos = <GTID position>`

 The replica will start replication from the current GTID position, run up to and including the event with the GTID specified, and then stop. Note that this stops both the IO thread and the SQL thread (unlike START SLAVE UNTIL MASTER\_LOG\_FILE/MASTER\_LOG\_POS, which stops only the SQL thread).

 If multiple GTIDs are specified, then they must be with distinct replication domain ID, for example:

  `START SLAVE UNTIL master_gtid_pos = "1-11-100,2-21-50"`

 With multiple domains in the UNTIL condition, each domain runs only up to and including the specified position, so it is possible for different domains to stop at different places in the binlog (each domain will resume from the stopped position when the replica is started the next time).

 Not specifying a replication domain at all in the UNTIL condition means that the domain is stopped immediately, nothing is replicated from that domain. In particular, specifying the empty string will stop the replica immediately.

 When using `START SLAVE UNTIL master_gtid_pos = XXX`, if the UNTIL position is present in the primary's binlog then it is permissible for the start position to be missing on the primary. In this case, replication for the associated domains stop immediately.

 Both replica threads must be already stopped when using UNTIL master\_gtid\_pos, otherwise an error occurs. It is also an error if the replica is not configured to use GTID (`CHANGE MASTER TO master_use_gtid=current_pos|slave_pos`). And both threads must be started at the same time, the `IO_THREAD` or `SQL_THREAD` options can not be used to start only one of them.

 `START SLAVE UNTIL master_gtid_pos=XXX` is particularly useful for promoting a new primary among a set of replicas when the old master goes away and replicas may have reached different positions in the old primary's binlog. The new primary needs to be ahead of all the other replicas to avoid losing events. This can be achieved by picking one server, say S1, and replicating any missing events from each other server S2, S3, ..., Sn:

 
```
    CHANGE MASTER TO master_host="S2";
    START SLAVE UNTIL master_gtid_pos = "<S2 GTID position>";
    ...
    CHANGE MASTER TO master_host="Sn";
    START SLAVE UNTIL master_gtid_pos = "<Sn GTID position>";

```

Once this is completed, S1 will have all events present on any of the servers. It can now be selected as the new primary, and all the other servers set to replicate from it.

 ### BINLOG\_GTID\_POS().

 The [BINLOG\_GTID\_POS()](../binlog_gtid_pos/index) function takes as input an old-style [binary log](../binary-log/index) position in the form of a file name and a file offset. It looks up the position in the current binlog, and returns a string representation of the corresponding GTID position. If the position is not found in the current binlog, NULL is returned.

 ### MASTER\_GTID\_WAIT

 The [MASTER\_GTID\_WAIT](../master_gtid_wait/index) function is useful in replication for controlling primary/replica synchronization, and blocks until the replica has read and applied all updates up to the specified position in the primary log. See [MASTER\_GTID\_WAIT](../master_gtid_wait/index) for details.

 System Variables
----------------

 #### `gtid_slave_pos`

 This system variable contains the GTID of the last transaction applied to the database by the server's [replica threads](../replication-threads/index#threads-on-the-slave) for each replication domain. This system variable's value is automatically updated whenever a [replica thread](../replication-threads/index#threads-on-the-slave) applies an event group. This system variable's value can also be manually changed by users, so that the user can change the GTID position of the [replica threads](../replication-threads/index#threads-on-the-slave).

 When using [multi-source replication](../multi-source-replication/index), the same GTID position is shared by all replica connections. In this case, different primaries should use different replication domains by configuring different [gtid\_domain\_id](#gtid_domain_id) values. If one primary was using a [gtid\_domain\_id](#gtid_domain_id) value of `1`, and if another primary was using a [gtid\_domain\_id](#gtid_domain_id) value of `2`, then any replicas replicating from both primaries would have GTIDs with both [gtid\_domain\_id](#gtid_domain_id) values in `gtid_slave_pos`.

 This system variable's value can be manually changed by executing [SET GLOBAL](../set/index#global-session), but all replica threads to be stopped with [STOP SLAVE](../stop-slave/index) first. For example:

 
```
STOP ALL SLAVES;
SET GLOBAL gtid_slave_pos = "1-10-100,2-20-500";
START ALL SLAVES;

```

This system variable's value can be reset by manually changing its value to the empty string. For example:

 
```
SET GLOBAL gtid_slave_pos = '';

```

The GTID position defined by `gtid_slave_pos` can be used as a replica's starting replication position by setting [MASTER\_USE\_GTID=slave\_pos](../change-master-to/index#master_use_gtid) when the replica is configured with the [CHANGE MASTER TO](../change-master-to/index) statement. As an alternative, the [gtid\_current\_pos](#gtid_current_pos) system variable can also be used as a replica's starting replication position.

 If a user sets the value of the `gtid_slave_pos` system variable, and [gtid\_binlog\_pos](#gtid_binlog_pos) contains later GTIDs for certain replication domains, then [gtid\_current\_pos](#gtid_current_pos) will contain the GTIDs from [gtid\_binlog\_pos](#gtid_binlog_pos) for those replication domains. To protect users in this scenario, if a user sets the `gtid_slave_pos` system variable to a GTID position that is behind the GTID position in [gtid\_binlog\_pos](#gtid_binlog_pos), then the server will give the user a warning.

 This can help protect the user when the replica is configured to use [gtid\_current\_pos](#gtid_current_pos) as its replication position. This can also help protect the user when a server has been rolled back to restart replication from an earlier point in time, but the user has forgotten to reset [gtid\_binlog\_pos](#gtid_binlog_pos) with [RESET MASTER](../reset-master/index).

 The [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) system table is used to store the contents of global.gtid\_slave\_pos and preserve it over restarts.

 * **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default:** Null

 

---

 #### `gtid_binlog_pos`

 This variable is the GTID of the last event group written to the binary log, for each replication domain.

 Note that when the binlog is empty (such as on a fresh install or after [RESET MASTER](../reset-master/index)), there are no event groups written in any replication domain, so in this case the value of `gtid_binlog_pos` will be the empty string.

 The value is read-only, but it is updated whenever a DML or DDL statement is written to the binary log. The value can be reset by executing [RESET MASTER](../reset-master/index), which will also delete all binary logs. However, note that [RESET MASTER](../reset-master/index) does not also reset [gtid\_slave\_pos](#gtid_slave_pos). Since [gtid\_current\_pos](#gtid_current_pos) is the union of [gtid\_slave\_pos](#gtid_slave_pos) and `gtid_binlog_pos`, that means that new GTIDs added to `gtid_binlog_pos` can lag behind those in [gtid\_current\_pos](#gtid_current_pos) if [gtid\_slave\_pos](#gtid_slave_pos) contains GTIDs in the same domain with higher sequence numbers. If you want to reset [gtid\_current\_pos](#gtid_current_pos) for a specific GTID domain in cases like this, then you will also have to change [gtid\_slave\_pos](#gtid_slave_pos) in addition to executing [RESET MASTER](../reset-master/index). See [gtid\_slave\_pos](#gtid_slave_pos) for notes on how to change its value.

 * **Commandline:** None
* **Scope:** Global
* **Dynamic:** Read-only
* **Data Type:** `string`
* **Default:** Null

 

---

 #### `gtid_binlog_state`

 The variable gtid\_binlog\_state holds the internal state of the binlog. The state consists of the last GTID ever logged to the binary log for every combination of domain\_id and server\_id. This information is used by the primary to determine whether a given GTID has been logged to the binlog in the past, even if it has later been deleted due to binlog purge. For each domain\_id, the last entry in @@gtid\_binlog\_state is the last GTID logged into binlog, ie. this is the value that appears in @@gtid\_binlog\_pos.

 Normally this internal state is not needed by users, as @@gtid\_binlog\_pos is more useful in most cases. The main usage of @@gtid\_binlog\_state is to restore the state of the binlog after RESET MASTER (or equivalently if the binlog files are lost). If the value of @@gtid\_binlog\_state is saved before RESET MASTER and restored afterwards, the primary will retain information about past history, same as if PURGE BINARY LOGS had been used (of course the actual events in the binary logs are still deleted).

 Note that to set the value of @@gtid\_binlog\_state, the binary log must be empty, that is it must not contain any GTID events and the previous value of @@gtid\_binlog\_state must be the empty string. If not, then RESET MASTER must be used first to erase the binary log first.

 The value of @@gtid\_binlog\_state is preserved by the server across restarts by writing a file MASTER-BIN.state, where MASTER-BIN is the base name of the binlog set with the --log-bin option. This file is written at server shutdown, and re-read at next server start. (In case of a server crash, the data in the MASTER-BIN.state is not correct, and the server instead recovers the correct value during binlog crash recovery by scanning the binlog files and recording each GTID found).

 For completeness, note that setting @@gtid\_binlog\_state internally executes a RESET MASTER. This is normally not noticeable as it can only be changed when the binlog is empty of GTID events. However, if executed e.g. immediately after upgrading to MariaDB 10, it is possible that the binlog is non-empty but without any GTID events, in which case all such events will be deleted, just as if RESET MASTER had been run.

 * **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default:** Null

 

---

 #### `gtid_current_pos`

 This system variable contains the GTID of the last transaction applied to the database for each replication domain.

 The value of this system variable is constructed from the values of the [gtid\_binlog\_pos](#gtid_binlog_pos) and [gtid\_slave\_pos](#gtid_slave_pos) system variables. It gets GTIDs of transactions executed locally from the value of the [gtid\_binlog\_pos](#gtid_binlog_pos) system variable. It gets GTIDs of replicated transactions from the value of the [gtid\_slave\_pos](#gtid_slave_pos) system variable.

 For each replication domain, if the [server\_id](../replication-and-binary-log-system-variables/index#server_id) of the corresponding GTID in [gtid\_binlog\_pos](#gtid_binlog_pos) is equal to the servers own [server\_id](../replication-and-binary-log-system-variables/index#server_id), *and* the sequence number is higher than the corresponding GTID in [gtid\_slave\_pos](#gtid_slave_pos), then the GTID from [gtid\_binlog\_pos](#gtid_binlog_pos) will be used. Otherwise the GTID from [gtid\_slave\_pos](#gtid_slave_pos) will be used for that domain.

 GTIDs from [gtid\_binlog\_pos](#gtid_binlog_pos) in which the [server\_id](../replication-and-binary-log-system-variables/index#server_id) of the GTID is **not** equal to the server's own [server\_id](../replication-and-binary-log-system-variables/index#server_id) are effectively ignored. If [gtid\_binlog\_pos](#gtid_binlog_pos) contains a GTID for a given replication domain, but the [server\_id](../replication-and-binary-log-system-variables/index#server_id) of the GTID is **not** equal to the server's own [server\_id](../replication-and-binary-log-system-variables/index#server_id), and [gtid\_slave\_pos](#gtid_slave_pos) does **not** contain a GTID for that given replication domain, then `gtid_current_pos` will **not** contain any GTID for that replication domain.

 Thus, `gtid_current_pos` contains the most recent GTID executed on the server, whether this was done as a primary or as a replica.

 The GTID position defined by `gtid_current_pos` can be used as a replica's starting replication position by setting [MASTER\_USE\_GTID=current\_pos](../change-master-to/index#master_use_gtid) when the replica is configured with the [CHANGE MASTER TO](../change-master-to/index) statement. As an alternative, the [gtid\_slave\_pos](#gtid_slave_pos) system variable can also be used as a replica's starting replication position.

 The value of `gtid_current_pos` is read-only, but it is updated whenever a transaction is written to the binary log and/or replicated by a replica thread, and that transaction's GTID is considered *newer* than the current GTID for that domain. See above for the rules on how to determine if a GTID would be considered *newer*.

 If you need to reset the value, see the notes on resetting [gtid\_slave\_pos](#gtid_slave_pos) and [gtid\_binlog\_pos](#gtid_binlog_pos), since `gtid_current_pos` is formed from the values of those variables.

 * **Commandline:** None
* **Scope:** Global
* **Dynamic:** Read-only
* **Data Type:** `string`
* **Default:** Null

 

---

 #### `gtid_strict_mode`

 The GTID strict mode is an optional setting that can be used to help the DBA enforce a strict discipline about keeping binlogs identical across multiple servers replicating using global transaction ID.

 When GTID strict mode is enabled, some additional errors are enabled for situations that could otherwise cause differences between binlogs on different servers in a replication hierarchy:

 1. If a replica server tries to replicate a GTID with a sequence number lower than what is already in the binlog for that replication domain, the SQL thread stops with an error (this indicates an extra transaction in the replica binlog not present on the primary).
2. Similarly, an attempt to manually binlog a GTID with a lower sequence number (by setting `@@SESSION.gtid_seq_no`) is rejected with an error.
3. If the replica tries to connect starting at a GTID that is missing in the primary's binlog, this is an error in GTID strict mode even if a GTID exists with a higher sequence number (this indicates a GTID on the replica missing on the primary). Note that this error is controlled by the setting of GTID strict mode on the connecting replica server.

 GTID mode is off by default; this is needed to preserve backwards compatibility with existing replication setups (older versions of the server did not enforce any strict mode for binlog order). Global transaction ID is designed to work correctly even when strict mode is not enabled. However, with strict mode enforced, the semantics is simpler and thus easier to understand, because binlog order is always identical across servers and sequence numbers are always strictly increasing within each replication domain. This can also make automated scripting of large replication setups easier to implement correctly.

 When GTID strict mode is enabled, the replica will stop with an error when a problem is encountered. This allows the DBA to become aware of the problem and take corrective actions to avoid similar issues in the future. One way to recover from such an error is to temporarily disable GTID strict mode on the offending replica, to be able to replicate past the problem point (perhaps using `START SLAVE UNTIL master_gtid_pos=XXX`).

 * **Commandline:** `--gtid-strict-mode[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default:** `Off`

 

---

 #### `gtid_domain_id`

 * **Description:** This variable is used to decide which replication domain new GTIDs are logged in for a primary server. See [Use with multi-source replication and other multi-primary setups](#use-with-multi-source-replication-and-other-multi-primary-setups) for details. This variable can also be set on the session level by a user with the SUPER privilege. This is used by [mariadb-binlog](../mariadb-binlog/index) to preserve the domain ID of GTID events.
* **Commandline:** `--gtid-domain-id=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric (32-bit unsigned integer)`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`

 

---

 #### `last_gtid`

 * **Description:** Holds the GTID that was assigned to the last transaction, or statement that was logged to the [binary log](../binary-log/index). If the binary log is disabled, or if no transaction or statement was executed in the session yet, then the value is an empty string.
* **Scope:** Session
* **Dynamic:** Read-only
* **Data Type:** `string`

 

---

 #### `server_id`

 * **Description:** Server\_id can be set on the session level to change which server\_id value is logged in binlog events (both GTID and other events). This is used by mariadb-binlog to preserve the server ID of GTID events.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric (32-bit unsigned integer)

 

---

 #### `gtid_seq_no`

 * **Description:** gtid\_seq\_no can be set on the session level to change which sequence number is logged in the following GTID event. The variable, along with [@@gtid\_domain\_id](#gtid_domain_id) and [@@server\_id](#server_id), is typically used by [mariadb-binlog](../mariadb-binlog/index) to set up the gtid value of the transaction being decoded into the output.
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `numeric (64-bit unsigned integer)`
* **Default:** Null

 

---

 #### `gtid_ignore_duplicates`

 * **Description:** When set, different primary 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. With gtid\_ignore\_duplicates=OFF, a duplicate event based on domain id and sequence number, will be executed.
* **Commandline:** `--gtid-ignore-duplicates=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default:** `OFF`

 

---

 #### `gtid_pos_auto_engines`

 This variable is used to enable multiple versions of the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table, one for each transactional storage engine in use. This can improve replication performance if a server is using multiple different storage engines in different transactions.

 The value is a list of engine names, separated by commas (','). Replication of transactions using these engines will automatically create new versions of the mysql.gtid\_slave\_pos table in the same engine and use that for future transactions (table creation takes place in a background thread). This avoids introducing a cross-engine transaction to update the GTID position. Only transactional storage engines are supported for gtid\_pos\_auto\_engines (this currently means [InnoDB](../innodb/index), [TokuDB](../tokudb/index), or [MyRocks](../myrocks/index)).

 The variable can be changed dynamically, but replica SQL threads should be stopped when changing it, and it will take effect when the replicas are running again.

 When setting the variable on the command line or in a configuration file, it is possible to specify engines that are not enabled in the server. The server will then still start if, for example, that engine is no longer used. Attempting to set a non-enabled engine dynamically in a running server (with SET GLOBAL gtid\_pos\_auto\_engines) will still result in an error.

 Removing a storage engine from the variable will have no effect once the new tables have been created - as long as these tables are detected, they will be used.

 * **Commandline:** `--gtid-pos-auto-engines=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string` (comma-separated list of engine names)
* **Default:** empty

 

---

 #### `gtid_cleanup_batch_size`

 * **Description:** Normally does not need tuning. How many old rows must accumulate in the [mysql.gtid\_slave\_pos table](../mysqlgtid_slave_pos-table/index) 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](#gtid_pos_auto_engines), or to reduce CPU overhead if using a huge number of different [gtid\_domain\_ids](#gtid_domain_id). Can be decreased to reduce number of old rows in the table.
* **Commandline:** `--gtid-cleanup-batch-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default:** `64`
* **Range:** `0` to `2147483647`
* **Introduced:** [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)

 

---

 See also
--------

 * [FLUSH](../flush/index) binary logs

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/gtid/>

Parallel Replication
====================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Some writes, [replicated](../standard-replication/index) from the primary can be executed in parallel (simultaneously) on the replica. Note that for parallel replication to work, both the primary and replica need to be [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) or later. 

 Parallel Replication Overview
-----------------------------

 MariaDB replication in general takes place in three parts:

 * Replication events are read from the primary by the IO thread and queued in the [relay log](../relay-log/index).
* Replication events are fetched one at a time by the SQL thread from the relay log
* Each event is applied on the replica to replicate all changes done on the primary.

 Before MariaDB 10, the third step was also performed by the SQL thread; this meant that only one event could execute at a time, and replication was essentially single-threaded. Since MariaDB 10, the third step can optionally be performed by a pool of separate replication worker threads, and thereby potentially increase replication performance by applying multiple events in parallel.

 How to Enable Parallel Replica
------------------------------

 To enable, specify [slave-parallel-threads=#](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) in your [my.cnf](../mysqld-startup-options/index) file as an argument to mysql. Parallel replication can in addition be disabled on a per-multi-source connection by setting [@@connection\_name.slave-parallel-mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) to "none".

 The value (#) of slave\_parallel\_threads specifies how many threads will be created in a pool of worker threads used to apply events in parallel for \*all\* your replicas (this includes [multi-source replication](../multi-source-replication/index)). If the value is zero, then no worker threads are created, and old-style replication is used where events are applied inside the SQL thread. Usually the value, if non-zero, should be at least two times the number of multi-source primary connections used. It makes little sense to use only a single worker thread for one connection; this will incur some overhead in inter-thread communication between the SQL thread and the worker thread, but with just a single worker thread events can not be applied in parallel anyway.

 `slave-parallel-threads=#` is a dynamic variable that can be changed without restarting mysqld. All replicas connections must however be stopped when changing the value.

 Configuring the Replica Parallel Mode
-------------------------------------

 Parallel replication can be in-order or out-of-order:

 * In-order executes transactions in parallel, but orders the commit step of the transactions to happen in the exact same order as on the primary. Transactions are only executed in parallel to the extent that this can be automatically verified to be possible without any conflicts. This means that the use of parallelism is completely transparent to the application.
* Out-of-order can execute and commit transactions in different order on the replica than originally on the primary. This means that the application must be tolerant to seeing updates occur in different order. The application is also responsible for ensuring that there are no conflicts between transactions that are replicated out-of-order. Out-of-order is only used in GTID mode and only when explicitly enabled by the application, using the replication domain that is part of the GTID.

 ### In-Order Parallel Replication

 #### Optimistic Mode of In-Order Parallel Replication

 Optimistic mode of in-order parallel replication provides a lot of opportunities for parallel apply on the replica while still preserving exact transaction semantics from the point of view of applications. It is the default mode from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/).

 Optimistic mode of in-order parallel replication can be configured by setting the [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) system variable to `optimistic` on the replica.

 Any transactional DML (INSERT/UPDATE/DELETE) is allowed to run in parallel, up to the limit of [@@slave\_domain\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads). This may cause conflicts on the replica, eg. if two transactions try to modify the same row. Any such conflict is detected, and the latter of the two transactions is rolled back, allowing the former to proceed. The latter transaction is then re-tried once the former has completed.

 The term "optimistic" is used for this mode, because the server optimistically assumes that few conflicts will occur, and that the extra work spent rolling back and retrying conflicting transactions is justified from the gain from running most transactions in parallel.

 There are a few heuristics to try to avoid needless conflicts. If a transaction executed a row lock wait on the primary, it will not be run in parallel on the replica. Transactions can also be marked explicitly as potentially conflicting on the primary, by setting the variable [@@skip\_parallel\_replication](../replication-and-binary-log-server-system-variables/index#skip_parallel_replication). More such heuristics may be added in later MariaDB versions. There is a further [--slave-parallel-mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) called "aggressive", where these heuristics are disabled, allowing even more transactions to be applied in parallel.

 Non-transactional DML and DDL is not safe to optimistically apply in parallel, as it cannot be rolled back in case of conflicts. Thus, in optimistic mode, non-transactional (such as MyISAM) updates are not applied in parallel with earlier events (it is however possible to apply a MyISAM update in parallel with a later InnoDB update). DDL statements are not applied in parallel with any other transactions, earlier or later.

 The different kind of transactions can be identified in the output of [mariadb-binlog](../mariadb-binlog/index). For example:

 
```
#150324 13:06:26 server id 1  end_log_pos 6881 	GTID 0-1-42 ddl
...
#150324 13:06:26 server id 1  end_log_pos 7816 	GTID 0-1-47
...
#150324 13:06:26 server id 1  end_log_pos 8177  GTID 0-1-49 trans
/*!100101 SET @@session.skip_parallel_replication=1*//*!*/;
...
#150324 13:06:26 server id 1  end_log_pos 9836 	GTID 0-1-59 trans waited

```

GTID 0-1-42 is marked as being DDL. GTID 0-1-47 is marked as being non-transactional DML, while GTID 0-1-49 is transactional DML (seen on the "trans" keyword). GTID 0-1-49 was additionally run with [@@skip\_parallel\_replication](../replication-and-binary-log-server-system-variables/index#skip_parallel_replication) set on the primary. GTID 0-1-59 is transactional DML that had a row lock wait when run on the primary (the "waited" keyword).

 #### Aggressive Mode of In-Order Parallel Replication

 Aggressive mode of in-order parallel replication is very similar to optimistic mode. The main difference is that the replica does not consider whether transactions conflicted on the primary when deciding whether to apply the transactions in parallel.

 Aggressive mode of in-order parallel replication can be configured by setting the [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) system variable to `aggressive` on the replica.

 #### Conservative Mode of In-Order Parallel Replication

 Conservative mode of in-order parallel replication uses the [group commit](../group-commit-for-the-binary-log/index) on the primary to discover potential for parallel apply of events on the replica. If two transactions commit together in a [group commit](../group-commit-for-the-binary-log/index) on the primary, they are written into the binlog with the same commit id. Such events are certain to not conflict with each other, and they can be scheduled by the parallel replication to run in different worker threads.

 Conservative mode of in-order parallel replication is the default mode until [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), but it can also be configured by setting the [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) system variable to `conservative` on the replica.

 Two transactions that were committed separately on the primary can potentially conflict (eg. modify the same row of a table). Thus, the worker that applies the second transaction will not start immediately, but wait until the first transaction begins the commit step; at this point it is safe to start the second transaction, as it can no longer disrupt the execution of the first one.

 Here is example output from [mariadb-binlog](../mariadb-binlog/index) that shows how GTID events are marked with commit id. The GTID 0-1-47 has no commit id, and can not run in parallel. The GTIDs 0-1-48 and 0-1-49 have the same commit id 630, and can thus replicate in parallel with one another on a replica:

 
```
#150324 12:54:24 server id 1  end_log_pos 20052 	GTID 0-1-47 trans
...
#150324 12:54:24 server id 1  end_log_pos 20212 	GTID 0-1-48 cid=630 trans
...
#150324 12:54:24 server id 1  end_log_pos 20372 	GTID 0-1-49 cid=630 trans

```

In either case, when the two transactions reach the point where the low-level commit happens and commit order is determined, the two commits are sequenced to happen in the same order as on the primary, so that operation is transparent to applications.

 The opportunities for parallel replication on replicas can be highly increased if more transactions are committed in a [group commit](../group-commit-for-the-binary-log/index) on the primary. This can be tuned using the [binlog\_commit\_wait\_count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count) and [binlog\_commit\_wait\_usec](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_usec) variables. If for example the application can tolerate up to 50 milliseconds extra delay for transactions on the primary, one can set `binlog_commit_wait_usec=50000` and `binlog_commit_wait_count=20` to get up to 20 transactions at a time available for replication in parallel. Care must however be taken to not set `binlog_commit_wait_usec` too high, as this could cause significant slowdown for applications that run a lot of small transactions serially one after the other.

 Note that even if there is no parallelism available from the primary [group commit](../group-commit-for-the-binary-log/index), there is still an opportunity for speedup from in-order parallel replication, since the actual commit steps of different transactions can run in parallel. This can be particularly effective on a replica with binlog enabled ([log\_slave\_updates=1](../replication-and-binary-log-server-system-variables/index#log_slave_updates)), and more so if replica is configured to be crash-safe ([sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) and [innodb\_flush\_log\_at\_trx\_commit=1](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit)), as this makes [group commit](../group-commit-for-the-binary-log/index) possible on the replica.

 #### Minimal Mode of In-Order Parallel Replication

 Minimal mode of in-order parallel replication *only*allows the commit step of transactions to be applied in parallel; all other steps are applied serially.

 Minimal mode of in-order parallel replication can be configured by setting the [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) system variable to `minimal` on the replica.

 ### Out-of-Order Parallel Replication

 Out-of-order parallel replication happens (only) when using GTID mode, when GTIDs with different replication domains are used. The replication domain is set by the DBA/application using the variable `gtid_domain_id`.

 Two transactions having GTIDs with different domain\_id are scheduled to different worker threads by parallel replication, and are allowed to execute completely independently from each other. It is the responsibility of the application to only set different domain\_ids for transactions that are truly independent, and are guaranteed to not conflict with each other. The application must also be able to work correctly even though the transactions with different domain\_id are seen as committing in different order between the replica and the primary, and between different replicas.

 Out-of-order parallel replication can potentially give more performance gain than in-order parallel replication, since the application can explicitly give more opportunities for running transactions in parallel than what the server can determine on its own automatically.

 One simple but effective usage is to run long-running statements, such as ALTER TABLE, in a separate replication domain. This allows replication of other transactions to proceed uninterrupted:

 
```
SET SESSION gtid_domain_id=1
ALTER TABLE t ADD INDEX myidx(b)
SET SESSION gtid_domain_id=0
```

Normally, a long-running ALTER TABLE or other query will stall all following transactions, causing the replica to become behind the primary as least as long time as it takes to run the long-running query. By using out-of-order parallel replication by setting the replication domain id, this can be avoided. The DBA/application must ensure that no conflicting transactions will be replicated while the ALTER TABLE runs.

 Another common opportunity for out-of-order parallel replication comes in connection with multi-source replication. Suppose we have two different primaries M1 and M2, and we are using multi-source replication to have S1 as a replica of both M1 and M2. S1 will apply events received from M1 in parallel with events received from M2. If we now have a third-level replica S2 that replicates from S1 as primary, we want S2 to also be able to apply events that originated on M1 in parallel with events that originated on M2. This can be achieved with out-of-order parallel replication, by setting `gtid_domain_id` different on M1 and M2.

 Note that there are no special restrictions on what operations can be replicated in parallel using out-of-order; such operations can be on the same database/schema or even on the same table. The only restriction is that the operations must not conflict, that is they must be able to be applied in any order and still end up with the same result.

 When using out-of-order parallel replication, the current replica position in the primary's binlog becomes multi-dimensional - each replication domain can have reached a different point in the primary binlog at any one time. The current position can be seen from the variable `gtid_slave_pos`. When the replica is stopped, restarted, or switched to replicate from a different primary using CHANGE MASTER, MariaDB automatically handles restarting each replication domain at the appropriate point in the binlog.

 Out-of-order parallel replication is disabled when [--slave-parallel-mode=minimal](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) (or none).

 Checking Worker Thread Status in SHOW PROCESSLIST
-------------------------------------------------

 The worker threads will be listed as "system user" in [SHOW PROCESSLIST](../show-processlist/index). Their state will show the query they are currently working on, or it can show one of these:

 * "Waiting for work from main SQL threads". This means that the worker thread is idle, no work is available for it at the moment.
* "Waiting for prior transaction to start commit before starting next transaction". This means that the previous batch of transactions that committed together on the primary primary has to complete first. This worker thread is waiting for that to happen before it can start working on the following batch.
* "Waiting for prior transaction to commit". This means that the transaction has been executed by the worker thread. In order to ensure in-order commit, the worker thread is waiting to commit until the previous transaction is ready to commit before it.

 Expected Performance Gain
-------------------------

 Here is an article showing up to ten times improvement when using parallel replication: <http://kristiannielsen.livejournal.com/18435.html>.

 Configuring the Maximum Size of the Parallel Replica Queue
----------------------------------------------------------

 The [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) system variable can be used to configure the maximum size of the parallel replica queue. This system variable is only meaningful when parallel replication is configured (i.e. when [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) > `0`).

 When parallel replication is used, the [SQL thread](../replication-threads/index#slave-sql-thread) will read ahead in the relay logs, queueing events in memory while looking for opportunities for executing events in parallel. The [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) system variable sets a limit for how much memory it will use for this.

 The configured value of the [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) system variable is actually allocated for each [worker thread](../replication-threads/index#worker-threads), so the total allocation is actually equivalent to the following:

 [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) \* [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads)

 If this value is set too high, and the replica is far (eg. gigabytes of binlog) behind the primary, then the [SQL thread](../replication-threads/index#slave-sql-thread) can quickly read all of that and fill up memory with huge amounts of binlog events faster than the [worker threads](../replication-threads/index#worker-threads) can consume them.

 On the other hand, if set too low, the [SQL thread](../replication-threads/index#slave-sql-thread) might not have sufficient space for queuing enough events to keep the worker threads busy, which could reduce performance. In this case, the [SQL thread](../replication-threads/index#slave-sql-thread) will have the [thread state](../thread-states/index) that states `Waiting for room in worker thread event queue`. For example:

 
```
+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+
| Id | User        | Host      | db   | Command | Time   | State                                         | Info             | Progress |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+
|  3 | system user |           | NULL | Connect |    139 | closing tables                                | NULL             |    0.000 |
|  4 | system user |           | NULL | Connect |    139 | Waiting for work from SQL thread              | NULL             |    0.000 |
|  6 | system user |           | NULL | Connect | 264274 | Waiting for master to send event              | NULL             |    0.000 |
| 10 | root        | localhost | NULL | Sleep   |     43 |                                               | NULL             |    0.000 |
| 21 | system user |           | NULL | Connect |     45 | Waiting for room in worker thread event queue | NULL             |    0.000 |
| 54 | root        | localhost | NULL | Query   |      0 | init                                          | SHOW PROCESSLIST |    0.000 |
+----+-------------+-----------+------+---------+--------+-----------------------------------------------+------------------+----------+

```

The [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) system variable does not define a hard limit, since the [binary log](../binary-log/index) events that are currently executing always need to be held in-memory. This means that at least two events per [worker thread](../replication-threads/index#worker-threads) can always be queued in-memory, regardless of the value of [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads).

 Usually, the [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) system variable should be set large enough that the [SQL thread](../replication-threads/index#slave-sql-thread) is able to read far enough ahead in the [binary log](../binary-log/index) to exploit all possible parallelism. In normal operation, the replica will hopefully not be too far behind, so there will not be a need to queue much data in-memory. The [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) system variable could be set fairly high (eg. a few hundred kilobytes) to not limit throughtput. It should just be set low enough that total allocation of the parallel replica queue will not cause the server to run out of memory.

 Configuration Variable slave\_domain\_parallel\_threads
-------------------------------------------------------

 The pool of replication worker threads is shared among all multi-source primary connections, and among all replication domains that can replicate in parallel using out-of-order.

 If one primary connection or replication domain is currently processing a long-running query, it is possible that it will allocate all the worker threads in the pool, only to have them wait for the long-running query to complete, stalling any other primary connection or replication domain, which will have to wait for a worker thread to become free.

 This can be avoided by setting [slave\_domain\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads) to a number that is lower than `slave_parallel_threads`. When set different from zero, each replication domain in one primary connection can reserve at most that many worker threads at any one time, leaving the rest (up to the value of [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads)) free for other primary connections or replication domains to use in parallel.

 The `slave_domain_parallel_threads` variable is dynamic and can be changed without restarting the server; all replicas must be stopped while changing it, though.

 Implementation Details
----------------------

 The implementation is described in [MDEV-4506](https://jira.mariadb.org/browse/MDEV-4506).

 See Also
--------

 * [Better Parallel Replication for MariaDB and MySQL](https://mariadb.com/blog/better-parallel-replication-mariadb-and-mysql) (MariaDB.com blog)
* [Evaluating MariaDB & MySQL Parallel Replication Part 2: Slave Group Commit](https://mariadb.com/blog/evaluating-mariadb-mysql-parallel-replication-part-2-slave-group-commit) (MariaDB.com blog)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/parallel-replication/>

Replication and Binary Log System Variables
===========================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   This page lists system variables that are related to [binary logging](../binary-log/index) and [replication](../replication/index).

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them, as well as [System variables for global transaction ID](../gtid/index#system-variables-for-global-transaction-id).

 Also see [mysqld replication options](../mysqld-options/index#replication-and-binary-logging-options) for related options that are not system variables (such as [binlog\_do\_db](../mysqld-options/index#-binlog-do-db) and [binlog\_ignore\_db](../mysqld-options/index#-binlog-ignore-db)).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `auto_increment_increment`

 * **Description:** The increment for all [AUTO\_INCREMENT](../auto_increment/index) values on the server, by default `1`. Intended for use in primary-to-primary [replication](../replication/index).
* **Commandline:** `--auto-increment-increment[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `65535`

 

---

 #### `auto_increment_offset`

 * **Description:** The offset for all [AUTO\_INCREMENT](../auto_increment/index) values on the server, by default `1`. Intended for use in primary-to-primary [replication](../replication/index). Should be smaller than `auto_increment_increment`, except when both variables are 1 (default setup).
* **Commandline:** `--auto-increment-offset[=#]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `65535`

 

---

 #### `binlog_alter_two_phase`

 * **Description:** When set, split ALTER at binary logging into two statements: START ALTER and COMMIT/ROLLBACK ALTER. The ON setting is recommended for long-running ALTER-table so it could start on replica before its actual execution on primary.
* **Commandline:** `--binlog-alter-two-phase[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/)

 

---

 #### `binlog_annotate_row_events`

 * **Description:** This option tells the primary to write [annotate\_rows\_events](../annotate_rows_log_event/index) to the binary log.
* **Commandline:** `--binlog-annotate-row-events[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:**
	+ `ON` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `OFF` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))

 #### `binlog_do_db`

 * **Description:** This option allows you to configure a [replication primary](../replication/index) to write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.
	+ This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ Until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only available as an option, not a system variable. This option can **not** be set dynamically.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--binlog-do-db=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** NULL
* **Introduced:** [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 

---

 #### `binlog_cache_size`

 * **Description:** If the [binary log](../binary-log/index) is active, this variable determines the size in bytes, per-connection, of the cache holding a record of binary log changes during a transaction. A separate variable, [binlog\_stmt\_cache\_size](#binlog_stmt_cache_size), sets the upper limit for the statement cache. The [binlog\_cache\_disk\_use](../server-status-variables/index#binlog_cache_disk_use) and [binlog\_cache\_use](../server-status-variables/index#binlog_cache_use) [server status variables](../server-status-variables/index) will indicate whether this variable needs to be increased (you want a low ratio of binlog\_cache\_disk\_use to binlog\_cache\_use).
* **Commandline:** `--binlog-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32768`
* **Range - 32 bit:** `4096` to `4294967295`
* **Range - 64 bit:** `4096` to `18446744073709547520`

 

---

 #### `binlog_checksum`

 * **Description:** Specifies the type of BINLOG\_CHECKSUM\_ALG for log events in the [binary log](../binary-log/index).
* **Commandline:** 
	+ `--binlog-checksum=name`
	+ `--binlog-checksum=[0|1]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:**
	+ `CRC32` (>= [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/))
	+ `NONE` (<= [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/))
* **Valid Values:** `NONE` (`0`), `CRC32` (`1`)

 

---

 #### `binlog_commit_wait_count`

 * **Description:** Configures the behavior of [group commit for the binary log](../group-commit-for-the-binary-log/index), which can help increase transaction throughput and is used to enable [conservative mode of in-order parallel replication](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication). With [group commit for the binary log](../group-commit-for-the-binary-log/index), the server can delay flushing a committed transaction into [binary log](../binary-log/index) until the given number of transactions are ready to be flushed as a group. The delay will however not be longer than the value set by [binlog\_commit\_wait\_usec](#binlog_commit_wait_usec). The default value of 0 means that no delay is introduced. Setting this value can reduce I/O on the binary log and give an increased opportunity for parallel apply on the replica when [conservative mode of in-order parallel replication](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication) is enabled, but too high a value will decrease the transaction throughput. By monitoring the status variable [binlog\_group\_commit\_trigger\_count](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_count) (>=[MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/)) it is possible to see how often this is occurring.
* Starting with [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) and [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/): If the server detects that one of the committing transactions T1 holds an [InnoDB](../xtradb-and-innodb/index) row lock that another transaction T2 is waiting for, then the commit will complete immediately without further delay. This helps avoid losing throughput when many transactions need conflicting locks. This often makes it safe to use this option without losing throughput on a replica with [conservative mode of in-order parallel replication](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication), provided the value of [slave\_parallel\_threads](#slave_parallel_threads) is sufficiently high.
* **Commandline:** `--binlog-commit-wait-count=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `binlog_commit_wait_usec`

 * **Description:** Configures the behavior of [group commit for the binary log](../group-commit-for-the-binary-log/index), which can help increase transaction throughput and is used to enable [conservative mode of in-order parallel replication](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication). With [group commit for the binary log](../group-commit-for-the-binary-log/index), the server can delay flushing a committed transaction into [binary log](../binary-log/index) until the transaction has waited the configured number of microseconds. By monitoring the status variable [binlog\_group\_commit\_trigger\_timeout](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_timeout) (>=[MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/)) it is possible to see how often group commits are made due to `binlog_commit_wait_usec`. As soon as the number of pending commits reaches [binlog\_commit\_wait\_count](#binlog_commit_wait_count), the wait will be terminated, though. Thus, this setting only takes effect if `binlog_commit_wait_count` is non-zero.
* **Commandline:** `--binlog-commit-wait-usec#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100000`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `binlog_direct_non_transactional_updates`

 * **Description:** [Replication](../replication/index) inconsistencies can occur due when a transaction updates both transactional and non-transactional tables and the updates to the non-transactional tables are visible before being written to the binary log. This is because, to preserve causality, the non-transactional statements are written to the transaction cache, which is only flushed on commit. Setting binlog\_direct\_non\_transactional\_updates to 1 (0 is default) will cause non-transactional tables to be written straight to the binary log, rather than the transaction cache. This setting has no effect when row-based binary logging is used, as it requires statement-based logging. See [binlog\_format](#binlog_format). Use with care, and only in situations where no dependencies exist between the non-transactional and transactional tables, for example INSERTing into a non-transactional table based upon the results of a SELECT from a transactional table.
* **Commandline:** `--binlog-direct-non-transactional-updates[=value]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF (0)`

 

---

 #### `binlog_expire_logs_seconds`

 * **Description:** If non-zero, binary logs will be purged after `binlog_expire_logs_seconds` seconds. Possible purges happen at startup and at binary log rotation. From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), `binlog_expire_logs_seconds` and [expire\_logs\_days](#expire_logs_days) are forms of aliases, such that changes to one automatically reflect in the other.
* **Commandline:** `--binlog-expire-logs-seconds=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)

 

---

 #### `binlog_file_cache_size`

 * **Description:** Size of in-memory cache that is allocated when reading [binary log](../binary-log/index) and [relay log](../relay-log/index) files.
* **Commandline:** `--binlog-file-cache-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `16384`
* **Range:** `8192` to `18446744073709551615`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `binlog_format`

 * **Description:** Determines whether [replication](../replication/index) is row-based, statement-based or mixed. Statement-based was the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/). Be careful of changing the binary log format when a replication environment is already running. See [Binary Log Formats](../binary-log-formats/index). Starting from [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) a replica will apply any events it gets from the primary, regardless of the binary log format. `binlog_format` only applies to normal (not replicated) updates.
* **Commandline:** `--binlog-format=format`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:**
	+ `MIXED` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `STATEMENT` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))
* **Valid Values:** `ROW`, `STATEMENT` or `MIXED`

 

---

 #### `binlog_ignore_db`

 * **Description:** This option allows you to configure a [replication primary](../replication/index) to **not** write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.
	+ This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ Until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only available as an option, not a system variable. This option can **not** be set dynamically.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--binlog-ignore-db=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** NULL
* **Introduced:** [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 

---

 #### `binlog_optimize_thread_scheduling`

 * **Description:** 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 another, and it should not normally be necessary to change it.
* **Commandline:** `--binlog-optimize-thread-scheduling` or `--skip-binlog-optimize-thread-scheduling`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `binlog_row_event_max_size`

 * **Description:** The maximum size of a row-based [binary log](../binary-log/index) event in bytes. Rows will be grouped into events smaller than this size if possible. The value has to be a multiple of 256. Until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only available as an option, not a system variable.
* **Commandline:** `--binlog-row-event-max-size=val`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8192`
* **Range:** `256` to `4294967040` (in multiples of 256)
* **Introduced:** [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 

---

 #### `binlog_row_image`

 * **Description:** Controls whether, in [row-based](../binary-log-formats/index#row-based) [replication](../replication/index), rows should be logged in 'FULL', 'NOBLOB' or 'MINIMAL' formats. In row-based replication (the variable has no effect with [statement-based replication](../binary-log-formats/index#statement-based)), each row change event contains an image for matching against when choosing the row to be updated, and another image containing the changes. Before the introduction of this variable, all columns were logged for both of these images. In certain circumstances, this is not necessary, and memory, disk and network resources can be saved by partial logging. Note that to safely change this setting from the default, the table being replicated to must contain identical primary key definitions, and columns must be present, in the same order, and use the same data types as the original table. If these conditions are not met, matches may not be correctly determined and updates and deletes may diverge on the replica, with no warnings or errors returned.
	+ `FULL`: All columns in the before and after image are logged. This is the default, and the only behavior in earlier versions.
	+ `NOBLOB`: mysqld avoids logging blob and text columns whenever possible (eg, blob column was not changed or is not part of primary key).
	+ `MINIMAL`: 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.
* **Commandline:** `--binlog-row-image=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `FULL`
* **Valid Values:** `FULL`, `NOBLOB` or `MINIMAL`

 

---

 #### `binlog_row_metadata`

 * **Description:** Controls the format used for binlog metadata logging.
	+ `NO_LOG`: No metadata is logged (default).
	+ `MINIMAL`: Only metadata required by a replica is logged.
	+ `FULL`: All metadata is logged.
* **Commandline:** `--binlog-row-metadata=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `NO_LOG`
* **Valid Values:** `NO_LOG`, `MINIMAL`, `FULL`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `binlog_stmt_cache_size`

 * **Description:** If the [binary log](../binary-log/index) is active, this variable determines the size in bytes of the cache holding a record of binary log changes outside of a transaction. The variable [binlog\_cache\_size](#binlog_cache_size), determines the cache size for binary log statements inside a transaction. The [binlog\_stmt\_cache\_disk\_use](../server-status-variables/index#binlog_stmt_cache_disk_use) and [binlog\_stmt\_cache\_use](../server-status-variables/index#binlog_stmt_cache_use) [server status variables](../server-status-variables/index) will indicate whether this variable needs to be increased (you want a low ratio of binlog\_stmt\_cache\_disk\_use to binlog\_stmt\_cache\_use).
* **Commandline:** `--binlog-stmt-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32768`
* **Range - 32 bit:** `4096` to `4294967295`
* **Range - 64 bit:** `4096` to `18446744073709547520`

 

---

 #### `default_master_connection`

 * **Description:** In [multi-source replication](../multi-source-replication/index), specifies which connection will be used for commands and variables if you don't specify a connection.
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty string)

 

---

 #### `encrypt_binlog`

 * **Description:** Encrypt [binary logs](../binary-log/index) (including [relay logs](../relay-log/index)). See [Data at Rest Encryption](../data-at-rest-encryption/index) and [Encrypting Binary Logs](../encrypting-binary-logs/index).
* **Commandline:** `--encrypt-binlog[={0|1}]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `expire_logs_days`

 * **Description:** Number of days after which the [binary log](../binary-log/index) can be automatically removed. By default 0, or no automatic removal. When using [replication](../replication/index), should always be set higher than the maximum lag by any replica. Removals take place when the server starts up, when the binary log is flushed, when the next binary log is created after the previous one reaches the maximum size, or when running [PURGE BINARY LOGS](../sql-commands-purge-logs/index). Units are whole days (integer) until [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), or 1/1000000 precision (double) from [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/).  
Starting from [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), `expire_logs_days` and [binlog\_expire\_logs\_seconds](#binlog_expire_logs_seconds) are forms of aliases, such that changes to one automatically reflect in the other.
* **Commandline:** `--expire-logs-days=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0.000000` (>= [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)), `0` (<= [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/))
* **Range:** `0` to `99`

 

---

 #### `init_slave`

 * **Description:** Similar to [init\_connect](../server-system-variables/index#init_connect), but the string contains one or more SQL statements, separated by semicolons, that will be executed by a replica server each time the SQL thread starts. These statements are only executed after the acknowledgement is sent to the replica and [START SLAVE](../start-slave/index) completes.
* **Commandline:** `--init-slave=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Related variables:**  `[init\_connect](../server-system-variables/index#init_connect)`

 

---

 #### `log_bin`

 * **Description:** Whether [binary logging](../binary-log/index) is enabled or not. If the --log-bin [option](../mysqld-options-full-list/index) is used, log\_bin will be set to ON, otherwise it will be OFF. If no `name` option is given for `--log-bin`, `datadir/'log-basename'-bin` or `'datadir'/mysql-bin` will be used (the latter if [--log-basename](../mysqld-options/index#-log-basename) is not specified). We strongly recommend you use either `--log-basename` or specify a filename to ensure that [replication](../replication/index) doesn't stop if the real hostname of the computer changes. The name option can optionally include an absolute path. If no path is specified, the log will be written to the [data directory](../server-system-variables/index#datadir). The name can optionally include the file extension; it will be stripped and only the file basename will be used.
* **Commandline:** `--log-bin[=name]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Related variables:** `[sql\_log\_bin](index#sql_log_bin)`

 

---

 #### `log_bin_basename`

 * **Description:** The full path of the binary log file names, excluding the extension. Its value is derived from the rules specified in `log_bin` system variable.
* **Commandline:** `No commandline option`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None
* **Dynamic:** `No`

 

---

 #### `log_bin_compress`

 * **Description:** Whether or not the binary log can be compressed. `0` (the default) means no compression. See [Compressing Events to Reduce Size of the Binary Log](../compressing-events-to-reduce-size-of-the-binary-log/index).
* **Commandline:** `--log-bin-compress`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `log_bin_compress_min_len`

 * **Description:** Minimum length of sql statement (in statement mode) or record (in row mode) that can be compressed. See [Compressing Events to Reduce Size of the Binary Log](../compressing-events-to-reduce-size-of-the-binary-log/index).
* **Commandline:** `--log-bin-compress-min-len`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `256`
* **Range: `10` to `1024`**

 

---

 #### `log_bin_index`

 * **Description:** File that holds the names for last binlog files.
* **Commandline:** `--log-bin-index=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None

 

---

 #### `log_bin_trust_function_creators`

 * **Description:** Functions and triggers can be dangerous when used with [replication](../high-availability-performance-tuning-mariadb-replication/index). Certain types of functions and triggers may have unintended consequences when the statements are applied on a replica. For that reason, there are some restrictions on the creation of functions and triggers when the [binary log](../binary-log/index) is enabled by default, such as:
	+ When `log_bin_trust_function_creators` is `OFF` and `[log\_bin](#log_bin)` is `ON`, `[CREATE FUNCTION](../create-function/index)` and `[ALTER FUNCTION](../alter-function/index)` statements will trigger an error if the function is defined with any of the `NOT DETERMINISTIC`, `CONTAINS SQL` or `MODIFIES SQL DATA` characteristics.
	+ This means that when `log_bin_trust_function_creators` is `OFF` and `[log\_bin](#log_bin)` is `ON`, `[CREATE FUNCTION](../create-function/index)` and `[ALTER FUNCTION](../alter-function/index)` statements will only succeed if the function is defined with any of the `DETERMINISTIC`, `NO SQL`, or `READS SQL DATA` characteristics.
	+ When `log_bin_trust_function_creators` is `OFF` and `[log\_bin](#log_bin)` is `ON`, the `[SUPER](../grant/index#global-privileges)` privilege is also required to execute the following statements:
		- `[CREATE FUNCTION](../create-function/index)`
		- `[CREATE TRIGGER](../create-trigger/index)`
		- `[DROP TRIGGER](../drop-trigger/index)`
	+ Setting `log_bin_trust_function_creators` to `ON` removes these requirements around functions characteristics and the `[SUPER](../grant/index#global-privileges)` privileges.
	+ See [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) for more information.
* **Commandline:** `--log-bin-trust-function-creators[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `log_slow_slave_statements`

 * **Description:** Log slow statements executed by replica thread to the [slow log](../slow-query-log/index) if it is open. Before [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), this was only available as a mysqld option, not a server variable.
* **Commandline:** `--log-slow-slave-statements`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`  (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `OFF` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))

 

---

 #### `log_slave_updates`

 * **Description:** If set to `0`, the default, updates on a replica received from a primary during [replication](../replication/index) are not logged in the replica's binary log. If set to `1`, they are. The replica's binary log needs to be enabled for this to have an effect. Set to `1` if you want to daisy-chain the replicas.
* **Commandline:** `--log-slave-updates`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `master_verify_checksum`

 * **Description:** Verify [binlog checksums](../binlog-event-checksums/index) when reading events from the binlog on the primary.
* **Commandline:** `--master-verify-checksum=[0|1]`
* **Scope:** Global
* **Access Type:** Can be changed dynamically
* **Data Type:** `bool`
* **Default Value:** `OFF (0)`

 

---

 #### `max_binlog_cache_size`

 * **Description:** Restricts the size in bytes used to cache a multi-transactional query. If more bytes are required, a `Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage` error is generated. If the value is changed, current sessions are unaffected, only sessions started subsequently. See [max\_binlog\_stmt\_cache\_size](#max_binlog_stmt_cache_size) and [binlog\_cache\_size](#binlog_cache_size).
* **Commandline:** `--max-binlog-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `18446744073709547520`
* **Range:** `4096` to `18446744073709547520`

 

---

 #### `max_binlog_size`

 * **Description:** If the [binary log](../binary-log/index) exceeds this size after a write, the server rotates it by closing it and opening a new binary log. Single transactions will always be stored in the same binary log, so the server will wait for open transactions to complete before rotating. This figure also applies to the size of [relay logs](../relay-log/index) if [max\_relay\_log\_size](#max_relay_log_size) is set to zero.
* **Commandline:** `--max-binlog-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1073741824` (1GB)
* **Range:** `4096 to 1073741824` (4KB to 1GB)

 

---

 #### `max_binlog_stmt_cache_size`

 * **Description:** Restricts the size used to cache non-transactional statements. See [max\_binlog\_cache\_size](#max_binlog_cache_size) and [binlog\_stmt\_cache\_size](#binlog_stmt_cache_size).
* **Commandline:** `--max-binlog-stmt-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `18446744073709547520` (64 bit), `4294963200` (32 bit)
* **Range:** `4096` to `18446744073709547520`

 

---

 #### `max_relay_log_size`

 * **Description:** Replica will rotate its [relay log](../relay-log/index) if it exceeds this size after a write. If set to 0, the [max\_binlog\_size](#max_binlog_size) setting is used instead. Previously global only, since the implementation of [multi-source replication](../multi-source-replication/index), it can be set per session as well.
* **Commandline:** `--max-relay-log-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0`, or `4096 to 1073741824` (4KB to 1GB)

 

---

 #### `read_binlog_speed_limit`

 * **Description:** Used to restrict the speed at which a [replica](../replication/index) can read the binlog from the primary. This can be used to reduce the load on a primary if many replicas need to download large amounts of old binlog files at the same time. The network traffic will be restricted to the specified number of kilobytes per second.
* **Commandline:** `--read-binlog-speed-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0` (no limit)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `relay_log`

 * **Description:** [Relay log](../relay-log/index) basename. If not set, the basename of the files will be `hostname-relay-bin`.
* **Commandline:** `--relay-log=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `filename`
* **Default Value:** `''` (none)

 

---

 #### `relay_log_basename`

 * **Description:** The full path of the relay log file names, excluding the extension. Its value is derived from the [relay-log](#relay_log) variable value.
* **Commandline:** `No commandline option`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None
* **Dynamic:** `No`

 

---

 #### `relay_log_index`

 * **Description:** Name and location of the [relay log](../relay-log/index) index file, the file that keeps a list of the last relay logs. Defaults to *hostname*-relay-bin.index.
* **Commandline:** `--relay-log-index=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None

 

---

 #### `relay_log_info_file`

 * **Description:** Name and location of the file where the `RELAY_LOG_FILE` and `RELAY_LOG_POS` options (i.e. the [relay log](../relay-log/index) position) for the [CHANGE MASTER](../change-master-to/index) statement are written. The [replica's SQL thread](../replication-threads/index#slave-sql-thread) keeps this [relay log](../relay-log/index) position updated as it applies events.
	+ See [CHANGE MASTER TO: Option Persistence](../change-master-to/index#option-persistence) for more information.
* **Commandline:** `--relay-log-info-file=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `relay-log.info`

 

---

 #### `relay_log_purge`

 * **Description:** If set to `1` (the default), [relay logs](../relay-log/index) will be purged as soon as they are no longer necessary.
* **Commandline:** `--relay-log-purge={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Note:** In MySQL and in MariaDB before version 10.0.8 this variable was silently changed if you did [CHANGE MASTER](../change-master-to/index).

 

---

 #### `relay_log_recovery`

 * **Description:** If set to `1` (`0` is default), on startup the replica will drop all [relay logs](../relay-log/index) that haven't yet been processed, and retrieve relay logs from the primary. Can be useful after the replica has crashed to prevent the processing of corrupt relay logs. relay\_log\_recovery should always be set together with [relay\_log\_purge](#relay_log_purge). Setting `relay-log-recovery=1` with `relay-log-purge=0` can cause the relay log to be read from files that were not purged, leading to data inconsistencies.
* **Commandline:** `--relay-log-recovery`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `relay_log_space_limit`

 * **Description:** Specifies the maximum space to be used for the [relay logs](../relay-log/index). The IO thread will stop until the SQL thread has cleared the backlog. By default `0`, or no limit.
* **Commandline:** `--relay-log-space-limit=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range - 32 bit:** `0` to `4294967295`
* **Range - 64 bit:** `0` to `18446744073709547520`

 

---

 #### `replicate_annotate_row_events`

 * **Description:** Tells the replica to reproduce [annotate\_rows\_events](../annotate_rows_log_event/index) received from the primary in its own binary log. This option is sensible only when used in tandem with the [log\_slave\_updates](#log_slave_updates) option.
* **Commandline:** `--replicate-annotate-row-events`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `OFF` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))

 

---

 #### `replicate_do_db`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to apply statements and transactions affecting databases that match a specified name.
	+ This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with `[SET GLOBAL](../set/index#global-session)`, the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-do-db=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `replicate_do_table`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to apply statements and transactions that affect tables that match a specified name. The table name is specified in the format: `dbname.tablename`.
	+ This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with `[SET GLOBAL](../set/index#global-session)`, the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-do-table=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `replicate_events_marked_for_skip`

 * **Description:** Tells the replica whether to [replicate](../replication/index) events that are marked with the `@@skip_replication` flag. See [Selectively skipping replication of binlog events](../selectively-skipping-replication-of-binlog-events/index) for more information.
* **Commandline:** `--replicate-events-marked-for-skip`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `replicate`
* **Valid Values:** `REPLICATE`, `FILTER_ON_SLAVE`, `FILTER_ON_MASTER`

 

---

 #### `replicate_ignore_db`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions affecting databases that match a specified name.
	+ This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with `[SET GLOBAL](../set/index#global-session)`, the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-ignore-db=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `replicate_ignore_table`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions that affect tables that match a specified name. The table name is specified in the format: `dbname.tablename`.
	+ This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with `[SET GLOBAL](../set/index#global-session)`, the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-ignore-table=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `replicate_rewrite_db`

 * **Description:** This option allows you to configure a [replica](../replication/index) to rewrite database names. It uses the format `primary_database->replica_database`. If a replica encounters a [binary log](../binary-log/index) event in which the default database (i.e. the one selected by the `[USE](../use/index)` statement) is `primary_database`, then the replica will apply the event in `replica_database` instead.
	+ This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ This option only affects statements that involve tables. This option does not affect statements involving the database itself, such as [CREATE DATABASE](../create-database/index), [ALTER DATABASE](../alter-database/index), and [DROP DATABASE](../drop-database/index).
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
	+ Before [MariaDB 10.11](../what-is-mariadb-1011/index), `replicate_rewrite_db` was not available as a system variable, only as a mariadbd/mysqld option, and could not be set dynamically. From [MariaDB 10.11](../what-is-mariadb-1011/index) it is available as a dynamic system variable
* **Commandline:** `--replicate-rewrite-db=primary_database->replica_database`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)
* **Introduced:** [MariaDB 10.11.0](../mdb-10-11-0-rn/index)

 

---

 #### `replicate_wild_do_table`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to apply statements and transactions that affect tables that match a specified wildcard pattern. The wildcard pattern uses the same semantics as the `[LIKE](../like/index)` operator.
	+ This system variable will work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with `[SET GLOBAL](../set/index#global-session)`, the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-wild-do-table=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `replicate_wild_ignore_table`

 * **Description:** This system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions that affect tables that match a specified wildcard pattern. The wildcard pattern uses the same semantics as the [LIKE](../like/index) operator.
	+ This system variable will work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.
* **Commandline:** `--replicate-wild-ignore-table=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `''` (empty)

 

---

 #### `report_host`

 * **Description:** The host name or IP address the replica reports to the primary when it registers. If left unset, the replica will not register itself. Reported by [SHOW SLAVE HOSTS](../show-slave-hosts/index). Note that it is not sufficient for the primary to simply read the IP of the replica from the socket once the replica connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the replica from the primary or other hosts.
* **Commandline:** `--report-host=host_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `report_password`

 * **Description:** Replica password reported to the primary when it registers. Reported by [SHOW SLAVE HOSTS](../show-slave-hosts/index) if `--show-slave-auth-info` is set. This password has no connection with user privileges or with the [replication](../replication/index) user account password.
* **Commandline:** `--report-password=password`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `report_port`

 * **Description:** The commandline option sets the TCP/IP port for connecting to the replica that will be reported to the [replicating](../replication/index) primary during the replica's registration. Viewing the variable will show this value.
* **Commandline:** `--report-port=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `65535`

 

---

 #### `report_user`

 * **Description:** Replica's account user name reported to the primary when it registers. Reported by [SHOW SLAVE HOSTS](../show-slave-hosts/index) if `--show-slave-auth-info` is set. This username has no connection with user privileges or with the [replication](../replication/index) user account.
* **Commandline:** `--report-user=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `server_id`

 * **Description:** This system variable is used with [MariaDB replication](../replication/index) to identify unique primary and replica servers in a topology. This system variable is also used with the [binary log](../binary-log/index) to determine which server a specific transaction originated on.
	+ When [MariaDB replication](../replication/index) is used with standalone MariaDB Server, each server in the replication topology must have a unique `server_id` value.
	+ When [MariaDB replication](../replication/index) is used with [MariaDB Galera Cluster](../galera/index), see [Using MariaDB Replication with MariaDB Galera Cluster: Setting server\_id on Cluster Nodes](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#setting-server_id-on-cluster-nodes) for more information on how to set the `server_id` values.
	+ In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and below, the default `server_id` value is `0`. If a replica's `server_id` value is `0`, then all primary's will refuse its connection attempts. If a primary's `server_id` value is `0`, then it will refuse all replica connection attempts.
* **Commandline:** `--server-id =#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `4294967295`

 

---

 #### `skip_parallel_replication`

 * **Description:** If set when a transaction is written to the binlog, parallel apply of that transaction will be avoided on a replica where [slave\_parallel\_mode](#slave_parallel_mode) is not `aggressive`. Can be used to avoid unnecessary rollback and retry for transactions that are likely to cause a conflict if replicated in parallel. See [parallel replication](../parallel-replication/index).
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `skip_replication`

 * **Description:** Changes are logged into the [binary log](../binary-log/index) with the @@skip\_replication flag set. Such events will not be [replicated](../replication/index) by replica that run with `--replicate-events-marked-for-skip` set different from its default of `REPLICATE`. See [Selectively skipping replication of binlog events](../selectively-skipping-replication-of-binlog-events/index) for more information.
* **Commandline:** None
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `slave_compressed_protocol`

 * **Description:** If set to 1 (0 is the default), will use compression for the replica/primary protocol if both primary and replica support this.
* **Commandline:** `--slave-compressed-protocol`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `slave_ddl_exec_mode`

 * **Description:** Modes for how [replication](../replication/index) of DDL events should be executed. Legal values are `STRICT` and `IDEMPOTENT` (default). In `IDEMPOTENT` mode, the replica will not stop for failed DDL operations that would not cause a difference between the primary and the replica. In particular [CREATE TABLE](../create-table/index) is treated as [CREATE OR REPLACE TABLE](../create-table/index#create-or-replace) and [DROP TABLE](../drop-table/index) is treated as `DROP TABLE IF EXISTS`.
* **Commandline:** `--slave-ddl-exec-mode=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `IDEMPOTENT`
* **Valid Values:** `IDEMPOTENT`, `STRICT`

 

---

 #### `slave_domain_parallel_threads`

 * **Description:** When set to a non-zero value, each [replication](../replication/index) domain in one primary connection can reserve at most that many worker threads at any one time, leaving the rest (up to the value of [slave\_parallel\_threads](#slave_parallel_threads)) free for other primary connections or replication domains to use in parallel. See [Parallel Replication](../parallel-replication/index#configuration-variable-slave_domain_parallel_threads) for details.
* **Commandline:** `--slave-domain-parallel-threads=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Valid Values:** `0` to `16383`

 

---

 #### `slave_exec_mode`

 * **Description:** Determines the mode used for [replication](../replication/index) error checking and conflict resolution. STRICT mode is the default, and catches all errors and conflicts. IDEMPOTENT mode suppresses duplicate key or no key errors, which can be useful in certain replication scenarios, such as when there are multiple primaries, or circular replication.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `IDEMPOTENT` (NDB), `STRICT` (All)
* **Valid Values:** `IDEMPOTENT`, `STRICT`

 

---

 #### `slave_load_tmpdir`

 * **Description:** Directory where the replica stores temporary files for [replicating](../replication/index) [LOAD DATA INFILE](../load-data-infile/index) statements. If not set, the replica will use [tmpdir](../server-system-variables/index#tmpdir). Should be set to a disk-based directory that will survive restarts, or else replication may fail.
* **Commandline:** `--slave-load-tmpdir=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** `/tmp`

 

---

 #### `slave_max_allowed_packet`

 * **Description:** Maximum packet size in bytes for replica SQL and I/O threads. This value overrides [max\_allowed\_packet](#max_allowed_packet) for [replication](../replication/index) purposes. Set in multiples of 1024 (the minimum) up to 1GB
* **Commandline:** `--slave-max-allowed-packet=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1073741824`
* **Range:** `1024` to `1073741824`

 

---

 #### `slave_net_timeout`

 * **Description:** Time in seconds for the replica to wait for more data from the primary before considering the connection broken, after which it will abort the read and attempt to reconnect. The retry interval is determined by the MASTER\_CONNECT\_RETRY open for the [CHANGE MASTER](../change-master-to/index) statement, while the maximum number of reconnection attempts is set by the [master-retry-count](../mysqld-options/index#-master-retry-count) option. The first reconnect attempt takes place immediately.
* **Commandline:** `--slave-net-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `60 (1 minute)`
* **Range:** `1` to `31536000`

 

---

 #### `slave_parallel_max_queued`

 * **Description:** When [parallel\_replication](../parallel-replication/index) is used, the [SQL thread](../replication-threads/index#slave-sql-thread) will read ahead in the relay logs, queueing events in memory while looking for opportunities for executing events in parallel. This system variable sets a limit for how much memory it will use for this.
	+ The configured value of this system variable is actually allocated for each [worker thread](../replication-threads/index#worker-threads), so the total allocation is actually equivalent to the following:
		- `[slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued)` \* `[slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads)`
	+ This system variable is only meaningful when parallel replication is configured (i.e. when `[slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads)` > `0`).
	+ See [Parallel Replication: Configuring the Maximum Size of the Parallel Slave Queue](../parallel-replication/index#configuring-the-maximum-size-of-the-parallel-slave-queue) for more information.
* **Commandline:** `--slave-parallel-max-queued=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `131072`
* **Range:** `0` to `2147483647`

 

---

 #### `slave_parallel_mode`

 * **Description:** Controls what transactions are applied in parallel when using [parallel replication](../parallel-replication/index).
	+ `optimistic`: tries to apply most transactional DML in parallel, and handles any conflicts with rollback and retry. See [optimistic mode](../parallel-replication/index#optimistic-mode-of-in-order-parallel-replication).
	+ `conservative`: limits parallelism in an effort to avoid any conflicts. See [conservative mode](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication).
	+ `aggressive`: tries to maximize the parallelism, possibly at the cost of increased conflict rate.
	+ `minimal`: only parallelizes the commit steps of transactions.
	+ `none` disables parallel apply completely.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `optimistic` (>= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)), `conservative` (<= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/))
* **Valid Values:** `conservative`, `optimistic`, `none`, `aggressive` and `minimal`

 

---

 #### `slave_parallel_threads`

 * **Description:** This system variable is used to configure [parallel replication](../parallel-replication/index).
	+ If this system variable is set to a value greater than `0`, then its value will determine how many replica [worker threads](../replication-threads/index#worker-threads) will be created to apply [binary log](../binary-log/index) events in parallel.
	+ If this system variable is set to `0` (which is the default value), then no replica [worker threads](../replication-threads/index#worker-threads) will be created. Instead, when replication is enabled, [binary log](../binary-log/index) events are applied by the replica's [SQL thread](../replication-threads/index#slave-sql-thread).
	+ The [replica threads](../replication-threads/index#threads-on-the-slave) must be [stopped](../stop-slave/index) in order to change this option's value dynamically.
	+ Events that were logged with [GTIDs](../gtid/index) with different `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` values can be applied in parallel in an [out-of-order](../parallel-replication/index#out-of-order-parallel-replication) manner. Each `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` can use the number of threads configured by `[slave\_domain\_parallel\_threads](#slave_domain_parallel_threads)`.
	+ Events that were [group-committed](../group-commit-for-the-binary-log/index) on the primary can be applied in parallel in an [in-order](../parallel-replication/index#what-can-be-run-in-parallel) manner, and the specific behavior can be configured by setting `[slave\_parallel\_mode](#slave_parallel_mode)`.
* **Commandline:** `--slave-parallel-threads=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `16383`

 

---

 #### `slave_parallel_workers`

 * **Description:** Alias for [slave\_parallel\_threads](#slave_parallel_threads).
* **Commandline:** `--slave-parallel-workers=#`

 

---

 #### `slave_run_triggers_for_rbr`

 * **Description:** See [Running triggers on the slave for Row-based events](../running-triggers-on-the-slave-for-row-based-events/index) for a description and use-case for this setting.
* **Commandline:** `--slave-run-triggers-for-rbr=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `NO`
* **Valid Values:** `NO`, `YES`, `LOGGING`, or `ENFORCE` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/))

 

---

 #### `slave_skip_errors`

 * **Description:** When an error occurs on the replica, [replication](../replication/index) usually halts. This option permits a list of [error codes](../mariadb-error-codes/index) to ignore, and for which replication will continue. This option should never be needed in normal use, and careless use could lead to replica that are out of sync with primary's. Error codes are in the format of the number from the replica error log. Using `all` as an option permits the replica the keep replicating no matter what error it encounters, an option you would never normally need in production and which could rapidly lead to data inconsistencies. A count of these is kept in [slave\_skipped\_errors](../replication-and-binary-log-status-variables/index#slave_skipped_errors).
* **Commandline:** `--slave-skip-errors=[error_code1,error_code2,...|all|ddl_exist_errors]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `OFF`
* **Valid Values:** `[list of error codes]`, `ALL`, `OFF`

 

---

 #### `slave_sql_verify_checksum`

 * **Description:** Verify [binlog checksums](../binlog-event-checksums/index) when the replica SQL thread reads events from the [relay log](../relay-log/index).
* **Commandline:** `--slave-sql-verify-checksum=[0|1]`
* **Scope:** Global
* **Access Type:** Can be changed dynamically
* **Data Type:** `bool`
* **Default Value:** `ON (1)`

 

---

 #### `slave_transaction_retries`

 * **Description:** Number of times a [replication](../replication/index) replica retries to execute an SQL thread after it fails due to InnDB deadlock or by exceeding the transaction execution time limit. If after this number of tries the SQL thread has still failed to execute, the replica will stop with an error. See also the [innodb\_lock\_wait\_timeout](../xtradbinnodb-server-system-variables/index#innodb_lock_wait_timeout) system variable.
* **Commandline:** `--slave-transaction-retries=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range - 32 bit:** `0` to `4294967295`
* **Range - 64 bit:** `0` to `18446744073709547520`

 

---

 #### `slave_transaction_retry_errors`

 * **Description:** When an error occurs during a transaction on the replica, [replication](../replication/index) usually halts. By default, transactions that caused a deadlock or elapsed lock wait timeout will be retried. One can add other errors to the the list of errors that should be retried by adding a comma-separated list of [error numbers](../mariadb-error-codes/index) to this variable. This is particularly useful in some [Spider](../spider/index) setups. Some recommended errors to retry for Spider are 1158,1159,1160,1161,1429,2013,12701.(From [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), these are in the default value)
* **Commandline:** `--slave-transaction_retry-errors=[error_code1,error_code2,...]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:**
	+ `1158,1159,1160,1161,1205,1213,1429,2013,12701` (>= [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/))
	+ `1213,1205` (>= [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/))
* **Valid Values:** `comma-separated list of error codes`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `slave_transaction_retry_interval`

 * **Description:** Interval in seconds for the replica SQL thread to retry a failed transaction due to a deadlock, elapsed lock wait timeout or an error listed in [slave\_transaction\_retry\_errors](#slave_transaction_retry_errors). The interval is calculated as `max(slave_transaction_retry_interval, min(retry_count, 5))`.
* **Commandline:** `--slave-transaction-retry-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `3600`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `slave_type_conversions`

 * **Description:** Determines the type conversion mode on the replica when using [row-based](../binary-log-formats/index#row-based) [replication](../replication/index), including replications in MariaDB Galera cluster. Multiple options can be set, delimited by commas. If left empty, the default, type conversions are disallowed. The variable is dynamic and a change in its value takes effect immediately. This variable tells the server what to do if the table definition is different between the primary and replica (for example a column is 'int' on the primary and 'bigint' on the replica).
	+ `ALL_NON_LOSSY` means that all safe conversions (no data loss) are allowed.
	+ `ALL_LOSSY` means that all lossy conversions are allowed (for example 'bigint' to 'int'). This, however, does not imply that safe conversions (non-lossy) are allowed as well. In order to allow all conversions, one needs to allow both lossy as well as non-lossy conversions by setting this variable to ALL\_NON\_LOSSY,ALL\_LOSSY.
	+ Empty (default) means that the server should give an error and replication should stop if the table definition is different between the primary and replica.
* **Commandline:** `--slave-type-conversions=set`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `set`
* **Default Value:** `Empty variable`
* **Valid Values:** `ALL_LOSSY`, `ALL_NON_LOSSY`, empty

 

---

 #### `sql_log_bin`

 * **Description:** If set to 0 (1 is the default), no logging to the [binary log](../binary-log/index) is done for the client. Only clients with the SUPER privilege can update this variable. Does not affect the replication of events in a Galera cluster.
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `sql_slave_skip_counter`

 * **Description:** Number of events that a replica skips from the primary. If this would cause the replica to begin in the middle of an event group, the replica will instead begin from the beginning of the next event group. See [SET GLOBAL sql\_slave\_skip\_counter](../set-global-sql_slave_skip_counter/index).
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

 #### `sync_binlog`

 * **Description:** MariaDB will synchronize its binary log file to disk after this many events. The default is 0, in which case the operating system handles flushing the file to disk. 1 is the safest, but slowest, choice, since the file is flushed after each write. If autocommit is enabled, there is one write per statement, otherwise there's one write per transaction. If the disk has cache backed by battery, synchronization will be fast and a more conservative number can be chosen.
* **Commandline:** `--sync-binlog=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`

 

---

 #### `sync_master_info`

 * **Description:** A [replication](../replication/index) replica will synchronize its master.info file to disk after this many events. If set to 0, the operating system handles flushing the file to disk.
* **Commandline:** `--sync-master-info=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10000`

 

---

 #### `sync_relay_log`

 * **Description:** The MariaDB server will synchronize its [relay log](../relay-log/index) to disk after this many writes to the log. The default until [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) was 0, in which case the operating system handles flushing the file to disk. 1 is the safest, but slowest, choice, since the file is flushed after each write. If autocommit is enabled, there is one write per statement, otherwise there's one write per transaction. If the disk has cache backed by battery, synchronization will be fast and a more conservative number can be chosen.
* **Commandline:** `--sync-relay-log=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10000`

 

---

 #### `sync_relay_log_info`

 * **Description:** A [replication](../replication/index) replica will synchronize its relay-log.info file to disk after this many transactions. The default until [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) was 0, in which case the operating system handles flushing the file to disk. 1 is the most secure choice, because at most one event could be lost in the event of a crash, but it's also the slowest.
* **Commandline:** `--sync-relay-log-info=#`
* **Scope:** Global,
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10000`
* **Range:** `0` to `4294967295`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-and-binary-log-system-variables/>

Binary Log
===========

   The binary log contains a record of all changes to the databases, both data and structure. It consists of a set of binary log files and an index.

 It is necessary for [replication](../replication/index), and can also be used to restore data after a backup.

  

| Title | Description |
| --- | --- |
|  [Overview of the Binary Log](../overview-of-the-binary-log/index) |  The binary log contains a record of all changes to the databases  |
|  [Activating the Binary Log](../activating-the-binary-log/index) |  Activating the Binary Log.  |
|  [Using and Maintaining the Binary Log](../using-and-maintaining-the-binary-log/index) |  Using and maintaining the binary log.  |
|  [Binary Log Formats](../binary-log-formats/index) |  The three binary logging formats.  |
|  [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) |  Stored routines require extra consideration when binary logging.  |
|  [SHOW BINARY LOGS](../show-binary-logs/index) |  SHOW BINARY LOGS lists all binary logs on the server.  |
|  [PURGE BINARY LOGS](../purge-binary-logs/index) |  PURGE BINARY LOGS removes all binary logs from the server, prior to the provided date or log file.  |
|  [SHOW BINLOG EVENTS](../show-binlog-events/index) |  Show events in the binary log.  |
|  [SHOW MASTER STATUS](../show-binlog-status/index) |  Status information about the binary log.  |
|  [Binlog Event Checksums](../binlog-event-checksums/index) |  Including a checksum in binlog events.  |
|  [Binlog Event Checksum Interoperability](../binlog-event-checksum-interoperability/index) |  Replicating between servers with differing binlog checksum availability  |
|  [Group Commit for the Binary Log](../group-commit-for-the-binary-log/index) |  Optimization when the server is run with innodb\_flush\_logs\_at\_trx\_commit or sync\_binlog.  |
|  [mariadb-binlog](../mariadb-binlog/index) |  mariadb-binlog utility for processing binary log files.  |
|  [Transaction Coordinator Log](../transaction-coordinator-log/index) |  The transaction coordinator log (tc\_log) is used to coordinate transactions...  |
|  [Compressing Events to Reduce Size of the Binary Log](../compressing-events-to-reduce-size-of-the-binary-log/index) |  Binlog events can be compressed to save space on disk and in network transfers.  |
|  [Encrypting Binary Logs](../encrypting-binary-logs/index) |  Data-at-rest encryption for binary logs and relay logs.  |
|  [Flashback](../flashback/index) |  Rollback instances/databases/tables to an old snapshot.  |
|  [Relay Log](../relay-log/index) |  Event log created by the replica from the primary binary log.  |
|  [Replication and Binary Log System Variables](../replication-and-binary-log-system-variables/index) |  Replication and binary log system variables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-log/>

Unsafe Statements for Statement-based Replication
=================================================

     A safe statement is generally deterministic; in other words the statement will always produce the same result. For example, an INSERT statement producing a random number will most likely produce a different result on the primary than on the replica, and so cannot be replicated safely.

 When an unsafe statement is run, the current binary logging format determines how the server responds.

 * If the binary logging format is [statement-based](../binary-log-formats/index#statement-based-logging) (the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)), unsafe statements generate a warning and are logged normally.
* If the binary logging format is [mixed](../binary-log-formats/index#mixed-logging) (the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)), unsafe statements are logged using the row-based format, while safe statements use the statement-based format.
* If the binary logging format is [row-based](../binary-log-formats/index#row-based-logging), all statements are logged normally, and the distinction between safe and unsafe is not made.

 MariaDB tries to detect unsafe statements. When an unsafe statement is issued, a warning similar to the following is produced:

 
```
Note (Code 1592): Unsafe statement written to the binary log using statement format since 
  BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This 
  is unsafe because the set of rows included cannot be predicted.

```

MariaDB also issues this warning for some classes of statements that are safe.

 Unsafe Statements
-----------------

 The following statements are regarded as unsafe:

 * [INSERT ... ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) statements upon tables with multiple primary or unique keys, as the order that the keys are checked in, and which affect the rows chosen to update, is not deterministic. Before [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5524-release-notes/), these statements were not regarded as unsafe. In [MariaDB 10.0](../what-is-mariadb-100/index) this warning has been removed as we always check keys in the same order on the primary and replica if the primary and replica are using the same storage engine.
* [INSERT-DELAYED](../insert-delayed/index). These statements are inserted in an indeterminate order.
* [INSERTs](../insert/index) on tables with a composite primary key that has an [AUTO\_INCREMENT](../auto_increment/index) column that isn't the first column of the composite key.
* When a table has an [AUTO\_INCREMENT](../auto_increment/index) column and a [trigger](../triggers/index) or [stored procedure](../stored-programs-and-views/index) executes an [UPDATE](../update/index) statement against the table. Before [MariaDB 5.5](../what-is-mariadb-55/index), all updates on tables with an AUTO\_INCREMENT column were considered unsafe, as the order that the rows were updated could differ across servers.
* [UPDATE](../update/index) statements that use [LIMIT](../select/index#limit), since the order of the returned rows is unspecified. This applies even to statements using an ORDER BY clause, which are deterministic (a known bug). However, since [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/), `LIMIT 0` is an exception to this rule (see [MDEV-6170](https://jira.mariadb.org/browse/MDEV-6170)), and these statements are safe for replication.
* When using a [user-defined function](../user-defined-functions/index).
* Statements using using any of the following functions, which can return different results on the replica:
	+ [CURRENT\_ROLE()](../current_role/index)
	+ [CURRENT\_USER()](../current_user/index)
	+ [FOUND\_ROWS()](../found_rows/index)
	+ [GET\_LOCK()](../get_lock/index)
	+ [IS\_FREE\_LOCK()](../is_free_lock/index)
	+ [IS\_USED\_LOCK()](../is_used_lock/index)
	+ [JSON\_TABLE()](../json_table/index)
	+ [LOAD\_FILE()](../load_file/index)
	+ [MASTER\_POS\_WAIT()](../master_pos_wait/index)
	+ [RAND()](../rand/index)
	+ [RANDOM\_BYTES()](../random_bytes/index)
	+ [RELEASE\_ALL\_LOCKS()](../release_all_locks/index)
	+ [RELEASE\_LOCK()](../release_lock/index)
	+ [ROW\_COUNT()](../row_count/index)
	+ [SESSION\_USER()](../session_user/index)
	+ [SLEEP()](../sleep/index)
	+ [SYSDATE()](../sysdate/index)
	+ [SYSTEM\_USER()](../system_user/index)
	+ [USER()](../user/index)
	+ [UUID()](../uuid/index)
	+ [UUID\_SHORT()](../uuid_short/index).
* Statements which refer to log tables, since these may differ across servers.
* Statements which refer to self-logging tables. Statements following a read or write to a self-logging table within a transaction are also considered unsafe.
* Statements which refer to [system variables](../server-system-variables/index) (there are a few exceptions).
* [LOAD DATA INFILE](../load-data-infile/index) statements (since [MariaDB 5.5](../what-is-mariadb-55/index)).
* Non-transactional reads or writes that execute after transactional reads within a transaction.
* If row-based logging is used for a statement, and the session executing the statement has any temporary tables, row-based logging is used for the remaining statements until the temporary table is dropped. This is because temporary tables can't use row-based logging, so if it is used due to one of the above conditions, all subsequent statements using that table are unsafe. The server deals with this situation by treating all statements in the session as unsafe for statement-based logging until the temporary table is dropped.

 Safe Statements
---------------

 The following statements are not deterministic, but are considered safe for binary logging and replication: 

 * [CONNECTION\_ID()](../connection_id/index)
* [CURDATE()](../curdate/index)
* [CURRENT\_DATE()](../current_date/index)
* [CURRENT\_TIME()](../current_time/index)
* [CURRENT\_TIMESTAMP()](../current_timestamp/index)
* [CURTIME()](../curtime/index)
* [LAST\_INSERT\_ID()](../last_insert_id/index)
* [LOCALTIME()](../localtime/index)
* [LOCALTIMESTAMP()](../localtimestamp/index)
* [NOW()](../now/index)
* [UNIX\_TIMESTAMP()](../unix_timestamp/index)
* [UTC\_DATE()](../utc_date/index)
* [UTC\_TIME()](../utc_time/index)
* [UTC\_TIMESTAMP()](../utc_timestamp/index)

 Isolation Levels
----------------

 Even when using safe statements, not all [transaction isolation levels](../set-transaction/index#isolation-levels) are safe with statement-based or mixed binary logging. The REPEATABLE READ and SERIALIZABLE isolation levels can only be used with the row-based format.

 This restriction does not apply if only non-transactional storage engines are used.

 See Also
--------

 * [Replication and Foreign Keys](../replication-and-foreign-keys/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/unsafe-statements-for-statement-based-replication/>

Replication and Foreign Keys
============================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 Replication is based upon the [binary log](../binary-log/index). However, cascading deletes or updates based on foreign key relations are an internal mechanism, and are not written to the binary log.

 Because of this, an identical statement run on the master and the slave may result in different outcomes if the foreign key relations are not identical on both master and slave This could be the case if the storage engine on one supports cascading deletes (e.g. InnoDB) and the storage engine on the other does not (e.g. MyISAM), or the one has specified a foreign key relation, and the other hasn't.

 Take the following example:

 
```
CREATE TABLE employees (
    x INT PRIMARY KEY,
    name VARCHAR(10)
) ENGINE = InnoDB;

CREATE TABLE children (
    y INT PRIMARY KEY,
    f INT,
    name VARCHAR(10),
    FOREIGN KEY fk (f) REFERENCES employees (x)
        ON DELETE CASCADE
) ENGINE = InnoDB;

```

The slave, however, has been set up without InnoDB support, and defaults to MyISAM, so the foreign key restrictions are not in place.

 
```
INSERT INTO employees VALUES (1, 'Yaser'), (2, 'Prune');

INSERT INTO children VALUES (1, 1, 'Haruna'), (2, 1, 'Hera'), (3, 2, 'Eva');

```

At this point, the slave and the master are in sync:

 
```
SELECT * FROM employees;
+---+-------+
| x | name  |
+---+-------+
| 1 | Yaser |
| 2 | Prune |
+---+-------+
2 rows in set (0.00 sec)

SELECT * FROM children;
+---+------+--------+
| y | f    | name   |
+---+------+--------+
| 1 |    1 | Haruna |
| 2 |    1 | Hera   |
| 3 |    2 | Eva    |
+---+------+--------+

```

However, after:

 
```
DELETE FROM employees WHERE x=1;

```

there are different outcomes on the slave and the master.

 On the master, the cascading deletes have taken effect:

 
```
SELECT * FROM children;
+---+------+------+
| y | f    | name |
+---+------+------+
| 3 |    2 | Eva  |
+---+------+------+

```

On the slave, the cascading deletes did not take effect:

 
```
SELECT * FROM children;
+---+------+--------+
| y | f    | name   |
+---+------+--------+
| 1 |    1 | Haruna |
| 2 |    1 | Hera   |
| 3 |    2 | Eva    |
+---+------+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-and-foreign-keys/>

Relay Log
=========

     The relay log is a set of log files created by a replica during [replication](../standard-replication/index).

 It's the same format as the [binary log](../binary-log/index), containing a record of events that affect the data or structure; thus, [mariadb-binlog](../mariadb-binlog/index) can be used to display its contents. It consists of a set of relay log files and an index file containing a list of all relay log files.

 Events are read from the primary's binary log and written to the replica's relay log. They are then performed on the replica. Old relay log files are automatically removed once they are no longer needed.

 Creating Relay Log Files
------------------------

 New relay log files are created by the replica at the following times:

 * when the IO thread starts
* when the logs are flushed, with [FLUSH LOGS](../flush/index) or [mariadb-admin flush-logs](../mariadb-admin/index).
* when the maximum size, determined by the [max\_relay\_log\_size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size) system variable, has been reached

 Relay Log Names
---------------

 By default, the relay log will be given a name `host_name-relay-bin.nnnnnn`, with `host_name` referring to the server's host name, and #nnnnnn `the sequence number.`

 This will cause problems if the replica's host name changes, returning the error `Failed to open the relay log` and `Could not find target log during relay log initialization`. To prevent this, you can specify the relay log file name by setting the [relay\_log](../replication-and-binary-log-server-system-variables/index#relay_log) and [relay\_log\_index](../replication-and-binary-log-server-system-variables/index#relay_log_index) system variables.

 If you need to overcome this issue while replication is already underway,you can stop the replica, prepend the old relay log index file to the new relay log index file, and restart the replica.

 For example:

 
```
shell> cat NEW_relay_log_name.index >> OLD_relay_log_name.index
shell> mv OLD_relay_log_name.index NEW_relay_log_name.index

```

Viewing Relay Logs
------------------

 The [SHOW RELAYLOG EVENTS](../show-relaylog-events/index) shows events in the relay log, and, since relay log files are the same format as binary log files, they can be read with the [mariadb-binlog](../mariadb-binlog/index) utility.

 Removing Old Relay Logs
-----------------------

 Old relay logs are automatically removed once all events have been implemented on the replica, and the relay log file is no longer needed. This behavior can be changed by adjusting the [relay\_log\_purge](../replication-and-binary-log-server-system-variables/index#relay_log_purge) system variable from its default of `1` to `0`, in which case the relay logs will be left on the server.

 Relay logs are also removed by the [CHANGE MASTER](../change-master-to/index) statement unless a [relay log option](../change-master-to/index#relay_log_options) is used.

 One can also flush the logs with the [FLUSH RELAY LOGS](../flush/index) commands.

 If the relay logs are taking up too much space on the replica, the [relay\_log\_space\_limit](../replication-and-binary-log-server-system-variables/index#relay_log_space_limit) system variable can be set to limit the size. The IO thread will stop until the SQL thread has cleared the backlog. By default there is no limit.

 See also
--------

 * [FLUSH RELAY LOGS](../flush/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/relay-log/>

Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT
===========================================================

     With the introduction of [group commit](../group-commit-for-the-binary-log/index), MariaDB also introduced an enhanced storage engine API for COMMIT that allows engines to coordinate commit ordering and visibility with each other and with the [binary log](../binary-log/index).

 With these improvements, the `START TRANSACTION WITH CONSISTENT SNAPSHOT` statement was enhanced to ensure consistency between storage engines that support the new API. At the time of writing, the supporting engines are [XtraDB](../xtradb-and-innodb/index) and [PBXT](../pbxt-storage-engine/index). In addition, the binary log, while not a storage engine as such, also supports the new API and can provide a binlog position consistent with storage engine transaction snapshots.

 This means that with transaction isolation level at least [REPEATABLE READ](../set-transaction/index#repeatable-read), the `START TRANSACTION WITH CONSISTENT SNAPSHOT` statement can be used to ensure that queries will see a transaction-consistent view of the database also between storage engines. It is then not possible for a query to see the changes from some transaction T in XtraDB tables without also seeing the changes T makes to PBXT tables. (Within a single transactional storage engine like XtraDB or PBXT, consistency is always guaranteed even without using `START TRANSACTION WITH CONSISTENT SNAPSHOT`).

 For example, suppose the following two transactions run in parallel:

 Transaction T1:

 
```
    BEGIN;
    SET @t = NOW();
    UPDATE xtradb_table SET a= @t WHERE id = 5;
    UPDATE pbxt_table SET b= @t WHERE id = 5;
    COMMIT;

```

Transaction T2:

 
```
    SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    START TRANSACTION WITH CONSISTENT SNAPSHOT;
    SELECT t1.a, t2.b
      FROM xtradb_table t1 INNER JOIN pbxt_table t2 ON t1.id=t2.id
     WHERE t1.id = 5;

```

Then transaction T2 will always see the same value for `xtradb_table.a` and `pbxt_table.b`.

 (In [MariaDB 5.2](../what-is-mariadb-52/index) and earlier, and MySQL at least up to 5.5, `START TRANSACTION
WITH CONSISTENT SNAPSHOT` did not give any guarantees of consistency between different storage engines. So it is possible, even with a "consistent" snapshot, to see the changes in a transaction only to InnoDB/XtraDB tables, not PBXT tables, for example.)

 Status Variables
----------------

 Another use for these enhancements is to obtain a binary log position that is consistent with a particular transactional state of the storage engine(s) in the database. This is done with two status variables for the binary log: [binlog\_snapshot\_file](../replication-and-binary-log-status-variables/index#binlog_snapshot_file) and [binlog\_snapshot\_position](../replication-and-binary-log-status-variables/index#binlog_snapshot_position)

 These variables give the binary log file and position like `SHOW MASTER STATUS` does. But they can be queried in a transactionally consistent way. After starting a transaction using `START TRANSACTION WITH CONSISTENT SNAPSHOT`, the two variables will give the binlog position corresponding to the state of the database of the consistent snapshot so taken, irrespectively of which other transactions have been committed since the snapshot was taken (`SHOW MASTER
STATUS` always shows the position of the last committed transaction). This works for MVCC storage engines that implement the commit ordering part of the storage engine API, which at the time of writing is XtraDB and PBXT.

 This is useful to obtain a logical dump/backup with a matching binlog position that can be used to provision a new slave with the original server as the master. First `START TRANSACTION WITH CONSISTENT SNAPSHOT` is executed. Then a consistent state of the database is obtained with queries, and the matching binlog position is obtained with `SHOW STATUS LIKE 'binlog_snapshot%'`. When this is loaded on a new slave server, the binlog position is used in a `CHANGE
MASTER TO` statement to set the slave replicating from the correct position.

 With the variables binlog\_snapshot\_file and binlog\_snapshot\_position, such provisioning can be done fully non-blocking on the master. Without them, it is necessary to get the binlog position under `FLUSH TABLES WITH READ LOCK`; this can potentially stall the server for a long time, as it blocks new queries until all updates that have already started have finished.

 ### mariadb-dump

 The [mariadb-dump](../mariadb-dump/index) program was extended to use these status variables. This means that a backup suitable for provisioning a slave can be obtained as normal like this:

 
```
    mariadb-dump --single-transaction --master-data ...

```

The dump will be fully non-blocking if both the mariadb-dump program and the queried server include the necessary feature (eg. both are from [MariaDB 5.2](../what-is-mariadb-52/index)-rpl, 5.3, or higher). In other cases, it will fall back to the old blocking method using `FLUSH TABLES WITH READ LOCK`.

 For more information on the design and implementation of this feature, see [MWL#136](http://askmonty.org/worklog/?tid=136).

 See Also
--------

 * [START TRANSACTION](../start-transaction/index)
* [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT](../myrocks-and-start-transaction-with-consistent-snapshot/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/enhancements-for-start-transaction-with-consistent-snapshot/>

Group Commit for the Binary Log
===============================

    Overview
--------

 The server supports group commit. This is an important optimization that helps MariaDB reduce the number of expensive disk operations that are performed.

 Durability
----------

 In ACID terminology, the "D" stands for durability. In order to ensure durability with group commit, [innodb\_flush\_log\_at\_trx\_commit=1](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) and/or [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) should be set. These settings are needed to ensure that if the server crashes, then any transaction that was committed prior to the time of crash will still be present in the database after crash recovery.

 ### Durable InnoDB Data and Binary Logs

 Setting both [innodb\_flush\_log\_at\_trx\_commit=1](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) and [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) provides the most durability and the best guarantee of [replication](../high-availability-performance-tuning-mariadb-replication/index) consistency after a crash.

 ### Non-Durable InnoDB Data

 If [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) is set, but [innodb\_flush\_log\_at\_trx\_commit](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) is not set to `1` or `3`, then it is possible after a crash to end up in a state where a transaction present in a server's [binary log](../binary-log/index) is missing from the server's [InnoDB redo log](../xtradbinnodb-redo-log/index). If the server is a [replication master](../high-availability-performance-tuning-mariadb-replication/index), then that means that the server can become inconsistent with its slaves, since the slaves may have replicated transactions from the master's [binary log](../binary-log/index) that are no longer present in the master's local [InnoDB](../innodb/index) data. 

 ### Non-Durable Binary Logs

 If [innodb\_flush\_log\_at\_trx\_commit](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) is set to `1` or `3`, but [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) is not set, then it is possible after a crash to end up in a state where a transaction present in a server's [InnoDB redo log](../xtradbinnodb-redo-log/index) is missing from the server's [binary log](../binary-log/index). If the server is a [replication master](../high-availability-performance-tuning-mariadb-replication/index), then that also means that the server can become inconsistent with its slaves, since the server's slaves would not be able to replicate the missing transactions from the server's [binary log](../binary-log/index).

 ### Non-Durable InnoDB Data and Binary Logs

 Setting [innodb\_flush\_log\_at\_trx\_commit=1](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) when [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) is not set can also cause the transaction to be missing from the server's [InnoDB redo log](../xtradbinnodb-redo-log/index) due to some optimizations added in those versions. In that case, it is recommended to always set [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog). If you can't do that, then it is recommended to set [innodb\_flush\_log\_at\_trx\_commit](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) to `3`, rather than `1`. See [Non-durable Binary Log Settings](../binary-log-group-commit-and-innodb-flushing-performance/index#non-durable-binary-log-settings) for more information.

 Amortizing Disk Flush Costs
---------------------------

 After every transaction [COMMIT](../commit/index), the server normally has to flush any changes the transaction made to the [InnoDB redo log](../xtradbinnodb-redo-log/index) and the [binary log](../binary-log/index) to disk (i.e. by calling system calls such as `fsync()` or `fdatasync()` or similar). This helps ensure that the data changes made by the transaction are stored durably on the disk. Disk flushing is a time-consuming operation, and can easily impose limits on throughput in terms of the number of transactions-per-second (TPS) which can be committed.

 The idea with group commit is to amortize the costs of each flush to disk over multiple commits from multiple parallel transactions. For example, if there are 10 transactions trying to commit in parallel, then we can force all of them to be flushed disk at once with a single system call, rather than do one system call for each commit. This can greatly reduce the need for flush operations, and can consequently greatly improve the throughput of transactions-per-second (TPS).

 However, to see the positive effects of group commit, the workload must have sufficient parallelism. A good rule of thumb is that at least three parallel transactions are needed for group commit to be effective. For example, while the first transaction is waiting for its flush operation to complete, the other two transactions will queue up waiting for their turn to flush their changes to disk. When the first transaction is done, a single system call can be used to flush the two queued-up transactions, saving in this case one of the three system calls.

 In addition to sufficient parallelism, it is also necessary to have enough transactions per second wanting to commit that the flush operations are a bottleneck. If no such bottleneck exists (i.e. transactions never or rarely need to wait for the flush of another to complete), then group commit will provide little to no improvement.

 Changing Group Commit Frequency
-------------------------------

 The frequency of group commits can be changed by configuring the [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec) and [binlog\_commit\_wait\_count](../replication-and-binary-log-system-variables/index#binlog_commit_wait_count) system variables.

 Measuring Group Commit Ratio
----------------------------

 Two status variables are available for checking how effective group commit is at reducing flush overhead. These are the [Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits) and [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits) status variables. We can obtain those values with the following query:

 
```
SHOW GLOBAL STATUS WHERE Variable_name IN('Binlog_commits', 'Binlog_group_commits');

```

[Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits) is the total number of transactions committed to the [binary log](../binary-log/index).

 [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits) is the total number of groups committed to the [binary log](../binary-log/index). As explained in the previous sections of this page, a group commit is when a group of transactions is flushed to the [binary log](../binary-log/index) together by sharing a single flush system call. When [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) is set, then this is also the total number of flush system calls executed in the process of flushing commits to the [binary log](../binary-log/index).

 Thus the extent to which group commit is effective at reducing the number of flush system calls on the binary log can be determined by the ratio between these two status variables. [Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits) will always be as equal to or greater than [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits). The greater the difference is between these status variables, the more effective group commit was at reducing flush overhead.

 To calculate the group commit ratio, we actually need the values of these status variables from two snapshots. Then we can calculate the ratio with the following formula:

 `transactions/group commit` = (`Binlog_commits` (*snapshot2*) - `Binlog_commits` (*snapshot1*))/(`Binlog_group_commits` (*snapshot2*) - `Binlog_group_commits` (*snapshot1*))

 For example, if we had the following first snapshot:

 
```
SHOW GLOBAL STATUS WHERE Variable_name IN('Binlog_commits', 'Binlog_group_commits');
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Binlog_commits       | 120   |
| Binlog_group_commits | 120   |
+----------------------+-------+
2 rows in set (0.00 sec)

```

And the following second snapshot:

 
```
SHOW GLOBAL STATUS WHERE Variable_name IN('Binlog_commits', 'Binlog_group_commits');
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| Binlog_commits       | 220   |
| Binlog_group_commits | 145   |
+----------------------+-------+
2 rows in set (0.00 sec)

```

Then we would have:

 `transactions/group commit` = (220 - 120) / (145 - 120) = 100 / 25 = 4 `transactions/group commit`

 If your group commit ratio is too close to 1, then it may help to [change your group commit frequency](index#changing-group-commit-frequency).

 Use of Group Commit with Parallel Replication
---------------------------------------------

 Group commit is also used to enable [conservative mode of in-order parallel replication](../parallel-replication/index#conservative-mode-of-in-order-parallel-replication).

 Effects of Group Commit on InnoDB Performance
---------------------------------------------

 When both [innodb\_flush\_log\_at\_trx\_commit=1](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) (the default) is set and the [binary log](../binary-log/index) is enabled, there is now one less sync to disk inside InnoDB during commit (2 syncs shared between a group of transactions instead of 3). See [Binary Log Group Commit and InnoDB Flushing Performance](../binary-log-group-commit-and-innodb-flushing-performance/index) for more information.

 Status Variables
----------------

 [Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits) is the total number of transactions committed to the [binary log](../binary-log/index).

 [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits) is the total number of groups committed to the [binary log](../binary-log/index).

 [Binlog\_group\_commit\_trigger\_count](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_count) is the total number of group commits triggered because of the number of [binary log](../binary-log/index) commits in the group reached the limit set by the system variable [binlog\_commit\_wait\_count](../replication-and-binary-log-system-variables/index#binlog_commit_wait_count).

 [Binlog\_group\_commit\_trigger\_lock\_wait](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_lock_wait) is the total number of group commits triggered because a [binary log](../binary-log/index) commit was being delayed because of a lock wait where the lock was held by a prior binary log commit. When this happens the later binary log commit is placed in the next group commit.

 [Binlog\_group\_commit\_trigger\_timeout](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_timeout) is the total number of group commits triggered because of the time since the first [binary log](../binary-log/index) commit reached the limit set by the system variable [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec).

 To query these variables, use a statement such as:

 
```
SHOW GLOBAL STATUS LIKE 'Binlog_%commit%';

```

See Also
--------

 * [Parallel Replication](../parallel-replication/index)
* [Binary Log Group Commit and InnoDB Flushing Performance](../binary-log-group-commit-and-innodb-flushing-performance/index)
* [Group commit benchmark](http://www.facebook.com/note.php?note_id=10150211546215933)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/group-commit-for-the-binary-log/>

Replication and Binary Log Status Variables
===========================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   The following status variables are useful in [binary logging](../binary-log/index) and [replication](../replication/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Binlog_bytes_written`

 * **Description:** The number of bytes written to the [binary log](../binary-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_cache_disk_use`

 * **Description:** Number of transactions which used a temporary disk cache because they could not fit in the regular [binary log](../binary-log/index) cache, being larger than [binlog\_cache\_size](../server-system-variables/index#binlog_cache_size). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_cache_use`

 * **Description:** Number of transaction which used the regular [binary log](../binary-log/index) cache, being smaller than [binlog\_cache\_size](../server-system-variables/index#binlog_cache_size). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_commits`

 * **Description:** Total number of transactions committed to the binary log.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_group_commit_trigger_count`

 * **Description:** Total number of group commits triggered because of the number of binary log commits in the group reached the limit set by the variable [binlog\_commit\_wait\_count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count). See [Group commit for the binary log](../group-commit-for-the-binary-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_group_commit_trigger_lock_wait`

 * **Description:** Total number of group commits triggered because a binary log commit was being delayed because of a lock wait where the lock was held by a prior binary log commit. When this happens the later binary log commit is placed in the next group commit. See [Group commit for the binary log](../group-commit-for-the-binary-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_group_commit_trigger_timeout`

 * **Description:** Total number of group commits triggered because of the time since the first binary log commit reached the limit set by the variable [binlog\_commit\_wait\_usec](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_usec). See [Group commit for the binary log](../group-commit-for-the-binary-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_group_commits`

 * **Description:** Total number of group commits done to the binary log. See [Group commit for the binary log](../group-commit-for-the-binary-log/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_snapshot_file`

 * **Description:** The binary log file. Unlike [SHOW MASTER STATUS](../show-master-status/index), can be queried in a transactionally consistent way, irrespective of which other transactions have been committed since the snapshot was taken. See [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index).
* **Scope:** Global
* **Data Type:** `string`

 

---

 #### `Binlog_snapshot_position`

 * **Description:** The binary log position. Unlike [SHOW MASTER STATUS](../show-master-status/index), can be queried in a transactionally consistent way, irrespective of which other transactions have been committed since the snapshot was taken. See [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_stmt_cache_disk_use`

 * **Description:** Number of non-transaction statements which used a temporary disk cache because they could not fit in the regular [binary log](../binary-log/index) cache, being larger than [binlog\_stmt\_cache\_size](../server-system-variables/index#binlog_stmt_cache_size). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Binlog_stmt_cache_use`

 * **Description:** Number of non-transaction statement which used the regular [binary log](../binary-log/index) cache, being smaller than [binlog\_stmt\_cache\_size](../server-system-variables/index#binlog_stmt_cache_size). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Com_change_master`

 * **Description:** Number of [CHANGE MASTER TO](../change-master-to/index) statements executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_binlog_status`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Com_show_master_status`

 * **Description:** Number of [SHOW MASTER STATUS](../show-master-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Com_show_new_master`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `Com_show_slave_hosts`

 * **Description:** Number of [SHOW SLAVE HOSTS](../show-slave-hosts/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_show_slave_status`

 * **Description:** Number of [SHOW SLAVE STATUS](../show-slave-status/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_slave_start`

 * **Description:** Number of [START SLAVE](../start-slave/index) commands executed. Removed in [MariaDB 10.0](../what-is-mariadb-100/index), see [Com\_start\_slave](#com_start_slave).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** `[MariaDB 10.0](../what-is-mariadb-100/index)`

 

---

 #### `Com_slave_stop`

 * **Description:** Number of [STOP SLAVE](../stop-slave/index) commands executed. Removed in [MariaDB 10.0](../what-is-mariadb-100/index), see [Com\_stop\_slave](#com_stop_slave).
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** `[MariaDB 10.0](../what-is-mariadb-100/index)`

 

---

 #### `Com_start_all_slaves`

 * **Description:** Number of [START ALL SLAVES](../start-slave/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_start_slave`

 * **Description:** Number of [START SLAVE](../start-slave/index) commands executed. Replaces the old [Com\_slave\_start](#com_slave_start).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stop_all_slaves`

 * **Description:** Number of [STOP ALL SLAVES](../stop-slave/index) commands executed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Com_stop_slave`

 * **Description:** Number of [STOP SLAVE](../stop-slave/index) commands executed. Replaces the old [Com\_slave\_stop](#com_slave_stop).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Master_gtid_wait_count`

 * **Description:** Number of times MASTER\_GTID\_WAIT called.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Master_gtid_wait_time`

 * **Description:** Total number of time spent in MASTER\_GTID\_WAIT.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Master_gtid_wait_timeouts`

 * **Description:** Number of timeouts occurring in MASTER\_GTID\_WAIT.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rpl_status`

 * **Description:** For showing the status of fail-safe replication. Removed in MySQL 5.6, still present in [MariaDB 10.0](../what-is-mariadb-100/index).

 

---

 #### `Rpl_transactions_multi_engine`

 * **Description:** Number of replicated transactions that involved changes in multiple (transactional) storage engines, before considering the update of `mysql.gtid_slave_pos`. These are transactions that were already cross-engine, independent of the GTID position update introduced by replication. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `Slave_connections`

 * **Description:** Number of REGISTER\_SLAVE attempts. In practice the number of times slaves has tried to connect to the master.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_heartbeat_period`

 * **Description:** Time in seconds that a heartbeat packet is requested from the master by a slave.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_open_temp_tables`

 * **Description:** Number of temporary tables the slave has open.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_received_heartbeats`

 * **Description:** Number of heartbeats the slave has received from the master.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_retried_transactions`

 * **Description:** Number of times the slave has retried transactions since the server started. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_running`

 * **Description:** Whether the [default connection](../replication-and-binary-log-system-variables/index#default_master_connection) slave is running (both I/O and SQL threads are running) or not.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slave_skipped_errors`

 * **Description:** The number of times a slave has skipped errors defined by [slave-skip-errors](../replication-and-binary-log-server-system-variables/index#slave_skip_errors).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slaves_connected`

 * **Description:** Number of slaves connected.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Slaves_running`

 * **Description:** Number of slave SQL threads running.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Transactions_gtid_foreign_engine`

 * **Description:** Number of replicated transactions where the update of the `gtid_slave_pos` table had to choose a storage engine that did not otherwise participate in the transaction. This can indicate that setting [gtid\_pos\_auto\_engines](../global-transaction-id/index#gtid_pos_auto_engines) might be useful. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `Transactions_multi_engine`

 * **Description:** Number of transactions that changed data in multiple (transactional) storage engines. If this is significantly larger than [Rpl\_transactions\_multi\_engine](#rpl_transactions_multi_engine), it indicates that setting <gtid_pos_auto_engines> could reduce the need for cross-engine transactions. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-and-binary-log-status-variables/>

Selectively Skipping Replication of Binlog Events
=================================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Normally, all changes that are logged as events in the [binary log](../binary-log/index) are also replicated to all replicas (though still subject to filtering by [replicate-do-db](../replication-and-binary-log-system-variables/index#replicate_do_db), [replicate-ignore-db](../replication-and-binary-log-system-variables/index#replicate_ignore_db), and similar options). However, sometimes it may be desirable to have certain events be logged into the binlog, but not be replicated to all or a subset of replicas, where the distinction between events that should be replicated or not is under the control of the application making the changes.

 This could be useful if an application does some replication external to the server outside of the built-in replication, or if it has some data that should not be replicated for whatever reason.

 This is possible with the following [system variables](../server-system-variables/index).

 Primary Session Variable: skip\_replication
-------------------------------------------

 When the [skip\_replication](../replication-and-binary-log-server-system-variables/index#skip_replication) variable is set to true, changes are logged into the [binary log](../binary-log/index) with the flag `@@skip_replication` set. Such events will not be replicated by replicas that run with `--replicate-events-marked-for-skip` set different from its default of `REPLICATE`.

 


|  |  |
| --- | --- |
| Variable Name | `skip_replication` |
| Scope | Session only |
| Access Type | Dynamic |
| Data Type | `bool` |
| Default Value | `OFF` |

 
The `skip_replication` option only has effect if [binary logging](../binary-log/index) is enabled and [sql\_log\_bin](../replication-and-binary-log-server-system-variables/index#skip_replication) is true.

 Attempting to change `@@skip_replication` in the middle of a transaction will fail; this is to avoid getting half of a transaction replicated while the other half is not replicated. Be sure to end any current transaction with `COMMIT`/`ROLLBACK` before changing the variable.

 Replica Option: --replicate-events-marked-for-skip
--------------------------------------------------

 The [replicate\_events\_marked\_for\_skip](../replication-and-binary-log-server-system-variables/index#replicate_events_marked_for_skip) option tells the replica whether to replicate events that are marked with the `@@skip_replication` flag. Default is `REPLICATE`, to ensure that all changes are replicated to the replica. If set to `FILTER_ON_SLAVE`, events so marked will be skipped on the replica and not replicated. If set to `FILTER_ON_MASTER`, the filtering will be done on the primary, saving on network bandwidth as the events will not be received by the replica at all.

 


|  |  |
| --- | --- |
| Variable Name | `replicate_events_marked_for_skip` |
| Scope | Global |
| Access Type | Dynamic |
| Data Type | enum: `REPLICATE` `|` `FILTER_ON_SLAVE` `|` `FILTER_ON_MASTER` |
| Default Value | `REPLICATE` |

 

**Note:** `replicate_events_marked_for_skip` is a dynamic variable (it can be changed without restarting the server), however the replica threads must be stopped when it is changed, otherwise an error will be thrown.

 
When events are filtered due to `@@skip_replication`, the filtering happens on the primary side; in other words, the event is never sent to the replica. If many events are filtered like this, a replica can sit a long time without receiving any events from the primary. This is not a problem in itself, but must be kept in mind when inquiring on the replica about events that are filtered. For example `START SLAVE UNTIL <some position>` will stop when the first event that is **not** filtered is encountered at the given position or beyond. If the event at the given position is filtered, then the replica thread will only stop when the next non-filtered event is encountered. In effect, if an event is filtered, to the replica it appears that it was never written to the binlog on the primary.

 Note that when events are filtered for a replica, the data in the database will be different on the replica and on the primary. It is the responsibility of the application to replicate the data outside of the built-in replication or otherwise ensure consistency of operation. If this is not done, it is possible for replication to encounter, for example, `[UNIQUE](../constraint_type-unique-constraint/index)` contraint violations or other problems which will cause replication to stop and require manual intervention to fix.

 The session variable `@@skip_replication` can be changed without requiring special privileges. This makes it possible for normal applications to control it without requiring `SUPER` privileges. But it must be kept in mind when using replicas with `--replicate-events-marked-for-skip` set different from `REPLICATE`, as it allows any connection to do changes that are not replicated.

 skip\_replication and sql\_log\_bin
-----------------------------------

 `[@@sql\_log\_bin](../set-sql_log_bin/index)` and `@@skip_replication` are somewhat related, as they can both be used to prevent a change on the primary from being replicated to the replica. The difference is that with `@@skip_replication`, changes are still written into the binlog, and replication of the events is only skipped on replicas that explicitly are configured to do so, with `--replicate-events-marked-for-skip` different from `REPLICATE`. With `@@sql_log_bin`, events are not logged into the binlog, and so are not replicated by any replica.

 skip\_replication and the Binlog
--------------------------------

 When events in the binlog are marked with the `@@skip_replication` flag, the flag will be preserved if the events are dumped by the [mariadb-binlog](../mariadb-binlog/index) program and re-applied against a server with the [mariadb client](../mariadb-command-line-client/index) program. Similarly, the [BINLOG](../binlog/index) statement will preserve the flag from the event being replayed. And a replica which runs with `--log-slave-updates` and does not filter events (`--replicate-events-marked-for-skip=REPLICATE`) will also preserve the flag in the events logged into the binlog on the replica.

 See Also
--------

 * [Using SQL\_SLAVE\_SKIP\_COUNTER](../set-global-sql_slave_skip_counter/index) - How to skip a number of events on the replica

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/selectively-skipping-replication-of-binlog-events/>

Binlog Event Checksums
======================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 MariaDB includes a feature to include a checksum in [binary log](../binary-log/index) events.

 Checksums are enabled with the [binlog\_checksum option](../replication-and-binary-log-server-system-variables/index#binlog_checksum). Until [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/), this was disabled by default. From [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/), the option is set to `CRC32`.

 The variable can be changed dynamically without restarting the server. Setting the variable in any way (even to the existing value) forces a rotation of the [binary log](../binary-log/index) (the intention is to avoid having a single binlog where some events are checksummed and others are not).

 When checksums are enabled, replication slaves will check events received over the network for checksum errors, and will stop with an error if a corrupt event is detected.

 In addition, the server can be configured to verify checksums in two other places.

 One is when reading events from the binlog on the master, for example when sending events to a slave or for something like SHOW BINLOG EVENTS. This is controlled by option master\_verify\_checksum, and is thus used to detect file system corruption of the binlog files.

 The other is when the slave SQL thread reads events from the [relay log](../relay-log/index). This is controlled by the slave\_sql\_verify\_checksum option, and is used to detect file system corruption of slave relay log files.

 `master_verify_checksum`

 * **Description:** Verify binlog checksums when reading events from the binlog on the master.
* **Commandline:** `--master_verify_checksum=[0|1]`
* **Scope:** Global
* **Access Type:** Can be changed dynamically
* **Data Type:** `bool`
* **Default Value:** `OFF (0)`

 `slave_sql_verify_checksum`

 * **Description:** Verify binlog checksums when the slave SQL thread reads events from the relay log.
* **Commandline:** `--slave_sql_verify_checksum=[0|1]`
* **Scope:** Global
* **Access Type:** Can be changed dynamically
* **Data Type:** `bool`
* **Default Value:** `ON (1)`

 The [mysqlbinlog](../mysqlbinlog/index) client program by default does not verify checksums when reading a binlog file, however it can be instructed to do so with the option verify-binlog-checksum:

 * **Variable Name:** `verify-binlog-checksum`
* **Data Type:** `bool`
* **Default Value:** `OFF`

 See Also
--------

 * [Binlog Event Checksum Interoperability](../binlog-event-checksum-interoperability/index)
* [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binlog-event-checksums/>

Binlog Event Checksum Interoperability
======================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 The introduction of [checksums on binlog events](../binlog-event-checksums/index) changes the format that events are stored in [binary log](../binary-log/index) files and sent over the network to replicas. This raises the question on what happens when replicating between different versions of the server, where one server is a newer version that has the binlog checksum feature implemented, while the other server is an older version that does not know about binlog checksums.

 When checksums are disabled on the primary (or the primary has the old version with no checksums implemented), there is no problem. In this case the binlog format is backwards compatible, and replication works fine.

 When the primary is a newer version with checksums enabled in the binlog, but the replica is an old version that does not understand checksums, replication will fail. The primary will disconnect the replica with an error, and also log a warning in its own error log. This prevents sending events to the replica that it will be unable to interpret correctly, but means that binlog checksums can not be used with older replicas. (With the recommended upgrade path, where replicas are upgraded before primaries, this is not a problem of course).

 Replicating from a new MySQL primary with checksums enabled to a new MariaDB which also understands checksums works, and the MariaDB replica will verify checksums on replicated events.

 There is however a problem when a newer MySQL replica replicates against a newer MariaDB primary with checksums enabled. The replica server looks at the primary server version to know whether events include checksums or not, and MySQL has not yet been updated to learn that MariaDB does this already from version 5.3.0 (as of the time of writing, MySQL 5.6.2). Thus, if MariaDB at least version 5.3.0 but less that 5.6.1 is used as a primary with binlog checksums enabled, a MySQL replica will interpret the received events incorrectly as it does not realise the last part of the events is the checksum. So replication will fail with an error about corrupt events or even silent corruption of replicated data in unlucky cases. This requires changes to the MySQL server to fix.

 Here is a summary table of the status of replication between different combination of primary and replica servers and checksum enabled/disabled:

 * **OLD:** MySQL <5.6.1 or MariaDB < 5.3.0 with no checksum capabilities
* **NEW-MARIA:** MariaDB >= 5.3.0 with checksum capabilities
* **NEW-MYSQL:** MySQL >= 5.6.1 with checksum capabilities

 


| Primary mariadb-lbinlog | Replica / enabled? | Checksums | Status |
| --- | --- | --- | --- |
| OLD | OLD | - | Ok |
| OLD | NEW-MARIA | - | Ok |
| OLD | MYSQL | - | Ok |
| NEW-MARIA | OLD | No | Ok |
| NEW-MARIA | OLD | Yes | Primary will refuse with error |
| NEW-MARIA | NEW-MARIA | Yes/No | Ok |
| NEW-MARIA | NEW-MYSQL | No | Ok |
| NEW-MARIA | NEW-MYSQL | Yes | Fail. Requires changes in MySQL, otherwise it will not realise MariaDB < 5.6.1 does checksums and will be confused. |
| NEW-MYSQL | OLD | No | Ok |
| NEW-MYSQL | OLD | Yes | Primary will refuse with error |
| NEW-MYSQL | NEW-MARIA | Yes/No | Ok |
| NEW-MYSQL | NEW-MYSQL | Yes/No | Ok |

 
Checksums and mariadb-binlog
----------------------------

 When using the [mariadb-binlog](../mariadb-binlog/index) client program, there are similar issues.

 A version of `mariadb-binlog` which understands checksums can read binlog files from either old or new servers, with or without checksums enabled.

 An old version of `mariadb-binlog` can read binlog files produced by a new server version **if** checksums were disabled when the log was produced. Old versions of `mariadb-binlog` reading a new binlog file containing checksums will be confused, and output will be garbled, with the added checksums being interpreted as extra garbage at the end of query strings and similar entries. No error will be reported in this case, just wrong output.

 A version of `mysqlbinlog` (the MySQL equivalent to mariadb-binlog and the old MariaDB name for the binary) from MySQL >= 5.6.1 will have similar problems as a replica until this is fixed in MySQL. When reading a binlog file with checksums produced by MariaDB >= 5.3.0 but < 5.6.1, it will not realise that checksums are included, and will produce garbled output just like an old version of `mysqlbinlog`. The MariaDB version of `mariadb-binlog` can read binlog files produced by either MySQL or MariaDB just fine.

 See Also
--------

 * [Binlog Event Checksums](../binlog-event-checksums/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binlog-event-checksum-interoperability/>

Error Log
=========

    The error log contains a record of critical errors that occurred during the server's operation, table corruption, start and stop information.

 SQL errors can also be logged in a separate file using the [SQL\_ERROR\_LOG plugin](../sql_error_log-plugin/index).

 Configuring the Error Log Output Destination
--------------------------------------------

 MariaDB always writes its error log, but the destination is configurable.

 ### Writing the Error Log to a File

 To configure the error log to be written to a file, you can set the [log\_error](../server-system-variables/index#log_error) system variable. You can configure a specific file name. However, if a specific file name is not configured, then the log will be written to the `${hostname}.err` file in the [datadir](../server-system-variables/index#datadir) directory by default.

 The [log\_error](../server-system-variables/index#log_error) system variable can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example, to write the error log to the default `${hostname}.err` file, you could configure the following:

 
```
[mariadb]
...
log_error

```

If you configure a specific file name as the [log\_error](../server-system-variables/index#log_error) system variable, and if it is not an absolute path, then it will be relative to the [datadir](../server-system-variables/index#datadir) directory. For example, if you configured the following, then the error log would be written to `mariadb.err` in the [datadir](../server-system-variables/index#datadir) directory:

 
```
[mariadb]
...
log_error=mariadb.err

```

If it is a relative path, then the [log\_error](../server-system-variables/index#log_error) is relative to the [datadir](../server-system-variables/index#datadir) directory.

 However, the [log\_error](../server-system-variables/index#log_error) system variable can also be an absolute path. For example:

 
```
[mariadb]
...
log_error=/var/log/mysql/mariadb.err

```

Another way to configure the error log file name is to set the [log-basename](../mysqld-options/index#-log-basename) option, which configures MariaDB to use a common prefix for all log files (e.g. [general query log](../general-query-log/index), [slow query log](../slow-query-log/index), error log, [binary logs](../binary-log/index), etc.). The error log file name will be built by adding a `.err` extension to this prefix. For example, if you configured the following, then the error log would still be written to `mariadb.err` in the [datadir](../server-system-variables/index#datadir) directory:

 
```
[mariadb]
...
log-basename=mariadb
log_error

```

The [log-basename](../mysqld-options/index#-log-basename) cannot be an absolute path. The log file name is relative to the [datadir](../server-system-variables/index#datadir) directory.

 ### Writing the Error Log to Stderr on Unix

 On Unix, if the [log\_error](../server-system-variables/index#log_error) system variable is not set, then errors are written to `stderr`, which usually means that the log messages are output to the terminal that started `mysqld`.

 If the [log\_error](../server-system-variables/index#log_error) system variable was set in an [option file](../configuring-mariadb-with-option-files/index) or on the command-line, then it can still be unset by specifying `--skip-log-error`.

 ### Writing the Error Log to Syslog on Unix

 On Unix, the error log can also be redirected to the [syslog](https://linux.die.net/man/8/rsyslogd). How this is done depends on how you [start](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB.

 #### Syslog with mysqld\_safe

 If you [start](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB with [mysqld\_safe](../mysqld_safe/index), then the error log can be redirected to the syslog. See [mysqld\_safe: Configuring MariaDB to Write the Error Log to Syslog](../mysqld_safe/index#configuring-mariadb-to-write-the-error-log-to-syslog) for more information.

 #### Syslog with Systemd

 If you [start](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB with [systemd](../systemd/index), then the error log can also be redirected to the syslog. See [Systemd: Configuring MariaDB to Write the Error Log to Syslog](../systemd/index#configuring-mariadb-to-write-the-error-log-to-syslog) for more information.

 [systemd](../systemd/index) also has its own logging system called the `journal`, and some errors may get logged there instead. See [Systemd:Systemd Journal](../systemd/index#systemd-journal) for more information.

 ### Writing the Error Log to Console on Windows

 On Windows, if the [console](../mysqld-options/index#-console) option is specified, and if the [log\_error](../server-system-variables/index#log_error) system variable is not used, then errors are written to the console. If both options are specified, then the last option takes precedence.

 ### Writing the Error Log to the Windows Event Viewer

 On Windows, error log messages are also written to the Windows Event Viewer. You can find MariaDB's error log messages by browsing **Windows Logs**, and then selecting **Application** or **Application Log**, depending on the Windows version.

 In [MariaDB 10.3](../what-is-mariadb-103/index) and before, you can find MariaDB's error log messages by searching for the **Source** `MySQL`.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you can find MariaDB's error log messages by searching for the **Source** `MariaDB`. 

 Finding the Error Log
---------------------

 To find where the error log is stored, one can find the options used for the error log with:

 
```
mariadbd --print-defaults

```

or

 
```
my_print_defaults --mysqld | grep log-error

```

If the above don't help, check also if your system is set to [write to syslog](../systemd/index#configuring-mariadb-to-write-the-error-log-to-syslog), in which case you need to use [journalctl](../systemd/index#systemd-journal) to access it.

 Configuring the Error Log Verbosity
-----------------------------------

 The default value of the [log\_warnings](../server-system-variables/index#log_warnings) system variable is `2`. 

 The [log\_warnings](../server-system-variables/index#log_warnings) system variable can be used to configure the verbosity of the error log. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_warnings=3;

```

It can also be set either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_warnings=3

```

Some of the warnings included in each verbosity level are described below.

 
The [log\_warnings](../server-system-variables/index#log_warnings) system variable only has an effect on some log messages. Some log messages are **always** written to the error log, regardless of the error log verbosity. For example, most warnings from the InnoDB storage engine are not affected by [log\_warnings](../server-system-variables/index#log_warnings). For a complete list of log messages affected by [log\_warnings](../server-system-variables/index#log_warnings), see the description of the [log\_warnings](../server-system-variables/index#log_warnings) system variable.

 
### Verbosity Level 0

 If [log\_warnings](../server-system-variables/index#log_warnings) is `0`, then many optional warnings will not be logged. However, this does not prevent all warnings from being logged, because there are certain core warnings that will always be written to the error log. For example:

 * If [InnoDB strict mode](../innodb-strict-mode/index) is disabled, and if DDL is performed on a table that triggers a ["Row size too large" error](../troubleshooting-row-size-too-large-errors-with-innodb/index), then InnoDB will log a warning:

 
```
[Warning] InnoDB: Cannot add field col25 in table db1.tab because after 
  adding it, the row size is 8477 which is greater than maximum allowed 
  size (8126) for a record on index leaf page.

```

However, if [InnoDB strict mode](../innodb-strict-mode/index) is enabled, then the same message will be logged as an error.

 ### Verbosity Level 1

 Default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/). If [log\_warnings](../server-system-variables/index#log_warnings) is `1`, then many types of warnings are logged. Some useful warnings are:

 * Replication-related messages:

 
```
[Note] Error reading relay log event: slave SQL thread was killed
[Note] Slave SQL thread exiting, replication stopped in log 
  'dbserver-2-bin.000033'   at position 181420; 
  GTID position '0-263316466-368886'
[Note] Slave I/O thread exiting, read up to log 
  'dbserver-2-bin.000034', position 642; 
  GTID position 0-263316466-368887

```

* Messages related to DNS lookup failures:

 
```
[Warning] IP address '192.168.1.193' 
  could not be resolved: Name or service not known

```

* Messages related to the [event scheduler](../event-scheduler/index):

 
```
[Note] Event Scheduler: Loaded 0 events

```

* Messages related to [unsafe statements for statement-based replication](../unsafe-statements-for-statement-based-replication/index):

 
```
[Warning] Unsafe statement written to the binary log using statement format since 
  BINLOG_FORMAT = STATEMENT. The statement is unsafe because 
  it uses a LIMIT clause. This 
  is unsafe because the set of rows included cannot be predicted.

```

Frequent warnings about [unsafe statements for statement-based replication](../unsafe-statements-for-statement-based-replication/index) can cause the error log to grow very large. MariaDB will automatically detect frequent duplicate warnings about [unsafe statements for statement-based replication](../unsafe-statements-for-statement-based-replication/index). After 10 identical warnings are detected, MariaDB will prevent that same warning from being written to the error log again for the next 5 minutes.

 ### Verbosity Level 2

 Default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/). If [log\_warnings](../server-system-variables/index#log_warnings) is `2`, then a couple other different kinds of warnings are printed. For example:

 * Messages related to access denied errors:

 
```
[Warning] Access denied for user 'root'@'localhost' (using password: YES)

```

* Messages related to connections that are aborted due to errors or timeouts:

 
```
[Warning] Aborted connection 35 to db: 'unconnected' user: 
  'user1@host1' host: '192.168.1.40' (Got an error writing communication packets)
[Warning] Aborted connection 36 to db: 'unconnected' user: 
  'user1@host2' host: '192.168.1.230' (Got an error writing communication packets)
[Warning] Aborted connection 38 to db: 'db1' user: 
  'user2' host: '192.168.1.60' (Unknown error) 
[Warning] Aborted connection 51 to db: 'db1' user: 
  'user2' host: '192.168.1.50' (Got an error reading communication packets)
[Warning] Aborted connection 52 to db: 'db1' user: 
  'user3' host: '192.168.1.53' (Got timeout reading communication packets)

```

* Messages related to table handler errors:

 
```
[Warning] Can't find record in 'tab1'.
[Warning] Can't write; duplicate key in table 'tab1'.
[Warning] Lock wait timeout exceeded; try restarting transaction.
[Warning] The number of locks exceeds the lock table size.
[Warning] Update locks cannot be acquired during a READ UNCOMMITTED transaction.

```

* Messages related to the files used to [persist replication state](../change-master-to/index#option-persistence):
	+ Either the default `master.info` file or the file that is configured by the [master\_info\_file](../mysqld-options/index#-master-info-file) option.
	+ Either the default `relay-log.info` file or the file that is configured by the [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable.

 
```
[Note] Reading Master_info: '/mariadb/data/master.info'  
  Relay_info:'/mariadb/data/relay-log.info'
[Note] Initialized Master_info from '/mariadb/data/master.info'
[Note] Reading of all Master_info entries succeded
[Note] Deleted Master_info file '/mariadb/data/master.info'.
[Note] Deleted Master_info file '/mariadb/data/relay-log.info'.

```

* Messages about a master's [binary log dump thread](../replication-threads/index#binary-log-dump-thread):

 
```
[Note] Start binlog_dump to slave_server(263316466), pos(, 4)

```

### Verbosity Level 3

 If [log\_warnings](../server-system-variables/index#log_warnings) is `3`, then a couple other different kinds of warnings are printed. For example:

 * Messages related to old-style language options:

 
```
[Warning] An old style --language value with language specific 
  part detected: /usr/local/mysql/data/
[Warning] Use --lc-messages-dir without language specific part instead.

```

* Messages related to [progress of InnoDB online DDL](https://mariadb.org/monitoring-progress-and-temporal-memory-usage-of-online-ddl-in-innodb/):

 
```
[Note] InnoDB: Online DDL : Start
[Note] InnoDB: Online DDL : Start reading clustered index of the table and 
  create temporary files
[Note] InnoDB: Online DDL : End of reading clustered index of the table and 
  create temporary files
[Note] InnoDB: Online DDL : Start merge-sorting index PRIMARY (1 / 3), 
  estimated cost : 18.0263
[Note] InnoDB: Online DDL : merge-sorting has estimated 33 runs
[Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 33 runs
[Note] InnoDB: Online DDL : merge-sorting current run 2 estimated 17 runs
[Note] InnoDB: Online DDL : merge-sorting current run 3 estimated 9 runs
[Note] InnoDB: Online DDL : merge-sorting current run 4 estimated 5 runs
[Note] InnoDB: Online DDL : merge-sorting current run 5 estimated 3 runs
[Note] InnoDB: Online DDL : merge-sorting current run 6 estimated 2 runs
[Note] InnoDB: Online DDL : End of  merge-sorting index PRIMARY (1 / 3)
[Note] InnoDB: Online DDL : Start building index PRIMARY (1 / 3), 
  estimated cost : 27.0395
[Note] InnoDB: Online DDL : End of building index PRIMARY (1 / 3)
[Note] InnoDB: Online DDL : Completed
[Note] InnoDB: Online DDL : Start merge-sorting index ux1 (2 / 3), 
  estimated cost : 5.7895
[Note] InnoDB: Online DDL : merge-sorting has estimated 2 runs
[Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 2 runs
[Note] InnoDB: Online DDL : End of  merge-sorting index ux1 (2 / 3)
[Note] InnoDB: Online DDL : Start building index ux1 (2 / 3), 
  estimated cost : 8.6842
[Note] InnoDB: Online DDL : End of building index ux1 (2 / 3)
[Note] InnoDB: Online DDL : Completed
[Note] InnoDB: Online DDL : Start merge-sorting index ix1 (3 / 3), 
  estimated cost : 6.1842
[Note] InnoDB: Online DDL : merge-sorting has estimated 3 runs
[Note] InnoDB: Online DDL : merge-sorting current run 1 estimated 3 runs
[Note] InnoDB: Online DDL : merge-sorting current run 2 estimated 2 runs
[Note] InnoDB: Online DDL : End of  merge-sorting index ix1 (3 / 3)
[Note] InnoDB: Online DDL : Start building index ix1 (3 / 3), 
  estimated cost : 9.2763
[Note] InnoDB: Online DDL : End of building index ix1 (3 / 3)
[Note] InnoDB: Online DDL : Completed

```

### Verbosity Level 4

 If [log\_warnings](../server-system-variables/index#log_warnings) is `4`, then a couple other different kinds of warnings are printed. For example:

 * Messages related to killed connections:

 
```
[Warning] Aborted connection 53 to db: 'db1' user: 
  'user2' host: '192.168.1.50' (KILLED)

```

* Messages related to **all** closed connections:

 
```
[Warning] Aborted connection 56 to db: 'db1' user: 
  'user2' host: '192.168.1.50' (CLOSE_CONNECTION)

```

* Messages related to released connections, such as when a transaction is committed and [completion\_type](../server-system-variables/index#completion_type) is set to `RELEASE`:

 
```
[Warning] Aborted connection 58 to db: 'db1' user: 
  'user2' host: '192.168.1.50' (RELEASE)

```

### Verbosity Level 9

 If [log\_warnings](../server-system-variables/index#log_warnings) is `9`, then some **very** verbose warnings are printed. For example:

 * Messages about initializing plugins:

 
```
[Note] Initializing built-in plugins
[Note] Initializing plugins specified on the command line
[Note] Initializing installed plugins

```

### MySQL's log\_error\_verbosity

 MariaDB does not support the [log\_error\_verbosity](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_log_error_verbosity) system variable added in MySQL 5.7.

 Format
------

 The format consists of the date (yyyy-mm-dd) and time, the thread ID, followed by the type of error (Note, Warning or Error) and the error message, for example:

 
```
2016-06-15 16:53:33 139651251140544 [Note] InnoDB: 
  The InnoDB memory heap is disabled

```

Until [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), the format only consisted of the date (yymmdd) and time, followed by the type of error (Note, Warning or Error) and the error message, for example:

 
```
160615 16:53:08 [Note] InnoDB: The InnoDB memory heap is disabled

```

Rotating the Error Log on Unix and Linux
----------------------------------------

 Unix and Linux distributions offer the [logrotate](https://linux.die.net/man/8/logrotate) utility, which makes it very easy to rotate log files. See [Rotating Logs on Unix and Linux](../rotating-logs-on-unix-and-linux/index) for more information on how to use this utility to rotate the error log.

 Error Messages File
-------------------

 Many error messages are ready from an error messages file that contains localized error messages. If the server can't find this file when it starts up, then you might see errors like the following:

 
```
[ERROR] Can't find messagefile '/usr/share/errmsg.sys'

```

If this error is occurring because the file is in a custom location, then you can configure this location by setting the [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) system variable either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
lc_messages_dir=/usr/share/mysql/

```

If you want to use a different locale for error messages, then you can also set the [lc\_messages](../server-system-variables/index#lc_messages) system variable. For example:

 
```
[mariadb]
...
lc_messages_dir=/usr/share/mysql/
lc_messages=en_US

```

See [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/error-log/>

Changing a Replica to Become the Primary
========================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   This article describes how to change a replica to become a primary and optionally to set the old primary as a replica for the new primary.

 A typical scenario of when this is useful is if you have set up a new version of MariaDB as a replica, for example for testing, and want to upgrade your primary to the new version.

 In MariaDB replication, a replica should be of a version same or newer than the primary. Because of this, one should first upgrades all replicas to the latest version before changing a replica to be a primary. In some cases one can have a replica to be of an older version than the primary, as long as one doesn't execute on the primary any SQL commands that the replica doesn't understand. This is however not guaranteed between all major MariaDB versions.

 Note that in the examples below, `[connection_name]` is used as the [name of the connection](../multi-source-replication/index). If you are not using named connections you can ignore this.

 ### Stopping the Original Master.

 First one needs to take down the original primary in such a way that the replica has all information on the primary.

 If you are using [Semisynchronous Replication](../semisynchronous-replication/index) you can just stop the server with the [SHUTDOWN](../shutdown/index) command as the replicas should be automatically up to date.

 If you are using [MariaDB MaxScale proxy](../maxscale/index), then you [can use MaxScale](https://mariadb.com/resources/blog/mariadb-maxscale-2-2-introducing-failover-switchover-and-automatic-rejoin) to handle the whole process of taking down the primary and replacing it with one of the replicas.

 If neither of the above is true, you have to do this step manually:

 #### Manually Take Down the Primary

 First we have to set the primary to read only to ensure that there are no new updates on the primary:

 
```
FLUSH TABLES WITH READ LOCK;

```

Note that you should not disconnect this session as otherwise the read lock will disappear and you have to start from the beginning.

 Then you should check the current position of the primary:

 
```
SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 |      343 |              |                  |
+--------------------+----------+--------------+------------------+
SELECT @@global.gtid_binlog_pos;
+--------------------------+
| @@global.gtid_binlog_pos |
+--------------------------+
| 0-1-2                    |
+--------------------------+

```

And wait until you have the same position on the replica: (The following should be excepted on the replica)

 
```
SHOW SLAVE [connection_name] STATUS;
+-------------------+-------------------+
Master_Log_File     | narttu-bin.000003 +
Read_Master_Log_Pos | 343               +
Exec_Master_Log_Pos | 343               +
...
Gtid_IO_Pos          0-1-2              +
+-------------------+-------------------+

```

The most important information to watch are `Master_Log_File` and `Exec_Master_Log_Pos` as when this matches the primary, it signals that all transactions has been committed on the replica.

 Note that `Gtid_IO_Pos` on replica can contain many different positions separated with ',' if the replica has been connected to many different primaries. What is important is that all the sequences that are on the primary is also on the replica.

 When replica is up to date, you can then take the **PRIMARY** down. This should be on the same connection where you executed [FLUSH TABLES WITH READ LOCK](../flush/index).

 
```
SHUTDOWN;

```

### Preparing the Replica to be a Primary

 Stop all old connections to the old primary(s) and reset **read only mode**, if you had it enabled. You also want to save the values of [SHOW MASTER STATUS](../show-master-status/index) and `gtid_binlog_pos`, as you may need these to setup new replicas.

 
```
STOP ALL SLAVES;
RESET SLAVE ALL;
SHOW MASTER STATUS;
SELECT @@global.gtid_binlog_pos;
SET @@global.read_only=0;

```

### Reconnect Other Replicas to the New Primary

 On the other replicas you have point them to the new primary (the replica you promoted to a primary).

 
```
STOP SLAVE [connection_name];
CHANGE MASTER [connection_name] TO MASTER_HOST="new_master_name",
MASTER_PORT=3306, MASTER_USER='root', MASTER_USE_GTID=current_pos,
MASTER_LOG_FILE="XXX", MASTER_LOG_POS=XXX;
START SLAVE;

```

The `XXX` values for `MASTER_LOG_FILE` and `MASTER_LOG_POS` should be the values you got from the `SHOW MASTER STATUS` command you did when you finished setting up the replica.

 ### Changing the Old Primary to be a Replica

 Now you can upgrade the new primary to a newer version of MariaDB and then follow the same procedure to connect it as a replica.

 When starting the original primary, it's good to start the `mysqld` executable with the `--with-skip-slave-start` and `--read-only` options to ensure that no old replica configurations could cause any conflicts.

 For the same reason it's also good to execute the following commands on the old primary (same as for other replicas, but with some extra security). The `read_only` option below is there to ensure that old applications doesn't by accident try to update the old primary by mistake. It only affects normal connections to the replica, not changes from the new primary.

 
```
set @@global.read_only=1;
STOP ALL SLAVES;
RESET MASTER;
RESET SLAVE ALL;
CHANGE MASTER [connection_name] TO MASTER_HOST="new_master_name",
MASTER_PORT=3306, MASTER_USER='root', MASTER_USE_GTID=current_pos,
MASTER_LOG_FILE="XXX", MASTER_LOG_POS=XXX;
START SLAVE;

```

### Moving Applications to Use New Primary

 You should now point your applications to use the new primary. If you are using the [MariaDB MaxScale proxy](../maxscale/index), then you don't have to do this step as MaxScale will take care of sending write request to the new primary.

 ### See Also

 * [CHANGE MASTER TO](../change-master-to/index) command
* [MaxScale Blog about using Switchover to swap a primary and replica](https://mariadb.com/resources/blog/mariadb-maxscale-2-2-introducing-failover-switchover-and-automatic-rejoin)
* [Percona blog about how to upgrade replica to primary](https://www.percona.com/blog/2015/12/01/upgrade-master-server-minimal-downtime)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/changing-a-replica-to-become-the-primary/>

Overview of MariaDB Logs
========================

    There are many variables in MariaDB that you can use to define what to log and when to log.

 This article will give you an overview of the different logs and how to enable/disable logging to these.

 Note that storage engines can have their logs too: for example, InnoDB keeps an [Undo Log](../undo-log/index) and a Redo Log which are used for rollback and crash recovery. However, this page only lists MariaDB server logs.

 ### [Error Log](../error-log/index)

 * Always enabled
* Usually a file in the data directory, but some distributions may move this to other locations.
* All critical errors are logged here.
* One can get warnings to be logged by setting [log\_warnings](../server-system-variables/index#log_warnings).
* With the [mysqld\_safe](../mysqld_safe/index) `--syslog` option one can duplicate the messages to the system's syslog.

 ### [General Query Log](../general-query-log/index)

 * Enabled with [--general-log](../server-system-variables/index#general_log)
* Logs all queries to a [file or table](../server-system-variables/index#log_output).
* Useful for debugging or auditing queries.
* The super user can disable logging to it for a connection by setting [SQL\_LOG\_OFF](../server-system-variables/index#sql_log_off) to 1.

 ### [Slow Query Log](../slow-query-log/index)

 * Enabled by starting mysqld with [--slow-query-log](../server-system-variables/index#slow_query_log)
* Logs all queries to a [file or table](../server-system-variables/index#log_output).
* Useful to find queries that causes performance problems.
* Logs all queries that takes more than [long\_query\_time](../server-system-variables/index#long_query_time) to run.
* One can decide what to log with the options [--log-slow-admin-statements](../server-system-variables/index#log_slow_admin_statements), [--log-slow-slave-statements](../server-system-variables/index#log_slow_slave_statements), [log\_slow\_filter](../server-system-variables/index#log_slow_filter) or [log\_slow\_rate\_limit](../server-system-variables/index#log_slow_rate_limit).
* One can change what is logged by setting [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity).
* One can disable it globally by setting [global.slow\_query\_log](../server-system-variables/index#slow_query_log) to 0
* In 10.1 one can disable it for a connection by setting [local.slow\_query\_log](../server-system-variables/index#slow_query_log) to 0.

 ### [Binary Log](../overview-of-the-binary-log/index)

 * Enabled by starting mysqld with [--log-bin](../replication-and-binary-log-server-system-variables/index#log_bin)
* Used on machines that are, or may become, replication masters.
* Required for point-in-time recovery.
* Binary log files are mainly used by replication and can also be used with [mariadb-binlog](../mariadb-binlog/index) to apply on a backup to get the database up to date.
* One can decide what to log with [--binlog-ignore-db=database\_name](../mysqld-options/index#-binlog-ignore-db) or [--binlog-do-db=database\_name](../mysqld-options/index#-binlog-do-db).
* The super user can disable logging for a connection by [setting SQL\_LOG\_BIN](../set-sql_log_bin/index) to 0. However while this is 0, no changes done in this connection will be replicated to the slaves!
* For examples, see [Using and Maintaining the Binary Log](../using-and-maintaining-the-binary-log/index).

 ### Examples

 If you know that your next query will be slow and you don't want to log it in the slow query log, do:

 
```
SET LOCAL SLOW_QUERY_LOG=0;

```

If you are a super user running a log batch job that you don't want to have logged (for example mariadb-dump), do:

 
```
SET LOCAL SQL_LOG_OFF=1, LOCAL SLOW_QUERY_LOG=0;

```

[mariadb-dump](../mariadb-dump/index) (previously mysqldump) since [MariaDB 10.1](../what-is-mariadb-101/index) will add this automatically to your dump file if you run it with the `--skip-log-queries` option.

 See Also
--------

 * [MariaDB audit plugin](../server_audit-mariadb-audit-plugin/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/overview-of-mariadb-logs/>

Annotate\_rows\_log\_event
==========================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

   `Annotate_rows` events accompany `row` events and describe the query which caused the row event.

 Until [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), the binlog event type `Annotate_rows_log_event` was off by default (so as not to change the binary log format and to allow one to replicate [MariaDB 5.3](../what-is-mariadb-53/index) to MySQL/[MariaDB 5.1](../what-is-mariadb-51/index)). You can enable this with `[--binlog-annotate-row-events](#master-option-binlog-annotate-row-events)`.

 In the [binary log](../mariadb-binlog/index), each `Annotate_rows` event precedes the corresponding Table map event or the first of the Table map events, if there are more than one (e.g. in a case of multi-delete or insert delayed).

 
`Annotate_rows` Example
------------------------

 
```
master> DROP DATABASE IF EXISTS test;
master> CREATE DATABASE test;
master> USE test;
master> CREATE TABLE t1(a int);
master> INSERT INTO t1 VALUES (1), (2), (3);
master> CREATE TABLE t2(a int);
master> INSERT INTO t2 VALUES (1), (2), (3);
master> CREATE TABLE t3(a int);
master> INSERT DELAYED INTO t3 VALUES (1), (2), (3);
master> DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
    ->        WHERE t1.a=t2.a AND t2.a=t3.a;  
    
master> SHOW BINLOG EVENTS IN 'master-bin.000001';  
+-------------------+------+---------------+-----------+-------------+---------------------------------------------------------------------------------+
| Log_name          | Pos  | Event_type    | Server_id | End_log_pos | Info                                                                            |
+-------------------+------+---------------+-----------+-------------+---------------------------------------------------------------------------------+
| master-bin.000001 |    4 | Format_desc   |       100 |         240 | Server ver: 5.5.20-MariaDB-mariadb1~oneiric-log, Binlog ver: 4                  |
| master-bin.000001 |  240 | Query         |       100 |         331 | DROP DATABASE IF EXISTS test                                                    |
| master-bin.000001 |  331 | Query         |       100 |         414 | CREATE DATABASE test                                                            |
| master-bin.000001 |  414 | Query         |       100 |         499 | use `test`; CREATE TABLE t1(a int)                                              |
| master-bin.000001 |  499 | Query         |       100 |         567 | BEGIN                                                                           |
| master-bin.000001 |  567 | Annotate_rows |       100 |         621 | INSERT INTO t1 VALUES (1), (2), (3)                                             |
| master-bin.000001 |  621 | Table_map     |       100 |         662 | table_id: 16 (test.t1)                                                          |
| master-bin.000001 |  662 | Write_rows    |       100 |         706 | table_id: 16 flags: STMT_END_F                                                  |
| master-bin.000001 |  706 | Query         |       100 |         775 | COMMIT                                                                          |
| master-bin.000001 |  775 | Query         |       100 |         860 | use `test`; CREATE TABLE t2(a int)                                              |
| master-bin.000001 |  860 | Query         |       100 |         928 | BEGIN                                                                           |
| master-bin.000001 |  928 | Annotate_rows |       100 |         982 | INSERT INTO t2 VALUES (1), (2), (3)                                             |
| master-bin.000001 |  982 | Table_map     |       100 |        1023 | table_id: 17 (test.t2)                                                          |
| master-bin.000001 | 1023 | Write_rows    |       100 |        1067 | table_id: 17 flags: STMT_END_F                                                  |
| master-bin.000001 | 1067 | Query         |       100 |        1136 | COMMIT                                                                          |
| master-bin.000001 | 1136 | Query         |       100 |        1221 | use `test`; CREATE TABLE t3(a int)                                              |
| master-bin.000001 | 1221 | Query         |       100 |        1289 | BEGIN                                                                           |
| master-bin.000001 | 1289 | Annotate_rows |       100 |        1351 | INSERT DELAYED INTO t3 VALUES (1), (2), (3)                                     |
| master-bin.000001 | 1351 | Table_map     |       100 |        1392 | table_id: 18 (test.t3)                                                          |
| master-bin.000001 | 1392 | Write_rows    |       100 |        1426 | table_id: 18 flags: STMT_END_F                                                  |
| master-bin.000001 | 1426 | Table_map     |       100 |        1467 | table_id: 18 (test.t3)                                                          |
| master-bin.000001 | 1467 | Write_rows    |       100 |        1506 | table_id: 18 flags: STMT_END_F                                                  |
| master-bin.000001 | 1506 | Query         |       100 |        1575 | COMMIT                                                                          |
| master-bin.000001 | 1575 | Query         |       100 |        1643 | BEGIN                                                                           |
| master-bin.000001 | 1643 | Annotate_rows |       100 |        1748 | DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a |
| master-bin.000001 | 1748 | Table_map     |       100 |        1789 | table_id: 16 (test.t1)                                                          |
| master-bin.000001 | 1789 | Table_map     |       100 |        1830 | table_id: 17 (test.t2)                                                          |
| master-bin.000001 | 1830 | Delete_rows   |       100 |        1874 | table_id: 16                                                                    |
| master-bin.000001 | 1874 | Delete_rows   |       100 |        1918 | table_id: 17 flags: STMT_END_F                                                  |
| master-bin.000001 | 1918 | Query         |       100 |        1987 | COMMIT                                                                          |
+-------------------+------+---------------+-----------+-------------+---------------------------------------------------------------------------------+

```

Options Related to Annotate\_rows\_log\_event
---------------------------------------------

 The following options have been added to control the behavior of `Annotate_rows_log_event`:

 ### Master Option: ``--`binlog-annotate-row-events`

 This option tells the master to write `Annotate_rows` events to the binary log. See [binlog\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events) for a detailed description of the variable.

 Session values allow you to annotate only some selected statements:

 
```
...
SET SESSION binlog_annotate_row_events=ON;
... statements to be annotated ...
SET SESSION binlog_annotate_row_events=OFF;
... statements not to be annotated ...

```

### Slave Option: ``--`replicate-annotate-row-events`

 This option tells the slave to reproduce `Annotate_row` events received from the master in its own binary log (sensible only when used in tandem with the `log-slave-updates` option).

 See [replicate\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#replicate_annotate_row_events) for a detailed description of the variable.

 ### mariadb-binlog Option: ``--`skip-annotate-row-events`

 This option tells [mariadb-binlog](../about-mariadb-binlog/index) to skip all `Annotate_row` events in its output (by default, mariadb-binlog prints `Annotate_row` events, if the binary log contains them). 

 Example of mariadb-binlog Output
--------------------------------

 
```
...> mariadb-binlog.exe -vv -R --user=root --port=3306 --host=localhost master-bin.000001  

/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#100516 15:36:00 server id 100  end_log_pos 240         Start: binlog v 4, server v 5.1.44-debug-log created 100516
 15:36:00 at startup
ROLLBACK/*!*/;
BINLOG '
oNjvSw9kAAAA7AAAAPAAAAAAAAQANS4xLjQ0LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAACg2O9LEzgNAAgAEgAEBAQEEgAA2QAEGggAAAAICAgCAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAA=
'/*!*/;
# at 240
#100516 15:36:18 server id 100  end_log_pos 331         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
SET @@session.pseudo_thread_id=1/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1
/*!*/;
SET @@session.sql_mode=0/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
DROP DATABASE IF EXISTS test
/*!*/;
# at 331
#100516 15:36:18 server id 100  end_log_pos 414         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
CREATE DATABASE test
/*!*/;
# at 414
#100516 15:36:18 server id 100  end_log_pos 499         Query   thread_id=1     exec_time=0     error_code=0
use test/*!*/;
SET TIMESTAMP=1274009778/*!*/;
CREATE TABLE t1(a int)
/*!*/;
# at 499
#100516 15:36:18 server id 100  end_log_pos 567         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
BEGIN
/*!*/;
# at 567
# at 621
# at 662
#100516 15:36:18 server id 100  end_log_pos 621         Annotate_rows:
#Q> INSERT INTO t1 VALUES (1), (2), (3)  
#100516 15:36:18 server id 100  end_log_pos 662         Table_map: `test`.`t1` mapped to number 16
#100516 15:36:18 server id 100  end_log_pos 706         Write_rows: table id 16 flags: STMT_END_F

BINLOG '
stjvSxNkAAAAKQAAAJYCAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE=
stjvSxdkAAAALAAAAMICAAAQABAAAAAAAAEAAf/+AQAAAP4CAAAA/gMAAAA=
'/*!*/;
### INSERT INTO test.t1
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO test.t1
### SET
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO test.t1
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
# at 706
#100516 15:36:18 server id 100  end_log_pos 775         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
COMMIT
/*!*/;
# at 775
#100516 15:36:18 server id 100  end_log_pos 860         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
CREATE TABLE t2(a int)
/*!*/;
# at 860
#100516 15:36:18 server id 100  end_log_pos 928         Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
BEGIN
/*!*/;
# at 928
# at 982
# at 1023
#100516 15:36:18 server id 100  end_log_pos 982         Annotate_rows:
#Q> INSERT INTO t2 VALUES (1), (2), (3)  
#100516 15:36:18 server id 100  end_log_pos 1023        Table_map: `test`.`t2` mapped to number 17
#100516 15:36:18 server id 100  end_log_pos 1067        Write_rows: table id 17 flags: STMT_END_F

BINLOG '
stjvSxNkAAAAKQAAAP8DAAAAABEAAAAAAAAABHRlc3QAAnQyAAEDAAE=
stjvSxdkAAAALAAAACsEAAAQABEAAAAAAAEAAf/+AQAAAP4CAAAA/gMAAAA=
'/*!*/;
### INSERT INTO test.t2
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO test.t2
### SET
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO test.t2
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
# at 1067
#100516 15:36:18 server id 100  end_log_pos 1136        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
COMMIT
/*!*/;
# at 1136
#100516 15:36:18 server id 100  end_log_pos 1221        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
CREATE TABLE t3(a int)
/*!*/;
# at 1221
#100516 15:36:18 server id 100  end_log_pos 1289        Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
BEGIN
/*!*/;
# at 1289
# at 1351
# at 1392
#100516 15:36:18 server id 100  end_log_pos 1351        Annotate_rows:
#Q> INSERT DELAYED INTO t3 VALUES (1), (2), (3)  
#100516 15:36:18 server id 100  end_log_pos 1392        Table_map: `test`.`t3` mapped to number 18
#100516 15:36:18 server id 100  end_log_pos 1426        Write_rows: table id 18 flags: STMT_END_F

BINLOG '
stjvSxNkAAAAKQAAAHAFAAAAABIAAAAAAAAABHRlc3QAAnQzAAEDAAE=
stjvSxdkAAAAIgAAAJIFAAAQABIAAAAAAAEAAf/+AQAAAA==
'/*!*/;
### INSERT INTO test.t3
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 1426
# at 1467
#100516 15:36:18 server id 100  end_log_pos 1467        Table_map: `test`.`t3` mapped to number 18
#100516 15:36:18 server id 100  end_log_pos 1506        Write_rows: table id 18 flags: STMT_END_F

BINLOG '
stjvSxNkAAAAKQAAALsFAAAAABIAAAAAAAAABHRlc3QAAnQzAAEDAAE=
stjvSxdkAAAAJwAAAOIFAAAQABIAAAAAAAEAAf/+AgAAAP4DAAAA
'/*!*/;
### INSERT INTO test.t3
### SET
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### INSERT INTO test.t3
### SET
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
# at 1506
#100516 15:36:18 server id 100  end_log_pos 1575        Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
COMMIT
/*!*/;
# at 1575
#100516 15:36:18 server id 100  end_log_pos 1643        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
BEGIN
/*!*/;
# at 1643
# at 1748
# at 1789
# at 1830
# at 1874
#100516 15:36:18 server id 100  end_log_pos 1748        Annotate_rows:
#Q> DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3
#Q>        WHERE t1.a=t2.a AND t2.a=t3.  
#100516 15:36:18 server id 100  end_log_pos 1789        Table_map: `test`.`t1` mapped to number 16
#100516 15:36:18 server id 100  end_log_pos 1830        Table_map: `test`.`t2` mapped to number 17
#100516 15:36:18 server id 100  end_log_pos 1874        Delete_rows: table id 16
#100516 15:36:18 server id 100  end_log_pos 1918        Delete_rows: table id 17 flags: STMT_END_F

BINLOG '
stjvSxNkAAAAKQAAAP0GAAAAABAAAAAAAAAABHRlc3QAAnQxAAEDAAE=
stjvSxNkAAAAKQAAACYHAAAAABEAAAAAAAAABHRlc3QAAnQyAAEDAAE=
stjvSxlkAAAALAAAAFIHAAAAABAAAAAAAAAAAf/+AQAAAP4CAAAA/gMAAAA=
### DELETE FROM test.t1
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM test.t1
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM test.t1
### WHERE
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
stjvSxlkAAAALAAAAH4HAAAQABEAAAAAAAEAAf/+AQAAAP4CAAAA/gMAAAA=
'/*!*/;
### DELETE FROM test.t2
### WHERE
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM test.t2
### WHERE
###   @1=2 /* INT meta=0 nullable=1 is_null=0 */
### DELETE FROM test.t2
### WHERE
###   @1=3 /* INT meta=0 nullable=1 is_null=0 */
# at 1918
#100516 15:36:18 server id 100  end_log_pos 1987        Query   thread_id=1     exec_time=0     error_code=0
SET TIMESTAMP=1274009778/*!*/;
COMMIT
/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mariadb-binlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

```

See Also
--------

 * [mariadb-binlog Options](../mariadb-binlog-options/index)
* [Replication and Binary Log Server System Variables](../replication-and-binary-log-server-system-variables/index)
* [Full List of MariaDB Options, System and Status Variables](../full-list-of-mariadb-options-system-and-status-variables/index)
* [mariadbd Options](../mariadbd-options/index)
* [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/annotate_rows_log_event/>

Row-based Replication With No Primary Key
=========================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 MariaDB improves on row-based [replication](../standard-replication/index) (see [binary log formats](../binary-log-formats/index)) of tables which have no primary key but do have some other index. This is based in part on the original Percona patch "row\_based\_replication\_without\_primary\_key.patch", with some additional fixes and enhancements.

 When row-based replication is used with [UPDATE](../update/index) or [DELETE](../delete/index), the slave needs to locate each replicated row based on the value in columns. If the table contains at least one index, an index lookup will be used (otherwise a table scan is needed for each row, which is extremely inefficient for all but the smallest table and generally to be avoided).

 In MariaDB, the slave will try to choose a good index among any available:

 * The primary key is used, if there is one.
* Else, the first unique index without NULL-able columns is used, if there is one.
* Else, a choice is made among any normal indexes on the table (e.g. a [FULLTEXT](../full-text-indexes/index) index is not considered).

 The choice of which of several non-unique indexes to use is based on the cardinality of indexes; the one that is most selective (has the smallest average number of rows per distinct tuple of column values) is preferred. Note that for this choice to be effective, for most storage engines (like MyISAM, InnoDB) it is necessary to make sure [ANALYZE TABLE](../analyze-table/index) has been run on the slave, otherwise statistics about index cardinality will not be available. In the absence of index cardinality, the first unique index will be chosen, if any, else the first non-unique index.

 Prior to [MariaDB 5.3](../what-is-mariadb-53/index), the slave would always choose the first index without considering cardinality. The slave could even choose an unusable index (like FULLTEXT) if no other index was available ([MySQL Bug #58997](http://bugs.mysql.com/bug.php?id=58997)), causing row-based replication to break in this case; this was also fixed in [MariaDB 5.3](../what-is-mariadb-53/index).

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/row-based-replication-with-no-primary-key/>

Replication Filters
===================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Replication filters allow users to configure [replicas](../replication-overview/index) to intentionally skip certain events.

 Binary Log Filters for Replication Primaries
--------------------------------------------

 MariaDB provides options that can be used on a [replication primary](../replication/index) to restrict local changes to specific databases from getting written to the [binary log](../binary-log/index), which also determines whether any replicas replicate those changes.

 ### Binary Log Filter Options

 The following options are available, and they are evaluated in the order that they are listed below. If there are conflicting settings, *binlog\_do\_db* prevails. Before [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), they are only available as options; from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) they are also available as system variables.

 #### `binlog_do_db`

 The [binlog\_do\_db](../mysqld-options/index#-binlog-do-db) option allows you to configure a [replication primary](../replication/index) to write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.

 This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 This option can **not** be set dynamically.

 When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times. For example:

 
```
[mariadb]
...
binlog_do_db=db1
binlog_do_db=db2

```

This will tell the primary to do the following:

 * Write statements and transactions affecting the database named *db1* into the [binary log](../binary-log/index).
* Write statements and transactions affecting the database named *db2* into the [binary log](../binary-log/index).
* Don't write statements and transactions affecting any other databases into the [binary log](../binary-log/index).

 #### `binlog_ignore_db`

 The [binlog\_ignore\_db](../mysqld-options/index#-binlog-ignore-db) option allows you to configure a [replication primary](../replication/index) to **not** write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.

 This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 This option can **not** be set dynamically.

 When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times. For example:

 
```
[mariadb]
...
binlog_ignore_db=db1
binlog_ignore_db=db2

```

This will tell the primary to do the following:

 * Don't write statements and transactions affecting the database named *db1* into the [binary log](../binary-log/index).
* Don't write statements and transactions affecting the database named *db2* into the [binary log](../binary-log/index).
* Write statements and transactions affecting any other databases into the [binary log](../binary-log/index).

 
The [binlog\_ignore\_db](#binlog_ignore_db) option is effectively ignored if the [binlog\_do\_db](#binlog_do_db) option is set, so those two options should not be set together.

 
Replication Filters for Replicas
--------------------------------

 MariaDB provides options and system variables that can be used on used on a [replicas](../replication/index) to filter events replicated in the [binary log](../binary-log/index).

 ### Replication Filter Options

 The following options and system variables are available, and they are evaluated in the order that they are listed below. If there are conflicting settings, the respective *replicate\_do\_* prevails.

 #### `replicate_rewrite_db`

 The [replicate\_rewrite\_db](../replication-and-binary-log-system-variables/index#replicate_rewrite_db) option (and, from [MariaDB 10.11](../what-is-mariadb-1011/index), system variable), allows you to configure a [replica](../replication/index) to rewrite database names. It uses the format `primary_database->replica_database`. If a replica encounters a [binary log](../binary-log/index) event in which the default database (i.e. the one selected by the [USE](../use/index) statement) is `primary_database`, then the replica will apply the event in `replica_database` instead.

 This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 This option only affects statements that involve tables. This option does not affect statements involving the database itself, such as [CREATE DATABASE](../create-database/index), [ALTER DATABASE](../alter-database/index), and [DROP DATABASE](../drop-database/index). 

 This option's rewrites are evaluated *before* any other replication filters configured by the `replicate_*` system variables.

 Statements that use table names qualified with database names do not work with other replication filters such as [replicate\_do\_table](#replicate_do_table).

 Until [MariaDB 10.11](../what-is-mariadb-1011/index), this option could not be set dynamically.

 When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times. For example:

 
```
[mariadb]
...
replicate_rewrite_db=db1->db3
replicate_rewrite_db=db2->db4

```

This will tell the replica to do the following:

 * If a [binary log](../binary-log/index) event is encountered in which the default database was *db1*, then apply the event in *db3* instead.
* If a [binary log](../binary-log/index) event is encountered in which the default database was *db2*, then apply the event in *db4* instead.

 See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_do_db`

 The [replicate\_do\_db](../replication-and-binary-log-server-system-variables/index#replicate_do_db) system variable allows you to configure a [replica](../replication/index) to apply statements and transactions affecting databases that match a specified name.

 This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging) or when using [mixed-based logging](../binary-log-formats/index#statement-based-logging) and the statement is logged statement based. For statement-based replication, only the default database (that is, the one selected by USE) is considered, not any explicitly mentioned tables in the query. See the [Statement-Based Logging](#statement-based-logging) section for more information.

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database names that contain commas. If you need to specify database names that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_do_db='db1,db2';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_do_db=db1
replicate_do_db=db2

```

This will tell the replica to do the following:

 * Replicate statements and transactions affecting the database named *db1*.
* Replicate statements and transactions affecting the database named *db2*.
* Ignore statements and transactions affecting any other databases.

 See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_ignore_db`

 The [replicate\_ignore\_db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db) system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions affecting databases that match a specified name.

 This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging) or when using [mixed-based logging](../binary-log-formats/index#statement-based-logging) and the statement is logged statement based. For statement-based replication, only the default database (that is, the one selected by USE) is considered, not any explicitly mentioned tables in the query. See the [Statement-Based Logging](#statement-based-logging) section for more information.

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database names that contain commas. If you need to specify names or patterns that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_ignore_db='db1,db2';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_ignore_db=db1
replicate_ignore_db=db2

```

This will tell the replica to do the following:

 * Ignore statements and transactions affecting databases named *db1*.
* Ignore statements and transactions affecting databases named *db2*.
* Replicate statements and transactions affecting any other databases.

 
The [replicate\_ignore\_db](#replicate_ignore_db) system variable is effectively ignored if the [replicate\_do\_db](#replicate_do_db) system variable is set, so those two system variables should not be set together.

 
See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_do_table`

 The [replicate\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_do_table) system variable allows you to configure a [replica](../replication/index) to apply statements and transactions that affect tables that match a specified name. The table name is specified in the format: `dbname.tablename`. 

 This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 This option only affects statements that involve tables. This option does not affect statements involving the database itself, such as [CREATE DATABASE](../create-database/index), [ALTER DATABASE](../alter-database/index), and [DROP DATABASE](../drop-database/index). 

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database or table names or patterns that contain commas. If you need to specify database or table names that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_do_table='db1.tab,db2.tab';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_do_table=db1.tab
replicate_do_table=db2.tab

```

This will tell the replica to do the following:

 * Replicate statements and transactions affecting tables in databases named *db1* and which are named *tab*.
* Replicate statements and transactions affecting tables in databases named *db2* and which are named *tab*.
* Ignore statements and transactions affecting any other tables.

 See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_ignore_table`

 The [replicate\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table) system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions that affect tables that match a specified name. The table name is specified in the format: `dbname.tablename`. 

 This system variable will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database or table names that contain commas. If you need to specify database or table names that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_ignore_table='db1.tab,db2.tab';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_ignore_table=db1.tab
replicate_ignore_table=db2.tab

```

This will tell the replica to do the following:

 * Ignore statements and transactions affecting tables in databases named *db1* and which are named *tab*.
* Ignore statements and transactions affecting tables in databases named *db2* and which are named *tab*.
* Replicate statements and transactions affecting any other tables.

 
The [replicate\_ignore\_table](#replicate_ignore_table) system variable is effectively ignored if either the [replicate\_do\_table](#replicate_do_table) system variable or the [replicate\_wild\_do\_table](#replicate_wild_do_table) system variable is set, so the [replicate\_ignore\_table](#replicate_ignore_table) system variable should not be used with those two system variables.

 
See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_wild_do_table`

 The [replicate\_wild\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table) system variable allows you to configure a [replica](../replication/index) to apply statements and transactions that affect tables that match a specified wildcard pattern.

 The wildcard pattern uses the same semantics as the [LIKE](../like/index) operator. This means that the the following characters have a special meaning:

 * `_` - The `_` character matches any single character.
* `%` - The `%` character matches zero or more characters.
* `\` - The `\` character is used to escape the other special characters in cases where you need the literal character.

 This system variable will work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 The system variable does filter databases, tables, [views](../views/index) and [triggers](../triggers/index).

 The system variable does not filter [stored procedures](../stored-procedures/index), [stored functions](../stored-functions/index), and [events](../stored-programs-and-views-events/index). The [replicate\_do\_db](../replication-and-binary-log-server-system-variables/index#replicate_do_db) system variable will need to be used to filter those.

 If the table name pattern for a filter is just specified as `%`, then all tables in the database will be matched. In this case, the filter will also affect certain database-level statements, such as [CREATE DATABASE](../create-database/index), [ALTER DATABASE](../alter-database/index) and [DROP DATABASE](../drop-database/index).

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database or table names or patterns that contain commas. If you need to specify database or table names or patterns that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_wild_do_table='db%.tab%,app1.%';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_wild_do_table=db%.tab%
replicate_wild_do_table=app1.%

```

This will tell the replica to do the following:

 * Replicate statements and transactions affecting tables in databases that start with *db* and whose table names start with *tab*.
* Replicate statements and transactions affecting the database named *app1*.
* Ignore statements and transactions affecting any other tables and databases.

 See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### `replicate_wild_ignore_table`

 The [replicate\_wild\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table) system variable allows you to configure a [replica](../replication/index) to ignore statements and transactions that affect tables that match a specified wildcard pattern.

 The wildcard pattern uses the same semantics as the [LIKE](../like/index) operator. This means that the the following characters have a special meaning:

 * `_` - The `_` character matches any single character.
* `%` - The `%` character matches zero or more characters.
* `\` - The `\` character is used to escape the other special characters in cases where you need the literal character.

 This system variable will work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](#statement-based-logging) section for more information.

 The system variable does filter databases, tables, [views](../views/index) and [triggers](../triggers/index).

 The system variable does not filter [stored procedures](../stored-procedures/index), [stored functions](../stored-functions/index), and [events](../stored-programs-and-views-events/index). The [replicate\_ignore\_db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db) system variable will need to be used to filter those.

 If the table name pattern for a filter is just specified as `%`, then all tables in the database will be matched. In this case, the filter will also affect certain database-level statements, such as [CREATE DATABASE](../create-database/index), [ALTER DATABASE](../alter-database/index) and [DROP DATABASE](../drop-database/index).

 When setting it dynamically with [SET GLOBAL](../set/index#global-session), the system variable accepts a comma-separated list of filters.

 When setting it dynamically, it is not possible to specify database or table names or patterns that contain commas. If you need to specify database or table names or patterns that contain commas, then you will need to specify them by either providing the command-line options or configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) when the server is [started](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index). 

 When setting it dynamically, the [replica threads](../replication-threads/index#threads-on-the-slave) must be stopped. For example:

 
```
STOP SLAVE;
SET GLOBAL replicate_wild_ignore_table='db%.tab%,app1.%';
START SLAVE;

```

When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the system variable does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the system variable multiple times. For example:

 
```
[mariadb]
...
replicate_wild_ignore_table=db%.tab%
replicate_wild_ignore_table=app1.%

```

This will tell the replica to do the following:

 * Ignore statements and transactions affecting tables in databases that start with *db* and whose table names start with *tab*.
* Ignore statements and transactions affecting all the tables in the database named *app1*.
* Replicate statements and transactions affecting any other tables and databases.

 
The [replicate\_ignore\_table](#replicate_wild_ignore_table) system variable is effectively ignored if either the [replicate\_do\_table](#replicate_do_table) system variable or the [replicate\_wild\_do\_table](#replicate_wild_do_table) system variable is set, so the [replicate\_ignore\_table](#replicate_wild_ignore_table) system variable should not be used with those two system variables.

 
See [Configuring Replication Filter Options with Multi-Source Replication](#configuring-replication-filter-options-with-multi-source-replication) for how to configure this system variable with [multi-source replication](../multi-source-replication/index).

 #### Configuring Replication Filter Options with Multi-Source Replication

 How you configure replication filters with [multi-source replication](../multi-source-replication/index) depends on whether you are configuring them dynamically or whether you are configuring them in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 ##### Setting Replication Filter Options Dynamically with Multi-Source Replication

 The usage of dynamic replication filters changes somewhat when [multi-source replication](../multi-source-replication/index) is in use. By default, the variables are addressed to the default connection, so in a multi-source environment, the required connection needs to be specified. There are two ways to do this.

 ###### Prefixing the Replication Filter Option with the Connection Name

 One way to change a replication filter for a multi-source connection is to explicitly specify the name when changing the filter. For example:

 
```
STOP SLAVE 'gandalf';
SET GLOBAL gandalf.replicate_do_table='database1.table1,database1.table2,database1.table3';
START SLAVE 'gandalf';

```

###### Changing the Default Connection

 Alternatively, the default connection can be changed by setting the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable, and then the replication filter can be changed in the usual fashion. For example:

 
```
SET default_master_connection = 'gandalf';
STOP SLAVE; 
SET GLOBAL replicate_do_table='database1.table1,database1.table2,database1.table3';
START SLAVE;

```

##### Setting Replication Filter Options in Option Files with Multi-Source Replication

 If you are using [multi-source replication](../multi-source-replication/index) and if you would like to make this filter persist server restarts by adding it to a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then the option file can also include the connection name that each filter would apply to. For example:

 
```
[mariadb]
...
gandalf.replicate_do_db=database1
saruman.replicate_do_db=database2

```

### CHANGE MASTER Options

 The [CHANGE MASTER](../change-master-to/index) statement has a few options that can be used to filter certain types of [binary log](../binary-log/index) events.

 #### `IGNORE_SERVER_IDS`

 The [IGNORE\_SERVER\_IDS](../change-master-to/index#ignore_server_ids) option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to ignore [binary log](binary_log) events that originated from certain servers. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 #### `DO_DOMAIN_IDS`

 The [DO\_DOMAIN\_IDS](../change-master-to/index#do_domain_ids) option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to only apply [binary log](binary_log) events if the transaction's [GTID](../global-transaction-id/index) is in a specific [gtid\_domain\_id](../gtid/index#gtid_domain_id) value. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 #### `IGNORE_DOMAIN_IDS`

 The [IGNORE\_DOMAIN\_IDS](../change-master-to/index#ignore_domain_ids) option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to ignore [binary log](binary_log) events if the transaction's [GTID](../global-transaction-id/index) is in a specific [gtid\_domain\_id](../gtid/index#gtid_domain_id) value. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 Replication Filters and Binary Log Formats
------------------------------------------

 The way that a replication filter is interpreted can depend on the [binary log format](../binary-log-formats/index).

 ### Statement-Based Logging

 When an event is logged in its statement-based format, many replication filters that affect a database will test the filter against the default database (i.e. the one selected by the [USE](../use/index) statement). This applies to the following replication filters:

 * [binlog\_do\_db](#binlog_do_db)
* [binlog\_ignore\_db](#binlog_ignore_db)
* [replicate\_rewrite\_db](#replicate_rewrite_db)
* [replicate\_do\_db](#replicate_do_db)
* [replicate\_ignore\_db](#replicate_ignore_db)

 When an event is logged in its statement-based format, many replication filters that affect a table will test the filter against the table in the default database (i.e. the one selected by the [USE](../use/index) statement). This applies to the following replication filters:

 * [replicate\_do\_table](#replicate_do_table)
* [replicate\_ignore\_table](#replicate_ignore_table)

 This means that cross-database updates **not** work with replication filters and statement-based binary logging. For example, if [replicate\_do\_table=db2.tab](replicate_do_table%3ddb2.tab) were set, then the following would not replicate with statement-based binary logging:

 
```
USE db1;
INSERT INTO db2.tab VALUES (1);

```

If you need to be able to support cross-database updates with replication filters and statement-based binary logging, then you should use the following replication filters:

 * [replicate\_wild\_do\_table](#replicate_wild_do_table)
* [replicate\_wild\_ignore\_table](#replicate_wild_ignore_table)

 ### Row-Based Logging

 When an event is logged in its row-based format, many replication filters that affect a database will test the filter against the database that is actually affected by the event.

 Similarly, when an event is logged in its row-based format, many replication filters that affect a table will test the filter against the table in the the database that is actually affected by the event.

 This means that cross-database updates work with replication filters and statement-based binary logging.

 
Keep in mind that DDL statements are always logged to the [binary log](../binary-log/index) in statement-based format, even when the [binlog\_format](../replication-and-binary-log-system-variables/index#binlog_format) system variable is set to `ROW`. This means that the notes mentioned in [Statement-Based Logging](#statement-based-logging) always apply to DDL.

 
Replication Filters and Galera Cluster
--------------------------------------

 When using Galera cluster, replication filters should be used with caution. See [Configuring MariaDB Galera Cluster: Replication Filters](../configuring-mariadb-galera-cluster/index#replication-filters) for more details.

 See Also
--------

 * [Dynamic replication filters — our wheel will be square!](https://mariadb.org/dynamic-replication-filters-our-wheel-will-be-square/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-filters/>

Running Triggers on the Replica for Row-based Events
====================================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  MariaDB can force the replica thread to run [triggers](../triggers/index) for row-based binlog events.

 The setting is controlled by the [slave\_run\_triggers\_for\_rbr](../replication-and-binary-log-server-system-variables/index#slave_run_triggers_for_rbr) global variable. It can be also specified as a command-line option or in my.cnf.

 Possible values are:

 


| Value | Meaning |
| --- | --- |
| NO (Default) | Don't invoke triggers for row-based events |
| YES | Invoke triggers for row-based events, don't log their effect into the binary log |
| LOGGING | Invoke triggers for row-based events, and log their effect into the binary log |
| ENFORCE | From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) only. Triggers will always be run on the replica, even if there are triggers on the master. ENFORCE implies LOGGING. |

 
**Note that if you just want to use triggers together with replication, you most likely don't need this option.** Read below for details.

 When to Use slave\_run\_triggers\_for\_rbr
------------------------------------------

 ### Background

 Normally, MariaDB's replication system can replicate trigger actions automatically. 

 * When one uses statement-based replication, the binary log contains SQL statements. Replica server(s) execute the SQL statements. Triggers are run on the master and on each replica, independently.
* When one uses row-based replication, the binary log contains row changes. It will have both the changes made by the statement itself, and the changes made by the triggers that were invoked by the statement. Replica server(s) do not need to run triggers for row changes they are applying.

 ### Target Usecase

 One may want to have a setup where a replica has triggers that are not present on the master (Suppose the replica needs to update summary tables or perform some other ETL-like process). 

 If one uses statement-based replication, they can just create the required triggers on the replica. The replica will run the statements from the binary log, which will cause the triggers to be invoked.

 However, there are cases where you have to use row-based replication. It could be because the master runs non-deterministic statements, or the master could be a node in a Galera cluster. In that case, you would want row-based events to invoke triggers on the replica. This is what the `slave_run_triggers_for_rbr` option is for. Setting the option to `YES` will cause the SQL replica thread to invoke triggers for row-based events; setting it to `LOGGING` will also cause the changes made by the triggers to be written into the binary log.

 The following triggers are invoked:

 * Update\_row\_event runs an UPDATE trigger
* Delete\_row\_event runs a DELETE trigger
* Write\_row\_event runs an INSERT trigger. Additionally it runs a DELETE trigger if there was a conflicting row that had to be deleted.

 Preventing Multiple Trigger Invocations
---------------------------------------

 There is a basic protection against triggers being invoked both on the master and replica. If the master modifies a table that has triggers, it will produce row-based binlog events with the "triggers were invoked for this event" flag. The replica will not invoke any triggers for flagged events.

 See Also
--------

 * Task in Jira, [MDEV-5095](https://jira.mariadb.org/browse/MDEV-5095).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-triggers-on-the-replica-for-row-based-events/>

Semisynchronous Replication
===========================

    Description
-----------

 [Standard MariaDB replication](../standard-replication/index) is asynchronous, but MariaDB also provides a semisynchronous replication option.

 With regular asynchronous replication, replicas request events from the primary's binary log whenever the replicas are ready. The primary does not wait for a replica to confirm that an event has been received.

 With fully synchronous replication, all replicas are required to respond that they have received the events. See [Galera Cluster](../galera-cluster/index).

 Semisynchronous replication waits for just one replica to acknowledge that it has received and logged the events. 

 Semisynchronous replication therefore comes with some negative performance impact, but increased data integrity. Since the delay is based on the roundtrip time to the replica and back, this delay is minimized for servers in close proximity over fast networks.

 In [MariaDB 10.3](../what-is-mariadb-103/index) and later, semisynchronous replication is built into the server, and is no longer a plugin so it can be enabled immediately in those versions. This removes some overhead and improves performance. See [MDEV-13073](https://jira.mariadb.org/browse/MDEV-13073) for more information.

 In [MariaDB 10.2](../what-is-mariadb-102/index) and before, semisynchronous replication requires the user to install a plugin on both the primary and the replica before it can be enabled.

 Installing the Plugin
---------------------

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) and later, the Semisynchronous Replication feature is built into MariaDB server and is no longer provided by a plugin. **This means that installing the plugin is not supported on those versions.** In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) and later, you can skip right to [Enabling Semisynchronous Replication](#enabling-semisynchronous-replication).

 
The semisynchronous replication plugin is actually two different plugins--one for the primary, and one for the replica. Shared libraries for both plugins are included with MariaDB. Although the plugins' shared libraries distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default prior to [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/). There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index).

 For example, if it's a primary:

 
```
INSTALL SONAME 'semisync_master';

```

Or if it's a replica:

 
```
INSTALL SONAME 'semisync_slave';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 For example, if it's a primary:

 
```
[mariadb]
...
plugin_load_add = semisync_master

```

Or if it's a replica:

 
```
[mariadb]
...
plugin_load_add = semisync_slave

```

Uninstalling the Plugin
-----------------------

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) and later, the Semisynchronous Replication feature is built into MariaDB server and is no longer provided by a plugin. **This means that uninstalling the plugin is not supported on those versions.**

 
You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index).

 For example, if it's a primary:

 
```
UNINSTALL SONAME 'semisync_master';

```

Or if it's a replica:

 
```
UNINSTALL SONAME 'semisync_slave';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Enabling Semisynchronous Replication
------------------------------------

 Semisynchronous replication can be enabled by setting the relevant system variables on the primary and the replica.

 If a server needs to be able to switch between acting as a primary and a replica, then you can enable both the primary and replica system variables on the server. For example, you might need to do this if [MariaDB MaxScale](../maxscale/index) is being used to enable [auto-failover or switchover](../mariadb-maxscale-23-mariadb-monitor/index#cluster-manipulation-operations) with [MariaDB Monitor](../mariadb-maxscale-23-mariadb-monitor/index).

 ### Enabling Semisynchronous Replication on the Primary

 Semisynchronous replication can be enabled on the primary by setting the [rpl\_semi\_sync\_master\_enabled](#rpl_semi_sync_master_enabled) system variable to `ON`. It can be set dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL rpl_semi_sync_master_enabled=ON;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
rpl_semi_sync_master_enabled=ON

```

### Enabling Semisynchronous Replication on the Replica

 Semisynchronous replication can be enabled on the replica by setting the [rpl\_semi\_sync\_slave\_enabled](#rpl_semi_sync_slave_enabled) system variable to `ON`. It can be set dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL rpl_semi_sync_slave_enabled=ON;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
rpl_semi_sync_slave_enabled=ON

```

If semisynchronous replication is enabled on a server when [replica threads](../replication-threads/index#threads-on-the-slave) were already running, the replica I/O thread will need to be restarted to enable the replica to register as a semisynchronous replica when it connects to the primary. For example:

 
```
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

```

If this is not done, and the replica thread is already running, then it will continue to use asynchronous replication.

 Configuring the Primary Timeout
-------------------------------

 In semisynchronous replication, only after the events have been written to the relay log and flushed does the replica acknowledge receipt of a transaction's events. If the replica does not acknowledge the transaction before a certain amount of time has passed, then a timeout occurs and the primary switches to asynchronous replication. This will be reflected in the primary's [error log](../error-log/index) with messages like the following: 

 
```
[Warning] Timeout waiting for reply of binlog (file: mariadb-1-bin.000002, pos: 538), semi-sync up to file , position 0.
[Note] Semi-sync replication switched OFF.

```

When this occurs, the [Rpl\_semi\_sync\_master\_status](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_status) status variable will be switched to `OFF`.

 When at least one semisynchronous replica catches up, semisynchronous replication is resumed. This will be reflected in the primary's [error log](../error-log/index) with messages like the following: 

 
```
[Note] Semi-sync replication switched ON with replica (server_id: 184137206) at (mariadb-1-bin.000002, 215076)

```

When this occurs, the [Rpl\_semi\_sync\_master\_status](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_status) status variable will be switched to `ON`.

 The number of times that semisynchronous replication has been switched off can be checked by looking at the value of the [Rpl\_semi\_sync\_master\_no\_times](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_times) status variable.

 If you see a lot of timeouts like this in your environment, then you may want to change the timeout period. The timeout period can be changed by setting the [rpl\_semi\_sync\_master\_timeout](#rpl_semi_sync_master_timeout) system variable. It can be set dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL rpl_semi_sync_master_timeout=20000;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
rpl_semi_sync_master_timeout=20000

```

To determine a good value for the [rpl\_semi\_sync\_master\_timeout](#rpl_semi_sync_master_timeout) system variable, you may want to look at the values of the [Rpl\_semi\_sync\_master\_net\_avg\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_net_avg_wait_time) and [Rpl\_semi\_sync\_master\_tx\_avg\_wait\_time](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_tx_avg_wait_time) status variables.

 Configuring the Primary Wait Point
----------------------------------

 In semisynchronous replication, there are two potential points at which the primary can wait for the replica acknowledge the receipt of a transaction's events. These two wait points have different advantages and disadvantages.

 The wait point is configured by the [rpl\_semi\_sync\_master\_wait\_point](#rpl_semi_sync_master_wait_point) system variable. The supported values are:

 * `AFTER_SYNC`
* `AFTER_COMMIT`

 It can be set dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL rpl_semi_sync_master_wait_point='AFTER_SYNC';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
rpl_semi_sync_master_wait_point=AFTER_SYNC

```

When this variable is set to `AFTER_SYNC`, the primary performs the following steps:

 1. Prepares the transaction in the storage engine.
2. Syncs the transaction to the [binary log](../binary-log/index).
3. Waits for acknowledgement from the replica.
4. Commits the transaction to the storage engine.
5. Returns an acknowledgement to the client.

 The effects of the `AFTER_SYNC` wait point are:

 * All clients see the same data on the primary at the same time; after acknowledgement by the replica and after being committed to the storage engine on the primary.

 * If the primary crashes, then failover should be lossless, because all transactions committed on the primary would have been replicated to the replica.

 * However, if the primary crashes, then its [binary log](../binary-log/index) may also contain events for transactions that were prepared by the storage engine and written to the binary log, but that were never actually committed by the storage engine. As part of the server's [automatic crash recovery](../heuristic-recovery-with-the-transaction-coordinator-log/index) process, the server may recover these prepared transactions when the server is restarted. This could cause the "old" crashed primary to become inconsistent with its former replicas when they have been reconfigured to replace the old primary with a new one. The old primary in such a scenario can be re-introduced only as a [semisync slave](index#rpl_semi_sync_slave_enabled). The server post-crash recovery of the server configured with `rpl_semi_sync_slave_enabled = ON` ensures through [MDEV-21117](https://jira.mariadb.org/browse/MDEV-21117) that the server will not have extra transactions. The reconfigured as semisync replica server's binlog gets truncated to discard transactions proven not to be committed, in any of their branches if they are multi-engine. Truncation does not occur though when there exists a non-transactional group of events beyond the truncation position in which case recovery reports an error. When the semisync replica recovery can't be carried out, the crashed primary may need to be rebuilt.

 When this variable is set to `AFTER_COMMIT`, the primary performs the following steps:

 1. Prepares the transaction in the storage engine.
2. Syncs the transaction to the [binary log](../binary-log/index).
3. Commits the transaction to the storage engine.
4. Waits for acknowledgement from the replica.
5. Returns an acknowledgement to the client.

 The effects of the `AFTER_COMMIT` wait point are:

 * Other clients may see the committed transaction before the committing client.

 * If the primary crashes, then failover may involve some data loss, because the primary may have committed transactions that had not yet been acknowledged by the replicas.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| N/A | N/A | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| 1.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| 1.0 | Unknown | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) |
| 1.0 | N/A | [MariaDB 5.5](../what-is-mariadb-55/index) |

 
System Variables
----------------

 #### `rpl_semi_sync_master_enabled`

 * **Description:** Set to `ON` to enable semi-synchronous replication primary. Disabled by default.
* **Commandline:** `--rpl-semi-sync-master-enabled[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rpl_semi_sync_master_timeout`

 * **Description:** The timeout value, in milliseconds, for semi-synchronous replication in the primary. If this timeout is exceeded in waiting on a commit for acknowledgement from a replica, the primary will revert to asynchronous replication.
	+ When a timeout occurs, the [Rpl\_semi\_sync\_master\_status](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_status) status variable will also be switched to `OFF`.
	+ See [Configuring the Primary Timeout](#configuring-the-primary-timeout) for more information.
* **Commandline:** `--rpl-semi-sync-master-timeout[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10000` (10 seconds)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rpl_semi_sync_master_trace_level`

 * **Description:** The tracing level for semi-sync replication. Four levels are defined:
	+ `1`: General level, including for example time function failures.
	+ `16`: More detailed level, with more verbose information.
	+ `32`: Net wait level, including more information about network waits.
	+ `64`: Function level, including information about function entries and exits.
* **Commandline:** `--rpl-semi-sync-master-trace-level[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rpl_semi_sync_master_wait_no_slave`

 * **Description:** If set to `ON`, the default, the replica count (recorded by [Rpl\_semi\_sync\_master\_clients](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_clients)) may drop to zero, and the primary will still wait for the timeout period. If set to `OFF`, the primary will revert to asynchronous replication as soon as the replica count drops to zero.
* **Commandline:** `--rpl-semi-sync-master-wait-no-slave[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rpl_semi_sync_master_wait_point`

 * **Description:** Whether the transaction should wait for semi-sync acknowledgement after having synced the binlog (`AFTER_SYNC`), or after having committed in storage engine (`AFTER_COMMIT`, the default).
	+ When this variable is set to `AFTER_SYNC`, the primary performs the following steps:
		1. Prepares the transaction in the storage engine.
		2. Syncs the transaction to the [binary log](../binary-log/index).
		3. Waits for acknowledgement from the replica.
		4. Commits the transaction to the storage engine.
		5. Returns an acknowledgement to the client.
	+ When this variable is set to `AFTER_COMMIT`, the primary performs the following steps:
		1. Prepares the transaction in the storage engine.
		2. Syncs the transaction to the [binary log](../binary-log/index).
		3. Commits the transaction to the storage engine.
		4. Waits for acknowledgement from the replica.
		5. Returns an acknowledgement to the client.
	+ In [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) and before, this system variable does not exist. However, in those versions, the primary waits for the acknowledgement from replicas at a point that is equivalent to `AFTER_COMMIT`.
	+ See [Configuring the Primary Wait Point](#configuring-the-primary-wait-point) for more information.
* **Commandline:** `--rpl-semi-sync-master-wait-point=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `AFTER_COMMIT`
* **Valid Values:** `AFTER_SYNC`, `AFTER_COMMIT`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `rpl_semi_sync_slave_delay_master`

 * **Description:** Only write primary info file when ack is needed.
* **Commandline:** `--rpl-semi-sync-slave-delay-master[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `rpl_semi_sync_slave_enabled`

 * **Description:** Set to `ON` to enable semi-synchronous replication replica. Disabled by default.
* **Commandline:** `--rpl-semi-sync-slave-enabled[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rpl_semi_sync_slave_kill_conn_timeout`

 * **Description:** Timeout for the mysql connection used to kill the replica io\_thread's connection on primary. This timeout comes into play when stop slave is executed.
* **Commandline:** `--rpl-semi-sync-slave-kill-conn-timeout[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `5`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `rpl_semi_sync_slave_trace_level`

 * **Description:** The tracing level for semi-sync replication. The levels are the same as for [rpl\_semi\_sync\_master\_trace\_level](#rpl_semi_sync_master_trace_level).
* **Commandline:** `--rpl-semi-sync-slave-trace_level[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32`
* **Range:** `0` to `18446744073709551615`

 

---

 Options
-------

 ### `rpl_semi_sync_master`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--rpl-semi-sync-master=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`
* **Removed:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 ### `rpl_semi_sync_slave`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--rpl-semi-sync-slave=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`
* **Removed:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 Status Variables
----------------

 For a list of status variables added when the plugin is installed, see [Semisynchronous Replication Plugin Status Variables](../semisynchronous-replication-plugin-status-variables/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/semisynchronous-replication/>

Using MariaDB Replication with MariaDB Galera Cluster
======================================================

  

| Title | Description |
| --- | --- |
|  [Using MariaDB Replication with MariaDB Galera Cluster](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index) |  Information on using MariaDB replication with MariaDB Galera Cluster.  |
|  [Using MariaDB GTIDs with MariaDB Galera Cluster](../using-mariadb-gtids-with-mariadb-galera-cluster/index) |  Information on using MariaDB's GTIDs with MariaDB Galera Cluster.  |
|  [Configuring MariaDB Replication between MariaDB Galera Cluster and MariaDB Server](../using-mariadb-replication-with-mariadb-galera-cluster-configuring-mariadb-r/index) |  Information on configuring replication between MariaDB Galera Cluster and MariaDB Server.  |
|  [Configuring MariaDB Replication between Two MariaDB Galera Clusters](../configuring-mariadb-replication-between-two-mariadb-galera-clusters/index) |  Information on configuring replication between two MariaDB Galera Clusters.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-replication-with-mariadb-galera-cluster/>

Delayed Replication
===================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

 
 Delayed replication allows specifying that a replica should lag behind the primary by (at least) a specified amount of time (specified in seconds). Before executing an event, the replica will first wait, if necessary, until the given time has passed since the event was created on the primary. The result is that the replica will reflect the state of the primary some time back in the past.

 The default is zero, or no delay, and the maximum value is 2147483647, or about 68 years.

 Delayed replication is enabled using the MASTER\_DELAY option to [CHANGE MASTER](../change-master-to/index):

 
```
  CHANGE MASTER TO master_delay=3600;

```

A zero delay disables delayed replication. The replica must be stopped when changing the delay value.

 Three fields in [SHOW SLAVE STATUS](../show-slave-status/index) are associated with delayed replication:

 1. SQL\_Delay: This is the value specified by MASTER\_DELAY in CHANGE MASTER (or 0 if none).
2. SQL\_Remaining\_Delay. When the replica is delaying the execution of an event due to MASTER\_DELAY, this is the number of seconds of delay remaining before the event will be applied. Otherwise, the value is NULL.
3. Slave\_SQL\_Running\_State. This shows the state of the SQL driver threads, same as in [SHOW PROCESSLIST](../show-processlist/index). When the replica is delaying the execution of an event due to MASTER\_DELAY, this fields displays: "Waiting until MASTER\_DELAY seconds after master executed event".

 When using older versions prior to [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), a 3rd party tool called [pt-slave-delay](https://www.percona.com/doc/percona-toolkit/LATEST/pt-slave-delay.html) can be used. It is part of the Percona Toolkit. Note that pt-slave-delay does not support MariaDB multi-channel replication syntax.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/delayed-replication/>

Replication When the Primary and Replica Have Different Table Definitions
=========================================================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  While replication is usually meant to take place between primaries and replicas with the same table definitions and this is recommended, in certain cases replication can still take place even if the definitions are identical.

 Tables on the replica and the primary do not need to have the same definition in order for [replication](../replication/index) to take place. There can be differing numbers of columns, or differing data definitions and, in certain cases, replication can still proceed.

 Different Column Definitions - Attribute Promotion and Demotion
---------------------------------------------------------------

 It is possible in some cases to replicate to a replica that has a column of a different type on the replica and the primary. This process is called attribute promotion (to a larger type) or attribute demotion (to a smaller type).

 The conditions differ depending on whether [statement-based](../binary-log-formats/index#statement-based) or [row-based replication](../binary-log-formats/index#row-based) is used.

 ### Statement-Based Replication

 When using [statement-based replication](../binary-log-formats/index#statement-based), generally, if a statement can run successfully on the replica, it will be replicated. If a column definition is the same or a larger type on the replica than on the primary, it can replicate successfully. For example a column defined as `[VARCHAR(10)](../varchar/index)` will successfully be replicated on a replica with a definition of `VARCHAR(12)`. 

 Replicating to a replica where the column is defined as smaller than on the primary can also work. For example, given the following table definitions:

 Master:

 
```
DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | tinyint(4)  | YES  |     | NULL    |       |
| v     | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

```

Slave

 
```
DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | tinyint(4)  | YES  |     | NULL    |       |
| v     | varchar(8) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

```

the statement

 
```
INSERT INTO r VALUES (6,'hi');

```

would successfully replicate because the value inserted into the `v` field can successfully be inserted on both the primary and the smaller replica equivalent.

 However, the following statement would fail:

 
```
INSERT INTO r VALUES (7,'abcdefghi')

```

In this case, the value fits in the primary definition, but is too long for the replica field, and so replication will fail.

 
```
SHOW SLAVE STATUS\G
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
...
Last_Errno: 1406
Last_Error: Error 'Data too long for column 'v' at row 1' on query. 
   Default database: 'test'. Query: 'INSERT INTO r VALUES (7,'abcdefghi')'
...

```

### Row-Based Replication

 When using [row-based replication](../binary-log-formats/index#row-based), the value of the [slave\_type\_conversions](../replication-and-binary-log-server-system-variables/index#slave_type_conversions) variable is important. The default value of this variable is empty, in which case MariaDB will not perform attribute promotion or demotion. If the column definitions do not match, replication will stop. If set to `ALL_NON_LOSSY`, safe replication is permitted. If set to `ALL_LOSSY` as well, replication will be permitted even if data loss takes place.

 For example:

 Master:

 
```
DESC r;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | smallint(6) | YES  |     | NULL    |       |
| v     | varchar(10) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

```

Slave:

 
```
SHOW VARIABLES LIKE 'slave_ty%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| slave_type_conversions |       |
+------------------------+-------+

 DESC r;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | tinyint(4) | YES  |     | NULL    |       |
| v     | varchar(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

```

The following query will fail:

 
```
INSERT INTO r VALUES (3,'c');

```


```
SHOW SLAVE STATUS\G;
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
...
Last_Errno: 1677
Last_Error: Column 0 of table 'test.r' cannot be converted from 
  type 'smallint' to type 'tinyint(4)'
...

```

By changing the value of the [slave\_type\_conversions](../replication-and-binary-log-server-system-variables/index#slave_type_conversions), replication can proceed:

 
```
SET GLOBAL slave_type_conversions='ALL_NON_LOSSY,ALL_LOSSY';

START SLAVE;

```


```
SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

```

#### Supported Conversions

 * Between [TINYINT](../tinyint/index), [SMALLINT](../smallint/index), [MEDIUMINT](../mediumint/index), [INT](../int/index) and [BIGINT](../bigint/index). If lossy conversion is supported, the value from the primary will be converted to the maximum or minimum permitted on the replica, which non-lossy conversions require the replica column to be large enough. For example, SMALLINT UNSIGNED can be converted to MEDIUMINT, but not SMALLINT SIGNED.

 Different Number or Order of Columns
------------------------------------

 Replication can also take place when the primary and replica have a different number of columns if the following criteria are met:

 * columns must be in the same order on the primary and replica
* common columns must be defined with the same data type
* extra columns must be defined after the common columns

 ### Row-Based

 The following example replicates incorrectly (replication proceeds, but the data is corrupted), as the columns are not in the same order.

 Master:

 
```
CREATE OR REPLACE TABLE r (i1 INT, i2 INT);

```

Slave:

 
```
ALTER TABLE r ADD i3 INT AFTER i1; 

```

Master:

 
```
INSERT INTO r (i1,i2) VALUES (1,1);

SELECT * FROM r;
+------+------+
| i1   | i2   |
+------+------+
|    1 |    1 |
+------+------+

```

Slave:

 
```
SELECT * FROM r;
+------+------+------+
| i1   | i3   | i2   |
+------+------+------+
|    1 |    1 | NULL |
+------+------+------+

```

### Statement-Based

 Using statement-based replication, the same example may work, even though the columns are not in the same order.

 Master:

 
```
CREATE OR REPLACE TABLE r (i1 INT, i2 INT);

```

Slave:

 
```
ALTER TABLE r ADD i3 INT AFTER i1; 

```

Master:

 
```
INSERT INTO r (i1,i2) VALUES (1,1);

SELECT * FROM r;
+------+------+
| i1   | i2   |
+------+------+
|    1 |    1 |
+------+------+

```

Slave:

 
```
 SELECT * FROM r;
+------+------+------+
| i1   | i3   | i2   |
+------+------+------+
|    1 | NULL |    1 |
+------+------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-when-the-primary-and-replica-have-different-table-definitions/>

Restricting Speed of Reading Binlog from Primary by a Replica
=============================================================

    When a replica starts after being stopped for some time, or a new replica starts that was created from a backup from some time back, a lot of old binlog events may need to be downloaded from the primary. If this happens from many replicas simultaneously, it can put a lot of load on the primary.

 The **read\_binlog\_speed\_limit** option can be used to reduce such load, by limiting the speed at which events are downloaded. The limit is given as maximum kilobytes per second to download on one replica connection.

 With this option set, the replication I/O thread will limit the rate of download. Since the I/O thread is often much faster to download events than the SQL thread is at applying them, an appropriate value for **read\_binlog\_speed\_limit** may reduce load spikes on the primary without much limit in the speed of the replica.

 The option **read\_binlog\_speed\_limit** is available starting from [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/).

 #### `read_binlog_speed_limit`

 * **Description:** Maximum speed(KB/s) to read binlog from primary.
* **Commandline:** `--read-binlog-speed-limit[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/restricting-speed-of-reading-binlog-from-primary-by-a-replica/>

Replication with Secure Connections
===================================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  By default, MariaDB replicates data between masters and slaves without encrypting it. This is generally acceptable when the master and slave run are in networks where security is guaranteed through other means. However, in cases where the master and slave exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt replicated data in transit between masters and slaves using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix `ssl_`, but internally, MariaDB only supports its secure successors.

 In order to secure connections between the master and slave, you need to ensure that both servers were compiled with TLS support. See [Secure Connections Overview](../secure-connections-overview/index) to determine how to check whether a server was compiled with TLS support.

 You also need an X509 certificate, a private key, and the Certificate Authority (CA) chain to verify the X509 certificate for the master. If you want to use two-way TLS, then you will also an X509 certificate, a private key, and the Certificate Authority (CA) chain to verify the X509 certificate for the slave. If you want to use self-signed certificates that are created with OpenSSL, then see [Certificate Creation with OpenSSL](../certificate-creation-with-openssl/index) for information on how to create those.

 Securing Replication Traffic
----------------------------

 In order to secure replication traffic, you will need to ensure that TLS is enabled on the master. If you want to use two-way TLS, then you will also need to ensure that TLS is enabled on the slave. See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to do that.

 For example, to set the TLS system variables for each server, add them to a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) on each server:

 
```
[mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/server-cert.pem
ssl_key = /etc/my.cnf.d/certificates/server-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem

```

And then [restart the server](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) to make the changes persistent.

 At this point, you can reconfigure the slaves to use TLS to encrypt replicated data in transit. There are two methods available to do this: 

 * Executing the `[CHANGE MASTER](../change-master-to/index)` statement to set the relevant TLS options.
* Setting TLS client options in an [option file](../configuring-mariadb-with-option-files/index).

 ### Executing CHANGE MASTER

 TLS can be enabled on a replication slave by executing the `[CHANGE MASTER](../change-master-to/index)` statement. In order to do so, there are a number of options that you would need to set. The specific options that you would need to set would depend on whether you want one-way TLS or two-way TLS, and whether you want to verify the server certificate.

 #### Enabling Two-Way TLS with CHANGE MASTER

 Two-way TLS means that both the client and server provide a private key and an X509 certificate. It is called "two-way" TLS because both the client and server can be authenticated. In this case, the "client" is the slave. To configure two-way TLS, you would need to set the following options:

 * You need to set the path to the server's certificate by setting the `[MASTER\_SSL\_CERT](../change-master-to/index#master_ssl_cert)` option.
* You need to set the path to the server's private key by setting the `[MASTER\_SSL\_KEY](../change-master-to/index#master_ssl_key)` option.
* You need to set the path to the certificate authority (CA) chain that can verify the server's certificate by setting either the `[MASTER\_SSL\_CA](../change-master-to/index#master_ssl_ca)` or the `[MASTER\_SSL\_CAPATH](../change-master-to/index#master_ssl_capath)` options.
* If you want [server certificate verification](../secure-connections-overview/index#server-certificate-verification), then you also need to set the `[MASTER\_SSL\_VERIFY\_SERVER\_CERT](../change-master-to/index#master_ssl_verify_server_cert)` option.
* If you want to restrict the server to certain ciphers, then you also need to set the `[MASTER\_SSL\_CIPHER](../change-master-to/index#master_ssl_cipher)` option.

 If the [slave threads](../replication-threads/index#threads-on-the-slave) are currently running, you first need to stop them by executing the `[STOP SLAVE](../stop-slave/index)` statement. For example:

 
```
STOP SLAVE;

```

Then, execute the `[CHANGE MASTER](../change-master-to/index)` statement to configure the slave to use TLS. For example:

 
```
CHANGE MASTER TO
   MASTER_SSL_CERT = '/path/to/client-cert.pem',
   MASTER_SSL_KEY = '/path/to/client-key.pem',
   MASTER_SSL_CA = '/path/to/ca/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;

```

At this point, you can start replication by executing the `[START SLAVE](../start-slave/index)` statement. For example:

 
```
START SLAVE;

```

The slave now uses TLS to encrypt data in transit as it replicates it from the master. 

 #### Enabling One-Way TLS with CHANGE MASTER

 ##### Enabling One-Way TLS with CHANGE MASTER with Server Certificate Verification

 One-way TLS means that only the server provides a private key and an X509 certificate. When TLS is used without a client certificate, it is called "one-way" TLS, because only the server can be authenticated, so authentication is only possible in one direction. However, encryption is still possible in both directions. [Server certificate verification](../secure-connections-overview/index#server-certificate-verification) means that the client verifies that the certificate belongs to the server. In this case, the "client" is the slave. To configure one-way TLS, you would need to set the following options:

 * You need to set the path to the certificate authority (CA) chain that can verify the server's certificate by setting either the `[MASTER\_SSL\_CA](../change-master-to/index#master_ssl_ca)` or the `[MASTER\_SSL\_CAPATH](../change-master-to/index#master_ssl_capath)` options.
* If you want [server certificate verification](../secure-connections-overview/index#server-certificate-verification), then you also need to set the `[MASTER\_SSL\_VERIFY\_SERVER\_CERT](../change-master-to/index#master_ssl_verify_server_cert)` option.
* If you want to restrict the server to certain ciphers, then you also need to set the `[MASTER\_SSL\_CIPHER](../change-master-to/index#master_ssl_cipher)` option.

 If the [slave threads](../replication-threads/index#threads-on-the-slave) are currently running, you first need to stop them by executing the `[STOP SLAVE](../stop-slave/index)` statement. For example:

 
```
STOP SLAVE;

```

Then, execute the `[CHANGE MASTER](../change-master-to/index)` statement to configure the slave to use TLS. For example:

 
```
CHANGE MASTER TO
   MASTER_SSL_CA = '/path/to/ca/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;

```

At this point, you can start replication by executing the `[START SLAVE](../start-slave/index)` statement. For example:

 
```
START SLAVE;

```

The slave now uses TLS to encrypt data in transit as it replicates it from the master. 

 ##### Enabling One-Way TLS with CHANGE MASTER without Server Certificate Verification

 One-way TLS means that only the server provides a private key and an X509 certificate. When TLS is used without a client certificate, it is called "one-way" TLS, because only the server can be authenticated, so authentication is only possible in one direction. However, encryption is still possible in both directions. In this case, the "client" is the slave. To configure two-way TLS without server certificate verification, you would need to set the following options:

 * You need to configure the slave to use TLS by setting the `[MASTER\_SSL](../change-master-to/index#master_ssl)` option.
* If you want to restrict the server to certain ciphers, then you also need to set the `[MASTER\_SSL\_CIPHER](../change-master-to/index#master_ssl_cipher)` option.

 If the [slave threads](../replication-threads/index#threads-on-the-slave) are currently running, you first need to stop them by executing the `[STOP SLAVE](../stop-slave/index)` statement. For example:

 
```
STOP SLAVE;

```

Then, execute the `[CHANGE MASTER](../change-master-to/index)` statement to configure the slave to use TLS. For example:

 
```
CHANGE MASTER TO
   MASTER_SSL=1;

```

At this point, you can start replication by executing the `[START SLAVE](../start-slave/index)` statement. For example:

 
```
START SLAVE;

```

The slave now uses TLS to encrypt data in transit as it replicates it from the master. 

 ### Setting TLS Client Options in an Option File

 In cases where you don't mind restarting the server or you are setting the server up from scratch for the first time, you may find it more convenient to configure TLS options for replication through an [option file](../configuring-mariadb-with-option-files/index). This is done the same way as it is for other clients. The specific options that you would need to set would depend on whether you want one-way TLS or two-way TLS, and whether you want to verify the server certificate. See [Securing Connections for Client and Server: Enabling TLS for MariaDB Clients](../securing-connections-for-client-and-server/index#enabling-tls-for-mariadb-clients) for more information.

 For example, to enable two-way TLS with [server certificate verification](../secure-connections-overview/index#server-certificate-verification), then you could specify the following options in a a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[client-mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/client-cert.pem
ssl_key = /etc/my.cnf.d/certificates/client-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl-verify-server-cert

```

Before you restart the server, you may also want to set the `[--skip-slave-start](../mysqld-options/index#-skip-slave-start)` option in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). This option prevents the [slave threads](../replication-threads/index#threads-on-the-slave) from restarting automatically when the server starts. Instead, they will have to be restarted manually.

 After these changes have been made, you can [restart the server](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Once the server is back online, set the `[MASTER\_SSL](../change-master-to/index#master_ssl)` option by executing the `[CHANGE MASTER](../change-master-to/index)` statement. This will enable TLS. For example:

 
```
CHANGE MASTER TO
   MASTER_SSL=1;

```

The certificate and keys will be read from the option file.

 At this point, you can start replication by executing the `[START SLAVE](../start-slave/index)` statement.

 
```
START SLAVE;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replication-with-secure-connections/>

Obsolete Replication Information
=================================

   This section is for replication-related items that are obsolete. The information in these articles is old or outdated, but rather than throwing it away, we're preserving it here.

  

| Title | Description |
| --- | --- |
|  [MariaDB 5.2 Replication Feature Preview](../mariadb-52-replication-feature-preview/index) |  OBSOLETE: Previewing MariaDB 5.3 replication features  |
|  [LOAD DATA FROM MASTER (removed)](../load-data-from-master-removed/index) |  Removed statement for loading the master with the slave's data  |
|  [LOAD TABLE FROM MASTER (removed)](../load-table-from-master-removed/index) |  Removed statement for loading a slave table from the master  |
|  [XtraDB option --innodb-release-locks-early](../xtradb-option-innodb-release-locks-early/index) |  Feature included only in the 5.2 replication preview  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/obsolete-replication-information/>

Setting the Language for Error Messages
=======================================

    MariaDB server error messages are by default in English. However, MariaDB server also supports error message [localization](../server-locale/index) in many different languages. Each supported language has its own version of the [error message file](../error-log/index#error-messages-file) called `errmsg.sys` in a dedicated directory for that language.

 Supported Languages for Error Messages
--------------------------------------

 Error message localization is supported for the following languages:

 * Bulgarian
* Chinese (from [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10425-release-notes/), [10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/), [10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), [10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/))
* Czech
* Danish
* Dutch
* English
* Estonian
* French
* Georgian (from [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/))
* German
* Greek
* Hindi
* Hungarian
* Italian
* Japanese
* Korean
* Norwegian
* Norwegian-ny (Nynorsk)
* Polish
* Portuguese
* Romanian
* Russian
* Serbian
* Slovak
* Spanish
* Swahili (from [MariaDB 11.1.2](https://mariadb.com/kb/en/mariadb-11-1-2-release-notes/))
* Swedish
* Ukrainian

 Setting the `lc_messages` and `lc_messages_dir` System Variables
----------------------------------------------------------------

 The [lc\_messages](../server-system-variables/index#lc_messages) and [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) system variables can be used to set the [server locale](../server-locale/index) used for error messages.

 The [lc\_messages](../server-system-variables/index#lc_messages) system variable can be specified as a [locale](../server-locale/index) name. The language of the associated [locale](../server-locale/index) will be used for error messages. See [Server Locales](../server-locale/index) for a list of supported locales and their associated languages.

 The [lc\_messages](../server-system-variables/index#lc_messages) system variable is set to `en_US` by default, which means that error messages are in English by default.

 If the `[lc\_messages](../server-system-variables/index#lc_messages)` system variable is set to a valid [locale](../server-locale/index) name, but the server can't find an [error message file](../error-log/index#error-messages-file) for the language associated with the [locale](../server-locale/index), then the default language will be used instead.

 This system variable can be specified as command-line arguments to [mariadbd](../mariadbd-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
lc_messages=fr_CA

```

The [lc\_messages](../server-system-variables/index#lc_messages) system variable can also be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL lc_messages='fr_CA';

```

If a server has the [lc\_messages](../server-system-variables/index#lc_messages) system variable set to the `fr_CA` locale like the above example, then error messages would be in French. For example:

 
```
SELECT blah;
ERROR 1054 (42S22): Champ 'blah' inconnu dans field list

```

The [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) system variable can be specified either as the path to the directory storing the server's [error message files](../error-log/index#error-messages-file) or as the path to the directory storing the specific language's [error message file](../error-log/index#error-messages-file). 

 The server initially tries to interpret the value of the `[lc\_messages\_dir](../server-system-variables/index#lc_messages_dir)` system variable as a path to the directory storing the server's [error message files](../error-log/index#error-messages-file). Therefore, it constructs the path to the language's [error message file](../error-log/index#error-messages-file) by concatenating the value of the [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) system variable with the language name of the [locale](../server-locale/index) specified by the [lc\_messages](../server-system-variables/index#lc_messages) system variable .

 If the server does not find the [error message file](../error-log/index#error-messages-file) for the language, then it tries to interpret the value of the [lc\_messages\_dir](../server-system-variables/index#lc_messages_dir) system variable as a direct path to the directory storing the specific language's [error message file](../error-log/index#error-messages-file).

 This system variable can be specified as command-line arguments to [mariadbd](../mariadbd-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 For example, to specify the path to the directory storing the server's [error message files](../error-log/index#error-messages-file):

 
```
[mariadb]
...
lc_messages_dir=/usr/share/mysql/

```

Or to specify the path to the directory storing the specific language's [error message file](../error-log/index#error-messages-file):

 
```
[mariadb]
...
lc_messages_dir=/usr/share/mysql/french/

```

The `[lc\_messages\_dir](../server-system-variables/index#lc_messages_dir)` system variable can not be changed dynamically.

 Setting the --language Option
-----------------------------

 The [--language](../mariadbd-options/index#-language) option can also be used to set the server's language for error messages, but it is deprecated. It is recommended to set the [lc\_messages](../server-system-variables/index#lc_messages) system variable instead.

 The [--language](../mariadbd-options/index#-language) option can be specified either as a language name or as the path to the directory storing the language's [error message file](../error-log/index#error-messages-file). See [Server Locales](../server-locale/index) for a list of supported locales and their associated languages.

 This option can be specified as command-line arguments to [mariadbd](../mariadbd-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 For example, to specify a language name:

 
```
[mariadb]
...
language=french

```

Or to specify the path to the directory storing the language's [error message file](../error-log/index#error-messages-file):

 
```
[mariadb]
...
language=/usr/share/mysql/french/

```

Character Set
-------------

 The character set that the error messages are returned in is determined by the [character\_set\_results](../server-system-variables/index#character_set_results) variable, which defaults to UTF8.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-the-language-for-error-messages/>

General Query Log
=================

    The general query log is a log of every SQL query received from a client, as well as each client connect and disconnect. Since it's a record of every query received by the server, it can grow large quite quickly.

 However, if you only want a record of queries that change data, it might be better to use the [binary log](../binary-log/index) instead. One important difference is that the [binary log](../binary-log/index) only logs a query when the transaction is committed by the server, but the general query log logs a query immediately when it is received by the server.

 Enabling the General Query Log
------------------------------

 The general query log is disabled by default. 

 To enable the general query log, set the `[general\_log](../server-system-variables/index#general_log)` system variable to `1`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL general_log=1;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
general_log

```

Configuring the General Query Log Filename
------------------------------------------

 By default, the general query log is written to `${hostname}.log` in the `[datadir](../server-system-variables/index#datadir)` directory. However, this can be changed.

 One way to configure the general query log filename is to set the `[general\_log\_file](../server-system-variables/index#general_log_file)` system variable. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL general_log_file='mariadb.log';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
general_log
general_log_file=mariadb.log

```

If it is a relative path, then the `[general\_log\_file](../server-system-variables/index#general_log_file)` is relative to the `[datadir](../server-system-variables/index#datadir)` directory.

 However, the `[general\_log\_file](../server-system-variables/index#general_log_file)` system variable can also be an absolute path. For example:

 
```
[mariadb]
...
general_log
general_log_file=/var/log/mysql/mariadb.log

```

Another way to configure the general query log filename is to set the `[log-basename](../mysqld-options/index#-log-basename)` option, which configures MariaDB to use a common prefix for all log files (e.g. general query log, [slow query log](../slow-query-log/index), [error log](../error-log/index), [binary logs](../binary-log/index), etc.). The general query log filename will be built by adding a `.log` extension to this prefix. This option cannot be set dynamically. It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log-basename=mariadb
general_log

```

The `[log-basename](../mysqld-options/index#-log-basename)` cannot be an absolute path. The log file name is relative to the `[datadir](../server-system-variables/index#datadir)` directory.

 Choosing the General Query Log Output Destination
-------------------------------------------------

 The general query log can either be written to a file on disk, or it can be written to the `[general\_log](../mysqlgeneral_log-table/index)` table in the `[mysql](../the-mysql-database-tables/index)` database. To choose the general query log output destination, set the `[log\_output](../server-system-variables/index#log_output)` system variable.

 ### Writing the General Query Log to a File

 The general query log is output to a file by default. However, it can be explicitly chosen by setting the `[log\_output](../server-system-variables/index#log_output)` system variable to `FILE`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL log_output='FILE';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
general_log
general_log_file=queries.log

```

### Writing the General Query Log to a Table

 The general query log can either be written to the `[general\_log](../mysqlgeneral_log-table/index)` table in the `[mysql](../the-mysql-database-tables/index)` database by setting the `[log\_output](../server-system-variables/index#log_output)` system variable to `TABLE`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL log_output='TABLE';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=TABLE
general_log

```

Some rows in this table might look like this:

 
```
SELECT * FROM mysql.general_log\G
*************************** 1. row ***************************
  event_time: 2014-11-11 08:40:04.117177
   user_host: root[root] @ localhost []
   thread_id: 74
   server_id: 1
command_type: Query
    argument: SELECT * FROM test.s
*************************** 2. row ***************************
  event_time: 2014-11-11 08:40:10.501131
   user_host: root[root] @ localhost []
   thread_id: 74
   server_id: 1
command_type: Query
    argument: SELECT * FROM mysql.general_log
...

```

See [Writing logs into tables](../writing-logs-into-tables/index) for more information.

 Disabling the General Query Log for a Session
---------------------------------------------

 A user with the [SUPER](../grant/index#global-privileges) privilege can disable logging to the general query log for a connection by setting the [SQL\_LOG\_OFF](../server-system-variables/index#sql_log_off) system variable to `1`. For example:

 
```
SET SESSION SQL_LOG_OFF=1;

```

Disabling the General Query Log for Specific Statements
-------------------------------------------------------

 In [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) and later, it is possible to disable logging to the general query log for specific types of statements by setting the `[log\_disabled\_statements](../server-system-variables/index#log_disabled_statements)` system variable. This option cannot be set dynamically. It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
general_log
general_log_file=queries.log
log_disabled_statements='slave,sp'

```

Rotating the General Query Log on Unix and Linux
------------------------------------------------

 Unix and Linux distributions offer the [logrotate](https://linux.die.net/man/8/logrotate) utility, which makes it very easy to rotate log files. See [Rotating Logs on Unix and Linux](../rotating-logs-on-unix-and-linux/index) for more information on how to use this utility to rotate the general query log.

 See Also
--------

 * [MariaDB audit plugin](../server_audit-mariadb-audit-plugin/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/general-query-log/>

Slow Query Log
===============

   The slow query log is a record of SQL queries that took a long time to perform.

  

| Title | Description |
| --- | --- |
|  [Slow Query Log Overview](../slow-query-log-overview/index) |  A record of SQL queries that took a long time to perform.  |
|  [Slow Query Log Extended Statistics](../slow-query-log-extended-statistics/index) |  The slow query log makes extended statistics available.  |
|  [mysqldumpslow](../mysqldumpslow/index) |  Symlink or old name for mariadb-dumpslow.  |
|  [EXPLAIN in the Slow Query Log](../explain-in-the-slow-query-log/index) |  EXPLAIN output in the slow query log.  |
|  [mysql.slow\_log Table](../mysqlslow_log-table/index) |  Contents of the slow query log if written to table.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slow-query-log/>

Rotating Logs on Unix and Linux
===============================

    Unix and Linux distributions offer the `[logrotate](https://linux.die.net/man/8/logrotate)` utility, which makes it very easy to rotate log files. This page will describe how to configure log rotation for the [error log](../error-log/index), [general query log](../general-query-log/index), and the [slow query log](../slow-query-log/index).

 Configuring Locations and File Names of Logs
--------------------------------------------

 The first step is to configure the locations and file names of logs. To make the log rotation configuration easier, it can be best to put these logs in a dedicated log directory.

 We will need to configure the following:

 * The [error log](../error-log/index) location and file name is configured with the `[log\_error](../server-system-variables/index#log_error)` system variable.
* The [general query log](../general-query-log/index) location and file name is configured with the `[general\_log\_file](../server-system-variables/index#general_log_file)` system variable.
* The [slow query log](../slow-query-log/index) location and file name is configured with the `[slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file)` system variable.

 If you want to enable the [general query log](../general-query-log/index) and [slow query log](../slow-query-log/index) immediately, then you will also have to configure the following:

 * The [general query log](../general-query-log/index) is enabled with the `[general\_log](../server-system-variables/index#general_log)` system variable.
* The [slow query log](../slow-query-log/index) is enabled with the `[slow\_query\_log](../server-system-variables/index#slow_query_log)` system variable.

 These options can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example, if we wanted to put our log files in `/var/log/mysql/`, then we could configure the following:

 
```
[mariadb]
...
log_error=/var/log/mysql/mariadb.err
general_log
general_log_file=/var/log/mysql/mariadb.log
slow_query_log
slow_query_log_file=/var/log/mysql/mariadb-slow.log
long_query_time=5

```

We will also need to create the relevant directory:

 
```
sudo mkdir /var/log/mysql/
sudo chown mysql:mysql /var/log/mysql/
sudo chmod 0770 /var/log/mysql/

```

If you are using [SELinux](../selinux/index), then you may also need to set the SELinux context for the directory. See [SELinux: Setting the File Context for Log Files](../selinux/index#setting-the-file-context-for-log-files) for more information. For example:

 
```
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?"
sudo restorecon -Rv /var/log/mysql

```

After MariaDB is [restarted](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index), it will use the new log locations and file names.

 Configuring Authentication for Logrotate
----------------------------------------

 The `[logrotate](https://linux.die.net/man/8/logrotate)` utility needs to be able to authenticate with MariaDB in order to flush the log files.

 The easiest way to allow the `[logrotate](https://linux.die.net/man/8/logrotate)` utility to authenticate with MariaDB is to configure the `root@localhost` user account to use `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the `root@localhost` user account is configured to use `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication by default, so this part can be skipped in those versions.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, a user account is only able to have one authentication method at a time. In these versions, this means that once you enable `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication for the `root@localhost` user account, you will no longer be able to use a password to log in with that user account. The user account will only be able to use `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication.

 
In [MariaDB 10.3](../what-is-mariadb-103/index) and before, you need to [install the unix\_socket plugin](../authentication-plugin-unix-socket/index#installing-the-plugin) before you can configure the `root@localhost` user account to use it. For example:

 
```
INSTALL SONAME 'auth_socket';

```

After the plugin is installed, the `root@localhost` user account can be configured to use `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication. How this is done depends on the version of MariaDB.

 The `root@localhost` user account can be altered to use [unix\_socket](../authentication-plugin-unix-socket/index) authentication with the [ALTER USER](../alter-user/index) statement. For example:

 
```
ALTER USER 'root'@'localhost' IDENTIFIED VIA unix_socket;

```

<</product>>

 Configuring Logrotate
---------------------

 At this point, we can configure the `[logrotate](https://linux.die.net/man/8/logrotate)` utility to rotate the log files.

 On many systems, the primary `[logrotate](https://linux.die.net/man/8/logrotate)` configuration file is located at the following path:

 * `/etc/logrotate.conf`

 And the `[logrotate](https://linux.die.net/man/8/logrotate)` configuration files for individual services are located in the following directory:

 * `/etc/logrotate.d/`

 We can create a `[logrotate](https://linux.die.net/man/8/logrotate)` configuration file for MariaDB by executing the following command in a shell:

 
```
$ sudo tee /etc/logrotate.d/mariadb <<EOF
/var/log/mysql/* {
        su mysql mysql
        missingok
        create 660 mysql mysql
        notifempty
        daily
        minsize 1M # only use with logrotate >= 3.7.4
        maxsize 100M # only use with logrotate >= 3.8.1
        rotate 30
        # dateext # only use if your logrotate version is compatible with below dateformat
        # dateformat .%Y-%m-%d-%H-%M-%S # only use with logrotate >= 3.9.2
        compress
        delaycompress
        sharedscripts 
        olddir archive/
        createolddir 770 mysql mysql # only use with logrotate >= 3.8.9
    postrotate
        # just if mysqld is really running
        if test -x /usr/bin/mysqladmin && \
           /usr/bin/mysqladmin ping &>/dev/null
        then
           /usr/bin/mysqladmin --local flush-error-log \
              flush-engine-log flush-general-log flush-slow-log
        fi
    endscript
}
EOF

```


You may have to modify this configuration file to use it on your system, depending on the specific version of the `[logrotate](https://linux.die.net/man/8/logrotate)` utility that is installed. See the description of each configuration directive below to determine which `[logrotate](https://linux.die.net/man/8/logrotate)` versions support that configuration directive.

 
Each specific configuration directive does the following:

 * **`missingok`**: This directive configures it to ignore missing files, rather than failing with an error.
* **`create 660 mysql mysql`**: This directive configures it to recreate the log files after log rotation with the specified permissions and owner.
* **`notifempty`**: This directive configures it to skip a log file during log rotation if it is empty.
* **`daily`**: This directive configures it to rotate each log file once per day.
* **`minsize 1M`**: This directive configures it to skip a log file during log rotation if it is smaller than 1 MB. This directive is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.7.4 and later.
* **`maxsize 100M`**: This directive configures it to rotate a log file more frequently than daily if it grows larger than 100 MB. This directive is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.8.1 and later.
* **`rotate 30`**: This directive configures it to keep 30 old copies of each log file.
* **`dateext`**: This directive configures it to use the date as an extension, rather than just a number. This directive is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.7.6 and later.
* **`dateformat .%Y-%m-%d-%H-%M-%S`**: This directive configures it to use this date format string (as defined by the format specification for `[strftime](https://linux.die.net/man/3/strftime)`) for the date extension configured by the `dateext` directive. This directive is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.7.7 and later. Support for `%H` is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.9.0 and later. Support for `%M` and `%S` is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.9.2 and later.
* **`compress`**: This directive configures it to compress the log files with `[gzip](https://linux.die.net/man/1/gzip)`.
* **`delaycompress`**: This directive configures it to delay compression of each log file until the next log rotation. If the log file is compressed at the same time that it is rotated, then there may be cases where a log file is being compressed while the MariaDB server is still writing to the log file. Delaying compression of a log file until the next log rotation can prevent race conditions such as these that can happen between the compression operation and the MariaDB server's log flush operation.
* **`olddir archive/`**: This directive configures it to archive the rotated log files in `/var/log/mysql/archive/`.
* **`createolddir 770 mysql mysql`**: This directive configures it to create the directory specified by the `olddir` directive with the specified permissions and owner, if the directory does not already exist. This directive is only available with `[logrotate](https://linux.die.net/man/8/logrotate)` 3.8.9 and later.
* **`sharedscripts`**: This directive configures it to run the `postrotate` script just once, rather than once for each rotated log file.
* **`postrotate`**: This directive configures it to execute a script after log rotation. This particular script executes the [mariadb-admin](../mariadb-admin/index) utility, which executes the [FLUSH](../flush/index) statement, which tells the MariaDB server to flush its various log files. When MariaDB server flushes a log file, it closes its existing file handle and reopens a new one. This ensure that MariaDB server does not continue writing to a log file after it has been rotated. This is an important component of the log rotation process.

 If our system does not have `[logrotate](https://linux.die.net/man/8/logrotate)` 3.8.9 or later, which is needed to support the `createolddir` directive, then we will also need to create the relevant directory specified by the `olddir` directive:

 
```
sudo mkdir /var/log/mysql/archive/
sudo chown mysql:mysql /var/log/mysql/archive/
sudo chmod 0770 /var/log/mysql/archive/

```

Testing Log Rotation
--------------------

 We can test log rotation by executing the `[logrotate](https://linux.die.net/man/8/logrotate)` utility with the `--force` option. For example:

 
```
sudo logrotate --force /etc/logrotate.d/mariadb

```

Keep in mind that under normal operation, the `[logrotate](https://linux.die.net/man/8/logrotate)` utility may skip a log file during log rotation if the utility does not believe that the log file needs to be rotated yet. For example:

 * If you set the `notifempty` directive mentioned above, then it will be configured to skip a log file during log rotation if the log file is empty.
* If you set the `daily` directive mentioned above, then it will be configured to only rotate each log file once per day.
* If you set the `minsize 1M` directive mentioned above, then it will be configured to skip a log file during log rotation if the log file size is smaller than 1 MB.

 However, when running tests with the `--force` option, the `[logrotate](https://linux.die.net/man/8/logrotate)` utility does not take these options into consideration.

 After a few tests, we can see that the log rotation is indeed working:

 
```
$ sudo ls -l /var/log/mysql/archive/
total 48
-rw-rw---- 1 mysql mysql  440 Mar 31 15:31 mariadb.err.1
-rw-rw---- 1 mysql mysql  138 Mar 31 15:30 mariadb.err.2.gz
-rw-rw---- 1 mysql mysql  145 Mar 31 15:28 mariadb.err.3.gz
-rw-rw---- 1 mysql mysql 1007 Mar 31 15:27 mariadb.err.4.gz
-rw-rw---- 1 mysql mysql 1437 Mar 31 15:32 mariadb.log.1
-rw-rw---- 1 mysql mysql  429 Mar 31 15:31 mariadb.log.2.gz
-rw-rw---- 1 mysql mysql  439 Mar 31 15:28 mariadb.log.3.gz
-rw-rw---- 1 mysql mysql  370 Mar 31 15:27 mariadb.log.4.gz
-rw-rw---- 1 mysql mysql 3915 Mar 31 15:32 mariadb-slow.log.1
-rw-rw---- 1 mysql mysql  554 Mar 31 15:31 mariadb-slow.log.2.gz
-rw-rw---- 1 mysql mysql  569 Mar 31 15:28 mariadb-slow.log.3.gz
-rw-rw---- 1 mysql mysql  487 Mar 31 15:27 mariadb-slow.log.4.gz

```

Logrotate in Ansible
--------------------

 Let's see an example of how to configure logrotate in Ansible.

 First, we'll create a couple of tasks in our playbook:

 
```
- name: Create mariadb_logrotate_old_dir
  file:
    path: "{{ mariadb_logrotate_old_dir }}"
    owner: mysql
    group: mysql
    mode: '770'
    state: directory

- name: Configure logrotate
  template:
    src: "../templates/logrotate.j2"
    dest: "/etc/logrotate.d/mysql"

```

The first task creates a directory to store the old, compressed logs, and set proper permissions.

 The second task uploads logrotate configuration file into the proper directory, and calls it `mysql`. As you can see the original name is different, and it ends with the `.j2` extension, because it is a Jinja 2 template.

 The file will look like the following:

 
```
{{ mariadb_log_dir }}/* {
        su mysql mysql
        missingok
        create 660 mysql mysql
        notifempty
        daily
        minsize 1M {{ mariadb_logrotate_min_size }}
        maxsize 100M {{ mariadb_logrotate_max_size }}
        rotate {{ mariadb_logrotate_old_dir }}
        dateformat .%Y-%m-%d-%H-%M-%S # only use with logrotate >= 3.9.2
        compress
        delaycompress
        sharedscripts 
        olddir archive/
        createolddir 770 mysql mysql # only use with logrotate >= 3.8.9
    postrotate
        # just if mysqld is really running
        if test -x /usr/bin/mysqladmin && \
           /usr/bin/mysqladmin ping &>/dev/null
        then
           /usr/bin/mysqladmin --local flush-error-log \
              flush-engine-log flush-general-log flush-slow-log
        fi
    endscript
}

```

The file is very similar to the file shown above, which is obvious because we're still uploading a logrotate configuration file. Ansible is just a tool we've chosen to do this.

 However, both in the tasks and in the template, we used some variables. This allows to use different paths and rotation parameters for different hosts, or host groups.

 If we have a group host called `mariadb` that contains the default configuration for all our MariaDB servers, we can define these variables in a file called `group_vars/mariadb.yml`:

 
```
# MariaDB writes its logs here
mariadb_log_dir: /var/lib/mysql/logs

# logrotate configuration

mariadb_logrotate_min_size: 500M
mariadb_logrotate_max_size: 1G
mariadb_logrotate_old_files: 7
mariadb_logrotate_old_dir: /var/mysql/old-logs

```

After setting up logrotate in Ansible, you may want to deploy it to a non-production server and test it manually as explained above. Once you're sure that it works fine on one server, you can be confident in the new Ansible tasks and deploy them on all servers.

 For more information on how to use Ansible to automate MariaDB configuration, see [Ansible and MariaDB](../ansible-and-mariadb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rotating-logs-on-unix-and-linux/>

InnoDB Redo Log
===============

    
Directly editing or moving the redo logs can cause corruption, and should never normally be attempted.

 
Overview
--------

 The redo log is used by [InnoDB](../innodb/index) during crash recovery. The redo log files have names like `ib_logfileN`, where `N` is an integer. From [MariaDB 10.5](../what-is-mariadb-105/index), there is only one redo log, so the file will always be named `ib_logfile0`. If the [innodb\_log\_group\_home\_dir](../innodb-system-variables/index#innodb_log_group_home_dir) system variable is configured, then the redo log files will be created in that directory. Otherwise, they will be created in the directory defined by the [datadir](../server-system-variables/index#datadir) system variable.

 Flushing Effects on Performance and Consistency
-----------------------------------------------

 The [innodb\_flush\_log\_at\_trx\_commit](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) system variable determines how often the transactions are flushed to the redo log, and it is important to achieve a good balance between speed and reliability.

 ### Binary Log Group Commit and Redo Log Flushing

 In [MariaDB 10.0](../what-is-mariadb-100/index) and above, when both [innodb\_flush\_log\_at\_trx\_commit=1](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) (the default) is set and the [binary log](../binary-log/index) is enabled, there is now one less sync to disk inside InnoDB during commit (2 syncs shared between a group of transactions instead of 3). See [Binary Log Group Commit and InnoDB Flushing Performance](../binary-log-group-commit-and-innodb-flushing-performance/index) for more information.

 Redo Log Group Capacity
-----------------------

 The redo log group capacity is the total combined size of all InnoDB redo logs. The relevant factors are:

 * From [MariaDB 10.5](../what-is-mariadb-105/index), there is 1 redo log. For [MariaDB 10.4](../what-is-mariadb-104/index) and before, the number of redo log files is configured by the [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group) system variable.
* The size of each redo log file is configured by the [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) system variable. This can safely be set to a much higher value from [MariaDB 10.5](../what-is-mariadb-105/index). Before [MariaDB 10.9](../what-is-mariadb-109/index), resizing required the server to be restarted. From [MariaDB 10.9](../what-is-mariadb-109/index) the variable can be set dynamically.

 The redo log group capacity is determined by the following calculation:

 `innodb_log_group_capacity` = `[innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size)` \* `[innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group)`

 For example, if [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) is set to `2G` and [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group) is set to `2`, then we would have the following:

 * `innodb_log_group_capacity` = `[innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size)` \* `[innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group)`
* = `2G` \* `2`
* = `4G`

 ### Changing the Redo Log Group Capacity

 The number (until [MariaDB 10.4](../what-is-mariadb-104/index) only - from [MariaDB 10.5](../what-is-mariadb-105/index) there is only 1 redo log) or size of redo log files can be changed with the following process:

 * Stop the server.
* To change the log file size, configure [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size). To increase the number of log files (until [MariaDB 10.4](../what-is-mariadb-104/index) only), configure [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group).
* Start the server.

 Log Sequence Number (LSN)
-------------------------

 Records within the InnoDB redo log are identified via a log sequence number (LSN).

 Checkpoints
-----------

 When InnoDB performs a checkpoint, it writes the LSN of the oldest dirty page in the [InnoDB buffer pool](../innodb-buffer-pool/index) to the InnoDB redo log. If a page is the oldest dirty page in the [InnoDB buffer pool](../innodb-buffer-pool/index), then that means that all pages with lower LSNs have been flushed to the physical InnoDB tablespace files. If the server were to crash, then InnoDB would perform crash recovery by only applying log records with LSNs that are greater than or equal to the LSN of the oldest dirty page written in the last checkpoint.

 Checkpoints are one of the tasks performed by the InnoDB master background thread. This thread schedules checkpoints 7 seconds apart when the server is very active, but checkpoints can happen more frequently when the server is less active.

 Dirty pages are not actually flushed from the buffer pool to the physical InnoDB tablespace files during a checkpoint. That process happens asynchronously on a continuous basis by InnoDB's write I/O background threads configured by the [innodb\_write\_io\_threads](../innodb-system-variables/index#innodb_write_io_threads) system variable. If you want to make this process more aggressive, then you can decrease the value of the [innodb\_max\_dirty\_pages\_pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct) system variable. You may also need to better tune InnoDB's I/O capacity on your system by setting the [innodb\_io\_capacity](../innodb-system-variables/index#innodb_io_capacity) system variable.

 ### Determining the Checkpoint Age

 The checkpoint age is the amount of data written to the InnoDB redo log since the last checkpoint.

 #### Determining the Checkpoint Age in InnoDB

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**[MariaDB 10.5](../what-is-mariadb-105/index) reintroduced the [Innodb\_checkpoint\_age](../innodb-status-variables/index#innodb_checkpoint_age) status variable (available in XtraDB until [MariaDB 10.1](../what-is-mariadb-101/index)) for determining the checkpoint age.

 
The checkpoint age can also be determined by the process shown below.

 To determine the InnoDB checkpoint age, do the following:

 * Query [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index).
* Find the `LOG` section. For example:

 
```
---
LOG
---
Log sequence number 252794398789379
Log flushed up to 252794398789379
Pages flushed up to 252792767756840
Last checkpoint at 252792767756840
0 pending log flushes, 0 pending chkp writes
23930412 log i/o's done, 2.03 log i/o's/second

```

* Perform the following calculation:

 `innodb_checkpoint_age` = `Log sequence number` - `Last checkpoint at`

 In the example above, that would be:

 * `innodb_checkpoint_age` = `Log sequence number` - `Last checkpoint at`
* = 252794398789379 - 252792767756840
* = 1631032539 bytes
* = 1631032539 byes / (1024 \* 1024 \* 1024) (GB/bytes)
* = 1.5 GB of redo log written since last checkpoint

 Determining the Redo Log Occupancy
----------------------------------

 The redo log occupancy is the percentage of the InnoDB redo log capacity that is taken up by dirty pages that have not yet been flushed to the physical InnoDB tablespace files in a checkpoint. Therefore, it's determined by the following calculation:

 `innodb_log_occupancy` = `[innodb\_checkpoint\_age](#determining-the-checkpoint-age)` / `[innodb\_log\_group\_capacity](#redo-log-group-capacity)`

 For example, if `[innodb\_checkpoint\_age](#determining-the-checkpoint-age)` is `1.5G` and `[innodb\_log\_group\_capacity](#redo-log-group-capacity)` is `4G`, then we would have the following:

 * `innodb_log_occupancy` = `[innodb\_checkpoint\_age](#determining-the-checkpoint-age)` / `[innodb\_log\_group\_capacity](#redo-log-group-capacity)`
* = `1.5G` / `4G`
* = `0.375`

 If the calculated value for redo log occupancy is too close to `1.0`, then the InnoDB redo log capacity may be too small for the current workload.

 
[MariaDB 10.8](../what-is-mariadb-108/index) Updates
-----------------------------------------------------

 A number of redo log improvements were made in [MariaDB 10.8](../what-is-mariadb-108/index):

 * Autosize innodb\_buffer\_pool\_chunk\_size ([MDEV-25342](https://jira.mariadb.org/browse/MDEV-25342)).
* Improve the redo log for concurrency ([MDEV-14425](https://jira.mariadb.org/browse/MDEV-14425)).
* Remove FIL\_PAGE\_FILE\_FLUSH\_LSN ([MDEV-27199](https://jira.mariadb.org/browse/MDEV-27199)).

 Before [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), [mariadb-backup --prepare](../mariabackup-options/index#-prepare) created a zero-length ib\_logfile0 as a dummy placeholder. From [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/) ([MDEV-14425](https://jira.mariadb.org/browse/MDEV-14425)), the size of that dummy file was increased to 12304 (0x3010) bytes, and all updates of FIL\_PAGE\_FILE\_FLUSH\_LSN in the first page of the system tablespace are removed.

 From [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), if the server is started up with a zero-sized ib\_logfile0, it is assumed that an upgrade is being performed after a backup had been prepared. The start LSN will then be read from FIL\_PAGE\_FILE\_FLUSH\_LSN, and a new log file will be created starting from exactly that LSN.

 Manually creating a zero-sized ib\_logfile0 without manually updating the FIL\_PAGE\_FILE\_FLUSH\_LSN in the system tablespace to a recent enough LSN may result in error messages such as "page LSN is in the future". If a log was discarded while some changes had already been written to data pages, all sort of corruption may occur.

 If the database was initialized with a server that never updates the FIL\_PAGE\_FILE\_FLUSH\_LSN field, then any server startup attempts with a zero-size ib\_logfile0 will be refused because of an invalid LSN. If that field was ever updated with a valid LSN by an older server, this safety mechanism cannot work, and the server may "rewind" to an earlier LSN.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-redo-log/>

InnoDB Undo Log
===============

    Overview
--------

 When a [transaction](../transactions/index) writes data, it always inserts them in the table indexes or data (in the buffer pool or in physical files). No private copies are created. The old versions of data being modified by active [InnoDB](../innodb/index) transactions are stored in the undo log. The original data can then be restored, or viewed by a consistent read.

 Implementation Details
----------------------

 Before a row is modified, it is copied into the undo log. Each normal row contains a pointer to the most recent version of the same row in the undo log. Each row in the undo log contains a pointer to previous version, if any. So, each modified row has an history chain.

 Rows are never physically deleted until a transaction ends. If they were deleted, the restore would be impossible. Thus, rows are simply marked for deletion.

 Each transaction uses a *view* of the records. The [transaction level](../set-transaction/index#isolation-levels) determines how this view is created. For example, READ UNCOMMITTED usually uses the current version of rows, even if they are not committed (*dirty reads*). Other isolation levels require that the most recent committed version of rows is searched in the undo log. READ COMMITTED uses a different view for each table, while REPEATABLE READ and SERIALIZABLE use the same view for all tables.

 There is also a global history list of the data. When a transaction is committed, its history is added to this history list. The order of the list is the chronological order of the commits.

 The purge thread deletes the rows in the undo log which are not needed by any existing view. The rows for which a most recent version exists are deleted, as well as the delete-marked rows.

 If InnoDB needs to restore an old version, it will simply replace the newer version with the older one. When a transaction inserts a new row, there is no older version. However, in that case, the restore can be done by deleting the inserted rows.

 Effects of Long-Running Transactions
------------------------------------

 Understanding how the undo log works helps with understanding the negative effects long transactions.

 * Long transactions generate several old versions of the rows in the undo log. Those rows will probably be needed for a longer time, because other long transactions will need them. Since those transactions will generate more modified rows, a sort of combinatory explosion can be observed. Thus, the undo log requires more space.
* Transaction may need to read very old versions of the rows in the history list, thus their performance will degrade.

 Of course read-only transactions do not write more entries in the undo log; however, they delay the purging of existing entries.

 Also, long transactions can more likely result in deadlocks, but this problem is not related to the undo log.

 Configuration
-------------

 The undo log is not a log file that can be viewed on disk in the usual sense, such as the [error log](../error-log/index) or [slow query log](../slow-query-log/index), rather an area of storage.

 The undo log is usually part of the physical system tablespace, but from [MariaDB 10.0](../what-is-mariadb-100/index), the [innodb\_undo\_directory](../innodb-system-variables/index#innodb_undo_directory) and [innodb\_undo\_tablespaces](../innodb-system-variables/index#innodb_undo_tablespaces) system variables can be used to split into different tablespaces and store in a different location (perhaps on a different storage device).

 Each insert or update portion of the undo log is known as a rollback segment. The [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) system variable specifies the number of rollback segments to be used per transaction.

 The related [innodb\_available\_undo\_logs](../innodb-status-variables/index#innodb_available_undo_logs) status variable stores the total number of available InnoDB undo logs.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-undo-log/>

Transaction Coordinator Log
============================

  

| Title | Description |
| --- | --- |
|  [Transaction Coordinator Log Overview](../transaction-coordinator-log-overview/index) |  The transaction coordinator log (tc\_log) is used to coordinate transactions...  |
|  [Heuristic Recovery with the Transaction Coordinator Log](../heuristic-recovery-with-the-transaction-coordinator-log/index) |  The transaction coordinator log (tc\_log) can be used to recover prepared XA...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transaction-coordinator-log/>

MyISAM Log
==========

    The MyISAM log records all changes to [MyISAM](../myisam/index) tables. It is not enabled by default. To enable it, start the server with the [--log-isam](../mysqld-options/index#-log-isam) option, for example:

 
```
--log-isam=myisam.log

```

The *isam* instead of *myisam* above is not a typo - it's a legacy from when the predecessor to the MyISAM format, called ISAM. The option can be used without specifying a filename, in which case the default, *myisam.log* is used.

 To process the contents of the log file, use the [myisamlog](../myisamlog/index) utility.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-log/>

Hardware Optimization
=====================

    Better hardware is one of the easiest ways to improve performance.

 As a general rule of thumb, hardware should be improved in the following order:

 Memory
------

 Memory is the most important factor as it allows you to adjust the [Server System Variables](../server-system-variables/index). More memory means larger key and table caches can be stored in memory so that disk access, an order of magnitude slower, is reduced.

 Simply adding more memory may not result in drastic improvements if the server variables are not set to make use of the extra available memory.

 Using more RAM slots on the motherboard increases the bus frequency, and there will be more latency between the RAM and the CPU. So, using the highest RAM size per slot is preferable.

 Disks
-----

 Fast disk access is critical, as ultimately it's where the data resides. The key figure is the disk seek time, a measurement of how fast the physical disk can move to access the data, so choose disks with as low a seek time as possible.

 You can also add dedicated disks for temporary files and transaction logs.

 Fast Ethernet
-------------

 CPU
---

 Although hardware bottlenecks often fall elsewhere, faster processors allow calculations to be performed more quickly, and the results sent back to the client more quickly. Besides processor speed, the processor's bus speed and cache size are also important factors to consider.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hardware-optimization/>

MariaDB Memory Allocation
=========================

    Allocating RAM for MariaDB - The Short Answer
---------------------------------------------

 If only using [MyISAM](../myisam/index), set [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) to 20% of **available** RAM. (Plus [innodb\_buffer\_pool\_size=0](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size))

 If only using InnoDB, set [innodb\_buffer\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) to 70% of **available** RAM. (Plus [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) = 10M, small, but not zero.)

 Rule of thumb for tuning:

 * Start with released copy of my.cnf / my.ini.
* Change [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) and [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) according to engine usage and RAM.
* Slow queries can usually be 'fixed' via indexes, schema changes, or SELECT changes, not by tuning.
* Don't get carried away with the [query cache](../query-cache/index) until you understand what it can and cannot do.
* Don't change anything else unless you run into trouble (eg, max connections).
* Be sure the changes are under the [mysqld] section, not some other section.

 The 20%/70% assumes you have at least 4GB of RAM. If you have a tiny antique, or a tiny VM, then those percentages are too high.

 Now for the gory details.

 How to troubleshoot out-of-memory issues
----------------------------------------

 If the MariaDB server is crashing because of 'out-of-memory' then it is probably wrongly configured.

 There are two kind of buffers in MariaDB:

 * Global ones that are only allocated once during the lifetime of the server:
	+ Storage engine buffers ([innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size), [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size), [aria\_pagecache\_buffer\_size](../aria-system-variables/index#aria_pagecache_buffer_size), etc)
	+ Query cache [query\_cache\_size](../server-system-variables/index#query_cache_size).

 * Global caches onces that grow and shrink dynamically on demand up to max limit:
	+ [max\_user\_connections](../server-system-variables/index#max_user_connections)
	+ [table\_open\_cache](../server-system-variables/index#table_open_cache)
	+ [table\_definition\_cache](../server-system-variables/index#table_definition_cache)
	+ [thread\_cache\_size](../server-system-variables/index#thread_cache_size)

 * Local buffers that are allocated on demand whenever needed
	+ Internal ones used during engine index creation ([myisam\_sort\_buffer\_size](../myisam-system-variables/index#myisam_sort_buffer_size), [aria\_sort\_buffer\_size).](../aria-system-variables/index#aria_sort_buffer_size)
	+ Internal buffers for storing blobs.
		- Some storage engine will keep a temporary cache to store the largest blob seen so far when scanning a table. This will be freed at end of query. Note that temporary blob storage is **not** included in the memory information in [information\_schema.processlist](../information-schema-processlist-table/index) but only in the total memory used (`show global status like "memory_used"`).
	+ Buffers and caches used during query execution:

 


| Variable | Description |
| --- | --- |
| [join\_buffer\_size](../server-system-variables/index#join_buffer_size) | Used when no keys can be used to find a row in next table |
| [mrr\_buffer\_size](../server-system-variables/index#mrr_buffer_size) | Size of buffer to use when using multi-range read with range access |
| [net\_buffer\_length](../server-system-variables/index#net_buffer_length) | Max size of network packet |
| [read\_buffer\_size](../server-system-variables/index#read_buffer_size) | Used by some storage engines when doing bulk insert |
| [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size) | When doing ORDER BY or GROUP BY |
| [max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size) | Used to store temporary tables in memory. See [Optimizing memory tables](../optimizing-memory-tables/index) |

 
If any variables in the last group is very large and you have a lot of simultaneous users that are executing queries that are using these buffers then you can run into trouble.

 In a default MariaDB installation the default of most of the above variables are quite small to ensure that one does not run out of memory.

 You can check which variables that have been changed in your setup by executing the following sql statement. If you are running into out-of-memory issues, it is very likely that the problematic variable is in this list!

 
```
select information_schema.system_variables.variable_name,
information_schema.system_variables.default_value,
global_variables.variable_value from
information_schema.system_variables,information_schema.global_variables where
system_variables.variable_name=global_variables.variable_name and
system_variables.default_value <> global_variables.variable_value and
system_variables.default_value <> 0

```

What is the Key Buffer?
-----------------------

 [MyISAM](../myisam/index) does two different things for caching.

 * Index blocks (1KB each, BTree structured, from .MYI file) live in the "key buffer".
* Data block caching (from .MYD file) is left to the OS, so be sure to leave a bunch of free space for this. Caveat: Some flavors of OS always claim to be using over 90%, even when there is really lots of free space.

 
```
SHOW GLOBAL STATUS LIKE 'Key%';

```

then calculate [Key\_read\_requests](../server-status-variables/index#key_read_requests) / [Key\_reads](../server-status-variables/index#key_reads). If it is high (say, over 10), then the key buffer is big enough, otherwise you should adjust the [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) value.

 What is the Buffer Pool?
------------------------

 InnoDB does all its caching in a the [buffer pool](../xtradbinnodb-buffer-pool/index), whose size is controlled by [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size). By default it contains 16KB data and index blocks from the open tables (see [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size)), plus some maintenance overhead.

 From [MariaDB 5.5](../what-is-mariadb-55/index), multiple buffer pools are permitted; this can help because there is one mutex per pool, thereby relieving some of the mutex bottleneck.

 [More on InnoDB tuning](http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/)

 Another Algorithm
-----------------

 This will set the main cache settings to the minimum; it could be important to systems with lots of other processes and/or RAM is 2GB or smaller.

 Do [SHOW TABLE STATUS](../show-table-status/index) for all the tables in all the databases.

 Add up Index\_length for all the MyISAM tables. Set [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) no larger than that size.

 Add up Data\_length + Index\_length for all the InnoDB tables. Set [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) to no more than 110% of that total.

 If that leads to swapping, cut both settings back. Suggest cutting them down proportionately.

 Run this to see the values for your system. (If you have a lot of tables, it can take minute(s).)

 
```
SELECT  ENGINE,
        ROUND(SUM(data_length) /1024/1024, 1) AS "Data MB",
        ROUND(SUM(index_length)/1024/1024, 1) AS "Index MB",
        ROUND(SUM(data_length + index_length)/1024/1024, 1) AS "Total MB",
        COUNT(*) "Num Tables"
    FROM  INFORMATION_SCHEMA.TABLES
    WHERE  table_schema not in ("information_schema", "PERFORMANCE_SCHEMA", "SYS_SCHEMA", "ndbinfo")
    GROUP BY  ENGINE;

```

Query Memory Allocation
-----------------------

 There are two variables that dictates how memory are allocated by MariaDB while parsing and executing a query. [query\_prealloc\_size](../server-system-variables/index#query_prealloc_size) defines the standard buffer for memory used for query execution and [query\_alloc\_block\_size](../server-system-variables/index#query_alloc_block_size) that is size of memory blocks if `query_prealloc_size` was not big enough. Getting these variables right will reduce memory fragmentation in the server.

 Mutex Bottleneck
----------------

 MySQL was designed in the days of single-CPU machines, and designed to be easily ported to many different architectures. Unfortunately, that lead to some sloppiness in how to interlock actions. There are a small number (too small) of "mutexes" to gain access to several critical processes. Of note:

 * MyISAM's key\_buffer
* The Query Cache
* InnoDB's buffer\_pool With multi-core boxes, the mutex problem is causing performance problems. In general, past 4-8 cores, MySQL gets slower, not faster. MySQL 5.5 and Percona's XtraDB made that somewhat better in InnoDB; the practical limit for cores is more like 32, and performance tends plateaus after that rather than declining. 5.6 claims to scale up to about 48 cores.

 HyperThreading and Multiple Cores (CPUs)
----------------------------------------

 Short answers (for older versions of MySQL and MariaDB):

 * Turn off HyperThreading
* Turn off any cores beyond 8
* HyperThreading is mostly a thing of the past, so this section may not apply.

 HyperThreading is great for marketing, lousy for performance. It involves having two processing units sharing a single hardware cache. If both units are doing the same thing, the cache will be reasonably useful. If the units are doing different things, they will be clobbering each other's cache entries.

 Furthermore MySQL is not great on using multiple cores. So, if you turn off HT, the remaining cores run a little faster.

 32-bit OS and MariaDB
---------------------

 First, the OS (and the hardware?) may conspire to not let you use all 4GB, if that is what you have. If you have more than 4GB of RAM, the excess beyond 4GB is \_totally\_ inaccessable and unusable on a 32-bit OS.

 Secondly, the OS probably has a limit on how much RAM it will allow any process to use.

 Example: FreeBSD's maxdsiz, which defaults to 512MB.

 Example:

 
```
$ ulimit -a
...
max memory size (kbytes, -m) 524288

```

So, once you have determined how much RAM is available to mysqld, then apply the 20%/70%, but round down some.

 If you get an error like `[ERROR] /usr/libexec/mysqld: Out of memory (Needed xxx bytes)`, it probably means that MySQL exceeded what the OS is willing to give it. Decrease the cache settings.

 64-bit OS with 32-bit MariaDB
-----------------------------

 The OS is not limited by 4GB, but MariaDB is.

 If you have at least 4GB of RAM, then maybe these would be good:

 * [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) = 20% of \_all\_ of RAM, but not more than 3G
* [innodb\_buffer\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) = 3G

 You should probably upgrade MariaDB to 64-bit.

 64-bit OS and MariaDB
---------------------

 MyISAM only: [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size): Use about 20% of RAM. Set (in my.cnf / my.ini) [innodb\_buffer\_pool\_size=0](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) = 0.

 InnoDB only: [innodb\_buffer\_pool\_size=0](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) = 70% of RAM. If you have lots of RAM and are using 5.5 (or later), then consider having multiple pools. Recommend 1-16 [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances), such that each one is no smaller than 1GB. (Sorry, no metric on how much this will help; probably not a lot.)

 Meanwhile, set [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) = 20M (tiny, but non-zero)

 If you have a mixture of engines, lower both numbers.

 max\_connections, thread\_stack Each "thread" takes some amount of RAM. This used to be about 200KB; 100 threads would be 20MB, not a significant size. If you have [max\_connections](../server-system-variables/index#max_connections) = 1000, then you are talking about 200MB, maybe more. Having that many connections probably implies other issues that should be addressed.

 In 5.6 (or [MariaDB 5.5](../what-is-mariadb-55/index)), optional thread pooling interacts with [max\_connections](../server-system-variables/index#max_connections). This is a more advanced topic.

 Thread stack overrun rarely happens. If it does, do something like thread\_stack=256K

 [More on max\_connections, wait\_timeout, connection pooling, etc](http://www.mysqlperformanceblog.com/2013/11/28/mysql-error-too-many-connections/)

 table\_open\_cache
------------------

 (In older versions this was called table\_cache)

 The OS has some limit on the number of open files it will let a process have. Each table needs 1 to 3 open files. Each PARTITION is effectively a table. Most operations on a partitioned table open \_all\_ partitions.

 In \*nix, ulimit tells you what the file limit is. The maximum value is in the tens of thousands, but sometimes it is set to only 1024. This limits you to about 300 tables. More discussion on ulimit

 (This paragraph is in disputed.) On the other side, the table cache is (was) inefficiently implemented -- lookups were done with a linear scan. Hence, setting table\_cache in the thousands could actually slow down mysql. (Benchmarks have shown this.)

 You can see how well your system is performing via [SHOW GLOBAL STATUS](../show-status/index); and computing the opens/second via [Opened\_files](../server-status-variables/index#opened_files) / [Uptime](../server-status-variables/index#uptime) If this is more than, say, 5, [table\_open\_cache](../server-system-variables/index#table_open_cache) should be increased. If it is less than, say, 1, you might get improvement by decreasing [table\_open\_cache](../server-system-variables/index#table_open_cache).

 From [MariaDB 10.1](../what-is-mariadb-101/index), [table\_open\_cache](../server-system-variables/index#table_open_cache) defaults to 2000.

 Query Cache
-----------

 Short answer: [query\_cache\_type](../server-system-variables/index#query_cache_type) = OFF and [query\_cache\_size](../server-system-variables/index#query_cache_size) = 0

 The [Query Cache](../query-cache/index) (QC) is effectively a hash mapping SELECT statements to resultsets.

 Long answer... There are many aspects of the "Query cache"; many are negative.

 * Novice Alert! The QC is totally unrelated to the key\_buffer and buffer\_pool.
* When it is useful, the QC is blazingly fast. It would not be hard to create a benchmark that runs 1000x faster.
* There is a single mutex controlling the QC.
* The QC, unless it is OFF & 0, is consulted for \_every\_ SELECT.
* Yes, the mutex is hit even if [query\_cache\_type](../server-system-variables/index#query_cache_type) = DEMAND (2).
* Yes, the mutex is hit even for [SQL\_NO\_CACHE](../query-cache/index#sql_no_cache-and-sql_cache).
* Any change to a query (even adding a space) leads (potentially) to a different entry in the QC.
* If my.cnf says type=ON and you later turn it OFF, it is not fully OFF. Ref: <https://bugs.mysql.com/bug.php?id=60696>

 "Pruning" is costly and frequent:

 * When \_any\_ write happens on a table, \_all\_ entries in the QC for \_that\_ table are removed.
* It happens even on a readonly Slave.
* Purges are performed with a linear algorithm, so a large QC (even 200MB) can be noticeably slow.

 To see how well your QC is performing, SHOW GLOBAL STATUS LIKE 'Qc%'; then compute the read hit rate: [Qcache\_hits](../server-status-variables/index#qcache_hits) / [Qcache\_inserts](../server-status-variables/index#qcache_inserts) If it is over, say, 5, the QC might be worth keeping.

 If you decide the QC is right for you, then I recommend

 * [query\_cache\_size](../server-system-variables/index#query_cache_size) = no more than 50M
* [query\_cache\_type](../server-system-variables/index#query_cache_type) = DEMAND
* [SQL\_CACHE or SQL\_NO\_CACHE](%5bquery-cache/index#sql_no_cache-and-sql_cache) in all SELECTs, based on which queries are likely to benefit from caching.

 * [Why to turn off the QC](http://dba.stackexchange.com/a/136814/1876)
* [Discussion about size](https://haydenjames.io/mysql-query-cache-size-performance/)

 thread\_cache\_size
-------------------

 It is not necessary to tune [thread\_cache\_size](../server-system-variables/index#thread_cache_size) from [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/). Previously, it was minor tunable variable. Zero will slow down thread (connection) creation. A small (say, 10), non-zero number is good. The setting has essentially no impact on RAM usage.

 It is the number of extra processes to hang onto. It does not restrict the number of threads; [max\_connections](../server-system-variables/index#max_connections) does.

 Binary Logs
-----------

 If you have turned on [binary logging](../binary-log/index) (via [log\_bin](../replication-and-binary-log-system-variables/index#log_bin)) for replication and/or point-in-time recovery, the system will create binary logs forever. That is, they can slowly fill up the disk. Suggest setting [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days) = 14 to keep only 14 days' worth of logs.

 Swappiness
----------

 RHEL, in its infinite wisdom, decided to let you control how aggressively the OS will pre-emptively swap RAM. This is good in general, but lousy for MariaDB.

 MariaDB would love for RAM allocations to be reasonably stable -- the caches are (mostly) pre-allocated; the threads, etc, are (mostly) of limited scope. ANY swapping is likely to severely hurt performance of MariaDB.

 With a high value for swappiness, you lose some RAM because the OS is trying to keep a lot of space free for future allocations (that MySQL is not likely to need).

 With swappiness = 0, the OS will probably crash rather than swap. I would rather have MariaDB limping than die. The latest recommendation is swappiness = 1. (2015)

 [More confirmation](http://www.mysqlperformanceblog.com/2014/04/28/oom-relation-vm-swappiness0-new-kernel/)

 Somewhere in between (say, 5?) might be a good value for a MariaDB-only server.

 NUMA
----

 OK, it's time to complicate the architecture of how a CPU talks to RAM. NUMA (Non-Uniform Memory Access) enters the picture. Each CPU (or maybe socket with several cores) has a part of the RAM hanging off each. This leads to memory access being faster for local RAM, but slower (tens of cycles slower) for RAM hanging off other CPUs.

 Then the OS enters the picture. In at least one case (RHEL?), two things seem to be done:

 * OS allocations are pinned to the 'first' CPU's RAM.]
* Other allocations go by default to the first CPU until it is full.

 Now for the problem.

 * The OS and MariaDB have allocated all the 'first' RAM.
* MariaDB has allocated some of the second RAM.
* The OS needs to allocate something. Ouch -- it is out of room in the one CPU where it is willing to allocate its stuff, so it swaps out some of MariaDB. Bad.

 dmesg | grep -i numa # to see if you have numa

 Probable solution: Configure the BIOS to "interleave" the RAM allocations. This should prevent the premature swapping, at the cost of off-CPU RAM accesses half the time. Well, you have the costly accesses anyway, since you really want to use all of RAM. Older MySQL versions: numactl --interleave=all. Or: [innodb\_numa\_interleave](../innodb-system-variables/index#innodb_numa_interleave)=1

 Another possible solution: Turn numa off (if the OS has a way of doing that)

 Overall performance loss/gain: A few percent.

 Huge Pages
----------

 This is another hardware performance gimmick.

 For a CPU to access RAM, especially mapping a 64-bit address to somewhere in, say, 128GB or 'real' RAM, the TLB is used. (TLB = Translation Lookup Buffer.) Think of the TLB as a hardware associative memory lookup table; given a 64-bit virtual address, what is the real address.

 Because it is an associative memory of finite size, sometimes there will be "misses" that require reaching into real RAM to resolve the lookup. This is costly, so should be avoided.

 Normally, RAM is 'paged' in 4KB pieces; the TLB actually maps the top (64-12) bits into a specific page. Then the bottom 12 bits of the virtual address are carried over intact.

 For example, 128GB of RAM broken 4KB pages means 32M page-table entries. This is a lot, and probably far exceeds the capacity of the TLB. So, enter the "Huge page" trick.

 With the help of both the hardware and the OS, it is possible to have some of RAM in huge pages, of say 4MB (instead of 4KB). This leads to far fewer TLB entries, but it means the unit of paging is 4MB for such parts of RAM. Hence, huge pages tend to be non-pagable.

 Now RAM is broken into pagable and non pagable parts; what parts can reasonably be non pagable? In MariaDB, the [Innodb Buffer Pool](../xtradbinnodb-buffer-pool/index) is a perfect candidate. So, by correctly configuring these, InnoDB can run a little faster:

 * Huge pages enabled
* Tell the OS to allocate the right amount (namely to match the buffer\_pool)
* Tell MariaDB to use huge pages

 * [innodb memory usage vs swap](http://forums.mysql.com/read.php?22,384707,385002)

 That thread has more details on what to look for and what to set.

 Overall performance gain: A few percent. Yawn. Too much hassle for too little benefit.

 Jumbo Pages? Turn off.

 ENGINE=MEMORY
-------------

 The [Memory Storage Engine](../memory-storage-engine/index) is a little-used alternative to [MyISAM](../myisam/index) and [InnoDB](../innodb/index). The data is not persistent, so it has limited uses. The size of a MEMORY table is limited to [max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size), which defaults to 16MB. I mention it in case you have changed the value to something huge; this would stealing from other possible uses of RAM.

 How to Set Variables
--------------------

 In the text file my.cnf (my.ini on Windows), add or modify a line to say something like

 [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) = 5G

 That is, VARIABLE name, "=", and a value. Some abbreviations are allowed, such as M for million (1048576), G for billion.

 For the server to see it, the settings must be in the "[mysqld]" section of the file.

 The settings in my.cnf or my.ini will not take effect until you restart the server.

 Most settings can be changed on the live system by connecting as user root (or other user with SUPER privilege) and doing something like

 
```
SET @@global.key_buffer_size = 77000000;

```

Note: No M or G suffix is allowed here.

 To see the setting a global VARIABLE do something like

 
```
SHOW GLOBAL VARIABLES LIKE "key_buffer_size";
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| key_buffer_size | 76996608 |
+-----------------+----------+

```

Note that this particular setting was rounded down to some multiple that MariaDB liked.

 You may want to do both (SET, and modify my.cnf) in order to make the change immediately and have it so that the next restart (for whatever reason) will again get the value.

 Web Server
----------

 A web server like Apache runs multiple threads. If each thread opens a connection to MariaDB, you could run out of connections. Make sure MaxClients (or equivalent) is set to some civilized number (under 50).

 Tools
-----

 * MySQLTuner
* TUNING-PRIMER

 There are several tools that advise on memory. One misleading entry they come up with

 Maximum possible memory usage: 31.3G (266% of installed RAM)

 Don't let it scare you -- the formulas used are excessively conservative. They assume all of [max\_connections](../server-system-variables/index#max_connections) are in use and active, and doing something memory-intensive.

 Total fragmented tables: 23 This implies that OPTIMIZE TABLE \_might\_ help. I suggest it for tables with either a high percentage of "free space" (see SHOW TABLE STATUS) or where you know you do a lot of DELETEs and/or UPDATEs. Still, don't bother to OPTIMIZE too often. Once a month might suffice.

 MySQL 5.7
---------

 5.7 stores a lot more information in RAM, leading to the footprint being perhaps half a GB more than 5.6. See [Memory increase in 5.7](https://blogs.oracle.com/svetasmirnova/entry/memory_summary_tables_in_performance).

 Postlog
-------

 Created 2010; Refreshed Oct, 2012, Jan, 2014

 The tips in this document apply to MySQL, MariaDB, and Percona.

 See Also
--------

 * [Configuring MariaDB for Optimal Performance](../configuring-mariadb-for-optimal-performance/index)
* More in-depth: Tocker's tuning for 5.6
* Irfan's InnoDB performance optimization basics (redux)
* 10 MySQL settings to tune after installation
* Magento
* Peter Zaitsev's take on such (5/2016)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/random>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-memory-allocation/>

Optimizing Data Structure
==========================

   Good database design is an important part of a well-run system. This section looks at some of the elements to consider.

  

| Title | Description |
| --- | --- |
|  [Numeric vs String Fields](../numeric-vs-string-fields/index) |  Choosing numeric over string fields  |
|  [Optimizing MEMORY Tables](../optimizing-memory-tables/index) |  MEMORY tables are a good choice for data that needs to be accessed often, a...  |
|  [Optimizing String and Character Fields](../optimizing-string-and-character-fields/index) |  Optimizations when comparing string columns and VARCHAR vs BLOB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-data-structure/>

Buffers, Caches and Threads
============================

   MariaDB makes use of a number of buffering, caching and threading techniques to improve performance.

  

| Title | Description |
| --- | --- |
|  [Thread Pool](../thread-pool/index) |  MariaDB thread pool  |
|  [Thread States](../thread-states/index) |  Descriptions of the various thread states  |
|  [InnoDB Buffer Pool](../innodb-buffer-pool/index) |  The most important memory buffer used by InnoDB.  |
|  [InnoDB Change Buffering](../innodb-change-buffering/index) |  Buffering INSERT, UPDATE and DELETE statements for greater efficiency.  |
|  [Query Cache](../query-cache/index) |  Caching SELECT queries for better performance.  |
|  [Segmented Key Cache](../segmented-key-cache/index) |  Collection of structures for regular MyISAM key caches  |
|  [Subquery Cache](../subquery-cache/index) |  Subquery cache for optimizing the evaluation of correlated subqueries.  |
|  [Thread Command Values](../thread-command-values/index) |  Thread command values from SHOW PROCESSLIST or Information Schema PROCESSLIST Table  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buffers-caches-and-threads/>

Benchmarking
============

    Published Results
-----------------

 * [Benchmark Results](../benchmark-results/index)

 Systemtap
---------

 * Useful scripts: <http://sourceware.org/systemtap/examples/keyword-index.html#DISK>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmarking/>

Operating System Optimizations
===============================

   Between the hardware and MariaDB sits the operating system, and there are a number of optimizations that can be made at this level

  

| Title | Description |
| --- | --- |
|  [Configuring Linux for MariaDB](../configuring-linux-for-mariadb/index) |  Linux kernel settings IO scheduler For optimal IO performance running a da...  |
|  [Configuring Swappiness](../configuring-swappiness/index) |  Setting Linux swappiness.  |
|  [Filesystem Optimizations](../filesystem-optimizations/index) |  Which filesystem is best? The filesystem is not the most important aspect ...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/operating-system-optimizations/>

MariaDB Internal Optimizations
===============================

   Different optimizations strategies done internally in MariaDB

  

| Title | Description |
| --- | --- |
|  [Binary Log Group Commit and InnoDB Flushing Performance](../binary-log-group-commit-and-innodb-flushing-performance/index) |  Improvement for group commit for InnoDB transactions with the binary log enabled.  |
|  [Fair Choice Between Range and Index\_merge Optimizations](../fair-choice-between-range-and-index_merge-optimizations/index) |  index\_merge is a method used by the optimizer to retrieve rows from a singl...  |
|  [Improvements to ORDER BY Optimization](../improvements-to-order-by/index) |  Several Improvements to the ORDER BY Optimizer in Version 10.1 of MariaDB.  |
|  [Multi Range Read Optimization](../multi-range-read-optimization/index) |  An optimization for improving performance of IO-bound queries which scan many rows.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-internal-optimizations/>

Optimizing Tables
==================

   Different ways to optimize tables and data on disk

  

| Title | Description |
| --- | --- |
|  [OPTIMIZE TABLE](../optimize-table/index) |  Reclaim unused space and defragment data.  |
|  [ANALYZE TABLE](../analyze-table/index) |  Store key distributions for a table.  |
|  [Choosing the Right Storage Engine](../choosing-the-right-storage-engine/index) |  Quickly choose the most suitable storage engine for your needs.  |
|  [Converting Tables from MyISAM to InnoDB](../converting-tables-from-myisam-to-innodb/index) |  Issues when converting tables from MyISAM to InnoDB.  |
|  [Histogram-Based Statistics](../histogram-based-statistics/index) |  Histogram-based statistics can improve the optimizer query plan in certain situations.  |
|  [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index) |  MariaDB 10.1.1 introduced a feature to defragment InnoDB tablespaces.  |
|  [Entity-Attribute-Value Implementation](../entity-attribute-value-implementation/index) |  A common, poorly performing, design pattern (EAV); plus an alternative  |
|  [IP Range Table Performance](../ip-range-table-performance/index) |  IP Range Table Performance Improvements  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-tables/>

Performance Schema
===================

   The MariaDB Performance Schema is a feature for monitoring the performance of your MariaDB server. It is not enabled by default - see [the overview](../performance-schema-overview/index) for details on activating.

  

| Title | Description |
| --- | --- |
|  [Performance Schema Tables](../performance-schema-tables/index) |  Tables making up the MariaDB Performance Schema.  |
|  [Performance Schema Overview](../performance-schema-overview/index) |  Quick overview of the Performance Schema.  |
|  [Performance Schema Status Variables](../performance-schema-status-variables/index) |  Performance Schema status variables.  |
|  [Performance Schema System Variables](../performance-schema-system-variables/index) |  Performance Schema system variables.  |
|  [Performance Schema Digests](../performance-schema-digests/index) |  Normalized statements with data values removed  |
|  [PERFORMANCE\_SCHEMA Storage Engine](../performance_schema-storage-engine/index) |  PERFORMANCE\_SCHEMA storage engine, a mechanism for implementing the feature.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema/>

Compression
============

   There are a number of different kinds of compression in MariaDB

  

| Title | Description |
| --- | --- |
|  [Encryption, Hashing and Compression Functions](../encryption-hashing-and-compression-functions/index) |  Functions used for encryption, hashing and compression.  |
|  [Storage-Engine Independent Column Compression](../storage-engine-independent-column-compression/index) |  Storage-engine independent support for column compression.  |
|  [InnoDB Page Compression](../innodb-page-compression/index) |  InnoDB page compression, which is more sophisticated than the COMPRESSED row format.  |
|  [Compression Plugins](../compression-plugins/index) |  Five MariaDB compression libraries are available as plugins.  |
|  [Compressing Events to Reduce Size of the Binary Log](../compressing-events-to-reduce-size-of-the-binary-log/index) |  Binlog events can be compressed to save space on disk and in network transfers.  |
|  [InnoDB COMPRESSED Row Format](../innodb-compressed-row-format/index) |  Similar to the COMPACT row format, but can store even more data on overflow pages.  |
|  [ColumnStore Compression Mode](../columnstore-compression-mode/index) |  ColumnStore has the ability to compress data  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimization-and-tuning-compression/>

Backup and Restore Overview
===========================

     This article briefly discusses the main ways to backup MariaDB. For detailed descriptions and syntax, see the individual pages. More detail is in the process of being added.

 Logical vs Physical Backups
---------------------------

 Logical backups consist of the SQL statements necessary to restore the data, such as [CREATE DATABASE](../create-database/index), [CREATE TABLE](../create-table/index) and [INSERT](../insert/index).

 Physical backups are performed by copying the individual data files or directories.

 The main differences are as follows:

 * logical backups are more flexible, as the data can be restored on other hardware configurations, MariaDB versions or even on another DBMS, while physical backups cannot be imported on significantly different hardware, a different DBMS, or potentially even a different MariaDB version.
* logical backups can be performed at the level of database and table, while physical databases are the level of directories and files. In the [MyISAM](../myisam/index) and [InnoDB](../innodb/index) storage engines, each table has an equivalent set of files. (In versions prior to [MariaDB 5.5](../what-is-mariadb-55/index), by default a number of InnoDB tables are stored in the same file, in which case it is not possible to backup by table. See [innodb\_file\_per\_table](../xtradbinnodb-server-system-variables/index#innodb_file_per_table).)
* logical backups are larger in size than the equivalent physical backup.
* logical backups takes more time to both backup and restore than the equivalent physical backup.
* log files and configuration files are not part of a logical backup

 Backup Tools
------------

 ### Mariadb-backup

 [Mariadb-backup](../mariadb-backup/index) is a fork of [Percona XtraBackup](../backup-restore-and-import-xtrabackup/index) with added support for [MariaDB 10.1](../what-is-mariadb-101/index) [compression](innodb_compression) and [data-at-rest encryption](../data-at-rest-encryption/index). It is included with [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/) and later.

 ### mariadb-dump

 [mariadb-dump](../mariadb-dump/index) (previously mysqldump) performs a logical backup. It is the most flexible way to perform a backup and restore, and a good choice when the data size is relatively small.

 For large datasets, the backup file can be large, and the restore time lengthy.

 mariadb-dump dumps the data into SQL format (it can also dump into other formats, such as CSV or XML) which can then easily be imported into another database. The data can be imported into other versions of MariaDB, MySQL, or even another DBMS entirely, assuming there are no version or DBMS-specific statements in the dump.

 mariadb-dump dumps triggers along with tables, as these are part of the table definition. However, [stored procedures](../stored-procedures/index), [views](../views/index), and [events](../events/index) are not, and need extra parameters to be recreated explicitly (for example, `--routines` and `--events`). [Procedures](../stored-procedures/index) and <functions> are however also part of the system tables (for example [mysql.proc](../mysqlproc-table/index)).

 #### InnoDB Logical Backups

 InnoDB uses the [buffer pool](../xtradbinnodb-buffer-pool/index), which stores data and indexes from its tables in memory. This buffer is very important for performance. If InnoDB data doesn't fit the memory, it is important that the buffer contains the most frequently accessed data. However, last accessed data is candidate for insertion into the buffer pool. If not properly configured, when a table scan happens, InnoDB may copy the whole contents of a table into the buffer pool. The problem with logical backups is that they always imply full table scans.

 An easy way to avoid this is by increasing the value of the [innodb\_old\_blocks\_time](../xtradbinnodb-server-system-variables/index#innodb_old_blocks_time) system variable. It represents the number of milliseconds that must pass before a recently accessed page can be put into the "new" sublist in the buffer pool. Data which is accessed only once should remain in the "old" sublist. This means that they will soon be evicted from the buffer pool. Since during the backup process the "old" sublist is likely to store data that is not useful, one could also consider resizing it by changing the value of the [innodb\_old\_blocks\_pct](../xtradbinnodb-server-system-variables/index#innodb_old_blocks_pct) system variable.

 It is also possible to explicitly dump the buffer pool on disk before starting a logical backup, and restore it after the process. This will undo any negative change to the buffer pool which happens during the backup. To dump the buffer pool, the [innodb\_buffer\_pool\_dump\_now](../innodb-system-variables/index#innodb_buffer_pool_dump_now) system variable can be set to ON. To restore it, the [innodb\_buffer\_pool\_load\_now](../innodb-system-variables/index#innodb_buffer_pool_load_now) system variable can be set to ON.

 #### Examples

 Backing up a single database

 
```
shell> mariadb-dump db_name > backup-file.sql

```

Restoring or loading the database

 
```
shell> mariadb db_name < backup-file.sql

```

See the [mariadb-dump](../mariadb-dump/index) page for detailed syntax and examples.

 ### mariadb-hotcopy

 
mariadb-hotcopy is deprecated.

 
[mariadb-hotcopy](../mariadb-hotcopy/index) performs a physical backup, and works only for backing up [MyISAM](../myisam/index) and [ARCHIVE](../archive/index) tables. It can only be run on the same machine as the location of the database directories.

 #### Examples

 
```
shell> mariadb-hotcopy db_name [/path/to/new_directory]
shell> mariadb-hotcopy db_name_1 ... db_name_n /path/to/new_directory

```

### Percona XtraBackup

 
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 
 [Percona XtraBackup](../backup-restore-and-import-xtrabackup/index) is a tool for performing fast, hot backups. It was designed specifically for [XtraDB/InnoDB](../innodb/index) databases, but can be used with any storage engine (although not with [MariaDB 10.1](../what-is-mariadb-101/index) [encryption](../encryption/index) and [compression](../compression/index)). It is not included by default with MariaDB.

 ### Filesystem Snapshots

 Some filesystems, like Veritas, support snapshots. During the snapshot, the table must be locked. The proper steps to obtain a snapshot are:

 * From the mariadb client, execute [FLUSH TABLES WITH READ LOCK](../flush/index). The client must remain open.
* From a shell, execute `mount vxfs snapshot`
* The client can execute [UNLOCK TABLES](../transactions-lock/index).
* Copy the snapshot files.
* From a shell, unmount the snapshot with `umount snapshot`.

 ### LVM

 Widely-used physical backup method, using a Perl script as a wrapper. See <http://www.lenzg.net/mylvmbackup/>.

 ### Percona TokuBackup

 For details, see:

 * [TokuDB Hot Backup – Part 1](https://www.percona.com/blog/2013/09/12/tokudb-hot-backup-part-1/)
* [TokuDB Hot Backup – Part 2](https://www.percona.com/blog/2013/09/19/tokudb-hot-backup-part-2/)
* [TokuDB Hot Backup Now a MySQL Plugin](https://www.percona.com/blog/2015/02/05/tokudb-hot-backup-now-mysql-plugin/)

 ### dbForge Studio for MySQL

 Besides the system utilities, it is possible to use third-party GUI tools to perform backup and restore operations. In this context, it is worth mentioning dbForge Studio for MySQL, a feature-rich database IDE that is fully compatible with MariaDB and delivers extensive backup functionality.

 The backup and restore module of the Studio allows precise [configuration and management of full and partial backups](../backup-and-restore-via-dbforge-studio/index) up to particular database objects. The feature of scheduling regular backups offers specific settings to handle errors and keep a log of them. Additionally, settings and configurations can be saved for later reuse. 

 These operations are wizard-aided allowing users to set up all tasks in a visual mode.

 See Also
--------

 * [Streaming MariaDB backups in the cloud](https://mariadb.com/blog/streaming-mariadb-backups-cloud) (mariadb.com blog)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-and-restore-overview/>

Optimization and Indexes
=========================

   A critical way to improve table performance is by creating indexes on key columns.

  

| Title | Description |
| --- | --- |
|  [The Essentials of an Index](../the-essentials-of-an-index/index) |  Explains the basics of a table index.  |
|  [Getting Started with Indexes](../getting-started-with-indexes/index) |  Extensive tutorial on creating indexes for tables.  |
|  [Full-Text Indexes](../full-text-indexes/index) |  MariaDB has support for full-text indexing and searching.  |
|  [ANALYZE TABLE](../analyze-table/index) |  Store key distributions for a table.  |
|  [Building the best INDEX for a given SELECT](../building-the-best-index-for-a-given-select/index) |  Cookbook for Creating Indexes  |
|  [Compound (Composite) Indexes](../compound-composite-indexes/index) |  Compound indexes plus other insights into the mysteries of indexing  |
|  [EXPLAIN](../explain/index) |  EXPLAIN returns information about index usage, as well as being a synonym for DESCRIBE.  |
|  [Foreign Keys](../foreign-keys/index) |  Foreign keys can be used to enforce data integrity.  |
|  [Ignored Indexes](../ignored-indexes/index) |  Indexes that are not used by the optimizer.  |
|  [Index Statistics](../index-statistics/index) |  Index statistics and the query optimizer.  |
|  [Latitude/Longitude Indexing](../latitudelongitude-indexing/index) |  Efficiently finding the nearest 10 pizza parlors in a huge database  |
|  [Primary Keys with Nullable Columns](../primary-keys-with-nullable-columns/index) |  SQL standards in dealing with multi-part primary keys with nullable columns.  |
|  [SHOW EXPLAIN](../show-explain/index) |  Shows an execution plan for a running query.  |
|  [SPATIAL INDEX](../spatial-index/index) |  An index type used for geometric columns.  |
|  [Storage Engine Index Types](../storage-engine-index-types/index) |  The permitted index\_types for each storage engine.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimization-and-indexes/>

Query Optimizations
====================

   Different query optimizations and how you can use and tune them to get better performance.

  

| Title | Description |
| --- | --- |
|  [Index Hints: How to Force Query Plans](../index-hints-how-to-force-query-plans/index) |  Using hints to get the optimizer to use another query plan.  |
|  [Subquery Optimizations](../subquery-optimizations/index) |  Articles about subquery optimizations in MariaDB.  |
|  [Optimization Strategies](../optimization-strategies/index) |  Various optimization strategies used by the query optimizer.  |
|  [Optimizations for Derived Tables](../optimizations-for-derived-tables/index) |  Optimizations for derived tables, or subqueries in the FROM clause  |
|  [Table Elimination](../table-elimination/index) |  Resolving queries without accessing some of the tables the query refers to  |
|  [Statistics for Optimizing Queries](../statistics-for-optimizing-queries/index) |  Different statistics provided by MariaDB to help you optimize your queries  |
|  [Filesort with Small LIMIT Optimization](../filesort-with-small-limit-optimization/index) |  Filesort with small LIMIT optimization.  |
|  [LIMIT ROWS EXAMINED](../limit-rows-examined/index) |  Means to terminate execution of SELECTs that examine too many rows.  |
|  [index\_merge sort\_intersection](../index_merge-sort_intersection/index) |  Operation to allow the use of index\_merge in a broader number of cases.  |
|  [MariaDB 5.3 Optimizer Debugging](../mariadb-53-optimizer-debugging/index) |  MariaDB 5.3's optimizer debugging patch  |
|  [optimizer\_switch](../optimizer-switch/index) |  Server variable for enabling specific optimizations.  |
|  [How to Quickly Insert Data Into MariaDB](../how-to-quickly-insert-data-into-mariadb/index) |  Techniques for inserting data quickly into MariaDB.  |
|  [Index Condition Pushdown](../index-condition-pushdown/index) |  Index Condition Pushdown optimization.  |
|  [Query Limits and Timeouts](../query-limits-and-timeouts/index) |  Different methods MariaDB provides to limit/timeout a query.  |
|  [Aborting Statements that Exceed a Certain Time to Execute](../aborting-statements/index) |  Aborting statements that take longer than a certain time to execute.  |
|  [Partition Pruning and Selection](../partition-pruning-and-selection/index) |  Partition pruning is when the optimizer knows which partitions are relevant for the query.  |
|  [Big DELETEs](../big-deletes/index)  |  How to DELETE lots of rows from a large table  |
|  [Data Sampling: Techniques for Efficiently Finding a Random Row](../data-sampling-techniques-for-efficiently-finding-a-random-row/index) |  Fetching random rows from a table (beyond ORDER BY RAND())  |
|  [Data Warehousing High Speed Ingestion](../data-warehousing-high-speed-ingestion/index) |  Ingesting lots of data and performance is bottlenecked in the INSERT area. What to do?  |
|  [Data Warehousing Summary Tables](../data-warehousing-summary-tables/index) |  Creation and maintenance of summary tables  |
|  [Data Warehousing Techniques](../data-warehousing-techniques/index) |  Improving performance for data-warehouse-like tables  |
|  [Equality propagation optimization](../equality-propagation-optimization/index) |  Basic idea Consider a query with a WHERE clause: WHERE col1=col2 AND ... t...  |
|  [FORCE INDEX](../force-index/index) |  Similar to USE INDEX, but tells the optimizer to regard a table scan as very expensive.  |
|  [Groupwise Max in MariaDB](../groupwise-max-in-mariadb/index) |  Finding the largest row for each group.  |
|  [GUID/UUID Performance](../guiduuid-performance/index) |  GUID/UUID performance (type 1 only).  |
|  [hash\_join\_cardinality optimizer\_switch Flag](../hash_join_cardinality-optimizer_switch-flag/index) |  MariaDB starting with [10.6.13...](/kb/en/mariadb-10613-release-notes/)  |
|  [IGNORE INDEX](../ignore-index/index) |  Tell the optimizer to not consider a particular index.  |
|  [not\_null\_range\_scan Optimization](../not_null_range_scan-optimization/index) |  Enables constructing range scans from NOT NULL conditions inferred from the WHERE clause.  |
|  [Optimizing for "Latest News"-style Queries](../optimizing-for-latest-news-style-queries/index) |  Optimizing the schema and code for "Latest News"-style queries  |
|  [Pagination Optimization](../pagination-optimization/index) |  Pagination, not with OFFSET, LIMIT  |
|  [Pivoting in MariaDB](../pivoting-in-mariadb/index) |  Pivoting data so a linear list of values with two keys becomes a spreadsheet-like array.  |
|  [Rollup Unique User Counts](../rollup-unique-user-counts/index) |  Technique for counting unique users  |
|  [Rowid Filtering Optimization](../rowid-filtering-optimization/index) |  Rowid filtering is an optimization available from MariaDB 10.4.  |
|  [USE INDEX](../use-index/index) |  Find rows in the table using only one of the named indexes.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-optimizations/>

Writing Logs Into Tables
========================

    By default, all logs are disabled or written into files. The [general query log](../general-query-log/index) and the [slow query log](../slow-query-log/index) can also be written to special tables in the `mysql` database. During the startup, entries will always be written into files.

 Note that [EXPLAIN output](../explain-in-the-slow-query-log/index) will only be recorded if the slow query log is written to a file and not to a table.

 To write logs into tables, the [log\_output](../server-system-variables/index#log_output) server system variable is used. Allowed values are `FILE`, `TABLE` and `NONE`. It is possible to specify multiple values, separated with commas, to write the logs into both tables and files. `NONE` disables logging and has precedence over the other values.

 So, to write logs into tables, one of the following settings can be used:

 
```
SET GLOBAL log_output = 'TABLE';
SET GLOBAL log_output = 'FILE,TABLE';

```

The general log will be written into the [general\_log](../mysqlgeneral_log-table/index) table, and the slow query log will be written into the [slow\_log](../mysqlslow_log-table/index) table. Only a limited set of operations are supported for those special tables. For example, direct DML statements (like `INSERT`) on those tables will fail with an error similar to the following:

 
```
ERROR 1556 (HY000): You can't use locks with log tables.

```

To flush data to the tables, use [FLUSH TABLES](../flush/index) instead of [FLUSH LOGS](../flush/index).

 To empty the contents of the log tables, [TRUNCATE TABLE](../truncate-table/index) can be used.

 The log tables use the [CSV](../csv/index) storage engine by default. This allows an external program to read the files if needed: normal CSV files are stored in the `mysql` subdirectory, in the data dir. However that engine is slow because it does not support indexes, so you can convert the tables to [MyISAM](../myisam/index) (but not other storage engines). To do so, first temporarily disable logging:

 
```
SET GLOBAL general_log = 'OFF';
ALTER TABLE mysql.general_log ENGINE = MyISAM;
ALTER TABLE mysql.slow_log ENGINE = MyISAM;
SET GLOBAL general_log = @old_log_state;

```

[CHECK TABLE](../sql-commands-check-table/index) and [CHECKSUM TABLE](../checksum-table/index) are supported.

 [CREATE TABLE](../create-table/index) is supported. [ALTER TABLE](../alter-table/index), [RENAME TABLE](../rename-table/index) and [DROP TABLE](../drop-table/index) are supported when logging is disabled, but log tables cannot be partitioned.

 The contents of the log tables is not logged in the [binary log](../binary-log/index) thus cannot be replicated.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/writing-logs-into-tables/>

Mariabackup
============

   Mariabackup is an open source tool provided by MariaDB for performing physical online backups of InnoDB, MyRocks, Aria and MyISAM tables.

  

| Title | Description |
| --- | --- |
|  [Mariabackup Overview](../mariabackup-overview/index) |  The Mariabackup utility performs physical backups and supports Data-at-Rest...  |
|  [Mariabackup Options](../mariabackup-options/index) |  Options for Mariabackup.  |
|  [Full Backup and Restore with Mariabackup](../full-backup-and-restore-with-mariabackup/index) |  Taking complete backups of databases and restoring from a complete backup.  |
|  [Incremental Backup and Restore with Mariabackup](../incremental-backup-and-restore-with-mariabackup/index) |  Backing up incremental changes of a database  |
|  [Partial Backup and Restore with Mariabackup](../partial-backup-and-restore-with-mariabackup/index) |  Taking partial backups of databases and restoring from a partial backup.  |
|  [Restoring Individual Tables and Partitions with Mariabackup](../restoring-individual-tables-and-partitions-with-mariabackup/index) |  Restoring individual tables and partitions from a backup.  |
|  [Setting up a Replica with Mariabackup](../setting-up-a-replica-with-mariabackup/index) |  Setting up a replica with Mariabackup.  |
|  [Files Backed Up By Mariabackup](../files-backed-up-by-mariabackup/index) |  Mariabackup backs up many different files in order to perform its operations.  |
|  [Files Created by Mariabackup](../files-created-by-mariabackup/index) |  Mariabackup creates many different files in order to perform its operations.  |
|  [Using Encryption and Compression Tools With Mariabackup](../using-encryption-and-compression-tools-with-mariabackup/index) |  Mariabackup supports streaming to stdout, allowing easy integration with popular tools.  |
|  [How Mariabackup Works](../how-mariabackup-works/index) |  Description of the different Mariabackup stages, what they do and why they are needed.  |
|  [Mariabackup and BACKUP STAGE Commands](../mariabackup-and-backup-stage-commands/index) |  How Mariabackup could use BACKUP STAGE commands.  |
|  [mariabackup SST Method](../mariabackup-sst-method/index) |  The mariabackup SST method uses the Mariabackup utility for performing SSTs.  |
|  [Manual SST of Galera Cluster Node With Mariabackup](../manual-sst-of-galera-cluster-node-with-mariabackup/index) |  It can be helpful to perform a "manual SST" with Mariabackup when Galera's normal SSTs fail.  |
|  [Individual Database Restores with MariaBackup from Full Backup](../individual-database-restores-with-mariabackup-from-full-backup/index) |  Restoring individual databases with MariaBackup from full backup.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariabackup/>

mariadb-dump
============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-dump` is a symlink to `mysqldump`, the backup tool. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-dump` is the name of the tool, with `mysqldump` a symlink .

 
The `mariadb-dump` client (originally called `mysqldump`)is a backup program originally written by Igor Romanenko. It can be used to dump a database or a collection of databases for backup or transfer to another database server (not necessarily MariaDB or MySQL). The dump typically contains SQL statements to create the table, populate it, or both. However, `mariadb-dump` can also be used to generate files in CSV, other delimited text, or XML format.

 If you are doing a backup on the server and your tables all are [MyISAM](../myisam/index) tables, consider using [mariadb-hotcopy](../mariadb-hotcopy/index) instead because it can accomplish faster backups and faster restores.

 mariadb-dump dumps triggers along with tables, as these are part of the table definition. However, [stored procedures](../stored-procedures/index), [views](../views/index), and [events](../events/index) are not, and need extra parameters to be recreated explicitly (for example, `--routines` and `--events`). [Procedures](../stored-procedures/index) and <functions> are however also part of the system tables (for example [mysql.proc](../mysqlproc-table/index)).

 `mariadb-dump` supports the [enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index#mariadb-dump). 

 Performance
-----------

 mariadb-dump doesn't usually consume much CPU resources on modern hardware as by default it uses a single thread. This method is good for a heavily loaded server.

 Disk input/outputs per second (IOPS), can however increase for multiple reasons. When you back-up on the same device as the database, this produces unnecessary random IOPS. The dump is done sequentially, on a per table basis, causing a full-table scan and many buffer page misses on tables that are not fully cached in memory. 

 It's recommended that you back-up from a network location to remove disk IOPS on the database server, but it is vital to use a separate network card to keep network bandwidth available for regular traffic.

 Although mariadb-dump will by default preserve your resources for regular spindle disks and low-core hardware, this doesn't mean that concurrent dumps cannot benefit from hardware architecture like SAN, flash storage, low write workload. The back-up time would benefit from a tool such as MyDumper.

 Usage
-----

 There are four general ways to invoke `mariadb-dump`:

 
```
shell> mariadb-dump [options] db_name [tbl_name ...]
shell> mariadb-dump [options] --databases db_name ...
shell> mariadb-dump [options] --all-databases
shell> mariadb-dump [options] --system=[option_list]

```

If you do not name any tables following db\_name or if you use the `--databases` or `--all-databases` option, entire databases are dumped.

 `mariadb-dump` does not dump the INFORMATION\_SCHEMA (or PERFORMANCE\_SCHEMA, if enabled) database by default. MariaDB dumps the `INFORMATION_SCHEMA` if you name it explicitly on the command line, although currently you must also use the `--skip-lock-tables` option.

 To see a list of the options your version of `mariadb-dump` supports, execute `mariadb-dump --help`.

 ### Row by Row vs. Buffering

 `mariadb-dump` can retrieve and dump table contents row by row, or it can retrieve the entire content from a table and buffer it in memory before dumping it. Buffering in memory can be a problem if you are dumping large tables. To dump tables row by row, use the `--quick` option (or `--opt`, which enables `--quick`). The `--opt` option (and hence `--quick`) is enabled by default, so to enable memory buffering, use `--skip-quick`.

 ### mariadb-dump and the mysql.transaction\_registry\_table

 `mariadb-dump` includes logic to cater for the [mysql.transaction\_registry table](../mysqltransaction_registry-table/index). `mysqldump` from an earlier MariaDB release cannot be used on [MariaDB 10.3](../what-is-mariadb-103/index) and beyond.

 ### mariadb-dump and Old Versions of MySQL

 If you are using a recent version of `mariadb-dump` to generate a dump to be reloaded into a very old MySQL server, you should not use the `--opt` or `--extended-insert` option. Use `--skip-opt` instead.

 ### Options

 `mariadb-dump` supports the following options:

 


| Option | Description |
| --- | --- |
| `--all` | Deprecated. Use `--create-options` instead. |
| `-A`, `--all-databases` | Dump all the databases. This will be same as `--databases` with all databases selected. |
| `-Y`, `--all-tablespaces` | Dump all the tablespaces. |
| `-y`, `--no-tablespaces` | Do not dump any tablespace information. |
| `--add-drop-database` | Add a [DROP DATABASE](../drop-database/index) before each create. Typically used in conjunction with the `--all-databases` or `--databases` option because no [CREATE DATABASE](../create-database/index) statements are written unless one of those options is specified. |
| `--add-drop-table` | Add a [DROP TABLE](../drop-table/index) before each create. |
| `--add-drop-trigger` | Add a [DROP TRIGGER](../drop-trigger/index) statement before each [CREATE TRIGGER](../create-trigger/index). From [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/). |
| `--add-locks` | Add locks around [INSERT](../insert/index) statements, which results in faster inserts when the dump file is reloaded. Use `--skip-add-locks` to disable. |
| `--allow-keywords` | Allow creation of column names that are keywords. This works by prefixing each column name with the table name. |
| `--apply-slave-statements` | Adds [STOP SLAVE](../stop-slave/index) prior to [CHANGE MASTER](../change-master-to/index) and [START SLAVE](../start-slave/index) to bottom of dump. |
| `--as-of` | Dump [system versioned table](../system-versioned-tables/index) as of specified timestamp. From [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/). |
| `--character-sets-dir=name` | Directory for [character set](../data-types-character-sets-and-collations/index) files. |
| `-i`, `--comments` | Write additional information in the dump file such as program version, server version, and host. Disable with `--skip-comments`. |
| `--compact` | Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables the `--skip-add-drop-table`, `--skip-add-locks`, `--skip-comments`, `--skip-disable-keys`, and `--skip-set-charset` options. |
| `--compatible=name` | Change the dump to be compatible with a given mode. By default tables are dumped in a format optimized for MariaDB and MySQL. Legal modes are: `ansi`, `mysql323`, `mysql40`, `postgresql`, `oracle`, `mssql`, `db2`, `maxdb`, `no_key_options`, `no_table_options`, and `no_field_options`. One can use several modes separated by commas.This option does not guarantee compatibility with other servers. It only enables those SQL mode values that are currently available for making dump output more compatible. For example, `--compatible=oracle` does not map data types to Oracle types or use Oracle comment syntax. |
| `-c`, `--complete-insert` | Use complete [INSERT](../insert/index) statements that include column names. |
| `-C`, `--compress` | Use compression in server/client protocol. Both client and server must support compression for this to work. |
| `--copy-s3-tables` | By default [S3](../s3-storage-engine/index) tables are ignored. With this option set, the result file will contain a CREATE statement for a similar [Aria](../aria-storage-engine/index) table, followed by the table data and ending with an `ALTER TABLE xxx ENGINE=S3`. From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). |
| `-a`, `--create-options` | Include all MariaDB and/or MySQL specific create options in `CREATE TABLE` statements. Use `--skip-create-options` to disable. |
| `-B`, `--databases` | Dump several databases. Normally, `mariadb-dump` treats the first name argument on the command line as a database name and following names as table names. With this option, it treats all name arguments as database names. [CREATE DATABASE](../create-database/index) and [USE](../use/index) statements are included in the output before each new database. |
| `-#, --debug[=#]` | If using a debug version of MariaDB, write a debugging log. A typical debug\_options string is ´d:t:o,file\_name´. The default value is ´d:t:o,/tmp/mysqldump.trace´. If using a non-debug version, `mariadb-dump` will catch this and exit. |
| `--debug-check` | Check memory and open file usage at exit. |
| `--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](../data-types-character-sets-and-collations/index) to *name*. If no character set is specified *mariadb-dump* uses utf8mb4. |
| `--defaults-extra-file=name` | Read the file *name* after the global files are read. Must be given as the first argument. |
| `--defaults-file=name` | Only read default options from the given file *name*. Must be given as the first argument. |
| `--defaults-group-suffix=str` | Also read groups with a suffix of *str*. For example, since *mariadb-dump* normally reads the [client] and [mariadb-dump] (or [mysqldump]) groups, --defaults-group-suffix=x would cause it to also read the groups [mariadb-dump\_x] (or [mysqldump\_x]) and [client\_x]. |
| `--delayed-insert` | Insert rows with [INSERT DELAYED](../insert-delayed/index) instead of [INSERT](../insert/index). |
| `--delete-master-logs` | On a primary replication server, delete the binary logs by sending a [PURGE BINARY LOGS](../sql-commands-purge-logs/index) statement to the server after performing the dump operation. This option automatically enables `--master-data`. |
| `-K`, `--disable-keys` | `'/*!40000 ALTER TABLE tb_name DISABLE KEYS */;` and `'/*!40000 ALTER TABLE tb_name ENABLE KEYS */;` will be put in the output. This makes loading the dump file faster because the indexes are created after all rows are inserted. This option is effective only for non-unique indexes of MyISAM tables. Disable with `--skip-disable-keys`. |
| `--dump-date` | If the `--comments` option and this option are given, `mariadb-dump` produces a comment at the end of the dump of the following form:`-- Dump completed on DATE` However, the date causes dump files taken at different times to appear to be different, even if the data are otherwise identical. `--dump-date` and `--skip-dump-date` control whether the date is added to the comment. The default is `--dump-date` (include the date in the comment). `--skip-dump-date` suppresses date printing. |
| `-H`, `--dump-history` | Dump tables with [history](../system-versioned-tables/index). From [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/). Until this option, `mariadb-dump` could not read historical rows from versioned tables, and so historical data would not be backed up. |
| `--dump-slave[=value]` | Used for producing a dump file from a replica server that can be used to set up another replica server with the same primary. Causes the [binary log](../binary-log/index) position and filename of the primary to be appended to the dumped data output. Setting the value to `1` (the default) will print it as a [CHANGE MASTER](../change-master-to/index) command in the dumped data output; if set to `2`, that command will be prefixed with a comment symbol. This option will turn `--lock-all-tables` on, unless `--single-transaction` is specified too (in which case a global read lock is only taken a short time at the beginning of the dump - don't forget to read about `--single-transaction` below). In all cases any action on logs will happen at the exact moment of the dump. Option automatically turns `--lock-tables` off. Using this option causes mariadb-dump to stop the replica SQL thread before beginning the dump, and restart it again after completion. |
| `-E, --events` | Include [Event Scheduler events](../stored-programs-and-views-events/index) for the dumped databases in the output. |
| `-e`, `--extended-insert` | Use multiple-row [INSERT](../insert/index) syntax that include several `VALUES` lists. This results in a smaller dump file and speeds up inserts when the file is reloaded. Defaults to on; use `--skip-extended-insert` to disable. |
| `--fields-terminated-by=name` | Fields in the output file are terminated by the given string. Used with the `--tab` option and has the same meaning as the corresponding `FIELDS` clause for [LOAD DATA INFILE](../load-data-infile/index). |
| `--fields-enclosed-by=name` | Fields in the output file are enclosed by the given character. Used with the `--tab` option and has the same meaning as the corresponding `FIELDS` clause for [LOAD DATA INFILE](../load-data-infile/index). |
| `--fields-optionally-enclosed-by=name` | Fields in the output file are optionally enclosed by the given character. Used with the `--tab` option and has the same meaning as the corresponding `FIELDS` clause for [LOAD DATA INFILE](../load-data-infile/index). |
| `--fields-escaped-by=name` | Fields in the output file are escaped by the given character. Used with the `--tab` option and has the same meaning as the corresponding `FIELDS` clause for [LOAD DATA INFILE](../load-data-infile/index). |
| `--first-slave` | Removed in [MariaDB 5.5](../what-is-mariadb-55/index). Use `--lock-all-tables` instead. |
| `-F`, `--flush-logs` | Flush the MariaDB server log files before starting the dump. This option requires the `RELOAD` privilege. If you use this option in combination with the `--databases=` or `--all-databases` option, the logs are flushed for each database dumped. The exception is when using `--lock-all-tables`or `--master-data`: In this case, the logs are flushed only once, corresponding to the moment all tables are locked. If you want your dump and the log flush to happen at the same exact moment, you should use `--flush-logs` together with either `--lock-all-tables` or `--master-data`. |
| `--flush-privileges` | Send a [FLUSH PRIVILEGES](../flush/index) statement to the server after dumping the [mysql database](../the-mysql-database-tables/index). This option should be used any time the dump contains the mysql database and any other database that depends on the data in the mysql database for proper restoration. |
| `-f`, ``--force`` | Continue even if an SQL error occurs during a table dump.One use for this option is to cause *mariadb-dump* to continue executing even when it encounters a view that has become invalid because the definition refers to a table that has been dropped. Without `--force` in this example, `mariadb-dump` exits with an error message. With `--force`, *mariadb-dump* prints the error message, but it also writes an SQL comment containing the view definition to the dump output and continues executing. |
| `--gtid` | Used together with `--master-data` and `--dump-slave` to more conveniently set up a new [GTID](../gtid/index) replica. It causes those options to output SQL statements that configure the replica to use the [global transaction ID](../global-transaction-id/index) to connect to the primary instead of old-style filename/offset positions. The old-style positions are still included in comments when `--gtid` is used; likewise the GTID position is included in comments even if `--gtid` is not used. |
| `-?`, `--help` | Display a help message and exit. |
| `--hex-blob` | Dump binary strings in hexadecimal format (for example, `´abc´` becomes `0x616263`). The affected data types are [BINARY](../binary/index), [VARBINARY](../varbinary/index), the [BLOB](../blob/index) types, and [BIT](../bit/index). |
| `-h name`, `--host=name` | Connect to and dump data from the MariaDB or MySQL server on the given host. The default host is `localhost`. |
| `--ignore-database=name` | Do not dump the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. Only takes effect when used together with `--all-databases` or `-A`. Added in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/). |
| `--ignore-table=name` | Do not dump the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names, e.g., `--ignore-table=database.table`. This option also can be used to ignore views. |
| `--ignore-table-data=name` | Do not dump the specified table data (only the structure). To specify more than one table to ignore, use the directive multiple times, once for each table. Each table must be specified with both database and table names. From [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/). See also `--no-data`. |
| `--include-master-host-port` | Add the `MASTER_HOST` and `MASTER_PORT` options for the [CHANGE MASTER TO](../change-master-to/index) statement when using the `--dump-slave` option for a replica dump. |
| `--insert-ignore` | Insert rows with `INSERT IGNORE` instead of `INSERT`. |
| `--lines-terminated-by=name` | Lines in the output file are terminated by the given string. This option is used with the `--tab` option and has the same meaning as the corresponding `LINES` clause for [LOAD DATA INFILE](../load-data-infile/index). |
| `-x`, `--lock-all-tables` | Lock all tables across all databases. This is achieved by acquiring a global read lock for the duration of the whole dump by executing [FLUSH TABLES WITH READ LOCK](../flush/index). This option automatically turns off `--single-transaction` and `--lock-tables`. |
| `-l`, `--lock-tables` | For each dumped database, lock all tables to be dumped before dumping them. The tables are locked with `READ LOCAL` to allow concurrent inserts in the case of [MyISAM](../myisam/index) tables. For transactional tables such as [InnoDB](../innodb/index), `--single-transaction` is a much better option than `--lock-tables` because it does not need to lock the tables at all.Because `--lock-tables` locks tables for each database separately, this option does not guarantee that the tables in the dump file are logically consistent between databases. Tables in different databases may be dumped in completely different states. Use `--skip-lock-tables` to disable. |
| `--log-error=name` | Log warnings and errors by appending them to the named file. The default is to do no logging. |
| `--log-queries` | When restoring the dump, the server will, if logging is turned on, log the queries to the general and [slow query log](../slow-query-log/index). Defaults to on; use --skip-log-queries to disable. Added in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/). |
| `--master-data[=#]` | Causes the [binary log](../binary-log/index) position and filename to be appended to the output, useful for dumping a primary replication server to produce a dump file that can be used to set up another server as a replica of the primary. These are the primary server coordinates from which the replica should start replicating after you load the dump file into the replica. If the option is set to 1 (the default), will print it as a [CHANGE MASTER](../change-master-to/index) command; if set to 2, that command will be prefixed with a comment symbol. This `--master-data` option will turn `--lock-all-tables` on, unless `--single-transaction` is specified too. Before [MariaDB 5.3](../what-is-mariadb-53/index) this would take a global read lock for a short time at the beginning of the dump - see [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index) and the `--single-transaction` option below). In all cases, any action on logs will happen at the exact moment of the dump. This option automatically turns `--lock-tables` off. In all cases, any action on logs happens at the exact moment of the dump. It is also possible to set up a replica by dumping an existing replica of the primary. To do this, use the following procedure on the existing replica:1. Stop the replica's SQL thread and get its current status:`mariadb> STOP SLAVE SQL_THREAD;``mariadb> SHOW SLAVE STATUS;`2. From the output of the SHOW SLAVE STATUS statement, the binary log coordinates of the primary server from which the new replica should start replicating are the values of the Relay\_Master\_Log\_File and Exec\_Master\_Log\_Pos fields. Denote those values as file\_name and file\_pos.2. Dump the replica server:`shell> mariadb-dump --master-data=2 --all-databases > dumpfile`3. Restart the replica:`mariadb> START SLAVE;`4. On the new replica, load the dump file:`shell> mariadb < dumpfile`5. On the new replica, set the replication coordinates to those of the primary server obtained earlier:`mariadb> CHANGE MASTER TO MASTER_LOG_FILE = ´file_name´, MASTER_LOG_POS = file_pos;` The `CHANGE MASTER` TO statement might also need other parameters, such as MASTER\_HOST to point the replica to the correct primary server host. Add any such parameters as necessary. |
| `--max-allowed-packet=#`  | The maximum packet length to send to or receive from server. The maximum is 1GB. |
| `--max-statement-time=#`  | Sets the maximum time any statement can run before being timed out by the server. (Default value is 0 (no limit)) |
| `--net-buffer-length=#`  | The initial buffer size for client/server TCP/IP and socket communication. This can be used to limit the size of rows in the dump. When creating multiple-row `INSERT` statements (as with the `--extended-insert` or `--opt` option), `mariadb-dump` creates rows up to `net_buffer_length` length. |
| `--no-autocommit` | Enclose the [INSERT](../insert/index) statements for each dumped table within [SET autocommit = 0](../server-system-variables/index#autocommit) and [COMMIT](../commit/index) statements. |
| `-n`, `--no-create-db` | This option suppresses the [CREATE DATABASE ... IF EXISTS](../create-database/index) statement that normally is output for each dumped database if `--all-databases` or `--databases` is given. |
| `-t`, `--no-create-info` | Do not write [CREATE TABLE](create-tablle) statements which re-create each dumped table. |
| `-d`, `--no-data` | Do not write any table row information (that is, do not dump table contents). This is useful if you want to dump only the [CREATE TABLE](../create-table/index) statement for the table (for example, to create an empty copy of the table by loading the dump file). See also --ignore-table-data . |
| `--no-data-med` | Do not dump rows for engines that manage external data (i.e. [MRG\_MyISAM](../merge/index), MRG\_ISAM, [CONNECT](../connect/index), [OQGRAPH](../oqgraph-storage-engine/index), [Spider](../spider/index), VP, [Federated](../federatedx-storage-engine/index)). This option is enabled by default. If you want to dump data for these engines, then you would need to set `--no-data-med=0`. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first argument. |
| `-N`, `--no-set-names` | Suppress the `SET NAMES` statement. This has the same effect as `--skip-set-charset`. |
| `--opt` | This option is shorthand. It is the same as specifying `--add-drop-table`, `--add-locks`, `--create-options`, `--quick`, `--extended-insert`, `--lock-tables`, `--set-charset`, and `--disable-keys`. Enabled by default, disable with `--skip-opt`. It should give you a fast dump operation and produce a dump file that can be reloaded into a MariaDB server quickly.The `--opt` option is enabled by default. Use `--skip-opt` to disable it. See the discussion at the beginning of this section for information about selectively enabling or disabling a subset of the options affected by `--opt`. |
| `--order-by-primary` | Sorts each table's rows by primary key, or first unique key, if such a key exists. This is useful when dumping a [MyISAM](../myisam/index) table to be loaded into an [InnoDB](../innodb/index) table, but will make the dump itself take considerably longer. |
| `--order-by-size` | Dump each table according to their size, smallest first. Useful when using `--single-transaction` on tables which get truncated/altered often. The assumption here is that smaller tables get truncated more often, and by dumping those first, this reduces the chance that a `--single-transaction` dump will fail with with 'Table definition has changed, please retry transaction'. From [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/). |
| `-p[passwd]`, `--password[=passwd` | The password to use when connecting to the server. If you use the short option form (`-p`), you cannot have a space between the option and the password. If you omit the password value following the `--password` or `-p` option on the command line, *mariadb-dump* prompts for one.Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `-W`, `--pipe` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `--plugin-dir` | Directory for client-side plugins. |
| `-P num`, `--port=num` | The TCP/IP port number to use for the connection. |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first argument. |
| `--protocol=name` | The connection protocol to use for connecting to the server (TCP, SOCKET, PIPE, MEMORY). It is useful when the other connection parameters normally would cause a protocol to be used other than the one you want. |
| `-q`, `--quick` | This option is useful for dumping large tables. It forces *mariadb-dump* to retrieve rows for a table from the server a row at a time and to then dump the results directly to stdout rather than retrieving the entire row set and buffering it in memory before writing it out. Defaults to on, use `--skip-quick` to disable. |
| `-Q`, `--quote-names` | Quote identifiers (such as database, table, and column names) within backtick (```) characters. If the `ANSI_QUOTES` SQL mode is enabled, identifiers are quoted within (`"`) characters. This option is enabled by default. It can be disabled with `--skip-quote-names`, but this option should be given after any option such as `--compatible` that may enable `--quote-names`. |
| `--replace` | Use [REPLACE INTO](../replace/index) statements instead of [INSERT INTO](../insert/index) statements. |
| `-r`, `--result-file=name` | Direct output to a given file. This option should be used on Windows to prevent newline `"\n"` characters from being converted to `"\r\n"` carriage return/newline sequences. The result file is created and its previous contents overwritten, even if an error occurs while generating the dump. |
| `-R`, `--routines` | Include stored routines ([procedures](../stored-procedures/index) and [functions](../stored-functions/index)) for the dumped databases in the output. Use of this option requires the `SELECT` privilege for the [mysql.proc](../mysqlproc-table/index) table. The output generated using `--routines` contains [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) statements to re-create the routines. However, these statements do not include attributes such as the routine creation and modification timestamps. This means that when the routines are reloaded, they will be created with the timestamps equal to the reload time.If you require routines to be re-created with their original timestamp attributes, do not use `--routines`. Instead, dump and reload the contents of the [mysql.proc](../mysqlproc-table/index) table directly, using a MariaDB account which has appropriate privileges for the mysql database. |
| `set-charset` | Add `'SET NAMES default_character_set'` to the output in order to set the [character set](../data-types-character-sets-and-collations/index). Enabled by default; suppress with `--skip-set-charset`. |
| `-O, --set-variable=name` | Change the value of a variable. Please note that this option is deprecated; you can set variables directly with `--variable-name=value`. |
| `--shared-memory-base-name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. Defaults to `MYSQL`. |
| `--single-transaction` | This option sends a [START TRANSACTION](../start-transaction/index) SQL statement to the server before dumping data. It is useful only with transactional tables such as [InnoDB](../innodb/index), because then it dumps the consistent state of the database at the time when `BEGIN` was issued without blocking any applications.When using this option, you should keep in mind that only InnoDB tables are dumped in a consistent state. The single-transaction feature depends not only on the engine being transactional and capable of REPEATABLE-READ, but also on START TRANSACTION WITH CONSISTENT SNAPSHOT. The dump is **not** guaranteed to be consistent for other storage engines. For example, any [TokuDB](../tokudb/index), [MyISAM](../myisam/index) or [MEMORY](../memory-storage-engine/index) tables dumped while using this option may still change state.While a `--single-transaction` dump is in process, to ensure a valid dump file (correct table contents and binary log coordinates), no other connection should use the following statements: [ALTER TABLE](../alter-table/index), [CREATE TABLE](../create-table/index), [DROP TABLE](../drop-table/index), [RENAME TABLE](../rename-table/index), or [TRUNCATE TABLE](../truncate-table/index). A consistent read is not isolated from those statements, so use of them on a table to be dumped can cause the `SELECT` (performed by *mariadb-dump* to retrieve the table contents) to obtain incorrect contents or fail.The `--single-transaction` option and the `--lock-tables` option are mutually exclusive because [LOCK TABLES](../lock-tables-and-unlock-tables/index) causes any pending transactions to be committed implicitly. So this option automatically turns off `--lock-tables`To dump large tables, you should combine the `--single-transaction` option with `--quick`. |
| `--skip-add-locks` | Disable the `--add-locks` option. |
| `--skip-comments` | Disable the `--comments` option. |
| `--skip-disable-keys` | Disable the `--disable-keys` option. |
| `--skip-extended-insert` | Disable the `--extended-insert` option. |
| `--skip-opt` | Disable the `--opt` option (disables `--add-drop-table`, `--add-locks`, `--create-options`, `--quick`, `--extended-insert`, `--lock-tables`, `--set-charset`, and `--disable-keys`). |
| `--skip-quick` | Disable the `--quick` option. |
| `--skip-quote-name` | Disable the `--quote-names` option. |
| `--skip-set-charset` | Disable the `--set-charset` option. |
| `--skip-triggers` | Disable the `--triggers` option. |
| `--skip-tz-utc` | Disable the `--tz-utc` option. |
| `-S name`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `--system=option[,option]]` | Dump the database's system tables in a logical form. With this option, the [mysql database](../the-mysql-database-tables/index) tables are dumped as [CREATE USER](../create-user/index), [CREATE SERVER](../create-server/index) and other forms of logical portable SQL statements. The option values here are from the set of `all`, `users`, `plugins`, `udfs`, `servers`, `stats`, `timezones`. From [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/) and [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/). |
| `-T`, `--tab=name` | Produce tab-separated text-format data files. With this option, for each dumped table `mariadb-dump` will create a `tbl_name.sql` file containing the `CREATE TABLE` statement that creates the table, and a `tbl_name.txt` file containing the table's data. The option value is the directory in which to write the files.**Note:** *This option can only be used when* mariadb-dump/ is run on the same machine as the mysqld server. You must have the `FILE` privilege, and the server must have permission to write files in the directory that you specify.*By default, the `.txt` data files are formatted using tab characters between column values and a newline at the end of each line. The format can be specified explicitly using the `--fields-xxx` and `--lines-terminated-by` options. Column values are converted to the character set specified by the `--default-character-set` option.* |
| `--tables` | This option overrides the `--databases` (`-B`) option. *mariadb-dump* regards all name arguments following the option as table names. |
| `--tls-version=name` | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. This option was added in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `--triggers` | Include [triggers](../triggers/index) for each dumped table in the output. This option is enabled by default; disable it with `--skip-triggers`. |
| `--tz-utc` | This option enables [TIMESTAMP](../timestamp/index) columns to be dumped and reloaded between servers in different time zones. *mariadb-dump* sets its connection time zone to UTC and adds `SET TIME_ZONE=´+00:00´` to the dump file. Without this option, TIMESTAMP columns are dumped and reloaded in the time zones local to the source and destination servers, which can cause the values to change if the servers are in different time zones. `--tz-utc` also protects against changes due to daylight saving time. `--tz-utc` is enabled by default. To disable it, use `--skip-tz-utc`. |
| `-u name`, `--user=name` | The MariaDB user name to use when connecting to the server. |
| `-v`, `--verbose` | Verbose mode. Print more information about what the program is doing during various stages. |
| `-V`, `--version` | Output version information and exit. |
| `-w cond`, `--where=cond` | Dump only rows selected by the given `WHERE` condition *cond*. Quotes around the condition are mandatory if it contains spaces or other characters that are special to your command interpreter.Examples:`--where="user=´jimf´"` `-w"userid>1"` `-w"userid<1"` |
| `-X`, `--xml` | Dump a database as well formed XML. |

 
#### Group Options

 Some `mariadb-dump` options are shorthand for groups of other options:

 * Use of `--opt` is the same as specifying `--add-drop-table`, `--add-locks`, `--create-options`, `--disable-keys`, `--extended-insert`, `--lock-tables`, `--quick`, and `--set-charset`. All of the options that `--opt` stands for also are on by default because `--opt` is on by default.
* Use of `--compact` is the same as specifying `--skip-add-drop-table`, `--skip-add-locks`, `--skip-comments`, `--skip-disable-keys`, and `--skip-set-charset` options.

 To reverse the effect of a group option, uses its `--skip-xxx` form (`--skip-opt` or `--skip-compact`). It is also possible to select only part of the effect of a group option by following it with options that enable or disable specific features. Here are some examples:

 * To select the effect of `--opt` except for some features, use the `--skip` option for each feature. To disable extended inserts and memory buffering, use `--opt` `--skip-extended-insert` `--skip-quick`. (Actually, `--skip-extended-insert` `--skip-quick` is sufficient because `--opt` is on by default.)
* To reverse `--opt` for all features except index disabling and table locking, use `--skip-opt` `--disable-keys` `--lock-tables`.

 When you selectively enable or disable the effect of a group option, order is important because options are processed first to last. For example, `--disable-keys` `--lock-tables` `--skip-opt` would not have the intended effect; it is the same as `--skip-opt` by itself.

 #### Special Characters in Option Values

 Some options, like `--lines-terminated-by`, accept a string. The string can be quoted, if necessary. For example, on Unix systems this is the option to enclose fields within double quotes:

 
```
--fields-enclosed-by='"'

```

An alternative to specify the hexadecimal value of a character. For example, the following syntax works on any platform:

 
```
--fields-enclosed-by=0x22

```

### Option Files

 In addition to reading options from the command-line, `mariadb-dump` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-dump` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
`mariadb-dump` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-dump` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqldump]` |  Options read by *mariadb-dump*, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-dump]` | Options read by *mariadb-dump*. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
### NULL, ´NULL´, and Empty Values in XML

 For a column named `column_name`, the `NULL` value, an empty string, and the string value `´NULL´` are distinguished from one another in the output generated by this option as follows.

 


| Value | XML Representation |
| --- | --- |
| NULL (unknown value) | `<field name="column\_name" xsi:nil="true" />` |
| ´´ (empty string) | `<field name="column\_name"></field>` |
| ´NULL´ (string value) | `<field name="column\_name">NULL</field>` |

 
The output from the mariadb client when run using the `--xml` option also follows the preceding rules.

 XML output from mariadb-dump includes the XML namespace, as shown here :

 
```
shell> mariadb-dump --xml -u root world City
<?xml version="1.0"?>
<mariadb-dump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="world">
<table_structure name="City">
<field Field="ID" Type="int(11)" Null="NO" Key="PRI" Extra="auto_increment" />
<field Field="Name" Type="char(35)" Null="NO" Key="" Default="" Extra="" />
<field Field="CountryCode" Type="char(3)" Null="NO" Key="" Default="" Extra="" />
<field Field="District" Type="char(20)" Null="NO" Key="" Default="" Extra="" />
<field Field="Population" Type="int(11)" Null="NO" Key="" Default="0" Extra="" />
<key Table="City" Non_unique="0" Key_name="PRIMARY" Seq_in_index="1" Column_name="ID"
Collation="A" Cardinality="4079" Null="" Index_type="BTREE" Comment="" />
<options Name="City" Engine="MyISAM" Version="10" Row_format="Fixed" Rows="4079"
Avg_row_length="67" Data_length="273293" Max_data_length="18858823439613951"
Index_length="43008" Data_free="0" Auto_increment="4080"
Create_time="2007-03-31 01:47:01" Update_time="2007-03-31 01:47:02"
Collation="latin1_swedish_ci" Create_options="" Comment="" />
</table_structure>
<table_data name="City">
<row>
<field name="ID">1</field>
<field name="Name">Kabul</field>
<field name="CountryCode">AFG</field>
<field name="District">Kabol</field>
<field name="Population">1780000</field>
</row>
...
<row>
<field name="ID">4079</field>
<field name="Name">Rafah</field>
<field name="CountryCode">PSE</field>
<field name="District">Rafah</field>
<field name="Population">92020</field>
</row>
</table_data>
</database>
</mariadb-dump>

```

### Restoring

 To restore a backup created with mariadb-dump, use the [mariadb client](../mariadb-command-line-client/index) to import the dump, for example:

 
```
mariadb db_name < backup-file.sql

```

Variables
---------

 You can also set the following variables (`--variable-name=value`) and boolean options `{FALSE|TRUE}` by using:

 


| Name | Default Values |
| --- | --- |
| `all` | `TRUE` |
| `all-databases` | `FALSE` |
| `all-tablespaces` | `FALSE` |
| `no-tablespaces` | `FALSE` |
| `add-drop-database` | `FALSE` |
| `add-drop-table` | `TRUE` |
| `add-drop-trigger` | `FALSE` |
| `add-locks` | `TRUE` |
| `allow-keywords` | `FALSE` |
| `apply-slave-statements` | FALSE |
| `as-of` | *(No default value)* |
| `character-sets-dir` | *(No default value)* |
| `comments` | `TRUE` |
| `compatible` | *(No default value)* |
| `compact` | `FALSE` |
| `complete-insert` | `FALSE` |
| `compress` | `FALSE` |
| `copy-s3-tables` | FALSE |
| `create-options` | `TRUE` |
| `databases` | `FALSE` |
| `debug-check` | `FALSE` |
| `debug-info` | `FALSE` |
| `default-character-set` | `utf8mb4` |
| `delayed-insert` | `FALSE` |
| `delete-master-logs` | `FALSE` |
| `disable-keys` | `TRUE` |
| `events` | `FALSE` |
| `extended-insert` | `TRUE` |
| `fields-terminated-by` | *(No default value)* |
| `fields-enclosed-by` | *(No default value)* |
| `fields-optionally-enclosed-by` | *(No default value)* |
| `fields-escaped-by` | *(No default value)* |
| `flush-logs` | `FALSE` |
| `flush-privileges` | `FALSE` |
| `force` | `FALSE` |
| `hex-blob` | `FALSE` |
| `host` | *(No default value)* |
| `include-master-host-port` | `FALSE` |
| `insert-ignore` | `FALSE` |
| `lines-terminated-by` | *(No default value)* |
| `lock-all-tables` | `FALSE` |
| `lock-tables` | `TRUE` |
| `log-error` | *(No default value)* |
| `log-queries` | `TRUE` |
| `master-data` | `0` |
| `max_allowed_packet` | `16777216` |
| `net-buffer-length` | `1046528` |
| `no-autocommit` | `FALSE` |
| `no-create-db` | `FALSE` |
| `no-create-info` | `FALSE` |
| `no-data` | `FALSE` |
| `no-data-med` | `TRUE` |
| `order-by-primary` | `FALSE` |
| `port` | `0` |
| `quick` | `TRUE` |
| `quote-names` | `TRUE` |
| `replace` | `FALSE` |
| `routines` | `FALSE` |
| `set-charset` | `TRUE` |
| `single-transaction` | `FALSE` |
| `dump-date` | `TRUE` |
| `socket` | *No default value)* |
| `ssl` | `FALSE` |
| `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-verify-server-cert` | `FALSE` |
| `system` | *(No default value)* |
| `tab` | *(No default value)* |
| `triggers` | `TRUE` |
| `tz-utc` | `TRUE` |
| `user` | *(No default value)* |
| `verbose` | `FALSE` |
| `where` | *(No default value)* |
| `plugin-dir` | *(No default value)* |
| `default-auth` | *(No default value)* |

 
Examples
--------

 A common use of `mariadb-dump` is for making a backup of an entire database:

 
```
shell> mariadb-dump db_name > backup-file.sql

```

You can load the dump file back into the server like this:

 
```
shell> mariadb db_name < backup-file.sql

```

Or like this:

 
```
shell> mariadb -e "source /path-to-backup/backup-file.sql" db_name

```

`mariadb-dump` is also very useful for populating databases by copying data from one MariaDB server to another:

 
```
shell> mariadb-dump --opt db_name | mariadb --host=remote_host -C db_name

```

It is possible to dump several databases with one command:

 
```
shell> mariadb-dump --databases db_name1 [db_name2 ...] > my_databases.sql

```

To dump all databases, use the `--all-databases` option:

 
```
shell> mariadb-dump --all-databases > all_databases.sql

```

For InnoDB tables, `mariadb-dump` provides a way of making an online backup:

 
```
shell> mariadb-dump --all-databases --single-transaction all_databases.sql

```

This backup acquires a global read lock on all tables (using `FLUSH TABLES WITH READ LOCK`) at the beginning of the dump. As soon as this lock has been acquired, the binary log coordinates are read and the lock is released. If long updating statements are running when the FLUSH statement is issued, the MariaDB server may get stalled until those statements finish. After that, the dump becomes lock free and does not disturb reads and writes on the tables. If the update statements that the MariaDB server receives are short (in terms of execution time), the initial lock period should not be noticeable, even with many updates.

 For point-in-time recovery (also known as “roll-forward,” when you need to restore an old backup and replay the changes that happened since that backup), it is often useful to rotate the [binary log](../binary-log/index) or at least know the binary log coordinates to which the dump corresponds:

 
```
shell> mariadb-dump --all-databases --master-data=2 > all_databases.sql

```

Or:

 
```
shell> mariadb-dump --all-databases --flush-logs --master-data=2 > all_databases.sql

```

The `--master-data` and `--single-transaction` options can be used simultaneously, which provides a convenient way to make an online backup suitable for use prior to point-in-time recovery if tables are stored using the InnoDB storage engine.

 See Also
--------

 * [Mariabackup](../mariabackup/index)
* [MariaDB point-in-time recovery](https://www.youtube.com/watch?v=ezHmnNmmcDo) (video)
* [MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/)
* [Upgrading to a newer major version of MariaDB](https://www.youtube.com/watch?v=1kLIXN2DoEo) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-dump/>

mariadb-hotcopy
===============

    
mariadb-hotcopy is deprecated and may be removed in a future release.

 

**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-hotcopy` is a symlink to `mysqlhotcopy`, the deprecated backup script. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-hotcopy` is the name of the script, with `mysqlhotcopy` a symlink .

 
`mariadb-hotcopy` is a Perl script that was originally written (as `mysqlhotcopy`) and contributed by Tim Bunce. It uses [FLUSH TABLES](../flush/index), [LOCK TABLES](../lock-tables/index), and cp or scp to make a database backup. It is a fast way to make a backup of the database or single tables, but it can be run only on the same machine where the database directories are located. `mariadb-hotcopy`> works only for backing up [MyISAM](../myisam/index) and [ARCHIVE](../archive/index) tables. It runs on Unix and NetWare.

 To use `mariadb-hotcopy`, you must have read access to the files for the tables that you are backing up, the SELECT [privilege](../grant/index) for those tables, the RELOAD privilege (to be able to execute FLUSH TABLES), and the LOCK TABLES privilege (to be able to lock the tables).

 
```
shell> mariadb-hotcopy db_name [/path/to/new_directory]
shell> mariadb-hotcopy db_name_1 ... db_name_n /path/to/new_directory

```

Back up tables in the given database that match a regular expression:

 
```
shell> mariadb-hotcopy db_name./regex/

```

The regular expression for the table name can be negated by prefixing it with a tilde (“`~`”):

 
```
shell> mariadb-hotcopy db_name./~regex/

```

 `mariadb-hotcopy` supports the following options, which can be specified on the command line or in the [`mariadb-hotcopy`] and [`client`] option file groups.

 


| Option | Description |
| --- | --- |
| `--help`, `-?` | Display a help message and exit. |
| `--addtodest` | Do not rename target directory (if it exists); merely add files to it. |
| `--allowold` | Do not abort if a target exists; rename it by adding an \_old suffix. |
| `--checkpoint=db_name.tbl_name` | Insert checkpoint entries into the specified database `db_name` and table `tbl_name`. |
| `--chroot=path` | Base directory of the chroot jail in which mysqld operates. The path value should match that of the `--chroot` option given to mysqld. |
| `--debug` | Enable debug output. |
| `--dryrun`, `-n` | Report actions without performing them. |
| `--flushlog` | Flush logs after all tables are locked. |
| `--host=host_name`, `-h host_name` | The host name of the local host to use for making a TCP/IP connection to the local server. By default, the connection is made to localhost using a Unix socket file. |
| `--keepold` | Do not delete previous (renamed) target when done. |
| `--method=command` | The method for copying files (cp or scp). The default is cp. |
| `--noindices` | Do not include full index files for MyISAM tables in the backup. This makes the backup smaller and faster. The indexes for reloaded tables can be reconstructed later with [myisamchk -rq](../myisamchk/index). |
| `--old-server` | Connect to old MySQL-server (before v5.5) which doesn't have [FLUSH TABLES WITH READ LOCK](../flush/index) fully implemented. |
| `--password=password`, `-ppassword` | The password to use when connecting to the server. The password value is not optional for this option, unlike for other MariaDB programs. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `--port=port_num`, `-P port_num` | The TCP/IP port number to use when connecting to the local server. |
| `--quiet`, `-q` | Be silent except for errors. |
| `--record_log_pos=db_name.tbl_name` | Record master and slave status in the specified database db\_name and table tbl\_name. |
| `--regexp=expr` | Copy all databases with names that match the given regular expression. |
| `--resetmaster` | Reset the binary log after locking all the tables. |
| `--resetslave` | Reset the master.info file after locking all the tables. |
| `--socket=path`, `-S path` | The Unix socket file to use for connections to localhost. |
| `--suffix=str` | The suffix to use for names of copied databases. |
| `--tmpdir=path` | The temporary directory. The default is /tmp. |
| `--user=username`, `-u username` | The MariaDB username to use when connecting to the server. |

 
Use perldoc for additional `mariadb-hotcopy` documentation, including information about the structure of the tables needed for the `--checkpoint` and `--record_log_pos` options:

 
```
shell> perldoc mariadb-hotcopy

```

See Also
--------

 * <mariadb-ldump>
* [Mariabackup](../mariabackup/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-hotcopy/>

What is MariaDB Galera Cluster?
===============================

    
The most recent release of [MariaDB 10.11](../what-is-mariadb-1011/index) is:  
 **[MariaDB 10.11.4](https://mariadb.com/kb/en/mariadb-10-11-4-release-notes/) Stable (GA)** [DownloadNow](https://mariadb.com/downloads/)  
 *[Alternate download from mariadb.org](https://mariadb.org/download/?tab=mariadb&release=10.11.4&product=mariadb)*

  About
-----

 ![galera_small]

 MariaDB Galera Cluster is a [virtually synchronous](../about-galera-replication/index) multi-primary cluster for MariaDB. It is available on Linux only, and only supports the [InnoDB](../innodb/index) storage engine (although there is experimental support for [MyISAM](../myisam/index) and, from [MariaDB 10.6](../what-is-mariadb-106/index), [Aria](../aria/index). See the [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) system variable, or, from [MariaDB 10.6](../what-is-mariadb-106/index), the [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) system variable).

 Features
--------

 * [Virtually synchronous replication](../about-galera-replication/index)
* Active-active multi-primary topology
* Read and write to any cluster node
* Automatic membership control, failed nodes drop from the cluster
* Automatic node joining
* True parallel replication, on row level
* Direct client connections, native MariaDB look & feel

 Benefits
--------

 The above features yield several benefits for a DBMS clustering solution, including:

 * No replica lag
* No lost transactions
* Read scalability
* Smaller client latencies

 The [Getting Started with MariaDB Galera Cluster](../getting-started-with-mariadb-galera-cluster/index) page has instructions on how to get up and running with MariaDB Galera Cluster.

 
A great resource for Galera users is [Codership on Google Groups](https://groups.google.com/forum/?fromgroups#!forum/codership-team) (*`codership-team` `'at'` `googlegroups` `(dot)` `com`*) - If you use Galera it is recommended you subscribe.

 
Galera Versions
---------------

 MariaDB Galera Cluster is powered by:

 * MariaDB Server.
* The [Galera wsrep provider library](https://github.com/codership/galera/).

 The functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the [Galera wsrep provider library](https://github.com/codership/galera/) package. The following [Galera](../galera/index) version corresponds to each MariaDB Server version:

 * In [MariaDB 10.4](../what-is-mariadb-104/index) and later, MariaDB Galera Cluster uses [Galera](../galera/index) 4. This means that the wsrep API version is 26 and the [Galera wsrep provider library](https://github.com/codership/galera/) is version 4.X.
* In [MariaDB 10.3](../what-is-mariadb-103/index) and before, MariaDB Galera Cluster uses [Galera](../galera/index) 3. This means that the wsrep API is version 25 and the [Galera wsrep provider library](https://github.com/codership/galera/) is version 3.X.

 See [Deciphering Galera Version Numbers](https://galeracluster.com/library/documentation/versioning-information.html/) for more information about how to interpret these version numbers.

 ### Galera 4 Versions

 The following table lists each version of the [Galera](../galera/index) 4 wsrep provider, and it lists which version of MariaDB each one was first released in. If you would like to install [Galera](../galera/index) 4 using [yum](../yum/index), [apt](../installing-mariadb-deb-files/index#installing-mariadb-with-apt), or [zypper](../installing-mariadb-with-zypper/index), then the package is called `galera-4`.

 


| Galera Version | Released in MariaDB Version |
| --- | --- |
| **26.4.14** | [10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), [10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [10.7.8](https://mariadb.com/kb/en/mariadb-10-7-8-release-notes/), [10.6.12](https://mariadb.com/kb/en/mariadb-10-6-12-release-notes/), [10.5.19](https://mariadb.com/kb/en/mariadb-10-5-19-release-notes/), [10.4.28](https://mariadb.com/kb/en/mariadb-10-4-28-release-notes/) |
| **26.4.13** | [10.10.2](https://mariadb.com/kb/en/mariadb-10-10-2-release-notes/), [10.9.4](https://mariadb.com/kb/en/mariadb-10-9-4-release-notes/), [10.8.6](https://mariadb.com/kb/en/mariadb-10-8-6-release-notes/), [10.7.7](https://mariadb.com/kb/en/mariadb-10-7-7-release-notes/), [10.6.11](https://mariadb.com/kb/en/mariadb-10-6-11-release-notes/), [10.5.18](https://mariadb.com/kb/en/mariadb-10-5-18-release-notes/), [10.4.27](https://mariadb.com/kb/en/mariadb-10-4-27-release-notes/) |
| **26.4.12** | [10.10.1](https://mariadb.com/kb/en/mariadb-10-10-1-release-notes/), [10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/) |
| **26.4.11** | [10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/) |
| **26.4.9** | [10.6.4](https://mariadb.com/kb/en/mariadb-10-6-4-release-notes/), [10.5.12](https://mariadb.com/kb/en/mariadb-10-5-12-release-notes/), [10.4.21](https://mariadb.com/kb/en/mariadb-10-4-21-release-notes/) |
| **26.4.8** | [10.6.1](https://mariadb.com/kb/en/mariadb-10-6-1-release-notes/), [10.5.10](https://mariadb.com/kb/en/mariadb-10-5-10-release-notes/), [10.4.19](https://mariadb.com/kb/en/mariadb-10-4-19-release-notes/) |
| **26.4.7** | [10.5.9](https://mariadb.com/kb/en/mariadb-10-5-9-release-notes/), [10.4.18](https://mariadb.com/kb/en/mariadb-10-4-18-release-notes/) |
| **26.4.6** | [10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/) |
| **26.4.5** | [10.5.4](https://mariadb.com/kb/en/mariadb-10-5-4-release-notes/), [10.4.14](https://mariadb.com/kb/en/mariadb-10-4-14-release-notes/) |
| **26.4.4** | [10.5.1](https://mariadb.com/kb/en/mariadb-10-5-1-release-notes/), [10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/) |
| **26.4.3** | [10.5.0](https://mariadb.com/kb/en/mariadb-10-5-0-release-notes/), [10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/) |
| **26.4.2** | [10.4.4](https://mariadb.com/kb/en/mariadb-10-4-4-release-notes/) |
| **26.4.1** | [10.4.3](https://mariadb.com/kb/en/mariadb-10-4-3-release-notes/) |
| **26.4.0** | [10.4.2](https://mariadb.com/kb/en/mariadb-10-4-2-release-notes/) |

  ### Galera 3 Versions

 The following table lists each version of the [Galera](../galera/index) 3 wsrep provider, and it lists which version of MariaDB each one was first released in. If you would like to install [Galera](../galera/index) 3 using [yum](../yum/index), [apt](../installing-mariadb-deb-files/index#installing-mariadb-with-apt), or [zypper](../installing-mariadb-with-zypper/index), then the package is called `galera`.

 


| Galera Version | Released in MariaDB Version |
| --- | --- |
| **25.3.37** | [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10336-release-notes/) |
| **25.3.35** | [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10333-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/) |
| **25.3.34** | [MariaDB 10.3.31](https://mariadb.com/kb/en/mariadb-10331-release-notes/), [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10240-release-notes/) |
| **25.3.33** | [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/) |
| **25.3.32** | [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/) |
| **25.3.31** | [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10148-release-notes/) |
| **25.3.30** | [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/) |
| **25.3.29** | [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/) |
| **25.3.28** | [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10228-release-notes/), [MariaDB 10.1.42](https://mariadb.com/kb/en/mariadb-10142-release-notes/) |
| **25.3.27** | [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/), [MariaDB 10.2.27](https://mariadb.com/kb/en/mariadb-10227-release-notes/) |
| **25.3.26** | [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/) |
| **25.3.25** | [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/), [MariaDB 10.2.20](https://mariadb.com/kb/en/mariadb-10220-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB Galera Cluster 10.0.38](https://mariadb.com/kb/en/mariadb-galera-cluster-10038-release-notes/), [MariaDB Galera Cluster 5.5.63](https://mariadb.com/kb/en/mariadb-galera-cluster-5563-release-notes/) |
| **25.3.24** | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10137-release-notes/), [MariaDB Galera Cluster 10.0.37](https://mariadb.com/kb/en/mariadb-galera-cluster-10037-release-notes/), [MariaDB Galera Cluster 5.5.62](https://mariadb.com/kb/en/mariadb-galera-cluster-5562-release-notes/) |
| **25.3.23** | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/), [MariaDB 10.1.32](https://mariadb.com/kb/en/mariadb-10132-release-notes/), [MariaDB Galera Cluster 10.0.35](https://mariadb.com/kb/en/mariadb-galera-cluster-10035-release-notes/), [MariaDB Galera Cluster 5.5.60](https://mariadb.com/kb/en/mariadb-galera-cluster-5560-release-notes/) |
| **25.3.22** | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/), [MariaDB Galera Cluster 10.0.33](https://mariadb.com/kb/en/mariadb-galera-cluster-10033-release-notes/), [MariaDB Galera Cluster 5.5.59](https://mariadb.com/kb/en/mariadb-galera-cluster-5559-release-notes/) |
| **25.3.21** | N/A |
| **25.3.20** | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/), [MariaDB Galera Cluster 10.0.31](https://mariadb.com/kb/en/mariadb-galera-cluster-10031-release-notes/), [MariaDB Galera Cluster 5.5.56](https://mariadb.com/kb/en/mariadb-galera-cluster-5556-release-notes/) |
| **25.3.19** | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/), [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/), [MariaDB Galera Cluster 10.0.29](https://mariadb.com/kb/en/mariadb-galera-cluster-10029-release-notes/), [MariaDB Galera Cluster 5.5.54](https://mariadb.com/kb/en/mariadb-galera-cluster-5554-release-notes/) |
| **25.3.18** | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/), [MariaDB Galera Cluster 10.0.28](https://mariadb.com/kb/en/mariadb-galera-cluster-10028-release-notes/), [MariaDB Galera Cluster 5.5.53](https://mariadb.com/kb/en/mariadb-galera-cluster-5553-release-notes/) |
| **25.3.17** | [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/), [MariaDB Galera Cluster 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/), [MariaDB Galera Cluster 5.5.51](https://mariadb.com/kb/en/mariadb-galera-cluster-5551-release-notes/) |
| **25.3.16** | N/A |
| **25.3.15** | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/), [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), [MariaDB Galera Cluster 10.0.25](https://mariadb.com/kb/en/mariadb-galera-cluster-10025-release-notes/), [MariaDB Galera Cluster 5.5.49](https://mariadb.com/kb/en/mariadb-galera-cluster-5549-release-notes/) |
| **25.3.14** | [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10112-release-notes/), [MariaDB Galera Cluster 10.0.24](https://mariadb.com/kb/en/mariadb-galera-cluster-10024-release-notes/), [MariaDB Galera Cluster 5.5.48](https://mariadb.com/kb/en/mariadb-galera-cluster-5548-release-notes/) |
| **25.3.12** | [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |
| **25.3.11** | N/A |
| **25.3.10** | N/A |
| **25.3.9** | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/), [MariaDB Galera Cluster 10.0.17](https://mariadb.com/kb/en/mariadb-galera-cluster-10017-release-notes/), [MariaDB Galera Cluster 5.5.42](https://mariadb.com/kb/en/mariadb-galera-cluster-5542-release-notes/) |
| **25.3.8** | N/A |
| **25.3.7** | N/A |
| **25.3.6** | N/A |
| **25.3.5** | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), [MariaDB Galera Cluster 10.0.10](https://mariadb.com/kb/en/mariadb-galera-cluster-10010-release-notes/), [MariaDB Galera Cluster 5.5.37](https://mariadb.com/kb/en/mariadb-galera-cluster-5537-release-notes/) |
| **25.3.4** | N/A |
| **25.3.3** | N/A |
| **25.3.2** | [MariaDB Galera Cluster 10.0.7](https://mariadb.com/kb/en/mariadb-galera-cluster-1007-release-notes/), [MariaDB Galera Cluster 5.5.35](https://mariadb.com/kb/en/mariadb-galera-cluster-5535-release-notes/) |

  See Also
--------

 * [Codership on Google Groups](https://groups.google.com/forum/?fromgroups#!forum/codership-team) (*`codership-team 'at' googlegroups (dot) com`*) - A great mailing list for Galera users.
* [About Galera Replication](../about-galera-replication/index)
* [Codership: Using Galera Cluster](http://codership.com/content/using-galera-cluster)
* [Galera Use Cases](../galera-use-cases/index)
* [Getting Started with MariaDB Galera Cluster](../getting-started-with-mariadb-galera-cluster/index)
* [MariaDB Galera Cluster - Known Limitations](../mariadb-galera-cluster-known-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/what-is-mariadb-galera-cluster/>

SQL Error Log Plugin
====================

     The `SQL_ERROR_LOG` plugin collects errors sent to clients in a log file defined by [sql\_error\_log\_filename](#sql_error_log_filename), so that they can later be analyzed. The log file can be rotated if [sql\_error\_log\_rotate](#sql_error_log_rotate) is set.

 Errors are logged as they happen and an error will be logged even if it was handled by a [condition handler](../declare-handler/index) and was never technically *sent* to the client.

 Comments are also logged, which can make the log easier to search. But this is only possible if the client does not strip the comments away. For example, [mysql](../mysql-command-line-client/index) command-line client only leaves comments when started with the [--comments](../mysql-command-line-client/index#mysql-options) option.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'sql_errlog';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = sql_errlog

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'sql_errlog';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
install plugin SQL_ERROR_LOG soname 'sql_errlog';
Query OK, 0 rows affected (0.00 sec)

use test;
Database changed

set sql_mode='STRICT_ALL_TABLES,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)

CREATE TABLE foo2 (id int) ENGINE=WHOOPSIE;
ERROR 1286 (42000): Unknown storage engine 'WHOOPSIE'
\! cat data/sql_errors.log
2013-03-19  9:38:40 msandbox[msandbox] @ localhost [] ERROR 1286: Unknown storage engine 'WHOOPSIE' : CREATE TABLE foo2 (id int) ENGINE=WHOOPSIE

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.0 | Alpha | [MariaDB 5.5.22](https://mariadb.com/kb/en/mariadb-5522-release-notes/) |

 
System Variables
----------------

 ### `sql_error_log_filename`

 * **Description:** The name of the logfile. Rotation of it will be named like `*sql\_error\_log\_filename*.001`
* **Commandline:** `--sql-error-log-filename=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `sql_errors.log`

 

---

 ### `sql_error_log_rate`

 * **Description:** The rate of logging. `SET sql_error_log_rate=300;` means that one of 300 errors will be written to the log.  
If `sql_error_log_rate` is `0` the logging is disabled.  
The default rate is `1` (every error is logged).
* **Commandline:** `--sql-error-log-rate=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`

 

---

 ### `sql_error_log_rotate`

 * **Description:** This is the 'write-only' variable. Assigning TRUE to this variable forces the log rotation.
* **Commandline:** `--sql-error-log-rotate={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 ### `sql_error_log_rotations`

 * **Description:** The number of rotations. When rotated, the current log file is stored and the new empty one created.  
The sql\_error\_log\_rotations logs are stored, older are removed.  
The default number of rotations is `9`.
* **Commandline:** `--sql-error-log-rotations`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `9`
* **Range:** `1` to `999`

 

---

 ### `sql_error_log_size_limit`

 * **Description:** The limitation for the size of the log file. After reaching the specified limit, the log file is rotated.  
1M limit set by default.
* **Commandline:** `--sql-error-log-size-limit=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1000000`
* **Range:** `100` to `9223372036854775807`

 

---

 Options
-------

 ### `sql_error_log`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--sql-error-log=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-error-log-plugin/>

System Variables
=================

  

| Title | Description |
| --- | --- |
|  [System and Status Variables Added By Major Release](../system-and-status-variables-added-by-major-release/index) |  Lists of status and system variables added in MariaDB major releases.  |
|  [Full List of MariaDB Options, System and Status Variables](../full-list-of-mariadb-options-system-and-status-variables/index) |  Complete alphabetical list of all MariaDB options as well as system and status variables.  |
|  [Server Status Variables](../server-status-variables/index) |  List and description of the Server Status Variables.  |
|  [Server System Variables](../server-system-variables/index) |  List of system variables.  |
|  [Aria Status Variables](../aria-status-variables/index) |  Aria-related server status variables.  |
|  [Aria System Variables](../aria-system-variables/index) |  Aria-related system variables.  |
|  [Cassandra Status Variables](../cassandra-status-variables/index) |  Cassandra-related status variables  |
|  [Cassandra System Variables](../cassandra-system-variables/index) |  Cassandra system variables  |
|  [CONNECT System Variables](../connect-system-variables/index) |  System variables related to the CONNECT storage engine.  |
|  [Galera Cluster Status Variables](../galera-cluster-status-variables/index) |  Galera Cluster status variables.  |
|  [Galera Cluster System Variables](../galera-cluster-system-variables/index) |  Listing and description of Galera Cluster system variables.  |
|  [InnoDB Server Status Variables](../innodb-status-variables/index) |  List and description of InnoDB status variables.  |
|  [InnoDB System Variables](../innodb-system-variables/index) |  List and description of InnoDB-related server system variables.  |
|  [MariaDB Audit Plugin Options and System Variables](../mariadb-audit-plugin-options-and-system-variables/index) |  Description of Server\_Audit plugin options and system variables.  |
|  [MariaDB Audit Plugin - Status Variables](../mariadb-audit-plugin-status-variables/index) |  Server Audit plugin status variables  |
|  [Mroonga Status Variables](../mroonga-status-variables/index) |  Mroonga-related status variables.  |
|  [Mroonga System Variables](../mroonga-system-variables/index) |  Mroonga-related system variables.  |
|  [MyISAM System Variables](../myisam-system-variables/index) |  MyISAM system variables.  |
|  [MyRocks Status Variables](../myrocks-status-variables/index) |  MyRocks-related status variables.  |
|  [MyRocks System Variables](../myrocks-system-variables/index) |  MyRocks server system variables.  |
|  [OQGRAPH System and Status Variables](../oqgraph-system-and-status-variables/index) |  List and description of OQGRAPH system and status variables.  |
|  [Performance Schema Status Variables](../performance-schema-status-variables/index) |  Performance Schema status variables.  |
|  [Performance Schema System Variables](../performance-schema-system-variables/index) |  Performance Schema system variables.  |
|  [Replication and Binary Log Status Variables](../replication-and-binary-log-status-variables/index) |  Replication and binary log status variables.  |
|  [Replication and Binary Log System Variables](../replication-and-binary-log-system-variables/index) |  Replication and binary log system variables.  |
|  [Semisynchronous Replication Plugin Status Variables](../semisynchronous-replication-plugin-status-variables/index) |  Semisynchronous Replication plugin status variables  |
|  [Semisynchronous Replication](../semisynchronous-replication/index) |  Semisynchronous replication.  |
|  [Sphinx Status Variables](../sphinx-status-variables/index) |  Sphinx status variables.  |
|  [Spider Status Variables](../spider-status-variables/index) |  Spider server status variables.  |
|  [Spider Server System Variables](../spider-server-system-variables/index) |  System variables for the Spider storage engine.  |
|  [SQL\_ERROR\_LOG Plugin System Variables](../sql_error_log-plugin-system-variables/index) |  SQL\_ERROR\_LOG plugin-related system variables.  |
|  [SSL/TLS Status Variables](../ssltls-status-variables/index) |  List and description of Transport Layer Security (TLS)-related status variables.  |
|  [SSL/TLS System Variables](../ssltls-system-variables/index) |  List and description of Transport Layer Security (TLS)-related system variables.  |
|  [Thread Pool System and Status Variables](../thread-pool-system-status-variables/index) |  System and status variables related to the MariaDB thread pool.  |
|  [TokuDB Status Variables](../tokudb-status-variables/index) |  TokuDB status variables  |
|  [TokuDB System Variables](../tokudb-system-variables/index) |  TokuDB System Variables  |
|  [MariaDB Optimization for MySQL Users](../mariadb-optimization-for-mysql-users/index) |  MariaDB contains many new options and optimizations which, for compatibilit...  |
|  [InnoDB Buffer Pool](../innodb-buffer-pool/index) |  The most important memory buffer used by InnoDB.  |
|  [InnoDB Change Buffering](../innodb-change-buffering/index) |  Buffering INSERT, UPDATE and DELETE statements for greater efficiency.  |
|  [Optimizing table\_open\_cache](../optimizing-table_open_cache/index) |  Adjusting table\_open\_cache to improve performance.  |
|  [Optimizing key\_buffer\_size](../optimizing-key_buffer_size/index) |  Optimizing index buffers with key\_buffer\_size  |
|  [Segmented Key Cache](../segmented-key-cache/index) |  Collection of structures for regular MyISAM key caches  |
|  [Big Query Settings](../big-query-settings/index) |  Recommended settings for large, IO-bound queries  |
|  [Sample my.cnf Files](../sample-mycnf-files/index) |  Place holder for sample my.cnf files, customized for different memory size ...  |
|  [Handling Too Many Connections](../handling-too-many-connections/index) |  Dealing with the 'Too many connections' error  |
|  [System Variable Differences between MariaDB and MySQL](../system-variable-differences-between-mariadb-and-mysql/index) |  Comparison of variable differences between major versions of MariaDB and MySQL.  |
|  [MariaDB Memory Allocation](../mariadb-memory-allocation/index) |  Basic issues in RAM allocation for MariaDB.  |
|  [Setting Innodb Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index) |  The InnoDB Buffer Pool size can be set dynamically.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables/>

Backup and Restore via dbForge Studio
=====================================

    
dbForge Studio is a proprietary third-party tool, not included with MariaDB Server. Content contributed by devart.

 
In the modern world, data importance is non-negotiable, and keeping data integrity and consistency is the top priority. Data stored in databases is vulnerable to system crashes, hardware problems, security breaches, and other failures causing data loss or corruption. To prevent database damage, it is important to back the data up regularly and implement the data restore policies. MariaDB, one of the most popular database management systems, provides several methods to configure routines for backing up and recovering data. The current guideline illustrates both processes performed with the help of dbForge Studio for MySQL which is also a fully-functional [GUI client for MariaDB](https://www.devart.com/dbforge/mysql/studio/mariadb-gui-client.html) that has everything you need to accomplish the database-related tasks on MariaDB.

 Create the backup on MariaDB
----------------------------

 dbForge Studio for MySQL and MariaDB has a separate module dedicated to the data backing up and recovering jobs. Let us first look at how set the tool to create a MariaDB backup. Launch the Studio and go to **Database > Backup and Restore > Backup Database**. The **Database Backup Wizard** with several pages will appear. On the General page, specify the database in question and how to connect to it, then choose where to save the created backup file, and specify its name. There are additional optional settings – you can select to delete old files automatically, zip the output backup file, etc. When done, click **Next**. 

 ![b1]

 On the **Backup content** page, select the objects to back up. Click **Next**.

 ![b2]

 The **Options** page. Here you can specify the details of the data backing up process. Plenty of available options allow you to configure this task precisely to meet the specific requirements. When done, click **Next**. 

 ![b3]

 The **Errors handling** page. Here you configure how the Studio should handle the errors that might occur during the backing up process. Also, you can set the Studio to write the information about the errors it encountered into the log file. 

 You can save the project settings to apply them in the future. For this, in the left bottom corner of the Wizard, select one of the saving options: **Save Project** or **Save Command Line**. The latter allows saving settings as a backup script which you can execute from the command line at any time later. 

 The configuration process is complete. Click Backup to launch the data backing up. 

 Note: It is not obligatory to go through all the pages of the Wizard. The Backup button is available no matter on which page you are. Thus, you can launch the process of backing the data up whenever you have set everything you needed. 

 ![b4]

 After you have clicked **Backup**, dbForge Studio for MySQL starts to create a MariaDB backup. 

 ![b5]

 When this is done, you will see the confirmation message. Click **Finish**.

 ![b6]

 Backup and restore policies suggest creating regular backups on a daily, weekly, monthly, quarterly, and yearly basis. Besides, to minimize the consequences of possible data loss, it is highly recommended make a backup before making any changes to a database, such as upgrading, modifying data, redesigning the structure, etc. Simply speaking, you always need a fresh backup to restore the most up-to-date database version. To ensure regular backups on schedule, you can use a batch file created with the help of the Studio and **Windows Task Scheduler**, where you need to create and schedule the backup task. 

 Restore the backup file on MariaDB
----------------------------------

 This is an even faster task, done in half as many steps. 

 The process of data recovery from the backup file is simple. It only takes several clicks: Launch dbForge Studio for MySQL and go to **Database > Backup and Restore > Restore Database**. The **Database Restore Wizard** will appear. Specify the database name, its connection parameters, and the path to the backup file you want to restore. Then click **Restore**, and the process will start immediately. 

 ![r1]

 When the process is complete, click **Finish**.

 ![r2]

 More information about this essential feature is available on the [dedicated backup and restore page](https://www.devart.com/dbforge/mysql/studio/mysql-backup.html) – it explores the routines performed on MySQL, but they fully apply to MariaDB backups. You can use the same IDE and the same workflow. 

 To test-drive this and other features of the Studio (the IDE includes all the tools necessary for the development, management, and administration of databases on MariaDB), [download dbForge Studio for a free 30-day trial](https://www.devart.com/dbforge/mysql/studio/download.html). dbForge Studio for MySQL and MariaDB boasts truly advanced functionality that will help your teams deliver more value.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-and-restore-via-dbforge-studio/>

About Galera Replication
========================

    In MariaDB Cluster, the Server replicates a transaction at commit time by broadcasting the write set associated with the transaction to every node in the cluster. The client connects directly to the DBMS and experiences behavior that is similar to native MariaDB in most cases. The wsrep API (write set replication API) defines the interface between Galera replication and MariaDB.

 Synchronous vs. Asynchronous Replication
----------------------------------------

 The basic difference between synchronous and asynchronous replication is that "synchronous" replication guarantees that if a change happened on one node in the cluster, then the change will happen on other nodes in the cluster "synchronously", or at the same time. "Asynchronous" replication gives no guarantees about the delay between applying changes on "master" node and the propagation of changes to "slave" nodes. The delay with "asynchronous" replication can be short or long. This also implies that if master node crashes in an "asynchronous" replication topology, then some of the latest changes may be lost.

 Theoretically, synchronous replication has a number of advantages over asynchronous replication:

 * Clusters utilizing synchronous replication are always highly available. If one of the nodes crashed, then there would be no data loss. Additionally, all cluster nodes are always consistent.
* Clusters utilizing synchronous replication allow transactions to be executed on all nodes in parallel.
* Clusters utilizing synchronous replication can guarantee causality across the whole cluster. This means that if a `SELECT` is executed on one cluster node after a transaction is executed on a cluster node, it should see the effects of that transaction.

 However, in practice, synchronous database replication has traditionally been implemented via the so-called "2-phase commit" or distributed locking which proved to be very slow. Low performance and complexity of implementation of synchronous replication led to a situation where asynchronous replication remains the dominant means for database performance scalability and availability. Widely adopted open-source databases such as MySQL or PostgreSQL offer only asynchronous or semi-synchronous replication solutions.

 Galera's replication is not completely synchronous. It is sometimes called **virtually synchronous** replication.

 Certification-Based Replication Method
--------------------------------------

 An alternative approach to synchronous replication that uses Group Communication and transaction ordering techniques was suggested by a number of researchers. For example:

 * [Database State Machine Approach](http://library.epfl.ch/theses/?nr=2090)
* [Don't Be Lazy, Be Consistent](http://www.cs.mcgill.ca/~kemme/papers/vldb00.html)

 Prototype implementations have shown a lot of promise. We combined our experience in synchronous database replication and the latest research in the field to create the Galera Replication library and the wsrep API.

 Galera replication is a **highly transparent**, **scalable**, and **virtually synchronous** replication solution for database clustering to achieve high availability and improved performance. Galera-based clusters are:

 * Highly available
* Highly transparent
* Highly scalable (near linear scalability may be reached depending on the application)

 Generic Replication Library
---------------------------

 Galera replication functionality is implemented as a shared library and can be linked with any transaction processing system which implements the wsrep API hooks.

 The Galera replication library is a protocol stack providing functionality for preparing, replicating and applying of transaction write sets. It consists of:

 * **wsrep API** specifies the interface — responsibilities for DBMS and replication provider
* **wsrep hooks** is the wsrep integration in the DBMS engine.
* **Galera provider** implements the wsrep API for Galera library
* **certification** layer takes care of preparing write sets and performing certification
* **replication** manages replication protocol and provides total ordering capabilities
* **GCS framework** provides plugin architecture for group communication systems
* many gcs implementations can be adapted, we have experimented with spread and our in-house implementations: vsbes and gemini

 Many components in the Galera replication library were redesigned and improved with the introduction of [MariaDB 10.4](../what-is-mariadb-104/index), which includes Galera 4. 

 Galera Slave Threads
--------------------

 Although the **Galera provider** certifies the write set associated with a transaction at commit time on each node in the cluster, this write set is not necessarily applied on that cluster node immediately. Instead, the write set is placed in the cluster node's receive queue on the node, and it is eventually applied by one of the cluster node's Galera slave thread.

 The number of Galera slave threads can be configured with the [wsrep\_slave\_threads](../galera-cluster-system-variables/index#wsrep_slave_threads) system variable.

 The Galera slave threads are able to determine which write sets are safe to apply in parallel. However, if your cluster nodes seem to have frequent consistency problems, then setting the value to `1` will probably fix the problem.

 When a cluster node's state, as seen by [wsrep\_local\_state\_comment](../galera-cluster-status-variables/index#wsrep_local_state_comment), is `JOINED`, then increasing the number of slave threads may help the cluster node catch up with the cluster more quickly. In this case, it may be useful to set the number of threads to twice the number of CPUs on the system.

 Streaming Replication
---------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**Streaming replication was introduced in Galera 4, and so is only available from [MariaDB 10.4](../what-is-mariadb-104/index). 

 
In older versions of MariaDB Cluster there was a 2GB limit on the size of the transaction you could run. The node waits on the transaction commit before performing replication and certification. With large transactions, long running writes, and changes to huge data-sets, there was a greater possibility of a conflict forcing rollback on an expensive operation.

 Using Streaming replication, the node breaks huge transactions up into smaller and more manageable fragments, it then replicates these fragments to the cluster as it works instead of waiting for the commit. Once certified, the fragment can no longer be aborted by conflicting transactions. As this can have performance consequences both during execution and in the event of rollback, it is recommended that you only use it with large transactions that are unlikely to experience conflict.

 For more information on Streaming Replication, see the [Galera](https://galeracluster.com/library/documentation/streaming-replication.html) documentation.

 Group Commits
-------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**Group Commit support for MariaDB Cluster was introduced in Galera 4, and so is only available from [MariaDB 10.4](../what-is-mariadb-104/index). 

 
In MariaDB Group Commit, groups of transactions are flushed together to disk to improve performance. Prior to [MariaDB 10.4](../what-is-mariadb-104/index), this feature was not available in MariaDB Cluster as it interfered with the global-ordering of transactions for replication. Beginning in 10.4, MariaDB Cluster can take advantage of Group Commit.

 For more information on Group Commit, see the [Galera](https://galeracluster.com/library/kb/group-commit.html) documentation.

 See Also
--------

 * [Galera Cluster: Galera Replication](https://galeracluster.com/products/)
* [What is MariaDB Galera Cluster?](../what-is-mariadb-galera-cluster/index)
* [Galera Use Cases](../galera-use-cases/index)
* [Getting Started with MariaDB/Galera Cluster](../getting-started-with-mariadb-galera-cluster/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-galera-replication/>

Galera Use Cases
================

    Here are some common use cases for Galera replication:

 


|  |  |
| --- | --- |
| Read Master | Traditional MariaDB master-slave topology, but with Galera all "slave" nodes are capable masters at all times - it is just the application that treats them as slaves. Galera replication can guarantee zero slave lag for such installations and, due to parallel slave applying, much better throughput for the cluster. |
| WAN Clustering | Synchronous replication works fine over the WAN network. There will be a delay, which is proportional to the network round trip time (RTT), but it only affects the commit operation. |
| Disaster Recover | Disaster recovery is a sub-class of WAN replication. Here one data center is passive and only receives replication events, but does not process any client transactions. Such a remote data center will be up to date at all times and no data loss can happen. During recovery, the spare site is just nominated as primary and application can continue as normal with a minimal fail over delay. |
| Latency Eraser | With WAN replication topology, cluster nodes can be located close to clients. Therefore all read & write operations will be super fast with the local node connection. The RTT related delay will be experienced only at commit time, and even then it can be generally accepted by end user, usually the kill-joy for end user experiences is the slow browsing response time, and read operations are as fast as they possibly can be. |

 
See Also
--------

 * [What is MariaDB Galera Cluster?](../what-is-mariadb-galera-cluster/index)
* [About Galera Replication](../about-galera-replication/index)
* [Codership: Using Galera Cluster](http://codership.com/content/using-galera-cluster)
* [Getting Started with MariaDB/Galera Cluster](../getting-started-with-mariadb-galera-cluster/index)
* [MariaDB Galera Cluster and M/S replication](https://www.youtube.com/watch?v=Nd0nvltLPdQ) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-use-cases/>

MariaDB Galera Cluster - Known Limitations
==========================================

    This article contains information on known problems and limitations of MariaDB Galera Cluster.

 Limitations from codership.com:
-------------------------------

 * Currently replication works only with the [InnoDB storage engine](../xtradb-and-innodb/index). Any writes to tables of other types, including system (mysql.\*) tables are not replicated (this limitation excludes DDL statements such as [CREATE USER](../create-user/index), which implicitly modify the mysql.\* tables — those are replicated). There is however experimental support for [MyISAM](../myisam/index) - see the [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) system variable)

 * Unsupported explicit locking include [LOCK TABLES](../transactions-lock/index), [FLUSH TABLES {explicit table list} WITH READ LOCK](../flush/index), ([GET\_LOCK()](../get_lock/index), [RELEASE\_LOCK()](../release_lock/index),…). Using transactions properly should be able to overcome these limitations. Global locking operators like [FLUSH TABLES WITH READ LOCK](../flush/index) are supported.

 * All tables should have a primary key (multi-column primary keys are supported). [DELETE](../delete/index) operations are unsupported on tables without a primary key. Also, rows in tables without a primary key may appear in a different order on different nodes.

 * The [general query log](../general-query-log/index) and the [slow query log](../slow-query-log/index) cannot be directed to a table. If you enable these logs, then you must forward the log to a file by setting `[log\_output=FILE](../server-system-variables/index#log_output)`.

 * [XA transactions](../xa-transactions/index) are not supported.

 * Transaction size. While Galera does not explicitly limit the transaction size, a writeset is processed as a single memory-resident buffer and as a result, extremely large transactions (e.g. [LOAD DATA](../load-data/index)) may adversely affect node performance. To avoid that, the [wsrep\_max\_ws\_rows](../galera-cluster-system-variables/index#wsrep_max_ws_rows) and [wsrep\_max\_ws\_size](../galera-cluster-system-variables/index#wsrep_max_ws_size) system variables limit transaction rows to 128K and the transaction size to 2Gb by default. If necessary, users may want to increase those limits. Future versions will add support for transaction fragmentation.

 Other observations, in no particular order:
-------------------------------------------

 * If you are using [mysqldump](../mysqldump/index) for state transfer, and it failed for whatever reason (e.g. you do not have the database account it attempts to connect with, or it does not have necessary permissions), you will see an SQL SYNTAX error in the server [error log](../error-log/index). Don't let it fool you, this is just a fancy way to deliver a message (the pseudo-statement inside of the bogus SQL will actually contain the error message).

 * Do not use transactions of any essential size. Just to insert 100K rows, the server might require additional 200-300 Mb. In a less fortunate scenario it can be 1.5 Gb for 500K rows, or 3.5 Gb for 1M rows. See [MDEV-466](https://jira.mariadb.org/browse/MDEV-466) for some numbers (you'll see that it's closed, but it's not closed because it was fixed).

 * Locking is lax when DDL is involved. For example, if your DML transaction uses a table, and a parallel DDL statement is started, in the normal MySQL setup it would have waited for the metadata lock, but in Galera context it will be executed right away. It happens even if you are running a single node, as long as you configured it as a cluster node. See also [MDEV-468](https://jira.mariadb.org/browse/MDEV-468). This behavior might cause various side-effects, the consequences have not been investigated yet. Try to avoid such parallelism.

 * Do not rely on auto-increment values to be sequential. Galera uses a mechanism based on autoincrement increment to produce unique non-conflicting sequences, so on every single node the sequence will have gaps. See <http://codership.blogspot.com/2009/02/managing-auto-increments-with-multi.html>

 * A command may fail with `ER_UNKNOWN_COM_ERROR` producing 'WSREP has not yet prepared node for application use' (or 'Unknown command' in older versions) error message. It happens when a cluster is suspected to be split and the node is in a smaller part — for example, during a network glitch, when nodes temporarily lose each other. It can also occur during state transfer. The node takes this measure to prevent data inconsistency. Its usually a temporary state which can be detected by checking [wsrep\_ready](../galera-cluster-status-variables/index#wsrep_ready) value. The node, however, allows SHOW and SET command during this period.

 * After a temporary split, if the 'good' part of the cluster was still reachable and its state was modified, resynchronization occurs. As a part of it, nodes of the 'bad' part of the cluster drop all client connections. It might be quite unexpected, especially if the client was idle and did not even know anything wrong was happening. Please also note that after the connection to the isolated node is restored, if there is a flow on the node, it takes a long time for it to synchronize, during which the "good" node says that the cluster is already of the normal size and synced, while the rejoining node says it's only joined (but not synced). The connections keep getting 'unknown command'. It should pass eventually.

 * While [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) is checked on startup and can only be ROW (see [Binary Log Formats](../binary-log-formats/index)), it can be changed at runtime. Do NOT change binlog\_format at runtime, it is likely not only cause replication failure, but make all other nodes crash.

 * If you are using rsync for state transfer, and a node crashes before the state transfer is over, rsync process might hang forever, occupying the port and not allowing to restart the node. The problem will show up as 'port in use' in the server error log. Find the orphan rsync process and kill it manually.

 * Performance: by design performance of the cluster cannot be higher than performance of the slowest node; however, even if you have only one node, its performance can be considerably lower comparing to running the same server in a standalone mode (without wsrep provider). It is particularly true for big enough transactions (even those which are well within current limitations on transaction size quoted above).

 * Windows is not supported.

 * Replication filters: When using Galera cluster, replication filters should be used with caution. See [Configuring MariaDB Galera Cluster: Replication Filters](../configuring-mariadb-galera-cluster/index#replication-filters) for more details. See also [MDEV-421](https://jira.mariadb.org/browse/MDEV-421) and [MDEV-6229](https://jira.mariadb.org/browse/MDEV-6229).

 * Flashback isn't supported in Galera due to incompatible binary log format.

 * `FLUSH PRIVILEGES` is not replicated.

 * The [query cache](../query-cache/index) needed to be disabled by setting `[query\_cache\_size=0](../server-system-variables/index#query_cache_size)` prior to MariaDB Galera Cluster 5.5.40, MariaDB Galera Cluster 10.0.14, and [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)..

 * In an asynchronous replication setup where a master replicates to a galera node acting as slave, parallel replication (slave-parallel-threads > 1) on slave is currently not supported (see [MDEV-6860](https://jira.mariadb.org/browse/MDEV-6860)).

 * The disk-based [Galera gcache](https://galeracluster.com/library/documentation/state-transfer.html#write-set-cache-gcache) is not encrypted ([MDEV-8072](https://jira.mariadb.org/browse/MDEV-8072)).

 * Nodes may have different table definitions, especially temporarily during [rolling schema upgrade](../galera-cluster-system-variables/index#wsrep_osu_method) operations, but the same [schema compatibility restrictions](../replication-when-the-master-and-slave-have-different-table-definitions/index) apply as they do for ROW based replication

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-galera-cluster-known-limitations/>

Tips on Converting to Galera
============================

     These topics will be discussed in more detail below.

 Dear Schema Designer:

 * InnoDB only, always have PK.

 Dear Developer:

 * Check for errors, even after COMMIT.
* Moderate sized transactions.
* Don't make assumptions about AUTO\_INCREMENT values.
* Handling of "critical reads" is quite different (arguably better).
* Read/Write split is not necessary, but is still advised in case the underlying structure changes in the future.

 Dear DBA:

 * Building the machines is quite different. (Not covered here)
* ALTERs are handled differently.
* TRIGGERs and EVENTs may need checking.
* Tricks in replication (eg, BLACKHOLE) may not work.
* Several variables need to be set differently.

 Galera is available in many places
----------------------------------

 Galera's High Availability replication is available via:

 * [MariaDB 10.1](../what-is-mariadb-101/index) and later
* Percona XtraDB Cluster
* Codership's Galera Cluster for MySQL

 Overview of cross-colo writing
------------------------------

 (This overview is valid even for same-datacenter nodes, but the issues of latency vanish.)

 Cross-colo latency is an 'different' than with traditional replication, but not necessarily better or worse with Galera. The latency happens at a very different time for Galera.

 In 'traditional' replication, these steps occur:

 * Client talks to Master. If Client and Master are in different colos, this has a latency hit.
* Each SQL to Master is another latency hit, including(?) the COMMIT (unless using autocommit).
* Replication to Slave(s) is asynchronous, so this does not impact the client writing to the Master.
* Since replication is asynchronous, a Client (same or subsequent) cannot be guaranteed to see that data on the Slave. This is a "critical read". The async Replication delay forces apps to take some evasive action.

 In Galera-based replication:

 * Client talks to any Master -- possibly with cross-colo latency. Or you could arrange to have Galera nodes co-located with clients to avoid this latency.
* At COMMIT time (or end of statement, in case of autocommit=1), galera makes one roundtrip to other nodes.
* The COMMIT usually succeeds, but could fail if some other node is messing with the same rows. (Galera retries on autocommit failures.)
* Failure of the COMMIT is reported to the Client, who should simply replay the SQL statements from the BEGIN.
* Later, the whole transaction will be applied (with possibility of conflict) on the other nodes.
* Critical Read -- details below

 For an N-statement transaction: In a typical 'traditional' replication setup:

 * 0 or N (N+2?) latency hits, depending on whether the Client is co-located with the Master.
* Replication latencies and delays lead to issues with "Critical Reads".

 In Galera:

 * 0 latency hits (assuming Client is 'near' some node)
* 1 latency hit for the COMMIT.
* 0 (usually) for Critical Read (details below)

 Bottom line: Depending on where your Clients are, and whether you clump statements into BEGIN...COMMIT transacitons, Galera may be faster or slower than traditional replication in a WAN topology.

 AUTO\_INCREMENT
---------------

 By using wsrep\_auto\_increment\_control = ON, the values of auto\_increment\_increment and auto\_increment\_offset will be automatically adjusted as nodes come/go.

 If you are building a Galera cluster by starting with one node as a Slave to an existing non-Galera system, and if you have multi-row INSERTs that depend on AUTO\_INCREMENTs, the read this Percona blog

 Bottom line: There may be gaps in AUTO\_INCREMENT values. Consecutive rows, even on one connection, will not have consecutive ids.

 Beware of Proxies that try to implement a "read/write split". In some situations, a reference to LAST\_INSERT\_ID() will be sent to a "Slave".

 InnoDB only
-----------

 For effective replication of data, you must use only InnoDB. This eliminates

 * FULLTEXT index (until 5.6)
* SPATIAL index
* MyISAM's PK as second column

 You can use MyISAM and MEMORY for data that does not need to be replicated.

 Also, you should use "START TRANSACTION READONLY" wherever appropriate.

 Check after COMMIT
------------------

 Check for errors after issuing COMMIT. A "deadlock" can occur due to writes on other node(s).

 Possible exception (could be useful for legacy code without such checks): Treat the system as single-Master, plus Slaves. By writing only to one node, COMMIT should always succeed(?)

 What about autocommit = 1? wsrep\_retry\_autocommit tells Galera to retry if a single statement that is autocommited N times. So, there is still a chance (very slim) of getting a deadlock on such a statement. The default setting of "1" retry is probably good.

 Always have PRIMARY KEY
-----------------------

 "Row Based Replication" will be used; this requires a PK on every table.

 A non-replicated table (eg, MyISAM) does not have to have a PK.

 Transaction "size"
------------------

 (This section assumes you have Galera nodes in multiple colos.) Because of some of the issues discussed, it is wise to group your write statements into moderate sized BEGIN...COMMIT transactions. There is one latency hit per COMMIT or autocommit. So, combining statements will decrease those hits. On the other hand, it is unwise (for other reasons) to make huge transactions, such as inserting/modifying millions of rows in a single transaction.

 To deal with failure on COMMIT, design your code so you can redo the SQL statements in the transaction without messing up other data. For example, move "normalization" statements out of the main transaction; there is arguably no compelling reason to roll them back if the main code rolls back.

 In any case, doing what is "right" for the business logic overrides other considerations.

 Galera's tx\_isolation is between Serializable and Repeatable Read. tx\_isolation variable is ignored.

 Set wsrep\_log\_conflicts to get errors put in the regular MySQL mysqld.err.

 XA transactions cannot be supported. (Galera is already doing a form of XA in order to do its thing.)

 Critical reads
--------------

 Here is a 'simple' (but not 'free') way to assure that a read-after-write, even from a different connection, will see the updated data.

  SET SESSION wsrep\_sync\_wait = 1; SELECT ... SET SESSION wsrep\_sync\_wait = 0;

 For non-SELECTs, use a different bit set for the first select. (TBD: Would 0xffff always work?) (Before Galera 3.6, it was wsrep\_causal\_reads = ON.) Doc for wsrep\_sync\_wait

 This setting stalls the SELECT until all current updates have been applied to the node. That is sufficient to guarantee that a previous write will be visible. The time cost is usually zero. However, a large UPDATE could lead to a delay. Because of RBR and parallel application, delays are likely to be less than on traditional replication. Zaitsev's blog

 It may be more practical (for a web app) to simply set wsrep\_sync\_wait right after connecting.

 MyISAM and MEMORY
-----------------

 As said above, use InnoDB only. However, here is more info on the MyISAM (and hence FULLTEXT, SPATIAL, etc) issues.

 MyISAM and MEMORY tables are not replicated.

 Having MyISAM not replicated can be a big benefit -- You can "CREATE TEMPORARY TABLE ... ENGINE=MyISAM" and have it exist on only one node. RBR assures that any data transferred from that temp table into a 'real' table can still be replicated.

 Replicating GRANTs
------------------

 GRANTs and related operations act on the MyISAM tables in the database `mysql`. The GRANT statements will(?) be replicated, but the underlying tables will not.

 ALTERs
------

 Many DDL changes on Galera can be achieved without downtime, even if they take a long time.

 [RSU vs TOI](https://galeracluster.com/documentation-webpages/documentation/schema-upgrades.html):

 * Rolling Schema Upgrade (RSU): manually execute the DDL on each node in the cluster. The node will desync while executing the DDL.
* Total Order Isolation (TOI): Galera automatically replicates the DDL to each node in the cluster, and it synchronizes each node so that the statement is executed at same time (in the replication sequence) on all nodes.

 Caution: Since there is no way to synchronize the clients with the DDL, you must make sure that the clients are happy with either the old or the new schema. Otherwise, you will probably need to take down the entire cluster while simultaneously switching over both the schema and the client code.

 Fast DDL operations can usually be executed in TOI mode:

 * DDL operations that support the `NOCOPY` and `INSTANT` algorithms are usually very fast.
* DDL operations that support the `INPLACE` algorithm may be fast or slow, depending on whether the table needs to be rebuilt.
* DDL operations that only support the `COPY` algorithm are usually very slow.

 For a list of which operations support which algorithms, see [InnoDB Online DDL](../innodb-online-ddl/index).

 If you need to use RSU mode, then do the following separately for each node:

 
```
SET SESSION wsrep_OSU_method='RSU';
ALTER TABLE tab <alter options here>;
SET SESSION wsrep_OSU_method='TOI';

```

[More discussion of RSU procedures](http://www.severalnines.com/blog/online-schema-upgrade-mysql-galera-cluster-using-rsu-method)

 Single "Master" Configuration
-----------------------------

 You can 'simulate' Master + Slaves by having clients write only to one node.

 * No need to check for errors after COMMIT.
* Lose the latency benefits.

 DBA tricks
----------

 * Remove node from cluster; back it up; put it back in. Syncup is automatic.
* Remove node from cluster; use it for testing, etc; put it back in. Syncup is automatic.
* Rolling hardware/software upgrade: Remove; upgrade; put back in. Repeat.

 Variables that may need to be different
---------------------------------------

 * [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) - If you are writing to multiple nodes, and you use AUTO\_INCREMENT, then auto\_increment\_increment will automatically be equal the current number of nodes.
* [binlog-do](../mysqld-options/index#-binlog-do-db)/[ignore-db](../mysqld-options/index#-binlog-ignore-db) - Do not use.
* [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) - ROW is required for Galera.
* [innodb\_autoinc\_lock\_mode](../replication-and-binary-log-server-system-variables/index#auto_autoinc_lock_mode) - 2
* [innodb\_doublewrite](../xtradbinnodb-server-system-variables/index#innodb_doublewrite) - ON: When an IST occurs, want there to be no torn pages? (With FusionIO or other drives that guarantee atomicity, OFF is better.)
* [innodb\_flush\_log\_at\_trx\_commit](../xtradbinnodb-server-system-variables/index#innodb_doublewrite) - 2 or 0. IST or SST will recover from loss if you have 1.
* [query\_cache\_size](../server-system-variables/index#query_cache_size) - 0
* [query\_cache\_type](../server-system-variables/index#query_cache_type) - 0: The Query cache cannot be used in a Galera context.
* [wsrep\_auto\_increment\_control](../galera-cluster-system-variables/index#wsrep_auto_increment_control) - Normally want ON
* [wsrep\_on](../galera-cluster-system-variables/index#wsrep_on) - ON
* [wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options) - Various settings may need tuning if you are using a WAN.
* [wsrep\_slave\_threads](../galera-cluster-system-variables/index#wsrep_slave_threads) - use for parallel replication
* [wsrep\_sync\_wait](../galera-cluster-system-variables/index#wsrep_sync_wait) (previously wsrep\_causal\_reads) - used transiently to dealing with "critical reads".

 Miscellany
----------

 Until recently, FOREIGN KEYs were buggy.

 LOAD DATA is auto-chunked. That is, it is passed to other nodes piecemeal, not all at once.

 [MariaDB's known issues with Galera](../mariadb-galera-cluster-known-limitations/index)

 DROP USER may not replicate?

 A slight difference in ROLLBACK for conflict: InnoDB rolls back smaller transaction; Galera rolls back last.

 [Slide Deck for Galera](http://www.slideshare.net/skysql/mariadb-galera-cluster-simple-transparent-highly-available)

 SET GLOBAL wsrep\_debug = 1; leads to a lot of debug info in the error log.

 Large UPDATEs / DELETEs should be broken up. This admonition is valid for all databases, but there are additional issues in Galera.

 WAN: May need to increase (from the defaults) wsrep\_provider\_options = evs...

 MySQL/Perona 5.6 or MariaDB 10 is recommended when going to Galera.

 [Cluster limitations](../mariadb-galera-cluster-known-limitations/index) [Slide show](https://www.percona.com/files/presentations/percona-live/nyc-2012/PLNY12-galera-cluster-best-practices.pdf)

 GTIDs
-----

 See [Using MariaDB GTIDs with MariaDB Galera Cluster](../using-mariadb-gtids-with-mariadb-galera-cluster/index).

 How many nodes to have in a cluster
-----------------------------------

 If all the servers are in the same 'vulnerability zone' -- eg, rack or data center -- Have an odd number (at least 3) of nodes.

 When spanning colos, you need 3 (or more) data centers in order to be 'always' up, even during a colo failure. With only 2 data centers, Galera can automatically recover from one colo outage, but not the other. (You pick which.)

 If you use 3 or 4 colos, these number of nodes per colo are safe:

 * 3 nodes: 1+1+1 (1 node in each of 3 colos)
* 4 nodes: 1+1+1+1 (4 nodes won't work in 3 colos)
* 5 nodes: 2+2+1, 2+1+1+1 (5 nodes spread 'evenly' across the colos)
* 6 nodes: 2+2+2, 2+2+1+1
* 7 nodes: 3+2+2, 3+3+1, 2+2+2+1, 3+2+1+1 There may be a way to "weight" the nodes differently; that would allow a few more configurations. With "weighting", give each colo the same weight; then subdivide the weight within each colo evenly. Four nodes in 3 colos: (1/6+1/6) + 1/3 + 1/3 That way, any single colo failure cannot lead to "split brain".

 Postlog
-------

 Posted 2013; VARIABLES: 2015; Refreshed Feb. 2016 

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/galera>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tips-on-converting-to-galera/>

Configuring MariaDB Galera Cluster
==================================

    A number of options need to be set in order for Galera Cluster to work when using MariaDB. These should be set in the [MariaDB option file](../configuring-mariadb-with-option-files/index).

 Mandatory Options
-----------------

 Several options are mandatory, which means that they \*must\* be set in order for Galera Cluster to be enabled or to work properly with MariaDB. The mandatory options are:

 * `[wsrep\_provider](../galera-cluster-system-variables/index#wsrep_provider)` — Path to the Galera library
* `[wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)` — See [Galera Cluster address format and usage](../galera-cluster-address/index)
* `[binlog\_format=ROW](../replication-and-binary-log-server-system-variables/index#binlog_format)` — See [Binary Log Formats](../binary-log-formats/index)
* `[default\_storage\_engine=InnoDB](../server-system-variables/index#default_storage_engine)`
* `[innodb\_autoinc\_lock\_mode=2](../xtradbinnodb-server-system-variables/index#innodb_autoinc_lock_mode)`
* `[innodb\_doublewrite=1](../xtradbinnodb-server-system-variables/index#innodb_doublewrite)` — This is the default value, but it should not be changed when using Galera provider version >= 2.0.
* `[query\_cache\_size=0](../server-system-variables/index#query_cache_size)` — Only mandatory for MariaDB versions prior to MariaDB Galera Cluster 5.5.40, MariaDB Galera Cluster 10.0.14, and [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/).
* `[wsrep\_on=ON](../galera-cluster-system-variables/index#wsrep_on)` — Enable wsrep replication (starting 10.1.1)

 Performance-related Options
---------------------------

 These are optional optimizations that can be made to improve performance.

 * `[innodb\_flush\_log\_at\_trx\_commit=0](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit)` — This is not usually recommended in the case of standard MariaDB. However, it is a bit safer with Galera Cluster, since inconsistencies can always be fixed by recovering from another node.

 Writing Replicated Write Sets to the Binary Log
-----------------------------------------------

 Like with [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index), write sets that are received by a node with [Galera Cluster's certification-based replication](../about-galera-replication/index) are not written to the [binary log](../binary-log/index) by default. If you would like a node to write its replicated write sets to the [binary log](../binary-log/index), then you will have to set `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)`. This is especially helpful if the node is a replication master. See [Using MariaDB Replication with MariaDB Galera Cluster: Configuring a Cluster Node as a Replication Master](../library/using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#configuring-a-cluster-node-as-a-replication-master).

 Replication Filters
-------------------

 Like with [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index), [replication filters](../replication-filters/index) can be used to filter write sets from being replicated by [Galera Cluster's certification-based replication](../about-galera-replication/index). However, they should be used with caution because they may not work as you'd expect.

 The following replication filters are honored for [InnoDB](../innodb/index) DML, but not DDL:

 * `[binlog\_do\_db](../mysqld-options/index#-binlog-do-db)`
* `[binlog\_ignore\_db](../mysqld-options/index#-binlog-ignore-db)`
* `[replicate\_wild\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table)`
* `[replicate\_wild\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table)`

 The following replication filters are honored for DML and DDL for tables that use both the [InnoDB](../innodb/index) and [MyISAM](../myisam-storage-engine/index) storage engines:

 * `[replicate\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_do_table)`
* `[replicate\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table)`

 However, it should be kept in mind that if replication filters cause inconsistencies that lead to replication errors, then nodes may abort.

 See also [MDEV-421](https://jira.mariadb.org/browse/MDEV-421) and [MDEV-6229](https://jira.mariadb.org/browse/MDEV-6229).

 Network Ports
-------------

 Galera Cluster needs access to the following ports:

 * **Standard MariaDB Port** (default: 3306) - For MySQL client connections and [State Snapshot Transfers](../introduction-to-state-snapshot-transfers-ssts/index) that use the `mysqldump` method. This can be changed by setting `[port](../server-system-variables/index#port)`.
* **Galera Replication Port** (default: 4567) - For Galera Cluster replication traffic, multicast replication uses both UDP transport and TCP on this port. Can be changed by setting `[wsrep\_node\_address](../galera-cluster-system-variables/index#wsrep_node_address)`.
* **Galera Replication Listening Interface** (default: `0.0.0.0:4567`) needs to be set using [gmcast.listen\_addr](../wsrep_provider_options/index#gmcastlisten_addr), either
	+ in [wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options): `wsrep_provider_options='gmcast.listen_addr=tcp://<IP_ADDR>:<PORT>;'`
	+ or in [wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)
* **IST Port** (default: 4568) - For Incremental State Transfers. Can be changed by setting `[ist.recv\_addr](http://galeracluster.com/library/documentation/galera-parameters.html#ist-recv-addr)` in `[wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options)`.
* **SST Port** (default: 4444) - For all [State Snapshot Transfer](../introduction-to-state-snapshot-transfers-ssts/index) methods other than `mysqldump`. Can be changed by setting `[wsrep\_sst\_receive\_address](../galera-cluster-system-variables/index#wsrep_sst_receive_address)`.

 Mutiple Galera Cluster Instances on One Server
----------------------------------------------

 If you want to run multiple Galera Cluster instances on one server, then you can do so by starting each instance with `[mysqld\_multi](../mysqld_multi/index)`, or if you are using [systemd](../systemd/index), then you can use the relevant [systemd method for interacting with multiple MariaDB instances](../systemd/index#interacting-with-multiple-mariadb-server-processes).

 You need to ensure that each instance is configured with a different `[datadir](../server-system-variables/index#datadir)`.

 You also need to ensure that each instance is configured with different [network ports](#network-ports).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-mariadb-galera-cluster/>

State Snapshot Transfers (SSTs) in Galera Cluster
==================================================

  

| Title | Description |
| --- | --- |
|  [Introduction to State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) |  In an SST, the cluster provisions nodes by transferring a full data copy from one node to another.  |
|  [mariabackup SST Method](../mariabackup-sst-method/index) |  The mariabackup SST method uses the Mariabackup utility for performing SSTs.  |
|  [Manual SST of Galera Cluster Node With Mariabackup](../manual-sst-of-galera-cluster-node-with-mariabackup/index) |  It can be helpful to perform a "manual SST" with Mariabackup when Galera's normal SSTs fail.  |
|  [xtrabackup-v2 SST Method](../xtrabackup-v2-sst-method/index) |  The xtrabackup-v2 SST method uses the Percona XtraBackup utility for performing SSTs.  |
|  [Manual SST of Galera Cluster Node With Percona XtraBackup](../manual-sst-of-galera-cluster-node-with-percona-xtrabackup/index) |  It can be helpful to perform a "manual SST" with Xtrabackup when Galera's normal SSTs fail.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/state-snapshot-transfers-ssts-in-galera-cluster/>

Galera Cluster Status Variables
===============================

    Viewing Galera Cluster Status Variables
---------------------------------------

 Galera status variables can be viewed with the [SHOW STATUS](../show-status/index) statement.

 
```
SHOW STATUS LIKE 'wsrep%';

```

See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 List of Galera Cluster status variables
---------------------------------------

 MariaDB Galera Cluster has the following status variables:

 #### `wsrep_applier_thread_count`

 * **Description:** Stores current number of applier threads to make clear how many slave threads of this type there are.
* **Introduced:** [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `wsrep_apply_oooe`

 * **Description:** How often writesets have been applied out of order, an indicators of parallelization efficiency.

 

---

 #### `wsrep_apply_oool`

 * **Description:** How often writesets with a higher sequence number were applied before ones with a lower sequence number, implying slow writesets.

 

---

 #### `wsrep_apply_window`

 * **Description:** Average distance between highest and lowest concurrently applied seqno.

 

---

 #### `wsrep_cert_deps_distance`

 * **Description:** Average distance between the highest and the lowest sequence numbers that can possibly be applied in parallel, or the potential degree of parallelization.

 

---

 #### `wsrep_cert_index_size`

 * **Description:** The number of entries in the certification index.

 

---

 #### `wsrep_cert_interval`

 * **Description:** Average number of transactions received while a transaction replicates.

 

---

 #### `wsrep_cluster_capabilities`

 * **Description:**

 

---

 #### `wsrep_cluster_conf_id`

 * **Description:** Total number of cluster membership changes that have taken place.

 

---

 #### `wsrep_cluster_size`

 * **Description:** Number of nodes currently in the cluster.

 

---

 #### `wsrep_cluster_state_uuid`

 * **Description:** UUID state of the cluster. If it matches the value in [wsrep\_local\_state\_uuid](#wsrep_local_state_uuid), the local and cluster nodes are in sync.

 

---

 #### `wsrep_cluster_status`

 * **Description:** Cluster component status. Possible values are `PRIMARY` (primary group configuration, quorum present), `NON_PRIMARY` (non-primary group configuration, quorum lost) or `DISCONNECTED` (not connected to group, retrying).

 

---

 #### `wsrep_cluster_weight`

 * **Description:** The total weight of the current members in the cluster. The value is counted as a sum of of pc.weight of the nodes in the current Primary Component.

 

---

 #### `wsrep_commit_oooe`

 * **Description:** How often a transaction was committed out of order.

 

---

 #### `wsrep_commit_oool`

 * **Description:** No meaning.

 

---

 #### `wsrep_commit_window`

 * **Description:** Average distance between highest and lowest concurrently committed seqno.

 

---

 #### `wsrep_connected`

 * **Description:** Whether or not MariaDB is connected to the wsrep provider. Possible values are `ON` or `OFF`.

 

---

 #### `wsrep_desync_count`

 * **Description:** Returns the number of operations in progress that require the node to temporarily desync from the cluster.

 

---

 #### `wsrep_evs_delayed`

 * **Description:** Provides a comma separated list of all the nodes this node has registered on its delayed list.

 

---

 #### `wsrep_evs_evict_list`

 * **Description:** Lists the UUID’s of all nodes evicted from the cluster. Evicted nodes cannot rejoin the cluster until you restart their mysqld processes.

 

---

 #### `wsrep_evs_repl_latency`

 * **Description:** This status variable provides figures for the replication latency on group communication. It measures latency (in seconds) from the time point when a message is sent out to the time point when a message is received. As replication is a group operation, this essentially gives you the slowest ACK and longest RTT in the cluster. Format is min/avg/​max/stddev

 

---

 #### `wsrep_evs_state`

 * **Description:** Shows the internal state of the EVS Protocol.

 

---

 #### `wsrep_flow_control_paused`

 * **Description:** The fraction of time since the last FLUSH STATUS command that replication was paused due to flow control.

 

---

 #### `wsrep_flow_control_paused_ns`

 * **Description:** The total time spent in a paused state measured in nanoseconds.

 

---

 #### `wsrep_flow_control_recv`

 * **Description:** Number of FC\_PAUSE events received as well as sent since the most recent status query.

 

---

 #### `wsrep_flow_control_sent`

 * **Description:** Number of FC\_PAUSE events sent since the most recent status query

 

---

 #### `wsrep_gcomm_uuid`

 * **Description:** The UUID assigned to the node.

 

---

 #### `wsrep_incoming_addresses`

 * **Description:** Comma-separated list of incoming server addresses in the cluster component.

 

---

 #### `wsrep_last_committed`

 * **Description:** Sequence number of the most recently committed transaction.

 

---

 #### `wsrep_local_bf_aborts`

 * **Description:** Total number of local transactions aborted by slave transactions while being executed

 

---

 #### `wsrep_local_cached_downto`

 * **Description:** The lowest sequence number, or seqno, in the write-set cache (GCache).

 

---

 #### `wsrep_local_cert_failures`

 * **Description:** Total number of local transactions that failed the certification test.

 

---

 #### `wsrep_local_commits`

 * **Description:** Total number of local transactions committed on the node.

 

---

 #### `wsrep_local_index`

 * **Description:** The node's index in the cluster. The index is zero-based.

 

---

 #### `wsrep_local_recv_queue`

 * **Description:** Current length of the receive queue, which is the number of writesets waiting to be applied.

 

---

 #### `wsrep_local_recv_queue_avg`

 * **Description:** Average length of the receive queue since the most recent status query. If this value is noticeably larger than zero, the node is likely to be overloaded, and cannot apply the writesets as quickly as they arrive, resulting in replication throttling.

 

---

 #### `wsrep_local_recv_queue_max`

 * **Description:** The maximum length of the recv queue since the last FLUSH STATUS command.

 

---

 #### `wsrep_local_recv_queue_min`

 * **Description:** The minimum length of the recv queue since the last FLUSH STATUS command.

 

---

 #### `wsrep_local_replays`

 * **Description:** Total number of transaction replays due to asymmetric lock granularity.

 

---

 #### `wsrep_local_send_queue`

 * **Description:** Current length of the send queue, which is the number of writesets waiting to be sent.

 

---

 #### `wsrep_local_send_queue_avg`

 * **Description:** Average length of the send queue since the most recent status query. If this value is noticeably larger than zero, there is most likely network throughput or replication throttling issues.

 

---

 #### `wsrep_local_send_queue_max`

 * **Description:** The maximum length of the send queue since the last FLUSH STATUS command.

 

---

 #### `wsrep_local_send_queue_min`

 * **Description:** The minimum length of the send queue since the last FLUSH STATUS command.

 

---

 #### `wsrep_local_state`

 * **Description:** Internal Galera Cluster FSM state number.

 

---

 #### `wsrep_local_state_comment`

 * **Description:** Human-readable explanation of the state.

 

---

 #### `wsrep_local_state_uuid`

 * **Description:** The node's UUID state. If it matches the value in [wsrep\_cluster\_state\_uuid](#wsrep_cluster_state_uuid), the local and cluster nodes are in sync.

 

---

 #### `wsrep_open_connections`

 * **Description:** The number of open connection objects inside the wsrep provider.

 

---

 #### `wsrep_open_transactions`

 * **Description:** The number of locally running transactions which have been registered inside the wsrep provider. This means transactions which have made operations which have caused write set population to happen. Transactions which are read only are not counted.

 

---

 #### `wsrep_protocol_version`

 * **Description:** The wsrep protocol version being used.

 

---

 #### `wsrep_provider_name`

 * **Description:** The name of the provider. The default is "Galera".

 

---

 #### `wsrep_provider_vendor`

 * **Description:** The vendor string.

 

---

 #### `wsrep_provider_version`

 * **Description:** The version number of the Galera wsrep provider

 

---

 #### `wsrep_ready`

 * **Description:** Whether or not the Galera wsrep provider is ready. Possible values are `ON` or `OFF`

 

---

 #### `wsrep_received`

 * **Description:** Total number of writesets received from other nodes.

 

---

 #### `wsrep_received_bytes`

 * **Description:** Total size in bytes of all writesets received from other nodes.

 

---

 #### `wsrep_repl_data_bytes`

 * **Description:** Total size of data replicated.

 

---

 #### `wsrep_repl_keys`

 * **Description:** Total number of keys replicated.

 

---

 #### `wsrep_repl_keys_bytes`

 * **Description:** Total size of keys replicated.

 

---

 #### `wsrep_repl_other_bytes`

 * **Description:** Total size of other bits replicated.

 

---

 #### `wsrep_replicated`

 * **Description:** Total number of writesets replicated to other nodes.

 

---

 #### `wsrep_replicated_bytes`

 * **Description:** Total size in bytes of all writesets replicated to other nodes.

 

---

 #### `wsrep_rollbacker_thread_count`

 * **Description:** Stores current number of rollbacker threads to make clear how many slave threads of this type there are.
* **Introduced:** [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `wsrep_thread_count`

 * **Description:** Total number of wsrep (applier/rollbacker) threads.

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-cluster-status-variables/>

Galera Cluster System Variables
===============================

     This page documents system variables related to [Galera Cluster](../galera/index). For options that are not system variables, see [Galera Options](../mysqld-options/index#galera-options).

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 Also see the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index).

 #### `wsrep_allowlist`

 * **Description:** Allowed IP addresses, comma delimited.
* **Commandline:** `--wsrep-allowlist=value1[,value2...]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** None
* **Introduced:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `wsrep_auto_increment_control`

 * **Description:** If set to `1` (the default), will automatically adjust the [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) and [auto\_increment\_offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset) variables according to the size of the cluster, and when the cluster size changes. This avoids replication conflicts due to [auto\_increment](../auto_increment/index). In a primary-replica environment, can be set to `OFF`.
* **Commandline:** `--wsrep-auto-increment-control[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `ON`

 

---

 #### `wsrep_causal_reads`

 * **Description:** If set to `ON` (`OFF` is default), enforces [read-committed](../set-transaction/index#read-committed) characteristics across the cluster. In the case that a primary applies an event more quickly than a replica, the two could briefly be out-of-sync. With this variable set to `ON`, the replica will wait for the event to be applied before processing further queries. Setting to `ON` also results in larger read latencies. Deprecated by [wsrep\_sync\_wait=1](#wsrep_sync_wait).
* **Commandline:** `--wsrep-causal-reads[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_certification_rules`

 * **Description:** Certification rules to use in the cluster. Possible values are:
	+ `strict`: Stricter rules that could result in more certification failures. For example with foreign keys, certification failure could result if different nodes receive non-conflicting insertions at about the same time that point to the same row in a parent table
	+ `optimized`: relaxed rules that allow more concurrency and cause less certification failures.
* **Commandline:** `--wsrep-certifcation-rules`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Enumeration
* **Default Value:** `strict`
* **Valid Values:** `strict`, `optimized`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/)

 

---

 #### `wsrep_certify_nonPK`

 * **Description:** When set to `ON` (the default), Galera will still certify transactions for tables with no [primary key](../getting-started-with-indexes/index#primary-key). However, this can still cause undefined behavior in some circumstances. It is recommended to define primary keys for every InnoDB table when using Galera.
* **Commandline:** `--wsrep-certify-nonPK[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `ON`

 

---

 #### `wsrep_cluster_address`

 * **Description:** The addresses of cluster nodes to connect to when starting up.
	+ Good practice is to specify all possible cluster nodes, in the form `gcomm://<node1 or ip:port>,<node2 or ip2:port>,<node3 or ip3:port>`.
	+ Specifying an empty ip (`gcomm://`) will cause the node to start a new cluster (which should not be done in the my.cnf file, as after each restart the server will not rejoin the current cluster).
	+ The variable can be changed at runtime in some configurations, and will result in the node closing the connection to any current cluster, and connecting to the new address.
	+ If specifying a port, note that this is the Galera port, not the MariaDB port.
	+ For example:
		- `gcomm://192.168.0.1,192.168.0.2,192.168.0.3`
		- `gcomm://192.168.0.1:1234,192.168.0.2:1234,192.168.0.3:1234?gmcast.listen_addr=tcp://0.0.0.0:1234`
	+ See also [gmcast.listen\_addr](../wsrep_provider_options/index#gmcastlisten_addr)
* **Commandline:** `--wsrep-cluster-address=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String

 

---

 #### `wsrep_cluster_name`

 * **Description:** The name of the cluster. Nodes cannot connect to clusters with a different name, so needs to be identical on all nodes in the same cluster. The variable can be set dynamically, but note that doing so may be unsafe and cause an outage, and that the wsrep provider is unloaded and loaded.
* **Commandline:** `--wsrep-cluster-name=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:** `my_wsrep_cluster`

 

---

 #### `wsrep_convert_LOCK_to_trx`

 * **Description:** Converts [LOCK/UNLOCK TABLES](../lock-tables-and-unlock-tables/index) statements to [BEGIN](../start-transaction/index) and [COMMIT](../commit/index). Used mainly for getting older applications to work with a multi-primary setup, use carefully, as can result in extremely large writesets.
* **Commandline:** `--wsrep-convert-LOCK-to-trx[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_data_home_dir`

 * **Description:** Directory where wsrep provider will store its internal files.
* **Commandline:** `--wsrep-data-home-dir=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** The [datadir](../server-system-variables/index#datadir) variable value.

 

---

 #### `wsrep_dbug_option`

 * **Description:** Unused. The mechanism to pass the DBUG options to the wsrep provider hasn't been implemented.
* **Commandline:** `--wsrep-dbug-option=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String

 

---

 #### `wsrep_debug`

 * **Description:** WSREP debug level logging. Before [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) was a boolean, which when set to `ON` (`OFF` was default), ensured debug messages would be logged to the [error log](../error-log/index) as well. Before [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), DDL logging was only logged on the originating node. From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), it is logged on other nodes as well.
* **Commandline:** `--wsrep-debug[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Enumeration (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), Boolean (<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))
* **Default Value:** `NONE` (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), `OFF` (<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))
* **Valid Values**: (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)) `NONE`, `SERVER`, `TRANSACTION`, `STREAMING`, `CLIENT`

 

---

 #### `wsrep_desync`

 * **Description:** When a node receives more write-sets than it can apply, the transactions are placed in a received queue. If the node's received queue has too many write-sets waiting to be applied (as defined by the `[gcs.fc\_limit](../wsrep_provider_options/index#gcsfc_limit)` WSREP provider option), then the node would usually engage Flow Control. However, when this option is set to `ON`, Flow Control will be disabled for the desynced node. The desynced node works through the received queue until it reaches a more manageable size. The desynced node continues to receive write-sets from the other nodes in the cluster. The other nodes in the cluster do not wait for the desynced node to catch up, so the desynced node can fall even further behind the other nodes in the cluster. You can check if a node is desynced by checking if the `[wsrep\_local\_state\_comment](../galera-cluster-status-variables/index#wsrep_local_state_comment)` status variable is equal to `Donor/Desynced`.
* **Commandline:** `--wsrep-desync[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_dirty_reads`

 * **Description:** By default, when not synchronized with the group ([wsrep\_ready](../galera-cluster-status-variables/index#wsrep_ready)=OFF) a node will reject all queries other than SET and SHOW. If `wsrep_dirty_reads` is set to `1`, queries which do not change data, like SELECT queries (dirty reads), creating of prepare statement, etc. will be accepted by the node.
* **Commandline:** `--wsrep-dirty-reads[={0|1}]`
* **Scope:** Global,Session
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`
* **Valid Values:** `ON`, `OFF`

 

---

 #### `wsrep_drupal_282555_workaround`

 * **Description:** If set to `ON`, a workaround for [Drupal/MySQL/InnoDB bug #282555](https://www.drupal.org/node/282555) is enabled. This is a bug where, in some cases, when inserting a `DEFAULT` value into an [AUTO\_INCREMENT](../auto_increment/index) column, a duplicate key error may be returned.
* **Commandline:** `--wsrep-drupal-282555-workaround[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_forced_binlog_format`

 * **Description:** A [binary log format](../binary-log-formats/index) that will override any session binlog format settings.
* **Commandline:** `--wsrep-forced-binlog-format=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Default Value:** `NONE`
* **Data Type:** Enum
* **Valid Values:** `STATEMENT`, `ROW`, `MIXED` or `NONE` (which resets the forced binlog format state).

 

---

 #### `wsrep_gtid_domain_id`

 * **Description:** This system variable defines the [GTID](../gtid/index) domain ID that is used for [wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#wsrep-gtid-mode).
	+ When `[wsrep\_gtid\_mode](#wsrep_gtid_mode)` is set to `ON`, `wsrep_gtid_domain_id` is used in place of `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` for all Galera Cluster write sets.
	+ When `[wsrep\_gtid\_mode](#wsrep_gtid_mode)` is set to `OFF`, `wsrep_gtid_domain_id` is simply ignored to allow for backward compatibility.
	+ There are some additional requirements that need to be met in order for this mode to generate consistent [GTIDs](../gtid/index). For more information, see [Using MariaDB GTIDs with MariaDB Galera Cluster](../using-mariadb-gtids-with-mariadb-galera-cluster/index).
* **Commandline:** `--wsrep-gtid-domain-id=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`

 

---

 #### `wsrep_gtid_mode`

 * **Description:** [Wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#wsrep-gtid-mode) attempts to keep [GTIDs](../gtid/index) consistent for Galera Cluster write sets on all cluster nodes. [GTID](../gtid/index) state is initially copied to a joiner node during an [SST](../introduction-to-state-snapshot-transfers-ssts/index). If you are planning to use Galera Cluster with [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index), then wsrep GTID mode can be helpful.
	+ When `wsrep_gtid_mode` is set to `ON`, `[wsrep\_gtid\_domain\_id](#wsrep_gtid_domain_id)` is used in place of `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` for all Galera Cluster write sets.
	+ When `wsrep_gtid_mode` is set to `OFF`, `[wsrep\_gtid\_domain\_id](#wsrep_gtid_domain_id)` is simply ignored to allow for backward compatibility.
	+ There are some additional requirements that need to be met in order for this mode to generate consistent [GTIDs](../gtid/index). For more information, see [Using MariaDB GTIDs with MariaDB Galera Cluster](../using-mariadb-gtids-with-mariadb-galera-cluster/index).
* **Commandline:** `--wsrep-gtid-mode[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `wsrep_gtid_seq_no`

 * **Description:** Internal server usage, manually set WSREP GTID seqno.
* **Commandline:** None
* **Scope:** Session only
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Range:** `0` to `18446744073709551615`
* **Introduced:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `wsrep_ignore_apply_errors`

 * **Description:** Bitmask determining whether errors are ignored, or reported back to the provider.
	+ 0: No errors are skipped.
	+ 1: Ignore some DDL errors (DROP DATABASE, DROP TABLE, DROP INDEX, ALTER TABLE).
	+ 2: Skip DML errors (Only ignores DELETE errors).
	+ 4: Ignore all DDL errors.
* **Commandline:** `--wsrep-ignore-apply-errors`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `7`
* **Range:** `0` to `7`
* **Introduced:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

 #### `wsrep_load_data_splitting`

 * **Description:** If set to `ON` (the default for [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) and before), [LOAD DATA INFILE](../load-data/index) supports big data files by introducing transaction splitting. The setting has been deprecated in Galera 4, and defaults to `OFF` from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).
* **Commandline:** `--wsrep-load-data-splitting[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF` (>= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)), `ON` (<= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/))

 

---

 #### `wsrep_log_conflicts`

 * **Description:** If set to `ON` (`OFF` is default), details of conflicting MDL as well as InnoDB locks in the cluster will be logged.
* **Commandline:** `--wsrep-log-conflicts[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_max_ws_rows`

 * **Description:** Maximum permitted number of rows per writeset. Before [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/) and [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/) this variable was ignored internally and had no effect on the node. From [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/) and [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/) support for this variable has been added and in order to be backward compatible the default value has been changed to `0`, which essentially allows writesets to be any size.
* **Commandline:** `--wsrep-max-ws-rows=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:**
	+ `0` (>= [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/), [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/))
	+ `131072` (<= [MariaDB Galera 10.0.26](https://mariadb.com/kb/en/mariadb-galera-cluster-10026-release-notes/), [MariaDB 10.1.16](https://mariadb.com/kb/en/mariadb-10116-release-notes/))
* **Range:** `0` to `1048576`

 

---

 #### `wsrep_max_ws_size`

 * **Description:** Maximum permitted size in bytes per writeset. Writesets exceeding this will be rejected. Note that versions from and before [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/) and [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/) permitted the maximum to be set beyond 2GB, which was rejected by Galera.
* **Commandline:** `--wsrep-max-ws-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:**
	+ `2147483647` (2GB, >= [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/), [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/))
	+ `1073741824` (1GB, <= [MariaDB Galera 10.0.26](https://mariadb.com/kb/en/mariadb-galera-cluster-10026-release-notes/), [MariaDB 10.1.16](https://mariadb.com/kb/en/mariadb-10116-release-notes/))
* **Range:** `1024` to `2147483647`

 

---

 #### `wsrep_mode`

 * **Description:** Turns on WSREP features which are not part of default behavior.
	+ BINLOG\_ROW\_FORMAT\_ONLY: Only ROW [binlog format](../binary-log-formats/index) is supported.
	+ DISALLOW\_LOCAL\_GTID: Nodes can have GTIDs for local transactions in a number of scenarios. If DISALLOW\_LOCAL\_GTID is set, these operations produce an error ERROR HY000: Galera replication not supported. Scenarios include:
		- A DDL statement is executed with wsrep\_OSU\_method=RSU set.
		- A DML statement writes to a non-InnoDB table.
		- A DML statement writes to an InnoDB table with wsrep\_on=OFF set.
	+ REPLICATE\_ARIA: Whether or not DML updates for [Aria](../aria/index) tables will be replicated. This functionality is experimental and should not be relied upon in production systems.
	+ REPLICATE\_MYISAM: Whether or not DML updates for [MyISAM](../myisam/index) tables will be replicated. This functionality is experimental and should not be relied upon in production systems.
	+ REQUIRED\_PRIMARY\_KEY: Table should have PRIMARY KEY defined.
	+ STRICT\_REPLICATION: Same as the old [wsrep\_strict\_ddl](#wsrep_strict_ddl) setting.
* **Commandline:** `--wsrep-mode=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Enumeration
* **Default Value:** (Empty)
* **Valid Values:** `BINLOG_ROW_FORMAT_ONLY`, `DISALLOW_LOCAL_GTID`, `REQUIRED_PRIMARY_KEY`, `REPLICATE_ARIA`, `REPLICATE_MYISAM` and `STRICT_REPLICATION`
* **Introduced:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `wsrep_mysql_replication_bundle`

 * **Description:** Determines the number of replication events that are grouped together. Experimental implementation aimed to assist with bottlenecks when a single replica faces a large commit time delay. If set to `0` (the default), there is no grouping.
* **Commandline:** `--wsrep-mysql-replication-bundle=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Numeric
* **Default Value:** `0`
* **Range:** `0` to `1000`

 

---

 #### `wsrep_node_address`

 * **Description:** Specifies the node's network address, in the format `ip address[:port]`. As of [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/), supports IPv6. The default behavior is for the node to pull the address of the first network interface on the system and the default Galera port. This autoguessing can be unreliable, particularly in the following cases:
	+ cloud deployments
	+ container deployments
	+ servers with multiple network interfaces.
	+ servers running multiple nodes.
	+ network address translation (NAT).
	+ clusters with nodes in more than one region.
* **See also** [wsrep\_provider\_options -> gmcast.listen\_addr](../wsrep_provider_options/index#gmcastlisten_addr)
* **Commandline:** `--wsrep-node-address=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** Primary network address, usually `eth0` with a default port of 4567, or `0.0.0.0` if no IP address.

 

---

 #### `wsrep_node_incoming_address`

 * **Description:** This is the address from which the node listens for client connections. If an address is not specified or it's set to `AUTO` (default), mysqld uses either [--bind-address](../server-system-variables/index#bind_address) or [--wsrep-node-address](#wsrep_node_address), or tries to get one from the list of available network interfaces, in the same order. See also [wsrep\_provider\_options -> gmcast.listen\_addr](../wsrep_provider_options/index#gmcastlisten_addr).
* **Commandline:** `--wsrep-node-incoming-address=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** `AUTO`

 

---

 #### `wsrep_node_name`

 * **Description:** Name of this node. This name can be used in [wsrep\_sst\_donor](#wsrep_sst_donor) as a preferred donor. Note that multiple nodes in a cluster can have the same name.
* **Commandline:** `--wsrep-node-name=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:** The server's hostname.

 

---

 #### `wsrep_notify_cmd`

 * **Description:** Command to be executed each time the node state or the cluster membership changes. Can be used for raising an alarm, configuring load balancers and so on. See the [Codership Notification Script page](https://galeracluster.com/library/documentation/notification-cmd.html) for more details.
* **Commandline:** `--wsrep-notify-command=value`
* **Scope:** Global
* **Dynamic:**
	+ No (>= [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/))
	+ Yes (<= [MariaDB 10.5.8](https://mariadb.com/kb/en/mariadb-1058-release-notes/), [MariaDB 10.4.17](https://mariadb.com/kb/en/mariadb-10417-release-notes/), [MariaDB 10.3.27](https://mariadb.com/kb/en/mariadb-10327-release-notes/), [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/))
* **Data Type:** String
* **Default Value:** Empty

 

---

 #### `wsrep_on`

 * **Description:** Whether or not wsrep replication is enabled. If the global value is set to `OFF` (the default since [MariaDB 10.1](../what-is-mariadb-101/index)), it is not possible to load the provider and join the node in the cluster. If only the session value is set to `OFF`, the operations from that particular session are not replicated in the cluster, but other sessions and applier threads will continue as normal. The session value of the variable does not affect the node's membership and thus, regardless of its value, the node keeps receiving updates from other nodes in the cluster. Before [MariaDB 10.1](../what-is-mariadb-101/index), even though this variable is `ON` by default, its value gets automatically adjusted based on whether mandatory configurations to turn on Galera replication have been specified. Since [MariaDB 10.1](../what-is-mariadb-101/index), it is set to `OFF` by default and must be turned on to enable Galera replication.
* **Commandline:** `--wsrep-on[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF` (>= [MariaDB 10.1](../what-is-mariadb-101/index)), `ON` (<= MariaDB Galera Cluster 10.0),
* **Valid Values:** `ON`, `OFF`

 

---

 #### `wsrep_OSU_method`

 * **Description:** Online schema upgrade method. The default is `TOI`, specifying the setting without the optional parameter will set to `RSU`.
	+ `TOI`: Total Order Isolation. In each cluster node, DDL is processed in the same order regarding other transactions, guaranteeing data consistency. However, affected parts of the database will be locked for the whole cluster.
	+ `RSU`: Rolling Schema Upgrade. DDL processing is only done locally on the node, and the user needs perform the changes manually on each node. The node is desynced from the rest of the cluster while the processing takes place to avoid the blocking other nodes. Schema changes [*must* be backwards compatible in the same way as for ROW based replication](../replication-when-the-master-and-slave-have-different-table-definitions/index) to avoid breaking replication when the DDL processing is complete on the single node, and replication recommences.
* **Commandline:** `--wsrep-OSU-method[=value]`
* **Scope:** Global, Session (since [MariaDB Galera 10.0.19](https://mariadb.com/kb/en/mariadb-galera-cluster-10019-release-notes/))
* **Dynamic:** Yes
* **Data Type:** Enum
* **Default Value:** `TOI`
* **Valid Values:** `TOI`, `RSU`

 

---

 #### `wsrep_patch_version`

 * **Description:** Wsrep patch version, for example `wsrep_25.10`.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** None

 

---

 #### `wsrep_provider`

 * **Description:** Location of the wsrep library, usually `/usr/lib/libgalera_smm.so` on Debian and Ubuntu, and `/usr/lib64/libgalera_smm.so` on Red Hat/CentOS.
* **Commandline:** `--wsrep-provider=value`
* **Scope:** Global
	+ No (>= [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/))
	+ Yes (<= [MariaDB 10.5.8](https://mariadb.com/kb/en/mariadb-1058-release-notes/), [MariaDB 10.4.17](https://mariadb.com/kb/en/mariadb-10417-release-notes/), [MariaDB 10.3.27](https://mariadb.com/kb/en/mariadb-10327-release-notes/), [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/))
* **Data Type:** String
* **Default Value:** None

 

---

 #### `wsrep_provider_options`

 * **Description:** Semicolon (;) separated list of wsrep options (see [wsrep\_provider\_options](../wsrep_provider_options/index)).
* **Commandline:** `--wsrep-provider-options=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** Empty

 

---

 #### `wsrep_recover`

 * **Description:** If set to `ON` when the server starts, the server will recover the sequence number of the most recent write set applied by Galera, and it will be output to `stderr`, which is usually redirected to the [error log](../error-log/index). At that point, the server will exit. This sequence number can be provided to the `[wsrep\_start\_position](#wsrep_start_position)` system variable.
* **Commandline:** `--wsrep-recover[={0|1}]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_reject_queries`

 * **Description:** Variable to set to reject queries from client connections, useful for maintenance. The node continues to apply write-sets, but an `Error 1047: Unknown command` error is generated by a client query.
	+ `NONE` - Not set. Queries will be processed as normal.
	+ `ALL` - All queries from client connections will be rejected, but existing client connections will be maintained.
	+ `ALL_KILL` All queries from client connections will be rejected, and existing client connections, including the current one, will be immediately killed.
* **Commandline:** `--wsrep-reject-queries[=value]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Enum
* **Default Value:** `NONE`
* **Valid Values:** `NONE`, `ALL`, `ALL_KILL`
* **Introduced:** [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), [MariaDB 10.2.14](https://mariadb.com/kb/en/mariadb-10214-release-notes/), [MariaDB 10.1.32](https://mariadb.com/kb/en/mariadb-10132-release-notes/)

 

---

 #### `wsrep_replicate_myisam`

 * **Description:** Whether or not DML updates for [MyISAM](../myisam/index) tables will be replicated. This functionality is still experimental and should not be relied upon in production systems. Deprecated in [MariaDB 10.6](../what-is-mariadb-106/index), and removed in [MariaDB 10.7](../what-is-mariadb-107/index), use [wsrep\_mode](#wsrep_mode) instead.
* **Commandline:** `--wsrep-replicate-myisam[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Default Value:** `OFF`
* **Data Type:** Boolean
* **Valid Values:** `ON`, `OFF`
* **Deprecated:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)
* **Removed:** [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)

 

---

 #### `wsrep_restart_slave`

 * **Description:** If set to ON, the replica is restarted automatically, when node joins back to cluster.
* **Commandline:** `--wsrep-restart-slave[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Default Value:** `OFF`
* **Data Type:** Boolean

 

---

 #### `wsrep_retry_autocommit`

 * **Description:** Number of times autocommited queries will be retried due to cluster-wide conflicts before returning an error to the client. If set to `0`, no retries will be attempted, while a value of `1` (the default) or more specifies the number of retries attempted. Can be useful to assist applications using autocommit to avoid deadlocks.
* **Commandline:** `--wsrep-retry-autocommit=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Numeric
* **Default Value:** `1`
* **Range:** `0` to `10000`

 

---

 #### `wsrep_slave_FK_checks`

 * **Description:** If set to ON (the default), the applier replica thread performs foreign key constraint checks.
* **Commandline:** `--wsrep-slave-FK-checks[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** ON

 

---

 #### `wsrep_slave_threads`

 * **Description:** Number of replica threads used to apply Galera write sets in parallel. The Galera replica threads are able to determine which write sets are safe to apply in parallel. However, if your cluster nodes seem to have frequent consistency problems, then setting the value to `1` will probably fix the problem. See [About Galera Replication: Galera Replica Threads](../about-galera-replication/index#galera-slave-threads) for more information.
* **Commandline:** `--wsrep-slave-threads=`#
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `1`
* **Range:** `1` to `512`

 

---

 #### `wsrep_slave_UK_checks`

 * **Description:** If set to ON, the applier replica thread performs secondary index uniqueness checks.
* **Commandline:** `--wsrep-slave-UK-checks[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** OFF

 

---

 #### `wsrep_sr_store`

 * **Description:** Storage for streaming replication fragments.
* **Commandline:** `--wsrep-sr-store=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Enum
* **Default Value:** `table`
* **Valid Values:** `table`, `none`
* **Introduced:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

 #### `wsrep_sst_auth`

 * **Description:** Username and password of the user to use for replication. Unused if [wsrep\_sst\_method](#wsrep_sst_method) is set to `rsync`, while for other methods it should be in the format `<user>:<password>`. The contents are masked in logs and when querying the value with [SHOW VARIABLES](../show-variables/index). See [Introduction to State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) for more information.
* **Commandline:** `--wsrep-sst-auth=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:** (Empty)

 

---

 #### `wsrep_sst_donor`

 * **Description:** Comma-separated list (from 5.5.33) or name (as per [wsrep\_node\_name](index#wsrep_node_name)) of the servers as donors, or the source of the state transfer, in order of preference. The donor-selection algorithm, in general, prefers a donor capable of transferring only the missing transactions (IST) to the joiner node, instead of the complete state (SST). Thus, it starts by looking for an IST-capable node in the given donor list followed by rest of the nodes in the cluster. In case multiple candidate nodes are found outside the specified donor list, the node in the same segment ([gmcast.segment](../wsrep_provider_options/index#gmcastsegment)) as the joiner is preferred. If none of the existing nodes in the cluster can serve the missing transactions through IST, the algorithm moves on to look for a suitable node to transfer the entire state (SST). It first looks at the nodes specified in the donor list (irrespective of their segment). If no suitable donor is still found, the rest of the donor nodes are checked for suitability only if the donor list has a "terminating-comma". Note that a stateless node (the Galera arbitrator) can never be a donor. See [Introduction to State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) for more information. [NOTE] Although the variable is dynamic, the node will not use the new value unless the node requiring SST or IST disconnects from the cluster. To force this, set [wsrep\_cluster\_address](index#wsrep_cluster_address) to an empty string and back to the nodes list. After setting this variable dynamically, on startup the value from the configuration file will be used again.
* **Commandline:** `--wsrep-sst-donor=value`
* **Scope:** Global
* **Dynamic:** Yes (read note above)
* **Data Type:** String
* **Default Value:**

 

---

 #### `wsrep_sst_donor_rejects_queries`

 * **Description:** If set to `ON` (`OFF` is default), the donor node will reject incoming queries, returning an `UNKNOWN COMMAND` error code. Can be used for informing load balancers that a node is unavailable.
* **Commandline:** `--wsrep-sst-donor-rejects-queries[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Boolean
* **Default Value:** `OFF`

 

---

 #### `wsrep_sst_method`

 * **Description:** Method used for taking the [state snapshot transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index). See [Introduction to State Snapshot Transfers (SSTs): SST Methods](../introduction-to-state-snapshot-transfers-ssts/index#sst-methods) for more information.
* **Commandline:** `--wsrep-sst-method=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:** `rsync`
* **Valid Values:** `rsync`, `mysqldump`, `xtrabackup`, `xtrabackup-v2`, `mariabackup`

 

---

 #### `wsrep_sst_receive_address`

 * **Description:** This is the address where other nodes (donor) in the cluster connect to in order to send the state-transfer updates. If an address is not specified or its set to `AUTO` (default), mysqld uses [--wsrep\_node\_address](index#wsrep_node_address)'s value as the receiving address. However, if [--wsrep\_node\_address](index#wsrep_node_address) is not set, it uses address from either [--bind-address](../server-system-variables/index#bind_address) or tries to get one from the list of available network interfaces, in the same order. Note: setting it to `localhost` will make it impossible for nodes running on other hosts to reach this node. See [Introduction to State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) for more information.
* **Commandline:** `--wsrep-sst-receive-address=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:** `AUTO`

 

---

 #### `wsrep_start_position`

 * **Description:** The start position that the node should use in the format: `UUID:seq_no`. The proper value to use for this position can be recovered with `[wsrep\_recover](#wsrep_recover)`.
* **Commandline:** `--wsrep-start-position=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** String
* **Default Value:**  `00000000-0000-0000-0000-000000000000:-1`

 

---

 #### `wsrep_status_file`

 * **Description:** wsrep status output filename.
* **Commandline:** `--wsrep-status-file=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** None
* **Introduced:** [MariaDB 10.9](../what-is-mariadb-109/index)

 

---

 #### `wsrep_strict_ddl`

 * **Description:** If set, reject DDL statements on affected tables not supporting Galera replication. This is done by checking if the table is InnoDB, which is the only table currently fully supporting Galera replication. MyISAM tables will not trigger the error if the experimental [wsrep\_replicate\_myisam](#wsrep_replicate_myisam) setting is `ON`. If set, should be set on all tables in the cluster. Affected DDL statements include:  
 [CREATE TABLE](../create-table/index) (e.g. CREATE TABLE t1(a int) engine=Aria)  
 [ALTER TABLE](../alter-table/index)  
 [TRUNCATE TABLE](../truncate-table/index)  
 [CREATE VIEW](../create-view/index)  
 [CREATE TRIGGER](../create-trigger/index)  
 [CREATE INDEX](../create-index/index)  
 [DROP INDEX](../drop-index/index)  
 [RENAME TABLE](../rename-table/index)  
 [DROP TABLE](../drop-table/index)  
 Statements in [procedures](../stored-procedures/index), [events](../event-scheduler/index), and [functions](../stored-functions/index) are permitted as the affected tables are only known at execution. Furthermore, the various USER, ROLE, SERVER and DATABASE statements are also allowed as they do not have an affected table. Deprecated in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) and removed in [MariaDB 10.7](../what-is-mariadb-107/index). Use [wsrep\_mode=STRICT\_REPLICATION](#wsrep_mode) instead.
* **Commandline:** `--wsrep-strict-ddl[={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)
* **Deprecated:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)
* **Removed:** [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)

 

---

 #### `wsrep_sync_wait`

 * **Description:** Setting this variable ensures causality checks will take place before executing an operation of the type specified by the value, ensuring that the statement is executed on a fully synced node. While the check is taking place, new queries are blocked on the node to allow the server to catch up with all updates made in the cluster up to the point where the check was begun. Once reached, the original query is executed on the node. This can result in higher latency. Note that when [wsrep\_dirty\_reads](#wsrep_dirty_reads) is ON, values of wsrep\_sync\_wait become irrelevant. Sample usage (for a critical read that must have the most up-to-date data) `SET SESSION wsrep_sync_wait=1; SELECT ...; SET SESSION wsrep_sync_wait=0;`
	+ `0` - Disabled (default)
	+ `1` - READ (SELECT and BEGIN/START TRANSACTION). Up until [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/), [MariaDB Galera 10.0.31](https://mariadb.com/kb/en/mariadb-galera-cluster-10031-release-notes/) and [MariaDB Galera 5.5.56](https://mariadb.com/kb/en/mariadb-galera-cluster-5556-release-notes/), also SHOW). This is the same as [wsrep\_causal\_reads=1](#wsrep_causal_reads).
	+ `2` - UPDATE and DELETE;
	+ `3` - READ, UPDATE and DELETE;
	+ `4` - INSERT and REPLACE;
	+ `5` - READ, INSERT and REPLACE;
	+ `6` - UPDATE, DELETE, INSERT and REPLACE;
	+ `7` - READ, UPDATE, DELETE, INSERT and REPLACE;
	+ `8` - SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `9` - READ and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `10` - UPDATE, DELETE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `11` - READ, UPDATE, DELETE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `12` - INSERT, REPLACE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `13` - READ, INSERT, REPLACE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `14` - UPDATE, DELETE, INSERT, REPLACE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
	+ `15` - READ, UPDATE, DELETE, INSERT, REPLACE and SHOW (from [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB Galera 10.0.32](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-release-notes/), [MariaDB Galera 5.5.57](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-release-notes/))
* **Commandline:** `--wsrep-sync-wait=`#
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `0`
* **Range:**
	+ `0` to `15`

 

---

 #### `wsrep_trx_fragment_size`

 * **Description:** Size of transaction fragments for streaming replication (measured in units as specified by [wsrep\_trx\_fragment\_unit](#wsrep_trx_fragment_unit))
* **Commandline:** `--wsrep-trx-fragment-size=`#
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`
* **Range:** `0` to `2147483647`
* **Introduced:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

 #### `wsrep_trx_fragment_unit`

 * **Description:** Unit for streaming replication transaction fragments' size:
	+ `bytes`: transaction’s binlog events buffer size in bytes
	+ `rows`: number of rows affected by the transaction
	+ `statements`: number of SQL statements executed in the multi-statement transaction
* **Commandline:** `--wsrep-trx-fragment-unit=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** enum
* **Default Value:** `bytes`
* **Valid Values:** `bytes`, `rows` or `statements`
* **Introduced:** [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-cluster-system-variables/>

Building the Galera wsrep Package on Ubuntu and Debian
======================================================

    The instructions on this page were used to create the *galera* package on the Ubuntu and Debian Linux distributions. This package contains the wsrep provider for [MariaDB Galera Cluster](../galera/index).

 
**MariaDB Galera Cluster starting with 5.5.35**Starting with MariaDB Galera Cluster 5.5.35, the version of the wsrep provider is **25.3.5**. We also provide **25.2.9** for those that need or want it.

 Prior to that, the wsrep version was 23.2.7.

 
1. Install prerequisites:

 
```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get -y install check debhelper libasio-dev libboost-dev libboost-program-options-dev libssl-dev scons

```

2. Clone [galera.git](https://github.com/mariadb/galera) from [github.com/mariadb](https://github.com/mariadb) and checkout mariadb-3.x banch:

 
```
git init repo
cd repo
git clone -b mariadb-3.x https://github.com/MariaDB/galera.git

```

3. Build the packages by executing `build.sh` under scripts/ directory with `-p` switch:

 
```
cd galera
./scripts/build.sh -p

```

When finished, you will have the Debian packages for galera library and arbitrator in the parent directory.

 Running galera test suite
-------------------------

 If you want to run the `galera` test suite (`mysql-test-run --suite=galera`), you need to install the galera library as either `/usr/lib/galera/libgalera_smm.so` or `/usr/lib64/galera/libgalera_smm.so`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-the-galera-wsrep-package-on-ubuntu-and-debian/>

Installing Galera from Source
=============================

     There are binary installation packages available for RPM and Debian-based distributions, which will pull in all required Galera dependencies.

 If these are not available, you will need to build Galera from source.

 
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**Starting from [MariaDB 10.1](../what-is-mariadb-101/index), the wsrep API for Galera Cluster is included by default. Follow the usual [compiling-mariadb-from-source](../compiling-mariadb-from-source/index) instructions

 

**MariaDB until [10.0](../what-is-mariadb-100/index)**[MariaDB 10.0](../what-is-mariadb-100/index) and below are no longer supported. The instructions below have only historical significance.

 Preparation
-----------

 *make* cannot manage dependencies for the build process, so the following packages need to be installed first:

 RPM-based:

 
```
yum-builddep MariaDB-server

```

Debian-based:

 
```
apt-get build-dep mariadb-server

```

If running on an alternative system, or the commands are available, the following packages are required. You will need to check the repositories for the correct package names on your distribution - these may differ between distributions, or require additional packages:

 #### MariaDB Database Server with wsrep API

 * Git, CMake (on Fedora, both cmake and cmake-fedora are required), GCC and GCC-C++, Automake, Autoconf, and Bison, as well as development releases of libaio and ncurses.

 Building
--------

 You can use Git to download the source code, as MariaDB source code is available through GitHub. Clone the repository:

 
```
git clone https://github.com/mariadb/server mariadb

```

1. Checkout the branch (e.g. 10.0-galera or 5.5-galera), for example:

 
```
cd mariadb
git checkout 10.0-galera

```

### Building the Database Server

 The standard and Galera cluster database servers are the same, except that for Galera Cluster, the wsrep API patch is included. Enable the patch with the CMake configuration options `WITH_WSREP` and `WITH_INNODB_DISALLOW_WRITES`. To build the database server, run the following commands:

 
```
cmake -DWITH_WSREP=ON -DWITH_INNODB_DISALLOW_WRITES=ON .
make
make install

```

There are also some build scripts in the *BUILD/* directory which may be more convenient to use. For example, the following pre-configures the build options discussed above:

 
```
./BUILD/compile-pentium64-wsrep

```

There are several others as well, so you can select the most convenient.

 
Besides the server with the Galera support, you will also need a galera provider.

 Preparation
-----------

 *make* cannot manage dependencies itself, so the following packages need to be installed first:

 
```
apt-get install -y scons check 

```

If running on an alternative system, or the commands are available, the following packages are required. You will need to check the repositories for the correct package names on your distribution - these may differ between distributions, or require additional packages:

 #### Galera Replication Plugin

 * SCons, as well as development releases of Boost (libboost\_program\_options, libboost\_headers1), Check and OpenSSL.

 Building
--------

 Run:

 
```
git clone -b mariadb-4.x https://github.com/MariaDB/galera.git

```

If you are using [MariaDB 10.3](../what-is-mariadb-103/index) or earlier, you should checkout `mariadb-3.x` instead.

 After this, the source files for the Galera provider will be in the `galera` directory.

 ### Building the Galera Provider

 The Galera Replication Plugin both implements the wsrep API and operates as the database server's wsrep Provider. To build, cd into the *galera/*  directory and do:

 
```
git submodule init
git submodule update
./scripts/build.sh
mkdir /usr/lib64/galera
cp libgalera_smm.so /usr/lib64/galera

```

The path to `libgalera_smm.so` needs to be defined in the *my.cnf* configuration file.

 
Building Galera Replication Plugin from source on FreeBSD runs into issues due to Linux dependencies. To overcome these, either install the binary package: `pkg install galera`, or use the ports build available at `/usr/ports/databases/galera`.

 
Configuration
-------------

 After building, a number of other steps are necessary:

 * Create the database server user and group:

 
```
 groupadd mysql
 useradd -g mysql mysql

```

* Install the database (the path may be different if you specified CMAKE\_INSTALL\_PREFIX):

 
```
 cd /usr/local/mysql
 ./scripts/mariadb-install-db --user=mysql

```

* If you want to install the database in a location other than  */usr/local/mysql/data* , use the *--basedir* or *--datadir* options.
* Change the user and group permissions for the base directory.

 
```
 chown -R mysql /usr/local/mysql
 chgrp -R mysql /usr/local/mysql

```

* Create a system unit for the database server.

 
```
cp /usr/local/mysql/supported-files/mysql.server /etc/init.d/mysql
chmod +x /etc/init.d/mysql
chkconfig --add mysql

```

* Galera Cluster can now be started using the service command, and is set to start at boot.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-galera-from-source/>

Galera Test Repositories
========================

    To facilitate development and QA, we have created some test repositories for the Galera wsrep provider.

 
These are **test** repositories. There will be periods when they do not work at all, or work incorrectly, or possibly cause earthquakes, typhoons, and tornadoes. You have been warned.

 
Galera Test Repositories for YUM
--------------------------------

 Replace `${dist}` in the code below for the YUM-based distribution you are testing. Valid distributions are:

 * `centos5-amd64`
* `centos5-x86`
* `centos6-amd64`
* `centos6-x86`
* `centos7-amd64`
* `rhel5-amd64`
* `rhel5-x86`
* `rhel6-amd64`
* `rhel6-x86`
* `rhel6-ppc64`
* `rhel7-amd64`
* `rhel7-ppc64`
* `rhel7-ppc64le`
* `fedora22-amd64`
* `fedora22-x86`
* `fedora23-amd64`
* `fedora23-x86`
* `fedora24-amd64`
* `fedora24-x86`
* `opensuse13-amd64`
* `opensuse13-x86`
* `sles11-amd64`
* `sles11-x86`
* `sles12-amd64`
* `sles12-ppc64le`

 
```
# Place this code block in a file at /etc/yum.repos.d/galera.repo
[galera-test]
name = galera-test
baseurl = http://yum.mariadb.org/galera/repo/rpm/${dist}
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

```

Galera Test Repositories for APT
--------------------------------

 Replace `${dist}` in the code below for the APT-based distribution you are testing. Valid ones are:

 * `wheezy`
* `jessie`
* `sid`
* `precise`
* `trusty`
* `xenial`

 
```
# run the following command:
sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db 0xF1656F24C74CD1D8

# Add the following line to your /etc/apt/sources.list file:
deb http://yum.mariadb.org/galera/repo/deb ${dist} main

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-test-repositories/>

wsrep\_provider\_options
========================

    wsrep\_provider\_options
------------------------

 The following options can be set as part of the Galera [wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options) variable. Dynamic options can be changed while the server is running.

 Options need to be provided as a semicolon (;) separated list on a single line. Options that are not explicitly set are set to their default value.

 Note that before Galera 3, the `repl` tag was named `replicator`.

 #### `base_dir`

 * **Description:** Specifies the data directory

 

---

 #### `base_host`

 * **Description:** For internal use. Should not be manually set.
* **Default:** `127.0.0.1` (detected network address)

 

---

 #### `base_port`

 * **Description:** For internal use. Should not be manually set.
* **Default:** `4567`

 

---

 #### `cert.log_conflicts`

 * **Description:** Certification failure log details.
* **Dynamic:** Yes
* **Default:** `no`

 

---

 #### `cert.optimistic_pa`

 * **Description:** Controls parallel application of actions on the replica. If set, the full range of parallelization as determined by the certification algorithm is permitted. If not set, the parallel applying window will not exceed that seen on the primary, and applying will start no sooner than after all actions it has seen on the master are committed.
* **Dynamic:** Yes
* **Default:** `yes`

 

---

 #### `debug`

 * **Description:** Enable debugging.
* **Dynamic:** Yes
* **Default:** `no`

 

---

 #### `evs.auto_evict`

 * **Description:** Number of entries the node permits for a given delayed node before triggering the Auto Eviction protocol. An entry is added to a delayed list for each delayed response from a node. If set to `0`, the default, the Auto Eviction protocol is disabled for this node. See [Auto Eviction](https://galeracluster.com/library/documentation/auto-eviction.html) for more.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `evs.causal_keepalive_period`

 * **Description:** Used by the developers only, and not manually serviceable.
* **Dynamic:** No
* **Default:** The [evs.keepalive\_period](#evskeepalive_period).

 

---

 #### `evs.debug_log_mask`

 * **Description:** Controls EVS debug logging. Only effective when [wsrep\_debug](../galera-cluster-system-variables/index#wsrep_debug) is on.
* **Dynamic:** Yes
* **Default:** `0x1`

 

---

 #### `evs.delay_margin`

 * **Description:** Time that response times can be delayed before this node adds an entry to the delayed list. See [evs.auto\_evict](#evsauto_evict). Must be set to a higher value than the round-trip delay time between nodes.
* **Dynamic:** No
* **Default:** `PT1S`

 

---

 #### `evs.delayed_keep_period`

 * **Description:** Time that this node requires a previously delayed node to remain responsive before being removed from the delayed list. See [evs.auto\_evict](#evsauto_evict).
* **Dynamic:** No
* **Default:** `PT30S`

 

---

 #### `evs.evict`

 * **Description:** When set to the gcomm UUID of a node, that node is evicted from the cluster. When set to an empty string, the eviction list is cleared on the node where it is set. See [evs.auto\_evict](#evsauto_evict).
* **Dynamic:** No
* **Default:** Empty string

 

---

 #### `evs.inactive_check_period`

 * **Description:** Frequency of checks for peer inactivity (looking for nodes with delayed responses), after which nodes may be added to the delayed list, and later evicted.
* **Dynamic:** No
* **Default:**  `PT0.5S`

 

---

 #### `evs.inactive_timeout`

 * **Description:** Time limit that a node can be inactive before being pronounced as dead.
* **Dynamic:** No
* **Default:** `PT15S`

 

---

 #### `evs.info_log_mask`

 * **Description:** Controls extra EVS info logging. Bits:
	+ 0x1 – extra view change information
	+ 0x2 – extra state change information
	+ 0x4 – statistics
	+ 0x8 – profiling (only available in builds with profiling enabled)
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `evs.install_timeout`

 * **Description:** Timeout on waits for install message acknowledgments. Replaces evs.consensus\_timeout.
* **Dynamic:** Yes
* **Default:** `PT7.5S`

 

---

 #### `evs.join_retrans_period`

 * **Description:** Time period for how often retransmission of EVS join messages when forming cluster membership should occur.
* **Dynamic:** Yes
* **Default:** `PT1S`

 

---

 #### `evs.keepalive_period`

 * **Description:** How often keepalive signals should be transmitted when there's no other traffic.
* **Dynamic:** Yes
* **Default:** `PT1S`

 

---

 #### `evs.max_install_timeouts`

 * **Description:** Number of membership install rounds to attempt before timing out. The total rounds will be this value plus two.
* **Dynamic:** No
* **Default:** `3`

 

---

 #### `evs.send_window`

 * **Description:** Maximum number of packets that can be replicated at a time, Must be more than [evs.user\_send\_window](#evsuser_send_window), which applies to data packets only (double is recommended). In WAN environments can be set much higher than the default, for example `512`.
* **Dynamic:** Yes
* **Default:** `4`

 

---

 #### `evs.stats_report_period`

 * **Description:** Reporting period for EVS statistics.
* **Dynamic:** No
* **Default:** `PT1M`

 

---

 #### `evs.suspect_timeout`

 * **Description:** A node will be suspected to be dead after this period of inactivity. If all nodes agree, the node is dropped from the cluster before [evs.inactive\_timeout](#evsinactive_timeout) is reached.
* **Dynamic:** No
* **Default:** `PT5S`

 

---

 #### `evs.use_aggregate`

 * **Description:** If set to `true` (the default), small packets will be aggregated into one where possible.
* **Dynamic:** No
* **Default:** `true`

 

---

 #### `evs.user_send_window`

 * **Description:** Maximum number of data packets that can be replicated at a time. Must be smaller than [evs.send\_window](#evssend_window) (half is recommended). In WAN environments can be set much higher than the default, for example `512`.
* **Dynamic:** Yes
* **Default:** `2`

 

---

 #### `evs.version`

 * **Description:** EVS protocol version. Defaults to `0` for backward compatibility. Certain EVS features (e.g. auto eviction) require more recent versions.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `evs.view_forget_timeout`

 * **Description:** Time after which past views will be dropped from the view history.
* **Dynamic:** No
* **Default:** `P1D`

 

---

 #### `gcache.dir`

 * **Description:** Directory where GCache files are placed.
* **Dynamic:** No
* **Default:** The working directory

 

---

 #### `gcache.keep_pages_size`

 * **Description:** Total size of the page storage pages for caching. One page is always present if only page storage is enabled.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `gcache.mem_size`

 * **Description:** Maximum size of size of the malloc() store for setups that have spare RAM.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `gcache.name`

 * **Description:** Gcache ring buffer storage file name. By default placed in the working directory, changing to another location or partition can reduce disk IO.
* **Dynamic:** No
* **Default:** `./galera.cache` ---

 #### `gcache.page_size`

 * **Description:** Size of the page storage page files. These are prefixed by `gcache.page`. Can be set to as large as the disk can handle.
* **Dynamic:** No
* **Default:** `128M`

 

---

 #### `gcache.recover`

 * **Description:** Whether or not gcache recovery takes place when the node starts up. If it is possible to recover gcache, the node can then provide IST to other joining nodes, which assists when the whole cluster is restarted.
* **Dynamic:** No
* **Default:** `no`
* **Introduced:** [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/), [MariaDB Galera 10.0.29](https://mariadb.com/kb/en/mariadb-galera-cluster-10029-release-notes/), [MariaDB Galera 5.5.54](https://mariadb.com/kb/en/mariadb-galera-cluster-5554-release-notes/)

 

---

 #### `gcache.size`

 * **Description:** Gcache ring buffer storage size (the space the node uses for caching write sets), preallocated on startup.
* **Dynamic:** No
* **Default:** `128M`

 

---

 #### `gcomm.thread_prio`

 * **Description:** Gcomm thread policy and priority (in the format `policy:priority`. Priority is an integer, while policy can be one of:
	+ `fifo`: First-in, first-out scheduling. Always preempt other, batch or idle threads and can only be preempted by other `fifo` threads of a higher priority or blocked by an I/O request.
	+ `rr`: Round-robin scheduling. Always preempt other, batch or idle threads. Runs for a fixed period of time after which the thread is stopped and moved to the end of the list, being replaced by another round-robin thread with the same priority. Otherwise runs until preempted by other `rr` threads of a higher priority or blocked by an I/O request.
	+ `other`: Default scheduling on Linux. Threads run until preempted by a thread of a higher priority or a superior scheduling designation, or blocked by an I/O request.
* **Dynamic:** No
* **Default:** Empty string

 

---

 #### `gcs.fc_debug`

 * **Description:** If set to a value greater than zero (the default), debug statistics about SST flow control will be posted each time after the specified number of writesets.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `gcs.fc_factor`

 * **Description:**Fraction below [gcs.fc\_limit](#gcsfc_limit) which if the recv queue drops below, replication resumes.
* **Dynamic:** Yes
* **Default:** `1.0`

 

---

 #### `gcs.fc_limit`

 * **Description:** If the recv queue exceeds this many writesets, replication is paused. Can increase greatly in master-slave setups. Replication will resume again according to the [gcs.fc\_factor](#gcsfc_factor) setting.
* **Dynamic:** Yes
* **Default:** `16`

 

---

 #### `gcs.fc_master_slave`

 * **Description:** Whether to assume that the cluster only contains one master. Deprecated since Galera 4.10 ([MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10422-release-notes/)) - see [gcs.fc\_single\_primary](#gcsfc_single_primary)
* **Dynamic:** No
* **Default:** `no`

 #### `gcs.fc_single_primary`

 * **Description:** Defines whether there is more than one source of replication. As the number of nodes in the cluster grows, the larger the calculated gcs.fc\_limit gets. At the same time, the number of writes from the nodes increases. When this parameter value is set to NO (multi-primary), the gcs.fc\_limit parameter is dynamically modified to give more margin for each node to be a bit further behind applying writes. The gcs.fc\_limit parameter is modified by the square root of the cluster size, that is, in a four-node cluster it is two times higher than the base value. This is done to compensate for the increasing replication rate noise.
* **Dynamic:** No
* **Default:** `no`

 

---

 #### `gcs.max_packet_size`

 * **Description:** Maximum packet size, after which writesets become fragmented.
* **Dynamic:** No
* **Default:** `64500`

 

---

 #### `gcs.max_throttle`

 * **Description:** How much we can throttle replication rate during state transfer (to avoid running out of memory). Set it to 0.0 if stopping replication is acceptable for the sake of completing state transfer.
* **Dynamic:** No
* **Default:** `0.25`

 

---

 #### `gcs.recv_q_hard_limit`

 * **Description:** Maximum size of the recv queue. If exceeded, the server aborts. Half of available RAM plus swap is a recommended size.
* **Dynamic:** No
* **Default:** LLONG\_MAX

 

---

 #### `gcs.recv_q_soft_limit`

 * **Description:** Fraction of [gcs.recv\_q\_hard\_limit](#gcsrecv_q_hard_limit) after which replication rate is throttled. The rate of throttling increases linearly from zero (the regular, varying rate of replication) at and below `csrecv_q_soft_limit` to one (full throttling) at [gcs.recv\_q\_hard\_limit](#gcsrecv_q_hard_limit)
* **Dynamic:** No
* **Default:** `0.25`

 

---

 #### `gcs.sync_donor`

 * **Description:** Whether or not the rest of the cluster should stay in sync with the donor. If set to `YES` (`NO` is default), if the donor is blocked by state transfer, the whole cluster is also blocked.
* **Dynamic:** No
* **Default:** `no`

 

---

 #### `gmcast.listen_addr`

 * **Description:** Address Galera listens for connections from other nodes. Can be used to override the default port to listen, which is obtained from the connection address.
* **Dynamic:** No
* **Default:** `tcp://0.0.0.0:4567`

 

---

 #### `gmcast.mcast_addr`

 * **Description:** Not set by default, but if set, UDP multicast will be used for replication. Must be identical on all nodes.For example, `gmcast.mcast_addr=239.192.0.11`
* **Dynamic:** No
* **Default:** None

 

---

 #### `gmcast.mcast_ttl`

 * **Description:** Multicast packet TTL (time to live) value.
* **Dynamic:** No
* **Default:** `1`

 

---

 #### `gmcast.peer_timeout`

 * **Description:** Connection timeout for initiating message relaying.
* **Dynamic:** No
* **Default:** `PT3S`

 

---

 #### `gmcast.segment`

 * **Description:** Defines the segment to which the node belongs. By default, all nodes are placed in the same segment (`0`). Usually, you would place all nodes in the same datacenter in the same segment. Galera protocol traffic is only redirected to one node in each segment, and then relayed to other nodes in that same segment, which saves cross-datacenter network traffic at the expense of some extra latency. State transfers are also, preferably but not exclusively, taken from the same segment. If there are no nodes available in the same segment, state transfer will be taken from a node in another segment.
* **Dynamic:** No
* **Default:** `0`
* **Range:** `0` to `255`

 

---

 #### `gmcast.time_wait`

 * **Description:** Waiting time before allowing a peer that was declared outside of the stable view to reconnect.
* **Dynamic:** No
* **Default:** `PT5S`

 

---

 #### `gmcast.version`

 * **Description:** Deprecated option. Gmcast version.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `ist.recv_addr`

 * **Description:** Address for listening for Incremental State Transfer.
* **Dynamic:** No
* **Default:** <address>:<port+1> from [wsrep\_node\_address](../galera-cluster-system-variables/index#wsrep_node_address)

 

---

 #### `ist.recv_bind`

 * **Description:**
* **Dynamic:** No
* **Default:** Empty string
* **Introduced:** [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/), [MariaDB Galera 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/), [MariaDB Galera 5.5.51](https://mariadb.com/kb/en/mariadb-galera-cluster-5551-release-notes/)

 

---

 #### `pc.announce_timeout`

 * **Description:** Period of time for which cluster joining announcements are sent every 1/2 second.
* **Dynamic:** No
* **Default:** `PT3S`

 

---

 #### `pc.checksum`

 * **Description:** For debug purposes, by default `false` (`true` in earlier releases), indicates whether to checksum replicated messages on PC level. Safe to turn off.
* **Dynamic:** No
* **Default:** `false`

 

---

 #### `pc.ignore_quorum`

 * **Description:** Whether to ignore quorum calculations, for example when a master splits from several slaves, it will remain in operation if set to `true` (`false is default`). Use with care however, as in master-slave setups, slaves will not automatically reconnect to the master if set.
* **Dynamic:** Yes
* **Default:** `false`

 

---

 #### `pc.ignore_sb`

 * **Description:** Whether to permit updates to be processed even in the case of split brain (when a node is disconnected from its remaining peers). Safe in master-slave setups, but could lead to data inconsistency in a multi-master setup.
* **Dynamic:** Yes
* **Default:** `false`

 

---

 #### `pc.linger`

 * **Description:** Time that the PC protocol waits for EVS termination.
* **Dynamic:** No
* **Default:** `PT20S`

 

---

 #### `pc.npvo`

 * **Description:** If set to `true` (`false` is default), when there are primary component conficts, the most recent component will override the older.
* **Dynamic:** No
* **Default:** `false`

 

---

 #### `pc.recovery`

 * **Description:** If set to `true` (the default), the Primary Component state is stored on disk and in the case of a full cluster crash (e.g power outages), automatic recovery is then possible. Subsequent graceful full cluster restarts will require explicit bootstrapping for a new Primary Component.
* **Dynamic:** No
* **Default:** `true`

 

---

 #### `pc.version`

 * **Description:** Deprecated option. PC protocol version.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `pc.wait_prim`

 * **Description:** When set to `true`, the default, the node will wait for a primary component for the period of time specified by [pc.wait\_prim\_timeout](#pc.wait_prim_timeout). Used to bring up non-primary components and make them primary using [pc.bootstrap](#pcbootstrap.).
* **Dynamic:** No
* **Default:** `true`

 

---

 #### `pc.wait_prim_timeout`

 * **Description:** Ttime to wait for a primary component. See [pc.wait\_prim](#pcwait_prim).
* **Dynamic:** No
* **Default:** `PT30S`

 

---

 #### `pc.weight`

 * **Description:** Node weight, used for quorum calculation. See the Codership article [Weighted Quorum](https://galeracluster.com/library/documentation/weighted-quorum.html#weighted-quorum).
* **Dynamic:** Yes
* **Default:** `1`

 

---

 #### `protonet.backend`

 * **Description:** Deprecated option. Transport backend to use. Only ASIO is supported currently.
* **Dynamic:** No
* **Default:** `asio`

 

---

 #### `protonet.version`

 * **Description:** Deprecated option. Protonet version.
* **Dynamic:** No
* **Default:** `0`

 

---

 #### `repl.causal_read_timeout`

 * **Description:** Timeout period for causal reads.
* **Dynamic:** Yes
* **Default:** `PT30S`

 

---

 #### `repl.commit_order`

 * **Description:** Whether or not out-of-order committing is permitted, and under what conditions. By default it is not permitted, but setting this can improve parallel performance.
	+ `0` BYPASS: No commit order monitoring is done (useful for measuring the performance penalty).
	+ `1` OOOC: Out-of-order committing is permitted for all transactions.
	+ `2` LOCAL\_OOOC: Out-of-order committing is permitted for local transactions only.
	+ `3` NO\_OOOC: Out-of-order committing is not permitted at all.
* **Dynamic:** No
* **Default:** `3`

 

---

 #### `repl.key_format`

 * **Description:** Format for key replication. Can be one of:
	+ `FLAT8` - shorter key with a higher probability of false positives when matching
	+ `FLAT16` - longer key with a lower probability of false positives when matching
	+ `FLAT8A` - shorter key with a higher probability of false positives when matching, includes annotations for debug purposes
	+ `FLAT16A` - longer key with a lower probability of false positives when matching, includes annotations for debug purposes
* **Dynamic:** Yes
* **Default:** `FLAT8`

 

---

 #### `repl.max_ws_size`

 * **Description:**
* **Dynamic:**
* **Default:** `2147483647`

 

---

 #### `repl.proto_max`

 * **Description:**
* **Dynamic:**
* **Default:** `9`

 

---

 #### `socket.checksum`

 * **Description:** Method used for generating checksum. Note: If Galera 25.2.x and 25.3.x are both being used in the cluster, MariaDB with Galera 25.3.x must be started with `wsrep_provider_options='socket.checksum=1'` in order to make it backward compatible with Galera v2. Galera wsrep providers other than 25.3.x or 25.2.x are not supported.
* **Dynamic:** No
* **Default:** `2`

 

---

 #### `socket.dynamic`

 * **Description:** Allow both encrypted and unencrypted connections between nodes. Typically this should be set to `false` (the default), when set to `true` encrypted connections will still be preferred, but will fall back to unencrypted connections when encryption is not possible, e.g. not enabled on all nodes yet. Needs to be `true` on all nodes when wanting to enable or disable encryption via a rolling restart. As this can't be changed at runtime a rolling restart to enable or disable encryption may need three restarts per node in total: one to enable `socket.dynamic` on each node, one to change the actual encryption settings on each node, and a final round to change `socket.dynamic` back to `false`.
* **Dynamic:** No
* **Default:** `false`
* **Introduced:** [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/), [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `socket.recv_buf_size`

 * **Description:** Size in bytes of the receive buffer used on the network sockets between nodes, passed on to the kernel via the SO\_RCVBUF socket option.
* **Dynamic:** No
* **Default:**
	+ >= [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/): Auto
	+ < [MariaDB 10.3.22](https://mariadb.com/kb/en/mariadb-10322-release-notes/): [MariaDB 10.2.31](https://mariadb.com/kb/en/mariadb-10231-release-notes/), [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10144-release-notes/): `212992`

 

---

 #### `socket.send_buf_size`

 * **Description:** Size in bytes of the send buffer used on the network sockets between nodes, passed on to the kernel via the SO\_SNDBUF socket option.
* **Dynamic:** No
* **Default:**: Auto
* **Introduced:** [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/)

 

---

 #### `socket.ssl`

 * **Description:** Explicitly enables TLS usage by the wsrep Provider.
* **Dynamic:** No
* **Default:** `NO`

 

---

 #### `socket.ssl_ca`

 * **Description:** Path to Certificate Authority (CA) file. Implicitly enables the `[socket.ssl](#socket.ssl)` option.
* **Dynamic:** No

 

---

 #### `socket.ssl_cert`

 * **Description:** Path to TLS certificate. Implicitly enables the `[socket.ssl](#socket.ssl)` option.
* **Dynamic:** No

 

---

 #### `socket.ssl_cipher`

 * **Description:** TLS cipher to use. Implicitly enables the `[socket.ssl](#socket.ssl)` option. Since [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/) defaults to the value of the `[ssl\_cipher](../ssltls-system-variables/index#ssl_cipher)` system variable.
* **Dynamic:** No
* **Default:** system default, before [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/) defaults to `AES128-SHA`.

 

---

 #### `socket.ssl_compression`

 * **Description:** Compression to use on TLS connections. Implicitly enables the `[socket.ssl](#socket.ssl)` option.
* **Dynamic:** No

 

---

 #### `socket.ssl_key`

 * **Description:** Path to TLS key file. Implicitly enables the `[socket.ssl](#socket.ssl)` option.
* **Dynamic:** No

 

---

 #### `socket.ssl_password_file`

 * **Description:** Path to password file to use in TLS connections. Implicitly enables the `[socket.ssl](#socket.ssl)` option.
* **Dynamic:** No

 

---

 See Also
--------

 * [Galera parameters documentation from Codership](https://galeracluster.com/library/documentation/galera-parameters.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wsrep_provider_options/>

Galera Cluster Address
======================

    URL's in [Galera](../galera/index) take a particular format:

 
```
<schema>://<cluster_address>[?option1=value1[&option2=value2]]

```
 Schema
------

 * `gcomm` - This is the option to use for a working implementation.
* `dummy` - Used for running tests and profiling, does not do any actual replication, and all following parameters are ignored.

 Cluster address
---------------

 * The cluster address shouldn't be empty like `gcomm://`. This should never be hardcoded into any configuration files.
* To connect the node to an existing cluster, the cluster address should contain the address of any member of the cluster you want to join.
* The cluster address can also contain a comma-separated list of multiple members of the cluster. It is good practice to list all possible members of the cluster, for example `gcomm:*<node1 name or ip>,<node2 name or ip2>,<node3 name or ip>*`. Alternately if multicast is use put the multicast address instead of the list of nodes. Each member address or multicast address can specify `<node name or ip>:<port>` if a non-default port is used.

 Option list
-----------

 * The [wsrep\_provider\_options](../galera-cluster-system-variables/index#wsrep_provider_options) variable is used to set a [list of options](../wsrep_provider_options/index). These parameters can also be provided (and overridden) as part of the URL. Unlike options provided in a configuration file, they will not endure, and need to be resubmitted with each connection.

 A useful option to set is `pc.wait_prim=no` to ensure the server will start running even if it can't determine a primary node. This is useful if all members go down at the same time.

 Port
----

 By default, gcomm listens on all interfaces. The port is either provided in the cluster address, or will default to 4567 if not set.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-cluster-address/>

Getting Started with MariaDB Galera Cluster
===========================================

    
The most recent release of [MariaDB 10.11](../what-is-mariadb-1011/index) is:  
 **[MariaDB 10.11.4](https://mariadb.com/kb/en/mariadb-10-11-4-release-notes/) Stable (GA)** [DownloadNow](https://mariadb.com/downloads/)  
 *[Alternate download from mariadb.org](https://mariadb.org/download/?tab=mariadb&release=10.11.4&product=mariadb)*

  
The current [versions](../what-is-mariadb-galera-cluster/index#galera-versions) of the Galera wsrep provider library are 26.4.13 for [Galera](../galera/index) 4 and 25.3.37 for [Galera](../galera/index) 3.  
 *For convenience, packages containing these libraries are included in the MariaDB [YUM and APT repositories](https://downloads.mariadb.org/mariadb/repositories/).*

  
Currently, MariaDB Galera Cluster only supports the [InnoDB](../innodb/index) storage engine (although there is experimental support for [MyISAM](../myisam/index) and, from [MariaDB 10.6](../what-is-mariadb-106/index), [Aria](../aria/index)).

 

A great resource for Galera users is the mailing list run by the developers at Codership. It can be found at [Codership on Google Groups](https://groups.google.com/forum/?fromgroups#!forum/codership-team). If you use Galera, then it is recommended you subscribe.

  Galera Cluster Support in MariaDB Server
----------------------------------------

 MariaDB Galera Cluster is powered by:

 * MariaDB Server.
* The [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch for MySQL Server and MariaDB Server developed by [Codership](http://www.codership.com). The patch currently supports only Unix-like operating systems.
* The [Galera wsrep provider library](https://github.com/codership/galera/).

 In [MariaDB 10.1](../what-is-mariadb-101/index) and later, the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch has been merged into MariaDB Server. This means that the functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the [Galera wsrep provider library](https://github.com/codership/galera/) package. The following [Galera](../galera/index) version corresponds to each MariaDB Server version:

 * In [MariaDB 10.4](../what-is-mariadb-104/index) and later, MariaDB Galera Cluster uses [Galera](../galera/index) 4. This means that the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch is version 26 and the [Galera wsrep provider library](https://github.com/codership/galera/) is version 4.
* In [MariaDB 10.3](../what-is-mariadb-103/index) and before, MariaDB Galera Cluster uses [Galera](../galera/index) 3. This means that the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch is version 25 and the [Galera wsrep provider library](https://github.com/codership/galera/) is version 3.

 See [Deciphering Galera Version Numbers](https://mariadb.com/resources/blog/deciphering-galera-version-numbers/) for more information about how to interpret these version numbers.

 See [What is MariaDB Galera Cluster?: Galera Versions](../what-is-mariadb-galera-cluster/index#galera-versions) for more information about which specific [Galera](../galera/index) version is included in each release of MariaDB Server.

 In supported builds, Galera Cluster functionality can be enabled by setting some configuration options that are mentioned below. Galera Cluster functionality is not enabled in a standard MariaDB Server installation unless explicitly enabled with these configuration options.

 Prerequisites
-------------

 ### Swap Size Requirements

 During normal operation a MariaDB Galera node does not consume much more memory than a regular MariaDB server. Additional memory is consumed for the certification index and uncommitted writesets, but normally this should not be noticeable in a typical application. There is one exception though:

 1. **Writeset caching during state transfer.** When a node is receiving a state transfer it cannot process and apply incoming writesets because it has no state to apply them to yet. Depending on a state transfer mechanism (e.g. [mysqldump](../mysqldump/index)) the node that sends the state transfer may not be able to apply writesets as well. Thus they need to cache those writesets for a catch-up phase. Currently the writesets are cached in memory and, if the system runs out of memory either the state transfer will fail or the cluster will block waiting for the state transfer to end.

 To control memory usage for writeset caching, check the [Galera parameters](https://galeracluster.com/library/documentation/galera-parameters.html): `gcs.recv_q_hard_limit`, `gcs.recv_q_soft_limit`, and `gcs.max_throttle`.

 ### Limitations

 Before using MariaDB Galera Cluster, we would recommend reading through the [known limitations](../mariadb-galera-cluster-known-limitations/index), so you can be sure that it is appropriate for your application.

 Installing MariaDB Galera Cluster
---------------------------------

 To use MariaDB Galera Cluster, there are two primary packages that you need to install:

 1. A MariaDB Server version that supports Galera Cluster.

 2. The Galera wsrep provider library.

 As mentioned in the previous section, in [MariaDB 10.1](../what-is-mariadb-101/index) and above, Galera Cluster support is actually included in the standard MariaDB Server packages. That means that installing MariaDB Galera Cluster package is the same as installing standard MariaDB Server package in those versions. However, you will also have to install an additional package to obtain the Galera wsrep provider library.

 Some [SST](../introduction-to-state-snapshot-transfers-ssts/index) methods may also require additional packages to be installed. The `[mariabackup](../mariabackup-sst-method/index)` SST method is generally the best option for large clusters that expect a lot of load.

 ### Installing MariaDB Galera Cluster with a Package Manager

 MariaDB Galera Cluster can be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 #### Installing MariaDB Galera Cluster with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM packages](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. 

 To install MariaDB Galera Cluster with `yum` or `dnf`, follow the instructions at [Installing MariaDB Galera Cluster with yum](../installing-mariadb-with-yum/index#installing-mariadb-galera-cluster-with-yum).

 #### Installing MariaDB Galera Cluster with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB packages](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`.

 To install MariaDB Galera Cluster with `apt-get`, follow the instructions at [Installing MariaDB Galera Cluster with apt-get](../installing-mariadb-deb-files/index#installing-mariadb-galera-cluster-with-apt).

 #### Installing MariaDB Galera Cluster with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM packages](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`.

 To install MariaDB Galera Cluster with `zypper`, follow the instructions at [Installing MariaDB Galera Cluster with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-galera-cluster-with-zypp).

 ### Installing MariaDB Galera Cluster with a Binary Tarball

 To install MariaDB Galera Cluster with a binary tarball, follow the instructions at [Installing MariaDB Binary Tarballs](../installing-mariadb-binary-tarballs/index).

 
**MariaDB Galera Cluster starting with 10.0.24**To make the location of the `libgalera_smm.so` library in binary tarballs more similar to its location in other packages, the library is now found at `lib/galera/libgalera_smm.so` in the binary tarballs, and there is a symbolic link in the `lib` directory that points to it.

 
### Installing MariaDB Galera Cluster from Source

 To install MariaDB Galera Cluster by compiling it from source, you will have to compile both MariaDB Server and the Galera wsrep provider library. For some information on how to do this, see the pages at [Installing Galera From Source](../installing-galera-from-source/index). The pages at [Compiling MariaDB From Source](../compiling-mariadb-from-source/index) and [Galera Cluster Documentation: Building Galera Cluster for MySQL](https://galeracluster.com/library/documentation/install-mysql-src.html#building-galera-cluster-for-mysql) may also be helpful.

 Configuring MariaDB Galera Cluster
----------------------------------

 A number of options need to be set in order for Galera Cluster to work when using MariaDB. See [Configuring MariaDB Galera Cluster](../configuring-mariadb-galera-cluster/index) for more information.

 Bootstrapping a New Cluster
---------------------------

 To first node of a new cluster needs to be bootstrapped by starting [mariadbd](../mariadbd-options/index) on that node with the option `[--wsrep-new-cluster](../mariadbd-options/index#-wsrep-new-cluster)` option. This option tells the node that there is no existing cluster to connect to. The node will create a new UUID to identify the new cluster.

 Do not use the [--wsrep-new-cluster](../mariadbd-options/index#-wsrep-new-cluster) option when connecting to an existing cluster. Restarting the node with this option set will cause the node to create new UUID to identify the cluster again, and the node won't reconnect to the old cluster. See the next section about how to reconnect to an existing cluster.

 For example, if you were manually starting [mariadbd](../mariadbd-options/index) on a node, then you could bootstrap it by executing the following:

 
```
$ mariadbd --wsrep-new-cluster

```

However, keep in mind that most users are not going to be starting [mariadbd](../mariadbd-options/index) manually. Instead, most users will use a [service manager](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) to start [mariadbd](../mariadbd-options/index). See the following sections on how to bootstrap a node with the most common service managers.

 ### Systemd and Bootstrapping

 On operating systems that use [systemd](../systemd/index), a node can be bootstrapped in the following way:

 
```
$ galera_new_cluster

```

This wrapper uses [systemd](../systemd/index) to run [mariadbd](../mariadbd-options/index) with the [--wsrep-new-cluster](../mariadbd-options/index#-wsrep-new-cluster) option.

 If you are using the [systemd](../systemd/index) service that supports the [systemd service's method for interacting with multiple MariaDB Server processes](../systemd/index#interacting-with-multiple-mariadb-server-processes), then you can bootstrap a specific instance by specifying the instance name as a suffix. For example:

 
```
$ galera_new_cluster mariadb@node1

```

Systemd support and the galera\_new\_cluster script were added in [MariaDB 10.1](../what-is-mariadb-101/index).

 ### SysVinit and Bootstrapping

 On operating systems that use [sysVinit](../sysvinit/index), a node can be bootstrapped in the following way:

 
```
$ service mysql bootstrap

```

This runs [mariadbd](../mariadbd-options/index) with the `[--wsrep-new-cluster](../mariadbd-options/index#-wsrep-new-cluster)` option.

 Adding Another Node to a Cluster
--------------------------------

 Once you have a cluster running and you want to add/reconnect another node to it, you must supply an address of one or more of the existing cluster members in the `[wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)` option. For example, if the first node of the cluster has the address 192.168.0.1, then you could add a second node to the cluster by setting the following option in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
wsrep_cluster_address=gcomm://192.168.0.1  # DNS names work as well, IP is preferred for performance

```

The new node only needs to connect to one of the existing cluster nodes. Once it connects to one of the existing cluster nodes, it will be able to see all of the nodes in the cluster. However, it is generally better to list all nodes of the cluster in `[wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)`, so that any node can join a cluster by connecting to any of the other cluster nodes, even if one or more of the cluster nodes are down. It is even OK to list a node's own IP address in `[wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)`, since Galera Cluster is smart enough to ignore it. 

 Once all members agree on the membership, the cluster's state will be exchanged. If the new node's state is different from that of the cluster, then it will request an IST or [SST](../introduction-to-state-snapshot-transfers-ssts/index) to make itself consistent with the other nodes.

 Restarting the Cluster
----------------------

 If you shut down all nodes at the same time, then you have effectively terminated the cluster. Of course, the cluster's data still exists, but the running cluster no longer exists. When this happens, you'll need to bootstrap the cluster again.

 If the cluster is not bootstrapped and [mariadbd](../mariadbd-options/index) on the first node is just [started normally](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index), then the node willl try to connect to at least one of the nodes listed in the `[wsrep\_cluster\_address](../galera-cluster-system-variables/index#wsrep_cluster_address)` option. If no nodes are currently running, then this will fail. Bootstrapping the first node solves this problem.

 ### Determining the Most Advanced Node

 In some cases Galera will refuse to bootstrap a node if it detects that it might not be the most advanced node in the cluster. Galera makes this determination if the node was not the last one in the cluster to be shut down or if the node crashed. In those cases, manual intervention is needed.

 If you know for sure which node is the most advanced you can edit the `grastate.dat` file in the `[datadir](../server-system-variables/index#datadir)`. You can set `safe_to_bootstrap=1` on the most advanced node. 

 You can determine which node is the most advanced by checking `grastate.dat` on each node and looking for the node with the highest `seqno`. If the node crashed and `seqno=-1`, then you can find the most advanced node by recovering the `seqno` on each node with the `[wsrep\_recover](../galera-cluster-system-variables/index#wsrep_recover)` option. For example:

 
```
$ mariadbd --wsrep_recover

```

#### Systemd and Galera Recovery

 On operating systems that use `[systemd](../systemd/index)`, the position of a node can be recovered by running the `galera_recovery` script. For example:

 
```
$ galera_recovery

```

If you are using the `[systemd](../systemd/index)` service that supports the [systemd service's method for interacting with multiple MariaDB Server processes](../systemd/index#interacting-with-multiple-mariadb-server-processes), then you can recover the position of a specific instance by specifying the instance name as a suffix. For example:

 
```
$ galera_recovery mariadb@node1

```

The `galera_recovery` script recovers the position of a node by running [mariadbd](../mariadbd-options/index) with the `[wsrep\_recover](../galera-cluster-system-variables/index#wsrep_recover)` option.

 When the `galera_recovery` script runs [mariadbd](../mariadbd-options/index), it does not write to the [error log](../error-log/index). Instead, it redirects [mariadbd](../mariadbd-options/index) log output to a file named with the format `/tmp/wsrep_recovery.XXXXXX`, where `XXXXXX` is replaced with random characters.

 When Galera is enabled, MariaDB's [systemd](../systemd/index) service automatically runs the `galera_recovery` script prior to starting MariaDB, so that MariaDB starts with the proper Galera position.

 Support for [systemd](../systemd/index) and the `galera_recovery` script were added in [MariaDB 10.1](../what-is-mariadb-101/index).

 State Snapshot Transfers (SSTs)
-------------------------------

 In a State Snapshot Transfer (SST), the cluster provisions nodes by transferring a full data copy from one node to another. When a new node joins the cluster, the new node initiates a State Snapshot Transfer to synchronize its data with a node that is already part of the cluster.

 See [Introduction to State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) for more information.

 Incremental State Transfers (ISTs)
----------------------------------

 In an Incremental State Transfer (SST), the cluster provisions nodes by transferring a node's missing writesets from one node to another. When a new node joins the cluster, the new node initiates a Incremental State Transfer to synchronize its data with a node that is already part of the cluster.

 If a node has only been out of a cluster for a little while, then an IST is generally faster than an SST.

 Data at Rest Encryption
-----------------------

 In [MariaDB 10.1](../what-is-mariadb-101/index) and above, MariaDB Galera Cluster supports [Data at Rest Encryption](../data-at-rest-encryption/index). See [SSTs and Data at Rest Encryption](../introduction-to-state-snapshot-transfers-ssts/index#ssts-and-data-at-rest-encryption) for some disclaimers on how SSTs are affected when encryption is configured.

 Some data still cannot be encrypted:

 * The disk-based [Galera gcache](https://galeracluster.com/library/documentation/state-transfer.html#write-set-cache-gcache) is not encrypted ([MDEV-8072](https://jira.mariadb.org/browse/MDEV-8072)).

 Monitoring
----------

 ### Status Variables

 [Galera Cluster's status variables](../mariadb-galera-cluster-status-variables/index) can be queried with the standard `[SHOW STATUS](../show-status/index)` command. For example:

 
```
SHOW GLOBAL STATUS LIKE 'wsrep_%';

```

### Cluster Change Notifications

 The cluster nodes can be configured to invoke a command when cluster membership or node status changes. This mechanism can also be used to communicate the event to some external monitoring agent. This is configured by setting `[wsrep\_notify\_cmd](../galera-cluster-system-variables/index#wsrep_notify_cmd)`. See [Galera Cluster documentation: Notification Command](https://galeracluster.com/library/documentation/notification-cmd.html) for more information.

 See Also
--------

 * [What is MariaDB Galera Cluster?](../what-is-mariadb-galera-cluster/index)
* [About Galera Replication](../about-galera-replication/index)
* [Galera Use Cases](../galera-use-cases/index)
* [Codership on Google Groups](https://groups.google.com/forum/?fromgroups#!forum/codership-team)
* [Galera Cluster documentation](https://galeracluster.com/library/documentation/)
* [Galera Cluster documentation: Notification Command](http://galeracluster.com/documentation-webpages/notificationcmd.html)
* [Introducing the “Safe-To-Bootstrap” feature in Galera Cluster](http://galeracluster.com/2016/11/introducing-the-safe-to-bootstrap-feature-in-galera-cluster/)
* [Github - galera](https://github.com/codership/galera/)
* [Github - mysql-wsrep](https://github.com/codership/mysql-wsrep/)

 Footnotes
---------

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/getting-started-with-mariadb-galera-cluster/>

Building the Galera wsrep Package on Fedora
===========================================

    The instructions on this page were used to create the *galera* package on the Fedora Linux distribution. This package contains the wsrep provider for [MariaDB Galera Cluster](../galera/index).   
  


 The following table lists each version of the [Galera](../galera/index) 4 wsrep provider, and it lists which version of MariaDB each one was first released in. If you would like to install [Galera](../galera/index) 4 using [yum](../yum/index), [apt](../installing-mariadb-deb-files/index#installing-mariadb-with-apt), or [zypper](../installing-mariadb-with-zypper/index), then the package is called `galera-4`.

 


| Galera Version | Released in MariaDB Version |
| --- | --- |
| **26.4.14** | [10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), [10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [10.7.8](https://mariadb.com/kb/en/mariadb-10-7-8-release-notes/), [10.6.12](https://mariadb.com/kb/en/mariadb-10-6-12-release-notes/), [10.5.19](https://mariadb.com/kb/en/mariadb-10-5-19-release-notes/), [10.4.28](https://mariadb.com/kb/en/mariadb-10-4-28-release-notes/) |
| **26.4.13** | [10.10.2](https://mariadb.com/kb/en/mariadb-10-10-2-release-notes/), [10.9.4](https://mariadb.com/kb/en/mariadb-10-9-4-release-notes/), [10.8.6](https://mariadb.com/kb/en/mariadb-10-8-6-release-notes/), [10.7.7](https://mariadb.com/kb/en/mariadb-10-7-7-release-notes/), [10.6.11](https://mariadb.com/kb/en/mariadb-10-6-11-release-notes/), [10.5.18](https://mariadb.com/kb/en/mariadb-10-5-18-release-notes/), [10.4.27](https://mariadb.com/kb/en/mariadb-10-4-27-release-notes/) |
| **26.4.12** | [10.10.1](https://mariadb.com/kb/en/mariadb-10-10-1-release-notes/), [10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/) |
| **26.4.11** | [10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/) |
| **26.4.9** | [10.6.4](https://mariadb.com/kb/en/mariadb-10-6-4-release-notes/), [10.5.12](https://mariadb.com/kb/en/mariadb-10-5-12-release-notes/), [10.4.21](https://mariadb.com/kb/en/mariadb-10-4-21-release-notes/) |
| **26.4.8** | [10.6.1](https://mariadb.com/kb/en/mariadb-10-6-1-release-notes/), [10.5.10](https://mariadb.com/kb/en/mariadb-10-5-10-release-notes/), [10.4.19](https://mariadb.com/kb/en/mariadb-10-4-19-release-notes/) |
| **26.4.7** | [10.5.9](https://mariadb.com/kb/en/mariadb-10-5-9-release-notes/), [10.4.18](https://mariadb.com/kb/en/mariadb-10-4-18-release-notes/) |
| **26.4.6** | [10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/) |
| **26.4.5** | [10.5.4](https://mariadb.com/kb/en/mariadb-10-5-4-release-notes/), [10.4.14](https://mariadb.com/kb/en/mariadb-10-4-14-release-notes/) |
| **26.4.4** | [10.5.1](https://mariadb.com/kb/en/mariadb-10-5-1-release-notes/), [10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/) |
| **26.4.3** | [10.5.0](https://mariadb.com/kb/en/mariadb-10-5-0-release-notes/), [10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/) |
| **26.4.2** | [10.4.4](https://mariadb.com/kb/en/mariadb-10-4-4-release-notes/) |
| **26.4.1** | [10.4.3](https://mariadb.com/kb/en/mariadb-10-4-3-release-notes/) |
| **26.4.0** | [10.4.2](https://mariadb.com/kb/en/mariadb-10-4-2-release-notes/) |

  The following table lists each version of the [Galera](../galera/index) 3 wsrep provider, and it lists which version of MariaDB each one was first released in. If you would like to install [Galera](../galera/index) 3 using [yum](../yum/index), [apt](../installing-mariadb-deb-files/index#installing-mariadb-with-apt), or [zypper](../installing-mariadb-with-zypper/index), then the package is called `galera`.

 


| Galera Version | Released in MariaDB Version |
| --- | --- |
| **25.3.37** | [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10336-release-notes/) |
| **25.3.35** | [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10333-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/) |
| **25.3.34** | [MariaDB 10.3.31](https://mariadb.com/kb/en/mariadb-10331-release-notes/), [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10240-release-notes/) |
| **25.3.33** | [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/) |
| **25.3.32** | [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/) |
| **25.3.31** | [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10148-release-notes/) |
| **25.3.30** | [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/) |
| **25.3.29** | [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/) |
| **25.3.28** | [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10228-release-notes/), [MariaDB 10.1.42](https://mariadb.com/kb/en/mariadb-10142-release-notes/) |
| **25.3.27** | [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/), [MariaDB 10.2.27](https://mariadb.com/kb/en/mariadb-10227-release-notes/) |
| **25.3.26** | [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/) |
| **25.3.25** | [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/), [MariaDB 10.2.20](https://mariadb.com/kb/en/mariadb-10220-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB Galera Cluster 10.0.38](https://mariadb.com/kb/en/mariadb-galera-cluster-10038-release-notes/), [MariaDB Galera Cluster 5.5.63](https://mariadb.com/kb/en/mariadb-galera-cluster-5563-release-notes/) |
| **25.3.24** | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10137-release-notes/), [MariaDB Galera Cluster 10.0.37](https://mariadb.com/kb/en/mariadb-galera-cluster-10037-release-notes/), [MariaDB Galera Cluster 5.5.62](https://mariadb.com/kb/en/mariadb-galera-cluster-5562-release-notes/) |
| **25.3.23** | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/), [MariaDB 10.1.32](https://mariadb.com/kb/en/mariadb-10132-release-notes/), [MariaDB Galera Cluster 10.0.35](https://mariadb.com/kb/en/mariadb-galera-cluster-10035-release-notes/), [MariaDB Galera Cluster 5.5.60](https://mariadb.com/kb/en/mariadb-galera-cluster-5560-release-notes/) |
| **25.3.22** | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/), [MariaDB Galera Cluster 10.0.33](https://mariadb.com/kb/en/mariadb-galera-cluster-10033-release-notes/), [MariaDB Galera Cluster 5.5.59](https://mariadb.com/kb/en/mariadb-galera-cluster-5559-release-notes/) |
| **25.3.21** | N/A |
| **25.3.20** | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/), [MariaDB Galera Cluster 10.0.31](https://mariadb.com/kb/en/mariadb-galera-cluster-10031-release-notes/), [MariaDB Galera Cluster 5.5.56](https://mariadb.com/kb/en/mariadb-galera-cluster-5556-release-notes/) |
| **25.3.19** | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/), [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/), [MariaDB Galera Cluster 10.0.29](https://mariadb.com/kb/en/mariadb-galera-cluster-10029-release-notes/), [MariaDB Galera Cluster 5.5.54](https://mariadb.com/kb/en/mariadb-galera-cluster-5554-release-notes/) |
| **25.3.18** | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/), [MariaDB Galera Cluster 10.0.28](https://mariadb.com/kb/en/mariadb-galera-cluster-10028-release-notes/), [MariaDB Galera Cluster 5.5.53](https://mariadb.com/kb/en/mariadb-galera-cluster-5553-release-notes/) |
| **25.3.17** | [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/), [MariaDB Galera Cluster 10.0.27](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-release-notes/), [MariaDB Galera Cluster 5.5.51](https://mariadb.com/kb/en/mariadb-galera-cluster-5551-release-notes/) |
| **25.3.16** | N/A |
| **25.3.15** | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/), [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), [MariaDB Galera Cluster 10.0.25](https://mariadb.com/kb/en/mariadb-galera-cluster-10025-release-notes/), [MariaDB Galera Cluster 5.5.49](https://mariadb.com/kb/en/mariadb-galera-cluster-5549-release-notes/) |
| **25.3.14** | [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10112-release-notes/), [MariaDB Galera Cluster 10.0.24](https://mariadb.com/kb/en/mariadb-galera-cluster-10024-release-notes/), [MariaDB Galera Cluster 5.5.48](https://mariadb.com/kb/en/mariadb-galera-cluster-5548-release-notes/) |
| **25.3.12** | [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |
| **25.3.11** | N/A |
| **25.3.10** | N/A |
| **25.3.9** | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/), [MariaDB Galera Cluster 10.0.17](https://mariadb.com/kb/en/mariadb-galera-cluster-10017-release-notes/), [MariaDB Galera Cluster 5.5.42](https://mariadb.com/kb/en/mariadb-galera-cluster-5542-release-notes/) |
| **25.3.8** | N/A |
| **25.3.7** | N/A |
| **25.3.6** | N/A |
| **25.3.5** | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), [MariaDB Galera Cluster 10.0.10](https://mariadb.com/kb/en/mariadb-galera-cluster-10010-release-notes/), [MariaDB Galera Cluster 5.5.37](https://mariadb.com/kb/en/mariadb-galera-cluster-5537-release-notes/) |
| **25.3.4** | N/A |
| **25.3.3** | N/A |
| **25.3.2** | [MariaDB Galera Cluster 10.0.7](https://mariadb.com/kb/en/mariadb-galera-cluster-1007-release-notes/), [MariaDB Galera Cluster 5.5.35](https://mariadb.com/kb/en/mariadb-galera-cluster-5535-release-notes/) |

  The following table lists each version of the [Galera](../galera/index) 2 wsrep provider, and it lists which version of MariaDB each one was first released in. 

 


| Galera Version | Released in MariaDB Galera Cluster Version |
| --- | --- |
| **25.2.9** | [10.0.10](https://mariadb.com/kb/en/mariadb-galera-cluster-10010-release-notes/), [5.5.37](https://mariadb.com/kb/en/mariadb-galera-cluster-5537-release-notes/) |
| **25.2.8** | [10.0.7](https://mariadb.com/kb/en/mariadb-galera-cluster-1007-release-notes/), [5.5.35](https://mariadb.com/kb/en/mariadb-galera-cluster-5535-release-notes/) |
| **23.2.7** | [5.5.34](https://mariadb.com/kb/en/mariadb-galera-cluster-5534-release-notes/) |

 
For convenience, a *galera* package containing the **preferred** wsrep provider is included in the MariaDB [YUM and APT repositories](https://downloads.mariadb.org/mariadb/repositories/) (the preferred versions are **bolded** in the table above).

 See also [Deciphering Galera Version Numbers](https://mariadb.com/blog/deciphering-galera-version-numbers).

 1. Install the prerequisites:

 
```
sudo yum update
sudo yum -y install boost-devel check-devel glibc-devel openssl-devel scons

```

2. Clone [galera.git](https://github.com/mariadb/galera) from [github.com/mariadb](https://github.com/mariadb) and checkout mariadb-3.x banch:

 
```
git init repo
cd repo
git clone -b mariadb-3.x https://github.com/MariaDB/galera.git

```

3. Build the packages by executing `build.sh` under scripts/ directory with `-p` switch:

 
```
cd galera
./scripts/build.sh -p

```

When finished, you will have an RPM package containing galera library, arbitrator and related files in the current directory. Note: The same set of instructions can be applied to other RPM based platforms to generate galera package.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-the-galera-wsrep-package-on-fedora/>

Galera Load Balancer
====================

    Galera Load Balancer is a simple Load Balancer specifically designed for [Galera Cluster](../galera/index). Like Galera, it only runs on Linux. Galera Load Balancer is developed and mantained by Codership. Documentation is available [on fromdual.com](http://www.fromdual.com/galera-load-balancer-documentation).

 Galera Load Balancer is inspired by pen, which is a generic TCP load balancer. However, since pen is a generic TCP connections load balancer, the techniques it uses are not well-suited to the particular use case of database servers. Galera Load Balancer is optimized for this type of workload.

 Several balancing policies are supported. Each node can be assigned a different weight. Nodes with a higher weight are preferred. Depending on the selected policy, other nodes can even be ignored, until the preferred nodes crash.

 A lightweight daemon called glbd receives the connections from clients and it redirects them to nodes. No specific client exists for this demo: a generic TCP client, like nc, can be used to send administrative commands and read the usage statistics.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/galera-load-balancer/>

MERGE
=====

    Description
-----------

 The MERGE storage engine, also known as the MRG\_MyISAM engine, is a collection of identical [MyISAM](../myisam/index) tables that can be used as one. "Identical" means that all tables have identical column and index information. You cannot merge MyISAM tables in which the columns are listed in a different order, do not have exactly the same columns, or have the indexes in different order. However, any or all of the MyISAM tables can be compressed with [myisampack](../myisampack/index). Columns names and indexes names can be different, as long as data types and NULL/NOT NULL clauses are the same. Differences in table options such as AVG\_ROW\_LENGTH, MAX\_ROWS, or PACK\_KEYS do not matter.

 Each index in a MERGE table must match an index in underlying MyISAM tables, but the opposite is not true. Also, a MERGE table cannot have a PRIMARY KEY or UNIQUE indexes, because it cannot enforce uniqueness over all underlying tables.

 The following options are meaningful for MERGE tables:

 * `UNION`. This option specifies the list of the underlying MyISAM tables. The list is enclosed between parentheses and separated with commas.
* `INSERT_METHOD`. This options specifies whether, and how, INSERTs are allowed for the table. Allowed values are: `NO` (INSERTs are not allowed), `FIRST` (new rows will be written into the first table specified in the `UNION` list), `LAST` (new rows will be written into the last table specified in the `UNION` list). The default value is `NO`.

 If you define a MERGE table with a definition which is different from the underlying MyISAM tables, or one of the underlying tables is not MyISAM, the CREATE TABLE statement will not return any error. But any statement which involves the table will produce an error like the following:

 
```
ERROR 1168 (HY000): Unable to open underlying table which is differently defined 
  or of non-MyISAM type or doesn't exist

```

A `[CHECK TABLE](../check-table/index)` will show more information about the problem.

 The error is also produced if the table is properly define, but an underlying table's definition changes at some point in time.

 If you try to insert a new row into a MERGE table with INSERT\_METHOD=NO, you will get an error like the following:

 
```
ERROR 1036 (HY000): Table 'tbl_name' is read only

```

It is possible to build a MERGE table on MyISAM tables which have one or more [virtual columns](../virtual-columns/index). MERGE itself does not support virtual columns, thus such columns will be seen as regular columns. The data types and sizes will still need to be identical, and they cannot be NOT NULL.

 Examples
--------

 
```
CREATE TABLE t1 (
    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    message CHAR(20)) ENGINE=MyISAM;

CREATE TABLE t2 (
    a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    message CHAR(20)) ENGINE=MyISAM;


INSERT INTO t1 (message) VALUES ('Testing'),('table'),('t1');

INSERT INTO t2 (message) VALUES ('Testing'),('table'),('t2');

CREATE TABLE total (
    a INT NOT NULL AUTO_INCREMENT,
    message CHAR(20), INDEX(a))
    ENGINE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;

SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+

```

In the following example, we'll create three MyISAM tables, and then a MERGE table on them. However, one of them uses a different data type for the column b, so a SELECT will produce an error:

 
```
CREATE TABLE t1 (
  a INT,
  b INT
) ENGINE = MyISAM;

CREATE TABLE t2 (
  a INT,
  b INT
) ENGINE = MyISAM;

CREATE TABLE t3 (
  a INT,
  b TINYINT
) ENGINE = MyISAM;

CREATE TABLE t_mrg (
  a INT,
  b INT
) ENGINE = MERGE,UNION=(t1,t2,t3);

SELECT * FROM t_mrg;
ERROR 1168 (HY000): Unable to open underlying table which is differently defined
 or of non-MyISAM type or doesn't exist

```

To find out what's wrong, we'll use a CHECK TABLE:

 
```
CHECK TABLE t_mrg\G
*************************** 1. row ***************************
   Table: test.t_mrg
      Op: check
Msg_type: Error
Msg_text: Table 'test.t3' is differently defined or of non-MyISAM type or doesn't exist
*************************** 2. row ***************************
   Table: test.t_mrg
      Op: check
Msg_type: Error
Msg_text: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
*************************** 3. row ***************************
   Table: test.t_mrg
      Op: check
Msg_type: error
Msg_text: Corrupt

```

Now, we know that the problem is in `t3`'s definition.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/merge/>

Aria
=====

   Information about the Aria storage engine. From [MariaDB 10.4](../what-is-mariadb-104/index), [system tables](../system-tables/index) use the Aria storage engine.

  

| Title | Description |
| --- | --- |
|  [Aria Storage Engine](../aria-storage-engine/index) |  The Aria storage engine is compiled-in by default and is considered as an upgrade to MyISAM.  |
|  [Aria Clients and Utilities](../aria-clients-and-utilities/index) |  Clients and utilities for working with Aria tables  |
|  [Aria FAQ](../aria-faq/index) |  Frequently-asked questions about the Aria storage engine.  |
|  [Aria Storage Formats](../aria-storage-formats/index) |  Table storage formats in Aria - PAGE, FIXED and DYNAMIC  |
|  [Aria Status Variables](../aria-status-variables/index) |  Aria-related server status variables.  |
|  [Aria System Variables](../aria-system-variables/index) |  Aria-related system variables.  |
|  [Aria Group Commit](../aria-group-commit/index) |  Aria group commits for speeding up multi-user inserts  |
|  [Benchmarking Aria](../benchmarking-aria/index) |  Aria benchmarks  |
|  [Aria Two-step Deadlock Detection](../aria-two-step-deadlock-detection/index) |  How Aria detects and deals with deadlocks  |
|  [Aria Encryption Overview](../aria-encryption-overview/index) |  Data-at-rest encryption for user-created tables and internal on-disk tempor...  |
|  [The Aria Name](../the-aria-name/index) |  How Aria got its name.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria/>

NoSQL
======

   MariaDB supports a lot of commands and interfaces that are closer to NoSQL than to SQL.

  

| Title | Description |
| --- | --- |
|  [CONNECT](../connect/index) |  The CONNECT storage engine enables MariaDB to access external local or remote data.  |
|  [HANDLER](../handler/index) |  Direct access to reading rows from the storage engine.  |
|  [HandlerSocket](../handlersocket/index) |  A NoSQL plugin giving you direct access to InnoDB and SPIDER.  |
|  [Dynamic Columns](../dynamic-columns/index) |  Dynamic columns allow one to store different sets of columns for each row in a table  |
|  [Dynamic Columns from MariaDB 10](../dynamic-columns-from-mariadb-10/index) |  Improvements to Dynamic Columns from MariaDB 10.  |
|  [Dynamic Column API](../dynamic-column-api/index) |  Client-side API for reading and writing Dynamic Columns blobs  |
|  [Dynamic Columns API](../dynamic-columns-api/index) |  MariaDB 10.0 API for reading and writing dynamic-columns blobs  |
|  [JSON Functions](../json-functions/index) |  Built-in functions related to JSON.  |
|  [LOAD\_FILE](../load_file/index) |  Returns file contents as a string.  |
|  [Cassandra Storage Engine](../cassandra/index) |  A storage engine interface to Cassandra.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nosql/>

SQL Language Structure
=======================

   SQL language structure rules.

  

| Title | Description |
| --- | --- |
|  [Identifier Names](../identifier-names/index) |  Naming rules for identifiers.  |
|  [Identifier Case-sensitivity](../identifier-case-sensitivity/index) |  Whether objects are case-sensitive or not is partly determined by the under...  |
|  [Binary Literals](../binary-literals/index) |  Binary literals can be written in one of the following formats.  |
|  [Boolean Literals](../sql-language-structure-boolean-literals/index) |  True and false.  |
|  [Date and Time Literals](../date-and-time-literals/index) |  Literals regarding date and time.  |
|  [Hexadecimal Literals](../hexadecimal-literals/index) |  Hexadecimal literals can be written using any of the following syntaxes  |
|  [Identifier Qualifiers](../identifier-qualifiers/index) |  How to reference an object and its context in an SQL statement.  |
|  [Identifier to File Name Mapping](../identifier-to-file-name-mapping/index) |  Some identifiers map to a file name on the filesystem. Databases each have ...  |
|  [MariaDB Error Codes](../mariadb-error-codes/index) |  MariaDB error codes reference list.  |
|  [Numeric Literals](../numeric-iterals/index) |  Numeric literals are written as a sequence of digits from 0 to 9  |
|  [Reserved Words](../reserved-words/index) |  List of reserved words in MariaDB.  |
|  [SQLSTATE](../sqlstate/index) |  A string which identifies a condition's class and subclass  |
|  [String Literals](../string-literals/index) |  Strings are sequences of characters and are enclosed with quotes.  |
|  [Table Value Constructors](../table-value-constructors/index) |  Documents adding arbitrary values to the result-set.  |
|  [User-Defined Variables](../user-defined-variables/index) |  Variables which exist within a session.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-language-structure/>

CSV
====

   The CSV storage engine

  

| Title | Description |
| --- | --- |
|  [CSV Overview](../csv-overview/index) |  Used to read and append to files stored in CSV (comma-separated-values) format.  |
|  [Checking and Repairing CSV Tables](../checking-and-repairing-csv-tables/index) |  CSV tables support the CHECK TABLE and REPAIR TABLE statements.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/csv/>

Geographic & Geometric Features
================================

   MariaDB supports spatial extensions that enable the creation, storage and analysis of geographic features. These can be used in the [Aria](../aria/index), [MyISAM](../myisam/index), [InnoDB/XtraDB](../innodb/index) and [ARCHIVE](../archive/index) engines in MariaDB.

 [Partitioned tables](../managing-mariadb-partitioning/index) do not support geometric types.

  

| Title | Description |
| --- | --- |
|  [GIS Resources](../gis-resources/index) |  Resources for those interested in GIS  |
|  [GIS features in 5.3.3](../gis-features-in-533/index) |  Basic information about the existing spatial features can be found in the G...  |
|  [Geometry Types](../geometry-types/index) |  Supported geometry types.  |
|  [Geometry Hierarchy](../geometry-hierarchy/index) |  The base Geometry class has subclasses for Point, Curve, Surface and GeometryCollection  |
|  [Geometry Constructors](../geometry-constructors/index) |  Geometry constructors  |
|  [Geometry Properties](../geometry-properties/index) |  Geometry properties  |
|  [Geometry Relations](../geometry-relations/index) |  Geometry relations  |
|  [LineString Properties](../linestring-properties/index) |  LineString properties  |
|  [MBR (Minimum Bounding Rectangle)](../mbr-minimum-bounding-rectangle/index) |  |
|  [Point Properties](../point-properties/index) |  Point properties  |
|  [Polygon Properties](../polygon-properties/index) |  Polygon properties  |
|  [WKB](../wkb/index) |  Well-Known Binary format for geometric data  |
|  [WKT](../wkt/index) |  Well-Known Text geometry representation  |
|  [MySQL/MariaDB Spatial Support Matrix](../mysqlmariadb-spatial-support-matrix/index) |  Table comparing when different spatial features were introduced into MySQL and MariaDB  |
|  [SPATIAL INDEX](../spatial-index/index) |  An index type used for geometric columns.  |
|  [MariaDB Plans - GIS](../mariadb-plans-gis/index) |  Old GIS plans  |
|  [The maria/5.3-gis tree on Launchpad.](../the-maria53-gis-tree-on-launchpad/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [GeoJSON](../geojson/index) |  GeoJSON functions  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geographic-geometric-features/>

InnoDB
=======

   InnoDB is a general-purpose storage engine, and the default in MariaDB.

  

| Title | Description |
| --- | --- |
|  [InnoDB Versions](../innodb-versions/index) |  From MariaDB 10.2, InnoDB is the default storage engine.  |
|  [InnoDB Limitations](../innodb-limitations/index) |  The InnoDB storage engine has the following limitations.  |
|  [InnoDB Troubleshooting](../innodb-troubleshooting/index) |  Guidelines when troubleshooting problems with InnoDB .  |
|  [InnoDB System Variables](../innodb-system-variables/index) |  List and description of InnoDB-related server system variables.  |
|  [InnoDB Server Status Variables](../innodb-status-variables/index) |  List and description of InnoDB status variables.  |
|  [AUTO\_INCREMENT Handling in InnoDB](../auto_increment-handling-in-innodb/index) |  AUTO\_INCREMENT handling in InnoDB and the lock modes.  |
|  [InnoDB Buffer Pool](../innodb-buffer-pool/index) |  The most important memory buffer used by InnoDB.  |
|  [InnoDB Change Buffering](../innodb-change-buffering/index) |  Buffering INSERT, UPDATE and DELETE statements for greater efficiency.  |
|  [InnoDB Doublewrite Buffer](../innodb-doublewrite-buffer/index) |  Buffer used for recovering from half-written pages.  |
|  [InnoDB Tablespaces](../innodb-tablespaces/index) |  Information on tablespaces in InnoDB, including an overview, system tablesp...  |
|  [InnoDB File Format](../innodb-file-format/index) |  Description of the file formats supported by InnoDB.  |
|  [InnoDB Row Formats](../innodb-row-formats/index) |  InnoDB's row formats are REDUNDANT, COMPACT, DYNAMIC, and COMPRESSED.  |
|  [InnoDB Strict Mode](../innodb-strict-mode/index) |  InnoD strict mode makes InnoDB more reliable.  |
|  [InnoDB Redo Log](../innodb-redo-log/index) |  The redo log is used by InnoDB during crash recovery.  |
|  [InnoDB Undo Log](../innodb-undo-log/index) |  InnoDB Undo log.  |
|  [InnoDB Page Flushing](../innodb-page-flushing/index) |  Configuring when and how InnoDB flushes dirty pages to disk.  |
|  [InnoDB Purge](../innodb-purge/index) |  Purge process to remove old versions of a row from the undo log.  |
|  [Information Schema InnoDB Tables](../information-schema-innodb-tables/index) |  All InnoDB-specific Information Schema tables.  |
|  [InnoDB Online DDL](../innodb-online-ddl/index) |  InnoDB tables support online DDL in certain circumstances.  |
|  [Binary Log Group Commit and InnoDB Flushing Performance](../binary-log-group-commit-and-innodb-flushing-performance/index) |  Improvement for group commit for InnoDB transactions with the binary log enabled.  |
|  [InnoDB Page Compression](../innodb-page-compression/index) |  InnoDB page compression, which is more sophisticated than the COMPRESSED row format.  |
|  [InnoDB Data Scrubbing](../innodb-data-scrubbing/index) |  Ensuring data is completely removed when deleted.  |
|  [InnoDB Lock Modes](../innodb-lock-modes/index) |  InnoDB supports a number of lock modes to ensure that concurrent write operations never collide.  |
|  [InnoDB Monitors](../innodb-monitors/index) |  Standard Monitor, Lock Monitor, Tablespace Monitor and the Table Monitor.  |
|  [InnoDB Encryption Overview](../innodb-encryption-overview/index) |  Data-at-rest encryption for tables that use the InnoDB storage engine.  |
|  [InnoDB - Unmaintained](../innodb-unmaintained/index) |  Articles that apply only to old, unmaintained versions of MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb/>

Sequences
==========

   
This section is about sequence objects. For details about the storage engine, see [Sequence Storage Engine](../sequence-storage-engine/index).

 
A sequence is an object that generates a sequence of numeric values, as specified by the [CREATE SEQUENCE](../create-sequence/index) statement. Sequences are an alternative to [AUTO\_INCREMENT](../auto_increment/index) when you want more control over how sequence numbers are generated. 

 Since a `SEQUENCE` caches values, it can sometimes be faster. Also, you can access the last value generated by all used sequences; it's not subjected to limitations of [LAST\_INSERT\_ID( )](../last_insert_id/index).

 See also [Sequence Storage Engine](../sequence-storage-engine/index).

  

| Title | Description |
| --- | --- |
|  [Sequence Overview](../sequence-overview/index) |  Object that generates a sequence of numeric values.  |
|  [CREATE SEQUENCE](../create-sequence/index) |  Creates a sequence that generates new values when called with NEXT VALUE FOR.  |
|  [SHOW CREATE SEQUENCE](../show-create-sequence/index) |  Shows the CREATE SEQUENCE statement that created the sequence.  |
|  [ALTER SEQUENCE](../alter-sequence/index) |  Change options for a SEQUENCE.  |
|  [DROP SEQUENCE](../drop-sequence/index) |  Deleting a SEQUENCE.  |
|  [SEQUENCE Functions](../sequence-functions/index) |  Functions that can be used on SEQUENCEs.  |
|  [SHOW TABLES](../show-tables/index) |  List of non-temporary tables, views or sequences.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sequences/>

aria\_pack
==========

     aria\_pack is a tool for compressing [Aria](../aria/index) tables. The resulting table are read-only, and usually about 40% to 70% smaller.

 aria\_pack is run as follows

 
```
aria_pack [options] file_name [file_name2...]

```

The file name is the .MAI index file. The extension can be omitted, although keeping it permits wildcards, such as 

 
```
aria_pack *.MAI

```

to compress all the files.

 aria\_pack compresses each column separately, and, when the resulting data is read, only the individual rows and columns required need to be decompressed, allowing for quicker reading.

 Once a table has been packed, use [aria\_chk -rq](../aria_chk/index) (the quick and recover options) to rebuild its indexes.

 Options
-------

 The following variables can be set while passed as commandline options to aria\_pack, or set in the [ariapack] section in your [my.cnf](../configuring-mariadb-with-mycnf/index) file.

 


| Option | Description |
| --- | --- |
| -b, --backup | Make a backup of the table as table\_name.OLD. |
| --character-sets-dir=name | Directory where character sets are. |
| -h, --datadir | Path for control file (and logs if `--logdir` not used). From [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/) |
| -#, --debug[=name] | Output debug log. Often this is 'd:t:o,filename'. |
| -?, --help | Display help and exit. |
| -f, --force | Force packing of table even if it gets bigger or if tempfile exists. |
| --ignore-control-file | Ignore the control file. From [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/). |
| -j, --join=name | Join all given tables into 'new\_table\_name'. All tables MUST have identical layouts. |
| --require-control-file | Abort if cannot find control file. From [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/). |
| -s, --silent | Only write output when an error occurs. |
| -t, --test | Don't pack table, only test packing it. |
| -T, --tmpdir=name | Use temporary directory to store temporary table. |
| -v, --verbose | Write info about progress and packing result. Use many -v for more verbosity! |
| -V, --version | Output version information and exit. |
| -w, --wait | Wait and retry if table is in use. |

 
Unpacking
---------

 To unpack a table compressed with aria\_pack, use the [aria\_chk -u](../aria_chk/index) option.

 Example
-------

 
```
> aria_pack /my/data/test/posts
Compressing /my/data/test/posts.MAD: (1690 records)
- Calculating statistics
- Compressing file
37.71%     
> aria_chk -rq --ignore-control-file /my/data/test/posts
- check record delete-chain
- recovering (with keycache) Aria-table '/my/data/test/posts'
Data records: 1690
State updated

```

See Also
--------

 * [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index)
* [myisamchk](../myisamchk/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria_pack/>

Operators
==========

   Operators can be used for comparing values or for assigning values. There are several operators and they may be used in different SQL statements and clauses. Some can be used somewhat on their own, not within an SQL statement clause.

 For comparing values—string or numeric—you can use symbols such as the equal-sign (i.e., `=`) or the exclamation point and the equal-sign together (i.e., `!=`). You might use these in `WHERE` clauses or within a flow-control statement or function (e.g., [IF( )](../if-function/index)). You can also use basic regular expressions with the `LIKE`  operator. 

 For assigning values, you can also use the equal-sign or other arithmetic symbols (e.g. plus-sign). You might do this with the [SET](../set/index) statement or in a `SET` clause in an [UPDATE](../update/index) statement.

  

| Title | Description |
| --- | --- |

 ###   [Arithmetic Operators](../arithmetic-operators/index)

 

| Title | Description |
| --- | --- |
|  [Addition Operator (+)](../addition-operator/index) |  Addition.  |
|  [DIV](../div/index) |  Integer division.  |
|  [Division Operator (/)](../division-operator/index) |  Division.  |
|  [MOD](../mod/index) |  Modulo operation. Remainder of N divided by M.  |
|  [Modulo Operator (%)](../modulo-operator/index) |  Modulo operator. Returns the remainder of N divided by M.  |
|  [Multiplication Operator (\*)](../multiplication-operator/index) |  Multiplication.  |
|  [Subtraction Operator (-)](../subtraction-operator-/index) |  Subtraction and unary minus.  |

 ###   [Assignment Operators](../assignment-operators/index)

 

| Title | Description |
| --- | --- |
|  [Assignment Operator (:=)](../assignment-operator/index) |  Assignment operator for assigning a value.  |
|  [Assignment Operator (=)](../assignment-operators-assignment-operator/index) |  The equal sign as an assignment operator.  |

 ###   [Bit Functions and Operators](../bit-functions-and-operators/index)

 

| Title | Description |
| --- | --- |
|  [Operator Precedence](../operator-precedence/index) |  Precedence of SQL operators  |
|  [&](../bitwise_and/index) |  Bitwise AND  |
|  [<<](../shift-left/index) |  Left shift  |
|  [>>](../shift-right/index) |  Shift right  |
|  [BIT\_COUNT](../bit_count/index) |  Returns the number of set bits  |
|  [^](../bitwise-xor/index) |  Bitwise XOR  |
|  [|](../bitwise-or/index) |  Bitwise OR  |
|  [~](../bitwise-not/index) |  Bitwise NOT  |
|  [Parentheses](../parentheses/index) |  Parentheses modify the precedence of other operators in an expression  |
|  [TRUE FALSE](../true-false/index) |  TRUE and FALSE evaluate to 1 and 0  |

 ###   [Comparison Operators](../comparison-operators/index)

 

| Title | Description |
| --- | --- |
|  [!=](../not-equal/index) |  Not equal operator.  |
|  [<](../less-than/index) |  Less than operator.  |
|  [<=](../less-than-or-equal/index) |  Less than or equal operator.  |
|  [<=>](../null-safe-equal/index) |  NULL-safe equal operator.  |
|  [=](../equal/index) |  Equal operator.  |
|  [>](../greater-than/index) |  Greater than operator.  |
|  [>=](../greater-than-or-equal/index) |  Greater than or equal operator.  |
|  [BETWEEN AND](../between-and/index) |  True if expression between two values.  |
|  [COALESCE](../coalesce/index) |  Returns the first non-NULL parameter  |
|  [GREATEST](../greatest/index) |  Returns the largest argument.  |
|  [IN](../in/index) |  True if expression equals any of the values in the list.  |
|  [INTERVAL](../interval/index) |  Index of the argument that is less than the first argument  |
|  [IS](../is/index) |  Tests whether a boolean is TRUE, FALSE, or UNKNOWN.  |
|  [IS NOT](../is-not/index) |  Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN  |
|  [IS NOT NULL](../is-not-null/index) |  Tests whether a value is not NULL  |
|  [IS NULL](../is-null/index) |  Tests whether a value is NULL  |
|  [ISNULL](../isnull/index) |  Checks if an expression is NULL  |
|  [LEAST](../least/index) |  Returns the smallest argument.  |
|  [NOT BETWEEN](../not-between/index) |  Same as NOT (expr BETWEEN min AND max)  |
|  [NOT IN](../not-in/index) |  Same as NOT (expr IN (value,...))  |

 ###   [Logical Operators](../logical-operators/index)

 

| Title | Description |
| --- | --- |
|  [!](../not/index) |  Logical NOT.  |
|  [&&](../and/index) |  Logical AND.  |
|  [XOR](../xor/index) |  Logical XOR.  |
|  [||](../or/index) |  Logical OR.  |

 ### Other Operators Articles

 

| Title | Description |
| --- | --- |
|  [Operator Precedence](../operator-precedence/index) |  Precedence of SQL operators  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/operators/>

MariaDB Galera Cluster Releases
================================

   Since [MariaDB 10.1](../what-is-mariadb-101/index), Galera has been a standard part of MariaDB Server. See [MariaDB Server Release Notes](../release-notes/index).

  

| Title | Description |
| --- | --- |
|  [MariaDB Galera 10.0 Changelogs](../mariadb-galera-100-changelogs/index) |  Changelogs for MariaDB Galera Cluster 10.0.x releases.  |
|  [MariaDB Galera 10.0 Release Notes](https://mariadb.com/kb/en/mariadb-galera-100-release-notes/) |  Release notes for MariaDB Galera Cluster 10.0 releases.  |
|  [MariaDB Galera 5.5 Changelogs](../mariadb-galera-55-changelogs/index) |  Changelogs for MariaDB Galera 5.5 releases.  |
|  [MariaDB Galera 5.5 Release Notes](https://mariadb.com/kb/en/mariadb-galera-55-release-notes/) |  Release Notes for MariaDB Galera Cluster 5.5 releases.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-galera-cluster-releases/>

myisampack
==========

     `myisampack` is a tool for compressing [MyISAM](../myisam/index) tables. The resulting tables are read-only, and usually about 40% to 70% smaller. It is run as follows:

 
```
myisampack [options] file_name [file_name2...]

```

The `file_name` is the `.MYI` index file. The extension can be omitted, although keeping it permits wildcards, such as: 

 
```
myisampack *.MYI

```

...to compress all the files.

 `myisampack` compresses each column separately, and, when the resulting data is read, only the individual rows and columns required need to be decompressed, allowing for quicker reading.

 Once a table has been packed, use `[myisamchk -rq](../myisamchk/index)` (the quick and recover options) to rebuild its indexes.

 `myisampack` does not support partitioned tables. 

 
Do not run myisampack if the tables could be updated during the operation, and [skip\_external\_locking](../server-system-variables/index#skip_external_locking) has been set.

 
Options
-------

 The following variables can be set while passed as commandline options to `myisampack`, or set with a `[myisampack]` section in your [my.cnf](../configuring-mariadb-with-mycnf/index) file.

 


| Option | Description |
| --- | --- |
| `-b`, `--backup` | Make a backup of the table as `table_name.OLD`. |
| `--character-sets-dir=name` | Directory where character sets are. |
| `-#` , `--debug[=name]` | Output debug log. Often this is `'d:t:o,filename'`. |
| `-f`, `--force` | Force packing of table even if it gets bigger or if tempfile exists. |
| `-j`, `--join=name` | Join all given tables into `'new_table_name'`. All tables **must** have identical layouts. |
| `-?`, `--help` | Display help and exit. |
| `-s`, `--silent` | Only write output when an error occurs |
| `-T`, `--tmpdir=name` | Use temporary directory to store temporary table. |
| `-t`, `--test` | Don't pack table, only test packing it. |
| `-v`, `--verbose` | Write info about progress and packing result. Use multiple `-v` flags for more verbosity. |
| `-V`, `--version` | Output version information and exit. |
| `-w`, `--wait` | Wait and retry if table is in use. |

 
Uncompressing
-------------

 To uncompress a table compressed with `myisampack`, use the `[myisamchk -u](../myisamchk/index)` option.

 Examples
--------

 
```
> myisampack /var/lib/mysql/test/posts
Compressing /var/lib/mysql/test/posts.MYD: (1680 records)
- Calculating statistics
- Compressing file
37.71%
> myisamchk -rq /var/lib/mysql/test/posts
- check record delete-chain
- recovering (with sort) MyISAM-table '/var/lib/mysql/test/posts'
Data records: 1680
- Fixing index 1
- Fixing index 2

```

See Also
--------

 * [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index)
* [myisamchk](../myisamchk/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisampack/>

MyISAM
=======

   MyISAM was the default [storage engine](storage-engine) from MySQL 3.23 until it was replaced by [InnoDB](../innodb/index) in MariaDB and MySQL 5.5. It's a light, non-transactional engine with great performance, is easy to copy between systems and has a small data footprint.

 You're encouraged to rather use the [Aria](../aria/index) storage engine for new applications, which has even better performance and the goal of being crash-safe.

 Until [MariaDB 10.4](../what-is-mariadb-104/index), [system tables](../system-tables/index) used the MyISAM storage engine.

  

| Title | Description |
| --- | --- |
|  [MyISAM Overview](../myisam-overview/index) |  Light, non-transactional storage engine.  |
|  [MyISAM System Variables](../myisam-system-variables/index) |  MyISAM system variables.  |
|  [MyISAM Storage Formats](../myisam-storage-formats/index) |  The MyISAM storage engine supports three different table storage formats  |
|  [MyISAM Clients and Utilities](../myisam-clients-and-utilities/index) |  Clients and utilities for working with MyISAM tables  |
|  [MyISAM Index Storage Space](../myisam-index-storage-space/index) |  Regular MyISAM tables make use of B-tree indexes  |
|  [MyISAM Log](../myisam-log/index) |  Records all changes to MyISAM tables  |
|  [Concurrent Inserts](../concurrent-inserts/index) |  Under some circumstances, MyISAM allows INSERTs and SELECTs to be executed concurrently.  |
|  [Segmented Key Cache](../segmented-key-cache/index) |  Collection of structures for regular MyISAM key caches  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam/>

Upgrading Galera Cluster
=========================

  

| Title | Description |
| --- | --- |
|  [Upgrading Between Minor Versions with Galera Cluster](../upgrading-between-minor-versions-with-galera-cluster/index) |  Upgrading between minor versions of MariaDB with Galera Cluster, e.g. from ...  |
|  [Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster](../upgrading-from-mariadb-103-to-mariadb-104-with-galera-cluster/index) |  How to upgrade from MariaDB 10.3 to MariaDB 10.4 in a Galera Cluster deployment.  |
|  [Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster](../upgrading-from-mariadb-102-to-mariadb-103-with-galera-cluster/index) |  How to upgrade from MariaDB 10.2 to MariaDB 10.3 in a Galera Cluster deployment.  |
|  [Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster](../upgrading-from-mariadb-101-to-mariadb-102-with-galera-cluster/index) |  How to upgrade from MariaDB 10.1 to MariaDB 10.2 in a Galera Cluster deployment.  |
|  [Upgrading from MariaDB Galera Cluster 10.0 to MariaDB 10.1 with Galera Cluster](../upgrading-galera-cluster-upgrading-from-mariadb-galera-cluster-100-to-maria/index) |  How to upgrade from MariaDB Galera Cluster 10.0 to MariaDB 10.1 in a Galera Cluster deployment.  |
|  [Upgrading from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0](../upgrading-from-mariadb-galera-cluster-55-to-mariadb-galera-cluster-100/index) |  How to upgrade from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-galera-cluster/>

Triggers
=========

   A trigger is a set of statements that run when an event occurs on a table.

  

| Title | Description |
| --- | --- |
|  [Trigger Overview](../trigger-overview/index) |  Statements run when an event occurs on a table.  |
|  [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) |  Stored routines require extra consideration when binary logging.  |
|  [CREATE TRIGGER](../create-trigger/index) |  Create a new trigger.  |
|  [DROP TRIGGER](../drop-trigger/index) |  Drops a trigger.  |
|  [Information Schema TRIGGERS Table](../information-schema-triggers-table/index) |  Information about triggers  |
|  [Running Triggers on the Replica for Row-based Events](../running-triggers-on-the-replica-for-row-based-events/index) |  Running triggers on the replica for row-based events.  |
|  [SHOW CREATE TRIGGER](../show-create-trigger/index) |  Shows the CREATE TRIGGER statement used to create the trigger  |
|  [SHOW TRIGGERS](../show-triggers/index) |  Shows currently-defined triggers  |
|  [Trigger Limitations](../trigger-limitations/index) |  Restrictions applying to triggers.  |
|  [Triggers and Implicit Locks](../triggers-and-implicit-locks/index) |  Implicit locks due to triggers and LOCK TABLE  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/triggers/>

Temporal Tables
================

   MariaDB supports temporal data tables in the form of system-versioning tables (allowing you to query and operate on historic data), application-time periods (allow you to query and operate on a temporal range of data), and bitemporal tables (which combine both system-versioning and application-time periods).

  

| Title | Description |
| --- | --- |
|  [System-Versioned Tables](../system-versioned-tables/index) |  System-versioned tables record the history of all changes to table data.  |
|  [Application-Time Periods](../application-time-periods/index) |  Application-time period tables, defined by a range between two temporal columns.  |
|  [Bitemporal Tables](../bitemporal-tables/index) |  Bitemporal tables use versioning both at the system and application-time period levels.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/temporal-tables/>

FLUSH TABLES FOR EXPORT
=======================

    Syntax
------

 
```
FLUSH TABLES table_name [, table_name] FOR EXPORT

```
 Description
-----------

 `FLUSH TABLES ... FOR EXPORT` flushes changes to the specified tables to disk so that binary copies can be made while the server is still running. This works for [Archive](../archive/index), [Aria](../aria/index), [CSV](../csv/index), [InnoDB](../innodb/index), [MyISAM](../myisam/index), [MERGE](../merge/index), and [XtraDB](../xtradb/index) tables.

 The table is read locked until one has issued [UNLOCK TABLES](../transactions-unlock-tables/index).

 If a storage engine does not support `FLUSH TABLES FOR EXPORT`, a 1031 error ([SQLSTATE](../sqlstate/index) 'HY000') is produced.

 If `FLUSH TABLES ... FOR EXPORT` is in effect in the session, the following statements will produce an error if attempted:

 * `FLUSH TABLES WITH READ LOCK`
* `FLUSH TABLES ... WITH READ LOCK`
* `FLUSH TABLES ... FOR EXPORT`
* Any statement trying to update any table

 If any of the following statements is in effect in the session, attempting  `FLUSH TABLES ... FOR EXPORT` will produce an error.

 * `FLUSH TABLES ... WITH READ LOCK`
* `FLUSH TABLES ... FOR EXPORT`
* `LOCK TABLES ... READ`
* `LOCK TABLES ... WRITE`

 `FLUSH FOR EXPORT` is not written to the [binary log](../binary-log/index).

 This statement requires the [RELOAD](../grant/index#global-privileges) and the [LOCK TABLES](../grant/index#database-privileges) privileges.

 If one of the specified tables cannot be locked, none of the tables will be locked.

 If a table does not exist, an error like the following will be produced:

 
```
ERROR 1146 (42S02): Table 'test.xxx' doesn't exist

```

If a table is a view, an error like the following will be produced:

 
```
ERROR 1347 (HY000): 'test.v' is not BASE TABLE

```

Example
-------

 
```
FLUSH TABLES test.t1 FOR EXPORT;
#  Copy files related to the table (see below)
UNLOCK TABLES;

```

For a full description, please see [copying MariaDB tables](../copying-tables-between-different-mariadb-databases-and-mariadb-servers/index).

 See Also
--------

 * [Copying Tables Between Different MariaDB Databases and MariaDB Servers](../copying-tables-between-different-mariadb-databases-and-mariadb-servers/index)
* [Copying Transportable InnoDB Tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces)
* [myisampack](../myisampack/index) - Compressing the MyISAM data file for easier distribution.
* [aria\_pack](../aria_pack/index) - Compressing the Aria data file for easier distribution

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/flush-tables-for-export/>

myisamchk
=========

     myisamchk is a commandline tool for checking, repairing and optimizing non-partitioned [MyISAM](../myisam/index) tables.

 myisamchk is run from the commandline as follows:

 
```
myisamchk [OPTIONS] tables[.MYI]

```

The full list of options are listed below. One or more MyISAM tables can be specified. MyISAM tables have an associated .MYI index file, and the table name can either be specified with or without the .MYI extension. Referencing it with the extension allows you to use wildcards, so it's possible to run myisamchk on *all* the MyISAM tables in the database with `*.MYI`. 

 The path to the files must also be specified if they're not in the current directory.

 
myisamchk should not be run while anyone is accessing any of the affected tables. It is also best to make a backup before running.

 
With no options, myisamchk simply checks your table as the default operation.

 The following options can be set while passed as commandline options to myisamchk, or set with a [myisamchk] section in your [my.cnf](../configuring-mariadb-with-mycnf/index) file.

 General Options
---------------

 


| Option | Description |
| --- | --- |
| -H, --HELP | Display help and exit. Options are presented in a single list. |
| -?, --help | Display help and exit. Options are grouped by type of operation. |
| -debug=options, -# options | Write a debugging log. A typical debug\_options string is ´d:t:o,file\_name´. The default is ´d:t:o,/tmp/myisamchk.trace´. (Available in debug builds only) |
| -t path, --tmpdir=path | Path for temporary files. Multiple paths can be specified, separated by colon (:) on Unix and semicolon (;) on Windows. They will be used in a round-robin fashion. If not set, the TMPDIR environment variable is used. |
| -s, --silent | Only print errors. One can use two -s (-ss) to make myisamchk very silent. |
| -v, --verbose | Print more information. This can be used with --description and --check. Use many -v for more verbosity. |
| -V, --version | Print version and exit. |
| -w, --wait | If table is locked, wait instead of returning an error. |
| --print-defaults | Print the program argument list and exit. |
| --no-defaults | Don't read default options from any option file. |
| --defaults-file=filename | Only read default options from the given file *filename*, which can be the full path, or the path relative to the current directory. |
| --defaults-extra-file=filename | Read the file *filename*, which can be the full path, or the path relative to the current directory, after the global files are read. |
| --defaults-group-suffix=str | Also read groups with a suffix of *str*. For example, `--defaults-group-suffix=x` would read the groups [myisamchk] and [myisamchk\_x] |

 
The following variables can also be set by using *--var\_name=value*, for example *--ft\_min\_word\_len=5*

 


| Variable | Default Value |
| --- | --- |
| decode\_bits | 9 |
| ft\_max\_word\_len | version-dependent |
| ft\_min\_word\_len | 4 |
| ft\_stopword\_file | built-in list |
| key\_buffer\_size | 1044480 |
| key\_cache\_block\_size | 1024 |
| myisam\_block\_size | 1024 |
| myisam\_sort\_buffer\_size | 134216704 |
| myisam\_sort\_key\_blocks | 16 |
| read\_buffer\_size | 262136 |
| sort\_buffer\_size | 134216704 |
| sort\_key\_blocks | 16 |
| stats\_method | nulls\_unequal |
| write\_buffer\_size | 262136 |

 
Checking Tables
---------------

 If no option is provided, myisamchk will perform a check table. It is possible to check [MyISAM](../myisam/index) tables without shutting down or restricting access to the server by using [CHECK TABLE](../check-table/index) instead.

 The following check options are available:

 


| Option | Description |
| --- | --- |
| -c, --check | Check table for errors. This is the default operation if you specify no option that selects an operation type explicitly. |
| -e, --extend-check | Check the table VERY throughly. Only use this in extreme cases as it may be slow, and myisamchk should normally be able to find out if the table has errors even without this switch. Increasing the *key\_buffer\_size* can help speed the process up. |
| -F, --fast | Check only tables that haven't been closed properly. |
| -C, --check-only-changed | Check only tables that have changed since last check. |
| -f, --force | Restart with '-r' (recover) if there are any errors in the table. States will be updated as with '--update-state'. |
| -i, --information | Print statistics information about the table that is checked. |
| -m, --medium-check | Faster than *extend-check*, but only finds 99.99% of all errors. Should be good enough for most cases. |
| -U --update-state | Mark tables as crashed if you find any errors. This should be used to get the full benefit of the *--check-only-changed* option, but you shouldn´t use this option if the mysqld server is using the table and you are running it with external locking disabled. |
| -T, --read-only | Don't mark table as checked. This is useful if you use myisamchk to check a table that is in use by some other application that does not use locking, such as mysqld when run with external locking disabled. |

 
Repairing Tables
----------------

 It is also possible to repair [MyISAM](../myisam/index) tables by using [REPAIR TABLE](../repair-table/index).

 The following repair options are available, and are applicable when using '-r' or '-o':

 


| Option | Description |
| --- | --- |
| -B, --backup | Make a backup of the .MYD file as 'filename-time.BAK'. |
| --correct-checksum | Correct the checksum information for table. |
| -D len, --data-file-length=# | Max length of data file (when recreating data file when it's full). |
| -e, --extend-check | Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate. |
| -f, --force | Overwrite old temporary files. Add another --force to avoid 'myisam\_sort\_buffer\_size is too small' errors. In this case we will attempt to do the repair with the given myisam\_sort\_buffer\_size and dynamically allocate as many management buffers as needed. |
| -k val, --keys-used=# | Specify which keys to update. The value is a bit mask of which keys to use. Each binary bit corresponds to a table index, with the first index being bit 0. *0* disables all index updates, useful for faster inserts. Deactivated indexes can be reactivated by using *myisamchk -r*. |
| --create-missing-keys | Create missing keys. This assumes that the data file is correct and that the number of rows stored in the index file is correct. Enables *--quick* |
| --max-record-length=# | Skip rows larger than this if myisamchk can't allocate memory to hold them. |
| -r, --recover | Can fix almost anything except unique keys that aren't unique (a rare occurrence). Usually this is the best option to try first. Increase  *myisam\_sort\_buffer\_size* for better performance. |
| -n, --sort-recover | Forces recovering with sorting even if the temporary file would be very large. |
| -p, --parallel-recover | Uses the same technique as '-r' and '-n', but creates all the keys in parallel, in different threads. |
| -o, --safe-recover | Uses old recovery method; Slower than '-r' but uses less disk space and can handle a couple of cases where '-r' reports that it can't fix the data file. Increase *key\_buffer\_size* for better performance. |
| --character-sets-dir=directory\_name | Directory where the [character sets](../data-types-character-sets-and-collations/index) are installed. |
| --set-collation=name | Change the collation (and by implication, the [character set](../data-types-character-sets-and-collations/index)) used by the index. |
| -q, --quick | Faster repair by not modifying the data file. One can give a second '-q' to force myisamchk to modify the original datafile in case of duplicate keys. NOTE: Tables where the data file is corrupted can't be fixed with this option. |
| -u, --unpack | Unpack file packed with myisampack. |

 
Other Actions
-------------

 


| Option | Description |
| --- | --- |
| -a, --analyze | Analyze distribution of keys. Will make some joins faster as the join optimizer can better choose the order in which to join the tables and which indexes to use. You can check the calculated distribution by using '--description --verbose table\_name' or [SHOW INDEX FROM table\_name](../show-index/index). |
| --stats\_method=name | Specifies how index statistics collection code should treat NULLs. Possible values of *name* are "nulls\_unequal" (default), "nulls\_equal" (emulate MySQL 4.0 behavior), and "nulls\_ignored". |
| -d, --description | Print some descriptive information about the table. Specifying the *--verbose* option once or twice produces additional information. |
| -A [value], --set-auto-increment[=value] | Force auto\_increment to start at this or higher value. If no value is given, then sets the next auto\_increment value to the highest used value for the auto key + 1. |
| -S, --sort-index | Sort the index tree blocks in high-low order. This optimizes seeks and makes table scans that use indexes faster. |
| -R index\_num, --sort-records=# | Sort records according to the given index (as specified by the index number). This makes your data much more localized and may speed up range-based SELECTs and ORDER BYs using this index. It may be VERY slow to do a sort the first time! To see the index numbers, [SHOW INDEX](../show-index/index) displays table indexes in the same order that myisamchk sees them. The first index is 1. |
| -b offset, --block-search=offset | Find the record to which a block at the given *offset* belongs. |

 
For more, see [Memory and Disk Use With myisamchk](../memory-and-disk-use-with-myisamchk/index).

 Examples
--------

 Check all the MyISAM tables in the current directory:

 
```
myisamchk *.MYI

```

If you are not in the database directory, you can check all the tables there by specifying the path to the directory:

 
```
myisamchk /path/to/database_dir/*.MYI

```

Check all tables in all databases by specifying a wildcard with the path to the MariaDB data directory:

 
```
myisamchk /path/to/datadir/*/*.MYI

```

The recommended way to quickly check all MyISAM tables:

 
```
myisamchk --silent --fast /path/to/datadir/*/*.MYI

```

Check all MyISAM tables and repair any that are corrupted:

 
```
myisamchk --silent --force --fast --update-state \
  --key_buffer_size=64M --sort_buffer_size=64M \
  --read_buffer_size=1M --write_buffer_size=1M \
  /path/to/datadir/*/*.MYI

```

See Also
--------

 * [Memory and Disk Use With myisamchk](../memory-and-disk-use-with-myisamchk/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisamchk/>

FederatedX
===========

   Information about the FederatedX Storage Engine

  

| Title | Description |
| --- | --- |
|  [About FederatedX](../about-federatedx/index) |  Federated Storage Engine fork that uses uses libmysql to talk to the data source  |
|  [Differences Between FederatedX and Federated](../differences-between-federatedx-and-federated/index) |  Main differences between FederatedX and Federated.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/federatedx-storage-engine/>

FLUSH
=====

    Syntax
------

 
```
FLUSH [NO_WRITE_TO_BINLOG | LOCAL]
    flush_option [, flush_option] ...

```

or when flushing tables:

 
```
FLUSH [NO_WRITE_TO_BINLOG | LOCAL] TABLES [table_list]  [table_flush_option]

```

 where `table_list` is a list of tables separated by `,` (comma).

 Description
-----------

 The `FLUSH` statement clears or reloads various internal caches used by MariaDB. To execute `FLUSH`, you must have the `RELOAD` privilege. See [GRANT](../grant/index).

 The `RESET` statement is similar to `FLUSH`. See [RESET](../reset/index).

 You cannot issue a FLUSH statement from within a [stored function](../stored-functions/index) or a [trigger](../triggers/index). Doing so within a stored procedure is permitted, as long as it is not called by a stored function or trigger. See [Stored Routine Limitations](../stored-routine-limitations/index), [Stored Function Limitations](../stored-function-limitations/index) and [Trigger Limitations](../trigger-limitations/index).

 If a listed table is a view, an error like the following will be produced:

 
```
ERROR 1347 (HY000): 'test.v' is not BASE TABLE

```

By default, `FLUSH` statements are written to the [binary log](../binary-log/index) and will be [replicated](../replication/index). The `NO_WRITE_TO_BINLOG` keyword (`LOCAL` is an alias) will ensure the statement is not written to the binary log. 

   
  
The different flush options are:  
  
  


 


| Option | Description |
| --- | --- |
| `CHANGED_PAGE_BITMAPS` | [XtraDB](../about-xtradb/index) only. Internal command used for backup purposes. See the [Information Schema CHANGED\_PAGE\_BITMAPS Table](../information-schema-changed_page_bitmaps-table/index). |
| `CLIENT_STATISTICS` | Reset client statistics (see [SHOW CLIENT\_STATISTICS](../show-client-statistics/index)). |
| `DES_KEY_FILE` | Reloads the DES key file (Specified with the [--des-key-file startup option](../mysqld-options-full-list/index)). |
| `HOSTS` | Flush the hostname cache (used for converting ip to host names and for unblocking blocked hosts. See [max\_connect\_errors](../server-system-variables/index#max_connect_errors) and [performance\_schema.host\_cache](../performance-schema-host_cache-table/index) |
| `INDEX_STATISTICS` | Reset index statistics (see [SHOW INDEX\_STATISTICS](../show-index-statistics/index)). |
| ``[ERROR | ENGINE | GENERAL | SLOW | BINARY | RELAY] LOGS`` | Close and reopen the specified log type, or all log types if none are specified. `FLUSH RELAY LOGS [connection-name]` can be used to flush the relay logs for a specific connection. Only one connection can be specified per `FLUSH` command. See [Multi-source replication](../multi-source-replication/index). `FLUSH ENGINE LOGS` will delete all unneeded [Aria](../aria/index) redo logs. `FLUSH BINARY LOGS DELETE_DOMAIN_ID=(list-of-domains)` can be used to discard obsolete [GTID](../gtid/index) domains from the server's [binary log](../binary-log/index) state. In order for this to be successful, no event group from the listed [GTID](../gtid/index) domains can be present in existing [binary log](../binary-log/index) files. If some still exist, then they must be purged prior to executing this command. If the command completes successfully, then it also rotates the [binary log](../binary-log/index). |
| `MASTER` | Deprecated option, use [RESET MASTER](../reset/index) instead. |
| `PRIVILEGES` | Reload all privileges from the privilege tables in the `mysql` database. If the server is started with `--skip-grant-table` option, this will activate the privilege tables again. |
| [QUERY CACHE](../flush-query-cache/index) | Defragment the [query cache](../query-cache/index) to better utilize its memory. If you want to reset the query cache, you can do it with [RESET QUERY CACHE](../reset/index). |
| `QUERY_RESPONSE_TIME` | See the [QUERY\_RESPONSE\_TIME](../query_response_time-plugin/index) plugin. |
| `SLAVE` | Deprecated option, use [RESET REPLICA or RESET SLAVE](../reset-replica/index) instead. |
| `SSL` | Used to dynamically reinitialize the server's [TLS](../data-in-transit-encryption/index) context by reloading the files defined by several [TLS system variables](../ssltls-system-variables/index). See [FLUSH SSL](#flush-ssl) for more information. |
| `STATUS` | Resets all [server status variables](../server-status-variables/index) that can be reset to 0. Not all global status variables support this, so not all global values are reset. See [FLUSH STATUS](#flush-status) for more information. |
| `TABLE` | Close tables given as options or all open tables if no table list was used. From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/), using without any table list will only close tables not in use, and tables not locked by the FLUSH TABLES connection. If there are no locked tables, FLUSH TABLES will be instant and will not cause any waits, as it no longer waits for tables in use. When a table list is provided, from [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/), the server will wait for the end of any transactions that are using the tables. Previously, FLUSH TABLES only waited for the statements to complete. |
| `TABLES` | Same as `FLUSH TABLE`. |
| `[TABLES ... FOR EXPORT](../flush-tables-for-export/index)` | For InnoDB tables, flushes table changes to disk to permit binary table copies while the server is running. See [FLUSH TABLES ... FOR EXPORT](../flush-tables-for-export/index) for more. |
| `TABLES WITH READ LOCK` | Closes all open tables. New tables are only allowed to be opened with read locks until an [UNLOCK TABLES](../transactions-unlock-tables/index) is given. |
| `TABLES WITH READ LOCK AND DISABLE CHECKPOINT` | As `TABLES WITH READ LOCK` but also disable all checkpoint writes by transactional table engines. This is useful when doing a disk snapshot of all tables. |
| `TABLE_STATISTICS` | Reset table statistics (see [SHOW TABLE\_STATISTICS](../show-table-statistics/index)). |
| `USER_RESOURCES` | Resets all per hour [user resources](../grant/index#setting-per-account-resources-limits). This enables clients that have exhausted their resources to connect again. |
| `USER_STATISTICS` | Reset user statistics (see [SHOW USER\_STATISTICS](../show-user-statistics/index)). |
| `USER_VARIABLES` | Reset user variables (see [User-defined variables](../user-defined-variables/index)). |

 
You can also use the [mariadb-admin](../mariadb-admin/index) client to flush things. Use `mariadb-admin --help` to examine what flush commands it supports.

 `FLUSH RELAY LOGS`
------------------

 
```
FLUSH RELAY LOGS 'connection_name';

```

### Compatibility with MySQL

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical to using the channel\_name directly after the `FLUSH command`.

 For example, one can now use:

 
```
FLUSH RELAY LOGS FOR CHANNEL 'connection_name';

```


`FLUSH STATUS`
--------------

 [Server status variables](../server-status-variables/index) can be reset by executing the following:

 
```
FLUSH STATUS;

```

### Global Status Variables that Support `FLUSH STATUS`

 Not all global status variables support being reset by `FLUSH STATUS`. Currently, the following status variables are reset by `FLUSH STATUS`:

 * [Aborted\_clients](../server-status-variables/index#aborted_clients)
* [Aborted\_connects](../server-status-variables/index#aborted_connects)
* [Binlog\_cache\_disk\_use](../replication-and-binary-log-status-variables/index#binlog_cache_disk_use)
* [Binlog\_cache\_use](../replication-and-binary-log-status-variables/index#binlog_cache_use)
* [Binlog\_stmt\_cache\_disk\_use](../replication-and-binary-log-status-variables/index#binlog_stmt_cache_disk_use)
* [Binlog\_stmt\_cache\_use](../replication-and-binary-log-status-variables/index#binlog_stmt_cache_use)
* [Connection\_errors\_accept](../server-status-variables/index#connection_errors_accept)
* [Connection\_errors\_internal](../server-status-variables/index#connection_errors_internal)
* [Connection\_errors\_max\_connections](../server-status-variables/index#connection_errors_max_connections)
* [Connection\_errors\_peer\_address](../server-status-variables/index#connection_errors_peer_address)
* [Connection\_errors\_select](../server-status-variables/index#connection_errors_select)
* [Connection\_errors\_tcpwrap](../server-status-variables/index#connection_errors_tcpwrap)
* [Created\_tmp\_files](../server-status-variables/index#created_tmp_files)
* [Delayed\_errors](../server-status-variables/index#delayed_errors)
* [Delayed\_writes](../server-status-variables/index#delayed_writes)
* [Feature\_check\_constraint](../server-status-variables/index#feature_check_constraint)
* [Feature\_delay\_key\_write](../server-status-variables/index#feature_delay_key_write)
* [Max\_used\_connections](../server-status-variables/index#max_used_connections)
* [Opened\_plugin\_libraries](../server-status-variables/index#opened_plugin_libraries)
* [Performance\_schema\_accounts\_lost](../performance-schema-status-variables/index#performance_schema_accounts_lost)
* [Performance\_schema\_cond\_instances\_lost](../performance-schema-status-variables/index#performance_schema_cond_instances_lost)
* [Performance\_schema\_digest\_lost](../performance-schema-status-variables/index#performance_schema_digest_lost)
* [Performance\_schema\_file\_handles\_lost](../performance-schema-status-variables/index#performance_schema_file_handles_lost)
* [Performance\_schema\_file\_instances\_lost](../performance-schema-status-variables/index#performance_schema_file_instances_lost)
* [Performance\_schema\_hosts\_lost](../performance-schema-status-variables/index#performance_schema_hosts_lost)
* [Performance\_schema\_locker\_lost](../performance-schema-status-variables/index#performance_schema_locker_lost)
* [Performance\_schema\_mutex\_instances\_lost](../performance-schema-status-variables/index#performance_schema_mutex_instances_lost)
* [Performance\_schema\_rwlock\_instances\_lost](../performance-schema-status-variables/index#performance_schema_rwlock_instances_lost)
* [Performance\_schema\_session\_connect\_attrs\_lost](../performance-schema-status-variables/index#performance_schema_session_connect_attrs_lost)
* [Performance\_schema\_socket\_instances\_lost](../performance-schema-status-variables/index#performance_schema_socket_instances_lost)
* [Performance\_schema\_stage\_classes\_lost](../performance-schema-status-variables/index#performance_schema_stage_classes_lost)
* [Performance\_schema\_statement\_classes\_lost](../performance-schema-status-variables/index#performance_schema_statement_classes_lost)
* [Performance\_schema\_table\_handles\_lost](../performance-schema-status-variables/index#performance_schema_table_handles_lost)
* [Performance\_schema\_table\_instances\_lost](../performance-schema-status-variables/index#performance_schema_table_instances_lost)
* [Performance\_schema\_thread\_instances\_lost](../performance-schema-status-variables/index#performance_schema_thread_instances_lost)
* [Performance\_schema\_users\_lost](../performance-schema-status-variables/index#performance_schema_users_lost)
* [Qcache\_hits](../server-status-variables/index#qcache_hits)
* [Qcache\_inserts](../server-status-variables/index#qcache_inserts)
* [Qcache\_lowmem\_prunes](../server-status-variables/index#qcache_lowmem_prunes)
* [Qcache\_not\_cached](../server-status-variables/index#qcache_not_cached)
* [Rpl\_semi\_sync\_master\_no\_times](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_times)
* [Rpl\_semi\_sync\_master\_no\_tx](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_tx)
* [Rpl\_semi\_sync\_master\_timefunc\_failures](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_timefunc_failures)
* [Rpl\_semi\_sync\_master\_wait\_pos\_backtraverse](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_wait_pos_backtraverse)
* [Rpl\_semi\_sync\_master\_yes\_tx](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_yes_tx)
* [Rpl\_transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#rpl_transactions_multi_engine)
* [Server\_audit\_writes\_failed](../mariadb-audit-plugin-status-variables/index#server_audit_writes_failed)
* [Slave\_retried\_transactions](../replication-and-binary-log-status-variables/index#slave_retried_transactions)
* [Slow\_launch\_threads](../server-status-variables/index#slow_launch_threads)
* [Ssl\_accept\_renegotiates](../ssltls-status-variables/index#ssl_accept_renegotiates)
* [Ssl\_accepts](../ssltls-status-variables/index#ssl_accepts)
* [Ssl\_callback\_cache\_hits](../ssltls-status-variables/index#ssl_callback_cache_hits)
* [Ssl\_client\_connects](../ssltls-status-variables/index#ssl_client_connects)
* [Ssl\_connect\_renegotiates](../ssltls-status-variables/index#ssl_connect_renegotiates)
* [Ssl\_ctx\_verify\_depth](../ssltls-status-variables/index#ssl_ctx_verify_depth)
* [Ssl\_ctx\_verify\_mode](../ssltls-status-variables/index#ssl_ctx_verify_mode)
* [Ssl\_finished\_accepts](../ssltls-status-variables/index#ssl_finished_accepts)
* [Ssl\_finished\_connects](../ssltls-status-variables/index#ssl_finished_connects)
* [Ssl\_session\_cache\_hits](../ssltls-status-variables/index#ssl_session_cache_hits)
* [Ssl\_session\_cache\_misses](../ssltls-status-variables/index#ssl_session_cache_misses)
* [Ssl\_session\_cache\_overflows](../ssltls-status-variables/index#ssl_session_cache_overflows)
* [Ssl\_session\_cache\_size](../ssltls-status-variables/index#ssl_session_cache_size)
* [Ssl\_session\_cache\_timeouts](../ssltls-status-variables/index#ssl_session_cache_timeouts)
* [Ssl\_sessions\_reused](../ssltls-status-variables/index#ssl_sessions_reused)
* [Ssl\_used\_session\_cache\_entries](../ssltls-status-variables/index#ssl_used_session_cache_entries)
* [Subquery\_cache\_hit](../server-status-variables/index#subquery_cache_hit)
* [Subquery\_cache\_miss](../server-status-variables/index#subquery_cache_miss)
* [Table\_locks\_immediate](../server-status-variables/index#table_locks_immediate)
* [Table\_locks\_waited](../server-status-variables/index#table_locks_waited)
* [Tc\_log\_max\_pages\_used](../server-status-variables/index#tc_log_max_pages_used)
* [Tc\_log\_page\_waits](../server-status-variables/index#tc_log_page_waits)
* [Transactions\_gtid\_foreign\_engine](../replication-and-binary-log-status-variables/index#transactions_gtid_foreign_engine)
* [Transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#transactions_multi_engine)

 The different usage of `FLUSH TABLES`
-------------------------------------

 ### The purpose of `FLUSH TABLES`

 The purpose of `FLUSH TABLES` is to clean up the open table cache and table definition cache from not in use tables. This frees up memory and file descriptors. Normally this is not needed as the caches works on a FIFO bases, but can be useful if the server seams to use up to much memory for some reason.

 ### The purpose of `FLUSH TABLES WITH READ LOCK`

 `FLUSH TABLES WITH READ LOCK` is useful if you want to take a backup of some tables. When `FLUSH TABLES WITH READ LOCK` returns, all write access to tables are blocked and all tables are marked as 'properly closed' on disk. The tables can still be used for read operations.

 ### The purpose of `FLUSH TABLES table_list`

 `FLUSH TABLES` table\_list is useful if you want to copy a table object/files to or from the server. This command puts a lock that stops new users of the table and will wait until everyone has stopped using the table. The table is then removed from the table definition and table cache.

 Note that it's up to the user to ensure that no one is accessing the table between `FLUSH TABLES` and the table is copied to or from the server. This can be secured by using [LOCK TABLES](../lock-tables/index).

 If there are any tables locked by the connection that is using `FLUSH TABLES` all the locked tables will be closed as part of the flush and reopened and relocked before `FLUSH TABLES` returns. This allows one to copy the table after `FLUSH TABLES` returns without having any writes on the table. For now this works works with most tables, except InnoDB as InnoDB may do background purges on the table even while it's write locked.

 ### The purpose of `FLUSH TABLES table_list WITH READ LOCK`

 `FLUSH TABLES table_list WITH READ LOCK` should work as `FLUSH TABLES WITH READ LOCK`, but only those tables that are listed will be properly closed. However in practice this works exactly like `FLUSH TABLES WITH READ LOCK` as the `FLUSH` command has anyway to wait for all WRITE operations to end because we are depending on a global read lock for this code. In the future we should consider fixing this to instead use meta data locks.

 Implementation of `FLUSH TABLES` commands in [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/) and above
------------------------------------------------------------------------------------------------------------------------------

 ### Implementation of `FLUSH TABLES`

 * Free memory and file descriptors not in use

 ### Implementation of `FLUSH TABLES WITH READ LOCK`

 * Lock all tables read only for simple old style backup.
* All background writes are suspended and tables are marked as closed.
* No statement requiring table changes are allowed for any user until `UNLOCK TABLES`.

 Instead of using `FLUSH TABLE WITH READ LOCK` one should in most cases instead use [BACKUP STAGE BLOCK\_COMMIT](../backup-stage/index).

 ### Implementation of `FLUSH TABLES table_list`

 * Free memory and file descriptors for tables not in use from table list.
* Lock given tables as read only.
* Wait until all translations has ended that uses any of the given tables.
* Wait until all background writes are suspended and tables are marked as closed.

 ### Implementation of `FLUSH TABLES table_list FOR EXPORT`

 * Free memory and file descriptors for tables not in use from table list
* Lock given tables as read.
* Wait until all background writes are suspended and tables are marked as closed.
* Check that all tables supports `FOR EXPORT`
* No changes to these tables allowed until `UNLOCK TABLES`

 This is basically the same behavior as in old MariaDB version if one first lock the tables, then do `FLUSH TABLES`. The tables will be copyable until `UNLOCK TABLES`.

 FLUSH SSL
---------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**The `FLUSH SSL` command was first added in [MariaDB 10.4](../what-is-mariadb-104/index).

 
In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the `FLUSH SSL` command can be used to dynamically reinitialize the server's [TLS](../data-in-transit-encryption/index) context. This is most useful if you need to replace a certificate that is about to expire without restarting the server.

 This operation is performed by reloading the files defined by the following [TLS system variables](../ssltls-system-variables/index):

 * [ssl\_cert](../ssltls-system-variables/index#ssl_cert)
* [ssl\_key](../ssltls-system-variables/index#ssl_key)
* [ssl\_ca](../ssltls-system-variables/index#ssl_ca)
* [ssl\_capath](../ssltls-system-variables/index#ssl_capath)
* [ssl\_crl](../ssltls-system-variables/index#ssl_crl)
* [ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)

 These [TLS system variables](../ssltls-system-variables/index) are not dynamic, so their values can **not** be changed without restarting the server.

 If you want to dynamically reinitialize the server's [TLS](../data-in-transit-encryption/index) context, then you need to change the certificate and key files at the relevant paths defined by these [TLS system variables](../ssltls-system-variables/index), without actually changing the values of the variables. See [MDEV-19341](https://jira.mariadb.org/browse/MDEV-19341) for more information.

 Reducing Memory Usage
---------------------

 To flush some of the global caches that take up memory, you could execute the following command:

 
```
FLUSH LOCAL HOSTS,
   QUERY CACHE, 
   TABLE_STATISTICS, 
   INDEX_STATISTICS, 
   USER_STATISTICS;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/flush/>

Unleashing the Power of Advanced SQL: Joins, Subqueries, and Set Operations
===========================================================================

    SQL (Structured Query Language) is a highly potent language used in the realm of databases and data analytics. It allows us to create, manipulate, and retrieve data stored in relational databases. While simple SQL commands can handle straightforward tasks, one must delve into advanced aspects such as multiple joins, subqueries, and set operations to unravel the full potential of SQL.

 ### Multiple Joins

 Joins are fundamental to SQL, as they enable us to combine rows from two or more tables based on related columns. Several types of joins exist, including INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL JOIN.

 In real-world scenarios, finding database schemas with multiple tables linked through relationships is common. In such cases, we often need to write SQL queries with multiple joins to fetch the required data.

 For instance, consider a database for a bookstore with three tables: Books, Authors, and Publishers. If we want to get a list of books along with their author names and publishers, you would require multiple joins.

 
SELECT Books.title, Authors.name, Publishers.name FROM Books INNER JOIN Authors ON Books.author\_id = Authors.id INNER JOIN Publishers ON Books.publisher\_id = Publishers.id;

 
In the above query, we've used two INNER JOIN operations to combine data from the three tables (source). <https://www.w3schools.com/sql/sql_join.asp>

 ### Subqueries

 A subquery, also known as a nested query or inner query, is a query embedded within another SQL query. The result of the subquery can be used in the outer query. Subqueries can be used in SELECT, INSERT, UPDATE, and DELETE statements and also in conjunction with WHERE and HAVING clauses.

 Subqueries can prove powerful in many scenarios. For example, suppose we want to find books that are above the average price in our bookstore database. We could achieve this using a subquery.

 
SELECT title, price FROM Books WHERE price > (SELECT AVG(price) FROM Books);

 
In this query, the subquery calculates the average book price, which the outer query then uses to filter books that are priced above average ("#"<https://www.sqlservertutorial.net/sql-server-basics/sql-server-subquery/>.

 ### Set Operations

 SQL also provides several set operations to combine rows from two or more tables, including UNION, UNION ALL, INTERSECT, and EXCEPT. These operations are instrumental when dealing with large databases where data is spread across multiple tables and we need to perform set-based operations.

 For example, suppose we have two tables, Books\_2019 and Books\_2020, listing the books sold in the respective years. If we want to find books sold in both years, we can use the INTERSECT operation.

 
SELECT title FROM Books\_2019 INTERSECT SELECT title FROM Books\_2020;

 
In the above query, INTERSECT returns the common book titles sold in both 2019 and 2020 (source). "#"<https://www.tutorialspoint.com/sql/sql-set-operations.htm>

 ### Conclusion

 Advanced SQL queries that involve multiple joins, subqueries, and set operations can be daunting at first glance. However, these incredibly powerful tools in our SQL toolkit enable us to craft complex data retrieval and manipulation commands. To truly excel in data analytics, mastering these aspects of SQL is not only beneficial but essential.

 Remember, practice is the key to mastering these advanced SQL concepts, like any other technical skill. Write queries, solve problems, make mistakes, and learn from them. Over time, you'll find yourself not only comfortable but proficient in creating intricate SQL queries.

 Refer to the official MariaDB knowledge base [https://mariadb.com/kb/en/sql-join/and](../sql-join/and) other online resources like W3Schools or SQL Server Tutorial for further information and hands-on examples.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/unleashing-the-power-of-advanced-sql-joins-subqueries-and-set-operations/>

InnoDB File-Per-Table Tablespaces
=================================

     When you create a table using the [InnoDB storage engine](../xtradb-and-innodb/index), data written to that table is stored on the file system in a data file called a tablespace. Tablespace files contain both the data and indexes.

 When [innodb\_file\_per\_table=ON](../innodb-system-variables/index#innodb_file_per_table) is set, InnoDB uses one tablespace file per InnoDB table. These tablespace files have the `.ibd` extension. When [innodb\_file\_per\_table=OFF](../innodb-system-variables/index#innodb_file_per_table) is set, InnoDB stores all tables in the [InnoDB system tablespace](../innodb-system-tablespaces/index).

 InnoDB versions in MySQL 5.7 and above also support an additional type of tablespace called [general tablespaces](https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html) that are created with [CREATE TABLESPACE](https://dev.mysql.com/doc/refman/5.7/en/create-tablespace.html). However, InnoDB versions in MariaDB Server do not support general tablespaces or [CREATE TABLESPACE](../create-tablespace/index).

 File-Per-Table Tablespace Locations
-----------------------------------

 By default, InnoDB's file-per-table tablespaces are created in the system's data directory, which is defined by the [datadir](../server-system-variables/index#datadir) system variable. The system variable [innodb\_data\_home\_dir](../innodb-system-variables/index#innodb_data_home_dir) will not change the location of file-per-table tablespaces.

 In the event that you have a specific tablespace that you need stored in a dedicated path, you can set the location using the [DATA DIRECTORY](../create-table/index#data-directoryindex-directory) table option when you create the table.

 For instance,

 
```
CREATE TABLE test.t1 (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(50)
) ENGINE=InnoDB
DATA DIRECTORY = "/data/contact";

```

MariaDB then creates a database directory on the configured path and the file-per-table tablespace will be created inside that directory. On Unix-like operating systems, you can see the file using the ls command:

 
```
# ls -al /data/contact/test
drwxrwx--- 2 mysql mysql  4096 Dec 8 18:46 .
drwxr-xr-x 3 mysql mysql  4096 Dec 8 18:46 ..
-rw-rw---- 1 mysql mysql 98304 Dec 8 20:41 t1.ibd

```

Note, the system user that runs the MariaDB Server process (which is usually `mysql`) must have write permissions on the given path.

 Copying Transportable Tablespaces
---------------------------------

 InnoDB's file-per-table tablespaces are transportable, which means that you can copy a file-per-table tablespace from one MariaDB Server to another server. You may find this useful in cases where you need to transport full tables between servers and don't want to use backup tools like [mariabackup](../mariabackup/index) or [mariadb-dump](../mariadb-dump/index). In fact, this process can even be used with [mariabackup](../mariabackup/index) in some cases, such as when [restoring partial backups](../partial-backup-and-restore-with-mariabackup/index) or when [restoring individual tables or partitions from a backup](../restoring-individual-tables-and-partitions-with-mariabackup/index).

 ### Copying Transportable Tablespaces for Non-partitioned Tables

 You can copy the transportable tablespace of a non-partitioned table from one server to another by exporting the tablespace file from the original server, and then importing the tablespace file into the new server.

 #### Exporting Transportable Tablespaces for Non-partitioned Tables

 You can export a non-partitioned table by locking the table and copying the table's `.ibd` and `.cfg` files from the relevant [tablespace location](#file-per-table-tablespace-locations) for the table to a backup location. For example, the process would go like this:

 * First, use the [FLUSH TABLES ... FOR EXPORT](../flush-tables-for-export/index) statement on the target table:

 
```
FLUSH TABLES test.t1 FOR EXPORT;

```

This forces the server to close the table and provides your connection with a read lock on the table.

 * Then, while your connection still holds the lock on the table, copy the tablespace file and the metadata file to a safe directory:

 
```
# cp /data/contacts/test/t1.ibd /data/saved-tablespaces/
# cp /data/contacts/test/t1.cfg /data/saved-tablespaces/

```

* Then, once you've copied the files, you can release the lock with [UNLOCK TABLES](../lock-tables-and-unlock-tables/index):

 
```
UNLOCK TABLES;

```

#### Importing Transportable Tablespaces for Non-partitioned Tables

 You can import a non-partitioned table by discarding the table's original tablespace, copying the table's `.ibd` and `.cfg` files from the backup location to the relevant [tablespace location](#file-per-table-tablespace-locations) for the table, and then telling the server to import the tablespace. For example, the process would go like this:

 * First, on the destination server, you need to create a copy of the table. Use the same [CREATE TABLE](../create-table/index) statement that was used to create the table on the original server:

 
```
CREATE TABLE test.t1 (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(50)
) ENGINE=InnoDB;

```

* Then, use [ALTER TABLE ... DISCARD TABLESPACE](../alter-table/index#discard-tablespace) to discard the new table's tablespace:

 
```
ALTER TABLE test.t1 DISCARD TABLESPACE;

```

* Then, copy the `.ibd` and `.cfg` files from the original server to the relevant directory on the target MariaDB Server:

 
```
# scp /data/tablespaces/t1.ibd target-server.com:/var/lib/mysql/test/
# scp /data/tablespaces/t1.cfg target-server.com:/var/lib/mysql/test/

```


File-per-table tablespaces can be imported with just the `.ibd` file in many cases. If you do not have the tablespace's `.cfg` file for whatever reason, then it is usually worth trying to import the tablespace with just the `.ibd` file.

 
* Then, once the files are in the proper directory on the target server, use [ALTER TABLE ... IMPORT TABLESPACE](../alter-table/index#import-tablespace) to import the new table's tablespace:

 
```
ALTER TABLE test.t1 IMPORT TABLESPACE;

```

### Copying Transportable Tablespaces for Partitioned Tables

 Currently, MariaDB does not directly support the transport of tablespaces from partitioned tables. See [MDEV-10568](https://jira.mariadb.org/browse/MDEV-10568) for more information about that. It is still possible to transport partitioned tables if we use a workaround. You can copy the transportable tablespaces of a partitioned table from one server to another by exporting the tablespace file of each partition from the original server, and then importing the tablespace file of each partition into the new server.

 #### Exporting Transportable Tablespaces for Partitioned Tables

 You can export a partitioned table by locking the table and copying the `.ibd` and `.cfg` files of each partition from the relevant [tablespace location](#file-per-table-tablespace-locations) for the partition to a backup location. For example, the process would go like this:

 * First, let's create a test table with some data on the original server:

 
```
CREATE TABLE test.t2 (
   employee_id INT,
   name VARCHAR(50)
) ENGINE=InnoDB
PARTITION BY RANGE (employee_id) (
   PARTITION p0 VALUES LESS THAN (6),
   PARTITION p1 VALUES LESS THAN (11),
   PARTITION p2 VALUES LESS THAN (16),
   PARTITION p3 VALUES LESS THAN MAXVALUE
);

INSERT INTO test.t2 (name, employee_id) VALUES
   ('Geoff Montee', 1), 
   ('Chris Calendar', 6),
   ('Kyle Joiner', 11), 
   ('Will Fong', 16);

```

* Then, we need to export the partitioned tablespace from the original server, which follows the same process as exporting non-partitioned tablespaces. That means that we need to use the [FLUSH TABLES ... FOR EXPORT](../flush-tables-for-export/index) statement on the target table:

 
```
FLUSH TABLES test.t2 FOR EXPORT;

```

This forces the server to close the table and provides your connection with a read lock on the table.

 * Then, if we grep the database directory in the data directory for the newly created `t2` table, we can see a number of `.ibd` and `.cfg` files for the table:

 
```
# ls -l /var/lib/mysql/test/ | grep t2
total 428
-rw-rw---- 1 mysql mysql 827 Dec 5 16:08 t2.frm
-rw-rw---- 1 mysql mysql 48 Dec 5 16:08 t2.par
-rw-rw---- 1 mysql mysql 579 Dec 5 18:47 t2#P#p0.cfg
-rw-r----- 1 mysql mysql 98304 Dec 5 16:43 t2#P#p0.ibd
-rw-rw---- 1 mysql mysql 579 Dec 5 18:47 t2#P#p1.cfg
-rw-rw---- 1 mysql mysql 98304 Dec 5 16:08 t2#P#p1.ibd
-rw-rw---- 1 mysql mysql 579 Dec 5 18:47 t2#P#p2.cfg
-rw-rw---- 1 mysql mysql 98304 Dec 5 16:08 t2#P#p2.ibd
-rw-rw---- 1 mysql mysql 579 Dec 5 18:47 t2#P#p3.cfg
-rw-rw---- 1 mysql mysql 98304 Dec 5 16:08 t2#P#p3.ibd

```

* Then, while our connection still holds the lock on the table, we need to copy the tablespace files and the metadata files to a safe directory:

 
```
$ mkdir /tmp/backup
$ sudo cp /var/lib/mysql/test/t2*.ibd /tmp/backup
$ sudo cp /var/lib/mysql/test/t2*.cfg /tmp/backup

```

* Then, once we've copied the files, we can release the lock with [UNLOCK TABLES](../lock-tables-and-unlock-tables/index):

 
```
UNLOCK TABLES;

```

#### Importing Transportable Tablespaces for Partitioned Tables

 You can import a partitioned table by creating a placeholder table, discarding the placeholder table's original tablespace, copying the partition's `.ibd` and `.cfg` files from the backup location to the relevant [tablespace location](#file-per-table-tablespace-locations) for the placeholder table, and then telling the server to import the tablespace. At that point, the server can exchange the tablespace for the placeholder table with the one for the partition. For example, the process would go like this:

 * First, we need to copy the saved tablespace files from the original server to the target server:

 
```
$ scp /tmp/backup/t2* user@target-host:/tmp/backup

```

* Then, we need to import the partitioned tablespaces onto the target server. The import process for partitioned tables is more complicated than the import process for non-partitioned tables. To start with, if it doesn't already exist, then we need to create a partitioned table on the target server that matches the partitioned table on the original server:

 
```
CREATE TABLE test.t2 (
   employee_id INT,
   name VARCHAR(50)
) ENGINE=InnoDB
PARTITION BY RANGE (employee_id) (
   PARTITION p0 VALUES LESS THAN (6),
   PARTITION p1 VALUES LESS THAN (11),
   PARTITION p2 VALUES LESS THAN (16),
   PARTITION p3 VALUES LESS THAN MAXVALUE
);

```

* Then, using this table as a model, we need to create a placeholder of this table with the same structure that does not use partitioning. This can be done with a [CREATE TABLE... AS SELECT](../create-table/index#create-select) statement:

 
```
CREATE TABLE test.t2_placeholder LIKE test.t2;
ALTER TABLE test.t2_placeholder REMOVE PARTITIONING;

```

This statement will create a new table called `t2_placeholder` that has the same schema structure as `t2`, but it does not use partitioning and it contains no rows.

 ##### For Each Partition

 From this point forward, the rest of our steps need to happen for each individual partition. For each partition, we need to do the following process:

 * First, we need to use [ALTER TABLE ... DISCARD TABLESPACE](../alter-table/index#discard-tablespace) to discard the placeholder table's tablespace:

 
```
ALTER TABLE test.t2_placeholder DISCARD TABLESPACE;

```

* Then, copy the `.ibd` and `.cfg` files for the next partition to the relevant directory for the `t2_placeholder` table on the target MariaDB Server:

 
```
# cp /tmp/backup/t2#P#p0.cfg /var/lib/mysql/test/t2_placeholder.cfg
# cp /tmp/backup/t2#P#p0.ibd /var/lib/mysql/test/t2_placeholder.ibd
# chown mysql:mysql /var/lib/mysql/test/t2_placeholder*

```


File-per-table tablespaces can be imported with just the `.ibd` file in many cases. If you do not have the tablepace's `.cfg` file for whatever reason, then it is usually worth trying to import the tablespace with just the `.ibd` file.

 
* Then, once the files are in the proper directory on the target server, we need to use [ALTER TABLE ... IMPORT TABLESPACE](../alter-table/index#import-tablespace) to import the new table's tablespace:

 
```
ALTER TABLE test.t2_placeholder IMPORT TABLESPACE;

```

The placeholder table now contains data from the `p0` partition on the source server.

 
```
SELECT * FROM test.t2_placeholder;

+-------------+--------------+
| employee_id | name         |
+-------------+--------------+
|           1 | Geoff Montee |
+-------------+--------------+

```

* Then, it's time to transfer the partition from the placeholder to the target table. This can be done with an [ALTER TABLE... EXCHANGE PARTITION](../alter-table/index#exchange-partition) statement:

 
```
ALTER TABLE test.t2 EXCHANGE PARTITION p0 WITH TABLE test.t2_placeholder;

```

The target table now contains the first partition from the source table.

 
```
SELECT * FROM test.t2;

+-------------+--------------+
| employee_id | name         |
+-------------+--------------+
|           1 | Geoff Montee |
+-------------+--------------+

```

* Repeat this procedure for each partition you want to import. For each partition, we need to discard the placeholder table's tablespace, and then import the partitioned table's tablespace into the placeholder table, and then exchange the tablespaces between the placeholder table and the partition of our target table.

 When this process is complete for all partitions, the target table will contain the imported data:

 
```
SELECT * FROM test.t2;

+-------------+----------------+
| employee_id | name           |
+-------------+----------------+
|           1 | Geoff Montee   |
|           6 | Chris Calendar |
|          11 | Kyle Joiner    |
|          16 | Will Fong      |
+-------------+----------------+

```

* Then, we can remove the placeholder table from the database:

 
```
DROP TABLE test.t2_placeholder;

```

### Known Problems with Copying Transportable Tablespaces

 #### Differing Storage Formats for Temporal Columns

 [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) added the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) system variable, which enables a new MySQL 5.6-compatible storage format for the [TIME](../time/index), [DATETIME](../datetime/index) and [TIMESTAMP](../timestamp/index) data types.

 If a file-per-tablespace file contains columns that use one or more of these temporal data types and if the tablespace file's original table was created with a certain storage format for these columns, then the tablespace file can only be imported into tables that were also created with the same storage format for these columns as the original table. Otherwise, you will see errors like the following:

 
```
ALTER TABLE dt_test IMPORT TABLESPACE;
ERROR 1808 (HY000): Schema mismatch (Column dt precise type mismatch.)

```

See [MDEV-15225](https://jira.mariadb.org/browse/MDEV-15225) for more information.

 See the pages for the [TIME](../time/index), [DATETIME](../datetime/index) and [TIMESTAMP](../timestamp/index) data types to determine how to update the storage format for temporal columns in tables that were created before [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) or that were created with [mysql56\_temporal\_format=OFF](../server-system-variables/index#mysql56_temporal_format).

 #### Differing ROW\_FORMAT Values

 InnoDB file-per-table tablespaces can use different [row formats](../xtradbinnodb-storage-formats/index). A specific row format can be specified when creating a table either by setting the [ROW\_FORMAT](../create-table/index#row_format) table option or by the setting the [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) system variable. See [Setting a Table's Row Format](../innodb-storage-formats/index#setting-a-tables-row-format) for more information on how to set an InnoDB table's row format.

 If a file-per-tablespace file was created with a certain row format, then the tablespace file can only be imported into tables that were created with the same row format as the original table. Otherwise, you will see errors like the following:

 
```
ALTER TABLE t0 IMPORT TABLESPACE;
ERROR 1808 (HY000): Schema mismatch (Expected FSP_SPACE_FLAGS=0x21, .ibd file contains 0x0.)

```

The error message is a bit more descriptive in [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/) and later:

 
```
ALTER TABLE t0 IMPORT TABLESPACE;
ERROR 1808 (HY000): Schema mismatch (Table flags don't match, server table has 0x1 and the meta-data file has 0x0; .cfg file uses ROW_FORMAT=REDUNDANT)

```

Be sure to check a tablespace's row format before moving it from one server to another. Keep in mind that the default row format can change between major versions of MySQL or MariaDB. See [Checking a Table's Row Format](../innodb-storage-formats/index#checking-a-tables-row-format) for information on how to check an InnoDB table's row format.

 See [MDEV-15049](https://jira.mariadb.org/browse/MDEV-15049) and [MDEV-16851](https://jira.mariadb.org/browse/MDEV-16851) for more information.

 #### Foreign Key Constraints

 DISCARD on a table with foreign key constraints is only possible after disabling [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks):

 
```
SET SESSION foreign_key_checks=0;
ALTER TABLE t0 DISCARD TABLESPACE;

```

IMPORT on the other hand does not enforce foreign key constraints. So when importing tablespaces, referential integrity can only be guaranteed to import all tables bound by foreign key constraint at the same time, from an EXPORT of those tables taken with the same transactional state.

 Tablespace Encryption
---------------------

 MariaDB supports data-at-rest encryption for the InnoDB storage engine. When enabled, the Server encrypts data before writing it to the tablespace and decrypts reads from the tablespace before returning result-sets. This means that a malicious user attempting to exfiltrate sensitive data won't be able to import the tablespace onto a different server as shown above without the encryption key.

 For more information on data encryption, see [Encrypting Data for InnoDB](../encrypting-data-for-innodb-xtradb/index).

 See Also
--------

 * [Geoff Montee:Importing InnoDB Partitions in MySQL 5.6 and MariaDB 10.0/10.1](http://www.geoffmontee.com/importing-innodb-partitions-in-mysql-5-6-and-mariadb-10-010-1/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-file-per-table-tablespaces/>

BLACKHOLE
=========

    The `BLACKHOLE` storage engine accepts data but does not store it and always returns an empty result.

 A table using the `BLACKHOLE` storage engine consists of a single .frm table format file, but no associated data or index files.

 This storage engine can be useful, for example, if you want to run complex filtering rules on a slave without incurring any overhead on a master. The master can run a `BLACKHOLE` storage engine, with the data replicated to the slave for processing.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'ha_blackhole';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = ha_blackhole

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'ha_blackhole';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Using the BLACKHOLE Storage Engine
----------------------------------

 ### Using with DML

 [INSERT](../insert/index), [UPDATE](../update/index), and [DELETE](../delete/index) statements all work with the `BLACKHOLE` storage engine. However, no data changes are actually applied.

 ### Using with Replication

 If the binary log is enabled, all SQL statements will be logged as usual, and replicated to any slave servers. However, since rows are not stored, it is important to use statement-based rather than the row or mixed format, as [UPDATE](../update/index) and [DELETE](../delete/index) statements are neither logged nor replicated. See [Binary Log Formats](../binary-log-formats/index).

 ### Using with Triggers

 Some [triggers](../triggers/index) work with the `BLACKHOLE` storage engine.

 `BEFORE` [triggers](../triggers/index) for [INSERT](../insert/index) statements are still activated.

 [Triggers](../triggers/index) for [UPDATE](../update/index) and [DELETE](../delete/index) statements are **not** activated.

 [Triggers](../triggers/index) with the `FOR EACH ROW` clause do not apply, since the tables have no rows.

 ### Using with Foreign Keys

 Foreign keys are not supported. If you convert an [InnoDB](../innodb/index) table to `BLACKHOLE`, then the foreign keys will disappear. If you convert the same table back to InnoDB, then you will have to recreate them.

 ### Using with Virtual Columns

 If you convert an [InnoDB](../innodb/index) table which contains [virtual columns](../virtual-columns/index) to `BLACKHOLE`, then it produces an error.

 ### Using with AUTO\_INCREMENT

 Because a BLACKHOLE table does not store data, it will not maintain the [AUTO\_INCREMENT](../auto_increment/index) value. If you are replicating to a table that can handle `AUTO_INCREMENT` columns, and are not explicitly setting the primary key auto-increment value in the [INSERT](../insert/index) query, or using the [SET](../set/index) [INSERT\_ID](../server-system-variables/index#insert_id) statement, inserts will fail on the slave due to duplicate keys.

 Limits
------

 The maximum key size is:

 * 3500 bytes (>= [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10148-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/) and [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/))
* 1000 bytes (<= [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10147-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/), [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10415-release-notes/) and [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/)).

 Examples
--------

 
```
CREATE TABLE table_name (
   id int unsigned primary key not null,
   v varchar(30)
) ENGINE=BLACKHOLE;

INSERT INTO table_name VALUES (1, 'bob'),(2, 'jane');

SELECT * FROM table_name;
Empty set (0.001 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/blackhole/>

MEMORY Storage Engine
=====================

     Contents of the MEMORY storage engine (previously known as HEAP) are stored in memory rather than on disk.

 It is best-used for read-only caches of data from other tables, or for temporary work areas.

 Since the data is stored in memory, it is highly vulnerable to power outages or hardware failure, and is unsuitable for permanent data storage. In fact, after a server restart, `MEMORY` tables will be recreated (because the definition file is stored on disk), but they will be empty. It is possible to re-populate them with a query using the `--init-file` server startup option.

 Variable-length types like [VARCHAR](../varchar/index) can be used in MEMORY tables. [BLOB](../blob/index) or [TEXT](../text/index) columns are not supported for MEMORY tables.

 Memory Usage
------------

 The maximum total size of MEMORY tables cannot exceed the [max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size) system server variable. When a table is created this value applies to that table, and when the server is restarted this value applies to existing tables. Changing this value has no effect on existing tables. However, executing a `ALTER TABLE ... ENGINE=MEMORY` statement applies the current value of `max_heap_table_size` to the table. Also, it is possible to change the session value of `max_heap_table_size` before creating a table, to make sure that tables created by other sessions are not affected.

 The `MAX_ROWS` table option provides a hint about the number of rows you plan to store in them. This is not a hard limit that cannot be exceeded, and does not allow to exceed `max_heap_table_size`. The storage engine uses max\_heap\_table\_size and MAX\_ROWS to calculate the maximum memory that could be allocated for the table.

 Memory allocated to a MEMORY table is freed by running [DROP TABLE](../drop-table/index) or [TRUNCATE TABLE](../truncate-table/index), or rebuilding with [ALTER TABLE tbl\_name ENGINE = MEMORY](../alter-table/index). When rows are deleted, space is not automatically freed. 

 Index Type
----------

 The MEMORY storage engine permits indexes to be either B-tree or Hash. Hash is the default type for MEMORY. See [Storage Engine index types](../storage-engine-index-types/index) for more on their characteristics.

 A MEMORY table can have up to 64 indexes, 16 columns for each index and a maximum key length of 3072 bytes.

 Replication
-----------

 MEMORY tables are lost when a server restarts. In order to achieve this result in [replication](../standard-replication/index), the first time a primary uses a MEMORY table after a restart, it writes a DELETE statement for that table to the binary log, so that replicas are also emptied.

 Example
-------

 The following example shows how to create a `MEMORY` table with a given maximum size, as described above.

 
```
SET max_heap_table_size = 1024*516;

CREATE TABLE t (a VARCHAR(10), b INT) ENGINE = MEMORY;

SET max_heap_table_size = @@max_heap_table_size;

```

See Also
--------

 * [Performance of MEMORY tables](../performance-of-memory-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/memory-storage-engine/>

ALTER TABLE
===========

    Syntax
------

 
```
ALTER [ONLINE] [IGNORE] TABLE [IF EXISTS] tbl_name
    [WAIT n | NOWAIT]
    alter_specification [, alter_specification] ...
alter_specification:
    table_option ...
  | ADD [COLUMN] [IF NOT EXISTS] col_name column_definition
        [FIRST | AFTER col_name ]
  | ADD [COLUMN] [IF NOT EXISTS] (col_name column_definition,...)
  | ADD {INDEX|KEY} [IF NOT EXISTS] [index_name]
        [index_type] (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]] PRIMARY KEY
        [index_type] (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]]
        UNIQUE [INDEX|KEY] [index_name]
        [index_type] (index_col_name,...) [index_option] ...
  | ADD FULLTEXT [INDEX|KEY] [index_name]
        (index_col_name,...) [index_option] ...
  | ADD SPATIAL [INDEX|KEY] [index_name]
        (index_col_name,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]]
        FOREIGN KEY [IF NOT EXISTS] [index_name] (index_col_name,...)
        reference_definition
  | ADD PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)
  | ALTER [COLUMN] col_name SET DEFAULT literal | (expression)
  | ALTER [COLUMN] col_name DROP DEFAULT
  | ALTER {INDEX|KEY} index_name [NOT] INVISIBLE
  | CHANGE [COLUMN] [IF EXISTS] old_col_name new_col_name column_definition
        [FIRST|AFTER col_name]
  | MODIFY [COLUMN] [IF EXISTS] col_name column_definition
        [FIRST | AFTER col_name]
  | DROP [COLUMN] [IF EXISTS] col_name [RESTRICT|CASCADE]
  | DROP PRIMARY KEY
  | DROP {INDEX|KEY} [IF EXISTS] index_name
  | DROP FOREIGN KEY [IF EXISTS] fk_symbol
  | DROP CONSTRAINT [IF EXISTS] constraint_name
  | DISABLE KEYS
  | ENABLE KEYS
  | RENAME [TO] new_tbl_name
  | ORDER BY col_name [, col_name] ...
  | RENAME COLUMN old_col_name TO new_col_name
  | RENAME {INDEX|KEY} old_index_name TO new_index_name
  | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
  | [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | DISCARD TABLESPACE
  | IMPORT TABLESPACE
  | ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}
  | LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
  | FORCE
  | partition_options
  | CONVERT TABLE normal_table TO partition_definition
  | CONVERT PARTITION partition_name TO TABLE tbl_name
  | ADD PARTITION [IF NOT EXISTS] (partition_definition)
  | DROP PARTITION [IF EXISTS] partition_names
  | COALESCE PARTITION number
  | REORGANIZE PARTITION [partition_names INTO (partition_definitions)]
  | ANALYZE PARTITION partition_names
  | CHECK PARTITION partition_names
  | OPTIMIZE PARTITION partition_names
  | REBUILD PARTITION partition_names
  | REPAIR PARTITION partition_names
  | EXCHANGE PARTITION partition_name WITH TABLE tbl_name
  | REMOVE PARTITIONING
  | ADD SYSTEM VERSIONING
  | DROP SYSTEM VERSIONING
index_col_name:
    col_name [(length)] [ASC | DESC]
index_type:
    USING {BTREE | HASH | RTREE}
index_option:
    [ KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | CLUSTERING={YES| NO} ]
  [ IGNORED | NOT IGNORED ]
table_options:
    table_option [[,] table_option] ...
```
 Description
-----------

 `ALTER TABLE` enables you to change the structure of an existing table. For example, you can add or delete columns, create or destroy indexes, change the type of existing columns, or rename columns or the table itself. You can also change the comment for the table and the storage engine of the table.

 If another connection is using the table, a [metadata lock](../metadata-locking/index) is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.

 When adding a `UNIQUE` index on a column (or a set of columns) which have duplicated values, an error will be produced and the statement will be stopped. To suppress the error and force the creation of `UNIQUE` indexes, discarding duplicates, the [IGNORE](../ignore/index) option can be specified. This can be useful if a column (or a set of columns) should be UNIQUE but it contains duplicate values; however, this technique provides no control on which rows are preserved and which are deleted. Also, note that `IGNORE` is accepted but ignored in `ALTER TABLE ... EXCHANGE PARTITION` statements.

 This statement can also be used to rename a table. For details see [RENAME TABLE](../rename-table/index).

 When an index is created, the storage engine may use a configurable buffer in the process. Incrementing the buffer speeds up the index creation. [Aria](../aria/index) and [MyISAM](../myisam/index) allocate a buffer whose size is defined by [aria\_sort\_buffer\_size](../aria-system-variables/index#aria_sort_buffer_size) or [myisam\_sort\_buffer\_size](../myisam-system-variables/index#myisam_sort_buffer_size), also used for [REPAIR TABLE](../repair-table/index). [InnoDB](../innodb/index) allocates three buffers whose size is defined by [innodb\_sort\_buffer\_size](../innodb-system-variables/index#innodb_sort_buffer_size).

 Privileges
----------

 Executing the `ALTER TABLE` statement generally requires at least the [ALTER](../grant/index#table-privileges) privilege for the table or the database..

 If you are renaming a table, then it also requires the [DROP](../grant/index#table-privileges), [CREATE](../grant/index#table-privileges) and [INSERT](../grant/index#table-privileges) privileges for the table or the database as well.

 Online DDL
----------

 Online DDL is supported with the [ALGORITHM](#algorithm) and [LOCK](#lock) clauses.

 See [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index) for more information on online DDL with [InnoDB](../innodb/index).

 ### ALTER ONLINE TABLE

 ALTER ONLINE TABLE also works for partitioned tables.

 Online `ALTER TABLE` is available by executing the following:

 
```
ALTER ONLINE TABLE ...;

```

This statement has the following semantics:

 This statement is equivalent to the following:

 
```
ALTER TABLE ... LOCK=NONE;

```

See the [LOCK](#lock) alter specification for more information.

 This statement is equivalent to the following:

 
```
ALTER TABLE ... ALGORITHM=INPLACE;

```

See the [ALGORITHM](#algorithm) alter specification for more information.

 WAIT/NOWAIT
-----------

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 IF EXISTS
---------

 The `IF EXISTS` and `IF NOT EXISTS` clauses are available for the following:

 
```
ADD COLUMN       [IF NOT EXISTS]
ADD INDEX        [IF NOT EXISTS]
ADD FOREIGN KEY  [IF NOT EXISTS]
ADD PARTITION    [IF NOT EXISTS]
CREATE INDEX     [IF NOT EXISTS]
DROP COLUMN      [IF EXISTS]
DROP INDEX       [IF EXISTS]
DROP FOREIGN KEY [IF EXISTS]
DROP PARTITION   [IF EXISTS]
CHANGE COLUMN    [IF EXISTS]
MODIFY COLUMN    [IF EXISTS]
DROP INDEX       [IF EXISTS]
```

When `IF EXISTS` and `IF NOT EXISTS` are used in clauses, queries will not report errors when the condition is triggered for that clause. A warning with the same message text will be issued and the ALTER will move on to the next clause in the statement (or end if finished).

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**If this is directive is used after `ALTER ... TABLE`, one will not get an error if the table doesn't exist.

 
Column Definitions
------------------

 See [CREATE TABLE: Column Definitions](../create-table/index#column-definitions) for information about column definitions.

 Index Definitions
-----------------

 See [CREATE TABLE: Index Definitions](../create-table/index#index-definitions) for information about index definitions.

 The [CREATE INDEX](../create-index/index) and [DROP INDEX](../drop-index/index) statements can also be used to add or remove an index.

 Character Sets and Collations
-----------------------------

 
```
CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
[DEFAULT] CHARACTER SET [=] charset_name
[DEFAULT] COLLATE [=] collation_name
```

See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on setting the [character sets and collations](../character-sets/index).

 Alter Specifications
--------------------

 ### Table Options

 See [CREATE TABLE: Table Options](../create-table/index#table-options) for information about table options.

 ### ADD COLUMN

 
```
... ADD COLUMN [IF NOT EXISTS]  (col_name column_definition,...)
```

Adds a column to the table. The syntax is the same as in [CREATE TABLE](../create-table/index). If you are using `IF NOT_EXISTS` the column will not be added if it was not there already. This is very useful when doing scripts to modify tables.

 The `FIRST` and `AFTER` clauses affect the physical order of columns in the datafile. Use `FIRST` to add a column in the first (leftmost) position, or `AFTER` followed by a column name to add the new column in any other position. Note that, nowadays, the physical position of a column is usually irrelevant.

 See also [Instant ADD COLUMN for InnoDB](../instant-add-column-for-innodb/index).

 ### DROP COLUMN

 
```
... DROP COLUMN [IF EXISTS] col_name [CASCADE|RESTRICT]
```

Drops the column from the table. If you are using `IF EXISTS` you will not get an error if the column didn't exist. If the column is part of any index, the column will be dropped from them, except if you add a new column with identical name at the same time. The index will be dropped if all columns from the index were dropped. If the column was used in a view or trigger, you will get an error next time the view or trigger is accessed. Dropping a column that is part of a multi-column `UNIQUE` constraint is not permitted. For example:

 
```
CREATE TABLE a (
  a int,
  b int,
  primary key (a,b)
);

ALTER TABLE x DROP COLUMN a;
[42000][1072] Key column 'A' doesn't exist in table

```

The reason is that dropping column `a` would result in the new constraint that all values in column `b` be unique. In order to drop the column, an explicit `DROP PRIMARY KEY` and `ADD PRIMARY KEY` would be required. Up until [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), the column was dropped and the additional constraint applied, resulting in the following structure:

 
```
ALTER TABLE x DROP COLUMN a;
Query OK, 0 rows affected (0.46 sec)

DESC x;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| b     | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+

```


**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**[MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) supports instant DROP COLUMN. DROP COLUMN of an indexed column would imply [DROP INDEX](../drop-index/index) (and in the case of a non-UNIQUE multi-column index, possibly ADD INDEX). These will not be allowed with [ALGORITHM=INSTANT](#algorithm), but unlike before, they can be allowed with [ALGORITHM=NOCOPY](#algorithm)

 
`RESTRICT` and `CASCADE` are allowed to make porting from other database systems easier. In MariaDB, they do nothing.

 ### MODIFY COLUMN

 Allows you to modify the type of a column. The column will be at the same place as the original column and all indexes on the column will be kept. Note that when modifying column, you should specify all attributes for the new column.

 
```
CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY((a));
ALTER TABLE t1 MODIFY a BIGINT UNSIGNED AUTO_INCREMENT;

```

### CHANGE COLUMN

 Works like `MODIFY COLUMN` except that you can also change the name of the column. The column will be at the same place as the original column and all index on the column will be kept.

 
```
CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(a));
ALTER TABLE t1 CHANGE a b BIGINT UNSIGNED AUTO_INCREMENT;

```

### ALTER COLUMN

 This lets you change column options.

 
```
CREATE TABLE t1 (a INT UNSIGNED AUTO_INCREMENT, b varchar(50), PRIMARY KEY(a));
ALTER TABLE t1 ALTER b SET DEFAULT 'hello';

```

### RENAME INDEX/KEY

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), it is possible to rename an index using the `RENAME INDEX` (or `RENAME KEY`) syntax, for example:

 
```
ALTER TABLE t1 RENAME INDEX i_old TO i_new;

```


### RENAME COLUMN

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), it is possible to rename a column using the `RENAME COLUMN` syntax, for example:

 
```
ALTER TABLE t1 RENAME COLUMN c_old TO c_new;

```


### ADD PRIMARY KEY

 Add a primary key.

 For `PRIMARY KEY` indexes, you can specify a name for the index, but it is silently ignored, and the name of the index is always `PRIMARY`.

 See [Getting Started with Indexes: Primary Key](../getting-started-with-indexes/index#primary-key) for more information.

 ### DROP PRIMARY KEY

 Drop a primary key.

 For `PRIMARY KEY` indexes, you can specify a name for the index, but it is silently ignored, and the name of the index is always `PRIMARY`.

 See [Getting Started with Indexes: Primary Key](../getting-started-with-indexes/index#primary-key) for more information.

 ### ADD FOREIGN KEY

 Add a foreign key.

 For `FOREIGN KEY` indexes, a reference definition must be provided.

 For `FOREIGN KEY` indexes, you can specify a name for the constraint, using the `CONSTRAINT` keyword. That name will be used in error messages.

 First, you have to specify the name of the target (parent) table and a column or a column list which must be indexed and whose values must match to the foreign key's values. The `MATCH` clause is accepted to improve the compatibility with other DBMS's, but has no meaning in MariaDB. The `ON DELETE` and `ON UPDATE` clauses specify what must be done when a `DELETE` (or a `REPLACE`) statements attempts to delete a referenced row from the parent table, and when an `UPDATE` statement attempts to modify the referenced foreign key columns in a parent table row, respectively. The following options are allowed:

 * `RESTRICT`: The delete/update operation is not performed. The statement terminates with a 1451 error (SQLSTATE '2300').
* `NO ACTION`: Synonym for `RESTRICT`.
* `CASCADE`: The delete/update operation is performed in both tables.
* `SET NULL`: The update or delete goes ahead in the parent table, and the corresponding foreign key fields in the child table are set to `NULL`. (They must not be defined as `NOT NULL` for this to succeed).
* `SET DEFAULT`: This option is implemented only for the legacy PBXT storage engine, which is disabled by default and no longer maintained. It sets the child table's foreign key fields to their `DEFAULT` values when the referenced parent table key entries are updated or deleted.

 If either clause is omitted, the default behavior for the omitted clause is `RESTRICT`.

 See [Foreign Keys](../foreign-keys/index) for more information.

 ### DROP FOREIGN KEY

 Drop a foreign key.

 See [Foreign Keys](../foreign-keys/index) for more information.

 ### ADD INDEX

 Add a plain index.

 Plain indexes are regular indexes that are not unique, and are not acting as a primary key or a foreign key. They are also not the "specialized" `FULLTEXT` or `SPATIAL` indexes.

 See [Getting Started with Indexes: Plain Indexes](../getting-started-with-indexes/index#plain-indexes) for more information.

 ### DROP INDEX

 Drop a plain index.

 Plain indexes are regular indexes that are not unique, and are not acting as a primary key or a foreign key. They are also not the "specialized" `FULLTEXT` or `SPATIAL` indexes.

 See [Getting Started with Indexes: Plain Indexes](../getting-started-with-indexes/index#plain-indexes) for more information.

 ### ADD UNIQUE INDEX

 Add a unique index.

 The `UNIQUE` keyword means that the index will not accept duplicated values, except for NULLs. An error will raise if you try to insert duplicate values in a UNIQUE index.

 For `UNIQUE` indexes, you can specify a name for the constraint, using the `CONSTRAINT` keyword. That name will be used in error messages.

 See [Getting Started with Indexes: Unique Index](../getting-started-with-indexes/index#unique-index) for more information.

 ### DROP UNIQUE INDEX

 Drop a unique index.

 The `UNIQUE` keyword means that the index will not accept duplicated values, except for NULLs. An error will raise if you try to insert duplicate values in a UNIQUE index.

 For `UNIQUE` indexes, you can specify a name for the constraint, using the `CONSTRAINT` keyword. That name will be used in error messages.

 See [Getting Started with Indexes: Unique Index](../getting-started-with-indexes/index#unique-index) for more information.

 ### ADD FULLTEXT INDEX

 Add a `FULLTEXT` index.

 See [Full-Text Indexes](../full-text-indexes/index) for more information.

 ### DROP FULLTEXT INDEX

 Drop a `FULLTEXT` index.

 See [Full-Text Indexes](../full-text-indexes/index) for more information.

 ### ADD SPATIAL INDEX

 Add a SPATIAL index.

 See [SPATIAL INDEX](../spatial-index/index) for more information.

 ### DROP SPATIAL INDEX

 Drop a SPATIAL index.

 See [SPATIAL INDEX](../spatial-index/index) for more information.

 ### ENABLE/ DISABLE KEYS

 `DISABLE KEYS` will disable all non unique keys for the table for storage engines that support this (at least MyISAM and Aria). This can be used to [speed up inserts](../how-to-quickly-insert-data-into-mariadb/index) into empty tables.

 `ENABLE KEYS` will enable all disabled keys.

 ### RENAME TO

 Renames the table. See also [RENAME TABLE](../rename-table/index).

 ### ADD CONSTRAINT

 Modifies the table adding a [constraint](../constraint/index) on a particular column or columns.

 
```
ALTER TABLE table_name 
ADD CONSTRAINT [constraint_name] CHECK(expression);
```

Before a row is inserted or updated, all constraints are evaluated in the order they are defined. If any constraint fails, then the row will not be updated. One can use most deterministic functions in a constraint, including [UDF's](../user-defined-functions/index).

 
```
CREATE TABLE account_ledger (
	id INT PRIMARY KEY AUTO_INCREMENT,
	transaction_name VARCHAR(100),
	credit_account VARCHAR(100),
	credit_amount INT,
	debit_account VARCHAR(100),
	debit_amount INT);

ALTER TABLE account_ledger 
ADD CONSTRAINT is_balanced 
    CHECK((debit_amount + credit_amount) = 0);

```

The `constraint_name` is optional. If you don't provide one in the `ALTER TABLE` statement, MariaDB auto-generates a name for you. This is done so that you can remove it later using [DROP CONSTRAINT](#drop-constraint) clause.

 You can disable all constraint expression checks by setting the variable [check\_constraint\_checks](../server-system-variables/index#check_constraint_checks) to `OFF`. You may find this useful when loading a table that violates some constraints that you want to later find and fix in SQL.

 To view constraints on a table, query [information\_schema.TABLE\_CONSTRAINTS](../information-schema-table_constraints-table/index):

 
```
SELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE 
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 'account_ledger';

+-----------------+----------------+-----------------+
| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |
+-----------------+----------------+-----------------+
| is_balanced     | account_ledger | CHECK           |
+-----------------+----------------+-----------------+

```

### DROP CONSTRAINT

 `DROP CONSTRAINT` for `UNIQUE` and `FOREIGN KEY` [constraints](../constraint/index) was introduced in [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/) and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/).

 `DROP CONSTRAINT` for `CHECK` constraints was introduced in [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)

 Modifies the table, removing the given constraint.

 
```
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;

```

When you add a constraint to a table, whether through a [CREATE TABLE](../create-table/index#constraint-expressions) or [ALTER TABLE...ADD CONSTRAINT](#add-constraint) statement, you can either set a `constraint_name` yourself, or allow MariaDB to auto-generate one for you. To view constraints on a table, query [information\_schema.TABLE\_CONSTRAINTS](../information-schema-table_constraints-table/index). For instance,

 
```
CREATE TABLE t (
   a INT,
   b INT,
   c INT,
   CONSTRAINT CHECK(a > b),
   CONSTRAINT check_equals CHECK(a = c)); 

SELECT CONSTRAINT_NAME, TABLE_NAME, CONSTRAINT_TYPE 
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_NAME = 't';

+-----------------+----------------+-----------------+
| CONSTRAINT_NAME | TABLE_NAME     | CONSTRAINT_TYPE |
+-----------------+----------------+-----------------+
| check_equals    | t              | CHECK           |
| CONSTRAINT_1    | t              | CHECK           |
+-----------------+----------------+-----------------+

```

To remove a constraint from the table, issue an `ALTER TABLE...DROP CONSTRAINT` statement. For example,

 
```
ALTER TABLE t DROP CONSTRAINT is_unique;

```

### ADD SYSTEM VERSIONING

 Add system versioning. See [System-versioned tables](../system-versioned-tables/index).

 ### DROP SYSTEM VERSIONING

 Drop system versioning. See [System-versioned tables](../system-versioned-tables/index).

 ### ADD PERIOD FOR SYSTEM\_TIME

 See [System-versioned tables](../system-versioned-tables/index).

 ### FORCE

 `ALTER TABLE ... FORCE` can force MariaDB to re-build the table.

 In [MariaDB 5.5](../what-is-mariadb-55/index) and before, this could only be done by setting the [ENGINE](../create-table/index#storage-engine) table option to its old value. For example, for an InnoDB table, one could execute the following:

 
```
ALTER TABLE tab_name ENGINE = InnoDB;

```

The `FORCE` option can be used instead. For example, :

 
```
ALTER TABLE tab_name FORCE;

```

With InnoDB, the table rebuild will only reclaim unused space (i.e. the space previously used for deleted rows) if the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is set to `ON` (the default). If the system variable is `OFF`, then the space will not be reclaimed, but it will be-re-used for new data that's later added.

 ### CONVERT TABLE / CONVERT PARTITION

 `CONVERT TABLE` and `CONVERT PARTITION` was introduced in [MariaDB 10.7.1](https://mariadb.com/kb/en/mariadb-1071-release-notes/).

 `CONVERT PARTITION` can be used to remove a partition from a table and make this an ordinary table. For example:

 
```
ALTER TABLE partitioned_table CONVERT PARTITION part1 TO TABLE normal_table;

```

`CONVERT PARTITION` will take an existing table and move this to another table as its own partition with a specified [partition definition](../create-table/index#partitions). For example the following moves `normal_table` to a partition of `partitioned_table` with a definition that its values, based on the `PARTITION BY` of the `partitioned_table`, are less than 12345.

 
```
ALTER TABLE partitioned_table CONVERT TABLE normal_table TO PARTITION part1 VALUES LESS THAN (12345);

```

### EXCHANGE PARTITION

 This is used to exchange the contents of a partition with another table.

 This is performed by swapping the tablespaces of the partition with the other table.

 See [copying InnoDB's transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) for more information.

 ### DISCARD TABLESPACE

 This is used to discard an InnoDB table's tablespace.

 See [copying InnoDB's transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) for more information.

 ### IMPORT TABLESPACE

 This is used to import an InnoDB table's tablespace. The tablespace should have been copied from its original server after executing [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index).

 See [copying InnoDB's transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) for more information.

 `ALTER TABLE ... IMPORT` only applies to InnoDB tables. Most other popular storage engines, such as Aria and MyISAM, will recognize their data files as soon as they've been placed in the proper directory under the datadir, and no special DDL is required to import them.

 ### ALGORITHM

 The `ALTER TABLE` statement supports the `ALGORITHM` clause. This clause is one of the clauses that is used to implement online DDL. `ALTER TABLE` supports several different algorithms. An algorithm can be explicitly chosen for an `ALTER TABLE` operation by setting the `ALGORITHM` clause. The supported values are:

 * `ALGORITHM=DEFAULT` - This implies the default behavior for the specific statement, such as if no `ALGORITHM` clause is specified.
* `ALGORITHM=COPY`
* `ALGORITHM=INPLACE`
* `ALGORITHM=NOCOPY` - This was added in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).
* `ALGORITHM=INSTANT` - This was added in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).

 See [InnoDB Online DDL Overview: ALGORITHM](../innodb-online-ddl-overview/index#algorithm) for information on how the `ALGORITHM` clause affects InnoDB.

 #### ALGORITHM=DEFAULT

 The default behavior, which occurs if `ALGORITHM=DEFAULT` is specified, or if `ALGORITHM` is not specified at all, usually only makes a copy if the operation doesn't support being done in-place at all. In this case, the most efficient available algorithm will usually be used.

 However, in [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) and before, if the value of the [old\_alter\_table](../server-system-variables/index#old_alter_table) system variable is set to `ON`, then the default behavior is to perform `ALTER TABLE` operations by making a copy of the table using the old algorithm.

 In [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) and later, the [old\_alter\_table](../server-system-variables/index#old_alter_table) system variable is deprecated. Instead, the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable defines the default algorithm for `ALTER TABLE` operations.

 #### ALGORITHM=COPY

 `ALGORITHM=COPY` is the name for the original [ALTER TABLE](index) algorithm from early MariaDB versions.

 When `ALGORITHM=COPY` is set, MariaDB essentially does the following operations:

 
```
-- Create a temporary table with the new definition
CREATE TEMPORARY TABLE tmp_tab (
...
);

-- Copy the data from the original table
INSERT INTO tmp_tab
   SELECT * FROM original_tab;

-- Drop the original table
DROP TABLE original_tab;

-- Rename the temporary table, so that it replaces the original one
RENAME TABLE tmp_tab TO original_tab;

```

This algorithm is very inefficient, but it is generic, so it works for all storage engines.

 If `ALGORITHM=COPY` is specified, then the copy algorithm will be used even if it is not necessary. This can result in a lengthy table copy. If multiple [ALTER TABLE](index) operations are required that each require the table to be rebuilt, then it is best to specify all operations in a single [ALTER TABLE](index) statement, so that the table is only rebuilt once.

 #### ALGORITHM=INPLACE

 `ALGORITHM=COPY` can be incredibly slow, because the whole table has to be copied and rebuilt. `ALGORITHM=INPLACE` was introduced as a way to avoid this by performing operations in-place and avoiding the table copy and rebuild, when possible.

 When `ALGORITHM=INPLACE` is set, the underlying storage engine uses optimizations to perform the operation while avoiding the table copy and rebuild. However, `INPLACE` is a bit of a misnomer, since some operations may still require the table to be rebuilt for some storage engines. Regardless, several operations can be performed without a full copy of the table for some storage engines.

 A more accurate name would have been `ALGORITHM=ENGINE`, where `ENGINE` refers to an "engine-specific" algorithm.

 If an [ALTER TABLE](index) operation supports `ALGORITHM=INPLACE`, then it can be performed using optimizations by the underlying storage engine, but it may rebuilt.

 See [InnoDB Online DDL Operations with ALGORITHM=INPLACE](../innodb-online-ddl-operations-with-the-inplace-alter-algorithm/index) for more.

 #### ALGORITHM=NOCOPY

 `ALGORITHM=NOCOPY` was introduced in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).

 `ALGORITHM=INPLACE` can sometimes be surprisingly slow in instances where it has to rebuild the clustered index, because when the clustered index has to be rebuilt, the whole table has to be rebuilt. `ALGORITHM=NOCOPY` was introduced as a way to avoid this. 

 If an `ALTER TABLE` operation supports `ALGORITHM=NOCOPY`, then it can be performed without rebuilding the clustered index.

 If `ALGORITHM=NOCOPY` is specified for an `ALTER TABLE` operation that does not support `ALGORITHM=NOCOPY`, then an error will be raised. In this case, raising an error is preferable, if the alternative is for the operation to rebuild the clustered index, and perform unexpectedly slowly.

 See [InnoDB Online DDL Operations with ALGORITHM=NOCOPY](../innodb-online-ddl-operations-with-algorithmnocopy/index) for more.

 #### ALGORITHM=INSTANT

 `ALGORITHM=INSTANT` was introduced in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).

 `ALGORITHM=INPLACE` can sometimes be surprisingly slow in instances where it has to modify data files. `ALGORITHM=INSTANT` was introduced as a way to avoid this.

 If an `ALTER TABLE` operation supports `ALGORITHM=INSTANT`, then it can be performed without modifying any data files.

 If `ALGORITHM=INSTANT` is specified for an `ALTER TABLE` operation that does not support `ALGORITHM=INSTANT`, then an error will be raised. In this case, raising an error is preferable, if the alternative is for the operation to modify data files, and perform unexpectedly slowly.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT](../innodb-online-ddl-operations-with-algorithminstant/index) for more.

 ### LOCK

 The `ALTER TABLE` statement supports the `LOCK` clause. This clause is one of the clauses that is used to implement online DDL. `ALTER TABLE` supports several different locking strategies. A locking strategy can be explicitly chosen for an `ALTER TABLE` operation by setting the `LOCK` clause. The supported values are:

 * `DEFAULT`: Acquire the least restrictive lock on the table that is supported for the specific operation. Permit the maximum amount of concurrency that is supported for the specific operation.
* `NONE`: Acquire no lock on the table. Permit **all** concurrent DML. If this locking strategy is not permitted for an operation, then an error is raised.
* `SHARED`: Acquire a read lock on the table. Permit **read-only** concurrent DML. If this locking strategy is not permitted for an operation, then an error is raised.
* `EXCLUSIVE`: Acquire a write lock on the table. Do **not** permit concurrent DML.

 Different storage engines support different locking strategies for different operations. If a specific locking strategy is chosen for an `ALTER TABLE` operation, and that table's storage engine does not support that locking strategy for that specific operation, then an error will be raised.

 If the `LOCK` clause is not explicitly set, then the operation uses `LOCK=DEFAULT`.

 [ALTER ONLINE TABLE](alter-online-table) is equivalent to `LOCK=NONE`. Therefore, the [ALTER ONLINE TABLE](alter-online-table) statement can be used to ensure that your `ALTER TABLE` operation allows all concurrent DML.

 See [InnoDB Online DDL Overview: LOCK](../innodb-online-ddl-overview/index#lock) for information on how the `LOCK` clause affects InnoDB.

 Progress Reporting
------------------

 MariaDB provides progress reporting for `ALTER TABLE` statement for clients that support the new progress reporting protocol. For example, if you were using the [mariadb](../mariadb-command-line-client/index) client, then the progress report might look like this::

 
```
ALTER TABLE test ENGINE=Aria;
Stage: 1 of 2 'copy to tmp table'    46% of stage

```

The progress report is also shown in the output of the [SHOW PROCESSLIST](../show-processlist/index) statement and in the contents of the [information\_schema.PROCESSLIST](../information-schema-processlist-table/index) table.

 See [Progress Reporting](../progress-reporting/index) for more information.

 Aborting ALTER TABLE Operations
-------------------------------

 If an `ALTER TABLE` operation is being performed and the connection is killed, the changes will be rolled back in a controlled manner. The rollback can be a slow operation as the time it takes is relative to how far the operation has progressed.

 Aborting `ALTER TABLE ... ALGORITHM=COPY` was made faster in [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/) by removing excessive undo logging ([MDEV-11415](https://jira.mariadb.org/browse/MDEV-11415)). This significantly shortened the time it takes to abort a running ALTER TABLE operation, compared with earlier releases.

 Atomic ALTER TABLE
------------------

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**From [MariaDB 10.6](../what-is-mariadb-106/index), `ALTER TABLE` is atomic for most engines, including InnoDB, MyRocks, MyISAM and Aria ([MDEV-25180](https://jira.mariadb.org/browse/MDEV-25180)). This means that if there is a crash (server down or power outage) during an `ALTER TABLE` operation, after recovery, either the old table and associated triggers and status will be intact, or the new table will be active.

 In older MariaDB versions one could get leftover #sql-alter..', '#sql-backup..' or 'table\_name.frm˝' files if the system crashed during the `ALTER TABLE` operation.

 See [Atomic DDL](../atomic-ddl/index) for more information.

 
Replication
-----------

 
**MariaDB starting with [10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/)**Before [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), ALTER TABLE got fully executed on the primary first, and only then was it replicated and started executing on replicas. From [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), ALTER TABLE gains [an option](../replication-and-binary-log-system-variables/index#binlog_alter_two_phase) to replicate sooner and begin executing on replicas when it merely *starts* executing on the primary, not when it *finishes*. This way the replication lag caused by a heavy ALTER TABLE can be completely eliminated ([MDEV-11675](https://jira.mariadb.org/browse/MDEV-11675)). 

 
Examples
--------

 Adding a new column:

 
```
ALTER TABLE t1 ADD x INT;

```

Dropping a column:

 
```
ALTER TABLE t1 DROP x;

```

Modifying the type of a column:

 
```
ALTER TABLE t1 MODIFY x bigint unsigned;

```

Changing the name and type of a column:

 
```
ALTER TABLE t1 CHANGE a b bigint unsigned auto_increment;

```

Combining multiple clauses in a single ALTER TABLE statement, separated by commas:

 
```
ALTER TABLE t1 DROP x, ADD x2 INT,  CHANGE y y2 INT;

```

Changing the storage engine and adding a comment:

 
```
ALTER TABLE t1 
  ENGINE = InnoDB 
  COMMENT = 'First of three tables containing usage info';

```

Rebuilding the table (the previous example will also rebuild the table if it was already InnoDB):

 
```
ALTER TABLE t1 FORCE;

```

Dropping an index:

 
```
ALTER TABLE rooms DROP INDEX u;

```

Adding a unique index:

 
```
ALTER TABLE rooms ADD UNIQUE INDEX u(room_number);

```

From [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/), adding a primary key for an [application-time period table](../application-time-periods/index) with a [WITHOUT OVERLAPS](../application-time-periods/index#without-overlaps) constraint:

 
```
ALTER TABLE rooms ADD PRIMARY KEY(room_number, p WITHOUT OVERLAPS);

```

From [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/), ALTER query can be replicated faster with the setting of

 
```
SET @@SESSION.binlog_alter_two_phase = true;

```

prior the ALTER query. Binlog would contain two event groups

 
```
| master-bin.000001 | 495 | Gtid              |         1 |         537 | GTID 0-1-2 START ALTER                                        |
| master-bin.000001 | 537 | Query             |         1 |         655 | use `test`; alter table t add column b int, algorithm=inplace |
| master-bin.000001 | 655 | Gtid              |         1 |         700 | GTID 0-1-3 COMMIT ALTER id=2                                  |
| master-bin.000001 | 700 | Query             |         1 |         835 | use `test`; alter table t add column b int, algorithm=inplace |

```

of which the first one gets delivered to replicas before ALTER is taken to actual execution on the primary. 

 See Also
--------

 * [CREATE TABLE](../create-table/index)
* [DROP TABLE](../drop-table/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [SHOW CREATE TABLE](../show-create-table/index)
* [Instant ADD COLUMN for InnoDB](../instant-add-column-for-innodb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-table/>

Choosing the Right Storage Engine
=================================

     A high-level overview of the main reasons for choosing a particular storage engine:

 Topic List
----------

 ### General Purpose

 * [InnoDB](../innodb/index) is a good general transaction storage engine, and, from [MariaDB 10.2](../what-is-mariadb-102/index), the best choice in most cases. It is the default storage engine from [MariaDB 10.2](../what-is-mariadb-102/index). For earlier releases, XtraDB was a performance enhanced fork of InnoDB and is usually preferred.
* [Aria](../aria/index), MariaDB's more modern improvement on [MyISAM](../myisam/index), has a small footprint and allows for easy copying between systems.
* [MyISAM](../myisam/index) has a small footprint and allows for easy copying between systems. MyISAM is MySQL's oldest storage engine. There is usually little reason to use it except for legacy purposes. Aria is MariaDB's more modern improvement.
* [XtraDB](../xtradb/index) was the best choice in [MariaDB 10.1](../what-is-mariadb-101/index) and earlier in the majority of cases. It was a performance-enhanced fork of InnoDB and was MariaDB's default engine until [MariaDB 10.1](../what-is-mariadb-101/index).

 ### Scaling, Partitioning

 When you want to split your database load on several servers or optimize for scaling. We also suggest looking at [Galera](../galera/index), a synchronous multi-master cluster.

 * [Spider](../spider/index) uses partitioning to provide data sharding through multiple servers.
* [ColumnStore](../columnstore/index) utilizes a massively parallel distributed data architecture and is designed for big data scaling to process petabytes of data.
* The [MERGE](../merge/index) storage engine is a collection of identical [MyISAM](../myisam/index) tables that can be used as one. "Identical" means that all tables have identical column and index information.
* [TokuDB](../tokudb/index) is a transactional storage engine which is optimized for workloads that do not fit in memory, and provides a good compression ratio. TokuDB has been deprecated by its upstream developers, and is disabled in [MariaDB 10.5](../what-is-mariadb-105/index), and removed in [MariaDB 10.6](../what-is-mariadb-106/index)

 ### Compression / Archive

 * [MyRocks](../myrocks/index) enables greater compression than InnoDB, as well as less write amplification giving better endurance of flash storage and improving overall throughput.
* The [Archive](../archive/index) storage engine is, unsurprisingly, best used for archiving.
* [TokuDB](../tokudb/index) is a transactional storage engine which is optimized for workloads that do not fit in memory, and provides a good compression ratio. TokuDB has been deprecated by its upstream developers, and is disabled in [MariaDB 10.5](../what-is-mariadb-105/index), and removed in [MariaDB 10.6](../what-is-mariadb-106/index)

 ### Connecting to Other Data Sources

 When you want to use data not stored in a MariaDB database. 

 * [CONNECT](../connect/index) allows access to different kinds of text files and remote resources as if they were regular MariaDB tables.
* The [CSV](../csv/index) storage engine can read and append to files stored in CSV (comma-separated-values) format. However, since [MariaDB 10.0](../what-is-mariadb-100/index), CONNECT is a better choice and is more flexibly able to read and write such files.
* [FederatedX](../federatedx/index) uses libmysql to talk to the data source, the data source being a remote RDBMS. Currently, since FederatedX only uses libmysql, it can only talk to another MySQL RDBMS.
* [CassandraSE](../cassandrase/index) is a storage engine allowing access to an older version of Apache Cassandra NoSQL DBMS. It was relatively experimental, is no longer being actively developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index).

 ### Search Optimized

 Search engines optimized for search. 

 * [SphinxSE](../sphinxse/index) is used as a proxy to run statements on a remote Sphinx database server (mainly useful for advanced fulltext searches).
* [Mroonga](../mroonga/index) provides fast CJK-ready full text searching using column store.

 ### Cache, Read-only

 * [MEMORY](../memory-storage-engine/index) does not write data on-disk (all rows are lost on crash) and is best-used for read-only caches of data from other tables, or for temporary work areas. With the default [InnoDB](../innodb/index) and other storage engines having good caching, there is less need for this engine than in the past.

 ### Other Specialized Storage Engines

 * [S3 Storage Engine](../s3-storage-engine/index) is a read-only storage engine that stores its data in Amazon S3.
* [Sequence](../sequence/index) allows the creation of ascending or descending sequences of numbers (positive integers) with a given starting value, ending value and increment, creating virtual, ephemeral tables automatically when you need them.
* The [BLACKHOLE](../blackhole/index) storage engine accepts data but does not store it and always returns an empty result. This can be useful in [replication](../replication/index) environments, for example, if you want to run complex filtering rules on a slave without incurring any overhead on a master.
* [OQGRAPH](../oqgraph/index) allows you to handle hierarchies (tree structures) and complex graphs (nodes having many connections in several directions).

 Alphabetical List
-----------------

 * The [Archive](../archive/index) storage engine is, unsurprisingly, best used for archiving.
* [Aria](../aria/index), MariaDB's more modern improvement on MyISAM, has a small footprint and allows for easy copy between systems.
* The [BLACKHOLE](../blackhole/index) storage engine accepts data but does not store it and always returns an empty result. This can be useful in [replication](../replication/index) environments, for example, if you want to run complex filtering rules on a slave without incurring any overhead on a master.
* [CassandraSE](../cassandrase/index) is a storage engine allowing access to an older version of Apache Cassandra NoSQL DBMS. It was relatively experimental, is no longer being actively developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index).
* [ColumnStore](../columnstore/index) utilizes a massively parallel distributed data architecture and is designed for big data scaling to process petabytes of data.
* [CONNECT](../connect/index) allows access to different kinds of text files and remote resources as if they were regular MariaDB tables.
* The [CSV](../csv-overview/index) storage engine can read and append to files stored in CSV (comma-separated-values) format. However, since [MariaDB 10.0](../what-is-mariadb-100/index), CONNECT is a better choice and is more flexibly able to read and write such files.
* [FederatedX](../federatedx/index) uses libmysql to talk to the data source, the data source being a remote RDBMS. Currently, since FederatedX only uses libmysql, it can only talk to another MySQL RDBMS.
* [InnoDB](../innodb/index) is a good general transaction storage engine, and, from [MariaDB 10.2](../what-is-mariadb-102/index), the best choice in most cases. It is the default storage engine from [MariaDB 10.2](../what-is-mariadb-102/index). For earlier releases, XtraDB was a performance enhanced fork of InnoDB and is usually preferred.
* The [MERGE](../merge/index) storage engine is a collection of identical MyISAM tables that can be used as one. "Identical" means that all tables have identical column and index information.
* [MEMORY](../memory-storage-engine/index) does not write data on-disk (all rows are lost on crash) and is best-used for read-only caches of data from other tables, or for temporary work areas. With the default [InnoDB](../innodb/index) and other storage engines having good caching, there is less need for this engine than in the past.
* [Mroonga](../mroonga/index) provides fast CJK-ready full text searching using column store.
* [MyISAM](../myisam/index) has a small footprint and allows for easy copying between systems. MyISAM is MySQL's oldest storage engine. There is usually little reason to use it except for legacy purposes. Aria is MariaDB's more modern improvement.
* [MyRocks](../myrocks/index) enables greater compression than InnoDB, as well as less write amplification giving better endurance of flash storage and improving overall throughput.
* [OQGRAPH](../oqgraph/index) allows you to handle hierarchies (tree structures) and complex graphs (nodes having many connections in several directions).
* [S3 Storage Engine](../s3-storage-engine/index) is a read-only storage engine that stores its data in Amazon S3.
* [Sequence](../sequence/index) allows the creation of ascending or descending sequences of numbers (positive integers) with a given starting value, ending value and increment, creating virtual, ephemeral tables automatically when you need them.
* [SphinxSE](../sphinx-storage-engine/index) is used as a proxy to run statements on a remote Sphinx database server (mainly useful for advanced fulltext searches).
* [Spider](../spider/index) uses partitioning to provide data sharding through multiple servers.
* [TokuDB](../tokudb/index) is a transactional storage engine which is optimized for workloads that do not fit in memory, and provides a good compression ratio. TokuDB has been deprecated by its upstream developers, and is disabled in [MariaDB 10.5](../what-is-mariadb-105/index), and removed in [MariaDB 10.6](../what-is-mariadb-106/index)
* [XtraDB](../xtradb/index) was the best choice in [MariaDB 10.1](../what-is-mariadb-101/index) and earlier in the majority of cases. It was a performance-enhanced fork of InnoDB and was MariaDB's default engine until [MariaDB 10.1](../what-is-mariadb-101/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/choosing-the-right-storage-engine/>

Mroonga
========

   Mroonga (formerly named Groonga Storage Engine) is a storage engine that provides fast CJK-ready full text searching using column store.

  

| Title | Description |
| --- | --- |
|  [About Mroonga](../about-mroonga/index) |  Mroonga full text search storage engine.  |
|  [Mroonga Overview](../mroonga-overview/index) |  Basic Mroonga usage.  |
|  [Mroonga Status Variables](../mroonga-status-variables/index) |  Mroonga-related status variables.  |
|  [Mroonga System Variables](../mroonga-system-variables/index) |  Mroonga-related system variables.  |
|  [Mroonga User-Defined Functions](../mroonga-user-defined-functions/index) |  Mroonga user-defined functions (UDFs).  |
|  [Information Schema MROONGA\_STATS Table](../information-schema-mroonga_stats-table/index) |  Mroonga activities statistics.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga/>

Archive
========

   The `ARCHIVE` storage engine is a storage engine that uses gzip to compress rows. It is mainly used for storing large amounts of data, without indexes, with only a very small footprint. 

 A table using the `ARCHIVE` storage engine is stored in two files on disk. There's a table definition file with an extension of .frm, and a data file with the extension .ARZ. At times during optimization, a .ARN file will appear.

 New rows are inserted into a compression buffer and are flushed to disk when needed. SELECTs cause a flush. Sometimes, rows created by multi-row inserts are not visible until the statement is complete.

 `ARCHIVE` allows a maximum of one key. The key must be on an `[AUTO\_INCREMENT](../auto_increment/index)` column, and can be a `PRIMARY KEY` or a non-unique key. However, it has a limitation: it is not possible to insert a value which is lower than the next `AUTO_INCREMENT` value.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'ha_archive';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = ha_archive

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'ha_archive';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Characteristics
---------------

 * Supports [INSERT](../insert/index) and [SELECT](../select/index), but not [DELETE](../delete/index), [UPDATE](../update/index) or [REPLACE](../replace/index).
* Data is compressed with zlib as it is inserted, making it very small.
* Data is slow the select, as it needs to be uncompressed, and, besides the [query cache](../query-cache/index), there is no cache.
* Supports AUTO\_INCREMENT (since MariaDB/MySQL 5.1.6), which can be a unique or a non-unique index.
* Since MariaDB/MySQL 5.1.6, selects scan past BLOB columns unless they are specifically requested, making these queries much more efficient.
* Does not support [spatial](../spatial/index) data types.
* Does not support [transactions](../transactions/index).
* Does not support foreign keys.
* Does not support [virtual columns](../virtual-columns/index).
* No storage limit.
* Supports row locking.
* Supports [table discovery](../table-discovery/index), and the server can access ARCHIVE tables even if the corresponding `.frm` file is missing.
* [OPTIMIZE TABLE](../optimize-table/index) and [REPAIR TABLE](../repair-table/index) can be used to compress the table in its entirety, resulting in slightly better compression.
* With MariaDB, it is possible to upgrade from the MySQL 5.0 format without having to dump the tables.
* [INSERT DELAYED](../insert-delayed/index) is supported.
* Running many SELECTs during the insertions can deteriorate the compression, unless only multi-rows INSERTs and INSERT DELAYED are used.

  

| Title | Description |
| --- | --- |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/archive/>

SphinxSE
=========

   SphinxSE is a storage engine that talks to searchd (Sphinx daemon) to enable text searching.

  

| Title | Description |
| --- | --- |
|  [About SphinxSE](../about-sphinxse/index) |  About the Sphinx Storage Engine  |
|  [Installing Sphinx](../installing-sphinx/index)  |  Installing the Sphinx daemon  |
|  [Configuring Sphinx](../configuring-sphinx/index) |  Before you can get Sphinx working with the Sphinx Storage Engine on MariaDB...  |
|  [Installing and Testing SphinxSE with MariaDB](../installing-and-testing-sphinxse-with-mariadb/index) |  How to install and test SphinxSE  |
|  [Sphinx Status Variables](../sphinx-status-variables/index) |  Sphinx status variables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sphinx-storage-engine/>

Securing Communications in Galera Cluster
=========================================

    By default, Galera Cluster replicates data between each node without encrypting it. This is generally acceptable when the cluster nodes runs on the same host or in networks where security is guaranteed through other means. However, in cases where the cluster nodes exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic or get a complete copy of the data by triggering an SST. 

 To mitigate this concern, Galera Cluster allows you to encrypt data in transit as it is replicated between each cluster node using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix `ssl_`, but internally, MariaDB only supports its secure successors.

 In order to secure connections between the cluster nodes, you need to ensure that all servers were compiled with TLS support. See [Secure Connections Overview](../secure-connections-overview/index) to determine how to check whether a server was compiled with TLS support.

 For each cluster node, you also need a certificate, private key, and the Certificate Authority (CA) chain to verify the certificate. If you want to use self-signed certificates that are created with OpenSSL, then see [Certificate Creation with OpenSSL](../certificate-creation-with-openssl/index) for information on how to create those.

 Securing Galera Cluster Replication Traffic
-------------------------------------------

 In order to enable TLS for Galera Cluster's replication traffic, there are a number of [wsrep\_provider\_options](../wsrep_provider_options/index) that you need to set, such as:

 * You need to set the path to the server's certificate by setting the `[socket.ssl\_cert](../wsrep_provider_options/index#socketssl_cert)` wsrep\_provider\_option.
* You need to set the path to the server's private key by setting the `[socket.ssl\_key](../wsrep_provider_options/index#socketssl_key)` wsrep\_provider\_option.
* You need to set the path to the certificate authority (CA) chain that can verify the server's certificate by setting the `[socket.ssl\_ca](../wsrep_provider_options/index#socketssl_ca)` wsrep\_provider\_option.
* If you want to restrict the server to certain ciphers, then you also need to set the `[socket.ssl\_cipher](../wsrep_provider_options/index#socketssl_cipher)` wsrep\_provider\_option.

 It is also a good idea to set MariaDB Server's regular TLS-related system variables, so that TLS will be enabled for regular client connections as well. See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to do that.

 For example, to set these variables for the server, add the system variables to a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/server-cert.pem
ssl_key = /etc/my.cnf.d/certificates/server-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
wsrep_provider_options="socket.ssl_cert=/etc/my.cnf.d/certificates/server-cert.pem;socket.ssl_key=/etc/my.cnf.d/certificates/server-key.pem;socket.ssl_ca=/etc/my.cnf.d/certificates/ca.pem"

```

And then [restart the server](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) to make the changes persistent.

 By setting both MariaDB Server's TLS-related system variables and Galera Cluster's TLS-related wsrep\_provider\_options, the server can secure both external client connections and Galera Cluster's replication traffic.

 Securing State Snapshot Transfers
---------------------------------

 The method that you would use to enable TLS for [State Snapshot Transfers (SSTs)](../introduction-to-state-snapshot-transfers-ssts/index) would depend on the value of `[wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method)`.

 ### mariabackup

 See [mariabackup SST Method: TLS](../mariabackup-sst-method/index#tls) for more information.

 ### xtrabackup-v2

 See [xtrabackup-v2 SST Method: TLS](../xtrabackup-v2-sst-method/index#tls) for more information.

 ### mysqldump

 This SST method simply uses the [mariadb-dump](../mariadb-dump/index) (previously mysqldump) utility, so TLS would be enabled by following the guide at [Securing Connections for Client and Server: Enabling TLS for MariaDB Clients](../securing-connections-for-client-and-server/index#enabling-tls-for-mariadb-clients) 

 ### rsync

 This SST method supports encryption in transit via `[stunnel](https://www.stunnel.org/)`. See [Introduction to State Snapshot Transfers (SSTs): rsync](../introduction-to-state-snapshot-transfers-ssts/index#rsync) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/securing-communications-in-galera-cluster/>

OQGRAPH
========

   The Open Query GRAPH computation engine, or OQGRAPH as the engine itself is called, allows you to handle hierarchies (tree structures) and complex graphs (nodes having many connections in several directions).

 


| OQGRAPH Version | Introduced | Maturity |
| --- | --- | --- |
| 3.0 | [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10025-release-notes/) | Gamma |
| 3.0 | [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) | Beta |
| 2.0 | [MariaDB 5.2.1](https://mariadb.com/kb/en/mariadb-521-release-notes/) |  |

   

| Title | Description |
| --- | --- |
|  [Installing OQGRAPH](../installing-oqgraph/index) |  Installing OQGRAPH.  |
|  [OQGRAPH Overview](../oqgraph-overview/index) |  Overview of the OQGRAPH storage engine.  |
|  [OQGRAPH Examples](../oqgraph-examples/index) |  OQGRAPH examples.  |
|  [Compiling OQGRAPH](../compiling-oqgraph/index) |  How to compile OQGRAPH.  |
|  [Building OQGRAPH Under Windows](../building-oqgraph-under-windows/index) |  OQGRAPH build instructions for Windows.  |
|  [OQGRAPH System and Status Variables](../oqgraph-system-and-status-variables/index) |  List and description of OQGRAPH system and status variables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oqgraph-storage-engine/>

Storage Engine Development
===========================

  

| Title | Description |
| --- | --- |
|  [Storage Engine FAQ](../storage-engine-faq/index) |  Are storage engines designed for MySQL compatible with MariaDB? In most cas...  |
|  [Engine-defined New Table/Field/Index Attributes](../engine-defined-new-tablefieldindex-attributes/index) |  A storage engine can allow the user to specify additional attributes per index, field, or table.  |
|  [Table Discovery](../table-discovery/index) |  Mechanism for an engine to tell the server that the table exists  |
|  [Table Discovery (before 10.0.2)](../table-discovery-before-1002/index) |  This page describes the old discovery API, created in MySQL for NDB Cluste...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engines-storage-engine-development/>

Sequence Storage Engine
=======================

    
This article is about the Sequence storage engine. For details about sequence objects, see [Sequences](../sequences/index).

 
A **Sequence** engine allows the creation of ascending or descending sequences of numbers (positive integers) with a given starting value, ending value and increment.

 It creates completely virtual, ephemeral tables automatically when you need them. There is no way to create a Sequence table explicitly. Nor are they ever written to disk or create `.frm` files. They are read-only, [transactional](../transactions/index), and [support XA](../xa-transactions/index).

 Installing
----------

 The Sequence engine is installed by default, and [SHOW ENGINES](../show-engines/index) will list the Sequence storage engine as supported:

 
```
SHOW ENGINES\G
...
*************************** 5. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: SEQUENCE
     Support: YES
     Comment: Generated tables filled with sequential values
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 7. row ***************************
      Engine: MRG_MyISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO

...

```

Usage and Examples
------------------

 To use a Sequence table, you simply select from it, as in

 
```
SELECT * FROM seq_1_to_5;
+-----+
| seq |
+-----+
|   1 |
|   2 |
|   3 |
|   4 |
|   5 |
+-----+

```

To use a sequence in a statement, you select from the table named by a pattern **seq\_**`FROM`**\_to\_**`TO` or **seq\_**`FROM`**\_to\_**`TO`**\_step\_**`STEP`.

 In the case of an odd step, the sequence will commence with the `FROM`, and end at the final result before `TO`.

 
```
SELECT * FROM seq_1_to_15_step_3;
+-----+
| seq |
+-----+
|   1 |
|   4 |
|   7 |
|  10 |
|  13 |
+-----+

```

A sequence can go backwards too. In this case the final value will always be the `TO` value, so that a descending sequence has the same values as an ascending sequence:

 
```
SELECT * FROM seq_5_to_1_step_2;
+-----+
| seq |
+-----+
|   5 |
|   3 |
|   1 |
+-----+

```


```
SELECT * FROM seq_15_to_1_step_3;
+-----+
| seq |
+-----+
|  13 |
|  10 |
|   7 |
|   4 |
|   1 |
+-----+

```


```
SELECT * FROM seq_15_to_2_step_3;
+-----+
| seq |
+-----+
|  14 |
|  11 |
|   8 |
|   5 |
|   2 |
+-----+

```

This engine is particularly useful with joins and subqueries. For example, this query finds all prime numbers below 50:

 
```
SELECT seq FROM seq_2_to_50 s1 WHERE 0 NOT IN
     (SELECT s1.seq % s2.seq FROM seq_2_to_50 s2 WHERE s2.seq <= sqrt(s1.seq));
+-----+
| seq |
+-----+
|   2 |
|   3 |
|   5 |
|   7 |
|  11 |
|  13 |
|  17 |
|  19 |
|  23 |
|  29 |
|  31 |
|  37 |
|  41 |
|  43 |
|  47 |
+-----+

```

And almost (without 2, the only even prime number) the same result with joins:

 
```
SELECT s1.seq FROM seq_2_to_50 s1 JOIN seq_2_to_50 s2 
  WHERE s1.seq > s2.seq AND s1.seq % s2.seq <> 0 
  GROUP BY s1.seq HAVING s1.seq - COUNT(*) = 2;
+-----+
| seq |
+-----+
|   3 |
|   5 |
|   7 |
|  11 |
|  13 |
|  17 |
|  19 |
|  23 |
|  29 |
|  31 |
|  37 |
|  41 |
|  43 |
|  47 |
+-----+

```

Sequence tables can also be useful in date calculations. For example, to find the day of the week that a particular date has fallen on over a 40 year period (perhaps for birthday planning ahead!):

 
```
SELECT DAYNAME('1980-12-05' + INTERVAL (seq) YEAR) day,
    '1980-12-05' + INTERVAL (seq) YEAR date FROM seq_0_to_40;
+-----------+------------+
| day       | date       |
+-----------+------------+
| Friday    | 1980-12-05 |
| Saturday  | 1981-12-05 |
| Sunday    | 1982-12-05 |
...
| Friday    | 2014-12-05 |
| Saturday  | 2015-12-05 |
| Monday    | 2016-12-05 |
| Tuesday   | 2017-12-05 |
| Wednesday | 2018-12-05 |
| Thursday  | 2019-12-05 |
| Saturday  | 2020-12-05 |
+-----------+------------+

```

Although Sequence tables can only directly make use of positive integers, they can indirectly be used to return negative results by making use of the [CAST](../cast/index) statement. For example:

 
```
SELECT CAST(seq AS INT) - 5 x FROM seq_5_to_1;
+----+
| x  |
+----+
|  0 |
| -1 |
| -2 |
| -3 |
| -4 |
+----+

```

[CAST](../cast/index) is required to avoid a `BIGINT UNSIGNED value is out of range` error.

 Sequence tables, while virtual, are still tables, so they must be in a database. This means that a default database must be selected (for example, via the [USE](../use/index) command) to be able to query a Sequence table. The [information\_schema](../information-schema/index) database cannot be used as the default for a Sequence table.

 Table Name Conflicts
--------------------

 If the SEQUENCE storage engine is installed, it is not possible to create a table with a name which follows the SEQUENCE pattern:

 
```
CREATE TABLE seq_1_to_100 (col INT) ENGINE = InnoDB;
ERROR 1050 (42S01): Table 'seq_1_to_100' already exists

```

However, a SEQUENCE table can be converted to another engine and the new table can be referred in any statement:

 
```
ALTER TABLE seq_1_to_100 ENGINE = BLACKHOLE;

SELECT * FROM seq_1_to_100;
Empty set (0.00 sec)

```

While a SEQUENCE table cannot be dropped, it is possible to drop the converted table. The SEQUENCE table with the same name will still exist:

 
```
DROP TABLE seq_1_to_100;

SELECT COUNT(*) FROM seq_1_to_100;
+----------+
| COUNT(*) |
+----------+
|      100 |
+----------+
1 row in set (0.00 sec)

```

A temporary table with a SEQUENCE-like name can always be created and used:

 
```
CREATE TEMPORARY TABLE seq_1_to_100 (col INT) ENGINE = InnoDB;

SELECT * FROM seq_1_to_100;
Empty set (0.00 sec)

```

See Also
--------

 * For details about sequence objects, see [Sequences](../sequences/index).
* [Sometimes its the little things](https://mariadb.com/blog/sometimes-its-little-things) - Dean Ellis tries out the Sequence engine.
* [MariaDB’s Sequence Storage Engine](http://falseisnotnull.wordpress.com/2013/06/23/mariadbs-sequence-storage-engine/) - Federico Razzoli writes more in-depth on the engine.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sequence-storage-engine/>

Legacy Storage Engines
=======================

   The following storage engines are no longer maintained.

  

| Title | Description |
| --- | --- |
|  [BDB](../bdb-obsolete/index) |  BDB storage engine  |
|  [Cassandra Storage Engine](../cassandra/index) |  A storage engine interface to Cassandra.  |
|  [EXAMPLE Storage Engine](../example-storage-engine/index) |  Legacy storage engine designed to assist developers with writing new storage engines  |
|  [FEDERATED Storage Engine](../federated-storage-engine/index) |  A legacy storage engine no longer in active development.  |
|  [IBMDB2I Storage Engine](../ibmdb2i-storage-engine/index) |  Legacy storage engine designed to allow storage on DB2 tables  |
|  [NDB in MariaDB](../ndb-in-mariadb/index) |  MySQL Cluster has been removed from MariaDB  |
|  [PBXT](../pbxt-storage-engine/index) |  PBXT is a general purpose transactional storage engine. It's however not maintained anymore.  |
|  [TokuDB](../tokudb/index) |  For use in high-performance and write-intensive environments.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/legacy-storage-engines/>

PERFORMANCE\_SCHEMA Storage Engine
==================================

    If you run [SHOW ENGINES](../show-engines/index), you'll see the following storage engine listed.

 
```
SHOW ENGINES\G
...
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
...

```

The PERFORMANCE\_SCHEMA is not a regular storage engine for storing data, it's a mechanism for implementing the [Performance Schema](../performance-schema/index) feature.

 The [SHOW ENGINE PERFORMANCE\_SCHEMA STATUS](../show-engine/index#show-engine-performance_schema-status) statement is also available, which shows how much memory is used by the tables and internal buffers.

 See [Performance Schema](../performance-schema/index) for more details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance_schema-storage-engine/>

MyRocks
========

   MyRocks is a storage engine that adds the RocksDB database to MariaDB. RocksDB is an LSM database with a great compression ratio that is optimized for flash storage.

 


| MyRocks Version | Introduced | Maturity |
| --- | --- | --- |
| MyRocks 1.0 | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.16](https://mariadb.com/kb/en/mariadb-10216-release-notes/) | Stable |
| MyRocks 1.0 | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), [MariaDB 10.2.14](https://mariadb.com/kb/en/mariadb-10214-release-notes/) | Gamma |
| MyRocks 1.0 | [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/) | Beta |
| MyRocks 1.0 | [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) | Alpha |

   

| Title | Description |
| --- | --- |
|  [About MyRocks for MariaDB](../about-myrocks-for-mariadb/index) |  Enables greater compression than InnoDB, and less write amplification.  |
|  [Getting Started with MyRocks](../getting-started-with-myrocks/index) |  Installing and getting started with MyRocks.  |
|  [Building MyRocks in MariaDB](../building-myrocks-in-mariadb/index) |  MariaDB compile process for MyRocks.  |
|  [Loading Data Into MyRocks](../loading-data-into-myrocks/index) |  MyRocks has ways to load data much faster than normal INSERTs  |
|  [MyRocks Status Variables](../myrocks-status-variables/index) |  MyRocks-related status variables.  |
|  [MyRocks System Variables](../myrocks-system-variables/index) |  MyRocks server system variables.  |
|  [MyRocks Transactional Isolation](../myrocks-transactional-isolation/index) |  TODO: MyRocks uses snapshot isolation Support do READ-COMMITTED and REPEAT...  |
|  [MyRocks and Replication](../myrocks-and-replication/index) |  Details about how MyRocks works with replication.  |
|  [MyRocks and Group Commit with Binary log](../myrocks-and-group-commit-with-binary-log/index) |  MyRocks supports group commit with the binary log  |
|  [Optimizer Statistics in MyRocks](../optimizer-statistics-in-myrocks/index) |  How MyRocks provides statistics to the query optimizer  |
|  [Differences Between MyRocks Variants](../differences-between-myrocks-variants/index) |  Differences between Facebook's, MariaDB's and Percona Server's MyRocks.  |
|  [MyRocks and Bloom Filters](../myrocks-and-bloom-filters/index) |  Bloom filters are used to reduce read amplification.  |
|  [MyRocks and CHECK TABLE](../myrocks-and-check-table/index) |  MyRocks supports the CHECK TABLE command.  |
|  [MyRocks and Data Compression](../myrocks-and-data-compression/index) |  MyRocks supports several compression algorithms.  |
|  [MyRocks and Index-Only Scans](../myrocks-and-index-only-scans/index) |  MyRocks and index-only scans on secondary indexes.  |
|  [MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT](../myrocks-and-start-transaction-with-consistent-snapshot/index) |  FB/MySQL has added new syntax which returns the binlog coordinates pointing at the snapshot.  |
|  [MyRocks Column Families](../myrocks-column-families/index) |  MyRocks stores data in column families, which are similar to tablespaces.  |
|  [MyRocks in MariaDB 10.2 vs MariaDB 10.3](../myrocks-in-mariadb-102-vs-mariadb-103/index) |  MyRocks storage engine in MariaDB 10.2 and MariaDB 10.3.  |
|  [MyRocks Performance Troubleshooting](../myrocks-performance-troubleshooting/index) |  MyRocks exposes its performance metrics through several interfaces.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks/>

Information Schema ENGINES Table
================================

    The [Information Schema](../information_schema/index) `ENGINES` table displays status information about the server's [storage engines](../mariadb-storage-engines/index).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `ENGINE` | Name of the storage engine. |
| `SUPPORT` | Whether the engine is the default, or is supported or not. |
| `COMMENT` | Storage engine comments. |
| `TRANSACTIONS` | Whether or not the engine supports [transactions](../transactions/index). |
| `XA` | Whether or not the engine supports [XA transactions](../xa-transactions/index). |
| `SAVEPOINTS` | Whether or not [savepoints](../savepoint/index) are supported. |

 
It provides identical information to the `[SHOW ENGINES](../show-engines/index)` statement. Since storage engines are plugins, different information about them is also shown in the `[information\_schema.PLUGINS](../information_schemaplugins-table/index)` table and by the `[SHOW PLUGINS](../show-plugins/index)` statement.

 The table is not a standard Information Schema table, and is a MySQL and MariaDB extension.

 Note that both MySQL's InnoDB and Percona's XtraDB replacement are labeled as `InnoDB`. However, if XtraDB is in use, it will be specified in the `COMMENT` field. See [XtraDB and InnoDB](../xtradb-and-innodb/index). The same applies to [FederatedX](../federatedx/index).

 Example
-------

 
```
SELECT * FROM information_schema.ENGINES\G;
*************************** 1. row ***************************
      ENGINE: InnoDB
     SUPPORT: DEFAULT
     COMMENT: Supports transactions, row-level locking, and foreign keys
TRANSACTIONS: YES
          XA: YES
  SAVEPOINTS: YES
*************************** 2. row ***************************
      ENGINE: CSV
     SUPPORT: YES
     COMMENT: CSV storage engine
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 3. row ***************************
      ENGINE: MyISAM
     SUPPORT: YES
     COMMENT: MyISAM storage engine
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 4. row ***************************
      ENGINE: BLACKHOLE
     SUPPORT: YES
     COMMENT: /dev/null storage engine (anything you write to it disappears)
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 5. row ***************************
      ENGINE: FEDERATED
     SUPPORT: YES
     COMMENT: FederatedX pluggable storage engine
TRANSACTIONS: YES
          XA: NO
  SAVEPOINTS: YES
*************************** 6. row ***************************
      ENGINE: MRG_MyISAM
     SUPPORT: YES
     COMMENT: Collection of identical MyISAM tables
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 7. row ***************************
      ENGINE: ARCHIVE
     SUPPORT: YES
     COMMENT: Archive storage engine
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 8. row ***************************
      ENGINE: MEMORY
     SUPPORT: YES
     COMMENT: Hash based, stored in memory, useful for temporary tables
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 9. row ***************************
      ENGINE: PERFORMANCE_SCHEMA
     SUPPORT: YES
     COMMENT: Performance Schema
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
*************************** 10. row ***************************
      ENGINE: Aria
     SUPPORT: YES
     COMMENT: Crash-safe tables with MyISAM heritage
TRANSACTIONS: NO
          XA: NO
  SAVEPOINTS: NO
10 rows in set (0.00 sec)

```

Check if a given storage engine is available:

 
```
SELECT SUPPORT FROM information_schema.ENGINES WHERE ENGINE LIKE 'tokudb';
Empty set

```

Check which storage engine supports XA transactions:

 
```
SELECT ENGINE FROM information_schema.ENGINES WHERE XA = 'YES';
+--------+
| ENGINE |
+--------+
| InnoDB |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-engines-table/>

Plugin SQL Statements
======================

   [Plugin](../plugin-overview/index) commands.

  

| Title | Description |
| --- | --- |
|  [SHOW PLUGINS](../show-plugins/index) |  Display information about installed plugins.  |
|  [SHOW PLUGINS SONAME](../show-plugins-soname/index) |  Information about all available plugins, installed or not.  |
|  [INSTALL PLUGIN](../install-plugin/index) |  Install a plugin.  |
|  [UNINSTALL PLUGIN](../uninstall-plugin/index) |  Remove a single installed plugin.  |
|  [INSTALL SONAME](../install-soname/index) |  Installs all plugins from a given library.  |
|  [UNINSTALL SONAME](../uninstall-soname/index) |  Remove all plugins belonging to a specified library.  |
|  [mysql\_plugin](../mysql_plugin/index) |  Symlink or old name for mariadb-plugin.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plugin-sql-statements/>

Spider
=======

   The Spider storage engine supports partitioning and [xa transactions](../xa-transactions/index), and allows tables of different MariaDB instances to be handled as if they were on the same instance.

 ### Versions of Spider in MariaDB

 From [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/), the Spider version number matches the server version. 





| Spider Version | Introduced | Maturity |
| --- | --- | --- |
| Spider 3.3.15 | [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) | Stable |
| Spider 3.3.15 | [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/) | Gamma |
| Spider 3.3.14 | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) | Stable |
| Spider 3.3.13 | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) | Stable |
| Spider 3.3.13 | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) | Gamma |
| Spider 3.2.37 | [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/) | Gamma |
| Spider 3.2.21 | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) | Gamma |
| Spider 3.2.18 | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) | Gamma |
| Spider 3.2.11 | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) | Gamma |
| Spider 3.2.4 | [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/) | Gamma |
| Spider 3.2 | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) | Gamma |
| Spider 3.0 | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) | Beta |

  Spider Documentation
--------------------

 See the [spider-2.0-doc](http://bazaar.launchpad.net/~kentokushiba/spiderformysql/spider-2.0-doc/files) repository for complete, older, documentation.

 [Presentation for new sharding features in Spider 3.3](https://speakerdeck.com/kentoku/new-features-and-enhancements-of-spider-storage-engine-for-sharding).

  

| Title | Description |
| --- | --- |
|  [Spider Storage Engine Overview](../spider-storage-engine-overview/index) |  Storage engine with sharding features.  |
|  [Spider Installation](../spider-installation/index) |  Setting up Spider.  |
|  [Spider Storage Engine Core Concepts](../spider-storage-engine-core-concepts/index) |  Key Spider concepts  |
|  [Spider Use Cases](../spider-use-cases/index) |  Basic working examples for Spider  |
|  [Spider Cluster Management](../spider-cluster-management/index) |  Spider cluster management.  |
|  [Spider Feature Matrix](../spider-feature-matrix/index) |  Matrix of Spider features  |
|  [Spider Server System Variables](../spider-server-system-variables/index) |  System variables for the Spider storage engine.  |
|  [Spider Table Parameters](../spider-table-parameters/index) |  Spider table parameters available in the CREATE TABLE ... COMMENT clause  |
|  [Spider Status Variables](../spider-status-variables/index) |  Spider server status variables.  |
|  [Spider Functions](../spider-functions/index) |  User-defined functions available with the Spider storage engine.  |
|  [Spider mysql Database Tables](../spider-mysql-database-tables/index) |  System tables related to the Spider storage engine.  |
|  [Information Schema SPIDER\_ALLOC\_MEM Table](../information-schema-spider_alloc_mem-table/index) |  Information about Spider's memory usage.  |
|  [Information Schema SPIDER\_WRAPPER\_PROTOCOLS Table](../information-schema-spider_wrapper_protocols-table/index) |  Installed along with the Spider storage engine.  |
|  [Spider Differences Between SpiderForMySQL and MariaDB](../spider-differences-between-spiderformysql-and-mariadb/index) |  Spider differences between MySQL and MariaDB  |
|  [Spider Case Studies](../spider-case-studies/index) |  List of clients using Spider  |
|  [Spider Benchmarks](../spider-benchmarks/index) |  Benchmarks for Spider  |
|  [Spider FAQ](../spider-faq/index) |  Frequently-asked questions about the Spider storage engine  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider/>

Converting Tables from MyISAM to InnoDB
=======================================

    The task
--------

 You have decided to change one or more tables from [MyISAM](../myisam/index) to [InnoDB](../innodb/index). That should be as simple as `ALTER TABLE foo ENGINE=InnoDB`. But you have heard that there might be some subtle issues. 

 This describes possible issues that may arise and what to do about them. 

  *Recommendation.* One way to assist in searching for issues in is to do (at least in \*nix)

 
```
mysqldump --no-data --all-databases >schemas
egrep 'CREATE|PRIMARY' schemas   # Focusing on PRIMARY KEYs
egrep 'CREATE|FULLTEXT' schemas  # Looking for FULLTEXT indexes
egrep 'CREATE|KEY' schemas       # Looking for various combinations of indexes

```

Understanding how the indexes work will help you better understand what might run faster or slower in InnoDB. 

 INDEX Issues
------------

  *(Most of these Recommendations and some of these Facts have exceptions.)*

  *Fact.* Every InnoDB table has a PRIMARY KEY. If you do not provide one, then the first non-NULL UNIQUE key is used. If that can't be done, then a 6-byte, hidden, integer is provided. 

  *Recommendation.* Look for tables without a PRIMARY KEY. Explicitly specify a PRIMARY KEY, even if it's an artificial AUTO\_INCREMENT. This is not an absolute requirement, but it is a stronger admonishment for InnoDB than for MyISAM. Some day you may need to walk through the table; without an explicit PK, you can't do it. 

  *Fact.* The fields of the PRIMARY KEY are included in each Secondary key. 

 * Check for redundant indexes with this in mind.

 
```
PRIMARY KEY(id),
INDEX(b), -- effectively the same as INDEX(b, id)
INDEX(b, id) -- effectively the same as INDEX(b)

```

* (Keep one of the INDEXes, not both)

 * Note subtle things like

 
```
PRIMARY KEY(id),
UNIQUE(b), -- keep for uniqueness constraint
INDEX(b, id) -- DROP this one

```

* Also, since the PK and the data coexist:

 
```
PRIMARY KEY(id),
INDEX(id, b) -- DROP this one; it adds almost nothing

```

 *Contrast.* This feature of MyISAM is not available in InnoDB; the value of 'id' will start over at 1 for each different value of 'abc':

 
```
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (abc, id)

```

A way to simulate the MyISAM 'feature' might be something like: What you want is this, but it won't work because it is referencing the table twice:

 
```
INSERT INTO foo
    (other, id, ...)
    VALUES
    (123, (SELECT MAX(id)+1 FROM foo WHERE other = 123), ...);

```

Instead, you need some variant on this. (You may already have a BEGIN...COMMIT.)

 
```
BEGIN;
SELECT @id := MAX(id)+1 FROM foo WHERE other = 123 FOR UPDATE;
INSERT INTO foo
    (other, id, ...)
    VALUES
    (123, @id, ...);
COMMIT;

```

Having a transaction is mandatory to prevent another thread from grabbing the same id. 

  *Recommendation.* Look for such PRIMARY KEYs. If you find such, ponder how to change the design. There is no straightforward workaround. However, the following may be ok. (Be sure that the datatype for id is big enough since it won't start over.):

 
```
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (abc, id),
UNIQUE(id)

```

 *Recommendation.* Keep the PRIMARY KEY short. If you have Secondary keys, remember that they include the fields of the PK. A long PK would make the Secondary keys bulky. Well, maybe not — if the is a lot of overlap in fields. Example: `PRIMARY KEY(a,b,c), INDEX(c,b,a)` — no extra bulk. 

  *Recommendation.* Check AUTO\_INCREMENT sizes. 

 * BIGINT is almost never needed. It wastes at least 4 bytes per row (versus INT).
* Always use UNSIGNED and NOT NULL.
* MEDIUMINT UNSIGNED (16M max) might suffice instead of INT
* Be sure to be pessimistic — it is painful to ALTER.

  *Contrast.* "Vertical Partitioning". This is where you artificially split a table to move bulky columns (eg, a BLOB) into another, parallel, table. It is beneficial in MyISAM to avoid stepping over the blob when you don't need to read it. InnoDB stores BLOB and TEXT differently — 767 bytes are in the record, the rest is in some other block. So, it may (or may not) be worth putting the tables back together. Caution: An InnoDB row is limited to 8KB, and the 767 counts against that. 

  *Fact.* FULLTEXT (prior to [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/)) and SPATIAL indexes are not available in InnoDB. Note that MyISAM and InnoDB [FULLTEXT indexes](../full-text-indexes/index) use different <stopword> lists and different system variables.

  *Recommendation.* Search for such indexes. Keep such tables in MyISAM. Better yet, do Vertical Partitioning (see above) to split out the minimum number of columns from InnoDB. 

  *Fact.* The maximum length of an INDEX is different between the Engines. (This change is not likely to hit you, but watch out.) MyISAM allows 1000 bytes; InnoDB allows 767 bytes, just big enough for a

 
```
VARCHAR(255) CHARACTER SET utf8.

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

```

 *Fact.* The PRIMARY KEY is included in the data. Hence, SHOW TABLE STATUS will show and `Index_length` of 0 bytes (or 16KB) for a table with no secondary indexes. Otherwise, `Index_length` is the total size for the secondary keys. 

  *Fact.* The PRIMARY KEY is included in the data. Hence, exact match by PK may be a little faster with InnoDB. And, "range" scans by PK are likely to be faster. 

  *Fact.* A lookup by Secondary Key traverses the secondary key's BTree, grabs the PRIMARY KEY, then traverses the PK's BTree. Hence, secondary key lookups are a little more cumbersome in InnoDB. 

  *Contrast.* The fields of the PRIMARY KEY are included in each Secondary key. This may lead to "Using index" (in the EXPLAIN plan) for InnoDB for cases where it did not happen in MyISAM. (This is a slight performance boost, and counteracts the double-lookup otherwise needed.) However, when "Using index" would be useful on the PRIMARY KEY, MyISAM would do an "index scan", yet InnoDB effectively has to do a "table scan". 

  *Same as MyISAM.* Almost always

 
```
INDEX(a)   -- DROP this one because the other one handles it.
INDEX(a,b)

```

 *Contrast.* The data is stored in PK order. This means that "recent" records are 'clustered' together at the end. This may give you better 'locality of reference' than in MyISAM. 

  *Same as MyISAM.* The optimizer almost never uses two indexes in a single SELECT. (5.1 will occasionally do "index merge".) SELECT in subqueries and UNIONs can independently pick indexes. 

  *Subtle issue.* When you DELETE a row, the AUTO\_INCREMENT id will be burned. Ditto for REPLACE, which is a DELETE plus an INSERT. 

  *Very subtle issue.* Replication occurs on COMMIT. If you have multiple threads using transactions, the AUTO\_INCREMENTs can arrive at a slave out of order. One transaction BEGINs, grabs an id. Then another transaction grabs an id but COMMITs before the first finishes. 

  *Same as MyISAM.* "Prefix" indexing is usually bad in both InnoDB and MyISAM. Example: `INDEX(foo(30))`

 Non-INDEX Issues
----------------

 Disk space for InnoDB is likely to be 2-3 times as much as for MyISAM. 

 MyISAM and InnoDB use RAM radically differently. If you change all your tables, you should make significant adjustments: 

 * [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) — small but non-zero; say, 10M;
* [innodb\_buffer\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) — 70% of available RAM

 InnoDB has essentially no need for CHECK, OPTIMIZE, or ANALYZE. Remove them from your maintenance scripts. (No real harm if you keep them.) 

 Backup scripts may need checking. A MyISAM table can be backed up by copying three files. With InnoDB this is only possible if [innodb\_file\_per\_table](../xtradbinnodb-server-system-variables/index#innodb_file_per_table) is set to 1. Before [MariaDB 10.0](../what-is-mariadb-100/index), capturing a table or database for copying from production to a development environment was not possible. Change to [mysqldump](../mysqldump/index). Since [MariaDB 10.0](../what-is-mariadb-100/index) a hot copy can be created - see [Backup and restore overview](../backup-and-restore-overview/index).

 Before [MariaDB 5.5](../what-is-mariadb-55/index), the DATA DIRECTORY [table option](../create-table/index#table-options) was not supported for InnoDB. Since [MariaDB 5.5](../what-is-mariadb-55/index) it is supported, but only in CREATE TABLE. INDEX DIRECTORY has no effect, since InnoDB does not use separate files for indexes. To better balance the workload through several disks, the paths of some InnoDB log files can also be changed.

 Understand autocommit and BEGIN/COMMIT. 

 * (default) autocommit = 1: In the absence of any BEGIN or COMMIT statements, every statement is a transaction by itself. This is close to the MyISAM behavior, but is not really the best.
* autocommit = 0: COMMIT will close a transaction and start another one. To me, this is kludgy.
* (recommended) BEGIN...COMMIT gives you control over what sequence of operation(s) are to be considered a transaction and "atomic". Include the ROLLBACK statement if you need to undo stuff back to the BEGIN.

 Perl's DBIx::DWIW and Java's JDBC have API calls to do BEGIN and COMMIT. These are probably better than 'executing' BEGIN and COMMIT. 

 Test for errors everywhere! Because InnoDB uses row-level locking, it can stumble into deadlocks that you are not expecting. The engine will automatically ROLLBACK to the BEGIN. The normal recovery is to redo, beginning at the BEGIN. Note that this is a strong reason to have BEGINs. 

 LOCK/UNLOCK TABLES — remove them. Replace them (sort of) with BEGIN ... COMMIT. (LOCK will work if [innodb\_table\_locks](../xtradbinnodb-server-system-variables/index#innodb_table_locks) is set to 1, but it is less efficient, and may have subtle issues.) 

 In 5.1, ALTER ONLINE TABLE can speed up some operations significantly. (Normally ALTER TABLE copies the table over and rebuilds the indexes.) 

 The "limits" on virtually everything are different between MyISAM and InnoDB. Unless you have huge tables, wide rows, lots of indexes, etc, you are unlikely to stumble into a different limit. 

 Mixture of MyISAM and InnoDB? This is OK. But there are caveats. 

 * RAM settings should be adjusted to accordingly.
* JOINing tables of different Engines works.
* A transaction that affects tables of both types can ROLLBACK InnoDB changes, but will leave MyISAM changes intact.
* Replication: MyISAM statements are replicated when finished; InnoDB statements are held until the COMMIT.

 FIXED (vs DYNAMIC) is meaningless in InnoDB. 

 PARTITION — You can partition MyISAM and InnoDB tables. Remember the screwball rule: You must either 

 * have no UNIQUE (or PRIMARY) keys, or
* have the value you are "partitioning on" in every UNIQUE key.

 The former is not advised for InnoDB. The latter is messy if you want an AUTO\_INCREMENT. 

 PRIMARY KEY in PARTITION — Since every key must include the field on which you are PARTITIONing, how can AUTO\_INCREMENT work? Well, there seems to be a convenient special case: 

 * This works: PRIMARY KEY(autoinc, partition\_key)

 * This does not work for InnoDB: PRIMARY KEY(partition\_key, autoinc)

 That is, an AUTO\_INCREMENT will correctly increment, and be unique across all PARTITINOs, when it is the first field of the PRIMARY KEY, but not otherwise.

 See Also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/myisam2innodb>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/converting-tables-from-myisam-to-innodb/>

Information on Plugins
=======================

  

| Title | Description |
| --- | --- |
|  [List of Plugins](../list-of-plugins/index) |  List of plugins included in MariaDB, ordered by their maturity.  |
|  [Information Schema PLUGINS Table](../plugins-table-information-schema/index) |  Information Schema table containing information on plugins installed on a server.  |
|  [Information Schema ALL\_PLUGINS Table](../all-plugins-table-information-schema/index) |  Information about server plugins, whether installed or not.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-on-plugins/>

Machine Learning with MindsDB
=============================

    Overview
--------

 [MindsDB](https://docs.mindsdb.com/) is a third-party application that interfaces with MariaDB Server to provide Machine Learning capabilities through SQL. The interface is done via the [Connect Storage Engine](../connect/index).

 Installation
------------

 To get a functional MariaDB - MindsDB installation, one needs to install the following components:

 * **MindsDB**: follow the instructions in the project's [official documentation](https://docs.mindsdb.com/installation/Installing/).
* **Connect Storage Engine** must be enabled for the integration to work. See [installing the connect storage engine](../installing-the-connect-storage-engine/index).

 MindsDB connects to MariaDB Server via a regular user to setup a dedicated database called `mindsdb`. Which user will be used is specified within MindsDB's [configuration file](https://docs.mindsdb.com/sql/create/databases/?h=maria#mariadb).

 For example, if MindsDB is installed locally, one can create a user called `mindsdb@localhost`. MindsDB only authenticates via the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) plugin, hence one must set a password for the user:

 
```
CREATE USER mindsdb@localhost;
SET PASSWORD for mindsdb@localhost=PASSWORD("password");

```

The user must be granted the global [FILE](../grant/index#file) privilege and all privileges on the `mindsdb` database.

 
```
GRANT FILE on *.* to mindsdb@localhost;
GRANT ALL on mindsdb.* to mindsdb@localhost;

```

Assuming MindsDB is in the python path one can start up MindsDB with the following parameters:

 
```
python -m mindsdb --config=$CONFIG_PATH --api=http,mysql

```

Make sure `$CONFIG_PATH` points to the appropriate MindsDB configuration file.

 Usage
-----

 Always consult the project's [official documentation](https://docs.mindsdb.com/installation/Installing/) for up-to-date usage scenarios as MindsDB is an actively developed project.

 For a step-by-step example, you can consult the following [blog post](https://mariadb.org/machine-learning-sql/).

 If the connection between MindsDB and MariaDB is successful, you should see the `mindsdb` database present and two tables within it: `commands` and `predictors`.

 MindsDB, as an AutoML framework does all the work when it comes to training the AI model. What is necessary is to pass it the initial data, which MindsDB retrieves via a SELECT statement. This can be done by inserting into the `predictors` table.

 
```
INSERT INTO `predictors`
       (`name`, `predict`, `select_data_query`)
VALUES ('bikes_model', 'count', 'SELECT * FROM test.bike_data');

```

The values inserted into predictors act as a command instructing MindsDB to:

 1. Train a model called 'bikes\_model'
2. From the input data, learn to predict the 'count' column.
3. The input data is generated via the select statement 'SELECT \* FROM test.bike\_data'. The `select_data_query` should be a valid select that MindsDB can run against MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/machine-learning-with-mindsdb/>

S3 Storage Engine
==================

   
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

  S3 is a read-only storage engine that stores its data in Amazon S3.

  

| Title | Description |
| --- | --- |
|  [Using the S3 Storage Engine](../using-the-s3-storage-engine/index) |  Using the S3 storage engine.  |
|  [Testing the Connections to S3](../testing-the-connections-to-s3/index) |  Steps to help verify where an S3 problem could be.  |
|  [S3 Storage Engine Internals](../s3-storage-engine-internals/index) |  The S3 storage engine is based on the Aria code.  |
|  [aria\_s3\_copy](../aria_s3_copy/index) |  Copies an Aria table to and from S3.  |
|  [S3 Storage Engine Status Variables](../s3-storage-engine-status-variables/index) |  S3 Storage Engine-related status variables.  |
|  [S3 Storage Engine System Variables](../s3-storage-engine-system-variables/index) |  S3 Storage Engine-related system variables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/s3-storage-engine/>

CONNECT
========

   
Note: You can download a [PDF version of the CONNECT documentation](https://mariadb.com/kb/en/connect-table-types/+attachment/connect_1_7_03) (1.7.0003).

  


| Connect Version | Introduced | Maturity |
| --- | --- | --- |
| Connect 1.07.0002 | [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/) | Stable |
| Connect 1.07.0001 | [MariaDB 10.4.12](https://mariadb.com/kb/en/mariadb-10412-release-notes/), [MariaDB 10.3.22](https://mariadb.com/kb/en/mariadb-10322-release-notes/), [MariaDB 10.2.31](https://mariadb.com/kb/en/mariadb-10231-release-notes/), [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10144-release-notes/) | Stable |
| Connect 1.06.0010 | [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/), [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/), [MariaDB 10.2.27](https://mariadb.com/kb/en/mariadb-10227-release-notes/) | Stable |
| Connect 1.06.0007 | [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), [MariaDB 10.2.14](https://mariadb.com/kb/en/mariadb-10214-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10133-release-notes/) | Stable |
| Connect 1.06.0005 | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/) | Stable |
| Connect 1.06.0004 | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/) | Stable |
| Connect 1.06.0001 | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/) | Beta |
| Connect 1.05.0003 | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/), [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/) | Stable |
| Connect 1.05.0001 | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) | Stable |
| Connect 1.04.0008 | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/) | Stable |
| Connect 1.04.0006 | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/), [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), | Stable |
| Connect 1.04.0005 | [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/) | Beta |
| Connect 1.04.0003 | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) | Beta |

  The CONNECT storage engine enables MariaDB to access external local or remote data (MED). This is done by defining tables based on different data types, in particular files in various formats, data extracted from other DBMS or products (such as Excel or MongoDB) via ODBC or JDBC, or data retrieved from the environment (for example DIR, WMI, and MAC tables)

 This storage engine supports table partitioning, MariaDB virtual columns and permits defining *special* columns such as ROWID, FILEID, and SERVID.

 No precise definition of maturity exists. Because CONNECT handles many table types, each type has a different maturity depending on whether it is old and well-tested, less well-tested or newly implemented. This will be indicated for all data types.

  

| Title | Description |
| --- | --- |
|  [Introduction to the CONNECT Engine](../introduction-to-the-connect-engine/index) |  Reasons behind the CONNECT storage engine.  |
|  [Installing the CONNECT Storage Engine](../installing-the-connect-storage-engine/index) |  Installing the CONNECT storage engine.  |
|  [CONNECT Create Table Options](../connect-create-table-options/index) |  CREATE TABLE options for the CONNECT engine.  |
|  [CONNECT Data Types](../connect-data-types/index) |  Data types supported by CONNECT.  |
|  [Current Status of the CONNECT Handler](../current-status-of-the-connect-handler/index) |  The current CONNECT handler is a stable release.  |

 ###   [CONNECT Table Types](../connect-table-types/index)

 

| Title | Description |
| --- | --- |
|  [CONNECT Table Types Overview](../connect-table-types-overview/index) |  CONNECT can handle many table formats.  |
|  [Inward and Outward Tables](../inward-and-outward-tables/index) |  The two broad categories of CONNECT tables.  |
|  [CONNECT Table Types - Data Files](../connect-table-types-data-files/index) |  CONNECT plain DOS or UNIX data files.  |
|  [CONNECT Zipped File Tables](../connect-zipped-file-tables/index) |  When the table file or files are compressed in one or several zip files.  |
|  [CONNECT DOS and FIX Table Types](../connect-dos-and-fix-table-types/index) |  CONNECT tables based on text files  |
|  [CONNECT DBF Table Type](../connect-dbf-table-type/index) |  CONNECT dBASE III or IV tables.  |
|  [CONNECT BIN Table Type](../connect-bin-table-type/index) |  CONNECT binary files in which each row is a logical record of fixed length  |
|  [CONNECT VEC Table Type](../connect-vec-table-type/index) |  CONNECT binary files organized in vectors  |
|  [CONNECT CSV and FMT Table Types](../connect-csv-and-fmt-table-types/index) |  Variable length CONNECT data files.  |
|  [CONNECT - NoSQL Table Types](../connect-nosql-table-types/index) |  Based on files that do not match the relational format but often represent hierarchical data.  |
|  [CONNECT - Files Retrieved Using Rest Queries](../connect-files-retrieved-using-rest-queries/index) |  JSON, XML and CSV data files can be retrieved as results from REST queries.  |
|  [CONNECT JSON Table Type](../connect-json-table-type/index) |  JSON (JavaScript Object Notation) is a widely-used lightweight data-interchange format.  |
|  [CONNECT XML Table Type](../connect-xml-table-type/index) |  CONNECT XML files  |
|  [CONNECT INI Table Type](../connect-ini-table-type/index) |  CONNECT INI Windows configuration or initialization files.  |
|  [CONNECT - External Table Types](../connect-external-table-types/index) |  Access tables belonging to the current or another server.  |
|  [CONNECT ODBC Table Type: Accessing Tables From Another DBMS](../connect-odbc-table-type-accessing-tables-from-another-dbms/index) |  CONNECT Table Types - ODBC Table Type: Accessing Tables from other DBMS  |
|  [CONNECT JDBC Table Type: Accessing Tables from Another DBMS](../connect-jdbc-table-type-accessing-tables-from-another-dbms/index) |  Using JDBC to access other tables.  |
|  [CONNECT MONGO Table Type: Accessing Collections from MongoDB](../connect-mongo-table-type/index) |  Used to directly access MongoDB collections as tables.  |
|  [CONNECT MYSQL Table Type: Accessing MySQL/MariaDB Tables](../connect-mysql-table-type-accessing-mysqlmariadb-tables/index) |  Accessing a MySQL or MariaDB table or view  |
|  [CONNECT PROXY Table Type](../connect-proxy-table-type/index) |  Tables that access and read the data of another table or view  |
|  [CONNECT XCOL Table Type](../connect-xcol-table-type/index) |  Based on another table/view, used when object tables have a column that contains a list of values  |
|  [CONNECT OCCUR Table Type](../connect-occur-table-type/index) |  Extension to the PROXY type when referring to a table/view having several c...  |
|  [CONNECT PIVOT Table Type](../connect-pivot-table-type/index) |  Transform the result of another table into another table along “pivot” and "fact" columns.  |
|  [CONNECT TBL Table Type: Table List](../connect-tbl-table-type-table-list/index) |  Define a table as a list of tables of any engine and type.  |
|  [CONNECT - Using the TBL and MYSQL Table Types Together](../connect-using-the-tbl-and-mysql-table-types-together/index) |  Used together, the TBL and MYSQL types lift all the limitations of the FEDERATED and MERGE engines  |
|  [CONNECT Table Types - Special "Virtual" Tables](../connect-table-types-special-virtual-tables/index) |  VIR, WMI and MAC special table types  |
|  [CONNECT Table Types - VIR](../connect-table-types-vir/index) |  VIR virtual type for CONNECT  |
|  [CONNECT Table Types - OEM: Implemented in an External LIB](../connect-table-types-oem/index) |  CONNECT OEM table types are implemented in an external library.  |
|  [CONNECT Table Types - Catalog Tables](../connect-table-types-catalog-tables/index) |  Catalog tables return information about another table or data source  |
|  [Adding DataFlex 3.1c .dat Files As An External Table Type With CONNECT](../adding-dataflex-31c-dat-files-as-an-external-table-type-with-connect/index) |  I'm using MariaDB's CONNECT engine to access / utilize a set of Visual FoxP...  |
|  [CONNECT engine windows](../connect-engine-windows/index) |  with mariadb 10.07 installed on windows, how to setup engines, particulary ...  |
|  [creating pivot table fails](../creating-pivot-table-fails/index) |  I tried to create a pivot table based on an existing table "test1" and get ...  |
|  [limit of number of columns](../limit-of-number-of-columns/index) |  I have a table of 6MB with 50 values in the pivot-values leading to 50 colu...  |

 ### Other CONNECT Articles

 

| Title | Description |
| --- | --- |
|  [CONNECT - Security](../connect-security/index) |  CONNECT requires the FILE privilege for "outward" tables  |
|  [CONNECT - OEM Table Example](../connect-oem-table-example/index) |  Example showing how an OEM table can be implemented.  |

 ###   [Using CONNECT](../using-connect/index)

 

| Title | Description |
| --- | --- |
|  [Using CONNECT - General Information](../using-connect-general-information/index) |  Using CONNECT - General Information.  |
|  [Using CONNECT - Virtual and Special Columns](../using-connect-virtual-and-special-columns/index) |  Virtual and special columns example usage  |
|  [Using CONNECT - Importing File Data Into MariaDB Tables](../using-connect-importing-file-data-into-mariadb-tables/index) |  Directly using external (file) data has many advantages  |
|  [Using CONNECT - Exporting Data From MariaDB](../using-connect-exporting-data-from-mariadb/index) |  Exporting data from MariaDB with CONNECT  |
|  [Using CONNECT - Indexing](../using-connect-indexing/index) |  Indexing with the CONNECT handler  |
|  [Using CONNECT - Condition Pushdown](../using-connect-condition-pushdown/index) |  Using CONNECT - Condition Pushdown.  |
|  [USING CONNECT - Offline Documentation](../using-connect-offline-documentation/index) |  CONNECT Plugin User Manual.  |
|  [Using CONNECT - Partitioning and Sharding](../using-connect-partitioning-and-sharding/index) |  Partitioning and Sharding with CONNECT  |

 ### Other CONNECT Articles

 

| Title | Description |
| --- | --- |
|  [CONNECT - Making the GetRest Library](../connect-making-the-getrest-library/index) |  Compiling the function calling the cpprestsdk package separately that will be loaded by CONNECT.  |
|  [CONNECT - Adding the REST Feature as a Library Called by an OEM Table](../connect-adding-the-rest-feature-as-a-library-called-by-an-oem-table/index) |  How the REST feature can be added as a library called by an OEM table.  |
|  [CONNECT - Compiling JSON UDFs in a Separate Library](../connect-compiling-json-udfs-in-a-separate-library/index) |  There are situations when you may need to have JSON UDFs in a separate library.  |
|  [CONNECT System Variables](../connect-system-variables/index) |  System variables related to the CONNECT storage engine.  |
|  [JSON Sample Files](../json-sample-files/index) |  expense.json sample file  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect/>

Creating and Building Plugins
==============================

  

| Title | Description |
| --- | --- |
|  [Specifying Which Plugins to Build](../specifying-which-plugins-to-build/index) |  Specifying which plugins to build.  |
|  [Writing Plugins for MariaDB](../development-writing-plugins-for-mariadb/index) |  Writing plugins for MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-and-building-plugins/>

MariaDB Replication & Cluster Plugins
======================================

  

| Title | Description |
| --- | --- |
|  [Semisynchronous Replication](../semisynchronous-replication/index) |  Semisynchronous replication.  |
|  [WSREP\_INFO Plugin](../wsrep_info-plugin/index) |  Adds two new Information Schema tables, WSREP\_MEMBERSHIP and WSREP\_STATUS.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-replication-cluster-plugins/>

Stored Routine Limitations
==========================

    The following SQL statements are not permitted inside any [stored routines](../stored-programs-and-views/index) ([stored functions](../stored-functions/index), [stored procedures](../stored-procedures/index), [events](../events/index) or [triggers](../triggers/index)).

 * [ALTER VIEW](../alter-view/index); you can use [CREATE OR REPLACE VIEW](../create-view/index) instead.
* [LOAD DATA](../load-data/index) and [LOAD TABLE](../load-table-from-master/index).
* [CHANGE MASTER TO](../change-master-to/index)
* [INSERT DELAYED](../insert-delayed/index) is permitted, but the statement is handled as a regular [INSERT](../insert/index).
* [LOCK TABLES](../lock-tables/index) and [UNLOCK TABLES](../unlock-tables/index).
* References to [local variables](../declare-variable/index) within prepared statements inside a stored routine (use [user-defined variables](../user-defined-variables/index) instead).
* [BEGIN (WORK)](../start-transaction/index) is treated as the beginning of a [BEGIN END](../begin-end/index) block, not a transaction, so [START TRANSACTION](../start-transaction/index) needs to be used instead.
* The number of permitted recursive calls is limited to [max\_sp\_recursion\_depth](../server-system-variables/index#max_sp_recursion_depth). If this variable is 0 (default), recursivity is disabled. The limit does not apply to stored functions.
* Most statements that are not permitted in prepared statements are not permitted in stored programs. See [Prepare Statement:Permitted statements](../prepare-statement/index#permitted-statements) for a list of statements that can be used. [SIGNAL](../signal/index), [RESIGNAL](../resignal/index) and [GET DIAGNOSTICS](../get-diagnostics/index) are exceptions, and may be used in stored routines.

 There are also further limitations specific to the kind of stored routine.

 Note that, if a stored program calls another stored program, the latter will inherit the caller's limitations. So, for example, if a stored procedure is called by a stored function, that stored procedure will not be able to produce a result set, because stored functions can't do this.

 See Also
--------

 * [Stored Function Limitations](../stored-function-limitations/index)
* [Trigger Limitations](../trigger-limitations/index)
* [Event Limitations](../event-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-routine-limitations/>

Installing MariaDB Galera on IBM Cloud
======================================

     Get MariaDB Galera on IBM Cloud

 You should have an IBM Cloud account, otherwise you can [register here](https://cloud.ibm.com/registration). At the end of the tutorial you will have a cluster with MariaDB up and running. IBM Cloud uses Bitnami charts to deploy MariaDB Galera on with helm

 1. We will provision a new Kubernetes Cluster for you if, you already have one skip to step **2**

 2. We will deploy the IBM Cloud Block Storage plug-in, if already have it skip to step **3**

 3. MariaDB Galera deployment

 Step 1 provision Kubernetes Cluster
-----------------------------------

 * Click the **Catalog** button on the top
* Select **Service** from the catalog
* Search for **Kubernetes Service** and click on it

 ![kubernetes-select]

 * You are now at the Kubernetes deployment page, you need to specify some details about the cluster
* Choose a plan **standard** or **free**, the free plan only has one worker node and no subnet, to provision a standard cluster, you will need to upgrade you account to Pay-As-You-Go
* To upgrade to a Pay-As-You-Go account, complete the following steps:

 * In the console, go to Manage > Account.
* Select Account settings, and click Add credit card.
* Enter your payment information, click Next, and submit your information
* Choose **classic** or **VPC**, read the [docs](https://cloud.ibm.com/docs/containers?topic=containers-infrastructure_providers) and choose the most suitable type for yourself

 ![infra-select]

 * Now choose your location settings, for more information please visit [Locations](https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones)
* Choose **Geography** (continent)

 ![location-geo]

 * Choose **Single** or **Multizone**, in single zone your data is only kept in on datacenter, on the other hand with Multizone it is distributed to multiple zones, thus safer in an unforseen zone failure

 ![location-avail]

 * Choose a **Worker Zone** if using Single zones or **Metro** if Multizone

  ![location-worker]

 * If you wish to use Multizone please set up your account with [VRF](https://cloud.ibm.com/docs/dl?topic=dl-overview-of-virtual-routing-and-forwarding-vrf-on-ibm-cloud) or [enable Vlan spanning](https://cloud.ibm.com/docs/vlans?topic=vlans-vlan-spanning#vlan-spanning)
* If at your current location selection, there is no available Virtual LAN, a new Vlan will be created for you

 * Choose a **Worker node setup** or use the preselected one, set **Worker node amount per zone**

 ![worker-pool]

 * Choose **Master Service Endpoint**, In VRF-enabled accounts, you can choose private-only to make your master accessible on the private network or via VPN tunnel. Choose public-only to make your master publicly accessible. When you have a VRF-enabled account, your cluster is set up by default to use both private and public endpoints. For more information visit [endpoints](https://cloud.ibm.com/docs/account?topic=account-service-endpoints-overview).

 ![endpoints]

 * Give cluster a **name**

 ![name-new]

 * Give desired **tags** to your cluster, for more information visit [tags](https://cloud.ibm.com/docs/account?topic=account-tag)

 ![tasg-new]

 * Click **create**

 ![create-new]

 * Wait for you cluster to be provisioned

 ![cluster-prepare]

 * Your cluster is ready for usage

 ![cluster-done]

 Step 2 deploy IBM Cloud Block Storage plug-in
---------------------------------------------

 The Block Storage plug-in is a persistent, high-performance iSCSI storage that you can add to your apps by using Kubernetes Persistent Volumes (PVs).

 * Click the **Catalog** button on the top
* Select **Software** from the catalog
* Search for **IBM Cloud Block Storage plug-in** and click on it

 ![block-search]

 * On the application page Click in the dot next to the cluster, you wish to use
* Click on **Enter or Select Namespace** and choose the default Namespace or use a custom one (if you get error please wait 30 minutes for the cluster to finalize)

 ![block-cluster]

 * Give a **name** to this workspace
* Click **install** and wait for the deployment

 ![block-storage-create]

 Step 3 deploy MariaDB Galera
----------------------------

 We will deploy MariaDB on our cluster 

 * Click the **Catalog** button on the top
* Select **Software** from the catalog
* Search for **MariaDB** and click on it

 ![search]

 * On the application page Click in the dot next to the cluster, you wish to use

 ![cluster-select]

 * Click on **Enter or Select Namespace** and choose the default Namespace or use a custom one

 ![details-namespace]

 * Give a unique **name** to workspace, which you can easily recognize

 ![details-name]

 * Select which resource group you want to use, it's for access controll and billing purposes. For more information please visit [resource groups](https://cloud.ibm.com/docs/account?topic=account-account_setup#bp_resourcegroups)

 ![details-resource]

 * Give **tags** to your MariaDB Galera, for more information visit [tags](https://cloud.ibm.com/docs/account?topic=account-tag)

 ![details-tag]

 * Click on **Parameters with default values**, You can set deployment values or use the default ones

 ![parameters]

 * Please set the MariaDB Galera root password in the parameters

 ![password]

 * After finishing everything, **tick** the box next to the agreements and click **install**

 ![aggreement-create]

 * The MariaDB Galera workspace will start installing, wait a couple of minutes

 ![in-progress]

 * Your MariaDB Galera workspace has been successfully deployed

 ![done]

 Verify MariaDB Galera installation
----------------------------------

 * Go to [Resources](http://cloud.ibm.com/resources) in your browser
* Click on **Clusters**
* Click on your Cluster

 ![resource-select]

 * Now you are at you clusters overview, here Click on **Actions** and **Web terminal** from the dropdown menu

 ![cluster-main]

 * Click **install** - wait couple of minutes

 ![terminal-install]

 * Click on **Actions**
* Click **Web terminal** --> a terminal will open up

 * **Type** in the terminal, please change NAMESPACE to the namespace you choose at the deployment setup:

 
```
$ kubectl get ns

```

![get-ns]

 
```
$ kubectl get pod -n NAMESPACE -o wide 

```

![get-pod]

 
```
$ kubectl get service -n NAMESPACE

```

![get-svc]

 * Enter your pod with bash , please replace PODNAME with your mariadb pod's name

 
```
$ kubectl exec --stdin --tty PODNAME -n NAMESPACE -- /bin/bash

```

![bash]

 * After you are in your pod , please verify that mariadb is running on your pods cluster. Please enter the root password after the prompt

 
```
mysql -u root -p -e "SHOW STATUS LIKE 'wsrep_cluster_size'"

```

![welcome]

 You have succesfully deployed MariaDB Galera on IBM Cloud!

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-galera-on-ibm-cloud/>

TokuDB
=======

   
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

 
 The TokuDB storage engine is for use in high-performance and write-intensive environments, offering increased compression and better performance.

 It is available in an open-source version, included with 64-bit MariaDB (but not enabled by default), and an Enterprise edition available from Tokutek.

 Official TokuDB Product Specs and Manuals are available on the Percona website. See:

 * [TokuDB Documentation](https://www.percona.com/doc/percona-tokudb/index.html)

 TokuDB is available on the following distributions:

 


| Distribution | Introduced |
| --- | --- |
| CentOS 6 64-bit and newer | [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5536-release-notes/) and [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| Debian 7 "wheezy"64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| Fedora 19 64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| openSUSE 13.1 64-bit and newer | [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/) and [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| Red Hat 6 64-bit and newer | [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5536-release-notes/) and [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| Ubuntu 12.10 "quantal" 64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |

  
Note that the default value of [tokudb\_pk\_insert\_mode](../tokudb-system-variables/index#tokudb_pk_insert_mode) will prevent row-based replication from working. To use RBR, change the value of this variable.

 
### Versions of the TokuDB plugin included in MariaDB

 


| TokuDB Version | Introduced | Maturity |
| --- | --- | --- |
| TokuDB from [Percona Server 5.6.49-89.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.49-89.0.html) | [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.46-86.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.46-86.2.html) | [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10144-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.43-84.3](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.43-84.3.html) | [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.42-84.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.42-84.2.html) | [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10038-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.41-84.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.41-84.1.html) | [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10136-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10037-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.39-83.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.39-82.1.html) | [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10035-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.38-83.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.38-83.0.html) | [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10034-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.37-82.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.37-82.2.html) | [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10033-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.36-82.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.1.html) | [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10032-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.36-82.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.0.html) | [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10031-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.35-80.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.35-80.0.html) | [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/), [MariaDB 10.0.30](https://mariadb.com/kb/en/mariadb-10030-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.34-79.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.34-79.1.html) | [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10029-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.33-79.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.33-79.0.html) | [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10119-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10028-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.32-78.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.32-78.1.html) | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.31-77.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.31-77.0.html) | [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/), [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.30-76.3](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.30-76.3.html) | [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10026-release-notes/) | Stable |
| TokuDB from [Percona Server 5.6.26-74.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.30-76.3.html) [[1](#_note-0)] | [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/) | Stable |
| [TokuDB 7.5.7](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-7) | [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10020-release-notes/), [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5544-release-notes/) | Stable |
| [TokuDB 7.5.6](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-6) | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/), [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5543-release-notes/) | Stable |
| [TokuDB 7.5.5](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-5) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/), [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5542-release-notes/) | Stable |
| [TokuDB 7.5.4](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-4) | [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/) | Stable |
| [TokuDB 7.5.3](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-3) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/), [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/) | Stable |
| [TokuDB 7.5.0](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-5-0) | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5540-release-notes/) | Stable |
| [TokuDB 7.1.7](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-1-7) | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/), [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5539-release-notes/) | Stable |
| [TokuDB 7.1.6](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-1-6) | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/), [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5538-release-notes/) | Stable |
| [TokuDB 7.1.5](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudbv-7-1-5) | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/), [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5537-release-notes/) | Stable |
| [TokuDB 7.1.0](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-1-0) | [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/) | Stable |
| [TokuDB 7.0.4](http://docs.tokutek.com/tokudb/tokudb-release-notes.html#tokudb-7-0-4) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/), [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) | Stable |

 
The version of TokuDB in your local MariaDB is available by querying the [tokudb\_version](../tokudb-system-and-status-variables/index#tokudb_version) status variable. For example:

 
```
SHOW VARIABLES LIKE 'tokudb_version';

```


In the MariaDB binary tarballs, only the ones labeled "glibc\_214" have TokuDB.

 
1. [↑](#_ref-0) with this version, TokuDB now follows the version numbering of Percona XtraDB

 More information about TokuDB in MariaDB can be found on the following pages:

  

| Title | Description |
| --- | --- |
|  [Installing TokuDB](../installing-tokudb/index) |  How to install and enable TokuDB in MariaDB.  |
|  [TokuDB Differences](../tokudb-differences/index) |  Things to know before using TokuDB in MariaDB.  |
|  [TokuDB Resources](../tokudb-resources/index) |  Online TokuDB resources.  |
|  [TokuDB Status Variables](../tokudb-status-variables/index) |  TokuDB status variables  |
|  [TokuDB System Variables](../tokudb-system-variables/index) |  TokuDB System Variables  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tokudb/>

Plugin Overview
===============

    Plugins are server components that enhance MariaDB in some way. These can be anything from new storage engines, plugins for enhancing full-text parsing, or even small enhancements, such as a plugin to get a timestamp as an integer.

 Querying Plugin Information
---------------------------

 There are a number of ways to see which plugins are currently active.

 A server almost always has a large number of active plugins, because the server contains a large number of built-in plugins, which are active by default and cannot be uninstalled.

 ### Querying Plugin Information with `SHOW PLUGINS`

 The [SHOW PLUGINS](../show-plugins/index) statement can be used to query information about all active plugins.

 For example:

 
```
SHOW PLUGINS\G;
********************** 1. row **********************
   Name: binlog
 Status: ACTIVE
   Type: STORAGE ENGINE
Library: NULL
License: GPL
********************** 2. row **********************
   Name: mysql_native_password
 Status: ACTIVE
   Type: AUTHENTICATION
Library: NULL
License: GPL
********************** 3. row **********************
   Name: mysql_old_password
 Status: ACTIVE
   Type: AUTHENTICATION
Library: NULL
License: GPL
...

```

If a plugin's `Library` column has a `NULL` value, then the plugin is built-in, and it cannot be uninstalled.

 ### Querying Plugin Information with information\_schema.PLUGINS

 The [information\_schema.PLUGINS](../information_schemaplugins-table/index) table can be queried to get more detailed information about plugins.

 For example:

 
```
SELECT * FROM information_schema.PLUGINS\G
...
*************************** 6. row ***************************
           PLUGIN_NAME: CSV
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: STORAGE ENGINE
   PLUGIN_TYPE_VERSION: 100003.0
        PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR: Brian Aker, MySQL AB
    PLUGIN_DESCRIPTION: CSV storage engine
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: FORCE
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
*************************** 7. row ***************************
           PLUGIN_NAME: MEMORY
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: STORAGE ENGINE
   PLUGIN_TYPE_VERSION: 100003.0
        PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR: MySQL AB
    PLUGIN_DESCRIPTION: Hash based, stored in memory, useful for temporary tables
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: FORCE
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
...

```

If a plugin's `PLUGIN_LIBRARY` column has the `NULL` value, then the plugin is built-in, and it cannot be uninstalled.

 ### Querying Plugin Information with `mysql.plugin`

 The [mysql.plugin](../mysqlplugin-table/index) table can be queried to get information about installed plugins.

 This table only contains information about plugins that have been installed via the following methods:

 * The [INSTALL SONAME](../install-soname/index) statement.
* The [INSTALL PLUGIN](../install-plugin/index) statement.
* The [mariadb-plugin](../mariadb-plugin/index) utility.

 This table does not contain information about:

 * Built-in plugins.
* Plugins loaded with the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) option.
* Plugins loaded with the [--plugin-load](../mariadbd-options/index#-plugin-load) option.

 This table only contains enough information to reload the plugin when the server is restarted, which means it only contains the plugin name and the plugin library.

 For example:

 
```
SELECT * FROM mysql.plugin;

+------+------------+
| name | dl         |
+------+------------+
| PBXT | libpbxt.so |
+------+------------+

```

Installing a Plugin
-------------------

 There are three primary ways to install a plugin:

 * A plugin can be installed dynamically with an SQL statement.
* A plugin can be installed with a [mariadbd](../mariadbd-options/index) option, but it requires a server restart.
* A plugin can be installed with the [mariadb-plugin](../mariadb-plugin/index) utility, while the server is completely offline.

 When you are installing a plugin, you also have to ensure that:

 * The server's plugin directory is properly configured, and the plugin's library is in the plugin directory.
* The server's minimum plugin maturity is properly configured, and the plugin is mature enough to be installed.

 ### Installing a Plugin Dynamically

 A plugin can be installed dynamically by executing either the [INSTALL SONAME](../install-soname/index) or the [INSTALL PLUGIN](../install-plugin/index) statement.

 If a plugin is installed with one of these statements, then a record will be added to the [mysql.plugins](../mysqlplugin-table/index) table for the plugin. This means that the plugin will automatically be loaded every time the server restarts, unless specifically uninstalled or deactivated.

 #### Installing a Plugin with `INSTALL SONAME`

 You can install a plugin dynamically by executing the [INSTALL SONAME](../install-soname/index) statement. [INSTALL SONAME](../install-soname/index) installs all plugins from the given plugin library. This could be required for some plugin libraries.

 For example, to install all plugins in the `server_audit` plugin library (which is currently only the [server\_audit](../mariadb-audit-plugin/index) audit plugin), you could execute the following:

 
```
INSTALL SONAME 'server_audit';

```

#### Installing a Plugin with `INSTALL PLUGIN`

 You can install a plugin dynamically by executing the [INSTALL PLUGIN](../install-plugin/index) statement. [INSTALL PLUGIN](../install-plugin/index) installs a single plugin from the given plugin library.

 For example, to install the [server\_audit](../mariadb-audit-plugin/index) audit plugin from the `server_audit` plugin library, you could execute the following:

 
```
INSTALL PLUGIN server_audit SONAME 'server_audit';

```

### Installing a Plugin with Plugin Load Options

 A plugin can be installed with a [mariadbd](../mariadbd-options/index) option by providing either the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) or the [--plugin-load](../mariadbd-options/index#-plugin-load) option.

 If a plugin is installed with one of these options, then a record will **not** be added to the [mysql.plugins](../mysqlplugin-table/index) table for the plugin. This means that if the server is restarted without the same option set, then the plugin will **not** automatically be loaded.

 #### Installing a Plugin with `--plugin-load-add`

 You can install a plugin with the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) option by specifying the option as a command-line argument to [mariadbd](../mariadbd-options/index) or by specifying the option in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 The [--plugin-load-add](-options/index#-plugin-load-add) option uses the following format:

 * Plugins can be specified in the format `name=library`, where `name` is the plugin name and `library` is the plugin library. This format installs a single plugin from the given plugin library.
* Plugins can also be specified in the format `library`, where `library` is the plugin library. This format installs all plugins from the given plugin library.
* Multiple plugins can be specified by separating them with semicolons.

 For example, to install all plugins in the `server_audit` plugin library (which is currently only the `[server\_audit](../mariadb-audit-plugin/index)` audit plugin) and also the `[ed25519](../authentication-plugin-ed25519/index)` authentication plugin from the `auth_ed25519` plugin library, you could set the option to the following values on the command-line:

 
```
$ mariadbd --user=mysql --plugin-load-add='server_audit' --plugin-load-add='ed25519=auth_ed25519'

```

You could also set the option to the same values in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
plugin_load_add = server_audit
plugin_load_add = ed25519=auth_ed25519

```


Special care must be taken when specifying both the [--plugin-load](../mariadbd-options/index#-plugin-load) option and the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) option together. The [--plugin-load](../mariadbd-options/index#-plugin-load) option resets the plugin load list, and this can cause unexpected problems if you are not aware. The [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) option does **not** reset the plugin load list, so it is much safer to use. See [Specifying Multiple Plugin Load Options](#specifying-multiple-plugin-load-options) for more information.

 
#### Installing a Plugin with `--plugin-load`

 You can install a plugin with the [--plugin-load](../mariadbd-options/index#-plugin-load) option by specifying the option as a command-line argument to [mariadbd](../mariadbd-options/index) or by specifying the option in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).

 The [--plugin-load](../mariadbd-options/index#-plugin-load) option uses the following format:

 * Plugins can be specified in the format `name=library`, where `name` is the plugin name and `library` is the plugin library. This format installs a single plugin from the given plugin library.
* Plugins can also be specified in the format `library`, where `library` is the plugin library. This format installs all plugins from the given plugin library.
* Multiple plugins can be specified by separating them with semicolons.

 For example, to install all plugins in the `server_audit` plugin library (which is currently only the `[server\_audit](../mariadb-audit-plugin/index)` audit plugin) and also the `[ed25519](../authentication-plugin-ed25519/index)` authentication plugin from the `auth_ed25519` plugin library, you could set the option to the following values on the command-line:

 
```
$ mariadbd --user=mysql --plugin-load='server_audit;ed25519=auth_ed25519'

```

You could also set the option to the same values in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
plugin_load = server_audit;ed25519=auth_ed25519

```


Special care must be taken when specifying the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option multiple times, or when specifying both the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option and the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option together. The `[--plugin-load](../mariadbd-options/index#-plugin-load)` option resets the plugin load list, and this can cause unexpected problems if you are not aware. The `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does **not** reset the plugin load list, so it is much safer to use. See [Specifying Multiple Plugin Load Options](#specifying-multiple-plugin-load-options) for more information.

 
#### Specifying Multiple Plugin Load Options

 Special care must be taken when specifying the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option multiple times, or when specifying both the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option and the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option. The `[--plugin-load](../mariadbd-options/index#-plugin-load)` option resets the plugin load list, and this can cause unexpected problems if you are not aware. The `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does **not** reset the plugin load list, so it is much safer to use.

 This can have the following consequences:

 * If the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option is specified **multiple times**, then only the last instance will have any effect. For example, in the following case, the first instance of the option is reset:

 
```
[mariadb]
...
plugin_load = server_audit
plugin_load = ed25519=auth_ed25519

```

* If the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option is specified **after** the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option, then it will also reset the changes made by that option. For example, in the following case, the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does not do anything, because the subsequent `[--plugin-load](../mariadbd-options/index#-plugin-load)` option resets the plugin load list:

 
```
[mariadb]
...
plugin_load_add = server_audit
plugin_load = ed25519=auth_ed25519

```

* In contrast, if the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option is specified **before** the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option, then it will work fine, because the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does not reset the plugin load list. For example, in the following case, both plugins are properly loaded:

 
```
[mariadb]
...
plugin_load = server_audit
plugin_load_add = ed25519=auth_ed25519

```

### Installing a Plugin with mariadb-plugin

 A plugin can be installed with the [mariadb-plugin](../mariadb-plugin/index) utility if the server is completely offline. 

 The syntax is:

 
```
mariadb-plugin [options] <plugin> ENABLE|DISABLE

```

For example, to install the [server\_audit](../mariadb-audit-plugin/index) audit plugin, you could execute the following:

 
```
mariadb-plugin server_audit ENABLE

```

If a plugin is installed with this utility, then a record will be added to the [mysql.plugins](../mysqlplugin-table/index) table for the plugin. This means that the plugin will automatically be loaded every time the server restarts, unless specifically uninstalled or deactivated.

 ### Configuring the Plugin Directory

 When a plugin is being installed, the server looks for the plugin's library in the server's plugin directory. This directory is configured by the `[plugin\_dir](../server-system-variables/index#plugin_dir)` system variable. This can be specified as a command-line argument to `[mariadbd](../mariadbd-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_dir = /usr/lib64/mysql/plugin

```

### Configuring the Minimum Plugin Maturity

 When a plugin is being installed, the server compares the plugin's maturity level against the server's minimum allowed plugin maturity. This can help prevent users from using unstable plugins on production servers. This minimum plugin maturity is configured by the `[plugin\_maturity](../server-system-variables/index#plugin_maturity)` system variable. This can be specified as a command-line argument to `[mariadbd](../mariadbd-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_maturity = stable

```

### Configuring Plugin Activation at Server Startup

 A plugin will be loaded by default when the server starts if:

 * The plugin was installed with the [INSTALL SONAME](../install-soname/index) statement.
* The plugin was installed with the [INSTALL PLUGIN](../install-plugin/index) statement.
* The plugin was installed with the [mariadb-plugin](../mariadb-plugin/index) utility.
* The server is configured to load the plugin with the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) option.
* The server is configured to load the plugin with the [--plugin-load](../mariadbd-options/index#-plugin-load) option.

 This behavior can be changed with special options that take the form `--plugin-name`. For example, for the `[server\_audit](../mariadb-audit-plugin/index)` audit plugin, the special option is called [--server-audit](../mariadb-audit-plugin-system-variables/index#server_audit).

 The possible values for these special options are:

 


| Option Value | Description |
| --- | --- |
| `OFF` | Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table. |
| `ON` | Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled. |
| `FORCE` | Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. |
| `FORCE_PLUS_PERMANENT` | Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) `or` [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running. |

 
A plugin's status can be found by looking at the `PLUGIN_STATUS` column of the [information\_schema.PLUGINS](../information_schemaplugins-table/index) table.

 Uninstalling Plugins
--------------------

 Plugins that are found in the mysql.plugin table, that is those that were installed with [INSTALL SONAME](../install-soname/index), [INSTALL PLUGIN](../install-plugin/index) or [mariadb-plugin](../mariadb-plugin/index) can be uninstalled in one of two ways:

 * The [UNINSTALL SONAME](../uninstall-soname/index) or the [UNINSTALL PLUGIN](../uninstall-plugin/index) statement while the server is running
* With [mariadb-plugin](../mariadb-plugin/index) while the server is offline.

 Plugins that were enabled as a `--plugin-load` option do not need to be uninstalled. If `--plugin-load` is omitted the next time the server starts, or the plugin is not listed as one of the `--plugin-load` entries, the plugin will not be loaded.

 [UNINSTALL PLUGIN](../uninstall-plugin/index) uninstalls a single installed plugin, while [UNINSTALL SONAME](../uninstall-soname/index) uninstalls all plugins belonging to a given library.

 See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [mariadb-plugin](../mariadb-plugin/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plugin-overview/>

Authentication Plugins
=======================

   When a user attempts to log in, the authentication plugin controls how MariaDB Server determines whether the connection is from a legitimate user.

 When creating or altering a user account with the [GRANT](../grant/index), [CREATE USER](../create-user/index) or [ALTER USER](../alter-user/index) statements, you can specify the authentication plugin you want the user account to use by providing the `IDENTIFIED VIA` clause. By default, when you create a user account without specifying an authentication plugin, MariaDB uses the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) plugin.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, there are some notable changes, such as:

 * You can specify multiple authentication plugins for each user account.
* The `root@localhost` user created by [mariadb-install-db](../mariadb-install-db/index) is created with the ability to use two authentication plugins. First, it is configured to try to use the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin. This allows the the `root@localhost` user to login without a password via the local Unix socket file defined by the [socket](../server-system-variables/index#socket) system variable, as long as the login is attempted from a process owned by the operating system `root` user account. Second, if authentication fails with the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, then it is configured to try to use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin. However, an invalid password is initially set, so in order to authenticate this way, a password must be set with [SET PASSWORD](../set-password/index).

   

| Title | Description |
| --- | --- |
|  [Pluggable Authentication Overview](../pluggable-authentication-overview/index) |  The authentication of users is delegated to plugins.  |
|  [Authentication Plugin - mysql\_native\_password](../authentication-plugin-mysql_native_password/index) |  Uses the password hashing algorithm introduced in MySQL 4.1.  |
|  [Authentication Plugin - mysql\_old\_password](../authentication-plugin-mysql_old_password/index) |  The mysql\_old\_password authentication plugin uses the pre-MySQL 4.1 password hashing algorithm.  |
|  [Authentication Plugin - ed25519](../authentication-plugin-ed25519/index) |  Uses the Elliptic Curve Digital Signature Algorithm to securely store users' passwords.  |
|  [Authentication Plugin - GSSAPI](../authentication-plugin-gssapi/index) |  The gssapi authentication plugin uses the GSSAPI interface to authenticate with Kerberos or NTLM.  |
|  [Authentication with Pluggable Authentication Modules (PAM)](../authentication-with-pluggable-authentication-modules-pam/index) |  Uses the Pluggable Authentication Module (PAM) framework to authenticate MariaDB users.  |
|  [Authentication Plugin - Unix Socket](../authentication-plugin-unix-socket/index) |  Uses the user name that owns the process connected to MariaDB's unix socket file.  |
|  [Authentication Plugin - Named Pipe](../authentication-plugin-named-pipe/index) |  Uses the user name that owns the process connected to MariaDB's named pipe on Windows.  |
|  [Authentication Plugin - SHA-256](../authentication-plugin-sha-256/index) |  MySQL supports the sha256\_password and caching\_sha2\_password authentication plugins.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugins/>

Password Validation Plugins
============================

  

| Title | Description |
| --- | --- |
|  [Simple Password Check Plugin](../simple-password-check-plugin/index) |  This plugin checks that passwords meet certain simple criteria.  |
|  [Cracklib Password Check Plugin](../cracklib-password-check-plugin/index) |  This plugin checks password strength using the CrackLib library.  |
|  [Password Reuse Check Plugin](../password-reuse-check-plugin/index) |  Plugin for preventing password reuse.  |
|  [Password Validation Plugin API](../password-validation/index) |  Allows the creation of password validation plugins to check user passwords as they are set.  |
|  [password\_reuse\_check\_interval](../password_reuse_check_interval/index) |  Retention period for password history.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/password-validation-plugins/>

Key Management and Encryption Plugins
======================================

  

| Title | Description |
| --- | --- |
|  [Encryption Key Management](../encryption-key-management/index) |  Managing encryption keys for data-at-rest encryption.  |
|  [File Key Management Encryption Plugin](../file-key-management-encryption-plugin/index) |  A key management and encryption plugin for data-at-rest encryption that uses a plain-text file.  |
|  [Hashicorp Key Management Plugin](../hashicorp-key-management-plugin/index) |  Implement encryption using keys stored in the Hashicorp Vault KMS.  |
|  [AWS Key Management Encryption Plugin](../aws-key-management-encryption-plugin/index) |  A key management and encryption plugin for data-at-rest encryption that use...  |
|  [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide](../aws-key-management-encryption-plugin-setup-guide/index) |  Plugin that uses the AWS Key Management Service.  |
|  [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Advanced Usage](../aws-key-management-encryption-plugin-advanced-usage/index) |  This document assumes you've already set up an Amazon Web Services (AWS) a...  |
|  [Eperi Key Management Encryption Plugin](../eperi-key-management-encryption-plugin/index) |  A key management and encryption plugin for data-at-rest encryption that use...  |
|  [Encryption Plugin API](../encryption-plugin-api/index) |  MariaDB uses plugins to handle key management and encryption of data.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/key-management-and-encryption-plugins/>

Other Plugins
==============

  

| Title | Description |
| --- | --- |
|  [Compression Plugins](../compression-plugins/index) |  Five MariaDB compression libraries are available as plugins.  |
|  [Disks Plugin](../disks-plugin/index) |  Shows metadata about disks on the system.  |
|  [Feedback Plugin](../feedback-plugin/index) |  Collect and send user statistics.  |
|  [Locales Plugin](../locales-plugin/index) |  List compiled-in locales.  |
|  [METADATA\_LOCK\_INFO Plugin](../metadata-lock-info-plugin/index) |  Active metadata locks.  |
|  [MYSQL\_JSON](../mysql_json/index) |  Converting MySQL's JSON data type to MariaDB's format.  |
|  [Query Cache Information Plugin](../query-cache-information-plugin/index) |  Examines the contents of the query cache.  |
|  [Query Response Time Plugin](../query-response-time-plugin/index) |  Records statistics on the time to execute queries on MariaDB Server.  |
|  [SQL Error Log Plugin](../sql-error-log-plugin/index) |  Records SQL-level errors to a log file.  |
|  [User Statistics](../user-statistics/index) |  User Statistics.  |
|  [User Variables Plugin](../user-variables-plugin/index) |  User Variables plugin.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/other-plugins/>

Stored Procedures
==================

   A stored procedure is a routine invoked with a CALL statement. It may have input parameters, output parameters and parameters that are both input parameters and output parameters.

  

| Title | Description |
| --- | --- |
|  [Stored Procedure Overview](../stored-procedure-overview/index) |  A Stored Procedure is a routine invoked with a CALL statement.  |
|  [Stored Routine Privileges](../stored-routine-privileges/index) |  Privileges associated with stored functions and stored procedures.  |
|  [CREATE PROCEDURE](../create-procedure/index) |  Creates a stored procedure.  |
|  [ALTER PROCEDURE](../alter-procedure/index) |  Change stored procedure characteristics.  |
|  [DROP PROCEDURE](../drop-procedure/index) |  Drop stored procedure.  |
|  [SHOW CREATE PROCEDURE](../show-create-procedure/index) |  Returns the string used for creating a stored procedure.  |
|  [SHOW PROCEDURE CODE](../show-procedure-code/index) |  Display internal implementation of a stored procedure.  |
|  [SHOW PROCEDURE STATUS](../show-procedure-status/index) |  Stored procedure characteristics.  |
|  [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) |  Stored routines require extra consideration when binary logging.  |
|  [Information Schema ROUTINES Table](../information-schema-routines-table/index) |  Stored procedures and stored functions information  |
|  [SQL\_MODE=ORACLE](../sql_modeoracle/index) |  MariaDB understands a subset of Oracle's PL/SQL language.  |
|  [Stored Procedure Internals](../stored-procedure-internals/index) |  Internal implementation of MariaDB stored procedures.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-procedures/>

Stored Functions
=================

   A stored function is a defined function that is called from within an SQL statement like a regular function, and returns a single value.

  

| Title | Description |
| --- | --- |
|  [Stored Function Overview](../stored-function-overview/index) |  Function called from within an SQL statement, returning a single value  |
|  [Stored Routine Privileges](../stored-routine-privileges/index) |  Privileges associated with stored functions and stored procedures.  |
|  [CREATE FUNCTION](../create-function/index) |  Creates a stored function.  |
|  [ALTER FUNCTION](../alter-function/index) |  Change the characteristics of a stored function.  |
|  [DROP FUNCTION](../drop-function/index) |  Drop a stored function.  |
|  [SHOW CREATE FUNCTION](../show-create-function/index) |  Statement that created the function.  |
|  [SHOW FUNCTION STATUS](../show-function-status/index) |  Stored function characteristics  |
|  [SHOW FUNCTION CODE](../show-function-code/index) |  Representation of the internal implementation of the stored function  |
|  [Stored Aggregate Functions](../stored-aggregate-functions/index) |  Custom aggregate functions.  |
|  [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) |  Stored routines require extra consideration when binary logging.  |
|  [Stored Function Limitations](../stored-function-limitations/index) |  Restrictions applying to stored functions  |
|  [Information Schema ROUTINES Table](../information-schema-routines-table/index) |  Stored procedures and stored functions information  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-functions/>

Binary Logging of Stored Routines
=================================

     Binary logging can be row-based, statement-based, or a mix of the two. See [Binary Log Formats](../binary-log-formats/index) for more details on the formats. If logging is statement-based, it is possible that a statement will have different effects on the master and on the slave.

 Stored routines are particularly prone to this, for two main reasons:

 * stored routines can be non-deterministic, in other words non-repeatable, and therefore have different results each time they are run.
* the slave thread executing the stored routine on the slave holds full privileges, while this may not be the case when the routine was run on the master.

 The problems with replication will only occur with statement-based logging. If row-based logging is used, since changes are made to rows based on the master's rows, there is no possibility of the slave and master getting out of sync.

 By default, with row-based replication, triggers run on the master, and the effects of their executions are replicated to the slaves. However, starting from [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), it is possible to run triggers on the slaves. See [Running triggers on the slave for Row-based events](../running-triggers-on-the-slave-for-row-based-events/index).

 How MariaDB Handles Statement-Based Binary Logging of Routines
--------------------------------------------------------------

 If the following criteria are met, then there are some limitations on whether stored routines can be created:

 * The [binary log](../binary-log/index) is enabled, and the `[binlog\_format](../replication-and-binary-log-system-variables/index#binlog_format)` system variable is set to `STATEMENT`. See [Binary Log Formats](../binary-log-formats/index) for more information.
* The `[log\_bin\_trust\_function\_creators](../replication-and-binary-log-system-variables/index#log_bin_trust_function_creators)` is set to `OFF`, which is the default value.

 If the above criteria are met, then the following limitations apply:

 * When a [stored function](../stored-functions/index) is created, it must be declared as either `DETERMINISTIC`, `NO SQL` or `READS SQL DATA`, or else an error will occur. MariaDB cannot check whether a function is deterministic, and relies on the correct definition being used.
* To create or modify a stored function, a user requires the `SUPER` privilege as well as the regular privileges. See [Stored Routine Privileges](../stored-routine-privileges/index) for these details.
* [Triggers](../triggers/index) work in the same way, except that they are always assumed to be deterministic for logging purposes, even if this is obviously not the case, such as when they use the [UUID](../uuid/index) function.
* [Triggers](../triggers/index) can also update data. The slave uses the DEFINER attribute to determine which user is taken to have created the trigger.
* Note that the above limitations do no apply to [stored procedures](../stored-procedures/index) or to [events](../events/index).

 ### Examples

 A deterministic function:

 
```
DELIMITER //
 
CREATE FUNCTION trust_me(x INT)
RETURNS INT
DETERMINISTIC
READS SQL DATA
BEGIN
   RETURN (x);
END //
 
DELIMITER ;

```

A non-deterministic function, since it uses the [UUID\_SHORT](../uuid_short/index) function:

 
```
DELIMITER //

CREATE FUNCTION dont_trust_me()
RETURNS INT
BEGIN
   RETURN UUID_SHORT();
END //

DELIMITER ;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-logging-of-stored-routines/>

Stored Routine Privileges
=========================

     It's important to give careful thought to the privileges associated with [stored functions](../stored-functions/index) and [stored procedures](../stored-procedures/index). The following is an explanation of how they work.

 Creating Stored Routines
------------------------

 * To create a stored routine, the `[CREATE ROUTINE](../grant/index#database-privileges)` privilege is needed. The `[SUPER](../grant/index#global-privileges)` privilege is required if a `DEFINER` is declared that's not the creator's account (see [DEFINER clause](#definer-clause) below). The `SUPER` privilege is also required if statement-based binary logging is used. See [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) for more details.

 Altering Stored Routines
------------------------

 * To make changes to, or drop, a stored routine, the `[ALTER ROUTINE](../grant/index#function-privileges)` privilege is needed. The creator of a routine is temporarily granted this privilege if they attempt to change or drop a routine they created, unless the [automatic\_sp\_privileges](../server-system-variables/index#automatic_sp_privileges) variable is set to `0` (it defaults to 1).
* The `SUPER` privilege is also required if statement-based binary logging is used. See [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index) for more details.

 Running Stored Routines
-----------------------

 * To run a stored routine, the `[EXECUTE](../grant/index#procedure-privileges)` privilege is needed. This is also temporarily granted to the creator if they attempt to run their routine unless the [automatic\_sp\_privileges](../server-system-variables/index#automatic_sp_privileges) variable is set to `0`.
* The `[SQL SECURITY clause](#sql-security-clause)` (by default `DEFINER`) specifies what privileges are used when a routine is called. If `SQL SECURITY` is `INVOKER`, the function body will be evaluated using the privileges of the user calling the function. If `SQL SECURITY` is `DEFINER`, the function body is always evaluated using the privileges of the definer account. `DEFINER` is the default. Thus, by default, users who can access the database associated with the stored routine can also run the routine, and potentially perform operations they wouldn't normally have permissions for.
* The creator of a routine is the account that ran the `[CREATE FUNCTION](../create-function/index)` or `[CREATE PROCEDURE](../create-procedure/index)` statement, regardless of whether a `DEFINER` is provided. The definer is by default the creator unless otherwise specified.
* The server automatically changes the privileges in the [mysql.proc](../mysqlproc-table/index) table as required, but will not look out for manual changes.

 ### DEFINER Clause

 If left out, the `DEFINER` is treated as the account that created the stored routine or view. If the account creating the routine has the `SUPER` privilege, another account can be specified as the `DEFINER`.

 ### SQL SECURITY Clause

 This clause specifies the context the stored routine or view will run as. It can take two values - `DEFINER` or `INVOKER`. `DEFINER` is the account specified as the `DEFINER` when the stored routine or view was created (see the section above). `INVOKER` is the account invoking the routine or view.

 As an example, let's assume a routine, created by a superuser who's specified as the `DEFINER`, deletes all records from a table. If `SQL SECURITY=DEFINER`, anyone running the routine, regardless of whether they have delete privileges, will be able to delete the records. If `SQL SECURITY = INVOKER`, the routine will only delete the records if the account invoking the routine has permission to do so.

 `INVOKER` is usually less risky, as a user cannot perform any operations they're normally unable to. However, it's not uncommon for accounts to have relatively limited permissions, but be specifically granted access to routines, which are then invoked in the `DEFINER` context.

 Dropping Stored Routines
------------------------

 All privileges that are specific to a stored routine will be dropped when a [DROP FUNCTION](../drop-function/index) or [DROP ROUTINE](drop-routine) is run. However, if a [CREATE OR REPLACE FUNCTION](../create-function/index) or [CREATE OR REPLACE PROCEDURE](../create-procedure/index) is used to drop and replace and the routine, any privileges specific to that routine will not be dropped.

 See Also
--------

 * [Changing the DEFINER of MySQL stored routines etc.](https://mariadb.com/blog/changing-definer-mysql-stored-routines-etc) - maria.com post on what to do after you've dropped a user, and now want to change the DEFINER on all database objects that currently have it set to this dropped user.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-routine-privileges/>

MariaDB Audit Plugin - Installation
===================================

    The `server_audit` plugin logs the server's activity. For each client session, it records who connected to the server (i.e., user name and host), what queries were executed, and which tables were accessed and server variables that were changed. This information is stored in a rotating log file or it may be sent to the local syslogd.

 Locating the Plugin
-------------------

 The `server_audit` plugin's shared library is included in MariaDB packages as the `server_audit.so` or `server_audit.dll` shared library on systems where it can be built.

 The plugin must be located in the plugin directory, the directory containing all plugin libraries for MariaDB. The path to this directory is configured by the `[plugin\_dir](../server-system-variables/index#plugin_dir)` system variable. To see the value of this variable and thereby determine the file path of the plugin library, execute the following SQL statement:

 
```
SHOW GLOBAL VARIABLES LIKE 'plugin_dir';

+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+

```

Check the directory returned at the filesystem level to make sure that you have a copy of the plugin library, `server_audit.so` or `server_audit.dll`, depending on your system. It's included in recent installations of MariaDB. If you do not have it, you should upgrade MariaDB.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'server_audit';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = server_audit

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'server_audit';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Prohibiting Uninstallation
--------------------------

 The `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` statements may be used to uninstall plugins. For the `server_audit` plugin, you might want to disable this capability. To prevent the plugin from being uninstalled, you could set the the `[server\_audit](../mariadb-audit-plugin-system-variables/index#server_audit)` option to `FORCE_PLUS_PERMANENT` in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) after the plugin is loaded once:

 
```
[mariadb]
...
plugin_load_add = server_audit
server_audit=FORCE_PLUS_PERMANENT

```

Once you've added the option to the server's option file and restarted the server, the plugin can't be uninstalled. If someone tries to uninstall the audit plugin, then an error message will be returned. Below is an example of the error message:

 
```
UNINSTALL PLUGIN server_audit;

ERROR 1702 (HY000):
Plugin 'server_audit' is force_plus_permanent and can not be unloaded

```

For more information on `FORCE_PLUS_PERMANENT` and other option values for the `[server\_audit](../mariadb-audit-plugin-system-variables/index#-server-audit)` option, see [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-installation/>

MariaDB Audit Plugin - Configuration
====================================

    After the audit plugin has been installed and loaded, there will be some new global variables within MariaDB. These can be used to configure many components, limits, and methods related to auditing the server. You may set these variables related to the logs, such as their location, size limits, rotation parameters, and method of logging information. You may also set what information is logged, such connects, disconnects, and failed attempts to connect. You can also have the audit plugin log queries, read and write access to tables. So as not to overload your logs, the audit plugin can be configured based on lists of users. You can include or exclude the activities of specific users in the logs.

 To see a list of [audit plugin-related variables](../mariadb-audit-plugin-system-variables/index) on the server and their values, execute the follow while connected to the server:

 
```
SHOW GLOBAL VARIABLES LIKE 'server_audit%';

+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| server_audit_events           | CONNECT,QUERY,TABLE   |
| server_audit_excl_users       |                       |
| server_audit_file_path        | server_audit.log      |
| server_audit_file_rotate_now  | OFF                   |
| server_audit_file_rotate_size | 1000000               |
| server_audit_file_rotations   | 9                     |
| server_audit_incl_users       |                       |
| server_audit_logging          | ON                    |
| server_audit_mode             | 0                     |
| server_audit_output_type      | file                  |
| server_audit_query_log_limit  | 1024                  |
| server_audit_syslog_facility  | LOG_USER              |
| server_audit_syslog_ident     | mysql-server_auditing |
| server_audit_syslog_info      |                       |
| server_audit_syslog_priority  | LOG_INFO              |
+-------------------------------+-----------------------+

```

The values of these variables can be changed by an administrator with the `SUPER` privilege, using the [`SET`](../set/index) statement. Below is an example of how to disable audit logging:

 
```
SET GLOBAL server_audit_logging=OFF;

```

Although it is possible to change all of the variables shown above, some of them may be reset when the server restarts. Therefore, you may want set them in the configuration file (e.g., `/etc/my.cnf.d/server.cnf`) to ensure the values are the same after a restart: 

 
```
[server]
... 
server_audit_logging=OFF 
…

```

For the reason given in the paragraph above, you would not generally set variables related to the auditing plugin using the [`SET`](../set/index) statement. However, you might do so to test settings before making them more permanent. Since one cannot always restart the server, you would use the [`SET`](../set/index) statement to change immediately the variables and then include the same settings in the configuration file so that the variables are set again as you prefer when the server is restarted.

 #### Configuring Logs and Setting Other Variables

 Of all of the server variables you can set, you may want to set initially the [server\_audit\_events](../server_audit-system-variables/index#server_audit_events) variable to tell the Audit Plugin which events to log. The [Log Settings documentation page](../mariadb-audit-plugin-log-settings/index) describes in detail the choices you have and provides examples of log entries related to them.

 You can see a detailed list of system variables related to the MariaDB Audit Plugin on the [System Variables documentation page](../mariadb-audit-plugin-system-variables/index). Status variables related to the Audit Plugin are listed and explained on the [Status Variables documentation page](../mariadb-audit-plugin-status-variables/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-configuration/>

MariaDB Audit Plugin - Log Settings
===================================

    Events that are logged by the MariaDB Audit Plugin are grouped generally into different types: connect, query, and table events. To log based on these types of events, set the variable, [server\_audit\_events](../server_audit-system-variables/index#server_audit_events) to `CONNECT`, `QUERY`, or `TABLE`. To have the Audit Plugin log more than one type of event, put them in a comma-separated list like so:

 
```
SET GLOBAL server_audit_events = 'CONNECT,QUERY,TABLE';

```

 You can put the equivalent of this in the configuration file like so:

 
```
[mysqld]
...
server_audit_events=connect,query

```

By default, logging is set to `OFF`. To enable it, set the [server\_audit\_logging](../server_audit-system-variables/index#server_audit_logging) variable to `ON`. Note that if the [query cache](../query-cache/index) is enabled, and a query is returned from the query cache, no `TABLE` records will appear in the log since the server didn't open or access any tables and instead relied on the cached results. So you may want to disable query caching.

 There are actually a few types of events that may be logged, not just the three common ones mentioned above. A full list of related system variables is detailed on the [Server\_Audit System Variables](../server_audit-system-variables/index) page, and status variables on the [Server\_Audit Status Variables](../server_audit-status-variables/index) page of this documentation. Some of the major ones are highlighted below:

 


| Type | Description |
| --- | --- |
| CONNECT | Connects, disconnects and failed connects—including the error code |  |
| QUERY | Queries executed and their results in plain text, including failed queries due to syntax or permission errors |  |
| TABLE | Tables affected by query execution |  |
| QUERY\_DDL | Similar to `QUERY`, but filters only DDL-type queries (`CREATE`, `ALTER`, `DROP`, `RENAME` and `TRUNCATE`). There are some exceptions however. `RENAME USER` is not logged, while `CREATE/DROP [PROCEDURE / FUNCTION / USER]` are only logged from [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/), [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10422-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10513-release-notes/) and [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/). In earlier versions they are not logged. See [MDEV-23457](https://jira.mariadb.org/browse/MDEV-23457). |
| QUERY\_DML | Similar to `QUERY`, but filters only DML-type queries (`DO`, `CALL`, `LOAD DATA/XML`, `DELETE`, `INSERT`, `SELECT`, `UPDATE`, `HANDLER` and `REPLACE` statements) |
| QUERY\_DML\_NO\_SELECT | Similar to `QUERY_DML`, but doesn't log SELECT queries. (since version 1.4.4) (`DO`, `CALL`, `LOAD DATA/XML`, `DELETE`, `INSERT`, `UPDATE`, `HANDLER` and `REPLACE` statements) |
| QUERY\_DCL | Similar to `QUERY`, but filters only DCL-type queries (`CREATE USER`, `DROP USER`, `RENAME USER`, `GRANT`, `REVOKE` and `SET PASSWORD` statements) |

 
Since there are other types of queries besides DDL and DML, using the `QUERY_DDL` and `QUERY_DML` options together is not equivalent to using `QUERY`. Starting in version 1.3.0 of the Audit Plugin, there is the `QUERY_DCL` option for logging DCL types of queries (e.g., `GRANT` and `REVOKE` statements). In the same version, the [server\_audit\_query\_log\_limit](../server_audit-system-variables/index#server_audit_query_log_limit) variable was added to be able to set the length of a log record. Previously, a log entry would be truncated due to long query strings.

 Logging Connect Events
----------------------

 If the Audit Plugin has been configured to log connect events, it will log connects, disconnects, and failed connects. For a failed connection, the log includes the error code.

 It's possible to define a list of users for which events can be excluded or included for tracing their database activities. This list will be ignored, though, for the loggings of connect events. This is because auditing standards distinguish between technical and physical users. Connects need to be logged for all types of users; access to objects need to be logged only for physical users.

 Logging Query Events
--------------------

 If `QUERY`, `QUERY_DDL`, `QUERY_DML`, `QUERY_DML_NO_SELECT`, and/or `QUERY_DCL` event types are enabled, then the corresponding types of queries that are executed will be logged for defined users. The queries will be logged exactly as they are executed, in plain text. This is a security vulnerability: anyone who has access to the log files will be able to read the queries. So make sure that only trusted users have access to the log files and that the files are in a protected location. An alternative is to use `TABLE` event type instead of the query-related event types.

 Queries are also logged if they cannot be executed, if they're unsuccessful. For example, a query will be logged because of a syntax error or because the user doesn't have the privileges necessary to access an object. These queries can be parsed by the error code that's provided in the log.

 You may find failed queries to be more interesting: They can reveal problems with applications (e.g., an SQL statement in an application that doesn't match the current schema). They can also reveal if a malicious user is guessing at the names of tables and columns to try to get access to data.

 Below is an example in which a user attempts to execute an `UPDATE` statement on a table for which he does not have permission: 

 
```
UPDATE employees 
SET salary = salary * 1.2 
WHERE emp_id = 18236;

ERROR 1142 (42000): 
UPDATE command denied to user 'bob'@'localhost' for table 'employees'

```

Looking in the Audit Plugin log (`server_audit.log`) for this entry, you can see the following entry:

 
```
20170817 11:07:18,ip-172-30-0-38,bob,localhost,15,46,QUERY,company,
'UPDATE employees SET salary = salary * 1.2 WHERE emp_id = 18236',1142

```

This log entry would be on one line, but it's reformatted here for better rendering. Looking at this log entry, you can see the date and time of the query, followed by the server host, the user and host for the account. Next is the connection and query identification numbers (i.e., `15` and `46`). After the log event type (i.e., `QUERY`), the database name (i.e., `company`), the query, and the error number is recorded.

 Notice that the last value in the log entry is `1142`. That's the error number for the query. To find failed queries, you would look for two elements: the notation indicating that it's a `QUERY` entry, and the last value for the entry. If the query is successful, the value will be `0`.

 ### Queries Not Included in Subordinate Query Event Types

 Note that the `QUERY` event type will log queries that are not included in any of the subordinate `QUERY_*` event types, such as:

 * CREATE FUNCTION
* DROP FUNCTION
* CREATE PROCEDURE
* DROP PROCEDURE
* SET
* CHANGE MASTER TO
* FLUSH
* KILL
* CHECK
* OPTIMIZE
* LOCK
* UNLOCK
* ANALYZE
* INSTALL PLUGIN
* UNINSTALL PLUGIN
* INSTALL SONAME
* UNINSTALL SONAME
* EXPLAIN

 Logging Table Events
--------------------

 MariaDB has the ability to record table events in the logs—this is not a feature of MySQL. This feature is the only way to log which tables have been accessed through a view, a stored procedure, a stored function, or a trigger. Without this feature, a log entry for a query shows only the view, stored procedure or function used, not the underlying tables. Of course, you could create a custom application to parse each query executed to find the SQL statements used and the tables accessed, but that would be a drain on system resources. Table event logging is much simpler: it adds a line to the log for each table accessed, without any parsing. It includes notes as to whether it was a read or a write.

 If you want to monitor user access to specific databases or tables (e.g., `mysql.user`), you can search the log for them. Then if you want to see a query which accessed a certain table, the audit log entry will include the query identificaiton number. You can use it to search the same log for the query entry. This can be useful when searching a log containing tens of thousands of entries.

 Because of the `TABLE` option, you may disable query logging and still know who accessed which tables. You might want to disable `QUERY` event logging to prevent sensitive data from being logged. Since *table* event logging will log who accessed which table, you can still watch for malicious activities with the log. This is often enough to fulfill auditing requirements.

 Below is an example with both `TABLE` and `QUERY` events logging. For this scenario, suppose there is a [VIEW](../create-view/index) in which columns are selected from a few tables in a `company` database. The underlying tables are related to sensitive employee information, in particular salaries. Although we may have taken precautions to ensure that only certain user accounts have access to those tables, we will monitor the Audit Plugin logs for anyone who queries them—directly or indirectly through a view.

 
```
20170817 16:04:33,ip-172-30-0-38,root,localhost,29,913,READ,company,employees,
20170817 16:04:33,ip-172-30-0-38,root,localhost,29,913,READ,company,employees_salaries,
20170817 16:04:33,ip-172-30-0-38,root,localhost,29,913,READ,company,ref_job_titles,
20170817 16:04:33,ip-172-30-0-38,root,localhost,29,913,READ,company,org_departments,
20170817 16:04:33,ip-172-30-0-38,root,localhost,29,913,QUERY,company,
'SELECT * FROM employee_pay WHERE title LIKE \'%Executive%\'  OR title LIKE \'%Manager%\'',0

```

Although the user executed only one [SELECT](../select/index) statement, there are multiple entries to the log: one for each table accessed and one entry for the query on the view, (i.e., `employee_pay`). We know primarily this is all for one query because they all have the same connection and query identification numbers (i.e., `29` and `913`).

 Logging User Activities
-----------------------

 The Audit Plugin will log the database activities of all users, or only the users that you specify. A database activity is defined as a *query* event or a *table* event. *Connect* events are logged for all users.

 You may specify users to include in the log with the `server_audit_incl_users` variable or exclude users with the `server_audit_excl_users` variable. This can be useful if you would like to log entries, but are not interested in entries from trusted applications and would like to exclude them from the logs.

 You would typically use either the `server_audit_incl_users` variable or the `server_audit_excl_users` variable. You may, though, use both variables. If a username is inadvertently listed in both variables, database activities for that user will be logged because `server_audit_incl_users` takes priority.

 Although MariaDB considers a user as the combination of the username and hostname, the Audit Plugin logs only based on the username. MariaDB uses both the username and hostname so as to grant privileges relevant to the location of the user. Privileges are not relevant though for tracing the access to database objects. The host name is still recorded in the log, but logging is not determined based on that information.

 The following example shows how to add a new username to the `server_audit_incl_users` variable without removing previous usernames:

 
```
SET GLOBAL server_audit_incl_users = CONCAT(@@global.server_audit_incl_users, ',Maria');

```

Remember to add also any new users to be included in the logs to the same variable in MariaDB configuration file. Otherwise, when the server restarts it will discard the setting.

 Excluding or Including Users
----------------------------

 By default events from all users are logged, but certain users can be excluded from logging by using the [server\_audit\_excl\_users](../server_audit-system-variables/index#server_audit_excl_users) variable. For example, to exclude users *valerianus* and *rocky* from having their events logged:

 
```
server_audit_excl_users=valerianus,rocky

```

This option is primarily used to exclude the activities of trusted applications.

 Alternatively, [server\_audit\_incl\_users](../server_audit-system-variables/index#server_audit_incl_users) can be used to specifically include users. Both variables can be used, but if a user appears on both lists, [server\_audit\_incl\_users](../server_audit-system-variables/index#server_audit_incl_users) has a higher priority, and their activities will be logged.

 Note that `CONNECT` events are always logged for all users, regardless of these two settings. Logging is also based on username only, not the username and hostname combination that MariaDB uses to determine privileges.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-log-settings/>

MariaDB Audit Plugin - Location and Rotation of Logs
====================================================

     Logs can be written to a separate file or to the system logs. If you prefer to have the logging separated from other system information, the value of the variable, [server\_audit\_output\_type](../mariadb-audit-plugin-system-variables/index#server_audit_output_type) should be set to `file`. Incidentally, `file` is the only option on Windows systems.

 You can force a rotation by enabling the [server\_audit\_file\_rotate\_now](../mariadb-audit-plugin-system-variables/index#server_audit_file_rotate_now) variable like so:

 
```
SET GLOBAL server_audit_file_rotate_now = ON;

```

### Separate log files

 In addition to setting [server\_audit\_output\_type](../mariadb-audit-plugin-system-variables/index#server_audit_output_type), you will have to provide the file path and name of the audit file. This is set in the variable, [server\_audit\_file\_path](../mariadb-audit-plugin-system-variables/index#server_audit_file_path). You can set the file size limit of the log file with the variable, [server\_audit\_file\_rotate\_size](../mariadb-audit-plugin-system-variables/index#server_audit_file_rotate_size). 

 So, if rotation is on and the log file has reached the size limit you set, a copy is created with a consecutive number as extension, the original file will be truncated to be used for the auditing again. To limit the number of log files created, set the variable, [server\_audit\_file\_rotations](../mariadb-audit-plugin-system-variables/index#server_audit_file_rotations). You can force log file rotation by setting the variable, [server\_audit\_file\_rotate\_now](../mariadb-audit-plugin-system-variables/index#server_audit_file_rotate_now) to a value of `ON`. When the number of files permitted is reached, the oldest file will be overwritten. Below is an example of how the variables described above might be set in a server's configuration files:

 
```
[mysqld]
...
server_audit_file_rotate_now=ON 
server_audit_file_rotate_size=1000000 
server_audit_file_rotations=5
...

```

### System logs

 For security reasons, it's better sometimes to use the system logs instead of a local file owned by the `mysql` user. To do this, the value of [server\_audit\_output\_type](../mariadb-audit-plugin-system-variables/index#server_audit_output_type) needs to be set to `syslog`. Advanced configurations, such as using a remote `syslogd` service, are part of the `syslogd` configuration.

 The variables, [server\_audit\_syslog\_ident](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_ident) and [server\_audit\_syslog\_info](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_info) can be used to identify a system log entry made by the audit plugin. If a remote `syslogd` service is used for several MariaDB servers, these same variables are also used to identify the MariaDB server.

 Below is an example of a system log entry taken from a server which had [server\_audit\_syslog\_ident](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_ident) set to the default value of `mysql­-server_auditing`, and [server\_audit\_syslog\_info](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_info) set to `<prod1>`.

 
```
Aug 717:19:58localhostmysql-­server_auditing: 
<prod1> localhost.localdomain,root,localhost,1,7, 
QUERY, mysql, 'SELECT * FROM user',0

```

Although the default values for [server\_audit\_syslog\_facility](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_facility) and [server\_audit\_syslog\_priority](../mariadb-audit-plugin-system-variables/index#server_audit_syslog_priority) should be sufficient in most cases, they can be changed based on the definition in `syslog.h` for the functions `openlog()` and `syslog()`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-location-and-rotation-of-logs/>

MariaDB Audit Plugin - Log Format
=================================

    The audit plugin logs user access to MariaDB and its objects. The audit trail (i.e., audit log) is a set of records, written as a list of fields to a file in a plain‐text format. The fields in the log are separated by commas. The format used for the plugin's own log file is slightly different from the format used if it logs to the system log because it has its own standard format. The general format for the logging to the plugin's own file is defined like the following:

 
```
[timestamp],[serverhost],[username],[host],[connectionid],
[queryid],[operation],[database],[object],[retcode]

```

If the [server\_audit\_output\_type](../server_audit-system-variables/index#server_audit_output_type) variable is set to `syslog` instead of the default, `file`, the audit log file format will be as follows:

 
```
[timestamp][syslog_host][syslog_ident]:[syslog_info][serverhost],[username],[host],
[connectionid],[queryid],[operation],[database],[object],[retcode]

```




| Item logged | Description |
| --- | --- |
| timestamp | Time at which the event occurred. If syslog is used, the format is defined by `syslogd`. |
| syslog\_host | Host from which the syslog entry was received. |
| syslog\_ident | For identifying a system log entry, including the MariaDB server. |
| syslog\_info | For providing information for identifying a system log entry. |
| serverhost | The MariaDB server host name. |
| username | Connected user. |
| host | Host from which the user connected. |
| connectionid | Connection ID number for the related operation. |
| queryid | Query ID number, which can be used for finding the relational table events and related queries. For TABLE events, multiple lines will be added. |
| operation | Recorded action type: CONNECT, QUERY, READ, WRITE, CREATE, ALTER, RENAME, DROP. |
| database | Active database (as set by [USE](../use/index)). |
| object | Executed query for QUERY events, or the table name in the case of TABLE events. |
| retcode | Return code of the logged operation. |

 
Various events will result in different audit records. Some events will not return a value for some fields (e.g., when the active database is not set when connecting to the server).

 Below is a generic example of the output for connect events, with placeholders representing data. These are events in which a user connected, disconnected, or tried unsuccessfully to connect to the server.

 
```
[timestamp],[serverhost],[username],[host],[connectionid],0,CONNECT,[database],,0 
[timestamp],[serverhost],[username],[host],[connectionid],0,DISCONNECT,,,0 
[timestamp],[serverhost],[username],[host],[connectionid],0,FAILED_CONNECT,,,[retcode]

```

Here is the one audit record generated for each query event:

 
```
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],QUERY,[database],[object], [retcode]

```

Below are generic examples of records that are entered in the audit log for each type of table event:

 
```
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],CREATE,[database],[object], 
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],READ,[database],[object], 
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],WRITE,[database],[object], 
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],ALTER,[database],[object], 
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],RENAME,[database], 
[object_old]|[database_new].[object_new], 
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],DROP,[database],[object],

```

Starting in version 1.2.0, passwords are hidden in the log for certain types of queries. They are replaced with asterisks for `GRANT`, `CREATE USER`, `CREATE MASTER`, `CREATE SERVER`, and `ALTER SERVER` statements. Passwords, however, are not replaced for the `PASSWORD()` and `OLD_PASSWORD()` functions when they are used inside other SQL statements (i.e., SET PASSWORD`).`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-log-format/>

MariaDB Audit Plugin - Status Variables
=======================================

    There are a few status variables related to the [MariaDB Audit Plugin](../server_audit-mariadb-audit-plugin/index), once it has been [installed](../mariadb-audit-plugin-entitymdashentity-installation/index). These variables can be displayed using the [SHOW STATUS](../show-status/index) statement like so:

 
```
SHOW STATUS LIKE 'server_audit%';

+----------------------------+------------------+
| Variable_name              | Value            |
+----------------------------+------------------+
| Server_audit_active        | ON               |
| Server_audit_current_log   | server_audit.log |
| Server_audit_last_error    |                  |
| Server_audit_writes_failed | 0                |
+----------------------------+------------------+

```

### Status Variables

 Below is a list of all status variables related to the Audit Plugin. These cannot be set: These are not to be confused with system variables, which can be set. See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with the [SHOW STATUS](../show-status/index) statement. See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Server_audit_active`

 * **Description:** If the auditing is actually working. It gets the ON value when the logging is successfully started. Then it can get the OFF value if the logging was stopped or log records can't be properly stored due to file or syslog errors.
* **Data Type:** `boolean`

 

---

 #### `Server_audit_current_log`

 * **Description:** The name of the logfile or the SYSLOG parameters that are in current use.
* **Data Type:** `string`

 

---

 #### `Server_audit_last_error`

 * **Description:** If something went wrong with the logging here you can see the message.
* **Data Type:** `string`

 

---

 #### `Server_audit_writes_failed`

 * **Description:** The number of log records since last logging-start that weren't properly stored because of errors of any kind. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-status-variables/>

Release Notes - MariaDB Audit Plugin
=====================================

   Notice that as of MariaDB versions 5.5.42 and 10.0.10 the Audit Plugin is included with MariaDB and not distributed separately, so separate release notes are no longer kept.

  

| Title | Description |
| --- | --- |
|  [MariaDB Audit Plugin 1.1.7 Release Notes](https://mariadb.com/kb/en/mariadb-audit-plugin-117-release-notes/) |  Status: Stable | Release Date: 1 May 2014  |
|  [MariaDB Audit Plugin 1.1.6 Release Notes](https://mariadb.com/kb/en/mariadb-audit-plugin-116-release-notes/) |  Status: Stable | Release Date: 27 Mar 2014  |
|  [MariaDB Audit Plugin 1.1.5 Release Notes](https://mariadb.com/kb/en/mariadb-audit-plugin-115-release-notes/) |  Status: Stable | Release Date: 25 Feb 2014  |
|  [MariaDB Audit Plugin 1.1.4 Release Notes](https://mariadb.com/kb/en/mariadb-audit-plugin-114-release-notes/) |  Status: Stable | Release Date: 21 Feb 2014  |
|  [MariaDB Audit Plugin 1.1.3 Release Notes](https://mariadb.com/kb/en/mariadb-audit-plugin-113-release-notes/) |  Status: Stable | Release Date: 7 Nov 2013  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/release-notes-mariadb-audit-plugin/>

MariaDB Audit Plugin - Versions
===============================

    Below is a list of the releases of the MariaDB Audit Plugin, the most recent version first, and in which versions of MariaDB each plugin version was included.

 


| Version | Introduced |
| --- | --- |
| 1.4.13 | [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/), [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/) |
| 1.4.10 | [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) |
| 1.4.7 | [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) |
| 1.4.5 | [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) |
| 1.4.4 | [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5561-release-notes/), [MariaDB 10.0.36](https://mariadb.com/kb/en/mariadb-10036-release-notes/), [MariaDB 10.1.34](https://mariadb.com/kb/en/mariadb-10134-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) |
| 1.4.0 | [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5548-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10024-release-notes/), [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |
| 1.3.0 | [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5543-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/), [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/) |
| 1.2.0 | [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5542-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/), [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [1.1.7](https://mariadb.com/kb/en/mariadb-audit-plugin-117-release-notes/) | [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5538-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/), [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [1.1.6](https://mariadb.com/kb/en/mariadb-audit-plugin-116-release-notes/) | [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5537-release-notes/), [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| [1.1.5](https://mariadb.com/kb/en/mariadb-audit-plugin-115-release-notes/) | [MariaDB 10.0.09](https://mariadb.com/kb/en/mariadb-10009-release-notes/) |
| [1.1.4](https://mariadb.com/kb/en/mariadb-audit-plugin-114-release-notes/) | [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5536-release-notes/) |
| [1.1.3](https://mariadb.com/kb/en/mariadb-audit-plugin-113-release-notes/) | [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/), [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-versions/>

MariaDB Audit Plugin Options and System Variables
=================================================

    There are a several options and system variables related to the [MariaDB Audit Plugin](../server_audit-mariadb-audit-plugin/index), once it has been [installed](../mariadb-audit-plugin-entitymdashentity-installation/index). System variables can be displayed using the [SHOW VARIABLES](../show-variables/index) statement like so:

 
```
SHOW GLOBAL VARIABLES LIKE '%server_audit%';

+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| server_audit_events           | CONNECT,QUERY,TABLE   |
| server_audit_excl_users       |                       |
| server_audit_file_path        | server_audit.log      |
| server_audit_file_rotate_now  | OFF                   |
| server_audit_file_rotate_size | 1000000               |
| server_audit_file_rotations   | 9                     |
| server_audit_incl_users       |                       |
| server_audit_logging          | ON                    |
| server_audit_mode             | 0                     |
| server_audit_output_type      | file                  |
| server_audit_query_log_limit  | 1024                  |
| server_audit_syslog_facility  | LOG_USER              |
| server_audit_syslog_ident     | mysql-server_auditing |
| server_audit_syslog_info      |                       |
| server_audit_syslog_priority  | LOG_INFO              |
+-------------------------------+-----------------------+

```

To change the value of one of these variables, you can use the `SET` statement, or set them at the command-line when starting MariaDB. It's recommended that you set them in the MariaDB configuration for the server like so:

 
```
[mariadb]
...
server_audit_excl_users='bob,ted'
...

```

### System Variables

 Below is a list of all system variables related to the Audit Plugin. See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them. See also the [full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `server_audit_events`

 * **Description:** If set, then this restricts audit logging to certain event types. If not set, then every event type is logged to the audit log. For example: *SET GLOBAL server\_audit\_events='connect, query'*
* **Commandline:** `--server-audit-events=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty string
* **Valid Values:**
	+ `CONNECT`, `QUERY`, `TABLE` (MariaDB Audit Plugin < 1.2.0)
	+ `CONNECT`, `QUERY`, `TABLE`, `QUERY_DDL`, `QUERY_DML` (MariaDB Audit Plugin >= 1.2.0)
	+ `CONNECT`, `QUERY`, `TABLE`, `QUERY_DDL`, `QUERY_DML`, `QUERY_DCL` (MariaDB Audit Plugin >=1.3.0)
	+ `CONNECT`, `QUERY`, `TABLE`, `QUERY_DDL`, `QUERY_DML`, `QUERY_DCL`, `QUERY_DML_NO_SELECT` (MariaDB Audit Plugin >= 1.4.4)
	+ See [MariaDB Audit Plugin - Versions](../mariadb-audit-plugin-versions/index) to determine which MariaDB releases contain each MariaDB Audit Plugin versions.

 

---

 #### `server_audit_excl_users`

 * **Description:** If not empty, it contains the list of users whose activity will NOT be logged. For example: `SET GLOBAL server_audit_excl_users='user_foo, user_bar'`. CONNECT records aren't affected by this variable - they are always logged. The user is still logged if it's specified in [server\_audit\_incl\_users](#server_audit_incl_users).
* **Commandline:** `--server-audit-excl-users=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty string
* **Size limit:** 1024 characters

 

---

 #### `server_audit_file_path`

 * **Description:** When [server\_audit\_output\_type=file](#server_audit_output_type), sets the path and the filename to the log file. If the specified path exists as a directory, then the log will be created inside that directory with the name 'server\_audit.log'. Otherwise the value is treated as a filename. The default value is 'server\_audit.log', which means this file will be created in the database directory.
* **Commandline:** `--server-audit-file-path=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `server_audit.log`

 

---

 #### `server_audit_file_rotate_now`

 * **Description:** When [server\_audit\_output\_type=file](#server_audit_output_type), the user can force the log file rotation by setting this variable to ON or 1.
* **Commandline:** `--server-audit-rotate-now[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `server_audit_file_rotate_size`

 * **Description:** When [server\_audit\_output\_type=file](#server_audit_output_type), it limits the size of the log file to the given amount of bytes. Reaching that limit turns on the rotation - the current log file is renamed as 'file\_path.1'. The empty log file is created as 'file\_path' to log into it. The default value is 1000000.
* **Commandline:** `--server-audit-rotate-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000000`
* **Range:** `100` to `9223372036854775807`

 

---

 #### `server_audit_file_rotations`

 * **Description:** When [server\_audit\_output\_type=file](#server_audit_output_type)', this specifies the number of rotations to save. If set to 0 then the log never rotates. The default value is 9.
* **Commandline:** `--server-audit-rotations=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `9`
* **Range:** `0` to `999`

 

---

 #### `server_audit_incl_users`

 * **Description:** If not empty, it contains a comma-delimited list of users whose activity will be logged. For example: `SET GLOBAL server_audit_incl_users='user_foo, user_bar'`. CONNECT records aren't affected by this variable - they are always logged. This setting has higher priority than [server\_audit\_excl\_users](#server_audit_excl_users). So if the same user is specified both in incl\_ and excl\_ lists, they will still be logged.
* **Commandline:** `--server-audit-incl-users=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty string
* **Size limit:** 1024 characters

 

---

 #### `server_audit_loc_info`

 * **Description:** Used by plugin internals. It has no useful meaning to users.
	+ In earlier versions, users see it as a read-only variable.
	+ In later versions, it is hidden from the user.
* **Commandline:** N/A
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** Empty string
* **Introduced:** [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10112-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10024-release-notes/), [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5548-release-notes/)
* **Hidden:** [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10028-release-notes/), [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5553-release-notes/)

 

---

 #### `server_audit_logging`

 * **Description:** Enables/disables the logging. Expected values are ON/OFF. For example: `SET GLOBAL server_audit_logging=on` If the server\_audit\_output\_type is FILE, this will actually create/open the logfile so the [server\_audit\_file\_path](#server_audit_file_path) should be properly specified beforehand. Same about the SYSLOG-related parameters. The logging is turned off by default.
* **Commandline:** `--server-audit-logging[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `server_audit_mode`

 * **Description:** This variable doesn't have any distinctive meaning for a user. Its value mostly reflects the server version with which the plugin was started and is intended to be used by developers for testing.
* **Commandline:** `--server-audit-mode[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1`

 

---

 #### `server_audit_output_type`

 * **Description:** Specifies the desired output type. Can be SYSLOG, FILE or null as no output. For example: `SET GLOBAL server_audit_output_type=file` file: log records will be saved into the rotating log file. The name of the file set by [server\_audit\_file\_path](#server_audit_file_path) variable. syslog: log records will be sent to the local syslogd daemon with the standard <syslog.h> API. The default value is 'file'.
* **Commandline:** `--server-audit-output-type=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `file`
* **Valid Values:** `SYSLOG`, `FILE`

 

---

 #### `server_audit_query_log_limit`

 * **Description:** Limit on the length of the query string in a record.
* **Commandline:** `--server-audit-query-log-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `0` to `2147483647`

 

---

 #### `server_audit_syslog_facility`

 * **Description:** SYSLOG-mode variable. It defines the 'facility' of the records that will be sent to the syslog. Later the log can be filtered by this parameter.
* **Commandline:** `--server-audit-syslog-facility=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `LOG_USER`
* **Valid Values:** `LOG_USER`, `LOG_MAIL`, `LOG_DAEMON`, `LOG_AUTH`, `LOG_SYSLOG`, `LOG_LPR`, `LOG_NEWS`, `LOG_UUCP`, `LOG_CRON`, `LOG_AUTHPRIV`, `LOG_FTP`, and `LOG_LOCAL0`–`LOG_LOCAL7`.

 

---

 #### `server_audit_syslog_ident`

 * **Description:** SYSLOG-mode variable. String value for the 'ident' part of each syslog record. Default value is 'mysql-server\_auditing'. New value becomes effective only after restarting the logging.
* **Commandline:** `--server-audit-syslog-ident=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `mysql-server_auditing`

 

---

 #### `server_audit_syslog_info`

 * **Description:** SYSLOG-mode variable. The 'info' string to be added to the syslog records. Can be changed any time.
* **Commandline:** `--server-audit-syslog-info=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty string

 

---

 #### `server_audit_syslog_priority`

 * **Description:** SYSLOG-mode variable. Defines the priority of the log records for the syslogd.
* **Commandline:** `--server-audit-syslog-priority=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `LOG_INFO`
* **Valid Values:**`LOG_EMERG`, `LOG_ALERT`, `LOG_CRIT`, `LOG_ERR`, `LOG_WARNING`, `LOG_NOTICE`, `LOG_INFO`, `LOG_DEBUG`

 

---

 ### Options

 #### `server_audit`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [MariaDB Audit Plugin - Installation: Prohibiting Uninstallation](../mariadb-audit-plugin-installation/index#prohibiting-uninstallation) for more information on one use case.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--server-audit=val`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-audit-plugin-options-and-system-variables/>

LEAVE
=====

    Syntax
------

 
```
LEAVE label

```

This statement is used to exit the flow control construct that has the given [label](../labels/index). The label must be in the same stored program, not in a caller procedure. `LEAVE` can be used within [BEGIN ... END](../begin-end/index) or loop constructs ([LOOP](../loop/index), [REPEAT](../repeat-loop/index), [WHILE](../while/index)). In [Stored Procedures](../stored-procedures/index), [Triggers](../triggers/index) and [Events](../events/index), LEAVE can refer to the outmost BEGIN ... END construct; in that case, the program exits the procedure. In [Stored Functions](../stored-functions/index), [RETURN](../return/index) can be used instead.

 Note that LEAVE cannot be used to exit a [DECLARE HANDLER](../declare-handler/index) block.

 If you try to LEAVE a non-existing label, or if you try to LEAVE a HANDLER block, the following error will be produced:

 
```
ERROR 1308 (42000): LEAVE with no matching label: <label_name>

```

The following example uses `LEAVE` to exit the procedure if a condition is true:

 
```
CREATE PROCEDURE proc(IN p TINYINT)
CONTAINS SQL
`whole_proc`:
BEGIN
   SELECT 1;
   IF p < 1 THEN
      LEAVE `whole_proc`;
   END IF;
   SELECT 2;
END;

CALL proc(0);
+---+
| 1 |
+---+
| 1 |
+---+

```

See Also
--------

 * [ITERATE](../iterate/index) - Repeats a loop execution

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/leave/>

Using Compound Statements Outside of Stored Programs
====================================================

    Compound statements can also be used outside of [stored programs](../stored-routines/index).

 
```
delimiter |
IF @have_innodb THEN
  CREATE TABLE IF NOT EXISTS innodb_index_stats (
    database_name    VARCHAR(64) NOT NULL,
    table_name       VARCHAR(64) NOT NULL,
    index_name       VARCHAR(64) NOT NULL,
    last_update      TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    stat_name        VARCHAR(64) NOT NULL,
    stat_value       BIGINT UNSIGNED NOT NULL,
    sample_size      BIGINT UNSIGNED,
    stat_description VARCHAR(1024) NOT NULL,
    PRIMARY KEY (database_name, table_name, index_name, stat_name)
  ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin STATS_PERSISTENT=0;
END IF|
Query OK, 0 rows affected, 2 warnings (0.00 sec)

```

Note, that using compound statements this way is subject to following limitations:

 * Only [BEGIN](../begin-end/index), [IF](../if-statement/index), [CASE](../case-statement/index), [LOOP](../loop/index), [WHILE](../while/index), [REPEAT](../repeat-loop/index) statements may start a compound statement outside of stored programs.
* [BEGIN](../begin-end/index) must use the `BEGIN NOT ATOMIC` syntax (otherwise it'll be confused with [BEGIN](../start-transaction/index) that starts a transaction).
* A compound statement might not start with a label.
* A compound statement is parsed completely—note "2 warnings" in the above example, even if the condition was false (InnoDB was, indeed, disabled), and the [CREATE TABLE](../create-table/index) statement was not executed, it was still parsed and the parser produced "Unknown storage engine" warning.

 Inside a compound block first three limitations do not apply, one can use anything that can be used inside a stored program — including labels, condition handlers, variables, and so on:

 
```
BEGIN NOT ATOMIC
    DECLARE foo CONDITION FOR 1146;
    DECLARE x INT DEFAULT 0;
    DECLARE CONTINUE HANDLER FOR SET x=1;
    INSERT INTO test.t1 VALUES ("hndlr1", val, 2);
    END|

```

Example how to use `IF`:

 
```
IF (1>0) THEN BEGIN NOT ATOMIC SELECT 1; END ; END IF;;


```

Example of how to use `WHILE` loop:

 
```
DELIMITER |
BEGIN NOT ATOMIC
    DECLARE x INT DEFAULT 0;
    WHILE x <= 10 DO
        SET x = x + 1;
        SELECT x;
    END WHILE;
END|
DELIMITER ;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-compound-statements-outside-of-stored-programs/>

BEGIN END
=========

    Syntax
------

 
```
[begin_label:] BEGIN [NOT ATOMIC]
    [statement_list]
END [end_label]

```
 `NOT ATOMIC` is required when used outside of a [stored procedure](../stored-procedures/index). Inside stored procedures or within an anonymous block, `BEGIN` alone starts a new anonymous block.

 Description
-----------

 `BEGIN ... END` syntax is used for writing compound statements. A compound statement can contain multiple statements, enclosed by the `BEGIN` and `END` keywords. statement\_list represents a list of one or more statements, each terminated by a semicolon (i.e., `;`) statement delimiter. statement\_list is optional, which means that the empty compound statement (`BEGIN END`) is legal.

 Note that `END` will perform a commit. If you are running in [autocommit](../server-system-variables/index#autocommit) mode, every statement will be committed separately. If you are not running in `autocommit` mode, you must execute a [COMMIT](../commit/index) or [ROLLBACK](../rollback/index) after `END` to get the database up to date.

 Use of multiple statements requires that a client is able to send statement strings containing the ; statement delimiter. This is handled in the [mysql](mysql-command-line_client) command-line client with the [DELIMITER](../delimiters/index) command. Changing the `;` end-of-statement delimiter (for example, to `//`) allows `;` to be used in a program body.

 A compound statement within a [stored program](../stored-programs-and-views/index) can be [labeled](../labels/index). `end_label` cannot be given unless `begin_label` also is present. If both are present, they must be the same.

 `BEGIN ... END` constructs can be nested. Each block can define its own variables, a `CONDITION`, a `HANDLER` and a [CURSOR](../programmatic-and-compound-statements-cursors/index), which don't exist in the outer blocks. The most local declarations override the outer objects which use the same name (see example below).

 The declarations order is the following:

 * [`DECLARE` local variables](../declare-variable/index);
* [`DECLARE CONDITION`s](../declare-condition/index);
* [`DECLARE CURSOR`s](../declare-cursor/index);
* [`DECLARE HANDLER`s](../declare-handler/index);

 Note that `DECLARE HANDLER` contains another `BEGIN ... END` construct.

 Here is an example of a very simple, anonymous block:

 
```
BEGIN NOT ATOMIC
SET @a=1;
CREATE TABLE test.t1(a INT);
END|

```

Below is an example of nested blocks in a stored procedure:

 
```
CREATE PROCEDURE t( )
BEGIN
   DECLARE x TINYINT UNSIGNED DEFAULT 1;
   BEGIN
      DECLARE x CHAR(2) DEFAULT '02';
       DECLARE y TINYINT UNSIGNED DEFAULT 10;
       SELECT x, y;
   END;
   SELECT x;
END;

```

In this example, a [TINYINT](../tinyint/index) variable, `x` is declared in the outter block. But in the inner block `x` is re-declared as a [CHAR](../char/index) and an `y` variable is declared. The inner [SELECT](../select/index) shows the "new" value of `x`, and the value of `y`. But when x is selected in the outer block, the "old" value is returned. The final [SELECT](../select/index) doesn't try to read `y`, because it doesn't exist in that context.

 See Also
--------

 * [Using compound statements outside of stored programs](../using-compound-statements-outside-of-stored-programs/index)
* [Changes in Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/begin-end/>

IF
==

    Syntax
------

 
```
IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF;

```

Description
-----------

 `IF` implements a basic conditional construct. If the `search_condition` evaluates to true, the corresponding SQL statement list is executed. If no `search_condition` matches, the statement list in the `ELSE` clause is executed. Each statement\_list consists of one or more statements.

 See Also
--------

 * The [IF() function](../if-function/index), which differs from the `IF` statement described above.
* [Changes in Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/if/>

ITERATE
=======

    Syntax
------

 
```
ITERATE label

```

`ITERATE` can appear only within [LOOP](../loop/index), [REPEAT](../repeat-loop/index), and [WHILE](../while/index) statements. `ITERATE` means "do the loop again", and uses the statement's [label](../labels/index) to determine which statements to repeat. The label must be in the same stored program, not in a caller procedure.

 If you try to use `ITERATE` with a non-existing label, or if the label is associated to a construct which is not a loop, the following error will be produced:

 
```
ERROR 1308 (42000): ITERATE with no matching label: <label_name>

```

Below is an example of how `ITERATE` might be used:

 
```
CREATE PROCEDURE doiterate(p1 INT)
BEGIN
  label1: LOOP
    SET p1 = p1 + 1;
    IF p1 < 10 THEN ITERATE label1; END IF;
    LEAVE label1;
  END LOOP label1;
  SET @x = p1;
END

```

See Also
--------

 * [LEAVE](../leave/index) - Exits a loop (or any labeled code block)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/iterate/>

RESIGNAL
========

    Syntax
------

 
```
RESIGNAL [error_condition]
    [SET error_property
    [, error_property] ...]

error_condition:
    SQLSTATE [VALUE] 'sqlstate_value'
  | condition_name

error_property:
    error_property_name = <error_property_value>

error_property_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME

```
 Description
-----------

 The syntax of `RESIGNAL` and its semantics are very similar to [SIGNAL](../signal/index). This statement can only be used within an error [HANDLER](../declare-handler/index). It produces an error, like [SIGNAL](../signal/index). `RESIGNAL` clauses are the same as SIGNAL, except that they all are optional, even [SQLSTATE](../sqlstate/index). All the properties which are not specified in `RESIGNAL`, will be identical to the properties of the error that was received by the error [HANDLER](../handler/index). For a description of the clauses, see [diagnostics area](../diagnostics-area/index).

 Note that `RESIGNAL` does not empty the diagnostics area: it just appends another error condition.

 `RESIGNAL`, without any clauses, produces an error which is identical to the error that was received by [HANDLER](../handler/index).

 If used out of a [HANDLER](../handler/index) construct, RESIGNAL produces the following error:

 
```
ERROR 1645 (0K000): RESIGNAL when handler not active

```

In [MariaDB 5.5](../what-is-mariadb-55/index), if a [HANDLER](../handler/index) contained a [CALL](../call/index) to another procedure, that procedure could use `RESIGNAL`. Since [MariaDB 10.0](../what-is-mariadb-100/index), trying to do this raises the above error.

 For a list of `SQLSTATE` values and MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).

 The following procedure tries to query two tables which don't exist, producing a 1146 error in both cases. Those errors will trigger the [HANDLER](../handler/index). The first time the error will be ignored and the client will not receive it, but the second time, the error is re-signaled, so the client will receive it.

 
```
CREATE PROCEDURE test_error( )
BEGIN
   DECLARE CONTINUE HANDLER
      FOR 1146
   BEGIN
   IF @hide_errors IS FALSE THEN
      RESIGNAL;
   END IF;
   END;
   SET @hide_errors = TRUE;
   SELECT 'Next error will be ignored' AS msg;
   SELECT `c` FROM `temptab_one`;
   SELECT 'Next error won''t be ignored' AS msg;
   SET @hide_errors = FALSE;
   SELECT `c` FROM `temptab_two`;
END;

CALL test_error( );

+----------------------------+
| msg                        |
+----------------------------+
| Next error will be ignored |
+----------------------------+

+-----------------------------+
| msg                         |
+-----------------------------+
| Next error won't be ignored |
+-----------------------------+

ERROR 1146 (42S02): Table 'test.temptab_two' doesn't exist

```

The following procedure re-signals an error, modifying only the error message to clarify the cause of the problem.

 
```
CREATE PROCEDURE test_error()
BEGIN
   DECLARE CONTINUE HANDLER
   FOR 1146
   BEGIN
      RESIGNAL SET
      MESSAGE_TEXT = '`temptab` does not exist';
   END;
   SELECT `c` FROM `temptab`;
END;

CALL test_error( );
ERROR 1146 (42S02): `temptab` does not exist

```

As explained above, this works on [MariaDB 5.5](../what-is-mariadb-55/index), but produces a 1645 error since 10.0.

 
```
CREATE PROCEDURE handle_error()
BEGIN
  RESIGNAL;
END;
CREATE PROCEDURE p()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL p();
  SIGNAL SQLSTATE '45000';
END;

```

See Also
--------

 * [Diagnostics Area](../diagnostics-area/index)
* [SIGNAL](../signal/index)
* [HANDLER](../handler/index)
* [Stored Routines](../stored-programs-and-views/index)
* [MariaDB Error Codes](../mariadb-error-codes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/resignal/>

LOOP
====

    Syntax
------

 
```
[begin_label:] LOOP
    statement_list
END LOOP [end_label]

```
 Description
-----------

 `LOOP` implements a simple loop construct, enabling repeated execution of the statement list, which consists of one or more statements, each terminated by a semicolon (i.e., `;`) statement delimiter. The statements within the loop are repeated until the loop is exited; usually this is accomplished with a [LEAVE](../leave/index) statement.

 A `LOOP` statement can be [labeled](../labels/index). `end_label` cannot be given unless `begin_label` also is present. If both are present, they must be the same.

 See [Delimiters](../delimiters/index) in the [mariadb](../mariadb-client/index) client for more on delimiter usage in the client.

 See Also
--------

 * [LOOP in Oracle mode](../sql_modeoracle-from-mariadb-103/index#loop)
* [ITERATE](../iterate/index)
* [LEAVE](../leave/index)
* [FOR Loops](../for/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/loop/>

REPEAT LOOP
===========

    Syntax
------

 
```
[begin_label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT [end_label]

```

The statement list within a `REPEAT` statement is repeated until the search\_condition is true. Thus, a `REPEAT` always enters the loop at least once. statement\_list consists of one or more statements, each terminated by a semicolon (i.e., `;`) statement delimiter.

 A `REPEAT` statement can be [labeled](../labels/index). end\_label cannot be given unless begin\_label also is present. If both are present, they must be the same.

 See [Delimiters](../delimiters/index) in the [mariadb](../mariadb-client/index) client for more on client delimiter usage.

 
```
DELIMITER //

CREATE PROCEDURE dorepeat(p1 INT)
  BEGIN
    SET @x = 0;
    REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
  END
//

CALL dorepeat(1000)//

SELECT @x//
+------+
| @x   |
+------+
| 1001 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/repeat-loop/>

GOTO
====

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**The GOTO statement was introduced in [MariaDB 10.3](../what-is-mariadb-103/index) for Oracle compatibility.

 
Syntax
------

 
```
GOTO label

```
 Description
-----------

 The `GOTO` statement causes the code to jump to the specified label, and continue operating from there. It is only accepted when in [Oracle mode](../sql_modeoracle-from-mariadb-103/index).

 Example
-------

 
```
SET sql_mode=ORACLE;

DELIMITER //

CREATE OR REPLACE PROCEDURE p1 AS

BEGIN

  SELECT 1;
  GOTO label;
  SELECT 2;
  <<label>>
  SELECT 3;

END;

//

DELIMITER 

call p1();
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.000 sec)

+---+
| 3 |
+---+
| 3 |
+---+
1 row in set (0.000 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/goto/>

Labels
======

    Syntax
------

 
```
label: <construct>
[label]

```

Labels are MariaDB [identifiers](../identifier-names/index) which can be used to identify a [BEGIN ... END](../begin-end/index) construct or a loop. They have a maximum length of 16 characters and can be quoted with backticks (i.e.., ```).

 Labels have a start part and an end part. The start part must precede the portion of code it refers to, must be followed by a colon (`:`) and can be on the same or different line. The end part is optional and adds nothing, but can make the code more readable. If used, the end part must precede the construct's delimiter (`;`). Constructs identified by a label can be nested. Each construct can be identified by only one label.

 Labels need not be unique in the stored program they belong to. However, a label for an inner loop cannot be identical to a label for an outer loop. In this case, the following error would be produced:

 
```
ERROR 1309 (42000): Redefining label <label_name>

```

[LEAVE](../leave/index) and [ITERATE](../iterate/index) statements can be used to exit or repeat a portion of code identified by a label. They must be in the same [Stored Routine](../stored-programs-and-views/index), [Trigger](../triggers/index) or [Event](../events/index) which contains the target label.

 Below is an example using a simple label that is used to exit a [LOOP](../loop/index):

 
```
CREATE PROCEDURE `test_sp`()
BEGIN
   `my_label`:
   LOOP
      SELECT 'looping';
      LEAVE `my_label`;
   END LOOP;
   SELECT 'out of loop';
END;

```

The following label is used to exit a procedure, and has an end part:

 
```
CREATE PROCEDURE `test_sp`()
`my_label`:
BEGIN
   IF @var = 1 THEN
      LEAVE `my_label`;
   END IF;
   DO something();
END `my_label`;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/labels/>

DECLARE Variable
================

    Syntax
------

 
```
DECLARE var_name [, var_name] ... [[ROW] TYPE OF]] type [DEFAULT value]

```
 Description
-----------

 This statement is used to declare local variables within [stored programs](../stored-programs-and-views/index). To provide a default value for the variable, include a `DEFAULT` clause. The value can be specified as an expression (even subqueries are permitted); it need not be a constant. If the `DEFAULT` clause is missing, the initial value is `NULL`.

 Local variables are treated like stored routine parameters with respect to data type and overflow checking. See [CREATE PROCEDURE](../create-procedure/index).

 Local variables must be declared before `CONDITION`s, [CURSORs](../programmatic-and-compound-statements-cursors/index) and `HANDLER`s.

 Local variable names are not case sensitive.

 The scope of a local variable is within the `BEGIN ... END` block where it is declared. The variable can be referred to in blocks nested within the declaring block, except those blocks that declare a variable with the same name.

 ### TYPE OF / ROW TYPE OF

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**`TYPE OF` and `ROW TYPE OF` anchored data types for stored routines were introduced in [MariaDB 10.3](../what-is-mariadb-103/index).

 
Anchored data types allow a data type to be defined based on another object, such as a table row, rather than specifically set in the declaration. If the anchor object changes, so will the anchored data type. This can lead to routines being easier to maintain, so that if the data type in the table is changed, it will automatically be changed in the routine as well.

 Variables declared with `ROW TYPE OF` will have the same features as implicit [ROW](../row/index) variables. It is not possible to use `ROW TYPE OF` variables in a [LIMIT](../limit/index) clause.

 The real data type of `TYPE OF` and `ROW TYPE OF table_name` will become known at the very beginning of the stored routine call. [ALTER TABLE](../alter-table/index) or [DROP TABLE](../drop-table/index) statements performed inside the current routine on the tables that appear in anchors won't affect the data type of the anchored variables, even if the variable is declared after an [ALTER TABLE](../alter-table/index) or [DROP TABLE](../drop-table/index) statement.

 The real data type of a `ROW TYPE OF cursor_name` variable will become known when execution enters into the block where the variable is declared. Data type instantiation will happen only once. In a cursor `ROW TYPE OF` variable that is declared inside a loop, its data type will become known on the very first iteration and won't change on further loop iterations.

 The tables referenced in `TYPE OF` and `ROW TYPE OF` declarations will be checked for existence at the beginning of the stored routine call. [CREATE PROCEDURE](../create-procedure/index) or [CREATE FUNCTION](../create-function/index) will not check the referenced tables for existence.

 Examples
--------

 `TYPE OF` and `ROW TYPE OF` from [MariaDB 10.3](../what-is-mariadb-103/index):

 
```
DECLARE tmp TYPE OF t1.a; -- Get the data type from the column {{a}} in the table {{t1}}

DECLARE rec1 ROW TYPE OF t1; -- Get the row data type from the table {{t1}}

DECLARE rec2 ROW TYPE OF cur1; -- Get the row data type from the cursor {{cur1}}

```

See Also
--------

 * [User-Defined variables](../user-defined-variables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/declare-variable/>

DECLARE CONDITION
=================

    Syntax
------

 
```
DECLARE condition_name CONDITION FOR condition_value

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code

```

Description
-----------

 The `DECLARE ... CONDITION` statement defines a named error condition. It specifies a condition that needs specific handling and associates a name with that condition. Later, the name can be used in a [DECLARE ... HANDLER](../declare-handler/index), [SIGNAL](../signal/index) or [RESIGNAL](../resignal/index) statement (as long as the statement is located in the same [BEGIN ... END](../begin-end/index) block).

 Conditions must be declared after [local variables](../declare-variable/index), but before [CURSORs](../programmatic-and-compound-statements-cursors/index) and [HANDLERs](../declare-handler/index).

 A condition\_value for `DECLARE ... CONDITION` can be an [SQLSTATE](../sqlstate/index) value (a 5-character string literal) or a MySQL error code (a number). You should not use SQLSTATE value '00000' or MySQL error code 0, because those indicate sucess rather than an error condition. If you try, or if you specify an invalid SQLSTATE value, an error like this is produced:

 
```
ERROR 1407 (42000): Bad SQLSTATE: '00000'

```

For a list of SQLSTATE values and MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/declare-condition/>

RETURN
======

    Syntax
------

 
```
RETURN expr 

```

The `RETURN` statement terminates execution of a [stored function](../stored-functions/index) and returns the value *`expr`* to the function caller. There must be at least one `RETURN` statement in a stored function. If the function has multiple exit points, all exit points must have a `RETURN`.

 This statement is not used in [stored procedures](../stored-procedures/index), [triggers](../triggers/index), or [events](../events/index). [LEAVE](../leave/index) can be used instead.

 The following example shows that `RETURN` can return the result of a [scalar subquery](../subqueries-scalar-subqueries/index):

 
```
CREATE FUNCTION users_count() RETURNS BOOL
   READS SQL DATA
BEGIN
   RETURN (SELECT COUNT(DISTINCT User) FROM mysql.user);
END;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/return/>

CASE Statement
==============

    Syntax
------

 
```
CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

```

Or:

 
```
CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list] 
END CASE

```

Description
-----------

 The text on this page describes the `CASE` statement for [stored programs](../stored-programs-and-views/index). See the [CASE OPERATOR](../case-operator/index) for details on the CASE operator outside of [stored programs](../stored-programs-and-views/index).

 The `CASE` statement for [stored programs](../stored-programs-and-views/index) implements a complex conditional construct. If a `search_condition` evaluates to true, the corresponding SQL statement list is executed. If no search condition matches, the statement list in the `ELSE` clause is executed. Each `statement_list` consists of one or more statements.

 The `CASE` statement cannot have an `ELSE NULL` clause, and it is terminated with `END CASE` instead of `END`. implements a complex conditional construct. If a `search_condition` evaluates to true, the corresponding SQL statement list is executed. If no search condition matches, the statement list in the `ELSE` clause is executed. Each `statement_list` consists of one or more statements.

 If no when\_value or search\_condition matches the value tested and the `CASE` statement contains no `ELSE` clause, a Case not found for `CASE` statement error results.

 Each statement\_list consists of one or more statements; an empty `statement_list` is not allowed. To handle situations where no value is matched by any `WHEN` clause, use an `ELSE` containing an empty [BEGIN ... END](../begin-end/index) block, as shown in this example:

 
```
DELIMITER |
CREATE PROCEDURE p()
BEGIN
  DECLARE v INT DEFAULT 1;
  CASE v
    WHEN 2 THEN SELECT v;
    WHEN 3 THEN SELECT 0;
    ELSE BEGIN END;
  END CASE;
END;
|

```

The indentation used here in the `ELSE` clause is for purposes of clarity only, and is not otherwise significant. See [Delimiters in the mariadb client](../delimiters/index) for more on the use of the delimiter command.

 **Note:** The syntax of the `CASE` statement used inside stored programs differs slightly from that of the SQL CASE expression described in [CASE OPERATOR](../case-operator/index). The `CASE` statement cannot have an `ELSE NULL` clause, and it is terminated with `END CASE` instead of `END`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/case-statement/>

DECLARE HANDLER
===============

    Syntax
------

 
```
DECLARE handler_type HANDLER
    FOR condition_value [, condition_value] ...
    statement

handler_type:
    CONTINUE
  | EXIT 
  | UNDO

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
  | mariadb_error_code

```

Description
-----------

 The `DECLARE ... HANDLER` statement specifies handlers that each may deal with one or more conditions. If one of these conditions occurs, the specified statement is executed. statement can be a simple statement (for example, `SET var_name = value`), or it can be a compound statement written using [BEGIN and END](../begin-end/index).

 Handlers must be declared after local variables, a `CONDITION` and a [CURSOR](../programmatic-and-compound-statements-cursors/index).

 For a `CONTINUE` handler, execution of the current program continues after execution of the handler statement. For an EXIT handler, execution terminates for the [BEGIN ... END](../begin-end/index) compound statement in which the handler is declared. (This is true even if the condition occurs in an inner block.) The `UNDO` handler type statement is not supported.

 If a condition occurs for which no handler has been declared, the default action is `EXIT`.

 A condition\_value for `DECLARE ... HANDLER` can be any of the following values:

 * An [SQLSTATE](../sqlstate/index) value (a 5-character string literal) or a MariaDB error code (a number). You should not use `SQLSTATE` value '00000' or MariaDB error code 0, because those indicate sucess rather than an error condition. For a list of `SQLSTATE` values and MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).
* A condition name previously specified with `DECLARE ... CONDITION`. It must be in the same stored program. See [DECLARE CONDITION](../declare-condition/index).
* `SQLWARNING` is shorthand for the class of SQLSTATE values that begin with '01'.
* `NOT FOUND` is shorthand for the class of `SQLSTATE` values that begin with '02'. This is relevant only the context of cursors and is used to control what happens when a cursor reaches the end of a data set. If no more rows are available, a No Data condition occurs with `SQLSTATE` value 02000. To detect this condition, you can set up a handler for it (or for a `NOT FOUND` condition). An example is shown in [Cursor Overview](../cursor-overview/index). This condition also occurs for [SELECT ... INTO](../select-into/index) var\_list statements that retrieve no rows.
* SQLEXCEPTION is shorthand for the class of SQLSTATE values that do not begin with '00', '01', or '02'.

 When an error raises, in some cases it could be handled by multiple `HANDLER`s. For example, there may be an handler for 1050 error, a separate handler for the 42S01 SQLSTATE, and another separate handler for the `SQLEXCEPTION` class: in theory all occurrences of `HANDLER` may catch the 1050 error, but MariaDB chooses the `HANDLER` with the highest precedence. Here are the precedence rules:

 * Handlers which refer to an error code have the highest precedence.
* Handlers which refer to a SQLSTATE come next.
* Handlers which refer to an error class have the lowest precedence.

 In some cases, a statement could produce multiple errors. If this happens, in some cases multiple handlers could have the highest precedence. In such cases, the choice of the handler is indeterminate.

 Note that if an error occurs within a `CONTINUE HANDLER` block, it can be handled by another `HANDLER`. However, a `HANDLER` which is already in the stack (that is, it has been called to handle an error and its execution didn't finish yet) cannot handle new errors—this prevents endless loops. For example, suppose that a stored procedure contains a `CONTINUE HANDLER` for `SQLWARNING` and another `CONTINUE HANDLER` for `NOT FOUND`. At some point, a NOT FOUND error occurs, and the execution enters the `NOT FOUND HANDLER`. But within that handler, a warning occurs, and the execution enters the `SQLWARNING HANDLER`. If another `NOT FOUND` error occurs, it cannot be handled again by the `NOT FOUND HANDLER`, because its execution is not finished.

 When a `DECLARE HANDLER` block can handle more than one error condition, it may be useful to know which errors occurred. To do so, you can use the [GET DIAGNOSTICS](../get-diagnostics/index) statement.

 An error that is handled by a `DECLARE HANDLER` construct can be issued again using the [RESIGNAL](../resignal/index) statement.

 Below is an example using `DECLARE HANDLER`:

 
```
CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));

DELIMITER //

CREATE PROCEDURE handlerdemo ( )
     BEGIN
       DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
       SET @x = 1;
       INSERT INTO test.t VALUES (1);
       SET @x = 2;
       INSERT INTO test.t VALUES (1);
       SET @x = 3;
     END;
     //

DELIMITER ;

CALL handlerdemo( );

SELECT @x;
+------+
| @x   |
+------+
|    3 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/declare-handler/>

FOR
===

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**FOR loops were introduced in [MariaDB 10.3](../what-is-mariadb-103/index).

 
Syntax
------

 Integer range FOR loop:

 
```
[begin_label:]
FOR var_name IN [ REVERSE ] lower_bound .. upper_bound
DO statement_list
END FOR [ end_label ]

```

Explicit cursor FOR loop

 
```
[begin_label:]
FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
DO statement_list
END FOR [ end_label ]

```

Explicit cursor FOR loop ([Oracle mode](../sql_modeoracle/index))

 
```
[begin_label:]
FOR record_name IN cursor_name [ ( cursor_actual_parameter_list)]
LOOP
  statement_list
END LOOP [ end_label ]

```

Implicit cursor FOR loop

 
```
[begin_label:]
FOR record_name IN ( select_statement )
DO statement_list
END FOR [ end_label ]

```
 Description
-----------

 FOR loops allow code to be executed a fixed number of times.

 In an integer range FOR loop, MariaDB will compare the lower bound and upper bound values, and assign the lower bound value to a counter. If REVERSE is not specified, and the upper bound value is greater than or equal to the counter, the counter will be incremented and the statement will continue, after which the loop is entered again. If the upper bound value is greater than the counter, the loop will be exited.

 If REVERSE is specified, the counter is decremented, and the upper bound value needs to be less than or equal for the loop to continue.

 Examples
--------

 Intger range FOR loop:

 
```
CREATE TABLE t1 (a INT);

DELIMITER //

FOR i IN 1..3
DO
  INSERT INTO t1 VALUES (i);
END FOR;
//

DELIMITER ;

SELECT * FROM t1;
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
+------+

```

REVERSE integer range FOR loop:

 
```
CREATE OR REPLACE TABLE t1 (a INT);

DELIMITER //
FOR i IN REVERSE 4..12
    DO
    INSERT INTO t1 VALUES (i);
END FOR;
//
Query OK, 9 rows affected (0.422 sec)


DELIMITER ;

SELECT * FROM t1;
+------+
| a    |
+------+
|   12 |
|   11 |
|   10 |
|    9 |
|    8 |
|    7 |
|    6 |
|    5 |
|    4 |
+------+

```

Explicit cursor in [Oracle mode](../sql_modeoracle/index):

 
```
SET sql_mode=ORACLE;

CREATE OR REPLACE TABLE t1 (a INT, b VARCHAR(32));

INSERT INTO t1 VALUES (10,'b0');
INSERT INTO t1 VALUES (11,'b1');
INSERT INTO t1 VALUES (12,'b2');

DELIMITER //

CREATE OR REPLACE PROCEDURE p1(pa INT) AS 
  CURSOR cur(va INT) IS
    SELECT a, b FROM t1 WHERE a=va;
BEGIN
  FOR rec IN cur(pa)
  LOOP
    SELECT rec.a, rec.b;
  END LOOP;
END;
//

DELIMITER ;

CALL p1(10);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    10 | b0    |
+-------+-------+

CALL p1(11);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    11 | b1    |
+-------+-------+

CALL p1(12);
+-------+-------+
| rec.a | rec.b |
+-------+-------+
|    12 | b2    |
+-------+-------+

CALL p1(13);
Query OK, 0 rows affected (0.000 sec)

```

See Also
--------

 * [LOOP](../loop/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/for/>

SELECT INTO
===========

    Syntax
------

 
```
SELECT col_name [, col_name] ...
    INTO var_name [, var_name] ...
    table_expr

```
 Description
-----------

 SELECT ... INTO enables selected columns to be stored directly into variables. No resultset is produced. The query should return a single row. If the query returns no rows, a warning with error code 1329 occurs (No data), and the variable values remain unchanged. If the query returns multiple rows, error 1172 occurs (Result consisted of more than one row). If it is possible that the statement may retrieve multiple rows, you can use `LIMIT 1` to limit the result set to a single row.

 The INTO clause can also be specified at the end of the statement.

 In the context of such statements that occur as part of events executed by the Event Scheduler, diagnostics messages (not only errors, but also warnings) are written to the error log, and, on Windows, to the application event log.

 This statement can be used with both [local variables](../declare-variable/index) and [user-defined variables](../user-defined-variables/index).

 For the complete syntax, see [SELECT](../select/index).

 Another way to set a variable's value is the [SET](../set-variable/index) statement.

 `SELECT ... INTO` results are not stored in the [query cache](../query-cache/index) even if `SQL_CACHE` is specified.

 Examples
--------

 
```
SELECT id, data INTO @x,@y 
FROM test.t1 LIMIT 1;
SELECT * from t1 where t1.a=@x and t1.b=@y

```

If you want to use this construct with `UNION` you have to use the syntax:

 
```
SELECT  * INTO @x FROM (SELECT t1.a FROM t1 UNION SELECT t2.a FROM t2);

```

See Also
--------

 * [SELECT](../select/index) - full SELECT syntax.
* [SELECT INTO OUTFILE](../select-into-outfile/index) - formatting and writing the result to an external file.
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index) - binary-safe writing of the unformatted results to an external file.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/selectinto/>

SIGNAL
======

    Syntax
------

 
```
SIGNAL error_condition
    [SET error_property
    [, error_property] ...]

error_condition:
    SQLSTATE [VALUE] 'sqlstate_value'
  | condition_name

error_property:
    error_property_name = <error_property_value>

error_property_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME

```
 `SIGNAL` empties the [diagnostics area](../diagnostics-area/index) and produces a custom error. This statement can be used anywhere, but is generally useful when used inside a [stored program](../stored-programs-and-views/index). When the error is produced, it can be caught by a [HANDLER](../handler/index). If not, the current stored program, or the current statement, will terminate with the specified error.

 Sometimes an error [HANDLER](../handler/index) just needs to [SIGNAL](index) the same error it received, optionally with some changes. Usually the [RESIGNAL](../resignal/index) statement is the most convenient way to do this.

 `error_condition` can be an [SQLSTATE](../sqlstate/index) value or a named error condition defined via [DECLARE CONDITION](../declare-condition/index). [SQLSTATE](../sqlstate/index) must be a constant string consisting of five characters. These codes are standard to ODBC and ANSI SQL. For customized errors, the recommended [SQLSTATE](../sqlstate/index) is '45000'. For a list of SQLSTATE values used by MariaDB, see the [MariaDB Error Codes](../mariadb-error-codes/index) page. The [SQLSTATE](../sqlstate/index) can be read via the API method `mysql_sqlstate( )`. 

 To specify error properties user-defined variables and [local variables](../declare-variable/index) can be used, as well as [character set conversions](../setting-character-sets-and-collations/index#literals) (but you can't set a collation).

 The error properties, their type and their default values are explained in the [diagnostics area](../diagnostics-area/index) page.

 Errors
------

 If the SQLSTATE is not valid, the following error like this will be produced:

 
```
ERROR 1407 (42000): Bad SQLSTATE: '123456'

```

If a property is specified more than once, an error like this will be produced:

 
```
ERROR 1641 (42000): Duplicate condition information item 'MESSAGE_TEXT'

```

If you specify a condition name which is not declared, an error like this will be produced:

 
```
ERROR 1319 (42000): Undefined CONDITION: cond_name

```

If MYSQL\_ERRNO is out of range, you will get an error like this:

 
```
ERROR 1231 (42000): Variable 'MYSQL_ERRNO' can't be set to the value of '0'

```

Examples
--------

 Here's what happens if [SIGNAL](index) is used in the client to generate errors:

 
```
SIGNAL SQLSTATE '01000';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;

+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1642 | Unhandled user-defined warning condition |
+---------+------+------------------------------------------+
1 row in set (0.06 sec)

SIGNAL SQLSTATE '02000';
ERROR 1643 (02000): Unhandled user-defined not found condition

```

How to specify MYSQL\_ERRNO and MESSAGE\_TEXT properties:

 
```
SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=30001, MESSAGE_TEXT='H
ello, world!';

ERROR 30001 (45000): Hello, world!

```

The following code shows how to use user variables, local variables and character set conversion with SIGNAL:

 
```
CREATE PROCEDURE test_error(x INT)
BEGIN
   DECLARE errno SMALLINT UNSIGNED DEFAULT 31001;
   SET @errmsg = 'Hello, world!';
   IF x = 1 THEN
      SIGNAL SQLSTATE '45000' SET
      MYSQL_ERRNO = errno,
      MESSAGE_TEXT = @errmsg;
   ELSE
      SIGNAL SQLSTATE '45000' SET
      MYSQL_ERRNO = errno,
      MESSAGE_TEXT = _utf8'Hello, world!';
   END IF;
END;

```

How to use named error conditions:

 
```
CREATE PROCEDURE test_error(n INT)
BEGIN
   DECLARE `too_big` CONDITION FOR SQLSTATE '45000';
   IF n > 10 THEN
      SIGNAL `too_big`;
   END IF;
END;

```

In this example, we'll define a [HANDLER](../handler/index) for an error code. When the error occurs, we [SIGNAL](index) a more informative error which makes sense for our procedure:

 
```
CREATE PROCEDURE test_error()
BEGIN
   DECLARE EXIT HANDLER
   FOR 1146
   BEGIN
      SIGNAL SQLSTATE '45000' SET
      MESSAGE_TEXT = 'Temporary tables not found; did you call init() procedure?';
   END;
   -- this will produce a 1146 error
   SELECT `c` FROM `temptab`;
END;

```

See Also
--------

 * [Diagnostics Area](../diagnostics-area/index)
* [RESIGNAL](../resignal/index)
* [DECLARE HANDLER](../declare-handler/index)
* [Stored Routines](../stored-programs-and-views/index)
* [MariaDB Error Codes](../mariadb-error-codes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/signal/>

WHILE
=====

    Syntax
------

 
```
[begin_label:] WHILE search_condition DO
    statement_list
END WHILE [end_label]

```

Description
-----------

 The statement list within a `WHILE` statement is repeated as long as the `search_condition` is true. statement\_list consists of one or more statements. If the loop must be executed at least once, `[REPEAT ... LOOP](../repeat-loop/index)` can be used instead.

 A `WHILE` statement can be [labeled](../labels/index). end\_label cannot be given unless begin\_label also is present. If both are present, they must be the same.

 Examples
--------

 
```
CREATE PROCEDURE dowhile()
BEGIN
  DECLARE v1 INT DEFAULT 5;

  WHILE v1 > 0 DO
    ...
    SET v1 = v1 - 1;
  END WHILE;
END

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/while/>

mariadb Client
===============

   The mariadb command-line client.

 Previously, the client was called `mysql` which, from [MariaDB 10.5](../what-is-mariadb-105/index), is still a symlink.

  

| Title | Description |
| --- | --- |
|  [mariadb Command-Line Client](../mariadb-command-line-client/index) |  mysql is a simple SQL shell with GNU readline capabilities.  |
|  [Delimiters](../delimiters/index) |  How to change the delimiter for the mariadb client.  |
|  [mysql Command-line Client](../mysql-command-line-client/index) |  Symlink or old name for mariadb, the command-line client.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-client/>

Cursors
========

   A cursor is a structure that allows you to go over records sequentially, and perform processing based on the result.

  

| Title | Description |
| --- | --- |
|  [Cursor Overview](../cursor-overview/index) |  Structure for traversing and processing results sequentially.  |
|  [DECLARE CURSOR](../declare-cursor/index) |  Declares a cursor which can be used inside stored programs.  |
|  [OPEN](../open/index) |  Open a previously declared cursor.  |
|  [FETCH](../fetch/index) |  Fetch a row from a cursor.  |
|  [CLOSE](../close/index) |  Close a previously opened cursor.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/programmatic-compound-statements-cursors/>

Aria Clients and Utilities
===========================

   Clients and utilities for working with the [Aria](../aria/index) storage engine

  

| Title | Description |
| --- | --- |
|  [aria\_chk](../aria_chk/index) |  Used for checking, repairing, optimizing and sorting Aria tables.  |
|  [aria\_pack](../aria_pack/index) |  Tool for compressing Aria tables.  |
|  [aria\_read\_log](../aria_read_log/index) |  Tool for displaying and applying log records from an Aria transaction log.  |
|  [aria\_s3\_copy](../aria_s3_copy/index) |  Copies an Aria table to and from S3.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-clients-and-utilities/>

Backup, Restore and Import Clients
===================================

   Clients for taking backups or importing/restoring data

  

| Title | Description |
| --- | --- |
|  [Mariabackup](../mariabackup/index) |  Physical backups, supports Data-at-Rest and InnoDB compression.  |
|  [mariadb-dump](../mariadb-dump/index) |  Dump a database or a collection of databases in a portable format.  |
|  [mariadb-hotcopy](../mariadb-hotcopy/index) |  Fast backup program on local machine. Deprecated.  |
|  [mariadb-import](../mariadb-import/index) |  Loads tables from text files in various formats.  |
|  [Backup/Restore + Data Export/Import via dbForge Studio](../backup-restore-and-import-clients-backuprestore-data-exportimport-via-dbfor/index) |  The fastest and easiest way to perform these operations with MariaDB databases.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-restore-and-import-clients/>

MyISAM Clients and Utilities
=============================

   Clients and utilities for working with the MyISAM storage engine

  

| Title | Description |
| --- | --- |
|  [myisamchk](../myisamchk/index) |  Utility for checking, repairing and optimizing MyISAM tables.  |
|  [Memory and Disk Use With myisamchk](../memory-and-disk-use-with-myisamchk/index) |  myisamchk's performance can be dramatically enhanced for larger tables  |
|  [myisamchk Table Information](../myisamchk-table-information/index) |  myisamchk can be used to obtain information about MyISAM tables  |
|  [myisamlog](../myisamlog/index) |  Process the MyISAM log  |
|  [myisampack](../myisampack/index) |  Tool for compressing MyISAM tables  |
|  [myisam\_ftdump](../myisam_ftdump/index) |  A tool for displaying information on MyISAM FULLTEXT indexes.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-clients-and-utilities/>

Diagnostics
============

   The diagnostics area contains information about the error conditions which were produced by an SQL statement, as well as some information about the statement which generated them.

  

| Title | Description |
| --- | --- |
|  [Error Codes](../error-codes/index) |  MariaDB error codes and SQLSTATE codes  |
|  [DECLARE CONDITION](../declare-condition/index) |  For declaring a named error condition (SQLSTATE or error code).  |
|  [DECLARE HANDLER](../declare-handler/index) |  Construct to declare how errors are handled.  |
|  [Diagnostics Area](../diagnostics-area/index) |  A description of the diagnostics area and how it is populated.  |
|  [GET DIAGNOSTICS](../get-diagnostics/index) |  Copy information about the diagnostics area into variables.  |
|  [RESIGNAL](../resignal/index) |  Used to send a SIGNAL again for the previous error.  |
|  [SHOW ERRORS](../show-errors/index) |  Displays errors.  |
|  [SHOW WARNINGS](../show-warnings/index) |  Displays errors, warnings and notes.  |
|  [SIGNAL](../signal/index) |  May be used to produce a custom error message.  |
|  [SQL Error Log Plugin](../sql-error-log-plugin/index) |  Records SQL-level errors to a log file.  |
|  [SQLSTATE](../sqlstate/index) |  A string which identifies a condition's class and subclass  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/programmatic-compound-statements-diagnostics/>

SET Variable
============

    Syntax
------

 
```
SET var_name = expr [, var_name = expr] ...

```
 Description
-----------

 The `SET` statement in [stored programs](../stored-programs-and-views/index) is an extended version of the general `[SET](../set/index)` statement. Referenced variables may be ones declared inside a stored program, global system variables, or user-defined variables.

 The `SET` statement in stored programs is implemented as part of the pre-existing [SET](../set/index) syntax. This allows an extended syntax of `SET a=x, 
b=y, ...` where different variable types (locally declared variables, global and session server variables, user-defined variables) can be mixed. This also allows combinations of local variables and some options that make sense only for system variables; in that case, the options are recognized but ignored.

 `SET` can be used with both [local variables](../declare-variable/index) and [user-defined variables](../user-defined-variables/index).

 When setting several variables using the columns returned by a query, `[SELECT INTO](../select-into/index)` should be preferred.

 To set many variables to the same value, the `[LAST\_VALUE( )](../last_value/index)` function can be used.

 Below is an example of how a user-defined variable may be set:

 
```
SET @x = 1;

```

See Also
--------

 * [SET](../set/index)
* [SET STATEMENT](../set-statement/index)
* [DECLARE Variable](../declare-variable/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-variable/>

dbForge Studio for MySQL/MariaDB
================================

    
dbForge Studio is a proprietary third-party tool, not included with MariaDB Server. Content contributed by devart.

 
**dbForge Studio for MySQL** is an advanced and powerful GUI toolset designed specifically for specialists who deal with databases on MySQL and MariaDB. The purpose is to equip you with all tools needed to set up and perform the database-related routines on MariaDB. It saves time and costs, allowing you to work much more productively overall.

 As a [MariaDB IDE](https://www.devart.com/dbforge/mysql/studio/mariadb-gui-client.html), this Studio offers the superior functionality to resolve all work tasks on this RDBMS. 

 *Database Development*

 The available functionality lets you produce high-quality code much faster. In particular, the advanced automated code completion feature helps you speed up the code writing. The syntax validator detects errors immediately. The code formatter with customized templates lets you set and follow the code standards across your projects. Code refactoring supports intelligent renaming operations for better readability.

 *Database Management*

 When you have the job to compare and synchronize MariaDB databases, the Studio will do these jobs. It covers both the data and schema comparison and generates the syncing scripts to deploy changes on MariaDB (also on MySQL and Percona). You can automate all these routines. Other helpful options allow you to profile queries as well as optimize them and detect any issues in them to fix. Also, you can generate reasonable test data in any volume, create detailed database documentation, design in-depth reports, etc.

 *Database Administration*

 With the tools available in this IDE, you get all the functionality necessary to create, configure, and manage users and their rights. Other features cover the tasks of backing up and restoring, data importing and exporting, and copying and migrating databases in several ways. You can maintain tables, generate database scripts, manage server variables and sessions, etc.

 The Express edition with basic features is offered *free of charge*. Also, a free trial with full functionality of the Studio is available *for 30 days*.

 * [**Learn more about dbForge Studio here**](https://www.devart.com/dbforge/mysql/studio/mariadb-gui-client.html).

 * [**Download a 30-day free trial here**](https://www.devart.com/dbforge/mysql/studio/download.html).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-studio-for-mysqlmariadb/>

dbdeployer
==========

    dbdeployer is a tool for installing multiple versions of MariaDB and/or MySQL in isolation from each other. It is primarily used for easily testing different server versions. It is written in Go, and is a replacement for [MySQL Sandbox](../mysql-sandbox/index).

 Visit <https://www.dbdeployer.com> for details on how to install and use it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbdeployer/>

Graphical and Enhanced Clients
===============================

   This list is incomplete - most MySQL tools will work with MariaDB. See also a list of projects that officially [work with MariaDB](../works-with-mariadb/index).

  

| Title | Description |
| --- | --- |
|  [dbForge Studio for MariaDB](../dbforge-studio-for-mariadb-universal-gui-tool-for-management-administration/index) |  Universal GUI Tool for Management & Administration, Development for MariaDB and MySQL  |
|  [dbForge Edge](../dbforge-edge/index) |  dbForge Edge is a versatile software solution designed to meet the needs of...  |
|  [DBeaver](../graphical-and-enhanced-clients-dbeaver/index) |  Free convenient cross-platform and cross-database Java GUI client  |
|  [ERBuilder Data Modeler](../erbuilder-data-modeler/index) |  A data modeling tool for multiple databases platforms including MariaDB, MySQL, and more ...  |
|  [SQLyog: Community Edition](../sqlyog-community-edition/index) |  SQLyog Community Edition  |
|  [HeidiSQL](../heidisql/index) |  Windows GUI client for MariaDB and MySQL.  |
|  [Navicat](../navicat/index) |  Graphical front-end for MariaDB  |
|  [Querious](../querious/index) |  Mac OS X tool for database administration  |
|  [TablePlus](../tableplus/index) |  A modern, native GUI client for multiple databases  |
|  [Database Workbench](../database-workbench/index) |  Database development environment for multiple database systems including MySQL and MariaDB  |
|  [Luna Modeler](../luna-modeler/index) |  Luna Modeler is a database design tool for MariaDB. Draw ER diagrams, visua...  |
|  [SQL Diagnostic Manager & SQLyog](../cost-effective-agentless-mariadb-database-performance-management/index) |  Graphical MariaDB manager and monitor  |
|  [mycli](../mycli/index) |  Command line interface with auto-completion and syntax highlighting  |
|  [ocelotgui](../ocelotgui/index) |  Linux client for MySQL and MariaDB  |
|  [phpMyAdmin](../phpmyadmin/index) |  Web-based MariaDB administration tool  |
|  [Sequel Pro](../graphical-and-enhanced-clients-sequel-pro/index) |  Database management tool running on Mac  |
|  [SQLTool Pro Database Editor](../sqltool-pro-database-editor/index) |  Android SQL client  |
|  [dbForge Data Compare](../dbforge-data-compare/index) |  A tool for MariaDB & MySQL data comparison and synchronization of data betw...  |
|  [dbForge Data Generator](../dbforge-data-generator/index) |  A tool for generation of large volumes of meaningful test table data.  |
|  [dbForge Documenter for MariaDB and MySQL](../dbforge-documenter-for-mariadb-and-mysql/index) |  dbForge Documenter is a useful tool for MariaDB and MySQL database for the ...  |
|  [dbForge Fusion: MySQL & MariaDB Plugin for VS](../dbforge-fusion-mysql-mariadb-plugin-for-vs/index) |  Visual Studio plugin designed to simplify database development and management.  |
|  [dbForge Query Builder for MySQL & MariaDB](../dbforge-query-builder-for-mysql-mariadb/index) |  A tool for visual query creation without code typing.  |
|  [dbForge Schema Compare for MariaDB & MySQL](../dbforge-schema-compare-for-mariadb-mysql/index) |  A tool for comparison and synchronization of DDL differences between database objects.  |
|  [DbSchema](../dbschema/index) |  Mariadb Diagram Designer & Admin GUI Tool  |
|  [Improved SQL Document Parser Performance in Updated dbForge Tools for MySQL and MariaDB](../graphical-and-enhanced-clients-improved-sql-document-parser-performance-in-/index) |  Devart has upgraded dbForge Tools for MySQL and MariaDB with improved SQL d...  |
|  [OmniDB](../graphical-and-enhanced-clients-omnidb/index) |  Browser-based IDE for MariaDB Administration  |
|  [TOAD Edge](../toad-edge/index) |  Windows GUI for MySQL. SQL Syntax Check. Freeware (Basic Features) & Payware (Extended Features).  |
|  [TOAD for MySQL](../toad-for-mysql-80/index) |  Windows GUI for MySQL. Compatible with MariaDB. Freeware. SQL syntax check.  |
|  [SQLPro Studio](../sqlpro-studio/index) |  SQLPro Studio is a fully native database client for macOS and iOS.  |
|  [SB Data Generator](../sb-data-generator/index) |  A tool to generate and populate selected tables or entire databases with realistic test data.  |
|  [Beekeeper Studio](../beekeeper-studio/index) |  Open source and free GUI with a focus on usability. Mac, Linux, and Windows  |
|  [LibreOffice Base](../libreoffice-base/index) |  An open source RDBMS front-end tool to create and manage various databases  |
|  [Valentina Studio](../valentina-studio/index) |  Free, advanced MariaDB GUI native on macOS, Windows & Linux, with advanced commercial version  |
|  [DbVisualizer](../dbvisualizer/index) |  Cross-platform universal database tool supporting MariaDB, PostgreSQL, MySQL and more  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/graphical-and-enhanced-clients/>

EXPLAIN Analyzer API
====================

    The online [EXPLAIN Analyzer](../explain-analyzer/index) tool has an open API to allow client applications to send it EXPLAINs.

 Sending EXPLAINs to the EXPLAIN Analyzer
----------------------------------------

 To send an EXPLAIN to the EXPLAIN Analyzer, simply POST or GET to the following address:

 
```
mariadb.org/explain_analyzer/api/1/?raw_explain=EXPLAIN&client=CLIENT

```

Replace "EXPLAIN" with the output of the EXPLAIN command and "CLIENT" with the name of your client.

 Client Banner
-------------

 If you like, you can have a banner promoting your client appear at the bottom of the page. Once you've added support for the EXPLAIN Analyzer to your client application, just send a logo, the name of your client, and what you want the name and logo to link to to bryan AT montyprogram DOT com

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-analyzer-api/>

innochecksum
============

     innochecksum is a tool for printing checksums for InnoDB files. 

 Usage
-----

 
```
innochecksum [options] file_name

```

Description
-----------

 It reads an [InnoDB](../innodb/index) tablespace file, calculates the checksum for each page, compares the calculated checksum to the stored checksum, and reports mismatches, which indicate damaged pages. It was originally developed to speed up verifying the integrity of tablespace files after power outages but can also be used after file copies. Because checksum mismatches will cause InnoDB to deliberately shut down a running server, it can be preferable to use innochecksum rather than waiting for a server in production usage to encounter the damaged pages.

 Multiple filenames can be specified by a wildcard on non-Windows systems only.

 innochecksum has worked with compressed pages since [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/).

 [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) added options to analyze leaf pages to estimate how fragmented an index is and how much benefit can be gained from defragmentation. 

 
innochecksum cannot be used on tablespace files that the server already has open. For such files, you should use [CHECK TABLE](../sql-commands-check-table/index) to check tables within the tablespace. If checksum mismatches are found, you would normally restore the tablespace from backup or start the server and attempt to use [mariadb-dump](../mariadb-dump/index) to make a backup of the tables within the tablespace.

 
Options
-------

 innochecksum supports the following options. For options that refer to page numbers, the numbers are zero-based.

 


| Option | Description | Added |
| --- | --- | --- |
| -a, --allow-mismatches=# | Maximum checksum mismatch allowed before innochecksum terminates. Defaults to 0, which terminates on the first mismatch. | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| -c, --count | Print a count of the number of pages in the file. |  |
| -d, --debug | Debug mode; prints checksums for each page, implies `--verbose`. Replaced by `--log` in [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |  |
| -e num, --end-page=# | End at this page number (0-based). |  |
| -?, --help | Displays help and exits. |  |
| -I, --info | Synonym for --help. |  |
| -f, --leaf | Examine leaf index pages. Until [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), the short code was `-l`, but this was changed to avoid confusion with the `--log` option. | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| -l fn, --log=fn | Log output to the specified filename `fn`. | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| -m num, --merge=# | Leaf page count if merge given number of consecutive pages. | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| -n, --no-check | Ignore the checksum verification. Until [MariaDB 10.6](../what-is-mariadb-106/index), must be used with the `--write` option. | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| -p num, --page=# | Check only this page number (0-based). |  |
| -D, --page-type-dump=name | Dump the page type info for each page in a tablespace. | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| -S, --page-type-summary | Display a count of each page type in a tablespace | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| -i, --per-page-details | Print out per-page detail information. |  |
| -u, --skip-corrupt | Skip corrupt pages. | [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/) |
| -s num, --start-page=# | Start at this page number (0-based). |  |
| -C, --strict-check=name | Specify the strict checksum algorithm. One of: crc32, innodb, none. If not specified, validates against innodb, crc32 and none. See also [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm). | Added [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) Removed [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| -v, --verbose | Verbose mode; print a progress indicator every five seconds. |  |
| -V, --version | Displays version information and exits. |  |
| -w, --write=name | Rewrite the checksum algorithm. One of crc32, innodb, none. An exclusive lock is obtained during use. Use in conjunction with the `-no-check` option to rewrite an invalid checksum. | Added [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) Removed [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |

 
Examples
--------

 Rewriting a crc32 checksum to replace an invalid checksum:

 
```
innochecksum --no-check --write crc32 tablename.ibd

```

A count of each page type:

 
```
innochecksum --page-type-summary data/mysql/gtid_slave_pos.ibd

File::data/mysql/gtid_slave_pos.ibd
================PAGE TYPE SUMMARY==============
#PAGE_COUNT	PAGE_TYPE
===============================================
       1	Index page
       0	Undo log page
       1	Inode page
       0	Insert buffer free list page
       2	Freshly allocated page
       1	Insert buffer bitmap
       0	System page
       0	Transaction system page
       1	File Space Header
       0	Extent descriptor page
       0	BLOB page
       0	Compressed BLOB page
       0	Page compressed page
       0	Page compressed encrypted page
       0	Other type of page

===============================================
Additional information:
Undo page type: 0 insert, 0 update, 0 other
Undo page state: 0 active, 0 cached, 0 to_free, 0 to_purge, 0 prepared, 0 other
index_id	#pages		#leaf_pages	#recs_per_page	#bytes_per_page
24		1		1		0		0

index_id	page_data_bytes_histgram(empty,...,oversized)
24		1	0	0	0	0	0	0	0	0	0	0	0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innochecksum/>

EXPLAIN Analyzer
================

    
The EXPLAIN Analyzer is no longer active.

 
The [EXPLAIN Analyzer](https://mariadb.org/explain_analyzer/analyze/) was an online tool for analyzing and optionally sharing the output of both [EXPLAIN](../explain/index) and `EXPLAIN EXTENDED`.

 Using the Analyzer
------------------

 Using the analyzer is very simple.

 1. In the mariadb client, run `EXPLAIN` on a query and copy the output. For example:

 
```
EXPLAIN SELECT * FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.a=t2.a AND t2.a=t3.a;
+------+-------------+-------+------+---------------+------+---------+------+------+--------------------------------------------------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                                  |
+------+-------------+-------+------+---------------+------+---------+------+------+--------------------------------------------------------+
|    1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    3 |                                                        |
|    1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using join buffer (flat, BNL join)        |
|    1 | SIMPLE      | t3    | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where; Using join buffer (incremental, BNL join) |
+------+-------------+-------+------+---------------+------+---------+------+------+--------------------------------------------------------+
3 rows in set (0.00 sec)

```

2. Paste the output into the [`EXPLAIN` Analyzer input box](https://mariadb.org/explain_analyzer/analyze/) and click the "Analyze Explain" button.

 3. The formatted `EXPLAIN` will be shown. You can now click on various part to get more information about them.

 ### Some Notes:

 * As you can see in the example above, you don't need to chop off the query line or the command prompt.
* To save the EXPLAIN, so you can share it, or just for future reference, click the "Save Explain for analysis and sharing" button and then click the "Analyze Explain" button. You will be given a link which leads to your saved `EXPLAIN`. For example, the above explain can be viewed here: <https://mariadb.org/explain_analyzer/analyze/>
* Some of the elements in the formatted `EXPLAIN` are clickable. Clicking on them will show pop-up help related to that element.

 Clients which integrate with the Explain Analyzer
-------------------------------------------------

 The Analyzer has an API that client programs can use to send EXPLAINs. If you are a client application developer, see the [EXPLAIN Analyzer API](../explain-analyzer-api/index) page for details.

 The following clients have support for the EXPLAIN Analyzer built in:

 ### HeidiSQL

 [HeidiSQL](https://www.heidisql.com/) has a button when viewing a query that sends the query to the explain analyzer.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-analyzer/>

msql2mysql
==========

    Description
-----------

 Initially, the MySQL C API was developed to be very similar to that of the mSQL database system.

 Because of this, mSQL programs often can be converted relatively easily for use with MySQL by changing the names of their C API functions.

 The `msql2mysql` utility performs the conversion of mSQL C API function calls to their MySQL equivalents.

 
**Warning:** `msql2mysql` converts the input file in place, so make a copy of the original before converting it.

 
Example
-------

 
```
shell> cp client-prog.c client-prog.c.orig
shell> msql2mysql client-prog.c
client-prog.c converted

```

After conversion, examine `client-prog.c` and make any necessary post-conversion revisions.

 `msql2mysql` uses the `[replace](../replace-utility/index)` utility to make the function name substitutions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/msql2mysql/>

my\_print\_defaults
===================

    `my_print_defaults` displays the options from option groups of option files. It is useful to see which options a particular tool will use.

 Output is one option per line, displayed in the form in which they would be specified on the command line.

 Usage
-----

 
```
my_print_defaults [OPTIONS] [groups]

```

Options
-------

 


| Option | Description |
| --- | --- |
| `-c`, `--config-file=name` | Deprecated, please use --defaults-file instead. Name of config file to read; if no extension is given, default extension (e.g., .ini or .cnf) will be added. |
| `-#` ,`--debug[=#]` | In debug versions, write a debugging log. A typical debug\_options string is `d:t:o,file_name`. The default is `d:t:o,/tmp/my_print_defaults.trace`. |
| `-c, --defaults-file=name` | Like --config-file, except: if first option, then read this file only, do not read global or per-user config files; should be the first option. Removed in [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/). |
| `-e`, `--defaults-extra-file=name` | Read this file after the global config file and before the config file in the users home directory; should be the first option. Removed in [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/). |
| `-g`, `--defaults-group-suffix=name` | In addition to the given groups, read also groups with this suffix. Removed in [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/). |
| `-e`, `--extra-file=name` | Deprecated. Synonym for --defaults-extra-file. |
| `--mysqld` | Read the same set of groups that the mysqld binary does. |
| `-n`, `--no-defaults` | Return an empty string (useful for scripts). |
| `?`, `--help` | Display this help message and exit. |
| `-v`, `--verbose` | Increase the output level. |
| `-V`, `--version` | Output version information and exit. |

 
Examples
--------

 
```
my_print_defaults --defaults-file=example.cnf client client-server mysql

```

[mariadb-check](../mariadb-check/index) reads from the [mariadb-check] and [client] sections, so the following would display the mariadb-check options. 

 
```
my_print_defaults mariadb-check client

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/my_print_defaults/>

mariadb-binlog
===============

   
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-binlog` is a symlink to `mysqlbinlog`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-binlog` is the name of the tool, with `mysqlbinlog` a symlink .

 
`mariadb-binlog` is a utility included with MariaDB for processing [binary log](../binary-log/index) and [relay log](../relay-log/index) files.

 The MariaDB server's binary log is a set of files containing "events" which represent modifications to the contents of a MariaDB database. These events are written in a binary (i.e. non-human-readable) format. The mariadb-binlog utility is used to view these events in plain text.

  

| Title | Description |
| --- | --- |
|  [Using mariadb-binlog](../using-mariadb-binlog/index) |  Viewing the binary log with mariadb-binlog.  |
|  [mariadb-binlog Options](../mariadb-binlog-options/index) |  Options supported by mariadb-binlog.  |
|  [Annotate\_rows\_log\_event](../annotate_rows_log_event/index) |  Annotate\_rows events accompany row events and describe the query which caused the row event.  |
|  [mysqlbinlog](../mariadb-binlog-mysqlbinlog/index) |  Symlink or old name for mariadb-binlog.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-binlog/>

mariadb-stress-test
===================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-stress-test` is a symlink to `mysql-stress-test`, the script for assisting with adding users or databases or changing passwords in MariaDB.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql-stress-test` is the symlink, and `mariadb-stress-test` the binary name.

 
 *mariadb-stress-test.pl* is a Perl script that performs stress-testing of the MariaDB server. It requires a version of Perl that has been built with threads support.

 Syntax
------

 
```
mariadb-stress-test.pl [options]

```

Options
-------

 


| Option | Description |
| --- | --- |
| `--help` | Display a help message and exit. |
| `--abort-on-error=N` | Causes the program to abort if an error with severity less than or equal to N was encountered. Set to 1 to abort on any error. |
| `--check-tests-file` | Periodically check the file that lists the tests to be run. If it has been modified, reread the file. This can be useful if you update the list of tests to be run during a stress test. |
| `--cleanup` | Force cleanup of the working directory. |
| `--log-error-details` | Log error details in the global [error log](../error-log/index) file. |
| `--loop-count=N` | In sequential test mode, the number of loops to execute before exiting. |
| `--mysqltest=path` | The path name to the [mysqltest](../mysqltest/index) program. |
| `--server-database=db_name` | The database to use for the tests. The default is test. |
| `--server-host=host_name` | he host name of the local host to use for making a TCP/IP connection to the local server. By default, the connection is made to localhost using a Unix socket file. |
| `--server-logs-dir=path` | This option is required. path is the directory where all client session logs will be stored. Usually this is the shared directory that is associated with the server used for testing. |
| `--server-password=password` | The password to use when connecting to the server. |
| `--server-port=port_num` | The TCP/IP port number to use for connecting to the server. The default is 3306. |
| `--server-socket=file_name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. The default is `/tmp/mysql.sock`. |
| `--server-user=user_name` | The MariaDB user name to use when connecting to the server. The default is root. |
| `--sleep-time=N` | The delay in seconds between test executions. |
| `--stress-basedir=path` | This option is required and specified the path is the working directory for the test run. It is used as the temporary location for result tracking during testing. |
| `--stress-datadir=path` | The directory of data files to be used during testing. The default location is the data directory under the location given by the `--stress-suite-basedir` option. |
| `--stress-init-file[=path]` | *file\_name* is the location of the file that contains the list of tests to be run once to initialize the database for the testing. If missing, the default file is `stress_init.txt` in the test suite directory. |
| `--stress-mode=mode` | This option indicates the test order in stress-test mode. The mode value is either `random` to select tests in random order or `seq` to run tests in each thread in the order specified in the test list file. The default mode is `random`. |
| `--stress-suite-basedir=path` | This option is required and specifies the directory that has the *t* and *r* subdirectories containing the test case and result files. This directory is also the default location of the `stress-test.txt` file that contains the list of tests. (A different location can be specified with the `--stress-tests-file` option.) |
| `--stress-tests-file[=file_name]` | Use this option to run the stress tests. *file\_name* is the location of the file that contains the list of tests. If omitted, the default file is `stress-test.txt` in the stress suite directory. (See `--stress-suite-basedir`.) |
| `--suite=suite_name` | Run the named test suite. The default name is `main` (the regular test suite located in the `mysql-test` directory). |
| `--test-count=N` | The number of tests to execute before exiting. |
| `--test-duration=N` | The duration of stress testing in seconds. |
| `--threads=N` | The number of threads. The default is 1. |
| `--verbose` | Verbose mode. Print more information about what the program does |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-stress-test/>

mariadb-test
=============

   MariaDB uses **mariadb-test** to test functionality. It is an all-in-one test framework, doing unit, regression, and conformance testing. The framework was inherited from MySQL, but is greatly enhanced, optimized, and extended in MariaDB.

  

| Title | Description |
| --- | --- |
|  [mariadb-test Overview](../mariadb-test-overview/index) |  Overview of mariadb-test.  |
|  [mariadb-test Auxiliary Files](../mariadb-test-auxiliary-files/index) |  Besides test and result files, many other files that affect the testing process in mariadb-test  |
|  [mariadb-test-run.pl Options](../mariadb-test-run-pl-options/index) |  Run test cases.  |
|  [Pausing mariadb-test-run.pl](../pausing-mariadb-test-run-pl/index) |  Working while your computer is busy running mariadb-test-run.pl.  |
|  [mariadb-test and mariadb-test-embedded](../mariadb-test-and-mariadb-test-embedded/index) |  Runs a test case against a MariaDB server, optionally comparing the output with a result file.  |
|  [New Features for mysqltest in MariaDB](../new-features-for-mysqltest-in-mariadb/index) |  MariaDB added a number of new options and commands to mysqltest.  |
|  [Debugging MariaDB With a Debugger](../debugging-mariadb-with-a-debugger/index) |  If MariaDB is compiled for debugging, you can both use it in a debugger, an...  |
|  [The Debug Sync Facility](../the-debug-sync-facility/index) |  DEBUG\_SYNC synchronization points in server code  |
|  [Code Coverage with dgcov](../dgcov/index) |  The dgcov tool helps you check the coverage for new code.  |
|  [Installing MinIO for Usage With mariadb-test-run](../installing-minio-for-usage-with-mariadb-test-run/index) |  Easiest way to access to Amazon S3 compatible storage.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-test/>

perror
======

     *perror* is a utility that displays descriptions for system or storage engine error codes.

 See [MariaDB Error Codes](../mariadb-error-codes/index) for a full list of MariaDB error codes, and [Operating System Error Codes](../operating-system-error-codes/index) for a list of Linux and Windows error codes.

 Usage
-----

 
```
perror [OPTIONS] [ERRORCODE [ERRORCODE...]]

```

If you need to describe a negative error code, use `--` before the first error code to end the options.

 Options
-------

 


| Option | Description |
| --- | --- |
| `-?`, `--help` | Display help and exit. |
| `-I`, `--info` | Synonym for `--help`. |
| `-s`, `--silent` | Only print the error message. |
| `-v`, `--verbose` | Print error code and message (default). (Defaults to on; use `--skip-verbose` to disable.) |
| `-V`, `--version` | Displays version information and exits. |

 
Examples
--------

 System error code:

 
```
shell> perror 96
OS error code  96:  Protocol family not supported

```

MariaDB/MySQL [error code](../mariadb-error-codes/index):

 
```
shell> perror 1005 1006
MySQL error code 1005 (ER_CANT_CREATE_TABLE): Can't create table %`s.%`s (errno: %M)
MySQL error code 1006 (ER_CANT_CREATE_DB): Can't create database '%-.192s' (errno: %M)

```


```
shell> perror --silent 1979
You are not owner of query %lu

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/perror/>

replace Utility
===============

    Description
-----------

 The replace utility program changes strings in place in files or on the standard input. Invoke replace in one of the following ways:

 
```
shell> replace from to [from to] ... -- file_name [file_name] ...
shell> replace from to [from to] ... < file_name

```

"`from`" represents a string to look for and "`to`" represents its replacement. There can be one or more pairs of strings.

 A from-string can contain these special characters:

 


| Character | Description |
| --- | --- |
| `\^` | Match start of line. |
| `\$` | Match end of line. |
| `\b` | Match space-character, start of line or end of line. For an end `\b` the next replace starts looking at the end space-character. A `\b` alone in a string matches only a space-character |

 
Use the `--` option to indicate where the string-replacement list ends and the file names begin. Any file named on the command line is modified in place, so you may want to make a copy of the original before converting it. `replace` prints a message indicating which of the input files it actually modifies.

 If the `--` option is not given, replace reads standard input and writes to standard output.

 replace uses a finite state machine to match longer strings first. It can be used to swap strings. For example, the following command swaps "a" and "b" in the given files, /file1 *and* file2*:*

 
```
shell> replace a b b a -- file1 file2 ...

```

The replace program is used by [msql2mysql](../msql2mysql/index).

 Options
-------

 `replace` supports the following options.

 


| Option | Description |
| --- | --- |
| `-?`, `-I` | Display a help message and exit. |
| `-#debug_options` | Enable debugging. |
| `-s` | Silent mode. Print less information about what the program does. |
| `-v` | Verbose mode. Print more information about what the program does. |
| `-V` | Display version information and exit. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replace-utility/>

resolveip
=========

     resolveip is a utility for resolving IP addresses to host names and vice versa.

 Usage
-----

 
```
resolveip [OPTIONS] hostname or IP-address

```

Options
-------

 


| Option | Description |
| --- | --- |
| `-?`, `--help` | Display help and exit. |
| `-I`, `--info` | Synonym for `--help`. |
| `-s`, `--silent#` | Be more silent. |
| `-V`, `--version` | Display version information and exit. |

 
Examples
--------

 
```
shell> resolveip mariadb.org
IP address of mariadb.org is 166.78.144.191

```


```
resolveip 166.78.144.191
Host name of 166.78.144.191 is mariadb.org

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/resolveip/>

resolve\_stack\_dump
====================

    resolve\_stack\_dump is a tool that resolves numeric stack strace dumps into symbols.

 Usage
-----

 
```
resolve_stack_dump [OPTIONS] symbols-file [numeric-dump-file]

```

The symbols-file should include the output from: `nm --numeric-sort mysqld`. The numeric-dump-file should contain a numeric stack trace from mysqld. If the numeric-dump-file is not given, the stack trace is read from stdin.

 Options
-------

 


| Option | Description |
| --- | --- |
| `-h`, `--help` | Display this help and exit. |
| `-V`, `--version` | Output version information and exit. |
| `-s`, `--symbols-file=name` | Use specified symbols file. |
| `-n`, `--numeric-dump-file=name` | Read the dump from specified file. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/resolve_stack_dump/>

xtstat
======

     `xtstat` can be used to monitor all internal activity of [PBXT](../pbxt/index).

 `xtstat` polls the `INFORMATION_SCHEMA.PBXT_STATISTICS` table. The poll interval can be set using the `--delay` option, and is 1 second by default.

 For most statistics, `xtstat` will display the difference in values between the current and previous polls. For example, if bytes written current value is 1000, and on the previous call it was 800, then `xtstat` will display 200. This means that 200 bytes were written to disk in the intervening period.

 Using `xtstat`
--------------

 Invoke xtstat as follows:

 
```
$ xtstat [ options ]

```

For example, to poll every 10 seconds:

 
```
xtstat -D10

```

Note that statistic counters are never reset, even if a rollback occurs. For example, if an `UPDATE` statement is rolled back, `xtstat` will still indicate that one write statement (see stat-write below) was executed.

 If MariaDB shuts down or crashes, `xtstat` will attempt to reconnect. `xtstat` can be terminated any time using the `CTRL-C` key cimbination.

 Before [PBXT](../pbxt/index) has recovered, not all statistics are available. In particular, the statistics relating to PBXT background threads are not available (including the `sweep` and `chkpnt` statistics).

 ### Command line options

 `xtstat` options are as follows:

 

| Option
 | Description |
| --- | --- |
| `-?, --help` | Prints help text. |
| `-h, --host=value` | Connect to host. |
| `-u, --user=value` | User for login if not current user. |
| `-p, --password[=value]` | Password to use when connecting to server. If password is not given it's asked from the tty. |
| `-d, --database=value` | Database to be used (`pbxt` or `information_schema` required), default is `information_schema` |
| `-P, --port=value` | Port number to use for connection. |
| `-S, --socket=value` | Socket file to use for connection. |
| `-D, --delay=value` | Delay in seconds between polls of the database. |
| `--protocol=value` | Connection protocol to use: `default/tcp/socket/pipe/memory` |
| `--display=value` | Columns to display: use short names separated by `|` (the pipe character), partial match allowed. Use `--display=all` to display all columns available. |

 Connection options will also be taken from the MySQL config file if available.

 #### Size indicators

 Values displayed by `xtstat` are either a time in milliseconds, a value in bytes, or a counter. If these values are too large to be displayed then the value is rounded and a size indicator is added.

 The following size indicators are used:

 

|  |  |  |
| --- | --- | --- |
| `K` | : | Kilobytes *(1,024 bytes)* |
| `M` | : | Megabytes *(1,048,576 bytes)* |
| `G` | : | Gigabytes *(1,073,741,024 bytes)* |
| `T` | : | Terabytes *(1,099,511,627,776 bytes)* |
| `t` | : | thousands *(1,000s)* |
| `m` | : | millions *(1,000,000s)* |
| `b` | : | billions *(1,000,000,000s)* |

 ### Statistics

 The following is a list of the statistics displayed by `xtstat`. Each statistic as a two-part display name. The first part is the category and the second part is the type.

 You can select categories and types for display, as you require. For example `--display=read` will display all read activity, `--display=xact|stat` will display transaction and statement activity.

 Note, for diagnostics it is best to capture all statistics. The reason is because you never now where a problem might turn up, so without certain statistics you may not be able to identify the problem.

 

| Displayname | Name | Description |
| --- | --- | --- |
| `time-curr` | Current Time | The current time in seconds |
| `time-msec` | TimeSinceLastCall | Time passed in milliseconds since last statistics call |
| `xact-commt` | Commit Count | Number of transactions committed |
| `xact-rollb` | Rollback Count | Number of transactions rolled back |
| `xact-waits` | Wait for Xact Count | Number of times waited for another transaction |
| `xact-dirty` | Dirty Xact Count | Number of transactions still to be cleaned up. This also includes all the currently running transactions. Cleanup means that the Sweeper thread must still scan the transcation and collect/mark any "garbage" left by the transaction. Garbage is, for example, versions of rows that are no longer visiable by any transaction. |
| `stat-read` | Read Statements | Number of SELECT statements |
| `stat-write` | Write Statements | Number of UPDATE/INSERT/DELETE statements |
| `rec-in` | Record Bytes Read | Bytes read from the record/row files |
| `rec-out` | Record Bytes Written | Bytes written to the record/row files. This data is transfered from the transaction logs to the handle data (xtd) and the row index files (xtr). |
| `rec-syncs/ms` | Record File Flushes | 2 values separated by a '/': the number of flushes to data handle (.xtd) and row index (.xtr) files and the time taken in milliseconds to perform the flush operations. |
| `rec-hits` | Record Cache Hits | Hits when accessing the record cache. The record cache caches the data handle (.xtd) and row index (.xtr) files. |
| `rec-miss` | Record Cache Misses | Misses when accessing the record cache |
| `rec-frees` | Record Cache Frees | Number of record cache pages freed |
| `rec-%use` | Record Cache Usage | Percentage of record cache in use. This value is displayed by xtstat as a percentage of the total cache available, but the value returned by PBXT\_STATISTICS table is in bytes used. |
| `ind-in` | Index Bytes Read | Bytes read from the index files |
| `ind-out` | IndexBytesWritten | Bytes written to the index files. This data is transfered from the index log files (ilog) to the index files (xti), during a consistent flush of the index. |
| `ind-syncs/ms` | Index File Flushes | 2 values separated by a '/': the number of flushes to index files and the time taken for the flush operations in milliseconds. |
| `ind-hits` | Index Cache Hits | Hits when accessing the index cache |
| `ind-miss` | Index Cache Misses | Misses when accessing the index cache |
| `ind-%use` | Index Cache Usage | Percentage of index cache used. This value is displayed by xtstat as a percentage of the total cache available, but the value returned by PBXT\_STATISTICS table is in bytes used. |
| `ilog-in` | Index Log Bytes In | Bytes read from the index log files |
| `ilog-out` | Index Log Bytes Out | Bytes written to the index log files. This data is transfered from the index cache in main memory to the index log files (ilog) during a consistent flush of the index. |
| `ilog-syncs/ms` | Index Log File Syncs | 2 values separated by a '/': the number of flushes to index log files and the time taken for the flush operations in milliseconds |
| `xlog-in` | Xact Log Bytes In | Bytes read from the transaction log files |
| `xlog-out` | Xact Log Bytes Out | Bytes written to the transaction log files. This is data transfered from the transaction log buffer (pbxt\_transaction\_buffer\_size) to the transaction log files (.xlog). This transfer occurs on commit or when the transaction log buffer is full. |
| `xlog-syncs` | Xact Log File Syncs | Number of flushes to transaction log files |
| `xlog-msec` | Xact Log Sync Time | The time in milliseconds to flush transaction log files |
| `xlog-hits` | Xact Log Cache Hits | Hits when accessing the transaction log cache |
| `xlog-miss` | Xact Log Cache Misses | Misses when accessing the transaction log cache |
| `xlog-%use` | Xact Log Cache Usage | Percentage of transaction log cache used. This value is displayed by xtstat as a percentage of the total cache available, but the value returned by PBXT\_STATISTICS table is in bytes used. |
| `data-in` | Data Log Bytes In | Bytes read from the data log files |
| `data-out` | Data Log Bytes Out | Bytes written to the data log files. This data is transfered from the data log buffer (pbxt\_log\_buffer\_size) to the data log files (.dlog), when the buffer is full, or on commit. |
| `data-syncs` | Data Log File Syncs | Number of flushes to data log files |
| `data-msec` | Data Log Sync Time | The time in milliseconds spent flushing data log files |
| `to-chkpt` | Bytes to Checkpoint | Bytes written to the transaction log since the last checkpoint |
| `to-write` | Log Bytes to Write | Bytes written to the transaction log, still to be written to the database |
| `to-sweep` | Log Bytes to Sweep | Bytes written to the transaction log, still to be read by the Sweeper thread |
| `sweep-waits` | SweeperWaitonXact
 | Attempts to cleanup a transaction |
| `scan-index` | Index Scan Count | Number of index scans |
| `scan-table` | Table Scan Count | Number of table scans |
| `row-sel` | Select Row Count | Number of rows selected |
| `row-ins` | Insert Row Count | Number of rows inserted |
| `row-upd` | Update Row Count | Number of rows updated |
| `row-del` | Delete Row Count | Number of rows deleted |

 More Information
----------------

 Documentation on this page is based on the [xtstat documentation](http://primebase.org/documentation/index.php#xtstat) on the PrimeBase website.

 Paul McCullagh's presentation from the 2010 User's Conference has some usage examples: <http://www.primebase.org/download/pbxt-uc-2010.pdf>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xtstat/>

mariadb-access
==============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-access` is a symlink to `mysqlaccess`, the tool for checking access privileges.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-access` is the name of the tool, with `mysqlaccess` a symlink .

 

**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-access` is a symlink to `mysqlaccess`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-access` is the name of the tool, with `mysqlaccess` a symlink .

 
 `mariadb-access` is a tool for checking access privileges, developed by Yves Carlier.

 It checks the access privileges for a host name, user name, and database combination. Note that mariadb-access checks access using only the [user](../mysqluser-table/index), [db](../mysqldb-table/index), and host tables. It does not check table, column, or routine privileges specified in the [tables\_priv](../mysqltables_priv-table/index), [columns\_priv](../mysqlcolumns_priv-table/index), or [procs\_priv](../mysqlprocs_priv-table/index) tables.

 Usage
-----

 
```
mariadb-access [host [user [db]]] OPTIONS

```

If your MariaDB distribution is installed in some non-standard location, you must change the location where *mariadb-access* expects to find the mariadb client. Edit the *mariadb-access* script at approximately line 18. Search for a line that looks like this: <<code> $MYSQL = ´/usr/local/bin/mariadb; # path to mariadb executable <</code>> Change the path to reflect the location where *mariadb* actually is stored on your system. If you do not do this, a *Broken pipe error* will occur when you run *mariadb-access*.

 Options
-------

 


| Option | Description |
| --- | --- |
| `-?`, `--help` | Displayhelp and exit. |
| `-v`, `--version` | Display version. |
| `-u username`, `--user=username` | Username for logging in to the db. |
| `-p[password]`, `--password[=password]` | Password to use for user. If ommitted, `mariadb-access` prompts for one. |
| `-h hostname`, `--host=hostname`  | Name or IP of the host. |
| `-d dbname`, `--db=dbname` | Name of the database. |
| `-U username`, `--superuser=username` | Connect as superuser. |
| `-P password`, `--spassword=password` | Password for superuser. |
| `-H server`, `--rhost=server` | Remote server to connect to. |
| `--old_server` | Connect to a very old MySQL servers (before version 3.21) that does not know how to handle full WHERE clauses. |
| `-b`, `--brief` | Single-line tabular report. |
| `-t`, `--table` | Report in table-format. |
| `--relnotes` | Print release-notes. |
| `--plan` | Print suggestions/ideas for future releases. |
| `--howto` | Some examples of how to run `mariadb-access'. |
| `--debug=N` | Enter debug level N (0..3). |
| `--copy` | Reload temporary grant-tables from original ones. |
| `--preview` | Show differences in privileges after making changes in (temporary) grant-tables. |
| `--commit` | Copy grant-rules from temporary tables to grant-tables (the grant tables must be flushed after, for example with [mariadb-admin reload](../mariadb-admin/index)). |
| `--rollback` | Undo the last changes to the grant-tables. |

 
Note
----

 At least the user (`-u`) and the database (`-d`) must be given, even with wildcards. If no host is provided, `localhost' is assumed. Wildcards (\*,?,%,\_) are allowed for *host*, *user* and *db*, but be sure to escape them from your shell!! (ie type \\* or '\*')

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-access/>

mariadb-admin
=============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-admin` is a symlink to `mysqladmin`, the administration program for the mysqld daemon.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-admin` is the name of the administration program for the mysqld daemon, with `mysqladmin` a symlink .

  `mariadb-admin` is an administration program for the mysqld daemon. It can be used to:

 * Monitor what the MariaDB clients are doing (processlist)
* Get usage statistics and variables from the MariaDB server
* Create/drop databases
* Flush (reset) logs, statistics and tables
* Kill running queries.
* Stop the server (shutdown)
* Start/stop replicas
* Check if the server is alive (ping)

 Using mariadb-admin
-------------------

 The command to use `mariadb-admin` and the general syntax is:

 
```
mariadb-admin [options] command [command-arg] [command [command-arg]] ...

```

### Options

 `mariadb-admin` supports the following options:

 


| Option | Description |
| --- | --- |
| `--character-sets-dir=name` | Directory where the [character set](../data-types-character-sets-and-collations/index) files are located. |
| `-C`, `--compress` | Compress all information sent between the client and the server if both support compression. |
| `--connect_timeout=val` | Maximum time in seconds before connection timeout. The default value is 43200 (12 hours). |
| `-c val`, `--count=val` | Number of iterations to make. This works with `-i` (`--sleep`) only. |
| `--debug[=debug_options]`, `-# [debug_options]` | Write a debugging log. A typical debug\_options string is `d:t:o,file_name`. The default is `d:t:o,/tmp/mysqladmin.trace`. |
| `--debug-check` | Check memory and open file usage at exit. |
| `--debug-info` | Print debugging information and memory and CPU usage statistics when the program exits. |
| `--default-auth=plugin` | Default authentication client-side plugin to use. |
| `--default-character-set=name` | Set the default character set. |
| `-f`, `--force` | Don't ask for confirmation on drop database; with multiple commands, continue even if an error occurs. |
| `-?`, `--help` | Display this help and exit. |
| `-h name`, `--host=name` | Hostname to connect to. |
| `-l`, `--local` | Suppress the SQL command(s) from being written to the [binary log](../binary-log/index) by enabling [sql\_log\_bin=0](../replication-and-binary-log-server-system-variables/index#sql_log_bin) for the session, or, from [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/) and [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/), for flush commands only, using `FLUSH LOCAL` rather than `SET sql_log_bin=0`, so the privilege requirement is RELOAD rather than SUPER. |
| `-b`, `--no-beep` | Turn off beep on error. |
| `-p[password]`, `--password[=password]` | Password to use when connecting to server. If password is not given it's asked from the terminal. |
| `--pipe`, `-W` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `-P portnum`, `--port=portnum` | 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). |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `-r`, `--relative` | Show difference between current and previous values when used with `-i`. Currently only works with extended-status. |
| `-O value`, `--set-variable=vaue` | Change the value of a variable. Please note that this option is deprecated; you can set variables directly with `--variable-name=value`. |
| `--shutdown_timeout=val` | Maximum number of seconds to wait for server shutdown. The default value is 3600 (1 hour). |
| `-s`, `--silent` | Silently exit if one can't connect to server. |
| `-i delay`, `--sleep=delay`  | Execute commands repeatedly, sleeping for *delay* seconds in between. The `--count` option determines the number of iterations. If `--count` is not given, *mariadb-admin* executes commands indefinitely until interrupted. |
| `-S name`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. The `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `--tls-version=name` | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. |
| `-u`, `--user=name` | User for login if not current user. |
| `-v`, `--verbose` | Write more information. |
| `-V`, `--version` | Output version information and exit. |
| `-E`, `--vertical` | Print output vertically. Is similar to '`--relative`', but prints output vertically. |
| `-w[count]`, `--wait[=count]` | If the connection cannot be established, wait and retry instead of aborting. If a *count* value is given, it indicates the number of times to retry. The default is one time. |
| `--wait-for-all-slaves` | Wait for the last binlog event to be sent to all connected replicas before shutting down. This option is off by default. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-admin` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-admin` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
`mariadb-admin` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-admin` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqladmin]` |  Options read by `mysqladmin`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-admin]` | Options read by `mariadb-admin`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
mariadb-admin Variables
-----------------------

 Variables can be set with `--variable-name=value`.

 


| Variables and boolean options | Value |
| --- | --- |
| `count` | `0` |
| `debug-check` | `FALSE` |
| `debug-info` | `FALSE` |
| `force` | `FALSE` |
| `compress` | `FALSE` |
| `character-sets-dir` | *(No default value)* |
| `default-character-set` | *(No default value)* |
| `host` | *(No default value)* |
| `no-beep` | `FALSE` |
| `port` | `3306` |
| `relative` | `FALSE` |
| `socket` | `/var/run/mysqld/mysqld.sock` |
| `sleep` | `0` |
| `ssl` | `FALSE` |
| `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-verify-server-cert` | `FALSE` |
| `user` | *(No default value)* |
| `verbose` | `FALSE` |
| `vertical` | `FALSE` |
| `connect_timeout` | `43200` |
| `shutdown_timeout` | `3600` |

 
mariadb-admin Commands
----------------------

 
```
mariadb-admin [options] command [command-arg] [command [command-arg]] ...

```

*Command* is one or more of the following. Commands may be shortened to a unique prefix.

 


| Command | Description |
| --- | --- |
| `create databasename` | Create a new database. |
| `debug` | Instruct server to write debug information to log. |
| `drop databasename` | Delete a database and all its tables. |
| `extended-status` | Return all [status variables](../server-status-variables/index) and their values. |
| `flush-all-statistics` | Flush all statistics tables |
| `flush-all-status` | Flush status and statistics. |
| `flush-binary-log` | Flush [binary log](../binary-log/index). |
| `flush-client-statistics` | Flush client statistics. |
| `flush-engine-log` | Flush engine log. |
| `flush-error-log` | Flush [error log](../error-log/index). |
| `flush-general-log` | Flush [general query log](../general-query-log/index). |
| `flush-hosts` | Flush all cached hosts. |
| `flush-index-statistics` | Flush index statistics. |
| `flush-logs` | Flush all logs. |
| `flush-privileges` | Reload grant tables (same as reload). |
| `flush-relay-log` | Flush [relay log](../relay-log/index). |
| `flush-slow-log` | Flush slow query log. |
| `flush-ssl` | Flush SSL certificates. Added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). |
| `flush-status` | Clear [status variables](../server-status-variables/index). |
| `flush-table-statistics` | Clear table statistics. |
| `flush-tables` | Flush all tables. |
| `flush-threads` | Flush the thread cache. |
| `flush-user-resources` | Flush user resources. |
| `flush-user-statistics` | Flush user statistics. |
| `kill id,id,...` | Kill mysql threads. |
| `password new-password` | Change old password to new-password. The new password can be passed on the commandline as the next argument (for example, `mariadb-admin password "new_password"`, or can be omitted (as long as no other command follows), in which case the user will be prompted for a password. If the password contains special characters, it needs to be enclosed in quotation marks. In Windows, the quotes can only be double quotes, as single quotes are assumed to be part of the password. If the server was started with the [--skip-grant-tables](../mysqld-options/index#-skip-grant-tables) option, changing the password in this way will have no effect. |
| `old-password new-password` | Change old password to new-password using the old pre-MySQL 4.1 format. |
| `ping` | Check if mysqld is alive. Return status is 0 if the server is running (even in the case of an error such as access denied), 1 if it is not. |
| `processlist` | Show list of active threads in server, equivalent to [SHOW PROCESSLIST](../show-processlist/index). With `--verbose`, equivalent to [SHOW FULL PROCESSLIST](../show-processlist/index). |
| `reload` | Reload grant tables. |
| `refresh` | Flush all tables and close and open log files. |
| `shutdown` | Take server down by executing the [SHUTDOWN](../shutdown/index) command on the server. If connected to a local server using a Unix socket file, mariadb-admin waits until the server's process ID file has been removed to ensure that the server has stopped properly. See also the `--wait-for-all-slaves` option. |
| `status` | Gives a short status message from the server. |
| `start-all-slaves` | Start all replicas. |
| `start-slave` | Start replication on a replica server. |
| `stop-all-slaves` | Stop all replicas. |
| `stop-slave` | Stop replication on a replica server. |
| `variables` | Prints variables available. |
| `version` | Returns version as well as status info from the server. |

 
The shutdown Command and the --wait-for-all-slaves Option
---------------------------------------------------------

 The `--wait-for-all-slaves` option was first added in [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/). When a primary server is shutdown and it goes through the normal shutdown process, the primary kills client threads in random order. By default, the primary also considers its binary log dump threads to be regular client threads. As a consequence, the binary log dump threads can be killed while client threads still exist, and this means that data can be written on the primary during a normal shutdown that won't be replicated. This is true even if [semi-synchronous replication](../semisynchronous-replication/index) is being used.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this problem can be solved by shutting down the server with the mariadb-admin utility and by providing the `--wait-for-all-slaves` option to the utility and by executing the `shutdown` command with the utility. For example:

 
```
mariadb-admin --wait-for-all-slaves shutdown

```

When the `--wait-for-all-slaves` option is provided, the server only kills its binary log dump threads after all client threads have been killed, and it only completes the shutdown after the last [binary log](../binary-log/index) has been sent to all connected replicas.

 See [Replication Threads: Binary Log Dump Threads and the Shutdown Process](../replication-threads/index#binary-log-dump-threads-and-the-shutdown-process) for more information.

 Examples
--------

 Quick check of what the server is doing:

 
```
shell> mariadb-admin status
Uptime: 8023 Threads: 1 Questions: 14 Slow queries: 0 Opens: 15 Flush tables: 1 Open tables: 8 Queries per second avg: 0.1
shell> mariadb-admin processlist
+----+-------+-----------+----+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------+-----------+----+---------+------+-------+------------------+
....
+----+-------+-----------+----+---------+------+-------+------------------+

```

More extensive information of what is happening 'just now' changing (great for troubleshooting a slow server):

 
```
shell> mariadb-admin --relative --sleep=1 extended-status | grep -v " 0 "

```

Check the variables for a running server:

 
```
shell> mariadb-admin variables | grep datadir
| datadir | /my/data/ |

```

Using a shortened prefix for the `version` command:

 
```
shell> mariadb-admin ver
mariadb-admin from 11.1.0-preview-MariaDB, client 9.1 for linux-systemd (x86_64)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Server version		11.1.0-preview-MariaDB
Protocol version	10
Connection		localhost via TCP/IP
TCP port		11100
Uptime:			3 min 21 sec

Threads: 1  Questions: 1  Slow queries: 0  Opens: 17  Open tables: 10  Queries per second avg: 0.004

```

### Other Ways To Stop mysqld (Unix)

 If you get the error:

 
```
mariadb-admin: shutdown failed; error: 'Access denied; you need (at least one of) the SHUTDOWN privilege(s) for this operation'

```

It means that you didn't use `mariadb-admin` with a user that has the SUPER or SHUTDOWN privilege.

 If you don't know the user password, you can still take the mysqld process down with a system `kill` command:

 
```
kill -SIGTERM pid-of-mysqld-process

```

The above is identical to `mariadb-admin shutdown`.

 On windows you should use:

 
```
NET STOP MySQL

```

You can use the [SHUTDOWN](../shutdown/index) command from any client.

 See Also
--------

 * [SHUTDOWN command](../shutdown/index)
* [mytop](http://www.mysqlfanboy.com/mytop-3/), a 'top' like program for MariaDB/MySQL that allows you to see what the server is doing. A mytop optimized for MariaDB is included in [MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-admin/>

mariadb-check
=============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-check` is a symlink to `mysqlcheck`, the tool for checking, repairing, analyzing and optimizing tables. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-check` is the name of the tool, with `mysqlcheck` a symlink .

 
 `mariadb-check` is a maintenance tool that allows you to check, repair, analyze and optimize multiple tables from the command line.

 It is essentially a commandline interface to the [CHECK TABLE](../check-table/index), [REPAIR TABLE](../repair-table/index), [ANALYZE TABLE](../analyze-table/index) and [OPTIMIZE TABLE](../optimize-table/index) commands, and so, unlike [myisamchk](../myisamchk/index) and [aria\_chk](../aria_chk/index), requires the server to be running.

 This tool does not work with partitioned tables.

 Using mariadb-check
-------------------

 
```
./client/mariadb-check [OPTIONS] database [tables]

```

OR

 
```
./client/mariadb-check [OPTIONS] --databases DB1 [DB2 DB3...]

```

OR

 
```
./client/mariadb-check [OPTIONS] --all-databases

```

`mariadb-check` can be used to CHECK (-c, -m, -C), REPAIR (-r), ANALYZE (-a), or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be used at the same time. Not all options are supported by all storage engines.

 The -c, -r, -a and -o options are exclusive to each other. 

 The option `--check` will be used by default, if no other options were specified. You can change the default behavior by making a symbolic link to the binary, or copying it somewhere with another name, the alternatives are:

 


|  |  |
| --- | --- |
| `mysqlrepair` | The default option will be `-r` (`--repair`) |
| `mysqlanalyze` | The default option will be `-a` (`--analyze`) |
| `mysqloptimize` | The default option will be `-o` (`--optimize`) |

 
### Options

 `mariadb-check` supports the following options:

 


| Option | Description |
| --- | --- |
| `-A`, `--all-databases` | Check all the databases. This is the same as `--databases` with all databases selected. |
| `-1`, `--all-in-1` | Instead of issuing one query for each table, use one query per database, naming all tables in the database in a comma-separated list. |
| `-a`, `--analyze` | Analyze given tables. |
| `--auto-repair` | If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked. |
| `--character-sets-dir=name` | Directory where [character set](../data-types-character-sets-and-collations/index) files are installed. |
| `-c`, `--check` | Check table for errors. |
| `-C`, `--check-only-changed` | Check only tables that have changed since last check or haven't been closed properly. |
| `-g`, `--check-upgrade` | Check tables for version-dependent changes. May be used with `--auto-repair` to correct tables requiring version-dependent updates. Automatically enables the `--fix-db-names` and `--fix-table-names` options. Used [when upgrading](../upgrading-to-mariadb-from-mysql/index) |
| `--compress` | Compress all information sent between the client and server if both support compression. |
| `-B`, `--databases` | Check several databases. Note that normally *mariadb-check* treats the first argument as a database name, and following arguments as table names. With this option, no tables are given, and all name arguments are regarded as database names. |
| `-#` , `--debug[=name]` | Output debug log. Often this is 'd:t:o,filename'. |
| `--debug-check` | Check memory and open file usage at exit. |
| `--debug-info` | Print some debug info at exit. |
| `--default-auth=plugin` | Default authentication client-side plugin to use. |
| `--default-character-set=name` | Set the default [character set](../data-types-character-sets-and-collations/index). |
| `-e`, `--extended` | If you are using this option with `--check`, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with `--repair`, it will force using the old, slow, repair with keycache method, instead of the much faster repair by sorting. |
| `-F`, `--fast` | Check only tables that haven't been closed properly. |
| `--fix-db-names` | Convert database names to the format used since MySQL 5.1. Only database names that contain special characters are affected. Used [when upgrading](../upgrading-to-mariadb-from-mysql/index) from an old MySQL version. |
| `--fix-table-names` | Convert table names (including [views](../views/index)) to the format used since MySQL 5.1. Only table names that contain special characters are affected. Used [when upgrading](../upgrading-to-mariadb-from-mysql/index) from an old MySQL version. |
| `--flush` | Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check. |
| `-f`, `--force` | Continue even if we get an SQL error. |
| `-?`, `--help` | Display this help message and exit. |
| `-h name`, `--host=name` | Connect to the given host. |
| `-m`, `--medium-check` | Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases. |
| `-o`, `--optimize` | Optimize tables. |
| `-p`, `--password[=name]` | Password to use when connecting to the server. If you use the short option form (`-p`), you cannot have a space between the option and the password. If you omit the password value following the `--password` or `-p` option on the command line, mariadb-check prompts for one. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `-Z`, `--persistent` | When using ANALYZE TABLE (`--analyze`), uses the PERSISTENT FOR ALL option, which forces [Engine-independent Statistics](../engine-independent-table-statistics/index) for this table to be updated. Added in [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/) |
| `-W`, `--pipe` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `--plugin-dir` | Directory for client-side plugins. |
| `-P num`, `--port=num` | 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). |
| `--process-tables` | Perform the requested operation (check, repair, analyze, optimize) on tables. Enabled by default. Use `--skip-process-tables` to disable. |
| `--process-views[=val]` | Perform the requested operation (only [CHECK VIEW](../check-view/index) or [REPAIR VIEW](../repair-view/index)). Possible values are NO, YES (correct the checksum, if necessary, add the mariadb-version field), UPGRADE\_FROM\_MYSQL (same as YES and toggle the algorithm MERGE<->TEMPTABLE. |
| `--protocol=name` | The connection protocol (tcp, socket, pipe, memory) to use for connecting to the server. Useful when other connection parameters would cause a protocol to be used other than the one you want. |
| `-q`, `--quick` | If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table. |
| `-r`, `--repair` | Can fix almost anything except unique keys that aren't unique. |
| `--shared-memory-base-name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. |
| `-s`, `--silent` | Print only error messages. |
| `--skip-database` | Don't process the database (case-sensitive) specified as argument. |
| `-S name`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `--tables` | Overrides the `--databases` or `-B` option such that all name arguments following the option are regarded as table names. |
| `--use-frm` | For repair operations on MyISAM tables, get table structure from .frm file, so the table can be repaired even if the .MYI header is corrupted. |
| `-u`, `--user=name` | User for login if not current user. |
| `-v`, `--verbose` | Print info about the various stages. You can give this option several times to get even more information. See [mariadb-check and verbose](#mariadb-check-and-verbose), below. |
| `-V`, `--version` | Output version information and exit. |
| `--write-binlog` | Write ANALYZE, OPTIMIZE and REPAIR TABLE commands to the [binary log](../binary-log/index). Enabled by default; use `--skip-write-binlog` when commands should not be sent to replication slaves. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-check` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-check` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
`mariadb-check` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-check` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqlcheck]` |  Options read by `mysqlcheck`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-check]` | Options read by `mariadb-check`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
Notes
-----

 ### Default Values

 To see the default values for the options and also to see the arguments you get from configuration files you can do:

 
```
./client/mariadb-check --print-defaults
./client/mariadb-check --help

```

### mariadb-check and auto-repair

 When running `mariadb-check` with `--auto-repair` (as done by [mariadb-upgrade](../mariadb-upgrade/index)), `mariadb-check` will first check all tables and then in a separate phase repair those that failed the check.

 ### mariadb-check and all-databases

 `mariadb-check --all-databases` will ignore the internal log tables [general\_log](../mysqlgeneral_log-table/index) and [slow\_log](../mysqlslow_log-table/index) as these can't be checked, repaired or optimized.

 ### mariadb-check and verbose

 Using one `--verbose` option will give you more information about what mariadb-check is doing.

 Using two `--verbose` options will also give you connection information.

 If you use three `--verbose` options you will also get, on stdout, all [ALTER](../alter-table/index), [RENAME](../rename-table/index), and [CHECK](../check-table/index) commands that mariadb-check executes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-check/>

mariadb-conv
============

    
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`mariadb-conv` is a character set conversion utility for MariaDB and was added in [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

  Usage
-----

 
```
mariadb-conv [OPTION...] [FILE...]

```

Options
-------

 `mariadb-conv` supports the following options:

 


| Option | Description |
| --- | --- |
| -f, --from=name | Specifies the encoding of the input. |
| -t, --to=name | Specifies the encoding of the output. |
| -c, --continue | Silently ignore conversion errors. |
| --delimiter=name | Treat the specified characters as delimiters. |

 
By default, `mariadb-conv` exits whenever it encounters any conversion problems, for example:

 * the input byte sequence is not valid in the source character set
* the character cannot be converted to the target character set

 The `-c` option makes `mariadb-conv` ignore such errors and use the question mark '?' to replace bytes in bad input sequences, or unconvertable characters.

 The `--delimiter=...` option makes `mariadb-conv` treat the specified characters as delimiters rather than data to convert, so the input is treated as a combination of:

 * data chunks, which are converted according to the `-f` and `-t` options.
* delimiters, which are not converted and are copied from the input to the output as is.

 Examples
--------

 Converts the file `file.latin1.txt` from `latin1` to `utf8`. 

 
```
mariadb-conv -f latin1 -t utf8 file.latin1.txt

```

Convert the file `file.latin1.txt` from `latin1` to `utf8`, reading the input data from stdin.

 
```
mariadb-conv -f latin1 -t utf8 < file.latin1.txt

```

Using mariadb-conv in a pipe:

 
```
echo test | ./mariadb-conv -f utf8 -t ucs2 >file.ucs2.txt

```

As a side effect, mariadb-conv can be used to list MariaDB data directories in a human readable form. Suppose you create the following tables:

 
```
SET NAMES utf8;
CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE ß (a INT);
CREATE OR REPLACE TABLE абв (a INT);
CREATE OR REPLACE TABLE 桌子 (a INT);

```

The above makes the server create the following files in the MariaDB data directory:

 
```
@1j.frm
@1j.ibd
@684c@5b50.frm
@684c@5b50.ibd
@g0@h0@i0.frm
@g0@h0@i0.ibd
t1.frm
t1.ibd

```

It's not precisely clear which file stores which table, because MariaDB uses a special table-name-to-file-name encoding.

 This command on Linux (assuming an utf-8 console) can print the table list in a readable way::

 
```
ls | mariadb-conv -f filename -t utf8 --delimiter=".\n"

ß.frm
ß.ibd
桌子.frm
桌子.ibd
абв.frm
абв.ibd
t1.frm
t1.ibd

```

Note, the `--delimiter=".\n"` option is needed to make `mariadb-conv` treat the dot character (delimiting the encoded table name from the file extension) and the new line character (delimiting separate lines) as delimiters rather than as the data to convert (otherwise the conversion would fail).

 Windows users can use the following command to list the data directory in the ANSI text console:

 
```
dir /b | mariadb-conv -c -f filename -t cp850 --delimiter=".\r\n"

```

Note:

 * The `-t` options assume a Western machine.
* The `-c` option is needed to ignore conversion errors for Cyrillic and CJK characters.
* `--delimiter=` additionally needs the carriage return character \r

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-conv/>

mariadb-convert-table-format
============================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-convert-table-format` is a symlink to `mysql_convert_table_format`, the tool for converting the tables in a database to use a particular storage engine. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-convert-table-format` is the name of the tool, with `mysql_convert_table_format` a symlink .

 
Usage
-----

 
```
mariadb-convert-table-format [options] db_name

```
 Description
-----------

 `mariadb-convert-table-format` converts the tables in a database to use a particular storage engine ([MyISAM](../myisam/index) by default).

 `mariadb-convert-table-format` is written in Perl and requires that the DBI and DBD::mysql Perl modules be installed

 Invoke `mariadb-convert-table-format` like this:

 
```
shell> mariadb-convert-table-format [options]db_name

```

The `db_name` argument indicates the database containing the tables to be converted.

 Options
-------

 `mariadb-convert-table-format` supports the options described in the following list:

 


| Option | Description |
| --- | --- |
| -?, --help | Display help and exit. |
| -e, --engine=ENGINE | Specify the storage engine that the tables should be converted to use. The default is [MyISAM](../myisam/index) if this option is not given. |
| -f, --force | Continue even if errors occur. |
| -h, --host=host\_name | Connect to the MariaDB server on the given host. Default localhost. |
| -p, --password=password | The password to use when connecting to the server. Note that the password value is not optional for this option, unlike for other client programs. Specifying the password on the command-line is generally considered insecure. |
| -P, --port=port\_num | The TCP/IP port number to use for the connection. |
| -S, --socket=path | For connections to localhost, the Unix socket file to use. |
| -u, --user=user\_name | The MariaDB user name to use when connecting to the server. |
| -v, --verbose | Verbose mode. Print more information about what the program does. |
| -V, --version | Display version information and exit. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-convert-table-format/>

mariadb-dumpslow
================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-dumpslow` is a symlink to `mysqldumpslow`, the tool for examining the [slow query log](../slow-query-log/index). 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-dumpslow` is the name of the tool, with `mysqldumpslow` a symlink .

 
`mariadb-dumpslow` is a tool to examine the [slow query log](../slow-query-log/index).

 It parses the slow query log files, printing a summary result. Normally, mariadb-dumpslow groups queries that are similar except for the particular values of number and string data values. It “abstracts” these values to N and ´S´ when displaying summary output. The `-a` and `-n` options can be used to modify value abstracting behavior.

 Usage
-----

 
```
mariadb-dumpslow [ options... ] [ logs... ]

```

Options
-------

 


| Option | Description |
| --- | --- |
| `-a` | Don't abstract all numbers to N and strings to 'S' |
| `-d`, `--debug` | Debug |
| `-g PATTERN` | Grep: only consider statements that include this string |
| `--help` | Display help |
| `-h HOSTNAME` | Hostname of db server for \*-slow.log filename (can be wildcard), default is '\*', i.e. match all |
| `-i NAME` | Name of server instance (if using mysql.server startup script) |
| `-l` | Don't subtract lock time from total time |
| `-n NUM` | Abstract numbers with at least *NUM* digits within names |
| `-r` | Reverse the sort order (largest last instead of first) |
| `-s ORDER` | What to sort by (aa, ae, al, ar, at, a, c, e, l, r, t). `at` is default. `aa` average rows affected `ae` aggregated number of rows examined `al` average lock time `ar` average rows sent `at` average query time `a` rows affected `c` count `e` rows examined `l` lock time `r` rows sent `t` query time |
| `-t NUM` | Just show the top *NUM* queries. |
| `-v`, `--verbose` | Verbose mode. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-dumpslow/>

mariadb-embedded
================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-embedded` is a symlink to `mysql_embedded`, the embedded server. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-embedded` is the name of the tool, with `mysql_embedded` a symlink.

 
`mariadb-embedded` is a [mariadb client](../mariadb-command-line-client/index) statically linked to libmariadbd, the embedded server. Upon execution, an embedded MariaDB server is instantiated and you can execute statements just as you would using the normal mariadb client, using the same options.

 
Do not run *mariadb-embedded* while MariaDB is running, as effectively it starts a new instance of the server.

 
Examples
--------

 
```
sudo mariadb-embedded -e 'select user, host, password from mysql.user where user="root"'
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | db1       | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | 127.0.0.1 | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | ::1       | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
+------+-----------+-------------------------------------------+

```

Sending options with `--server-arg`:

 
```
sudo mariadb-embedded --server-arg='--skip-innodb'
  --server-arg='--default-storage-engine=myisam' 
  --server-arg='--log-error=/tmp/mysql.err' 
  -e 'select user, host, password from mysql.user where user="root"'
+------+-----------+-------------------------------------------+
| user | host      | password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | db1       | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | 127.0.0.1 | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
| root | ::1       | *196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7 |
+------+-----------+-------------------------------------------+

```

See Also
--------

 * [Using mysql\_embedded and mysqld --bootstrap to tinker with privilege tables](using_mysql_embedded_and_mysqld_--bootstrap_to_tinker_with_privilege_tables)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-embedded/>

mariadb-fix-extensions
======================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-fix-extensions` is a symlink to `mysql_fix_extensions`, the tool for converting the extensions for [MyISAM](../myisam/index) (or ISAM) table files to their canonical forms.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_fix_extensions` is the symlink, and `mariadb-fix-extensions` the binary name.

 
`mariadb-fix-extensions` converts the extensions for [MyISAM](../myisam/index) (or ISAM) table files to their canonical forms.

 It looks for files with extensions matching any lettercase variant of `.frm`, `.myd`, `.myi`, `.isd`, and `.ism` and renames them to have extensions of `.frm`, `.MYD`, `.MYI`, `.ISD`, and `.ISM`, respectively. This can be useful after transferring the files from a system with case-insensitive file names (such as Windows) to a system with case-sensitive file names.

 Invoke mariadb-fix-extensions as follows, where data\_dir is the path name to the MariaDB data directory.

 
```
mariadb-fix-extensions data_dir

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-fix-extensions/>

mariadb-find-rows
=================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-find-rows` is a symlink to `mysql_find_rows`, the tool for reading files containing SQL statements and extracting statements that match a given regular expression or that contain [USE db\_name](../use/index) or [SET](../set/index) statements. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-find-rows` is the name of the tool, with `mysql_find_rows` a symlink .

 
 `mariadb-find-rows` reads files containing SQL statements and extracts statements that match a given regular expression or that contain [USE db\_name](../use/index) or [SET](../set/index) statements. The utility was written for use with update log files (as used prior to MySQL 5.0) and as such expects statements to be terminated with semicolon (;) characters. It may be useful with other files that contain SQL statements as long as statements are terminated with semicolons.

 Usage
-----

 
```
mariadb-find-rows [options] [file_name ...]

```

Each file\_name argument should be the name of file containing SQL statements. If no file names are given, *mariadb-find-rows* reads the standard input.

 Options
-------

 mariadb-find-rows supports the following options:

 


| Option | Description |
| --- | --- |
| `--help`, `--Information` | Display help and exit. |
| `--regexp=pattern` | Display queries that match the pattern. |
| `--rows=N` | Quit after displaying N queries. |
| `--skip-use-db` | Do not include [USE db\_name](../use/index) statements in the output. |
| `--start_row=N` | Start output from this row (first row is 1). |

 
Examples
--------

 
```
mariadb-find-rows --regexp=problem_table --rows=20 < update.log
mariadb-find-rows --regexp=problem_table  update-log.1 update-log.2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-find-rows/>

ABS
===

    Syntax
------

 
```
ABS(X)

```
 Description
-----------

 Returns the absolute (non-negative) value of `X`. If `X` is not a number, it is converted to a numeric type.

 Examples
--------

 
```
SELECT ABS(42);
+---------+
| ABS(42) |
+---------+
|      42 |
+---------+

SELECT ABS(-42);
+----------+
| ABS(-42) |
+----------+
|       42 |
+----------+

SELECT ABS(DATE '1994-01-01');
+------------------------+
| ABS(DATE '1994-01-01') |
+------------------------+
|               19940101 |
+------------------------+

```

See Also
--------

 * [SIGN()](../sign/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/abs/>

mariadb-setpermission
=====================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-setpermission` is a symlink to `mysql_setpermission`, the script for assisting with adding users or databases or changing passwords in MariaDB.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_setpermission` is the symlink, and `mariadb-setpermission` the binary name.

  Syntax
------

 
```
mariadb-setpermission [options]

```

Description
-----------

 *mariadb-setpermission* is a Perl script that was originally written and contributed by Luuk de Boer. It requires the DBI and DBD::mysql Perl modules to be installed. *mariadb-setpermission* can help you add users or databases or change passwords in MariaDB. 

 It interactively sets permissions in the MariaDB grant tables, but does not check permissions which have already been set in MariaDB. So if you can't connect to MariaDB using the permission you just added, take a look at the permissions which have already been set in MariaDB.

 The account used when you connect determines which permissions you have when attempting to modify existing permissions in the grant tables.

 *mariadb-setpermission* also reads options from the [client] and [perl] groups in the .my.cnf file in your home directory, if the file exists.

 The following options are available:

 Options
-------

 

| Option | Description |
| --- | --- |

 


|  |  |
| --- | --- |
| `--help` | Display a help message and exit. |
| `--host=host_name` | Connect to the MariaDB server on the given host. |
| `--password=password` | The password to use when connecting to the server. Note that the password value is not optional for this option, unlike for other MariaDB programs **Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line.** |
| `--port=port_num` | The TCP/IP port number to use for the connection. |
| `--socket=path` | For connections to localhost, the Unix socket file to use. |
| `--user=user_name` | The MariaDB user name to use when connecting to the server. |

 
Example
-------

 
```
./mariadb-setpermission --user=msandbox --password=msandbox --host=127.0.0.1 --port=11200
######################################################################
## Welcome to the permission setter 1.4 for MariaDB.
## made by Luuk de Boer
######################################################################
What would you like to do:
  1. Set password for an existing user.
  2. Create a database + user privilege for that database
     and host combination (user can only do SELECT)
  3. Create/append user privilege for an existing database
     and host combination (user can only do SELECT)
  4. Create/append broader user privileges for an existing
     database and host combination
     (user can do SELECT,INSERT,UPDATE,DELETE)
  5. Create/append quite extended user privileges for an
     existing database and host combination (user can do
     SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,
     LOCK TABLES,CREATE TEMPORARY TABLES)
  6. Create/append full privileges for an existing database
     and host combination (user has FULL privilege)
  7. Remove all privileges for for an existing database and
     host combination.
     (user will have all permission fields set to N)
  0. exit this program

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-setpermission/>

User-Defined Functions Calling Sequences
========================================

    The functions described in [Creating User-defined Functions](../creating-user-defined-functions/index) are expanded on this page. They are declared as follows:

 Simple Functions
----------------

 ### x()

 If x() returns an integer, it is declared as follows:

 
```
long long x(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);

```

If x() returns a string (DECIMAL functions also return string values), it is declared as follows:

 
```
char *x(UDF_INIT *initid, UDF_ARGS *args,
          char *result, unsigned long *length,
          char *is_null, char *error);

```

If x() returns a real, it is declared as follows:

 
```
double x(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);

```

### x\_init()

 
```
my_bool x_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

```

### x\_deinit()

 
```
void x_deinit(UDF_INIT *initid);

```

### Description

 *initid* is a parameter passed to all three functions that points to a *UDF\_INIT* structure, used for communicating information between the functions. Its structure members are:

 * my\_bool maybe\_null
	+ *maybe\_null* should be set to *1* if x\_init can return a NULL value, Defaults to *1* if any arguments are declared *maybe\_null*.
* unsigned int decimals
	+ Number of decimals after the decimal point. The default, if an explicit number of decimals is passed in the arguments to the main function, is the maximum number of decimals, so if *9.5*, *9.55* and *9.555* are passed to the function, the default would be three (based on *9.555*, the maximum). If there are no explicit number of decimals, the default is set to 31, or one more than the maximum for the DOUBLE, FLOAT and DECIMAL types. This default can be changed in the function to suit the actual calculation.
* unsigned int max\_length
	+ Maximum length of the result. For integers, the default is 21. For strings, the length of the longest argument. For reals, the default is 13 plus the number of decimals indicated by *initid->decimals*. The length includes any signs or decimal points. Can also be set to 65KB or 16MB in order to return a BLOB. The memory remains unallocated, but this is used to decide on the data type to use if the data needs to be temporarily stored.
* char \*ptr
	+ A pointer for use as required by the function. Commonly, *initid->ptr* is used to communicate allocated memory, with *x\_init()* allocating the memory and assigning it to this pointer, *x()* using it, and *x\_deinit()* de-allocating it.
* my\_bool const\_item
	+ Should be set to *1* in *x\_init()* if *x()* always returns the same value, otherwise *0*.

 Aggregate Functions
-------------------

 ### x\_clear()

 *x\_clear()* is a required function for aggregate functions, and is declared as follows:

 
```
void x_clear(UDF_INIT *initid, char *is_null, char *error);

```

It is called when the summary results need to be reset, that is at the beginning of each new group. but also to reset the values when there were no matching rows.

 *is\_null* is set to point to CHAR(0) before calling x\_clear().

 In the case of an error, you can store the value to which the error argument points (a single-byte variable, not a string string buffer) in the variable.

 ### x\_reset()

 *x\_reset()* is declared as follows:

 
```
void x_reset(UDF_INIT *initid, UDF_ARGS *args,
               char *is_null, char *error);

```

It is called on finding the first row in a new group. Should reset the summary variables, and then use *UDF\_ARGS* as the first value in the group's internal summary value. The function is not required if the UDF interface uses *x\_clear()*.

 ### x\_add()

 *x\_add()* is declared as follows:

 
```
void x_add(UDF_INIT *initid, UDF_ARGS *args,
             char *is_null, char *error);

```

It is called for all rows belonging to the same group, and should be used to add the value in *UDF\_ARGS* to the internal summary variable.

 ### x\_remove()

 *x\_remove()* was added in [MariaDB 10.4](../what-is-mariadb-104/index) and is declared as follows (same as *x\_add()*):

 
```
void x_remove(UDF_INIT* initid, UDF_ARGS* args,
               char* is_null, char *error );

```

It adds more efficient support of aggregate UDFs as [window functions](../window-functions/index). *x\_remove()* should "subtract" the row (reverse *x\_add()*). In [MariaDB 10.4](../what-is-mariadb-104/index) aggregate UDFs will work as WINDOW functions without *x\_remove()* but it will not be so efficient.

 If *x\_remove()* supported (defined) detected automatically.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-defined-functions-calling-sequences/>

Creating User-Defined Functions
===============================

    [User-defined functions](../user-defined-functions/index) allow MariaDB to be extended with a new function that works like a native (built-in) MariaDB function such as [ABS()](../abs/index) or [CONCAT()](../concat/index). There are alternative ways to add a new function: writing a native function (which requires modifying and compiling the server source code), or writing a stored function.

 Statements making use of user-defined functions are not safe for replication.

 Functions are written in C or C++, and to make use of them, the operating system must support dynamic loading. 

 Each new SQL function requires corresponding functions written in C/C++. In the list below, at least the main function - x() - and one other, are required. *x* should be replaced by the name of the function you are creating.

 All functions need to be thread-safe, so not global or static variables that change can be allocated. Memory is allocated in *x\_init()/ and freed in* x\_deinit()*.* 

 Simple Functions
----------------

 ### x()

 Required for all UDFs; this is where the results are calculated.

 

| C/C++ type | SQL type |
| --- | --- |
| char \* | [STRING](../string-data-types/index) |
| long long | [INTEGER](../integer/index) |
| double | [REAL](../data-types-numeric-data-types/index) |

 DECIMAL functions return string values, and so should be written accordingly. It is not possible to create ROW functions.

 ### x\_init()

 Initialization function for x(). Can be used for the following:

 * Check the number of arguments to X() (the SQL equivalent).
* Verify the argument types, or to force arguments to be of a particular type after the function is called.
* Specify whether the result can be NULL.
* Specify the maximum result length.
* For REAL functions, specify the maximum number of decimals for the result.
* Allocate any required memory.

 ### x\_deinit()

 De-initialization function for x(). Used to de-allocate memory that was allocated in x\_init().

 ### Description

 Each time the SQL function *X()* is called:

 * MariaDB will first call the C/C++ initialization function, *x\_init()*, assuming it exists. All setup will be performed, and if it returns an error, the SQL statement is aborted and no further functions are called.
* If there is no *x\_init()* function, or it has been called and did not return an error, *x()* is then called once per row.
* After all rows have finished processing, *x\_deinit()* is called, if present, to clean up by de-allocating any memory that was allocated in *x\_init()*.
* See [User-defined Functions Calling Sequences](../user-defined-functions-calling-sequences/index) for more details on the functions.

 Aggregate Functions
-------------------

 The following functions are required for aggregate functions, such as [AVG()](../avg/index) and [SUM()](../sum/index). When using [CREATE FUNCTION](../create-function-udf/index), the [AGGREGATE](../create-function-udf/index#aggregate) keyword is required.

 ### x\_clear()

 Used to reset the current aggregate, but without inserting the argument as the initial aggregate value for the new group.

 ### x\_add()

 Used to add the argument to the current aggregate. 

 ### x\_remove()

 Starting from [MariaDB 10.4](../what-is-mariadb-104/index), improves the support of [window functions](../window-functions/index) (so it is not obligatory to add it) and should remove the argument from the current aggregate.

 ### Description

 Each time the aggregate SQL function *X()* is called:

 * MariaDB will first call the C/C++ initialization function, *x\_init()*, assuming it exists. All setup will be performed, and if it returns an error, the SQL statement is aborted and no further functions are called.
* If there is no *x\_init()* function, or it has been called and did not return an error, *x()* is then called once per row.
* After all rows have finished processing, *x\_deinit()* is called, if present, to clean up by de-allocating any memory that was allocated in *x\_init()*.

 * MariaDB will first call the C/C++ initialization function, *x\_init()*, assuming it exists. All setup will be performed, and if it returns an error, the SQL statement is aborted and no further functions are called.
* The table is sorted according to the [GROUP BY](../group-by/index) expression.
* *x\_clear()* is called for the first row of each new group.
* *x\_add()* is called once per row for each row in the same group.
* *x()* is called when the group changes, or after the last row, to get the aggregate result.
* The latter three steps are repeated until all rows have been processed.
* After all rows have finished processing, *x\_deinit()* is called, if present, to clean up by de-allocating any memory that was allocated in *x\_init()*.

 Examples
--------

 For an example, see `sql/udf_example.cc` in the source tree. For a collection of existing UDFs see <https://github.com/mysqludf>.

 See Also
--------

 * [Stored Functions](../stored-functions/index)
* [Stored Aggregate Functions](../stored-aggregate-functions/index)
* [User-defined Functions Calling Sequences](../user-defined-functions-calling-sequences/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-user-defined-functions/>

mariadb-tzinfo-to-sql
=====================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-tzinfo-to-sql` is a symlink to `mysql_tzinfo_to_sql`, the tool for loading [time zones](../time-zones/index) on systems that have a zoneinfo database.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_tzinfo_to_sql` is the symlink, and `mariadb-tzinfo-to-sql` the binary name.

 
`mariadb-tzinfo-to-sql` is a utility used to load [time zones](../time-zones/index) on systems that have a zoneinfo database to load the time zone tables ([time\_zone](../mysqltime_zone-table/index), [time\_zone\_leap\_second](../mysqltime_zone_leap_second-table/index), [time\_zone\_name](../mysqltime_zone_name-table/index), [time\_zone\_transition](../mysqltime_zone_transition-table/index) and [time\_zone\_transition\_type](../mysqltime_zone_transition_type-table/index)) into the mysql database.

 Most Linux, Mac OS X, FreeBSD and Solaris systems will have a zoneinfo database - Windows does not. The database is commonly found in the /usr/share/zoneinfo directory, or, on Solaris, the /usr/share/lib/zoneinfo directory. 

 Usage
-----

 `mariadb-tzinfo-to-sql` can be called in several ways. The output is usually passed straight to the [mariadb client](../mariadb-client/index) for direct loading in the mysql database.

 
```
shell> mariadb-tzinfo-to-sql timezone_dir
shell> mariadb-tzinfo-to-sql timezone_file timezone_name
shell> mariadb-tzinfo-to-sql --leap timezone_file

```

Examples
--------

 Most commonly, the whole directory is passed:

 
```
shell>mariadb-tzinfo-to-sql /usr/share/zoneinfo | mariadb -u root mysql

```

Load a single time zone file, `timezone_file`, corresponding to the time zone called `timezone_name`.

 
```
shell> mariadb-tzinfo-to-sql timezone_file timezone_name | mariadb -u root mysql

```

A separate command for each time zone and time zone file the server needs is required.

 To account for leap seconds, use:

 
```
shell> mariadb-tzinfo-to-sql --leap timezone_file | mariadb -u root mysql

```

After populating the time zone tables, you should usually restart the server so that the new time zone data is correctly loaded.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-tzinfo-to-sql/>

User-Defined Functions Security
===============================

    The MariaDB server imposes a number of limitations on [user-defined functions](../user-defined-functions/index) for security purposes.

 * The INSERT privilege for the mysql database is required to run [CREATE FUNCTION](../create-function-udf/index), as a record will be added to the [mysql.func-table](../mysqlfunc-table/index).
* The DELETE privilege for the mysql database is required to run [DROP FUNCTION](../drop-function-udf/index) as the corresponding record will be removed from the [mysql.func-table](../mysqlfunc-table/index).
* UDF object files can only be placed in the plugin directory, as specified by the value of the [plugin\_dir](../server-system-variables/index#plugin_dir) system variable.
* At least one symbol, beyond the required *x()* - corresponding to an SQL function *X())* - is required. These can be *x\_init()*, *x\_deinit()*, *xxx\_reset()*, *x\_clear()* and *x\_add()* functions (see [Creating User-defined Functions](../creating-user-defined-functions/index)). The [allow-suspicious-udfs](../mysqld-options/index#-allow-suspicious-udfs) mysqld option (by default unset) provides a workaround, permitting only one symbol to be used. This is not recommended, as it opens the possibility of loading shared objects that are not legitimate user-defined functions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-defined-functions-security/>

CONCAT
======

    Syntax
------

 
```
CONCAT(str1,str2,...)

```
 Description
-----------

 Returns the string that results from concatenating the arguments. May have one or more arguments. If all arguments are non-binary strings, the result is a non-binary string. If the arguments include any binary strings, the result is a binary string. A numeric argument is converted to its equivalent binary string form; if you want to avoid that, you can use an explicit type cast, as in this example:

 
```
SELECT CONCAT(CAST(int_col AS CHAR), char_col);

```

`CONCAT()` returns `NULL` if any argument is `NULL`.

 A `NULL` parameter hides all information contained in other parameters from the result. Sometimes this is not desirable; to avoid this, you can:

 * Use the `[CONCAT\_WS()](../concat_ws/index)` function with an empty separator, because that function is `NULL`-safe.
* Use `[IFNULL()](../ifnull/index)` to turn NULLs into empty strings.

 ### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#null-handling), `CONCAT` ignores [NULL](null).

 
Examples
--------

 
```
SELECT CONCAT('Ma', 'ria', 'DB');
+---------------------------+
| CONCAT('Ma', 'ria', 'DB') |
+---------------------------+
| MariaDB                   |
+---------------------------+

SELECT CONCAT('Ma', 'ria', NULL, 'DB');
+---------------------------------+
| CONCAT('Ma', 'ria', NULL, 'DB') |
+---------------------------------+
| NULL                            |
+---------------------------------+

SELECT CONCAT(42.0);
+--------------+
| CONCAT(42.0) |
+--------------+
| 42.0         |
+--------------+

```

Using `IFNULL()` to handle NULLs:

 
```
SELECT CONCAT('The value of @v is: ', IFNULL(@v, ''));
+------------------------------------------------+
| CONCAT('The value of @v is: ', IFNULL(@v, '')) |
+------------------------------------------------+
| The value of @v is:                            |
+------------------------------------------------+

```

In [Oracle mode](../sql_modeoracle-from-mariadb-103/index#null-handling), from [MariaDB 10.3](../what-is-mariadb-103/index):

 
```
SELECT CONCAT('Ma', 'ria', NULL, 'DB');
+---------------------------------+
| CONCAT('Ma', 'ria', NULL, 'DB') |
+---------------------------------+
| MariaDB                         |
+---------------------------------+

```

See Also
--------

 * [GROUP\_CONCAT()](../group_concat/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/concat/>

mariadb-secure-installation
===========================

    
Note that many of the reasons for the existence of this script no longer apply (and therefore the guidelines in many online tutorials. In particular, from [MariaDB 10.4](../what-is-mariadb-104/index), [Unix socket authentication](../authentication-plugin-unix-socket/index) is applied by default, and there is usually no need to create a root password. See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index).

 

**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-secure-installation` is a symlink to [mysql\_secure\_installation](../mysql_secure_installation/index), the script for enabling you to improve the security of your MariaDB installation.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_secure_installation` is the symlink, and `mariadb-secure-installation` the binary name.

  Description
-----------

 `mariadb-secure-installation` is a shell script available on Unix systems, and enables you to improve the security of your MariaDB installation in the following ways:

 * You can set a password for root accounts.
* You can remove root accounts that are accessible from outside the local host.
* You can remove anonymous-user accounts.
* You can remove the test database, which by default can be accessed by anonymous users.

 `mariadb-secure-installation` can be invoked without arguments:

 
```
shell> mariadb-secure-installation
```

The script will prompt you to determine which actions to perform.

 
```
Example:
localhost:# mariadb-secure-installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!
In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none): 
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.
You already have a root password set, so you can safely answer 'n'.
Change the root password? [Y/n] n
 ... skipping.
By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n] y
 ... Success!
Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] y
 ... Success!
By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n] y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n] y
 ... Success!
Cleaning up...
All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.
Thanks for using MariaDB!
```

### Options

 `mariadb-secure-installation` accepts some options:

 


| Option | Description |
| --- | --- |
| `--basedir=dir` | Base directory. |
| `--no-defaults` | Don't read default options from any option file. |
| `--defaults-file=#`  | Only read default options from the given file #. |
| `--defaults-extra-file=#`  | Read this file after the global files are read. |

 
Other unrecognized options will be passed on to the server.

 ### Option Files

 In addition to reading options from the command-line, `mariadb-secure-installation` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-secure-installation` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
#### Option Groups

 `mariadb-secure-installation` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
### Use With Galera Cluster

 This script is not 100% safe for use with [Galera Cluster](../galera/index) as it directly manipulates the [mysql.user](../mysqluser-table/index)/[mysql.global\_priv](../mysqlglobal_priv-table/index) table, which is not transported by Galera to the other nodes.

 You should run this script on the first node in the cluster before adding more nodes.

 If you want to run this after the cluster is up and running you should find alternative ways.

 Anyone can vote for this to be fixed at <https://jira.mariadb.org/browse/MDEV-10112>.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-secure-installation/>

mariadb-upgrade
===============

    `mariadb-upgrade` is a tool that checks and updates your tables to the latest version.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-upgrade` is a symlink to `mysql_upgrade`, the tool that checks and updates your tables to the latest version.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_upgrade` is the symlink, and `mariadb-upgrade` the binary name.

 

**MariaDB starting with [10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/)**Starting from `mysql_upgrade` / `mariadb-upgrade` 2.0, the user running the upgrade tool must have write access to `datadir/mysql_upgrade_info`, so that the tool can write the current MariaDB version into the file. `mysql-upgrade` was updated in [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10333-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10423-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/) and newer.

  You should run `mariadb-upgrade` after upgrading from one major MySQL/MariaDB release to another, such as [from MySQL 5.0 to MariaDB 10.4](../upgrading-to-mariadb-from-mysql/index) or [MariaDB 10.4](../what-is-mariadb-104/index) to [MariaDB 10.5](../what-is-mariadb-105/index). You also have to use `mariadb-upgrade` after a direct "horizontal" migration, for example from MySQL 5.5.40 to [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5540-release-notes/). It's also safe to run `mariadb-upgrade` for minor upgrades, as if there are no incompatibilities nothing is changed.

 It needs to be run as a user with write access to the data directory.

 `mariadb-upgrade` is run after starting the new MariaDB server. Running it before you shut down the old version will not hurt anything and will allow you to make sure it works and figure out authentication for it ahead of time.

 It is recommended to make a [backup](../backing-up-and-restoring/index) of all the databases before running `mariadb-upgrade`.

 In most cases, `mariadb-upgrade` should just take a few seconds. The main work of `mariadb-upgrade` is to:

 * Update the system tables in the `mysql` database to the latest version (normally just add new fields to a few tables).
* Check that all tables are up to date (runs [CHECK TABLE table\_name FOR UPGRADE](../sql-commands-check-table/index)). For tables that are not up to date, runs [ALTER TABLE table\_name FORCE](../alter-table/index) on the table to update it. A table is not up to date if:
	+ The table uses an index for which there has been a [collation](../character-sets/index) change (rare)
	+ A format change in the storage engine requires an update (very rare)

 Using mariadb-upgrade
---------------------

 
```
mariadb-upgrade [--force] [--user=# --password=# 
  --host=hostname --port=# --socket=#
  --protocol=tcp|socket|pipe|memory 
  --verbose] [OTHER_OPTIONS]

```

`mariadb-upgrade` is mainly a framework to call [mariadb-check](../mariadb-check/index). `mariadb-upgrade` works by doing the following operations:

 
```
# Find out path to datadir
echo "show show variables like 'datadir'" | mysql
mariadb-check --no-defaults --check-upgrade --auto-repair --databases mysql
mysql_fix_privilege_tables
mariadb-check --no-defaults --all-databases --fix-db-names --fix-table-names
mariadb-check --no-defaults --check-upgrade --all-databases --auto-repair

```

The connect options given to `mariadb-upgrade` are passed along to [mariadb-check](../mariadb-check/index) and [mysql](../mysql-command-line-client/index).

 The `mysql_fix_privilege_tables` script is not actually called; it's included as part of `mariadb-upgrade`

 If you have a problem with `mariadb-upgrade` try run it in very verbose mode:

 
```
mariadb-upgrade --verbose --verbose other-options

```

`mariadb-upgrade` also saves the MariaDB version number in a file named `mysql_upgrade_info` in the [data directory](../server-system-variables/index#datadir). This is used to quickly check whether all tables have been checked for this release so that table-checking can be skipped. For this reason, `mariadb-upgrade` needs to be run as a user with write access to the data directory. To ignore this file and perform the check regardless, use the `--force` option.

 ### Options

 `mariadb-upgrade` supports the following options:

 


| Option | Description | Version |
| --- | --- | --- |
| `-?`, `--help` | Display this help message and exit. |  |
| `--basedir=path` | Old option accepted for backward compatibility but ignored. |  |
| `--character-sets-dir=path` | Old option accepted for backward compatibility but ignored. |  |
| `check-if-upgrade-is-needed` | Do a quick check if upgrade is needed. Returns 0 if yes, 1 if no. | 2.0 |
| `--compress=name` | Old option accepted for backward compatibility but ignored. |  |
| `--datadir=name` | Old option accepted for backward compatibility but ignored. |  |
| `-# [name]`, `--debug[=name]` | For debug builds, output debug log. |  |
| `--debug-check` | Check memory and open file usage at exit. |  |
| `-T`, `--debug-info` | Print some debug info at exit. |  |
| `--default-character-set=name` | Old option accepted for backward compatibility but ignored. |  |
| `-f`, `--force` | Force execution of mariadb-check even if `mariadb-upgrade` has already been executed for the current version of MariaDB. Ignores `mysql_upgrade_info`. |  |
| `-h`, `--host=name` | Connect to MariaDB on the given host. |  |
| `-p`, `--password[=name]` | Password to use when connecting to server. If password is not given, it's solicited on the command line (which should be considered insecure). You can use an option file to avoid giving the password on the command line. |  |
| `-P`, `--port=name` | Port number to use for connection or 0 for default to, in order of preference, my.cnf, the MYSQL\_TCP\_PORT [environment variable](../mariadb-environment-variables/index), /etc/services, built-in default (3306). |  |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |  |
| `--silent` | Print less information. |  |
| `-S`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |  |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |  |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |  |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |  |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |  |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |  |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |  |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |  |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |  |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |  |
| `-t`, `--tmpdir=name` | Directory for temporary files. |  |
| `-s`, `--upgrade-system-tables` | Only upgrade the system tables in the mysql database. Tables in other databases are not checked or touched. |  |
| `-u`, `--user=name` | User for login if not current user. |  |
| `-v`, `--verbose` | Display more output about the process, using it twice will print connection arguments; using it 3 times will print out all [CHECK](../check-table/index), [RENAME](../rename-table/index) and [ALTER TABLE](../alter-table/index) commands used during the check phase; using it 4 times will also write out all [mariadb-check](../mariadb-check/index) commands used. |  |
| `-V`, `--version` | Output version information and exit. |  |
| `-k`, `--version-check` | Run this program only if its 'server version' matches the version of the server to which it's connecting check. Note: the 'server version' of the program is the version of the MariaDB server with which it was built/distributed. (Defaults to on; use `--skip-version-check` to disable.) |  |
| `--write-binlog` | All commands including those run by [mariadb-check](../mariadb-check/index) are written to the [binary log](../binary-log/index). Disabled by default. Before [MariaDB 10.0.6](https://mariadb.com/kb/en/mariadb-1006-release-notes/) and [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/), this was enabled by default, and `--skip-write-binlog` should be used when commands should not be sent to replication slaves. |  |

 
mariadb-upgrade 2.0
-------------------

 `mariadb-upgrate/mysql_upgrade 2.0` was introduced in [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10333-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10423-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/).

 Previously the tool first ran the upgrade process and then created the `datadir/mysql_upgrade_info` file. If the file could not be created because of permissions (`mariadb-upgrade` did not have rights to create the file), `mariadb-upgrad` gave an error, but this was often ignored. One effect of not being able to create the `mysql_upgrade_info` file was that every new `mariadb-upgrade` run would have to do a full upgrade check, which can take a while if there are a lot of tables.

 `mariadb-upgrade` 2.0 fixes the following issues:

 * The `datadir/mysql_upgrade_info` is now created at the start of the upgrade process and locked. This ensures that two `mariadb-upgrade` processes cannot be run in parallel, which can cause deadlocks ([MDEV-27068](https://jira.mariadb.org/browse/MDEV-27068)). One side-effect of this is that `mariadb-upgrade` has to have write access to `datadir`, which means it has to be run as as the user that installed MariaDB, normally 'mysql' or 'root' .
* One can use `mariadb-upgrade --force --force` to force the upgrade to be run, even if there was no version change or if one doesn't have write access to `datadir`. Note that if this option is used, the next `mariadb-upgrade` run will assume that there is a major version change and the upgrade must be done (again).
* The upgrade will only be done if there is a major server version change (10.4.X -> 10.5.X). This will avoid unnecessary upgrades.
* New option added: `--check-if-upgrade-is-needed`. If this is used, `mariadb-upgrade` will return 0 if there has been a major version change and one should run `mariadb-upgrade`. If not upgrade is need, 1 will be returned.
* `--verbose` writes more information, including from which version to which version the upgrade will be done.
* Better messages when there is no need to run `mariadb-upgrade`.

 ### Option Files

 In addition to reading options from the command-line, `mariadb-upgrade` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-upgrade` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
In [MariaDB 10.2](../what-is-mariadb-102/index) and later, `mariadb-upgrade` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-upgrade` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysql_upgrade]` |  Options read by `mariadb-upgrade`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-upgrade]` | Options read by `mariadb-upgrade`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
Differences Between mysql\_upgrade in MariaDB and MySQL
-------------------------------------------------------

 This is as of [MariaDB 5.1.50](https://mariadb.com/kb/en/mariadb-5150-release-notes/):

 * MariaDB will convert long [table names](../identifier-names/index) properly.
* MariaDB will convert [InnoDB](../xtradb-and-innodb/index) tables (no need to do a dump/restore or `[ALTER TABLE](../alter-table/index)`).
* MariaDB will convert old archive tables to the new 5.1 format.
* "mysql\_upgrade --verbose" will run "mariadb-check --verbose" so that you get more information of what is happening. Running with 3 times --verbose will in [MariaDB 10.0](../what-is-mariadb-100/index) print out all CHECK, RENAME and ALTER TABLE commands executed.
* The [mysql.event table](../mysqlevent-table/index) is upgraded live; no need to restart the server to use events if the event table has changed ([MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) and [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).
* More descriptive output.

 Speeding Up mariadb-upgrade
---------------------------

 - If you are sure that all your tables are up to date with the current version, then you can run `mariadb-upgrade ---upgrade-system-tables`, which will only fix your system tables in the mysql database to be compatible with the latest version.

 The main reason to run `mariadb-upgrade` on all your tables is to allow it to check that:

 * There has not been any change in table formats between versions.
	+ This has not happened since [MariaDB 5.1](../what-is-mariadb-51/index).
* If some of the tables are using an index for which we have changed sort order.
	+ This has not happened since [MariaDB 5.5](../what-is-mariadb-55/index).

 If you are 100% sure this applies to you, you can just run `mariadb-upgrade` with the `---upgrade-system-tables` option.

 Symptoms of Not Having Run mariadb-upgrade When It Was Needed
-------------------------------------------------------------

 * Errors in the [error log](../error-log/index) that some system tables don't have all needed columns.
* Updates or searches may not find the record they are attempting to update or search for.
* [CHECKSUM TABLE](../checksum-table/index) may report the wrong checksum for [MyISAM](../myisam/index) or [Aria](../aria/index) tables.
* The error message "Cannot load from mysql.proc. The table is probably corrupted."

 To fix issues like this, run `mariadb-upgrade`, [mariadb-check](../mariadb-check/index), [CHECK TABLE](../sql-commands-check-table/index) and if needed [REPAIR TABLE](../repair-table/index) on the wrong table.

 Other Uses
----------

 * `mariadb-upgrade` will re-create any missing tables in the [mysql database](../the-mysql-database-tables/index). It will not touch any data in existing tables.

 See Also
--------

 * [mariadb-check](../mariadb-check/index)
* [CHECK TABLE](../sql-commands-check-table/index)
* [REPAIR TABLE](../repair-table/index)
* [Downgrading between Major Versions of MariaDB](../downgrading-between-major-versions-of-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-upgrade/>

mariadb-install-db
==================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-install-db` is a symlink to `mysql_install_db`. the tool for initializing the MariaDB data directory and creating the [system tables](../system-tables/index)

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_install_db` is the symlink, and `mariadb-install-db` the binary name.

 

**This page is for the `mariadb-install-db` script for Linux/Unix only**

 For the Windows specific tool of similar name and purpose see [mysql\_install\_db.exe](../mysql_install_dbexe/index).

 The Windows version shares the common theme (creating system tables), yet has a lot of functionality specific to Windows systems, for example creating a Windows service. The Windows version does \*not\* share command line parameters with the Unix shell script.

  `mariadb-install-db` initializes the MariaDB data directory and creates the [system tables](../system-tables/index) in the [mysql](../the-mysql-database-tables/index) database, if they do not exist. MariaDB uses these tables to manage [privileges](../grant/index#privilege-levels), [roles](../roles/index), and [plugins](../plugins/index). It also uses them to provide the data for the [help](../help-command/index) command in the [mariadb](../mariadb-command-line-client/index) client.

 `mariadb-install-db` works by starting MariaDB Server's `mysqld` process in [--bootstrap](../mysqld-options/index#-bootstrap) mode and sending commands to create the [system tables](../system-tables/index) and their content.

 Using mariadb-install-db
------------------------

 To invoke `mariadb-install-db`, use the following syntax:

 
```
$ mariadb-install-db [options]

```

Because the MariaDB server, `mysqld`, needs to access the data directory when it runs later, you should either run `mariadb-install-db` from the same account that will be used for running `mysqld` or run it as root and use the `--user` option to indicate the user name that `mysqld` will run as. It might be necessary to specify other options such as `--basedir` or `--datadir` if `mariadb-install-db` does not use the correct locations for the installation directory or data directory. For example:

 
```
$ scripts/mariadb-install-db --user=mysql \
   --basedir=/opt/mysql/mysql \
   --datadir=/opt/mysql/mysql/data

```

### Options

 `mariadb-install-db` supports the following options:

 


| Option | Description |
| --- | --- |
| `--auth-root-authentication-method={normal `|` socket}` | If set to `normal`, it creates a `root@localhost` account that authenticates with the `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` authentication plugin and that has no initial password set, which can be insecure. If set to `socket`, it creates a `root@localhost` account that authenticates with the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin. Set to `socket` by default from [MariaDB 10.4](../what-is-mariadb-104/index) (see [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)), or `normal` by default in earlier versions. Available since [MariaDB 10.1](../what-is-mariadb-101/index). |
| `--auth-root-socket-user=USER` | Used with `--auth-root-authentication-method=socket`. It specifies the name of the second account to create with `[SUPER](../grant/index#global-privileges)` privileges in addition to `root`, as well as of the system account allowed to access it. Defaults to the value of `--user`. |
| `--basedir=path` | The path to the MariaDB installation directory. |
| `--builddir=path` | If using `--srcdir` with out-of-directory builds, you will need to set this to the location of the build directory where built files reside. |
| `--catalogs=["list"]` |  Initialize MariaDB for [catalogs](../catalogs/index). Argument is a list, separated with space, of the catalogs to create. The def catalog is created automatically. Added in [MariaDB 11.3](../what-is-mariadb-113/index). |
| `--catalog-user=user` | User when adding [catalogs](../catalogs/index) to running server. Added in [MariaDB 11.3](../what-is-mariadb-113/index). |
| `--catalog-password[=password]` | Password for [catalog-user](../catalogs/index). Added in [MariaDB 11.3](../what-is-mariadb-113/index). |
| `--catalog-client-arg=arg` | Other arguments to 'mariadb' when adding new [catalogs](../catalogs/index). Added in [MariaDB 11.3](../what-is-mariadb-113/index). |
| `--cross-bootstrap` | For internal use. Used when building the MariaDB system tables on a different host than the target. |
| `--datadir=path`, `--ldata=path` | The path to the MariaDB data directory. |
| `--debug=path` | Write commands to-be executed in 'path'. Added in [MariaDB 11.3](../what-is-mariadb-113/index). |
| `--defaults-extra-file=name` | Read this file after the global files are read. Must be given as the first option. |
| `--defaults-file=name` | Only read default options from the given file *name* Must be given as the first option. |
| `--defaults-group-suffix=name` | In addition to the given groups, read also groups with this suffix. From [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/) and [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/). |
| `--force` | Causes `mariadb-install-db` to run even if DNS does not work. In that case, grant table entries that normally use host names will use IP addresses. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first option. |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first option. |
| `--rpm` | For internal use. This option is used by RPM files during the MariaDB installation process. |
| `--skip-name-resolve` | Uses IP addresses rather than host names when creating grant table entries. This option can be useful if your DNS does not work. |
| `--skip-test-db` | Don't install the test database |
| `--srcdir=path` | For internal use. The path to the MariaDB source directory. This option uses the compiled binaries and support files within the source tree, useful for if you don't want to install MariaDB yet and just want to create the system tables. The directory under which `mariadb-install-db` looks for support files such as the error message file and the file for populating the help tables. |
| `--user=user_name` | The login user name to use for running `mysqld`. Files and directories created by `mysqld` will be owned by this user. You must be `root` to use this option. By default, `mysqld` runs using your current login name and files and directories that it creates will be owned by you. |
| `--verbose` | Verbose mode. Print more information about what the program does. |
| `--windows` | For internal use. This option is used for creating Windows distributions. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-install-db` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-install-db` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
#### Option Groups

 `mariadb-install-db` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysql_install_db]` |  Options read by `mysqld_safe`, which includes both MariaDB Server and MySQL Server. |

 
`mariadb-install-db` also reads options from the following server [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[server]` | Options read by MariaDB Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-5.5]`. |
| `[mariadb]` | Options read by MariaDB Server. |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[galera]` |  Options read by a galera-capable MariaDB Server. Available on systems compiled with Galera support. |

 
Installing System Tables
------------------------

 ### Installing System Tables From a Source Tree

 If you have just [compiled MariaDB from source](../compiling-mariadb-from-source/index), and if you want to use `mariadb-install-db` from your source tree, then that can be done without having to actually install MariaDB. This is very useful if you want to test your changes to MariaDB without disturbing any existing installations of MariaDB.

 To do so, you would have to provide the `--srcdir` option. For example:

 
```
./scripts/mariadb-install-db --srcdir=. --datadir=path-to-temporary-data-dir

```

### Installing System Tables From a Binary Tarball

 If you install a [binary tarball](../installing-mariadb-binary-tarballs/index) package in a non standard path, like your home directory, and if you already have a MariaDB / MySQL package installed, then you may get conflicts with the default `/etc/my.cnf`. This often results in permissions errors.

 One possible solution is to use the `--no-defaults` option, so that it does not read any [option files](../configuring-mariadb-with-option-files/index). For example:

 
```
./scripts/mariadb-install-db --no-defaults --basedir=. --datadir=data

```

Another possible solution is to use the `defaults-file` option, so that you can specify your own [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
./scripts/mariadb-install-db --defaults-file=~/.my.cnf

```

User Accounts Created by Default
--------------------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, `mariadb-install-db` sets `--auth-root-authentication-method=socket` by default. When this is set, the default `root@localhost` user account is created with the ability to use two [authentication plugins](../authentication-plugins/index):

 * First, it is configured to try to use the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin. This allows the the `root@localhost` user to login without a password via the local Unix socket file defined by the [socket](../server-system-variables/index#socket) system variable, as long as the login is attempted from a process owned by the operating system `root` user account.
* Second, if authentication fails with the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, then it is configured to try to use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin.

 The definition of the default `root@localhost` user account is:

 
```
CREATE USER 'root'@'localhost' IDENTIFIED VIA unix_socket 
  OR mysql_native_password USING 'invalid';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION;

```

Since `mariadb-install-db` sets `--auth-root-authentication-method=socket` by default, the following additional user accounts are **not** created by default:

 * `root@127.0.0.1`
* `root@::1`
* `root@${current_hostname}`

 However, an additional user account that is defined by the `--auth-root-socket-user` option is created. If this option is not set, then the value defaults to the value of the `--user` option. On most systems, the `--user` option will use the value of `mysql` by default, so this additional user account would be called `mysql@localhost`.

 The definition of this `mysql@localhost` user account is similar to the `root@localhost` user account:

 
```
CREATE USER 'mysql'@'localhost' IDENTIFIED VIA unix_socket 
  OR mysql_native_password USING 'invalid';
GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost' WITH GRANT OPTION;

```

An invalid password is initially set for both of these user accounts. This means that before a password can be used to authenticate as either of these user accounts, the accounts must first be given a valid password by executing the `[SET PASSWORD](../set-password/index)` statement.

 For example, here is an example of setting the password for the `root@localhost` user account immediately after installation:

 
```
$ sudo yum install MariaDB-server
$ sudo systemctl start mariadb
$ sudo mariadb
...
MariaDB> SET PASSWORD = PASSWORD('XH4VmT3_jt');

```

You may notice in the above example that the [mariadb](../mariadb-command-line-client/index) command-line client is executed via [sudo](https://linux.die.net/man/8/sudo). This allows the `root@localhost` user account to successfully authenticate via the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, `mariadb-install-db` sets `--auth-root-authentication-method=normal` by default. When this is set, the following default accounts are created with no password:

 * `root@localhost`
* `root@127.0.0.1`
* `root@::1`
* `root@${current_hostname}`

 The definition of the default `root@localhost` user account is:

 
```
CREATE USER 'root'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION;

```

The definition of the other default `root` accounts is similar.

 A password should be set for these user accounts immediately after installation. This can be done either by executing the [SET PASSWORD](../set-password/index) statement or by running [mysql\_secure\_installation](../mysql_secure_installation/index).

 For example, here is an example of setting the password for the `root@localhost` user account immediately after installation:

 
```
$ sudo yum install MariaDB-server
$ sudo systemctl start mariadb
$ mysql -u root
...
MariaDB> SET PASSWORD = PASSWORD('XH4VmT3_jt');

```

Since `mariadb-install-db` sets `--auth-root-authentication-method=normal` by default, the `--auth-root-socket-user` option is ignored by default.

 
Troubleshooting Issues
----------------------

 ### Checking the Error Log

 If `mariadb-install-db` fails, you should examine the [error log](../error-log/index) in the data directory, which is the directory specified with `--datadir` option. This should provide a clue about what went wrong.

 ### Testing With mysqld

 You can also test that this is not a general fault of MariaDB Server by trying to start the `mysqld` process. The [-skip-grant-tables](../mysqld-options/index#-skip-grant-tables) option will tell it to ignore the [system tables](../system-tables/index). Enabling the [general query log](../general-query-log/index) can help you determine what queries are being run on the server. For example:

 
```
mysqld --skip-grant-tables --general-log

```

At this point, you can use the [mariadb](../mariadb-command-line-client/index) client to connect to the [mysql](../the-mysql-database-tables/index) database and look at the [system tables](../system-tables/index). For example:

 
```
$ /usr/local/mysql/bin/mysql -u root mysql
MariaDB [mysql]> show tables

```

Using a Server Compiled With --disable-grant-options
----------------------------------------------------

 The following only apply in the exceptional case that you are using a mysqld server which is configured with the `--disable-grant-options` option:

 `mariadb-install-db` needs to invoke `mysqld` with the `--bootstrap` and `--skip-grant-tables` options. A MariaDB configured with the `--disable-grant-options` option has `--bootstrap` and `--skip-grant-tables` disabled. To handle this case, set the `MYSQLD_BOOTSTRAP` environment variable to the full path name of a mysqld server that is configured without `--disable-grant-options`. `mariadb-install-db` will use that server.

 The test and test\_% Databases
------------------------------

 When calling the `mariadb-install-db` script, a new folder called `test` is created in the data directory. It only has the single `db.opt` file, which sets the client options `default-character-set` and `default-collation` only.

 If you run `mysql` as an anonymous user,  `mysql -u''@localhost`, and look for the grants and databases you are able to work with, you will get the following:

 
```
SELECT current_user;
+--------------+
| current_user |
+--------------+
| @localhost   |
+--------------+

SHOW GRANTS FOR current_user;
+--------------------------------------+
| Grants for @localhost                |
+--------------------------------------+
| GRANT USAGE ON *.* TO ``@`localhost` |
+--------------------------------------+

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
+--------------------+

```

Shown are the `information_schema` as well as `test` databases that are built in databases. But looking from [SHOW GRANTS](../show-grants/index) appears to be a paradox; how can the current user see something if they don't have privileges for that?

 Let's go a step further.  
 Now, use the `root`/`unix` user, which has all rights, in order to create a new database with the prefix `test_` , something like:

 
```
CREATE DATABASE test_electricity;

```

With the above change, a new directory will be created in the data directory.  
 Now login again with the anonymous user and run [SHOW DATABASES](../show-databases/index):

 
```
SHOW DATABASES
+--------------------+
| Database           |
+--------------------+
| information_schema |
| test               |
| test_electricity   |
+--------------------+

```

Again we are able to see the newly created database, without any rights? We have an anonymous user that has no privileges, but still can see the `test` and `test_electricity` databases.  
 **Where does this come from?**

 

---

 Login with the `root`/`unix` user to find out all privileges that the anonymous user has:

 
```
SELECT * FROM mysql.user WHERE user='' AND host='localhost'\G
*************************** 1. row ***************************
                  Host: localhost
                  User: 
              Password: 
           Select_priv: N
           Insert_priv: N
           Update_priv: N
           Delete_priv: N
           Create_priv: N
             Drop_priv: N
           Reload_priv: N
         Shutdown_priv: N
          Process_priv: N
             File_priv: N
            Grant_priv: N
       References_priv: N
            Index_priv: N
            Alter_priv: N
          Show_db_priv: N
            Super_priv: N
 Create_tmp_table_priv: N
      Lock_tables_priv: N
          Execute_priv: N
       Repl_slave_priv: N
      Repl_client_priv: N
      Create_view_priv: N
        Show_view_priv: N
   Create_routine_priv: N
    Alter_routine_priv: N
      Create_user_priv: N
            Event_priv: N
          Trigger_priv: N
Create_tablespace_priv: N
   Delete_history_priv: N
              ssl_type: 
            ssl_cipher: 
           x509_issuer: 
          x509_subject: 
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin: 
 authentication_string: 
      password_expired: N
               is_role: N
          default_role: 
    max_statement_time: 0.000000

```

As seen above from the [mysql.user](../mysqluser-table/index) table, the anonymous user doesn't have any global privileges. Still, the anonymous user can see databases, so there must be a way so that anonymous user can see the `test` and `test_electricity` databases.

 Let's check for grants on the database level. That information can be found in the [mysql.db](../mysqldb-table/index) table. Looking at the `mysql.db` table, it already contains 2 rows created when the `mariadb-install-db` script was invoked.

 The anonymous user has database privileges (without `grant`, `alter_routine` and `execute`) on `test` and `test_%` databases:

 
```
SELECT * FROM mysql.db\G
*************************** 1. row ***************************
                 Host: %
                   Db: test
                 User: 
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: N
         Execute_priv: N
           Event_priv: Y
         Trigger_priv: Y
  Delete_history_priv: Y
*************************** 2. row ***************************
                 Host: %
                   Db: test\_%
                 User: 
          Select_priv: Y
          Insert_priv: Y
          Update_priv: Y
          Delete_priv: Y
          Create_priv: Y
            Drop_priv: Y
           Grant_priv: N
      References_priv: Y
           Index_priv: Y
           Alter_priv: Y
Create_tmp_table_priv: Y
     Lock_tables_priv: Y
     Create_view_priv: Y
       Show_view_priv: Y
  Create_routine_priv: Y
   Alter_routine_priv: N
         Execute_priv: N
           Event_priv: Y
         Trigger_priv: Y
  Delete_history_priv: Y

```

The first row is reserved for explicit usage for the `test` database, which is automatically created with `mariadb-install-db`.

 Since database `test_electricity` satisfies the `test_%` pattern where `test_` is a prefix, we can understand why the user has the right to work with the newly-created database.

 As long as records in `mysql.db` for the anonymous user exists, each new user created will have the privileges for the `test` and `test_%` databases.

 Other databases privileges **are not automatically granted** for the newly created user. We have to grant privileges, which will be visible in `mysql.db` table.

 ### Not Creating the test Database and Anonymous User

 If you run `mariadb-install-db` with the `--skip-test-db` option, no `test` database will be created, which we can see as follows:

 
```
SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

SELECT * FROM mysql.db;
Empty set (0.001 sec)

```

Also, no anonymous user is created (only `unix`/`mariadb.sys`/`root` users):

 
```
SELECT user,host FROM mysql.user;
+-------------+-----------+
| User        | Host      |
+-------------+-----------+
| anel        | localhost |
| mariadb.sys | localhost |
| root        | localhost |
+-------------+-----------+

```

See Also
--------

 * [Configure MariaDB with catalog support](../starting-with-catalogs/index)
* [Installing system tables (mariadb-install-db)](../installing-system-tables-mysql_install_db/index)
* The Windows version of `mariadb-install-db`: `[mysql\_install\_db.exe](../mysql_install_dbexe/index)`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-install-db/>

mariadb-waitpid
===============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-waitpid` is a symlink to `mysql_waitpid`, the utility for terminating processes.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_waitpid` is the symlink, and `mariadb-waitpid` the binary name.From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_waitpid` is the symlink, and `mariadb-waitpid` the binary name.

 
`mysql_pid` is a utility for terminating processes. It runs on Unix-like systems, making use of the `kill()` system call.

 Usage
-----

 
```
mariadb-waitpid [options] pid time

```

Description
-----------

 `mariadb-waitpid` sends signal 0 to the process *pid* and waits up to *time* seconds for the process to terminate. *pid* and *time* must be positive integers.

 Returns 0 if the process terminates in time, or does not exist, and 1 otherwise.

 Signal 1 is used if the kill() system call cannot handle signal 0

 Options
-------

 


| Option | Description |
| --- | --- |
| `-?`, `--help` | Display help and exit |
| `-I`, `--help` | Synonym for -? |
| `-v`, `--verbose` | Be more verbose. Give a warning, if kill can't handle signal 0 |
| `-V`, `--version` | Print version information and exit |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-waitpid/>

mariadb-show
============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-show` is a symlink to `mysqlshow`, the script showing the structure of a MariaDB database.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysqlshow` is the symlink, and `mariadb-show` the binary name.

 
 Shows the structure of a MariaDB database (databases, tables, columns and indexes). You can also use [SHOW DATABASES](../show-databases/index), [SHOW TABLES](../show-tables/index), [SHOW COLUMNS](../show-columns/index), [SHOW INDEX](../show-index/index) and [SHOW TABLE STATUS](../show-table-status/index), as well as the [Information Schema](../information_schema/index) tables ([TABLES](../information-schema-tables-table/index), [COLUMNS](../information-schema-columns-table/index), [STATISTICS](../information-schema-statistics-table/index)), to get similar functionality.

 Using mariadb-show
------------------

 
```
mariadb-show [OPTIONS] [database [table [column]]]

```

The output displays only the names of those databases, tables, or columns for which you have some privileges.

 If no database is given then all matching databases are shown. If no table is given, then all matching tables in database are shown. If no column is given, then all matching columns and column types in table are shown.

 If the last argument contains a shell or SQL wildcard (\*,?,% or \_) then only what's matched by the wildcard is shown. If a database name contains any underscores, those should be escaped with a backslash (some Unix shells require two) to get a list of the proper tables or columns. “\*” and “?” characters are converted into SQL “%” and “\_” wildcard characters. This might cause some confusion when you try to display the columns for a table with a “\_” in the name, because in this case, mariadb-show shows you only the table names that match the pattern. This is easily fixed by adding an extra “%” last on the command line as a separate argument.

 ### Options

 `mariadb-show` supports the following options:

 


| Option | Description |
| --- | --- |
| `-c name`, `--character-sets-dir=name` | Directory for [character set](../data-types-character-sets-and-collations/index) files. |
| `-C`, `--compress` | Use compression in server/client protocol if both support it. |
| `--count` | Show number of rows per table (may be slow for non-[MyISAM](../myisam/index) tables). |
| `-# [name]`, `--debug[=name]` | Output debug log. Typical is `d:t:o,filename`, the default is `d:t:o`. |
| `--debug-check` | Check memory and open file usage at exit. |
| `--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](../data-types-character-sets-and-collations/index). |
| `--defaults-extra-file=name` | Read the file *name* after the global files are read. Must be given as the first option. |
| `--defaults-file=name` | Only read default options from the given file *name*. Must be given as the first option. |
| `--defaults-group-suffix=suffix` | In addition to the given groups, also read groups with this suffix. |
| `-?`, `--help` | Display help and exit. |
| `-h name`, `--host=name` | Connect to the MariaDB server on the given host. |
| `-k`, `--keys` | Show indexes for table. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first option. |
| `-p[password]`, `--password[=password]` | Password to use when connecting to server. If password is not given, it's solicited on the command line. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `-W`, `--pipe` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `--plugin-dir=name` | Directory for client-side plugins. |
| `-P num`, `--port=num` | 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). |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first option. |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `--shared-memory-base-name=name` | On Windows, the shared-memory name to use, for connections made using shared memory to a local server. The default value is `MYSQL`. The shared-memory name is case sensitive. The server must be started with the `--shared-memory` option to enable shared-memory connections. |
| `-t`, `--show-table-type` | Show table type column, as in [SHOW FULL TABLES](../show-tables/index). The type is BASE TABLE or VIEW. |
| `-S name`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables (or disables) [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `-i`, `--status` | Shows a lot of extra information about each table. See the [INFORMATION\_SCHEMA.TABLES](../information-schema-tables-table/index) table for more details on the returned information. |
| `--tls-version=name` | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. This option was added in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `-u`, `--user=name` | User for login if not current user. |
| `-v`, `--verbose` | More verbose output; you can use this multiple times to get even more verbose output. |
| `-V`, `--version` | Output version information and exit. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-show` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-show` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
In [MariaDB 10.2](../what-is-mariadb-102/index) and later, `mariadb-show` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-show` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqlshow]` |  Options read by `mysqlshow`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-show]` | Options read by `mariadb-show`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
Examples
--------

 Getting a list of databases:

 
```
bin/mariadb-show
+--------------------+
|     Databases      |
+--------------------+
| information_schema |
| test               |
+--------------------+

```

Getting a list of tables in the `test` database:

 
```
bin/mariadb-show test
Database: test
+---------+
| Tables  |
+---------+
| author  |
| book    |
| city    |
| country |
+---------+

```

Getting a list of columns in the `test`.`book` table:

 
```
bin/mariadb-show test book
Database: test  Table: book
+-----------+-----------------------+-------------------+------+-----+---------+----------------+--------------------------------+---------+
| Field     | Type                  | Collation         | Null | Key | Default | Extra          | Privileges                      | Comment |
+-----------+-----------------------+-------------------+------+-----+---------+----------------+--------------------------------+---------+
| id        | mediumint(8) unsigned |                   | NO   | PRI |         | auto_increment | select,insert,update,references |         |
| title     | varchar(200)          | latin1_swedish_ci | NO   |     |         |                | select,insert,update,references |         |
| author_id | smallint(5) unsigned  |                   | NO   | MUL |         |                | select,insert,update,references |         |
+-----------+-----------------------+-------------------+------+-----+---------+----------------+--------------------------------+---------+


```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-show/>

Legacy Clients and Utilities
=============================

   Category for removed, deprecated or unmaintained MariaDB clients and utilities.

  

| Title | Description |
| --- | --- |
|  [Percona XtraBackup](../backing-up-and-restoring-databases-percona-xtrabackup/index) |  Open source tool for performing hot backups of MariaDB, MySQL and Percona Server databases.  |
|  [MySQL Sandbox](../mysql-sandbox/index) |  Installing multiple MariaDB versions in isolation.  |
|  [mysqlaccess](../mysqlaccess/index) |  Symlink or old name for mariadb-access.  |
|  [mysqladmin](../mysqladmin/index) |  Old name or symlink for mariadb-admin.  |
|  [mysqlcheck](../mysqlcheck/index) |  Symlink or old name for mariadb-check.  |
|  [mysqldump](../mysqldump/index) |  Symlink or old name for mariadb-dump.  |
|  [mysqldumpslow](../mysqldumpslow/index) |  Symlink or old name for mariadb-dumpslow.  |
|  [mysqlhotcopy](../mysqlhotcopy/index) |  Symlink or old name for mariadb-hotcopy.  |
|  [mysqlimport](../mysqlimport/index) |  Symlink or old name for mariadb-import.  |
|  [mysqlreport](../mysqlreport/index) |  Symlink or old name for mariadb-report.  |
|  [mysqlshow](../mysqlshow/index) |  Symlink or old name for mariadb-show.  |
|  [mysqlslap](../mysqlslap/index) |  Symlink or old name for mariadb-slap.  |
|  [mysql\_convert\_table\_format](../mysql_convert_table_format/index) |  Symlink or old name for mariadb-convert-table-format.  |
|  [mysql\_embedded](../mysql_embedded/index) |  Symlink or old name for mariadb-embedded.  |
|  [mysql\_find\_rows](../mysql_find_rows/index) |  Symlink or old name for mariadb-find-rows.  |
|  [mysql\_fix\_extensions](../mysql_fix_extensions/index) |  Symlink or old name for mariadb-fix-extensions.  |
|  [mysql\_install\_db](../mysql_install_db/index) |  Symlink or old name for mariadb-install-db.  |
|  [mysql\_plugin](../mysql_plugin/index) |  Symlink or old name for mariadb-plugin.  |
|  [mysql\_secure\_installation](../mysql_secure_installation/index) |  Symlink or old name for mariadb-secure-installation.  |
|  [mysql\_setpermission](../mysql_setpermission/index) |  Symlink or old name for mariadb\_setpermission.  |
|  [mysql\_tzinfo\_to\_sql](../mysql_tzinfo_to_sql/index) |  Symlink or old name for mariadb-tzinfo-to-sql.  |
|  [mysql\_upgrade](../mysql_upgrade/index) |  Symlink or old name for mariadb-upgrade.  |
|  [mysql\_waitpid](../mysql_waitpid/index) |  Symlink or old name for mariadb-waitpid.  |
|  [mysql\_zap](../mysql_zap/index) |  Kill processes that match a pattern.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/legacy-clients-and-utilities/>

Character Set and Collation Overview
====================================

    What Are Character Sets and Collations
--------------------------------------

 A character set is a set of characters while a collation is the rules for comparing and sorting a particular character set.

 For example, a subset of a character set could consist of the letters `A`, `B` and `C`. A default collation could define these as appearing in an ascending order of `A, B, C`.

 If we consider different case characters, more complexity is added. A binary collation would evaluate the characters `A` and `a` differently, ordering them in a particular way. A case-insensitive collation would evaluate `A` and `a` equivalently, while the German phone book collation evaluates the characters `ue` and `ü` equivalently.

 A character set can have many collations associated with it, while each collation is only associated with one character set. In MariaDB, the character set name is always part of the collation name. For example, the `latin1_german1_ci` collation applies only to the `latin1` character set. Each character set also has one default collation. The `latin1` default collation is `latin1_swedish_ci`. 

 As an example, by default, the character `y` comes between `x` and `z`, while in Lithuanian, it's sorted between `i` and `k`. Similarly, the German phone book order is different to the German dictionary order, so while they share the same character set, the collation is different.

 Viewing Character Sets and Collations
-------------------------------------

 In MariaDB, the default character set is latin1, and the default collation is latin1\_swedish\_ci (however this may differ in some distros, see for example [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index)). You can view a full list of character sets and collations supported by MariaDB at [Supported Character Sets and Collations](../supported-character-sets-and-collations/index), or see what's supported on your server with the [SHOW CHARACTER SET](../show-character-set/index) and [SHOW COLLATION](../show-collation/index) commands.

 By default, `A` comes before `Z`, so the following evaluates to true:

 
```
 SELECT "A" < "Z";
+-----------+
| "A" < "Z" |
+-----------+
|         1 |
+-----------+

```

By default, comparisons are case-insensitive:

 
```
SELECT "A" < "a", "A" = "a";
+-----------+-----------+
| "A" < "a" | "A" = "a" |
+-----------+-----------+
|         0 |         1 |
+-----------+-----------+

```

Changing Character Sets and Collations
--------------------------------------

 Character sets and collations can be set from the server level right down to the column level, as well as for client-server communication.

 For example, `ue` and `ü` are by default evaluated differently.

 
```
SELECT 'Mueller' = 'Müller';
+----------------------+
| 'Müller' = 'Mueller' |
+----------------------+
|                    0 |
+----------------------+

```

By using the [collation\_connection](../server-system-variables/index#collation_connection) system variable to change the connection character set to `latin1_german2_ci`, or German phone book, the same two characters will evaluate as equivalent.

 
```
SET collation_connection = latin1_german2_ci;

SELECT 'Mueller' = 'Müller';
+-----------------------+
| 'Mueller' = 'Müller'  |
+-----------------------+
|                     1 |
+-----------------------+

```

See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for more.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/character-set-and-collation-overview/>

mariadb-plugin
==============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-plugin` is a symlink to `mysql_plugin`, the tool for enabling or disabling [plugins](../mariadb-plugins/index).

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_plugin` is the symlink, and `mariadb-plugin` the binary name.

 
 `mariadb-plugin` is a tool for enabling or disabling [plugins](../mariadb-plugins/index).

 It is a commandline alternative to the [INSTALL PLUGIN](../install-plugin/index) and [UNINSTALL PLUGIN](../uninstall-plugin/index) statements, and the `--plugin-load option` to [mysqld](../mysqld-options-full-list/index).

 `mariadb-plugin` must be run while the server is offline, and works by adding or removing rows from the [mysql.plugin](../mysqlplugin-table/index) table.

 `mariadb-plugin` basically has two use cases:

 * adding a plugin even before the first real server startup
* removing a plugin that crashes the server on startup

 For the install use case, adding a [plugin-load-add](../plugin-overview/index#installing-a-plugin-with-plugin-load-add) entry to `my.cnf` or in a separate include option file, is probably a better alternative. In case of a plugin loaded via a `mysql.plugin` crashing the server, uninstalling the plugin with the help of `mariadb-plugin` can be the only viable action though.

 Usage
-----

 
```
mariadb-plugin [options] <plugin> ENABLE|DISABLE

```

`mariadb-plugin` expects to find a configuration file that indicates how to configure the plugins. The configuration file is by default the same name as the plugin, with a `.ini` extension. For example:

 
```
mariadb-plugin crazyplugins ENABLE

```

Here, `mariadb-plugin` will look for a file called `crazyplugins.ini`

 
```
crazyplugins
crazyplugin1
crazyplugin2
crazyplugin3

```

The first line should contain the name of the library object file, with no extension. The other lines list the names of the components. Each value should be on a separate line, and the `#` character at the start of the line indicates a comment. 

 Options
-------

 The following options can be specified on the command line, while some can be specified in the `[mysqld]` group of any option file. For options specified in a `[mysqld]` group, only the `--basedir`, `--datadir`, and `--plugin-dir` options can be used - the rest are ignored.

 


| Option | Description |
| --- | --- |
| `-b`, `--basedir=name` | The base directory for the server. |
| `-d`, `--datadir=name` | The data directory for the server. |
| `-?`, `--help` | Display help and exit. |
| `-f`, `--my-print-defaults=name` | Path to `my_print_defaults` executable. Example: `/source/temp11/extra` |
| `-m`, `--mysqld=name` | Path to `mysqld` executable. Example: `/sbin/temp1/mysql/bin` |
| `-n`, `--no-defaults` | Do not read values from configuration file. |
| `-p`, `--plugin-dir=name` | The plugin directory for the server. |
| `-i`, `--plugin-ini=name` | Read plugin information from configuration file specified instead of from `<plugin-dir>/<plugin_name>.ini`. |
| `-P`, `--print-defaults` | Show default values from configuration file. |
| `-v`, `--verbose` | More verbose output; you can use this multiple times to get even more verbose output. |
| `-V`, `--version` | Output version information and exit. |

 
See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [Plugin Overview](../plugin-overview/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-plugin/>

DROP FUNCTION UDF
=================

    Syntax
------

 
```
DROP FUNCTION [IF EXISTS] function_name

```
 Description
-----------

 This statement drops the [user-defined function](../user-defined-functions/index) (UDF) named `function_name`.

 To drop a function, you must have the `[DELETE privilege](../grant/index)` for the mysql database. This is because `DROP FUNCTION` removes the row from the [mysql.func](../mysqlfunc-table/index) system table that records the function's name, type and shared library name.

 For dropping a stored function, see [DROP FUNCTION](../drop-function/index).

 ### Upgrading a UDF

 To upgrade the UDF's shared library, first run a [DROP FUNCTION](../drop-function/index) statement, then upgrade the shared library and finally run the CREATE FUNCTION statement. If you upgrade without following this process, you may crash the server.

 Examples
--------

 
```
DROP FUNCTION jsoncontains_path;

```

IF EXISTS:

 
```
DROP FUNCTION jsoncontains_path;
ERROR 1305 (42000): FUNCTION test.jsoncontains_path does not exist

DROP FUNCTION IF EXISTS jsoncontains_path;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------------------------------+
| Level | Code | Message                                        |
+-------+------+------------------------------------------------+
| Note  | 1305 | FUNCTION test.jsoncontains_path does not exist |
+-------+------+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-function-udf/>

mysql.func Table
================

    The `mysql.func` table stores information about [user-defined functions](../user-defined-functions/index) (UDFs) created with the [CREATE FUNCTION UDF](../create-function-udf/index) statement.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.func` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `name` | `char(64)` | NO | PRI |  | UDF name |
| `ret` | `tinyint(1)` | NO |  | 0 |  |
| `dl` | `char(128)` | NO |  |  | Shared library name |
| `type` | `enum('function','aggregate')` | NO |  | `NULL` | Type, either `function` or `aggregate`. Aggregate functions are summary functions such as [SUM()](../sum/index) and [AVG()](../avg/index). |

 
Example
-------

 
```
SELECT * FROM mysql.func;
+------------------------------+-----+--------------+-----------+
| name                         | ret | dl           | type      |
+------------------------------+-----+--------------+-----------+
| spider_direct_sql            |   2 | ha_spider.so | function  |
| spider_bg_direct_sql         |   2 | ha_spider.so | aggregate |
| spider_ping_table            |   2 | ha_spider.so | function  |
| spider_copy_tables           |   2 | ha_spider.so | function  |
| spider_flush_table_mon_cache |   2 | ha_spider.so | function  |
+------------------------------+-----+--------------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlfunc-table/>

SHOW CHARACTER SET
==================

    Syntax
------

 
```
SHOW CHARACTER SET
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 The `SHOW CHARACTER SET` statement shows all available [character sets](../data-types-character-sets-and-collations/index). The `LIKE` clause, if present on its own, indicates which character set names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The same information can be queried from the [Information Schema CHARACTER\_SETS](../information-schema-character_sets-table/index) table.

 See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on specifying the character set at the server, database, table and column levels.

 Examples
--------

 
```
SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | cp1252 West European        | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+

```


```
SHOW CHARACTER SET WHERE Maxlen LIKE '2';
+---------+---------------------------+-------------------+--------+
| Charset | Description               | Default collation | Maxlen |
+---------+---------------------------+-------------------+--------+
| big5    | Big5 Traditional Chinese  | big5_chinese_ci   |      2 |
| sjis    | Shift-JIS Japanese        | sjis_japanese_ci  |      2 |
| euckr   | EUC-KR Korean             | euckr_korean_ci   |      2 |
| gb2312  | GB2312 Simplified Chinese | gb2312_chinese_ci |      2 |
| gbk     | GBK Simplified Chinese    | gbk_chinese_ci    |      2 |
| ucs2    | UCS-2 Unicode             | ucs2_general_ci   |      2 |
| cp932   | SJIS for Windows Japanese | cp932_japanese_ci |      2 |
+---------+---------------------------+-------------------+--------+

```

See Also
--------

 * [Supported Character Sets and Collations](../supported-character-sets-and-collations/index)
* [Setting Character Sets and Collations](../setting-character-sets-and-collations/index)
* [Information Schema CHARACTER\_SETS](../information-schema-character_sets-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-character-set/>

String Data Types
==================

  

| Title | Description |
| --- | --- |
|  [String Literals](../string-literals/index) |  Strings are sequences of characters and are enclosed with quotes.  |
|  [BINARY](../binary/index) |  Fixed-length binary byte string.  |
|  [BLOB](../blob/index) |  Binary large object up to 65,535 bytes.  |
|  [BLOB and TEXT Data Types](../blob-and-text-data-types/index) |  Binary large object data types and the corresponding TEXT types.  |
|  [CHAR](../char/index) |  Fixed-length string.  |
|  [CHAR BYTE](../char-byte/index) |  Alias for BINARY.  |
|  [ENUM](../enum/index) |  Enumeration, or string object that can have one value chosen from a list of values.  |
|  [INET4](../inet4/index) |  For storage of IPv4 addresses.  |
|  [INET6](../inet6/index) |  For storage of IPv6 addresses.  |
|  [JSON Data Type](../json-data-type/index) |  Compatibility data type that is an alias for LONGTEXT.  |
|  [MEDIUMBLOB](../mediumblob/index) |  Medium binary large object up to 16,777,215 bytes.  |
|  [MEDIUMTEXT](../mediumtext/index) |  A TEXT column with a maximum length of 16,777,215 characters.  |
|  [LONGBLOB](../longblob/index) |  Long BLOB holding up to 4GB.  |
|  [LONG and LONG VARCHAR](../long-and-long-varchar/index) |  LONG and LONG VARCHAR are synonyms for MEDIUMTEXT.  |
|  [LONGTEXT](../longtext/index) |  A TEXT column with a maximum length of 4,294,967,295 characters.  |
|  [ROW](../row/index) |  Data type for stored procedure variables.  |
|  [TEXT](../text/index) |  A TEXT column with a maximum length of 65,535 characters.  |
|  [TINYBLOB](../tinyblob/index) |  Tiny binary large object up to 255 bytes.  |
|  [TINYTEXT](../tinytext/index) |  A TEXT column with a maximum length of 255 characters.  |
|  [VARBINARY](../varbinary/index) |  Variable-length binary byte string.  |
|  [VARCHAR](../varchar/index) |  Variable-length string.  |
|  [SET Data Type](../set-data-type/index) |  Set, or string object that can have 0 or more values chosen from a list of values.  |
|  [UUID Data Type](../uuid-data-type/index) |  Data type intended for the storage of UUID data.  |
|  [Data Type Storage Requirements](../data-type-storage-requirements/index) |  Storage requirements for the various data types.  |
|  [Supported Character Sets and Collations](../supported-character-sets-and-collations/index) |  MariaDB supports the following character sets and collations.  |
|  [Character Sets and Collations](../character-sets/index) |  Setting character set and collation for a language.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/string-data-types/>

Supported Character Sets and Collations
=======================================

    Character Sets
--------------

 MariaDB supports the following character sets:

 Note that the [Mroonga Storage Engine](../mroonga/index) only supports a limited number of character sets. See [Mroonga available character sets](../about-mroonga/index#available-character-sets).

 


| Charset | Description | Default collation | Maxlen |
| --- | --- | --- | --- |
| armscii8 | ARMSCII-8 Armenian | armscii8\_general\_ci | 1 |
| ascii | US ASCII | ascii\_general\_ci | 1 |
| big5 | Big5 Traditional Chinese | big5\_chinese\_ci | 2 |
| binary | Binary pseudo charset | binary | 1 |
| cp1250 | Windows Central European | cp1250\_general\_ci | 1 |
| cp1251 | Windows Cyrillic | cp1251\_general\_ci | 1 |
| cp1256 | Windows Arabic | cp1256\_general\_ci | 1 |
| cp1257 | Windows Baltic | cp1257\_general\_ci | 1 |
| cp850 | DOS West European | cp850\_general\_ci | 1 |
| cp852 | DOS Central European | cp852\_general\_ci | 1 |
| cp866 | DOS Russian | cp866\_general\_ci | 1 |
| cp932 | SJIS for Windows Japanese | cp932\_japanese\_ci | 2 |
| dec8 | DEC West European | dec8\_swedish\_ci | 1 |
| eucjpms | UJIS for Windows Japanese | eucjpms\_japanese\_ci | 3 |
| euckr | EUC-KR Korean | euckr\_korean\_ci | 2 |
| gb2312 | GB2312 Simplified Chinese | gb2312\_chinese\_ci | 2 |
| gbk | GBK Simplified Chinese | gbk\_chinese\_ci | 2 |
| geostd8 | GEOSTD8 Georgian | geostd8\_general\_ci | 1 |
| greek | ISO 8859-7 Greek | greek\_general\_ci | 1 |
| hebrew | ISO 8859-8 Hebrew | hebrew\_general\_ci | 1 |
| hp8 | HP West European | hp8\_english\_ci | 1 |
| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2\_general\_ci | 1 |
| koi8r | KOI8-R Relcom Russian | koi8r\_general\_ci | 1 |
| koi8u | KOI8-U Ukrainian | koi8u\_general\_ci | 1 |
| latin1 | cp1252 West European | latin1\_swedish\_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2\_general\_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5\_turkish\_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7\_general\_ci | 1 |
| macce | Mac Central European | macce\_general\_ci | 1 |
| macroman | Mac West European | macroman\_general\_ci | 1 |
| sjis | Shift-JIS Japanese | sjis\_japanese\_ci | 2 |
| swe7 | 7bit Swedish | swe7\_swedish\_ci | 1 |
| tis620 | TIS620 Thai | tis620\_thai\_ci | 1 |
| ucs2 | UCS-2 Unicode | ucs2\_general\_ci | 2 |
| ujis | EUC-JP Japanese | ujis\_japanese\_ci | 3 |
| utf8 | UTF-8 Unicode | utf8\_general\_ci | 3/4 (see [OLD\_MODE](../old-mode/index)) |
| utf16 | UTF-16 Unicode | utf16\_general\_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le\_general\_ci | 4 |
| utf32 | UTF-32 Unicode | utf32\_general\_ci | 4 |
| utf8mb3 | UTF-8 Unicode | utf8mb3\_general\_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4\_general\_ci | 4 |

 
You can see which character sets are available in a particular version by running the [SHOW CHARACTER SET](../show-character-set/index) statement or by querying the [Information Schema CHARACTER\_SETS Table](../information-schema-character_sets-table/index).

 Collations
----------

 MariaDB supports the following collations:

 
```
show collation;
+--------------------------------+----------+------+---------+----------+---------+
| Collation                      | Charset  | Id   | Default | Compiled | Sortlen |
+--------------------------------+----------+------+---------+----------+---------+
| big5_chinese_ci                | big5     |    1 | Yes     | Yes      |       1 |
| big5_bin                       | big5     |   84 |         | Yes      |       1 |
| big5_chinese_nopad_ci          | big5     | 1025 |         | Yes      |       1 |
| big5_nopad_bin                 | big5     | 1108 |         | Yes      |       1 |
| dec8_swedish_ci                | dec8     |    3 | Yes     | Yes      |       1 |
| dec8_bin                       | dec8     |   69 |         | Yes      |       1 |
| dec8_swedish_nopad_ci          | dec8     | 1027 |         | Yes      |       1 |
| dec8_nopad_bin                 | dec8     | 1093 |         | Yes      |       1 |
| cp850_general_ci               | cp850    |    4 | Yes     | Yes      |       1 |
| cp850_bin                      | cp850    |   80 |         | Yes      |       1 |
| cp850_general_nopad_ci         | cp850    | 1028 |         | Yes      |       1 |
| cp850_nopad_bin                | cp850    | 1104 |         | Yes      |       1 |
| hp8_english_ci                 | hp8      |    6 | Yes     | Yes      |       1 |
| hp8_bin                        | hp8      |   72 |         | Yes      |       1 |
| hp8_english_nopad_ci           | hp8      | 1030 |         | Yes      |       1 |
| hp8_nopad_bin                  | hp8      | 1096 |         | Yes      |       1 |
| koi8r_general_ci               | koi8r    |    7 | Yes     | Yes      |       1 |
| koi8r_bin                      | koi8r    |   74 |         | Yes      |       1 |
| koi8r_general_nopad_ci         | koi8r    | 1031 |         | Yes      |       1 |
| koi8r_nopad_bin                | koi8r    | 1098 |         | Yes      |       1 |
| latin1_german1_ci              | latin1   |    5 |         | Yes      |       1 |
| latin1_swedish_ci              | latin1   |    8 | Yes     | Yes      |       1 |
| latin1_danish_ci               | latin1   |   15 |         | Yes      |       1 |
| latin1_german2_ci              | latin1   |   31 |         | Yes      |       2 |
| latin1_bin                     | latin1   |   47 |         | Yes      |       1 |
| latin1_general_ci              | latin1   |   48 |         | Yes      |       1 |
| latin1_general_cs              | latin1   |   49 |         | Yes      |       1 |
| latin1_spanish_ci              | latin1   |   94 |         | Yes      |       1 |
| latin1_swedish_nopad_ci        | latin1   | 1032 |         | Yes      |       1 |
| latin1_nopad_bin               | latin1   | 1071 |         | Yes      |       1 |
| latin2_czech_cs                | latin2   |    2 |         | Yes      |       4 |
| latin2_general_ci              | latin2   |    9 | Yes     | Yes      |       1 |
| latin2_hungarian_ci            | latin2   |   21 |         | Yes      |       1 |
| latin2_croatian_ci             | latin2   |   27 |         | Yes      |       1 |
| latin2_bin                     | latin2   |   77 |         | Yes      |       1 |
| latin2_general_nopad_ci        | latin2   | 1033 |         | Yes      |       1 |
| latin2_nopad_bin               | latin2   | 1101 |         | Yes      |       1 |
| swe7_swedish_ci                | swe7     |   10 | Yes     | Yes      |       1 |
| swe7_bin                       | swe7     |   82 |         | Yes      |       1 |
| swe7_swedish_nopad_ci          | swe7     | 1034 |         | Yes      |       1 |
| swe7_nopad_bin                 | swe7     | 1106 |         | Yes      |       1 |
| ascii_general_ci               | ascii    |   11 | Yes     | Yes      |       1 |
| ascii_bin                      | ascii    |   65 |         | Yes      |       1 |
| ascii_general_nopad_ci         | ascii    | 1035 |         | Yes      |       1 |
| ascii_nopad_bin                | ascii    | 1089 |         | Yes      |       1 |
| ujis_japanese_ci               | ujis     |   12 | Yes     | Yes      |       1 |
| ujis_bin                       | ujis     |   91 |         | Yes      |       1 |
| ujis_japanese_nopad_ci         | ujis     | 1036 |         | Yes      |       1 |
| ujis_nopad_bin                 | ujis     | 1115 |         | Yes      |       1 |
| sjis_japanese_ci               | sjis     |   13 | Yes     | Yes      |       1 |
| sjis_bin                       | sjis     |   88 |         | Yes      |       1 |
| sjis_japanese_nopad_ci         | sjis     | 1037 |         | Yes      |       1 |
| sjis_nopad_bin                 | sjis     | 1112 |         | Yes      |       1 |
| hebrew_general_ci              | hebrew   |   16 | Yes     | Yes      |       1 |
| hebrew_bin                     | hebrew   |   71 |         | Yes      |       1 |
| hebrew_general_nopad_ci        | hebrew   | 1040 |         | Yes      |       1 |
| hebrew_nopad_bin               | hebrew   | 1095 |         | Yes      |       1 |
| tis620_thai_ci                 | tis620   |   18 | Yes     | Yes      |       4 |
| tis620_bin                     | tis620   |   89 |         | Yes      |       1 |
| tis620_thai_nopad_ci           | tis620   | 1042 |         | Yes      |       4 |
| tis620_nopad_bin               | tis620   | 1113 |         | Yes      |       1 |
| euckr_korean_ci                | euckr    |   19 | Yes     | Yes      |       1 |
| euckr_bin                      | euckr    |   85 |         | Yes      |       1 |
| euckr_korean_nopad_ci          | euckr    | 1043 |         | Yes      |       1 |
| euckr_nopad_bin                | euckr    | 1109 |         | Yes      |       1 |
| koi8u_general_ci               | koi8u    |   22 | Yes     | Yes      |       1 |
| koi8u_bin                      | koi8u    |   75 |         | Yes      |       1 |
| koi8u_general_nopad_ci         | koi8u    | 1046 |         | Yes      |       1 |
| koi8u_nopad_bin                | koi8u    | 1099 |         | Yes      |       1 |
| gb2312_chinese_ci              | gb2312   |   24 | Yes     | Yes      |       1 |
| gb2312_bin                     | gb2312   |   86 |         | Yes      |       1 |
| gb2312_chinese_nopad_ci        | gb2312   | 1048 |         | Yes      |       1 |
| gb2312_nopad_bin               | gb2312   | 1110 |         | Yes      |       1 |
| greek_general_ci               | greek    |   25 | Yes     | Yes      |       1 |
| greek_bin                      | greek    |   70 |         | Yes      |       1 |
| greek_general_nopad_ci         | greek    | 1049 |         | Yes      |       1 |
| greek_nopad_bin                | greek    | 1094 |         | Yes      |       1 |
| cp1250_general_ci              | cp1250   |   26 | Yes     | Yes      |       1 |
| cp1250_czech_cs                | cp1250   |   34 |         | Yes      |       2 |
| cp1250_croatian_ci             | cp1250   |   44 |         | Yes      |       1 |
| cp1250_bin                     | cp1250   |   66 |         | Yes      |       1 |
| cp1250_polish_ci               | cp1250   |   99 |         | Yes      |       1 |
| cp1250_general_nopad_ci        | cp1250   | 1050 |         | Yes      |       1 |
| cp1250_nopad_bin               | cp1250   | 1090 |         | Yes      |       1 |
| gbk_chinese_ci                 | gbk      |   28 | Yes     | Yes      |       1 |
| gbk_bin                        | gbk      |   87 |         | Yes      |       1 |
| gbk_chinese_nopad_ci           | gbk      | 1052 |         | Yes      |       1 |
| gbk_nopad_bin                  | gbk      | 1111 |         | Yes      |       1 |
| latin5_turkish_ci              | latin5   |   30 | Yes     | Yes      |       1 |
| latin5_bin                     | latin5   |   78 |         | Yes      |       1 |
| latin5_turkish_nopad_ci        | latin5   | 1054 |         | Yes      |       1 |
| latin5_nopad_bin               | latin5   | 1102 |         | Yes      |       1 |
| armscii8_general_ci            | armscii8 |   32 | Yes     | Yes      |       1 |
| armscii8_bin                   | armscii8 |   64 |         | Yes      |       1 |
| armscii8_general_nopad_ci      | armscii8 | 1056 |         | Yes      |       1 |
| armscii8_nopad_bin             | armscii8 | 1088 |         | Yes      |       1 |
| utf8mb3_general_ci             | utf8mb3  |   33 | Yes     | Yes      |       1 |
| utf8mb3_bin                    | utf8mb3  |   83 |         | Yes      |       1 |
| utf8mb3_unicode_ci             | utf8mb3  |  192 |         | Yes      |       8 |
| utf8mb3_icelandic_ci           | utf8mb3  |  193 |         | Yes      |       8 |
| utf8mb3_latvian_ci             | utf8mb3  |  194 |         | Yes      |       8 |
| utf8mb3_romanian_ci            | utf8mb3  |  195 |         | Yes      |       8 |
| utf8mb3_slovenian_ci           | utf8mb3  |  196 |         | Yes      |       8 |
| utf8mb3_polish_ci              | utf8mb3  |  197 |         | Yes      |       8 |
| utf8mb3_estonian_ci            | utf8mb3  |  198 |         | Yes      |       8 |
| utf8mb3_spanish_ci             | utf8mb3  |  199 |         | Yes      |       8 |
| utf8mb3_swedish_ci             | utf8mb3  |  200 |         | Yes      |       8 |
| utf8mb3_turkish_ci             | utf8mb3  |  201 |         | Yes      |       8 |
| utf8mb3_czech_ci               | utf8mb3  |  202 |         | Yes      |       8 |
| utf8mb3_danish_ci              | utf8mb3  |  203 |         | Yes      |       8 |
| utf8mb3_lithuanian_ci          | utf8mb3  |  204 |         | Yes      |       8 |
| utf8mb3_slovak_ci              | utf8mb3  |  205 |         | Yes      |       8 |
| utf8mb3_spanish2_ci            | utf8mb3  |  206 |         | Yes      |       8 |
| utf8mb3_roman_ci               | utf8mb3  |  207 |         | Yes      |       8 |
| utf8mb3_persian_ci             | utf8mb3  |  208 |         | Yes      |       8 |
| utf8mb3_esperanto_ci           | utf8mb3  |  209 |         | Yes      |       8 |
| utf8mb3_hungarian_ci           | utf8mb3  |  210 |         | Yes      |       8 |
| utf8mb3_sinhala_ci             | utf8mb3  |  211 |         | Yes      |       8 |
| utf8mb3_german2_ci             | utf8mb3  |  212 |         | Yes      |       8 |
| utf8mb3_croatian_mysql561_ci   | utf8mb3  |  213 |         | Yes      |       8 |
| utf8mb3_unicode_520_ci         | utf8mb3  |  214 |         | Yes      |       8 |
| utf8mb3_vietnamese_ci          | utf8mb3  |  215 |         | Yes      |       8 |
| utf8mb3_general_mysql500_ci    | utf8mb3  |  223 |         | Yes      |       1 |
| utf8mb3_croatian_ci            | utf8mb3  |  576 |         | Yes      |       8 |
| utf8mb3_myanmar_ci             | utf8mb3  |  577 |         | Yes      |       8 |
| utf8mb3_thai_520_w2            | utf8mb3  |  578 |         | Yes      |       4 |
| utf8mb3_general_nopad_ci       | utf8mb3  | 1057 |         | Yes      |       1 |
| utf8mb3_nopad_bin              | utf8mb3  | 1107 |         | Yes      |       1 |
| utf8mb3_unicode_nopad_ci       | utf8mb3  | 1216 |         | Yes      |       8 |
| utf8mb3_unicode_520_nopad_ci   | utf8mb3  | 1238 |         | Yes      |       8 |
| ucs2_general_ci                | ucs2     |   35 | Yes     | Yes      |       1 |
| ucs2_bin                       | ucs2     |   90 |         | Yes      |       1 |
| ucs2_unicode_ci                | ucs2     |  128 |         | Yes      |       8 |
| ucs2_icelandic_ci              | ucs2     |  129 |         | Yes      |       8 |
| ucs2_latvian_ci                | ucs2     |  130 |         | Yes      |       8 |
| ucs2_romanian_ci               | ucs2     |  131 |         | Yes      |       8 |
| ucs2_slovenian_ci              | ucs2     |  132 |         | Yes      |       8 |
| ucs2_polish_ci                 | ucs2     |  133 |         | Yes      |       8 |
| ucs2_estonian_ci               | ucs2     |  134 |         | Yes      |       8 |
| ucs2_spanish_ci                | ucs2     |  135 |         | Yes      |       8 |
| ucs2_swedish_ci                | ucs2     |  136 |         | Yes      |       8 |
| ucs2_turkish_ci                | ucs2     |  137 |         | Yes      |       8 |
| ucs2_czech_ci                  | ucs2     |  138 |         | Yes      |       8 |
| ucs2_danish_ci                 | ucs2     |  139 |         | Yes      |       8 |
| ucs2_lithuanian_ci             | ucs2     |  140 |         | Yes      |       8 |
| ucs2_slovak_ci                 | ucs2     |  141 |         | Yes      |       8 |
| ucs2_spanish2_ci               | ucs2     |  142 |         | Yes      |       8 |
| ucs2_roman_ci                  | ucs2     |  143 |         | Yes      |       8 |
| ucs2_persian_ci                | ucs2     |  144 |         | Yes      |       8 |
| ucs2_esperanto_ci              | ucs2     |  145 |         | Yes      |       8 |
| ucs2_hungarian_ci              | ucs2     |  146 |         | Yes      |       8 |
| ucs2_sinhala_ci                | ucs2     |  147 |         | Yes      |       8 |
| ucs2_german2_ci                | ucs2     |  148 |         | Yes      |       8 |
| ucs2_croatian_mysql561_ci      | ucs2     |  149 |         | Yes      |       8 |
| ucs2_unicode_520_ci            | ucs2     |  150 |         | Yes      |       8 |
| ucs2_vietnamese_ci             | ucs2     |  151 |         | Yes      |       8 |
| ucs2_general_mysql500_ci       | ucs2     |  159 |         | Yes      |       1 |
| ucs2_croatian_ci               | ucs2     |  640 |         | Yes      |       8 |
| ucs2_myanmar_ci                | ucs2     |  641 |         | Yes      |       8 |
| ucs2_thai_520_w2               | ucs2     |  642 |         | Yes      |       4 |
| ucs2_general_nopad_ci          | ucs2     | 1059 |         | Yes      |       1 |
| ucs2_nopad_bin                 | ucs2     | 1114 |         | Yes      |       1 |
| ucs2_unicode_nopad_ci          | ucs2     | 1152 |         | Yes      |       8 |
| ucs2_unicode_520_nopad_ci      | ucs2     | 1174 |         | Yes      |       8 |
| cp866_general_ci               | cp866    |   36 | Yes     | Yes      |       1 |
| cp866_bin                      | cp866    |   68 |         | Yes      |       1 |
| cp866_general_nopad_ci         | cp866    | 1060 |         | Yes      |       1 |
| cp866_nopad_bin                | cp866    | 1092 |         | Yes      |       1 |
| keybcs2_general_ci             | keybcs2  |   37 | Yes     | Yes      |       1 |
| keybcs2_bin                    | keybcs2  |   73 |         | Yes      |       1 |
| keybcs2_general_nopad_ci       | keybcs2  | 1061 |         | Yes      |       1 |
| keybcs2_nopad_bin              | keybcs2  | 1097 |         | Yes      |       1 |
| macce_general_ci               | macce    |   38 | Yes     | Yes      |       1 |
| macce_bin                      | macce    |   43 |         | Yes      |       1 |
| macce_general_nopad_ci         | macce    | 1062 |         | Yes      |       1 |
| macce_nopad_bin                | macce    | 1067 |         | Yes      |       1 |
| macroman_general_ci            | macroman |   39 | Yes     | Yes      |       1 |
| macroman_bin                   | macroman |   53 |         | Yes      |       1 |
| macroman_general_nopad_ci      | macroman | 1063 |         | Yes      |       1 |
| macroman_nopad_bin             | macroman | 1077 |         | Yes      |       1 |
| cp852_general_ci               | cp852    |   40 | Yes     | Yes      |       1 |
| cp852_bin                      | cp852    |   81 |         | Yes      |       1 |
| cp852_general_nopad_ci         | cp852    | 1064 |         | Yes      |       1 |
| cp852_nopad_bin                | cp852    | 1105 |         | Yes      |       1 |
| latin7_estonian_cs             | latin7   |   20 |         | Yes      |       1 |
| latin7_general_ci              | latin7   |   41 | Yes     | Yes      |       1 |
| latin7_general_cs              | latin7   |   42 |         | Yes      |       1 |
| latin7_bin                     | latin7   |   79 |         | Yes      |       1 |
| latin7_general_nopad_ci        | latin7   | 1065 |         | Yes      |       1 |
| latin7_nopad_bin               | latin7   | 1103 |         | Yes      |       1 |
| utf8mb4_general_ci             | utf8mb4  |   45 | Yes     | Yes      |       1 |
| utf8mb4_bin                    | utf8mb4  |   46 |         | Yes      |       1 |
| utf8mb4_unicode_ci             | utf8mb4  |  224 |         | Yes      |       8 |
| utf8mb4_icelandic_ci           | utf8mb4  |  225 |         | Yes      |       8 |
| utf8mb4_latvian_ci             | utf8mb4  |  226 |         | Yes      |       8 |
| utf8mb4_romanian_ci            | utf8mb4  |  227 |         | Yes      |       8 |
| utf8mb4_slovenian_ci           | utf8mb4  |  228 |         | Yes      |       8 |
| utf8mb4_polish_ci              | utf8mb4  |  229 |         | Yes      |       8 |
| utf8mb4_estonian_ci            | utf8mb4  |  230 |         | Yes      |       8 |
| utf8mb4_spanish_ci             | utf8mb4  |  231 |         | Yes      |       8 |
| utf8mb4_swedish_ci             | utf8mb4  |  232 |         | Yes      |       8 |
| utf8mb4_turkish_ci             | utf8mb4  |  233 |         | Yes      |       8 |
| utf8mb4_czech_ci               | utf8mb4  |  234 |         | Yes      |       8 |
| utf8mb4_danish_ci              | utf8mb4  |  235 |         | Yes      |       8 |
| utf8mb4_lithuanian_ci          | utf8mb4  |  236 |         | Yes      |       8 |
| utf8mb4_slovak_ci              | utf8mb4  |  237 |         | Yes      |       8 |
| utf8mb4_spanish2_ci            | utf8mb4  |  238 |         | Yes      |       8 |
| utf8mb4_roman_ci               | utf8mb4  |  239 |         | Yes      |       8 |
| utf8mb4_persian_ci             | utf8mb4  |  240 |         | Yes      |       8 |
| utf8mb4_esperanto_ci           | utf8mb4  |  241 |         | Yes      |       8 |
| utf8mb4_hungarian_ci           | utf8mb4  |  242 |         | Yes      |       8 |
| utf8mb4_sinhala_ci             | utf8mb4  |  243 |         | Yes      |       8 |
| utf8mb4_german2_ci             | utf8mb4  |  244 |         | Yes      |       8 |
| utf8mb4_croatian_mysql561_ci   | utf8mb4  |  245 |         | Yes      |       8 |
| utf8mb4_unicode_520_ci         | utf8mb4  |  246 |         | Yes      |       8 |
| utf8mb4_vietnamese_ci          | utf8mb4  |  247 |         | Yes      |       8 |
| utf8mb4_croatian_ci            | utf8mb4  |  608 |         | Yes      |       8 |
| utf8mb4_myanmar_ci             | utf8mb4  |  609 |         | Yes      |       8 |
| utf8mb4_thai_520_w2            | utf8mb4  |  610 |         | Yes      |       4 |
| utf8mb4_general_nopad_ci       | utf8mb4  | 1069 |         | Yes      |       1 |
| utf8mb4_nopad_bin              | utf8mb4  | 1070 |         | Yes      |       1 |
| utf8mb4_unicode_nopad_ci       | utf8mb4  | 1248 |         | Yes      |       8 |
| utf8mb4_unicode_520_nopad_ci   | utf8mb4  | 1270 |         | Yes      |       8 |
| uca1400_ai_ci                  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_ai_cs                  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_as_ci                  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_as_cs                  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_nopad_ai_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_nopad_ai_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_nopad_as_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_nopad_as_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_ai_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_ai_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_as_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_as_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_nopad_ai_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_nopad_ai_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_nopad_as_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_icelandic_nopad_as_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_latvian_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_ai_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_ai_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_as_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_as_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_nopad_ai_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_nopad_ai_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_nopad_as_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_romanian_nopad_as_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_ai_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_ai_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_as_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_as_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_nopad_ai_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_nopad_ai_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_nopad_as_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovenian_nopad_as_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_ai_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_ai_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_as_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_as_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_nopad_ai_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_nopad_ai_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_nopad_as_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_polish_nopad_as_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_ai_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_ai_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_as_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_as_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_nopad_ai_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_nopad_ai_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_nopad_as_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_estonian_nopad_as_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_swedish_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_turkish_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_ai_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_ai_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_as_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_as_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_nopad_ai_ci      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_nopad_ai_cs      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_nopad_as_ci      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_czech_nopad_as_cs      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_ai_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_ai_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_as_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_as_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_nopad_ai_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_nopad_ai_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_nopad_as_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_danish_nopad_as_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_ai_ci       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_ai_cs       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_as_ci       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_as_cs       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_nopad_ai_ci | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_nopad_ai_cs | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_nopad_as_ci | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_lithuanian_nopad_as_cs | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_ai_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_ai_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_as_ci           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_as_cs           | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_nopad_ai_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_nopad_ai_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_nopad_as_ci     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_slovak_nopad_as_cs     | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_ai_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_ai_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_as_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_as_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_nopad_ai_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_nopad_ai_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_nopad_as_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_spanish2_nopad_as_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_ai_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_ai_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_as_ci            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_as_cs            | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_nopad_ai_ci      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_nopad_ai_cs      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_nopad_as_ci      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_roman_nopad_as_cs      | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_persian_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_ai_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_ai_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_as_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_as_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_nopad_ai_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_nopad_ai_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_nopad_as_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_esperanto_nopad_as_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_ai_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_ai_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_as_ci        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_as_cs        | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_nopad_ai_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_nopad_ai_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_nopad_as_ci  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_hungarian_nopad_as_cs  | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_sinhala_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_ai_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_ai_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_as_ci          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_as_cs          | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_nopad_ai_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_nopad_ai_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_nopad_as_ci    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_german2_nopad_as_cs    | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_ai_ci       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_ai_cs       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_as_ci       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_as_cs       | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_nopad_ai_ci | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_nopad_ai_cs | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_nopad_as_ci | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_vietnamese_nopad_as_cs | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_ai_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_ai_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_as_ci         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_as_cs         | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_nopad_ai_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_nopad_ai_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_nopad_as_ci   | NULL     | NULL | NULL    | Yes      |       8 |
| uca1400_croatian_nopad_as_cs   | NULL     | NULL | NULL    | Yes      |       8 |
| cp1251_bulgarian_ci            | cp1251   |   14 |         | Yes      |       1 |
| cp1251_ukrainian_ci            | cp1251   |   23 |         | Yes      |       1 |
| cp1251_bin                     | cp1251   |   50 |         | Yes      |       1 |
| cp1251_general_ci              | cp1251   |   51 | Yes     | Yes      |       1 |
| cp1251_general_cs              | cp1251   |   52 |         | Yes      |       1 |
| cp1251_nopad_bin               | cp1251   | 1074 |         | Yes      |       1 |
| cp1251_general_nopad_ci        | cp1251   | 1075 |         | Yes      |       1 |
| utf16_general_ci               | utf16    |   54 | Yes     | Yes      |       1 |
| utf16_bin                      | utf16    |   55 |         | Yes      |       1 |
| utf16_unicode_ci               | utf16    |  101 |         | Yes      |       8 |
| utf16_icelandic_ci             | utf16    |  102 |         | Yes      |       8 |
| utf16_latvian_ci               | utf16    |  103 |         | Yes      |       8 |
| utf16_romanian_ci              | utf16    |  104 |         | Yes      |       8 |
| utf16_slovenian_ci             | utf16    |  105 |         | Yes      |       8 |
| utf16_polish_ci                | utf16    |  106 |         | Yes      |       8 |
| utf16_estonian_ci              | utf16    |  107 |         | Yes      |       8 |
| utf16_spanish_ci               | utf16    |  108 |         | Yes      |       8 |
| utf16_swedish_ci               | utf16    |  109 |         | Yes      |       8 |
| utf16_turkish_ci               | utf16    |  110 |         | Yes      |       8 |
| utf16_czech_ci                 | utf16    |  111 |         | Yes      |       8 |
| utf16_danish_ci                | utf16    |  112 |         | Yes      |       8 |
| utf16_lithuanian_ci            | utf16    |  113 |         | Yes      |       8 |
| utf16_slovak_ci                | utf16    |  114 |         | Yes      |       8 |
| utf16_spanish2_ci              | utf16    |  115 |         | Yes      |       8 |
| utf16_roman_ci                 | utf16    |  116 |         | Yes      |       8 |
| utf16_persian_ci               | utf16    |  117 |         | Yes      |       8 |
| utf16_esperanto_ci             | utf16    |  118 |         | Yes      |       8 |
| utf16_hungarian_ci             | utf16    |  119 |         | Yes      |       8 |
| utf16_sinhala_ci               | utf16    |  120 |         | Yes      |       8 |
| utf16_german2_ci               | utf16    |  121 |         | Yes      |       8 |
| utf16_croatian_mysql561_ci     | utf16    |  122 |         | Yes      |       8 |
| utf16_unicode_520_ci           | utf16    |  123 |         | Yes      |       8 |
| utf16_vietnamese_ci            | utf16    |  124 |         | Yes      |       8 |
| utf16_croatian_ci              | utf16    |  672 |         | Yes      |       8 |
| utf16_myanmar_ci               | utf16    |  673 |         | Yes      |       8 |
| utf16_thai_520_w2              | utf16    |  674 |         | Yes      |       4 |
| utf16_general_nopad_ci         | utf16    | 1078 |         | Yes      |       1 |
| utf16_nopad_bin                | utf16    | 1079 |         | Yes      |       1 |
| utf16_unicode_nopad_ci         | utf16    | 1125 |         | Yes      |       8 |
| utf16_unicode_520_nopad_ci     | utf16    | 1147 |         | Yes      |       8 |
| utf16le_general_ci             | utf16le  |   56 | Yes     | Yes      |       1 |
| utf16le_bin                    | utf16le  |   62 |         | Yes      |       1 |
| utf16le_general_nopad_ci       | utf16le  | 1080 |         | Yes      |       1 |
| utf16le_nopad_bin              | utf16le  | 1086 |         | Yes      |       1 |
| cp1256_general_ci              | cp1256   |   57 | Yes     | Yes      |       1 |
| cp1256_bin                     | cp1256   |   67 |         | Yes      |       1 |
| cp1256_general_nopad_ci        | cp1256   | 1081 |         | Yes      |       1 |
| cp1256_nopad_bin               | cp1256   | 1091 |         | Yes      |       1 |
| cp1257_lithuanian_ci           | cp1257   |   29 |         | Yes      |       1 |
| cp1257_bin                     | cp1257   |   58 |         | Yes      |       1 |
| cp1257_general_ci              | cp1257   |   59 | Yes     | Yes      |       1 |
| cp1257_nopad_bin               | cp1257   | 1082 |         | Yes      |       1 |
| cp1257_general_nopad_ci        | cp1257   | 1083 |         | Yes      |       1 |
| utf32_general_ci               | utf32    |   60 | Yes     | Yes      |       1 |
| utf32_bin                      | utf32    |   61 |         | Yes      |       1 |
| utf32_unicode_ci               | utf32    |  160 |         | Yes      |       8 |
| utf32_icelandic_ci             | utf32    |  161 |         | Yes      |       8 |
| utf32_latvian_ci               | utf32    |  162 |         | Yes      |       8 |
| utf32_romanian_ci              | utf32    |  163 |         | Yes      |       8 |
| utf32_slovenian_ci             | utf32    |  164 |         | Yes      |       8 |
| utf32_polish_ci                | utf32    |  165 |         | Yes      |       8 |
| utf32_estonian_ci              | utf32    |  166 |         | Yes      |       8 |
| utf32_spanish_ci               | utf32    |  167 |         | Yes      |       8 |
| utf32_swedish_ci               | utf32    |  168 |         | Yes      |       8 |
| utf32_turkish_ci               | utf32    |  169 |         | Yes      |       8 |
| utf32_czech_ci                 | utf32    |  170 |         | Yes      |       8 |
| utf32_danish_ci                | utf32    |  171 |         | Yes      |       8 |
| utf32_lithuanian_ci            | utf32    |  172 |         | Yes      |       8 |
| utf32_slovak_ci                | utf32    |  173 |         | Yes      |       8 |
| utf32_spanish2_ci              | utf32    |  174 |         | Yes      |       8 |
| utf32_roman_ci                 | utf32    |  175 |         | Yes      |       8 |
| utf32_persian_ci               | utf32    |  176 |         | Yes      |       8 |
| utf32_esperanto_ci             | utf32    |  177 |         | Yes      |       8 |
| utf32_hungarian_ci             | utf32    |  178 |         | Yes      |       8 |
| utf32_sinhala_ci               | utf32    |  179 |         | Yes      |       8 |
| utf32_german2_ci               | utf32    |  180 |         | Yes      |       8 |
| utf32_croatian_mysql561_ci     | utf32    |  181 |         | Yes      |       8 |
| utf32_unicode_520_ci           | utf32    |  182 |         | Yes      |       8 |
| utf32_vietnamese_ci            | utf32    |  183 |         | Yes      |       8 |
| utf32_croatian_ci              | utf32    |  736 |         | Yes      |       8 |
| utf32_myanmar_ci               | utf32    |  737 |         | Yes      |       8 |
| utf32_thai_520_w2              | utf32    |  738 |         | Yes      |       4 |
| utf32_general_nopad_ci         | utf32    | 1084 |         | Yes      |       1 |
| utf32_nopad_bin                | utf32    | 1085 |         | Yes      |       1 |
| utf32_unicode_nopad_ci         | utf32    | 1184 |         | Yes      |       8 |
| utf32_unicode_520_nopad_ci     | utf32    | 1206 |         | Yes      |       8 |
| binary                         | binary   |   63 | Yes     | Yes      |       1 |
| geostd8_general_ci             | geostd8  |   92 | Yes     | Yes      |       1 |
| geostd8_bin                    | geostd8  |   93 |         | Yes      |       1 |
| geostd8_general_nopad_ci       | geostd8  | 1116 |         | Yes      |       1 |
| geostd8_nopad_bin              | geostd8  | 1117 |         | Yes      |       1 |
| cp932_japanese_ci              | cp932    |   95 | Yes     | Yes      |       1 |
| cp932_bin                      | cp932    |   96 |         | Yes      |       1 |
| cp932_japanese_nopad_ci        | cp932    | 1119 |         | Yes      |       1 |
| cp932_nopad_bin                | cp932    | 1120 |         | Yes      |       1 |
| eucjpms_japanese_ci            | eucjpms  |   97 | Yes     | Yes      |       1 |
| eucjpms_bin                    | eucjpms  |   98 |         | Yes      |       1 |
| eucjpms_japanese_nopad_ci      | eucjpms  | 1121 |         | Yes      |       1 |
| eucjpms_nopad_bin              | eucjpms  | 1122 |         | Yes      |       1 |
+--------------------------------+----------+------+---------+----------+---------+
506 rows in set (0.002 sec)

```

This is from [MariaDB 10.11.5](https://mariadb.com/kb/en/mariadb-10-11-5-release-notes/) including the UCA-14.0.0 collations added in [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10101-release-notes/).

 Before [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), the `utf8mb3*` collations listed above were named `utf8*`.

 Case Sensitivity
----------------

 A '`ci`' at the end of a collation name indicates the collation is case insensitive. A '`cs`' at the end of a collation name indicates the collation is case sensitive.

 NO PAD Collations
-----------------

 `NO PAD` collations regard trailing spaces as normal characters. You can get a list of all of these by querying the [Information Schema COLLATIONS Table](../information-schema-collations-table/index) as follows:

 
```
SELECT collation_name FROM information_schema.COLLATIONS
WHERE collation_name LIKE "%nopad%";  
+------------------------------+
| collation_name               |
+------------------------------+
| big5_chinese_nopad_ci        |
| big5_nopad_bin               |
...

```

Accent Insensitivity
--------------------

 An accent insensitive collation is one where the accented and unaccented versions of a letter are considered to be identical for sorting purposes.

 [MariaDB 10.10](../what-is-mariadb-1010/index) added the accent insensitivity flag, and new collations are marked with '\_ai' or '\_as' in the name to indicate this, for example:

 
```
...
| uca1400_spanish2_ai_ci         |
| uca1400_spanish2_ai_cs         |
| uca1400_spanish2_as_ci         |
| uca1400_spanish2_as_cs         |
...

```

Changes
-------

 * [MariaDB 10.10](../what-is-mariadb-1010/index) added 184 UCA-14.0.0 collations. Unicode-14.0.0 was released in September 2021. They contain 939 [built-in contractions](http://www.unicode.org/Public/UCA/14.0.0/allkeys.txt). Old collations based on UCA-4.0.0 and UCA-5.2.0 did not support built-in contractions. This is a step towards better Unicode Collation Algorithm compliance. With built-in contractions, some languages (e.g. Thai) won't need specific collations and will just work with the default "root" collation.
* [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) changed the `utf8` character set by default to be an alias for utf8mb3 rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](../old_mode/index) system variable.
* [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) added 88 `NO PAD` collations.
* [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/) added the `utf8_thai_520_w2`, `utf8mb4_thai_520_w2`, `ucs2_thai_520_w2`, `utf16_thai_520_w2` and `utf32_thai_520_w2` collations.
* [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) added the `utf8_myanmar_ci`, `ucs2_myanmar_ci`, `utf8mb4_myanmar_ci`, `utf16_myanmar_ci` and `utf32_myanmar_ci` collations.
* [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) added the `utf8_german2_ci`, `utf8mb4_german2_ci`, `ucs2_german2_ci`, `utf16_german2_ci` and `utf32_german2_ci` collations.
* [MariaDB 5.1.41](https://mariadb.com/kb/en/mariadb-5141-release-notes/) added a Croatian collation patch from [Alexander Barkov](http://www.collation-charts.org/) to fix some problems with the Croatian character set and `LIKE` queries. This patch added `utf8_croatian_ci` and `ucs2_croatian_ci` collations to MariaDB.

 See Also
--------

 * [Information Schema CHARACTER\_SETS Table](../information-schema-character_sets-table/index)
* [Information Schema COLLATIONS Table](../information-schema-collations-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/supported-character-sets-and-collations/>

Unicode
=======

    Unicode is a standard for encoding text across multiple writing systems. MariaDB supports a number of [character sets](../data-types-character-sets-and-collations/index) for storing Unicode data:

 


| Character Set | Description |
| --- | --- |
| ucs2 | UCS-2, each character is represented by a 2-byte code with the most significant byte first. Fixed-length 16-bit encoding. |
| utf8 | Until [MariaDB 10.5](../what-is-mariadb-105/index), this was a UTF-8 encoding using one to three bytes per character. Basic Latin letters, numbers and punctuation use one byte. European and Middle East letters mostly fit into 2 bytes. Korean, Chinese, and Japanese ideographs use 3-bytes. No supplementary characters are stored. From [MariaDB 10.6](../what-is-mariadb-106/index), `utf8` is an alias for `utf8mb3`, but this can changed to `ut8mb4` by changing the default value of the [old\_mode](../server-system-variables/index#old_mode) system variable. |
| utf8mb3 | UTF-8 encoding using one to three bytes per character. Basic Latin letters, numbers and punctuation use one byte. European and Middle East letters mostly fit into 2 bytes. Korean, Chinese, and Japanese ideographs use 3-bytes. No supplementary characters are stored. Until [MariaDB 10.5](../what-is-mariadb-105/index), this was an alias for `utf8`. From [MariaDB 10.6](../what-is-mariadb-106/index), `utf8` is by default an alias for `utf8mb3`, but this can changed to `ut8mb4` by changing the default value of the [old\_mode](../server-system-variables/index#old_mode) system variable. |
| utf8mb4 | UTF-8 encoding the same as `utf8mb3` but which stores supplementary characters in four bytes. |
| utf16 | UTF-16, same as ucs2, but stores supplementary characters in 32 bits. 16 or 32-bits. |
| utf32 | UTF-32, fixed-length 32-bit encoding. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/unicode/>

SHOW COLLATION
==============

    Syntax
------

 
```
SHOW COLLATION
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 The output from `SHOW COLLATION` includes all available [collations](../data-types-character-sets-and-collations/index). The `LIKE` clause, if present on its own, indicates which collation names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The same information can be queried from the [Information Schema COLLATIONS](../information-schema-collations-table/index) table.

 See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on specifying the collation at the server, database, table and column levels.

 Examples
--------

 
```
SHOW COLLATION LIKE 'latin1%';
+-------------------------+---------+------+---------+----------+---------+
| Collation               | Charset | Id   | Default | Compiled | Sortlen |
+-------------------------+---------+------+---------+----------+---------+
| latin1_german1_ci       | latin1  |    5 |         | Yes      |       1 |
| latin1_swedish_ci       | latin1  |    8 | Yes     | Yes      |       1 |
| latin1_danish_ci        | latin1  |   15 |         | Yes      |       1 |
| latin1_german2_ci       | latin1  |   31 |         | Yes      |       2 |
| latin1_bin              | latin1  |   47 |         | Yes      |       1 |
| latin1_general_ci       | latin1  |   48 |         | Yes      |       1 |
| latin1_general_cs       | latin1  |   49 |         | Yes      |       1 |
| latin1_spanish_ci       | latin1  |   94 |         | Yes      |       1 |
| latin1_swedish_nopad_ci | latin1  | 1032 |         | Yes      |       1 |
| latin1_nopad_bin        | latin1  | 1071 |         | Yes      |       1 |
+-------------------------+---------+------+---------+----------+---------+

```


```
SHOW COLLATION WHERE Sortlen LIKE '8' AND Charset LIKE 'utf8mb4';
+------------------------------+---------+------+---------+----------+---------+
| Collation                    | Charset | Id   | Default | Compiled | Sortlen |
+------------------------------+---------+------+---------+----------+---------+
| utf8mb4_unicode_ci           | utf8mb4 |  224 |         | Yes      |       8 |
| utf8mb4_icelandic_ci         | utf8mb4 |  225 |         | Yes      |       8 |
| utf8mb4_latvian_ci           | utf8mb4 |  226 |         | Yes      |       8 |
| utf8mb4_romanian_ci          | utf8mb4 |  227 |         | Yes      |       8 |
| utf8mb4_slovenian_ci         | utf8mb4 |  228 |         | Yes      |       8 |
| utf8mb4_polish_ci            | utf8mb4 |  229 |         | Yes      |       8 |
| utf8mb4_estonian_ci          | utf8mb4 |  230 |         | Yes      |       8 |
| utf8mb4_spanish_ci           | utf8mb4 |  231 |         | Yes      |       8 |
| utf8mb4_swedish_ci           | utf8mb4 |  232 |         | Yes      |       8 |
| utf8mb4_turkish_ci           | utf8mb4 |  233 |         | Yes      |       8 |
| utf8mb4_czech_ci             | utf8mb4 |  234 |         | Yes      |       8 |
| utf8mb4_danish_ci            | utf8mb4 |  235 |         | Yes      |       8 |
| utf8mb4_lithuanian_ci        | utf8mb4 |  236 |         | Yes      |       8 |
| utf8mb4_slovak_ci            | utf8mb4 |  237 |         | Yes      |       8 |
| utf8mb4_spanish2_ci          | utf8mb4 |  238 |         | Yes      |       8 |
| utf8mb4_roman_ci             | utf8mb4 |  239 |         | Yes      |       8 |
| utf8mb4_persian_ci           | utf8mb4 |  240 |         | Yes      |       8 |
| utf8mb4_esperanto_ci         | utf8mb4 |  241 |         | Yes      |       8 |
| utf8mb4_hungarian_ci         | utf8mb4 |  242 |         | Yes      |       8 |
| utf8mb4_sinhala_ci           | utf8mb4 |  243 |         | Yes      |       8 |
| utf8mb4_german2_ci           | utf8mb4 |  244 |         | Yes      |       8 |
| utf8mb4_croatian_mysql561_ci | utf8mb4 |  245 |         | Yes      |       8 |
| utf8mb4_unicode_520_ci       | utf8mb4 |  246 |         | Yes      |       8 |
| utf8mb4_vietnamese_ci        | utf8mb4 |  247 |         | Yes      |       8 |
| utf8mb4_croatian_ci          | utf8mb4 |  608 |         | Yes      |       8 |
| utf8mb4_myanmar_ci           | utf8mb4 |  609 |         | Yes      |       8 |
| utf8mb4_unicode_nopad_ci     | utf8mb4 | 1248 |         | Yes      |       8 |
| utf8mb4_unicode_520_nopad_ci | utf8mb4 | 1270 |         | Yes      |       8 |
+------------------------------+---------+------+---------+----------+---------+

```

See Also
--------

 * [Supported Character Sets and Collations](../supported-character-sets-and-collations/index)
* [Setting Character Sets and Collations](../setting-character-sets-and-collations/index)
* [Information Schema COLLATIONS](../information-schema-collations-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-collation/>

Setting Character Sets and Collations
=====================================

     In MariaDB, the default [character set](../data-types-character-sets-and-collations/index) is latin1, and the default collation is latin1\_swedish\_ci (however this may differ in some distros, see for example [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index)). Both character sets and collations can be specified from the server right down to the column level, as well as for client-server connections. When changing a character set and not specifying a collation, the default collation for the new character set is always used. 

 Character sets and collations always cascade down, so a column without a specified collation will look for the table default, the table for the database, and the database for the server. It's therefore possible to have extremely fine-grained control over all the character sets and collations used in your data.

 Default collations for each character set can be viewed with the [SHOW COLLATION](../show-collation/index) statement, for example, to find the default collation for the latin2 character set:

 
```
SHOW COLLATION LIKE 'latin2%';
+---------------------+---------+----+---------+----------+---------+
| Collation           | Charset | Id | Default | Compiled | Sortlen |
+---------------------+---------+----+---------+----------+---------+
| latin2_czech_cs     | latin2  |  2 |         | Yes      |       4 |
| latin2_general_ci   | latin2  |  9 | Yes     | Yes      |       1 |
| latin2_hungarian_ci | latin2  | 21 |         | Yes      |       1 |
| latin2_croatian_ci  | latin2  | 27 |         | Yes      |       1 |
| latin2_bin          | latin2  | 77 |         | Yes      |       1 |
+---------------------+---------+----+---------+----------+---------+

```

Server Level
------------

 The [character\_set\_server](../server-system-variables/index#character_set_server) system variable can be used to change the default server character set. It can be set both on startup or dynamically, with the [SET](../set/index) command:

 
```
SET character_set_server = 'latin2';

```

Similarly, the [collation\_server](../server-system-variables/index#collation_server) variable is used for setting the default server collation.

 
```
SET collation_server = 'latin2_czech_cs';

```

Database Level
--------------

 The [CREATE DATABASE](../create-database/index) and [ALTER DATABASE](../alter-database/index) statements have optional character set and collation clauses. If these are left out, the server defaults are used.

 
```
CREATE DATABASE czech_slovak_names 
  CHARACTER SET = 'keybcs2'
  COLLATE = 'keybcs2_bin';

```


```
ALTER DATABASE czech_slovak_names COLLATE = 'keybcs2_general_ci';

```

To determine the default character set used by a database, use: 

 
```
SHOW CREATE DATABASE czech_slovak_names;
+--------------------+--------------------------------------------------------------------------------+
| Database           | Create Database                                                                |
+--------------------+--------------------------------------------------------------------------------+
| czech_slovak_names | CREATE DATABASE `czech_slovak_names` /*!40100 DEFAULT CHARACTER SET keybcs2 */ |
+--------------------+--------------------------------------------------------------------------------+

```

or alternatively, for the character set and collation:

 
```
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def          | czech_slovak_names | keybcs2                    | keybcs2_general_ci     | NULL     |
| def          | information_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | mysql              | latin1                     | latin1_swedish_ci      | NULL     |
| def          | performance_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | test               | latin1                     | latin1_swedish_ci      | NULL     |
+--------------+--------------------+----------------------------+------------------------+----------+

```

It is also possible to specify only the collation, and, since each collation only applies to one character set, the associated character set will automatically be specified.

 
```
CREATE DATABASE danish_names COLLATE 'utf8_danish_ci';

SHOW CREATE DATABASE danish_names;
+--------------+----------------------------------------------------------------------------------------------+
| Database     | Create Database                                                                              |
+--------------+----------------------------------------------------------------------------------------------+
| danish_names | CREATE DATABASE `danish_names` /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_danish_ci */ |
+--------------+----------------------------------------------------------------------------------------------+

```

Although there are [character\_set\_database](../server-system-variables/index#character_set_database) and [collation\_database](../server-system-variables/index#collation_database) system variables which can be set dynamically, these are used for determining the character set and collation for the default database, and should only be set by the server.

 Table Level
-----------

 The [CREATE TABLE](../create-table/index) and [ALTER TABLE](../alter-table/index) statements support optional character set and collation clauses, a MariaDB and MySQL extension to standard SQL.

 
```
CREATE TABLE english_names (id INT, name VARCHAR(40)) 
  CHARACTER SET 'utf8' 
  COLLATE 'utf8_icelandic_ci';

```

If neither character set nor collation is provided, the database default will be used. If only the character set is provided, the default collation for that character set will be used . If only the collation is provided, the associated character set will be used. See [Supported Character Sets and Collations](../supported-character-sets-and-collations/index).

 
```
ALTER TABLE table_name
 CONVERT TO CHARACTER SET charset_name [COLLATE collation_name];

```

If no collation is provided, the collation will be set to the default collation for that character set. See [Supported Character Sets and Collations](../supported-character-sets-and-collations/index).

 For [VARCHAR](../varchar/index) or [TEXT](../text/index) columns, CONVERT TO CHARACTER SET changes the data type if needed to ensure the new column is long enough to store as many characters as the original column. 

 For example, an ascii TEXT column requires a single byte per character, so the column can hold up to 65,535 characters. If the column is converted to utf8, 3 bytes can be required for each character, so the column will be converted to [MEDIUMTEXT](../mediumtext/index) to be able to hold the same number of characters.

 `CONVERT TO CHARACTER SET binary` will convert [CHAR](../char/index), [VARCHAR](../varchar/index) and [TEXT](../text/index) columns to [BINARY](../binary/index), [VARBINARY](../varbinary/index) and [BLOB](../blob/index) respectively, and from that point will no longer have a character set, or be affected by future `CONVERT TO CHARACTER SET` statements. 

 To avoid data type changes resulting from `CONVERT TO CHARACTER SET`, use `MODIFY` on the individual columns instead. For example:

 
```
ALTER TABLE table_name MODIFY ascii_text_column TEXT CHARACTER SET utf8;
ALTER TABLE table_name MODIFY ascii_varchar_column VARCHAR(M) CHARACTER SET utf8;

```

Column Level
------------

 Character sets and collations can also be specified for columns that are character types CHAR, TEXT or VARCHAR. The [CREATE TABLE](../create-table/index) and [ALTER TABLE](../alter-table/index) statements support optional character set and collation clauses for this purpose - unlike those at the table level, the column level definitions are standard SQL.

 
```
CREATE TABLE european_names (
  croatian_names VARCHAR(40) COLLATE 'cp1250_croatian_ci',
  greek_names VARCHAR(40) CHARACTER SET 'greek');

```

If neither collation nor character set is provided, the table default is used. If only the character set is specified, that character set's default collation is used, while if only the collation is specified, the associated character set is used. 

 
When using [ALTER TABLE](../alter-table/index) to change a column's character set, you need to ensure the character sets are compatible with your data. MariaDB will map the data as best it can, but it's possible to lose data if care is not taken.

 
The [SHOW CREATE TABLE](../show-create-table/index) statement or INFORMATION SCHEMA database can be used to determine column character sets and collations.

 
```
SHOW CREATE TABLE european_names\G
*************************** 1. row ***************************
       Table: european_names
Create Table: CREATE TABLE `european_names` (
  `croatian_names` varchar(40) CHARACTER SET cp1250 COLLATE cp1250_croatian_ci DEFAULT NULL,
  `greek_names` varchar(40) CHARACTER SET greek DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_danish_ci

```


```
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME LIKE 'european%'\G
*************************** 1. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: danish_names
              TABLE_NAME: european_names
             COLUMN_NAME: croatian_names
        ORDINAL_POSITION: 1
          COLUMN_DEFAULT: NULL
             IS_NULLABLE: YES
               DATA_TYPE: varchar
CHARACTER_MAXIMUM_LENGTH: 40
  CHARACTER_OCTET_LENGTH: 40
       NUMERIC_PRECISION: NULL
           NUMERIC_SCALE: NULL
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: cp1250
          COLLATION_NAME: cp1250_croatian_ci
             COLUMN_TYPE: varchar(40)
              COLUMN_KEY: 
                   EXTRA: 
              PRIVILEGES: select,insert,update,references
          COLUMN_COMMENT: 
*************************** 2. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: danish_names
              TABLE_NAME: european_names
             COLUMN_NAME: greek_names
        ORDINAL_POSITION: 2
          COLUMN_DEFAULT: NULL
             IS_NULLABLE: YES
               DATA_TYPE: varchar
CHARACTER_MAXIMUM_LENGTH: 40
  CHARACTER_OCTET_LENGTH: 40
       NUMERIC_PRECISION: NULL
           NUMERIC_SCALE: NULL
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: greek
          COLLATION_NAME: greek_general_ci
             COLUMN_TYPE: varchar(40)
              COLUMN_KEY: 
                   EXTRA: 
              PRIVILEGES: select,insert,update,references
          COLUMN_COMMENT: 

```

Filenames
---------

 Since [MariaDB 5.1](../what-is-mariadb-51/index), the [character\_set\_filesystem](../server-system-variables/index#character_set_filesystem) system variable has controlled interpretation of file names that are given as literal strings. This affects the following statements and functions:

 * [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* SELECT INTO OUTFILE
* [LOAD DATA INFILE](../load-data-infile/index)
* [LOAD XML](../load-xml/index)
* [LOAD\_FILE()](../load_file/index)

 Literals
--------

 By default, the character set and collation used for literals is determined by the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables. However, they can also be specified explicitly:

 
```
[_charset_name]'string' [COLLATE collation_name]

```

The character set of string literals that do not have a character set introducer is determined by the [character\_set\_connection](../server-system-variables/index#character_set_connection) system variable.

 This query:

 
```
  SELECT CHARSET('a'), @@character_set_connection;

```

always returns the same character set name in both columns.

 [character\_set\_client](../server-system-variables/index#character_set_client) and [character\_set\_connection](../server-system-variables/index#character_set_connection) are normally (e.g. during handshake, or after a SET NAMES query) are set to equal values. However, it's possible to set to different values.

 ### Examples

 Examples when setting @@character\_set\_client and @@character\_set\_connection to different values can be useful:

 Example 1:

 Suppose, we have a utf8 database with this table:

 
```
CREATE TABLE t1 (a VARCHAR(10)) CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO t1 VALUES ('oe'),('ö');

```

Now we connect to it using "mysql.exe", which uses the DOS character set (cp850 on a West European machine), and want to fetch all records that are equal to 'ö' according to the German phonebook rules.

 It's possible with the following:

 
```
SET @@character_set_client=cp850, @@character_set_connection=utf8;
SELECT a FROM t1 WHERE a='ö' COLLATE utf8_german2_ci;

```

This will return:

 
```
+------+
| a    |
+------+
| oe   |
| ö    |
+------+

```

It works as follows:

 1. The client sends the query using cp850.
2. The server, when parsing the query, creates a utf8 string literal by converting 'ö' from @@character\_set\_client (cp850) to @@character\_set\_connection (utf8)
3. The server applies the collation "utf8\_german2\_ci" to this string literal.
4. The server uses utf8\_german2\_ci for comparison.

 Note, if we rewrite the script like this:

 
```
SET NAMES cp850;
SELECT a FROM t1 WHERE a='ö' COLLATE utf8_german2_ci;

```

we'll get an error:

 
```
ERROR 1253 (42000): COLLATION 'utf8_german2_ci' is not valid for CHARACTER SET 'cp850'

```

because:

 * on step #2, the literal is not converted to utf8 any more and is created using cp850.
* on step #3, the server fails to apply utf8\_german2\_ci to an cp850 string literal.

 Example 2:

 Suppose we have a utf8 database and use "mysql.exe" from a West European machine again.

 We can do this:

 
```
SET @@character_set_client=cp850, @@character_set_connection=utf8;
CREATE TABLE t2 AS SELECT 'ö';

```

It will create a table with a column of the type `VARCHAR(1) CHARACTER SET utf8`.

 Note, if we rewrite the query like this:

 
```
SET NAMES cp850;
CREATE TABLE t2 AS SELECT 'ö';

```

It will create a table with a column of the type `VARCHAR(1) CHARACTER SET cp850`, which is probably not a good idea.

 ### N

 Also, `N` or `n` can be used as prefix to convert a literal into the National Character set (which in MariaDB is always utf8).

 For example:

 
```
SELECT _latin2 'Müller';
+-----------+
| MĂźller   |
+-----------+
| MĂźller   |
+-----------+

```


```
SELECT CHARSET(N'a string');
+----------------------+
| CHARSET(N'a string') |
+----------------------+
| utf8                 |
+----------------------+

```


```
SELECT 'Mueller' = 'Müller' COLLATE 'latin1_german2_ci';
+---------------------------------------------------+
| 'Mueller' = 'Müller' COLLATE 'latin1_german2_ci'  |
+---------------------------------------------------+
|                                                 1 |
+---------------------------------------------------+

```

Stored Programs and Views
-------------------------

 The literals which occur in stored programs and views, by default, use the character set and collation which was specified by the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables when the stored program was created. These values can be seen using the SHOW CREATE statements. To change the character sets used for literals in an existing stored program, it is necessary to drop and recreate the stored program.

 For stored routines parameters and return values, a character set and a collation can be specified via the CHARACTER SET and COLLATE clauses. Before 5.5, specifying a collation was not supported.

 The following example shows that the character set and collation are determined at the time of creation:

 
```
SET @@local.character_set_connection='latin1';

DELIMITER ||
CREATE PROCEDURE `test`.`x`()
BEGIN
	SELECT CHARSET('x');
END;
||
Query OK, 0 rows affected (0.00 sec)

DELIMITER ;
SET @@local.character_set_connection='utf8';

CALL `test`.`x`();
+--------------+
| CHARSET('x') |
+--------------+
| latin1       |
+--------------+

```

The following example shows how to specify a function parameters character set and collation:

 
```
CREATE FUNCTION `test`.`y`(`str` TEXT CHARACTER SET utf8 COLLATE utf8_bin)
	RETURNS TEXT CHARACTER SET latin1 COLLATE latin1_bin
BEGIN
	SET @param_coll = COLLATION(`str`);
	RETURN `str`;
END;

-- return value's collation:
SELECT COLLATION(`test`.`y`('Hello, planet!'));
+-----------------------------------------+
| COLLATION(`test`.`y`('Hello, planet!')) |
+-----------------------------------------+
| latin1_bin                              |
+-----------------------------------------+

-- parameter's collation:
SELECT @param_coll;
+-------------+
| @param_coll |
+-------------+
| utf8_bin    |
+-------------+

```

### Illegal Collation Mix

 
**MariaDB [10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/) - [10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/)**In [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/), you may encounter Error 1267 when performing comparison operations in views on tables that use binary constants. For instance,

 
```
CREATE TABLE test.t1 (
   a TEXT CHARACTER SET gbk 
) ENGINE=InnoDB 
CHARSET=latin1
COLLATE=latin1_general_cs;

INSERT INTO t1 VALUES ('user_a');

CREATE VIEW v1 AS
SELECT a <> 0xEE5D FROM t1;

SELECT * FROM v1;
Error 1267 (HY000): Illegal mix of collations (gbk_chinese_ci, IMPLICIT)
and (latin_swedish_ci, COERCIBLE) for operation

```

When the view query is written to file, MariaDB converts the binary character into a string literal, which causes it to be misinterpreted when you execute the `[SELECT](../select/index)` statement. If you encounter this issue, set the character set in the view to force it to the value you want.

 MariaDB throws this error due to a bug that was fixed in [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/). Later releases do not throw errors in this situation.

 
Example: Changing the Default Character Set To UTF-8
----------------------------------------------------

 To change the default character set from latin1 to UTF-8, the following settings should be specified in the my.cnf configuration file.

 
```
[mysql]
...
default-character-set=utf8mb4
...
[mysqld]
...
collation-server = utf8mb4_unicode_ci
init-connect='SET NAMES utf8mb4'
character-set-server = utf8mb4
...

```

Note that the `default-character-set` option is a client option, not a server option.

 See Also
--------

 * [String literals](../string-literals/index)
* [CAST()](../cast/index)
* [CONVERT()](../convert/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-character-sets-and-collations/>

Internationalization and Localization
======================================

  

| Title | Description |
| --- | --- |
|  [Server Locale](../server-locale/index) |  Server locale.  |
|  [Time Zones](../time-zones/index) |  MariaDB time zones.  |
|  [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) |  Specifying the language for the server error messages.  |
|  [Coordinated Universal Time](../coordinated-universal-time/index) |  Coordinated Universal Time.  |
|  [Locales Plugin](../locales-plugin/index) |  List compiled-in locales.  |
|  [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) |  Load time zones into the time zone tables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/internationalization-and-localization/>

Information Schema COLLATIONS Table
===================================

     The [Information Schema](../information_schema/index) `COLLATIONS` table contains a list of supported [collations](../data-types-character-sets-and-collations/index).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `COLLATION_NAME` | Name of the collation. |
| `CHARACTER_SET_NAME` | Associated character set. |
| `ID` | Collation id. |
| `IS_DEFAULT` | Whether the collation is the character set's default. |
| `IS_COMPILED` | Whether the collation is compiled into the server. |
| `SORTLEN` | Sort length, used for determining the memory used to sort strings in this collation. |

 
The [SHOW COLLATION](../show-collation/index) statement returns the same results and both can be reduced in a similar way.

 For example, in [MariaDB 10.6](../what-is-mariadb-106/index), the following two statements return the same results:

 
```
SHOW COLLATION WHERE Charset LIKE 'utf8mb3';

```

and

 
```
SELECT * FROM information_schema.COLLATIONS 
WHERE CHARACTER_SET_NAME LIKE 'utf8mb3';

```

In [MariaDB 10.5](../what-is-mariadb-105/index) and before, `utf8` should be specified instead of `utf8mb3`.

 NO PAD collations
-----------------

 `NO PAD` collations regard trailing spaces as normal characters. You can get a list of all `NO PAD` collations as follows:

 
```
SELECT collation_name FROM information_schema.COLLATIONS
WHERE collation_name LIKE "%nopad%";  
+------------------------------+
| collation_name               |
+------------------------------+
| big5_chinese_nopad_ci        |
| big5_nopad_bin               |
...

```

Example
-------

 
```
SELECT * FROM information_schema.COLLATIONS;
+------------------------------+--------------------+------+------------+-------------+---------+
| COLLATION_NAME               | CHARACTER_SET_NAME | ID   | IS_DEFAULT | IS_COMPILED | SORTLEN |
+------------------------------+--------------------+------+------------+-------------+---------+
| big5_chinese_ci              | big5               |    1 | Yes        | Yes         |       1 |
| big5_bin                     | big5               |   84 |            | Yes         |       1 |
| big5_chinese_nopad_ci        | big5               | 1025 |            | Yes         |       1 |
| big5_nopad_bin               | big5               | 1108 |            | Yes         |       1 |
| dec8_swedish_ci              | dec8               |    3 | Yes        | Yes         |       1 |
| dec8_bin                     | dec8               |   69 |            | Yes         |       1 |
| dec8_swedish_nopad_ci        | dec8               | 1027 |            | Yes         |       1 |
| dec8_nopad_bin               | dec8               | 1093 |            | Yes         |       1 |
| cp850_general_ci             | cp850              |    4 | Yes        | Yes         |       1 |
| cp850_bin                    | cp850              |   80 |            | Yes         |       1 |
...

```

See Also
--------

 * [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) - specifying the character set at the server, database, table and column levels
* [Supported Character Sets and Collations](../supported-character-sets-and-collations/index) - full list of supported characters sets and collations.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-collations-table/>

String Literals
===============

    Strings are sequences of characters and are enclosed with quotes.

 The syntax is:

 
```
[_charset_name]'string' [COLLATE collation_name]

```

For example:

 
```
'The MariaDB Foundation'
_utf8 'Foundation' COLLATE utf8_unicode_ci;

```

Strings can either be enclosed in single quotes or in double quotes (the same character must be used to both open and close the string).

 The ANSI SQL-standard does not permit double quotes for enclosing strings, and although MariaDB does by default, if the MariaDB server has enabled the [ANSI\_QUOTES\_SQL](../sql-mode/index#ansi_quotes) [SQL\_MODE](../sql-mode/index), double quotes will be treated as being used for [identifiers](../identifier-names/index) instead of strings.

 Strings that are next to each other are automatically concatenated. For example:

 
```
'The ' 'MariaDB ' 'Foundation'

```

and

 
```
'The MariaDB Foundation'

```

are equivalent.

 The `\` (backslash character) is used to escape characters (unless the [SQL\_MODE](../sql-mode/index) hasn't been set to [NO\_BACKSLASH\_ESCAPES](../sql-mode/index#no_backslash_escapes)). For example:

 
```
'MariaDB's new features'

```

is not a valid string because of the single quote in the middle of the string, which is treated as if it closes the string, but is actually meant as part of the string, an apostrophe. The backslash character helps in situations like this:

 
```
'MariaDB\'s new features'

```

is now a valid string, and if displayed, will appear without the backslash.

 
```
SELECT 'MariaDB\'s new features';
+------------------------+
| MariaDB's new features |
+------------------------+
| MariaDB's new features |
+------------------------+

```

Another way to escape the quoting character is repeating it twice:

 
```
SELECT 'I''m here', """Double""";
+----------+----------+
| I'm here | "Double" |
+----------+----------+
| I'm here | "Double" |
+----------+----------+

```

Escape Sequences
----------------

 There are other escape sequences also. Here is a full list:

 


| Escape sequence | Character |
| --- | --- |
| `\0` | ASCII NUL (0x00). |
| `\'` | Single quote (“'”). |
| `\"` | Double quote (“"”). |
| `\b` | Backspace. |
| `\n` | Newline, or linefeed,. |
| `\r` | Carriage return. |
| `\t` | Tab. |
| `\Z` | ASCII 26 (Control+Z). See note following the table. |
| `\\` | Backslash (“\”). |
| `\%` | “%” character. See note following the table. |
| `\_` | A “\_” character. See note following the table. |

 
Escaping the `%` and `_` characters can be necessary when using the [LIKE](../like/index) operator, which treats them as special characters.

 The ASCII 26 character (`\Z`) needs to be escaped when included in a batch file which needs to be executed in Windows. The reason is that ASCII 26, in Windows, is the end of file (EOF).

 Backslash (`\`), if not used as an escape character, must always be escaped. When followed by a character that is not in the above table, backslashes will simply be ignored.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/string-literals/>

BINARY
======

    
This page describes the BINARY data type. For details about the operator, see [Binary Operator](../binary-operator/index).

 
Syntax
------

 
```
BINARY(M)

```
 Description
-----------

 The `BINARY` type is similar to the `[CHAR](../char/index)` type, but stores binary byte strings rather than non-binary character strings. `M` represents the column length in bytes.

 It contains no character set, and comparison and sorting are based on the numeric value of the bytes.

 If the maximum length is exceeded, and [SQL strict mode](../sql-mode/index) is not enabled , the extra characters will be dropped with a warning. If strict mode is enabled, an error will occur.

 BINARY values are right-padded with `0x00` (the zero byte) to the specified length when inserted. The padding is *not* removed on select, so this needs to be taken into account when sorting and comparing, where all bytes are significant. The zero byte, `0x00` is less than a space for comparison purposes.

 Examples
--------

 Inserting too many characters, first with strict mode off, then with it on:

 
```
CREATE TABLE bins (a BINARY(10));

INSERT INTO bins VALUES('12345678901');
Query OK, 1 row affected, 1 warning (0.04 sec)

SELECT * FROM bins;
+------------+
| a          |
+------------+
| 1234567890 |
+------------+

SET sql_mode='STRICT_ALL_TABLES';

INSERT INTO bins VALUES('12345678901');
ERROR 1406 (22001): Data too long for column 'a' at row 1

```

Sorting is performed with the byte value:

 
```
TRUNCATE bins;

INSERT INTO bins VALUES('A'),('B'),('a'),('b');

SELECT * FROM bins ORDER BY a;
+------+
| a    |
+------+
| A    |
| B    |
| a    |
| b    |
+------+

```

Using [CAST](../cast/index) to sort as a [CHAR](../char/index) instead:

 
```
SELECT * FROM bins ORDER BY CAST(a AS CHAR);
+------+
| a    |
+------+
| a    |
| A    |
| b    |
| B    |
+------+

```

The field is a BINARY(10), so padding of two '\0's are inserted, causing comparisons that don't take this into account to fail:

 
```
TRUNCATE bins;

INSERT INTO bins VALUES('12345678');

SELECT a = '12345678', a = '12345678\0\0' from bins;
+----------------+--------------------+
| a = '12345678' | a = '12345678\0\0' |
+----------------+--------------------+
|              0 |                  1 |
+----------------+--------------------+

```

See Also
--------

 * [CHAR](../char/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary/>

SET NAMES
=========

    Syntax
------

 
```
SET NAMES {'charset_name'
    [COLLATE 'collation_name'] | DEFAULT}

```
 Description
-----------

 Sets the [character\_set\_client](../server-system-variables/index#character_set_client), [character\_set\_connection](../server-system-variables/index#character_set_connection), [character\_set\_results](../server-system-variables/index#character_set_results) and, implicitly, the [collation\_connection](../server-system-variables/index#collation_connection) session system variables to the specified character set and collation.

 This determines which [character set](../character-sets/index) the client will use to send statements to the server, and the server will use for sending results back to the client. 

 `ucs2`, `utf16`, `utf16le` and `utf32` are not valid character sets for `SET NAMES`, as they cannot be used as client character sets. 

 The collation clause is optional. If not defined (or if `DEFAULT` is specified), the [default collation for the character set](../supported-character-sets-and-collations/index) will be used.

 Quotes are optional for the character set or collation clauses.

 Examples
--------

 
```
SELECT VARIABLE_NAME, SESSION_VALUE 
  FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME LIKE 'character_set_c%' OR 
  VARIABLE_NAME LIKE 'character_set_re%' OR 
  VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-----------------+
| VARIABLE_NAME            | SESSION_VALUE   |
+--------------------------+-----------------+
| CHARACTER_SET_RESULTS    | utf8            |
| CHARACTER_SET_CONNECTION | utf8            |
| CHARACTER_SET_CLIENT     | utf8            |
| COLLATION_CONNECTION     | utf8_general_ci |
+--------------------------+-----------------+

SET NAMES big5;

SELECT VARIABLE_NAME, SESSION_VALUE 
  FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME LIKE 'character_set_c%' OR 
  VARIABLE_NAME LIKE 'character_set_re%' OR 
  VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-----------------+
| VARIABLE_NAME            | SESSION_VALUE   |
+--------------------------+-----------------+
| CHARACTER_SET_RESULTS    | big5            |
| CHARACTER_SET_CONNECTION | big5            |
| CHARACTER_SET_CLIENT     | big5            |
| COLLATION_CONNECTION     | big5_chinese_ci |
+--------------------------+-----------------+

SET NAMES 'latin1' COLLATE 'latin1_bin';

SELECT VARIABLE_NAME, SESSION_VALUE 
  FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME LIKE 'character_set_c%' OR 
  VARIABLE_NAME LIKE 'character_set_re%' OR 
  VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+---------------+
| VARIABLE_NAME            | SESSION_VALUE |
+--------------------------+---------------+
| CHARACTER_SET_RESULTS    | latin1        |
| CHARACTER_SET_CONNECTION | latin1        |
| CHARACTER_SET_CLIENT     | latin1        |
| COLLATION_CONNECTION     | latin1_bin    |
+--------------------------+---------------+

SET NAMES DEFAULT;

SELECT VARIABLE_NAME, SESSION_VALUE 
  FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME LIKE 'character_set_c%' OR 
  VARIABLE_NAME LIKE 'character_set_re%' OR 
  VARIABLE_NAME LIKE 'collation_c%';
+--------------------------+-------------------+
| VARIABLE_NAME            | SESSION_VALUE     |
+--------------------------+-------------------+
| CHARACTER_SET_RESULTS    | latin1            |
| CHARACTER_SET_CONNECTION | latin1            |
| CHARACTER_SET_CLIENT     | latin1            |
| COLLATION_CONNECTION     | latin1_swedish_ci |
+--------------------------+-------------------+

```

See Also
--------

 * [SET CHARACTER SET](../set-character-set/index)
* [Character Sets and Collations](../character-sets/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-names/>

BLOB
====

    Syntax
------

 
```
BLOB[(M)]

```
 Description
-----------

 A `BLOB` column with a maximum length of `65,535` (`216 - 1`) bytes. Each `BLOB` value is stored using a two-byte length prefix that indicates the number of bytes in the value.

 An optional length `M` can be given for this type. If this is done, MariaDB creates the column as the smallest `BLOB` type large enough to hold values *`M`* bytes long.

 BLOBS can also be used to store [dynamic columns](../dynamic-columns/index).

 `BLOB` and `TEXT` columns can both be assigned a [DEFAULT](../create-table/index#default) value.

 ### Indexing

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**From [MariaDB 10.4](../what-is-mariadb-104/index), it is possible to set a [unique index](../getting-started-with-indexes/index#unique-index) on a column that uses the `BLOB` data type. In previous releases this was not possible, as the index would only guarantee the uniqueness of a fixed number of characters.

 
### Oracle Mode

 In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `BLOB` is a synonym for `LONGBLOB`.

 See Also
--------

 * [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/blob/>

CHAR BYTE
=========

    Description
-----------

 The `CHAR BYTE` data type is an alias for the `[BINARY](../binary/index)` data type. This is a compatibility feature.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/char-byte/>

Information Schema CHARACTER\_SETS Table
========================================

    The [Information Schema](../information_schema/index) `CHARACTER_SETS` table contains a list of supported [character sets](../data-types-character-sets-and-collations/index), their default collations and maximum lengths.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CHARACTER_SET_NAME` | Name of the character set. |
| `DEFAULT_COLLATE_NAME` | Default collation used. |
| `DESCRIPTION` | Character set description. |
| `MAXLEN` | Maximum length. |

 
The [SHOW CHARACTER SET](../show-character-set/index) statement returns the same results (although in a different order), and both can be refined in the same way. For example, the following two statements return the same results:

 
```
SHOW CHARACTER SET WHERE Maxlen LIKE '2';

```

and

 
```
SELECT * FROM information_schema.CHARACTER_SETS 
WHERE MAXLEN LIKE '2';

```

See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on specifying the character set at the server, database, table and column levels, and [Supported Character Sets and Collations](../supported-character-sets-and-collations/index) for a full list of supported characters sets and collations.

 Example
-------

 
```
SELECT CHARACTER_SET_NAME FROM information_schema.CHARACTER_SETS 
WHERE DEFAULT_COLLATE_NAME LIKE '%chinese%';
+--------------------+
| CHARACTER_SET_NAME |
+--------------------+
| big5               |
| gb2312             |
| gbk                |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-character_sets-table/>

BLOB and TEXT Data Types
========================

    Description
-----------

 A `BLOB` is a binary large object that can hold a variable amount of data. The four `BLOB` types are 

 * [TINYBLOB](../sql_language-data_types-tinyblob/index),
* [BLOB](../sql_language-data_types-blob/index),
* [MEDIUMBLOB](../sql_language-data_types-mediumblob/index), and
* [LONGBLOB](../sql_language-data_types-longblob/index).

 These differ only in the maximum length of the values they can hold. 

 The `TEXT` types are 

 * [TINYTEXT](../sql_language-data_types-tinytext/index),
* [TEXT](../sql_language-data_types-text/index),
* [MEDIUMTEXT](../sql_language-data_types-mediumtext/index), and
* [LONGTEXT](../sql_language-data_types-longtext/index).
* [JSON](../json-data-type/index) (alias for LONGTEXT)

 These correspond to the four `BLOB` types and have the same maximum lengths and [storage requirements](../data-type-storage-requirements/index).

 `BLOB` and `TEXT` columns can have a `DEFAULT` value.

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**From [MariaDB 10.4](../what-is-mariadb-104/index), it is possible to set a [unique index](../getting-started-with-indexes/index#unique-index) on columns that use the `BLOB` or `TEXT` data types.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/blob-and-text-data-types/>

CHAR
====

    This article covers the CHAR data type. See [CHAR Function](../char-function/index) for the function.

 Syntax
------

 
```
[NATIONAL] CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

```
 Description
-----------

 A fixed-length string that is always right-padded with spaces to the specified length when stored. `M` represents the column length in characters. The range of `M` is `0` to `255`. If `M` is omitted, the length is `1`.

 CHAR(0) columns can contain 2 values: an empty string or NULL. Such columns cannot be part of an index. The [CONNECT](../connect/index) storage engine does not support CHAR(0).

 **Note:** Trailing spaces are removed when `CHAR` values are retrieved unless the `PAD_CHAR_TO_FULL_LENGTH` [SQL mode](../sql_mode/index) is enabled.

 Before [MariaDB 10.2](../what-is-mariadb-102/index), all collations were of type PADSPACE, meaning that CHAR (as well as [VARCHAR](../varchar/index) and [TEXT](../text/index)) values are compared without regard for trailing spaces. This does not apply to the [LIKE](../like/index) pattern-matching operator, which takes into account trailing spaces.

 If a unique index consists of a column where trailing pad characters are stripped or ignored, inserts into that column where values differ only by the number of trailing pad characters will result in a duplicate-key error.

 Examples
--------

 Trailing spaces:

 
```
CREATE TABLE strtest (c CHAR(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT c='Maria',c='Maria   ' FROM strtest;
+-----------+--------------+
| c='Maria' | c='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT c LIKE 'Maria',c LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| c LIKE 'Maria' | c LIKE 'Maria   ' |
+----------------+-------------------+
|              1 |                 0 |
+----------------+-------------------+

```

NO PAD Collations
-----------------

 NO PAD collations regard trailing spaces as normal characters. You can get a list of all NO PAD collations by querying the [Information Schema Collations table](../information-schema-collations-table/index), for example:

 
```
SELECT collation_name FROM information_schema.collations 
  WHERE collation_name LIKE "%nopad%";  
+------------------------------+
| collation_name               |
+------------------------------+
| big5_chinese_nopad_ci        |
| big5_nopad_bin               |
...

```

See Also
--------

 * [CHAR Function](../char-function/index)
* [VARCHAR](../varchar/index)
* [BINARY](../binary/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/char/>

ENUM
====

    Syntax
------

 
```
ENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]

```
 Description
-----------

 An enumeration. A string object that can have only one value, chosen from the list of values 'value1', 'value2', ..., NULL or the special '' error value. In theory, an `ENUM` column can have a maximum of 65,535 distinct values; in practice, the real maximum depends on many factors. `ENUM` values are represented internally as integers.

 Trailing spaces are automatically stripped from ENUM values on table creation.

 ENUMs require relatively little storage space compared to strings, either one or two bytes depending on the number of enumeration values.

 ### NULL and empty values

 An ENUM can also contain NULL and empty values. If the ENUM column is declared to permit NULL values, NULL becomes a valid value, as well as the default value (see below). If [strict SQL Mode](../sql_mode/index) is not enabled, and an invalid value is inserted into an ENUM, a special empty string, with an index value of zero (see Numeric index, below), is inserted, with a warning. This may be confusing, because the empty string is also a possible value, and the only difference if that is this case its index is not 0. Inserting will fail with an error if strict mode is active.

 If a `DEFAULT` clause is missing, the default value will be:

 * `NULL` if the column is nullable;
* otherwise, the first value in the enumeration.

 ### Numeric index

 ENUM values are indexed numerically in the order they are defined, and sorting will be performed in this numeric order. We suggest not using ENUM to store numerals, as there is little to no storage space benefit, and it is easy to confuse the enum integer with the enum numeral value by leaving out the quotes.

 An ENUM defined as ENUM('apple','orange','pear') would have the following index values:

 


| Index | Value |
| --- | --- |
| NULL | NULL |
| 0 | '' |
| 1 | 'apple' |
| 2 | 'orange' |
| 3 | 'pear' |

 
Examples
--------

 
```
CREATE TABLE fruits (
  id INT NOT NULL auto_increment PRIMARY KEY,
  fruit ENUM('apple','orange','pear'),
  bushels INT);

DESCRIBE fruits;
+---------+-------------------------------+------+-----+---------+----------------+
| Field   | Type                          | Null | Key | Default | Extra          |
+---------+-------------------------------+------+-----+---------+----------------+
| id      | int(11)                       | NO   | PRI | NULL    | auto_increment |
| fruit   | enum('apple','orange','pear') | YES  |     | NULL    |                |
| bushels | int(11)                       | YES  |     | NULL    |                |
+---------+-------------------------------+------+-----+---------+----------------+

INSERT INTO fruits
    (fruit,bushels) VALUES
    ('pear',20),
    ('apple',100),
    ('orange',25);

INSERT INTO fruits
    (fruit,bushels) VALUES
    ('avocado',10);
ERROR 1265 (01000): Data truncated for column 'fruit' at row 1

SELECT * FROM fruits;
+----+--------+---------+
| id | fruit  | bushels |
+----+--------+---------+
|  1 | pear   |      20 |
|  2 | apple  |     100 |
|  3 | orange |      25 |
+----+--------+---------+

```

Selecting by numeric index:

 
```
SELECT * FROM fruits WHERE fruit=2;
+----+--------+---------+
| id | fruit  | bushels |
+----+--------+---------+
|  3 | orange |      25 |
+----+--------+---------+

```

Sorting is according to the index value:

 
```
CREATE TABLE enums (a ENUM('2','1'));

INSERT INTO enums VALUES ('1'),('2');

SELECT * FROM enums ORDER BY a ASC;
+------+
| a    |
+------+
| 2    |
| 1    |
+------+

```

It's easy to get confused between returning the enum integer with the stored value, so we don't suggest using ENUM to store numerals. The first example returns the 1st indexed field ('2' has an index value of 1, as it's defined first), while the second example returns the string value '1'.

 
```
SELECT * FROM enums WHERE a=1;
+------+
| a    |
+------+
| 2    |
+------+

SELECT * FROM enums WHERE a='1';
+------+
| a    |
+------+
| 1    |
+------+

```

See Also
--------

 * [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/enum/>

SET CHARACTER SET
=================

    Syntax
------

 
```
SET {CHARACTER SET | CHARSET}
    {charset_name | DEFAULT}

```

Description
-----------

 Sets the [character\_set\_client](../server-system-variables/index#character_set_client) and [character\_set\_results](../server-system-variables/index#character_set_results) session system variables to the specified character set and [collation\_connection](../server-system-variables/index#collation_connection) to the value of [collation\_database](../server-system-variables/index#collation_database), which implicitly sets [character\_set\_connection](../server-system-variables/index#character_set_connection) to the value of [character\_set\_database](../server-system-variables/index#character_set_database).

 This maps all strings sent between the current client and the server with the given mapping.

 Example
-------

 
```
SHOW VARIABLES LIKE 'character_set\_%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | utf8   |
| character_set_connection | utf8   |
| character_set_database   | latin1 |
| character_set_filesystem | binary |
| character_set_results    | utf8   |
| character_set_server     | latin1 |
| character_set_system     | utf8   |
+--------------------------+--------+

SHOW VARIABLES LIKE 'collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | utf8_general_ci   |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

SET CHARACTER SET utf8mb4;

SHOW VARIABLES LIKE 'character_set\_%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_client     | utf8mb4 |
| character_set_connection | latin1  |
| character_set_database   | latin1  |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | latin1  |
| character_set_system     | utf8    |
+--------------------------+---------+

SHOW VARIABLES LIKE 'collation%';
+----------------------+-------------------+
| Variable_name        | Value             |
+----------------------+-------------------+
| collation_connection | latin1_swedish_ci |
| collation_database   | latin1_swedish_ci |
| collation_server     | latin1_swedish_ci |
+----------------------+-------------------+

```

See Also
--------

 * [SET NAMES](../set-names/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-character-set/>

MEDIUMBLOB
==========

    Syntax
------

 
```
MEDIUMBLOB

```

Description
-----------

 A [BLOB](../blob/index) column with a maximum length of 16,777,215 (224 - 1) bytes. Each MEDIUMBLOB value is stored using a three-byte length prefix that indicates the number of bytes in the value. 

 See Also
--------

 * [BLOB](../blob/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mediumblob/>

mariadb-slap
============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-slap` is a symlink to `mysqlslap`, the tool for load-testing MariaDB.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysqlslap` is the symlink, and `mariadb-slap` the binary name.

 
 `mariadb-slap` is a tool for load-testing MariaDB. It allows you to emulate multiple concurrent connections, and run a set of queries multiple times.

 It returns a benchmark including the following information:

 * Average number of seconds to run all queries
* Minimum number of seconds to run all queries
* Maximum number of seconds to run all queries
* Number of clients running queries
* Average number of queries per client

 Using mariadb-slap
------------------

 The command to use `mariadb-slap` and the general syntax is:

 
```
mariadb-slap [options]

```

### Options

 `mariadb-slap` supports the following options:

 


| Option | Description |
| --- | --- |
| `-a`, `--auto-generate-sql` | Generate SQL statements automatically when they are not supplied in files or via command options. |
| `--auto-generate-sql-add-autoincrement` | Add an [AUTO\_INCREMENT](../auto_increment/index) column to auto-generated tables. |
| `--auto-generate-sql-execute-number=num` | Specify how many queries to generate automatically. |
| `--auto-generate-sql-guid-primary` | Add GUID based primary keys to auto-generated tables. |
| `--auto-generate-sql-load-type=name`  | Specify the test load type. The allowable values are `read` (scan tables), `write` (insert into tables), `key` (read primary keys), `update` (update primary keys), or `mixed` (half inserts, half scanning selects). The default is mixed. |
| `--auto-generate-sql-secondary-indexes=num` | Number of secondary indexes to add to auto-generated tables. By default, none are added. |
| `--auto-generate-sql-unique-query-number=num` | Number of unique queries to generate for automatic tests. For example, if you run a key test that performs 1000 selects, you can use this option with a value of 1000 to run 1000 unique queries, or with a value of 50 to perform 50 different selects. The default is 10. |
| `--auto-generate-sql-unique-write-number=num` | Number of unique queries to generate for `auto-generate-sql-write-number`. |
| `--auto-generate-sql-write-number=num` | Number of row inserts to perform for each thread. The default is 100. |
| `--commit=num` | Number of statements to execute before committing. The default is 0. |
| `-C`, `--compress` | Use compression in server/client protocol if both support it. |
| `-c name`, `--concurrency=name` | Number of clients to simulate for query to run. |
| `--create=name` | File or string containing the statement to use for creating the table. |
| `--create-schema=name` | Schema to run tests in. |
| `--csv[=name]` | Generate comma-delimited output to named file or to standard output if no file is named. |
| `-#` , `--debug[=options]` | For debug builds, write a debugging log. A typical debug\_options string is `d:t:o,file_name`. The default is `d:t:o,/tmp/mariadb-slap.trace`. |
| `--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. |
| `--defaults-extra-file=name` | Read this file after the global files are read. Must be given as the first option. |
| `--defaults-file=name` | Only read default options from the given file *name* Must be given as the first option. |
| `-F name`, `--delimiter=name` | Delimiter to use in SQL statements supplied in file or command line. |
| `--detach=num` | Detach (close and reopen) connections after the specified number of requests. The default is 0 (connections are not detached). |
| `-e name`, `--engine=name` | Comma separated list of storage engines to use for creating the table. The test is run for each engine. You can also specify an option for an engine after a #:#, for example `memory:max_row=2300`. |
| `-?`, `--help` | Display help and exit. |
| `-h name`, `--host=name` | Connect to the MariaDB server on the given host. |
| `--init-command=name` | SQL Command to execute when connecting to the MariaDB server. Will automatically be re-executed when reconnecting. Added in [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/). |
| `-i num`, `--iterations=num` | Number of times to run the tests. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first option. |
| `--no-drop` | Do not drop any schema created during the test after the test is complete. |
| `-x name`, `--number-char-cols=name` | Number of [VARCHAR](../varchar/index) columns to create in table if specifying `--auto-generate-sql`. |
| `-y name`, `--number-int-cols=name` | Number of [INT](../int/index) columns to create in table if specifying `--auto-generate-sql`. |
| `--number-of-queries=num` | Limit each client to approximately this number of queries. Query counting takes into account the statement delimiter. For example, if you invoke as follows, `mariadb-slap --delimiter=";" --number-of-queries=10`  `--query="use test;insert into t values(null)"`, the #;# delimiter is recognized so that each instance of the query string counts as two queries. As a result, 5 rows (not 10) are inserted. |
| `--only-print` | Do not connect to the databases, but instead print out what would have been done. |
| `-p[password]`, `--password[=password]` | Password to use when connecting to server. If password is not given it's asked from the command line. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `-W`, `--pipe` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `--plugin-dir=name` | Directory for client-side plugins. |
| `-P num`, `--port=num` | Port number to use for connection. |
| `--post-query=name` | Query to run or file containing query to execute after tests have completed. This execution is not counted for timing purposes. |
| `--post-system=name` | system() string to execute after tests have completed. This execution is not counted for timing purposes. |
| `--pre-query=name` | Query to run or file containing query to execute before running tests. This execution is not counted for timing purposes. |
| `--pre-system=name` | system() string to execute before running tests. This execution is not counted for timing purposes. |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first option. |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `-q name`, `--query=name` | Query to run or file containing query to run. |
| `--shared-memory-base-name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. |
| `-s`, `--silent` | Run program in silent mode - no output. |
| `-S`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. The `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `-u`, `--user=name` | User for login if not current user. |
| `-v`, `--verbose` | More verbose output; you can use this multiple times to get even more verbose output. |
| `-V`, `--version` | Output version information and exit. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-slap` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-slap` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
`mariadb-slap` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb-slap` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqlslap]` |  Options read by `mariadb-slap`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-slap]` | Options read by `mariadb-slap`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
Examples
--------

 Create a table with data, and then query it with 40 simultaneous connections 100 times each.

 
```
mariadb-slap 
 --delimiter=";" 
 --create="CREATE TABLE t (a int);INSERT INTO t VALUES (5)"
 --query="SELECT * FROM t"
 --concurrency=40
 --iterations=100

Benchmark
	Average number of seconds to run all queries: 0.010 seconds
	Minimum number of seconds to run all queries: 0.009 seconds
	Maximum number of seconds to run all queries: 0.020 seconds
	Number of clients running queries: 40
	Average number of queries per client: 1

```

Using files to store the create and query SQL. Each file can contain multiple statements separated by the specified delimiter.

 
```
mariadb-slap
 --create=define.sql
 --query=query.sql
 --concurrency=10
 --iterations=20
 --delimiter=";"

Benchmark
	Average number of seconds to run all queries: 0.002 seconds
	Minimum number of seconds to run all queries: 0.002 seconds
	Maximum number of seconds to run all queries: 0.004 seconds
	Number of clients running queries: 10
	Average number of queries per client: 1

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-slap/>

MEDIUMTEXT
==========

    Syntax
------

 
```
MEDIUMTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

```

Description
-----------

 A [TEXT](../text/index) column with a maximum length of 16,777,215 (`224 - 1`) characters. The effective maximum length is less if the value contains multi-byte characters. Each MEDIUMTEXT value is stored using a three-byte length prefix that indicates the number of bytes in the value.

 See Also
--------

 * [TEXT](../text/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mediumtext/>

LONGBLOB
========

    Syntax
------

 
```
LONGBLOB

```

Description
-----------

 A [BLOB](../blob/index) column with a maximum length of 4,294,967,295 bytes or 4GB (232 - 1). The effective maximum length of LONGBLOB columns depends on the configured maximum packet size in the client/server protocol and available memory. Each LONGBLOB value is stored using a four-byte length prefix that indicates the number of bytes in the value.

 ### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `BLOB` is a synonym for `LONGBLOB`.

 
See Also
--------

 * [BLOB](../blob/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/longblob/>

LONGTEXT
========

    Syntax
------

 
```
LONGTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

```
 Description
-----------

 A [TEXT](../text/index) column with a maximum length of 4,294,967,295 or 4GB (`232 - 1`) characters. The effective maximum length is less if the value contains multi-byte characters. The effective maximum length of LONGTEXT columns also depends on the configured maximum packet size in the client/server protocol and available memory. Each LONGTEXT value is stored using a four-byte length prefix that indicates the number of bytes in the value.

 From [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), JSON is an alias for LONGTEXT. See [JSON Data Type](../json-data-type/index) for details.

 Oracle Mode
-----------

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `CLOB` is a synonym for `LONGTEXT`.

 
See Also
--------

 * [TEXT](../text/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [JSON Data Type](../json-data-type/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/longtext/>

INET4
=====

    
**MariaDB starting with [10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/)**The INET4 data type was added in [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/)

 
Syntax
------

 
```
INET4

```
 Description
-----------

 `INET4` is a data type to store IPv4 addresses, as 4-byte binary strings.

 Examples
--------

 
```
CREATE OR REPLACE TABLE t1 (a INET4);

INSERT INTO t1 VALUES('0.0.0.0'), ('255.10.0.0'), ('255.255.255.255');

INSERT INTO t1 VALUES (0xa0000001);
INSERT INTO t1 VALUES (0xf0000000);
INSERT INTO t1 VALUES (0xff000001);

SELECT HEX(a), a FROM t1 ORDER BY a;
+----------+-----------------+
| HEX(a)   | a               |
+----------+-----------------+
| 00000000 | 0.0.0.0         |
| A0000001 | 160.0.0.1       |
| F0000000 | 240.0.0.0       |
| FF000001 | 255.0.0.1       |
| FF0A0000 | 255.10.0.0      |
| FFFFFFFF | 255.255.255.255 |
+----------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet4/>

INET6
=====

    
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**The INET6 data type was added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 
Syntax
------

 
```
INET6

```
 Description
-----------

 The `INET6` data type is intended for storage of IPv6 addresses, as well as IPv4 addresses assuming conventional mapping of IPv4 addresses into IPv6 addresses.

 Both short and long IPv6 notation are permitted, according to RFC-5952.

 * Values are stored as a 16-byte fixed length binary string, with most significant byte first.
* Storage engines see INET6 as BINARY(16).
* Clients see INET6 as CHAR(39) and get text representation on retrieval.

 The IPv4-compatible notation is considered as deprecated. It is supported for compatibility with the [INET6\_ATON](../inet6_aton/index) function, which also understands this format. It's recommended to use the mapped format to store IPv4 addresses in INET6.

 When an IPv4 mapped (or compatible) value is stored in INET6, it still occupies 16 bytes:

 ### Retrieval

 On retrieval, in the client-server text protocol, INET6 values are converted to the short text representation, according to RFC-5952, that is with all leading zeroes in each group removed and with consequent zero groups compressed.

 Besides creating one's own [stored function](../stored-functions/index), there is no a way to retrieve an INET6 value using long text representation.

 ### Casting

 * [CAST](../cast/index) from a character string to INET6 understands addresses in short or long text notation (including IPv4 mapped and compatible addresses). NULL is returned if the format is not understood.
* CAST from a binary string to INET6 requires a 16-byte string as an argument. NULL is returned if the argument length is not equal to 16.
* CAST from other data types to INET6 first converts data to a character string, then CAST from character string to INET6 is applied.
* CAST from INET6 to [CHAR](../char/index) returns short text address notation.
* CAST from INET6 to [BINARY](../binary/index) returns its 16-byte binary string representation.
* CAST from INET6 to data types other than [CHAR](../char/index) (e.g. SIGNED, UNSIGNED, TIME, etc) returns an error.

 ### Comparisons

 An INET6 expression can be compared to:

 * another INET6 expression
* a character string expression with a text (short or long) address representation:
* a 16-byte binary string expression:

 Attempting to compare INET6 to an expression of any other data type returns an error.

 ### Mixing INET6 Values for Result

 An INET6 expression can be mixed for result (i.e. [UNION](../union/index), [CASE..THEN](case), [COALESCE](../coalesce/index) etc) with:

 * another INET6 expression. The resulting data type is INET6.
* a character string in text (short or long) address representation. The result data type is INET6. The character string counterpart is automatically converted to INET6. If the string format is not understood, it's converted with a warning to either NULL or to '::', depending on the NULL-ability of the result.
* a 16-byte binary string. The resulting data type is INET6. The binary string counterpart is automatically converted to INET6. If the length of the binary string is not equal to 16, it's converted with a warning to NULL or to '::' depending on the NULL-ability of the result.

 Attempts to mix INET6 for result with other data types will return an error.

 Mixing INET6 with other data types for [LEAST](../least/index) and [GREATEST](../greatest/index), when mixing for comparison and mixing for result are involved at the same time, uses the same rules with mixing for result, described in the previous paragraphs.

 ### Functions and Operators

 * [HEX()](../hex/index) with an INET6 argument returns a hexadecimal representation of the underlying 16-byte binary string
* Arithmetic operators (+,-,\*,/,MOD,DIV) are not supported for INET6. This may change in the future.
* The [INET6\_ATON](../inet6_aton/index) function now understands INET6 values as an argument
* The prototypes of the [IS\_IPV4\_COMPAT](../is_ipv4_compat/index) and I[S\_IPV4\_MAPPED](../is_ipv4_mapped/index) functions have changed from `a BINARY(16)` to `a INET6`,
* When the argument for these two functions is not INET6, automatic implicit CAST to INET6 is applied. As a consequence, both functions now understand arguments in both text representation and binary(16) representation. Before [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), these functions understood only binary(16) representation.

 ### Prepared Statement Parameters

 INET6 understands both [text](../text/index) and [binary(16)](../binary/index) address representation in [prepared statement](../prepared-statements/index) parameters ([PREPARE](../prepare-statement/index)..[EXECUTE](../execute-statement/index) and [EXECUTE IMMEDIATE](../execute-immediate/index) statements).

 ### Migration between BINARY(16) and INET6

 Before [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), you may have used [BINARY(16)](../binary/index) as a storage for IPv6 internet addresses, in combination with [INET6\_ATON](../inet6_aton/index) and [INET6\_NTOA](../inet6_ntoa/index) to respectively insert and retrieve data.

 From 10.5, you can [ALTER](../alter-table/index) BINARY(16) columns storing IPv6 addresses to INET6. After such an alter, there is no a need to use INET6\_ATON() and INET6\_NTOA(). Addresses can be inserted and retrieved directly.

 It is also possible to convert INET6 columns to BINARY(16) and continue using the data in combination with INET6\_NTOA() and INET6\_ATON().

 Examples
--------

 
```
CREATE TABLE t1 (a INET6);

```

Inserting using short text address notation:

 
```
INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

```

Long text address notation:

 
```
INSERT INTO t1 VALUES ('2001:0db8:0000:0000:0000:ff00:0042:8329');

```

16-byte binary string notation:

 
```
INSERT INTO t1 VALUES (0x20010DB8000000000000FF0000428329);
INSERT INTO t1 VALUES (UNHEX('20010DB8000000000000FF0000428329'));

```

IPv4 addresses, using IPv4-mapped and IPv4-compatible notations:

 
```
INSERT INTO t1 VALUES ('::ffff:192.0.2.128'); -- mapped
INSERT INTO t1 VALUES ('::192.0.2.128'); -- compatible

```


```
SELECT * FROM t1;
+------------------------+
| a                      |
+------------------------+
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| 2001:db8::ff00:42:8329 |
| ::ffff:192.0.2.128     |
| ::192.0.2.128          |
+------------------------+

```

IPv4 mapped (or compatible) values still occupy 16 bytes:

 
```
CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('::ffff:192.0.2.128');

SELECT * FROM t1;
+--------------------+
| a                  |
+--------------------+
| ::ffff:192.0.2.128 |
+--------------------+

SELECT HEX(a) FROM t1;
+----------------------------------+
| HEX(a)                           |
+----------------------------------+
| 00000000000000000000FFFFC0000280 |
+----------------------------------+

```

Casting from INET6 to anything other than [CHAR](../char/index) returns an error:

 
```
SELECT CAST(a AS DECIMAL) FROM t1;

ERROR 4079 (HY000): Illegal parameter data type inet6 for operation 'decimal_typecast'

```

### Comparison Examples

  Comparison with another INET6 expression:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6);
    CREATE OR REPLACE TABLE t2 (a INET6);

    INSERT INTO t1 VALUES ('2001:db8::ff00:42:8328'),('2001:db8::ff00:42:8329');
    INSERT INTO t2 VALUES ('2001:db8::ff00:42:832a'),('2001:db8::ff00:42:8329');

    SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a;
    +------------------------+
    | a                      |
    +------------------------+
    | 2001:db8::ff00:42:8329 |
    +------------------------+

```

With a character string expression with a text (short or long) address representation:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6);

    INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

    SELECT * FROM t1 WHERE a='2001:db8::ff00:42:8329';
    +------------------------+
    | a                      |
    +------------------------+
    | 2001:db8::ff00:42:8329 |
    +------------------------+

```

With a 16-byte binary string expression:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6);

    INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

    SELECT * FROM t1 WHERE a=X'20010DB8000000000000FF0000428329';
    +------------------------+
    | a                      |
    +------------------------+
    | 2001:db8::ff00:42:8329 |
    +------------------------+

```

With an expression of another data type:

 
```
SELECT * FROM t1 WHERE a=1;
ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation '='

```

### Mixing for Result Examples

 Mixed with another INET6 expression, returning an INET6 data type:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6, b INET6);

    INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8329');

    SELECT a FROM t1 UNION SELECT b FROM t1;
    +------------------------+
    | a                      |
    +------------------------+
    | NULL                   |
    | 2001:db8::ff00:42:8329 |
    +------------------------+

    SELECT COALESCE(a, b) FROM t1;
    +------------------------+
    | COALESCE(a, b)         |
    +------------------------+
    | 2001:db8::ff00:42:8329 |
    +------------------------+

```

 Mixed with a character string in text (short or long) address representation:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6, b VARCHAR(64));

    INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:8328');

    INSERT INTO t1 VALUES (NULL,'2001:db8::ff00:42:832a garbage');

    SELECT COALESCE(a,b) FROM t1;
    +------------------------+
    | COALESCE(a,b)          |
    +------------------------+
    | 2001:db8::ff00:42:8328 |
    | NULL                   |
    +------------------------+
    2 rows in set, 1 warning (0.001 sec)

    SHOW WARNINGS;
    +---------+------+---------------------------------------------------------+
    | Level   | Code | Message                                                 |
    +---------+------+---------------------------------------------------------+
    | Warning | 1292 | Incorrect inet6 value: '2001:db8::ff00:42:832a garbage' |
    +---------+------+---------------------------------------------------------+

```

Mixed with a 16-byte binary string:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6, b VARBINARY(16));

    INSERT INTO t1 VALUES (NULL,CONCAT(0xFFFF,REPEAT(0x0000,6),0xFFFF));

    INSERT INTO t1 VALUES (NULL,0x00/*garbage*/);

    SELECT COALESCE(a,b) FROM t1;
    +---------------+
    | COALESCE(a,b) |
    +---------------+
    | ffff::ffff    |
    | NULL          |
    +---------------+
    2 rows in set, 1 warning (0.001 sec)

    SHOW WARNINGS;
    +---------+------+-------------------------------+
    | Level   | Code | Message                       |
    +---------+------+-------------------------------+
    | Warning | 1292 | Incorrect inet6 value: '\x00' |
    +---------+------+-------------------------------+

```

Mixing with other data types:

 
```
SELECT CAST('ffff::ffff' AS INET6) UNION SELECT 1;
ERROR 4078 (HY000): Illegal parameter data types inet6 and int for operation 'UNION'

```

### Functions and Operators Examples

 [HEX](../hex/index) with an INET6 argument returning a hexadecimal representation:

 
```
    SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));
    +----------------------------------------------+
    | HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
    +----------------------------------------------+
    | 20010DB8000000000000FF0000428329             |
    +----------------------------------------------+

```

[INET6\_ATON](../inet6_aton/index) now understands INET6 values as an argument:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6);

    INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');

    SELECT a, HEX(INET6_ATON(a)) FROM t1;
    +------------------------+----------------------------------+
    | a                      | HEX(INET6_ATON(a))               |
    +------------------------+----------------------------------+
    | 2001:db8::ff00:42:8329 | 20010DB8000000000000FF0000428329 |
    +------------------------+----------------------------------+

```

[IS\_IPV4\_COMPAT](../is_ipv4_compat/index) and [IS\_IPV4\_MAPPED](../is_ipv4_mapped/index) prototype now `a BINARY(16))`:

 
```
    CREATE OR REPLACE TABLE t1 (a INET6);

    INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
    INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
    INSERT INTO t1 VALUES ('::192.168.0.1');

    SELECT a, IS_IPV4_MAPPED(a), IS_IPV4_COMPAT(a) FROM t1;
    +------------------------+-------------------+-------------------+
    | a                      | IS_IPV4_MAPPED(a) | IS_IPV4_COMPAT(a) |
    +------------------------+-------------------+-------------------+
    | 2001:db8::ff00:42:8329 |                 0 |                 0 |
    | ::ffff:192.168.0.1     |                 1 |                 0 |
    | ::192.168.0.1          |                 0 |                 1 |
    +------------------------+-------------------+-------------------+

```

Automatic implicit CAST to INET6:

 
```
    CREATE OR REPLACE TABLE t1 (
      a INET6,
      b VARCHAR(39) DEFAULT a
    );

    INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');

    SELECT a, IS_IPV4_MAPPED(a), b, IS_IPV4_MAPPED(b) FROM t1;
    +--------------------+-------------------+--------------------+-------------------+
    | a                  | IS_IPV4_MAPPED(a) | b                  | IS_IPV4_MAPPED(b) |
    +--------------------+-------------------+--------------------+-------------------+
    | ffff::ffff         |                 0 | ffff::ffff         |                 0 |
    | ::ffff:192.168.0.1 |                 1 | ::ffff:192.168.0.1 |                 1 |
    +--------------------+-------------------+--------------------+-------------------+

    CREATE OR REPLACE TABLE t1 (
      a INET6,
      b BINARY(16) DEFAULT UNHEX(HEX(a))
    );

    INSERT INTO t1 (a) VALUES ('ffff::ffff'),('::ffff:192.168.0.1');

    SELECT a, IS_IPV4_MAPPED(a), HEX(b), IS_IPV4_MAPPED(b) FROM t1;
    +--------------------+-------------------+----------------------------------+-------------------+
    | a                  | IS_IPV4_MAPPED(a) | HEX(b)                           | IS_IPV4_MAPPED(b) |
    +--------------------+-------------------+----------------------------------+-------------------+
    | ffff::ffff         |                 0 | FFFF000000000000000000000000FFFF |                 0 |
    | ::ffff:192.168.0.1 |                 1 | 00000000000000000000FFFFC0A80001 |                 1 |
    +--------------------+-------------------+----------------------------------+-------------------+

```

### Prepared Statement Parameters Examples

 
```
CREATE OR REPLACE TABLE t1 (a INET6);

EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING 'ffff::fffe';
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING X'FFFF000000000000000000000000FFFF';

SELECT * FROM t1;
+------------+
| a          |
+------------+
| ffff::fffe |
| ffff::ffff |
+------------+

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING 'ffff::fffe';
+------------+
| a          |
+------------+
| ffff::fffe |
+------------+

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING X'FFFF000000000000000000000000FFFF';
+------------+
| a          |
+------------+
| ffff::ffff |
+------------+

```

### Migration between BINARY(16) and INET6 Examples

 Before [MariaDB 10.5](../what-is-mariadb-105/index):

 
```
CREATE OR REPLACE TABLE t1 (a BINARY(16));

INSERT INTO t1 VALUES (INET6_ATON('ffff::ffff'));

SELECT INET6_NTOA(a) FROM t1;
+---------------+
| INET6_NTOA(a) |
+---------------+
| ffff::ffff    |
+---------------+

```

Migrating to INET6, from [MariaDB 10.5](../what-is-mariadb-105/index):

 
```
ALTER TABLE t1 MODIFY a INET6;

INSERT INTO t1 VALUES ('ffff::fffe');

SELECT * FROM t1;
+------------+
| a          |
+------------+
| ffff::ffff |
| ffff::fffe |
+------------+

```

Migration from INET6 to BINARY(16):

 
```
CREATE OR REPLACE TABLE t1 (a INET6);

INSERT INTO t1 VALUES ('2001:db8::ff00:42:8329');
INSERT INTO t1 VALUES ('::ffff:192.168.0.1');
INSERT INTO t1 VALUES ('::192.168.0.1');

ALTER TABLE t1 MODIFY a BINARY(16);

SELECT INET6_NTOA(a) FROM t1;
+------------------------+
| INET6_NTOA(a)          |
+------------------------+
| 2001:db8::ff00:42:8329 |
| ::ffff:192.168.0.1     |
| ::192.168.0.1          |
+------------------------+

```

See Also
--------

 * [IS\_IPV6](../is_ipv6/index)
* [INET6\_ATON](../inet6_aton/index)
* [INET6\_NTOA](../inet6_ntoa/index)
* [Working with IPv6 in MariaDB - the INET6 datatype](https://www.youtube.com/watch?v=1zNOGGgUnlQ) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet6/>

SET Data Type
=============

    Syntax
------

 
```
SET('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]

```

Description
-----------

 A set. A string object that can have zero or more values, each of which must be chosen from the list of values 'value1', 'value2', ... A SET column can have a maximum of 64 members. SET values are represented internally as integers.

 SET values cannot contain commas.

 If a SET contains duplicate values, an error will be returned if [strict mode](../sql-mode/index#strict-mode) is enabled, or a warning if strict mode is not enabled. 

 See Also
--------

 * [Character Sets and Collations](../character-sets-and-collations/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-data-type/>

TINYTEXT
========

    Syntax
------

 
```
TINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]

```

Description
-----------

 A [TEXT](../text/index) column with a maximum length of 255 (`28 - 1`) characters. The effective maximum length is less if the value contains multi-byte characters. Each TINYTEXT value is stored using a one-byte length prefix that indicates the number of bytes in the value.

 See Also
--------

 * [TEXT](../text/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tinytext/>

TEXT
====

    Syntax
------

 
```
TEXT[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]

```
 Description
-----------

 A `TEXT` column with a maximum length of `65,535` (`216 - 1`) characters. The effective maximum length is less if the value contains multi-byte characters. Each `TEXT` value is stored using a two-byte length prefix that indicates the number of bytes in the value. If you need a bigger storage, consider using [MEDIUMTEXT](../mediumtext/index) instead.

 An optional length `M` can be given for this type. If this is done, MariaDB creates the column as the smallest `TEXT` type large enough to hold values `M` characters long.

 Before [MariaDB 10.2](../what-is-mariadb-102/index), all MariaDB [collations](../character-sets/index) were of type PADSPACE, meaning that TEXT (as well as [VARCHAR](../varchar/index) and [CHAR](../char/index) values) are compared without regard for trailing spaces. This does not apply to the [LIKE](../like/index) pattern-matching operator, which takes into account trailing spaces.

 Before [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/), `BLOB` and `TEXT` columns could not be assigned a [DEFAULT](../create-table/index#default) value. This restriction was lifted in [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/).

 Examples
--------

 Trailing spaces:

 
```
CREATE TABLE strtest (d TEXT(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT d='Maria',d='Maria   ' FROM strtest;
+-----------+--------------+
| d='Maria' | d='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT d LIKE 'Maria',d LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| d LIKE 'Maria' | d LIKE 'Maria   ' |
+----------------+-------------------+
|              0 |                 1 |
+----------------+-------------------+

```

Indexing
--------

 `TEXT` columns can only be indexed over a specified length. This means that they cannot be used as the [primary key](../getting-started-with-indexes/index#primary-key) of a table norm until [MariaDB 10.4](../what-is-mariadb-104/index), can a [unique index](../getting-started-with-indexes/index#unique-index) be created on them.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**Starting with [MariaDB 10.4](../what-is-mariadb-104/index), a unique index can be created on a `TEXT` column.

 Internally, this uses hash indexing to quickly check the values and if a hash collision is found, the actual stored values are compared in order to retain the uniqueness.

 
Difference between [VARCHAR](../varchar/index) and TEXT
-------------------------------------------------------

 * [VARCHAR](../varchar/index) columns can be fully indexed. `TEXT` columns can only be indexed over a specified length.
* Using TEXT or [BLOB](../blob/index) in a [SELECT](../select/index) query that uses temporary tables for storing intermediate results will force the temporary table to be disk based (using the [Aria storage engine](../aria-storage-engine/index) instead of the [memory storage engine](../memory-storage-engine/index), which is a bit slower. This is not that bad as the [Aria storage engine](../aria-storage-engine/index) caches the rows in memory. To get the benefit of this, one should ensure that the [aria\_pagecache\_buffer\_size](../aria-system-variables/index#aria_pagecache_buffer_size) variable is big enough to hold most of the row and index data for temporary tables.

 ### For Storage Engine Developers

 * Internally the full length of the [VARCHAR](../varchar/index) column is allocated inside each TABLE objects record[] structure. As there are three such buffers, each open table will allocate 3 times max-length-to-store-varchar bytes of memory.
* `TEXT` and `BLOB` columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes length. The `TEXT` data is only stored once. This means that internally `TEXT` uses less memory for each open table but instead has the additional overhead that each `TEXT` object needs to be allocated and freed for each row access (with some caching in between).

 See Also
--------

 * [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [MEDIUMTEXT](../mediumtext/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/text/>

TINYBLOB
========

    Syntax
------

 
```
TINYBLOB

```

Description
-----------

 A [BLOB](../blob/index) column with a maximum length of 255 (28 - 1) bytes. Each TINYBLOB value is stored using a one-byte length prefix that indicates the number of bytes in the value.

 See Also
--------

 * [BLOB](../blob/index)
* [BLOB and TEXT Data Types](../blob-and-text-data-types/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tinyblob/>

CREATE FUNCTION UDF
===================

    Syntax
------

 
```
CREATE [OR REPLACE] [AGGREGATE] FUNCTION [IF NOT EXISTS] function_name
    RETURNS {STRING|INTEGER|REAL|DECIMAL}
    SONAME shared_library_name

```
 Description
-----------

 A user-defined function (UDF) is a way to extend MariaDB with a new function that works like a native (built-in) MariaDB function such as [ABS()](../abs/index) or [CONCAT()](../concat/index).

 `function_name` is the name that should be used in SQL statements to invoke the function. 

 To create a function, you must have the [INSERT privilege](../grant/index) for the mysql database. This is necessary because`CREATE FUNCTION` adds a row to the [mysql.func system table](../mysqlfunc-table/index) that records the function's name, type, and shared library name. If you do not have this table, you should run the [mariadb-upgrade](../mariadb-upgrade/index) command to create it.

 UDFs need to be written in C, C++ or another language that uses C calling conventions, MariaDB needs to have been dynamically compiled, and your operating system must support dynamic loading.

 For an example, see `sql/udf_example.cc` in the source tree. For a collection of existing UDFs see <http://www.mysqludf.org/>.

 Statements making use of user-defined functions are not [safe for replication](../unsafe-statements-for-replication/index).

 For creating a stored function as opposed to a user-defined function, see [CREATE FUNCTION](../create-function/index).

 For valid identifiers to use as function names, see [Identifier Names](../identifier-names/index).

 #### RETURNS

 The `RETURNS` clause indicates the type of the function's return value, and can be one of [STRING](string), [INTEGER](../integer/index), [REAL](real) or [DECIMAL](../decimal/index). `DECIMAL` functions currently return string values and should be written like [STRING](../string-data-types/index) functions.

 #### shared\_library\_name

 `shared_library_name` is the basename of the shared object file that contains the code that implements the function. The file must be located in the plugin directory. This directory is given by the value of the [plugin\_dir](../server-system-variables/index#plugin_dir) system variable. Note that before MariaDB/MySQL 5.1, the shared object could be located in any directory that was searched by your system's dynamic linker.

 #### AGGREGATE

 Aggregate functions are summary functions such as [SUM()](../sum/index) and [AVG()](../avg/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**Aggregate UDF functions can be used as [window functions](../window-functions/index).

 
#### OR REPLACE

 
**MariaDB starting with [10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)**The `OR REPLACE` clause was added in [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 
If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION name ...;

```

#### IF NOT EXISTS

 
**MariaDB starting with [10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)**The `IF NOT EXISTS` clause was added in [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 
When the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the specified function already exists. Cannot be used together with OR REPLACE.

 ### Upgrading a UDF

 To upgrade the UDF's shared library, first run a [DROP FUNCTION](../drop-function/index) statement, then upgrade the shared library and finally run the CREATE FUNCTION statement. If you upgrade without following this process, you may crash the server.

 ### Examples

 
```
CREATE FUNCTION jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
Query OK, 0 rows affected (0.00 sec)

```

OR REPLACE and IF NOT EXISTS:

 
```
CREATE FUNCTION jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
ERROR 1125 (HY000): Function 'jsoncontains_path' already exists

CREATE OR REPLACE FUNCTION jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
Query OK, 0 rows affected (0.00 sec)

CREATE FUNCTION IF NOT EXISTS jsoncontains_path RETURNS integer SONAME 'ha_connect.so';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------+
| Level | Code | Message                                     |
+-------+------+---------------------------------------------+
| Note  | 1125 | Function 'jsoncontains_path' already exists |
+-------+------+---------------------------------------------+

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [DROP FUNCTION](../drop-function/index)
* [CREATE FUNCTION](../create-function/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-function-udf/>

JSON Data Type
==============

    The JSON alias was added to make it possible to use JSON columns in [statement based](../binary-log-formats/index#statement-based) [replication](../high-availability-performance-tuning-mariadb-replication/index) from MySQL to MariaDB and to make it possible for MariaDB to read [mysqldumps](../mysqldump/index) from MySQL. 

 JSON is an alias for [LONGTEXT](../longtext/index) introduced for compatibility reasons with MySQL's JSON data type. MariaDB implements this as a LONGTEXT rather, as the JSON data type contradicts the SQL standard, and MariaDB's benchmarks indicate that performance is at least equivalent.

 In order to ensure that a a valid json document is inserted, the [JSON\_VALID](../json_valid/index) function can be used as a [CHECK constraint](../constraint/index#check-constraint-expressions). This constraint is automatically included for types using the JSON alias from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

 Examples
--------

 
```
CREATE TABLE t (j JSON);

DESC t;
+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| j     | longtext | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

```

With validation:

 
```
CREATE TABLE t2 (
  j JSON 
  CHECK (JSON_VALID(j))
);

INSERT INTO t2 VALUES ('invalid');
ERROR 4025 (23000): CONSTRAINT `j` failed for `test`.`t2`

INSERT INTO t2 VALUES ('{"id": 1, "name": "Monty"}');
Query OK, 1 row affected (0.13 sec)

```

Replicating JSON Data Between MySQL and MariaDB
-----------------------------------------------

 The JSON type in MySQL stores the JSON object in a compact form, not as [LONGTEXT](../longtext/index) as in MariaDB. This means that row based replication will not work for JSON types from MySQL to MariaDB.

 There are a a few different ways to solve this:

 * Use statement based replication.
* Change the JSON column to type TEXT in MySQL
* If you must use row-based replication and cannot change the MySQL master from JSON to TEXT, you can try to introduce an intermediate MySQL slave and change the column type from JSON to TEXT on it. Then you replicate from this intermediate slave to MariaDB.

 Converting a MySQL TABLE with JSON Fields to MariaDB
----------------------------------------------------

 MariaDB can't directly access MySQL's JSON format.

 There are a a few different ways to move the table to MariaDB:

 * From [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), see the you can use the [mysql\_json](../mysql_json/index) plugin. See [Making MariaDB understand MySQL JSON](https://mariadb.org/making-mariadb-understand-mysql-json/).
* Change the JSON column to type TEXT in MySQL. After this, MariaDB can directly use the table without any need for a dump and restore.
* [Use mysqldump to copy the table](../mysqldump/index#examples).

 Differences Between MySQL JSON Strings and MariaDB JSON Strings
---------------------------------------------------------------

 * In MySQL, JSON is an object and is [compared according to json values](https://dev.mysql.com/doc/refman/8.0/en/json.html#json-comparison). In MariaDB JSON strings are normal strings and compared as strings. One exception is when using [JSON\_EXTRACT()](../json_extract/index) in which case strings are unescaped before comparison.

 See Also
--------

 * [JSON Functions](../json-functions/index)
* [CONNECT JSON Table Type](../connect-json-table-type/index)
* [MDEV-9144](https://jira.mariadb.org/browse/MDEV-9144)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json-data-type/>

ROW
===

    
**MariaDB starting with [10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)**The `ROW` data type was introduced in [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/).

 
Syntax
------

 
```
ROW (<field name> <data type> [{, <field name> <data type>}... ])
```
 Description
-----------

 `ROW` is a data type for [stored procedure](../stored-procedures/index) variables.

 Features
--------

 ### ROW fields as normal variables

 `ROW` fields (members) act as normal variables, and are able to appear in all query parts where a stored procedure variable is allowed:

 * Assignment is using the `:=` operator and the [SET](../set/index) command:

 
```
a.x:= 10;
a.x:= b.x;
SET a.x= 10, a.y=20, a.z= b.z;

```

* Passing to functions and operators:

 
```
SELECT f1(rec.a), rec.a<10;

```

* Clauses (select list, WHERE, HAVING, LIMIT, etc...,):

 
```
SELECT var.a, t1.b FROM t1 WHERE t1.b=var.b LIMIT var.c;

```

* `INSERT` values:

 
```
INSERT INTO t1 VALUES (rec.a, rec.b, rec.c);

```

* `SELECT .. INTO` targets

 
```
SELECT a,b INTO rec.a, rec.b FROM t1 WHERE t1.id=10;

```

* Dynamic SQL out parameters ([EXECUTE](../execute-statement/index) and [EXECUTE IMMEDIATE](../execute-immediate/index))

 
```
EXECUTE IMMEDIATE 'CALL proc_with_out_param(?)' USING rec.a;

```

### ROW type variables as FETCH targets

 `ROW` type variables are allowed as [FETCH](../fetch/index) targets:

 
```
FETCH cur INTO rec;

```

where `cur` is a `CURSOR` and `rec` is a `ROW` type stored procedure variable.

 
Note, currently an attempt to use `FETCH` for a `ROW` type variable returns this error: 



```
ERROR 1328 (HY000): Incorrect number of FETCH variables
```
 
`FETCH` from a cursor `cur` into a `ROW` variable `rec` works as follows:

 * The number of fields in `cur` must match the number of fields in `rec`. Otherwise, an error is reported.

 * Assignment is done from left to right. The first cursor field is assigned to the first variable field, the second cursor field is assigned to the second variable field, etc.

 * Field names in `rec` are not important and can differ from field names in `cur`.

 See [FETCH Examples](#fetch-examples) (below) for examples of using this with `sql_mode=ORACLE` and `sql_mode=DEFAULT`.

 ### ROW type variables as `SELECT...INTO` targets

 `ROW` type variables are allowed as `SELECT..INTO` targets with some differences depending on which `sql_mode` is in use.

 * When using `sql_mode=ORACLE`, `table%ROWTYPE` and `cursor%ROWTYPE` variables can be used as `SELECT...INTO` targets.

 * Using multiple `ROW` variables in the `SELECT..INTO` list will report an error.

 * Using `ROW` variables with a different column count than in the `SELECT..INTO` list will report an error.

 See [SELECT...INTO Examples](#selectinto-examples) (below) for examples of using this with `sql_mode=ORACLE` and `sql_mode=DEFAULT`.

 Features not implemented
------------------------

 The following features are planned, but not implemented yet:

 * Returning a ROW type expression from a stored function (see [MDEV-12252](https://jira.mariadb.org/browse/MDEV-12252)). This will need some grammar change to support field names after parentheses:

 
```
SELECT f1().x FROM DUAL;

```

* Returning a ROW type expression from a built-in hybrid type function, such as `CASE`, `IF`, etc.
* ROW of ROWs

 Examples
--------

 ### Declaring a ROW in a stored procedure

 
```
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE r ROW (c1 INT, c2 VARCHAR(10));
  SET r.c1= 10;
  SET r.c2= 'test';
  INSERT INTO t1 VALUES (r.c1, r.c2);
END;
$$
DELIMITER ;
CALL p1();

```

### FETCH Examples

 A complete `FETCH` example for `sql_mode=ORACLE`:

 
```
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=oracle;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec ROW(a INT, b VARCHAR(32));
  CURSOR c IS SELECT a,b FROM t1;
BEGIN
  OPEN c;
  LOOP
    FETCH c INTO rec;
    EXIT WHEN c%NOTFOUND;
    SELECT ('rec=(' || rec.a ||','|| rec.b||')');
  END LOOP;
  CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

```

A complete `FETCH` example for `sql_mode=DEFAULT`:

 
```
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
INSERT INTO t1 VALUES (20,'b20');
INSERT INTO t1 VALUES (30,'b30');

SET sql_mode=DEFAULT;
DROP PROCEDURE IF EXISTS p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE rec ROW(a INT, b VARCHAR(32));
  DECLARE c CURSOR FOR SELECT a,b FROM t1;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
  OPEN c;
read_loop:
  LOOP
    FETCH c INTO rec;
    IF done THEN
      LEAVE read_loop;
    END IF;
    SELECT CONCAT('rec=(',rec.a,',',rec.b,')');
  END LOOP;
  CLOSE c;
END;
$$
DELIMITER ;
CALL p1();

```

### SELECT...INTO Examples

 A `SELECT...INTO` example for `sql_mode=DEFAULT`:

 
```
SET sql_mode=DEFAULT;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE rec1 ROW(a INT, b VARCHAR(32));
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

```

The above example returns:

 
```
+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

```

A `SELECT...INTO` example for `sql_mode=ORACLE`:

 
```
SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec1 ROW(a INT, b VARCHAR(32));
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

```

The above example returns:

 
```
+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

```

An example for `sql_mode=ORACLE` using `table%ROWTYPE` variables as `SELECT..INTO` targets:

 
```
SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  rec1 t1%ROWTYPE;
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

```

The above example returns:

 
```
+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

```

An example for `sql_mode=ORACLE` using `cursor%ROWTYPE` variables as `SELECT..INTO` targets:

 
```
SET sql_mode=ORACLE;
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (a INT, b VARCHAR(32));
INSERT INTO t1 VALUES (10,'b10');
DELIMITER $$
CREATE PROCEDURE p1 AS
  CURSOR cur1 IS SELECT * FROM t1;
  rec1 cur1%ROWTYPE;
BEGIN
  SELECT * FROM t1 INTO rec1;
  SELECT rec1.a, rec1.b;
END;
$$
DELIMITER ;
CALL p1();

```

The above example returns:

 
```
+--------+--------+
| rec1.a | rec1.b |
+--------+--------+
|     10 | b10    |
+--------+--------+

```

See Also
--------

 * [STORED PROCEDURES](../stored-procedures/index)
* [DECLARE Variable](../declare-variable/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/row/>

VARCHAR
=======

    Syntax
------

 
```
[NATIONAL] VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]

```
 Description
-----------

 A variable-length string. M represents the maximum column length in characters. The range of M is 0 to 65,532. The effective maximum length of a VARCHAR is subject to the maximum row size and the character set used. For example, utf8 characters can require up to three bytes per character, so a VARCHAR column that uses the utf8 character set can be declared to be a maximum of 21,844 characters.

 **Note:** For the [ColumnStore](../columnstore/index) engine, M represents the maximum column length in bytes.

 MariaDB stores VARCHAR values as a one-byte or two-byte length prefix plus data. The length prefix indicates the number of bytes in the value. A VARCHAR column uses one length byte if values require no more than 255 bytes, two length bytes if values may require more than 255 bytes.

 MariaDB follows the standard SQL specification, and does not remove trailing spaces from VARCHAR values.

 VARCHAR(0) columns can contain 2 values: an empty string or NULL. Such columns cannot be part of an index. The [CONNECT](../connect/index) storage engine does not support VARCHAR(0).

 VARCHAR is shorthand for CHARACTER VARYING. NATIONAL VARCHAR is the standard SQL way to define that a VARCHAR column should use some predefined character set. MariaDB uses utf8 as this predefined character set, as does MySQL 4.1 and up. NVARCHAR is shorthand for NATIONAL VARCHAR.

 Before [MariaDB 10.2](../what-is-mariadb-102/index), all MariaDB [collations](../character-sets/index) were of type `PADSPACE`, meaning that VARCHAR (as well as [CHAR](../char/index) and [TEXT](../text/index) values) are compared without regard for trailing spaces. This does not apply to the [LIKE](../like/index) pattern-matching operator, which takes into account trailing spaces. From [MariaDB 10.2](../what-is-mariadb-102/index), a number of [NO PAD collations](../supported-character-sets-and-collations/index#no-pad-collations) are available.

 If a unique index consists of a column where trailing pad characters are stripped or ignored, inserts into that column where values differ only by the number of trailing pad characters will result in a duplicate-key error.

 Examples
--------

 The following are equivalent:

 
```
VARCHAR(30) CHARACTER SET utf8
NATIONAL VARCHAR(30)
NVARCHAR(30)
NCHAR VARCHAR(30)
NATIONAL CHARACTER VARYING(30)
NATIONAL CHAR VARYING(30)

```

Trailing spaces:

 
```
CREATE TABLE strtest (v VARCHAR(10));
INSERT INTO strtest VALUES('Maria   ');

SELECT v='Maria',v='Maria   ' FROM strtest;
+-----------+--------------+
| v='Maria' | v='Maria   ' |
+-----------+--------------+
|         1 |            1 |
+-----------+--------------+

SELECT v LIKE 'Maria',v LIKE 'Maria   ' FROM strtest;
+----------------+-------------------+
| v LIKE 'Maria' | v LIKE 'Maria   ' |
+----------------+-------------------+
|              0 |                 1 |
+----------------+-------------------+

```

Truncation
----------

 * Depending on whether or not [strict sql mode](../sql-mode/index#strict-mode) is set, you will either get a warning or an error if you try to insert a string that is too long into a VARCHAR column. If the extra characters are spaces, the spaces that can't fit will be removed and you will always get a warning, regardless of the [sql mode](../sql_mode/index) setting.

 Difference Between VARCHAR and [TEXT](../text/index)
----------------------------------------------------

 * VARCHAR columns can be fully indexed. [TEXT](../text/index) columns can only be indexed over a specified length.
* Using [TEXT](../text/index) or [BLOB](../blob/index) in a [SELECT](../select/index) query that uses temporary tables for storing intermediate results will force the temporary table to be disk based (using the [Aria storage engine](../aria-storage-engine/index) instead of the [memory storage engine](../memory-storage-engine/index), which is a bit slower. This is not that bad as the [Aria storage engine](../aria-storage-engine/index) caches the rows in memory. To get the benefit of this, one should ensure that the [aria\_pagecache\_buffer\_size](../aria-system-variables/index#aria_pagecache_buffer_size) variable is big enough to hold most of the row and index data for temporary tables.

 Oracle Mode
-----------

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `VARCHAR2` is a synonym.

 
### For Storage Engine Developers

 * Internally the full length of the VARCHAR column is allocated inside each TABLE objects record[] structure. As there are three such buffers, each open table will allocate 3 times max-length-to-store-varchar bytes of memory.
* [TEXT](../text/index) and [BLOB](../blob/index) columns are stored with a pointer (4 or 8 bytes) + a 1-4 bytes length. The [TEXT](../text/index) data is only stored once. This means that internally `TEXT` uses less memory for each open table but instead has the additional overhead that each `TEXT` object needs to be allocated and freed for each row access (with some caching in between).

 See Also
--------

 * [VARBINARY](../varbinary/index)
* [TEXT](../text/index)
* [CHAR](../char/index)
* [Character Sets and Collations](../data-types-character-sets-and-collations/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/varchar/>

LONG and LONG VARCHAR
=====================

    `LONG` and `LONG VARCHAR` are synonyms for [MEDIUMTEXT](../mediumtext/index).

 
```
CREATE TABLE t1 (a LONG, b LONG VARCHAR);

DESC t1;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| a     | mediumtext | YES  |     | NULL    |       |
| b     | mediumtext | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/long-and-long-varchar/>

CREATE VIEW
===========

    Syntax
------

 
```
CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW [IF NOT EXISTS] view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

```
 Description
-----------

 The CREATE VIEW statement creates a new [view](../views/index), or replaces an existing one if the OR REPLACE clause is given. If the view does not exist, CREATE OR REPLACE VIEW is the same as CREATE VIEW. If the view does exist, CREATE OR REPLACE VIEW is the same as [ALTER VIEW](../alter-view/index).

 The select\_statement is a [SELECT](../select/index) statement that provides the definition of the view. (When you select from the view, you select in effect using the SELECT statement.) select\_statement can select from base tables or other views.

 The view definition is "frozen" at creation time, so changes to the underlying tables afterwards do not affect the view definition. For example, if a view is defined as SELECT \* on a table, new columns added to the table later do not become part of the view. A [SHOW CREATE VIEW](../show-create-view/index) shows that such queries are rewritten and column names are included in the view definition.

 The view definition must be a query that does not return errors at view creation times. However, the base tables used by the views might be altered later and the query may not be valid anymore. In this case, querying the view will result in an error. [CHECK TABLE](../check-table/index) helps in finding this kind of problems.

 The [ALGORITHM clause](../view-algorithms/index) affects how MariaDB processes the view. The DEFINER and SQL SECURITY clauses specify the security context to be used when checking access privileges at view invocation time. The WITH CHECK OPTION clause can be given to constrain inserts or updates to rows in tables referenced by the view. These clauses are described later in this section.

 The CREATE VIEW statement requires the CREATE VIEW privilege for the view, and some privilege for each column selected by the SELECT statement. For columns used elsewhere in the SELECT statement you must have the SELECT privilege. If the OR REPLACE clause is present, you must also have the DROP privilege for the view.

 A view belongs to a database. By default, a new view is created in the default database. To create the view explicitly in a given database, specify the name as db\_name.view\_name when you create it.

 
```
CREATE VIEW test.v AS SELECT * FROM t;

```

Base tables and views share the same namespace within a database, so a database cannot contain a base table and a view that have the same name.

 Views must have unique column names with no duplicates, just like base tables. By default, the names of the columns retrieved by the SELECT statement are used for the view column names. To define explicit names for the view columns, the optional column\_list clause can be given as a list of comma-separated identifiers. The number of names in column\_list must be the same as the number of columns retrieved by the SELECT statement.

 
**MySQL until 5.1.28**Prior to MySQL 5.1.29, When you modify an existing view, the current view definition is backed up and saved. It is stored in that table's database directory, in a subdirectory named arc. The backup file for a view v is named v.frm-00001. If you alter the view again, the next backup is named v.frm-00002. The three latest view backup definitions are stored. Backed up view definitions are not preserved by [mysqldump](../mysqldump/index), or any other such programs, but you can retain them using a file copy operation. However, they are not needed for anything but to provide you with a backup of your previous view definition. It is safe to remove these backup definitions, but only while mysqld is not running. If you delete the arc subdirectory or its files while mysqld is running, you will receive an error the next time you try to alter the view: 



```
MariaDB [test]> ALTER VIEW v AS SELECT * FROM t; 
ERROR 6 (HY000): Error on delete of '.\test\arc/v.frm-0004' (Errcode: 2)

```
 
Columns retrieved by the SELECT statement can be simple references to table columns. They can also be expressions that use functions, constant values, operators, and so forth.

 Unqualified table or view names in the SELECT statement are interpreted with respect to the default database. A view can refer to tables or views in other databases by qualifying the table or view name with the proper database name.

 A view can be created from many kinds of SELECT statements. It can refer to base tables or other views. It can use joins, UNION, and subqueries. The SELECT need not even refer to any tables. The following example defines a view that selects two columns from another table, as well as an expression calculated from those columns:

 
```
CREATE TABLE t (qty INT, price INT);

INSERT INTO t VALUES(3, 50);

CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;

SELECT * FROM v;
+------+-------+-------+
| qty  | price | value |
+------+-------+-------+
|    3 |    50 |   150 |
+------+-------+-------+

```

A view definition is subject to the following restrictions:

 * The SELECT statement cannot contain a subquery in the FROM clause.
* The SELECT statement cannot refer to system or user variables.
* Within a stored program, the definition cannot refer to program parameters or local variables.
* The SELECT statement cannot refer to prepared statement parameters.
* Any table or view referred to in the definition must exist. However, after a view has been created, it is possible to drop a table or view that the definition refers to. In this case, use of the view results in an error. To check a view definition for problems of this kind, use the CHECK TABLE statement.
* The definition cannot refer to a TEMPORARY table, and you cannot create a TEMPORARY view.
* Any tables named in the view definition must exist at definition time.
* You cannot associate a trigger with a view.
* For valid identifiers to use as view names, see [Identifier Names](../identifier-names/index).

 ORDER BY is allowed in a view definition, but it is ignored if you select from a view using a statement that has its own ORDER BY.

 For other options or clauses in the definition, they are added to the options or clauses of the statement that references the view, but the effect is undefined. For example, if a view definition includes a LIMIT clause, and you select from the view using a statement that has its own LIMIT clause, it is undefined which limit applies. This same principle applies to options such as ALL, DISTINCT, or SQL\_SMALL\_RESULT that follow the SELECT keyword, and to clauses such as INTO, FOR UPDATE, and LOCK IN SHARE MODE.

 The PROCEDURE clause cannot be used in a view definition, and it cannot be used if a view is referenced in the FROM clause.

 If you create a view and then change the query processing environment by changing system variables, that may affect the results that you get from the view:

 
```
CREATE VIEW v (mycol) AS SELECT 'abc';

SET sql_mode = '';

SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| mycol | 
+-------+

SET sql_mode = 'ANSI_QUOTES';

SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| abc   | 
+-------+

```

The DEFINER and SQL SECURITY clauses determine which MariaDB account to use when checking access privileges for the view when a statement is executed that references the view. They were added in MySQL 5.1.2. The legal SQL SECURITY characteristic values are DEFINER and INVOKER. These indicate that the required privileges must be held by the user who defined or invoked the view, respectively. The default SQL SECURITY value is DEFINER.

 If a user value is given for the DEFINER clause, it should be a MariaDB account in 'user\_name'@'host\_name' format (the same format used in the GRANT statement). The user\_name and host\_name values both are required. The definer can also be given as CURRENT\_USER or CURRENT\_USER(). The default DEFINER value is the user who executes the CREATE VIEW statement. This is the same as specifying DEFINER = CURRENT\_USER explicitly.

 If you specify the DEFINER clause, these rules determine the legal DEFINER user values:

 * If you do not have the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [SET USER](../grant/index#set-user) privilege, the only legal user value is your own account, either specified literally or by using CURRENT\_USER. You cannot set the definer to some other account.
* If you have the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [SET USER](../grant/index#set-user) privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated.
* If the SQL SECURITY value is DEFINER but the definer account does not exist when the view is referenced, an error occurs.

 Within a view definition, CURRENT\_USER returns the view's DEFINER value by default. For views defined with the SQL SECURITY INVOKER characteristic, CURRENT\_USER returns the account for the view's invoker. For information about user auditing within views, see <http://dev.mysql.com/doc/refman/5.1/en/account-activity-auditing.html>.

 Within a stored routine that is defined with the SQL SECURITY DEFINER characteristic, CURRENT\_USER returns the routine's DEFINER value. This also affects a view defined within such a program, if the view definition contains a DEFINER value of CURRENT\_USER.

 View privileges are checked like this:

 * At view definition time, the view creator must have the privileges needed to use the top-level objects accessed by the view. For example, if the view definition refers to table columns, the creator must have privileges for the columns, as described previously. If the definition refers to a stored function, only the privileges needed to invoke the function can be checked. The privileges required when the function runs can be checked only as it executes: For different invocations of the function, different execution paths within the function might be taken.
* When a view is referenced, privileges for objects accessed by the view are checked against the privileges held by the view creator or invoker, depending on whether the SQL SECURITY characteristic is DEFINER or INVOKER, respectively.
* If reference to a view causes execution of a stored function, privilege checking for statements executed within the function depend on whether the function is defined with a SQL SECURITY characteristic of DEFINER or INVOKER. If the security characteristic is DEFINER, the function runs with the privileges of its creator. If the characteristic is INVOKER, the function runs with the privileges determined by the view's SQL SECURITY characteristic.

 Example: A view might depend on a stored function, and that function might invoke other stored routines. For example, the following view invokes a stored function f():

 
```
CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);

Suppose that f() contains a statement such as this:

IF name IS NULL then
  CALL p1();
ELSE
  CALL p2();
END IF;

```

The privileges required for executing statements within f() need to be checked when f() executes. This might mean that privileges are needed for p1() or p2(), depending on the execution path within f(). Those privileges must be checked at runtime, and the user who must possess the privileges is determined by the SQL SECURITY values of the view v and the function f().

 The DEFINER and SQL SECURITY clauses for views are extensions to standard SQL. In standard SQL, views are handled using the rules for SQL SECURITY INVOKER.

 If you invoke a view that was created before MySQL 5.1.2, it is treated as though it was created with a SQL SECURITY DEFINER clause and with a DEFINER value that is the same as your account. However, because the actual definer is unknown, MySQL issues a warning. To make the warning go away, it is sufficient to re-create the view so that the view definition includes a DEFINER clause.

 The optional ALGORITHM clause is an extension to standard SQL. It affects how MariaDB processes the view. ALGORITHM takes three values: MERGE, TEMPTABLE, or UNDEFINED. The default algorithm is UNDEFINED if no ALGORITHM clause is present. See [View Algorithms](../view-algorithms/index) for more information.

 Some views are updatable. That is, you can use them in statements such as UPDATE, DELETE, or INSERT to update the contents of the underlying table. For a view to be updatable, there must be a one-to-one relationship between the rows in the view and the rows in the underlying table. There are also certain other constructs that make a view non-updatable. See [Inserting and Updating with Views](../inserting-and-updating-with-views/index).

 ### WITH CHECK OPTION

 The WITH CHECK OPTION clause can be given for an updatable view to prevent inserts or updates to rows except those for which the WHERE clause in the select\_statement is true.

 In a WITH CHECK OPTION clause for an updatable view, the LOCAL and CASCADED keywords determine the scope of check testing when the view is defined in terms of another view. The LOCAL keyword restricts the CHECK OPTION only to the view being defined. CASCADED causes the checks for underlying views to be evaluated as well. When neither keyword is given, the default is CASCADED.

 For more information about updatable views and the WITH CHECK OPTION clause, see [Inserting and Updating with Views](../inserting-and-updating-with-views/index).

 ### IF NOT EXISTS

 
**MariaDB starting with [10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)**The `IF NOT EXISTS` clause was added in [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 
When the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the specified view already exists. Cannot be used together with the `OR REPLACE` clause.

 ### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index) and `CREATE VIEW` is atomic.

 
Examples
--------

 
```
CREATE TABLE t (a INT, b INT) ENGINE = InnoDB;

INSERT INTO t VALUES (1,1), (2,2), (3,3);

CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;

SELECT * FROM v;
+------+------+
| a    | a2   |
+------+------+
|    1 |    2 |
|    2 |    4 |
|    3 |    6 |
+------+------+

```

OR REPLACE and IF NOT EXISTS:

 
```
CREATE VIEW v AS SELECT a, a*2 AS a2 FROM t;
ERROR 1050 (42S01): Table 'v' already exists

CREATE OR REPLACE VIEW v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected (0.04 sec)

CREATE VIEW IF NOT EXISTS v AS SELECT a, a*2 AS a2 FROM t;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+--------------------------+
| Level | Code | Message                  |
+-------+------+--------------------------+
| Note  | 1050 | Table 'v' already exists |
+-------+------+--------------------------+

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [ALTER VIEW](../alter-view/index)
* [DROP VIEW](../drop-view/index)
* [SHOW CREATE VIEWS](show-create-views)
* [INFORMATION SCHEMA VIEWS Table](../information-schema-views-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-view/>

Data Type Storage Requirements
==============================

     The following tables indicate the approximate data storage requirements for each data type.

 Numeric Data Types
------------------

 


| Data Type | Storage Requirement |
| --- | --- |
| [TINYINT](../tinyint/index) | 1 byte |
| [SMALLINT](../smallint/index) | 2 bytes |
| [MEDIUMINT](../mediumint/index) | 3 bytes |
| [INT](../int/index) | 4 bytes |
| [BIGINT](../bigint/index) | 8 bytes |
| [FLOAT](../float/index)(p) | 4 bytes if p <= 24, otherwise 8 bytes |
| [DOUBLE](../double/index) | 8 bytes |
| [DECIMAL](../decimal/index) | See table below |
| [BIT](../bit/index)(M) | (M+7)/8 bytes |

 
Note that MEDIUMINT columns will require 4 bytes in memory (for example, in InnoDB buffer pool).

 ### Decimal

 [Decimals](../decimal/index) are stored using a binary format, with the integer and the fraction stored separately. Each nine-digit multiple requires 4 bytes, followed by a number of bytes for whatever remains, as follows:

 


| Remaining digits | Storage Requirement |
| --- | --- |
| 0 | 0 bytes |
| 1 | 1 byte |
| 2 | 1 byte |
| 3 | 2 bytes |
| 4 | 2 bytes |
| 5 | 3 bytes |
| 6 | 3 bytes |
| 7 | 4 bytes |
| 8 | 4 bytes |

 
String Data Types
-----------------

 In the descriptions below, `M` is the declared column length (in characters or in bytes), while `len` is the actual length in bytes of the value.

 


| Data Type | Storage Requirement |
| --- | --- |
| [ENUM](../enum/index) | 1 byte for up to 255 enum values, 2 bytes for 256 to 65,535 enum values |
| [CHAR(M)](../char/index) | M × w bytes, where w is the number of bytes required for the maximum-length character in the character set |
| [BINARY(M)](../binary/index) | M bytes |
| [VARCHAR(M)](../varchar/index), [VARBINARY(M)](../varbinary/index) | len + 1 bytes if column is 0 – 255 bytes, len + 2 bytes if column may require more than 255 bytes |
| [TINYBLOB](../tinyblob/index), [TINYTEXT](../tinytext/index) | len + 1 bytes |
| [BLOB](../blob/index), [TEXT](../text/index) | len + 2 bytes |
| [MEDIUMBLOB](../mediumblob/index), [MEDIUMTEXT](../mediumtext/index) | len + 3 bytes |
| [LONGBLOB](../longblob/index), [LONGTEXT](../longtext/index) | len + 4 bytes |
| [SET](../set-data-type/index) | Given M members of the set, (M+7)/8 bytes, rounded up to 1, 2, 3, 4, or 8 bytes |
| [INET6](../inet6/index) | 16 bytes |
| [UUID](uuid_datatype) | 16 bytes |

 
In some [character sets](../data-types-character-sets-and-collations/index), not all characters use the same number of bytes. utf8 encodes characters with one to three bytes per character, while utf8mb4 requires one to four bytes per character.

 When using field the COMPRESSED attribute, 1 byte is reserved for metadata. For example, VARCHAR(255) will use +2 bytes instead of +1.

 ### Examples

 Assuming a single-byte character-set:

 


|  |  |  |  |  |
| --- | --- | --- | --- | --- |
| Value | CHAR(2) | Storage Required | VARCHAR(2) | Storage Required |
| '' | ' ' | 2 bytes | '' | 1 byte |
| '1' | '1 ' | 2 bytes | '1' | 2 bytes |
| '12' | '12' | 2 bytes | '12' | 3 bytes |

 
Date and Time Data Types
------------------------

 


| Data Type | Storage Requirement |
| --- | --- |
| [DATE](../date/index) | 3 bytes |
| [TIME](../time/index) | 3 bytes |
| [DATETIME](../datetime/index) | 8 bytes |
| [TIMESTAMP](../timestamp/index) | 4 bytes |
| [YEAR](../year-data-type/index) | 1 byte |

 
### Microseconds

 [MariaDB 5.3](../what-is-mariadb-53/index) and MySQL 5.6 introduced [microseconds](../microseconds-in-mariadb/index). The underlying storage implementations were different, but from [MariaDB 10.1](../what-is-mariadb-101/index), MariaDB defaults to the MySQL format (by means of the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) variable). Microseconds have the following additional storage requirements: 

 #### MySQL 5.6+ and [MariaDB 10.1](../what-is-mariadb-101/index)+

 


| Precision | Storage Requirement |
| --- | --- |
| 0 | 0 bytes |
| 1,2 | 1 byte |
| 3,4 | 2 bytes |
| 5,6 | 3 bytes |

 
#### 
[MariaDB 5.3](../what-is-mariadb-53/index) - [MariaDB 10.0](../what-is-mariadb-100/index)

 


| Precision | Storage Requirement |
| --- | --- |
| 0 | 0 bytes |
| 1,2 | 1 byte |
| 3,4,5 | 2 bytes |
| 6 | 3 bytes |

 
NULLs
-----

 For the InnoDB [COMPACT](../innodb-compact-row-format/index), [DYNAMIC](../innodb-dynamic-row-format/index) and [COMPRESSED](../innodb-compressed-row-format/index) row formats, a number of bytes will be allocated in the record header for the nullable fields. If there are between 1 and 8 nullable fields, 1 such byte will be allocated. In the record payload area, no space will be reserved for values that are NULL.

 For the [InnoDB REDUNDANT row format](../innodb-redundant-row-format/index), the overhead is 1 bit in the record header (as a part of the 1-byte or 2-byte "end of field" pointer). In that format, a NULL fixed-length field will consume the same amount of space as any NOT NULL value in the record payload area. The motivation is that it is possible to update in place between NOT NULL and NULL values.

 In other formats, NULL values usually require 1 bit in the data file, 1 byte in the index file.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-type-storage-requirements/>

DROP VIEW
=========

    Syntax
------

 
```
DROP VIEW [IF EXISTS]
    view_name [, view_name] ...
    [RESTRICT | CASCADE]

```
 Description
-----------

 `DROP VIEW` removes one or more [views](../views/index). You must have the DROP privilege for each view. If any of the views named in the argument list do not exist, MariaDB returns an error indicating by name which non-existing views it was unable to drop, but it also drops all of the views in the list that do exist.

 The `IF EXISTS` clause prevents an error from occurring for views that don't exist. When this clause is given, a `NOTE` is generated for each non-existent view. See [SHOW WARNINGS](../show-warnings/index).

 `RESTRICT` and `CASCADE`, if given, are parsed and ignored.

 It is possible to specify view names as `db_name`.`view_name`. This is useful to delete views from multiple databases with one statement. See [Identifier Qualifiers](../identifier-qualifiers/index) for details.

 The [DROP privilege](../grant/index#table-privileges) is required to use `DROP TABLE` on non-temporary tables. For temporary tables, no privilege is required, because such tables are only visible for the current session.

 If a view references another view, it will be possible to drop the referenced view. However, the other view will reference a view which does not exist any more. Thus, querying it will produce an error similar to the following:

 
```
ERROR 1356 (HY000): View 'db_name.view_name' references invalid table(s) or 
column(s) or function(s) or definer/invoker of view lack rights to use them

```

This problem is reported in the output of [CHECK TABLE](../check-table/index).

 Note that it is not necessary to use `DROP VIEW` to replace an existing view, because `[CREATE VIEW](../create-view/index)` has an `OR REPLACE` clause.

 ### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index) and `DROP VIEW` for a singular view is atomic. Dropping multiple views is crash-safe.

 
Examples
--------

 
```
DROP VIEW v,v2;

```

Given views `v` and `v2`, but no view `v3`

 
```
DROP VIEW v,v2,v3;
ERROR 1051 (42S02): Unknown table 'v3'

```


```
DROP VIEW IF EXISTS v,v2,v3;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+-------------------------+
| Level | Code | Message                 |
+-------+------+-------------------------+
| Note  | 1051 | Unknown table 'test.v3' |
+-------+------+-------------------------+

```

See Also
--------

 * [CREATE VIEW](../create-view/index)
* [ALTER VIEW](../alter-view/index)
* [SHOW CREATE VIEWS](show-create-views)
* [INFORMATION SCHEMA VIEWS Table](../information-schema-views-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-view/>

mariadb-report
==============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-report` is a symlink to `mysqlreport`, the binary for showing the value of important status variables.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-report` is the name of the binary, with `mysqlreport` a symlink .

 
 `mariadb-report` makes a friendly report of important MariaDB status values. Actually, it makes a friendly report of nearly every status value from SHOW STATUS. Unlike SHOW STATUS which simply dumps over 100 values to the screen in one long list, mariadb-report interprets and formats the values and presents the basic values and many more inferred values in a human-readable format. Numerous example reports are available in the archive of the old [hackmysql.com/mysqlreport](http://hackmysql.com/mysqlreport), [archived here](https://github.com/daniel-nichter/hackmysql.com/tree/master/mysqlreport).

 The benefit of mariadb-report is that it allows you to very quickly see a wide array of performance indicators for your MariaDB server which would otherwise need to be calculated by hand from all the various SHOW STATUS values. For example, the Index Read Ratio is an important value but it's not present in SHOW STATUS; it's an inferred value (the ratio of Key\_reads to Key\_read\_requests).

 This documentation outlines all the command line options in mariadb-report, most of which control which reports are printed. This document does not address how to interpret these reports; that topic is covered in the document Guide To Understanding mysqlreport, [archived here](https://github.com/daniel-nichter/hackmysql.com/blob/master/mysqlreport/mysqlreportguide.html).

 Usage
-----

 
```
mariadb-report [options]

```

mariadb-report options
----------------------

 Technically, command line options are in the form `--option`, but `-option` works too. All options can be abbreviated if the abbreviation is unique. For example, option `--host` can be abbreviated to `--ho` but not `--h` because `--h` is ambiguous: it could mean `--host` or `--help`.

 


| Option | Description |
| --- | --- |
| `--all` | Equivalent to `--dtq --dms --com 3 --sas --qcache`. (Notice `--tab` is not invoked by `--all`.) |
| `--com N` | Print top N number of non-DMS Com\_ [status values](../server-status-variables/index) in descending order (after DMS in Questions report). If N is not given, default is 3. Such non-DMS Com\_ values include [Com\_change\_db](../server-status-variables/index#com_change_db), [Com\_show\_tables](../server-status-variables/index#com_show_tables), [Com\_rollback](../server-status-variables/index#com_rollback), etc. |
| `--dms` | Print Data Manipulation Statements (DMS) report (under DMS in Questions report). DMS are those from the [Data Manipulation](../data-manipulation/index) section. mariadb-report considers only [SELECT](../select/index), [INSERT](../insert/index), [REPLACE](../replace/index), [UPDATE](../update/index), and [DELETE](../delete/index). Each DMS is listed in descending order by count. |
| `--dtq` | Print Distribution of Total Queries (DTQ) report (under Total in Questions report). Queries (or Questions) can be divided into four main areas: DMS (see `--dms`), Com\_ (see `--com` ), COM\_QUIT (see COM\_QUIT and Questions, [archived here](https://github.com/daniel-nichter/hackmysql.com/blob/master/mysqlreport/mysqlreportguide.html)), and Unknown. `--dtq` lists the number of queries in each of these areas in descending order. |
| `--email ADDRESS` | After printing the report to screen, email the report to ADDRESS. This option requires sendmail in /usr/sbin/, therefore it does not work on Windows. /usr/sbin/sendmail can be a sym link to qmail, for example, or any MTA that emulates sendmail's -t command line option and operation. The FROM: field is "mariadb-report", SUBJECT: is "MySQL status report". |
| `--flush-status` | Execute a [FLUSH STATUS](../flush/index) after generating the reports. If you do not have permissions in MariaDB to do this an error from DBD::mysql::st will be printed after the reports. |
| `--help` | Output help information and exit. |
| `--host ADDRESS` | Host address. |
| `--infile FILE` | Instead of getting [SHOW STATUS](../show-status/index) values from MariaDB, read values from FILE. FILE is often a copy of the output of SHOW STATUS including formatting characters (+, -). *mariadb-report* expects FILE to have the format " value number " where value is only alpha and underscore characters (A-Z and \_) and number is a positive integer. Anything before, between, or after value and number is ignored. *mariadb-report* also needs the following MariaDB server variables: [version](../server-system-variables/index#version), [table\_cache](../server-system-variables/index#table_open_cache), [max\_connections](../server-system-variables/index#max_connections), [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size), [query\_cache\_size](../server-system-variables/index#query_cache_size). These values can be specified in INFILE in the format "name = value" where name is one of the aforementioned server variables and value is a positive integer with or without a trailing M and possible periods (for version). For example, to specify an 18M key\_buffer\_size: key\_buffer\_size = 18M. Or, a 256 table\_cache: table\_cache = 256. The M implies Megabytes not million, so 18M means 18,874,368 not 18,000,000. If these server variables are not specified the following defaults are used (respectively) which may cause strange values to be reported: 0.0.0, 64, 100, 8M, 0. |
| `--no-mycnf` | Makes mariadb-report not read /.my.cnf which it does by default otherwise. `--user` and `--password` always override values from /.my.cnf. |
| `--outfile FILE` | After printing the report to screen, print the report to FILE too. Internally, mariadb-report always writes the report to a temp file first: `/tmp/mysqlreport.PID` on \*nix, `c:sqlreport.PID` on Windows (PID is the script's process ID). Then it prints the temp file to screen. Then if `--outfile` is specified, the temp file is copied to OUTFILE. After `--email` (above), the temp file is deleted. |
| `--password` | As of version 2.3 `--password` can take the password on the command line like `--password FOO`. Using `--password` alone without giving a password on the command line causes mariadb-report to prompt for a password. |
| `--port PORT` | Port number. |
| `--qcache` | Print [Query Cache](../query-cache/index) report. |
| `--sas` | Print report for Select\_ and Sort\_ [status values](../server-status-variables/index) (after Questions report). See MySQL Select and Sort Status Variables, archived [here](https://github.com/daniel-nichter/hackmysql.com/blob/master/mysqlreport/mysqlreportguide.html). |
| `--socket SOCKET` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--tab` | Print Threads, Aborted, and Bytes status reports (after Created temp report). The Threads report reports on all Threads\_ status values. |
| `--user USERNAME` | Username. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-report/>

UUID Data Type
==============

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The UUID data type was added in a [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/) preview.

 
Syntax
------

 
```
UUID

```
 Description
-----------

 The `UUID` data type is intended for the storage of 128-bit UUID (Universally Unique Identifier) data. See the [UUID function](../uuid/index) page for more details on UUIDs themselves.

 ### Retrieval

 Data retrieved by this data type is in the string representation defined in [RFC4122](https://datatracker.ietf.org/doc/html/rfc4122).

 ### Casting

 [String literals](../string-literals/index) of hexadecimal characters and [CHAR](../char/index)/[VARCHAR](../varchar/index)/[TEXT](../text/index) can be cast to the UUID data type. Likewise [hexadecimal literals](../hexadecimal-literals/index), [binary-literals](../binary-literals/index), and [BINARY](../binary/index)/[VARBINARY](../varbinary/index)/[BLOB](../blob/index) types can also be cast to UUID.

 The data type will not accept a short UUID generated with the [UUID\_SHORT](../uuid_short/index) function, but will accept a value without the `-` character generated by the [SYS\_GUID](../sys_guid/index) function (or inserted directly). Hyphens can be partially omitted as well, or included after any group of two digits.

 The type does not accept UUIDs in braces, permitted by some implementations.

 ### Storage

 UUID are stored in an index friendly manner, the order of a UUID of llllllll-mmmm-Vhhh-vsss-nnnnnnnnnnnn is stored as:

 
```
nnnnnnnnnnnn-vsss-Vhhh-mmmm-llllllll

```

This provides a sorting order, if a UUIDv1 (node and timestamp) is used, of the node, followed by the timestamp.

 Examples
--------

 
```
CREATE TABLE t1 (id UUID);

```

Directly Inserting via [string literals](../string-literals/index):

 
```
INSERT INTO t1 VALUES('123e4567-e89b-12d3-a456-426655440000');

```

Directly Inserting via [hexadecimal literals](../hexadecimal-literals/index):

 
```
INSERT INTO t1 VALUES (x'fffffffffffffffffffffffffffffffe');

```

Generating and inserting via the [UUID function](../uuid/index).

 
```
INSERT INTO t1 VALUES (UUID());


```

Retrieval:

 
```
SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

```

The [UUID\_SHORT](../uuid_short/index) function does not generate valid full-length UUID:

 
```
INSERT INTO t1 VALUES (UUID_SHORT());
ERROR 1292 (22007): Incorrect uuid value: '99440417627439104' 
  for column `test`.`t1`.`id` at row 1

```

Accepting a value without the `-` character, either directly or generated by the [SYS\_GUID](../sys_guid/index) function:

 
```
INSERT INTO t1 VALUES (SYS_GUID());

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
| ea0368d3-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

SELECT SYS_GUID();
+----------------------------------+
| SYS_GUID()                       |
+----------------------------------+
| ff5b6bcc1a1411ecab4ef859713e4be4 |
+----------------------------------+

INSERT INTO t1 VALUES ('ff5b6bcc1a1411ecab4ef859713e4be4');

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| 123e4567-e89b-12d3-a456-426655440000 |
| ffffffff-ffff-ffff-ffff-fffffffffffe |
| 93aac041-1a14-11ec-ab4e-f859713e4be4 |
| ea0368d3-1a14-11ec-ab4e-f859713e4be4 |
| ff5b6bcc-1a14-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

```

Valid and invalid hyphen and brace usage:

 
```
TRUNCATE t1;

INSERT INTO t1 VALUES ('f8aa-ed66-1a1b-11ec-ab4e-f859-713e-4be4');

INSERT INTO t1 VALUES ('1b80667f1a1c-11ecab4ef859713e4be4');

INSERT INTO t1 VALUES ('2fd6c945-1a-1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('49-c9-f9-59-1a-1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('57-96-da-c1-1a-1c-11-ec-ab-4e-f8-59-71-3e-4b-e4');

INSERT INTO t1 VALUES ('6-eb74f8f-1a1c-11ec-ab4e-f859713e4be4');

INSERT INTO t1 VALUES ('{29bad136-1a1d-11ec-ab4e-f859713e4be4}');
ERROR 1292 (22007): Incorrect uuid value: '{29bad136-1a1d-11ec-ab4e-f859713e4be4}' 
  for column `test`.`t1`.`id` at row 1

SELECT * FROM t1;
+--------------------------------------+
| id                                   |
+--------------------------------------+
| f8aaed66-1a1b-11ec-ab4e-f859713e4be4 |
| 1b80667f-1a1c-11ec-ab4e-f859713e4be4 |
| 2fd6c945-1a1c-11ec-ab4e-f859713e4be4 |
| 49c9f959-1a1c-11ec-ab4e-f859713e4be4 |
| 5796dac1-1a1c-11ec-ab4e-f859713e4be4 |
| 6eb74f8f-1a1c-11ec-ab4e-f859713e4be4 |
+--------------------------------------+

```

See Also
--------

 * [10.7 preview feature: UUID Data Type](https://mariadb.org/10-7-preview-feature-uuid-data-type/) (mariadb.org blog post)
* [UUID function](../uuid/index)
* [UUID\_SHORT function](../uuid_short/index)
* [SYS\_GUID](../sys_guid/index) - UUID without the `-` character for Oracle compatibility

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uuid-data-type/>

Event Scheduler
================

   Events are named database objects containing SQL statements that are to be executed at a later stage, either once off, or at regular intervals.

  

| Title | Description |
| --- | --- |
|  [Events Overview](../events/index) |  Scheduled events.  |
|  [Event Limitations](../event-limitations/index) |  Restrictions applying to events  |
|  [CREATE EVENT](../create-event/index) |  Create and schedule a new event.  |
|  [ALTER EVENT](../alter-event/index) |  Change an existing event.  |
|  [DROP EVENT](../drop-event/index) |  Removes an existing event.  |
|  [Information Schema EVENTS Table](../information-schema-events-table/index) |  Server event information  |
|  [SHOW EVENTS](../show-events/index) |  Shows information about events  |
|  [SHOW CREATE EVENT](../show-create-event/index) |  Displays the CREATE EVENT statement needed to re-create a given event  |
|  [Automating MariaDB Tasks with Events](../automating-mariadb-tasks-with-events/index) |  Using MariaDB events for automating tasks.  |
|  [mysql.event Table](../mysqlevent-table/index) |  Information about MariaDB events.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/event-scheduler/>

SHOW CREATE VIEW
================

    Syntax
------

 
```
SHOW CREATE VIEW view_name

```

Description
-----------

 This statement shows a [CREATE VIEW](../create-view/index) statement that creates the given [view](../views/index), as well as the character set used by the connection when the view was created. This statement also works with views.

 `SHOW CREATE VIEW` quotes table, column and stored function names according to the value of the [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) server system variable.

 Examples
--------

 
```
SHOW CREATE VIEW example\G
*************************** 1. row ***************************
                View: example
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL
SECURITY DEFINER VIEW `example` AS (select `t`.`id` AS `id`,`t`.`s` AS `s` from
`t`)
character_set_client: cp850
collation_connection: cp850_general_ci

```

With `[sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create)` off:

 
```
SHOW CREATE VIEW example\G
*************************** 1. row ***************************
                View: example
         Create View: CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECU
RITY DEFINER VIEW example AS (select t.id AS id,t.s AS s from t)
character_set_client: cp850
collation_connection: cp850_general_ci

```

Grants
------

 To be able to see a view, you need to have the [SHOW VIEW](../grant/index#table-privileges) and the [SELECT](../grant/index#table-privileges) privilege on the view:

 
```
GRANT SHOW VIEW,SELECT ON test_database.test_view TO 'test'@'localhost';

```

See Also
--------

 * [Grant privileges to tables, views etc](../grant/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-view/>

View Algorithms
===============

    Description
-----------

 The [CREATE VIEW](../create-view/index) statement accepts an optional ALGORITHM clause, an extension to standard SQL for [Views](../views/index).

 It can contain one of three values: MERGE, TEMPTABLE or UNDEFINED, and affects how MariaDB will process the view.

 With MERGE, the view definition and the related portion of the statement referring to the view are merged. If TEMPTABLE is selected, the view results are stored in a temporary table. 

 MERGE is usually more efficient, and a view can only be updated with this algorithm. TEMPTABLE can be useful in certain situations, as locks on the underlying tables can be released before the statement is finished processing.

 If it's UNDEFINED (or the ALGORITHM clause is not used), MariaDB will choose what it thinks is the best algorithm. An algorithm can also be UNDEFINED if its defined as MERGE, but the view requires a temporary table.

 
Views with definition ALGORITHM=MERGE or ALGORITHM=TEMPTABLE got accidentally swapped between MariaDB and MySQL. When upgrading, you have to re-create views created with either of these definitions (see [MDEV-6916](https://jira.mariadb.org/browse/MDEV-6916)).

 
MERGE Limitations
-----------------

 A view cannot be of type ALGORITHM=MERGE if it uses any of the following:

 * [HAVING](../select/index)
* [LIMIT](../select/index#limit)
* [GROUP BY](../select/index#group-by)
* [DISTINCT](../select/index#distinct)
* [UNION](../union/index)
* [UNION ALL](../union/index)
* An aggregate function, such as [MAX()](../max/index), [MIN()](../min/index), [SUM()](../sum/index) or [COUNT()](../count/index)
* subquery in the SELECT list
* if it has no underlying table because it refers only to literal values

 MERGE Examples
--------------

 ### Example 1

 Here's an example of how MariaDB handles a view with a MERGE algorithm. Take a view defined as follows:

 
```
CREATE ALGORITHM = MERGE VIEW view_name (view_field1, view_field2) AS
SELECT field1, field2 FROM table_name WHERE field3 > '2013-06-01';

```

Now, if we run a query on this view, as follows:

 
```
SELECT * FROM view_name;

```

to execute the view `view_name` becomes the underlying table, `table_name`, the `*` becomes the fields `view_field1` and `view_field2`, corresponding to `field1` and `field2` and the WHERE clause, `WHERE field3 > 100` is added, so the actual query executed is:

 
```
SELECT field1, field2 FROM table_name WHERE field3 > '2013-06-01'

```

### Example 2

 Given the same view as above, if we run the query:

 
```
SELECT * FROM view_name WHERE view_field < 8000;

```

everything occurs as it does in the previous example, but `view_field < 8000` takes the corresponding field name and becomes `field1 < 8000`, connected with `AND` to the `field3 > '2013-06-01'` part of the query.

 So the resulting query is:

 
```
SELECT field1, field2 FROM table_name WHERE (field3 > '2013-06-01') AND (field1 < 8000);

```

When connecting with `AND`, parentheses are added to make sure the correct precedence is used.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/view-algorithms/>

VARBINARY
=========

    Syntax
------

 
```
VARBINARY(M)

```
 Description
-----------

 The VARBINARY type is similar to the [VARCHAR](../sql_language-data_types-varchar/index) type, but stores binary byte strings rather than non-binary character strings. `M` represents the maximum column length in bytes. 

 It contains no [character set](../data-types-character-sets-and-collations/index), and comparison and sorting are based on the numeric value of the bytes.

 If the maximum length is exceeded, and [SQL strict mode](../sql-mode/index) is not enabled , the extra characters will be dropped with a warning. If strict mode is enabled, an error will occur.

 Unlike [BINARY](../binary/index) values, VARBINARYs are not right-padded when inserting.

 ### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `RAW` is a synonym for `VARBINARY`.

 
Examples
--------

 Inserting too many characters, first with strict mode off, then with it on:

 
```
CREATE TABLE varbins (a VARBINARY(10));

INSERT INTO varbins VALUES('12345678901');
Query OK, 1 row affected, 1 warning (0.04 sec)

SELECT * FROM varbins;
+------------+
| a          |
+------------+
| 1234567890 |
+------------+

SET sql_mode='STRICT_ALL_TABLES';

INSERT INTO varbins VALUES('12345678901');
ERROR 1406 (22001): Data too long for column 'a' at row 1

```

Sorting is performed with the byte value:

 
```
TRUNCATE varbins;

INSERT INTO varbins VALUES('A'),('B'),('a'),('b');

SELECT * FROM varbins ORDER BY a;
+------+
| a    |
+------+
| A    |
| B    |
| a    |
| b    |
+------+

```

Using [CAST](../cast/index) to sort as a [CHAR](../char/index) instead:

 
```
SELECT * FROM varbins ORDER BY CAST(a AS CHAR);
+------+
| a    |
+------+
| a    |
| A    |
| b    |
| B    |
+------+

```

See Also
--------

 * [VARCHAR](../varchar/index)
* [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/varbinary/>

Creating & Using Views
======================

    A Tutorial Introduction
-----------------------

 **Up-front warning:** This is the beginning of a very basic tutorial on views, based on my experimentation with them. This tutorial assumes that you've read the appropriate tutorials up to and including [More Advanced Joins](more_advanced_joins) (or that you understand the concepts behind them). This page is intended to give you a general idea of how views work and what they do, as well as some examples of when you could use them.

 ### Requirements for This Tutorial

 In order to perform the SQL statements in this tutorial, you will need access to a MariaDB database and you will need the CREATE TABLE and CREATE VIEW privileges on this table.

 The Employee Database
---------------------

 First, we need some data we can perform our optimizations on, so we'll recreate the tables from the [More Advanced Joins](../more-advanced-joins/index) tutorial, to provide us with a starting point. If you have already completed that tutorial and have this database already, you can skip ahead.

 First, we create the table that will hold all of the employees and their contact information:

 
```
CREATE TABLE `Employees` (
  `ID` TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `First_Name` VARCHAR(25) NOT NULL,
  `Last_Name` VARCHAR(25) NOT NULL,
  `Position` VARCHAR(25) NOT NULL,
  `Home_Address` VARCHAR(50) NOT NULL,
  `Home_Phone` VARCHAR(12) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM;

```

Next, we add a few employees to the table:

 
```
INSERT INTO `Employees` (`First_Name`, `Last_Name`, `Position`, `Home_Address`, `Home_Phone`)
VALUES
  ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza', '326-555-3492'),
  ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847'),
  ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456'),
  ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349'),
  ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329'),
  ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478'); 

```

Now, we create a second table, containing the hours which each employee clocked in and out during the week:

 
```
CREATE TABLE `Hours` (
  `ID` TINYINT(3) UNSIGNED NOT NULL,
  `Clock_In` DATETIME NOT NULL,
  `Clock_Out` DATETIME NOT NULL
) ENGINE=MyISAM;

```

Finally, although it is a lot of information, we add a full week of hours for each of the employees into the second table that we created:

 
```
INSERT INTO `Hours`
VALUES ('1', '2005-08-08 07:00:42', '2005-08-08 17:01:36'),
  ('1', '2005-08-09 07:01:34', '2005-08-09 17:10:11'),
  ('1', '2005-08-10 06:59:56', '2005-08-10 17:09:29'),
  ('1', '2005-08-11 07:00:17', '2005-08-11 17:00:47'),
  ('1', '2005-08-12 07:02:29', '2005-08-12 16:59:12'),
  ('2', '2005-08-08 07:00:25', '2005-08-08 17:03:13'),
  ('2', '2005-08-09 07:00:57', '2005-08-09 17:05:09'),
  ('2', '2005-08-10 06:58:43', '2005-08-10 16:58:24'),
  ('2', '2005-08-11 07:01:58', '2005-08-11 17:00:45'),
  ('2', '2005-08-12 07:02:12', '2005-08-12 16:58:57'),
  ('3', '2005-08-08 07:00:12', '2005-08-08 17:01:32'),
  ('3', '2005-08-09 07:01:10', '2005-08-09 17:00:26'),
  ('3', '2005-08-10 06:59:53', '2005-08-10 17:02:53'),
  ('3', '2005-08-11 07:01:15', '2005-08-11 17:04:23'),
  ('3', '2005-08-12 07:00:51', '2005-08-12 16:57:52'),
  ('4', '2005-08-08 06:54:37', '2005-08-08 17:01:23'),
  ('4', '2005-08-09 06:58:23', '2005-08-09 17:00:54'),
  ('4', '2005-08-10 06:59:14', '2005-08-10 17:00:12'),
  ('4', '2005-08-11 07:00:49', '2005-08-11 17:00:34'),
  ('4', '2005-08-12 07:01:09', '2005-08-12 16:58:29'),
  ('5', '2005-08-08 07:00:04', '2005-08-08 17:01:43'),
  ('5', '2005-08-09 07:02:12', '2005-08-09 17:02:13'),
  ('5', '2005-08-10 06:59:39', '2005-08-10 17:03:37'),
  ('5', '2005-08-11 07:01:26', '2005-08-11 17:00:03'),
  ('5', '2005-08-12 07:02:15', '2005-08-12 16:59:02'),
  ('6', '2005-08-08 07:00:12', '2005-08-08 17:01:02'),
  ('6', '2005-08-09 07:03:44', '2005-08-09 17:00:00'),
  ('6', '2005-08-10 06:54:19', '2005-08-10 17:03:31'),
  ('6', '2005-08-11 07:00:05', '2005-08-11 17:02:57'),
  ('6', '2005-08-12 07:02:07', '2005-08-12 16:58:23');

```

Working with the Employee Database
----------------------------------

 In this example, we are going to assist Human Resources by simplifying the queries that their applications need to perform. At the same time, it's going to enable us to abstract their queries from the database, which allows us more flexibility in maintaining it.

 ### Filtering by Name, Date and Time

 In the previous tutorial, we looked at a JOIN query that displayed all of the lateness instances for a particular employee. In this tutorial, we are going to abstract that query somewhat to provide us with all lateness occurrences for all employees, and then standardize that query by making it into a view.

 Our previous query looked like this:

 
```
SELECT
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`
FROM `Employees`
INNER JOIN `Hours` ON `Employees`.`ID` = `Hours`.`ID`
WHERE `Employees`.`First_Name` = 'Helmholtz'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') >= '2005-08-08'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') <= '2005-08-12'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%H:%i:%S') > '07:00:59';

```

The result:

 
```
+------------+-----------+---------------------+---------------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           |
+------------+-----------+---------------------+---------------------+
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |
+------------+-----------+---------------------+---------------------+

```

### Refining Our Query

 The previous example displays to us all of Heimholtz's punch-in times that were after seven AM. We can see here that Heimholz has been late twice within this reporting period, and we can also see that in both instances, he either left exactly on time or he left early. Our company policy, however, dictates that late instances must be made up at the end of one's shift, so we want to exclude from our report anyone whose clock-out time was greater than 10 hours and one minute after their clock-in time.

 
```
SELECT
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`,
  (TIMESTAMPDIFF(MINUTE,`Hours`.`Clock_Out`,`Hours`.`Clock_In`) + 601) as Difference
FROM `Employees`
INNER JOIN `Hours` USING (`ID`)
WHERE DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') >= '2005-08-08'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') <= '2005-08-12'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%H:%i:%S') > '07:00:59'
AND TIMESTAMPDIFF(MINUTE,`Hours`.`Clock_Out`,`Hours`.`Clock_In`) > -601;

```

This gives us the following list of people who have violated our attendance policy:

 
```
+------------+-----------+---------------------+---------------------+------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           | Difference |
+------------+-----------+---------------------+---------------------+------------+
| Mustapha   | Mond      | 2005-08-12 07:02:29 | 2005-08-12 16:59:12 |          4 |
| Henry      | Foster    | 2005-08-11 07:01:58 | 2005-08-11 17:00:45 |          2 |
| Henry      | Foster    | 2005-08-12 07:02:12 | 2005-08-12 16:58:57 |          4 |
| Bernard    | Marx      | 2005-08-09 07:01:10 | 2005-08-09 17:00:26 |          1 |
| Lenina     | Crowne    | 2005-08-12 07:01:09 | 2005-08-12 16:58:29 |          3 |
| Fanny      | Crowne    | 2005-08-11 07:01:26 | 2005-08-11 17:00:03 |          2 |
| Fanny      | Crowne    | 2005-08-12 07:02:15 | 2005-08-12 16:59:02 |          4 |
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |          4 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |          4 |
+------------+-----------+---------------------+---------------------+------------+

```

The Utility of Views
--------------------

 We can see in the previous example that there have been several instances of employees coming in late and leaving early. Unfortunately, we can also see that this query is getting needlessly complex. Having all of this SQL in our application not only creates more complex application code, but also means that if we ever change the structure of this table we're going to have to change what is becoming a somewhat messy query. This is where views begin to show their usefulness.

 ### Creating the Employee Tardiness View

 Creating a view is almost exactly the same as creating a SELECT statement, so we can use our previous SELECT statement in the creation of our new view:

 
```
CREATE SQL SECURITY INVOKER VIEW Employee_Tardiness AS 
SELECT
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`,
(TIMESTAMPDIFF(MINUTE,`Hours`.`Clock_Out`,`Hours`.`Clock_In`) + 601) as Difference
FROM `Employees`
INNER JOIN `Hours` USING (`ID`)
WHERE DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') >= '2005-08-08'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') <= '2005-08-12'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%H:%i:%S') > '07:00:59'
AND TIMESTAMPDIFF(MINUTE,`Hours`.`Clock_Out`,`Hours`.`Clock_In`) > -601;

```

Note that the first line of our query contains the statement 'SQL SECURITY INVOKER' - this means that when the view is accessed, it runs with the same privileges that the person accessing the view has. Thus, if someone without access to our Employees table tries to access this view, they will get an error.

 Other than the security parameter, the rest of the query is fairly self explanatory. We simply run 'CREATE VIEW <view-name> AS' and then append any valid SELECT statement, and our view is created. Now if we do a SELECT from the view, we can see we get the same results as before, with much less SQL:

 
```
SELECT * FROM Employee_Tardiness;

```


```
+------------+-----------+---------------------+---------------------+------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           | Difference |
+------------+-----------+---------------------+---------------------+------------+
| Mustapha   | Mond      | 2005-08-12 07:02:29 | 2005-08-12 16:59:12 |          5 |
| Henry      | Foster    | 2005-08-11 07:01:58 | 2005-08-11 17:00:45 |          3 |
| Henry      | Foster    | 2005-08-12 07:02:12 | 2005-08-12 16:58:57 |          5 |
| Bernard    | Marx      | 2005-08-09 07:01:10 | 2005-08-09 17:00:26 |          2 |
| Lenina     | Crowne    | 2005-08-12 07:01:09 | 2005-08-12 16:58:29 |          4 |
| Fanny      | Crowne    | 2005-08-09 07:02:12 | 2005-08-09 17:02:13 |          1 |
| Fanny      | Crowne    | 2005-08-11 07:01:26 | 2005-08-11 17:00:03 |          3 |
| Fanny      | Crowne    | 2005-08-12 07:02:15 | 2005-08-12 16:59:02 |          5 |
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |          5 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |          5 |
+------------+-----------+---------------------+---------------------+------------+

```

Now we can even perform operations on the table, such as limiting our results to just those with a Difference of at least five minutes:

 
```
SELECT * FROM Employee_Tardiness WHERE Difference >=5;

```


```
+------------+-----------+---------------------+---------------------+------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           | Difference |
+------------+-----------+---------------------+---------------------+------------+
| Mustapha   | Mond      | 2005-08-12 07:02:29 | 2005-08-12 16:59:12 |          5 |
| Henry      | Foster    | 2005-08-12 07:02:12 | 2005-08-12 16:58:57 |          5 |
| Fanny      | Crowne    | 2005-08-12 07:02:15 | 2005-08-12 16:59:02 |          5 |
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |          5 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |          5 |
+------------+-----------+---------------------+---------------------+------------+

```

### Other Uses of Views

 Aside from just simplifying our application's SQL queries, there are also other benefits that views can provide, some of which are only possible by using views.

 #### Restricting Data Access

 For example, even though our Employees database contains fields for Position, Home Address, and Home Phone, our query does not allow for these fields to be shown. This means that in the case of a security issue in the application (for example, an SQL injection attack, or even a malicious programmer), there is no risk of disclosing an employee's personal information.

 #### Row-level Security

 We can also define separate views to include a specific WHERE clause for security; for example, if we wanted to restrict a department head's access to only the staff that report to him, we could specify his identity in the view's CREATE statement, and he would then be unable to see any other department's employees, despite them all being in the same table. If this view is writeable and it is defined with the CASCADE clause, this restriction will also apply to writes. This is actually the only way to implement row-level security in MariaDB, so views play an important part in that area as well.

 #### Pre-emptive Optimization

 We can also define our views in such a way as to force the use of indexes, so that other, less-experienced developers don't run the risk of running un-optimized queries or JOINs that result in full-table scans and extended locks. Expensive queries, queries that SELECT \*, and poorly thought-out JOINs can not only slow down the database entirely, but can cause inserts to fail, clients to time out, and reports to error out. By creating a view that is already optimized and letting users perform their queries on that, you can ensure that they won't cause a significant performance hit unnecessarily.

 #### Abstracting Tables

 When we re-engineer our application, we sometimes need to change the database to optimize or accommodate new or removed features. We may, for example, want to [normalize](../database-normalization/index) our tables when they start getting too large and queries start taking too long. Alternately, we may be installing a new application with different requirements alongside a legacy application. Unfortunately, database redesign will tend to break backwards-compatibility with previous applications, which can cause obvious problems.

 Using views, we can change the format of the underlying tables while still presenting the same table format to the legacy application. Thus, an application which demands username, hostname, and access time in string format can access the same data as an application which requires firstname, lastname, user@host, and access time in Unix timestamp format.

 Summary
-------

 Views are an SQL feature that can provide a lot of versatility in larger applications, and can even simplify smaller applications further. Just as stored procedures can help us abstract out our database logic, views can simplify the way we access data in the database, and can help un-complicate our queries to make application debugging easier and more efficient.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Views_(Basic>) on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-using-views/>

SHOW TABLES
===========

    Syntax
------

 
```
SHOW [FULL] TABLES [FROM db_name]
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 `SHOW TABLES` lists the tables (until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only non-`TEMPORARY` tables are shown), [sequences](../sequences/index) and [views](../views/index) in a given database. 

 The `LIKE` clause, if present on its own, indicates which table names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index). For example, when searching for tables in the `test` database, the column name for use in the `WHERE` and `LIKE` clauses will be `Tables_in_test`

 The `FULL` modifier is supported such that `SHOW FULL TABLES` displays a second output column. Values for the second column, `Table_type`, are `BASE TABLE` for a table, `VIEW` for a [view](../views/index) and `SEQUENCE` for a [sequence](../sequences/index).

 You can also get this information using:

 
```
mariadb-show db_name

```

See [mariadb-show](../mariadb-show/index) for more details.

 If you have no privileges for a base table or view, it does not show up in the output from `SHOW TABLES` or `mariadb-show *db\_name*`.

 The [information\_schema.TABLES](../information-schema-tables-table/index) table, as well as the [SHOW TABLE STATUS](../show-table-status/index) statement, provide extended information about tables.

 Examples
--------

 
```
SHOW TABLES;
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
| t1                   |
| view1                |
+----------------------+

```

Showing the tables beginning with *a* only.

 
```
SHOW TABLES WHERE Tables_in_test LIKE 'a%';
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
+----------------------+

```

Showing tables and table types:

 
```
SHOW FULL TABLES;
+----------------+------------+
| Tables_in_test | Table_type |
+----------------+------------+
| s1             | SEQUENCE   |
| student        | BASE TABLE |
| v1             | VIEW       |
+----------------+------------+

```

Showing temporary tables: <= [MariaDB 11.1](../what-is-mariadb-111/index)

 
```
CREATE TABLE t (t int(11));
CREATE TEMPORARY TABLE t (t int(11));
CREATE TEMPORARY TABLE te (t int(11));

SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| t              |
+----------------+

```

From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/):

 
```
CREATE TABLE t (t int(11));
CREATE TEMPORARY TABLE t (t int(11));
CREATE TEMPORARY TABLE te (t int(11));

SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| te             |
| t              |
| t              |
+----------------+

```

See Also
--------

 * [SHOW TABLE STATUS](../show-table-status/index)
* The [information\_schema.TABLES](../information-schema-tables-table/index) table

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-tables/>

Basic MariaDB Articles
=======================

   These articles are at a basic level. They are more advanced than beginners and less advanced than intermediate developers and administrators.

  

| Title | Description |
| --- | --- |
|  [Basic SQL Debugging](../basic-sql-debugging/index) |  An introductory tutorial on debugging MariaDB.  |
|  [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index) |  How to configure MariaDB for remote client access.  |
|  [Creating & Using Views](../creating-using-views/index) |  A tutorial on creating and using views.  |
|  [Getting Started with Indexes](../getting-started-with-indexes/index) |  Extensive tutorial on creating indexes for tables.  |
|  [Joining Tables with JOIN Clauses](../joining-tables-with-join-clauses/index) |  An introductory tutorial on using the JOIN clause.  |
|  [The Essentials of an Index](../the-essentials-of-an-index/index) |  Explains the basics of a table index.  |
|  [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index) |  Common problems when trying to connect to MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/basic-mariadb-articles/>

ALTER VIEW
==========

    Syntax
------

 
```
ALTER
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER }]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

```
 Description
-----------

 This statement changes the definition of a [view](../views/index), which must exist. The syntax is similar to that for [CREATE VIEW](../create-view/index) and the effect is the same as for `CREATE OR REPLACE VIEW` if the view exists. This statement requires the `CREATE VIEW` and `DROP` [privileges](../grant/index#table-privileges) for the view, and some privilege for each column referred to in the `SELECT` statement. `ALTER VIEW` is allowed only to the definer or users with the [SUPER](../grant/index#global-privileges) privilege.

 Example
-------

 
```
ALTER VIEW v AS SELECT a, a*3 AS a2 FROM t;

```

See Also
--------

 * [CREATE VIEW](../create-view/index)
* [DROP VIEW](../drop-view/index)
* [SHOW CREATE VIEW](../show-create-view/index)
* [INFORMATION SCHEMA VIEWS Table](../information-schema-views-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-view/>

Intermediate MariaDB Articles
==============================

   These are articles for intermediate level MariaDB developers and administrators.

  

| Title | Description |
| --- | --- |
|  [Database Theory](../database-theory/index) |  Articles on hierarchical, network and relational databases.  |
|  [Starting and Stopping MariaDB](../starting-and-stopping-mariadb/index) |  Articles related to starting and stopping MariaDB Server.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/intermediate-mariadb-articles/>

Books on MariaDB
=================

  

| Title | Description |
| --- | --- |
|  [Beginner Books](../beginner-books/index) |  List of books on MariaDB for newcomers and beginners.  |
|  [Intermediate and Advanced Books](../intermediate-and-advanced-books/index) |  List of books on MariaDB for intermediate and advanced developers and administrators.  |
|  [Books on MariaDB Code](../books-on-mariadb-code/index) |  List of books on coding MariaDB Server and plugins.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/books/>

TINYINT
=======

    Syntax
------

 
```
TINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```
 Description
-----------

 A very small [integer](../sql_language-data_types-int/index). The signed range is -128 to 127. The unsigned range is 0 to 255. For details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 [INT1](../int1/index) is a synonym for `TINYINT`. [BOOL and BOOLEAN](../boolean/index) are synonyms for `TINYINT(1)`.

 Examples
--------

 
```
CREATE TABLE tinyints (a TINYINT,b TINYINT UNSIGNED,c TINYINT ZEROFILL);

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO tinyints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO tinyints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,10);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |   10 |  010 |
+------+------+------+

INSERT INTO tinyints VALUES (128,128,128);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO tinyints VALUES (127,128,128);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |   10 |  010 |
|  127 |  128 |  128 |
+------+------+------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO tinyints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.08 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.11 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO tinyints VALUES (-10,10,10);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |    0 |  000 |
|  -10 |   10 |  000 |
|  -10 |   10 |  010 |
+------+------+------+

INSERT INTO tinyints VALUES (128,128,128);
Query OK, 1 row affected, 1 warning (0.19 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO tinyints VALUES (127,128,128);

SELECT * FROM tinyints;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|  -10 |    0 |  000 |
|  -10 |   10 |  000 |
|  -10 |   10 |  010 |
|  127 |  128 |  128 |
|  127 |  128 |  128 |
+------+------+------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [SMALLINT](../smallint/index)
* [MEDIUMINT](../mediumint/index)
* [INTEGER](../int/index)
* [BIGINT](../bigint/index)
* [BOOLEAN](../boolean/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tinyint/>

RENAME TABLE
============

    Syntax
------

 
```
RENAME TABLE[S] [IF EXISTS] tbl_name 
  [WAIT n | NOWAIT]
  TO new_tbl_name
    [, tbl_name2 TO new_tbl_name2] ...

```
 Description
-----------

 This statement renames one or more tables or [views](../views/index), but not the privileges associated with them.

 ### IF EXISTS

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**If this directive is used, one will not get an error if the table to be renamed doesn't exist.

 
The rename operation is done atomically, which means that no other session can access any of the tables while the rename is running. For example, if you have an existing table `old_table`, you can create another table `new_table` that has the same structure but is empty, and then replace the existing table with the empty one as follows (assuming that `backup_table` does not already exist):

 
```
CREATE TABLE new_table (...);
RENAME TABLE old_table TO backup_table, new_table TO old_table;

```

`tbl_name` can optionally be specified as `db_name`.`tbl_name`. See [Identifier Qualifiers](../identifier-qualifiers/index). This allows to use `RENAME` to move a table from a database to another (as long as they are on the same filesystem):

 
```
RENAME TABLE db1.t TO db2.t;

```

Note that moving a table to another database is not possible if it has some [triggers](../triggers/index). Trying to do so produces the following error:

 
```
ERROR 1435 (HY000): Trigger in wrong schema

```

Also, views cannot be moved to another database:

 
```
ERROR 1450 (HY000): Changing schema from 'old_db' to 'new_db' is not allowed.

```

Multiple tables can be renamed in a single statement. The presence or absence of the optional `S` (`RENAME TABLE` or `RENAME TABLES`) has no impact, whether a single or multiple tables are being renamed.

 If a `RENAME TABLE` renames more than one table and one renaming fails, all renames executed by the same statement are rolled back.

 Renames are always executed in the specified order. Knowing this, it is also possible to swap two tables' names:

 
```
RENAME TABLE t1 TO tmp_table,
    t2 TO t1,
    tmp_table TO t2;

```

### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 ### Privileges

 Executing the `RENAME TABLE` statement requires the [DROP](../grant/index#table-privileges), [CREATE](../grant/index#table-privileges) and [INSERT](../grant/index#table-privileges) privileges for the table or the database.

 ### Atomic RENAME TABLE

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**From [MariaDB 10.6](../what-is-mariadb-106/index), `RENAME TABLE` is atomic for most engines, including InnoDB, MyRocks, MyISAM and Aria ([MDEV-23842](https://jira.mariadb.org/browse/MDEV-23842)). This means that if there is a crash (server down or power outage) during `RENAME TABLE`, all tables will revert to their original names and any changes to trigger files will be reverted.

 In older MariaDB version there was a small chance that, during a server crash happening in the middle of `RENAME TABLE`, some tables could have been renamed (in the worst case partly) while others would not be renamed.

 See [Atomic DDL](../atomic-ddl/index) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rename-table/>

Information Schema VIEWS Table
==============================

    The [Information Schema](../information_schema/index) `VIEWS` table contains information about [views](../views/index). The `SHOW VIEW` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_CATALOG` | Aways `def`. |
| `TABLE_SCHEMA` | Database name containing the view. |
| `TABLE_NAME` | View table name. |
| `VIEW_DEFINITION` | Definition of the view. |
| `CHECK_OPTION` | `YES` if the `WITH CHECK_OPTION` clause has been specified, `NO` otherwise. |
| `IS_UPDATABLE` | Whether the view is updatable or not. |
| `DEFINER` | Account specified in the DEFINER clause (or the default when created). |
| `SECURITY_TYPE` | `SQL SECURITY` characteristic, either `DEFINER` or `INVOKER`. |
| `CHARACTER_SET_CLIENT` | The client [character set](../data-types-character-sets-and-collations/index) when the view was created, from the session value of the [character\_set\_client](../server-system-variables/index#character_set_client) system variable. |
| `COLLATION_CONNECTION` | The client [collation](../data-types-character-sets-and-collations/index) when the view was created, from the session value of the [collation\_connection](../server-system-variables/index#collation_connection) system variable. |
| `ALGORITHM` | The algorithm used in the view. See [View Algorithms](../view-algorithms/index). |

 
Example
-------

 
```
SELECT * FROM information_schema.VIEWS\G
*************************** 1. row ***************************
       TABLE_CATALOG: def
        TABLE_SCHEMA: test
          TABLE_NAME: v
     VIEW_DEFINITION: select `test`.`t`.`qty` AS `qty`,`test`.`t`.`price` AS `price`,(`test`.`t`.`qty` * `test`.`t`.`price`) AS `value` from `test`.`t`
        CHECK_OPTION: NONE
        IS_UPDATABLE: YES
             DEFINER: root@localhost
       SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
           ALGORITHM: UNDEFINED

```

See Also
--------

 * [CREATE VIEW](../create-view/index)
* [ALTER VIEW](../alter-view/index)
* [DROP VIEW](../drop-view/index)
* [SHOW CREATE VIEWS](show-create-views)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-views-table/>

Beginner MariaDB Articles
==========================

   These tutorial articles were written for those who very little about databases and nothing about MariaDB. They are articles for newcomers and beginners.

  

| Title | Description |
| --- | --- |
|  [A MariaDB Primer](../a-mariadb-primer/index) |  A 10-minute primer on using MariaDB.  |
|  [MariaDB Basics](../mariadb-basics/index) |  Basic article on using MariaDB.  |
|  [Getting Data from MariaDB](../getting-data-from-mariadb/index) |  Extensive tutorial on using the SELECT statement.  |
|  [Adding and Changing Data in MariaDB](../adding-and-changing-data-in-mariadb/index) |  Tutorial on using INSERT and UPDATE statements.  |
|  [Altering Tables in MariaDB](../altering-tables-in-mariadb/index) |  Tutorial on using the ALTER TABLE statement.  |
|  [Changing Times in MariaDB](../changing-times-in-mariadb/index) |  Tutorial on using various time and date functions in MariaDB.  |
|  [Doing Time with MariaDB](../doing-time-with-mariadb/index) |  Tutorial about temporal data types and functions.  |
|  [Importing Data into MariaDB](../importing-data-into-mariadb/index) |  Tutorial on using the LOAD DATA INFILE statement.  |
|  [Making Backups with mariadb-dump](../making-backups-with-mariadb-dump/index) |  Tutorial article on how to make back-ups with mariadb-dump.  |
|  [MariaDB String Functions](../mariadb-string-functions/index) |  Extensive tutorial on how to use several string functions.  |
|  [Restoring Data from Dump Files](../restoring-data-from-dump-files/index) |  Tutorial on how to restore data from a mariadb-dump backup.  |
|  [Basic SQL Statements](../basic-sql-statements/index) |  Basic SQL statements for structuring and manipulating data.  |
|  [Connecting to MariaDB](../connecting-to-mariadb/index) |  Connecting to MariaDB with the basic connection parameters.  |
|  [External Tutorials](../external-tutorials/index) |  Links to external MariaDB, MySQL and SQL tutorials.  |
|  [Useful MariaDB Queries](../useful-mariadb-queries/index) |  Quick reference of commonly-used MariaDB queries.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/beginner-mariadb-articles/>

Advanced MariaDB Articles
==========================

   Tutorial articles for advanced MariaDB developers and administrators.

  

| Title | Description |
| --- | --- |
|  [Development Articles](../development-articles/index) |  Articles of interest to MariaDB developers.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/advanced-mariadb-articles/>

BOOLEAN
=======

    Syntax
------

 
```
BOOL, BOOLEAN

```

Description
-----------

 These types are synonyms for [TINYINT(1)](../sql_language-data_types-tinyint/index). A value of zero is considered false. Non-zero values are considered true.

 However, the values TRUE and FALSE are merely aliases for 1 and 0. See [Boolean Literals](../sql-language-structure-boolean-literals/index), as well as the [IS operator](../is/index) for testing values against a boolean.

 Examples
--------

 
```
CREATE TABLE boo (i BOOLEAN);

DESC boo;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| i     | tinyint(1) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

```


```
SELECT IF(0, 'true', 'false');
+------------------------+
| IF(0, 'true', 'false') |
+------------------------+
| false                  |
+------------------------+

SELECT IF(1, 'true', 'false');
+------------------------+
| IF(1, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+

SELECT IF(2, 'true', 'false');
+------------------------+
| IF(2, 'true', 'false') |
+------------------------+
| true                   |
+------------------------+

```

TRUE and FALSE as aliases for 1 and 0:

 
```
SELECT IF(0 = FALSE, 'true', 'false');

+--------------------------------+
| IF(0 = FALSE, 'true', 'false') |
+--------------------------------+
| true                           |
+--------------------------------+

SELECT IF(1 = TRUE, 'true', 'false');
+-------------------------------+
| IF(1 = TRUE, 'true', 'false') |
+-------------------------------+
| true                          |
+-------------------------------+

SELECT IF(2 = TRUE, 'true', 'false');
+-------------------------------+
| IF(2 = TRUE, 'true', 'false') |
+-------------------------------+
| false                         |
+-------------------------------+

SELECT IF(2 = FALSE, 'true', 'false');
+--------------------------------+
| IF(2 = FALSE, 'true', 'false') |
+--------------------------------+
| false                          |
+--------------------------------+

```

The last two statements display the results shown because 2 is equal to neither 1 nor 0.

 See Also
--------

 * [Boolean Literals](../sql-language-structure-boolean-literals/index)
* [IS operator](../is/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/boolean/>

Beginner Books
==============

    Below is a list of books on MariaDB for beginners, listed in order by date of publication—the most recent first. We've provided links to Amazon.com or the publisher for convenience, but they can be found at many bookstores.

 

*[PHP 7 et MariaDB : Coffret en 2 volumes](https://www.amazon.co.uk/PHP-MariaDB-D%C3%A9veloppez-application-persistance/dp/2409016669/ref=sr_1_3?keywords=mariadb&qid=1558010639&s=books&sr=1-3)* by Stéphane Combaudon and Olivier Heurtel, December 2018 (French) Build interactive, database-driven websites with PHP 7, MySQL 8, and MariaDB.   
  

 
*[Practical PHP 7, MySQL 8, and MariaDB Website Databases](https://www.amazon.com/Practical-MySQL-MariaDB-Website-Databases/dp/1484238427?tag=uuid10-20)* by Adrian W. West, 2nd edition, September 2018 Build interactive, database-driven websites with PHP 7, MySQL 8, and MariaDB.   
  

 
*[MariaDB Essentials](https://www.packtpub.com/application-development/mariadb-essentials)* by Emilien Kenler and Federico Razzoli, October 2015 For those that don't know SQL and want to quickly jump in and learn MariaDB, or that already know MySQL but want to go further.   
  

 
*[Getting Started with MariaDB, 2nd Edition](https://www.packtpub.com/big-data-and-business-intelligence/getting-started-mariadb-second-edition)* by Daniel Bartholomew, June 2015 A beginner's guide to MariaDB. No prior MariaDB or MySQL experience necessary. An expanded update to the 1st edition.   
  

 
*[Learning MySQL and MariaDB](http://www.amazon.com/gp/product/1449362907/)* by Russell J. T. Dyer, April 2015. An introduction to MariaDB: developing databases, using SQL statements, as well as basic administration tasks.   
  

 
*[MariaDB Beginners Guide](http://www.amazon.com/gp/product/B00MQC06HC)* by Rodrigo Ribeiro Gonçalves, August 2014 A book for newcomers to MariaDB and SQL.   
  

 
*[Getting Started with MariaDB](https://www.packtpub.com/big-data-and-business-intelligence/getting-started-mariadb)* by Daniel Bartholomew, October 2013 A beginner's guide to MariaDB. No prior MariaDB or MySQL experience necessary.   
  

 
*[MariaDB Crash Course](http://forta.com/books/0321799941/)* by Ben Forta, September 2011 First MariaDB book. For people who want to learn SQL and the basics of MariaDB.   
  

 
*[Building a Web Application with PHP and MariaDB: A Reference Guide](https://www.amazon.com/dp/B00L2AP6ME)* by Sai Srinivas Sriparasa, June 2014 Learn how to construct scalable and secure web applications   
  

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/beginner-books/>

SMALLINT
========

    Syntax
------

 
```
SMALLINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 A small [integer](../sql_language-data_types-int/index). The signed range is -32768 to 32767. The unsigned range is 0 to 65535.

 If a column has been set to ZEROFILL, all values will be prepended by zeros so that the SMALLINT value contains a number of M digits.

 **Note:** If the ZEROFILL attribute has been specified, the column will automatically become UNSIGNED.

 `INT2` is a synonym for `SMALLINT`.

 For more details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 Examples
--------

 
```
CREATE TABLE smallints (a SMALLINT,b SMALLINT UNSIGNED,c SMALLINT ZEROFILL);

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO smallints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO smallints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,10);

INSERT INTO smallints VALUES (32768,32768,32768);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO smallints VALUES (32767,32768,32768);

SELECT * FROM smallints;
+-------+-------+-------+
| a     | b     | c     |
+-------+-------+-------+
|   -10 |    10 | 00010 |
| 32767 | 32768 | 32768 |
+-------+-------+-------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO smallints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.09 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO smallints VALUES (-10,10,10);

INSERT INTO smallints VALUES (32768,32768,32768);
Query OK, 1 row affected, 1 warning (0.04 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO smallints VALUES (32767,32768,32768);

SELECT * FROM smallints;
+-------+-------+-------+
| a     | b     | c     |
+-------+-------+-------+
|   -10 |     0 | 00000 |
|   -10 |    10 | 00000 |
|   -10 |    10 | 00010 |
| 32767 | 32768 | 32768 |
| 32767 | 32768 | 32768 |
+-------+-------+-------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [TINYINT](../tinyint/index)
* [MEDIUMINT](../mediumint/index)
* [INTEGER](../int/index)
* [BIGINT](../bigint/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/smallint/>

INT
===

    Syntax
------

 
```
INT[(M)] [SIGNED | UNSIGNED | ZEROFILL]
INTEGER[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 A normal-size integer. When marked UNSIGNED, it ranges from 0 to 4294967295, otherwise its range is -2147483648 to 2147483647 (SIGNED is the default). If a column has been set to ZEROFILL, all values will be prepended by zeros so that the INT value contains a number of M digits. INTEGER is a synonym for INT.

 **Note:** If the ZEROFILL attribute has been specified, the column will automatically become UNSIGNED.

 `INT4` is a synonym for `INT`.

 For details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 Examples
--------

 
```
CREATE TABLE ints (a INT,b INT UNSIGNED,c INT ZEROFILL);

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO ints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO ints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,10);

INSERT INTO ints VALUES (2147483648,2147483648,2147483648);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO ints VALUES (2147483647,2147483648,2147483648);

SELECT * FROM ints;
+------------+------------+------------+
| a          | b          | c          |
+------------+------------+------------+
|        -10 |         10 | 0000000010 |
| 2147483647 | 2147483648 | 2147483648 |
+------------+------------+------------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO ints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.10 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO ints VALUES (-10,10,10);

INSERT INTO ints VALUES (2147483648,2147483648,2147483648);
Query OK, 1 row affected, 1 warning (0.07 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO ints VALUES (2147483647,2147483648,2147483648);

SELECT * FROM ints;
+------------+------------+------------+
| a          | b          | c          |
+------------+------------+------------+
|        -10 |          0 | 0000000000 |
|        -10 |         10 | 0000000000 |
|        -10 |         10 | 0000000010 |
| 2147483647 | 2147483648 | 2147483648 |
| 2147483647 | 2147483648 | 2147483648 |
+------------+------------+------------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [TINYINT](../tinyint/index)
* [SMALLINT](../smallint/index)
* [MEDIUMINT](../mediumint/index)
* [BIGINT](../bigint/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int/>

MEDIUMINT
=========

    Syntax
------

 
```
MEDIUMINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 A medium-sized integer. The signed range is -8388608 to 8388607. The unsigned range is 0 to 16777215.

 `ZEROFILL` pads the integer with zeroes and assumes `UNSIGNED` (even if `UNSIGNED` is not specified).

 `INT3` is a synonym for `MEDIUMINT`.

 For details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 Examples
--------

 
```
CREATE TABLE mediumints (a MEDIUMINT,b MEDIUMINT UNSIGNED,c MEDIUMINT ZEROFILL);

DESCRIBE mediumints;
+-------+--------------------------------+------+-----+---------+-------+
| Field | Type                           | Null | Key | Default | Extra |
+-------+--------------------------------+------+-----+---------+-------+
| a     | mediumint(9)                   | YES  |     | NULL    |       |
| b     | mediumint(8) unsigned          | YES  |     | NULL    |       |
| c     | mediumint(8) unsigned zerofill | YES  |     | NULL    |       |
+-------+--------------------------------+------+-----+---------+-------+

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO mediumints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO mediumints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,10);

INSERT INTO mediumints VALUES (8388608,8388608,8388608);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO mediumints VALUES (8388607,8388608,8388608);

SELECT * FROM mediumints;
+---------+---------+----------+
| a       | b       | c        |
+---------+---------+----------+
|     -10 |      10 | 00000010 |
| 8388607 | 8388608 | 08388608 |
+---------+---------+----------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO mediumints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.05 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO mediumints VALUES (-10,10,10);

INSERT INTO mediumints VALUES (8388608,8388608,8388608);
Query OK, 1 row affected, 1 warning (0.05 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO mediumints VALUES (8388607,8388608,8388608);

SELECT * FROM mediumints;
+---------+---------+----------+
| a       | b       | c        |
+---------+---------+----------+
|     -10 |       0 | 00000000 |
|     -10 |       0 | 00000000 |
|     -10 |      10 | 00000000 |
|     -10 |      10 | 00000010 |
| 8388607 | 8388608 | 08388608 |
| 8388607 | 8388608 | 08388608 |
+---------+---------+----------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [TINYINT](../tinyint/index)
* [SMALLINT](../smallint/index)
* [INTEGER](../int/index)
* [BIGINT](../bigint/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mediumint/>

Numeric Data Type Overview
==========================

    There are a number of numeric data types:

 * [TINYINT](../tinyint/index)
* [BOOLEAN](../boolean/index) - Synonym for TINYINT(1)
* [INT1](../int1/index) - Synonym for TINYINT
* [SMALLINT](../smallint/index)
* [INT2](../int2/index) - Synonym for SMALLINT
* [MEDIUMINT](../mediumint/index)
* [INT3](../int3/index) - Synonym for MEDIUMINT
* [INT](../int/index), INTEGER
* [INT4](../int4/index) - Synonym for INT
* [BIGINT](../bigint/index)
* [INT8](../int8/index) - Synonym for BIGINT
* [DECIMAL](../decimal/index), DEC, NUMERIC, FIXED
* [FLOAT](../float/index)
* [DOUBLE](../double/index), DOUBLE PRECISION, REAL
* [BIT](../bit/index)

 See the specific articles for detailed information on each.

 SIGNED, UNSIGNED and ZEROFILL
-----------------------------

 Most numeric types can be defined as `SIGNED`, `UNSIGNED` or `ZEROFILL`, for example:

 
```
TINYINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

If `SIGNED`, or no attribute, is specified, a portion of the numeric type will be reserved for the sign (plus or minus). For example, a TINYINT SIGNED can range from -128 to 127. 

 If `UNSIGNED` is specified, no portion of the numeric type is reserved for the sign, so for integer types range can be larger. For example, a TINYINT UNSIGNED can range from 0 to 255. Floating point and fixed-point types also can be `UNSIGNED`, but this only prevents negative values from being stored and doesn't alter the range. 

 If `ZEROFILL` is specified, the column will be set to UNSIGNED and the spaces used by default to pad the field are replaced with zeros. `ZEROFILL` is ignored in expressions or as part of a [UNION](../union/index). `ZEROFILL` is a non-standard MySQL and MariaDB enhancement.

 Note that although the preferred syntax indicates that the attributes are exclusive, more than one attribute can be specified.

 Until [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/) ([MDEV-8659](https://jira.mariadb.org/browse/MDEV-8659)), any combination of the attributes could be used in any order, with duplicates. In this case:

 * the presence of `ZEROFILL` makes the column `UNSIGNED ZEROFILL`.
* the presence of `UNSIGNED` makes the column `UNSIGNED`.

 From [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), only the following combinations are supported:

 * `SIGNED`
* `UNSIGNED`
* `ZEROFILL`
* `UNSIGNED ZEROFILL`
* `ZEROFILL UNSIGNED`

 The latter two should be replaced with simply `ZEROFILL`, but are still accepted by the parser.

 ### Examples

 
```
CREATE TABLE zf (
  i1 TINYINT SIGNED,
  i2 TINYINT UNSIGNED,
  i3 TINYINT ZEROFILL
);

INSERT INTO zf VALUES (2,2,2);

SELECT * FROM zf;
+------+------+------+
| i1   | i2   | i3   |
+------+------+------+
|    2 |    2 |  002 |
+------+------+------+

```

Range
-----

 When attempting to add a value that is out of the valid range for the numeric type, MariaDB will react depending on the [strict SQL\_MODE](../sql-mode/index#strict-mode) setting.

 If [strict\_mode](../sql-mode/index#strict-mode) has been set (the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)), MariaDB will return an error.

 If [strict\_mode](../sql-mode/index#strict-mode) has not been set (the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)), MariaDB will adjust the number to fit in the field, returning a warning.

 ### Examples

 With strict\_mode set:

 
```
SHOW VARIABLES LIKE 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                     |
+---------------+-------------------------------------------------------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------+

CREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);

INSERT INTO ranges VALUES (257,257,257);
ERROR 1264 (22003): Out of range value for column 'i1' at row 1

SELECT * FROM ranges;
Empty set (0.10 sec)

```

With strict\_mode unset:

 
```
SHOW VARIABLES LIKE 'sql_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+

CREATE TABLE ranges (i1 TINYINT, i2 SMALLINT, i3 TINYINT UNSIGNED);

INSERT INTO ranges VALUES (257,257,257);
Query OK, 1 row affected, 2 warnings (0.00 sec)

SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'i1' at row 1 |
| Warning | 1264 | Out of range value for column 'i3' at row 1 |
+---------+------+---------------------------------------------+
2 rows in set (0.00 sec)

SELECT * FROM ranges;
+------+------+------+
| i1   | i2   | i3   |
+------+------+------+
|  127 |  257 |  255 |
+------+------+------+

```

Auto\_increment
---------------

 The `AUTO_INCREMENT` attribute can be used to generate a unique identity for new rows. For more details, see [auto\_increment](../auto_increment/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numeric-data-type-overview/>

Intermediate and Advanced Books
===============================

    Below is a list of books on MariaDB for Intermediate and Advanced Developers and Administrators, listed in order by date of publication—the most recent first. We've provided links to Amazon.com or the publisher for convenience, but they can be found at many bookstores.

 

*[Migrating to MariaDB](https://www.apress.com/gp/book/9781484239964)* by William Wood, December 2018 Describes the process and lessons learned during a migration from a proprietary database management engine to the MariaDB open source solution.  

*[Query Answers with MariaDB: Volume II: Introduction to SQL Queries](https://www.amazon.co.uk/Query-Answers-MariaDB-Depth-Querying/dp/1999617258/ref=sr_1_5?keywords=mariadb&qid=1558010639&s=books&sr=1-5)* by Adam Aspin, Karine Aspin , October 2018 Helps you further develop your analytical abilities as you discover how to write powerful SQL queries.  

*[Query Answers with MariaDB: Volume I: Introduction to SQL Queries](https://www.amazon.com/Query-Answers-MariaDB-Introduction-Queries/dp/199961724X?tag=uuid10-20)* by Adam Aspin, Karine Aspin , October 2018 Helps you develop your analytical abilities as you discover how to write powerful SQL queries.  

*[MariaDB and MySQL Common Table Expressions and Window Functions Revealed](http://apress.com/9781484231197)* by Daniel Bartholomew, November 2017 An introduction to [Common Table Expressions](../common-table-expressions/index) (CTEs) and [Window Functions](../window-functions/index) in MariaDB and MySQL.  

*[MariaDB : Administration et optimisation](https://www.amazon.co.uk/MariaDB-Administration-optimisation-St%C3%A9phane-Combaudon/dp/2409008550)* by Stéphane Combaudon, July 2017 (French) S'adresse aux développeurs et administrateurs MySQL ou MariaDB désireux de consolider leurs connaissances sur la principale variante de MySQL.  

*[MariaDB High Performance](https://www.packtpub.com/application-development/mariadb-high-performance)* by Pierre Mavro, September 2014 For system administrators/architects or DBAs with existing MariaDB knowledge who want to learn more about how to grow their current infrastructure to support larger traffic.  

*[Mastering MariaDB](https://www.packtpub.com/application-development/mastering-mariadb)* by Federico Razzoli, September 2014 Aimed at intermediate users who want to learn how to administrate a MariaDB server or a set of servers.  

*[MariaDB Cookbook](https://www.packtpub.com/big-data-and-business-intelligence/mariadb-cookbook)* by Daniel Bartholomew, March 2014 A cookbook filled with useful MariaDB recipes. Chapters cover such things as [Sphinx](../sphinxse/index), [Connect](../connect/index), [Cassandra](../cassandra/index), [virtual](../virtual-columns/index) and [dynamic columns](../dynamic-columns/index), [TokuDB](../tokudb/index), and more.  

*[Building a Web Application with PHP and MariaDB: A Reference Guide](https://www.packtpub.com/application-development/building-web-application-php-and-mariadb-reference-guide)* by Sai Srinivas Sriparasa, June 2014 A how-to guide for creating scalable and secure web applications with PHP and MariaDB     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/intermediate-and-advanced-books/>

Books on MariaDB Code
=====================

    Below is a list of books on coding in MariaDB, listed in order by date of publication—the most recent first. We've provided links to Amazon.com or the publisher for convenience, but they can be found at many bookstores.

 

*[Understanding MySQL Internals](http://www.amazon.com/dp/0596009577)* by Sasha Pachev, former MySQL developer at MySQL AB, April 2007 This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB! Not all topics are covered and some parts are slightly outdated, but still the best book on this topic.   
  

 
*[MySQL 5.1 Plugin Development](http://www.amazon.com/dp/1849510601)* by Sergei Golubchik and Andrew Hutching, August 2010 A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB!     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/books-on-mariadb-code/>

Inserting and Updating with Views
=================================

     A [view](../views/index) can be used for inserting or updating. However, there are certain limitations.

 Updating with views
-------------------

 A view cannot be used for updating if it uses any of the following:

 * ALGORITHM=TEMPTABLE (see [View Algorithms](../view-algorithms/index))
* [HAVING](../select/index)
* [GROUP BY](../select/index#group-by)
* [DISTINCT](../select/index#distinct)
* [UNION](../union/index)
* [UNION ALL](../union/index)
* An aggregate function, such as [MAX()](../max/index), [MIN()](../min/index), [SUM()](../sum/index) or [COUNT()](../count/index)
* subquery in the SELECT list
* subquery in the WHERE clause referring to a table in the FROM clause
* if it has no underlying table because it refers only to literal values
* the FROM clause contains a non-updatdable view.
* multiple references to any base table column
* an outer join
* an inner join where more than one table in the view definition is being updated
* if there's a LIMIT clause, the view does not contain all primary or not null unique key columns from the underlying table and the [updatable\_views\_with\_limit](../server-system-variables/index#updatable_views_with_limit) system variable is set to `0`.

 Inserting with views
--------------------

 A view cannot be used for inserting if it fails any of the criteria for [updating](#updating-with-views), and must also meet the following conditions:

 * the view contains all base table columns that don't have default values
* no base table columns are present in view select list more than once
* the view columns are all simple columns, and not derived in any way. The following are examples of derived columns
	+ column\_name + 25
	+ LOWER(column\_name)
	+ (subquery)
	+ 9.5
	+ column1 / column2

 Checking whether a view is updatable
------------------------------------

 MariaDB stores an IS\_UPDATABLE flag with each view, so it is always possible to see if MariaDB considers a view updatable (although not necessarily insertable) by querying the IS\_UPDATABLE column in the INFORMATION\_SCHEMA.VIEWS table.

 WITH CHECK OPTION
-----------------

 The WITH CHECK OPTION clause is used to prevent updates or inserts to views unless the WHERE clause in the SELECT statement is true.

 There are two keywords that can be applied. WITH LOCAL CHECK OPTION restricts the CHECK OPTION to only the view being defined, while WITH CASCADED CHECK OPTION checks all underlying views as well. CASCADED is treated as default if neither keyword is given.

 If a row is rejected because of the CHECK OPTION, an error similar to the following is produced:

 
```
ERROR 1369 (HY000): CHECK OPTION failed 'db_name.view_name'

```

A view with a WHERE which is always false (like `WHERE 0`) and WITH CHECK OPTION is similar to a [BLACKHOLE](../blackhole/index) table: no row is ever inserted and no row is ever returned. An insertable view with a WHERE which is always false but no CHECK OPTION is a view that accepts data but does not show them.

 Examples
--------

 
```
CREATE TABLE table1 (x INT);

CREATE VIEW view1 AS SELECT x, 99 AS y FROM table1;

```

Checking whether the view is updateable:

 
```
SELECT TABLE_NAME,IS_UPDATABLE FROM INFORMATION_SCHEMA.VIEWS;
+------------+--------------+
| TABLE_NAME | IS_UPDATABLE |
+------------+--------------+
| view1      | YES          |
+------------+--------------+

```

This query works, as the view is updateable:

 
```
UPDATE view1 SET x = 5;

```

This query fails, since column `y` is a literal.

 
```
UPDATE view1 SET y = 5;
ERROR 1348 (HY000): Column 'y' is not updatable

```

Here are three views to demonstrate the WITH CHECK OPTION clause.

 
```
CREATE VIEW view_check1 AS SELECT * FROM table1 WHERE x < 100 WITH CHECK OPTION;

CREATE VIEW view_check2 AS SELECT * FROM view_check1 WHERE x > 10 WITH LOCAL CHECK OPTION;

CREATE VIEW view_check3 AS SELECT * FROM view_check1 WHERE x > 10 WITH CASCADED CHECK OPTION;

```

This insert succeeds, as `view_check2` only checks the insert against `view_check2`, and the WHERE clause evaluates to true (`150` is `>10`).

 
```
INSERT INTO view_check2 VALUES (150);

```

This insert fails, as `view_check3` checks the insert against both `view_check3` and the underlying views. The WHERE clause for `view_check1` evaluates as false (`150` is `>10`, but `150` is not `<100`), so the insert fails.

 
```
INSERT INTO view_check3 VALUES (150);
ERROR 1369 (HY000): CHECK OPTION failed 'test.view_check3'

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inserting-and-updating-with-views/>

INTEGER
=======

    Syntax
------

 
```
INTEGER[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 This type is a synonym for [INT](../sql_language-data_types-int/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/integer/>

DEC, NUMERIC, FIXED
===================

    Syntax
------

 
```
DEC[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

NUMERIC[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

FIXED[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 These types are synonyms for [DECIMAL](../decimal/index). The `FIXED` synonym is available for compatibility with other database systems.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dec-numeric-fixed/>

BIGINT
======

    Syntax
------

 
```
BIGINT[(M)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 A large integer. The signed range is `-9223372036854775808` to `9223372036854775807`. The unsigned range is `0` to `18446744073709551615`.

 If a column has been set to ZEROFILL, all values will be prepended by zeros so that the BIGINT value contains a number of M digits.

 **Note:** If the ZEROFILL attribute has been specified, the column will automatically become UNSIGNED.

 For more details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 `SERIAL` is an alias for:

 
```
BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE

```

`INT8` is a synonym for `BIGINT`.

 Examples
--------

 
```
CREATE TABLE bigints (a BIGINT,b BIGINT UNSIGNED,c BIGINT ZEROFILL);

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO bigints VALUES (-10,-10,-10);
ERROR 1264 (22003): Out of range value for column 'b' at row 1

INSERT INTO bigints VALUES (-10,10,-10);
ERROR 1264 (22003): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,10);

INSERT INTO bigints VALUES (9223372036854775808,9223372036854775808,9223372036854775808);
ERROR 1264 (22003): Out of range value for column 'a' at row 1

INSERT INTO bigints VALUES (9223372036854775807,9223372036854775808,9223372036854775808);

SELECT * FROM bigints;
+---------------------+---------------------+----------------------+
| a                   | b                   | c                    |
+---------------------+---------------------+----------------------+
|                 -10 |                  10 | 00000000000000000010 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
+---------------------+---------------------+----------------------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO bigints VALUES (-10,-10,-10);
Query OK, 1 row affected, 2 warnings (0.08 sec)
Warning (Code 1264): Out of range value for column 'b' at row 1
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,-10);
Query OK, 1 row affected, 1 warning (0.08 sec)
Warning (Code 1264): Out of range value for column 'c' at row 1

INSERT INTO bigints VALUES (-10,10,10);

INSERT INTO bigints VALUES (9223372036854775808,9223372036854775808,9223372036854775808);
Query OK, 1 row affected, 1 warning (0.07 sec)
Warning (Code 1264): Out of range value for column 'a' at row 1

INSERT INTO bigints VALUES (9223372036854775807,9223372036854775808,9223372036854775808);

SELECT * FROM bigints;
+---------------------+---------------------+----------------------+
| a                   | b                   | c                    |
+---------------------+---------------------+----------------------+
|                 -10 |                   0 | 00000000000000000000 |
|                 -10 |                  10 | 00000000000000000000 |
|                 -10 |                  10 | 00000000000000000010 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
| 9223372036854775807 | 9223372036854775808 | 09223372036854775808 |
+---------------------+---------------------+----------------------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [TINYINT](../tinyint/index)
* [SMALLINT](../smallint/index)
* [MEDIUMINT](../mediumint/index)
* [INTEGER](../int/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bigint/>

DECIMAL
=======

    Syntax
------

 
```
DECIMAL[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

```
 Description
-----------

 A packed "exact" fixed-point number. `M` is the total number of digits (the precision) and `D` is the number of digits after the decimal point (the scale). 

 * The decimal point and (for negative numbers) the "-" sign are not counted in `M`.
* If `D` is `0`, values have no decimal point or fractional part and on [INSERT](../insert/index) the value will be rounded to the nearest `DECIMAL`.
* The maximum number of digits (`M`) for `DECIMAL` is 65.
* The maximum number of supported decimals (`D`) is `30` before [MariadB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and `38` afterwards.
* If `D` is omitted, the default is `0`. If `M` is omitted, the default is `10`.

 `UNSIGNED`, if specified, disallows negative values.

 `ZEROFILL`, if specified, pads the number with zeros, up to the total number of digits specified by `M`.

 All basic calculations (+, -, \*, /) with `DECIMAL` columns are done with a precision of 65 digits.

 For more details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 `DEC`, `NUMERIC` and `FIXED` are synonyms, as well as `NUMBER` in [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types).

 Examples
--------

 
```
CREATE TABLE t1 (d DECIMAL UNSIGNED ZEROFILL);

INSERT INTO t1 VALUES (1),(2),(3),(4.0),(5.2),(5.7);
Query OK, 6 rows affected, 2 warnings (0.16 sec)
Records: 6  Duplicates: 0  Warnings: 2

Note (Code 1265): Data truncated for column 'd' at row 5
Note (Code 1265): Data truncated for column 'd' at row 6

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 0000000001 |
| 0000000002 |
| 0000000003 |
| 0000000004 |
| 0000000005 |
| 0000000006 |
+------------+

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO t1 VALUES (-7);
ERROR 1264 (22003): Out of range value for column 'd' at row 1

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO t1 VALUES (-7);
Query OK, 1 row affected, 1 warning (0.02 sec)
Warning (Code 1264): Out of range value for column 'd' at row 1

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 0000000001 |
| 0000000002 |
| 0000000003 |
| 0000000004 |
| 0000000005 |
| 0000000006 |
| 0000000000 |
+------------+

```

See Also
--------

 * [Numeric Data Type Overview](../numeric-data-type-overview/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/decimal/>

Numeric Data Types
===================

  

| Title | Description |
| --- | --- |
|  [Numeric Data Type Overview](../numeric-data-type-overview/index) |  Overview and usage of the numeric data types.  |
|  [TINYINT](../tinyint/index) |  Tiny integer, -128 to 127 signed.  |
|  [BOOLEAN](../boolean/index) |  Synonym for TINYINT(1).  |
|  [SMALLINT](../smallint/index) |  Small integer from -32768 to 32767 signed.  |
|  [MEDIUMINT](../mediumint/index) |  Medium integer from -8388608 to 8388607 signed.  |
|  [INT](../int/index) |  Integer from -2147483648 to 2147483647 signed.  |
|  [INTEGER](../integer/index) |  Synonym for INT  |
|  [BIGINT](../bigint/index) |  Large integer.  |
|  [DECIMAL](../decimal/index) |  A packed "exact" fixed-point number.  |
|  [DEC, NUMERIC, FIXED](../dec-numeric-fixed/index) |  Synonyms for DECIMAL  |
|  [NUMBER](../number/index) |  Synonym for DECIMAL in Oracle mode.  |
|  [FLOAT](../float/index) |  Single-precision floating-point number  |
|  [DOUBLE](../double/index) |  Normal-size (double-precision) floating-point number  |
|  [DOUBLE PRECISION](../double-precision/index) |  REAL and DOUBLE PRECISION are synonyms for DOUBLE.  |
|  [BIT](../bit/index) |  Bit field type.  |
|  [Floating-point Accuracy](../floating-point-accuracy/index) |  Not all floating-point numbers can be stored with exact precision  |
|  [INT1](../int1/index) |  A synonym for TINYINT.  |
|  [INT2](../int2/index) |  Synonym for SMALLINT.  |
|  [INT3](../int3/index) |  Synonym for MEDIUMINT.  |
|  [INT4](../int4/index) |  Synonym for INT.  |
|  [INT8](../int8/index) |  Synonym for BIGINT.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-types-numeric-data-types/>

DOUBLE
======

    Syntax
------

 
```
DOUBLE[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]
DOUBLE PRECISION[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]
REAL[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]

```
 Description
-----------

 A normal-size (double-precision) floating-point number (see [FLOAT](../float/index) for a single-precision floating-point number).

 Allowable values are:

 * `-1.7976931348623157E+308` *to* `-2.2250738585072014E-308`
* `0`
* `2.2250738585072014E-308` *to* `1.7976931348623157E+308`

 These are the theoretical limits, based on the IEEE standard. The actual range might be slightly smaller depending on your hardware or operating system.

 `M` is the total number of digits and `D` is the number of digits following the decimal point. If `M` and `D` are omitted, values are stored to the limits allowed by the hardware. A double-precision floating-point number is accurate to approximately 15 decimal places.

 `UNSIGNED`, if specified, disallows negative values.

 `ZEROFILL`, if specified, pads the number with zeros, up to the total number of digits specified by `M`.

 REAL and DOUBLE PRECISION are synonyms, unless the REAL\_AS\_FLOAT [SQL mode](../sql_mode/index) is enabled, in which case REAL is a synonym for [FLOAT](../float/index) rather than DOUBLE.

 See [Floating Point Accuracy](../floating-point-accuracy/index) for issues when using floating-point numbers.

 For more details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 Examples
--------

 
```
CREATE TABLE t1 (d DOUBLE(5,0) zerofill);

INSERT INTO t1 VALUES (1),(2),(3),(4);

SELECT * FROM t1;
+-------+
| d     |
+-------+
| 00001 |
| 00002 |
| 00003 |
| 00004 |
+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/double/>

FLOAT
=====

    Syntax
------

 
```
FLOAT[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]

```
 Description
-----------

 A small (single-precision) floating-point number (see [DOUBLE](../double/index) for a regular-size floating point number). Allowable values are:

 * -3.402823466E+38 to -1.175494351E-38
* 0
* 1.175494351E-38 to 3.402823466E+38.

 These are the theoretical limits, based on the IEEE standard. The actual range might be slightly smaller depending on your hardware or operating system.

 M is the total number of digits and D is the number of digits following the decimal point. If M and D are omitted, values are stored to the limits allowed by the hardware. A single-precision floating-point number is accurate to approximately 7 decimal places.

 UNSIGNED, if specified, disallows negative values.

 Using FLOAT might give you some unexpected problems because all calculations in MariaDB are done with double precision. See [Floating Point Accuracy](../floating-point-accuracy/index).

 For more details on the attributes, see [Numeric Data Type Overview](../numeric-data-type-overview/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/float/>

BIT
===

    Syntax
------

 
```
BIT[(M)]

```

Description
-----------

 A bit-field type. `M` indicates the number of bits per value, from `1` to `64`. The default is `1` if `M` is omitted.

 Bit values can be inserted with `b'value'` notation, where `value` is the bit value in 0's and 1's.

 Bit fields are automatically zero-padded from the left to the full length of the bit, so for example in a BIT(4) field, '10' is equivalent to '0010'.

 Bits are returned as binary, so to display them, either add 0, or use a function such as [HEX](../hex/index), [OCT](../oct/index) or [BIN](../bin/index) to convert them.

 Examples
--------

 
```
CREATE TABLE b ( b1 BIT(8) );

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 
```
INSERT INTO b VALUES (b'11111111');

INSERT INTO b VALUES (b'01010101');

INSERT INTO b VALUES (b'1111111111111');
ERROR 1406 (22001): Data too long for column 'b1' at row 1

SELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;
+------+---------+---------+----------+
| b1+0 | HEX(b1) | OCT(b1) | BIN(b1)  |
+------+---------+---------+----------+
|  255 | FF      | 377     | 11111111 |
|   85 | 55      | 125     | 1010101  |
+------+---------+---------+----------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
INSERT INTO b VALUES (b'11111111'),(b'01010101'),(b'1111111111111');
Query OK, 3 rows affected, 1 warning (0.10 sec)
Records: 3  Duplicates: 0  Warnings: 1

SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'b1' at row 3 |
+---------+------+---------------------------------------------+

SELECT b1+0, HEX(b1), OCT(b1), BIN(b1) FROM b;
+------+---------+---------+----------+
| b1+0 | HEX(b1) | OCT(b1) | BIN(b1)  |
+------+---------+---------+----------+
|  255 | FF      | 377     | 11111111 |
|   85 | 55      | 125     | 1010101  |
|  255 | FF      | 377     | 11111111 |
+------+---------+---------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit/>

Floating-point Accuracy
=======================

    Due to their nature, not all floating-point numbers can be stored with exact precision. Hardware architecture, the CPU or even the compiler version and optimization level may affect the precision.

 If you are comparing [DOUBLEs](../double/index) or [FLOATs](../float/index) with numeric decimals, it is not safe to use the [equality](../equal/index) operator.

 Sometimes, changing a floating-point number from single-precision (FLOAT) to double-precision (DOUBLE) will fix the problem.

 Example
-------

 f1, f2 and f3 have seemingly identical values across each row, but due to floating point accuracy, the results may be unexpected.

 
```
CREATE TABLE fpn (id INT, f1 FLOAT, f2 DOUBLE, f3 DECIMAL (10,3));
INSERT INTO fpn VALUES (1,2,2,2),(2,0.1,0.1,0.1);

SELECT * FROM fpn WHERE f1*f1 = f2*f2;
+------+------+------+-------+
| id   | f1   | f2   | f3    |
+------+------+------+-------+
|    1 |    2 |    2 | 2.000 |
+------+------+------+-------+

```

The reason why only one instead of two rows was returned becomes clear when we see how the floating point squares were evaluated.

 
```
SELECT f1*f1, f2*f2, f3*f3 FROM fpn;
+----------------------+----------------------+----------+
| f1*f1                | f2*f2                | f3*f3    |
+----------------------+----------------------+----------+
|                    4 |                    4 | 4.000000 |
| 0.010000000298023226 | 0.010000000000000002 | 0.010000 |
+----------------------+----------------------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/floating-point-accuracy/>

Date and Time Data Types
=========================

  

| Title | Description |
| --- | --- |
|  [DATE](../date/index) |  The date type YYYY-MM-DD.  |
|  [TIME](../time/index) |  Time format HH:MM:SS.ssssss  |
|  [DATETIME](../datetime/index) |  Date and time combination displayed as YYYY-MM-DD HH:MM:SS.  |
|  [TIMESTAMP](../timestamp/index) |  YYYY-MM-DD HH:MM:SS  |
|  [YEAR Data Type](../year-data-type/index) |  A four-digit year.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date-and-time-data-types/>

NUMBER
======

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**
```
NUMBER[(M[,D])] [SIGNED | UNSIGNED | ZEROFILL]

```

In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `NUMBER` is a synonym for [DECIMAL](../decimal/index).

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/number/>

DATE
====

    Syntax
------

 
```
DATE

```

Description
-----------

 A date. The supported range is '`1000-01-01`' to '`9999-12-31`'. MariaDB displays `DATE` values in '`YYYY-MM-DD`' format, but can be assigned dates in looser formats, including strings or numbers, as long as they make sense. These include a short year, `YY-MM-DD`, no delimiters, `YYMMDD`, or any other acceptable delimiter, for example `YYYY/MM/DD`. For details, see [date and time literals](../date-and-time-literals/index).

 '`0000-00-00`' is a permitted special value (zero-date), unless the [NO\_ZERO\_DATE](../sql-mode/index#no_zero_date) [SQL\_MODE](../sql-mode/index) is used. Also, individual components of a date can be set to 0 (for example: '`2015-00-12`'), unless the [NO\_ZERO\_IN\_DATE](../sql-mode/index#no_zero_in_date) [SQL\_MODE](../sql-mode/index) is used. In many cases, the result of en expression involving a zero-date, or a date with zero-parts, is `NULL`. If the [ALLOW\_INVALID\_DATES](../sql-mode/index#allow_invalid_dates) SQL\_MODE is enabled, if the day part is in the range between 1 and 31, the date does not produce any error, even for months that have less than 31 days.

 ### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `DATE` with a time portion is a synonym for [DATETIME](../datetime/index). See also [mariadb\_schema](../mariadb_schema/index).

 
Examples
--------

 
```
CREATE TABLE t1 (d DATE);

INSERT INTO t1 VALUES ("2010-01-12"), ("2011-2-28"), ('120314'),('13*04*21');

SELECT * FROM t1;
+------------+
| d          |
+------------+
| 2010-01-12 |
| 2011-02-28 |
| 2012-03-14 |
| 2013-04-21 |
+------------+

```

See Also
--------

 * [mariadb\_schema](../mariadb_schema/index) data type qualifier

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date/>

DOUBLE PRECISION
================

    Syntax
------

 
```
DOUBLE PRECISION[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]
REAL[(M,D)] [SIGNED | UNSIGNED | ZEROFILL]

```

Description
-----------

 REAL and DOUBLE PRECISION are synonyms for [DOUBLE](../double/index). 

 Exception: If the REAL\_AS\_FLOAT [SQL mode](../sql_mode/index) is enabled, REAL is a synonym for [FLOAT](../float/index) rather than [DOUBLE](../double/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/double-precision/>

DATETIME
========

    Syntax
------

 
```
DATETIME [(microsecond precision)]

```

Description
-----------

 A date and time combination.

 MariaDB displays `DATETIME` values in '`YYYY-MM-DD HH:MM:SS.ffffff`' format, but allows assignment of values to `DATETIME` columns using either strings or numbers. For details, see [date and time literals](../date-and-time-literals/index).

 DATETIME columns also accept [CURRENT\_TIMESTAMP](../now/index) as the default value.

 [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) introduced the [--mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format) option, on by default, which allows MariaDB to store DATETMEs using the same low-level format MySQL 5.6 uses. For more information, see [Internal Format](#internal-format), below.

 For storage requirements, see [Data Type Storage Requirements](../data-type-storage-requirements/index).

 Supported Values
----------------

 MariaDB stores values that use the `DATETIME` data type in a format that supports values between `1000-01-01 00:00:00.000000` and `9999-12-31 23:59:59.999999`.

 MariaDB can also store [microseconds](../microseconds-in-mariadb/index) with a precision between 0 and 6. If no microsecond precision is specified, then 0 is used by default.

 MariaDB also supports '`0000-00-00`' as a special *zero-date* value, unless [NO\_ZERO\_DATE](../sql-mode/index#no_zero_date) is specified in the [SQL\_MODE](../sql-mode/index). Similarly, individual components of a date can be set to `0` (for example: '`2015-00-12`'), unless [NO\_ZERO\_IN\_DATE](../sql-mode/index#no_zero_in_date) is specified in the [SQL\_MODE](../sql-mode/index). In many cases, the result of en expression involving a zero-date, or a date with zero-parts, is `NULL`. If the [ALLOW\_INVALID\_DATES](../sql-mode/index#allow_invalid_dates) SQL\_MODE is enabled, if the day part is in the range between 1 and 31, the date does not produce any error, even for months that have less than 31 days.

 Oracle Mode
-----------

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types), `DATE` with a time portion is a synonym for `DATETIME`. See also [mariadb\_schema](../mariadb_schema/index).

 
Internal Format
---------------

 In [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) a new temporal format was introduced from MySQL 5.6 that alters how the `TIME`, `DATETIME` and `TIMESTAMP` columns operate at lower levels. These changes allow these temporal data types to have fractional parts and negative values. You can disable this feature using the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) system variable.

 Tables that include `TIMESTAMP` values that were created on an older version of MariaDB or that were created while the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) system variable was disabled continue to store data using the older data type format.

 In order to update table columns from the older format to the newer format, execute an [ALTER TABLE... MODIFY COLUMN](../alter-table/index#modify-column) statement that changes the column to the \*same\* data type. This change may be needed if you want to export the table's tablespace and import it onto a server that has `mysql56_temporal_format=ON` set (see [MDEV-15225](https://jira.mariadb.org/browse/MDEV-15225)).

 For instance, if you have a `DATETIME` column in your table: 

 
```
SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col DATETIME;

```

When MariaDB executes the [ALTER TABLE](../alter-table/index) statement, it converts the data from the older temporal format to the newer one. 

 In the event that you have several tables and columns using temporal data types that you want to switch over to the new format, make sure the system variable is enabled, then perform a dump and restore using `mysqldump`. The columns using relevant temporal data types are restored using the new temporal format.

 Starting from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) columns with old temporal formats are marked with a `/* mariadb-5.3 */` comment in the output of [SHOW CREATE TABLE](../show-create-table/index), [SHOW COLUMNS](../show-columns/index), [DESCRIBE](../describe/index) statements, as well as in the `COLUMN_TYPE` column of the [INFORMATION\_SCHEMA.COLUMNS Table](../information-schema-columns-table/index).

 
```
SHOW CREATE TABLE mariadb5312_datetime\G
*************************** 1. row ***************************
       Table: mariadb5312_datetime
Create Table: CREATE TABLE `mariadb5312_datetime` (
  `dt0` datetime /* mariadb-5.3 */ DEFAULT NULL,
  `dt6` datetime(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

```

Examples
--------

 
```
CREATE TABLE t1 (d DATETIME);

INSERT INTO t1 VALUES ("2011-03-11"), ("2012-04-19 13:08:22"),
 ("2013-07-18 13:44:22.123456");

SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2011-03-11 00:00:00 |
| 2012-04-19 13:08:22 |
| 2013-07-18 13:44:22 |
+---------------------+

```


```
CREATE TABLE t2 (d DATETIME(6));

INSERT INTO t2 VALUES ("2011-03-11"), ("2012-04-19 13:08:22"),
 ("2013-07-18 13:44:22.123456");

SELECT * FROM t2;
+----------------------------+
| d                          |
+----------------------------+
| 2011-03-11 00:00:00.000000 |
| 2012-04-19 13:08:22.000000 |
| 2013-07-18 13:44:22.123456 |
+----------------------------++

```

Strings used in datetime context are automatically converted to datetime(6). If you want to have a datetime without seconds, you should use [CONVERT(..,datetime)](../convert/index).

 
```
SELECT CONVERT('2007-11-30 10:30:19',datetime);
+-----------------------------------------+
| CONVERT('2007-11-30 10:30:19',datetime) |
+-----------------------------------------+
| 2007-11-30 10:30:19                     |
+-----------------------------------------+

SELECT CONVERT('2007-11-30 10:30:19',datetime(6));
+--------------------------------------------+
| CONVERT('2007-11-30 10:30:19',datetime(6)) |
+--------------------------------------------+
| 2007-11-30 10:30:19.000000                 |
+--------------------------------------------+

```

See Also
--------

 * [Data Type Storage Requirements](../data-type-storage-requirements/index)
* [CONVERT()](../convert/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#synonyms-for-basic-sql-types)
* [mariadb\_schema](../mariadb_schema/index) data type qualifier

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/datetime/>

YEAR Data Type
==============

    Syntax
------

 
```
YEAR[(4)]

```

Description
-----------

 A year in two-digit or four-digit format. The default is four-digit format. Note that the two-digit format has been deprecated since [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5527-release-notes/). 

 In four-digit format, the allowable values are 1901 to 2155, and 0000. In two-digit format, the allowable values are 70 to 69, representing years from 1970 to 2069. MariaDB displays YEAR values in YYYY format, but allows you to assign values to YEAR columns using either strings or numbers.

 Inserting numeric zero has a different result for YEAR(4) and YEAR(2). For YEAR(2), the value `00` reflects the year 2000. For YEAR(4), the value `0000` reflects the year zero. This only applies to numeric zero. String zero always reflects the year 2000.

 Examples
--------

 Accepting a string or a number:

 
```
CREATE TABLE y(y YEAR);

INSERT INTO y VALUES (1990),('2012');

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
+------+

```

With [strict\_mode](../sql-mode/index#strict-mode) set, the default from [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/):

 Out of range:

 
```
INSERT INTO y VALUES (1005),('3080');
ERROR 1264 (22003): Out of range value for column 'y' at row 1

INSERT INTO y VALUES ('2013-12-12');
ERROR 1265 (01000): Data truncated for column 'y' at row 1

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
+------+

```

With [strict\_mode](../sql-mode/index#strict-mode) unset, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 Out of range:

 
```
INSERT INTO y VALUES (1005),('3080');
Query OK, 2 rows affected, 2 warnings (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 2

SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1264 | Out of range value for column 'y' at row 1 |
| Warning | 1264 | Out of range value for column 'y' at row 2 |
+---------+------+--------------------------------------------+

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
| 0000 |
| 0000 |
+------+

```

Truncating:

 
```
INSERT INTO y VALUES ('2013-12-12');
Query OK, 1 row affected, 1 warning (0.05 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1265 | Data truncated for column 'y' at row 1 |
+---------+------+----------------------------------------+

SELECT * FROM y;
+------+
| y    |
+------+
| 1990 |
| 2012 |
| 0000 |
| 0000 |
| 2013 |
+------+

```

Difference between YEAR(2) and YEAR(4), and string and numeric zero:

 
```
CREATE TABLE y2(y YEAR(4), y2 YEAR(2));
Query OK, 0 rows affected, 1 warning (0.40 sec)

Note (Code 1287): 'YEAR(2)' is deprecated and will be removed in a future release. 
 Please use YEAR(4) instead

INSERT INTO y2 VALUES(0,0),('0','0');

SELECT YEAR(y),YEAR(y2) FROM y2;
+---------+----------+
| YEAR(y) | YEAR(y2) |
+---------+----------+
|       0 |     2000 |
|    2000 |     2000 |
+---------+----------+

```

See Also
--------

 * [YEAR() function](../year/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/year-data-type/>

TIMESTAMP
=========

    Syntax
------

 
```
TIMESTAMP [(<microsecond precision)]

```
 Description
-----------

 A timestamp in the format `YYYY-MM-DD HH:MM:SS.ffffff`.

 The timestamp field is generally used to define at which moment in time a row was added or updated and by default will automatically be assigned the current datetime when a record is inserted or updated. The automatic properties only apply to the first TIMESTAMP in the record; subsequent TIMESTAMP columns will not be changed.

 MariaDB includes the [--mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format) option, on by default, which allows MariaDB to store TIMESTAMPs using the same low-level format MySQL 5.6 uses.

 For more information, see [Internal Format](#internal-format).

 Supported Values
----------------

 MariaDB stores values that use the `TIMESTAMP` data type as the number of seconds since '1970-01-01 00:00:00' ([UTC](../coordinated-universal-time/index)). This means that the `TIMESTAMP` data type can hold values between '1970-01-01 00:00:01' ([UTC](../coordinated-universal-time/index)) and '2038-01-19 03:14:07' ([UTC](../coordinated-universal-time/index)). 

 MariaDB can also store [microseconds](../microseconds-in-mariadb/index) with a precision between 0 and 6. If no microsecond precision is specified, then 0 is used by default.

 Automatic Values
----------------

 MariaDB has special behavior for the first column that uses the `TIMESTAMP` data type in a specific table when the system variable [explicit\_defaults\_for\_timestamp](../server-system-variables/index#explicit_defaults_for_timestamp) is not set (which is the default until [MariaDB 10.10](../what-is-mariadb-1010/index)). For the first column that uses the `TIMESTAMP` data type in a specific table, MariaDB automatically assigns the following properties to the column:

 * `DEFAULT CURRENT_TIMESTAMP`
* `ON UPDATE CURRENT_TIMESTAMP`

 This means that if the column is not explicitly assigned a value in an `INSERT` or `UPDATE` query, then MariaDB will automatically initialize the column's value with the current date and time.

 This automatic initialization for `INSERT` and `UPDATE` queries can also be **explicitly enabled** for a column that uses the `TIMESTAMP` data type by specifying the `DEFAULT CURRENT_TIMESTAMP` and `ON UPDATE CURRENT_TIMESTAMP` clauses for the column. In these clauses, any synonym of `[CURRENT\_TIMESTAMP](../now/index)` is accepted, including `CURRENT_TIMESTAMP()`, `NOW()`, `LOCALTIME`, `LOCALTIME()`, `LOCALTIMESTAMP`, and `LOCALTIMESTAMP()`.

 This automatic initialization for `INSERT` queries can also be **explicitly disabled** for a column that uses the `TIMESTAMP` data type by specifying a constant `DEFAULT` value. For example, `DEFAULT 0`.

 This automatic initialization for `UPDATE` queries can also be **explicitly disabled** for a column that uses the `TIMESTAMP` data type by specifying a `DEFAULT` clause for the column, but no `ON UPDATE` clause. If a `DEFAULT` clause is explicitly specified for a column that uses the `TIMESTAMP` data type, but an `ON UPDATE` clause is not specified for the column, then the timestamp value will not automatically change when an `UPDATE` statement is executed.

 MariaDB also has special behavior if `NULL` is assigned to column that uses the `TIMESTAMP` data type. If the column is assigned the `NULL` value in an `INSERT` or `UPDATE` query, then MariaDB will automatically initialize the column's value with the current date and time. For details, see [NULL values in MariaDB](../null-values-in-mariadb/index#auto_increment-timestamp-and-virtual-columns).

 This automatic initialization for `NULL` values can also be **explicitly disabled** for a column that uses the `TIMESTAMP` data type by specifying the `NULL` attribute for the column. In this case, if the column's value is set to `NULL`, then the column's value will actually be set to `NULL`.

 Time Zones
----------

 If a column uses the `TIMESTAMP` data type, then any inserted values are converted from the session's time zone to [Coordinated Universal Time (UTC)](../coordinated-universal-time/index) when stored, and converted back to the session's time zone when retrieved.

 MariaDB validates `TIMESTAMP` literals against the session's time zone. For example, if a specific time range never occurred in a specific time zone due to daylight savings time, then `TIMESTAMP` values within that range would be invalid for that time zone.

 MariaDB does not currently store any time zone identifier with the value of the `TIMESTAMP` data type. See [MDEV-10018](https://jira.mariadb.org/browse/MDEV-10018) for more information.

 MariaDB does not currently support time zone literals that contain time zone identifiers. See [MDEV-11829](https://jira.mariadb.org/browse/MDEV-11829) for more information.

 Limitations
-----------

 * Because the TIMESTAMP value is stored as Epoch Seconds, the timestamp value '1970-01-01 00:00:00' (UTC) is reserved since the second #0 is used to represent '0000-00-00 00:00:00'.
* In [MariaDB 5.5](../what-is-mariadb-55/index) and before there could only be one TIMESTAMP column per table that had CURRENT\_TIMESTAMP defined as its default value. This limit has no longer applied since [MariaDB 10.0](../what-is-mariadb-100/index).

 SQL\_MODE=MAXDB
---------------

 If the [SQL\_MODE](../sql-mode/index) is set to `MAXDB`, TIMESTAMP fields will be silently converted to [DATETIME](../datetime/index).

 Internal Format
---------------

 In [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) a new temporal format was introduced from MySQL 5.6 that alters how the `TIME`, `DATETIME` and `TIMESTAMP` columns operate at lower levels. These changes allow these temporal data types to have fractional parts and negative values. You can disable this feature using the `[mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format)` system variable.

 Tables that include `TIMESTAMP` values that were created on an older version of MariaDB or that were created while the `[mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format)` system variable was disabled continue to store data using the older data type format.

 In order to update table columns from the older format to the newer format, execute an `[ALTER TABLE... MODIFY COLUMN](../alter-table/index#modify-column)` statement that changes the column to the \*same\* data type. This change may be needed if you want to export the table's tablespace and import it onto a server that has `mysql56_temporal_format=ON` set (see [MDEV-15225](https://jira.mariadb.org/browse/MDEV-15225)).

 For instance, if you have a `TIMESTAMP` column in your table: 

 
```
SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col TIMESTAMP;

```

When MariaDB executes the `[ALTER TABLE](../alter-table/index)` statement, it converts the data from the older temporal format to the newer one. 

 In the event that you have several tables and columns using temporal data types that you want to switch over to the new format, make sure the system variable is enabled, then perform a dump and restore using `mysqldump`. The columns using relevant temporal data types are restored using the new temporal format.

 Starting from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) columns with old temporal formats are marked with a `/* mariadb-5.3 */` comment in the output of `[SHOW CREATE TABLE](../show-create-table/index)`, `[SHOW COLUMNS](../show-columns/index)`, `[DESCRIBE](../describe/index)` statements, as well as in the `COLUMN_TYPE` column of the `[INFORMATION\_SCHEMA.COLUMNS Table](../information-schema-columns-table/index)`.

 
```
SHOW CREATE TABLE mariadb5312_timestamp\G
*************************** 1. row ***************************
       Table: mariadb5312_timestamp
Create Table: CREATE TABLE `mariadb5312_timestamp` (
  `ts0` timestamp /* mariadb-5.3 */ NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `ts6` timestamp(6) /* mariadb-5.3 */ NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
) ENGINE=MyISAM DEFAULT CHARSET=latin1

```


**Note:** Prior to MySQL 4.1 a different format for the TIMESTAMP datatype was used. This format is unsupported in [MariaDB 5.1](../what-is-mariadb-51/index) and upwards.

 
Examples
--------

 
```
CREATE TABLE t (id INT, ts TIMESTAMP);

DESC t;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id    | int(11)   | YES  |     | NULL              |                             |
| ts    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+

INSERT INTO t(id)  VALUES (1),(2);

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    1 | 2013-07-22 12:50:05 |
|    2 | 2013-07-22 12:50:05 |
+------+---------------------+

INSERT INTO t  VALUES (3,NULL),(4,'2001-07-22 12:12:12');

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    1 | 2013-07-22 12:50:05 |
|    2 | 2013-07-22 12:50:05 |
|    3 | 2013-07-22 12:51:56 |
|    4 | 2001-07-22 12:12:12 |
+------+---------------------+

```

Converting to Unix epoch:

 
```
SELECT ts, UNIX_TIMESTAMP(ts) FROM t;
+---------------------+--------------------+
| ts                  | UNIX_TIMESTAMP(ts) |
+---------------------+--------------------+
| 2013-07-22 12:50:05 |         1374490205 |
| 2013-07-22 12:50:05 |         1374490205 |
| 2013-07-22 12:51:56 |         1374490316 |
| 2001-07-22 12:12:12 |          995796732 |
+---------------------+--------------------+

```

Update also changes the timestamp:

 
```
UPDATE t set id=5 WHERE id=1;

SELECT * FROM t;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    5 | 2013-07-22 14:52:33 |
|    2 | 2013-07-22 12:50:05 |
|    3 | 2013-07-22 12:51:56 |
|    4 | 2001-07-22 12:12:12 |
+------+---------------------+

```

Default NULL:

 
```
CREATE TABLE t2 (id INT, ts TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP);

INSERT INTO t(id)  VALUES (1),(2);

SELECT * FROM t2;

INSERT INTO t2(id)  VALUES (1),(2);

SELECT * FROM t2;
+------+------+
| id   | ts   |
+------+------+
|    1 | NULL |
|    2 | NULL |
+------+------+

UPDATE t2 SET id=3 WHERE id=1;

SELECT * FROM t2;
+------+---------------------+
| id   | ts                  |
+------+---------------------+
|    3 | 2013-07-22 15:32:22 |
|    2 | NULL                |
+------+---------------------+

```

Only the first timestamp is automatically inserted and updated:

 
```
CREATE TABLE t3 (id INT, ts1 TIMESTAMP, ts2 TIMESTAMP);

INSERT INTO t3(id)  VALUES (1),(2);

SELECT * FROM t3;
+------+---------------------+---------------------+
| id   | ts1                 | ts2                 |
+------+---------------------+---------------------+
|    1 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    2 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
+------+---------------------+---------------------+

DESC t3;
+-------+-----------+------+-----+---------------------+-----------------------------+
| Field | Type      | Null | Key | Default             | Extra                       |
+-------+-----------+------+-----+---------------------+-----------------------------+
| id    | int(11)   | YES  |     | NULL                |                             |
| ts1   | timestamp | NO   |     | CURRENT_TIMESTAMP   | on update CURRENT_TIMESTAMP |
| ts2   | timestamp | NO   |     | 0000-00-00 00:00:00 |                             |
+-------+-----------+------+-----+---------------------+-----------------------------+

```

Explicitly setting a timestamp with the [CURRENT\_TIMESTAMP](../current_timestamp/index) function:

 
```
INSERT INTO t3(id,ts2)  VALUES (3,CURRENT_TIMESTAMP());

SELECT * FROM t3;
+------+---------------------+---------------------+
| id   | ts1                 | ts2                 |
+------+---------------------+---------------------+
|    1 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    2 | 2013-07-22 15:35:07 | 0000-00-00 00:00:00 |
|    3 | 2013-07-22 15:38:52 | 2013-07-22 15:38:52 |
+------+---------------------+---------------------+

```

Specifying the timestamp as NOT NULL:

 
```
CREATE TABLE t4 (id INT, ts TIMESTAMP NOT NULL);

INSERT INTO t4(id)  VALUES (1);
SELECT SLEEP(1);
INSERT INTO t4(id,ts) VALUES (2,NULL);

SELECT * FROM t4;

```

See Also
--------

 * [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/timestamp/>

INT1
====

    `INT1` is a synonym for [TINYINT](../tinyint/index).

 
```
CREATE TABLE t1 (x INT1);

DESC t1;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| x     | tinyint(4) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int1/>

INT2
====

    `INT2` is a synonym for [SMALLINT](../smallint/index).

 
```
CREATE TABLE t1 (x INT2);

DESC t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| x     | smallint(6) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int2/>

Geometry Types
==============

    Description
-----------

 MariaDB provides a standard way of creating spatial columns for geometry types, for example, with [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index). Currently, spatial columns are supported for [MyISAM](../myisam/index), [InnoDB](../innodb/index) and [ARCHIVE](../archive/index) tables. See also [SPATIAL INDEX](../spatial/index).

 The basic geometry type is `GEOMETRY`. But the type can be more specific. The following types are supported:

 


| Geometry Types |
| --- |
| [POINT](../point/index) |
| [LINESTRING](../linestring/index) |
| [POLYGON](../polygon/index) |
| [MULTIPOINT](../multipoint/index) |
| [MULTILINESTRING](../multilinestring/index) |
| [MULTIPOLYGON](../multipolygon/index) |
| [GEOMETRYCOLLECTION](../geometrycollection/index) |
| GEOMETRY |

 
Examples
--------

 
**Note:** For clarity, only one type is listed per table in the examples below, but a table row can contain multiple types. For example:

 
```
CREATE TABLE object (shapeA POLYGON, shapeB LINESTRING);

```


### [POINT](../point/index)

 
```
CREATE TABLE gis_point  (g POINT);
SHOW FIELDS FROM gis_point;
INSERT INTO gis_point VALUES
    (PointFromText('POINT(10 10)')),
    (PointFromText('POINT(20 10)')),
    (PointFromText('POINT(20 20)')),
    (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

```

### [LINESTRING](../linestring/index)

 
```
CREATE TABLE gis_line  (g LINESTRING);
SHOW FIELDS FROM gis_line;
INSERT INTO gis_line VALUES
    (LineFromText('LINESTRING(0 0,0 10,10 0)')),
    (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
    (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

```

### [POLYGON](../polygon/index)

 
```
CREATE TABLE gis_polygon   (g POLYGON);
SHOW FIELDS FROM gis_polygon;
INSERT INTO gis_polygon VALUES
    (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
    (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
    (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));

```

### [MULTIPOINT](../multipoint/index)

 
```
CREATE TABLE gis_multi_point (g MULTIPOINT);
SHOW FIELDS FROM gis_multi_point;
INSERT INTO gis_multi_point VALUES
    (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
    (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
    (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

```

### [MULTILINESTRING](../multilinestring/index)

 
```
CREATE TABLE gis_multi_line (g MULTILINESTRING);
SHOW FIELDS FROM gis_multi_line;
INSERT INTO gis_multi_line VALUES
    (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
    (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
    (MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));

```

### [MULTIPOLYGON](../multipolygon/index)

 
```
CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
SHOW FIELDS FROM gis_multi_polygon;
INSERT INTO gis_multi_polygon VALUES
    (MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));

```

### [GEOMETRYCOLLECTION](../geometrycollection/index)

 
```
CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
    (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
    (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
    (GeomFromText('GeometryCollection()')),
    (GeomFromText('GeometryCollection EMPTY'));

```

### [GEOMETRY](../geometry/index)

 
```
CREATE TABLE gis_geometry (g GEOMETRY);
SHOW FIELDS FROM gis_geometry;
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
INSERT into gis_geometry SELECT * FROM gis_polygon;
INSERT into gis_geometry SELECT * FROM gis_multi_point;
INSERT into gis_geometry SELECT * FROM gis_multi_line;
INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
INSERT into gis_geometry SELECT * FROM gis_geometrycollection;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-types/>

INT3
====

    `INT3` is a synonym for [MEDIUMINT](../mediumint/index).

 
```
CREATE TABLE t1 (x INT3);

DESC t1;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| x     | mediumint(9) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int3/>

INT4
====

    `INT4` is a synonym for [INT](../int/index).

 
```
CREATE TABLE t1 (x INT4);

DESC t1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| x     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int4/>

AUTO\_INCREMENT
===============

    Description
-----------

 The `AUTO_INCREMENT` attribute can be used to generate a unique identity for new rows. When you insert a new record to the table (or upon adding an [AUTO\_INCREMENT](index) attribute with the [ALTER TABLE](../alter-table/index) statement), and the auto\_increment field is [NULL](../null-values/index) or DEFAULT (in the case of an INSERT), the value will automatically be incremented. This also applies to 0, unless the [NO\_AUTO\_VALUE\_ON\_ZERO SQL\_MODE](../sql-mode/index#no_auto_value_on_zero) is enabled.

 `AUTO_INCREMENT` columns start from 1 by default. The automatically generated value can never be lower than 0.

 Each table can have only one `AUTO_INCREMENT` column. It must defined as a key (not necessarily the `PRIMARY KEY` or `UNIQUE` key). In some storage engines (including the default [InnoDB](../innodb/index)), if the key consists of multiple columns, the `AUTO_INCREMENT` column must be the first column. Storage engines that permit the column to be placed elsewhere are [Aria](../aria/index), [MyISAM](../myisam/index), [MERGE](../merge/index), [Spider](../spider/index), [TokuDB](../tokudb/index), [BLACKHOLE](../blackhole/index), [FederatedX](../federatedx/index) and [Federated](../federated-storage-engine/index).

 
```
CREATE TABLE animals (
     id MEDIUMINT NOT NULL AUTO_INCREMENT,
     name CHAR(30) NOT NULL,
     PRIMARY KEY (id)
 );

INSERT INTO animals (name) VALUES
    ('dog'),('cat'),('penguin'),
    ('fox'),('whale'),('ostrich');

```


```
SELECT * FROM animals;
+----+---------+
| id | name    |
+----+---------+
|  1 | dog     |
|  2 | cat     |
|  3 | penguin |
|  4 | fox     |
|  5 | whale   |
|  6 | ostrich |
+----+---------+

```

`SERIAL` is an alias for `BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE`.

 
```
CREATE TABLE t (id SERIAL, c CHAR(1)) ENGINE=InnoDB;

SHOW CREATE TABLE t \G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `c` char(1) DEFAULT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

Setting or Changing the Auto\_Increment Value
---------------------------------------------

 You can use an `[ALTER TABLE](../alter-table/index)` statement to assign a new value to the `auto_increment` table option, or set the [insert\_id](../server-system-variables/index#insert_id) server system variable to change the next `AUTO_INCREMENT` value inserted by the current session.

 `[LAST\_INSERT\_ID()](../last_insert_id/index)` can be used to see the last `AUTO_INCREMENT` value inserted by the current session.

 
```
ALTER TABLE animals AUTO_INCREMENT=8;

INSERT INTO animals (name) VALUES ('aardvark');

SELECT * FROM animals;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | dog       |
|  2 | cat       |
|  3 | penguin   |
|  4 | fox       |
|  5 | whale     |
|  6 | ostrich   |
|  8 | aardvark  |
+----+-----------+

SET insert_id=12;

INSERT INTO animals (name) VALUES ('gorilla');

SELECT * FROM animals;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | dog       |
|  2 | cat       |
|  3 | penguin   |
|  4 | fox       |
|  5 | whale     |
|  6 | ostrich   |
|  8 | aardvark  |
| 12 | gorilla   |
+----+-----------+

```

InnoDB
------

 Until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), InnoDB used an auto-increment counter that is stored in memory. When the server restarts, the counter is re-initialized to the highest value used in the table, which cancels the effects of any AUTO\_INCREMENT = N option in the table statements.

 From [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), this restriction has been lifted and AUTO\_INCREMENT is persistent.

 See also [AUTO\_INCREMENT Handling in InnoDB](../auto_increment-handling-in-innodb/index).

 Setting Explicit Values
-----------------------

 It is possible to specify a value for an `AUTO_INCREMENT` column. If the key is primary or unique, the value must not already exist in the key.

 If the new value is higher than the current maximum value, the `AUTO_INCREMENT` value is updated, so the next value will be higher. If the new value is lower than the current maximum value, the `AUTO_INCREMENT` value remains unchanged.

 The following example demonstrates these behaviors:

 
```
CREATE TABLE t (id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY) ENGINE = InnoDB;

INSERT INTO t VALUES (NULL);
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
+----+

INSERT INTO t VALUES (10); -- higher value
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
| 10 |
+----+

INSERT INTO t VALUES (2); -- lower value
INSERT INTO t VALUES (NULL); -- auto value
SELECT id FROM t;
+----+
| id |
+----+
|  1 |
|  2 |
| 10 |
| 11 |
+----+

```

The [ARCHIVE](../archive/index) storage engine does not allow to insert a value that is lower than the current maximum.

 Missing Values
--------------

 An AUTO\_INCREMENT column normally has missing values. This happens because if a row is deleted, or an AUTO\_INCREMENT value is explicitly updated, old values are never re-used. The REPLACE statement also deletes a row, and its value is wasted. With InnoDB, values can be reserved by a transaction; but if the transaction fails (for example, because of a ROLLBACK) the reserved value will be lost.

 Thus AUTO\_INCREMENT values can be used to sort results in a chronological order, but not to create a numeric sequence.

 Replication
-----------

 To make master-master or Galera safe to use `AUTO_INCREMENT` one should use the system variables [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) and [auto\_increment\_offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset) to generate unique values for each server.

 CHECK Constraints, DEFAULT Values and Virtual Columns
-----------------------------------------------------

 
**MariaDB starting with [10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)**From [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) auto\_increment columns are no longer permitted in [CHECK constraints](../constraint/index), [DEFAULT value expressions](../create-table/index#default) and [virtual columns](../virtual-computed-columns/index). They were permitted in earlier versions, but did not work correctly. See [MDEV-11117](https://jira.mariadb.org/browse/MDEV-11117).

 
Generating Auto\_Increment Values When Adding the Attribute
-----------------------------------------------------------

 
```
CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (0),(0),(0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+

```


```
CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (5),(0),(8),(0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 5 |
| 6 |
| 8 |
| 9 |
+---+

```

If the [NO\_AUTO\_VALUE\_ON\_ZERO SQL\_MODE](../sql-mode/index#no_auto_value_on_zero) is set, zero values will not be automatically incremented: 

 
```
SET SQL_MODE='no_auto_value_on_zero';
CREATE OR REPLACE TABLE t1 (a INT);
INSERT t1 VALUES (3), (0);
ALTER TABLE t1 MODIFY a INT NOT NULL AUTO_INCREMENT PRIMARY KEY;
SELECT * FROM t1;
+---+
| a |
+---+
| 0 |
| 3 |
+---+

```

See Also
--------

 * [Getting Started with Indexes](../getting-started-with-indexes/index)
* [Sequences](../sequences/index) - an alternative to auto\_increment available from [MariaDB 10.3](../what-is-mariadb-103/index)
* [AUTO\_INCREMENT FAQ](../autoincrement-faq/index)
* [LAST\_INSERT\_ID()](../last_insert_id/index)
* [AUTO\_INCREMENT handling in InnoDB](../auto_increment-handling-in-innodb/index)
* [BLACKHOLE and AUTO\_INCREMENT](../blackhole/index#blackhole-and-auto_increment)
* [UUID\_SHORT()](../uuid_short/index) - Generate unique ids
* [Generating Identifiers – from AUTO\_INCREMENT to Sequence (percona.com)](https://www.percona.com/community-blog/2018/10/12/generating-identifiers-auto_increment-sequence/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/auto_increment/>

AUTO\_INCREMENT FAQ
===================

    How do I get the last inserted auto\_increment value?
-----------------------------------------------------

 Use the [LAST\_INSERT\_ID()](../last_insert_id/index) function:

 
```
SELECT LAST_INSERT_ID();

```

What if someone else inserts before I select my id?
---------------------------------------------------

 [LAST\_INSERT\_ID()](../last_insert_id/index) is connection specific, so there is no problem from race conditions.

 How do I get the next value to be inserted?
-------------------------------------------

 You don't. Insert, then find out what you did with [LAST\_INSERT\_ID()](../last_insert_id/index).

 How do I change what number auto\_increment starts with?
--------------------------------------------------------

 `ALTER TABLE yourTable AUTO_INCREMENT = x;` — Next insert will contain `x` or `MAX(autoField) + 1`, whichever is higher

 or

 `INSERT INTO yourTable (autoField) VALUES (x);` — Next insert will contain `x+1` or `MAX(autoField) + 1`, whichever is higher

 Issuing [TRUNCATE TABLE](../truncate-table/index) will delete all the rows in the table, and will reset the auto\_increment value to 0 in most cases (some earlier versions mapped TRUNCATE to DELETE for InnoDB tables, meaning the auto\_increment value would not be reset).

 How do I renumber rows once I've deleted some in the middle?
------------------------------------------------------------

 Typically, you don't want to. Gaps are hardly ever a problem; if your application can't handle gaps in the sequence, you probably should rethink your application.

 Can I do group-wise auto\_increment?
------------------------------------

 Yes, if you use the [MyISAM engine](../myisam/index).

 How do I get the auto\_increment value in a BEFORE INSERT trigger?
------------------------------------------------------------------

 You don't. It's only available after insert.

 How do I assign two fields the same auto\_increment value in one query?
-----------------------------------------------------------------------

 You can't, not even with an AFTER INSERT trigger. Insert, then go back and update using `LAST_INSERT_ID()`. Those two statements could be wrapped into one stored procedure if you wish.

 However, you can mimic this behavior with a BEFORE INSERT trigger and a second table to store the sequence position:

 
```
CREATE TABLE sequence (table_name VARCHAR(255), position INT UNSIGNED);
INSERT INTO sequence VALUES ('testTable', 0);
CREATE TABLE testTable (firstAuto INT UNSIGNED, secondAuto INT UNSIGNED);
DELIMITER //
CREATE TRIGGER testTable_BI BEFORE INSERT ON testTable FOR EACH ROW BEGIN
  UPDATE sequence SET position = LAST_INSERT_ID(position + 1) WHERE table_name = 'testTable';
  SET NEW.firstAuto = LAST_INSERT_ID();
  SET NEW.secondAuto = LAST_INSERT_ID();
END//
DELIMITER ;
INSERT INTO testTable VALUES (NULL, NULL), (NULL, NULL);
SELECT * FROM testTable;

+-----------+------------+
| firstAuto | secondAuto |
+-----------+------------+
|         1 |          1 |
|         2 |          2 |
+-----------+------------+

```

The same sequence table can maintain separate sequences for multiple tables (or separate sequences for different fields in the same table) by adding extra rows.

 Does the auto\_increment field have to be primary key?
------------------------------------------------------

 No, it only has to be indexed. It doesn't even have to be unique.

 InnoDB and AUTO\_INCREMENT
--------------------------

 See [AUTO\_INCREMENT handling in InnoDB](../auto_increment-handling-in-innodb/index)

 General Information To Read
---------------------------

 [AUTO\_INCREMENT](../auto_increment/index)

 Manual Notes
------------

 There can be only one `AUTO_INCREMENT` column per table, it must be indexed, and it cannot have a `DEFAULT` value. An `AUTO_INCREMENT` column works properly only if it contains only positive values. Inserting a negative number is regarded as inserting a very large positive number. This is done to avoid precision problems when numbers wrap over from positive to negative and also to ensure that you do not accidentally get an `AUTO_INCREMENT` column that contains 0.

 How to start a table with a set AUTO\_INCREMENT value?
------------------------------------------------------

 
```
CREATE TABLE autoinc_test (
  h INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, 
  m INT UNSIGNED 
) AUTO_INCREMENT = 100;

INSERT INTO autoinc_test ( m ) VALUES ( 1 );

SELECT * FROM autoinc_test;
+-----+------+
| h   | m    |
+-----+------+
| 100 |    1 |
+-----+------+

```

See Also
--------

 * [AUTO\_INCREMENT](../auto_increment/index)
* [AUTO\_INCREMENT handling in XtraDB/InnoDB](../auto_increment-handling-in-xtradbinnodb/index)
* [LAST\_INSERT\_ID()](../last_insert_id/index)
* [BLACKHOLE and AUTO\_INCREMENT](../blackhole/index#blackhole-and-auto_increment)
* [Sequences](../sequences/index) - an alternative to auto\_increment available from [MariaDB 10.3](../what-is-mariadb-103/index)

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Autoincrement_FAQ> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/auto_increment-faq/>

INT8
====

    `INT8` is a synonym for [BIGINT](../bigint/index).

 
```
CREATE TABLE t1 (x INT8);

DESC t1;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| x     | bigint(20) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/int8/>

SHOW PLUGINS
============

    Syntax
------

 
```
SHOW PLUGINS;

```
 Description
-----------

  `SHOW PLUGINS` displays information about installed [plugins](../mariadb-plugins/index). The `Library` column indicates the plugin library - if it is `NULL`, the plugin is built-in and cannot be uninstalled.

 The `[PLUGINS](../information_schemaplugins-table/index)` table in the `information_schema` database contains more detailed information.

 For specific information about storage engines (a particular type of plugin), see the `[information\_schema.ENGINES](../information-schema-engines-table/index)` table and the `[SHOW ENGINES](../show-engines/index)` statement.

 Examples
--------

 
```
SHOW PLUGINS;
+----------------------------+----------+--------------------+-------------+---------+
| Name                       | Status   | Type               | Library     | License |
+----------------------------+----------+--------------------+-------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL        | GPL     |
| mysql_old_password         | ACTIVE   | AUTHENTICATION     | NULL        | GPL     |
| MRG_MyISAM                 | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| FEDERATED                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| Aria                       | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
...
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| SPHINX                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| FEEDBACK                   | DISABLED | INFORMATION SCHEMA | NULL        | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| pam                        | ACTIVE   | AUTHENTICATION     | auth_pam.so | GPL     |
+----------------------------+----------+--------------------+-------------+---------+

```

See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [Plugin Overview](../plugin-overview/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [INFORMATION\_SCHEMA.ALL\_PLUGINS Table](../information-schema-all_plugins-table/index) (all plugins, installed or not)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-plugins/>

TIME
====

    Syntax
------

 
```
TIME [(<microsecond precision>)]

```
 Description
-----------

 A time. The range is `'-838:59:59.999999'` to `'838:59:59.999999'`. [Microsecond precision](../microseconds-in-mariadb/index) can be from 0-6; if not specified 0 is used. Microseconds have been available since [MariaDB 5.3](../what-is-mariadb-53/index). 

 MariaDB displays `TIME` values in `'HH:MM:SS.ssssss'` format, but allows assignment of times in looser formats, including 'D HH:MM:SS', 'HH:MM:SS', 'HH:MM', 'D HH:MM', 'D HH', 'SS', or 'HHMMSS', as well as permitting dropping of any leading zeros when a delimiter is provided, for example '3:9:10'. For details, see [date and time literals](../date-and-time-literals/index).

 [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) introduced the [--mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format) option, on by default, which allows MariaDB to store TIMEs using the same low-level format MySQL 5.6 uses.

 ### Internal Format

 In [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) a new temporal format was introduced from MySQL 5.6 that alters how the `TIME`, `DATETIME` and `TIMESTAMP` columns operate at lower levels. These changes allow these temporal data types to have fractional parts and negative values. You can disable this feature using the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) system variable.

 Tables that include `TIMESTAMP` values that were created on an older version of MariaDB or that were created while the [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) system variable was disabled continue to store data using the older data type format.

 In order to update table columns from the older format to the newer format, execute an [ALTER TABLE... MODIFY COLUMN](../alter-table/index#modify-column) statement that changes the column to the \*same\* data type. This change may be needed if you want to export the table's tablespace and import it onto a server that has `mysql56_temporal_format=ON` set (see [MDEV-15225](https://jira.mariadb.org/browse/MDEV-15225)).

 For instance, if you have a `TIME` column in your table: 

 
```
SHOW VARIABLES LIKE 'mysql56_temporal_format';

+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| mysql56_temporal_format | ON    |
+-------------------------+-------+

ALTER TABLE example_table MODIFY ts_col TIME;

```

When MariaDB executes the `[ALTER TABLE](../alter-table/index)` statement, it converts the data from the older temporal format to the newer one. 

 In the event that you have several tables and columns using temporal data types that you want to switch over to the new format, make sure the system variable is enabled, then perform a dump and restore using `mariadb-dump`. The columns using relevant temporal data types are restored using the new temporal format.

 Starting from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) columns with old temporal formats are marked with a `/* mariadb-5.3 */` comment in the output of [SHOW CREATE TABLE](../show-create-table/index), [SHOW COLUMNS](../show-columns/index), [DESCRIBE](../describe/index) statements, as well as in the `COLUMN_TYPE` column of the [INFORMATION\_SCHEMA.COLUMNS Table](../information-schema-columns-table/index).

 
```
SHOW CREATE TABLE mariadb5312_time\G
*************************** 1. row ***************************
       Table: mariadb5312_time
Create Table: CREATE TABLE `mariadb5312_time` (
  `t0` time /* mariadb-5.3 */ DEFAULT NULL,
  `t6` time(6) /* mariadb-5.3 */ DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1

```

Note, columns with the current format are not marked with a comment.

 Examples
--------

 
```
INSERT INTO time VALUES ('90:00:00'), ('800:00:00'), (800), (22), (151413), ('9:6:3'), ('12 09');

SELECT * FROM time;
+-----------+
| t         |
+-----------+
| 90:00:00  |
| 800:00:00 |
| 00:08:00  |
| 00:00:22  |
| 15:14:13  |
| 09:06:03  |
| 297:00:00 |
+-----------+

```

See Also
--------

 * [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time/>

CREATE TABLE
============

    Syntax
------

 
```
CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    (create_definition,...) [table_options    ]... [partition_options]
CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
    [(create_definition,...)] [table_options   ]... [partition_options]
    select_statement
CREATE [OR REPLACE] [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
   { LIKE old_table_name | (LIKE old_table_name) }
select_statement:
    [IGNORE | REPLACE] [AS] SELECT ...   (Some legal select statement)
```
 Description
-----------

 Use the `CREATE TABLE` statement to create a table with the given name.

 In its most basic form, the `CREATE TABLE` statement provides a table name followed by a list of columns, indexes, and constraints. By default, the table is created in the default database. Specify a database with `*db\_name*.*tbl\_name*`. If you quote the table name, you must quote the database name and table name separately as ``*db\_name*`.`*tbl\_name*``. This is particularly useful for [CREATE TABLE ... SELECT](#create-table-select), because it allows to create a table into a database, which contains data from other databases. See [Identifier Qualifiers](../identifier-qualifiers/index).

 If a table with the same name exists, error 1050 results. Use [IF NOT EXISTS](#create-table-if-not-exists) to suppress this error and issue a note instead. Use [SHOW WARNINGS](../show-warnings/index) to see notes.

 The `CREATE TABLE` statement automatically commits the current transaction, except when using the [TEMPORARY](#create-temporary-table) keyword.

 For valid identifiers to use as table names, see [Identifier Names](../identifier-names/index).

 
**Note:** if the default\_storage\_engine is set to ColumnStore then it needs setting on all UMs. Otherwise when the tables using the default engine are replicated across UMs they will use the wrong engine. You should therefore not use this option as a session variable with ColumnStore.

 
[Microsecond precision](../microseconds-in-mariadb/index) can be between 0-6. If no precision is specified it is assumed to be 0, for backward compatibility reasons.

 Privileges
----------

 Executing the `CREATE TABLE` statement requires the [CREATE](../grant/index#table-privileges) privilege for the table or the database.

 CREATE OR REPLACE
-----------------

 If the `OR REPLACE` clause is used and the table already exists, then instead of returning an error, the server will drop the existing table and replace it with the newly defined table.

 This syntax was originally added to make [replication](../replication/index) more robust if it has to rollback and repeat statements such as `CREATE ... SELECT` on replicas.

 
```
CREATE OR REPLACE TABLE table_name (a int);

```

is basically the same as:

 
```
DROP TABLE IF EXISTS table_name;
CREATE TABLE table_name (a int);

```

with the following exceptions:

 * If `table_name` was locked with [LOCK TABLES](../lock-tables-and-unlock-tables/index) it will continue to be locked after the statement.
* Temporary tables are only dropped if the `TEMPORARY` keyword was used. (With [DROP TABLE](../drop-table/index), temporary tables are preferred to be dropped before normal tables).

 ### Things to be Aware of With CREATE OR REPLACE

 * The table is dropped first (if it existed), after that the `CREATE` is done. Because of this, if the `CREATE` fails, then the table will not exist anymore after the statement. If the table was used with `LOCK TABLES` it will be unlocked.
* One can't use `OR REPLACE` together with `IF EXISTS`.
* Slaves in replication will by default use `CREATE OR REPLACE` when replicating `CREATE` statements that don''t use `IF EXISTS`. This can be changed by setting the variable [slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode) to `STRICT`.

 CREATE TABLE IF NOT EXISTS
--------------------------

 If the `IF NOT EXISTS` clause is used, then the table will only be created if a table with the same name does not already exist. If the table already exists, then a warning will be triggered by default.

 CREATE TEMPORARY TABLE
----------------------

 Use the `TEMPORARY` keyword to create a temporary table that is only available to the current session. Temporary tables are dropped when the session ends. Temporary table names are specific to the session. They will not conflict with other temporary tables from other sessions even if they share the same name. They will shadow names of non-temporary tables or views, if they are identical. A temporary table can have the same name as a non-temporary table which is located in the same database. In that case, their name will reference the temporary table when used in SQL statements. You must have the [CREATE TEMPORARY TABLES](../grant/index#database-privileges) privilege on the database to create temporary tables. If no storage engine is specified, the [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine) setting will determine the engine.

 [ROCKSDB](../myrocks/index) temporary tables cannot be created by setting the [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine) system variable, or using `CREATE TEMPORARY TABLE LIKE`. Before [MariaDB 10.7](../what-is-mariadb-107/index), they could be specified, but would silently fail, and a MyISAM table would be created instead. From [MariaDB 10.7](../what-is-mariadb-107/index) an error is returned. Explicitly creating a temporary table with `ENGINE=ROCKSDB` has never been permitted.

 CREATE TABLE ... LIKE
---------------------

 Use the `LIKE` clause instead of a full table definition to create a table with the same definition as another table, including columns, indexes, and table options. Foreign key definitions, as well as any DATA DIRECTORY or INDEX DIRECTORY table options specified on the original table, will not be created.

 CREATE TABLE ... SELECT
-----------------------

 You can create a table containing data from other tables using the `CREATE ... SELECT` statement. Columns will be created in the table for each field returned by the `SELECT` query.

 You can also define some columns normally and add other columns from a `SELECT`. You can also create columns in the normal way and assign them some values using the query, this is done to force a certain type or other field characteristics. The columns that are not named in the query will be placed before the others. For example:

 
```
CREATE TABLE test (a INT NOT NULL, b CHAR(10)) ENGINE=MyISAM
    SELECT 5 AS b, c, d FROM another_table;

```

Remember that the query just returns data. If you want to use the same indexes, or the same columns attributes (`[NOT] NULL`, `DEFAULT`, `AUTO_INCREMENT`) in the new table, you need to specify them manually. Types and sizes are not automatically preserved if no data returned by the `SELECT` requires the full size, and `VARCHAR` could be converted into `CHAR`. The [CAST()](../cast/index) function can be used to forcee the new table to use certain types.

 Aliases (`AS`) are taken into account, and they should always be used when you `SELECT` an expression (function, arithmetical operation, etc).

 If an error occurs during the query, the table will not be created at all.

 If the new table has a primary key or `UNIQUE` indexes, you can use the [IGNORE](../ignore/index) or `REPLACE` keywords to handle duplicate key errors during the query. `IGNORE` means that the newer values must not be inserted an identical value exists in the index. `REPLACE` means that older values must be overwritten.

 If the columns in the new table are more than the rows returned by the query, the columns populated by the query will be placed after other columns. Note that if the strict `SQL_MODE` is on, and the columns that are not names in the query do not have a `DEFAULT` value, an error will raise and no rows will be copied.

 [Concurrent inserts](../concurrent-inserts/index) are not used during the execution of a `CREATE ... SELECT`.

 If the table already exists, an error similar to the following will be returned:

 
```
ERROR 1050 (42S01): Table 't' already exists

```

If the `IF NOT EXISTS` clause is used and the table exists, a note will be produced instead of an error.

 To insert rows from a query into an existing table, [INSERT ... SELECT](../insert-select/index) can be used.

 Column Definitions
------------------

 
```
create_definition:
  { col_name column_definition | index_definition | period_definition | CHECK (expr) }
column_definition:
  data_type
    [NOT NULL | NULL] [DEFAULT default_value | (expression)]
    [ON UPDATE [NOW | CURRENT_TIMESTAMP] [(precision)]]
    [AUTO_INCREMENT] [ZEROFILL] [UNIQUE [KEY] | [PRIMARY] KEY]
    [INVISIBLE] [{WITH|WITHOUT} SYSTEM VERSIONING]
    [COMMENT 'string'] [REF_SYSTEM_ID = value]
    [reference_definition]
  | data_type [GENERATED ALWAYS] 
  AS { { ROW {START|END} } | { (expression) [VIRTUAL | PERSISTENT | STORED] } }
      [UNIQUE [KEY]] [COMMENT 'string']
constraint_definition:
   CONSTRAINT [constraint_name] CHECK (expression)
```


**Note:** Until [MariaDB 10.4](../what-is-mariadb-104/index), MariaDB accepts the shortcut format with a REFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that syntax does nothing. For example:

 
```
CREATE TABLE b(for_key INT REFERENCES a(not_key));

```

MariaDB simply parses it without returning any error or warning, for compatibility with other DBMS's. Before [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) this was also true for `CHECK` constraints. However, only the syntax described below creates foreign keys.

 From [MariaDB 10.5](../what-is-mariadb-105/index), MariaDB will attempt to apply the constraint. See [Foreign Keys examples](../foreign-keys/index#references).

 
Each definition either creates a column in the table or specifies and index or constraint on one or more columns. See [Indexes](#indexes) below for details on creating indexes.

 Create a column by specifying a column name and a data type, optionally followed by column options. See [Data Types](../data-types/index) for a full list of data types allowed in MariaDB.

 ### NULL and NOT NULL

 Use the `NULL` or `NOT NULL` options to specify that values in the column may or may not be `NULL`, respectively. By default, values may be `NULL`. See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 ### DEFAULT Column Option

 Specify a default value using the `DEFAULT` clause. If you don't specify `DEFAULT` then the following rules apply:

 * If the column is not defined with `NOT NULL`, `AUTO_INCREMENT` or `TIMESTAMP`, an explicit `DEFAULT NULL` will be added. Note that in MySQL and in MariaDB before 10.1.6, you may get an explicit `DEFAULT` for primary key parts, if not specified with NOT NULL.

 The default value will be used if you [INSERT](../insert/index) a row without specifying a value for that column, or if you specify [DEFAULT](../default/index) for that column. Before [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) you couldn't usually provide an expression or function to evaluate at insertion time. You had to provide a constant default value instead. The one exception is that you may use [CURRENT\_TIMESTAMP](../now/index) as the default value for a [TIMESTAMP](../timestamp/index) column to use the current timestamp at insertion time.

 [CURRENT\_TIMESTAMP](../now/index) may also be used as the default value for a [DATETIME](../datetime/index)

 You can use most functions in `DEFAULT`. Expressions should have parentheses around them. If you use a non deterministic function in `DEFAULT` then all inserts to the table will be [replicated](../replication/index) in [row mode](../binary-log-formats/index#row-based). You can even refer to earlier columns in the `DEFAULT` expression (excluding `AUTO_INCREMENT` columns):

 
```
CREATE TABLE t1 (a int DEFAULT (1+1), b int DEFAULT (a+1));
CREATE TABLE t2 (a bigint primary key DEFAULT UUID_SHORT());

```

The `DEFAULT` clause cannot contain any [stored functions](../stored-functions/index) or [subqueries](../subqueries/index), and a column used in the clause must already have been defined earlier in the statement.

 It is possible to assign [BLOB](../blob/index) or [TEXT](../text/index) columns a `DEFAULT` value. In versions prior to [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/), assigning a default to these columns was not possible.

 You can also use DEFAULT ([NEXT VALUE FOR sequence](../next-value-for-sequence_name/index))

 ### AUTO\_INCREMENT Column Option

 Use [AUTO\_INCREMENT](../auto_increment/index) to create a column whose value can can be set automatically from a simple counter. You can only use `AUTO_INCREMENT` on a column with an integer type. The column must be a key, and there can only be one `AUTO_INCREMENT` column in a table. If you insert a row without specifying a value for that column (or if you specify `0`, `NULL`, or [DEFAULT](../default/index) as the value), the actual value will be taken from the counter, with each insertion incrementing the counter by one. You can still insert a value explicitly. If you insert a value that is greater than the current counter value, the counter is set based on the new value. An `AUTO_INCREMENT` column is implicitly `NOT NULL`. Use [LAST\_INSERT\_ID](../last_insert_id/index) to get the [AUTO\_INCREMENT](../auto_increment/index) value most recently used by an [INSERT](../insert/index) statement.

 ### ZEROFILL Column Option

 If the `ZEROFILL` column option is specified for a column using a [numeric](../numeric-data-type-overview/index) data type, then the column will be set to `UNSIGNED` and the spaces used by default to pad the field are replaced with zeros. `ZEROFILL` is ignored in expressions or as part of a [UNION](../union/index). `ZEROFILL` is a non-standard MySQL and MariaDB enhancement.

 ### PRIMARY KEY Column Option

 Use `PRIMARY KEY` to make a column a primary key. A primary key is a special type of a unique key. There can be at most one primary key per table, and it is implicitly `NOT NULL`.

 Specifying a column as a unique key creates a unique index on that column. See the [Index Definitions](#index-definitions) section below for more information.

 ### UNIQUE KEY Column Option

 Use `UNIQUE KEY` (or just `UNIQUE`) to specify that all values in the column must be distinct from each other. Unless the column is `NOT NULL`, there may be multiple rows with `NULL` in the column. 

 Specifying a column as a unique key creates a unique index on that column.

 See the [Index Definitions](#index-definitions) section below for more information.

 ### COMMENT Column Option

 You can provide a comment for each column using the `COMMENT` clause. The maximum length is 1024 characters. Use the [SHOW FULL COLUMNS](../show-columns/index) statement to see column comments.

 ### REF\_SYSTEM\_ID

 `REF_SYSTEM_ID` can be used to specify Spatial Reference System IDs for spatial data type columns. For example:

 
```
CREATE TABLE t1(g GEOMETRY(9,4) REF_SYSTEM_ID=101);

```

### Generated Columns

 A generated column is a column in a table that cannot explicitly be set to a specific value in a [DML query](../data-manipulation/index). Instead, its value is automatically generated based on an expression. This expression might generate the value based on the values of other columns in the table, or it might generate the value by calling [built-in functions](../built-in-functions/index) or [user-defined functions (UDFs)](../user-defined-functions/index).

 There are two types of generated columns:

 * `PERSISTENT` or `STORED`: This type's value is actually stored in the table.
* `VIRTUAL`: This type's value is not stored at all. Instead, the value is generated dynamically when the table is queried. This type is the default.

 Generated columns are also sometimes called computed columns or virtual columns.

 For a complete description about generated columns and their limitations, see [Generated (Virtual and Persistent/Stored) Columns](../generated-columns/index).

 ### COMPRESSED

 Certain columns may be compressed. See [Storage-Engine Independent Column Compression](../storage-engine-independent-column-compression/index).

 ### INVISIBLE

 Columns may be made invisible, and hidden in certain contexts. See [Invisible Columns](../invisible-columns/index).

 ### WITH SYSTEM VERSIONING Column Option

 Columns may be explicitly marked as included from system versioning. See [System-versioned tables](../system-versioned-tables/index) for details.

 ### WITHOUT SYSTEM VERSIONING Column Option

 Columns may be explicitly marked as excluded from system versioning. See [System-versioned tables](../system-versioned-tables/index) for details.

 Index Definitions
-----------------

 
```
index_definition:
    {INDEX|KEY} [index_name] [index_type] (index_col_name,...) [index_option] ...
  {{{|}}} {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (index_col_name,...) [index_option] ...
  {{{|}}} [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (index_col_name,...) [index_option] ...
  {{{|}}} [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (index_col_name,...) [index_option] ...
  {{{|}}} [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (index_col_name,...) reference_definition

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH | RTREE}

index_option:
    [ KEY_BLOCK_SIZE [=] value
  {{{|}}} index_type
  {{{|}}} WITH PARSER parser_name
  {{{|}}} COMMENT 'string'
  {{{|}}} CLUSTERING={YES| NO} ]
  [ IGNORED | NOT IGNORED ]

reference_definition:
    REFERENCES tbl_name (index_col_name,...)
      [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
      [ON DELETE reference_option]
      [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

```

`INDEX` and `KEY` are synonyms. 

 Index names are optional, if not specified an automatic name will be assigned. Index name are needed to drop indexes and appear in error messages when a constraint is violated.

 ### Index Categories

 #### Plain Indexes

 Plain indexes are regular indexes that are not unique, and are not acting as a primary key or a foreign key. They are also not the "specialized" `FULLTEXT` or `SPATIAL` indexes.

 See [Getting Started with Indexes: Plain Indexes](../getting-started-with-indexes/index#plain-indexes) for more information.

 #### PRIMARY KEY

 For `PRIMARY KEY` indexes, you can specify a name for the index, but it is ignored, and the name of the index is always `PRIMARY`. From [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/) and [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/), a warning is explicitly issued if a name is specified. Before then, the name was silently ignored. 

 See [Getting Started with Indexes: Primary Key](../getting-started-with-indexes/index#primary-key) for more information.

 #### UNIQUE

 The `UNIQUE` keyword means that the index will not accept duplicated values, except for NULLs. An error will raise if you try to insert duplicate values in a UNIQUE index.

 For `UNIQUE` indexes, you can specify a name for the constraint, using the `CONSTRAINT` keyword. That name will be used in error messages.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**Unique, if index type is not specified, is normally a BTREE index that can also be used by the optimizer to find rows. If the key is longer than the max key length for the used storage engine, a HASH key will be created. This enables MariaDB to enforce uniqueness for any type or number of columns.

 
See [Getting Started with Indexes: Unique Index](../getting-started-with-indexes/index#unique-index) for more information.

 #### FOREIGN KEY

 For `FOREIGN KEY` indexes, a reference definition must be provided.

 For `FOREIGN KEY` indexes, you can specify a name for the constraint, using the `CONSTRAINT` keyword. That name will be used in error messages.

 First, you have to specify the name of the target (parent) table and a column or a column list which must be indexed and whose values must match to the foreign key's values. The `MATCH` clause is accepted to improve the compatibility with other DBMS's, but has no meaning in MariaDB. The `ON DELETE` and `ON UPDATE` clauses specify what must be done when a `DELETE` (or a `REPLACE`) statements attempts to delete a referenced row from the parent table, and when an `UPDATE` statement attempts to modify the referenced foreign key columns in a parent table row, respectively. The following options are allowed:

 * `RESTRICT`: The delete/update operation is not performed. The statement terminates with a 1451 error (SQLSTATE '2300').
* `NO ACTION`: Synonym for `RESTRICT`.
* `CASCADE`: The delete/update operation is performed in both tables.
* `SET NULL`: The update or delete goes ahead in the parent table, and the corresponding foreign key fields in the child table are set to `NULL`. (They must not be defined as `NOT NULL` for this to succeed).
* `SET DEFAULT`: This option is currently implemented only for the PBXT storage engine, which is disabled by default and no longer maintained. It sets the child table's foreign key fields to their `DEFAULT` values when the referenced parent table key entries are updated or deleted.

 If either clause is omitted, the default behavior for the omitted clause is `RESTRICT`.

 See [Foreign Keys](../foreign-keys/index) for more information.

 #### FULLTEXT

 Use the `FULLTEXT` keyword to create full-text indexes.

 See [Full-Text Indexes](../full-text-indexes/index) for more information.

 #### SPATIAL

 Use the `SPATIAL` keyword to create geometric indexes.

 See [SPATIAL INDEX](../spatial-index/index) for more information.

 ### Index Options

 #### KEY\_BLOCK\_SIZE Index Option

 The `KEY_BLOCK_SIZE` index option is similar to the [KEY\_BLOCK\_SIZE](#key_block_size) table option.

 With the [InnoDB](../innodb/index) storage engine, if you specify a non-zero value for the `KEY_BLOCK_SIZE` table option for the whole table, then the table will implicitly be created with the [ROW\_FORMAT](#row_format) table option set to `COMPRESSED`. However, this does not happen if you just set the `KEY_BLOCK_SIZE` index option for one or more indexes in the table. The [InnoDB](../innodb/index) storage engine ignores the `KEY_BLOCK_SIZE` index option. However, the [SHOW CREATE TABLE](../show-create-table/index) statement may still report it for the index.

 For information about the `KEY_BLOCK_SIZE` index option, see the [KEY\_BLOCK\_SIZE](#key_block_size) table option below.

 #### Index Types

 Each storage engine supports some or all index types. See [Storage Engine Index Types](../storage-engine-index-types/index) for details on permitted index types for each storage engine.

 Different index types are optimized for different kind of operations:

 * `BTREE` is the default type, and normally is the best choice. It is supported by all storage engines. It can be used to compare a column's value with a value using the =, >, >=, <, <=, `BETWEEN`, and `LIKE` operators. `BTREE` can also be used to find `NULL` values. Searches against an index prefix are possible.
* `HASH` is only supported by the MEMORY storage engine. `HASH` indexes can only be used for =, <=, and >= comparisons. It can not be used for the `ORDER BY` clause. Searches against an index prefix are not possible.
* `RTREE` is the default for [SPATIAL](../spatial/index) indexes, but if the storage engine does not support it `BTREE` can be used.

 Index columns names are listed between parenthesis. After each column, a prefix length can be specified. If no length is specified, the whole column will be indexed. `ASC` and `DESC` can be specified for compatibility with are DBMS's, but have no meaning in MariaDB.

 #### WITH PARSER Index Option

 The `WITH PARSER` index option only applies to [FULLTEXT](../full-text-indexes/index) indexes and contains the fulltext parser name. The fulltext parser must be an installed plugin.

 #### COMMENT Index Option

 A comment of up to 1024 characters is permitted with the `COMMENT` index option.

 The `COMMENT` index option allows you to specify a comment with user-readable text describing what the index is for. This information is not used by the server itself.

 #### CLUSTERING Index Option

 The `CLUSTERING` index option is only valid for tables using the [TokuDB](../tokudb/index) storage engine.

 #### IGNORED / NOT IGNORED

 
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), indexes can be specified to be ignored by the optimizer. See [Ignored Indexes](../ignored-indexes/index).

 
Periods
-------

 
```
period_definition:
    PERIOD FOR SYSTEM_TIME (start_column_name, end_column_name)
```

MariaDB supports a subset of the standard syntax for periods. At the moment it's only used for creating [System-versioned tables](../system-versioned-tables/index). Both columns must be created, must be either of a `TIMESTAMP(6)` or `BIGINT UNSIGNED` type, and be generated as `ROW START` and `ROW END` accordingly. See [System-versioned tables](../system-versioned-tables/index) for details.

 The table must also have the `WITH SYSTEM VERSIONING` clause.

 Constraint Expressions
----------------------

 Note: Before [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/), constraint expressions were accepted in the syntax but ignored.

 [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) introduced two ways to define a constraint:

 * `CHECK(expression)` given as part of a column definition.
* `CONSTRAINT [constraint_name] CHECK (expression)`

 Before a row is inserted or updated, all constraints are evaluated in the order they are defined. If any constraints fails, then the row will not be updated. One can use most deterministic functions in a constraint, including [UDFs](../user-defined-functions/index).

 
```
create table t1 (a int check(a>0) ,b int check (b> 0), constraint abc check (a>b));

```

If you use the second format and you don't give a name to the constraint, then the constraint will get a auto generated name. This is done so that you can later delete the constraint with [ALTER TABLE DROP constraint\_name](../alter-table/index).

 One can disable all constraint expression checks by setting the variable `check_constraint_checks` to `OFF`. This is useful for example when loading a table that violates some constraints that you want to later find and fix in SQL.

 See [CONSTRAINT](../constraint/index) for more information.

 Table Options
-------------

 For each individual table you create (or alter), you can set some table options. The general syntax for setting options is:

  <OPTION\_NAME> = <option\_value>, [<OPTION\_NAME> = <option\_value> ...]

 The equal sign is optional.

 Some options are supported by the server and can be used for all tables, no matter what storage engine they use; other options can be specified for all storage engines, but have a meaning only for some engines. Also, engines can [extend `CREATE TABLE` with new options](../extending-create-table/index).

 If the `IGNORE_BAD_TABLE_OPTIONS` [SQL\_MODE](../sql-mode/index) is enabled, wrong table options generate a warning; otherwise, they generate an error.

 
```
table_option:    
    [STORAGE] ENGINE [=] engine_name
  | AUTO_INCREMENT [=] value
  | AVG_ROW_LENGTH [=] value
  | [DEFAULT] CHARACTER SET [=] charset_name
  | CHECKSUM [=] {0 | 1}
  | [DEFAULT] COLLATE [=] collation_name
  | COMMENT [=] 'string'
  | CONNECTION [=] 'connect_string'
  | DATA DIRECTORY [=] 'absolute path to directory'
  | DELAY_KEY_WRITE [=] {0 | 1}
  | ENCRYPTED [=] {YES | NO}
  | ENCRYPTION_KEY_ID [=] value
  | IETF_QUOTES [=] {YES | NO}
  | INDEX DIRECTORY [=] 'absolute path to directory'
  | INSERT_METHOD [=] { NO | FIRST | LAST }
  | KEY_BLOCK_SIZE [=] value
  | MAX_ROWS [=] value
  | MIN_ROWS [=] value
  | PACK_KEYS [=] {0 | 1 | DEFAULT}
  | PAGE_CHECKSUM [=] {0 | 1}
  | PAGE_COMPRESSED [=] {0 | 1}
  | PAGE_COMPRESSION_LEVEL [=] {0 .. 9}
  | PASSWORD [=] 'string'
  | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT|PAGE}
  | SEQUENCE [=] {0|1}
  | STATS_AUTO_RECALC [=] {DEFAULT|0|1}
  | STATS_PERSISTENT [=] {DEFAULT|0|1}
  | STATS_SAMPLE_PAGES [=] {DEFAULT|value}
  | TABLESPACE tablespace_name
  | TRANSACTIONAL [=]  {0 | 1}
  | UNION [=] (tbl_name[,tbl_name]...)
  | WITH SYSTEM VERSIONING
```

### [STORAGE] ENGINE

 `[STORAGE] ENGINE` specifies a [storage engine](../mariadb-storage-engines/index) for the table. If this option is not used, the default storage engine is used instead. That is, the [default\_storage\_engine](../server-system-variables/index#default_storage_engine) session option value if it is set, or the value specified for the `--default-storage-engine` [mysqld startup option](../mysqld-options-full-list/index), or the default storage engine, [InnoDB](../innodb/index). If the specified storage engine is not installed and active, the default value will be used, unless the `NO_ENGINE_SUBSTITUTION` [SQL MODE](../sql-mode/index) is set (default). This is only true for `CREATE TABLE`, not for `ALTER TABLE`. For a list of storage engines that are present in your server, issue a [SHOW ENGINES](../show-engines/index).

 ### AUTO\_INCREMENT

 `AUTO_INCREMENT` specifies the initial value for the [AUTO\_INCREMENT](../auto_increment/index) primary key. This works for MyISAM, Aria, InnoDB, MEMORY, and ARCHIVE tables. You can change this option with `ALTER TABLE`, but in that case the new value must be higher than the highest value which is present in the `AUTO_INCREMENT` column. If the storage engine does not support this option, you can insert (and then delete) a row having the wanted value - 1 in the `AUTO_INCREMENT` column.

 ### AVG\_ROW\_LENGTH

 `AVG_ROW_LENGTH` is the average rows size. It only applies to tables using [MyISAM](../myisam/index) and [Aria](../aria-storage-engine/index) storage engines that have the [ROW\_FORMAT](#row_format) table option set to `FIXED` format.

 MyISAM uses `MAX_ROWS` and `AVG_ROW_LENGTH` to decide the maximum size of a table (default: 256TB, or the maximum file size allowed by the system).

 ### [DEFAULT] CHARACTER SET/CHARSET

 `[DEFAULT] CHARACTER SET` (or `[DEFAULT] CHARSET`) is used to set a default character set for the table. This is the character set used for all columns where an explicit character set is not specified. If this option is omitted or `DEFAULT` is specified, database's default character set will be used. See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on setting the [character sets](../data-types-character-sets-and-collations/index).

 ### CHECKSUM/TABLE\_CHECKSUM

 `CHECKSUM` (or `TABLE_CHECKSUM`) can be set to 1 to maintain a live checksum for all table's rows. This makes write operations slower, but [CHECKSUM TABLE](../checksum-table/index) will be very fast. This option is only supported for [MyISAM](../myisam/index) and [Aria tables](../aria-storage-engine/index).

 ### [DEFAULT] COLLATE

 `[DEFAULT] COLLATE` is used to set a default collation for the table. This is the collation used for all columns where an explicit character set is not specified. If this option is omitted or `DEFAULT` is specified, database's default option will be used. See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on setting the [collations](../data-types-character-sets-and-collations/index)

 ### COMMENT

 `COMMENT` is a comment for the table. The maximum length is 2048 characters. Also used to define table parameters when creating a [Spider](../spider/index) table.

 ### CONNECTION

 `CONNECTION` is used to specify a server name or a connection string for a [Spider](../spider/index), [CONNECT](../connect/index), [Federated or FederatedX table](../about-federatedx/index).

 ### DATA DIRECTORY/INDEX DIRECTORY

 `DATA DIRECTORY` and `INDEX DIRECTORY` are supported for MyISAM and Aria, and DATA DIRECTORY is also supported by InnoDB if the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) server system variable is enabled, but only in CREATE TABLE, not in [ALTER TABLE](../alter-table/index). So, carefully choose a path for InnoDB tables at creation time, because it cannot be changed without dropping and re-creating the table. These options specify the paths for data files and index files, respectively. If these options are omitted, the database's directory will be used to store data files and index files. Note that these table options do not work for [partitioned](../managing-mariadb-partitioning/index) tables (use the partition options instead), or if the server has been invoked with the [--skip-symbolic-links startup option](../mysqld-options-full-list/index). To avoid the overwriting of old files with the same name that could be present in the directories, you can use [the `--keep_files_on_create` option](../mysqld-options-full-list/index) (an error will be issued if files already exist). These options are ignored if the `NO_DIR_IN_CREATE` [SQL\_MODE](../sql-mode/index) is enabled (useful for replication slaves). Also note that symbolic links cannot be used for InnoDB tables.

 `DATA DIRECTORY` works by creating symlinks from where the table would normally have been (inside the [datadir](../server-system-variables/index#datadir)) to where the option specifies. For security reasons, to avoid bypassing the privilege system, the server does not permit symlinks inside the datadir. Therefore, `DATA DIRECTORY` cannot be used to specify a location inside the datadir. An attempt to do so will result in an error `1210 (HY000) Incorrect arguments to DATA DIRECTORY`.

 ### DELAY\_KEY\_WRITE

 `DELAY_KEY_WRITE` is supported by MyISAM and Aria, and can be set to 1 to speed up write operations. In that case, when data are modified, the indexes are not updated until the table is closed. Writing the changes to the index file altogether can be much faster. However, note that this option is applied only if the `delay_key_write` server variable is set to 'ON'. If it is 'OFF' the delayed index writes are always disabled, and if it is 'ALL' the delayed index writes are always used, disregarding the value of `DELAY_KEY_WRITE`.

 ### ENCRYPTED

 The `ENCRYPTED` table option can be used to manually set the encryption status of an [InnoDB](../innodb/index) table. See [InnoDB Encryption](../innodb-encryption/index) for more information.

 Aria does not support the `ENCRYPTED` table option. See [MDEV-18049](https://jira.mariadb.org/browse/MDEV-18049).

 See [Data-at-Rest Encryption](../securing-mariadb-data-at-rest-encryption/index) for more information.

 ### ENCRYPTION\_KEY\_ID

 The `ENCRYPTION_KEY_ID` table option can be used to manually set the encryption key of an [InnoDB](../innodb/index) table. See [InnoDB Encryption](../innodb-encryption/index) for more information.

 Aria does not support the `ENCRYPTION_KEY_ID` table option. See [MDEV-18049](https://jira.mariadb.org/browse/MDEV-18049).

 See [Data-at-Rest Encryption](../securing-mariadb-data-at-rest-encryption/index) for more information.

 ### IETF\_QUOTES

 For the [CSV](../csv/index) storage engine, the `IETF_QUOTES` option, when set to `YES`, enables IETF-compatible parsing of embedded quote and comma characters. Enabling this option for a table improves compatibility with other tools that use CSV, but is not compatible with MySQL CSV tables, or MariaDB CSV tables created without this option. Disabled by default.

 ### INSERT\_METHOD

 `INSERT_METHOD` is only used with [MERGE](../merge/index) tables. This option determines in which underlying table the new rows should be inserted. If you set it to 'NO' (which is the default) no new rows can be added to the table (but you will still be able to perform `INSERT`s directly against the underlying tables). `FIRST` means that the rows are inserted into the first table, and `LAST` means that thet are inserted into the last table.

 ### KEY\_BLOCK\_SIZE

 `KEY_BLOCK_SIZE` is used to determine the size of key blocks, in bytes or kilobytes. However, this value is just a hint, and the storage engine could modify or ignore it. If `KEY_BLOCK_SIZE` is set to 0, the storage engine's default value will be used.

 With the [InnoDB](../innodb/index) storage engine, if you specify a non-zero value for the `KEY_BLOCK_SIZE` table option for the whole table, then the table will implicitly be created with the [ROW\_FORMAT](#row_format) table option set to `COMPRESSED`.

 ### MIN\_ROWS/MAX\_ROWS

 `MIN_ROWS` and `MAX_ROWS` let the storage engine know how many rows you are planning to store as a minimum and as a maximum. These values will not be used as real limits, but they help the storage engine to optimize the table. `MIN_ROWS` is only used by MEMORY storage engine to decide the minimum memory that is always allocated. `MAX_ROWS` is used to decide the minimum size for indexes.

 ### PACK\_KEYS

 `PACK_KEYS` can be used to determine whether the indexes will be compressed. Set it to 1 to compress all keys. With a value of 0, compression will not be used. With the `DEFAULT` value, only long strings will be compressed. Uncompressed keys are faster.

 ### PAGE\_CHECKSUM

 `PAGE_CHECKSUM` is only applicable to [Aria](../aria/index) tables, and determines whether indexes and data should use page checksums for extra safety. 

 ### PAGE\_COMPRESSED

 `PAGE_COMPRESSED` is used to enable [InnoDB page compression](../compression/index) for [InnoDB](../innodb/index) tables.

 ### PAGE\_COMPRESSION\_LEVEL

 `PAGE_COMPRESSION_LEVEL` is used to set the compression level for [InnoDB page compression](../compression/index) for [InnoDB](../innodb/index) tables. The table must also have the [PAGE\_COMPRESSED](#page_compressed) table option set to `1`.

 Valid values for `PAGE_COMPRESSION_LEVEL` are 1 (the best speed) through 9 (the best compression), .

 ### PASSWORD

 `PASSWORD` is unused.

 ### RAID\_TYPE

 `RAID_TYPE` is an obsolete option, as the raid support has been disabled since MySQL 5.0.

 ### ROW\_FORMAT

 The `ROW_FORMAT` table option specifies the row format for the data file. Possible values are engine-dependent.

 #### Supported MyISAM Row Formats

 For [MyISAM](../myisam/index), the supported row formats are: 

 * `FIXED`
* `DYNAMIC`
* `COMPRESSED`

 The `COMPRESSED` row format can only be set by the [myisampack](../myisampack/index) command line tool.

 See [MyISAM Storage Formats](../myisam-storage-formats/index) for more information.

 #### Supported Aria Row Formats

 For [Aria](../aria-storage-engine/index), the supported row formats are:

 * `PAGE`
* `FIXED`
* `DYNAMIC`.

 See [Aria Storage Formats](../aria-storage-formats/index) for more information.

 #### Supported InnoDB Row Formats

 For [InnoDB](../innodb/index), the supported row formats are:

 * `COMPACT`
* `REDUNDANT`
* `COMPRESSED`
* `DYNAMIC`.

 If the `ROW_FORMAT` table option is set to `FIXED` for an InnoDB table, then the server will either return an error or a warning depending on the value of the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable. If the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable is set to `OFF`, then a warning is issued, and MariaDB will create the table using the default row format for the specific MariaDB server version. If the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable is set to `ON`, then an error will be raised.

 See [InnoDB Storage Formats](../innodb-storage-formats/index) for more information.

 #### Other Storage Engines and ROW\_FORMAT

 Other storage engines do not support the `ROW_FORMAT` table option.

 ### SEQUENCE

 If the table is a [sequence](../sequences/index), then it will have the `SEQUENCE` set to `1`.

 ### STATS\_AUTO\_RECALC

 `STATS_AUTO_RECALC` indicates whether to automatically recalculate persistent statistics (see `STATS_PERSISTENT`, below) for an InnoDB table. If set to `1`, statistics will be recalculated when more than 10% of the data has changed. When set to `0`, stats will be recalculated only when an [ANALYZE TABLE](../analyze-table/index) is run. If set to `DEFAULT`, or left out, the value set by the [innodb\_stats\_auto\_recalc](../innodb-system-variables/index#innodb_stats_auto_recalc) system variable applies. See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).

 ### STATS\_PERSISTENT

 `STATS_PERSISTENT` indicates whether the InnoDB statistics created by [ANALYZE TABLE](../analyze-table/index) will remain on disk or not. It can be set to `1` (on disk), `0` (not on disk, the pre-MariaDB 10 behavior), or `DEFAULT` (the same as leaving out the option), in which case the value set by the [innodb\_stats\_persistent](../innodb-system-variables/index#innodb_stats_persistent) system variable will apply. Persistent statistics stored on disk allow the statistics to survive server restarts, and provide better query plan stability. See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).

 ### STATS\_SAMPLE\_PAGES

 `STATS_SAMPLE_PAGES` indicates how many pages are used to sample index statistics. If 0 or DEFAULT, the default value, the [innodb\_stats\_sample\_pages](../innodb-system-variables/index#innodb_stats_sample_pages) value is used. See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).

 ### TRANSACTIONAL

 `TRANSACTIONAL` is only applicable for Aria tables. In future Aria tables created with this option will be fully transactional, but currently this provides a form of crash protection. See [Aria Storage Engine](../aria-storage-engine/index) for more details.

 ### UNION

 `UNION` must be specified when you create a MERGE table. This option contains a comma-separated list of MyISAM tables which are accessed by the new table. The list is enclosed between parenthesis. Example: `UNION = (t1,t2)`

 ### WITH SYSTEM VERSIONING

 `WITH SYSTEM VERSIONING` is used for creating [System-versioned tables](../system-versioned-tables/index).

 Partitions
----------

 
```
partition_options:
    PARTITION BY
        { [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list)
        | RANGE(expr)
        | LIST(expr)
        | SYSTEM_TIME [INTERVAL time_quantity time_unit] [LIMIT num] }
    [PARTITIONS num]
    [SUBPARTITION BY
        { [LINEAR] HASH(expr)
        | [LINEAR] KEY(column_list) }
      [SUBPARTITIONS num]
    ]
    [(partition_definition [, partition_definition] ...)]
partition_definition:
    PARTITION partition_name
        [VALUES {LESS THAN {(expr) | MAXVALUE} | IN (value_list)}]
        [[STORAGE] ENGINE [=] engine_name]
        [COMMENT [=] 'comment_text' ]
        [DATA DIRECTORY [=] 'data_dir']
        [INDEX DIRECTORY [=] 'index_dir']
        [MAX_ROWS [=] max_number_of_rows]
        [MIN_ROWS [=] min_number_of_rows]
        [TABLESPACE [=] tablespace_name]
        [NODEGROUP [=] node_group_id]
        [(subpartition_definition [, subpartition_definition] ...)]
subpartition_definition:
    SUBPARTITION logical_name
        [[STORAGE] ENGINE [=] engine_name]
        [COMMENT [=] 'comment_text' ]
        [DATA DIRECTORY [=] 'data_dir']
        [INDEX DIRECTORY [=] 'index_dir']
        [MAX_ROWS [=] max_number_of_rows]
        [MIN_ROWS [=] min_number_of_rows]
        [TABLESPACE [=] tablespace_name]
        [NODEGROUP [=] node_group_id]
```

If the `PARTITION BY` clause is used, the table will be [partitioned](../managing-mariadb-partitioning/index). A partition method must be explicitly indicated for partitions and subpartitions. Partition methods are:

 * `[LINEAR] HASH` creates a hash key which will be used to read and write rows. The partition function can be any valid SQL expression which returns an `INTEGER` number. Thus, it is possible to use the `HASH` method on an integer column, or on functions which accept integer columns as an argument. However, `VALUES LESS THAN` and `VALUES IN` clauses can not be used with `HASH`. An example:

 
```
CREATE TABLE t1 (a INT, b CHAR(5), c DATETIME)
    PARTITION BY HASH ( YEAR(c) );

```

 `[LINEAR] HASH` can be used for subpartitions, too.

 * `[LINEAR] KEY` is similar to `HASH`, but the index has an even distribution of data. Also, the expression can only be a column or a list of columns. `VALUES LESS THAN` and `VALUES IN` clauses can not be used with `KEY`.
* [RANGE](../range-partitioning-type/index) partitions the rows using on a range of values, using the `VALUES LESS THAN` operator. `VALUES IN` is not allowed with `RANGE`. The partition function can be any valid SQL expression which returns a single value.
* [LIST](../list-partitioning/index) assigns partitions based on a table's column with a restricted set of possible values. It is similar to `RANGE`, but `VALUES IN` must be used for at least 1 columns, and `VALUES LESS THAN` is disallowed.
* `SYSTEM_TIME` partitioning is used for [System-versioned tables](../system-versioned-tables/index) to store historical data separately from current data.

 Only `HASH` and `KEY` can be used for subpartitions, and they can be `[LINEAR]`.

 It is possible to define up to 1024 partitions and subpartitions.

 The number of defined partitions can be optionally specified as `PARTITION count`. This can be done to avoid specifying all partitions individually. But you can also declare each individual partition and, additionally, specify a `PARTITIONS count` clause; in the case, the number of `PARTITION`s must equal count.

 Also see [Partitioning Types Overview](../partitioning-types-overview/index).

 Sequences
---------

 `CREATE TABLE` can also be used to create a [SEQUENCE](../sequences/index). See [CREATE SEQUENCE](../create-sequence/index) and [Sequence Overview](../sequence-overview/index).

 Atomic DDL
----------

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index). `CREATE TABLE` is atomic, except for `CREATE OR REPLACE`, which is only crash safe. 

 
Examples
--------

 
```
create table if not exists test (
a bigint auto_increment primary key,
name varchar(128) charset utf8,
key name (name(32))
) engine=InnoDB default charset latin1;

```

This example shows a couple of things:

 * Usage of `IF NOT EXISTS`; If the table already existed, it will not be created. There will not be any error for the client, just a warning.
* How to create a `PRIMARY KEY` that is [automatically generated](../auto_increment/index).
* How to specify a table-specific [character set](../data-types-character-sets-and-collations/index) and another for a column.
* How to create an index (`name`) that is only partly indexed (to save space).

 The following clauses will work from [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) only.

 
```
CREATE TABLE t1(
  a int DEFAULT (1+1),
  b int DEFAULT (a+1),
  expires DATETIME DEFAULT(NOW() + INTERVAL 1 YEAR),
  x BLOB DEFAULT USER()
);

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [ALTER TABLE](../alter-table/index)
* [DROP TABLE](../drop-table/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [SHOW CREATE TABLE](../show-create-table/index)
* Storage engines can add their own [attributes for columns, indexes and tables](../engine-defined-new-tablefieldindex-attributes/index).
* Variable [slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-table/>

Information Schema PARTITIONS Table
===================================

    The [Information Schema](../information_schema/index) `PARTITIONS` contains information about table partitions, with each record corresponding to a single partition or subpartition of a partitioned table. Each non-partitioned table also has a record in the `PARTITIONS` table, but most of the values are `NULL`.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_CATALOG` | Always `def`. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name containing the partition. |
| `PARTITION_NAME` | Partition name. |
| `SUBPARTITION_NAME` | Subpartition name, or `NULL` if not a subpartition. |
| `PARTITION_ORDINAL_POSITION` | Order of the partition starting from 1. |
| `SUBPARTITION_ORDINAL_POSITION` | Order of the subpartition starting from 1. |
| `PARTITION_METHOD` | The partitioning type; one of `RANGE`, `LIST`, `HASH`, `LINEAR HASH`, `KEY` or `LINEAR KEY`. |
| `SUBPARTITION_METHOD` | Subpartition type; one of `HASH`, `LINEAR HASH`, `KEY` or `LINEAR KEY`, or `NULL` if not a subpartition. |
| `PARTITION_EXPRESSION` | Expression used to create the partition by the `[CREATE TABLE](../create-table/index)` or `[ALTER TABLE](../alter-table/index)` statement. |
| `SUBPARTITION_EXPRESSION` | Expression used to create the subpartition by the `[CREATE TABLE](../create-table/index)` or `[ALTER TABLE](../alter-table/index)` statement, or `NULL` if not a subpartition. |
| `PARTITION_DESCRIPTION` | For a `RANGE` partition, contains either `MAXINTEGER` or an integer, as set in the `VALUES LESS THAN` clause. For a `LIST` partition, contains a comma-separated list of integers, as set in the `VALUES IN`. `NULL` if another type of partition. |
| `TABLE_ROWS` | Number of rows in the table (may be an estimate for some storage engines). |
| `AVG_ROW_LENGTH` | Average row length, that is `DATA_LENGTH` divided by `TABLE_ROWS` |
| `DATA_LENGTH` | Total number of bytes stored in all rows of the partition. |
| `MAX_DATA_LENGTH` | Maximum bytes that could be stored in the partition. |
| `INDEX_LENGTH` | Size in bytes of the partition index file. |
| `DATA_FREE` | Unused bytes allocated to the partition. |
| `CREATE_TIME` | Time the partition was created |
| `UPDATE_TIME` | Time the partition was last modified. |
| `CHECK_TIME` | Time the partition was last checked, or `NULL` for storage engines that don't record this information. |
| `CHECKSUM` | Checksum value, or `NULL` if none. |
| `PARTITION_COMMENT` | Partition comment, truncated to 80 characters, or an empty string if no comment. |
| `NODEGROUP` | Node group, only used for MySQL Cluster, defaults to `0`. |
| `TABLESPACE_NAME` | Always `default`. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-partitions-table/>

mariadbd Options
================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd` is a symlink to `mysqld`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd` is the name of the binary, with `mysqld` a symlink .

 
 This page lists all of the options for `mariadbd` (called mysqld before [MariaDB 10.5](../what-is-mariadb-105/index)), ordered by topic. For a full alphabetical list of all mariadbd options, as well as server and status variables, see [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index).

 In many cases, the entry here is a summary, and links to the full description.

 By convention, [server variables](../server-system-variables/index) have usually been specified with an underscore in the configuration files, and a dash on the command line. You can however specify underscores as dashes - they are interchangeable.

 See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index) for which files and groups mariadbd reads for it's default options.

 Option Prefixes
---------------

 #### `--autoset-*`

 * **Description:** Sets the option value automatically. Only supported for certain options.

 #### `--disable-*`

 * **Description:** For all boolean options, disables the setting (equivalent to setting it to `0`). Same as `--skip`.

 #### `--enable-*`

 * **Description:** For all boolean options, enables the setting (equivalent to setting it to `1`).

 #### `--loose-*`

 * **Description:** Don't produce an error if the option doesn't exist.

 #### `--maximum-*`

 * **Description:** Sets the maximum value for the option.

 #### `--skip-*`

 * **Description:** For all boolean options, disables the setting (equivalent to setting it to `0`). Same as `--disable`.

 Option File Options
-------------------

 #### `--defaults-extra-file`

 * **Commandline:** `--defaults-extra-file=name`
* **Description:** Read this extra option file after all other option files are read.
	+ See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

 

---

 #### `--defaults-file`

 * **Commandline:** `--defaults-file=name`
* **Description:** Only read options from the given option file.
	+ See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

 

---

 #### `--defaults-group-suffix`

 * **Commandline:** `--defaults-group-suffix=name`
* **Description:** In addition to the default option groups, also read option groups with the given suffix.
	+ See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

 

---

 #### `--no-defaults`

 * **Commandline:** `--no-defaults`
* **Description:** Don't read options from any option file.
	+ See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

 

---

 #### `--print-defaults`

 * **Commandline:** `--print-defaults`
* **Description:** Read options from option files, print all option values, and then exit the program.
	+ See [Configuring MariaDB with Option Files](../configuring-mariadb-with-option-files/index).

 

---

 Compatibility Options
---------------------

 The following options have been added to MariaDB to make it more compliant with other MariaDB and MySQL versions. Options that are also system variables are listed after:

 #### `-a, --ansi`

 * **Description:** Use ANSI SQL syntax instead of MariaDB syntax. This mode will also set [transaction isolation level](../set-transaction-isolation-level/index#isolation-levels) [serializable](../set-transaction-isolation-level/index#serializable).

 

---

 #### `--new`

 * **Description:** Use new functionality that will exist in next version of MariaDB. This function exists to make it easier to prepare for an upgrade. For version 5.1 this functions enables the LIST and RANGE partitions functions for ndbcluster.

 

---

 #### `--old-style-user-limits`

 * **Description:** Enable old-style user limits (before MySQL 5.0.3, user resources were counted per each user+host vs. per account).

 

---

 #### `--safe-mode`

 * **Description:** Disable some potential unsafe optimizations. For 5.2, [INSERT DELAYED](../insert-delayed/index) is disabled, [myisam\_recover\_options](../myisam-system-variables/index#myisam_recover_options) is set to DEFAULT (automatically recover crashed MyISAM files) and the [query cache](../query-cache/index) is disabled. For [Aria](../aria/index) tables, disable bulk insert optimization to enable one to use [aria\_read\_log](../aria_read_log/index) to recover tables even if tables are deleted (good for testing recovery).

 

---

 #### `--skip-new`

 * **Description:** Disables [--new](#-new) in 5.2. In 5.1 used to disable some new potentially unsafe functions.

 

---

 ### Compatibility Options and System Variables

 * [--old](../server-system-variables/index#old)
* [--old-alter-table](../server-system-variables/index#old_alter_table)
* [--old-mode](../server-system-variables/index#old_mode)
* [--old-passwords](../server-system-variables/index#old_passwords)
* [--show-old-temporals](../server-system-variables/index#show_old_temporals)

 Locale Options
--------------

 Options that are also system variables are listed after:

 #### `--character-set-client-handshake`

 * **Commandline:** `--character-set-client-handshake`
* **Description:** Don't ignore client side character set value sent during handshake.

 

---

 #### `--default-character-set`

 * **Commandline:** `--default-character-set=name`
* **Description:** Still available as an option for setting the default character set for clients and their connections, it was deprecated and removed in [MariaDB 10.2](../what-is-mariadb-102/index) as a server option. Use [character-set-server](../server-system-variables/index#character_set_server) instead.

 

---

 #### `--language`

 * **Description:** This option can be used to set the server's language for error messages. This option can be specified either as a language name or as the path to the directory storing the language's [error message file](../error-log/index#error-messages-file). See [Server Locales](../server-locale/index) for a list of supported locales and their associated languages.
	+ This option is deprecated. Use the `[lc\_messages](../server-system-variables/index#lc_messages)` and `[lc\_messages\_dir](../server-system-variables/index#lc_messages_dir)` system variables instead.
	+ See [Setting the Language for Error Messages](../setting-the-language-for-error-messages/index) for more information.

 

---

 ### Locale Options and System Variables

 * [character-set-filesystem](../server-system-variables/index#character_set_filesystem)
* [character-set-client](../server-system-variables/index#character_set_client)
* [character-set-connection](../server-system-variables/index#character_set_connection)
* [character-set-database](../server-system-variables/index#character_set_database)
* [character-set-filesystem](../server-system-variables/index#character_set_filesystem)
* [character-set-results](../server-system-variables/index#character_set_results)
* [character-set-server](../server-system-variables/index#character_set_server)
* [character-set-system](../server-system-variables/index#character_set_system)
* [character-sets-dir](../server-system-variables/index#character_sets_dir)
* [collation-connection](../server-system-variables/index#collation_connection)
* [collation-database](../server-system-variables/index#collation_database)
* [collation-server](../server-system-variables/index#collation_server)
* [default-week-format](../server-system-variables/index#default_week_format)
* [default-time-zone](../server-system-variables/index#time_zone)
* [lc-messages](../server-system-variables/index#lc_messages)
* [lc-messages-dir](../server-system-variables/index#lc_messages_dir)
* [lc-time-names](../server-system-variables/index#lc_time_names)

 Windows Options
---------------

 Options that are also system variables are listed after:

 #### `--console`

 * **Description:** Windows-only option that keeps the console window open and for writing log messages to stderr and stdout. If specified together with [--log-error](../server-system-variables/index#log_error), the last option will take precedence.

 

---

 #### `--install`

 * **Description:** Windows-only option that installs the `mariadbd` process as a Windows service.
	+ The Windows service created with this option [auto-starts](https://docs.microsoft.com/en-us/windows/desktop/Services/automatically-starting-services). If you want a service that is [started on demand](https://docs.microsoft.com/en-us/windows/desktop/Services/starting-services-on-demand), then use the `[--install-manual](#install-manual)` option.
	+ This option takes a service name as an argument. If this option is provided without a service name, then the service name defaults to "MARIADB".
	+ This option is deprecated and may be removed in a future version. See [MDEV-19358](https://jira.mariadb.org/browse/MDEV-19358) for more information.

 

---

 #### `--install-manual`

 * **Description:** Windows-only option that installs the `mariadbd` process as a Windows service.
	+ The Windows service created with this option is [started on demand](https://docs.microsoft.com/en-us/windows/desktop/Services/starting-services-on-demand). If you want a service that [auto-starts](https://docs.microsoft.com/en-us/windows/desktop/Services/automatically-starting-services), use the `[--install](#install)` option.
	+ This option takes a service name as an argument. If this option is provided without a service name, then the service name defaults to "MARIADB".
	+ This option is deprecated and may be removed in a future version. See [MDEV-19358](https://jira.mariadb.org/browse/MDEV-19358) for more information.

 

---

 #### `--remove`

 * **Description:** Windows-only option that removes the Windows service created by the `[--install](#install)` or `[--install-manual](#install-manual)` options.
	+ This option takes a service name as an argument. If this option is provided without a service name, then the service name defaults to "MARIADB".
	+ This option is deprecated and may be removed in a future version. See [MDEV-19358](https://jira.mariadb.org/browse/MDEV-19358) for more information.

 

---

 #### `--slow-start-timeout`

 * **Description:** Windows-only option that defines the maximum number of milliseconds that the service control manager should wait before trying to kill the Windows service during startup. Defaults to `15000`.

 

---

 #### `--standalone`

 * **Description:** Windows-only option that has no effect. Kept for compatibility reasons.

 

---

 ### Windows Options and System Variables

 The following options and system variables are related to using MariaDB on Windows:

 * `[--named-pipe](../server-system-variables/index#named_pipe)`

 Replication and Binary Logging Options
--------------------------------------

 The following options are related to [replication](../replication/index) and the [binary log](../binary-log/index). Options that are also system variables are listed after: 

 #### `--abort-slave-event-count`

 * **Commandline:** `--abort-slave-event-count=#`
* **Description:** Option used by mysql-test for debugging and testing of replication.

 

---

 #### `--binlog-do-db`

 * **Commandline:** `--binlog-do-db=name`
* **Description:** This option allows you to configure a [replication master](../replication/index) to write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.
	+ This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ This option can **not** be set dynamically. Available as a [system variable](../replication-and-binary-log-system-variables/index#binlog_do_db) from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.

 

---

 #### `--binlog-ignore-db`

 * **Commandline:** `--binlog-ignore-db=name`
* **Description:** This option allows you to configure a [replication master](../replication/index) to **not** write statements and transactions affecting databases that match a specified name into its [binary log](../binary-log/index). Since the filtered statements or transactions will not be present in the [binary log](../binary-log/index), its replicas will not be able to replicate them.
	+ This option will **not** work with cross-database updates with [statement-based logging](../binary-log-formats/index#statement-based-logging). See the [Statement-Based Logging](../replication-filters/index#statement-based-logging) section for more information.
	+ This option can **not** be set dynamically. Available as a [system variable](../replication-and-binary-log-system-variables/index#binlog_ignore_db) from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).
	+ When setting it on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), the option does not accept a comma-separated list. If you would like to specify multiple filters, then you need to specify the option multiple times.
	+ See [Replication Filters](../replication-filters/index) for more information.

 

---

 #### `--binlog-row-event-max-size`

 * **Commandline:** `--binlog-row-event-max-size=#`
* **Description:** The maximum size of a row-based [binary log](../binary-log/index) event in bytes. Rows will be grouped into events smaller than this size if possible. The value has to be a multiple of 256. Available as a [system variable](../replication-and-binary-log-system-variables/index#binlog_row_event_max_size) from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).
* **Default value** `8192`

 

---

 #### `--disconnect-slave-event-count`

 * **Commandline:** `--disconnect-slave-event-count=#`
* **Description:** Option used by mysql-test for debugging and testing of replication.

 

---

 #### `--flashback`

 * **Commandline:** `--flashback`
* **Description:** Setup the server to use flashback. This enables the [binary log](../binary-log/index) and sets `binlog_format=ROW`.
* **Introduced:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `--init-rpl-role`

 * **Commandline:** `--init-rpl-role=name`
* **Description:** Set the replication role.

 

---

 #### `--log-basename`

 * **Commandline:** `--log-basename=name`
* **Description:** 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. This is especially recommended to be set if you are using [replication](../replication/index) as it ensures that your log file names are not dependent on your host name. Sets names for [log-bin](../replication-and-binary-log-server-system-variables/index#log_bin), [log-bin-index](../replication-and-binary-log-server-system-variables/index#log_bin_index), [relay-log](../replication-and-binary-log-server-system-variables/index#relay_log), [relay-log-index](../replication-and-binary-log-server-system-variables/index#relay_log_index), [general-log-file](../server-system-variables/index#general_log_file), `--log-slow-query-log-file`, `--log-error-file`, and [pid-file](../server-system-variables/index#pid_file).
* **Introduced:** [MariaDB 5.2](../what-is-mariadb-52/index)

 

---

 #### `--log-bin-trust-routine-creators`

 * **Commandline:** `--log-bin-trust-routine-creators`
* **Description:** Deprecated, use [log-bin-trust-function-creators](../replication-and-binary-log-server-system-variables/index#log_bin_trust_function_creators).

 

---

 #### `--master-host`

 * **Commandline:** `--master-host=name`
* **Description:** Primary hostname or IP address for replication. If not set, the replica thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.

 

---

 #### `--master-info-file`

 * **Commandline:** `--master-info-file=name`
* **Description:** Name and location of the file on the replica where the `MASTER_LOG_FILE` and `MASTER_LOG_POS` options (i.e. the [binary log](../binary-log/index) position on the primary) and most other [CHANGE MASTER](../change-master-to/index) options are written. The [replica's I/O thread](../replication-threads/index#replica-io-thread) keeps this [binary log](../binary-log/index) position updated as it downloads events.
	+ See [CHANGE MASTER TO: Option Persistence](../change-master-to/index#option-persistence) for more information.

 

---

 #### `--master-password`

 * **Commandline:** `--master-password=name`
* **Description:** The password the replica thread will authenticate with when connecting to the primary. If not set, an empty password is assumed. The value in master.info will take precedence if it can be read.

 

---

 #### `--master-port`

 * **Commandline:** `--master-port=#`
* **Description:** The port the master is listening on. If not set, the compiled setting of MYSQL\_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read.

 

---

 #### `--master-retry-count`

 * **Commandline:** `--master-retry-count=#`
* **Description:** Number of times a replica will attempt to connect to a primary before giving up. The retry interval is determined by the MASTER\_CONNECT\_RETRY option for the CHANGE MASTER statement. A value of 0 means the replica will not stop attempting to reconnect. Reconnects are triggered when a replica has timed out. See [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout).
* **Default Value:** `86400`
* **Range - 32 bit:** `0 to 4294967295`
* **Range - 64 bit:** `0 to 18446744073709551615`

 

---

 #### `--master-ssl`

 * **Commandline:** `--master-ssl`
* **Description:** Enable the replica to [connect to the master using TLS](../secure-connections-overview/index).

 

---

 #### `--master-ssl-ca`

 * **Commandline:** `--master-ssl-ca[=name]`
* **Description:** Master TLS CA file. Only applies if you have enabled [master-ssl](#-master-ssl).

 

---

 #### `--master-ssl-capath`

 * **Commandline:** `--master-ssl-capath[=name]`
* **Description:** Master TLS CA path. Only applies if you have enabled [master-ssl](#-master-ssl).

 

---

 #### `--master-ssl-cert`

 * **Commandline:** `--master-ssl-cert[=name]`
* **Description:** Master TLS certificate file name. Only applies if you have enabled [master-ssl](#-master-ssl).

 

---

 #### `--master-ssl-cipher`

 * **Commandline:** `--master-ssl-cipher[=name]`
* **Description:** Master TLS cipher. Only applies if you have enabled [master-ssl](#-master-ssl).

 

---

 #### `--master-ssl-key`

 * **Commandline:** `--master-ssl-key[=name]`
* **Description:** Master TLS keyfile name. Only applies if you have enabled [master-ssl](#-master-ssl).

 

---

 #### `--master-user`

 * **Commandline:** `--master-user=name`
* **Description:** The username the replica thread will use for authentication when connecting to the primary. The user must have FILE privilege. If the primary user is not set, user test is assumed. The value in master.info will take precedence if it can be read.

 

---

 #### `--max-binlog-dump-events`

 * **Commandline:** `--max-binlog-dump-events=#`
* **Description:** Option used by mysql-test for debugging and testing of replication.

 

---

 #### `--replicate-same-server-id`

 * **Commandline:** `--replicate-same-server-id`
* **Description:** 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](../replication-and-binary-log-server-system-variables/index#log_slave_updates) is used.

 

---

 #### `--sporadic-binlog-dump-fail`

 * **Commandline:** `--sporadic-binlog-dump-fail`
* **Description:** Option used by mysql-test for debugging and testing of replication.

 

---

 #### `--sysdate-is-now`

 * **Commandline:** `--sysdate-is-now`
* **Description:** Non-default option to alias [SYSDATE()](../sysdate/index) to [NOW()](../now/index) to make it safe for [replication](../replication/index). Since 5.0, SYSDATE() has returned a `dynamic' value different for different invocations, even within the same statement.

 

---

 ### Replication and Binary Logging Options and System Variables

 The following options and system variables are related to [replication](../replication/index) and the [binary log](../binary-log/index):

 * [auto-increment-increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment)
* [auto-increment-offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset)
* [binlog-alter-two-phase](../replication-and-binary-log-server-system-variables/index#binlog_alter_two_phase)
* [binlog-annotate-row-events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events)
* [binlog-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_cache_size)
* [binlog-checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum)
* [binlog-commit-wait-count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count)
* [binlog-commit-wait-usec](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_usec)
* [binlog-direct-non-transactional-updates|](../replication-and-binary-log-server-system-variables/index#binlog_direct_non_transactional_updates)
* [binlog-expire-logs-seconds](../replication-and-binary-log-server-system-variables/index#binlog_expire_logs_seconds)
* [binlog-file-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_file_cache_size)
* [binlog-format](../replication-and-binary-log-server-system-variables/index#binlog_format)
* [binlog-optimize-thread-scheduling](../replication-and-binary-log-server-system-variables/index#binlog_optimize_thread_scheduling)
* [binlog-row-image](../replication-and-binary-log-server-system-variables/index#binlog_row_image)
* [binlog-row-metadata](../replication-and-binary-log-server-system-variables/index#binlog_row_metadata)
* [binlog-stmt-cache-size](../replication-and-binary-log-server-system-variables/index#binlog_stmt_cache_size)
* [default-master-connection](../replication-and-binary-log-server-system-variables/index#default_master_connection)
* [gtid-cleanup-batch-size](../global-transaction-id/index#gtid_cleanup_batch_size)
* [gtid-domain-id](../global-transaction-id/index#gtid_domain_id)
* [gtid-ignore-duplicates](../global-transaction-id/index#gtid_ignore_duplicates)
* [gtid-strict-mode](../global-transaction-id/index#gtid_strict_mode)
* [init-slave](../replication-and-binary-log-server-system-variables/index#init_slave)
* [log-bin](../replication-and-binary-log-server-system-variables/index#log_bin)
* [log-bin-compress](../replication-and-binary-log-server-system-variables/index#log_bin_compress)
* [log-bin-compress-min-len](../replication-and-binary-log-server-system-variables/index#log_bin_compress_min_len)
* [log-bin-index](../replication-and-binary-log-server-system-variables/index#log_bin_index)
* [log-bin-trust-function-creators](../replication-and-binary-log-server-system-variables/index#log_bin_trust_function_creators)
* [log-slave-updates](../replication-and-binary-log-server-system-variables/index#log_slave_updates)
* [master-verify-checksum](../replication-and-binary-log-server-system-variables/index#master_verify_checksum)
* [max-binlog-cache-size](../replication-and-binary-log-server-system-variables/index#max_binlog_cache_size)
* [max-binlog-size](../replication-and-binary-log-server-system-variables/index#max_binlog_size)
* [max-binlog-stmt-cache-size](../replication-and-binary-log-server-system-variables/index#max_binlog_stmt_cache_size)
* [max-relay-log-size](../replication-and-binary-log-server-system-variables/index#max_relay_log_size)
* [read-binlog-speed-limit](../replication-and-binary-log-server-system-variables/index#read_binlog_speed_limit)
* [relay-log](../replication-and-binary-log-server-system-variables/index#relay_log)
* [relay-log-index](../replication-and-binary-log-server-system-variables/index#relay_log_index)
* [relay-log-info-file](../replication-and-binary-log-server-system-variables/index#relay_log_info_file)
* [relay-log-purge](../replication-and-binary-log-server-system-variables/index#relay_log_purge)
* [relay-log-recovery](../replication-and-binary-log-server-system-variables/index#relay_log_recovery)
* [relay-log-space-limit](../replication-and-binary-log-server-system-variables/index#relay_log_space_limit)
* [replicate-annotate-row-events](../replication-and-binary-log-server-system-variables/index#replicate_annotate_row_events)
* [replicate-do-db](../replication-and-binary-log-server-system-variables/index#replicate_do_db)
* [replicate-do-table](../replication-and-binary-log-server-system-variables/index#replicate_do_table)
* [replicate-events-marked-for-skip](../replication-and-binary-log-server-system-variables/index#replicate_events_marked_for_skip)
* [replicate-ignore-db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db)
* [replicate-ignore-table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table)
* [replicate-rewrite-db](../replication-and-binary-log-server-system-variables/index#replicate_rewrite_db)
* [replicate-wild-do-table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table)
* [replicate-wild-ignore-table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table)
* [report-host](../replication-and-binary-log-server-system-variables/index#report_host)
* [report-password](../replication-and-binary-log-server-system-variables/index#report_password)
* [report-port](../replication-and-binary-log-server-system-variables/index#report_port)
* [report-user](../replication-and-binary-log-server-system-variables/index#report_user)
* [rpl-recovery-rank](../replication-and-binary-log-server-system-variables/index#rpl_recovery_rank)
* [server-id](../replication-and-binary-log-server-system-variables/index#server_id)
* [slave-compressed-protocol](../replication-and-binary-log-server-system-variables/index#slave_compressed_protocol)
* [slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode)
* [slave-domain-parallel-threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads)
* [slave-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_exec_mode)
* [slave-load-tmpdir](../replication-and-binary-log-server-system-variables/index#slave_load_tmpdir)
* [slave-max-allowed-packet](../replication-and-binary-log-server-system-variables/index#slave_max_allowed_packet)
* [slave-net-timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout)
* [slave-parallel-max-queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued)
* [slave-parallel-threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads)
* [slave-run-triggers-for-rbr](../replication-and-binary-log-server-system-variables/index#slave_run_triggers_for_rbr)
* [slave-skip-errors](../replication-and-binary-log-server-system-variables/index#slave_skip_errors)
* [slave-sql-verify-checksum](../replication-and-binary-log-server-system-variables/index#slave_sql_verify_checksum)
* [slave-transaction-retries](../replication-and-binary-log-server-system-variables/index#slave_transaction_retries)
* [slave\_transaction\_retry\_errors](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_errors)
* [slave\_transaction\_retry\_interval](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_interval)
* [slave-type-conversions](../replication-and-binary-log-server-system-variables/index#slave_type_conversions)
* [sync-binlog](../replication-and-binary-log-server-system-variables/index#sync_binlog)
* [sync-master-info](../replication-and-binary-log-server-system-variables/index#sync_master_info)
* [sync-relay-log](../replication-and-binary-log-server-system-variables/index#sync_relay_log)
* [sync-relay-log-info](../replication-and-binary-log-server-system-variables/index#sync_relay_log_info)

 ### Semisynchronous Replication Options and System Variables

 The options and system variables related to [Semisynchronous Replication](../semisynchronous-replication/index) are described [here](../semisynchronous-replication/index#system-variables).

 Optimizer Options
-----------------

 Options that are also system variables are listed after:

 #### `--record-buffer`

 * **Commandline:** `--record-buffer=#`
* **Description:** Old alias for [read\_buffer\_size](../server-system-variables/index#read_buffer_size).
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `--table-cache`

 * **Commandline:** `--table-open-cache=#`
* **Description:** Removed; use [--table-open-cache](../server-system-variables/index#table_open_cache) instead.
* **Removed:** [MariaDB 5.1.3](https://mariadb.com/kb/en/mariadb-513-release-notes/)

 

---

 ### Optimizer Options and System Variables

 * [alter-algorithm](../server-system-variables/index#alter_algorithm)
* [analyze-sample-percentage](../server-system-variables/index#analyze_sample_percentage)
* [big-tables](../server-system-variables/index#big_tables)
* [bulk-insert-buffer-size](../server-system-variables/index#bulk_insert_buffer_size)
* [expensive-subquery-limit](../server-system-variables/index#expensive_subquery_limit)
* [join-buffer-size](../server-system-variables/index#join_buffer_size)
* [join-buffer-space-limit](../server-system-variables/index#join_buffer_space_limit)
* [join-cache-level](../server-system-variables/index#join_cache_level)
* [max-heap-table-size](../server-system-variables/index#max_heap_table_size)
* [max-join-size](../server-system-variables/index#max_join_size)
* [max-seeks-for-key](../server-system-variables/index#max_seeks_for_key)
* [max-sort-length](../server-system-variables/index#max_sort_length)
* [mrr-buffer-size](../server-system-variables/index#mrr_buffer_size)
* [optimizer-extra-pruning-depth](../server-system-variables/index#optimizer_extra_pruning_depth)
* [optimizer-max-sel-arg-weight](../server-system-variables/index#optimizer_max_sel_arg_weight)
* [optimizer-prune-level](../server-system-variables/index#optimizer_prune_level)
* [optimizer-search-depth](../server-system-variables/index#optimizer_search_depth)
* [optimizer-selectivity-sampling-limit](../server-system-variables/index#optimizer_selectivity_sampling_limit)
* [optimizer-switch](../server-system-variables/index#optimizer_switch)
* [optimizer-trace](../server-system-variables/index#optimizer_trace)
* [optimizer-trace-max-mem-size](../server-system-variables/index#optimizer_trace_max_mem_size)
* [optimizer-use-condition-selectivity](../server-system-variables/index#optimizer_use_condition_selectivity)
* [query-alloc-block-size](../server-system-variables/index#query_alloc_block_size)
* [query-prealloc-size](../server-system-variables/index#query_prealloc_size)
* [range-alloc-block-size](../server-system-variables/index#range_alloc_block_size)
* [read-buffer-size](../server-system-variables/index#read_buffer_size)
* [rowid-merge-buff-size](../server-system-variables/index#rowid_merge_buff_size)
* [table-definition-cache](../server-system-variables/index#table_definition_cache)
* [table-open-cache](../server-system-variables/index#table_open_cache)
* [table-open-cache-instances](../server-system-variables/index#table_open_cache_instances)
* [tmp-disk-table-size](../server-system-variables/index#tmp_disk_table_size)
* [tmp-memory-table-size](../server-system-variables/index#tmp_memory_table_size)
* [tmp-table-size](../server-system-variables/index#tmp_table_size)
* [use-stat-tables](../server-system-variables/index#use_stat_tables)

 Storage Engine Options
----------------------

 #### `--skip-bdb`

 * **Commandline:** `----skip-bdb`
* **Description:** Deprecated option; Exists only for compatibility with very old my.cnf files.
* **Removed:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)

 

---

 #### `--external-locking`

 * **Commandline:** `--external-locking`
* **Description:** Use system (external) locking (disabled by default). With this option enabled you can run [myisamchk](../myisamchk/index) to test (not repair) tables while the server is running. Disable with [--skip-external-locking](../server-system-variables/index#skip_external_locking). From [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10240-release-notes/), [MariaDB 10.3.31](https://mariadb.com/kb/en/mariadb-10331-release-notes/), [MariaDB 10.4.21](https://mariadb.com/kb/en/mariadb-10421-release-notes/), [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10512-release-notes/), [MariaDB 10.6.4](https://mariadb.com/kb/en/mariadb-1064-release-notes/) and all later version, this effects InnoDB and can be used to prevent multiple instances running on the same data.

 

---

 ### MyISAM Storage Engine Options

 The options related to the [MyISAM](../myisam-storage-engine/index) storage engine are described below. Options that are also system variables are listed after:

 #### `--log-isam`

 * **Commandline:** `--log-isam[=file_name]`
* **Description:** Enable the [MyISAM log](../myisam-log/index), which logs all MyISAM changes to file. If no filename is provided, the default, *myisam.log* is used.

 

---

 #### MyISAM Storage Engine Options and System Variables

 Some options and system variables related to the [MyISAM](../myisam-storage-engine/index) storage engine can be found [here](../myisam-system-variables/index). Direct links to many of them can be found below.

 * [concurrent-insert](../server-system-variables/index#concurrent_insert)
* [delayed-insert-limit](../server-system-variables/index#delayed_insert_limit)
* [delayed-insert-timeout](../server-system-variables/index#delayed_insert_timeout)
* [delayed-queue-size](../server-system-variables/index#delayed_queue_size)
* [keep-files-on-create](../server-system-variables/index#keep_files_on_create)
* [key-buffer-size](../myisam-system-variables/index#key_buffer_size)
* [key-cache-age-threshold](../myisam-system-variables/index#key_cache_age_threshold)
* [key-cache-block-size](../myisam-system-variables/index#key_cache_block_size)
* [key-cache-division-limit](../myisam-system-variables/index#key_cache_division_limit)
* [key-cache-file-hash-size](../myisam-system-variables/index#key_cache_file_hash_size)
* [key-cache-segments](../myisam-system-variables/index#key_cache_segments)
* [myisam-block-size](../myisam-server-system-variables/index#myisam_block_size)
* [myisam-data-pointer-size](../myisam-server-system-variables/index#myisam_data_pointer_size)
* [myisam-max-sort-file-size](../myisam-server-system-variables/index#myisam_max_sort_file_size)
* [myisam-mmap-size](../myisam-server-system-variables/index#myisam_mmap_size)
* [myisam-recover-options](../myisam-server-system-variables/index#myisam_recover_options)
* [myisam-repair-threads](../myisam-server-system-variables/index#myisam_repair_threads)
* [myisam-sort-buffer-size](../myisam-server-system-variables/index#myisam_sort_buffer_size)
* [myisam-stats-method](../myisam-server-system-variables/index#myisam_stats_method)
* [myisam-use-mmap](../myisam-server-system-variables/index#myisam_use_mmap)

 ### InnoDB Storage Engine Options

 The options related to the [InnoDB](../innodb/index) storage engine are described below. Options that are also system variables are listed after:

 #### `--innodb`

 * **Commandline:** `--innodb=value`, `--skip-innodb`
* **Description:** This variable controls whether or not to load the InnoDB storage engine. Possible values are `ON`, `OFF`, `FORCE` or `FORCE_PLUS_PERMANENT` (from [MariaDB 5.5](../what-is-mariadb-55/index)). If set to `OFF` (the same as --skip-innodb), since InnoDB is the default storage engine, the server will not start unless another storage engine has been chosen with [--default-storage-engine](../server-system-variables/index#default_storage_engine). `FORCE` means that the storage engine must be successfully loaded, or else the server won't start. `FORCE_PLUS_PERMANENT` enables the plugin, but if plugin cannot initialize, the server will not start. In addition, the plugin cannot be uninstalled while the server is running.

 

---

 #### `--innodb-cmp`

 * **Commandline:** `--innodb-cmp`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-cmp-reset`

 * **Commandline:** `--innodb-cmp-reset`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-cmpmem`

 * **Commandline:** `--innodb-cmpmem`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-cmpmem-reset`

 * **Commandline:** `--innodb-cmpmem-reset`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-file-io-threads`

 * **Commandline:** `--innodb-file-io-threads`
* **Description:**
* **Default:** `4`
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `--innodb-index-stats`

 * **Commandline:** `--innodb-index-stats`
* **Description:**
* **Default:** `ON`
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `--innodb-lock-waits`

 * **Commandline:** `--innodb-lock-waits`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-locks`

 * **Commandline:** `--innodb-locks`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-rseg`

 * **Commandline:** `--innodb-rseg`
* **Description:**
* **Default:** `ON`
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `--innodb-status-file`

 * **Commandline:** `--innodb-status-file`
* **Description:**
* **Default:** `FALSE`

 

---

 #### `--innodb-sys-indexes`

 * **Commandline:** `--innodb-sys-indexes`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-sys-stats`

 * **Commandline:** `--innodb-sys-stats`
* **Description:**
* **Default:** `ON`
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `--innodb-sys-tables`

 * **Commandline:** `--innodb-sys-tables`
* **Description:**
* **Default:** `ON`

 

---

 #### `--innodb-table-stats`

 * **Commandline:** `--innodb-table-stats`
* **Description:**
* **Default:** `ON`
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `--innodb-trx`

 * **Commandline:** `--innodb-trx`
* **Description:**
* **Default:** `ON`

 

---

 #### InnoDB Storage Engine Options and System Variables

 Some options and system variables related to the [InnoDB](../innodb/index) storage engine can be found [here](../innodb-system-variables/index). Direct links to many of them can be found below.

 * [ignore-builtin-innodb](../innodb-system-variables/index#ignore_builtin_innodb)
* [innodb-adaptive-checkpoint](../innodb-system-variables/index#innodb_adaptive_checkpoint)
* [innodb-adaptive-flushing](../innodb-system-variables/index#innodb_adaptive_flushing)
* [innodb-adaptive-flushing-lwm](../innodb-system-variables/index#innodb_adaptive_flushing_lwm)
* [innodb-adaptive-flushing-method](../innodb-system-variables/index#innodb_adaptive_flushing_method)
* [innodb-adaptive-hash-index](../innodb-system-variables/index#innodb_adaptive_hash_index)
* [innodb-adaptive-hash-index-partitions](../innodb-system-variables/index#innodb_adaptive_hash_index_partitions)
* [innodb-adaptive-hash-index-parts](../innodb-system-variables/index#innodb_adaptive_hash_index_parts)
* [innodb-adaptive-max-sleep-delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay)
* [innodb-additional-mem-pool-size](../innodb-system-variables/index#innodb_additional_mem_pool_size)
* [innodb-api-bk-commit-interval](../innodb-system-variables/index#innodb_api_bk_commit_interval)
* [innodb-api-disable-rowlock](../innodb-system-variables/index#innodb_api_disable_rowlock)
* [innodb-api-enable-binlog](../innodb-system-variables/index#innodb_api_enable_binlog)
* [innodb-api-enable-mdl](../innodb-system-variables/index#innodb_api_enable_mdl)
* [innodb-api-trx-level](../innodb-system-variables/index#innodb_api_trx_level)
* [innodb-auto-lru-dump](../innodb-system-variables/index#innodb_auto_lru_dump)
* [innodb-autoextend-increment](../innodb-system-variables/index#innodb_autoextend_increment)
* [innodb-autoinc-lock-mode](../innodb-system-variables/index#innodb_autoinc_lock_mode)
* [innodb-background-scrub-data-check-interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval)
* [innodb-background-scrub-data-compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed)
* [innodb-background-scrub-data-interval](../innodb-system-variables/index#innodb_background_scrub_data_interval)
* [innodb-background-scrub-data-uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed)
* [innodb-blocking-buffer-pool-restore](../innodb-system-variables/index#innodb_blocking_buffer_pool_restore)
* [innodb-buf-dump-status-frequency](../innodb-system-variables/index#innodb_buf_dump_status_frequency)
* [innodb-buffer-pool-chunk-size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size)
* [innodb-buffer-pool-dump-at-shutdown](../innodb-system-variables/index#innodb_buffer_pool_dump_at_shutdown)
* [innodb-buffer-pool-dump-now](../innodb-system-variables/index#innodb_buffer_pool_dump_now)
* [innodb-buffer-pool-dump-pct](../innodb-system-variables/index#innodb_buffer_pool_dump_pct)
* [innodb-buffer-pool-evict](../innodb-system-variables/index#innodb_buffer_pool_evict)
* [innodb-buffer-pool-filename](../innodb-system-variables/index#innodb_buffer_pool_filename)
* [innodb-buffer-pool-instances](../innodb-system-variables/index#innodb_buffer_pool_instances)
* [innodb-buffer-pool-load-abort](../innodb-system-variables/index#innodb_buffer_pool_load_abort)
* [innodb-buffer-pool-load-at-startup](../innodb-system-variables/index#innodb_buffer_pool_load_at_startup)
* [innodb-buffer-pool-load-now](../innodb-system-variables/index#innodb_buffer_pool_load_now)
* [innodb-buffer-pool-load-pages-abort](../innodb-system-variables/index#innodb_buffer_pool_load_pages_abort)
* [innodb-buffer-pool-populate](../innodb-system-variables/index#innodb_buffer_pool_populate)
* [innodb-buffer-pool-restore-at-startup](../innodb-system-variables/index#innodb_buffer_pool_restore_at_startup)
* [innodb-buffer-pool-shm-checksum](../innodb-system-variables/index#innodb_buffer_pool_shm_checksum)
* [innodb-buffer-pool-shm-key](../innodb-system-variables/index#innodb_buffer_pool_shm_key)
* [innodb-buffer-pool-size](../innodb-system-variables/index#innodb_buffer_pool_size)
* [innodb-change-buffer-max-size](../innodb-system-variables/index#innodb_change_buffer_max_size)
* [innodb-change-buffering](../innodb-system-variables/index#innodb_change_buffering)
* [innodb-change-buffering-debug](../innodb-system-variables/index#innodb_change_buffering_debug)
* [innodb-checkpoint-age-target](../innodb-system-variables/index#innodb_checkpoint_age_target)
* [innodb-checksum-algorithm](../innodb-system-variables/index#innodb_checksum_algorithm)
* [innodb-checksums](../innodb-system-variables/index#innodb_checksums)
* [innodb-cleaner-lsn-age-factor](../innodb-system-variables/index#innodb_cleaner_lsn_age_factor)
* [innodb-cmp-per-index-enabled](../innodb-system-variables/index#innodb_cmp_per_index_enabled)
* [innodb-commit-concurrency](../innodb-system-variables/index#innodb_commit_concurrency)
* [innodb-compression-algorithm](../innodb-system-variables/index#innodb_compression_algorithm)
* [innodb-compression-failure-threshold-pct](../innodb-system-variables/index#innodb_compression_failure_threshold_pct)
* [innodb-compression-level](../innodb-system-variables/index#innodb_compression_level)
* [innodb-compression-pad-pct-max](../innodb-system-variables/index#innodb_compression_pad_pct_max)
* [innodb-concurrency-tickets](../innodb-system-variables/index#innodb_concurrency_tickets)
* [innodb-corrupt-table-action](../innodb-system-variables/index#innodb_corrupt_table_action)
* [innodb-data-file-buffering](../innodb-system-variables/index#innodb_data_file_buffering)
* [innodb-data-file-path](../innodb-system-variables/index#innodb_data_file_path)
* [innodb-data-file-write-through](../innodb-system-variables/index#innodb_data_file_write_through)
* [innodb-data-home-dir](../innodb-system-variables/index#innodb_data_home_dir)
* [innodb-deadlock-detect](../innodb-system-variables/index#innodb_deadlock_detect)
* [innodb-deadlock-report](../innodb-system-variables/index#innodb_deadlock_report)
* [innodb-default-encryption-key-id](../innodb-system-variables/index#innodb_default_encryption_key_id)
* [innodb-default-page-encryption-key](../innodb-system-variables/index#innodb_default_page_encryption_key)
* [innodb-default-row-format](../innodb-system-variables/index#innodb_default_row_format)
* [innodb-defragment](../innodb-system-variables/index#innodb_defragment)
* [innodb-defragment-fill-factor](../innodb-system-variables/index#innodb_defragment_fill_factor)
* [innodb-defragment-fill-factor-n-recs](../innodb-system-variables/index#innodb_defragment_fill_factor_n_recs)
* [innodb-defragment-frequency](../innodb-system-variables/index#innodb_defragment_frequency)
* [innodb-defragment-n-pages](../innodb-system-variables/index#innodb_defragment_n_pages)
* [innodb-defragment-stats-accuracy](../innodb-system-variables/index#innodb_defragment_stats_accuracy)
* [innodb-dict-size-limit](../innodb-system-variables/index#innodb_dict_size_limit)
* [innodb\_disable\_sort\_file\_cache](../innodb-system-variables/index#innodb_disable_sort_file_cache)
* [innodb-doublewrite](../innodb-system-variables/index#innodb_doublewrite)
* [innodb-doublewrite-file](../innodb-system-variables/index#innodb_doublewrite_file)
* [innodb-empty-free-list-algorithm](../innodb-system-variables/index#innodb_empty_free_list_algorithm)
* [innodb-enable-unsafe-group-commit](../innodb-system-variables/index#innodb_enable_unsafe_group_commit)
* [innodb-encrypt-log](../innodb-system-variables/index#innodb_encrypt_log)
* [innodb-encrypt-tables](../innodb-system-variables/index#innodb_encrypt_tables)
* [innodb-encrypt-temporary-tables](../innodb-system-variables/index#innodb_encrypt_tables)
* [innodb-encryption-rotate-key-age](../innodb-system-variables/index#innodb_encryption_rotate_key_age)
* [innodb-encryption-rotation\_iops](../innodb-system-variables/index#innodb_encryption_rotation_iops)
* [innodb-encryption-threads](../innodb-system-variables/index#innodb_encryption_threads)
* [innodb-extra-rsegments](../innodb-system-variables/index#innodb_extra_rsegments)
* [innodb-extra-undoslots](../innodb-system-variables/index#innodb_extra_undoslots)
* [innodb-fake-changes](../innodb-system-variables/index#innodb_fake_changes)
* [innodb-fast-checksum](../innodb-system-variables/index#innodb_fast_checksum)
* [innodb-fast-shutdown](../innodb-system-variables/index#innodb_fast_shutdown)
* [innodb-fatal-semaphore-wait-threshold](../innodb-system-variables/index#innodb_fatal_semaphore_wait_threshold)
* [innodb-file-format](../innodb-system-variables/index#innodb_file_format)
* [innodb-file-format-check](../innodb-system-variables/index#innodb_file_format_check)
* [innodb-file-format-max](../innodb-system-variables/index#innodb_file_format_max)
* [innodb-file-per-table](../innodb-system-variables/index#innodb_file_per_table)
* [innodb-fill-factor](../innodb-system-variables/index#innodb_fill_factor)
* [innodb-flush-log-at-trx-commit](../innodb-system-variables/index#innodb_flush_log_at_trx_commit)
* [innodb-flush-method](../innodb-system-variables/index#innodb_flush_method)
* [innodb-flush-neighbor-pages](../innodb-system-variables/index#innodb_flush_neighbor_pages)
* [innodb-flush-neighbors](../innodb-system-variables/index#innodb_flush_neighbors)
* [innodb-flush-sync](../innodb-system-variables/index#innodb_flush_sync)
* [innodb-flushing-avg-loops](../innodb-system-variables/index#innodb_flushing_avg_loops)
* [innodb-force-load-corrupted](../innodb-system-variables/index#innodb_force_load_corrupted)
* [innodb-force-primary-key](../innodb-system-variables/index#innodb_force_primary_key)
* [innodb-force-recovery](../innodb-system-variables/index#innodb_force_recovery)
* [innodb-foreground-preflush](../innodb-system-variables/index#innodb_foreground_preflush)
* [innodb-ft-aux-table](../innodb-system-variables/index#innodb_ft_aux_table)
* [innodb-ft-cache-size](../innodb-system-variables/index#innodb_ft_cache_size)
* [innodb-ft-enable-diag-print](../innodb-system-variables/index#innodb_ft_enable_diag_print)
* [innodb-ft-enable-stopword](../innodb-system-variables/index#innodb_ft_enable_stopword)
* [innodb-ft-max-token-size](../innodb-system-variables/index#innodb_ft_max_token_size)
* [innodb-ft-min-token-size](../innodb-system-variables/index#innodb_ft_min_token_size)
* [innodb-ft-num-word-optimize](../innodb-system-variables/index#innodb_ft_num_word_optimize)
* [innodb-ft-result-cache-limit](../innodb-system-variables/index#innodb_ft_result_cache_limit)
* [innodb-ft-server-stopword-table](../innodb-system-variables/index#innodb_ft_server_stopword_table)
* [innodb-ft-sort-pll-degree](../innodb-system-variables/index#innodb_ft_sort_pll_degree)
* [innodb-ft-total-cache-size](../innodb-system-variables/index#innodb_ft_total_cache_size)
* [innodb-ft-user-stopword-table](../innodb-system-variables/index#innodb_ft_user_stopword_table)
* [innodb-ibuf-accel-rate](../innodb-system-variables/index#innodb_ibuf_accel_rate)
* [innodb-ibuf-active-contract](../innodb-system-variables/index#innodb_ibuf_active_contract)
* [innodb-ibuf-max-size](../innodb-system-variables/index#innodb_ibuf_max_size)
* [innodb-idle-flush-pct](../innodb-system-variables/index#innodb_idle_flush_pct)
* [innodb-immediate-scrub-data-uncompressed](../innodb-system-variables/index#innodb_immediate_scrub_data_uncompressed)
* [innodb-import-table-from-xtrabackup](../innodb-system-variables/index#innodb_import_table_from_xtrabackup)
* [innodb-instant-alter-column-allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed)
* [innodb-instrument-semaphores](../innodb-system-variables/index#innodb_instrument_semaphores)
* [innodb-io-capacity](../innodb-system-variables/index#innodb_io_capacity)
* [innodb-io-capacity-max](../innodb-system-variables/index#innodb_io_capacity_max)
* [innodb-large-prefix](../innodb-system-variables/index#innodb_large_prefix)
* [innodb-lazy-drop-table](../innodb-system-variables/index#innodb_lazy_drop_table)
* [innodb-lock-schedule-algorithm](../innodb-system-variables/index#innodb_lock_schedule_algorithmt)
* [innodb-locking-fake-changes](../innodb-system-variables/index#innodb_locking_fake_changes)
* [innodb-locks-unsafe-for-binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog)
* [innodb-log-arch-dir](../innodb-system-variables/index#innodb_log_arch_dir)
* [innodb-log-arch-expire-sec](../innodb-system-variables/index#innodb_log_arch_expire_sec)
* [innodb-log-archive](../innodb-system-variables/index#innodb_log_archive)
* [innodb-log-block-size](../innodb-system-variables/index#innodb_log_block_size)
* [innodb-log-buffer-size](../innodb-system-variables/index#innodb_log_buffer_size)
* [innodb-log-checksum-algorithm](../innodb-system-variables/index#innodb_log_checksum_algorithm)
* [innodb-log-checksums](../innodb-system-variables/index#innodb_log_checksums)
* [innodb-log-compressed-pages](../innodb-system-variables/index#innodb_log_compressed_pages)
* [innodb-log-file-buffering](../innodb-system-variables/index#innodb_log_file_buffering)
* [innodb-log-file-size](../innodb-system-variables/index#innodb_log_file_size)
* [innodb-log-file-write-through](../innodb-system-variables/index#innodb_log_file_write_through)
* [innodb-log-files-in-group](../innodb-system-variables/index#innodb_log_files_in_group)
* [innodb-log-group-home-dir](../innodb-system-variables/index#innodb_log_group_home_dir)
* [innodb-log-optimize-ddl](../innodb-system-variables/index#innodb_log_optimize_ddl)
* [innodb-log-write-ahead-size](../innodb-system-variables/index#innodb_log_write_ahead_size)
* [innodb-lru-flush-size](../innodb-system-variables/index#innodb_lru_flush_size)
* [innodb-lru-scan-depth](../innodb-system-variables/index#innodb_lru_scan_depth)
* [innodb-max-bitmap-file-size](../innodb-system-variables/index#innodb_max_bitmap_file_size)
* [innodb-max-changed-pages](../innodb-system-variables/index#innodb_max_changed_pages)
* [innodb-max-dirty-pages-pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct)
* [innodb-max-dirty-pages-pct-lwm](../innodb-system-variables/index#innodb_max_dirty_pages_pct_lwm)
* [innodb-max-purge-lag](../innodb-system-variables/index#innodb_max_purge_lag)
* [innodb-max-purge-lag-delay](../innodb-system-variables/index#innodb_max_purge_lag_delay)
* [innodb-max-purge-lag-wait](../innodb-system-variables/index#innodb_max_purge_lag_wait)
* [innodb-max-undo-log-size](../innodb-system-variables/index#innodb_max_undo_log_size)
* [innodb-merge-sort-block-size](../innodb-system-variables/index#innodb_merge_sort_block_size)
* [innodb-mirrored-log-groups](../innodb-system-variables/index#innodb_mirrored_log_groups)
* [innodb-monitor-disable](../innodb-system-variables/index#innodb_monitor_disable)
* [innodb-monitor-enable](../innodb-system-variables/index#innodb_monitor_enable)
* [innodb-monitor-reset](../innodb-system-variables/index#innodb_monitor_reset)
* [innodb-monitor-reset-all](../innodb-system-variables/index#innodb_monitor_reset_all)
* [innodb-mtflush-threads](../innodb-system-variables/index#innodb_mtflush_threads)
* [innodb-numa-interleave](../innodb-system-variables/index#innodb_numa_interleave)
* [innodb-old-blocks-pct](../innodb-system-variables/index#innodb_old_blocks_pct)
* [innodb-old-blocks-time](../innodb-system-variables/index#innodb_old_blocks_time)
* [innodb-online-alter-log-max-size](../innodb-system-variables/index#innodb_online_alter_log_max_size)
* [innodb-open-files](../innodb-system-variables/index#innodb_open_files)
* [innodb-optimize-fulltext-only](../innodb-system-variables/index#innodb_optimize_fulltext_only)
* [innodb-page-cleaners](../innodb-system-variables/index#innodb_page_cleaners)
* [innodb-page-size](../innodb-system-variables/index#innodb_page_size)
* [innodb-pass-corrupt-table](../innodb-system-variables/index#innodb_pass_corrupt_table)
* [innodb-prefix-index-cluster-optimization](../innodb-system-variables/index#innodb_prefix_index_cluster_optimization)
* [innodb-print-all-deadlocks](../innodb-system-variables/index#innodb_print_all_deadlocks)
* [innodb-purge-batch-size](../innodb-system-variables/index#innodb_purge_batch_size)
* [innodb-purge-rseg-truncate-frequency](../innodb-system-variables/index#innodb_purge_rseg_truncate_frequency)
* [innodb-purge-threads](../innodb-system-variables/index#innodb_purge_threads)
* [innodb-random-read-ahead](../innodb-system-variables/index#innodb_random_read_ahead)
* [innodb-read-ahead](../innodb-system-variables/index#innodb_read_ahead)
* [innodb-read-ahead-threshold](../innodb-system-variables/index#innodb_read_ahead_threshold)
* [innodb-read-io-threads](../innodb-system-variables/index#innodb_read_io_threads)
* [innodb-read-only](../innodb-system-variables/index#innodb_read_only)
* [innodb-recovery-update-relay-log](../innodb-system-variables/index#innodb_recovery_update_relay_log)
* [innodb-replication-delay](../innodb-system-variables/index#innodb_replication_delay)
* [innodb-rollback-on-timeout](../innodb-system-variables/index#innodb_rollback_on_timeout)
* [innodb-rollback-segments](../innodb-system-variables/index#innodb_rollback_segments)
* [innodb-safe-truncate](../innodb-system-variables/index#innodb_safe_truncate)
* [innodb-sched-priority-cleaner](../innodb-system-variables/index#innodb_sched_priority_cleaner)
* [innodb-scrub-log](../innodb-system-variables/index#innodb_scrub_log)
* [innodb-scrub-log-interval](../innodb-system-variables/index#innodb_scrub_log_interval)
* [innodb-scrub-log-speed](../innodb-system-variables/index#innodb_scrub_log_speed)
* [innodb-show-locks-held](../innodb-system-variables/index#innodb_show_locks_held)
* [innodb-show-verbose-locks](../innodb-system-variables/index#innodb_show_verbose_locks)
* [innodb-sort-buffer-size](../innodb-system-variables/index#innodb_sort_buffer_size)
* [innodb-spin-wait-delay](../innodb-system-variables/index#innodb_spin_wait_delay)
* [innodb-stats-auto-recalc](../innodb-system-variables/index#innodb_stats_auto_recalc)
* [innodb-stats-auto-update](../innodb-system-variables/index#innodb_stats_auto_update)
* [innodb-stats-include-delete-marked](../innodb-system-variables/index#innodb_stats_include_delete_marked)
* [innodb-stats-method](../innodb-system-variables/index#innodb_stats_method)
* [innodb-stats-modified-counter](../innodb-system-variables/index#innodb_stats_modified_counter)
* [innodb-stats-on-metadata](../innodb-system-variables/index#innodb_stats_on_metadata)
* [innodb-stats-persistent](../innodb-system-variables/index#innodb_stats_persistent)
* [innodb-stats-persistent-sample-pages](../innodb-system-variables/index#innodb_stats_persistent_sample_pages)
* [innodb-stats-sample-pages](../innodb-system-variables/index#innodb_stats_sample_pages)
* [innodb-stats-transient-sample-pages](../innodb-system-variables/index#innodb_stats_transient_sample_pages)
* [innodb-stats-traditional](../innodb-system-variables/index#innodb_stats_traditional)
* [innodb-stats-update-need-lock](../innodb-system-variables/index#innodb_stats_update_need_lock)
* [innodb-status-output](../innodb-system-variables/index#innodb_status_output)
* [innodb-status-output-locks](../innodb-system-variables/index#innodb_status_output_locks)
* [innodb-strict-mode](../innodb-system-variables/index#innodb_strict_mode)
* [innodb-support-xa](../innodb-system-variables/index#innodb_support_xa)
* [innodb-sync-array-size](../innodb-system-variables/index#innodb_sync_array_size)
* [innodb-sync-spin-loops](../innodb-system-variables/index#innodb_sync_spin_loops)
* [innodb-table-locks](../innodb-system-variables/index#innodb_table_locks)
* [innodb-temp-data-file-path](../innodb-system-variables/index#innodb_temp_data_file_path)
* [innodb-thread-concurrency](../innodb-system-variables/index#innodb_thread_concurrency)
* [innodb-thread-concurrency-timer-based](../innodb-system-variables/index#innodb_thread_concurrency_timer_based)
* [innodb-thread-sleep-delay](../innodb-system-variables/index#innodb_thread_sleep_delay)
* [innodb-tmpdir](../innodb-system-variables/index#innodb_tmpdir)
* [innodb-track-changed-pages](../innodb-system-variables/index#innodb_track_changed_pages)
* [innodb-track-redo-log-now](../innodb-system-variables/index#innodb_track_redo_log_now)
* [innodb-undo-directory](../innodb-system-variables/index#innodb_undo_directory)
* [innodb-undo-log-truncate](../innodb-system-variables/index#innodb_undo_log_truncate)
* [innodb-undo-logs](../innodb-system-variables/index#innodb_undo_logs)
* [innodb-undo-tablespaces](../innodb-system-variables/index#innodb_undo_tablespaces)
* [innodb-use-atomic-writes](../innodb-system-variables/index#innodb_use_atomic_writes)
* [innodb-use-fallocate](../innodb-system-variables/index#innodb_use_fallocate)
* [innodb-use-global-flush-log-at-trx-commit](../innodb-system-variables/index#innodb_use_global_flush_log_at_trx_commit)
* [innodb-use-mtflush](../innodb-system-variables/index#innodb_use_mtflush)
* [innodb-use-native\_aio](../innodb-system-variables/index#innodb_use_native_aio)
* [innodb-use-purge-thread](../innodb-system-variables/index#innodb_use_purge_thread)
* [innodb-use-stacktrace](../innodb-system-variables/index#innodb_use_stacktrace)
* [innodb-use-sys-malloc](../innodb-system-variables/index#innodb_use_sys_malloc)
* [innodb-use-sys-stats-table](../innodb-system-variables/index#innodb_use_sys_stats_table)
* [innodb-use-trim](../innodb-system-variables/index#innodb_use_trim)
* [innodb-write-io-threads](../innodb-system-variables/index#innodb_write_io_threads)
* [skip-innodb](#-innodb)
* [skip-innodb-checksums](../innodb-system-variables/index#innodb_checksums)
* [skip-innodb-doublewrite](../innodb-system-variables/index#innodb_doublewrite)

 ### Aria Storage Engine Options

 The options related to the [Aria](../aria/index) storage engine are described below. Options that are also system variables are listed after:

 #### `--aria-log-dir-path`

 * **Commandline:** `--aria-log-dir-path=value`
* **Description:** Path to the directory where transactional log should be stored
* **Default:** `SAME AS DATADIR`

 

---

 #### Aria Storage Engine Options and System Variables

 Some options and system variables related to the [Aria](../aria/index) storage engine can be found [here](../aria-system-variables/index). Direct links to many of them can be found below.

 * [aria-block-size](../aria-system-variables/index#aria_block_size)
* [aria-checkpoint-interval](../aria-system-variables/index#aria_checkpoint_interval)
* [aria-checkpoint-log-activity](../aria-system-variables/index#aria_checkpoint_log_activity)
* [aria-encrypt-tables](../aria-system-variables/index#aria_encrypt_tables)
* [aria-force-start-after-recovery-failures](../aria-system-variables/index#aria_force_start_after_recovery_failures)
* [aria-group-commit](../aria-system-variables/index#aria_group_commit)
* [aria-group-commit-interval](../aria-system-variables/index#aria_group_commit_interval)
* [aria-log-file-size](../aria-system-variables/index#aria_log_file_size)
* [aria-log-purge-type](../aria-system-variables/index#aria_log_purge_type)
* [aria-max-sort-file-size](../aria-system-variables/index#aria_max_sort_file_size)
* [aria-page-checksum](../aria-system-variables/index#aria_page_checksum)
* [aria-pagecache-age-threshold](../aria-system-variables/index#aria_pagecache_age_threshold)
* [aria-pagecache-buffer-size](../aria-system-variables/index#aria_pagecache_buffer_size)
* [aria-pagecache-division-limit](../aria-system-variables/index#aria_pagecache_division_limit)
* [aria-pagecache-file-hash-size](../aria-system-variables/index#aria_pagecache_file_hash_size)
* [aria-recover](../aria-system-variables/index#aria_recover)
* [aria-recover-options](../aria-system-variables/index#aria_recover_options)
* [aria-repair-threads](../aria-system-variables/index#aria_repair_threads)
* [aria-sort-buffer-size](../aria-system-variables/index#aria_sort_buffer_size)
* [aria-stats-method](../aria-system-variables/index#aria_stats_method)
* [aria-sync-log-dir](../aria-system-variables/index#aria_sync_log_dir)
* [aria-used-for-temp-tables](../aria-system-variables/index#aria_used_for_temp_tables)
* [deadlock-search-depth-long](../aria-system-variables/index#deadlock_search_depth_long)
* [deadlock-search-depth-short](../aria-system-variables/index#deadlock_search_depth_short)
* [deadlock-timeout-long](../aria-system-variables/index#deadlock_timeout_long)
* [deadlock-timeout-short](../aria-system-variables/index#deadlock_timeout_short)

 ### MyRocks Storage Engine Options

 The options and system variables related to the [MyRocks](../myrocks/index) storage engine can be found [here](../myrocks-system-variables/index). 

 ### S3 Storage Engine Options

 The options and system variables related to the [S3](../s3-storage-engine/index) storage engine can be found [here](../s3-storage-engine-system-variables/index).

 ### CONNECT Storage Engine Options

 The options related to the [CONNECT](../connect/index) storage engine are described below.

 #### CONNECT Storage Engine Options and System Variables

 Some options and system variables related to the [CONNECT](../connect/index) storage engine can be found [here](../connect-system-variables/index). Direct links to many of them can be found below.

 * [connect-class-path](../connect-system-variables/index#connect_class_path)
* [connect-cond-push](../connect-system-variables/index#connect_cond_push)
* [connect-conv-size](../connect-system-variables/index#connect_conv_size)
* [connect-default-depth](../connect-system-variables/index#connect_default_depth)
* [connect-default-prec](../connect-system-variables/index#connect_default_prec)
* [connect-enable-mongo](../connect-system-variables/index#connect_enable_mongo)
* [connect-exact-info](../connect-system-variables/index#connect_exact_info)
* [connect-force\_bson](../connect-system-variables/index#connect_force_bson)
* [connect-indx-map](../connect-system-variables/index#connect_indx_map)
* [connect-java-wrapper](../connect-system-variables/index#connect_java_wrapper)
* [connect-json-all-path](../connect-system-variables/index#connect_json_all_path)
* [connect-json-grp-size](../connect-system-variables/index#connect_json_grp_size)
* [connect-json-null](../connect-system-variables/index#connect_json_null)
* [connect-jvm-path](../connect-system-variables/index#connect_jvm_path)
* [connect-type-conv](../connect-system-variables/index#connect_type_conv)
* [connect-use-tempfile](../connect-system-variables/index#connect_use_tempfile)
* [connect-work-size](../connect-system-variables/index#connect_work_size)
* [connect-xtrace](../connect-system-variables/index#connect_xtrace)

 ### Spider Storage Engine Options

 The options and system variables related to the [Spider](../spider/index) storage engine can be found [here](../spider-server-system-variables/index).

 ### Mroonga Storage Engine Options

 The options and system variables related to the [Mroonga](../mroonga/index) storage engine can be found [here](../mroonga-system-variables/index).

 ### TokuDB Storage Engine Options

 The options and system variables related to the [TokuDB](../tokudb/index) storage engine can be found [here](../tokudb-system-variables/index).

 Performance Schema Options
--------------------------

 The options related to the [Performance Schema](../performance-schema/index) are described below. Options that are also system variables are listed after:

 #### `--performance-schema-consumer-events-stages-current`

 * **Commandline:** `--performance-schema-consumer-events-stages-current`
* **Description:** Enable the [events-stages-current](../performance-schema-events_stages_current-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-stages-history`

 * **Commandline:** `--performance-schema-consumer-events-stages-history`
* **Description:** Enable the [events-stages-history](../performance-schema-events_stages_history-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-stages-history-long`

 * **Commandline:** `--performance-schema-consumer-events-stages-history-long`
* **Description:** Enable the [events-stages-history-long](../performance-schema-events_stages_history_long-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-statements-current`

 * **Commandline:** `--performance-schema-consumer-events-statements-current`
* **Description:** Enable the [events-statements-current](../performance-schema-events_statements_current-table/index) consumer. Use `--skip-performance-schema-consumer-events-statements-current` to disable.
* **Default:** `ON`

 

---

 #### `--performance-schema-consumer-events-statements-history`

 * **Commandline:** `--performance-schema-consumer-events-statements-history`
* **Description:** Enable the [events-statements-history](../performance-schema-events_statements_history-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-statements-history-long`

 * **Commandline:** `--performance-schema-consumer-events-statements-history-long`
* **Description:** Enable the [events-statements-history-long](../performance-schema-events_statements_history_long-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-waits-current`

 * **Commandline:** `--performance-schema-consumer-events-waits-current`
* **Description:** Enable the [events-waits-current](../performance-schema-events_waits_current-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-waits-history`

 * **Commandline:** `--performance-schema-consumer-events-waits-history`
* **Description:** Enable the [events-waits-history](../performance-schema-events_waits_history-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-events-waits-history-long`

 * **Commandline:** `--performance-schema-consumer-events-waits-history-long`
* **Description:** Enable the [events-waits-history-long](../performance-schema-events_waits_history_long-table/index) consumer.
* **Default:** `OFF`

 

---

 #### `--performance-schema-consumer-global-instrumentation`

 * **Commandline:** `--performance-schema-consumer-global-instrumentation`
* **Description:** Enable the global-instrumentation consumer. Use `--skip-performance-schema-consumer-global-instrumentation` to disable.
* **Default:** `ON`

 

---

 #### `--performance-schema-consumer-statements-digest`

 * **Commandline:** `--performance-schema-consumer-statements-digest`
* **Description:** Enable the statements-digest consumer. Use `--skip-performance-schema-consumer-statements-digest` to disable.
* **Default:** `ON`

 

---

 #### `--performance-schema-consumer-thread-instrumentation`

 * **Commandline:** `--performance-schema-consumer-thread-instrumentation`
* **Description:** Enable the statements-thread-instrumentation. Use `--skip-performance-schema-thread-instrumentation` to disable.
* **Default:** `ON`

 

---


### Performance Schema Options and System Variables

 Some options and system variables related to the [Performance Schema](../performance-schema/index) can be found [here](../performance-schema-system-variables/index). Direct links to many of them can be found below.

 * [performance-schema](../performance-schema-system-variables/index#performance_schema)
* [performance-schema-accounts-size](../performance-schema-system-variables/index#performance_schema_accounts_size)
* [performance-schema-digests-size](../performance-schema-system-variables/index#performance_schema_digests_size)
* [performance-schema-events-stages-history-long-size](../performance-schema-system-variables/index#performance_schema_events_stages_history_long_size)
* [performance-schema-events-stages-history-size](../performance-schema-system-variables/index#performance_schema_events_stages_history_size)
* [performance-schema-events-statements-history-long-size](../performance-schema-system-variables/index#performance_schema_events_statements_history_long_size)
* [performance-schema-events-statements-history-size](../performance-schema-system-variables/index#performance_schema_events_statements_history_size)
* [performance-schema-events-waits-history-long-size](../performance-schema-system-variables/index#performance_schema_events_waits_history_long_size)
* [performance-schema-events-waits-history-size](../performance-schema-system-variables/index#performance_schema_events_waits_history_size)
* [performance-schema-hosts-size](../performance-schema-system-variables/index#performance_schema_hosts_size)
* [performance-schema-max-cond-classes](../performance-schema-system-variables/index#performance_schema_max_cond_classes)
* [performance-schema-max-cond-instances](../performance-schema-system-variables/index#performance_schema_max_cond_instances)
* [performance-schema-max-digest-length](../performance-schema-system-variables/index#performance_schema_max_digest_length)
* [performance-schema-max-file-classes](../performance-schema-system-variables/index#performance_schema_max_file_classes)
* [performance-schema-max-file-handles](../performance-schema-system-variables/index#performance_schema_max_file_handles)
* [performance-schema-max-file-instances](../performance-schema-system-variables/index#performance_schema_max_file_instances)
* [performance-schema-max-mutex-classes](../performance-schema-system-variables/index#performance_schema_max_mutex_classes)
* [performance-schema-max-mutex-instances](../performance-schema-system-variables/index#performance_schema_max_mutex_instances)
* [performance-schema-max-rwlock-classes](../performance-schema-system-variables/index#performance_schema_max_rwlock_classes)
* [performance-schema-max-rwlock-instances](../performance-schema-system-variables/index#performance_schema_max_rwlock_instances)
* [performance-schema-max-socket-classes](../performance-schema-system-variables/index#performance_schema_max_socket_classes)
* [performance-schema-max-socket-instances](../performance-schema-system-variables/index#performance_schema_max_socket_instances)
* [performance-schema-max-stage-classes](../performance-schema-system-variables/index#performance_schema_max_stage_classes)
* [performance-schema-max-statement-classes](../performance-schema-system-variables/index#performance_schema_max_statement_classes)
* [performance-schema-max-table-handles](../performance-schema-system-variables/index#performance_schema_max_table_handles)
* [performance-schema-max-table-instances](../performance-schema-system-variables/index#performance_schema_max_table_instances)
* [performance-schema-max-thread-classes](../performance-schema-system-variables/index#performance_schema_max_thread_classes)
* [performance-schema-max-thread-instances](../performance-schema-system-variables/index#performance_schema_max_thread_instances)
* [performance-schema-session-connect-attrs-size](../performance-schema-system-variables/index#performance_schema_session_connect_attrs_size)
* [performance-schema-setup-actors-size](../performance-schema-system-variables/index#performance_schema_setup_actors_size)
* [performance-schema-setup-objects-size](../performance-schema-system-variables/index#performance_schema_setup_objects_size)
* [performance-schema-users-size](../performance-schema-system-variables/index#performance_schema_users_size)

 Galera Cluster Options
----------------------

 The options related to [Galera Cluster](../galera/index) are described below. Options that are also system variables are listed after:

 #### `--wsrep-new-cluster`

 * **Commandline:** `--wsrep-new-cluster`
* **Description:** 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.

 

---

 ### Galera Cluster Options and System Variables

 Some options and system variables related to [Galera Cluster](../galera/index) can be found [here](../galera-cluster-system-variables/index). Direct links to many of them can be found below.

 * [wsrep-allowlist](../galera-cluster-system-variables/index#wsrep_allowlist)
* [wsrep-auto-increment-control](../galera-cluster-system-variables/index#wsrep_auto_increment_control)
* [wsrep-causal-reads](../galera-cluster-system-variables/index#wsrep_causal_reads)
* [wsrep-certify-nonPK](../galera-cluster-system-variables/index#wsrep_certify_nonpk)
* [wsrep-cluster-address](../galera-cluster-system-variables/index#wsrep_cluster_address)
* [wsrep-cluster-name](../galera-cluster-system-variables/index#wsrep_cluster_name)
* [wsrep-convert-LOCK-to-trx](../galera-cluster-system-variables/index#wsrep_convert_lock_to_trx)
* [wsrep-data-home-dir](../galera-cluster-system-variables/index#wsrep_data_home_dir)
* [wsrep-dbug-option](../galera-cluster-system-variables/index#wsrep_dbug_option)
* [wsrep-debug](../galera-cluster-system-variables/index#wsrep_debug)
* [wsrep-desync](../galera-cluster-system-variables/index#wsrep_desync)
* [wsrep-dirty-reads](../galera-cluster-system-variables/index#wsrep_dirty_reads)
* [wsrep-drupal-282555-workaround](../galera-cluster-system-variables/index#wsrep_drupal_282555_workaround)
* [wsrep-forced-binlog-format](../galera-cluster-system-variables/index#wsrep_forced_binlog_format)
* [wsrep-gtid-domain-id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)
* [wsrep-gtid-mode](../galera-cluster-system-variables/index#wsrep_gtid_mode)
* [wsrep-ignore-apply-errors](../galera-cluster-system-variables/index#wsrep_ignore_apply_errors)
* [wsrep-load-data-splitting](../galera-cluster-system-variables/index#wsrep_load_data_splitting)
* [wsrep-log-conflicts](../galera-cluster-system-variables/index#wsrep_log_conflicts)
* [wsrep-max-ws-rows](../galera-cluster-system-variables/index#wsrep_max_ws_rows)
* [wsrep-max-ws-size](../galera-cluster-system-variables/index#wsrep_max_ws_size)
* [wsrep-mode](../galera-cluster-system-variables/index#wsrep_mode)
* [wsrep-mysql-replication-bundle](../galera-cluster-system-variables/index#wsrep_mysql_replication_bundle)
* [wsrep-node-address](../galera-cluster-system-variables/index#wsrep_node_address)
* [wsrep-node-incoming-address](../galera-cluster-system-variables/index#wsrep_node_incoming_address)
* [wsrep-node-name](../galera-cluster-system-variables/index#wsrep_node_name)
* [wsrep-notify-cmd](../galera-cluster-system-variables/index#wsrep_notify_cmd)
* [wsrep-on](../galera-cluster-system-variables/index#wsrep_on)
* [wsrep-OSU-method](../galera-cluster-system-variables/index#wsrep_osu_method)
* [wsrep-provider](../galera-cluster-system-variables/index#wsrep_provider)
* [wsrep-provider-options](../galera-cluster-system-variables/index#wsrep_provider_options)
* [wsrep-recover](../galera-cluster-system-variables/index#wsrep_recover)
* [wsrep-reject\_queries](../galera-cluster-system-variables/index#wsrep_reject_queries)
* [wsrep-retry-autocommit](../galera-cluster-system-variables/index#wsrep_retry_autocommit)
* [wsrep-slave-FK-checks](../galera-cluster-system-variables/index#wsrep_slave_fk_checks)
* [wsrep-slave-threads](../galera-cluster-system-variables/index#wsrep_slave_threads)
* [wsrep-slave-UK-checks](../galera-cluster-system-variables/index#wsrep_slave_uk_checks)
* [wsrep-sr-store](../galera-cluster-system-variables/index#wsrep_sr_store)
* [wsrep-sst-auth](../galera-cluster-system-variables/index#wsrep_sst_auth)
* [wsrep-sst-donor](../galera-cluster-system-variables/index#wsrep_sst_donor)
* [wsrep-sst-donor-rejects-queries](../galera-cluster-system-variables/index#wsrep_sst_donor_rejects_queries)
* [wsrep-sst-method](../galera-cluster-system-variables/index#wsrep_sst_method)
* [wsrep-sst-receive-address](../galera-cluster-system-variables/index#wsrep_sst_receive_address)
* [wsrep-start-position](../galera-cluster-system-variables/index#wsrep_start_position)
* [wsrep-status-file](../galera-cluster-system-variables/index#wsrep_status_file)
* [wsrep-strict-ddl](../galera-cluster-system-variables/index#wsrep_strict_ddl)
* [wsrep-sync-wait](../galera-cluster-system-variables/index#wsrep_sync_wait)
* [wsrep-trx\_fragment\_size](../galera-cluster-system-variables/index#wsrep_trx_fragment_size)
* [wsrep-trx\_fragment\_unit](../galera-cluster-system-variables/index#wsrep_trx_fragment_unit)

 Options When Debugging mariadbd
-------------------------------

 #### `--debug-assert-if-crashed-table`

 * **Description:** Do an assert in handler::print\_error() if we get a crashed table.

 

---

 #### `--debug-binlog-fsync-sleep`

 * **Description:** `--debug-binlog-fsync-sleep=#`If not set to zero, sets the number of micro-seconds to sleep after running fsync() on the [binary log](../binary-log/index) to flush transactions to disk. This can thus be used to artificially increase the perceived cost of such an fsync().

 

---

 #### `--debug-crc-break`

 * **Description:** `--debug-crc-break=#`Call my\_debug\_put\_break\_here() if crc matches this number (for debug).

 

---

 #### `--debug-flush`

 * **Description:** Default debug log with flush after write.

 

---

 #### `--debug-no-sync`

 * **Description:** `debug-no-sync[=#]`Disables system sync calls. Only for running tests or debugging!

 

---

 #### `--debug-sync-timeout`

 * **Description:** `debug-sync-timeout[=#]`Enable the debug sync facility and optionally specify a default wait timeout in seconds. A zero value keeps the facility disabled.

 

---

 #### `--gdb`

 * **Description:** Set up signals usable for debugging.

 

---

 #### `--silent-startup`

 * **Description:** Don't print Notes to the [error log](../error-log/index) during startup.
* **Introduced:** [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/)

 

---

 #### `--sync-sys`

 * **Description:** Enable/disable system sync calls. Syncs should only be turned off (`--disable-sync-sys`) when running tests or debugging! Replaced by [debug-no-sync](#-debug-no-sync) from [MariaDB 5.5](../what-is-mariadb-55/index).
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `--thread-alarm`

 * **Description:** Enable/disable system thread alarm calls. Should only be turned off (`--disable-thread-alarm`) when running tests or debugging!

 

---

 ### Debugging Options and System Variables

 * [core-file](../server-system-variables/index#core_file)
* [debug](../server-system-variables/index#debug)
* [debug-no-thread-alarm](../server-system-variables/index#debug_no_thread_alarm)

 Other Options
-------------

 Options that are also system variables are listed after:

 #### `--allow-suspicious-udfs`

 * **Commandline:** `--allow-suspicious-udfs`
* **Description:** Allows use of [user-defined functions](../user-defined-functions/index) consisting of only one symbol `x()` without corresponding `x_init()` or `x_deinit()`. That also means that one can load any function from any library, for example `exit()` from `libc.so`. Not recommended unless you require old UDF's with one symbol that cannot be recompiled

 

---

 #### `--bootstrap`

 * **Commandline:** `--bootstrap`
* **Description:** Used by mariadb installation scripts, such as [mariadb-install-db](../mariadb-install-db/index) to execute SQL scripts before any privilege or system tables exist. Do no use while an existing MariaDB instance is running.

 

---

 #### `--chroot`

 * **Commandline:** `--chroot=name`
* **Description:** Chroot mariadbd daemon during startup.

 

---

 #### `--des-key-file`

 * **Commandline:** `--des-key-file=name`
* **Description:** Load keys for [des\_encrypt()](../des_encrypt/index) and des\_encrypt from given file.

 

---

 #### `--exit-info`

 * **Commandline:** `--exit-info[=#]`
* **Description:** Used for debugging. Use at your own risk.

 

---

 #### `--getopt-prefix-matching`

 * **Commandline:** `--getopt-prefix-matching={0|1}`
* **Description:** Makes it possible to disable historical "unambiguous prefix" matching in the command-line option parsing.
* **Default:** TRUE
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `--help`

 * **Commandline:** `--help`
* **Description:** Displays help with many commandline options described, and exits.

 

---

 #### `--log-ddl-recovery`

 * **Commandline:** `--log-ddl-recovery=name`
* **Description:** Path to file used for recovery of DDL statements after a crash.
* **Default Value:** `ddl-recover.log`
* **Introduced:** [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)

 #### `--log-short-format`

 * **Commandline:** `--log-short-format`
* **Description:** Don't log extra information to update and [slow-query](../slow-query-log/index) logs.

 

---

 #### `--log-slow-file`

 * **Commandline:** `--log-slow-file=name`
* **Description:** Log [slow queries](../slow-query-log/index) to given log file. Defaults logging to hostname-slow.log

 

---

 #### `--log-slow-time`

 * **Commandline:** `--log-slow-time=#`
* **Description:** Log all queries that have taken more than [long-query-time](../server-system-variables/index#long_query_time) seconds to execute to the slow query log, if active. The argument will be treated as a decimal value with microsecond precision.

 

---

 #### `--log-tc`

 * **Commandline:** `--log-tc=name`
* **Description:** Defines the path to the memory-mapped file-based transaction coordinator log, which is only used if the [binary log](../binary-log/index) is disabled. If you have two or more XA-capable storage engines enabled, then a transaction coordinator log must be available. See [Transaction Coordinator Log](../transaction-coordinator-log/index) for more information. Also see the the `[log\_tc\_size](../server-system-variables/index#log_tc_size)` system variable and the `[--tc-heuristic-recover](#-tc-heuristic-recover)` option.
* **Default Value:** `tc.log`

 

---

 #### `--master-connect-retry`

 * **Commandline:** `--master-connect-retry=#`
* **Description:** Deprecated in 5.1.17 and removed in 5.5. The number of seconds the replica thread will sleep before retrying to connect to the master, in case the master goes down or the connection is lost.

 

---

 #### `--memlock`

 * **Commandline:** `--memlock`
* **Description:** Lock mariadbd in memory.

 

---

 #### `--ndb-use-copying-alter-table`

 * **Commandline:** `--ndb-use-copying-alter-table`
* **Description:** Force ndbcluster to always copy tables at alter table (should only be used if on-line alter table fails).

 

---

 #### `--one-thread`

 * **Commandline:** `--one-thread`
* **Description:** (Deprecated): Only use one thread (for debugging under Linux). Use [thread-handling=no-threads](../thread-pool-system-and-status-variables/index#thread_handling) instead.
* **Removed:** [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/)

 

---

 #### `--plugin-load`

 * **Commandline:** `--plugin-load=name`
* **Description:** This option can be used to configure the server to load specific [plugins](../mariadb-plugins/index). This option uses the following format:
	+ Plugins can be specified in the format `name=library`, where `name` is the plugin name and `library` is the plugin library. This format installs a single plugin from the given plugin library.
	+ Plugins can also be specified in the format `library`, where `library` is the plugin library. This format installs all plugins from the given plugin library.
	+ Multiple plugins can be specified by separating them with semicolons.
* Special care must be taken when specifying the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option multiple times, or when specifying both the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option and the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option together. The `[--plugin-load](../mariadbd-options/index#-plugin-load)` option resets the plugin load list, and this can cause unexpected problems if you are not aware. The `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does **not** reset the plugin load list, so it is much safer to use. See [Plugin Overview: Specifying Multiple Plugin Load Options](../plugin-overview/index#specifying-multiple-plugin-load-options) for more information.
* See [Plugin Overview: Installing a Plugin with Plugin Load Options](../plugin-overview/index#installing-a-plugin-with-plugin-load-options) for more information.

 

---

 #### `--plugin-load-add`

 * **Commandline:** `--plugin-load-add=name`
* **Description:** This option can be used to configure the server to load specific [plugins](../mariadb-plugins/index). This option uses the following format:
	+ Plugins can be specified in the format `name=library`, where `name` is the plugin name and `library` is the plugin library. This format installs a single plugin from the given plugin library.
	+ Plugins can also be specified in the format `library`, where `library` is the plugin library. This format installs all plugins from the given plugin library.
	+ Multiple plugins can be specified by separating them with semicolons.
* Special care must be taken when specifying both the `[--plugin-load](../mariadbd-options/index#-plugin-load)` option and the `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option together. The `[--plugin-load](../mariadbd-options/index#-plugin-load)` option resets the plugin load list, and this can cause unexpected problems if you are not aware. The `[--plugin-load-add](../mariadbd-options/index#-plugin-load-add)` option does **not** reset the plugin load list, so it is much safer to use. See [Plugin Overview: Specifying Multiple Plugin Load Options](../plugin-overview/index#specifying-multiple-plugin-load-options) for more information.
* See [Plugin Overview: Installing a Plugin with Plugin Load Options](../plugin-overview/index#installing-a-plugin-with-plugin-load-options) for more information.
* **Introduced:** [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/)

 

---

 #### `--port-open-timeout`

 * **Commandline:** `--port-open-timeout=#`
* **Description:** Maximum time in seconds to wait for the port to become free. (Default: No wait).

 

---

 #### `--safe-user-create`

 * **Commandline:** `--safe-user-create`
* **Description:** Don't allow new user creation by the user who has no write privileges to the [mysql.user](../mysqluser-table/index) table.

 

---

 #### `--safemalloc-mem-limit`

 * **Commandline:** `--safemalloc-mem-limit=#`
* **Description:** Simulate memory shortage when compiled with the ``--`with-debug=full` option.

 

---

 #### `--show-slave-auth-info`

 * **Commandline:** `--show-slave-auth-info`
* **Description:** Show user and password in SHOW SLAVE HOSTS on this primary.

 

---

 #### `--skip-grant-tables`

 * **Commandline:** `--skip-grant-tables`
* **Description:** Start without grant tables. This gives all users FULL ACCESS to all tables, which is useful in case of a lost root password. Use [mariadb-admin flush-privileges](../mariadb-admin/index), [mariadb-admin reload](../mariadb-admin/index) or [FLUSH PRIVILEGES](../flush/index) to resume using the grant tables. From [MariaDB 10.10](../what-is-mariadb-1010/index), available as a [system variable](../server-system-variables/index#skip_grant_tables) as well.

 Because the [Event Scheduler](../event-scheduler/index) also depends on the grant tables for its functionality, it is automatically disabled when running with `--skip-grant-tables`.

 

---

 #### `--skip-host-cache`

 * **Commandline:** `--skip-host-cache`
* **Description:** Don't cache host names.

 

---

 #### `--skip-partition`

 * **Commandline:** `--skip-partition`, `--disable-partition`
* **Description:** Disables user-defined [partitioning](../managing-mariadb-partitioning/index). Previously partitioned tables cannot be accessed or modifed. Tables can still be seen with [SHOW TABLES](../show-tables/index) or by viewing the [INFORMATION\_SCHEMA.TABLES table](../information-schema-tables-table/index). Tables can be dropped with [DROP TABLE](../drop-table/index), but this only removes .frm files, not the associated .par files, which will need to be removed manually.

 

---

 #### `--skip-slave-start`

 * **Commandline:** `--skip-slave-start`
* **Description:** If set, replica is not autostarted.

 

---

 #### `--skip-ssl`

 * **Commandline:** `--skip-ssl`
* **Description:** Disable [TLS connections](../secure-connections-overview/index).

 

---

 #### `--skip-symlink`

 * **Commandline:** `--skip-symlink`
* **Description:** Don't allow symlinking of tables. Deprecated and removed in [MariaDB 5.5](../what-is-mariadb-55/index). Use [symbolic-links](#-symbolic-links) with the `skip` [option prefix](#option-prefixes) instead.
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `--skip-thread-priority`

 * **Commandline:** `--skip-thread-priority`
* **Description:** Don't give threads different priorities. Deprecated and removed in [MariaDB 10.0](../what-is-mariadb-100/index).
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `--sql-bin-update-same`

 * **Commandline:** `--sql-bin-update-same=#`
* **Description:** The update log was deprecated in version 5.0 and replaced by the [binary log](../binary-log/index), so this option did nothing since then. Deprecated and removed in [MariaDB 5.5](../what-is-mariadb-55/index).
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `--ssl`

 * **Commandline:** `--ssl`
* **Description:** Enable [TLS for connection](../secure-connections-overview/index) (automatically enabled with other flags). Disable with '``--`skip-ssl`'.

 

---

 #### `--stack-trace`

 * **Commandline:** `--stack-trace`, `--skip-stack-trace`
* **Description:** Print a stack trace on failure. Enabled by default, disable with `-skip-stack-trace`.

 

---

 #### `--symbolic-links`

 * **Commandline:** `--symbolic-links`
* **Description:** Enables symbolic link support. When set, the [have\_symlink](../server-system-variables/index#have_symlink) system variable shows as `YES`. Silently ignored in Windows. Use `--skip-symbolic-links` to disable.

 

---

 #### `--tc-heuristic-recover`

 * **Commandline:** `--tc-heuristic-recover=name`
* **Description:** If [manual heuristic recovery](../heuristic-recovery-with-the-transaction-coordinator-log/index) is needed, this option defines the decision to use in the heuristic recovery process. Manual heuristic recovery may be needed if the [transaction coordination log](../transaction-coordinator-log/index) is missing or if it doesn't contain all prepared transactions. This option can be set to `OFF`, `COMMIT`, or `ROLLBACK`. The default is `OFF`. See also the `[--log-tc](../mariadbd-options/index#-log-tc)` server option and the `[log\_tc\_size](../server-system-variables/index#log_tc_size)` system variable.

 

---

 #### `--temp-pool`

 * **Commandline:** `--temp-pool`
* **Description:** 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. Defaults to `1` until [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/), use `--skip-temp-pool` to disable. Deprecated and defaults to `0` from [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), as benchmarking shows it causes a heavy mutex contention.

 

---

 #### `--test-expect-abort`

 * **Commandline:** `--test-expect-abort`
* **Description:** Expect that server aborts with 'abort'; Don't write out server variables on 'abort'. Useful only for test scripts.

 

---

 #### `--test-ignore-wrong-options`

 * **Commandline:** `--test-ignore-wrong-options`
* **Description:** Ignore wrong enums values in command line arguments. Useful only for test scripts.

 

---

 #### `--user`

 * **Commandline:** `--user=name`
* **Description:** Run mariadbd daemon as user.

 

---

 #### `--verbose`

 * **Commandline:** `-v`, `--verbose`
* **Description:** Used with [help](#help) option for detailed help.

 

---

 Other Options and System Variables
----------------------------------

 * [allow-suspicious-udfs](../server-system-variables/index#allow-suspicious-udfs)
* [automatic-sp-privileges](../server-system-variables/index#automatic_sp_privileges)
* [back-log](../server-system-variables/index#back_log)
* [basedir](../server-system-variables/index#basedir)
* [check-constraint-checks](../server-system-variables/index#check_constraint_checks)
* [column-compression-threshold](../storage-engine-independent-column-compression/index#column_compression_threshold)
* [column-compression-zlib-level](../storage-engine-independent-column-compression/index#column_compression_zlib_level)
* [column-compression-zlib-strategy](../storage-engine-independent-column-compression/index#column_compression_zlib_strategy)
* [column-compression-zlib-wrap](../storage-engine-independent-column-compression/index#column_compression_zlib_wrap)
* [completion-type](../server-system-variables/index#completion_type)
* [connect-timeout](../server-system-variables/index#connect_timeout)
* [datadir](../server-system-variables/index#datadir)
* [date-format](../server-system-variables/index#date_format)
* [datetime-format](../server-system-variables/index#datetime_format)
* [deadlock-search-depth-long](../aria-server-system-variables/index#deadlock_search_depth_long)
* [deadlock-search-depth-short](../aria-server-system-variables/index#deadlock_search_depth_short)
* [deadlock-timeout-long](../aria-server-system-variables/index#deadlock_timeout_long)
* [deadlock-timeout-short](../aria-server-system-variables/index#deadlock_timeout_short)
* [default-password-lifetime](../server-system-variables/index#default_password_lifetime)
* [default-regex-flags](../server-system-variables/index#default_regex_flags)
* [default-storage-engine](../server-system-variables/index#default_storage_engine)
* [default-table-type](../server-system-variables/index#default_table_type)
* [delay-key-write](../server-system-variables/index#delay_key_write)
* [disconnect-on-expired-password](../server-system-variables/index#disconnect_on_expired_password)
* [div-precision-increment](../server-system-variables/index#div_precision_increment)
* [enable-named-pipe](../server-system-variables/index#named_pipe)
* [encrypt-binlog](../server-system-variables/index#encrypt_binlog)
* [encrypt-tmp-disk-tables](../server-system-variables/index#encrypt_tmp_disk_tables)
* [encrypt-tmp-files](../server-system-variables/index#encrypt_tmp_files)
* [encryption-algorithm](../server-system-variables/index#encryption_algorithm)
* [engine-condition-pushdown](../server-system-variables/index#engine_condition_pushdown)
* [eq-range-index-dive-limit](../server-system-variables/index#eq_range_index_dive_limit)
* [event-scheduler](../server-system-variables/index#event_scheduler)
* [expire-logs-days](../server-system-variables/index#expire_logs_days)
* [explicit-defaults-for-timestamp](../server-system-variables/index#explicit_defaults_for_timestamp)
* [extra-max-connections](../thread-pool-system-and-status-variables/index#extra_max_connections)
* [extra-port](../thread-pool-system-and-status-variables/index#extra_port)
* [flush](../server-system-variables/index#flush)
* [flush-time](../server-system-variables/index#flush_time)
* [ft-boolean-syntax](../server-system-variables/index#ft_boolean_syntax)
* [ft-max-word-len](../server-system-variables/index#ft_max_word_len)
* [ft-min-word-len](../server-system-variables/index#ft_min_word_len)
* [ft-query-expansion-limit](../server-system-variables/index#ft_query_expansion_limit)
* [ft-stopword-file](../server-system-variables/index#ft_stopword_file)
* [general-log](../server-system-variables/index#general_log)
* [general-log-file](../server-system-variables/index#general_log_file)
* [group-concat-max-len](../server-system-variables/index#group_concat_max_len)
* [histogram-size](../server-system-variables/index#histogram_size)
* [histogram-type](../server-system-variables/index#histogram_type)
* [host-cache-size](../server-system-variables/index#host_cache_size)
* [idle-readonly-transaction-timeout](../server-system-variables/index#idle_readonly_transaction_timeout)
* [idle-transaction-timeout](../server-system-variables/index#idle_transaction_timeout)
* [idle-write-transaction-timeout](../server-system-variables/index#idle_write_transaction_timeout)
* [ignore-db-dirs](../server-system-variables/index#ignore_db_dirs)
* [in-predicate-conversion-threshold](../server-system-variables/index#in_predicate_conversion_threshold)
* [init-connect](../server-system-variables/index#init_connect)
* [init-file](../server-system-variables/index#init_file)
* [interactive-timeout](../server-system-variables/index#interactive_timeout)
* [large-pages](../server-system-variables/index#large_pages)
* [local-infile](../server-system-variables/index#local_infile)
* [lock-wait-timeout](../server-system-variables/index#lock_wait_timeout)
* [log](../server-system-variables/index#log)
* [log-disabled-statements](../server-system-variables/index#log_disabled_statements)
* [log-error](../server-system-variables/index#log_error)
* [log-output](../server-system-variables/index#log_output)
* [log-queries-not-using-indexes](../server-system-variables/index#log_queries_not_using_indexes)
* [log-slow-admin-statements](../server-system-variables/index#log_slow_admin_statements)
* [log-slow-disabled-statements](../server-system-variables/index#log_slow_disabled_statements)
* [log-slow-filter](../server-system-variables/index#log_slow_filter)
* [log-slow-min-examined-row-limit](../server-system-variables/index#log_slow_min_examined_row_limit)
* [log-slow-queries](../server-system-variables/index#log_slow_queries)
* [log-slow-query](../server-system-variables/index#log_slow_query)
* [log-slow-query-file](../server-system-variables/index#log_slow_query_file)
* [log-slow-query-time](../server-system-variables/index#log_slow_query_time)
* [log-slow-rate-limit](../server-system-variables/index#log_slow_rate_limit)
* [log-slow-slave-statements](../replication-and-binary-log-system-variables/index#log_slow_slave_statements)
* [log-slow-verbosity](../server-system-variables/index#log_slow_verbosity)
* [log-tc-size](../server-system-variables/index#log_tc_size)
* [log-warnings](../server-system-variables/index#log_warnings)
* [long-query-time](../server-system-variables/index#long_query_time)
* [low-priority-updates](../server-system-variables/index#low_priority_updates)
* [lower-case-table-names](../server-system-variables/index#lower_case_table_names)
* [max-allowed-packet](../server-system-variables/index#max_allowed_packet)
* [max-connections](../server-system-variables/index#max_connections)
* [max-connect-errors](../server-system-variables/index#max_connect_errors)
* [max-delayed-threads](../server-system-variables/index#max_delayed_threads)
* [max-digest-length](../server-system-variables/index#max_digest_length%22)
* [max-error-count](../server-system-variables/index#max_error_count)
* [max-length-for-sort-data](../server-system-variables/index#max_length_for_sort_data)
* [max-long-data-size](../server-system-variables/index#max_long_data_size)
* [max-password-errors](../server-system-variables/index#max_password_errors)
* [max-prepared-stmt-count](../server-system-variables/index#max_prepared_stmt_count)
* [max-recursive-iterations](../server-system-variables/index#max_recursive_iterations)
* [max-rowid-filter-size](../server-system-variables/index#max_rowid_filter_size)
* [max-session-mem-used](../server-system-variables/index#max_session_mem_used)
* [max-sp-recursion-depth](../server-system-variables/index#max_sp_recursion_depth)
* [max-statement-time](../server-system-variables/index#max_statement_time)
* [max-tmp-tables](../server-system-variables/index#max_tmp_tables)
* [max-user-connections](../server-system-variables/index#max_user_connections)
* [max-write-lock-count](../server-system-variables/index#max_write_lock_count)
* [metadata-locks-cache-size](../server-system-variables/index#metadata_locks_cache_size)
* [metadata-locks-hash-instances](../server-system-variables/index#metadata_locks_hash_instances)
* [min-examined-row-limit](../server-system-variables/index#min_examined_row_limit)
* [mrr-buffer-size](../server-system-variables/index#mrr_buffer_size)
* [multi-range-count](../server-system-variables/index#multi_range_count)
* [--mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format)
* [net-buffer-length](../server-system-variables/index#net_buffer_length)
* [net-read-timeout](../server-system-variables/index#net_read_timeout)
* [net-retry-count](../server-system-variables/index#net_retry_count)
* [net-write-timeout](../server-system-variables/index#net_write_timeout)
* [open-files-limit](../server-system-variables/index#open_files_limit)
* [pid-file](../server-system-variables/index#pid_file)
* [plugin-dir](../server-system-variables/index#plugin_dir)
* [plugin-maturity](../server-system-variables/index#plugin_maturity)
* [port](../server-system-variables/index#port)
* [preload-buffer-size](../server-system-variables/index#preload_buffer_size)
* [profiling-history-size](../server-system-variables/index#profiling_history_size)
* [progress-report-time](../server-system-variables/index#progress_report_time)
* [proxy-protocol-networks](../server-system-variables/index#proxy_protocol_networks)
* [query-cache-limit](../server-system-variables/index#query_cache_limit)
* [query-cache-min-res-unit](../server-system-variables/index#query_cache_min_res_unit)
* [query-cache-strip-comments](../server-system-variables/index#query_cache_strip_comments)
* [query-cache-wlock-invalidate](../server-system-variables/index#query_cache_wlock_invalidate)
* [read-rnd-buffer-size](../server-system-variables/index#read_rnd_buffer_size)
* [read-only](../server-system-variables/index#read_only)
* [require-secure-transport](../server-system-variables/index#require_secure_transport)
* [safe-show-database](../server-system-variables/index#safe_show_database)
* [secure-auth](../server-system-variables/index#secure_auth)
* [secure-file-priv](../server-system-variables/index#secure_file_priv)
* [secure-timestamp](../server-system-variables/index#secure_timestamp)
* [session-track-schema](../server-system-variables/index#session_track_schema)
* [session-track-state-change](../server-system-variables/index#session_track_state_change)
* [session-track-system-variables](../server-system-variables/index#session_track_system_variables)
* [session-track-transaction-info](../server-system-variables/index#session_track_transaction_info)
* [skip-automatic-sp-privileges](../server-system-variables/index#automatic_sp_privileges)
* [skip-external-locking](../server-system-variables/index#skip_external_locking)
* [skip-large-pages](../server-system-variables/index#large_pages)
* [skip-log-error](../server-system-variables/index#log_error)
* [skip-name-resolve](../server-system-variables/index#skip_name_resolve)
* [skip-networking](../server-system-variables/index#skip_networking)
* [skip-show-database](../server-system-variables/index#skip_show_database)
* [slow-launch-time](../server-system-variables/index#slow_launch_time)
* [slow-query-log](../server-system-variables/index#slow_query_log)
* [slow-query-log-file](../server-system-variables/index#slow_query_log_file)
* [socket](../server-system-variables/index#socket)
* [sort-buffer-size](../server-system-variables/index#sort_buffer_size)
* [sql-if-exists](../server-system-variables/index#sql_if_exists)
* [sql-mode](../server-system-variables/index#sql_mode)
* [ssl-ca](../ssl-server-system-variables/index#ssl_ca)
* [ssl-capath](../ssl-server-system-variables/index#ssl_capath)
* [ssl-cert](../ssl-server-system-variables/index#ssl_cert)
* [ssl-cipher](../ssl-server-system-variables/index#ssl_cipher)
* [ssl-crl](../ssl-server-system-variables/index#ssl_crl)
* [ssl-crlpath](../ssl-server-system-variables/index#ssl_crlpath)
* [ssl-key](../ssl-server-system-variables/index#ssl_key)
* [standards\_compliant\_cte](../server-system-variables/index#standards_compliant_cte)
* [stored-program-cache](../server-system-variables/index#stored_program_cache)
* [strict\_password\_validation](../server-system-variables/index#strict_password_validation)
* [sync-frm](../server-system-variables/index#sync_frm)
* [system-versioning-alter-history](../system-versioned-tables/index#system_versioning_alter_history)
* [system-versioning-asof](../system-versioned-tables/index#system_versioning_asof)
* [system-versioning-innodb-algorithm-simple](../system-versioned-tables/index#system_versioning_innodb_algorithm_simple)
* [system-versioning-insert-history](../system-versioned-tables/index#system_versioning_insert_history)
* [table-lock-wait-timeout](../server-system-variables/index#table_lock_wait_timeout)
* [tcp-keepalive-interval](../server-system-variables/index#tcp_keepalive_interval)
* [tcp-keepalive-probes](../server-system-variables/index#tcp_keepalive_probes)
* [tcp-keepalive-time](../server-system-variables/index#tcp_keepalive_time)
* [tcp-nodelay](../server-system-variables/index#tcp_nodelay)
* [thread-cache-size](../server-system-variables/index#thread_cache_size)
* [thread-concurrency](../server-system-variables/index#thread_concurrency)
* [thread-handling](../server-system-variables/index#thread_handling)
* [thread-pool-dedicated-listener](../thread-pool-system-and-status-variables/index#thread_pool_dedicated_listener)
* [thread-pool-exact-stats](../thread-pool-system-and-status-variables/index#thread_pool_exact_stats)
* [thread-pool-idle-timeout](../thread-pool-system-and-status-variables/index#thread_pool_idle_timeout)
* [thread-pool-max-threads](../thread-pool-system-and-status-variables/index#thread_pool_max_threads)
* [thread-pool-min-threads](../thread-pool-system-and-status-variables/index#thread_pool_min_threads)
* [thread-pool-oversubscribe](../thread-pool-system-and-status-variables/index#thread_pool_oversubscribe)
* [thread-pool-prio-kickup-timer](../thread-pool-system-and-status-variables/index#thread_pool_prio_kickup_timer)
* [thread-pool-priority](../thread-pool-system-and-status-variables/index#thread_pool_priority)
* [thread-pool-size](../thread-pool-system-and-status-variables/index#thread_pool_size)
* [thread-pool-stall-limit](../thread-pool-system-and-status-variables/index#thread_pool_stall_limit)
* [thread-stack](../server-system-variables/index#thread_stack)
* [timed-mutexes](../server-system-variables/index#timed_mutexes)
* [time-format](../server-system-variables/index#time_format)
* [tls-version](../ssl-server-system-variables/index#tls_version)
* [tmpdir](../server-system-variables/index#tmpdir)
* [transaction-isolation](../server-system-variables/index#tx_isolation)
* [transaction-alloc-block-size](../server-system-variables/index#transaction_alloc_block_size)
* [transaction-prealloc-size](../server-system-variables/index#transaction_prealloc_size)
* [transaction-read-only](../server-system-variables/index#tx_read_only)
* [updatable-views-with-limit](../server-system-variables/index#updatable_views_with_limit)
* [userstat](../server-system-variables/index#userstat)
* [version](../server-system-variables/index#version)
* [wait-timeout](../server-system-variables/index#wait_timeout)

 Authentication Plugins - Options and System Variables
-----------------------------------------------------

 ### Authentication Plugin - `ed25519`

 The options related to the `[ed25519](../authentication-plugin-ed25519/index)` authentication plugin can be found [here](../authentication-plugin-ed25519/index#options).

 ### Authentication Plugin - `gssapi`

 The system variables related to the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin can be found [here](../authentication-plugin-gssapi/index#system-variables).

 The options related to the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin can be found [here](../authentication-plugin-gssapi/index#options).

 ### Authentication Plugin - `named_pipe`

 The options related to the `[named\_pipe](../authentication-plugin-named-pipe/index)` authentication plugin can be found [here](../authentication-plugin-named-pipe/index#options).

 ### Authentication Plugin - `pam`

 The system variables related to the `[pam](../authentication-plugin-pam/index)` authentication plugin can be found [here](../authentication-plugin-pam/index#system-variables).

 The options related to the `[pam](../authentication-plugin-pam/index)` authentication plugin can be found [here](../authentication-plugin-pam/index#options).

 ### Authentication Plugin - `unix_socket`

 The options related to the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin can be found [here](../authentication-plugin-unix-socket/index#options).

 Encryption Plugins - Options and System Variables
-------------------------------------------------

 ### Encryption Plugin - `aws_key_management`

 The system variables related to the `[aws\_key\_management](../aws-key-management-encryption-plugin/index)` encryption plugin can be found [here](../aws-key-management-encryption-plugin/index#system-variables).

 The options elated to the `[aws\_key\_management](../aws-key-management-encryption-plugin/index)` encryption plugin can be found [here](../aws-key-management-encryption-plugin/index#options).

 ### Encryption Plugin - `file_key_management`

 The system variables related to the `[file\_key\_management](../file-key-management-encryption-plugin/index)` encryption plugin can be found [here](../file-key-management-encryption-plugin/index#system-variables).

 The options related to the `[file\_key\_management](../file-key-management-encryption-plugin/index)` encryption plugin can be found [here](../file-key-management-encryption-plugin/index#options).

 Password Validation Plugins - Options and System Variables
----------------------------------------------------------

 ### Password Validation Plugin - `simple_password_check`

 The system variables related to the `[simple\_password\_check](../simple_password_check/index)` password validation plugin can be found [here](../simple_password_check/index#system-variables).

 The options related to the `[simple\_password\_check](../simple_password_check/index)` password validation plugin can be found [here](../simple_password_check/index#options).

 ### Password Validation Plugin - `cracklib_password_check`

 The system variables related to the `[cracklib\_password\_check](../cracklib_password_check/index)` password validation plugin can be found [here](../cracklib_password_check/index#system-variables).

 The options related to the `[cracklib\_password\_check](../cracklib_password_check/index)` password validation plugin can be found [here](../cracklib_password_check/index#options).

 Audit Plugins - Options and System Variables
--------------------------------------------

 ### Audit Plugin - `server_audit`

 Options and system variables related to the `[server\_audit](../mariadb-audit-plugin/index)` audit plugin can be found [here](../server_audit-system-variables/index).

 ### Audit Plugin - `SQL_ERROR_LOG`

 The system variables related to the `[SQL\_ERROR\_LOG](../sql-error-log-plugin/index)` audit plugin can be found [here](../sql-error-log-plugin/index#system-variables).

 The options related to the `[SQL\_ERROR\_LOG](../sql-error-log-plugin/index)` audit plugin can be found [here](../sql-error-log-plugin/index#options).

 ### Audit Plugin - QUERY\_RESPONSE\_TIME\_AUDIT

 The options related to the `[QUERY\_RESPONSE\_TIME\_AUDIT](../query-response-time-plugin/index)` audit plugin can be found [here](../query-response-time-plugin/index#options).

 Daemon Plugins - Options and System Variables
---------------------------------------------

 ### Daemon Plugin - `handlersocket`

 The options for the HandlerSocket plugin are all described on the [HandlerSocket Configuration Option](../handlersocket-configuration-options/index) page.

 Information Schema Plugins - Options and System Variables
---------------------------------------------------------

 ### Information Schema Plugin - `DISKS`

 The options related to the `[DISKS](../disks-plugin/index)` information schema plugin can be found [here](../disks-plugin/index#options).

 ### Information Schema Plugin - `feedback`

 The system variables related to the `[feedback](../feedback-plugin/index)` plugin can be found [here](../feedback-plugin/index#system-variables).

 The options related to the `[feedback](../feedback-plugin/index)` plugin can be found [here](../feedback-plugin/index#options).

 ### Information Schema Plugin - `LOCALES`

 The options related to the `[LOCALES](../locales-plugin/index)` information schema plugin can be found [here](../locales-plugin/index#options).

 ### Information Schema Plugin - `METADATA_LOCK_INFO`

 The options related to the `[METADATA\_LOCK\_INFO](../metadata_lock_info/index)` information schema plugin can be found [here](../metadata_lock_info/index#options).

 ### Information Schema Plugin - `QUERY_CACHE_INFO`

 The options related to the `[QUERY\_CACHE\_INFO](../query-cache-information-plugin/index)` information schema plugin can be found [here](../query-cache-information-plugin/index#options).

 ### Information Schema Plugin - `QUERY_RESPONSE_TIME`

 The system variables related to the `[QUERY\_RESPONSE\_TIME](../query-response-time-plugin/index)` information schema plugin can be found [here](../query-response-time-plugin/index#system-variables).

 The options related to the `[QUERY\_RESPONSE\_TIME](../query-response-time-plugin/index)` information schema plugin can be found [here](../query-response-time-plugin/index#options).

 ### Information Schema Plugin - `user_variables`

 The options related to the `[user\_variables](../user-variables-plugin/index)` information schema plugin can be found [here](../user-variables-plugin/index#options).

 ### Information Schema Plugin - `WSREP_MEMBERSHIP`

 The options related to the `[WSREP\_MEMBERSHIP](../wsrep_info-plugin/index)` information schema plugin can be found [here](../wsrep_info-plugin/index#options).

 ### Information Schema Plugin - `WSREP_STATUS`

 The options related to the `[WSREP\_STATUS](../wsrep_info-plugin/index)` information schema plugin can be found [here](../wsrep_info-plugin/index#options).

 Replication Plugins - Options and System Variables
--------------------------------------------------

 ### Replication Plugin - `rpl_semi_sync_master`

 The system variables related to the `[rpl\_semi\_sync\_master](../semisynchronous-replication/index)` replication plugin can be found [here](../semisynchronous-replication/index#system-variables).

 The options related to the `[rpl\_semi\_sync\_master](../semisynchronous-replication/index)` replication plugin can be found [here](../semisynchronous-replication/index#options).

 ### Replication Plugin - `rpl_semi_sync_slave`

 The system variables related to the `[rpl\_semi\_sync\_slave](../semisynchronous-replication/index)` replication plugin can be found [here](../semisynchronous-replication/index#system-variables).

 The options related to the `[rpl\_semi\_sync\_slave](../semisynchronous-replication/index)` replication plugin can be found [here](../semisynchronous-replication/index#options).

 Default Values
--------------

 You can verify the default values for an option by doing:

 
```
mariadbd --no-defaults --help --verbose

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqld-options/>

Partitioning Types Overview
===========================

    A partitioning type determines how a partitioned table's rows are distributed across partitions. Some partition types require the user to specify a partitioning expression that determines in which partition a row will be stored.

 The size of individual partitions depends on the partitioning type. Read and write performance are affected by the partitioning expression. Therefore, these choices should be made carefully.

 MariaDB supports the following partitioning types:

 * [RANGE](../range-partitioning-type/index)
* [LIST](../list-partitioning/index)
* [RANGE COLUMNS and LIST COLUMNS](../range-columns-and-list-columns-partitioning-types/index), HASH COLUMNS
* [HASH](../hash-partitioning-type/index)
* [KEY](../key-partitioning-type/index)
* LINEAR HASH, LINEAR KEY
* [SYSTEM\_TIME](../system-versioned-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partitioning-types-overview/>

LIST Partitioning Type
======================

    LIST partitioning is conceptually similar to [RANGE partitioning](../range-partitioning-type/index). In both cases you decide a partitioning expression (a column, or a slightly more complex calculation) and use it to determine which partitions will contain each row. However, with the RANGE type, partitioning is done by assigning a range of values to each partition. With the LIST type, we assign a set of values to each partition. This is usually preferred if the partitioning expression can return a limited set of values.

 A variant of this partitioning method, [LIST COLUMNS](../range-columns-and-list-columns-partitioning-types/index), allows us to use multiple columns and more datatypes.

 Syntax
------

 The last part of a [CREATE TABLE](../create-table/index) statement can be the definition of the new table's partitions. In the case of LIST partitioning, the syntax is the following:

 
```
PARTITION BY LIST (partitioning_expression)
(
	PARTITION partition_name VALUES IN (value_list),
	[ PARTITION partition_name VALUES IN (value_list), ... ]
        [ PARTITION partition_name DEFAULT ]
)

```

PARTITION BY LIST indicates that the partitioning type is LIST.

 The `partitioning_expression` is an SQL expression that returns a value from each row. In the simplest cases, it is a column name. This value is used to determine which partition should contain a row.

 `partition_name` is the name of a partition.

 `value_list` is a list of values. If `partitioning_expression` returns one of these values, the row will be stored in this partition. If we try to insert something that does not belong to any of these value lists, the row will be rejected with an error.

 The `DEFAULT` partition catches all records which do not fit into other partitions. Only one `DEFAULT` partition is permitted. This option was added in [MariaDB 10.2](../what-is-mariadb-102/index).

 Use cases
---------

 LIST partitioning can be useful when we have a column that can only contain a limited set of values. Even in that case, RANGE partitioning could be used instead; but LIST partitioning allows us to equally distribute the rows by assigning a proper set of values to each partition.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/list-partitioning-type/>

NULL Values
===========

     NULL represents an unknown value. It is *not* an empty string (by default), or a zero value. These are all valid values, and are not NULLs.

 When a table is [created](../create-table/index) or the format [altered](../alter-table/index), columns can be specified as accepting NULL values, or not accepting them, with the `NULL` and `NOT NULL` clauses respectively.

 For example, a customer table could contain dates of birth. For some customers, this information is unknown, so the value could be NULL.

 The same system could allocate a customer ID for each customer record, and in this case a NULL value would not be permitted.

 
```
CREATE TABLE customer (
 id INT NOT NULL, 
 date_of_birth DATE NULL
...
)

```

[User-defined variables](../user-defined-variables/index) are NULL until a value is explicitly assigned.

 [Stored routines](../stored-programs-and-views/index) parameters and [local variables](../declare-variable/index) can always be set to NULL. If no DEFAULT value is specified for a local variable, its initial value will be NULL. If no value is assigned to an OUT parameter in a stored procedure, NULL is assigned at the end of the procedure.

 Syntax
------

 The case of `NULL` is not relevant. `\N` (uppercase) is an alias for `NULL`.

 The `[IS](../is/index)` operator accepts `UNKNOWN` as an alias for `NULL`, which is meant for [boolean contexts](../sql-language-structure-boolean-literals/index).

 Comparison Operators
--------------------

 NULL values cannot be used with most [comparison operators](../comparison-operators/index). For example, [=](../equal/index), [>](../greater-than/index), [>=](../greater-than-or-equal/index), [<=](../less-than-or-equal/index), [<](../less-than/index), or [!=](../not-equal/index) cannot be used, as any comparison with a NULL always returns a NULL value, never true (1) or false (0). 

 
```
SELECT NULL = NULL;
+-------------+
| NULL = NULL |
+-------------+
|        NULL |
+-------------+

SELECT 99 = NULL;
+-----------+
| 99 = NULL |
+-----------+
|      NULL |
+-----------+

```

To overcome this, certain operators are specifically designed for use with NULL values. To cater for testing equality between two values that may contain NULLs, there's [<=>](../null-safe-equal/index), NULL-safe equal.

 
```
SELECT 99 <=> NULL, NULL <=> NULL;
+-------------+---------------+
| 99 <=> NULL | NULL <=> NULL |
+-------------+---------------+
|           0 |             1 |
+-------------+---------------+

```

Other operators for working with NULLs include [IS NULL](../is-null/index) and [IS NOT NULL](../is-not-null/index), [ISNULL](../isnull/index) (for testing an expression) and [COALESCE](../coalesce/index) (for returning the first non-NULL parameter).

 Ordering
--------

 When you order by a field that may contain NULL values, any NULLs are considered to have the lowest value. So ordering in DESC order will see the NULLs appearing last. To force NULLs to be regarded as highest values, one can add another column which has a higher value when the main field is NULL. Example:

 
```
SELECT col1 FROM tab ORDER BY ISNULL(col1), col1;

```

Descending order, with NULLs first:

 
```
SELECT col1 FROM tab ORDER BY IF(col1 IS NULL, 0, 1), col1 DESC;

```

All NULL values are also regarded as equivalent for the purposes of the DISTINCT and GROUP BY clauses.

 Functions
---------

 In most cases, functions will return NULL if any of the parameters are NULL. There are also functions specifically for handling NULLs. These include [IFNULL()](../ifnull/index), [NULLIF()](../nullif/index) and [COALESCE()](../coalesce/index).

 
```
SELECT IFNULL(1,0); 
+-------------+
| IFNULL(1,0) |
+-------------+
|           1 |
+-------------+

SELECT IFNULL(NULL,10);
+-----------------+
| IFNULL(NULL,10) |
+-----------------+
|              10 |
+-----------------+

SELECT COALESCE(NULL,NULL,1);
+-----------------------+
| COALESCE(NULL,NULL,1) |
+-----------------------+
|                     1 |
+-----------------------+

```

Aggregate functions, such as [SUM](../sum/index) and [AVG](../avg/index) ignore NULLs.

 
```
CREATE TABLE t(x INT);

INSERT INTO t VALUES (1),(9),(NULL);

SELECT SUM(x) FROM t;
+--------+
| SUM(x) |
+--------+
|     10 |
+--------+

SELECT AVG(x) FROM t;
+--------+
| AVG(x) |
+--------+
| 5.0000 |
+--------+

```

The one exception is [COUNT(\*)](../count/index), which counts rows, and doesn't look at whether a value is NULL or not. Compare for example, COUNT(x), which ignores the NULL, and COUNT(\*), which counts it:

 
```
SELECT COUNT(x) FROM t;
+----------+
| COUNT(x) |
+----------+
|        2 |
+----------+

SELECT COUNT(*) FROM t;
+----------+
| COUNT(*) |
+----------+
|        3 |
+----------+

```

AUTO\_INCREMENT, TIMESTAMP and Virtual Columns
----------------------------------------------

 MariaDB handles NULL values in a special way if the field is an [AUTO\_INCREMENT](../auto_increment/index), a [TIMESTAMP](../timestamp/index) or a [virtual column](../virtual-columns/index). Inserting a NULL value into a numeric AUTO\_INCREMENT column will result in the next number in the auto increment sequence being inserted instead. This technique is frequently used with AUTO\_INCREMENT fields, which are left to take care of themselves.

 
```
CREATE TABLE t2(id INT PRIMARY KEY AUTO_INCREMENT, letter CHAR(1));

INSERT INTO t2(letter) VALUES ('a'),('b');

SELECT * FROM t2;
+----+--------+
| id | letter |
+----+--------+
|  1 | a      |
|  2 | b      |
+----+--------+

```

Similarly, if a NULL value is assigned to a TIMESTAMP field, the current date and time is assigned instead.

 
```
CREATE TABLE t3 (x INT, ts TIMESTAMP);

INSERT INTO t3(x) VALUES (1),(2);

```

After a pause,

 
```
INSERT INTO t3(x) VALUES (3);

SELECT* FROM t3;
+------+---------------------+
| x    | ts                  |
+------+---------------------+
|    1 | 2013-09-05 10:14:18 |
|    2 | 2013-09-05 10:14:18 |
|    3 | 2013-09-05 10:14:29 |
+------+---------------------+

```

If a `NULL` is assigned to a `VIRTUAL` or `PERSISTENT` column, the default value is assigned instead.

 
```
CREATE TABLE virt (c INT, v INT AS (c+10) PERSISTENT) ENGINE=InnoDB;

INSERT INTO virt VALUES (1, NULL);

SELECT c, v FROM virt;
+------+------+
| c    | v    |
+------+------+
|    1 |   11 |
+------+------+

```

In all these special cases, `NULL` is equivalent to the `DEFAULT` keyword.

 Inserting
---------

 If a NULL value is single-row inserted into a column declared as NOT NULL, an error will be returned. However, if the [SQL mode](../sql_mode/index) is not [strict](../sql-mode/index#strict-mode) (default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)), if a NULL value is multi-row inserted into a column declared as NOT NULL, the implicit default for the column type will be inserted (and NOT the default value in the table definition). The implicit defaults are an empty string for string types, and the zero value for numeric, date and time types.

 Since [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), by default both cases will result in an error.

 ### Examples

 
```
CREATE TABLE nulltest (
  a INT(11), 
  x VARCHAR(10) NOT NULL DEFAULT 'a', 
  y INT(11) NOT NULL DEFAULT 23
);

```

Single-row insert:

 
```
INSERT INTO nulltest (a,x,y) VALUES (1,NULL,NULL);
ERROR 1048 (23000): Column 'x' cannot be null

```

Multi-row insert with [SQL mode](../sql_mode/index) not [strict](../sql-mode/index#strict-mode) (default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)):

 
```
show variables like 'sql_mode%';
+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+

INSERT INTO nulltest (a,x,y) VALUES (1,NULL,NULL),(2,NULL,NULL); 
Query OK, 2 rows affected, 4 warnings (0.08 sec)
Records: 2  Duplicates: 0  Warnings: 4

```

The specified defaults have not been used; rather, the implicit column type defaults have been inserted

 
```
SELECT * FROM nulltest;
+------+---+---+
| a    | x | y |
+------+---+---+
|    1 |   | 0 |
|    2 |   | 0 |
+------+---+---+

```

Primary Keys and UNIQUE Indexes
-------------------------------

 UNIQUE indexes can contain multiple NULL values.

 Primary keys are never nullable.

   


 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**Oracle Compatibility
--------------------

 In [Oracle mode](../sql_modeoracle-from-mariadb-103/index#null-handling), NULL can be used as a statement:

 
```
IF a=10 THEN NULL; ELSE NULL; END IF

```

In [Oracle mode](../sql_modeoracle-from-mariadb-103/index#null-handling), [CONCAT](../concat/index) and the [Logical OR operator ||](../or/index) ignore [NULL](null).

 When setting [sql\_mode=EMPTY\_STRING\_IS\_NULL](../sql-mode/index), empty strings and NULLs are the same thing. For example:

 
```
SET sql_mode=EMPTY_STRING_IS_NULL;
SELECT '' IS NULL; -- returns TRUE
INSERT INTO t1 VALUES (''); -- inserts NULL

```


See Also
--------

 * [Primary Keys with Nullable Columns](../primary-keys-with-nullable-columns/index)
* [IS NULL operator](../is-null/index)
* [IS NOT NULL operator](../is-not-null/index)
* [ISNULL function](../isnull/index)
* [COALESCE function](../coalesce/index)
* [IFNULL function](../ifnull/index)
* [NULLIF function](../nullif/index)
* [CONNECT data types](../connect-data-types/index#null-handling)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/null-values/>

RANGE Partitioning Type
=======================

     The RANGE partitioning type is used to assign each partition a range of values generated by the partitioning expression. Ranges must be ordered, contiguous and non-overlapping. The minimum value is always included in the first range. The highest value may or may not be included in the last range.

 A variant of this partitioning method, [RANGE COLUMNS](../range-columns-and-list-columns-partitioning-types/index), allows us to use multiple columns and more datatypes.

 Syntax
------

 The last part of a [CREATE TABLE](../create-table/index) statement can be definition of the new table's partitions. In the case of RANGE partitioning, the syntax is the following:

 
```
PARTITION BY RANGE (partitioning_expression)
(
	PARTITION partition_name VALUES LESS THAN (value),
	[ PARTITION partition_name VALUES LESS THAN (value), ... ]
)

```

PARTITION BY RANGE indicates that the partitioning type is RANGE.

 The `partitioning_expression` is an SQL expression that returns a value from each row. In the simplest cases, it is a column name. This value is used to determine which partition should contain a row.

 `partition_name` is the name of a partition.

 `value` indicates the upper bound for that partition. The values must be ascending. For the first partition, the lower limit is NULL. When trying to insert a row, if its value is higher than the upper limit of the last partition, the row will be rejected (with an error, if the [IGNORE](../ignore/index) keyword is not used).

 If this is a problem, MAXVALUE can be specified as a value for the last partition. Note however that it is not possible to split partitions of an existing RANGE partitioned table. New partitions can be appended, but this will not be possible if the last partition's higher bound is MAXVALUE.

 Use Cases
---------

 A typical use case is when we want to partition a table whose rows refer to a moment or period in time; for example commercial transactions, blog posts, or events of some kind. We can partition the table by year, to keep all recent data in one partition and distribute historical data in big partitions that are stored on slower disks. Or, if our queries always read rows which refer to the same month or week, we can partition the table by month or year week (in this case, historical data and recent data will be stored together).

 [AUTO\_INCREMENT](../auto_increment/index) values also represent a chronological order. So, these values can be used to store old data in separate partitions. However, partitioning by id is not the best choice if we usually query a table by date.

 Examples
--------

 In the following example, we will partition a log table by year.

 
```
CREATE TABLE log
(
	id INT UNSIGNED NOT NULL AUTO_INCREMENT,
	timestamp DATETIME NOT NULL,
	user INT UNSIGNED,
	ip BINARY(16) NOT NULL,
	action VARCHAR(20) NOT NULL,
	PRIMARY KEY (id, timestamp)
)
	ENGINE = InnoDB
PARTITION BY RANGE (YEAR(timestamp))
(
	PARTITION p0 VALUES LESS THAN (2013),
	PARTITION p1 VALUES LESS THAN (2014),
	PARTITION p2 VALUES LESS THAN (2015),
	PARTITION p3 VALUES LESS THAN (2016)
);

```

As an alternative, we can partition the table by both year and month:

 
```
CREATE TABLE log
(
	id INT UNSIGNED NOT NULL AUTO_INCREMENT,
	timestamp TIMESTAMP NOT NULL,
	user INT UNSIGNED,
	ip BINARY(16) NOT NULL,
	action VARCHAR(20) NOT NULL,
	PRIMARY KEY (id, timestamp)
)
	ENGINE = InnoDB
PARTITION BY RANGE (UNIX_TIMESTAMP(timestamp))
(
	PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2014-08-01 00:00:00')),
	PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2014-11-01 00:00:00')),
	PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2015-01-01 00:00:00')),
	PARTITION p3 VALUES LESS THAN (UNIX_TIMESTAMP('2015-02-01 00:00:00'))
);

```

As you can see, we used the [UNIX\_TIMESTAMP](../unix_timestamp/index) function to accomplish the purpose. Also, the first two partitions cover longer periods of time (probably because the logged activities were less intensive).

 In both cases, when our tables become huge and we don't need to store all historical data any more, we can drop the oldest partitions in this way:

 
```
 ALTER TABLE log DROP PARTITION p0;

```


We will still be able to drop a partition that does not contain the oldest data, but all rows stored in it will disappear.

 
Example of an error when inserting outside a defined partition range:

 
```
INSERT INTO log(id,timestamp) VALUES 
  (1, '2016-01-01 01:01:01'), 
  (2, '2015-01-01 01:01:01');
ERROR 1526 (HY000): Table has no partition for value 2016

```

Unless the IGNORE keyword is used:

 
```
INSERT IGNORE INTO log(id,timestamp) VALUES 
  (1, '2016-01-01 01:01:01'), 
  (2, '2015-01-01 01:01:01');

SELECT * FROM log;
+----+---------------------+------+------------------+--------+
| id | timestamp           | user | ip               | action |
+----+---------------------+------+------------------+--------+
|  2 | 2015-01-01 01:01:01 | NULL |                  |        |
+----+---------------------+------+------------------+--------+

```

An alternative definition with MAXVALUE as a catchall:

 
```
CREATE TABLE log
(
	id INT UNSIGNED NOT NULL AUTO_INCREMENT,
	timestamp DATETIME NOT NULL,
	user INT UNSIGNED,
	ip BINARY(16) NOT NULL,
	action VARCHAR(20) NOT NULL,
	PRIMARY KEY (id, timestamp)
)
	ENGINE = InnoDB
PARTITION BY RANGE (YEAR(timestamp))
(
	PARTITION p0 VALUES LESS THAN (2013),
	PARTITION p1 VALUES LESS THAN (2014),
	PARTITION p2 VALUES LESS THAN (2015),
	PARTITION p3 VALUES LESS THAN (2016),
	PARTITION p4 VALUES LESS THAN MAXVALUE
);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/range-partitioning-type/>

HASH Partitioning Type
======================

    ### Syntax

 
```
PARTITION BY HASH (partitioning_expression)
[PARTITIONS(number_of_partitions)]

```

### Description

 HASH partitioning is a form of [partitioning](../partitioning-tables/index) in which the server takes care of the partition in which to place the data, ensuring an even distribution among the partitions.

 It requires a column value, or an expression based on a column value, which is hashed, as well as the number of partitions into which to divide the table.

 *partitioning\_expression* needs to return a non-constant, deterministic integer. It is evaluated for each insert and update, so overly complex expressions can lead to performance issues.

 *number\_of\_partitions* is a positive integer specifying the number of partitions into which to divide the table. If the `PARTITIONS` clause is omitted, the default number of partitions is one.

 ### Examples

 
```
CREATE OR REPLACE TABLE t1 (c1 INT, c2 DATETIME) 
  PARTITION BY HASH(TO_DAYS(c2)) 
  PARTITIONS 5;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hash-partitioning-type/>

EXPLAIN
=======

    Syntax
------

 
```
EXPLAIN tbl_name [col_name | wild]

```

Or

 
```
EXPLAIN [EXTENDED | PARTITIONS | FORMAT=JSON] 
  {SELECT select_options | UPDATE update_options | DELETE delete_options}

```
 Description
-----------

 The `EXPLAIN` statement can be used either as a synonym for [DESCRIBE](../describe/index) or as a way to obtain information about how MariaDB executes a `SELECT`, `UPDATE` or `DELETE` statement:

 * `'EXPLAIN tbl_name'` is synonymous with `'[DESCRIBE](../describe/index) tbl_name'` or `'[SHOW COLUMNS](../show-columns/index) FROM tbl_name'`.
* When you precede a `SELECT`, `UPDATE` or a `DELETE` statement with the keyword `EXPLAIN`, MariaDB displays information from the optimizer about the query execution plan. That is, MariaDB explains how it would process the `SELECT`, `UPDATE` or `DELETE`, including information about how tables are joined and in which order. `EXPLAIN EXTENDED` can be used to provide additional information.
* `EXPLAIN PARTITIONS` is useful only when examining queries involving partitioned tables.  
 For details, see [Partition pruning and selection](../partition-pruning-and-selection/index).
* [ANALYZE statement](../analyze-statement/index) performs the query as well as producing EXPLAIN output, and provides actual as well as estimated statistics.
* `EXPLAIN` output can be printed in the [slow query log](../slow-query-log/index). See [EXPLAIN in the Slow Query Log](../explain-in-the-slow-query-log/index) for details.

 [SHOW EXPLAIN](../show-explain/index) shows the output of a running statement. In some cases, its output can be closer to reality than `EXPLAIN`.

 The [ANALYZE statement](../analyze-statement/index) runs a statement and returns information about its execution plan. It also shows additional columns, to check how much the optimizer's estimation about filtering and found rows are close to reality.

 There is an online [EXPLAIN Analyzer](../explain-analyzer/index) that you can use to share `EXPLAIN` and `EXPLAIN EXTENDED` output with others.

 
`EXPLAIN` can acquire metadata locks in the same way that `SELECT` does, as it needs to know table metadata and, sometimes, data as well.

 
### Columns in EXPLAIN ... SELECT

 


| Column name | Description |
| --- | --- |
| `id` | Sequence number that shows in which order tables are joined. |
| `select_type` | What kind of `SELECT` the table comes from. |
| `table` | Alias name of table. Materialized temporary tables for sub queries are named <subquery#> |
| `type` | How rows are found from the table (join type). |
| `possible_keys` | keys in table that could be used to find rows in the table |
| `key` | The name of the key that is used to retrieve rows. `NULL` is no key was used. |
| `key_len` | How many bytes of the key that was used (shows if we are using only parts of the multi-column key). |
| `ref` | The reference that is used as the key value. |
| `rows` | An estimate of how many rows we will find in the table for each key lookup. |
| `Extra` | Extra information about this join. |

 
Here are descriptions of the values for some of the more complex columns in `EXPLAIN ... SELECT`:

 #### "Select\_type" Column

 The `select_type` column can have the following values:

 


| Value | Description | Comment |
| --- | --- | --- |
| `DEPENDENT SUBQUERY` | The `SUBQUERY` is `DEPENDENT`. |  |
| `DEPENDENT UNION` | The `UNION` is `DEPENDENT`. |  |
| `DERIVED` | The `SELECT` is `DERIVED` from the `PRIMARY`. |  |
| `MATERIALIZED` | The `SUBQUERY` is `[MATERIALIZED](../semi-join-materialization-strategy/index)`. | Materialized tables will be populated at first access and will be accessed by the primary key (= one key lookup). Number of rows in EXPLAIN shows the cost of populating the table |
| `PRIMARY` | The `SELECT` is in the outermost query, but there is also a `SUBQUERY` within it. |  |
| `SIMPLE` | It is a simple `SELECT` query without any `SUBQUERY` or `UNION`. |  |
| `SUBQUERY` | The `SELECT` is a `SUBQUERY` of the `PRIMARY`. |  |
| `UNCACHEABLE SUBQUERY` | The `SUBQUERY` is `UNCACHEABLE`. |  |
| `UNCACHEABLE UNION` | The `UNION` is `UNCACHEABLE`. |  |
| `UNION` | The `SELECT` is a `UNION` of the `PRIMARY`. |  |
| `UNION RESULT` | The result of the `UNION`. |  |
| `LATERAL DERIVED` | The `SELECT` uses a [Lateral Derived optimization](../lateral-derived-optimization/index) |  |

 
#### "Type" Column

 This column contains information on how the table is accessed.

 


| Value | Description |
| --- | --- |
| `ALL` | A full table scan is done for the table (all rows are read). This is bad if the table is large and the table is joined against a previous table! This happens when the optimizer could not find any usable index to access rows. |
| `const` | There is only one possibly matching row in the table. The row is read before the optimization phase and all columns in the table are treated as constants. |
| `eq_ref` | A unique index is used to find the rows. This is the best possible plan to find the row. |
| `fulltext` | A fulltext index is used to access the rows. |
| `index_merge` | A 'range' access is done for for several index and the found rows are merged. The key column shows which keys are used. |
| `index_subquery` | This is similar as ref, but used for sub queries that are transformed to key lookups. |
| `index` | A full scan over the used index. Better than ALL but still bad if index is large and the table is joined against a previous table. |
| `range` | The table will be accessed with a key over one or more value ranges. |
| `ref_or_null` | Like 'ref' but in addition another search for the 'null' value is done if the first value was not found. This happens usually with sub queries. |
| `ref` | A non unique index or prefix of an unique index is used to find the rows. Good if the prefix doesn't match many rows. |
| `system` | The table has 0 or 1 rows. |
| `unique_subquery` | This is similar as eq\_ref, but used for sub queries that are transformed to key lookups |

 
#### "Extra" Column

 This column consists of one or more of the following values, separated by ';'

  *Note that some of these values are detected after the optimization phase.*

 The optimization phase can do the following changes to the `WHERE` clause:

 * Add the expressions from the `ON` and `USING` clauses to the `WHERE` clause.
* Constant propagation: If there is `column=constant`, replace all column instances with this constant.
* Replace all columns from '`const`' tables with their values.
* Remove the used key columns from the `WHERE` (as this will be tested as part of the key lookup).
* Remove impossible constant sub expressions. For example `WHERE '(a=1 and a=2) OR b=1'` becomes `'b=1'`.
* Replace columns with other columns that has identical values: Example: `WHERE` `a=b` and `a=c` may be treated as `'WHERE a=b and a=c and b=c'`.
* Add extra conditions to detect impossible row conditions earlier. This happens mainly with `OUTER JOIN` where we in some cases add detection of `NULL` values in the `WHERE` (Part of '`Not exists`' optimization). This can cause an unexpected '`Using where`' in the Extra column.
* For each table level we remove expressions that have already been tested when we read the previous row. Example: When joining tables `t1` with `t2` using the following `WHERE 't1.a=1 and t1.a=t2.b'`, we don't have to test `'t1.a=1'` when checking rows in `t2` as we already know that this expression is true.

 


| Value | Description |
| --- | --- |
| `const row not found` | The table was a system table (a table with should exactly one row), but no row was found. |
| `Distinct` | If distinct optimization (remove duplicates) was used. This is marked only for the last table in the `SELECT`. |
| `Full scan on NULL key` | The table is a part of the sub query and if the value that is used to match the sub query will be `NULL`, we will do a full table scan. |
| `Impossible HAVING` | The used `HAVING` clause is always false so the `SELECT` will return no rows. |
| `Impossible WHERE` `noticed` `after` `reading` `const` `tables.` | The used `WHERE` clause is always false so the `SELECT` will return no rows. This case was detected after we had read all 'const' tables and used the column values as constant in the `WHERE` clause. For example: `WHERE const_column=5` and `const_column` had a value of 4. |
| `Impossible WHERE` | The used `WHERE` clause is always false so the `SELECT` will return no rows. For example: `WHERE 1=2` |
| `No matching min/max row` | During early optimization of `MIN()`/`MAX()` values it was detected that no row could match the `WHERE` clause. The `MIN()`/`MAX()` function will return `NULL`. |
| `no matching row` `in` `const` `table` | The table was a const table (a table with only one possible matching row), but no row was found. |
| `No tables used` | The `SELECT` was a sub query that did not use any tables. For example a there was no `FROM` clause or a `FROM DUAL` clause. |
| `Not exists` | Stop searching after more row if we find one single matching row. This optimization is used with `LEFT JOIN` where one is explicitly searching for rows that doesn't exists in the `LEFT JOIN TABLE`. Example: `SELECT * FROM t1 LEFT JOIN t2 on (...) WHERE t2.not_null_column IS NULL`. As `t2.not_null_column` can only be `NULL` if there was no matching row for on condition, we can stop searching if we find a single matching row. |
| `Open_frm_only` | For `information_schema` tables. Only the `frm` (table definition file was opened) was opened for each matching row. |
| `Open_full_table` | For `information_schema` tables. A full table open for each matching row is done to retrieve the requested information. (Slow) |
| `Open_trigger_only` | For `information_schema` tables. Only the trigger file definition was opened for each matching row. |
| `Range checked` `for` `each` `record` `(index map: ...)` | This only happens when there was no good default index to use but there may some index that could be used when we can treat all columns from previous table as constants. For each row combination the optimizer will decide which index to use (if any) to fetch a row from this table. This is not fast, but faster than a full table scan that is the only other choice. The index map is a bitmask that shows which index are considered for each row condition. |
| `Scanned 0/1/all databases` | For `information_schema` tables. Shows how many times we had to do a directory scan. |
| `Select tables` `optimized` `away` | All tables in the join was optimized away. This happens when we are only using `COUNT(*)`, `MIN()` and `MAX()` functions in the `SELECT` and we where able to replace all of these with constants. |
| `Skip_open_table` | For `information_schema` tables. The queried table didn't need to be opened. |
| `unique row not found` | The table was detected to be a const table (a table with only one possible matching row) during the early optimization phase, but no row was found. |
| `Using filesort` | Filesort is needed to resolve the query. This means an extra phase where we first collect all columns to sort, sort them with a disk based merge sort and then use the sorted set to retrieve the rows in sorted order. If the column set is small, we store all the columns in the sort file to not have to go to the database to retrieve them again. |
| `Using index` | Only the index is used to retrieve the needed information from the table. There is no need to perform an extra seek to retrieve the actual record. |
| `Using index condition` | Like '`Using where`' but the where condition is pushed down to the table engine for internal optimization at the index level. |
| `Using index condition(BKA)` | Like '`Using index condition`' but in addition we use batch key access to retrieve rows. |
| `Using index for group-by` | The index is being used to resolve a `GROUP BY` or `DISTINCT` query. The rows are not read. This is very efficient if the table has a lot of identical index entries as duplicates are quickly jumped over. |
| `Using intersect(...)` | For `index_merge` joins. Shows which index are part of the intersect. |
| `Using join buffer` | We store previous row combinations in a row buffer to be able to match each row against all of the rows combinations in the join buffer at one go. |
| `Using sort_union(...)` | For `index_merge` joins. Shows which index are part of the union. |
| `Using temporary` | A temporary table is created to hold the result. This typically happens if you are using `GROUP BY`, `DISTINCT` or `ORDER BY`. |
| `Using where` | A `WHERE` expression (in additional to the possible key lookup) is used to check if the row should be accepted. If you don't have 'Using where' together with a join type of `ALL`, you are probably doing something wrong! |
| `Using where` `with` `pushed` `condition` | Like '`Using where`' but the where condition is pushed down to the table engine for internal optimization at the row level. |
| `Using buffer` | The `UPDATE` statement will first buffer the rows, and then run the updates, rather than do updates on the fly. See [Using Buffer UPDATE Algorithm](../using-buffer-update-algorithm/index) for a detailed explanation. |

 
### EXPLAIN EXTENDED

 The `EXTENDED` keyword adds another column, *filtered*, to the output. This is a percentage estimate of the table rows that will be filtered by the condition.

 An `EXPLAIN EXTENDED` will always throw a warning, as it adds extra *Message* information to a subsequent `[SHOW WARNINGS](../show-warnings/index)` statement. This includes what the `SELECT` query would look like after optimizing and rewriting rules are applied and how the optimizer qualifies columns and tables.

 Examples
--------

 As synonym for `DESCRIBE` or `SHOW COLUMNS FROM`:

 
```
DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | YES  |     | NULL    |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

```

A simple set of examples to see how `EXPLAIN` can identify poor index usage:

 
```
CREATE TABLE IF NOT EXISTS `employees_example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(30) NOT NULL,
  `last_name` varchar(40) NOT NULL,
  `position` varchar(25) NOT NULL,
  `home_address` varchar(50) NOT NULL,
  `home_phone` varchar(12) NOT NULL,
  `employee_code` varchar(25) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `employee_code` (`employee_code`),
  KEY `first_name` (`first_name`,`last_name`)
) ENGINE=Aria;

INSERT INTO `employees_example` (`first_name`, `last_name`, `position`, `home_address`, `home_phone`, `employee_code`)
  VALUES
  ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza', '326-555-3492', 'MM1'),
  ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847', 'HF1'),
  ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456', 'BM1'),
  ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349', 'LC1'),
  ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329', 'FC1'),
  ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478', 'HW1');

SHOW INDEXES FROM employees_example;
+-------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table             | Non_unique | Key_name      | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| employees_example |          0 | PRIMARY       |            1 | id            | A         |           7 |     NULL | NULL   |      | BTREE      |         |               |
| employees_example |          0 | employee_code |            1 | employee_code | A         |           7 |     NULL | NULL   |      | BTREE      |         |               |
| employees_example |          1 | first_name    |            1 | first_name    | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
| employees_example |          1 | first_name    |            2 | last_name     | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
+-------------------+------------+---------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

```

`SELECT` on a primary key:

 
```
EXPLAIN SELECT * FROM employees_example WHERE id=1;
+------+-------------+-------------------+-------+---------------+---------+---------+-------+------+-------+
| id   | select_type | table             | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+------+-------------+-------------------+-------+---------------+---------+---------+-------+------+-------+
|    1 | SIMPLE      | employees_example | const | PRIMARY       | PRIMARY | 4       | const |    1 |       |
+------+-------------+-------------------+-------+---------------+---------+---------+-------+------+-------+

```

The type is *const*, which means that only one possible result could be returned. Now, returning the same record but searching by their phone number:

 
```
EXPLAIN SELECT * FROM employees_example WHERE home_phone='326-555-3492';
+------+-------------+-------------------+------+---------------+------+---------+------+------+-------------+
| id   | select_type | table             | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------------------+------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | employees_example | ALL  | NULL          | NULL | NULL    | NULL |    6 | Using where |
+------+-------------+-------------------+------+---------------+------+---------+------+------+-------------+

```

Here, the type is *All*, which means no index could be used. Looking at the rows count, a full table scan (all six rows) had to be performed in order to retrieve the record. If it's a requirement to search by phone number, an index will have to be created.

 [SHOW EXPLAIN](../show-explain/index) example:

 
```
SHOW EXPLAIN FOR 1;
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | tbl   | index | NULL          | a    | 5       | NULL | 1000107 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
1 row in set, 1 warning (0.00 sec)

```

### Example of `ref_or_null` Optimization

 
```
SELECT * FROM table_name
  WHERE key_column=expr OR key_column IS NULL;

```

`ref_or_null` is something that often happens when you use subqueries with `NOT IN` as then one has to do an extra check for `NULL` values if the first value didn't have a matching row. 

 See Also
--------

 * [SHOW EXPLAIN](../show-explain/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain/>

SELECT
======

    Syntax
------

 
```
SELECT
    [ALL | DISTINCT | DISTINCTROW]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [ FROM table_references
      [WHERE where_condition]
      [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]
      [HAVING where_condition]
      [ORDER BY {col_name | expr | position} [ASC | DESC], ...]
      [LIMIT {[offset,] row_count | row_count OFFSET offset  [ROWS EXAMINED rows_limit] } |
        [OFFSET start { ROW | ROWS }]
        [FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }] ]
      procedure|[PROCEDURE procedure_name(argument_list)]
      [INTO OUTFILE 'file_name' [CHARACTER SET charset_name] [export_options] |
        INTO DUMPFILE 'file_name' | INTO var_name [, var_name] ]
      [FOR UPDATE lock_option | LOCK IN SHARE MODE lock_option]
export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
lock_option:
    [WAIT n | NOWAIT | SKIP LOCKED]
```
 Description
-----------

 `SELECT` is used to retrieve rows selected from one or more tables, and can include [UNION](../union/index) statements and [subqueries](../subqueries/index).

 * Each *select\_expr* expression indicates a column or data that you want to retrieve. You must have at least one select expression. See [Select Expressions](#select-expressions) below.

 * The `FROM` clause indicates the table or tables from which to retrieve rows. Use either a single table name or a `JOIN` expression. See [JOIN](../join/index) for details. If no table is involved, [FROM DUAL](../dual/index) can be specified.

 * Each table can also be specified as `db_name`.`tabl_name`. Each column can also be specified as `tbl_name`.`col_name` or even `db_name`.`tbl_name`.`col_name`. This allows one to write queries which involve multiple databases. See [Identifier Qualifiers](../identifier-qualifiers/index) for syntax details.

 * The `WHERE` clause, if given, indicates the condition or conditions that rows must satisfy to be selected. `where_condition` is an expression that evaluates to true for each row to be selected. The statement selects all rows if there is no WHERE clause.
	+ In the `WHERE` clause, you can use any of the functions and operators that MariaDB supports, except for aggregate (summary) functions. See [Functions and Operators](../functions-and-operators/index) and [Functions and Modifiers for use with GROUP BY](../functions-and-modifiers-for-use-with-group-by/index) (aggregate).

 * Use the [ORDER BY](../order-by/index) clause to order the results.

 * Use the [LIMIT](../limit/index) clause allows you to restrict the results to only a certain number of rows, optionally with an offset.

 * Use the [GROUP BY](../group-by/index) and `HAVING` clauses to group rows together when they have columns or computed values in common.

 SELECT can also be used to retrieve rows computed without reference to any table.

 ### Select Expressions

 A `SELECT` statement must contain one or more select expressions, separated by commas. Each select expression can be one of the following:

 * The name of a column.
* Any expression using [functions and operators](../functions-and-operators/index).
* `*` to select all columns from all tables in the `FROM` clause.
* `tbl_name.*` to select all columns from just the table *tbl\_name*.

 When specifying a column, you can either use just the column name or qualify the column name with the name of the table using `tbl_name.col_name`. The qualified form is useful if you are joining multiple tables in the `FROM` clause. If you do not qualify the column names when selecting from multiple tables, MariaDB will try to find the column in each table. It is an error if that column name exists in multiple tables.

 You can quote column names using backticks. If you are qualifying column names with table names, quote each part separately as ``tbl_name`.`col_name``.

 If you use any [grouping functions](../functions-and-modifiers-for-use-with-group-by/index) in any of the select expressions, all rows in your results will be implicitly grouped, as if you had used `GROUP BY NULL`.

 ### DISTINCT

 A query may produce some identical rows. By default, all rows are retrieved, even when their values are the same. To explicitly specify that you want to retrieve identical rows, use the `ALL` option. If you want duplicates to be removed from the resultset, use the `DISTINCT` option. `DISTINCTROW` is a synonym for `DISTINCT`. See also [COUNT DISTINCT](../count-distinct/index) and [SELECT UNIQUE in Oracle mode](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility).

 ### INTO

 The `INTO` clause is used to specify that the query results should be written to a file or variable.

 * [SELECT INTO OUTFILE](../select-into-outfile/index) - formatting and writing the result to an external file.
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index) - binary-safe writing of the unformatted results to an external file.
* [SELECT INTO Variable](../select-into-variable/index) - selecting and setting variables.

 The reverse of `SELECT INTO OUTFILE` is [LOAD DATA](../load-data-into-tables-or-index/index).

 ### LIMIT

 Restricts the number of returned rows. See [LIMIT](../limit/index) and [LIMIT ROWS EXAMINED](../limit-rows-examined/index) for details.

 ### LOCK IN SHARE MODE/FOR UPDATE

 See [LOCK IN SHARE MODE](../lock-in-share-mode/index) and [FOR UPDATE](../for-update/index) for details on the respective locking clauses.

 ### OFFSET ... FETCH

 
**MariaDB starting with [10.6](../what-is-mariadb-106/index)**See [SELECT ... OFFSET ... FETCH](../select-offset-fetch/index).

 
### ORDER BY

 Order a resultset. See [ORDER BY](../order-by/index) for details.

 ### PARTITION

 Specifies to the optimizer which partitions are relevant for the query. Other partitions will not be read. See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 ### PROCEDURE

 Passes the whole result set to a C Procedure. See [PROCEDURE](../procedure/index) and [PROCEDURE ANALYSE](../procedure-analyse/index) (the only built-in procedure not requiring the server to be recompiled).

 ### SKIP LOCKED

 
**MariaDB starting with [10.6](../what-is-mariadb-106/index)**The SKIP LOCKED clause was introduced in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).

 This causes those rows that couldn't be locked ([LOCK IN SHARE MODE](../lock-in-share-mode/index) or [FOR UPDATE](../for-update/index)) to be excluded from the result set. An explicit `NOWAIT` is implied here. This is only implemented on [InnoDB](../innodb/index) tables and ignored otherwise.

 
### SQL\_CALC\_FOUND\_ROWS

 When `SQL_CALC_FOUND_ROWS` is used, then MariaDB will calculate how many rows would have been in the result, if there would be no [LIMIT](../limit/index) clause. The result can be found by calling the function [FOUND\_ROWS()](../found_rows/index) in your next sql statement.

   


 ### max\_statement\_time clause

 By using [max\_statement\_time](../server-system-variables/index#max_statement_time) in conjunction with [SET STATEMENT](../set-statement/index), it is possible to limit the execution time of individual queries. For example:

 
```
SET STATEMENT max_statement_time=100 FOR 
  SELECT field1 FROM table_name ORDER BY field1;

```

### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 Examples
--------

 
```
SELECT f1,f2 FROM t1 WHERE (f3<=10) AND (f4='y');

```

See [Getting Data from MariaDB](../getting-data-from-mariadb/index) (Beginner tutorial), or the various sub-articles, for more examples.

 See Also
--------

 * [Getting Data from MariaDB](../getting-data-from-mariadb/index) (Beginner tutorial)
* [Joins and Subqueries](../joins-subqueries/index)
* [LIMIT](../limit/index)
* [ORDER BY](../order-by/index)
* [GROUP BY](../group-by/index)
* [Common Table Expressions](../common-table-expressions/index)
* [SELECT WITH ROLLUP](../select-with-rollup/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* [FOR UPDATE](../for-update/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [Optimizer Hints](../optimizer-hints/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select/>

INSERT
======

    Syntax
------

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
 [ ON DUPLICATE KEY UPDATE
   col=expr
     [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)]
    SET col={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```
 The `INSERT` statement is used to insert new rows into an existing table. The `INSERT ... VALUES` and `INSERT ... SET` forms of the statement insert rows based on explicitly specified values. The `INSERT ... SELECT` form inserts rows selected from another table or tables. `INSERT ... SELECT` is discussed further in the `[INSERT ... SELECT](../insert-select/index)` article.

 The table name can be specified in the form `db_name`.`tbl_name` or, if a default database is selected, in the form `tbl_name` (see [Identifier Qualifiers](../identifier-qualifiers/index)). This allows to use [INSERT ... SELECT](../insert-select/index) to copy rows between different databases.

 The PARTITION clause can be used in both the INSERT and the SELECT part. See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The RETURNING clause was introduced in [MariaDB 10.5](../what-is-mariadb-105/index).

 
The columns list is optional. It specifies which values are explicitly inserted, and in which order. If this clause is not specified, all values must be explicitly specified, in the same order they are listed in the table definition.

 The list of value follow the `VALUES` or `VALUE` keyword (which are interchangeable, regardless how much values you want to insert), and is wrapped by parenthesis. The values must be listed in the same order as the columns list. It is possible to specify more than one list to insert more than one rows with a single statement. If many rows are inserted, this is a speed optimization.

 For one-row statements, the `SET` clause may be more simple, because you don't need to remember the columns order. All values are specified in the form `col` = `expr`.

 Values can also be specified in the form of a SQL expression or subquery. However, the subquery cannot access the same table that is named in the `INTO` clause.

 If you use the `LOW_PRIORITY` keyword, execution of the `INSERT` is delayed until no other clients are reading from the table. If you use the `HIGH_PRIORITY` keyword, the statement has the same priority as `SELECT`s. This affects only storage engines that use only table-level locking (MyISAM, MEMORY, MERGE). However, if one of these keywords is specified, [concurrent inserts](../concurrent-inserts/index) cannot be used. See [HIGH\_PRIORITY and LOW\_PRIORITY clauses](../high_priority-and-low_priority-clauses/index) for details.

 INSERT DELAYED
--------------

 For more details on the `DELAYED` option, see [INSERT DELAYED](../insert-delayed/index).

 HIGH PRIORITY and LOW PRIORITY
------------------------------

 See [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index).

 Defaults and Duplicate Values
-----------------------------

 See [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index) for details..

 INSERT IGNORE
-------------

 See [INSERT IGNORE](../insert-ignore/index).

 INSERT ON DUPLICATE KEY UPDATE
------------------------------

 See [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index).

 Examples
--------

 Specifying the column names:

 
```
INSERT INTO person (first_name, last_name) VALUES ('John', 'Doe');

```

Inserting more than 1 row at a time:

 
```
INSERT INTO tbl_name VALUES (1, "row 1"), (2, "row 2");

```

Using the `SET` clause:

 
```
INSERT INTO person SET first_name = 'John', last_name = 'Doe';

```

SELECTing from another table:

 
```
INSERT INTO contractor SELECT * FROM person WHERE status = 'c';

```

See [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) and [INSERT IGNORE](../insert-ignore/index) for further examples.

 INSERT ... RETURNING
--------------------

 
`INSERT ... RETURNING` returns a resultset of the inserted rows.

 This returns the listed columns for all the rows that are inserted, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.

 
### Examples

 Simple INSERT statement

 
```
INSERT INTO t2 VALUES (1,'Dog'),(2,'Lion'),(3,'Tiger'),(4,'Leopard') 
RETURNING id2,id2+id2,id2&id2,id2||id2;
+-----+---------+---------+----------+
| id2 | id2+id2 | id2&id2 | id2||id2 |
+-----+---------+---------+----------+
|   1 |       2 |       1 |        1 |
|   2 |       4 |       2 |        1 |
|   3 |       6 |       3 |        1 |
|   4 |       8 |       4 |        1 |
+-----+---------+---------+----------+

```

Using stored functions in RETURNING

 
```
DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
    BEGIN
       RETURN (SELECT arg+arg);
    END|

DELIMITER ;

PREPARE stmt FROM "INSERT INTO t1 SET id1=1, animal1='Bear' RETURNING f(id1), UPPER(animal1)";

EXECUTE stmt;
+---------+----------------+
| f(id1)  | UPPER(animal1) |
+---------+----------------+
|       2 | BEAR           |
+---------+----------------+

```

Subqueries in the RETURNING clause that return more than one row or column cannot be used.

 Aggregate functions cannot be used in the RETURNING clause. Since aggregate functions work on a set of values, and if the purpose is to get the row count, ROW\_COUNT() with SELECT can be used or it can be used in INSERT...SELECT...RETURNING if the table in the RETURNING clause is not the same as the INSERT table.

 See Also
--------

 * [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [REPLACE](../replace/index) Equivalent to DELETE + INSERT of conflicting row.
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)
* [How to quickly insert data into MariaDB](../how-to-quickly-insert-data-into-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert/>

UPDATE
======

    Syntax
------

 Single-table syntax:

 
```
UPDATE [LOW_PRIORITY] [IGNORE] table_reference 
  [PARTITION (partition_list)]
  [FOR PORTION OF period FROM expr1 TO expr2]
  SET col1={expr1|DEFAULT} [,col2={expr2|DEFAULT}] ...
  [WHERE where_condition]
  [ORDER BY ...]
  [LIMIT row_count]

```

Multiple-table syntax:

 
```
UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET col1={expr1|DEFAULT} [, col2={expr2|DEFAULT}] ...
    [WHERE where_condition]

```
 Description
-----------

 For the single-table syntax, the `UPDATE` statement updates columns of existing rows in the named table with new values. The `SET` clause indicates which columns to modify and the values they should be given. Each value can be given as an expression, or the keyword `DEFAULT` to set a column explicitly to its default value. The `WHERE` clause, if given, specifies the conditions that identify which rows to update. With no `WHERE` clause, all rows are updated. If the [ORDER BY](../order-by/index) clause is specified, the rows are updated in the order that is specified. The [LIMIT](../limit/index) clause places a limit on the number of rows that can be updated.

 Until [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), for the multiple-table syntax, `UPDATE` updates rows in each table named in table\_references that satisfy the conditions. In this case, [ORDER BY](../order-by/index) and [LIMIT](../limit/index) cannot be used. This restriction was lifted in [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) and both clauses can be used with multiple-table updates. An `UPDATE` can also reference tables which are located in different databases; see [Identifier Qualifiers](../identifier-qualifiers/index) for the syntax.

 `where_condition` is an expression that evaluates to true for each row to be updated.

 `table_references` and `where_condition` are as specified as described in [SELECT](../select/index).

 For single-table updates, assignments are evaluated in left-to-right order, while for multi-table updates, there is no guarantee of a particular order. If the `SIMULTANEOUS_ASSIGNMENT` [sql\_mode](../sql-mode/index) (available from [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)) is set, UPDATE statements evaluate all assignments simultaneously.

 You need the `UPDATE` privilege only for columns referenced in an `UPDATE` that are actually updated. You need only the [SELECT](../select/index) privilege for any columns that are read but not modified. See [GRANT](../grant/index).

 The `UPDATE` statement supports the following modifiers:

 * If you use the `LOW_PRIORITY` keyword, execution of the `UPDATE` is delayed until no other clients are reading from the table. This affects only storage engines that use only table-level locking (MyISAM, MEMORY, MERGE). See [HIGH\_PRIORITY and LOW\_PRIORITY clauses](../high_priority-and-low_priority-clauses/index) for details.
* If you use the `IGNORE` keyword, the update statement does not abort even if errors occur during the update. Rows for which duplicate-key conflicts occur are not updated. Rows for which columns are updated to values that would cause data conversion errors are updated to the closest valid values instead.

 ### PARTITION

 See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 ### FOR PORTION OF

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**See [Application Time Periods - Updating by Portion](../application-time-periods/index#updating-by-portion).

 
### UPDATE Statements With the Same Source and Target

 
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**From [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), UPDATE statements may have the same source and target.

 
For example, given the following table:

 
```
DROP TABLE t1;
CREATE TABLE t1 (c1 INT, c2 INT);
INSERT INTO t1 VALUES (10,10), (20,20);

```

Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), the following UPDATE statement would not work:

 
```
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);
ERROR 1093 (HY000): Table 't1' is specified twice, 
  both as a target for 'UPDATE' and as a separate source for data

```

From [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), the statement executes successfully:

 
```
UPDATE t1 SET c1=c1+1 WHERE c2=(SELECT MAX(c2) FROM t1);

SELECT * FROM t1;
+------+------+
| c1   | c2   |
+------+------+
|   10 |   10 |
|   21 |   20 |
+------+------+

```

Example
-------

 Single-table syntax:

 
```
UPDATE table_name SET column1 = value1, column2 = value2 WHERE id=100;

```

Multiple-table syntax:

 
```
UPDATE tab1, tab2 SET tab1.column1 = value1, tab1.column2 = value2 WHERE tab1.id = tab2.id;

```

See Also
--------

 * [How IGNORE works](../ignore/index)
* [SELECT](../select/index)
* [ORDER BY](../order-by/index)
* [LIMIT](../limit/index)
* [Identifier Qualifiers](../identifier-qualifiers/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/update/>

DELETE
======

    Syntax
------

 Single-table syntax:

 
```
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] 
  FROM tbl_name [PARTITION (partition_list)]
  [FOR PORTION OF period FROM expr1 TO expr2]
  [WHERE where_condition]
  [ORDER BY ...]
  [LIMIT row_count]
  [RETURNING select_expr 
    [, select_expr ...]]

```

Multiple-table syntax:

 
```
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

```

Or:

 
```
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

```

Trimming history:

 
```
DELETE HISTORY
  FROM tbl_name [PARTITION (partition_list)]
  [BEFORE SYSTEM_TIME [TIMESTAMP|TRANSACTION] expression]

```

Description
-----------

 


| Option | Description |
| --- | --- |
| LOW\_PRIORITY | Wait until all SELECT's are done before starting the statement. Used with storage engines that uses table locking (MyISAM, Aria etc). See [HIGH\_PRIORITY and LOW\_PRIORITY clauses](../high_priority-and-low_priority-clauses/index) for details. |
| QUICK | Signal the storage engine that it should expect that a lot of rows are deleted. The storage engine engine can do things to speed up the DELETE like ignoring merging of data blocks until all rows are deleted from the block (instead of when a block is half full). This speeds up things at the expanse of lost space in data blocks. At least [MyISAM](../myisam/index) and [Aria](../aria/index) support this feature. |
| IGNORE | Don't stop the query even if a not-critical error occurs (like data overflow). See [How IGNORE works](../ignore/index) for a full description. |

 
For the single-table syntax, the `DELETE` statement deletes rows from tbl\_name and returns a count of the number of deleted rows. This count can be obtained by calling the [ROW\_COUNT()](../row-count/index) function. The `WHERE` clause, if given, specifies the conditions that identify which rows to delete. With no `WHERE` clause, all rows are deleted. If the [ORDER BY](../order-by/index) clause is specified, the rows are deleted in the order that is specified. The [LIMIT](../limit/index) clause places a limit on the number of rows that can be deleted.

 For the multiple-table syntax, `DELETE` deletes from each `tbl_name` the rows that satisfy the conditions. In this case, [ORDER BY](../order-by/index) and [LIMIT](../limit/index)> cannot be used. A `DELETE` can also reference tables which are located in different databases; see [Identifier Qualifiers](../identifier-qualifiers/index) for the syntax.

 `where_condition` is an expression that evaluates to true for each row to be deleted. It is specified as described in [SELECT](../select/index).

 Currently, you cannot delete from a table and select from the same table in a subquery.

 You need the `DELETE` privilege on a table to delete rows from it. You need only the `SELECT` privilege for any columns that are only read, such as those named in the `WHERE` clause. See [GRANT](../grant/index).

 As stated, a `DELETE` statement with no `WHERE` clause deletes all rows. A faster way to do this, when you do not need to know the number of deleted rows, is to use `TRUNCATE TABLE`. However, within a transaction or if you have a lock on the table, `TRUNCATE TABLE` cannot be used whereas `DELETE` can. See [TRUNCATE TABLE](../truncate-table/index), and [LOCK](../lock/index).

 ### PARTITION

 See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 ### FOR PORTION OF

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**See [Application Time Periods - Deletion by Portion](../application-time-periods/index#deletion-by-portion).

 
### RETURNING

 It is possible to return a resultset of the deleted rows for a single table to the client by using the syntax `DELETE ... RETURNING select_expr [, select_expr2 ...]]`

 Any of SQL expression that can be calculated from a single row fields is allowed. Subqueries are allowed. The AS keyword is allowed, so it is possible to use aliases.

 The use of aggregate functions is not allowed. RETURNING cannot be used in multi-table DELETEs.

 
**MariaDB starting with [10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)**### Same Source and Target Table

 Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), deleting from a table with the same source and target was not possible. From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), this is now possible. For example:

 
```
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);

```



**MariaDB starting with [10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/)**### DELETE HISTORY

 One can use `DELETE HISTORY` to delete historical information from [System-versioned tables](../system-versioned-tables/index).

 
Examples
--------

 How to use the [ORDER BY](../order-by/index) and [LIMIT](../limit/index) clauses:

 
```
DELETE FROM page_hit ORDER BY timestamp LIMIT 1000000;

```

How to use the RETURNING clause:

 
```
DELETE FROM t RETURNING f1;
+------+
| f1   |
+------+
|    5 |
|   50 |
|  500 |
+------+ 

```

The following statement joins two tables: one is only used to satisfy a WHERE condition, but no row is deleted from it; rows from the other table are deleted, instead.

 
```
DELETE post FROM blog INNER JOIN post WHERE blog.id = post.blog_id;

```

### Deleting from the Same Source and Target

 
```
CREATE TABLE t1 (c1 INT, c2 INT);
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);

```

Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), this returned:

 
```
ERROR 1093 (HY000): Table 't1' is specified twice, both as a target for 'DELETE' 
  and as a separate source for

```

From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/):

 
```
Query OK, 0 rows affected (0.00 sec)

```

See Also
--------

 * [How IGNORE works](../ignore/index)
* [SELECT](../select/index)
* [ORDER BY](../order-by/index)
* [LIMIT](../limit/index)
* [REPLACE ... RETURNING](../replacereturning/index)
* [INSERT ... RETURNING](../insertreturning/index)
* [Returning clause](https://www.youtube.com/watch?v=n-LTdEBeAT4) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/delete/>

Using CONNECT - Partitioning and Sharding
=========================================

     CONNECT supports the MySQL/MariaDB partition specification. It is done similar to the way [MyISAM](../myisam/index) or [InnoDB](../innodb/index) do by using the PARTITION engine that must be enabled for this to work. This type of partitioning is sometimes referred as “horizontal partitioning”.

 Partitioning enables you to distribute portions of individual tables across a file system according to rules which you can set largely as needed. In effect, different portions of a table are stored as separate tables in different locations. The user-selected rule by which the division of data is accomplished is known as a partitioning function, which in MariaDB can be the modulus, simple matching against a set of ranges or value lists, an internal hashing function, or a linear hashing function.

 CONNECT takes this notion a step further, by providing two types of partitioning:

 1. File partitioning. Each partition is stored in a separate file like in multiple tables.
2. Table partitioning. Each partition is stored in a separate table like in TBL tables.

 Partition engine issues
-----------------------

 Using partitions sometimes requires creating the tables in an unnatural way to avoid some error due to several partition engine bugs:

 1. Engine specific column and index options are not recognized and cause a syntax error when the table is created. The workaround is to create the table in two steps, a CREATE TABLE statement followed by an ALTER TABLE statement.
2. The connection string, when specified for the table, is lost by the partition engine. The workaround is to specify the connection string in the *option\_list*.
3. [MySQL upstream bug #71095](https://bugs.mysql.com/bug.php?id=71095). In case of list columns partitioning it sometimes causes a false “impossible where” clause to be raised. This makes a wrong void result returned when it should not be void. There is no workaround but this bug should be hopefully fixed.

 The following examples are using the above workaround syntax to address these issues.

 File Partitioning
-----------------

 File partitioning applies to file-based CONNECT table types. As with multiple tables, physical data is stored in several files instead of just one. The differences to multiple tables are:

 1. Data is distributed amongst the different files following the partition rule.
2. Unlike multiple tables, partitioned tables are not read only.
3. Unlike multiple tables, partitioned tables can be indexable.
4. The file names are generated from the partition names.
5. Query pruning is automatically made by the partition engine.

 The table file names are generated differently depending on whether the table is an inward or outward table. For inward tables, for which the file name is not specified, the partition file names are:

 
```
Data file name: table_name#P#partition_name.table_file_type
Index file name: table_name#P#partition_name.index_file_type

```

For instance for the table:

 
```
CREATE TABLE t1 (
id INT KEY NOT NULL,
msg VARCHAR(32))
ENGINE=CONNECT TABLE_TYPE=FIX
partition by range(id) (
partition first values less than(10),
partition middle values less than(50),
partition last values less than(MAXVALUE));

```

CONNECT will generate in the current data directory the files:

 
```
| t1#P#first.fix
| t1#P#first.fnx
| t1#P#middle.fix
| t1#P#middle.fnx
| t1#P#last.fix
| t1#P#last.fnx

```

This is similar to what the partition engine does for other engines - CONNECT partitioned inward tables behave like other engines partition tables do. Just the data format is different.

 Note: If sub-partitioning is used, inward table files and index files are named:

 
```
| table_name#P#partition_name#SP#subpartition_name.type
| table_name#P#partition_name#SP#subpartition_name.index_type

```

### Outward Tables

 The real problems occur with outward tables, in particular when they are created from already existing files. The first issue is to make the partition table use the correct existing file names. The second one, only for already existing not void tables, is to be sure the partitioning function match the distribution of the data already existing in the files.

 The first issue is addressed by the way data file names are constructed. For instance let us suppose we want to make a table from the fixed formatted files:

 
```
E:\Data\part1.txt
E:\Data\part2.txt
E:\Data\part3.txt

```

This can be done by creating a table such as:

 
```
create table t2 (
id int not null,
msg varchar(32),
index XID(id))
engine=connect table_type=FIX file_name='E:/Data/part%s.txt'
partition by range(id) (
partition `1` values less than(10),
partition `2` values less than(50),
partition `3` values less than(MAXVALUE));

```

The rule is that for each partition the matching file name is internally generated by replacing in the given FILE \_ NAME option value the “%s” part by the partition name.

 If the table was initially void, further inserts will populate it according to the partition function. However, if the files did exist and contained data, this is your responsibility to determine what partition function actually matches the data distribution in them. This means in particular that partitioning by key or by hash cannot be used (except in exceptional cases) because you have almost no control over what the used algorithm does.

 In the example above, there is no problem if the table is initially void, but if it is not, serious problems can be met if the initial distribution does not match the table distribution. Supposing a row in which “id” as the value 12 was initially contained in the part1.txt file, it will be seen when selecting the whole table but if you ask:

 
```
select * from t2 where id = 12;

```

The result will have 0 rows. This is because according to the partition function query pruning will only look inside the second partition and will miss the row that is in the wrong partition.

 One way to check for wrong distribution if for instance to compare the results from queries such as:

 
```
SELECT partition_name, table_rows FROM
information_schema.partitions WHERE table_name = 't2';

```

And

 
```
SELECT CASE WHEN id < 10 THEN 1 WHEN id < 50 THEN 2 ELSE 3 END
AS pn, COUNT(*) FROM part3 GROUP BY pn;

```

If they match, the distribution can be correct although this does not prove it. However, if they do not match, the distribution is surely wrong.

 #### Partitioning on a Special Column

 There are some cases where the files of a multiple table do not contain columns that can be used for range or list partitioning. For instance, let’s suppose we have a multiple table based on the following files:

 
```
tmp/boston.txt
tmp/chicago.txt
tmp/atlanta.txt

```

Each of them containing the same kind of data:

 
```
ID: int
First_name: varchar(16)
Last_name: varchar(30)
Birth: date
Hired: date
Job: char(10)
Salary: double(8,2)

```

A multiple table can be created on them, for instance by:

 
```
create table mulemp (
id int NOT NULL,
first_name varchar(16) NOT NULL,
last_name varchar(30) NOT NULL,
birth date NOT NULL date_format='DD/MM/YYYY',
hired date NOT NULL date_format='DD/MM/YYYY',
job char(10) NOT NULL,
salary double(8,2) NOT NULL
) engine=CONNECT table_type=FIX file_name='tmp/*.txt' multiple=1;

```

The issue is that if we want to create a partitioned table on these files, there are no columns to use for defining a partition function. Each city file can have the same kind of column values and there is no way to distinguish them.

 However, there is a solution. It is to add to the table a special column that will be used by the partition function. For instance, the new table creation can be done by:

 
```
create table partemp (
id int NOT NULL,
first_name varchar(16) NOT NULL,
last_name varchar(30) NOT NULL,
birth date NOT NULL date_format='DD/MM/YYYY',
hired date NOT NULL date_format='DD/MM/YYYY',
job char(16) NOT NULL,
salary double(10,2) NOT NULL,
city char(12) default 'boston' special=PARTID,
index XID(id)
) engine=CONNECT table_type=FIX file_name='E:/Data/Test/%s.txt';
alter table partemp
partition by list columns(city) (
partition `atlanta` values in('atlanta'),
partition `boston` values in('boston'),
partition `chicago` values in('chicago'));

```

Note 1: we had to do it in two steps because of the column CONNECT options.

 Note 2: the special column PARTID returns the name of the partition in which the row is located.

 Note 3: here we could have used the FNAME special column instead because the file name is specified as being the partition name.

 This may seem rather stupid because it means for instance that a row will be in partition boston if it belongs to the partition boston! However, it works because the partition engine doesn’t know about special columns and behaves as if the city column was a real column.

 What happens if we populate it by?

 
```
insert into partemp(id,first_name,last_name,birth,hired,job,salary) values
(1205,'Harry','Cover','1982-10-07','2010-09-21','MANAGEMENT',125000.00);
insert into partemp values
(1524,'Jim','Beams','1985-06-18','2012-07-25','SALES',52000.00,'chicago'),
(1431,'Johnny','Walker','1988-03-12','2012-08-09','RESEARCH',46521.87,'boston'),
(1864,'Jack','Daniels','1991-12-01','2013-02-16','DEVELOPMENT',63540.50,'atlanta');

```

The value given for the city column (explicitly or by default) will be used by the partition engine to decide in which partition to insert the rows. It will be ignored by CONNECT (a special column cannot be given a value) but later will return the matching value. For instance:

 
```
select city, first_name, job from partemp where id in (1524,1431);

```

This query returns:

 


| city | first\_name | job |
| --- | --- | --- |
| boston | Johnny | RESEARCH |
| chicago | Jim | SALES |

  Everything works as if the city column was a real column contained in the table data files.

 #### Partitioning of zipped tables

 Two cases are currently supported:

 If a table is based on several zipped files, portioning is done the standard way as above. This is the *file\_name* option specifying the name of the zip files that shall contain the ‘%s’ part used to generate the file names.

 If a table is based on only one zip file containing several entries, this will be indicated by placing the ‘%s’ part in the entry option value.

 Note: If a table is based on several zipped files each containing several entries, only the first case is possible. Using sub-partitioning to make partitions on each entries is not supported yet. 

 Table Partitioning
------------------

 With table partitioning, each partition is physically represented by a sub-table. Compared to standard partitioning, this brings the following features:

 1. The partitions can be tables driven by different engines. This relieves the current existing limitation of the partition engine.
2. The partitions can be tables driven by engines not currently supporting partitioning.
3. Partition tables can be located on remote servers, enabling table sharding.
4. Like for TBL tables, the columns of the partition table do not necessarily match the columns of the sub-tables.

 The way it is done is to create the partition table with a table type referring to other tables, [PROXY](../connect-table-types-proxy-table-type/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index) or [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index). Let us see how this is done on a simple example. Supposing we have created the following tables:

 
```
create table xt1 (
id int not null,
msg varchar(32))
engine=myisam;

create table xt2 (
id int not null,
msg varchar(32)); /* engine=innoDB */

create table xt3 (
id int not null,
msg varchar(32))
engine=connect table_type=CSV;

```

We can for instance create a partition table using these tables as physical partitions by:

 
```
create table t3 (
id int not null,
msg varchar(32))
engine=connect table_type=PROXY tabname='xt%s'
partition by range columns(id) (
partition `1` values less than(10),
partition `2` values less than(50),
partition `3` values less than(MAXVALUE));

```

Here the name of each partition sub-table will be made by replacing the ‘%s’ part of the tabname option value by the partition name. Now if we do:

 
```
insert into t3 values
(4, 'four'),(7,'seven'),(10,'ten'),(40,'forty'),
(60,'sixty'),(81,'eighty one'),(72,'seventy two'),
(11,'eleven'),(1,'one'),(35,'thirty five'),(8,'eight');

```

The rows will be distributed in the different sub-tables according to the partition function. This can be seen by executing the query:

 
```
select partition_name, table_rows from
information_schema.partitions where table_name = 't3';

```

This query replies: 

 

| partition\_name | table\_rows |
| --- | --- |
| 1 | 4 |
| 2 | 4 |
| 3 | 3 |

 
Query pruning is of course automatic, for instance:

 
```
explain partitions select * from t3 where id = 81;

```

This query replies:

 


| id | select\_type | table | partitions | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | part5 | 3 | ALL | <null> | <null> | <null> | <null> | 22 | Using where |

 
When executing this select query, only sub-table xt3 will be used.

 ### Indexing with Table Partitioning

 Using the [PROXY](../connect-table-types-proxy-table-type/index) table type seems natural. However, in this current version, the issue is that PROXY (and [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index)) tables are not indexable. This is why, if you want the table to be indexed, you must use the [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) table type. The CREATE TABLE statement will be almost the same:

 
```
create table t4 (
id int key not null,
msg varchar(32))
engine=connect table_type=MYSQL tabname='xt%s'
partition by range columns(id) (
partition `1` values less than(10),
partition `2` values less than(50),
partition `3` values less than(MAXVALUE));

```

The column *id* is declared as a key, and the table type is now MYSQL. This makes Sub-tables accessed by calling a MariaDB server as MYSQL tables do. Note that this modifies only the way CONNECT sub-tables are accessed.

 However, indexing just make the partitioned table use “remote indexing” the way FEDERATED tables do. This means that when sending the query to retrieve the table data, a where clause will be added to the query. For instance, let’s suppose you ask:

 
```
select * from t4 where id = 7;

```

The query sent to the server will be:

 
```
SELECT `id`, `msg` FROM `xt1` WHERE `id` = 7

```

On a query like this one, it does not change much because the where clause could have been added anyway by the cond\_push function, but it does make a difference in case of joins. The main thing to understand is that real indexing is done by the called table and therefore that it should be indexed.

 This also means that the xt1, xt2, and xt3 table indexes should be made separately because creating the t2 table as indexed does not make the indexes on the sub-tables.

 ### Sharding with Table Partitioning

 Using table partitioning can have one more advantage. Because the sub-tables can address a table located on another server, it is possible to shard a table on separate servers and hardware machines. This may be required to access as one table data already located on several remote machines, such as servers of a company branches. Or it can be just used to split a huge table for performance reason. For instance, supposing we have created the following tables:

 
```
create table rt1 (id int key not null, msg varchar(32))
engine=federated connection='mysql://root@host1/test/sales';

create table rt2 (id int key not null, msg varchar(32))
engine=federated connection='mysql://root@host2/test/sales';

create table rt3 (id int key not null, msg varchar(32))
engine=federated connection='mysql://root@host3/test/sales';

```

Creating the partition table accessing all these will be almost like what we did with the t4 table:

 
```
create table t5 (
id int key not null,
msg varchar(32))
engine=connect table_type=MYSQL tabname='rt%s'
partition by range columns(id) (
partition `1` values less than(10),
partition `2` values less than(50),
partition `3` values less than(MAXVALUE));

```

.

 The only difference is the tabname option now referring to the rt1, rt2, and rt3 tables. However, even if it works, this is not the best way to do it. This is because accessing a table via the MySQL API is done twice per table. Once by CONNECT to access the FEDERATED table on the local server, then a second time by FEDERATED engine to access the remote table.

 The CONNECT MYSQL table type being used anyway, you’d rather use it to directly access the remote tables. Indeed, the partition names can also be used to modify the connection URL’s. For instance, in the case shown above, the partition table can be created as:

 
```
create table t6 (
id int key not null,
msg varchar(32))
engine=connect table_type=MYSQL
option_list='connect=mysql://root@host%s/test/sales'
partition by range columns(id) (
partition `1` values less than(10),
partition `2` values less than(50),
partition `3` values less than(MAXVALUE));

```

Several things can be noted here:

 1. As we have seen before, the partition engine currently loses the connection string. This is why it was specified as “connect” in the option list.
2. For each partition sub-tables, the “%s” part of the connection string has been replaced by the partition name.
3. It is not needed anymore to define the rt1, rt2, and rt3 tables (even it does not harm) and the FEDERATED engine is no more used to access the remote tables.

 This is a simple case where the connection string is almost the same for all the sub-tables. But what if the sub-tables are accessed by very different connection strings? For instance:

 
```
For rt1: connection='mysql://root:tinono@127.0.0.1:3307/test/xt1'
For rt2: connection='mysql://foo:foopass@denver/dbemp/xt2'
For rt3: connection='mysql://root@huston :5505/test/tabx'

```

There are two solutions. The first one is to use the parts of the connection string to differentiate as partition names:

 
```
create table t7 (
id int key not null,
msg varchar(32))
engine=connect table_type=MYSQL
option_list='connect=mysql://%s'
partition by range columns(id) (
partition `root:tinono@127.0.0.1:3307/test/xt1` values less than(10),
partition `foo:foopass@denver/dbemp/xt2` values less than(50),
partition `root@huston :5505/test/tabx` values less than(MAXVALUE));

```

The second one, allowing avoiding too complicated partition names, is to create federated servers to access the remote tables (if they do not already exist, else just use them). For instance the first one could be:

 
```
create server `server_one` foreign data wrapper 'mysql'
options
(host '127.0.0.1',
database 'test',
user 'root',
password 'tinono',
port 3307);

```

Similarly, “server\_two” and “server\_three” would be created and the final partition table would be created as:

 
```
create table t8 (
id int key not null,
msg varchar(32))
engine=connect table_type=MYSQL
option_list='connect=server_%s'
partition by range columns(id) (
partition `one/xt1` values less than(10),
partition `two/xt2` values less than(50),
partition `three/tabx` values less than(MAXVALUE));

```

It would be even simpler if all remote tables had the same name on the remote databases, for instance if they all were named xt1, the connection string could be set as “server\_%s/xt1” and the partition names would be just “one”, “two”, and “three”.

 #### Sharding on a Special Column

 The technique we have seen above with file partitioning is also available with table partitioning. Companies willing to use as one table data sharded on the company branch servers can, as we have seen, add to the table create definition a special column. For instance:

 
```
create table t9 (
id int not null,
msg varchar(32),
branch char(16) default 'main' special=PARTID,
index XID(id))
engine=connect table_type=MYSQL
option_list='connect=server_%s/sales'
partition by range columns(id) (
partition `main` values in('main'),
partition `east` values in('east'),
partition `west` values in('west'));

```

This example assumes that federated servers had been created named “server\_main”, “server\_east” and “server\_west” and that all remote tables are named “sales”. Note also that in this example, the column id is no more a key.

 Current Partition Limitations
-----------------------------

 Because the partition engine was written before some other engines were added to MariaDB, the way it works is sometime incompatible with these engines, in particular with CONNECT.

 ### Update statement

 With the sample tables above, you can do update statements such as:

 
```
update t2 set msg = 'quatre' where id = 4;

```

It works perfectly and is accepted by CONNECT. However, let us consider the statement:

 
```
update t2 set id = 41 where msg = 'four';

```

This statement is not accepted by CONNECT. The reason is that the column id being part of the partition function, changing its value may require the modified row to be moved to another partition. The way it is done by the partition engine is to delete the old row and to re-insert the new modified one. However, this is done in a way that is not currently compatible with CONNECT (remember that CONNECT supports UPDATE in a specific way, in particular for the table type MYSQL) This limitation could be temporary. Meanwhile the workaround is to manually do what is done above,

 Deleting the row to modify and inserting the modified row:

 
```
delete from t2 where id = 4;
insert into t2 values(41, 'four');

```

### Alter Table statement

 For all CONNECT outward tables, the ALTER TABLE statement does not make any change in the table data. This is why ALTER TABLE should not be used; in particular to modify the partition definition, except of course to correct a wrong definition. Note that using ALTER TABLE to create a partition table in two steps because column options would be lost is valid as it applies to a table that is not yet partitioned.

 As we have seen, it is also safe to use it to create or drop indexes. Otherwise, a simple rule of thumb is to avoid altering a table definition and better drop and re-create a table whose definition must be modified. Just remember that for outward CONNECT tables, dropping a table does not erase the data and that creating it does not modify existing data.

 ### Rowid special column

 Each partition being handled separately as one table, the ROWID special column returns the rank of the row in its partition, not in the whole table. This means that for partition tables ROWID and ROWNUM are equivalent.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-partitioning-and-sharding/>

KEY Partitioning Type
=====================

    ### Syntax

 
```
PARTITION BY KEY (column_value)
[PARTITIONS (number_of_partitions)]

```

### Description

 Partitioning by key is a type of partitioning that is similar to and can be used in a similar way as partitioning by hash. 

 Just like HASH partitioning, in KEY partitioning the server takes care of the partition and ensures an even distribution among the partitions. However, the largest difference is that KEY partitioning requires a *column\_value*, and cannot accept a *partitioning\_expression* which is based on a *column\_value*, in contrast to HASH partitioning, which can.

 It requires a *column\_value*, and the hashing function is given by the server.

 ### Example

 
```
CREATE OR REPLACE TABLE t1 (v1 INT)
  PARTITION BY KEY (v1)
  PARTITIONS 2;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/key-partitioning-type/>

RANGE COLUMNS and LIST COLUMNS Partitioning Types
=================================================

    RANGE COLUMNS and LIST COLUMNS are variants of, respectively, [RANGE](../range-partitioning-type/index) and [LIST](../list-partitioning/index). With these partitioning types there is not a single partitioning expression; instead, a list of one or more columns is accepted. The following rules apply:

 * The list can contain one or more columns.
* Columns can be of any [integer](../int/index), [string](../string-data-types/index), [DATE](../date/index), and [DATETIME](../datetime/index) types.
* Only bare columns are permitted; no expressions.

 All the specified columns are compared to the specified values to determine which partition should contain a specific row. See below for details.

 Syntax
------

 The last part of a [CREATE TABLE](../create-table/index) statement can be definition of the new table's partitions. In the case of RANGE COLUMNS partitioning, the syntax is the following:

 
```
PARTITION BY RANGE COLUMNS (col1, col2, ...)
(
	PARTITION partition_name VALUES LESS THAN (value1, value2, ...),
	[ PARTITION partition_name VALUES LESS THAN (value1, value2, ...), ... ]
)

```

The syntax for LIST COLUMNS is the following:

 
```
PARTITION BY LIST COLUMNS (partitioning_expression)
(
	PARTITION partition_name VALUES IN (value1, value2, ...),
	[ PARTITION partition_name VALUES IN (value1, value2, ...), ... ]
        [ PARTITION partititon_name DEFAULT ]
)

```

`partition_name` is the name of a partition.

 Comparisons
-----------

 To determine which partition should contain a row, all specified columns will be compared to each partition definition.

 With LIST COLUMNS, a row matches a partition if all row values are identical to the specified values. At most one partition can match the row.

 With RANGE COLUMNS, a row matches a partition if all row values are less than specified values. The first partition that matches row values will be used.

 `DEFAULT` partition catch all records which do not fit in other partitions. Only one `DEFAULT` partititon allowed. This option added in [MariaDB 10.2](../what-is-mariadb-102/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/range-columns-and-list-columns-partitioning-types/>

REPLACE
=======

    Syntax
------

 
```
REPLACE [LOW_PRIORITY | DELAYED]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [PARTITION (partition_list)]
    SET col={expr | DEFAULT}, ...
[RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
    SELECT ...
[RETURNING select_expr 
      [, select_expr ...]]

```
 Description
-----------

  `REPLACE` works exactly like `[INSERT](../insert/index)`, except that if an old row in the table has the same value as a new row for a `PRIMARY KEY` or a `UNIQUE` index, the old row is deleted before the new row is inserted. If the table has more than one `UNIQUE` keys, it is possible that the new row conflicts with more than one row. In this case, all conflicting rows will be deleted.

 The table name can be specified in the form `db_name`.`tbl_name` or, if a default database is selected, in the form `tbl_name` (see [Identifier Qualifiers](../identifier-qualifiers/index)). This allows to use `[REPLACE ... SELECT](../insert-select/index)` to copy rows between different databases.   
  


 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**The RETURNING clause was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 
Basically it works like this:

 
```
BEGIN;
SELECT 1 FROM t1 WHERE key=# FOR UPDATE;
IF found-row
  DELETE FROM t1 WHERE key=# ;
ENDIF
INSERT INTO t1 VALUES (...);
END;

```

The above can be replaced with:

 
```
REPLACE INTO t1 VALUES (...)

```

 `REPLACE` is a MariaDB/MySQL extension to the SQL standard. It either inserts, or deletes and inserts. For other MariaDB/MySQL extensions to standard SQL --- that also handle duplicate values --- see [IGNORE](../ignore/index) and [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index).

 Note that unless the table has a `PRIMARY KEY` or `UNIQUE` index, using a `REPLACE` statement makes no sense. It becomes equivalent to `INSERT`, because there is no index to be used to determine whether a new row duplicates another.

 Values for all columns are taken from the values sSee [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.pecified in the `REPLACE` statement. Any missing columns are set to their default values, just as happens for `INSERT`. You cannot refer to values from the current row and use them in the new row. If you use an assignment such as `'SET col = col + 1'`, the reference to the column name on the right hand side is treated as `DEFAULT(col)`, so the assignment is equivalent to `'SET col = DEFAULT(col) + 1'`.

 To use `REPLACE`, you must have both the `INSERT` and `DELETE` [privileges](../grant/index) for the table.

 There are some gotchas you should be aware of, before using `REPLACE`:

 * If there is an `[AUTO\_INCREMENT](../auto_increment/index)` field, a new value will be generated.
* If there are foreign keys, `ON DELETE` action will be activated by `REPLACE`.
* [Triggers](../triggers/index) on `DELETE` and `INSERT` will be activated by `REPLACE`.

 To avoid some of these behaviors, you can use `INSERT ... ON DUPLICATE KEY UPDATE`.

 This statement activates INSERT and DELETE triggers. See [Trigger Overview](../trigger-overview/index) for details.

 ### PARTITION

 See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 ### REPLACE RETURNING

 
`REPLACE ... RETURNING` returns a resultset of the replaced rows.

 This returns the listed columns for all the rows that are replaced, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.

 
#### Examples

 Simple REPLACE statement

 
```
REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

```

Using stored functions in RETURNING

 
```
DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
    BEGIN
      RETURN (SELECT arg+arg);
    END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

```

Subqueries in the statement

 
```
REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

```

Subqueries in the RETURNING clause that return more than one row or column cannot be used..

 Aggregate functions cannot be used in the RETURNING clause. Since aggregate functions work on a set of values and if the purpose is to get the row count, ROW\_COUNT() with SELECT can be used, or it can be used in REPLACE...SEL== Description

 
`REPLACE ... RETURNING` returns a resultset of the replaced rows.

 This returns the listed columns for all the rows that are replaced, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.

 
Examples
--------

 Simple REPLACE statement

 
```
REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

```

Using stored functions in RETURNING

 
```
DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
    BEGIN
      RETURN (SELECT arg+arg);
    END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

```

Subqueries in the statement

 
```
REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

```

Subqueries in the RETURNING clause that return more than one row or column cannot be used..

 Aggregate functions cannot be used in the RETURNING clause. Since aggregate functions work on a set of values and if the purpose is to get the row count, ROW\_COUNT() with SELECT can be used, or it can be used in REPLACE...SELECT...RETURNING if the table in the RETURNING clause is not the same as the REPLACE table. ECT...RETURNING if the table in the RETURNING clause is not the same as the REPLACE table.

 See Also
--------

 * [INSERT](../insert/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY clauses](../high_priority-and-low_priority-clauses/index)
* [INSERT DELAYED](../insert-delayed/index) for details on the `DELAYED` clause

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replace/>

Information Schema
===================

   Articles about the Information Schema

  

| Title | Description |
| --- | --- |
|  [Information Schema Tables](../information-schema-tables/index) |  Tables in the Information\_Schema database  |
|  [Extended Show](../extended-show/index) |  Extended SHOW with WHERE and LIKE.  |
|  [TIME\_MS column in INFORMATION\_SCHEMA.PROCESSLIST](../time_ms-column-in-information_schemaprocesslist/index) |  Microseconds in the INFORMATION\_SCHEMA.PROCESSLIST table  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema/>

Foreign Keys
============

    Overview
--------

 A foreign key is a constraint which can be used to enforce data integrity. It is composed by a column (or a set of columns) in a table called the child table, which references to a column (or a set of columns) in a table called the parent table. If foreign keys are used, MariaDB performs some checks to enforce that some integrity rules are always enforced. For a more exhaustive explanation, see [Relational databases: Foreign Keys](../relational-databases-foreign-keys/index).

 Foreign keys can only be used with storage engines that support them. The default [InnoDB](../innodb/index) and the obsolete [PBXT](../pbxt/index) support foreign keys.

 [Partitioned tables](../managing-mariadb-partitioning/index) cannot contain foreign keys, and cannot be referenced by a foreign key.

 Syntax
------

 
**Note:** Until [MariaDB 10.4](../what-is-mariadb-104/index), MariaDB accepts the shortcut format with a REFERENCES clause only in ALTER TABLE and CREATE TABLE statements, but that syntax does nothing. For example:

 
```
CREATE TABLE b(for_key INT REFERENCES a(not_key));

```

MariaDB simply parses it without returning any error or warning, for compatibility with other DBMS's. However, only the syntax described below creates foreign keys.

 From [MariaDB 10.5](../what-is-mariadb-105/index), MariaDB will attempt to apply the constraint. See the [Examples](#references) below.

 
Foreign keys are created with [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index). The definition must follow this syntax:

 
```
[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

```

The `symbol` clause, if specified, is used in error messages and must be unique in the database.

 The columns in the child table must be a BTREE (not HASH, RTREE, or FULLTEXT — see [SHOW INDEX](../show-index/index)) index, or the leftmost part of a BTREE index. Index prefixes are not supported (thus, [TEXT](../text/index) and [BLOB](../blob/index) columns cannot be used as foreign keys). If MariaDB automatically creates an index for the foreign key (because it does not exist and is not explicitly created), its name will be `index_name`.

 The referenced columns in the parent table must be a an index or a prefix of an index.

 The foreign key columns and the referenced columns must be of the same type, or similar types. For integer types, the size and sign must also be the same.

 Both the foreign key columns and the referenced columns can be [PERSISTENT](../virtual-columns/index) columns. However, the ON UPDATE CASCADE, ON UPDATE SET NULL, ON DELETE SET NULL clauses are not allowed in this case.

 The parent and the child table must use the same storage engine, and must not be `TEMPORARY` or partitioned tables. They can be the same table.

 Constraints
-----------

 If a foreign keys exists, each row in the child table must match a row in the parent table. Multiple child rows can match the same parent row. A child row *matches* a parent row if all its foreign key values are identical to a parent row's values in the parent table. However, if at least one of the foreign key values is `NULL`, the row has no parents, but it is still allowed.

 MariaDB performs certain checks to guarantee that the data integrity is enforced:

 * Trying to insert non-matching rows (or update matching rows in a way that makes them non-matching rows) in the child table produces a 1452 error ([SQLSTATE](../sqlstate/index) '23000').
* When a row in the parent table is deleted and at least one child row exists, MariaDB performs an action which depends on the `ON DELETE` clause of the foreign key.
* When a value in the column referenced by a foreign key changes and at least one child row exists, MariaDB performs an action which depends on the `ON UPDATE` clause of the foreign key.
* Trying to drop a table that is referenced by a foreign key produces a 1217 error ([SQLSTATE](../sqlstate/index) '23000').
* A [TRUNCATE TABLE](../truncate-table/index) against a table containing one or more foreign keys is executed as a [DELETE](../delete/index) without WHERE, so that the foreign keys are enforced for each row.

 The allowed actions for `ON DELETE` and `ON UPDATE` are:

 * `RESTRICT`: The change on the parent table is prevented. The statement terminates with a 1451 error ([SQLSTATE](../sqlstate/index) '2300'). This is the default behavior for both `ON DELETE` and `ON UPDATE`.
* `NO ACTION`: Synonym for `RESTRICT`.
* `CASCADE`: The change is allowed and propagates on the child table. For example, if a parent row is deleted, the child row is also deleted; if a parent row's ID changes, the child row's ID will also change.
* `SET NULL`: The change is allowed, and the child row's foreign key columns are set to `NULL`.
* `SET DEFAULT`: Only worked with PBXT. Similar to `SET NULL`, but the foreign key columns were set to their default values. If default values do not exist, an error is produced.

 The delete or update operations triggered by foreign keys do not activate [triggers](../triggers/index) and are not counted in the [Com\_delete](../server-status-variables/index#com_delete) and [Com\_update](../server-status-variables/index#com_update) status variables.

 Foreign key constraints can be disabled by setting the [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) server system variable to 0. This speeds up the insertion of large quantities of data.

 Metadata
--------

 The [Information Schema](../information_schema/index) `[REFERENTIAL\_CONSTRAINTS](../information-schema-referential_constraints-table/index)` table contains information about foreign keys. The individual columns are listed in the `[KEY\_COLUMN\_USAGE](../information-schema-key_column_usage-table/index)` table.

 The InnoDB-specific Information Schema tables also contain information about the InnoDB foreign keys. The foreign key information is stored in the `[INNODB\_SYS\_FOREIGN](../information-schema-innodb_sys_foreign-table/index)`. Data about the individual columns are stored in `[INNODB\_SYS\_FOREIGN\_COLS](../information-schema-innodb_sys_foreign_cols-table/index)`.

 The most human-readable way to get information about a table's foreign keys sometimes is the `[SHOW CREATE TABLE](../show-create-table/index)` statement.

 Limitations
-----------

 Foreign keys have the following limitations in MariaDB:

 * Currently, foreign keys are only supported by InnoDB.
* Cannot be used with views.
* The `SET DEFAULT` action is not supported.
* Foreign keys actions do not activate [triggers](../triggers/index).
* If ON UPDATE CASCADE recurses to update the same table it has previously updated during the cascade, it acts like RESTRICT.

 Examples
--------

 Let's see an example. We will create an `author` table and a `book` table. Both tables have a primary key called `id`. `book` also has a foreign key composed by a field called `author_id`, which refers to the `author` primary key. The foreign key constraint name is optional, but we'll specify it because we want it to appear in error messages: `fk_book_author`.

 
```
CREATE TABLE author (
  id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
) ENGINE = InnoDB;

CREATE TABLE book (
  id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(200) NOT NULL,
  author_id SMALLINT UNSIGNED NOT NULL,
  CONSTRAINT `fk_book_author`
    FOREIGN KEY (author_id) REFERENCES author (id)
    ON DELETE CASCADE
    ON UPDATE RESTRICT
) ENGINE = InnoDB;

```

Now, if we try to insert a book with a non-existing author, we will get an error:

 
```
INSERT INTO book (title, author_id) VALUES ('Necronomicon', 1);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
 (`test`.`book`, CONSTRAINT `fk_book_author` FOREIGN KEY (`author_id`) 
  REFERENCES `author` (`id`) ON DELETE CASCADE)

```

The error is very descriptive.

 Now, let's try to properly insert two authors and their books:

 
```
INSERT INTO author (name) VALUES ('Abdul Alhazred');
INSERT INTO book (title, author_id) VALUES ('Necronomicon', LAST_INSERT_ID());

INSERT INTO author (name) VALUES ('H.P. Lovecraft');
INSERT INTO book (title, author_id) VALUES
  ('The call of Cthulhu', LAST_INSERT_ID()),
  ('The colour out of space', LAST_INSERT_ID());

```

It worked!

 Now, let's delete the second author. When we created the foreign key, we specified `ON DELETE CASCADE`. This should propagate the deletion, and make the deleted author's books disappear:

 
```
DELETE FROM author WHERE name = 'H.P. Lovecraft';

SELECT * FROM book;
+----+--------------+-----------+
| id | title        | author_id |
+----+--------------+-----------+
|  3 | Necronomicon |         1 |
+----+--------------+-----------+

```

We also specified `ON UPDATE RESTRICT`. This should prevent us from modifying an author's `id` (the column referenced by the foreign key) if a child row exists:

 
```
UPDATE author SET id = 10 WHERE id = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
 (`test`.`book`, CONSTRAINT `fk_book_author` FOREIGN KEY (`author_id`) 
  REFERENCES `author` (`id`) ON DELETE CASCADE)

```

### REFERENCES

 Until [MariaDB 10.4](../what-is-mariadb-104/index)

 
```
CREATE TABLE a(a_key INT primary key, not_key INT);

CREATE TABLE b(for_key INT REFERENCES a(not_key));

SHOW CREATE TABLE b;
+-------+----------------------------------------------------------------------------------+
| Table | Create Table                                                                     |
+-------+----------------------------------------------------------------------------------+
| b     | CREATE TABLE `b` (
  `for_key` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------+

INSERT INTO a VALUES (1,10);
Query OK, 1 row affected (0.005 sec)

INSERT INTO b VALUES (10);
Query OK, 1 row affected (0.004 sec)

INSERT INTO b VALUES (1);
Query OK, 1 row affected (0.004 sec)

SELECT * FROM b;
+---------+
| for_key |
+---------+
|      10 |
|       1 |
+---------+

```

From [MariaDB 10.5](../what-is-mariadb-105/index)

 
```
CREATE TABLE a(a_key INT primary key, not_key INT);

CREATE TABLE b(for_key INT REFERENCES a(not_key));
ERROR 1005 (HY000): Can't create table `test`.`b` 
  (errno: 150 "Foreign key constraint is incorrectly formed")

CREATE TABLE c(for_key INT REFERENCES a(a_key));

SHOW CREATE TABLE c;
+-------+----------------------------------------------------------------------------------+
| Table | Create Table                                                                     |
+-------+----------------------------------------------------------------------------------+
| c     | CREATE TABLE `c` (
  `for_key` int(11) DEFAULT NULL,
  KEY `for_key` (`for_key`),
  CONSTRAINT `c_ibfk_1` FOREIGN KEY (`for_key`) REFERENCES `a` (`a_key`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------+

INSERT INTO a VALUES (1,10);
Query OK, 1 row affected (0.004 sec)

INSERT INTO c VALUES (10);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails 
  (`test`.`c`, CONSTRAINT `c_ibfk_1` FOREIGN KEY (`for_key`) REFERENCES `a` (`a_key`))

INSERT INTO c VALUES (1);
Query OK, 1 row affected (0.004 sec)

SELECT * FROM c;
+---------+
| for_key |
+---------+
|       1 |
+---------+

```

See Also
--------

 * [MariaDB: InnoDB foreign key constraint errors](https://blog.mariadb.org/mariadb-innodb-foreign-key-constraint-errors/), a post in the MariaDB blog

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/foreign-keys/>

Query Cache
===========

     The query cache stores results of SELECT queries so that if the identical query is received in future, the results can be quickly returned.

 This is extremely useful in high-read, low-write environments (such as most websites). It does not scale well in environments with high throughput on multi-core machines, so it is disabled by default.

 
Note that the query cache cannot be enabled in certain environments. See [Limitations](#limitations).

 
Setting Up the Query Cache
--------------------------

 Unless MariaDB has been specifically built without the query cache, the query cache will always be available, although inactive. The [have\_query\_cache](../server-system-variables/index#have_query_cache) server variable will show whether the query cache is available.

 
```
SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+

```

If this is set to `NO`, you cannot enable the query cache unless you rebuild or reinstall a version of MariaDB with the cache available.

 To see if the cache is enabled, view the [query\_cache\_type](../server-system-variables/index#query_cache_type) server variable. It is enabled by default in MariaDB versions up to 10.1.6, but disabled starting with [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) - if needed enable it by setting `query_cache_type` to `1`.

 Although enabled in versions prior to [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), the [query\_cache\_size](../server-system-variables/index#query_cache_size) is by default 0KB there, which effectively disables the query cache. From 10.1.7 on the cache size defaults to 1MB. If needed set the cache to a size large enough amount, for example:

 
```
SET GLOBAL query_cache_size = 1000000;

```

Starting from [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), `query_cache_type` is automatically set to ON if the server is started with the `query_cache_size` set to a non-zero (and non-default) value. 

 See [Limiting the size of the Query Cache](#limiting-the-size-of-the-query-cache) below for details.

 How the Query Cache Works
-------------------------

 When the query cache is enabled and a new SELECT query is processed, the query cache is examined to see if the query appears in the cache. 

 Queries are considered identical if they use the same database, same protocol version and same default character set. Prepared statements are always considered as different to non-prepared statements, see [Query cache internal structure](#query-cache-internal-structure) for more info.

 If the identical query is not found in the cache, the query will be processed normally and then stored, along with its result set, in the query cache. If the query is found in the cache, the results will be pulled from the cache, which is much quicker than processing it normally.

 Queries are examined in a case-sensitive manner, so :

 
```
SELECT * FROM t

```

Is different from :

 
```
select * from t

```

Comments are also considered and can make the queries differ, so :

 
```
/* retry */SELECT * FROM t

```

Is different from :

 
```
/* retry2 */SELECT * FROM t

```

See the [query\_cache\_strip\_comments](../server-system-variables/index#query_cache_strip_comments) server variable for an option to strip comments before searching. 

 Each time changes are made to the data in a table, all affected results in the query cache are cleared. It is not possible to retrieve stale data from the query cache.

 When the space allocated to query cache is exhausted, the oldest results will be dropped from the cache.

 When using `query_cache_type=ON`, and the query specifies `SQL_NO_CACHE` (case-insensitive), the server will not cache the query and will not fetch results from the query cache.

 When using `query_cache_type=DEMAND` (after [MDEV-6631](https://jira.mariadb.org/browse/MDEV-6631) feature request) and the query specifies `SQL_CACHE`, the server will cache the query.

 One important point of [MDEV-6631](https://jira.mariadb.org/browse/MDEV-6631) is : switching between `query_cache_type=ON` and `query_cache_type=DEMAND` can "turn off" query cache of old queries without the `SQL_CACHE` string, that's not yet defined if we should include another `query_cache_type` (DEMAND\_NO\_PRUNE) value or not to allow use of old queries

 Queries Stored in the Query Cache
---------------------------------

 If the [query\_cache\_type](../server-system-variables/index#query_cache_type) system variable is set to `1`, or `ON`, all queries fitting the size constraints will be stored in the cache unless they contain a `SQL_NO_CACHE` clause, or are of a nature that caching makes no sense, for example making use of a function that returns the current time. Check that `SQL_NO_CACHE` will force server to don't use query cache locks.

 If any of the following functions are present in a query, it will not be cached. Queries with these functions are sometimes called 'non-deterministic' - don't get confused with the use of this term in other contexts.

 


|  |  |
| --- | --- |
| [BENCHMARK()](../benchmark/index) | [CONNECTION\_ID()](../connection_id/index) |
| [CONVERT\_TZ()](../convert_tz/index) | [CURDATE()](../curdate/index) |
| [CURRENT\_DATE()](../current_date/index) | [CURRENT\_TIME()](../current_time/index) |
| [CURRENT\_TIMESTAMP()](../current_timestamp/index) | [CURTIME()](../curtime/index) |
| [DATABASE()](../database/index) | [ENCRYPT()](../encrypt/index) (one parameter) |
| [FOUND\_ROWS()](../found_rows/index) | [GET\_LOCK()](../get_lock/index) |
| [LAST\_INSERT\_ID()](../last_insert_id/index) | [LOAD\_FILE()](../load_file/index) |
| [MASTER\_POS\_WAIT()](../master_pos_wait/index) | [NOW()](../now/index) |
| [RAND()](../rand/index) | [RELEASE\_LOCK()](../release_lock/index) |
| [SLEEP()](../sleep/index) | [SYSDATE()](../sysdate/index) |
| [UNIX\_TIMESTAMP()](../unix_timestamp/index) (no parameters) | [USER()](../user/index) |
| [UUID()](../uuid/index) | [UUID\_SHORT()](../uuid_short/index) |

 
A query will also not be added to the cache if:

 * It is of the form:
	+ SELECT SQL\_NO\_CACHE ...
	+ SELECT ... INTO OUTFILE ...
	+ SELECT ... INTO DUMPFILE ...
	+ SELECT ... FOR UPDATE
	+ SELECT \* FROM ... WHERE autoincrement\_column IS NULL
	+ SELECT ... LOCK IN SHARE MODE
* It uses TEMPORARY table
* It uses no tables at all
* It generates a warning
* The user has a column-level privilege on any table in the query
* It accesses a table from INFORMATION\_SCHEMA, mysql or the performance\_schema database
* It makes use of user or local variables
* It makes use of stored functions
* It makes use of user-defined functions
* It is inside a transaction with the SERIALIZABLE isolation level
* It is quering a table inside a transaction after the same table executed a query cache invalidation using INSERT, UPDATE or DELETE

 The query itself can also specify that it is not to be stored in the cache by using the `SQL_NO_CACHE` attribute. Query-level control is an effective way to use the cache more optimally.

 It is also possible to specify that *no* queries must be stored in the cache unless the query requires it. To do this, the [query\_cache\_type](../server-system-variables/index#query_cache_type) server variable must be set to `2`, or `DEMAND`. Then, only queries with the `SQL_CACHE` attribute are cached.

 Limiting the Size of the Query Cache
------------------------------------

 There are two main ways to limit the size of the query cache. First, the overall size in bytes is determined by the [query\_cache\_size](../server-system-variables/index#query_cache_size) server variable. About 40KB is needed for various query cache structures.

 The query cache size is allocated in 1024 byte-blocks, thus it should be set to a multiple of 1024. 

 The query result is stored using a minimum block size of [query\_cache\_min\_res\_unit](../server-system-variables/index#query_cache_min_res_unit). Check two conditions to use a good value of this variable: Query cache insert result blocks with locks, each new block insert lock query cache, a small value will increase locks and fragmentation and waste less memory for small results, a big value will increase memory use wasting more memory for small results but it reduce locks. Test with your workload for fine tune this variable.

 If the [strict mode](../sql-mode/index) is enabled, setting the query cache size to an invalid value will cause an error. Otherwise, it will be set to the nearest permitted value, and a warning will be triggered.

 
```
SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 67108864 |
+------------------+----------+

SET GLOBAL query_cache_size = 8000000;
Query OK, 0 rows affected, 1 warning (0.03 sec)

SHOW VARIABLES LIKE 'query_cache_size';
+------------------+---------+
| Variable_name    | Value   |
+------------------+---------+
| query_cache_size | 7999488 |
+------------------+---------+

```

The ideal size of the query cache is very dependent on the specific needs of each system. Setting a value too small will result in query results being dropped from the cache when they could potentially be re-used later. Setting a value too high could result in reduced performance due to lock contention, as the query cache is locked during updates.

 The second way to limit the cache is to have a maximum size for each set of query results. This prevents a single query with a huge result set taking up most of the available memory and knocking a large number of smaller queries out of the cache. This is determined by the [query\_cache\_limit](../server-system-variables/index#query_cache_limit) server variable.

 If you attempt to set a query cache that is too small (the amount depends on the architecture), the resizing will fail and the query cache will be set to zero, for example :

 
```
SET GLOBAL query_cache_size=40000;
Query OK, 0 rows affected, 2 warnings (0.03 sec)

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------+
| Level   | Code | Message                                                         |
+---------+------+-----------------------------------------------------------------+
| Warning | 1292 | Truncated incorrect query_cache_size value: '40000'             |
| Warning | 1282 | Query cache failed to set size 39936; new query cache size is 0 |
+---------+------+-----------------------------------------------------------------+

```

Examining the Query Cache
-------------------------

 A number of status variables provide information about the query cache.

 
```
SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1158     |
| Qcache_free_memory      | 3760784  |
| Qcache_hits             | 31943398 |
| Qcache_inserts          | 42998029 |
| Qcache_lowmem_prunes    | 34695322 |
| Qcache_not_cached       | 652482   |
| Qcache_queries_in_cache | 4628     |
| Qcache_total_blocks     | 11123    |
+-------------------------+----------+

```

`Qcache_inserts` contains the number of queries added to the query cache, `Qcache_hits` contains the number of queries that have made use of the query cache, while `Qcache_lowmem_prunes` contains the number of queries that were dropped from the cache due to lack of memory.

 The above example could indicate a poorly performing cache. More queries have been added, and more queries have been dropped, than have actually been used.

 Note that before [MariaDB 5.5](../what-is-mariadb-55/index), queries returned from the query cache did not increment the [Com\_select](../server-status-variables/index#com_select) status variable, so to find the total number of valid queries run on the server, add [Com\_select](../server-status-variables/index#com_select) to [Qcache\_hits](../server-status-variables/index#qcache_hits). Starting from [MariaDB 5.5](../what-is-mariadb-55/index), results returned by the query cache count towards `Com_select` (see [MDEV-4981](https://jira.mariadb.org/browse/MDEV-4981)).

 The [QUERY\_CACHE\_INFO plugin](../query_cache_info-plugin/index) creates the [QUERY\_CACHE\_INFO](../information-schema-query_cache_info-table/index) table in the [INFORMATION\_SCHEMA](../information_schema/index), allowing you to examine the contents of the query cache.

 Query Cache Fragmentation
-------------------------

 The Query Cache uses blocks of variable length, and over time may become fragmented. A high `Qcache_free_blocks` relative to `Qcache_total_blocks` may indicate fragmentation. [FLUSH QUERY CACHE](../flush-query-cache/index) will defragment the query cache without dropping any queries :

 
```
FLUSH QUERY CACHE;

```

After this, there will only be one free block :

 
```
SHOW STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name           | Value    |
+-------------------------+----------+
| Qcache_free_blocks      | 1        |
| Qcache_free_memory      | 6101576  |
| Qcache_hits             | 31981126 |
| Qcache_inserts          | 43002404 |
| Qcache_lowmem_prunes    | 34696486 |
| Qcache_not_cached       | 655607   |
| Qcache_queries_in_cache | 4197     |
| Qcache_total_blocks     | 8833     |
+-------------------------+----------+

```

Emptying and disabling the Query Cache
--------------------------------------

 To empty or clear all results from the query cache, use [RESET QUERY CACHE](../reset/index). [FLUSH TABLES](../flush/index) will have the same effect.

 Setting either [query\_cache\_type](../server-system-variables/index#query_cache_type) or [query\_cache\_size](../server-system-variables/index#query_cache_size) to `0` will disable the query cache, but to free up the most resources, set both to `0` when you wish to disable caching.

 Limitations
-----------

 * The query cache needs to be disabled in order to use [OQGRAPH](../oqgraph/index).
* The query cache is not used by the [Spider](../spider/index) storage engine (amongst others).
* The query cache also needs to be disabled for MariaDB [Galera](../galera/index) cluster versions prior to "5.5.40-galera", "10.0.14-galera" and "10.1.2".

 LOCK TABLES and the Query Cache
-------------------------------

 The query cache can be used when tables have a write lock (which may seem confusing since write locks should avoid table reads). This behaviour can be changed by setting the [query\_cache\_wlock\_invalidate](../server-system-variables/index#query_cache_wlock_invalidate) system variable to `ON`, in which case each write lock will invalidate the table query cache. Setting to `OFF`, the default, means that cached queries can be returned even when a table lock is being held. For example:

 
```
1> SELECT * FROM T1
+---+
| a |
+---+
| 1 |
+---+
-- Here the query is cached

-- From another connection execute:
2> LOCK TABLES T1 WRITE;

-- Expected result with: query_cache_wlock_invalidate = OFF
1> SELECT * FROM T1
+---+
| a |
+---+
| 1 |
+---+
-- read from query cache


-- Expected result with: query_cache_wlock_invalidate = ON
1> SELECT * FROM T1
-- Waiting Table Write Lock

```

Transactions and the Query Cache
--------------------------------

 The query cache handles transactions. Internally a flag (FLAGS\_IN\_TRANS) is set to 0 when a query was executed outside a transaction, and to 1 when the query was inside a transaction ([BEGIN](begin) / [COMMIT](../commit/index) / [ROLLBACK](../rollback/index)). This flag is part of the "query cache hash", in others words one query inside a transaction is different from a query outside a transaction. 

 Queries that change rows ([INSERT](../insert/index) / [UPDATE](../update/index) / [DELETE](../delete/index) / [TRUNCATE](../truncate/index)) inside a transaction will invalidate all queries from the table, and turn off the query cache to the changed table. Transactions that don't end with COMMIT / ROLLBACK check that even without COMMIT / ROLLBACK, the query cache is turned off to allow row level locking and consistency level.

 Examples:

 
```
SELECT * FROM T1 <first insert to query cache, using FLAGS_IN_TRANS=0>
+---+
| a |
+---+
| 1 |
+---+

```


```
BEGIN;
SELECT * FROM T1 <first insert to query cache, using FLAGS_IN_TRANS=1>
+---+
| a |
+---+
| 1 |
+---+

```


```
SELECT * FROM T1 <result from query cache, using FLAGS_IN_TRANS=1>
+---+
| a |
+---+
| 1 |
+---+

```


```
INSERT INTO T1 VALUES(2);  <invalidate queries from table T1 and disable query cache to table T1>

```


```
SELECT * FROM T1 <don't use query cache, a normal query from innodb table>
+---+
| a |
+---+
| 1 |
| 2 |
+---+

```


```
SELECT * FROM T1 <don't use query cache, a normal query from innodb table>
+---+
| a |
+---+
| 1 |
| 2 |
+---+

```


```
COMMIT;  <query cache is now turned on to T1 table>

```


```
SELECT * FROM T1 <first insert to query cache, using FLAGS_IN_TRANS=0>
+---+
| a |
+---+
| 1 |
+---+

```


```
SELECT * FROM T1 <result from query cache, using FLAGS_IN_TRANS=0>
+---+
| a |
+---+
| 1 |
+---+

```

Query Cache Internal Structure
------------------------------

 Internally, each flag that can change a result using the same query is a different query. For example, using the latin1 charset and using the utf8 charset with the same query are treated as different queries by the query cache. 

 Some fields that differentiate queries are (from "Query\_cache\_query\_flags" internal structure) :

 * query (string)
* current database schema name (string)
* client long flag (0/1)
* client protocol 4.1 (0/1)
* protocol type (internal value)
* more results exists (protocol flag)
* in trans (inside transaction or not)
* autocommit ([autocommit](../server-system-variables/index#autocommit) session variable)
* pkt\_nr (protocol flag)
* character set client ([character\_set\_client](../server-system-variables/index#character_set_client) session variable)
* character set results ([character\_set\_results](../server-system-variables/index#character_set_results) session variable)
* collation connection ([collation\_connection](../server-system-variables/index#collation_connection) session variable)
* limit ([sql\_select\_limit](../server-system-variables/index#sql_select_limit) session variable)
* time zone ([time\_zone](../server-system-variables/index#time_zone) session variable)
* sql\_mode ([sql\_mode](../server-system-variables/index#sql_mode) session variable)
* max\_sort\_length ([max\_sort\_length](../server-system-variables/index#max_sort_length) session variable)
* group\_concat\_max\_len ([group\_concat\_max\_len](../server-system-variables/index#group_concat_max_len) session variable)
* default\_week\_format ([default\_week\_format](../server-system-variables/index#default_week_format) session variable)
* div\_precision\_increment ([div\_precision\_increment](../server-system-variables/index#div_precision_increment) session variable)
* lc\_time\_names ([lc\_time\_names](../server-system-variables/index#lc_time_names) session variable)

 More information can be found by viewing the source code ([MariaDB 10.1](../what-is-mariadb-101/index)) :

 * <https://github.com/MariaDB/server/blob/10.1/sql/sql_cache.cc>
* <https://github.com/MariaDB/server/blob/10.1/sql/sql_cache.h>

 Timeout and Mutex Contention
----------------------------

 When searching for a query inside the query cache, a try\_lock function waits with a timeout of 50ms. If the lock fails, the query isn't executed via the query cache. This timeout is hard coded ([MDEV-6766](https://jira.mariadb.org/browse/MDEV-6766) include two variables to tune this timeout).

 From the sql\_cache.cc, function "try\_lock" using TIMEOUT :

 
```
        struct timespec waittime;
        set_timespec_nsec(waittime,(ulong)(50000000L));  /* Wait for 50 msec */
        int res= mysql_cond_timedwait(&COND_cache_status_changed,
                                      &structure_guard_mutex, &waittime);
        if (res == ETIMEDOUT)
          break;

```

When inserting a query inside the query cache or aborting a query cache insert (using the [KILL](../kill/index) command for example), a try\_lock function waits until the query cache returns; no timeout is used in this case.

 When two processes execute the same query, only the last process stores the query result. All other processes increase the [Qcache\_not\_cached](../server-status-variables/index#qcache_not_cached) status variable.

 SQL\_NO\_CACHE and SQL\_CACHE
-----------------------------

 There are two aspects to the query cache: placing a query in the cache, and retrieving it from the cache.

 1. Adding a query to the query cache. This is done automatically for cacheable queries (see ([Queries Stored in the Query Cache](#queries-stored-in-the-query-cache)) when the [query\_cache\_type](../server-system-variables/index#query_cache_type) system variable is set to `1`, or `ON` and the query contains no SQL\_NO\_CACHE clause, or when the [query\_cache\_type](../server-system-variables/index#query_cache_type) system variable is set to `2`, or `DEMAND`, and the query contains the SQL\_CACHE clause.
2. Retrieving a query from the cache. This is done after the server receives the query and before the query parser. In this case one point should be considered:

 When using SQL\_NO\_CACHE, it should be after the first SELECT hint, for example :

 
```
SELECT SQL_NO_CACHE .... FROM (SELECT SQL_CACHE ...) AS temp_table 

```

instead of

 
```
SELECT SQL_CACHE .... FROM (SELECT SQL_NO_CACHE ...) AS temp_table 

```

The second query will be checked. The query cache only checks if SQL\_NO\_CACHE/SQL\_CACHE exists after the first SELECT. (More info at [MDEV-6631](https://jira.mariadb.org/browse/MDEV-6631))

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-cache/>

Fusion-io
==========

   This category contains information about Fusion-io support in MariaDB

  

| Title | Description |
| --- | --- |
|  [Fusion-io Introduction](../fusion-io-introduction/index) |  Fusion-io PCIe SSD cards to speed up MariaDB.  |
|  [Atomic Write Support](../atomic-write-support/index) |  Enabling atomic writes to speed up InnoDB on selected SSD cards.  |
|  [MariaDB 10.0.15 Fusion-io Release Notes](https://mariadb.com/kb/en/mariadb-10015-fusion-io-release-notes/) |  Status: | Release Date: 12 Dec 2014  |
|  [MariaDB 10.0.15 Fusion-io Changelog](https://mariadb.com/kb/en/mariadb-10015-fusion-io-changelog/) |  Status: | Release Date: 12 Dec 2014  |
|  [InnoDB Page Flushing](../innodb-page-flushing/index) |  Configuring when and how InnoDB flushes dirty pages to disk.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/fusion-io/>

SHOW TABLE STATUS
=================

    Syntax
------

 
```
SHOW TABLE STATUS [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

  `SHOW TABLE STATUS` works like [SHOW TABLES](../show-tables/index), but provides more extensive information about each table (until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only non-TEMPORARY tables are shown).

 The `LIKE` clause, if present on its own, indicates which table names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The following information is returned:

 


| Column | Description |
| --- | --- |
| Name | Table name. |
| Engine | Table [storage engine](../storage-engines/index). |
| Version | Version number from the table's .frm file. |
| Row\_format | Row format (see [InnoDB](../innodb-storage-formats/index), [Aria](../aria-storage-formats/index) and [MyISAM](../myisam-storage-formats/index) row formats). |
| Rows | Number of rows in the table. Some engines, such as [InnoDB](../innodb/index) may store an estimate. |
| Avg\_row\_length | Average row length in the table. |
| Data\_length | For [InnoDB](../innodb/index), the index size, in pages, multiplied by the page size. For [Aria](../aria/index) and [MyISAM](../myisam/index), length of the data file, in bytes. For [MEMORY](../memory-storage-engine/index), the approximate allocated memory. |
| Max\_data\_length | Maximum length of the data file, ie the total number of bytes that could be stored in the table. Not used in [InnoDB](../innodb/index). |
| Index\_length | Length of the index file. |
| Data\_free | Bytes allocated but unused. For InnoDB tables in a shared tablespace, the free space of the shared tablespace with small safety margin. An estimate in the case of partitioned tables - see the [PARTITIONS](../information-schema-partitions-table/index) table. |
| Auto\_increment | Next [AUTO\_INCREMENT](../auto_increment/index) value. |
| Create\_time | Time the table was created. Some engines just return the ctime information from the file system layer here, in that case the value is not necessarily the table creation time but rather the time the file system metadata for it had last changed. |
| Update\_time | Time the table was last updated. On Windows, the timestamp is not updated on update, so MyISAM values will be inaccurate. In [InnoDB](../innodb/index), if shared tablespaces are used, will be `NULL`, while buffering can also delay the update, so the value will differ from the actual time of the last `UPDATE`, `INSERT` or `DELETE`. |
| Check\_time | Time the table was last checked. Not kept by all storage engines, in which case will be `NULL`. |
| Collation | [Character set and collation](../data-types-character-sets-and-collations/index). |
| Checksum | Live checksum value, if any. |
| Create\_options | Extra [CREATE TABLE](../create-table/index) options. |
| Comment | Table comment provided when MariaDB created the table. |
| Max\_index\_length | Maximum index length (supported by MyISAM and Aria tables). |
| Temporary | Until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), placeholder to signal that a table is a temporary table and always "N", except "Y" for generated information\_schema tables and NULL for views. From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), will also be set to "Y" for local temporary tables. |

 
Similar information can be found in the [information\_schema.TABLES](../information-schema-tables-table/index) table as well as by using [mariadb-show](../mariadb-show/index):

 
```
mariadb-show --status db_name

```

Views
-----

 For views, all columns in `SHOW TABLE STATUS` are `NULL` except 'Name' and 'Comment'

 Example
-------

 
```
show table status\G
*************************** 1. row ***************************
           Name: bus_routes
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 5
 Avg_row_length: 3276
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2017-05-24 11:17:46
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: 
        Comment:

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-table-status/>

SHOW CREATE TABLE
=================

    Syntax
------

 
```
SHOW CREATE TABLE tbl_name

```
 Description
-----------

 Shows the [CREATE TABLE](../create-table/index) statement that created the given table. The statement requires the [SELECT privilege](../select/index) for the table. This statement also works with [views](../views/index) and [SEQUENCE](../create-sequence/index).

 `SHOW CREATE TABLE` quotes table and column names according to the value of the [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) server system variable.

 
Certain [SQL\_MODE](../sql-mode/index) values can result in parts of the original CREATE statement not being included in the output. MariaDB-specific table options, column options, and index options are not included in the output of this statement if the [NO\_TABLE\_OPTIONS](../sql-mode/index#no_table_options), [NO\_FIELD\_OPTIONS](../sql-mode/index#no_field_options) and [NO\_KEY\_OPTIONS](../sql-mode/index#no_key_options) [SQL\_MODE](../sql-mode/index) flags are used. All MariaDB-specific table attributes are also not shown when a non-MariaDB/MySQL emulation mode is used, which includes [ANSI](../sql-mode/index#ansi), [DB2](../sql-mode/index#db2), [POSTGRESQL](../sql-mode/index#postgresql), [MSSQL](../sql-mode/index#mssql), [MAXDB](../sql-mode/index#maxdb) or [ORACLE](../sql-mode/index#oracle).

 
Invalid table options, column options and index options are normally commented out (note, that it is possible to create a table with invalid options, by altering a table of a different engine, where these options were valid). To have them uncommented, enable the [IGNORE\_BAD\_TABLE\_OPTIONS](../sql-mode/index#ignore_bad_table_options) [SQL\_MODE](../sql-mode/index). Remember that replaying a [CREATE TABLE](../create-table/index) statement with uncommented invalid options will fail with an error, unless the [IGNORE\_BAD\_TABLE\_OPTIONS](../sql-mode/index#ignore_bad_table_options) [SQL\_MODE](../sql-mode/index) is in effect.

 Note that `SHOW CREATE TABLE` is not meant to provide metadata about a table. It provides information about how the table was declared, but the real table structure could differ a bit. For example, if an index has been declared as `HASH`, the `CREATE TABLE` statement returned by `SHOW CREATE TABLE` will declare that index as `HASH`; however, it is possible that the index is in fact a `BTREE`, because the storage engine does not support `HASH`.

 MariaDB permits [TEXT](../text/index) and [BLOB](../blob/index) data types to be assigned a [DEFAULT](../create-table/index#default) value. As a result, `SHOW CREATE TABLE` will append a `DEFAULT NULL` to nullable TEXT or BLOB fields if no specific default is provided. 

 Numbers are no longer quoted in the `DEFAULT` clause in `SHOW CREATE` statement. Prior to [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), MariaDB quoted numbers. 

 ### Index Order

 Indexes are sorted and displayed in the following order, which may differ from the order of the CREATE TABLE statement.

 * PRIMARY KEY
* UNIQUE keys where all column are NOT NULL
* UNIQUE keys that don't contain partial segments
* Other UNIQUE keys
* LONG UNIQUE keys
* Normal keys
* Fulltext keys

 See sql/sql\_table.cc for details.

 Examples
--------

 
```
SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `s` char(60) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

With [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) off:

 
```
SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE t (
  id int(11) NOT NULL AUTO_INCREMENT,
  s char(60) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

Unquoted numeric DEFAULTs, from [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/):

 
```
CREATE TABLE td (link TINYINT DEFAULT 1);

SHOW CREATE TABLE td\G
*************************** 1. row ***************************
       Table: td
Create Table: CREATE TABLE `td` (
  `link` tinyint(4) DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

Quoted numeric DEFAULTs, until [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/):

 
```
CREATE TABLE td (link TINYINT DEFAULT 1);

SHOW CREATE TABLE td\G
*************************** 1. row ***************************
       Table: td
Create Table: CREATE TABLE `td` (
  `link` tinyint(4) DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

[SQL\_MODE](../sql-mode/index) impacting the output:

 
```
SELECT @@sql_mode;
+-------------------------------------------------------------------------------------------+
| @@sql_mode                                                                                |
+-------------------------------------------------------------------------------------------+
| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------+

CREATE TABLE `t1` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `msg` varchar(100) DEFAULT NULL,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1
;

SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `msg` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

SET SQL_MODE=ORACLE;

SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE "t1" (
  "id" int(11) NOT NULL,
  "msg" varchar(100) DEFAULT NULL,
  PRIMARY KEY ("id")

```

See Also
--------

 * [SHOW CREATE SEQUENCE](../show-create-sequence/index)
* [SHOW CREATE VIEW](../show-create-view/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-table/>

Atomic Write Support
====================

    Partial Write Operations
------------------------

 When Innodb writes to the filesystem, there is generally no guarantee that a given write operation will be complete (not partial) in cases of a poweroff event, or if the operating system crashes at the exact moment a write is being done.

 Without detection or prevention of partial writes, the integrity of the database can be compromised after recovery. 

 innodb\_doublewrite - an Imperfect Solution
-------------------------------------------

 Since its inception, Innodb has had a mechanism to detect and ignore partial writes via the [InnoDB Doublewrite Buffer](../xtradbinnodb-doublewrite-buffer/index) (also innodb\_checksum can be used to detect a partial write). 

 Doublewrites, controlled by the [innodb\_doublewrite](../xtradbinnodb-server-system-variables/index#innodb_doublewrite) system variable, comes with its own set of problems. Especially on SSD, writing each page twice can have detrimental effects (write leveling).

 Atomic Write - a Faster Alternative to innodb\_doublewrite
----------------------------------------------------------

 A better solution is to directly ask the filesystem to provide an atomic (all or nothing) write guarantee. Currently this is only available on [a few SSD cards](index#devices-that-support-atomic-writes-with-mariadb). 

 Enabling Atomic Writes from [MariaDB 10.2](../what-is-mariadb-102/index)
------------------------------------------------------------------------

 When starting, [MariaDB 10.2](../what-is-mariadb-102/index) and beyond automatically detects if any of the supported SSD cards are used.

 When opening an InnoDB table, there is a check if the tablespace for the table is [on a device that supports atomic writes](index#devices-that-support-atomic-writes-with-mariadb) and if yes, it will automatically enable atomic writes for the table. If atomic writes support is not detected, the doublewrite buffer will be used.

 One can disable atomic write support for all cards by setting the variable [innodb-use-atomic-writes](../xtradbinnodb-server-system-variables/index#innodb_use_atomic_writes) to `OFF` in your my.cnf file. It's `ON` by default.

 Enabling Atomic Writes in [MariaDB 5.5](../what-is-mariadb-55/index) to [MariaDB 10.1](../what-is-mariadb-101/index)
--------------------------------------------------------------------------------------------------------------------

 To use atomic writes instead of the doublewrite buffer, add:

 
```
innodb_use_atomic_writes = 1

```

to the my.cnf config file.

 Note that atomic writes are only supported on [Fusion-io devices that use the NVMFS file system](../fusion-io-introduction/index#atomic-writes) in these versions of MariaDB.

 ### About innodb\_use\_atomic\_writes (in [MariaDB 5.5](../what-is-mariadb-55/index) to [MariaDB 10.1](../what-is-mariadb-101/index))

 The following happens when atomic writes are enabled

 * if [innodb\_flush\_method](../xtradbinnodb-server-system-variables/index#innodb_flush_method) is neither `O_DIRECT`, `ALL_O_DIRECT`, or `O_DIRECT_NO_FSYNC`, it is switched to `O_DIRECT`

 * [innodb\_use\_fallocate](../xtradbinnodb-server-system-variables/index#innodb_use_fallocate) is switched `ON` (files are extended using `posix_fallocate` rather than writing zeros behind the end of file)

 * Whenever an Innodb datafile is opened, a special `ioctl()` is issued to switch on atomic writes. If the call fails, an error is logged and returned to the caller. This means that if the system tablespace is not located on an atomic write capable device or filesystem, InnoDB/XtraDB will refuse to start.

 * if [innodb\_doublewrite](../xtradbinnodb-server-system-variables/index#innodb_doublewrite) is set to `ON`, `innodb_doublewrite` will be switched `OFF` and a message written to the error log.

 Here is a flowchart showing how atomic writes work inside InnoDB:

 ![Atomic write support flow inside InnoDB]

 Devices that Support Atomic Writes with MariaDB
-----------------------------------------------

 MariaDB currently supports atomic writes on the following devices:

 * [Fusion-io devices with the NVMFS file system](../fusion-io-introduction/index#atomic-writes) . [MariaDB 5.5](../what-is-mariadb-55/index) and above.
* [Shannon SSD](http://www.shannon-sys.com). [MariaDB 10.2](../what-is-mariadb-102/index) and above.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/atomic-write-support/>

Big DELETEs
===========

    The problem
-----------

 How to [DELETE](../delete/index) lots of rows from a large table? Here is an example of purging items older than 30 days:

 
```
DELETE FROM tbl WHERE 
  ts < CURRENT_DATE() - INTERVAL 30 DAY

```

If there are millions of rows in the table, this statement may take minutes, maybe hours.

 Any suggestions on how to speed this up?

 Why it is a problem
-------------------

 * [MyISAM](../myisam/index) will lock the table during the entire operation, thereby nothing else can be done with the table.
* [InnoDB](../innodb/index) won't lock the table, but it will chew up a lot of resources, leading to sluggishness.
* InnoDB has to write the undo information to its transaction logs; this significantly increases the I/O required.
* [Replication](../replication/index), being asynchronous, will effectively be delayed (on Slaves) while the DELETE is running.

 InnoDB and undo
---------------

 To be ready for a crash, a transactional engine such as InnoDB will record what it is doing to a log file. To make that somewhat less costly, the log file is sequentially written. If the log files you have (there are usually 2) fill up because the delete is really big, then the undo information spills into the actual data blocks, leading to even more I/O.

 Deleting in chunks avoids some of this excess overhead.

 Limited benchmarking of total delete elapsed time show two observations:

 * Total delete time approximately doubles above some 'chunk' size (as opposed to below that threshold). I do not have a formula relating the log file size with the threshold cutoff.
* Chunk size below several hundred rows is slower. This is probably because the overhead of starting/ending each chunk dominates the timing.

 Solutions

 * PARTITION -- Requires some careful setup, but is excellent for purging a time-base series.
* DELETE in chunks -- Carefully walk through the table N rows at a time.

 PARTITION
---------

 The idea here is to have a sliding window of [partitions](../managing-mariadb-partitioning/index). Let's say you need to purge news articles after 30 days. The "partition key" would be the [datetime](../datetime/index) (or [timestamp](../timestamp/index)) that is to be used for purging, and the PARTITIONs would be "range". Every night, a cron job would come along and build a new partition for the next day, and drop the oldest partition.

 Dropping a partition is essentially instantaneous, much faster than deleting that many rows. However, you must design the table so that the entire partition can be dropped. That is, you cannot have some items living longer than others.

 PARTITION tables have a lot of restrictions, some are rather weird. You can either have no UNIQUE (or PRIMARY) key on the table, or every UNIQUE key must include the partition key. In this use case, the partition key is the datetime. It should not be the first part of the PRIMARY KEY (if you have a PRIMARY KEY).

 You can PARTITION InnoDB or MyISAM tables.

 Since two news articles could have the same timestamp, you cannot assume the partition key is sufficient for uniqueness of the PRIMARY KEY, so you need to find something else to help with that.

 Reference implementation for Partition maintenance

 [MariaDB docs on PARTITION](../managing-mariadb-partitioning/index)

 Deleting in chunks
------------------

 Although the discussion in this section talks about DELETE, it can be used for any other "chunking", such as, say, UPDATE, or SELECT plus some complex processing.

 (This discussion applies to both MyISAM and InnoDB.)

 When deleting in chunks, be sure to avoid doing a table scan. The code below is good at that; it scans no more than 1001 rows in any one query. (The 1000 is tunable.)

 Assuming you have news articles that need to be purged, and you have a schema something like

 
```
   CREATE TABLE tbl
      id INT UNSIGNED NOT NULL AUTO_INCREMENT,
      ts TIMESTAMP,
      ...
      PRIMARY KEY(id)

```

Then, this pseudo-code is a good way to delete the rows older than 30 days:

 
```
   @a = 0
   LOOP
      DELETE FROM tbl
         WHERE id BETWEEN @a AND @a+999
           AND ts < DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
      SET @a = @a + 1000
      sleep 1  -- be a nice guy
   UNTIL end of table

```

Notes (Most of these caveats will be covered later):

 * It uses the PK instead of the secondary key. This gives much better locality of disk hits, especially for InnoDB.
* You could (should?) do something to avoid walking through recent days but doing nothing. Caution -- the code for this could be costly.
* The 1000 should be tweaked so that the DELETE usually takes under, say, one second.
* No INDEX on ts is needed. (This helps INSERTs a little.)
* If your PRIMARY KEY is compound, the code gets messier.
* This code will not work without a numeric PRIMARY or UNIQUE key.
* Read on, we'll develop messier code to deal with most of these caveats.

 If there are big gaps in `id` values (and there will after the first purge), then

 
```
   @a = SELECT MIN(id) FROM tbl
   LOOP
      SELECT @z := id FROM tbl WHERE id >= @a ORDER BY id LIMIT 1000,1
      If @z is null
         exit LOOP  -- last chunk
      DELETE FROM tbl
         WHERE id >= @a
           AND id <  @z
           AND ts < DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
      SET @a = @z
      sleep 1  -- be a nice guy, especially in replication
   ENDLOOP
   # Last chunk:
   DELETE FROM tbl
      WHERE id >= @a
        AND ts < DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)

```

That code works whether id is numeric or character, and it mostly works even if id is not UNIQUE. With a non-unique key, the risk is that you could be caught in a loop whenever @z==@a. That can be detected and fixed thus:

 
```
   ...
      SELECT @z := id FROM tbl WHERE id >= @a ORDER BY id LIMIT 1000,1
      If @z == @a
         SELECT @z := id FROM tbl WHERE id > @a ORDER BY id LIMIT 1
   ...

```

The drawback is that there could be more than 1000 items with a single id. In most practical cases, that is unlikely.

 If you do not have a primary (or unique) key defined on the table, and you have an INDEX on ts, then consider

 
```
   LOOP
      DELETE FROM tbl
         WHERE ts < DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
         ORDER BY ts   -- to use the index, and to make it deterministic
         LIMIT 1000
   UNTIL no rows deleted

```

This technique is NOT recommended because the LIMIT leads to a warning on replication about it being non-deterministic (discussed below).

 InnoDB chunking recommendation
------------------------------

 * Have a 'reasonable' size for [innodb\_log\_file\_size](../xtradbinnodb-server-system-variables/index#innodb_log_file_size).
* Use AUTOCOMMIT=1 for the session doing the deletions.
* Pick about 1000 rows for the chunk size.
* Adjust the row count down if asynchronous replication (Statement Based) causes too much delay on the Slaves or hogs the table too much.

 Iterating through a compound key
--------------------------------

 To perform the chunked deletes recommended above, you need a way to walk through the PRIMARY KEY. This can be difficult if the PK has more than one column in it.

 To efficiently to do compound 'greater than':

 Assume that you left off at ($g, $s) (and have handled that row):

 
```
   INDEX(Genus, species)
   SELECT/DELETE ...
      WHERE Genus >= '$g' AND ( species  > '$s' OR Genus > '$g' )
      ORDER BY Genus, species
      LIMIT ...

```

Addenda: The above AND/OR works well in older versions of MySQL; this works better in MariaDB and newer versions of MySQL:

 
```
      WHERE ( Genus = '$g' AND species  > '$s' ) OR Genus > '$g' )

```

A caution about using @variables for strings. If, instead of '$g', you use @g, you need to be careful to make sure that @g has the same CHARACTER SET and COLLATION as `Genus`, else there could be a charset/collation conversion on the fly that prevents the use of the INDEX. Using the INDEX is vital for performance. It may require a COLLATE clause on SET NAMES and/or the @g in the SELECT.

 Reclaiming the disk space
-------------------------

 This is costly. (Switch to the PARTITION solution if practical.)

 MyISAM leaves gaps in the table (.MYD file); [OPTIMIZE TABLE](../optimize-table/index) will reclaim the freed space after a big delete. But it may take a long time and lock the table.

 InnoDB is block-structured, organized in a BTree on the PRIMARY KEY. An isolated deleted row leaves a block less full. A lot of deleted rows can lead to coalescing of adjacent blocks. (Blocks are normally 16KB - see [innodb\_page\_size](../xtradbinnodb-server-system-variables/index#innodb_page_size).)

 In InnoDB, there is no practical way to reclaim the freed space from ibdata1, other than to reuse the freed blocks eventually.

 The only option with [innodb\_file\_per\_table = 0](../xtradbinnodb-server-system-variables/index#innodb_file_per_table) is to dump ALL tables, remove ibdata\*, restart, and reload. That is rarely worth the effort and time.

 InnoDB, even with innodb\_file\_per\_table = 1, won't give space back to the OS, but at least it is only one table to rebuild with. In this case, something like this should work:

 
```
   CREATE TABLE new LIKE main;
   INSERT INTO new SELECT * FROM main;  -- This could take a long time
   RENAME TABLE main TO old, new TO main;   -- Atomic swap
   DROP TABLE old;   -- Space freed up here

```

You do need enough disk space for both copies. You must not write to the table during the process.

 Deleting more than half a table
-------------------------------

 The following technique can be used for any combination of

 * Deleting a large portion of the table more efficiently
* Add PARTITIONing
* Converting to [innodb\_file\_per\_table = ON](../xtradbinnodb-server-system-variables/index#innodb_file_per_table)
* Defragmenting

 This can be done by chunking, or (if practical) all at once:

 
```
   -- Optional:  SET GLOBAL innodb_file_per_table = ON;
   CREATE TABLE New LIKE Main;
   -- Optional:  ALTER TABLE New ADD PARTITION BY RANGE ...;
   -- Do this INSERT..SELECT all at once, or with chunking:
   INSERT INTO New
      SELECT * FROM Main
         WHERE ...;  -- just the rows you want to keep
   RENAME TABLE main TO Old, New TO Main;
   DROP TABLE Old;   -- Space freed up here

```

Notes:

 * You do need enough disk space for both copies.
* You must not write to the table during the process. (Changes to Main may not be reflected in New.)

 Non-deterministic replication
-----------------------------

 Any UPDATE, DELETE, etc with LIMIT that is replicated to slaves (via [Statement Based Replication](../binary-log-formats/index)) *may* cause inconsistencies between the Master and Slaves. This is because the actual order of the records discovered for updating/deleting may be different on the slave, thereby leading to a different subset being modified. To be safe, add ORDER BY to such statements. Moreover, be sure the ORDER BY is deterministic -- that is, the fields/expressions in the ORDER BY are unique.

 An example of an ORDER BY that does not quite work: Assume there are multiple rows for each 'date':

 
```
   DELETE * FROM tbl ORDER BY date LIMIT 111

```

Given that id is the PRIMARY KEY (or UNIQUE), this will be safe:

 
```
   DELETE * FROM tbl ORDER BY date, id LIMIT 111

```

Unfortunately, even with the ORDER BY, MySQL has a deficiency that leads to a bogus warning in mysqld.err. See Spurious "Statement is not safe to log in statement format." warnings

 Some of the above code avoids this spurious warning by doing

 
```
   SELECT @z := ... LIMIT 1000,1;  -- not replicated
   DELETE ... BETWEEN @a AND @z;   -- deterministic

```

That pair of statements guarantees no more than 1000 rows are touched, not the whole table.

 Replication and KILL
--------------------

 If you KILL a DELETE (or any? query) on the master in the middle of its execution, what will be replicated?

 If it is InnoDB, the query should be rolled back. (Exceptions??)

 In MyISAM, rows are DELETEd as the statement is executed, and there is no provision for ROLLBACK. Some of the rows will be deleted, some won't. You probably have no clue of how much was deleted. In a single server, simply run the delete again. The delete is put into the binlog, but with error 1317. Since replication is supposed to keep the master and slave in sync, and since it has no clue of how to do that, replication stops and waits for manual intervention. In a HA (High Available) system using replication, this is a minor disaster. Meanwhile, you need to go to each slave(s) and verify that it is stuck for this reason, then do

 
```
   SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
   START SLAVE;

```

Then (presumably) re-executing the DELETE will finish the aborted task.

 (That is yet another reason to move all your tables [from MyISAM to InnoDB](../converting-tables-from-myisam-to-innodb/index).)

 SBR vs RBR; Galera
------------------

 TBD -- "Row Based Replication" may impact this discussion.

 Postlog
-------

 The tips in this document apply to MySQL, MariaDB, and Percona. 

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/deletebig>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/big-deletes/>

Configuring Linux for MariaDB
=============================

    Linux kernel settings
---------------------

 ### IO scheduler

 For optimal IO performance running a database we are using the *none* (previously called *noop*) scheduler. Recommended schedulers are *none* and *mq-deadline* (previously called *deadline*). You can check your scheduler setting with:

 
```
cat /sys/block/${DEVICE}/queue/scheduler

```

For instance, it should look like this output:

 
```
cat /sys/block/vdb/queue/scheduler
[none] mq-deadline kyber bfq

```

Older kernels may look like:

 
```
cat /sys/block/sda/queue/scheduler
[noop] deadline cfq

```

Writing the new scheduler name to the same /sys node will change the scheduler:

 
```
echo mq-deadline >  /sys/block/vdb/queue/scheduler

```

The impact of schedulers depend significantly on workload and hardware. You can measure the IO-latency using the [biolatency](https://github.com/iovisor/bcc/blob/master/tools/biolatency_example.txt) bcc-tools script with an aim to keep the mean as low as possible.

 Resource Limits
---------------

 ### Configuring the Open Files Limit

 By default, the system limits how many open file descriptors a process can have open at one time. It has both a soft and hard limit. On many systems, both the soft and hard limit default to 1024. On an active database server, it is very easy to exceed 1024 open file descriptors. Therefore, you may need to increase the soft and hard limits. There are a few ways to do so.

 If you are using `[mysqld\_safe](../mysqld_safe/index)` to start `mysqld`, then see the instructions at [mysqld\_safe: Configuring the Open Files Limit](../mysqld_safe/index#configuring-the-open-files-limit).

 If you are using `[systemd](../systemd/index)` to start `mysqld`, then see the instructions at [systemd: Configuring the Open Files Limit](../systemd/index#configuring-the-open-files-limit).

 Otherwise, you can set the soft and hard limits for the `mysql` user account by adding the following lines to `[/etc/security/limits.conf](https://linux.die.net/man/5/limits.conf)`:

 
```
mysql soft nofile 65535
mysql hard nofile 65535

```

After the system is rebooted, the `mysql` user should use the new limits, and the user's `ulimit` output should look like the following:

 
```
$ ulimit -Sn
65535
$ ulimit -Hn
65535

```

### Configuring the Core File Size

 By default, the system limits the size of core files that could be created. It has both a soft and hard limit. On many systems, the soft limit defaults to 0. If you want to [enable core dumps](../enabling-core-dumps/index), then you may need to increase this. Therefore, you may need to increase the soft and hard limits. There are a few ways to do so.

 If you are using `[mysqld\_safe](../mysqld_safe/index)` to start `mysqld`, then see the instructions at [mysqld\_safe: Configuring the Core File Size](../mysqld_safe/index#configuring-the-core-file-size).

 If you are using `[systemd](../systemd/index)` to start `mysqld`, then see the instructions at [systemd: Configuring the Core File Size](../systemd/index#configuring-the-core-file-size).

 Otherwise, you can set the soft and hard limits for the `mysql` user account by adding the following lines to `[/etc/security/limits.conf](https://linux.die.net/man/5/limits.conf)`:

 
```
mysql soft core unlimited
mysql hard core unlimited

```

After the system is rebooted, the `mysql` user should use the new limits, and the user's `ulimit` output should look like the following:

 
```
$ ulimit -Sc
unlimited
$ ulimit -Hc
unlimited

```

Swappiness
----------

 See [configuring swappiness](../configuring-swappiness/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-linux-for-mariadb/>

Configuring MariaDB for Optimal Performance
===========================================

     This article is to help you configure MariaDB for optimal performance.

 Note that by default MariaDB is configured to work on a desktop system and should because of this not take a lot of resources. To get things to work for a dedicated server, you have to do a few minutes of work.

 For this article we assume that you are going to run MariaDB on a dedicated server.

 Feel free to update this article if you have more ideas.

 
[my.cnf](../configuring-mariadb-with-mycnf/index) Files
--------------------------------------------------------

 MariaDB is normally configured by editing the [my.cnf](../mysqld-configuration-files-and-groups/index) file.

 The following my.cnf example files were included with MariaDB until [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/). If present, you can examine them to see more complete examples of some of the many ways to configure MariaDB and use the one that fits you best as a base. Note that these files are now quite outdated, so what was huge a few years ago may no longer be seen as such.

 * my-small.cnf
* my-medium.cnf
* my-large.cnf
* my-huge.cnf

 
[InnoDB](../innodb/index) Storage Engine
-----------------------------------------

 InnoDB is normally the default storage engine with MariaDB.

 * You should set [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) to about 80% of your memory. The goal is to ensure that 80 % of your working set is in memory.

 The other most important InnoDB variables are:

 * [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size)
* [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method)
* [innodb\_thread\_sleep\_delay](../innodb-system-variables/index#innodb_thread_sleep_delay)

 Some other important InnoDB variables:

 * [innodb\_adaptive\_max\_sleep\_delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay)
* [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances)
* [innodb\_max\_dirty\_pages\_pct\_lwm](../innodb-system-variables/index#innodb_max_dirty_pages_pct_lwm)
* [innodb\_read\_ahead\_threshold](../innodb-system-variables/index#innodb_read_ahead_threshold)
* [innodb\_thread\_concurrency](../innodb-system-variables/index#innodb_thread_concurrency)

 
[Aria](../aria-storage-engine/index) Storage Engine
----------------------------------------------------

 * MariaDB uses by default the Aria storage engine for internal temporary files. If you have many temporary files, you should set [aria\_pagecache\_buffer\_size](../aria-server-system-variables/index#aria_pagecache_buffer_size) to a reasonably large value so that temporary overflow data is not flushed to disk. The default is 128M.

 [MyISAM](../myisam/index)
-------------------------

 * If you don't use MyISAM tables explicitly (true for most [MariaDB 10.4](../what-is-mariadb-104/index)+ users), you can set [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) to a very low value, like 64K.

 Lots of Connections
-------------------

 ### A Lot of Fast Connections + Small Set of Queries + Disconnects

 * If you are doing a lot of fast connections / disconnects, you should increase [back\_log](../server-system-variables/index#back_log) and if you are running [MariaDB 10.1](../what-is-mariadb-101/index) or below [thread\_cache\_size](../server-system-variables/index#thread_cache_size).
* If you have a lot (> 128) of simultaneous running fast queries, you should consider setting [thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling) to `pool_of_threads`.

 ### Connecting From a Lot of Different Machines

 * If you are connecting from a lot of different machines you should increase [host\_cache\_size](../server-system-variables/index#host_cache_size) to the max number of machines (default 128) to cache the resolving of hostnames. If you don't connect from a lot of machines, you can set this to a very low value!

 See Also
--------

 * [MariaDB Memory Allocation](../mariadb-memory-allocation/index)
* [Full List of MariaDB Options, System and Status Variables](../full-list-of-mariadb-options-system-and-status-variables/index)
* [Server system variables](../server-system-variables/index)
* [mysqld options](../mysqld-options-full-list/index)
* [Performance schema](../performance-schema/index) helps you understand what is taking time and resources.
* [Slow query log](../slow-query-log/index) is used to find queries that are running slow.
* [OPTIMIZE TABLE](../optimize-table/index) helps you defragment tables.

 External Links
--------------

 * <http://www.tocker.ca/2013/09/17/what-to-tune-in-mysql-56-after-installation.html>
* <http://www.percona.com/resources/technical-presentations/optimizing-mysql-configuration-percona-mysql-university-montevideo>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-mariadb-for-optimal-performance/>

Configuring Swappiness
======================

    Why to Avoid Swapping
---------------------

 Obviously, accessing swap memory from disk is far slower than accessing RAM directly. This is particularly bad on a database server because:

 * MariaDB's internal algorithms assume that memory is not swap, and are highly inefficient if it is. Some algorithms are intended to avoid or delay disk IO, and use memory where possible - performing this with swap can be worse than just doing it on disk in the first place.
* Swap increases IO over just using disk in the first place as pages are actively swapped in and out of swap. Even something like removing a dirty page that is no longer going to be stored in memory, while designed to improve efficiency, will under a swap situation cost more IO.
* Database locks are particularly inefficient in swap. They are designed to be obtained and released often and quickly, and pausing to perform disk IO will have a serious impact on their usability.

 The main way to avoid swapping is to make sure you have enough RAM for all processes that need to run on the machine. Setting the [system variables](../system-variables/index) too high can mean that under load the server runs short of memory, and needs to use swap. So understanding what settings to use and how these impact your server's memory usage is critical.

 Setting Swappiness on Linux
---------------------------

 Linux has a swappiness setting which determines the balance between swapping out pages (chunks of memory) from RAM to a preconfigured swap space on the hard drive. 

 The setting is from 0 to 100, with lower values meaning a lower likelihood of swapping. The default is usually 60 - you can check this by running:

 
```
sysctl vm.swappiness

```

The default setting encourages the server to use swap. Since there probably won't be much else on the database server besides MariaDB processes to put into swap, you'll probably want to reduce this to zero to avoid swapping as much as possible. You can change the default by adding a line to the `sysctl.conf` file (usually found in `/etc/sysctl.conf`).

 To set the swappiness to zero, add the line:

 
```
vm.swappiness = 0

```

This normally takes effect after a reboot, but you can change the value without rebooting as follows:

 
```
sysctl -w vm.swappiness=0

```


Since RHEL 6.4, setting swappiness=0 more aggressively avoids swapping out, which increases the risk of OOM killing under strong memory and I/O pressure.

 
A low swappiness setting is recommended for database workloads. For MariaDB databases, it is recommended to set swappiness to a value of 1.

 
```
vm.swappiness = 1

```

Disabling Swap Altogether
-------------------------

 While some disable swap altogether, and you certainly want to avoid any database processes from using it, it can be prudent to leave some swap space to at least allow the kernel to fall over gracefully should a spike occur. Having emergency swap available at least allows you some scope to kill any runaway processes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-swappiness/>

SHUTDOWN
========

    Syntax
------

 
```
SHUTDOWN [WAIT FOR ALL { SLAVES | REPLICAS } ]

```

Description
-----------

 The `SHUTDOWN` command shuts the server down. 

 WAIT FOR ALL REPLICAS / SLAVES
------------------------------

 
**MariaDB starting with [10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/)**The `WAIT FOR ALL SLAVES` option was first added in [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/). `WAIT FOR ALL REPLICAS` has been a synonym since [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/).

 
When a primary server is shutdown and it goes through the normal shutdown process, the primary kills client threads in random order. By default, the primary also considers its binary log dump threads to be regular client threads. As a consequence, the binary log dump threads can be killed while client threads still exist, and this means that data can be written on the primary during a normal shutdown that won't be replicated. This is true even if [semi-synchronous replication](../semisynchronous-replication/index) is being used.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this problem can be solved by shutting down the server with the [SHUTDOWN](index) command and by providing the `WAIT FOR ALL REPLICAS`/`WAIT FOR ALL SLAVES` option to the command. For example:

 
```
SHUTDOWN WAIT FOR ALL REPLICAS;

```

When the `WAIT FOR ALL REPLICAS` option is provided, the server only kills its binary log dump threads after all client threads have been killed, and it only completes the shutdown after the last [binary log](../binary-log/index) has been sent to all connected replicas.

 See [Replication Threads: Binary Log Dump Threads and the Shutdown Process](../replication-threads/index#binary-log-dump-threads-and-the-shutdown-process) for more information.

 Required Permissions
--------------------

 One must have a `SHUTDOWN` privilege (see [GRANT](../grant/index)) to use this command. It is the same privilege one needs to use the [mariadb-admin shutdown](../mariadb-admin/index#mariadb-admin-commands) command.

 Shutdown for Upgrades
---------------------

 If you are doing a shutdown to [migrate to another major version of MariaDB](upgrading-between-major-mariadb-version), please ensure that the [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) variable is not 2 (fast crash shutdown). The default of this variable is 1.

 Example
-------

 The following example shows how to create an [event](../stored-programs-and-views-events/index) which turns off the server at a certain time:

 
```
CREATE EVENT `test`.`shutd`
    ON SCHEDULE
        EVERY 1 DAY
        STARTS '2014-01-01 20:00:00'
    COMMENT 'Shutdown Maria when the office is closed'
DO BEGIN
    SHUTDOWN;
END;

```

Other Ways to Stop mariadbd
---------------------------

 You can use the [mariadb-admin shutdown](../mariadb-admin/index) command to take down mariadbd cleanly.

 You can also use the system kill command on Unix with signal SIGTERM (15)

 
```
kill -SIGTERM pid-of-mariadbd-process

```

You can find the process number of the server process in the file that ends with `.pid` in your data directory.

 The above is identical to `mariadb-admin shutdown`.

 On windows you should use:

 
```
NET STOP MariaDB

```

See Also
--------

 * [mariadb-admin shutdown](../mariadb-admin/index).
* [InnoDB fast shutdown option](../innodb-system-variables/index#innodb_fast_shutdown)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/shutdown/>

InnoDB System Variables
=======================

     This page documents system variables related to the [InnoDB storage engine](../innodb/index). For options that are not system variables, see [InnoDB Options](../mysqld-options/index#innodb-options).

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 Also see the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index).

 #### `have_innodb`

 * **Description:** If the server supports [InnoDB tables](../innodb/index), will be set to `YES`, otherwise will be set to `NO`. Removed in [MariaDB 10.0](../what-is-mariadb-100/index), use the [Information Schema PLUGINS](../information-schema-plugins-table/index) table or [SHOW ENGINES](../show-engines/index) instead.
* **Scope:** Global
* **Dynamic:** No
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `ignore_builtin_innodb`

 * **Description:** Setting this to `1` results in the built-in InnoDB storage engine being ignored. In some versions of MariaDB, XtraDB is the default and is always present, so this variable is ignored and setting it results in a warning. From [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) to [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-1008-release-notes/), when InnoDB was the default instead of XtraDB, this variable needed to be set. Usually used in conjunction with the [plugin-load=innodb=ha\_innodb](../mysqld-options/index#-plugin-load) option to use the InnoDB plugin.
* **Commandline:** `--ignore-builtin-innodb`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_adaptive_checkpoint`

 * **Description:** Replaced with [innodb\_adaptive\_flushing\_method](#innodb_adaptive_flushing_method). Controls adaptive checkpointing. InnoDB's fuzzy checkpointing can cause stalls, as many dirty blocks are flushed at once as the checkpoint age nears the maximum. Adaptive checkpointing aims for more consistent flushing, approximately `modified age / maximum checkpoint age`. Can result in larger transaction log files
	+ `reflex` Similar to [innodb\_max\_dirty\_pages\_pct](#innodb_max_dirty_pages_pct) flushing but flushes blocks constantly and contiguously based on the oldest modified age. If the age exceeds 1/2 of the maximum age capacity, flushing will be weak contiguous. If the age exceeds 3/4, flushing will be strong. Strength can be adjusted by the variable [innodb\_io\_capacity](#innodb_io_capacity).
	+ `estimate` The default, and independent of [innodb\_io\_capacity](#innodb_io_capacity). If the oldest modified age exceeds 1/2 of the maximum age capacity, blocks will be flushed every second at a rate determined by the number of modified blocks, LSN progress speed and the average age of all modified blocks.
	+ `keep_average` Attempts to keep the I/O rate constant by using a shorter loop cycle of one tenth of a second. Designed for SSD cards.
* **Commandline:** `--innodb-adaptive-checkpoint=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `estimate`
* **Valid Values:** `none` or `0`, `reflex` or `1`, `estimate` or `2`, `keep_average` or `3`
* **Removed:** XtraDB 5.5 - replaced with [innodb\_adaptive\_flushing\_method](#innodb_adaptive_flushing_method)

 

---

 #### `innodb_adaptive_flushing`

 * **Description:** If set to `1`, the default, the server will dynamically adjust the flush rate of dirty pages in the [InnoDB buffer pool](../innodb-buffer-pool/index). This assists to reduce brief bursts of I/O activity. If set to `0`, adaptive flushing will only take place when the limit specified by [innodb\_adaptive\_flushing\_lwm](#innodb_adaptive_flushing_lwm) is reached.
* **Commandline:** `--innodb-adaptive-flushing={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_adaptive_flushing_lwm`

 * **Description:** Adaptive flushing is enabled when this low water mark percentage of the [InnoDB redo log](../innodb-redo-log/index) capacity is reached. Takes effect even if [innodb\_adaptive\_flushing](#innodb_adaptive_flushing) is disabled.
* **Commandline:** `--innodb-adaptive-flushing-lwm=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `double`
* **Default Value:** `10.000000`
* **Range:** `0` to `70`

 

---

 #### `innodb_adaptive_flushing_method`

 * **Description:** Determines the method of flushing dirty blocks from the InnoDB [buffer pool](../innodb-buffer-pool/index). If set to `native` or `0`, the original InnoDB method is used. The maximum checkpoint age is determined by the total length of all transaction log files. When the checkpoint age reaches the maximum checkpoint age, blocks are flushed. This can cause lag if there are many updates per second and many blocks with an almost identical age need to be flushed. If set to `estimate` or `1`, the default, the oldest modified age will be compared with the maximum age capacity. If it's more than 1/4 of this age, blocks are flushed every second. The number of blocks flushed is determined by the number of modified blocks, the LSN progress speed and the average age of all modified blocks. It's therefore independent of the [innodb\_io\_capacity](#innodb_io_capacity) for the 1-second loop, but not entirely so for the 10-second loop. If set to `keep_average` or `2`, designed specifically for SSD cards, a shorter loop cycle is used in an attempt to keep the I/O rate constant. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced with InnoDB flushing method from MySQL 5.6.
* **Commandline:** `innodb-adaptive-flushing-method=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `estimate`
* **Valid Values:** `native` or `0`, `estimate` or `1`, `keep_average` or `2`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced with InnoDB flushing method from MySQL 5.6

 

---

 #### `innodb_adaptive_hash_index`

 * **Description:** If set to `1`, the default until [MariaDB 10.5](../what-is-mariadb-105/index), the [InnoDB](../innodb/index) hash index is enabled. Based on performance testing ([MDEV-17492](https://jira.mariadb.org/browse/MDEV-17492)), the InnoDB adaptive hash index helps performance in mostly read-only workloads, and could slow down performance in other environments, especially [DROP TABLE](../drop-table/index), [TRUNCATE TABLE](../truncate-table/index), [ALTER TABLE](../alter-table/index), or [DROP INDEX](../drop-index/index) operations.
* **Commandline:** `--innodb-adaptive-hash-index={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF` (>= [MariaDB 10.5](../what-is-mariadb-105/index)), `ON` (<= [MariaDB 10.4](../what-is-mariadb-104/index))

 

---

 #### `innodb_adaptive_hash_index_partitions`

 * **Description:** Specifies the number of partitions for use in adaptive searching. If set to `1`, no extra partitions are created. XtraDB-only. From [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB), this is an alias for [innodb\_adaptive\_hash\_index\_parts](#innodb_adaptive_hash_index_parts) to allow for easier upgrades.
* **Commandline:** `innodb-adaptive-hash-index-partitions=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `64`

 

---

 #### `innodb_adaptive_hash_index_parts`

 * **Description:** Specifies the number of partitions for use in adaptive searching. If set to `1`, no extra partitions are created.
* **Commandline:** `innodb-adaptive-hash-index-parts=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `1` to `512`

 

---

 #### `innodb_adaptive_max_sleep_delay`

 * **Description:** Maximum time in microseconds to automatically adjust the [innodb\_thread\_sleep\_delay](#innodb_thread_sleep_delay) value to, based on the workload. Useful in extremely busy systems with hundreds of thousands of simultaneous connections. `0` disables any limit. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).
* **Commandline:** `--innodb-adaptive-max-sleep-delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `0` (>= [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/))
	+ `150000` (<= [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))
* **Range:** `0` to `1000000`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_additional_mem_pool_size`

 * **Description:** Size in bytes of the [InnoDB](../innodb/index) memory pool used for storing information about internal data structures. Defaults to 8MB, if your application has many tables and a large structure, and this is exceeded, operating system memory will be allocated and warning messages written to the error log, in which case you should increase this value. Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index) and removed in [MariaDB 10.2](../what-is-mariadb-102/index) along with InnoDB's internal memory allocator.
* **Commandline:** `--innodb-additional-mem-pool-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8388608`
* **Range:** `2097152` to `4294967295`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `innodb_api_bk_commit_interval`

 * **Description:** Time in seconds between auto-commits for idle connections using the InnoDB memcached interface (not implemented in MariaDB).
* **Commandline:** `--innodb-api-bk-commit-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `5`
* **Range:** `1` to `1073741824`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `innodb_api_disable_rowlock`

 * **Description:** For use with MySQL's memcached (not implemented in MariaDB)
* **Commandline:** `--innodb-api-disable-rowlock={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `innodb_api_enable_binlog`

 * **Description:** For use with MySQL's memcached (not implemented in MariaDB)
* **Commandline:** `--innodb-api-enable-binlog={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `innodb_api_enable_mdl`

 * **Description:** For use with MySQL's memcached (not implemented in MariaDB)
* **Commandline:** `--innodb-api-enable-mdl={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `innodb_api_trx_level`

 * **Description:** For use with MySQL's memcached (not implemented in MariaDB)
* **Commandline:** `--innodb-api-trx-level=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `innodb_auto_lru_dump`

 * **Description:** Renamed [innodb\_buffer\_pool\_restore\_at\_startup](#innodb_buffer_pool_restore_at_startup) since XtraDB 5.5.10-20.1, which was in turn replaced by [innodb\_buffer\_pool\_load\_at\_startup](#innodb_buffer_pool_load_at_startup) in [MariaDB 10.0](../what-is-mariadb-100/index).
* **Commandline:** `--innodb-auto-lru-dump=#`
* **Removed:** XtraDB 5.5.10-20.1

 

---

 #### `innodb_autoextend_increment`

 * **Description:** Size in MB to increment an auto-extending shared tablespace file when it becomes full. If [innodb\_file\_per\_table](#innodb_file_per_table) was set to `1`, this setting does not apply to the resulting per-table tablespace files, which are automatically extended in their own way.
* **Commandline:** `--innodb-autoextend-increment=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `64` (from [MariaDB 10.0](../what-is-mariadb-100/index)) `8` (before [MariaDB 10.0](../what-is-mariadb-100/index)),
* **Range:** `1` to `1000`

 

---

 #### `innodb_autoinc_lock_mode`

 * **Description:** The lock mode that is used when generating `[AUTO\_INCREMENT](../auto_increment/index)` values for InnoDB tables.
	+ Valid values are:
		- `0` is the traditional lock mode.
		- `1` is the consecutive lock mode.
		- `2` is the interleaved lock mode.
	+ In order to use [Galera Cluster](../galera/index), the lock mode needs to be set to `2`.
	+ See [AUTO\_INCREMENT Handling in InnoDB: AUTO\_INCREMENT Lock Modes](../auto_increment-handling-in-xtradbinnodb/index#auto_increment-lock-modes) for more information.
* **Commandline:** `--innodb-autoinc-lock-mode=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `2`

 

---

 #### `innodb_background_scrub_data_check_interval`

 * **Description:** Check if spaces needs scrubbing every [innodb\_background\_scrub\_data\_check\_interval](#innodb_background_scrub_data_check_interval) seconds. See [Data Scrubbing](../innodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Commandline:** `--innodb-background-scrub-data-check-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `3600`
* **Range:** `1` to `4294967295`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_background_scrub_data_compressed`

 * **Description:** Enable scrubbing of compressed data by background threads (same as encryption\_threads). See [Data Scrubbing](../innodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Commandline:** `--innodb-background-scrub-data-compressed={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_background_scrub_data_interval`

 * **Description:** Scrub spaces that were last scrubbed longer than this number of seconds ago. See [Data Scrubbing](../innodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Commandline:** `--innodb-background-scrub-data-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `604800`
* **Range:** `1` to `4294967295`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_background_scrub_data_uncompressed`

 * **Description:** Enable scrubbing of uncompressed data by background threads (same as encryption\_threads). See [Data Scrubbing](../innodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Commandline:** `--innodb-background-scrub-data-uncompressed={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_blocking_buffer_pool_restore`

 * **Description:** If set to `1` (`0` is default), XtraDB will wait until the least-recently used (LRU) dump is completely restored upon restart before reporting back to the server that it has successfully started up. Available with XtraDB only, not InnoDB.
* **Commandline:** `innodb-blocking-buffer-pool-restore={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `innodb_buf_dump_status_frequency`

 * **Description:** Determines how often (as a percent) the buffer pool dump status should be printed in the logs. For example, `10` means that the buffer pool dump status is printed when every 10% of the number of buffer pool pages are dumped. The default is `0` (only start and end status is printed).
* **Commandline:** `--innodb-buf-dump-status-frequency=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `100`

 

---

 #### `innodb_buffer_pool_chunk_size`

 * **Description:** Chunk size used for dynamically resizing the [buffer pool](../innodb-buffer-pool/index). Note that changing this setting can change the size of the buffer pool. When [large-pages](../server-system-variables/index#large_pages) is used this value is effectively rounded up to the next multiple of [large-page-size](../server-system-variables/index#large_page_size). See [Setting Innodb Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index). From [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/), the variable is autosized based on the [buffer pool size](../innodb-buffer-pool/index).
* **Commandline:** `--innodb-buffer-pool-chunk-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**
	+ `autosize (0)`, resulting in [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size)/64, if [large\_pages](../server-system-variables/index#large_pages) round down to multiple of largest page size, with 1MiB minimum (>= [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/))
	+ `134217728` (<= [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/))
* **Range:**
	+ `0`, as autosize, and then `1048576` to `18446744073709551615` (>= [MariaDB 10.8](../what-is-mariadb-108/index))
	+ `1048576` to [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size)/[innodb\_buffer\_pool\_instances](#innodb_buffer_pool_instances) (<= [MariaDB 10.7](../what-is-mariadb-107/index))

 

---

 #### `innodb_buffer_pool_dump_at_shutdown`

 * **Description:** Whether to record pages cached in the [buffer pool](../innodb-buffer-pool/index) on server shutdown, which reduces the length of the warmup the next time the server starts. The related [innodb\_buffer\_pool\_load\_at\_startup](#innodb_buffer_pool_load_at_startup) specifies whether the buffer pool is automatically warmed up at startup.
* **Commandline:** `--innodb-buffer-pool-dump-at-shutdown={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`

 

---

 #### `innodb_buffer_pool_dump_now`

 * **Description:** Immediately records pages stored in the [buffer pool](../innodb-buffer-pool/index). The related [innodb\_buffer\_pool\_load\_now](#innodb_buffer_pool_load_now) does the reverse, and will immediately warm up the buffer pool.
* **Commandline:** `--innodb-buffer-pool-dump-now={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_buffer_pool_dump_pct`

 * **Description:** Dump only the hottest N% of each [buffer pool](../innodb-buffer-pool/index).
* **Commandline:** `--innodb-buffer-pool-dump-pct={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `25`
* **Range:** `1` to `100`

 

---

 #### `innodb_buffer_pool_evict`

 * **Description:** Evict pages from the buffer pool. If set to "uncompressed" then all uncompressed pages are evicted from the buffer pool. Variable to be used only for testing. Only exists in DEBUG builds.
* **Commandline:** `--innodb-buffer-pool-evict=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `""`
* **Valid Values:** "" or "uncompressed"

 

---

 #### `innodb_buffer_pool_filename`

 * **Description:** The file that holds the [buffer pool](../innodb-buffer-pool/index) list of page numbers set by [innodb\_buffer\_pool\_dump\_at\_shutdown](#innodb_buffer_pool_dump_at_shutdown) and [innodb\_buffer\_pool\_dump\_now](#innodb_buffer_pool_dump_now).
* **Commandline:** `--innodb-buffer-pool-filename=file`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `ib_buffer_pool`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_buffer_pool_instances`

 * **Description:** If [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size) is set to more than 1GB, innodb\_buffer\_pool\_instances divides the [InnoDB](../innodb/index) buffer pool into this many instances. The default was 1 in [MariaDB 5.5](../what-is-mariadb-55/index), but for large systems with buffer pools of many gigabytes, many instances can help reduce contention concurrency. The default is 8 in MariaDB 10 (except on Windows 32-bit, where it varies according to [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size), or from [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), where it is set to 1 if [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size) < 1GB). Each instance manages its own data structures and takes an equal portion of the total buffer pool size, so for example if innodb\_buffer\_pool\_size is 4GB and innodb\_buffer\_pool\_instances is set to 4, each instance will be 1GB. Each instance should ideally be at least 1GB in size. Deprecated and ignored from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), as the original reasons for for splitting the buffer pool have mostly gone away.
* **Commandline:** `--innodb-buffer-pool-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** >= [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/): `8`, `1` (>= [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) if [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size) < 1GB), or dependent on [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size) (Windows 32-bit)
* **Deprecated:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_buffer_pool_load_abort`

 * **Description:** Aborts the process of restoring [buffer pool](../innodb-buffer-pool/index) contents started by [innodb\_buffer\_pool\_load\_at\_startup](#innodb_buffer_pool_load_at_startup) or [innodb\_buffer\_pool\_load\_now](#innodb_buffer_pool_load_now).
* **Commandline:** `--innodb-buffer-pool-load-abort={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_buffer_pool_load_at_startup`

 * **Description:** Specifies whether the [buffer pool](../innodb-buffer-pool/index) is automatically warmed up when the server starts by loading the pages held earlier. The related [innodb\_buffer\_pool\_dump\_at\_shutdown](#innodb_buffer_pool_dump_at_shutdown) specifies whether pages are saved at shutdown. If the buffer pool is large and taking a long time to load, increasing [innodb\_io\_capacity](#innodb_io_capacity) at startup may help.
* **Commandline:** `--innodb-buffer-pool-load-at-startup={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`

 

---

 #### `innodb_buffer_pool_load_now`

 * **Description:** Immediately warms up the [buffer pool](../innodb-buffer-pool/index) by loading the stored data pages. The related [innodb\_buffer\_pool\_dump\_now](#innodb_buffer_pool_dump_now) does the reverse, and immediately records pages stored in the buffer pool.
* **Commandline:** `--innodb-buffer-pool-load-now={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_buffer_pool_load_pages_abort`

 * **Description:** Number of pages during a buffer pool load to process before signaling [innodb\_buffer\_pool\_load\_abort=1](#innodb_buffer_pool_load_abort). Debug builds only.
* **Commandline:** `--innodb-buffer-pool-load-pages-abort=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `9223372036854775807`
* **Range:** `1` to `9223372036854775807`
* **Introduced:** [MariaDB 10.3](../what-is-mariadb-103/index)

 

---

 #### `innodb_buffer_pool_populate`

 * **Description:** When set to `1` (`0` is default), XtraDB will preallocate pages in the buffer pool on starting up so that NUMA allocation decisions are made while the buffer cache is still clean. XtraDB only. This option was made ineffective in [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/). Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-buffer-pool-populate={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_buffer_pool_restore_at_startup`

 * **Description:** Time in seconds between automatic buffer pool dumps. If set to a non-zero value, XtraDB will also perform an automatic restore of the [buffer pool](../innodb-buffer-pool/index) at startup. If set to `0`, automatic dumps are not performed, nor automatic restores on startup. Replaced by [innodb\_buffer\_pool\_load\_at\_startup](#innodb_buffer_pool_load_at_startup) in [MariaDB 10.0](../what-is-mariadb-100/index).
* **Commandline:** `innodb-buffer-pool-restore-at-startup`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range - 32 bit:** `0` to `4294967295`
* **Range - 64 bit:** `0` to `18446744073709547520`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced by [innodb\_buffer\_pool\_load\_at\_startup](#innodb_buffer_pool_load_at_startup)

 

---

 #### `innodb_buffer_pool_shm_checksum`

 * **Description:** Used with Percona's SHM buffer pool patch in XtraDB 5.5. Was shortly deprecated and removed in XtraDB 5.6. XtraDB only.
* **Commandline:** `innodb-buffer-pool-shm-checksum={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_buffer_pool_shm_key`

 * **Description:** Used with Percona's SHM buffer pool patch in XtraDB 5.5. Later deprecated in XtraDB 5.5, and removed in XtraDB 5.6.
* **Commandline:** `innodb-buffer-pool-shm-key={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_buffer_pool_size`

 * **Description:** InnoDB buffer pool size in bytes. The primary value to adjust on a database server with entirely/primarily [InnoDB](../innodb/index) tables, can be set up to 80% of the total memory in these environments. See the [InnoDB Buffer Pool](../innodb-buffer-pool/index) for more on setting this variable, and also [Setting InnoDB Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index) if doing so dynamically.
* **Commandline:** `--innodb-buffer-pool-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `134217728` (128iMB)
* **Range:**
	+ Minimum: `5242880` (5MiB ) for [InnoDB Page Size](innodb-page-size) <= 16k otherwise `25165824` (24MiB) for [InnoDB Page Size](innodb-page-size) > 16k (for versions less than next line)
	+ Minimium: `2MiB` [InnoDB Page Size](innodb-page-size) = 4k, `3MiB` [InnoDB Page Size](innodb-page-size) = 8k, `5MiB` [InnoDB Page Size](innodb-page-size) = 16k, `10MiB` [InnoDB Page Size](innodb-page-size) = 32k, `20MiB` [InnoDB Page Size](innodb-page-size) = 64k, (>= [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10242-release-notes/), >= [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10333-release-notes/), >= [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10423-release-notes/), >= [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), >= [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), >= [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/))
	+ Minimum: 1GiB for [innodb\_buffer\_pool\_instances](#innodb_buffer_pool_instances) > 1 (<= [MariaDB 10.7](../what-is-mariadb-107/index))
	+ Maximium: `9223372036854775807` (8192PB) (all versions)

 

---

 #### `innodb_change_buffer_dump`

 * **Description:** If set, causes the contents of the InnoDB change buffer to be dumped to the server error log at startup. Only available in debug builds.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10228-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-1049-release-notes/)

 

---

 #### `innodb_change_buffer_max_size`

 * **Description:** Maximum size of the [InnoDB Change Buffer](../innodb-change-buffering/index) as a percentage of the total buffer pool. The default is 25%, and this can be increased up to 50% for servers with high write activity, and lowered down to 0 for servers used exclusively for reporting.
* **Commandline:** `--innodb-change-buffer-max-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `25`
* **Range:** `0` to `50`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Deprecated:** [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/)
* **Removed:** [MariaDB 11.0.0](../mdb-11-0-0-rn/index)

 

---

 #### `innodb_change_buffering`

 * **Description:** Sets how [InnoDB](../innodb/index) change buffering is performed. See [InnoDB Change Buffering](../innodb-change-buffering/index) for details on the settings. Deprecated and ignored from [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/).
* **Commandline:** `--innodb-change-buffering=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration` (>= [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)), `string` (<= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/))
* **Default Value:**
	+ >= [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10515-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-1067-release-notes/), [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-1073-release-notes/), [MariaDB 10.8.2](https://mariadb.com/kb/en/mariadb-1082-release-notes/): `none`
	+ <= [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/), [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/):`all`
* **Valid Values:** `inserts`, `none`, `deletes`, `purges`, `changes`, `all`
* **Deprecated:** [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/)
* **Removed:** [MariaDB 11.0.0](../mdb-11-0-0-rn/index)

 

---

 #### `innodb_change_buffering_debug`

 * **Description:** If set to `1`, an [InnoDB Change Buffering](../innodb-change-buffering/index) debug flag is set. `1` forces all changes to the change buffer, while `2` causes a crash at merge. `0`, the default, indicates no flag is set. Only available in debug builds.
* **Commandline:** `--innodb-change-buffering-debug=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2`

 

---

 #### `innodb_checkpoint_age_target`

 * **Description:** The maximum value of the checkpoint age. If set to `0`, has no effect. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced with InnoDB flushing method from MySQL 5.6.
* **Commandline:** `innodb-checkpoint-age-target=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` upwards
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced with InnoDB flushing method from MySQL 5.6.

 

---

 #### `innodb_checksum_algorithm`

 * **Description:** Specifies how the InnoDB tablespace checksum is generated and verified.
	+ `innodb`: Backwards compatible with earlier versions (<= [MariaDB 5.5](../what-is-mariadb-55/index)). Deprecated in [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/) and removed in [MariaDB 10.6](../what-is-mariadb-106/index). If really needed, data files can still be converted with [innochecksum](../innochecksum/index).
	+ `crc32`: A newer, faster algorithm, but incompatible with earlier versions. Tablespace blocks will be converted to the new format over time, meaning that a mix of checksums may be present.
	+ `full_crc32` and `strict_full_crc32`: From [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/). Permits encryption to be supported over a [SPATIAL INDEX](../spatial-index/index), which `crc32` does not support. Newly-created data files will carry a flag that indicates that all pages of the file will use a full CRC-32C checksum over the entire page contents (excluding the bytes where the checksum is stored, at the very end of the page). Such files will always use that checksum, no matter what parameter `innodb_checksum_algorithm` is assigned to. Even if `innodb_checksum_algorithm` is modified later, the same checksum will continue to be used. A special flag will be set in the FSP\_SPACE\_FLAGS in the first data page to indicate the new format of checksum and encryption/page\_compressed. ROW\_FORMAT=COMPRESSED tables will only use the old format. These tables do not support new features, such as larger innodb\_page\_size or instant ADD/DROP COLUMN. Also cleans up the MariaDB tablespace flags - flags are reserved to store the page\_compressed compression algorithm, and to store the compressed payload length, so that checksum can be computed over the compressed (and possibly encrypted) stream and can be validated without decrypting or decompressing the page. In the full\_crc32 format, there no longer are separate before-encryption and after-encryption checksums for pages. The single checksum is computed on the page contents that is written to the file.See [MDEV-12026](https://jira.mariadb.org/browse/MDEV-12026) for details.
	+ `none`: Writes a constant rather than calculate a checksum. Deprecated in [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/) and removed in [MariaDB 10.6](../what-is-mariadb-106/index) as was mostly used to disable the original, slow, page checksum for benchmarketing purposes.
	+ `strict_crc32`, `strict_innodb` and `strict_none`: The options are the same as the regular options, but InnoDB will halt if it comes across a mix of checksum values. These are faster, as both new and old checksum values are not required, but can only be used when setting up tablespaces for the first time.
* **Commandline:** `--innodb-checksum-algorithm=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:**
	+ `full_crc32` (>= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/))
	+ `crc32` (>= [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) to <= [MariaDB 10.4](../what-is-mariadb-104/index))
	+ `innodb` (<= [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/))
* **Valid Values:**
	+ >= [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/): `crc32`, `full_crc32`, `strict_crc32`, `strict_full_crc32`
	+ [MariaDB 10.5](../what-is-mariadb-105/index), >= [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/): `innodb`, `crc32`, `full_crc32`, `none`, `strict_innodb`, `strict_crc32`, `strict_none`, `strict_full_crc32`
	+ <= [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/): `innodb`, `crc32`, `none`, `strict_innodb`, `strict_crc32`, `strict_none`

 

---

 #### `innodb_checksums`

 * **Description:** By default, [InnoDB](../innodb/index) performs checksum validation on all pages read from disk, which provides extra fault tolerance. You would usually want this set to `1` in production environments, although setting it to `0` can provide marginal performance improvements. Deprecated and functionality replaced by [innodb\_checksum\_algorithm](#innodb_checksum_algorithm) in [MariaDB 10.0](../what-is-mariadb-100/index), and should be removed to avoid conflicts. `ON` is equivalent to `--innodb_checksum_algorithm=innodb` and `OFF` to `--innodb_checksum_algorithm=none`.
* **Commandline:** `--innodb-checksums`, `--skip-innodb-checksums`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `innodb_cleaner_lsn_age_factor`

 * **Description:** XtraDB has enhanced page cleaner heuristics, and with these in place, the default InnoDB adaptive flushing may be too aggressive. As a result, a new LSN age factor formula has been introduced, controlled by this variable. The default setting, `high_checkpoint`, uses the new formula, while the alternative, `legacy`, uses the original algorithm. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-cleaner-lsn-age-factor=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:**
	+ `deprecated`
* **Valid Values:**
	+ `deprecated`, `high_checkpoint`, `legacy`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_cmp_per_index_enabled`

 * **Description:** If set to `ON` (`OFF` is default), per-index compression statistics are stored in the [INFORMATION\_SCHEMA.INNODB\_CMP\_PER\_INDEX](../information-schema-innodb-tables-information-schema-innodb_cmp_per_index-an/index) table. These are expensive to record, so this setting should only be changed with care, such as for performance tuning on development or replica servers.
* **Commandline:** `--innodb-cmp-per-index-enabled={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_commit_concurrency`

 * **Description:** Limit to the number of transaction threads that can can commit simultaneously. 0, the default, imposes no limit. While you can change from one positive limit to another at runtime, you cannot set this variable to 0, or change it from 0, while the server is running. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).
* **Commandline:** `--innodb-commit-concurrency=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1000`
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_compression_algorithm`

 * **Description:** Compression algorithm used for [InnoDB page compression](../innodb-page-compression/index). The supported values are:
	+ `none`: Pages are not compressed.
	+ `zlib`: Pages are compressed using the bundled `[zlib](https://www.zlib.net/)` compression algorithm.
	+ `lz4`: Pages are compressed using the `[lz4](https://code.google.com/p/lz4/)` compression algorithm.
	+ `lzo`: Pages are compressed using the `[lzo](http://www.oberhumer.com/opensource/lzo/)` compression algorithm.
	+ `lzma`: Pages are compressed using the `[lzma](http://tukaani.org/xz/)` compression algorithm.
	+ `bzip2`: Pages are compressed using the `[bzip2](http://www.bzip.org/)` compression algorithm.
	+ `snappy`: Pages are compressed using the `[snappy](http://google.github.io/snappy/)` algorithm.
	+ On many distributions, MariaDB may not support all page compression algorithms by default. From [MariaDB 10.7](../what-is-mariadb-107/index), libraries can be installed as a plugin. See [Compression Plugins](../compression-plugins/index).
	+ See [InnoDB Page Compression: Configuring the InnoDB Page Compression Algorithm](../innodb-page-compression/index#configuring-the-innodb-page-compression-algorithm) for more information.
* **Commandline:** `--innodb-compression-algorithm=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `zlib`
* **Valid Values:**`none`, `zlib`, `lz4`, `lzo`, `lzma`, `bzip2` or `snappy`

 

---

 #### `innodb_compression_default`

 * **Description:** Whether or not [InnoDB page compression](../innodb-page-compression/index) is enabled by default for new tables.
	+ The default value is `OFF`, which means new tables are not compressed.
	+ See [InnoDB Page Compression: Enabling InnoDB Page Compression by Default](../innodb-page-compression/index#enabling-innodb-page-compression-by-default) for more information.
* **Commandline:** `--innodb-compression-default={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_compression_failure_threshold_pct`

 * **Description:** Specifies the percentage cutoff for expensive compression failures during updates to a table that uses [InnoDB page compression](../innodb-page-compression/index), after which free space is added to each new compressed page, dynamically adjusted up to the level set by [innodb\_compression\_pad\_pct\_max](#innodb_compression_pad_pct_max). Zero disables checking of compression efficiency and adjusting padding.
	+ See [InnoDB Page Compression: Configuring the Failure Threshold and Padding](../innodb-page-compression/index#configuring-the-failure-threshold-and-padding) for more information.
* **Commandline:** `--innodb-compression-failure-threshold-pct=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `5`
* **Range:** `0` to `100`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_compression_level`

 * **Description:** Specifies the default level of compression for tables that use [InnoDB page compression](../innodb-page-compression/index).
	+ Only a subset of InnoDB page compression algorithms support compression levels. If an InnoDB page compression algorithm does not support compression levels, then the compression level value is ignored.
	+ The compression level can be set to any value between `1` and `9`. The default compression level is `6`. The range goes from the fastest to the most compact, which means that `1` is the fastest and `9` is the most compact.
	+ See [InnoDB Page Compression: Configuring the Default Compression Level](../innodb-page-compression/index#configuring-the-default-compression-level) for more information.
* **Commandline:** `--innodb-compression-level=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `6`
* **Range:** `1` to `9`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_compression_pad_pct_max`

 * **Description:** The maximum percentage of reserved free space within each compressed page for tables that use [InnoDB page compression](../innodb-page-compression/index). Reserved free space is used when the page's data is reorganized and might be recompressed. Only used when [innodb\_compression\_failure\_threshold\_pct](#innodb_compression_failure_threshold_pct) is not zero, and the rate of compression failures exceeds its setting.
	+ See [InnoDB Page Compression: Configuring the Failure Threshold and Padding](../innodb-page-compression/index#configuring-the-failure-threshold-and-padding) for more information.
* **Commandline:** `--innodb-compression-pad-pct-max=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `50`
* **Range:** `0` to `75`
* **Introduced:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_concurrency_tickets`

 * **Description:** Number of times a newly-entered thread can enter and leave [InnoDB](../innodb/index) until it is again subject to the limitations of [innodb\_thread\_concurrency](#innodb_thread_concurrency) and may possibly be queued. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).
* **Commandline:** `--innodb-concurrency-tickets=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `0` (>= [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/))
	+ `5000` (<= [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))
* **Range:** `1` to `18446744073709551615`
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_corrupt_table_action`

 * **Description:** What action to perform when a corrupt table is found. XtraDB only.
	+ When set to `assert`, the default, XtraDB will intentionally crash the server when it detects corrupted data in a single-table tablespace, with an assertion failure.
	+ When set to `warn`, it will pass corruption as corrupt table instead of crashing, and disable all further I/O (except for deletion) on the table file.
	+ If set to `salvage`, read access is permitted, but corrupted pages are ignored. [innodb\_file\_per\_table](#innodb_file_per_table) must be enabled for this option. Previously named `innodb_pass_corrupt_table`.
	+ Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-corrupt-table-action=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:**
	+ `assert` (<= [MariaDB 10.1](../what-is-mariadb-101/index))
	+ `deprecated` (<= [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/))
* **Valid Values:**
	+ `deprecated`, `assert`, `warn`, `salvage`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_data_file_buffering`

 * **Description:** Whether to enable the file system cache for data files. Set to `OFF` by default, will be set to `ON` if [innodb\_flush\_method](#innodb_flush_method) is set to `fsync`, `littlesync`, `nosync`, or (Windows specific) `normal`.
* **Commandline:** `--innodb-data-file-buffering={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 11.0.0](https://mariadb.com/kb/en/mariadb-11-0-0-release-notes/)

 

---

 #### `innodb_data_file_path`

 * **Description:** Individual [InnoDB](../innodb/index) data files, paths and sizes. The value of [innodb\_data\_home\_dir](#innodb_data_home_dir) is joined to each path specified by innodb\_data\_file\_path to get the full directory path. If innodb\_data\_home\_dir is an empty string, absolute paths can be specified here. A file size is specified with K for kilobytes, M for megabytes and G for gigabytes, and whether or not to autoextend the data file is also specified.
* **Commandline:** `--innodb-data-file-path=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `ibdata1:12M:autoextend` (from [MariaDB 10.0](../what-is-mariadb-100/index)), `ibdata1:10M:autoextend` (before [MariaDB 10.0](../what-is-mariadb-100/index))

 

---

 #### `innodb_data_file_write_through`

 * **Description:** Whether writes to InnoDB data files (including the temporary tablespace) are write through. Set to `OFF` by default, will be set to `ON` if [innodb\_flush\_method](#innodb_flush_method) is set to `O_DSYNC`. On systems that support FUA it may make sense to enable write-through, to avoid extra system calls.
* **Commandline:** `--innodb-data-file-write-through={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 11.0.0](https://mariadb.com/kb/en/mariadb-11-0-0-release-notes/)

 

---

 #### `innodb_data_home_dir`

 * **Description:** Directory path for all [InnoDB](../innodb/index) data files in the shared tablespace (assuming [innodb\_file\_per\_table](#innodb_file_per_table) is not enabled). File-specific information can be added in [innodb\_data\_file\_path](#innodb_data_file_path), as well as absolute paths if innodb\_data\_home\_dir is set to an empty string.
* **Commandline:** `--innodb-data-home-dir=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`
* **Default Value:** `The MariaDB data directory`

 

---

 #### `innodb_deadlock_detect`

 * **Description:** By default, the InnoDB deadlock detector is enabled. If set to off, deadlock detection is disabled and MariaDB will rely on [innodb\_lock\_wait\_timeout](#innodb_lock_wait_timeout) instead. This may be more efficient in systems with high concurrency as deadlock detection can cause a bottleneck when a number of threads have to wait for the same lock.
* **Commandline:** `--innodb-deadlock-detect`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 #### `innodb_deadlock_report`

 * **Description:** How to report deadlocks (if [innodb\_deadlock\_detect=ON](#innodb_deadlock_detect)).
	+ `off`: Do not report any details of deadlocks.
	+ `basic`: Report transactions and waiting locks.
	+ `full`: Default. Report transactions, waiting locks and blocking locks.
* **Commandline:** `--innodb-deadlock-report=val`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `full`
* **Valid Values:** `off`, `basic`, `full`
* **Introduced:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_default_page_encryption_key`

 * **Description:** Encryption key used for page encryption.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB Encryption Keys](../innodb-encryption-keys/index) for more information.
* **Commandline:** `--innodb-default-page-encryption-key=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `255`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)

 

---

 #### `innodb_default_encryption_key_id`

 * **Description:** ID of encryption key used by default to encrypt InnoDB tablespaces.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB Encryption Keys](../innodb-encryption-keys/index) for more information.
* **Commandline:** `--innodb-default-encryption-key-id=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `4294967295`

 

---

 #### `innodb_default_row_format`

 * **Description:** Specifies the default [row format](../innodb-row-formats-overview/index) to be used for InnoDB tables. The compressed row format cannot be set as the default.
	+ See [InnoDB Row Formats Overview: Default Row Format](../innodb-row-formats-overview/index#default-row-format) for more information.
* **Commandline:** `--innodb-default-row-format=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `dynamic`
* **Valid Values:** `redundant`, `compact` or `dynamic`

 

---

 #### `innodb_defragment`

 * **Description:** When set to `1` (the default is `0`), InnoDB defragmentation is enabled. When set to FALSE, all existing defragmentation will be paused and new defragmentation commands will fail. Paused defragmentation commands will resume when this variable is set to true again. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_defragment_fill_factor`

 * **Description:**. Indicates how full defragmentation should fill a page. Together with [innodb\_defragment\_fill\_factor\_n\_recs](#innodb_defragment_fill_factor_n_recs) ensures defragmentation won’t pack the page too full and cause page split on the next insert on every page. The variable indicating more defragmentation gain is the one effective. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment-fill-factor=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `double`
* **Default Value:** `0.9`
* **Range:** `0.7` to `1`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_defragment_fill_factor_n_recs`

 * **Description:** Number of records of space that defragmentation should leave on the page. This variable, together with [innodb\_defragment\_fill\_factor](#innodb_defragment_fill_factor), is introduced so defragmentation won't pack the page too full and cause page split on the next insert on every page. The variable indicating more defragmentation gain is the one effective. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment-fill-factor-n-recs=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `1` to `100`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_defragment_frequency`

 * **Description:** Maximum times per second for defragmenting a single index. This controls the number of times the defragmentation thread can request X\_LOCK on an index. The defragmentation thread will check whether 1/defragment\_frequency (s) has passed since it last worked on this index, and put the index back in the queue if not enough time has passed. The actual frequency can only be lower than this given number. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment-frequency=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `integer`
* **Default Value:** `40`
* **Range:** `1` to `1000`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_defragment_n_pages`

 * **Description:** Number of pages considered at once when merging multiple pages to defragment. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment-n-pages=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `7`
* **Range:** `2` to `32`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_defragment_stats_accuracy`

 * **Description:** Number of defragment stats changes there are before the stats are written to persistent storage. Defaults to zero, meaning disable defragment stats tracking. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Commandline:** `--innodb-defragment-stats-accuracy=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Deprecated:** [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/)
* **Removed:** [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/)

 

---

 #### `innodb_dict_size_limit`

 * **Description:** Size in bytes of a soft limit the memory used by tables in the data dictionary. Once this limit is reached, XtraDB will attempt to remove unused entries. If set to `0`, the default and standard InnoDB behavior, there is no limit to memory usage. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced by MySQL 5.6's new [table\_definition\_cache](../server-system-variables/index#table_definition_cache) implementation.
* **Commandline:** `innodb-dict-size-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Default Value - 32 bit:** `2147483648`
* **Default Value - 64 bit:** `9223372036854775807`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced by MySQL 5.6's [table\_definition\_cache](../server-system-variables/index#table_definition_cache) implementation.

 

---

 #### `innodb_disable_sort_file_cache`

 * **Description:** If set to `1` (`0` is default), the operating system file system cache for merge-sort temporary files is disabled.
* **Commandline:** `--innodb-disable-sort-file-cache={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_disallow_writes`

 * **Description:** Tell InnoDB to stop any writes to disk.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.3.35](https://mariadb.com/kb/en/mariadb-10335-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10425-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/)

 

---

 #### `innodb_doublewrite`

 * **Description:** If set to `1`, the default, to improve fault tolerance [InnoDB](../innodb/index) first stores data to a [doublewrite buffer](../innodb-doublewrite-buffer/index) before writing it to data file. Disabling will provide a marginal peformance improvement.
* **Commandline:** `--innodb-doublewrite`, `--skip-innodb-doublewrite`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_doublewrite_file`

 * **Description:** The absolute or relative path and filename to a dedicated tablespace for the [doublewrite buffer](../xtradbinnodb-doublewrite-buffer/index). In heavy workloads, the doublewrite buffer can impact heavily on the server, and moving it to a different drive will reduce contention on random reads. Since the doublewrite buffer is mostly sequential writes, a traditional HDD is a better choice than SSD. This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** `innodb-doublewrite-file=filename`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `filename`
* **Default Value:** `NULL`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_empty_free_list_algorithm`

 * **Description:** XtraDB 5.6.13-61 introduced an algorithm to assist with reducing mutex contention when the buffer pool free list is empty, controlled by this variable. If set to `backoff`, the default until [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/), the new algorithm will be used. If set to `legacy`, the original InnoDB algorithm will be used. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades. See [#1651657](https://bugs.launchpad.net/percona-server/+bug/1651657) for the reasons this was changed back to `legacy` in XtraDB 5.6.36-82.0. When upgrading from 10.0 to 10.1 (>= 10.1.24), for large buffer pools the default will remain `backoff`, while for small ones it will be changed to `legacy`.
* **Commandline:** `innodb-empty-free-list-algorithm=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:**
	+ `deprecated`
* **Valid Values:**
	+ `deprecated`, `backoff`, `legacy`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_enable_unsafe_group_commit`

 * **Description:** Unneeded after XtraDB 1.0.5. If set to `0`, the default, InnoDB will keep transactions between the transaction log and [binary log](../binary-log/index)s in the same order. Safer, but slower. If set to `1`, transactions can be group-committed, but there is no guarantee of the order being kept, and a small risk of the two logs getting out of sync. In write-intensive environments, can lead to a significant improvement in performance.
* **Commandline:** `--innodb-enable-unsafe-group-commit`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1`
* **Removed:** Not needed after XtraDB 1.0.5

 

---

 #### `innodb_encrypt_log`

 * **Description:** Enables encryption of the [InnoDB redo log](../innodb-redo-log/index). This also enables encryption of some temporary files created internally by InnoDB, such as those used for merge sorts and row logs.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB / XtraDB Enabling Encryption: Enabling Encryption for Redo Log](../innodb-enabling-encryption/index#enabling-encryption-for-the-redo-log) for more information.
* **Commandline:** `--innodb-encrypt-log`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_encrypt_tables`

 * **Description:** Enables automatic encryption of all InnoDB tablespaces.
	+ `OFF` - Disables table encryption for all new and existing tables that have the `[ENCRYPTED](../create-table/index#encrypted)` table option set to `DEFAULT`.
	+ `ON` - Enables table encryption for all new and existing tables that have the `[ENCRYPTED](../create-table/index#encrypted)` table option set to `DEFAULT`, but allows unencrypted tables to be created.
	+ `FORCE` - Enables table encryption for all new and existing tables that have the `[ENCRYPTED](../create-table/index#encrypted)` table option set to `DEFAULT`, and doesn't allow unencrypted tables to be created (CREATE TABLE ... ENCRYPTED=NO will fail).
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB / XtraDB Enabling Encryption: Enabling Encryption for Automatically Encrypted Tablespaces](../innodb-enabling-encryption/index#enabling-encryption-for-automatically-encrypted-tablespaces) for more information.
* **Commandline:** `--innodb-encrypt-tables={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Valid Values:** `ON`, `OFF`, `FORCE`

 

---

 #### `innodb_encrypt_temporary_tables`

 * **Description:** Enables automatic encryption of the InnoDB [temporary tablespace](../innodb-temporary-tablespaces/index).
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB Enabling Encryption: Enabling Encryption for Temporary Tablespaces](../innodb-enabling-encryption/index#enabling-encryption-for-temporary-tablespaces) for more information.
* **Commandline:** `--innodb-encrypt-temporary-tables={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Valid Values:** `ON`, `OFF`
* **Introduced:** [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `innodb_encryption_rotate_key_age`

 * **Description:** Re-encrypt in background any page having a key older than this number of key versions. When setting up encryption, this variable must be set to a non-zero value. Otherwise, when you enable encryption through `[innodb\_encrypt\_tables](#innodb_encrypt_tables)` MariaDB won't be able to automatically encrypt any unencrypted tables.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB / XtraDB Encryption Keys: Key Rotation](../innodb-xtradb-encryption-keys/index#key-rotation) for more information.
* **Commandline:** `--innodb-encryption-rotate-key-age=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `4294967295`

 

---

 #### `innodb_encryption_rotation_iops`

 * **Description:** Use this many iops for background key rotation operations performed by the background encryption threads.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB / XtraDB Encryption Keys: Key Rotation](../innodb-xtradb-encryption-keys/index#key-rotation) for more information.
* **Commandline:** `--innodb-encryption-rotation_iops=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `0` to `4294967295`

 

---

 #### `innodb_encryption_threads`

 * **Description:** Number of background encryption threads threads performing background key rotation and [scrubbing](../innodb-data-scrubbing/index). When setting up encryption, this variable must be set to a non-zero value. Otherwise, when you enable encryption through [innodb\_encrypt\_tables](#innodb_encrypt_tables) MariaDB won't be able to automatically encrypt any unencrypted tables. Recommended never be set higher than 255.
	+ See [Data-at-Rest Encryption](../data-at-rest-encryption/index) and [InnoDB Background Encryption Threads](../innodb-background-encryption-threads/index) for more information.
* **Commandline:** `--innodb-encryption-threads=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:**
	+ `0` to `4294967295` (<= [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/))
	+ `0` to `255` (>= [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/), [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))

 

---

 #### `innodb_extra_rsegments`

 * **Description:** Removed in XtraDB 5.5 and replaced by [innodb\_rollback\_segments](#innodb_rollback_segments). Usually there is one rollback segment protected by single mutex, a source of contention in high write environments. This option specifies a number of extra user rollback segments. Changing the default will make the data readable by XtraDB only, and is incompatible with InnoDB. After modifying, the server must be slow-shutdown. If there is existing data, it must be dumped before changing, and re-imported after the change has taken effect.
* **Commandline:** `--innodb-extra-rsegments=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `126`
* **Removed:** XtraDB 5.5 - replaced by [innodb\_rollback\_segments](#innodb_rollback_segments)

 

---

 #### `innodb_extra_undoslots`

 * **Description:** Usually, InnoDB has 1024 undo slots in its rollback segment, so 1024 transactions can run in parallel. New transactions will fail if all slots are used. Setting this variable to `1` expands the available undo slots to 4072. Not recommended unless you get the `Warning: cannot find a free slot for an undo log` error in the error log, as it makes data files unusable for ibbackup, or MariaDB servers not run with this option. See also [undo log](../undo-log/index).
* **Commandline:** `--innodb-extra-undoslots={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** XtraDB 5.5

 

---

 #### `innodb_fake_changes`

 * **Description:** From [MariaDB 5.5](../what-is-mariadb-55/index) until [MariaDB 10.1](../what-is-mariadb-101/index), XtraDB-only option that enables the fake changes feature. In [replication](../replication/index), setting up or restarting a replica can cause a replication reads to perform more slowly, as MariaDB is single-threaded and needs to read the data before it can execute the queries. This can be speeded up by prefetching threads to warm the server, replaying the statements and then rolling back at commit. This however has an overhead from locking rows only then to undo changes at rollback. Fake changes attempts to reduce this overhead by reading the rows for INSERT, UPDATE and DELETE statements but not updating them. The rollback is then very fast with little or nothing to do. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades. Not present in [MariaDB 10.3](../what-is-mariadb-103/index) and beyond.
* **Commandline:** `--innodb-fake-changes={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_fast_checksum`

 * **Description:** Implements a more CPU efficient XtraDB checksum algorithm, useful for write-heavy loads with high I/O. If set to `1` on a server with tables that have been created with it set to `0`, reads will be slower, so tables should be recreated (dumped and reloaded). XtraDB will fail to start if set to `0` and there are tables created while set to `1`. Replaced with [innodb\_checksum\_algorithm](#innodb_checksum_algorithm) in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6.
* **Commandline:** `--innodb-fast-checksum={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 - replaced with [innodb\_checksum\_algorithm](#innodb_checksum_algorithm)

 

---

 #### `innodb_fast_shutdown`

 * **Description:** The shutdown mode.
	+ `0` - InnoDB performs a slow shutdown, including full purge (before [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), not always, due to [MDEV-13603](https://jira.mariadb.org/browse/MDEV-13603)) and change buffer merge. Can be very slow, even taking hours in extreme cases.
	+ `1` - the default, [InnoDB](../innodb/index) performs a fast shutdown, not performing a full purge or an insert buffer merge.
	+ `2`, the [InnoDB redo log](../xtradbinnodb-redo-log/index) is flushed and a cold shutdown takes place, similar to a crash. The resulting startup then performs crash recovery. Extremely fast, in cases of emergency, but risks corruption. Not suitable for upgrades between major versions!
	+ `3` (from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)) - active transactions will not be rolled back, but all changed pages will be written to data files. The active transactions will be rolled back by a background thread on a subsequent startup. The fastest option that will not involve [InnoDB redo log](../xtradbinnodb-redo-log/index) apply on subsequent startup. See [MDEV-15832](https://jira.mariadb.org/browse/MDEV-15832).
* **Commandline:** `--innodb-fast-shutdown[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:**  `0` to `3` (>= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)), `0` to `2` (<= [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/))

 

---

 #### `innodb_fatal_semaphore_wait_threshold`

 * **Description:** In MariaDB, the fatal semaphore timeout is configurable. This variable sets the maximum number of seconds for semaphores to time out in InnoDB.
* **Commandline:** `--innodb-fatal-semaphore-wait-threshold=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `600`
* **Range:** `1` to `4294967295`

 

---

 #### `innodb_file_format`

 * **Description:** File format for new [InnoDB](../innodb/index) tables. Can either be `Antelope`, the default and the original format, or `Barracuda`, which supports [compression](../compression/index). Note that this value is also used when a table is re-created with an [ALTER TABLE](../alter-table/index) which requires a table copy. See [XtraDB/InnoDB File Format](../xtradbinnodb-file-format/index) for more on the file formats. Removed in 10.3.1 and restored as a deprecated and unused variable in 10.4.3 for compatibility purposes.
* **Commandline:** `--innodb-file-format=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:**
	+ `Barracuda`
* **Valid Values:** `Antelope`, `Barracuda`
* **Deprecated:** [MariaDB 10.2](../what-is-mariadb-102/index)
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)
* **Re-introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) (for compatibility purposes)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_file_format_check`

 * **Description:** If set to `1`, the default, [InnoDB](../innodb/index) checks the shared tablespace file format tag. If this is higher than the current version supported by XtraDB/InnoDB (for example Barracuda when only Antelope is supported), XtraDB/InnoDB will will not start. If it the value is not higher, XtraDB/InnoDB starts correctly and the [innodb\_file\_format\_max](#innodb_file_format_max) value is set to this value. If innodb\_file\_format\_check is set to `0`, no checking is performed. See [XtraDB/InnoDB File Format](../xtradbinnodb-file-format/index) for more on the file formats.
* **Commandline:** `--innodb-file-format-check={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.2](../what-is-mariadb-102/index)
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `innodb_file_format_max`

 * **Description:** The highest [XtraDB/InnoDB](../innodb/index) file format. This is set to the value of the file format tag in the shared tablespace on startup (see [innodb\_file\_format\_check](#innodb_file_format_check)). If the server later creates a higher table format, innodb\_file\_format\_max is set to that value. See [XtraDB/InnoDB File Format](../xtradbinnodb-file-format/index) for more on the file formats.
* **Commandline:** `--innodb-file-format-max=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `Antelope`
* **Valid Values:** `Antelope`, `Barracuda`
* **Deprecated:** [MariaDB 10.2](../what-is-mariadb-102/index)
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 

---

 #### `innodb_file_per_table`

 * **Description:** If set to `ON`, then new [InnoDB](../innodb/index) tables are created with their own [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index). If set to `OFF`, then new tables are created in the [InnoDB system tablespace](../innodb-system-tablespaces/index) instead. [Page compression](../compression/index) is only available with file-per-table tablespaces. Note that this value is also used when a table is re-created with an [ALTER TABLE](../alter-table/index) which requires a table copy. Deprecated in [MariaDB 11.0](../what-is-mariadb-11-0/index) as there's no benefit to setting to `OFF`, the original InnoDB default.
* **Commandline:** `--innodb-file-per-table`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 11.0.1](../mdb-11-0-1-rn/index)

 

---

 #### `innodb_fill_factor`

 * **Description:** Percentage of B-tree page filled during bulk insert (sorted index build). Used as a hint rather than an absolute value. Setting to `70`, for example, reserves 30% of the space on each B-tree page for the index to grow in future.
* **Commandline:** `--innodb-fill-factor=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value**: `100`
* **Range:** `10` to `100`

 

---

 #### `innodb_flush_log_at_timeout`

 * **Description:** Interval in seconds to write and flush the [InnoDB redo log](../innodb-redo-log/index). Before MariaDB 10, this was fixed at one second, which is still the default, but this can now be changed. It's usually increased to reduce flushing and avoid impacting performance of binary log group commit.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `2700`

 

---

 #### `innodb_flush_log_at_trx_commit`

 * **Description:** Set to `1`, along with [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog) for the greatest level of fault tolerance. The value of [innodb\_use\_global\_flush\_log\_at\_trx\_commit](#innodb_use_global_flush_log_at_trx_commit) determines whether this variable can be reset with a SET statement or not.
	+ `1` The default, the log buffer is written to the [InnoDB redo log](../innodb-redo-log/index) file and a flush to disk performed after each transaction. This is required for full ACID compliance.
	+ `0` Nothing is done on commit; rather the log buffer is written and flushed to the [InnoDB redo log](../innodb-redo-log/index) once a second. This gives better performance, but a server crash can erase the last second of transactions.
	+ `2` The log buffer is written to the [InnoDB redo log](../innodb-redo-log/index) after each commit, but flushing takes place every [innodb\_flush\_log\_at\_timeout](#innodb_flush_log_at_timeout) seconds (by default once a second). Performance is slightly better, but a OS or power outage can cause the last second's transactions to be lost.
	+ `3` Emulates [MariaDB 5.5](../what-is-mariadb-55/index) [group commit](../group-commit-for-the-binary-log/index) (3 syncs per group commit). See [Binlog group commit and innodb\_flush\_log\_at\_trx\_commit](../binlog-group-commit-and-innodb_flush_log_at_trx_commit/index). This option has not been working correctly since 10.2 and may be removed in future, see <https://github.com/MariaDB/server/pull/1873>
* **Commandline:** `--innodb-flush-log-at-trx-commit[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `1`
* **Valid Values:** `0`, `1`, `2` or `3`

 

---

 #### `innodb_flush_method`

 * **Description:** [InnoDB](../innodb/index) flushing method. Windows always uses async\_unbuffered and this variable then has no effect. On Unix, before [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), by default fsync() is used to flush data and logs. Adjusting this variable can give performance improvements, but behavior differs widely on different filesystems, and changing from the default has caused problems in some situations, so test and benchmark carefully before adjusting. In MariaDB, Windows recognises and correctly handles the Unix methods, but if none are specified it uses own default - unbuffered write (analog of O\_DIRECT) + syncs (e.g FileFlushBuffers()) for all files.
	+ `O_DSYNC` - O\_DSYNC is used to open and flush logs, and fsync() to flush the data files.
	+ `O_DIRECT` - O\_DIRECT or directio(), is used to open data files, and fsync() to flush data and logs. Default on Unix from [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).
	+ `fsync` - Default on Unix until [MariaDB 10.5](../what-is-mariadb-105/index). Can be specified directly, but if the variable is unset on Unix, fsync() will be used by default.
	+ `O_DIRECT_NO_FSYNC` - introduced in [MariaDB 10.0](../what-is-mariadb-100/index). Uses O\_DIRECT during flushing I/O, but skips fsync() afterwards. Not suitable for XFS filesystems. Generally not recommended over O\_DIRECT, as does not get the benefit of [innodb\_use\_native\_aio=ON](#innodb_use_native_aio).
	+ `ALL_O_DIRECT` - introduced in [MariaDB 5.5](../what-is-mariadb-55/index) and available with XtraDB only. Uses O\_DIRECT for opening both data and logs and fsync() to flush data but not logs. Use with large InnoDB files only, otherwise may cause a performance degradation. Set [innodb\_log\_block\_size](#innodb_log_block_size) to 4096 on ext4 filesystems. This is the default log block size on ext4 and will avoid unaligned AIO/DIO warnings.
	+ `unbuffered` - Windows-only default
	+ `async_unbuffered` - Windows-only, alias for `unbuffered`
	+ `normal` - Windows-only, alias for `fsync`
	+ `littlesync` - for internal testing only
	+ `nosync` - for internal testing only
* Deprecated in [MariaDB 11.0](../what-is-mariadb-110/index) and replaced by four boolean dynamic variables that can be changed while the server is running: [innodb\_log\_file\_buffering](#innodb_log_file_buffering) (disable O\_DIRECT, added by [MDEV-28766](https://jira.mariadb.org/browse/MDEV-28766) in 10.8.4, 10.9.2), [innodb\_data\_file\_buffering](#innodb_data_file_buffering) (disable O\_DIRECT on data files), [innodb\_log\_file\_write\_through](#innodb_log_file_write_through) (enable O\_DSYNC on the log), [innodb\_data\_file\_write\_through](#innodb_data_file_write_through) (enable O\_DSYNC on persistent data files)  
  
From [MariaDB 11.0](../what-is-mariadb-110/index), if set to one of the following values, then the values of the four boolean flags will be set as follows:
	+ `O_DSYNC`: [innodb\_log\_file\_write\_through=ON](#innodb_log_file_write_through), [innodb\_data\_file\_write\_through=ON](#innodb_data_file_write_through), [innodb\_data\_file\_buffering=OFF](#innodb_data_file_buffering), and (if supported) [innodb\_log\_file\_buffering=OFF](#innodb_log_file_buffering).
	+ `fsync`, `littlesync`, `nosync`, or (Microsoft Windows specific) `normal`: [innodb\_log\_file\_write\_through=OFF](#innodb_log_file_write_through), [innodb\_data\_file\_write\_through=OFF](#innodb_data_file_write_through), and [innodb\_data\_file\_buffering=ON](#innodb_data_file_buffering).
* **Commandline:** `--innodb-flush-method=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumeration` (>= [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)), `string` (<= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/))
* **Default Value:**
	+ `O_DIRECT` (Unix, >= [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/))
	+ `fsync` (Unix, >= [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), <= [MariaDB 10.5](../what-is-mariadb-105/index))
	+ Not set (<= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/))
* **Valid Values:**
	+ Unix: `fsync`, `O_DSYNC`, `littlesync`, `nosync`. `O_DIRECT`, `O_DIRECT_NO_FSYNC`
	+ Windows: `unbuffered`, `async_unbuffered`, `normal`
* **Deprecated:** [MariaDB 11.0](../what-is-mariadb-110/index)

 

---

 #### `innodb_flush_neighbor_pages`

 * **Description:** Determines whether, when dirty pages are flushed to the data file, neighboring pages in the data file are flushed at the same time. If set to `none`, the feature is disabled. If set to `area`, the default, the standard InnoDB behavior is used. For each page to be flushed, dirty neighboring pages are flushed too. If there's little head seek delay, such as SSD or large enough write buffer, one of the other two options may be more efficient. If set to `cont`, for each page to be flushed, neighboring contiguous blocks are flushed at the same time. Being contiguous, a sequential I/O is used, unlike the random I/O used in `area`. Replaced by [innodb\_flush\_neighbors](#innodb_flush_neighbors) in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6.
* **Commandline:** `innodb-flush-neighbor-pages=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `area`
* **Valid Values:** `none` or `0`, `area` or `1`, `cont` or `2`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 - replaced by [innodb\_flush\_neighbors](#innodb_flush_neighbors)

 

---

 #### `innodb_flush_neighbors`

 * **Description:** Determines whether flushing a page from the [buffer pool](../innodb-buffer-pool/index) will flush other dirty pages in the same group of pages (extent). In high write environments, if flushing is not aggressive enough, it can fall behind resulting in higher memory usage, or if flushing is too aggressive, cause excess I/O activity. SSD devices, with low seek times, would be less likely to require dirty neighbor flushing to be set. Since [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/) an attempt is made under Windows and Linux to determine SSD status which was exposed in [information\_schema.innodb\_tablespaces\_scrubbing\_table](../information-schema-innodb_tablespaces_scrubbing-table/index). This variable is ignored for table spaces that are detected as stored on SSD (and the `0` behavior applies).
	+ `1`: The default, flushes contiguous dirty pages in the same extent from the buffer pool.
	+ `0`: No other dirty pages are flushed.
	+ `2`: Flushes dirty pages in the same extent from the buffer pool.
* **Commandline:** `--innodb-flush-neighbors=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `1`
* **Valid Values:** `0`, `1`, `2`

 

---

 #### `innodb_flush_sync`

 * **Description:** If set to `ON`, the default, the [innodb\_io\_capacity](#innodb_io_capacity) setting is ignored for I/O bursts occuring at checkpoints.
* **Commandline:** `--innodb-flush-sync={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value**: `ON`

 

---

 #### `innodb_flushing_avg_loops`

 * **Description:** Determines how quickly adaptive flushing will respond to changing workloads. The value is the number of iterations that a previously calculated flushing state snapshot is kept. Increasing the value smooths and slows the rate that the flushing operations change, while decreasing it causes flushing activity to spike quickly in response to workload changes.
* **Commandline:** `--innodb-flushing-avg-loops=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `30`
* **Range:** `1` to `1000`

 

---

 #### `innodb_force_load_corrupted`

 * **Description:** Set to `0` by default, if set to `1`, [InnoDB](../innodb/index) will be permitted to load tables marked as corrupt. Only use this to recover data you can't recover any other way, or in troubleshooting. Always restore to `0` when the returning to regular use. Given that [MDEV-11412](https://jira.mariadb.org/browse/MDEV-11412) in [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/) aims to allow any metadata for a missing or corrupted table to be dropped, and given that [MDEV-17567](https://jira.mariadb.org/browse/MDEV-17567) and [MDEV-25506](https://jira.mariadb.org/browse/MDEV-25506) and related tasks made DDL operations crash-safe, the parameter no longer serves any purpose and was removed in [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/).
* **Commandline:** `--innodb-force-load-corrupted`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/)

 

---

 #### `innodb_force_primary_key`

 * **Description:** If set to `1` (`0` is default) CREATE TABLEs without a primary or unique key where all keyparts are NOT NULL will not be accepted, and will return an error.
* **Commandline:** `--innodb-force-primary-key`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_force_recovery`

 * **Description:** [InnoDB](../innodb/index) crash recovery mode. `0` is the default. The other modes are for recovery purposes only, and no data can be changed while another mode is active. Some queries relying on indexes are also blocked. See [InnoDB Recovery Modes](../innodb-recovery-modes/index) for more on mode specifics.
* **Commandline:** `--innodb-force-recovery=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumeration`
* **Default Value:** `0`
* **Range:** `0` to `6`

 

---

 #### `innodb_foreground_preflush`

 * **Description:** Before XtraDB 5.6.13-61.0, if the checkpoint age is in the sync preflush zone while a thread is writing to the [XtraDB redo log](../innodb-redo-log/index), it will try to advance the checkpoint by issuing a flush list flush batch if this is not already being done. XtraDB has enhanced page cleaner tuning, and may already be performing furious flushing, resulting in the flush simply adding unneeded mutex pressure. Instead, the thread now waits for the flushes to finish, and then has two options, controlled by this variable. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
	+ `exponential_backoff` - thread sleeps while it waits for the flush list flush to occur. The sleep time randomly progressively increases, periodically reset to avoid runaway sleeps.
	+ `sync_preflush` - thread issues a flush list batch, and waits for it to complete. This is the same as is used when the page cleaner thread is not running.
* **Commandline:** `innodb-foreground-preflush=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:**
	+ `deprecated`
* **Valid Values:**
	+ `deprecated`, `exponential_backoff`, `sync_preflush`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_ft_aux_table`

 * **Description:** Diagnostic variable intended only to be set at runtime. It specifies the qualified name (for example `test/ft_innodb`) of an InnoDB table that has a [FULLTEXT index](../full-text-indexes/index), and after being set the INFORMATION\_SCHEMA tables [INNODB\_FT\_INDEX\_TABLE](../information-schema-innodb_ft_index_table-table/index), [INNODB\_FT\_INDEX\_CACHE](../information-schema-innodb_ft_index_cache-table/index), INNODB\_FT\_CONFIG, [INNODB\_FT\_DELETED](../information-schema-innodb_ft_deleted-table/index), and [INNODB\_FT\_BEING\_DELETED](../information-schema-innodb_ft_being_deleted-table/index) will contain search index information for the specified table.
* **Commandline:** `--innodb-ft-aux-table=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `innodb_ft_cache_size`

 * **Description:** Cache size available for a parsed document while creating an InnoDB [FULLTEXT index](../full-text-indexes/index).
* **Commandline:** `--innodb-ft-cache-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8000000`

 

---

 #### `innodb_ft_enable_diag_print`

 * **Description:** If set to `1`, additional [full-text](../full-text-indexes/index) search diagnostic output is enabled.
* **Commandline:** `--innodb-ft-enable-diag-print={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_ft_enable_stopword`

 * **Description:** If set to `1`, the default, a set of [stopwords](../stopwords/index) is associated with an InnoDB [FULLTEXT index](../full-text-indexes/index) when it is created. The stopword list comes from the table set by the session variable [innodb\_ft\_user\_stopword\_table](#innodb_ft_user_stopword_table), if set, otherwise the global variable [innodb\_ft\_server\_stopword\_table](#innodb_ft_server_stopword_table), if that is set, or the [built-in list](../stopwords/index) if neither variable is set.
* **Commandline:** `--innodb-ft-enable-stopword={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_ft_max_token_size`

 * **Description:** Maximum length of words stored in an InnoDB [FULLTEXT index](../full-text-indexes/index). A larger limit will increase the size of the index, slowing down queries, but permit longer words to be searched for. In most normal situations, longer words are unlikely search terms.
* **Commandline:** `--innodb-ft-max-token-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `84`
* **Range:** `10` to `84`

 

---

 #### `innodb_ft_min_token_size`

 * **Description:** Minimum length of words stored in an InnoDB [FULLTEXT index](../full-text-indexes/index). A smaller limit will increase the size of the index, slowing down queries, but permit shorter words to be searched for. For data stored in a Chinese, Japanese or Korean [character set](../data-types-character-sets-and-collations/index), a value of 1 should be specified to preserve functionality.
* **Commandline:** `--innodb-ft-min-token-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `3`
* **Range:** `0` to `16`

 

---

 #### `innodb_ft_num_word_optimize`

 * **Description:** Number of words processed during each [OPTIMIZE TABLE](../optimize-table/index) on an InnoDB [FULLTEXT index](../full-text-indexes/index). To ensure all changes are incorporated, multiple OPTIMIZE TABLE statements could be run in case of a substantial change to the index.
* **Commandline:** `--innodb-ft-num-word-optimize=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2000`

 

---

 #### `innodb_ft_result_cache_limit`

 * **Description:** Limit in bytes of the InnoDB [FULLTEXT index](../full-text-indexes/index) query result cache per fulltext query. The latter stages of the full-text search are handled in memory, and limiting this prevents excess memory usage. If the limit is exceeded, the query returns an error.
* **Commandline:** `--innodb-ft-result-cache-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2000000000`
* **Range:** `1000000` to `18446744073709551615`

 

---

 #### `innodb_ft_server_stopword_table`

 * **Description:** Table name containing a list of stopwords to ignore when creating an InnoDB [FULLTEXT index](../full-text-indexes/index), in the format db\_name/table\_name. The specified table must exist before this option is set, and must be an InnoDB table with a single column, a [VARCHAR](../varchar/index) named VALUE. See also [innodb\_ft\_enable\_stopword](#innodb_ft_enable_stopword).
* **Commandline:** `--innodb-ft-server-stopword-table=db_name/table_name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty

 

---

 #### `innodb_ft_sort_pll_degree`

 * **Description:** Number of parallel threads used when building an InnoDB [FULLTEXT index](../full-text-indexes/index). See also [innodb\_sort\_buffer\_size](#innodb_sort_buffer_size).
* **Commandline:** `--innodb-ft-sort-pll-degree=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `2`
* **Range:** `1` to `32`

 

---

 #### `innodb_ft_total_cache_size`

 * **Description:**Total memory allocated for the cache for all InnoDB [FULLTEXT index](../full-text-indexes/index) tables. A force sync is triggered if this limit is exceeded.
* **Commandline:** `--innodb-ft-total-cache-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `640000000`
* **Range:** `32000000` to `1600000000`
* **Introduced:** [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/)

 

---

 #### `innodb_ft_user_stopword_table`

 * **Description:** Table name containing a list of stopwords to ignore when creating an InnoDB [FULLTEXT index](../full-text-indexes/index), in the format db\_name/table\_name. The specified table must exist before this option is set, and must be an InnoDB table with a single column, a [VARCHAR](../varchar/index) named VALUE. See also [innodb\_ft\_enable\_stopword](#innodb_ft_enable_stopword).
* **Commandline:** `--innodb-ft-user-stopword-table=db_name/table_name`
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty

 

---

 #### `innodb_ibuf_accel_rate`

 * **Description:** Allows the insert buffer activity to be adjusted. The following formula is used: [real activity] = [default activity] \* (innodb\_io\_capacity/100) \* (innodb\_ibuf\_accel\_rate/100). As `innodb_ibuf_accel_rate` is increased from its default value of `100`, the lowest setting, insert buffer activity is increased. See also [innodb\_io\_capacity](#innodb_io_capacity). This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** `innodb-ibuf-accel-rate=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `100` to `999999999`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_ibuf_active_contract`

 * **Description:** Specifies whether the insert buffer can be processed before it's full. If set to `0`, the standard InnoDB method is used, and the buffer is not processed until it's full. If set to `1`, the default, the insert buffer can be processed before it is full. This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** `innodb-ibuf-active-contract=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_ibuf_max_size`

 * **Description:** Maximum size in bytes of the insert buffer. Defaults to half the size of the [buffer pool](../innodb-buffer-pool/index) so you may want to reduce if you have a very large buffer pool. If set to `0`, the insert buffer is disabled, which will cause all secondary index updates to be performed synchronously, usually at a cost to performance. This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** `innodb-ibuf-max-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** 1/2 the size of the InnoDB buffer pool
* **Range:** `0` to 1/2 the size of the InnoDB buffer pool
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_idle_flush_pct`

 * **Description:** Up to what percentage of dirty pages should be flushed when innodb finds it has spare resources to do so. Has had no effect since merging InnoDB 5.7 from mysql-5.7.9 ([MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)). Deprecated in [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/) and removed in [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/).
* **Commandline:** `--innodb-idle-flush-pct=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `0` to `100`
* **Deprecated:** [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/)
* **Removed:** [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/)

 

---

 #### `innodb_immediate_scrub_data_uncompressed`

 * **Description:** Enable scrubbing of data. See [Data Scrubbing](../innodb-data-scrubbing/index).
* **Commandline:** `--innodb-immediate-scrub-data-uncompressed={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_import_table_from_xtrabackup`

 * **Description:** If set to `1`, permits importing of .ibd files exported with the [XtraBackup](../backup-restore-and-import-xtrabackup/index) --export option. Previously named `innodb_expand_import`. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced with MySQL 5.6's transportable tablespaces.
* **Commandline:** `innodb-import-table-from-xtrabackup=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_instant_alter_column_allowed`

 * **Description:**
	+ If a table is altered using ALGORITHM=INSTANT, it can force the table to use a non-canonical format: A hidden metadata record at the start of the clustered index is used to store each column's DEFAULT value. This makes it possible to add new columns that have default values without rebuilding the table. Starting with [MariaDB 10.4](../what-is-mariadb-104/index), a BLOB in the hidden metadata record is used to store column mappings. This makes it possible to drop or reorder columns without rebuilding the table. This also makes it possible to add columns to any position or drop columns from any position in the table without rebuilding the table. If a column is dropped without rebuilding the table, old records will contain garbage in that column's former position, and new records will be written with NULL values, empty strings, or dummy values.
	+ This is generally not a problem. However, there may be cases where you want to avoid putting a table into this format. For example, to ensure that future UPDATE operations after an ADD COLUMN will be performed in-place, to reduce write amplification. (Instantly added columns are essentially always variable-length.) Also avoid bugs similar to [MDEV-19916](https://jira.mariadb.org/browse/MDEV-19916), or to be able to export tables to older versions of the server.
	+ This variable has been introduced as a result, with the following values:
	+ `never` (0): Do not allow instant add/drop/reorder, to maintain format compatibility with MariaDB 10.x and MySQL 5.x. If the table (or partition) is not in the canonical format, then any ALTER TABLE (even one that does not involve instant column operations) will force a table rebuild.
	+ `add_last` (1, default in 10.3): Store a hidden metadata record that allows columns to be appended to the table instantly ([MDEV-11369](https://jira.mariadb.org/browse/MDEV-11369)). In 10.4 or later, if the table (or partition) is not in this format, then any ALTER TABLE (even one that does not involve column changes) will force a table rebuild.
	+ `add_drop_reorder` (2, default): From [MariaDB 10.4](../what-is-mariadb-104/index) only. Like 'add\_last', but allow the metadata record to store a column map, to support instant add/drop/reorder of columns.
* **Commandline:** `--innodb-instant-alter-column-allowed=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Valid Values:**
	+ <= [MariaDB 10.3](../what-is-mariadb-103/index): `never`, `add_last`
	+ >= [MariaDB 10.4](../what-is-mariadb-104/index): `never`, `add_last`, `add_drop_reorder`
* **Default Value:**
	+ <= [MariaDB 10.3](../what-is-mariadb-103/index): `add_last`
	+ >= [MariaDB 10.4](../what-is-mariadb-104/index): `add_drop_reorder`
* **Introduced:** [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/)

 

---

 #### `innodb_instrument_semaphores`

 * **Description:** Enable semaphore request instrumentation. This could have some effect on performance but allows better information on long semaphore wait problems.
* **Commandline:** `--innodb-instrument-semaphores={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) (treated as if `OFF`)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_io_capacity`

 * **Description:** Limit on I/O activity for InnoDB background tasks, including merging data from the insert buffer and flushing pages. Should be set to around the number of I/O operations per second that system can handle, based on the type of drive/s being used. You can also set it higher when the server starts to help with the extra workload at that time, and then reduce for normal use. Ideally, opt for a lower setting, as at higher value data is removed from the buffers too quickly, reducing the effectiveness of caching. See also [innodb\_flush\_sync](#innodb_flush_sync).
	+ See [InnoDB Page Flushing: Configuring the InnoDB I/O Capacity](../innodb-page-flushing/index#configuring-the-innodb-io-capacity) for more information.
* **Commandline:** `--innodb-io-capacity=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `200`
* **Range:** `100` to `18446744073709551615` (264-1)

 

---

 #### `innodb_io_capacity_max`

 * **Description:** Upper limit to which InnoDB can extend [innodb\_io\_capacity](#innodb_io_capacity) in case of emergency. See [InnoDB Page Flushing: Configuring the InnoDB I/O Capacity](../innodb-page-flushing/index#configuring-the-innodb-io-capacity) for more information.
* **Commandline:** `--innodb-io-capacity-max=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2000` or twice [innodb\_io\_capacity](#innodb_io_capacity), whichever is higher.
* **Range :** `100` to `18446744073709551615` (264-1)

 

---

 #### `innodb_kill_idle_transaction`

 * **Description:** Time in seconds before killing an idle XtraDB transaction. If set to `0` (the default), the feature is disabled. Used to prevent accidental user locks. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_large_prefix`

 * **Description:** If set to `1`, tables that use specific [row formats](../innodb-row-formats-overview/index) are permitted to have index key prefixes up to 3072 bytes (for 16k pages, [smaller otherwise](../innodb-limitations/index#page-sizes)). If not set, the limit is 767 bytes.
	+ This applies to the `[DYNAMIC](../innodb-dynamic-row-format/index)` and `[COMPRESSED](../innodb-compressed-row-format/index)` row formats.
	+ Removed in 10.3.1 and restored as a deprecated and unused variable in 10.4.3 for compatibility purposes.
* **Commandline:** `--innodb-large-prefix`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`
* **Deprecated:** [MariaDB 10.2](../what-is-mariadb-102/index)
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)
* **Re-introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) (for compatibility purposes)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_lazy_drop_table`

 * **Description:** Deprecated and removed in XtraDB 5.6. [DROP TABLE](../drop-table/index) processing can take a long time when [innodb\_file\_per\_table](#innodb_file_per_table) is set to 1 and there's a large [buffer pool](../xtradbinnodb-memory-buffer/index). If `innodb_lazy_drop_table` is set to `1` (`0` is default), XtraDB attempts to optimize [DROP TABLE](../drop-table/index) processing by deferring the dropping of related pages from the [buffer pool](../xtradbinnodb-memory-buffer/index) until there is time, only initially marking them.
* **Commandline:** `innodb-lazy-drop-table={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Deprecated:** XtraDB 5.5.30-30.2
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `innodb_lock_schedule_algorithm`

 * **Description:** Specifies the algorithm that InnoDB uses to decide which of the waiting transactions should be granted the lock once it has been released. The possible values are: `FCFS` (First-Come-First-Served) where locks are granted in the order they appear in the lock queue and `VATS` (Variance-Aware-Transaction-Scheduling) where locks are granted based on the Eldest-Transaction-First heuristic. Note that `VATS` should not be used with [Galera](../galera/index), and InnoDB will refuse to start if `VATS` is used with Galera. From [MariaDB 10.2.12](https://mariadb.com/kb/en/mariadb-10212-release-notes/), the value was be changed to `FCFS` and a warning produced when using Galera.
* **Commandline:** `--innodb-lock-schedule-algorithm=#`
* **Scope:** Global
* **Dynamic:** No (>= [MariaDB 10.2.12](https://mariadb.com/kb/en/mariadb-10212-release-notes/), [MariaDB 10.1.30](https://mariadb.com/kb/en/mariadb-10130-release-notes/)), Yes (<= [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/))
* **Data Type:** `enum`
* **Valid Values:** `FCFS`, `VATS`
* **Default Value:** `FCFS` ([MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/)), `VATS` ([MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)), `FCFS` ([MariaDB 10.1](../what-is-mariadb-101/index))
* **Deprecated:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_lock_wait_timeout`

 * **Description:** Time in seconds that an InnoDB transaction waits for an InnoDB record lock (or table lock) before giving up with the error `ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction`. When this occurs, the statement (not transaction) is rolled back. The whole transaction can be rolled back if the [innodb\_rollback\_on\_timeout](#innodb_rollback_on_timeout) option is used. Increase this for data warehousing applications or where other long-running operations are common, or decrease for OLTP and other highly interactive applications. This setting does not apply to deadlocks, which InnoDB detects immediately, rolling back a deadlocked transaction. `0` means no wait. See [WAIT and NOWAIT](../wait-and-nowait/index). Setting to `100000000` or more (from [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/), `100000000` is the maximum) means the timeout is infinite.
* **Commandline:** `--innodb-lock-wait-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `INT UNSIGNED` (>= [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/)), `BIGINT UNSIGNED` (<= [MariaDB 10.6.2](https://mariadb.com/kb/en/mariadb-1062-release-notes/))
* **Default Value:** `50`
* **Range:**
	+ `0` to `100000000` (>= [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/))
	+ `0` to `1073741824` (>= [MariaDB 10.3](../what-is-mariadb-103/index) to <= [MariaDB 10.6.2](https://mariadb.com/kb/en/mariadb-1062-release-notes/))

 

---

 #### `innodb_locking_fake_changes`

 * **Description:** From [MariaDB 5.5](../what-is-mariadb-55/index) to [MariaDB 10.1](../what-is-mariadb-101/index), XtraDB-only option that if set to `OFF`, fake transactions (see [innodb\_fake\_changes](#innodb_fake_changes)) don't take row locks. This is an experimental feature to attempt to deal with drawbacks in fake changes blocking real locks. It is not safe for use in all environments. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-locking-fake-changes`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_locks_unsafe_for_binlog`

 * **Description:** Set to `0` by default, in which case XtraDB/InnoDB uses [gap locking](../xtradbinnodb-lock-modes/index#gap-locks). If set to `1`, gap locking is disabled for searches and index scans. Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index), and removed in [MariaDB 10.5](../what-is-mariadb-105/index), use [READ COMMITTED transaction isolation level](../set-transaction/index#read-committed) instead.
* **Commandline:** `--innodb-locks-unsafe-for-binlog`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `innodb_log_arch_dir`

 * **Description:** The directory for [XtraDB redo log](../innodb-redo-log/index) archiving. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-log-arch-dir=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `./`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_log_arch_expire_sec`

 * **Description:** Time in seconds since the last change after which the archived [XtraDB redo log](../xtradbinnodb-redo-log/index) should be deleted. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-log-arch-expire-sec=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_log_archive`

 * **Description:** Whether or not [XtraDB redo log](../xtradbinnodb-redo-log/index) archiving is enabled. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-log-archive={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_log_block_size`

 * **Description:** Size in bytes of the [XtraDB redo log](../xtradbinnodb-redo-log/index) records. Generally `512`, the default, or `4096`, are the only two useful values. If the server is restarted and this value is changed, all old log files need to be removed. Should be set to `4096` for SSD cards or if [innodb\_flush\_method](#innodb_flush_method) is set to `ALL_O_DIRECT` on ext4 filesystems. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-log-block-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `512`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_log_buffer_size`

 * **Description:** Size in bytes of the buffer for writing [InnoDB redo log](../xtradbinnodb-redo-log/index) files to disk. Increasing this means larger transactions can run without needing to perform disk I/O before committing.
* **Commandline:** `--innodb-log-buffer-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `16777216` (16MB)
* **Range:** `262144` to `4294967295` (256KB to 4096MB)

 

---

 #### `innodb_log_checksum_algorithm`

 * **Description:** Experimental feature (as of [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/)), this variable specifies how to generate and verify [XtraDB redo log](../xtradbinnodb-redo-log/index) checksums. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
	+ `none` - No checksum. A constant value is instead written to logs, and no checksum validation is performed.
	+ `innodb` - The default, and the original InnoDB algorithm. This is inefficient, but compatible with all MySQL, MariaDB and Percona versions that don't support other checksum algorithms.
	+ `crc32` - CRC32© is used for log block checksums, which also permits recent CPUs to use hardware acceleration (on SSE4.2 x86 machines and Power8 or later) for the checksums.
	+ `strict_*` - Whether or not to accept checksums from other algorithms. If strict mode is used, checksums blocks will be considered corrupt if they don't match the specified algorithm. Normally they are considered corrupt only if no other algorithm matches.
* **Commandline:** `innodb-log-checksum-algorithm=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:**
	+ `deprecated` (>= [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/))
	+ `innodb` (<= [MariaDB 10.1](../what-is-mariadb-101/index))
* **Valid Values:**
	+ `deprecated`, `innodb`, `none`, `crc32`, `strict_none`, `strict_innodb`, `strict_crc32` (>= [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/))
	+ `innodb`, `none`, `crc32`, `strict_none`, `strict_innodb`, `strict_crc32` (<= [MariaDB 10.1](../what-is-mariadb-101/index))
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_log_checksums`

 * **Description:** If set to `1`, the CRC32C for Innodb or `innodb_log_checksum_algorithm` for XtraDB algorithm is used for [InnoDB redo log](../xtradbinnodb-redo-log/index) pages. If disabled, the checksum field contents are ignored. From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), the variable is deprecated, and checksums are always calculated, as previously, the InnoDB redo log used the slow innodb algorithm, but with hardware or SIMD assisted CRC-32C computation being available, there is no reason to allow checksums to be disabled on the redo log.
* **Commandline:** `innodb-log-checksums={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_log_compressed_pages`

 * **Description:** Whether or not images of recompressed pages are stored in the [InnoDB redo log](../innodb-redo-log/index). Deprecated and ignored from [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/).
* **Commandline:** `--innodb-log-compressed-pages={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `ON`
* **Deprecated:** [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_log_file_buffering`

 * **Description:** Whether the file system cache for ib\_logfile0 is enabled. In [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/), MariaDB disabled the file system cache on the InnoDB write-ahead log file (ib\_logfile0) by default on Linux. With [innodb\_flush\_trx\_log\_at\_commit=2](#innodb_flush_log_at_trx_commit) in particular, writing to the log via the file system cache typically improves throughput, especially on slow storage or at a small number of concurrent transactions. For other values of innodb\_flush\_log\_at\_trx\_commit, direct writes were observed to be mostly but not always faster. Whether it pays off to disable the file system cache on the log may depend on the type of storage, the workload, and the operating system kernel version. If the server is started up with [innodb\_flush\_log\_at\_trx\_commit=2](#innodb_flush_log_at_trx_commit), the value will be changed to `ON`. Will be set to `OFF` if [innodb\_flush\_method](#innodb_flush_method) is set to `O_DSYNC`. On Linux, when the physical block size cannot be determined to be a power of 2 between 64 and 4096 bytes, the file system cache cannot be disabled, and innodb\_log\_file\_buffering=ON cannot be changed. Linux and Windows only.
* **Commandline:** `--innodb-log-file-buffering={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/), [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/)

 

---

 #### `innodb_log_file_size`

 * **Description:** Size in bytes of each [InnoDB redo log](../innodb-redo-log/index) file in the log group. The combined size can be no more than 512GB. Larger values mean less disk I/O due to less flushing checkpoint activity, but also slower recovery from a crash. In [MariaDB 10.5](../what-is-mariadb-105/index), crash recovery has been improved and shouldn't run out of memory, so the default has been increased. It can safely be set higher to reduce checkpoint flushing, even larger than [innodb\_buffer\_pool\_size](#innodb_buffer_pool_size).  
From [MariaDB 10.9](../what-is-mariadb-109/index) the variable is dynamic, and the server no longer needs to be restarted for the resizing to take place. Unless the log is located in a persistent memory file system (PMEM), an attempt to [SET GLOBAL](../set/index) innodb\_log\_file\_size to less than [innodb\_log\_buffer\_size](#innodb_log_buffer_size) will be refused. Log resizing can be aborted by killing the connection that is executing the SET GLOBAL statement.
* **Commandline:** `--innodb-log-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes (>= [MariaDB 10.9](../what-is-mariadb-109/index)), No (<= [MariaDB 10.8](../what-is-mariadb-108/index))
* **Data Type:** `numeric`
* **Default Value:** `100663296` (96MB) (>= [MariaDB 10.5](../what-is-mariadb-105/index)), `50331648` (48MB) (<= [MariaDB 10.4](../what-is-mariadb-104/index))
* **Range:**
	+ >= [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/): `4194304` to `512GB` (4MB to 512GB)
	+ <= [MariaDB 10.8.2](https://mariadb.com/kb/en/mariadb-1082-release-notes/): `1048576` to `512GB` (1MB to 512GB)

 

---

 #### `innodb_log_file_write_through`

 * **Description:** Whether each write to ib\_logfile0 is write through (disabling any caching, as in O\_SYNC or O\_DSYNC). Set to `OFF` by default, will be set to `ON` if [innodb\_flush\_method](#innodb_flush_method) is set to `O_DSYNC`. On systems that support FUA it may make sense to enable write-through, to avoid extra system calls.
* **Commandline:** `--innodb-log-file-write-through={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 11.0.0](https://mariadb.com/kb/en/mariadb-11-0-0-release-notes/)

 

---

 #### `innodb_log_files_in_group`

 * **Description:** Number of physical files in the [InnoDB redo log](../xtradbinnodb-redo-log/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Commandline:** `--innodb-log-files-in-group=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1` (>= [MariaDB 10.5](../what-is-mariadb-105/index)), `2` (<= [MariaDB 10.4](../what-is-mariadb-104/index))
* **Range:** `1` to `100` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_log_group_home_dir`

 * **Description:** Path to the [InnoDB redo log](../xtradbinnodb-redo-log/index) files. If none is specified, [innodb\_log\_files\_in\_group](#innodb_log_files_in_group) files named ib\_logfile0 and so on, with a size of [innodb\_log\_file\_size](#innodb_log_file_size) are created in the data directory.
* **Commandline:** `--innodb-log-group-home-dir=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`

 

---

 #### `innodb_log_optimize_ddl`

 * **Description:** Whether [InnoDB redo log](../innodb-redo-log/index) activity should be reduced when natively creating indexes or rebuilding tables. Reduced logging requires additional page flushing and interferes with [Mariabackup](../mariabackup/index). Enabling this may slow down backup and cause delay due to page flushing. Deprecated and ignored from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). Deprecated (but not ignored) from [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/) and [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/).
* **Commandline:** `--innodb-log-optimize-ddl={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:**
	+ `OFF` (>= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/))
	+ `ON` (<= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10415-release-notes/), [MariaDB 10.3.25](https://mariadb.com/kb/en/mariadb-10325-release-notes/), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10234-release-notes/))
* **Introduced:** [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/), [MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/)
* **Deprecated:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_log_write_ahead_size`

 * **Description:** [InnoDB redo log](../innodb-redo-log/index) write ahead unit size to avoid read-on-write. Should match the OS cache block IO size. Removed in [MariaDB 10.8](../what-is-mariadb-108/index), and instead on Linux and Windows, the physical block size of the underlying storage is detected and used.
* **Commandline:** `--innodb-log-write-ahead-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8192`
* **Range:** `512` to [innodb\_page\_size](#innodb_page_size)
* **Removed:** [MariaDB 10.8](../what-is-mariadb-108/index)

 

---

 #### `innodb_lru_flush_size`

 * **Description:** Number of pages to flush on LRU eviction.
* **Commandline:** `--innodb-lru-flush-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `32`
* **Range:** `1` to `18446744073709551615`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/)

 

---

 #### `innodb_lru_scan_depth`

 * **Description:** Specifies how far down the buffer pool least-recently used (LRU) list the cleaning thread should look for dirty pages to flush. This process is performed once a second. In an I/O intensive-workload, can be increased if there is spare I/O capacity, or decreased if in a write-intensive workload with little spare I/O capacity.
	+ See [InnoDB Page Flushing](../innodb-page-flushing/index) for more information.
* **Commandline:** `--innodb-lru-scan-depth=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `1536` (>= [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/))
	+ `1024` (<= [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/))
* **Range - 32bit:** `100` to `232-1`
* **Range - 64bit:** `100` to `264-1`

 

---

 #### `innodb_max_bitmap_file_size`

 * **Description:** Limit in bytes of the changed page bitmap files. For faster incremental backup with [Xtrabackup](../backup-restore-and-import-xtrabackup/index), XtraDB tracks pages with changes written to them according to the [XtraDB redo log](../xtradbinnodb-redo-log/index) and writes the information to special changed page bitmap files. These files are rotated when the server restarts or when this limit is reached. XtraDB only. See also [innodb\_track\_changed\_pages](#innodb_track_changed_pages) and [innodb\_max\_changed\_pages](#innodb_max_changed_pages).
	+ Deprecated and ignored in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-max-bitmap-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4096` (4KB)
* **Range:** `4096` (4KB) to `18446744073709551615` (16EB)
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)

 

---

 #### `innodb_max_changed_pages`

 * **Description:** Limit to the number of changed page bitmap files (stored in the [Information Schema INNODB\_CHANGED\_PAGES table](../information-schema-innodb_changed_pages-table/index)). Zero is unlimited. See [innodb\_max\_bitmap\_file\_size](#innodb_max_bitmap_file_size) and [innodb\_track\_changed\_pages](#innodb_track_changed_pages). Previously named `innodb_changed_pages_limit`. XtraDB only.
	+ Deprecated and ignored in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-max-changed-pages=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000000`
* **Range:** `0` to `18446744073709551615`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)

 

---

 #### `innodb_max_dirty_pages_pct`

 * **Description:** Maximum percentage of unwritten (dirty) pages in the buffer pool.
	+ See [InnoDB Page Flushing](../innodb-page-flushing/index) for more information.
* **Commandline:** `--innodb-max-dirty-pages-pct=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `90.000000` (>= [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/))
	+ `75.000000` (<= [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-1056-release-notes/))
* **Range:** `0` to `99.999`

 

---

 #### `innodb_max_dirty_pages_pct_lwm`

 * **Description:** Low water mark percentage of dirty pages that will enable preflushing to lower the dirty page ratio. The value 0 (default) means 'refer to [innodb\_max\_dirty\_pages\_pct](#innodb_max_dirty_pages_pct)'.
	+ See [InnoDB Page Flushing](../innodb-page-flushing/index) for more information.
* **Commandline:** `--innodb-max-dirty-pages-pct-lwm=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `99.999`

 

---

 #### `innodb_max_purge_lag`

 * **Description:** When purge operations are lagging on a busy server, setting innodb\_max\_purge\_lag can help. By default set to `0`, no lag, the figure is used to calculate a time lag for each INSERT, UPDATE, and DELETE when the system is lagging. InnoDB keeps a list of transactions with delete-marked index records due to UPDATE and DELETE statements. The length of this list is `purge_lag`, and the calculation, performed every ten seconds, is as follows: ((purge\_lag/innodb\_max\_purge\_lag)×10)–5 microseconds.
* **Commandline:** `--innodb-max-purge-lag=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`

 

---

 #### `innodb_max_purge_lag_delay`

 * **Description:** Maximum delay in milliseconds imposed by the [innodb\_max\_purge\_lag](#innodb_max_purge_lag) setting. If set to `0`, the default, there is no maximum.
* **Commandline:** `--innodb-max-purge-lag-delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

 #### `innodb_max_purge_lag_wait`

 * **Description:** Wait until History list length is below the specified limit.
* **Commandline:** `--innodb-max-purge-wait=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4294967295`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/), [MariaDB 10.3.26](https://mariadb.com/kb/en/mariadb-10326-release-notes/), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10235-release-notes/)

 

---

 #### `innodb_max_undo_log_size`

 * **Description:** If an undo tablespace is larger than this, it will be marked for truncation if [innodb\_undo\_log\_truncate](#innodb_undo_log_truncate) is set.
* **Commandline:** `--innodb-max-undo-log-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `10485760`
* **Range:** `10485760` to `18446744073709551615`

 

---

 #### `innodb_merge_sort_block_size`

 * **Description:** Size in bytes of the block used for merge sorting in fast index creation. Replaced in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 by [innodb\_sort\_buffer\_size](#innodb_sort_buffer_size).
* **Commandline:** `innodb-merge-sort-block-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1048576` (1M)
* **Range:** `1048576` (1M) to `1073741824` (1G)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced by [innodb\_sort\_buffer\_size](#innodb_sort_buffer_size)

 

---

 #### `innodb_mirrored_log_groups`

 * **Description:** Unused. Restored as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) - [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/)

 

---

 #### `innodb_mtflush_threads`

 * **Description:** Sets the number of threads to use in Multi-Threaded Flush operations. For more information, see [Fusion-io Multi-threaded Flush](../fusion-io-multi-threaded-flush/index).
	+ InnoDB's multi-thread flush feature was deprecated in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and removed from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/). In later versions of MariaDB, use `[innodb\_page\_cleaners](#innodb_page_cleaners)` system variable instead.
	+ See [InnoDB Page Flushing: Page Flushing with Multi-threaded Flush Threads](../innodb-page-flushing/index#page-flushing-with-multi-threaded-flush-threads) for more information.
* **Commandline:** `--innodb-mtflush-threads=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `1` to `64`
* **Deprecated:** [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/)
* **Removed:** [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `innodb_monitor_disable`

 * **Description:** Disables the specified counters in the [INFORMATION\_SCHEMA.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table.
* **Commandline:** `--innodb-monitor-disable=string`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `innodb_monitor_enable`

 * **Description:** Enables the specified counters in the [INFORMATION\_SCHEMA.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table.
* **Commandline:** `--innodb-monitor-enable=string`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `innodb_monitor_reset`

 * **Description:** Resets the count value of the specified counters in the [INFORMATION\_SCHEMA.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table to zero.
* **Commandline:** `--innodb-monitor-reset=string`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `innodb_monitor_reset_all`

 * **Description:** Resets all values for the specified counters in the [INFORMATION\_SCHEMA.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table.
* **Commandline:** `---innodb-monitor-reset-all=string`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `innodb_numa_interleave`

 * **Description:** Whether or not to use the NUMA interleave memory policy to allocate the [InnoDB buffer pool](../innodb-buffer-pool/index). Before [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), required that MariaDB be compiled on a NUMA-enabled Linux system.
* **Commandline:** `innodb-numa-interleave={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/)

 

---

 #### `innodb_old_blocks_pct`

 * **Description:** Percentage of the [buffer pool](../xtradbinnodb-memory-buffer/index) to use for the old block sublist.
* **Commandline:** `--innodb-old-blocks-pct=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `37`
* **Range:** `5` to `95`

 

---

 #### `innodb_old_blocks_time`

 * **Description:** Time in milliseconds an inserted block must stay in the old sublist after its first access before it can be moved to the new sublist. '0' means "no delay". Setting a non-zero value can help prevent full table scans clogging the [buffer pool](../xtradbinnodb-memory-buffer/index). See also [innodb\_old\_blocks\_pct](#innodb_old_blocks_pct).
* **Commandline:** `--innodb-old-blocks-time=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `0` to `232-1`

 

---

 #### `innodb_online_alter_log_max_size`

 * **Description:** The maximum size for temporary log files during online DDL (data and index structure changes). The temporary log file is used for each table being altered, or index being created, to store data changes to the table while the process is underway. The table is extended by [innodb\_sort\_buffer\_size](#innodb_sort_buffer_size) up to the limit set by this variable. If this limit is exceeded, the online DDL operation fails and all uncommitted changes are rolled back. A lower value reduces the time a table could lock at the end of the operation to apply all the log's changes, but also increases the chance of the online DDL changes failing.
* **Commandline:** `--innodb-online-alter-log-max-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `134217728`
* **Range:** `65536` to `264-1`

 

---

 #### `innodb_open_files`

 * **Description:** Maximum .ibd files MariaDB can have open at the same time. Only applies to systems with multiple XtraDB/InnoDB tablespaces, and is separate to the table cache and [open\_files\_limit](#open_files_limit). The default, if [innodb\_file\_per\_table](#innodb_file_per_table) is disabled, is 300 or the value of [table\_open\_cache](../server-system-variables/index#table_open_cache), whichever is higher. It will also auto-size up to the default value if it is set to a value less than `10`.
* **Commandline:** `--innodb-open-files=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `autosized`
* **Range:** `10` to `4294967295`

 

---

 #### `innodb_optimize_fulltext_only`

 * **Description:** When set to `1` (`0` is default), [OPTIMIZE TABLE](../optimize-table/index) will only process InnoDB [FULLTEXT index](../full-text-indexes/index) data. Only intended for use during fulltext index maintenance.
* **Commandline:** `--innodb-optimize-fulltext-only={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_page_cleaners`

 * **Description:** Number of page cleaner threads. The default is `4`, but the value will be set to the number of [innodb\_buffer\_pool\_instances](#innodb_buffer_pool_instances) if this is lower. If set to `1`, only a single cleaner thread is used, as was the case until [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/). Cleaner threads flush dirty pages from the [buffer pool](../xtradbinnodb-buffer-pool/index), performing flush list and least-recently used (LRU) flushing. Deprecated and ignored from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), as the original reasons for for splitting the buffer pool have mostly gone away.
	+ See [InnoDB Page Flushing: Page Flushing with Multiple InnoDB Page Cleaner Threads](../innodb-page-flushing/index#page-flushing-with-multiple-innodb-page-cleaner-threads) for more information.
* **Commandline:** `--innodb-page-cleaners=#`
* **Scope:** Global
* **Dynamic:** Yes (>= [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)), No (<= [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/))
* **Data Type:** `numeric`
* **Default Value:** `4` (or set to [innodb\_buffer\_pool\_instances](#innodb_buffer_pool_instances) if lower)
* **Range:** `1` to `64`
* **Deprecated:** [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_page_size`

 * **Description:** Specifies the page size in bytes for all InnoDB tablespaces. The default, `16k`, is suitable for most uses.
	+ A smaller InnoDB page size might work more effectively in a situation with many small writes (OLTP), or with SSD storage, which usually has smaller block sizes.
	+ A larger InnoDB page size can provide a larger [maximum row size](../innodb-row-formats-overview/index#maximum-row-size).
	+ InnoDB's page size can be as large as `64k` for tables using the following [row formats](../innodb-row-formats-overview/index): [DYNAMIC](../innodb-dynamic-row-format/index), [COMPACT](../innodb-compact-row-format/index), and [REDUNDANT](../innodb-redundant-row-format/index).
	+ InnoDB's page size must still be `16k` or less for tables using the [COMPRESSED](../innodb-compressed-row-format/index) row format.
	+ This system variable's value cannot be changed after the `datadir` has been initialized. InnoDB's page size is set when a MariaDB instance starts, and it remains constant afterwards.
* **Commandline:** `--innodb-page-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumeration`
* **Default Value:** `16384`
* **Valid Values:** `4k` or `4096`, `8k` or `8192`, `16k` or `16384`, `32k` and `64k`.

 

---

 #### `innodb_pass_corrupt_table`

 * **Removed:** XtraDB 5.5 - renamed [innodb\_corrupt\_table\_action](#innodb_corrupt_table_action).

 

---

 #### `innodb_prefix_index_cluster_optimization`

 * **Description:** Enable prefix optimization to sometimes avoid cluster index lookups. Deprecated and ignored from [MariaDB 10.10](../what-is-mariadb-1010/index), as the optimization is now always enabled.
* **Commandline:** `--innodb-prefix-index-cluster-optimization={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10101-release-notes/)

 

---

 #### `innodb_print_all_deadlocks`

 * **Description:** If set to `1` (`0` is default), all XtraDB/InnoDB transaction deadlock information is written to the [error log](../error-log/index).
* **Commandline:** `--innodb-print-all-deadlocks={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_purge_batch_size`

 * **Description:** Units of [InnoDB redo log](../xtradbinnodb-redo-log/index) records that will trigger a purge operation. Together with [innodb\_purge\_threads](#innodb_purge_threads) has a small effect on tuning.
* **Commandline:** `--innodb-purge-batch-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `1` to `5000`

 

---

 #### `innodb_purge_rseg_truncate_frequency`

 * **Description:** Frequency with which undo records are purged. Set by default to every 128 times, reducing this increases the frequency at which rollback segments are freed. See also [innodb\_undo\_log\_truncate](#innodb_undo_log_truncate).
* **Commandline:** `-- innodb-purge-rseg-truncate-frequency=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `128`
* **Range:** `1` to `128`

 

---

 #### `innodb_purge_threads`

 * **Description:** Number of background threads dedicated to InnoDB purge operations. The range is `1` to `32`. At least one background thread is always used from [MariaDB 10.0](../what-is-mariadb-100/index). The default was increased from `1` to `4` in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/). Setting to a value greater than 1 creates that many separate purge threads. This can improve efficiency in some cases, such as when performing DML operations on many tables. In [MariaDB 5.5](../what-is-mariadb-55/index), the options were `0` and `1`. If set to `0`, the default, purging is done with the primary thread. If set to `1`, purging is done on a separate thread, which could reduce contention. See also [innodb\_purge\_batch\_size](#innodb_purge_batch_size).
* **Commandline:** `--innodb-purge-threads=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**
	+ `4`
* **Range:** `1` to `32`

 

---

 #### `innodb_random_read_ahead`

 * **Description:** Originally, random read-ahead was always set as an optimization technique, but was removed in [MariaDB 5.5](../what-is-mariadb-55/index). `innodb_random_read_ahead` permits it to be re-instated if set to `1` (`0`) is default.
* **Commandline:** `--innodb-random-read-ahead={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_read_ahead`

 * **Description:** If set to `linear`, the default, XtraDB/InnoDB will automatically fetch remaining pages if there are enough within the same extent that can be accessed sequentially. If set to `none`, read-ahead is disabled. `random` has been removed and is now ignored, while `both` sets to both `linear` and `random`. Also see [innodb\_read\_ahead\_threshold](#innodb_read_ahead_threshold) for more control on read-aheads. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced by MySQL 5.6's [innodb\_random\_read\_ahead](#innodb_random_read_ahead).
* **Commandline:** `innodb-read-ahead=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `linear`
* **Valid Values:** `none`, `random`, `linear`, `both`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 - replaced by MySQL 5.6's [innodb\_random\_read\_ahead](#innodb_random_read_ahead)

 

---

 #### `innodb_read_ahead_threshold`

 * **Description:** Minimum number of pages XtraDB/InnoDB must read from an extent of 64 before initiating an asynchronous read for the following extent.
* **Commandline:** `--innodb-read-ahead-threshold=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `56`
* **Range:** `0` to `64`

 

---

 #### `innodb_read_io_threads`

 * **Description:** Number of I/O threads for InnoDB reads. You may on rare occasions need to reduce this default on Linux systems running multiple MariaDB servers to avoid exceeding system limits.
* **Commandline:** `--innodb-read-io-threads=#`
* **Scope:** Global
* **Dynamic:** Yes (>= [MariaDB 10.11](../what-is-mariadb-1011/index)), No (<= [MariaDB 10.10](../what-is-mariadb-1010/index))
* **Data Type:** `numeric`
* **Default Value:** `4`
* **Range:** `1` to `64`

 

---

 #### `innodb_read_only`

 * **Description:** If set to `1` (`0` is default), the server will be read-only. For use in distributed applications, data warehouses or read-only media.
* **Commandline:** `--innodb-read-only={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_read_only_compressed`

 * **Description:** If set (the default before [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/)), [ROW\_FORMAT=COMPRESSED](../innodb-compressed-row-format/index) tables will be read-only. This was intended to be the first step towards removing write support and deprecating the feature, but this plan has been abandoned.
* **Commandline:** `--innodb-read-only-compressed`, `--skip-innodb-read-only-compressed`
* **Scope:**
* **Dynamic:**
* **Data Type:** `boolean`
* **Default Value:** `OFF` (>= [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/)), `ON` (<= [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/))
* **Introduced:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_recovery_stats`

 * **Description:** If set to `1` (`0` is default) and recovery is necessary on startup, the server will write detailed recovery statistics to the error log at the end of the recovery process. This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** No
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `innodb_recovery_update_relay_log`

 * **Description:** If set to `1` (`0` is default), the relay log info file will be overwritten on crash recovery if the information differs from the InnoDB record. Should not be used if multiple storage engine types are being replicated. Previously named `innodb_overwrite_relay_log_info`. Removed in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6 and replaced by MySQL 5.6's `relay-log-recovery`
* **Commandline:** `innodb-recovery-update-relay-log={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced by MySQL 5.6's `relay-log-recovery`

 

---

 #### `innodb_replication_delay`

 * **Description:** Time in milliseconds for the replica server to delay the replication thread if [innodb\_thread\_concurrency](#innodb_thread_concurrency) is reached. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).
* **Commandline:** `--innodb-replication-delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_rollback_on_timeout`

 * **Description:** InnoDB usually rolls back the last statement of a transaction that's been timed out (see [innodb\_lock\_wait\_timeout](#innodb_lock_wait_timeout)). If innodb\_rollback\_on\_timeout is set to 1 (0 is default), InnoDB will roll back the entire transaction. Before [MariaDB 5.5](../what-is-mariadb-55/index), rolling back the entire transaction was the default behavior.
* **Commandline:** `--innodb-rollback-on-timeout`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `innodb_rollback_segments`

 * **Description:** Specifies the number of rollback segments that XtraDB/InnoDB will use within a transaction (see [undo log](../undo-log/index)). Deprecated and replaced by [innodb\_undo\_logs](#innodb_undo_logs) in [MariaDB 10.0](../what-is-mariadb-100/index).
* **Commandline:** `--innodb-rollback-segments=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `128`
* **Range:** `1` to `128`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `innodb_safe_truncate`

 * **Description:** Use a backup-safe [TRUNCATE TABLE](../truncate-table/index) implementation and crash-safe rename operations inside InnoDB. This is not compatible with hot backup tools other than [Mariabackup](../mariabackup-overview/index). Users who need to use such tools may set this to `OFF`.
* **Commandline:** `--innodb-safe-truncate={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_scrub_log`

 * **Description:** Enable [InnoDB redo log](../xtradbinnodb-redo-log/index) scrubbing. See [Data Scrubbing](../xtradbinnodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), as never really worked ([MDEV-13019](https://jira.mariadb.org/browse/MDEV-13019) and [MDEV-18370](https://jira.mariadb.org/browse/MDEV-18370)). If old log contents should be kept secret, then enabling [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) or setting a smaller [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) could help.
* **Commandline:** `--innodb-scrub-log`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_scrub_log_interval`

 * **Description:** Used with [Data Scrubbing](../xtradbinnodb-data-scrubbing/index) in 10.1.3 only - replaced in 10.1.4 by [innodb\_scrub\_log\_speed](#innodb_scrub_log_speed). [InnoDB redo log](../xtradbinnodb-redo-log/index) scrubbing interval in milliseconds.
* **Commandline:** `--innodb-scrub-log-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `56`
* **Range:** `0` to `50000`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)

 

---

 #### `innodb_scrub_log_speed`

 * **Description:** [InnoDB redo log](../xtradbinnodb-redo-log/index) scrubbing speed in bytes/sec. See [Data Scrubbing](../xtradbinnodb-data-scrubbing/index). Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Commandline:** `--innodb-scrub-log-speed=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `256`
* **Range:** `1` to `50000`
* **Deprecated:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_sched_priority_cleaner`

 * **Description:** Set a thread scheduling priority for cleaner and least-recently used (LRU) manager threads. The range from `0` to `39` corresponds in reverse order to Linux nice values of `-20` to `19`. So `0` is the lowest priority (Linux nice value `19`) and `39` is the highest priority (Linux nice value `-20`). XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-sched-priority-cleaner=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `19`
* **Range:** `0` to `39`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_show_locks_held`

 * **Description:** Specifies the number of locks held for each InnoDB transaction to be displayed in [SHOW ENGINE INNODB STATUS](../show-engine/index) output. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-show-locks-held=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `1000`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_show_verbose_locks`

 * **Description:** If set to `1`, and [innodb\_status\_output\_locks](#innodb_status_output_locks) is also ON, the traditional InnoDB behavior is followed and locked records will be shown in [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. If set to `0`, the default, only high-level information about the lock is shown. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-show-verbose-locks=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_simulate_comp_failures`

 * **Description:** Simulate compression failures. Used for testing robustness against random compression failures. XtraDB only.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `99`

 

---

 #### `innodb_sort_buffer_size`

 * **Description:** Size of the sort buffers used for sorting data when an InnoDB index is created, as well as the amount by which the temporary log file is extended during online DDL operations to record concurrent writes. The larger the setting, the fewer merge phases are required between buffers while sorting. When a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) creates a new index, three buffers of this size are allocated, as well as pointers for the rows in the buffer.
* **Commandline:** `--innodb-sort-buffer-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1048576` (1M)
* **Range:** `65536` to `67108864`

 

---

 #### `innodb_spin_wait_delay`

 * **Description:** Maximum delay (not strictly corresponding to a time unit) between spin lock polls. Default changed from `6` to `4` in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), as this was verified to give the best throughput by OLTP update index and read-write benchmarks on Intel Broadwell (2/20/40) and ARM (1/46/46).
* **Commandline:** `--innodb-spin-wait-delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4` (>= [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)), `6` (<= [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/))
* **Range:** `0` to `4294967295`

 

---

 #### `innodb_stats_auto_recalc`

 * **Description:** If set to `1` (the default), persistent statistics are automatically recalculated when the table changes significantly (more than 10% of the rows). Affects tables created or altered with STATS\_PERSISTENT=1 (see [CREATE TABLE](../create-table/index)), or when [innodb\_stats\_persistent](#innodb_stats_persistent) is enabled. [innodb\_stats\_persistent\_sample\_pages](#innodb_stats_persistent_sample_pages) determines how much data to sample when recalculating. See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).
* **Commandline:** `--innodb-stats-auto-recalc={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_stats_auto_update`

 * **Description:** If set to `0` (`1` is default), index statistics will not be automatically calculated except when an [ANALYZE TABLE](../analyze-table/index) is run, or the table is first opened. Replaced by [innodb\_stats\_auto\_recalc](#innodb_stats_auto_recalc) in [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index) - replaced by [innodb\_stats\_auto\_recalc](#innodb_stats_auto_recalc).

 

---

 #### `innodb_stats_include_delete_marked`

 * **Description:** Include delete marked records when calculating persistent statistics.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_stats_method`

 * **Description:** Determines how NULLs are treated for InnoDB index statistics purposes.
	+ `nulls_equal`: The default, all NULL index values are treated as a single group. This is usually fine, but if you have large numbers of NULLs the average group size is slanted higher, and the optimizer may miss using the index for ref accesses when it would be useful.
	+ `nulls_unequal`: The opposite approach to `nulls_equal` is taken, with each NULL forming its own group of one. Conversely, the average group size is slanted lower, and the optimizer may use the index for ref accesses when not suitable.
	+ `nulls_ignored`: Ignore NULLs altogether from index group calculations.
	+ See also [Index Statistics](../index-statistics/index), [aria\_stats\_method](../aria-server-system-variables/index#aria_stats_method) and [myisam\_stats\_method](../myisam-server-system-variables/index#myisam_stats_method).
* **Commandline:** `--innodb-stats-method=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `nulls_equal`
* **Valid Values:** `nulls_equal`, `nulls_unequal`, `nulls_ignored`

 

---

 #### `innodb_stats_modified_counter`

 * **Description:** The number of rows modified before we calculate new statistics. If set to `0`, the default, current limits are used.
* **Commandline:** `--innodb-stats-modified-counter=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `innodb_stats_on_metadata`

 * **Description:** If set to `1`, the default, XtraDB/InnoDB updates statistics when accessing the INFORMATION\_SCHEMA.TABLES or INFORMATION\_SCHEMA.STATISTICS tables, and when running metadata statements such as [SHOW INDEX](../show-index/index) or [SHOW TABLE STATUS](../show-table-status/index). If set to `0`, statistics are not updated at those times, which can reduce the access time for large schemas, as well as make execution plans more stable.
* **Commandline:** `--innodb-stats-on-metadata`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_stats_persistent`

 * **Description:** [ANALYZE TABLE](../analyze-table/index) produces index statistics, and this setting determines whether they will be stored on disk, or be required to be recalculated more frequently, such as when the server restarts. This information is stored for each table, and can be set with the STATS\_PERSISTENT clause when creating or altering tables (see [CREATE TABLE](../create-table/index)). See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).
* **Commandline:** `--innodb-stats-persistent={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_stats_persistent_sample_pages`

 * **Description:** Number of index pages sampled when estimating cardinality and statistics for indexed columns. Increasing this value will increases index statistics accuracy, but use more I/O resources when running [ANALYZE TABLE](../analyze-table/index). See [InnoDB Persistent Statistics](../innodb-persistent-statistics/index).
* **Commandline:** `--innodb-stats-persistent-sample-pages=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `20`

 

---

 #### `innodb_stats_sample_pages`

 * **Description:** Gives control over the index distribution statistics by determining the number of index pages to sample. Higher values produce more disk I/O, but, especially for large tables, produce more accurate statistics and therefore make more effective use of the query optimizer. Lower values than the default are not recommended, as the statistics can be quite inaccurate.
	+ If [innodb\_stats\_traditional](#innodb_stats_traditional) is enabled, then the exact number of pages configured by this system variable will be sampled for statistics.
	+ If [innodb\_stats\_traditional](#innodb_stats_traditional) is disabled, then the number of pages to sample for statistics is calculated using a logarithmic algorithm, so the exact number can change depending on the size of the table. This means that more samples may be used for larger tables.
	+ If [persistent statistics](../innodb-persistent-statistics/index) are enabled, then the [innodb\_stats\_persistent\_sample\_pages](#innodb_stats_persistent_sample_pages) system variable applies instead. [persistent statistics](../innodb-persistent-statistics/index) are enabled with the [innodb\_stats\_persistent](#innodb_stats_persistent) system variable.
	+ This system variable has been **deprecated**. The [innodb\_stats\_transient\_sample\_pages](#innodb_stats_transient_sample_pages) system variable should be used instead.
* **Commandline:** `--innodb-stats-sample-pages=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `1` to `264-1`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `innodb_stats_traditional`

 * **Description:** This system variable affects how the number of pages to sample for transient statistics is determined, in particular how [innodb\_stats\_transient\_sample\_pages](##innodb_stats_transient_sample_pages)#is used.
	+ If [innodb\_stats\_traditional](#innodb_stats_traditional) is enabled, then the exact number of pages configured by the system variable will be sampled for statistics.
	+ If [innodb\_stats\_traditional](#innodb_stats_traditional) is disabled, then the number of pages to sample for statistics is calculated using a logarithmic algorithm, so the exact number can change depending on the size of the table. This means that more samples may be used for larger tables.
	+ This system variable does not affect the calculation of [persistent statistics](../innodb-persistent-statistics/index).
* **Commandline:** `--innodb-stats-traditional={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_stats_transient_sample_pages`

 * **Description:** Gives control over the index distribution statistics by determining the number of index pages to sample. Higher values produce more disk I/O, but, especially for large tables, produce more accurate statistics and therefore make more effective use of the query optimizer. Lower values than the default are not recommended, as the statistics can be quite inaccurate.
	+ If `[innodb\_stats\_traditional](#innodb_stats_traditional)` is enabled, then the exact number of pages configured by this system variable will be sampled for statistics.
	+ If `[innodb\_stats\_traditional](#innodb_stats_traditional)` is disabled, then the number of pages to sample for statistics is calculated using a logarithmic algorithm, so the exact number can change depending on the size of the table. This means that more samples may be used for larger tables.
	+ If [persistent statistics](../innodb-persistent-statistics/index) are enabled, then the `[innodb\_stats\_persistent\_sample\_pages](#innodb_stats_persistent_sample_pages)` system variable applies instead. [persistent statistics](../innodb-persistent-statistics/index) are enabled with the `[innodb\_stats\_persistent](#innodb_stats_persistent)` system variable.
* **Commandline:** `--innodb-stats-transient-sample-pages=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `1` to `264-1`

 

---

 #### `innodb_stats_update_need_lock`

 * **Description:** Setting to `0` (`1` is default) may help reduce contention of the `&dict_operation_lock`, but also disables the *Data\_free* option in [SHOW TABLE STATUS](../show-table-status/index). This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `1`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6

 

---

 #### `innodb_status_output`

 * **Description:** Enable [InnoDB monitor](../xtradbinnodb-monitors/index) output to the [error log](../error-log/index).
* **Commandline:** `--innodb-status-output={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_status_output_locks`

 * **Description:** Enable [InnoDB lock monitor](../xtradb-innodb-monitors/index) output to the [error log](../error-log/index) and [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index). Also requires [innodb\_status\_output=ON](#innodb_status_output) to enable output to the error log.
* **Commandline:** `--innodb-status-output-locks={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_strict_mode`

 * **Description:** If set to `1` (the default), InnoDB will return errors instead of warnings in certain cases, similar to strict SQL mode. See [InnoDB Strict Mode](../innodb-strict-mode/index) for details.
* **Commandline:** `--innodb-strict-mode={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_support_xa`

 * **Description:** If set to `1`, the default, [XA transactions](../xa-transactions/index) are supported. XA support ensures data is written to the [binary log](../binary-log/index) in the same order to the actual database, which is critical for [replication](../replication/index) and disaster recovery, but comes at a small performance cost. If your database is set up to only permit one thread to change data (for example, on a replication replica with only the replication thread writing), it is safe to turn this option off. Removed in [MariaDB 10.3](../what-is-mariadb-103/index), XA transactions are always supported.
* **Commandline:** `--innodb-support-xa`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.2](../what-is-mariadb-102/index)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_sync_array_size`

 * **Description:** By default `1`, can be increased to split internal thread co-ordinating, giving higher concurrency when there are many waiting threads.
* **Commandline:** `--innodb-sync-array-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `1024`
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_sync_spin_loops`

 * **Description:** The number of times a thread waits for an XtraDB/InnoDB mutex to be freed before the thread is suspended.
* **Commandline:** `--innodb-sync-spin-loops=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `30`
* **Range:** `0` to `4294967295`

 

---

 #### `innodb_table_locks`

 * **Description:** If [autocommit](#autocommit) is set to to `0` (`1` is default), setting innodb\_table\_locks to `1`, the default, will cause XtraDB/InnoDB to lock a table internally upon a [LOCK TABLE](lock_tables).
* **Commandline:** `--innodb-table-locks`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_thread_concurrency`

 * **Description:** Once this number of threads is reached (excluding threads waiting for locks), XtraDB/InnoDB will place new threads in a wait state in a first-in, first-out queue for execution, in order to limit the number of threads running concurrently. A setting of `0`, the default, permits as many threads as necessary. A suggested setting is twice the number of CPU's plus the number of disks. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).
* **Commandline:** `--innodb-thread-concurrency=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `1000`
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_thread_concurrency_timer_based`

 * **Description:** If set to `1`, thread concurrency will be handled in a lock-free timer-based manner rather than the default mutex-based method. Depends on atomic op builtins being available. This Percona XtraDB variable has not been ported to XtraDB 5.6.
* **Commandline:** `innodb-thread-concurrency-timer-based={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6

 

---

 #### `innodb_thread_sleep_delay`

 * **Description:** Time in microseconds that InnoDB threads sleep before joining the queue. Setting to `0` disables sleep. Deprecated and ignored from [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Commandline:** `--innodb-thread-sleep-delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `0` (>= [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).)
	+ `10000` (<= [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))
* **Range:** `0` to `1000000`
* **Deprecated:** [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_temp_data_file_path`

 * **Description:**
* **Commandline:** `--innodb-temp-data-file-path=path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `ibtmp1:12M:autoextend`

 

---

 #### `innodb_tmpdir`

 * **Description:** Allows an alternate location to be set for temporary non-tablespace files. If not set (the default), files will be created in the usual [tmpdir](../server-system-variables/index#tmpdir) location.
* **Commandline:** `--innodb-tmpdir=path`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** Empty

 

---

 #### `innodb_track_changed_pages`

 * **Description:** For faster incremental backup with [Xtrabackup](../backup-restore-and-import-xtrabackup/index), XtraDB tracks pages with changes written to them according to the [XtraDB redo log](../xtradbinnodb-redo-log/index) and writes the information to special changed page bitmap files. This read-only variable is used for controlling this feature. See also [innodb\_max\_changed\_pages](#innodb_max_changed_pages) and [innodb\_max\_bitmap\_file\_size](#innodb_max_bitmap_file_size). XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-track-changed-pages={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)

 

---

 #### `innodb_track_redo_log_now`

 * **Description:** Available on debug builds only. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-track-redo-log-now={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)

 

---

 #### `innodb_undo_directory`

 * **Description:** Path to the directory (relative or absolute) that InnoDB uses to create separate tablespaces for the [undo logs](../undo-log/index). `.` (the default value before 10.2.2) leaves the undo logs in the same directory as the other log files. From [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), the default value is NULL, and if no path is specified, undo tablespaces will be created in the directory defined by [datadir](../server-system-variables/index#datadir). Use together with [innodb\_undo\_logs](#innodb_undo_logs) and [innodb\_undo\_tablespaces](#innodb_undo_tablespaces). Undo logs are most usefully placed on a separate storage device.
* **Commandline:** `--innodb-undo-directory=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** NULL

 

---

 #### `innodb_undo_log_truncate`

 * **Description:** When enabled, undo tablespaces that are larger than [innodb\_max\_undo\_log\_size](#innodb_max_undo_log_size) are marked for truncation. See also [innodb\_purge\_rseg\_truncate\_frequency](#innodb_purge_rseg_truncate_frequency).
* **Commandline:** `--innodb-undo-log-truncate[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `innodb_undo_logs`

 * **Description:** Specifies the number of rollback segments that XtraDB/InnoDB will use within a transaction (or the number of active [undo logs](../undo-log/index)). By default set to the maximum, `128`, it can be reduced to avoid allocating unneeded rollback segments. See the [Innodb\_available\_undo\_logs](../xtradbinnodb-server-status-variables/index#innodb_available_undo_logs) status variable for the number of undo logs available. See also [innodb\_undo\_directory](#innodb_undo_directory) and [innodb\_undo\_tablespaces](#innodb_undo_tablespaces). Replaced [innodb\_rollback\_segments](#innodb_rollback_segments) in [MariaDB 10.0](../what-is-mariadb-100/index). The [Information Schema XTRADB\_RSEG Table](../information-schema-xtradb_rseg-table/index) contains information about the XtraDB rollback segments. Deprecated and ignored in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), as it always makes sense to use the maximum number of rollback segments.
* **Commandline:** `--innodb-undo-logs=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `128`
* **Range:** `0` to `128`
* **Deprecated:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)
* **Removed:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `innodb_undo_tablespaces`

 * **Description:** Number of tablespaces files used for dividing up the [undo logs](../undo-log/index). By default (0), undo logs are all part of the system tablespace, which contains one undo tablespace more than the `innodb_undo_tablespaces` setting. A value of 1 is reset to 0 as 2 or more are needed for separate tablespaces. When the undo logs can grow large, splitting them over multiple tablespaces will reduce the size of any single tablespace. Until [MariaDB 10.11.1](mdb-10-11-1), must be set before InnoDB is initialized, or else MariaDB will fail to start, with an error saying that `InnoDB did not find the expected number of undo tablespaces`. The files are created in the directory specified by [innodb\_undo\_directory](#innodb_undo_directory), and are named `undoN`, N being an integer. The default size of an undo tablespace is 10MB. [innodb\_undo\_logs](#innodb_undo_logs) must have a non-zero setting for `innodb_undo_tablespaces` to take effect.
* **Commandline:** `--innodb-undo-tablespaces=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `3` (>= [MariaDB 11.0](../what-is-mariadb-110/index)), `0` (<= [MariaDB 10.11](../what-is-mariadb-1011/index))
* **Range:** `0`, or `2` to `95`

 

---

 #### `innodb_use_atomic_writes`

 * **Description:** Implement atomic writes on supported SSD devices. See [atomic write support](../atomic-write-support/index) for other variables affected when this is set.
* **Commandline:** `innodb-use-atomic-writes={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_use_fallocate`

 * **Description:** Preallocate files fast, using operating system functionality. On POSIX systems, posix\_fallocate system call is used.
	+ Automatically set to `1` when [innodb\_use\_atomic\_writes](#innodb_use_atomic_writes) is set - see [FusionIO DirectFS atomic write support](../fusionio-directfs-atomic-write-support/index).
	+ See [InnoDB Page Compression: Saving Storage Space with Sparse Files](../innodb-page-compression/index#saving-storage-space-with-sparse-files) for more information.
* **Commandline:** `innodb-use-fallocate={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) (treated as if `ON`)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_use_global_flush_log_at_trx_commit`

 * **Description:** Determines whether a user can set the variable [innodb\_flush\_log\_at\_trx\_commit](#innodb_flush_log_at_trx_commit). If set to `1`, a user cannot reset the value with a SET command, while if set to `1`, a user can reset the value of `innodb_flush_log_at_trx_commit`. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `innodb-use-global-flush-log-at-trx_commit={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_use_mtflush`

 * **Description:** Whether to enable Multi-Threaded Flush operations. For more information, see Fusion.
	+ InnoDB's multi-thread flush feature was deprecated in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and removed from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/). In later versions of MariaDB, use `[innodb\_page\_cleaners](#innodb_page_cleaners)` system variable instead.
	+ See [InnoDB Page Flushing: Page Flushing with Multi-threaded Flush Threads](../innodb-page-flushing/index#page-flushing-with-multi-threaded-flush-threads) for more information.
* **Commandline:** `--innodb-use-mtflush={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/)
* **Removed:** [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `innodb_use_native_aio`

 * **Description:** For Linux systems only, specified whether to use Linux's asynchronous I/O subsystem. Set to `ON` by default, it may be changed to `0` at startup if InnoDB detects a problem, or from [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/)/[MariaDB 10.7.1](https://mariadb.com/kb/en/mariadb-1071-release-notes/), if a 5.11 - 5.15 Linux kernel is detected, to avoid an io-uring bug/incompatibility ([MDEV-26674](https://jira.mariadb.org/browse/MDEV-26674)). MariaDB-10.6.6/MariaDB-10.7.2 and later also consider 5.15.3+ as a fixed kernel and default to `ON`. To really benefit from the setting, the files should be opened in O\_DIRECT mode ([innodb\_flush\_method=O\_DIRECT](#innodb_flush_method), default from [MariaDB 10.6](../what-is-mariadb-106/index)), to bypass the file system cache. In this way, the reads and writes can be submitted with DMA, using the InnoDB buffer pool directly, and no processor cycles need to be used for copying data.
* **Commandline:** `--innodb-use-native-aio={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `innodb_use_purge_thread`

 * **Description:** Usually with InnoDB, data changed by a transaction is written to an undo space to permit read consistency, and freed when the transaction is complete. Many, or large, transactions, can cause the main tablespace to grow dramatically, reducing performance. This option, introduced in XtraDB 5.1 and removed for 5.5, allows multiple threads to perform the purging, resulting in slower, but much more stable performance.
* **Commandline:** `--innodb-use-purge-thread=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `32`
* **Removed:** XtraDB 5.5

 

---

 #### `innodb_use_stacktrace`

 * **Description:** If set to `ON` (`OFF` is default), a signal handler for SIGUSR2 is installed when the InnoDB server starts. When a long semaphore wait is detected at sync/sync0array.c, a SIGUSR2 signal is sent to the waiting thread and thread that has acquired the RW-latch. For both threads a full stacktrace is produced as well as if possible. XtraDB only. Added as a deprecated and ignored option in [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) (which uses InnoDB as default instead of XtraDB) to allow for easier upgrades.
* **Commandline:** `--innodb-use-stacktrace={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Deprecated:** [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_use_sys_malloc`

 * **Description:** If set the `1`, the default, XtraDB/InnoDB will use the operating system's memory allocator. If set to `0` it will use its own. Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index) and removed in [MariaDB 10.2](../what-is-mariadb-102/index) along with InnoDB's internal memory allocator.
* **Commandline:** `--innodb-use-sys-malloc={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.0](../what-is-mariadb-100/index)
* **Removed**: [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `innodb_use_sys_stats_table`

 * **Description:** If set to `1` (`0` is default), XtraDB will use the SYS\_STATS system table for extra table index statistics. When a table is opened for the first time, statistics will then be loaded from SYS\_STATS instead of sampling the index pages. Statistics are designed to be maintained only by running an [ANALYZE TABLE](../analyze-table/index). Replaced by MySQL 5.6's Persistent Optimizer Statistics.
* **Commandline:** `innodb-use-sys-stats-table={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)/XtraDB 5.6

 

---

 #### `innodb_use_trim`

 * **Description:** Use trim to free up space of compressed blocks.
	+ See [InnoDB Page Compression: Saving Storage Space with Sparse Files](../innodb-page-compression/index#saving-storage-space-with-sparse-files) for more information.
* **Commandline:** `--innodb-use-trim={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Deprecated:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)
* **Removed:** [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 

---

 #### `innodb_version`

 * **Description:** InnoDB version number. From [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), as the InnoDB implementation in MariaDB has diverged from MySQL, the MariaDB version is instead reported. For example, the InnoDB version reported in [MariaDB 10.1](../what-is-mariadb-101/index) (which is based on MySQL 5.6) included encryption and variable-size page compression before MySQL 5.7 introduced them. [MariaDB 10.2](../what-is-mariadb-102/index) (based on MySQL 5.7) introduced persistent AUTO\_INCREMENT ([MDEV-6076](https://jira.mariadb.org/browse/MDEV-6076)) in a GA release before MySQL 8.0. [MariaDB 10.3](../what-is-mariadb-103/index) (based on MySQL 5.7) introduced instant ADD COLUMN ([MDEV-11369](https://jira.mariadb.org/browse/MDEV-11369)) before MySQL.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `innodb_write_io_threads`

 * **Description:** Number of I/O threads for InnoDB writes. You may on rare occasions need to reduce this default on Linux systems running multiple MariaDB servers to avoid exceeding system limits.
* **Commandline:** `--innodb-write-io-threads=#`
* **Scope:** Global
* **Dynamic:** Yes (>= [MariaDB 10.11](../what-is-mariadb-1011/index)), No (<= [MariaDB 10.10](../what-is-mariadb-1010/index))
* **Data Type:** `numeric`
* **Default Value:** `4`
* **Range:** `1` to `64`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xtradbinnodb-server-system-variables/>

The mysql Database Tables
==========================

   MariaDB comes pre-installed with a system database called `mysql` containing many important tables storing, in particular, [grant and privilege](../grant/index) information. Before [MariaDB 10.4](../what-is-mariadb-104/index), system tables used the [MyISAM](../myisam/index) storage engine. From [MariaDB 10.4](../what-is-mariadb-104/index), they use [Aria](../aria/index).

  

| Title | Description |
| --- | --- |
|  [mysql.column\_stats Table](../mysqlcolumn_stats-table/index) |  Column stats for engine-independent statistics.  |
|  [mysql.columns\_priv Table](../mysqlcolumns_priv-table/index) |  Column-level privileges  |
|  [mysql.db Table](../mysqldb-table/index) |  Database-level access and privileges.  |
|  [mysql.event Table](../mysqlevent-table/index) |  Information about MariaDB events.  |
|  [mysql.func Table](../mysqlfunc-table/index) |  User-defined function information  |
|  [mysql.general\_log Table](../mysqlgeneral_log-table/index) |  Contents of the general query log if written to table  |
|  [mysql.global\_priv Table](../mysqlglobal_priv-table/index) |  Global privileges.  |
|  [mysql.gtid\_slave\_pos Table](../mysqlgtid_slave_pos-table/index) |  For replicas to keep track of the GTID.  |
|  [mysql.help\_category Table](../mysql-help_category-table/index) |  Help categories.  |
|  [mysql.help\_keyword Table](../mysql-help_keyword-table/index) |  Help keywords.  |
|  [mysql.help\_relation Table](../mysql-help_relation-table/index) |  HELP command relations  |
|  [mysql.help\_topic Table](../mysql-help_topic-table/index) |  Help topics.  |
|  [mysql.index\_stats Table](../mysqlindex_stats-table/index) |  Index stats for engine-independent statistics.  |
|  [mysql.innodb\_index\_stats](../mysqlinnodb_index_stats/index) |  Data related to particular persistent index statistics, multiple rows for each index.  |
|  [mysql.innodb\_table\_stats](../mysqlinnodb_table_stats/index) |  Data related to persistent indexes, one row per table.  |
|  [mysql.password\_reuse\_check\_history Table](../mysqlpassword_reuse_check_history-table/index) |  Contains old passwords for purposes of preventing password reuse.  |
|  [mysql.plugin Table](../mysql-plugin-table/index) |  Plugins loaded with INSTALL SONAME, INSTALL PLUGIN or the mariadb-plugin utility.  |
|  [mysql.proc Table](../mysqlproc-table/index) |  Information about stored routines.  |
|  [mysql.procs\_priv Table](../mysqlprocs_priv-table/index) |  Stored procedure and stored function privileges  |
|  [mysql.proxies\_priv Table](../mysqlproxies_priv-table/index) |  Proxy privileges.  |
|  [mysql.roles\_mapping Table](../mysqlroles_mapping-table/index) |  MariaDB roles information.  |
|  [mysql.servers Table](../mysqlservers-table/index) |  MariaDB servers  |
|  [mysql.slow\_log Table](../mysqlslow_log-table/index) |  Contents of the slow query log if written to table.  |
|  [mysql.tables\_priv Table](../mysqltables_priv-table/index) |  Table-level privileges  |
|  [mysql.table\_stats Table](../mysqltable_stats-table/index) |  Table stats for engine-independent statistics.  |
|  [mysql.time\_zone Table](../mysql-time_zone-table/index) |  Time zone table in the mysql database.  |
|  [mysql.time\_zone\_leap\_second Table](../mysql-time_zone_leap_second-table/index) |  Time zone leap second.  |
|  [mysql.time\_zone\_name Table](../mysql-time_zone_name-table/index) |  Time zone name.  |
|  [mysql.time\_zone\_transition Table](../mysql-time_zone_transition-table/index) |  Time zone transition table.  |
|  [mysql.time\_zone\_transition\_type Table](../mysql-time_zone_transition_type-table/index) |  Time zone transition type table.  |
|  [mysql.transaction\_registry Table](../mysql-transaction_registry-table/index) |  Used for transaction-precise versioning.  |
|  [mysql.user Table](../mysql-user-table/index) |  User access and global privileges.  |
|  [Obsolete mysql Database Tables](../obsolete-mysql-database-tables/index) |  Tables no longer present in the mysql system database.  |
|  [Spider mysql Database Tables](../spider-mysql-database-tables/index) |  System tables related to the Spider storage engine.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-mysql-database-tables/>

Instant ADD COLUMN for InnoDB
=============================

    Normally, adding a column to a table requires the full table to be rebuilt. The complexity of the operation is proportional to the size of the table, or O(n·m) where n is the number of rows in the table and m is the number of indexes. 

 In [MariaDB 10.0](../what-is-mariadb-100/index) and later, the [ALTER TABLE](../alter-table/index) statement supports [online DDL](../alter-table/index#online-ddl) for storage engines that have implemented the relevant online DDL [algorithms](../alter-table/index#algorithm) and [locking strategies](../alter-table/index#lock).

 The [InnoDB](../innodb/index) storage engine has implemented online DDL for many operations. These online DDL optimizations allow concurrent DML to the table in many cases, even if the table needs to be rebuilt.

 See [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index) for more information about online DDL with InnoDB.

 Allowing concurrent DML during the operation does not solve all problems. When a column was added to a table with the older in-place optimization, the resulting table rebuild could still significantly increase the I/O and memory consumption and cause replication lag.

 In contrast, with the new instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column), all that is needed is an O(log n) operation to insert a special hidden record into the table, and an update of the data dictionary. For a large table, instead of taking several hours, the operation would be completed in the blink of an eye. The [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) operation is only slightly more expensive than a regular [INSERT](../insert/index), due to locking constraints.

 In the past, some developers may have implemented a kind of "instant add column" in the application by encoding multiple columns in a single [TEXT](../text/index) or [BLOB](../blob/index) column. MariaDB [Dynamic Columns](../dynamic-columns/index) was an early example of that. A more recent example is [JSON](../json-functions/index) and related string manipulation functions.

 Adding real columns has the following advantages over encoding columns into a single "expandable" column:

 * Efficient storage in a native binary format
* Data type safety
* Indexes can be built natively
* Constraints are available: UNIQUE, CHECK, FOREIGN KEY
* DEFAULT values can be specified
* Triggers can be written more easily

 With instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column), you can enjoy all the benefits of structured storage without the drawback of having to rebuild the table.

 Instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) is available for both old and new InnoDB tables. Basically you can just upgrade from MySQL 5.x or MariaDB and start adding columns instantly.

 Columns instantly added to a table exist in a separate data structure from the main table definition, similar to how InnoDB separates `BLOB` columns. If the table ever becomes empty, (such as from [TRUNCATE](../truncate/index) or [DELETE](../delete/index) statements), InnoDB incorporates the instantly added columns into the main table definition. See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Non-canonical Storage Format Caused by Some Operations](../innodb-online-ddl-operations-with-algorithminstant/index#non-canonical-storage-format-caused-by-some-operations) for more information.

 The operation is also crash safe. If the server is killed while executing an instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column), when the table is restored InnoDB integrates the new column, flattening the table definition.

 Limitations
-----------

 * In [MariaDB 10.3](../what-is-mariadb-103/index), instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) only applies when the added columns appear last in the table. The place specifier `LAST` is the default. If `AFTER` col is specified, then col must be the last column, or the operation will require the table to be rebuilt. In [MariaDB 10.4](../what-is-mariadb-104/index), this restriction was lifted.

 * If the table contains a hidden `FTS_DOC_ID` column due to a [FULLTEXT INDEX](../full-text-indexes/index), then instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) will not be possible.

 * InnoDB data files after instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) cannot be imported to older versions of MariaDB or MySQL without first being rebuilt.

 * After using Instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column), any table-rebuilding operation such as [ALTER TABLE … FORCE](../alter-table/index#force) will incorporate instantaneously added columns into the main table body.

 * Instant [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) is not available for [ROW\_FORMAT=COMPRESSED](../innodb-storage-formats/index#compressed-row-format).

 * In [MariaDB 10.3](../what-is-mariadb-103/index), [ALTER TABLE … DROP COLUMN](../alter-table/index#drop-column) requires the table to be rebuilt. In [MariaDB 10.4](../what-is-mariadb-104/index), this restriction was lifted.

 Example
-------

 
```
CREATE TABLE t(id INT PRIMARY KEY, u INT UNSIGNED NOT NULL UNIQUE)
ENGINE=InnoDB;

INSERT INTO t(id,u) VALUES(1,1),(2,2),(3,3);

ALTER TABLE t ADD COLUMN
(d DATETIME DEFAULT current_timestamp(),
 p POINT NOT NULL DEFAULT ST_GeomFromText('POINT(0 0)'),
 t TEXT CHARSET utf8 DEFAULT 'The quick brown fox jumps over the lazy dog');

UPDATE t SET t=NULL WHERE id=3;

SELECT id,u,d,ST_AsText(p),t FROM t;

SELECT variable_value FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';

```

The above example illustrates that when the added columns are declared NOT NULL, a DEFAULT value must be available, either implied by the data type or set explicitly by the user. The expression need not be constant, but it must not refer to the columns of the table, such as DEFAULT u+1 (a MariaDB extension). The DEFAULT current\_timestamp() would be evaluated at the time of the ALTER TABLE and apply to each row, like it does for non-instant ALTER TABLE. If a subsequent ALTER TABLE changes the DEFAULT value for subsequent INSERT, the values of the columns in existing records will naturally be unaffected.

 The design was brainstormed in April by engineers from MariaDB Corporation, Alibaba and Tencent. A prototype was developed by Vin Chen (陈福荣) from the Tencent Game DBA Team.

 ### See Also

 * [Other INSTANT operations in InnoDB](../innodb-online-ddl-operations-with-the-instant-alter-algorithm/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/instant-add-column-for-innodb/>

systemd
=======

    `systemd` is a `[sysVinit](../sysvinit/index)` replacement that is the default service manager on the following Linux distributions:

 * RHEL 7 and above
* CentOS 7 and above
* Fedora 15 and above
* Debian 8 and above
* Ubuntu 15.04 and above
* SLES 12 and above
* OpenSUSE 12.2 and above

 MariaDB's `systemd` unit file is included in the server packages for [RPMs](../rpm/index) and [DEBs](../installing-mariadb-deb-files/index). It is also included in certain [binary tarballs](../installing-mariadb-binary-tarballs/index).

 The service name is `mariadb.service`.

 When MariaDB is started with the `systemd` unit file, it directly starts the `[mariadbd](../mariadbd-options/index)` process as the `mysql` user. Unlike with `[sysVinit](../sysvinit/index)`, the `[mariadbd](../mariadbd-options/index)` process is not started with `[mysqld\_safe](../mysqld_safe/index)`. As a consequence, options will not be read from the `[mysqld_safe]` [option group](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index).

 Contents of the MariaDB Service's Unit File
-------------------------------------------

 The contents of the `mariadb.service` file can be examined with `systemctl show mariadb.service`.

 Interacting with the MariaDB Server Process
-------------------------------------------

 The service can be interacted with by using the `[systemctl](https://www.freedesktop.org/software/systemd/man/systemctl.html)` command.

 ### Starting the MariaDB Server Process on Boot

 MariaDB's `systemd` service can be configured to start at boot by executing the following:

 
```
sudo systemctl enable mariadb.service

```

### Starting the MariaDB Server Process

 MariaDB's `systemd` service can be started by executing the following:

 
```
sudo systemctl start mariadb.service

```

MariaDB's `systemd` unit file has a default startup timeout of about 90 seconds on most systems. If certain startup tasks, such as crash recovery, take longer than this default startup timeout, then `systemd` will assume that `mariadbd` has failed to startup, which causes `systemd` to kill the `mariadbd` process. To work around this, you can reconfigure the MariaDB `systemd` unit to have an [infinite timeout](#configuring-the-systemd-service-timeout).

 Note that [systemd 236 added the `EXTEND_TIMEOUT_USEC` environment variable](https://lists.freedesktop.org/archives/systemd-devel/2017-December/039996.html) that allows services to extend the startup timeout during long-running processes. Starting with [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10133-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), and [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), on systems with systemd versions that support it, MariaDB uses this feature to extend the startup timeout during certain startup processes that can run long. Therefore, if you are using `systemd` 236 or later, then you should not need to manually override `TimeoutStartSec`, even if your startup tasks, such as crash recovery, run for longer than the configured value. See [MDEV-14705](https://jira.mariadb.org/browse/MDEV-14705) for more information.

 ### Stopping the MariaDB Server Process

 MariaDB's `systemd` service can be stopped by executing the following:

 
```
sudo systemctl stop mariadb.service

```

### Restarting the MariaDB Server Process

 MariaDB's `systemd` service can be restarted by executing the following:

 
```
sudo systemctl restart mariadb.service

```

### Checking the Status of the MariaDB Server Process

 The status of MariaDB's `systemd` service can be obtained by executing the following:

 
```
sudo systemctl status mariadb.service

```

### Interacting with Multiple MariaDB Server Processes

 A `systemd` [template unit file](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) with the name `mariadb@.service` is installed in `INSTALL_SYSTEMD_UNITDIR` on some systems. See [Locating the MariaDB Service's Unit File](#locating-the-mariadb-services-unit-file) to see what directory that refers to on each distribution.

 This template unit file allows you to interact with multiple MariaDB instances on the same system using the same template unit file. When you interact with a MariaDB instance using this template unit file, you have to provide an instance name as a suffix. For example, the following command tries to start a MariaDB instance with the name `node1`:

 
```
sudo systemctl start mariadb@node1.service

```


MariaDB's build system cannot include the `mariadb@.service` template unit file in [RPM](../rpm/index) packages on platforms that have `[cmake](../generic-build-instructions/index#using-cmake)` versions older than 3.3.0, because these `[cmake](../generic-build-instructions/index#using-cmake)` versions have a [bug](https://public.kitware.com/Bug/view.php?id=14782) that causes it to encounter errors when packaging a file in RPMs if the file name contains the `@` character. MariaDB's RHEL 7 and CentOS 7 RPM build hosts only got a new enough `[cmake](../generic-build-instructions/index#using-cmake)` version starting with [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), and [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/). To use this functionality on a MariaDB version that does not have the file, you can copy the file from a package that does have the file.

 
#### Default configuration of Multiple Instances in 10.4 and Later

 `systemd` will also look for an [option file](../configuring-mariadb-with-option-files/index) for a specific MariaDB instance based on the instance name. 

 It will use the `.%I` as the [custom option group suffix](../configuring-mariadb-with-option-files/index#custom-option-group-suffixes) that is appended to any [server option group](../configuring-mariadb-with-option-files/index#server-option-groups), in any configuration file included by default.

 In all distributions, the `%I` is the MariaDB instance name. In the above `node1` case, it would use the [option file](../configuring-mariadb-with-option-files/index) at the path`/etc/mynode1.cnf`.

 When using multiple instances, each instance will of course also need their own `[datadir](../server-system-variables/index#datadir)`, `[socket](../server-system-variables/index#socket)` and , `[port](../server-system-variables/index#port)` (unless `[skip\_networking](../server-system-variables/index#skip_networking) is specified). As [mariadb-install-db#option-groups](../mariadb-install-db/index#option-groups) reads the same sections as the server, and` ExecStartPre= `run [mariadb-install-db](../mariadb-install-db/index) within the service, the instances are autocreated if there is sufficient priviledges.`

 To use a 10.3 configuration in 10.4 or later and the following customisation in the editor after running `sudo systemctl edit mariadb@.service`:

 
```
[Unit]
ConditionPathExists=

[Service]
Environment='MYSQLD_MULTI_INSTANCE=--defaults-file=/etc/my%I.cnf'

```

#### Custom configuration of Multiple Instances in 10.4 and Later

 Because users may want to do many various things with their multiple instances, we've provided a way to let the user define how they wish their multiple instances to run. The systemd environment variable `MYSQLD_MULTI_INSTANCE` can be set to anything that [mariadbd](../mariadbd/index) and [mariadb-install-db](../mariadb-install-db/index) will recognise.

 A hosting environment where each user has their own instance may look like (with `sudo systemctl edit mariadb@.service`):

 
```
[Service]
ProtectHome=false
Environment='MYSQLD_MULTI_INSTANCE=--defaults-file=/home/%I/my.cnf \
                        --user=%I \
                        --socket=/home/%I.sock \ 
                        --datadir=/home/%I/mariadb_data \
                        --skip-networking'

```

Here the instance name is the unix user of the service.

 #### Configuring Multiple Instances in 10.3 and Earlier

 `systemd` will also look for an [option file](../configuring-mariadb-with-option-files/index) for a specific MariaDB instance based on the instance name. By default, it will look for the option file in a directory defined at build time by the `INSTALL_SYSCONF2DIR` option provided to `[cmake](../generic-build-instructions/index#using-cmake)`.

 For example, on RHEL, CentOS, Fedora, and other similar Linux distributions, `INSTALL_SYSCONF2DIR` is defined as `/etc/my.cnf.d/`, so it will look for an option file that matches the format:

 * `/etc/my.cnf.d/my%I.cnf`

 And on Debian, Ubuntu, and other similar Linux distributions, `INSTALL_SYSCONF2DIR` is defined as `/etc/mysql/conf.d//`, so it will look for an option file that matches the format:

 * `/etc/mysql/conf.d/my%I.cnf`

 In all distributions, the `%I` is the MariaDB instance name. In the above `node1` case, it would use the [option file](../configuring-mariadb-with-option-files/index) at the path`/etc/my.cnf.d/mynode1.cnf` for RHEL-like distributions and `/etc/mysql/conf.d/mynode1.cnf` for Debian-like distributions.

 When using multiple instances, each instance will of course also need their own `[datadir](../server-system-variables/index#datadir)`. See [mariadb-install-db](../mariadb-install-db/index) for information on how to initialize the `[datadir](../server-system-variables/index#datadir)` for additional MariaDB instances.

 Systemd and Galera Cluster
--------------------------

 ### Bootstrapping a New Cluster

 When using [Galera Cluster](../galera/index) with systemd, the first node in a cluster has to be started with `galera_new_cluster`. See [Getting Started with MariaDB Galera Cluster: Bootstrapping a New Cluster](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster) for more information.

 ### Recovering a Node's Cluster Position

 When using [Galera Cluster](../galera/index) with systemd, a node's position in the cluster can be recovered with `galera_recovery`. See [Getting Started with MariaDB Galera Cluster: Determining the Most Advanced Node](../getting-started-with-mariadb-galera-cluster/index#determining-the-most-advanced-node) for more information.

 ### SSTs and Systemd

 MariaDB's `systemd` unit file has a default startup timeout of about 90 seconds on most systems. If an SST takes longer than this default startup timeout on a joiner node, then `systemd` will assume that `mariadbd` has failed to startup, which causes `systemd` to kill the `mariadbd` process on the joiner node. To work around this, you can reconfigure the MariaDB `systemd` unit to have an [infinite timeout](#configuring-the-systemd-service-timeout). See [Introduction to State Snapshot Transfers (SSTs): SSTs and Systemd](../introduction-to-state-snapshot-transfers-ssts/index#ssts-and-systemd) for more information.

 Note that [systemd 236 added the `EXTEND_TIMEOUT_USEC` environment variable](https://lists.freedesktop.org/archives/systemd-devel/2017-December/039996.html) that allows services to extend the startup timeout during long-running processes. Starting with [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/), and [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/), on systems with systemd versions that support it, MariaDB uses this feature to extend the startup timeout during long SSTs. Therefore, if you are using `systemd` 236 or later, then you should not need to manually override `TimeoutStartSec`, even if your SSTs run for longer than the configured value. See [MDEV-15607](https://jira.mariadb.org/browse/MDEV-15607) for more information.

 Configuring the Systemd Service
-------------------------------

 You can configure MariaDB's `systemd` service by creating a "drop-in" configuration file for the `systemd` service. On most systems, the `systemd` service's directory for "drop-in" configuration files is `/etc/systemd/system/mariadb.service.d/`. You can confirm the directory and see what "drop-in" configuration files are currently loaded by executing:

 
```
$ sudo systemctl status mariadb.service
● mariadb.service - MariaDB 10.1.37 database server
   Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/mariadb.service.d
           └─migrated-from-my.cnf-settings.conf, timeoutstartsec.conf
...

```

If you want to configure the `systemd` service, then you can create a file with the `.conf` extension in that directory. The configuration option(s) that you would like to change would need to be placed in an appropriate section within the file, usually `[Service]`. If a `systemd` option is a list, then you may need to set the option to empty before you set the replacement values. For example:

 
```
[Service]

ExecStart=
ExecStart=/usr/bin/numactl --interleave=all  /usr/sbin/mariadbd $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION

```

After any configuration change, you will need to execute the following for the change to go into effect:

 
```
sudo systemctl daemon-reload

```

### Useful Systemd Options

 Useful `systemd` options are listed below. If an option is equivalent to a common `[mysqld\_safe](../mysqld_safe/index)` option, then that is also listed. Use `systemctl edit mariadb.service` to create the systemd option under a `[Service]` section header.

 


| mysqld\_safe option | systemd option | Comments |
| --- | --- | --- |
| no option | `[ProtectHome=false](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=)` | If any MariaDB files are in /home/ |
| no option | `[PrivateDevices=false](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateDevices=)` | If any MariaDB storage references raw block devices |
| no option | `[ProtectSystem=](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectSystem=)` | If any MariaDB write any files to anywhere under /boot, /usr or /etc |
| no option | `[TimeoutStartSec={time}](https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStartSec=)` | Service startup timeout. See [Configuring the Systemd Service Timeout](#configuring-the-systemd-service-timeout). |
| no option (see [MDEV-9264](https://jira.mariadb.org/browse/MDEV-9264)) | `[OOMScoreAdjust={priority}](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#OOMScoreAdjust=)` | e.g. -600 to lower priority of OOM killer for mariadbd |
| `[open-files-limit](../mysqld_safe/index#mysqld_safe-options)` | `[LimitNOFILE={limit}](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=)` | Limit on number of open files. See [Configuring the Open Files Limit](#configuring-the-open-files-limit). |
| `[core-file-size](../mysqld_safe/index#mysqld_safe-options)` | `[LimitCORE={size}](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=)` | Limit on core file size. Useful when [enabling core dumps](../enabling-core-dumps/index). See [Configuring the Core File Size](#configuring-the-core-file-size). |
|  | `[LimitMEMLOCK={size}](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=)` or `infinity` | Limit on how much can be locked in memory. Useful when [large-pages](../server-system-variables/index#large_pages) or [memlock](../mariadbd-options/index#-memlock) is used |
| `[nice](../mysqld_safe/index#mysqld_safe-options)` | `[Nice={nice value}](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Nice=)` |  |
| `[syslog](../mysqld_safe/index#mysqld_safe-options)` | `[StandardOutput=syslog](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardOutput=)` | See [Configuring MariaDB to Write the Error Log to Syslog](#configuring-mariadb-to-write-the-error-log-to-syslog). |
|  | `[StandardError=syslog](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardError=)` |  |
|  | `[SyslogFacility=daemon](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogFacility=)` |  |
|  | `[SyslogLevel=err](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogLevel=)` |  |
| `[syslog-tag](../mysqld_safe/index#mysqld_safe-options)` | `[SyslogIdentifier](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogIdentifier=)` |  |
| `[flush-caches](../mysqld_safe/index#mysqld_safe-options)` | ExecStartPre=/usr/bin/sync |  |
|  | ExecStartPre=/usr/sbin/sysctl -q -w vm.drop\_caches=3 |  |
| `[malloc-lib](../mysqld_safe/index#mysqld_safe-options)` | `[Environment=LD\_PRELOAD=/path/to/library](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment=)` |  |
| `[numa-interleave](../mysqld_safe/index#mysqld_safe-options)` | `[NUMAPolicy=interleave](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#NUMAPolicy=)` | from systemd v243 onwards |
|  | or: `ExecStart=/usr/bin/numactl --interleave=all /usr/sbin/mariadbd $MYSQLD_OPTS $_WSREP_NEW_CLUSTER $_WSREP_START_POSITION` | prepending `ExecStart=/usr/bin/numactl --interleave=all` to existing `ExecStart` setting |
| `[no-auto-restart](../mysqld_safe/index#mysqld_safe-options)` | Restart={exit-status} |  |

 
Note: the `[systemd](http://www.freedesktop.org/software/systemd/man/systemd.service.html)` manual contains the official meanings for these options. The manual also lists considerably more options than the ones listed above.

 There are other options and the `mariadb-service-convert` script will attempt to convert these as accurately as possible.

 ### Configuring the Systemd Service Timeout

 MariaDB's `[systemd](index)` unit file has a default startup timeout of about 90 seconds on most systems. If a service startup takes longer than this default startup timeout, then `systemd` will assume that `mariadbd` has failed to startup, which causes `systemd` to kill the `mariadbd` process. To work around this, it can be changed by configuring the `[TimeoutStartSec](https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStartSec=)` option for the `systemd` service.

 A similar problem can happen when stopping the MariaDB service. Therefore, it may also be a good idea to set `[TimeoutStopSec](https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStopSec=)`.

 For example, you can reconfigure the MariaDB `systemd` service to have an infinite timeout by executing one of the following commands:

 If you are using `systemd` 228 or older, then you can execute the following to set an infinite timeout:

 
```
sudo systemctl edit mariadb.service

[Service]

TimeoutStartSec=0
TimeoutStopSec=0

```

[Systemd 229 added the infinity option](https://lists.freedesktop.org/archives/systemd-devel/2016-February/035748.html), so if you are using `systemd` 229 or later, then you can execute the following to set an infinite timeout:

 
```
sudo systemctl edit mariadb.service

[Service]

TimeoutStartSec=infinity
TimeoutStopSec=infinity

```

Note that [systemd 236 added the EXTEND\_TIMEOUT\_USEC environment variable](https://lists.freedesktop.org/archives/systemd-devel/2017-December/039996.html) that allows services to extend the startup timeout during long-running processes. On systems with systemd versions that support it, MariaDB uses this feature to extend the startup timeout during certain startup processes that can run long.

 ### Configuring the Open Files Limit

 When using `systemd`, rather than setting the open files limit by setting the `[open-files-limit](../mysqld_safe/index#mysqld_safe-options)` option for `mysqld_safe` or the `[open\_files\_limit](../server-system-variables/index#open_files_limit)` system variable, the limit can be changed by configuring the `[LimitNOFILE](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=)` option for the MariaDB `systemd` service. The default is set to `LimitNOFILE=16364` in `mariadb.service`.

 For example, you can reconfigure the MariaDB `systemd` service to have a larger limit for open files by executing the following commands:

 
```
sudo systemctl edit mariadb.service

[Service]

LimitNOFILE=infinity

```

An important note is that setting `LimitNOFILE=infinity` doesn't actually set the open file limit to *infinite*.

 In `systemd` 234 and later, setting `LimitNOFILE=infinity` actually sets the open file limit to the value of the kernel's `fs.nr_open` parameter. Therefore, in these `systemd` versions, you may have to change this parameter's value.

 The value of the `fs.nr_open` parameter can be changed permanently by setting the value in `[/etc/sysctl.conf](https://linux.die.net/man/5/sysctl.conf)` and restarting the server.

 The value of the `fs.nr_open` parameter can be changed temporarily by executing the `[sysctl](https://linux.die.net/man/8/sysctl)` utility. For example:

 
```
sudo sysctl -w fs.nr_open=1048576‬

```

In `systemd` 233 and before, setting `LimitNOFILE=infinity` actually sets the open file limit to `65536`. See [systemd issue #6559](https://github.com/systemd/systemd/issues/6559) for more information. Therefore, in these `systemd` versions, it is not generally recommended to set `LimitNOFILE=infinity`. Instead, it is generally better to set `LimitNOFILE` to a very large integer. For example:

 
```
sudo systemctl edit mariadb.service

[Service]
LimitNOFILE=1048576

```

### Configuring the Core File Size

 When using `systemd`, if you would like to [enable core dumps](../enabling-core-dumps/index), rather than setting the core file size by setting the `[core-file-size](../mysqld_safe/index#mysqld_safe-options)` option for `mysqld_safe`, the limit can be changed by configuring the `[LimitCORE](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=)` option for the MariaDB `systemd` service. For example, you can reconfigure the MariaDB `systemd` service to have an infinite size for core files by executing the following commands:

 
```
sudo systemctl edit mariadb.service

[Service]
LimitCORE=infinity

```

### Configuring MariaDB to Write the Error Log to Syslog

 When using `systemd`, if you would like to redirect the [error log](../error-log/index) to the [syslog](https://linux.die.net/man/8/rsyslogd), then that can easily be done by doing the following:

 * Ensure that `[log\_error](../server-system-variables/index#log_error)` system variable is **not** set.
* Set `[StandardOutput=syslog](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardOutput=)`.
* Set `[StandardError=syslog](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#StandardError=)`.
* Set `[SyslogFacility=daemon](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogFacility=)`.
* Set `[SysLogLevel=err](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogLevel=)`.

 For example:

 
```
sudo systemctl edit mariadb.service

[Service]

StandardOutput=syslog
StandardError=syslog
SyslogFacility=daemon
SysLogLevel=err

```

If you have multiple instances of MariaDB, then you may also want to set `[SyslogIdentifier](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#SyslogIdentifier=)` with a different tag for each instance.

 ### Configuring LimitMEMLOCK

 If using [--memlock](../mariadbd-options/index#-memlock) or the iouring in InnoDB in [MariaDB 10.6](../what-is-mariadb-106/index) with a Linux Kernel version < 5.12, you will need to raise the LimitMEMLOCK limit.

 
```
sudo systemctl edit mariadb.service

[Service]

LimitMEMLOCK=2M

```

Note: Prior to [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/), the [--memlock](../mariadbd-options/index#-memlock) option could not be used with the MariaDB `systemd` service.

 ### Configuring Access to Home Directories

 MariaDB's [systemd](index) unit file restricts access to `/home`, `/root`, and `/run/user` by default. This restriction can be overridden by setting the [ProtectHome](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=) option to `false` for the MariaDB `systemd` service. This is done by creating a "drop-in" directory `/etc/systemd/system/mariadb.service.d/` and in it a file with a `.conf` suffix that contains the `ProtectHome=false` directive.

 You can reconfigure the MariaDB `systemd` service to allow access to `/home` by executing the following commands:

 
```
sudo systemctl edit mariadb.service

[Service]

ProtectHome=false

```

### Configuring the umask

 When using `systemd`, the default file permissions of `mariadbd` can be set by setting the `UMASK` and `UMASK_DIR` environment variables for the `systemd` service. For example, you can configure the MariaDB `systemd` service's umask by executing the following commands:

 
```
sudo systemctl edit mariadb.service

[Service]

Environment="UMASK=0750"
Environment="UMASK_DIR=0750"

```


These environment variables do not set the umask. They set the default file system permissions. See [MDEV-23058](https://jira.mariadb.org/browse/MDEV-23058) for more information.

 

Keep in mind that configuring the umask this way will only affect the permissions of files created by the `mariadbd` process that is managed by `systemd`. The permissions of files created by components that are not managed by `systemd`, such as [mariadb-install-db](../mariadb-install-db/index), will not be affected.

 
See [Specifying Permissions for Schema (Data) Directories and Tables](../specifying-permissions-for-schema-data-directories-and-tables/index) for more information.

 ### Configuring the data directory

 When doing a standard binary tarball install the datadir will be under /usr/local/data. The default systemd service file makes the whole /usr directory tree write protected however.

 So when just copying the distributed service file a tarball install will not start up, complaining e.g. about

 
```
[Warning] Can't create test file /usr/local/.../data/ubuntu-focal.lower-test
[ERROR] mariadbd: File '/usr/local/.../data/aria_log_control' not found (Errcode: 30 "Read-only file system")
[ERROR] mariadbd: Got error 'Can't open file' when trying to use aria control file '/usr/local/.../data/aria_log_control'

```

So when using a data directory under /usr/local that specific directory needs to be made writable for the service using the ReadWritePaths setting:

 
```
sudo systemctl edit mariadb.service

[Service]
ReadWritePaths=/usr/local/mysql/data

```

Systemd Socket Activation
-------------------------

 
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**MariaDB can use systemd's socket activation.

 
This is an on-demand service for MariaDB that will activate when required.

 Systemd socket activation uses a `mariadb.socket` definition file to define a set of UNIX and TCP sockets. Systemd will listen on these sockets, and when they are connected to, systemd will start the `mariadb.service` and hand over the socket file descriptors for MariaDB to process the connection.

 MariaDB remains running at this point and will have all sockets available and process connections exactly like it did before 10.6.

 When MariaDB is shut down, the systemd `mariadb.socket` remains active, and a new connection will restart the `mariadb.service`.

 ### Using Systemd Socket Activation

 To use MariaDB systemd socket activation, instead of enabling/starting `mariadb.service`, `mariadb.socket` is used instead.

 So the following commands work exactly like the `mariadb.service` equivalents.

 
```
systemctl start mariadb.socket
systemctl enable mariadb.socket

```

These files alone only contain the UNIX and TCP sockets and basic network connection information to which will be listening for connections. `@mariadb` is a UNIX abstract socket, which means it doesn't appear on the filesystem. Connectors based on MariaDB Connector/C will be able to connect with these by using the socket name directly, provided the higher level implementation doesn't try to test for the file's existence first. Some connectors like PHP use mysqlnd that is a pure PHP implementation and as such will only be able to connect to on filesystem UNIX sockets.

 With systemd activated sockets there is only a file descriptor limit on the number of listening sockets that can be created.

 ### When to Use Systemd Socket Activation

 A common use case for systemd socket activated MariaDB is when there needs to be a quick boot up time. MariaDB needs to be ready to run, but it doesn't need to be running.

 The ideal use case for systemd socket activation for MariaDB is for infrastructure providers running many multiple instances of MariaDB, where each instance is dedicated for a user.

 ### Downsides to Using Systemd Socket Activiation

 From the time the connection occurs, the client is going to be waiting until MariaDB has fully initialized before MariaDB can process the awaiting connection. If MariaDB was previously hard shutdown and needs to perform an extensive InnoDB rollback, then the activation time may be larger than the desired wait time of the client connection.

 ### Configuring Systemd Socket Activation

 When MariaDB is run under systemd socket activation, the usual [socket](../server-system-variables/index#socket) , [port](../server-system-variables/index#port), and [backlog](../server-system-variables/index#backlog) system variables are ignored, as these settings are contained within the systemd socket definition file.

 There is no configuration required in MariaDB to use MariaDB under socket activation.

 The systemd options available are from the `[systemd documentation](https://www.freedesktop.org/software/systemd/man/systemd.socket.html)`, however `[ListenStream](https://www.freedesktop.org/software/systemd/man/systemd.socket.html#ListenStream=)` and `[BackLog](https://www.freedesktop.org/software/systemd/man/systemd.socket.html#Backlog=)` would be the most common configuration options.

 As MariaDB isn't creating these sockets, the sockets don't need to be created with a `mysql` user. The sockets MariaDB may end up listening to under systemd socket activation, it may have not had the privileges to create itself.

 Changes to the default `mariadb.socket` can be made in the same way as services, `systemctl edit mariadb.socket`, or using `/etc/systemd/system/mariadb.socket.d/someconfig.conf` files.

 ### Extra Port

 A systemd socket can be configured as an `[extra\_port](../thread-pool-system-status-variables/index#extra_port), by using the` [FileDescriptorName=extra](https://www.freedesktop.org/software/systemd/man/systemd.socket.html#FileDescriptorName=) `in the` .socket `file.`

 The `mariadb-extra.socket` is already packaged and ready for use.

 ### Multi-instance socket activation

 `mariadb@.socket` is MariaDB's packaged multi-instance defination. It creates multiple UNIX sockets based on the socket file started.

 Starting `mariadb@bob.socket` will use the `mariadb@.socket` defination with `%I` within the defination replaced with "bob".

 When something connects to a socket defined there, the `mariadb@bob.service` will be started.

 Systemd Socket Activation for Hosting Service Providers
-------------------------------------------------------

 A systemd socket activation service with multi-instance can provide an on-demand per user access to a hosting service provider's dedicated database.

 "User", in this case, refers to the customer of the hosting service provider.

 ### End User Benefits

 This provides the following benefits for the user:

 * Each user has their own dedicated instance with the following benefits:
	+ The instance is free from the database contention of neighbors on MariaDB shared resources (table cache, connections, etc)
	+ The user is free to change their own configuration of MariaDB, within the limits and permissions of the service provider.
	+ Database service level backups, like mariabackup, are now directly available.
	+ A user can install their own plugins.
	+ The user can run a different database version to their neighbors.
	+ If a user's neighbor triggers a fault in the server, the uder's instance isn't affected.
* The database runs as their unix user in the server facilitating:
	+ User can directly migrate their MariaDB data directory to a different provider.
	+ The user's data is protected from other users on a kernel level.

 ### Hosting Service Provider Benefits

 In addition to providing user benefits as a sales item, the following are additional benefits for the hosting service provider compared to a monolith service:

 * Without passwords for the database, while still having security, support may be easier.
* When a user's database isn't active, there is no resource usage, only listening file descriptors by systemd.
* The socket activation transparently, with a minor startup time, starts the service as required.
* When the user's database hasn't had any activity after a time, it will deactivate ([MDEV-25282](https://jira.mariadb.org/browse/MDEV-25282)).
* Planned enhancements in InnoDB provide:
	+ an on-demand consumption of memory ([MDEV-25340](https://jira.mariadb.org/browse/MDEV-25340) .
	+ a proactive reduction in memory ([MDEV-25341](https://jira.mariadb.org/browse/MDEV-25341)).
	+ a memory resource pressure reduction in memory use ([MDEV-24670](https://jira.mariadb.org/browse/MDEV-24670)).
* The service provider can still cap the user's database memory usage in a ulimit way that a user cannot override in settings.
* The service provider may choose a CPU/memory/IO based billing to the user on Linux cgroup accounting rather than the available comprared to the rather limited options in `[CREATE USER](../create-user/index#resource-limit-options)`.
* Because a user's database will shutdown when inactive, a database upgrade on the server will not take effect for the user until it passively shuts down, restarts, and then gets reactivated hence reducing user downtime..

 ### Downsides to the Hosting Service Provider

 The extra memory used by more instances. This is mitigated by the on-demand activation. The deactivation when idle, and improved InnoDB memory management.

 With plenty of medium size database servers running, the Linux OOM kill has the opportunity to kill off only a small number of database servers running rather than everyones.

 ### Example on configuration Items for a per user, systemd socket activitated multi-instance service

 From a server pespective the operation would be as follows;

 To make the socket ready to connect and systemd will be listening to the socket:

 
```
# systemctl start mariadb@username.socket
# systemctl start mariadb-extra@username.socket

```

To enable this on reboot (the same way as a systemd service):

 
```
# systemctl enable mariadb@username.socket
# systemctl enable mariadb-extra@username.socket

```

#### A MariaDB Template File

 A global template file. Once installed as a user's `$HOME/.my.cnf` file, it will becomes the default for many applications, and the MariaDB server itself.

 
```
# cat /etc/my.cnf.templ
[client]
socket=/home/USER/mariadb.sock

[client-server]
user=USER

[mariadbd]
datadir=/home/USER/mariadb-datadir

```

#### Custom Configuration for the Multi-instance Service

 This extends/modifies the MariaDB multi-instance service.

 The feature of this extension are:

 * that it will autocreate configuration file for user applications
* It will install the database on first service start
* `auth-root-*` in [mariadb-install-db](../mariadb-install-db/index) means that the user is their own privileged user with unix socket authentication active. This means non-that user cannot access another users service, even with access to the unix socket(s). For more information see [unix socket authentication security](../authentication-plugin-unix-socket/index#security).
* If the MariaDB version was upgrade, the upgrade changes are made automatically
* `LimitData` places a hard upper limit so the user doesn't exceed a portion of the server resources

 
```
# cat /etc/systemd/system/mariadb@.service.d/user.conf
[Service]
User=%I
ProtectHome=false

Environment=MYSQLD_MULTI_INSTANCE="--defaults-file=/home/%I/.my.cnf"

ExecStartPre=
ExecStartPre=/bin/sh -c "[ -f /home/%I/.my.cnf ] || sed -e \"s/USER/%I/g\" /etc/my.cnf.templ > /home/%I/.my.cnf"
ExecStartPre=mkdir -p /home/%I/mariadb-datadir
ExecStartPre=/usr/bin/mariadb-install-db $MYSQLD_MULTI_INSTANCE --rpm \
   --auth-root-authentication-method=socket --auth-root-socket-user=%I
ExecStartPost=/usr/bin/mariadb-upgrade $MYSQLD_MULTI_INSTANCE

# To limit user based tuning
LimitData=768M
# For io_uring use by innodb on < 5.12 kernels
LimitMEMLOCK=1M

```

#### Custom Configuration for the Multi-instance Socket

 This extends/modifies the MariaDB socket defination to be per user.

 Create sockets based on the user of the istance (`%I`). Permissions are only necessary in the sense that the user can connect to them. It won't matter to the server. Access control is enforced within the server, however if the user web services are run as the user, `Mode=777` can be reduced. `@mariadb-%I` is a abstract unix socket not on the filesystem. It may help if a user is in a chroot. Not all applications can connect to abstract sockets.

 
```
# cat /etc/systemd/system/mariadb@.socket.d/user.conf
[Socket]
SocketUser=%I
SocketMode=777
ListenSteam=
ListenStream=@mariadb-%I
ListenStream=/home/%I/mariadb.sock

```

The extra socket provides the user the ability to access the server when all max-connections are used:

 
```
# cat /etc/systemd/system/mariadb-extra@.socket.d/user.conf
[Socket]
SocketUser=%I
SocketMode=777
ListenSteam=
ListenStream=@mariadb-extra-%I
ListenStream=/home/%I/mariadb-extra.sock

```

Systemd Journal
---------------

 `systemd` has its own logging system called the `systemd` journal. The `systemd` journal contains information about the service startup process. It is a good place to look when a failure has occurred.

 The MariaDB `systemd` service's journal can be queried by using the `[journalctl](https://www.freedesktop.org/software/systemd/man/journalctl.html)` command. For example:

 
```
$ sudo journalctl n 20 -u mariadb.service
-- Logs begin at Fri 2019-01-25 13:49:04 EST, end at Fri 2019-01-25 18:07:02 EST. --
Jan 25 13:49:15 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Starting MariaDB 10.1.37 database server...
Jan 25 13:49:16 ip-172-30-0-249.us-west-2.compute.internal mysqld[2364]: 2019-01-25 13:49:16 140547528317120 [Note] /usr/sbin/mysqld (mysqld 10.1.37-MariaDB) starting as process 2364 ...
Jan 25 13:49:17 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Started MariaDB 10.1.37 database server.
Jan 25 18:06:42 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Stopping MariaDB 10.1.37 database server...
Jan 25 18:06:44 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Stopped MariaDB 10.1.37 database server.
Jan 25 18:06:57 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Starting MariaDB 10.1.37 database server...
Jan 25 18:08:32 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: mariadb.service start-pre operation timed out. Terminating.
Jan 25 18:08:32 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Failed to start MariaDB 10.1.37 database server.
Jan 25 18:08:32 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: Unit mariadb.service entered failed state.
Jan 25 18:08:32 ip-172-30-0-249.us-west-2.compute.internal systemd[1]: mariadb.service failed.

```

Converting mysqld\_safe Options to Systemd Options
--------------------------------------------------

 `mariadb-service-convert` is a script included in many MariaDB packages that is used by the package manager to convert `[mysqld\_safe](../mysqld_safe/index#mysqld_safe-options)` options to `systemd` options. It reads any explicit settings in the `[mysqld_safe]` [option group](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index), and its output is directed to `/etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf`. This helps to keep the configuration the same when upgrading from a version of MariaDB that does not use `systemd` to one that does.

 Implicitly high defaults of `[open-files-limit](../mysqld_safe/index#mysqld_safe-options)` may be missed by the conversion script and require explicit configuration. See [Configuring the Open Files Limit](#configuring-the-open-files-limit).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/systemd/>

System Tables
==============

  

| Title | Description |
| --- | --- |
|  [Information Schema](../information-schema/index) |  Articles about the Information Schema  |
|  [Performance Schema](../performance-schema/index) |  Monitoring server performance.  |
|  [The mysql Database Tables](../the-mysql-database-tables/index) |  mysql database tables.  |
|  [Sys Schema](../sys-schema/index) |  Collection of views, functions and procedures to help administrators get in...  |
|  [mariadb\_schema](../mariadb_schema/index) |  mariadb\_schema is used to enforce MariaDB native types independent of SQL\_MODE.  |
|  [Writing Logs Into Tables](../writing-logs-into-tables/index) |  The general query log and the slow query log can be written into system tables  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-tables/>

Sample Platform X3 implementation for Transactional and Analytical Workloads
============================================================================

    **MariaDB Platform X3** responds to business design challenges by integrating:

 * MariaDB Server, the leading enterprise open source database;
* MariaDB ColumnStore, a columnar database for on-demand analytical processing; and
* MariaDB MaxScale, the world's most advanced database proxy.

 MariaDB Server powers website and application workloads as a modern RDBMS. MariaDB Platform X3 extends MariaDB Server's capabilities to include:

 * Transactional workloads (OLTP);
* Analytical workloads (OLAP); and
* the combination of the two as Hybrid Transactional and Analytical Processing (HTAP) queries.

 This guide has been written for the DBA, developer and operator to help you stand up Platform X3 for HTAP queries, unleashing the ability to perform analysis across events as they are happening. It is also a deployment that can scale from the small cluster of the examples below to accommodate more transactions, larger analytical processing and high availability.

 Platform X3 Query Routing and Data Streaming
--------------------------------------------

 When MariaDB Platform X3 is deployed for HTAP, web and mobile services send queries to MariaDB MaxScale. In turn, MaxScale distributes these queries according to their purpose, transactional queries are sent to MariaDB Servers for OLTP workloads, and analytical queries are sent to MariaDB ColumnStore for OLAP operations. 

 On the back-end, changes made to the MariaDB Servers are sent through MaxScale streaming data adapters to ColumnStore, ensuring that ColumnStore remains up-to-date.

 ![platform-x3-routing-streaming-small]

 Platform X3 Scaleout
--------------------

 MariaDB Platform X3 can operate from individual servers, but as your application grows more complicated and your database workload increases, each component can scale out to suit your particular infrastructure needs.

 ![platform-x3-scaleout]

 For OLTP operations, our sample Platform X3 deployment we start with four MariaDB Servers, configured to run as one master and three slaves synchronized with each other in a MariaDB Replication cluster. In scaling OLTP, you can increases the number of MariaDB Servers, allowing for high availability, replication backups and failover.

 For OLAP operations, our sample deployment uses five MariaDB ColumnStore nodes, two of which are configured as User Modules (UM's) and three as Performance Modules (PM's). In scaling OLAP, you can increase the number of UM's to handle more incoming queries or increase the number of PM's to better handle the processing of those queries.

 To manage network communication between the application and our deployment and between the database servers we use two MaxScale servers, one to handle the back-end data streaming and the other to handle selective query proxying from your application. In scaling for the network load, you can add MaxScale servers to the first to handle a larger database write load or to the second to manage a greater number of queries from your application.

 Sample Use Cases
----------------

 ### Retail Store Example

 A retail store wants to amplify sales by providing a personalized shopping experience. When a customer checks out at a cash register or online, the customer is presented promotions tailored to the customer's interests. These offers may also be integrated across channels, available when the known customer visits the website, shops by mobile phone app, or be included in the next personalized email sent to the customer.

 At a technical level, when an OLTP query is performed to process the customer's purchase, the customer's past and current purchase history is analyzed with an OLAP query to provide promotions tailored to the customer's buying history.

 ### Retail Bank Example

 A retail bank maintains a customer database that includes their account information and a transaction activities ledger. When a customer makes a deposit or a withdrawal, the application updates the transaction activities ledger of their account. The customer can access their account information and activity through the bank's online portal.

 Additionally, the application generates reports analyzing transaction activities. These reports are adapted for categories of customers (business, student, regular checking, savings) or for types of transactions (cash deposits, checks, ATM deposits, in-branch deposits, transfers, withdrawals). These reports can be run by the customers on their individual accounts or by the bank's back office on all customer activities.

 In this scenario, queries listing account information and general transaction activities are OLTP operations. Reports analyzing transaction activities run by the customer for individual accounts or by the bank on all customers are OLAP operations.

 ### Internet of Things Example

 A chain of convenience stores maintains an IoT (Internet of Things) network in which each store records data on its milk inventory levels and sensor data such as refrigerator temperature. The central office continuously monitors inventory levels to trigger replenishment on an as-needed basis. The maintenance teams and store also receive real-time alerts if issues arise with the cooling system, speeding repair and reducing product losses. A holistic, whole-picture view of supply levels and status allows the chain to keep costs low and the customer experience consistent.

 At a technical level, purchasing of a milk carton or container triggers an OLTP query, and inventory reporting is an OLAP query. OLTP data is used for logging, and analysis of OLAP data drives understanding of product losses, replenishment patterns, and equipment failures.

 Sample Deployment
-----------------

 The following sections detail how to implement a sample deployment of Platform X3 for HTAP. The first steps cover server installation and deployment; the next cover configuration for [Replication](#configure-for-replication), [Data Streaming](#configure-for-data-streaming), and [Application Traffic](#configure-for-application-traffic), and lastly [Testing](#test-htap-application-traffic) with OLTP and OLAP queries and with DML statements.

 ### Deploy MariaDB Servers

 Our sample deployment calls for four servers running MariaDB Server to handle OLTP workloads, which we've named `Server-1` to `Server-4`. These are shown at the left of our sample deployment diagram, in orange. We use InnoDB as the storage engine on these servers.

 These four servers run MariaDB Server 10.3, installed per the instructions at: [Getting and Upgrading MariaDB](../getting-installing-and-upgrading-mariadb/index).

 ### Deploy MariaDB ColumnStore Servers

 Our sample deployment calls for five servers to run MariaDB ColumnStore to handle OLAP workloads. Two of these servers operate as User Module servers, named `UM-1` and `UM-2`, and receive application traffic from MaxScale. The other three operate as Performance Module servers, named `PM-1` through `PM-3`, and perform distributed query processing.

 These servers run MariaDB ColumnStore 1.2.2 and are installed using the non-root and non-distributed installation method, as per the instructions at: [Preparing and Installing MariaDB ColumnStore](../preparing-and-installing-mariadb-columnstore-12x/index).

 ### Deploy MariaDB MaxScale Servers

 Our sample deployment calls for two servers to run MariaDB MaxScale. The first server, named `MaxScale-1`, handles data streaming from the MariaDB Servers to the MariaDB ColumnStore servers. The second, named `MaxScale-2`, selectively proxies application traffic to the respective servers for OLTP and OLAP workloads.

 These servers run MariaDb MaxScale 2.3.1, installed per the instructions at: [Installing MariaDB MaxScale](mariadb-enterprise/mariadb-maxscale-23-mariadb-maxscale-installation-guide).

 ### Configure for Replication

 Once we have the server software installed on the respective hosts, we can begin configuring them for use. To start, our sample deployment calls for the four MariaDB Servers to synchronize data using MariaDB Replication. This allows for high availability on OLTP operations, replication backup and failover.

 In MariaDB Replication, one server operates as the master receiving all writes from the application and replicating changes to the cluster. The other servers operate as slaves, receiving reads from the application and only accepting writes from the master server.

 For our sample deployment, `Server-1` operates as the replication master while `Server-2` through `Server-4` operates as the replication slaves.

 #### Configure `Server-1` (master)

 Add the following lines to the `[mysqld]` section of `/etc/my.cnf.d/server.cnf`:

 
```
[mysqld]
server_id        = 1
log_bin          = mariadb-bin
binlog_format    = ROW
gtid_strict_mode = 1
log_error
log-slave-updates

```

In streaming data from MariaDB Server to ColumnStore for analysis, MaxScale requires that the Servers format the binary log events by each row modified by a statement, rather than by operation. So, when deploying a cluster for HTAP, ensure that the `[binlog\_format](../server-system-variables/index#binlog_format)` system variable on the MariaDB Servers is always set to the `ROW` value.

 For more information on these server system variables and others, see [Server System Variables](../server-system-variables/index).

 #### Configure `Server-2` (slave)

 Add the following lines to the `[mysqld]` section of `/etc/my.cnf.d/server.cnf`:

 
```
[mysqld]
server_id        = 2
log-bin          = mariadb-bin
binlog-format    = ROW
gtid_strict_mode = 1
log_error
log-slave-updates

```

#### Configure `Server-3` (slave)

 Add the following lines to the `[mysqld]` section of `/etc/my.cnf.d/server.cnf`:

 
```
[mysqld]
server_id        = 3
log-bin          = mariadb-bin
binlog-format    = ROW
gtid_strict_mode = 1
log_error
log-slave-updates

```

#### Configure `Server-4` (slave)

 Add the following lines to the `[mysqld]` section of `/etc/my.cnf.d/server.cnf`:

 
```
[mysqld]
server_id        = 4
log-bin          = mariadb-bin
binlog-format    = ROW
gtid_strict_mode = 1
log_error
log-slave-updates

```

#### Restart `Server-1` to `Server-4`

 Restart all four MariaDB Servers. Log into each server (`Server-1`, `Server-2`, `Server-3` and `Server-4`), and issue the restart command to `systemctl` on each server:

 
```
# systemctl restart mariadb.service

```

#### Create a replication user on `Server-1`

 When MariaDB Servers run as replication slaves, they replicate data through client connections with the master server. In order for these servers to establish client connections, create a replication user on the master server, `Server-1`, and grant the user the relevant privileges to retrieve the data.

 Connect to the master MariaDB Server through the client:

 
```
$ mysql -u root -p -h <Server-1-ip> -P 3306

```

Once connected, reset the master:

 
```
RESET MASTER;

```

Then, create a replication user for MaxScale and the slave MariaDB Servers and grant the relevant privileges to the user:

 
```
CREATE USER 'repl'@'%' IDENTIFIED BY 'pass';
GRANT REPLICATION SLAVE ON *.* TO 'repl';
GRANT SELECT ON mysql.user TO 'repl';
GRANT SELECT ON mysql.db TO 'repl';
GRANT SELECT ON mysql.tables_priv TO 'repl';
GRANT SELECT ON mysql.roles_mapping TO 'repl';
GRANT SHOW DATABASES ON *.* TO 'repl';
GRANT REPLICATION CLIENT ON *.* TO 'repl';

```

For more information on MariaDB Replication, see [Performance Tuning with MariaDB Replication](../high-availability-performance-tuning-mariadb-replication/index).

 #### Configure and start replication on `Server-2` to `Server-4`

 With each slave MariaDB Server in your deployment, configure it to replicate data from the master server and start the replication process. Perform the following operations on each slave server, (that is, `Server-2` through `Server-4`).

 First, connect to the slave server:

 
```
$ mysql -u root -h <slave-server-ip> -P 3306 -p

```

If replication is currently running, reset the master so you can update its configuration:

 
```
RESET MASTER;

```

Issue a `[CHANGE MASTER TO](../change-master-to/index)` statement to configure the slave to replicate from `Server-1`:

 
```
CHANGE MASTER TO
       MASTER_HOST='Server-1-ip',
       MASTER_USER='repl',
       MASTER_PASSWORD='pass';

```

Then, start the replication slave:

 
```
START SLAVE;

```

You can verify that replication is working using a `[SHOW SLAVE STATUS](../show-slave-status/index)` statement.

 
```
SHOW SLAVE STATUS;

```

### Configure for data streaming

 In HTAP deployments the only queries issued to MariaDB ColumnStore are those specific to OLAP workloads, which does not include writes. In order to update ColumnStore with new data written to the MariaDB Servers, configure MaxScale on the back-end to stream writes to ColumnStore.

 #### Configure MaxScale

 Our sample deployment calls for a MaxScale server to handle data streaming between the MariaDB Servers and the MariaDB ColumnStore cluster. On the `MaxScale-1` server, edit the `/etc/maxscale.cnf` configuration file, adding the following lines to set it up for data streaming to ColumnStore using the Avro Listener.

 First, configure the replication router. Set it to use the particular `server_id` and the binary log:

 
```
[replication-router]
type                    = service
router                  = binlogrouter
user                    = repl
password                = pass
server_id               = 5
master_id               = 1
Binlogdir               = /var/lib/maxscale
Mariadb10-compatibility = 1
filestem                = mariadb-bin

```

Then, configure the replication listener:

 
```
[replication-listener]
type     = listener
service  = replication-router
protocol = MySQLClient
port     = 6603

```

MaxScale now listens for configuration connections on port 6603. This allows a MariaDB client to set up replication using commands similar to those that manage a replication slave server. It only uses the user and password to authentication the configuration connection, (the credentials for connecting to the Server are specified in the [configuration](#configure-maxscale-as-a-slave) below). 

 Next, configure the router for the Avro service.

 
```
[avro-router]
type    = service
router  = avrorouter
source  = replication-router
avrodir = /var/lib/maxscale

```

This generates JSON files from the binary logs it receives from the master MariaDB Server and stores them in the `avodir` directory (that is, `/var/lib/maxscale/`) using the replication router.

 Then, configure the listener for the Avro service to use a specific port:

 
```
[avro-listener]
type     = listener
service  = avro-router
protocol = cdc
port     = 4001

```

Once this is done, save the file and restart MaxScale to apply the new configuration:

 
```
# sudo systemctl restart maxscale

```

Lastly, using the `maxctrl` utility, create a user for the Avro Router to capture data changes. This user handles streaming data MaxScale retrieves from the MariaDB Servers to ColumnStore.

 
```
# maxctrl call command cdc add_user avro-router cdcuser cdc

```

For more information on the Avro Router, see: [Avro Router](../mariadb-maxscale-21-avrorouter/index).

 #### Configure MaxScale as a slave

 When the MaxScale server streams data to MariaDB ColumnStore it retrieves it from the master server using the same process that the slaves use in MariaDB Replication. In effect it operates as a replication slave, only instead of writing data locally, it streams the writes to the ColumnStore User Modules.

 Connect to MaxScale using the MariaDB Client. Unlike when connecting to MariaDB Servers previously, use port 6603, (which you configured above in the `/etc/maxscale.cnf` file as the replication listener port).

 
```
$ mysql -h <MaxScale-1-ip> -P 6603 -u repl -p

```

Issue a `[CHANGE MASTER TO](../change-master-to/index)` statement to use the master MariaDB Server host (that is, the IP address to Server-1) and the port for client connections, (which defaults to 3306). Set the user and password as defined for the replication router in `/etc/maxscale.cnf` above.

 
```
CHANGE MASTER TO MASTER_HOST='<Server-1-ip>',
       MASTER_PORT=3306, 
       MASTER_USER='repl', 
       MASTER_PASSWORD='pass', 
       MASTER_LOG_FILE='mariadb-bin.000001';

```

Then, start the slave:

 
```
START SLAVE;

```

Once you've started the replication slave process on MaxScale, you can check it using the `[SHOW SLAVE STATUS](../show-slave-status/index)` statement, just as you would when checking the status of a slave MariaDB Server. 

 
```
SHOW SLAVE STATUS;

```

If there are no errors, `MaxScale-1` is now running as a replication slave to `Server-1`.

 #### Configure the CDC user

 On the master MariaDB Server, (that is, `Server-1`), create a user for the CDC service. The CDC Data Adapter authenticates with this user when retrieving data from the MariaDB Servers. 

 Connect using the MariaDB Client to `Server-1`:

 
```
$ mysql -u root -p -h <Server-1-ip>

```

Then, issue the following statements to create the CDC user and grant it the necessary privileges:

 
```
CREATE USER 'cdcuser'@'%' IDENTIFIED BY 'cdc';
GRANT REPLICATION SLAVE ON *.* TO 'cdcuser';
GRANT SELECT ON mysql.user TO 'cdcuser';
GRANT SELECT ON mysql.db TO 'cdcuser';
GRANT SELECT ON mysql.tables_priv TO 'cdcuser';
GRANT SELECT ON mysql.roles_mapping TO 'cdcuser';
GRANT SHOW DATABASES ON *.* TO 'cdcuser';
GRANT REPLICATION CLIENT ON *.* TO 'cdcuser';

```

#### Install the CDC Streaming Data Adapter

 The MaxScale CDC Streaming Data Adapter allows you to stream binary log events from MariaDB Servers to MariaDB ColumnStore clusters. In order to use it, install the ColumnStore Bulk Write SDK and the MaxScale CDC Adapter packages on a dedicated host or on any MaxScale server that you want to use for data streaming, (`MaxScale-1` in our sample deployment).

 Downloads are available at: [Downloads](https://mariadb.com/downloads/#mariadbax-axdataadapters).

 Note these packages conflict with ColumnStore installations. Don't install them on any of your ColumnStore servers.

 To install the ColumnStore Bulk Write SDK, download the RPM package from MariaDB, then install the EPEL releases and package dependencies using YUM:

 
```
$ wget https://downloads.mariadb.com/Data-Adapters/mariadb-columnstore-api/1.2.2/centos/x86_64/7/Mariadb-columnstore-api-1.2.2-1-x86_64-centos7-cpp.rpm
$ sudo yum install epel-release
$ sudo yum install -y libuv libxml2 snappy python34
$ sudo yum install -y  mariadb-columnstore-api-1.2.2-1-x86_64-centos7-cpp.rpm

```

To install the CDC Data Adapter, download the RPM package from MariaDB, then install it using YUM:

 
```
$ wget https://downloads.mariadb.com/Data-Adapters/mariadb-streaming-data-adapters/cdc-data-adapter/1.2.2/centos-7/mariadb-columnstore-maxscale-cdc-adapters-1.2.2-1-x86_64-centos7.rpm
$ sudo yum install -y mariadb-columnstore-maxscale-cdc-adapters-1.2.2-1-x86_64-centos7.rpm

```

For more information on installing the Data Adapter, see [Data Adapters Installation](../columnstore-streaming-data-adapters/index#installation).

 #### Configure the CDC Data Adapter

 With the CDC Data Adapter installed you can configure it to stream data to MariaDB ColumnStore. This is done by copying the `Columnstore.xml` configuration file from one of the ColumnStore nodes to the `MaxScale-1` server, where the CDC Data Adapter can use it.

 
```
$ scp root@columnstore-host:/home/mysql/columnstore/etc/Columnstore.xml \
      ~/Columnstore.xml
$ sudo mv Columnstore.xml /etc

```

Note, installing MaxScale and the CDC Data Adapter as root creates the `/var/lib/mxs_adapter/` directory. If you intend to run `mxs_adapter` as a non-root user, ensure that the user can read and write from this directory. If not, change the ownership to that of your user. For instance,

 
```
$ sudo chown ec2-user /var/lib/mxs_adapter

```

Lastly, check the firewall and SELinux. ColumnStore uses ports 8600 to 8630, as well as ports 8700 and 8800. The CDC Data Adapter uses the same ports to stream data from `MaxScale-1` to ColumnStore. Check each server to ensure that there is no firewall blocking these ports. Additionally, ensure that SELinux has a policy allowing these connections or that it is running in permissive mode.

 #### Verify data streaming

 Once you've installed and configured the MaxScale and the CDC Data Adapter, you can run checks to verify that it is properly configured and able to communicate and stream data from the MariaDB Servers to the MariaDB ColumnStore cluster. Using the `mxs_adapter` utility, you can connect to MaxScale and test data streaming.

 In order to test this feature, you first need to create tables to store the data the CDC Data Adapter transfers. First, connect to the master MariaDB Server, `Server-1`, and create an InnoDB table to use in storing test data:

 
```
CREATE TABLE test.t6(a INT, b INT) ENGINE=InnoDB;

```

Then, connect to one of the User Modules and create a ColumnStore table with the same name and schema:

 
```
CREATE TABLE test.t6(a INT, b INT) ENGINE=ColumnStore;

```

In order to stream data from the MariaDB Servers to ColumnStore,call the `mxs_adapter` utility. From the `MaxScale-1` server, run the following command:

 
```
$ mxs_adapter -c /etc/ColumnStore.xml -u cdcuser -p cdc \
  	-h localhost -P 4001 -r 2 -d -n -z test t6

```

Use the username and password for the CDC user created in the previous section. In the MaxScale configuration, we set port 4001 for the listener service.

 The last two arguments tell it to stream the `t6` table on the `test` database. If you want to stream multiple tables, replace these arguments with a `-f` option that gives the path to a table list file. Format the file for one table per line, separating the database name and table name by a tab. For instance,

 
```
$ cat tbl.lst
test t6
test t7
test t8

```

When you start streaming data, the `mxs_adapter` utility begins printing logging messages to stdout. As you add data to the MariaDB Servers, you can check this output to see binary events streaming over to ColumnStore.

 To test this, begin inserting data onto the `test.t6` table on the `Server-1` server. This is the master server in the MariaDB Replication and the only one that accepts write operations.

 
```
INSERT INTO test.t6 VALUES (1,1);

INSERT INTO test.t6 VALUES (1,2);

INSERT INTO test.t6 VALUES (1,3);

INSERT INTO test.t6 VALUES (1,4);

INSERT INTO test.t6 VALUES (1,5);

```

Then, issue a `[SELECT](../select/index)` statement to see what data is available on the MariaDB Servers for the OLTP operations:

 
```
SELECT * FROM test.t6;
+----+----+
| a  | b  |
+----+----+
|  1 |  1 |
|  1 |  2 |
|  1 |  3 |
|  1 |  4 |
|  1 |  5 |
+----+----+
5 rows in set (0.010 sec)

```

By checking the logging messages coming from the `mxs_adapter` utility, you can watch these `[INSERT](../insert/index)` statements as they stream from the MariaDB Servers through MaxScale to ColumnStore:

 
```
2018-11-23 18:39:09 [main] Started thread 0x176b470
2018-11-23 18:39:09 [main] Started 1 threads
2018-11-23 18:39:09 [test.t6] Requesting data for table: test.t6
2018-11-23 18:39:09 [test.t6] INSERT INTO `test`.`t6` (`a`,`b`) VALUES (1,1)
2018-11-23 18:39:09 [test.t6] DML average: 12ms
2018-11-23 18:39:19 [test.t6] Read timeout
2018-11-23 18:39:22 [test.t6] INSERT INTO `test`.`t6` (`a`,`b`) VALUES (1,2)
2018-11-23 18:39:22 [test.t6] DML average: 4ms
2018-11-23 18:39:24 [test.t6] INSERT INTO `test`.`t6` (`a`,`b`) VALUES (1,3)
2018-11-23 18:39:24 [test.t6] DML average: 4ms
2018-11-23 18:39:26 [test.t6] INSERT INTO `test`.`t6` (`a`,`b`) VALUES (1,4)
2018-11-23 18:39:26 [test.t6] DML average: 4ms
2018-11-23 18:39:28 [test.t6] INSERT INTO `test`.`t6` (`a`,`b`) VALUES (1,5)
2018-11-23 18:39:28 [test.t6] DML average: 9ms

```

Then, you can issue a similar `[SELECT](../select/index)` statement to the `test.t6` table on either of the User Modules for MariaDB ColumnStore to see that the data is now available for OLAP operations:

 
```
SELECT * FROM test.t6;
+----+----+
|  a | b  |
+----+----+
|  1 |  1 |
|  1 |  2 |
|  1 |  3 |
|  1 |  4 |
|  1 |  5 |
+----+----+
5 rows in set (0.010 sec)

```

Next, test out other write operations using either an `[UPDATE](../update/index)` or `[DELETE](../delete/index)` statement on `Server-1`:

 
```
UPDATE test.t6 SET a = 2 WHERE b > 3;

SELECT * FROM test.t6;
+----+----+
| a  | b  |
+----+----+
|  1 |  1 |
|  1 |  2 |
|  1 |  3 |
|  2 |  4 |
|  2 |  5 |
+----+----+
5 rows in set (0.000 sec)

```

Using the logging messages from the CDC Data Adapter, you can watch the binary events for this operation stream through MaxScale:

 
```
2018-11-23 18:44:18 [test.t6] Read timeout
2018-11-23 18:44:22 [test.t6] UPDATE `test`.`t6` SET `a` = 2, `b` = 4 WHERE `a` = 1 AND `b` = 4
2018-11-23 18:44:22 [test.t6] DML average: 12ms
2018-11-23 18:44:22 [test.t6] UPDATE `test`.`t6` SET `a` = 2, `b` = 5 WHERE `a` = 1 AND `b` = 5
2018-11-23 18:44:22 [test.t6] DML average: 13ms
2018-11-23 18:44:27 [test.t6] Read timeout

```

As you can see from the logging messages, MaxScale detected the `[UPDATE](../update/index)` statement and streamed it through the CDC Data Adapter to ColumnStore. The CDC Data Adapter then begins logging `Read timeout` messages to indicate that it is done streaming and is waiting on additional binary events from the MariaDB Servers.

 You can confirm that the data was successfully transferred by issuing a `[SELECT](../select/index)` statement to one of the MariaDB ColumnStore User Modules:

 
```
SELECT * FROM test.t6;
+----+----+
| a  | b  |
+----+----+
|  1 |  1 |
|  1 |  2 |
|  1 |  3 |
|  2 |  4 |
|  2 |  5 |
+----+----+
5 rows in set (0.011 sec)

```

Notice that rows 4 and 5 now contain new values.

 ### Configure for Application Traffic

 When your application issues queries to Platform X3 for HTAP operations, it doesn't connect to either the MariaDB Servers or to the MariaDB ColumnStore User Modules directly. Instead, it connects to a MaxScale server configured to selectively routes queries, ensuring that OLTP operations execute on MariaDB Servers and OLAP operations execute on ColumnStore.

 In order to better illustrate how MaxScale distributes queries between the servers, we are going to install a sample banking database and show how to process payments and analyze loan data.

 Our sample database contains the following tables:

 * `account` - each record describes the static characteristics of an account
* `client` - each record describes the characteristics of a client
* `client_accts` - each record relates together a client with an account
* `loan` - each record describes a loan granted for a given account

 ![platform-x3-bank-db]

 With the configuration so far, our sample deployment will streams these new tables from the MariaDB Serves to ColumnStore through the CDC Data Adapter running on `MaxScale-1`. We'll then configure the second MaxScale server to selectively route your application traffic for HTAP operations.

 #### Prepare MariaDB Server and MariaDB ColumnStore to receive traffic from MaxScale

 Create a read user for MaxScale on the master MariaDB Server `Server-1` and the ColumnStore User Modules. Grant it the necessary privileges to operate.

 
```
CREATE USER 'maxscale' IDENTIFIED BY 'pass';
GRANT SELECT ON mysql.user TO 'maxscale';
GRANT SELECT ON mysql.db TO 'maxscale';
GRANT SELECT ON mysql.tables_priv TO 'maxscale';
GRANT SHOW DATABASES ON *.* TO 'maxscale';

```

Then, create a write user for MaxScale on the same servers.

 
```
CREATE USER 'maxuser'@'%' IDENTIFIED BY 'maxpwd';
GRANT ALL ON *.* TO 'maxuser'@'%';

```

#### Create the schema

 Download and unzip the sample dataset onto both Server-1 and a ColumnStore User Module from [test-db](https://drive.google.com/a/mariadb.com/file/d/1At6q7qSKJkCe-NcwDCQrkjpDisXVOIDn/view?usp=sharing). This file is `test-db.zip`, which unzips into the `test-db/` directory . It contains following SQL and CSV files:

 
```
$ unzip test-db.zip
$ ls test-db/
create-db-cs.sql
create-db-innodb.sql 
account.csv  
client_accts.csv  
client.csv  
loan.csv

```

On the master MariaDB Server, `Server-1`, change into the unzipped directory and launch the client as the write user `maxuser` you created above for MaxScale:

 
```
$ cd test-db
$ mysql -u 'maxuser' -p

```

Use the `[SOURCE](../source/index)` command to load the `create-db-innodb.sql` file, initializing the base database:

 
```
SOURCE create-db-innodb.sql;

```

Then, modify the schema to add a balance column to the `bank.loan` table. This column will be used in the ColumnStore examples below.

 
```
SET sql_log_bin = 0;
ALTER TABLE bank.loan ADD COLUMN balance decimal(10,2);
SET sql_log_bin = 1;

```

On a ColumnStore User Module, connect from the same directory and with the same user:

 
```
$ cd test-db
$ mysql -u 'maxuser' -p 

```

Then, use the `[SOURCE](../source/index)` command to load the `create-db-cs.sql` file:

 
```
SOURCE create-db-cs.sql;

```

At this point, we have created the bank database and tables, and have loaded the data into the MariaDB Servers, (though we only wrote to `Server-1`, as the master server it has replicated the data out to the slaves). We have also created the bank database and tables in MariaDB ColumnStore. The tables on MariaDB ColumnStore are empty at this point.

 #### Streaming Data from MariaDB Servers to MariaDB ColumnStore

 Next, we will start streaming data via the `mxs_adapter` utility, so that the data we've loaded on the MariaDB Servers can stream to MariaDB ColumnStore. On `MaxScale-1`, create a TSV (tab-separated) file named bank.lst with the bank database tables we want to stream:

 
```
$ cat bank.lst
bank	account
bank	client
bank	client_accts
bank	loan

```

Now, start the `mxs_adapter` utility designating this file with the `-f` option for this file:

 
```
$ mxs_adapter -c /etc/Columnstore.xml -u cdcuser -p cdc \
      -h <maxscale-1-host> -P 4001 -r 50 -d -n -f bank.lst

```

When you run the `mxs_adapter` utility, it streams logging messages about the operations it's performing to stdout. You can monitor this information to see the binary events its streaming from the MariaDB Servers to MariaDB ColumnStore.

 
```
2018-11-28 03:56:49 [bank.client_accts] client_id: 13971
2018-11-28 03:56:49 [bank.client_accts] account_id: 11362
2018-11-28 03:56:49 [bank.client_accts] ca_type: OWNER
2018-11-28 03:56:49 [bank.client_accts] ca_id: 13690
2018-11-28 03:56:49 [bank.client_accts] client_id: 13998
2018-11-28 03:56:49 [bank.client_accts] account_id: 11382
2018-11-28 03:56:49 [bank.client_accts] ca_type: OWNER
2018-11-28 03:56:49 [bank.client_accts] ca_id: 0
2018-11-28 03:56:49 [bank.client_accts] client_id:
2018-11-28 03:56:49 [bank.client_accts] account_id:
2018-11-28 03:56:49 [bank.client_accts] ca_type:
2018-11-28 03:56:52 [bank.account] Read timeout
2018-11-28 03:56:57 [bank.loan] Read timeout
2018-11-28 03:56:58 [bank.client] Flushing batch
2018-11-28 03:56:58 [bank.client] 21 rows, 0 transactions inserted over 10.1008 seconds. GTID = 0-1-23:5371
2018-11-28 03:56:59 [bank.client_accts] Flushing batch
2018-11-28 03:56:59 [bank.client_accts] 21 rows, 0 transactions inserted over 10.1153 seconds. GTID = 0-1-27:5371
2018-11-28 03:57:02 [bank.account] Read timeout

```

When all the loaded data has been streamed from the MariaDB Servers to ColumnStore, you'll begin to see `Read timeout` messages in the output. This means that the `mxs_adapter` utility is now waiting on additional binary events to occur on the MariaDB Servers.

 At this point, if you issue a `[SELECT COUNT(\*)](../count/index)` statements to MariaDB ColumnStore, you should get following result-sets:

 
```
SELECT COUNT(*) FROM bank.account;
+----------+
| COUNT(*) |
+----------+
|     4502 |
+----------+
1 row in set (0.057 sec)

SELECT COUNT(*) FROM bank.client;
+----------+
| COUNT(*) |
+----------+
|     5371 |
+----------+
1 row in set (0.051 sec)

SELECT COUNT(*) FROM bank.loan;
+----------+
| COUNT(*) |
+----------+
|      684 |
+----------+
1 row in set (0.056 sec)

SELECT COUNT(*) FROM bank.client_accts;
+----------+
| COUNT(*) |
+----------+
|     5371 |
+----------+
1 row in set (0.027 sec)

```

The MariaDB Servers and ColumnStore now contain the same data.

 #### Configure HTAP routing

 Our sample deployment proxies application traffic through a second MariaDB MaxScale server for the selective routing of HTAP queries. Specifically, it involves configuring the MaxScale-2 server so that:

 * All `[INSERT](../insert/index)`, `[UPDATE](../update/index)`, `[DELETE](../delete/index)` statements always route to `Server-1` for (OLTP)
* All `[SELECT](../select/index)` queries on the loan table always route to MariaDB ColumnStore (OLAP)
* All remaining read queries will route to any MariaDB Server.

 Below is a diagram of the `MaxScale-2` server configuration:

 ![platform-x3-htap-routing]

 Here is the configuration file you should have in `/etc/maxscale.cnf` on `MaxScale-2` to achieve the above.

 
```
[maxscale]
threads  = auto
sql_mode = default

## Identify the Master MariaDB Server: Server-1
[sw-db1]
type     = server
address  = <MariaDB-Server-1-IP>
port     = 3306
protocol = MariaDBBackend

## Identify the Slave MariaDB Server: Server-2
[sw-db2]
type     = server
address  = <MariaDB-Server-2-IP>
port     = 3306
protocol = MariaDBBackend

## Identify the Slave MariaDB Server: Server-3
[sw-db3]
type     = server
address  = <MariaDB-Server-3-IP>
port     = 3306
protocol = MariaDBBackend

## Identify the Columnstore Server: UM-1
[sw-mcs-um1]
type     = server
address  = <MariaDB-UM-1-IP>
port     = 3306
protocol = MariaDBBackend

## Monitor all servers
[MariaDB-Monitor]
type             = monitor
module           = mariadbmon
servers          = sw-db1,sw-db2,sw-db3,sw-mcs-um1
user             = maxuser
password         = maxpwd
monitor_interval = 10000

## Service to talk to the servers.
[MDB-Service]
type      = service
router    = readwritesplit
servers   = sw-db1,sw-db2
user      = maxuser
password  = maxpwd

## Listener that clients use to access the MariaDB Servers.
[MDB-Listener]
type     = listener
service  = MDB-Service
protocol = MariaDBClient
port     = 4009

## The MDB-Service abstracted as a server
[MDB-Service-as-server]
type     = server
address  = 127.0.0.1
port     = 4009
protocol = MariaDBBackend

## Service to talk to the ColumnStore UM
[CS-Service]
type           = service
router         = readconnroute
router_options = running
servers        = sw-mcs-um1
user           = maxuser
password       = maxpwd

## Listener that clients use to access the CS-Service.
[CS-Listener]
type     = listener
service  = CS-Service
protocol = MariaDBClient
port     = 4010

## CS-Service abstracted as a server
[CS-Service-as-server]
type     = server
address  = 127.0.0.1
port     = 4010
protocol = MariaDBBackend

## Filter the _datamart_ queries to the ColumnStore server and rest of the queries to the MariaDB Servers
[target-selector]
type     = filter
module   = namedserverfilter
match01  = (?i)SELECT.*loan
target01 = CS-Service-as-server
match02  = .*
target02 = MDB-Service-as-server

## Filter to replace loan table name without database qualifier, with bank.loan, so that the connection to ColumnStore knows which database to use
[loan-table-filter]
type      = filter
module    = regexfilter
options   = ignorecase
match     = \sloan\s
replace   = /* */  bank.loan /* */
log_trace = true
log_file  = /tmp/regexfilter.log

## Combines the two services as one
[HTAP-Service]
type                   = service
Router                 = schemarouter
ignore_databases_regex = .*
servers                = MDB-Service-as-server,CS-Service-as-server
Preferred_server       = MDB-Service-as-server
user                   = maxuser
password               = maxpwd
filters                = target-selector

## Listener clients use to access the combined service
[HTAP-Listener]
type     = listener
service  = HTAP-Service
protocol = MariaDBClient
port     = 4011

```

Then, start MaxScale:

 
```
# systemctl start maxscale

```

### Test HTAP Application Traffic

 With the MariaDB Servers, ColumnStore and MaxScale servers configured and deployed, you can begin testing the sample HTAP deployment. The application connects to the second MaxScale server, `MaxScale-2`, on port 4011, where it performs selective query routing:

 * All `[INSERT](../insert/index)`, `[UPDATE](../update/index)`, `[DELETE](../delete/index)` queries always route to `Server-1` (OLTP)
* All `[SELECT](../select/index)` queries on loans table always route to MariaDB ColumnStore (OLAP)
* All remaining read queries route to any MariaDB Server (OLTP)

 #### Connect from application to MaxScale HTAP Service

 From your application server use the MariaDB Client to connect to the MaxScale HTAP Service.

 
```
$ mysql -h <maxscale2-host> -P 4011 -u maxuser -p

```

These are the same command-line options as you would use to connect to a MariaDB Server, but instead of an individual server, you connect to MaxScale, which sends the queries to the Servers or to one of the ColumnStore UM's.

 Use the password '`maxpwd`' value that you previously set for this user.

 #### Transactional queries

 The MariaDB MaxScale server configuration above designates queries on tables other than bank.loan as transactional and routes them to the MariaDB Servers rather than ColumnStore. You can identify which server cluster the query executes on using the `[version\_comment](../server-system-variables/index#version_comment)` system variable.

 
```
SELECT *, @@version_comment FROM bank.account LIMIT 5;
+------------+-------------+------------------+------------+-------------------+
| account_id | district_id | frequency        | a_d        | @@version_comment |
+------------+-------------+------------------+------------+-------------------+
|        576 |          55 | POPLATEK MESICNE | 1993-01-01 | MariaDB Server    |
|       3818 |          74 | POPLATEK MESICNE | 1993-01-01 | MariaDB Server    |
|        704 |          55 | POPLATEK MESICNE | 1993-01-01 | MariaDB Server    |
|       2378 |          16 | POPLATEK MESICNE | 1993-01-01 | MariaDB Server    |
|       2632 |          24 | POPLATEK MESICNE | 1993-01-02 | MariaDB Server    |
+------------+-------------+------------------+------------+-------------------+
5 rows in set (0.039 sec)

```

Since MaxScale routes this query as a transactional operation, the `[version\_comment](../server-system-variables/index#version_comment)` system variable returns MariaDB Server.

 #### Analytical queries

 The MariaDB MaxScale server configuration above designates queries on the bank.loans table as analytical queries and routes them to the MariaDB ColumnStore User Modules rather than the MariaDB Servers. You can identify which server cluster the query executes on using the `[version\_comment](../server-system-variables/index#version_comment)` system variable.

 
```
SELECT loan_id, account_id, amount, duration, payments,  @@version_comment 
FROM loan LIMIT 5;
+---------+------------+-----------+----------+----------+---------------------+
| loan_id | account_id | amount    | duration | payments | @@version_comment   |
+---------+------------+-----------+----------+----------+---------------------+
|       0 |          0 |      0.00 |        0 |     0.00 | Columnstore 1.2.1-1 |
|    5314 |       1787 |  96396.00 |       12 |  8033.00 | Columnstore 1.2.1-1 |
|    5316 |       1801 | 165960.00 |       36 |  4610.00 | Columnstore 1.2.1-1 |
|    6863 |       9188 | 127080.00 |       60 |  2118.00 | Columnstore 1.2.1-1 |
|    5325 |       1843 | 105804.00 |       36 |  2939.00 | Columnstore 1.2.1-1 |
+---------+------------+-----------+----------+----------+---------------------+

```

Since MaxScale routes the query as an analytical operation, the `[version\_comment](../server-system-variables/index#version_comment)` system variable indicates a ColumnStore server.

 #### DML Statements

 The MariaDB MaxScale server configuration above designates data manipulation statements such as `[INSERT](../insert/index)`, `[UPDATE](../update/index)` and `[DELETE](../delete/index)` as transactional and routes these statements to the MariaDB Servers. The other MaxScale server then streams the changes over to ColumnStore.

 Issue an `[UPDATE](../update/index)` statement to set the initial balance for a loan:

 
```
UPDATE bank.loan SET balance = amount WHERE loan_id = 5314;

```

Then, query the updated row to see the changes on ColumnStore:

 
```
SELECT loan_id, account_id, amount, payments, @@version_comment 
FROM bank.loan WHERE loan_id = 5314;
+---------+------------+----------+----------+-----------+---------------------+
| loan_id | account_id | amount   | payments |  balance  | @@version_comment   |
+---------+------------+----------+----------+-----------+---------------------+
|    5314 |       1787 | 96396.00 |  8033.00 |  96369.00 | Columnstore 1.2.1-1 |
+---------+------------+----------+----------+-----------+---------------------+
1 row in set (0.113 sec)

```

The loan balance has been set to its initial value of the received funds.

 As you can see, the account holder has made payments on the loan. This amount should be removed from the balance to reflect their paying it down. Issue another `[UPDATE](../update/index)` statement to modify the balance, removing payments made on the account:

 
```
UPDATE bank.loan SET balance = balance - payments WHERE loan_id = 5314;

```

Then, query the loan to view the updated rows on ColumnStore:

 
```
SELECT loan_id, account_id, amount, payments, @@version_comment 
FROM bank.loan WHERE  loan_id = 5314;
+---------+------------+----------+----------+----------+---------------------+
| loan_id | account_id | amount   | payments | balance  | @@version_comment   |
+---------+------------+----------+----------+----------+---------------------+
|    5314 |       1787 | 96396.00 |  8033.00 | 88336.00 | Columnstore 1.2.1-1 |
+---------+------------+----------+----------+----------+---------------------+
1 row in set (0.094 sec)

```

The loan balance has now been reduced to reflect account payments. MaxScale has also streamed the data from the changes over to ColumnStore.

 For More Information
--------------------

 ### Obtaining the Products

 When you're ready to install MariaDB Platform X3, go to [Downloads](https://mariadb.com/downloads) and select Platform X3. If you use an RPM or APT based distribution of Linux, you can configure your server repositories to install it through the package manager.

 ### Documentation

 Documentation for MariaDB products is available in the [Library](../library). For the documentation on specific products, see the links below:

 * **[MariaDB Server Documentation](../library/documentation/index)**
	+ **[Getting Started](../getting-installing-and-upgrading-mariadb/index)**
	+ **[SQL Statements](../sql-statements-structure/index)**
	+ **[SQL Functions](../built-in-functions/index)**
	+ **[MariaDB Replication](../high-availability-performance-tuning-mariadb-replication/index)**
	+ **[Server System Variables](../server-system-variables/index)**
* **[MariadB ColumnStore Documentation](../mariadb-columnstore/index)**
	+ **[Getting Started](../columnstore-getting-started/index)**
	+ **[ColumnStore Streaming Data Adapters](../columnstore-streaming-data-adapters/index)**
* **[MariaDB MaxScale Documentation](mariadb-enterprise/maxscale)**

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sample-platform-x3-implementation-for-transactional-and-analytical-workloads/>

Starting and Stopping MariaDB Server
====================================

    There are several different methods to start or stop the MariaDB Server process. There are two primary categories that most of these methods fall into: starting the process with the help of a service manager, and starting the process manually.

 Service Managers
----------------

 [sysVinit](../sysvinit/index) and [systemd](../systemd/index) are the most common Linux service managers. [launchd](../launchd/index) is used in MacOS X. [Upstart](https://en.wikipedia.org/wiki/Upstart_(software)) is a less common service manager.

 ### Systemd

 RHEL/CentOS 7 and above, Debian 8 Jessie and above, and Ubuntu 15.04 and above use [systemd](../systemd/index) by default.

 For information on how to start and stop MariaDB with this service manager, see [systemd: Interacting with the MariaDB Server Process](../systemd/index#interacting-with-the-mariadb-server-process).

 ### SysVinit

 RHEL/CentOS 6 and below, and Debian 7 Wheezy and below use [sysVinit](../sysvinit/index) by default.

 For information on how to start and stop MariaDB with this service manager, see [sysVinit: Interacting with the MariaDB Server Process](../sysvinit/index#interacting-with-the-mariadb-server-process).

 ### launchd

 [launchd](../launchd/index) is used in MacOS X.

 ### Upstart

 Ubuntu 14.10 and below use Upstart by default.

 Starting the Server Process Manually
------------------------------------

 ### mysqld

 [mysqld](../mysqld-options/index) is the actual MariaDB Server binary. It can be started manually on its own.

 ### mysqld\_safe

 [mysqld\_safe](../mysqld_safe/index) is a wrapper that can be used to start the [mysqld](../mysqld-options/index) server process. The script has some built-in safeguards, such as automatically restarting the server process if it dies. See [mysqld\_safe](../mysqld_safe/index) for more information.

 ### mysqld\_multi

 [mysqld\_multi](../mysqld_multi/index) is a wrapper that can be used to start the [mysqld](../mysqld-options/index) server process if you plan to run multiple server processes on the same host. See [mysqld\_multi](../mysqld_multi/index) for more information.

 ### mysql.server

 [mysql.server](../mysqlserver/index) is a wrapper that works as a standard [sysVinit](../sysvinit/index) script. However, it can be used independently of [sysVinit](../sysvinit/index) as a regular `sh` script. The script starts the [mysqld](../mysqld-options/index) server process by first changing its current working directory to the MariaDB install directory and then starting [mysqld\_safe](../mysqld_safe/index). The script requires the standard [sysVinit](../sysvinit/index) arguments, such as `start`, `stop`, and `status`. See [mysql.server](../mysqlserver/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/starting-and-stopping-mariadb-automatically/>

What to Do if MariaDB Doesn't Start
===================================

    There could be many reasons that MariaDB fails to start. This page will help troubleshoot some of the more common reasons and provide solutions.

 If you have tried everything here, and still need help, you can ask for help on IRC or on the forums - see [Where to find other MariaDB users and developers](../where-to-find-other-mariadb-users-and-developers/index) - or ask a question at the [Starting and Stopping MariaDB](../starting-and-stopping-mariadb/index) page.

 The Error Log and the Data Directory
------------------------------------

 The reason for the failure will almost certainly be written in the [error log](../error-log/index) and, if you are starting MariaDB manually, to the console. By default, the error log is named *host-name*.err and is written to the data directory.

 Common Locations:

 * /var/log/
* /var/log/mysql
* C:\Program Files\MariaDB x.y\data (x.y refers to the version number)
* C:\Program Files (x86)\MariaDB x.y\data (32bit version on 64bit Windows)

 It's also possible that the error log has been explicitly written to another location. This is often done by changing the `[datadir](../server-system-variables/index#datadir)` or `[log\_error](../server-system-variables/index#log_error)` system variables in an [option file](../configuring-mariadb-with-option-files/index). See [Option Files](#option-files) below for more information about that.

 A quick way to get the values of these system variables is to execute the following commands:

 
```
mysqld --help --verbose | grep 'log-error' | tail -1
mysqld --help --verbose | grep 'datadir' | tail -1

```

Option Files
------------

 Another kind of file to consider when troubleshooting is [option files](../configuring-mariadb-with-option-files/index). The default option file is called `my.cnf`. Option files contain configuration options, such as the location of the data directory mentioned above. If you're unsure where the option file is located, see [Configuring MariaDB with Option Files: Default Option File Locations](../configuring-mariadb-with-option-files/index#default-option-file-locations) for information on the default locations.

 You can check which configuration options MariaDB server will use from its option files by executing the following command:

 
```
mysqld --print-defaults

```

You can also check by executing the following command:

 
```
my_print_defaults --mysqld

```

See [Configuring MariaDB with Option Files: Checking Program Options](../configuring-mariadb-with-option-files/index#checking-program-options) for more information on checking configuration options.

 ### Invalid Option or Option Value

 Another potential reason for a startup failure is that an [option file](../configuring-mariadb-with-option-files/index) contains an invalid option or an invalid option value. In those cases, the [error log](../error-log/index) should contain an error similar to this:

 
```
140514 12:19:37 [ERROR] /usr/local/mysql/bin/mysqld: unknown variable 'option=value'

```

This is more likely to happen when you upgrade to a new version of MariaDB. In most cases the [option file](../configuring-mariadb-with-option-files/index) from the old version of MariaDB will work just fine with the new version. However, occasionally, options are removed in new versions of MariaDB, or the valid values for options are changed in new versions of MariaDB. Therefore, it's possible for an [option file](../configuring-mariadb-with-option-files/index) to stop working after an upgrade.

 Also remember that option names are case sensitive.

 Examine the specifics of the error. Possible fixes are usually one of the following:

 * If the option is completely invalid, then remove it from the [option file](../configuring-mariadb-with-option-files/index).
* If the option's name has changed, then fix the name.
* If the option's valid values have changed, then change the option's value to a valid one.
* If the problem is caused by a simple typo, then fix the typo.

 Can't Open Privilege Tables
---------------------------

 It is possible to see errors similar to the following:

 
```
System error 1067 has occurred.
Fatal error: Can't open privilege tables: Table 'mysql.host' doesn't exist

```

If errors like this occur, then critical [system tables](../system-tables/index) are either missing or are in the wrong location. The above error is quite common after an upgrade if the [option files](../configuring-mariadb-with-option-files/index) set the `[basedir](../server-system-variables/index#basedir)` or `[datadir](../server-system-variables/index#datadir)` to a non-standard location, but the new server is using the default location. Therefore, make sure that the `[basedir](../server-system-variables/index#basedir)` and `[datadir](../server-system-variables/index#datadir)` variables are correctly set.

 If you're unsure where the option file is located, see [Configuring MariaDB with Option Files: Default Option File Locations](../configuring-mariadb-with-option-files/index#default-option-file-locations) for information on the default locations.

 If the [system tables](../system-tables/index) really do not exist, then you may need to create them with [mariadb-install-db](../mariadb-install-db/index). See [Installing System Tables (mariadb-install-db)](../installing-system-tables-mariadb-install-db/index) for more information.

 Can't Create Test File
----------------------

 One of the first tests on startup is to check whether MariaDB can write to the data directory. When this fails, it will log an error like this:

 
```
May 13 10:24:28 mariadb3 mysqld[19221]: 2019-05-13 10:24:28 0 [Warning] Can't create test file /usr/local/data/mariadb/mariadb3.lower-test
May 13 10:24:28 mariadb3 mysqld[19221]: 2019-05-13 10:24:28 0 [ERROR] Aborting

```

This is usually a permission error on the directory in which this file is being written. Ensure that the entire `[datadir](../server-system-variables/index#datadir)` is owned by the user running `mysqld`, usually `mysql`. Ensure that directories have the "x" (execute) directory permissions for the owner. Ensure that all the parent directories of the `[datadir](../server-system-variables/index#datadir)` upwards have "x" (execute) permissions for all (`user`, `group`, and `other`).

 Once this is checked look at the [systemd](#systemd) and [selinux](#selinux) documentation below, or [AppArmor](#AppArmorl).

 Can't Lock Aria Control File
----------------------------

 On starting MariaDB, the `aria_log_control` file is locked. If a lock cannot be obtained, it will log and error like this:

 
```
2023-05-01 16:27:03 0 [ERROR] mariadbd: Can't lock aria control file '/var/lib/mysql/aria_log_control' for exclusive use, error: 11. Will retry for 30 seconds

```

This almost always cause for this is that there is already an existing MariaDB service running on this data directory. Recommend aborting this startup and looking closely for the other MariaDB instance.

 The less likely case is there isn't locking available which might occur on a NFS data directory with explictly disable locking.

 Unable to lock ./ibdata1 error 11
---------------------------------

 Like the above for the Aria Control File, this is a attempting to exclusively lock the `ibdata1` InnoDB system tablespace. Error 11 corresponds to the system error "OS error code 11: Resource temporarily unavailable" meaning the lock cannot be created.

 
```
2023-05-01 16:27:34 0 [ERROR] InnoDB: Unable to lock ./ibdata1 error: 11
2023-05-01 16:27:34 0 [Note] InnoDB: Check that you do not already have another mariadbd process using the same InnoDB data or log files.
2023-05-01 16:27:34 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2023-05-01 16:27:35 0 [Note] InnoDB: Starting shutdown...

```

Like the above, this is an indication that a second MariaDB instance is already running on the data directory.

 InnoDB
------

 [InnoDB](../xtradb-and-innodb/index) is probably the MariaDB component that most frequently causes a crash. In the error log, lines containing InnoDB messages generally start with "InnoDB:".

 ### Cannot Allocate Memory for the InnoDB Buffer Pool

 In a typical installation on a dedicated server, at least 70% of your memory should be assigned to [InnoDB buffer pool](../xtradbinnodb-buffer-pool/index); sometimes it can even reach 85%. But be very careful: don't assign to the buffer pool more memory than it can allocate. If it cannot allocate memory, InnoDB will use the disk's swap area, which is very bad for performance. If swapping is disabled or the swap area is not big enough, InnoDB will crash. In this case, MariaDB will probably try to restart several times, and each time it will log a message like this:

 
```
140124 17:29:01 InnoDB: Fatal error: cannot allocate memory for the buffer pool

```

In that case, you will need to add more memory to your server/VM or decrease the value of the [innodb\_buffer\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size) variables.

 Remember that the buffer pool will slightly exceed that limit. Also, remember that MariaDB also needs allocate memory for other storage engines and several per-connection buffers. The operating system also needs memory.

 ### InnoDB Table Corruption

 By default, InnoDB deliberately crashes the server when it detects table corruption. The reason for this behavior is preventing corruption propagation. However, in some situations, server availability is more important than data integrity. For this reason, we can avoid these crashes by changing the value of [innodb\_corrupt\_table\_action](../xtradbinnodb-server-system-variables/index#innodb_corrupt_table_action) to 'warn'.

 If InnoDB crashes the server after detecting data corruption, it writes a detailed message in the error log. The first lines are similar to the following:

 
```
InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 7.
InnoDB: You may have to recover from a backup.

```

Generally, it is still possible to recover most of the corrupted data. To do so, restart the server in [InnoDB recovery mode](../xtradbinnodb-recovery-modes/index) and try to extract the data that you want to backup. You can save them in a CSV file or in a non-InnoDB table. Then, restart the server in normal mode and restore the data.

 MyISAM
------

 Most tables in the [mysql](../the-mysql-database-tables/index) database are MyISAM tables. These tables are necessary for MariaDB to properly work, or even start.

 A MariaDB crash could cause system tables corruption. With the default settings, MariaDB will simply not start if the system tables are corrupted. With [myisam\_recover\_options](../myisam-system-variables/index#myisam_recover_options), we can force MyISAM to repair damaged tables.

 systemd
-------

 If you are using `[systemd](../systemd/index)`, then there are a few relevant notes about startup failures:

 * If MariaDB is configured to access files under `/home`, `/root`, or `/run/user`, then the default systemd unit file will prevent access to these directories with a `Permission Denied` error. This happens because the unit file set `[ProtectHome=true](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=)`. See [Systemd: Configuring Access to Home Directories](../systemd/index#configuring-access-to-home-directories) for information on how to work around this.

 * The default systemd unit file also sets [ProtectSystem=full](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectSystem=), which places restrictions on writing to a few other directories. Overwriting this with `ProtectSystem=off` in the same way as above will restore access to these directories.

 * If MariaDB takes longer than 90 seconds to start, then the default systemd unit file will cause it to fail with an error. This happens because the default value for the `[TimeoutStartSec](https://www.freedesktop.org/software/systemd/man/systemd.service.html#TimeoutStartSec=)` option is 90 seconds. See [Systemd: Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for information on how to work around this.

 * The systemd journal may also contain useful information about startup failures. See [Systemd: Systemd Journal](../systemd/index#systemd-journal) for more information.

 See [systemd](../systemd/index) documentation for further information on systemd configuration.

 SELinux
-------

 [Security-Enhanced Linux (SELinux)](https://selinuxproject.org/page/Main_Page) is a Linux kernel module that provides a framework for configuring [mandatory access control (MAC)](https://en.wikipedia.org/wiki/Mandatory_access_control) system for many resources on the system. It is enabled by default on some Linux distributions, including RHEL, CentOS, Fedora, and other similar Linux distribution. SELinux prevents programs from accessing files, directories or ports unless it is configured to access those resources.

 You might need to troubleshoot SELinux-related issues in cases, such as:

 * MariaDB is using a non-default port.
* MariaDB is reading from or writing to some files (datadir, log files, option files, etc.) located at non-default paths.
* MariaDB is using a plugin that requires access to resources that default installations do not use.

 Setting SELinux state to `permissive` is a common way to investigate what is going wrong while allowing MariaDB to function normally. `permissive` is supposed to produce a log entry every time it should block a resource access, without actually blocking it. However, [there are situations](https://danwalsh.livejournal.com/67855.html) when SELinux blocks resource accesses even in `permissive` mode.

 See [SELinux](../selinux/index) for more information.

 AppArmor
--------

 Add the following to `/etc/apparmor.d/tunables/alias` if you have moved the datadir:

 
```
alias /var/lib/mysql/ -> /data/mariadb/,

```

The restart AppArmor:

 
```
sudo systemctl restart apparmor

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/what-to-do-if-mariadb-doesnt-start/>

Running MariaDB from the Build Directory
========================================

    You can run mariadbd directly from the build directory (without doing `make install`).

 Starting mariadbd After Build on Windows
----------------------------------------

 On Windows, the data directory is produced during the build.

 The simplest way to start database from the command line is:

 1. Go to the directory where mariadbd.exe is located (subdirectory sql\Debug or sql\Relwithdebinfo of the build directory)
2. From here, execute, if you are using [MariaDB 10.5](../what-is-mariadb-105/index) or newer, 
```
mariadbd.exe --console

```
 else 
```
mariadbd.exe --console

```

 As usual, you can pass other server parameters on the command line, or store them in a my.ini configuraton file and pass `--defaults-file=path\to\my.ini`

 The default search path on Windows for the my.ini file is:

 * GetSystemWindowsDirectory()
* GetWindowsDirectory()
* C:\
* Directory where the executable is located

 Starting mariadbd After Build on Unix
-------------------------------------

 Copy the following to your '`~/.my.cnf`' file.

 There are two lines you have to edit: '`datadir=`' and '`language=`'. Be sure to change them to match your environment.

 
```
# Example MariadB config file.
# You can copy this to one of:
# /etc/my.cnf to set global options,
# /mysql-data-dir/my.cnf to get server specific options or
# ~/my.cnf for user specific options.
# 
# One can use all long options that the program supports.
# Run the program with --help to get a list of available options

# This will be passed to all MariaDB clients
[client]
#password=my_password
#port=3306
#socket=/tmp/mysql.sock

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

# The mariadb server  (both [mysqld] and [mariadb] works here)
[mariadb]
#port=3306
#socket=/tmp/mysql.sock

# The following three entries caused mysqld 10.0.1-MariaDB (and possibly other versions) to abort...
# skip-locking
# set-variable  = key_buffer=16M

loose-innodb_data_file_path = ibdata1:1000M
loose-mutex-deadlock-detector
gdb

######### Fix the two following paths

# Where you want to have your database
datadir=/path/to/data/dir

# Where you have your mysql/MariaDB source + sql/share/english
language=/path/to/src/dir/sql/share/english

########## One can also have a different path for different versions, to simplify development.

[mariadb-10.1]
lc-messages-dir=/my/maria-10.1/sql/share

[mariadb-10.2]
lc-messages-dir=/my/maria-10.2/sql/share

[mysqldump]
quick
set-variable = max_allowed_packet=16M

[mysql]
no-auto-rehash

[myisamchk]
set-variable= key_buffer=128M

```

With the above file in place, go to your MariaDB source directory and execute:

 
```
./scripts/mariadb-install-db --srcdir=$PWD --datadir=/path/to/data/dir --user=$LOGNAME

```

Above '$PWD' is the environment variable that points to your current directory. If you added `datadir` to your `my.cnf`, you don't have to give this option above. Also above, --user=$LOGNAME is necessary when using msqyld 10.0.1-MariaDB (and possibly other versions)

 Now you can start `mariadbd` (or `mysqld` if you are using a version older than [MariaDB 10.5](../what-is-mariadb-105/index)) in the debugger:

 
```
cd sql
ddd ./mariadbd &

```

Or start mariadbd on its own:

 
```
cd sql
./mariadbd &

```

After starting up `mariadbd` using one of the above methods (with the debugger or without), launch the client (as root if you don't have any users setup yet).

 
```
../client/mariadb

```

Using a Storage Engine Plugin
-----------------------------

 The simplest case is to compile the storage engine into MariaDB:

 
```
cmake -DWITH_PLUGIN_<plugin_name>=1` .

```

Another option is to point `mariadbd` to the storage engine directory:

 
```
./mariadbd --plugin-dir={build-dir-path}/storage/connect/.libs

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-mariadb-from-the-build-directory/>

mysql.user Table
================

    
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the [mysql.global\_priv table](../mysqlglobal_priv-table/index) has replaced the `mysql.user` table, and `mysql.user` should be considered obsolete. It is now a [view](../views/index) into `mysql.global_priv` created for compatibility with older applications and monitoring scripts. New tools are supposed to use `INFORMATION_SCHEMA` tables. From [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), the dedicated `mariadb.sys` user is created as the definer of the view. Previously, `root` was the definer, which resulted in privilege problems when this username was changed ([MDEV-19650](https://jira.mariadb.org/browse/MDEV-19650)).

 
The `mysql.user` table contains information about users that have permission to access the MariaDB server, and their global privileges. The table can be queried and although it is possible to directly update it, it is best to use [GRANT](../grant/index) and [CREATE USER](../create-user/index) for adding users and privileges. 

 Note that the MariaDB privileges occur at many levels. A user may not be granted `create` privilege at the user level, but may still have `create` permission on certain tables or databases, for example. See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 The `mysql.user` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User` makes up the unique identifier for this account. |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host` makes up the unique identifier for this account. |
| `Password` | `longtext` (>= [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)), `char(41)` (<= [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)) | NO |  |  | Hashed password, generated by the [PASSWORD()](../password/index) function. |
| `Select_priv` | `enum('N','Y')` | NO |  | N | Can perform [SELECT](../select/index) statements. |
| `Insert_priv` | `enum('N','Y')` | NO |  | N | Can perform [INSERT](../insert/index) statements. |
| `Update_priv` | `enum('N','Y')` | NO |  | N | Can perform [UPDATE](../update/index) statements. |
| `Delete_priv` | `enum('N','Y')` | NO |  | N | Can perform [DELETE](../delete/index) statements. |
| `Create_priv` | `enum('N','Y')` | NO |  | N | Can [CREATE DATABASE's](../create-database/index) or [CREATE TABLE's](../create-table/index). |
| `Drop_priv` | `enum('N','Y')` | NO |  | N | Can [DROP DATABASE's](../drop-database/index) or [DROP TABLE's](../drop-table/index). |
| `Reload_priv` | `enum('N','Y')` | NO |  | N | Can execute [FLUSH](../flush/index) statements or equivalent [mariadb-admin](../mariadb-admin/index) commands. |
| `Shutdown_priv` | `enum('N','Y')` | NO |  | N | Can shut down the server with [SHUTDOWN](../shutdown/index) or [mariadb-admin shutdown](../mariadb-admin/index). |
| `Process_priv` | `enum('N','Y')` | NO |  | N | Can show information about active processes, via [SHOW PROCESSLIST](../show-processlist/index) or [mariadb-admin processlist](../mariadb-admin/index). |
| `File_priv` | `enum('N','Y')` | NO |  | N | Read and write files on the server, using statements like [LOAD DATA INFILE](../load-data-infile/index) or functions like [LOAD\_FILE()](../load_file/index). Also needed to create [CONNECT](../connect/index) outward tables. MariaDB server must have permission to access those files. |
| `Grant_priv` | `enum('N','Y')` | NO |  | N | User can [grant](../grant/index) privileges they possess. |
| `References_priv` | `enum('N','Y')` | NO |  | N | Unused |
| `Index_priv` | `enum('N','Y')` | NO |  | N | Can create an index on a table using the [CREATE INDEX](../create-index/index) statement. Without the `INDEX` privilege, user can still create indexes when creating a table using the [CREATE TABLE](../create-table/index) statement if the user has have the `CREATE` privilege, and user can create indexes using the [ALTER TABLE](../alter-table/index) statement if they have the `ALTER` privilege. |
| `Alter_priv` | `enum('N','Y')` | NO |  | N | Can perform [ALTER TABLE](../alter-table/index) statements. |
| `Show_db_priv` | `enum('N','Y')` | NO |  | N | Can list all databases using the [SHOW DATABASES](../show-databases/index) statement. Without the `SHOW DATABASES` privilege, user can still issue the `SHOW DATABASES` statement, but it will only list databases containing tables on which they have privileges. |
| `Super_priv` | `enum('N','Y')` | NO |  | N | Can execute superuser statements: [CHANGE MASTER TO](../change-master-to/index), [KILL](../data-manipulation-kill-connection-query/index) (users who do not have this privilege can only `KILL` their own threads), [PURGE LOGS](../sql-commands-purge-logs/index), [SET global system variables](../set/index), or the [mariadb-admin debug](../mariadb-admin/index) command. Also, this permission allows the user to write data even if the [read\_only](../server-system-variables/index#read_only) startup option is set, enable or disable logging, enable or disable replication on slaves, specify a `DEFINER` for statements that support that clause, connect once after reaching the `MAX_CONNECTIONS`. If a statement has been specified for the [init-connect](../server-system-variables/index#init_connect) mysqld option, that command will not be executed when a user with `SUPER` privileges connects to the server. |
| `Create_tmp_table_priv` | `enum('N','Y')` | NO |  | N | Can create temporary tables with the [CREATE TEMPORARY TABLE](../create-table/index) statement. |
| `Lock_tables_priv` | `enum('N','Y')` | NO |  | N | Acquire explicit locks using the [LOCK TABLES](../transactions-lock/index) statement; user also needs to have the `SELECT` privilege on a table in order to lock it. |
| `Execute_priv` | `enum('N','Y')` | NO |  | N | Can execute [stored procedure](../stored-procedures/index) or functions. |
| `Repl_slave_priv` | `enum('N','Y')` | NO |  | N | Accounts used by slave servers on the master need this privilege. This is needed to get the updates made on the master. |
| `Repl_client_priv` | `enum('N','Y')` | NO |  | N | Can execute [SHOW MASTER STATUS](../show-master-status/index) and [SHOW SLAVE STATUS](../show-slave-status/index) statements. |
| `Create_view_priv` | `enum('N','Y')` | NO |  | N | Can create a view using the [CREATE\_VIEW](../create-view/index) statement. |
| `Show_view_priv` | `enum('N','Y')` | NO |  | N | Can show the [CREATE VIEW](../create-view/index) statement to create a view using the [SHOW CREATE VIEW](../show-create-view/index) statement. |
| `Create_routine_priv` | `enum('N','Y')` | NO |  | N | Can create stored programs using the [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) statements. |
| `Alter_routine_priv` | `enum('N','Y')` | NO |  | N | Can change the characteristics of a stored function using the [ALTER FUNCTION](../alter-function/index) statement. |
| `Create_user_priv` | `enum('N','Y')` | NO |  | N | Can create a user using the [CREATE USER](../create-user/index) statement, or implicitly create a user with the [GRANT](../grant/index) statement. |
| `Event_priv` | `enum('N','Y')` | NO |  | N | Create, drop and alter [events](../stored-programs-and-views-events/index). |
| `Trigger_priv` | `enum('N','Y')` | NO |  | N | Can execute [triggers](../triggers/index) associated with tables the user updates, execute the [CREATE TRIGGER](../create-trigger/index) and [DROP TRIGGER](../drop-trigger/index) statements. |
| `Create_tablespace_priv` | `enum('N','Y')` | NO |  | N |  |
| `Delete_history_priv` | `enum('N','Y')` | NO |  | N | Can delete rows created through [system versioning](../system-versioned-tables/index). |
| `ssl_type` | `enum('', 'ANY', 'X509', 'SPECIFIED')` | NO |  |  | TLS type - see [TLS options](../grant/index#per-account-tls-options). |
| `ssl_cipher` | `blob` | NO |  | NULL | TLS cipher - see [TLS options](../grant/index#per-account-tls-options). |
| `x509_issuer` | `blob` | NO |  | NULL | X509 cipher - see [TLS options](../grant/index#per-account-tls-options). |
| `x509_subject` | `blob` | NO |  | NULL | SSL subject - see [TLS options](../grant/index#per-account-tls-options). |
| `max_questions` | `int(11) unsigned` | NO |  | 0 | Number of queries the user can perform per hour. Zero is unlimited. See [per-account resource limits](../grant/index#setting-per-account-resources-limits). |
| `max_updates` | `int(11) unsigned` | NO |  | 0 | Number of updates the user can perform per hour. Zero is unlimited. See [per-account resource limits](../grant/index#setting-per-account-resources-limits). |
| `max_connections` | `int(11) unsigned` | NO |  | 0 | Number of connections the account can start per hour. Zero is unlimited. See [per-account resource limits](../grant/index#setting-per-account-resources-limits). |
| `max_user_connections` | `int(11)` | NO |  | 0 | Number of simultaneous connections the account can have. Zero is unlimited. See [per-account resource limits](../grant/index#setting-per-account-resources-limits). |
| `plugin` | `char(64)` | NO |  |  | Authentication plugin used on connection. If empty, uses the [default](#authentication-plugin). |
| `authentication_string` | `text` | NO |  | NULL | Authentication string for the authentication plugin. |
| `password_expired` | `enum('N','Y')` | NO |  | N | MySQL-compatibility option, not implemented in MariaDB. |
| `is_role` | `enum('N','Y')` | NO |  | N | Whether the user is a [role](../roles/index). |
| `default_role` | `char(80)` | NO |  | N | Role which will be enabled on user login automatically. |
| `max_statement_time` | `decimal(12,6)` | NO |  | 0.000000 | If non-zero, how long queries can run before being killed automatically. |
| Field | Type | Null | Key | Default | Description |

 
The [Acl\_roles](../server-status-variables/index#acl_roles) status variable indicates how many rows the `mysql.user` table contains where `is_role='Y'`.

 The [Acl\_users](../server-status-variables/index#acl_users) status variable, indicates how many rows the `mysql.user` table contains where `is_role='N'`.

 ### Authentication Plugin

 When the `plugin` column is empty, MariaDB defaults to authenticating accounts with either the `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` or the `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` plugins. It decides which based on the hash used in the value for the `Password` column. When there's no password set or when the 4.1 password hash is used, (which is 41 characters long), MariaDB uses the `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` plugin. The `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` plugin is used with pre-4.1 password hashes, (which are 16 characters long).

 MariaDB also supports the use of alternative [authentication plugins](../authentication-plugins/index). When the `plugin` column is not empty for the given account, MariaDB uses it to authenticate connection attempts. The specific plugin then uses the value of either the `Password` column or the `authentication_string` column to authenticate the user.

 A specific authentication plugin can be used for an account by providing the `IDENTIFIED VIA authentication_plugin` clause with the [CREATE USER](../create-user/index), [ALTER USER](../alter-user/index), or [GRANT](../grant/index) statements.

 For example, the following statement would create an account that authenticates with the [PAM authentication plugin](../authentication-plugin-pam/index):

 
```
CREATE USER foo2@test IDENTIFIED VIA pam;

```

If the specific authentication plugin uses the `authentication_string` column, then this value for the account can be specified after a `USING` or `AS` keyword. For example, the [PAM authentication plugin](../authentication-plugin-pam/index) accepts a [service name](../authentication-plugin-pam/index#configuring-the-pam-service) that would go into the `authentication_string` column for the account:

 
```
CREATE USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql-user-table/>

GRANT
=====

    Syntax
------

 
```
GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    TO user_specification [ user_options ...]

user_specification:
  username [authentication_option]
  | PUBLIC
authentication_option:
  IDENTIFIED BY 'password' 
  | IDENTIFIED BY PASSWORD 'password_hash'
  | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule  ...]

authentication_rule:
    authentication_plugin
  | authentication_plugin {USING|AS} 'authentication_string'
  | authentication_plugin {USING|AS} PASSWORD('password')

GRANT PROXY ON username
    TO user_specification [, user_specification ...]
    [WITH GRANT OPTION]

GRANT rolename TO grantee [, grantee ...]
    [WITH ADMIN OPTION]

grantee:
    rolename
    username [authentication_option]

user_options:
    [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
    [WITH with_option [with_option] ...]

object_type:
    TABLE
  | FUNCTION
  | PROCEDURE
  | PACKAGE

priv_level:
    *
  | *.*
  | db_name.*
  | db_name.tbl_name
  | tbl_name
  | db_name.routine_name

with_option:
    GRANT OPTION
  | resource_option

resource_option:
  MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
  | MAX_STATEMENT_TIME time

tls_option:
  SSL 
  | X509
  | CIPHER 'cipher'
  | ISSUER 'issuer'
  | SUBJECT 'subject'

```

Description
-----------

 The `GRANT` statement allows you to grant privileges or [roles](#roles) to accounts. To use `GRANT`, you must have the `GRANT OPTION` privilege, and you must have the privileges that you are granting.

 Use the [REVOKE](../revoke/index) statement to revoke privileges granted with the `GRANT` statement.

 Use the [SHOW GRANTS](../show-grants/index) statement to determine what privileges an account has.

 ### Account Names

 For `GRANT` statements, account names are specified as the `username` argument in the same way as they are for [CREATE USER](../create-user/index) statements. See [account names](../create-user/index#account-names) from the `CREATE USER` page for details on how account names are specified.

 ### Implicit Account Creation

 The `GRANT` statement also allows you to implicitly create accounts in some cases.

 If the account does not yet exist, then `GRANT` can implicitly create it. To implicitly create an account with `GRANT`, a user is required to have the same privileges that would be required to explicitly create the account with the `CREATE USER` statement.

 If the `NO_AUTO_CREATE_USER` [SQL\_MODE](../sql-mode/index) is set, then accounts can only be created if authentication information is specified, or with a [CREATE USER](../create-user/index) statement. If no authentication information is provided, `GRANT` will produce an error when the specified account does not exist, for example:

 
```
show variables like '%sql_mode%' ;
+---------------+--------------------------------------------+
| Variable_name | Value                                      |
+---------------+--------------------------------------------+
| sql_mode      | NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+

GRANT USAGE ON *.* TO 'user123'@'%' IDENTIFIED BY '';
ERROR 1133 (28000): Can't find any matching row in the user table

GRANT USAGE ON *.* TO 'user123'@'%' 
  IDENTIFIED VIA PAM using 'mariadb' require ssl ;
Query OK, 0 rows affected (0.00 sec)
 
select host, user from mysql.user where user='user123' ;

+------+----------+
| host | user     |
+------+----------+
| %    | user123 |
+------+----------+

```

### Privilege Levels

 Privileges can be set globally, for an entire database, for a table or routine, or for individual columns in a table. Certain privileges can only be set at certain levels.

 Global privileges do not take effect immediately and are only applied to connections created after the `GRANT` statement was executed.

 * [Global privileges *priv\_type*](#global-privileges) are granted using `*.*` for *priv\_level*. Global privileges include privileges to administer the database and manage user accounts, as well as privileges for all tables, functions, and procedures. Global privileges are stored in the [mysql.user table](../mysqluser-table/index) prior to [MariaDB 10.4](../what-is-mariadb-104/index), and in [mysql.global\_priv table](../mysqlglobal_priv-table/index) afterwards.
* [Database privileges *priv\_type*](#database-privileges) are granted using `db_name.*` for *priv\_level*, or using just `*` to use default database. Database privileges include privileges to create tables and functions, as well as privileges for all tables, functions, and procedures in the database. Database privileges are stored in the [mysql.db table](../mysqldb-table/index).
* [Table privileges *priv\_type*](#table-privileges) are granted using `db_name.tbl_name` for *priv\_level*, or using just `tbl_name` to specify a table in the default database. The `TABLE` keyword is optional. Table privileges include the ability to select and change data in the table. Certain table privileges can be granted for individual columns.
* [Column privileges *priv\_type*](#column-privileges) are granted by specifying a table for *priv\_level* and providing a column list after the privilege type. They allow you to control exactly which columns in a table users can select and change.
* [Function privileges *priv\_type*](#function-privileges) are granted using `FUNCTION db_name.routine_name` for *priv\_level*, or using just `FUNCTION routine_name` to specify a function in the default database.
* [Procedure privileges *priv\_type*](#procedure-privileges) are granted using `PROCEDURE db_name.routine_name` for *priv\_level*, or using just `PROCEDURE routine_name` to specify a procedure in the default database.

 #### The `USAGE` Privilege

 The `USAGE` privilege grants no real privileges. The [SHOW GRANTS](../show-grants/index) statement will show a global `USAGE` privilege for a newly-created user. You can use `USAGE` with the `GRANT` statement to change options like `GRANT OPTION` and `MAX_USER_CONNECTIONS` without changing any account privileges.

 #### The `ALL PRIVILEGES` Privilege

 The `ALL PRIVILEGES` privilege grants all available privileges. Granting all privileges only affects the given privilege level. For example, granting all privileges on a table does not grant any privileges on the database or globally.

 Using `ALL PRIVILEGES` does not grant the special `GRANT OPTION` privilege.

 You can use `ALL` instead of `ALL PRIVILEGES`.

 #### The `GRANT OPTION` Privilege

 Use the `WITH GRANT OPTION` clause to give users the ability to grant privileges to other users at the given privilege level. Users with the `GRANT OPTION` privilege can only grant privileges they have. They cannot grant privileges at a higher privilege level than they have the `GRANT OPTION` privilege.

 The `GRANT OPTION` privilege cannot be set for individual columns. If you use `WITH GRANT OPTION` when specifying [column privileges](#column-privileges), the `GRANT OPTION` privilege will be granted for the entire table.

 Using the `WITH GRANT OPTION` clause is equivalent to listing `GRANT OPTION` as a privilege.

 #### Global Privileges

 The following table lists the privileges that can be granted globally. You can also grant all database, table, and function privileges globally. When granted globally, these privileges apply to all databases, tables, or functions, including those created later.

 To set a global privilege, use `*.*` for *priv\_level*.

 ##### BINLOG ADMIN

 Enables administration of the [binary log](../binary-log/index), including the [PURGE BINARY LOGS](../purge-binary-logs/index) statement and setting the system variables:

 * [binlog\_annotate\_row\_events](../replication-and-binary-log-system-variables/index#binlog_annotate_row_events)
* [binlog\_cache\_size](../replication-and-binary-log-system-variables/index#binlog_cache_size)
* [binlog\_commit\_wait\_count](../replication-and-binary-log-system-variables/index#binlog_commit_wait_count)
* [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec)
* [binlog\_direct\_non\_transactional\_updates](../replication-and-binary-log-system-variables/index#binlog_direct_non_transactional_updates)
* [binlog\_expire\_logs\_seconds](../replication-and-binary-log-system-variables/index#binlog_expire_logs_seconds)
* [binlog\_file\_cache\_size](../replication-and-binary-log-system-variables/index#binlog_file_cache_size)
* [binlog\_format](../replication-and-binary-log-system-variables/index#binlog_format)
* [binlog\_row\_image](../replication-and-binary-log-system-variables/index#binlog_row_image)
* [binlog\_row\_metadata](../replication-and-binary-log-system-variables/index#binlog_row_metadata)
* [binlog\_stmt\_cache\_size](../replication-and-binary-log-system-variables/index#binlog_stmt_cache_size)
* [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days)
* [log\_bin\_compress](../replication-and-binary-log-system-variables/index#log_bin_compress)
* [log\_bin\_compress\_min\_len](../replication-and-binary-log-system-variables/index#log_bin_compress_min_len)
* [log\_bin\_trust\_function\_creators](../replication-and-binary-log-system-variables/index#log_bin_trust_function_creators)
* [max\_binlog\_cache\_size](../replication-and-binary-log-system-variables/index#max_binlog_cache_size)
* [max\_binlog\_size](../replication-and-binary-log-system-variables/index#max_binlog_size)
* [max\_binlog\_stmt\_cache\_size](../replication-and-binary-log-system-variables/index#max_binlog_stmt_cache_size)
* [sql\_log\_bin](../replication-and-binary-log-system-variables/index#sql_log_bin) and
* [sync\_binlog](../replication-and-binary-log-system-variables/index#sync_binlog).

 Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). 

 ##### BINLOG MONITOR

 New name for [REPLICATION CLIENT](#replication-client) from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), (`REPLICATION CLIENT` still supported as an alias for compatibility purposes). Permits running SHOW commands related to the [binary log](../binary-log/index), in particular the [SHOW BINLOG STATUS](../show-binlog-status/index) and [SHOW BINARY LOGS](../show-binary-logs/index) statements. Unlike [REPLICATION CLIENT](#replication-client) prior to [MariaDB 10.5](../what-is-mariadb-105/index), [SHOW REPLICA STATUS](../show-replica-status/index) isn't included in this privilege, and [REPLICA MONITOR](#replica-monitor) is required.

 ##### BINLOG REPLAY

 Enables replaying the binary log with the [BINLOG](../binlog/index) statement (generated by [mariadb-binlog](../mysqlbinlog/index)), executing [SET timestamp](../server-system-variables/index#timestamp) when [secure\_timestamp](../server-system-variables/index#secure_timestamp) is set to `replication`, and setting the session values of system variables usually included in BINLOG output, in particular:

 * [gtid\_domain\_id](../gtid/index#gtid_domain_id)
* [gtid\_seq\_no](../gtid/index#gtid_seq_no)
* [pseudo\_thread\_id](../server-system-variables/index#pseudo_thread_id)
* [server\_id](../replication-and-binary-log-system-variables/index#server_id).

 Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 ##### CONNECTION ADMIN

 Enables administering connection resource limit options. This includes ignoring the limits specified by:

 * [max\_connections](../server-system-variables/index#max_connections)
* [max\_user\_connections](../server-system-variables/index#max_user_connections) and
* [max\_password\_errors](../server-system-variables/index#max_password_errors).

 The statements specified in [init\_connect](../server-system-variables/index#init_connect) are not executed, [killing connections and queries](../kill/index) owned by other users is permitted. The following connection-related system variables can be changed:

 * [connect\_timeout](../server-system-variables/index#connect_timeout)
* [disconnect\_on\_expired\_password](../server-system-variables/index#disconnect_on_expired_password)
* [extra\_max\_connections](../thread-pool-system-status-variables/index#extra_max_connections)
* [init\_connect](../server-system-variables/index#init_connect)
* [max\_connections](../server-system-variables/index#max_connections)
* [max\_connect\_errors](../server-system-variables/index#max_connect_errors)
* [max\_password\_errors](../server-system-variables/index#max_password_errors)
* [proxy\_protocol\_networks](../server-system-variables/index#proxy_protocol_networks)
* [secure\_auth](../server-system-variables/index#secure_auth)
* [slow\_launch\_time](../server-system-variables/index#slow_launch_time)
* [thread\_pool\_exact\_stats](../thread-pool-system-status-variables/index#thread_pool_exact_stats)
* [thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener)
* [thread\_pool\_idle\_timeout](../thread-pool-system-status-variables/index#thread_pool_idle_timeout)
* [thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)
* [thread\_pool\_min\_threads](../thread-pool-system-status-variables/index#thread_pool_min_threads)
* [thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)
* [thread\_pool\_prio\_kickup\_timer](../thread-pool-system-status-variables/index#thread_pool_prio_kickup_timer)
* [thread\_pool\_priority](../thread-pool-system-status-variables/index#thread_pool_priority)
* [thread\_pool\_size](../thread-pool-system-status-variables/index#thread_pool_size), and
* [thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit).

 Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 ##### CREATE USER

 Create a user using the [CREATE USER](../create-user/index) statement, or implicitly create a user with the `GRANT` statement.

 ##### FEDERATED ADMIN

 Execute [CREATE SERVER](../create-server/index), [ALTER SERVER](../alter-server/index), and [DROP SERVER](../drop-server/index) statements. Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 ##### FILE

 Read and write files on the server, using statements like [LOAD DATA INFILE](../load-data-infile/index) or functions like [LOAD\_FILE()](../load_file/index). Also needed to create [CONNECT](../connect/index) outward tables. MariaDB server must have the permissions to access those files.

 ##### GRANT OPTION

 Grant global privileges. You can only grant privileges that you have.

 ##### PROCESS

 Show information about the active processes, for example via [SHOW PROCESSLIST](../show-processlist/index) or [mariadb-admin processlist](../mariadb-admin/index). If you have the PROCESS privilege, you can see all threads. Otherwise, you can see only your own threads (that is, threads associated with the MariaDB account that you are using).

 ##### READ\_ONLY ADMIN

 User can set the [read\_only](../server-system-variables/index#read_only) system variable and allows the user to perform write operations, even when the `read_only` option is active. Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 From [MariaDB 10.11.0](../mdb-10-11-0-rn/index), the `READ_ONLY ADMIN` privilege has been removed from [SUPER](#super). The benefit of this is that one can remove the READ\_ONLY ADMIN privilege from all users and ensure that no one can make any changes on any non-temporary tables. This is useful on replicas when one wants to ensure that the replica is kept identical to the primary.

 ##### RELOAD

 Execute [FLUSH](../flush/index) statements or equivalent [mariadb-admin](../mariadb-admin/index) commands.

 ##### REPLICATION CLIENT

 Execute [SHOW MASTER STATUS](../show-master-status/index) and [SHOW BINARY LOGS](../show-binary-logs/index) informative statements. Renamed to [BINLOG MONITOR](#binlog-monitor) in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) (but still supported as an alias for compatibility reasons). [SHOW SLAVE STATUS](../show-slave-status/index) was part of [REPLICATION CLIENT](#replication-client) prior to [MariaDB 10.5](../what-is-mariadb-105/index).

 ##### REPLICATION MASTER ADMIN

 Permits administration of primary servers, including the [SHOW REPLICA HOSTS](../show-replica-hosts/index) statement, and setting the [gtid\_binlog\_state](../gtid/index#gtid_binlog_state), [gtid\_domain\_id](../gtid/index#gtid_domain_id), [master\_verify\_checksum](../replication-and-binary-log-system-variables/index#master_verify_checksum) and [server\_id](../replication-and-binary-log-system-variables/index#server_id) system variables. Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 ##### REPLICA MONITOR

 Permit [SHOW REPLICA STATUS](../show-replica-status/index) and [SHOW RELAYLOG EVENTS](../show-relaylog-events/index). From [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/).

 When a user would upgrade from an older major release to a [MariaDB 10.5](../what-is-mariadb-105/index) minor release prior to [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), certain user accounts would lose capabilities. For example, a user account that had the REPLICATION CLIENT privilege in older major releases could run [SHOW REPLICA STATUS](../show-replica-status/index), but after upgrading to a [MariaDB 10.5](../what-is-mariadb-105/index) minor release prior to [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), they could no longer run [SHOW REPLICA STATUS](../show-replica-status/index), because that statement was changed to require the REPLICATION REPLICA ADMIN privilege.

 This issue is fixed in [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/) with this new privilege, which now grants the user the ability to execute SHOW [ALL] (SLAVE | REPLICA) STATUS.

 When a database is upgraded from an older major release to MariaDB Server 10.5.9 or later, any user accounts with the REPLICATION CLIENT or REPLICATION SLAVE privileges will automatically be granted the new REPLICA MONITOR privilege. The privilege fix occurs when the server is started up, not when mariadb-upgrade is performed.

 However, when a database is upgraded from an early 10.5 minor release to 10.5.9 and later, the user will have to fix any user account privileges manually.

 ##### REPLICATION REPLICA

 Synonym for [REPLICATION SLAVE](#replication-slave). From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/).

 ##### REPLICATION SLAVE

 Accounts used by replica servers on the primary need this privilege. This is needed to get the updates made on the master. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), [REPLICATION REPLICA](#replication-replica) is an alias for `REPLICATION SLAVE`.

 ##### REPLICATION SLAVE ADMIN

 Permits administering replica servers, including [START REPLICA/SLAVE](../start-replica/index), [STOP REPLICA/SLAVE](../stop-replica/index), [CHANGE MASTER](../change-master-to/index), [SHOW REPLICA/SLAVE STATUS](../show-replica-status/index), [SHOW RELAYLOG EVENTS](../show-relaylog-events/index) statements, replaying the binary log with the [BINLOG](../binlog/index) statement (generated by [mariadb-binlog](../mysqlbinlog/index)), and setting the system variables:

 * [gtid\_cleanup\_batch\_size](../gtid/index#gtid_cleanup_batch_size)
* [gtid\_ignore\_duplicates](../gtid/index#gtid_ignore_duplicates)
* [gtid\_pos\_auto\_engines](../gtid/index#gtid_pos_auto_engines)
* [gtid\_slave\_pos](../gtid/index#gtid_slave_pos)
* [gtid\_strict\_mode](../gtid/index#gtid_strict_mode)
* [init\_slave](../replication-and-binary-log-system-variables/index#init_slave)
* [read\_binlog\_speed\_limit](../replication-and-binary-log-system-variables/index#read_binlog_speed_limit)
* [relay\_log\_purge](../replication-and-binary-log-system-variables/index#relay_log_purge)
* [relay\_log\_recovery](../replication-and-binary-log-system-variables/index#relay_log_recovery)
* [replicate\_do\_db](../replication-and-binary-log-system-variables/index#replicate_do_db)
* [replicate\_do\_table](../replication-and-binary-log-system-variables/index#replicate_do_table)
* [replicate\_events\_marked\_for\_skip](../replication-and-binary-log-system-variables/index#replicate_events_marked_for_skip)
* [replicate\_ignore\_db](../replication-and-binary-log-system-variables/index#replicate_ignore_db)
* [replicate\_ignore\_table](../replication-and-binary-log-system-variables/index#replicate_ignore_table)
* [replicate\_wild\_do\_table](../replication-and-binary-log-system-variables/index#replicate_wild_do_table)
* [replicate\_wild\_ignore\_table](../replication-and-binary-log-system-variables/index#replicate_wild_ignore_table)
* [slave\_compressed\_protocol](../replication-and-binary-log-system-variables/index#slave_compressed_protocol)
* [slave\_ddl\_exec\_mode](../replication-and-binary-log-system-variables/index#slave_ddl_exec_mode)
* [slave\_domain\_parallel\_threads](../replication-and-binary-log-system-variables/index#slave_domain_parallel_threads)
* [slave\_exec\_mode](../replication-and-binary-log-system-variables/index#slave_exec_mode)
* [slave\_max\_allowed\_packet](../replication-and-binary-log-system-variables/index#slave_max_allowed_packet)
* [slave\_net\_timeout](../replication-and-binary-log-system-variables/index#slave_net_timeout)
* [slave\_parallel\_max\_queued](../replication-and-binary-log-system-variables/index#slave_parallel_max_queued)
* [slave\_parallel\_mode](../replication-and-binary-log-system-variables/index#slave_parallel_mode)
* [slave\_parallel\_threads](../replication-and-binary-log-system-variables/index#slave_parallel_threads)
* [slave\_parallel\_workers](../replication-and-binary-log-system-variables/index#slave_parallel_workers)
* [slave\_run\_triggers\_for\_rbr](../replication-and-binary-log-system-variables/index#slave_run_triggers_for_rbr)
* [slave\_sql\_verify\_checksum](../replication-and-binary-log-system-variables/index#slave_sql_verify_checksum)
* [slave\_transaction\_retry\_interval](../replication-and-binary-log-system-variables/index#slave_transaction_retry_interval)
* [slave\_type\_conversions](../replication-and-binary-log-system-variables/index#slave_type_conversions)
* [sync\_master\_info](../replication-and-binary-log-system-variables/index#sync_master_info)
* [sync\_relay\_log](../replication-and-binary-log-system-variables/index#sync_relay_log), and
* [sync\_relay\_log\_info](../replication-and-binary-log-system-variables/index#sync_relay_log_info).

  Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 ##### SET USER

 Enables setting the `DEFINER` when creating [triggers](../triggers/index), [views](../views/index), [stored functions](../stored-functions/index) and [stored procedures](../stored-procedures/index). Added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 ##### SHOW DATABASES

 List all databases using the [SHOW DATABASES](../show-databases/index) statement. Without the `SHOW DATABASES` privilege, you can still issue the `SHOW DATABASES` statement, but it will only list databases containing tables on which you have privileges.

 ##### SHUTDOWN

 Shut down the server using [SHUTDOWN](../shutdown/index) or the [mariadb-admin shutdown](../mariadb-admin/index) command.

 ##### SUPER

 Execute superuser statements: [CHANGE MASTER TO](../change-master-to/index), [KILL](../kill/index) (users who do not have this privilege can only `KILL` their own threads), [PURGE LOGS](../purge-binary-logs/index), [SET global system variables](../set/index), or the [mariadb-admin debug](../mariadb-admin/index) command. Also, this permission allows the user to write data even if the [read\_only](../server-system-variables/index#read_only) startup option is set, enable or disable logging, enable or disable replication on replica, specify a `DEFINER` for statements that support that clause, connect once reaching the `MAX_CONNECTIONS`. If a statement has been specified for the [init-connect](../server-system-variables/index#init_connect) `mysqld` option, that command will not be executed when a user with `SUPER` privileges connects to the server.

 The SUPER privilege has been split into multiple smaller privileges from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) to allow for more fine-grained privileges ([MDEV-21743](https://jira.mariadb.org/browse/MDEV-21743)). The privileges are:

 * [SET USER](#set-user)
* [FEDERATED ADMIN](#federated-admin)
* [CONNECTION ADMIN](#connection-admin)
* [REPLICATION SLAVE ADMIN](#replication-slave-admin)
* [BINLOG ADMIN](#binlog-admin)
* [BINLOG REPLAY](#binlog-replay)
* [REPLICA MONITOR](#replica-monitor)
* [BINLOG MONITOR](#binlog-monitor)
* [REPLICATION MASTER ADMIN](#replication-master-admin)
* [READ\_ONLY ADMIN](#read_only-admin)

 However, the smaller privileges are still a part of the SUPER grant in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). From [MariaDB 11.0.1](../mdb-11-0-1-rn/index) onwards, these grants are no longer a part of SUPER and need to be granted separately ([MDEV-29668](https://jira.mariadb.org/browse/MDEV-29668)).

 From [MariaDB 10.11.0](../mdb-10-11-0-rn/index), the [READ\_ONLY ADMIN](#read_only-admin) privilege has been removed from `SUPER`. The benefit of this is that one can remove the READ\_ONLY ADMIN privilege from all users and ensure that no one can make any changes on any non-temporary tables. This is useful on replicas when one wants to ensure that the replica is kept identical to the primary ([MDEV-29596](https://jira.mariadb.org/browse/MDEV-29596)).

 #### Database Privileges

 The following table lists the privileges that can be granted at the database level. You can also grant all table and function privileges at the database level. Table and function privileges on a database apply to all tables or functions in that database, including those created later.

 To set a privilege for a database, specify the database using `db_name.*` for *priv\_level*, or just use `*` to specify the default database.

 


| Privilege | Description |
| --- | --- |
| `CREATE` | Create a database using the [CREATE DATABASE](../create-database/index) statement, when the privilege is granted for a database. You can grant the `CREATE` privilege on databases that do not yet exist. This also grants the `CREATE` privilege on all tables in the database. |
| `CREATE ROUTINE` | Create Stored Programs using the [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) statements. |
| `CREATE TEMPORARY TABLES` | Create temporary tables with the [CREATE TEMPORARY TABLE](../create-table/index) statement. This privilege enable writing and dropping those temporary tables |
| `DROP` | Drop a database using the [DROP DATABASE](../drop-database/index) statement, when the privilege is granted for a database. This also grants the `DROP` privilege on all tables in the database. |
| `EVENT` | Create, drop and alter `EVENT`s. |
| `GRANT OPTION` | Grant database privileges. You can only grant privileges that you have. |
| `LOCK TABLES` | Acquire explicit locks using the [LOCK TABLES](../lock-tables/index) statement; you also need to have the `SELECT` privilege on a table, in order to lock it. |

 
#### Table Privileges

 


| Privilege | Description |
| --- | --- |
| `ALTER` | Change the structure of an existing table using the [ALTER TABLE](../alter-table/index) statement. |
| `CREATE` | Create a table using the [CREATE TABLE](../create-table/index) statement. You can grant the `CREATE` privilege on tables that do not yet exist. |
| `CREATE VIEW` | Create a view using the [CREATE\_VIEW](../create-view/index) statement. |
| `DELETE` | Remove rows from a table using the [DELETE](../delete/index) statement. |
| `DELETE HISTORY` | Remove [historical rows](../system-versioned-tables/index) from a table using the [DELETE HISTORY](../delete/index) statement. Displays as `DELETE VERSIONING ROWS` when running [SHOW GRANTS](../show-grants/index) until [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/) and until [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) ([MDEV-17655](https://jira.mariadb.org/browse/MDEV-17655)), or when running SHOW PRIVILEGES until [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/) and [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/) ([MDEV-20382](https://jira.mariadb.org/browse/MDEV-20382)). From [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/). From [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), if a user has the `SUPER` privilege but not this privilege, running [mariadb-upgrade](../mariadb-upgrade/index) will grant this privilege as well. |
| `DROP` | Drop a table using the [DROP TABLE](../drop-table/index) statement or a view using the [DROP VIEW](../drop-view/index) statement. Also required to execute the [TRUNCATE TABLE](../truncate-table/index) statement. |
| `GRANT OPTION` | Grant table privileges. You can only grant privileges that you have. |
| `INDEX` | Create an index on a table using the [CREATE INDEX](../create-index/index) statement. Without the `INDEX` privilege, you can still create indexes when creating a table using the [CREATE TABLE](../create-table/index) statement if the you have the `CREATE` privilege, and you can create indexes using the [ALTER TABLE](../alter-table/index) statement if you have the `ALTER` privilege. |
| `INSERT` | Add rows to a table using the [INSERT](../insert/index) statement. The `INSERT` privilege can also be set on individual columns; see [Column Privileges](#column-privileges) below for details. |
| `REFERENCES` | Unused. |
| `SELECT` | Read data from a table using the [SELECT](../select/index) statement. The `SELECT` privilege can also be set on individual columns; see [Column Privileges](#column-privileges) below for details. |
| `SHOW VIEW` | Show the [CREATE VIEW](../create-view/index) statement to create a view using the [SHOW CREATE VIEW](../show-create-view/index) statement. |
| `TRIGGER` | Execute triggers associated to tables you update, execute the [CREATE TRIGGER](../create-trigger/index), [DROP TRIGGER](../drop-trigger/index), and [SHOW CREATE TRIGGER](../show-create-trigger/index) statements. |
| `UPDATE` | Update existing rows in a table using the [UPDATE](../update/index) statement. `UPDATE` statements usually include a `WHERE` clause to update only certain rows. You must have `SELECT` privileges on the table or the appropriate columns for the `WHERE` clause. The `UPDATE` privilege can also be set on individual columns; see [Column Privileges](#column-privileges) below for details. |

 
#### Column Privileges

 Some table privileges can be set for individual columns of a table. To use column privileges, specify the table explicitly and provide a list of column names after the privilege type. For example, the following statement would allow the user to read the names and positions of employees, but not other information from the same table, such as salaries.

 
```
GRANT SELECT (name, position) on Employee to 'jeffrey'@'localhost';

```




| Privilege | Description |
| --- | --- |
| `INSERT (column_list)` | Add rows specifying values in columns using the [INSERT](../insert/index) statement. If you only have column-level `INSERT` privileges, you must specify the columns you are setting in the `INSERT` statement. All other columns will be set to their default values, or `NULL`. |
| `REFERENCES (column_list)` | Unused. |
| `SELECT (column_list)` | Read values in columns using the [SELECT](../select/index) statement. You cannot access or query any columns for which you do not have `SELECT` privileges, including in `WHERE`, `ON`, `GROUP BY`, and `ORDER BY` clauses. |
| `UPDATE (column_list)` | Update values in columns of existing rows using the [UPDATE](../update/index) statement. `UPDATE` statements usually include a `WHERE` clause to update only certain rows. You must have `SELECT` privileges on the table or the appropriate columns for the `WHERE` clause. |

 
#### Function Privileges

 


| Privilege | Description |
| --- | --- |
| `ALTER ROUTINE` | Change the characteristics of a stored function using the [ALTER FUNCTION](../alter-function/index) statement. |
| `EXECUTE` | Use a stored function. You need `SELECT` privileges for any tables or columns accessed by the function. |
| `GRANT OPTION` | Grant function privileges. You can only grant privileges that you have. |

 
#### Procedure Privileges

 


| Privilege | Description |
| --- | --- |
| `ALTER ROUTINE` | Change the characteristics of a stored procedure using the [ALTER PROCEDURE](../alter-procedure/index) statement. |
| `EXECUTE` | Execute a [stored procedure](../stored-procedures/index) using the [CALL](../call/index) statement. The privilege to call a procedure may allow you to perform actions you wouldn't otherwise be able to do, such as insert rows into a table. |
| `GRANT OPTION` | Grant procedure privileges. You can only grant privileges that you have. |

 

```
GRANT EXECUTE ON PROCEDURE mysql.create_db TO maintainer;

```

#### Proxy Privileges

 


| Privilege | Description |
| --- | --- |
| `PROXY` | Permits one user to be a proxy for another. |

 
The `PROXY` privilege allows one user to proxy as another user, which means their privileges change to that of the proxy user, and the [CURRENT\_USER()](../current_user/index) function returns the user name of the proxy user.

 The `PROXY` privilege only works with authentication plugins that support it. The default [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin does not support proxy users.

 The [pam](../authentication-plugin-pam/index) authentication plugin is the only plugin included with MariaDB that currently supports proxy users. The `PROXY` privilege is commonly used with the [pam](../authentication-plugin-pam/index) authentication plugin to enable [user and group mapping with PAM](../user-and-group-mapping-with-pam/index).

 For example, to grant the `PROXY` privilege to an [anonymous account](../create-user/index#anonymous-accounts) that authenticates with the [pam](../authentication-plugin-pam/index) authentication plugin, you could execute the following:

 
```
CREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'%' ;

CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
GRANT PROXY ON 'dba'@'%' TO ''@'%';

```

A user account can only grant the `PROXY` privilege for a specific user account if the granter also has the `PROXY` privilege for that specific user account, and if that privilege is defined `WITH GRANT OPTION`. For example, the following example fails because the granter does not have the `PROXY` privilege for that specific user account at all:

 
```
SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+-----------------------------------------------------------------------------------------------------------------------+
| Grants for alice@localhost                                                                                            |
+-----------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
+-----------------------------------------------------------------------------------------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';
ERROR 1698 (28000): Access denied for user 'alice'@'localhost'

```

And the following example fails because the granter does have the `PROXY` privilege for that specific user account, but it is not defined `WITH GRANT OPTION`:

 
```
SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+-----------------------------------------------------------------------------------------------------------------------+
| Grants for alice@localhost                                                                                            |
+-----------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
| GRANT PROXY ON 'dba'@'localhost' TO 'alice'@'localhost'                                                               |
+-----------------------------------------------------------------------------------------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';
ERROR 1698 (28000): Access denied for user 'alice'@'localhost'

```

But the following example succeeds because the granter does have the `PROXY` privilege for that specific user account, and it is defined `WITH GRANT OPTION`:

 
```
SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+-----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for alice@localhost                                                                                                              |
+-----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
| GRANT PROXY ON 'dba'@'localhost' TO 'alice'@'localhost' WITH GRANT OPTION                                                               |
+-----------------------------------------------------------------------------------------------------------------------------------------+

GRANT PROXY ON 'dba'@'localhost' TO 'bob'@'localhost';

```

A user account can grant the `PROXY` privilege for any other user account if the granter has the `PROXY` privilege for the `''@'%'` anonymous user account, like this:

 
```
GRANT PROXY ON ''@'%' TO 'dba'@'localhost' WITH GRANT OPTION;

```

For example, the following example succeeds because the user can grant the `PROXY` privilege for any other user account:

 
```
SELECT USER(), CURRENT_USER();
+-----------------+-----------------+
| USER()          | CURRENT_USER()  |
+-----------------+-----------------+
| alice@localhost | alice@localhost |
+-----------------+-----------------+

SHOW GRANTS;
+-----------------------------------------------------------------------------------------------------------------------------------------+
| Grants for alice@localhost                                                                                                              |
+-----------------------------------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'alice'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'alice'@'localhost' WITH GRANT OPTION                                                                          |
+-----------------------------------------------------------------------------------------------------------------------------------------+

GRANT PROXY ON 'app1_dba'@'localhost' TO 'bob'@'localhost';
Query OK, 0 rows affected (0.004 sec)

GRANT PROXY ON 'app2_dba'@'localhost' TO 'carol'@'localhost';
Query OK, 0 rows affected (0.004 sec)

```

The default `root` user accounts created by [mariadb-install-db](../mariadb-install-db/index) have this privilege. For example:

 
```
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION;

```

This allows the default `root` user accounts to grant the `PROXY` privilege for any other user account, and it also allows the default `root` user accounts to grant others the privilege to do the same.

 ### Authentication Options

 The authentication options for the `GRANT` statement are the same as those for the [CREATE USER](../create-user/index) statement.

 #### IDENTIFIED BY 'password'

 The optional `IDENTIFIED BY` clause can be used to provide an account with a password. The password should be specified in plain text. It will be hashed by the [PASSWORD](../password/index) function prior to being stored.

 For example, if our password is `mariadb`, then we can create the user with:

 
```
GRANT USAGE ON *.* TO foo2@test IDENTIFIED BY 'mariadb';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 If the user account already exists and if you provide the `IDENTIFIED BY` clause, then the user's password will be changed. You must have the privileges needed for the [SET PASSWORD](../set-password/index) statement to change a user's password with `GRANT`.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 #### IDENTIFIED BY PASSWORD 'password\_hash'

 The optional `IDENTIFIED BY PASSWORD` clause can be used to provide an account with a password that has already been hashed. The password should be specified as a hash that was provided by the [PASSWORD](../password/index) function. It will be stored as-is.

 For example, if our password is `mariadb`, then we can find the hash with:

 
```
SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+
1 row in set (0.00 sec)

```

And then we can create a user with the hash:

 
```
GRANT USAGE ON *.* TO foo2@test IDENTIFIED BY 
  PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 If the user account already exists and if you provide the `IDENTIFIED BY` clause, then the user's password will be changed. You must have the privileges needed for the [SET PASSWORD](../set-password/index) statement to change a user's password with `GRANT`.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 #### IDENTIFIED {VIA|WITH} authentication\_plugin

 The optional `IDENTIFIED VIA authentication_plugin` allows you to specify that the account should be authenticated by a specific [authentication plugin](../authentication-plugins/index). The plugin name must be an active authentication plugin as per [SHOW PLUGINS](../show-plugins/index). If it doesn't show up in that output, then you will need to install it with [INSTALL PLUGIN](../install-plugin/index) or [INSTALL SONAME](../install-soname/index).

 For example, this could be used with the [PAM authentication plugin](../authentication-plugin-pam/index):

 
```
GRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam;

```

Some authentication plugins allow additional arguments to be specified after a `USING` or `AS` keyword. For example, the [PAM authentication plugin](../authentication-plugin-pam/index) accepts a [service name](../authentication-plugin-pam/index#configuring-the-pam-service):

 
```
GRANT USAGE ON *.* TO foo2@test IDENTIFIED VIA pam USING 'mariadb';

```

The exact meaning of the additional argument would depend on the specific authentication plugin.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**The `USING` or `AS` keyword can also be used to provide a plain-text password to a plugin if it's provided as an argument to the [PASSWORD()](../password/index) function. This is only valid for [authentication plugins](../authentication-plugins/index) that have implemented a hook for the [PASSWORD()](../password/index) function. For example, the [ed25519](../authentication-plugin-ed25519/index) authentication plugin supports this:

 
```
CREATE USER safe@'%' IDENTIFIED VIA ed25519 
  USING PASSWORD('secret');

```



**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**One can specify many authentication plugins, they all work as alternatives ways of authenticating a user:

 
```
CREATE USER safe@'%' IDENTIFIED VIA ed25519 
  USING PASSWORD('secret') OR unix_socket;

```


By default, when you create a user without specifying an authentication plugin, MariaDB uses the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) plugin.

 ### Resource Limit Options

 It is possible to set per-account limits for certain server resources. The following table shows the values that can be set per account:

 


| Limit Type | Decription |
| --- | --- |
| `MAX_QUERIES_PER_HOUR` | Number of statements that the account can issue per hour (including updates) |
| `MAX_UPDATES_PER_HOUR` | Number of updates (not queries) that the account can issue per hour |
| `MAX_CONNECTIONS_PER_HOUR` | Number of connections that the account can start per hour |
| `MAX_USER_CONNECTIONS` | Number of simultaneous connections that can be accepted from the same account; if it is 0, `max_connections` will be used instead; if `max_connections` is 0, there is no limit for this account's simultaneous connections. |
| `MAX_STATEMENT_TIME` | Timeout, in seconds, for statements executed by the user. See also [Aborting Statements that Exceed a Certain Time to Execute](../aborting-statements/index). |

 
If any of these limits are set to `0`, then there is no limit for that resource for that user.

 To set resource limits for an account, if you do not want to change that account's privileges, you can issue a `GRANT` statement with the `USAGE` privilege, which has no meaning. The statement can name some or all limit types, in any order.

 Here is an example showing how to set resource limits:

 
```
GRANT USAGE ON *.* TO 'someone'@'localhost' WITH
    MAX_USER_CONNECTIONS 0
    MAX_QUERIES_PER_HOUR 200;

```

The resources are tracked per account, which means `'user'@'server'`; not per user name or per connection.

 The count can be reset for all users using [FLUSH USER\_RESOURCES](../flush/index), [FLUSH PRIVILEGES](../flush/index) or [mariadb-admin reload](../mariadb-admin/index).

 Users with the `CONNECTION ADMIN` privilege (in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) and later) or the `SUPER` privilege are not restricted by `max_user_connections`, `max_connections`, or `max_password_errors`.

 Per account resource limits are stored in the [user](../mysqluser-table/index) table, in the [mysql](../the-mysql-database-tables/index) database. Columns used for resources limits are named `max_questions`, `max_updates`, `max_connections` (for `MAX_CONNECTIONS_PER_HOUR`), and `max_user_connections` (for `MAX_USER_CONNECTIONS`).

 ### TLS Options

 By default, MariaDB transmits data between the server and clients without encrypting it. This is generally acceptable when the server and client run on the same host or in networks where security is guaranteed through other means. However, in cases where the server and client exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt data in transit between the server and clients using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix ssl\_, but internally, MariaDB only supports its secure successors.

 See [Secure Connections Overview](../secure-connections-overview/index) for more information about how to determine whether your MariaDB server has TLS support.

 You can set certain TLS-related restrictions for specific user accounts. For instance, you might use this with user accounts that require access to sensitive data while sending it across networks that you do not control. These restrictions can be enabled for a user account with the [CREATE USER](../create-user/index), [ALTER USER](../alter-user/index), or [GRANT](index) statements. The following options are available:

 


| Option | Description |
| --- | --- |
| `REQUIRE NONE` | TLS is not required for this account, but can still be used. |
| `REQUIRE SSL` | The account must use TLS, but no valid X509 certificate is required. This option cannot be combined with other TLS options. |
| `REQUIRE X509` | The account must use TLS and must have a valid X509 certificate. This option implies `REQUIRE SSL`. This option cannot be combined with other TLS options. |
| `REQUIRE ISSUER 'issuer'` | The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be the one specified via the string `issuer`. This option implies `REQUIRE X509`. This option can be combined with the `SUBJECT`, and `CIPHER` options in any order. |
| `REQUIRE SUBJECT 'subject'` | The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be the one specified via the string `subject`. This option implies `REQUIRE X509`. This option can be combined with the `ISSUER`, and `CIPHER` options in any order. |
| `REQUIRE CIPHER 'cipher'` | The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the connection must use a specific cipher method specified in the string `cipher`. This option implies `REQUIRE SSL`. This option can be combined with the `ISSUER`, and `SUBJECT` options in any order. |

 
The `REQUIRE` keyword must be used only once for all specified options, and the `AND` keyword can be used to separate individual options, but it is not required.

 For example, you can create a user account that requires these TLS options with the following:

 
```
GRANT USAGE ON *.* TO 'alice'@'%'
  REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
  AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com'
  AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

```

If any of these options are set for a specific user account, then any client who tries to connect with that user account will have to be configured to connect with TLS.

 See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to enable TLS on the client and server.

 ### Roles

 #### Syntax

 
```
GRANT role TO grantee [, grantee ... ]
[ WITH ADMIN OPTION ]

grantee:
    rolename
    username [authentication_option]

```

The GRANT statement is also used to grant the use of a [role](../roles/index) to one or more users or other roles. In order to be able to grant a role, the grantor doing so must have permission to do so (see WITH ADMIN in the [CREATE ROLE](../create-role/index) article).

 Specifying the `WITH ADMIN OPTION` permits the grantee to in turn grant the role to another.

 For example, the following commands show how to grant the same role to a couple different users.

 
```
GRANT journalist TO hulda;

GRANT journalist TO berengar WITH ADMIN OPTION;

```

If a user has been granted a role, they do not automatically obtain all permissions associated with that role. These permissions are only in use when the user activates the role with the [SET ROLE](../set-role/index) statement.

 ### TO PUBLIC

 
**MariaDB starting with [10.11](../what-is-mariadb-1011/index)**#### Syntax

 
```
GRANT <privilege> ON <database>.<object> TO PUBLIC;
REVOKE <privilege> ON <database>.<object> FROM PUBLIC;

```

GRANT ... TO PUBLIC grants privileges to all users with access to the server. The privileges also apply to users created after the privileges are granted. This can be useful when one only wants to state once that all users need to have a certain set of privileges. 

 When running [SHOW GRANTS](../show-grants/index), a user will also see all privileges inherited from PUBLIC. [SHOW GRANTS FOR PUBLIC](../show-grants/index#for-public) will only show TO PUBLIC grants.

 
Grant Examples
--------------

 ### Granting Root-like Privileges

 You can create a user that has privileges similar to the default `root` accounts by executing the following:

 
```
CREATE USER 'alexander'@'localhost';
GRANT ALL PRIVILEGES ON  *.* to 'alexander'@'localhost' WITH GRANT OPTION;

```

See Also
--------

 * [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index)
* [--skip-grant-tables](../mysqld-options/index#-skip-grant-tables) allows you to start MariaDB without `GRANT`. This is useful if you lost your root password.
* [CREATE USER](../create-user/index)
* [ALTER USER](../alter-user/index)
* [DROP USER](../drop-user/index)
* [SET PASSWORD](../set-password/index)
* [SHOW CREATE USER](../show-create-user/index)
* [mysql.global\_priv table](../mysqlglobal_priv-table/index)
* [mysql.user table](../mysqluser-table/index)
* [Password Validation Plugins](../password-validation-plugins/index) - permits the setting of basic criteria for passwords
* [Authentication Plugins](../authentication-plugins/index) - allow various authentication methods to be used, and new ones to be developed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/grant/>

Roles
======

   Roles bundle privileges together to ease account management

  

| Title | Description |
| --- | --- |
|  [Roles Overview](../roles_overview/index) |  Bundling privileges together.  |
|  [CREATE ROLE](../create-role/index) |  Add new roles.  |
|  [DROP ROLE](../drop-role/index) |  Drop a role.  |
|  [CURRENT\_ROLE](../current_role/index) |  Current role name.  |
|  [SET ROLE](../set-role/index) |  Enable a role.  |
|  [SET DEFAULT ROLE](../set-default-role/index) |  Sets a default role for a specified (or current) user.  |
|  [GRANT](../grant/index) |  Create accounts and set privileges or roles.  |
|  [REVOKE](../revoke/index) |  Remove privileges or roles.  |
|  [mysql.roles\_mapping Table](../mysqlroles_mapping-table/index) |  MariaDB roles information.  |
|  [Information Schema APPLICABLE\_ROLES Table](../information-schema-applicable_roles-table/index) |  Roles available to be used.  |
|  [Information Schema ENABLED\_ROLES Table](../information-schema-enabled_roles-table/index) |  Enabled roles for the current session.  |
|  [SecuRich](../securich/index) |  Library of security-related stored procedures.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/roles/>

mariadb Command-Line Client
===========================

    **mariadb** is a simple SQL shell (with GNU readline capabilities).

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb` is a symlink to `mysql`, the command-line client. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb` is the name of the command-line client, with `mysql` a symlink .

  About the mariadb Command-Line Client
-------------------------------------

 **mariadb** supports interactive and non-interactive use. When used interactively, query results are presented in an ASCII-table format. When used non-interactively (for example, as a filter), the result is presented in tab-separated format. The output format can be changed using command options.

 If you have problems due to insufficient memory for large result sets, use the `--quick` option. This forces mariadb to retrieve results from the server a row at a time rather than retrieving the entire result set and buffering it in memory before displaying it. This is done by returning the result set using the `mysql_use_result()` C API function in the client/server library rather than `mysql_store_result()`.

 Using mariadb is very easy. Invoke it from the prompt of your command interpreter as follows:

 
```
mariadb db_name

```

Or:

 
```
mariadb --user=user_name --password=your_password db_name

```

Then type an SQL statement, end it with “;”, \g, or \G and press Enter.

 Typing Control-C causes mariadb to attempt to kill the current statement. If this cannot be done, or Control-C is typed again before the statement is killed, mariadb exits.

 You can execute SQL statements in a script file (batch file) like this:

 
```
mariadb db_name < script.sql > output.tab

```

Using mariadb
-------------

 The command to use `mariadb` and the general syntax is:

 
```
mariadb <options>

```

### Options

 `mariadb` supports the following options:

 


| Option | Description |
| --- | --- |
| `-?`, `--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. This option is on by default, which enables database, table, and column name completion. Use `--disable-auto-rehash`, `--no-auto-rehash` or `skip-auto-rehash` to disable rehashing. That causes mariadb to start faster, but you must issue the rehash command if you want to use name completion. To complete a name, enter the first part and press Tab. If the name is unambiguous, mariadb completes it. Otherwise, you can press Tab again to see the possible names that begin with what you have typed so far. Completion does not occur if there is no default database. |
| `-A`, `--no-auto-rehash` | No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mariadb 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` | Print results using tab as the column separator, with each row on a new line. With this option, mariadb does not use the history file. Batch mode results in nontabular output format and escaping of special characters. Escaping may be disabled by using raw mode; see the description for the `--raw` option. (Enables `--silent`.) |
| `--binary-mode` | By default, ASCII '\0' is disallowed and '\r\n' is translated to '\n'. This switch turns off both features, and also turns off parsing of all client commands except \C and DELIMITER, in non-interactive mode (for input piped to mariadb or loaded using the 'source' command). This is necessary when processing output from [mariadb-binlog](../mariadb-binlog/index) that may contain blobs. |
| `--character-sets-dir=name` | Directory for [character set](../data-types-character-sets-and-collations/index) files. |
| `--column-names` | Write column names in results. (Defaults to on; use `--skip-column-names` to disable.) |
| `--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` | Compress all information sent between the client and the server if both support compression. |
| `--connect-expired-password` | Notify the server that this client is prepared to handle [expired password sandbox mode](../user-password-expiry/index) even if `--batch` was specified. From [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/). |
| `--connect-timeout=num` | Number of seconds before connection timeout. Defaults to zero. |
| `-D`, `--database=name` | Database to use. |
| `-# [options]`, `--debug[=options]` | On debugging builds, write a debugging log. A typical debug\_options string is `d:t:o,file_name`. The default is `d:t:o,/tmp/mysql.trace`. |
| `--debug-check` | Check memory and open file usage at exit. |
| `-T`, `--debug-info` | Print some debug info at exit. |
| `--default-auth=plugin` | Default authentication client-side plugin to use. |
| `--default-character-set=name` | Set the default [character set](../data-types-character-sets-and-collations/index). A common issue that can occur when the operating system uses utf8 or another multibyte character set is that output from the mariadb client is formatted incorrectly, due to the fact that the MariaDB client uses the latin1 character set by default. You can usually fix such issues by using this option to force the client to use the system character set instead. If set to `auto` the character set is taken from the client environment (`LC_CTYPE` on Unix). |
| `--defaults-extra-file=file` | Read this file after the global files are read. Must be given as the first option. |
| `--defaults-file=file` | Only read default options from the given *file*. Must be given as the first option. |
| `--defaults-group-suffix=suffix` | In addition to the given groups, also read groups with this suffix. |
| `--delimiter=name` | Delimiter to be used. The default is the semicolon character (“;”). |
| `--enable-cleartext-plugin` | Obsolete option. Exists only for MySQL compatibility. From [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10336-release-notes/). |
| `-e`, `--execute=name` | Execute statement and quit. Disables `--force` and history file. The default output format is like that produced with `--batch`. |
| `-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. |
| `-U`, `--i-am-a-dummy` | Synonym for option `--safe-updates`, `-U`. |
| `-i`, `--ignore-spaces` | Ignore space after function names. Allows one to have spaces (including tab characters and new line characters) between function name and '('. The drawback is that this causes built in functions to become reserved words. |
| `--init-command=str` | SQL Command to execute when connecting to the 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.) |
| `--local-infile` | Enable or disable LOCAL capability for [LOAD DATA INFILE](../load-data-infile/index). With no value, the option enables LOCAL. The option may be given as`--local-infile=0` or `--local-infile=1` to explicitly disable or enable LOCAL. Enabling LOCAL has no effect if the server does not also support it. |
| `--max-allowed-packet=num` | The maximum packet length to send to or receive from server. The default is 16MB, the maximum 1GB. |
| `--max-join-size=num` | Automatic limit for rows in a join when using `--safe-updates`. Default is 1000000. |
| `-G`, `--named-commands` | Enable named commands. Named commands mean mariadb's internal commands (see below) . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Long-format commands are allowed, not just short-format commands. For example, `quit` and `\q` are both recognized. Disable with `--disable-named-commands`. This option is disabled by default. |
| `--net-buffer-length=num` | The buffer size for TCP/IP and socket communication. Default is 16KB. |
| `-b`, `--no-beep` | Turn off beep on error. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first option. |
| `-o`, `--one-database` | Ignore statements except those those that occur while the default database is the one named on the command line. This filtering is limited, and based only on [USE](../use/index) statements. This is useful for skipping updates to other databases in the binary log. |
| `--pager[=name]` | Pager to use to display results (Unix only). 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 you use the short option form (-p), you cannot have a space between the option and the password. If you omit the password value following the `--password` or `-p` option on the command line, mariadb prompts for one. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `--plugin-dir=name` | Directory for client-side plugins. |
| `-P`, `--port=num` | 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). |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first option. |
| `--progress-reports` | Get [progress reports](../progress-reporting/index) for long running commands (such as [ALTER TABLE](../alter-table/index)). (Defaults to on; use `--skip-progress-reports` to disable.) |
| `--prompt=name` | Set the mariadb prompt to this value. See [prompt command](#prompt-command) for options. |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `-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` | For tabular output, the “boxing” around columns enables one column value to be distinguished from another. For nontabular output (such as is produced in batch mode or when the `--batch` or `--silent` option is given), special characters are escaped in the output so they can be identified easily. Newline, tab, NUL, and backslash are written as `\n`, `\t`, `\0`, and . The `--raw` option disables this character escaping. |
| `--reconnect` | Reconnect if the connection is lost. This option is enabled by default. Disable with `--disable-reconnect` or `skip-reconnect`. |
| `-U`, `--safe-updates` | Allow only those [UPDATE](../update/index) and [DELETE](../delete/index) statements that specify which rows to modify by using key values. If you have set this option in an option file, you can override it by using `--safe-updates` on the command line. See [using the --safe-updates option](#using-the-safe-updates-option) for more. |
| `--secure-auth` | Refuse client connecting to server if it uses old (pre-MySQL4.1.1) protocol. Defaults to false (unlike MySQL since 5,6, which defaults to true). |
| `--select-limit=num` | Automatic limit for SELECT when using --safe-updates. Default 1000. |
| `--server-arg=name` | Send embedded server this as a parameter. |
| `--shared-memory-base-name=name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the --shared-memory option). Case-sensitive. |
| `--show-warnings` | Show warnings after every statement. Applies to interactive and batch mode. |
| `--sigint-ignore` | Ignore SIGINT signals (usually CTRL-C). |
| `-s`, `--silent` | Be more silent. This option can be given multiple times to produce less and less output. This option results in nontabular output format and escaping of special characters. Escaping may be disabled by using raw mode; see the description for the `--raw` option. |
| `-L`, `--skip-auto-rehash` | Disable automatic rehashing. See `--auto-rehash`. |
| `-N`, `--skip-column-names` | Don't write column names in results. See `--column-names`. |
| `-L`, `--skip-comments` | Discard comments. Set by default, see `--comments` to enable. |
| `-L`, `--skip-line-numbers` | Don't write line number for errors. See `--line-numbers`. |
| `-L`, `--skip-progress-reports` | Disables getting [progress reports](../progress-reporting/index) for long running commands. See `--progress-reports`. |
| `-L`, `--skip-reconnect` | Don't reconnect if the connection is lost. See `--reconnect`. |
| `-S`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. The `--ssl` option does not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. Set by default from [MariaDB 10.10](../what-is-mariadb-1010/index). |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `-t`, `--table` | Display output in table format. This is the default for interactive use, but can be used to produce table output in batch mode. |
| `--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. |
| `--tls-version=name` | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. This option was added in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `-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. Use the `\G` delimiter to apply to a particular statement if this option is not enabled. |
| `-w`, `--wait` | If the connection cannot be established, wait and retry instead of aborting. |
| `-X`, `--xml` | Produce XML output. See the [mariadb-dump --xml option](../mariadb-dump/index#null-null-and-empty-values-in-xml) for more. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
`mariadb` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 #### Option Groups

 `mariadb` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysql]` |  Options read by `mysql`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-client]` | Options read by `mariadb`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
How to Specify Which Protocol to Use When Connecting to the Server
------------------------------------------------------------------

 You can force which protocol to be used to connect to the `mariadbd` server by giving the `protocol` option one of the following values: `tcp`, `socket`, `pipe` or `memory`.

 If `protocol` is not specified, before [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), command line connection properties that do not force protocol are ignored.

 From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), a connection property specified via the command line (e.g. `--port=3306`) will force its type. The protocol that matches the respective connection property is used, e.g. a TCP/IP connection is created when `--port` is specified. 

 If multiple or no connection properties are specified via the command-line, then the following happens:

 ### Linux/Unix

 * If `hostname` is not specified or `hostname` is `localhost`, then Unix sockets are used.
* In other cases (`hostname` is given and it's not `localhost`) then a TCP/IP connection through the `port` option is used.

 Note that `localhost` is a special value. Using 127.0.0.1 is not the same thing. The latter will connect to the mariadbd server through TCP/IP.

 ### Windows

 * If `shared-memory-base-name` is specified and `hostname` is not specified or `hostname` is `localhost`, then the connection will happen through shared memory.
* If `shared-memory-base-name` is not specified and `hostname` is not specified or `hostname` is `localhost`, then the connection will happen through windows named pipes.
* Named pipes will also be used if the `libmysql` / `libmariadb` client library detects that the client doesn't support TCP/IP.
* In other cases then a TCP/IP connection through the `port` option is used.

 How to Test Which Protocol is Used
----------------------------------

 The `status` command shows you information about which protocol is used:

 
```
shell> mariadb test

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.2.2-MariaDB-valgrind-max-debug Source distribution

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [test]> status;
--------------
mysql  Ver 15.1 Distrib 10.0.25-MariaDB, for Linux (x86_64) using readline 5.2

Connection id:          10
Current database:       test
Current user:           monty@localhost
...
Connection:             Localhost via UNIX socket
...
UNIX socket:            /tmp/mysql-dbug.sock

```

mariadb Commands
----------------

 There are also a number of commands that can be run inside the client. Note that all text commands must be first on line and end with ';'

 


| Command | Description |
| --- | --- |
| `?`, `\?` | Synonym for `help'. |
| `clear`, `\c` | Clear the current input statement. |
| `connect`, `\r` | Reconnect to the server. Optional arguments are db and host. |
| `delimiter`, `\d` | Set statement delimiter. |
| `edit`, `\e` | Edit command with $EDITOR. |
| `ego`, `\G` | Send command to mariadb server, display result vertically. |
| `exit`, `\q` | Exit mariadb. Same as quit. |
| `go`, `\g` | Send command to mariadb server. |
| `help`, `\h` | Display this help. |
| `nopager`, `\n` | Disable pager, print to stdout. |
| `notee`, `\t` | Don't write into outfile. |
| `pager`, `\P` | Set PAGER [to\_pager]. Print the query results via PAGER. |
| `print`, `\p` | Print current command. |
| `prompt`, `\R` | Change your mariadb prompt. See [prompt command](#prompt-command) for options. |
| `quit`, `\q` | Quit mariadb. |
| `rehash`, `\#`  | Rebuild completion hash. |
| `source`, `\.` | Execute an SQL script file. Takes a file name as an argument. |
| `status`, `\s` | Get status information from the server. |
| `system`, `\!` | Execute a system shell command. Only works in Unix-like systems. |
| `tee`, `\T` | Set outfile [to\_outfile]. Append everything into given outfile. |
| `use`, `\u` | Use another database. Takes database name as argument. |
| `charset`, `\C` | Switch to another charset. Might be needed for processing binlog with multi-byte charsets. |
| `warnings`, `\W` | Show warnings after every statement. |
| `nowarning`, `\w` | Don't show warnings after every statement. |

 
The mysql\_history File
-----------------------

 On Unix, the mariadb client writes a record of executed statements to a history file. By default, this file is named `.mysql_history` and is created in your home directory. To specify a different file, set the value of the MYSQL\_HISTFILE environment variable.

 The .mysql\_history file should be protected with a restrictive access mode because sensitive information might be written to it, such as the text of SQL statements that contain passwords.

 If you do not want to maintain a history file, first remove .mysql\_history if it exists, and then use either of the following techniques:

 * Set the MYSQL\_HISTFILE variable to /dev/null. To cause this setting to take effect each time you log in, put the setting in one of your shell's startup files.
* Create .mysql\_history as a symbolic link to /dev/null:

 
```
shell> ln -s /dev/null $HOME/.mysql_history

```

You need do this only once.

 prompt Command
--------------

 The prompt command reconfigures the default prompt `\N [\d]>`. The string for defining the prompt can contain the following special sequences.

 


| Option | Description |
| --- | --- |
| `\c` | A counter that increments for each statement you issue. |
| `\D` | The full current date. |
| `\d` | The default database. |
| `\h` | The server host. |
| `\l` | The current delimiter. |
| `\m` | Minutes of the current time. |
| `\n` | A newline character. |
| `\O` | The current month in three-letter format (Jan, Feb, ...). |
| `\o` | The current month in numeric format. |
| `\P` | am/pm. |
| `\p` | The current TCP/IP port or socket file. |
| `\R` | The current time, in 24-hour military time (0–23). |
| `\r` | The current time, standard 12-hour time (1–12). |
| `\S` | Semicolon. |
| `\s` | Seconds of the current time. |
| `\t` | A tab character. |
| `\U` | Your full user\_name@host\_name account name. |
| `\u` | Your user name. |
| `\v` | The server version. |
| `\w` | The current day of the week in three-letter format (Mon, Tue, ...). |
| `\Y` | The current year, four digits. |
| `\y` | The current year, two digits. |
| `\_` | A space. |
| `\` | A space (a space follows the backslash). |
| `\'` | Single quote. |
| `\"` | Double quote. |
| `\ \` | A literal “\” backslash character. |
| `\x` | x, for any “x” not listed above. |

 
mariadb Tips
------------

 This section describes some techniques that can help you use `**mariadb**` more effectively.

 ### Displaying Query Results Vertically

 Some query results are much more readable when displayed vertically, instead of in the usual horizontal table format. Queries can be displayed vertically by terminating the query with \G instead of a semicolon. For example, longer text values that include newlines often are much easier to read with vertical output:

 
```
mariadb> SELECT * FROM mails WHERE LENGTH(txt) < 300 LIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
    date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@no.spam.com
  mail_to: "Thimble Smith" <tim@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:
Thimble> Hi.  I think this is a good idea.  Is anyone familiar
Thimble> with UTF-8 or Unicode? Otherwise, I´ll put this on my
Thimble> TODO list and see what happens.
Yes, please do that.
Regards,
Monty
    file: inbox-jani-1
    hash: 190402944
1 row in set (0.09 sec)

```

### Using the --safe-updates Option

 For beginners, a useful startup option is `--safe-updates` (or `--i-am-a-dummy`, which has the same effect). It is helpful for cases when you might have issued a `DELETE FROM tbl_name` statement but forgotten the `WHERE` clause. Normally, such a statement deletes all rows from the table. With `--safe-updates`, you can delete rows only by specifying the key values that identify them. This helps prevent accidents.

 When you use the `--safe-updates` option, mariadb issues the following statement when it connects to the MariaDB server:

 
```
SET sql_safe_updates=1, sql_select_limit=1000, sql_max_join_size=1000000;

```

The [SET](../set/index) statement has the following effects:

 * You are not allowed to execute an [UPDATE](../update/index) or [DELETE](../delete/index) statement unless you specify a key constraint in the WHERE clause or provide a LIMIT clause (or both). For example:

 
```
UPDATE tbl_name SET not_key_column=val WHERE key_column=val;
UPDATE tbl_name SET not_key_column=val LIMIT 1;

```

* The server limits all large`SELECT` results to 1,000 rows unless the statement includes a `LIMIT` clause.
* The server aborts multiple-table `SELECT` statements that probably need to examine more than 1,000,000 row combinations.

 To specify limits different from 1,000 and 1,000,000, you can override the defaults by using the `--select_limit` and `--max_join_size` options:

 
```
mariadb --safe-updates --select_limit=500 --max_join_size=10000

```

### Disabling mariadb Auto-Reconnect

 If the mariadb client loses its connection to the server while sending a statement, it immediately and automatically tries to reconnect once to the server and send the statement again. However, even if mariadb succeeds in reconnecting, your first connection has ended and all your previous session objects and settings are lost: temporary tables, the autocommit mode, and user-defined and session variables. Also, any current transaction rolls back. This behavior may be dangerous for you, as in the following example where the server was shut down and restarted between the first and second statements without you knowing it:

 
```
mariadb> SET @a=1;
Query OK, 0 rows affected (0.05 sec)
mariadb> INSERT INTO t VALUES(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test
Query OK, 1 row affected (1.30 sec)
mariadb> SELECT * FROM t;
+------+
| a    |
+------+
| NULL |
+------+

```

The @a user variable has been lost with the connection, and after the reconnection it is undefined. If it is important to have mariadb terminate with an error if the connection has been lost, you can start the mariadb client with the `--skip-reconnect` option.

 See Also
--------

 * [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index)
* [Readline commands and configuration](https://docs.freebsd.org/info/readline/readline.pdf)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-command-line-client/>

mysql.server
============

    The `[mysql.server](index)` startup script is in MariaDB distributions on Linux and Unix. It is a wrapper that works as a standard [sysVinit](../sysvinit/index) script. However, it can be used independently of [sysVinit](../sysvinit/index) as a regular `sh` script. The script starts the `[mysqld](../mysqld-options/index)` server process by first changing its current working directory to the MariaDB install directory and then starting `[mysqld\_safe](../mysqld_safe/index)`. The script requires the standard [sysVinit](../sysvinit/index) arguments, such as `start`, `stop`, `restart`, and `status`. For example:

 
```
mysql.server start
mysql.server restart
mysql.server stop
mysql.server status

```

It can be used on systems such as Linux, Solaris, and Mac OS X.

 The `mysql.server` script starts `[mysqld](../mysqld-options/index)` by first changing to the MariaDB install directory and then calling `[mysqld\_safe](https://mariadb.com/mysqld_safe)`.

 Using mysql.server
------------------

 The command to use `mysql.server` and the general syntax is:

 
```
mysql.server [ start | stop | restart | status ] <options> <mysqld_options>

```

### Options

 If an unknown option is provided to `mysqld_safe` on the command-line, then it is passed to `mysqld_safe`.

 `mysql.server` supports the following options:

 


| Option | Description |
| --- | --- |
| `--basedir=path` | The path to the MariaDB installation directory. |
| `--datadir=path` | The path to the MariaDB data directory. |
| `--pid-file=file_name` | The path name of the file in which the server should write its process ID. If not provided, the default, `host_name.pid` is used. |
| `--service-startup-timeout=file_name` | How long in seconds to wait for confirmation of server startup. If the server does not start within this time, *mysql.server* exits with an error. The default value is 900. A value of 0 means not to wait at all for startup. Negative values mean to wait forever (no timeout). |
| `--use-mysqld_safe` | Use [mysqld\_safe](../mysqld_safe/index) to start the server. This is the default. |
| `--use-manager` | Use Instance Manager to start the server. |
| `--user=user_name` | The login user name to use for running `mysqld`. |

 
### Option Files

 In addition to reading options from the command-line, `mysql.server` can also read options from [option files](../configuring-mariadb-with-option-files/index).

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--defaults-file=#`  | Only read default options from the given file #. |
| `--defaults-extra-file=#`  | Read this file after the global files are read. |

 
#### Option Groups

 `mysql.server` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysql.server]` |  Options read by `mysql.server`, which includes both MariaDB Server and MySQL Server. |

 
`mysql.server` also reads options from the following server [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[server]` | Options read by MariaDB Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-5.5]`. |
| `[mariadb]` | Options read by MariaDB Server. |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[galera]` |  Options read by a galera-capable MariaDB Server. Available on systems compiled with Galera support. |

 
### Customizing mysql.server

 If you have installed MariaDB to a non-standard location, then you may need to edit the `mysql.server` script to get it to work right.

 If you do not want to edit the `mysql.server` script itself, then `mysql.server` also sources a few other `sh` scripts. These files can be used to set any variables that might be needed to make the script work in your specific environment. The files are:

 * /etc/default/mysql
* /etc/sysconfig/mysql
* /etc/conf.d/mysql

 Installed Locations
-------------------

 `mysql.server` can be found in the `support-files` directory under your MariaDB installation directory or in a MariaDB source distribution.

 ### Installed SysVinit Locations

 On systems that use [sysVinit](../sysvinit/index), `mysql.server` may also be installed in other locations and with other names.

 If you installed MariaDB on Linux using [RPMs](../rpm/index), then the `mysql.server` script will be installed into the `/etc/init.d` directory with the name `mysql`. You need not install it manually. 

 #### Manually Installing with SysVinit

 If you install MariaDB from [source](../compiling-mariadb-from-source/index) or from a [binary tarball](../installing-mariadb-binary-tarballs/index) that does not install `[mysql.server](index)` automatically, and if you are on a system that uses [sysVinit](../sysvinit/index), then you can manually install `mysql.server` with [sysVinit](../sysvinit/index). This is usually done by copying it to `/etc/init.d/` and then creating specially named symlinks in the appropriate `/etc/rcX.d/` directories (where 'X' is a number between 0 and 6).

 
In the examples below we will follow the historical convention of renaming the `mysql.server` script to '`mysql`' when we copy it to `/etc/init.d/`.

 
The first step for most Linux distributions is to copy the `mysql.server` script to `/etc/init.d/` and make it executable:

 
```
cd /path/to/your/mariadb-version/support-files/
cp mysql.server /etc/init.d/mysql
chmod +x /etc/init.d/mysql

```

Now all that is needed is to create the specially-named symlinks. On both RPM and Debian-based Linux distributions there are tools which do this for you. Consult your distribution's documentation if neither of these work for you and follow their instructions for generating the symlinks or creating them manually.

 On RPM-based distributions (like Fedora and CentOS), you use `chkconfig`:

 
```
chkconfig --add mysql
chkconfig --level 345 mysql on

```

On Debian-based distributions you use `update-rc.d`:

 
```
update-rc.d mysql defaults

```

On FreeBSD, the location for startup scripts is `/usr/local/etc/rc.d/` and when you copy the `mysql.server` script there you should rename it so that it matches the `*.sh` pattern, like so:

 
```
cd /path/to/your/mariadb/support-files/
cp mysql.server /usr/local/etc/rc.d/mysql.server.sh

```

As stated above, consult your distribution's documentation for more information on starting services like MariaDB at system startup.

 See [mysqld startup options](../mysqld-startup-options/index) for information on configuration options for `mysqld`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlserver/>

mysqld\_safe
============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd-safe` is a symlink to `mysqld_safe`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd-safe` is the name of the server, with `mysqld_safe` a symlink .

 
   
  
 The `mysqld_safe` startup script is in MariaDB distributions on Linux and Unix. It is a wrapper that starts `mysqld` with some extra safety features. For example, if `mysqld_safe` notices that `mysqld` has crashed, then `mysqld_safe` will automatically restart `mysqld`.

 `mysqld_safe` is the recommended way to start `mysqld` on Linux and Unix distributions that do not support `[systemd](../systemd/index)`. Additionally, the `[mysql.server](../mysqlserver/index)` init script used by `[sysVinit](../sysvinit/index)` starts `mysqld` with `mysqld_safe` by default.   
  


 Using mysqld\_safe
------------------

 The command to use `mysqld_safe` and the general syntax is:

 
```
mysqld_safe [ --no-defaults | --defaults-file | --defaults-extra-file | --defaults-group-suffix | --print-defaults ] <options> <mysqld_options>

```

### Options

 Many of the options supported by `mysqld_safe` are identical to options supported by `[mysqld](../mysqld-options/index)`. If an unknown option is provided to `mysqld_safe` on the command-line, then it is passed to `mysqld`.

 `mysqld_safe` supports the following options:

 


| Option | Description |
| --- | --- |
| `--help` | Display a help message and exit. |
| `--autoclose` | (NetWare only) On NetWare, `mysqld_safe` provides a screen presence. When you unload (shut down) the `mysqld_safe` NLM, the screen does not by default go away. Instead, it prompts for user input: `NLM has terminated; Press any key to close the screen`. If you want NetWare to close the screen automatically instead, use the `--autoclose` option to mysqld\_safe. |
| `--basedir=path` | The path to the MariaDB installation directory. |
| `--core-file-size=size` | The size of the core file that mysqld should be able to create. The option value is passed to ulimit -c. |
| `--crash-script=file` | Script to call in the event of mysqld crashing. |
| `--datadir=path` | The path to the data directory. |
| `--defaults-extra-file=path` | The name of an option file to be read in addition to the usual option files. This must be the first option on the command line if it is used. If the file does not exist or is otherwise inaccessible, the server will exit with an error. |
| `--defaults-file=file_name` | The name of an option file to be read instead of the usual option files. This must be the first option on the command line if it is used. |
| `--defaults-group-suffix=#`  | In addition to the default option groups, also read option groups with this suffix. |
| `--flush-caches` | Flush and purge buffers/caches before starting the server. |
| `--ledir=path` | If mysqld\_safe cannot find the server, use this option to indicate the path name to the directory where the server is located. |
| `--log-error=file_name` | Write the error log to the given file. |
| `--malloc-lib=lib` | Preload shared library *lib* if available. See [debugging MariaDB](../debugging-a-running-server-on-linux/index) for an example. |
| `--mysqld=prog_nam` | The name of the server program (in the ledir directory) that you want to start. This option is needed if you use the MariaDB binary distribution but have the data directory outside of the binary distribution. If mysqld\_safe cannot find the server, use the `--ledir` option to indicate the path name to the directory where the server is located. |
| `--mysqld-version=suffix` | This option is similar to the `--mysqld` option, but you specify only the suffix for the server program name. The basename is assumed to be mysqld. For example, if you use`--mysqld-version=debug`, mysqld\_safe starts the mysqld-debug program in the ledir directory. If the argument to `--mysqld-version` is empty, mysqld\_safe uses mysqld in the ledir directory. |
| `--nice=priority` | Use the nice program to set the server´s scheduling priority to the given value. |
| `--no-defaults` | Do not read any option files. This must be the first option on the command line if it is used. |
| `--no-watch`, `--nowatch`, `--no-auto-restart` | Exit after starting mysqld. |
| `--numa-interleave` | Run mysqld with its memory interleaved on all NUMA nodes. |
| `--open-files-limit=count` | The number of files that mysqld should be able to open. The option value is passed to ulimit -n. Note that you need to start mysqld\_safe as root for this to work properly. |
| `--pid-file=file_name` | The path name of the process ID file. |
| `--plugin-dir=dir_name` | Directory for client-side plugins. |
| `--port=port_num` | The port number that the server should use when listening for TCP/IP connections. The port number must be 1024 or higher unless the server is started by the root system user. |
| `--print-defaults` | Print the program argument list and exit. |
| `--skip-kill-mysqld` | Do not try to kill stray mysqld processes at startup. This option works only on Linux. |
| `--socket=path` | The Unix socket file that the server should use when listening for local connections. |
| `--syslog`, `--skip-syslog` | `--syslog` causes error messages to be sent to syslog on systems that support the logger program. `--skip-syslog` suppresses the use of syslog; messages are written to an error log file. |
| `--syslog-tag=tag` | For logging to syslog, messages from `mysqld_safe` and mysqld are written with a tag of mysqld\_safe and mysqld, respectively. To specify a suffix for the tag, use `--syslog-tag=tag`, which modifies the tags to be `mysqld_safe-tag` and `mysqld-tag`. |
| `--timezone=timezone` | Set the TZ time zone [environment variable](../mariadb-environment-variables/index) to the given option value. Consult your operating system documentation for legal time zone specification formats. Also see [Time Zones](../time-zones/index). |
| `--user={user_name or user_id}` | Run the mysqld server as the user having the name user\_name or the numeric user ID user\_id. (“User” in this context refers to a system login account, not a MariaDB user listed in the grant tables.) |

 
### Option Files

 In addition to reading options from the command-line, `mysqld_safe` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mysqld_safe` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the **first argument** on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
#### Option Groups

 `mysqld_safe` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqld_safe]` |  Options read by `mysqld_safe`, which includes both MariaDB Server and MySQL Server. |
| `[safe_mysqld]` |  Options read by `mysqld_safe`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb_safe]` | Options read by `mysqld_safe` from MariaDB Server. |
| `[mariadb-safe]` | Options read by `mysqld_safe` from MariaDB Server. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |

 
The `[safe_mysqld]` option group is primarily supported for backward compatibility. You should rename such option groups to `[mysqld_safe]` in MariaDB installations to prevent breakage in the future if this compatibility is removed.

 `mysqld_safe` also reads options from the following server [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[server]` | Options read by MariaDB Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-5.5]`. |
| `[mariadb]` | Options read by MariaDB Server. |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[galera]` |  Options read by a galera-capable MariaDB Server. Available on systems compiled with Galera support. |

 
For example, if you specify the `[log\_error](../server-system-variables/index#log_error)` option in a server option group in an option file, like this: 

 
```
[mariadb]
log_error=error.log

```

Then `mysqld_safe` will also use this value for its own `--log-error` option:

 ### Configuring the Open Files Limit

 When using `mysqld_safe`, the system's open files limit can be changed by providing the `--open-files-limit` option either on the command-line or in an option file. For example:

 
```
[mysqld_safe]
open_files_limit=4294967295

```

The option value is passed to `ulimit -n`. Note that you need to start `mysqld_safe` as root for this to work properly. However, you can't currently set this to `unlimited`. See [MDEV-18410](https://jira.mariadb.org/browse/MDEV-18410) about that.

 When `mysqld_safe` starts `mysqld`, it also uses this option to set the value of the `[open\_files\_limit](../server-system-variables/index#open_files_limit)` system variable for `mysqld`.

 ### Configuring the Core File Size

 When using `mysqld_safe`, if you would like to [enable core dumps](../enabling-core-dumps/index), the system's core file size limit can be changed by providing the `--core-file-size` option either on the command-line or in an option file. For example:

 
```
[mysqld_safe]
core_file_size=unlimited

```

The option value is passed to `ulimit -c`. Note that you need to start `mysqld_safe` as root for this to work properly.

 ### Configuring MariaDB to Write the Error Log to Syslog

 When using `mysqld_safe`, if you would like to redirect the error log to the [syslog](https://linux.die.net/man/8/rsyslogd), then that can easily be done by using the `--syslog` option. `mysqld_safe` redirects two types of log messages to the syslog--its own log messages, and log messages for `mysqld`.

 * `mysqld_safe` configures its own log messages to go to the `daemon` syslog facility. The log level for these messages is either `notice` or `error`, depending on the specific type of log message. The default tag is `mysqld_safe`.

 * `mysqld_safe` also configures the log messages for `mysqld` to go to the `daemon` syslog facility. The log level for these messages is `error`. The default tag is `mysqld`.

 Sometimes it can be helpful to add a suffix to the syslog tag, such as if you are running multiple instances of MariaDB on the same host. To add a suffix to each syslog tag, use the `--syslog-tag` option.

 Specifying mysqld
-----------------

 By default, `mysqld_safe` tries to start an executable named `mysqld`.

 You can also specify another executable for `mysqld_safe` to start instead of `mysqld` by providing the `--mysqld` or `--mysqld-version` options either on the command-line or in an option file.

 By default, it will look for `mysqld` in the following locations in the following order:

 * `$BASEDIR/libexec/mysqld`
* `$BASEDIR/sbin/mysqld`
* `$BASEDIR/bin/mysqld`
* `$PWD/bin/mysqld`
* `$PWD/libexec/mysqld`
* `$PWD/sbin/mysqld`
* `@libexecdir@/mysql`

 Where `$BASEDIR` is set by the `--basedir` option, `$PWD` is the current working directory where `mysqld_safe` was invoked, and `@libexecdir@` is set at compile-time by the `INSTALL_BINDIR` option for `[cmake](../generic-build-instructions/index#using-cmake)`.

 You can also specify where the executable is located by providing the `--ledir` option either on the command-line or in an option file.

 Specifying datadir
------------------

 By default, `mysqld_safe` will look for the `datadir` in the following locations in the following order:

 * `$BASEDIR/data/mysql`
* `$BASEDIR/data`
* `$BASEDIR/var/mysql`
* `$BASEDIR/var`
* `@localstatedir@`

 Where `$BASEDIR` is set by the `--basedir` option, and `@localstatedir@` is set at compile-time by the `INSTALL_MYSQLDATADIR` option for `[cmake](../generic-build-instructions/index#using-cmake)`.

 You can also specify where the `datadir` is located by providing the `--datadir` option either on the command-line or in an option file.

 Logging
-------

 When you use `mysqld_safe` to start `mysqld`, `mysqld_safe` logs to the same destination as `mysqld`.

 `mysqld_safe` has several log-related options:

 * `--syslog`: Write error messages to syslog on systems that support the logger program.
* `--skip-syslog`: Do not write error messages to syslog. Messages are written to the default error log file (host\_name.err in the data directory), or to a named file if the `--log-error` option is given.
* `--log-error=file_name`: Write error messages to the named error file.

 If none of these options is provided, then the default is `--skip-syslog`.

 If `--syslog` and `--log-error` are both provided, then a warning is issued and `--log-error` takes precedence.

 `mysqld_safe` also writes notices to `stdout` and errors to `stderr`.

 Editing mysqld\_safe
--------------------

 `mysqld_safe` is a `sh` script, so if you need to change its behavior, then it can easily be edited. However, you should not normally edit the script. A lot of behavior can be changed by providing options either on the command-line or in an option file.

 If you do edit `mysqld_safe`, then you should be aware of the fact that a package upgrade can overwrite your changes. If you would like to preserve your changes, be sure to have a backup.

 NetWare
-------

 On NetWare, mysqld\_safe is a NetWare Loadable Module (NLM) that is ported from the original Unix shell script. It starts the server as follows:

 1. Runs a number of system and option checks.
2. Runs a check on MyISAM tables.
3. Provides a screen presence for the MariaDB server.
4. Starts mysqld, monitors it, and restarts it if it terminates in error.
5. Sends error messages from mysqld to the host\_name.err file in the data directory.
6. Sends mysqld\_safe screen output to the host\_name.safe file in the data directory.

 See Also
--------

 * [How to increase max number of open files on Linux](http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files). This can be used to solve issues like this warning from mysqld: `Changed limits: max_open_files: 1024 (requested 5000)"`
* [mysqld Options](../mysqld-options/index)
* [systemd](../systemd/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqld_safe/>

mysqladmin
==========

    mysqladmin is an administration program for the mysqld daemon.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-admin` is a symlink to `mysqladmin`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-admin` is the name of the script, with `mysqladmin` a symlink .

 
See [mariadb-admin](../mariadb-admin/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqladmin/>

Switching Between Different Installed MariaDB Versions
======================================================

     This article is about managing many different installed MariaDB versions and running them one at a time. This is useful when doing benchmarking, testing, or for when developing different MariaDB versions.

 This is most easily done using the tar files from [mariadb.org/download/](https://mariadb.org/download/).

 Stopping a pre-installed MySQL/MariaDB from interfering with your tests
-----------------------------------------------------------------------

 If MySQL/MariaDB is already installed and running, you have two options:

 1. Use test MariaDB servers with a different port & socket.
	* In this case you are probably best off creating a specific section for MariaDB in your `~/.my.cnf` file.
2. Stop mysqld with `/etc/rc.d/mysql stop` or `mariadb-admin shutdown`.

 Note that you don't have to uninstall or otherwise remove MySQL!

 How to create a binary distribution (tar file)
----------------------------------------------

 Here is a short description of how to generate a tar file from a source distribution. If you have [downloaded](http://downloads.askmonty.org/mariadb/) a binary tar file, you can skip this section.

 The steps to create a binary tar file are:

 * Decide where to put the source. A good place is under `/usr/local/src/mariadb-5.#`.
* [Get the source](../source-getting-the-mariadb-source-code/index)
* [Compile the source](../compiling-mariadb-from-source/index)
* [Create the binary tar ball](../creating-the-mariadb-binary-tarball/index).

 You will then be left with a tar file named something like: `mariadb-11.0.1-MariaDB-linux-x86_64.tar.gz`

 Creating a directory structure for the different installations
--------------------------------------------------------------

 Install the binary tar files under `/usr/local/` with the following directory names (one for each MariaDB version you want to use), for example:

 * `mariadb-10.5`
* `mariadb-10.6`
* `mariadb-10.11`
* `mariadb-11.0`
* `mariadb-11.1`

 The above assumes you are just testing major versions of MariaDB. If you are testing specific versions, use directory names like `mariadb-11.0.1`

 With the directories in place, create a sym-link named `mariadb` which points at the `mariadb-XXX` directory you are currently testing. When you want to switch to testing a different version, just update the sym-link.

 Example:

 
```
cd /usr/local
tar xfz /tmp/mariadb-11.0.1-linux-systemd-x86_64.tar.gz
mv -vi mariadb-11.0.1-MariaDB-systemd-linux-x86_64 mariadb-11.0
ln -vs mariadb-11.0 mariadb

```

Setting up the data directory
-----------------------------

 When setting up the data directory, you have the option of either using a shared database directory or creating a unique database directory for each server version. For testing, a common directory is probably easiest. Note that you can only have one `mysqld` server running against one data directory.

 ### Setting up a common data directory

 The steps are:

 1. Create the `mysql` system user if you don't have it already! (On Linux you do it with the `useradd` command).
2. Create the directory (we call it `mariadb-data` in the example below) or add a symlink to a directory which is in some other place.
3. Create the `mysql` permission tables with [mariadb-install-db](../mariadb-install-db/index)

 
```
cd /usr/local/
mkdir mariadb-data
cd mariadb
./bin/mariadb-install-db --no-defaults --datadir=/usr/local/mariadb-data
chown -R mysql mariadb-data mariadb-data/*

```

The reason to use `--no-defaults` is to ensure that we don't inherit incorrect options from some old my.cnf.

 ### Setting up different data directories

 To create a different `data` directories for each installation:

 
```
cd mariadb
./scripts/mariadb-install-db --no-defaults
chown -R mysql mariadb-data mariadb-data/*

```

This will create a directory `data` inside the current directory.

 If you want to use another disk you should do:

 
```
cd mariadb
ln -s path-to-empty-directory-for-data data
./scripts/mariadb-install-db --no-defaults --datadir=./data
chown -R mysql mariadb-data mariadb-data/*

```

Running a MariaDB server
------------------------

 The normal steps are:

 
```
rm mariadb
ln -s mariadb-# mariadb
cd mariadb
./bin/mysqld_safe --no-defaults --datadir=/usr/local/mariadb-data &

```

Setting up a .my.cnf file for running multiple MariaDB main versions
--------------------------------------------------------------------

 If you are going to start/stop MariaDB a lot of times, you should create a `~/.my.cnf` file for the common options you are using.

 The following example shows how to use a non-standard TCP-port and socket (to not interfere with a main MySQL/MariaDB server) and how to setup different options for each main server:

 
```
[client-server]
socket=/tmp/mysql.sock
port=3306
[mysqld]
datadir=/usr/local/mariadb-data

[mariadb-11.0]
# Options for MariaDB 11.0
[mariadb-11.1]
# Options for MariaDB 11.1

```

If you create an `~/.my.cnf` file, you should start `mysqld` with `--defaults-file=~/.my.cnf` instead of `--no-defaults` in the examples above.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/switching-between-different-installed-mariadb-versions/>

Running Multiple MariaDB Server Processes
=========================================

    It is possible to run multiple MariaDB Server processes on the same server, but there are certain things that need to be kept in mind. This page will go over some of those things.

 Configuring Multiple MariaDB Server Processes
---------------------------------------------

 If multiple MariaDB Server process are running on the same server, then at minimum, you will need to ensure that the different instances do not use the same `[datadir](../server-system-variables/index#datadir)`, `[port](../server-system-variables/index#port)`, and `[socket](../server-system-variables/index#socket)`. The following example shows these options set in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[client]
# TCP port to use to connect to mysqld server
port=3306
# Socket to use to connect to mysqld server
socket=/tmp/mysql.sock
[mariadb]
# TCP port to make available for clients
port=3306
#  Socket to make available for clients
socket=/tmp/mysql.sock
# Where MariaDB should store all its data
datadir=/usr/local/mysql/data

```

The above values are the defaults. If you would like to run multiple MariaDB Server instances on the same server, then you will need to set unique values for each instance.

 There may be additional options that also need to be changed for each instance. Take a look at the full list of options for `[mysqld](../mysqld-options/index)`.

 To see the current values set for an instance, see [Checking Program Options](../configuring-mariadb-with-option-files/index#checking-program-options) for how to do so.

 To list the default values, check the end of:

 
```
mysqld --help --verbose

```

Starting Multiple MariaDB Server Processes
------------------------------------------

 There are several different methods to start or stop the MariaDB Server process. There are two primary categories that most of these methods fall into: starting the process with the help of a service manager, and starting the process manually. See [Starting and Stopping MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) for more information.

 ### Service Managers

 [sysVinit](../sysvinit/index) and [systemd](../systemd/index) are the most common Linux service managers. [launchd](../launchd/index) is used in MacOS X. [Upstart](https://en.wikipedia.org/wiki/Upstart_(software)) is a less common service manager.

 #### Systemd

 RHEL/CentOS 7 and above, Debian 8 Jessie and above, and Ubuntu 15.04 and above use [systemd](../systemd/index) by default.

 For information on how to start and stop multiple MariaDB Server processes on the same server with this service manager, see [systemd: Interacting with Multiple MariaDB Server Processes](../systemd/index#interacting-with-multiple-mariadb-server-processes).

 ### Starting the Server Process Manually

 #### mysqld

 `[mysqld](../mysqld-options/index)` is the actual MariaDB Server binary. It can be started manually on its own.

 If you want to force each instance to read only a single [option file](../configuring-mariadb-with-option-files/index), then you can use the `[--defaults-file](../mysqld-options/index#-defaults-file)` option:

 
```
mysqld --defaults-file=/etc/my_instance1.cnf

```

#### mysqld\_safe

 `[mysqld\_safe](../mysqld_safe/index)` is a wrapper that can be used to start the `[mysqld](../mysqld-options/index)` server process. The script has some built-in safeguards, such as automatically restarting the server process if it dies. See [mysqld\_safe](../mysqld_safe/index) for more information.

 If you want to force each instance to read only a single [option file](../configuring-mariadb-with-option-files/index), then you can use the `[--defaults-file](../mysqld-options/index#-defaults-file)` option:

 
```
mysqld_safe --defaults-file=/etc/my_instance1.cnf

```

#### mysqld\_multi

 `[mysqld\_multi](../mysqld_multi/index)` is a wrapper that can be used to start the `[mysqld](../mysqld-options/index)` server process if you plan to run multiple server processes on the same host. See [mysqld\_multi](../mysqld_multi/index) for more information.

 Other Options
-------------

 In some cases, there may be easier ways to run multiple MariaDB Server instances on the same server, such as:

 * Using [dbdeployer](../dbdeployer/index).
* Starting multiple [Docker](../installing-and-using-mariadb-via-docker/index) containers.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-multiple-mariadb-server-processes/>

Specifying Permissions for Schema (Data) Directories and Tables
===============================================================

    Default File Permissions
------------------------

 By default MariaDB uses the following permissions for files and directories:

 


| Object Type | Default Mode | Default Permissions |
| --- | --- | --- |
| Files | `0660` | `-rw-rw----` |
| Directories | `0700` | `drwx------` |

 
Configuring File Permissions with Environment Variables
-------------------------------------------------------

 You can configure MariaDB to use different permissions for files and directories by setting the following [environment variables](../mariadb-environment-variables/index) before you start the server:

 


| Object Type | Environment Variable |
| --- | --- |
| Files | `UMASK` |
| Directories | `UMASK_DIR` |

 
In other words, if you would run the following in a shell:

 
```
export UMASK=0640
export UMASK_DIR=0750

```


These environment variables do not set the umask. They set the default file system permissions. See [MDEV-23058](https://jira.mariadb.org/browse/MDEV-23058) for more information.

 
### Configuring File Permissions with systemd

 If your server is started by `[systemd](../systemd/index)`, then there is a specific way to configure the umask. See [Systemd: Configuring the umask](../systemd/index#configuring-the-umask) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/specifying-permissions-for-schema-data-directories-and-tables/>

mysqld\_multi
=============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd-multi` is a symlink to `mysqld_multi`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd-multi` is the name of the server, with `mysqld_multi` a symlink .

 

Before using mysqld\_multi be sure that you understand the meanings of the options that are passed to the mysqld servers and why you would want to have separate mysqld processes. Beware of the dangers of using multiple mysqld servers with the same data directory. Use separate data directories, unless you know what you are doing. Starting multiple servers with the same data directory does not give you extra performance in a threaded system.

  The `mysqld_multi` startup script is in MariaDB distributions on Linux and Unix. It is a wrapper that is designed to manage several `mysqld` processes running on the same host. In order for multiple `mysqld` processes to work on the same host, these processes must:

 * Use different Unix socket files for local connections.
* Use different TCP/IP ports for network connections.
* Use different data directories.
* Use different process ID files (specified by the `--pid-file` option) if using `[mysqld\_safe](../mysqld_safe/index)` to start `mysqld`.

 `mysqld_multi` can start or stop servers, or report their current status.

 Using mysqld\_multi
-------------------

 The command to use `mysqld_multi` and the general syntax is:

 
```
mysqld_multi [options] {start|stop|report} [GNR[,GNR] ...]

```

`start`, `stop`, and `report` indicate which operation to perform.

 You can specify which servers to perform the operation on by providing one or more `GNR` values. `GNR` refers to an option group number, and it is explained more in the [option groups](#option-groups) section below. If there is no `GNR` list, then `mysqld_multi` performs the operation for all `GNR` values found in its option files.

 Multiple `GNR` values can be specified as a comma-separated list. `GNR` values can also be specified as a range by separating the numbers by a dash. There must not be any whitespace characters in the `GNR` list.

 For example:

 This command starts a single server using option group `[mysqld17]`:

 
```
mysqld_multi start 17

```

This command stops several servers, using option groups `[mysqld8]` and `[mysqld10]` through `[mysqld13]`:

 
```
mysqld_multi stop 8,10-13

```

### Options

 `mysqld_multi` supports the following options:

 


| Option | Description |
| --- | --- |
| `--example` | Give an example of a config file with extra information. |
| `--help` | Display help and exit. |
| `--log=filename` | Specify the path and name of the log file. If the file exists, log output is appended to it. |
| `--mysqladmin=prog_name` | The [mariadb-admin](../mariadb-admin/index) binary to be used to stop servers. Can be given within groups `[mysqld#]`. |
| `--mysqld=prog_name` | The mysqld binary to be used. Note that you can also specify [mysqld\_safe](../mysqld_safe/index) as the value for this option. If you use mysqld\_safe to start the server, you can include the `mysqld` or `ledir` options in the corresponding `[mysqldN]` option group. These options indicate the name of the server that mysqld\_safe should start and the path name of the directory where the server is located. Example:`[mysqld38]``mysqld = mysqld-debug``ledir = /opt/local/mysql/libexec`. |
| `--no-log` | Print to stdout instead of the log file. By default the log file is turned on. |
| `--password=password` | The password of the MariaDB account to use when invoking [mariadb-admin](../mariadb-admin/index). Note that the password value is not optional for this option, unlike for other MariaDB programs. |
| `--silent` | Silent mode; disable warnings. |
| `--tcp-ip` | Connect to the MariaDB server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket. This option affects stop and report operations. |
| `--user=username` | The user name of the MariaDB account to use when invoking [mariadb-admin](../mariadb-admin/index). |
| `--verbose` | Be more verbose. |
| `--version` | Display version information and exit. |
| `--wsrep-new-cluster` | Bootstrap a cluster. Added in [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/). |

 
### Option Files

 In addition to reading options from the command-line, `mysqld_multi` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mysqld_multi` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
#### Option Groups

 `mysqld_safe` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqld_multi]` |  Options read by `mysqld_multi`, which includes both MariaDB Server and MySQL Server. |

 
`mysqld_multi` also searches [option files](../configuring-mariadb-with-option-files/index) for [option groups](../configuring-mariadb-with-option-files/index#option-groups) with names like `[mysqldN]`, where `N` can be any positive integer. This number is referred to in the following discussion as the option group number, or `GNR`:

 


| Group | Description |
| --- | --- |
| `[mysqldN]` |  Options read by a `mysqld` instance managed by `mysqld_multi`, which includes both MariaDB Server and MySQL Server. The `N` refers to the instance's `GNR`. |

 
`GNR` values distinguish option groups from one another and are used as arguments to `mysqld_multi` to specify which servers you want to start, stop, or obtain a status report for. The `GNR` value should be the number at the end of the option group name in the option file. For example, the `GNR` for an option group named `[mysqld17]` is `17`.

 Options listed in these option groups are the same that you would use in the regular server option groups used for configuring `mysqld`. However, when using multiple servers, it is necessary that each one use its own value for options such as the Unix socket file and TCP/IP port number.

 The `[mysqld_multi]` option group can be used for options that are needed for `mysqld_multi` itself. `[mysqldN]` option groups can be used for options passed to specific `mysqld` instances.

 The regular server [option groups](../configuring-mariadb-with-option-files/index#option-groups) can also be used for common options that are read by all instances:

 


| Group | Description |
| --- | --- |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[server]` | Options read by MariaDB Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-5.5]`. |
| `[mariadb]` | Options read by MariaDB Server. |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[galera]` |  Options read by a galera-capable MariaDB Server. Available on systems compiled with Galera support. |

 
For an example of how you might set up an option file, use this command:

 
```
mysqld_multi --example

```

### Authentication and Privileges

 Make sure that the MariaDB account used for stopping the `mysqld` processes (with the [mariadb-admin](../mariadb-admin/index) utility) has the same user name and password for each server. Also, make sure that the account has the `SHUTDOWN` privilege. If the servers that you want to manage have different user names or passwords for the administrative accounts, you might want to create an account on each server that has the same user name and password. For example, you might set up a common `multi_admin` account by executing the following commands for each server:

 
```
shell> mysql -u root -S /tmp/mysql.sock -p
Enter password:
mysql> GRANT SHUTDOWN ON *.*
 -> TO ´multi_admin´@´localhost´ IDENTIFIED BY ´multipass´;

```

Change the connection parameters appropriately when connecting to each one. Note that the host name part of the account name must allow you to connect as `multi_admin` from the host where you want to run `mysqld_multi`.

 User Account
------------

 Make sure that the data directory for each server is fully accessible to the Unix account that the specific `mysqld` process is started as. If you run the `mysqld_multi` script as the Unix `root` account, and if you want the `mysqld` process to be started with another Unix account, then you can use use the `--user` option with `mysqld`. If you specify the `--user` option in an option file, and if you did not run the `mysqld_multi` script as the Unix `root` account, then it will just log a warning and the `mysqld` processes are started under the original Unix account.

 Do not run the `mysqld` process as the Unix `root` account, unless you know what you are doing.

 Example
-------

 The following example shows how you might set up an option file for use with mysqld\_multi. The order in which the mysqld programs are started or stopped depends on the order in which they appear in the option file. Group numbers need not form an unbroken sequence. The first and fifth [mysqldN] groups were intentionally omitted from the example to illustrate that you can have “gaps” in the option file. This gives you more flexibility.

 
```
           # This file should probably be in your home dir (~/.my.cnf)
           # or /etc/my.cnf
           # Version 2.1 by Jani Tolonen
           [mysqld_multi]
           mysqld     = /usr/local/bin/mysqld_safe
           mysqladmin = /usr/local/bin/mysqladmin
           user       = multi_admin
           password   = multipass
           [mysqld2]
           socket     = /tmp/mysql.sock2
           port       = 3307
           pid-file   = /usr/local/mysql/var2/hostname.pid2
           datadir    = /usr/local/mysql/var2
           language   = /usr/local/share/mysql/english
           user       = john
           [mysqld3]
           socket     = /tmp/mysql.sock3
           port       = 3308
           pid-file   = /usr/local/mysql/var3/hostname.pid3
           datadir    = /usr/local/mysql/var3
           language   = /usr/local/share/mysql/swedish
           user       = monty
           [mysqld4]
           socket     = /tmp/mysql.sock4
           port       = 3309
           pid-file   = /usr/local/mysql/var4/hostname.pid4
           datadir    = /usr/local/mysql/var4
           language   = /usr/local/share/mysql/estonia
           user       = tonu
           [mysqld6]
           socket     = /tmp/mysql.sock6
           port       = 3311
           pid-file   = /usr/local/mysql/var6/hostname.pid6
           datadir    = /usr/local/mysql/var6
           language   = /usr/local/share/mysql/japanese
           user       = jani

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqld_multi/>

sysVinit
========

    [sysVinit](https://en.wikipedia.org/wiki/Init#SysV-style) is one of the most common service managers. On systems that use [sysVinit](https://en.wikipedia.org/wiki/Init#SysV-style), the `[mysql.server](../mysqlserver/index)` script is normally installed to `/etc/init.d/mysql`. 

 Interacting with the MariaDB Server Process
-------------------------------------------

 The service can be interacted with by using the `[service](https://linux.die.net/man/8/service)` command.

 ### Starting the MariaDB Server Process on Boot

 On RHEL/CentOS and other similar distributions, the `[chkconfig](https://linux.die.net/man/8/chkconfig)` command can be used to enable the MariaDB Server process at boot:

 
```
chkconfig --add mysql
chkconfig --level 345 mysql on

```

On Debian and Ubuntu and other similar distributions, the `[update-rc.d](https://manpages.debian.org/wheezy/sysv-rc/update-rc.d.8.en.html)` command can be used:

 
```
update-rc.d mysql defaults

```

### Starting the MariaDB Server Process

 
```
service mysql start

```

### Stopping the MariaDB Server Process

 
```
service mysql stop

```

### Restarting the MariaDB Server Process

 
```
service mysql restart

```

### Checking the Status of the MariaDB Server Process

 
```
service mysql status

```

Manually Installing mysql.server with SysVinit
----------------------------------------------

 If you install MariaDB from [source](../compiling-mariadb-from-source/index) or from a [binary tarball](../installing-mariadb-binary-tarballs/index) that does not install `[mysql.server](../mysqlserver/index)` automatically, and if you are on a system that uses [sysVinit](index), then you can manually install `mysql.server` with [sysVinit](index). See [mysql.server: Manually Installing with SysVinit](../mysqlserver/index#manually-installing-with-sysvinit) for more information.

 SysVinit and Galera Cluster
---------------------------

 ### Bootstrapping a New Cluster

 When using [Galera Cluster](../galera/index) with sysVinit, the first node in a cluster has to be started with `service mysql bootstrap`. See [Getting Started with MariaDB Galera Cluster: Bootstrapping a New Cluster](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysvinit/>

mariadbd
========

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd` is a symlink to [mysqld](../mysqld-options/index), the MariaDB server.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd` is the name of the server, with `mysqld` a symlink .

 
See [mysqld](../mysqld-options/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadbd/>

mariadbd-multi
==============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd-multi` is a symlink to `mysqld_multi`, the wrapper designed to manage several mysqld processes running on the same host.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd-multi` is the name of the server, with `mysqld_multi` a symlink .

 
See [mysqld\_multi](../mysqld_multi/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadbd-multi/>

launchd
=======

    In MacOS, create a file called /Library/LaunchDaemons/com.mariadb.server.plist with the following contents (edit to suit):

 
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key> <string>com.mariadb.server</string>
  <key>KeepAlive</key><true/>
  <key>RunAtLoad</key><true/>
  <key>LaunchOnlyOnce</key><false/>
  <key>ExitTimeOut</key><integer>600</integer>
  <key>WorkingDirectory</key><string>/usr/local/var</string>
  <key>Program</key><string>/usr/local/bin/mysqld</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/mysqld</string>
    <string>--user=_mysql</string>
    <string>--basedir=/usr/local/opt/mariadb</string>
    <string>--plugin-dir=/usr/local/opt/mariadb/lib/plugin</string>
    <string>--datadir=/usr/local/var/mysql</string>
    <string>--log-error=/usr/local/var/mysql/Data-Server.local.err</string>
    <string>--pid-file=/usr/local/var/mysql/Data-Server.local.pid</string>
    <string>--sql-mode=ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION</string>
  </array>
</dict>
</plist>

```

Then from a shell, run `launchctl load /Library/LaunchDaemons/com.mariadb.server.plist` and MariaDB will run immediately, and also upon reboot.

 See Also
--------

 * [Creating Launch Daemons and Agents](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html)
* [A launchd Tutorial](http://www.launchd.info/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/launchd/>

Build Environment Setup for Linux
=================================

    Required Tools
--------------

 The following is a list of tools that are required for building MariaDB on Linux and Mac OS X. Most, if not all, of these will exist as packages in your distribution's package repositories, so check there first. See [Building MariaDB on Ubuntu](../building-mariadb-on-ubuntu/index), [Building MariaDB on CentOS](../building-mariadb-on-centos/index), and [Building MariaDB on Gentoo](../building-mariadb-on-gentoo/index) pages for specific requirements for those platforms.

 * [git](https://git-scm.com/)
* [gzip](http://www.gzip.org/)
* [GNU tar](http://www.gnu.org/software/tar/)
* [gcc/g++ 4.8.5 or later, recommend above 9](http://gcc.gnu.org/) or [clang/clang++](https://clang.llvm.org/)
* [GNU make 3.75 or later](http://www.gnu.org/software/make/) or [Ninja](https://ninja-build.org/)
* [bison (3.0)](http://www.gnu.org/software/bison/)
* [libncurses](http://www.gnu.org/software/ncurses/)
* [zlib-dev](http://www.zlib.net/)
* [libevent-dev](http://libevent.org)
* [cmake above 2.8.7 though preferably above 3.3](http://www.cmake.org)
* [gnutls](http://www.gnutls.org) or [openssl](http://www.openssl.org)
* [jemalloc](http://www.canonware.com/jemalloc) (optional)
* [snappy](http://google.github.io/snappy) (compression library, optional)
* [valgrind](http://www.valgrind.org/) (only needed if running [mysql-test-run --valgrind](../mysql-test-runpl-options/index#options-for-valgrind))
* [libcurl](https://curl.se/libcurl//libcurl) (only needed if you want to use the [S3 storage engine](../s3-storage-engine/index))
* libxml2-devel
* boost
* libaio-devel
* systemd-devel
* pcre2-devel (optiona, will be automatically downloaded and installed if not on the system)
* ccache ; Will speed up builds if you are going to use the scripts in the BUILD directory.

 You can install these programs individually through your package manager.

 In addition, some package managers support the use a build dependency command. When using this command, the package manager retrieves a list of build dependencies and install them for you, making it much easier to get started on the compile. The actual option varies, depending on the distribution you use.

 On Ubuntu and Debian you can use the `build-dep` command.

 
```
# apt build-dep mariadb-server

```

Fedora uses the `builddep` command with DNF.

 
```
# dnf builddep mariadb-server

```

If building on Centos 7, use the [building MariaDB on Centos instructions](../source-building-mariadb-on-centos/index).

 With openSUSE and SUSE, you can use the source-install command.

 
```
# zypper source-install -d mariadb

```

Each of these commands works off of the release of MariaDB provided in the official software repositories of the given distribution. In some instances and especially in older versions of Linux, MariaDB may not be available in the official repositories. In these cases you can use the MariaDB repositories as an alternative.

 Bear in mind, the release of MariaDB provided by your distribution may not be the same as the version you are trying to install. Additionally, the package managers don't always retrieve all of the packages you need to compile MariaDB. There may be some missed or unlisted in the process. When this is the case, CMake fails during checks with an error message telling you what's missing.

 
Note: On Debian-based distributions, you may receive a *"You must put some 'source' URIs in your sources.list"* error. To avoid this, ensure that /etc/apt/sources.list contains the source repositories.  
   
 For example, for Debian buster:

 
```
deb http://ftp.debian.org/debian buster main contrib
deb http://security.debian.org buster/updates main contrib
deb-src http://ftp.debian.org/debian buster main contrib
deb-src  http://security.debian.org buster/updates main contrib

```

Refer to the documentation for your Linux distribution for how to do this on your system.  
   
 After editing the sources.list, do:

 
```
sudo apt update

```

...and then the above mentioned `build-dep` command.

 

Note: On openSUSE the source package repository may be disabled. The following command will enable it:

 
```
sudo zypper mr -er repo-source

```

After enabling it, you will be able to run the zypper command to install the build dependencies.

 
You should now have your build environment set up and can proceed to [Getting the MariaDB Source Code](../getting_the_mariadb_source_code/index) and then using the [Generic Build Instructions](../generic-build-instructions/index) to build MariadB (or following the steps for your Linux distribution or [Creating a MariaDB Binary Tarball](../creating-the-mariadb-binary-tarball/index)).

 See Also
--------

 * [Installing Galera from source](../installating-galera-from-source/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Build_Environment_Setup_for_Linux/>

mariadbd-safe
=============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadbd-safe` is a symlink to `mysqld_safe`, the tool for starting mysqld on Linux and Unix distributions that do not support [systemd](../systemd/index).

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadbd-safe` is the name of the binary, with `mysqld_safe` a symlink .

 
See [mysqld\_safe](../mysqld_safe/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadbd-safe/>

Troubleshooting Connection Issues
=================================

       
  
  
 If you are completely new to MariaDB and relational databases, you may want to start with the [MariaDB Primer](../a-mariadb-primer/index). Also, make sure you understand the connection parameters discussed in the [Connecting to MariaDB](../connecting-to-mariadb/index) article.   
  
  
 There are a number of common problems that can occur when connecting to MariaDB.   
  
  


 ### Server Not Running in Specified Location

 If the error you get is something like:

 
```
mariadb -uname -p -uname -p
ERROR 2002 (HY000): Can't connect to local MySQL server through 
  socket '/var/run/mysqld/mysqld.sock' (2 "No such file or directory")

```

or

 
```
mariadb -uname -p --port=3307 --protocol=tcp
ERROR 2003 (HY000): Can't connect to MySQL server on  'localhost' 
  (111 "Connection refused")

```

the server is either not running, or not running on the specified port, socket or pipe. Make sure you are using the correct [host](../connecting-to-mariadb/index#host), [port](../connecting-to-mariadb/index#port), [pipe](../connecting-to-mariadb/index#pipe), [socket](../connecting-to-mariadb/index#socket) and [protocol](../connecting-to-mariadb/index#protocol) options, or alternatively, see [Getting, Installing and Upgrading MariaDB](../getting-installing-and-upgrading-mariadb/index), [Starting and Stopping MariaDB](../starting-and-stopping-mariadb/index) or [Troubleshooting Installation Issues](../troubleshooting-installation-issues/index).

 The socket file can be in a non-standard path. In this case, the `socket` option is probably written in the my.cnf file. Check that its value is identical in the [mysqld] and [client] sections; if not, the client will look for a socket in a wrong place.

 If unsure where the Unix socket file is running, it's possible to find this out, for example:

 
```
netstat -ln | grep mysqld
unix  2      [ ACC ]     STREAM     LISTENING     33209505 /var/run/mysqld/mysqld.sock

```

### Unable to Connect from a Remote Location

 Usually, the MariaDB server does not by default accept connections from a remote client or connecting with tcp and a hostname and has to be configured to permit these.

 
```
(/my/maria-10.4) ./client/mysql --host=myhost --protocol=tcp --port=3306 test
ERROR 2002 (HY000): Can't connect to MySQL server on 'myhost' (115)
(/my/maria-10.4) telnet myhost 3306
Trying 192.168.0.11...
telnet: connect to address 192.168.0.11: Connection refused
(/my/maria-10.4) perror 115
OS error code 115:  Operation now in progress

```

To solve this, see [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index)

 ### Authentication Problems

 Note that from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), the [unix\_socket authentication plugin](../authentication-plugin-unix-socket/index) is enabled by default on Unix-like systems. This uses operating system credentials when connecting to MariaDB via the local Unix socket file. See [unix\_socket authentication plugin](../authentication-plugin-unix-socket/index) for instructions on connecting and on switching to password-based authentication as well as [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for an overview of the [MariaDB 10.4](../what-is-mariadb-104/index) changes..

 Authentication is granted to a particular username/host combination. `user1'@'localhost'`, for example, is not the same as `user1'@'166.78.144.191'`. See the [GRANT](../grant/index) article for details on granting permissions.

 Passwords are hashed with [PASSWORD](../password/index) function. If you have set a password with the [SET PASSWORD](../set-password/index) statement, the [PASSWORD](../password/index) function must be used at the same time. For example, `SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass')` rather than just `SET PASSWORD FOR 'bob'@'%.loc.gov' = 'newpass'`;

 #### Problems Exporting Query Results

 If you can run regular queries, but get an authentication error when running the [SELECT ... INTO OUTFILE](../select-into-outfile/index), [SELECT ... INTO DUMPFILE](../select-into-dumpfile/index) or [LOAD DATA INFILE](../load-data-infile/index) statements, you do not have permission to write files to the server. This requires the FILE privilege. See the [GRANT](../grant/index) article.

 #### Access to the Server, but not to a Database

 If you can connect to the server, but not to a database, for example:

 
```
USE test;
ERROR 1044 (42000): Access denied for user 'ian'@'localhost' to database 'test'

```

or can connect to a particular database, but not another, for example `mariadb -uname -p -u name db1` works but not `mariadb -uname -p -u name db2`, you have not been granted permission for the particular database. See the [GRANT](../grant/index) article.

 #### Option Files and Environment Variables

 It's possible that option files or environment variables may be providing incorrect connection parameters. Check the values provided in any option files read by the client you are using (see [mysqld Configuration Files and Groups](../mysqld-configuration-files-and-groups/index) and the documentation for the particular client you're using - see [Clients and Utilities](../clients-and-utilities/index)).

 Option files can usually be suppressed with `no-defaults` option, for example:

 
```
mariadb-import --no-defaults ...

```

#### Unable to Connect to a Running Server / Lost root Password

 If you are unable to connect to a server, for example because you have lost the root password, you can start the server without using the privilege tables by running the [--skip-grant-tables](../mysqld-options/index#-skip-grant-tables) option, which gives users full access to all tables. You can then run [FLUSH PRIVILEGES](../flush/index) to resume using the grant tables, followed by [SET PASSWORD](../set-password/index) to change the password for an account.

 #### localhost and %

 You may have created a user with something like:

 
```
CREATE USER melisa identified by 'password';

```

This creates a user with the '%' wildcard host. 

 
```
select user,host from mysql.user where user='melisa';
+--------+------+
| user   | host |
+--------+------+
| melisa | %    |
+--------+------+

```

However, you may still be failing to login from localhost. Some setups create anonymous users, including localhost. So the following records exist in the user table:

 
```
select user,host from mysql.user where user='melisa' or user='';
+--------+-----------+
| user   | host      |
+--------+-----------+
| melisa | %         |
|        | localhost |
+--------+-----------+

```

Since you are connecting from localhost, the anonymous credentials, rather than those for the 'melisa' user, are used. The solution is either to add a new user specific to localhost, or to remove the anonymous localhost user.

 ### See Also

 * [CREATE USER](../create-user/index)
* [GRANT](../grant/index)
* [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [Authentication from MariaDB 10 4 video tutorial](https://www.youtube.com/watch?v=aWFG4uLbimM)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/troubleshooting-connection-issues/>

Installation issues on Windows
==============================

    [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/)
-------------------------------------------------------------------------

 [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/) may not start on Windows. See [MDEV-22555](https://jira.mariadb.org/browse/MDEV-22555).

 To resolve this, download, click and install <https://aka.ms/vs/16/release/vc_redist.x64.exe> and then install 10.4.13.

 Unsupported Versions of Windows
-------------------------------

 Recent versions of MariaDB may not install on unsupported Windows versions. See [Deprecated Package Platforms](../deprecation-policy/index#deprecated-package-platforms) to find the final supported versions.

 
[MariaDB 5.2.5](https://mariadb.com/kb/en/mariadb-525-release-notes/) and earlier
----------------------------------------------------------------------------------

 ### On Windows Vista/7 , changes to database or my.ini are not persistent, when mysqld.exe is run from the command line.

 The reason for this behavior is Vista/Win7 file system redirection. Writes to protected locations (in this case a subdirectory of Program Files) are redirected to the user's so-called "Virtual Store".

 Workarounds:

 * Run mysqld.exe as service. See answer [here](http://stackoverflow.com/questions/4962342/mariadb-on-windows-what-is-this-error-when-trying-to-start-the-database-engine) on how to create a MariaDB service.
* Run mysqld.exe from the [elevated command prompt](http://www.winhelponline.com/articles/158/1/How-to-open-an-elevated-Command-Prompt-in-Windows-Vista.html).
* [Change the ACL](http://technet.microsoft.com/en-us/library/bb727008.aspx) of the data directory and add full control for the current user.

 The Windows installer for [MariaDB 5.2.6](https://mariadb.com/kb/en/mariadb-526-release-notes/) and higher will set the data directory ACL to include full access rights for the user who runs the setup to prevent this issue from happening.

 Systems with User Account Control
---------------------------------

 Running `mysql_install_db.exe` from a standard command prompt might cause the error: 

 
```
FATAL ERROR: OpenSCManager failed

```

To get rid of it, use the elevated command prompt, for example on Windows 7 start it via 'Run as administrator' option.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installation-issues-on-windows/>

Troubleshooting MariaDB Installs on Red Hat/CentOS
==================================================

    The following article is about different issues people have encountered when installing MariaDB on Red Hat / CentOS.

 It is highly recommended to [install with yum](../yum/index) where possible.

 In Red Hat / CentOS it is also possible to install a [RPM](http://downloads.askmonty.org/mariadb/) or a [tar ball](../installing-mariadb-binary-tarballs/index). The RPM is the preferred version, except if you want to install many versions of MariaDB or install MariaDB in a non standard location.

 ### Replacing MySQL

 If you removed an MySQL RPM to install MariaDB, note that the MySQL RPM on uninstall renames /etc/my.cnf to /etc/my.cnf.rpmsave.

 After installing MariaDB you should do the following to restore your configuration options:

 
```
mv /etc/my.cnf.rpmsave /etc/my.cnf

```

### Unsupported configuration options

 If you are using any of the following options in your /etc/my.cnf or other my.cnf file you should remove them. This is also true for MySQL 5.1 or newer:

 
```
skip-bdb

```

See also
--------

 * [Installing with yum (recommended)](../yum/index)
* [Installing MariaDB RPM Files](../installing-mariadb-rpm-files/index)
* [Checking MariaDB RPM Package Signatures](../checking-mariadb-rpm-package-signatures/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/troubleshooting-mariadb-installs-on-red-hatcentos/>

Installation issues on Debian and Ubuntu
=========================================

   Solutions to different installation issues on Debian and Ubuntu

  

| Title | Description |
| --- | --- |
|  [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) |  MariaDB when installed from the Debian repos has a number of differences with standard MariaDB.  |
|  [Moving from MySQL to MariaDB in Debian 9](../moving-from-mysql-to-mariadb-in-debian-9/index) |  MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"  |
|  [Creating a Debian Repository](../creating_a_debian_repository/index) |  Instructions for creating your own Debian repository  |
|  [MariaDB 5.5.33 Debian and Ubuntu Installation Issues](../mariadb-5533-debian-and-ubuntu-installation-issues/index) |  Workarounds for some repository issues with the 5.5.33 release.  |
|  [MariaDB Debian Live Images](../mariadb-debian-live-images/index) |  Debian live iso images with pre-installed MariaDB (obsolete)  |
|  [apt-upgrade Fails, But the Database is Running](../apt-upgrade-fails-but-the-database-is-running/index) |  timeout causing apt to fail while the database is running.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installation-issues-on-debian-and-ubuntu/>

Installing on an Old Linux Version
==================================

    This article lists some typical errors that may happen when you try to use an incompatible MariaDB binary on a linux system:

 The following example errors are from trying to install MariaDB built for SuSE 11.x on a SuSE 9.0 server:

 
```
> scripts/mysql_install_db
./bin/my_print_defaults: /lib/i686/libc.so.6: 
  version `GLIBC_2.4' not found (required by ./bin/my_print_defaults)

```

and

 
```
> ./bin/mysqld --skip-grant &
./bin/mysqld: error while loading shared libraries: libwrap.so.0:
cannot open shared object file: No such file or directory

```

If you see either of the above errors, the binary MariaDB package you installed is not compatible with your system.

 The options you have are:

 * Find another MariaDB package or tar from the [download page](https://downloads.mariadb.org/) that matches your system.

 * or

 * [Download the source](../source-getting-the-mariadb-source-code/index) and [build it](../generic-build-instructions/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-on-an-old-linux-version/>

Error: symbol mysql\_get\_server\_name, version libmysqlclient\_16 not defined
==============================================================================

    If you see the error message:

 
```
symbol mysql_get_server_name, version libmysqlclient_16 not defined in file libmysqlclient.so.16 with link time reference

```

...then you are probably trying to use the mysql command-line client from MariaDB with libmysqlclient.so from MySQL.

 The symbol `mysql_get_server_name()` is something present in the MariaDB source tree and not in the MySQL tree. 

 If you have both the MariaDB client package and the MySQL client packages installed this error will happen if your system finds the MySQL version of `libmysqlclient.so` first.

 To figure out which library is being linked in dynamically (ie, the wrong one) use the 'ldd' tool.

 
```
ldd $(which mysql) | grep mysql

```

or

 
```
ldd /path/to/the/binary | grep mysql

```

For example:

 
```
me@mybox:~$ ldd $(which mysql)|grep mysql
        libmysqlclient.so.16 => /usr/lib/libmysqlclient.so.16 (0xb74df000)

```

You can then use your package manager's tools to find out which package the library belongs to.

 On CentOS the command to find out which package installed a specific file is:

 
```
rpm -qf /path/to/file

```

On Debian-based systems, the command is:

 
```
dpkg -S /path/to/file

```

Here's an example of locating the library and finding out which package it belongs to on an Ubuntu system:

 
```
me@mybox:~$ ldd $(which mysql)|grep mysql
	libmysqlclient.so.16 => /usr/lib/libmysqlclient.so.16 (0xb75f8000)
me@mybox:~$ dpkg -S /usr/lib/libmysqlclient.so.16
libmariadbclient16: /usr/lib/libmysqlclient.so.16

```

The above shows that the mysql command-line client is using the library `/usr/lib/libmysqlclient.so.16` and that that library is part of the `libmariadbclient16` Ubuntu package. Unsurprisingly, the mysql command-line client works perfectly on this system.

 If the answer that came back had been something other than a MariaDB package, then it is likely there would have been issues with running the MariaDB mysql client application.

 If the library that the system tries to use is not from a MariaDB package, the remedy is to remove the offending package (and possibly install or re-install the correct package) so that the correct library can be used.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/error-symbol-mysql_get_server_name-version-libmysqlclient_16-not-defined/>

Installation Issues with PHP5
=============================

    PHP5 may give an error if used with the old connect method:

 
```
'mysql_connect(): Headers and client library minor version mismatch. Headers:50156 Library:50206'

```

This is because the library wrongly checks and expects that the client library must be the exact same version as PHP was compiled with. You would get the same error if you tried to upgrade just the MySQL client library without upgrading PHP at the same time. See also [How to match API version for php5\_mysql and mariadb client](1079).

 Ways to fix this issue:

 1. Switch to using the [mysqlnd driver](http://dev.mysql.com/downloads/connector/php-mysqlnd/) in PHP (Recommended solution).
2. Run with a lower [error reporting level](http://php.net/error-reporting):
```
$err_level = error_reporting(0);
$conn = mysql_connect('params');
error_reporting($err_level); 

```
3. Recompile PHP with the MariaDB client libraries.
4. Use your original MySQL client library with the MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installation-issues-with-php5/>

mysql\_install\_db
==================

    `mariadb-install-db` initializes the MariaDB data directory and creates the system tables in the mysql database.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-install-db](../mariadb-install-db/index) is a symlink to `mysql_install_db`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_install_db` is the symlink, and [mariadb-install-db](../mariadb-install-db/index) the binary name.

 
See [mariadb-install-db](../mariadb-install-db/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_install_db/>

Get, Build and Test Latest MariaDB the Lazy Way
===============================================

    The intention of this documentation is show all the steps of getting, building and testing the latest MariaDB server (10.5 at time of writing) from GitHub. Each stage links to the full documentation for that step if you need to find out more.

 [Install all tools needed to build MariaDB](../build_environment_setup_for_linux/index)
---------------------------------------------------------------------------------------

 ### OpenSuse

 
```
sudo zypper install git gcc gcc-c++ make bison ncurses ncurses-devel zlib-devel libevent-devel cmake openssl

```

### Debian

 
```
apt install -y build-essential bison
apt build-dep mariadb-server 

```

[Set Up git](../using-git/index)
--------------------------------

 Fetch and checkout the MariaDB source to a subdirectory of the current directory

 
```
git clone https://github.com/MariaDB/server.git mariadb
cd mariadb
git checkout 10.5

```

[Build It](../generic-build-instructions/index)
-----------------------------------------------

 The following command builds a server the same way that is used for building releases. Use `cmake . -DCMAKE_BUILD_TYPE=Debug` to build for debugging.

 
```
cmake . -DBUILD_CONFIG=mysql_release && make -j8

```

[Check the Server (If You Want To)](%5bmysql-test)
--------------------------------------------------

 
```
cd mysql-test
mtr --parallel=8 --force

```

[Install the Default Databases](../mariadb-install-db/index)
------------------------------------------------------------

 
```
./scripts/mariadb-install-db --srcdir=.

```

(Older MariaDB version use [mysql\_install\_db](../mysql_install_db/index))

 Install the Server (If needed)
------------------------------

 You can also [run and test mariadb directly from the build directory](../running-mariadb-from-the-build-directory/index), in which case you can skip the rest of the steps below.

 
```
make install

```

### [Start the Server](../starting-and-stopping-mariadb-automatically/index)

 Start the server in it's own terminal window for testing. Note that the directory depends on your system!

 
```
/usr/sbin/mysqld

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/get-build-and-test-latest-mariadb-the-lazy-way/>

Generic Build Instructions
==========================

     The instructions on this page will help you compile [MariaDB](../mariadb/index) from source. Links to more complete instructions for specific platforms can be found on the [source](../source/index) page.

 First, [get a copy of the MariaDB source](../getting-the-mariadb-source-code/index).

 Next, [prepare your system to be able to compile the source](../build-environment-setup-for-linux/index).

 If you don't want to run MariaDB as yourself, then you should create a `mysql` user. The example below uses this user.

 Using cmake
-----------

 [MariaDB 5.5](../what-is-mariadb-55/index) and above is compiled using *cmake*.

 It is recommended to create a build directory **beside** your source directory

 
```
mkdir build-mariadb
cd build-mariadb

```

**NOTE** If you have built MariaDB in the past and have recently updated the repository, you should perform a complete cleanup of old artifacts (such as cmake configured files). In the base repository run:

 
```
git clean -xffd && git submodule foreach --recursive git clean -xffd

```

You can configure your build simply by running *cmake* without any special options, like

 
```
cmake ../server

```

where `server` is where you installed MariaDB. If you are building in the source directory, just omit `../server`.

 If you want it to be configured exactly as a normal MariaDB server release is built, use

 
```
cmake ../server -DBUILD_CONFIG=mysql_release

```

This will configure the build to generate binary tarballs similar to release tarballs from downloads.mariadb.org. Unfortunately this doesn't work on old platforms, like OpenSuse Leap 15.0, because MariaDB binary tarballs are built to minimize external dependencies, and that needs static libraries that might not be provided by the platform by default, and would need to be installed manually.

 To do a build suitable for debugging use:

 
```
cmake ../server -DCMAKE_BUILD_TYPE=Debug

```

By default, MariaDB is compiled with the `-Werror` flag, which causes compiling to abort if there is a compiler warning. You can disable that by configuring with `-DMYSQL_MAINTAINER_MODE=OFF`.

 
```
cmake ../server -DCMAKE_BUILD_TYPE=Debug -DMYSQL_MAINTAINER_MODE=OFF.

```

All *cmake* configuration options for MariaDB can be displayed with:

 
```
cmake ../server -LH

```

To build and install MariaDB after running *cmake* use

 
```
cmake --build .
sudo cmake --install .

```

If the commands above fail, you can enable more compilation information by doing:

 
```
cmake --build . --verbose

```

If you want to generate a binary tarball, run

 
```
cpack

```

Using BUILD Scripts
-------------------

 There are also `BUILD` scripts for the most common systems for those that doesn't want to dig into cmake options. These are optimized for in source builds.

 The scripts are of type 'compile-#cpu#-how\_to\_build'. Some common scripts-are

 


| Script | Description |
| --- | --- |
| compile-pentium64 |  Compile an optimized binary optimized for 64 bit pentium (works also for amd64) |
| compile-pentium-debug | Compile a debug binary optimized for 64 bit pentium |
| compile-pentium-valgrind-max |  Compile a debug binary that can be used with [valgrind](http://www.valgrind.org/) to find wrong memory accesses and memory leaks. Should be used if one want's to run the `mysql-test-run` test suite with the `--valgrind` option |

 
Some common suffixes used for the scripts:

 


| Suffix | Description |
| --- | --- |
| `32` |  Compile for 32 bit cpu's |
| `64` | Compile for 64 bit cpu's |
| `-max` | Enable (almost) all features and plugins that MariaDB supports |
| `-gprof` | binary is compiled with profiling (gcc --pg) |
| `-gcov` | binary is compiled with code coverage (gcc -fprofile-arcs -ftest-coverage) |
| `-valgrind` | The binary is compiled for debugging and optimized to be used with [valgrind](http://www.valgrind.org/). |
| `-debug` |  The binary is compiled with all symbols (gcc -g) and the `[DBUG](../creating-a-trace-file/index)` log system is enabled. |

 
All `BUILD` scripts support the following options:

 


| Suffix | Description |
| --- | --- |
| -h, --help | Show this help message. |
| -n, --just-print | Don't actually run any commands; just print them. |
| -c, --just-configure | Stop after running configure. Combined with --just-print shows configure options. |
| --extra-configs=xxx | Add this to configure options |
| --extra-flags=xxx | Add this C and CXX flags |
| --extra-cflags=xxx | Add this to C flags |
| --extra-cxxflags=xxx | Add this to CXX flags |
| --verbose | Print out full compile lines |
| --with-debug=full | Build with full debug(no optimizations, keep call stack). |

 
A typical compilation used by a developer would be:

 
```
shell> ./BUILD/compile-pentium64-debug

```

This configures the source for debugging and runs make. The server binary will be `sql/mariadbd` or `sql/mysqld`.

 Starting MariaDB for the First Time
-----------------------------------

 After installing MariaDB (using `sudo make install`), but prior to starting MariaDB for the first time, one should:

 1. ensure the directory where you installed MariaDB is owned by the mysql user (if the user doesn't exist, you'll need to create it)
2. run the [mariadb-install-db](../mariadb-install-db/index) script to generate the needed system tables

 Here is an example:

 
```
# The following assumes that the 'mysql' user exists and that we installed MariaDB
# in /usr/local/mysql
chown -R mysql /usr/local/mysql/
cd /usr/local/mysql/
scripts/mariadb-install-db --user=mysql
/usr/local/mysql/bin/mysqld_safe --user=mysql &

```

Testing MariaDB
---------------

 If you want to test your compiled MariaDB, you can do either of:

 Run unit tests:

 
```
cmake --build . --target test

```

Or run mtr tests:

 
```
mysql-test/mysql-test-run --force

```

Each of the above are run from the build directory. There is no need to '`make install`/`cmake --install .`' MariaDB prior to running them.

 
**NOTE:** If you are doing more extensive testing or debugging of MariaDB (like with real application data and workloads) you may want to start and run MariaDB directly from the source directory instead of installing it with '`sudo make install`'. If so, see [Running MariaDB from the Source Directory](../running-mariadb-from-the-source-directory/index).

 
Increasing Version Number or Tagging a Version
----------------------------------------------

 If you have made code changes and want to increase the version number or tag our version with a specific tag you can do this by editing the `VERSION` file. Tags are shown when running the '`mysqld --version`' command. 

 Non-ascii Symbols
-----------------

 MariaDB builds with `readline`; using an alternative such as `Editline` may result in problems with non-ascii symbols.

 Post-install Tasks
------------------

 * [Installing system tables (mariadb-install-db)](../installing-system-tables-mariadb-install-db/index)
* [Starting and Stopping MariaDB Automatically](../starting-and-stopping-mariadb-automatically/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/generic-build-instructions/>

Compiling MariaDB with Extra Modules/Options
=============================================

  

| Title | Description |
| --- | --- |
|  [Compiling MariaDB with TCMalloc](../compiling-mariadb-with-tcmalloc/index) |  TCMalloc is a malloc replacement library optimized for multi-threaded usage.  |
|  [Compiling MariaDB with Vanilla XtraDB](../compiling-mariadb-with-vanilla-xtradb/index) |  Sometimes, one needs to have MariaDB compiled with Vanilla XtraDB. This pag...  |
|  [Specifying Which Plugins to Build](../specifying-which-plugins-to-build/index) |  Specifying which plugins to build.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-with-extra-modulesoptions/>

Creating the MariaDB Source Tarball
===================================

    How to create a source tar.gz file.

 First [Setup your build environment](../linux_build_environment_setup/index).

 Then use automake/configure/make to generate the tar file:

 
```
BUILD/autorun.sh
./configure --with-plugin-xtradb
make dist

```

This creates a source file with a name like `mysql-5.3.2-MariaDB-beta.tar.gz`

 See also [the generic build instructions](../generic-build-instructions/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Creating_the_MariaDB_Source_Tarball/>

Creating the MariaDB Binary Tarball
===================================

    How to generate binary tar.gz files.

 * [Setup your build environment](../linux_build_environment_setup/index).
* [Build binaries](http://kb.askmonty.org/en/generic-build-instructions) with your preferred options/plugins.

 If the binaries are already built, you can generate a binary tarball with

 
```
make package

```

Prior to [MariaDB 5.5](../what-is-mariadb-55/index), the following steps were required:

 * Use `make_binary_distribution` to generate a binary tar file:

 
```
cd mariadb-source
./scripts/make_binary_distribution

```

This creates a source file with a name like `mariadb-5.3.2-MariaDB-beta-linux-x86_64.tar.gz` in your current directory.

 The other option is to use the bakery scripts. In this case you don't have to compile MariaDB source first.

 
```
cd $PACKAGING_WORK
bakery/preheat.sh
cd bakery_{number}
bakery/tarbake51.sh last:1 $MARIA_WORK
bakery/autobake51-bintar.sh mariadb-{version_num}-maria-beta-ourdelta{number}.tar.gz

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-the-mariadb-binary-tarball/>

Build Environment Setup for Mac
===============================

    XCode
-----

 * Install Xcode from Apple (free registration required): <https://developer.apple.com/xcode/> or from your Mac OS X installation disk (macports needs XCode >= 3.1, so if you do not have that version or greater you will need to download the latest version, which is 900+ MB)

 You can install the necessary dependencies using either MacPorts or Homebrew.

 Using MacPorts
--------------

 * [Download](http://svn.macports.org/repository/macports/downloads/) and install the MacPorts dmg image from <http://www.macports.org>

 * After installing, update it from the terminal: `sudo port -v selfupdate`

 `sudo port install cmake jemalloc judy openssl boost gnutls`

 Using Homebrew
--------------

 * Download and install Homebrew from [https:*brew.sh*](https://brew.sh/)

 `brew install cmake jemalloc traildb/judy/judy openssl boost gnutls`

 Your Mac should now have everything it needs to get, compile, and otherwise work with the MariaDB source code. The next step is to actually get a copy of the code. For help with this see the [Getting the MariaDB Source Code](../getting_the_mariadb_source_code/index) page.

 When building with Mac, you'll need `-DOPENSSL_ROOT_DIR=/usr/local/openssl` passed as a `cmake` argument to build against openssl correctly.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Build_Environment_Setup_for_Mac/>

Building MariaDB from a Source RPM
==================================

    For some distributions you can build MariaDB from a source RPM. (See also [Why Source RPMs (SRPMs) Aren't Packaged For Some Platforms](../why-source-rpms-srpms-arent-packaged-for-some-platforms/index)).

 You can build it as follows:

 ### using dnf

 On RHEL8 you might need to start with:

 
```
    sudo dnf config-manager --set-enabled codeready-builder-beta-for-rhel-8-x86_64-rpms

```

Then, on all dnf distributions:

 
```
    sudo dnf install rpm-build perl-generators
    dnf download --source MariaDB
    sudo dnf builddep MariaDB-*.src.rpm
    rpmbuild --rebuild MariaDB-*.src.rpm

```

### using yum

 
```
    sudo yum install rpm-build yum-utils
    yumdownloader --source MariaDB
    sudo yum-builddep MariaDB-*.src.rpm
    rpmbuild --rebuild MariaDB-*.src.rpm

```

### using zypper

 
```
    sudo zypper in rpm-build
    sudo zypper si MariaDB
    sudo rpmbuild -bb /usr/src/packages/SPECS/MariaDB.spec

```

Or (to avoid building as root):

 
```
    sudo zypper in rpm-build
    sudo zypper si -d MariaDB
    zypper --pkg-cache-dir=`pwd` si --download-only MariaDB
    rpmbuild --rebuild mariadb/srpms/MariaDB-*.src.rpm

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-from-a-source-rpm/>

Building MariaDB on CentOS
==========================

     In the event that you are using the Linux-based operating system CentOS or any of its derivatives, you can optionally compile MariaDB from source code. This is useful in cases where you want use a more advanced release than the one that's available in the official repositories, or when you want to enable certain feature that are not otherwise accessible.

 Installing Build Dependencies for [MariaDB 5.5](../what-is-mariadb-55/index)
----------------------------------------------------------------------------

 Before you start building MariaDB, you first need to install the build dependencies required to run the compile. CentOS provides a tool for installing build dependencies. The `yum-builddep` utility reads a package and generates a list of the packages required to build from source, then calls YUM to install them for you. In the event that this utility is not available on your system, you can install it through the `yum-utils` package. Once you have it, install the MariaDB build dependencies.

 
```
yum install yum-utils
yum-builddep mariadb-server

```

Running the above command installs many of the build dependencies, but it **doesn't install all of them**. It will only install dependencies for [MariaDB 5.5](../what-is-mariadb-55/index), which is not enough if you want to compile a newer MariaDB version!

 Installing Build Dependencies for newer MariaDB versions
--------------------------------------------------------

 The following commands installs all packages needed to get and compile [MariaDB 10.11](../what-is-mariadb-1011/index):

 
```
yum install git
yum install gcc
yum install gcc-c++
yum install tar make cmake
yum install bison
yum install ncurses-devel
yum install openssl openssl-devel
yum install snappy snappy-devel
yum install valgrind
yum install libcurl-devel
yum install gzip
yum install zlib-devel
yum install lz4-devel
yum install lzo-devel
yum install bzip2-devel
yum install libxml2-devel
yum install libevent-devel
yum install libaio-devel
yum install boost
yum install pcre2-devel
yum install systemd-devel
yum install rpm-build
yum install libaio-devel
yum install zstd
yum install pam-devel
yum install checkpolicy
yum install policycoreutils-python
yum install galera.x86_64

```

You can replace `openssl` with `gnutls` above, depending on the TLS implementation you want to use.

 If you plan to use the BUILD scripts to make it easier to build different configurations of MariaDB, then you should also install ccache to speed up your compilations:

 
```
yum install ccache

```

If you want to test the MariaDB installation, with the include mysql-test-run (mtr) system, you also need to install and configure cpan:

 
```
yum install cpan
# Complete Perl installing with the next command. Use the default answer to all questions
cpan App::cpanminus

```

For more information on dependencies, see [Linux Build Environment](../build_environment_setup_for_linux/index).

 Building MariaDB
----------------

 Once you have the base dependencies installed, you can retrieve the source code and start building MariaDB. The source code is available on GitHub. Use the `--branch` option to specify the particular version of MariaDB you want to build.

 
```
$ git clone --branch 10.11 https://github.com/MariaDB/server.git

```

With the source repository cloned onto your system, you can start building MariaDB. Run CMake to ready MariaDB for the build,

 
```
$ cmake -DRPM=centos7 server/

```

Once CMake readies the relevant Makefile for your system, use Make to build MariaDB.

 
```
$ umask 0022
$ make package

```

This generates an RPM file, which you can then install on your system or copy over to install on other CentOS hosts. The umask is needed because of a bug in cmake / cmake scripts.

 Alternative, use one of the build scripts in the `BUILD` directory that allows you to compile different versions of MariaDB (debug, optimized, profiling etc).

 A good option for developers is:

 
```
./BUILD/compile-pentium64-debug

```

Creating MariaDB-compat package
-------------------------------

 MariaDB-compat package contains libraries from older MariaDB releases. They cannot be built from the current source tree, so cpack creates them by repackaging old MariaDB-shared packages. If you want to have -compat package created, you need to download MariaDB-shared-5.3 and MariaDB-shared-10.1 rpm packages for your architecture (any minor version will do) and put them *one level above* the source tree you're building. CMake will pick them up and create a MariaDB-compat package. CMake reports it as

 
```
$ ls ../*.rpm
../MariaDB-shared-10.1.17-centos7-x86_64.rpm
../MariaDB-shared-5.3.12-122.el5.x86_64.rpm
$ cmake -DRPM=centos7 .
...
Using ../MariaDB-shared-5.3.12-122.el5.x86_64.rpm to build MariaDB-compat
Using ../MariaDB-shared-10.1.17-centos7-x86_64.rpm to build MariaDB-compat

```

Additional Dependencies
-----------------------

 In the event that you miss a package while installing build dependencies, CMake may continue to fail after you install the necessary packages. If this happens to you, delete the CMake cache then run the above the command again:

 
```
$ rm CMakeCache.txt

```

When CMake runs through the tests again, it should now find the packages it needs, instead of the cache telling it they're unavailable.

 More about CMake and CPackRPM
-----------------------------

 See also [building RPM packages from source](../building-rpm-packages-from-source/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/source-building-mariadb-on-centos/>

Building MariaDB on Fedora
==========================

    In the event that you are using the Linux-based operating system Fedora or any of its derivatives and would like to compile MariaDB from source code, you can do so using the MariaDB build in the official repositories. 

 Installing Build Dependencies
-----------------------------

 MariaDB requires a number of packages to compile from source. Fortunately, you can use the package in the Fedora repository to retrieve most of the relevant build dependencies through DNF.

 
```
# dnf builddep mariadb-server

```

Running DNF in this way pulls the build dependencies for the release of MariaDB compiled by your version of Fedora. These may not be all the dependencies you need to build the particular version of MariaDB you want to use, but it will retrieve most of them.

 You'll also need to install Git to retrieve the source repository:

 
```
# dnf install git

```

Building MariaDB
----------------

 Once you have the base dependencies installed, you can retrieve the source code and start building MariaDB. The source code is available on GitHub. Use the `--branch` option to specify the particular version of MariaDB you want to build.

 
```
$ git clone --branch 10.3 https://github.com/MariaDB/server.git mariadb-server

```

With the source repository cloned onto your system, you can start building MariaDB. Change into the new `mariadb-server/` directory and run CMake to prepare the build.

 
```
$ mkdir mariadb-build
$ cd mariadb-build
$ cmake -DRPM=fedora ../mariadb-server

```

Once CMake readies the relevant Makefile for your system, use Make to build MariaDB.

 
```
$ make package

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-on-fedora/>

Building MariaDB on Windows
===========================

    Build Requirements
------------------

 To build MariaDB you need the following:

 * [Visual C++](http://www.microsoft.com/visualstudio): We currently support Visual Studio 2019 and 2022. Generally we try to support the two most recent VS versions, but build ourselves using the last one. Community editions will work fine; we only use them in our builds. While installing Visual Studio, make sure to [add "Desktop Development with C++"](https://mariadb.com/kb/en/Building_MariaDB_on_Windows/+image/vs2019_workloads).

 * [CMake](https://cmake.org/download): We recommend the latest release. Older releases might not support your version of Visual Studio. Visual Studio 2019 requires cmake 3.14 at least.

 * [Git](https://git-scm.com/download): Required to build newer versions from the source tree.
	+ NOTE: run

 
```
git config --global core.autocrlf input

```

after the installation, otherwise some mtr tests will fail

 In the "Adjusting your PATH" dialog, choose "Use Git from Windows command prompt", otherwise wrong (mingw64) git and perl will be in your PATH

 * [Bison from GnuWin32](http://gnuwin32.sourceforge.net/packages/bison.htm): Bison creates parts of the SQL parser. Choose "Complete package except sources" when downloading.
	+ NOTE:  **Do not** install this into your default path with spaces (e.g. under `C:\Program Files\GnuWin32`); the build will break due to [this bison bug](http://sourceforge.net/tracker/index.php?func=detail&aid=2788969&group_id=23617&atid=379173). Instead, install into `C:\GnuWin32`.
	+ Add `C:\GnuWin32\bin` to your system `PATH` after installation.
* [Strawberry perl](http://strawberryperl.com): Used to run the test suite. [ActiveState Perl](http://www.activestate.com/activeperl/downloads) is another Win32 Perl distribution and should work as well (but it is not as well tested). NOTE: Cygwin or mingw Perl versions **will not work** for testing. Use Windows native Perl, please.
* Optional: If you intend to build the MSI packages, install [Windows Installer XML](https://wixtoolset.org/releases/) . If you build MSI with 10.4, also modify your Visual Studio installation, add "Redistributable MSMs" (see [MDEV-22555](https://jira.mariadb.org/browse/MDEV-22555))

 * [Gnu Diff](http://gnuwin32.sourceforge.net/packages/diffutils.htm), needed if you run mysql-test-run.pl tests.

 Verify that bison.exe, or git.exe, cmake.exe and perl.exe can be found in the PATH environment variable with "`where bison`", "`where git`", "`where perl`" etc. from the command line prompt.

 Building Windows Binaries
-------------------------

 The above instructions assume [MariaDB 10.2](../what-is-mariadb-102/index) or higher. 

 Branch the MariaDB repository, or unpack the source archive. On the command prompt, switch to your source directory, then execute:

 
```
mkdir bld
cd bld
cmake ..
cmake --build . --config RelWithDebInfo

```

The above example builds a release configured for 64 bit systems in a subdirectory named `bld`. "`cmake ...`" is the configuration step, "`cmake --build . --config Relwithdebinfo`" is the build step.

 Build Variations
----------------

 ### Debug Builds

 Building Debug version is done with:

 
```
cmake --build . --config Debug

```

### 32bit and 64 bit Builds

 #### Build 64 bit binary

 Visual Studio 2019-2022 cmake generator will use host architecture by default, that is, with the steps above, cmake will build x64 binaries on x64 machine.

 #### Build 32 bit binary

 pass -A Win32 parameter for CMake, like this

 
```
cmake .. -A Win32

```

Historical note: With Visual Studio 2017 and earlier, one had to pass the name of 32bit generator ,e.g cmake .. -G "Visual Studio 15 2017"

 For a complete list of available generators, call "cmake" without any parameters.

 ### IDE Builds

 Instead of calling "`cmake --build`" as above, open `MySQL.sln`. When Visual Studio starts, choose Build/Compile.

 Building the ZIP Package
------------------------

 
```
cmake --build . --config relwithdebinfo --target package

```

This is how it is "done by the book", standard cmake target.

 MariaDB however uses non-standard target "win\_package" for the packaging for its releases, it generates 2 ZIPs, a slim one with executables, and another one with debuginfo (.PDB files). The debuginfo is important to be able to debug released binaries, and to analyze crashes.

 
```
cmake --build . --config relwithdebinfo --target win_package

```

Building the MSI Package
------------------------

 
```
cmake --build . --config relwithdebinfo 
cmake --build . --config relwithdebinfo --target MSI

```

Including HeidiSQL in the MSI Installer
---------------------------------------

 Starting with [MariaDB 5.2.7](https://mariadb.com/kb/en/mariadb-527-release-notes/), it is possible to build an installer which includes 3rd party products, as described in [MWL#200](http://askmonty.org/worklog/Other/?tid=200). Currently only [HeidiSQL](http://www.heidisql.com) support is implemented; it is also included in the official builds. Use the CMake parameter `-DWITH_THIRD_PARTY=HeidiSQL` to include it in the installer.

 Code Signing
------------

 MariaDB builds optionally support authenticode code signing with an optional parameter `SIGNCODE`. Use `cmake -DSIGNCODE=1` during the configuration step to sign the binaries in the `ZIP` and `MSI` packages.

 **Important:** for `SIGNCODE=1` to work, the user that runs the build needs to install a valid authenticode digital certificate into their certificate store, otherwise the packaging step will fail.

 Building Packages for MariaDB Releases
--------------------------------------

 The full script to create the release in an out-of-source build with Visual Studio with signed binaries might look like:

 
```
mkdir bld
cd bld
cmake .. -DSIGNCODE=1 -DWITH_THIRD_PARTY=HeidiSQL
cmake --build . --config relwithdebinfo --target win_package
cmake --build . --config relwithdebinfo  --target MSI

```

This command sequence will produce a ZIP package (e.g mariadb-5.2.6-win32.zip) and MSI package (e.g mariadb-5.2.6-win32.msi) in the `bld` directory.

 Running Tests
-------------

 * **Important: Do not use Cygwin** bash, MinGW bash, Git bash, WSL bash, or any other bash when running the test suite. You will then very likely use the wrong version of Perl too (a "Unix-flavoured" one on Windows), and spend a lot of time trying to figure out why this version of Perl does not work for the test suite. Use native perl, in cmd.exe , or powershell instead,

 * Switch mysql-test subdirectory of the build directory

 
```
cd C:\server\bld\mysql-test

```

* Run the test suite

 
```
perl mysql-test-run.pl --suite=main --parallel=auto

```

### Running a Test Under Debugger

 Assuming VS is installed on the machine

 
```
perl mysql-test-run.pl  <test_name> --vsjitdebugger

```

If vsjitdebugger does not start, you can edit AeDebug registry key as mentioned in 

 <https://docs.microsoft.com/en-us/visualstudio/debugger/debug-using-the-just-in-time-debugger?view=vs-2019#jit_errors>

 Alternatively:

 
```
perl mysql-test-run.pl  <test_name> --devenv 

```

(devenv.exe needs to be in PATH)

 or, if you prefer WinDBG

 
```
perl mysql-test-run.pl  <test_name> --windbg

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Building_MariaDB_on_Windows/>

Compiling with the InnoDB Plugin from Oracle
============================================

    From [MariaDB 10.2](../what-is-mariadb-102/index), MariaDB uses InnoDB as the default storage engine. Before [MariaDB 10.2](../what-is-mariadb-102/index), MariaDB came by default with [XtraDB](../xtradb/index), an enhanced version of the InnoDB plugin that comes from Oracle.

 If you want to use Oracle's InnoDB plugin, then you need to compile MariaDB and **not** specify `--without-plugin-innodb_plugin` when configuring. For example, a simple `./configure` without any options will do.

 When the InnoDB plugin is compiled, the innodb\_plugin test suite will test the InnoDB plugin in addition to xtradb:

 
```
./mysql-test-run --suite=innodb_plugin

```

To use the innodb\_plugin instead of xtradb you can do (for [MariaDB 5.5](../what-is-mariadb-55/index)):

 
```
mysqld --ignore-builtin-innodb --plugin-load=innodb=ha_innodb.so \
--plugin_dir=/usr/local/mysql/lib/mysql/plugin

```

See Also
--------

 <http://dev.mysql.com/doc/refman/5.1/en/replacing-builtin-innodb.html>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-with-the-innodb-plugin-from-oracle/>

Installing MariaDB Server on macOS Using Homebrew
=================================================

     MariaDB Server is available for installation on macOS (formerly Mac OS X) via the [Homebrew](http://brew.sh/) package manager. 

 MariaDB Server is available as a Homebrew "bottle", a pre-compiled package. This means you can install it without having to build from source yourself. This saves time.

 After installing Homebrew, MariaDB Server can be installed with this command:

 
```
brew install mariadb

```

After installation, start MariaDB Server:

 
```
mysql.server start

```

To auto-start MariaDB Server, use Homebrew's services functionality, which configures auto-start with the launchctl utility from [launchd](../launchd/index):

 
```
brew services start mariadb

```

After MariaDB Server is started, you can log in as your user:

 
```
mysql

```

Or log in as root:

 
```
sudo mysql -u root

```

Upgrading MariaDB
-----------------

 First you may need to update your brew installation:

 
```
brew update

```

Then, to upgrade MariaDB Server:

 
```
brew upgrade mariadb

```

Building MariaDB Server from source
-----------------------------------

 In addition to the "bottled" MariaDB Server package available from Homebrew, you can use Homebrew to build MariaDB from source. This is useful if you want to use a different version of the server or enable some different capabilities that are not included in the bottle package.

 Two components not included in the bottle package (as of MariaDB Server 10.1.19) are the CONNECT and OQGRAPH engines, because they have non-standard dependencies. To build MariaDB Server with these engines, you must first install `boost` and `judy`. As of December 2016, judy is in the Homebrew "boneyard", but the old formula still works on macOS Sierra. Follow these steps to install the dependencies and build the server:

 
```
brew install boost homebrew/boneyard/judy
brew install mariadb --build-from-source

```

You can also use Homebrew to build and install a pre-release version of MariaDB Server (for example MariaDB Server 10.2, when the highest GA version is MariaDB Server 10.1). Use this command to build and install a "development" version of MariaDB Server:

 
```
brew install mariadb --devel

```

Other resources
---------------

 * [mariadb.rb on github](https://github.com/mxcl/homebrew/commit/debd033ad7bcd73df68d7370d7f2386e60fd24a0#Library/Formula/mariadb.rb)
* [Terin Stock (terinjokes)](https://github.com/terinjokes) who is the packager for Homebrew
* [MariaDB Server on macOS: Does it even make sense to try?](https://www.youtube.com/watch?v=VoAPP6GDyYw) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-on-macos-using-homebrew/>

Installing MariaDB MSI Packages on Windows
==========================================

    MSI packages are available for both x86 (32 bit) and x64 (64 bit) processor architectures. We'll use screenshots from an x64 installation below (the 32 bit installer is very similar).

 Installation UI
---------------

 This is the typical mode of installation. To start the installer, just click on the mariadb-<major>.<minor>.<patch>.msi

 ### Welcome

 ![Welcome dialog]

 ### License Agreement

 ![License Agreement]

 Click on "I accept the terms"

 ### Custom Setup

 ![Custom Setup]

 Here, you can choose what features to install. By default, all features are installed with the exception of the debug symbols. If the "Database instance" feature is selected, the installer will create a database instance, by default running as a service. In this case the installer will present additional dialogs to control various database properties. Note that you do not necessarily have to create an instance at this stage. For example, if you already have MySQL or MariaDB databases running as services, you can just upgrade them during the installation. Also, you can create additional database instances after the installation, with the `[mysql\_install\_db.exe](../mysql_install_dbexe/index)` utility.

 
**NOTE**: By default, if you install a database instance, the data directory will be in the "data" folder under the installation root. To change the data directory location, select "Database instance" in the feature tree, and use the "Browse" button to point to another place.

 
### Database Authentication/Security Related Properties

 ![Database security properties]

 This dialog is shown if you selected the "Database instance" feature. Here, you can set the password for the "root" database user and specify whether root can access database from remote machines. The "Create anonymous account" setting allows for anonymous (non-authenticated) users. It is off by default and it is not recommended to change this setting.

 ### Other Database Properties

 ![Other database properties]

 * Install as service

 * Defines whether the database should be run as a service. If it should be run as a service, then it also defines the service name. It is recommended to run your database instance as a service as it greatly simplifies database management. In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the default service name used by the MSI installer is "MariaDB". In 10.3 and before, the default service name used by the MSI installer is "MySQL". Note that the default service name for the `[--install](../mysqld-options/index#-install)` and `[--install-manual](../mysqld-options/index#-install-manual)` options for `mysqld.exe` is "MySQL" in all versions of MariaDB.

 * Enable Networking

 * Whether to enable TCP/IP (recommended) and which port MariaDB should listen to. If security is a concern, you can change the [bind-address](../server-system-variables/index#bind_address) parameter post-installation to bind to only local addresses. If the "Enable networking" checkbox is deselected, the database will use named pipes for communication.

 * Optimize for Transactions

 * If this checkbox is selected, the default storage engine is set to Innodb (or XtraDB) and the `sql_mode` parameter is set to "`NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES`". You can also define the Innodb/Xtradb buffer pool size. The default buffer pool size is 12.5% of RAM and depending on your requirements you can give innodb more (up to 70-80% RAM). 32 bit versions of MariaDB have restrictions on maximum buffer pool size, which is approximately 1GB, due to virtual address space limitations for 32bit processes.

 ### Ready to Install

 ![Ready Dialog]

 At this point, all installation settings are collected. Click on the "Install" button.

 ### End

 ![Finish]

 Installation is finished now. If you have upgradable instances of MariaDB/MySQL, running as services, this dialog will present a "Do you want to upgrade existing instances" checkbox (if selected, it launches the Upgrade Wizard post-installation).

 If you installed a database instance as service, the service will be running already. 

 New Entries in Start Menu
-------------------------

 Installation will add some entries in the Start Menu:

 ![Start Menu](https://mariadb.com/kb/en/installing-mariadb-msi-packages-on-windows/+image/StartMenu_New "Start Menu")

 * MariaDB Client - Starts command line client mysql.exe

 * Command Prompt - Starts a command prompt. Environment is set such that "bin" directory of the installation is included into PATH environment variable, i.e you can use this command prompt to issue MariaDB commands (mysqldadmin, mysql etc...)

 * Database directory - Opens the data directory in Explorer.

 * Error log - Opens the database error log in Notepad.

 * my.ini - Opens the database configuration file my.ini in Notepad.

 * Upgrade Wizard - Starts the Wizard to upgrade an existing MariaDB/MySQL database instance to this MariaDB version.

 Uninstall UI
------------

 In the Explorer applet "Programs and Features" (or "Add/Remove programs" on older Windows), find the entry for MariaDB, choose Uninstall/Change and click on the "Remove" button in the dialog below.

 ![UninstallChangeDialog_New]

 If you installed a database instance, you will need to decide if you want to remove or keep the data in the database directory.

 ![KeepOrRemoveDataDialog_New]

 Silent Installation
-------------------

 The MSI installer supports silent installations as well. In its simplest form silent installation with all defaults can be performed from an elevated command prompt like this:

 
```
  msiexec /i path-to-package.msi /qn

```


**Note:** the installation is silent due to msiexe.exe's /qn switch (no user interface), if you omit the switch, the installation will have the full UI.

 
### Properties

 Silent installations also support installation properties (a property would correspond for example to checked/unchecked state of a checkbox in the UI, user password, etc). With properties the command line to install the MSI package would look like this:

 
```
msiexec /i path-to-package.msi [PROPERTY_1=VALUE_1 ... PROPERTY_N=VALUE_N] /qn

```

The MSI installer package requires property names to be all capitals and contain only English letters. By convention, for a boolean property, an empty value means "false" and a non-empty is "true".

 MariaDB installation supports the following properties:

 


| Property name | Default value | Description |
| --- | --- | --- |
| INSTALLDIR | %ProgramFiles%\MariaDB <version>\ | Installation root |
| PORT | 3306 | --port parameter for the server |
| ALLOWREMOTEROOTACCESS |  | Allow remote access for root user |
| BUFFERPOOLSIZE | RAM/8 | Bufferpoolsize for innodb |
| CLEANUPDATA | 1 | Remove the data directory (uninstall only) |
| DATADIR | INSTALLDIR\data | Location of the data directory |
| DEFAULTUSER |  | Allow anonymous users |
| PASSWORD |  | Password of the root user |
| SERVICENAME |  | Name of the Windows service. A service is not created if this value is empty. |
| SKIPNETWORKING |  | Skip networking |
| STDCONFIG | 1 | Corresponds to "optimize for transactions" in the GUI, default engine innodb, strict sql mode |
| UTF8 |  | if set, adds character-set-server=utf8 to my.ini file |
| PAGESIZE | 16K | page size for innodb |

 
### Features

  *Feature* is a Windows installer term for a unit of installation. Features can be selected and deselected in the UI in the feature tree in the "Custom Setup" dialog.

 Silent installation supports adding features with the special property `ADDLOCAL=Feature_1,..,Feature_N` and removing features with `REMOVE=Feature_1,..., Feature_N`

 Features in the MariaDB installer:

 


| Feature id | Installed by default? | Description |
| --- | --- | --- |
| DBInstance | yes | Install database instance |
| Client | yes | Command line client programs |
| MYSQLSERVER | yes | Install server |
| SharedLibraries | yes | Install client shared library |
| DEVEL | yes | install C/C++ header files and client libraries |
| HeidiSQL | yes | Installs HeidiSQL |

 
### Silent Installation Examples

 All examples here require running as administrator (and elevated command line in Vista and later)

 * Install default features, database instance as service, non-default datadir and port 
```
msiexec /i path-to-package.msi SERVICENAME=MySQL DATADIR=C:\mariadb5.2\data PORT=3307 /qn 
```

 * Install service, add debug symbols, do not add development components (client libraries and headers) 
```
msiexec /i path-to-package.msi SERVICENAME=MySQL ADDLOCAL=DEBUGSYMBOLS REMOVE=DEVEL /qn
```

 ### Silent Uninstall

 To uninstall silently, use the `REMOVE=ALL` property with msiexec:



```
msiexec /i path-to-package.msi REMOVE=ALL /qn
```
 To keep the data directory during an uninstall, you will need to pass an additional parameter:



```
msiexec /i path-to-package.msi REMOVE=ALL CLEANUPDATA="" /qn
```
 Installation Logs
-----------------

 If you encounter a bug in the installer, the installer logs should be used for diagnosis. Please attach verbose logs to the bug reports you create. To create a verbose installer log, start the installer from the command line with the `/l*v` switch, like so:

 
```
  msiexec.exe /i path-to-package.msi  /l*v path-to-logfile.txt

```

Running 32 and 64 Bit Distributions on the Same Machine
-------------------------------------------------------

 It is possible to install 32 and 64 bit packages on the same Windows x64. 

 Apart from testing, an example where this feature can be useful is a development scenario, where users want to run a 64 bit server and develop both 32 and 64 bit client components. In this case the full 64 bit package can be installed, including a database instance plus development-related features (headers and libraries) from the 32 bit package.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-msi-packages-on-windows/>

Building MariaDB on Debian
==========================

     In the event that you are using the Linux-based operating system Debian or any of its direct derivatives and would like to compile MariaDB from source code, you can do so using the MariaDB source repository for the release that interests you. For Ubuntu and its derivatives, see [Building on Ubuntu](../building-mariadb-on-ubuntu/index).

 Before you begin, install the `software-properties-common` and `devscripts` packages: 

 
```
$ sudo apt-get install -y software-properties-common \
      devscripts

```

Installing Build Dependencies
-----------------------------

 MariaDB requires a number of packages to compile from source. Fortunately, you can use the MariaDB repositories to retrieve the necessary code for the version you want. Use the [Repository Configuration](https://downloads.mariadb.org/mariadb/repositories/) tool to determine how to set up the MariaDB repository for your release of Debian, the version of MariaDB that you want to install, and the mirror that you want to use.

 First add the authentication key for the repository, then add the repository.

 
```
$ sudo apt-key adv --recv-keys \
      --keyserver hkp://keyserver.ubuntu.com:80 \
      0xF1656F24C74CD1D8
$ sudo add-apt-repository 'deb [arch=amd64] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.3/debian stretch main'

```

The second command added text to the `/etc/apt/sources.list` file. One of these lines is the repository containing binary packages for MariaDB, the other contains the source packages. The line for the source packages is commented out by default. This can be scripted:

 
```
sed -e '/^# deb-src.*mariadb/s/^# //' -i /etc/apt/sources.list

```

Alternately, open the file using your preferred text editor and uncomment the source repository.

 
```
$ sudo vim /etc/apt/sources.list

...
deb [arch=amd64] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.3/debian stretch main
deb-src [arch=amd64] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.3/debian stretch main

```

Once the repository is set up, you can use `apt-get` to retrieve the build dependencies. MariaDB packages supplied by Ubuntu and packages supplied by the MariaDB repository have the same base name of `mariadb-server`. You need to specify the specific version you want to retrieve.

 
```
$ sudo apt-get update
$ sudo apt-get build-dep -y mariadb-server-10.3

```

Building MariaDB
----------------

 Once you have the base dependencies installed, you can retrieve the source code and start building MariaDB. The source code is available on GitHub. Use the `--branch` option to specify the particular version of MariaDB you want to build.

 
```
$ git clone --branch 10.3 https://github.com/MariaDB/server.git

```

The source code includes scripts to install the remaining build dependencies. For Ubuntu, they're located in the `debian/` directory. Navigate into the repository and run the `autobake-deb.sh` script. Then use 

 
```
$ export DEB_BUILD_OPTIONS=parallel=$(nproc)
$ cd server/
$ ./debian/autobake-deb.sh

```

### After Building

 After building the packages, it is a good idea to put them in a repository. See the [Creating a Debian Repository](../creating_a_debian_repository/index) page for instructions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-on-debian/>

Building MariaDB on FreeBSD
===========================

     It is relatively straightforward to build MariaDB from source on FreeBSD. When working with an individual host, you can use Ports to compile particular or multiple versions of MariaDB. When working with multiple hosts, you can use Poudriere to build MariaDB once, then serve it as a package to multiple FreeBSD hosts.

 Using Ports
-----------

 The FreeBSD Ports Collection provides a series of Makefiles that you can use to retrieve source code, configure builds, install dependencies and compile software. This allows you to use more advanced releases than what is normally available through the package managers as well as enable any additional features that interest you.

 In the event that you have not used Ports before on your system, you need to first fetch and extract the Ports tree. This downloads the Ports tree from FreeBSD and extracts it onto your system, placing the various Makefiles, patches and so on in the `/usr/ports/` directory.

 
```
# portsnap fetch extract

```

In the event that you have used Ports before on this system, run Portsnap again to download and install any updates to the Ports tree.

 
```
# portsnap fetch update

```

This ensures that you are using the most up to date release of the Ports tree that is available on your system.

 ### Building MariaDB from Ports

 Once Portsnap has installed or updated your Ports tree, you can change into the relevant directory and install MariaDB. Ports for MariaDB are located in the `/usr/ports/databases/` directory.

 
```
$ ls /usr/ports/databases | grep mariadb

mariadb-connector-c
mariadb-connector-odbc
mariadb100-client
mariadb100-server
mariadb101-client
mariadb101-server
mariadb102-client
mariadb102-server
mariadb103-client
mariadb103-server
mariadb55-client
mariadb55-server

```

Note that FreeBSD treats the Server and Client as separate packages. The Client is a dependency of the Server, so you only need to build the Server to get both. It also provides a number of different versions. You can search the available ports from [Fresh Ports](http://www.freshports.org/databases). Decide what version of MariaDB you want to install, the change into the relevant directory. Once in the directory, run Make to build MariaDB. 

 
```
# cd /usr/ports/databases/mariadb103-server
# make

```

In addition to downloading and building MariaDB, Ports also downloads and build any libraries on which MariaDB depends. Each port it builds will take you to a GUI window where you can select various build options. In the case of MariaDB, this includes various storage engines and specific features you need in your build.

 Once you finish building the ports, install MariaDB on your system and clean the directory to free up disk space.

 
```
# make install clean

```

This installs FreeBSD on your server. You can now enable, configure and start the service as you normally would after installing MariaDB from a package.

 Using Poudriere
---------------

 Poudriere is a utility for building FreeBSD packages. It allows you to build MariaDB from a FreeBSD Jail, then serve it as a binary package to other FreeBSD hosts. You may find this is particularly useful when building to deploy multiple MariaDB servers on FreeBSD, such as with Galera Cluster or similar deployments.

 ### Building MariaDB

 Once you've configured your host to use Jails and Poudriere, initialize a jail to use in building packages and a jail for managing ports.

 
```
# poudriere jail -c -j package-builder -v 11.2-RELEASE
# poudriere ports -c -p local-ports

```

This creates two jails, `package-builder` and `local-ports`, which you can then use to build MariaDB. Create a text file to define the packages you want to build. Poudriere will build these packages as well as their dependencies. MariaDB is located at `databases/mariadb103-server`. Adjust the path to match the version you want to install.

 
```
$ vi maraidb-package-builder.txt

databases/mariadb103-server

```

Use the `options` command to initialize the build options for the packages you want Poudriere to compile.

 
```
# poudriere options -j package-builder -p local-ports -z mariadb-builder -f mariadb-package-builder.txt

```

Lastly, use the `bulk` command to compile the packages.

 
```
# poudriere bulk -j package-builder -p local-ports -z mariadb-builder -f mariadb-package-builder.txt

```

### Using Poudriere Repositories

 In order to use Poudriere, you need to set up and configure a web server, such as Nginx or Apache to serve the directory that Poudriere built. For instance, in the case of the above example, you would map to the `package-builder` jail: `/usr/local/poudriere/data/packages/package-builder/`. You may find it useful to map this directory to a sub-domain, for instance `https*pkg.example.com*` or something similar.

 Lastly, you need to configure the FreeBSD hosts to use the Poudriere repository you just created. On each host, disable the FreeBSD official repositories and enable your Poudriere repository as an alternative.

 
```
# vi /usr/local/etc/pkg/repos/FreeBSD.conf

FreeBSD: {
      enabled: no
}

```

Then add the URL for your Poudriere repository to configuration file:

 
```
# vi /usr/local/etc/pkg/repos/mariadb.conf

custom: {
      url: "https://pkg.example.com",
      enabled: yes
}

```

You can then install MariaDB from Poudriere using the package manager.

 
```
# pkg install mariadb103-server

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-on-freebsd/>

Building MariaDB on Gentoo
==========================

    MariaDB is in Gentoo, so the steps to build it are:

 1. Synchronize your tree with 
```
emerge --sync

```
2. Build MariaDB using 
```
emerge mariadb

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Building_MariaDB_on_Gentoo/>

Building MariaDB on Solaris and OpenSolaris
===========================================

    The following two articles should help you get your Solaris machine prepared to build MariaDB (just ignore the parts about installing buildbot):

 * [Buildbot Setup for Solaris Sparc](../buildbot-setup-for-solaris-sparc/index)
* [Buildbot Setup for Solaris x86](../buildbot-setup-for-solaris-x86/index)

 Notes
-----

 * The BUILD dir contains various scripts for compiling MariaDB on Solaris. The `BUILD/compile-solaris-amd64` and `BUILD/compile-solaris-amd64-debug` are probably the most useful.

 * The scripts do not play nice with non-bash shells such as the Korn Shell (ksh). So if your /bin/sh is pointing at ksh or ksh93, you'll want to change it so that it points at bash.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-on-solaris-and-opensolaris/>

Building MariaDB on Ubuntu
==========================

     In the event that you are using the Linux-based operating system Ubuntu or any of its derivatives and would like to compile MariaDB from source code, you can do so using the MariaDB source repository for the release that interests you.

 Before you begin, install the `software-properties-common`, `devscripts` and `equivs` packages.

 
```
$ sudo apt-get install software-properties-common \
      devscripts \
      equivs

```

Installing Build Dependencies
-----------------------------

 MariaDB requires a number of packages to compile from source. Fortunately, you can use the MariaDB repositories to retrieve the necessary code for the version you want. Use the [Repository Configuration](https://downloads.mariadb.org/mariadb/repositories/) tool to determine how to set up the MariaDB repository for your release of Ubuntu, the version of MariaDB that you want to install, and the mirror that you want to use.

 First add the authentication key for the repository, then add the repository.

 
```
$ sudo apt-key adv --recv-keys \
      --keyserver hkp://keyserver.ubuntu.com:80 \
      0xF1656F24C74CD1D8
$ sudo add-apt-repository --update --yes --enable-source \
       'deb [arch=amd64] http://nyc2.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu '$(lsb_release -sc)' main'

```

Once the repository is set up, you can use `apt-get` to retrieve the build dependencies. MariaDB packages supplied by Ubuntu and packages supplied by the MariaDB repository have the same base name of `mariadb-server`. You need to specify the specific version you want to retrieve.

 
```
$ sudo apt-get build-dep mariadb-10.3

```

Building MariaDB
----------------

 Once you have the base dependencies installed, you can retrieve the source code and start building MariaDB. The source code is available on GitHub. Use the `--branch` option to specify the particular version of MariaDB you want to build.

 
```
$ git clone --branch 10.3 https://github.com/MariaDB/server.git

```

The source code includes scripts to install the remaining build dependencies. For Ubuntu, they're located in the `debian/` directory. Navigate into the repository and run the `autobake-deb.sh` script. Then use 

 
```
$ cd server/
$ ./debian/autobake-deb.sh

```


### Further Dependencies

 In the event that there are still build dependencies that are not satisfied, use `mk-build-deps` to generate a build dependency `deb` to use in installing the remaining packages.

 
```
$ mk-build-deps debian/control
$ apt-get install ./mariadb-*build-deps_*.deb

```

Then, call the `autobake-deb.sh` script again to build MariaDB.

 
```
$ ./debian/autobake-deb.sh

```


### After Building

 After building the packages, it is a good idea to put them in a repository. See the [Creating a Debian Repository](../creating_a_debian_repository/index) page for instructions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-on-ubuntu/>

Creating a Debian Repository
============================

    Below are instructions for creating your own Debian repository. The instructions are based on <http://www.debian.org/doc/manuals/repository-howto/repository-howto.en.html>

 
```
REPO_DIR={pick some location}
mkdir $REPO_DIR
mkdir $REPO_DIR/binary
mkdir $REPO_DIR/source
cp *.deb *.ddeb $REPO_DIR/binary
cd $REPO_DIR
dpkg-scanpackages binary  /dev/null | gzip -9c > binary/Packages.gz
dpkg-scansources  source  /dev/null | gzip -9c > source/Sources.gz

```

Using the Debian repository you just created
--------------------------------------------

 One needs to add a new file to the `/etc/apt/sources.list.d/` directory. For instance a new file called `mariadb.list`

 
```
# sergey's MariaDB repository
#
deb file:///home/psergey/testrepo binary/
deb-src file:///home/psergey/testrepo source/

```

after which one can run

 
```
apt-get update  # Let apt learn about the new repository
apt-get install mariadb-server

```

and collect bugs :-).

 "apt-get install" will spray output of scripts and servers all over /var/log. It is also possible to set DEBIAN\_SCRIPT\_DEBUG=1 to get some (not all) of it to stdout.

 Cleaning up after failed installation
-------------------------------------

 Run 

 
```
dpkg --get-selections | grep mariadb
dpkg --get-selections | grep mysql

```

to see what is installed, and then

 
```
 dpkg --purge <packages>

```

until the former produces empty output. Note: after some failures, /etc/mysql and /var/lib/mysql are not cleaned and still need to be removed manually.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/Creating_a_Debian_Repository/>

Building MariaDB From Source Using musl-based GNU/Linux
=======================================================

    Instructions on compiling MariaDB on musl-based operating systems (Alpine)
--------------------------------------------------------------------------

  The instructions on this page will help you compile [MariaDB](../mariadb/index) from source. Links to more complete instructions for specific platforms can be found on the [source](../source/index) page.

 * First, [get a copy of the MariaDB source](../getting-the-mariadb-source-code/index).
* Next, [prepare your system to be able to compile the source](../build-environment-setup-for-linux/index).

 Using cmake
-----------

 [MariaDB 10.1](../what-is-mariadb-101/index) and above is compiled using *cmake*. You can configure your build simply by running *cmake* using special option, i.e.

 
```
cmake . -DWITHOUT_TOKUDB=1

```

To build and install MariaDB after running *cmake* use

 
```
make
sudo make install

```

Note that building with MariaDB this way will disable tokuDB, till tokuDB becomes fully supported on musl.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-mariadb-from-source-using-musl-based-gnulinux/>

Compiling MariaDB for Debugging
===============================

    Compiling MariaDB with full debug information includes all code symbols and also new code to do internal testing of structures and allow one to trace MariaDB execution. A full debug binary will be notably slower than a normal binary (30%).

 Compiling MariaDB for Debugging Using the `CMAKE_BUILD_TYPE` Option
-------------------------------------------------------------------

 On Unix systems, you can build a debug build by executing `cmake` and by setting the `CMAKE_BUILD_TYPE` option to `Debug`. For example:

 
```
cmake -DCMAKE_BUILD_TYPE=Debug .

```

Compiling MariaDB for Debugging Using Build Scripts
---------------------------------------------------

 The other option is to use the scripts in the BUILD directory that will compile MariaDB with most common debug options and plugins:

 
```
./BUILD/compile-pentium64-debug-max

```

or alternatively if you want to use the [Valgrind](http://www.valgrind.org) memory checking tool with the [MariaDB test system](../mysqltest/index):

 
```
./BUILD/compile-pentium64-valgrind-max

```

There are separate build scripts for different configurations in the BUILD directory.

 You can find a list of the needed packages/libraries for building on Linux [here](../build_environment_setup_for_linux/index).

 ### Example of Compiling MariaDB for Debugging Using Build Scripts

 * Scripts containing "debug" in the name are for developers that want to build, develop and test MariaDB.
* Scripts containing "valgrind" in the name are for running mysqld under [[|http://valgrind.org|valgrind]]. Compiling for valgrind means that we are using another implementation of MEM\_ROOT to allow valgrind to better detect memory overruns. In addition, some memory areas are marked as used/not used to remove some false positives.
* Scripts containing "max" in the name include all normal plugins.

 Here is an example of how to compile MariaDB for debugging in your home directory with [MariaDB 5.2.9](https://mariadb.com/kb/en/mariadb-529-release-notes/) as an example:

 
```
cd ~
mkdir mariadb
cd mariadb
tar xvf mariadb-5.2.9.tar.gz
ln -s mariadb-5.2.9 current
cd current
./BUILD/compile-pentium64-debug-max

```

The last command will produce a debug version of `sql/mysqld`. If you have a system other than 64 bit Intel/AMD on Linux you can use a different `BUILD/...-debug-max` file. If this fails, you can try with:

 
```
cmake --build  .  --config Debug
make -j4

```

Building Optimized Build With Debug Symbols
-------------------------------------------

 To build MariaDB with symbols, to get better stack traces and to be able to debug the binary with `gdb`, you need to supply the `-g3` option to the `gcc` compiler.

 Just compiling with `-g3` will make the binary much bigger but the slowdown of the server should be negligible.

 One way to do this is to edit the script

 
```
BUILD/compile-pentium64-max

```

and add the -g3 last on the line with `extra_flags`, like this:

 
```
extra_flags="$pentium64_cflags $fast_cflags -g3"

```

After that you can compile MariaDB with debugging symbols by just execution the above script.

 Doing a Debug Build on Debian/Ubuntu
------------------------------------

 To build a "mysqld" binary with debugging enabled that uses the same parameters as the ones used in Debian/Ubuntu binary packages, you must do as follows (you must have a deb-src line of one of the MariaDB repositories on your /etc/apt/sources.list in order to do that):

 
```
apt-get build-dep mariadb-10.2
apt-get install cmake libaio1 libaio-dev
apt-get source mariadb-10.2
cd mariadb-10.2*
./debian/rules configure
./BUILD/compile-pentuim64-debug-all

```

Then you will have your "debugging enabled" mysqld binary in the sql/ directory.

 This binary can directly replace the one provided by the binary package that is placed on "/usr/bin/mysqld".

 ### Temporarily Installing your Debug Build

 The commands shown below replace the release `mysqld` binary with the debug `mysqld` binary that you compiled. Most importantly, they replace the binary in a way which makes it trivial to revert back to the original release `mysqld` binary.

 First, [stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Then, use the `mv` utility to rename the release `mysqld` binary:

 
```
sudo mv /usr/sbin/mysqld /usr/sbin/mysqld-orig

```

Note: Do not use the `cp` utility because that will change the file modification timestamp.

 Then, install the debug `mysqld` binary from your source tree:

 
```
sudo install ~/mariadb-10.3.14/sql/mysqld /usr/sbin/mysqld-debug

```

Then, link the `mysqld` path to the path of your debug `mysqld` binary:

 
```
sudo ln -s /usr/sbin/mysqld-debug /usr/sbin/mysqld

```

Then, [start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Be sure to replace `/usr/sbin/mysqld` with the path to your `mysqld` binary and to also replace ``~`/mariadb-10.3.14/sql/mysqld` with the path to your debug `mysqld` binary.

 ### Reinstalling your Release Build

 If you want to restore your original `mysqld` binary, you can do it with the following process::

 First, [stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Then, execute the following command to delete the symbolic link:

 
```
sudo rm /usr/sbin/mysqld

```

Then, execute the following command to move the original `mysqld` release binary back into place:

 
```
sudo mv /usr/sbin/mysqld-orig /usr/sbin/mysqld

```

Then, [start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Be sure to replace `/usr/sbin/mysqld` with the path to your `mysqld` binary

 Notice that the debug `mysqld` binary located at `/usr/sbin/mysqld-debug` was not deleted. Only the symbolic link to this file was deleted. The debug `mysqld` binary is still present if it is needed again in the future.

 Different Compilation Options
-----------------------------

 ### Changing DBUG\_ASSERT to Print to Error Log

 A debug binary has lots of code checks and asserts, that are not checked in production. This is done to get more performance when running in production. In some cases, when one is trying to find a hard-to-repeat bug, it could be beneficial to have these checks in production builds too.

 Compiling with `-DDBUG_ASSERT_AS_PRINTF` will change DBUG\_ASSERT() to print any failed check to the [error log](../error-log/index).

 
```
cmake . -DDBUG_ASSERT_AS_PRINTF

```

Enabling the above option should not have any notable impact on performance (probably < 1% slowdown). This is achieved by grouping asserts in MariaDB server code into two groups:

 * Fast checks, using `DBUG_ASSERT()`: These are converted to printing to error log.
* Slow checks, using `DBUG_SLOW_ASSERT()`. These will always be removed in production builds.

 See Also
--------

 * [Build environment setup for Linux](../build_environment_setup_for_linux/index)
* [Debugging MariaDB with a debugger](../debugging-mariadb-with-a-debugger/index)
* [Creating a trace file](../creating-a-trace-file/index)
* [Using ASAN with MariaDB](../how-to-compile-and-use-mariadb-with-addresssanitizer-asan/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-for-debugging/>

Cross-compiling MariaDB
=======================

    Buildroot
---------

 [Buildroot](https://buildroot.org/downloads/manual/manual.html#_user_guide) is a way to cross compile MariaDB and other packages into a root filesystem. In the menuconfig you need to enable "Enable C++ Support" first under "Toolchain". After C++ is enabled MariaDB is an option under "Target Packages" ->"Libraries" -> "Databases" -> "mysql support" -> "mysql variant" -> "mariadb". Also enable the "mariadb server" below the "mysql support" option.

 Details
-------

 To cross-compile with cmake you will need a toolchain file. See, for example, [here](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html?highlight=linker#cross-compiling-for-linux). Besides cmake specific variables it should have, at least

 
```
  SET(STACK_DIRECTION -1)
  SET(HAVE_IB_GCC_ATOMIC_BUILTINS 1)

```

with appropriate values for your target architecture. Normally these MariaDB configuration settings are detected by running a small test program, and it cannot be done when cross-compiling.

 Note that during the build few helper tools are compiled and then immediately used to generate more source files for this very build. When cross-compiling these tools naturally should be built for the host architecture, not for the target architecture. Do it like this (assuming you're in the mariadb source tree):

 
```
$ mkdir host
$ cd host
$ cmake ..
$ make import_executables
$ cd ..

```

Now the helpers are built and you can cross-compile:

 
```
$ mkdir target
$ cd target
$ cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/file.cmake -DIMPORT_EXECUTABLES=../host/import_executables.cmake
$ make

```

Here you invoke cmake, specifying the path to your toolchain file and the path to the `import_executables.cmake` that you have just built on the previous step. Of course, you can also specify any other cmake parameters that could be necessary for this build, for example, enable or disable specific storage engines.

 See also <https://lists.launchpad.net/maria-discuss/msg02911.html>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cross-compiling-mariadb/>

MariaDB Source Configuration Options
====================================

     All CMake configuration options for MariaDB can be displayed with:

 
```
cmake . -LH

```

See Also
--------

 * [Get the Code, Build it, Test it](https://mariadb.org/get-involved/getting-started-for-developers/get-code-build-test/) (mariadb.org)
* [Generic Build Instructions](../generic-build-instructions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-from-source-mariadb-source-configuration-options/>

Building RPM Packages From Source
=================================

    To generate RPM packages from the build, supply the `-DRPM=xxx` flag to CMake, where the value `xxx` is the name of the distribution you're building for. For example, centos7 or rocky8 or fedora36 or sles12.

 What these do are controlled in the following CMake files:

 * `cmake/cpack_rpm.cmake`
* `cmake/build_configurations/mysql_release.cmake`
* `cmake/mariadb_connector_c.cmake`

 To build the packages you should execute:

 
```
$ umask 0022
$ make packages

```

See Also
--------

 * [About the MariaDB RPM Files](../about-the-mariadb-rpm-files/index)
* [Building MariaDB on CentOS](../source-building-mariadb-on-centos/index)
* [Installing MariaDB RPM Files](../rpm/index)
* [MariaDB RPM Packages](../mariadb-rpm-packages/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-rpm-packages-from-source/>

Compile and Using MariaDB with Sanitizers (ASAN, UBSAN, TSAN, MSAN)
===================================================================

    What are Sanitizers?
--------------------

 Sanitizers are open source runtime error detectors developed by Google that are enabled during the compile step. These sanitizers add extra code during compilation that will throw exceptions when certain errors are detected.

 [AddressSanitizer (aka ASAN)](https://github.com/google/sanitizers/wiki/AddressSanitizer) is a memory error detector for C/C++. It finds a lot of the same things as [valgrind](../compiling-mariadb-for-debugging/index), but with a lot less overhead.

 * Use after free (dangling pointer dereference)
* Heap buffer overflow
* Stack buffer overflow
* Global buffer overflow
* Use after return
* Use after scope
* Initialization order bugs
* Memory leaks

 To use ASAN you need a gcc version that supports ASAN. gcc 4.8.5 and up are known to work.

 In addition to ASAN there are sanitizers for Undefined Behaviour, Thread and Memory related errors.

 [UndefinedBehaviourSanitizer (aka UBSAN)](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) 

 [ThreadSanitizer (aka TSAN)](https://clang.llvm.org/docs/ThreadSanitizer.html)

 [MemorySanitizer (aka MSAN)](https://clang.llvm.org/docs/MemorySanitizer.html)

 How to Compile MariaDB with Sanitizers
--------------------------------------

 Before using ASAN locally, please ensure that it is installed on the system:

 
```
yum install -y /usr/lib64/libasan.so.6.0.0

```

ASAN is supported in [MariaDB 10.1](../what-is-mariadb-101/index) and up.

 You can use one of the two following build commands:

 
```
cmake . -DWITH_ASAN=ON

```

or from [MariaDB 10.2](../what-is-mariadb-102/index) and up:

 
```
./BUILD/compile-pentium64-asan-max

```

Additionally, UBSAN, TSAN, and MSAN can be enabled in a similar way:

 UBSAN:

 
```
yum install -y /usr/lib64/libubsan.so.1.0.0
cmake . -DWITH_UBSAN=ON

```

TSAN:

 
```
yum install -y /usr/lib64/libtsan.so.0.0.0
cmake . -DWITH_TSAN=ON

```

MSAN:

 Note: keep in mind that only clang supports MSAN, g++ or other compilers will not work.

 
```
cmake . -DWITH_MSAN=ON

```

Running an MSAN Build
---------------------

 The time consuming aspect of building with MSAN is having instrumented system libraries. As MariaDB Foundation have built the MSAN container already for buildbot, this is how you re-use this for building locally.

 First, run the container where your current directory is the source directory:

 
```
podman run -v $PWD:/source:z -ti --user buildbot --entrypoint bash --shm-size 5G --env MSAN_SYMBOLIZER_PATH=/msan-libs/bin/llvm-symbolizer-msan --env  MSAN_OPTIONS=abort_on_error=1:poison_in_dtor=0 quay.io/mariadb-foundation/bb-worker:debian11-msan

```

Note: docker can be used instead of the lighter weight podman if you so desire.

 The shm-size is for the MTR tests which exceed the 64k default shm-size.

 All the following instructions are executed within the container. Now run the configure stage of cmake:

 
```
cmake /source -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 '-DCMAKE_C_FLAGS=-O2 -Wno-unused-command-line-argument -fdebug-macro' '-DCMAKE_CXX_FLAGS=-stdlib=libc++ -O2 -Wno-unused-command-line-argument -fdebug-macro' -DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Debug -DWITH_INNODB_BZIP2=OFF -DWITH_INNODB_LZ4=OFF -DWITH_INNODB_LZMA=OFF -DWITH_INNODB_LZO=OFF -DWITH_INNODB_SNAPPY=OFF -DPLUGIN_ARCHIVE=NO -DPLUGIN_TOKUDB=NO -DPLUGIN_MROONGA=NO -DPLUGIN_OQGRAPH=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_CONNECT=NO -DPLUGIN_SPIDER=NO -DWITH_SAFEMALLOC=OFF -DWITH_ZLIB=bundled -DWITH_SSL=bundled -DWITH_PCRE=bundled -DHAVE_LIBAIO_H=0 -DCMAKE_DISABLE_FIND_PACKAGE_URING=1 -DCMAKE_DISABLE_FIND_PACKAGE_LIBAIO=1 -DWITH_MSAN=ON -DWITH_DBUG_TRACE=OFF

```

Run the build stage:

 
```
cmake --build . --parallel 
...
[100%] Built target mariadbd
[100%] Linking CXX executable mariadb-backup
Creating mariabackup link
[100%] Built target mariadb-backup

```

As the important MTR step needs to use the instrumented libraries MTR is run using the LD\_LIBRARY\_PATH to use those.

 
```
LD_LIBRARY_PATH=/msan-libs mysql-test/mtr  --mem --big-test --force --retry=0 --skip-test=.*compression.*  --parallel=auto

```

As newer versions occur and improvements happen these instructions may change. Look at the execution on the [buildbot builder](https://buildbot.mariadb.org/#/builders/amd64-debian-11-msan) to see if any changes have been made.

 Running an ASAN Build
---------------------

 To run mysqld with instrumentation you have to set the `ASAN_OPTIONS` environment variable before starting `mysqld`. Either in your shell or in your [mysqld\_safe](../mysqld_safe/index) script.

 
```
export ASAN_OPTIONS=abort_on_error=1

```

The above command will abort any instrumented executable if any errors are found, which is good for debugging. If you set abort\_on\_error=0 all server errors are logged to your error log file (mysqld.err).

 To catch errors for other processes than the server, you can set more options, like this:

 
```
export ASAN_OPTIONS=abort_on_error=1:log_path=/tmp/asan

```

If you are seeing an incomplete stack trace for a memory allocation, you may rerun the failing test with

 
```
export ASAN_OPTIONS=abort_on_error=1:log_path=/tmp/asan:fast_unwind_on_malloc=0

```

To get core dumps of failures:

 
```
export ASAN_OPTIONS=abort_on_error=1:disable_coredump=0

```

To see all the options (or to check if an executable is instrumented), you may try the following:

 
```
ASAN_OPTIONS=help=1 extra/perror 0

```

### Using Valgrind

 The [MariaDB test system](../mysqltest/index) can use [Valgrind](http://www.valgrind.org) for finding memory leaks and wrong memory accesses. Valgrind is an instrumentation framework for building dynamic analysis tools. If Valgrind is installed on your system, you can simply use [mysql-test-run --valgrind](../mysql-test-runpl-options/index#options-for-valgrind) to run the test under Valgrind.

 See Also
--------

 * [Compiling MariaDB for debugging](../compiling-mariadb-for-debugging/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compile-and-using-mariadb-with-sanitizers-asan-ubsan-tsan-msan/>

Puppet and MariaDB
===================

   General information and hints on how to automate MariaDB deployments and configuration with Puppet.

 Puppet is an open source tool deployment, configuration and operations.

  

| Title | Description |
| --- | --- |
|  [Puppet Overview for MariaDB Users](../puppet-overview-for-mariadb-users/index) |  Overview of Puppet and how it works with MariaDB.  |
|  [Bolt Examples](../bolt-examples/index) |  How to invoke Bolt to run commands or apply roles on remote hosts.  |
|  [Puppet hiera Configuration System](../puppet-hiera-configuration-system/index) |  Using hiera to handle Puppet configuration files.  |
|  [Deploying Docker Containers with Puppet](../deploying-docker-containers-with-puppet/index) |  How to deploy and manage Docker containers with Puppet.  |
|  [Existing Puppet Modules for MariaDB](../existing-puppet-modules-for-mariadb/index) |  Links to existing Puppet modules for MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/automated-mariadb-deployment-and-administration-puppet-and-mariadb/>

Installing MariaDB RPM Files
=============================

   MariaDB provides RPM packages for several RPM-based Linux distributions. MariaDB also provides YUM/DNF and ZYpp repositories for these Linux distributions. The articles here provide information and instructions on using the RPM packages and the related repositories.

  

| Title | Description |
| --- | --- |
|  [About the MariaDB RPM Files](../about-the-mariadb-rpm-files/index) |  Describes the contents of the RPM packages that come with each MariaDB release.  |
|  [Installing MariaDB with yum/dnf](../yum/index) |  Installing MariaDB with yum or dnf on RHEL, CentOS, Fedora, and similar distros.  |
|  [Installing MariaDB with zypper](../installing-mariadb-with-zypper/index) |  How to install MariaDB with zypper on SLES, OpenSUSE, and other similar Linux distributions.  |
|  [Installing MariaDB With the rpm Tool](../installing-mariadb-with-the-rpm-tool/index) |  Downloading and installing RPM files using the rpm command  |
|  [Checking MariaDB RPM Package Signatures](../checking-mariadb-rpm-package-signatures/index) |  Steps to check MariaDB RPM package signatures  |
|  [Troubleshooting MariaDB Installs on Red Hat/CentOS](../troubleshooting-mariadb-installs-on-red-hatcentos/index) |  Issues people have encountered when installing MariaDB on Red Hat / CentOS  |
|  [MariaDB for DirectAdmin Using RPMs](../mariadb-for-directadmin-using-rpms/index) |  Using DirectAdmin when installing MariaDB with YUM  |
|  [MariaDB Installation (Version 10.1.21) via RPMs on CentOS 7](../mariadb-installation-version-10121-via-rpms-on-centos-7/index) |  Detailed steps for installing MariaDB (version 10.1.21) via RPMs on CentOS 7  |
|  [Why Source RPMs (SRPMs) Aren't Packaged For Some Platforms](../why-source-rpms-srpms-arent-packaged-for-some-platforms/index) |  Explanation for why source RPM (SRPMs) aren't packaged for some platforms  |
|  [Building MariaDB from a Source RPM](../building-mariadb-from-a-source-rpm/index) |  How to build MariaDB from a source RPM (SRPM).  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rpm/>

Installing MariaDB .deb Files
=============================

    Installing MariaDB with APT
---------------------------

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant `.deb` packages from MariaDB's repository using `[apt](http://manpages.ubuntu.com/manpages/bionic/man8/apt.8.html)`, `[aptitude](http://manpages.ubuntu.com/manpages/bionic/man8/aptitude-curses.8.html)`, [Ubuntu Software Center](https://help.ubuntu.com/community/UbuntuSoftwareCenter), [Synaptic Package Manager](https://help.ubuntu.com/community/SynapticHowto), or another package manager.

 This page walks you through the simple installation steps using `apt`.

 ### Adding the MariaDB APT repository

 We currently have APT repositories for the following Linux distributions:

 * Debian 10 (Buster)
* Debian 11 (Bullseye)
* Debian Unstable (Sid)
* Ubuntu 18.04 LTS (Bionic)
* Ubuntu 20.04 LTS (Focal)
* Ubuntu 22.04 (Jammy)
* Ubuntu 22.10 (Kinetic)
* Ubuntu 23.04 (Lunar)

 #### Using the MariaDB Package Repository Setup Script

 If you want to install MariaDB with `apt`, then you can configure `apt` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 MariaDB Corporation provides a MariaDB Package Repository for several Linux distributions that use `apt` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Package Repository setup script automatically configures your system to install packages from the MariaDB Package Repository.

 To use the script, execute the following command:

 
```
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

```

Note that this script also configures a repository for [MariaDB MaxScale](../maxscale/index) and a repository for MariaDB Tools, which currently only contains [Percona XtraBackup](../percona-xtrabackup/index) and its dependencies.

 See [MariaDB Package Repository Setup and Usage](../mariadb-package-repository-setup-and-usage/index) for more information.

 #### Using the MariaDB Repository Configuration Tool

 If you want to install MariaDB with `apt`, then you can configure `apt` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://mariadb.org/download/?t=repo-config).

 The MariaDB Foundation provides a MariaDB repository for several Linux distributions that use `apt-get` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Repository Configuration Tool can easily generate the appropriate commands to add the repository for your distribution.

 There are several ways to add the repository.

 ##### Executing add-apt-repository

 One way to add an `apt` repository is by using the `[add-apt-repository](http://manpages.ubuntu.com/manpages/bionic/man1/add-apt-repository.1.html)` command. This command will add the repository configuration to `/etc/apt/sources.list`.

 For example, if you wanted to use the repository to install [MariaDB 10.3](../what-is-mariadb-103/index) on Ubuntu 18.04 LTS (Bionic), then you could use the following commands to add the MariaDB `apt` repository:

 
```
sudo apt-get install software-properties-common
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main'

```

And then you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

##### Creating a Source List File

 Another way to add an `apt` repository is by creating a [source list](http://manpages.ubuntu.com/manpages/bionic/man5/sources.list.5.html) file in `/etc/apt/sources.list.d/`.

 For example, if you wanted to use the repository to install [MariaDB 10.3](../what-is-mariadb-103/index) on Ubuntu 18.04 LTS (Bionic), then you could create the `MariaDB.list` file in `/etc/apt/sources.list.d/` with the following contents to add the MariaDB `apt` repository:

 
```
# MariaDB 10.3 repository list - created 2019-01-27 09:50 UTC
# http://downloads.mariadb.org/mariadb/repositories/
deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main
deb-src http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main

```

And then you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

##### Using Ubuntu Software Center

 Another way to add an `apt` repository is by using [Ubuntu Software Center](https://help.ubuntu.com/community/UbuntuSoftwareCenter).

 You can do this by going to the **Software Sources** window. This window can be opened either by navigating to **Edit** > **Software Sources** or by navigating to **System** > **Administration** > **Software Sources**. 

 Once the **Software Sources** window is open, go to the **Other Software** tab, and click the **Add** button. At that point, you can input the repository information provided by the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 See [here](https://help.ubuntu.com/community/UbuntuSoftwareCenter#Managing_software_sources) for more information.

 ##### Using Synaptic Package Manager

 Another way to add an `apt` repository is by using [Synaptic Package Manager](https://help.ubuntu.com/community/SynapticHowto).

 You can do this by going to the **Software Sources** window. This window can be opened either by navigating to **System** > **Administrator** > **Software Sources** or by navigating to **Settings** > **Repositories**.

 Once the **Software Sources** window is open, go to the **Other Software** tab, and click the **Add** button. At that point, you can input the repository information provided by the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 See [here](https://help.ubuntu.com/community/SynapticHowto#Managing_Repositories) for more information.

 #### Pinning the MariaDB Repository to a Specific Minor Release

 If you wish to pin the `apt` repository to a specific minor release, or if you would like to downgrade to a specific minor release, then you can create a `apt` repository with the URL hard-coded to that specific minor release. 

 The MariaDB Foundation archives repositories of old minor releases at the following URL:

 * <http://archive.mariadb.org/>

 Archives are only of the distros and architectures supported at the time of release. For example [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10038-release-notes/) is exists for Ubuntu `precise`, `trusty`, `xenial`, `wily`, and `yakkety` obtained looking in <https://archive.mariadb.org/mariadb-10.0.38/repo/ubuntu/dists>.

 For example, if you wanted to pin your repository to [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/) on Ubuntu 20.04 LTS (Focal), then you would have to first remove any existing MariaDB repository source list file from `/etc/apt/sources.list.d/`. And then you could use the following commands to add the MariaDB `apt-get` repository:

 
```
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el,s390x] http://archive.mariadb.org/mariadb-10.5.9/repo/ubuntu/ focal main main/debug'

```

Ensure you have the [signing key installed](#Importing_the_MariaDB_GPG_Public_Key).

 Ubuntu Xenial and older will need:

 
```
sudo apt-get install -y apt-transport-https

```

And then you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

### Updating the MariaDB APT repository to a New Major Release

 MariaDB's `apt` repository can be updated to a new major release. How this is done depends on how you originally configured the repository.

 #### Updating the Major Release with the MariaDB Package Repository Setup Script

 If you configured `apt` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index), then you can update the major release that the repository uses by running the script again.

 #### Updating the Major Release with the MariaDB Repository Configuration Tool

 If you configured `apt` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/), then you can update the major release in various ways, depending on how you originally added the repository.

 ##### Updating a Repository with add-apt-repository

 If you added the `apt` repository by using the `[add-apt-repository](http://manpages.ubuntu.com/manpages/bionic/man1/add-apt-repository.1.html)` command, then you can update the major release that the repository uses by using the the `[add-apt-repository](http://manpages.ubuntu.com/manpages/bionic/man1/add-apt-repository.1.html)` command again.

 First, look for the repository string for the old version in `/etc/apt/sources.list`.

 And then, you can remove the repository for the old version by executing the `[add-apt-repository](http://manpages.ubuntu.com/manpages/bionic/man1/add-apt-repository.1.html)` command and providing the `--remove` option. For example, if you wanted to remove a [MariaDB 10.2](../what-is-mariadb-102/index) repository, then you could do so by executing something like the following:

 
```
sudo add-apt-repository --remove 'deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.2/ubuntu bionic main'

```

After that, you can add the repository for the new version with the `[add-apt-repository](http://manpages.ubuntu.com/manpages/bionic/man1/add-apt-repository.1.html)` command. For example, if you wanted to use the repository to install [MariaDB 10.3](../what-is-mariadb-103/index) on Ubuntu 18.04 LTS (Bionic), then you could use the following commands to add the MariaDB `apt` repository:

 
```
sudo apt-get install software-properties-common
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main'

```

And then you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

After that, the repository should refer to [MariaDB 10.3](../what-is-mariadb-103/index).

 ##### Updating a Source List File

 If you added the `apt` repository by creating a [source list](http://manpages.ubuntu.com/manpages/bionic/man5/sources.list.5.html) file in `/etc/apt/sources.list.d/`, then you can update the major release that the repository uses by updating the source list file in-place. For example, if you wanted to change the repository from [MariaDB 10.2](../what-is-mariadb-102/index) to [MariaDB 10.3](../what-is-mariadb-103/index), and if the source list file was at `/etc/apt/sources.list.d/MariaDB.list`, then you could execute the following:

 
```
sudo sed -i 's/10.2/10.3/' /etc/apt/sources.list.d/MariaDB.list

```

And then you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

After that, the repository should refer to [MariaDB 10.3](../what-is-mariadb-103/index).

 ### Importing the MariaDB GPG Public Key

 Before MariaDB can be installed, you also have to import the GPG public key that is used to verify the digital signatures of the packages in our repositories. This allows the `apt` utility to verify the integrity of the packages that it installs.

 * Prior to Debian 9 (Stretch), and Debian Unstable (Sid), and Ubuntu 16.04 LTS (Xenial), the id of our GPG public key is `0xcbcb082a1bb943db`. The full key fingerprint is:

 
```
1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

```

The `[apt-key](http://manpages.ubuntu.com/manpages/bionic/man8/apt-key.8.html)` utility can be used to import this key. For example:

 
```
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db

```

* Starting with Debian 9 (Stretch) and Ubuntu 16.04 LTS (Xenial), the id of our GPG public key is `0xF1656F24C74CD1D8`. The full key fingerprint is:

 
```
177F 4010 FE56 CA33 3630  0305 F165 6F24 C74C D1D8

```

The `[apt-key](http://manpages.ubuntu.com/manpages/bionic/man8/apt-key.8.html)` utility can be used to import this key. For example:

 
```
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8

```


Starting with Debian 9 (Stretch), the `[dirmngr](https://manpages.debian.org/stretch/dirmngr/dirmngr.8.en.html)` package needs to be installed before the GPG public key can be imported. To install it, execute: `sudo apt install dirmngr`

 
If you are unsure which GPG public key you need, then it is perfectly safe to import both keys.

 The command used to import the GPG public key is the same on both Debian and Ubuntu. For example:

 
```
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --secret-keyring /tmp/tmp.ASyOPV87XC --trustdb-name /etc/apt/trustdb.gpg --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
gpg: requesting key 1BB943DB from hkp server keyserver.ubuntu.com
gpg: key 1BB943DB: "MariaDB Package Signing Key <package-signing-key@mariadb.org>" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:               imported: 1

```

Once the GPG public key is imported, you are ready to install packages from the repository.

 ### Installing MariaDB Packages with APT

 After the `apt` repository is configured, you can install MariaDB by executing the `[apt-get](http://manpages.ubuntu.com/manpages/bionic/man8/apt-get.8.html)` command. The specific command that you would use would depend on which specific packages that you want to install.

 #### Installing the Most Common Packages with APT

 To Install the most common packages, first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```


**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to Install the most common packages, execute the following command:

 
```
sudo apt-get install mariadb-server galera-4 mariadb-client libmariadb3 mariadb-backup mariadb-common

```



**MariaDB [10.2](../what-is-mariadb-102/index) - [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index), to Install the most common packages, execute the following command:

 
```
sudo apt-get install mariadb-server galera mariadb-client libmariadb3 mariadb-backup mariadb-common

```


#### Installing MariaDB Server with APT

 To Install MariaDB Server, first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

Then, execute the following command:

 
```
sudo apt-get install mariadb-server

```

#### Installing MariaDB Galera Cluster with APT

 The process to install MariaDB Galera Cluster with the MariaDB `apt-get` repository is practically the same as installing standard MariaDB Server.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and later, Galera Cluster support has been included in the standard MariaDB Server packages, so you will need to install the `mariadb-server` package, as you normally would.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you also need to install the `galera-4` package to obtain the [Galera](../galera/index) 4 wsrep provider library.

 In [MariaDB 10.3](../what-is-mariadb-103/index) and before, you also need to install the `galera-3` package to obtain the [Galera](../galera/index) 3 wsrep provider library.

 To install MariaDB Galera Cluster, first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```


**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo apt-get install mariadb-server mariadb-client galera-4

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo apt-get install mariadb-server mariadb-client galera-3

```


MariaDB Galera Cluster also has a separate package that can be installed on arbitrator nodes. In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the package is called `galera-arbitrator-4` In [MariaDB 10.3](../what-is-mariadb-103/index) and before, the package is called `galera-arbitrator-3`. This package should be installed on whatever node you want to serve as the arbitrator. It can either run on a separate server that is not acting as a cluster node, which is the recommended configuration, or it can run on a server that is also acting as an existing cluster node.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to install the arbitrator package, you could execute the following command:

 
```
sudo apt-get install galera-arbitrator-4

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to install the arbitrator package, you could execute the following command:

 
```
sudo apt-get install galera-arbitrator-3

```


See [MariaDB Galera Cluster](../galera/index) for more information on MariaDB Galera Cluster.

 #### Installing MariaDB Clients and Client Libraries with APT

 In [MariaDB 10.2](../what-is-mariadb-102/index) and later, [MariaDB Connector/C](../about-mariadb-connector-c/index) has been included as the client library.

 To Install the clients and client libraries, first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

Then, in [MariaDB 10.2](../what-is-mariadb-102/index) and later, execute the following command:

 
```
sudo apt-get install mariadb-client libmariadb3

```

#### Installing Mariabackup with APT

 To install [Mariabackup](../mariabackup/index), first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

Then, execute the following command:

 
```
sudo apt-get install mariadb-backup

```

#### Installing Plugins with APT

 Some [plugins](../plugins/index) may also need to be installed.

 For example, to install the `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin, first you would have to update the package cache by executing the following command:

 
```
sudo apt update

```

Then, execute the following command:

 
```
sudo apt-get install mariadb-cracklib-password-check

```

#### Installing Older Versions from the Repository

 The MariaDB `apt` repository contains the last few versions of MariaDB. To show what versions are available, use the `[apt-cache](http://manpages.ubuntu.com/manpages/bionic/man8/apt-cache.8.html)` command:

 
```
sudo apt-cache showpkg mariadb-server

```

In the output you will see the available versions.

 To install an older version of a package instead of the latest version we just need to specify the package name, an equal sign, and then the version number.

 However, when installing an older version of a package, if `apt-get` has to install dependencies, then it will automatically choose to install the latest versions of those packages. To ensure that all MariaDB packages are on the same version in this scenario, it is necessary to specify them all. Therefore, to install [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/) from this `apt` repository, we would do the following:

 
```
sudo apt-get install mariadb-server=10.3.14-1 mariadb-client=10.3.14-1 libmariadb3=10.3.14-1 mariadb-backup=10.3.14-1 mariadb-common=10.3.14-1

```

The rest of the install and setup process is as normal.

 Installing MariaDB with dpkg
----------------------------

 While it is not recommended, it is possible to download and install the `.deb` packages manually. However, it is generally recommended to use a package manager like `apt-get`.

 A tarball that contains the `.deb` packages can be downloaded from the following URL:

 * <https://downloads.mariadb.com>

 For example, to install the [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/) `.deb` packages on Ubuntu 18.04 LTS (Bionic), you could execute the following: 

 
```
sudo apt-get update
sudo apt-get install libdbi-perl libdbd-mysql-perl psmisc libaio1 socat
wget https://downloads.mariadb.com/MariaDB/mariadb-10.4.8/repo/ubuntu/mariadb-10.4.8-ubuntu-bionic-amd64-debs.tar
tar -xvf mariadb-10.4.8-ubuntu-bionic-amd64-debs.tar
cd mariadb-10.4.8-ubuntu-bionic-amd64-debs/
sudo dpkg --install ./mariadb-common*.deb \
   ./mysql-common*.deb \
   ./mariadb-client*.deb \
   ./libmariadb3*.deb \
   ./libmysqlclient18*.deb 
sudo dpkg --install ./mariadb-server*.deb \
   ./mariadb-backup*.deb \
   ./galera-4*.deb 

```

After Installation
------------------

 After the installation is complete, you can [start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 If you are using [MariaDB Galera Cluster](../galera/index), then keep in mind that the first node will have to be [bootstrapped](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster).

 Available DEB Packages
----------------------

 The available DEB packages depend on the specific MariaDB release series.

 ### Available DEB Packages in [MariaDB 10.4](../what-is-mariadb-104/index)

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index), the following DEBs are available:

 


| Package Name | Description |
| --- | --- |
| `galera-4` | The WSREP provider for [Galera](../galera/index) 4. |
| `libmariadb3` | Dynamic client libraries. |
| `libmariadb-dev` | Development headers and static libraries. |
| `libmariadbclient18` | Virtual package to satisfy external depends |
| `libmysqlclient18` | Virtual package to satisfy external depends |
| `mariadb-backup` | [Mariabackup](../mariabackup/index) |
| `mariadb-client` | Client tools like [mariadb CLI](../mariadb-client/index), [mariadb-dump](../mariadb-dump/index), and others. |
| `mariadb-client-core` | Core client tools |
| `mariadb-common` | Character set files and `/etc/my.cnf` |
| `mariadb-plugin-connect` | The `[CONNECT](../connect/index)` storage engine. |
| `mariadb-plugin-cracklib-password-check` | The `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `mariadb-plugin-gssapi-client` | The client-side component of the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `mariadb-plugin-gssapi-server` | The server-side component of the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `mariadb-plugin-rocksdb` | The [MyRocks](../myrocks/index) storage engine. |
| `mariadb-plugin-spider` | The `[SPIDER](../spider/index)` storage engine. |
| `mariadb-plugin-tokudb` | The [TokuDB](../tokudb/index) storage engine. |
| `mariadb-server` | The server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `mariadb-server-core` | The core server. |
| `mariadb-test` | `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `mariadb-test-data` | MariaDB database regression test suite - data files |

 

### Available DEB Packages in [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index)

 
**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index), the following DEBs are available:

 


| Package Name | Description |
| --- | --- |
| `galera` | The WSREP provider for [Galera](../galera/index) 3. |
| `libmariadb3` | Dynamic client libraries. |
| `libmariadb-dev` | Development headers and static libraries. |
| `libmariadbclient18` | Virtual package to satisfy external depends |
| `libmysqlclient18` | Virtual package to satisfy external depends |
| `mariadb-backup` | [Mariabackup](../mariabackup/index) |
| `mariadb-client` | Client tools like [mariadb CLI](../mariadb-client/index), [mariadb-dump](../mariadb-dump/index), and others. |
| `mariadb-client-core` | Core client tools |
| `mariadb-common` | Character set files and `/etc/my.cnf` |
| `mariadb-plugin-connect` | The `[CONNECT](../connect/index)` storage engine. |
| `mariadb-plugin-cracklib-password-check` | The `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `mariadb-plugin-gssapi-client` | The client-side component of the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `mariadb-plugin-gssapi-server` | The server-side component of the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `mariadb-plugin-rocksdb` | The [MyRocks](../myrocks/index) storage engine. |
| `mariadb-plugin-spider` | The `[SPIDER](../spider/index)` storage engine. |
| `mariadb-plugin-tokudb` | The [TokuDB](../tokudb/index) storage engine. |
| `mariadb-server` | The server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `mariadb-server-core` | The core server. |
| `mariadb-test` | `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `mariadb-test-data` | MariaDB database regression test suite - data files |

 

Actions Performed by DEB Packages
---------------------------------

 ### Users and Groups Created

 When the `mariadb-server` DEB package is installed, it will create a user and group named `mysql`, if they do not already exist.

 See Also
--------

 * [Differences in MariaDB in Debian](../differences-in-mariadb-in-debian/index)
* [Installing MariaDB .deb Files with Ansible](../installing-mariadb-deb-files-with-ansible/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-deb-files/>

Installing MariaDB Server PKG packages on macOS
===============================================

    
MariaDB Server does not currently provide a `.pkg` installer for macOS. For information about how to install MariaDB Server on macOS using Homebrew, see [Installing MariaDB Server on macOS Using Homebrew](../installing-mariadb-on-macos-using-homebrew/index).

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-server-pkg-packages-on-macos/>

Installing MariaDB Binary Tarballs
==================================

     MariaDB Binary tarballs are named following the pattern: mariadb-VERSION-OS.tar.gz. Be sure to [download](https://mariadb.org/download) the correct version for your machine.

 
**Note:** Some older binary tarballs are marked *'(GLIBC\_2.14)'* or *'(requires GLIBC\_2.14+)'*. These binaries are built the same as the others, but on a newer build host, and they require GLIBC 2.14 or higher. Use the other binaries for machines with older versions of GLIBC installed. Run `ldd --version` to see which version is running on your distribution.

 Others are marked *'systemd'*, which are for systems with `systemd` and GLIBC 2.19 or higher.

 
To install the [binaries](http://downloads.mariadb.org), unpack the distribution into the directory of your choice and run the `[mariadb-install-db](../installing-system-tables-mariadb-install-db/index)` script.

 In the example below we install MariaDB in the `/usr/local/mysql` directory (this is the default location for MariaDB for many platforms). However any other directory should work too.

 We install the binary with a symlink to the original name. This is done so that you can easily change MariaDB versions just by moving the symlink to point to another directory.

 ### Ensure You Use the Correct my.cnf Files

 MariaDB searches for the configuration files '`/etc/my.cnf`' (on some systems '`/etc/mysql/my.cnf`') and '`~/.my.cnf`'. If you have an old `my.cnf` file (maybe from a system installation of MariaDB or MySQL) you need to take care that you don't accidentally use the old one with your new binary .tar installation.

 The normal solution for this is to ignore the `my.cnf` file in `/etc` when you use the programs in the tar file.

 This is done by [creating your own .my.cnf file](../mysqld-startup-options/index) in your home directory and telling [mariadb-install-db](../mariadb-install-db/index), [mysqld\_safe](../mysqld_safe/index) and possibly [mysql (the command-line client utility)](../mysql-client/index) to **only** use this one with the option '`--defaults-file=~/.my.cnf`'. Note that this has to be first option for the above commands!

 ### Installing MariaDB as root in /usr/local/mysql

 If you have root access to the system, you probably want to install MariaDB under the user and group 'mysql' (to keep compatibility with MySQL installations):

 
```
groupadd mysql
useradd -g mysql mysql
cd /usr/local
tar -zxvpf /path-to/mariadb-VERSION-OS.tar.gz
ln -s mariadb-VERSION-OS mysql
cd mysql
./scripts/mariadb-install-db --user=mysql
chown -R root .
chown -R mysql data

```

The symlinking with `ln -s` is recommended as it makes it easy to install many MariaDB version at the same time (for easy testing, upgrading, downgrading etc).

 If you are installing MariaDB to replace MySQL, then you can leave out the call to `mariadb-install-db`. Instead shut down MySQL. MariaDB should find the path to the data directory from your old `/etc/my.cnf` file (path may vary depending on your system).

 To start mysqld you should now do:

 
```
./bin/mysqld_safe --user=mysql &
or
./bin/mysqld_safe --defaults-file=~/.my.cnf --user=mysql &

```

To test connection, modify your $PATH so you can invoke client such as [mysql](../mysql-client/index), [mysqldump](../mysqldump/index), etc.

 
```
export PATH=$PATH:/usr/local/mysql/bin/

```

You may want to modify your .bashrc or .bash\_profile to make it permanent.

 ### Installing MariaDB as Not root in Any Directory

 Below, change /usr/local to the directory of your choice.

 
```
cd /usr/local
gunzip < /path-to/mariadb-VERSION-OS.tar.gz | tar xf -
ln -s mariadb-VERSION-OS mysql
cd mysql
./scripts/mariadb-install-db --defaults-file=~/.my.cnf

```

If you have problems with the above gunzip command line, you can instead, if you have gnu tar, do:

 
```
tar xfz /path-to/mariadb-VERSION-OS.tar.gz

```

To start mysqld you should now do:

 
```
./bin/mysqld_safe --defaults-file=~/.my.cnf &

```

### Auto Start of mysqld

 You can get mysqld (the MariaDB server) to autostart by copying the file `mysql.server` file to the right place.

 
```
cp support-files/mysql.server /etc/init.d/mysql.server

```

The exact place depends on your system. The `mysql.server` file contains instructions of how to use and fine tune it.

 For systemd installation the mariadb.service file will need to be copied from the support-files/systemd folder to the /usr/lib/systemd/system/ folder. 

 
```
cp support-files/systemd/mariadb.service /usr/lib/systemd/system/mariadb.service

```

Note that by default the /usr/ directory is write protected by systemd though, so when having the data directory in /usr/local/mysql/data as per the instructions above you also need to make that directory writable. You can do so by adding an extra service include file:

 
```
mkdir /etc/systemd/system/mariadb.service.d/

cat > /etc/systemd/system/mariadb.service.d/datadir.conf <<EOF
[Service]
ReadWritePaths=/usr/local/mysql/data
EOF

systemctl daemon-reload

```

After this you can start and stop the service using 

 
```
systemctl start mariadb.service

```

and 

 
```
systemctl stop mariadb.service 

```

respectively.

 Please refer to the [systemd](../systemd/index) page for further information.

 ### Post Installation

 After this, remember to set proper passwords for all accounts accessible from untrusted sources, to avoid exposing the host to security risks! 

 Also consider using the [mysql.server](../mysqlserver/index) to [start MariaDB automatically](../starting-and-stopping-mariadb-automatically/index) when your system boots.

 On systems using systemd you can instead enable automatic startup during system boot with

 
```
systemctl enable mariadb.service

```

instead.

 Our MariaDB binaries are similar to the Generic binaries available for the MySQL binary distribution. So for more options on using these binaries, the MySQL 5.5 manual entry on [installing generic binaries](http://docs.oracle.com/cd/E17952_01/refman-5.5-en/binary-installation.html) can be consulted.

 For details on the exact steps used to build the binaries, see the [compiling MariaDB section](../compiling-mariadb-from-source/index) of the KB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-binary-tarballs/>

Installing MariaDB Windows ZIP Packages
=======================================

    Users need to run [mysql\_install\_db.exe](../mysql_install_dbexe/index), without parameters to create a data directory, e.g

 
```
C:\zip_unpack\directory> bin\mysqld_install_db.exe 

```

Then you can start server like this

 
```
C:\zip_unpack\directory> bin\mysqld.exe --console

```

For very old distributions (10.3 and earlier), a prebuilt data directory is already provided.

 If you like to customize the server instance (data directory, install as service etc), please refer to [mysql\_install\_db.exe documentation](../mysql_install_dbexe/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-windows-zip-packages/>

Distributions Which Include MariaDB
===================================

     The following is a partial list of distributions which include MariaDB in their package repositories. For these you can use the distribution's management system to install MariaDB.

 The term "default" in the list below refers to the distribution's default relational or MySQL-type database.

 Linux Distributions
-------------------

 * [AlmaLinux](https://almalinux.org/) — [MariaDB 10.5](../what-is-mariadb-105/index) was included since 8.8.
* [Alpine Linux](https://www.alpinelinux.org/) — Defaults to MariaDB. [MariaDB 10.6](../what-is-mariadb-106/index) has been available 3.12.11 and [MariaDB 10.11](../what-is-mariadb-1011/index) since 3.18.2.
* [4mLinux](https://4mlinux.com) — Defaults to MariaDB. [MariaDB 10.6](../what-is-mariadb-106/index) has been available [since 37.0](http://4mlinux-releases.blogspot.com/2022/03/4mlinux-390-stable-released.html)
* [ALT Linux](https://packages.altlinux.org/en/Sisyphus/srpms/mariadb) — [MariaDB 5.5](../what-is-mariadb-55/index) included in 7.0.0, MariaDB is default from 8.1, which includes [MariaDB 10.1](../what-is-mariadb-101/index), 9.1 includes [MariaDB 10.4](../what-is-mariadb-104/index)
* [Arch Linux](https://www.archlinux.org/news/mariadb-replaces-mysql-in-repositories/) — Features [MariaDB 10.11](../what-is-mariadb-1011/index), and replaced MySQL as a default
* [Austrumi](http://cyti.latgola.lv/ruuni/)— Defaulted to [MariaDB 5.3](../what-is-mariadb-53/index) in 2.4.8, 3.5.8 includes [MariaDB 10.1](../what-is-mariadb-101/index)
* [BlackArch](http://blackarch.org/) — Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 2014.07.01, 2020.12.01 includes [MariaDB 10.5](../what-is-mariadb-105/index)
* [BlueOnyx](http://www.blueonyx.it/) — 5209 defaults to [MariaDB 5.5](../what-is-mariadb-55/index), 5210R to [MariaDB 10.3](../what-is-mariadb-103/index)
* [BlueStar](http://bluestarlinux.sourceforge.net/) — 4.8.4 defaults to [MariaDB 10.1](../what-is-mariadb-101/index), 5.4.2 to [MariaDB 10.5](../what-is-mariadb-105/index)
* [CentOS](https://wiki.centos.org/About/Product/) — [MariaDB 5.5](../what-is-mariadb-55/index) replaced MySQL in CentOS 7
* [The Chakra Project](https://chakraos.org/) — MariaDB replaced MySQL as default in 2013.05. 2016.02 includes [MariaDB 10.1](../what-is-mariadb-101/index)
* [Debian](https://www.debian.org/) — Debian 10 "Buster" includes [MariaDB 10.3](../what-is-mariadb-103/index), Debian 11 "Bullseye" [MariaDB 10.5](../what-is-mariadb-105/index), Debian 12 "Bookworm" [MariaDB 10.11](../what-is-mariadb-1011/index) as default.
* [Elastix](http://www.elastix.org/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 4.0.76
* [Exherbo](http://exherbo.org/) —Includes [MariaDB 10.4](../what-is-mariadb-104/index)
* [Fedora](https://getfedora.org/) — [MariaDB 5.5](../what-is-mariadb-55/index) became the default relational database in Fedora 19. Fedora 30 [includes MariaDB 10.3](https://bodhi.fedoraproject.org/updates/?packages=mariadb&page=1), Fedora 34 [includes MariaDB 10.5](https://fedoraproject.org/wiki/Releases/34/ChangeSet#MariaDB_10.5).
* [Funtoo](http://www.funtoo.org/) —Includes [MariaDB 5.5](../what-is-mariadb-55/index)
* [Gentoo Linux](https://packages.gentoo.org/packages/dev-db/mariadb)
* [Guix](https://www.gnu.org/software/guix/)—11.2.0 includes [MariaDB 10.1](../what-is-mariadb-101/index)
* [Hanthana](http://www.hanthana.org/)— 19.1 defaulted to [MariaDB 5.5](../what-is-mariadb-55/index), 21 includes [MariaDB 10.0](../what-is-mariadb-100/index), 28.1.2 includes [MariaDB 10.2](../what-is-mariadb-102/index), 30 includes [MariaDB 10.3](../what-is-mariadb-103/index)
* [KaOS](http://kaosx.us/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 2014.12, 2019.04 includes [MariaDB 10.3](../what-is-mariadb-103/index)
* [Kali Linux](https://www.kali.org/) —2017.3 Included [MariaDB 10.1](../what-is-mariadb-101/index), 2023.1 includes [MariaDB 10.11](../what-is-mariadb-1011/index)
* [GNU/Linux KDu](http://www.linux-kdu.com.br/) — [MariaDB 5.5](../what-is-mariadb-55/index) replaced MySQL as a default in 2.0 Final.
* [Korora](https://kororaproject.org/) —Defaulted to MariaDB in 19.1, 26 includes [MariaDB 10.1](../what-is-mariadb-101/index)
* [Linux from Scratch](http://www.linuxfromscratch.org/) —10.1-BLFS defaults to [MariaDB 10.5](../what-is-mariadb-105/index)
* [Lunar](http://www.lunar-linux.org/) —1.7.0 includes [MariaDB 5.5](../what-is-mariadb-55/index), Moonbase includes [MariaDB 10.5](../what-is-mariadb-105/index)
* [Mageia](https://www.mageia.org/) — [MariaDB 5.5](../what-is-mariadb-55/index) replaced MySQL as default in version 3, [MariaDB 10.3](../what-is-mariadb-103/index) from version 7.1, [MariaDB 10.5](../what-is-mariadb-105/index) from 8, [MariaDB 10.11](../what-is-mariadb-1011/index) from 9.
* [Manjaro Linux](https://manjaro.github.io/) — Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 0.8.11, 16.10.3 includes [MariaDB 10.1](../what-is-mariadb-101/index).
* [NixOS](http://nixos.org/) —14.0.4.630 included [MariaDB 10.0](../what-is-mariadb-100/index), 18.09 includes [MariaDB 10.2](../what-is-mariadb-102/index), Stable includes [MariaDB 10.5](../what-is-mariadb-105/index)
* [Network Security Toolkit](http://www.networksecuritytoolkit.org/) —20-5663 defaulted to [MariaDB 5.5](../what-is-mariadb-55/index), 32-11992 includes [MariaDB 10.4](../what-is-mariadb-104/index)
* [NuTyX](http://www.nutyx.org/) —14.11 included [MariaDB 10.0](../what-is-mariadb-100/index), defaulted to [MariaDB 10.1](../what-is-mariadb-101/index) in 8.2.1, 20.12.1 includes [MariaDB 10.5](../what-is-mariadb-105/index)
* [OpenELEC](http://news.softpedia.com/news/openelec-8-0-3-embedded-linux-entertainment-os-adds-mesa-17-0-5-and-linux-4-9-25-515302.shtml)
* [OpenEuler](https://openeuler.org/en/) —21.9 includes [10.5](https://repo.openeuler.org/openEuler-21.09/source/Packages/), 22.03 LTS [includes MariaDB 10.5](https://repo.openeuler.org/openEuler-22.03-LTS/source/Packages/)
* [Open Mandriva](http://openmandriva.org/) —Defaulted to [MariaDB 10.0](../what-is-mariadb-100/index) in 2014.2, includes [MariaDB 10.5](../what-is-mariadb-105/index) in 4.2
* [openSUSE](https://en.opensuse.org/Portal:MySQL) — [MariaDB 5.5](../what-is-mariadb-55/index) became the default relational database in [openSUSE 12.3](https://blog.mariadb.org/opensuse-12-3-released-with-mariadb-as-default), and [MariaDB 10.6](../what-is-mariadb-106/index) the default since 15.5
* [Oracle Linux](http://www.oracle.com/us/technologies/linux/index.html) — 7.3 includes [MariaDB 5.5](../what-is-mariadb-55/index). 8.0 includes [MariaDB 10.3](../what-is-mariadb-103/index)
* [Paldo](http://www.paldo.org/) —Defaults to [MariaDB 10.5](../what-is-mariadb-105/index) in Stable
* [Parabola GNU/Linux](https://www.parabola.nu/packages/?q=mariadb) —Includes [MariaDB 10.1](../what-is-mariadb-101/index) since 3.7
* [Parrot Security](http://www.parrotsec.org/) —Based on Debian's testing branch (stretch), Parrot Security switched from MySQL to [MariaDB 10.0](../what-is-mariadb-100/index) in 3.1, 4.7 includes [MariaDB 10.3](../what-is-mariadb-103/index)
* [Parted Magic](http://partedmagic.com/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 2015\_11\_13
* [PCLinuxOS](http://www.pclinuxos.com/forum/index.php?topic=140029.0) —Replaced MySQL with [MariaDB 10.1](../what-is-mariadb-101/index) in 2017.03
* [Pisi Linux](http://www.pisilinux.org/) —Defaulted to [MariaDB 10.0](../what-is-mariadb-100/index) in 1.1
* [Plamo](http://www.plamolinux.org/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 5.3.1, 7.3 includes [MariaDB 10.2](../what-is-mariadb-102/index)
* [PoliArch](http://www.poliarch.org/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 13.1, 15.1 includes [MariaDB 10.0](../what-is-mariadb-100/index)
* [Red Hat Enterprise Linux](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux) — [MariaDB 5.5](../what-is-mariadb-55/index) was included as the default "MySQL" database since RHEL 7, RHEL 9 includes [MariaDB 10.5](../what-is-mariadb-105/index)
* [Rocky Linux](https://rockylinux.org) — [MariaDB 10.5](../what-is-mariadb-105/index) was included since 8.7.
* [ROSA](http://www.rosalab.com/) —Defaulted to [MariaDB 10.0](../what-is-mariadb-100/index) in R4 and [MariaDB 10.1](../what-is-mariadb-101/index) in R9.
* [Sabayon](http://www.sabayon.org/) —Included [MariaDB 10.0](../what-is-mariadb-100/index) in 14.12, includes [MariaDB 10.3](../what-is-mariadb-103/index) since 19.03
* [Scientific Linux](https://www.scientificlinux.org/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 7.3
* [Slackware](https://slackbuilds.org/apps/mariadb/) — [MariaDB 5.5](../what-is-mariadb-55/index) replaced MySQL as default in 14.1. 15.0 includes [MariaDB 10.5](../what-is-mariadb-105/index), current includes [MariaDB 10.11](../what-is-mariadb-1011/index)
* [SliTaz GNU/Linux](http://www.slitaz.org/) —Includes [MariaDB 10.0](../what-is-mariadb-100/index) in 5.0-rolling
* [SME Server](https://wiki.contribs.org/SME_Server:10.0)— started to use [MariaDB 5.5](../what-is-mariadb-55/index) from 10.0
* [Springdale Linux](http://springdale.math.ias.edu/) —Defaulted to [MariaDB 5.5](../what-is-mariadb-55/index) in 7.2, 8.1 includes [MariaDB 10.3](../what-is-mariadb-103/index)
* [SuliX](http://www.sulix.hu/) — Defaults to [MariaDB 5.5](../what-is-mariadb-55/index) in 8.
* [SUSE Linux Enterprise](https://www.suse.com) — [MariaDB 10.6](../what-is-mariadb-106/index) is the default relational database option on 15-SP6
* [Ubuntu](https://wiki.ubuntu.com/Releases/) —[MariaDB 5.5](../what-is-mariadb-55/index) was included in Trusty Tahr 14.04. 20.04 [includes MariaDB 10.3](http://packages.ubuntu.com/focal/mariadb-server-10.3), and 22.04 [includes 10.6](https://packages.ubuntu.com/jammy/database/).
* [Void](http://www.voidlinux.eu/) — [Includes MariaDB 10.5 in current](https://voidlinux.org/packages/)
* [Wifislax](http://www.wifislax.com/) — Defaulted to [MariaDB 10.0](../what-is-mariadb-100/index) in 4.11.1

 BSD Distributions
-----------------

 * [Dragonfly BSD](https://www.dragonflybsd.org/) — 3.8 included [MariaDB 5.5](../what-is-mariadb-55/index). 5.8.0 includes [MariaDB 10.4](../what-is-mariadb-104/index).
* [FreeBSD](https://svnweb.freebsd.org/ports/head/databases/#mariadb100-client) — MariaDB is available in the ports tree and the FreeBSD Manual has instructions on [Installing Applications: Packages and Ports](https://www.freebsd.org/doc/en/books/handbook/ports.html). [MariaDB 10.5](../what-is-mariadb-105/index) is included in 12.2
	+ [MariaDB on FreshPorts](https://www.freshports.org/search.php?query=mariadb)
* [NetBSD](https://www.netbsd.org/) — 6.1 and 7.0 include [MariaDB 5.5](../what-is-mariadb-55/index).
* [OpenBSD](https://marc.info/?m=141063182731679) — [MariaDB 10.0](../what-is-mariadb-100/index) was included in 5.7, 6.8 includes [MariaDB 10.5](../what-is-mariadb-105/index).

 macOS
-----

 * [Homebrew](http://brew.sh/) — If you have Homebrew installed, you can install MariaDB Server by executing `brew install mariadb`. Find out more at [Installing MariaDB Server on macOS Using Homebrew](../installing-mariadb-on-macos-using-homebrew/index).
* [MacPorts](https://www.macports.org/) —This provides [mariadb and mariadb-server](https://trac.macports.org/browser/trunk/dports/databases/mariadb/Portfile). A [quick guide](http://yosun.me/2012/04/13/mariadb-via-macports-on-mac-os-x-10-6/) on how to install it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/distributions-which-include-mariadb/>

Installing MariaDB Alongside MySQL
==================================

    MariaDB was originally designed as a drop-in replacement of MySQL, with more features, new storage engines, fewer bugs, and better performance, but you can also install it alongside MySQL. (This can be useful, for example, if you want to migrate databases/applications one by one.)

 Here are the steps to install MariaDB near an existing MySQL installation.

 * Download the compiled binary tar.gz that contains the latest version ([mariadb-5.5.24-linux-x86\_64.tar.gz](http://downloads.mariadb.org/mariadb/5.5.24/#bits=64&file_type=tar_gz) - as of writing this article) and extract the files in a directory of your choice. I will assume for this article that the directory was **/opt**.

 
```
[root@mariadb-near-mysql ~]# cat /etc/issue
CentOS release 6.2 (Final)

[root@mariadb-near-mysql ~]# rpm -qa mysql*
mysql-5.1.61-1.el6_2.1.x86_64
mysql-libs-5.1.61-1.el6_2.1.x86_64
mysql-server-5.1.61-1.el6_2.1.x86_64

[root@mariadb-near-mysql ~]# ps axf | grep mysqld
 2072 pts/0    S+     0:00          \_ grep mysqld
 1867 ?        S      0:01 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --socket=/var/lib/mysql/mysql.sock ...
 1974 ?        Sl     0:06  \_ /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql ...

```

* Create data directory and symlinks as below:

 
```
[root@mariadb-near-mysql opt]# mkdir mariadb-data
[root@mariadb-near-mysql opt]# ln -s mariadb-5.5.24-linux-x86_64 mariadb
[root@mariadb-near-mysql opt]# ls -al
total 20
drwxr-xr-x.  5 root root 4096 2012-06-06 07:27 .
dr-xr-xr-x. 23 root root 4096 2012-06-06 06:38 ..
lrwxrwxrwx.  1 root root   27 2012-06-06 07:27 mariadb -> mariadb-5.5.24-linux-x86_64
drwxr-xr-x. 13 root root 4096 2012-06-06 07:07 mariadb-5.5.24-linux-x86_64
drwxr-xr-x.  2 root root 4096 2012-06-06 07:26 mariadb-data

```

* Create group **mariadb** and user **mariadb** and set correct ownerships:

 
```
[root@mariadb-near-mysql opt]# groupadd --system mariadb
[root@mariadb-near-mysql opt]# useradd -c "MariaDB Server" -d /opt/mariadb -g mariadb --system mariadb
[root@mariadb-near-mysql opt]# chown -R mariadb:mariadb mariadb-5.5.24-linux-x86_64/
[root@mariadb-near-mysql opt]# chown -R mariadb:mariadb mariadb-data/

```

* Create a new **my.cnf** in **/opt/mariadb** from support files:

 
```
[root@mariadb-near-mysql opt]# cp mariadb/support-files/my-medium.cnf mariadb-data/my.cnf
[root@mariadb-near-mysql opt]# chown mariadb:mariadb mariadb-data/my.cnf

```

* Edit the file **/opt/mariadb-data/my.cnf** and add custom paths, socket, port, user and the most important of all: data directory and base directory. Finally the file should have at least the following:

 
```
[client]
port		= 3307
socket		= /opt/mariadb-data/mariadb.sock

[mysqld]
datadir         = /opt/mariadb-data
basedir         = /opt/mariadb
port		= 3307
socket		= /opt/mariadb-data/mariadb.sock
user            = mariadb

```

* Copy the init.d script from support files in the right location:

 
```
[root@mariadb-near-mysql opt]# cp mariadb/support-files/mysql.server /etc/init.d/mariadb
[root@mariadb-near-mysql opt]# chmod +x /etc/init.d/mariadb

```

* Edit **/etc/init.d/mariadb** replacing **mysql** with **mariadb** as below:

 
```
- # Provides: mysql
+ # Provides: mariadb
- basedir=
+ basedir=/opt/mariadb
- datadir=
+ datadir=/opt/mariadb-data
- lock_file_path="$lockdir/mysql"
+ lock_file_path="$lockdir/mariadb"

```

The trickiest part will be the last changes to this file. You need to tell mariadb to use only one cnf file. In the **start** section after **$bindir/mysqld\_safe** add **--defaults-file=/opt/mariadb-data/my.cnf**. Finally the lines should look like:

 
```
# Give extra arguments to mysqld with the my.cnf file. This script
# may be overwritten at next upgrade.
$bindir/mysqld_safe --defaults-file=/opt/mariadb-data/my.cnf --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 &

```

The same change needs to be made to the [mariadb-admin](../mariadb-admin/index) command below in the wait\_for\_ready() function so that the mariadb start command can properly listen for the server start. In the **wait\_for\_ready()** function, after **$bindir/mariadb-admin** add **--defaults-file=/opt/mariadb-data/my.cnf**. The lines should look like:

 
```
wait_for_ready () {
[...]
    if $bindir/mariadb-admin --defaults-file=/opt/mariadb-data/my.cnf ping >/dev/null 2>&1; then

```

* Run [mariadb-install-db](../mariadb-install-db/index) by explicitly giving it the my.cnf file as argument:

 
```
[root@mariadb-near-mysql opt]# cd mariadb
[root@mariadb-near-mysql mariadb]# scripts/mariadb-install-db --defaults-file=/opt/mariadb-data/my.cnf

```

* Now you can start MariaDB by

 
```
[root@mariadb-near-mysql opt]# /etc/init.d/mariadb start
Starting MySQL...                                          [  OK  ]

```

* Make MariaDB start at system start:

 
```
[root@mariadb-near-mysql opt]# cd /etc/init.d
[root@mariadb-near-mysql init.d]# chkconfig --add mariadb 
[root@mariadb-near-mysql init.d]# chkconfig --levels 3 mariadb on

```

* Finally test that you have both instances running:

 
```
[root@mariadb-near-mysql ~]# mysql -e "SELECT VERSION();"
+-----------+
| VERSION() |
+-----------+
| 5.1.61    |
+-----------+
[root@mariadb-near-mysql ~]# mysql -e "SELECT VERSION();" --socket=/opt/mariadb-data/mariadb.sock
+----------------+
| VERSION()      |
+----------------+
| 5.5.24-MariaDB |
+----------------+

```

What about MariaDB Upgrades ?
-----------------------------

 By having the **mariadb.socket**, **my.cnf** file and **databases** in **/opt/mariadb-data** if you want to upgrade the MariaDB version you will will only need to:

 * extract the new version from the archive in **/opt** near the current version
* stop MariaDB
* change the symlink **mariadb** to point to the new directory
* start MariaDB
* run upgrade script... but remember you will need to provide the socket option **--socket=/opt/mariadb-data/mariadb.sock**

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-alongside-mysql/>

GPG
===

     The MariaDB project signs their MariaDB packages for Debian, Ubuntu, Fedora, CentOS, and Red Hat.

 Debian / Ubuntu key
-------------------

 Our repositories for Debian "Sid" and the Ubuntu 16.04 and beyond "Xenial" use the following GPG signing key. As detailed in [MDEV-9781](https://jira.mariadb.org/browse/MDEV-9781), APT 1.2.7 (and later) prefers SHA2 GPG keys and now prints warnings when a repository is signed using a SHA1 key like our previous GPG key. We have created a SHA2 key for use with these.

 Information about this key:

 * The short Key ID is: `0xC74CD1D8`
* The long Key ID is: `0xF1656F24C74CD1D8`
* The full fingerprint of the key is: `177F 4010 FE56 CA33 3630 0305 F165 6F24 C74C D1D8`
* The key can be added on Debian-based systems using the following command:

 
```
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8

```

* Usage of the `apt-key` command is deprecated in the latest versions of Debian and Ubuntu, and the replacement method is to download the keyring file to the `/etc/apt/trusted.gpg.d/` directory. This can be done with the following:

 
```
sudo curl -LsSo /etc/apt/trusted.gpg.d/mariadb-keyring-2019.gpg https://supplychain.mariadb.com/mariadb-keyring-2019.gpg

```

RPM / Source Key 2023+
----------------------

 Beginning in 2023 we migrated the key used to sign our yum/dnf/zypper repositories and to sign our source code and binary tarballs to the same key we use for Debian and Ubuntu. This unifies our GPG signing and enables our repositories to be compatible with FIPS and other regulations that mandate a stronger signing key.

 The key can be imported on RPM-based systems using the following command:

 
```
sudo rpm --import https://supplychain.mariadb.com/MariaDB-Server-GPG-KEY

```

or

 
```
sudo rpmkeys --import https://supplychain.mariadb.com/MariaDB-Server-GPG-KEY

```

RPM / Source key pre-2023
-------------------------

 The GPG Key ID of the MariaDB signing key we used for yum/dnf/zypper repositories and to sign our source code tarballs until the end of 2022 was `0xCBCB082A1BB943DB`. The short form of the id is `0x1BB943DB` and the full key fingerprint is:

 
```
1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

```

This key was used by the yum/dnf/zypper repositories for RedHat, CentOS, Fedora, openSUSE, and SLES. 

 If you configure the mariadb.org rpm repositories using the repository configuration tool (see below) then your package manager will prompt you to import the key the first time you install a package from the repository.

 You can also import the key directly using the following command:

 
```
sudo rpmkeys --import https://supplychain.mariadb.com/MariaDB-Server-GPG-KEY

```

Configuring Repositories
------------------------

 See the [this page](https://mariadb.com/docs/server/deploy/deployment-methods/repo/#Configure_MariaDB_Community_Repository) for details on using the `mariadb_repo_setup` script to configure repositories that use these keys.

 See the [this page](https://downloads.mariadb.org/mariadb/repositories/) for details on configuring MariaDB Foundation repositories that use these keys.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/gpg/>

Upgrading from MySQL to MariaDB
================================

  

| Title | Description |
| --- | --- |
|  [Upgrading from MySQL to MariaDB](../upgrading-from-mysql-to-mariadb/index) |  Upgrading from MySQL to MariaDB.  |
|  [Moving from MySQL to MariaDB in Debian 9](../moving-from-mysql-to-mariadb-in-debian-9/index) |  MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"  |
|  [Screencast for Upgrading MySQL to MariaDB](../screencast-for-upgrading-mysql-to-mariadb/index) |  Screencast for upgrading MySQL 5.1.55 to MariaDB  |
|  [Upgrading from MySQL 5.7 to MariaDB 10.2](../upgrading-from-mysql-57-to-mariadb-102/index) |  Following compatibility report was done on 10.2.4 and may get some fixing i...  |
|  [Upgrading to MariaDB From MySQL 5.0 or Older](../upgrading-to-mariadb-from-mysql-50-or-older/index) |  Upgrading to MariaDB from MySQL 5.0 (or older version)  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-mariadb-upgrading-from-mysql-to-mariadb/>

Upgrading MariaDB on Windows
============================

    
For incompatibilities such as removed features, and changes to variables, see the pages describing changes by version on [Upgrading MariaDB](../upgrading/index).

 
Minor Upgrades
--------------

 To install a minor upgrade, e.g 10.1.27 on top of existing 10.1.26, with MSI, just download the 10.1.27 MSI and start it. It will do everything that needs to be done for minor upgrade automatically - shutdown MariaDB service(s), replace executables and DLLs, and start service(s) again.

 The rest of the article is dedicated to \*major\* upgrades, e.g 10.1.x to 10.2.y. 

 General Information on Upgrade and Version Coexistence
------------------------------------------------------

 This section assumes MSI installations.

 First, check everything listed in the Incompatibilities section of the article relating to the version you are upgrading, for example, [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index), to make sure you are prepared for the upgrade.

 MariaDB (and also MySQL) allows different versions of the product to co-exist on the same machine, as long as these versions are different either in major or minor version numbers. For example, it is possible to have say [MariaDB 5.1.51](https://mariadb.com/kb/en/mariadb-5151-release-notes/) and 5.2.6 to be installed on the same machine.

 However only a single instance of 5.2 can exist. If for example 5.2.7 is installed on a machine where 5.2.6 is already installed, the installer will just replace 5.2.6 executables with 5.2.7 ones.

 Now imagine, that both 5.1 and 5.2 are installed on the same machine and we want to upgrade the database instance running on 5.1 to the new version. In this case special tools are requied. Traditionally, `[mysql\_upgrade](../mysql_upgrade/index)` is used to accomplish this. On Windows, the [MySQL upgrade](http://dev.mysql.com/doc/refman/5.5/en/windows-upgrading.html) is a complicated multiple-step manual process.

 Since [MariaDB 5.2.6](https://mariadb.com/kb/en/mariadb-526-release-notes/), the Windows distribution includes tools that simplify migration between different versions and also allow migration between MySQL and MariaDB.

 **Note**. Automatic upgrades are only possible for DB instances that run as a Windows service.

 General Recommendations
-----------------------

 
 **Important:** Ignore any statement that tells you to *"just uninstall MySQL and install MariaDB"*. This does not work on Windows, never has, and never will. Keep your MySQL installed until after the database had been converted.

 
The following install/upgrade sequence is recommended in case of "major" upgrades, like going from 5.3 to 5.5

 * Install new version, while still retaining the old one
* Upgrade services one by one, like described later in the document (e.g with mysql\_upgrade\_service). It is recommeded to have services cleanly shut down before the upgrade.
* Uninstall old version when previous step is done.

 
**Note**. This recommendation differs from the procedure on Unixes, where the upgrade sequence is "uninstall old version, install new version"

 
Upgrade Wizard
--------------

 This is a GUI tool that is typically invoked at the end of a MariaDB installation if upgradable services are found. The UI allows you to select instances you want to upgrade.

 ![UpgradeWizard](https://mariadb.com/kb/en/upgrading-mariadb-on-windows/+image/UpgradeWizard "UpgradeWizard")

 mysql\_upgrade\_service
-----------------------

 This is a command line tool that performs upgrades. The tool requires full administrative privileges (it has to start and stop services).

 Example usage:

 
```
  mysql_upgrade_service --service=MySQL

```

`mysql_upgrade_service` accepts a single parameter — the name of the MySQL or MariaDB service. It performs all the steps to convert a MariaDB/MySQL instance running as the service to the current version.

 Migration to 64 bit MariaDB from 32 bit
---------------------------------------

 Earlier we said that only single instance of "MariaDB <major>.<minor>" version can be installed on the same machine. This was almost correct, because MariaDB MSI installations allow 32 and 64-bit versions to be installed on the same machine, and in this case it is possible to have two instances of say 5.2 installed at the same time, an x86 one and an x64 one. One can use the x64 Upgrade wizard to upgrade an instance running as a 32-bit process to run as 64-bit.

 Upgrading ZIP-based Installations.
----------------------------------

 Both UpgradeWizard and mysql\_upgrade\_service can also be used to upgrade database instances that were installed with the [ZIP installation](../installing-mariadb-windows-zip-packages/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-mariadb-on-windows/>

Automated MariaDB Deployment and Administration
================================================

   It is possible to automate the deployment and administration of MariaDB servers and related technologies by using third-party software. This is especially useful when deploying and administering a large number of servers, but it also has benefits for small environments.

 This section describes some automation technologies from MariaDB users perspective.

  

| Title | Description |
| --- | --- |
|  [Why to Automate MariaDB Deployments and Management](../why-to-automate-mariadb-deployments-and-management/index) |  The reasons to automate deployment and configuration of MariaDB.  |
|  [A Comparison Between Automation Systems](../a-comparison-between-automation-systems/index) |  A summary of the differences between automation systems, to help evaluating them.  |
|  [Ansible and MariaDB](../ansible-and-mariadb/index) |  General information and hints on automating MariaDB deployments with Ansible.  |
|  [Puppet and MariaDB](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index) |  General information on how to automate MariaDB deployments and configuration with Puppet.  |
|  [Vagrant and MariaDB](../vagrant-and-mariadb/index) |  General information on how to setup development MariaDB servers with Vagrant.  |
|  [MariaDB Containers](../docker-and-mariadb/index) |  MariaDB containers with and Docker Official Images  |
|  [Kubernetes and MariaDB](../kubernetes-and-mariadb/index) |  General information and tips on deploying MariaDB on Kubernetes.  |
|  [Automating Upgrades with MariaDB.Org Downloads REST API](../automating-upgrades-with-mariadborg-downloads-rest-api/index) |  How to use MariaDB.Org Downloads APIs to automate upgrades.  |
|  [HashiCorp Vault and MariaDB](../hashicorp-vault-and-mariadb/index) |  An overview of secret management with Vault for MariaDB users.  |
|  [Orchestrator Overview](../orchestrator-overview/index) |  Using Orchestrator to automate failover and replication operations.  |
|  [Rotating Logs on Unix and Linux](../rotating-logs-on-unix-and-linux/index) |  Rotating logs on Unix and Linux with logrotate.  |
|  [Automating MariaDB Tasks with Events](../automating-mariadb-tasks-with-events/index) |  Using MariaDB events for automating tasks.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/automated-mariadb-deployment-and-administration/>

MariaDB Package Repository Setup and Usage
==========================================

    If you are looking to set up MariaDB Server, it is often easiest to use a repository. The MariaDB Foundation has a repository configuration tool at <https://mariadb.org/download/> and MariaDB Corporation provides a convenient shell script to configure access to their MariaDB Package Repositories. It is available at:

 * <https://r.mariadb.com/downloads/mariadb_repo_setup>

 The script by default sets up 3 different repositories in a single repository configuration file. The repositories are

 * MariaDB Server Repository
* MariaDB MaxScale Repository
* MariaDB Tools Repository

 The script can be executed in the following way:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash

```

For the script to work, the `curl` and `ca-certificates` packages need to be installed on your system. Additionally on Debian and Ubuntu the `apt-transport-https` package needs to be installed. The script will check if these are installed and let you know before it attempts to create the repository configuration on your system.

 Repositories
------------

 The script will will set up 2 different repositories in a single repository configuration file.

 ### MariaDB Repository

 The **MariaDB Repository** contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index).

 The binaries in MariaDB Corporation's **MariaDB Repository** are currently identical to the binaries in MariaDB Foundation's MariaDB Repository that is configured with the [MariaDB Repository Configuration Tool](https://mariadb.org/download/?t=repo-config).

 By default, the script will configure your system to install from the repository of the latest GA version of MariaDB. That is currently [MariaDB 10.7](../what-is-mariadb-107/index). If a new major GA release occurs and you would like to upgrade to it, then you will need to either manually edit the repository configuration file to point to the new version, or run the MariaDB Package Repository setup script again.

 The script can also configure your system to install from the repository of a different version of MariaDB if you use the `[--mariadb-server-version](#-mariadb-server-version)` option. 

 If you would not like to configure the **MariaDB Repository** on your system, then you can use the `--skip-server` option to prevent the MariaDB Package Repository setup script from configuring it.

 ### MariaDB MaxScale Repository

 The **MariaDB MaxScale Repository** contains software packages related to [MariaDB MaxScale](../maxscale/index).

 By default, the script will configure your system to install from the repository of the *latest* GA version of MariaDB MaxScale. When a new major GA release occurs, the repository will automatically switch to the new version. If instead you would like to stay on a particular version you will need to manually edit the repository configuration file and change '`latest`' to the version you want (e.g. '`6.1`') or run the MariaDB Package Repository setup script again, specifying the particular version or series you want.

 Older versions of the MariaDB Package Repository setup script would configure a specific MariaDB MaxScale series in the repository (i.e. '`2.4`'), so if you used the script in the past to set up your repository and want MariaDB MaxScale to automatically use the latest GA version then change '`2.4`' or '`2.3`' in the repository configuration to '`latest`'. Or download the current version of the script and re-run it to set up the repository again.

 The script can configure your system to install from the repository of an older version of MariaDB MaxScale if you use the `[--mariadb-maxscale-version](#-mariadb-maxscale-version)` option. For example, `--mariadb-maxscale-version=2.4` if you want the latest release in the MariaDB MaxScale 2.4.x series.

 If you do not want to configure the **MariaDB MaxScale Repository** on your system, then you can use the `--skip-maxscale` option to prevent the MariaDB Package Repository setup script from configuring it.

 
MariaDB MaxScale is licensed under the [Business Source License 1.1](https://mariadb.com/bsl11/), so it is not entirely free to use for organizations who do not have a subscription with MariaDB Corporation. If you would like more information, see the information at [MariaDB Business Source License (BSL): Frequently Asked Questions](https://mariadb.com/bsl-faq-mariadb/). If you would like to know how much a subscription to use MariaDB MaxScale would cost, see [MariaDB Corporation's subscription pricing](https://mariadb.com/pricing/).

 
Supported Distributions
-----------------------

 The script supports Linux distributions that are officially supported by MariaDB Corporation's [MariaDB TX subscription](https://mariadb.com/products/mariadb-platform-transactional/). However, a MariaDB TX subscription with MariaDB Corporation is not required to use the MariaDB Package Repository.

 The distributions currently supported by the script include:

 * Red Hat Enterprise Linux (RHEL) 7 and 8
* CentOS 7
* Debian 9 (Stretch), 10 (Buster), 11 (Bullseye)
* Ubuntu 18.04 LTS (Bionic), and 20.04 LTS (Focal)
* SUSE Linux Enterprise Server (SLES) 12 and 15

 To install MariaDB on distributions not supported by the MariaDB Package Repository setup script, please consider using MariaDB Foundation's [MariaDB Repository Configuration Tool](https://mariadb.org/download/?t=repo-config). Some Linux distributions also include MariaDB [in their own repositories](../distributions-which-include-mariadb/index).

 Using the MariaDB Package Repository Setup Script
-------------------------------------------------

 The script can be executed in the following way:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash

```

The script will have to set up package repository configuration files, so it will need to be executed as root.

 The script will also install the GPG public keys used to verify the signature of MariaDB software packages. If you want to avoid that, then you can use the `--skip-key-import` option.

 If the script tries to create the repository configuration file and one with that name already exists, then the script will rename the existing file with an extension in the format ".old\_[0-9]+", which would make the OS's package manager ignore the file. You can safely remove those files after you have confirmed that the updated repository configuration file works..

 If you want to see the repository configuration file that would be created without actually doing so, then you can use the `[--write-to-stdout](#-write-to-stdout)` option. This also prevents the need to run the script as root, 

 If you want to download the script, rather than executing it, then you can do so in the following way:

 
```
curl -LO https://r.mariadb.com/downloads/mariadb_repo_setup

```

### Options

 To provide options to the script, you must tell bash to expect them by executing bash with the options `-s --`, for example:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --help

```




| Option | Description |
| --- | --- |
| `--help` | Display a usage message and exit. |
| `--mariadb-server-version=<version>` | Override the default MariaDB Server version. By default, the script will use 'mariadb-10.5'. |
| `--mariadb-maxscale-version=<version>` | Override the default MariaDB MaxScale version. By default, the script will use 'latest'. |
| `--os-type=<type>` | Override detection of OS type. Acceptable values include `debian`, `ubuntu`, `rhel`, and `sles`. |
| `--os-version=<version>` | Override detection of OS version. Acceptable values depend on the OS type you specify. |
| `--skip-key-import` | Skip importing GPG signing keys. |
| `--skip-maxscale` | Skip the 'MaxScale' repository. |
| `--skip-server` | Skip the 'MariaDB Server' repository. |
| `--skip-tools` | Skip the 'Tools' repository. |
| `--skip-verify` | Skip verification of MariaDB Server versions. Use with caution as this can lead to an invalid repository configuration file being created. |
| `--skip-check-installed` | Skip tests for required prerequisites for this script. |
| `--skip-eol-check` | Skip tests for versions being past their EOL date |
| `--skip-os-eol-check` | Skip tests for operating system versions being past EOL date |
| `--write-to-stdout` | Write output to stdout instead of to the OS's repository configuration file. This will also skip importing GPG public keys and updating the package cache on platforms where that behavior exists. |

 
#### `--mariadb-server-version`

 By default, the script will configure your system to install from the repository of the latest GA version of MariaDB. That is currently [MariaDB 10.5](../what-is-mariadb-105/index). If a new major GA release occurs and you would like to upgrade to it, then you will need to either manually edit the repository configuration file to point to the new version, or run the MariaDB Package Repository setup script again.

 The script can also configure your system to install from the repository of a different version of MariaDB if you use the `--mariadb-server-version` option.

 The string `mariadb-` has to be prepended to the version number. For example, to configure your system to install from the repository of [MariaDB 10.3](../what-is-mariadb-103/index), that would be:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-10.6"

```

The following MariaDB versions are currently supported:

 * `mariadb-10.4`
* `mariadb-10.5`
* `mariadb-10.6`
* `mariadb-10.9`
* `mariadb-10.10`
* `mariadb-10.11`
* `mariadb-11.0`
* `mariadb-11.1`

 If you want to pin the repository of a specific minor release, such as [MariaDB 10.6.14](https://mariadb.com/kb/en/mariadb-10614-release-notes/), then you can also specify the minor release. For example, `mariadb-10.6.14`. This may be helpful if you want to avoid upgrades. However, avoiding upgrades is not recommended, since minor maintenance releases may contain important bug fixes and fixes for security vulnerabilities.

 #### `--mariadb-maxscale-version`

 By default, the script will configure your system to install from the repository of the latest GA version of MariaDB MaxScale.

 If you would like to pin the repository to a specific version of MariaDB MaxScale then you will need to either manually edit the repository configuration file to point to the desired version, or use the `--mariadb-maxscale-version` option.

 For example, to configure your system to install from the repository of MariaDB MaxScale 6.1, that would be:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-maxscale-version="6.1"

```

The following MariaDB MaxScale versions are currently supported:

 * MaxScale 1.4
* MaxScale 2.0
* MaxScale 2.1
* MaxScale 2.2
* MaxScale 2.3
* MaxScale 2.4
* MaxScale 2.5
* MaxScale 6.1
* MaxScale 6.2

 The special identifiers `latest` (for the latest GA release) and `beta` (for the latest beta release) are also supported. By default the `mariadb_repo_setup` script uses `latest` as the version.

 #### 
`--os-type` and `--os-version`

 If you want to run this script on an unsupported OS that you believe to be package-compatible with an OS that is supported, then you can use the `--os-type` and `--os-version` options to override the script's OS detection. If you use either option, then you must use both options.

 The supported values for `--os-type` are:

 * `rhel`
* `debian`
* `ubuntu`
* `sles`

 If you use a non-supported value, then the script will fail, just as it would fail if you ran the script on an unsupported OS.

 The supported values for `--os-version` are entirely dependent on the OS type.

 For Red Hat Enterprise Linux (RHEL) and CentOS, `7` and `8` are valid options.

 For Debian and Ubuntu, the version must be specified as the codename of the specific release. For example, Debian 9 must be specified as `stretch`, and Ubuntu 18.04 must be specified as `bionic`.

 These options can be useful if your distribution is a fork of another distribution. As an example, Linux Mint 8.1 is based on and is fully compatible with Ubuntu 16.04 LTS (Xenial). Therefore, If you are using Linux Mint 8.1, then you can configure your system to install from the repository of Ubuntu 16.04 LTS (Xenial). If you would like to do that, then you can do so by specifying `--os-type=ubuntu` and `--os-version=xenial` to the MariaDB Package Repository setup script.

 For example, to manually set the `--os-type` and `--os-version` to RHEL 8 you could do:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --os-type=rhel --os-version=8

```

#### `--write-to-stdout`

 The `--write-to-stdout` option will prevent the script from modifying anything on the system. The repository configuration will not be written to the repository configuration file. Instead, it will be printed to standard output. That allows the configuration to be reviewed, redirected elsewhere, consumed by another script, or used in some other way.

 The `--write-to-stdout` option automatically enables `--skip-key-import`.

 For example:

 
```
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --write-to-stdout

```

### Platform-Specific Behavior

 #### Platform-Specific Behavior on RHEL and CentOS

 On Red Hat Enterprise Linux (RHEL) and CentOS, the MariaDB Package Repository setup script performs the following tasks:

 1. Creates a repository configuration file at `/etc/yum.repos.d/mariadb.repo`.

 2. Imports the GPG public key used to verify the signature of MariaDB software packages with `rpm --import` from `downloads.mariadb.com`.

 #### Platform-Specific Behavior on Debian and Ubuntu

 On Debian and Ubuntu, the MariaDB Package Repository setup script performs the following tasks:

 1. Creates a repository configuration file at `/etc/apt/sources.list.d/mariadb.list`.

 2. Creates a package preferences file at `/etc/apt/preferences.d/mariadb-enterprise.pref`, which gives packages from MariaDB repositories a higher priority than packages from OS and other repositories, which can help avoid conflicts. It looks like the following:

 
```
Package: *
Pin: origin downloads.mariadb.com
Pin-Priority: 1000

```
 3. Imports the GPG public key used to verify the signature of MariaDB software package with `apt-key` from the `keyserver.ubuntu.com` key server.

 4. Updates the package cache with package definitions from the MariaDB Package Repository with `apt-get update`.

 #### Platform-Specific Behavior on SLES

 On SUSE Linux Enterprise Server (SLES), the MariaDB Package Repository setup script performs the following tasks:

 1. Creates a repository configuration file at `/etc/zypp/repos.d/mariadb.repo`.

 2. Imports the GPG public key used to verify the signature of MariaDB software packages with `rpm --import` from `downloads.mariadb.com`.

 Installing Packages with the MariaDB Package Repository
-------------------------------------------------------

 After setting up the MariaDB Package Repository, you can install the software packages in the supported repositories.

 ### Installing Packages on RHEL and CentOS

 To install MariaDB on Red Hat Enterprise Linux (RHEL) and CentOS, see the instructions at [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum). For example:

 
```
sudo yum install MariaDB-server MariaDB-client MariaDB-backup

```

To install MariaDB MaxScale on Red Hat Enterprise Linux (RHEL) and CentOS, see the instructions at [MariaDB MaxScale Installation Guide](../mariadb-maxscale-23-mariadb-maxscale-installation-guide/index). For example:

 
```
sudo yum install maxscale

```

### Installing Packages on Debian and Ubuntu

 To install MariaDB on Debian and Ubuntu, see the instructions at [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt). For example:

 
```
sudo apt-get install mariadb-server mariadb-client mariadb-backup

```

To install MariaDB MaxScale on Debian and Ubuntu, see the instructions at [MariaDB MaxScale Installation Guide](../mariadb-maxscale-23-mariadb-maxscale-installation-guide/index). For example:

 
```
sudo apt-get install maxscale

```

### Installing Packages on SLES

 To install MariaDB on SUSE Linux Enterprise Server (SLES), see the instructions at [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp). For example:

 
```
sudo zypper install MariaDB-server MariaDB-client MariaDB-backup

```

To install MariaDB MaxScale on SUSE Linux Enterprise Server (SLES), see the instructions at [MariaDB MaxScale Installation Guide](../mariadb-maxscale-23-mariadb-maxscale-installation-guide/index). For example:

 
```
sudo zypper install maxscale

```

Versions
--------

 


| Version | sha256sum |
| --- | --- |
| 2023-06-09 | `3a562a8861fc6362229314772c33c289d9096bafb0865ba4ea108847b78768d2` |
| 2023-02-16 | `ad125f01bada12a1ba2f9986a21c59d2cccbe8d584e7f55079ecbeb7f43a4da4` |
| 2022-11-17 | `367a80b01083c34899958cdd62525104a3de6069161d309039e84048d89ee98b` |
| 2022-08-22 | `733cf126b03f73050e242102592658913d10829a5bf056ab77e7f864b3f8de1f` |
| 2022-08-15 | `f99e1d560bd72a3a23f64eaede8982d5494407cafa8f995de45fb9a7274ebc5c` |
| 2022-06-14 | `d4e4635eeb79b0e96483bd70703209c63da55a236eadd7397f769ee434d92ca8` |
| 2022-02-08 | `b9e90cde27affc2a44f9fc60e302ccfcacf71f4ae02071f30d570e6048c28597` |
| 2022-01-18 | `c330d2755e18e48c3bba300a2898b0fc8ad2d3326d50b64e02fe65c67b454599` |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-package-repository-setup-and-usage/>

Upgrading Between Major MariaDB Versions
========================================

     MariaDB is designed to allow easy upgrades. You should be able to trivially upgrade from ANY earlier MariaDB version to the latest one (for example [MariaDB 10.3](../what-is-mariadb-103/index).x to [MariaDB 10.11](../what-is-mariadb-1011/index).x), usually in a few seconds. This is also mainly true for any MySQL version < 8.0 to [MariaDB 10.4](../what-is-mariadb-104/index) and up.

 Upgrades are normally easy because:

 * All MariaDB table data files are backward compatible
* The MariaDB connection protocol is backward compatible. You don't normally need to upgrade any of your old clients to be able to connect to a newer MariaDB version.
* The MariaDB replica can be of any newer version than the primary.

 MariaDB Corporation regularly runs tests to check that one can upgrade from [MariaDB 5.5](../what-is-mariadb-55/index) to the latest MariaDB version without any trouble. All older versions should work too (as long as the storage engines you were using are still around).

 Note that if you are using [MariaDB Galera Cluster](../galera-cluster/index), you have to follow the [Galera upgrading instructions](../upgrading-galera-cluster/index)!

 Requirements for Doing an Upgrade Between Major Versions
--------------------------------------------------------

 * Go through the individual version upgrade notes (listed below) to look for any major changes or configuration options that have changed.
* Ensure that the target MariaDB version supports the storage engines you are using. For example, in 10.5 [TokuDB](../tokudb/index) is not supported.
* Backup the database (just in case). At least, take a copy of the `mysql` data directory with [mariadb-dump --add-drop-table mysql](../mariadb-dump/index) (called mysqldump in [MariaDB 10.3](../what-is-mariadb-103/index) and earlier) as most of the upgrade changes are done there (adding new fields and new system tables etc).
* Cleanly shutdown the server. This is necessary because even if data files are compatible between versions, recovery logs may not be.
	+ Ensure that the [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) variable is not 2 (fast crash shutdown) or 3. The default of this variable is 1. The safest and recommended option for upgrades is 0. The shutdown time may be notably larger with 0 than for 1 as there are a lot more cleanups done for 0, however when preparing for an upgrade this should not be an issue.
	+ [innodb\_force\_recovery](../innodb-system-variables/index#innodb_force_recovery) must be less than `3`.

 Note that rpms don't support upgrading between major versions, only minor like 10.4.1 to 10.4.2. If you are using rpms, you should de-install the old MariaDB rpms and install the new MariaDB rpms before running [mariadb-upgrade](../mariadb-upgrade/index). Note that when installing the new rpms, [mariadb-upgrade](../mariadb-upgrade/index) may be run automatically. There is no problem with running [mariadb-upgrade](../mariadb-upgrade/index) many times.

 Recommended Steps
-----------------

 * If you have a [primary-replica setup](../standard-replication/index), first upgrade one replica and when you have verified that the replica works well, upgrade the rest of the replicas (if any). Then [upgrade one replica to primary](../changing-a-replica-to-become-the-primary/index), upgrade the primary, and change the replica to a primary.

 * If you don't have a primary-replica setup, then [take a backup](../mariabackup/index), [shutdown MariaDB](../mysqladmin/index) and do the upgrade.

 ### Step by Step Instructions for Upgrades

 * Upgrade MariaDB binaries and libraries, preferably without starting MariaDB.
* If the MariaDB server process, [mysqld or mariadbd](https://mariadb.com/mysqld-options) was not started as part of the upgrade, start it by executing `mysqld --skip-grant-tables`. This may produce some warnings about some system tables not being up to date, but you can ignore these for now as [mariadb-upgrade](../mariadb-upgrade/index) will fix that.
* Run [mariadb-upgrade](../mariadb-upgrade/index)
* Restart MariaDB server.

 Work Done by mariadb-upgrade
----------------------------

 The main work done when upgrading is done by running [mariadb-upgrade](../mariadb-upgrade/index). The main things it does are:

 * Updating the system tables in the `mysql` database to the newest version. This is very quick.
* [mariadb-upgrade](../mariadb-upgrade/index) also runs [mariadb-check --check-upgrade](../mariadb-check/index) to check if there have been any collation changes between the major versions. This recreates indexes in old tables that are using any of the changed collations. This can take a bit of time if there are a lot of tables or there are many tables which used the changed collation. The last time a collation changed was in MariaDB/MySQL 5.1.23.

 Post Upgrade Work
-----------------

 Check the [MariaDB error log](../error-log/index) for any problems during upgrade. If there are any warnings in the log files, do your best to get rid of them!

 The common warnings/errors are:

 * Using obsolete options. If this is the case, remove them from your [my.cnf files](../configuring-mariadb-with-option-files/index).

 * Check the manual for [new features](../upgrading/index) that have been added since your last MariaDB version.
* Test that your application works as before. The main difference from before is that because of optimizer improvements your application should work better than before, but in some rare cases the optimizer may get something wrong. In this case, you can try to use [explain](../explain/index), [optimizer trace](../mariadb-internals-documentation-optimizer-trace/index) or [optimizer\_switch](../optimizer-switch/index) to fix the queries.

 If Something Goes Wrong
-----------------------

 * First, check the [MariaDB error log](../error-log/index) to see if you are using configure options that are not supported anymore.
* Check the upgrade notices for the MariaDB release that you are upgrading to.
* File an issue in the [MariaDB bug tracker](../bug-tracking/index) so that we know about the issue and can provide a fix to make upgrades even better.
* Add a comment to this manual entry for how we can improve it.

 ### Disaster Recovery

 In the unlikely event something goes wrong, you can try the following:

 * Remove the InnoDB tables from the `mysql` data directory. They are:
	+ gtid\_slave\_pos
	+ innodb\_table\_stats
	+ innodb\_index\_stats
	+ transaction\_registry
* Move the `mysql` data directory to `mysql-old` and run [mariadb-install-db](../mariadb-install-db/index) to generate a new one.
* After the above, you have to add back your old users.
* When done, delete the `mysql-old` data directory.

 Downgrading
-----------

 MariaDB server is not designed for downgrading. That said, in most cases, as long as you haven't run any [ALTER TABLE](../alter-table/index) or [CREATE TABLE](../create-table/index) statements and you have a [mariadb-dump](../mariadb-dump/index) of your old `mysql` database , you should be able to downgrade to your previous version by doing the following:

 * Do a clean shutdown. For this special case you have to set [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) to 0,before taking down the new MariaDB server, to ensure there are no redo or undo logs that need to be applied on the downgraded server.
* Delete the tables in the `mysql` database (if you didn't use the option `--add-drop-table` to [mariadb-dump](../mariadb-dump/index))
* Delete the new MariaDB installation
* Install the old MariaDB version
* Start the server with [mysqld --skip-grant-tables](../mysqld-options/index#-skip-grant-tables)
* Install the old `mysql` database
* Execute in the [mariadb client](../mariadb-client/index) `FLUSH PRIVILEGES`

 See Also
--------

 * [Upgrading from MySQL to MariaDB](../upgrading-from-mysql-to-mariadb/index)
* [Upgrading from MariaDB 10.11 to MariaDB 11.0](../upgrading-from-mariadb-10-11-to-mariadb-11-0/index)
* [Upgrading from MariaDB 10.6 to MariaDB 10.11](../upgrading-from-mariadb-10-6-to-mariadb-10-11/index)
* [Upgrading from MariaDB 10.6 to MariaDB 10.7](../upgrading-from-mariadb-106-to-mariadb-107/index)
* [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-105-to-mariadb-106/index)
* [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index)
* [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index)

 * [Galera upgrading instructions](../upgrading-galera-cluster/index)
* [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-between-major-mariadb-versions/>

Upgrading Between Minor Versions on Linux
=========================================

    
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading Between Minor Versions with Galera Cluster](../upgrading-between-minor-versions-with-galera-cluster/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  To upgrade between minor versions of MariaDB on Linux/Unix (for example from [MariaDB 10.11.2](https://mariadb.com/kb/en/mariadb-10-11-2-release-notes/) to [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/)), the following procedure is suggested:

 1. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
2. Uninstall the old version of MariaDB.
3. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
4. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`.
5. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
6. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysq](../the-mysql-database-tables/index)l database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .
	* In most cases this should be a fast operation (depending of course on the number of tables).

 To upgrade between major versions, see the following:

 * [Upgrading Between Major MariaDB Versions](../upgrading-between-major-mariadb-versions/index)
* [Upgrading from MariaDB 10.6 to MariaDB 10.11](../upgrading-from-mariadb-10-6-to-mariadb-10-11/index)
* [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-10-5-to-mariadb-10-6/index)
* [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index)
* [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-between-minor-versions-on-linux/>

Upgrading from MariaDB 10.11 to MariaDB 11.0
============================================

    
This page includes details for upgrading from [MariaDB 10.11](../what-is-mariadb-1011/index) to [MariaDB 11.0](../what-is-mariadb-110/index). It is currently incomplete. Note that [MariaDB 10.11](../what-is-mariadb-1011/index) is [maintained for five years](https://mariadb.org/about/#maintenance-policy), while [MariaDB 11.0](../what-is-mariadb-110/index) is a short-term maintenance release, only maintained for one year.

 
### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index).

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 11.0](../what-is-mariadb-110/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.11 and 11.0

 On most servers upgrading from 10.11 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Options That Have Changed Default Values

 


| Option | Old default | New default |
| --- | --- | --- |
| [innodb\_undo\_tablespaces](../innodb-system-variables/index#innodb_undo_tablespaces) | 0 | 3 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_change\_buffer\_max\_size](../innodb-system-variables/index#innodb_change_buffer_max_size) | [InnoDB Change Buffer removed](../innodb-change-buffering/index) |
| [innodb\_change\_buffering](../innodb-system-variables/index#innodb_change_buffering) | [InnoDB Change Buffer removed](../innodb-change-buffering/index) |

 
#### Deprecated Options

 The following options have been deprecated. They have not yet been removed, but will be in a future version, and should ideally no longer be used.

 


| Option | Reason |
| --- | --- |
| [innodb\_defragment](../innodb-system-variables/index#innodb_defragment) | [InnoDB Defragmentation](../defragmenting-innodb-tablespaces/index#innodb-defragmentation) is not particularly useful and causes a maintenance burden. |
| [innodb\_defragment\_n\_pages](../innodb-system-variables/index#innodb_defragment_n_pages) |  |
| [innodb\_defragment\_stats\_accuracy](../innodb-system-variables/index#innodb_defragment_stats_accuracy) |  |
| [innodb\_defragment\_fill\_factor\_n\_recs](../innodb-system-variables/index#innodb_defragment_fill_factor_n_recs) |  |
| [innodb\_defragment\_fill\_factor](../innodb-system-variables/index#innodb_defragment_fill_factor) |  |
| [innodb\_defragment\_frequency](../innodb-system-variables/index#innodb_defragment_frequency) |  |
| [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) |  |
| [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method) |  |
| [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) | Has been set for many releases. Unsetting (the original InnoDB default) is no longer useful) |
| [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method) | Mapped it to 4 new boolean parameters that can be changed while the server is running |

 
### See Also

 * [Features in MariaDB 11.0](../what-is-mariadb-11-0/index)
* [Features in MariaDB 10.11](../what-is-mariadb-1011/index)

 
* [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster)

 
* [Upgrading from MariaDB 10.6 to MariaDB 10.11](../upgrading-from-mariadb-10-6-to-mariadb-10-11/index)
* [Upgrading from MariaDB 10.7 to MariaDB 10.8](../upgrading-from-mariadb-10-7-to-mariadb-10-8/index)
* [Upgrading from MariaDB 10.6 to MariaDB 10.7](../upgrading-from-mariadb-106-to-mariadb-107/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-10-11-to-mariadb-11-0/>

Upgrading from MariaDB 10.6 to MariaDB 10.11
============================================

    
This page includes details for upgrading from [MariaDB 10.6](../what-is-mariadb-106/index) to the subsequent long-term maintenance version, [MariaDB 10.11](../what-is-mariadb-1011/index). It is currently incomplete.

 
### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index).

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.11](../what-is-mariadb-1011/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.6 and 10.11

 On most servers upgrading from 10.6 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Compression

 If a non-zlib compression algorithm was used in [InnoDB](../innodb/index) or [Mroonga](../mroonga/index) before upgrading to 10.11, those tables will be unreadable until the appropriate compression library is installed. See [Compression Plugins#Upgrading](../compression-plugins/index#upgrading).

 #### Options That Have Changed Default Values

 


| Option | Old default | New default |
| --- | --- | --- |
| [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) | 134217728 | Autosized |
| [spider\_auto\_increment\_mode](../spider-server-system-variables/index#spider_auto_increment_mode) | -1 | 0 |
| [spider\_bgs\_first\_read](../spider-server-system-variables/index#spider_bgs_first_read) | -1 | 2 |
| [spider\_bgs\_mode](../spider-server-system-variables/index#spider_bgs_mode) | -1 | 0 |
| [spider\_bgs\_second\_read](../spider-server-system-variables/index#spider_bgs_second_read) | -1 | 100 |
| [spider\_bka\_mode](../spider-server-system-variables/index#spider_bka_mode) | -1 | 1 |
| [spider\_bka\_table\_name\_type](../spider-server-system-variables/index#spider_bka_table_name_type) | -1 | 1 |
| [spider\_buffer\_size](../spider-server-system-variables/index#spider_buffer_size) | -1 | 16000 |
| [spider\_bulk\_size](../spider-server-system-variables/index#spider_bulk_size) | -1 | 16000 |
| [spider\_bulk\_update\_mode](../spider-server-system-variables/index#spider_bulk_update_mode) | -1 | 0 |
| [spider\_bulk\_update\_size](../spider-server-system-variables/index#spider_bulk_update_size) | -1 | 16000 |
| [spider\_casual\_read](../spider-server-system-variables/index#spider_casual_read) | -1 | 0 |
| [spider\_connect\_timeout](../spider-server-system-variables/index#spider_connect_timeout) | -1 | 6 |
| [spider\_crd\_bg\_mode](../spider-server-system-variables/index#spider_crd_bg_mode) | -1 | 2 |
| [spider\_crd\_interval](../spider-server-system-variables/index#spider_crd_interval) | -1 | 51 |
| [spider\_crd\_mode](../spider-server-system-variables/index#spider_crd_mode) | -1 | 1 |
| [spider\_crd\_sync](../spider-server-system-variables/index#spider_crd_sync) | -1 | 0 |
| [spider\_crd\_type](../spider-server-system-variables/index#spider_crd_type) | -1 | 2 |
| [spider\_crd\_weight](../spider-server-system-variables/index#spider_crd_weight) | -1 | 2 |
| [spider\_delete\_all\_rows\_type](../spider-server-system-variables/index#spider_delete_all_rows_type) | -1 | 1 |
| [spider\_direct\_dup\_insert](../spider-server-system-variables/index#spider_direct_dup_insert) | -1 | 0 |
| [spider\_direct\_order\_limit](../spider-server-system-variables/index#spider_direct_order_limit) | -1 | 9223372036854775807 |
| [spider\_error\_read\_mode](../spider-server-system-variables/index#spider_error_read_mode) | -1 | 0 |
| [spider\_error\_write\_mode](../spider-server-system-variables/index#spider_error_write_mode) | -1 | 0 |
| [spider\_first\_read](../spider-server-system-variables/index#spider_first_read) | -1 | 0 |
| [spider\_init\_sql\_alloc\_size](../spider-server-system-variables/index#spider_init_sql_alloc_size) | -1 | 1024 |
| [spider\_internal\_limit](../spider-server-system-variables/index#spider_internal_limit) | -1 | 9223372036854775807 |
| [spider\_internal\_offset](../spider-server-system-variables/index#spider_internal_offset) | -1 | 0 |
| [spider\_internal\_optimize](../spider-server-system-variables/index#spider_internal_optimize) | -1 | 0 |
| [spider\_internal\_optimize\_local](../spider-server-system-variables/index#spider_internal_optimize_local) | -1 | 0 |
| [spider\_load\_crd\_at\_startup](../spider-server-system-variables/index#spider_load_crd_at_startup) | -1 | 1 |
| [spider\_load\_sts\_at\_startup](../spider-server-system-variables/index#spider_load_sts_at_startup) | -1 | 1 |
| [spider\_low\_mem\_read](../spider-server-system-variables/index#spider_low_mem_read) | -1 | 1 |
| [spider\_max\_order](../spider-server-system-variables/index#spider_max_order) | -1 | 32767 |
| [spider\_multi\_split\_read](../spider-server-system-variables/index#spider_multi_split_read) | -1 | 100 |
| [spider\_net\_read\_timeout](../spider-server-system-variables/index#spider_net_read_timeout) | -1 | 600 |
| [spider\_net\_write\_timeout](../spider-server-system-variables/index#spider_net_write_timeout) | -1 | 600 |
| [spider\_quick\_mode](../spider-server-system-variables/index#spider_quick_mode) | -1 | 3 |
| [spider\_quick\_page\_byte](../spider-server-system-variables/index#spider_quick_page_byte) | -1 | 10485760 |
| [spider\_quick\_page\_size](../spider-server-system-variables/index#spider_quick_page_size) | -1 | 1024 |
| [spider\_read\_only\_mode](../spider-server-system-variables/index#spider_read_only_mode) | -1 | 0 |
| [spider\_reset\_sql\_alloc](../spider-server-system-variables/index#spider_reset_sql_alloc) | -1 | 1 |
| [spider\_second\_read](../spider-server-system-variables/index#spider_second_read) | -1 | 0 |
| [spider\_selupd\_lock\_mode](../spider-server-system-variables/index#spider_selupd_lock_mode) | -1 | 1 |
| [spider\_semi\_split\_read](../spider-server-system-variables/index#spider_semi_split_read) | -1 | 2 |
| [spider\_semi\_split\_read\_limit](../spider-server-system-variables/index#spider_semi_split_read_limit) | -1 | 1 |
| [spider\_semi\_table\_lock\_connection](../spider-server-system-variables/index#spider_semi_table_lock_connection) | -1 | 1 |
| [spider\_semi\_table\_lock](../spider-server-system-variables/index#spider_semi_table_lock) | 1 | 0 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_log\_write\_ahead\_size](../innodb-system-variables/index#innodb_log_write_ahead_size) | On Linux and Windows, the physical block size of the underlying storage is instead detected and used. |
| [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |
| [wsrep\_strict\_ddl](../galera-cluster-system-variables/index#wsrep_strict_ddl) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |

 
#### Deprecated Options

 The following options have been deprecated. They have not yet been removed, but will be in a future version, and should ideally no longer be used.

 


| Option | Reason |
| --- | --- |
| [keep\_files\_on\_create](../server-system-variables/index#keep_files_on_create) | MariaDB now deletes orphan files, so this setting should never be necessary. |

 
### See Also

 * [Features in MariaDB 10.11](../what-is-mariadb-1011/index)
* [Features in MariaDB 10.10](../what-is-mariadb-1010/index)
* [Features in MariaDB 10.9](../what-is-mariadb-109/index)
* [Features in MariaDB 10.8](../what-is-mariadb-108/index)
* [Features in MariaDB 10.7](../what-is-mariadb-107/index)

 
* [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster)

 
* [Upgrading from MariaDB 10.7 to MariaDB 10.8](../upgrading-from-mariadb-10-7-to-mariadb-10-8/index)
* [Upgrading from MariaDB 10.6 to MariaDB 10.7](../upgrading-from-mariadb-106-to-mariadb-107/index)
* [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-105-to-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-11/>

Upgrading from MariaDB 10.7 to MariaDB 10.8
===========================================

    
Note that [MariaDB 10.8](../what-is-mariadb-108/index) is [only maintained for one year](https://mariadb.org/about/#maintenance-policy). [MariaDB 10.6](../what-is-mariadb-106/index) is currently the latest long-term maintenance release.

 
### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index).

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.7 to MariaDB 10.8 with Galera Cluster](upgrading-from-mariadb-107-to-mariadb-108-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.8](../what-is-mariadb-108/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.7 and 10.8

 On most servers upgrading from 10.7 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Options That Have Changed Default Values

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) | 134217728 | Autosized |
| [spider\_semi\_table\_lock](../spider-server-system-variables/index#spider_semi_table_lock) | 1 | 0 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_log\_write\_ahead\_size](../innodb-system-variables/index#innodb_log_write_ahead_size) | On Linux and Windows, the physical block size of the underlying storage is instead detected and used. |

 
#### Deprecated Options

 The following options have been deprecated. They have not yet been removed, but will be in a future version, and should ideally no longer be used.

 


| Option | Reason |
| --- | --- |
| [keep\_files\_on\_create](../server-system-variables/index#keep_files_on_create) | MariaDB now deletes orphan files, so this setting should never be necessary. |

 
### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.8](../what-is-mariadb-108/index):

 * Stored procedures already have support for the [IN, OUT and INOUT](../create-procedure/index#inoutinout) parameter qualifiers. Added as well for [stored functions](../create-function/index#in-out-inout-in-out) and (IN only) [cursors](../declare-cursor/index#in) ([MDEV-10654](https://jira.mariadb.org/browse/MDEV-10654)).
* Individual columns in the [index](../optimization-and-indexes/index) can now be explicitly sorted in the ascending or descending order. This can be useful for optimizing certain [ORDER BY](../order-by/index) cases ([MDEV-13756](https://jira.mariadb.org/browse/MDEV-13756), [MDEV-26938](https://jira.mariadb.org/browse/MDEV-26938), [MDEV-26939](https://jira.mariadb.org/browse/MDEV-26939), [MDEV-26996](https://jira.mariadb.org/browse/MDEV-26996)).
* See also [System Variables Added in MariaDB 10.8](../system-variables-added-in-mariadb-10-8/index).

 ### See Also

 * [The features in MariaDB 10.8](../what-is-mariadb-108/index)

 
* [Upgrading from MariaDB 10.7 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-107-to-mariadb-108-with-galera-cluster)

 
* [Upgrading from MariaDB 10.6 to MariaDB 10.7](../upgrading-from-mariadb-106-to-mariadb-107/index)
* [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-105-to-mariadb-106/index)
* [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-10-7-to-mariadb-10-8/>

Upgrading from MariaDB 10.6 to MariaDB 10.7
===========================================

    
Note that [MariaDB 10.7](../what-is-mariadb-107/index) is [only maintained for one year](https://mariadb.org/about/#maintenance-policy). [MariaDB 10.6](../what-is-mariadb-106/index) is currently the latest long-term maintenance release.

 
### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index).

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.7](../what-is-mariadb-107/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.6 and 10.7

 On most servers upgrading from 10.6 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Reserved Words

 * ROW\_NUMBER is now a [reserved word](../reserved-words/index).

 #### Compression

 If a non-zlib compression algorithm was used in [InnoDB](../innodb/index) or [Mroonga](../mroonga/index) before upgrading to 10.7, those tables will be unreadable until the appropriate compression library is installed. See [Compression Plugins#Upgrading](../compression-plugins/index#upgrading).

 #### Options That Have Changed Default Values

 


| Option | Old default | New default |
| --- | --- | --- |
| [spider\_auto\_increment\_mode](../spider-server-system-variables/index#spider_auto_increment_mode) | -1 | 0 |
| [spider\_bgs\_first\_read](../spider-server-system-variables/index#spider_bgs_first_read) | -1 | 2 |
| [spider\_bgs\_mode](../spider-server-system-variables/index#spider_bgs_mode) | -1 | 0 |
| [spider\_bgs\_second\_read](../spider-server-system-variables/index#spider_bgs_second_read) | -1 | 100 |
| [spider\_bka\_mode](../spider-server-system-variables/index#spider_bka_mode) | -1 | 1 |
| [spider\_bka\_table\_name\_type](../spider-server-system-variables/index#spider_bka_table_name_type) | -1 | 1 |
| [spider\_buffer\_size](../spider-server-system-variables/index#spider_buffer_size) | -1 | 16000 |
| [spider\_bulk\_size](../spider-server-system-variables/index#spider_bulk_size) | -1 | 16000 |
| [spider\_bulk\_update\_mode](../spider-server-system-variables/index#spider_bulk_update_mode) | -1 | 0 |
| [spider\_bulk\_update\_size](../spider-server-system-variables/index#spider_bulk_update_size) | -1 | 16000 |
| [spider\_casual\_read](../spider-server-system-variables/index#spider_casual_read) | -1 | 0 |
| [spider\_connect\_timeout](../spider-server-system-variables/index#spider_connect_timeout) | -1 | 6 |
| [spider\_crd\_bg\_mode](../spider-server-system-variables/index#spider_crd_bg_mode) | -1 | 2 |
| [spider\_crd\_interval](../spider-server-system-variables/index#spider_crd_interval) | -1 | 51 |
| [spider\_crd\_mode](../spider-server-system-variables/index#spider_crd_mode) | -1 | 1 |
| [spider\_crd\_sync](../spider-server-system-variables/index#spider_crd_sync) | -1 | 0 |
| [spider\_crd\_type](../spider-server-system-variables/index#spider_crd_type) | -1 | 2 |
| [spider\_crd\_weight](../spider-server-system-variables/index#spider_crd_weight) | -1 | 2 |
| [spider\_delete\_all\_rows\_type](../spider-server-system-variables/index#spider_delete_all_rows_type) | -1 | 1 |
| [spider\_direct\_dup\_insert](../spider-server-system-variables/index#spider_direct_dup_insert) | -1 | 0 |
| [spider\_direct\_order\_limit](../spider-server-system-variables/index#spider_direct_order_limit) | -1 | 9223372036854775807 |
| [spider\_error\_read\_mode](../spider-server-system-variables/index#spider_error_read_mode) | -1 | 0 |
| [spider\_error\_write\_mode](../spider-server-system-variables/index#spider_error_write_mode) | -1 | 0 |
| [spider\_first\_read](../spider-server-system-variables/index#spider_first_read) | -1 | 0 |
| [spider\_init\_sql\_alloc\_size](../spider-server-system-variables/index#spider_init_sql_alloc_size) | -1 | 1024 |
| [spider\_internal\_limit](../spider-server-system-variables/index#spider_internal_limit) | -1 | 9223372036854775807 |
| [spider\_internal\_offset](../spider-server-system-variables/index#spider_internal_offset) | -1 | 0 |
| [spider\_internal\_optimize](../spider-server-system-variables/index#spider_internal_optimize) | -1 | 0 |
| [spider\_internal\_optimize\_local](../spider-server-system-variables/index#spider_internal_optimize_local) | -1 | 0 |
| [spider\_load\_crd\_at\_startup](../spider-server-system-variables/index#spider_load_crd_at_startup) | -1 | 1 |
| [spider\_load\_sts\_at\_startup](../spider-server-system-variables/index#spider_load_sts_at_startup) | -1 | 1 |
| [spider\_low\_mem\_read](../spider-server-system-variables/index#spider_low_mem_read) | -1 | 1 |
| [spider\_max\_order](../spider-server-system-variables/index#spider_max_order) | -1 | 32767 |
| [spider\_multi\_split\_read](../spider-server-system-variables/index#spider_multi_split_read) | -1 | 100 |
| [spider\_net\_read\_timeout](../spider-server-system-variables/index#spider_net_read_timeout) | -1 | 600 |
| [spider\_net\_write\_timeout](../spider-server-system-variables/index#spider_net_write_timeout) | -1 | 600 |
| [spider\_quick\_mode](../spider-server-system-variables/index#spider_quick_mode) | -1 | 3 |
| [spider\_quick\_page\_byte](../spider-server-system-variables/index#spider_quick_page_byte) | -1 | 10485760 |
| [spider\_quick\_page\_size](../spider-server-system-variables/index#spider_quick_page_size) | -1 | 1024 |
| [spider\_read\_only\_mode](../spider-server-system-variables/index#spider_read_only_mode) | -1 | 0 |
| [spider\_reset\_sql\_alloc](../spider-server-system-variables/index#spider_reset_sql_alloc) | -1 | 1 |
| [spider\_second\_read](../spider-server-system-variables/index#spider_second_read) | -1 | 0 |
| [spider\_selupd\_lock\_mode](../spider-server-system-variables/index#spider_selupd_lock_mode) | -1 | 1 |
| [spider\_semi\_split\_read](../spider-server-system-variables/index#spider_semi_split_read) | -1 | 2 |
| [spider\_semi\_split\_read\_limit](../spider-server-system-variables/index#spider_semi_split_read_limit) | -1 | 1 |
| [spider\_semi\_table\_lock\_connection](../spider-server-system-variables/index#spider_semi_table_lock_connection) | -1 | 1 |
| [spider\_reset\_sql\_alloc](../spider-server-system-variables/index#spider_reset_sql_alloc) | -1 | 1 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |
| [wsrep\_strict\_ddl](../galera-cluster-system-variables/index#wsrep_strict_ddl) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |

 
### See Also

 * [The features in MariaDB 10.7](../what-is-mariadb-107/index)

 
* [Upgrading from MariaDB 10.6 to MariaDB 10.7 with Galera Cluster](upgrading-from-mariadb-106-to-mariadb-107-with-galera-cluster)

 
* [Upgrading from MariaDB 10.5 to MariaDB 10.6](../upgrading-from-mariadb-105-to-mariadb-106/index)
* [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index)
* [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-10-6-to-mariadb-10-7/>

Upgrading from MariaDB 10.5 to MariaDB 10.6
===========================================

    ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index).

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.5 to MariaDB 10.6 with Galera Cluster](upgrading-from-mariadb-105-to-mariadb-106-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.6](../what-is-mariadb-106/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mariadb-upgrade](../mariadb-upgrade/index).
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the [mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.5 and 10.6

 On most servers upgrading from 10.5 should be painless. However, there are some things that have changed which could affect an upgrade:

 The bahaviour of sorting non-deterministic variables in a Select query can be changed , see ([MDEV-27745](https://jira.mariadb.org/browse/MDEV-27745))

 #### Reserved Word

 * New [reserved word](../reserved-words/index): OFFSET. This can no longer be used as an [identifier](../identifier-names/index) without being quoted.

 #### InnoDB COMPRESSED Row Format

 From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) until [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/), tables that are of the `COMPRESSED` row format are read-only by default. This was intended to be the first step towards removing write support and deprecating the feature.

 This plan has been scrapped, and from [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), `COMPRESSED` tables are no longer read-only by default.

 From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) to [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/), set the [innodb\_read\_only\_compressed](../innodb-system-variables/index#innodb_read_only_compressed) variable to `OFF` to make the tables writable.

 #### Character Sets

 From [MariaDB 10.6](../what-is-mariadb-106/index), the `utf8` [character set](../character-sets/index) (and related collations) is by default an alias for `utf8mb3` rather than the other way around. It can be set to imply `utf8mb4` by changing the value of the [old\_mode](../server-system-variables/index#old_mode) system variable.

 #### Options That Have Changed Default Values

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [character\_set\_client](../server-system-variables/index#character_set_client) | utf8 | utf8mb3 |
| [character\_set\_connection](../server-system-variables/index#character_set_connection) | utf8 | utf8mb3 |
| [character\_set\_results](../server-system-variables/index#character_set_results) | utf8 | utf8mb3 |
| [character\_set\_system](../server-system-variables/index#character_set_system) | utf8 | utf8mb3 |
| [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method) | fsync | O\_DIRECT |
| [old\_mode](../server-system-variables/index#old_mode) | Empty | UTF8\_IS\_UTF8MB3 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_adaptive\_max\_sleep\_delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay) |  |
| [innodb\_background\_scrub\_data\_check\_interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval) |  |
| [innodb\_background\_scrub\_data\_compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed) |  |
| [innodb\_background\_scrub\_data\_interval](../innodb-system-variables/index#innodb_background_scrub_data_interval) |  |
| [innodb\_background\_scrub\_data\_uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed) |  |
| [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) |  |
| [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) | The variable is still present, but the `*innodb` and `*none` options have been removed as the `crc32` algorithm only is supported from [MariaDB 10.6](../what-is-mariadb-106/index). |
| [innodb\_commit\_concurrency](../innodb-system-variables/index#innodb_commit_concurrency) |  |
| [innodb\_concurrency\_tickets](../innodb-system-variables/index#innodb_concurrency_tickets) |  |
| [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) |  |
| [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) |  |
| [innodb\_lock\_schedule\_algorithm](../innodb-system-variables/index#innodb_lock_schedule_algorithm) |  |
| [innodb\_log\_checksums](../innodb-system-variables/index#innodb_log_checksums) |  |
| [innodb\_log\_compressed\_pages](../innodb-system-variables/index#innodb_log_compressed_pages) |  |
| [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group) |  |
| [innodb\_log\_optimize\_ddl](../innodb-system-variables/index#innodb_log_optimize_ddl) |  |
| [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) |  |
| [innodb\_replication\_delay](../innodb-system-variables/index#innodb_replication_delay) |  |
| [innodb\_scrub\_log](../innodb-system-variables/index#innodb_scrub_log) |  |
| [innodb\_scrub\_log\_speed](../innodb-system-variables/index#innodb_scrub_log_speed) |  |
| [innodb\_sync\_array\_size](../innodb-system-variables/index#innodb_sync_array_size) |  |
| [innodb\_thread\_concurrency](../innodb-system-variables/index#innodb_thread_concurrency) |  |
| [innodb\_thread\_sleep\_delay](../innodb-system-variables/index#innodb_thread_sleep_delay) |  |
| [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) |  |

 
#### Deprecated Options

 The following options have been deprecated. They have not yet been removed, but will be in a future version, and should ideally no longer be used.

 


| Option | Reason |
| --- | --- |
| [wsrep\_replicate\_myisam](../galera-cluster-system-variables/index#wsrep_replicate_myisam) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |
| [wsrep\_strict\_ddl](../galera-cluster-system-variables/index#wsrep_strict_ddl) | Use [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) instead. |

 
### Major New Features To Consider

 * See also [System Variables Added in MariaDB 10.6](../system-variables-added-in-mariadb-106/index).

 ### See Also

 * [The features in MariaDB 10.6](../what-is-mariadb-106/index)

 
* [Upgrading from MariaDB 10.5 to MariaDB 10.6 with Galera Cluster](upgrading-from-mariadb-105-to-mariadb-106-with-galera-cluster)

 
* [Upgrading from MariaDB 10.4 to MariaDB 10.5](../upgrading-from-mariadb-104-to-mariadb-105/index)
* [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-10-5-to-mariadb-10-6/>

Upgrading from MariaDB 10.4 to MariaDB 10.5
===========================================

    ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.4 to MariaDB 10.5 with Galera Cluster](upgrading-from-mariadb-104-to-mariadb-105-with-galera-cluster) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.5](../what-is-mariadb-105/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run [mysql\_upgrade](../mysql_upgrade/index).
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the#[mysql](../the-mysql-database-tables/index) database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.4 and 10.5

 On most servers upgrading from 10.4 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Binary name changes

 All binaries previously beginning with mysql now begin with mariadb, with symlinks for the corresponding mysql command.

 Usually that shouldn't cause any changed behavior, but when starting the MariaDB server via [systemd](../systemd/index), or via the [mysqld\_safe](../mysqld_safe/index) script symlink, the server process will now always be started as `mariadbd`, not `mysqld`.

 So anything looking for the `mysqld` name in the system process list, like e.g. monitoring solutions, now needs for `mariadbd` instead when the server / service is not started directly, but via `mysqld_safe` or as a system service.

 #### GRANT PRIVILEGE changes

 A number of statements changed the privileges that they require. The old privileges were historically inappropriately chosen in the upstream. 10.5.2 fixes this problem. Note, these changes are incompatible to previous versions. A number of GRANT commands might be needed after upgrade.

 * `SHOW BINLOG EVENTS` now requires the `BINLOG MONITOR` privilege (requred `REPLICATION SLAVE` prior to 10.5.2).
* `SHOW SLAVE HOSTS` now requires the `REPLICATION MASTER ADMIN` privilege (required `REPLICATION SLAVE` prior to 10.5.2).
* `SHOW SLAVE STATUS` now requires the `REPLICATION SLAVE ADMIN` or the `SUPER` privilege (required `REPLICATION CLIENT` or `SUPER` prior to 10.5.2).
* `SHOW RELAYLOG EVENTS` now requires the `REPLICATION SLAVE ADMIN` privilege (required `REPLICATION SLAVE` prior to 10.5.2).

 #### Options That Have Changed Default Values

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [innodb\_adaptive\_hash\_index](../innodb-system-variables/index#innodb_adaptive_hash_index) | ON | OFF |
| [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) | crc32 | full\_crc32 |
| [innodb\_log\_optimize\_ddl](../innodb-system-variables/index#innodb_log_optimize_ddl) | ON | OFF |
| [slave\_parallel\_mode](../replication-and-binary-log-system-variables/index#slave_parallel_mode) | conservative | optimistic |
| [performance\_schema\_max\_cond\_classes](../performance-schema-system-variables/index#performance_schema_max_cond_classes) | 80 | 90 |
| [performance\_schema\_max\_file\_classes](../performance-schema-system-variables/index#performance_schema_max_file_classes) | 50 | 80 |
| [performance\_schema\_max\_mutex\_classes](../performance-schema-system-variables/index#performance_schema_max_mutex_classes) | 200 | 210 |
| [performance\_schema\_max\_rwlock\_classes](../performance-schema-system-variables/index#performance_schema_max_rwlock_classes) | 40 | 50 |
| [performance\_schema\_setup\_actors\_size](../performance-schema-system-variables/index#performance_schema_setup_actors_size) | 100 | -1 |
| [performance\_schema\_setup\_objects\_size](../performance-schema-system-variables/index#performance_schema_setup_objects_size) | 100 | -1 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_checksums](../innodb-system-variables/index#innodb_checksums) | Deprecated and functionality replaced by [innodb\_checksum\_algorithms](../innodb-system-variables/index#innodb_checksum_algorithm) in [MariaDB 10.0](../what-is-mariadb-100/index). |
| [idle\_flush\_pct](../innodb-system-variables/index#innodb_idle_flush_pct) | Has had no effect since merging InnoDB 5.7 from mysql-5.7.9 ([MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)). |
| [innodb\_locks\_unsafe\_for\_binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog) | Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index). Use [READ COMMITTED transaction isolation level](../set-transaction/index#read-committed) instead. |
| [innodb\_rollback\_segments](../innodb-system-variables/index#innodb_rollback_segments) | Deprecated and replaced by [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) in [MariaDB 10.0](../what-is-mariadb-100/index). |
| [innodb\_stats\_sample\_pages](../innodb-system-variables/index#innodb_stats_sample_pages) | Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index). Use [innodb\_stats\_transient\_sample\_pages](../innodb-system-variables/index#innodb_stats_transient_sample_pages) instead. |
| [max\_long\_data\_size](../server-system-variables/index#max_long_data_size) | Deprecated and replaced by [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) in [MariaDB 5.5](../what-is-mariadb-55/index). |
| [multi\_range\_count](../server-system-variables/index#multi_range_count) | Deprecated and has had no effect since [MariaDB 5.3](../what-is-mariadb-53/index). |
| [thread\_concurrency](../server-system-variables/index#thread_concurrency) | Deprecated and has had no effect since [MariaDB 5.5](../what-is-mariadb-55/index). |
| [timed\_mutexes](../server-system-variables/index#timed_mutexes) | Deprecated and has had no effect since [MariaDB 5.5](../what-is-mariadb-55/index). |

 
#### Deprecated Options

 The following options have been deprecated. They have not yet been removed, but will be in a future version, and should ideally no longer be used.

 


| Option | Reason |
| --- | --- |
| [innodb\_adaptive\_max\_sleep\_delay](../innodb-system-variables/index#innodb_adaptive_max_sleep_delay) | No need for thread throttling any more. |
| [innodb\_background\_scrub\_data\_check\_interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval) | Problematic ‘background scrubbing’ code removed. |
| [innodb\_background\_scrub\_data\_interval](../innodb-system-variables/index#innodb_background_scrub_data_interval) | Problematic ‘background scrubbing’ code removed. |
| [innodb\_background\_scrub\_data\_compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed) | Problematic ‘background scrubbing’ code removed. |
| [innodb\_background\_scrub\_data\_uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed) | Problematic ‘background scrubbing’ code removed. |
| [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) | Having more than one buffer pool is no longer necessary. |
| [innodb\_commit\_concurrency](../innodb-system-variables/index#innodb_commit_concurrency) | No need for thread throttling any more. |
| [innodb\_concurrency\_tickets](../innodb-system-variables/index#innodb_concurrency_tickets) | No need for thread throttling any more. |
| [innodb\_log\_files\_in\_group](../innodb-system-variables/index#innodb_log_files_in_group) | Redo log was unnecessarily split into multiple files. Limited to 1 from [MariaDB 10.5](../what-is-mariadb-105/index). |
| [innodb\_log\_optimize\_ddl](../innodb-system-variables/index#innodb_log_optimize_ddl) | Prohibited optimizations. |
| [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) | Having more than one page cleaner task no longer necessary. |
| [innodb\_replication\_delay](../innodb-system-variables/index#innodb_replication_delay) | No need for thread throttling any more. |
| [innodb\_scrub\_log](../innodb-system-variables/index#innodb_scrub_log) | Never really worked as intended, redo log format is being redone. |
| [innodb\_scrub\_log\_speed](../innodb-system-variables/index#innodb_scrub_log_speed) | Never really worked as intended, redo log format is being redone. |
| [innodb\_thread\_concurrency](../innodb-system-variables/index#innodb_thread_concurrency) | No need for thread throttling any more. |
| [innodb\_thread\_sleep\_delay](../innodb-system-variables/index#innodb_thread_sleep_delay) | No need for thread throttling any more. |
| [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) | It always makes sense to use the maximum number of rollback segments. |
| [large\_page\_size](../server-system-variables/index#large_page_size) | Unused since multiple page size support was added. |

 
### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.5](../what-is-mariadb-105/index):

 * The [S3 storage engine](../s3-storage-engine/index) allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud that implements S3 API.
* [ColumnStore](../mariadb-columnstore/index) columnar storage engine.
* See also [System Variables Added in MariaDB 10.5](../system-variables-added-in-mariadb-105/index).

 ### See Also

 * [The features in MariaDB 10.5](../what-is-mariadb-105/index)

 
* [Upgrading from MariaDB 10.4 to MariaDB 10.5 with Galera Cluster](upgrading-from-mariadb-104-to-mariadb-105-with-galera-cluster)

 
* [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index)
* [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-104-to-mariadb-105/>

Upgrading from MariaDB 10.3 to MariaDB 10.4
===========================================

    ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster](../upgrading-from-mariadb-103-to-mariadb-104-with-galera-cluster/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.4](../what-is-mariadb-104/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run `[mysql\_upgrade](../mysql_upgrade/index)`.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.3 and 10.4

 On most servers upgrading from 10.3 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Options That Have Changed Default Values

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [slave\_transaction\_retry\_errors](../replication-and-binary-log-system-variables/index#slave_transaction_retry_errors) | 1213,1205 | 1158,1159,1160,1161,1205,1213,1429,2013,12701 |
| [wsrep\_debug](../galera-cluster-system-variables/index#wsrep_debug) | OFF | NONE |
| [wsrep\_load\_data\_splitting](../galera-cluster-system-variables/index#wsrep_load_data_splitting) | ON | OFF |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |

 
#### Authentication and TLS

 * See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for an overview of the changes.
* The [unix\_socket authentication plugin](../authentication-plugin-unix-socket/index) is now default on Unix-like systems.
* TLSv1.0 is disabled by default in [MariaDB 10.4](../what-is-mariadb-104/index). See [tls\_version](../ssltls-system-variables/index#tls_version) and [TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions).

 ### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.4](../what-is-mariadb-104/index):

 * [Galera](../galera-cluster/index) has been upgraded from [Galera](../galera-cluster/index) 3 to [Galera](../galera-cluster/index) 4.
* [System-versioning](../temporal-data-tables/index) extended with support for [application-time periods](../temporal-data-tables/index#application-time-periods).
* [User password expiry](../user-password-expiry/index)
* [Account Locking](../account-locking/index)
* See also [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-104/index).

 ### See Also

 * [The features in MariaDB 10.4](../what-is-mariadb-104/index)
* [Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster](../upgrading-from-mariadb-103-to-mariadb-104-with-galera-cluster/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index)
* [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index)
* [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-mariadb-101/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-103-to-mariadb-104/>

Upgrading from MariaDB 10.2 to MariaDB 10.3
===========================================

    ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster](../upgrading-from-mariadb-102-to-mariadb-103-with-galera-cluster/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.3](../what-is-mariadb-103/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index). The server should be cleanly shut down, with no incomplete transactions remaining. [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) must be set to `0` or `1` and [innodb\_force\_recovery](../innodb-system-variables/index#innodb_force_recovery) must be less than `3`.
3. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
4. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
5. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
6. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
7. Run `[mysql\_upgrade](../mysql_upgrade/index)`.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.2 and 10.3

 On most servers upgrading from 10.2 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Options That Have Changed Default Values

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [innodb\_flush\_method](../innodb-system-variables/index#innodb_flush_method) | (empty) | fsync |
| [innodb\_spin\_wait\_delay](../innodb-system-variables/index#innodb_spin_wait_delay) | 6 | 4 |
| [performance\_schema\_max\_stage\_classes](../performance-schema-system-variables/index#performance_schema_max_stage_classes) | 150 | 160 |
| [plugin\_maturity](../server-system-variables/index#plugin_maturity) | unknown | One less than the server maturity |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| [innodb\_buffer\_pool\_populate](../innodb-system-variables/index#innodb_buffer_pool_populate) | Used in XtraDB-only |
| [innodb\_cleaner\_lsn\_age\_factor](../innodb-system-variables/index#innodb_cleaner_lsn_age_factor) | Used in XtraDB-only |
| [innodb\_corrupt\_table\_action](../innodb-system-variables/index#innodb_corrupt_table_action) | Used in XtraDB-only |
| [innodb\_empty\_free\_list\_algorithm](../innodb-system-variables/index#innodb_empty_free_list_algorithm) | Used in XtraDB-only |
| [innodb\_fake\_changes](../innodb-system-variables/index#innodb_fake_changes) | Used in XtraDB-only |
| [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) | The [InnoDB file format](../xtradbinnodb-file-format/index) is now Barracuda, and the old Antelope file format is no longer supported. |
| [innodb\_file\_format\_check](../innodb-system-variables/index#innodb_file_format_check) | No longer necessary as the Antelope [InnoDB file format](../xtradbinnodb-file-format/index) is no longer supported. |
| [innodb\_file\_format\_max](../innodb-system-variables/index#innodb_file_format_max) | No longer necessary as the Antelope [InnoDB file format](../xtradbinnodb-file-format/index) is no longer supported. |
| [innodb\_foreground\_preflush](../innodb-system-variables/index#innodb_foreground_preflush) | Used in XtraDB-only |
| [innodb\_instrument\_semaphores](../innodb-system-variables/index#innodb_instrument_semaphores) |  |
| [innodb\_kill\_idle\_transaction](../innodb-system-variables/index#innodb_kill_idle_transaction) | Used in XtraDB-only |
| [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) | Large index key prefixes were made default from [MariaDB 10.2](../what-is-mariadb-102/index), and limiting tables to small prefixes is no longer permitted in [MariaDB 10.3](../what-is-mariadb-103/index). |
| [innodb\_locking\_fake\_changes](../innodb-system-variables/index#innodb_locking_fake_changes) | Used in XtraDB-only |
| [innodb\_log\_arch\_dir](../innodb-system-variables/index#innodb_log_arch_dir) | Used in XtraDB-only |
| [innodb\_log\_arch\_expire\_sec](../innodb-system-variables/index#innodb_log_arch_expire_sec) | Used in XtraDB-only |
| [innodb\_log\_archive](../innodb-system-variables/index#innodb_log_archive) | Used in XtraDB-only |
| [innodb\_log\_block\_size](../innodb-system-variables/index#innodb_log_block_size) | Used in XtraDB-only |
| [innodb\_log\_checksum\_algorithm](../innodb-system-variables/index#innodb_log_checksum_algorithm) | Translated to [innodb\_log\_checksums](../innodb-system-variables/index#innodb_log_checksums) (NONE to OFF, everything else to ON); only existed to allow easier upgrade from earlier XtraDB versions. |
| [innodb\_mtflush\_threads](../innodb-system-variables/index#innodb_mtflush_threads) | Replaced by the [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) system variable. |
| [innodb\_sched\_priority\_cleaner](../innodb-system-variables/index#innodb_sched_priority_cleaner) | Used in XtraDB-only |
| [innodb\_show\_locks\_held](../innodb-system-variables/index#innodb_show_locks_held) | Used in XtraDB-only |
| [innodb\_show\_verbose\_locks](../innodb-system-variables/index#innodb_show_verbose_locks) | Used in XtraDB-only |
| [innodb\_support\_xa](../innodb-system-variables/index#innodb_support_xa) | XA transactions are always supported. |
| [innodb\_use\_fallocate](../innodb-system-variables/index#innodb_use_fallocate) |  |
| [innodb\_use\_global\_flush\_log\_at\_trx\_commit](../innodb-system-variables/index#innodb_use_global_flush_log_at_trx_commit) | Used in XtraDB-only |
| [innodb\_use\_mtflush](../innodb-system-variables/index#innodb_use_mtflush) | Replaced by the [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) system variable. |
| [innodb\_use\_stacktrace](../innodb-system-variables/index#innodb_use_stacktrace) | Used in XtraDB-only |
| [innodb\_use\_trim](../innodb-system-variables/index#innodb_use_trim) |  |

 
#### Reserved Words

 * New [reserved words](../reserved-words/index): EXCEPT and INTERSECT. These can no longer be used as [identifiers](../identifier-names/index) without being quoted.

 #### SQL\_MODE=ORACLE

 * [MariaDB 10.3](../what-is-mariadb-103/index) has introduced major new Oracle compatibility features. If you upgrade and are using this setting, please check the [changes carefully](../what-is-mariadb-103/index).

 #### Functions

 * As a result of implementing Table Value Constructors, the [VALUES function](../values/index) has been renamed to VALUE().
* Functions that used to only return 64-bit now can return 32-bit results ([MDEV-12619](https://jira.mariadb.org/browse/MDEV-12619)). This could cause incompatibilities with strongly-typed clients.

 #### mysqldump

 * [mysqldump](../mysqldump/index) in [MariaDB 10.3](../what-is-mariadb-103/index) includes logic to cater for the [mysql.transaction\_registry table](../mysqltransaction_registry-table/index). `mysqldump` from an earlier MariaDB release cannot be used on [MariaDB 10.3](../what-is-mariadb-103/index) and beyond.

 #### MariaDB Backup and Percona XtraBackup

 * [Percona XtraBackup](../percona-xtrabackup/index) is not compatible with [MariaDB 10.3](../what-is-mariadb-103/index). Installations currently using XtraBackup should upgrade to [MariaDB Backup](../mariadb-backup/index) before upgrading to [MariaDB 10.3](../what-is-mariadb-103/index).

 #### Privileges

 * If a user has the [SUPER privilege](../grant/index) but not the `DELETE HISTORY` privilege, running [mysql\_upgrade](../mysql_upgrade/index) will grant `DELETE HISTORY` as well.

 ### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.3](../what-is-mariadb-103/index):

 * [System-versioned tables](../system-versioned-tables/index)
* [Sequences](../sequences/index)
* See also [System Variables Added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index).

 ### See Also

 * [The features in MariaDB 10.3](../what-is-mariadb-103/index)
* [Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster](../upgrading-from-mariadb-102-to-mariadb-103-with-galera-cluster/index)
* [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index)
* [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-mariadb-101/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-102-to-mariadb-103/>

Upgrading to Unmaintained MariaDB Releases
===========================================

  

| Title | Description |
| --- | --- |
|  [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index) |  How to upgrade from MariaDB 10.1 to MariaDB 10.2.  |
|  [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-mariadb-101/index) |  How to upgrade from MariaDB 10.0 to MariaDB 10.1.  |
|  [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index) |  How to upgrade from MariaDB 5.5 to MariaDB 10.0.  |
|  [Upgrading from MariaDB 5.3 to MariaDB 5.5](../upgrading-from-mariadb-53-to-mariadb-55/index) |  How to upgrade from MariaDB 5.3 to MariaDB 5.5  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-to-unmaintained-mariadb-releases/>

Time Zones
==========

    MariaDB keeps track of several time zone settings.

 Setting the Time Zone
---------------------

 The [time\_zone](../server-system-variables/index#time_zone) system variable is the primary way to set the time zone. It can be specified in one of the following formats:

 * The default value is `SYSTEM`, which indicates that the system time zone defined in the [system\_time\_zone](../server-system-variables/index#system_time_zone) system variable will be used. See [System Time Zone](#system-time-zone) below for more information.
* An offset from [Coordinated Universal Time (UTC)](../coordinated-universal-time/index), such as `+5:00` or `-9:00`, can also be used.
* If the time zone tables in the [mysql](../the-mysql-database-tables/index) database were loaded, then a named time zone, such as `America/New_York`, `Africa/Johannesburg`, or `Europe/Helsinki`, is also permissible. See [mysql Time Zone Tables](#mysql-time-zone-tables) below for more information.

 There are two time zone settings that can be set within MariaDB--the global server time zone, and the time zone for your current session. There is also a third time zone setting which may be relevant--the system time zone.

 ### Global Server Time Zone

 The global server time zone can be changed at server startup by setting the `--default-time-zone` option either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
default_time_zone = 'America/New_York'

```

The global server time zone can also be changed dynamically by setting the [time\_zone](../server-system-variables/index#time_zone) system variable as a user account that has the [SUPER](../grant/index#super) privilege. For example:

 
```
SET GLOBAL time_zone = 'America/New_York';

```

The current global server time zone can be viewed by looking at the global value of the [time\_zone](../server-system-variables/index#time_zone) system variable. For example:

 
```
SHOW GLOBAL VARIABLES LIKE 'time_zone';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM |
+---------------+--------+

```

### Session Time Zone

 Each session that connects to the server will also have its own time zone. This time zone is initially inherited from the global value of the [time\_zone](../server-system-variables/index#time_zone) system variable, which sets the session value of the same variable.

 A session's time zone can be changed dynamically by setting the [time\_zone](../server-system-variables/index#time_zone) system variable. For example:

 
```
SET time_zone = 'America/New_York';

```

The current session time zone can be viewed by looking at the session value of the [time\_zone](../server-system-variables/index#time_zone) system variable. For example:

 
```
SHOW SESSION VARIABLES LIKE 'time_zone';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | SYSTEM |
+---------------+--------+

```

### System Time Zone

 The system time zone is determined when the server starts, and it sets the value of the [system\_time\_zone](../server-system-variables/index#system_time_zone) system variable. The system time zone is usually read from the operating system's environment. You can change the system time zone in several different ways, such as:

 * If you are starting the server with [mysqld\_safe](../mysqld_safe/index), then you can set the system time zone with the `--timezone` option either on the command-line or in the [mysqld\_safe] [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mysqld_safe]
timezone='America/New_York'

```

* If you are using a Unix-like operating system, then you can set the system time zone by setting the `TZ` [environment variable](../mariadb-environment-variables/index) in your shell before starting the server. For example:

 
```
$ export TZ='America/New_York'
$ service mysql start

```

* On some Linux operating systems, you can change the default time zone for the whole system by making the [/etc/localtime](https://www.freedesktop.org/software/systemd/man/localtime.html) symbolic link point to the desired time zone. For example:

 
```
$ sudo rm /etc/localtime
$ sudo ln -s /usr/share/zoneinfo/America/New_York /etc/localtime

```

* On some Debian-based Linux operating systems, you can change the default time zone for the whole system by executing the following:

 
```
sudo dpkg-reconfigure tzdata

```

* On Linux operating systems that use [systemd](../systemd/index), you can change the default time zone for the whole system by using the [timedatectl](https://www.freedesktop.org/software/systemd/man/timedatectl.html) utility. For example:

 
```
sudo timedatectl set-timezone America/New_York

```

Time Zone Effects
-----------------

 ### Time Zone Effects on Functions

 Some functions are affected by the time zone settings. These include:

 * [NOW()](../now/index)
* [SYSDATE()](../sysdate/index)
* [CURDATE()](../curdate/index)
* [CURTIME()](../curtime/index)
* [UNIX\_TIMESTAMP()](../unix_timestamp/index)

 Some functions are not affected. These include:

 * [UTC\_DATE()](../utc_date/index)
* [UTC\_TIME()](../utc_time/index)
* [UTC\_TIMESTAMP()](../utc_timestamp/index)

 ### Time Zone Effects on Data Types

 Some data types are affected by the time zone settings.

 * [TIMESTAMP](../timestamp/index) - See [TIMESTAMP: Time Zones](../timestamp/index#time-zones) for information on how this data type is effected by time zones.
* [DATETIME](../datetime/index) - See [DATETIME: Time Zones](../datetime/index#time-zones) for information on how this data type is effected by time zones.

 mysql Time Zone Tables
----------------------

 The [mysql](../the-mysql-database-tables/index) database contains a number of time zone tables:

 * [time\_zone](../mysqltime_zone-table/index)
* [time\_zone\_leap\_second](../mysqltime_zone_leap_second-table/index)
* [time\_zone\_name](../mysqltime_zone_name-table/index)
* [time\_zone\_transition](../mysqltime_zone_transition-table/index)
* [time\_zone\_transition\_type](../mysqltime_zone_transition_type-table/index)

 By default, these time zone tables in the [mysql](../the-mysql-database-tables/index) database are created, but not populated.

 If you are using a Unix-like operating system, then you can populate these tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility, which uses the [zoneinfo](https://linux.die.net/man/5/tzfile) data available on Linux, Mac OS X, FreeBSD and Solaris.

 If you are using Windows, then you will need to import pre-populated time zone tables. These are available at [MariaDB mirrors](https://mirror.mariadb.org/zoneinfo/).

 Time zone data needs to be updated on occasion. When that happens, the time zone tables may need to be reloaded.

 See Also
--------

 * [LinuxJedi in Spacetime: Properly Handling Time and Date](https://www.youtube.com/watch?v=IV8q_mbZzEo) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time-zones/>

Percona XtraBackup Overview
===========================

    
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](index#compatibility-with-mariadb) for more information.

  Percona XtraBackup is an open source tool for performing hot backups of MariaDB, MySQL and Percona Server databases. Percona XtraBackup can perform compressed, incremental and streaming backups. It was designed to back up [XtraDB/InnoDB](../innodb/index) tables but can also back up other [storage engines](../storage-engines/index).

 [Mariabackup](../mariabackup/index) is a fork of Percona XtraBackup designed to work with encrypted and compressed tables and other MariaDB enhancements. There are many bug fixes, such as [MDEV-13807](https://jira.mariadb.org/browse/MDEV-13807), and some unsafe or redundant options have been removed. [Mariabackup](../mariabackup/index) is the recommended backup method for MariaDB servers.

 Installing Percona XtraBackup
-----------------------------

 ### Installing with a Package Manager

 Percona XtraBackup can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from a repository that has it.

 You can also configure your package manager to install it from Percona's repository by following the instructions in their documentation:

 * [Installing Percona XtraBackup 2.3](https://www.percona.com/doc/percona-xtrabackup/2.3/installation.html)
* [Installing Percona XtraBackup 2.4](https://www.percona.com/doc/percona-xtrabackup/2.4/installation.html)

 #### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example, to install Percona XtraBackup 2.3:

 
```
sudo yum install percona-xtrabackup

```

And to install Percona XtraBackup 2.4:

 
```
sudo yum install percona-xtrabackup-24

```

#### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example, to install Percona XtraBackup 2.3:

 
```
sudo apt-get install percona-xtrabackup

```

And to install Percona XtraBackup 2.4:

 
```
sudo apt-get install percona-xtrabackup-24

```

#### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example, to install Percona XtraBackup 2.3:

 
```
sudo zypper install percona-xtrabackup

```

And to install Percona XtraBackup 2.4:

 
```
sudo zypper install percona-xtrabackup-24

```

Using Percona XtraBackup
------------------------

 The command to use `xtrabackup` and the general syntax is:

 
```
xtrabackup <options>

```

or:

 
```
innobackupex <options>

```

### Options

 Options supported by Percona XtraBackup can be found on Percona's documentation.

 `xtrabackup` options:

 * [`xtrabackup` options - Percona XtraBackup 2.3](https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html)
* [`xtrabackup` options - Percona XtraBackup 2.4](https://www.percona.com/doc/percona-xtrabackup/2.4/xtrabackup_bin/xbk_option_reference.html)

 `innobackupex` options:

 * [`innobackupex` options - Percona XtraBackup 2.3](https://www.percona.com/doc/percona-xtrabackup/2.3/innobackupex/innobackupex_option_reference.html)
* [`innobackupex` options - Percona XtraBackup 2.4](https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/innobackupex_option_reference.html)

 ### Option Files

 In addition to reading options from the command-line, Percona XtraBackup can also read options from [option files](../configuring-mariadb-with-option-files/index).

 The following options relate to how MariaDB/MySQL command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--defaults-file=#`  | Only read default options from the given file #. |
| `--defaults-extra-file=#`  | Read this file after the global files are read. |

 
#### Server Option Groups

 Percona XtraBackup reads server options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[xtrabackup]` | Options read by [Mariabackup](../mariabackup/index) and Percona XtraBackup. |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |

 
#### Client Option Groups

 Percona XtraBackup reads client options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[xtrabackup]` | Options read by [Mariabackup](../mariabackup/index) and Percona XtraBackup. |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |

 
### Authentication and Privileges

 Percona XtraBackup needs to authenticate with the database server when it performs a backup operation (i.e. when the `--backup` option is specified). The user account that performs the backup needs to have the `RELOAD` , `PROCESS`, `LOCK TABLES` and `REPLICATION CLIENT` [global privileges](../grant/index#global-privileges) on the database server. For example:

 
```
CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY 'mypassword';
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'xtrabackup'@'localhost';

```

The user account information can be specified with the `-user` and `--password` command-line options. For example:

 
```
$ xtrabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=xtrabackup --password=mypassword

```

The user account information can also be specified in a supported [client option group](#client-option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[xtrabackup]
user=xtrabackup
password=mypassword

```

Percona XtraBackup does not need to authenticate with the database server when preparing or restoring a backup.

 ### File System Permissions

 Percona XtraBackup has to read MariaDB's files from the file system. Therefore, when you run Percona XtraBackup as a specific operating system user, you should ensure that user account has sufficient permissions to read those files.

 If you are using Linux and if you installed MariaDB with a package manager, then MariaDB's files will probably be owned by the `mysql` user and the `mysql` group.

 Compatibility with MariaDB
--------------------------

 ### Compatibility with [MariaDB 10.3](../what-is-mariadb-103/index) and Later

 
In [MariaDB 10.3](../what-is-mariadb-103/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 
In [MariaDB 10.3](../what-is-mariadb-103/index) and later, Percona XtraBackup is not supported.

 This limitation is being tracked by Percona XtraBackup bug [PXB-1550](https://jira.percona.com/browse/PXB-1550). However, it does not appear that there are plans to fix it. 

 ### Compatibility with [MariaDB 10.2](../what-is-mariadb-102/index)

 
In [MariaDB 10.2](../what-is-mariadb-102/index), [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 
In [MariaDB 10.2](../what-is-mariadb-102/index), Percona XtraBackup 2.4 is supported in some cases if [InnoDB page compression](../compression/index) is not used, and if [data at rest encryption](../data-at-rest-encryption/index) is not used, and if [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) is set to `16k`.

 However, users should be aware that problems are likely due to the MySQL 5.7 undo log format incompatibility bug that was fixed in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) in [MDEV-12289](https://jira.mariadb.org/browse/MDEV-12289). Due to this bug, backups prepared with Percona XtraBackup 2.4 may fail to recover some transactions. Only if you ran the server with the setting [innodb\_undo\_logs](../xtradbinnodb-server-system-variables/index#innodb_undo_logs)=1 this would not be a problem. Percona XtraBackup 2.4 may also fail to work entirely with [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and later if [innodb\_safe\_truncate=ON](../xtradbinnodb-server-system-variables/index#innodb_safe_truncate) is set due to changes in the redo log format introduced by [MDEV-14717](https://jira.mariadb.org/browse/MDEV-14717). In that case, you may see the following error:

 
```
InnoDB: Unsupported redo log format. The redo log was created with MariaDB 10.2.19. Please follow the instructions at http://dev.mysql.com/doc/refman/5.7/en/upgrading-downgrading.html

```

### Compatibility with [MariaDB 10.1](../what-is-mariadb-101/index)

 
In [MariaDB 10.1](../what-is-mariadb-101/index), [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 
In [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup 2.3 is supported if [InnoDB page compression](../compression/index) is not used, and if [data at rest encryption](../data-at-rest-encryption/index) is not used, and if [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) is set to `16k`.

 ### Compatibility with [MariaDB 10.0](../what-is-mariadb-100/index) and Before

 In [MariaDB 10.0](../what-is-mariadb-100/index) and before, Percona XtraBackup 2.3 is supported.

 Using Percona XtraBackup for Galera SSTs
----------------------------------------

 The `xtrabackup-v2` SST method uses the [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) utility for performing SSTs. See [xtrabackup-v2 SST method](../xtrabackup-v2-sst-method/index) for more information.

 See Also
--------

 * [Mariabackup](../mariabackup/index)
* [mysqldump](../mysqldump/index)
* [Percona XtraBackup documentation](http://www.percona.com/doc/percona-xtrabackup/)
* [Percona JIRA](https://jira.percona.com/secure/Dashboard.jspa)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/percona-xtrabackup-overview/>

mysql\_upgrade
==============

    `mariadb-upgrade/mysql_upgrade` is a tool that checks and updates your tables to the latest version.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-upgrade` is a symlink to `mysql_upgrade`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_upgrade` is the symlink, and `mariadb-upgrade` the binary name.

 
See [mariadb-upgrade](../mariadb-upgrade/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_upgrade/>

mysqlshow
=========

    Shows the structure of a MariaDB database (databases, tables, columns and indexes). 

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-show](../mariadb-show/index) is a symlink to `mysqlshow`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysqlshow` is the symlink, and [mariadb-show](../mariadb-show/index) the binary name.

 
See [mariadb-show](../mariadb-show/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlshow/>

mysqldump
=========

    mysqldump is used to dump a database or a collection of databases for backup or transfer to another database server.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `[mariadb-dump](../mariadb-dump/index)` is a symlink to `mysqldump`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `[mariadb-dump](../mariadb-dump/index)` is the name of the command-line client, with `mysqldump` a symlink .

 

**MariaDB starting with [11.0.1](https://mariadb.com/kb/en/mariadb-1101-release-notes/)**From [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/), `mysqldump` is deprecated and removed from the `mariadb` Docker Official Image. Use `[mariadb-dump](../mariadb-dump/index)` instead.

 
See [mariadb-dump](../mariadb-dump/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqldump/>

mysqlslap
=========

    `mysqlslap` is a tool for load-testing MariaDB. It allows you to emulate multiple concurrent connections, and run a set of queries multiple times.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-slap](../mariadb-slap/index) is a symlink to `mysqlslap`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysqlslap` is the symlink, and [mariadb-slap](../mariadb-slap/index) the binary name.

 
See [mariadb-slap](../mariadb-slap/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlslap/>

Configuring MariaDB for Remote Client Access
============================================

     Some MariaDB packages bind MariaDB to 127.0.0.1 (the loopback IP address) by default as a security measure using the [bind-address](../server-system-variables/index#bind_address) configuration directive. Old MySQL packages sometimes disabled TCP/IP networking altogether using the [skip-networking](../server-system-variables/index#skip_networking) directive. Before going in to how to configure these, let's explain what each of them actually does:

 * [skip-networking](../server-system-variables/index#skip_networking) is fairly simple. It just tells MariaDB to run without any of the TCP/IP networking options.

 * [bind-address](../server-system-variables/index#bind_address) requires a little bit of background information. A given server usually has at least two networking interfaces (although this is not required) and can easily have more. The two most common are a *Loopback* network device and a physical *Network Interface Card* (NIC) which allows you to communicate with the network. MariaDB is bound to the loopback interface by default because it makes it impossible to connect to the TCP port on the server from a remote host (the bind-address must refer to a local IP address, or you will receive a fatal error and MariaDB will not start). This of course is not desirable if you want to use the TCP port from a remote host, so you must remove this bind-address directive (MariaDB only supports one bind-address, but binds to 0.0.0.0, or :: (every IP) if the bind-address directive is left out).

 If [bind-address](../server-system-variables/index#bind_address) is bound to 127.0.0.1 (localhost), one can't connect to the MariaDB server from other hosts or from the same host over TCP/IP on a different interface than the loopback (127.0.0.1). This for example will not work (connecting with a hostname that points to a local IP of the host):

 
```
(/my/maria-10.4) ./client/mysql --host=myhost --protocol=tcp --port=3306 test
ERROR 2002 (HY000): Can't connect to MySQL server on 'myhost' (115)
(/my/maria-10.4) telnet myhost 3306
Trying 192.168.0.11...
telnet: connect to address 192.168.0.11: Connection refused

```

Using 'localhost' works when binding with `bind_address`:

 
```
(my/maria-10.4) ./client/mysql --host=localhost --protocol=tcp --port=3306 test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
...

```

Finding the Defaults File
-------------------------

 To enable MariaDB to listen to remote connections, you need to edit your defaults file. See [Configuring MariaDB with my.cnf](../configuring-mariadb-with-mycnf/index) for more detail.

 Common locations for defaults files:

 
```
  * /etc/my.cnf                              (*nix/BSD)
  * $MYSQL_HOME/my.cnf                       (*nix/BSD) *Most Notably /etc/mysql/my.cnf
  * SYSCONFDIR/my.cnf                        (*nix/BSD)
  * DATADIR\my.ini                           (Windows)

```

You can see which defaults files are read and in which order by executing:

 
```
shell> mysqld --help --verbose
./sql/mysqld  Ver 10.4.2-MariaDB-valgrind-max-debug for Linux on x86_64 (Source distribution)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Starts the MariaDB database server.

Usage: ./sql/mysqld [OPTIONS]

Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf 

```

The last line shows which defaults files are read.

 Editing the Defaults File
-------------------------

 Once you have located the defaults file, use a text editor to open the file and try to find lines like this under the [mysqld] section:

 
```
 [mysqld]
    ...
    skip-networking
    ...
    bind-address = <some ip-address>
    ...

```

(The lines may not be in this order, and the order doesn't matter.)

 If you are able to locate these lines, make sure they are both commented out (prefaced with hash (#) characters), so that they look like this:

 
```
 [mysqld]
    ...
    #skip-networking
    ...
    #bind-address = <some ip-address>
    ...

```

(Again, the order of these lines don't matter)

 Alternatively, just add the following lines **at the end** of your .my.cnf (notice that the file name starts with a dot) file in your home directory or alternative **last** in your /etc/my.cnf file.

 
```
[mysqld]
skip-networking=0
skip-bind-address

```

This works as one can have any number of <mysqld> sections.

 Save the file and restart the mysqld daemon or service (see [Starting and Stopping MariaDB](../starting-and-stopping-mariadb/index)).

 You can check the options mysqld is using by executing:

 
```
shell> ./sql/mysqld --print-defaults
./sql/mysqld would have been started with the following arguments:
--bind-address=127.0.0.1 --innodb_file_per_table=ON --server-id=1 --skip-bind-address ...

```

It doesn't matter if you have the original --bind-address left as the later --skip-bind-address will overwrite it.

 Granting User Connections From Remote Hosts
-------------------------------------------

 Now that your MariaDB server installation is setup to accept connections from remote hosts, we have to add a user that is allowed to connect from something other than 'localhost' (Users in MariaDB are defined as 'user'@'host', so 'chadmaynard'@'localhost' and 'chadmaynard'@'1.1.1.1' (or 'chadmaynard'@'server.domain.local') are different users that can have completely different permissions and/or passwords.

 To create a new user:

 * log into the [mysql command line client](../mysql-command-line-client/index) (or your favorite graphical client if you wish)

 
```
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 36
Server version: 5.5.28-MariaDB-mariadb1~lucid mariadb.org binary distribution

Copyright (c) 2000, 2012, Oracle, Monty Program Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

```

* if you are interested in viewing any existing remote users, issue the following SQL statement on the [mysql.user](../mysqluser-table/index) table:

 
```
SELECT User, Host FROM mysql.user WHERE Host <> 'localhost';
+--------+-----------+
| User   | Host      |
+--------+-----------+
| daniel | %         |
| root   | 127.0.0.1 |
| root   | ::1       |
| root   | gandalf   |
+--------+-----------+
4 rows in set (0.00 sec)

```

(If you have a fresh install, it is normal for no rows to be returned)

 Now you have some decisions to make. At the heart of every grant statement you have these things:

 * list of allowed privileges
* what database/tables these privileges apply to
* username
* host this user can connect from
* and optionally a password

 It is common for people to want to create a "root" user that can connect from anywhere, so as an example, we'll do just that, but to improve on it we'll create a root user that can connect from anywhere on my local area network (LAN), which has addresses in the subnet 192.168.100.0/24. This is an improvement because opening a MariaDB server up to the Internet and granting access to all hosts is bad practice.

 
```
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.100.%' 
  IDENTIFIED BY 'my-new-password' WITH GRANT OPTION;

```

(% is a wildcard)

 For more information about how to use GRANT, please see the [GRANT](../grant/index) page.

 At this point we have accomplished our goal and we have a user 'root' that can connect from anywhere on the 192.168.100.0/24 LAN.

 Port 3306 is Configured in Firewall
-----------------------------------

 One more point to consider whether the firwall is configured to allow incoming request from remote clients:

 On RHEL and CentOS 7, it may be necessary to configure the firewall to allow TCP access to MySQL from remote hosts. To do so, execute both of these commands:

 
```
firewall-cmd --add-port=3306/tcp 
firewall-cmd --permanent --add-port=3306/tcp

```

Caveats
-------

 * If your system is running a software firewall (or behind a hardware firewall or NAT) you must allow connections destined to TCP port that MariaDB runs on (by default and almost always 3306).
* To undo this change and not allow remote access anymore, simply remove the `skip-bind-address` line or uncomment the [bind-address](../server-system-variables/index#bind_address) line in your defaults file. The end result should be that you should have in the output from `./sql/mysqld --print-defaults` the option `--bind-address=127.0.0.1` and no `--skip-bind-address`.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Remote_Clients_Cannot_Connect> on 2012-10-30.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-mariadb-for-remote-client-access/>

mysqlimport
===========

    mysqlimport is used to load tables from text files in various formats

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-import](../mariadb-import/index) is a symlink to `mysqlimport`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-import](../mariadb-import/index) is the name of the script, with `mysqlimport` a symlink .

 
See [mariadb-import](../mariadb-import/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlimport/>

MariaDB Debian Live Images
==========================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  A member of the MariaDB community, Mark `<ms (at) it-infrastrukturen (dot) org>`, has created some Debian "squeeze" 6.0.4 based, live iso images with [MariaDB 5.2](../what-is-mariadb-52/index) or 5.3 pre-installed on them and some Debian "squeeze" 6.0.5 based, live iso images with [MariaDB 5.5](../what-is-mariadb-55/index) pre-installed on them.

 These live and install images can be used to quickly run a MariaDB server in live mode for learning or testing purposes, or to simplify and speed up off-line installations of Debian-based MariaDB servers onto harddisk.

 To work in live mode the system boots from a usb stick (or CD/DVD) and runs in RAM without touching the system's harddisk drive.

 The same usb stick (or CD/DVD media) can be used to install a complete server installation onto the harddisk drive using the included Debian installer.

 All required MariaDB packages are included on the media, so there is no need for an Internet connection.

 Three types of images are provided, text (command line), LXDE, and Gnome. The text-based live images can be used for testing or server off-line installations. The two gui types, LXDE and Gnome, can be used for testing/learning in live mode or for off-line desktop installations. Debian live images with LXDE (gnome, KDE or awesome) are pretty comfortable for daily work as a replacement for whatever desktop OS is installed on on the system.

 There are three iso images for each type, one for 32-bit (i386) systems, one for 64-bit (amd64) systems, and one with both.

 1. [MariaDB 5.2](../what-is-mariadb-52/index) Live iso images (text) for i386, amd64 or multi architectures.
	* `[binary-hybrid-squeeze-i386-mariadb52-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-mariadb52-text.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb52-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb52-text.iso)`
	* `[binary-hybrid-squeeze-i386-amd64-mariadb52-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-amd64-mariadb52-text.iso)`

 2. [MariaDB 5.3](../what-is-mariadb-53/index) Live iso images (text) for i386, amd64 or multi architectures.
	* `[binary-hybrid-squeeze-i386-mariadb53-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-mariadb53-text.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb53-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb53-text.iso)`
	* `[binary-hybrid-squeeze-i386-amd64-mariadb53-text.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-amd64-mariadb53-text.iso)`

 3. [MariaDB 5.3](../what-is-mariadb-53/index) Live iso images with LXDE for i386, amd64 or multi architectures.
	* `[binary-hybrid-squeeze-i386-mariadb53-lxde.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-mariadb53-lxde.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb53-lxde.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb53-lxde.iso)`
	* `[binary-hybrid-squeeze-i386-amd64-mariadb53-lxde.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-amd64-mariadb53-lxde.iso)`

 4. [MariaDB 5.3](../what-is-mariadb-53/index) Live iso images with Gnome for i386, amd64 or multi architectures.
	* `[binary-hybrid-squeeze-i386-mariadb53-gnome.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-mariadb53-gnome.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb53-gnome.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb53-gnome.iso)`
	* `[binary-hybrid-squeeze-i386-amd64-mariadb53-gnome.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-i386-amd64-mariadb53-gnome.iso)`

 5. [MariaDB 5.5](../what-is-mariadb-55/index) Live images
	* `[binary-hybrid-squeeze-amd64-mariadb55-text-bpo.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb55-text-bpo.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb55-lxde-bpo.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb55-lxde-bpo.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb55-gnome-bpo.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb55-gnome-bpo.iso)`
	* `[binary-hybrid-squeeze-amd64-mariadb55-awesome-bpo.iso](http://rsync.it-infrastrukturen.org/public-mariadb/binary-hybrid-squeeze-amd64-mariadb55-awesome-bpo.iso)`

 6. [MariaDB 5.5](../what-is-mariadb-55/index) Live images demonstration video
	* `[README-mariadb-video.txt](http://rsync.it-infrastrukturen.org/public-mariadb/README-mariadb-video.txt)`
	* `[video-mariadb5.5-live-images-on-USB.ogv](http://rsync.it-infrastrukturen.org/public-mariadb/video-mariadb5.5-live-images-on-USB.ogv)`
	* `[video-mariadb5.5-live-images-on-USB.mp4](http://rsync.it-infrastrukturen.org/public-mariadb/video-mariadb5.5-live-images-on-USB.mp4)`

 The LXDE and Gnome images contain documentation under `/srv/PDF`. Including instructions on how to create your own Debian live images in live mode (you need 16GB RAM or more to be able to do this). See the README, README.live, and live-manual.en.pdf files under `/srv/PDF` for details.

 
**Note:** Some HP notebooks are not able to boot binary hybrid iso images from a USB stick.

 
Downloads
---------

 To get the iso images you can use rsync:

 
```
rsync -avP rsync://rsync.it-infrastrukturen.org/ftp/public-mariadb/<image_or_file_name_as_above> .

```

or just use the links above (or go to: <http://rsync.it-infrastrukturen.org/public-mariadb/> ).

 Preparing of bootable media:
----------------------------

 A USB stick or CD/DVD can be used as bootable media. The preferred way is a USB stick.

 * for Linux: `dd if=./<image_name_as_above.iso> of=/dev/<USB-stick-ID_like_sdb_or_sdc>`
* for other systems: cygwin includes dd and some other linux/Unix tools.

 The iso images have been successfully tested on:

 * Acer ASPIRE @ne netbooks (1GB RAM)
* ThinkPad T60p and T61p notebooks (2 or 4GB RAM)
* Xeon E31270 / Asus P8BWS desktop (16GB ECC RAM)
* AMD FX-4100 / Asus M5A99X EVO desktop (16GB ECC RAM)
* HP DL385g7 Opteron 6170SE or 6180SE servers (32 or 64GB ECC RAM)

 ### Notes

 It is possible to add some options on the bootline for special purposes like, for example, the installation of additional packages from a local repository on the image or assigning a static IP address and running sshd.

 1. To configure a static IP use "`ip=`". For example: "`ip=eth0:192.168.1.53:255.255.255.0:192.168.1.1`"
	* The full format of "`ip=`" is: "`ip=[interface]:[IP_address]:[netmask]:[gateway]`"

 2. If you use an empty "`ip=`" value the content of `/etc/network/interfaces` and `/etc/resolv.conf` will be used. Without the "`ip=`" option, dhcp will be used to get an IP address.

 3. For installing and running sshd (so that the image can act as a server in a test environment) use: "`sshd=on`"
	* The live user is "sql" and the password is "live". Please change the password immediately after first login!

 4. Depending on the image [MariaDB 5.2](../what-is-mariadb-52/index) or 5.3 server is installed. There is no root passord for the database set so please set a password immediately after first login!

 5. Run `repo-off-line.sh` to activate local repositories on the image for apt-get (for off-line installations) or `repo-on-line.sh` for internet repositories.

 6. The binary hybrid live iso images with multiple-choices inside the boot menu allow for the assignment of two different IPs. (e.g. for testing of clustered database operations)

 Send any feedback or suggestions related to these images to:

 * Mark `<ms (at) it-infrastrukturen (dot) org>`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-debian-live-images/>

mariabackup SST Method
======================

    The `mariabackup` SST method uses the [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) utility for performing SSTs. It is one of the methods that does not block the donor node. [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) was originally forked from [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index), and similarly, the `mariabackup` SST method was originally forked from the `[xtrabackup-v2](../xtrabackup-v2-sst-method/index)` SST method.

 Note that if you use the `mariabackup` SST method, then you also need to have `[socat](#socat-dependency)` installed on the server. This is needed to stream the backup from the donor node to the joiner node. This is a limitation that was inherited from the `[xtrabackup-v2](../xtrabackup-v2-sst-method/index)` SST method.

 Choosing Mariabackup for SSTs
-----------------------------

 To use the `mariabackup` SST method, you must set the `[wsrep\_sst\_method=mariabackup](../galera-cluster-system-variables/index#wsrep_sst_method)` on both the donor and joiner node. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_method='mariabackup';

```

It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_method = mariabackup

```

For an SST to work properly, the donor and joiner node must use the same SST method. Therefore, it is recommended to set `[wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method)` to the same value on all nodes, since any node will usually be a donor or joiner node at some point.

 Major version upgrades
----------------------

 The InnoDB redo log format has been changed in [MariaDB 10.5](../what-is-mariadb-105/index) and [MariaDB 10.8](../what-is-mariadb-108/index) in a way that will not allow the crash recovery or the preparation of a backup from an older major version. Because of this, the `mariabackup` SST method cannot be used for some major version upgrades, unless you temporarily edit the `wsrep_sst_mariabackup` script so that the `--prepare` step on the newer-major-version joiner will be executed using the older-major-version `mariabackup` tool.

 The default method `wsrep_sst_method=rsync` will work for major version upgrades; see [MDEV-27437](https://jira.mariadb.org/browse/MDEV-27437).

 Authentication and Privileges
-----------------------------

 To use the `mariabackup` SST method, [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) needs to be able to authenticate locally on the donor node, so that it can create a backup to stream to the joiner. You can tell the donor node what username and password to use by setting the `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` system variable. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_auth = 'mariabackup:mypassword';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = mariabackup:mypassword

```

Some [authentication plugins](../authentication-plugins/index) do not require a password. For example, the `[unix\_socket](../authentication-plugin-unix-socket/index)` and `[gssapi](../authentication-plugin-gssapi/index)` authentication plugins do not require a password. If you are using a user account that does not require a password in order to log in, then you can just leave the password component of `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` empty. For example:

 
```
[mariadb]
...
wsrep_sst_auth = mariabackup:

```

The user account that performs the backup for the SST needs to have [the same privileges as Mariabackup](../mariabackup-overview/index#authentication-and-privileges), which are the `RELOAD` , `PROCESS`, `LOCK TABLES` and `REPLICATION CLIENT` [global privileges](../grant/index#global-privileges). To be safe, you should ensure that these privileges are set on each node in your cluster. [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) connects locally on the donor node to perform the backup, so the following user should be sufficient:

 
```
CREATE USER 'mariabackup'@'localhost' IDENTIFIED BY 'mypassword';
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mariabackup'@'localhost';

```

### Passwordless Authentication - Unix Socket

 It is possible to use the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin for the user account that performs SSTs. This would provide the benefit of not needing to configure a plain-text password in `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`.

 The user account would have to have the same name as the operating system user account that is running the `mysqld` process. On many systems, this is the user account configured as the `[user](../mysqld-options/index#-user)` option, and it tends to default to `mysql`.

 For example, if the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin is already installed, then you could execute the following to create the user account:

 
```
CREATE USER 'mysql'@'localhost' IDENTIFIED VIA unix_socket;
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mysql'@'localhost';

```

And then to configure `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`, you could set the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = mysql:

```

### Passwordless Authentication - GSSAPI

 It is possible to use the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin for the user account that performs SSTs. This would provide the benefit of not needing to configure a plain-text password in `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`.

 The following steps would need to be done beforehand:

 * You need a KDC running [MIT Kerberos](http://web.mit.edu/Kerberos/krb5-1.12/doc/index.html) or [Microsoft Active Directory](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview).
* You will need to [create a keytab file](../authentication-plugin-gssapi/index#creating-a-keytab-file-on-a-unix-server) for the MariaDB server.
* You will need to [install the package](../authentication-plugin-gssapi/index#installing-the-plugins-package) containing the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin.
* You will need to [install the plugin](../authentication-plugin-gssapi/index#installing-the-plugin) in MariaDB, so that the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin is available to use.
* You will need to [configure the plugin](../authentication-plugin-gssapi/index#configuring-the-plugin).
* You will need to [create a user account](../authentication-plugin-gssapi/index#creating-users) that authenticates with the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin, so that the user account can be used for SSTs. This user account will need to correspond with a user account that exists on the backend KDC.

 For example, you could execute the following to create the user account in MariaDB:

 
```
CREATE USER 'mariabackup'@'localhost' IDENTIFIED VIA gssapi;
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mariabackup'@'localhost';

```

And then to configure `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`, you could set the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = mariabackup:

```

Choosing a Donor Node
---------------------

 When Mariabackup is used to create the backup for the SST on the donor node, Mariabackup briefly requires a system-wide lock at the end of the backup. In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this is done with `[FLUSH TABLES WITH READ LOCK](../flush/index)`. In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this is done with `[BACKUP STAGE BLOCK\_COMMIT](../backup-stage/index)`.

 If a specific node in your cluster is acting as the *primary* node by receiving all of the application's write traffic, then this node should not usually be used as the donor node, because the system-wide lock could interfere with the application. In this case, you can define one or more preferred donor nodes by setting the `[wsrep\_sst\_donor](../galera-cluster-system-variables/index#wsrep_sst_donor)` system variable.

 For example, let's say that we have a 5-node cluster with the nodes `node1`, `node2`, `node3`, `node4`, and `node5`, and let's say that `node1` is acting as the *primary* node. The preferred donor nodes for `node2` could be configured by setting the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_donor=node3,node4,node5,

```

The trailing comma tells the server to allow any other node as donor when the preferred donors are not available. Therefore, if `node1` is the only node left in the cluster, the trailing comma allows it to be used as the donor node.

 Socat Dependency
----------------

 During the SST process, the donor node uses [socat](http://www.dest-unreach.org/socat/doc/socat.html) to stream the backup to the joiner node. Then the joiner node prepares the backup before restoring it. The socat utility must be installed on both the donor node and the joiner node in order for this to work. Otherwise, the MariaDB error log will contain an error like:

 
```
WSREP_SST: [ERROR] socat not found in path: /usr/sbin:/sbin:/usr//bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin (20180122 14:55:32.993)

```

### Installing Socat on RHEL/CentOS

 On RHEL/CentOS, `socat` can be installed from the [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL) repository.

 TLS
---

 This SST method supports two different TLS methods. The specific method can be selected by setting the `encrypt` option in the `[sst]` section of the MariaDB configuration file. The options are:

 * TLS using OpenSSL encryption built into `socat` (`encrypt=2`)
* TLS using OpenSSL encryption with Galera-compatible certificates and keys (`encrypt=3`)

 Note that `encrypt=1` refers to a TLS encryption method that has been deprecated and removed. `encrypt=4` refers to a TLS encryption method in `xtrabackup-v2` that has not yet been ported to `mariabackup`. See [MDEV-18050](https://jira.mariadb.org/browse/MDEV-18050) about that.

 ### TLS Using OpenSSL Encryption Built into Socat

 To generate keys compatible with this encryption method, you can follow [these directions](http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html).

 For example:

 * First, generate the keys and certificates:

 
```
FILENAME=sst
openssl genrsa -out $FILENAME.key 1024
openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt
cat $FILENAME.key $FILENAME.crt >$FILENAME.pem
chmod 600 $FILENAME.key $FILENAME.pem

```

* On some systems, you may also have to add dhparams to the certificate:

 
```
openssl dhparam -out dhparams.pem 2048
cat dhparams.pem >> sst.pem

```

* Then, copy the certificate and keys to all nodes in the cluster.

 * Then, configure the following on all nodes in the cluster:

 
```
[sst]
encrypt=2
tca=/etc/my.cnf.d/certificates/sst.crt
tcert=/etc/my.cnf.d/certificates/sst.pem

```

But replace the paths with whatever is relevant on your system.

 This should allow your SSTs to be encrypted.

 ### TLS Using OpenSSL Encryption with Galera-compatible Certificates and Keys

 To generate keys compatible with this encryption method, you can follow [these directions](https://galeracluster.com/library/documentation/ssl-cert.html).

 For example:

 * First, generate the keys and certificates:

 
```
# CA
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365000 \
-key ca-key.pem -out ca-cert.pem
 
# server1
openssl req -newkey rsa:2048 -days 365000 \
-nodes -keyout server1-key.pem -out server1-req.pem
openssl rsa -in server1-key.pem -out server1-key.pem
openssl x509 -req -in server1-req.pem -days 365000 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \
-out server1-cert.pem

```

* Then, copy the certificate and keys to all nodes in the cluster.

 * Then, configure the following on all nodes in the cluster:

 
```
[sst]
encrypt=3
tkey=/etc/my.cnf.d/certificates/server1-key.pem
tcert=/etc/my.cnf.d/certificates/server1-cert.pem

```

But replace the paths with whatever is relevant on your system.

 This should allow your SSTs to be encrypted.

 Logs
----

 The `mariabackup` SST method has its own logging outside of the MariaDB Server logging.

 ### Logging to SST Logs

 
**MariaDB starting with [10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/)**Starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), logging for `mariabackup` SSTs works the following way.

 By default, on the donor node, it logs to `mariabackup.backup.log`. This log file is located in the `[datadir](../server-system-variables/index#datadir)`.

 By default, on the joiner node, it logs to `mariabackup.prepare.log` and `mariabackup.move.log` These log files are also located in the `[datadir](../server-system-variables/index#datadir)`.

 By default, before a new SST is started, existing `mariabackup` SST log files are compressed and moved to `/tmp/sst_log_archive`. This behavior can be disabled by setting `sst-log-archive=0` in the `[sst]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). Similarly, the archive directory can be changed by setting `sst-log-archive-dir`. For example:

 
```
[sst]
sst-log-archive=1
sst-log-archive-dir=/var/log/mysql/sst/

```

See [MDEV-17973](https://jira.mariadb.org/browse/MDEV-17973) for more information.

 

**MariaDB until [10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/)**Prior to [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), logging for `mariabackup` SSTs works the following way.

 By default, on the donor node, it logs to `innobackup.backup.log`. This log file is located in the `[datadir](../server-system-variables/index#datadir)`.

 By default, on the joiner node, it logs to `innobackup.prepare.log` and `innobackup.move.log`. These log files are located in the `.sst` directory, which is a hidden directory inside the `[datadir](../server-system-variables/index#datadir)`.

 These log files are overwritten by each subsequent SST, so if an SST fails, it is best to copy them somewhere safe before starting another SST, so that the log files can be analyzed. 

 
### Logging to Syslog

 You can redirect the SST logs to the syslog instead by setting the following in the `[sst]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[sst]
sst-syslog=1

```

You can also redirect the SST logs to the syslog by setting the following in the `[mysqld_safe]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mysqld_safe]
syslog

```

Performing SSTs with IPv6 Addresses
-----------------------------------

 If you are performing Mariabackup SSTs with IPv6 addresses, then the `socat` utility needs to be passed the `pf=ip6` option. This can be done by setting the `sockopt` option in the `[sst]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[sst]
sockopt=",pf=ip6"

```

See [MDEV-18797](https://jira.mariadb.org/browse/MDEV-18797) for more information.

 Manual SST with Mariabackup
---------------------------

 In some cases, if Galera Cluster's automatic SSTs repeatedly fail, then it can be helpful to perform a "manual SST". See the following page on how to do that:

 * [Manual SST of Galera Cluster node with Mariabackup](../manual-sst-of-galera-cluster-node-with-mariabackup/index)

 See Also
--------

 * [Percona XtraBackup SST Configuration](https://www.percona.com/doc/percona-xtradb-cluster/5.7/manual/xtrabackup_sst.html)
* [Encrypting PXC Traffic: ENCRYPTING SST TRAFFIC](https://www.percona.com/doc/percona-xtradb-cluster/5.7/security/encrypt-traffic.html#encrypt-sst)
* [XTRABACKUP PARAMETERS](https://galeracluster.com/library/documentation/xtrabackup-options.html)
* [SSL FOR STATE SNAPSHOT TRANSFERS: ENABLING SSL FOR XTRABACKUP](https://galeracluster.com/library/documentation/ssl-sst.html#ssl-xtrabackup)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariabackup-sst-method/>

Migrating to MariaDB from SQL Server
=====================================

   This section is a guide to help you migrate from SQL Server to MariaDB. This includes a general understanding of MariaDB, information to help plan the migration, and differences in the configuration and syntax.

  

| Title | Description |
| --- | --- |
|  [Understanding MariaDB Architecture](../understanding-mariadb-architecture/index) |  An overview of MariaDB server architecture, especially where it differs from SQL Server.  |
|  [SQL Server Features Not Available in MariaDB](../sql-server-features-not-available-in-mariadb/index) |  List of SQL Server features not available in MariaDB.  |
|  [SQL Server Features Implemented Differently in MariaDB](../sql-server-features-implemented-differently-in-mariadb/index) |  List of SQL Server features that MariaDB implements in a different way.  |
|  [MariaDB Features Not Available in SQL Server](../mariadb-features-not-available-in-sql-server/index) |  List of MariaDB features not available in SQL Server.  |
|  [Setting Up MariaDB for Testing for SQL Server Users](../setting-up-mariadb-for-testing-for-sql-server-users/index) |  Hints for SQL Server users to setup MariaDB for testing.  |
|  [Syntax Differences between MariaDB and SQL Server](../syntax-differences-between-mariadb-and-sql-server/index) |  MariaDB syntax hints for SQL Server users.  |
|  [SQL Server and MariaDB Types Comparison](../sql-server-and-mariadb-types-comparison/index) |  Comparison tables between SQL Server types and MariaDB types.  |
|  [MariaDB Transactions and Isolation Levels for SQL Server Users](../mariadb-transactions-and-isolation-levels-for-sql-server-users/index) |  How MariaDB transactions and isolation levels differ from SQL Server.  |
|  [MariaDB Authorization and Permissions for SQL Server Users](../mariadb-authorization-and-permissions-for-sql-server-users/index) |  MariaDB handles users and permissions quite differently to SQL Server.  |
|  [Repairing MariaDB Tables for SQL Server Users](../repairing-mariadb-tables-for-sql-server-users/index) |  MariaDB table repair explained to SQL Server users.  |
|  [MariaDB Backups Overview for SQL Server Users](../mariadb-backups-overview-for-sql-server-users/index) |  An overview of MariaDB backup tools and techniques for SQL Server users.  |
|  [MariaDB Replication Overview for SQL Server Users](../mariadb-replication-overview-for-sql-server-users/index) |  An overview of MariaDB replication types for SQL Server users.  |
|  [Moving Data Between SQL Server and MariaDB](../moving-data-between-sql-server-and-mariadb/index) |  Information and some advice on how to import SQL Server data into MariaDB.  |
|  [SQL\_MODE=MSSQL](../sql_modemssql/index) |  Microsoft SQL Server compatibility mode.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/migrating-to-mariadb-from-sql-server/>

Migrating to MariaDB from Oracle
=================================

  

| Title | Description |
| --- | --- |
|  [Oracle XE 11.2. and MariaDB 10.1 integration on Ubuntu 14.04 and Debian systems](../oracle-xe-112-and-mariadb-101-integration-on-ubuntu-1404-and-debian-systems/index) |  1) Sign up for Oracle downloads and download Oracle Express at: http://www...  |
|  [SQL\_MODE=ORACLE](../sql_modeoracle/index) |  MariaDB understands a subset of Oracle's PL/SQL language.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/migrating-to-mariadb-from-oracle/>

mariadb-import
==============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-import` is a symlink to `mysqlimport`, the old name of tool for loading tables from text files in various formats. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-import` is the name of the script, with `mysqlimport` a symlink .

 
`mariadb-import` loads tables from text files in various formats. The base name of the text file must be the name of the table that should be used. If one uses sockets to connect to the MariaDB server, the server will open and read the text file directly. In other cases the client will open the text file. The SQL command [LOAD DATA INFILE](../load-data-infile/index) is used to import the rows.

 Using mariadb-import
--------------------

 The command to use `mariadb-import` and the general syntax is:

 
```
mariadb-import [OPTIONS] database textfile1 [textfile2 ...]

```

### Options

 `mariadb-import` supports the following options:

 


| variable | Description |
| --- | --- |
| `--character-sets-dir=name` | Directory for character set files. |
| `-c cols`, `--columns=cols` | Use only these columns to import the data to. Give the column names in a comma separated list. This is same as giving columns to [LOAD DATA INFILE](../load-data-infile/index). |
| `-C`, `--compress` | Use compression in server/client protocol. |
| `-# [options]` , `--debug[=options]` | Output debug log. Often this is `d:t:o,filename`. The default is `d:t:o`. |
| `--debug-check` | Check memory and open file usage at exit. |
| `--debug-info` | Print some debug info at exit. |
| `--default-auth=plugin` | Default authentication client-side plugin to use. |
| `--default-character-set=name` | Set the default [character set](../data-types-character-sets-and-collations/index). |
| `--defaults-extra-file=name` | Read this file after the global files are read. Must be given as the first option. |
| `--defaults-file=name` | Only read default options from the given file *name* Must be given as the first option. |
| `--defaults-group-suffix=name` | In addition to the given groups, also read groups with this suffix. |
| `-d`, `--delete` | First delete all rows from table. |
| `--fields-terminated-by=name` | Fields in the input file are terminated by the given string. |
| `--fields-enclosed-by=name` | Fields in the import file are enclosed by the given character. |
| `--fields-optionally-enclosed-by=name` | Fields in the input file are optionally enclosed by the given character. |
| `--fields-escaped-by=name` | Fields in the input file are escaped by the given character. |
| `-f`, `--force` | Continue even if we get an SQL error. |
| `-?`, `--help` | Displays this help and exits. |
| `-h name`, `--host=name` | Connect to host. |
| `-i`, `--ignore` | If duplicate unique key was found, keep old row. |
| `k`, `--ignore-foreign-keys` | Disable foreign key checks while importing the data. From [MariaDB 10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/), [MariaDB 10.2.25](https://mariadb.com/kb/en/mariadb-10225-release-notes/) and [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/). |
| `--ignore-lines=n` | Ignore first *n* lines of data infile. |
| `--lines-terminated-by=name` | Lines in the input file are terminated by the given string. |
| `-L`, `--local` | Read all files through the client. |
| `-l`, `--lock-tables` | Lock all tables for write (this disables threads). |
| `--low-priority` | Use LOW\_PRIORITY when updating the table. |
| `--no-defaults` | Don't read default options from any option file. Must be given as the first option. |
| `-p[passwd]`, `--password[=passwd]` | Password to use when connecting to server. If password is not given it's asked from the terminal. Specifying a password on the command line should be considered insecure. You can use an option file to avoid giving the password on the command line. |
| `--pipe`, `-W` | On Windows, connect to the server via a named pipe. This option applies only if the server supports named-pipe connections. |
| `--plugin-dir` | Directory for client-side plugins. |
| `-P num`, `--port=num` | Port number to use for connection or 0 for default to, in order of preference, my.cnf, the MYSQL\_TCP\_PORT [environment variable](../mariadb-environment-variables/index), /etc/services, built-in default (3306). |
| `--print-defaults` | Print the program argument list and exit. Must be given as the first option. |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `-r`, `--replace` | If duplicate unique key was found, replace old row. |
| `--shared-memory-base-name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. |
| `-s`, `--silent` | Silent mode. Produce output only when errors occur. |
| `-S`, `--socket=name` | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |
| `--ssl` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |
| `--ssl-ca=name` | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |
| `--ssl-capath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |
| `--ssl-cert=name` | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-cipher=name` | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |
| `--ssl-crl=name` | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-crlpath=name` | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |
| `--ssl-key=name` | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |
| `--ssl-verify-server-cert` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |
| `--tls-version=name` | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. This option was added in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `--use-threads=num` | Load files in parallel. The argument is the number of threads to use for loading data. |
| `-u name`, `--user=name` | User for login if not current user. |
| `-v`, `--verbose` | Print info about the various stages. |
| `-V`, `--version` | Output version information and exit. |

 
### Option Files

 In addition to reading options from the command-line, `mariadb-import` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-import` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--defaults-file=#`  | Only read default options from the given file #. |
| `--defaults-extra-file=#`  | Read this file after the global files are read. |

 
In [MariaDB 10.2](../what-is-mariadb-102/index) and later, `mariadb-import` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). Therefore, it may be helpful to see [Configuring MariaDB Connector/C with Option Files](../configuring-mariadb-connectorc-with-option-files/index) for more information on how MariaDB Connector/C handles option files. 

 #### Option Groups

 `mariadb-import` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqlimport]` |  Options read by `mysqlimport`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-import]` | Options read by `mysqlimport`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
### Default Values

 


| Variables (``--`variable-name=value`) and boolean options `{FALSE`|`TRUE}` | Value (after reading options) |
| --- | --- |
| `character-sets-dir` | *(No default value)* |
| `default-character-set` | latin1 |
| `columns` | *(No default value)* |
| `compress` | FALSE |
| `debug-check` | FALSE |
| `debug-info` | FALSE |
| `delete` | FALSE |
| `fields-terminated-by` | *(No default value)* |
| `fields-enclosed-by` | *(No default value)* |
| `fields-optionally-enclosed-by` | *(No default value)* |
| `fields-escaped-by` | *(No default value)* |
| `force` | FALSE |
| `host` | *(No default value)* |
| `ignore` | FALSE |
| `ignore-lines` | 0 |
| `lines-terminated-by` | *(No default value)* |
| `local` | FALSE |
| `lock-tables` | FALSE |
| `low-priority` | FALSE |
| `port` | 3306 |
| `replace` | FALSE |
| `silent` | FALSE |
| `socket` | /var/run/mysqld/mysqld.sock |
| `ssl` | FALSE |
| `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-verify-server-cert` | FALSE |
| `use-threads` | 0 |
| `user` | *(No default value)* |
| `verbose` | FALSE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-import/>

Migrating to MariaDB from MySQL
================================

   .

  

| Title | Description |
| --- | --- |
|  [MariaDB versus MySQL - Features](../mariadb-vs-mysql-features/index) |  MariaDB advantage in delivering enterprise-level high availability, scalability and security.  |
|  [MariaDB versus MySQL - Compatibility](../mariadb-vs-mysql-compatibility/index) |  Compatibility and differences with MariaDB related to high availability, security and scalability.  |
|  [Upgrading from MySQL to MariaDB](../upgrading-from-mysql-to-mariadb/index) |  Upgrading from MySQL to MariaDB.  |
|  [Incompatibilities and Feature Differences Between MariaDB 11.0 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-11-0-and-mysql-8-/index) |  List of incompatibilities and feature differences between MariaDB 11.0 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.11 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-11-and-mysql-8/index) |  List of incompatibilities and feature differences between MariaDB 10.11 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.10 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-10-and-mysql-8/index) |  List of incompatibilities and feature differences between MariaDB 10.10 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.9 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-9-and-mysql-8-/index) |  List of incompatibilities and feature differences between MariaDB 10.9 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.6 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-6-and-mysql-8-/index) |  List of incompatibilities and feature differences between MariaDB 10.6 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.5 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-5-and-mysql-8-/index) |  List of incompatibilities and feature differences between MariaDB 10.5 and MySQL 8.0.  |
|  [Incompatibilities and Feature Differences Between MariaDB 10.4 and MySQL 8.0](../incompatibilities-and-feature-differences-between-mariadb-10-4-and-mysql-8-/index) |  List of incompatibilities and feature differences between MariaDB 10.4 and MySQL 8.0.  |
|  [Function Differences Between MariaDB and MySQL](../function-differences-between-mariadb-and-mysql/index) |  Functions available only in MariaDB.  |
|  [System Variable Differences between MariaDB and MySQL](../system-variable-differences-between-mariadb-and-mysql/index) |  Comparison of variable differences between major versions of MariaDB and MySQL.  |
|  [Upgrading from MySQL 5.7 to MariaDB 10.2](../upgrading-from-mysql-57-to-mariadb-102/index) |  Following compatibility report was done on 10.2.4 and may get some fixing i...  |
|  [Installing MariaDB Alongside MySQL](../installing-mariadb-alongside-mysql/index) |  MariaDB was designed as a drop in place replacement for MySQL, but you can ...  |
|  [Moving from MySQL to MariaDB in Debian 9](../moving-from-mysql-to-mariadb-in-debian-9/index) |  MariaDB 10.1 is the default mysql server in Debian 9 "Stretch"  |
|  [Screencast for Upgrading MySQL to MariaDB](../screencast-for-upgrading-mysql-to-mariadb/index) |  Screencast for upgrading MySQL 5.1.55 to MariaDB  |
|  [Upgrading to MariaDB From MySQL 5.0 or Older](../upgrading-to-mariadb-from-mysql-50-or-older/index) |  Upgrading to MariaDB from MySQL 5.0 (or older version)  |
|  [Incompatibilities and Feature Differences Between MariaDB and MySQL - Unmaintained Series](../incompatibilities-and-feature-differences-between-mariadb-and-mysql-unmaint/index) |  Incompatibilities and feature differences between unmaintained MariaDB and MySQL series.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/moving-from-mysql/>

Migrating to MariaDB from PostgreSQL
====================================

    There are many different ways to migrate from [PostgreSQL](https://www.postgresql.org/) to MariaDB. This article will discuss some of those options.

 MariaDB's CONNECT Storage Engine
--------------------------------

 MariaDB's [CONNECT](../connect/index) storage engine can be used to migrate from PostgreSQL to MariaDB. There are two primary ways that this can be done.

 See [Loading the CONNECT Storage Engine](../loading-the-connect-storage-engine/index) for information on how to install the CONNECT storage engine.

 ### Tables with ODBC table\_type

 The CONNECT storage engine allows you to create tables that refer to tables on an external server, and it can fetch the data using a compatible [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity) driver. PostgreSQL does have a freely available ODBC driver called `[psqlODBC](https://odbc.postgresql.org/)`. Therefore, if you install `psqlODBC` on the MariaDB Server, and then configure the system's ODBC framework (such as [unixODBC](http://www.unixodbc.org/)), then the MariaDB server will be able to connect to the remote PostgreSQL server. At that point, you can create tables with the `[ENGINE=CONNECT](../create-table/index#storage-engine)` and `[table\_type=ODBC](../connect-odbc-table-type-accessing-tables-from-another-dbms/index)` table options set, so that you can access the PostgreSQL tables from MariaDB.

 See [CONNECT ODBC Table Type: Accessing Tables From Another DBMS](../connect-odbc-table-type-accessing-tables-from-another-dbms/index) for more information on how to do that.

 Once the remote table is setup, you can migrate the data to local tables very simply. For example:

 
```
CREATE TABLE psql_tab (
   id int,
   str varchar(50)
) ENGINE = CONNECT
table_type=ODBC
tabname='tab'
connection='DSN=psql_server';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE = InnoDB;

INSERT INTO tab SELECT * FROM psql_tab;

```

### Tables with JDBC table\_type

 The CONNECT storage engine allows you to create tables that refer to tables on an external server, and it can fetch the data using a compatible [JDBC](https://en.wikipedia.org/wiki/Java_Database_Connectivity) driver. PostgreSQL does have a freely available [JDBC driver](https://jdbc.postgresql.org/). If you install this JDBC driver on the MariaDB server, then the MariaDB server will be able to connect to the remote PostgreSQL server via JDBC. At that point, you can create tables with the `[ENGINE=CONNECT](../create-table/index#storage-engine)` and `[table\_type=JDBC](../connect-odbc-table-type-accessing-tables-from-another-dbms/index)` table options set, so that you can access the PostgreSQL tables from MariaDB.

 See [CONNECT JDBC Table Type: Accessing Tables from Another DBMS](../connect-jdbc-table-type-accessing-tables-from-another-dbms/index) for more information on how to do that.

 Once the remote table is setup, you can migrate the data to local tables very simply. For example:

 
```
CREATE TABLE psql_tab (
   id int,
   str varchar(50)
) ENGINE = CONNECT
table_type=JDBC
tabname='tab'
connection='jdbc:postgresql://psql_server/db1';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE = InnoDB;

INSERT INTO tab SELECT * FROM psql_tab;

```

PostgreSQL's Foreign Data Wrappers
----------------------------------

 PostgreSQL's [foreign data wrappers](https://wiki.postgresql.org/wiki/Foreign_data_wrappers) can also be used to migrate from PostgreSQL to MariaDB.

 ### mysql\_fdw

 [mysql\_fdw](https://github.com/EnterpriseDB/mysql_fdw) allows you to create a table in PostgreSQL that actual refers to a remote MySQL or MariaDB server. Since MySQL and MariaDB are compatible at the protocol level, this should also support MariaDB.

 The foreign data wrapper also supports writes, so you should be able to write to the remote MariaDB table to migrate your PostgreSQL data. For example:

 
```
CREATE TABLE tab (
   id int,
   str text
);

INSERT INTO tab VALUES (1, 'str1');

CREATE SERVER mariadb_server
   FOREIGN DATA WRAPPER mysql_fdw
   OPTIONS (host '10.1.1.101', port '3306');

CREATE USER MAPPING FOR postgres
   SERVER mariadb_server
   OPTIONS (username 'foo', password 'bar');

CREATE FOREIGN TABLE mariadb_tab (
   id int,
   str text
)
SERVER mariadb_server
OPTIONS (dbname 'db1', table_name 'tab');

INSERT INTO mariadb_tab SELECT * FROM tab;

```

PostgreSQL's COPY TO
--------------------

 PostgreSQL's `[COPY TO](https://www.postgresql.org/docs/current/sql-copy.html)` allows you to copy the data from a PostgreSQL table to a text file. This data can then be loaded into MariaDB with `[LOAD DATA INFILE](../load-data-infile/index)`.

 MySQL Workbench
---------------

 MySQL Workbench has a [migration feature](https://www.mysql.com/products/workbench/migrate/) that requires an [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity) driver. PostgreSQL does have a freely available ODBC driver called `[psqlODBC](https://odbc.postgresql.org/)`. 

 See [Set up and configure PostgreSQL ODBC drivers for the MySQL Workbench Migration Wizard](http://mysqlworkbench.org/2012/11/set-up-and-configure-postgresql-odbc-drivers-for-the-mysql-workbench-migration-wizard/) for more information.

 Known Issues
------------

 ### Migrating Functions and Procedures

 PostgreSQL's [functions](https://www.postgresql.org/docs/current/sql-createfunction.html) and [procedures](https://www.postgresql.org/docs/11/sql-createprocedure.html) use a language called `[PL/pgSQL](https://www.postgresql.org/docs/current/plpgsql.html)`. This language is quite different than the default `SQL/PSM` language used for MariaDB's [stored procedures](../stored-procedures/index). `PL/pgSQL` is more similar to `PL/PSQL` from Oracle, so you may find it beneficial to try migrate with `[SQL\_MODE=ORACLE](../sql_modeoracle-from-mariadb-103/index)` set.

 See also
--------

 * [Set up and configure PostgreSQL ODBC drivers for the MySQL Workbench Migration Wizard](http://mysqlworkbench.org/2012/11/set-up-and-configure-postgresql-odbc-drivers-for-the-mysql-workbench-migration-wizard/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/migrating-to-mariadb-from-postgresql/>

IGNORE
======

    The `IGNORE` option tells the server to ignore some common errors.

 `IGNORE` can be used with the following statements:

 * [DELETE](../delete/index)
* [INSERT](../insert/index) (see also [INSERT IGNORE](../insert-ignore/index))
* [LOAD DATA INFILE](../load-data-infile/index)
* [UPDATE](../update/index)
* [ALTER TABLE](../alter-table/index)
* [CREATE TABLE ... SELECT](../create-table/index#create-select)
* [INSERT ... SELECT](../insert-select/index)

 The logic used:

 * Variables out of ranges are replaced with the maximum/minimum value.

 * [SQL\_MODEs](../sql_mode/index) `STRICT_TRANS_TABLES`, `STRICT_ALL_TABLES`, `NO_ZERO_IN_DATE`, `NO_ZERO_DATE` are ignored.

 * Inserting `NULL` in a `NOT NULL` field will insert 0 ( in a numerical field), 0000-00-00 ( in a date field) or an empty string ( in a character field).

 * Rows that cause a duplicate key error or break a foreign key constraint are not inserted, updated, or deleted.

 The following errors are ignored:

 


| Error number | Symbolic error name | Description |
| --- | --- | --- |
| `1022` | `ER_DUP_KEY` | Can't write; duplicate key in table '%s' |
| `1048` | `ER_BAD_NULL_ERROR` | Column '%s' cannot be null |
| `1062` | `ER_DUP_ENTRY` | Duplicate entry '%s' for key %d |
| `1242` | `ER_SUBQUERY_NO_1_ROW` | Subquery returns more than 1 row |
| `1264` | `ER_WARN_DATA_OUT_OF_RANGE` | Out of range value for column '%s' at row %ld |
| `1265` | `WARN_DATA_TRUNCATED` | Data truncated for column '%s' at row %ld |
| `1292` | `ER_TRUNCATED_WRONG_VALUE` | Truncated incorrect %s value: '%s' |
| `1366` | `ER_TRUNCATED_WRONG_VALUE_FOR_FIELD` | Incorrect integer value |
| `1369` | `ER_VIEW_CHECK_FAILED` | `CHECK OPTION failed '%s.%s'` |
| `1451` | `ER_ROW_IS_REFERENCED_2` | Cannot delete or update a parent row |
| `1452` | `ER_NO_REFERENCED_ROW_2` | Cannot add or update a child row: a foreign key constraint fails (%s) |
| `1526` | `ER_NO_PARTITION_FOR_GIVEN_VALUE` | Table has no partition for value %s |
| `1586` | `ER_DUP_ENTRY_WITH_KEY_NAME` | Duplicate entry '%s' for key '%s' |
| `1591` | `ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT` | Table has no partition for some existing values |
| `1748` | `ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET` | Found a row not matching the given partition set |

 
Ignored errors normally generate a warning.

 A property of the `IGNORE` clause consists in causing transactional engines and non-transactional engines (like InnoDB and Aria) to behave the same way. For example, normally a multi-row insert which tries to violate a `UNIQUE` contraint is completely rolled back on InnoDB, but might be partially executed on Aria. With the `IGNORE` clause, the statement will be partially executed in both engines.

 Duplicate key errors also generate warnings. The [OLD\_MODE](../old_mode/index) server variable can be used to prevent this.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ignore/>

CURDATE
=======

    Syntax
------

 
```
CURDATE()
CURRENT_DATE
CURRENT_DATE()

```

Description
-----------

 `CURDATE` returns the current date as a value in 'YYYY-MM-DD' or YYYYMMDD format, depending on whether the function is used in a string or numeric context.

 `CURRENT_DATE` and `CURRENT_DATE()` are synonyms.

 Examples
--------

 
```
SELECT CURDATE();
+------------+
| CURDATE()  |
+------------+
| 2019-03-05 |
+------------+

```

In a numeric context (note this is not performing date calculations):

 
```
SELECT CURDATE() +0;
+--------------+
| CURDATE() +0 |
+--------------+
|     20190305 |
+--------------+

```

Data calculation:

 
```
SELECT CURDATE() - INTERVAL 5 DAY;
+----------------------------+
| CURDATE() - INTERVAL 5 DAY |
+----------------------------+
| 2019-02-28                 |
+----------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/curdate/>

SHOW PROCESSLIST
================

    Syntax
------

 
```
SHOW [FULL] PROCESSLIST

```

Description
-----------

 `SHOW PROCESSLIST` shows you which threads are running. You can also get this information from the [information\_schema.PROCESSLIST](../information-schema-processlist-table/index) table or the [mariadb-admin processlist](../mariadb-admin/index) command. If you have the `[PROCESS privilege](../show-privileges/index)`, you can see all threads. Otherwise, you can see only your own threads (that is, threads associated with the MariaDB account that you are using). If you do not use the `FULL` keyword, only the first 100 characters of each statement are shown in the Info field.

 The columns shown in `SHOW PROCESSLIST` are:

 


| Name | Description |
| --- | --- |
| **`ID`** | The client's process ID. |
| **`USER`** | The username associated with the process. |
| **`HOST`** | The host the client is connected to. |
| **`DB`** | The default database of the process (NULL if no default). |
| **`COMMAND`** | The command type. See [Thread Command Values](../thread-command-values/index). |
| **`TIME`** | The amount of time, in seconds, the process has been in its current state. For a replica SQL thread before [MariaDB 10.1](../what-is-mariadb-101/index), this is the time in seconds between the last replicated event's timestamp and the replica machine's real time. |
| **`STATE`** | See [Thread States](../thread-states/index). |
| **`INFO`** | The statement being executed. |
| **`PROGRESS`** | The total progress of the process (0-100%) (see [Progress Reporting](../progress-reporting/index)). |

 
See `TIME_MS` column in [information\_schema.PROCESSLIST](../time_ms-column-in-information_schemaprocesslist/index) for differences in the `TIME` column between MariaDB and MySQL.

 The [information\_schema.PROCESSLIST](../information-schema-processlist-table/index) table contains the following additional columns:

 


| Name | Description |
| --- | --- |
| **`TIME_MS`** | The amount of time, in milliseconds, the process has been in its current state. |
| **`STAGE`** | The stage the process is currently in. |
| **`MAX_STAGE`** | The maximum number of stages. |
| **`PROGRESS`** | The progress of the process within the current stage (0-100%). |
| **`MEMORY_USED`** | The amount of memory used by the process. |
| **`EXAMINED_ROWS`** | The number of rows the process has examined. |
| **`QUERY_ID`** | Query ID. |

 
Note that the `PROGRESS` field from the information schema, and the `PROGRESS` field from `SHOW PROCESSLIST` display different results. `SHOW PROCESSLIST` shows the total progress, while the information schema shows the progress for the current stage only.

 Threads can be killed using their thread\_id or their query\_id, with the [KILL](../data-manipulation-kill-connection-query/index) statement.

 Since queries on this table are locking, if the [performance\_schema](../performance-schema/index) is enabled, you may want to query the [THREADS](../performance-schema-threads-table/index) table instead.

 Examples
--------

 
```
SHOW PROCESSLIST;
+----+-----------------+-----------+------+---------+------+------------------------+------------------+----------+
| Id | User            | Host      | db   | Command | Time | State                  | Info             | Progress |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+----------+
|  2 | event_scheduler | localhost | NULL | Daemon  | 2693 | Waiting on empty queue | NULL             |    0.000 |
|  4 | root            | localhost | NULL | Query   |    0 | Table lock             | SHOW PROCESSLIST |    0.000 |
+----+-----------------+-----------+------+---------+------+------------------------+------------------+----------+

```

See Also
--------

 [CONNECTION\_ID()](../connection_id/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-processlist/>

COUNT
=====

    Syntax
------

 
```
COUNT(expr)

```
 Description
-----------

 Returns a count of the number of non-NULL values of expr in the rows retrieved by a [SELECT](../select/index) statement. The result is a [BIGINT](../bigint/index) value. It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 COUNT(\*) counts the total number of rows in a table.

 COUNT() returns 0 if there were no matching rows.

 COUNT() can be used as a [window function](../window-functions/index).

 Examples
--------

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT COUNT(*) FROM student;
+----------+
| COUNT(*) |
+----------+
|        8 |
+----------+

```

[COUNT(DISTINCT)](../count-distinct/index) example:

 
```
SELECT COUNT(DISTINCT (name)) FROM student;
+------------------------+
| COUNT(DISTINCT (name)) |
+------------------------+
|                      4 |
+------------------------+

```

As a [window function](../window-functions/index)

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, COUNT(score) OVER (PARTITION BY name) 
    AS tests_written FROM student_test;
+---------+--------+-------+---------------+
| name    | test   | score | tests_written |
+---------+--------+-------+---------------+
| Chun    | SQL    |    75 |             2 |
| Chun    | Tuning |    73 |             2 |
| Esben   | SQL    |    43 |             2 |
| Esben   | Tuning |    31 |             2 |
| Kaolin  | SQL    |    56 |             2 |
| Kaolin  | Tuning |    88 |             2 |
| Tatiana | SQL    |    87 |             1 |
+---------+--------+-------+---------------+

```

See Also
--------

 * [SELECT](../select/index)
* [COUNT DISTINCT](../count-distinct/index)
* [Window Functions](../window-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/count/>

MAX
===

    Syntax
------

 
```
MAX([DISTINCT] expr)

```
 Description
-----------

 Returns the largest, or maximum, value of *`expr`*. `MAX()` can also take a string argument in which case it returns the maximum string value. The `DISTINCT` keyword can be used to find the maximum of the distinct values of *`expr`*, however, this produces the same result as omitting `DISTINCT`.

 Note that [SET](../set/index) and [ENUM](../enum/index) fields are currently compared by their string value rather than their relative position in the set, so MAX() may produce a different highest result than ORDER BY DESC.

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 MAX() can be used as a [window function](../window-functions/index).

 `MAX()` returns `NULL` if there were no matching rows.

 Examples
--------

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, MAX(score) FROM student GROUP BY name;
+---------+------------+
| name    | MAX(score) |
+---------+------------+
| Chun    |         75 |
| Esben   |         43 |
| Kaolin  |         88 |
| Tatiana |         87 |
+---------+------------+

```

MAX string:

 
```
SELECT MAX(name) FROM student;
+-----------+
| MAX(name) |
+-----------+
| Tatiana   |
+-----------+

```

Be careful to avoid this common mistake, not grouping correctly and returning mismatched data: 

 
```
SELECT name,test,MAX(SCORE) FROM student;
+------+------+------------+
| name | test | MAX(SCORE) |
+------+------+------------+
| Chun | SQL  |         88 |
+------+------+------------+

```

Difference between ORDER BY DESC and MAX():

 
```
CREATE TABLE student2(name CHAR(10),grade ENUM('b','c','a'));

INSERT INTO student2 VALUES('Chun','b'),('Esben','c'),('Kaolin','a');

SELECT MAX(grade) FROM student2;
+------------+
| MAX(grade) |
+------------+
| c          |
+------------+

SELECT grade FROM student2 ORDER BY grade DESC LIMIT 1;
+-------+
| grade |
+-------+
| a     |
+-------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);
INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, MAX(score) 
  OVER (PARTITION BY name) AS highest_score FROM student_test;
+---------+--------+-------+---------------+
| name    | test   | score | highest_score |
+---------+--------+-------+---------------+
| Chun    | SQL    |    75 |            75 |
| Chun    | Tuning |    73 |            75 |
| Esben   | SQL    |    43 |            43 |
| Esben   | Tuning |    31 |            43 |
| Kaolin  | SQL    |    56 |            88 |
| Kaolin  | Tuning |    88 |            88 |
| Tatiana | SQL    |    87 |            87 |
+---------+--------+-------+---------------+

```

See Also
--------

 * [AVG](../avg/index) (average)
* [MIN](../min/index) (minimum)
* [SUM](../sum/index) (sum total)
* [MIN/MAX optimization](../minmax-optimization/index) used by the optimizer
* [GREATEST()](../greatest/index) returns the largest value from a list

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/max/>

SHOW CREATE PROCEDURE
=====================

    Syntax
------

 
```
SHOW CREATE PROCEDURE proc_name

```
 Description
-----------

 This statement is a MariaDB extension. It returns the exact string that can be used to re-create the named [stored procedure](../stored-procedures/index), as well as the `[SQL\_MODE](../sql-mode/index)` that was used when the trigger has been created and the character set used by the connection.. A similar statement, `[SHOW CREATE FUNCTION](../show-create-function/index)`, displays information about [stored functions](../stored-functions/index).

 Both statements require that you are the owner of the routine or have the `[SELECT](../grant/index)` privilege on the `[mysql.proc](../mysqlproc-table/index)` table. When neither is true, the statements display `NULL` for the `Create Procedure` or `Create Function` field.

 
**Warning** Users with `SELECT` privileges on `[mysql.proc](../mysqlproc-table/index)` or `USAGE` privileges on `*.*` can view the text of routines, even when they do not have privileges for the function or procedure itself.

 
The output of these statements is unreliably affected by the `[sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create)` server system variable - see <http://bugs.mysql.com/bug.php?id=12719>

 Examples
--------

 Here's a comparison of the `SHOW CREATE PROCEDURE` and `[SHOW CREATE FUNCTION](../show-create-function/index)` statements.

 
```
SHOW CREATE PROCEDURE test.simpleproc\G
*************************** 1. row ***************************
           Procedure: simpleproc
            sql_mode: 
    Create Procedure: CREATE PROCEDURE `simpleproc`(OUT param1 INT)
                      BEGIN
                      SELECT COUNT(*) INTO param1 FROM t;
                      END
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

SHOW CREATE FUNCTION test.hello\G
*************************** 1. row ***************************
            Function: hello
            sql_mode:
     Create Function: CREATE FUNCTION `hello`(s CHAR(20))
                      RETURNS CHAR(50)
                      RETURN CONCAT('Hello, ',s,'!')
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

```

When the user issuing the statement does not have privileges on the routine, attempting to `[CALL](../call/index)` the procedure raises Error 1370.

 
```
CALL test.prc1();
Error 1370 (42000): execute command denieed to user 'test_user'@'localhost' for routine 'test'.'prc1'

```

If the user neither has privilege to the routine nor the `[SELECT](../grant/index)` privilege on `[mysql.proc](../mysqlproc-table/index)` table, it raises Error 1305, informing them that the procedure does not exist.

 
```
SHOW CREATE TABLES test.prc1\G
Error 1305 (42000): PROCEDURE prc1 does not exist

```

See Also
--------

 * [Stored Procedure Overview](../stored-procedure-overview/index)
* [CREATE PROCEDURE](../create-procedure/index)
* [ALTER PROCEDURE](../alter-procedure/index)
* [DROP PROCEDURE](../drop-procedure/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-procedure/>

Reserved Words
==============

    The following is a list of all reserved words in MariaDB.

 Reserved words cannot be used as [Identifiers](../identifier-names/index), unless they are quoted.

 The definitive list of reserved words for each version can be found by examining the `sql/lex.h` and `sql/sql_yacc.yy` files.

 Reserved Words
--------------

 


| Keyword | Notes |
| --- | --- |
| ACCESSIBLE |  |
| ADD |  |
| ALL |  |
| ALTER |  |
| ANALYZE |  |
| AND |  |
| AS |  |
| ASC |  |
| ASENSITIVE |  |
| BEFORE |  |
| BETWEEN |  |
| BIGINT |  |
| BINARY |  |
| BLOB |  |
| BOTH |  |
| BY |  |
| CALL |  |
| CASCADE |  |
| CASE |  |
| CHANGE |  |
| CHAR |  |
| CHARACTER |  |
| CHECK |  |
| COLLATE |  |
| COLUMN |  |
| CONDITION |  |
| CONSTRAINT |  |
| CONTINUE |  |
| CONVERT |  |
| CREATE |  |
| CROSS |  |
| CURRENT\_DATE |  |
| CURRENT\_ROLE |  |
| CURRENT\_TIME |  |
| CURRENT\_TIMESTAMP |  |
| CURRENT\_USER |  |
| CURSOR |  |
| DATABASE |  |
| DATABASES |  |
| DAY\_HOUR |  |
| DAY\_MICROSECOND |  |
| DAY\_MINUTE |  |
| DAY\_SECOND |  |
| DEC |  |
| DECIMAL |  |
| DECLARE |  |
| DEFAULT |  |
| DELAYED |  |
| DELETE |  |
| DELETE\_DOMAIN\_ID |  |
| DESC |  |
| DESCRIBE |  |
| DETERMINISTIC |  |
| DISTINCT |  |
| DISTINCTROW |  |
| DIV |  |
| DO\_DOMAIN\_IDS |  |
| DOUBLE |  |
| DROP |  |
| DUAL |  |
| EACH |  |
| ELSE |  |
| ELSEIF |  |
| ENCLOSED |
| ESCAPED |  |
| EXCEPT | Added in [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| EXISTS |  |
| EXIT |  |
| EXPLAIN |  |
| FALSE |  |
| FETCH |  |
| FLOAT |  |
| FLOAT4 |  |
| FLOAT8 |  |
| FOR |  |
| FORCE |  |
| FOREIGN |  |
| FROM |
| FULLTEXT |  |
| GENERAL |  |
| GRANT |  |
| GROUP |  |
| HAVING |  |
| HIGH\_PRIORITY |  |
| HOUR\_MICROSECOND |  |
| HOUR\_MINUTE |  |
| HOUR\_SECOND |  |
| IF |  |
| IGNORE |  |
| IGNORE\_DOMAIN\_IDS |  |
| IGNORE\_SERVER\_IDS |  |
| IN |  |
| INDEX |  |
| INFILE |  |
| INNER |  |
| INOUT |  |
| INSENSITIVE |  |
| INSERT |  |
| INT |  |
| INT1 |  |
| INT2 |  |
| INT3 |  |
| INT4 |  |
| INT8 |  |
| INTEGER |  |
| INTERSECT | Added in [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| INTERVAL |  |
| INTO |  |
| IS |  |
| ITERATE |  |
| JOIN |  |
| KEY |  |
| KEYS |  |
| KILL |  |
| LEADING |  |
| LEAVE |  |
| LEFT |  |
| LIKE |  |
| LIMIT |  |
| LINEAR |  |
| LINES |  |
| LOAD |  |
| LOCALTIME |  |
| LOCALTIMESTAMP |  |
| LOCK |  |
| LONG |  |
| LONGBLOB |  |
| LONGTEXT |  |
| LOOP |  |
| LOW\_PRIORITY |  |
| MASTER\_HEARTBEAT\_PERIOD |  |
| MASTER\_SSL\_VERIFY\_SERVER\_CERT |  |
| MATCH |  |
| MAXVALUE |  |
| MEDIUMBLOB |  |
| MEDIUMINT |  |
| MEDIUMTEXT |  |
| MIDDLEINT |  |
| MINUTE\_MICROSECOND |  |
| MINUTE\_SECOND |  |
| MOD |  |
| MODIFIES |  |
| NATURAL |  |
| NOT |  |
| NO\_WRITE\_TO\_BINLOG |  |
| NULL |  |
| NUMERIC |  |
| OFFSET | Added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| ON |  |
| OPTIMIZE |  |
| OPTION |  |
| OPTIONALLY |  |
| OR |  |
| ORDER |  |
| OUT |  |
| OUTER |  |
| OUTFILE |  |
| OVER |  |
| PAGE\_CHECKSUM |  |
| PARSE\_VCOL\_EXPR |  |
| PARTITION |  |
| POSITION |  |
| PRECISION |  |
| PRIMARY |  |
| PROCEDURE |  |
| PURGE |  |
| RANGE |  |
| READ |  |
| READS |  |
| READ\_WRITE |  |
| REAL |
| RECURSIVE |  |
| REF\_SYSTEM\_ID |  |
| REFERENCES |  |
| REGEXP |  |
| RELEASE |  |
| RENAME |  |
| REPEAT |  |
| REPLACE |  |
| REQUIRE |  |
| RESIGNAL |  |
| RESTRICT |  |
| RETURN |  |
| RETURNING |  |
| REVOKE |  |
| RIGHT |  |
| RLIKE |  |
| ROW\_NUMBER | From [MariaDB 10.7](../what-is-mariadb-107/index) |
| ROWS |  |
| SCHEMA |  |
| SCHEMAS |  |
| SECOND\_MICROSECOND |  |
| SELECT |  |
| SENSITIVE |  |
| SEPARATOR |  |
| SET |  |
| SHOW |  |
| SIGNAL |  |
| SLOW |  |
| SMALLINT |  |
| SPATIAL |  |
| SPECIFIC |  |
| SQL |  |
| SQLEXCEPTION |  |
| SQLSTATE |  |
| SQLWARNING |  |
| SQL\_BIG\_RESULT |  |
| SQL\_CALC\_FOUND\_ROWS |  |
| SQL\_SMALL\_RESULT |  |
| SSL |  |
| STARTING |  |
| STATS\_AUTO\_RECALC |  |
| STATS\_PERSISTENT |  |
| STATS\_SAMPLE\_PAGES |  |
| STRAIGHT\_JOIN |  |
| TABLE |  |
| TERMINATED |  |
| THEN |  |
| TINYBLOB |  |
| TINYINT |  |
| TINYTEXT |  |
| TO |  |
| TRAILING |  |
| TRIGGER |  |
| TRUE |  |
| UNDO |  |
| UNION |  |
| UNIQUE |  |
| UNLOCK |  |
| UNSIGNED |  |
| UPDATE |  |
| USAGE |  |
| USE |  |
| USING |  |
| UTC\_DATE |  |
| UTC\_TIME |  |
| UTC\_TIMESTAMP |  |
| VALUES |  |
| VARBINARY |  |
| VARCHAR |  |
| VARCHARACTER |  |
| VARYING |  |
| WHEN |  |
| WHERE |  |
| WHILE |  |
| WINDOW | Only disallowed for table aliases. |
| WITH |  |
| WRITE |  |
| XOR |  |
| YEAR\_MONTH |  |
| ZEROFILL |  |

 
Exceptions
----------

 Some keywords are exceptions for historical reasons, and are permitted as unquoted identifiers. These include:

 


| Keyword |
| --- |
| ACTION |
| [BIT](../bit/index) |
| [DATE](../date/index) |
| [ENUM](../enum/index) |
| NO |
| [TEXT](../text/index) |
| [TIME](../time/index) |
| [TIMESTAMP](../timestamp/index) |

 
Oracle Mode
-----------

 In [Oracle mode, from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index), there are a number of extra reserved words:

 


| Keyword | Notes |
| --- | --- |
| BODY |  |
| ELSIF |  |
| GOTO |  |
| HISTORY | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only |
| MINUS | From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) |
| OTHERS |  |
| PACKAGE |
| PERIOD | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only |
| RAISE |  |
| ROWNUM | From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) |
| ROWTYPE |  |
| SYSDATE | From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) |
| SYSTEM | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only. Note however that SYSTEM sometimes needs to be quoted to avoid confusion with [System-versioned tables](../system-versioned-tables/index). |
| SYSTEM\_TIME | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only |
| VERSIONING | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only |
| WITHOUT | <= [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) only |

 
Function Names
--------------

 If the `IGNORE_SPACE` [SQL\_MODE](../sql-mode/index) flag is set, function names become reserved words.

 See Also
--------

 * [Information Schema KEYWORDS Table](../information-schema-keywords-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/reserved-words/>

Information Schema ROUTINES Table
=================================

    The [Information Schema](../information_schema/index) `ROUTINES` table stores information about [stored procedures](../stored-procedures/index) and [stored functions](../stored-functions/index).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `SPECIFIC_NAME` |  |
| `ROUTINE_CATALOG` | Always `def`. |
| `ROUTINE_SCHEMA` | Database name associated with the routine. |
| `ROUTINE_NAME` | Name of the routine. |
| `ROUTINE_TYPE` | Whether the routine is a `PROCEDURE` or a `FUNCTION`. |
| `DATA_TYPE` | The return value's [data type](../data-types/index) (for stored functions). |
| `CHARACTER_MAXIMUM_LENGTH` | Maximum length. |
| `CHARACTER_OCTET_LENGTH` | Same as the `CHARACTER_MAXIMUM_LENGTH` except for multi-byte [character sets](../data-types-character-sets-and-collations/index). |
| `NUMERIC_PRECISION` | For numeric types, the precision (number of significant digits) for the column. `NULL` if not a numeric field. |
| `NUMERIC_SCALE` | For numeric types, the scale (significant digits to the right of the decimal point). NULL if not a numeric field. |
| `DATETIME_PRECISION` | Fractional-seconds precision, or NULL if not a [time data type](../date-and-time-data-types/index). |
| `CHARACTER_SET_NAME` | [Character set](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise `NULL`. |
| `COLLATION_NAME` | [Collation](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise NULL. |
| `DATA_TYPE` | The column's [data type](../data-types/index). |
| `ROUTINE_BODY` | Always `SQL`. |
| `ROUTINE_DEFINITION` | Definition of the routine. |
| `EXTERNAL_NAME` | Always `NULL`. |
| `EXTERNAL_LANGUAGE` | Always `SQL`. |
| `PARAMETER_STYLE` | Always `SQL`. |
| `IS_DETERMINISTIC` | Whether the routine is deterministic (can produce only one result for a given list of parameters) or not. |
| `SQL_DATA_ACCESS` | One of `READS SQL DATA`, `MODIFIES SQL DATA`, `CONTAINS SQL`, or `NO SQL`. |
| `SQL_PATH` | Always `NULL`. |
| `SECURITY_TYPE` | `INVOKER` or `DEFINER`. Indicates which user's privileges apply to this routine. |
| `CREATED` | Date and time the routine was created. |
| `LAST_ALTERED` | Date and time the routine was last changed. |
| `SQL_MODE` | The `[SQL\_MODE](../sql-mode/index)` at the time the routine was created. |
| `ROUTINE_COMMENT` | Comment associated with the routine. |
| `DEFINER` | If the `SECURITY_TYPE` is `DEFINER`, this value indicates which user defined this routine. |
| `CHARACTER_SET_CLIENT` | The [character set](../data-types-character-sets-and-collations/index) used by the client that created the routine. |
| `COLLATION_CONNECTION` | The [collation](../data-types-character-sets-and-collations/index) (and character set) used by the connection that created the routine. |
| `DATABASE_COLLATION` | The default [collation](../data-types-character-sets-and-collations/index) (and character set) for the database, at the time the routine was created. |

 
It provides information similar to, but more complete, than the `[SHOW PROCEDURE STATUS](../show-procedure-status/index)` and `[SHOW FUNCTION STATUS](../show-function-status/index)` statements.

 For information about the parameters accepted by the routine, you can query the `[information\_schema.PARAMETERS](../information-schema-parameters-table/index)` table.

 See also
--------

 * [Stored Function Overview](../stored-function-overview/index)
* [Stored Procedure Overview](../stored-procedure-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-routines-table/>

mysql\_secure\_installation
===========================

    
Note that many of the reasons for the existence of this script no longer apply. In particular, from [MariaDB 10.4](../what-is-mariadb-104/index), [Unix socket authentication](../authentication-plugin-unix-socket/index) is applied by default, and there is usually no need to create a root password. See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index).

 

**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-secure-installation](../mariadb-secure-installation/index) is a symlink to `mysql_secure_installation`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_secure_installation` is the symlink, and [mariadb-secure-installation](../mariadb-secure-installation/index) the binary name.

 
See [mariadb-secure-installation](../mariadb-secure-installation/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_secure_installation/>

Running mysqld as root
======================

    MariaDB should never normally be run as the system's root user (this is unrelated to the MariaDB root user). If it is, any user with the FILE privilege can create or modify any files on the server as root.

 MariaDB will normally return the error  **Fatal error: Please read "Security" section of the manual to find out how to run mysqld as root!** if you attempt to run mysqld as root. If you need to override this restriction for some reason, start mysqld with the `[user=root](../mysqld-options/index#-user)` option.

 Better practice, and the default in most situations, is to use a separate user, exclusively used for MariaDB. In most distributions, this user is called `mysql`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-mysqld-as-root/>

Data-in-Transit Encryption
===========================

   Data can be encrypted in transit using the Transport Layer Security (TLS) protocol.

  

| Title | Description |
| --- | --- |
|  [Secure Connections Overview](../secure-connections-overview/index) |  Data can be encrypted in transit using the TLS protocol.  |
|  [Certificate Creation with OpenSSL](../certificate-creation-with-openssl/index) |  How to generate a self-signed certificate in OpenSSL.  |
|  [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) |  Enabling TLS encryption in transit on both the client and server.  |
|  [Replication with Secure Connections](../replication-with-secure-connections/index) |  Enabling TLS encryption in transit for MariaDB replication.  |
|  [Securing Communications in Galera Cluster](../securing-communications-in-galera-cluster/index) |  Enabling TLS encryption in transit for Galera Cluster.  |
|  [SSL/TLS System Variables](../ssltls-system-variables/index) |  List and description of Transport Layer Security (TLS)-related system variables.  |
|  [SSL/TLS Status Variables](../ssltls-status-variables/index) |  List and description of Transport Layer Security (TLS)-related status variables.  |
|  [Using TLSv1.3](../using-tlsv13/index) |  TLSv1.3 is a major rewrite of the protocol.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-in-transit-encryption/>

Encryption
===========

  

| Title | Description |
| --- | --- |
|  [Data-in-Transit Encryption](../data-in-transit-encryption/index) |  Data can be encrypted in transit using the Transport Layer Security (TLS) protocol.  |
|  [Data-at-Rest Encryption](../encryption-data-at-rest-encryption/index) |  MariaDB supports the use of data-at-rest encryption for tables and tablespa...  |
|  [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) |  MariaDB supports several different TLS and cryptography libraries.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/securing-mariadb-encryption/>

SecuRich
========

    
SecuRich has not been updated since 2011.

 
SecuRich is a library of [stored procedures](../stored-procedures/index) that adds security features to MariaDB and MySQL. It is maintained by Darren Cassar, and can be downloaded from [securich.com](http://www.securich.com/).

 Its main purpose is to emulate [roles](../roles/index), but this feature has been supported in the server since [MariaDB 10.0](../what-is-mariadb-100/index). However other interesting features are available via SecuRich, such as the ability to block a user, clone a user or set a password that will expire (also supported since [MariaDB 10.4](../what-is-mariadb-104/index) - see [User Password Expiry](../user-password-expiry/index)).

 To use SecuRich features, its stored procedures should be used instead of the usual security-related SQL statements. For example, drop\_user() should be used instead of [DROP USER](../drop-user/index). However, if a combination of SecuRich procedure and normal SQL statements is used, SecuRich can reconcile its tables with the system tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/securich/>

Security-Enhanced Linux with MariaDB
====================================

    [Security-Enhanced Linux (SELinux)](https://selinuxproject.org/page/Main_Page) is a Linux kernel module that provides a framework for configuring [mandatory access control (MAC)](https://en.wikipedia.org/wiki/Mandatory_access_control) system for many resources on the system. It is enabled by default on some Linux distributions, including RHEL, CentOS, Fedora, and other similar Linux distribution. SELinux prevents programs from accessing files, directories or ports unless it is configured to access those resources.

 Verifying Whether SELinux Is Enabled
------------------------------------

 To verify whether SELinux is enabled, execute the `[getenforce](https://linux.die.net/man/8/getenforce)` command. For example:

 
```
getenforce

```

### Temporarily Putting mysqld Into Permissive Mode

 When you are troubleshooting issues that you think SELinux might be causing, it can help to temporarily put `mysqld_t` into permissive mode. This can be done by executing the `[semanage](https://linux.die.net/man/8/semanage)` command. For example:

 
```
sudo semanage permissive -a mysqld_t

```

If that solved the problem, then it means that the current SELinux policy is the culprit. You need to adjust the SELinux policy or labels for MariaDB.

 Configuring a MariaDB Server SELinux Policy
-------------------------------------------

 MariaDB Server should work with your default distribution policy (which is usually part of the `selinux-policy` or `selinux-policy-targeted` system package). If you use `mysqld_safe`, you will need an additional policy file, `mariadb.pp`, which is installed together with the MariaDB Server. It will be loaded automatically if you have `/usr/sbin/semodule` installed, but you can load it manually anytime with

 
```
/usr/sbin/semodule -i /usr/share/mysql/policy/selinux/mariadb.pp

```

Note that this policy file extends, but not replaces the system policy.

 Setting File Contexts
---------------------

 SELinux uses [file contexts](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-working_with_selinux-selinux_contexts_labeling_files) as a way to determine who should be able to access that file.

 File contexts are managed with the `[semanage fcontext](##%5B%5Bhttps%3A//linux.die.net/man/8/semanage)` and `[restorecon](https://linux.die.net/man/8/restorecon)` commands.

 On many systems, the `[semanage](##%5B%5Bhttps%3A//linux.die.net/man/8/semanage)` utility is installed by the `policycoreutils-python` package, and the `[restorecon](https://linux.die.net/man/8/restorecon)` utility is installed by the `policycoreutils` package. You can install these with the following command:

 
```
sudo yum install policycoreutils policycoreutils-python

```

A file or directory's current context can be checked by executing `ls` with the `--context` or `--scontext` options.

 ### Setting the File Context for the Data Directory

 If you use a custom directory for `[datadir](../server-system-variables/index#datadir)`, then you may need to set the file context for that directory. The SELinux file context for MariaDB data files is `mysqld_db_t`. You can determine if this file context is present on your system and which files or directories it is associated with by executing the following command:

 
```
sudo semanage fcontext --list | grep mysqld_db_t

```

If you would like to set the file context for your custom directory for your `[datadir](../server-system-variables/index#datadir)`, then that can be done by executing the `[semanage fcontext](https://linux.die.net/man/8/semanage)` and `[restorecon](https://linux.die.net/man/8/restorecon)` commands. For example:

 
```
sudo semanage fcontext -a -t mysqld_db_t "/mariadb/data(/.*)?"
sudo restorecon -Rv /mariadb/data

```

If you would like to check the current file context, you can do so by by executing `ls` with the `--context` or `--scontext` options. For example:

 
```
ls --directory --scontext /mariadb/data

```

### Setting the File Context for Log Files

 If you use a custom directory for [log files](../server-monitoring-logs/index), then you may need to set the file context for that directory. The SELinux file context for MariaDB [log files](../server-monitoring-logs/index) is `mysqld_log_t`. You can determine if this file context is present on your system and which files or directories it is associated with by executing the following command:

 
```
sudo semanage fcontext --list | grep mysqld_log_t

```

If you would like to set the file context for your custom directory for [log files](../server-monitoring-logs/index), then that can be done by executing the `[semanage fcontext](https://linux.die.net/man/8/semanage)` and `[restorecon](https://linux.die.net/man/8/restorecon)` commands. For example:

 
```
sudo semanage fcontext -a -t mysqld_log_t "/var/log/mysql(/.*)?"
sudo restorecon -Rv /var/log/mysql

```

If you would like to check the current file context, you can do so by by executing `ls` with the `--context` or `--scontext` options. For example:

 
```
ls --directory --scontext /var/log/mysql

```

### Setting the File Context for Option Files

 If you use a custom directory for [option files](../configuring-mariadb-with-option-files/index), then you may need to set the file context for that directory. The SELinux file context for MariaDB [option files](../configuring-mariadb-with-option-files/index) is `mysqld_etc_t`. You can determine if this file context is present on your system and which files or directories it is associated with by executing the following command:

 
```
sudo semanage fcontext --list | grep mysqld_etc_t

```

If you would like to set the file context for your custom directory for [option files](../configuring-mariadb-with-option-files/index), then that can be done by executing the `[semanage fcontext](https://linux.die.net/man/8/semanage)` and `[restorecon](https://linux.die.net/man/8/restorecon)` commands. For example:

 
```
sudo semanage fcontext -a -t mysqld_etc_t "/etc/mariadb(/.*)?"
sudo restorecon -Rv /etc/mariadb

```

If you would like to check the current file context, you can do so by by executing `ls` with the `--context` or `--scontext` options. For example:

 
```
ls --directory --scontext /etc/mariadb

```

### Allowing Access to the Tmpfs File Context

 If you wanted to mount your `[tmpdir](../server-system-variables/index#tmpdir)` on a `tmpfs` file system or wanted to use a `tmpfs` file system on `/run/shm`, then you might need to allow `mysqld_t` to have access to a couple tmpfs-related file contexts. For example:

 
```
cd /usr/share/mysql/policy/selinux/
tee ./mysqld_tmpfs.te <<EOF
module mysqld_tmpfs 1.0;

require {
type tmpfs_t;
type mysqld_t;
class dir { write search read remove_name open getattr add_name };
class file { write getattr read lock create unlink open };
}

allow mysqld_t tmpfs_t:dir { write search read remove_name open getattr add_name };

allow mysqld_t tmpfs_t:file { write getattr read lock create unlink open }
EOF
sudo checkmodule -M -m mysqld_tmpfs.te -o mysqld_tmpfs.mod
sudo semodule_package -m mysqld_tmpfs.mod -o mysqld_tmpfs.pp 
sudo semodule -i mysqld_tmpfs.pp

```

Troubleshooting SELinux Issues
------------------------------

 You might need to troubleshoot SELinux-related issues in cases, such as:

 * MariaDB is using a non-default port.
* MariaDB is reading from or writing to some files (datadir, log files, option files, etc.) located at non-default paths.
* MariaDB is using a plugin that requires access to resources that default installations do not use.

 ### File System Permission Errors

 If the file system permissions for some MariaDB directory look fine, but the MariaDB [error log](../error-log/index) still has errors that look similar to the following:

 
```
130321 11:50:51 mysqld_safe Starting mysqld daemon with databases from /datadir
...
2013-03-21 11:50:52 2119 [Warning] Can't create test file /datadir/
2013-03-21 11:50:52 2119 [Warning] Can't create test file /datadir/
...
2013-03-21 11:50:52 2119 [ERROR] /usr/sbin/mysqld: Can't create/write to file 
    '/datadir/boxy.pid' (Errcode: 13 - Permission denied)
2013-03-21 11:50:52 2119 [ERROR] Can't start server: can't create PID file: 
    Permission denied
130321 11:50:52 mysqld_safe mysqld from pid file /datadir/boxy.pid ended

```

Then check SELinux's `/var/log/audit/audit.log` for log entries that look similar to the following:

 
```
type=AVC msg=audit(1363866652.030:24): avc:  denied  { write } for  pid=2119 
    comm="mysqld" name="datadir" dev=dm-0 ino=394 
    scontext=unconfined_u:system_r:mysqld_t:s0 
    tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

```

If you see any entries that look similar to this, then you most likely need to adjust the file contexts for some files or directories. See [Setting File Contexts](#setting-file-contexts) for more information on how to do that.

 ### SELinux and MariaDB On a Different Port

 TCP and UDP ports are enabled for permission to bind too. If you are using a different port, or some Galera ports, configure SELinux to be able to use those ports:

 
```
sudo semanage port -a -t mysqld_port_t -p tcp 3307 

```

### Generating SELinux Policies with audit2allow

 In some cases, a MariaDB system might need non-standard policies. It is possible to create these policies from the SELinux audit log using the `[audit2allow](https://linux.die.net/man/1/audit2allow)` utility. The `[semanage](https://linux.die.net/man/8/semanage)` and `[semodule](https://linux.die.net/man/8/semodule)` utilities will also be needed.

 On many systems, the `[audit2allow](https://linux.die.net/man/1/audit2allow)` and `[semanage](https://linux.die.net/man/8/semanage)` utilities are installed by the `policycoreutils-python` package, and the `[semodule](https://linux.die.net/man/8/semodule)` utility is installed by the `policycoreutils` package. You can install these with the following command:

 
```
sudo yum install policycoreutils policycoreutils-python

```

The following process can be used to generate a policy from the audit log:

 * Remove dontaudits from the policy:

 
```
sudo semodule -DB

```

* Temporarily put `mysqld_t` into permissive mode. For example:

 
```
sudo semanage permissive -a mysqld_t

```

* [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 * Do whatever was causing SELinux errors.

 * Use the generated audit log to create a policy:

 
```
sudo grep mysqld /var/log/audit/audit.log | audit2allow -M mariadb_local
sudo semodule -i mariadb_local.pp

```

* Pull `mysqld_t` out of permissive mode. For example:

 
```
sudo semanage permissive -d mysqld_t

```

* Restore dontaudits for the policy:

 
```
sudo setmodule -B

```

The same procedure can be used if MariaDB starts but SELinux prevents it from functioning correctly. For example, SELinux may prevent [PAM plugin](../pam-authentication-plugin/index) from authenticating users. The solution is the same — enable auditing, switch to permissive, do, whatever SELinux didn't allow you to, create a policy from the audit log.

 When you discover any needed SELinux permissions, please report the needed permissions to your operating system bug tracking so all users can benefit from your work (e.g. Red Hat Bugzilla <https://bugzilla.redhat.com/>).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/selinux/>

Security Vulnerabilities Fixed in MariaDB
=========================================

    
This page is about security vulnerabilities fixed in MariaDB. If you are looking for information on securing your MariaDB installation, see [Securing MariaDB](../securing-mariadb/index).

 Sensitive security issues can be reported on <https://hackerone.com/mariadb> or sent directly to the persons responsible for MariaDB security: security [AT] mariadb (dot) org.

 
About CVEs
----------

 CVE® stands for *"**C**ommon **V**ulnerabilities and **E**xposures"*. It is a publicly available and free to use database of known software vulnerabilities maintained at <https://cve.mitre.org/>

 On this page is the master list of CVEs fixed across all versions of MariaDB. Follow the links to more information on a particular CVE or specific version of MariaDB.

 Some CVEs apply to MySQL but are not present in MariaDB, these are listed on the [Security Vulnerabilities fixed in Oracle MySQL that did not exist in MariaDB](../security-vulnerabilities-in-oracle-mysql-that-did-not-exist-in-mariadb/index) page.

 Separate lists of CVEs fixed in specific MariaDB series are maintained on their individual "What is MariaDB x.x?" pages:

 * [What is MariaDB 11.2?](../what-is-mariadb-11-2/index)
* [What is MariaDB 11.1?](../what-is-mariadb-11-1/index)
* [What is MariaDB 11.0?](../what-is-mariadb-11-0/index)
* [What is MariaDB 10.11?](../what-is-mariadb-10-11/index)
* [What is MariaDB 10.10?](../what-is-mariadb-1010/index)
* [What is MariaDB 10.9?](../what-is-mariadb-109/index)
* [What is MariaDB 10.8?](../what-is-mariadb-108/index)
* [What is MariaDB 10.7?](../what-is-mariadb-107/index)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)
* [What is MariaDB 10.5?](../what-is-mariadb-105/index)
* [What is MariaDB 10.4?](../what-is-mariadb-104/index)
* [What is MariaDB 10.3?](../what-is-mariadb-103/index)
* [What is MariaDB 10.2?](../what-is-mariadb-102/index)
* [What is MariaDB 10.1?](../what-is-mariadb-101/index)
* [What is MariaDB 10.0?](../what-is-mariadb-100/index)
* [What is MariaDB 5.5?](../what-is-mariadb-55/index)
* [What is MariaDB 5.3?](../what-is-mariadb-53/index)
* [What is MariaDB 5.2?](../what-is-mariadb-52/index)
* [What is MariaDB 5.1?](../what-is-mariadb-51/index)

 Full List of CVEs fixed in MariaDB
----------------------------------

 * [CVE-2022-47015](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-47015): [MariaDB 10.9.6](../mdb-10-9-6-rn/index), [MariaDB 10.8.8](../mdb-10-8-8-rn/index), [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/), [MariaDB 10.5.20](https://mariadb.com/kb/en/mariadb-10520-release-notes/), [MariaDB 10.4.29](https://mariadb.com/kb/en/mariadb-10429-release-notes/), [MariaDB 10.3.39](https://mariadb.com/kb/en/mariadb-10339-release-notes/), [MariaDB 10.11.3](../mdb-10-11-3-rn/index), [MariaDB 10.10.4](../mdb-10-10-4-rn/index)
* [CVE-2022-32091](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32091): [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [MariaDB 10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/), [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10-3-36-release-notes/)
* [CVE-2022-32089](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32089): [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [MariaDB 10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/)
* [CVE-2022-32088](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32088): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-32087](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32087): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-32086](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32086): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-32085](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32085): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-32084](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32084): [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [MariaDB 10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/), [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10-3-36-release-notes/)
* [CVE-2022-32083](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32083): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-32082](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32082): [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/)
* [CVE-2022-32081](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32081): [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [MariaDB 10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/)
* [CVE-2022-31624](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-31624): [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-10-6-5-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10-5-13-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/), [MariaDB 10.3.32](../mdb-10332-rn/index), [MariaDB 10.2.41](https://mariadb.com/kb/en/mariadb-10-2-41-release-notes/)
* [CVE-2022-27458](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27458): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27457](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27457): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27456](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27456): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27455](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27455): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27452](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27452): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27451](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27451): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27449](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27449): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27448](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27448): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27447](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27447): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27446](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27446): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27445](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27445): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27444](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27444): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27387](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27387): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27386](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27386): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27385](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27385): [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-10-6-5-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10-5-13-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/), [MariaDB 10.3.32](../mdb-10332-rn/index)
* [CVE-2022-27384](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27384): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27383](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27383): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27382](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27382): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/)
* [CVE-2022-27381](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27381): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27380](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27380): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27379](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27379): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-27378](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27378): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27377](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27377): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-27376](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27376): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index)
* [CVE-2022-24052](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24052): [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2022-24051](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24051): [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2022-24050](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24050): [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2022-24048](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24048): [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2022-21595](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21595): [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2022-21451](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21451): [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10-5-10-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10-4-19-release-notes/), [MariaDB 10.3.29](../mdb-10329-rn/index), [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10-2-38-release-notes/)
* [CVE-2022-21427](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21427): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2022-0778](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0778): [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2021-46669](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46669): [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-10-7-4-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-10-6-8-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10-5-16-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10-4-25-release-notes/), [MariaDB 10.3.35](../mdb-10335-rn/index), [MariaDB 10.2.44](https://mariadb.com/kb/en/mariadb-10-2-44-release-notes/)
* [CVE-2021-46668](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46668): [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-10-7-3-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-10-6-7-release-notes/), [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10-5-15-release-notes/), [MariaDB 10.4.24](https://mariadb.com/kb/en/mariadb-10-4-24-release-notes/), [MariaDB 10.3.34](../mdb-10334-rn/index), [MariaDB 10.2.43](https://mariadb.com/kb/en/mariadb-10-2-43-release-notes/)
* [CVE-2021-46667](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46667): [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-10-6-5-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10-5-13-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/), [MariaDB 10.3.32](../mdb-10332-rn/index), [MariaDB 10.2.41](https://mariadb.com/kb/en/mariadb-10-2-41-release-notes/)
* [CVE-2021-46666](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46666): [MariaDB 10.5.11](https://mariadb.com/kb/en/mariadb-10-5-11-release-notes/), [MariaDB 10.4.20](https://mariadb.com/kb/en/mariadb-10-4-20-release-notes/), [MariaDB 10.3.30](../mdb-10330-rn/index), [MariaDB 10.2.39](https://mariadb.com/kb/en/mariadb-10-2-39-release-notes/)
* [CVE-2021-46665](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46665): [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-10-7-3-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-10-6-7-release-notes/), [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10-5-15-release-notes/), [MariaDB 10.4.24](https://mariadb.com/kb/en/mariadb-10-4-24-release-notes/), [MariaDB 10.3.34](../mdb-10334-rn/index), [MariaDB 10.2.43](https://mariadb.com/kb/en/mariadb-10-2-43-release-notes/)
* [CVE-2021-46664](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46664): [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-10-7-3-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-10-6-7-release-notes/), [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10-5-15-release-notes/), [MariaDB 10.4.24](https://mariadb.com/kb/en/mariadb-10-4-24-release-notes/), [MariaDB 10.3.34](../mdb-10334-rn/index), [MariaDB 10.2.43](https://mariadb.com/kb/en/mariadb-10-2-43-release-notes/)
* [CVE-2021-46663](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46663): [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-10-7-3-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-10-6-7-release-notes/), [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10-5-15-release-notes/), [MariaDB 10.4.24](https://mariadb.com/kb/en/mariadb-10-4-24-release-notes/), [MariaDB 10.3.34](../mdb-10334-rn/index), [MariaDB 10.2.43](https://mariadb.com/kb/en/mariadb-10-2-43-release-notes/)
* [CVE-2021-46662](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46662): [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-10-6-5-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10-5-13-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/), [MariaDB 10.3.32](../mdb-10332-rn/index)
* [CVE-2021-46661](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46661): [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-10-7-3-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-10-6-7-release-notes/), [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10-5-15-release-notes/), [MariaDB 10.4.24](https://mariadb.com/kb/en/mariadb-10-4-24-release-notes/), [MariaDB 10.3.34](../mdb-10334-rn/index), [MariaDB 10.2.43](https://mariadb.com/kb/en/mariadb-10-2-43-release-notes/)
* [CVE-2021-46659](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46659): [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-10-8-1-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-10-7-2-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-10-6-6-release-notes/), [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10-5-14-release-notes/), [MariaDB 10.4.23](https://mariadb.com/kb/en/mariadb-10-4-23-release-notes/), [MariaDB 10.3.33](https://mariadb.com/kb/en/mariadb-10-3-33-release-notes/), [MariaDB 10.2.42](https://mariadb.com/kb/en/mariadb-10-2-42-release-notes/)
* [CVE-2021-46658](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46658): [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-10-6-3-release-notes/), [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10-5-12-release-notes/), [MariaDB 10.4.21](https://mariadb.com/kb/en/mariadb-10-4-21-release-notes/), [MariaDB 10.3.31](../mdb-10331-rn/index), [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10-2-40-release-notes/)
* [CVE-2021-46657](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-46657): [MariaDB 10.5.11](https://mariadb.com/kb/en/mariadb-10-5-11-release-notes/), [MariaDB 10.4.20](https://mariadb.com/kb/en/mariadb-10-4-20-release-notes/), [MariaDB 10.3.30](../mdb-10330-rn/index), [MariaDB 10.2.39](https://mariadb.com/kb/en/mariadb-10-2-39-release-notes/)
* [CVE-2021-35604](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35604): [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-10-6-3-release-notes/), [MariaDB 10.5.13](https://mariadb.com/kb/en/mariadb-10-5-13-release-notes/), [MariaDB 10.4.22](https://mariadb.com/kb/en/mariadb-10-4-22-release-notes/), [MariaDB 10.3.32](../mdb-10332-rn/index), [MariaDB 10.2.41](https://mariadb.com/kb/en/mariadb-10-2-41-release-notes/)
* [CVE-2021-27928](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-27928): [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-10-5-9-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10-4-18-release-notes/), [MariaDB 10.3.28](../mdb-10328-rn/index), [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10-2-37-release-notes/)
* [CVE-2021-2389](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2389): [MariaDB 10.6.4](https://mariadb.com/kb/en/mariadb-10-6-4-release-notes/) [[2](https://mariadb.com/kb/es/mariadb-10-6-4-release-notes/)], [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10-5-12-release-notes/), [MariaDB 10.4.21](https://mariadb.com/kb/en/mariadb-10-4-21-release-notes/), [MariaDB 10.3.31](../mdb-10331-rn/index), [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10-2-40-release-notes/)
* [CVE-2021-2372](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2372): [MariaDB 10.6.4](https://mariadb.com/kb/en/mariadb-10-6-4-release-notes/) [[2](https://mariadb.com/kb/es/mariadb-10-6-4-release-notes/)], [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10-5-12-release-notes/), [MariaDB 10.4.21](https://mariadb.com/kb/en/mariadb-10-4-21-release-notes/), [MariaDB 10.3.31](../mdb-10331-rn/index), [MariaDB 10.2.40](https://mariadb.com/kb/en/mariadb-10-2-40-release-notes/)
* [CVE-2021-2194](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2194): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/)
* [CVE-2021-2180](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2180): [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10-2-38-release-notes/)
* [CVE-2021-2174](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2174): [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10-2-18-release-notes/)
* [CVE-2021-2166](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2166): [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10-5-10-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10-4-19-release-notes/), [MariaDB 10.3.29](../mdb-10329-rn/index), [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10-2-38-release-notes/)
* [CVE-2021-2154](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2154): [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10-5-10-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10-4-19-release-notes/), [MariaDB 10.3.29](../mdb-10329-rn/index), [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10-2-38-release-notes/)
* [CVE-2021-2144](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2144): [MariaDB 5.5.66](https://mariadb.com/kb/en/mariadb-5-5-66-release-notes/), [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10-3-19-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10-2-28-release-notes/), [MariaDB 10.1.42](https://mariadb.com/kb/en/mariadb-10-1-42-release-notes/)
* [CVE-2021-2032](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2032): [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2021-2022](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2022): [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-10-5-5-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10-4-14-release-notes/), [MariaDB 10.3.24](../mdb-10324-rn/index), [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10-2-33-release-notes/), [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10-1-46-release-notes/)
* [CVE-2021-2011](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2011): [MariaDB Connector/C 3.0.5](../mcc-305-rn/index), [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2021-2007](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2007): [MariaDB Connector/C 3.1.3](../mcc-313-rn/index), [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2020-7221](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7221): [MariaDB 10.4.12](https://mariadb.com/kb/en/mariadb-10-4-12-release-notes/)
* [CVE-2020-2922](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2922): [MariaDB Connector/C 3.1.3](../mcc-313-rn/index), [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2020-28912](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28912): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/), [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10-1-48-release-notes/)
* [CVE-2020-2814](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2814): [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10-3-23-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10-2-32-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10-1-45-release-notes/)
* [CVE-2020-2812](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2812): [MariaDB 5.5.68](https://mariadb.com/kb/en/mariadb-5-5-68-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10-3-23-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10-2-32-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10-1-45-release-notes/)
* [CVE-2020-2780](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2780): [MariaDB 5.5.66](https://mariadb.com/kb/en/mariadb-5-5-66-release-notes/), [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10-3-19-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10-2-28-release-notes/), [MariaDB 10.1.42](https://mariadb.com/kb/en/mariadb-10-1-42-release-notes/)
* [CVE-2020-2760](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2760): [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10-3-23-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10-2-32-release-notes/)
* [CVE-2020-2752](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2752): [MariaDB Connector/C 3.1.8](../mcc-318-rn/index), [MariaDB 5.5.68](https://mariadb.com/kb/en/mariadb-5-5-68-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10-3-23-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10-2-32-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10-1-45-release-notes/)
* [CVE-2020-2574](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2574): [MariaDB Connector/C 3.1.7](../mcc-317-rn/index), [MariaDB 5.5.67](https://mariadb.com/kb/en/mariadb-5-5-67-release-notes/), [MariaDB 10.4.12](https://mariadb.com/kb/en/mariadb-10-4-12-release-notes/), [MariaDB 10.3.22](https://mariadb.com/kb/en/mariadb-10-3-22-release-notes/), [MariaDB 10.2.31](https://mariadb.com/kb/en/mariadb-10-2-31-release-notes/), [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10-1-44-release-notes/)
* [CVE-2020-15180](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15180): [MariaDB 10.5.6](https://mariadb.com/kb/en/mariadb-10-5-6-release-notes/), [MariaDB 10.4.15](https://mariadb.com/kb/en/mariadb-10-4-15-release-notes/), [MariaDB 10.3.25](../mdb-10325-rn/index), [MariaDB 10.2.34](https://mariadb.com/kb/en/mariadb-10-2-34-release-notes/), [MariaDB 10.1.47](https://mariadb.com/kb/en/mariadb-10-1-47-release-notes/)
* [CVE-2020-14812](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14812): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/), [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10-1-48-release-notes/)
* [CVE-2020-14789](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14789): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/)
* [CVE-2020-14776](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14776): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/)
* [CVE-2020-14765](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14765): [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-10-5-7-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10-4-16-release-notes/), [MariaDB 10.3.26](../mdb-10326-rn/index), [MariaDB 10.2.35](https://mariadb.com/kb/en/mariadb-10-2-35-release-notes/), [MariaDB 10.1.48](https://mariadb.com/kb/en/mariadb-10-1-48-release-notes/)
* [CVE-2020-14550](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14550): [MariaDB Connector/C 3.0.5](../mcc-305-rn/index), [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2020-13249](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-13249): [MariaDB Connector/C 3.1.8](../mcc-318-rn/index), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10-4-13-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10-3-23-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10-2-32-release-notes/)
* [CVE-2019-2974](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2974): [MariaDB 5.5.66](https://mariadb.com/kb/en/mariadb-5-5-66-release-notes/), [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10-3-19-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10-2-28-release-notes/), [MariaDB 10.1.42](https://mariadb.com/kb/en/mariadb-10-1-42-release-notes/)
* [CVE-2019-2938](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2938): [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-10-4-9-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10-3-19-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10-2-28-release-notes/)
* [CVE-2019-2805](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2805): [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2019-2758](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2758): [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/)
* [CVE-2019-2740](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2740): [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2019-2739](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2739): [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2019-2737](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2737): [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5-5-65-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-10-4-7-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10-3-17-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10-2-26-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10-1-41-release-notes/)
* [CVE-2019-2628](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2628): [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-10-4-5-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10-3-15-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10-2-24-release-notes/)
* [CVE-2019-2627](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2627): [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5-5-64-release-notes/), [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-10-4-5-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10-3-15-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10-2-24-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10-1-39-release-notes/)
* [CVE-2019-2614](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2614): [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5-5-64-release-notes/), [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-10-4-5-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10-3-15-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10-2-24-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10-1-39-release-notes/)
* [CVE-2019-2537](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2537): [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10-3-13-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10-2-22-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10-1-38-release-notes/), [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10-0-38-release-notes/)
* [CVE-2019-2529](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2529): [MariaDB 5.5.63](https://mariadb.com/kb/en/mariadb-5-5-63-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10-1-38-release-notes/), [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10-0-38-release-notes/)
* [CVE-2019-2510](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2510): [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10-3-13-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10-2-22-release-notes/)
* [CVE-2019-2503](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2503): [MariaDB 5.5.62](https://mariadb.com/kb/en/mariadb-5-5-62-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10-3-10-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10-2-18-release-notes/), [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10-1-36-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2019-2481](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2481): [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5-5-37-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2019-2455](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2455): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-3284](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3284): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3282](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3282): [MariaDB 5.5.62](https://mariadb.com/kb/en/mariadb-5-5-62-release-notes/), [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2018-3277](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3277): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3251](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3251): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2018-3200](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3200): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3185](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3185): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3174](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3174): [MariaDB 5.5.62](https://mariadb.com/kb/en/mariadb-5-5-62-release-notes/), [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2018-3173](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3173): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3162](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3162): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/)
* [CVE-2018-3156](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3156): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2018-3143](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3143): [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2018-3133](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3133): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.12](https://mariadb.com/kb/en/mariadb-10-2-12-release-notes/), [MariaDB 10.1.30](https://mariadb.com/kb/en/mariadb-10-1-30-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-3081](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3081): [MariaDB Connector/C 3.0.5](../mcc-305-rn/index), [MariaDB Connector/C 2.3.7](../mcc-237-rn/index) [[2](../mcc-237-cl/index)], [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-3066](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3066): [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.3.9](../mdb-1039-rn/index), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10-2-17-release-notes/), [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10-1-35-release-notes/), [MariaDB 10.0.36](https://mariadb.com/kb/en/mariadb-10-0-36-release-notes/)
* [CVE-2018-3064](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3064): [MariaDB 10.3.9](../mdb-1039-rn/index), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10-2-17-release-notes/), [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10-1-35-release-notes/), [MariaDB 10.0.36](https://mariadb.com/kb/en/mariadb-10-0-36-release-notes/)
* [CVE-2018-3063](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3063): [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.3.9](../mdb-1039-rn/index), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10-2-17-release-notes/), [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10-1-35-release-notes/), [MariaDB 10.0.36](https://mariadb.com/kb/en/mariadb-10-0-36-release-notes/)
* [CVE-2018-3060](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3060): [MariaDB 10.3.9](../mdb-1039-rn/index), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10-2-17-release-notes/)
* [CVE-2018-3058](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3058): [MariaDB 5.5.61](https://mariadb.com/kb/en/mariadb-5-5-61-release-notes/), [MariaDB 10.3.9](../mdb-1039-rn/index), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10-2-17-release-notes/), [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10-1-35-release-notes/), [MariaDB 10.0.36](https://mariadb.com/kb/en/mariadb-10-0-36-release-notes/)
* [CVE-2018-2819](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2819): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2817](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2817): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2813](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2813): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2810](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2810): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/)
* [CVE-2018-2787](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2787): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2786](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2786): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/)
* [CVE-2018-2784](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2784): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2782](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2782): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2781](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2781): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2777](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2777): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/)
* [CVE-2018-2771](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2771): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2767](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2767): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2766](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2766): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2761](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2761): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2759](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2759): [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/)
* [CVE-2018-2755](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2755): [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5-5-60-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10-2-15-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10-1-33-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10-0-35-release-notes/)
* [CVE-2018-2668](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2668): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-2665](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2665): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-2640](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2640): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-2622](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2622): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-2612](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2612): [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-2562](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2562): [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5-5-59-release-notes/), [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10-2-13-release-notes/), [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10-1-31-release-notes/), [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10-0-34-release-notes/)
* [CVE-2018-25032](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-25032): [MariaDB Connector/C 3.3.1](../mcc-331-rn/index), [MariaDB Connector/C 3.2.7](../mcc-327-rn/index), [MariaDB Connector/C 3.1.17](../mcc-3117-rn/index), [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-10-9-2-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-10-8-4-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-10-7-5-release-notes/), [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-10-6-9-release-notes/), [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10-5-17-release-notes/), [MariaDB 10.4.26](https://mariadb.com/kb/en/mariadb-10-4-26-release-notes/), [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10-3-36-release-notes/)
* [CVE-2017-3653](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3653): [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5-5-57-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-3651](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3651): [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5-5-53-release-notes/), [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10-1-19-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2017-3641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3641): [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5-5-57-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-3636](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3636): [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5-5-57-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-3600](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3600): [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5-5-53-release-notes/), [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10-1-19-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2017-3464](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3464): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-10-2-6-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10-1-23-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10-0-31-release-notes/)
* [CVE-2017-3456](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3456): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-10-2-6-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10-1-23-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10-0-31-release-notes/)
* [CVE-2017-3453](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3453): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-10-2-6-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10-1-23-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10-0-31-release-notes/)
* [CVE-2017-3318](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3318): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3317](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3317): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3313](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3313): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-10-2-5-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10-1-22-release-notes/), [MariaDB 10.0.30](https://mariadb.com/kb/en/mariadb-10-0-30-release-notes/)
* [CVE-2017-3312](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3312): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3309](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3309): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-10-2-6-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10-1-23-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10-0-31-release-notes/)
* [CVE-2017-3308](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3308): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-10-2-6-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10-1-23-release-notes/), [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10-0-31-release-notes/)
* [CVE-2017-3302](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3302): [MariaDB 5.5.55](https://mariadb.com/kb/en/mariadb-5-5-55-release-notes/), [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-10-2-5-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10-1-22-release-notes/), [MariaDB 10.0.30](https://mariadb.com/kb/en/mariadb-10-0-30-release-notes/)
* [CVE-2017-3291](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3291): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3265](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3265): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3258](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3258): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3257](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3257): [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3244](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3244): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3243](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3243): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-3238](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3238): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2017-15365](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15365): [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10-2-10-release-notes/), [MariaDB 10.1.30](https://mariadb.com/kb/en/mariadb-10-1-30-release-notes/)
* [CVE-2017-10384](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10384): [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5-5-57-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-10379](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10379): [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5-5-57-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-10378](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10378): [MariaDB 5.5.58](https://mariadb.com/kb/en/mariadb-5-5-58-release-notes/), [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10-2-10-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10-1-29-release-notes/), [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10-0-33-release-notes/)
* [CVE-2017-10365](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10365): [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/)
* [CVE-2017-10320](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10320): [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/)
* [CVE-2017-10286](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10286): [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-10-2-8-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10-1-26-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10-0-32-release-notes/)
* [CVE-2017-10268](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10268): [MariaDB 5.5.58](https://mariadb.com/kb/en/mariadb-5-5-58-release-notes/), [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10-2-10-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10-1-29-release-notes/), [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10-0-33-release-notes/)
* [CVE-2016-9843](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9843): [MariaDB 5.5.62](https://mariadb.com/kb/en/mariadb-5-5-62-release-notes/), [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10-3-11-release-notes/), [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10-2-19-release-notes/), [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10-1-37-release-notes/), [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10-0-37-release-notes/)
* [CVE-2016-8283](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8283): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-7440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-7440): [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5-5-53-release-notes/), [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10-1-19-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-6664](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6664): [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5-5-54-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10-1-21-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10-0-29-release-notes/)
* [CVE-2016-6663](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6663): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-6662](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6662): [MariaDB 5.5.51](https://mariadb.com/kb/en/mariadb-5-5-51-release-notes/), [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10-1-17-release-notes/), [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10-0-27-release-notes/)
* [CVE-2016-5630](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5630): [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10-0-27-release-notes/)
* [CVE-2016-5629](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5629): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5626](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5626): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5624](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5624): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5616](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5616): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5612](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5612): [MariaDB 5.5.51](https://mariadb.com/kb/en/mariadb-5-5-51-release-notes/), [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10-0-27-release-notes/)
* [CVE-2016-5584](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5584): [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5-5-53-release-notes/), [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10-1-19-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5483](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5483): [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5-5-53-release-notes/), [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10-1-19-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-5444](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5444): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-5440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5440): [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5-5-50-release-notes/), [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10-1-15-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10-0-26-release-notes/)
* [CVE-2016-3615](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3615): [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5-5-50-release-notes/), [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10-1-15-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10-0-26-release-notes/)
* [CVE-2016-3521](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3521): [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5-5-50-release-notes/), [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10-1-15-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10-0-26-release-notes/)
* [CVE-2016-3492](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3492): [MariaDB 5.5.52](https://mariadb.com/kb/en/mariadb-5-5-52-release-notes/), [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10-1-18-release-notes/), [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10-0-28-release-notes/)
* [CVE-2016-3477](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3477): [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5-5-50-release-notes/), [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10-1-15-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10-0-26-release-notes/)
* [CVE-2016-3471](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3471): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-10-1-9-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2016-3459](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3459): [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-3452](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3452): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-2047](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2047): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0668](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0668): [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0666](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0666): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-0655](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0655): [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-0651](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0651): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0650](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0650): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0649](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0649): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0648](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0648): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-0647](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0647): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-0646](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0646): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0644](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0644): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0643](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0643): [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5-5-49-release-notes/), [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10-1-14-release-notes/), [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10-0-25-release-notes/)
* [CVE-2016-0642](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0642): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0641): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0640](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0640): [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5-5-48-release-notes/), [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10-1-12-release-notes/), [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10-0-24-release-notes/)
* [CVE-2016-0616](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0616): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0610](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0610): [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-10-1-9-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2016-0609](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0609): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0608](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0608): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0606](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0606): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0600](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0600): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0598](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0598): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0597](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0597): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0596](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0596): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0546](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0546): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0505](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0505): [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5-5-47-release-notes/), [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10-1-10-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10-0-23-release-notes/)
* [CVE-2016-0502](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0502): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2015-7744](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7744): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-10-1-9-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4913](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4913): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4895](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4895): [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10-0-21-release-notes/)
* [CVE-2015-4879](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4879): [MariaDB 5.5.45](https://mariadb.com/kb/en/mariadb-5-5-45-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10-0-21-release-notes/)
* [CVE-2015-4870](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4870): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4866](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4866): [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-4864](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4864): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-4861](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4861): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4858](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4858): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4836](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4836): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4830](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4830): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4826](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4826): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4819](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4819): [MariaDB 5.5.45](https://mariadb.com/kb/en/mariadb-5-5-45-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10-0-21-release-notes/)
* [CVE-2015-4816](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4816): [MariaDB 5.5.45](https://mariadb.com/kb/en/mariadb-5-5-45-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10-0-21-release-notes/)
* [CVE-2015-4815](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4815): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4807](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4807): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4802](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4802): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4792](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4792): [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5-5-46-release-notes/), [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-10-1-8-release-notes/), [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10-0-22-release-notes/)
* [CVE-2015-4757](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4757): [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5-5-43-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-4752](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4752): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-3152](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3152): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-2648](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2648): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-2643](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2643): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-2620](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2620): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-2582](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2582): [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5-5-44-release-notes/), [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10-0-20-release-notes/)
* [CVE-2015-2573](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2573): [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5-5-42-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10-0-17-release-notes/)
* [CVE-2015-2571](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2571): [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5-5-43-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-2568](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2568): [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5-5-42-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10-0-17-release-notes/)
* [CVE-2015-2326](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2326): [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-2325](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2325): [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-0505](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0505): [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5-5-43-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-0501](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0501): [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5-5-43-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-0499](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0499): [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5-5-43-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2015-0441](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0441): [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5-5-42-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10-0-17-release-notes/)
* [CVE-2015-0433](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0433): [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5-5-42-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10-0-17-release-notes/)
* [CVE-2015-0432](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0432): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2015-0411](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0411): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2015-0391](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0391): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2015-0382](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0382): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2015-0381](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0381): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2015-0374](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0374): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2014-8964](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-8964): [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10-0-18-release-notes/)
* [CVE-2014-6568](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6568): [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5-5-41-release-notes/), [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10-0-16-release-notes/)
* [CVE-2014-6564](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6564): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6559](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6559): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6555](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6555): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6551](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6551): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6530](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6530): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6520](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6520): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6507](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6507): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6505](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6505): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6500](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6500): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6496](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6496): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6495](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6495): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6494](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6494): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6491](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6491): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6489](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6489): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6484): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6478](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6478): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6474](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6474): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-6469](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6469): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6464](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6464): [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5-5-40-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10-0-15-release-notes/)
* [CVE-2014-6463](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6463): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-4287](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4287): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-4274](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4274): [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5-5-39-release-notes/), [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-4260](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4260): [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5-5-38-release-notes/), [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10-0-12-release-notes/)
* [CVE-2014-4258](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4258): [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5-5-38-release-notes/), [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10-0-12-release-notes/)
* [CVE-2014-4243](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4243): [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5-5-36-release-notes/), [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-10-0-9-release-notes/)
* [CVE-2014-4207](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4207): [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5-5-38-release-notes/), [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10-0-12-release-notes/)
* [CVE-2014-3470](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3470): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-2494](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2494): [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5-5-38-release-notes/), [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10-0-12-release-notes/)
* [CVE-2014-2440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2440): [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5-5-37-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2014-2438](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2438): [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5-5-36-release-notes/), [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-10-0-9-release-notes/)
* [CVE-2014-2436](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2436): [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5-5-37-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2014-2432](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2432): [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5-5-36-release-notes/), [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-10-0-9-release-notes/)
* [CVE-2014-2431](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2431): [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5-5-37-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2014-2430](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2430): [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5-5-37-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10-0-11-release-notes/)
* [CVE-2014-2419](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2419): [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5-5-36-release-notes/), [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-10-0-9-release-notes/)
* [CVE-2014-0437](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0437): [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5-5-35-release-notes/), [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-10-0-8-release-notes/)
* [CVE-2014-0420](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0420): [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5-5-35-release-notes/), [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-10-0-8-release-notes/)
* [CVE-2014-0412](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0412): [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5-5-35-release-notes/), [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-10-0-8-release-notes/)
* [CVE-2014-0402](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0402): [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5-5-34-release-notes/), [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-10-0-7-release-notes/)
* [CVE-2014-0401](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0401): [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5-5-35-release-notes/), [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-10-0-8-release-notes/)
* [CVE-2014-0393](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0393): [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5-5-34-release-notes/), [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-10-0-7-release-notes/)
* [CVE-2014-0386](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0386): [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5-5-34-release-notes/), [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-10-0-7-release-notes/)
* [CVE-2014-0384](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0384): [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5-5-36-release-notes/), [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-10-0-9-release-notes/)
* [CVE-2014-0224](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-0221](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0221): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-0198](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0198): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2014-0195](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0195): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2013-5908](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5908): [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5-5-35-release-notes/), [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-10-0-8-release-notes/)
* [CVE-2013-5891](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5891): [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5-5-34-release-notes/), [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-10-0-7-release-notes/)
* [CVE-2013-5807](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5807): [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5-5-33-release-notes/), [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-10-0-5-release-notes/)
* [CVE-2013-3839](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3839): [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5-5-33-release-notes/), [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-10-0-5-release-notes/)
* [CVE-2013-3812](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3812): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-3809](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3809): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-3808](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3808): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-3805](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3805): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-3804](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3804): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-3802](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3802): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-3801](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3801): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-3794](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3794): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-3793](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3793): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-3783](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3783): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-2392](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2392): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-2391](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2391): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-2389](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2389): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-2378](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2378): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-2376](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2376): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-2375](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2375): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-1861](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1861): [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5-5-32-release-notes/), [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-10-0-4-release-notes/)
* [CVE-2013-1555](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1555): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1552](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1552): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1548](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1548): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2013-1544](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1544): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-1532](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1532): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-1531](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1531): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-1526](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1526): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1523](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1523): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1521](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1521): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1512](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1512): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1511](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1511): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-1506](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1506): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2013-1502](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1502): [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5-5-31-release-notes/), [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-10-0-3-release-notes/)
* [CVE-2013-0389](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0389): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0386](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0386): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0385](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0385): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0384](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0384): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0383](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0383): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0375](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0375): [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/)
* [CVE-2013-0371](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0371): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0368](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0368): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2013-0367](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0367): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5627](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5627): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-5-29-changelog/)], [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-3-12-changelog/)], [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-2-14-changelog/)], [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5615](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5615): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-5-29-changelog/)], [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-3-12-changelog/)], [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-2-14-changelog/)], [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5614](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5614): [MariaDB 5.5.30](https://mariadb.com/kb/en/mariadb-5-5-30-release-notes/), [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-10-0-2-release-notes/)
* [CVE-2012-5612](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5612): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-5-29-changelog/)], [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5611](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5611): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5-5-28a-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.3.11](https://mariadb.com/kb/en/mariadb-5-3-11-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.2.13](https://mariadb.com/kb/en/mariadb-5-2-13-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5096](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5096): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-5060](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-5060): [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5-5-28-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-4414](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-4414): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-5-27-changelog/)], [MariaDB 5.3.8](https://mariadb.com/kb/en/mariadb-5-3-8-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-3-8-changelog/)], [MariaDB 5.2.13](https://mariadb.com/kb/en/mariadb-5-2-13-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-2-13-changelog/)], [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-5-1-66-changelog/)], [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-10-0-0-release-notes/) [[2](https://mariadb.com/kb/en/mariadb-10-0-0-changelog/)]
* [CVE-2012-3197](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3197): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3180](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3180): [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5-5-28-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3177](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3177): [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5-5-28-release-notes/), [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3173](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3173): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3167](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3167): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3166](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3166): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3163](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3163): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3160](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3160): [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5-5-28-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3158](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3158): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-3150](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3150): [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5-5-27-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-2750](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2750): [MariaDB 5.5.23](https://mariadb.com/kb/en/mariadb-5-5-23-release-notes/)
* [CVE-2012-1757](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1757): [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5-5-24-release-notes/)
* [CVE-2012-1756](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1756): [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5-5-24-release-notes/)
* [CVE-2012-1735](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1735): [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5-5-24-release-notes/)
* [CVE-2012-1734](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1734): [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5-5-24-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-1705](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1705): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-1703](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1703): [MariaDB 5.5.22](https://mariadb.com/kb/en/mariadb-5-5-22-release-notes/), [MariaDB 5.1.62](https://mariadb.com/kb/en/mariadb-5-1-62-release-notes/)
* [CVE-2012-1702](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1702): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-1697](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1697): [MariaDB 5.5.22](https://mariadb.com/kb/en/mariadb-5-5-22-release-notes/)
* [CVE-2012-1690](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1690): [MariaDB 5.5.22](https://mariadb.com/kb/en/mariadb-5-5-22-release-notes/), [MariaDB 5.1.62](https://mariadb.com/kb/en/mariadb-5-1-62-release-notes/)
* [CVE-2012-1689](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1689): [MariaDB 5.5.23](https://mariadb.com/kb/en/mariadb-5-5-23-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2012-1688](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1688): [MariaDB 5.5.22](https://mariadb.com/kb/en/mariadb-5-5-22-release-notes/), [MariaDB 5.1.62](https://mariadb.com/kb/en/mariadb-5-1-62-release-notes/)
* [CVE-2012-0578](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0578): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-0574](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0574): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-0572](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0572): [MariaDB 5.5.29](https://mariadb.com/kb/en/mariadb-5-5-29-release-notes/), [MariaDB 5.3.12](https://mariadb.com/kb/en/mariadb-5-3-12-release-notes/), [MariaDB 5.2.14](https://mariadb.com/kb/en/mariadb-5-2-14-release-notes/), [MariaDB 5.1.67](https://mariadb.com/kb/en/mariadb-5-1-67-release-notes/), [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-10-0-1-release-notes/)
* [CVE-2012-0540](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0540): [MariaDB 5.5.24](https://mariadb.com/kb/en/mariadb-5-5-24-release-notes/), [MariaDB 5.1.66](https://mariadb.com/kb/en/mariadb-5-1-66-release-notes/)
* [CVE-2010-5298](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-5298): [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10-0-13-release-notes/)
* [CVE-2009-4484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-4484): [MariaDB 5.1.42](https://mariadb.com/kb/en/mariadb-5-1-42-changelog/)
* [CVE-2005-0004](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-0004): [MariaDB 5.5.66](https://mariadb.com/kb/en/mariadb-5-5-66-changelog/)
 ### CVEs without specific version numbers:

 The following CVEs were fixed in [MariaDB 5.1](../what-is-mariadb-51/index) and/or [MariaDB 5.5](../what-is-mariadb-55/index) as indicated, but the fix is not tied to a specific MariaDB version.

 * [CVE-2012-0113](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0113): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2011-2262](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2262): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0116](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0116): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0118](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0118): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0496](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0496): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0087](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0087): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.1](../what-is-mariadb-51/index)
* [CVE-2012-0101](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0101): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.1](../what-is-mariadb-51/index)
* [CVE-2012-0102](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0102): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.1](../what-is-mariadb-51/index)
* [CVE-2012-0115](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0115): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0119](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0119): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0120](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0120): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0484): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0485](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0485): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0486](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0486): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0487](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0487): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0488](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0488): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0489](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0489): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0490](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0490): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0491](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0491): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0495](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0495): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0112](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0112): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0117](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0117): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0114](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0114): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0492](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0492): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0493](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0493): [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0075](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0075): [MariaDB 5.1](../what-is-mariadb-51/index), [MariaDB 5.5](../what-is-mariadb-55/index)
* [CVE-2012-0494](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0494): [MariaDB 5.5](../what-is-mariadb-55/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cve/>

Catalogs
=========

   Catalogs are an upcoming feature intended primarily for Cloud Service Providers with many customers, each having many MariaDB Server users and databases.

 Catalogs will permit several unrelated users or customers to share a single MariaDB Server instance.

  

| Title | Description |
| --- | --- |
|  [Catalogs Overview](../catalogs-overview/index) |  Catalogs offer multi-tenancy.  |
|  [Starting with Catalogs](../starting-with-catalogs/index) |  Installing MariaDB with catalogs and adding new catalogs.  |
|  [Catalog Status Variables](../catalog-status-variables/index) |  With catalogs enabled, status information is collected for the whole server...  |
|  [DROP CATALOG](../drop-catalog/index) |  Deletes a catalog.  |
|  [USE CATALOG](../use-catalog/index) |  Changes to another catalog.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/catalogs/>

Account Locking
===============

    
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**Account locking was introduced in [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

  ### Description

 Account locking permits privileged administrators to lock/unlock user accounts. No new client connections will be permitted if an account is locked (existing connections are not affected).

 User accounts can be locked at creation, with the [CREATE USER](../create-user/index) statement, or modified after creation with the [ALTER USER](../alter-user/index) statement. For example:

 
```
CREATE USER 'lorin'@'localhost' ACCOUNT LOCK;

```

or

 
```
ALTER USER 'marijn'@'localhost' ACCOUNT LOCK;

```

The server will return an `ER_ACCOUNT_HAS_BEEN_LOCKED` error when locked users attempt to connect:

 
```
mysql -ulorin
  ERROR 4151 (HY000): Access denied, this account is locked

```

The [ALTER USER](../alter-user/index) statement is also used to unlock a user:

 
```
ALTER USER 'lorin'@'localhost' ACCOUNT UNLOCK;

```

The [SHOW CREATE USER](../show-create-user/index) statement will show whether the account is locked:

 
```
SHOW CREATE USER 'marijn'@'localhost';
+-----------------------------------------------+
| CREATE USER for marijn@localhost              |
+-----------------------------------------------+
| CREATE USER 'marijn'@'localhost' ACCOUNT LOCK |
+-----------------------------------------------+

```

as well as querying the [mysql.global\_priv table](../mysqlglobal_priv-table/index):

 
```
SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM mysql.global_priv 
  WHERE user='marijn';
+--------------------------------------------------------------------------------------+
| CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv))                                 |
+--------------------------------------------------------------------------------------+
| marijn@localhost => {
    "access": 0,
    "plugin": "mysql_native_password",
    "authentication_string": "",
    "account_locked": true,
    "password_last_changed": 1558017158
} |
+--------------------------------------------------------------------------------------+

```

See Also
--------

 * [Account Locking and Password Expiry](https://www.youtube.com/watch?v=AWM_fWZ3XIw) video tutorial

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/account-locking/>

Authentication from MariaDB 10.4
================================

    
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**[MariaDB 10.4](../what-is-mariadb-104/index) introduced a number of changes to the authentication process, intended to make things easier and more intuitive.

  Overview
--------

 There are four **new main features in 10.4** relating to authentication:

 * It is possible to use more than one [authentication plugin](../authentication-plugins/index) for each user account. For example, this can be useful to slowly migrate users to the more secure [ed25519](../authentication-plugin-ed25519/index) authentication plugin over time, while allowing the old [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin as an alternative for the transitional period.
* The `root@localhost` user account created by [mariadb-install-db](../mariadb-install-db/index) is created with the ability to use two [authentication plugins](../authentication-plugins/index).
	+ First, it is configured to try to use the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin. This allows the `root@localhost` user to login without a password via the local Unix socket file defined by the [socket](../server-system-variables/index#socket) system variable, as long as the login is attempted from a process owned by the operating system `root` user account.
	+ Second, if authentication fails with the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, then it is configured to try to use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin. However, an invalid password is initially set, so in order to authenticate this way, a password must be set with [SET PASSWORD](../set-password/index).
	+ However, just using the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin may be fine for many users, and it is very secure. You may want to try going without password authentication to see how well it works for you. Remember, the best way to keep your password safe is not to have one!
* All user accounts, passwords, and global privileges are now stored in the [mysql.global\_priv](../mysqlglobal_priv-table/index) table. The [mysql.user](../mysqluser-table/index) table still exists and has exactly the same set of columns as before, but it’s now a view that references the [mysql.global\_priv](../mysqlglobal_priv-table/index) table. Tools that analyze the [mysql.user](../mysqluser-table/index) table should continue to work as before. From [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), the dedicated `mariadb.sys` user is created as the definer of this view. Previously `root` was the definer, which resulted in privilege problems when this username was changed.
* [MariaDB 10.4](../what-is-mariadb-104/index) adds supports for [User Password Expiry](../user-password-expiry/index), which is not active by default.

 Description
-----------

 As a result of the above changes, the open-for-everyone all-powerful root account is finally gone. And installation scripts will no longer demand that you “PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !”, because the root account is securely created automatically.

 Two all-powerful accounts are created by default — root and the OS user that owns the data directory, typically mysql. They are created as:

 
```
CREATE USER root@localhost IDENTIFIED VIA unix_socket OR mysql_native_password USING 'invalid'
CREATE USER mysql@localhost IDENTIFIED VIA unix_socket OR mysql_native_password USING 'invalid'

```

Using unix\_socket means that if you are the system root user, you can login as root@locahost without a password. This technique was pioneered by Otto Kekäläinen in Debian MariaDB packages and has been successfully [used in Debian](../differences-in-mariadb-in-debian-and-ubuntu/index) since as early as [MariaDB 10.0](../what-is-mariadb-100/index). 

 It is based on a simple fact that asking the system root for a password adds no extra security — root has full access to all the data files and all process memory anyway. But not asking for a password means, there is no root password to forget (no need for the numerous tutorials on “how to reset MariaDB root password”). And if you want to script some tedious database work, there is no need to store the root password in plain text for the script to use (no need for debian-sys-maint user).

 Still, some users may wish to log in as MariaDB root without using sudo. Hence the old authentication method — conventional MariaDB password — is still available. By default it is disabled (“invalid” is not a valid password hash), but one can set the password with a usual [SET PASSWORD](../set-password/index) statement. And still retain the password-less access via sudo.

 If you install MariaDB locally (say from a tarball), you would not want to use sudo to be able to login. This is why MariaDB creates a second all-powerful user with the same name as a system user that owns the data directory. In local (not system-wide) installations, this will be the user who installed MariaDB — they automatically get convenient password-less root-like access, because they can access all the data files anyway.

 Even if MariaDB is installed system-wide, you may not want to run your database maintenance scripts as system root — now you can run them as system mysql user. And you will know that they will never destroy your entire system, even if you make a typo in a shell script.

 However, seasoned MariaDB DBAs who are used to the old ways do need to make some changes. See the examples below for common tasks. 

 Cookbook
--------

 After installing MariaDB system-wide the first thing you’ve got used to doing is logging in into the unprotected root account and protecting it, that is, setting the root password:

 
```
$ sudo dnf install MariaDB-server
$ mysql -uroot
...
MariaDB> set password = password("XH4VmT3_jt");

```

This is not only unnecessary now, it will simply not work — there is no unprotected root account. To login as root use

 
```
$ sudo dnf install MariaDB-server
$ sudo mysql

```

Note that it implies you are connecting via the unix socket, not tcp. If you happen to have `protocol=tcp` in a system-wide `/etc/my.cnf` file, use `sudo mysql --protocol=socket`.

 After installing MariaDB locally you’ve also used to connect to the unprotected root account using `mysql -uroot`. This will not work either, simply use `mysql` without specifying a username.

 If you've forgotten your root password, no problem — you can still connect using sudo and change the password. And if you've also removed unix\_socket authentication, to restore access do as follows:

 * restart MariaDB with [--skip-grant-tables](../mysqld-options/index#-skip-grant-tables)
* login into the unprotected server
* run [FLUSH PRIVILEGES](../flush/index) (note, before 10.4 this would’ve been the last step, not anymore). This disables `--skip-grant-tables` and allows you to change the stored authentication method
* run [SET PASSWORD](../set-password/index) FOR root@localhost to change the root password.

 To view inside privilege tables, the old mysql.user table still exists. You can select from it as before, although you cannot update it anymore. It doesn’t show alternative authentication plugins and this was one of the reasons for switching to the mysql.global\_priv table — complex authentication rules did not fit into rigid structure of a relational table. You can select from the new table, for example: 

 
```
select concat(user, '@', host, ' => ', json_detailed(priv)) from mysql.global_priv;

```

Reverting to the Previous Authentication Method for root@localhost
------------------------------------------------------------------

 If you don't want the `root@localhost` user account created by [mariadb-install-db](../mariadb-install-db/index) to use [unix\_socket](../authentication-plugin-unix-socket/index) authentication by default, then there are a few ways to revert to the previous [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication method for this user account.

 ### Configuring mariadb-install-db to Revert to the Previous Authentication Method

 One way to revert to the previous [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication method for the `root@localhost` user account is to execute [mariadb-install-db](../mariadb-install-db/index) with a special option. If [mariadb-install-db](../mariadb-install-db/index) is executed while `--auth-root-authentication-method=normal` is specified, then it will create the default user accounts using the default behavior of [MariaDB 10.3](../what-is-mariadb-103/index) and before.

 This means that the `root@localhost` user account will use [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication by default. There are some other differences as well. See [mariadb-install-db: User Accounts Created by Default](../mariadb-install-db/index#user-accounts-created-by-default) for more information.

 For example, the option can be set on the command-line while running [mariadb-install-db](../mariadb-install-db/index):

 
```
mariadb-install-db --user=mysql --datadir=/var/lib/mysql --auth-root-authentication-method=normal

```

The option can also be set in an [option file](../configuring-mariadb-with-option-files/index) in an [option group](../configuring-mariadb-with-option-files/index#option-groups) supported by [mariadb-install-db](../mariadb-install-db/index). For example:

 
```
[mysql_install_db]
auth_root_authentication_method=normal

```

If the option is set in an [option file](../configuring-mariadb-with-option-files/index) and if [mariadb-install-db](../mariadb-install-db/index) is executed, then [mariadb-install-db](../mariadb-install-db/index) will read this option from the [option file](../configuring-mariadb-with-option-files/index), and it will automatically set this option.

 ### Altering the User Account to Revert to the Previous Authentication Method

 If you have already installed MariaDB, and if the `root@localhost` user account is already using [unix\_socket](../authentication-plugin-unix-socket/index) authentication, then you can revert to the old [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication method for the user account by executing the following:

 
```
ALTER USER root@localhost IDENTIFIED VIA mysql_native_password USING PASSWORD("verysecret")

```

See Also
--------

 * [Authentication from MariaDB 10 4 video tutorial](https://www.youtube.com/watch?v=aWFG4uLbimM)
* [Authentication in MariaDB 10.4 — understanding the changes (mariadb.org)](https://mariadb.org/authentication-in-mariadb-10-4/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-from-mariadb-10-4/>

User Password Expiry
====================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**User password expiry was introduced in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

  Password expiry permits administrators to expire user passwords, either manually or automatically. 

 System Variables
----------------

 There are two system variables which affect password expiry: [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime), which determines the amount of time between requiring the user to change their password. `0`, the default, means automatic password expiry is not active.

 The second variable, [disconnect\_on\_expired\_password](../server-system-variables/index#disconnect_on_expired_password) determines whether a client is permitted to connect if their password has expired, or whether they are permitted to connect in sandbox mode, able to perform a limited subset of queries related to resetting the password, in particular [SET PASSWORD](../set-password/index) and [SET](../set/index).

 Setting a Password Expiry Limit for a User
------------------------------------------

 Besides automatic password expiry, as determined by [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime), password expiry times can be set on an individual user basis, overriding the global using the [CREATE USER](../create-user/index) or [ALTER USER](../alter-user/index) statements, for example:

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

```


```
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

```

Limits can be disabled by use of the `NEVER` keyword, for example:

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;

```


```
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;

```

A manually set limit can be restored the system default by use of `DEFAULT`, for example:

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

```


```
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

```

SHOW CREATE USER
----------------

 The [SHOW CREATE USER](../show-create-user/index) statement will display information about the password expiry status of the user. Unlike MySQL, it will not display if the user is unlocked, or if the password expiry is set to default.

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;
CREATE USER 'konstantin'@'localhost' PASSWORD EXPIRE NEVER;
CREATE USER 'amse'@'localhost' PASSWORD EXPIRE DEFAULT;

SHOW CREATE USER 'monty'@'localhost';
+------------------------------------------------------------------+
| CREATE USER for monty@localhost                                  |
+------------------------------------------------------------------+
| CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY |
+------------------------------------------------------------------+

SHOW CREATE USER 'konstantin'@'localhost';
+------------------------------------------------------------+
| CREATE USER for konstantin@localhost                       |
+------------------------------------------------------------+
| CREATE USER 'konstantin'@'localhost' PASSWORD EXPIRE NEVER |
+------------------------------------------------------------+

SHOW CREATE USER 'amse'@'localhost';
+--------------------------------+
| CREATE USER for amse@localhost |
+--------------------------------+
| CREATE USER 'amse'@'localhost' |
+--------------------------------+

```

Checking When Passwords Expire
------------------------------

 The following query can be used to check when the current passwords expire for all users:

 
```
WITH password_expiration_info AS (
  SELECT User, Host,
  IF(
   IFNULL(JSON_EXTRACT(Priv, '$.password_lifetime'), -1) = -1,
   @@global.default_password_lifetime,
   JSON_EXTRACT(Priv, '$.password_lifetime')
  ) AS password_lifetime,
  JSON_EXTRACT(Priv, '$.password_last_changed') AS password_last_changed
  FROM mysql.global_priv
)
SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
  FROM_UNIXTIME(
   pei.password_last_changed +
   (pei.password_lifetime * 60 * 60 * 24)
  ) AS password_expiration_datetime
  FROM password_expiration_info pei
  WHERE pei.password_lifetime != 0
   AND pei.password_last_changed IS NOT NULL
UNION
SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changed) AS password_last_changed_datetime,
  0 AS password_expiration_datetime
  FROM password_expiration_info pei
  WHERE pei.password_lifetime = 0
   OR pei.password_last_changed IS NULL;

```

--connect-expired-password Client Option
----------------------------------------

 The [mariadb client](../mariadb-command-line-client/index) `--connect-expired-password` option notifies the server that the client is prepared to handle expired password sandbox mode (even if the `--batch` option was specified).

 See Also
--------

 * [Account Locking and Password Expiry](https://www.youtube.com/watch?v=AWM_fWZ3XIw) video tutorial

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-password-expiry/>

Addition Operator (+)
=====================

    Syntax
------

 
```
+

```
 Description
-----------

 Addition.

 If both operands are integers, the result is calculated with [BIGINT](../bigint/index) precision. If either integer is unsigned, the result is also an unsigned integer.

 For real or string operands, the operand with the highest precision determines the result precision.

 Examples
--------

 
```
SELECT 3+5;
+-----+
| 3+5 |
+-----+
|   8 |
+-----+

```

See Also
--------

 * [Type Conversion](../type-conversion/index)
* [Subtraction Operator (-)](../subtraction-operator-/index)
* [Multiplication Operator (\*)](../multiplication-operator/index)
* [Division Operator (/)](../division-operator/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/addition-operator/>

Multiplication Operator (\*)
============================

    Syntax
------

 
```
*

```
 Description
-----------

 Multiplication operator.

 Examples
--------

 
```
SELECT 7*6;
+-----+
| 7*6 |
+-----+
|  42 |
+-----+

SELECT 1234567890*9876543210;
+-----------------------+
| 1234567890*9876543210 |
+-----------------------+
|  -6253480962446024716 |
+-----------------------+

SELECT 18014398509481984*18014398509481984.0;
+---------------------------------------+
| 18014398509481984*18014398509481984.0 |
+---------------------------------------+
|   324518553658426726783156020576256.0 |
+---------------------------------------+

SELECT 18014398509481984*18014398509481984;
+-------------------------------------+
| 18014398509481984*18014398509481984 |
+-------------------------------------+
|                                   0 |
+-------------------------------------+

```

See Also
--------

 * [Type Conversion](../type-conversion/index)
* [Addition Operator (+)](../addition-operator/index)
* [Subtraction Operator (-)](../subtraction-operator-/index)
* [Division Operator (/)](../division-operator/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multiplication-operator/>

Modulo Operator (%)
===================

    Syntax
------

 
```
N % M

```

Description
-----------

 Modulo operator. Returns the remainder of `N` divided by `M`. See also [MOD](../mod/index).

 Examples
--------

 
```
SELECT 1042 % 50;
+-----------+
| 1042 % 50 |
+-----------+
|        42 |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/modulo-operator/>

<=
==

    Syntax
------

 
```
<=

```
 Description
-----------

 Less than or equal operator. Evaluates both SQL expressions and returns 1 if the left value is less than or equal to the right value and 0 if it is not, or `NULL` if either expression is NULL. If the expressions return different data types, (for instance, a number and a string), performs type conversion.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) <= (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b <= t2.y))
FROM t1 INNER JOIN t2;

```

Examples
--------

 
```
SELECT 0.1 <= 2;
+----------+
| 0.1 <= 2 |
+----------+
|        1 |
+----------+

```


```
SELECT 'a'<='A';
+----------+
| 'a'<='A' |
+----------+
|        1 |
+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/less-than-or-equal/>

<=>
===

    Syntax
------

 
```
<=>

```

Description
-----------

 NULL-safe equal operator. It performs an equality comparison like the [= operator](../equal/index), but returns 1 rather than NULL if both operands are NULL, and 0 rather than NULL if one operand is NULL.

 `a <=> b` is equivalent to `a = b OR (a IS NULL AND b IS NULL)`.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) <=> (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a <=> t2.x) AND (t1.b <=> t2.y)
FROM t1 INNER JOIN t2;

```

See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 Examples
--------

 
```
SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
+---------+---------------+------------+
| 1 <=> 1 | NULL <=> NULL | 1 <=> NULL |
+---------+---------------+------------+
|       1 |             1 |          0 |
+---------+---------------+------------+

SELECT 1 = 1, NULL = NULL, 1 = NULL;
+-------+-------------+----------+
| 1 = 1 | NULL = NULL | 1 = NULL |
+-------+-------------+----------+
|     1 |        NULL |     NULL |
+-------+-------------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/null-safe-equal/>

Division Operator (/)
=====================

    Syntax
------

 
```
/

```
 Description
-----------

 Division operator. Dividing by zero will return NULL. By default, returns four digits after the decimal. This is determined by the server system variable [div\_precision\_increment](../server-system-variables/index#div_precision_increment) which by default is four. It can be set from 0 to 30.

 Dividing by zero returns `NULL`. If the `ERROR_ON_DIVISION_BY_ZERO` [SQL\_MODE](../sql-mode/index) is used (the default since [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)), a division by zero also produces a warning.

 Examples
--------

 
```
SELECT 4/5;
+--------+
| 4/5    |
+--------+
| 0.8000 |
+--------+

SELECT 300/(2-2);
+-----------+
| 300/(2-2) |
+-----------+
|      NULL |
+-----------+

SELECT 300/7;
+---------+
| 300/7   |
+---------+
| 42.8571 |
+---------+

```

Changing [div\_precision\_increment](../server-system-variables/index#div_precision_increment) for the session from the default of four to six:

 
```
SET div_precision_increment = 6;

SELECT 300/7;
+-----------+
| 300/7     |
+-----------+
| 42.857143 |
+-----------+

SELECT 300/7;
+-----------+
| 300/7     |
+-----------+
| 42.857143 |
+-----------+

```

See Also
--------

 * [Type Conversion](../type-conversion/index)
* [Addition Operator (+)](../addition-operator/index)
* [Subtraction Operator (-)](../subtraction-operator-/index)
* [Multiplication Operator (\*)](../multiplication-operator/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/division-operator/>

=
=

    Syntax
------

 
```
left_expr = right_expr

```
 Description
-----------

 Equal operator. Evaluates both SQL expressions and returns 1 if they are equal, 0 if they are not equal, or `[NULL](../null-values-in-mariadb/index)` if either expression is NULL. If the expressions return different data types (for example, a number and a string), a type conversion is performed.

 When used in row comparisons these two queries are synonymous and return the same results:

 
```
SELECT (t1.a, t1.b) = (t2.x, t2.y) FROM t1 INNER JOIN t2;

SELECT (t1.a = t2.x) AND (t1.b = t2.y) FROM t1 INNER JOIN t2;

```

To perform a NULL-safe comparison, use the `[<=>](../null-safe-equal/index)` operator.

 `=` can also be used as an [assignment operator](../assignment-operators-assignment-operator/index).

 Examples
--------

 
```
SELECT 1 = 0;
+-------+
| 1 = 0 |
+-------+
|     0 |
+-------+

SELECT '0' = 0;
+---------+
| '0' = 0 |
+---------+
|       1 |
+---------+

SELECT '0.0' = 0;
+-----------+
| '0.0' = 0 |
+-----------+
|         1 |
+-----------+

SELECT '0.01' = 0;
+------------+
| '0.01' = 0 |
+------------+
|          0 |
+------------+

SELECT '.01' = 0.01;
+--------------+
| '.01' = 0.01 |
+--------------+
|            1 |
+--------------+

SELECT (5 * 2) = CONCAT('1', '0');
+----------------------------+
| (5 * 2) = CONCAT('1', '0') |
+----------------------------+
|                          1 |
+----------------------------+

SELECT 1 = NULL;
+----------+
| 1 = NULL |
+----------+
|     NULL |
+----------+

SELECT NULL = NULL;
+-------------+
| NULL = NULL |
+-------------+
|        NULL |
+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/equal/>

>
=

    Syntax
------

 
```
>

```
 Description
-----------

 Greater than operator. Evaluates both SQL expressions and returns 1 if the left value is greater than the right value and 0 if it is not, or `NULL` if either expression is NULL. If the expressions return different data types, (for instance, a number and a string), performs type conversion.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) > (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b > t2.y))
FROM t1 INNER JOIN t2;

```

Examples
--------

 
```
SELECT 2 > 2;
+-------+
| 2 > 2 |
+-------+
|     0 |
+-------+

SELECT 'b' > 'a';
+-----------+
| 'b' > 'a' |
+-----------+
|         1 |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/greater-than/>

>=
==

    Syntax
------

 
```
>=

```
 Description
-----------

 Greater than or equal operator. Evaluates both SQL expressions and returns 1 if the left value is greater than or equal to the right value and 0 if it is not, or `NULL` if either expression is NULL. If the expressions return different data types, (for instance, a number and a string), performs type conversion.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) >= (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a > t2.x) OR ((t1.a = t2.x) AND (t1.b >= t2.y))
FROM t1 INNER JOIN t2;

```

Examples
--------

 
```
SELECT 2 >= 2;
+--------+
| 2 >= 2 |
+--------+
|      1 |
+--------+

SELECT 'A' >= 'a';
+------------+
| 'A' >= 'a' |
+------------+
|          1 |
+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/greater-than-or-equal/>

&
=

    Syntax
------

 
```
&

```

Description
-----------

 Bitwise AND. Converts the values to binary and compares bits. Only if both the corresponding bits are 1 is the resulting bit also 1.

 See also [bitwise OR](../bitwise-or/index).

 Examples
--------

 
```
SELECT 2&1;
+-----+
| 2&1 |
+-----+
|   0 |
+-----+

SELECT 3&1;
+-----+
| 3&1 |
+-----+
|   1 |
+-----+

SELECT 29 & 15;
+---------+
| 29 & 15 |
+---------+
|      13 |
+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bitwise_and/>

<<
==

    Syntax
------

 
```
value1 << value2

```

Description
-----------

 Converts a longlong ([BIGINT](../bigint/index)) number (*value1*) to binary and shifts *value2* units to the left.

 Examples
--------

 
```
SELECT 1 << 2;
+--------+
| 1 << 2 |
+--------+
|      4 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/shift-left/>

<
=

    Syntax
------

 
```
<

```
 Description
-----------

 Less than operator. Evaluates both SQL expressions and returns 1 if the left value is less than the right value and 0 if it is not, or `NULL` if either expression is NULL. If the expressions return different data types, (for instance, a number and a string), performs type conversion.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) < (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a < t2.x) OR ((t1.a = t2.x) AND (t1.b < t2.y))
FROM t1 INNER JOIN t2;

```

Examples
--------

 
```
SELECT 2 < 2;
+-------+
| 2 < 2 |
+-------+
|     0 |
+-------+

```

Type conversion:

 
```
SELECT 3<'4';
+-------+
| 3<'4' |
+-------+
|     1 |
+-------+

```

Case insensitivity - see [Character Sets and Collations](../data-types-character-sets-and-collations/index):

 
```
SELECT 'a'<'A';
+---------+
| 'a'<'A' |
+---------+
|       0 |
+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/less-than/>

Not Equal Operator: !=
======================

    Syntax
------

 
```
<>, !=

```
 Description
-----------

 Not equal operator. Evaluates both SQL expressions and returns 1 if they are not equal and 0 if they are equal, or `NULL` if either expression is NULL. If the expressions return different data types, (for instance, a number and a string), performs type conversion.

 When used in row comparisons these two queries return the same results:

 
```
SELECT (t1.a, t1.b) != (t2.x, t2.y) 
FROM t1 INNER JOIN t2;

SELECT (t1.a != t2.x) OR (t1.b != t2.y)
FROM t1 INNER JOIN t2;

```

Examples
--------

 
```
SELECT '.01' <> '0.01';
+-----------------+
| '.01' <> '0.01' |
+-----------------+
|               1 |
+-----------------+

SELECT .01 <> '0.01';
+---------------+
| .01 <> '0.01' |
+---------------+
|             0 |
+---------------+

SELECT 'zapp' <> 'zappp';
+-------------------+
| 'zapp' <> 'zappp' |
+-------------------+
|                 1 |
+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not-equal/>

Subtraction Operator (-)
========================

    Syntax
------

 
```
-

```

Description
-----------

 Subtraction. The operator is also used as the unary minus for changing sign.

 If both operands are integers, the result is calculated with [BIGINT](../bigint/index) precision. If either integer is unsigned, the result is also an unsigned integer, unless the NO\_UNSIGNED\_SUBTRACTION [SQL\_MODE](../sql-mode/index) is enabled, in which case the result is always signed.

 For real or string operands, the operand with the highest precision determines the result precision.

 Examples
--------

 
```
SELECT 96-9;
+------+
| 96-9 |
+------+
|   87 |
+------+

SELECT 15-17;
+-------+
| 15-17 |
+-------+
|    -2 |
+-------+

SELECT 3.66 + 1.333;
+--------------+
| 3.66 + 1.333 |
+--------------+
|        4.993 |
+--------------+

```

Unary minus:

 
```
 SELECT - (3+5);
+---------+
| - (3+5) |
+---------+
|      -8 |
+---------+

```

See Also
--------

 * [Type Conversion](../type-conversion/index)
* [Addition Operator (+)](../addition-operator/index)
* [Multiplication Operator (\*)](../multiplication-operator/index)
* [Division Operator (/)](../division-operator/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subtraction-operator-/>

!
=

    Syntax
------

 
```
NOT, !

```
 Description
-----------

 Logical NOT. Evaluates to 1 if the operand is 0, to 0 if the operand is non-zero, and NOT NULL returns NULL.

 By default, the `!` operator has a [higher precedence](../operator-precedence/index). If the `HIGH_NOT_PRECEDENCE` [SQL\_MODE](../sql-mode/index) flag is set, `NOT` and `!` have the same precedence.

 Examples
--------

 
```
SELECT NOT 10;
+--------+
| NOT 10 |
+--------+
|      0 |
+--------+

SELECT NOT 0;
+-------+
| NOT 0 |
+-------+
|     1 |
+-------+

SELECT NOT NULL;
+----------+
| NOT NULL |
+----------+
|     NULL |
+----------+

SELECT ! (1+1);
+---------+
| ! (1+1) |
+---------+
|       0 |
+---------+

SELECT ! 1+1;
+-------+
| ! 1+1 |
+-------+
|     1 |
+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not/>

XOR
===

    Syntax
------

 
```
XOR

```
 Description
-----------

 XOR stands for eXclusive OR. Returns NULL if either operand is NULL. For non-NULL operands, evaluates to 1 if an odd number of operands is non-zero, otherwise 0 is returned.

 Examples
--------

 
```
SELECT 1 XOR 1;
+---------+
| 1 XOR 1 |
+---------+
|       0 |
+---------+

SELECT 1 XOR 0;
+---------+
| 1 XOR 0 |
+---------+
|       1 |
+---------+

SELECT 1 XOR NULL;
+------------+
| 1 XOR NULL |
+------------+
|       NULL |
+------------+

```

In the following example, the right `1 XOR 1` is evaluated first, and returns `0`. Then, `1 XOR 0` is evaluated, and `1` is returned.

 
```
SELECT 1 XOR 1 XOR 1;
+---------------+
| 1 XOR 1 XOR 1 |
+---------------+
|             1 |
+---------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xor/>

>>
==

    Syntax
------

 
```
value1 >> value2

```

Description
-----------

 Converts a longlong ([BIGINT](../bigint/index)) number (*value1*) to binary and shifts *value2* units to the right.

 Examples
--------

 
```
SELECT 4 >> 2;
+--------+
| 4 >> 2 |
+--------+
|      1 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/shift-right/>

&&
==

    Syntax
------

 
```
AND, &&

```
 Description
-----------

 Logical AND. Evaluates to 1 if all operands are non-zero and not NULL, to 0 if one or more operands are 0, otherwise NULL is returned.

 For this operator, [short-circuit evaluation](../operator-precedence/index#short-circuit-evaluation) can be used.

 Examples
--------

 
```
SELECT 1 && 1;
+--------+
| 1 && 1 |
+--------+
|      1 |
+--------+

SELECT 1 && 0;
+--------+
| 1 && 0 |
+--------+
|      0 |
+--------+

SELECT 1 && NULL;
+-----------+
| 1 && NULL |
+-----------+
|      NULL |
+-----------+

SELECT 0 && NULL;
+-----------+
| 0 && NULL |
+-----------+
|         0 |
+-----------+

SELECT NULL && 0;
+-----------+
| NULL && 0 |
+-----------+
|         0 |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/and/>

^
=

    Syntax
------

 
```
^

```

Description
-----------

 Bitwise XOR. Converts the values to binary and compares bits. If one (and only one) of the corresponding bits is 1 is the resulting bit also 1.

 Examples
--------

 
```
SELECT 1 ^ 1;
+-------+
| 1 ^ 1 |
+-------+
|     0 |
+-------+

SELECT 1 ^ 0;
+-------+
| 1 ^ 0 |
+-------+
|     1 |
+-------+

SELECT 11 ^ 3;
+--------+
| 11 ^ 3 |
+--------+
|      8 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bitwise-xor/>

Assignment Operator (:=)
========================

    Syntax
------

 
```
var_name := expr

```

Description
-----------

 Assignment operator for assigning a value. The value on the right is assigned to the variable on left.

 Unlike the [= operator](../assignment-operators-assignment-operator/index), `:=` can always be used to assign a value to a variable.

 This operator works with both [user-defined variables](../user-defined-variables/index) and [local variables](../declare-variable/index).

 When assigning the same value to several variables, [LAST\_VALUE()](../last_value/index) can be useful.

 Examples
--------

 
```
 SELECT @x := 10;
+----------+
| @x := 10 |
+----------+
|       10 |
+----------+

SELECT @x, @y := @x;
+------+----------+
| @x   | @y := @x |
+------+----------+
|   10 |       10 |
+------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/assignment-operator/>

|
=

    Syntax
------

 
```
|

```

Description
-----------

 Bitwise OR. Converts the values to binary and compares bits. If either of the corresponding bits has a value of 1, the resulting bit is also 1.

 See also [bitwise AND](../bitwise_and/index).

 Examples
--------

 
```
SELECT 2|1;
+-----+
| 2|1 |
+-----+
|   3 |
+-----+

SELECT 29 | 15;
+---------+
| 29 | 15 |
+---------+
|      31 |
+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bitwise-or/>

xtrabackup-v2 SST Method
========================

    
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

  The `xtrabackup-v2` SST method uses the [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) utility for performing SSTs. It is one of the methods that does not block the donor node.

 Note that if you use the `xtrabackup-v2` SST method, then you also need to have [socat](#socat-dependency) installed on the server. This is needed to stream the backup from the donor node to the joiner node.

 Since [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) is a third party product, it may require additional installation and additional configuration. Please refer to [Percona's xtrabackup SST documentation](http://www.percona.com/doc/percona-xtradb-cluster/5.5/manual/xtrabackup_sst.html) for information from the vendor.

 Choosing Percona XtraBackup for SSTs
------------------------------------

 To use the `xtrabackup-v2` SST method, you must set the `[wsrep\_sst\_method=xtrabackup-v2](../galera-cluster-system-variables/index#wsrep_sst_method)` on both the donor and joiner node. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_method='xtrabackup-v2';

```

It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_method = xtrabackup-v2

```

For an SST to work properly, the donor and joiner node must use the same SST method. Therefore, it is recommended to set `[wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method)` to the same value on all nodes, since any node will usually be a donor or joiner node at some point.

 Authentication and Privileges
-----------------------------

 To use the `xtrabackup-v2` SST method, [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) needs to be able to authenticate locally on the donor node, so that it can create a backup to stream to the joiner. You can tell the donor node what username and password to use by setting the `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` system variable. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_auth = 'xtrabackup:mypassword';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = xtrabackup:mypassword

```

Some [authentication plugins](../authentication-plugins/index) do not require a password. For example, the `[unix\_socket](../authentication-plugin-unix-socket/index)` and `[gssapi](../authentication-plugin-gssapi/index)` authentication plugins do not require a password. If you are using a user account that does not require a password in order to log in, then you can just leave the password component of `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` empty. For example:

 
```
[mariadb]
...
wsrep_sst_auth = xtrabackup:

```

The user account that performs the backup for the SST needs to have [the same privileges as Percona XtraBackup](../percona-xtrabackup-overview/index#authentication-and-privileges), which are the `RELOAD` , `PROCESS`, `LOCK TABLES` and `REPLICATION CLIENT` [global privileges](../grant/index#global-privileges). To be safe, you should ensure that these privileges are set on each node in your cluster. [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) connects locally on the donor node to perform the backup, so the following user should be sufficient:

 
```
CREATE USER 'xtrabackup'@'localhost' IDENTIFIED BY 'mypassword';
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'xtrabackup'@'localhost';

```

### Passwordless Authentication - Unix Socket

 It is possible to use the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin for the user account that performs SSTs. This would provide the benefit of not needing to configure a plain-text password in `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`.

 The user account would have to have the same name as the operating system user account that is running the `mysqld` process. On many systems, this is the user account configured as the `[user](../mysqld-options/index#-user)` option, and it tends to default to `mysql`.

 For example, if the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin is already installed, then you could execute the following to create the user account:

 
```
CREATE USER 'mysql'@'localhost' IDENTIFIED VIA unix_socket;
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mysql'@'localhost';

```

And then to configure `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`, you could set the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = mysql:

```

### Passwordless Authentication - GSSAPI

 It is possible to use the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin for the user account that performs SSTs. This would provide the benefit of not needing to configure a plain-text password in `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`.

 The following steps would need to be done beforehand:

 * You need a KDC running [MIT Kerberos](http://web.mit.edu/Kerberos/krb5-1.12/doc/index.html) or [Microsoft Active Directory](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview).
* You will need to [create a keytab file](../authentication-plugin-gssapi/index#creating-a-keytab-file-on-a-unix-server) for the MariaDB server.
* You will need to [install the package](../authentication-plugin-gssapi/index#installing-the-plugins-package) containing the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin.
* You will need to [install the plugin](../authentication-plugin-gssapi/index#installing-the-plugin) in MariaDB, so that the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin is available to use.
* You will need to [configure the plugin](../authentication-plugin-gssapi/index#configuring-the-plugin).
* You will need to [create a user account](../authentication-plugin-gssapi/index#creating-users) that authenticates with the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin, so that the user account can be used for SSTs. This user account will need to correspond with a user account that exists on the backend KDC.

 For example, you could execute the following to create the user account in MariaDB:

 
```
CREATE USER 'xtrabackup'@'localhost' IDENTIFIED VIA gssapi;
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'xtrabackup'@'localhost';

```

And then to configure `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)`, you could set the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = xtrabackup:

```

Choosing a Donor Node
---------------------

 When Percona XtraBackup is used to create the backup for the SST on the donor node, XtraBackup briefly requires a system-wide lock at the end of the backup. This is done with `[FLUSH TABLES WITH READ LOCK](../flush/index)`.

 If a specific node in your cluster is acting as the *primary* node by receiving all of the application's write traffic, then this node should not usually be used as the donor node, because the system-wide lock could interfere with the application. In this case, you can define one or more preferred donor nodes by setting the `[wsrep\_sst\_donor](../galera-cluster-system-variables/index#wsrep_sst_donor)` system variable.

 For example, let's say that we have a 5-node cluster with the nodes `node1`, `node2`, `node3`, `node4`, and `node5`, and let's say that `node1` is acting as the *primary* node.The preferred donor nodes for `node2` could be configured by setting the following in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_donor=node3,node4,node5,

```

The trailing comma tells the server to allow any other node as donor when the preferred donors are not available. Therefore, if `node1` is the only node left in the cluster, the trailing comma allows it to be used as the donor node.

 Socat Dependency
----------------

 During the SST process, the donor node uses [socat](http://www.dest-unreach.org/socat/doc/socat.html) to stream the backup to the joiner node. Then the joiner node prepares the backup before restoring it. The socat utility must be installed on both the donor node and the joiner node in order for this to work. Otherwise, the MariaDB error log will contain an error like:

 
```
WSREP_SST: [ERROR] socat not found in path: /usr/sbin:/sbin:/usr//bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin (20180122 14:55:32.993)

```

### Installing Socat on RHEL/CentOS

 On RHEL/CentOS, `socat` can be installed from the [Extra Packages for Enterprise Linux (EPEL)](https://fedoraproject.org/wiki/EPEL) repository.

 TLS
---

 This SST method supports three different TLS methods. The specific method can be selected by setting the `encrypt` option in the `[sst]` section of the MariaDB configuration file. The options are:

 * TLS using OpenSSL encryption built into `socat` (`encrypt=2`)
* TLS using OpenSSL encryption with Galera-compatible certificates and keys (`encrypt=3`)
* TLS using OpenSSL encryption with MariaDB-compatible certificates and keys (`encrypt=4`)

 Note that `encrypt=1` refers to a TLS encryption method that has been deprecated and removed.

 ### TLS Using OpenSSL Encryption Built into Socat

 To generate keys compatible with this encryption method, you can follow [these directions](http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html).

 For example:

 * First, generate the keys and certificates:

 
```
FILENAME=sst
openssl genrsa -out $FILENAME.key 1024
openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt
cat $FILENAME.key $FILENAME.crt >$FILENAME.pem
chmod 600 $FILENAME.key $FILENAME.pem

```

* On some systems, you may also have to add dhparams to the certificate:

 
```
openssl dhparam -out dhparams.pem 2048
cat dhparams.pem >> sst.pem

```

* Then, copy the certificate and keys to all nodes in the cluster.

 * Then, configure the following on all nodes in the cluster:

 
```
[sst]
encrypt=2
tca=/etc/my.cnf.d/certificates/sst.crt
tcert=/etc/my.cnf.d/certificates/sst.pem

```

But replace the paths with whatever is relevant on your system.

 This should allow your SSTs to be encrypted.

 ### TLS Using OpenSSL Encryption with Galera-compatible Certificates and Keys

 To generate keys compatible with this encryption method, you can follow [these directions](https://galeracluster.com/library/documentation/ssl-sst.html#ssl-xtrabackup).

 For example:

 * First, generate the keys and certificates:

 
```
# CA
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365000 \
-key ca-key.pem -out ca-cert.pem
 
# server1
openssl req -newkey rsa:2048 -days 365000 \
-nodes -keyout server1-key.pem -out server1-req.pem
openssl rsa -in server1-key.pem -out server1-key.pem
openssl x509 -req -in server1-req.pem -days 365000 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \
-out server1-cert.pem

```

* Then, copy the certificate and keys to all nodes in the cluster.

 * Then, configure the following on all nodes in the cluster:

 
```
[sst]
encrypt=3
tkey=/etc/my.cnf.d/certificates/server1-key.pem
tcert=/etc/my.cnf.d/certificates/server1-cert.pem

```

But replace the paths with whatever is relevant on your system.

 This should allow your SSTs to be encrypted.

 ### TLS Using OpenSSL Encryption with MariaDB-compatible Certificates and Keys

 To generate keys compatible with this encryption method, you can follow [these directions](../certificate-creation-with-openssl/index).

 For example:

 * First, generate the keys and certificates:

 
```
# CA
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 365000 \
-key ca-key.pem -out ca-cert.pem
 
# server1
openssl req -newkey rsa:2048 -days 365000 \
-nodes -keyout server1-key.pem -out server1-req.pem
openssl rsa -in server1-key.pem -out server1-key.pem
openssl x509 -req -in server1-req.pem -days 365000 \
-CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \
-out server1-cert.pem

```

* Then, copy the certificate and keys to all nodes in the cluster.

 * Then, configure the following on all nodes in the cluster:

 
```
[sst]
encrypt=4
ssl-ca=/etc/my.cnf.d/certificates/ca-cert.pem
ssl-cert=/etc/my.cnf.d/certificates/server1-cert.pem
ssl-key=/etc/my.cnf.d/certificates/server1-key.pem

```

But replace the paths with whatever is relevant on your system.

 This should allow your SSTs to be encrypted.

 Logs
----

 The `xtrabackup-v2` SST method has its own logging outside of the MariaDB Server logging.

 ### Logging to SST Logs

 By default, on the donor node, it logs to `innobackup.backup.log`. This log file is located in the `[datadir](../server-system-variables/index#datadir)`.

 By default, on the joiner node, it logs to `innobackup.prepare.log` and `innobackup.move.log`. These log files are located in the `.sst` directory, which is a hidden directory inside the `[datadir](../server-system-variables/index#datadir)`.

 These log files are overwritten by each subsequent SST, so if an SST fails, it is best to copy them somewhere safe before starting another SST, so that the log files can be analyzed. See [MDEV-17973](https://jira.mariadb.org/browse/MDEV-17973) about that.

 ### Logging to Syslog

 You can redirect the SST logs to the syslog instead by setting the following in the `[sst]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[sst]
sst-syslog=1

```

You can also redirect the SST logs to the syslog by setting the following in the `[mysqld_safe]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mysqld_safe]
syslog

```

Performing SSTs with IPv6 Addresses
-----------------------------------

 If you are performing Percona XtraBackup SSTs with IPv6 addresses, then the `socat` utility needs to be passed the `pf=ip6` option. This can be done by setting the `sockopt` option in the `[sst]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[sst]
sockopt=",pf=ip6"

```

See [MDEV-18797](https://jira.mariadb.org/browse/MDEV-18797) for more information.

 Manual SST with Percona XtraBackup
----------------------------------

 In some cases, if Galera Cluster's automatic SSTs repeatedly fail, then it can be helpful to perform a "manual SST". See the following page on how to do that:

 * [Manual SST of Galera Cluster node with Percona XtraBackup](../manual-sst-of-galera-cluster-node-with-percona-xtrabackup/index)

 See Also
--------

 * [Percona XtraBackup SST Configuration](https://www.percona.com/doc/percona-xtradb-cluster/5.7/manual/xtrabackup_sst.html)
* [Encrypting PXC Traffic: ENCRYPTING SST TRAFFIC](https://www.percona.com/doc/percona-xtradb-cluster/5.7/security/encrypt-traffic.html#encrypt-sst)
* [XTRABACKUP PARAMETERS](https://galeracluster.com/library/documentation/xtrabackup-options.html)
* [SSL FOR STATE SNAPSHOT TRANSFERS: ENABLING SSL FOR XTRABACKUP](https://galeracluster.com/library/documentation/ssl-sst.html#ssl-xtrabackup)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xtrabackup-v2-sst-method/>

ADDTIME
=======

    Syntax
------

 
```
ADDTIME(expr1,expr2)

```

Description
-----------

 `ADDTIME()` adds *expr2* to *expr1* and returns the result. *expr1* is a time or datetime expression, and *expr2* is a time expression.

 Examples
--------

 
```
SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');
+---------------------------------------------------------+
| ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002') |
+---------------------------------------------------------+
| 2008-01-02 01:01:01.000001                              |
+---------------------------------------------------------+

SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
+-----------------------------------------------+
| ADDTIME('01:00:00.999999', '02:00:00.999998') |
+-----------------------------------------------+
| 03:00:01.999997                               |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/addtime/>

~
=

    Syntax
------

 
```
~

```

Description
-----------

 Bitwise NOT. Converts the value to 4 bytes binary and inverts all bits.

 Examples
--------

 
```
SELECT 3 & ~1;
+--------+
| 3 & ~1 |
+--------+
|      2 |
+--------+

SELECT 5 & ~1;
+--------+
| 5 & ~1 |
+--------+
|      4 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bitwise-not/>

ACOS
====

    Syntax
------

 
```
ACOS(X)

```
 Description
-----------

 Returns the arc cosine of `X`, that is, the value whose cosine is `X`. Returns `NULL` if `X` is not in the range `-1` to `1`.

 Examples
--------

 
```
SELECT ACOS(1);
+---------+
| ACOS(1) |
+---------+
|       0 |
+---------+

SELECT ACOS(1.0001);
+--------------+
| ACOS(1.0001) |
+--------------+
|         NULL |
+--------------+

SELECT ACOS(0);
+-----------------+
| ACOS(0)         |
+-----------------+
| 1.5707963267949 |
+-----------------+

SELECT ACOS(0.234);
+------------------+
| ACOS(0.234)      |
+------------------+
| 1.33460644244679 |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/acos/>

AES\_ENCRYPT
============

    Syntax
------

 
```
AES_ENCRYPT(str,key_str)

```

From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 
```
AES_ENCRYPT(str, key, [, iv [, mode]])

```

Description
-----------

 `AES_ENCRYPT()` and [AES\_DECRYPT()](../aes_decrypt/index) allow encryption and decryption of data using the official AES (Advanced Encryption Standard) algorithm, previously known as "Rijndael." Encoding with a 128-bit key length is used (from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), this is the default, and can be changed). 128 bits is much faster and is secure enough for most purposes.

 `AES_ENCRYPT()` encrypts a string *`str`* using the key *`key_str`*, and returns a binary string.

 `AES_DECRYPT()` decrypts the encrypted string and returns the original string.

 The input arguments may be any length. If either argument is NULL, the result of this function is also `NULL`.

 Because AES is a block-level algorithm, padding is used to encode uneven length strings and so the result string length may be calculated using this formula:

 
```
16 x (trunc(string_length / 16) + 1)

```

If `AES_DECRYPT()` detects invalid data or incorrect padding, it returns `NULL`. However, it is possible for `AES_DECRYPT()` to return a non-`NULL` value (possibly garbage) if the input data or the key is invalid.

 
**MariaDB starting with [11.2](../what-is-mariadb-112/index)**From [MariaDB 11.2](../what-is-mariadb-112/index), the function supports an initialization vector, and control of the block encryption mode. The default mode is specified by the [block\_encryption\_mode](../server-system-variables/index#block_encryption_mode) system variable, which can be changed when calling the function with a mode. *mode* is aes-{128,192,256}-{ecb,cbc,ctr} for example: "AES-128-cbc".

 AES\_ENCRYPT(str, key) can no longer be used in persistent virtual columns (and the like).

 
Examples
--------

 
```
INSERT INTO t VALUES (AES_ENCRYPT('text',SHA2('password',512)));

```

From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/):

 
```
SELECT HEX(AES_ENCRYPT('foo', 'bar', '0123456789abcdef', 'aes-256-cbc')) AS x;
+----------------------------------+
| x                                |
+----------------------------------+
| 42A3EB91E6DFC40A900D278F99E0726E |
+----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aes_encrypt/>

ADDDATE
=======

    Syntax
------

 
```
ADDDATE(date,INTERVAL expr unit), ADDDATE(expr,days)

```

Description
-----------

 When invoked with the `INTERVAL` form of the second argument, `ADDDATE()` is a synonym for `[DATE\_ADD()](../date_add/index)`. The related function `[SUBDATE()](../subdate/index)` is a synonym for `[DATE\_SUB()](../date_sub/index)`. For information on the `INTERVAL` unit argument, see the discussion for `[DATE\_ADD()](../date_add/index)`.

 When invoked with the days form of the second argument, MariaDB treats it as an integer number of days to be added to *expr*.

 Examples
--------

 
```
SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_ADD('2008-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 2008-02-02                              |
+-----------------------------------------+

SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
+----------------------------------------+
| ADDDATE('2008-01-02', INTERVAL 31 DAY) |
+----------------------------------------+
| 2008-02-02                             |
+----------------------------------------+

```


```
SELECT ADDDATE('2008-01-02', 31);
+---------------------------+
| ADDDATE('2008-01-02', 31) |
+---------------------------+
| 2008-02-02                |
+---------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d, ADDDATE(d, 10) from t1;
+---------------------+---------------------+
| d                   | ADDDATE(d, 10)      |
+---------------------+---------------------+
| 2007-01-30 21:31:07 | 2007-02-09 21:31:07 |
| 1983-10-15 06:42:51 | 1983-10-25 06:42:51 |
| 2011-04-21 12:34:56 | 2011-05-01 12:34:56 |
| 2011-10-30 06:31:41 | 2011-11-09 06:31:41 |
| 2011-01-30 14:03:25 | 2011-02-09 14:03:25 |
| 2004-10-07 11:19:34 | 2004-10-17 11:19:34 |
+---------------------+---------------------+

SELECT d, ADDDATE(d, INTERVAL 10 HOUR) from t1;
+---------------------+------------------------------+
| d                   | ADDDATE(d, INTERVAL 10 HOUR) |
+---------------------+------------------------------+
| 2007-01-30 21:31:07 | 2007-01-31 07:31:07          |
| 1983-10-15 06:42:51 | 1983-10-15 16:42:51          |
| 2011-04-21 12:34:56 | 2011-04-21 22:34:56          |
| 2011-10-30 06:31:41 | 2011-10-30 16:31:41          |
| 2011-01-30 14:03:25 | 2011-01-31 00:03:25          |
| 2004-10-07 11:19:34 | 2004-10-07 21:19:34          |
+---------------------+------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/adddate/>

Assignment Operator (=)
=======================

    Syntax
------

 
```
identifier = expr

```
 Description
-----------

 The equal sign is used as both an assignment operator in certain contexts, and as a [comparison operator](../equal/index). When used as assignment operator, the value on the right is assigned to the variable (or column, in some contexts) on the left.

 Since its use can be ambiguous, unlike the [:= assignment operator](../assignment-operator/index), the *`=`* assignment operator cannot be used in all contexts, and is only valid as part of a [SET](../set/index) statement, or the SET clause of an [UPDATE](../update/index) statement

 This operator works with both [user-defined variables](../user-defined-variables/index) and [local variables](../declare-variable/index).

 Examples
--------

 
```
UPDATE table_name SET x = 2 WHERE x > 100;

```


```
SET @x = 1, @y := 2;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/assignment-operators-assignment-operator/>

AES\_DECRYPT
============

    Syntax
------

 
```
AES_DECRYPT(crypt_str,key_str)

```

From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 
```
AES_ENCRYPT(crypt_str, key_str, [, iv [, mode]])

```

Description
-----------

 This function allows decryption of data using the official AES (Advanced Encryption Standard) algorithm. For more information, see the description of [AES\_ENCRYPT()](../aes_encrypt/index).   
  


 
**MariaDB starting with [11.2](../what-is-mariadb-112/index)**From [MariaDB 11.2](../what-is-mariadb-112/index), the function supports an initialization vector, and control of the block encryption mode. The default mode is specified by the [block\_encryption\_mode](../server-system-variables/index#block_encryption_mode) system variable, which can be changed when calling the function with a mode. *mode* is aes-{128,192,256}-{ecb,cbc,ctr} for example: "AES-128-cbc".

 For modes that require it, the initialization\_vector *iv* should be 16 bytes (it can be longer, but the extra bytes are ignored). A shorter *iv*, where one is required, results in the function returning NULL. Calling [RANDOM\_BYTES(16)](../random_bytes/index) will generate a random series of bytes that can be used for the *iv*. 

 
Examples
--------

 From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/):

 
```
SELECT HEX(AES_ENCRYPT('foo', 'bar', '0123456789abcdef', 'aes-128-ctr')) AS x; 
+--------+
| x      |
+--------+
| C57C4B |
+--------+


SELECT AES_DECRYPT(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr'); 
+------------------------------------------------------------------+
| AES_DECRYPT(x'C57C4B', 'bar', '0123456789abcdef', 'aes-128-ctr') |
+------------------------------------------------------------------+
| foo                                                              |
+------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aes_decrypt/>

ASCII
=====

    Syntax
------

 
```
ASCII(str)

```

Description
-----------

 Returns the numeric ASCII value of the leftmost character of the string argument. Returns `0` if the given string is empty and `NULL` if it is `NULL`.

 `ASCII()` works for 8-bit characters.

 Examples
--------

 
```
SELECT ASCII(9);
+----------+
| ASCII(9) |
+----------+
|       57 |
+----------+

SELECT ASCII('9');
+------------+
| ASCII('9') |
+------------+
|         57 |
+------------+

SELECT ASCII('abc');
+--------------+
| ASCII('abc') |
+--------------+
|           97 |
+--------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ascii/>

ADD\_MONTHS
===========

    
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**The ADD\_MONTHS function was introduced in [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) to enhance Oracle compatibility. Similar functionality can be achieved with the [DATE\_ADD](../date_add/index) function.

 
Syntax
------

 
```
ADD_MONTHS(date, months)

```
 Description
-----------

 `ADD_MONTHS` adds an integer *months* to a given *date* ([DATE](../date/index), [DATETIME](../datetime/index) or [TIMESTAMP](../timestamp/index)), returning the resulting date.

 *months* can be positive or negative.

 The resulting day component will remain the same as that specified in *date*, unless the resulting month has fewer days than the day component of the given date, in which case the day will be the last day of the resulting month.

 Returns NULL if given an invalid date, or a NULL argument.

 Examples
--------

 
```
SELECT ADD_MONTHS('2012-01-31', 2);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 2) |
+-----------------------------+
| 2012-03-31                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', -5);
+------------------------------+
| ADD_MONTHS('2012-01-31', -5) |
+------------------------------+
| 2011-08-31                   |
+------------------------------+

SELECT ADD_MONTHS('2011-01-31', 1);
+-----------------------------+
| ADD_MONTHS('2011-01-31', 1) |
+-----------------------------+
| 2011-02-28                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 1);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 1) |
+-----------------------------+
| 2012-02-29                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 2);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 2) |
+-----------------------------+
| 2012-03-31                  |
+-----------------------------+

SELECT ADD_MONTHS('2012-01-31', 3);
+-----------------------------+
| ADD_MONTHS('2012-01-31', 3) |
+-----------------------------+
| 2012-04-30                  |
+-----------------------------+

```

See Also
--------

 * [SQL\_MODE=ORACLE](../sql_modeoracle/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/add_months/>

ASIN
====

    Syntax
------

 
```
ASIN(X)

```
 Description
-----------

 Returns the arc sine of X, that is, the value whose sine is X. Returns NULL if X is not in the range -1 to 1.

 Examples
--------

 
```
SELECT ASIN(0.2);
+--------------------+
| ASIN(0.2)          |
+--------------------+
| 0.2013579207903308 |
+--------------------+

SELECT ASIN('foo');
+-------------+
| ASIN('foo') |
+-------------+
|           0 |
+-------------+

SHOW WARNINGS;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' |
+---------+------+-----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/asin/>

ATAN
====

    Syntax
------

 
```
ATAN(X)

```
 Description
-----------

 Returns the arc tangent of X, that is, the value whose tangent is X.

 Examples
--------

 
```
SELECT ATAN(2);
+--------------------+
| ATAN(2)            |
+--------------------+
| 1.1071487177940904 |
+--------------------+

SELECT ATAN(-2);
+---------------------+
| ATAN(-2)            |
+---------------------+
| -1.1071487177940904 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/atan/>

AVG
===

    Syntax
------

 
```
AVG([DISTINCT] expr)

```
 Description
-----------

 Returns the average value of expr. The DISTINCT option can be used to return the average of the distinct values of expr. NULL values are ignored. It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 AVG() returns NULL if there were no matching rows.

 AVG() can be used as a [window function](../window-functions/index).

 Examples
--------

 
```
CREATE TABLE sales (sales_value INT);

INSERT INTO sales VALUES(10),(20),(20),(40);

SELECT AVG(sales_value) FROM sales;
+------------------+
| AVG(sales_value) |
+------------------+
|          22.5000 |
+------------------+

SELECT AVG(DISTINCT(sales_value)) FROM sales;
+----------------------------+
| AVG(DISTINCT(sales_value)) |
+----------------------------+
|                    23.3333 |
+----------------------------+

```

Commonly, AVG() is used with a [GROUP BY](../select/index#group-by) clause:

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, AVG(score) FROM student GROUP BY name;
+---------+------------+
| name    | AVG(score) |
+---------+------------+
| Chun    |    74.0000 |
| Esben   |    37.0000 |
| Kaolin  |    72.0000 |
| Tatiana |    85.0000 |
+---------+------------+

```

Be careful to avoid this common mistake, not grouping correctly and returning mismatched data: 

 
```
SELECT name,test,AVG(score) FROM student;
+------+------+------------+
| name | test | MIN(score) |
+------+------+------------+
| Chun | SQL  |         31 |
+------+------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, test, score, AVG(score) OVER (PARTITION BY test) 
    AS average_by_test FROM student_test;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_test |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         65.2500 |
| Chun    | Tuning |    73 |         68.7500 |
| Esben   | SQL    |    43 |         65.2500 |
| Esben   | Tuning |    31 |         68.7500 |
| Kaolin  | SQL    |    56 |         65.2500 |
| Kaolin  | Tuning |    88 |         68.7500 |
| Tatiana | SQL    |    87 |         65.2500 |
| Tatiana | Tuning |    83 |         68.7500 |
+---------+--------+-------+-----------------+

```

See Also
--------

 * [MAX](../max/index) (maximum)
* [MIN](../min/index) (minimum)
* [SUM](../sum/index) (sum total)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/avg/>

BENCHMARK
=========

    Syntax
------

 
```
BENCHMARK(count,expr)

```

Description
-----------

 The BENCHMARK() function executes the expression `expr` repeatedly `count` times. It may be used to time how quickly MariaDB processes the expression. The result value is always 0. The intended use is from within the [mariadb client](../mariadb-command-line-client/index), which reports query execution times.

 Examples
--------

 
```
SELECT BENCHMARK(1000000,ENCODE('hello','goodbye'));
+----------------------------------------------+
| BENCHMARK(1000000,ENCODE('hello','goodbye')) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (0.21 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmark/>

ST\_AREA
========

    Syntax
------

 
```
ST_Area(poly)
Area(poly)

```

Description
-----------

 Returns as a double-precision number the area of the Polygon value `poly`, as measured in its spatial reference system.

 `ST_Area()` and `Area()` are synonyms.

 Examples
--------

 
```
SET @poly = 'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';

SELECT Area(GeomFromText(@poly));
+---------------------------+
| Area(GeomFromText(@poly)) |
+---------------------------+
|                         4 |
+---------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/area/>

ATAN2
=====

    Syntax
------

 
```
ATAN(Y,X), ATAN2(Y,X)

```

Description
-----------

 Returns the arc tangent of the two variables X and Y. It is similar to calculating the arc tangent of Y / X, except that the signs of both arguments are used to determine the quadrant of the result.

 Examples
--------

 
```
SELECT ATAN(-2,2);
+---------------------+
| ATAN(-2,2)          |
+---------------------+
| -0.7853981633974483 |
+---------------------+

SELECT ATAN2(PI(),0);
+--------------------+
| ATAN2(PI(),0)      |
+--------------------+
| 1.5707963267948966 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/atan2/>

BETWEEN AND
===========

    Syntax
------

 
```
expr BETWEEN min AND max

```
 Description
-----------

 If expr is greater than or equal to min and expr is less than or equal to max, BETWEEN returns 1, otherwise it returns 0. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. Otherwise type conversion takes place according to the rules described at [Type Conversion](../type-conversion/index), but applied to all the three arguments.

 Examples
--------

 
```
SELECT 1 BETWEEN 2 AND 3;
+-------------------+
| 1 BETWEEN 2 AND 3 |
+-------------------+
|                 0 |
+-------------------+

```


```
SELECT 'b' BETWEEN 'a' AND 'c';
+-------------------------+
| 'b' BETWEEN 'a' AND 'c' |
+-------------------------+
|                       1 |
+-------------------------+

```


```
SELECT 2 BETWEEN 2 AND '3';
+---------------------+
| 2 BETWEEN 2 AND '3' |
+---------------------+
|                   1 |
+---------------------+

```


```
SELECT 2 BETWEEN 2 AND 'x-3';
+-----------------------+
| 2 BETWEEN 2 AND 'x-3' |
+-----------------------+
|                     0 |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: 'x-3'

```

NULL:

 
```
SELECT 1 BETWEEN 1 AND NULL;
+----------------------+
| 1 BETWEEN 1 AND NULL |
+----------------------+
|                 NULL |
+----------------------+

```

DATE, DATETIME and TIMESTAMP examples. Omitting the time component compares against `00:00`, so later times on the same date are not returned:

 
```
CREATE TABLE `x` (
  a date ,
  b datetime,
  c timestamp
)

INSERT INTO x VALUES 
 ('2018-11-11', '2018-11-11 05:15', '2018-11-11 05:15'), 
 ('2018-11-12', '2018-11-12 05:15', '2018-11-12 05:15'); 

SELECT * FROM x WHERE a BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
| 2018-11-12 | 2018-11-12 05:15:00 | 2018-11-12 05:15:00 |
+------------+---------------------+---------------------+

SELECT * FROM x WHERE b BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
+------------+---------------------+---------------------+

SELECT * FROM x WHERE c BETWEEN '2018-11-11' AND '2018-11-12';
+------------+---------------------+---------------------+
| a          | b                   | c                   |
+------------+---------------------+---------------------+
| 2018-11-11 | 2018-11-11 05:15:00 | 2018-11-11 05:15:00 |
+------------+---------------------+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/between-and/>

AsWKB
=====

    A synonym for [ST\_AsBinary()](../st_asbinary/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aswkb/>

ST\_AsText
==========

    Syntax
------

 
```
ST_AsText(g)
AsText(g)
ST_AsWKT(g)
AsWKT(g)

```

Description
-----------

 Converts a value in internal geometry format to its [WKT](../wkt-definition/index) representation and returns the string result.

 `ST_AsText()`, `AsText()`, `ST_AsWKT()` and `AsWKT()` are all synonyms.

 Examples
--------

 
```
SET @g = 'LineString(1 1,4 4,6 6)';

SELECT ST_AsText(ST_GeomFromText(@g));
+--------------------------------+
| ST_AsText(ST_GeomFromText(@g)) |
+--------------------------------+
| LINESTRING(1 1,4 4,6 6)        |
+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/astext/>

ST\_AsBinary
============

    Syntax
------

 
```
ST_AsBinary(g)
AsBinary(g)
ST_AsWKB(g)
AsWKB(g)

```

Description
-----------

 Converts a value in internal geometry format to its [WKB](../well-known-binary-wkb-format/index) representation and returns the binary result.

 `ST_AsBinary()`, `AsBinary()`, `ST_AsWKB()` and `AsWKB()` are synonyms,

 Examples
--------

 
```
SET @poly = ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))');
SELECT ST_AsBinary(@poly);

SELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly)));
+--------------------------------------------+
| ST_AsText(ST_GeomFromWKB(ST_AsWKB(@poly))) |
+--------------------------------------------+
| POLYGON((0 0,0 1,1 1,1 0,0 0))             |
+--------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/asbinary/>

BINLOG\_GTID\_POS
=================

    Syntax
------

 
```
BINLOG_GTID_POS(binlog_filename,binlog_offset)

```

Description
-----------

 The BINLOG\_GTID\_POS() function takes as input an old-style [binary log](../binary-log/index) position in the form of a file name and a file offset. It looks up the position in the current binlog, and returns a string representation of the corresponding [GTID](../global-transaction-id/index) position. If the position is not found in the current binlog, NULL is returned.

 Examples
--------

 
```
SELECT BINLOG_GTID_POS("master-bin.000001", 600);

```

See Also
--------

 * [SHOW BINLOG EVENTS](../show-binlog-events/index) - Show events and their positions in the binary log

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binlog_gtid_pos/>

BINARY Operator
===============

    
This page describes the BINARY operator. For details about the data type, see [Binary Data Type](../binary/index).

 
Syntax
------

 
```
BINARY

```

Description
-----------

 The `BINARY` operator casts the string following it to a binary string. This is an easy way to force a column comparison to be done byte by byte rather than character by character. This causes the comparison to be case sensitive even if the column isn't defined as `[BINARY](../binary/index)` or `[BLOB](../string-data-types-blob-data-types/index)`. 

 `BINARY` also causes trailing spaces to be significant.

 Examples
--------

 
```
SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
|         1 |
+-----------+

SELECT BINARY 'a' = 'A';
+------------------+
| BINARY 'a' = 'A' |
+------------------+
|                0 |
+------------------+

SELECT 'a' = 'a ';
+------------+
| 'a' = 'a ' |
+------------+
|          1 |
+------------+

SELECT BINARY 'a' = 'a ';
+-------------------+
| BINARY 'a' = 'a ' |
+-------------------+
|                 0 |
+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-operator/>

ST\_ASWKT
=========

    A synonym for [ST\_ASTEXT()](../st_astext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aswkt/>

BIN
===

    Syntax
------

 
```
BIN(N)

```

Description
-----------

 Returns a string representation of the binary value of the given longlong (that is, `[BIGINT](../bigint/index)`) number. This is equivalent to `[CONV(N,10,2)](../conv/index)`. The argument should be positive. If it is a `FLOAT`, it will be truncated. Returns `NULL` if the argument is `NULL`.

 Examples
--------

 
```
SELECT BIN(12);
+---------+
| BIN(12) |
+---------+
| 1100    |
+---------+

```

See Also
--------

 * [Binary literals](../binary-literals/index)
* [CONV()](../conv/index)
* [OCT()](../oct/index)
* [HEX()](../hex/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bin/>

BIT\_COUNT
==========

    Syntax
------

 
```
BIT_COUNT(N)

```

Description
-----------

 Returns the number of bits that are set in the argument N.

 Examples
--------

 
```
SELECT BIT_COUNT(29), BIT_COUNT(b'101010');
+---------------+----------------------+
| BIT_COUNT(29) | BIT_COUNT(b'101010') |
+---------------+----------------------+
|             4 |                    3 |
+---------------+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit_count/>

BIT\_LENGTH
===========

    Syntax
------

 
```
BIT_LENGTH(str)

```
 Description
-----------

 Returns the length of the given string argument in bits. If the argument is not a string, it will be converted to string. If the argument is `NULL`, it returns `NULL`.

 Examples
--------

 
```
SELECT BIT_LENGTH('text');
+--------------------+
| BIT_LENGTH('text') |
+--------------------+
|                 32 |
+--------------------+

```


```
SELECT BIT_LENGTH('');
+----------------+
| BIT_LENGTH('') |
+----------------+
|              0 |
+----------------+

```

Compatibility
-------------

 PostgreSQL and Sybase support BIT\_LENGTH().

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit_length/>

BIT\_AND
========

    Syntax
------

 
```
BIT_AND(expr) [over_clause]

```

Description
-----------

 Returns the bitwise AND of all bits in *expr*. The calculation is performed with 64-bit ([BIGINT](../bigint/index)) precision. It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 If no rows match, `BIT_AND` will return a value with all bits set to 1. NULL values have no effect on the result unless all results are NULL, which is treated as no match.

 `BIT_AND` can be used as a [window function](../window-functions/index) with the addition of the *over\_clause*.

 Examples
--------

 
```
CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

```

As an [aggregate function](../aggregate-functions/index):

 
```
CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
  ('a',111),('a',110),('a',100),
  ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
  FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

```

No match:

 
```
SELECT BIT_AND(NULL);
+----------------------+
| BIT_AND(NULL)        |
+----------------------+
| 18446744073709551615 |
+----------------------+

```

See Also
--------

 * [BIT\_OR](../bit_or/index)
* [BIT\_XOR](../bit_xor/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit_and/>

CASE OPERATOR
=============

    Syntax
------

 
```
CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN
result ...] [ELSE result] END

CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...]
[ELSE result] END

```
 Description
-----------

 The first version returns the result where value=compare\_value. The second version returns the result for the first condition that is true. If there was no matching result value, the result after ELSE is returned, or NULL if there is no ELSE part.

 There is also a [CASE statement](../case-statement/index), which differs from the CASE operator described here.

 Examples
--------

 
```
SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;
+------------------------------------------------------------+
| CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END |
+------------------------------------------------------------+
| one                                                        |
+------------------------------------------------------------+

SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;
+--------------------------------------------+
| CASE WHEN 1>0 THEN 'true' ELSE 'false' END |
+--------------------------------------------+
| true                                       |
+--------------------------------------------+


SELECT CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
+-----------------------------------------------------+
| CASE BINARY 'B' WHEN 'a' THEN 1 WHEN 'b' THEN 2 END |
+-----------------------------------------------------+
|                                                NULL |
+-----------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/case-operator/>

BUFFER
======

    A synonym for [ST\_BUFFER](../st_buffer/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buffer/>

CEIL
====

    Syntax
------

 
```
CEIL(X)

```

Description
-----------

 CEIL() is a synonym for [CEILING()](../ceiling/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ceil/>

CENTROID
========

    A synonym for [ST\_CENTROID](../st_centroid/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/centroid/>

BIT\_XOR
========

    Syntax
------

 
```
BIT_XOR(expr) [over_clause]

```
 Description
-----------

 Returns the bitwise XOR of all bits in `expr`. The calculation is performed with 64-bit ([BIGINT](../bigint/index)) precision. It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 If no rows match, `BIT_XOR` will return a value with all bits set to `0`. NULL values have no effect on the result unless all results are NULL, which is treated as no match.

 `BIT_XOR` can be used as a [window function](../window-functions/index) with the addition of the *over\_clause*.

 Examples
--------

 
```
CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

```

As an [aggregate function](../aggregate-functions/index):

 
```
CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
  ('a',111),('a',110),('a',100),
  ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
  FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

```

No match:

 
```
SELECT BIT_XOR(NULL);
+---------------+
| BIT_XOR(NULL) |
+---------------+
|             0 |
+---------------+

```

See Also
--------

 * [BIT\_AND](../bit_and/index)
* [BIT\_OR](../bit_or/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit_xor/>

CHARACTER\_LENGTH
=================

    Syntax
------

 
```
CHARACTER_LENGTH(str)

```

Description
-----------

 `CHARACTER_LENGTH()` is a synonym for `[CHAR\_LENGTH()](../char_length/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/character_length/>

CAST
====

    Syntax
------

 
```
CAST(expr AS type)

```
 Description
-----------

 The `CAST()` function takes a value of one [type](../data-types/index) and produces a value of another type, similar to the [CONVERT()](../convert/index) function. 

 The type can be one of the following values:

 * [BINARY](../binary/index)
* [CHAR](../char/index)
* [DATE](../date/index)
* [DATETIME](../datetime/index)
* [DECIMAL[(M[,D])](../decimal/index)]
* [DOUBLE](../double/index)
* [FLOAT](../float/index) (from [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/))
* [INTEGER](../int/index)
	+ Short for `SIGNED INTEGER`
* SIGNED [INTEGER]
* UNSIGNED [INTEGER]
* [TIME](../time/index)
* [VARCHAR](../varchar/index) (in [Oracle mode](../sql_modeoracle/index), from [MariaDB 10.3](../what-is-mariadb-103/index))

 The main difference between `CAST` and [CONVERT()](../convert/index) is that `[CONVERT(expr,type)](../convert/index)` is ODBC syntax while `CAST(expr as type)` and `[CONVERT(... USING ...)](../convert/index)` are SQL92 syntax.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you can use the `CAST()` function with the `INTERVAL` keyword.

 Until [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/), `X'HHHH'`, the standard SQL syntax for binary string literals, erroneously worked in the same way as `0xHHHH`. In 5.5.31 it was intentionally changed to behave as a string in all contexts (and never as a number).

 This introduced an incompatibility with previous versions of MariaDB, and all versions of MySQL (see the example below). 

 Examples
--------

 Simple casts:

 
```
SELECT CAST("abc" AS BINARY);
SELECT CAST("1" AS UNSIGNED INTEGER);
SELECT CAST(123 AS CHAR CHARACTER SET utf8)

```

Note that when one casts to [CHAR](../char/index) without specifying the character set, the [collation\_connection](../server-system-variables/index#collation_connection) character set collation will be used. When used with `CHAR CHARACTER SET`, the default collation for that character set will be used.

 
```
SELECT COLLATION(CAST(123 AS CHAR));
+------------------------------+
| COLLATION(CAST(123 AS CHAR)) |
+------------------------------+
| latin1_swedish_ci            |
+------------------------------+

SELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8));
+-------------------------------------------------+
| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8)) |
+-------------------------------------------------+
| utf8_general_ci                                 |
+-------------------------------------------------+

```

If you also want to change the collation, you have to use the `COLLATE` operator:

 
```
SELECT COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) 
  COLLATE utf8_unicode_ci);
+-------------------------------------------------------------------------+
| COLLATION(CAST(123 AS CHAR CHARACTER SET utf8) COLLATE utf8_unicode_ci) |
+-------------------------------------------------------------------------+
| utf8_unicode_ci                                                         |
+-------------------------------------------------------------------------+

```

Using `CAST()` to order an `[ENUM](../enum/index)` field as a `[CHAR](../char/index)` rather than the internal numerical value:

 
```
CREATE TABLE enum_list (enum_field enum('c','a','b'));

INSERT INTO enum_list (enum_field) 
VALUES('c'),('a'),('c'),('b');

SELECT * FROM enum_list 
ORDER BY enum_field;
+------------+
| enum_field |
+------------+
| c          |
| c          |
| a          |
| b          |
+------------+

SELECT * FROM enum_list 
ORDER BY CAST(enum_field AS CHAR);
+------------+
| enum_field |
+------------+
| a          |
| b          |
| c          |
| c          |
+------------+

```

From [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/), the following will trigger warnings, since `x'aa'` and `'X'aa'` no longer behave as a number. Previously, and in all versions of MySQL, no warnings are triggered since they did erroneously behave as a number:

 
```
SELECT CAST(0xAA AS UNSIGNED), CAST(x'aa' AS UNSIGNED), CAST(X'aa' AS UNSIGNED);
+------------------------+-------------------------+-------------------------+
| CAST(0xAA AS UNSIGNED) | CAST(x'aa' AS UNSIGNED) | CAST(X'aa' AS UNSIGNED) |
+------------------------+-------------------------+-------------------------+
|                    170 |                       0 |                       0 |
+------------------------+-------------------------+-------------------------+
1 row in set, 2 warnings (0.00 sec)

Warning (Code 1292): Truncated incorrect INTEGER value: '\xAA'
Warning (Code 1292): Truncated incorrect INTEGER value: '\xAA'

```

Casting to intervals:

 
```
SELECT CAST(2019-01-04 INTERVAL AS DAY_SECOND(2)) AS "Cast";

+-------------+
| Cast        |
+-------------+
| 00:20:17.00 |
+-------------+

```

See Also
--------

 * [Supported data types](../data-types/index)
* [Microseconds in MariaDB](../microseconds-in-mariadb/index)
* [String literals](../string-literals/index)
* [COLLATION()](../collation/index)
* [CONVERT()](../convert/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cast/>

ST\_BOUNDARY
============

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**The ST\_BOUNDARY function was introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
Syntax
------

 
```
ST_BOUNDARY(g)
BOUNDARY(g)

```

Description
-----------

 Returns a geometry that is the closure of the combinatorial boundary of the geometry value *`g`*.

 BOUNDARY() is a synonym.

 Examples
--------

 
```
SELECT ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(3 3,0 0, -3 3)')));
+----------------------------------------------------------------------+
| ST_AsText(ST_Boundary(ST_GeomFromText('LINESTRING(3 3,0 0, -3 3)'))) |
+----------------------------------------------------------------------+
| MULTIPOINT(3 3,-3 3)                                                 |
+----------------------------------------------------------------------+

SELECT ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((3 3,0 0, -3 3, 3 3))')));
+--------------------------------------------------------------------------+
| ST_AsText(ST_Boundary(ST_GeomFromText('POLYGON((3 3,0 0, -3 3, 3 3))'))) |
+--------------------------------------------------------------------------+
| LINESTRING(3 3,0 0,-3 3,3 3)                                             |
+--------------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/boundary/>

CEILING
=======

    Syntax
------

 
```
CEILING(X)

```

Description
-----------

 Returns the smallest integer value not less than X.

 Examples
--------

 
```
SELECT CEILING(1.23);
+---------------+
| CEILING(1.23) |
+---------------+
|             2 |
+---------------+

SELECT CEILING(-1.23);
+----------------+
| CEILING(-1.23) |
+----------------+
|             -1 |
+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ceiling/>

CHAR Function
=============

    Syntax
------

 
```
CHAR(N,... [USING charset_name])

```

Description
-----------

 `CHAR()` interprets each argument as an `[INT](../int/index)` and returns a string consisting of the characters given by the code values of those integers. `NULL` values are skipped. By default, `CHAR()` returns a binary string. To produce a string in a given [character set](../data-types-character-sets-and-collations/index), use the optional `USING` clause:

 
```
SELECT CHARSET(CHAR(0x65)), CHARSET(CHAR(0x65 USING utf8));
+---------------------+--------------------------------+
| CHARSET(CHAR(0x65)) | CHARSET(CHAR(0x65 USING utf8)) |
+---------------------+--------------------------------+
| binary              | utf8                           |
+---------------------+--------------------------------+

```

If `USING` is given and the result string is illegal for the given character set, a warning is issued. Also, if strict [SQL mode](../sql_mode/index) is enabled, the result from `CHAR()` becomes `NULL`.

 Examples
--------

 
```
SELECT CHAR(77,97,114,'105',97,'68',66);
+----------------------------------+
| CHAR(77,97,114,'105',97,'68',66) |
+----------------------------------+
| MariaDB                          |
+----------------------------------+

SELECT CHAR(77,77.3,'77.3');
+----------------------+
| CHAR(77,77.3,'77.3') |
+----------------------+
| MMM                  |
+----------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect INTEGER value: '77.3'

```

See Also
--------

 * [Character Sets and Collations](../data-types-character-sets-and-collations/index)
* [ASCII()](../ascii/index) - Return ASCII value of first character
* [ORD()](../ord/index) - Return value for character in single or multi-byte character sets
* [CHR](../chr/index) - Similar, Oracle-compatible, function

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/char-function/>

BIT\_OR
=======

    Syntax
------

 
```
BIT_OR(expr) [over_clause]

```
 Description
-----------

 Returns the bitwise OR of all bits in `expr`. The calculation is performed with 64-bit ([BIGINT](../bigint/index)) precision. It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 If no rows match, `BIT_OR` will return a value with all bits set to `0`. NULL values have no effect on the result unless all results are NULL, which is treated as no match.

 `BIT_OR` can be used as a [window function](../window-functions/index) with the addition of the *over\_clause*.

 Examples
--------

 
```
CREATE TABLE vals (x INT);

INSERT INTO vals VALUES(111),(110),(100);

SELECT BIT_AND(x), BIT_OR(x), BIT_XOR(x) FROM vals;
+------------+-----------+------------+
| BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+------------+-----------+------------+
|        100 |       111 |        101 |
+------------+-----------+------------+

```

As an [aggregate function](../aggregate-functions/index):

 
```
CREATE TABLE vals2 (category VARCHAR(1), x INT);

INSERT INTO vals2 VALUES
  ('a',111),('a',110),('a',100),
  ('b','000'),('b',001),('b',011);

SELECT category, BIT_AND(x), BIT_OR(x), BIT_XOR(x) 
  FROM vals GROUP BY category;
+----------+------------+-----------+------------+
| category | BIT_AND(x) | BIT_OR(x) | BIT_XOR(x) |
+----------+------------+-----------+------------+
| a        |        100 |       111 |        101 |
| b        |          0 |        11 |         10 |
+----------+------------+-----------+------------+

```

No match:

 
```
SELECT BIT_OR(NULL);
+--------------+
| BIT_OR(NULL) |
+--------------+
|            0 |
+--------------+

```

See Also
--------

 * [BIT\_AND](../bit_and/index)
* [BIT\_XOR](../bit_xor/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bit_or/>

CHARSET
=======

    Syntax
------

 
```
CHARSET(str)

```

Description
-----------

 Returns the [character set](../data-types-character-sets-and-collations/index) of the string argument. If `str` is not a string, it is considered as a binary string (so the function returns 'binary'). This applies to `NULL`, too. The return value is a string in the utf8 [character set](../data-types-character-sets-and-collations/index).

 Examples
--------

 
```
SELECT CHARSET('abc');
+----------------+
| CHARSET('abc') |
+----------------+
| latin1         |
+----------------+

SELECT CHARSET(CONVERT('abc' USING utf8));
+------------------------------------+
| CHARSET(CONVERT('abc' USING utf8)) |
+------------------------------------+
| utf8                               |
+------------------------------------+

SELECT CHARSET(USER());
+-----------------+
| CHARSET(USER()) |
+-----------------+
| utf8            |
+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/charset/>

COALESCE
========

    Syntax
------

 
```
COALESCE(value,...)

```

Description
-----------

 Returns the first non-NULL value in the list, or NULL if there are no non-NULL values. At least one parameter must be passed.

 The function is useful when substituting a default value for null values when displaying data.

 See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 Examples
--------

 
```
SELECT COALESCE(NULL,1);
+------------------+
| COALESCE(NULL,1) |
+------------------+
|                1 |
+------------------+

```


```
SELECT COALESCE(NULL,NULL,NULL);
+--------------------------+
| COALESCE(NULL,NULL,NULL) |
+--------------------------+
|                     NULL |
+--------------------------+

```

When two arguments are given, COALESCE() is the same as [IFNULL()](../ifnull/index):

 
```
SET @a=NULL, @b=1;

SELECT COALESCE(@a, @b), IFNULL(@a, @b);
+------------------+----------------+
| COALESCE(@a, @b) | IFNULL(@a, @b) |
+------------------+----------------+
|                1 |              1 |
+------------------+----------------+

```

Hex type confusion:

 
```
CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (0x31, 0x61),(COALESCE(0x31), COALESCE(0x61));

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|   49 | a    |
|    1 | a    |
+------+------+

```

The reason for the differing results above is that when 0x31 is inserted directly to the column, it's treated as a number (see [Hexadecimal Literals](../hexadecimal-literals/index)), while when 0x31 is passed to COALESCE(), it's treated as a string, because:

 * HEX values have a string data type by default.
* COALESCE() has the same data type as the argument.

 Substituting zero for NULL (in this case when the aggregate function returns NULL after finding no rows):

 
```
SELECT SUM(score) FROM student;
+------------+
| SUM(score) |
+------------+
|       NULL |
+------------+

SELECT COALESCE(SUM(score),0) FROM student;
+------------------------+
| COALESCE(SUM(score),0) |
+------------------------+
|                      0 |
+------------------------+

```

See also
--------

 * [NULL values](../null-values/index)
* [IS NULL operator](../is-null/index)
* [IS NOT NULL operator](../is-not-null/index)
* [IFNULL function](../ifnull/index)
* [NULLIF function](../nullif/index)
* [CONNECT data types](../connect-data-types/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/coalesce/>

CHAR\_LENGTH
============

    Syntax
------

 
```
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)

```
 Description
-----------

 Returns the length of the given string argument, measured in characters. A multi-byte character counts as a single character. This means that for a string containing five two-byte characters, [LENGTH()](../length/index) (or [OCTET\_LENGTH()](../octet_length/index) in [Oracle mode](../sql_modeoracle/index)) returns 10, whereas `CHAR_LENGTH()` returns 5. If the argument is `NULL`, it returns `NULL`. 

 If the argument is not a string value, it is converted into a string.

 It is synonymous with the `CHARACTER_LENGTH()` function.

 Examples
--------

 
```
SELECT CHAR_LENGTH('MariaDB');
+------------------------+
| CHAR_LENGTH('MariaDB') |
+------------------------+
|                      7 |
+------------------------+

```

When [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3](../what-is-mariadb-103/index) is not set:

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

In [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions):

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

See Also
--------

 * [LENGTH()](../length/index)
* [LENGTHB()](../lengthb/index)
* [OCTET\_LENGTH()](../octet_length/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/char_length/>

COERCIBILITY
============

    Syntax
------

 
```
COERCIBILITY(str)

```

Description
-----------

 Returns the collation coercibility value of the string argument. Coercibility defines what will be converted to what in case of collation conflict, with an expression with higher coercibility being converted to the collation of an expression with lower coercibility.

 


| Coercibility | Description | Example |
| --- | --- | --- |
| 0 | Explicit | Value using a COLLATE clause |
| 1 | No collation | Concatenated strings using different collations |
| 2 | Implicit | Column value |
| 3 | Constant | USER() return value |
| 4 | Coercible | Literal string |
| 5 | Ignorable | NULL or derived from NULL |

 
Examples
--------

 
```
SELECT COERCIBILITY('abc' COLLATE latin1_swedish_ci);
+-----------------------------------------------+
| COERCIBILITY('abc' COLLATE latin1_swedish_ci) |
+-----------------------------------------------+
|                                             0 |
+-----------------------------------------------+

SELECT COERCIBILITY(USER());
+----------------------+
| COERCIBILITY(USER()) |
+----------------------+
|                    3 |
+----------------------+

SELECT COERCIBILITY('abc');
+---------------------+
| COERCIBILITY('abc') |
+---------------------+
|                   4 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/coercibility/>

COLLATION
=========

    Syntax
------

 
```
COLLATION(str)

```
 Description
-----------

 Returns the collation of the string argument. If `str` is not a string, it is considered as a binary string (so the function returns 'binary'). This applies to `NULL`, too. The return value is a string in the utf8 [character set](../data-types-character-sets-and-collations/index).

 See [Character Sets and Collations](../data-types-character-sets-and-collations/index).

 Examples
--------

 
```
SELECT COLLATION('abc');
+-------------------+
| COLLATION('abc')  |
+-------------------+
| latin1_swedish_ci |
+-------------------+

SELECT COLLATION(_utf8'abc');
+-----------------------+
| COLLATION(_utf8'abc') |
+-----------------------+
| utf8_general_ci       |
+-----------------------+

```

See Also
--------

 * [String literals](../string-literals/index)
* [CAST()](../cast/index)
* [CONVERT()](../convert/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/collation/>

COLUMN\_ADD
===========

    Syntax
------

 
```
COLUMN_ADD(dyncol_blob, column_nr, value [as type], [column_nr, value [as type]]...);
COLUMN_ADD(dyncol_blob, column_name, value [as type], [column_name, value [as type]]...);

```

Description
-----------

 Adds or updates [dynamic columns](../dynamic-columns/index).

 * **`dyncol_blob`** must be either a valid dynamic columns blob (for example, `COLUMN_CREATE` returns such blob), or an empty string.
* **`column_name`** specifies the name of the column to be added. If `dyncol_blob` already has a column with this name, it will be overwritten.
* **`value`** specifies the new value for the column. Passing a NULL value will cause the column to be deleted.
* **`as type`** is optional. See <#datatypes> section for a discussion about types.

 The return value is a dynamic column blob after the modifications.

 Examples
--------

 
```
UPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value") WHERE id=1;

```

Note: `COLUMN_ADD()` is a regular function (just like `[CONCAT()](../concat/index)`), hence, in order to update the value in the table you have to use the `UPDATE ... SET dynamic_col=COLUMN_ADD(dynamic_col,
....)`  pattern.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_add/>

CHR
===

    
**MariaDB starting with [10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)**The `CHR()` function was introduced in [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) to provide Oracle compatibility

 
Syntax
------

 
```
CHR(N)

```

Description
-----------

 `CHR()` interprets each argument N as an integer and returns a `[VARCHAR(1)](../varchar/index)` string consisting of the character given by the code values of the integer. The character set and collation of the string are set according to the values of the `[character\_set\_database](../server-system-variables/index#character_set_database)` and `[collation\_database](../server-system-variables/index#collation_database)` system variables.

 `CHR()` is similar to the `[CHAR()](../char-function/index)` function, but only accepts a single argument.

 `CHR()` is available in all [sql\_modes](../sql-mode/index).

 Examples
--------

 
```
SELECT CHR(67);
+---------+
| CHR(67) |
+---------+
| C       |
+---------+

SELECT CHR('67');
+-----------+
| CHR('67') |
+-----------+
| C         |
+-----------+

SELECT CHR('C');
+----------+
| CHR('C') |
+----------+
|          |
+----------+
1 row in set, 1 warning (0.000 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect INTEGER value: 'C' |
+---------+------+----------------------------------------+

```

See Also
--------

 * [Character Sets and Collations](../data-types-character-sets-and-collations/index)
* [ASCII()](../ascii/index) - Return ASCII value of first character
* [ORD()](../ord/index) - Return value for character in single or multi-byte character sets
* [CHAR()](../char-function/index) - Similar function which accepts multiple integers

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/chr/>

COLUMN\_CHECK
=============

    Syntax
------

 
```
COLUMN_CHECK(dyncol_blob);

```

Description
-----------

 Check if `dyncol_blob` is a valid packed dynamic columns blob. Return value of 1 means the blob is valid, return value of 0 means it is not.

 **Rationale:** Normally, one works with valid dynamic column blobs. Functions like [COLUMN\_CREATE](../column_create/index), [COLUMN\_ADD](../column_add/index), [COLUMN\_DELETE](../column_delete/index) always return valid dynamic column blobs. However, if a dynamic column blob is accidentally truncated, or transcoded from one character set to another, it will be corrupted. This function can be used to check if a value in a blob field is a valid dynamic column blob.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_check/>

COLUMN\_CREATE
==============

    Syntax
------

 
```
COLUMN_CREATE(column_nr, value [as type], [column_nr, value [as type]]...);
COLUMN_CREATE(column_name, value [as type], [column_name, value [as type]]...);

```

Description
-----------

 Returns a [dynamic columns](../dynamic-columns/index) blob that stores the specified columns with values.

 The return value is suitable for 

 * storing in a table
* further modification with other dynamic columns functions

 The **`as type`** part allows one to specify the value type. In most cases, this is redundant because MariaDB will be able to deduce the type of the value. Explicit type specification may be needed when the type of the value is not apparent. For example, a literal `'2012-12-01'` has a CHAR type by default, one will need to specify `'2012-12-01' AS DATE` to have it stored as a date. See [Dynamic Columns:Datatypes](../dynamic-columns/index#datatypes) for further details.

 Examples
--------

 
```
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_create/>

COLUMN\_EXISTS
==============

    Syntax
------

 
```
COLUMN_EXISTS(dyncol_blob, column_nr);
COLUMN_EXISTS(dyncol_blob, column_name);

```

Description
-----------

 Checks if a column with name `column_name` exists in `dyncol_blob`. If yes, return `1`, otherwise return `0`. See [dynamic columns](../dynamic-columns/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_exists/>

COLUMN\_JSON
============

    Syntax
------

 
```
COLUMN_JSON(dyncol_blob)

```

Description
-----------

 Returns a JSON representation of data in `dyncol_blob`. Can also be used to display nested columns. See [dynamic columns](../dynamic-columns/index) for more information.

 Example
-------

 
```
select item_name, COLUMN_JSON(dynamic_cols) from assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

```

Limitation: `COLUMN_JSON` will decode nested dynamic columns at a nesting level of not more than 10 levels deep. Dynamic columns that are nested deeper than 10 levels will be shown as BINARY string, without encoding.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_json/>

COLUMN\_GET
===========

    Syntax
------

 
```
COLUMN_GET(dyncol_blob, column_nr as type);
COLUMN_GET(dyncol_blob, column_name as type);

```

Description
-----------

 Gets the value of a [dynamic column](../dynamic-columns/index) by its name. If no column with the given name exists, `NULL` will be returned.

 **`column_name as type`** requires that one specify the datatype of the dynamic column they are reading. 

 This may seem counter-intuitive: why would one need to specify which datatype they're retrieving? Can't the dynamic columns system figure the datatype from the data being stored?

 The answer is: SQL is a statically-typed language. The SQL interpreter needs to know the datatypes of all expressions before the query is run (for example, when one is using prepared statements and runs `"select COLUMN_GET(...)"`, the prepared statement API requires the server to inform the client about the datatype of the column being read before the query is executed and the server can see what datatype the column actually has).

 ### Lengths

 If you're running queries like:

 
```
SELECT COLUMN_GET(blob, 'colname' as CHAR) ...

```

without specifying a maximum length (i.e. using `as CHAR`, not `as CHAR(n)`), MariaDB will report the maximum length of the resultset column to be 16,777,216. This may cause excessive memory usage in some client libraries, because they try to pre-allocate a buffer of maximum resultset width. To avoid this problem, use CHAR(n) whenever you're using COLUMN\_GET in the select list.

 See [Dynamic Columns:Datatypes](../dynamic-columns/index#datatypes) for more information about datatypes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_get/>

COLUMN\_LIST
============

    Syntax
------

 
```
COLUMN_LIST(dyncol_blob);

```

Description
-----------

 Returns a comma-separated list of column names. The names are quoted with backticks.

 See [dynamic columns](../dynamic-columns/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_list/>

COMPRESS
========

    Syntax
------

 
```
COMPRESS(string_to_compress)

```

Description
-----------

 Compresses a string and returns the result as a binary string. This function requires MariaDB to have been compiled with a compression library such as zlib. Otherwise, the return value is always `NULL`. The compressed string can be uncompressed with `[UNCOMPRESS()](../uncompress/index)`.

 The [have\_compress](../server-system-variables/index#have_compress) server system variable indicates whether a compression library is present. 

 Examples
--------

 
```
SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
+------------------------------------+
| LENGTH(COMPRESS(REPEAT('a',1000))) |
+------------------------------------+
|                                 21 |
+------------------------------------+

SELECT LENGTH(COMPRESS(''));
+----------------------+
| LENGTH(COMPRESS('')) |
+----------------------+
|                    0 |
+----------------------+

SELECT LENGTH(COMPRESS('a'));
+-----------------------+
| LENGTH(COMPRESS('a')) |
+-----------------------+
|                    13 |
+-----------------------+

SELECT LENGTH(COMPRESS(REPEAT('a',16)));
+----------------------------------+
| LENGTH(COMPRESS(REPEAT('a',16))) |
+----------------------------------+
|                               15 |
+----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compress/>

CONTAINS
========

    Syntax
------

 
```
Contains(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether a geometry `g1` completely contains geometry `g2`. CONTAINS() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_CONTAINS()](../st_contains/index) uses object shapes. 

 This tests the opposite relationship to [Within()](../within/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/contains/>

CONNECTION\_ID
==============

    Syntax
------

 
```
CONNECTION_ID()

```

Description
-----------

 Returns the connection ID for the connection. Every connection (including events) has an ID that is unique among the set of currently connected clients.

 Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), returns `MYSQL_TYPE_LONGLONG`, or [bigint(10)](../bigint/index), in all cases. From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), returns `MYSQL_TYPE_LONG`, or [int(10)](../int/index), when the result would fit within 32-bits.

 Examples
--------

 
```
SELECT CONNECTION_ID();
+-----------------+
| CONNECTION_ID() |
+-----------------+
|               3 |
+-----------------+

```

See Also
--------

 * [SHOW PROCESSLIST](../show-processlist/index)
* [INFORMATION\_SCHEMA.PROCESSLIST](../information-schema-processlist-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connection_id/>

CONCAT\_WS
==========

    Syntax
------

 
```
CONCAT_WS(separator,str1,str2,...)

```

Description
-----------

 `CONCAT_WS()` stands for Concatenate With Separator and is a special form of `[CONCAT()](../concat/index)`. The first argument is the separator for the rest of the arguments. The separator is added between the strings to be concatenated. The separator can be a string, as can the rest of the arguments.

 If the separator is `NULL`, the result is `NULL`; all other `NULL` values are skipped. This makes `CONCAT_WS()` suitable when you want to concatenate some values and avoid losing all information if one of them is `NULL`.

 Examples
--------

 
```
SELECT CONCAT_WS(',','First name','Second name','Last Name');
+-------------------------------------------------------+
| CONCAT_WS(',','First name','Second name','Last Name') |
+-------------------------------------------------------+
| First name,Second name,Last Name                      |
+-------------------------------------------------------+

SELECT CONCAT_WS('-','Floor',NULL,'Room');
+------------------------------------+
| CONCAT_WS('-','Floor',NULL,'Room') |
+------------------------------------+
| Floor-Room                         |
+------------------------------------+

```

In some cases, remember to include a space in the separator string:

 
```
SET @a = 'gnu', @b = 'penguin', @c = 'sea lion';
Query OK, 0 rows affected (0.00 sec)

SELECT CONCAT_WS(', ', @a, @b, @c);
+-----------------------------+
| CONCAT_WS(', ', @a, @b, @c) |
+-----------------------------+
| gnu, penguin, sea lion      |
+-----------------------------+

```

Using `CONCAT_WS()` to handle `NULL`s:

 
```
SET @a = 'a', @b = NULL, @c = 'c';

SELECT CONCAT_WS('', @a, @b, @c);
+---------------------------+
| CONCAT_WS('', @a, @b, @c) |
+---------------------------+
| ac                        |
+---------------------------+

```

See Also
--------

 * [GROUP\_CONCAT()](../group_concat/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/concat_ws/>

CONVERT
=======

    Syntax
------

 
```
CONVERT(expr,type), CONVERT(expr USING transcoding_name)

```
 Description
-----------

 The `CONVERT()` and [CAST()](../cast/index) functions take a value of one type and produce a value of another type.

 The type can be one of the following values:

 * [BINARY](../binary/index)
* [CHAR](../char/index)
* [DATE](../date/index)
* [DATETIME](../datetime/index)
* [DECIMAL[(M[,D])](../decimal/index)]
* [DOUBLE](../double/index)
* [FLOAT](../float/index) (from [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/))
* [INTEGER](../int/index)
	+ Short for `SIGNED INTEGER`
* SIGNED [INTEGER]
* UNSIGNED [INTEGER]
* [TIME](../time/index)
* [VARCHAR](../varchar/index) (in [Oracle mode](../sql_modeoracle/index), from [MariaDB 10.3](../what-is-mariadb-103/index))

 Note that in MariaDB, `INT` and `INTEGER` are the same thing.

 `BINARY` produces a string with the [BINARY](../binary/index) data type. If the optional length is given, `BINARY(N)` causes the cast to use no more than `N` bytes of the argument. Values shorter than the given number in bytes are padded with 0x00 bytes to make them equal the length value.

 `CHAR(N)` causes the cast to use no more than the number of characters given in the argument.

 The main difference between the [CAST()](../cast/index) and `CONVERT()` is that `CONVERT(expr,type)` is ODBC syntax while [CAST(expr as type)](../cast/index) and `CONVERT(... USING ...)` are SQL92 syntax.

 `CONVERT()` with `USING` is used to convert data between different [character sets](../data-types-character-sets-and-collations/index). In MariaDB, transcoding names are the same as the corresponding character set names. For example, this statement converts the string 'abc' in the default character set to the corresponding string in the utf8 character set:

 
```
SELECT CONVERT('abc' USING utf8);

```

Examples
--------

 
```
SELECT enum_col FROM tbl_name 
ORDER BY CAST(enum_col AS CHAR);

```

Converting a [BINARY](../binary/index) to string to permit the [LOWER](../lower/index) function to work:

 
```
SET @x = 'AardVark';

SET @x = BINARY 'AardVark';

SELECT LOWER(@x), LOWER(CONVERT (@x USING latin1));
+-----------+----------------------------------+
| LOWER(@x) | LOWER(CONVERT (@x USING latin1)) |
+-----------+----------------------------------+
| AardVark  | aardvark                         |
+-----------+----------------------------------+

```

See Also
--------

 * [Character Sets and Collations](../data-types-character-sets-and-collations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/convert/>

CONVERT\_TZ
===========

    Syntax
------

 
```
CONVERT_TZ(dt,from_tz,to_tz)

```

Description
-----------

 CONVERT\_TZ() converts a datetime value *dt* from the [time zone](../time-zones/index) given by *from\_tz* to the time zone given by *to\_tz* and returns the resulting value.

 In order to use named time zones, such as GMT, MET or Africa/Johannesburg, the time\_zone tables must be loaded (see [mysql\_tzinfo\_to\_sql](../mysql_tzinfo_to_sql/index)).

 No conversion will take place if the value falls outside of the supported TIMESTAMP range ('1970-01-01 00:00:01' to '2038-01-19 05:14:07' UTC) when converted from *from\_tz* to UTC.

 This function returns NULL if the arguments are invalid (or named time zones have not been loaded).

 See [time zones](../time-zones/index) for more information.

 Examples
--------

 
```
SELECT CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('2016-01-01 12:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 2016-01-01 22:00:00                                 |
+-----------------------------------------------------+

```

Using named time zones (with the time zone tables loaded):

 
```
SELECT CONVERT_TZ('2016-01-01 12:00:00','GMT','Africa/Johannesburg');
+---------------------------------------------------------------+
| CONVERT_TZ('2016-01-01 12:00:00','GMT','Africa/Johannesburg') |
+---------------------------------------------------------------+
| 2016-01-01 14:00:00                                           |
+---------------------------------------------------------------+

```

The value is out of the TIMESTAMP range, so no conversion takes place:

 
```
SELECT CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00');
+-----------------------------------------------------+
| CONVERT_TZ('1969-12-31 22:00:00','+00:00','+10:00') |
+-----------------------------------------------------+
| 1969-12-31 22:00:00                                 |
+-----------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/convert_tz/>

CONV
====

    Syntax
------

 
```
CONV(N,from_base,to_base)

```

Description
-----------

 Converts numbers between different number bases. Returns a string representation of the number *`N`*, converted from base *`from_base`* to base *`to_base`*.

 Returns `NULL` if any argument is `NULL`, or if the second or third argument are not in the allowed range.

 The argument *`N`* is interpreted as an integer, but may be specified as an integer or a string. The minimum base is 2 and the maximum base is 36. If *`to_base`* is a negative number, *`N`* is regarded as a signed number. Otherwise, *`N`* is treated as unsigned. `CONV()` works with 64-bit precision.

 Some shortcuts for this function are also available: `[BIN()](../bin/index)`, `[OCT()](../oct/index)`, `[HEX()](../hex/index)`, `[UNHEX()](../unhex/index)`. Also, MariaDB allows [binary](../binary-literals/index) literal values and [hexadecimal](../hexadecimal-literals/index) literal values.

 Examples
--------

 
```
SELECT CONV('a',16,2);
+----------------+
| CONV('a',16,2) |
+----------------+
| 1010           |
+----------------+

SELECT CONV('6E',18,8);
+-----------------+
| CONV('6E',18,8) |
+-----------------+
| 172             |
+-----------------+

SELECT CONV(-17,10,-18);
+------------------+
| CONV(-17,10,-18) |
+------------------+
| -H               |
+------------------+

SELECT CONV(12+'10'+'10'+0xa,10,10);
+------------------------------+
| CONV(12+'10'+'10'+0xa,10,10) |
+------------------------------+
| 42                           |
+------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/conv/>

COT
===

    Syntax
------

 
```
COT(X)

```

Description
-----------

 Returns the cotangent of X.

 Examples
--------

 
```
SELECT COT(42);
+--------------------+
| COT(42)            |
+--------------------+
| 0.4364167060752729 |
+--------------------+

SELECT COT(12);
+---------------------+
| COT(12)             |
+---------------------+
| -1.5726734063976893 |
+---------------------+

SELECT COT(0);
ERROR 1690 (22003): DOUBLE value is out of range in 'cot(0)'

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cot/>

COLUMN\_DELETE
==============

    Syntax
------

 
```
COLUMN_DELETE(dyncol_blob, column_nr, column_nr...);
COLUMN_DELETE(dyncol_blob, column_name, column_name...);

```

Description
-----------

 Deletes a [dynamic column](../dynamic-columns/index) with the specified name. Multiple names can be given. The return value is a dynamic column blob after the modification.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/column_delete/>

CONVEXHULL
==========

    A synonym for [ST\_CONVEXHULL](../st_convexhull/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/convexhull/>

COS
===

    Syntax
------

 
```
COS(X)

```

Description
-----------

 Returns the cosine of X, where X is given in radians.

 Examples
--------

 
```
SELECT COS(PI());
+-----------+
| COS(PI()) |
+-----------+
|        -1 |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cos/>

COUNT DISTINCT
==============

    Syntax
------

 
```
COUNT(DISTINCT expr,[expr...])

```
 Description
-----------

 Returns a count of the number of different non-NULL values.

 COUNT(DISTINCT) returns 0 if there were no matching rows.

 Although, from [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/), [COUNT](../count/index) can be used as a [window function](../window-functions/index), COUNT DISTINCT cannot be.

 Examples
--------

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT COUNT(*) FROM student;
+----------+
| COUNT(*) |
+----------+
|        8 |
+----------+

SELECT COUNT(DISTINCT (name)) FROM student;
+------------------------+
| COUNT(DISTINCT (name)) |
+------------------------+
|                      4 |
+------------------------+

```

See Also
--------

 * [SELECT](../select/index)
* [COUNT](../count/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/count-distinct/>

CRC32
=====

    Syntax
------

 <= [MariaDB 10.7](../what-is-mariadb-107/index)

 
```
CRC32(expr)

```

From [MariaDB 10.8](../what-is-mariadb-108/index)

 
```
CRC32([par,]expr)

```

Description
-----------

 Computes a cyclic redundancy check (CRC) value and returns a 32-bit unsigned value. The result is NULL if the argument is NULL. The argument is expected to be a string and (if possible) is treated as one if it is not.

 Uses the ISO 3309 polynomial that used by zlib and many others. [MariaDB 10.8](../what-is-mariadb-108/index) introduced the [CRC32C()](../crc32c/index) function, which uses the alternate Castagnoli polynomia.   
  


 
**MariaDB starting with [10.8](../what-is-mariadb-108/index)**Often, CRC is computed in pieces. To facilitate this, [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/) introduced an optional parameter: CRC32('MariaDB')=CRC32(CRC32('Maria'),'DB'). 

 
Examples
--------

 
```
SELECT CRC32('MariaDB');
+------------------+
| CRC32('MariaDB') |
+------------------+
|       4227209140 |
+------------------+

SELECT CRC32('mariadb');
+------------------+
| CRC32('mariadb') |
+------------------+
|       2594253378 |
+------------------+

```

From [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/)

 
```
SELECT CRC32(CRC32('Maria'),'DB');
+----------------------------+
| CRC32(CRC32('Maria'),'DB') |
+----------------------------+
|                 4227209140 |
+----------------------------+

```

See Also
--------

 * [CRC32C()](../crc32c/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/crc32/>

CRC32C
======

    
**MariaDB starting with [10.8](../what-is-mariadb-108/index)**Introduced in [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/) to compute a cyclic redundancy check (CRC) value using the Castagnoli polynomial.

 
Syntax
------

 
```
CRC32C([par,]expr)

```

Description
-----------

 MariaDB has always included a native unary function [CRC32()](../crc32/index) that computes the CRC-32 of a string using the ISO 3309 polynomial that used by zlib and many others.

 InnoDB and MyRocks use a different polynomial, which was implemented in SSE4.2 instructions that were introduced in the Intel Nehalem microarchitecture. This is commonly called CRC-32C (Castagnoli).

 The CRC32C function uses the Castagnoli polynomial.

 This allows `SELECT…INTO DUMPFILE` to be used for the creation of files with valid checksums, such as a logically empty InnoDB redo log file `ib_logfile0` corresponding to a particular log sequence number.

 The optional parameter allows the checksum to be computed in pieces: CRC32C('MariaDB')=CRC32C(CRC32C('Maria'),'DB').

 Examples
--------

 
```
SELECT CRC32C('MariaDB');
+-------------------+
| CRC32C('MariaDB') |
+-------------------+
|         809606978 |
+-------------------+

SELECT CRC32C(CRC32C('Maria'),'DB');
+------------------------------+
| CRC32C(CRC32C('Maria'),'DB') |
+------------------------------+
|                    809606978 |
+------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/crc32c/>

CROSSES
=======

    Syntax
------

 
```
Crosses(g1,g2)

```

Description
-----------

 Returns `1` if `g1` spatially crosses `g2`. Returns `NULL` if `g1` is a [Polygon](../polygon/index) or a [MultiPolygon](../multipolygon/index), or if `g2` is a [Point](../point/index) or a [MultiPoint](../multipoint/index). Otherwise, returns `0`.

 The term spatially crosses denotes a spatial relation between two given geometries that has the following properties:

 * The two geometries intersect
* Their intersection results in a geometry that has a dimension that is one less than the maximum dimension of the two given geometries
* Their intersection is not equal to either of the two given geometries

 CROSSES() is based on the original MySQL implementation, and uses object bounding rectangles, while [ST\_CROSSES()](../st_crosses/index) uses object shapes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/crosses/>

CUME\_DIST
==========

    Syntax
------

 
```
CUME_DIST() OVER ( 
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

```

Description
-----------

 CUME\_DIST() is a [window function](../window-functions/index) that returns the cumulative distribution of a given row. The following formula is used to calculate the value:

 
```
(number of rows <= current row) / (total rows)

```

Examples
--------

 
```
create table t1 (
  pk int primary key,
  a int,
  b int
);


insert into t1 values
( 1 , 0, 10),
( 2 , 0, 10),
( 3 , 1, 10),
( 4 , 1, 10),
( 8 , 2, 10),
( 5 , 2, 20),
( 6 , 2, 20),
( 7 , 2, 20),
( 9 , 4, 20),
(10 , 4, 20);

select pk, a, b,
    rank() over (order by a) as rank,
    percent_rank() over (order by a) as pct_rank,
    cume_dist() over (order by a) as cume_dist
from t1;
+----+------+------+------+--------------+--------------+
| pk | a    | b    | rank | pct_rank     | cume_dist    |
+----+------+------+------+--------------+--------------+
|  1 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  2 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  3 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  4 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  5 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  6 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  7 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  8 |    2 |   10 |    5 | 0.4444444444 | 0.8000000000 |
|  9 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
| 10 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
+----+------+------+------+--------------+--------------+

select pk, a, b,
       percent_rank() over (order by pk) as pct_rank,
       cume_dist() over (order by pk) as cume_dist
from t1 order by pk;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 0.1000000000 |
|  2 |    0 |   10 | 0.1111111111 | 0.2000000000 |
|  3 |    1 |   10 | 0.2222222222 | 0.3000000000 |
|  4 |    1 |   10 | 0.3333333333 | 0.4000000000 |
|  5 |    2 |   20 | 0.4444444444 | 0.5000000000 |
|  6 |    2 |   20 | 0.5555555556 | 0.6000000000 |
|  7 |    2 |   20 | 0.6666666667 | 0.7000000000 |
|  8 |    2 |   10 | 0.7777777778 | 0.8000000000 |
|  9 |    4 |   20 | 0.8888888889 | 0.9000000000 |
| 10 |    4 |   20 | 1.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

select pk, a, b,
        percent_rank() over (partition by a order by a) as pct_rank,
        cume_dist() over (partition by a order by a) as cume_dist
from t1;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  2 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  3 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  4 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  5 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  6 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  7 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  8 |    2 |   10 | 0.0000000000 | 1.0000000000 |
|  9 |    4 |   20 | 0.0000000000 | 1.0000000000 |
| 10 |    4 |   20 | 0.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

```

See Also
--------

 * [PERCENT\_RANK()](../percent_rank/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cume_dist/>

CURRENT\_DATE
=============

    Syntax
------

 
```
CURRENT_DATE, CURRENT_DATE()

```

Description
-----------

 `CURRENT_DATE` and `CURRENT_DATE()` are synonyms for [CURDATE()](../curdate/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current_date/>

CURRENT\_ROLE
=============

    Syntax
------

 
```
CURRENT_ROLE, CURRENT_ROLE()

```

Description
-----------

 Returns the current [role](../roles/index) name. This determines your access privileges. The return value is a string in the utf8 [character set](../data-types-character-sets-and-collations/index).

 If there is no current role, NULL is returned.

 The output of `SELECT CURRENT_ROLE` is equivalent to the contents of the [ENABLED\_ROLES](../information-schema-enabled_roles-table/index) Information Schema table.

 [USER()](../user/index) returns the combination of user and host used to login. [CURRENT\_USER()](../current_user/index) returns the account used to determine current connection's privileges.

 Examples
--------

 
```
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE staff;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| staff        |
+--------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current_role/>

CURRENT\_TIME
=============

    Syntax
------

 
```
CURRENT_TIME
CURRENT_TIME([precision])

```

Description
-----------

 `CURRENT_TIME` and `CURRENT_TIME()` are synonyms for `[CURTIME()](../curtime/index)`.

 See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current_time/>

CURRENT\_TIMESTAMP
==================

    Syntax
------

 
```
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])

```

Description
-----------

 `CURRENT_TIMESTAMP` and `CURRENT_TIMESTAMP()` are synonyms for `[NOW()](../now/index)`.

 See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)
* The [TIMESTAMP](../timestamp/index) data type

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current_timestamp/>

CURRENT\_USER
=============

    Syntax
------

 
```
CURRENT_USER, CURRENT_USER()

```

Description
-----------

 Returns the user name and host name combination for the MariaDB account that the server used to authenticate the current client. This account determines your access privileges. The return value is a string in the utf8 [character set](../data-types-character-sets-and-collations/index).

 The value of `CURRENT_USER()` can differ from the value of [USER()](../user/index). [CURRENT\_ROLE()](../current_role/index) returns the current active role.

 Examples
--------

 
```
shell> mysql --user="anonymous"

select user(),current_user();
+---------------------+----------------+
| user()              | current_user() |
+---------------------+----------------+
| anonymous@localhost | @localhost     |
+---------------------+----------------+

```

When calling `CURRENT_USER()` in a stored procedure, it returns the owner of the stored procedure, as defined with `DEFINER`.

 See Also
--------

 * [USER()](../user/index)
* [CREATE PROCEDURE](../create-procedure/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current_user/>

CURTIME
=======

    Syntax
------

 
```
CURTIME([precision])

```

Description
-----------

 Returns the current time as a value in 'HH:MM:SS' or HHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current [time zone](../time-zones/index).

 The optional *precision* determines the microsecond precision. See [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 Examples
--------

 
```
SELECT CURTIME();
+-----------+
| CURTIME() |
+-----------+
| 12:45:39  |
+-----------+

SELECT CURTIME() + 0;
+---------------+
| CURTIME() + 0 |
+---------------+
| 124545.000000 |
+---------------+

```

With precision:

 
```
SELECT CURTIME(2);
+-------------+
| CURTIME(2)  |
+-------------+
| 09:49:08.09 |
+-------------+

```

See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/curtime/>

DATABASE
========

    Syntax
------

 
```
DATABASE()
SCHEMA()

```

Description
-----------

 Returns the default (current) database name as a string in the utf8 [character set](../data-types-character-sets-and-collations/index). If there is no default database, DATABASE() returns NULL. Within a [stored routine](../stored-routines/index), the default database is the database that the routine is associated with, which is not necessarily the same as the database that is the default in the calling context.

 SCHEMA() is a synonym for DATABASE().

 To select a default database, the [USE](../use/index) statement can be run. Another way to set the default database is specifying its name at [mariadb](../mariadb-command-line-client/index) command line client startup.

 Examples
--------

 
```
SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| NULL       |
+------------+

USE test;
Database changed

SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| test       |
+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database/>

DATE FUNCTION
=============

    Syntax
------

 
```
DATE(expr)

```

Description
-----------

 Extracts the date part of the [date](../date/index) or [datetime](../datetime/index) expression *expr*. Returns NULL and throws a warning when passed an invalid date.

 Examples
--------

 
```
SELECT DATE('2013-07-18 12:21:32');
+-----------------------------+
| DATE('2013-07-18 12:21:32') |
+-----------------------------+
| 2013-07-18                  |
+-----------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date-function/>

DATEDIFF
========

    Syntax
------

 
```
DATEDIFF(expr1,expr2)

```

Description
-----------

 `DATEDIFF()` returns (*expr1* – *expr2*) expressed as a value in days from one date to the other. *expr1* and *expr2* are date or date-and-time expressions. Only the date parts of the values are used in the calculation.

 Examples
--------

 
```
SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
+----------------------------------------------+
| DATEDIFF('2007-12-31 23:59:59','2007-12-30') |
+----------------------------------------------+
|                                            1 |
+----------------------------------------------+

SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
+----------------------------------------------+
| DATEDIFF('2010-11-30 23:59:59','2010-12-31') |
+----------------------------------------------+
|                                          -31 |
+----------------------------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2011-05-23 10:56:05 |
+---------------------+

SELECT d, DATEDIFF(NOW(),d) FROM t1;
+---------------------+-------------------+
| d                   | DATEDIFF(NOW(),d) |
+---------------------+-------------------+
| 2007-01-30 21:31:07 |              1574 |
| 1983-10-15 06:42:51 |             10082 |
| 2011-04-21 12:34:56 |                32 |
| 2011-10-30 06:31:41 |              -160 |
| 2011-01-30 14:03:25 |               113 |
| 2004-10-07 11:19:34 |              2419 |
+---------------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/datediff/>

DATE\_ADD
=========

    Syntax
------

 
```
DATE_ADD(date,INTERVAL expr unit)

```
 Description
-----------

 Performs date arithmetic. The *date* argument specifies the starting date or datetime value. *expr* is an expression specifying the interval value to be added or subtracted from the starting date. *expr* is a string; it may start with a "`-`" for negative intervals. *unit* is a keyword indicating the units in which the expression should be interpreted. See [Date and Time Units](../date-and-time-units/index) for a complete list of permitted units. 

 Examples
--------

 
```
SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '2008-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 2009-01-01 00:00:00                       |
+-------------------------------------------+

```


```
SELECT INTERVAL 1 DAY + '2008-12-31';
+-------------------------------+
| INTERVAL 1 DAY + '2008-12-31' |
+-------------------------------+
| 2009-01-01                    |
+-------------------------------+

```


```
SELECT '2005-01-01' - INTERVAL 1 SECOND;
+----------------------------------+
| '2005-01-01' - INTERVAL 1 SECOND |
+----------------------------------+
| 2004-12-31 23:59:59              |
+----------------------------------+

```


```
SELECT DATE_ADD('2000-12-31 23:59:59', INTERVAL 1 SECOND);
+----------------------------------------------------+
| DATE_ADD('2000-12-31 23:59:59', INTERVAL 1 SECOND) |
+----------------------------------------------------+
| 2001-01-01 00:00:00                                |
+----------------------------------------------------+

```


```
SELECT DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY);
+-------------------------------------------------+
| DATE_ADD('2010-12-31 23:59:59', INTERVAL 1 DAY) |
+-------------------------------------------------+
| 2011-01-01 23:59:59                             |
+-------------------------------------------------+

```


```
SELECT DATE_ADD('2100-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND);
+---------------------------------------------------------------+
| DATE_ADD('2100-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND) |
+---------------------------------------------------------------+
| 2101-01-01 00:01:00                                           |
+---------------------------------------------------------------+

```


```
SELECT DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR);
+------------------------------------------------------------+
| DATE_ADD('1900-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR) |
+------------------------------------------------------------+
| 1899-12-30 14:00:00                                        |
+------------------------------------------------------------+

```


```
SELECT DATE_ADD('1992-12-31 23:59:59.000002', INTERVAL '1.999999' SECOND_MICROSECOND);
+--------------------------------------------------------------------------------+
| DATE_ADD('1992-12-31 23:59:59.000002', INTERVAL '1.999999' SECOND_MICROSECOND) |
+--------------------------------------------------------------------------------+
| 1993-01-01 00:00:01.000001                                                     |
+--------------------------------------------------------------------------------+

```

See Also
--------

 * [DATE\_SUB](../date_sub/index)
* [ADD\_MONTHS](../add_months/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date_add/>

DATE\_FORMAT
============

    Syntax
------

 
```
DATE_FORMAT(date, format[, locale])

```
 Description
-----------

 Formats the date value according to the format string. 

 The language used for the names is controlled by the value of the [lc\_time\_names](../server-system-variables/index#lc_time_names) system variable. See [server locale](../server-locale/index) for more on the supported locales.

 The options that can be used by DATE\_FORMAT(), as well as its inverse [STR\_TO\_DATE](../str_to_date/index)() and the [FROM\_UNIXTIME()](../from_unixtime/index) function, are:

 


| Option | Description |
| --- | --- |
| `%a` | Short weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%b` | Short form month name in current locale. For locale en\_US this is one of: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov or Dec. |
| `%c` | Month with 1 or 2 digits. |
| `%D` | Day with English suffix 'th', 'nd', 'st' or 'rd''. (1st, 2nd, 3rd...). |
| `%d` | Day with 2 digits. |
| `%e` | Day with 1 or 2 digits. |
| `%f` | [Microseconds](../microseconds-in-mariadb/index) 6 digits. |
| `%H` | Hour with 2 digits between 00-23. |
| `%h` | Hour with 2 digits between 01-12. |
| `%I` | Hour with 2 digits between 01-12. |
| `%i` | Minute with 2 digits. |
| `%j` | Day of the year (001-366) |
| `%k` | Hour with 1 digits between 0-23. |
| `%l` | Hour with 1 digits between 1-12. |
| `%M` | Full month name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%m` | Month with 2 digits. |
| `%p` | AM/PM according to current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%r` | Time in 12 hour format, followed by AM/PM. Short for '%I:%i:%S %p'. |
| `%S` | Seconds with 2 digits. |
| `%s` | Seconds with 2 digits. |
| `%T` | Time in 24 hour format. Short for '%H:%i:%S'. |
| `%U` | Week number (00-53), when first day of the week is Sunday. |
| `%u` | Week number (00-53), when first day of the week is Monday. |
| `%V` | Week number (01-53), when first day of the week is Sunday. Used with %X. |
| `%v` | Week number (01-53), when first day of the week is Monday. Used with %x. |
| `%W` | Full weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%w` | Day of the week. 0 = Sunday, 6 = Saturday. |
| `%X` | Year with 4 digits when first day of the week is Sunday. Used with %V. |
| `%x` | Year with 4 digits when first day of the week is Monday. Used with %v. |
| `%Y` | Year with 4 digits. |
| `%y` | Year with 2 digits. |
| `%#` | For [str\_to\_date](../str_to_date/index)(), skip all numbers. |
| `%.` | For [str\_to\_date](../str_to_date/index)(), skip all punctation characters. |
| `%@` | For [str\_to\_date](../str_to_date/index)(), skip all alpha characters. |
| `%%` | A literal `%` character. |

 
To get a date in one of the standard formats, `[GET\_FORMAT()](../get_format/index)` can be used.

 Examples
--------

 
```
SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
+------------------------------------------------+
| DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y') |
+------------------------------------------------+
| Sunday October 2009                            |
+------------------------------------------------+

SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
+------------------------------------------------+
| DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s') |
+------------------------------------------------+
| 22:23:00                                       |
+------------------------------------------------+

SELECT DATE_FORMAT('1900-10-04 22:23:00', '%D %y %a %d %m %b %j');
+------------------------------------------------------------+
| DATE_FORMAT('1900-10-04 22:23:00', '%D %y %a %d %m %b %j') |
+------------------------------------------------------------+
| 4th 00 Thu 04 10 Oct 277                                   |
+------------------------------------------------------------+

SELECT DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w');
+------------------------------------------------------------+
| DATE_FORMAT('1997-10-04 22:23:00', '%H %k %I %r %T %S %w') |
+------------------------------------------------------------+
| 22 22 10 10:23:00 PM 22:23:00 00 6                         |
+------------------------------------------------------------+

SELECT DATE_FORMAT('1999-01-01', '%X %V');
+------------------------------------+
| DATE_FORMAT('1999-01-01', '%X %V') |
+------------------------------------+
| 1998 52                            |
+------------------------------------+

SELECT DATE_FORMAT('2006-06-00', '%d');
+---------------------------------+
| DATE_FORMAT('2006-06-00', '%d') |
+---------------------------------+
| 00                              |
+---------------------------------+

```

Optionally, the locale can be explicitly specified as the third DATE\_FORMAT() argument. Doing so makes the function independent from the session settings, and the three argument version of DATE\_FORMAT() can be used in virtual indexed and persistent [generated-columns](../generated-columns/index):

 
```
SELECT DATE_FORMAT('2006-01-01', '%W', 'el_GR');
+------------------------------------------+
| DATE_FORMAT('2006-01-01', '%W', 'el_GR') |
+------------------------------------------+
| Κυριακή                                  |
+------------------------------------------+

```

See Also
--------

 * [STR\_TO\_DATE()](../str_to_date/index)
* [FROM\_UNIXTIME()](../from_unixtime/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date_format/>

DIMENSION
=========

    A synonym for [ST\_DIMENSION](../st_dimension/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dimension/>

DATE\_SUB
=========

    Syntax
------

 
```
DATE_SUB(date,INTERVAL expr unit)

```

Description
-----------

 Performs date arithmetic. The *date* argument specifies the starting date or datetime value. *expr* is an expression specifying the interval value to be added or subtracted from the starting date. *expr* is a string; it may start with a "`-`" for negative intervals. *unit* is a keyword indicating the units in which the expression should be interpreted. See [Date and Time Units](../date-and-time-units/index) for a complete list of permitted units. 

 See also `[DATE\_ADD()](../date_add/index)`.

 Examples
--------

 
```
SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_SUB('1998-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 1997-12-02                              |
+-----------------------------------------+

```


```
SELECT DATE_SUB('2005-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND);
+----------------------------------------------------------------+
| DATE_SUB('2005-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND) |
+----------------------------------------------------------------+
| 2004-12-30 22:58:59                                            |
+----------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date_sub/>

DAYOFYEAR
=========

    Syntax
------

 
```
DAYOFYEAR(date)

```

Description
-----------

 Returns the day of the year for date, in the range 1 to 366.

 Examples
--------

 
```
SELECT DAYOFYEAR('2018-02-16');
+-------------------------+
| DAYOFYEAR('2018-02-16') |
+-------------------------+
|                      47 |
+-------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dayofyear/>

DIV
===

    Syntax
------

 
```
DIV

```

Description
-----------

 Integer division. Similar to [FLOOR()](../floor/index), but is safe with [BIGINT](../bigint/index) values. Incorrect results may occur for non-integer operands that exceed BIGINT range.

 If the `ERROR_ON_DIVISION_BY_ZERO` [SQL\_MODE](../sql-mode/index) is used, a division by zero produces an error. Otherwise, it returns NULL.

 The remainder of a division can be obtained using the [MOD](../mod/index) operator.

 Examples
--------

 
```
SELECT 300 DIV 7;
+-----------+
| 300 DIV 7 |
+-----------+
|        42 |
+-----------+

SELECT 300 DIV 0;
+-----------+
| 300 DIV 0 |
+-----------+
|      NULL |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/div/>

DEFAULT
=======

    Syntax
------

 
```
DEFAULT(col_name)

```

Description
-----------

 Returns the default value for a table column. If the column has no default value (and is not NULLABLE - NULLABLE fields have a NULL default), an error is returned.

 For integer columns using [AUTO\_INCREMENT](../auto_increment/index), `0` is returned.

 When using `DEFAULT` as a value to set in an [INSERT](../insert/index) or [UPDATE](../update/index) statement, you can use the bare keyword `DEFAULT` without the parentheses and argument to refer to the column in context. You can only use `DEFAULT` as a bare keyword if you are using it alone without a surrounding expression or function.

 Examples
--------

 Select only non-default values for a column:

 
```
SELECT i FROM t WHERE i != DEFAULT(i);

```

Update values to be one greater than the default value:

 
```
UPDATE t SET i = DEFAULT(i)+1 WHERE i < 100;

```

When referring to the default value exactly in `UPDATE` or `INSERT`, you can omit the argument:

 
```
INSERT INTO t (i) VALUES (DEFAULT);
UPDATE t SET i = DEFAULT WHERE i < 100;

```


```
CREATE OR REPLACE TABLE t (
  i INT NOT NULL AUTO_INCREMENT, 
  j INT NOT NULL, 
  k INT DEFAULT 3, 
  l INT NOT NULL DEFAULT 4, 
  m INT, 
  PRIMARY KEY (i)
);

DESC t;
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| i     | int(11) | NO   | PRI | NULL    | auto_increment |
| j     | int(11) | NO   |     | NULL    |                |
| k     | int(11) | YES  |     | 3       |                |
| l     | int(11) | NO   |     | 4       |                |
| m     | int(11) | YES  |     | NULL    |                |
+-------+---------+------+-----+---------+----------------+

INSERT INTO t (j) VALUES (1);
INSERT INTO t (j,m) VALUES (2,2);
INSERT INTO t (j,l,m) VALUES (3,3,3);

SELECT * FROM t;
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
| 3 | 3 |    3 | 3 |    3 |
+---+---+------+---+------+

SELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m) FROM t;
+------------+------------+-------------+------------+
| DEFAULT(i) | DEFAULT(k) | DEFAULT (l) | DEFAULT(m) |
+------------+------------+-------------+------------+
|          0 |          3 |           4 |       NULL |
|          0 |          3 |           4 |       NULL |
|          0 |          3 |           4 |       NULL |
+------------+------------+-------------+------------+

SELECT DEFAULT(i), DEFAULT(k), DEFAULT (l), DEFAULT(m), DEFAULT(j)  FROM t;
ERROR 1364 (HY000): Field 'j' doesn't have a default value

SELECT * FROM t WHERE i = DEFAULT(i);
Empty set (0.001 sec)

SELECT * FROM t WHERE j = DEFAULT(j);
ERROR 1364 (HY000): Field 'j' doesn't have a default value

SELECT * FROM t WHERE k = DEFAULT(k);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
| 3 | 3 |    3 | 3 |    3 |
+---+---+------+---+------+

SELECT * FROM t WHERE l = DEFAULT(l);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
| 2 | 2 |    3 | 4 |    2 |
+---+---+------+---+------+

SELECT * FROM t WHERE m = DEFAULT(m);
Empty set (0.001 sec)

SELECT * FROM t WHERE m <=> DEFAULT(m);
+---+---+------+---+------+
| i | j | k    | l | m    |
+---+---+------+---+------+
| 1 | 1 |    3 | 4 | NULL |
+---+---+------+---+------+

```

See Also
--------

 * [CREATE TABLE DEFAULT Clause](../create-table/index#default-column-option)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/default/>

ELT
===

    Syntax
------

 
```
ELT(N, str1[, str2, str3,...])

```

Description
-----------

 Takes a numeric argument and a series of string arguments. Returns the string that corresponds to the given numeric position. For instance, it returns `str1` if `N` is 1, `str2` if `N` is 2, and so on. If the numeric argument is a `[FLOAT](../float/index)`, MariaDB rounds it to the nearest `[INTEGER](../int/index)`. If the numeric argument is less than 1, greater than the total number of arguments, or not a number, `ELT()` returns `NULL`. It must have at least two arguments.

 It is complementary to the `[FIELD()](../field/index)` function.

 Examples
--------

 
```
SELECT ELT(1, 'ej', 'Heja', 'hej', 'foo');
+------------------------------------+
| ELT(1, 'ej', 'Heja', 'hej', 'foo') |
+------------------------------------+
| ej                                 |
+------------------------------------+

SELECT ELT(4, 'ej', 'Heja', 'hej', 'foo');
+------------------------------------+
| ELT(4, 'ej', 'Heja', 'hej', 'foo') |
+------------------------------------+
| foo                                |
+------------------------------------+

```

See also
--------

 * [FIND\_IN\_SET()](../find_in_set/index) function. Returns the position of a string in a set of strings.
* [FIELD()](../field/index) function. Returns the index position of a string in a list.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/elt/>

ENCODE
======

    Syntax
------

 
```
ENCODE(str,pass_str)

```

Description
-----------

 
ENCODE is not considered cryptographically secure, and should not be used for password encryption.

 
Encrypt `str` using `pass_str` as the password. To decrypt the result, use `[DECODE()](../decode/index)`.

 The result is a binary string of the same length as `str`.

 The strength of the encryption is based on how good the random generator is. 

 It is not recommended to rely on the encryption performed by the ENCODE function. Using a salt value (changed when a password is updated) will improve matters somewhat, but for storing passwords, consider a more cryptographically secure function, such as [SHA2()](../sha2/index).

 Examples
--------

 
```
ENCODE('not so secret text', CONCAT('random_salt','password'))

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encode/>

DAYNAME
=======

    Syntax
------

 
```
DAYNAME(date)

```

Description
-----------

 Returns the name of the weekday for date. The language used for the name is controlled by the value of the [lc\_time\_names](../server-system-variables/index#lc_time_names) system variable. See [server locale](../server-locale/index) for more on the supported locales.

 Examples
--------

 
```
SELECT DAYNAME('2007-02-03');
+-----------------------+
| DAYNAME('2007-02-03') |
+-----------------------+
| Saturday              |
+-----------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d, DAYNAME(d) FROM t1;
+---------------------+------------+
| d                   | DAYNAME(d) |
+---------------------+------------+
| 2007-01-30 21:31:07 | Tuesday    |
| 1983-10-15 06:42:51 | Saturday   |
| 2011-04-21 12:34:56 | Thursday   |
| 2011-10-30 06:31:41 | Sunday     |
| 2011-01-30 14:03:25 | Sunday     |
| 2004-10-07 11:19:34 | Thursday   |
+---------------------+------------+

```

Changing the locale:

 
```
SET lc_time_names = 'fr_CA';

SELECT DAYNAME('2013-04-01');
+-----------------------+
| DAYNAME('2013-04-01') |
+-----------------------+
| lundi                 |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dayname/>

DECODE\_HISTOGRAM
=================

    Syntax
------

 
```
DECODE_HISTOGRAM(hist_type,histogram)

```

Description
-----------

 Returns a string of comma separated numeric values corresponding to a probability distribution represented by the histogram of type `hist_type` (`SINGLE_PREC_HB` or `DOUBLE_PREC_HB`). The `hist_type` and `histogram` would be commonly used from the [mysql.column\_stats table](../mysqlcolumn_stats-table/index).

 See [Histogram Based Statistics](../histogram-based-statistics/index) for details.

 Examples
--------

 
```
CREATE TABLE origin (
  i INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  v INT UNSIGNED NOT NULL
);

INSERT INTO origin(v) VALUES 
  (1),(2),(3),(4),(5),(10),(20),
  (30),(40),(50),(60),(70),(80),
  (90),(100),(200),(400),(800);

SET histogram_size=10,histogram_type=SINGLE_PREC_HB;

ANALYZE TABLE origin PERSISTENT FOR ALL;
+-------------+---------+----------+-----------------------------------------+
| Table       | Op      | Msg_type | Msg_text                                |
+-------------+---------+----------+-----------------------------------------+
| test.origin | analyze | status   | Engine-independent statistics collected |
| test.origin | analyze | status   | OK                                      |
+-------------+---------+----------+-----------------------------------------+

SELECT db_name,table_name,column_name,hist_type,
  hex(histogram),decode_histogram(hist_type,histogram) 
  FROM mysql.column_stats WHERE db_name='test' and table_name='origin';
+---------+------------+-------------+----------------+----------------------+-------------------------------------------------------------------+
| db_name | table_name | column_name | hist_type      | hex(histogram)       | decode_histogram(hist_type,histogram)                             |
+---------+------------+-------------+----------------+----------------------+-------------------------------------------------------------------+
| test    | origin     | i           | SINGLE_PREC_HB | 0F2D3C5A7887A5C3D2F0 | 0.059,0.118,0.059,0.118,0.118,0.059,0.118,0.118,0.059,0.118,0.059 |
| test    | origin     | v           | SINGLE_PREC_HB | 000001060C0F161C1F7F | 0.000,0.000,0.004,0.020,0.024,0.012,0.027,0.024,0.012,0.376,0.502 |
+---------+------------+-------------+----------------+----------------------+-------------------------------------------------------------------+

SET histogram_size=20,histogram_type=DOUBLE_PREC_HB;

ANALYZE TABLE origin PERSISTENT FOR ALL;
+-------------+---------+----------+-----------------------------------------+
| Table       | Op      | Msg_type | Msg_text                                |
+-------------+---------+----------+-----------------------------------------+
| test.origin | analyze | status   | Engine-independent statistics collected |
| test.origin | analyze | status   | OK                                      |
+-------------+---------+----------+-----------------------------------------+

SELECT db_name,table_name,column_name,
  hist_type,hex(histogram),decode_histogram(hist_type,histogram) 
  FROM mysql.column_stats WHERE db_name='test' and table_name='origin';
+---------+------------+-------------+----------------+------------------------------------------+-----------------------------------------------------------------------------------------+
| db_name | table_name | column_name | hist_type      | hex(histogram)                           | decode_histogram(hist_type,histogram)                                                   |
+---------+------------+-------------+----------------+------------------------------------------+-----------------------------------------------------------------------------------------+
| test    | origin     | i           | DOUBLE_PREC_HB | 0F0F2D2D3C3C5A5A78788787A5A5C3C3D2D2F0F0 | 0.05882,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765,0.11765,0.05882,0.11765,0.05882 |
| test    | origin     | v           | DOUBLE_PREC_HB | 5200F600480116067E0CB30F1B16831CB81FD67F | 0.00125,0.00250,0.00125,0.01877,0.02502,0.01253,0.02502,0.02502,0.01253,0.37546,0.50063 |

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/decode_histogram/>

DAYOFMONTH
==========

    Syntax
------

 
```
DAYOFMONTH(date)

```

Description
-----------

 Returns the day of the month for date, in the range `1` to `31`, or `0` for dates such as `'0000-00-00'` or `'2008-00-00'` which have a zero day part.

 DAY() is a synonym.

 Examples
--------

 
```
SELECT DAYOFMONTH('2007-02-03');
+--------------------------+
| DAYOFMONTH('2007-02-03') |
+--------------------------+
|                        3 |
+--------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d FROM t1 where DAYOFMONTH(d) = 30;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dayofmonth/>

DES\_DECRYPT
============

    
DES\_DECRYPT has been deprecated from [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/), and will be removed in a future release.

 
Syntax
------

 
```
DES_DECRYPT(crypt_str[,key_str])

```

Description
-----------

 Decrypts a string encrypted with `[DES\_ENCRYPT()](../des_encrypt/index)`. If an error occurs, this function returns `NULL`.

 This function works only if MariaDB has been configured with [TLS support](../secure-connections-overview/index).

 If no `key_str` argument is given, `DES_DECRYPT()` examines the first byte of the encrypted string to determine the DES key number that was used to encrypt the original string, and then reads the key from the DES key file to decrypt the message. For this to work, the user must have the SUPER privilege. The key file can be specified with the `--des-key-file` server option.

 If you pass this function a `key_str` argument, that string is used as the key for decrypting the message.

 If the `crypt_str` argument does not appear to be an encrypted string, MariaDB returns the given crypt\_str.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/des_decrypt/>

DECODE
======

    Syntax
------

 
```
DECODE(crypt_str,pass_str)

```

In [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/):

 
```
DECODE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...] [default_expr])

```

In all modes from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/):

 
```
DECODE_ORACLE(expr, search_expr, result_expr [, search_expr2, result_expr2 ...] [default_expr])

```

Description
-----------

 In the default mode, `DECODE` decrypts the encrypted string *crypt\_str* using *pass\_str* as the password. *crypt\_str* should be a string returned from [ENCODE()](../encode/index). The resulting string will be the original string only if *pass\_str* is the same.

 In [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), `DECODE` compares *expr* to the search expressions, in order. If it finds a match, the corresponding result expression is returned. If no matches are found, the default expression is returned, or NULL if no default is provided.

 NULLs are treated as equivalent.

 `DECODE_ORACLE` is a synonym for the Oracle-mode version of the function, and is available in all modes.

 Examples
--------

 From [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/):

 
```
SELECT DECODE_ORACLE(2+1,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+1,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| found1                                                 |
+--------------------------------------------------------+

SELECT DECODE_ORACLE(2+4,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+4,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| found2                                                 |
+--------------------------------------------------------+

SELECT DECODE_ORACLE(2+2,3*1,'found1',3*2,'found2','default');
+--------------------------------------------------------+
| DECODE_ORACLE(2+2,3*1,'found1',3*2,'found2','default') |
+--------------------------------------------------------+
| default                                                |
+--------------------------------------------------------+

```

Nulls are treated as equivalent:

 
```
SELECT DECODE_ORACLE(NULL,NULL,'Nulls are equivalent','Nulls are not equivalent');
+----------------------------------------------------------------------------+
| DECODE_ORACLE(NULL,NULL,'Nulls are equivalent','Nulls are not equivalent') |
+----------------------------------------------------------------------------+
| Nulls are equivalent                                                       |
+----------------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/decode/>

ENCRYPT
=======

    Syntax
------

 
```
ENCRYPT(str[,salt])

```

Description
-----------

 Encrypts a string using the Unix crypt() system call, returning an encrypted binary string. The `salt` argument should be a string with at least two characters or the returned result will be NULL. If no salt argument is given, a random value of sufficient length is used.

 It is not recommended to use ENCRYPT() with utf16, utf32 or ucs2 multi-byte character sets because the crypt() system call expects a string terminated with a zero byte.

 Note that the underlying crypt() system call may have some limitations, such as ignoring all but the first eight characters.

 If the [have\_crypt](../server-system-variables/index#have_crypt) system variable is set to `NO` (because the crypt() system call is not available), the ENCRYPT function will always return NULL.

 Examples
--------

 
```
SELECT ENCRYPT('encrypt me');
+-----------------------+
| ENCRYPT('encrypt me') |
+-----------------------+
| 4I5BsEx0lqTDk         |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encrypt/>

EQUALS
======

    Syntax
------

 
```
Equals(g1,g2)

```

From [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/):

 
```
MBREQUALS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether *`g1`* is spatially equal to *`g2`*.

 EQUALS() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_EQUALS()](index) uses object shapes.

 From [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), `MBREQUALS` is a synonym for `Equals`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/equals/>

ST\_ENDPOINT
============

    Syntax
------

 
```
ST_EndPoint(ls)
EndPoint(ls)

```

Description
-----------

 Returns the [Point](../point/index) that is the endpoint of the [LineString](../linestring/index) value `ls`.

 `ST_EndPoint()` and `EndPoint()` are synonyms.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(EndPoint(GeomFromText(@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@ls))) |
+-------------------------------------+
| POINT(3 3)                          |
+-------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/endpoint/>

DES\_ENCRYPT
============

    
DES\_ENCRYPT has been deprecated from [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/), and will be removed in a future release.

 
Syntax
------

 
```
DES_ENCRYPT(str[,{key_num|key_str}])

```

Description
-----------

 Encrypts the string with the given key using the Triple-DES algorithm.

 This function works only if MariaDB has been configured with [TLS support](../secure-connections-overview/index).

 The encryption key to use is chosen based on the second argument to `DES_ENCRYPT()`, if one was given. With no argument, the first key from the DES key file is used. With a *`key_num`* argument, the given key number (0-9) from the DES key file is used. With a *`key_str`* argument, the given key string is used to encrypt *`str`*. 

 The key file can be specified with the `--des-key-file` server option.

 The return string is a binary string where the first character is `CHAR(128 | key_num)`. If an error occurs, `DES_ENCRYPT()` returns `NULL`.

 The 128 is added to make it easier to recognize an encrypted key. If you use a string key, *`key_num`* is 127.

 The string length for the result is given by this formula:

 
```
new_len = orig_len + (8 - (orig_len % 8)) + 1

```

Each line in the DES key file has the following format:

 
```
key_num des_key_str

```

Each *`key_num`* value must be a number in the range from 0 to 9. Lines in the file may be in any order. *`des_key_str`* is the string that is used to encrypt the message. There should be at least one space between the number and the key. The first key is the default key that is used if you do not specify any key argument to `DES_ENCRYPT()`.

 You can tell MariaDB to read new key values from the key file with the FLUSH DES\_KEY\_FILE statement. This requires the RELOAD privilege.

 One benefit of having a set of default keys is that it gives applications a way to check for the existence of encrypted column values, without giving the end user the right to decrypt those values.

 Examples
--------

 
```
SELECT customer_address FROM customer_table 
   WHERE crypted_credit_card = DES_ENCRYPT('credit_card_number');

```

See Also
--------

 * [DES\_DECRYPT()](../des_decrypt/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/des_encrypt/>

EXP
===

    Syntax
------

 
```
EXP(X)

```

Description
-----------

 Returns the value of e (the base of natural logarithms) raised to the power of X. The inverse of this function is [LOG()](../log/index) (using a single argument only) or [LN()](../ln/index).

 If `X` is `NULL`, this function returns `NULL`.

 Examples
--------

 
```
SELECT EXP(2);
+------------------+
| EXP(2)           |
+------------------+
| 7.38905609893065 |
+------------------+

SELECT EXP(-2);
+--------------------+
| EXP(-2)            |
+--------------------+
| 0.1353352832366127 |
+--------------------+

SELECT EXP(0);
+--------+
| EXP(0) |
+--------+
|      1 |
+--------+

SELECT EXP(NULL);
+-----------+
| EXP(NULL) |
+-----------+
|      NULL |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/exp/>

FIELD
=====

    Syntax
------

 
```
FIELD(pattern, str1[,str2,...])

```

Description
-----------

 Returns the index position of the string or number matching the given pattern. Returns `0` in the event that none of the arguments match the pattern. Raises an Error 1582 if not given at least two arguments.

 When all arguments given to the `FIELD()` function are strings, they are treated as case-insensitive. When all the arguments are numbers, they are treated as numbers. Otherwise, they are treated as doubles. 

 If the given pattern occurs more than once, the `FIELD()` function only returns the index of the first instance. If the given pattern is `NULL`, the function returns `0`, as a `NULL` pattern always fails to match.

 This function is complementary to the `[ELT()](../elt/index)` function.

 Examples
--------

 
```
SELECT FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo') 
   AS 'Field Results';
+---------------+
| Field Results | 
+---------------+
|             2 |
+---------------+

SELECT FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo')
   AS 'Field Results';
+---------------+
| Field Results | 
+---------------+
|             0 |
+---------------+

SELECT FIELD(1, 2, 3, 4, 5, 1) AS 'Field Results';
+---------------+
| Field Results |
+---------------+
|             5 |
+---------------+

SELECT FIELD(NULL, 2, 3) AS 'Field Results';
+---------------+
| Field Results |
+---------------+
|             0 |
+---------------+

SELECT FIELD('fail') AS 'Field Results';
Error 1582 (42000): Incorrect parameter count in call
to native function 'field'

```

See also
--------

 * [ELT()](../elt/index) function. Returns the N'th element from a set of strings.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/field/>

DEGREES
=======

    Syntax
------

 
```
DEGREES(X)

```

Description
-----------

 Returns the argument *`X`*, converted from radians to degrees.

 This is the converse of the [RADIANS()](../radians/index) function.

 Examples
--------

 
```
SELECT DEGREES(PI());
+---------------+
| DEGREES(PI()) |
+---------------+
|           180 |
+---------------+

SELECT DEGREES(PI() / 2);
+-------------------+
| DEGREES(PI() / 2) |
+-------------------+
|                90 |
+-------------------+

SELECT DEGREES(45);
+-----------------+
| DEGREES(45)     |
+-----------------+
| 2578.3100780887 |
+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/degrees/>

DENSE\_RANK
===========

    Syntax
------

 
```
DENSE_RANK() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 

```

Description
-----------

 DENSE\_RANK() is a [window function](../window-functions/index) that displays the number of a given row, starting at one and following the [ORDER BY](../order-by/index) sequence of the window function, with identical values receiving the same result. Unlike the [RANK()](../rank/index) function, there are no skipped values if the preceding results are identical. It is also similar to the [ROW\_NUMBER()](../row_number/index) function except that in that function, identical values will receive a different row number for each result.

 Examples
--------

 The distinction between DENSE\_RANK(), [RANK()](../rank/index) and [ROW\_NUMBER()](../row_number/index):

 
```
CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
  ('Maths', 60, 'Thulile'),
  ('Maths', 60, 'Pritha'),
  ('Maths', 70, 'Voitto'),
  ('Maths', 55, 'Chun'),
  ('Biology', 60, 'Bilal'),
   ('Biology', 70, 'Roger');

SELECT 
  RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank, 
  DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank, 
  ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num, 
  course, mark, name 
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

```

See Also
--------

 * [RANK()](../rank/index)
* [ROW\_NUMBER()](../row_number/index)
* [ORDER BY](../order-by/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dense_rank/>

EXPORT\_SET
===========

    Syntax
------

 
```
EXPORT_SET(bits, on, off[, separator[, number_of_bits]])

```

Description
-----------

 Takes a minimum of three arguments. Returns a string where each bit in the given `bits` argument is returned, with the string values given for `on` and `off`. 

 Bits are examined from right to left, (from low-order to high-order bits). Strings are added to the result from left to right, separated by a separator string (defaults as '`,`'). You can optionally limit the number of bits the `EXPORT_SET()` function examines using the `number_of_bits` option. 

 If any of the arguments are set as `NULL`, the function returns `NULL`.

 Examples
--------

 
```
SELECT EXPORT_SET(5,'Y','N',',',4);
+-----------------------------+
| EXPORT_SET(5,'Y','N',',',4) |
+-----------------------------+
| Y,N,Y,N                     |
+-----------------------------+

SELECT EXPORT_SET(6,'1','0',',',10);
+------------------------------+
| EXPORT_SET(6,'1','0',',',10) |
+------------------------------+
| 0,1,1,0,0,0,0,0,0,0          |
+------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/export_set/>

FIND\_IN\_SET
=============

    Syntax
------

 
```
FIND_IN_SET(pattern, strlist)

```

Description
-----------

 Returns the index position where the given pattern occurs in a string list. The first argument is the pattern you want to search for. The second argument is a string containing comma-separated variables. If the second argument is of the `[SET](../set-data-type/index)` data-type, the function is optimized to use bit arithmetic.

 If the pattern does not occur in the string list or if the string list is an empty string, the function returns `0`. If either argument is `NULL`, the function returns `NULL`. The function does not return the correct result if the pattern contains a comma ("`,`") character.

 Examples
--------

 
```
SELECT FIND_IN_SET('b','a,b,c,d') AS "Found Results";
+---------------+
| Found Results |
+---------------+
|             2 |
+---------------+

```

See Also
--------

 * [ELT()](../elt/index) function. Returns the N'th element from a set of strings.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/find_in_set/>

ST\_ENVELOPE
============

    Syntax
------

 
```
ST_ENVELOPE(g)
ENVELOPE(g)

```

Description
-----------

 Returns the Minimum Bounding Rectangle (MBR) for the geometry value `g`. The result is returned as a Polygon value.

 The polygon is defined by the corner points of the bounding box:

 
```
POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

```

`ST_ENVELOPE()` and `ENVELOPE()` are synonyms.

 Examples
--------

 
```
SELECT AsText(ST_ENVELOPE(GeomFromText('LineString(1 1,4 4)')));
+----------------------------------------------------------+
| AsText(ST_ENVELOPE(GeomFromText('LineString(1 1,4 4)'))) |
+----------------------------------------------------------+
| POLYGON((1 1,4 1,4 4,1 4,1 1))                           |
+----------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/envelope/>

EXTRACTVALUE
============

    Syntax
------

 
```
EXTRACTVALUE(xml_frag, xpath_expr)

```
 Description
-----------

 The `EXTRACTVALUE()` function takes two string arguments: a fragment of XML markup and an XPath expression, (also known as a locator). It returns the text (That is, CDDATA), of the first text node which is a child of the element or elements matching the XPath expression. 

 In cases where a valid XPath expression does not match any text nodes in a valid XML fragment, (including the implicit `/text()` expression), the `EXTRACTVALUE()` function returns an empty string.

 ### Invalid Arguments

 When either the XML fragment or the XPath expression is `NULL`, the `EXTRACTVALUE()` function returns `NULL`. When the XML fragment is invalid, it raises a warning Code 1525:

 
```
Warning (Code 1525): Incorrect XML value: 'parse error at line 1 pos 11: unexpected END-OF-INPUT'

```

When the XPath value is invalid, it generates an Error 1105:

 
```
ERROR 1105 (HY000): XPATH syntax error: ')'

```

### Explicit text() Expressions

 This function is the equivalent of performing a match using the XPath expression after appending `/text()`. In other words:

 
```
SELECT
   EXTRACTVALUE('<cases><case>example</case></cases>', '/cases/case') 
    AS 'Base Example',
   EXTRACTVALUE('<cases><case>example</case></cases>', '/cases/case/text()') 
    AS 'text() Example';
+--------------+----------------+
| Base Example | text() Example |
+--------------+----------------+
| example      | example        |
+--------------+----------------+

```

### Count Matches

 When `EXTRACTVALUE()` returns multiple matches, it returns the content of the first child text node of each matching element, in the matched order, as a single, space-delimited string.

 By design, the `EXTRACTVALUE()` function makes no distinction between a match on an empty element and no match at all. If you need to determine whether no matching element was found in the XML fragment or if an element was found that contained no child text nodes, use the XPath `count()` function. 

 For instance, when looking for a value that exists, but contains no child text nodes, you would get a count of the number of matching instances:

 
```
SELECT
   EXTRACTVALUE('<cases><case/></cases>', '/cases/case') 
    AS 'Empty Example',
   EXTRACTVALUE('<cases><case/></cases>', 'count(/cases/case)') 
    AS 'count() Example';
+---------------+-----------------+
| Empty Example | count() Example |
+---------------+-----------------+
|               |               1 |
+---------------+-----------------+

```

Alternatively, when looking for a value that doesn't exist, `count()` returns 0.

 
```
SELECT
   EXTRACTVALUE('<cases><case/></cases>', '/cases/person') 
    AS 'No Match Example',
   EXTRACTVALUE('<cases><case/></cases>', 'count(/cases/person)') 
    AS 'count() Example';
+------------------+-----------------+
| No Match Example | count() Example |
+------------------+-----------------+
|                  |                0|
+------------------+-----------------+

```

### Matches

 **Important**: The `EXTRACTVALUE()` function only returns CDDATA. It does not return tags that the element might contain or the text that these child elements contain.

 
```
SELECT 
  EXTRACTVALUE('<cases><case>Person<email>x@example.com</email></case></cases>', '/cases')
   AS Case;
+--------+
| Case   |
+--------+
| Person |
+--------+

```

Note, in the above example, while the XPath expression matches to the parent `<case>` instance, it does not return the contained `<email>` tag or its content.

 Examples
--------

 
```
SELECT
    ExtractValue('<a>ccc<b>ddd</b></a>', '/a')            AS val1,
    ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b')          AS val2,
    ExtractValue('<a>ccc<b>ddd</b></a>', '//b')           AS val3,
    ExtractValue('<a>ccc<b>ddd</b></a>', '/b')            AS val4,
    ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+------+------+------+------+---------+
| val1 | val2 | val3 | val4 | val5    |
+------+------+------+------+---------+
| ccc  | ddd  | ddd  |      | ddd eee |
+------+------+------+------+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extractvalue/>

DISJOINT
========

    Syntax
------

 
```
Disjoint(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether `g1` is spatially disjoint from (does not intersect) `g2`.

 DISJOINT() tests the opposite relationship to [INTERSECTS()](../intersects/index).

 DISJOINT() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_DISJOINT()](../st_disjoint/index) uses object shapes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/disjoint/>

DAY
===

    Syntax
------

 
```
DAY(date)

```

Description
-----------

 `DAY()` is a synonym for `[DAYOFMONTH()](../dayofmonth/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/day/>

EXTRACT
=======

    Syntax
------

 
```
EXTRACT(unit FROM date)

```
 Description
-----------

 The EXTRACT() function extracts the required unit from the date. See [Date and Time Units](../date-and-time-units/index) for a complete list of permitted units.

 In [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) and [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5535-release-notes/), `EXTRACT (HOUR FROM ...)` was changed to return a value from 0 to 23, adhering to the SQL standard. Until [MariaDB 10.0.6](https://mariadb.com/kb/en/mariadb-1006-release-notes/) and [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/), and in all versions of MySQL at least as of MySQL 5.7, it could return a value > 23. [HOUR()](../hour/index) is not a standard function, so continues to adhere to the old behaviour inherited from MySQL.

 Examples
--------

 
```
SELECT EXTRACT(YEAR FROM '2009-07-02');
+---------------------------------+
| EXTRACT(YEAR FROM '2009-07-02') |
+---------------------------------+
|                            2009 |
+---------------------------------+

SELECT EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03');
+------------------------------------------------+
| EXTRACT(YEAR_MONTH FROM '2009-07-02 01:02:03') |
+------------------------------------------------+
|                                         200907 |
+------------------------------------------------+

SELECT EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03');
+------------------------------------------------+
| EXTRACT(DAY_MINUTE FROM '2009-07-02 01:02:03') |
+------------------------------------------------+
|                                          20102 |
+------------------------------------------------+

SELECT EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123');
+--------------------------------------------------------+
| EXTRACT(MICROSECOND FROM '2003-01-02 10:30:00.000123') |
+--------------------------------------------------------+
|                                                    123 |
+--------------------------------------------------------+

```

From [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) and [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5535-release-notes/), `EXTRACT (HOUR FROM...)` returns a value from 0 to 23, as per the SQL standard. `HOUR` is not a standard function, so continues to adhere to the old behaviour inherited from MySQL.

 
```
SELECT EXTRACT(HOUR FROM '26:30:00'), HOUR('26:30:00');
+-------------------------------+------------------+
| EXTRACT(HOUR FROM '26:30:00') | HOUR('26:30:00') |
+-------------------------------+------------------+
|                             2 |               26 |
+-------------------------------+------------------+

```

See Also
--------

 * [Date and Time Units](../date-and-time-units/index)
* [Date and Time Literals](../date-and-time-literals/index)
* [HOUR()](../hour/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extract/>

FLOOR
=====

    Syntax
------

 
```
FLOOR(X)

```

Description
-----------

 Returns the largest integer value not greater than X.

 Examples
--------

 
```
SELECT FLOOR(1.23);
+-------------+
| FLOOR(1.23) |
+-------------+
|           1 |
+-------------+

SELECT FLOOR(-1.23);
+--------------+
| FLOOR(-1.23) |
+--------------+
|           -2 |
+--------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/floor/>

DAYOFWEEK
=========

    Syntax
------

 
```
DAYOFWEEK(date)

```

Description
-----------

 Returns the day of the week index for the date (1 = Sunday, 2 = Monday, ..., 7 = Saturday). These index values correspond to the ODBC standard.

 This contrasts with `[WEEKDAY()](../weekday/index)` which follows a different index numbering (`0` = Monday, `1` = Tuesday, ... `6` = Sunday).

 Examples
--------

 
```
SELECT DAYOFWEEK('2007-02-03');
+-------------------------+
| DAYOFWEEK('2007-02-03') |
+-------------------------+
|                       7 |
+-------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d, DAYNAME(d), DAYOFWEEK(d), WEEKDAY(d) from t1;
+---------------------+------------+--------------+------------+
| d                   | DAYNAME(d) | DAYOFWEEK(d) | WEEKDAY(d) |
+---------------------+------------+--------------+------------+
| 2007-01-30 21:31:07 | Tuesday    |            3 |          1 |
| 1983-10-15 06:42:51 | Saturday   |            7 |          5 |
| 2011-04-21 12:34:56 | Thursday   |            5 |          3 |
| 2011-10-30 06:31:41 | Sunday     |            1 |          6 |
| 2011-01-30 14:03:25 | Sunday     |            1 |          6 |
| 2004-10-07 11:19:34 | Thursday   |            5 |          3 |
+---------------------+------------+--------------+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dayofweek/>

ST\_ExteriorRing
================

    Syntax
------

 
```
ST_ExteriorRing(poly)
ExteriorRing(poly)

```

Description
-----------

 Returns the exterior ring of the Polygon value `poly` as a LineString.

 `ST_ExteriorRing()` and `ExteriorRing()` are synonyms.

 Examples
--------

 
```
SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT AsText(ExteriorRing(GeomFromText(@poly)));
+-------------------------------------------+
| AsText(ExteriorRing(GeomFromText(@poly))) |
+-------------------------------------------+
| LINESTRING(0 0,0 3,3 3,3 0,0 0)           |
+-------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/exteriorring/>

FOUND\_ROWS
===========

    Syntax
------

 
```
FOUND_ROWS()

```

Description
-----------

 A [SELECT](../select/index) statement may include a [LIMIT](../select/index#limit) clause to restrict the number of rows the server returns to the client. In some cases, it is desirable to know how many rows the statement would have returned without the LIMIT, but without running the statement again. To obtain this row count, include a [SQL\_CALC\_FOUND\_ROWS](../select/index#sql_calc_found_rows) option in the SELECT statement, and then invoke FOUND\_ROWS() afterwards.

 You can also use FOUND\_ROWS() to obtain the number of rows returned by a [SELECT](../select/index) which does not contain a [LIMIT](../select/index#limit) clause. In this case you don't need to use the [SQL\_CALC\_FOUND\_ROWS](../select/index#sql_calc_found_rows) option. This can be useful for example in a [stored procedure](../stored-procedures/index).

 Also, this function works with some other statements which return a resultset, including [SHOW](../show/index), [DESC](../describe/index) and [HELP](../help-command/index). For [DELETE ... RETURNING](../delete/index) you should use [ROW\_COUNT()](../information-functions-row_count/index). It also works as a [prepared statement](../prepared-statements/index), or after executing a prepared statement.

 Statements which don't return any results don't affect FOUND\_ROWS() - the previous value will still be returned.

 **Warning:** When used after a [CALL](../call/index) statement, this function returns the number of rows selected by the last query in the procedure, not by the whole procedure.

 Statements using the FOUND\_ROWS() function are not [safe for replication](../unsafe-statements-for-replication/index).

 Examples
--------

 
```
SHOW ENGINES\G
*************************** 1. row ***************************
      Engine: CSV
     Support: YES
     Comment: Stores tables as CSV files
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 2. row ***************************
      Engine: MRG_MyISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO

...

*************************** 8. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
8 rows in set (0.000 sec)

SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
|           8 |
+--------------+

SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;

SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
|           23 |
+--------------+

```

See Also
--------

 * [ROW\_COUNT()](../information-functions-row_count/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/found_rows/>

FORMAT
======

    Syntax
------

 
```
FORMAT(num, decimal_position[, locale])

```

Description
-----------

 Formats the given number for display as a string, adding separators to appropriate position and rounding the results to the given decimal position. For instance, it would format `15233.345` to `15,233.35`.

 If the given decimal position is `0`, it rounds to return no decimal point or fractional part. You can optionally specify a [locale](../server-locale/index) value to format numbers to the pattern appropriate for the given region.

 Examples
--------

 
```
SELECT FORMAT(1234567890.09876543210, 4) AS 'Format';
+--------------------+
| Format             |
+--------------------+
| 1,234,567,890.0988 |
+--------------------+

SELECT FORMAT(1234567.89, 4) AS 'Format';
+----------------+
| Format         |
+----------------+
| 1,234,567.8900 |
+----------------+

SELECT FORMAT(1234567.89, 0) AS 'Format';
+-----------+
| Format    |
+-----------+
| 1,234,568 |
+-----------+

SELECT FORMAT(123456789,2,'rm_CH') AS 'Format';
+----------------+
| Format         |
+----------------+
| 123'456'789,00 |
+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format/>

FROM\_UNIXTIME
==============

    Syntax
------

 
```
FROM_UNIXTIME(unix_timestamp), FROM_UNIXTIME(unix_timestamp,format)

```
 Description
-----------

 Returns a representation of the unix\_timestamp argument as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. The value is expressed in the current [time zone](../time-zones/index). unix\_timestamp is an internal timestamp value such as is produced by the [UNIX\_TIMESTAMP()](../unix_timestamp/index) function.

 If format is given, the result is formatted according to the format string, which is used the same way as listed in the entry for the [DATE\_FORMAT()](../date_format/index) function.

 
Timestamps in MariaDB have a maximum value of 2147483647, equivalent to 2038-01-19 05:14:07. This is due to the underlying 32-bit limitation. Using the function on a timestamp beyond this will result in NULL being returned. Use [DATETIME](../datetime/index) as a storage type if you require dates beyond this.

 
The options that can be used by FROM\_UNIXTIME(), as well as [DATE\_FORMAT()](../date_format/index) and [STR\_TO\_DATE()](../str_to_date/index), are:

 


| Option | Description |
| --- | --- |
| `%a` | Short weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%b` | Short form month name in current locale. For locale en\_US this is one of: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov or Dec. |
| `%c` | Month with 1 or 2 digits. |
| `%D` | Day with English suffix 'th', 'nd', 'st' or 'rd''. (1st, 2nd, 3rd...). |
| `%d` | Day with 2 digits. |
| `%e` | Day with 1 or 2 digits. |
| `%f` | [Microseconds](../microseconds-in-mariadb/index) 6 digits. |
| `%H` | Hour with 2 digits between 00-23. |
| `%h` | Hour with 2 digits between 01-12. |
| `%I` | Hour with 2 digits between 01-12. |
| `%i` | Minute with 2 digits. |
| `%j` | Day of the year (001-366) |
| `%k` | Hour with 1 digits between 0-23. |
| `%l` | Hour with 1 digits between 1-12. |
| `%M` | Full month name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%m` | Month with 2 digits. |
| `%p` | AM/PM according to current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%r` | Time in 12 hour format, followed by AM/PM. Short for '%I:%i:%S %p'. |
| `%S` | Seconds with 2 digits. |
| `%s` | Seconds with 2 digits. |
| `%T` | Time in 24 hour format. Short for '%H:%i:%S'. |
| `%U` | Week number (00-53), when first day of the week is Sunday. |
| `%u` | Week number (00-53), when first day of the week is Monday. |
| `%V` | Week number (01-53), when first day of the week is Sunday. Used with %X. |
| `%v` | Week number (01-53), when first day of the week is Monday. Used with %x. |
| `%W` | Full weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%w` | Day of the week. 0 = Sunday, 6 = Saturday. |
| `%X` | Year with 4 digits when first day of the week is Sunday. Used with %V. |
| `%x` | Year with 4 digits when first day of the week is Sunday. Used with %v. |
| `%Y` | Year with 4 digits. |
| `%y` | Year with 2 digits. |
| `%#` | For [str\_to\_date](../str_to_date/index)(), skip all numbers. |
| `%.` | For [str\_to\_date](../str_to_date/index)(), skip all punctation characters. |
| `%@` | For [str\_to\_date](../str_to_date/index)(), skip all alpha characters. |
| `%%` | A literal `%` character. |

 
Performance Considerations
--------------------------

 If your [session time zone](../server-system-variables/index#time_zone) is set to `SYSTEM` (the default), `FROM_UNIXTIME()` will call the OS function to convert the data using the system time zone. At least on Linux, the corresponding function (`localtime_r`) uses a global mutex inside glibc that can cause contention under high concurrent load.

 Set your time zone to a named time zone to avoid this issue. See [mysql time zone tables](../time-zones/index#mysql-time-zone-tables) for details on how to do this.

 Examples
--------

 
```
SELECT FROM_UNIXTIME(1196440219);
+---------------------------+
| FROM_UNIXTIME(1196440219) |
+---------------------------+
| 2007-11-30 11:30:19       |
+---------------------------+

SELECT FROM_UNIXTIME(1196440219) + 0;
+-------------------------------+
| FROM_UNIXTIME(1196440219) + 0 |
+-------------------------------+
|         20071130113019.000000 |
+-------------------------------+

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x');
+---------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP(), '%Y %D %M %h:%i:%s %x') |
+---------------------------------------------------------+
| 2010 27th March 01:03:47 2010                           |
+---------------------------------------------------------+

```

See Also
--------

 * [UNIX\_TIMESTAMP()](../unix_timestamp/index)
* [DATE\_FORMAT()](../date_format/index)
* [STR\_TO\_DATE()](../str_to_date/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/from_unixtime/>

FROM\_DAYS
==========

    Syntax
------

 
```
FROM_DAYS(N)

```

Description
-----------

 Given a day number N, returns a DATE value. The day count is based on the number of days from the start of the standard calendar (0000-00-00). 

 The function is not designed for use with dates before the advent of the Gregorian calendar in October 1582. Results will not be reliable since it doesn't account for the lost days when the calendar changed from the Julian calendar.

 This is the converse of the [TO\_DAYS()](../to_days/index) function.

 Examples
--------

 
```
SELECT FROM_DAYS(730669);
+-------------------+
| FROM_DAYS(730669) |
+-------------------+
| 2000-07-03        |
+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/from_days/>

FROM\_BASE64
============

    Syntax
------

 
```
FROM_BASE64(str)

```

Description
-----------

 Decodes the given base-64 encode string, returning the result as a binary string. Returns `NULL` if the given string is `NULL` or if it's invalid.

 It is the reverse of the `[TO\_BASE64](../to_base64/index)` function.

 There are numerous methods to base-64 encode a string. MariaDB uses the following:

 * It encodes alphabet value 64 as '`+`'.
* It encodes alphabet value 63 as '`/`'.
* It codes output in groups of four printable characters. Each three byte of data encoded uses four characters. If the final group is incomplete, it pads the difference with the '`=`' character.
* It divides long output, adding a new line very 76 characters.
* In decoding, it recognizes and ignores newlines, carriage returns, tabs and space whitespace characters.

 
```
SELECT TO_BASE64('Maria') AS 'Input';
+-----------+
| Input     |
+-----------+
| TWFyaWE=  |
+-----------+

SELECT FROM_BASE64('TWFyaWE=') AS 'Output';
+--------+
| Output |
+--------+
| Maria  |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/from_base64/>

GET\_FORMAT
===========

    Syntax
------

 
```
GET_FORMAT({DATE|DATETIME|TIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})

```

Description
-----------

 Returns a format string. This function is useful in combination with the [DATE\_FORMAT()](../date_format/index) and the [STR\_TO\_DATE()](../str_to_date/index) functions.

 Possible result formats are:

 


| Function Call | Result Format |
| --- | --- |
| GET\_FORMAT(DATE,'EUR') | '%d.%m.%Y' |
| GET\_FORMAT(DATE,'USA') | '%m.%d.%Y' |
| GET\_FORMAT(DATE,'JIS') | '%Y-%m-%d' |
| GET\_FORMAT(DATE,'ISO') | '%Y-%m-%d' |
| GET\_FORMAT(DATE,'INTERNAL') | '%Y%m%d' |
| GET\_FORMAT(DATETIME,'EUR') | '%Y-%m-%d %H.%i.%s' |
| GET\_FORMAT(DATETIME,'USA') | '%Y-%m-%d %H.%i.%s' |
| GET\_FORMAT(DATETIME,'JIS') | '%Y-%m-%d %H:%i:%s' |
| GET\_FORMAT(DATETIME,'ISO') | '%Y-%m-%d %H:%i:%s' |
| GET\_FORMAT(DATETIME,'INTERNAL') | '%Y%m%d%H%i%s' |
| GET\_FORMAT(TIME,'EUR') | '%H.%i.%s' |
| GET\_FORMAT(TIME,'USA') | '%h:%i:%s %p' |
| GET\_FORMAT(TIME,'JIS') | '%H:%i:%s' |
| GET\_FORMAT(TIME,'ISO') | '%H:%i:%s' |
| GET\_FORMAT(TIME,'INTERNAL') | '%H%i%s' |

 
Examples
--------

 Obtaining the string matching to the standard European date format:

 
```
SELECT GET_FORMAT(DATE, 'EUR');
+-------------------------+
| GET_FORMAT(DATE, 'EUR') |
+-------------------------+
| %d.%m.%Y                |
+-------------------------+

```

Using the same string to format a date:

 
```
SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
+--------------------------------------------------+
| DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR')) |
+--------------------------------------------------+
| 03.10.2003                                       |
+--------------------------------------------------+

SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
+--------------------------------------------------+
| STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA')) |
+--------------------------------------------------+
| 2003-10-31                                       |
+--------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/get_format/>

GEOMETRYCOLLECTION
==================

    Syntax
------

 
```
GeometryCollection(g1,g2,...)

```

Description
-----------

 Constructs a [WKB](../wkb/index) GeometryCollection. If any argument is not a well-formed WKB representation of a geometry, the return value is `NULL`.

 Examples
--------

 
```
CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
    (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
    (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
    (GeomFromText('GeometryCollection()')),
    (GeomFromText('GeometryCollection EMPTY'));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometrycollection/>

GLENGTH
=======

    Syntax
------

 
```
GLength(ls)

```

Description
-----------

 Returns as a double-precision number the length of the [LineString](../linestring/index) value *`ls`* in its associated spatial reference.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT GLength(GeomFromText(@ls));
+----------------------------+
| GLength(GeomFromText(@ls)) |
+----------------------------+
|           2.82842712474619 |
+----------------------------+

```

See Also
--------

 * [ST\_LENGTH()](../st_length/index) is the OpenGIS equivalent.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/glength/>

GET\_LOCK
=========

    Syntax
------

 
```
GET_LOCK(str,timeout)

```
 Description
-----------

 Tries to obtain a lock with a name given by the string `str`, using a timeout of `timeout` seconds. Returns `1` if the lock was obtained successfully, `0` if the attempt timed out (for example, because another client has previously locked the name), or `NULL` if an error occurred (such as running out of memory or the thread was killed with [mariadb-admin kill](mariadb-admin_kill)).

 A lock is released with [RELEASE\_LOCK()](../release_lock/index), when the connection terminates (either normally or abnormally). A connection can hold multiple locks at the same time, so a lock that is no longer needed needs to be explicitly released.

 The [IS\_FREE\_LOCK](../is_free_lock/index) function returns whether a specified lock a free or not, and the [IS\_USED\_LOCK](../is_used_lock/index) whether the function is in use or not.

 Locks obtained with `GET_LOCK()` do not interact with transactions. That is, committing a transaction does not release any such locks obtained during the transaction.

 It is also possible to recursively set the same lock. If a lock with the same name is set `n` times, it needs to be released `n` times as well. 

 `str` is case insensitive for `GET_LOCK()` and related functions. If `str` is an empty string or `NULL`, `GET_LOCK()` returns `NULL` and does nothing. `timeout` supports microseconds.

 If the [metadata\_lock\_info](../metadata-lock-info/index) plugin is installed, locks acquired with this function are visible in the [Information Schema](../information_schema/index) [METADATA\_LOCK\_INFO](../information-schema-metadata_lock_info-table/index) table.

 This function can be used to implement application locks or to simulate record locks. Names are locked on a server-wide basis. If a name has been locked by one client, `GET_LOCK()` blocks any request by another client for a lock with the same name. This allows clients that agree on a given lock name to use the name to perform cooperative advisory locking. But be aware that it also allows a client that is not among the set of cooperating clients to lock a name, either inadvertently or deliberately, and thus prevent any of the cooperating clients from locking that name. One way to reduce the likelihood of this is to use lock names that are database-specific or application-specific. For example, use lock names of the form `db_name.str` or `app_name.str`.

 Statements using the `GET_LOCK` function are [not safe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 The patch to permit multiple locks was [contributed by Konstantin "Kostja" Osipov](http://kostja-osipov.livejournal.com/46410.html) ([MDEV-3917](https://jira.mariadb.org/browse/MDEV-3917)).

 Examples
--------

 
```
SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT IS_FREE_LOCK('lock1'), IS_USED_LOCK('lock1');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock1') | IS_USED_LOCK('lock1') |
+-----------------------+-----------------------+
|                     0 |                    46 |
+-----------------------+-----------------------+

SELECT IS_FREE_LOCK('lock2'), IS_USED_LOCK('lock2');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock2') | IS_USED_LOCK('lock2') |
+-----------------------+-----------------------+
|                     1 |                  NULL |
+-----------------------+-----------------------+

```

Multiple locks can be held:

 
```
SELECT GET_LOCK('lock2',10);
+----------------------+
| GET_LOCK('lock2',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT IS_FREE_LOCK('lock1'), IS_FREE_LOCK('lock2');
+-----------------------+-----------------------+
| IS_FREE_LOCK('lock1') | IS_FREE_LOCK('lock2') |
+-----------------------+-----------------------+
|                     0 |                     0 |
+-----------------------+-----------------------+

SELECT RELEASE_LOCK('lock1'), RELEASE_LOCK('lock2');
+-----------------------+-----------------------+
| RELEASE_LOCK('lock1') | RELEASE_LOCK('lock2') |
+-----------------------+-----------------------+
|                     1 |                     1 |
+-----------------------+-----------------------+

```

It is possible to hold the same lock recursively. This example is viewed using the [metadata\_lock\_info](../metadata-lock-info/index) plugin:

 
```
SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+------------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+------------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |            |
+-----------+---------------------+---------------+-----------+--------------+------------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+------------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+------------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |            |
+-----------+---------------------+---------------+-----------+--------------+------------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
Empty set (0.000 sec)

```

Timeout example: Connection 1:

 
```
SELECT GET_LOCK('lock4',10);
+----------------------+
| GET_LOCK('lock4',10) |
+----------------------+
|                    1 |
+----------------------+

```

Connection 2:

 
```
SELECT GET_LOCK('lock4',10);

```

After 10 seconds...

 
```
+----------------------+
| GET_LOCK('lock4',10) |
+----------------------+
|                    0 |
+----------------------+

```

Deadlocks are automatically detected and resolved. Connection 1:

 
```
SELECT GET_LOCK('lock5',10); 
+----------------------+
| GET_LOCK('lock5',10) |
+----------------------+
|                    1 |
+----------------------+

```

Connection 2:

 
```
SELECT GET_LOCK('lock6',10);
+----------------------+
| GET_LOCK('lock6',10) |
+----------------------+
|                    1 |
+----------------------+

```

Connection 1:

 
```
SELECT GET_LOCK('lock6',10); 
+----------------------+
| GET_LOCK('lock6',10) |
+----------------------+
|                    0 |
+----------------------+

```

Connection 2:

 
```
SELECT GET_LOCK('lock5',10);
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

```

See Also
--------

 * [RELEASE\_LOCK](../release_lock/index)
* [IS\_FREE\_LOCK](../is_free_lock/index)
* [IS\_USED\_LOCK](../is_used_lock/index)
* [RELEASE\_ALL\_LOCKS](../release_all_locks/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/get_lock/>

ST\_GeomCollFromWKB
===================

    Syntax
------

 
```
ST_GeomCollFromWKB(wkb[,srid])
ST_GeometryCollectionFromWKB(wkb[,srid])
GeomCollFromWKB(wkb[,srid])
GeometryCollectionFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a GEOMETRYCOLLECTION value using its [WKB](../well-known-binary-wkb-format/index) representation and SRID.

 `ST_GeomCollFromWKB()`, `ST_GeometryCollectionFromWKB()`, `GeomCollFromWKB()` and `GeometryCollectionFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(ST_GeomFromText('GEOMETRYCOLLECTION(
   POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10))'));

SELECT ST_AsText(ST_GeomCollFromWKB(@g));
+----------------------------------------------------------------+
| ST_AsText(ST_GeomCollFromWKB(@g))                              |
+----------------------------------------------------------------+
| GEOMETRYCOLLECTION(POLYGON((5 5,10 5,10 10,5 5)),POINT(10 10)) |
+----------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geomcollfromwkb/>

GeometryCollectionFromWKB
=========================

    A synonym for [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometrycollectionfromwkb/>

ST\_GeomFromText
================

    Syntax
------

 
```
ST_GeomFromText(wkt[,srid])
ST_GeometryFromText(wkt[,srid])
GeomFromText(wkt[,srid])
GeometryFromText(wkt[,srid])

```

Description
-----------

 Constructs a geometry value of any type using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `GeomFromText()`, `GeometryFromText()`, `ST_GeomFromText()` and `ST_GeometryFromText()` are all synonyms.

 Example
-------

 
```
SET @g = ST_GEOMFROMTEXT('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))');

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geomfromtext/>

ST\_GeomCollFromText
====================

    Syntax
------

 
```
ST_GeomCollFromText(wkt[,srid])
ST_GeometryCollectionFromText(wkt[,srid])
GeomCollFromText(wkt[,srid])
GeometryCollectionFromText(wkt[,srid])

```

Description
-----------

 Constructs a [GEOMETRYCOLLECTION](../geometrycollection/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `ST_GeomCollFromText()`, `ST_GeometryCollectionFromText()`, `GeomCollFromText()` and `GeometryCollectionFromText()` are all synonyms.

 Example
-------

 
```
CREATE TABLE gis_geometrycollection  (g GEOMETRYCOLLECTION);
SHOW FIELDS FROM gis_geometrycollection;
INSERT INTO gis_geometrycollection VALUES
    (GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
    (GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
    (GeomFromText('GeometryCollection()')),
    (GeomFromText('GeometryCollection EMPTY'));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geomcollfromtext/>

GeometryCollectionFromText
==========================

    A synonym for [ST\_GeomCollFromText](../st_geomcollfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometrycollectionfromtext/>

GeometryFromText
================

    A synonym for [ST\_GeomFromText](../st_geomfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometryfromtext/>

GREATEST
========

    Syntax
------

 
```
GREATEST(value1,value2,...)

```

Description
-----------

 With two or more arguments, returns the largest (maximum-valued) argument. The arguments are compared using the same rules as for [LEAST()](../least/index).

 Examples
--------

 
```
SELECT GREATEST(2,0);
+---------------+
| GREATEST(2,0) |
+---------------+
|             2 |
+---------------+

```


```
SELECT GREATEST(34.0,3.0,5.0,767.0);
+------------------------------+
| GREATEST(34.0,3.0,5.0,767.0) |
+------------------------------+
|                        767.0 |
+------------------------------+

```


```
SELECT GREATEST('B','A','C');
+-----------------------+
| GREATEST('B','A','C') |
+-----------------------+
| C                     |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/greatest/>

ST\_GeomFromWKB
===============

    Syntax
------

 
```
ST_GeomFromWKB(wkb[,srid])
ST_GeometryFromWKB(wkb[,srid])
GeomFromWKB(wkb[,srid])
GeometryFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a geometry value of any type using its [WKB](../well-known-binary-wkb-format/index) representation and SRID.

 `ST_GeomFromWKB()`, `ST_GeometryFromWKB()`, `GeomFromWKB()` and `GeometryFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(ST_LineFromText('LINESTRING(0 4, 4 6)'));

SELECT ST_AsText(ST_GeomFromWKB(@g));
+-------------------------------+
| ST_AsText(ST_GeomFromWKB(@g)) |
+-------------------------------+
| LINESTRING(0 4,4 6)           |
+-------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geomfromwkb/>

GROUP\_CONCAT
=============

    Syntax
------

 
```
GROUP_CONCAT(expr)

```
 Description
-----------

 This function returns a string result with the concatenated non-NULL values from a group. It returns NULL if there are no non-NULL values.

 The maximum returned length in bytes is determined by the [group\_concat\_max\_len](../server-system-variables/index#group_concat_max_len) server system variable, which defaults to 1M (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)) or 1K (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)).

 If group\_concat\_max\_len <= 512, the return type is [VARBINARY](../varbinary/index) or [VARCHAR](../varchar/index); otherwise, the return type is [BLOB](../blob/index) or [TEXT](../text/index). The choice between binary or non-binary types depends from the input.

 The full syntax is as follows:

 
```
GROUP_CONCAT([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [SEPARATOR str_val]
             [LIMIT {[offset,] row_count | row_count OFFSET offset}])

```

`DISTINCT` eliminates duplicate values from the output string.

 [ORDER BY](../order-by/index) determines the order of returned values.

 `SEPARATOR` specifies a separator between the values. The default separator is a comma (`,`). It is possible to avoid using a separator by specifying an empty string.

 ### LIMIT

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**Until [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), it was not possible to use the [LIMIT](../limit/index) clause with `GROUP_CONCAT`. This restriction was lifted in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

 
Examples
--------

 
```
SELECT student_name,
       GROUP_CONCAT(test_score)
       FROM student
       GROUP BY student_name;

```

Get a readable list of MariaDB users from the [mysql.user](../mysqluser-table/index) table:

 
```
SELECT GROUP_CONCAT(DISTINCT User ORDER BY User SEPARATOR '\n')
   FROM mysql.user;

```

In the former example, `DISTINCT` is used because the same user may occur more than once. The new line (`\n`) used as a `SEPARATOR` makes the results easier to read.

 Get a readable list of hosts from which each user can connect:

 
```
SELECT User, GROUP_CONCAT(Host ORDER BY Host SEPARATOR ', ') 
   FROM mysql.user GROUP BY User ORDER BY User;

```

The former example shows the difference between the `GROUP_CONCAT`'s [ORDER BY](../order-by/index) (which sorts the concatenated hosts), and the `SELECT`'s [ORDER BY](../order-by/index) (which sorts the rows).

 From [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), [LIMIT](../limit/index) can be used with `GROUP_CONCAT`, so, for example, given the following table:

 
```
CREATE TABLE d (dd DATE, cc INT);

INSERT INTO d VALUES ('2017-01-01',1);
INSERT INTO d VALUES ('2017-01-02',2);
INSERT INTO d VALUES ('2017-01-04',3);

```

the following query:

 
```
SELECT SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) FROM d;
+----------------------------------------------------------------------------+
| SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) |
+----------------------------------------------------------------------------+
| 2017-01-04:3                                                               |
+----------------------------------------------------------------------------+

```

can be more simply rewritten as:

 
```
SELECT GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) FROM d;
+-------------------------------------------------------------+
| GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) |
+-------------------------------------------------------------+
| 2017-01-04:3                                                |
+-------------------------------------------------------------+

```

See Also
--------

 * [CONCAT()](../concat/index)
* [CONCAT\_WS()](../concat_ws/index)
* [SELECT](../select/index)
* [ORDER BY](../order-by/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/group_concat/>

FORMAT\_PICO\_TIME
==================

    
**MariaDB starting with [11.0.2](https://mariadb.com/kb/en/mariadb-1102-release-notes/)**Introduced in [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/)

 
Syntax
------

 
```
FORMAT_PICO_TIME(time_val)

```
 Description
-----------

 Given a time in picoseconds, returns a human-readable time value and unit indicator. Resulting unit is dependent on the length of the argument, and can be:

 * ps - picoseconds
* ns - nanoseconds
* us - microseconds
* ms - milliseconds
* s - seconds
* min - minutes
* h - hours
* d - days

 With the exception of results under one nanosecond, which are not rounded and are represented as whole numbers, the result is rounded to 2 decimal places, with a minimum of 3 significant digits.

 Returns NULL if the argument is NULL.

 This function is very similar to the [Sys Schema](../sys-schema/index) [FORMAT\_TIME](../format_time/index) function, but with the following differences:

 * Represents minutes as `min` rather than `m`.
* Does not represent weeks.

 Examples
--------

 
```
SELECT
    FORMAT_PICO_TIME(43) AS ps,
    FORMAT_PICO_TIME(4321) AS ns, 
    FORMAT_PICO_TIME(43211234) AS us,
    FORMAT_PICO_TIME(432112344321) AS ms,
    FORMAT_PICO_TIME(43211234432123) AS s,
    FORMAT_PICO_TIME(432112344321234) AS m,
    FORMAT_PICO_TIME(4321123443212345) AS h,
    FORMAT_PICO_TIME(432112344321234545) AS d;
+--------+---------+----------+-----------+---------+----------+--------+--------+
| ps     | ns      | us       | ms        | s       | m        | h      | d      |
+--------+---------+----------+-----------+---------+----------+--------+--------+
|  43 ps | 4.32 ns | 43.21 us | 432.11 ms | 43.21 s | 7.20 min | 1.20 h | 5.00 d |
+--------+---------+----------+-----------+---------+----------+--------+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format_pico_time/>

GeometryFromWKB
===============

    A synonym for [ST\_GeomFromWKB](../st_geomfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometryfromwkb/>

ST\_GEOMETRYTYPE
================

    Syntax
------

 
```
ST_GeometryType(g)
GeometryType(g)

```

Description
-----------

 Returns as a string the name of the geometry type of which the geometry instance `g` is a member. The name corresponds to one of the instantiable Geometry subclasses.

 `ST_GeometryType()` and `GeometryType()` are synonyms.

 Examples
--------

 
```
SELECT GeometryType(GeomFromText('POINT(1 1)'));
+------------------------------------------+
| GeometryType(GeomFromText('POINT(1 1)')) |
+------------------------------------------+
| POINT                                    |
+------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometrytype/>

HEX
===

    Syntax
------

 
```
HEX(N_or_S)

```

Description
-----------

 If `N_or_S` is a number, returns a string representation of the hexadecimal value of `N`, where `N` is a `longlong` (`[BIGINT](../bigint/index)`) number. This is equivalent to `[CONV](../conv/index)(N,10,16)`.

 If `N_or_S` is a string, returns a hexadecimal string representation of `N_or_S` where each byte of each character in `N_or_S` is converted to two hexadecimal digits. If `N_or_S` is NULL, returns NULL. The inverse of this operation is performed by the [UNHEX](../unhex/index)() function.

   


 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**HEX() with an [INET6](../inet6/index) argument returns a hexadecimal representation of the underlying 16-byte binary string.

 
Examples
--------

 
```
SELECT HEX(255);
+----------+
| HEX(255) |
+----------+
| FF       |
+----------+

SELECT 0x4D617269614442;
+------------------+
| 0x4D617269614442 |
+------------------+
| MariaDB          |
+------------------+

SELECT HEX('MariaDB');
+----------------+
| HEX('MariaDB') |
+----------------+
| 4D617269614442 |
+----------------+

```

From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 
```
SELECT HEX(CAST('2001:db8::ff00:42:8329' AS INET6));
+----------------------------------------------+
| HEX(CAST('2001:db8::ff00:42:8329' AS INET6)) |
+----------------------------------------------+
| 20010DB8000000000000FF0000428329             |
+----------------------------------------------+

```

See Also
--------

 * [Hexadecimal literals](../hexadecimal-literals/index)
* [UNHEX()](../unhex/index)
* [CONV()](../conv/index)
* [BIN()](../bin/index)
* [OCT()](../oct/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hex/>

IFNULL
======

    Syntax
------

 
```
IFNULL(expr1,expr2)
NVL(expr1,expr2)

```
 Description
-----------

 If *`expr1`* is not NULL, IFNULL() returns *`expr1`*; otherwise it returns *`expr2`*. IFNULL() returns a numeric or string value, depending on the context in which it is used. 

 From [MariaDB 10.3](../what-is-mariadb-103/index), NVL() is an alias for IFNULL().

 Examples
--------

 
```
SELECT IFNULL(1,0); 
+-------------+
| IFNULL(1,0) |
+-------------+
|           1 |
+-------------+

SELECT IFNULL(NULL,10);
+-----------------+
| IFNULL(NULL,10) |
+-----------------+
|              10 |
+-----------------+

SELECT IFNULL(1/0,10);
+----------------+
| IFNULL(1/0,10) |
+----------------+
|        10.0000 |
+----------------+

SELECT IFNULL(1/0,'yes');
+-------------------+
| IFNULL(1/0,'yes') |
+-------------------+
| yes               |
+-------------------+

```

See Also
--------

 * [NULL values](../null-values/index)
* [IS NULL operator](../is-null/index)
* [IS NOT NULL operator](../is-not-null/index)
* [COALESCE function](../coalesce/index)
* [NULLIF function](../nullif/index)
* [CONNECT data types](../connect-data-types/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ifnull/>

HOUR
====

    Syntax
------

 
```
HOUR(time)

```

Description
-----------

 Returns the hour for time. The range of the return value is 0 to 23 for time-of-day values. However, the range of `TIME` values actually is much larger, so HOUR can return values greater than 23.

 The return value is always positive, even if a negative `TIME` value is provided.

 Examples
--------

 
```
SELECT HOUR('10:05:03');
+------------------+
| HOUR('10:05:03') |
+------------------+
|               10 |
+------------------+

SELECT HOUR('272:59:59');
+-------------------+
| HOUR('272:59:59') |
+-------------------+
|               272 |
+-------------------+

```

Difference between `[EXTRACT (HOUR FROM ...)](../extract/index)` (>= [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) and [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5535-release-notes/)) and `HOUR`:

 
```
SELECT EXTRACT(HOUR FROM '26:30:00'), HOUR('26:30:00');
+-------------------------------+------------------+
| EXTRACT(HOUR FROM '26:30:00') | HOUR('26:30:00') |
+-------------------------------+------------------+
|                             2 |               26 |
+-------------------------------+------------------+

```

See Also
--------

 * [Date and Time Units](../date-and-time-units/index)
* [Date and Time Literals](../date-and-time-literals/index)
* [EXTRACT()](../extract/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hour/>

IF Function
===========

    Syntax
------

 
```
IF(expr1,expr2,expr3)

```
 Description
-----------

 If `expr1` is `TRUE` (`expr1 <> 0` and `expr1 <> NULL`) then `IF()` returns `expr2`; otherwise it returns `expr3`. `IF()` returns a numeric or string value, depending on the context in which it is used.

 **Note:** There is also an [IF statement](../if-statement/index) which differs from the `IF()` function described here.

 Examples
--------

 
```
SELECT IF(1>2,2,3);
+-------------+
| IF(1>2,2,3) |
+-------------+
|           3 |
+-------------+

```


```
SELECT IF(1<2,'yes','no');
+--------------------+
| IF(1<2,'yes','no') |
+--------------------+
| yes                |
+--------------------+

```


```
SELECT IF(STRCMP('test','test1'),'no','yes');
+---------------------------------------+
| IF(STRCMP('test','test1'),'no','yes') |
+---------------------------------------+
| no                                    |
+---------------------------------------+

```

See Also
--------

 There is also an [IF statement](../if-statement/index), which differs from the `IF()` function described above.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/if-function/>

ST\_GEOMETRYN
=============

    Syntax
------

 
```
ST_GeometryN(gc,N)
GeometryN(gc,N)

```

Description
-----------

 Returns the N-th geometry in the GeometryCollection *`gc`.* Geometries are numbered beginning with 1.

 `ST_GeometryN()` and `GeometryN()` are synonyms.

 Example
-------

 
```
SET @gc = 'GeometryCollection(Point(1 1),LineString(12 14, 9 11))';

SELECT AsText(GeometryN(GeomFromText(@gc),1));
+----------------------------------------+
| AsText(GeometryN(GeomFromText(@gc),1)) |
+----------------------------------------+
| POINT(1 1)                             |
+----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometryn/>

IN
==

    Syntax
------

 
```
expr IN (value,...)

```

Description
-----------

 Returns 1 if *`expr`* is equal to any of the values in the IN list, else returns 0. If all values are constants, they are evaluated according to the type of *`expr`* and sorted. The search for the item then is done using a binary search. This means IN is very quick if the IN value list consists entirely of constants. Otherwise, type conversion takes place according to the rules described at [Type Conversion](../type-conversion/index), but applied to all the arguments.

 If *`expr`* is NULL, IN always returns NULL. If at least one of the values in the list is NULL, and one of the comparisons is true, the result is 1. If at least one of the values in the list is NULL and none of the comparisons is true, the result is NULL.

 Examples
--------

 
```
SELECT 2 IN (0,3,5,7);
+----------------+
| 2 IN (0,3,5,7) |
+----------------+
|              0 |
+----------------+

```


```
SELECT 'wefwf' IN ('wee','wefwf','weg');
+----------------------------------+
| 'wefwf' IN ('wee','wefwf','weg') |
+----------------------------------+
|                                1 |
+----------------------------------+ 

```

Type conversion:

 
```
SELECT 1 IN ('1', '2', '3');
+----------------------+
| 1 IN ('1', '2', '3') |
+----------------------+
|                    1 |
+----------------------+

```


```
SELECT NULL IN (1, 2, 3);
+-------------------+
| NULL IN (1, 2, 3) |
+-------------------+
|              NULL |
+-------------------+

SELECT 1 IN (1, 2, NULL);
+-------------------+
| 1 IN (1, 2, NULL) |
+-------------------+
|                 1 |
+-------------------+

SELECT 5 IN (1, 2, NULL);
+-------------------+
| 5 IN (1, 2, NULL) |
+-------------------+
|              NULL |
+-------------------+

```

See Also
--------

 * [Conversion of Big IN Predicates Into Subqueries](../conversion-of-big-in-predicates-into-subqueries/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/in/>

INTERVAL
========

    Syntax
------

 
```
INTERVAL(N,N1,N2,N3,...)

```

Description
-----------

 Returns the index of the last argument that is less than the first argument or is NULL. 

 Returns 0 if N < N1, 1 if N < N2, 2 if N < N3 and so on or -1 if N is NULL. All arguments are treated as integers. It is required that N1 < N2 < N3 < ... < Nn for this function to work correctly. This is because a fast binary search is used. 

 Examples
--------

 
```
SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);
+--------------------------------------+
| INTERVAL(23, 1, 15, 17, 30, 44, 200) |
+--------------------------------------+
|                                    3 |
+--------------------------------------+

SELECT INTERVAL(10, 1, 10, 100, 1000);
+--------------------------------+
| INTERVAL(10, 1, 10, 100, 1000) |
+--------------------------------+
|                              2 |
+--------------------------------+

SELECT INTERVAL(22, 23, 30, 44, 200);
+-------------------------------+
| INTERVAL(22, 23, 30, 44, 200) |
+-------------------------------+
|                             0 |
+-------------------------------+

SELECT INTERVAL(10, 2, NULL);
+-----------------------+
| INTERVAL(10, 2, NULL) |
+-----------------------+
|                     2 |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/interval/>

INET\_ATON
==========

    Syntax
------

 
```
INET_ATON(expr)

```

Description
-----------

 Given the dotted-quad representation of an IPv4 network address as a string, returns an integer that represents the numeric value of the address. Addresses may be 4- or 8-byte addresses.

 Returns NULL if the argument is not understood.

 Examples
--------

 
```
SELECT INET_ATON('192.168.1.1');
+--------------------------+
| INET_ATON('192.168.1.1') |
+--------------------------+
|               3232235777 |
+--------------------------+

```

This is calculated as follows: 192 x 2563 + 168 x 256 2 + 1 x 256 + 1

 See Also
--------

 * [INET6\_ATON()](../inet6_aton/index)
* [INET\_NTOA()](../inet_ntoa/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet_aton/>

INSERT Function
===============

    Syntax
------

 
```
INSERT(str,pos,len,newstr)

```

Description
-----------

 Returns the string `str`, with the substring beginning at position `pos` and `len` characters long replaced by the string `newstr`. Returns the original string if `pos` is not within the length of the string. Replaces the rest of the string from position `pos` if `len` is not within the length of the rest of the string. Returns NULL if any argument is NULL.

 Examples
--------

 
```
SELECT INSERT('Quadratic', 3, 4, 'What');
+-----------------------------------+
| INSERT('Quadratic', 3, 4, 'What') |
+-----------------------------------+
| QuWhattic                         |
+-----------------------------------+

SELECT INSERT('Quadratic', -1, 4, 'What');
+------------------------------------+
| INSERT('Quadratic', -1, 4, 'What') |
+------------------------------------+
| Quadratic                          |
+------------------------------------+

SELECT INSERT('Quadratic', 3, 100, 'What');
+-------------------------------------+
| INSERT('Quadratic', 3, 100, 'What') |
+-------------------------------------+
| QuWhat                              |
+-------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-function/>

INET6\_ATON
===========

    Syntax
------

 
```
INET6_ATON(expr)

```

Description
-----------

 Given an IPv6 or IPv4 network address as a string, returns a binary string that represents the numeric value of the address.

 No trailing zone ID's or traling network masks are permitted. For IPv4 addresses, or IPv6 addresses with IPv4 address parts, no classful addresses or trailing port numbers are permitted and octal numbers are not supported.

 The returned binary string will be [VARBINARY(16)](../varbinary/index) or [VARBINARY(4)](../varbinary/index) for IPv6 and IPv4 addresses respectively.

 Returns NULL if the argument is not understood.

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), `INET6_ATON` can take [INET6](../inet6/index) as an argument.

 
Examples
--------

 
```
SELECT HEX(INET6_ATON('10.0.1.1'));
+-----------------------------+
| HEX(INET6_ATON('10.0.1.1')) |
+-----------------------------+
| 0A000101                    |
+-----------------------------+

SELECT HEX(INET6_ATON('48f3::d432:1431:ba23:846f'));
+----------------------------------------------+
| HEX(INET6_ATON('48f3::d432:1431:ba23:846f')) |
+----------------------------------------------+
| 48F3000000000000D4321431BA23846F             |
+----------------------------------------------+

```

See Also
--------

 * [INET6\_NTOA()](../inet6_ntoa/index)
* [INET\_ATON()](../inet_aton/index)
* [INET6](../inet6/index) Data Type

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet6_aton/>

INET\_NTOA
==========

    Syntax
------

 
```
INET_NTOA(expr)

```

Description
-----------

 Given a numeric IPv4 network address in network byte order (4 or 8 byte), returns the dotted-quad representation of the address as a string.

 Examples
--------

 
```
SELECT INET_NTOA(3232235777);
+-----------------------+
| INET_NTOA(3232235777) |
+-----------------------+
| 192.168.1.1           |
+-----------------------+

```

192.168.1.1 corresponds to 3232235777 since 192 x 2563 + 168 x 256 2 + 1 x 256 + 1 = 3232235777

 See Also
--------

 * [INET6\_NTOA()](../inet6_ntoa/index)
* [INET\_ATON()](../inet_aton/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet_ntoa/>

IS
==

    Syntax
------

 
```
IS boolean_value

```

Description
-----------

 Tests a value against a boolean value, where `boolean_value` can be TRUE, FALSE, or UNKNOWN.

 There is an important difference between using IS TRUE or comparing a value with TRUE using `=`. When using `=`, only `1` equals to TRUE. But when using IS TRUE, all values which are logically true (like a number > 1) return TRUE.

 Examples
--------

 
```
SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
+-----------+------------+-----------------+
| 1 IS TRUE | 0 IS FALSE | NULL IS UNKNOWN |
+-----------+------------+-----------------+
|         1 |          1 |               1 |
+-----------+------------+-----------------+

```

Difference between `=` and `IS TRUE`:

 
```
SELECT 2 = TRUE, 2 IS TRUE;
+----------+-----------+
| 2 = TRUE | 2 IS TRUE |
+----------+-----------+
|        0 |         1 |
+----------+-----------+

```

See Also
--------

 * [Boolean Literals](../sql-language-structure-boolean-literals/index)
* [BOOLEAN Data Type](../boolean/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is/>

INSTR
=====

    Syntax
------

 
```
INSTR(str,substr)

```
 Description
-----------

 Returns the position of the first occurrence of substring *substr* in string *str*. This is the same as the two-argument form of [LOCATE()](../locate/index), except that the order of the arguments is reversed.

 `INSTR()` performs a case-insensitive search.

 If any argument is `NULL`, returns `NULL`.

 Examples
--------

 
```
SELECT INSTR('foobarbar', 'bar');
+---------------------------+
| INSTR('foobarbar', 'bar') |
+---------------------------+
|                         4 |
+---------------------------+

SELECT INSTR('My', 'Maria');
+----------------------+
| INSTR('My', 'Maria') |
+----------------------+
|                    0 |
+----------------------+

```

See Also
--------

 * [LOCATE()](../locate/index) ; Returns the position of a string within a string
* [SUBSTRING\_INDEX()](../substring_index/index) ; Returns the substring from string before count occurrences of a delimiter

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/instr/>

INTERSECTS
==========

    Syntax
------

 
```
INTERSECTS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* spatially intersects geometry *`g2`*.

 INTERSECTS() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_INTERSECTS()](../st_intersects/index) uses object shapes.

 INTERSECTS() tests the opposite relationship to [DISJOINT()](../disjoint/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/intersects/>

IS\_FREE\_LOCK
==============

    Syntax
------

 
```
IS_FREE_LOCK(str)

```
 Description
-----------

 Checks whether the lock named `str` is free to use (that is, not locked). Returns `1` if the lock is free (no one is using the lock), `0` if the lock is in use, and `NULL` if an error occurs (such as an incorrect argument, like an empty string or `NULL`). `str` is case insensitive.

 If the [metadata\_lock\_info](../metadata_lock_info/index) plugin is installed, the [Information Schema](../information_schema/index) [metadata\_lock\_info](../information-schema-metadata_lock_info-table/index) table contains information about locks of this kind (as well as [metadata locks](../metadata-locking/index)).

 Statements using the `IS_FREE_LOCK` function are [not safe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 See Also
--------

 * [GET\_LOCK](../get_lock/index)
* [RELEASE\_LOCK](../release_lock/index)
* [IS\_USED\_LOCK](../is_used_lock/index)
* [RELEASE\_ALL\_LOCKS](../release_all_locks/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_free_lock/>

IsClosed
========

    A synonym for [ST\_IsClosed](../st_isclosed/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/isclosed/>

IS\_IPV4
========

    Syntax
------

 
```
IS_IPV4(expr)

```

Description
-----------

 If the expression is a valid IPv4 address, returns 1, otherwise returns 0.

 IS\_IPV4() is stricter than [INET\_ATON()](../inet_aton/index), but as strict as [INET6\_ATON()](../inet6_aton/index), in determining the validity of an IPv4 address. This implies that if IS\_IPV4 returns 1, the same expression will always return a non-NULL result when passed to INET\_ATON(), but that the reverse may not apply.

 Examples
--------

 
```
SELECT IS_IPV4('1110.0.1.1');
+-----------------------+
| IS_IPV4('1110.0.1.1') |
+-----------------------+
|                     0 |
+-----------------------+

SELECT IS_IPV4('48f3::d432:1431:ba23:846f');
+--------------------------------------+
| IS_IPV4('48f3::d432:1431:ba23:846f') |
+--------------------------------------+
|                                    0 |
+--------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_ipv4/>

INET6\_NTOA
===========

    Syntax
------

 
```
INET6_NTOA(expr)

```

Description
-----------

 Given an IPv6 or IPv4 network address as a numeric binary string, returns the address as a nonbinary string in the connection character set.

 The return string is lowercase, and is platform independent, since it does not use functions specific to the operating system. It has a maximum length of 39 characters.

 Returns NULL if the argument is not understood.

 Examples
--------

 
```
SELECT INET6_NTOA(UNHEX('0A000101'));
+-------------------------------+
| INET6_NTOA(UNHEX('0A000101')) |
+-------------------------------+
| 10.0.1.1                      |
+-------------------------------+

SELECT INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F'));
+-------------------------------------------------------+
| INET6_NTOA(UNHEX('48F3000000000000D4321431BA23846F')) |
+-------------------------------------------------------+
| 48f3::d432:1431:ba23:846f                             |
+-------------------------------------------------------+

```

See Also
--------

 * [INET6\_ATON()](../inet6_aton/index)
* [INET\_NTOA()](../inet_ntoa/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inet6_ntoa/>

ST\_ISEMPTY
===========

    Syntax
------

 
```
ST_IsEmpty(g)
IsEmpty(g)

```

Description
-----------

 IsEmpty is a function defined by the OpenGIS specification, but is not fully implemented by MariaDB or MySQL. 

 Since MariaDB and MySQL do not support GIS EMPTY values such as POINT EMPTY, as implemented it simply returns `1` if the geometry value *`g`* is invalid, `0` if it is valid, and `NULL` if the argument is `NULL`.

 `ST_IsEmpty()` and `IsEmpty()` are synonyms.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/isempty/>

ST\_InteriorRingN
=================

    Syntax
------

 
```
ST_InteriorRingN(poly,N)
InteriorRingN(poly,N)

```

Description
-----------

 Returns the N-th interior ring for the Polygon value `poly` as a LineString. Rings are numbered beginning with 1.

 `ST_InteriorRingN()` and `InteriorRingN()` are synonyms.

 Examples
--------

 
```
SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT AsText(InteriorRingN(GeomFromText(@poly),1));
+----------------------------------------------+
| AsText(InteriorRingN(GeomFromText(@poly),1)) |
+----------------------------------------------+
| LINESTRING(1 1,1 2,2 2,2 1,1 1)              |
+----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/interiorringn/>

IS NOT NULL
===========

    Syntax
------

 
```
IS NOT NULL

```

Description
-----------

 Tests whether a value is not NULL. See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 Examples
--------

 
```
SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
+---------------+---------------+------------------+
| 1 IS NOT NULL | 0 IS NOT NULL | NULL IS NOT NULL |
+---------------+---------------+------------------+
|             1 |             1 |                0 |
+---------------+---------------+------------------+

```

See also
--------

 * [NULL values](../null-values/index)
* [IS NULL operator](../is-null/index)
* [COALESCE function](../coalesce/index)
* [IFNULL function](../ifnull/index)
* [NULLIF function](../nullif/index)
* [CONNECT data types](../connect-data-types/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is-not-null/>

IS NULL
=======

    Syntax
------

 
```
IS NULL

```

Description
-----------

 Tests whether a value is NULL. See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 Examples
--------

 
```
SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
+-----------+-----------+--------------+
| 1 IS NULL | 0 IS NULL | NULL IS NULL |
+-----------+-----------+--------------+
|         0 |         0 |            1 |
+-----------+-----------+--------------+

```

Compatibility
-------------

 Some `ODBC` applications use the syntax `auto_increment_field IS NOT NULL` to find the latest row that was inserted with an autogenerated key value. If your applications need this, you can set the [sql\_auto\_is\_null](../server-system-variables/index#sql_auto_is_null) variable to 1.

 
```
SET @@sql_auto_is_null=1;
CREATE TABLE t1 (auto_increment_column INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
INSERT INTO t1 VALUES (NULL);
SELECT * FROM t1 WHERE auto_increment_column IS NULL;

+-----------------------+
| auto_increment_column |
+-----------------------+
|                     1 |
+-----------------------+

```

See also
--------

 * [NULL values](../null-values/index)
* [IS NOT NULL operator](../is-not-null/index)
* [COALESCE function](../coalesce/index)
* [IFNULL function](../ifnull/index)
* [NULLIF function](../nullif/index)
* [CONNECT data types](../connect-data-types/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is-null/>

IS NOT
======

    Syntax
------

 
```
IS NOT boolean_value

```

Description
-----------

 Tests a value against a boolean value, where boolean\_value can be TRUE, FALSE, or UNKNOWN. 

 Examples
--------

 
```
SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
+------------------+------------------+---------------------+
| 1 IS NOT UNKNOWN | 0 IS NOT UNKNOWN | NULL IS NOT UNKNOWN |
+------------------+------------------+---------------------+
|                1 |                1 |                   0 |
+------------------+------------------+---------------------+

```


```
SELECT NULL IS NOT TRUE, NULL IS NOT FALSE;
+------------------+-------------------+
| NULL IS NOT TRUE | NULL IS NOT FALSE |
+------------------+-------------------+
|                1 |                 1 |
+------------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is-not/>

ISNULL
======

    Syntax
------

 
```
ISNULL(expr)

```

Description
-----------

 If *`expr`* is NULL, ISNULL() returns 1, otherwise it returns 0.

 See also [NULL Values in MariaDB](../null-values-in-mariadb/index).

 Examples
--------

 
```
SELECT ISNULL(1+1);
+-------------+
| ISNULL(1+1) |
+-------------+
|           0 |
+-------------+

SELECT ISNULL(1/0);
+-------------+
| ISNULL(1/0) |
+-------------+
|           1 |
+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/isnull/>

IS\_IPV4\_COMPAT
================

    Syntax
------

 
```
IS_IPV4_COMPAT(expr)

```

Description
-----------

 Returns 1 if a given numeric binary string IPv6 address, such as returned by [INET6\_ATON()](../inet6_aton/index), is IPv4-compatible, otherwise returns 0. 

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), when the argument is not [INET6](../inet6/index), automatic implicit [CAST](../cast/index) to INET6 is applied. As a consequence, `IS_IPV4_COMPAT` now understands arguments in both text representation and binary(16) representation. Before [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), the function understood only binary(16) representation.

 
Examples
--------

 
```
SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1'));
+------------------------------------------+
| IS_IPV4_COMPAT(INET6_ATON('::10.0.1.1')) |
+------------------------------------------+
|                                        1 |
+------------------------------------------+

SELECT IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f'));
+-----------------------------------------------------------+
| IS_IPV4_COMPAT(INET6_ATON('::48f3::d432:1431:ba23:846f')) |
+-----------------------------------------------------------+
|                                                         0 |
+-----------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_ipv4_compat/>

IS\_IPV6
========

    Syntax
------

 
```
IS_IPV6(expr)

```

Description
-----------

 Returns 1 if the expression is a valid IPv6 address specified as a string, otherwise returns 0. Does not consider IPv4 addresses to be valid IPv6 addresses.

 Examples
--------

 
```
 SELECT IS_IPV6('48f3::d432:1431:ba23:846f');
+--------------------------------------+
| IS_IPV6('48f3::d432:1431:ba23:846f') |
+--------------------------------------+
|                                    1 |
+--------------------------------------+
1 row in set (0.02 sec)

SELECT IS_IPV6('10.0.1.1');
+---------------------+
| IS_IPV6('10.0.1.1') |
+---------------------+
|                   0 |
+---------------------+

```

See Also
--------

 * [INET6](../inet6/index) data type
* [INET6\_ATON](../inet6_aton/index)
* [INET6\_NTOA](../inet6_ntoa/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_ipv6/>

IS\_IPV4\_MAPPED
================

    Syntax
------

 
```
IS_IPV4_MAPPED(expr)

```

Description
-----------

 Returns 1 if a given a numeric binary string IPv6 address, such as returned by [INET6\_ATON()](../inet6_aton/index), is a valid IPv4-mapped address, otherwise returns 0.

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), when the argument is not [INET6](../inet6/index), automatic implicit [CAST](../cast/index) to INET6 is applied. As a consequence, `IS_IPV4_MAPPED` now understands arguments in both text representation and binary(16) representation. Before [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), the function understood only binary(16) representation.

 
Examples
--------

 
```
SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1'));
+------------------------------------------+
| IS_IPV4_MAPPED(INET6_ATON('::10.0.1.1')) |
+------------------------------------------+
|                                        0 |
+------------------------------------------+

SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1'));
+-----------------------------------------------+
| IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.1.1')) |
+-----------------------------------------------+
|                                             1 |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_ipv4_mapped/>

IsRing
======

    A synonym for [ST\_IsRing](../st_isring/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/isring/>

IsSimple
========

    A synonym for [ST\_IsSImple](../st_issimple/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-issimple/>

JSON\_ARRAY
===========

    Syntax
------

 
```
JSON_ARRAY([value[, value2] ...])

```

Description
-----------

 Returns a JSON array containing the listed values. The list can be empty.

 Example
-------

 
```
SELECT Json_Array(56, 3.1416, 'My name is "Foo"', NULL);
+--------------------------------------------------+
| Json_Array(56, 3.1416, 'My name is "Foo"', NULL) |
+--------------------------------------------------+
| [56, 3.1416, "My name is \"Foo\"", null]         |
+--------------------------------------------------+

```

See also
--------

 * [JSON\_MAKE\_ARRAY](../connect-json-table-type/index#json_make_array), the CONNECT storage engine function

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_array/>

IS\_USED\_LOCK
==============

    Syntax
------

 
```
IS_USED_LOCK(str)

```
 Description
-----------

 Checks whether the lock named `str` is in use (that is, locked). If so, it returns the connection identifier of the client that holds the lock. Otherwise, it returns `NULL`. `str` is case insensitive.

 If the [metadata\_lock\_info](../metadata_lock_info/index) plugin is installed, the [Information Schema](../information_schema/index) [metadata\_lock\_info](../information-schema-metadata_lock_info-table/index) table contains information about locks of this kind (as well as [metadata locks](../metadata-locking/index)).

 Statements using the `IS_USED_LOCK` function are [not safe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 See Also
--------

 * [GET\_LOCK](../get_lock/index)
* [RELEASE\_LOCK](../release_lock/index)
* [IS\_FREE\_LOCK](../is_free_lock/index)
* [RELEASE\_ALL\_LOCKS](../release_all_locks/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/is_used_lock/>

JSON\_ARRAY\_APPEND
===================

    Syntax
------

 
```
JSON_ARRAY_APPEND(json_doc, path, value[, path, value] ...)

```

Description
-----------

 Appends values to the end of the specified arrays within a JSON document, returning the result, or NULL if any of the arguments are NULL.

 Evaluation is performed from left to right, with the resulting document from the previous pair becoming the new value against which the next pair is evaluated.

 If the `json_doc` is not a valid JSON document, or if any of the paths are not valid, or contain a `*` or `**` wildcard, an error is returned.

 Examples
--------

 
```
SET @json = '[1, 2, [3, 4]]';

SELECT JSON_ARRAY_APPEND(@json, '$[0]', 5)
+-------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[0]', 5) |
+-------------------------------------+
| [[1, 5], 2, [3, 4]]                 |
+-------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$[1]', 6);
+-------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[1]', 6) |
+-------------------------------------+
| [1, [2, 6], [3, 4]]                 |
+-------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$[1]', 6, '$[2]', 7);
+------------------------------------------------+
| JSON_ARRAY_APPEND(@json, '$[1]', 6, '$[2]', 7) |
+------------------------------------------------+
| [1, [2, 6], [3, 4, 7]]                         |
+------------------------------------------------+

SELECT JSON_ARRAY_APPEND(@json, '$', 5);
+----------------------------------+
| JSON_ARRAY_APPEND(@json, '$', 5) |
+----------------------------------+
| [1, 2, [3, 4], 5]                |
+----------------------------------+

SET @json = '{"A": 1, "B": [2], "C": [3, 4]}';

SELECT JSON_ARRAY_APPEND(@json, '$.B', 5);
+------------------------------------+
| JSON_ARRAY_APPEND(@json, '$.B', 5) |
+------------------------------------+
| {"A": 1, "B": [2, 5], "C": [3, 4]} |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_array_append/>

JSON\_ARRAY\_INSERT
===================

    Syntax
------

 
```
JSON_ARRAY_INSERT(json_doc, path, value[, path, value] ...)

```

Description
-----------

 Inserts a value into a JSON document, returning the modified document, or NULL if any of the arguments are NULL.

 Evaluation is performed from left to right, with the resulting document from the previous pair becoming the new value against which the next pair is evaluated.

 If the `json_doc` is not a valid JSON document, or if any of the paths are not valid, or contain a `*` or `**` wildcard, an error is returned.

 Examples
--------

 
```
SET @json = '[1, 2, [3, 4]]';

SELECT JSON_ARRAY_INSERT(@json, '$[0]', 5);
+-------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[0]', 5) |
+-------------------------------------+
| [5, 1, 2, [3, 4]]                   |
+-------------------------------------+

SELECT JSON_ARRAY_INSERT(@json, '$[1]', 6);
+-------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[1]', 6) |
+-------------------------------------+
| [1, 6, 2, [3, 4]]                   |
+-------------------------------------+

SELECT JSON_ARRAY_INSERT(@json, '$[1]', 6, '$[2]', 7);
+------------------------------------------------+
| JSON_ARRAY_INSERT(@json, '$[1]', 6, '$[2]', 7) |
+------------------------------------------------+
| [1, 6, 7, 2, [3, 4]]                           |
+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_array_insert/>

JSON\_COMPACT
=============

    Syntax
------

 
```
JSON_COMPACT(json_doc)

```
 Description
-----------

 Removes all unnecessary spaces so the json document is as short as possible.

 Example
-------

 
```
SET @j = '{ "A": 1, "B": [2, 3]}';

SELECT JSON_COMPACT(@j), @j;
+-------------------+------------------------+
| JSON_COMPACT(@j)  | @j                     |
+-------------------+------------------------+
| {"A":1,"B":[2,3]} | { "A": 1, "B": [2, 3]} |
+-------------------+------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_COMPACT.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_compact/>

JSON\_CONTAINS
==============

    Syntax
------

 
```
JSON_CONTAINS(json_doc, val[, path])

```

Description
-----------

 Returns whether or not the specified value is found in the given JSON document or, optionally, at the specified path within the document. Returns `1` if it does, `0` if not and NULL if any of the arguments are null. An error occurs if the document or path is not valid, or contains the `*` or `**` wildcards.

 Examples
--------

 
```
SET @json = '{"A": 0, "B": {"C": 1}, "D": 2}';

SELECT JSON_CONTAINS(@json, '2', '$.A');
+----------------------------------+
| JSON_CONTAINS(@json, '2', '$.A') |
+----------------------------------+
|                                0 |
+----------------------------------+

SELECT JSON_CONTAINS(@json, '2', '$.D');
+----------------------------------+
| JSON_CONTAINS(@json, '2', '$.D') |
+----------------------------------+
|                                1 |
+----------------------------------+

SELECT JSON_CONTAINS(@json, '{"C": 1}', '$.A');
+-----------------------------------------+
| JSON_CONTAINS(@json, '{"C": 1}', '$.A') |
+-----------------------------------------+
|                                       0 |
+-----------------------------------------+

SELECT JSON_CONTAINS(@json, '{"C": 1}', '$.B');
+-----------------------------------------+
| JSON_CONTAINS(@json, '{"C": 1}', '$.B') |
+-----------------------------------------+
|                                       1 |
+-----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_contains/>

JSON\_DETAILED
==============

    Syntax
------

 
```
JSON_DETAILED(json_doc[, tab_size])
JSON_PRETTY(json_doc[, tab_size])

```
 Description
-----------

 Represents JSON in the most understandable way emphasizing nested structures. 

 `JSON_PRETTY` was added as an alias for `JSON_DETAILED` in [MariaDB 10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), [MariaDB 10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [MariaDB 10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [MariaDB 10.7.8](https://mariadb.com/kb/en/mariadb-1078-release-notes/), [MariaDB 10.6.12](https://mariadb.com/kb/en/mariadb-10612-release-notes/), [MariaDB 10.5.19](https://mariadb.com/kb/en/mariadb-10519-release-notes/) and [MariaDB 10.4.28](https://mariadb.com/kb/en/mariadb-10428-release-notes/).

 Example
-------

 
```
SET @j = '{ "A":1,"B":[2,3]}';

SELECT @j;
+--------------------+
| @j                 |
+--------------------+
| { "A":1,"B":[2,3]} |
+--------------------+

SELECT JSON_DETAILED(@j);
+------------------------------------------------------------+
| JSON_DETAILED(@j)                                          |
+------------------------------------------------------------+
| {
    "A": 1,
    "B": 
    [
        2,
        3
    ]
} |
+------------------------------------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_DETAILED.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_detailed/>

JSON\_EXISTS
============

    Syntax
------

 Description
-----------

 Determines whether a specified JSON value exists in the given data. Returns `1` if found, `0` if not, or `NULL` if any of the inputs were NULL.

 Examples
--------

 
```
SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2");
+------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2") |
+------------------------------------------------------------+
|                                                          1 |
+------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key3");
+------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key3") |
+------------------------------------------------------------+
|                                                          0 |
+------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]");
+---------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[1]") |
+---------------------------------------------------------------+
|                                                             1 |
+---------------------------------------------------------------+

SELECT JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]");
+----------------------------------------------------------------+
| JSON_EXISTS('{"key1":"xxxx", "key2":[1, 2, 3]}', "$.key2[10]") |
+----------------------------------------------------------------+
|                                                              0 |
+----------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_exists/>

JSON\_CONTAINS\_PATH
====================

    Syntax
------

 
```
JSON_CONTAINS_PATH(json_doc, return_arg, path[, path] ...)

```

Description
-----------

 Indicates whether the given JSON document contains data at the specified path or paths. Returns `1` if it does, `0` if not and NULL if any of the arguments are null.

 The *return\_arg* can be `one` or `all`:

 * `one` - Returns `1` if at least one path exists within the JSON document.
* `all` - Returns `1` only if all paths exist within the JSON document.

 Examples
--------

 
```
SET @json = '{"A": 1, "B": [2], "C": [3, 4]}';

SELECT JSON_CONTAINS_PATH(@json, 'one', '$.A', '$.D');
+------------------------------------------------+
| JSON_CONTAINS_PATH(@json, 'one', '$.A', '$.D') |
+------------------------------------------------+
|                                              1 |
+------------------------------------------------+
1 row in set (0.00 sec)

SELECT JSON_CONTAINS_PATH(@json, 'all', '$.A', '$.D');
+------------------------------------------------+
| JSON_CONTAINS_PATH(@json, 'all', '$.A', '$.D') |
+------------------------------------------------+
|                                              0 |
+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_contains_path/>

JSON\_DEPTH
===========

    Syntax
------

 
```
JSON_DEPTH(json_doc)

```

Description
-----------

 Returns the maximum depth of the given JSON document, or NULL if the argument is null. An error will occur if the argument is an invalid JSON document.

 * Scalar values or empty arrays or objects have a depth of 1.
* Arrays or objects that are not empty but contain only elements or member values of depth 1 will have a depth of 2.
* In other cases, the depth will be greater than 2.

 Examples
--------

 
```
SELECT JSON_DEPTH('[]'), JSON_DEPTH('true'), JSON_DEPTH('{}');
+------------------+--------------------+------------------+
| JSON_DEPTH('[]') | JSON_DEPTH('true') | JSON_DEPTH('{}') |
+------------------+--------------------+------------------+
|                1 |                  1 |                1 |
+------------------+--------------------+------------------+

SELECT JSON_DEPTH('[1, 2, 3]'), JSON_DEPTH('[[], {}, []]');
+-------------------------+----------------------------+
| JSON_DEPTH('[1, 2, 3]') | JSON_DEPTH('[[], {}, []]') |
+-------------------------+----------------------------+
|                       2 |                          2 |
+-------------------------+----------------------------+

SELECT JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]');
+---------------------------------------+
| JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]') |
+---------------------------------------+
|                                     3 |
+---------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_depth/>

JSON\_ARRAY\_INTERSECT
======================

    
**MariaDB starting with [11.2.0](https://mariadb.com/kb/en/mariadb-1120-release-notes/)**JSON\_ARRAY\_INTERSECT was added in [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).

 
Syntax
------

 
```
JSON_ARRAY_INTERSECT(arr1, arr2) :

```

Description
-----------

 Goes over one of the json and adds each item of the array in hash (after normalizing each item). Go over the second array, searching the normalized item one by one in the hash. If the item is found, adds it to the result.

 Examples
--------

 
```
SET @json1= '[1,2,3]';
SET @json2= '[1,2,4]';

SELECT json_array_intersect(@json1, @json2); 
+--------------------------------------+
| json_array_intersect(@json1, @json2) |
+--------------------------------------+
| [1, 2]                               |
+--------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_array_intersect/>

JSON\_EXTRACT
=============

    Syntax
------

 
```
JSON_EXTRACT(json_doc, path[, path] ...)

```

Description
-----------

 Extracts data from a JSON document. The extracted data is selected from the parts matching the path arguments. Returns all matched values; either as a single matched value, or, if the arguments could return multiple values, a result autowrapped as an array in the matching order.

 Returns NULL if no paths match or if any of the arguments are NULL. 

 An error will occur if any path argument is not a valid path, or if the json\_doc argument is not a valid JSON document.

 The path expression be a [JSONPath expression](../jsonpath-expressions/index) as supported by MariaDB 

 Examples
--------

 
```
SET @json = '[1, 2, [3, 4]]';

SELECT JSON_EXTRACT(@json, '$[1]');
+-----------------------------+
| JSON_EXTRACT(@json, '$[1]') |
+-----------------------------+
| 2                           |
+-----------------------------+

SELECT JSON_EXTRACT(@json, '$[2]');
+-----------------------------+
| JSON_EXTRACT(@json, '$[2]') |
+-----------------------------+
| [3, 4]                      |
+-----------------------------+

SELECT JSON_EXTRACT(@json, '$[2][1]');
+--------------------------------+
| JSON_EXTRACT(@json, '$[2][1]') |
+--------------------------------+
| 4                              |
+--------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_EXTRACT.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_extract/>

JSON\_KEYS
==========

    Syntax
------

 
```
JSON_KEYS(json_doc[, path])

```

Description
-----------

 Returns the keys as a JSON array from the top-level value of a JSON object or, if the optional path argument is provided, the top-level keys from the path. 

 Excludes keys from nested sub-objects in the top level value. The resulting array will be empty if the selected object is empty.

 Returns NULL if any of the arguments are null, a given path does not locate an object, or if the json\_doc argument is not an object.

 An error will occur if JSON document is invalid, the path is invalid or if the path contains a `*` or `**` wildcard.

 Examples
--------

 
```
SELECT JSON_KEYS('{"A": 1, "B": {"C": 2}}');
+--------------------------------------+
| JSON_KEYS('{"A": 1, "B": {"C": 2}}') |
+--------------------------------------+
| ["A", "B"]                           |
+--------------------------------------+

SELECT JSON_KEYS('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C');
+-----------------------------------------------------+
| JSON_KEYS('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C') |
+-----------------------------------------------------+
| ["D"]                                               |
+-----------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_keys/>

JSON\_INSERT
============

    Syntax
------

 
```
JSON_INSERT(json_doc, path, val[, path, val] ...)

```
 Description
-----------

 Inserts data into a JSON document, returning the resulting document or NULL if either of the *json\_doc* or *path* arguments are null. 

 An error will occur if the JSON document is invalid, or if any of the paths are invalid or contain a `*` or `**` wildcard.

 JSON\_INSERT can only insert data while [JSON\_REPLACE](../json_replace/index) can only update. [JSON\_SET](../json_set/index) can update or insert data. 

 Examples
--------

 
```
SET @json = '{ "A": 0, "B": [1, 2]}';

SELECT JSON_INSERT(@json, '$.C', '[3, 4]');
+--------------------------------------+
| JSON_INSERT(@json, '$.C', '[3, 4]')  |
+--------------------------------------+
| { "A": 0, "B": [1, 2], "C":"[3, 4]"} |
+--------------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_INSERT.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_insert/>

JSON\_EQUALS
============

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**JSON\_EQUALS was added in [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)

 
Syntax
------

 
```
JSON_EQUALS(json1, json2)

```

Description
-----------

 Checks if there is equality between two json objects. Returns `1` if it there is, `0` if not, or NULL if any of the arguments are null.

 Examples
--------

 
```
SELECT JSON_EQUALS('{"a"   :[1, 2, 3],"b":[4]}', '{"b":[4],"a":[1, 2, 3.0]}');
+------------------------------------------------------------------------+
| JSON_EQUALS('{"a"   :[1, 2, 3],"b":[4]}', '{"b":[4],"a":[1, 2, 3.0]}') |
+------------------------------------------------------------------------+
|                                                                      1 |
+------------------------------------------------------------------------+

SELECT JSON_EQUALS('{"a":[1, 2, 3]}', '{"a":[1, 2, 3.01]}');
+------------------------------------------------------+
| JSON_EQUALS('{"a":[1, 2, 3]}', '{"a":[1, 2, 3.01]}') |
+------------------------------------------------------+
|                                                    0 |
+------------------------------------------------------+

```

See Also
--------

 * [JSON\_NORMALIZE](../json_normalize/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_equals/>

JSON\_LENGTH
============

    Syntax
------

 
```
JSON_LENGTH(json_doc[, path])

```

Description
-----------

 Returns the length of a JSON document, or, if the optional path argument is given, the length of the value within the document specified by the path. 

 Returns NULL if any of the arguments argument are null or the path argument does not identify a value in the document. 

 An error will occur if the JSON document is invalid, the path is invalid or if the path contains a `*` or `**` wildcard.

 Length will be determined as follow:

 * A scalar's length is always 1.
* If an array, the number of elements in the array.
* If an object, the number of members in the object.

 The length of nested arrays or objects are not counted.

 Examples
--------

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_length/>

JSON\_MERGE
===========

    Syntax
------

 
```
JSON_MERGE(json_doc, json_doc[, json_doc] ...)

```

Description
-----------

 Merges the given JSON documents.

 Returns the merged result,or NULL if any argument is NULL.

 An error occurs if any of the arguments are not valid JSON documents.

 `JSON_MERGE` has been deprecated since [MariaDB 10.2.25](https://mariadb.com/kb/en/mariadb-10225-release-notes/), [MariaDB 10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/) and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/). [JSON\_MERGE\_PATCH](../json_merge_patch/index) is an RFC 7396-compliant replacement, and [JSON\_MERGE\_PRESERVE](../json_merge_preserve/index) is a synonym.

 Example
-------

 
```
SET @json1 = '[1, 2]';
SET @json2 = '[3, 4]';

SELECT JSON_MERGE(@json1,@json2);
+---------------------------+
| JSON_MERGE(@json1,@json2) |
+---------------------------+
| [1, 2, 3, 4]              |
+---------------------------+

```

See Also
--------

 * [JSON\_MERGE\_PATCH](../json_merge_patch/index)
* [JSON\_MERGE\_PRESERVE](../json_merge_preserve/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_merge/>

JSON\_LOOSE
===========

    Syntax
------

 
```
JSON_LOOSE(json_doc)

```

Description
-----------

 Adds spaces to a JSON document to make it look more readable.

 Example
-------

 
```
SET @j = '{ "A":1,"B":[2,3]}';

SELECT JSON_LOOSE(@j), @j;
+-----------------------+--------------------+
| JSON_LOOSE(@j)        | @j                 |
+-----------------------+--------------------+
| {"A": 1, "B": [2, 3]} | { "A":1,"B":[2,3]} |
+-----------------------+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_loose/>

JSON\_OBJECT
============

    Syntax
------

 
```
JSON_OBJECT([key, value[, key, value] ...])

```

Description
-----------

 Returns a JSON object containing the given key/value pairs. The key/value list can be empty.

 An error will occur if there are an odd number of arguments, or any key name is NULL.

 Example
-------

 
```
SELECT JSON_OBJECT("id", 1, "name", "Monty");
+---------------------------------------+
| JSON_OBJECT("id", 1, "name", "Monty") |
+---------------------------------------+
| {"id": 1, "name": "Monty"}            |
+---------------------------------------+

```

See also
--------

 * [JSON\_MAKE\_OBJECT](../connect-json-table-type/index#json_make_object), the CONNECT storage engine function

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_object/>

JSON\_NORMALIZE
===============

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**JSON\_NORMALIZE was added in [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/).

 
Syntax
------

 
```
JSON_NORMALIZE(json)

```

Description
-----------

 Recursively sorts keys and removes spaces, allowing comparison of json documents for equality.

 Examples
--------

 We may wish our application to use the database to enforce a unique constraint on the JSON contents, and we can do so using the JSON\_NORMALIZE function in combination with a unique key.

 For example, if we have a table with a JSON column:

 
```
CREATE TABLE t1 (
 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
 val JSON,
 /* other columns here */
 PRIMARY KEY (id)
);

```

Add a unique constraint using JSON\_NORMALIZE like this:

 
```
ALTER TABLE t1
   ADD COLUMN jnorm JSON AS (JSON_NORMALIZE(val)) VIRTUAL,
   ADD UNIQUE KEY (jnorm);

```

We can test this by first inserting a row as normal:

 
```
INSERT INTO t1 (val) VALUES ('{"name":"alice","color":"blue"}');

```

And then seeing what happens with a different string which would produce the same JSON object:

 
```
INSERT INTO t1 (val) VALUES ('{ "color": "blue", "name": "alice" }');
ERROR 1062 (23000): Duplicate entry '{"color":"blue","name":"alice"}' for key 'jnorm'

```

See Also
--------

 * [JSON\_EQUALS](../json_equals/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_normalize/>

JSON\_QUERY
===========

    Syntax
------

 
```
JSON_QUERY(json_doc, path)

```

Description
-----------

 Given a JSON document, returns an object or array specified by the path. Returns NULL if not given a valid JSON document, or if there is no match.

 Examples
--------

 
```
select json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1');
+-----------------------------------------------------+
| json_query('{"key1":{"a":1, "b":[1,2]}}', '$.key1') |
+-----------------------------------------------------+
| {"a":1, "b":[1,2]}                                  |
+-----------------------------------------------------+

select json_query('{"key1":123, "key1": [1,2,3]}', '$.key1');
+-------------------------------------------------------+
| json_query('{"key1":123, "key1": [1,2,3]}', '$.key1') |
+-------------------------------------------------------+
| [1,2,3]                                               |
+-------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_query/>

JSON\_OBJECTAGG
===============

    
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**JSON\_OBJECTAGG was added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
Syntax
------

 
```
JSON_OBJECTAGG(key, value)

```

Description
-----------

 `JSON_OBJECTAGG` returns a JSON object containing key-value pairs. It takes two expressions that evaluate to a single value, or two column names, as arguments, the first used as a key, and the second as a value. 

 Returns NULL in the case of an error, or if the result contains no rows.

 `JSON_OBJECTAGG` cannot currently be used as a [window function](../window-functions/index).

 Examples
--------

 
```
select * from t1;
+------+-------+
| a    | b     |
+------+-------+
|    1 | Hello |
|    1 | World |
|    2 | This  |
+------+-------+

SELECT JSON_OBJECTAGG(a, b) FROM t1;
+----------------------------------------+
| JSON_OBJECTAGG(a, b)                   |
+----------------------------------------+
| {"1":"Hello", "1":"World", "2":"This"} |
+----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_objectagg/>

JSON\_OBJECT\_FILTER\_KEYS
==========================

    
**MariaDB starting with [11.2.0](https://mariadb.com/kb/en/mariadb-1120-release-notes/)**JSON\_OBJECT\_FILTER\_KEYS was added in [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).

 
Syntax
------

 
```
JSON_OBJECT_FILTER_KEYS(obj, array_keys)

```

Description
-----------

 `JSON_OBJECT_FILTER_KEYS` puts keys *array\_keys* in a hash, goes over the object *obj* and gets the key one by one. If the key is present in the hash, adds the key-value pair to result.

 Example
-------

 
```
SET @obj1= '{ "a": 1, "b": 2, "c": 3}';
SET @obj2= '{"b" : 10, "c": 20, "d": 30}';
SELECT JSON_OBJECT_FILTER_KEYS (@obj1, JSON_ARRAY_INTERSECT(JSON_KEYS(@obj1), JSON_KEYS(@obj2)));
+-------------------------------------------------------------------------------------------+
| JSON_OBJECT_FILTER_KEYS (@obj1, JSON_ARRAY_INTERSECT(JSON_KEYS(@obj1), JSON_KEYS(@obj2))) |
+-------------------------------------------------------------------------------------------+
| {"b": 2, "c": 3}                                                                          |
+-------------------------------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_object_filter_keys/>

JSON\_QUOTE
===========

    Syntax
------

 
```
JSON_QUOTE(json_value)

```

Description
-----------

 Quotes a string as a JSON value, usually for producing valid JSON string literals for inclusion in JSON documents. Wraps the string with double quote characters and escapes interior quotes and other special characters, returning a utf8mb4 string. 

 Returns NULL if the argument is NULL.

 Examples
--------

 
```
SELECT JSON_QUOTE('A'), JSON_QUOTE("B"), JSON_QUOTE('"C"');
+-----------------+-----------------+-------------------+
| JSON_QUOTE('A') | JSON_QUOTE("B") | JSON_QUOTE('"C"') |
+-----------------+-----------------+-------------------+
| "A"             | "B"             | "\"C\""           |
+-----------------+-----------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_quote/>

JSON\_REMOVE
============

    Syntax
------

 
```
JSON_REMOVE(json_doc, path[, path] ...)

```
 Description
-----------

 Removes data from a JSON document returning the result, or NULL if any of the arguments are null. If the element does not exist in the document, no changes are made.

 The function returns NULL and throws a warning if the JSON document is invalid, the path is invalid, contains a range, or contains a `*` or `**` wildcard.

 Path arguments are evaluated from left to right, with the result from the earlier evaluation being used as the value for the next.

 Examples
--------

 
```
SELECT JSON_REMOVE('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C');
+-------------------------------------------------------+
| JSON_REMOVE('{"A": 1, "B": 2, "C": {"D": 3}}', '$.C') |
+-------------------------------------------------------+
| {"A": 1, "B": 2}                                      |
+-------------------------------------------------------+

SELECT JSON_REMOVE('["A", "B", ["C", "D"], "E"]', '$[1]');
+----------------------------------------------------+
| JSON_REMOVE('["A", "B", ["C", "D"], "E"]', '$[1]') |
+----------------------------------------------------+
| ["A", ["C", "D"], "E"]                             |
+----------------------------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_REMOVE.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_remove/>

JSON\_REPLACE
=============

    Syntax
------

 
```
JSON_REPLACE(json_doc, path, val[, path, val] ...)

```
 Description
-----------

 Replaces existing values in a JSON document, returning the result, or NULL if any of the arguments are NULL. 

 An error will occur if the JSON document is invalid, the path is invalid or if the path contains a `*` or `**` wildcard.

 Paths and values are evaluated from left to right, with the result from the earlier evaluation being used as the value for the next.

 JSON\_REPLACE can only update data, while [JSON\_INSERT](../json_insert/index) can only insert. [JSON\_SET](../json_set/index) can update or insert data. 

 Examples
--------

 
```
SELECT JSON_REPLACE('{ "A": 1, "B": [2, 3]}', '$.B[1]', 4);
+-----------------------------------------------------+
| JSON_REPLACE('{ "A": 1, "B": [2, 3]}', '$.B[1]', 4) |
+-----------------------------------------------------+
| { "A": 1, "B": [2, 4]}                              |
+-----------------------------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_REPLACE.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_replace/>

JSON\_PRETTY
============

    `JSON_PRETTY` was added as an alias for [JSON\_DETAILED](../json_detailed/index) in [MariaDB 10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), [MariaDB 10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [MariaDB 10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [MariaDB 10.7.8](https://mariadb.com/kb/en/mariadb-1078-release-notes/), [MariaDB 10.6.12](https://mariadb.com/kb/en/mariadb-10612-release-notes/), [MariaDB 10.5.19](https://mariadb.com/kb/en/mariadb-10519-release-notes/) and [MariaDB 10.4.28](https://mariadb.com/kb/en/mariadb-10428-release-notes/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_pretty/>

JSON\_OBJECT\_TO\_ARRAY
=======================

    
**MariaDB starting with [11.2.0](https://mariadb.com/kb/en/mariadb-1120-release-notes/)**JSON\_OBJECT\_TO\_ARRAY was added in [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/).

 
Syntax
------

 
```
JSON_OBJECT_TO_ARRAY(Obj)

```

Description
-----------

 Create a string variable, Go over the json object, and add each key value pair as an array into the result.

 Examples
--------

 
```
SET @obj1= '{ "a": [1, 2, 3], "b": { "key1":"val1", "key2": {"key3":"val3"} }}';

SELECT JSON_OBJECT_TO_ARRAY(@obj1);
+-----------------------------------------------------------------------+
| JSON_OBJECT_TO_ARRAY(@obj1)                                           |
+-----------------------------------------------------------------------+
| [["a", [1, 2, 3]], ["b", {"key1": "val1", "key2": {"key3": "val3"}}]] |
+-----------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_object_to_array/>

JSON\_SEARCH
============

    Syntax
------

 
```
JSON_SEARCH(json_doc, return_arg, search_str[, escape_char[, path] ...])

```

Description
-----------

 Returns the path to the given string within a JSON document, or NULL if any of *json\_doc*, *search\_str* or a path argument is NULL; if the search string is not found, or if no path exists within the document. 

 A warning will occur if the JSON document is not valid, any of the path arguments are not valid, if *return\_arg* is neither *one* nor *all*, or if the escape character is not a constant. NULL will be returned.

 *return\_arg* can be one of two values:

 * `'one`: Terminates after finding the first match, so will return one path string. If there is more than one match, it is undefined which is considered first.
* `all`: Returns all matching path strings, without duplicates. Multiple strings are autowrapped as an array. The order is undefined.

 Examples
--------

 
```
SET @json = '["A", [{"B": "1"}], {"C":"AB"}, {"D":"BC"}]';

SELECT JSON_SEARCH(@json, 'one', 'AB');
+---------------------------------+
| JSON_SEARCH(@json, 'one', 'AB') |
+---------------------------------+
| "$[2].C"                        |
+---------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_search/>

JSON\_OVERLAPS
==============

    
**MariaDB starting with [10.9](../what-is-mariadb-109/index)**JSON\_OVERLAPS was added in [MariaDB 10.9](../what-is-mariadb-109/index).

 
Syntax
------

 
```
JSON_OVERLAPS(json_doc1, json_doc2)

```

Description
-----------

 JSON\_OVERLAPS() compares two json documents and returns true if they have at least one common key-value pair between two objects, array element common between two arrays, or array element common with scalar if one of the arguments is a scalar and other is an array. If two json documents are scalars, it returns true if they have same type and value.

 If none of the above conditions are satisfied then it returns false.

 Examples
--------

 
```
SELECT JSON_OVERLAPS('false', 'false');
+---------------------------------+
| JSON_OVERLAPS('false', 'false') |
+---------------------------------+
| 1                               |
+---------------------------------+

SELECT JSON_OVERLAPS('true', '["abc", 1, 2, true, false]');
+----------------------------------------------------+
| JSON_OVERLAPS('true','["abc", 1, 2, true, false]') |
+----------------------------------------------------+
| 1                                                  |
+----------------------------------------------------+

SELECT JSON_OVERLAPS('{"A": 1, "B": {"C":2}}', '{"A": 2, "B": {"C":2}}') AS is_overlap;
+---------------------+
| is_overlap          |
+---------------------+
| 1                   |
+---------------------+

```

Partial match is considered as no-match.

 Examples
--------

 
```
SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, [1]]') AS is_overlap;
+--------------------- +
| is_overlap           |
+----------------------+
| 0                    |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_overlaps/>

JSON\_SET
=========

    Syntax
------

 
```
JSON_SET(json_doc, path, val[, path, val] ...)

```

Description
-----------

 Updates or inserts data into a JSON document, returning the result, or NULL if any of the arguments are NULL or the optional path fails to find an object.

 An error will occur if the JSON document is invalid, the path is invalid or if the path contains a \* or  **wildcard.**

 JSON\_SET can update or insert data, while [JSON\_REPLACE](../json_replace/index) can only update, and [JSON\_INSERT](../json_insert/index) only insert. 

 Examples
--------

 
```
SELECT JSON_SET(Priv, '$.locked', 'true') FROM mysql.global_priv

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_set/>

LAST\_DAY
=========

    Syntax
------

 
```
LAST_DAY(date)

```

Description
-----------

 Takes a date or datetime value and returns the corresponding value for the last day of the month. Returns NULL if the argument is invalid.

 Examples
--------

 
```
SELECT LAST_DAY('2003-02-05');
+------------------------+
| LAST_DAY('2003-02-05') |
+------------------------+
| 2003-02-28             |
+------------------------+

SELECT LAST_DAY('2004-02-05');
+------------------------+
| LAST_DAY('2004-02-05') |
+------------------------+
| 2004-02-29             |
+------------------------+

SELECT LAST_DAY('2004-01-01 01:01:01');
+---------------------------------+
| LAST_DAY('2004-01-01 01:01:01') |
+---------------------------------+
| 2004-01-31                      |
+---------------------------------+

SELECT LAST_DAY('2003-03-32');
+------------------------+
| LAST_DAY('2003-03-32') |
+------------------------+
| NULL                   |
+------------------------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Incorrect datetime value: '2003-03-32'

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/last_day/>

JSON\_SCHEMA\_VALID
===================

    
**MariaDB starting with [11.1](../what-is-mariadb-111/index)**`JSON_SCHEMA_VALID` was introduced in [MariaDB 11.1](../what-is-mariadb-111/index).

 
### Syntax

 
```
JSON_SCHEMA_VALID(schema, json);

```
 Description
-----------

 `JSON_SCHEMA_VALID` allows MariaDB to support JSON schema validation. If a given json is valid against a schema it returns true. When JSON does not validate against the schema, it does not return a message about which keyword it failed against and only returns false.

 The function supports [JSON Schema Draft 2020](https://json-schema.org/draft/2020-12/release-notes.html) with a few exceptions:

 * External resources are not supported
* Hyper schema keywords are not supported
* Formats like date, email etc are treated as annotations.

 Examples
--------

 To create validation rules for json field

 
```
CREATE TABLE obj_table(val_obj JSON CHECK(JSON_SCHEMA_VALID('{
  "type":"object",
    "properties": {
      "number1":{
        "type":"number",
        "maximum":5,
        "const":4
      },
      "string1":{
        "type":"string",
        "maxLength":5,
        "minLength":3
      },
    "object1":{
      "type":"object",
       "properties":{
         "key1": {"type":"string"},
         "key2":{"type":"array"},
         "key3":{"type":"number", "minimum":3}
       },
       "dependentRequired": { "key1":["key3"] }
     }
  },
  "required":["number1","object1"]
  }', val_obj)));

INSERT INTO obj_table VALUES(
  '{"number1":4, "string1":"abcd", 
  "object1":{"key1":"val1", "key2":[1,2,3, "string1"], "key3":4}}'
);

INSERT INTO obj_table VALUES(
  '{"number1":3, "string1":"abcd", 
  "object1":{"key1":"val1", "key2":[1,2,3, "string1"], "key3":4}}'
);
ERROR 4025 (23000): CONSTRAINT `obj_table.val_obj` failed for `test`.`obj_table`

SELECT * FROM obj_table;
+--------------------------------------------------------------------------------------------------+
| val_obj                                                                                          |
+--------------------------------------------------------------------------------------------------+
| {"number1":4, "string1":"abcd", "object1":{"key1":"val1", "key2":[1,2,3, "string1"], "key3":4}} |
+--------------------------------------------------------------------------------------------------+

SET @schema= '{
  "properties" : {
    "number1":{ "maximum":10 },
    "string1" : { "maxLength": 3} 
  }
}';

SELECT JSON_SCHEMA_VALID(@schema, '{ "number1":25, "string1":"ab" }');
+----------------------------------------------------------------+
| JSON_SCHEMA_VALID(@schema, '{ "number1":25, "string1":"ab" }') |
+----------------------------------------------------------------+
|                                                              0 |
+----------------------------------------------------------------+

SELECT JSON_SCHEMA_VALID(@schema, '{ "number1":10, "string1":"ab" }');
+----------------------------------------------------------------+
| JSON_SCHEMA_VALID(@schema, '{ "number1":10, "string1":"ab" }') |
+----------------------------------------------------------------+
|                                                              1 |
+----------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_schema_valid/>

LAST\_INSERT\_ID
================

    Syntax
------

 
```
LAST_INSERT_ID(), LAST_INSERT_ID(expr)

```
 Description
-----------

 LAST\_INSERT\_ID() (no arguments) returns the first automatically generated value successfully inserted for an [AUTO\_INCREMENT](../auto_increment/index) column as a result of the most recently executed INSERT statement. The value of LAST\_INSERT\_ID() remains unchanged if no rows are successfully inserted.

 If one gives an argument to LAST\_INSERT\_ID(), then it will return the value of the expression and the next call to LAST\_INSERT\_ID() will return the same value. The value will also be sent to the client and can be accessed by the [mysql\_insert\_id](../mysql_insert_id/index) function.

 For example, after inserting a row that generates an AUTO\_INCREMENT value, you can get the value like this:

 
```
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                9 |
+------------------+

```

You can also use LAST\_INSERT\_ID() to delete the last inserted row:

 
```
DELETE FROM product WHERE id = LAST_INSERT_ID();

```

If no rows were successfully inserted, LAST\_INSERT\_ID() returns 0.

 The value of LAST\_INSERT\_ID() will be consistent across all versions if all rows in the [INSERT](../insert/index) or [UPDATE](../update/index) statement were successful.

 The currently executing statement does not affect the value of LAST\_INSERT\_ID(). Suppose that you generate an AUTO\_INCREMENT value with one statement, and then refer to LAST\_INSERT\_ID() in a multiple-row INSERT statement that inserts rows into a table with its own AUTO\_INCREMENT column. The value of LAST\_INSERT\_ID() will remain stable in the second statement; its value for the second and later rows is not affected by the earlier row insertions. (However, if you mix references to LAST\_INSERT\_ID() and LAST\_INSERT\_ID(expr), the effect is undefined.)

 If the previous statement returned an error, the value of LAST\_INSERT\_ID() is undefined. For transactional tables, if the statement is rolled back due to an error, the value of LAST\_INSERT\_ID() is left undefined. For manual [ROLLBACK](../rollback/index), the value of LAST\_INSERT\_ID() is not restored to that before the transaction; it remains as it was at the point of the ROLLBACK.

 Within the body of a stored routine (procedure or function) or a trigger, the value of LAST\_INSERT\_ID() changes the same way as for statements executed outside the body of these kinds of objects. The effect of a stored routine or trigger upon the value of LAST\_INSERT\_ID() that is seen by following statements depends on the kind of routine:

 * If a [stored procedure](../stored-procedures/index) executes statements that change the value of LAST\_INSERT\_ID(), the new value will be seen by statements that follow the procedure call.

 * For [stored functions](../stored-functions/index) and [triggers](../triggers/index) that change the value, the value is restored when the function or trigger ends, so following statements will not see a changed value.

 Examples
--------

 
```
CREATE TABLE t (
  id INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
  f VARCHAR(1)) 
ENGINE = InnoDB;

INSERT INTO t(f) VALUES('a');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                1 |
+------------------+

INSERT INTO t(f) VALUES('b');

INSERT INTO t(f) VALUES('c');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                3 |
+------------------+

INSERT INTO t(f) VALUES('d'),('e');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                4 |
+------------------+

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
+----+------+

SELECT LAST_INSERT_ID(12);
+--------------------+
| LAST_INSERT_ID(12) |
+--------------------+
|                 12 |
+--------------------+

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|               12 |
+------------------+

INSERT INTO t(f) VALUES('f');

SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                6 |
+------------------+

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
|  6 | f    |
+----+------+

SELECT LAST_INSERT_ID(12);
+--------------------+
| LAST_INSERT_ID(12) |
+--------------------+
|                 12 |
+--------------------+

INSERT INTO t(f) VALUES('g');

SELECT * FROM t;
+----+------+
| id | f    |
+----+------+
|  1 | a    |
|  2 | b    |
|  3 | c    |
|  4 | d    |
|  5 | e    |
|  6 | f    |
|  7 | g    |
+----+------+

```

See Also
--------

 * [mysql\_insert\_id](../mysql_insert_id/index)
* [AUTO\_INCREMENT](../auto_increment/index)
* [AUTO\_INCREMENT handling in InnoDB](../auto_increment-handling-in-innodb/index)
* [Sequences](../sequences/index) - an alternative to auto\_increment available from [MariaDB 10.3](../what-is-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/last_insert_id/>

JSON\_TYPE
==========

    Syntax
------

 
```
JSON_TYPE(json_val)

```

Description
-----------

 Returns the type of a JSON value (as a string), or NULL if the argument is null.

 An error will occur if the argument is an invalid JSON value.

 The following is a complete list of the possible return types:

 


| Return type | Value | Example |
| --- | --- | --- |
| ARRAY | JSON array | [1, 2, {"key": "value"}] |
| OBJECT | JSON object | {"key":"value"} |
| BOOLEAN | JSON true/false literals | true, false |
| DOUBLE | A number with at least one floating point decimal. | 1.2 |
| INTEGER | A number without a floating point decimal. | 1 |
| NULL | JSON null literal (this is returned as a string, not to be confused with the SQL NULL value!) | null |
| STRING | JSON String | "a sample string" |

 
Examples
--------

 
```
SELECT JSON_TYPE('{"A": 1, "B": 2, "C": 3}');
+---------------------------------------+
| JSON_TYPE('{"A": 1, "B": 2, "C": 3}') |
+---------------------------------------+
| OBJECT                                |
+---------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_type/>

JSON\_UNQUOTE
=============

    Syntax
------

 
```
JSON_UNQUOTE(val)

```

Description
-----------

 Unquotes a JSON value, returning a string, or NULL if the argument is null. 

 An error will occur if the given value begins and ends with double quotes and is an invalid JSON string literal.

 If the given value is not a JSON string, value is passed through unmodified.

 Certain character sequences have special meanings within a string. Usually, a backslash is ignored, but the escape sequences in the table below are recognised by MariaDB, unless the [SQL Mode](../sql-mode/index) is set to NO\_BACKSLASH\_ESCAPES SQL.

 


| Escape sequence | Character |
| --- | --- |
| `\"` | Double quote (") |
| `\b` | Backslash |
| `\f` | Formfeed |
| `\n` | Newline (linefeed) |
| `\r` | Carriage return |
| `\t` | Tab |
| `\\` | Backslash (\) |
| `\uXXXX` | UTF-8 bytes for Unicode value XXXX |

 
Examples
--------

 
```
SELECT JSON_UNQUOTE('"Monty"');
+-------------------------+
| JSON_UNQUOTE('"Monty"') |
+-------------------------+
| Monty                   |
+-------------------------+

```

With the default [SQL Mode](../sql-mode/index):

 
```
SELECT JSON_UNQUOTE('Si\bng\ting');
+-----------------------------+
| JSON_UNQUOTE('Si\bng\ting') |
+-----------------------------+
| Sng	ing                   |
+-----------------------------+

```

Setting NO\_BACKSLASH\_ESCAPES:

 
```
SET @@sql_mode = 'NO_BACKSLASH_ESCAPES';

SELECT JSON_UNQUOTE('Si\bng\ting');
+-----------------------------+
| JSON_UNQUOTE('Si\bng\ting') |
+-----------------------------+
| Si\bng\ting                 |
+-----------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_unquote/>

JSON\_TABLE
===========

    
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**JSON\_TABLE was added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).

 
JSON\_TABLE is a table function that converts JSON data into a relational form.

 Syntax
------

 
```
JSON_TABLE(json_doc, 
          context_path COLUMNS (column_list)
) [AS] alias

```


```
column_list:
    column[, column][, ...]

```


```
column:
    name FOR ORDINALITY
    |  name type PATH path_str [on_empty] [on_error]
    |  name type EXISTS PATH path_str
    |  NESTED PATH path_str COLUMNS (column_list)

```


```
on_empty:
    {NULL | DEFAULT string | ERROR} ON EMPTY

```


```
on_error:
    {NULL | DEFAULT string | ERROR} ON ERROR

```
 Description
-----------

 JSON\_TABLE can be used in contexts where a table reference can be used; in the FROM clause of a [SELECT](../select/index) statement, and in multi-table [UPDATE](../update/index)/[DELETE](../delete/index) statements.

 `json_doc` is the JSON document to extract data from. In the simplest case, it is a string literal containing JSON. In more complex cases it can be an arbitrary expression returning JSON. The expression may have references to columns of other tables. However, one can only refer to tables that precede this JSON\_TABLE invocation. For RIGHT JOIN, it is assumed that its outer side precedes the inner. All tables in outer selects are also considered preceding.

 `context_path` is a [JSON Path](../jsonpath-expressions/index) expression pointing to a collection of nodes in `json_doc` that will be used as the source of rows.

 The `COLUMNS` clause declares the names and types of the columns that JSON\_TABLE returns, as well as how the values of the columns are produced.

 ### Column Definitions

 The following types of columns are supported:

 #### Path Columns

 
```
name type PATH path_str [on_empty] [on_error]

```

Locates the JSON node pointed to by `path_str` and returns its value. The path\_str is evaluated using the current row source node as the context node.

 
```
set @json='
[
  {"name":"Laptop", "color":"black", "price":"1000"},
  {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
  columns(
   name  varchar(10) path '$.name', 
   color varchar(10) path '$.color',
   price decimal(8,2) path '$.price' ) 
) as jt;
+--------+-------+---------+
| name   | color | price   |
+--------+-------+---------+
| Laptop | black | 1000.00 |
| Jeans  | blue  |    NULL |
+--------+-------+---------+

```

The `on_empty` and `on_error` clauses specify the actions to be performed when the value was not found or there was an error condition. See the ON EMPTY and ON ERROR clauses section for details.

 #### ORDINALITY Columns

 
```
name FOR ORDINALITY

```

Counts the rows, starting from 1. 

 Example:

 
```
set @json='
[
  {"name":"Laptop", "color":"black"},
  {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
  columns(
   id for ordinality, 
   name  varchar(10) path '$.name')
) as jt;
+------+--------+
| id   | name   |
+------+--------+
|    1 | Laptop |
|    2 | Jeans  |
+------+--------+

```

#### EXISTS PATH Columns

 
```
name type EXISTS PATH path_str

```

Checks whether the node pointed to by `value_path` exists. The `value_path` is evaluated using the current row source node as the context node.

 
```
set @json='
[
  {"name":"Laptop", "color":"black", "price":1000},
  {"name":"Jeans",  "color":"blue"}
]';

select * from json_table(@json, '$[*]' 
  columns(
   name  varchar(10) path '$.name',
   has_price integer exists path '$.price')
) as jt;
+--------+-----------+
| name   | has_price |
+--------+-----------+
| Laptop |         1 |
| Jeans  |         0 |
+--------+-----------+

```

#### NESTED PATHs

 NESTED PATH converts nested JSON structures into multiple rows.

 
```
NESTED PATH path COLUMNS (column_list)

```

It finds the sequence of JSON nodes pointed to by `path` and uses it to produce rows. For each found node, a row is generated with column values as specified by the NESTED PATH's COLUMNS clause. If `path` finds no nodes, only one row is generated with all columns having NULL values.

 For example, consider a JSON document that contains an array of items, and each item, in turn, is expected to have an array of its available sizes:

 
```
set @json='
[
  {"name":"Jeans",  "sizes": [32, 34, 36]},
  {"name":"T-Shirt", "sizes":["Medium", "Large"]},
  {"name":"Cellphone"}
]';

```

NESTED PATH allows one to produce a separate row for each size each item has:

 
```
select * from json_table(@json, '$[*]' 
  columns(
    name  varchar(10) path '$.name', 
    nested path '$.sizes[*]' columns (
      size varchar(32) path '$'
    )
  )
) as jt;
+-----------+--------+
| name      | size   |
+-----------+--------+
| Jeans     | 32     |
| Jeans     | 34     |
| Jeans     | 36     |
| T-Shirt   | Medium |
| T-Shirt   | Large  |
| Cellphone | NULL   |
+-----------+--------+

```

NESTED PATH clauses can be nested within one another. They can also be located next to each other. In that case, the nested path clauses will produce records one at a time. The ones that are not producing records will have all columns set to NULL.

 Example:

 
```
set @json='
[
  {"name":"Jeans",  "sizes": [32, 34, 36], "colors":["black", "blue"]}
]';

select * from json_table(@json, '$[*]' 
  columns(
    name  varchar(10) path '$.name', 
    nested path '$.sizes[*]' columns (
      size varchar(32) path '$'
    ),
    nested path '$.colors[*]' columns (
      color varchar(32) path '$'
    )
  )
) as jt;

+-------+------+-------+
| name  | size | color |
+-------+------+-------+
| Jeans | 32   | NULL  |
| Jeans | 34   | NULL  |
| Jeans | 36   | NULL  |
| Jeans | NULL | black |
| Jeans | NULL | blue  |
+-------+------+-------+

```

### ON EMPTY and ON ERROR Clauses

 The ON EMPTY clause specifies what will be done when the element specified by the search path is missing in the JSON document.

 
```
on_empty:
    {NULL | DEFAULT string | ERROR} ON EMPTY

```

When `ON EMPTY` clause is not present, `NULL ON EMPTY` is implied.

 
```
on_error:
    {NULL | DEFAULT string | ERROR} ON ERROR

```

The ON ERROR clause specifies what should be done if a JSON structure error occurs when trying to extract the value pointed to by the path expression. A JSON structure error here occurs only when one attempts to convert a JSON non-scalar (array or object) into a scalar value. When the `ON ERROR` clause is not present, `NULL ON ERROR` is implied.

 **Note**: A datatype conversion error (e.g. attempt to store a non-integer value into an [integer](../int/index) field, or a [varchar](../varchar/index) column being truncated) is not considered a JSON error and so will not trigger the `ON ERROR` behavior. It will produce warnings, in the same way as [CAST(value AS datatype)](../cast/index) would.

 ### Replication

 In the current code, evaluation of JSON\_TABLE is deterministic, that is, for a given input string JSON\_TABLE will always produce the same set of rows in the same order. However, one can think of JSON documents that one can consider identical which will produce different output. In order to be future-proof and withstand changes like:

 * sorting JSON object members by name (like MySQL does)
* changing the way duplicate object members are handled the function is marked as [unsafe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 ### Extracting a Subdocument into a Column

 
**MariaDB starting with [10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/)**Prior to [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/), JSON\_TABLE did not allow one to extract a JSON "subdocument" into a JSON column. 

 
```
SELECT * FROM JSON_TABLE('{"foo": [1,2,3,4]}','$' columns( jscol json path '$.foo') ) AS T;
+-------+
| jscol |
+-------+
| NULL  |
+-------+

```

This is supported from [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/):

 
```
SELECT * FROM JSON_TABLE('{"foo": [1,2,3,4]}','$' columns( jscol json path '$.foo') ) AS T;
+-----------+
| jscol     |
+-----------+
| [1,2,3,4] |
+-----------+

```


See Also
--------

 * [JSON Support](https://www.youtube.com/watch?v=ZkmwHPqA790) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_table/>

LEAST
=====

    Syntax
------

 
```
LEAST(value1,value2,...)

```

Description
-----------

 With two or more arguments, returns the smallest (minimum-valued) argument. The arguments are compared using the following rules:

 * If the return value is used in an INTEGER context or all arguments are integer-valued, they are compared as integers.
* If the return value is used in a REAL context or all arguments are real-valued, they are compared as reals.
* If any argument is a case-sensitive string, the arguments are compared as case-sensitive strings.
* In all other cases, the arguments are compared as case-insensitive strings.

 LEAST() returns NULL if any argument is NULL.

 Examples
--------

 
```
SELECT LEAST(2,0);
+------------+
| LEAST(2,0) |
+------------+
|          0 |
+------------+

```


```
SELECT LEAST(34.0,3.0,5.0,767.0);
+---------------------------+
| LEAST(34.0,3.0,5.0,767.0) |
+---------------------------+
|                       3.0 |
+---------------------------+

```


```
SELECT LEAST('B','A','C');
+--------------------+
| LEAST('B','A','C') |
+--------------------+
| A                  |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/least/>

JSON\_VALUE
===========

    Syntax
------

 
```
JSON_VALUE(json_doc, path)

```

Description
-----------

 Given a JSON document, returns the scalar specified by the path. Returns NULL if not given a valid JSON document, or if there is no match.

 Examples
--------

 
```
select json_value('{"key1":123}', '$.key1');
+--------------------------------------+
| json_value('{"key1":123}', '$.key1') |
+--------------------------------------+
| 123                                  |
+--------------------------------------+

select json_value('{"key1": [1,2,3], "key1":123}', '$.key1');
+-------------------------------------------------------+
| json_value('{"key1": [1,2,3], "key1":123}', '$.key1') |
+-------------------------------------------------------+
| 123                                                   |
+-------------------------------------------------------+

```

In the SET statement below, two escape characters are needed, as a single escape character would be applied by the SQL parser in the SET statement, and the escaped character would not form part of the saved value.

 
```
SET @json = '{"key1":"60\\" Table", "key2":"1"}';

SELECT JSON_VALUE(@json,'$.key1') AS Name , json_value(@json,'$.key2') as ID;
+-----------+------+
| Name      | ID   |
+-----------+------+
| 60" Table | 1    |
+-----------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_value/>

LCASE
=====

    Syntax
------

 
```
LCASE(str)

```

Description
-----------

 LCASE() is a synonym for [LOWER()](../lower/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lcase/>

JSON\_VALID
===========

    Syntax
------

 
```
JSON_VALID(value)

```
 Description
-----------

 Indicates whether the given value is a valid JSON document or not. Returns `1` if valid, `0` if not, and NULL if the argument is NULL.

 From [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), the JSON\_VALID function is automatically used as a [CHECK constraint](../constraint/index#check-constraints) for the [JSON data type alias](../json-data-type/index) in order to ensure that a valid json document is inserted. 

 Examples
--------

 
```
SELECT JSON_VALID('{"id": 1, "name": "Monty"}');
+------------------------------------------+
| JSON_VALID('{"id": 1, "name": "Monty"}') |
+------------------------------------------+
|                                        1 |
+------------------------------------------+

SELECT JSON_VALID('{"id": 1, "name": "Monty", "oddfield"}');
+------------------------------------------------------+
| JSON_VALID('{"id": 1, "name": "Monty", "oddfield"}') |
+------------------------------------------------------+
|                                                    0 |
+------------------------------------------------------+

```

See Also
--------

 * [JSON video tutorial](https://www.youtube.com/watch?v=sLE7jPETp8g) covering JSON\_VALID.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_valid/>

LEFT
====

    Syntax
------

 
```
LEFT(str,len)

```

Description
-----------

 Returns the leftmost `len` characters from the string `str`, or NULL if any argument is NULL.

 Examples
--------

 
```
SELECT LEFT('MariaDB', 5);
+--------------------+
| LEFT('MariaDB', 5) |
+--------------------+
| Maria              |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/left/>

LENGTH
======

    Syntax
------

 
```
LENGTH(str)

```
 Description
-----------

 Returns the length of the string `str`.

 In the default mode, when [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions) is not set, the length is measured in bytes. In this case, a multi-byte character counts as multiple bytes. This means that for a string containing five two-byte characters, `LENGTH()` returns 10, whereas [CHAR\_LENGTH()](../char_length/index) returns 5. 

 When running [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions), the length is measured in characters, and `LENGTH` is a synonym for [CHAR\_LENGTH()](../char_length/index).

 If `str` is not a string value, it is converted into a string. If `str` is `NULL`, the function returns `NULL`.

 Examples
--------

 
```
SELECT LENGTH('MariaDB');
+-------------------+
| LENGTH('MariaDB') |
+-------------------+
|                 7 |
+-------------------+

```

When [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3](../what-is-mariadb-103/index) is not set:

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

In [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions):

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

See Also
--------

 * [CHAR\_LENGTH()](../char_length/index)
* [LENGTHB()](../lengthb/index)
* [OCTET\_LENGTH()](../octet_length/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/length/>

LINESTRING
==========

    Syntax
------

 
```
LineString(pt1,pt2,...)

```

Description
-----------

 Constructs a [WKB](../wkb/index) LineString value from a number of WKB [Point](../point/index) arguments. If any argument is not a WKB Point, the return value is `NULL`. If the number of [Point](../point/index) arguments is less than two, the return value is `NULL`.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(EndPoint(GeomFromText(@ls)));
+-------------------------------------+
| AsText(EndPoint(GeomFromText(@ls))) |
+-------------------------------------+
| POINT(3 3)                          |
+-------------------------------------+

CREATE TABLE gis_line  (g LINESTRING);
INSERT INTO gis_line VALUES
    (LineFromText('LINESTRING(0 0,0 10,10 0)')),
    (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
    (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring/>

LIKE
====

    Syntax
------

 
```
expr LIKE pat [ESCAPE 'escape_char']
expr NOT LIKE pat [ESCAPE 'escape_char']

```
 Description
-----------

 Tests whether *expr* matches the pattern *pat*. Returns either 1 (`TRUE`) or 0 (`FALSE`). Both *expr* and *pat* may be any valid expression and are evaluated to strings. Patterns may use the following wildcard characters:

 * `%` matches any number of characters, including zero.
* `_` matches any single character.

 Use `NOT LIKE` to test if a string does not match a pattern. This is equivalent to using the `[NOT](../not/index)` operator on the entire `LIKE` expression.

 If either the expression or the pattern is `NULL`, the result is `NULL`.

 `LIKE` performs case-insensitive substring matches if the collation for the expression and pattern is case-insensitive. For case-sensitive matches, declare either argument to use a binary collation using `[COLLATE](collate)`, or coerce either of them to a `[BINARY](../binary/index)` string using `[CAST](../cast/index)`. Use `[SHOW COLLATION](../show-collation/index)` to get a list of available collations. Collations ending in `_bin` are case-sensitive.

 Numeric arguments are coerced to binary strings.

 The `_` wildcard matches a single character, not byte. It will only match a multi-byte character if it is valid in the expression's character set. For example, `_` will match `_utf8"€"`, but it will not match `_latin1"€"` because the Euro sign is not a valid latin1 character. If necessary, use `[CONVERT](../convert/index)` to use the expression in a different character set.

 If you need to match the characters `_` or `%`, you must escape them. By default, you can prefix the wildcard characters the backslash character `\` to escape them. The backslash is used both to encode special characters like newlines when a string is parsed as well as to escape wildcards in a pattern after parsing. Thus, to match an actual backslash, you sometimes need to double-escape it as `"\``\``\``\"`.

 To avoid difficulties with the backslash character, you can change the wildcard escape character using `ESCAPE` in a `LIKE` expression. The argument to `ESCAPE` must be a single-character string.

 Examples
--------

 Select the days that begin with "T":

 
```
CREATE TABLE t1 (d VARCHAR(16));
INSERT INTO t1 VALUES 
  ("Monday"), ("Tuesday"), ("Wednesday"), 
  ("Thursday"), ("Friday"), ("Saturday"), ("Sunday");
SELECT * FROM t1 WHERE d LIKE "T%";

```


```
SELECT * FROM t1 WHERE d LIKE "T%";
+----------+
| d        |
+----------+
| Tuesday  |
| Thursday |
+----------+

```

Select the days that contain the substring "es":

 
```
SELECT * FROM t1 WHERE d LIKE "%es%";

```


```
SELECT * FROM t1 WHERE d LIKE "%es%";
+-----------+
| d         |
+-----------+
| Tuesday   |
| Wednesday |
+-----------+

```

Select the six-character day names:

 
```
SELECT * FROM t1 WHERE d like "___day";

```


```
SELECT * FROM t1 WHERE d like "___day";
+---------+
| d       |
+---------+
| Monday  |
| Friday  |
| Sunday  |
+---------+

```

With the default collations, `LIKE` is case-insensitive:

 
```
SELECT * FROM t1 where d like "t%";

```


```
SELECT * FROM t1 where d like "t%";
+----------+
| d        |
+----------+
| Tuesday  |
| Thursday |
+----------+

```

Use `[COLLATE](collate)` to specify a binary collation, forcing case-sensitive matches:

 
```
SELECT * FROM t1 WHERE d like "t%" COLLATE latin1_bin;

```


```
SELECT * FROM t1 WHERE d like "t%" COLLATE latin1_bin;
Empty set (0.00 sec)

```

You can include functions and operators in the expression to match. Select dates based on their day name:

 
```
CREATE TABLE t2 (d DATETIME);
INSERT INTO t2 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");
SELECT * FROM t2 WHERE DAYNAME(d) LIKE "T%";

```


```
SELECT * FROM t2 WHERE DAYNAME(d) LIKE "T%";
+------------------+
| d                |
+------------------+
| 2007-01-30 21:31 |
| 2011-04-21 12:34 |
| 2004-10-07 11:19 |
+------------------+
3 rows in set, 7 warnings (0.00 sec)

```

Optimizing LIKE
---------------

 * MariaDB can use indexes for LIKE on string columns in the case where the LIKE doesn't start with `%` or `_`.
* Starting from [MariaDB 10.0](../what-is-mariadb-100/index), one can set the [optimizer\_use\_condition\_selectivity](../server-system-variables/index#optimizer_use_condition_selectivity) variable to 5. If this is done, then the optimizer will read [optimizer\_selectivity\_sampling\_limit](../server-system-variables/index#optimizer_selectivity_sampling_limit) rows to calculate the selectivity of the LIKE expression before starting to calculate the query plan. This can help speed up some LIKE queries by providing the optimizer with more information about your data.

 See Also
--------

 * For searches on text columns, with results sorted by relevance, see [full-text](../full-text-indexes/index) indexes.
* For more complex searches and operations on strings, you can use [regular expressions](../regular-expressions-functions/index), which were enhanced in MariaDB 10 (see [PCRE Regular Expressions](../pcre-regular-expressions/index)).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/like/>

LAST\_VALUE
===========

    Syntax
------

 
```
LAST_VALUE(expr,[expr,...])

```


```
LAST_VALUE(expr) OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 

```
 Description
-----------

 `LAST_VALUE()` evaluates all expressions and returns the last.

 This is useful together with [setting user variables to a value with @var:=expr](../set/index), for example when you want to get data of rows updated/deleted without having to do two queries against the table.

 LAST\_VALUE can be used as a [window function](../window-functions/index).

 Returns NULL if no last value exists.

 Examples
--------

 
```
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES(1,10),(2,20);
DELETE FROM t1 WHERE a=1 AND last_value(@a:=a,@b:=b,1);
SELECT @a,@b;
+------+------+
| @a   | @b   |
+------+------+
|    1 |   10 |
+------+------+

```

As a [window function](../window-functions/index):

 
```
CREATE TABLE t1 (
  pk int primary key,
  a int,
  b int,
  c char(10),
  d decimal(10, 3),
  e real
);

INSERT INTO t1 VALUES
( 1, 0, 1,    'one',    0.1,  0.001),
( 2, 0, 2,    'two',    0.2,  0.002),
( 3, 0, 3,    'three',  0.3,  0.003),
( 4, 1, 2,    'three',  0.4,  0.004),
( 5, 1, 1,    'two',    0.5,  0.005),
( 6, 1, 1,    'one',    0.6,  0.006),
( 7, 2, NULL, 'n_one',  0.5,  0.007),
( 8, 2, 1,    'n_two',  NULL, 0.008),
( 9, 2, 2,    NULL,     0.7,  0.009),
(10, 2, 0,    'n_four', 0.8,  0.010),
(11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, FIRST_VALUE(pk) OVER (ORDER BY pk) AS first_asc,
           LAST_VALUE(pk) OVER (ORDER BY pk) AS last_asc,
           FIRST_VALUE(pk) OVER (ORDER BY pk DESC) AS first_desc,
           LAST_VALUE(pk) OVER (ORDER BY pk DESC) AS last_desc
FROM t1
ORDER BY pk DESC;

+----+-----------+----------+------------+-----------+
| pk | first_asc | last_asc | first_desc | last_desc |
+----+-----------+----------+------------+-----------+
| 11 |         1 |       11 |         11 |        11 |
| 10 |         1 |       10 |         11 |        10 |
|  9 |         1 |        9 |         11 |         9 |
|  8 |         1 |        8 |         11 |         8 |
|  7 |         1 |        7 |         11 |         7 |
|  6 |         1 |        6 |         11 |         6 |
|  5 |         1 |        5 |         11 |         5 |
|  4 |         1 |        4 |         11 |         4 |
|  3 |         1 |        3 |         11 |         3 |
|  2 |         1 |        2 |         11 |         2 |
|  1 |         1 |        1 |         11 |         1 |
+----+-----------+----------+------------+-----------+

```


```
CREATE OR REPLACE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

SELECT i,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS f_1f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS l_1f,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS f_1p1f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS l_1p1f,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS f_2p1p,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS l_2p1p,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS f_1f2f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS l_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i    | f_1f | l_1f | f_1p1f | l_1p1f | f_2p1p | l_2p1p | f_1f2f | l_1f2f |
+------+------+------+--------+--------+--------+--------+--------+--------+
|    1 |    1 |    2 |      1 |      2 |   NULL |   NULL |      2 |      3 |
|    2 |    2 |    3 |      1 |      3 |      1 |      1 |      3 |      4 |
|    3 |    3 |    4 |      2 |      4 |      1 |      2 |      4 |      5 |
|    4 |    4 |    5 |      3 |      5 |      2 |      3 |      5 |      6 |
|    5 |    5 |    6 |      4 |      6 |      3 |      4 |      6 |      7 |
|    6 |    6 |    7 |      5 |      7 |      4 |      5 |      7 |      8 |
|    7 |    7 |    8 |      6 |      8 |      5 |      6 |      8 |      9 |
|    8 |    8 |    9 |      7 |      9 |      6 |      7 |      9 |     10 |
|    9 |    9 |   10 |      8 |     10 |      7 |      8 |     10 |     10 |
|   10 |   10 |   10 |      9 |     10 |      8 |      9 |   NULL |   NULL |
+------+------+------+--------+--------+--------+--------+--------+--------+

```

See Also
--------

 * [Setting a variable to a value](../set/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/last_value/>

LN
==

    Syntax
------

 
```
LN(X)

```

Description
-----------

 Returns the natural logarithm of X; that is, the base-e logarithm of X. If X is less than or equal to 0, or `NULL`, then NULL is returned.

 The inverse of this function is `[EXP()](../exp/index)`.

 Examples
--------

 
```
SELECT LN(2);
+-------------------+
| LN(2)             |
+-------------------+
| 0.693147180559945 |
+-------------------+

SELECT LN(-2);
+--------+
| LN(-2) |
+--------+
|   NULL |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ln/>

ST\_LineFromWKB
===============

    Syntax
------

 
```
ST_LineFromWKB(wkb[,srid])
LineFromWKB(wkb[,srid])
ST_LineStringFromWKB(wkb[,srid])
LineStringFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a LINESTRING value using its [WKB](../well-known-binary-wkb-format/index) representation and SRID.

 `ST_LineFromWKB()`, `LineFromWKB()`, `ST_LineStringFromWKB()`, and `LineStringFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(ST_LineFromText('LineString(0 4,4 6)'));

SELECT ST_AsText(ST_LineFromWKB(@g)) AS l;
+---------------------+
| l                   |
+---------------------+
| LINESTRING(0 4,4 6) |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linefromwkb/>

LOCALTIME
=========

    Syntax
------

 
```
LOCALTIME
LOCALTIME([precision])

```

Description
-----------

 `LOCALTIME` and `LOCALTIME()` are synonyms for `[NOW()](../now/index)`.

 See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/localtime/>

LOCALTIMESTAMP
==============

    Syntax
------

 
```
LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

```

Description
-----------

 `LOCALTIMESTAMP` and `LOCALTIMESTAMP()` are synonyms for `[NOW()](../now/index)`.

 See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/localtimestamp/>

ST\_LineFromText
================

    Syntax
------

 
```
ST_LineFromText(wkt[,srid])
ST_LineStringFromText(wkt[,srid])
LineFromText(wkt[,srid])
LineStringFromText(wkt[,srid])

```

Description
-----------

 Constructs a [LINESTRING](../linestring/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `ST_LineFromText()`, `ST_LineStringFromText()`, `ST_LineFromText()` and `ST_LineStringFromText()` are all synonyms.

 Examples
--------

 
```
CREATE TABLE gis_line  (g LINESTRING);
SHOW FIELDS FROM gis_line;
INSERT INTO gis_line VALUES
    (LineFromText('LINESTRING(0 0,0 10,10 0)')),
    (LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
    (LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linefromtext/>

LineStringFromWKB
=================

    A synonym for [ST\_LineFromWKB](../st_linefromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestringfromwkb/>

LOAD\_FILE
==========

    Syntax
------

 
```
LOAD_FILE(file_name)

```
 Description
-----------

 Reads the file and returns the file contents as a string. To use this function, the file must be located on the server host, you must specify the full path name to the file, and you must have the FILE privilege. The file must be readable by all and it must be less than the size, in bytes, of the [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) system variable. If the [secure\_file\_priv](../server-system-variables/index#secure_file_priv) system variable is set to a non-empty directory name, the file to be loaded must be located in that directory.

 If the file does not exist or cannot be read because one of the preceding conditions is not satisfied, the function returns NULL.

 Since [MariaDB 5.1](../what-is-mariadb-51/index), the [character\_set\_filesystem](../server-system-variables/index#character_set_filesystem) system variable has controlled interpretation of file names that are given as literal strings.

 Statements using the LOAD\_FILE() function are not [safe for statement based replication](../unsafe-statements-for-replication/index). This is because the slave will execute the LOAD\_FILE() command itself. If the file doesn't exist on the slave, the function will return NULL.

 Examples
--------

 
```
UPDATE t SET blob_col=LOAD_FILE('/tmp/picture') WHERE id=1;

```

See Also
--------

 * [SELECT INTO DUMPFILE](../select-into-dumpfile/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load_file/>

LineStringFromText
==================

    A synonym for [ST\_LineFromText](../st_linefromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestringfromtext/>

LOCATE
======

    Syntax
------

 
```
LOCATE(substr,str), LOCATE(substr,str,pos)

```

Description
-----------

 The first syntax returns the position of the first occurrence of substring `substr` in string `str`. The second syntax returns the position of the first occurrence of substring `substr` in string `str`, starting at position `pos`. Returns 0 if `substr` is not in `str`.

 `LOCATE()` performs a case-insensitive search.

 If any argument is `NULL`, returns `NULL.`

 [INSTR()](../instr/index) is the same as the two-argument form of `LOCATE()`, except that the order of the arguments is reversed.

 Examples
--------

 
```
SELECT LOCATE('bar', 'foobarbar');
+----------------------------+
| LOCATE('bar', 'foobarbar') |
+----------------------------+
|                          4 |
+----------------------------+

SELECT LOCATE('My', 'Maria');
+-----------------------+
| LOCATE('My', 'Maria') |
+-----------------------+
|                     0 |
+-----------------------+

SELECT LOCATE('bar', 'foobarbar', 5);
+-------------------------------+
| LOCATE('bar', 'foobarbar', 5) |
+-------------------------------+
|                             7 |
+-------------------------------+

```

See Also
--------

 * [INSTR()](../instr/index) ; Returns the position of a string withing a string
* [SUBSTRING\_INDEX()](../substring_index/index) ; Returns the substring from string before count occurrences of a delimiter

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/locate/>

LOG
===

    Syntax
------

 
```
LOG(X), LOG(B,X)

```

Description
-----------

 If called with one parameter, this function returns the natural logarithm of X. If X is less than or equal to 0, then NULL is returned.

 If called with two parameters, it returns the logarithm of X to the base B. If B is <= 1 or X <= 0, the function returns NULL.

 If any argument is `NULL`, the function returns `NULL`.

 The inverse of this function (when called with a single argument) is the [EXP()](../exp/index) function.

 Examples
--------

 LOG(X):

 
```
SELECT LOG(2);
+-------------------+
| LOG(2)            |
+-------------------+
| 0.693147180559945 |
+-------------------+

SELECT LOG(-2);
+---------+
| LOG(-2) |
+---------+
|    NULL |
+---------+

```

LOG(B,X)

 
```
SELECT LOG(2,16);
+-----------+
| LOG(2,16) |
+-----------+
|         4 |
+-----------+

SELECT LOG(3,27);
+-----------+
| LOG(3,27) |
+-----------+
|         3 |
+-----------+

SELECT LOG(3,1);
+----------+
| LOG(3,1) |
+----------+
|        0 |
+----------+

SELECT LOG(3,0);
+----------+
| LOG(3,0) |
+----------+
|     NULL |
+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/log/>

LOWER
=====

    Syntax
------

 
```
LOWER(str)

```
 Description
-----------

 Returns the string `str` with all characters changed to lowercase according to the current character set mapping. The default is latin1 (cp1252 West European).

 Examples
--------

 
```
 SELECT LOWER('QUADRATICALLY');
+------------------------+
| LOWER('QUADRATICALLY') |
+------------------------+
| quadratically          |
+------------------------+

```

`LOWER()` (and `[UPPER](../upper/index)()`) are ineffective when applied to binary strings (`[BINARY](../binary/index)`, `[VARBINARY](../varbinary/index)`, `[BLOB](../blob/index)`). To perform lettercase conversion, [CONVERT](../convert/index) the string to a non-binary string:

 
```
SET @str = BINARY 'North Carolina';

SELECT LOWER(@str), LOWER(CONVERT(@str USING latin1));
+----------------+-----------------------------------+
| LOWER(@str)    | LOWER(CONVERT(@str USING latin1)) |
+----------------+-----------------------------------+
| North Carolina | north carolina                    |
+----------------+-----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lower/>

PREVIOUS VALUE FOR sequence\_name
=================================

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**SEQUENCEs were introduced in [MariaDB 10.3](../what-is-mariadb-103/index).

 
Syntax
------

 
```
PREVIOUS VALUE FOR sequence_name

```

or

 
```
LASTVAL(sequence_name)

```

or in Oracle mode ([SQL\_MODE=ORACLE](../sql-mode/index))

 
```
sequence_name.currval

```
 `PREVIOUS VALUE FOR` is IBM DB2 syntax while `LASTVAL()` is PostgreSQL syntax.

 Description
-----------

 Get last value in the current connection generated from a sequence.

 * If the sequence has not yet been used by the connection, `PREVIOUS VALUE FOR` returns `NULL` (the same thing applies with a new connection which doesn't see a last value for an existing sequence).
* If a `SEQUENCE` has been dropped and re-created then it's treated as a new `SEQUENCE` and `PREVIOUS VALUE FOR` will return `NULL`.
* `[FLUSH TABLES](../flush/index)` has no effect on `PREVIOUS VALUE FOR`.
* Previous values for all used sequences are stored per connection until connection ends.
* `PREVIOUS VALUE FOR` requires the [SELECT privilege](../grant/index).

 Example
-------

 
```
CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

SELECT PREVIOUS VALUE FOR s;
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                 NULL |
+----------------------+

# The function works for sequences only, if the table is used an error is generated
SELECT PREVIOUS VALUE FOR t;
ERROR 4089 (42S02): 'test.t' is not a SEQUENCE

# Call the NEXT VALUE FOR s:
SELECT NEXT VALUE FOR s;
+------------------+
| NEXT VALUE FOR s |
+------------------+
|              100 |
+------------------+

SELECT PREVIOUS VALUE FOR s;
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                  100 |
+----------------------+

```

Now try to start the new connection and check that the last value is still NULL, before updating the value in the new connection after the output of the new connection gets current value (110 in the example below). Note that first connection cannot see this change and the result of last value still remains the same (100 in the example above).

 
```
$ .mysql -uroot test -e"SELECT PREVIOUS VALUE FOR s; SELECT NEXT VALUE FOR s; SELECT PREVIOUS VALUE FOR s;"
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                 NULL |
+----------------------+
+------------------+
| NEXT VALUE FOR s |
+------------------+
|              110 |
+------------------+
+----------------------+
| PREVIOUS VALUE FOR s |
+----------------------+
|                  110 |
+----------------------+

```

See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [NEXT VALUE FOR](../next-value-for-sequence_name/index)
* [SETVAL()](../setval/index). Set next value for the sequence.
* [AUTO\_INCREMENT](../auto_increment/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/previous-value-for-sequence_name/>

LOG2
====

    Syntax
------

 
```
LOG2(X)

```

Description
-----------

 Returns the base-2 logarithm of X.

 Examples
--------

 
```
SELECT LOG2(4398046511104);
+---------------------+
| LOG2(4398046511104) |
+---------------------+
|                  42 |
+---------------------+

SELECT LOG2(65536);
+-------------+
| LOG2(65536) |
+-------------+
|          16 |
+-------------+

SELECT LOG2(-100);
+------------+
| LOG2(-100) |
+------------+
|       NULL |
+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/log2/>

LPAD
====

    Syntax
------

 
```
LPAD(str, len [,padstr])

```
 Description
-----------

 Returns the string `str`, left-padded with the string `padstr` to a length of `len` characters. If `str` is longer than `len`, the return value is shortened to `len` characters. If `padstr` is omitted, the LPAD function pads spaces.

 Prior to [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), the `padstr` parameter was mandatory.

 Returns NULL if given a NULL argument. If the result is empty (zero length), returns either an empty string or, from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) with [SQL\_MODE=Oracle](../sql_modeoracle-from-mariadb-103/index), NULL.

 The Oracle mode version of the function can be accessed outside of Oracle mode by using `LPAD_ORACLE` as the function name.

 Examples
--------

 
```
SELECT LPAD('hello',10,'.');
+----------------------+
| LPAD('hello',10,'.') |
+----------------------+
| .....hello           |
+----------------------+

SELECT LPAD('hello',2,'.');
+---------------------+
| LPAD('hello',2,'.') |
+---------------------+
| he                  |
+---------------------+

```

From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), with the pad string defaulting to space.

 
```
SELECT LPAD('hello',10);
+------------------+
| LPAD('hello',10) |
+------------------+
|      hello       |
+------------------+

```

Oracle mode version from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/):

 
```
SELECT LPAD('',0),LPAD_ORACLE('',0);
+------------+-------------------+
| LPAD('',0) | LPAD_ORACLE('',0) |
+------------+-------------------+
|            | NULL              |
+------------+-------------------+

```

See Also
--------

 * [RPAD](../rpad/index) - Right-padding instead of left-padding.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lpad/>

LOG10
=====

    Syntax
------

 
```
LOG10(X)

```

Description
-----------

 Returns the base-10 logarithm of X.

 Examples
--------

 
```
SELECT LOG10(2);
+-------------------+
| LOG10(2)          |
+-------------------+
| 0.301029995663981 |
+-------------------+

SELECT LOG10(100);
+------------+
| LOG10(100) |
+------------+
|          2 |
+------------+

SELECT LOG10(-100);
+-------------+
| LOG10(-100) |
+-------------+
|        NULL |
+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/log10/>

MAKE\_SET
=========

    Syntax
------

 
```
MAKE_SET(bits,str1,str2,...)

```

Description
-----------

 Returns a set value (a string containing substrings separated by "," characters) consisting of the strings that have the corresponding bit in bits set. *`str1`* corresponds to bit 0, *`str2`* to bit 1, and so on. NULL values in *`str1`*, *`str2`*, ... are not appended to the result.

 Examples
--------

 
```
SELECT MAKE_SET(1,'a','b','c');
+-------------------------+
| MAKE_SET(1,'a','b','c') |
+-------------------------+
| a                       |
+-------------------------+

SELECT MAKE_SET(1 | 4,'hello','nice','world');
+----------------------------------------+
| MAKE_SET(1 | 4,'hello','nice','world') |
+----------------------------------------+
| hello,world                            |
+----------------------------------------+

SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
+---------------------------------------------+
| MAKE_SET(1 | 4,'hello','nice',NULL,'world') |
+---------------------------------------------+
| hello                                       |
+---------------------------------------------+

SELECT QUOTE(MAKE_SET(0,'a','b','c'));
+--------------------------------+
| QUOTE(MAKE_SET(0,'a','b','c')) |
+--------------------------------+
| ''                             |
+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/make_set/>

MAKEDATE
========

    Syntax
------

 
```
MAKEDATE(year,dayofyear)

```

Description
-----------

 Returns a date, given `year` and `day-of-year values`. `dayofyear` must be greater than 0 or the result is NULL.

 Examples
--------

 
```
SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);
+-------------------+-------------------+
| MAKEDATE(2011,31) | MAKEDATE(2011,32) |
+-------------------+-------------------+
| 2011-01-31        | 2011-02-01        |
+-------------------+-------------------+

SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);
+--------------------+--------------------+
| MAKEDATE(2011,365) | MAKEDATE(2014,365) |
+--------------------+--------------------+
| 2011-12-31         | 2014-12-31         |
+--------------------+--------------------+

SELECT MAKEDATE(2011,0);
+------------------+
| MAKEDATE(2011,0) |
+------------------+
| NULL             |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/makedate/>

MASTER\_POS\_WAIT
=================

    Syntax
------

 
```
MASTER_POS_WAIT(log_name,log_pos[,timeout,["connection_name"]])

```

Description
-----------

 This function is useful in [replication](../replication/index) for controlling primary/replica synchronization. It blocks until the replica has read and applied all updates up to the specified position (`log_name,log_pos`) in the primary log. The return value is the number of log events the replica had to wait for to advance to the specified position. The function returns NULL if the replica SQL thread is not started, the replica's primary information is not initialized, the arguments are incorrect, or an error occurs. It returns -1 if the timeout has been exceeded. If the replica SQL thread stops while `MASTER_POS_WAIT()` is waiting, the function returns NULL. If the replica is past the specified position, the function returns immediately.

 If a `timeout` value is specified, `MASTER_POS_WAIT()` stops waiting when `timeout` seconds have elapsed. `timeout` must be greater than 0; a zero or negative `timeout` means no `timeout`.

 The `connection_name` is used when you are using [multi-source-replication](../multi-source-replication/index). If you don't specify it, it's set to the value of the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable.

 Statements using the MASTER\_POS\_WAIT() function are not [safe for replication](../unsafe-statements-for-replication/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/master_pos_wait/>

MATCH AGAINST
=============

    Syntax
------

 
```
MATCH (col1,col2,...) AGAINST (expr [search_modifier])

```

Description
-----------

 A special construct used to perform a fulltext search on a fulltext index.

 See [Fulltext Index Overview](../fulltext-index-overview/index) for a full description, and [Full-text Indexes](../full-text-indexes/index) for more articles on the topic.

 Examples
--------

 
```
CREATE TABLE ft_myisam(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM;

INSERT INTO ft_myisam(copy) VALUES ('Once upon a time'), ('There was a wicked witch'), 
 ('Who ate everybody up');

SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked');
+--------------------------+
| copy                     |
+--------------------------+
| There was a wicked witch |
+--------------------------+

```


```
SELECT id, body, MATCH (title,body) AGAINST
    ('Security implications of running MySQL as root'
    IN NATURAL LANGUAGE MODE) AS score
    FROM articles WHERE MATCH (title,body) AGAINST
    ('Security implications of running MySQL as root'
    IN NATURAL LANGUAGE MODE);
+----+-------------------------------------+-----------------+
| id | body                                | score           |
+----+-------------------------------------+-----------------+
|  4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 |
|  6 | When configured properly, MySQL ... | 1.3114095926285 |
+----+-------------------------------------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/match-against/>

LTRIM
=====

    Syntax
------

 
```
LTRIM(str)

```
 Description
-----------

 Returns the string `str` with leading space characters removed.

 Returns NULL if given a NULL argument. If the result is empty, returns either an empty string, or, from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) with [SQL\_MODE=Oracle](../sql_modeoracle-from-mariadb-103/index), NULL.

 The Oracle mode version of the function can be accessed outside of Oracle mode by using `LTRIM_ORACLE` as the function name.

 Examples
--------

 
```
SELECT QUOTE(LTRIM('   MariaDB   '));
+-------------------------------+
| QUOTE(LTRIM('   MariaDB   ')) |
+-------------------------------+
| 'MariaDB   '                  |
+-------------------------------+

```

Oracle mode version from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/):

 
```
SELECT LTRIM(''),LTRIM_ORACLE('');
+-----------+------------------+
| LTRIM('') | LTRIM_ORACLE('') |
+-----------+------------------+
|           | NULL             |
+-----------+------------------+

```

See Also
--------

 * [RTRIM](../rtrim/index) - trailing spaces removed
* [TRIM](../trim/index) - removes all given prefixes or suffixes

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ltrim/>

MAKETIME
========

    Syntax
------

 
```
MAKETIME(hour,minute,second)

```

Description
-----------

 Returns a time value calculated from the `hour`, `minute`, and `second` arguments.

 If `minute` or `second` are out of the range 0 to 60, NULL is returned. The `hour` can be in the range -838 to 838, outside of which the value is truncated with a warning.

 Examples
--------

 
```
SELECT MAKETIME(13,57,33);
+--------------------+
| MAKETIME(13,57,33) |
+--------------------+
| 13:57:33           |
+--------------------+

SELECT MAKETIME(-13,57,33);
+---------------------+
| MAKETIME(-13,57,33) |
+---------------------+
| -13:57:33           |
+---------------------+

SELECT MAKETIME(13,67,33);
+--------------------+
| MAKETIME(13,67,33) |
+--------------------+
| NULL               |
+--------------------+

SELECT MAKETIME(-1000,57,33);
+-----------------------+
| MAKETIME(-1000,57,33) |
+-----------------------+
| -838:59:59            |
+-----------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-----------------------------------------------+
| Level   | Code | Message                                       |
+---------+------+-----------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '-1000:57:33' |
+---------+------+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/maketime/>

MASTER\_GTID\_WAIT
==================

    Syntax
------

 
```
MASTER_GTID_WAIT(gtid-list[, timeout)

```

Description
-----------

 This function takes a string containing a comma-separated list of [global transaction id's](../global-transaction-id/index) (similar to the value of, for example, [gtid\_binlog\_pos](../global-transaction-id/index#gtid_binlog_pos)). It waits until the value of [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) has the same or higher seq\_no within all replication domains specified in the gtid-list; in other words, it waits until the slave has reached the specified GTID position.

 An optional second argument gives a timeout in seconds. If the timeout expires before the specified GTID position is reached, then the function returns -1. Passing NULL or a negative number for the timeout means no timeout, and the function will wait indefinitely.

  If the wait completes without a timeout, 0 is returned. Passing NULL for the gtid-list makes the function return NULL immediately, without waiting.

 The gtid-list may be the empty string, in which case MASTER\_GTID\_WAIT() returns immediately. If the gtid-list contains fewer domains than [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos), then only those domains are waited upon. If gtid-list contains a domain that is not present in @@gtid\_slave\_pos, then MASTER\_GTID\_WAIT() will wait until an event containing such domain\_id arrives on the slave (or until timed out or killed).

 MASTER\_GTID\_WAIT() can be useful to ensure that a slave has caught up to a master. Simply take the value of [gtid\_binlog\_pos](../global-transaction-id/index#gtid_binlog_pos) on the master, and use it in a MASTER\_GTID\_WAIT() call on the slave; when the call completes, the slave will have caught up with that master position.

 MASTER\_GTID\_WAIT() can also be used in client applications together with the [last\_gtid](../global-transaction-id/index#last_gtid) session variable. This is useful in a read-scaleout [replication](../replication/index) setup, where the application writes to a single master but divides the reads out to a number of slaves to distribute the load. In such a setup, there is a risk that an application could first do an update on the master, and then a bit later do a read on a slave, and if the slave is not fast enough, the data read from the slave might not include the update just made, possibly confusing the application and/or the end-user. One way to avoid this is to request the value of [last\_gtid](../global-transaction-id/index#last_gtid) on the master just after the update. Then before doing the read on the slave, do a MASTER\_GTID\_WAIT() on the value obtained from the master; this will ensure that the read is not performed until the slave has replicated sufficiently far for the update to have become visible.

 Note that MASTER\_GTID\_WAIT() can be used even if the slave is configured not to use GTID for connections ([CHANGE MASTER TO master\_use\_gtid=no](../change-master-to/index#master_use_gtid)). This is because from MariaDB 10, GTIDs are always logged on the master server, and always recorded on the slave servers.

 Differences to MASTER\_POS\_WAIT()
----------------------------------

 * MASTER\_GTID\_WAIT() is global; it waits for any master connection to reach the specified GTID position. [MASTER\_POS\_WAIT()](../master_pos_wait/index) works only against a specific connection. This also means that while MASTER\_POS\_WAIT() aborts if its master connection is terminated with [STOP SLAVE](../stop-slave/index) or due to an error, MASTER\_GTID\_WAIT() continues to wait while slaves are stopped.

 * MASTER\_GTID\_WAIT() can take its timeout as a floating-point value, so a timeout in fractional seconds is supported, eg. MASTER\_GTID\_WAIT("0-1-100", 0.5). (The minimum wait is one microsecond, 0.000001 seconds).

 * MASTER\_GTID\_WAIT() allows one to specify a timeout of zero in order to do a non-blocking check to see if the slaves have progressed to a specific GTID position (MASTER\_POS\_WAIT() takes a zero timeout as meaning an infinite wait). To do an infinite MASTER\_GTID\_WAIT(), specify a negative timeout, or omit the timeout argument.

 * MASTER\_GTID\_WAIT() does not return the number of events executed since the wait started, nor does it return NULL if a slave thread is stopped. It always returns either 0 for successful wait completed, or -1 for timeout reached (or NULL if the specified gtid-pos is NULL).

 Since MASTER\_GTID\_WAIT() looks only at the seq\_no part of the GTIDs, not the server\_id, care is needed if a slave becomes diverged from another server so that two different GTIDs with the same seq\_no (in the same domain) arrive at the same server. This situation is in any case best avoided; setting [gtid\_strict\_mode](../global-transaction-id/index#gtid_strict_mode) is recommended, as this will prevent any such out-of-order sequence numbers from ever being replicated on a slave.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/master_gtid_wait/>

MBRContains
===========

    Syntax
------

 
```
MBRContains(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 contains the Minimum Bounding Rectangle of g2. This tests the opposite relationship as [MBRWithin()](../mbrwithin/index).

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');

SET @g2 = GeomFromText('Point(1 1)');

SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
+----------------------+----------------------+
| MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
+----------------------+----------------------+
|                    1 |                    0 |
+----------------------+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrcontains/>

MBRDisjoint
===========

    Syntax
------

 
```
MBRDisjoint(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 are disjoint. Two geometries are disjoint if they do not intersect, that is touch or overlap.

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECTmbrdisjoint(@g1,@g2);
+----------------------+
| mbrdisjoint(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrdisjoint(@g1,@g2);
+----------------------+
| mbrdisjoint(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrdisjoint/>

MBRIntersects
=============

    Syntax
------

 
```
MBRIntersects(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 intersect.

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrintersects(@g1,@g2);
+------------------------+
| mbrintersects(@g1,@g2) |
+------------------------+
|                      1 |
+------------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbrintersects(@g1,@g2);
+------------------------+
| mbrintersects(@g1,@g2) |
+------------------------+
|                      0 |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrintersects/>

MBROverlaps
===========

    Syntax
------

 
```
MBROverlaps(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries `g1` and `g2` overlap. The term spatially overlaps is used if two geometries intersect and their intersection results in a geometry of the same dimension but not equal to either of the given geometries.

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 4,4 4,4 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbroverlaps(@g1,@g2);
+----------------------+
| mbroverlaps(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbroverlaps/>

MBREqual
========

    Syntax
------

 
```
MBREqual(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries g1 and g2 are the same.

 Examples
--------

 
```
SET @g1=GEOMFROMTEXT('LINESTRING(0 0, 1 2)');
SET @g2=GEOMFROMTEXT('POLYGON((0 0, 0 2, 1 2, 1 0, 0 0))');
SELECT MbrEqual(@g1,@g2);
+-------------------+
| MbrEqual(@g1,@g2) |
+-------------------+
|                 1 |
+-------------------+

SET @g1=GEOMFROMTEXT('LINESTRING(0 0, 1 3)');
SET @g2=GEOMFROMTEXT('POLYGON((0 0, 0 2, 1 4, 1 0, 0 0))');
SELECT MbrEqual(@g1,@g2);
+-------------------+
| MbrEqual(@g1,@g2) |
+-------------------+
|                 0 |
+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrequal/>

MD5
===

    Syntax
------

 
```
MD5(str)

```

Description
-----------

 Calculates an MD5 128-bit checksum for the string. 

 The return value is a 32-hex digit string, and as of [MariaDB 5.5](../what-is-mariadb-55/index), is a nonbinary string in the connection [character set and collation](../data-types-character-sets-and-collations/index), determined by the values of the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables. Before 5.5, the return value was a binary string.

 NULL is returned if the argument was NULL. 

 Examples
--------

 
```
SELECT MD5('testing');
+----------------------------------+
| MD5('testing')                   |
+----------------------------------+
| ae2b1fca515949e5d54fb22b8ed95575 |
+----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/md5/>

MBRWithin
=========

    Syntax
------

 
```
MBRWithin(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangle of g1 is within the Minimum Bounding Rectangle of g2. This tests the opposite relationship as [MBRContains()](../mbrcontains/index).

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
+--------------------+--------------------+
| MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
+--------------------+--------------------+
|                  1 |                  0 |
+--------------------+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrwithin/>

MID
===

    Syntax
------

 
```
MID(str,pos,len)

```

Description
-----------

 MID(str,pos,len) is a synonym for [SUBSTRING(str,pos,len)](../substring/index).

 Examples
--------

 
```
SELECT MID('abcd',4,1);
+-----------------+
| MID('abcd',4,1) |
+-----------------+
| d               |
+-----------------+

SELECT MID('abcd',2,2);
+-----------------+
| MID('abcd',2,2) |
+-----------------+
| bc              |
+-----------------+

```

A negative starting position:

 
```
SELECT MID('abcd',-2,4);
+------------------+
| MID('abcd',-2,4) |
+------------------+
| cd               |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mid/>

MBRTouches
==========

    Syntax
------

 
```
MBRTouches(g1,g2)

```

Description
-----------

 Returns 1 or 0 to indicate whether the Minimum Bounding Rectangles of the two geometries `g1` and `g2` touch. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.

 Examples
--------

 
```
SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((4 4,4 7,7 7,7 4,4 4))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = GeomFromText('Polygon((0 0,0 4,4 4,4 0,0 0))');
SET @g2 = GeomFromText('Polygon((3 3,3 6,6 6,6 3,3 3))');
SELECT mbrtouches(@g1,@g2);
+---------------------+
| mbrtouches(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbrtouches/>

MEDIAN
======

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**The MEDIAN() [window function](../window-functions/index) was first introduced with in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

  Syntax
------

 
```
MEDIAN(median expression) OVER (
  [ PARTITION BY partition_expression ] 
)

```

Description
-----------

 MEDIAN() is a [window function](../window-functions/index) that returns the median value of a range of values.

 It is a specific case of [PERCENTILE\_CONT](../percentile_cont/index), with an argument of 0.5 and the [ORDER BY](../order-by/index) column the one in `MEDIAN`'s argument.   


 
```
MEDIAN(<median-arg>) OVER ( [ PARTITION BY partition_expression] )

```

Is equivalent to:  


 
```
PERCENTILE_CONT(0.5) WITHIN 
  GROUP (ORDER BY <median-arg>) OVER ( [ PARTITION BY partition_expression ])

```

Examples
--------

 
```
CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, median(star_rating) OVER (PARTITION BY name) FROM book_rating;
+-----------------------+----------------------------------------------+
| name                  | median(star_rating) OVER (PARTITION BY name) |
+-----------------------+----------------------------------------------+
| Lord of the Ladybirds |                                 4.0000000000 |
| Lord of the Ladybirds |                                 4.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
| Lady of the Flies     |                                 2.0000000000 |
+-----------------------+----------------------------------------------+

```

See Also
--------

 * [PERCENTILE\_CONT](../percentile_cont/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/median/>

MICROSECOND
===========

    Syntax
------

 
```
MICROSECOND(expr)

```
 Description
-----------

 Returns the microseconds from the time or datetime expression *expr* as a number in the range from 0 to 999999.

 If *expr* is a time with no microseconds, zero is returned, while if *expr* is a date with no time, zero with a warning is returned.

 Examples
--------

 
```
SELECT MICROSECOND('12:00:00.123456');
+--------------------------------+
| MICROSECOND('12:00:00.123456') |
+--------------------------------+
|                         123456 |
+--------------------------------+

SELECT MICROSECOND('2009-12-31 23:59:59.000010');
+-------------------------------------------+
| MICROSECOND('2009-12-31 23:59:59.000010') |
+-------------------------------------------+
|                                        10 |
+-------------------------------------------+

SELECT MICROSECOND('2013-08-07 12:13:14');
+------------------------------------+
| MICROSECOND('2013-08-07 12:13:14') |
+------------------------------------+
|                                  0 |
+------------------------------------+

SELECT MICROSECOND('2013-08-07');
+---------------------------+
| MICROSECOND('2013-08-07') |
+---------------------------+
|                         0 |
+---------------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '2013-08-07' |
+---------+------+----------------------------------------------+

```

See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/microsecond/>

MINUTE
======

    Syntax
------

 
```
MINUTE(time)

```

Description
-----------

 Returns the minute for *time*, in the range 0 to 59. 

 Examples
--------

 
```
SELECT MINUTE('2013-08-03 11:04:03');
+-------------------------------+
| MINUTE('2013-08-03 11:04:03') |
+-------------------------------+
|                             4 |
+-------------------------------+

 SELECT MINUTE ('23:12:50');
+---------------------+
| MINUTE ('23:12:50') |
+---------------------+
|                  12 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/minute/>

MLineFromText
=============

    Syntax
------

 
```
MLineFromText(wkt[,srid])
MultiLineStringFromText(wkt[,srid])

```

Description
-----------

 Constructs a [MULTILINESTRING](../multilinestring/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `MLineFromText()` and `MultiLineStringFromText()` are synonyms.

 Examples
--------

 
```
CREATE TABLE gis_multi_line (g MULTILINESTRING);
SHOW FIELDS FROM gis_multi_line;
INSERT INTO gis_multi_line VALUES
    (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
    (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
    (MLineFromWKB(AsWKB(MultiLineString(
      LineString(Point(1, 2), Point(3, 5)), 
      LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mlinefromtext/>

MIN
===

    Syntax
------

 
```
MIN([DISTINCT] expr)

```
 Description
-----------

 Returns the minimum value of *`expr`*. `MIN()` may take a string argument, in which case it returns the minimum string value. The `DISTINCT` keyword can be used to find the minimum of the distinct values of *`expr`*, however, this produces the same result as omitting `DISTINCT`.

 Note that [SET](../set/index) and [ENUM](../enum/index) fields are currently compared by their string value rather than their relative position in the set, so MIN() may produce a different lowest result than ORDER BY ASC.

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 `MIN()` can be used as a [window function](../window-functions/index).

 `MIN()` returns `NULL` if there were no matching rows.

 Examples
--------

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

SELECT name, MIN(score) FROM student GROUP BY name;
+---------+------------+
| name    | MIN(score) |
+---------+------------+
| Chun    |         73 |
| Esben   |         31 |
| Kaolin  |         56 |
| Tatiana |         83 |
+---------+------------+

```

MIN() with a string:

 
```
SELECT MIN(name) FROM student;
+-----------+
| MIN(name) |
+-----------+
| Chun      |
+-----------+

```

Be careful to avoid this common mistake, not grouping correctly and returning mismatched data: 

 
```
SELECT name,test,MIN(score) FROM student;
+------+------+------------+
| name | test | MIN(score) |
+------+------+------------+
| Chun | SQL  |         31 |
+------+------+------------+

```

Difference between ORDER BY ASC and MIN():

 
```
CREATE TABLE student2(name CHAR(10),grade ENUM('b','c','a'));

INSERT INTO student2 VALUES('Chun','b'),('Esben','c'),('Kaolin','a');

SELECT MIN(grade) FROM student2;
+------------+
| MIN(grade) |
+------------+
| a          |
+------------+

SELECT grade FROM student2 ORDER BY grade ASC LIMIT 1;
+-------+
| grade |
+-------+
| b     |
+-------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);
INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);


SELECT name, test, score, MIN(score) 
  OVER (PARTITION BY name) AS lowest_score FROM student_test;
+---------+--------+-------+--------------+
| name    | test   | score | lowest_score |
+---------+--------+-------+--------------+
| Chun    | SQL    |    75 |           73 |
| Chun    | Tuning |    73 |           73 |
| Esben   | SQL    |    43 |           31 |
| Esben   | Tuning |    31 |           31 |
| Kaolin  | SQL    |    56 |           56 |
| Kaolin  | Tuning |    88 |           56 |
| Tatiana | SQL    |    87 |           87 |
+---------+--------+-------+--------------+

```

See Also
--------

 * [AVG](../avg/index) (average)
* [MAX](../max/index) (maximum)
* [SUM](../sum/index) (sum total)
* [MIN/MAX optimization](../minmax-optimization/index) used by the optimizer
* [LEAST()](../least/index) returns the smallest value from a list.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/min/>

MOD
===

    Syntax
------

 
```
MOD(N,M), N % M, N MOD M

```

Description
-----------

 Modulo operation. Returns the remainder of N divided by M. See also [Modulo Operator](../modulo-operator/index).

 If the `ERROR_ON_DIVISION_BY_ZERO` [SQL\_MODE](../sql-mode/index) is used, any number modulus zero produces an error. Otherwise, it returns NULL.

 The integer part of a division can be obtained using [DIV](../div/index).

 Examples
--------

 
```
SELECT 1042 % 50;
+-----------+
| 1042 % 50 |
+-----------+
|        42 |
+-----------+

SELECT MOD(234, 10);
+--------------+
| MOD(234, 10) |
+--------------+
|            4 |
+--------------+

SELECT 253 % 7;
+---------+
| 253 % 7 |
+---------+
|       1 |
+---------+

SELECT MOD(29,9);
+-----------+
| MOD(29,9) |
+-----------+
|         2 |
+-----------+

SELECT 29 MOD 9;
+----------+
| 29 MOD 9 |
+----------+
|        2 |
+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mod/>

MONTH
=====

    Syntax
------

 
```
MONTH(date)

```

Description
-----------

 Returns the month for `date` in the range 1 to 12 for January to December, or 0 for dates such as '0000-00-00' or '2008-00-00' that have a zero month part.

 Examples
--------

 
```
SELECT MONTH('2019-01-03');
+---------------------+
| MONTH('2019-01-03') |
+---------------------+
|                   1 |
+---------------------+

SELECT MONTH('2019-00-03');
+---------------------+
| MONTH('2019-00-03') |
+---------------------+
|                   0 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/month/>

MPointFromWKB
=============

    Syntax
------

 
```
MPointFromWKB(wkb[,srid])
MultiPointFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a [MULTIPOINT](../multipoint/index) value using its [WKB](../well-known-binary-wkb-format/index) representation and [SRID](../srid/index).

 `MPointFromWKB()` and `MultiPointFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(MPointFromText('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9, 4 9, 1 5 )'));

SELECT ST_AsText(MPointFromWKB(@g));
+-----------------------------------------------------+
| ST_AsText(MPointFromWKB(@g))                        |
+-----------------------------------------------------+
| MULTIPOINT(1 1,2 2,5 3,7 2,9 3,8 4,6 6,6 9,4 9,1 5) |
+-----------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mpointfromwkb/>

MPolyFromText
=============

    Syntax
------

 
```
MPolyFromText(wkt[,srid])
MultiPolygonFromText(wkt[,srid])

```

Description
-----------

 Constructs a [MULTIPOLYGON](../multipolygon/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `MPolyFromText()` and `MultiPolygonFromText()` are synonyms.

 Examples
--------

 
```
CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
SHOW FIELDS FROM gis_multi_polygon;
INSERT INTO gis_multi_polygon VALUES
    (MultiPolygonFromText('MULTIPOLYGON(
       ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
       ((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromText('MULTIPOLYGON(
       ((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
       ((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(
       LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mpolyfromtext/>

MLineFromWKB
============

    Syntax
------

 
```
MLineFromWKB(wkb[,srid])
MultiLineStringFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a [MULTILINESTRING](../multilinestring/index) value using its [WKB](../well-known-binary-wkb-format/index) representation and [SRID](../srid/index).

 `MLineFromWKB()` and `MultiLineStringFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(MLineFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))'));

SELECT ST_AsText(MLineFromWKB(@g));
+--------------------------------------------------------+
| ST_AsText(MLineFromWKB(@g))                            |
+--------------------------------------------------------+
| MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48)) |
+--------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mlinefromwkb/>

MULTIPOINT
==========

    Syntax
------

 
```
MultiPoint(pt1,pt2,...)

```

Description
-----------

 Constructs a [WKB](../wkb/index) MultiPoint value using WKB [Point](../point/index) arguments. If any argument is not a WKB Point, the return value is `NULL`.

 Examples
--------

 
```
SET @g = ST_GEOMFROMTEXT('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9, 4 9, 1 5 )');

CREATE TABLE gis_multi_point (g MULTIPOINT);
INSERT INTO gis_multi_point VALUES
    (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
    (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
    (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipoint/>

MONTHNAME
=========

    Syntax
------

 
```
MONTHNAME(date)

```

Description
-----------

 Returns the full name of the month for date. The language used for the name is controlled by the value of the [lc\_time\_names](../server-system-variables/index#lc_time_names) system variable. See [server locale](../server-locale/index) for more on the supported locales.

 Examples
--------

 
```
SELECT MONTHNAME('2019-02-03');
+-------------------------+
| MONTHNAME('2019-02-03') |
+-------------------------+
| February                |
+-------------------------+

```

Changing the locale:

 
```
SET lc_time_names = 'fr_CA';

SELECT MONTHNAME('2019-05-21');
+-------------------------+
| MONTHNAME('2019-05-21') |
+-------------------------+
| mai                     |
+-------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/monthname/>

MPolyFromWKB
============

    Syntax
------

 
```
MPolyFromWKB(wkb[,srid])
MultiPolygonFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a [MULTIPOLYGON](../multipolygon/index) value using its [WKB](../well-known-binary-wkb-format/index) representation and [SRID](../srid/index).

 `MPolyFromWKB()` and `MultiPolygonFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(MPointFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))'));

SELECT ST_AsText(MPolyFromWKB(@g))\G
*************************** 1. row ***************************
ST_AsText(MPolyFromWKB(@g)): MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mpolyfromwkb/>

MPointFromText
==============

    Syntax
------

 
```
MPointFromText(wkt[,srid])
MultiPointFromText(wkt[,srid])

```

Description
-----------

 Constructs a [MULTIPOINT](../multipoint/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `MPointFromText()` and `MultiPointFromText()` are synonyms.

 Examples
--------

 
```
CREATE TABLE gis_multi_point (g MULTIPOINT);
SHOW FIELDS FROM gis_multi_point;
INSERT INTO gis_multi_point VALUES
    (MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
    (MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
    (MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mpointfromtext/>

MULTIPOLYGON
============

    Syntax
------

 
```
MultiPolygon(poly1,poly2,...)

```

Description
-----------

 Constructs a [WKB](../wkb/index) MultiPolygon value from a set of WKB [Polygon](../polygon/index) arguments. If any argument is not a WKB Polygon, the return value is `NULL`.

 Example
-------

 
```
CREATE TABLE gis_multi_polygon  (g MULTIPOLYGON);
INSERT INTO gis_multi_polygon VALUES
    (MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
     ((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),
        ((59 18,67 18,67 13,59 13,59 18)))')),
    (MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(
       Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipolygon/>

MultiLineStringFromWKB
======================

    A synonym for [MLineFromWKB()](../mlinefromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multilinestringfromwkb/>

MULTILINESTRING
===============

    Syntax
------

 
```
MultiLineString(ls1,ls2,...)

```

Description
-----------

 Constructs a WKB MultiLineString value using [WKB](../wkb/index) [LineString](../linestring/index) arguments. If any argument is not a WKB LineString, the return value is `NULL`.

 Example
-------

 
```
CREATE TABLE gis_multi_line (g MULTILINESTRING);
INSERT INTO gis_multi_line VALUES
 (MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
 (MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
 (MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), 
    Point(3, 5)), LineString(Point(2, 5),Point(5, 8),Point(21, 7))))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multilinestring/>

MultiLineStringFromText
=======================

    A synonym for [MLineFromText](../mlinefromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multilinestringfromtext/>

MultiPointFromWKB
=================

    A synonym for [MPointFromWKB](../mpointfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipointfromwkb/>

NAME\_CONST
===========

    Syntax
------

 
```
NAME_CONST(name,value)

```

Description
-----------

 Returns the given value. When used to produce a result set column, `NAME_CONST()` causes the column to have the given name. The arguments should be constants.

 This function is used internally when replicating stored procedures. It makes little sense to use it explicitly in SQL statements, and it was not supposed to be used like that.

 
```
SELECT NAME_CONST('myname', 14);
+--------+
| myname |
+--------+
|     14 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/name_const/>

MultiPointFromText
==================

    A synonym for [MPointFromText](../mpointfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipointfromtext/>

NOT LIKE
========

    Syntax
------

 
```
expr NOT LIKE pat [ESCAPE 'escape_char']

```

Description
-----------

 This is the same as [NOT (expr LIKE pat [ESCAPE 'escape\_char'])](../not/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not-like/>

MultiPolygonFromWKB
===================

    Synonym for [MPolyFromWKB](../mpolyfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipolygonfromwkb/>

MultiPolygonFromText
====================

    A synonym for [MPolyFromText](../mpolyfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multipolygonfromtext/>

NATURAL\_SORT\_KEY
==================

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**NATURAL\_SORT\_KEY was added in [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/).

 
Syntax
------

 
```
NATURAL_SORT_KEY(str)

```
 Description
-----------

 The `NATURAL_SORT_KEY` function is used for sorting that is closer to natural sorting. Strings are sorted in alphabetical order, while numbers are treated in a way such that, for example, `10` is greater than `2`, whereas in other forms of sorting, `2` would be greater than `10`, just like `z` is greater than `ya`.

 There are multiple natural sort implementations, differing in the way they handle leading zeroes, fractions, i18n, negatives, decimals and so on.

 MariaDB's implementation ignores leading zeroes when performing the sort.

 You can use also use `NATURAL_SORT_KEY` with [generated columns](../generated-columns/index). The value is not stored permanently in the table. When using a generated column, the virtual column must be longer than the base column to cater for embedded numbers in the string and [MDEV-24582](https://jira.mariadb.org/browse/MDEV-24582).

 Examples
--------

 ### Strings and Numbers

 
```
CREATE TABLE t1 (c TEXT);

INSERT INTO t1 VALUES ('b1'),('a2'),('a11'),('a1');

SELECT c FROM t1;
+------+
| c    |
+------+
| b1   |
| a2   |
| a11  |
| a1   |
+------+

SELECT c FROM t1 ORDER BY c;
+------+
| c    |
+------+
| a1   |
| a11  |
| a2   |
| b1   |
+------+

```

Unsorted, regular sort and natural sort:

 
```
TRUNCATE t1;

INSERT INTO t1 VALUES 
  ('5.5.31'),('10.7.0'),('10.2.1'),
  ('10.1.22'),('10.3.32'),('10.2.12');

SELECT c FROM t1;
+---------+
| c       |
+---------+
| 5.5.31  |
| 10.7.0  |
| 10.2.1  |
| 10.1.22 |
| 10.3.32 |
| 10.2.12 |
+---------+

SELECT c FROM t1 ORDER BY c;
+---------+
| c       |
+---------+
| 10.1.22 |
| 10.2.1  |
| 10.2.12 |
| 10.3.32 |
| 10.7.0  |
| 5.5.31  |
+---------+

SELECT c FROM t1 ORDER BY NATURAL_SORT_KEY(c);
+---------+
| c       |
+---------+
| 5.5.31  |
| 10.1.22 |
| 10.2.1  |
| 10.2.12 |
| 10.3.32 |
| 10.7.0  |
+---------+

```

### IPs

 Sorting IPs, unsorted, regular sort and natural sort::

 
```
TRUNCATE t1;

INSERT INTO t1 VALUES 
  ('192.167.3.1'),('192.167.1.12'),('100.200.300.400'),
  ('100.50.60.70'),('100.8.9.9'),('127.0.0.1'),('0.0.0.0');

SELECT c FROM t1;
+-----------------+
| c               |
+-----------------+
| 192.167.3.1     |
| 192.167.1.12    |
| 100.200.300.400 |
| 100.50.60.70    |
| 100.8.9.9       |
| 127.0.0.1       |
| 0.0.0.0         |
+-----------------+

SELECT c FROM t1 ORDER BY c;
+-----------------+
| c               |
+-----------------+
| 0.0.0.0         |
| 100.200.300.400 |
| 100.50.60.70    |
| 100.8.9.9       |
| 127.0.0.1       |
| 192.167.1.12    |
| 192.167.3.1     |
+-----------------+

SELECT c FROM t1 ORDER BY NATURAL_SORT_KEY(c);
+-----------------+
| c               |
+-----------------+
| 0.0.0.0         |
| 100.8.9.9       |
| 100.50.60.70    |
| 100.200.300.400 |
| 127.0.0.1       |
| 192.167.1.12    |
| 192.167.3.1     |
+-----------------+

```

### Generated Columns

 Using with a [generated column](../generated-columns/index):

 
```
CREATE TABLE t(c VARCHAR(3), k VARCHAR(4) AS (NATURAL_SORT_KEY(c)) INVISIBLE);

INSERT INTO t(c) VALUES ('b1'),('a2'),('a11'),('a10');

SELECT * FROM t ORDER by k;
+------+
| c    |
+------+
| a2   |
| a10  |
| a11  |
| b1   |
+------+

```

Note that if the virtual column is not longer, results may not be as expected:

 
```
CREATE TABLE t2(c VARCHAR(3), k VARCHAR(3) AS (NATURAL_SORT_KEY(c)) INVISIBLE);

INSERT INTO t2(c) VALUES ('b1'),('a2'),('a11'),('a10');

SELECT * FROM t2 ORDER by k;
+------+
| c    |
+------+
| a2   |
| a11  |
| a10  |
| b1   |
+------+

```

### Leading Zeroes

 Ignoring leading zeroes can lead to undesirable results in certain contexts. For example:

 
```
CREATE TABLE t3 (a VARCHAR(4));

INSERT INTO t3 VALUES 
  ('a1'), ('a001'), ('a10'), ('a001'), ('a10'), 
  ('a01'), ('a01'), ('a01b'), ('a01b'), ('a1');

SELECT a FROM t3 ORDER BY a;
+------+
| a    |
+------+
| a001 |
| a001 |
| a01  |
| a01  |
| a01b |
| a01b |
| a1   |
| a1   |
| a10  |
| a10  |
+------+
10 rows in set (0.000 sec)

SELECT a FROM t3 ORDER BY NATURAL_SORT_KEY(a);
+------+
| a    |
+------+
| a1   |
| a01  |
| a01  |
| a001 |
| a001 |
| a1   |
| a01b |
| a01b |
| a10  |
| a10  |
+------+

```

This may not be what we were hoping for in a 'natural' sort. A workaround is to sort by both NATURAL\_SORT\_KEY and regular sort.

 
```
SELECT a FROM t3 ORDER BY NATURAL_SORT_KEY(a), a;
+------+
| a    |
+------+
| a001 |
| a001 |
| a01  |
| a01  |
| a1   |
| a1   |
| a01b |
| a01b |
| a10  |
| a10  |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/natural_sort_key/>

NOT REGEXP
==========

    Syntax
------

 
```
expr NOT REGEXP pat, expr NOT RLIKE pat

```

Description
-----------

 This is the same as [NOT (expr REGEXP pat)](../not/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not-regexp/>

NULLIF
======

    Syntax
------

 
```
NULLIF(expr1,expr2)

```
 Description
-----------

 Returns NULL if expr1 = expr2 is true, otherwise returns expr1. This is the same as [CASE](../case-operator/index) WHEN expr1 = expr2 THEN NULL ELSE expr1 END.

 Examples
--------

 
```
SELECT NULLIF(1,1);
+-------------+
| NULLIF(1,1) |
+-------------+
|        NULL |
+-------------+

SELECT NULLIF(1,2);
+-------------+
| NULLIF(1,2) |
+-------------+
|           1 |
+-------------+

```

See Also
--------

 * [NULL values](../null-values/index)
* [IS NULL operator](../is-null/index)
* [IS NOT NULL operator](../is-not-null/index)
* [COALESCE function](../coalesce/index)
* [IFNULL function](../ifnull/index)
* [CONNECT data types](../connect-data-types/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nullif/>

NEXT VALUE for sequence\_name
=============================

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**SEQUENCEs were introduced in [MariaDB 10.3](../what-is-mariadb-103/index)

 
Syntax
------

 
```
NEXT VALUE FOR sequence

```

or

 
```
NEXTVAL(sequence_name)

```

or in Oracle mode ([SQL\_MODE=ORACLE](../sql-mode/index))

 
```
sequence_name.nextval

```
 `NEXT VALUE FOR` is ANSI SQL syntax while `NEXTVAL()` is PostgreSQL syntax.

 Description
-----------

 Generate next value for a `SEQUENCE`.

 * You can greatly speed up `NEXT VALUE` by creating the sequence with the `CACHE` option. If not, every `NEXT VALUE` usage will cause changes in the stored `SEQUENCE` table.
* When using `NEXT VALUE` the value will be reserved at once and will not be reused, except if the `SEQUENCE` was created with `CYCLE`. This means that when you are using `SEQUENCE`s you have to expect gaps in the generated sequence numbers.
* If one updates the `SEQUENCE` with [SETVAL()](../setval/index) or [ALTER SEQUENCE ... RESTART](../alter-sequence/index), `NEXT VALUE FOR` will notice this and start from the next requested value.
* [FLUSH TABLES](../flush/index) will close the sequence and the next sequence number generated will be according to what's stored in the `SEQUENCE` object. In effect, this will discard the cached values.
* A server restart (or closing the current connection) also causes a drop of all cached values. The cached sequence numbers are reserved only for the current connection.
* `NEXT VALUE` requires the `INSERT` [privilege](../grant/index).

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)*** You can also use `NEXT VALUE FOR sequence` for column `DEFAULT`.

 
See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [PREVIOUS VALUE FOR](../previous-value-for-sequence_name/index)
* [SETVAL()](../setval/index). Set next value for the sequence.
* [AUTO\_INCREMENT](../auto_increment/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/next-value-for-sequence_name/>

NOT BETWEEN
===========

    Syntax
------

 
```
expr NOT BETWEEN min AND max

```

Description
-----------

 This is the same as NOT (expr [BETWEEN](../between-and/index) min AND max).

 Note that the meaning of the alternative form `NOT expr BETWEEN min AND max` is affected by the `HIGH_NOT_PRECEDENCE` [SQL\_MODE](../sql-mode/index) flag.

 Examples
--------

 
```
SELECT 1 NOT BETWEEN 2 AND 3;
+-----------------------+
| 1 NOT BETWEEN 2 AND 3 |
+-----------------------+
|                     1 |
+-----------------------+

```


```
SELECT 'b' NOT BETWEEN 'a' AND 'c';
+-----------------------------+
| 'b' NOT BETWEEN 'a' AND 'c' |
+-----------------------------+
|                           0 |
+-----------------------------+

```

NULL:

 
```
SELECT 1 NOT BETWEEN 1 AND NULL;
+--------------------------+
| 1 NOT BETWEEN 1 AND NULL |
+--------------------------+
|                     NULL |
+--------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not-between/>

NOT IN
======

    Syntax
------

 
```
expr NOT IN (value,...)

```

Description
-----------

 This is the same as NOT (expr [IN](../in/index) (value,...)).

 Examples
--------

 
```
SELECT 2 NOT IN (0,3,5,7);
+--------------------+
| 2 NOT IN (0,3,5,7) |
+--------------------+
|                  1 |
+--------------------+

```


```
SELECT 'wefwf' NOT IN ('wee','wefwf','weg');
+--------------------------------------+
| 'wefwf' NOT IN ('wee','wefwf','weg') |
+--------------------------------------+
|                                    0 |
+--------------------------------------+

```


```
SELECT 1 NOT IN ('1', '2', '3');
+--------------------------+
| 1 NOT IN ('1', '2', '3') |
+--------------------------+
|                        0 |
+--------------------------+

```

NULL:

 
```
SELECT NULL NOT IN (1, 2, 3);
+-----------------------+
| NULL NOT IN (1, 2, 3) |
+-----------------------+
|                  NULL |
+-----------------------+

SELECT 1 NOT IN (1, 2, NULL);
+-----------------------+
| 1 NOT IN (1, 2, NULL) |
+-----------------------+
|                     0 |
+-----------------------+

SELECT 5 NOT IN (1, 2, NULL);
+-----------------------+
| 5 NOT IN (1, 2, NULL) |
+-----------------------+
|                  NULL |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not-in/>

NOW
===

    Syntax
------

 
```
NOW([precision])
CURRENT_TIMESTAMP
CURRENT_TIMESTAMP([precision])
LOCALTIME, LOCALTIME([precision])
LOCALTIMESTAMP
LOCALTIMESTAMP([precision])

```
 Description
-----------

 Returns the current date and time as a value in `'YYYY-MM-DD HH:MM:SS'` or `YYYYMMDDHHMMSS.uuuuuu` format, depending on whether the function is used in a string or numeric context. The value is expressed in the current [time zone](../time-zones/index).

 The optional *precision* determines the microsecond precision. See [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 `NOW()` (or its synonyms) can be used as the default value for [TIMESTAMP](../timestamp/index) columns as well as, since [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/), [DATETIME](../datetime/index) columns. Before [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/), it was only possible for a single TIMESTAMP column per table to contain the CURRENT\_TIMESTAMP as its default.

 When displayed in the [INFORMATION\_SCHEMA.COLUMNS](../information-schema-columns-table/index) table, a default [CURRENT TIMESTAMP](../current_timestamp/index) is displayed as `CURRENT_TIMESTAMP` up until [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), and as `current_timestamp()` from [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), due to to [MariaDB 10.2](../what-is-mariadb-102/index) accepting expressions in the DEFAULT clause.

 Changing the [timestamp system variable](../server-system-variables/index#timestamp) with a [SET](../set/index) `timestamp` statement affects the value returned by NOW(), but not by [SYSDATE()](../sysdate/index).

 Examples
--------

 
```
SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2010-03-27 13:13:25 |
+---------------------+

SELECT NOW() + 0;
+-----------------------+
| NOW() + 0             |
+-----------------------+
| 20100327131329.000000 |
+-----------------------+

```

With precision:

 
```
SELECT CURRENT_TIMESTAMP(2);
+------------------------+
| CURRENT_TIMESTAMP(2)   |
+------------------------+
| 2018-07-10 09:47:26.24 |
+------------------------+

```

Used as a default TIMESTAMP:

 
```
CREATE TABLE t (createdTS TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);

```

From [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/):

 
```
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test'
  AND COLUMN_NAME LIKE '%ts%'\G
*************************** 1. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: test
              TABLE_NAME: t
             COLUMN_NAME: ts
        ORDINAL_POSITION: 1
          COLUMN_DEFAULT: current_timestamp()
...

```

<= [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)

 
```
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test'
  AND COLUMN_NAME LIKE '%ts%'\G
*************************** 1. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: test
              TABLE_NAME: t
             COLUMN_NAME: createdTS
        ORDINAL_POSITION: 1
          COLUMN_DEFAULT: CURRENT_TIMESTAMP
...

```

See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)
* [timestamp server system variable](../server-system-variables/index#timestamp)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/now/>

NTILE
=====

    Syntax
------

 
```
NTILE (expr) OVER ( 
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

```

Description
-----------

 NTILE() is a [window function](../window-functions/index) that returns an integer indicating which group a given row falls into. The number of groups is specified in the argument (*expr*), starting at one. Ordered rows in the partition are divided into the specified number of groups with as equal a size as possible. 

 Examples
--------

 
```
create table t1 (
    pk int primary key,
    a int,
    b int
  );

insert into t1 values
    (11 , 0, 10),
    (12 , 0, 10),
    (13 , 1, 10),
    (14 , 1, 10),
    (18 , 2, 10),
    (15 , 2, 20),
    (16 , 2, 20),
    (17 , 2, 20),
    (19 , 4, 20),
    (20 , 4, 20);

select pk, a, b,
    ntile(1) over (order by pk)
  from t1;
+----+------+------+-----------------------------+
| pk | a    | b    | ntile(1) over (order by pk) |
+----+------+------+-----------------------------+
| 11 |    0 |   10 |                           1 |
| 12 |    0 |   10 |                           1 |
| 13 |    1 |   10 |                           1 |
| 14 |    1 |   10 |                           1 |
| 15 |    2 |   20 |                           1 |
| 16 |    2 |   20 |                           1 |
| 17 |    2 |   20 |                           1 |
| 18 |    2 |   10 |                           1 |
| 19 |    4 |   20 |                           1 |
| 20 |    4 |   20 |                           1 |
+----+------+------+-----------------------------+

select pk, a, b,
    ntile(4) over (order by pk)
 from t1;
+----+------+------+-----------------------------+
| pk | a    | b    | ntile(4) over (order by pk) |
+----+------+------+-----------------------------+
| 11 |    0 |   10 |                           1 |
| 12 |    0 |   10 |                           1 |
| 13 |    1 |   10 |                           1 |
| 14 |    1 |   10 |                           2 |
| 15 |    2 |   20 |                           2 |
| 16 |    2 |   20 |                           2 |
| 17 |    2 |   20 |                           3 |
| 18 |    2 |   10 |                           3 |
| 19 |    4 |   20 |                           4 |
| 20 |    4 |   20 |                           4 |
+----+------+------+-----------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ntile/>

ST\_NumInteriorRings
====================

    Syntax
------

 
```
ST_NumInteriorRings(poly)
NumInteriorRings(poly)

```

Description
-----------

 Returns an integer containing the number of interior rings in the Polygon value `poly`.

 Note that according the the OpenGIS standard, a [POLYGON](../polygon/index) should have exactly one ExteriorRing and all other rings should lie within that ExteriorRing and thus be the InteriorRings. Practically, however, some systems, including MariaDB's, permit polygons to have several 'ExteriorRings'. In the case of there being multiple, non-overlapping exterior rings ST\_NumInteriorRings() will return `1`.

 `ST_NumInteriorRings()` and `NumInteriorRings()` are synonyms.

 Examples
--------

 
```
SET @poly = 'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';

SELECT NumInteriorRings(GeomFromText(@poly));
+---------------------------------------+
| NumInteriorRings(GeomFromText(@poly)) |
+---------------------------------------+
|                                     1 |
+---------------------------------------+

```

Non-overlapping 'polygon':

 
```
SELECT ST_NumInteriorRings(ST_PolyFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),
  (-1 -1,-5 -1,-5 -5,-1 -5,-1 -1))')) AS NumInteriorRings;
+------------------+
| NumInteriorRings |
+------------------+
|                1 |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numinteriorrings/>

ST\_NUMPOINTS
=============

    Syntax
------

 
```
ST_NumPoints(ls)
NumPoints(ls)

```

Description
-----------

 Returns the number of [Point](../point/index) objects in the [LineString](../linestring/index) value `ls`.

 `ST_NumPoints()` and `NumPoints()` are synonyms.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT NumPoints(GeomFromText(@ls));
+------------------------------+
| NumPoints(GeomFromText(@ls)) |
+------------------------------+
|                            3 |
+------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numpoints/>

OCT
===

    Syntax
------

 
```
OCT(N)

```
 Description
-----------

 Returns a string representation of the octal value of N, where N is a longlong ([BIGINT](../bigint/index)) number. This is equivalent to [CONV(N,10,8)](../conv/index). Returns NULL if N is NULL.

 Examples
--------

 
```
SELECT OCT(34);
+---------+
| OCT(34) |
+---------+
| 42      |
+---------+

SELECT OCT(12);
+---------+
| OCT(12) |
+---------+
| 14      |
+---------+

```

See Also
--------

 * [CONV()](../conv/index)
* [BIN()](../bin/index)
* [HEX()](../hex/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oct/>

OCTET\_LENGTH
=============

    Syntax
------

 
```
OCTET_LENGTH(str)

```

Description
-----------

 `OCTET_LENGTH()` returns the length of the given string, in octets (bytes). This is a synonym for [LENGTHB()](../lengthb/index), and, when [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions) is not set, a synonym for [LENGTH()](../length/index).

 A multi-byte character counts as multiple bytes. This means that for a string containing five two-byte characters, `OCTET_LENGTH()` returns 10, whereas [CHAR\_LENGTH()](../char_length/index) returns 5.

 If `str` is not a string value, it is converted into a string. If `str` is `NULL`, the function returns `NULL`.

 Examples
--------

 When [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3](../what-is-mariadb-103/index) is not set:

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

In [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions):

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

See Also
--------

 * [CHAR\_LENGTH()](../char_length/index)
* [LENGTH()](../length/index)
* [LENGTHB()](../lengthb/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/octet_length/>

OLD\_PASSWORD
=============

    Syntax
------

 
```
OLD_PASSWORD(str)

```
 Description
-----------

 `OLD_PASSWORD()` was added to MySQL when the implementation of [PASSWORD()](../password/index) was changed to improve security. `OLD_PASSWORD()` returns the value of the old (pre-MySQL 4.1) implementation of PASSWORD() as a string, and is intended to permit you to reset passwords for any pre-4.1 clients that need to connect to a more recent MySQL server version, or any version of MariaDB, without locking them out.

 As of [MariaDB 5.5](../what-is-mariadb-55/index), the return value is a nonbinary string in the connection [character set and collation](../data-types-character-sets-and-collations/index), determined by the values of the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables. Before 5.5, the return value was a binary string.

 The return value is 16 bytes in length, or NULL if the argument was NULL.

 See Also
--------

 * [PASSWORD()](../password/index)
* [MySQL manual on password hashing](http://dev.mysql.com/doc/refman/5.1/en/password-hashing.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/old_password/>

ORD
===

    Syntax
------

 
```
ORD(str)

```

Description
-----------

 If the leftmost character of the string `str` is a multi-byte character, returns the code for that character, calculated from the numeric values of its constituent bytes using this formula:

 
```
  (1st byte code)
+ (2nd byte code x 256)
+ (3rd byte code x 256 x 256) ...

```

If the leftmost character is not a multi-byte character, ORD() returns the same value as the [ASCII()](../ascii/index) function.

 Examples
--------

 
```
SELECT ORD('2');
+----------+
| ORD('2') |
+----------+
|       50 |
+----------+

```

See Also
--------

 * [ASCII()](../ascii/index) - Return ASCII value of first character
* [CHAR()](../char-function/index) - Create a character from an integer value

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ord/>

OVERLAPS
========

    Syntax
------

 
```
OVERLAPS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether `g1` spatially overlaps `g2`. The term spatially overlaps is used if two geometries intersect and their intersection results in a geometry of the same dimension but not equal to either of the given geometries.

 OVERLAPS() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_OVERLAPS()](../st_overlaps/index) uses object shapes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/overlaps/>

PASSWORD
========

    Syntax
------

 
```
PASSWORD(str)

```
 Description
-----------

 
The PASSWORD() function is used for hashing passwords for use in authentication by the MariaDB server. It is not intended for use in other applications.

 
Calculates and returns a hashed password string from the plaintext password *str*. Returns an empty string (>= [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/)) if the argument was NULL. 

 The return value is a nonbinary string in the connection [character set and collation](../data-types-character-sets-and-collations/index), determined by the values of the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables.

 This is the function that is used for hashing MariaDB passwords for storage in the Password column of the [user table](../mysqluser-table/index) (see [privileges](../grant/index)), usually used with the [SET PASSWORD](../set-password/index) statement. It is not intended for use in other applications.

 Until [MariaDB 10.3](../what-is-mariadb-103/index), the return value is 41-bytes in length, and the first character is always '\*'. From [MariaDB 10.4](../what-is-mariadb-104/index), the function takes into account the authentication plugin where applicable (A [CREATE USER](../create-user/index) or [SET PASSWORD](../set-password/index) statement). For example, when used in conjunction with a user authenticated by the [ed25519 plugin](../authentication-plugin-ed25519/index), the statement will create a longer hash:

 
```
CREATE USER edtest@localhost IDENTIFIED VIA ed25519 USING PASSWORD('secret');

CREATE USER edtest2@localhost IDENTIFIED BY 'secret';

SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM mysql.global_priv
  WHERE user LIKE 'edtest%'\G
*************************** 1. row ***************************
CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)): edtest@localhost => {
...
    "plugin": "ed25519",
    "authentication_string": "ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY",
...
}
*************************** 2. row ***************************
CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)): edtest2@localhost => {
...
    "plugin": "mysql_native_password",
    "authentication_string": "*14E65567ABDB5135D0CFD9A70B3032C179A49EE7",
...
}


```

The behavior of this function is affected by the value of the [old\_passwords](../server-system-variables/index#old_passwords) system variable. If this is set to `1` (`0` is default), MariaDB reverts to using the [mysql\_old\_password authentication plugin](../authentication-plugin-mysql_old_password/index) by default for newly created users and passwords. 

 Examples
--------

 
```
SELECT PASSWORD('notagoodpwd');
+-------------------------------------------+
| PASSWORD('notagoodpwd')                   |
+-------------------------------------------+
| *3A70EE9FC6594F88CE9E959CD51C5A1C002DC937 |
+-------------------------------------------+

```


```
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');

```

See Also
--------

 * [Password Validation Plugins](../password-validation-plugins/index) - permits the setting of basic criteria for passwords
* [OLD\_PASSWORD()](../old_password/index) - pre-MySQL 4.1 password function

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/password/>

PERCENT\_RANK
=============

    Syntax
------

 
```
PERCENT_RANK() OVER (
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

```

Description
-----------

 PERCENT\_RANK() is a [window function](../window-functions/index) that returns the relative percent rank of a given row. The following formula is used to calculate the percent rank:

 
```
(rank - 1) / (number of rows in the window or partition - 1)

```

Examples
--------

 
```
create table t1 (
  pk int primary key,
  a int,
  b int
);


insert into t1 values
( 1 , 0, 10),
( 2 , 0, 10),
( 3 , 1, 10),
( 4 , 1, 10),
( 8 , 2, 10),
( 5 , 2, 20),
( 6 , 2, 20),
( 7 , 2, 20),
( 9 , 4, 20),
(10 , 4, 20);

select pk, a, b,
    rank() over (order by a) as rank,
    percent_rank() over (order by a) as pct_rank,
    cume_dist() over (order by a) as cume_dist
from t1;
+----+------+------+------+--------------+--------------+
| pk | a    | b    | rank | pct_rank     | cume_dist    |
+----+------+------+------+--------------+--------------+
|  1 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  2 |    0 |   10 |    1 | 0.0000000000 | 0.2000000000 |
|  3 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  4 |    1 |   10 |    3 | 0.2222222222 | 0.4000000000 |
|  5 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  6 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  7 |    2 |   20 |    5 | 0.4444444444 | 0.8000000000 |
|  8 |    2 |   10 |    5 | 0.4444444444 | 0.8000000000 |
|  9 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
| 10 |    4 |   20 |    9 | 0.8888888889 | 1.0000000000 |
+----+------+------+------+--------------+--------------+

select pk, a, b,
       percent_rank() over (order by pk) as pct_rank,
       cume_dist() over (order by pk) as cume_dist
from t1 order by pk;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 0.1000000000 |
|  2 |    0 |   10 | 0.1111111111 | 0.2000000000 |
|  3 |    1 |   10 | 0.2222222222 | 0.3000000000 |
|  4 |    1 |   10 | 0.3333333333 | 0.4000000000 |
|  5 |    2 |   20 | 0.4444444444 | 0.5000000000 |
|  6 |    2 |   20 | 0.5555555556 | 0.6000000000 |
|  7 |    2 |   20 | 0.6666666667 | 0.7000000000 |
|  8 |    2 |   10 | 0.7777777778 | 0.8000000000 |
|  9 |    4 |   20 | 0.8888888889 | 0.9000000000 |
| 10 |    4 |   20 | 1.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+

select pk, a, b,
        percent_rank() over (partition by a order by a) as pct_rank,
        cume_dist() over (partition by a order by a) as cume_dist
from t1;
+----+------+------+--------------+--------------+
| pk | a    | b    | pct_rank     | cume_dist    |
+----+------+------+--------------+--------------+
|  1 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  2 |    0 |   10 | 0.0000000000 | 1.0000000000 |
|  3 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  4 |    1 |   10 | 0.0000000000 | 1.0000000000 |
|  5 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  6 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  7 |    2 |   20 | 0.0000000000 | 1.0000000000 |
|  8 |    2 |   10 | 0.0000000000 | 1.0000000000 |
|  9 |    4 |   20 | 0.0000000000 | 1.0000000000 |
| 10 |    4 |   20 | 0.0000000000 | 1.0000000000 |
+----+------+------+--------------+--------------+


```

See Also
--------

 * [CUME\_DIST()](../cume_dist/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/percent_rank/>

PERCENTILE\_CONT
================

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**The PERCENTILE\_CONT() [window function](../window-functions/index) was first introduced with in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

  Syntax
------

 Description
-----------

 `PERCENTILE_CONT()` (standing for continuous percentile) is a [window function](../window-functions/index) which returns a value which corresponds to the given fraction in the sort order. If required, it will interpolate between adjacent input items.

 Essentially, the following process is followed to find the value to return:

 * Get the number of rows in the partition, denoted by N
* RN = p\*(N-1), where p denotes the argument to the PERCENTILE\_CONT function
* calculate the FRN(floor row number) and CRN(column row number for the group( FRN= floor(RN) and CRN = ceil(RN))
* look up rows FRN and CRN
* If (CRN = FRN = RN) then the result is (value of expression from row at RN)
* Otherwise the result is
* (CRN - RN) \* (value of expression for row at FRN) +
* (RN - FRN) \* (value of expression for row at CRN)

 The [MEDIAN function](../median/index) is a specific case of `PERCENTILE_CONT`, equivalent to `PERCENTILE_CONT(0.5)`.

 Examples
--------

 
```
CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc 
  FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 4.0000000000 |
| Lord of the Ladybirds | 4.0000000000 |
| Lady of the Flies     | 2.0000000000 |
| Lady of the Flies     | 2.0000000000 |
| Lady of the Flies     | 2.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(1) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc 
  FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 5.0000000000 |
| Lord of the Ladybirds | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
| Lady of the Flies     | 5.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(0) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc 
  FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 3.0000000000 |
| Lord of the Ladybirds | 3.0000000000 |
| Lady of the Flies     | 1.0000000000 |
| Lady of the Flies     | 1.0000000000 |
| Lady of the Flies     | 1.0000000000 |
+-----------------------+--------------+

SELECT name, PERCENTILE_CONT(0.6) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc 
  FROM book_rating;
+-----------------------+--------------+
| name                  | pc           |
+-----------------------+--------------+
| Lord of the Ladybirds | 4.2000000000 |
| Lord of the Ladybirds | 4.2000000000 |
| Lady of the Flies     | 2.6000000000 |
| Lady of the Flies     | 2.6000000000 |
| Lady of the Flies     | 2.6000000000 |
+-----------------------+--------------+

```

See Also
--------

 * [MEDIAN()](../median/index) - a special case of `PERCENTILE_CONT` equivalent to `PERCENTILE_CONT(0.5)`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/percentile_cont/>

QUARTER
=======

    Syntax
------

 
```
QUARTER(date)

```

Description
-----------

 Returns the quarter of the year for `date`, in the range 1 to 4. Returns 0 if month contains a zero value, or `NULL` if the given value is not otherwise a valid date (zero values are accepted).

 Examples
--------

 
```
SELECT QUARTER('2008-04-01');
+-----------------------+
| QUARTER('2008-04-01') |
+-----------------------+
|                     2 |
+-----------------------+

SELECT QUARTER('2019-00-01');
+-----------------------+
| QUARTER('2019-00-01') |
+-----------------------+
|                     0 |
+-----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/quarter/>

PI
==

    Syntax
------

 
```
PI()

```

Description
-----------

 Returns the value of π (pi). The default number of decimal places displayed is six, but MariaDB uses the full double-precision value internally.

 Examples
--------

 
```
SELECT PI();
+----------+
| PI()     |
+----------+
| 3.141593 |
+----------+

SELECT PI()+0.0000000000000000000000;
+-------------------------------+
| PI()+0.0000000000000000000000 |
+-------------------------------+
|      3.1415926535897931159980 |
+-------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pi/>

PERIOD\_DIFF
============

    Syntax
------

 
```
PERIOD_DIFF(P1,P2)

```

Description
-----------

 Returns the number of months between periods P1 and P2. P1 and P2 can be in the format `YYMM` or `YYYYMM`, and are not date values.

 If P1 or P2 contains a two-digit year, values from 00 to 69 are converted to from 2000 to 2069, while values from 70 are converted to 1970 upwards.

 Examples
--------

 
```
SELECT PERIOD_DIFF(200802,200703);
+----------------------------+
| PERIOD_DIFF(200802,200703) |
+----------------------------+
|                         11 |
+----------------------------+

SELECT PERIOD_DIFF(6902,6803);
+------------------------+
| PERIOD_DIFF(6902,6803) |
+------------------------+
|                     11 |
+------------------------+

SELECT PERIOD_DIFF(7002,6803);
+------------------------+
| PERIOD_DIFF(7002,6803) |
+------------------------+
|                  -1177 |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/period_diff/>

POLYGON
=======

    Syntax
------

 
```
Polygon(ls1,ls2,...)

```

Description
-----------

 Constructs a WKB Polygon value from a number of [WKB](../wkb/index) [LineString](../linestring/index) arguments. If any argument does not represent the WKB of a LinearRing (that is, not a closed and simple LineString) the return value is `NULL`.

 Note that according to the OpenGIS standard, a POLYGON should have exactly one ExteriorRing and all other rings should lie within that ExteriorRing and thus be the InteriorRings. Practically, however, some systems, including MariaDB's, permit polygons to have several 'ExteriorRings'. In the case of there being multiple, non-overlapping exterior rings [ST\_NUMINTERIORRINGS()](../st_numinteriorrings/index) will return 1.

 Examples
--------

 
```
SET @g = ST_GEOMFROMTEXT('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))');

CREATE TABLE gis_polygon   (g POLYGON);
INSERT INTO gis_polygon VALUES
    (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
    (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
    (PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));

```

Non-overlapping 'polygon':

 
```
SELECT ST_NumInteriorRings(ST_PolyFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),
  (-1 -1,-5 -1,-5 -5,-1 -5,-1 -1))')) AS NumInteriorRings;
+------------------+
| NumInteriorRings |
+------------------+
|                1 |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon/>

PolygonFromWKB
==============

    A synonym for [ST\_PolyFromWKB](../st_polyfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygonfromwkb/>

POSITION
========

    Syntax
------

 
```
POSITION(substr IN str)

```

Description
-----------

 POSITION(substr IN str) is a synonym for [LOCATE(substr,str)](../locate/index).

 It's part of ODBC 3.0.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/position/>

PolygonFromText
===============

    A synonym for [ST\_PolyFromText](../st_polyfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygonfromtext/>

POINT
=====

    Syntax
------

 
```
Point(x,y)

```

Description
-----------

 Constructs a [WKB](../wkb/index) Point using the given coordinates.

 Examples
--------

 
```
SET @g = ST_GEOMFROMTEXT('Point(1 1)');

CREATE TABLE gis_point  (g POINT);
INSERT INTO gis_point VALUES
    (PointFromText('POINT(10 10)')),
    (PointFromText('POINT(20 10)')),
    (PointFromText('POINT(20 20)')),
    (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/point/>

PERCENTILE\_DISC
================

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**The PERCENTILE\_DISC() [window function](../window-functions/index) was first introduced with in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

 
Syntax
------

 Description
-----------

 `PERCENTILE_DISC()` (standing for discrete percentile) is a [window function](../window-functions/index) which returns the first value in the set whose ordered position is the same or more than the specified fraction.

 Essentially, the following process is followed to find the value to return:

 * Get the number of rows in the partition.
* Walk through the partition, in order, until finding the the first row with [CUME\_DIST()](../cume_dist/index) >= function\_argument.

 Examples
--------

 
```
CREATE TABLE book_rating (name CHAR(30), star_rating TINYINT);

INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 5);
INSERT INTO book_rating VALUES ('Lord of the Ladybirds', 3);
INSERT INTO book_rating VALUES ('Lady of the Flies', 1);
INSERT INTO book_rating VALUES ('Lady of the Flies', 2);
INSERT INTO book_rating VALUES ('Lady of the Flies', 5);

SELECT name, PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY star_rating)
  OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    3 |
| Lord of the Ladybirds |    3 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(0) WITHIN GROUP (ORDER BY star_rating) 
 OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    3 |
| Lord of the Ladybirds |    3 |
| Lady of the Flies     |    1 |
| Lady of the Flies     |    1 |
| Lady of the Flies     |    1 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(1) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    5 |
| Lord of the Ladybirds |    5 |
| Lady of the Flies     |    5 |
| Lady of the Flies     |    5 |
| Lady of the Flies     |    5 |
+-----------------------+------+
5 rows in set (0.000 sec)

SELECT name, PERCENTILE_DISC(0.6) WITHIN GROUP (ORDER BY star_rating) 
  OVER (PARTITION BY name) AS pc FROM book_rating;
+-----------------------+------+
| name                  | pc   |
+-----------------------+------+
| Lord of the Ladybirds |    5 |
| Lord of the Ladybirds |    5 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
| Lady of the Flies     |    2 |
+-----------------------+------

```

See Also
--------

 * [CUME\_DIST()](../cume_dist/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/percentile_disc/>

PERIOD\_ADD
===========

    Syntax
------

 
```
PERIOD_ADD(P,N)

```

Description
-----------

 Adds `N` months to period `P`. `P` is in the format YYMM or YYYYMM, and is not a date value. If `P` contains a two-digit year, values from 00 to 69 are converted to from 2000 to 2069, while values from 70 are converted to 1970 upwards.

 Returns a value in the format YYYYMM.

 Examples
--------

 
```
SELECT PERIOD_ADD(200801,2);
+----------------------+
| PERIOD_ADD(200801,2) |
+----------------------+
|               200803 |
+----------------------+

SELECT PERIOD_ADD(6910,2);
+--------------------+
| PERIOD_ADD(6910,2) |
+--------------------+
|             206912 |
+--------------------+

SELECT PERIOD_ADD(7010,2);
+--------------------+
| PERIOD_ADD(7010,2) |
+--------------------+
|             197012 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/period_add/>

ST\_POINTN
==========

    Syntax
------

 
```
ST_PointN(ls,N)
PointN(ls,N)

```

Description
-----------

 Returns the N-th [Point](../point/index) in the [LineString](../linestring/index) value `ls`. Points are numbered beginning with `1`.

 `ST_PointN()` and `PointN()` are synonyms.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(PointN(GeomFromText(@ls),2));
+-------------------------------------+
| AsText(PointN(GeomFromText(@ls),2)) |
+-------------------------------------+
| POINT(2 2)                          |
+-------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pointn/>

PointOnSurface
==============

    A synonym for [ST\_PointOnSurface](../st_pointonsurface/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pointonsurface/>

POW
===

    Syntax
------

 
```
POW(X,Y)

```

Description
-----------

 Returns the value of X raised to the power of Y.

 POWER() is a synonym.

 Examples
--------

 
```
SELECT POW(2,3);
+----------+
| POW(2,3) |
+----------+
|        8 |
+----------+

SELECT POW(2,-2);
+-----------+
| POW(2,-2) |
+-----------+
|      0.25 |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pow/>

POWER
=====

    Syntax
------

 
```
POWER(X,Y)

```

Description
-----------

 This is a synonym for [POW()](../pow/index), which returns the value of X raised to the power of Y.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/power/>

QUOTE
=====

    Syntax
------

 
```
QUOTE(str)

```

Description
-----------

 Quotes a string to produce a result that can be used as a properly escaped data value in an SQL statement. The string is returned enclosed by single quotes and with each instance of single quote ("`'`"), backslash ("`\`"), `ASCII NUL`, and Control-Z preceded by a backslash. If the argument is `NULL`, the return value is the word "`NULL`" without enclosing single quotes.

 Examples
--------

 
```
SELECT QUOTE("Don't!");
+-----------------+
| QUOTE("Don't!") |
+-----------------+
| 'Don\'t!'       |
+-----------------+

SELECT QUOTE(NULL); 
+-------------+
| QUOTE(NULL) |
+-------------+
| NULL        |
+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/quote/>

ST\_PointFromWKB
================

    Syntax
------

 
```
ST_PointFromWKB(wkb[,srid])
PointFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a [POINT](../point/index) value using its [WKB](../well-known-binary-wkb-format/index) representation and [SRID](../srid/index).

 `ST_PointFromWKB()` and `PointFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(ST_PointFromText('POINT(0 4)'));

SELECT ST_AsText(ST_PointFromWKB(@g)) AS p;
+------------+
| p          |
+------------+
| POINT(0 4) |
+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pointfromwkb/>

ST\_PointFromText
=================

    Syntax
------

 
```
ST_PointFromText(wkt[,srid])
PointFromText(wkt[,srid])

```

Description
-----------

 Constructs a [POINT](../point/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `ST_PointFromText()` and `PointFromText()` are synonyms.

 Examples
--------

 
```
CREATE TABLE gis_point  (g POINT);
SHOW FIELDS FROM gis_point;
INSERT INTO gis_point VALUES
    (PointFromText('POINT(10 10)')),
    (PointFromText('POINT(20 10)')),
    (PointFromText('POINT(20 20)')),
    (PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pointfromtext/>

ST\_PolyFromText
================

    Syntax
------

 
```
ST_PolyFromText(wkt[,srid])
ST_PolygonFromText(wkt[,srid])
PolyFromText(wkt[,srid])
PolygonFromText(wkt[,srid])

```

Description
-----------

 Constructs a [POLYGON](../polygon/index) value using its [WKT](../wkt-definition/index) representation and [SRID](../srid/index).

 `ST_PolyFromText()`, `ST_PolygonFromText()`, `PolyFromText()` and `ST_PolygonFromText()` are all synonyms.

 Examples
--------

 
```
CREATE TABLE gis_polygon   (g POLYGON);
INSERT INTO gis_polygon VALUES
    (PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
    (PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))'));

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polyfromtext/>

ST\_PolyFromWKB
===============

    Syntax
------

 
```
ST_PolyFromWKB(wkb[,srid])
ST_PolygonFromWKB(wkb[,srid])
PolyFromWKB(wkb[,srid])
PolygonFromWKB(wkb[,srid])

```

Description
-----------

 Constructs a [POLYGON](../polygon/index) value using its [WKB](../well-known-binary-wkb-format/index) representation and [SRID](../srid/index).

 `ST_PolyFromWKB()`, `ST_PolygonFromWKB()`, `PolyFromWKB()` and `PolygonFromWKB()` are synonyms.

 Examples
--------

 
```
SET @g = ST_AsBinary(ST_PolyFromText('POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1))'));

SELECT ST_AsText(ST_PolyFromWKB(@g)) AS p;
+----------------------------------------+
| p                                      |
+----------------------------------------+
| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |
+----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polyfromwkb/>

RADIANS
=======

    Syntax
------

 
```
RADIANS(X)

```

Description
-----------

 Returns the argument *`X`*, converted from degrees to radians. Note that π radians equals 180 degrees. 

 This is the converse of the [DEGREES()](../degrees/index) function.

 Examples
--------

 
```
SELECT RADIANS(45);
+-------------------+
| RADIANS(45)       |
+-------------------+
| 0.785398163397448 |
+-------------------+

SELECT RADIANS(90);
+-----------------+
| RADIANS(90)     |
+-----------------+
| 1.5707963267949 |
+-----------------+

SELECT RADIANS(PI());
+--------------------+
| RADIANS(PI())      |
+--------------------+
| 0.0548311355616075 |
+--------------------+

SELECT RADIANS(180);
+------------------+
| RADIANS(180)     |
+------------------+
| 3.14159265358979 |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/radians/>

ST\_NUMGEOMETRIES
=================

    Syntax
------

 
```
ST_NumGeometries(gc)
NumGeometries(gc)

```

Description
-----------

 Returns the number of geometries in the GeometryCollection `gc`.

 `ST_NumGeometries()` and `NumGeometries()` are synonyms.

 Example
-------

 
```
SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';

SELECT NUMGEOMETRIES(GeomFromText(@gc));
+----------------------------------+
| NUMGEOMETRIES(GeomFromText(@gc)) |
+----------------------------------+
|                                2 |
+----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numgeometries/>

RAND
====

    Syntax
------

 
```
RAND(), RAND(N)

```

Description
-----------

 Returns a random `[DOUBLE](../double/index)` precision floating point value v in the range 0 <= v < 1.0. If a constant integer argument N is specified, it is used as the seed value, which produces a repeatable sequence of column values. In the example below, note that the sequences of values produced by RAND(3) is the same both places where it occurs.

 In a WHERE clause, RAND() is evaluated each time the WHERE is executed.

 Statements using the RAND() function are not [safe for statement-based replication](../unsafe-statements-for-replication/index).

 Practical uses
--------------

 The expression to get a random integer from a given range is the following:

 
```
FLOOR(min_value + RAND() * (max_value - min_value +1))

```

RAND() is often used to read random rows from a table, as follows:

 
```
SELECT * FROM my_table ORDER BY RAND() LIMIT 10;

```

Note, however, that this technique should never be used on a large table as it will be extremely slow. MariaDB will read all rows in the table, generate a random value for each of them, order them, and finally will apply the LIMIT clause.

 Examples
--------

 
```
CREATE TABLE t (i INT);

INSERT INTO t VALUES(1),(2),(3);

SELECT i, RAND() FROM t;
+------+-------------------+
| i    | RAND()            |
+------+-------------------+
|    1 | 0.255651095188829 |
|    2 | 0.833920199269355 |
|    3 |  0.40264774151393 |
+------+-------------------+

SELECT i, RAND(3) FROM t;
+------+-------------------+
| i    | RAND(3)           |
+------+-------------------+
|    1 |  0.90576975597606 |
|    2 | 0.373079058130345 |
|    3 | 0.148086053457191 |
+------+-------------------+

SELECT i, RAND() FROM t;
+------+-------------------+
| i    | RAND()            |
+------+-------------------+
|    1 | 0.511478140495232 |
|    2 | 0.349447508668012 |
|    3 | 0.212803152588013 |
+------+-------------------+

```

Using the same seed, the same sequence will be returned:

 
```
SELECT i, RAND(3) FROM t;
+------+-------------------+
| i    | RAND(3)           |
+------+-------------------+
|    1 |  0.90576975597606 |
|    2 | 0.373079058130345 |
|    3 | 0.148086053457191 |
+------+-------------------+

```

Generating a random number from 5 to 15:

 
```
SELECT FLOOR(5 + (RAND() * 11));

```

See Also
--------

 * [Techniques for Efficiently Finding a Random Row](../techniques-for-efficiently-finding-a-random-row/index)
* [rand\_seed1 and rand\_seed2 system variables](../server-system-variables/index#rand_seed1)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rand/>

REGEXP
======

    Syntax
------

 
```
expr REGEXP pat, expr RLIKE pat

```

Description
-----------

 Performs a pattern match of a string expression `expr` against a pattern `pat`. The pattern can be an extended regular expression. See [Regular Expressions Overview](../regular-expressions-overview/index) for details on the syntax for regular expressions (see also [PCRE Regular Expressions](../pcre-regular-expressions/index)). 

 Returns `1` if `expr` matches `pat` or `0` if it doesn't match. If either `expr` or `pat` are NULL, the result is NULL. 

 The negative form [NOT REGEXP](../not-regexp/index) also exists, as an alias for `NOT (string REGEXP pattern)`. RLIKE and NOT RLIKE are synonyms for REGEXP and NOT REGEXP, originally provided for mSQL compatibility.

 The pattern need not be a literal string. For example, it can be specified as a string expression or table column.

 **Note:** Because MariaDB uses the C escape syntax in strings (for example, "\n" to represent the newline character), you must double any "\" that you use in your REGEXP strings.

 REGEXP is not case sensitive, except when used with binary strings.

 [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) moved to the PCRE regex library - see [PCRE Regular Expressions](../pcre-regular-expressions/index) for enhancements to REGEXP introduced in [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/).

 The [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable addresses the remaining compatibilities between PCRE and the old regex library. 

 Examples
--------

 
```
SELECT 'Monty!' REGEXP 'm%y%%';
+-------------------------+
| 'Monty!' REGEXP 'm%y%%' |
+-------------------------+
|                       0 |
+-------------------------+

SELECT 'Monty!' REGEXP '.*';
+----------------------+
| 'Monty!' REGEXP '.*' |
+----------------------+
|                    1 |
+----------------------+

SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
+---------------------------------------+
| 'new*\n*line' REGEXP 'new\\*.\\*line' |
+---------------------------------------+
|                                     1 |
+---------------------------------------+

SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
+----------------+-----------------------+
| 'a' REGEXP 'A' | 'a' REGEXP BINARY 'A' |
+----------------+-----------------------+
|              1 |                     0 |
+----------------+-----------------------+

SELECT 'a' REGEXP '^[a-d]';
+---------------------+
| 'a' REGEXP '^[a-d]' |
+---------------------+
|                   1 |
+---------------------+

```

### default\_regex\_flags examples

 [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) introduced the [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable to address the remaining compatibilities between PCRE and the old regex library. 

 The default behaviour (multiline match is off)

 
```
SELECT 'a\nb\nc' RLIKE '^b$';
+---------------------------+
| '(?m)a\nb\nc' RLIKE '^b$' |
+---------------------------+
|                         0 |
+---------------------------+

```

Enabling the multiline option using the PCRE option syntax:

 
```
SELECT 'a\nb\nc' RLIKE '(?m)^b$';
+---------------------------+
| 'a\nb\nc' RLIKE '(?m)^b$' |
+---------------------------+
|                         1 |
+---------------------------+

```

Enabling the multiline option using default\_regex\_flags

 
```
SET default_regex_flags='MULTILINE';
SELECT 'a\nb\nc' RLIKE '^b$';
+-----------------------+
| 'a\nb\nc' RLIKE '^b$' |
+-----------------------+
|                     1 |
+-----------------------+ 

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regexp/>

REGEXP\_INSTR
=============

    Syntax
------

 
```
REGEXP_INSTR(subject, pattern)

```

Returns the position of the first occurrence of the regular expression `pattern` in the string `subject`, or 0 if pattern was not found.

 The positions start with 1 and are measured in characters (i.e. not in bytes), which is important for multi-byte character sets. You can cast a multi-byte character set to [BINARY](../binary/index) to get offsets in bytes.

 The function follows the case sensitivity rules of the effective [collation](../data-types-character-sets-and-collations/index). Matching is performed case insensitively for case insensitive collations, and case sensitively for case sensitive collations and for binary data.

 The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags.

 MariaDB uses the [PCRE regular expression](../pcre-regular-expressions/index) library for enhanced regular expression performance, and REGEXP\_INSTR was introduced as part of this enhancement.

 Examples
--------

 
```
SELECT REGEXP_INSTR('abc','b');
-> 2

SELECT REGEXP_INSTR('abc','x');
-> 0

SELECT REGEXP_INSTR('BJÖRN','N');
-> 5

```

Casting a multi-byte character set as BINARY to get offsets in bytes:

 
```
SELECT REGEXP_INSTR(BINARY 'BJÖRN','N') AS cast_utf8_to_binary;
-> 6

```

Case sensitivity:

 
```
SELECT REGEXP_INSTR('ABC','b');
-> 2

SELECT REGEXP_INSTR('ABC' COLLATE utf8_bin,'b');
-> 0

SELECT REGEXP_INSTR(BINARY'ABC','b');
-> 0

SELECT REGEXP_INSTR('ABC','(?-i)b');
-> 0

SELECT REGEXP_INSTR('ABC' COLLATE utf8_bin,'(?i)b');
-> 2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regexp_instr/>

REPEAT Function
===============

    Syntax
------

 
```
REPEAT(str,count)

```

Description
-----------

 Returns a string consisting of the string `str` repeated `count` times. If `count` is less than 1, returns an empty string. Returns NULL if `str` or `count` are NULL.

 Examples
--------

 
```
SELECT QUOTE(REPEAT('MariaDB ',4));
+------------------------------------+
| QUOTE(REPEAT('MariaDB ',4))        |
+------------------------------------+
| 'MariaDB MariaDB MariaDB MariaDB ' |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/repeat-function/>

REGEXP\_SUBSTR
==============

    Syntax
------

 
```
REGEXP_SUBSTR(subject,pattern)

```

Description
-----------

 Returns the part of the string `subject` that matches the regular expression `pattern`, or an empty string if `pattern` was not found.

 The function follows the case sensitivity rules of the effective [collation](../data-types-character-sets-and-collations/index). Matching is performed case insensitively for case insensitive collations, and case sensitively for case sensitive collations and for binary data.

 The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags.

 MariaDB uses the [PCRE regular expression](../pcre-regular-expressions/index) library for enhanced regular expression performance, and `REGEXP_SUBSTR` was introduced as part of this enhancement.

 The [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable addresses the remaining compatibilities between PCRE and the old regex library. 

 Examples
--------

 
```
SELECT REGEXP_SUBSTR('ab12cd','[0-9]+');
-> 12

SELECT REGEXP_SUBSTR(
  'See https://mariadb.org/en/foundation/ for details',
  'https?://[^/]*');
-> https://mariadb.org

```


```
SELECT REGEXP_SUBSTR('ABC','b');
-> B

SELECT REGEXP_SUBSTR('ABC' COLLATE utf8_bin,'b');
->

SELECT REGEXP_SUBSTR(BINARY'ABC','b');
->

SELECT REGEXP_SUBSTR('ABC','(?i)b');
-> B

SELECT REGEXP_SUBSTR('ABC' COLLATE utf8_bin,'(?+i)b');
-> B

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regexp_substr/>

REPLACE Function
================

    Syntax
------

 
```
REPLACE(str,from_str,to_str)

```

Description
-----------

 Returns the string `str` with all occurrences of the string `from_str` replaced by the string `to_str`. REPLACE() performs a case-sensitive match when searching for `from_str`.

 Examples
--------

 
```
SELECT REPLACE('www.mariadb.org', 'w', 'Ww');
+---------------------------------------+
| REPLACE('www.mariadb.org', 'w', 'Ww') |
+---------------------------------------+
| WwWwWw.mariadb.org                    |
+---------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replace-function/>

REVERSE
=======

    Syntax
------

 
```
REVERSE(str)

```

Description
-----------

 Returns the string `str` with the order of the characters reversed.

 Examples
--------

 
```
SELECT REVERSE('desserts');
+---------------------+
| REVERSE('desserts') |
+---------------------+
| stressed            |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/reverse/>

ROW\_COUNT
==========

    Syntax
------

 
```
ROW_COUNT()

```

Description
-----------

 ROW\_COUNT() returns the number of rows updated, inserted or deleted by the preceding statement. This is the same as the row count that the mariadb client displays and the value from the [mysql\_affected\_rows()](../mysql_affected_rows/index) C API function.

 Generally:

 * For statements which return a result set (such as [SELECT](../select/index), [SHOW](../show/index), [DESC](../describe/index) or [HELP](../help-command/index)), returns -1, even when the result set is empty. This is also true for administrative statements, such as [OPTIMIZE](../optimize-table/index).
* For DML statements other than [SELECT](../select/index) and for [ALTER TABLE](../alter/index), returns the number of affected rows.
* For DDL statements (including [TRUNCATE](../truncate/index)) and for other statements which don't return any result set (such as [USE](../use/index), [DO](../do/index), [SIGNAL](../signal/index) or [DEALLOCATE PREPARE](../deallocate-drop-prepared-statement/index)), returns 0.

 For [UPDATE](../update/index), affected rows is by default the number of rows that were actually changed. If the CLIENT\_FOUND\_ROWS flag to [mysql\_real\_connect()](../mysql_real_connect/index) is specified when connecting to mysqld, affected rows is instead the number of rows matched by the WHERE clause. 

 For [REPLACE](../replace/index), deleted rows are also counted. So, if REPLACE deletes a row and adds a new row, ROW\_COUNT() returns 2.

 For [INSERT ... ON DUPLICATE KEY](../insert-on-duplicate-key-update/index), updated rows are counted twice. So, if INSERT adds a new rows and modifies another row, ROW\_COUNT() returns 3.

 ROW\_COUNT() does not take into account rows that are not directly deleted/updated by the last statement. This means that rows deleted by foreign keys or triggers are not counted.

 **Warning:** You can use ROW\_COUNT() with prepared statements, but you need to call it after EXECUTE, not after [DEALLOCATE PREPARE](../deallocate-drop-prepared-statement/index), because the row count for allocate prepare is always 0.

 **Warning:** When used after a [CALL](../call/index) statement, this function returns the number of rows affected by the last statement in the procedure, not by the whole procedure.

 **Warning:** After [INSERT DELAYED](../insert-delayed/index), ROW\_COUNT() returns the number of the rows you tried to insert, not the number of the successful writes.

 This information can also be found in the [diagnostics area](../diagnostics-area/index).

 Statements using the ROW\_COUNT() function are not [safe for replication](../unsafe-statements-for-replication/index).

 Examples
--------

 
```
CREATE TABLE t (A INT);

INSERT INTO t VALUES(1),(2),(3);

SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+

DELETE FROM t WHERE A IN(1,2);

SELECT ROW_COUNT(); 
+-------------+
| ROW_COUNT() |
+-------------+
|           2 |
+-------------+

```

Example with prepared statements:

 
```
SET @q = 'INSERT INTO t VALUES(1),(2),(3);';

PREPARE stmt FROM @q;

EXECUTE stmt;
Query OK, 3 rows affected (0.39 sec)
Records: 3  Duplicates: 0  Warnings: 0

SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+

```

See Also
--------

 * [FOUND\_ROWS()](../found_rows/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/row_count/>

RLIKE
=====

    Syntax
------

 
```
expr REGEXP pat, expr RLIKE pat

```

Description
-----------

 `RLIKE` is a synonym for [REGEXP](../regexp/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rlike/>

ROUND
=====

    Syntax
------

 
```
ROUND(X), ROUND(X,D)

```

Description
-----------

 Rounds the argument `X` to `D` decimal places. `D` defaults to `0` if not specified. `D` can be negative to cause `D` digits left of the decimal point of the value `X` to become zero.

 The rounding algorithm depends on the data type of `X`:

 * for floating point types ([FLOAT](../float/index), [DOUBLE](../double/index)) the C libraries rounding function is used, so the behavior \*may\* differ between operating systems
* for fixed point types ([DECIMAL](../decimal/index), [DEC/NUMBER/FIXED](../dec-numeric-fixed/index)) the "round half up" rule is used, meaning that e.g. a value ending in exactly .5 is always rounded up.

 Examples
--------

 
```
SELECT ROUND(-1.23);
+--------------+
| ROUND(-1.23) |
+--------------+
|           -1 |
+--------------+

SELECT ROUND(-1.58);
+--------------+
| ROUND(-1.58) |
+--------------+
|           -2 |
+--------------+

SELECT ROUND(1.58); 
+-------------+
| ROUND(1.58) |
+-------------+
|           2 |
+-------------+

SELECT ROUND(1.298, 1);
+-----------------+
| ROUND(1.298, 1) |
+-----------------+
|             1.3 |
+-----------------+

SELECT ROUND(1.298, 0);
+-----------------+
| ROUND(1.298, 0) |
+-----------------+
|               1 |
+-----------------+

SELECT ROUND(23.298, -1);
+-------------------+
| ROUND(23.298, -1) |
+-------------------+
|                20 |
+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/round/>

REGEXP\_REPLACE
===============

    Syntax
------

 
```
REGEXP_REPLACE(subject, pattern, replace)

```

Description
-----------

 `REGEXP_REPLACE` returns the string `subject` with all occurrences of the regular expression `pattern` replaced by the string `replace`. If no occurrences are found, then `subject` is returned as is.

 The replace string can have backreferences to the subexpressions in the form \N, where N is a number from 1 to 9.

 The function follows the case sensitivity rules of the effective [collation](../data-types-character-sets-and-collations/index). Matching is performed case insensitively for case insensitive collations, and case sensitively for case sensitive collations and for binary data.

 The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags.

 MariaDB uses the [PCRE regular expression](../pcre-regular-expressions/index) library for enhanced regular expression performance, and `REGEXP_REPLACE` was introduced as part of this enhancement.

 The [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable addresses the remaining compatibilities between PCRE and the old regex library. 

 Examples
--------

 
```
SELECT REGEXP_REPLACE('ab12cd','[0-9]','') AS remove_digits;
-> abcd

SELECT REGEXP_REPLACE('<html><head><title>title</title><body>body</body></htm>', '<.+?>',' ')
AS strip_html;
-> title  body

```

Backreferences to the subexpressions in the form `\N`, where N is a number from 1 to 9:

 
```
SELECT REGEXP_REPLACE('James Bond','^(.*) (.*)$','\\2, \\1') AS reorder_name;
-> Bond, James

```

Case insensitive and case sensitive matches:

 
```
SELECT REGEXP_REPLACE('ABC','b','-') AS case_insensitive;
-> A-C

SELECT REGEXP_REPLACE('ABC' COLLATE utf8_bin,'b','-') AS case_sensitive;
-> ABC

SELECT REGEXP_REPLACE(BINARY 'ABC','b','-') AS binary_data;
-> ABC

```

Overwriting the collation case sensitivity using the (?i) and (?-i) PCRE flags.

 
```
SELECT REGEXP_REPLACE('ABC','(?-i)b','-') AS force_case_sensitive;
-> ABC

SELECT REGEXP_REPLACE(BINARY 'ABC','(?i)b','-') AS force_case_insensitive;
-> A-C

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regexp_replace/>

RIGHT
=====

    Syntax
------

 
```
RIGHT(str,len)

```

Description
-----------

 Returns the rightmost *`len`* characters from the string *`str`*, or NULL if any argument is NULL.

 Examples
--------

 
```
SELECT RIGHT('MariaDB', 2);
+---------------------+
| RIGHT('MariaDB', 2) |
+---------------------+
| DB                  |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/right/>

RPAD
====

    Syntax
------

 
```
RPAD(str, len [, padstr])

```
 Description
-----------

 Returns the string `str`, right-padded with the string `padstr` to a length of `len` characters. If `str` is longer than `len`, the return value is shortened to `len` characters. If `padstr` is omitted, the RPAD function pads spaces.

 Prior to [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), the `padstr` parameter was mandatory.

 Returns NULL if given a NULL argument. If the result is empty (a length of zero), returns either an empty string, or, from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) with [SQL\_MODE=Oracle](../sql_modeoracle-from-mariadb-103/index), NULL.

 The Oracle mode version of the function can be accessed outside of Oracle mode by using `RPAD_ORACLE` as the function name.

 Examples
--------

 
```
SELECT RPAD('hello',10,'.');
+----------------------+
| RPAD('hello',10,'.') |
+----------------------+
| hello.....           |
+----------------------+

SELECT RPAD('hello',2,'.');
+---------------------+
| RPAD('hello',2,'.') |
+---------------------+
| he                  |
+---------------------+

```

From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), with the pad string defaulting to space.

 
```
SELECT RPAD('hello',30);
+--------------------------------+
| RPAD('hello',30)               |
+--------------------------------+
| hello                          |
+--------------------------------+

```

Oracle mode version from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/):

 
```
SELECT RPAD('',0),RPAD_ORACLE('',0);
+------------+-------------------+
| RPAD('',0) | RPAD_ORACLE('',0) |
+------------+-------------------+
|            | NULL              |
+------------+-------------------+

```

See Also
--------

 * [LPAD](../lpad/index) - Left-padding instead of right-padding.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rpad/>

RANK
====

    Syntax
------

 
```
RANK() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 

```

Description
-----------

 RANK() is a [window function](../window-functions/index) that displays the number of a given row, starting at one and following the [ORDER BY](../order-by/index) sequence of the window function, with identical values receiving the same result. It is similar to the [ROW\_NUMBER()](../row_number/index) function except that in that function, identical values will receive a different row number for each result.

 Examples
--------

 The distinction between [DENSE\_RANK()](../dense_rank/index), RANK() and [ROW\_NUMBER()](../row_number/index):

 
```
CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
  ('Maths', 60, 'Thulile'),
  ('Maths', 60, 'Pritha'),
  ('Maths', 70, 'Voitto'),
  ('Maths', 55, 'Chun'),
  ('Biology', 60, 'Bilal'),
   ('Biology', 70, 'Roger');

SELECT 
  RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank, 
  DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank, 
  ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num, 
  course, mark, name 
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

```

See Also
--------

 * [DENSE\_RANK()](../dense_rank/index)
* [ROW\_NUMBER()](../row_number/index)
* [ORDER BY](../order-by/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rank/>

SCHEMA
======

    Syntax
------

 
```
SCHEMA()

```

Description
-----------

 This function is a synonym for [DATABASE()](../database/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/schema/>

RELEASE\_LOCK
=============

    Syntax
------

 
```
RELEASE_LOCK(str)

```
 Description
-----------

 Releases the lock named by the string `str` that was obtained with [GET\_LOCK()](../get_lock/index). Returns 1 if the lock was released, 0 if the lock was not established by this thread (in which case the lock is not released), and `NULL` if the named lock did not exist. The lock does not exist if it was never obtained by a call to `GET_LOCK()` or if it has previously been released.

 `str` is case insensitive. If `str` is an empty string or `NULL`, `RELEASE_LOCK()` returns `NULL` and does nothing.

 Statements using the RELEASE\_LOCK() function are not [safe for replication](../unsafe-statements-for-replication/index).

 The [DO statement](../do/index) is convenient to use with `RELEASE_LOCK()`.

 Examples
--------

 Connection1:

 
```
SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

```

Connection 2:

 
```
SELECT GET_LOCK('lock2',10);
+----------------------+
| GET_LOCK('lock2',10) |
+----------------------+
|                    1 |
+----------------------+

```

Connection 1:

 
```
SELECT RELEASE_LOCK('lock1'), RELEASE_LOCK('lock2'), RELEASE_LOCK('lock3');
+-----------------------+-----------------------+-----------------------+
| RELEASE_LOCK('lock1') | RELEASE_LOCK('lock2') | RELEASE_LOCK('lock3') |
+-----------------------+-----------------------+-----------------------+
|                     1 |                     0 |                  NULL |
+-----------------------+-----------------------+-----------------------+

```

From [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/), it is possible to hold the same lock recursively. This example is viewed using the [metadata\_lock\_info](../metadata-lock-info/index) plugin:

 
```
SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT GET_LOCK('lock3',10);
+----------------------+
| GET_LOCK('lock3',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+------------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+------------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |            |
+-----------+---------------------+---------------+-----------+--------------+------------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
+-----------+---------------------+---------------+-----------+--------------+------------+
| THREAD_ID | LOCK_MODE           | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+---------------------+---------------+-----------+--------------+------------+
|        46 | MDL_SHARED_NO_WRITE | NULL          | User lock | lock3        |            |
+-----------+---------------------+---------------+-----------+--------------+------------+

SELECT RELEASE_LOCK('lock3');
+-----------------------+
| RELEASE_LOCK('lock3') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT * FROM INFORMATION_SCHEMA.METADATA_LOCK_INFO;
Empty set (0.000 sec)

```

See Also
--------

 * [GET\_LOCK](../get_lock/index)
* [IS\_FREE\_LOCK](../is_free_lock/index)
* [IS\_USED\_LOCK](../is_used_lock/index)
* [RELEASE\_ALL\_LOCKS](../release_all_locks/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/release_lock/>

ROW\_NUMBER
===========

    Syntax
------

 
```
ROW_NUMBER() OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 

```

Description
-----------

 ROW\_NUMBER() is a [window function](../window-functions/index) that displays the number of a given row, starting at one and following the [ORDER BY](../order-by/index) sequence of the window function, with identical values receiving different row numbers. It is similar to the [RANK()](../rank/index) and [DENSE\_RANK()](../dense_rank/index) functions except that in that function, identical values will receive the same rank for each result.

 Examples
--------

 The distinction between [DENSE\_RANK()](../dense_rank/index), [RANK()](../rank/index) and ROW\_NUMBER():

 
```
CREATE TABLE student(course VARCHAR(10), mark int, name varchar(10));

INSERT INTO student VALUES 
  ('Maths', 60, 'Thulile'),
  ('Maths', 60, 'Pritha'),
  ('Maths', 70, 'Voitto'),
  ('Maths', 55, 'Chun'),
  ('Biology', 60, 'Bilal'),
   ('Biology', 70, 'Roger');

SELECT 
  RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS rank, 
  DENSE_RANK() OVER (PARTITION BY course ORDER BY mark DESC) AS dense_rank, 
  ROW_NUMBER() OVER (PARTITION BY course ORDER BY mark DESC) AS row_num, 
  course, mark, name 
FROM student ORDER BY course, mark DESC;
+------+------------+---------+---------+------+---------+
| rank | dense_rank | row_num | course  | mark | name    |
+------+------------+---------+---------+------+---------+
|    1 |          1 |       1 | Biology |   70 | Roger   |
|    2 |          2 |       2 | Biology |   60 | Bilal   |
|    1 |          1 |       1 | Maths   |   70 | Voitto  |
|    2 |          2 |       2 | Maths   |   60 | Thulile |
|    2 |          2 |       3 | Maths   |   60 | Pritha  |
|    4 |          3 |       4 | Maths   |   55 | Chun    |
+------+------------+---------+---------+------+---------+

```

See Also
--------

 * [RANK()](../rank/index)
* [DENSE\_RANK()](../dense_rank/index)
* [ORDER BY](../order-by/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/row_number/>

SEC\_TO\_TIME
=============

    Syntax
------

 
```
SEC_TO_TIME(seconds)

```

Description
-----------

 Returns the seconds argument, converted to hours, minutes, and seconds, as a TIME value. The range of the result is constrained to that of the [TIME data type](../time/index). A warning occurs if the argument corresponds to a value outside that range.

 The time will be returned in the format `hh:mm:ss`, or `hhmmss` if used in a numeric calculation.

 Examples
--------

 
```
SELECT SEC_TO_TIME(12414);
+--------------------+
| SEC_TO_TIME(12414) |
+--------------------+
| 03:26:54           |
+--------------------+

SELECT SEC_TO_TIME(12414)+0;
+----------------------+
| SEC_TO_TIME(12414)+0 |
+----------------------+
|                32654 |
+----------------------+

SELECT SEC_TO_TIME(9999999);
+----------------------+
| SEC_TO_TIME(9999999) |
+----------------------+
| 838:59:59            |
+----------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1292 | Truncated incorrect time value: '9999999' |
+---------+------+-------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sec_to_time/>

SESSION\_USER
=============

    Syntax
------

 
```
SESSION_USER()

```

Description
-----------

 SESSION\_USER() is a synonym for [USER()](../user/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/session_user/>

RTRIM
=====

    Syntax
------

 
```
RTRIM(str)

```
 Description
-----------

 Returns the string `str` with trailing space characters removed.

 Returns NULL if given a NULL argument. If the result is empty, returns either an empty string, or, from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) with [SQL\_MODE=Oracle](../sql_modeoracle-from-mariadb-103/index), NULL.

 The Oracle mode version of the function can be accessed outside of Oracle mode by using `RTRIM_ORACLE` as the function name.

 Examples
--------

 
```
SELECT QUOTE(RTRIM('MariaDB    '));
+-----------------------------+
| QUOTE(RTRIM('MariaDB    ')) |
+-----------------------------+
| 'MariaDB'                   |
+-----------------------------+

```

Oracle mode version from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/):

 
```
SELECT RTRIM(''),RTRIM_ORACLE('');
+-----------+------------------+
| RTRIM('') | RTRIM_ORACLE('') |
+-----------+------------------+
|           | NULL             |
+-----------+------------------+

```

See Also
--------

 * [LTRIM](../ltrim/index) - leading spaces removed
* [TRIM](../trim/index) - removes all given prefixes or suffixes

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rtrim/>

SECOND
======

    Syntax
------

 
```
SECOND(time)

```

Description
-----------

 Returns the second for a given `time` (which can include [microseconds](../microseconds-in-mariadb/index)), in the range 0 to 59, or `NULL` if not given a valid time value.

 Examples
--------

 
```
SELECT SECOND('10:05:03');
+--------------------+
| SECOND('10:05:03') |
+--------------------+
|                  3 |
+--------------------+

SELECT SECOND('10:05:01.999999');
+---------------------------+
| SECOND('10:05:01.999999') |
+---------------------------+
|                         1 |
+---------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/second/>

SHA1
====

    Syntax
------

 
```
SHA1(str), SHA(str)

```

Description
-----------

 Calculates an SHA-1 160-bit checksum for the string *`str`*, as described in RFC 3174 (Secure Hash Algorithm).

 The value is returned as a string of 40 hex digits, or NULL if the argument was NULL. As of [MariaDB 5.5](../what-is-mariadb-55/index), the return value is a nonbinary string in the connection [character set and collation](../data-types-character-sets-and-collations/index), determined by the values of the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables. Before 5.5, the return value was a binary string.

 Examples
--------

 
```
SELECT SHA1('some boring text');
+------------------------------------------+
| SHA1('some boring text')                 |
+------------------------------------------+
| af969fc2085b1bb6d31e517d5c456def5cdd7093 |
+------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sha1/>

SHA2
====

    Syntax
------

 
```
SHA2(str,hash_len)

```

Description
-----------

 Given a string *`str`*, calculates an SHA-2 checksum, which is considered more cryptographically secure than its [SHA-1](../sha1/index) equivalent. The SHA-2 family includes SHA-224, SHA-256, SHA-384, and SHA-512, and the *`hash_len`* must correspond to one of these, i.e. 224, 256, 384 or 512. 0 is equivalent to 256.

 The return value is a nonbinary string in the connection [character set and collation](../data-types-character-sets-and-collations/index), determined by the values of the [character\_set\_connection](../server-system-variables/index#character_set_connection) and [collation\_connection](../server-system-variables/index#collation_connection) system variables. 

 NULL is returned if the hash length is not valid, or the string `str` is NULL.

 SHA2 will only work if MariaDB was has been configured with [TLS support](../secure-connections-overview/index). 

 Examples
--------

 
```
SELECT SHA2('Maria',224);
+----------------------------------------------------------+
| SHA2('Maria',224)                                        |
+----------------------------------------------------------+
| 6cc67add32286412efcab9d0e1675a43a5c2ef3cec8879f81516ff83 |
+----------------------------------------------------------+

SELECT SHA2('Maria',256);
+------------------------------------------------------------------+
| SHA2('Maria',256)                                                |
+------------------------------------------------------------------+
| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |
+------------------------------------------------------------------+

SELECT SHA2('Maria',0);
+------------------------------------------------------------------+
| SHA2('Maria',0)                                                  |
+------------------------------------------------------------------+
| 9ff18ebe7449349f358e3af0b57cf7a032c1c6b2272cb2656ff85eb112232f16 |
+------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sha2/>

SIN
===

    Syntax
------

 
```
SIN(X)

```

Description
-----------

 Returns the sine of X, where X is given in radians.

 Examples
--------

 
```
SELECT SIN(1.5707963267948966);
+-------------------------+
| SIN(1.5707963267948966) |
+-------------------------+
|                       1 |
+-------------------------+

SELECT SIN(PI());
+----------------------+
| SIN(PI())            |
+----------------------+
| 1.22460635382238e-16 |
+----------------------+

SELECT ROUND(SIN(PI()));
+------------------+
| ROUND(SIN(PI())) |
+------------------+
|                0 |
+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sin/>

SLEEP
=====

    Syntax
------

 
```
SLEEP(duration)

```

Description
-----------

 Sleeps (pauses) for the number of seconds given by the duration argument, then returns `0`. If `SLEEP()` is interrupted, it returns `1`. The duration may have a fractional part given in microseconds.

 Statements using the SLEEP() function are not [safe for replication](../unsafe-statements-for-replication/index).

 Example
-------

 
```
SELECT SLEEP(5.5);
+------------+
| SLEEP(5.5) |
+------------+
|          0 |
+------------+
1 row in set (5.50 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sleep/>

SOUNDEX
=======

    Syntax
------

 
```
SOUNDEX(str)

```

Description
-----------

 Returns a soundex string from *`str`*. Two strings that sound almost the same should have identical soundex strings. A standard soundex string is four characters long, but the `SOUNDEX()` function returns an arbitrarily long string. You can use `SUBSTRING()` on the result to get a standard soundex string. All non-alphabetic characters in *`str`* are ignored. All international alphabetic characters outside the A-Z range are treated as vowels.

 **Important:** When using SOUNDEX(), you should be aware of the following details:

 * This function, as currently implemented, is intended to work well with strings that are in the English language only. Strings in other languages may not produce reasonable results.

 * This function implements the original Soundex algorithm, not the more popular enhanced version (also described by D. Knuth). The difference is that original version discards vowels first and duplicates second, whereas the enhanced version discards duplicates first and vowels second.

 Examples
--------

 
```
SOUNDEX('Hello');
+------------------+
| SOUNDEX('Hello') |
+------------------+
| H400             |
+------------------+

```


```
SELECT SOUNDEX('MariaDB');
+--------------------+
| SOUNDEX('MariaDB') |
+--------------------+
| M631               |
+--------------------+

```


```
SELECT SOUNDEX('Knowledgebase');
+--------------------------+
| SOUNDEX('Knowledgebase') |
+--------------------------+
| K543212                  |
+--------------------------+

```


```
SELECT givenname, surname FROM users WHERE SOUNDEX(givenname) = SOUNDEX("robert");
+-----------+---------+
| givenname | surname |
+-----------+---------+
| Roberto   | Castro  |
+-----------+---------+

```

See Also
--------

 * [SOUNDS LIKE](../sounds-like/index)()

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/soundex/>

SOUNDS LIKE
===========

    Syntax
------

 
```
expr1 SOUNDS LIKE expr2

```

Description
-----------

 This is the same as `[SOUNDEX](../soundex/index)(expr1) = SOUNDEX(expr2)`.

 Example
-------

 
```
SELECT givenname, surname FROM users WHERE givenname SOUNDS LIKE "robert";
+-----------+---------+
| givenname | surname |
+-----------+---------+
| Roberto   | Castro  |
+-----------+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sounds-like/>

SPACE
=====

    Syntax
------

 
```
SPACE(N)

```

Description
-----------

 Returns a string consisting of *`N`* space characters. If `N` is NULL, returns NULL.

 Examples
--------

 
```
SELECT QUOTE(SPACE(6));
+-----------------+
| QUOTE(SPACE(6)) |
+-----------------+
| '      '        |
+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/space/>

SPIDER\_BG\_DIRECT\_SQL
=======================

    Syntax
------

 
```
SPIDER_BG_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

```

Description
-----------

 Executes the given SQL statement in the background on the remote server, as defined in the parameters listing. If the query returns a result-set, it sttores the results in the given temporary table. When the given SQL statement executes successfully, this function returns the number of called UDF's. It returns `0` when the given SQL statement fails.

 This function is a [UDF](../user-defined-functions/index) installed with the [Spider](../spider/index) storage engine.

 Examples
--------

 
```
SELECT SPIDER_BG_DIRECT_SQL('SELECT * FROM example_table',  '', 
   'srv "node1", port "8607"') AS "Direct Query";
+--------------+
| Direct Query | 
+--------------+
|            1 |
+--------------+

```

Parameters
----------

 #### `error_rw_mode`

 * **Description:** Returns empty results on network error.
	+ `0` : Return error on getting network error.
	+ `1`: Return 0 records on getting network error.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `erwm`

 See also
--------

 * [SPIDER\_DIRECT\_SQL](../spider_direct_sql/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider_bg_direct_sql/>

SPIDER\_COPY\_TABLES
====================

    Syntax
------

 
```
SPIDER_COPY_TABLES(spider_table_name, 
  source_link_id, destination_link_id_list [,parameters])

```

Description
-----------

 A [UDF](../user-defined-functions/index) installed with the [Spider Storage Engine](../spider/index), this function copies table data from `source_link_id` to `destination_link_id_list`. The service does not need to be stopped in order to copy.

 If the Spider table is partitioned, the name must be of the format `table_name#P#partition_name`. The partition name can be viewed in the `mysql.spider_tables` table, for example:

 
```
SELECT table_name FROM mysql.spider_tables;
+-------------+
| table_name  |
+-------------+
| spt_a#P#pt1 |
| spt_a#P#pt2 |
| spt_a#P#pt3 |
+-------------+

```

Returns `1` if the data was copied successfully, or `0` if copying the data failed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider_copy_tables/>

SETVAL
======

    
**MariaDB starting with [10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)**SEQUENCEs were introduced in [MariaDB 10.3](../what-is-mariadb-103/index).

 
Syntax
------

 
```
SETVAL(sequence_name, next_value, [is_used, [round]])

```
 Description
-----------

 Set the next value to be returned for a `SEQUENCE`.

 This function is compatible with PostgreSQL syntax, extended with the `round` argument.

 If the `is_used` argument is not given or is `1` or `true`, then the next used value will one after the given value. If `is_used` is `0` or `false` then the next generated value will be the given value.

 If `round` is used then it will set the `round` value (or the internal cycle count, starting at zero) for the sequence. If `round` is not used, it's assumed to be 0.

 `next_value` must be an integer literal.

 For `SEQUENCE` tables defined with `CYCLE` (see [CREATE SEQUENCE](../create-sequence/index)) one should use both `next_value` and `round` to define the next value. In this case the current sequence value is defined to be `round`, `next_value`.

 The result returned by `SETVAL()` is `next_value` or NULL if the given `next_value` and `round` is smaller than the current value.

 `SETVAL()` will not set the `SEQUENCE` value to a something that is less than its current value. This is needed to ensure that `SETVAL()` is replication safe. If you want to set the SEQUENCE to a smaller number use [ALTER SEQUENCE](../alter-sequence/index).

 If `CYCLE` is used, first `round` and then `next_value` are compared to see if the value is bigger than the current value.

 Internally, in the MariaDB server, `SETVAL()` is used to inform slaves that a `SEQUENCE` has changed value. The slave may get `SETVAL()` statements out of order, but this is ok as only the biggest one will have an effect.

 `SETVAL` requires the [INSERT privilege](../grant/index).

 Examples
--------

 
```
SELECT setval(foo, 42);           -- Next nextval will return 43
SELECT setval(foo, 42, true);     -- Same as above
SELECT setval(foo, 42, false);    -- Next nextval will return 42

```

SETVAL setting higher and lower values on a sequence with an increment of 10:

 
```
SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|         50 |
+------------+

SELECT SETVAL(s, 100);
+----------------+
| SETVAL(s, 100) |
+----------------+
|            100 |
+----------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        110 |
+------------+

SELECT SETVAL(s, 50);
+---------------+
| SETVAL(s, 50) |
+---------------+
|          NULL |
+---------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        120 |
+------------+

```

Example demonstrating `round`:

 
```
CREATE OR REPLACE SEQUENCE s1
  START WITH 1
  MINVALUE 1
  MAXVALUE 99
  INCREMENT BY 1 
  CACHE 20 
  CYCLE;

SELECT SETVAL(s1, 99, 1, 0);
+----------------------+
| SETVAL(s1, 99, 1, 0) |
+----------------------+
|                   99 |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           1 |
+-------------+

```

The following statement returns NULL, as the given `next_value` and `round` is smaller than the current value.

 
```
SELECT SETVAL(s1, 99, 1, 0);
+----------------------+
| SETVAL(s1, 99, 1, 0) |
+----------------------+
|                 NULL |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           2 |
+-------------+

```

Increasing the round from zero to 1 will allow `next_value` to be returned.

 
```
SELECT SETVAL(s1, 99, 1, 1);
+----------------------+
| SETVAL(s1, 99, 1, 1) |
+----------------------+
|                   99 |
+----------------------+

SELECT NEXTVAL(s1);
+-------------+
| NEXTVAL(s1) |
+-------------+
|           1 |
+-------------+

```

See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [NEXT VALUE FOR](../next-value-for-sequence_name/index)
* [PREVIOUS VALUE FOR](../previous-value-for-sequence_name/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setval/>

SIGN
====

    Syntax
------

 
```
SIGN(X)

```

Description
-----------

 Returns the sign of the argument as -1, 0, or 1, depending on whether X is negative, zero, or positive.

 Examples
--------

 
```
SELECT SIGN(-32);
+-----------+
| SIGN(-32) |
+-----------+
|        -1 |
+-----------+

SELECT SIGN(0);
+---------+
| SIGN(0) |
+---------+
|       0 |
+---------+

SELECT SIGN(234);
+-----------+
| SIGN(234) |
+-----------+
|         1 |
+-----------+

```

See Also
--------

 * [ABS()](../abs/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sign/>

SQRT
====

    Syntax
------

 
```
SQRT(X)

```

Description
-----------

 Returns the square root of X. If X is negative, NULL is returned.

 Examples
--------

 
```
SELECT SQRT(4);
+---------+
| SQRT(4) |
+---------+
|       2 |
+---------+

SELECT SQRT(20);
+------------------+
| SQRT(20)         |
+------------------+
| 4.47213595499958 |
+------------------+

SELECT SQRT(-16);
+-----------+
| SQRT(-16) |
+-----------+
|      NULL |
+-----------+

SELECT SQRT(1764);
+------------+
| SQRT(1764) |
+------------+
|         42 |
+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sqrt/>

SPIDER\_FLUSH\_TABLE\_MON\_CACHE
================================

    Syntax
------

 
```
SPIDER_FLUSH_TABLE_MON_CACHE()

```

Description
-----------

 A [UDF](../user-defined-functions/index) installed with the [Spider Storage Engine](../spider/index), this function is used for refreshing monitoring server information. It returns a value of `1`.

 Examples
--------

 
```
SELECT SPIDER_FLUSH_TABLE_MON_CACHE();
+--------------------------------+
| SPIDER_FLUSH_TABLE_MON_CACHE() |
+--------------------------------+
|                              1 |
+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider_flush_table_mon_cache/>

SPIDER\_DIRECT\_SQL
===================

    Syntax
------

 
```
SPIDER_DIRECT_SQL('sql', 'tmp_table_list', 'parameters')

```

Description
-----------

 A [UDF](../user-defined-functions/index) installed with the [Spider Storage Engine](../spider/index), this function is used to execute the SQL string `sql` on the remote server, as defined in `parameters`. If any resultsets are returned, they are stored in the `tmp_table_list`.

 The function returns `1` if the SQL executes successfully, or `0` if it fails.

 Examples
--------

 
```
SELECT SPIDER_DIRECT_SQL('SELECT * FROM s', '', 'srv "node1", port "8607"');
+----------------------------------------------------------------------+
| SPIDER_DIRECT_SQL('SELECT * FROM s', '', 'srv "node1", port "8607"') |
+----------------------------------------------------------------------+
|                                                                    1 |
+----------------------------------------------------------------------+

```

See also
--------

 * [SPIDER\_BG\_DIRECT\_SQL](../spider_bg_direct_sql/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider_direct_sql/>

ST\_SRID
========

    Syntax
------

 
```
ST_SRID(g)
SRID(g)

```

Description
-----------

 Returns an integer indicating the Spatial Reference System ID for the geometry value g.

 In MariaDB, the SRID value is just an integer associated with the geometry value. All calculations are done assuming Euclidean (planar) geometry.

 `ST_SRID()` and `SRID()` are synonyms.

 Examples
--------

 
```
SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
+-----------------------------------------------+
| SRID(GeomFromText('LineString(1 1,2 2)',101)) |
+-----------------------------------------------+
|                                           101 |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/srid/>

ST\_AsWKB
=========

    A synonym for [ST\_AsBinary()](../st_asbinary/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_aswkb/>

ST\_BUFFER
==========

    Syntax
------

 
```
ST_BUFFER(g1,r)
BUFFER(g1,r)

```

Description
-----------

 Returns a geometry that represents all points whose distance from geometry *`g1`* is less than or equal to distance, or radius, *`r`*.

 Uses for this function could include creating for example a new geometry representing a buffer zone around an island.

 BUFFER() is a synonym.

 Examples
--------

 Determining whether a point is within a buffer zone:

 
```
SET @g1 = ST_GEOMFROMTEXT('POLYGON((10 10, 10 20, 20 20, 20 10, 10 10))');

SET @g2 = ST_GEOMFROMTEXT('POINT(8 8)');

SELECT ST_WITHIN(@g2,ST_BUFFER(@g1,5));
+---------------------------------+
| ST_WITHIN(@g2,ST_BUFFER(@g1,5)) |
+---------------------------------+
|                               1 |
+---------------------------------+

SELECT ST_WITHIN(@g2,ST_BUFFER(@g1,1));
+---------------------------------+
| ST_WITHIN(@g2,ST_BUFFER(@g1,1)) |
+---------------------------------+
|                               0 |
+---------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_buffer/>

ST\_CENTROID
============

    Syntax
------

 
```
ST_Centroid(mpoly)
Centroid(mpoly)

```

Description
-----------

 Returns a point reflecting the mathematical centroid (geometric center) for the [MultiPolygon](../multipolygon/index) *mpoly*. The resulting point will not necessarily be on the MultiPolygon. 

 `ST_Centroid()` and `Centroid()` are synonyms.

 Examples
--------

 
```
SET @poly = ST_GeomFromText('POLYGON((0 0,20 0,20 20,0 20,0 0))');
SELECT ST_AsText(ST_Centroid(@poly)) AS center;
+--------------+
| center       |
+--------------+
| POINT(10 10) |
+--------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_centroid/>

ST\_CONVEXHULL
==============

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**ST\_ConvexHull() was introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
Syntax
------

 
```
ST_ConvexHull(g)
ConvexHull(g)

```

Description
-----------

 Given a geometry, returns a geometry that is the minimum convex geometry enclosing all geometries within the set. Returns NULL if the geometry value is NULL or an empty value.

 ST\_ConvexHull() and ConvexHull() are synonyms.

 Examples
--------

 The ConvexHull of a single point is simply the single point:

 
```
SET @g = ST_GEOMFROMTEXT('Point(0 0)');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g)) |
+------------------------------+
| POINT(0 0)                   |
+------------------------------+

```


```
SET @g = ST_GEOMFROMTEXT('MultiPoint(0 0, 1 2, 2 3)');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g)) |
+------------------------------+
| POLYGON((0 0,1 2,2 3,0 0))   |
+------------------------------+

```


```
SET @g = ST_GEOMFROMTEXT('MultiPoint( 1 1, 2 2, 5 3, 7 2, 9 3, 8 4, 6 6, 6 9, 4 9, 1 5 )');

SELECT ST_ASTEXT(ST_CONVEXHULL(@g));
+----------------------------------------+
| ST_ASTEXT(ST_CONVEXHULL(@g))           |
+----------------------------------------+
| POLYGON((1 1,1 5,4 9,6 9,9 3,7 2,1 1)) |
+----------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_convexhull/>

ST\_DIMENSION
=============

    Syntax
------

 
```
ST_Dimension(g)
Dimension(g)

```

Description
-----------

 Returns the inherent dimension of the geometry value *`g`*. The result can be

 


| Dimension | Definition |
| --- | --- |
|  `-1` | empty geometry |
|  `0` | geometry with no length or area |
|  `1` | geometry with no area but nonzero length |
|  `2` | geometry with nonzero area |

 
`ST_Dimension()` and `Dimension()` are synonyms.

 Examples
--------

 
```
SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
+------------------------------------------------+
| Dimension(GeomFromText('LineString(1 1,2 2)')) |
+------------------------------------------------+
|                                              1 |
+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_dimension/>

ST\_DIFFERENCE
==============

    Syntax
------

 
```
ST_DIFFERENCE(g1,g2)

```

Description
-----------

 Returns a geometry representing the point set difference of the given geometry values.

 Example
-------

 
```
SET @g1 = POINT(10,10), @g2 = POINT(20,20);

SELECT ST_AsText(ST_Difference(@g1, @g2));
+------------------------------------+
| ST_AsText(ST_Difference(@g1, @g2)) |
+------------------------------------+
| POINT(10 10)                       |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_difference/>

ST\_DISTANCE\_SPHERE
====================

    
**MariaDB starting with [10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/)**`ST_DISTANCE_SPHERE` was introduced in [MariaDB 10.2.38](https://mariadb.com/kb/en/mariadb-10238-release-notes/), [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/) and [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/). 

 
Syntax
------

 
```
ST_DISTANCE_SPHERE(g1,g2,[r])

```

Description
-----------

 Returns the spherical distance between two geometries (point or multipoint) on a sphere with the optional radius *r* (default is the Earth radius if *r* is not specified), or NULL if not given valid inputs.

 Example
-------

 
```
set @zenica   = ST_GeomFromText('POINT(17.907743 44.203438)');
set @sarajevo = ST_GeomFromText('POINT(18.413076 43.856258)');
SELECT ST_Distance_Sphere(@zenica, @sarajevo);
55878.59337591705

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_distance_sphere/>

ST\_CONTAINS
============

    Syntax
------

 
```
ST_CONTAINS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether a geometry `g1` completely contains geometry `g2`.

 ST\_CONTAINS() uses object shapes, while [CONTAINS()](../contains/index), based on the original MySQL implementation, uses object bounding rectangles.

 ST\_CONTAINS tests the opposite relationship to [ST\_WITHIN()](../st_within/index).

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))');

SET @g2 = ST_GEOMFROMTEXT('POINT(174 149)');

SELECT ST_CONTAINS(@g1,@g2);
+----------------------+
| ST_CONTAINS(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g2 = ST_GEOMFROMTEXT('POINT(175 151)');

SELECT ST_CONTAINS(@g1,@g2);
+----------------------+
| ST_CONTAINS(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_contains/>

ST\_DISJOINT
============

    Syntax
------

 
```
ST_DISJOINT(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* is spatially disjoint from (does not intersect with) geometry *`g2`*.

 ST\_DISJOINT() uses object shapes, while [DISJOINT()](../disjoint/index), based on the original MySQL implementation, uses object bounding rectangles.

 ST\_DISJOINT() tests the opposite relationship to [ST\_INTERSECTS()](../st_intersects/index).

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POINT(0 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_DISJOINT(@g1,@g2);
+----------------------+
| ST_DISJOINT(@g1,@g2) |
+----------------------+
|                    1 |
+----------------------+

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(0 0, 0 2)');

SELECT ST_DISJOINT(@g1,@g2);
+----------------------+
| ST_DISJOINT(@g1,@g2) |
+----------------------+
|                    0 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_disjoint/>

ST\_DISTANCE
============

    Syntax
------

 
```
ST_DISTANCE(g1,g2)

```

Description
-----------

 Returns the distance between two geometries, or null if not given valid inputs.

 Example
-------

 
```
SELECT ST_Distance(POINT(1,2),POINT(2,2));
+------------------------------------+
| ST_Distance(POINT(1,2),POINT(2,2)) |
+------------------------------------+
|                                  1 |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_distance/>

ST\_GeometryFromText
====================

    A synonym for [ST\_GeomFromText](../st_geomfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_geometryfromtext/>

ST\_GeometryCollectionFromText
==============================

    A synonym for [ST\_GeomCollFromText](../st_geomcollfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_geometrycollectionfromtext/>

ST\_GeometryFromWKB
===================

    A synonym for [ST\_GeomFromWKB](../st_geomfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_geometryfromwkb/>

ST\_GeometryCollectionFromWKB
=============================

    A synonym for [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_geometrycollectionfromwkb/>

ST\_EQUALS
==========

    Syntax
------

 
```
ST_EQUALS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* is spatially equal to geometry *`g2`*.

 ST\_EQUALS() uses object shapes, while [EQUALS()](../equals/index), based on the original MySQL implementation, uses object bounding rectangles.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('LINESTRING(174 149, 176 151)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(176 151, 174 149)');

SELECT ST_EQUALS(@g1,@g2);
+--------------------+
| ST_EQUALS(@g1,@g2) |
+--------------------+
|                  1 |
+--------------------+

```


```
SET @g1 = ST_GEOMFROMTEXT('POINT(0 2)');

SET @g1 = ST_GEOMFROMTEXT('POINT(2 0)');

SELECT ST_EQUALS(@g1,@g2);
+--------------------+
| ST_EQUALS(@g1,@g2) |
+--------------------+
|                  0 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_equals/>

ST\_CROSSES
===========

    Syntax
------

 
```
ST_CROSSES(g1,g2)

```

Description
-----------

 Returns `1` if geometry *`g1`* spatially crosses geometry *`g2`*. Returns `NULL` if `g1` is a [Polygon](../polygon/index) or a [MultiPolygon](../multipolygon/index), or if `g2` is a [Point](../point/index) or a [MultiPoint](../multipoint/index). Otherwise, returns `0`.

 The term spatially crosses denotes a spatial relation between two given geometries that has the following properties:

 * The two geometries intersect
* Their intersection results in a geometry that has a dimension that is one less than the maximum dimension of the two given geometries
* Their intersection is not equal to either of the two given geometries

 ST\_CROSSES() uses object shapes, while [CROSSES()](../crosses/index), based on the original MySQL implementation, uses object bounding rectangles.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('LINESTRING(174 149, 176 151)');

SET @g2 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))');

SELECT ST_CROSSES(@g1,@g2);
+---------------------+
| ST_CROSSES(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = ST_GEOMFROMTEXT('LINESTRING(176 149, 176 151)');

SELECT ST_CROSSES(@g1,@g2);
+---------------------+
| ST_CROSSES(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_crosses/>

ST\_INTERSECTION
================

    Syntax
------

 
```
ST_INTERSECTION(g1,g2)

```

Description
-----------

 Returns a geometry that is the intersection, or shared portion, of geometry *`g1`* and geometry *`g2`*.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POINT(2 1)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 1, 0 2)');

SELECT ASTEXT(ST_INTERSECTION(@g1,@g2));
+----------------------------------+
| ASTEXT(ST_INTERSECTION(@g1,@g2)) |
+----------------------------------+
| POINT(2 1)                       |
+----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_intersection/>

ST\_IsSimple
============

    Syntax
------

 
```
ST_IsSimple(g)
IsSimple(g)

```

Description
-----------

 Returns true if the given Geometry has no anomalous geometric points, false if it does, or NULL if given a NULL value.

 ST\_IsSimple() and IsSimple() are synonyms.

 Examples
--------

 A POINT is always simple.

 
```
SET @g = 'Point(1 2)';

SELECT ST_ISSIMPLE(GEOMFROMTEXT(@g));
+-------------------------------+
| ST_ISSIMPLE(GEOMFROMTEXT(@g)) |
+-------------------------------+
|                             1 |
+-------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_issimple/>

ST\_ISCLOSED
============

    Syntax
------

 
```
ST_IsClosed(g)
IsClosed(g)

```

Description
-----------

 Returns 1 if a given [LINESTRING's](../linestring/index) start and end points are the same, or 0 if they are not the same. Before [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), returns NULL if not given a LINESTRING. After [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), returns -1.

 `ST_IsClosed()` and `IsClosed()` are synonyms.

 Examples
--------

 
```
SET @ls = 'LineString(0 0, 0 4, 4 4, 0 0)';
SELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));
+--------------------------------+
| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |
+--------------------------------+
|                              1 |
+--------------------------------+

SET @ls = 'LineString(0 0, 0 4, 4 4, 0 1)';
SELECT ST_ISCLOSED(GEOMFROMTEXT(@ls));
+--------------------------------+
| ST_ISCLOSED(GEOMFROMTEXT(@ls)) |
+--------------------------------+
|                              0 |
+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_isclosed/>

ST\_LENGTH
==========

    Syntax
------

 
```
ST_LENGTH(ls)

```

Description
-----------

 Returns as a double-precision number the length of the [LineString](../linestring/index) value *`ls`* in its associated spatial reference.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT ST_LENGTH(ST_GeomFromText(@ls));
+---------------------------------+
| ST_LENGTH(ST_GeomFromText(@ls)) |
+---------------------------------+
|                2.82842712474619 |
+---------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_length/>

ST\_IsRing
==========

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**The ST\_IsRing function was introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
Syntax
------

 
```
ST_IsRing(g)
IsRing(g)

```

Description
-----------

 Returns true if a given [LINESTRING](../linestring/index) is a ring, that is, both [ST\_IsClosed](../st_isclosed/index) and [ST\_IsSimple](../st_issimple/index). A simple curve does not pass through the same point more than once. However, see [MDEV-7510](https://jira.mariadb.org/browse/MDEV-7510).

 `St_IsRing()` and `IsRing()` are synonyms.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_isring/>

ST\_LineStringFromWKB
=====================

    A synonym for [ST\_LineFromWKB](../st_linefromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_linestringfromwkb/>

ST\_LineStringFromText
======================

    A synonym for [ST\_LineFromText](../st_linefromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_linestringfromtext/>

ST\_INTERSECTS
==============

    Syntax
------

 
```
ST_INTERSECTS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* spatially intersects geometry *`g2`*.

 ST\_INTERSECTS() uses object shapes, while [INTERSECTS()](../intersects/index), based on the original MySQL implementation, uses object bounding rectangles.

 ST\_INTERSECTS() tests the opposite relationship to [ST\_DISJOINT()](../st_disjoint/index).

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POINT(0 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(0 0, 0 2)');

SELECT ST_INTERSECTS(@g1,@g2);
+------------------------+
| ST_INTERSECTS(@g1,@g2) |
+------------------------+
|                      1 |
+------------------------+

```


```
SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_INTERSECTS(@g1,@g2);
+------------------------+
| ST_INTERSECTS(@g1,@g2) |
+------------------------+
|                      0 |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_intersects/>

ST\_POINTONSURFACE
==================

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**ST\_POINTONSURFACE() was introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
Syntax
------

 
```
ST_PointOnSurface(g)
PointOnSurface(g)

```

Description
-----------

 Given a geometry, returns a [POINT](../point/index) guaranteed to intersect a surface. However, see [MDEV-7514](https://jira.mariadb.org/browse/MDEV-7514).

 ST\_PointOnSurface() and PointOnSurface() are synonyms.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_pointonsurface/>

ST\_OVERLAPS
============

    Syntax
------

 
```
ST_OVERLAPS(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* spatially overlaps geometry *`g2`*.

 The term spatially overlaps is used if two geometries intersect and their intersection results in a geometry of the same dimension but not equal to either of the given geometries.

 ST\_OVERLAPS() uses object shapes, while [OVERLAPS()](../overlaps/index), based on the original MySQL implementation, uses object bounding rectangles.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_overlaps/>

ST\_STARTPOINT
==============

    Syntax
------

 
```
ST_StartPoint(ls)
StartPoint(ls)

```

Description
-----------

 Returns the [Point](../point/index) that is the start point of the [LineString](../linestring/index) value `ls`.

 `ST_StartPoint()` and `StartPoint()` are synonyms.

 Examples
--------

 
```
SET @ls = 'LineString(1 1,2 2,3 3)';

SELECT AsText(StartPoint(GeomFromText(@ls)));
+---------------------------------------+
| AsText(StartPoint(GeomFromText(@ls))) |
+---------------------------------------+
| POINT(1 1)                            |
+---------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_startpoint/>

ST\_PolygonFromWKB
==================

    A synonym for [ST\_PolyFromWKB](../st_polyfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_polygonfromwkb/>

ST\_SYMDIFFERENCE
=================

    Syntax
------

 
```
ST_SYMDIFFERENCE(g1,g2)

```

Description
-----------

 Returns a geometry that represents the portions of geometry *`g1`* and geometry *`g2`* that don't intersect.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('LINESTRING(10 20, 10 40)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(10 15, 10 25)');

SELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));
+----------------------------------------------+
| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2))            |
+----------------------------------------------+
| MULTILINESTRING((10 15,10 20),(10 25,10 40)) |
+----------------------------------------------+

SET @g2 = ST_GeomFromText('LINESTRING(10 20, 10 41)');

SELECT ASTEXT(ST_SYMDIFFERENCE(@g1,@g2));
+-----------------------------------+
| ASTEXT(ST_SYMDIFFERENCE(@g1,@g2)) |
+-----------------------------------+
| LINESTRING(10 40,10 41)           |
+-----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_symdifference/>

ST\_PolygonFromText
===================

    A synonym for [ST\_PolyFromText](../st_polyfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_polygonfromtext/>

ST\_RELATE
==========

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**The ST\_RELATE() function was introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
Syntax
------

 
```
ST_Relate(g1, g2, i)

```

Description
-----------

 Returns true if Geometry `g1` is spatially related to Geometry`g2` by testing for intersections between the interior, boundary and exterior of the two geometries as specified by the values in intersection matrix pattern `i`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_relate/>

ST\_X
=====

    Syntax
------

 
```
ST_X(p)
X(p)

```

Description
-----------

 Returns the X-coordinate value for the point `p` as a double-precision number.

 `ST_X()` and `X()` are synonyms.

 Examples
--------

 
```
SET @pt = 'Point(56.7 53.34)';

SELECT X(GeomFromText(@pt));
+----------------------+
| X(GeomFromText(@pt)) |
+----------------------+
|                 56.7 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_x/>

ST\_Y
=====

    Syntax
------

 
```
ST_Y(p)
Y(p)

```

Description
-----------

 Returns the Y-coordinate value for the point p as a double-precision number.

 `ST_Y()` and `Y()` are synonyms.

 Examples
--------

 
```
SET @pt = 'Point(56.7 53.34)';

SELECT Y(GeomFromText(@pt));
+----------------------+
| Y(GeomFromText(@pt)) |
+----------------------+
|                53.34 |
+----------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_y/>

ST\_UNION
=========

    Syntax
------

 
```
ST_UNION(g1,g2)

```

Description
-----------

 Returns a geometry that is the union of the geometry *`g1`* and geometry *`g2`*.

 Examples
--------

 
```
SET @g1 = GEOMFROMTEXT('POINT (0 2)');

SET @g2 = GEOMFROMTEXT('POINT (2 0)');

SELECT ASTEXT(ST_UNION(@g1,@g2));
+---------------------------+
| ASTEXT(ST_UNION(@g1,@g2)) |
+---------------------------+
| MULTIPOINT(2 0,0 2)       |
+---------------------------+

```


```
SET @g1 = GEOMFROMTEXT('POLYGON((0 0,0 3,3 3,3 0,0 0))');

SET @g2 = GEOMFROMTEXT('POLYGON((2 2,4 2,4 4,2 4,2 2))');

SELECT ASTEXT(ST_UNION(@g1,@g2));
+------------------------------------------------+
| ASTEXT(ST_UNION(@g1,@g2))                      |
+------------------------------------------------+
| POLYGON((0 0,0 3,2 3,2 4,4 4,4 2,3 2,3 0,0 0)) |
+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_union/>

STD
===

    Syntax
------

 
```
STD(expr)

```

Description
-----------

 Returns the population standard deviation of *`expr`*. This is an extension to standard SQL. The standard SQL function `[STDDEV\_POP()](../stddev_pop/index)` can be used instead. 

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 STD() can be used as a [window function](../window-functions/index).

 This function returns `NULL` if there were no matching rows.

 Examples
--------

 As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
  OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

```

See Also
--------

 * [STDDEV\_POP](../stddev_pop/index) (equivalent, standard SQL)
* [STDDEV](../stddev/index) (equivalent, Oracle-compatible non-standard SQL)
* [VAR\_POP](../var_pop/index) (variance)
* [STDDEV\_SAMP](../stddev_samp/index) (sample standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/std/>

STDDEV\_SAMP
============

    Syntax
------

 
```
STDDEV_SAMP(expr)

```

Description
-----------

 Returns the sample standard deviation of `expr` (the square root of [VAR\_SAMP()](../var_samp/index)).

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 STDDEV\_SAMP() can be used as a [window function](../window-functions/index).

 STDDEV\_SAMP() returns `NULL` if there were no matching rows.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stddev_samp/>

STRCMP
======

    Syntax
------

 
```
STRCMP(expr1,expr2)

```

Description
-----------

 `STRCMP()` returns `0` if the strings are the same, `-1` if the first argument is smaller than the second according to the current sort order, and `1` if the strings are otherwise not the same. Returns `NULL` is either argument is `NULL`.

 Examples
--------

 
```
SELECT STRCMP('text', 'text2');
+-------------------------+
| STRCMP('text', 'text2') |
+-------------------------+
|                      -1 |
+-------------------------+

SELECT STRCMP('text2', 'text');
+-------------------------+
| STRCMP('text2', 'text') |
+-------------------------+
|                       1 |
+-------------------------+

SELECT STRCMP('text', 'text');
+------------------------+
| STRCMP('text', 'text') |
+------------------------+
|                      0 |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/strcmp/>

STR\_TO\_DATE
=============

    Syntax
------

 
```
STR_TO_DATE(str,format)

```
 Description
-----------

 This is the inverse of the [DATE\_FORMAT](../date_format/index)() function. It takes a string `str` and a format string `format`. `STR_TO_DATE()` returns a `DATETIME` value if the format string contains both date and time parts, or a `DATE` or `TIME` value if the string contains only date or time parts.

 The date, time, or datetime values contained in `str` should be given in the format indicated by format. If str contains an illegal date, time, or datetime value, `STR_TO_DATE()` returns `NULL`. An illegal value also produces a warning.

 Under specific [SQL\_MODE](../sql-mode/index) settings an error may also be generated if the `str` isn't a valid date:

 * [ALLOW\_INVALID\_DATES](../sql-mode/index#allow_invalid_dates)
* [NO\_ZERO\_DATE](../sql-mode/index#no_zero_date)
* [NO\_ZERO\_IN\_DATE](../sql-mode/index#no_zero_in_date)

 The options that can be used by STR\_TO\_DATE(), as well as its inverse [DATE\_FORMAT()](../date_format/index) and the [FROM\_UNIXTIME()](../from_unixtime/index) function, are:

 


| Option | Description |
| --- | --- |
| `%a` | Short weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%b` | Short form month name in current locale. For locale en\_US this is one of: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov or Dec. |
| `%c` | Month with 1 or 2 digits. |
| `%D` | Day with English suffix 'th', 'nd', 'st' or 'rd''. (1st, 2nd, 3rd...). |
| `%d` | Day with 2 digits. |
| `%e` | Day with 1 or 2 digits. |
| `%f` | [Microseconds](../microseconds-in-mariadb/index) 6 digits. |
| `%H` | Hour with 2 digits between 00-23. |
| `%h` | Hour with 2 digits between 01-12. |
| `%I` | Hour with 2 digits between 01-12. |
| `%i` | Minute with 2 digits. |
| `%j` | Day of the year (001-366) |
| `%k` | Hour with 1 digits between 0-23. |
| `%l` | Hour with 1 digits between 1-12. |
| `%M` | Full month name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%m` | Month with 2 digits. |
| `%p` | AM/PM according to current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%r` | Time in 12 hour format, followed by AM/PM. Short for '%I:%i:%S %p'. |
| `%S` | Seconds with 2 digits. |
| `%s` | Seconds with 2 digits. |
| `%T` | Time in 24 hour format. Short for '%H:%i:%S'. |
| `%U` | Week number (00-53), when first day of the week is Sunday. |
| `%u` | Week number (00-53), when first day of the week is Monday. |
| `%V` | Week number (01-53), when first day of the week is Sunday. Used with %X. |
| `%v` | Week number (01-53), when first day of the week is Monday. Used with %x. |
| `%W` | Full weekday name in current locale (Variable [lc\_time\_names](../server-system-variables/index#lc_time_names)). |
| `%w` | Day of the week. 0 = Sunday, 6 = Saturday. |
| `%X` | Year with 4 digits when first day of the week is Sunday. Used with %V. |
| `%x` | Year with 4 digits when first day of the week is Monday. Used with %v. |
| `%Y` | Year with 4 digits. |
| `%y` | Year with 2 digits. |
| `%#` | For [str\_to\_date](index)(), skip all numbers. |
| `%.` | For [str\_to\_date](index)(), skip all punctation characters. |
| `%@` | For [str\_to\_date](index)(), skip all alpha characters. |
| `%%` | A literal `%` character. |

 
Examples
--------

 
```
SELECT STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y');
+---------------------------------------------------------+
| STR_TO_DATE('Wednesday, June 2, 2014', '%W, %M %e, %Y') |
+---------------------------------------------------------+
| 2014-06-02                                              |
+---------------------------------------------------------+


SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y');
+--------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W, %M %e, %Y') |
+--------------------------------------------------------------+
| NULL                                                         |
+--------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------------------+
| Level   | Code | Message                                                                           |
+---------+------+-----------------------------------------------------------------------------------+
| Warning | 1411 | Incorrect datetime value: 'Wednesday23423, June 2, 2014' for function str_to_date |
+---------+------+-----------------------------------------------------------------------------------+

SELECT STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y');
+----------------------------------------------------------------+
| STR_TO_DATE('Wednesday23423, June 2, 2014', '%W%#, %M %e, %Y') |
+----------------------------------------------------------------+
| 2014-06-02                                                     |
+----------------------------------------------------------------+

```

See Also
--------

 * [DATE\_FORMAT()](../date_format/index)
* [FROM\_UNIXTIME()](../from_unixtime/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/str_to_date/>

SUBDATE
=======

    Syntax
------

 
```
SUBDATE(date,INTERVAL expr unit), SUBDATE(expr,days)

```

Description
-----------

 When invoked with the `INTERVAL` form of the second argument, `SUBDATE()` is a synonym for `[DATE\_SUB()](../date_sub/index)`. See [Date and Time Units](../date-and-time-units/index) for a complete list of permitted units. 

 The second form allows the use of an integer value for days. In such cases, it is interpreted as the number of days to be subtracted from the date or datetime expression expr.

 Examples
--------

 
```
SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_SUB('2008-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 2007-12-02                              |
+-----------------------------------------+

SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
+----------------------------------------+
| SUBDATE('2008-01-02', INTERVAL 31 DAY) |
+----------------------------------------+
| 2007-12-02                             |
+----------------------------------------+

```


```
SELECT SUBDATE('2008-01-02 12:00:00', 31);
+------------------------------------+
| SUBDATE('2008-01-02 12:00:00', 31) |
+------------------------------------+
| 2007-12-02 12:00:00                |
+------------------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d, SUBDATE(d, 10) from t1;
+---------------------+---------------------+
| d                   | SUBDATE(d, 10)      |
+---------------------+---------------------+
| 2007-01-30 21:31:07 | 2007-01-20 21:31:07 |
| 1983-10-15 06:42:51 | 1983-10-05 06:42:51 |
| 2011-04-21 12:34:56 | 2011-04-11 12:34:56 |
| 2011-10-30 06:31:41 | 2011-10-20 06:31:41 |
| 2011-01-30 14:03:25 | 2011-01-20 14:03:25 |
| 2004-10-07 11:19:34 | 2004-09-27 11:19:34 |
+---------------------+---------------------+

SELECT d, SUBDATE(d, INTERVAL 10 MINUTE) from t1;
+---------------------+--------------------------------+
| d                   | SUBDATE(d, INTERVAL 10 MINUTE) |
+---------------------+--------------------------------+
| 2007-01-30 21:31:07 | 2007-01-30 21:21:07            |
| 1983-10-15 06:42:51 | 1983-10-15 06:32:51            |
| 2011-04-21 12:34:56 | 2011-04-21 12:24:56            |
| 2011-10-30 06:31:41 | 2011-10-30 06:21:41            |
| 2011-01-30 14:03:25 | 2011-01-30 13:53:25            |
| 2004-10-07 11:19:34 | 2004-10-07 11:09:34            |
+---------------------+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subdate/>

ST\_WITHIN
==========

    Syntax
------

 
```
ST_WITHIN(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* is spatially within geometry *`g2`*.

 This tests the opposite relationship as `[ST\_CONTAINS()](../st_contains/index)`.

 ST\_WITHIN() uses object shapes, while [WITHIN()](../within/index), based on the original MySQL implementation, uses object bounding rectangles.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POINT(174 149)');

SET @g2 = ST_GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))');

SELECT ST_WITHIN(@g1,@g2);
+--------------------+
| ST_WITHIN(@g1,@g2) |
+--------------------+
|                  1 |
+--------------------+

SET @g1 = ST_GEOMFROMTEXT('POINT(176 151)');

SELECT ST_WITHIN(@g1,@g2);
+--------------------+
| ST_WITHIN(@g1,@g2) |
+--------------------+
|                  0 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_within/>

ST\_TOUCHES
===========

    Syntax
------

 
```
ST_TOUCHES(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether geometry *`g1`* spatially touches geometry *`g2`*. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.

 ST\_TOUCHES() uses object shapes, while [TOUCHES()](../touches/index), based on the original MySQL implementation, uses object bounding rectangles.

 Examples
--------

 
```
SET @g1 = ST_GEOMFROMTEXT('POINT(2 0)');

SET @g2 = ST_GEOMFROMTEXT('LINESTRING(2 0, 0 2)');

SELECT ST_TOUCHES(@g1,@g2);
+---------------------+
| ST_TOUCHES(@g1,@g2) |
+---------------------+
|                   1 |
+---------------------+

SET @g1 = ST_GEOMFROMTEXT('POINT(2 1)');

SELECT ST_TOUCHES(@g1,@g2);
+---------------------+
| ST_TOUCHES(@g1,@g2) |
+---------------------+
|                   0 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_touches/>

SUBSTRING
=========

    Syntax
------

 
```
SUBSTRING(str,pos), 
SUBSTRING(str FROM pos), 
SUBSTRING(str,pos,len),
SUBSTRING(str FROM pos FOR len)

SUBSTR(str,pos), 
SUBSTR(str FROM pos), 
SUBSTR(str,pos,len),
SUBSTR(str FROM pos FOR len)

```
 Description
-----------

 The forms without a *`len`* argument return a substring from string *`str`* starting at position *`pos`*.

 The forms with a *`len`* argument return a substring *`len`* characters long from string *`str`*, starting at position *`pos`*.

 The forms that use *`FROM`* are standard SQL syntax.

 It is also possible to use a negative value for *`pos`*. In this case, the beginning of the substring is *`pos`* characters from the end of the string, rather than the beginning. A negative value may be used for *`pos`* in any of the forms of this function.

 By default, the position of the first character in the string from which the substring is to be extracted is reckoned as 1. For [Oracle-compatibility](../sql_modeoracle-from-mariadb-103/index), from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), when sql\_mode is set to 'oracle', position zero is treated as position 1 (although the first character is still reckoned as 1).

 If any argument is `NULL`, returns `NULL`.

 Examples
--------

 
```
SELECT SUBSTRING('Knowledgebase',5);
+------------------------------+
| SUBSTRING('Knowledgebase',5) |
+------------------------------+
| ledgebase                    |
+------------------------------+

SELECT SUBSTRING('MariaDB' FROM 6);
+-----------------------------+
| SUBSTRING('MariaDB' FROM 6) |
+-----------------------------+
| DB                          |
+-----------------------------+

SELECT SUBSTRING('Knowledgebase',3,7);
+--------------------------------+
| SUBSTRING('Knowledgebase',3,7) |
+--------------------------------+
| owledge                        |
+--------------------------------+

SELECT SUBSTRING('Knowledgebase', -4);
+--------------------------------+
| SUBSTRING('Knowledgebase', -4) |
+--------------------------------+
| base                           |
+--------------------------------+

SELECT SUBSTRING('Knowledgebase', -8, 4);
+-----------------------------------+
| SUBSTRING('Knowledgebase', -8, 4) |
+-----------------------------------+
| edge                              |
+-----------------------------------+

SELECT SUBSTRING('Knowledgebase' FROM -8 FOR 4);
+------------------------------------------+
| SUBSTRING('Knowledgebase' FROM -8 FOR 4) |
+------------------------------------------+
| edge                                     |
+------------------------------------------+

```

[Oracle mode from MariaDB 10.3.3](../sql_modeoracle-from-mariadb-103/index):

 
```
SELECT SUBSTR('abc',0,3);
+-------------------+
| SUBSTR('abc',0,3) |
+-------------------+
|                   |
+-------------------+

SELECT SUBSTR('abc',1,2);
+-------------------+
| SUBSTR('abc',1,2) |
+-------------------+
| ab                |
+-------------------+

SET sql_mode='oracle';

SELECT SUBSTR('abc',0,3);
+-------------------+
| SUBSTR('abc',0,3) |
+-------------------+
| abc               |
+-------------------+

SELECT SUBSTR('abc',1,2);
+-------------------+
| SUBSTR('abc',1,2) |
+-------------------+
| ab                |
+-------------------+

```

See Also
--------

 * [INSTR()](../instr/index) - Returns the position of a string within a string
* [LOCATE()](../locate/index) - Returns the position of a string within a string
* [SUBSTRING\_INDEX()](../substring_index/index) - Returns a string based on substring

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/substring/>

SUBSTRING\_INDEX
================

    Syntax
------

 
```
SUBSTRING_INDEX(str,delim,count)

```
 Description
-----------

 Returns the substring from string *`str`* before count occurrences of the delimiter *`delim`*. If *`count`* is positive, everything to the left of the final delimiter (counting from the left) is returned. If *`count`* is negative, everything to the right of the final delimiter (counting from the right) is returned. `SUBSTRING_INDEX()` performs a case-sensitive match when searching for *`delim`*.

 If any argument is `NULL`, returns `NULL`.

 For example

 
```
SUBSTRING_INDEX('www.mariadb.org', '.', 2)

```

means "Return all of the characters up to the 2nd occurrence of ."

 Examples
--------

 
```
SELECT SUBSTRING_INDEX('www.mariadb.org', '.', 2);
+--------------------------------------------+
| SUBSTRING_INDEX('www.mariadb.org', '.', 2) |
+--------------------------------------------+
| www.mariadb                                |
+--------------------------------------------+

SELECT SUBSTRING_INDEX('www.mariadb.org', '.', -2);
+---------------------------------------------+
| SUBSTRING_INDEX('www.mariadb.org', '.', -2) |
+---------------------------------------------+
| mariadb.org                                 |
+---------------------------------------------+

```

See Also
--------

 * [INSTR()](../instr/index) - Returns the position of a string within a string
* [LOCATE()](../locate/index) - Returns the position of a string within a string
* [SUBSTRING()](../substring/index) - Returns a string based on position

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/substring_index/>

SUBSTR
======

    Description
-----------

 `SUBSTR()` is a synonym for `[SUBSTRING](../substring/index)()`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/substr/>

SUBTIME
=======

    Syntax
------

 
```
SUBTIME(expr1,expr2)

```

Description
-----------

 SUBTIME() returns `expr1` - `expr2` expressed as a value in the same format as `expr1`. `expr1` is a time or datetime expression, and expr2 is a time expression.

 Examples
--------

 
```
SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');
+--------------------------------------------------------+
| SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002') |
+--------------------------------------------------------+
| 2007-12-30 22:58:58.999997                             |
+--------------------------------------------------------+

SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
+-----------------------------------------------+
| SUBTIME('01:00:00.999999', '02:00:00.999998') |
+-----------------------------------------------+
| -00:59:59.999999                              |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subtime/>

SUM
===

    Syntax
------

 
```
SUM([DISTINCT] expr)

```
 Description
-----------

 Returns the sum of *`expr`*. If the return set has no rows, `SUM()` returns `NULL`. The `DISTINCT` keyword can be used to sum only the distinct values of `expr`.

 SUM() can be used as a [window function](../window-functions/index), although not with the DISTINCT specifier.

 Examples
--------

 
```
CREATE TABLE sales (sales_value INT);
INSERT INTO sales VALUES(10),(20),(20),(40);

SELECT SUM(sales_value) FROM sales;
+------------------+
| SUM(sales_value) |
+------------------+
|               90 |
+------------------+

SELECT SUM(DISTINCT(sales_value)) FROM sales;
+----------------------------+
| SUM(DISTINCT(sales_value)) |
+----------------------------+
|                         70 |
+----------------------------+

```

Commonly, SUM is used with a [GROUP BY](../select/index#group-by) clause:

 
```
CREATE TABLE sales (name CHAR(10), month CHAR(10), units INT);

INSERT INTO sales VALUES 
  ('Chun', 'Jan', 75), ('Chun', 'Feb', 73),
  ('Esben', 'Jan', 43), ('Esben', 'Feb', 31),
  ('Kaolin', 'Jan', 56), ('Kaolin', 'Feb', 88),
  ('Tatiana', 'Jan', 87), ('Tatiana', 'Feb', 83);

SELECT name, SUM(units) FROM sales GROUP BY name;
+---------+------------+
| name    | SUM(units) |
+---------+------------+
| Chun    |        148 |
| Esben   |         74 |
| Kaolin  |        144 |
| Tatiana |        170 |
+---------+------------+

```

The [GROUP BY](../select/index#group-by) clause is required when using an aggregate function along with regular column data, otherwise the result will be a mismatch, as in the following common type of mistake:

 
```
SELECT name,SUM(units) FROM sales
;+------+------------+
| name | SUM(units) |
+------+------------+
| Chun |        536 |
+------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);
INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, SUM(score) OVER (PARTITION BY name) AS total_score FROM student_test;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Chun    | SQL    |    75 |         148 |
| Chun    | Tuning |    73 |         148 |
| Esben   | SQL    |    43 |          74 |
| Esben   | Tuning |    31 |          74 |
| Kaolin  | SQL    |    56 |         144 |
| Kaolin  | Tuning |    88 |         144 |
| Tatiana | SQL    |    87 |          87 |
+---------+--------+-------+-------------+

```

See Also
--------

 * [AVG](../avg/index) (average)
* [MAX](../max/index) (maximum)
* [MIN](../min/index) (minimum)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sum/>

STDDEV
======

    Syntax
------

 
```
STDDEV(expr)

```
 Description
-----------

 Returns the population standard deviation of *`expr`*. This function is provided for compatibility with Oracle. The standard SQL function `[STDDEV\_POP()](../stddev_pop/index)` can be used instead.

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 STDDEV() can be used as a [window function](../window-functions/index).

 This function returns `NULL` if there were no matching rows.

 Examples
--------

 As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
  OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

```

See Also
--------

 * [STDDEV\_POP](../stddev_pop/index) (equivalent, standard SQL)
* [STD](../std/index) (equivalent, non-standard SQL)
* [VAR\_POP](../var_pop/index) (variance)
* [STDDEV\_SAMP](../stddev_samp/index) (sample standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stddev/>

extract\_schema\_from\_file\_name
=================================

    Syntax
------

 
```
sys.extract_schema_from_file_name(path)

```

Description
-----------

 `extract_schema_from_file_name` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 Given a file path, it returns the schema (database) name. The file name is assumed to be within the schema directory, and therefore the function will not return the expected result with partitions, or when tables are defined using the DATA\_DIRECTORY table option.

 The function does not examine anything on disk. The return value, a VARCHAR(64), is determined solely from the provided path.

 Examples
--------

 
```
SELECT sys.extract_schema_from_file_name('/usr/local/mysql/data/db/t1.ibd');
+----------------------------------------------------------------------+
| sys.extract_schema_from_file_name('/usr/local/mysql/data/db/t1.ibd') |
+----------------------------------------------------------------------+
| db                                                                   |
+----------------------------------------------------------------------+

```

See also
--------

 * [extract\_table\_from\_file\_name()](../extract_table_from_file_name/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extract_schema_from_file_name/>

STDDEV\_POP
===========

    Syntax
------

 
```
STDDEV_POP(expr)

```
 Description
-----------

 Returns the population standard deviation of *`expr`* (the square root of `[VAR\_POP()](../var_pop/index)`). You can also use `[STD()](../std/index)` or `[STDDEV()](../stddev/index)`, which are equivalent but not standard SQL.

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 STDDEV\_POP() can be used as a [window function](../window-functions/index).

 STDDEV\_POP() returns `NULL` if there were no matching rows.

 Examples
--------

 As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, STDDEV_POP(score) 
  OVER (PARTITION BY test) AS stddev_results FROM student_test;
+---------+--------+-------+----------------+
| name    | test   | score | stddev_results |
+---------+--------+-------+----------------+
| Chun    | SQL    |    75 |        16.9466 |
| Chun    | Tuning |    73 |        24.1247 |
| Esben   | SQL    |    43 |        16.9466 |
| Esben   | Tuning |    31 |        24.1247 |
| Kaolin  | SQL    |    56 |        16.9466 |
| Kaolin  | Tuning |    88 |        24.1247 |
| Tatiana | SQL    |    87 |        16.9466 |
+---------+--------+-------+----------------+

```

See Also
--------

 * [STD](../std/index) (equivalent, non-standard SQL)
* [STDDEV](../stddev/index) (equivalent, Oracle-compatible non-standard SQL)
* [VAR\_POP](../var_pop/index) (variance)
* [STDDEV\_SAMP](../stddev_samp/index) (sample standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stddev_pop/>

extract\_table\_from\_file\_name
================================

    Syntax
------

 
```
sys.extract_table_from_file_name(path)

```

Description
-----------

 `extract_table_from_file_name` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 Given a file path, it returns the table name.

 The function does not examine anything on disk. The return value, a VARCHAR(64), is determined solely from the provided path.

 Examples
--------

 
```
SELECT sys.extract_table_from_file_name('/usr/local/mysql/data/db/t1.ibd');
+---------------------------------------------------------------------+
| sys.extract_table_from_file_name('/usr/local/mysql/data/db/t1.ibd') |
+---------------------------------------------------------------------+
| t1                                                                  |
+---------------------------------------------------------------------+

```

See also
--------

 * [extract\_schema\_from\_file\_name()](../extract_schema_from_file_name/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extract_table_from_file_name/>

format\_statement
=================

    Syntax
------

 
```
sys.format_statement(statement)

```

Description
-----------

 Returns a reduced length string. The length is specified by the [statement\_truncate\_len configuration option](../sys-schema-sys_config-table/index) (default 64), and the removed part of the string (if any) is replaced with an ellipsis (three dots).

 The function is intended for use in formatting lengthy SQL statements to a fixed length.

 Examples
--------

 Default truncation length 64:

 
```
SELECT sys.format_statement(
  'SELECT field1, field2, field3, field4, field5, field6 FROM table1'
  ) AS formatted_statement;
+-------------------------------------------------------------------+
| formatted_statement                                               |
+-------------------------------------------------------------------+
| SELECT field1, field2, field3, ... d4, field5, field6 FROM table1 |
+-------------------------------------------------------------------+

```

Reducing the truncation length to 48:

 
```
SET @sys.statement_truncate_len = 48;

SELECT sys.format_statement( 
  'SELECT field1, field2, field3, field4, field5, field6 FROM table1'
  ) AS formatted_statement;
+---------------------------------------------------+
| formatted_statement                               |
+---------------------------------------------------+
| SELECT field1, field2, ... d5, field6 FROM table1 |
+---------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format_statement/>

format\_path
============

    Syntax
------

 
```
sys.format_path(path)

```

Description
-----------

 `format_path` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index) that, given a path, returns a modified path after replacing subpaths matching the values of various system variables with the variable name.

 The system variables that are matched are, in order: 

 * [datadir](../server-system-variables/index#datadir)
* [tmpdir](../server-system-variables/index#tmpdir)
* [slave\_load\_tmpdir](../replication-and-binary-log-system-variables/index#slave_load_tmpdir)
* [innodb\_data\_home\_dir](../innodb-system-variables/index#innodb_data_home_dir)
* [innodb\_log\_group\_home\_dir](../innodb-system-variables/index#innodb_log_group_home_dir)
* [innodb\_undo\_directory](../innodb-system-variables/index#innodb_undo_directory)
* [basedir](../server-system-variables/index#basedir)

 Examples
--------

 
```
SELECT @@tmpdir;
+------------------------------------+
| @@tmpdir                           |
+------------------------------------+
| /home/ian/sandboxes/msb_10_8_2/tmp |
+------------------------------------+

SELECT sys.format_path('/home/ian/sandboxes/msb_10_8_2/tmp/testdb.ibd');
+------------------------------------------------------------------+
| sys.format_path('/home/ian/sandboxes/msb_10_8_2/tmp/testdb.ibd') |
+------------------------------------------------------------------+
| @@tmpdir/testdb.ibd                                              |
+------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format_path/>

format\_bytes
=============

    Syntax
------

 
```
sys.format_bytes(double)

```

Description
-----------

 `format_bytes` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 Given a byte count, returns a string consisting of a value and the units in a human-readable format. The units will be in bytes, KiB (kibibytes), MiB (mebibytes), GiB (gibibytes), TiB (tebibytes), or PiB (pebibytes).

 The binary prefixes (kibi, mebi, gibi, tebi and pebi) were created in December 1998 by the International Electrotechnical Commission to avoid possible ambiguity, as the widely-used prefixes kilo, mega, giga, tera and peta can be used to refer to both the power-of-10 decimal system multipliers and the power-of-two binary system multipliers.

 Examples
--------

 
```
SELECT sys.format_bytes(1000),sys.format_bytes(1024);
+------------------------+------------------------+
| sys.format_bytes(1000) | sys.format_bytes(1024) |
+------------------------+------------------------+
| 1000 bytes             | 1.00 KiB               |
+------------------------+------------------------+

SELECT sys.format_bytes(1000000),sys.format_bytes(1048576);
+---------------------------+---------------------------+
| sys.format_bytes(1000000) | sys.format_bytes(1048576) |
+---------------------------+---------------------------+
| 976.56 KiB                | 1.00 MiB                  |
+---------------------------+---------------------------+

SELECT sys.format_bytes(1000000000),sys.format_bytes(1073741874);
+------------------------------+------------------------------+
| sys.format_bytes(1000000000) | sys.format_bytes(1073741874) |
+------------------------------+------------------------------+
| 953.67 MiB                   | 1.00 GiB                     |
+------------------------------+------------------------------+

SELECT sys.format_bytes(1000000000000),sys.format_bytes(1099511627776);
+---------------------------------+---------------------------------+
| sys.format_bytes(1000000000000) | sys.format_bytes(1099511627776) |
+---------------------------------+---------------------------------+
| 931.32 GiB                      | 1.00 TiB                        |
+---------------------------------+---------------------------------+

SELECT sys.format_bytes(1000000000000000),sys.format_bytes(1125899906842624);
+------------------------------------+------------------------------------+
| sys.format_bytes(1000000000000000) | sys.format_bytes(1125899906842624) |
+------------------------------------+------------------------------------+
| 909.49 TiB                         | 1.00 PiB                           |
+------------------------------------+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format_bytes/>

list\_drop
==========

    Syntax
------

 
```
sys.list_drop(list,value)

```

Description
-----------

 `list_drop` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It takes a *list* to be be modified and a *value* to be dropped from the list, returning the resulting value. This can be used, for example, to remove a value from a system variable taking a comma-delimited list of options, such as [sql\_mode](../sql-mode/index).

 The related function [list\_add](../list_add/index) can be used to add a value to a list.

 Examples
--------

 
```
SELECT @@sql_mode;
+-----------------------------------------------------------------------+
| @@sql_mode                                                            |
+-----------------------------------------------------------------------+
| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------+

SET @@sql_mode = sys.list_drop(@@sql_mode, 'NO_ENGINE_SUBSTITUTION');

SELECT @@sql_mode;
+-----------------------------------------------------------------------+
| @@sql_mode                                                            |
+-----------------------------------------------------------------------+
| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER |
+-----------------------------------------------------------------------+

```

See Also
--------

 * [list\_add](../list_add/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/list_drop/>

format\_time
============

    Syntax
------

 
```
sys.format_time(picoseconds)

```

Description
-----------

 `format_time` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index). Given a time in picoseconds, returns a human-readable time value and unit indicator. Unit can be:

 * ps - picoseconds
* ns - nanoseconds
* us - microseconds
* ms - milliseconds
* s - seconds
* m - minutes
* h - hours
* d - days
* w - weeks

 This function is very similar to the [FORMAT\_PICO\_TIME](../format_pico_time/index) function introduced in [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/), but with the following differences:

 * Represents minutes as `m` rather than `min`.
* Represent weeks.

 Examples
--------

 
```
SELECT
    sys.format_time(43) AS ps,
    sys.format_time(4321) AS ns, 
    sys.format_time(43211234) AS us,
    sys.format_time(432112344321) AS ms,
    sys.format_time(43211234432123) AS s,
    sys.format_time(432112344321234) AS m,
    sys.format_time(4321123443212345) AS h,
    sys.format_time(432112344321234545) AS d,
    sys.format_time(43211234432123444543) AS w;
+-------+---------+----------+-----------+---------+--------+--------+--------+---------+
| ps    | ns      | us       | ms        | s       | m      | h      | d      | w       |
+-------+---------+----------+-----------+---------+--------+--------+--------+---------+
| 43 ps | 4.32 ns | 43.21 us | 432.11 ms | 43.21 s | 7.20 m | 1.20 h | 5.00 d | 71.45 w |
+-------+---------+----------+-----------+---------+--------+--------+--------+---------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/format_time/>

list\_add
=========

    Syntax
------

 
```
sys.list_add(list,value)

```

Description
-----------

 `list_add` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It takes a *list* to be be modified and a *value* to be added to the list, returning the resulting value. This can be used, for example, to add a value to a system variable taking a comma-delimited list of options, such as [sql\_mode](../sql-mode/index).

 The related function [list\_drop](../list_drop/index) can be used to drop a value from a list.

 Examples
--------

 
```
SELECT @@sql_mode;
+-----------------------------------------------------------------------+
| @@sql_mode                                                            |
+-----------------------------------------------------------------------+
| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------+

SET @@sql_mode = sys.list_add(@@sql_mode, 'NO_ZERO_DATE');

SELECT @@sql_mode;
+-----------------------------------------------------------------------+
| @@sql_mode                                                            |
+-----------------------------------------------------------------------+
| STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-----------------------------------------------------------------------+

```

See Also
--------

 * [list\_drop](../list_drop/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/list_add/>

ps\_is\_consumer\_enabled
=========================

    Syntax
------

 
```
sys.ps_is_consumer_enabled(consumer)

```

Description
-----------

 `ps_is_consumer_enabled` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns an ENUM('YES','NO') depending on whether Performance Schema instrumentation for the given consumer is enabled, and NULL if not given a valid consumer name.

 Examples
--------

 
```
SELECT sys.ps_is_consumer_enabled('global_instrumentation');
+------------------------------------------------------+
| sys.ps_is_consumer_enabled('global_instrumentation') |
+------------------------------------------------------+
| YES                                                  |
+------------------------------------------------------+

SELECT sys.ps_is_consumer_enabled('events_stages_current');
+-----------------------------------------------------+
| sys.ps_is_consumer_enabled('events_stages_current') |
+-----------------------------------------------------+
| NO                                                  |
+-----------------------------------------------------+

SELECT sys.ps_is_consumer_enabled('nonexistent_consumer');
+----------------------------------------------------+
| sys.ps_is_consumer_enabled('nonexistent_consumer') |
+----------------------------------------------------+
| NULL                                               |
+----------------------------------------------------+

```

See Also
--------

 * [Performance Schema setup\_consumers Table](../performance-schema-setup_consumers-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_is_consumer_enabled/>

ps\_is\_account\_enabled
========================

    Syntax
------

 
```
sys.ps_is_account_enabled(host,user)

```

Description
-----------

 `ps_is_account_enabled` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It takes *host* and *user* arguments, and returns an ENUM('YES','NO') depending on whether Performance Schema instrumentation for the given account is enabled.

 Examples
--------

 
```
SELECT sys.ps_is_account_enabled('localhost', 'root');
+------------------------------------------------+
| sys.ps_is_account_enabled('localhost', 'root') |
+------------------------------------------------+
| YES                                            |
+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_is_account_enabled/>

ps\_is\_instrument\_default\_timed
==================================

    Syntax
------

 
```
sys.ps_is_instrument_default_timed(instrument)

```

Description
-----------

 `ps_is_instrument_default_timed` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns `YES` if the given Performance Schema *instrument* is timed by default, and `NO` if it is not, does not exist, or is a NULL value.

 Examples
--------

 
```
SELECT sys.ps_is_instrument_default_timed('statement/sql/select');
+------------------------------------------------------------+
| sys.ps_is_instrument_default_timed('statement/sql/select') |
+------------------------------------------------------------+
| YES                                                        |
+------------------------------------------------------------+

SELECT sys.ps_is_instrument_default_timed('memory/sql/udf_mem');
+----------------------------------------------------------+
| sys.ps_is_instrument_default_timed('memory/sql/udf_mem') |
+----------------------------------------------------------+
| NO                                                       |
+----------------------------------------------------------+

SELECT sys.ps_is_instrument_default_timed('memory/sql/nonexistent');
+-------------------------------------------------------------+
| sys.ps_is_instrument_default_timed('memory/sql/udf_memsds') |
+-------------------------------------------------------------+
| NO                                                          |
+-------------------------------------------------------------+

SELECT sys.ps_is_instrument_default_timed(NULL);
+------------------------------------------+
| sys.ps_is_instrument_default_timed(NULL) |
+------------------------------------------+
| NO                                       |
+------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_is_instrument_default_timed/>

ps\_is\_instrument\_default\_enabled
====================================

    Syntax
------

 
```
sys.ps_is_instrument_default_enabled(instrument)

```

Description
-----------

 `ps_is_instrument_default_enabled` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns `YES` if the given Performance Schema *instrument* is enabled by default, and `NO` if it is not, does not exist, or is a NULL value.

 Examples
--------

 
```
SELECT sys.ps_is_instrument_default_enabled('statement/sql/select');
+--------------------------------------------------------------+
| sys.ps_is_instrument_default_enabled('statement/sql/select') |
+--------------------------------------------------------------+
| YES                                                          |
+--------------------------------------------------------------+

SELECT sys.ps_is_instrument_default_enabled('memory/sql/udf_mem');
+------------------------------------------------------------+
| sys.ps_is_instrument_default_enabled('memory/sql/udf_mem') |
+------------------------------------------------------------+
| NO                                                         |
+------------------------------------------------------------+

SELECT sys.ps_is_instrument_default_enabled('memory/sql/nonexistent');
+----------------------------------------------------------------+
| sys.ps_is_instrument_default_enabled('memory/sql/nonexistent') |
+----------------------------------------------------------------+
| NO                                                             |
+----------------------------------------------------------------+

SELECT sys.ps_is_instrument_default_enabled(NULL);
+--------------------------------------------+
| sys.ps_is_instrument_default_enabled(NULL) |
+--------------------------------------------+
| NO                                         |
+--------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_is_instrument_default_enabled/>

ps\_thread\_account
===================

    Syntax
------

 
```
sys.ps_thread_account(thread_id)

```

Description
-----------

 `ps_thread_account` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index) that returns the account (username@hostname) associated with the given *thread\_id*.

 Returns `NULL` if the thread\_id is not found.

 Examples
--------

 
```
SELECT sys.ps_thread_account(sys.ps_thread_id(CONNECTION_ID()));
+----------------------------------------------------------+
| sys.ps_thread_account(sys.ps_thread_id(CONNECTION_ID())) |
+----------------------------------------------------------+
| msandbox@localhost                                       |
+----------------------------------------------------------+

SELECT sys.ps_thread_account(sys.ps_thread_id(2042));
+-----------------------------------------------+
| sys.ps_thread_account(sys.ps_thread_id(2042)) |
+-----------------------------------------------+
| NULL                                          |
+-----------------------------------------------+

SELECT sys.ps_thread_account(sys.ps_thread_id(NULL));
+-----------------------------------------------+
| sys.ps_thread_account(sys.ps_thread_id(NULL)) |
+-----------------------------------------------+
| msandbox@localhost                            |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_thread_account/>

ps\_thread\_id
==============

    Syntax
------

 
```
sys.ps_thread_id(connection_id)

```

Description
-----------

 `ps_thread_id` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index) that returns the thread\_id associated with the given *connection\_id*. If the *connection\_id* is NULL, returns the thread\_id for the current connection. 

 Examples
--------

 
```
SELECT * FROM performance_schema.threads\G
*************************** 13. row ***************************
          THREAD_ID: 13
               NAME: thread/sql/one_connection
               TYPE: FOREGROUND
     PROCESSLIST_ID: 3
   PROCESSLIST_USER: msandbox
   PROCESSLIST_HOST: localhost
     PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Query
   PROCESSLIST_TIME: 0
  PROCESSLIST_STATE: Sending data
   PROCESSLIST_INFO: SELECT * FROM performance_schema.threads
   PARENT_THREAD_ID: 1
               ROLE: NULL
       INSTRUMENTED: YES
            HISTORY: YES
    CONNECTION_TYPE: Socket
       THREAD_OS_ID: 24379


SELECT sys.ps_thread_id(3);
+---------------------+
| sys.ps_thread_id(3) |
+---------------------+
|                  13 |
+---------------------+

SELECT sys.ps_thread_id(NULL);
+------------------------+
| sys.ps_thread_id(NULL) |
+------------------------+
|                     13 |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_thread_id/>

ps\_is\_thread\_instrumented
============================

    Syntax
------

 
```
sys.ps_is_thread_instrumented(connection_id)

```

Description
-----------

 `ps_is_thread_instrumented` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index) that returns whether or not Performance Schema instrumentation for the given *connection\_id* is enabled.

 * `YES` - instrumentation is enabled
* `NO` - instrumentation is not enabled
* `UNKNOWN` - the connection ID is unknown
* `NULL` - NULL value

 Examples
--------

 
```
SELECT sys.ps_is_thread_instrumented(CONNECTION_ID());
+------------------------------------------------+
| sys.ps_is_thread_instrumented(CONNECTION_ID()) |
+------------------------------------------------+
| YES                                            |
+------------------------------------------------+

SELECT sys.ps_is_thread_instrumented(2042);
+-------------------------------------+
| sys.ps_is_thread_instrumented(2042) |
+-------------------------------------+
| UNKNOWN                             |
+-------------------------------------+

SELECT sys.ps_is_thread_instrumented(NULL);
+-------------------------------------+
| sys.ps_is_thread_instrumented(NULL) |
+-------------------------------------+
| NULL                                |
+-------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_is_thread_instrumented/>

quote\_identifier
=================

    Syntax
------

 
```
sys.quote_identifier(str)

```

Description
-----------

 `quote_identifier` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It quotes a string to produce a result that can be used as an identifier in an SQL statement. The string is returned enclosed by backticks ("```") and with each instance of backtick ("```") doubled. If the argument is `NULL`, the return value is the word "`NULL`" without enclosing backticks.

 Examples
--------

 
```
SELECT sys.quote_identifier("Identifier with spaces");
+------------------------------------------------+
| sys.quote_identifier("Identifier with spaces") |
+------------------------------------------------+
| `Identifier with spaces`                       |
+------------------------------------------------+

SELECT sys.quote_identifier("Identifier` containing `backticks");
+-----------------------------------------------------------+
| sys.quote_identifier("Identifier` containing `backticks") |
+-----------------------------------------------------------+
| `Identifier`` containing ``backticks`                     |
+-----------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/quote_identifier/>

ps\_thread\_stack
=================

    Syntax
------

 
```
sys.ps_thread_stack(thread_id, verbose)

```

Description
-----------

 `ps_thread_stack` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index) that, for a given *thread\_id*, returns all statements, stages, and events within the Performance Schema, as a JSON formatted stack.

 The boolean *verbose* argument specifies whether or not to include `file:lineno` information in the events.

 Examples
--------

 
```
SELECT sys.ps_thread_stack(13, FALSE) AS thread_stack\G
*************************** 1. row ***************************
thread_stack: {"rankdir": "LR","nodesep": "0.10",
  "stack_created": "2022-03-28 16:01:06",
  "mysql_version": "10.8.2-MariaDB",
  "mysql_user": "msandbox@localhost",
  "events": []}

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_thread_stack/>

ps\_thread\_trx\_info
=====================

    Syntax
------

 
```
sys.ps_thread_trx_info(thread_id)

```
 Description
-----------

 `ps_thread_trx_info` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns a JSON object with information about the thread specified by the given *thread\_id*. This information includes:

 * the current transaction
* executed statements (derived from the [Performance Schema events\_transactions\_current Table](../performance-schema-events_transactions_current-table/index) and the [Performance Schema events\_statements\_history Table](../performance-schema-events_statements_history-table/index) (full data will only returned if the consumers for those tables are enabled).

 The maximum length of the returned JSON object is determined by the value of the [ps\_thread\_trx\_info.max\_length sys\_config option](../sys-schema-sys_config-table/index) (by default 65535). If the returned value exceeds this length, a JSON object error is returned.

 Examples
--------


See Also
--------

 * [Sys Schema sys\_config Table](../sys-schema-sys_config-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_thread_trx_info/>

SYSTEM\_USER
============

    Syntax
------

 
```
SYSTEM_USER()

```

Description
-----------

 SYSTEM\_USER() is a synonym for [USER()](../user/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system_user/>

TAN
===

    Syntax
------

 
```
TAN(X)

```

Description
-----------

 Returns the tangent of X, where X is given in radians.

 Examples
--------

 
```

SELECT TAN(0.7853981633974483);
+-------------------------+
| TAN(0.7853981633974483) |
+-------------------------+
|      0.9999999999999999 |
+-------------------------+

SELECT TAN(PI());
+-----------------------+
| TAN(PI())             |
+-----------------------+
| -1.22460635382238e-16 |
+-----------------------+

SELECT TAN(PI()+1);
+-----------------+
| TAN(PI()+1)     |
+-----------------+
| 1.5574077246549 |
+-----------------+

SELECT TAN(RADIANS(PI()));
+--------------------+
| TAN(RADIANS(PI())) |
+--------------------+
| 0.0548861508080033 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tan/>

TIME Function
=============

    Syntax
------

 
```
TIME(expr)

```

Description
-----------

 Extracts the time part of the time or datetime expression `expr` and returns it as a string.

 Examples
--------

 
```
SELECT TIME('2003-12-31 01:02:03');
+-----------------------------+
| TIME('2003-12-31 01:02:03') |
+-----------------------------+
| 01:02:03                    |
+-----------------------------+

SELECT TIME('2003-12-31 01:02:03.000123');
+------------------------------------+
| TIME('2003-12-31 01:02:03.000123') |
+------------------------------------+
| 01:02:03.000123                    |
+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time-function/>

TIMEDIFF
========

    Syntax
------

 
```
TIMEDIFF(expr1,expr2)

```

Description
-----------

 TIMEDIFF() returns `expr1` - `expr2` expressed as a time value. `expr1` and `expr2` are time or date-and-time expressions, but both must be of the same type.

 Examples
--------

 
```
SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
+---------------------------------------------------------------+
| TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001') |
+---------------------------------------------------------------+
| -00:00:00.000001                                              |
+---------------------------------------------------------------+

SELECT TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002');
+----------------------------------------------------------------------+
| TIMEDIFF('2008-12-31 23:59:59.000001', '2008-12-30 01:01:01.000002') |
+----------------------------------------------------------------------+
| 46:58:57.999999                                                      |
+----------------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/timediff/>

sys\_get\_config
================

    Syntax
------

 
```
sys.sys_get_config(name,default)

```
 Description
-----------

 `sys_get_config` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 The function returns a configuration option value from the [sys\_config table](../sys-schema-sys_config-table/index). It takes two arguments; *name*, a configuration option name, and *default*, which is returned if the given option does not exist in the table. 

 Both arguments are VARCHAR(128) and can be NULL. Returns NULL if *name* is NULL, or if the given option is not found and *default* is NULL.

 Examples
--------

 
```
SELECT sys.sys_get_config('ps_thread_trx_info.max_length',NULL);
+----------------------------------------------------------+
| sys.sys_get_config('ps_thread_trx_info.max_length',NULL) |
+----------------------------------------------------------+
| 65535                                                    |
+----------------------------------------------------------+

```

See Also
--------

 * [Sys Schema sys\_config Table](../sys-schema-sys_config-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys_get_config/>

TIMESTAMP FUNCTION
==================

    Syntax
------

 
```
TIMESTAMP(expr), TIMESTAMP(expr1,expr2)

```

Description
-----------

 With a single argument, this function returns the date or datetime expression `expr` as a datetime value. With two arguments, it adds the time expression `expr2` to the date or datetime expression `expr1` and returns the result as a datetime value.

 Examples
--------

 
```
SELECT TIMESTAMP('2003-12-31');
+-------------------------+
| TIMESTAMP('2003-12-31') |
+-------------------------+
| 2003-12-31 00:00:00     |
+-------------------------+

SELECT TIMESTAMP('2003-12-31 12:00:00','6:30:00');
+--------------------------------------------+
| TIMESTAMP('2003-12-31 12:00:00','6:30:00') |
+--------------------------------------------+
| 2003-12-31 18:30:00                        |
+--------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/timestamp-function/>

TIMESTAMPDIFF
=============

    Syntax
------

 
```
TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)

```

Description
-----------

 Returns `datetime_expr2` - `datetime_expr1`, where `datetime_expr1` and `datetime_expr2` are date or datetime expressions. One expression may be a date and the other a datetime; a date value is treated as a datetime having the time part '00:00:00' where necessary. The unit for the result (an integer) is given by the unit argument. The legal values for unit are the same as those listed in the description of the [TIMESTAMPADD()](../timestampadd/index) function, i.e MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.

 `TIMESTAMPDIFF` can also be used to calculate age.

 Examples
--------

 
```
SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
+------------------------------------------------+
| TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01') |
+------------------------------------------------+
|                                              3 |
+------------------------------------------------+

SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
+-----------------------------------------------+
| TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01') |
+-----------------------------------------------+
|                                            -1 |
+-----------------------------------------------+

SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
+----------------------------------------------------------+
| TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55') |
+----------------------------------------------------------+
|                                                   128885 |
+----------------------------------------------------------+

```

Calculating age:

 
```
SELECT CURDATE();
+------------+
| CURDATE()  |
+------------+
| 2019-05-27 |
+------------+

SELECT TIMESTAMPDIFF(YEAR, '1971-06-06', CURDATE()) AS age;
+------+
| age  |
+------+
|   47 |
+------+

SELECT TIMESTAMPDIFF(YEAR, '1971-05-06', CURDATE()) AS age;
+------+
| age  |
+------+
|   48 |
+------+

```

Age as of 2014-08-02:

 
```
SELECT name, date_of_birth, TIMESTAMPDIFF(YEAR,date_of_birth,'2014-08-02') AS age 
  FROM student_details;
+---------+---------------+------+
| name    | date_of_birth | age  |
+---------+---------------+------+
| Chun    | 1993-12-31    |   20 |
| Esben   | 1946-01-01    |   68 |
| Kaolin  | 1996-07-16    |   18 |
| Tatiana | 1988-04-13    |   26 |
+---------+---------------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/timestampdiff/>

TIMESTAMPADD
============

    Syntax
------

 
```
TIMESTAMPADD(unit,interval,datetime_expr)

```

Description
-----------

 Adds the integer expression interval to the date or datetime expression datetime\_expr. The unit for interval is given by the unit argument, which should be one of the following values: MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.

 The unit value may be specified using one of keywords as shown, or with a prefix of SQL\_TSI\_. For example, DAY and SQL\_TSI\_DAY both are legal.

 Before [MariaDB 5.5](../what-is-mariadb-55/index), FRAC\_SECOND was permitted as a synonym for MICROSECOND.

 Examples
--------

 
```
SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
+-------------------------------------+
| TIMESTAMPADD(MINUTE,1,'2003-01-02') |
+-------------------------------------+
| 2003-01-02 00:01:00                 |
+-------------------------------------+

SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
+-----------------------------------+
| TIMESTAMPADD(WEEK,1,'2003-01-02') |
+-----------------------------------+
| 2003-01-09                        |
+-----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/timestampadd/>

SYSDATE
=======

    Syntax
------

 
```
SYSDATE([precision])

```
 Description
-----------

 Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context.

 The optional *precision* determines the microsecond precision. See [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 SYSDATE() returns the time at which it executes. This differs from the behavior for [NOW()](../now/index), which returns a constant time that indicates the time at which the statement began to execute. (Within a stored routine or trigger, NOW() returns the time at which the routine or triggering statement began to execute.)

 In addition, changing the [timestamp system variable](../server-system-variables/index#timestamp) with a [SET](../set/index) `timestamp` statement affects the value returned by NOW() but not by SYSDATE(). This means that timestamp settings in the [binary log](../binary-log/index) have no effect on invocations of SYSDATE().

 Because SYSDATE() can return different values even within the same statement, and is not affected by SET TIMESTAMP, it is non-deterministic and therefore unsafe for replication if statement-based binary logging is used. If that is a problem, you can use row-based logging, or start the server with the mysqld option [--sysdate-is-now](../mysqld-options/index#-sysdate-is-now) to cause SYSDATE() to be an alias for NOW(). The non-deterministic nature of SYSDATE() also means that indexes cannot be used for evaluating expressions that refer to it, and that statements using the SYSDATE() function are [unsafe for statement-based replication](../unsafe-statements-for-replication/index).

 Examples
--------

 Difference between NOW() and SYSDATE():

 
```
SELECT NOW(), SLEEP(2), NOW();
+---------------------+----------+---------------------+
| NOW()               | SLEEP(2) | NOW()               |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:40 |        0 | 2010-03-27 13:23:40 |
+---------------------+----------+---------------------+

SELECT SYSDATE(), SLEEP(2), SYSDATE();
+---------------------+----------+---------------------+
| SYSDATE()           | SLEEP(2) | SYSDATE()           |
+---------------------+----------+---------------------+
| 2010-03-27 13:23:52 |        0 | 2010-03-27 13:23:54 |
+---------------------+----------+---------------------+

```

With precision:

 
```
SELECT SYSDATE(4);
+--------------------------+
| SYSDATE(4)               |
+--------------------------+
| 2018-07-10 10:17:13.1689 |
+--------------------------+

```

See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)
* [timestamp server system variable](../server-system-variables/index#timestamp)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysdate/>

SYS\_GUID
=========

    
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**The SYS\_GUID function was introduced in [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) to enhance Oracle compatibility. Similar functionality can be achieved with the [UUID](../uuid/index) function.

 
Syntax
------

 
```
SYS_GUID()

```

Description
-----------

 Returns a 16-byte globally unique identifier (GUID), similar to the [UUID](../uuid/index) function, but without the `-` character.

 Example
-------

 
```
SELECT SYS_GUID();
+----------------------------------+
| SYS_GUID()                       |
+----------------------------------+
| 2C574E45BA2811EBB265F859713E4BE4 |
+----------------------------------+

```

See Also
--------

 * [UUID](../uuid/index)
* [UUID\_SHORT](../uuid_short/index)
* [UUID data type](../uuid-data-type/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys_guid/>

TIME\_TO\_SEC
=============

    Syntax
------

 
```
TIME_TO_SEC(time)

```

Description
-----------

 Returns the time argument, converted to seconds.

 The value returned by `TIME_TO_SEC` is of type `[DOUBLE](../double/index)`. Before [MariaDB 5.3](../what-is-mariadb-53/index) (and MySQL 5.6), the type was `[INT](../int/index)`. The returned value preserves microseconds of the argument. See also [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 Examples
--------

 
```
SELECT TIME_TO_SEC('22:23:00');
+-------------------------+
| TIME_TO_SEC('22:23:00') |
+-------------------------+
|                   80580 |
+-------------------------+

```


```
SELECT TIME_TO_SEC('00:39:38');
+-------------------------+
| TIME_TO_SEC('00:39:38') |
+-------------------------+
|                    2378 |
+-------------------------+

```


```
SELECT TIME_TO_SEC('09:12:55.2355');
+------------------------------+
| TIME_TO_SEC('09:12:55.2355') |
+------------------------------+
|                   33175.2355 |
+------------------------------+
1 row in set (0.000 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time_to_sec/>

version\_patch
==============

    Syntax
------

 
```
sys.version_patch()

```

Description
-----------

 `version_patch` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns the MariaDB Server patch release version.

 Examples
--------

 
```
SELECT VERSION(),
 sys.version_major() AS major, 
 sys.version_minor() AS minor,
 sys.version_patch() AS patch;
+----------------+-------+-------+-------+
| VERSION()      | major | minor | patch |
+----------------+-------+-------+-------+
| 10.8.2-MariaDB |    10 |     8 |     2 |
+----------------+-------+-------+-------+

```

See Also
--------

 * [version\_major](../version_major/index)
* [version\_minor](../version_minor/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/version_patch/>

TIME\_FORMAT
============

    Syntax
------

 
```
TIME_FORMAT(time,format)

```

Description
-----------

 This is used like the [DATE\_FORMAT()](../date_format/index) function, but the format string may contain format specifiers only for hours, minutes, and seconds. Other specifiers produce a NULL value or 0.

 Examples
--------

 
```
SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
+--------------------------------------------+
| TIME_FORMAT('100:00:00', '%H %k %h %I %l') |
+--------------------------------------------+
| 100 100 04 04 4                            |
+--------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time_format/>

version\_major
==============

    Syntax
------

 
```
sys.version_major()

```

Description
-----------

 `version_major` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns the MariaDB Server major release version.

 Examples
--------

 
```
SELECT VERSION(),
 sys.version_major() AS major, 
 sys.version_minor() AS minor,
 sys.version_patch() AS patch;
+----------------+-------+-------+-------+
| VERSION()      | major | minor | patch |
+----------------+-------+-------+-------+
| 10.8.2-MariaDB |    10 |     8 |     2 |
+----------------+-------+-------+-------+

```

See Also
--------

 * [version\_minor](../version_minor/index)
* [version\_patch](../version_patch/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/version_major/>

TO\_DAYS
========

    Syntax
------

 
```
TO_DAYS(date)

```

Description
-----------

 Given a date `date`, returns the number of days since the start of the current calendar (0000-00-00).

 The function is not designed for use with dates before the advent of the Gregorian calendar in October 1582. Results will not be reliable since it doesn't account for the lost days when the calendar changed from the Julian calendar.

 This is the converse of the [FROM\_DAYS()](../from_days/index) function.

 Examples
--------

 
```
SELECT TO_DAYS('2007-10-07');
+-----------------------+
| TO_DAYS('2007-10-07') |
+-----------------------+
|                733321 |
+-----------------------+

SELECT TO_DAYS('0000-01-01');
+-----------------------+
| TO_DAYS('0000-01-01') |
+-----------------------+
|                     1 |
+-----------------------+

SELECT TO_DAYS(950501);
+-----------------+
| TO_DAYS(950501) |
+-----------------+
|          728779 |
+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/to_days/>

version\_minor
==============

    Syntax
------

 
```
sys.version_minor()

```

Description
-----------

 `version_minor` is a [stored function](../stored-functions/index) available with the [Sys Schema](../sys-schema/index).

 It returns the MariaDB Server minor release version.

 Examples
--------

 
```
SELECT VERSION(),
 sys.version_major() AS major, 
 sys.version_minor() AS minor,
 sys.version_patch() AS patch;
+----------------+-------+-------+-------+
| VERSION()      | major | minor | patch |
+----------------+-------+-------+-------+
| 10.8.2-MariaDB |    10 |     8 |     2 |
+----------------+-------+-------+-------+

```

See Also
--------

 * [version\_major](../version_major/index)
* [version\_patch](../version_patch/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/version_minor/>

TO\_BASE64
==========

    Syntax
------

 
```
TO_BASE64(str)

```

Description
-----------

 Converts the string argument `str` to its base-64 encoded form, returning the result as a character string in the connection character set and collation.

 The argument `str` will be converted to string first if it is not a string. A NULL argument will return a NULL result.

 The reverse function, [FROM\_BASE64()](../from_base64/index), decodes an encoded base-64 string.

 There are a numerous different methods to base-64 encode a string. The following are used by MariaDB and MySQL:

 * Alphabet value 64 is encoded as '+'.
* Alphabet value 63 is encoded as '/'.
* Encoding output is made up of groups of four printable characters, with each three bytes of data encoded using four characters. If the final group is not complete, it is padded with '=' characters to make up a length of four.
* To divide long output, a newline is added after every 76 characters.
* Decoding will recognize and ignore newlines, carriage returns, tabs, and spaces.

 Examples
--------

 
```
SELECT TO_BASE64('Maria');
+--------------------+
| TO_BASE64('Maria') |
+--------------------+
| TWFyaWE=           |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/to_base64/>

TOUCHES
=======

    Syntax
------

 
```
Touches(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether `g1` spatially touches `g2`. Two geometries spatially touch if the interiors of the geometries do not intersect, but the boundary of one of the geometries intersects either the boundary or the interior of the other.

 TOUCHES() is based on the original MySQL implementation and uses object bounding rectangles, while [ST\_TOUCHES()](../st_touches/index) uses object shapes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/touches/>

TRUNCATE
========

    
This page documents the TRUNCATE function. See [TRUNCATE TABLE](../truncate-table/index) for the DDL statement.

 
Syntax
------

 
```
TRUNCATE(X,D)

```
 Description
-----------

 Returns the number X, truncated to D decimal places. If D is 0, the result has no decimal point or fractional part. D can be negative to cause D digits left of the decimal point of the value X to become zero.

 Examples
--------

 
```
SELECT TRUNCATE(1.223,1);
+-------------------+
| TRUNCATE(1.223,1) |
+-------------------+
|               1.2 |
+-------------------+

SELECT TRUNCATE(1.999,1);
+-------------------+
| TRUNCATE(1.999,1) |
+-------------------+
|               1.9 |
+-------------------+

SELECT TRUNCATE(1.999,0); 
+-------------------+
| TRUNCATE(1.999,0) |
+-------------------+
|                 1 |
+-------------------+

SELECT TRUNCATE(-1.999,1);
+--------------------+
| TRUNCATE(-1.999,1) |
+--------------------+
|               -1.9 |
+--------------------+

SELECT TRUNCATE(122,-2);
+------------------+
| TRUNCATE(122,-2) |
+------------------+
|              100 |
+------------------+

SELECT TRUNCATE(10.28*100,0);
+-----------------------+
| TRUNCATE(10.28*100,0) |
+-----------------------+
|                  1028 |
+-----------------------+

```

See Also
--------

 * [TRUNCATE TABLE](../truncate-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/truncate/>

TO\_CHAR
========

    
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**The TO\_CHAR function was introduced in [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) to enhance Oracle compatibility.

 
Syntax
------

 
```
TO_CHAR(expr[, fmt])

```
 Description
-----------

 The `TO_CHAR` function converts an *expr* of type [date](../date/index), [datetime](../datetime/index), [time](../time/index) or [timestamp](../timestamp/index) to a string. The optional *fmt* argument supports YYYY/YYY/YY/RRRR/RR/MM/MON/MONTH/MI/DD/DY/HH/HH12/HH24/SS and special characters. The default value is "YYYY-MM-DD HH24:MI:SS".

 In Oracle, TO\_CHAR can also be used to convert numbers to strings, but this is not supported in MariaDB and will give an error.

 Examples
--------

 
```
SELECT TO_CHAR('1980-01-11 04:50:39', 'YYYY-MM-DD');
+----------------------------------------------+
| TO_CHAR('1980-01-11 04:50:39', 'YYYY-MM-DD') |
+----------------------------------------------+
| 1980-01-11                                   |
+----------------------------------------------+

SELECT TO_CHAR('1980-01-11 04:50:39', 'HH24-MI-SS');
+----------------------------------------------+
| TO_CHAR('1980-01-11 04:50:39', 'HH24-MI-SS') |
+----------------------------------------------+
| 04-50-39                                     |
+----------------------------------------------+

SELECT TO_CHAR('00-01-01 00:00:00', 'YY-MM-DD HH24:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('00-01-01 00:00:00', 'YY-MM-DD HH24:MI:SS') |
+-----------------------------------------------------+
| 00-01-01 00:00:00                                   |
+-----------------------------------------------------+

SELECT TO_CHAR('99-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('99-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS') |
+-----------------------------------------------------+
| 99-12-31 23:59:59                                   |
+-----------------------------------------------------+

SELECT TO_CHAR('9999-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS');
+-------------------------------------------------------+
| TO_CHAR('9999-12-31 23:59:59', 'YY-MM-DD HH24:MI:SS') |
+-------------------------------------------------------+
| 99-12-31 23:59:59                                     |
+-------------------------------------------------------+

SELECT TO_CHAR('21-01-03 08:30:00', 'Y-MONTH-DY HH:MI:SS');
+-----------------------------------------------------+
| TO_CHAR('21-01-03 08:30:00', 'Y-MONTH-DY HH:MI:SS') |
+-----------------------------------------------------+
| 1-January  -Sun 08:30:00                            |
+-----------------------------------------------------+

```

See Also
--------

 * [SQL\_MODE=ORACLE](../sql_modeoracle/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/to_char/>

TO\_SECONDS
===========

    Syntax
------

 
```
TO_SECONDS(expr)

```

Description
-----------

 Returns the number of seconds from year 0 till `expr`, or NULL if `expr` is not a valid date or [datetime](../datetime/index).

 Examples
--------

 
```
SELECT TO_SECONDS('2013-06-13');
+--------------------------+
| TO_SECONDS('2013-06-13') |
+--------------------------+
|              63538300800 |
+--------------------------+

SELECT TO_SECONDS('2013-06-13 21:45:13');
+-----------------------------------+
| TO_SECONDS('2013-06-13 21:45:13') |
+-----------------------------------+
|                       63538379113 |
+-----------------------------------+

SELECT TO_SECONDS(NOW());
+-------------------+
| TO_SECONDS(NOW()) |
+-------------------+
|       63543530875 |
+-------------------+

SELECT TO_SECONDS(20130513);
+----------------------+
| TO_SECONDS(20130513) |
+----------------------+
|          63535622400 |
+----------------------+
1 row in set (0.00 sec)

SELECT TO_SECONDS(130513);
+--------------------+
| TO_SECONDS(130513) |
+--------------------+
|        63535622400 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/to_seconds/>

TRIM
====

    Syntax
------

 
```
TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)

```

From [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)

 
```
TRIM_ORACLE([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)

```
 Description
-----------

 Returns the string `str` with all `remstr` prefixes or suffixes removed. If none of the specifiers `BOTH`, `LEADING`, or `TRAILING` is given, `BOTH` is assumed. `remstr` is optional and, if not specified, spaces are removed.

 Returns NULL if given a NULL argument. If the result is empty, returns either an empty string, or, from [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) with [SQL\_MODE=Oracle](../sql_modeoracle/index), NULL. `SQL_MODE=Oracle` is not set by default.

 The Oracle mode version of the function can be accessed in any mode by using `TRIM_ORACLE` as the function name.

 Examples
--------

 
```
SELECT TRIM('  bar   ')\G
*************************** 1. row ***************************
TRIM('  bar   '): bar

SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx')\G
*************************** 1. row ***************************
TRIM(LEADING 'x' FROM 'xxxbarxxx'): barxxx

SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx')\G
*************************** 1. row ***************************
TRIM(BOTH 'x' FROM 'xxxbarxxx'): bar

SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz')\G
*************************** 1. row ***************************
TRIM(TRAILING 'xyz' FROM 'barxxyz'): barx

```

From [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), with [SQL\_MODE=Oracle](../sql_modeoracle/index) not set:

 
```
SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
|          | NULL            |
+----------+-----------------+

```

From [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), with [SQL\_MODE=Oracle](../sql_modeoracle/index) set:

 
```
SELECT TRIM(''),TRIM_ORACLE('');
+----------+-----------------+
| TRIM('') | TRIM_ORACLE('') |
+----------+-----------------+
| NULL     | NULL            |
+----------+-----------------+

```

See Also
--------

 * [LTRIM](../ltrim/index) - leading spaces removed
* [RTRIM](../rtrim/index) - trailing spaces removed

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/trim/>

UCASE
=====

    Syntax
------

 
```
UCASE(str)

```

Description
-----------

 `UCASE()` is a synonym for `[UPPER](../upper/index)()`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ucase/>

UNHEX
=====

    Syntax
------

 
```
UNHEX(str)

```

Description
-----------

 Performs the inverse operation of [HEX](../hex/index)(str). That is, it interprets each pair of hexadecimal digits in the argument as a number and converts it to the character represented by the number. The resulting characters are returned as a binary string.

 If `str` is `NULL`, `UNHEX()` returns `NULL`.

 Examples
--------

 
```
SELECT HEX('MariaDB');
+----------------+
| HEX('MariaDB') |
+----------------+
| 4D617269614442 |
+----------------+

SELECT UNHEX('4D617269614442');
+-------------------------+
| UNHEX('4D617269614442') |
+-------------------------+
| MariaDB                 |
+-------------------------+

SELECT 0x4D617269614442;
+------------------+
| 0x4D617269614442 |
+------------------+
| MariaDB          |
+------------------+

SELECT UNHEX(HEX('string'));
+----------------------+
| UNHEX(HEX('string')) |
+----------------------+
| string               |
+----------------------+

SELECT HEX(UNHEX('1267'));
+--------------------+
| HEX(UNHEX('1267')) |
+--------------------+
| 1267               |
+--------------------+

```

See Also
--------

 * [Hexadecimal literals](../hexadecimal-literals/index)
* [HEX()](../hex/index)
* [CONV()](../conv/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/unhex/>

UNCOMPRESS
==========

    Syntax
------

 
```
UNCOMPRESS(string_to_uncompress)

```

Description
-----------

 Uncompresses a string compressed by the `[COMPRESS()](../compress/index)` function. If the argument is not a compressed value, the result is `NULL`. This function requires MariaDB to have been compiled with a compression library such as zlib. Otherwise, the return value is always `NULL`. The [have\_compress](../server-system-variables/index#have_compress) server system variable indicates whether a compression library is present. 

 Examples
--------

 
```
SELECT UNCOMPRESS(COMPRESS('a string'));
+----------------------------------+
| UNCOMPRESS(COMPRESS('a string')) |
+----------------------------------+
| a string                         |
+----------------------------------+

SELECT UNCOMPRESS('a string');
+------------------------+
| UNCOMPRESS('a string') |
+------------------------+
| NULL                   |
+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uncompress/>

UNCOMPRESSED\_LENGTH
====================

    Syntax
------

 
```
UNCOMPRESSED_LENGTH(compressed_string)

```

Description
-----------

 Returns the length that the compressed string had before being compressed with `[COMPRESS()](../compress/index)`.

 `UNCOMPRESSED_LENGTH()` returns `NULL` or an incorrect result if the string is not compressed.

 Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), returns `MYSQL_TYPE_LONGLONG`, or [bigint(10)](../bigint/index), in all cases. From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), returns `MYSQL_TYPE_LONG`, or [int(10)](../int/index), when the result would fit within 32-bits.

 Examples
--------

 
```
SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
+-----------------------------------------------+
| UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30))) |
+-----------------------------------------------+
|                                            30 |
+-----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uncompressed_length/>

UNIX\_TIMESTAMP
===============

    Syntax
------

 
```
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)

```

Description
-----------

 If called with no argument, returns a Unix timestamp (seconds since '1970-01-01 00:00:00' [UTC](../coordinated-universal-time/index)) as an unsigned integer. If `UNIX_TIMESTAMP()` is called with a date argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00' UTC. date may be a `[DATE](../date/index)` string, a `[DATETIME](../datetime/index)` string, a `[TIMESTAMP](../timestamp/index)`, or a number in the format YYMMDD or YYYYMMDD. The server interprets date as a value in the current [time zone](../time-zones/index) and converts it to an internal value in [UTC](../coordinated-universal-time/index). Clients can set their time zone as described in [time zones](../time-zones/index).

 The inverse function of `UNIX_TIMESTAMP()` is `[FROM\_UNIXTIME()](../from_unixtime/index)`

 `UNIX_TIMESTAMP()` supports [microseconds](../microseconds-in-mariadb/index).

 
Timestamps in MariaDB have a maximum value of 2147483647, equivalent to 2038-01-19 05:14:07. This is due to the underlying 32-bit limitation. Using the function on a date beyond this will result in NULL being returned. Use [DATETIME](../datetime/index) as a storage type if you require dates beyond this.

 
### Error Handling

 Returns NULL for wrong arguments to `UNIX_TIMESTAMP()`. In MySQL and MariaDB before 5.3 wrong arguments to `UNIX_TIMESTAMP()` returned 0. 

 ### Compatibility

 As you can see in the examples above, UNIX\_TIMESTAMP(constant-date-string) returns a timestamp with 6 decimals while [MariaDB 5.2](../what-is-mariadb-52/index) and before returns it without decimals. This can cause a problem if you are using UNIX\_TIMESTAMP() as a partitioning function. You can fix this by using [FLOOR](../floor/index)(UNIX\_TIMESTAMP(..)) or changing the date string to a date number, like 20080101000000. 

 Examples
--------

 
```
SELECT UNIX_TIMESTAMP();
+------------------+
| UNIX_TIMESTAMP() |
+------------------+
|       1269711082 |
+------------------+

SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19');
+---------------------------------------+
| UNIX_TIMESTAMP('2007-11-30 10:30:19') |
+---------------------------------------+
|                     1196436619.000000 |
+---------------------------------------+

SELECT UNIX_TIMESTAMP("2007-11-30 10:30:19.123456");
+----------------------------------------------+
| unix_timestamp("2007-11-30 10:30:19.123456") |
+----------------------------------------------+
|                            1196411419.123456 |
+----------------------------------------------+

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP('2007-11-30 10:30:19'));
+------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP('2007-11-30 10:30:19')) |
+------------------------------------------------------+
| 2007-11-30 10:30:19.000000                           |
+------------------------------------------------------+

SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP('2007-11-30 10:30:19')));
+-------------------------------------------------------------+
| FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP('2007-11-30 10:30:19'))) |
+-------------------------------------------------------------+
| 2007-11-30 10:30:19                                         |
+-------------------------------------------------------------+

```

See Also
--------

 * [FROM\_UNIXTIME()](../from_unixtime/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/unix_timestamp/>

UPPER
=====

    Syntax
------

 
```
UPPER(str)

```

Description
-----------

 Returns the string `str` with all characters changed to uppercase according to the current character set mapping. The default is latin1 (cp1252 West European).

 
```
SELECT UPPER(surname), givenname FROM users ORDER BY surname;
+----------------+------------+
| UPPER(surname) | givenname  |
+----------------+------------+
| ABEL           | Jacinto    |
| CASTRO         | Robert     |
| COSTA          | Phestos    |
| MOSCHELLA      | Hippolytos |
+----------------+------------+

```

`UPPER()` is ineffective when applied to binary strings (`[BINARY](../binary/index)`, `[VARBINARY](../varbinary/index)`, `[BLOB](../blob/index)`). The description of `[LOWER](../lower/index)()` shows how to perform lettercase conversion of binary strings.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upper/>

UPDATEXML
=========

    Syntax
------

 
```
UpdateXML(xml_target, xpath_expr, new_xml)

```

Description
-----------

 This function replaces a single portion of a given fragment of XML markup `xml_target` with a new XML fragment `new_xml`, and then returns the changed XML. The portion of `xml_target` that is replaced matches an XPath expression `xpath_expr` supplied by the user. If no expression matching `xpath_expr` is found, or if multiple matches are found, the function returns the original `xml_target` XML fragment. All three arguments should be strings.

 Examples
--------

 
```
SELECT
    UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
    UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
    UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
    UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
    UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
    \G
*************************** 1. row ***************************
val1: <e>fff</e>
val2: <a><b>ccc</b><d></d></a>
val3: <a><e>fff</e><d></d></a>
val4: <a><b>ccc</b><e>fff</e></a>
val5: <a><d></d><b>ccc</b><d></d></a>
1 row in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/updatexml/>

USER
====

    Syntax
------

 
```
USER()

```

Description
-----------

 Returns the current MariaDB user name and host name, given when authenticating to MariaDB, as a string in the utf8 [character set](../data-types-character-sets-and-collations/index).

 Note that the value of USER() may differ from the value of [CURRENT\_USER()](../current_user/index), which is the user used to authenticate the current client. `[CURRENT\_ROLE()](../current_role/index)` returns the current active role.

 `SYSTEM_USER()` and `SESSION_USER` are synonyms for `USER()`.

 Statements using the `USER()` function or one of its synonyms are not [safe for statement level replication](../unsafe-statements-for-replication/index).

 Examples
--------

 
```
shell> mysql --user="anonymous"

SELECT USER(),CURRENT_USER();
+---------------------+----------------+
| USER()              | CURRENT_USER() |
+---------------------+----------------+
| anonymous@localhost | @localhost     |
+---------------------+----------------+

```

To select only the IP address, use [SUBSTRING\_INDEX()](../substring_index/index),

 
```
SELECT SUBSTRING_INDEX(USER(), '@', -1);
+----------------------------------+
| SUBSTRING_INDEX(USER(), '@', -1) |
+----------------------------------+
| 192.168.0.101                    |
+----------------------------------+

```

See Also
--------

 * [CURRENT\_USER()](../current_user/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user/>

UTC\_DATE
=========

    Syntax
------

 
```
UTC_DATE, UTC_DATE()

```

Description
-----------

 Returns the current [UTC date](../coordinated-universal-time/index) as a value in 'YYYY-MM-DD' or YYYYMMDD format, depending on whether the function is used in a string or numeric context. 

 Examples
--------

 
```
SELECT UTC_DATE(), UTC_DATE() + 0;
+------------+----------------+
| UTC_DATE() | UTC_DATE() + 0 |
+------------+----------------+
| 2010-03-27 |       20100327 |
+------------+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/utc_date/>

UTC\_TIME
=========

    Syntax
------

 
```
UTC_TIME
UTC_TIME([precision])

```

Description
-----------

 Returns the current [UTC time](../coordinated-universal-time/index) as a value in 'HH:MM:SS' or HHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context. 

 The optional *precision* determines the microsecond precision. See [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 Examples
--------

 
```
SELECT UTC_TIME(), UTC_TIME() + 0;
+------------+----------------+
| UTC_TIME() | UTC_TIME() + 0 |
+------------+----------------+
| 17:32:34   |  173234.000000 |
+------------+----------------+

```

With precision:

 
```
SELECT UTC_TIME(5);
+----------------+
| UTC_TIME(5)    |
+----------------+
| 07:52:50.78369 |
+----------------+

```

See Also
--------

 * [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/utc_time/>

UTC\_TIMESTAMP
==============

    Syntax
------

 
```
UTC_TIMESTAMP
UTC_TIMESTAMP([precision])

```

Description
-----------

 Returns the current [UTC](../coordinated-universal-time/index) date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format, depending on whether the function is used in a string or numeric context.

 The optional *precision* determines the microsecond precision. See [Microseconds in MariaDB](../microseconds-in-mariadb/index).

 Examples
--------

 
```
SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
+---------------------+-----------------------+
| UTC_TIMESTAMP()     | UTC_TIMESTAMP() + 0   |
+---------------------+-----------------------+
| 2010-03-27 17:33:16 | 20100327173316.000000 |
+---------------------+-----------------------+

```

With precision:

 
```
SELECT UTC_TIMESTAMP(4);
+--------------------------+
| UTC_TIMESTAMP(4)         |
+--------------------------+
| 2018-07-10 07:51:09.1019 |
+--------------------------+

```

See Also
--------

 * [Time Zones](../time-zones/index)
* [Microseconds in MariaDB](../microseconds-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/utc_timestamp/>

UUID
====

    Syntax
------

 
```
UUID()

```
 Description
-----------

 Returns a Universally Unique Identifier (UUID).

 A UUID is designed as a number that is globally unique in space and time. Two calls to `UUID()` are expected to generate two different values, even if these calls are performed on two separate computers that are not connected to each other.

 
UUID() results are intended to be unique, but cannot always be relied upon to unpredictable and unguessable, so should not be relied upon for these purposes.

 
A UUID is a 128-bit number represented by a utf8 string of five hexadecimal numbers in `aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee` format:

 * The first three numbers are generated from a timestamp.
* The fourth number preserves temporal uniqueness in case the timestamp value loses monotonicity (for example, due to daylight saving time).
* The fifth number is an IEEE 802 node number that provides spatial uniqueness. A random number is substituted if the latter is not available (for example, because the host computer has no Ethernet card, or we do not know how to find the hardware address of an interface on your operating system). In this case, spatial uniqueness cannot be guaranteed. Nevertheless, a collision should have very low probability.

 Currently, the MAC address of an interface is taken into account only on FreeBSD and Linux. On other operating systems, MariaDB uses a randomly generated 48-bit number.

 Statements using the UUID() function are not [safe for replication](../unsafe-statements-for-replication/index).

 The results are generated according to the "DCE 1.1:Remote Procedure Call" (Appendix A) CAE (Common Applications Environment) Specifications published by The Open Group in October 1997 ([Document Number C706](http://www.opengroup.org/public/pubs/catalog/c706.htm)).

 Examples
--------

 
```
SELECT UUID();
+--------------------------------------+
| UUID()                               |
+--------------------------------------+
| cd41294a-afb0-11df-bc9b-00241dd75637 |
+--------------------------------------+

```

See Also
--------

 * [UUID\_SHORT()](../uuid_short/index) - Return short (64 bit) Universal Unique Identifier
* [SYS\_GUID](../sys_guid/index) - UUID without the `-` character for Oracle compatibility
* [UUID data type](../uuid-data-type/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uuid/>

UUID\_SHORT
===========

    Syntax
------

 
```
UUID_SHORT()

```
 Description
-----------

 Returns a "short" universally unique identifier as a 64-bit unsigned integer (rather than a string-form 128-bit identifier as returned by the [UUID()](../uuid/index) function).

 The value of `UUID_SHORT()` is guaranteed to be unique if the following conditions hold:

 * The server\_id of the current host is unique among your set of master and slave servers
* `server_id` is between 0 and 255
* You don't set back your system time for your server between mysqld restarts
* You do not invoke `UUID_SHORT()` on average more than 16 million times per second between mysqld restarts

 The UUID\_SHORT() return value is constructed this way:

 
```
  (server_id & 255) << 56
+ (server_startup_time_in_seconds << 24)
+ incremented_variable++;

```

Statements using the UUID\_SHORT() function are not [safe for statement-based replication](../unsafe-statements-for-replication/index).

 Examples
--------

 
```
SELECT UUID_SHORT();
+-------------------+
| UUID_SHORT()      |
+-------------------+
| 21517162376069120 |
+-------------------+

```


```
create table t1 (a bigint unsigned default(uuid_short()) primary key);
insert into t1 values(),();
select * from t1;
+-------------------+
| a                 |
+-------------------+
| 98113699159474176 |
| 98113699159474177 |
+-------------------+

```

See Also
--------

 * [UUID()](../uuid/index) ; Return full (128 bit) Universally Unique Identifier
* [AUTO\_INCREMENT](../auto_increment/index)
* [Sequences](../sequences/index) - an alternative to auto\_increment available from [MariaDB 10.3](../what-is-mariadb-103/index)
* [SYS\_GUID](../sys_guid/index) - UUID without the `-` character for Oracle compatibility
* [UUID data type](../uuid-data-type/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uuid_short/>

VALUES / VALUE
==============

    Syntax
------

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**
```
VALUE(col_name) 

```



**MariaDB until [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**
```
VALUES(col_name) 

```


Description
-----------

 In an [INSERT ... ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) statement, you can use the `VALUES(col_name)` function in the [UPDATE](../update/index) clause to refer to column values from the [INSERT](../insert/index) portion of the statement. In other words, `VALUES(col_name)` in the `UPDATE` clause refers to the value of col\_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.

 The `VALUES()` function is meaningful only in `INSERT ... ON DUPLICATE KEY UPDATE` statements and returns `NULL` otherwise.

 In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) this function was renamed to `VALUE()`, because it's incompatible with the standard Table Value Constructors syntax, implemented in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

 The `VALUES()` function can still be used even from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), but only in `INSERT ... ON DUPLICATE KEY UPDATE` statements; it's a syntax error otherwise.

 Examples
--------

 
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**
```
INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)
    ON DUPLICATE KEY UPDATE c=VALUE(a)+VALUE(b);

```



**MariaDB until [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**
```
INSERT INTO t (a,b,c) VALUES (1,2,3),(4,5,6)
    ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/values-value/>

VAR\_POP
========

    Syntax
------

 
```
VAR_POP(expr)

```
 Description
-----------

 Returns the population standard variance of `expr`. It considers rows as the whole population, not as a sample, so it has the number of rows as the denominator. You can also use [VARIANCE()](../variance/index), which is equivalent but is not standard SQL.

 Variance is calculated by

 * working out the mean for the set
* for each number, subtracting the mean and squaring the result
* calculate the average of the resulting differences

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 VAR\_POP() can be used as a [window function](../window-functions/index).

 VAR\_POP() returns `NULL` if there were no matching rows.

 Examples
--------

 
```
CREATE TABLE v(i tinyint);

INSERT INTO v VALUES(101),(99);

SELECT VAR_POP(i) FROM v;
+------------+
| VAR_POP(i) |
+------------+
|     1.0000 |
+------------+

INSERT INTO v VALUES(120),(80);

SELECT VAR_POP(i) FROM v;
+------------+
| VAR_POP(i) |
+------------+
|   200.5000 |
+------------+

```

As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_POP(score) 
  OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         287.1875 |
| Esben   | SQL    |    43 |         287.1875 |
| Kaolin  | SQL    |    56 |         287.1875 |
| Tatiana | SQL    |    87 |         287.1875 |
| Chun    | Tuning |    73 |         582.0000 |
| Esben   | Tuning |    31 |         582.0000 |
| Kaolin  | Tuning |    88 |         582.0000 |
+---------+--------+-------+------------------+

```

See Also
--------

 * [VARIANCE](../variance/index) (equivalent, non-standard SQL)
* [STDDEV\_POP](../stddev_pop/index) (population standard deviation)
* [STDDEV\_SAMP](../stddev_samp/index) (sample standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/var_pop/>

VAR\_SAMP
=========

    Syntax
------

 
```
VAR_SAMP(expr)

```
 Description
-----------

 Returns the sample variance of *`expr`*. That is, the denominator is the number of rows minus one.

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 VAR\_SAMP() can be used as a [window function](../window-functions/index).

 VAR\_SAMP() returns `NULL` if there were no matching rows.

 Examples
--------

 As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_SAMP(score) 
  OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         382.9167 |
| Chun    | Tuning |    73 |         873.0000 |
| Esben   | SQL    |    43 |         382.9167 |
| Esben   | Tuning |    31 |         873.0000 |
| Kaolin  | SQL    |    56 |         382.9167 |
| Kaolin  | Tuning |    88 |         873.0000 |
| Tatiana | SQL    |    87 |         382.9167 |
+---------+--------+-------+------------------+

```

See Also
--------

 * [VAR\_POP](../var_pop/index) (variance)
* [STDDEV\_POP](../stddev_pop/index) (population standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/var_samp/>

VARIANCE
========

    Syntax
------

 
```
VARIANCE(expr) 

```
 Description
-----------

 Returns the population standard variance of `expr`. This is an extension to standard SQL. The standard SQL function [VAR\_POP()](../var_pop/index) can be used instead.

 Variance is calculated by

 * working out the mean for the set
* for each number, subtracting the mean and squaring the result
* calculate the average of the resulting differences

 It is an [aggregate function](../aggregate-functions/index), and so can be used with the [GROUP BY](../group-by/index) clause.

 VARIANCE() can be used as a [window function](../window-functions/index).

 VARIANCE() returns `NULL` if there were no matching rows.

 Examples
--------

 
```
CREATE TABLE v(i tinyint);

INSERT INTO v VALUES(101),(99);

SELECT VARIANCE(i) FROM v;
+-------------+
| VARIANCE(i) |
+-------------+
|      1.0000 |
+-------------+

INSERT INTO v VALUES(120),(80);

SELECT VARIANCE(i) FROM v;
+-------------+
| VARIANCE(i) |
+-------------+
|    200.5000 |
+-------------+

```

As an [aggregate function](../aggregate-functions/index):

 
```
CREATE OR REPLACE TABLE stats (category VARCHAR(2), x INT);

INSERT INTO stats VALUES 
  ('a',1),('a',2),('a',3),
  ('b',11),('b',12),('b',20),('b',30),('b',60);

SELECT category, STDDEV_POP(x), STDDEV_SAMP(x), VAR_POP(x) 
  FROM stats GROUP BY category;
+----------+---------------+----------------+------------+
| category | STDDEV_POP(x) | STDDEV_SAMP(x) | VAR_POP(x) |
+----------+---------------+----------------+------------+
| a        |        0.8165 |         1.0000 |     0.6667 |
| b        |       18.0400 |        20.1693 |   325.4400 |
+----------+---------------+----------------+------------+

```

As a [window function](../window-functions/index):

 
```
CREATE OR REPLACE TABLE student_test (name CHAR(10), test CHAR(10), score TINYINT);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, VAR_POP(score) 
  OVER (PARTITION BY test) AS variance_results FROM student_test;
+---------+--------+-------+------------------+
| name    | test   | score | variance_results |
+---------+--------+-------+------------------+
| Chun    | SQL    |    75 |         287.1875 |
| Chun    | Tuning |    73 |         582.0000 |
| Esben   | SQL    |    43 |         287.1875 |
| Esben   | Tuning |    31 |         582.0000 |
| Kaolin  | SQL    |    56 |         287.1875 |
| Kaolin  | Tuning |    88 |         582.0000 |
| Tatiana | SQL    |    87 |         287.1875 |
+---------+--------+-------+------------------+

```

See Also
--------

 * [VAR\_POP](../var_pop/index) (equivalent, standard SQL)
* [STDDEV\_POP](../stddev_pop/index) (population standard deviation)
* [STDDEV\_SAMP](../stddev_samp/index) (sample standard deviation)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/variance/>

VERSION
=======

    Syntax
------

 
```
VERSION()

```

Description
-----------

 Returns a string that indicates the MariaDB server version. The string uses the utf8 [character set](../data-types-character-sets-and-collations/index).

 Examples
--------

 
```
SELECT VERSION();
+----------------+
| VERSION()      |
+----------------+
| 10.4.7-MariaDB |
+----------------+

```

The `VERSION()` string may have one or more of the following suffixes:

 


| Suffix | Description |
| --- | --- |
| -embedded | The server is an embedded server (libmariadbd). |
| -log | General logging, slow logging or binary (replication) logging is enabled. |
| -debug | The server is compiled for debugging. |
| -valgrind |  The server is compiled to be instrumented with valgrind. |

 
Changing the Version String
---------------------------

 Some old legacy code may break because they are parsing the `VERSION` string and expecting a MySQL string or a simple version string like Joomla til API17, see [MDEV-7780](https://jira.mariadb.org/browse/MDEV-7780).

 One can fool these applications by setting the version string from the command line or the my.cnf files with [--version=...](../server-system-variables/index#version).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/version/>

WEEK
====

    Syntax
------

 
```
WEEK(date[,mode])

```

Description
-----------

 This function returns the week number for `date`. The two-argument form of `WEEK()` allows you to specify whether the week starts on Sunday or Monday and whether the return value should be in the range from 0 to 53 or from 1 to 53. If the `mode` argument is omitted, the value of the [default\_week\_format](../server-system-variables/index#default_week_format) system variable is used.

 ### Modes

 


| Mode | 1st day of week | Range | Week 1 is the 1st week with |
| --- | --- | --- | --- |
| 0 | Sunday | 0-53 | a Sunday in this year |
| 1 | Monday | 0-53 | more than 3 days this year |
| 2 | Sunday | 1-53 | a Sunday in this year |
| 3 | Monday | 1-53 | more than 3 days this year |
| 4 | Sunday | 0-53 | more than 3 days this year |
| 5 | Monday | 0-53 | a Monday in this year |
| 6 | Sunday | 1-53 | more than 3 days this year |
| 7 | Monday | 1-53 | a Monday in this year |

 
With the mode value of 3, which means 'more than 3 days this year', weeks are numbered according to ISO 8601:1988.

 Examples
--------

 
```
SELECT WEEK('2008-02-20');
+--------------------+
| WEEK('2008-02-20') |
+--------------------+
|                  7 |
+--------------------+

SELECT WEEK('2008-02-20',0);
+----------------------+
| WEEK('2008-02-20',0) |
+----------------------+
|                    7 |
+----------------------+

SELECT WEEK('2008-02-20',1);
+----------------------+
| WEEK('2008-02-20',1) |
+----------------------+
|                    8 |
+----------------------+

SELECT WEEK('2008-12-31',0);
+----------------------+
| WEEK('2008-12-31',0) |
+----------------------+
|                   52 |
+----------------------+

SELECT WEEK('2008-12-31',1);
+----------------------+
| WEEK('2008-12-31',1) |
+----------------------+
|                   53 |
+----------------------+

 SELECT WEEK('2019-12-30',3);
+----------------------+
| WEEK('2019-12-30',3) |
+----------------------+
|                    1 |
+----------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d, WEEK(d,0), WEEK(d,1) from t1;
+---------------------+-----------+-----------+
| d                   | WEEK(d,0) | WEEK(d,1) |
+---------------------+-----------+-----------+
| 2007-01-30 21:31:07 |         4 |         5 |
| 1983-10-15 06:42:51 |        41 |        41 |
| 2011-04-21 12:34:56 |        16 |        16 |
| 2011-10-30 06:31:41 |        44 |        43 |
| 2011-01-30 14:03:25 |         5 |         4 |
| 2004-10-07 11:19:34 |        40 |        41 |
+---------------------+-----------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/week/>

WEEKDAY
=======

    Syntax
------

 
```
WEEKDAY(date)

```

Description
-----------

 Returns the weekday index for `date` (`0` = Monday, `1` = Tuesday, ... `6` = Sunday).

 This contrasts with `[DAYOFWEEK()](../dayofweek/index)` which follows the ODBC standard (`1` = Sunday, `2` = Monday, ..., `7` = Saturday).

 Examples
--------

 
```
SELECT WEEKDAY('2008-02-03 22:23:00');
+--------------------------------+
| WEEKDAY('2008-02-03 22:23:00') |
+--------------------------------+
|                              6 |
+--------------------------------+

SELECT WEEKDAY('2007-11-06');
+-----------------------+
| WEEKDAY('2007-11-06') |
+-----------------------+
|                     1 |
+-----------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT d FROM t1 where WEEKDAY(d) = 6;
+---------------------+
| d                   |
+---------------------+
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/weekday/>

WEEKOFYEAR
==========

    Syntax
------

 
```
WEEKOFYEAR(date)

```

Description
-----------

 Returns the calendar week of the date as a number in the range from 1 to 53. `WEEKOFYEAR()` is a compatibility function that is equivalent to `[WEEK(date,3)](../week/index)`.

 Examples
--------

 
```
SELECT WEEKOFYEAR('2008-02-20');
+--------------------------+
| WEEKOFYEAR('2008-02-20') |
+--------------------------+
|                        8 |
+--------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
 select * from t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+

```


```
SELECT d, WEEKOFYEAR(d), WEEK(d,3) from t1;
+---------------------+---------------+-----------+
| d                   | WEEKOFYEAR(d) | WEEK(d,3) |
+---------------------+---------------+-----------+
| 2007-01-30 21:31:07 |             5 |         5 |
| 1983-10-15 06:42:51 |            41 |        41 |
| 2011-04-21 12:34:56 |            16 |        16 |
| 2011-10-30 06:31:41 |            43 |        43 |
| 2011-01-30 14:03:25 |             4 |         4 |
| 2004-10-07 11:19:34 |            41 |        41 |
+---------------------+---------------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/weekofyear/>

WEIGHT\_STRING
==============

    Syntax
------

 
```
WEIGHT_STRING(str [AS {CHAR|BINARY}(N)] [LEVEL levels] [flags])
  levels: N [ASC|DESC|REVERSE] [, N [ASC|DESC|REVERSE]] ... 

```

Description
-----------

 Returns a binary string representing the string's sorting and comparison value. A string with a lower result means that for sorting purposes the string appears before a string with a higher result.

 WEIGHT\_STRING() is particularly useful when adding new collations, for testing purposes.

 If `str` is a non-binary string ([CHAR](../char/index), [VARCHAR](../varchar/index) or [TEXT](../text/index)), WEIGHT\_STRING returns the string's collation weight. If `str` is a binary string ([BINARY](../binary/index), [VARBINARY](../varbinary/index) or [BLOB](../blob/index)), the return value is simply the input value, since the weight for each byte in a binary string is the byte value.

 WEIGHT\_STRING() returns NULL if given a NULL input. 

 The optional AS clause permits casting the input string to a binary or non-binary string, as well as to a particular length.

 AS BINARY(N) measures the length in bytes rather than characters, and right pads with 0x00 bytes to the desired length. 

 AS CHAR(N) measures the length in characters, and right pads with spaces to the desired length.

 N has a minimum value of 1, and if it is less than the length of the input string, the string is truncated without warning.

 The optional LEVEL clause specifies that the return value should contain weights for specific collation levels. The `levels` specifier can either be a single integer, a comma-separated list of integers, or a range of integers separated by a dash (whitespace is ignored). Integers can range from 1 to a maximum of 6, dependent on the collation, and need to be listed in ascending order.

 If the LEVEL clause is no provided, a default of 1 to the maximum for the collation is assumed.

 If the LEVEL is specified without using a range, an optional modifier is permitted.

 `ASC`, the default, returns the weights without any modification.

 `DESC` returns bitwise-inverted weights.

 `REVERSE` returns the weights in reverse order.

 Examples
--------

 The examples below use the [HEX()](../hex/index) function to represent non-printable results in hexadecimal format.

 
```
SELECT HEX(WEIGHT_STRING('x'));
+-------------------------+
| HEX(WEIGHT_STRING('x')) |
+-------------------------+
| 0058                    |
+-------------------------+

SELECT HEX(WEIGHT_STRING('x' AS BINARY(4)));
+--------------------------------------+
| HEX(WEIGHT_STRING('x' AS BINARY(4))) |
+--------------------------------------+
| 78000000                             |
+--------------------------------------+

SELECT HEX(WEIGHT_STRING('x' AS CHAR(4)));
+------------------------------------+
| HEX(WEIGHT_STRING('x' AS CHAR(4))) |
+------------------------------------+
| 0058002000200020                   |
+------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1));
+--------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1)) |
+--------------------------------------+
| AA22EE                               |
+--------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC));
+-------------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 DESC)) |
+-------------------------------------------+
| 55DD11                                    |
+-------------------------------------------+

SELECT HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE));
+----------------------------------------------+
| HEX(WEIGHT_STRING(0xaa22ee LEVEL 1 REVERSE)) |
+----------------------------------------------+
| EE22AA                                       |
+----------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/weight_string/>

WITHIN
======

    Syntax
------

 
```
Within(g1,g2)

```

Description
-----------

 Returns `1` or `0` to indicate whether `g1` is spatially within `g2`. This tests the opposite relationship as `[Contains()](../contains/index)`.

 WITHIN() is based on the original MySQL implementation, and uses object bounding rectangles, while [ST\_WITHIN()](../st_within/index) uses object shapes.

 Examples
--------

 
```
SET @g1 = GEOMFROMTEXT('POINT(174 149)');
SET @g2 = GEOMFROMTEXT('POINT(176 151)');
SET @g3 = GEOMFROMTEXT('POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))');

SELECT within(@g1,@g3);
+-----------------+
| within(@g1,@g3) |
+-----------------+
|               1 |
+-----------------+

SELECT within(@g2,@g3);
+-----------------+
| within(@g2,@g3) |
+-----------------+
|               0 |
+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/within/>

WSREP\_LAST\_SEEN\_GTID
=======================

    
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**WSREP\_LAST\_SEEN\_GTID was added as part of Galera 4 in [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

 
Syntax
------

 
```
WSREP_LAST_SEEN_GTID()

```

Description
-----------

 Returns the [Global Transaction ID](../gtid/index) of the most recent write transaction observed by the client.

 The result can be useful to determine the transaction to provide to [WSREP\_SYNC\_WAIT\_UPTO\_GTID](../wsrep_sync_wait_upto_gtid/index) for waiting and unblocking purposes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wsrep_last_seen_gtid/>

WSREP\_LAST\_WRITTEN\_GTID
==========================

    
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**WSREP\_LAST\_WRITTEN\_GTID was added as part of Galera 4 in [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

 
Syntax
------

 
```
WSREP_LAST_WRITTEN_GTID()

```

Description
-----------

 Returns the [Global Transaction ID](../gtid/index) of the most recent write transaction performed by the client.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wsrep_last_written_gtid/>

WSREP\_SYNC\_WAIT\_UPTO\_GTID
=============================

    
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**WSREP\_SYNC\_WAIT\_UPTO\_GTID was added as part of Galera 4 in [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

 
Syntax
------

 
```
WSREP_SYNC_WAIT_UPTO_GTID(gtid[,timeout])

```

Description
-----------

 Blocks the client until the transaction specified by the given [Global Transaction ID](../gtid/index) is applied and committed by the node.

 The optional *timeout* argument can be used to specify a block timeout in seconds. If not provided, the timeout will be indefinite.

 Returns the node that applied and committed the Global Transaction ID, `ER_LOCAL_WAIT_TIMEOUT` if the function is timed out before this, or `ER_WRONG_ARGUMENTS` if the function is given an invalid GTID.

 The result from [WSREP\_LAST\_SEEN\_GTID](../wsrep_last_seen_gtid/index) can be useful to determine the transaction to provide to WSREP\_SYNC\_WAIT\_UPTO\_GTID for waiting and unblocking purposes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wsrep_sync_wait_upto_gtid/>

YEARWEEK
========

    Syntax
------

 
```
YEARWEEK(date), YEARWEEK(date,mode)

```

Description
-----------

 Returns year and week for a date. The mode argument works exactly like the mode argument to [WEEK()](../week/index). The year in the result may be different from the year in the date argument for the first and the last week of the year.

 Examples
--------

 
```
SELECT YEARWEEK('1987-01-01');
+------------------------+
| YEARWEEK('1987-01-01') |
+------------------------+
|                 198652 |
+------------------------+

```


```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+
6 rows in set (0.02 sec)

```


```
SELECT YEARWEEK(d) FROM t1 WHERE YEAR(d) = 2011;
+-------------+
| YEARWEEK(d) |
+-------------+
|      201116 |
|      201144 |
|      201105 |
+-------------+
3 rows in set (0.03 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/yearweek/>

YEAR
====

    Syntax
------

 
```
YEAR(date)

```

Description
-----------

 Returns the year for the given date, in the range 1000 to 9999, or 0 for the "zero" date.

 Examples
--------

 
```
CREATE TABLE t1 (d DATETIME);
INSERT INTO t1 VALUES
    ("2007-01-30 21:31:07"),
    ("1983-10-15 06:42:51"),
    ("2011-04-21 12:34:56"),
    ("2011-10-30 06:31:41"),
    ("2011-01-30 14:03:25"),
    ("2004-10-07 11:19:34");

```


```
SELECT * FROM t1;
+---------------------+
| d                   |
+---------------------+
| 2007-01-30 21:31:07 |
| 1983-10-15 06:42:51 |
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
| 2004-10-07 11:19:34 |
+---------------------+

SELECT * FROM t1 WHERE YEAR(d) = 2011;
+---------------------+
| d                   |
+---------------------+
| 2011-04-21 12:34:56 |
| 2011-10-30 06:31:41 |
| 2011-01-30 14:03:25 |
+---------------------+

```


```
SELECT YEAR('1987-01-01');
+--------------------+
| YEAR('1987-01-01') |
+--------------------+
|               1987 |
+--------------------+

```

See Also
--------

 * [YEAR data type](../year-data-type/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/year/>

Full-Text Index Stopwords
=========================

     Stopwords are used to provide a list of commonly-used words that can be ignored for the purposes of [Full-text-indexes](../full-text-indexes/index).

 Full-text indexes built in [MyISAM](../myisam/index) and [InnoDB](../innodb/index) have different stopword lists by default.

 MyISAM Stopwords
----------------

 For full-text indexes on MyISAM tables, by default, the list is built from the file `storage/myisam/ft_static.c`, and searched using the server's character set and collation. The [ft\_stopword\_file](../server-system-variables/index#ft_stopword_file) system variable allows the default list to be overridden with words from another file, or for stopwords to be ignored altogether.

 If the stopword list is changed, any existing full-text indexes need to be rebuilt

 The following table shows the default list of stopwords, although you should always treat `storage/myisam/ft_static.c` as the definitive list. See the [Fulltext Index Overview](../fulltext-index-overview/index) for more details, and [Full-text-indexes](../full-text-indexes/index) for related articles.

 


|  |  |  |  |
| --- | --- | --- | --- |
| a's | able | about | above |
| according | accordingly | across | actually |
| after | afterwards | again | against |
| ain't | all | allow | allows |
| almost | alone | along | already |
| also | although | always | am |
| among | amongst | an | and |
| another | any | anybody | anyhow |
| anyone | anything | anyway | anyways |
| anywhere | apart | appear | appreciate |
| appropriate | are | aren't | around |
| as | aside | ask | asking |
| associated | at | available | away |
| awfully | be | became | because |
| become | becomes | becoming | been |
| before | beforehand | behind | being |
| believe | below | beside | besides |
| best | better | between | beyond |
| both | brief | but | by |
| c'mon | c's | came | can |
| can't | cannot | cant | cause |
| causes | certain | certainly | changes |
| clearly | co | com | come |
| comes | concerning | consequently | consider |
| considering | contain | containing | contains |
| corresponding | could | couldn't | course |
| currently | definitely | described | despite |
| did | didn't | different | do |
| does | doesn't | doing | don't |
| done | down | downwards | during |
| each | edu | eg | eight |
| either | else | elsewhere | enough |
| entirely | especially | et | etc |
| even | ever | every | everybody |
| everyone | everything | everywhere | ex |
| exactly | example | except | far |
| few | fifth | first | five |
| followed | following | follows | for |
| former | formerly | forth | four |
| from | further | furthermore | get |
| gets | getting | given | gives |
| go | goes | going | gone |
| got | gotten | greetings | had |
| hadn't | happens | hardly | has |
| hasn't | have | haven't | having |
| he | he's | hello | help |
| hence | her | here | here's |
| hereafter | hereby | herein | hereupon |
| hers | herself | hi | him |
| himself | his | hither | hopefully |
| how | howbeit | however | i'd |
| i'll | i'm | i've | ie |
| if | ignored | immediate | in |
| inasmuch | inc | indeed | indicate |
| indicated | indicates | inner | insofar |
| instead | into | inward | is |
| isn't | it | it'd | it'll |
| it's | its | itself | just |
| keep | keeps | kept | know |
| knows | known | last | lately |
| later | latter | latterly | least |
| less | lest | let | let's |
| like | liked | likely | little |
| look | looking | looks | ltd |
| mainly | many | may | maybe |
| me | mean | meanwhile | merely |
| might | more | moreover | most |
| mostly | much | must | my |
| myself | name | namely | nd |
| near | nearly | necessary | need |
| needs | neither | never | nevertheless |
| new | next | nine | no |
| nobody | non | none | noone |
| nor | normally | not | nothing |
| novel | now | nowhere | obviously |
| of | off | often | oh |
| ok | okay | old | on |
| once | one | ones | only |
| onto | or | other | others |
| otherwise | ought | our | ours |
| ourselves | out | outside | over |
| overall | own | particular | particularly |
| per | perhaps | placed | please |
| plus | possible | presumably | probably |
| provides | que | quite | qv |
| rather | rd | re | really |
| reasonably | regarding | regardless | regards |
| relatively | respectively | right | said |
| same | saw | say | saying |
| says | second | secondly | see |
| seeing | seem | seemed | seeming |
| seems | seen | self | selves |
| sensible | sent | serious | seriously |
| seven | several | shall | she |
| should | shouldn't | since | six |
| so | some | somebody | somehow |
| someone | something | sometime | sometimes |
| somewhat | somewhere | soon | sorry |
| specified | specify | specifying | still |
| sub | such | sup | sure |
| t's | take | taken | tell |
| tends | th | than | thank |
| thanks | thanx | that | that's |
| thats | the | their | theirs |
| them | themselves | then | thence |
| there | there's | thereafter | thereby |
| therefore | therein | theres | thereupon |
| these | they | they'd | they'll |
| they're | they've | think | third |
| this | thorough | thoroughly | those |
| though | three | through | throughout |
| thru | thus | to | together |
| too | took | toward | towards |
| tried | tries | truly | try |
| trying | twice | two | un |
| under | unfortunately | unless | unlikely |
| until | unto | up | upon |
| us | use | used | useful |
| uses | using | usually | value |
| various | very | via | viz |
| vs | want | wants | was |
| wasn't | way | we | we'd |
| we'll | we're | we've | welcome |
| well | went | were | weren't |
| what | what's | whatever | when |
| whence | whenever | where | where's |
| whereafter | whereas | whereby | wherein |
| whereupon | wherever | whether | which |
| while | whither | who | who's |
| whoever | whole | whom | whose |
| why | will | willing | wish |
| with | within | without | won't |
| wonder | would | wouldn't | yes |
| yet | you | you'd | you'll |
| you're | you've | your | yours |
| yourself | yourselves | zero |  |

 
InnoDB Stopwords
----------------

 Stopwords on full-text indexes are only enabled if the [innodb\_ft\_enable\_stopword](../xtradbinnodb-server-system-variables/index#innodb_ft_enable_stopword) system variable is set (by default it is) at the time the index was created.

 The stopword list is determined as follows:

 * If the [innodb\_ft\_user\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_user_stopword_table) system variable is set, that table is used as a stopword list.
* If `innodb_ft_user_stopword_table` is not set, the table set by [innodb\_ft\_server\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_server_stopword_table) is used.
* If neither variable is set, the built-in list is used, which can be viewed by querying the [INNODB\_FT\_DEFAULT\_STOPWORD table](../information-schema-innodb_ft_default_stopword-table/index) in the [Information Schema](../information_schema/index).

 In the first two cases, the specified table must exist at the time the system variable is set and the full-text index created. It must be an InnoDB table with a single column, a [VARCHAR](../varchar/index) named VALUE.

 The default InnoDB stopword list differs from the default MyISAM list, being much shorter, and contains the following words:

 


|  |  |  |  |
| --- | --- | --- | --- |
| a | about | an | are |
| as | at | be | by |
| com | de | en | for |
| from | how | i | in |
| is | it | la | of |
| on | or | that | the |
| this | to | was | what |
| when | where | who | will |
| with | und | the | www |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/full-text-index-stopwords/>

Date and Time Units
===================

    The `INTERVAL` keyword can be used to add or subtract a time interval of time to a `[DATETIME](../datetime/index)`, `[DATE](../date/index)` or `[TIME](../time/index)` value.

 The syntax is:

 
```
INTERVAL time_quantity time_unit

```

For example, the `SECOND` unit is used below by the `[DATE\_ADD()](../date_add/index)` function:

 
```
SELECT '2008-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '2008-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 2009-01-01 00:00:00                       |
+-------------------------------------------+

```

The following units are valid:

 


| Unit | Description |
| --- | --- |
| `MICROSECOND` | Microseconds |
| `SECOND` | Seconds |
| `MINUTE` | Minutes |
| `HOUR` | Hours |
| `DAY` | Days |
| `WEEK` | Weeks |
| `MONTH` | Months |
| `QUARTER` | Quarters |
| `YEAR` | Years |
| `SECOND_MICROSECOND` | Seconds.Microseconds |
| `MINUTE_MICROSECOND` | Minutes.Seconds.Microseconds |
| `MINUTE_SECOND` | Minutes.Seconds |
| `HOUR_MICROSECOND` | Hours.Minutes.Seconds.Microseconds |
| `HOUR_SECOND` | Hours.Minutes.Seconds |
| `HOUR_MINUTE` | Hours.Minutes |
| `DAY_MICROSECOND` | Days Hours.Minutes.Seconds.Microseconds |
| `DAY_SECOND` | Days Hours.Minutes.Seconds |
| `DAY_MINUTE` | Days Hours.Minutes |
| `DAY_HOUR` | Days Hours |
| `YEAR_MONTH` | Years-Months |

 
The time units containing an underscore are composite; that is, they consist of multiple base time units. For base time units, `time_quantity` is an integer number. For composite units, the quantity must be expressed as a string with multiple integer numbers separated by any punctuation character.

 Example of composite units:

 
```
INTERVAL '2:2' YEAR_MONTH
INTERVAL '1:30:30' HOUR_SECOND
INTERVAL '1!30!30' HOUR_SECOND -- same as above

```

Time units can be used in the following contexts:

 * after a `[+](../addition-operator/index)` or a `[-](../subtraction-operator-/index)` operator;
* with the following `DATE` or `TIME` functions: `[ADDDATE()](../adddate/index)`, `[SUBDATE()](../subdate/index)`, `[DATE\_ADD()](../date_add/index)`, `[DATE\_SUB()](../date_sub/index)`, `[TIMESTAMPADD()](../timestampadd/index)`, `[TIMESTAMPDIFF()](../timestampdiff/index)`, `[EXTRACT()](../extract/index)`;
* in the `ON SCHEDULE` clause of `[CREATE EVENT](../create-event/index)` and `[ALTER EVENT](../alter-event/index)`.
* when defining a [partitioning](../create-table/index#partitions) `BY SYSTEM_TIME`

 See also
--------

 * [Date and time literals](../date-and-time-literals/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date-and-time-units/>

Regular Expressions Functions
==============================

   MariaDB includes a number of functions for dealing with regular expressions.

  

| Title | Description |
| --- | --- |
|  [Regular Expressions Overview](../regular-expressions-overview/index) |  Regular Expressions allow MariaDB to perform complex pattern matching on a string.  |
|  [PCRE - Perl Compatible Regular Expressions](../pcre/index) |  PCRE (Perl Compatible Regular Expressions) for enhanced regular expressions.  |
|  [NOT REGEXP](../not-regexp/index) |  Same as NOT (expr REGEXP pat).  |
|  [REGEXP](../regexp/index) |  Performs pattern matching  |
|  [REGEXP\_INSTR](../regexp_instr/index) |  Position of the first appearance of a regex.  |
|  [REGEXP\_REPLACE](../regexp_replace/index) |  Replaces all occurrences of a pattern.  |
|  [REGEXP\_SUBSTR](../regexp_substr/index) |  Returns the matching part of a string.  |
|  [RLIKE](../rlike/index) |  Synonym for REGEXP  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regular-expressions-functions/>

Microseconds in MariaDB
=======================

     The [TIME](../time/index), [DATETIME](../datetime/index), and [TIMESTAMP](../timestamp/index) types, along with the temporal functions, [CAST](../cast/index) and [dynamic columns](../dynamic-columns/index), support microseconds. The datetime precision of a column can be specified when creating the table with [CREATE TABLE](../create-table/index), for example:

 
```
CREATE TABLE example(
  col_microsec DATETIME(6),
  col_millisec TIME(3)
);

```

Generally, the precision can be specified for any `TIME`, `DATETIME`, or `TIMESTAMP` column, in parentheses, after the type name. The datetime precision specifies number of digits after the decimal dot and can be any integer number from 0 to 6. If no precision is specified it is assumed to be 0, for backward compatibility reasons.

 A datetime precision can be specified wherever a type name is used. For example:

 * when declaring arguments of stored routines.
* when specifying a return type of a stored function.
* when declaring variables.
* in a `CAST` function:
```
create function example(x datetime(5)) returns time(4)
begin
  declare y timestamp(6);
  return cast(x as time(2));
end;

```

 `%f` is used as the formatting option for microseconds in the [STR\_TO\_DATE](../str_to_date/index), [DATE\_FORMAT](../date_format/index) and [FROM\_UNIXTIME](../from_unixtime/index) functions, for example:

 
```
SELECT STR_TO_DATE('20200809 020917076','%Y%m%d %H%i%s%f');
+-----------------------------------------------------+
| STR_TO_DATE('20200809 020917076','%Y%m%d %H%i%s%f') |
+-----------------------------------------------------+
| 2020-08-09 02:09:17.076000                          |
+-----------------------------------------------------+

```

Additional Information
----------------------

 * when comparing anything to a temporal value (`DATETIME`, `TIME`, `[DATE](../date/index)`, or `TIMESTAMP`), both values are compared as temporal values, not as strings.
* The [INFORMATION\_SCHEMA.COLUMNS table](../information-schema-columns-table/index) has a new column `DATETIME_PRECISION`
* [NOW()](../now/index), [CURTIME()](../curtime/index), [UTC\_TIMESTAMP()](../utc_timestamp/index), [UTC\_TIME()](../utc_time/index), [CURRENT\_TIME()](../current_time/index), [CURRENT\_TIMESTAMP()](../current_timestamp/index), [LOCALTIME()](../localtime/index) and [LOCALTIMESTAMP()](../localtimestamp/index) now accept datetime precision as an optional argument. For example:
```
SELECT CURTIME(4);
--> 10:11:12.3456

```
* [TIME\_TO\_SEC()](../time_to_sec/index) and [UNIX\_TIMESTAMP()](../unix_timestamp/index) preserve microseconds of the argument. These functions will return a [decimal](../decimal/index) number if the result non-zero datetime precision and an [integer](../int/index) otherwise (for backward compatibility).
```
SELECT TIME_TO_SEC('10:10:10.12345');
--> 36610.12345

```
* Current versions of this patch fix a bug in the following optimization: in certain queries with `DISTINCT` MariaDB can ignore this clause if it can prove that all result rows are unique anyway, for example, when a primary key is compared with a constant. Sometimes this optimization was applied incorrectly, though — for example, when comparing a string with a date constant. This is now fixed.
* `DATE_ADD()` and `DATE_SUB()` functions can now take a `TIME` expression as an argument (not just `DATETIME` as before).
```
SELECT TIME('10:10:10') + INTERVAL 100 MICROSECOND;
--> 10:10:10.000100

```
* The `event_time` field in the [mysql.general\_log](../mysqlgeneral_log-table/index) table and the `start_time`, `query_time`, and `lock_time` fields in the [mysql.slow\_log](../mysqlslow_log-table/index) table now store values with microsecond precision.
* This patch fixed a bug when comparing a temporal value using the `BETWEEN` operator and one of the operands is `NULL`.
* The old syntax `TIMESTAMP(N)`, where `N` is the display width, is no longer supported. It was deprecated in MySQL 4.1.0 (released on 2003-04-03).
* when a `DATETIME` value is compared to a `TIME` value, the latter is treated as a full datetime with a zero date part, similar to comparing `DATE` to a `DATETIME`, or to comparing `DECIMAL` numbers. Earlier versions of MariaDB used to compare only the time part of both operands in such a case.
* In MariaDB, an extra column `[TIME\_MS](../time_ms-column-in-information_schemaprocesslist/index)` has been added to the `[INFORMATION\_SCHEMA.PROCESSLIST](../information-schema-processlist-table/index)` table, as well as to the output of `[SHOW FULL PROCESSLIST](../show-processlist/index)`.

 
**Note:** When you convert a temporal value to a value with a smaller precision, it will be truncated, not rounded. This is done to guarantee that the date part is not changed. For example:



```
SELECT CAST('2009-12-31 23:59:59.998877' as DATETIME(3));
-> 2009-12-31 23:59:59.998

```
 
MySQL 5.6 Microseconds
----------------------

 MySQL 5.6 introduced microseconds using a slightly different implementation to [MariaDB 5.3](../what-is-mariadb-53/index). Since [MariaDB 10.1](../what-is-mariadb-101/index), MariaDB has defaulted to the MySQL format, by means of the [--mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format) variable. The MySQL version requires slightly [more storage](../data-type-storage-requirements/index) but has some advantages in permitting the eventual support of negative dates, and in replication.

 See Also
--------

 * [Data Type Storage Requirements](../data-type-storage-requirements/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/microseconds-in-mariadb/>

Stored Aggregate Functions
==========================

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**The ability to create stored aggregate functions was added in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

  [Aggregate functions](../aggregate-functions/index) are functions that are computed over a sequence of rows and return one result for the sequence of rows.

 Creating a custom aggregate function is done using the [CREATE FUNCTION](../create-function/index) statement with two main differences:

 * The addition of the AGGREGATE keyword, so `CREATE AGGREGATE FUNCTION`
* The `FETCH GROUP NEXT ROW` instruction inside the loop
* Oracle PL/SQL compatibility using SQL/PL is provided

 Standard Syntax
---------------

 
```
CREATE AGGREGATE FUNCTION function_name (parameters) RETURNS return_type
BEGIN
      All types of declarations
      DECLARE CONTINUE HANDLER FOR NOT FOUND RETURN return_val;
      LOOP
           FETCH GROUP NEXT ROW; // fetches next row from table
           other instructions
      END LOOP;
END

```

Stored aggregate functions were a [2016 Google Summer of Code](../google-summer-of-code-2016/index) project by Varun Gupta.

 ### Using SQL/PL

 
```
SET sql_mode=Oracle;
DELIMITER //

CREATE AGGREGATE FUNCTION function_name (parameters) RETURN return_type
   declarations
BEGIN
   LOOP
      FETCH GROUP NEXT ROW; -- fetches next row from table
      -- other instructions

   END LOOP;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      RETURN return_val;
END //

DELIMITER ;

```

Examples
--------

 First a simplified example:

 
```
CREATE TABLE marks(stud_id INT, grade_count INT);

INSERT INTO marks VALUES (1,6), (2,4), (3,7), (4,5), (5,8);

SELECT * FROM marks;
+---------+-------------+
| stud_id | grade_count |
+---------+-------------+
|       1 |           6 |
|       2 |           4 |
|       3 |           7 |
|       4 |           5 |
|       5 |           8 |
+---------+-------------+

DELIMITER //
CREATE AGGREGATE FUNCTION IF NOT EXISTS aggregate_count(x INT) RETURNS INT
BEGIN
 DECLARE count_students INT DEFAULT 0;
 DECLARE CONTINUE HANDLER FOR NOT FOUND
 RETURN count_students;
      LOOP
          FETCH GROUP NEXT ROW;
          IF x  THEN
            SET count_students = count_students+1;
          END IF;
      END LOOP;
END //
DELIMITER ;

```

A non-trivial example that cannot easily be rewritten using existing functions:

 
```
DELIMITER //
CREATE AGGREGATE FUNCTION medi_int(x INT) RETURNS DOUBLE
BEGIN
  DECLARE CONTINUE HANDLER FOR NOT FOUND
    BEGIN
      DECLARE res DOUBLE;
      DECLARE cnt INT DEFAULT (SELECT COUNT(*) FROM tt);
      DECLARE lim INT DEFAULT (cnt-1) DIV 2;
      IF cnt % 2 = 0 THEN
        SET res = (SELECT AVG(a) FROM (SELECT a FROM tt ORDER BY a LIMIT lim,2) ttt);
      ELSE
        SET res = (SELECT a FROM tt ORDER BY a LIMIT lim,1);
      END IF;
      DROP TEMPORARY TABLE tt;
      RETURN res;
    END;
  CREATE TEMPORARY TABLE tt (a INT);
  LOOP
    FETCH GROUP NEXT ROW;
    INSERT INTO tt VALUES (x);
  END LOOP;
END //
DELIMITER ;

```

### SQL/PL Example

 This uses the same marks table as created above.

 
```
SET sql_mode=Oracle;
DELIMITER //

CREATE AGGREGATE FUNCTION aggregate_count(x INT) RETURN INT AS count_students INT DEFAULT 0;
BEGIN
   LOOP
      FETCH GROUP NEXT ROW;
      IF x  THEN
        SET count_students := count_students+1;
      END IF;
   END LOOP;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      RETURN count_students;
END aggregate_count //
DELIMITER ;

SELECT aggregate_count(stud_id) FROM marks;

```

See Also
--------

 * [Stored Function Overview](../stored-function-overview/index)
* [CREATE FUNCTION](../create-function/index)
* [SHOW CREATE FUNCTION](../show-create-function/index)
* [DROP FUNCTION](../drop-function/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-aggregate-functions/>

LENGTHB
=======

    
**MariaDB starting with [10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)**Introduced in [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) as part of the [Oracle compatibility enhancements](../sql_modeoracle/index).

 
Syntax
------

 
```
LENGTHB(str)

```

Description
-----------

 `LENGTHB()` returns the length of the given string, in bytes. When [Oracle mode](../sql_modeoracle/index) is not set, this is a synonym for [LENGTH](../length/index).

 A multi-byte character counts as multiple bytes. This means that for a string containing five two-byte characters, `LENGTHB()` returns 10, whereas [CHAR\_LENGTH()](../char_length/index) returns 5. 

 If `str` is not a string value, it is converted into a string. If `str` is `NULL`, the function returns `NULL`.

 Examples
--------

 When [Oracle mode](../sql_modeoracle/index) from [MariaDB 10.3](../what-is-mariadb-103/index) is not set:

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            2 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

In [Oracle mode from MariaDB 10.3](../sql_modeoracle/index#functions):

 
```
SELECT CHAR_LENGTH('π'), LENGTH('π'), LENGTHB('π'), OCTET_LENGTH('π');
+-------------------+--------------+---------------+--------------------+
| CHAR_LENGTH('π')  | LENGTH('π')  | LENGTHB('π')  | OCTET_LENGTH('π')  |
+-------------------+--------------+---------------+--------------------+
|                 1 |            1 |             2 |                  2 |
+-------------------+--------------+---------------+--------------------+

```

See Also
--------

 * [CHAR\_LENGTH()](../char_length/index)
* [LENGTH()](../length/index)
* [OCTET\_LENGTH()](../octet_length/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lengthb/>

Aria Status Variables
=====================

    This page documents status variables related to the [Aria storage engine](../aria/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Aria_pagecache_blocks_not_flushed`

 * **Description:** The number of dirty blocks in the Aria page cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_blocks_unused`

 * **Description:** Free blocks in the Aria page cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_blocks_used`

 * **Description:** Blocks used in the Aria page cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_read_requests`

 * **Description:** The number of requests to read something from the Aria page cache.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_reads`

 * **Description:** The number of Aria page cache read requests that caused a block to be read from the disk.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_write_requests`

 * **Description:** The number of requests to write a block to the Aria page cache.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_pagecache_writes`

 * **Description:** The number of blocks written to disk from the Aria page cache.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Aria_transaction_log_syncs`

 * **Description:** The number of Aria log fsyncs.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-server-status-variables/>

TRIM\_ORACLE
============

    
**MariaDB starting with [10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/)**`TRIM_ORACLE` is a synonym for the [Oracle mode](../sql_modeoracle/index) version of the [TRIM function](../trim/index), and is available in all modes.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/trim_oracle/>

Aria System Variables
=====================

     This page documents system variables related to the [Aria storage engine](../aria/index). For options that are not system variables, see [Aria Options](../mysqld-options/index#aria-storage-engine-options). 

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting system variables.

 Also see the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `aria_block_size`

 * **Description:** Block size to be used for Aria index pages. Changing this requires dumping, deleting old tables and deleting all log files, and then restoring your Aria tables. If key lookups take too long (and one has to search roughly 8192/2 by default to find each key), can be made smaller, e.g. `4096`.
* **Commandline:** `--aria-block-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `8192`
* **Range:**
	+ >= [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/): `4096` to `32768` in increments of `1024`
	+ <= [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/): `1024` to `32768` in increments of `1024`

 

---

 #### `aria_checkpoint_interval`

 * **Description:** Interval in seconds between automatic checkpoints. 0 means 'no automatic checkpoints' which makes sense only for testing.
* **Commandline:** `--aria-checkpoint-interval=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `30`
* **Range:** `0` to `4294967295`

 

---

 #### `aria_checkpoint_log_activity`

 * **Description:** Number of bytes that the transaction log has to grow between checkpoints before a new checkpoint is written to the log.
* **Commandline:** `aria-checkpoint-log-activity=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1048576`
* **Range** `0` to `4294967295`

 

---

 #### `aria_encrypt_tables`

 * **Description:** Enables automatic encryption of all user-created Aria tables that have the `[ROW\_FORMAT](../create-table/index#row_format)` table option set to `[PAGE](../aria-storage-formats/index#page)`. See [Data at Rest Encryption](../data-at-rest-encryption/index) and [Enabling Encryption for User-created Tables](../encrypting-data-for-aria/index#enabling-encryption-for-user-created-tables).
* **Commandline:** `aria-encrypt-tables={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `aria_force_start_after_recovery_failures`

 * **Description:** Number of consecutive log recovery failures after which logs will be automatically deleted to cure the problem; 0 (the default) disables the feature.
* **Commandline:** `--aria-force-start-after-recovery-failures=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

 #### `aria_group_commit`

 * **Description:** Specifies Aria [group commit mode](../aria-group-commit/index).
* **Commandline:** `--aria_group_commit="value"`
* **Alias:** `maria_group_commit`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Valid values:**
	+ `none` - *Group commit is disabled.*
	+ `hard` - *Wait the number of microseconds specified by aria\_group\_commit\_interval before actually doing the commit. If the interval is 0 then just check if any other threads have requested a commit during the time this commit was preparing (just before sync() file) and send their data to disk also before sync().*
	+ `soft` - *The service thread will wait the specified time and then sync() to the log. If the interval is 0 then it won't wait for any commits (this is dangerous and should generally not be used in production)*
* **Default Value:** `none`

 

---

 #### `aria_group_commit_interval`

 * **Description:** Interval between [Aria group commits](../aria-group-commit/index) in microseconds (1/1000000 second) for other threads to come and do a commit in "hard" mode and sync()/commit at all in "soft" mode. Option only has effect if [aria\_group\_commit](#aria_group_commit) is used.
* **Commandline:** `--aria_group_commit_interval=#`
* **Alias:** `maria_group_commit_interval`
* **Scope:** Global
* **Dynamic:** No
* **Type:** numeric
* **Valid Values:**
	+ **Default Value:** `0` *(no waiting)*
	+ **Range:** `0-4294967295`

 

---

 #### `aria_log_file_size`

 * **Description:** Limit for Aria transaction log size
* **Commandline:** `--aria-log-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1073741824`

 

---

 #### `aria_log_purge_type`

 * **Description:** Specifies how the Aria transactional log will be purged. Set to `at_flush` to keep a copy of the transaction logs (good as an extra backup). The logs will stay until the next [FLUSH LOGS](../flush/index);
* **Commandline:** `--aria-log-purge-type=name`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `immediate`
* **Valid Values:** `immediate`, `external`, `at_flush`

 

---

 #### `aria_max_sort_file_size`

 * **Description:** Don't use the fast sort index method to created index if the temporary file would get bigger than this.
* **Commandline:** `--aria-max-sort-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `9223372036853727232`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `aria_page_checksum`

 * **Description:** Determines whether index and data should use page checksums for extra safety. Can be overridden per table with PAGE\_CHECKSUM clause in [CREATE TABLE](../create-table/index).
* **Commandline:** `--aria-page-checksum=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `aria_pagecache_age_threshold`

 * **Description:** 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.
* **Commandline:** `--aria-pagecache-age-threshold=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `300`
* **Range:** `100` to `9999900`

 

---

 #### `aria_pagecache_buffer_size`

 * **Description:** The size of the buffer used for index and data blocks for Aria tables. This can include explicit Aria tables, system tables, and temporary tables. Increase this to get better handling and measure by looking at [aria-status-variables/#aria\_pagecache\_reads](../aria-status-variables/index#aria_pagecache_reads) (should be small) vs [aria-status-variables/#aria\_pagecache\_read\_requests](../aria-status-variables/index#aria_pagecache_read_requests).
* **Commandline:** `--aria-pagecache-buffer-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `134217720` (128MB)
* **Range:** `131072` (128KB) upwards

 

---

 #### `aria_pagecache_division_limit`

 * **Description:** The minimum percentage of warm blocks in the key cache.
* **Commandline:** `--aria-pagecache-division-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `1` to `100`

 

---

 #### `aria_pagecache_file_hash_size`

 * **Description:** Number of hash buckets for open and changed files. If you have many Aria files open you should increase this for faster flushing of changes. A good value is probably 1/10th of the number of possible open Aria files.
* **Commandline:** `--aria-pagecache-file-hash-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `512`
* **Range:** `128` to `16384`

 

---

 #### `aria_recover`

 * **Description:** `aria_recover` has been renamed to `aria_recover_options` in [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/). See [aria\_recover\_options](#aria_recover_options) for the description.

 

---

 #### `aria_recover_options`

 * **Description:** Specifies how corrupted tables should be automatically repaired. More than one option can be specified, for example `FORCE,BACKUP`.
	+ `NORMAL`: Normal automatic repair, the default until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)
	+ `OFF`: Autorecovery is disabled, the equivalent of not using the option
	+ `QUICK`: Does not check rows in the table if there are no delete blocks.
	+ `FORCE`: Runs the recovery even if it determines that more than one row from the data file will be lost.
	+ `BACKUP`: Keeps a backup of the data files.
* **Commandline:** `--aria-recover-options[=#]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:**
	+ `BACKUP,QUICK` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `NORMAL` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))
* **Valid Values:** `NORMAL`, `BACKUP`, `FORCE`, `QUICK`, `OFF`
* **Introduced:** [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/)

 

---

 #### `aria_repair_threads`

 * **Description:** Number of threads to use when repairing Aria tables. The value of 1 disables parallel repair. Increasing from the default will usually result in faster repair, but will use more CPU and memory.
* **Commandline:** `--aria-repair-threads=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`

 

---

 #### `aria_sort_buffer_size`

 * **Description:** The buffer that is allocated when sorting the index when doing a [REPAIR](../repair-table/index) or when creating indexes with [CREATE INDEX](../create-index/index) or [ALTER TABLE](../alter-table/index).
* **Commandline:** `--aria-sort-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `268434432`

 

---

 #### `aria_stats_method`

 * **Description:** Determines how NULLs are treated for Aria index statistics purposes. If set to `nulls_equal`, all NULL index values are treated as a single group. This is usually fine, but if you have large numbers of NULLs the average group size is slanted higher, and the optimizer may miss using the index for ref accesses when it would be useful. If set to `nulls_unequal`, the default, the opposite approach is taken, with each NULL forming its own group of one. Conversely, the average group size is slanted lower, and the optimizer may use the index for ref accesses when not suitable. Setting to `nulls_ignored` ignores NULLs altogether from index group calculations. Statistics need to be recalculated after this method is changed. See also [Index Statistics](../index-statistics/index), [myisam\_stats\_method](../myisam-server-system-variables/index#myisam_stats_method) and [innodb\_stats\_method](../xtradbinnodb-server-system-variables/index#innodb_stats_method).
* **Commandline:** `--aria-stats-method=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `nulls_unequal`
* **Valid Values:** `nulls_equal`, `nulls_unequal`, `nulls_ignored`

 

---

 #### `aria_sync_log_dir`

 * **Description:** Controls syncing directory after log file growth and new file creation.
* **Commandline:** `--aria-sync-log-dir=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `NEWFILE`
* **Valid Values:** `NEWFILE`, `NEVER`, `ALWAYS`

 

---

 #### `aria_used_for_temp_tables`

 * **Description:** Readonly variable indicating whether the [Aria](../aria/index) storage engine is used for temporary tables. If set to `ON`, the default, the Aria storage engine is used. If set to `OFF`, MariaDB reverts to using [MyISAM](../myisam/index) for on-disk temporary tables. The [MEMORY](../memory-storage-engine/index) storage engine is used for temporary tables regardless of this variable's setting where appropriate. The default can be changed by not using the `--with-aria-tmp-tables` option when building MariaDB.
* **Commandline:** No
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `deadlock_search_depth_long`

 * **Description:** Long search depth for the [two-step deadlock detection](../aria-two-step-deadlock-detection/index). Only used by the [Aria](../aria/index) storage engine.
* **Commandline:** `--deadlock-search-depth-long=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `15`
* **Range:** `0` to `33`

 

---

 #### `deadlock_search_depth_short`

 * **Description:** Short search depth for the [two-step deadlock detection](../aria-two-step-deadlock-detection/index). Only used by the [Aria](../aria/index) storage engine.
* **Commandline:** `--deadlock-search-depth-short=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `4`
* **Range:** `0` to `32`

 

---

 #### `deadlock_timeout_long`

 * **Description:** Long timeout in microseconds for the [two-step deadlock detection](../aria-two-step-deadlock-detection/index). Only used by the [Aria](../aria/index) storage engine.
* **Commandline:** `--deadlock-timeout-long=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `50000000`
* **Range:** `0` to `4294967295`

 

---

 #### `deadlock_timeout_short`

 * **Description:** Short timeout in microseconds for the [two-step deadlock detection](../aria-two-step-deadlock-detection/index). Only used by the [Aria](../aria/index) storage engine.
* **Commandline:** `--deadlock-timeout-short=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10000`
* **Range:** `0` to `4294967295`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-server-system-variables/>

SFORMAT
=======

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**SFORMAT was added in [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/).

 
Description
-----------

 The `SFORMAT` function takes an input string and a formatting specification and returns the string formatted using the rules the user passed in the specification.

 It uses the [fmtlib library](https://fmt.dev/) for Python-like (as well as Rust, C++20, etc) string formatting.

 Only fmtlib 7.0.0+ is supported.

 There is no native support for temporal and decimal values:

 * TIME\_RESULT is handled as STRING\_RESULT
* DECIMAL\_RESULT as REAL\_RESULT

 Examples
--------

 
```
SELECT SFORMAT("The answer is {}.", 42);
+----------------------------------+
| SFORMAT("The answer is {}.", 42) |
+----------------------------------+
| The answer is 42.                |
+----------------------------------+

CREATE TABLE test_sformat(mdb_release char(6), mdev int, feature char(20));

INSERT INTO test_sformat VALUES('10.7.0', 25015, 'Python style sformat'), 
  ('10.7.0', 4958, 'UUID');

SELECT * FROM test_sformat;
+-------------+-------+----------------------+
| mdb_release | mdev  | feature              |
+-------------+-------+----------------------+
| 10.7.0      | 25015 | Python style sformat |
| 10.7.0      |  4958 | UUID                 |
+-------------+-------+----------------------+

SELECT SFORMAT('MariaDB Server {} has a preview for MDEV-{} which is about {}', 
  mdb_release, mdev, feature) AS 'Preview Release Examples'
  FROM test_sformat;
+----------------------------------------------------------------------------------------+
| Preview Release Examples                                                               |
+----------------------------------------------------------------------------------------+
| MariaDB Server 10.7.0 has a preview for MDEV-25015 which is about Python style sformat |
| MariaDB Server 10.7.0 has a preview for MDEV-4958 which is about UUID                  |
+----------------------------------------------------------------------------------------+

```

See Also
--------

 * [10.7 preview feature: Python-like string formatting](https://mariadb.org/10-7-preview-feature-sformat/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sformat/>

JSON\_ARRAYAGG
==============

    
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**JSON\_ARRAYAGG was added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
Syntax
------

 
```
JSON_ARRAYAGG(column_or_expression)

```

Description
-----------

 `JSON_ARRAYAGG` returns a JSON array containing an element for each value in a given set of JSON or SQL values. It acts on a column or an expression that evaluates to a single value. 

 Returns NULL in the case of an error, or if the result contains no rows.

 `JSON_ARRAYAGG` cannot currently be used as a [window function](../window-functions/index).

 The full syntax is as follows:

 
```
JSON_ARRAYAGG([DISTINCT] expr [,expr ...]
             [ORDER BY {unsigned_integer | col_name | expr}
                 [ASC | DESC] [,col_name ...]]
             [LIMIT {[offset,] row_count | row_count OFFSET offset}])

```

Examples
--------

 
```
CREATE TABLE t1 (a INT, b INT);

INSERT INTO t1 VALUES (1, 1),(2, 1), (1, 1),(2, 1), (3, 2),(2, 2),(2, 2),(2, 2);

SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
+-------------------+-------------------+
| JSON_ARRAYAGG(a)  | JSON_ARRAYAGG(b)  |
+-------------------+-------------------+
| [1,2,1,2,3,2,2,2] | [1,1,1,1,2,2,2,2] |
+-------------------+-------------------+

SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1 GROUP BY b;
+------------------+------------------+
| JSON_ARRAYAGG(a) | JSON_ARRAYAGG(b) |
+------------------+------------------+
| [1,2,1,2]        | [1,1,1,1]        |
| [3,2,2,2]        | [2,2,2,2]        |
+------------------+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_arrayagg/>

Storage-Engine Independent Column Compression
=============================================

    
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**Storage-engine independent support for column compression was introduced in [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

  Storage-engine independent column compression enables [TINYBLOB](../tinyblob/index), [BLOB](../blob/index), [MEDIUMBLOB](../mediumblob/index), [LONGBLOB](../longblob/index), [TINYTEXT](../tinytext/index), [TEXT](../text/index), [MEDIUMTEXT](../mediumtext/index), [LONGTEXT](../longtext/index), [VARCHAR](../varchar/index) and [VARBINARY](../varbinary/index) columns to be compressed.

 This is performed by means of a new COMPRESSED [column attribute](../create-table/index#column-and-index-definitions): `COMPRESSED[=<compression_method>]`

 Currently the only supported compression method is `zlib`.

 ### Field Length Compatibility

 When using the `COMPRESSED` attribute, note that FIELD LENGTH is reduced by 1; for example, a BLOB has a length of 65535, while BLOB COMPRESSED has 65535-1. See [MDEV-15592](https://jira.mariadb.org/browse/MDEV-15592).

 ### New System Variables

 #### `column_compression_threshold`

 * **Description:** Minimum column data length eligible for compression.
* **Commandline:** `--column-compression-threshold=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `0` to `4294967295`

 

---

 #### `column_compression_zlib_level`

 * **Description:** zlib compression level (1 gives best speed, 9 gives best compression).
* **Commandline:** `--column-compression-zlib-level=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `6`
* **Range:** `1` to `9`

 

---

 #### `column_compression_zlib_strategy`

 * **Description:** 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.
* **Commandline:** `--column-compression-zlib-strategy=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `DEFAULT_STRATEGY`
* **Valid Values:** `DEFAULT_STRATEGY`, `FILTERED`, `HUFFMAN_ONLY`, `RLE`, `FIXED`

 

---

 #### `column_compression_zlib_wrap`

 * **Description:** If set to `1` (`0` is default), 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.
* **Commandline:** `--column-compression-zlib-wrap{=0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 ### New Status Variables

 #### `Column_compressions`

 * **Description:** Incremented each time field data is compressed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Column_decompressions`

 * **Description:** Incremented each time field data is decompressed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 ### Limitations

 * The only supported method currently is zlib.
* The [CSV](../csv/index) storage engine stores data uncompressed on-disk even if the COMPRESSED attribute is present.
* It is not possible to create indexes over compressed columns.

 ### Comparison with InnoDB Page Compression

 Storage-independent column compression is different to [InnoDB Page Compression](../innodb-page-compression/index) in a number of ways.

 * It is storage engine independent, while InnoDB page compression applies to InnoDB only.
* By being specific to a column, one can access non-compressed fields without the decompression overhead.
* Only zlib is available, while InnoDB page compression can offer alternative compression algorithms.
* It is not recommended to use multiple forms of compression over the same data.
* It is intended for compressing large blobs, while InnoDB page compression is suitable for a more general case.
* Columns cannot be indexed, while with InnoDB page compression indexes are possible as usual.

 ### Examples

 
```
CREATE TABLE cmp (i TEXT COMPRESSED);

CREATE TABLE cmp2 (i TEXT COMPRESSED=zlib);

```

### See Also

 * [InnoDB Page Compression](../innodb-page-compression/index)
* [InnoDB Compressed Row Format](../innodb-compressed-row-format/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engine-independent-column-compression/>

Feedback Plugin
===============

    
The Feedback plugin is not currently working.

 
The `feedback` plugin is designed to collect and, optionally, upload configuration and usage information to [MariaDB.org](http://mariadb.org/) or to any other configured URL.

 
See the [MariaDB User Feedback](http://mariadb.org/feedback_plugin/) page on MariaDB.org to see collected MariaDB usage statistics.

 
The `feedback` plugin exists in all MariaDB versions.

 MariaDB is distributed with this plugin included, but it is not enabled by default. On Windows, this plugin is part of the server and has a special checkbox in the installer window. Either way, you need to explicitly install and enable it in order for feedback data to be sent. 

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'feedback';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = feedback

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'feedback';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Enabling the Plugin
-------------------

 You can enable the plugin by setting the `[feedback](#feedback)` option to `ON` in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
feedback=ON

```

In Windows, the plugin can also be enabled during a new [MSI](../installing-mariadb-msi-packages-on-windows/index) installation. The MSI GUI installation provides the "Enable feedback plugin" checkbox to enable the plugin. The MSI command-line installation provides the FEEDBACK=1 command-line option to enable the plugin.

 See the next section for how to verify the plugin is installed and active and (if needed) install the plugin.

 Verifying the Plugin's Status
-----------------------------

 To verify whether the `feedback` plugin is installed and enabled, execute the `[SHOW PLUGINS](../show-plugins/index)` statement or query the `[information\_schema.plugins](../plugins-table-information-schema/index)` table. For example:

 
```
SELECT plugin_status FROM information_schema.plugins 
  WHERE plugin_name = 'feedback';

```

If that `SELECT` returns no rows, then you still need to [install the plugin](#installing-the-plugin).

 When the plugin is installed and enabled, you will see:

 
```
SELECT plugin_status FROM information_schema.plugins 
  WHERE plugin_name = 'feedback';
+---------------+
| plugin_status |
+---------------+
| ACTIVE        |
+---------------+

```

If you see `DISABLED` instead of `ACTIVE`, then you still need to [enable the plugin](#enabling-the-plugin).

 Collecting Data
---------------

 The `feedback` plugin will collect:

 * Certain rows from [SHOW STATUS](../show-status/index) and [SHOW VARIABLES](../show-variables/index).
* All installed [plugins](../plugins/index) and their versions.
* System information such as CPU count, memory, architecture, and OS/linux distribution.
* The [feedback\_server\_uid](#feedback_server_uid), which is a SHA1 hash of the MAC address of the first network interface and the TCP port that the server listens on.

 The `feedback` plugin creates the [FEEDBACK](../information-schema-feedback-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. To see the data that has been collected by the plugin, you can execute:

 
```
SELECT * FROM information_schema.feedback;

```

Only the contents of this table are sent to the [feedback\_url](#feedback_url).

 MariaDB stores collation usage statistics. Each collation that has been used by the server will have a record in "SELECT \* FROM information\_schema.feedback" output, for example:

 
```
+----------------------------------------+---------------------+
| VARIABLE_NAME                          | VARIABLE_VALUE      |
+----------------------------------------+---------------------+
| Collation used utf8_unicode_ci         | 10                  |
| Collation used latin1_general_ci       | 20                  |
+----------------------------------------+---------------------+

```

Collations that have not been used will not be included into the result.

 Sending Data
------------

 The `feedback` plugin sends the data using a `POST` request to any URL or a list of URLs that you specify by setting the [feedback\_url](#feedback_url) system variable. By default, this is set to the following URL:

 * <https://mariadb.org/feedback_plugin/post>

 Both HTTP and HTTPS protocols are supported. 

 If HTTP traffic requires a proxy in your environment, then you can specify the proxy by setting the [feedback\_http\_proxy](#feedback_http_proxy) system variable.

 If the [feedback\_url](#feedback_url) system variable is not set to an empty string, then the plugin will automatically send a report to all URLs in the list a few minutes after the server starts up and then once a week after that.

 If the [feedback\_url](#feedback_url) system variable is set to an empty string, then the plugin will **not** automatically send any data. This may be necessary if outbound HTTP communication from your database server is not permitted. In this case, you can still upload the data manually, if you'd like.

 First, generate the report file with the MariaDB command-line [mariadb](../mariadb-command-line-client/index) client:

 
```
$ mariadb -e 'select * from information_schema.feedback' > report.txt

```

Then you can upload the generated `report.txt` [here](https://mariadb.org/feedback_plugin/post) using your web browser.

 Or you can do it from the command line with tools such as [curl](https://curl.haxx.se/docs/manpage.html). For example:

 
```
$ curl -F data=@report.txt https://mariadb.org/feedback_plugin/post

```

Manual uploading allows you to be absolutely sure that we receive only the data shown in the [INFORMATION\_SCHEMA.FEEDBACK](../information-schema-feedback-table/index) table and that no private or sensitive information is being sent.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.1 | Stable | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.1 | Beta | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/), [MariaDB 5.3.3](https://mariadb.com/kb/en/mariadb-533-release-notes/) |

 
System Variables
----------------

 ### `feedback_http_proxy`

 * **Description:** Proxy server for use when http calls cannot be made, such as in a firewall environment. The format is `host:port`.
* **Commandline:** `--feedback-http=proxy=value`
* **Read-only:** Yes
* **Data Type:** string
* **Default Value:** `''` (empty)

 

---

 ### `feedback_send_retry_wait`

 * **Description:** Time in seconds before retrying if the plugin failed to send the data for any reason.
* **Commandline:** `--feedback-send-retry-wait=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `60`
* **Valid Values:** `1` to `86400`

 

---

 ### `feedback_send_timeout`

 * **Description:** An attempt to send the data times out and fails after this many seconds.
* **Commandline:** `--feedback-send-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `60`
* **Valid Values:** `1` to `86400`

 

---

 ### `feedback_server_uid`

 * **Description:** Automatically calculated server unique id hash.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** string

 

---

 ### `feedback_url`

 * **Description:** URL to which the data is sent. More than one URL, separated by spaces, can be specified. Set it to an empty string to disable data sending.
* **Commandline:** `--feedback-url=url`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** string
* **Default Value:** `<https://mariadb.org/feedback_plugin/post>`

 

---

 ### `feedback_user_info`

 * **Description:** The value of this option is not used by the plugin, but it is included in the feedback data. It can be used to add any user-specified string to the report. This could be used to help to identify it. For example, a support contract number, or a computer name (if you collect reports internally by specifying your own `feedback-url`).
* **Commandline:** `--feedback-user-info=string`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** string
* **Default Value:** Empty string

 

---

 Options
-------

 ### `feedback`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--feedback=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/feedback-plugin/>

Type Conversion
===============

     Implicit type conversion takes place when MariaDB is using operands or different types, in order to make the operands compatible.

 It is best practice not to rely upon implicit conversion; rather use [CAST](../cast/index) to explicitly convert types.

 ### Rules for Conversion on Comparison

 * If either argument is NULL, the result of the comparison is NULL unless the NULL-safe [<=>](../null-safe-equal/index) equality comparison operator is used.
* If both arguments are integers, they are compared as integers.
* If both arguments are strings, they are compared as strings.
* If one argument is decimal and the other argument is decimal or integer, they are compared as decimals.
* If one argument is decimal and the other argument is a floating point, they are compared as floating point values.
* If one argument is string and the other argument is integer, they are compared as decimals. This conversion was added in [MariaDB 10.3.36](https://mariadb.com/kb/en/mariadb-10336-release-notes/). Prior to 10.3.36, this combination was compared as floating point values, which did not always work well for huge 64-bit integers because of a possible precision loss on conversion to double.
* If a hexadecimal argument is not compared to a number, it is treated as a binary string.
* If a constant is compared to a TIMESTAMP or DATETIME, the constant is converted to a timestamp, unless used as an argument to the [IN](../in/index) function.
* In other cases, arguments are compared as floating point, or real, numbers.

 Note that if a string column is being compared with a numeric value, MariaDB will not use the index on the column, as there are numerous alternatives that may evaluate as equal (see examples below).

 #### Comparison Examples

 Converting a string to a number:

 
```
SELECT 15+'15';
+---------+
| 15+'15' |
+---------+
|      30 |
+---------+

```

Converting a number to a string:

 
```
SELECT CONCAT(15,'15');
+-----------------+
| CONCAT(15,'15') |
+-----------------+
| 1515            |
+-----------------+

```

Floating point number errors:

 
```
SELECT '9746718491924563214' = 9746718491924563213;
+---------------------------------------------+
| '9746718491924563214' = 9746718491924563213 |
+---------------------------------------------+
|                                           1 |
+---------------------------------------------+

```

Numeric equivalence with strings:

 
```
SELECT '5' = 5;
+---------+
| '5' = 5 |
+---------+
|       1 |
+---------+

SELECT '   5' = 5;
+------------+
| '   5' = 5 |
+------------+
|          1 |
+------------+

SELECT '   5  ' = 5;
+--------------+
| '   5  ' = 5 |
+--------------+
|            1 |
+--------------+
1 row in set, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+--------------------------------------------+
| Level | Code | Message                                    |
+-------+------+--------------------------------------------+
| Note  | 1292 | Truncated incorrect DOUBLE value: '   5  ' |
+-------+------+--------------------------------------------+

```

As a result of the above, MariaDB cannot use the index when comparing a string with a numeric value in the example below:

 
```
CREATE TABLE t (a VARCHAR(10), b VARCHAR(10), INDEX idx_a (a));

INSERT INTO t VALUES 
  ('1', '1'), ('2', '2'), ('3', '3'), 
  ('4', '4'), ('5', '5'), ('1', '5');

EXPLAIN SELECT * FROM t WHERE a = '3' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ref
possible_keys: idx_a
          key: idx_a
      key_len: 13
          ref: const
         rows: 1
        Extra: Using index condition

EXPLAIN SELECT * FROM t WHERE a = 3 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ALL
possible_keys: idx_a
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 6
        Extra: Using where

```

### Rules for Conversion on Dyadic Arithmetic Operations

 Implicit type conversion also takes place on dyadic arithmetic operations ([+](../addition-operator/index),[-](../subtraction-operator-/index),[\*](../multiplication-operator/index),[/](../division-operator/index)). MariaDB chooses the minimum data type that is guaranteed to fit the result and converts both arguments to the result data type.

 For [addition (+)](../addition-operator/index), [subtraction (-)](../subtraction-operator-/index) and [multiplication (\*)](../multiplication-operator/index), the result data type is chosen as follows:

 * If either of the arguments is an approximate number (float, double), the result is double.
* If either of the arguments is a string (char, varchar, text), the result is double.
* If either of the arguments is a decimal number, the result is decimal.
* If either of the arguments is of a temporal type with a non-zero fractional second precision (time(N), datetime(N), timestamp(N)), the result is decimal.
* If either of the arguments is of a temporal type with a zero fractional second precision (time(0), date, datetime(0), timestamp(0)), the result may vary between int, int unsigned, bigint or bigint unsigned, depending on the exact data type combination.
* If both arguments are integer numbers (tinyint, smallint, mediumint, bigint), the result may vary between int, int unsigned, bigint or bigint unsigned, depending of the exact data types and their signs.

 For [division (/)](../division-operator/index), the result data type is chosen as follows:

 * If either of the arguments is an approximate number (float, double), the result is double.
* If either of the arguments is a string (char, varchar, text), the result is double.
* Otherwise, the result is decimal.

 #### Arithmetic Examples

 Note, the above rules mean that when an argument of a temporal data type appears in addition or subtraction, it's treated as a number by default.

 
```
SELECT TIME'10:20:30' + 1;
+--------------------+
| TIME'10:20:30' + 1 |
+--------------------+
|             102031 |
+--------------------+

```

In order to do temporal addition or subtraction instead, use the [DATE\_ADD()](../date_add/index) or [DATE\_SUB()](../date_sub/index) functions, or an [INTERVAL](../date-and-time-units/index) expression as the second argument:

 
```
SELECT TIME'10:20:30' + INTERVAL 1 SECOND;
+------------------------------------+
| TIME'10:20:30' + INTERVAL 1 SECOND |
+------------------------------------+
| 10:20:31                           |
+------------------------------------+

```


```
SELECT "2.2" + 3;
+-----------+
| "2.2" + 3 |
+-----------+
|       5.2 |
+-----------+

SELECT 2.2 + 3;
+---------+
| 2.2 + 3 |
+---------+
| 5.2     |
+---------+

SELECT 2.2 / 3;
+---------+
| 2.2 / 3 |
+---------+
| 0.73333 |
+---------+

SELECT "2.2" / 3;
+--------------------+
| "2.2" / 3          |
+--------------------+
| 0.7333333333333334 |
+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/type-conversion/>

Authentication Plugin - GSSAPI
==============================

    The `gssapi` authentication plugin allows the user to authenticate with services that use the [Generic Security Services Application Program Interface (GSSAPI)](https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface). Windows has a slightly different but very similar API called [Security Support Provider Interface (SSPI)](https://docs.microsoft.com/en-us/windows/desktop/secauthn/sspi). The GSSAPI is a standardized API described in [RFC2743](https://tools.ietf.org/html/rfc2743.html) and [RFC2744](https://tools.ietf.org/html/rfc2744.html). The client and server negotiate using a standardized protocol described in [RFC7546](https://tools.ietf.org/html/rfc7546.html).

 On Windows, this authentication plugin supports [Kerberos](https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-kerberos) and [NTLM](https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-ntlm) authentication. Windows authentication is supported regardless of whether a [domain](https://en.wikipedia.org/wiki/Windows_domain) is used in the environment.

 On Unix systems, the most dominant GSSAPI service is [Kerberos](https://en.wikipedia.org/wiki/Kerberos_(protocol)). However, it is less commonly used on Unix systems than it is on Windows. Regardless, this authentication plugin also supports Kerberos authentication on Unix.

 The `gssapi` authentication plugin is most often used for authenticating with [Microsoft Active Directory](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview).

 This article gives instructions on configuring the `gssapi` authentication plugin for MariaDB for passwordless login.

 Installing the Plugin's Package
-------------------------------

 Since [MariaDB 10.11](../what-is-mariadb-1011/index), on Windows, the plugin is included in the server, and there is no need for separate installation.

 The `gssapi` authentication plugin's shared library is included in MariaDB packages as the `auth_gssapi.so` or `auth_gssapi.dll` shared library on systems where it can be built.

 ### Installing on Linux

 The `gssapi` authentication plugin is included in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 #### Installing with a Package Manager

 The `gssapi` authentication plugin can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 ##### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-gssapi-server

```

##### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 
```
sudo apt-get install mariadb-plugin-gssapi-server

```

##### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-gssapi-server

```

### Installing on Windows

 Since [MariaDB 10.11](../what-is-mariadb-1011/index), the plugin is included in the server, and there is no need for separate installation.

 Before [MariaDB 10.11](../what-is-mariadb-1011/index), the `gssapi` authentication plugin is included in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 Installing the Plugin
---------------------

 Since [MariaDB 10.11](../what-is-mariadb-1011/index), on Windows, the plugin is included in the server, and there is no need for separate installation.

 Before [MariaDB 10.11](../what-is-mariadb-1011/index) on Windows, and on other operating systems, although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'auth_gssapi';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mariadbd-options/index#-plugin-load) or the [--plugin-load-add](../mariadbd-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mariadbd](../mariadbd-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = auth_gssapi

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'auth_gssapi';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Configuring the Plugin
----------------------

 If the MariaDB server is running on Unix, then some additional configuration steps will need to be implemented in order to use the plugin.

 If the MariaDB server is running on Windows, then no special configuration steps will need to be implemented in order to use the plugin, as long as the following is true:

 * The Windows server is joined to a domain.
* The MariaDB server process is running as either a [NetworkService Account](https://docs.microsoft.com/en-us/windows/desktop/services/networkservice-account) or a [Domain User Account](https://docs.microsoft.com/en-us/windows/desktop/ad/domain-user-accounts).

 ### Creating a Keytab File on Unix

 If the MariaDB server is running on Unix, then the KDC server will need to create a keytab file for the MariaDB server. The keytab file contains the service principal name, which is the identity that the MariaDB server will use to communicate with the KDC server. The keytab will need to be transferred to the MariaDB server, and the `mysqld` server process will need read access to this keytab file. 

 How this keytab file is generated depends on whether the KDC server is **[Microsoft Active Directory KDC](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview)** or **[MIT Kerberos KDC](http://web.mit.edu/Kerberos/krb5-1.12/doc/index.html)**.

 #### Creating a Keytab File with Microsoft Active Directory

 If you are using **[Microsoft Active Directory KDC](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview)**, then you may need to create a keytab using the `[ktpass.exe](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ktpass)` utility on a Windows host. The service principal will need to be mapped to an existing domain user. To do so, follow the steps listed below.

 Be sure to replace the following items in the step below:

 * Replace `${HOST}` with the fully qualified DNS name for the MariaDB server host.
* Replace `${DOMAIN}` with the Active Directory domain.
* Replace `${AD_USER}` with the existing domain user.
* Replace `${PASSWORD}` with the password for the service principal.

 To create the service principal, execute the following:

 
```
ktpass.exe /princ mariadb/${HOST}@${DOMAIN} /mapuser ${AD_USER} /pass ${PASSWORD} /out mariadb.keytab /crypto all /ptype KRB5_NT_PRINCIPAL /mapop set

```

#### Creating a Keytab File with MIT Kerberos

 If you are using **[MIT Kerberos KDC](http://web.mit.edu/Kerberos/krb5-1.12/doc/index.html)**, then you can create a [keytab](http://web.mit.edu/Kerberos/krb5-1.12/doc/admin/install_appl_srv.html#the-keytab-file) file using the `[kadmin](https://web.mit.edu/kerberos/krb5-1.12/doc/admin/admin_commands/kadmin_local.html)` utility. To do so, follow the steps listed below.

 In the following steps, be sure to replace `${HOST}` with the fully qualified DNS name for the MariaDB server host.

 First, create the service principal using the `[kadmin](https://web.mit.edu/kerberos/krb5-1.12/doc/admin/admin_commands/kadmin_local.html)` utility. For example:

 
```
kadmin -q "addprinc -randkey mariadb/${HOST}"

```

Then, export the newly created user to the keytab file using the `[kadmin](https://web.mit.edu/kerberos/krb5-1.12/doc/admin/admin_commands/kadmin_local.html)` utility. For example:

 
```
kadmin -q "ktadd -k /path/to/mariadb.keytab mariadb/${HOST}"

```

More details can be found at the following links:

 * [MIT Kerberos Documentation: Database administration](http://web.mit.edu/Kerberos/krb5-1.12/doc/admin/database.html)
* [MIT Kerberos Documentation: Application servers](http://web.mit.edu/Kerberos/krb5-1.12/doc/admin/appl_servers.html)

 ### Configuring the Path to the Keytab File on Unix

 If the MariaDB server is running on Unix, then the path to the keytab file that was previously created can be set by configuring the `[gssapi\_keytab\_path](#gssapi_keytab_path)` system variable. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
gssapi_keytab_path=/path/to/mariadb.keytab

```

### Configuring the Service Principal Name

 The service principal name can be set by configuring the `[gssapi\_principal\_name](#gssapi_principal_name)` system variable. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
gssapi_principal_name=service_principal_name/host.domain.com@REALM

```

If a service principal name is not provided, then the plugin will try to use `mariadb/host.domain.com@REALM` by default.

 If the MariaDB server is running on Unix, then the plugin needs a service principal name in order to function.

 If the MariaDB server is running on Windows, then the plugin does not usually need a service principal in order to function. However, if you want to use one anyway, then one can be created with the `[setspn](https://social.technet.microsoft.com/wiki/contents/articles/717.service-principal-names-spns-setspn-syntax-setspn-exe.aspx)` utility.

 Different KDC implementations may use different canonical forms to identify principals. See [RFC2744: Section 3.10](https://tools.ietf.org/html/rfc2744.html#section-3.10) to learn what the standard says about principal names.

 More details can be found at the following links:

 * [Active Directory Domain Services: Service Principal Names](https://docs.microsoft.com/en-us/windows/win32/ad/service-principal-names)
* [MIT Kerberos Documentation: Realm configuration decisions](http://web.mit.edu/Kerberos/krb5-1.12/doc/admin/realm_config.html)
* [MIT Kerberos Documentation: Principal names and DNS](http://web.mit.edu/Kerberos/krb5-1.12/doc/admin/princ_dns.html)

 Creating Users
--------------

 To create a user account via `[CREATE USER](../create-user/index)`, specify the name of the plugin in the `[IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin)` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA gssapi;

```

If `[SQL\_MODE](../sql-mode/index)` does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via `[GRANT](../grant/index)`. For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA gssapi;

```

You can also specify the user's [realm](https://docs.microsoft.com/en-us/windows-server/networking/technologies/nps/nps-crp-realm-names) for MariaDB with the `USING` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA gssapi USING 'username@EXAMPLE.COM';

```

The format of the realm depends on the specific authentication mechanism that is used. For example, the format would need to be `machine\\username` for Windows users authenticating with NTLM.

 If the realm is not provided in the user account's definition, then the realm is **not** used for comparison. Therefore, 'usr1@EXAMPLE.COM', 'usr1@EXAMPLE.CO.UK' and 'mymachine\usr1' would all identify as the following user account:

 
```
CREATE USER usr1@hostname IDENTIFIED VIA gssapi;

```

### Creating Users Identified Via Group Membership or SID (Windows-specific)

 Since 10.6.0, on Windows only, it is possible to login using a AD or local group-membership. This is achieved by using GROUP prefix in IDENTIFIED ... AS

 
```
CREATE USER root IDENTIFIED VIA gssapi as 'GROUP:Administrators'
CREATE USER root IDENTIFIED VIA gssapi as 'GROUP:BUILTIN\\Administrators'

```

Effect of the above definition is that every user that identifies as member of group Administrators can login using user name root, passwordless.

 User can also login using own or group [SID](https://en.wikipedia.org/wiki/Security_Identifier)

 
```
CREATE USER root IDENTIFIED VIA gssapi as 'SID:S-1-5-32-544' 

```

Using SIDs will perform slightly faster than using name (since it will spare translation between SID and name which is otherwise done), also SIDs immune against user or group renaming.

 Passwordless login on Windows
-----------------------------

 
**MariaDB starting with [10.11](../what-is-mariadb-1011/index)**From [MariaDB 10.11](../what-is-mariadb-1011/index), on Windows, in addition to the usual authentication with a password, passwordless authentication is permitted, when creating the 'root' user during install.

 This works in a similar manner to [Unix socket authentication](../authentication-from-mariadb-104/index). However, since auth\_gssapi, unlike unix\_socket, requires client support, to avoid failures when MariaDB is used with 3rd party drivers, authentication on Windows first attempts password-based native\_authentication, and only if it fails, falls back to passwordless auth\_gssapi.

 
Client Authentication Plugins
-----------------------------

 For clients that use the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries, MariaDB provides one client authentication plugin that is compatible with the `gssapi` authentication plugin:

 * `auth_gssapi_client`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `gssapi` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mysql --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```

### `auth_gssapi_client`

 The `auth_gssapi_client` client authentication plugin receives the principal name from the server, and then uses either the `[gss\_init\_sec\_context](https://web.mit.edu/kerberos/krb5-devel/doc/appdev/gssapi.html#initiator-credentials)` function (on Unix) or the `[InitializeSecurityContext](https://docs.microsoft.com/en-us/windows/desktop/api/sspi/nf-sspi-initializesecuritycontexta)` function (on Windows) to establish a security context on the client.

 Support in Client Libraries
---------------------------

 ### Using the Plugin with MariaDB Connector/C

 [MariaDB Connector/C](../mariadb-connector-c/index) supports `gssapi` authentication using the [client authentication plugins](#client-authentication-plugins) mentioned in the previous section since MariaDB Connector/C 3.0.1.

 ### Using the Plugin with MariaDB Connector/ODBC

 [MariaDB Connector/ODBC](../mariadb-connector-odbc/index) supports `gssapi` authentication using the [client authentication plugins](#client-authentication-plugins) mentioned in the previous section since MariaDB Connector/ODBC 3.0.0.

 ### Using the Plugin with MariaDB Connector/J

 [MariaDB Connector/J](../mariadb-connector-j/index) supports `gssapi` authentication since MariaDB Connector/J 1.4.0. Current documentation can be found [here](../gssapi-authentication-with-mariadb-connectorj/index).

 ### Using the Plugin with MariaDB Connector/Node.js

 [MariaDB Connector/Node.js](../nodejs-connector/index) does not yet support `gssapi` authentication. See [CONJS-72](https://jira.mariadb.org/browse/CONJS-72) for more information.

 ### Using the Plugin with MySqlConnector for .NET

 [MySqlConnector for ADO.NET](../mysqlconnector-for-adonet/index) supports `gssapi` authentication since MySqlConnector 0.47.0.

 The support is transparent. Normally, the connector only needs to be provided the correct user name, and no other parameters are required.

 However, this connector also supports the `[ServerSPN](https://mysql-net.github.io/MySqlConnector/connection-options)` connection string parameter, which can be used for mutual authentication.

 #### .NET specific problems/workarounds

 When connecting from Unix client to Windows server with ADO.NET, in an Active Directory domain environment, be aware that .NET Core on Unix does not support principal names in UPN(User Principal Name) form, which is default on Windows (e.g machine$@domain.com) . Thus, upon encountering an authentication exception with "server not found in Kerberos database", use one of workarounds below

 * Force host-based SPN on server side.
	+ For example, this can be done by setting the `[gssapi\_principal\_name](#gssapi_principal_name)` system variable to `HOST/machine` in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index).
* Pass host-based SPN on client side.
	+ For example, this can be done by setting the connector's `[ServerSPN](https://mysql-net.github.io/MySqlConnector/connection-options)` connection string parameter to `HOST/machine`.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/) |
| 1.0 | Beta | [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |

 
System Variables
----------------

 ### `gssapi_keytab_path`

 * **Description:** Defines the path to the server's keytab file.
	+ This system variable is only meaningful on **Unix**.
	+ See [Creating a Keytab File on Unix](#creating-a-keytab-file) and [Configuring the Path to the Keytab File on Unix](#configuring-the-path-to-the-keytab-file-on-unix) for more information.
* **Commandline:** `--gssapi-keytab-path`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** ''
* **Introduced:** [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/)

 

---

 ### `gssapi_principal_name`

 * **Description:** Name of the service principal.
	+ See [Configuring the Service Principal Name](#configuring-the-service-principal-name) for more information.
* **Commandline:** `--gssapi-principal-name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** ''
* **Introduced:** [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/)

 

---

 ### `gssapi_mech_name`

 * **Description:** Name of the SSPI package used by server. Can be either 'Kerberos' or 'Negotiate'. Set it to 'Kerberos', to prevent less secure NTLM in domain environments, but leave it as default (Negotiate) to allow non-domain environments (e.g if server does not run in a domain environment).
	+ This system variable is only meaningful on **Windows**.
* **Commandline:** `--gssapi-mech-name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `Negotiate`
* **Valid Values:** `Kerberos`, `Negotiate`
* **Introduced:** [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/)

 

---

 Options
-------

 ### `gssapi`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--gssapi=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`
* **Introduced:** [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-gssapi/>

Cracklib Password Check Plugin
==============================

     `cracklib_password_check` is a [password validation](../password-validation-plugin-api/index) plugin. It uses the [CrackLib](https://github.com/cracklib/cracklib) library to check the strength of new passwords. CrackLib is installed by default in many Linux distributions, since the system's [Pluggable Authentication Module (PAM)](https://en.wikipedia.org/wiki/Pluggable_authentication_module) authentication framework is usually configured to check the strength of new passwords with the `[pam\_cracklib](https://linux.die.net/man/8/pam_cracklib)` PAM module.

 Note that passwords can be directly set as a hash, bypassing the password validation, if the [strict\_password\_validation](../server-system-variables/index#strict_password_validation) variable is `OFF` (it is `ON` by default).

 The plugin requires at least cracklib 2.9.0, so it is not available on Debian/Ubuntu builds before Debian 8 Jessie/Ubuntu 14.04 Trusty, RedHat Enterprise Linux / CentOS 6.

 Installing the Plugin's Package
-------------------------------

 The `cracklib_password_check` plugin's shared library is included in MariaDB packages as the `cracklib_password_check.so` or `cracklib_password_check.dll` shared library on systems where it can be built.

 ### Installing on Linux

 The `cracklib_password_check` plugin is included in `systemd` [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux, but not in the older generic and `glibc_214` tarballs.

 #### Installing with a Package Manager

 The `cracklib_password_check` plugin can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 ##### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-cracklib-password-check

```

##### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 
```
sudo apt-get install mariadb-plugin-cracklib-password-check

```

##### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-cracklib-password-check

```

Installing the Plugin
---------------------

 Once the shared library is in place, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'cracklib_password_check';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = cracklib_password_check

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'cracklib_password_check';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Viewing CrackLib Errors
-----------------------

 If password validation fails, then the original CrackLib error message can be viewed by executing `[SHOW WARNINGS](../show-warnings/index)`.

 Example
-------

 When creating a new password, if the criteria are not met, the following error is returned:

 
```
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('abc');
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

```

Known Issues
------------

 ### Issues with PAM Authentication Plugin

 Prior to [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), all [password validation plugins](../password-validation-plugins/index) are incompatible with the `[pam](../pam-authentication-plugin/index)` authentication plugin. See [Authentication Plugin - PAM: Conflicts with Password Validation](../authentication-plugin-pam/index#conflicts-with-password-validation) for more information.

 ### SELinux

 When using the standard [SELinux](../selinux/index) policy with the [mode](../selinux/index#changing-selinuxs-mode) set to `enforcing`, `mysqld` does not have access to `/usr/share/cracklib`, and you may see the following error when attempting to use the `cracklib_password_check` plugin:

 
```
CREATE USER `user`@`hostname` IDENTIFIED BY 's0mePwd123.';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

SHOW WARNINGS;
+---------+------+----------------------------------------------------------------+
| Level   | Code | Message                                                        |
+---------+------+----------------------------------------------------------------+
| Warning | 1819 | cracklib: error loading dictionary                             |
| Error   | 1819 | Your password does not satisfy the current policy requirements |
| Error   | 1396 | Operation CREATE USER failed for 'user'@'hostname'             |
+---------+------+----------------------------------------------------------------+

```

And the SELinux `audit.log` will contain errors like the following:

 
```
type=AVC msg=audit(1548371977.821:66): avc:  denied  { read } for  pid=3537 comm="mysqld" name="pw_dict.pwd" dev="xvda2" ino=564747 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:crack_db_t:s0 tclass=file
type=SYSCALL msg=audit(1548371977.821:66): arch=c000003e syscall=2 success=no exit=-13 a0=7fdd2a674580 a1=0 a2=1b6 a3=1b items=0 ppid=1 pid=3537 auid=4294967295 uid=995 gid=992 euid=995 suid=995 fsuid=995 egid=992 sgid=992 fsgid=992 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null)

```

This can be fixed by creating an SELinux policy that allows `mysqld` to load the CrackLib dictionary. For example:

 
```
cd /usr/share/mysql/policy/selinux/
tee ./mariadb-plugin-cracklib-password-check.te <<EOF

module mariadb-plugin-cracklib-password-check 1.0;

require {
        type mysqld_t;
        type crack_db_t;
        class file { execute setattr read create getattr execute_no_trans write ioctl open append unlink };
        class dir { write search getattr add_name read remove_name open };
}

allow mysqld_t crack_db_t:dir { search read open };
allow mysqld_t crack_db_t:file { getattr read open };
EOF
sudo yum install selinux-policy-devel
make -f /usr/share/selinux/devel/Makefile mariadb-plugin-cracklib-password-check.pp
sudo semodule -i mariadb-plugin-cracklib-password-check.pp

```

See [MDEV-18374](https://jira.mariadb.org/browse/MDEV-18374) for more information.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |

 
System Variables
----------------

 #### `cracklib_password_check_dictionary`

 * **Description:** Sets the path to the CrackLib dictionary. If not set, the default CrackLib dictionary path is used. The parameter expects the base name of a cracklib dictionary (a set of three files with endings `.hwm`, `.pwd`, `.pwi`), not a directory path.
* **Commandline:** `--cracklib-password-check-dictionary=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** Depends on the system. Often `/usr/share/cracklib/pw_dict`

 

---

 Options
-------

 #### `cracklib_password_check`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--cracklib-password-check=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 See Also
--------

 * [Password Validation](../password-validation/index)
* [simple\_password\_check plugin](../simple_password_check/index) - permits the setting of basic criteria for passwords

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cracklib_password_check/>

File Key Management Encryption Plugin
=====================================

    MariaDB's [data-at-rest encryption](../data-at-rest-encryption/index) requires the use of a [key management and encryption plugin](../encryption-key-management/index). These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of [multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports [key rotation](../encryption-key-management/index#key-rotation), then encryption keys can also be rotated, which creates a new version of the encryption key.

 The File Key Management plugin that ships with MariaDB is a [key management and encryption plugin](../encryption-key-management/index) that reads encryption keys from a plain-text file.

 Overview
--------

 The File Key Management plugin is the easiest [key management and encryption plugin](../encryption-key-management/index) to set up for users who want to use [data-at-rest encryption](../data-at-rest-encryption/index). Some of the plugin's primary features are:

 * It reads encryption keys from a plain-text key file.
* As an extra protection mechanism, the plain-text key file can be encrypted.
* It supports multiple encryption keys.
* It does **not** support key rotation.
* It supports two different algorithms for encrypting data.

 It can also serve as an example and as a starting point when developing a key management and encryption plugin with the [encryption plugin API](../encryption-plugin-api/index).

 Installing the File Key Management Plugin's Package
---------------------------------------------------

 The File Key Management plugin is included in MariaDB packages as the `file_key_management.so` or `file_key_management.dll` shared library. The shared library is in the main server package, so no additional package installations are necessary.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. The plugin can be installed by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = file_key_management

```

Uninstalling the Plugin
-----------------------

 Before you uninstall the plugin, you should ensure that [data-at-rest encryption](../data-at-rest-encryption/index) is completely disabled, and that MariaDB no longer needs the plugin to decrypt tables or other files.

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'file_key_management';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Creating the Key File
---------------------

 In order to encrypt your tables with encryption keys using the File Key Management plugin, you first need to create the file that contains the encryption keys. The file needs to contain two pieces of information for each encryption key. First, each encryption key needs to be identified with a 32-bit integer as the key identifier. Second, the encryption key itself needs to be provided in hex-encoded form. These two pieces of information need to be separated by a semicolon. For example, the file is formatted in the following way:

 
```
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>

```

You can also optionally encrypt the key file to make it less accessible from the file system. That is explained further in the section below.

 The File Key Management plugin uses [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) to encrypt data, which supports 128-bit, 192-bit, and 256-bit encryption keys. Therefore, the plugin also supports 128-bit, 192-bit, and 256-bit encryption keys.

 You can generate random encryption keys using the `[openssl rand](https://www.openssl.org/docs/man1.1.1/man1/rand.html)` command. For example, to create a random 256-bit (32-byte) encryption key, you would run the following command:

 
```
$ openssl rand -hex 32
a7addd9adea9978fda19f21e6be987880e68ac92632ca052e5bb42b1a506939a

```

The key file still needs to have a key identifier for each encryption key added to the beginning of each line. Key identifiers do not need to be contiguous. 

 For example, to append three new encryption keys to a new key file, you could execute the following:

 
```
$ (echo -n "1;" ; openssl rand -hex 32 ) | sudo tee -a  /etc/mysql/encryption/keyfile
$ (echo -n "2;" ; openssl rand -hex 32 ) | sudo tee -a  /etc/mysql/encryption/keyfile
$ (echo -n "100;" ; openssl rand -hex 32 ) | sudo tee -a  /etc/mysql/encryption/keyfile

```

The new key file would look something like the following after this step:

 
```
1;a7addd9adea9978fda19f21e6be987880e68ac92632ca052e5bb42b1a506939a
2;49c16acc2dffe616710c9ba9a10b94944a737de1beccb52dc1560abfdd67388b
100;8db1ee74580e7e93ab8cf157f02656d356c2f437d548d5bf16bf2a56932954a3

```

The key identifiers give you a way to reference the encryption keys from MariaDB. In the example above, you could reference these encryption keys using the key identifiers `1`, `2` or `100` with the `[ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id)` table option or with system variables such as `[innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id)`. You do not necessarily need multiple encryption keys--the encryption key with the key identifier `1` is the only mandatory encryption key.

 ### Configuring the Path to an Unencrypted Key File

 If the key file is unencrypted, then the File Key Management plugin only requires the `[file\_key\_management\_filename](#file_key_management_filename)` system variable to be configured.

 This system variable can be specified as command-line arguments to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
loose_file_key_management_filename = /etc/mysql/encryption/keyfile

```

Note that the `[loose](../mysqld-options/index#-loose-)` option prefix is specified. This option prefix is used in case the plugin hasn't been installed yet.

 Encrypting the Key File
-----------------------

 By enabling the File Key Management plugin and setting the appropriate path on the `[file\_key\_management\_filename](#file_key_management_filename)` system variable, you can begin using the plugin to manage your encryption keys. But, there is a security risk in doing so, given that the keys are stored in plain text on your system. You can reduce this exposure using file permissions, but it's better to encrypt the whole key file to further restrict access.

 There are some important details to keep in mind about encrypting the key file, such as:

 * The only algorithm that MariaDB currently supports to encrypt the key file is [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
* The encryption key size can be 128-bits, 192-bits, or 256-bits.
* The encryption key is created from the [SHA-1](https://en.wikipedia.org/wiki/SHA-1) hash of the encryption password.
* The encryption password has a max length of 256 characters.

 You can generate a random encryption password using the `[openssl rand](https://www.openssl.org/docs/man1.1.1/man1/rand.html)` command. For example, to create a random 256 character encryption password, you could execute the following:

 
```
$ sudo openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key

```

You can encrypt the key file using the `[openssl enc](https://www.openssl.org/docs/man1.1.1/man1/enc.html)` command. For example, to encrypt the key file with the encryption password created in the previous step, you could execute the following:

 
```
$ sudo openssl enc -aes-256-cbc -md sha1 \
   -pass file:/etc/mysql/encryption/keyfile.key \
   -in /etc/mysql/encryption/keyfile \
   -out /etc/mysql/encryption/keyfile.enc

```

Running this command reads the unencrypted `keyfile` file created above and creates a new encrypted `keyfile.enc` file, using the encryption password stored in `keyfile.key`. Once you've finished preparing your system, you can delete the unencrypted `keyfile` file, as it's no longer necessary.

 ### Configuring the Path to an Encrypted Key File

 If the key file is encrypted, then the File Key Management plugin requires both the `[file\_key\_management\_filename](#file_key_management_filename)` and the `[file\_key\_management\_filekey](#file_key_management_filekey)` system variables to be configured.

 The `[file\_key\_management\_filekey](#file_key_management_filekey)` system variable can be provided in two forms:

 * It can be the actual plain-text encryption password. This is not recommended, since the plain-text encryption password would be visible in the output of the `[SHOW VARIABLES](../show-variables/index)` statement.
* If it is prefixed with `FILE:`, then it can be a path to a file that contains the plain-text encryption password.

 These system variables can be specified as command-line arguments to `[mysqld](../mysqld-options/index)` or they can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
loose_file_key_management_filename = /etc/mysql/encryption/keyfile.enc
loose_file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key

```

Note that the `[loose](../mysqld-options/index#-loose-)` option prefix is specified. This option prefix is used in case the plugin hasn't been installed yet.

 Choosing an Encryption Algorithm
--------------------------------

 The File Key Management plugin currently supports two encryption algorithms for encrypting data: `AES_CBC` and `AES_CTR`. Both of these algorithms use [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) in different modes. AES uses 128-bit blocks, and supports 128-bit, 192-bit, and 256-bit keys. The modes are:

 * The `AES_CBC` mode uses AES in the [Cipher Block Chaining (CBC)](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29) mode.
* The `AES_CTR` mode uses AES in two slightly different modes in different contexts. When encrypting tablespace pages (such as pages in InnoDB, XtraDB, and Aria tables), it uses AES in the [Counter (CTR)](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29) mode. When encrypting temporary files (where the cipher text is allowed to be larger than the plain text), it uses AES in the authenticated [Galois/Counter Mode (GCM)](http://en.wikipedia.org/wiki/Galois/Counter_Mode).

 The recommended algorithm is `AES_CTR`, but this algorithm is only available when MariaDB is built with recent versions of [OpenSSL](https://www.openssl.org/). If the server is built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then this algorithm is not available. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 ### Configuring the Encryption Algorithm

 The encryption algorithm can be configured by setting the `[file\_key\_management\_encryption\_algorithm](#file_key_management_encryption_algorithm)` system variable.

 This system variable can be set to one of the following values:

 


| System Variable Value | Description |
| --- | --- |
| `AES_CBC` | Data is encrypted using AES in the [Cipher Block Chaining (CBC)](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29) mode. This is the default value. |
| `AES_CTR` | Data is encrypted using AES either in the [Counter (CTR)](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29) mode or in the authenticated [Galois/Counter Mode (GCM)](http://en.wikipedia.org/wiki/Galois/Counter_Mode) mode, depending on context. This is only supported in some builds. See the previous section for more information. |

 
This system variable can be specified as command-line arguments to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
loose_file_key_management_encryption_algorithm = AES_CTR

```

Note that the `[loose](../mysqld-options/index#-loose-)` option prefix is specified. This option prefix is used in case the plugin hasn't been installed yet.

 
Note that this variable does not affect the algorithm that MariaDB uses to decrypt the key file. This variable only affects the encryption algorithm that MariaDB uses to encrypt and decrypt data. The only algorithm that MariaDB currently supports to encrypt the key file is [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).

 
Using the File Key Management Plugin
------------------------------------

 Once the File Key Management Plugin is enabled, you can use it by creating an encrypted table:

 
```
CREATE TABLE t (i int) ENGINE=InnoDB ENCRYPTED=YES

```

Now, table `t` will be encrypted using the encryption key from the key file.

 For more information on how to use encryption, see [Data at Rest Encryption](../data-at-rest-encryption/index).

 Using Multiple Encryption Keys
------------------------------

 The File Key Management Plugin supports [using multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key can be defined with a different 32-bit integer as a key identifier.

 When [encrypting InnoDB tables](../innodb-encryption/index), the key that is used to encrypt tables [can be changed](../innodb-xtradb-encryption-keys/index).

 When [encrypting Aria tables](../aria-encryption/index), the key that is used to encrypt tables [cannot currently be changed](../aria-encryption-keys/index).

 Key Rotation
------------

 The File Key Management plugin does not currently support [key rotation](../encryption-key-management/index#key-rotation). See [MDEV-20713](https://jira.mariadb.org/browse/MDEV-20713) for more information.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
System Variables
----------------

 ### `file_key_management_encryption_algorithm`

 * **Description:** This system variable is used to determine which algorithm the plugin will use to encrypt data.
	+ The recommended algorithm is `AES_CTR`, but this algorithm is only available when MariaDB is built with recent versions of [OpenSSL](https://www.openssl.org/). If the server is built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then this algorithm is not available. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Commandline:** `--file-key-management-encryption-algorithm=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `AES_CBC`
* **Valid Values:** `AES_CBC`, `AES_CTR`

 

---

 ### `file_key_management_filekey`

 * **Description:** This system variable is used to determine the encryption password that is used to decrypt the key file defined by `[file\_key\_management\_filename](#file_key_management_filename)`.
	+ If this system variable's value is prefixed with `FILE:`, then it is interpreted as a path to a file that contains the plain-text encryption password.
	+ If this system variable's value is **not** prefixed with `FILE:`, then it is interpreted as the plain-text encryption password. However, this is not recommended.
	+ The encryption password has a max length of 256 characters.
	+ The only algorithm that MariaDB currently supports when decrypting the key file is [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard). The encryption key size can be 128-bits, 192-bits, or 256-bits. The encryption key is calculated by taking a [SHA-1](https://en.wikipedia.org/wiki/SHA-1) hash of the encryption password.
* **Commandline:** `--file-key-management-filekey=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (empty)

 

---

 ### `file_key_management_filename`

 * **Description:** This system variable is used to determine the path to the file that contains the encryption keys. If `[file\_key\_management\_filekey](#file_key_management_filekey)` is set, then this file can be encrypted with [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of [Advanced Encryption Standard (AES)](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard).
* **Commandline:** `--file-key-management-filename=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (empty)

 

---

 Options
-------

 ### `file_key_management`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--file-key-management=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/file-key-management-encryption-plugin/>

HandlerSocket Configuration Options
===================================

     The [HandlerSocket](../handlersocket/index) plugin has the following options.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 Add the options to the [mysqld] section of your my.cnf file.

 

---

 ### `handlersocket_accept_balance`

 * **Description:** When set to a value other than zero ('`0`'), handlersocket will try to balance accepted connections among threads. Default is `0` but if you use persistent connections (for example if you use client-side connection pooling) then a non-zero value is recommended.
* **Commandline:** `--handlersocket-accept-balance="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `0` to `10000`
* **Default Value:** `0`

 

---

 ### `handlersocket_address`

 * **Description:** Specify the IP address to bind to.
* **Commandline:** `--handlersocket-address="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** IP Address
* **Default Value:** Empty, previously `0.0.0.0`

 

---

 ### `handlersocket_backlog`

 * **Description:** Specify the listen backlog length.
* **Commandline:** `--handlersocket-backlog="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `5` to `1000000`
* **Default Value:** `32768`

 

---

 ### `handlersocket_epoll`

 * **Description:** Specify whether to use epoll for I/O multiplexing.
* **Commandline:** `--handlersocket-epoll="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Valid values:**
	+ **Min:** `0`
	+ **Max:** `1`
* **Default Value:** `1`

 

---

 ### `handlersocket_plain_secret`

 * **Description:** When set, enables plain-text authentication for the listener for read requests, with the value of the option specifying the secret authentication key.
* **Commandline:** `--handlersocket-plain-secret="value"`
* **Dynamic:** No
* **Type:** string
* **Default Value:** Empty

 

---

 ### `handlersocket_plain_secret_wr`

 * **Description:** When set, enables plain-text authentication for the listener for write requests, with the value of the option specifying the secret authentication key.
* **Commandline:** `--handlersocket-plain-secret-wr="value"`
* **Dynamic:** No
* **Type:** string
* **Default Value:** Empty

 

---

 ### `handlersocket_port`

 * **Description:** Specify the port to bind to for reads. An empty value disables the listener.
* **Commandline:** `--handlersocket-port="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Default Value:** Empty, previously `9998`

 

---

 ### `handlersocket_port_wr`

 * **Description:** Specify the port to bind to for writes. An empty value disables the listener.
* **Commandline:** `--handlersocket-port-wr="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Default Value:** Empty, previously `9999`

 

---

 ### `handlersocket_rcvbuf`

 * **Description:** Specify the maximum socket receive buffer (in bytes). If '0' then the system default is used.
* **Commandline:** `--handlersocket-rcvbuf="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `0` to `1677216`
* **Default Value:** `0`

 

---

 ### `handlersocket_readsize`

 * **Description:** Specify the minimum length of the request buffer. Larger values consume available memory but can make handlersocket faster for large requests.
* **Commandline:** `--handlersocket-readsize="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `0` to `1677216`
* **Default Value:** `0` (possibly `4096`)

 

---

 ### `handlersocket_sndbuf`

 * **Description:** Specify the maximum socket send buffer (in bytes). If '0' then the system default is used.
* **Commandline:** `--handlersocket-sndbuf="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `0` to `1677216`
* **Default Value:** `0`

 

---

 ### `handlersocket_threads`

 * **Description:** Specify the number of worker threads for reads. Recommended value = ((# CPU cores) \* 2).
* **Commandline:** `--handlersocket-threads="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `1` to `3000`
* **Default Value:** `16`

 

---

 ### `handlersocket_threads_wr`

 * **Description:** Specify the number of worker threads for writes. Recommended value = 1.
* **Commandline:** `--handlersocket-threads-wr="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `1` to `3000`
* **Default Value:** `1`

 

---

 ### `handlersocket_timeout`

 * **Description:** Specify the socket timeout in seconds.
* **Commandline:** `--handlersocket-timeout="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `30` to `3600`
* **Default Value:** `300`

 

---

 ### `handlersocket_verbose`

 * **Description:** Specify the logging verbosity.
* **Commandline:** `--handlersocket-verbose="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Valid values:**
	+ **Min:** `0`
	+ **Max:** `10000`
* **Default Value:** `10`

 

---

 ### `handlersocket_wrlock_timeout`

 * **Description:** The write lock timeout in seconds. When acting on write requests, handlersocket locks an advisory lock named 'handlersocket\_wr' and this option sets the timeout for it.
* **Commandline:** `--handlersocket-wrlock-timeout="value"`
* **Scope:** Global
* **Dynamic:** No
* **Type:** number
* **Range:** `0` to `3600`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handlersocket-configuration-options/>

Thread Pool System and Status Variables
=======================================

    This article describes the system and status variables used by the MariaDB thread pool. For a full description, see [Thread Pool in MariaDB](../thread-pool-in-mariadb/index).

 System variables
----------------

 #### `extra_max_connections`

 * **Description:** The number of connections on the `[extra\_port](#extra_port)`.
	+ See [Thread Pool in MariaDB: Configuring the Extra Port](../thread-pool-in-mariadb/index#configuring-the-extra-port) for more information.
* **Commandline:** `--extra-max-connections=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `100000`

 

---

 #### `extra_port`

 * **Description:** Extra port number to use for TCP connections in a `one-thread-per-connection` manner. If set to `0`, then no extra port is used.
	+ See [Thread Pool in MariaDB: Configuring the Extra Port](../thread-pool-in-mariadb/index#configuring-the-extra-port) for more information.
* **Commandline:** `--extra-port=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`

 

---

 #### `thread_handling`

 * **Description:** Determines how the server handles threads for client connections. In addition to threads for client connections, this also applies to certain internal server threads, such as [Galera slave threads](../about-galera-replication/index#galera-slave-threads). On Windows, if you would like to use the thread pool, then you do not need to do anything, because the default for the thread\_handling system variable is already preset to `pool-of-threads`.
	+ When the default `one-thread-per-connection` mode is enabled, the server uses one thread to handle each client connection.
	+ When the `pool-of-threads` mode is enabled, the server uses the [thread pool](../thread-pool-in-mariadb/index) for client connections.
	+ When the `no-threads` mode is enabled, the server uses a single thread for all client connections, which is really only usable for debugging.
* **Commandline:** `--thread-handling=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumeration`
* **Default Value:** `one-thread-per-connection` (non-Windows), `pool-of-threads` (Windows)
* **Valid Values:** `no-threads`, `one-thread-per-connection`, `pool-of-threads`.
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).
* **Notes:** In MySQL, the thread pool is only available in MySQL Enterprise. In MariaDB it's available in all versions.

 

---

 #### `thread_pool_dedicated_listener`

 * **Description:** If set to 1, then each group will have its own dedicated listener, and the listener thread will not pick up work items. As a result, the queueing time in the [Information Schema Threadpool\_Queues](../information-schema-threadpool_queues-table/index) and the actual queue size in the [Information Schema Threadpool\_Groups](../information-schema-threadpool_groups-table/index) table will be more exact, since IO requests are immediately dequeued from poll, without delay.
	+ This system variable is only meaningful on **Unix**.
* **Commandline:** `thread-pool-dedicated-listener={0|1}`
* **Scope:**
* **Dynamic:**
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `thread_pool_exact_stats`

 * **Description:** If set to 1, provides better queueing time statistics by using a high precision timestamp, at a small performance cost, for the time when the connection was added to the queue. This timestamp helps calculate the queuing time shown in the [Information Schema Threadpool\_Queues](../information-schema-threadpool_queues-table/index) table.
	+ This system variable is only meaningful on **Unix**.
* **Commandline:** `thread-pool-exact-stats={0|1}`
* **Scope:**
* **Dynamic:**
* **Data Type:** `boolean`
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `thread_pool_idle_timeout`

 * **Description:** The number of seconds before an idle worker thread exits. The default value is `60`. If there is currently no work to do, how long should an idle thread wait before exiting?
	+ This system variable is only meaningful on **Unix**.
	+ The `[thread\_pool\_min\_threads](#thread_pool_min_threads)` system variable is comparable for Windows.
* **Commandline:** `thread-pool-idle-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `60`
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_max_threads`

 * **Description:** The maximum number of threads in the [thread pool](../thread-pool-in-mariadb/index). Once this limit is reached, no new threads will be created in most cases.
	+ On Unix, in rare cases, the actual number of threads can slightly exceed this, because each [thread group](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) needs at least two threads (i.e. at least one worker thread and at least one listener thread) to prevent deadlocks.
* **Scope:**
* **Commandline:** `thread-pool-max-threads=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ `65536` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `1000` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), >= [MariaDB 10.1](../what-is-mariadb-101/index))
	+ `500` (<= [MariaDB 10.0](../what-is-mariadb-100/index))
* **Range:** `1` to `65536`
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_min_threads`

 * **Description:** Minimum number of threads in the [thread pool](../thread-pool-in-mariadb/index). In bursty environments, after a period of inactivity, threads would normally be retired. When the next burst arrives, it would take time to reach the optimal level. Setting this value higher than the default would prevent thread retirement even if inactive.
	+ This system variable is only meaningful on **Windows**.
	+ The `[thread\_pool\_idle\_timeout](#thread_pool_idle_timeout)` system variable is comparable for Unix.
* **Commandline:** `thread-pool-min-threads=#`
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_oversubscribe`

 * **Description:** Determines how many worker threads in a thread group can remain active at the same time once a thread group is oversubscribed due to stalls. The default value is `3`. Usually, a thread group only has one active worker thread at a time. However, the timer thread can add more active worker threads to a thread group if it detects a stall. There are trade-offs to consider when deciding whether to allow **only one** thread per CPU to run at a time, or whether to allow **more than one** thread per CPU to run at a time. Allowing only one thread per CPU means that the thread can have unrestricted access to the CPU while its running, but it also means that there is additional overhead from putting threads to sleep or waking them up more frequently. Allowing more than one thread per CPU means that the threads have to share the CPU, but it also means that there is less overhead from putting threads to sleep or waking them up.
	+ See [Thread Groups in the Unix Implementation of the Thread Pool: Thread Group Oversubscription](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-group-oversubscription) for more information.
	+ This is primarily for **internal** use, and it is **not** meant to be changed for most users.
	+ This system variable is only meaningful on **Unix**.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `3`
* **Range:** `1` to `65536`
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_prio_kickup_timer`

 * **Description:** Time in milliseconds before a dequeued low-priority statement is moved to the high-priority queue.
	+ This system variable is only meaningful on **Unix**.
* **Commandline:** `thread-pool-kickup-timer=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_priority`

 * **Description:** [Thread pool](../thread-pool-in-mariadb/index) priority. High-priority connections usually start executing earlier than low-priority. If set to 'auto' (the default), the actual priority (low or high) is determined by whether or not the connection is inside a transaction.
* **Commandline:** `--thread-pool-priority=#`
* **Scope:** Global,Connection
* **Data Type:** `enum`
* **Default Value:** `auto`
* **Valid Values:** `high`, `low`, `auto`.
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_size`

 * **Description:** The number of [thread groups](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) in the [thread pool](../thread-pool-in-mariadb/index), which determines how many statements can execute simultaneously. The default value is the number of CPUs on the system. When setting this system variable's value at system startup, the max value is 100000. However, it is not a good idea to set it that high. When setting this system variable's value dynamically, the max value is either 128 or the value that was set at system startup--whichever value is higher.
	+ See [Thread Groups in the Unix Implementation of the Thread Pool](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) for more information.
	+ This system variable is only meaningful on **Unix**.
* **Commandline:** `--thread-pool-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** Based on the number of processors (but see [MDEV-7806](https://jira.mariadb.org/browse/MDEV-7806)).
* **Range:** `1` to `128` (< [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5537-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/)), `1` to `100000` (>= [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5537-release-notes/), [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/))
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 #### `thread_pool_stall_limit`

 * **Description:** The number of milliseconds between each stall check performed by the timer thread. The default value is `500`. Stall detection is used to prevent a single client connection from monopolizing a thread group. When the timer thread detects that a thread group is stalled, it wakes up a sleeping worker thread in the thread group, if one is available. If there isn't one, then it creates a new worker thread in the thread group. This temporarily allows several client connections in the thread group to run in parallel. However, note that the timer thread will not create a new worker thread if the number of threads in the thread pool is already greater than or equal to the maximum defined by the `[thread\_pool\_max\_threads](#thread_pool_max_threads)` variable, unless the thread group does not already have a listener thread.
	+ See [Thread Groups in the Unix Implementation of the Thread Pool: Thread Group Stalls](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-group-stalls) for more information.
	+ This system variable is only meaningful on **Unix**.
	+ Note that if you are migrating from the MySQL Enterprise thread pool plugin, then the unit used in their implementation is 10ms, not 1ms.
* **Commandline:** `--thread-pool-stall-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `500`
* **Range:** `10` to `4294967295` (< [MariaDB 10.5](../what-is-mariadb-105/index)), `1` to `4294967295` (>= [MariaDB 10.5](../what-is-mariadb-105/index))
* **Documentation:** [Using the thread pool](../thread-pool-in-mariadb/index).

 

---

 Status variables
----------------

 #### `Threadpool_idle_threads`

 * **Description:** Number of inactive threads in the [thread pool](../thread-pool-in-mariadb/index). Threads become inactive for various reasons, such as by waiting for new work. However, an inactive thread is not necessarily one that has not been assigned work. Threads are also considered inactive if they are being blocked while waiting on disk I/O, or while waiting on a lock, etc.
	+ This status variable is only meaningful on **Unix**.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Threadpool_threads`

 * **Description:** Number of threads in the [thread pool](../thread-pool-in-mariadb/index). In rare cases, this can be slightly higher than `[thread\_pool\_max\_threads](#thread_pool_max_threads)`, because each thread group needs at least two threads (i.e. at least one worker thread and at least one listener thread) to prevent deadlocks.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 See Also
--------

 * [Thread Pool in MariaDB](../thread-pool-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-pool-system-and-status-variables/>

InnoDB Server Status Variables
==============================

    See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 Much of the [InnoDB](../innodb/index) information here can also be seen with a [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) statement.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Innodb_adaptive_hash_cells`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `Innodb_adaptive_hash_hash_searches`

 * **Description:** Hash searches as shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ Before the variable was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), use the `adaptive_hash_searches` counter in the [information\_schema.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table instead.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_adaptive_hash_heap_buffers`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `Innodb_adaptive_hash_non_hash_searches`

 * **Description:** Non-hash searches as shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. From [MariaDB 10.6.2](https://mariadb.com/kb/en/mariadb-1062-release-notes/), not updated if [innodb\_adaptive\_hash\_index](../innodb-system-variables/index#innodb_adaptive_hash_index) is not enabled (the default).
	+ In [MariaDB 10.1](../what-is-mariadb-101/index), [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present. Use the `adaptive_hash_searches_btree` counter in the [information\_schema.INNODB\_METRICS](../information-schema-innodb_metrics-table/index) table instead.
	+ From [MariaDB 10.5](../what-is-mariadb-105/index), this status variable is present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)
* **Removed:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `Innodb_available_undo_logs`

 * **Description:** Total number available InnoDB [undo logs](../undo-log/index). Differs from the [innodb\_undo\_logs](../innodb-system-variables/index#innodb_undo_logs) system variable, which specifies the number of *active* undo logs.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_background_log_sync`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index), [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_buffer_pool_bytes_data`

 * **Description:** Number of bytes contained in the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index), both dirty (modified) and clean (unmodified). See also [Innodb\_buffer\_pool\_pages\_data](#innodb_buffer_pool_pages_data), which can contain pages of different sizes in the case of compression.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_bytes_dirty`

 * **Description:** Number of dirty (modified) bytes contained in the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index). See also [Innodb\_buffer\_pool\_pages\_dirty](#innodb_buffer_pool_pages_dirty), which can contain pages of different sizes in the case of compression.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_dump_status`

 * **Description:** A text description of the progress or final status of the last Innodb buffer pool dump.
* **Scope:** Global
* **Data Type:** `string`
* **Introduced:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `Innodb_buffer_pool_load_incomplete`

 * **Description:** Whether or not the loaded buffer pool is incomplete, for example after a shutdown or abort during innodb buffer pool load from file caused an incomplete save.
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### `Innodb_buffer_pool_load_status`

 * **Description:** A text description of the progress or final status of the last Innodb buffer pool load.
* **Scope:** Global
* **Data Type:** `string`
* **Introduced:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_data`

 * **Description:** Number of [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages which contain data, both dirty (modified) and clean (unmodified). See also [Innodb\_buffer\_pool\_bytes\_data](#innodb_buffer_pool_bytes_data).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_pages_dirty`

 * **Description:** Number of [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages which contain dirty (modified) data. See also [Innodb\_buffer\_pool\_bytes\_dirty](innodb_buffer_pool_bytes_dirty).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_pages_flushed`

 * **Description:** Number of [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages which have been flushed.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_pages_LRU_flushed`

 * **Description:** Flush list as shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_LRU_freed`

 * **Description:** Monitor the number of pages that were freed by a buffer pool LRU eviction scan, without flushing.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_free`

 * **Description:** Number of free [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_pages_made_not_young`

 * **Description:** Pages not young as shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_made_young`

 * **Description:** Pages made young as shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_misc`

 * **Description:** Number of [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages set aside for internal use.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_pages_old`

 * **Description:** Old database page, as shown in the BUFFER POOL AND MEMORY section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present for XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_buffer_pool_pages_total`

 * **Description:** Total number of [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) pages.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_read_ahead`

 * **Description:** Number of pages read into the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) by the read-ahead background thread.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_read_ahead_evicted`

 * **Description:** Number of pages read into the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) by the read-ahead background thread that were evicted without having been accessed by queries.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_read_ahead_rnd`

 * **Description:** Number of random read-aheads.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_read_requests`

 * **Description:** Number of requests to read from the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_reads`

 * **Description:** Number of reads that could not be satisfied by the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) and had to be read from disk.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_resize_status`

 * **Description:** Progress of the dynamic [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) resizing operation. See [Setting Innodb Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)

 

---

 #### `Innodb_buffer_pool_wait_free`

 * **Description:** Number of times InnoDB waited for a free page before reading or creating a page. Normally, writes to the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index) happen in the background. When no clean pages are available, dirty pages are flushed first in order to free some up. This counts the numbers of wait for this operation to finish. If this value is not small, look at increasing [innodb\_buffer\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_size).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffer_pool_write_requests`

 * **Description:** Number of requests to write to the [InnoDB buffer pool](../xtradbinnodb-memory-buffer/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_buffered_aio_submitted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_checkpoint_age`

 * **Description:** The checkpoint age, as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. (This is equivalent to subtracting "Last checkpoint at" from "Log sequence number".)
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_checkpoint_max_age`

 * **Description:** Max checkpoint age, as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_checkpoint_target_age`

 * **Description:** Checkpoint age target, as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. XtraDB only. Removed in [MariaDB 10.0](../what-is-mariadb-100/index) and replaced with MySQL 5.6's flushing implementation.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_current_row_locks`

 * **Description:** Number of current row locks on InnoDB tables as shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. Renamed from [InnoDB\_row\_lock\_numbers](#innodb_row_lock_numbers) in XtraDB 5.5.8-20.1.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Innodb_data_fsyncs`

 * **Description:** Number of InnoDB fsync (sync-to-disk) calls. fsync call frequency can be influenced by the [innodb\_flush\_method](../xtradbinnodb-server-system-variables/index#innodb_flush_method) configuration option.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_pending_fsyncs`

 * **Description:** Number of pending InnoDB fsync (sync-to-disk) calls. fsync call frequency can be influenced by the [innodb\_flush\_method](../xtradbinnodb-server-system-variables/index#innodb_flush_method) configuration option.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_pending_reads`

 * **Description:** Number of pending InnoDB reads.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_pending_writes`

 * **Description:** Number of pending InnoDB writes.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_read`

 * **Description:** Number of InnoDB bytes read since server startup (not to be confused with [Innodb\_data\_reads](#innodb_data_reads)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_reads`

 * **Description:** Number of InnoDB read operations (not to be confused with [Innodb\_data\_read](#innodb_data_read)).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_writes`

 * **Description:** Number of InnoDB write operations.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_data_written`

 * **Description:** Number of InnoDB bytes written since server startup. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), no longer includes writes to the redo log file `ib_logfile0`, which continue to be counted by [Innodb\_os\_log\_written](#innodb_os_log_written). An error in counting was introduced in [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) until [MariaDB 10.5.20](https://mariadb.com/kb/en/mariadb-10520-release-notes/), [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/), [MariaDB 10.8.8](https://mariadb.com/kb/en/mariadb-10-8-8-release-notes/), [MariaDB 10.9.6](https://mariadb.com/kb/en/mariadb-10-9-6-release-notes/), [MariaDB 10.10.4](https://mariadb.com/kb/en/mariadb-10-10-4-release-notes/) and [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/) ([MDEV-31124](https://jira.mariadb.org/browse/MDEV-31124)) in which writes via the doublewrite buffer started to be counted incorrectly, without multiplying them by innodb\_page\_size. A workaround for the error could be the following formulae:  
 real\_data\_written = Innodb\_data\_written + (innodb\_page\_size - 1) \* Innodb\_dblwr\_pages\_written  
innodb\_written = real\_data\_written + Innodb\_os\_log\_written
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_dblwr_pages_written`

 * **Description:** Number of pages written to the [InnoDB doublewrite buffer](../xtradbinnodb-doublewrite-buffer/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_dblwr_writes`

 * **Description:** Number of writes to the [InnoDB doublewrite buffer](../xtradbinnodb-doublewrite-buffer/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_deadlocks`

 * **Description:** Total number of InnoDB deadlocks. Deadlocks occur when at least two transactions are waiting for the other to finish, creating a circular dependency. InnoDB usually detects these quickly, returning an error.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_defragment_compression_failures`

 * **Description:** Number of defragment re-compression failures. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Innodb_defragment_count`

 * **Description:** Number of defragment operations. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Innodb_defragment_failures`

 * **Description:** Number of defragment failures. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 

---

 #### `Innodb_dict_tables`

 * **Description:** Number of entries in the XtraDB data dictionary cache. This Percona XtraDB variable was removed in MariaDB 10/XtraDB 5.6 as it was replaced with MySQL 5.6's [table\_definition\_cache](../server-system-variables/index#table_definition_cache) implementation.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** XtraDB 5.0.77-b13
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_encryption_n_merge_blocks_decrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `Innodb_encryption_n_merge_blocks_encrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `Innodb_encryption_n_rowlog_blocks_decrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `Innodb_encryption_n_rowlog_blocks_encrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.28](https://mariadb.com/kb/en/mariadb-10128-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `Innodb_encryption_n_temp_blocks_decrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `Innodb_encryption_n_temp_blocks_encrypted`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `Innodb_encryption_num_key_requests`

 * **Description:** Was not present in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_encryption_rotation_estimated_iops`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_encryption_rotation_pages_flushed`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_encryption_rotation_pages_modified`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_encryption_rotation_pages_read_from_cache`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_encryption_rotation_pages_read_from_disk`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_have_atomic_builtins`

 * **Description:** Whether the server has been built with atomic instructions, provided by the CPU ensuring that critical low-level operations can't be interrupted. XtraDB only.
* **Scope:** Global
* **Data Type:** `boolean`

 

---

 #### `Innodb_have_bzip2`

 * **Description:** Whether the server has the bzip2 compression method available. See [InnoDB/XtraDB Page Compression](../innodbxtradb-page-compression/index).
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_have_lz4`

 * **Description:** Whether the server has the lz4 compression method available. See [InnoDB/XtraDB Page Compression](../innodbxtradb-page-compression/index).
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_have_lzma`

 * **Description:** Whether the server has the lzma compression method available. See [InnoDB/XtraDB Page Compression](../innodbxtradb-page-compression/index).
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_have_lzo`

 * **Description:** Whether the server has the lzo compression method available. See [InnoDB/XtraDB Page Compression](../innodbxtradb-page-compression/index).
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_have_punch_hole`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_have_snappy`

 * **Description:** Whether the server has the snappy compression method available. See [InnoDB/XtraDB Page Compression](../innodbxtradb-page-compression/index).
* **Scope:** Global
* **Data Type:** `boolean`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 #### `Innodb_history_list_length`

 * **Description:** History list length as shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. XtraDB only until introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_discarded_delete_marks`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_discarded_deletes`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_discarded_inserts`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_free_list`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_merged_delete_marks`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_merged_deletes`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_merged_inserts`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_merges`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_segment_size`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_ibuf_size`

 * **Description:** As shown in the INSERT BUFFER AND ADAPTIVE HASH INDEX section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_instant_alter_column`

 * **Description:** See [Instant ADD COLUMN for InnoDB](../instant-add-column-for-innodb/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)

 

---

 #### `Innodb_log_waits`

 * **Description:** Number of times InnoDB was forced to wait for log writes to be flushed due to the log buffer being too small.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_log_write_requests`

 * **Description:** Number of requests to write to the InnoDB redo log.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_log_writes`

 * **Description:** Number of writes to the InnoDB redo log.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_lsn_current`

 * **Description:** Log sequence number as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_lsn_flushed`

 * **Description:** Flushed up to log sequence number as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_lsn_last_checkpoint`

 * **Description:** Log sequence number last checkpoint as shown in the LOG section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_master_thread_1_second_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_master_thread_10_second_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_master_thread_active_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 

---

 #### `Innodb_master_thread_background_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_master_thread_idle_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 

---

 #### `Innodb_master_thread_main_flush_loops`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and later, this system variable is not present
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_master_thread_sleeps`

 * **Description:** As shown in the BACKGROUND THREAD section of the [SHOW ENGINE INNODB STATUS](../show-engine/index) output. XtraDB only.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index), [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present. Use the `innodb_master_thread_sleeps` counter in the `[information\_schema.INNODB\_METRICS](../information-schema-innodb_metrics-table/index)` table instead.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.0](../what-is-mariadb-100/index)

 

---

 #### `Innodb_max_trx_id`

 * **Description:** As shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_mem_adaptive_hash`

 * **Description:** As shown in the BUFFER POOL AND MEMORY section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_mem_dictionary`

 * **Description:** As shown in the BUFFER POOL AND MEMORY section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), this system variable is not present.
	+ In [MariaDB 10.5](../what-is-mariadb-105/index), this system variable was reintroduced.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) (XtraDB-only), [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)

 

---

 #### `Innodb_mem_total`

 * **Description:** As shown in the BUFFER POOL AND MEMORY section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Innodb_mutex_os_waits`

 * **Description:** Mutex OS waits as shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Innodb_mutex_spin_rounds`

 * **Description:** Mutex spin rounds as shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Innodb_mutex_spin_waits`

 * **Description:** Mutex spin waits as shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)

 

---

 #### `Innodb_num_index_pages_written`

 * **Description:**
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_num_non_index_pages_written`

 * **Description:**
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/)

 

---

 #### `Innodb_num_open_files`

 * **Description:** Number of open files held by InnoDB. InnoDB only.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_page_compressed_trim_op`

 * **Description:** Number of trim operations performed.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_page_compressed_trim_op_saved`

 * **Description:** Number of trim operations not done because of an earlier trim.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_decrypted`

 * **Description:** Number of pages page decrypted. See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_encrypted`

 * **Description:** Number of pages page encrypted. See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_page_compressed`

 * **Description:** Number of pages that are page compressed.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_page_compression_error`

 * **Description:** Number of compression errors.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_page_decompressed`

 * **Description:** Number of pages compressed with page compression that are decompressed.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_num_pages_page_encryption_error`

 * **Description:** Number of page encryption errors. See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)

 

---

 #### `Innodb_oldest_view_low_limit_trx_id`

 * **Description:** As shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_onlineddl_pct_progress`

 * **Description:** Shows the progress of in-place alter table. It might be not so accurate because in-place alter is highly dependent on disk and buffer pool status. See [Monitoring progress and temporal memory usage of Online DDL in InnoDB](https://blog.mariadb.org/monitoring-progress-and-temporal-memory-usage-of-online-ddl-in-innodb).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_onlineddl_rowlog_pct_used`

 * **Description:** Shows row log buffer usage in 5-digit integer (10000 means 100.00%). See [Monitoring progress and temporal memory usage of Online DDL in InnoDB](https://blog.mariadb.org/monitoring-progress-and-temporal-memory-usage-of-online-ddl-in-innodb).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_onlineddl_rowlog_rows`

 * **Description:** Number of rows stored in the row log buffer. See [Monitoring progress and temporal memory usage of Online DDL in InnoDB](https://blog.mariadb.org/monitoring-progress-and-temporal-memory-usage-of-online-ddl-in-innodb).
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_os_log_fsyncs`

 * **Description:** Number of InnoDB log fsync (sync-to-disk) requests.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.8](../what-is-mariadb-108/index)

 

---

 #### `Innodb_os_log_pending_fsyncs`

 * **Description:** Number of pending InnoDB log fsync (sync-to-disk) requests.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.8](../what-is-mariadb-108/index)

 

---

 #### `Innodb_os_log_pending_writes`

 * **Description:** Number of pending InnoDB log writes.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.8](../what-is-mariadb-108/index)

 

---

 #### `Innodb_os_log_written`

 * **Description:** Number of bytes written to the InnoDB log.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_page_compression_saved`

 * **Description:** Number of bytes saved by page compression.
* **Scope:**
* **Data Type:**

 

---

 #### `Innodb_page_compression_trim_sect512`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 512 byte block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect1024`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 1K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect2048`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 2K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect4096`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 4K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect8192`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 8K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect16384`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 16K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_compression_trim_sect32768`

 * **Description:** Number of TRIM operations performed for the page-compression/NVM Compression workload for the 32K block-size.
* **Scope:**
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) Fusion-io
* **Removed:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 

---

 #### `Innodb_page_size`

 * **Description:** Page size used by InnoDB. Defaults to 16KB, can be compiled with a different value.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_pages_created`

 * **Description:** Number of InnoDB pages created.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_pages_read`

 * **Description:** Number of InnoDB pages read.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_pages0_read`

 * **Description:** Counter for keeping track of reads of the first page of InnoDB data files, because the original implementation of data-at-rest-encryption for InnoDB introduced new code paths for reading the pages. Removed in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) as the extra reads of the first page were removed, and the encryption subsystem will be initialized whenever we first read the first page of each data file, in fil\_node\_open\_file().
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/), [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/)
* **Removed:** [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)

 

---

 #### `Innodb_pages_written`

 * **Description:** Number of InnoDB pages written.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_purge_trx_id`

 * **Description:** Purge transaction id as shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_purge_undo_no`

 * **Description:** As shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_read_views_memory`

 * **Description:** As shown in the BUFFER POOL AND MEMORY section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. Shows the total of memory in bytes allocated for the InnoDB read view.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5532-release-notes/)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_row_lock_current_waits`

 * **Description:** Number of pending row lock waits on InnoDB tables.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_row_lock_numbers`

 * **Description:** Number of current row locks on InnoDB tables as shown in the TRANSACTIONS section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output. Renamed to [InnoDB\_current\_row\_locks](#innodb_current_row_locks) in XtraDB 5.5.10-20.1.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index) / XtraDB 5.5.8-20
* **Removed:** [MariaDB 5.5](../what-is-mariadb-55/index) / XtraDB 5.5.10-20.1

 

---

 #### `Innodb_row_lock_time`

 * **Description:** Total time in milliseconds spent getting InnoDB row locks.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_row_lock_time_avg`

 * **Description:** Average time in milliseconds spent getting an InnoDB row lock.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_row_lock_time_max`

 * **Description:** Maximum time in milliseconds spent getting an InnoDB row lock.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_row_lock_waits`

 * **Description:** Number of times InnoDB had to wait before getting a row lock.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_rows_deleted`

 * **Description:** Number of rows deleted from InnoDB tables that where not system tables. Almost equivalent to [Handler\_delete](../server-status-variables/index#handler_delete) which does include system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_rows_inserted`

 * **Description:** Number of rows inserted into InnoDB tables that where not system tables. No direct equivalent in [Handler](../server-status-variables/index#handler_commit) status variables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_rows_read`

 * **Description:** Number of rows read from InnoDB tables that where not system tables. Almost equivalent to the sum of [Handler\_read\*](../server-status-variables/index#handler_read_first) status variables which do include system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_rows_updated`

 * **Description:** Number of rows updated in InnoDB tables that where not system tables. Almost equivalent to [Handler\_update](../server-status-variables/index#handler_update) which does include system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_s_lock_os_waits`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_s_lock_spin_rounds`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_s_lock_spin_waits`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_scrub_background_page_reorganizations`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_background_page_split_failures_missing_index`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_background_page_split_failures_out_of_filespace`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_background_page_split_failures_underflow`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_background_page_split_failures_unknown`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_background_page_splits`

 * **Description:** See [Table and Tablespace Encryption](../table-and-tablespace-encryption/index).
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_scrub_log`

 * **Description:**
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)
* **Removed:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Innodb_secondary_index_triggered_cluster_reads`

 * **Description:** Used to track the effectiveness of the Prefix Index Queries Optimization ([MDEV-6929](https://jira.mariadb.org/browse/MDEV-6929)). Removed in [MariaDB 10.10](../what-is-mariadb-1010/index) as the optimization is now always enabled.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_secondary_index_triggered_cluster_reads_avoided`

 * **Description:** Used to track the effectiveness of the Prefix Index Queries Optimization ([MDEV-6929](https://jira.mariadb.org/browse/MDEV-6929)). Removed in [MariaDB 10.10](../what-is-mariadb-1010/index) as the optimization is now always enabled.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_system_rows_deleted`

 * **Description:** Number of rows deleted on system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_system_rows_inserted`

 * **Description:** Number of rows inserted on system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `Innodb_system_rows_read`

 * **Description:** Number of rows read on system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/)

 

---

 #### `Innodb_system_rows_updated`

 * **Description:** Number of rows updated on system tables.
* **Scope:** Global
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/)

 

---

 #### `Innodb_truncated_status_writes`

 * **Description:** Number of times output from [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) has been truncated.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Innodb_undo_truncations`

 * **Description:** Number of undo tablespace truncation operations.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/)

 

---

 #### `Innodb_x_lock_os_waits`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_x_lock_spin_rounds`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

 #### `Innodb_x_lock_spin_waits`

 * **Description:** As shown in the SEMAPHORES section of the [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) output.
	+ In [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.1](../what-is-mariadb-101/index), this system variable is present in XtraDB.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this system variable is not present.
* **Scope:** Global
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 5.5](../what-is-mariadb-55/index)
* **Removed:** [MariaDB 10.2](../what-is-mariadb-102/index)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-status-variables/>

Cassandra Status Variables
==========================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  This page documents status variables related to the [Cassandra storage engine](../cassandra/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 #### `Cassandra_multiget_keys_scanned`

 * **Description:** Number of keys we've made lookups for.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_multiget_reads`

 * **Description:** Number of read operations.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_multiget_rows_read`

 * **Description:** Number of rows actually read.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_network_exceptions`

 * **Description:** Number of network exceptions.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** `[MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/)`

 

---

 #### `Cassandra_row_insert_batches`

 * **Description:** Number of insert batches performed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_row_inserts`

 * **Description:** Number of rows inserted.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_timeout_exceptions`

 * **Description:** Number of Timeout exceptions we got from Cassandra.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Cassandra_unavailable_exceptions`

 * **Description:** Number of Unavailable exceptions we got from Cassandra.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-status-variables/>

CONNECT System Variables
========================

     This page documents system variables related to the [CONNECT storage engine](../connect/index). See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `connect_class_path`

 * **Description:** Java class path
* **Commandline:** `--connect-class-path=value`
* **Scope:** Global
* **Dynamic:**
* **Data Type:** `string`
* **Default Value:**

 

---

 #### `connect_cond_push`

 * **Description:** Enable condition pushdown
* **Commandline:** `--connect-cond-push={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `connect_conv_size`

 * **Description:** The size of the [VARCHAR](../varchar/index) created when converting from a [TEXT](../text/index) type. See [connect\_type\_conv](#connect_type_conv).
* **Commandline:** `--connect-conv-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**
	+ >= [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/): `1024`
	+ <= [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/): `8192`
* **Range:** `0` to `65500`

 

---

 #### `connect_default_depth`

 * **Description:** Default depth used by Json, XML and Mongo discovery.
* **Commandline:** `--connect-default-depth=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**`5`
* **Range:** `-1` to `16`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/)

 

---

 #### `connect_default_prec`

 * **Description:** Default precision used for doubles.
* **Commandline:** `--connect-default-prec=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:**`6`
* **Range:** `0` to `16`
* **Introduced:** [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/)

 

---

 #### `connect_enable_mongo`

 * **Description:** Enable the [Mongo table type](../connect-mongo-table-type/index).
* **Commandline:** `--connect-enable-mongo={0|1}`
* **Scope:** Global, Session
* **Dynamic:**
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/)
* **Removed:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `connect_exact_info`

 * **Description:** Whether the CONNECT engine should return an exact record number value to information queries. It is OFF by default because this information can take a very long time for large variable record length tables or for remote tables, especially if the remote server is not available. It can be set to ON when exact values are desired, for instance when querying the repartition of rows in a partition table.
* **Commandline:** `--connect-exact-info={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `connect_force_bson`

 * **Description:** Force using BSON for JSON tables. Starting with these releases, the internal way JSON was parsed and handled was changed. The main advantage of the new way is to reduce the memory required to parse JSON (from 6 to 10 times the size of the JSON source to now only 2 to 4 times). However, this is in Beta mode and JSON tables are still handled using the old mode. To use the new mode, tables should be created with TABLE\_TYPE=BSON, or by setting this session variable to 1 or ON. Then, all JSON tables will be handled as BSON. This is temporary until the new way replaces the old way by default.
* **Commandline:** `--connect-force-bson={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/)

 

---

 #### `connect_indx_map`

 * **Description:** Enable file mapping for index files. To accelerate the indexing process, CONNECT makes an index structure in memory from the index file. This can be done by reading the index file or using it as if it was in memory by “file mapping”. Set to 0 (file read, the default) or 1 (file mapping).
* **Commandline:** `--connect-indx-map=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `connect_java_wrapper`

 * **Description:** Java wrapper.
* **Commandline:** `--connect-java-wrapper=val`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `wrappers/JdbcInterface`

 

---

 #### `connect_json_all_path`

 * **Description:** Discovery to generate json path for all columns if ON (the default) or do not when the path is the column name.
* **Commandline:** `--connect-json-all-path={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.16](https://mariadb.com/kb/en/mariadb-10416-release-notes/)

 

---

 #### `connect_json_grp_size`

 * **Description:** Max number of rows for JSON aggregate functions.
* **Commandline:** `--connect-json-grp-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `50` (>= Connect 1.7.0003), `10` (<= Connect 1.7.0002)
* **Range:** `1` to `2147483647`

 

---

 #### `connect_json_null`

 * **Description:** Representation of JSON null values.
* **Commandline:** `--connect-json-null=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `<null>`

 

---

 #### `connect_jvm_path`

 * **Description:** Path to JVM library.
* **Commandline:** `--connect-jvm_path=value`
* **Scope:** Global
* **Dynamic:**
* **Data Type:** `string`
* **Default Value:**

 

---

 #### `connect_type_conv`

 * **Description:** Determines the handling of [TEXT](../text/index) columns.
	+ `NO`: The default until Connect 1.06.005, no conversion takes place, and a TYPE\_ERROR is returned, resulting in a “not supported” message.
	+ `YES`: The default from Connect 1.06.006. The column is internally converted to a column declared as VARCHAR(n), `n` being the value of [connect\_conv\_size](#connect_conv_size).
	+ `FORCE` (>= Connect 1.06.006): Also convert ODBC blob columns to TYPE\_STRING.
	+ `SKIP`: No conversion. When the column declaration is provided via Discovery (meaning the CONNECT table is created without a column description), this column is not generated. Also applies to ODBC tables.
* **Commandline:** `--connect-type-conv=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Valid Values:** `NO`, `YES`, `FORCE` or `SKIP`
* **Default Value:** `YES`

 

---

 #### `connect_use_tempfile`

 * **Description:**
	+ `NO`: The first algorithm is always used. Because it can cause errors when updating variable record length tables, this value should be set only for testing.
	+ `AUTO`: This is the default value. It leaves CONNECT to choose the algorithm to use. Currently it is equivalent to `NO`, except when updating variable record length tables ([DOS](../connect-table-types-data-files/index#dos-and-fix-table-types), [CSV](../connect-table-types-data-files/index#csv-and-fmt-table-types) or [FMT](../connect-table-types-data-files/index#fmt-type)) with file mapping forced to OFF.
	+ `YES`: Using a temporary file is chosen with some exceptions. These are when file mapping is ON, for [VEC](../connect-table-types-data-files/index#vec-table-type-vector) tables and when deleting from [DBF](../connect-table-types-data-files/index#dbf-type) tables (soft delete). For variable record length tables, file mapping is forced to OFF.
	+ `FORCE`: Like YES but forces file mapping to be OFF for all table types.
	+ `TEST`: Reserved for CONNECT development.
* **Commandline:** `--connect-use-tempfile=#`
* **Scope:** Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `AUTO`

 

---

 #### `connect_work_size`

 * **Description:** Size of the CONNECT work area used for memory allocation. Permits allocating a larger memory sub-allocation space when dealing with very large if sub-allocation fails. If the specified value is too big and memory allocation fails, the size of the work area remains but the variable value is not modified and should be reset.
* **Commandline:** `--connect-work-size=#`
* **Scope:** Global, Session (Session-only from CONNECT 1.03.005)
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `67108864`
* **Range:** `4194304` upwards, depending on the physical memory size

 

---

 #### `connect_xtrace`

 * **Description:** Console trace value. Set to `0` (no trace), or to other values if a console tracing is desired. Note that to test this handler, MariaDB should be executed with the [--console](../mysqld-options/index#-console) parameter because CONNECT prints some error and trace messages on the console. In some Linux versions, this is re-routed into the error log file. Console tracing can be set on the command line or later by names or values. Valid values (from Connect 1.06.006) include:
	+ `0`: No trace
	+ `YES` or `1`: Basic trace
	+ `MORE` or `2`: More tracing
	+ `INDEX` or `4`: Index construction
	+ `MEMORY` or `8`: Allocating and freeing memory
	+ `SUBALLOC` or `16`: Sub-allocating in work area
	+ `QUERY` or `32`: Constructed query sent to external server
	+ `STMT` or `64`: Currently executing statement
	+ `HANDLER` or `128`: Creating and dropping CONNECT handlers
	+ `BLOCK` or `256`: Creating and dropping CONNECT objects
	+ `MONGO` or `512`: Mongo and REST (from [Connect 1.06.0010](../connect/index)) tracing
* For example:
	+ `set global connect_xtrace=0;  *No trace*`
	+ `set global connect_xtrace='YES';  *By name*`
	+ `set global connect_xtrace=1;  *By value*`
	+ `set global connect_xtrace='QUERY,STMT';  *By name*`
	+ `set global connect_xtrace=96;  *By value*`
	+ `set global connect_xtrace=1023;  *Trace all*`
* **Commandline:** `--connect-xtrace=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `set`
* **Default Value:** `0`
* **Valid Values:** See description

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-system-variables/>

MyISAM System Variables
=======================

     This page documents system variables related to the [MyISAM](../myisam/index) storage engine. For options, see [MyISAM Options](../mysqld-options/index#myisam-options).

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `key_buffer_size`

 * **Description:** Size of the buffer for the index blocks used by MyISAM tables and shared for all threads. See [Optimizing key\_buffer\_size](../optimizing-key_buffer_size/index) for more on selecting the best value.
* **Commandline:** `--key-buffer-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `134217728`
* **Range:** `8` upwards (upper limit determined by operating system per process limit)

 

---

 #### `key_cache_age_threshold`

 * **Description:** The lower the setting, the more quickly buffers move from the hot key cache sublist to the warm sublist.
* **Commandline:** `--key-cache-age-threshold=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `300`
* **Range:** `100` to `4294967295`

 

---

 #### `key_cache_block_size`

 * **Description:** [MyISAM](../myisam/index) key cache block size in bytes .
* **Commandline:** `--key-cache-block-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `512` to `16384`

 

---

 #### `key_cache_division_limit`

 * **Description:** Percentage to use for the warm key cache buffer list (the remainder is allocated between the hot and cold caches).
* **Commandline:** `--key-cache-division-limit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `1` to `100`

 

---

 #### `key_cache_file_hash_size`

 * **Description:** Number of hash buckets for open and changed files. If you have many MyISAM files open you should increase this for faster flushing of changes. A good value is probably 1/10th of the number of possible open MyISAM files.
* **Commandline:** `--key-cache-file-hash-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `512`
* **Range:** `128` to `16384`

 

---

 #### `key_cache_segments`

 * **Description:** The number of segments in a key cache. See [Segmented Key Cache](../segmented-key-cache/index).
* **Commandline:** `--key-cache-segments=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Type:** numeric
* **Default Value:** `0` *(non-segmented)*
* **Range:** `0` to `64`

 

---

 #### `myisam_block_size`

 * **Description:** Block size to be used for MyISAM index pages.
* **Commandline:** `--myisam-block-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1024`

 

---

 #### `myisam_data_pointer_size`

 * **Description:** Size in bytes of the default pointer, used in a [MyISAM](../myisam/index) [CREATE TABLE](../create-table/index) with no MAX\_ROWS option.
* **Commandline:** `--myisam-data-pointer-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `6`
* **Range:** `2` to `7`

 

---

 #### `myisam_max_extra_sort_file_size`

 * **Description:** Removed in MySQL 5.0.6, was used as a way to force long character keys in large tables to use the key cache method.
* **Removed:** MySQL 5.0.6

 

---

 #### `myisam_max_sort_file_size`

 * **Description:** Maximum size in bytes of the temporary file used while recreating a MyISAM index. If the this size is exceeded, the slower process of using the key cache is done instead.
* **Commandline:** `--myisam-max-sort-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value - 32 bit:** `2147483648`
* **Default Value - 64 bit:** `9223372036854775807`

 

---

 #### `myisam_mmap_size`

 * **Description:** Maximum memory in bytes that can be used for memory mapping compressed MyISAM files. Too high a value may result in swapping if there are many compressed MyISAM tables.
* **Commandline:** `--myisam-mmap-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value - 32 bit:** `4294967295`
* **Default Value - 64 bit:** `18446744073709547520`
* **Range - 32-bit:** `7` to `4294967295`
* **Range - 64-bit:** `7` to `18446744073709547520`

 

---

 #### `myisam_recover_options`

 * **Description:** MyISAM recovery mode. Multiple options can be selected, comma-delimited. Using no argument is equivalent to specifying `DEFAULT`, while specifying "" is equivalent to `OFF`. If enabled each time the server opens a MyISAM table, it checks whether it has been marked as crashed, or wasn't closed properly. If so, mysqld will run a check and then attempt to repair the table, writing to the error log beforehand.
	+ **OFF**: No recovery.
	+ **BACKUP**: If the data file is changed while recovering, saves a backup of the .MYD data file. t.MYD will be saved as t.MYD-datetime.BAK.
	+ **BACKUP\_ALL**: Same as `BACKUP` but also backs up the .MYI index file. t.MYI will be saved as t.MYI-datetime.BAK.
	+ **DEFAULT**: Recovers without backing up, forcing, or quick checking.
	+ **FORCE**: Runs the recovery even if it determines that more than one row from the data file will be lost.
	+ **QUICK**: Does not check rows in the table if there are no delete blocks.
* **Commandline:** `--myisam-recover-options[=name]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumeration`
* **Default Value:**
	+ `BACKUP,QUICK` (>= [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/))
	+ `DEFAULT` (<= [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/))
	+ `OFF`
* **Valid Values:** `OFF`, `DEFAULT`, `BACKUP`, `BACKUP_ALL`, `FORCE` or `QUICK`

 

---

 #### `myisam_repair_threads`

 * **Description:** If set to more than `1`, the default, MyISAM table indexes each have their own thread during repair and sorting. Increasing from the default will usually result in faster repair, but will use more CPU and memory.
* **Commandline:** `--myisam-repair-threads=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range - 32-bit:** `1` to `4294967295`
* **Range - 64-bit:** `1` to `18446744073709547520`

 

---

 #### `myisam_sort_buffer_size`

 * **Description:** Size in bytes of the buffer allocated when creating or sorting indexes on a MyISAM table.
* **Commandline:** `--myisam-sort-buffer-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `134217720` (128MB)
* **Range:** `4096` to `18446744073709547520`

 

---

 #### `myisam_stats_method`

 * **Description:** Determines how NULLs are treated for [MyISAM](../myisam/index) index statistics purposes. If set to `nulls_equal`, the default, all NULL index values are treated as a single group. This is usually fine, but if you have large numbers of NULLs the average group size is slanted higher, and the optimizer may miss using the index for ref accesses when it would be useful. If set to `nulls_unequal`, the opposite approach is taken, with each NULL forming its own group of one. Conversely, the average group size is slanted lower, and the optimizer may use the index for ref accesses when not suitable. Setting to `nulls_ignored` ignores NULLs altogether from index group calculations. See also [Index Statistics](../index-statistics/index), [aria\_stats\_method](../aria-server-system-variables/index#aria_stats_method), [innodb\_stats\_method](../xtradbinnodb-server-system-variables/index#innodb_stats_method).
* **Commandline:** `--myisam-stats-method=name`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enumeration`
* **Default Value:** `nulls_equal`
* **Valid Values:** `nulls_equal`, `nulls_unequal`, `nulls_ignored`

 

---

 #### `myisam_use_mmap`

 * **Description:** If set to `1` (0 is default), memory mapping will be used to reading and writing MyISAM tables.
* **Commandline:** `--myisam-use-mmap`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-system-variables/>

GROUP BY
========

     Use the `GROUP BY` clause in a [SELECT](../select/index) statement to group rows together that have the same value in one or more column, or the same computed value using expressions with any [functions and operators](../functions-and-operators/index) except [grouping functions](../functions-and-modifiers-for-use-with-group-by/index). When you use a `GROUP BY` clause, you will get a single result row for each group of rows that have the same value for the expression given in `GROUP BY`.

 When grouping rows, grouping values are compared as if by the `[=](../equal/index)` operator. For string values, the `=` operator ignores trailing whitespace and may normalize characters and ignore case, depending on the [collation](../data-types-character-sets-and-collations/index) in use.

 You can use any of the grouping functions in your select expression. Their values will be calculated based on all the rows that have been grouped together for each result row. If you select a non-grouped column or a value computed from a non-grouped column, it is undefined which row the returned value is taken from. This is not permitted if the `ONLY_FULL_GROUP_BY` [SQL\_MODE](../sql-mode/index) is used.

 You can use multiple expressions in the `GROUP BY` clause, separated by commas. Rows are grouped together if they match on each of the expressions.

 You can also use a single integer as the grouping expression. If you use an integer *n*, the results will be grouped by the *n*th column in the select expression.

 The `WHERE` clause is applied before the `GROUP BY` clause. It filters non-aggregated rows before the rows are grouped together. To filter grouped rows based on aggregate values, use the `HAVING` clause. The `HAVING` clause takes any expression and evaluates it as a boolean, just like the `WHERE` clause. You can use grouping functions in the `HAVING` clause. As with the select expression, if you reference non-grouped columns in the `HAVING` clause, the behavior is undefined.

 By default, if a `GROUP BY` clause is present, the rows in the output will be sorted by the expressions used in the `GROUP BY`. You can also specify `ASC` or `DESC` (ascending, descending) after those expressions, like in [ORDER BY](../order-by/index). The default is `ASC`.

 If you want the rows to be sorted by another field, you can add an explicit [ORDER BY](../order-by/index). If you don't want the result to be ordered, you can add [ORDER BY NULL](../order-by/index).

 ### WITH ROLLUP

 The `WITH ROLLUP` modifer adds extra rows to the resultset that represent super-aggregate summaries. For a full description with examples, see [SELECT WITH ROLLUP](../select-with-rollup/index).

 ### GROUP BY Examples

 Consider the following table that records how many times each user has played and won a game:

 
```
CREATE TABLE plays (name VARCHAR(16), plays INT, wins INT);
INSERT INTO plays VALUES 
  ("John", 20, 5), 
  ("Robert", 22, 8), 
  ("Wanda", 32, 8), 
  ("Susan", 17, 3);

```

Get a list of win counts along with a count:

 
```
SELECT wins, COUNT(*) FROM plays GROUP BY wins;
+------+----------+
| wins | COUNT(*) |
+------+----------+
|    3 |        1 |
|    5 |        1 |
|    8 |        2 |
+------+----------+
3 rows in set (0.00 sec)

```

The `GROUP BY` expression can be a computed value, and can refer back to an identifer specified with `AS`. Get a list of win averages along with a count:

 
```
SELECT (wins / plays) AS winavg, COUNT(*) FROM plays GROUP BY winavg;
+--------+----------+
| winavg | COUNT(*) |
+--------+----------+
| 0.1765 |        1 |
| 0.2500 |        2 |
| 0.3636 |        1 |
+--------+----------+
3 rows in set (0.00 sec)

```

You can use any [grouping function](../functions-and-modifiers-for-use-with-group-by/index) in the select expression. For each win average as above, get a list of the average play count taken to get that average:

 
```
SELECT (wins / plays) AS winavg, AVG(plays) FROM plays 
  GROUP BY winavg;
+--------+------------+
| winavg | AVG(plays) |
+--------+------------+
| 0.1765 |    17.0000 |
| 0.2500 |    26.0000 |
| 0.3636 |    22.0000 |
+--------+------------+
3 rows in set (0.00 sec)

```

You can filter on aggregate information using the `HAVING` clause. The `HAVING` clause is applied after `GROUP BY` and allows you to filter on aggregate data that is not available to the `WHERE` clause. Restrict the above example to results that involve an average number of plays over 20:

 
```
SELECT (wins / plays) AS winavg, AVG(plays) FROM plays 
  GROUP BY winavg HAVING AVG(plays) > 20;
+--------+------------+
| winavg | AVG(plays) |
+--------+------------+
| 0.2500 |    26.0000 |
| 0.3636 |    22.0000 |
+--------+------------+
2 rows in set (0.00 sec)

```

### See Also

 * [SELECT](../select/index)
* [Joins and Subqueries](../joins-subqueries/index)
* [LIMIT](../limit/index)
* [ORDER BY](../order-by/index)
* [Common Table Expressions](../common-table-expressions/index)
* [SELECT WITH ROLLUP](../select-with-rollup/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* [FOR UPDATE](../for-update/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [Optimizer Hints](../optimizer-hints/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/group-by/>

Hashicorp Key Management Plugin
===============================

    
**MariaDB starting with [10.9](../what-is-mariadb-109/index)**The Hashicorp Key Management Plugin is used to implement encryption using keys stored in the Hashicorp Vault KMS. For more information, see [Hashicorp Vault and MariaDB](../hashicorp-vault-and-mariadb/index), and for how to install Vault, see [Install Vault](https://www.vaultproject.io/docs/install), as well as [MySQL/MariaDB Database Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/databases/mysql-maria).

  The current version of this plugin implements the following features:

 * Authentication is done using the Hashicorp Vault's token authentication method;
* If additional client authentication is required, then the path to the CA authentication bundle file may be passed as a plugin parameter;
* The creation of the keys and their management is carried out using the Hashicorp Vault KMS and their tools;
* The plugin uses libcurl (https) as an interface to the HashiCorp Vault server;
* JSON parsing is performed through the JSON service (through the include/mysql/service\_json.h);
* HashiCorp Vault 1.2.4 was used for development and testing.

 Since we require support for key versioning, the key-value storage must be configured in Hashicorp Vault as a key-value storage that uses the interface of the second version. For example, you can create it as follows:

 
```
~$ vault secrets enable -path /test -version=2 kv

```

Key names must correspond to their numerical identifiers. Key identifiers itself, their possible values and rules of use are described in more detail in the MariaDB main documentation.

 From the point of view of the key-value storage (in terms of Hashicorp Vault), the key is a secret containing one key-value pair with the name "data" and a value representing a binary string containing the key value, for example:

 
```
~$ vault kv get /test/1

====== Metadata ======
Key              Value
---              -----
created_time     2019-12-14T14:19:19.42432951Z
deletion_time    n/a
destroyed        false
version          1

==== Data ====
Key     Value
---     -----
data    0123456789ABCDEF0123456789ABCDEF

```

Keys values are strings containing binary data. MariaDB currently uses the AES algorithm with 256-bit keys as the default encryption method. In this case, the keys that will be stored in the Hashicorp Vault should be 32-byte strings. Most likely you will use some utilities for creating and administering keys designed to work with Hashicorp Vault. But in the simplest case, keys can be created from the command line through the vault utility, for example, as follows:

 
```
~$ vault kv put /test/1 data="0123456789ABCDEF0123456789ABCDEF"

```

If you use default encryption (AES), you should ensure that the key length is 32 bytes, otherwise it may fail to use InnoDB as a data storage.

 The plugin currently does not unseal Hashicorp Vault on its own, you must do this in advance and on your own.

 To use Hashicorp Vault KMS, the plugin must be preloaded and activated on the server. Most of its parameters should not be changed during plugin operation and therefore must be preconfigured as part of the server configuration through configuration file or command line options:

 
```
--plugin-load-add=hashicorp_key_management.so
--loose-hashicorp-key-management
--loose-hashicorp-key-management-vault-url="$VAULT_ADDR/v1/test"
--loose-hashicorp-key-management-token="$VAULT_TOKEN"

```

### Options

 The plugin supports the following parameters, which must be set in advance and cannot be changed during server operation:

 #### `hashicorp-key-management-vault-url`

 * **Description:** HTTP[s] URL that is used to connect to the Hashicorp Vault server. It must include the name of the scheme (`https://` for a secure connection) and, according to the API rules for storages of the key-value type in Hashicorp Vault, after the server address, the path must begin with the "/v1/" string (as prefix), for example: `https://127.0.0.1:8200/v1/my_secrets`. By default, the path is not set, therefore you must replace with the correct path to your secrets.
* **Commandline:** `--[loose-]hashicorp-key-management-vault-url="<url>"`

 #### `hashicorp-key-management-token`

 * **Description:** Authentication token that passed to the Hashicorp Vault in the request header. By default, this parameter contains an empty string, so you must specify the correct value for it, otherwise the Hashicorp Vault server will refuse authorization.
* **Commandline:** `--[loose-]hashicorp-key-management-token="<token>"`

 #### `hashicorp-key-management-vault-ca`

 * **Description:** Path to the Certificate Authority (CA) bundle (is a file that contains root and intermediate certificates). By default, this parameter contains an empty string, which means no CA bundle.
* **Commandline:** `--[loose-]hashicorp-key-management-vault-ca="<path>"`

 #### `hashicorp-key-management-timeout`

 * **Description:** Set the duration (in seconds) for the Hashicorp Vault server connection timeout. The default value is 15 seconds. The allowed range is from 1 to 86400 seconds. The user can also specify a zero value, which means the default timeout value set by the libcurl library (currently 300 seconds).
* **Commandline:** `--[loose-]hashicorp-key-management-timeout=<timeout>`

 #### `hashicorp-key-management-retries`

 * **Description:** Number of server request retries in case of timeout. Default is three retries.
* **Commandline:** `----[loose-]hashicorp-key-management-retries=<retries>`

 #### `hashicorp-key-management-caching-enabled`

 * **Description:** Enable key caching (storing key values received from the Hashicorp Vault server in the local memory). By default caching is enabled.
* **Commandline:** `--[loose-]hashicorp-key-management-caching-enabled="on"|"off"`

 #### `hashicorp-key-management-use-cache-on-timeout`

 * **Description:** This parameter instructs the plugin to use the key values or version numbers taken from the cache in the event of a timeout when accessing the vault server. By default this option is disabled. Please note that key values or version numbers will be read from the cache when the timeout expires only after the number of attempts to read them from the storage server that specified by the --[loose-]hashicorp-key-management-retries parameter has been exhausted.
* **Commandline:** `--[loose-]hashicorp-key-management-use-cache-on-timeout="on"|"off"`

 #### `hashicorp-key-management-cache-timeout`

 * **Description:** The time (in milliseconds) after which the value of the key stored in the cache becomes invalid and an attempt to read this data causes a new request send to the vault server. By default, cache entries become invalid after 60,000 milliseconds (after one minute). If the value of this parameter is zero, then the keys will always be considered invalid, but they still can be used if the vault server is unavailable and the corresponding cache operating mode (--[loose-]hashicorp-key-management-use-cache-on-timeout="on") is enabled.
* **Commandline:** `--[loose-]hashicorp-key-management-cache-timeout=<timeout>`

 #### `hashicorp-key-management-cache-version-timeout`

 * **Description:** The time (in milliseconds) after which the information about latest version number of the key (which stored in the cache) becomes invalid and an attempt to read this information causes a new request send to the vault server. If the value of this parameter is zero, then information about latest key version numbers always considered invalid, unless there is no communication with the vault server and use of the cache is allowed when the server is unavailable. By default, this parameter is zero, that is, the latest version numbers for the keys stored in the cache are considered always invalid, except when the vault server is unavailable and use of the cache is allowed on server failures.
* **Commandline:** `--[loose-]hashicorp-key-management-cache-version-timeout=<timeout>`

 #### `hashicorp-key-management-check-kv-version`

 * **Description:** This parameter enables ("on", this is the default value) or disables ("off") checking the kv storage version during plugin initialization. The plugin requires storage to be version 2 or older in order for it to work properly.
* **Commandline:** `--[loose-]hashicorp-key-management-check-kv-version="on"|"off"`

 See Also
--------

 * [HashiCorp Vault and MariaDB](../hashicorp-vault-and-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hashicorp-key-management-plugin/>

OQGRAPH System and Status Variables
===================================

    This page documents system and status variables related to the [OQGRAPH storage engine](../oqgraph/index). See [Server Status Variables](../server-status-variables/index) and [Server System Variables](../server-system-variables/index) for complete list of all system and status variables.

 System Variables
----------------

 #### `oqgraph_allow_create_integer_latch`

 * **Description:** Created when the [OQGRAPH](../oqgraph/index) storage engine is installed, if set to `1` (`0` is default), permits the `latch` field to be an integer (see [OQGRAPH Overview](../oqgraph-overview/index#creating-a-table)).
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 Status Variables
----------------

 #### `Oqgraph_boost_version`

 * **Description:** [OQGRAPH](../oqgraph/index) boost version.
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

 #### `Oqgraph_compat_mode`

 * **Description:** Whether or not legacy tables with integer latches are supported.
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

 #### `Oqgraph_verbose_debug`

 * **Description:** Whether or not verbose debugging is enabled. If it is, performance may be adversely impacted
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oqgraph-system-and-status-variables/>

Mroonga Status Variables
========================

    This page documents status variables related to the [Mroonga storage engine](../mroonga/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 #### `Mroonga_count_skip`

 * **Description:** Incremented each time the 'fast line count feature' is used. Can be used to check if the feature is working after enabling it.
* **Data Type:** `numeric`

 

---

 #### `Mroonga_fast_order_limit`

 * **Description:** Incremented each time the 'fast ORDER BY LIMIT feature' is used. Can be used to check if the feature is working after enabling it.
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga-status-variables/>

Cassandra System Variables
==========================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

   This page documents system variables related to the [Cassandra storage engine](../cassandra/index). See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 #### `cassandra_default_thrift_host`

 * **Description:** Host to connect to, if not specified on per-table basis.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`

 

---

 #### `cassandra_failure_retries`

 * **Description:** Number of times to retry on timeout/unavailable failures.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `3`
* **Valid Values:** `1` to `1073741824`

 

---

 #### `cassandra_insert_batch_size`

 * **Description:** INSERT batch size.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Valid Values:** `1` to `1073741824`

 

---

 #### `cassandra_multiget_batch_size`

 * **Description:** Batched Key Access batch size.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Valid Values:** `1` to `1073741824`

 

---

 #### `cassandra_read_consistency`

 * **Description:** Consistency to use for reading. See [Datastax's documentation](http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_config_consistency_c.html) for details.
* **Scope:** Global, Session
* **Default Value:** `ONE`
* **Valid Values:** `ONE`, `TWO`, `THREE`, `ANY`, `ALL`, `QUORUM`, `EACH_QUORUM`, `LOCAL_QUORUM`,

 

---

 #### `cassandra_rnd_batch_size`

 * **Description:** Full table scan batch size.
* **Scope:** Global, Session
* **Default Value:** `10000`
* **Valid Values:** `1` to `1073741824`

 

---

 #### `cassandra_write_consistency`

 * **Description:** Consistency to use for writing. See [Datastax's documentation](http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_config_consistency_c.html) for details.
* **Scope:** Global, Session
* **Default Value:** `ONE`
* **Valid Values:** `ONE`, `TWO`, `THREE`, `ANY`, `ALL`, `QUORUM`, `EACH_QUORUM`, `LOCAL_QUORUM`,

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-system-variables/>

SSL/TLS System Variables
========================

    The system variables listed on this page relate to encrypting data during transfer between servers and clients using the Transport Layer Security (TLS) protocol. Often, the term Secure Sockets Layer (SSL) is used interchangeably with TLS, although strictly speaking the SSL protocol is the predecessor of TLS and is no longer considered secure.

 For compatibility reasons, the TLS system variables in MariaDB still use the `ssl_` prefix, but MariaDB only supports its more secure successors. For more information on SSL/TLS in MariaDB, see [Secure Connections Overview](../secure-connections-overview/index).

 Variables
---------

 #### `have_openssl`

 * **Description:** This variable shows whether the server is linked with [OpenSSL](https://www.openssl.org/) rather than MariaDB's bundled TLS library, which might be [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/).
	+ In [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) and later, if this system variable shows `YES`, then the server is linked with OpenSSL.
	+ In [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) and before, this system variable was an alias for the `[have\_ssl](#have_ssl)` system variable.
	+ See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `have_ssl`

 * **Description:** This variable shows whether the server supports using [TLS](../data-in-transit-encryption/index) to secure connections.
	+ If the value is `YES`, then the server supports TLS, and TLS is enabled.
	+ If the value is `DISABLED`, then the server supports TLS, but TLS is **not** enabled.
	+ If the value is `NO`, then the server was not compiled with TLS support, so TLS cannot be enabled.
	+ When TLS is supported, check the `[have\_openssl](#have_openssl)` system variable to determine whether the server is using OpenSSL or MariaDB's bundled TLS library. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Scope:** Global
* **Dynamic:** No

 

---

 #### `ssl_ca`

 * **Description:** Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path. This system variable implies the `[ssl](../mysqld-options/index#-ssl)` option.
	+ See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information.
* **Commandline:** `--ssl-ca=file_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`

 

---

 #### `ssl_capath`

 * **Description:** Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path. The directory specified by this variable needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. This system variable implies the `[ssl](../mysqld-options/index#-ssl)` option.
	+ See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information.
* **Commandline:** `--ssl-capath=directory_name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`

 

---

 #### `ssl_cert`

 * **Description:** Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path. This system variable implies the `[ssl](../mysqld-options/index#-ssl)` option.
* **Commandline:** `--ssl-cert=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** None

 

---

 #### `ssl_cipher`

 * **Description:** List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). Besides cipher names, if MariaDB was compiled with OpenSSL, this variable could be set to "SSLv3" or "TLSv1.2" to allow all SSLv3 or all TLSv1.2 ciphers. Note that the TLSv1.3 ciphers cannot be excluded when using OpenSSL, even by using this system variable. See [Using TLSv1.3](../using-tlsv13/index) for details. This system variable implies the `[ssl](../mysqld-options/index#-ssl)` option.
* **Commandline:** `--ssl-cipher=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None

 

---

 #### `ssl_crl`

 * **Description:** Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path.
	+ See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.
	+ This variable is only valid if the server was built with OpenSSL. If the server was built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then this variable is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Commandline:** `--ssl-crl=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `file name`
* **Default Value:** None
* **Introduced:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `ssl_crlpath`

 * **Description:** Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path. The directory specified by this variable needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command.
	+ See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.
	+ This variable is only supported if the server was built with OpenSSL. If the server was built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then this variable is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Commandline:** `--ssl-crlpath=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `directory name`
* **Default Value:** None
* **Introduced:** [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/)

 

---

 #### `ssl_key`

 * **Description:** Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This system variable requires that you use the absolute path, not a relative path. This system variable implies the [ssl](../mysqld-options/index#-ssl) option.
* **Commandline:** `--ssl-key=name`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None

 

---

 #### `tls_version`

 * **Description:** This system variable accepts a comma-separated list (with no whitespaces) of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted.
	+ See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information.
* **Commandline:** `--tls-version=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** TLSv1.1,TLSv1.2,TLSv1.3
* **Valid Values:** TLSv1.0,TLSv1.1,TLSv1.2,TLSv1.3
* **Introduced:** [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)

 

---

 #### `version_ssl_library`

 * **Description:** The version of the [TLS](../data-in-transit-encryption/index) library that is being used. Note that the version returned by this system variable does not always necessarily correspond to the exact version of the OpenSSL package installed on the system. OpenSSL shared libraries tend to contain interfaces for multiple versions at once to allow for backward compatibility. Therefore, if the OpenSSL package installed on the system is newer than the OpenSSL version that the MariaDB server binary was built with, then the MariaDB server binary might use one of the interfaces for an older version.
	+ See [TLS and Cryptography Libraries Used by MariaDB: Checking the Server's OpenSSL Version](../tls-and-cryptography-libraries-used-by-mariadb/index#checking-the-servers-openssl-version) for more information.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** None
* **Introduced:** [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 

---

 See Also
--------

 * [Secure Connections Overview](../secure-connections-overview/index)
* [System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.
* [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ssl-server-system-variables/>

Disks Plugin
============

    The `DISKS` plugin creates the [DISKS](../information-schema-disks-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. This table shows metadata about disks on the system.

 Before [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) and [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), this plugin did **not** check [user privileges](../grant/index). When it is enabled, **any** user can query the `INFORMATION_SCHEMA.DISKS` table and see all the information it provides.

 Since [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) and [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/) , it required the [FILE privilege](../grant/index).

 The plugin only works on Linux.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'disks';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = disks

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'disks';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
SELECT * FROM information_schema.DISKS;

+-----------+-------+----------+---------+-----------+
| Disk      | Path  | Total    | Used    | Available |
+-----------+-------+----------+---------+-----------+
| /dev/vda1 | /     | 26203116 | 2178424 |  24024692 |
| /dev/vda1 | /boot | 26203116 | 2178424 |  24024692 |
| /dev/vda1 | /etc  | 26203116 | 2178424 |  24024692 |
+-----------+-------+----------+---------+-----------+

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.1 | Stable | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/) |
| 1.0 | Beta | [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), [MariaDB 10.2.14](https://mariadb.com/kb/en/mariadb-10214-release-notes/), [MariaDB 10.1.32](https://mariadb.com/kb/en/mariadb-10132-release-notes/) |

 
Options
-------

 ### `disks`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--disks=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/disks-plugin/>

PBXT System Variables
=====================

    
**MariaDB until [5.3](../what-is-mariadb-53/index)**PBXT is no longer maintained, and is not part of [MariaDB 5.5](../what-is-mariadb-55/index) or later.

 
This page documents system variables related to the [PrimeBase XT storage engine (PBXT)](../pbxt/index). PBXT is no longer maintained, and is not part of [MariaDB 5.5](../what-is-mariadb-55/index) or later.

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 Variables that specify a number of bytes may include a unit indication after the value. For example: 100KB, 64MB, etc. There should be no space between the number and the unit. Units are case insensitive (KB = Kb = kb). If no unit is specified then bytes is assumed. The recognized units are:

 * **KB** (or **K**) - Kilobyte, 1024 bytes
* **MB** (or **M**) - Megabyte, 1024 KB
* **GB** (or **G**) - Gigabyte, 1024 MB
* **TB** (or **T**) - Terabyte, 1024 GB
* **PB** (or **P**) - Petabyte, 1024 TB

 Variables which use this type of value are: `pbxt_index_cache_size`, `pbxt_record_cache_size`, `pbxt_log_cache_size`, `pbxt_log_file_threshold`, `pbxt_checkpoint_frequency`, `pbxt_data_log_threshold`, `pbxt_log_buffer_size`, `pbxt_data_file_grow_size`, and `pbxt_row_file_grow_size`.

 #### PBXT Data Log Variables

 PBXT stores part of the database in the data logs. This is mostly data from rows containing long VARCHAR fields or BLOB data. The data logs are managed by the "compactor" thread. When a record is deleted from a data log, the data is marked as garbage. When the total garbage in a data log reaches a certain threshold, the compactor thread compacts the data log by copying the valid data to a new data log, and deleting the old data log.

 #### Options for PBXT

 


| Option | Default Value |
| --- | --- |
| ``--`pbxt` | `ON` |
| ``--`pbxt-max-threads` | `0` |
| ``--`pbxt-statistics` | `ON` |

 
#### `pbxt_auto_increment_mode`

 * **Description:** The parameter determines how PBXT manages auto-increment values. Possible values are '`0`' (MySQL standard) or '`1`' (Previous IDs are never re-used).  
  
In the standard 'MySQL' mode it is possible that an auto-increment value is re-issued. This occurs when the maximum auto-increment value is deleted, and then MariaDB is restarted. This occurs because the next auto-increment value to be issued is determined at startup by retrieving the current maximum auto-increment value from the table.  
  
In mode 1, auto-increment values are never re-issued because PBXT automatically incrementing the table level AUTO\_INCREMENT table option. The AUTO\_INCREMENT table is incremented in steps of 100. Since this requires the table file to be flushed to disk, this can influence performance.
* **Commandline:** `--pbxt-auto-increment-mode=#`
* **Default Value:** `0`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_checkpoint_frequency`

 * **Description:** The amount of data written to the transaction log before a checkpoint is performed.
* **Commandline:** `--pbxt-checkpoint-frequency=#`
* **Default Value:** `24MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_data_file_grow_size`

 * **Description:** The grow size of the handle data (.xtd) files.
* **Commandline:** `--pbxt-data-file-grow-size=#`
* **Default Value:** `2MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_data_log_threshold`

 * **Description:** The maximum size of a data log file. PBXT can create a maximum of 32000 data logs, which are used by all tables. So the value of this variable can be increased to increase the total amount of data that can be stored in the database.
* **Commandline:** `--pbxt-data-log-threshold=#`
* **Default Value:** `64MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_flush_log_at_trx_commit`

 * **Description:** This variable specifies the durability of recently committed transactions. By reducing the durability, the speed of write operations can be increased.  
  
'`0`' - Lowest durability, the transaction log is not written or flushed on transaction commit. In this case it is possible to loose transactions if the server executable crashes.  
'`1`' - Full-durability, the transaction log is written and flushed on every transaction commit.  
'`2`' - Medium durabilty, the transaction log is written, but not flushed on transaction commit. In this case it is possible to loose transactions of the server machine crashes (for example, a power failer).  
  
In all cases, the transaction log is flushed at least once every second. This means that it is only every possible to loose database changes that occurred within the last second.
* **Commandline:** `--pbxt-flush-log-at-trx-commit=#`
* **Default Value:** `1`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_garbage_threshold`

 * **Description:** The percentage of garbage in a data log file before it is compacted. This is a value between 1 and 99.
* **Commandline:** `--pbxt-garbage-threshold=#`
* **Default Value:** `50`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_index_cache_size`

 * **Description:** The amount of memory allocated to the index cache. The memory allocated here is used only for caching index pages (.xti files).
* **Commandline:** `--pbxt-index-cache-size=#`
* **Default Value:** `32MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_log_buffer_size`

 * **Description:** This is the size of the buffer used when writing a data log. The engine allocates one buffer per thread, but only if the thread is required to write a data log.
* **Commandline:** `--pbxt-log-buffer-size=#`
* **Default Value:** `256MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_log_cache_size`

 * **Description:** The size of a transaction log file (xlog-\*.xt files) before "rollover", and a new log file is created.
* **Commandline:** `--pbxt-log-cache-size=#`
* **Default Value:** `32MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_log_file_count`

 * **Description:** The number of transaction log files on disk before logs that are no longer required are deleted, default value is 3. The number of transaction logs on disk may exceed this number if the logs are still being read.  
  
If a transaction log has been read (i.e. the log is offline), it will be recycled for writing again, unless it must be deleted because the number of logs on disk exceeds this threshold. Recycling logs is an optimization because the writing a pre-allocated file is faster then writing to the end of a file.  
  
Note: an exception to this rule is Mac OS X. On Mac OS X old log files are not recycled because writing pre-allocated file is slower than writing to the end of file.
* **Commandline:** `--pbxt-log-file-count=#`
* **Default Value:** `3`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_log_file_threshold`

 * **Description:** The size of a transaction log file (xlog-\*.xt files) before "rollover", and a new log file is created.
* **Commandline:** `--pbxt-log-file-threshold=#`
* **Default Value:** `32MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_offline_log_function`

 * **Description:** This variable determines what happens to a transaction log when it is offline. A log is offline if PBXT is no longer reading or writing to the log. There are 3 possibilities:  
  
'`0`' - Recycle log (default). This means the log is renamed and written again.  
'`1`' - Delete log (default on Mac OS X).  
'`2`' - Keep log. The logs can be used to repeat all operations that were applied to the database.
* **Commandline:** `--pbxt-offline-log-function=#`
* **Default Value:** `0`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_record_cache_size`

 * **Description:** This is the amount of memory allocated to the record cache used to cache table data. This memory is used to cache changes to the handle data (.xtd) and row index (.xtr) files.
* **Commandline:** `--pbxt-record-cache-size=#`
* **Default Value:** `32MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_row_file_grow_size`

 * **Description:** The grow size of the row index (.xtr) files.
* **Commandline:** `--pbxt-row-file-grow-size=#`
* **Default Value:** `256KB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_sweeper_priority`

 * **Description:** Determines the priority of the background Sweeper thread. Possible values are '`0`' (Low), '`1`' (Normal), or '`2`' (High). The Sweeper is responsible for removing deleted records and index entries (deleted records also result from UPDATE statements). If many old deleted records accumulate search operations become slower. Therefore it may improve performance to increase the priority of the Sweeper on a machine with 4 or more cores.
* **Commandline:** `--pbxt-sweeper-priority=#`
* **Default Value:** `0`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_support_xa`

 * **Description:** This variable determines if XA (2-phase commit) support is enabled.
* **Commandline:** `--pbxt-support-xa=#`
* **Default Value:** `TRUE`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

 #### `pbxt_transaction_buffer_size`

 * **Description:** The size of the global transaction log buffer (the engine allocates 2 buffers of this size). Data to be written to a transaction log file is first written to the transaction log buffer. Since the buffer is flushed on transaction commit, it only makes sense to use a large transaction log buffer if you have longer running transactions, or many transaction running in parallel.
* **Commandline:** `--pbxt-transaction-buffer-size=#`
* **Default Value:** `1MB`
* **Removed:** `[MariaDB 5.5](../what-is-mariadb-55/index)`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pbxt-system-variables/>

Authentication Plugin - PAM
===========================

    The `pam` authentication plugin allows MariaDB to offload user authentication to the system's [Pluggable Authentication Module (PAM)](http://en.wikipedia.org/wiki/Pluggable_authentication_module) framework. PAM is an authentication framework used by Linux, FreeBSD, Solaris, and other Unix-like operating systems.

 
**Note:** Windows does not support PAM, so the `pam` authentication plugin does not support Windows. However, one can use a MariaDB client on Windows to connect to MariaDB server that is installed on a Unix-like operating system and that is configured to use the `pam` authentication plugin. For an example of how to do this, see the blog post: [MariaDB: Improve Security with Two-Step Verification](https://mariadb.org/improve-security-with-two-step-verification/).

  Use Cases
---------

 PAM makes it possible to implement various authentication scenarios of different complexity. For example,

 * Authentication using passwords from `/etc/shadow` (indeed, this is what a default PAM configuration usually does). See the [pam\_unix](#pam_unix) PAM module.
* Authentication using LDAP. See the [pam\_ldap](#pam_ldap) PAM module.
* Authentication using Microsoft's Active Directory. See the [pam\_lsass](#pam_lsass), [pam\_winbind](#pam_winbind), and [pam\_centrifydc](#pam_centrifydc) PAM modules.
* Authentication using one-time passwords (even with SMS confirmation!). See the [pam\_google\_authenticator](#pam_google_authenticator) and [pam\_securid](#pam_securid) PAM modules.
* Authentication using SSH keys. See the [pam\_ssh](#pam_ssh) PAM module.
* User and group mapping. See the [pam\_user\_map](#pam_user_map) PAM module.
* Combining different authentication modules in interesting ways in a [PAM service](#configuring-the-pam-service).
* Password expiration.
* Limiting access by time, date, day of the week, etc. See the [pam\_time](#pam_time) PAM module.
* Logging every login attempt.
* and so on, the list is in no way exhaustive.

 Installing the Plugin
---------------------

 The `pam` authentication plugin's library is provided in [binary packages](../binary-packages/index) in all releases on Linux.

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'auth_pam';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = auth_pam

```

### Installing the v1 Plugin

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**Starting in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), the `auth_pam` shared library actually refers to version `2.0` of the `pam` authentication plugin. [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) and later also provides version `1.0` of the plugin as the `auth_pam_v1` shared library.

 
In [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) and later, if you need to install version `1.0` of the authentication plugin instead of version `2.0`, then you can do so. For example, with [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index):

 
```
INSTALL SONAME 'auth_pam_v1';

```

Or by specifying in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
plugin_load_add = auth_pam_v1

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'auth_pam';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 ### Uninstalling the v1 Plugin

 If you installed version `1.0` of the authentication plugin, then you can uninstall that by executing a similar statement for `auth_pam_v1`. For example:

 
```
UNINSTALL SONAME 'auth_pam_v1';

```

Configuring PAM
---------------

 The `pam` authentication plugin tells MariaDB to delegate the authentication to the PAM authentication framework. How exactly that authentication is performed depends on how PAM was configured. 

 ### Configuring the PAM Service

 PAM is divided into `services`. PAM services are configured by [PAM configuration files](http://www.linux-pam.org/Linux-PAM-html/sag-configuration-file.html). Typically, the global PAM configuration file is located at `/etc/pam.conf` and [PAM directory-based configuration files](http://www.linux-pam.org/Linux-PAM-html/sag-configuration-directory.html) for individual services are located in `/etc/pam.d/`.

 If you want to use a PAM service called `mariadb` for your MariaDB PAM authentication, then the PAM configuration file for that service would also be called `mariadb`, and it would typically be located at `/etc/pam.d/mariadb`.

 For example, here is a minimal PAM service configuration file that performs simple password authentication with UNIX passwords:

 
```
auth required pam_unix.so audit
account required pam_unix.so audit

```

Let's breakdown this relatively simple PAM service configuration file.

 Each line of a PAM service configuration file has the following general format:

 *type control module-path module-arguments*

 The above PAM service configuration file instructs the PAM authentication framework that for successful **authentication** (i.e. type=[auth](http://www.linux-pam.org/Linux-PAM-html/mwg-expected-of-module-auth.html)), it is **required** that the `pam_unix.so` PAM module returns a success.

 The above PAM service configuration file also instructs the PAM authentication framework that for an **account** (i.e. type=[account](http://www.linux-pam.org/Linux-PAM-html/mwg-expected-of-module-acct.html)) to be valid, it is **required** that the `pam_unix.so` PAM module returns a success. 

 PAM also supports [session](http://www.linux-pam.org/Linux-PAM-html/mwg-expected-of-module-session.html) and [password](http://www.linux-pam.org/Linux-PAM-html/mwg-expected-of-module-chauthtok.html) types, but MariaDB's `pam` authentication plugin does not support those.

 The above PAM service configuration file also provides the `audit` module argument to the `pam_unix` PAM module. The [pam\_unix manual](https://linux.die.net/man/8/pam_unix) says that this module argument enables extreme debug logging to the syslog.

 On most systems, you can find many other examples of PAM service configuration files in your `/etc/pam.d/` directory.

 #### Configuring the pam\_unix PAM Module

 If you configure PAM to use the [pam\_unix](https://linux.die.net/man/8/pam_unix) PAM module (as in the above example), then you might notice on some systems that this will fail by default with errors like the following:

 
```
Apr 14 12:56:23 localhost unix_chkpwd[3332]: check pass; user unknown
Apr 14 12:56:23 localhost unix_chkpwd[3332]: password check failed for user (alice)
Apr 14 12:56:23 localhost mysqld: pam_unix(mysql:auth): authentication failure; logname= uid=991 euid=991 tty= ruser= rhost=  user=alice

```

The problem is that on some systems, the `pam_unix` PAM module needs access to `/etc/shadow` in order to function, and most systems only allow `root` to access that file by default.

 Newer versions of PAM do not have this limitation, so you may want to try upgrading your version of PAM to see if that fixes the issue.

 If that does not work, then you can work around this problem by giving the user that runs [mysqld](../mysqld-options/index) access to `/etc/shadow`. For example, if the `mysql` user runs [mysqld](../mysqld-options/index), then you could do the following:

 
```
sudo groupadd shadow
sudo usermod -a -G shadow mysql
sudo chown root:shadow /etc/shadow
sudo chmod g+r /etc/shadow

```

And then you would have to [restart the server](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 At that point, the server should be able to read `/etc/shadow`.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**Starting in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), the `pam` authentication plugin uses a [setuid](https://linux.die.net/man/2/setuid) wrapper to perform its PAM checks, so it should not need any special workarounds to perform privileged operations, such as reading `/etc/shadow` when using the `pam_unix` PAM module. See [MDEV-7032](https://jira.mariadb.org/browse/MDEV-7032) for more information.

 
Creating Users
--------------

 Similar to all other [authentication plugins](../authentication-plugins/index), to create a user in MariaDB which uses the `pam` authentication plugin, you would execute [CREATE USER](../create-user/index) while specifying the name of the plugin in the [IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin) clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA pam;

```

If [SQL\_MODE](../sql-mode/index) does not have `NO_AUTO_CREATE_USER` set, then you can also create the user this way with [GRANT](../grant/index). For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA pam;

```

You can also specify a [PAM service name](#configuring-the-pam-service) for MariaDB to use by providing it with the `USING` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA pam USING 'mariadb';

```

This line creates a user that needs to be authenticated via the `pam` authentication plugin using the [PAM service name](#configuring-the-pam-service) `mariadb`. As mentioned in a previous section, this service's configuration file will typically be present in `/etc/pam.d/mariadb`.

 If no service name is specified, then the plugin will use `mysql` as the default [PAM service name](#configuring-the-pam-service).

 Client Authentication Plugins
-----------------------------

 For clients that use the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries, MariaDB provides two client authentication plugins that are compatible with the `pam` authentication plugin:

 * `dialog`
* `mysql_clear_password`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `pam` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mariadb --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```


Both the `dialog` and the `mysql_clear_password` client authentication plugins transmit the password to the server in clear text. Therefore, when you use the `pam` authentication plugin, it is incredibly important to [encrypt client connections using TLS](../data-in-transit-encryption/index) to prevent the clear-text passwords from being seen by unauthorized users.

 
### `dialog`

 Usually the `pam` authentication plugin uses the `dialog` client authentication plugin to communicate with the user. This client authentication plugin allows MariaDB to support arbitrarily complex PAM configurations with regular or one-time passwords, challenge-response, multiple questions, or just about anything else. When using a MariaDB client library, there is no need to install or enable anything — the `dialog` client authentication plugin is loaded by the client library completely automatically and transparently for the application.

 The `dialog` client authentication plugin was developed by MariaDB, so MySQL's clients and client libraries as well as third party applications that bundle MySQL's client libraries do not support the `dialog` client authentication plugin out of the box. If the server tells an unsupported client to use the `dialog` client authentication plugin, then the client is likely to throw an error like the following:

 
```
ERROR 2059 (HY000): Authentication plugin 'dialog' cannot be loaded: /usr/lib/mysql/plugin/dialog.so: cannot open shared object file: No such file or directory

```

For some libraries or applications, this problem can be fixed by copying `dialog.so` or `dialog.dll` from a MariaDB client installation that is compatible with the system into the system's MySQL client authentication plugin directory. However, not all clients are compatible with the `dialog` client authentication plugin, so this may not work for every client.

 If your client does not support the `dialog` client authentication plugin, then you may need to use the [mysql\_clear\_password](#mysql_clear_password) client authentication plugin instead.

 
The `dialog` client authentication plugin transmits the password to the server in clear text. Therefore, when you use the `pam` authentication plugin, it is incredibly important to [encrypt client connections using TLS](../data-in-transit-encryption/index) to prevent the clear-text passwords from being seen by unauthorized users.

 
### `mysql_clear_password`

 Users can instruct the `pam` authentication plugin to use the `mysql_clear_password` client authentication plugin instead of the [dialog](#dialog) client authentication plugin by configuring the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable on the server. It can be set in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
pam_use_cleartext_plugin

```

It is important to note that the `mysql_clear_password` plugin has very limited functionality.

 * The `mysql_clear_password` client authentication plugin only supports PAM services that require password-based authentication.

 * The `mysql_clear_password` client authentication plugin also only supports PAM services that ask the user a single question.

 * If the PAM service requires challenge-responses, multiple questions, or other similar complicated authentication schemes, then the PAM service is not compatible with `mysql_clear_password` client authentication plugin. In that case, the [dialog](#dialog) client authentication plugin will have to be used instead.

 
The `mysql_clear_password` client authentication plugin transmits the password to the server in clear text. Therefore, when you use the `pam` authentication plugin, it is incredibly important to [encrypt client connections using TLS](../data-in-transit-encryption/index) to prevent the clear-text passwords from being seen by unauthorized users.

 
#### Compatiblity with MySQL Clients and Client Libraries

 The `mysql_clear_password` client authentication plugin is similar to MySQL's [mysql\_clear\_password](https://dev.mysql.com/doc/refman/5.7/en/cleartext-pluggable-authentication.html) client authentication plugin.

 The `mysql_clear_password` client authentication plugin is compatible with MySQL clients and most MySQL client libraries, while the [dialog](#dialog) client authentication plugin is not always compatible with them. Therefore, the `mysql_clear_password` client authentication plugin is most useful if you need some kind of MySQL compatibility in your environment, but you still want to use the `pam` authentication plugin.

 Even though the `mysql_clear_password` client authentication plugin is compatible with MySQL clients and most MySQL client libraries, the `mysql_clear_password` client authentication plugin may be disabled by default by these clients and client libraries. For example, MySQL's version of the [mysql](https://dev.mysql.com/doc/refman/5.7/en/mysql.html) command-line client has the [--enable-cleartext-plugin](https://dev.mysql.com/doc/refman/5.7/en/mysql-command-options.html#option_mysql_enable-cleartext-plugin) option that must be set in order to use the `mysql_clear_password` client authentication plugin. For example:

 
```
mysql --enable-cleartext-plugin --user=alice -p 

```

Other clients may require other methods to enable the authentication plugin. For example, [MySQL Workbench](https://www.mysql.com/products/workbench/) has a checkbox titled **Enable Cleartext Authentication Plugin** under the **Advanced** tab on the connection configuration screen.

 For applications that use MySQL's `libmysqlclient`, the authentication plugin can be enabled by setting the `MYSQL_ENABLE_CLEARTEXT_PLUGIN` option with the `mysql_options()` function. For example:

 
```
mysql_options(mysql, MYSQL_ENABLE_CLEARTEXT_PLUGIN, 1);

```

For MySQL compatibility, [MariaDB Connector/C](../mariadb-connector-c/index) also allows applications to set the `MYSQL_ENABLE_CLEARTEXT_PLUGIN` option with the [mysql\_optionsv](../mysql_optionsv/index) function. However, this option does not actually do anything in [MariaDB Connector/C](../mariadb-connector-c/index), because the `mysql_clear_password` client authentication plugin is always enabled for MariaDB clients and client libraries.

 Support in Client Libraries
---------------------------

 ### Using the Plugin with MariaDB Connector/C

 [MariaDB Connector/C](../mariadb-connector-c/index) supports `pam` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section since MariaDB Connector/C 2.1.0, regardless of the value of the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable.

 ### Using the Plugin with MariaDB Connector/ODBC

 [MariaDB Connector/ODBC](../mariadb-connector-odbc/index) supports `pam` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section since MariaDB Connector/ODBC 1.0.0, regardless of the value of the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable.

 ### Using the Plugin with MariaDB Connector/J

 [MariaDB Connector/J](../mariadb-connector-j/index) supports `pam v1` authentication since MariaDB Connector/J 1.4.0, regardless of the value of the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable.

 [MariaDB Connector/J](../mariadb-connector-j/index) supports `pam v2` authentication since MariaDB Connector/J 2.4.4, regardless of the value of the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable.

 ### Using the Plugin with MariaDB Connector/Node.js

 [MariaDB Connector/Node.js](../nodejs-connector/index) supports `pam` authentication since MariaDB Connector/Node.js 0.7.0, regardless of the value of the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable.

 ### Using the Plugin with MySqlConnector for .NET

 [MySqlConnector for ADO.NET](../mysqlconnector-for-adonet/index) supports `pam` authentication since MySqlConnector 0.20.0, but only if the [pam\_use\_cleartext\_plugin](#pam_use_cleartext_plugin) system variable is enabled on the server.

 Logging
-------

 ### PAM Module Logging

 Errors and messages from PAM modules are usually logged using the [syslog](https://linux.die.net/man/8/rsyslogd) daemon with the `authpriv` facility. To determine the specific log file where the `authpriv` facility is logged, you can check [rsyslog.conf](https://linux.die.net/man/5/rsyslog.conf).

 On RHEL, CentOS, Fedora, and other similar Linux distributions, the default location for these messages is usually `/var/log/secure`.

 On Debian, Ubuntu, and other similar Linux distributions, the default location for these messages is usually `/var/log/auth.log`.

 For example, the syslog can contain messages like the following when MariaDB's `pam` authentication plugin is configured to use the [pam\_unix](#pam_unix) PAM module, and the user enters an incorrect password:

 
```
Jan  9 05:35:41 ip-172-30-0-198 unix_chkpwd[1205]: password check failed for user (foo)
Jan  9 05:35:41 ip-172-30-0-198 mysqld: pam_unix(mariadb:auth): authentication failure; logname= uid=997 euid=997 tty= ruser= rhost=  user=foo

```

### PAM Authentication Plugin's Debug Logging

 MariaDB's `pam` authentication plugin can also log additional verbose debug logging to the [error log](../error-log/index). This is only done if the plugin is a [debug build](../compiling-mariadb-for-debugging/index) and if [pam\_debug](#pam_debug) is set.

 The output looks like this:

 
```
PAM: pam_start(mariadb, alice)
PAM: pam_authenticate(0)
PAM: conv: send(Enter PASSCODE:)
PAM: conv: recv(123456789)
PAM: pam_acct_mgmt(0)
PAM: pam_get_item(PAM_USER)
PAM: status = 0 user = ��\>

```

### Custom Logging with pam\_exec

 The [pam\_exec](https://linux.die.net/man/8/pam_exec) PAM module can be used to implement some custom logging. This can be very useful when debugging certain kinds of issues.

 For example, first, create a script that writes the log output:

 
```
tee /tmp/pam_log_script.sh <<EOF
#!/bin/bash
echo "\${PAM_SERVICE}:\${PAM_TYPE} - \${PAM_RUSER}@\${PAM_RHOST} is authenticating as \${PAM_USER}" 
EOF
chmod 0775 /tmp/pam_log_script.sh

```

And then change the [PAM service configuration](#configuring-the-pam-service) to execute the script using the [pam\_exec](https://linux.die.net/man/8/pam_exec) PAM module. For example:

 
```
auth optional pam_exec.so log=/tmp/pam_output.txt /tmp/pam_log_script.sh
auth required pam_unix.so audit
account optional pam_exec.so log=/tmp/pam_output.txt /tmp/pam_log_script.sh
account required pam_unix.so audit

```

Whenever the above PAM service is used, the output of the script will be written to `/tmp/pam_output.txt`. It may look similar to this:

 
```
*** Tue May 14 14:53:23 2019
mariadb:auth - @ is authenticating as alice
*** Tue May 14 14:53:25 2019
mariadb:account - @ is authenticating as alice
*** Tue May 14 14:53:28 2019
mariadb:auth - @ is authenticating as alice
*** Tue May 14 14:53:31 2019
mariadb:account - @ is authenticating as alice

```

User and Group Mapping
----------------------

 Even when using the `pam` authentication plugin, the authenticating PAM user account still needs to exist in MariaDB, and the account needs to have privileges in the database. Creating these MariaDB accounts and making sure the privileges are correct can be a lot of work. To decrease the amount of work involved, some users would like to be able to map a PAM user to a different MariaDB user. For example, let’s say that `alice` and `bob` are both DBAs. It would be nice if each of them could log into MariaDB with their own PAM username and password, while MariaDB sees both of them as the same `dba` user. That way, there is only one MariaDB account to keep track of. See [User and Group Mapping with PAM](../user-and-group-mapping-with-pam/index) for more information on how to do this.

 PAM Modules
-----------

 There are many PAM modules. The ones described below are the ones that have been seen most often by MariaDB.

 ### pam\_unix

 The [pam\_unix](https://linux.die.net/man/8/pam_unix) PAM module provides support for Unix password authentication. It is the default PAM module on most systems.

 For a tutorial on setting up PAM authentication and user or group mapping with Unix authentication, see [Configuring PAM Authentication and User Mapping with Unix Authentication](../configuring-pam-authentication-and-user-mapping-with-unix-authentication/index).

 ### pam\_user\_map

 The [pam\_user\_map](../user-and-group-mapping-with-pam/index) PAM module was developed by MariaDB to support user and group mapping.

 ### pam\_ldap

 The [pam\_ldap](https://linux.die.net/man/5/pam_ldap) PAM module provides support for LDAP authentication.

 For a tutorial on setting up PAM authentication and user or group mapping with LDAP authentication, see [Configuring PAM Authentication and User Mapping with LDAP Authentication](../configuring-pam-authentication-and-user-mapping-with-ldap-authentication/index).

 This can also be configured for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication.

 ### pam\_sss

 The [pam\_sss](https://linux.die.net/man/8/pam_sss) PAM module provides support for authentication with [System Security Services Daemon (SSSD)](https://en.wikipedia.org/wiki/System_Security_Services_Daemon).

 This can be configured for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication.

 ### pam\_lsass

 The `pam_lsass` PAM module provides support for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication. It is provided by [PowerBroker Identity Services – Open Edition](https://github.com/BeyondTrust/pbis-open/wiki).

 ### pam\_winbind

 The [pam\_winbind](https://www.samba.org/samba/docs/current/man-html/pam_winbind.8.html) PAM module provides support for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication. It is provided by [winbindd](https://www.samba.org/samba/docs/current/man-html/winbindd.8.html) from the [samba](https://www.samba.org/samba/docs/current/man-html/samba.7.html) suite.

 This PAM module converts all provided user names to lowercase. There is no way to disable this functionality. If you do not want to be forced to use all lowercase user names, then you may need to configure the [pam\_winbind\_workaround](#pam_winbind_workaround) system variable. See [MDEV-18686](https://jira.mariadb.org/browse/MDEV-18686) for more information.

 ### pam\_centrifydc

 The [pam\_centrifydc](https://docs.centrify.com/en/css/2018-html/index.html#page/Planning,_preparation,_and_deployment/unix_pam_services.html) PAM module provides support for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication. It integrates with the commercial [Active Directory Bridge from Centrify](https://www.centrify.com/products/infrastructure-services/authentication/active-directory-bridge/integration/).

 ### pam\_krb5

 The [pam\_krb5](https://linux.die.net/man/8/pam_krb5) PAM module provides support for [Kerberos](https://en.wikipedia.org/wiki/Kerberos_(protocol)) authentication.

 This can be configured for [Active Directory](https://en.wikipedia.org/wiki/Active_Directory) authentication.

 ### pam\_google\_authenticator

 The `pam_google_authenticator` PAM module provides two-factor identification with Google Authenticator. It is from Google's [google-authenticator-libpam](https://github.com/google/google-authenticator-libpam) open-source project. The PAM module should work with the open-source mobile apps built by Google's [google-authenticator](https://github.com/google/google-authenticator) and [google-authenticator-android](https://github.com/google/google-authenticator-android) projects as well as the the closed source Google Authenticator mobile apps that are present in each mobile app store.

 For an example of how to use this PAM module, see the blog post: [MariaDB: Improve Security with Two-Step Verification](https://mariadb.org/improve-security-with-two-step-verification/).

 ### pam\_securid

 The `pam_securid` PAM module provides support for multi-factor authentication. It is part of the commercial [RSA SecurID Suite](https://www.rsa.com/en-us/products/rsa-securid-suite).

 Note that current versions of this module are not [safe for multi-threaded environments](#multi-threaded-issues), and the vendor does not officially support the product on MariaDB. See [MDEV-10361](https://jira.mariadb.org/browse/MDEV-10361) about that. However, the module may work with [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) and above.

 ### pam\_ssh

 The [pam\_ssh](https://linux.die.net/man/8/pam_ssh) PAM module provides authentication using SSH keys.

 ### pam\_time

 The [pam\_time](https://linux.die.net/man/8/pam_time) PAM module provides time-controlled access.

 Known Issues
------------

 ### Multi-Threaded Issues

 MariaDB is a multi-threaded program, which means that different connections concurrently run in different threads. Current versions of MariaDB's `pam` authentication plugin execute PAM module code in the server address space. This means that any PAM modules used with MariaDB must be safe for multi-threaded environments. Otherwise, if multiple clients try to authenticate with the same PAM module in parallel, undefined behavior can occur. For example, the `pam_fprintd` PAM module is not safe for multi-threaded environments, and if you use it with MariaDB, you may experience server crashes.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**Starting in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), the `pam` authentication plugin isolates PAM module code from the server address space, so even PAM modules that are known to be unsafe for multi-threaded environments should not cause issues with MariaDB. See [MDEV-15473](https://jira.mariadb.org/browse/MDEV-15473) for more information.

 
### Conflicts with Password Validation

 When a [password validation plugin](../password-validation-plugins/index) is enabled, MariaDB won't allow an account to be created if the password validation plugin says that the account's password is too weak. This creates a problem for accounts that authenticate with the `pam` authentication plugin, since MariaDB has no knowledge of the user's password. When a user tries to create an account that authenticates with the `pam` authentication plugin, the password validation plugin would throw an error, even with [strict\_password\_validation=OFF](../server-system-variables/index#strict_password_validation) set.

 The workaround is to uninstall the [password validation plugin](../password-validation-plugins/index) with [UNINSTALL PLUGIN](../uninstall-plugin/index), and then create the account, and then reinstall the [password validation plugin](../password-validation/index) with [INSTALL PLUGIN](../install-plugin/index).

 For example:

 
```
INSTALL PLUGIN simple_password_check SONAME 'simple_password_check';
Query OK, 0 rows affected (0.002 sec)

SET GLOBAL strict_password_validation=OFF;
Query OK, 0 rows affected (0.000 sec)

CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
UNINSTALL PLUGIN simple_password_check;
Query OK, 0 rows affected (0.000 sec)

CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
Query OK, 0 rows affected (0.000 sec)

INSTALL PLUGIN simple_password_check SONAME 'simple_password_check';
Query OK, 0 rows affected (0.001 sec)

```


**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**Starting in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), accounts that authenticate with the `pam` authentication plugin should be exempt from password validation checks. See [MDEV-12321](https://jira.mariadb.org/browse/MDEV-12321) and [MDEV-10457](https://jira.mariadb.org/browse/MDEV-10457) for more information.

 
### SELinux

 [SELinux](../selinux/index) may cause issues when using the `pam` authentication plugin. For example, using [pam\_unix](#pam_unix) with the `pam` authentication plugin while SELinux is enabled can sometimes lead to SELinux errors involving [unix\_chkpwd](https://linux.die.net/man/8/unix_chkpwd), such as the following::

 
```
Apr 14 12:37:59 localhost setroubleshoot: Plugin Exception restorecon_source
Apr 14 12:37:59 localhost setroubleshoot: SELinux is preventing /usr/sbin/unix_chkpwd from execute access on the file . For complete SELinux messages. run sealert -l c56fe6e0-c78c-4bdb-a80f-27ef86a1ea85
Apr 14 12:37:59 localhost python: SELinux is preventing /usr/sbin/unix_chkpwd from execute access on the file .

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that unix_chkpwd should be allowed execute access on the  file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# grep unix_chkpwd /var/log/audit/audit.log | audit2allow -M mypol
# semodule -i mypol.pp

```

Sometimes issues like this can be fixed by updating the system's SELinux policies. You may be able to update the policies using [audit2allow](https://linux.die.net/man/1/audit2allow). See [SELinux: Generating SELinux Policies with audit2allow](../selinux/index#generating-selinux-policies-with-audit2allow) for more information.

 If you can't get the `pam` authentication plugin to work with SELinux at all, then it can help to disable SELinux entirely. See [SELinux: Changing SELinux's Mode](../selinux/index#changing-selinuxs-mode) for information on how to do this.

 ### Memory Overcommit

 On [MariaDB 10.4](../what-is-mariadb-104/index) and later you may run into authentication failures with the following log message in the MariaDB error log:

 
```
pam: cannot exec /usr/lib64/mysql/plugin/auth_pam_tool_dir/auth_pam_tool (errno: 12 "Cannot allocate memory") 

```

This can happen on operating system setups that are configured to prevent memory overcommit. When the MariaDB server process spawns the `auth_pam_tool` helper process there's a brief period where the new process inherits the memory of the MariaDB process before releasing that memory and executing the new command. When having a MariaDB server configured to use more than 50% of the server machnines RAM -- which is common for dedicated database servers -- this duplication would lead to an over-commit situation.

 Starting with [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10425-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), and [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), we changed to use `posix_spawn()` instead of the classic `fork();exec()` to prevent this, but systems with older glibc versions prior to 2.26 still use `fork();exec()` to implement `posix_spawn()` internally and so are still affected; this is for example still the case on RedHat Enterprise Linux 7.

 To solve this you can either:

 * change the `vm.overcommit_memory` kernel setting to allow memory overcommit
* install the older `auth_pam_v1` plugin version that does not spawn a helper process (but may run into problems with file permissions or multi threading with some PAM modules)

 See also [MDEV-26212](https://jira.mariadb.org/browse/MDEV-26212) and [MDEV-30734](https://jira.mariadb.org/browse/MDEV-30734)

 Tutorials
---------

 You may find the following PAM-related tutorials helpful:

 * [Configuring PAM Authentication and User Mapping with Unix Authentication](../configuring-pam-authentication-and-user-mapping-with-unix-authentication/index)
* [Configuring PAM Authentication and User Mapping with LDAP Authentication](../configuring-pam-authentication-and-user-mapping-with-ldap-authentication/index)

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 2.0 | Beta | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) |
| 1.0 | Stable | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.0 | Beta | [MariaDB 5.2.10](https://mariadb.com/kb/en/mariadb-5210-release-notes/) |

 
System Variables
----------------

 ### `pam_debug`

 * **Description:** Enables verbose debug logging to the [error log](../error-log/index) for all authentication handled by the plugin.
	+ This system variable is only available when the plugin is a [debug build](../compiling-mariadb-for-debugging/index).
* **Commandline:** `--pam-debug`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/)

 

---

 ### `pam_use_cleartext_plugin`

 * **Description:** Use the [mysql\_clear\_password](#mysql_clear_password) client authentication plugin instead of the [dialog](#dialog) client authentication plugin. This may be needed for compatibility reasons, but it only supports simple PAM configurations that don't require any input besides a password.
* **Commandline:** `--pam-use-cleartext-plugin`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5532-release-notes/)

 

---

 ### `pam_winbind_workaround`

 * **Description:** Configures the authentication plugin to compare the user name provided by the client with the user name returned by the PAM module in a case insensitive manner. This may be needed if you use the [pam\_winbind](#pam_winbind) PAM module, which is known to convert all user names to lowercase, and which does not allow this behavior to be disabled.
* **Commandline:** `--pam-winbind-workaround`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/)

 

---

 Options
-------

 ### `pam`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--pam=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 See Also
--------

 * [Writing a MariaDB PAM Authentication Plugin](https://mariadb.org/writing-a-mariadb-pam-authentication-plugin/)
* [MariaDB: Improve Security with Two-Step Verification](https://mariadb.org/improve-security-with-two-step-verification/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-pam/>

Mroonga System Variables
========================

     This page documents system variables related to the [Mroonga storage engine](../mroonga/index). See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `mroonga_action_on_fulltext_query_error`

 * **Description:** Action to take when encountering a Mroonga fulltext error.
	+ `ERROR`: Report an error without logging.
	+ `ERROR_AND_LOG`: Report an error with logging (the default)
	+ `IGNORE`: No logging or reporting - the error is ignored.
	+ `IGNORE_AND_LOG`: Log the error without reporting it.
* **Commandline:** `--mroonga-action-on-fulltext-query-error=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `ERROR_AND_LOG`

 

---

 #### `mroonga_boolean_mode_syntax_flags`

 * **Description:** Flags to customize syntax in BOOLEAN MODE searches. Available flags:
	+ `DEFAULT`: (=SYNTAX\_QUERY,ALLOW\_LEADING\_NOT)
	+ `ALLOW_COLUMN`: Allows `COLUMN:...` syntax in query syntax, an incompatible change to the regular BOOLEAN MODE syntax. Permits multiple indexes in one `MATCH () AGAINST ()`. Can be used in other operations besides full-text search, such as equal, and prefix search. See [Groonga query syntax](http://groonga.org/docs/reference/grn_expr/query_syntax.html) for more details.
	+ `ALLOW_LEADING_NOT` Permits using the `NOT_INCLUDED_KEYWORD` syntax in the query syntax.
	+ `ALLOW_UPDATE`: Permits updating values with the `COLUMN:=NEW_VALUE` syntax in the query syntax.
	+ `SYNTAX_QUERY`: Mroonga will use Groonga's query syntax, compatible with MariaDB's BOOLEAN MODE syntax. Unless `SYNTAX_SCRIPT` is specified, this mode is always in use.
	+ `SYNTAX_SCRIPT`: Mroonga will use Groonga's script syntax, a JavaScript-like syntax. If both `SYNTAX_QUERY` and `SYNTAX_SCRIPT` are specified, `SYNTAX_SCRIPT` will take precedence..
* **Commandline:** `--mroonga-boolean-mode-syntax-flags=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `DEFAULT`

 

---

 #### `mroonga_database_path_prefix`

 * **Description:** The database path prefix.
* **Commandline:** `--mroonga-database-path-prefix=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `mroonga_default_parser`

 * **Description:** The fulltext default parser, for example `TokenBigramSplitSymbolAlphaDigit` or `TokenBigram` (the default). See the list of options at [Mroonga Overview:Parser](../mroonga-overview/index#parser). Deprecated since Mroonga 5.04, use [mroonga\_default\_tokenizer](#mroonga_default_tokenizer) instead.
* **Commandline:** `--mroonga-default-parser=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `TokenBigram`
* **Deprecated:** [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/), Mroonga 5.0.4

 

---

 #### `mroonga_default_tokenizer`

 * **Description:** The fulltext default parser, for example `TokenBigramSplitSymbolAlphaDigit` or `TokenBigram` (the default). See the list of options at [Mroonga Overview:Parser](../mroonga-overview/index#parser).
* **Commandline:** `--mroonga-default-tokenizer=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `TokenBigram`
* **Introduced:** [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/), Mroonga 5.0.4

 

---

 #### `mroonga_default_wrapper_engine`

 * **Description:** The default engine for wrapper mode.
* **Commandline:** `--mroonga-default-wrapper-engine=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `mroonga_dry_write`

 * **Description:** If set to `on`, (`off` is default), data is not actually written to the Groonga database. Only really useful to change for benchmarking.
* **Commandline:** `--mroonga-dry-write[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `off`

 

---

 #### `mroonga_enable_operations_recording`

 * **Description:** Whether recording operations for recovery to the Groonga database is enabled (default) or not. Requires reopening the database with [FLUSH TABLES](../flush/index) after changing the variable.
* **Commandline:** `--mroonga-enable-operations-recording={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/)

 

---

 #### `mroonga_enable_optimization`

 * **Description:** If set to `on` (the default), optimization is enabled. Only really useful to change for benchmarking.
* **Commandline:** `--mroonga-enable-optimization={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `on`

 

---

 #### `mroonga_libgroonga_embedded`

 * **Description:** Whether libgroonga is embedded or not.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/)

 

---

 #### `mroonga_libgroonga_support_lz4`

 * **Description:** Whether libgroonga supports lz4 or not.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `mroonga_libgroonga_support_zlib`

 * **Description:** Whether libgroonga supports zlib or not.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `mroonga_libgroonga_support_zstd`

 * **Description:** Whether libgroonga supports Zstandard or not.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/)

 

---

 #### `mroonga_libgroonga_version`

 * **Description:** Groonga library version.
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

 #### `mroonga_lock_timeout`

 * **Description:** Lock timeout used in Groonga.
* **Commandline:** `<<code>>`--mroonga-lock-timeout=#</code>>
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `900000`
* **Range:** `-1` to `2147483647`

 

---

 #### `mroonga_log_file`

 * **Description:** Name and path of the Mroonga log file.
* **Commandline:** `--mroonga-log-file=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `groonga.log`

 

---

 #### `mroonga_log_level`

 * **Description:** Mroonga log file output level, which determines what is logged. Valid levels include:
	+ `NONE` No output.
	+ `EMERG`: Only emergency error messages, such as database corruption.
	+ `ALERT`: Alert messages, such as internal errors.
	+ `CRIT` : Critical error messages, such as deadlocks.
	+ `ERROR` : Errors, such as API errors.
	+ `WARNING`: Warnings, such as invalid arguments.
	+ `NOTICE`: Notices, such as a change in configuration or a status change.
	+ `INFO`: Information messages, such as file system operations.
	+ `DEBUG`: Debug messages, suggested for developers or testers.
	+ `DUMP`: Dump messages.
* **Commandline:** `--mroonga-log-level=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `NOTICE`

 

---

 #### `mroonga_match_escalation_threshold`

 * **Description:** The threshold to determine whether the match method is escalated. `-1` means never escalate.
* **Commandline:** `--mroonga-match-escalation-threshold=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-1` to `9223372036854775807`

 

---

 #### `mroonga_max_n_records_for_estimate`

 * **Description:** The max number of records to estimate the number of matched records
* **Commandline:** `--mroonga-max-n-records-for-estimate=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `-1` to `2147483647`

 

---

 #### `mroonga_query_log_file`

 * **Description:** Query log file for Mroonga.
* **Commandline:** `--mroonga-query-log-file=filename`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty string)
* **Introduced:** [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/)

 

---

 #### `mroonga_vector_column_delimiter`

 * **Description:** Delimiter to use when outputting a vector column. The default is a white space.
* **Commandline:** `--mroonga-vector-column-delimiter=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (white space)

 

---

 #### `mroonga_version`

 * **Description:** Mroonga version
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga-system-variables/>

password\_reuse\_check\_interval
================================

    The password\_reuse\_check\_interval system variable is available when the [password\_reuse\_check plugin](../password_reuse_check-plugin/index) is installed. It determines the retention period for the password history in days. Zero, the default, means passwords are never discarded.

 * **Commandline:** `--password_reuse_check_interval=#`
* **Scope:** Global
* **Read-only:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `36500`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/password_reuse_check_interval/>

Performance Schema System Variables
===================================

   
The following variables are used with MariaDB's [Performance Schema](../performance-schema/index). See [Performance Schema Options](../mysqld-options/index#performance-schema-options) for Performance Schema options that are not system variables. See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `performance_schema`

 * **Description:** If set to `1` (`0` is default), enables the Performance Schema
* **Commandline:** `--performance-schema=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `performance_schema_accounts_size`

 * **Description:** Maximum number of rows in the [performance\_schema.accounts](../performance-schema-accounts-table/index) table. If set to 0, the [Performance Schema](../performance-schema/index) will not store statistics in the accounts table. Use `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-accounts-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_digests_size`

 * **Description:** Maximum number of rows that can be stored in the [events\_statements\_summary\_by\_digest](../performance-schema-events_statements_summary_by_digest-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-digests-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_events_stages_history_long_size`

 * **Description:** Number of rows in the [events\_stages\_history\_long](../performance-schema-events_stages_history_long-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-stages-history-long-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_events_stages_history_size`

 * **Description:** Number of rows per thread in the [events\_stages\_history](../performance-schema-events_stages_history-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-stages-history-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1024`

 

---

 #### `performance_schema_events_statements_history_long_size`

 * **Description:** Number of rows in the [events\_statements\_history\_long](../performance-schema-events_statements_history_long-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-statements-history-long-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_events_statements_history_size`

 * **Description:** Number of rows per thread in the [events\_statements\_history](../performance-schema-events_statements_history-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-statements-history-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1024`

 

---

 #### `performance_schema_events_transactions_history_long_size`

 * **Description:** Number of rows in [events\_transactions\_history\_long](../performance-schema-events_transactions_history_long-table/index) table. Use `0` to disable, `-1` for automated sizing.
* **Commandline:** `--performance-schema-events-transactions-history-long-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_events_transactions_history_size`

 * **Description:**Number of rows per thread in [events\_transactions\_history](../performance-schema-events_transactions_history-table/index). Use 0 to disable, -1 for automated sizing.
* **Commandline:** `--performance-schema-events-transactions-history-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1024`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_events_waits_history_long_size`

 * **Description:** Number of rows contained in the [events\_waits\_history\_long](../performance-schema-events_waits_history_long-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-waits-history-long-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_events_waits_history_size`

 * **Description:** Number of rows per thread contained in the [events\_waits\_history](../performance-schema-events_waits_history-table/index) table. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-events-waits-history-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1024`

 

---

 #### `performance_schema_hosts_size`

 * **Description:** Number of rows stored in the [hosts](../performance-schema-hosts-table/index) table. If set to zero, no connection statistics are kept for the hosts table. `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-hosts-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_cond_classes`

 * **Description:** Specifies the maximum number of condition instruments.
* **Commandline:** `--performance-schema-max-cond-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `90` (>= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)), `80` (<= [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/))
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_cond_instances`

 * **Description:** Specifies the maximum number of instrumented condition objects. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-cond-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_digest_length`

 * **Description:** Maximum length considered for digest text, when stored in performance\_schema tables.
* **Commandline:** `--performance-schema-max-digest-length=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `0` to `1048576`

 

---

 #### `performance_schema_max_file_classes`

 * **Description:** Specifies the maximum number of file instruments.
* **Commandline:** `--performance-schema-max-file-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`80` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `50` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_file_handles`

 * **Description:** Specifies the maximum number of opened file objects. Should always be higher than [open\_files\_limit](../server-system-variables/index#open_files_limit).
* **Commandline:** `--performance-schema-max-file-handles=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `32768`
* **Range:** `-1` to `32768`

 

---

 #### `performance_schema_max_file_instances`

 * **Description:** Specifies the maximum number of instrumented file objects. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-file-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_index_stat`

 * **Description:** Maximum number of index statistics for instrumented tables. Use 0 to disable, -1 for automated scaling.
* **Commandline:** `--performance-schema-max-index-stat=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_memory_classes`

 * **Description:** Maximum number of memory pool instruments.
* **Commandline:** `--performance-schema-max-memory-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `320`
* **Range:** `0` to `1024`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_metadata_locks`

 * **Description:** Maximum number of [Performance Schema metadata locks](../performance-schema-metadata_locks-table/index). Use 0 to disable, -1 for automated scaling.
* **Commandline:** `--performance-schema-max-metadata-locks=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `104857600`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_mutex_classes`

 * **Description:** Specifies the maximum number of mutex instruments.
* **Commandline:** `--performance-schema-max-mutex-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `210` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `200` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_mutex_instances`

 * **Description:** Specifies the maximum number of instrumented mutex instances. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-mutex-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`-1`
* **Range:** `-1` to `104857600`

 

---

 #### `performance_schema_max_prepared_statement_instances`

 * **Description:** Maximum number of instrumented prepared statements. Use 0 to disable, -1 for automated scaling.
* **Commandline:** `--performance-schema-max-prepared-statement-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_program_instances`

 * **Description:** Maximum number of instrumented programs. Use 0 to disable, -1 for automated scaling.
* **Commandline:** `--performance-schema-max-program-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_rwlock_classes`

 * **Description:** Specifies the maximum number of rwlock instruments.
* **Commandline:** `--performance-schema-max-rwlock-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `50` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `40` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_rwlock_instances`

 * **Description:** Specifies the maximum number of instrumented rwlock objects. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-rwlock-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`-1`
* **Range:** `-1` to `104857600`

 

---

 #### `performance_schema_max_socket_classes`

 * **Description:** Specifies the maximum number of socket instruments.
* **Commandline:** `--performance-schema-max-socket-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_socket_instances`

 * **Description:** Specifies the maximum number of instrumented socket objects. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-socket-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_sql_text_length`

 * **Description:** Maximum length of displayed sql text.
* **Commandline:** `--performance-schema-max-sql-text-length=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1024`
* **Range:** `0` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_stage_classes`

 * **Description:** Specifies the maximum number of stage instruments.
* **Commandline:** `--performance-schema-max-stage-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `160` (>= [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)), `150` (<= [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/))
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_statement_classes`

 * **Description:** Specifies the maximum number of statement instruments. Automatically calculated at server build based on the number of available statements. Should be left as either autosized or disabled, as changing to any positive value has no benefit and will most likely allocate unnecessary memory. Setting to zero disables all statement instrumentation, and no memory will be allocated for this purpose.
* **Commandline:** `--performance-schema-max-statement-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** Autosized (see description)
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_statement_stack`

 * **Description:** Number of rows per thread in EVENTS\_STATEMENTS\_CURRENT.
* **Commandline:** `--performance-schema-max-statement-stack=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `1` to `256`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_table_handles`

 * **Description:** Specifies the maximum number of opened table objects. `0` for disabling, `-1` (the default) for automated sizing. See also the [Performance Schema table\_handles table](../performance-schema-table_handles-table/index).
* **Commandline:** `--performance-schema-max-table-handles=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_table_instances`

 * **Description:** Specifies the maximum number of instrumented table objects. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-table-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_max_table_lock_stat`

 * **Description:** Maximum number of lock statistics for instrumented tables. Use 0 to disable, -1 for automated scaling.
* **Commandline:** `--performance-schema-max-table-lock-stat=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `performance_schema_max_thread_classes`

 * **Description:** Specifies the maximum number of thread instruments.
* **Commandline:** `--performance-schema-max-thread-classes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `50`
* **Range:** `0` to `256`

 

---

 #### `performance_schema_max_thread_instances`

 * **Description:** Specifies how many of the running server threads (see [max\_connections](../server-system-variables/index#max_connections) and [max\_delayed\_threads](../server-system-variables/index#max_delayed_threads)) can be instrumented. Should be greater than the sum of max\_connections and max\_delayed\_threads. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-max-thread-instances=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:**`-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_session_connect_attrs_size`

 * **Description:** Per thread preallocated memory for holding connection attribute strings. Incremented if the strings are larger than the reserved space. `0` for disabling, `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-session-connect-attrs-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

 #### `performance_schema_setup_actors_size`

 * **Description:** The maximum number of rows to store in the performance schema [setup\_actors](../performance-schema-setup_actors-table/index) table. `-1` (from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) denotes automated sizing.
* **Commandline:** `--performance-schema-setup-actors-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `100` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))
* **Range:** `-1` to `1024` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `0` to `1024` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))

 

---

 #### `performance_schema_setup_objects_size`

 * **Description:** The maximum number of rows that can be stored in the performance schema [setup\_objects](../performance-schema-setup_objects-table/index) table. `-1` (from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) denotes automated sizing.
* **Commandline:** `--performance-schema-setup-objects-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `100` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))
* **Range:** `-1` to `1048576` (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)), `0` to `1048576` (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/))

 

---

 #### `performance_schema_users_size`

 * **Description:** Number of rows in the [performance\_schema.users](../performance-schema-users-table/index) table. If set to 0, the [Performance Schema](../performance-schema/index) will not store connection statistics in the users table. `-1` (the default) for automated sizing.
* **Commandline:** `--performance-schema-users-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1048576`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-system-variables/>

Performance Schema Status Variables
===================================

   
This page documents status variables related to the [Performance Schema](../performance-schema/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Performance_schema_accounts_lost`

 * **Description:** Number of times a row could not be added to the performance schema accounts table due to it being full. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_cond_classes_lost`

 * **Description:** Number of condition instruments that could not be loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_cond_instances_lost`

 * **Description:** Number of instances a condition object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_digest_lost`

 * **Description:** The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_file_classes_lost`

 * **Description:** Number of file instruments that could not be loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_file_handles_lost`

 * **Description:** Number of instances a file object could not be opened. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_file_instances_lost`

 * **Description:** Number of instances a file object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_hosts_lost`

 * **Description:** Number of times a row could not be added to the performance schema hosts table due to it being full. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_index_stat_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_locker_lost`

 * **Description:** Number of events not recorded, due to either being recursive, or having a deeper nested events stack than the implementation limit. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_memory_classes_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_metadata_lock_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_mutex_classes_lost`

 * **Description:** Number of mutual exclusion instruments that could not be loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_mutex_instances_lost`

 * **Description:** Number of instances a mutual exclusion object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_nested_statement_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_prepared_statements_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_program_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_rwlock_classes_lost`

 * **Description:** Number of read/write lock instruments that could not be loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_rwlock_instances_lost`

 * **Description:** Number of instances a read/write lock object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_session_connect_attrs_lost`

 * **Description:** Number of connections for which connection attribute truncation has occurred. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_socket_classes_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_socket_instances_lost`

 * **Description:** Number of instances a socket object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_stage_classes_lost`

 * **Description:** Number of stage event instruments that could not be loaded. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_statement_classes_lost`

 * **Description:** Number of statement instruments that could not be loaded. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_table_handles_lost`

 * **Description:** Number of instances a table object could not be opened. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_table_instances_lost`

 * **Description:** Number of instances a table object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_table_lock_stat_lost`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)

 

---

 #### `Performance_schema_thread_classes_lost`

 * **Description:** Number of thread instruments that could not be loaded.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_thread_instances_lost`

 * **Description:** Number of instances thread object could not be created. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Performance_schema_users_lost`

 * **Description:** Number of times a row could not be added to the performance schema users table due to it being full. The global value can be flushed by [FLUSH STATUS](../flush/index).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-status-variables/>

Query Response Time Plugin
==========================

    The `query_response_time` plugin creates the [QUERY\_RESPONSE\_TIME](../information-schema-query_response_time-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. The plugin also adds the [SHOW QUERY\_RESPONSE\_TIME](../show-query_response_time/index) and [FLUSH QUERY\_RESPONSE\_TIME](../flush/index) statements.

 The [slow query log](../slow-query-log/index) provides exact information about queries that take a long time to execute. However, sometimes there are a large number of queries that each take a very short amount of time to execute. This feature provides a tool for analyzing that information by counting and displaying the number of queries according to the the length of time they took to execute. 

 This feature is based on Percona's [Response Time Distribution](http://www.percona.com/doc/percona-server/5.5/diagnostics/response_time_distribution.html).

 Installing the Plugin
---------------------

 This shared library actually consists of two different plugins:

 * `QUERY_RESPONSE_TIME` - An INFORMATION\_SCHEMA plugin that exposes statistics.
* `QUERY_RESPONSE_TIME_AUDIT` - audit plugin, collects statistics.

 Both plugins need to be installed to get meaningful statistics.

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'query_response_time';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = query_response_time

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'query_response_time';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Response Time Distribution
--------------------------

 The user can define time intervals that divide the range 0 to positive infinity into smaller intervals and then collect the number of commands whose execution times fall into each of those intervals.

 Each interval is described as:

 
```
(range_base ^ n; range_base ^ (n+1)]

```

The range\_base is some positive number (see Limitations). The interval is defined as the difference between two nearby powers of the range base.

 For example, if the range base=10, we have the following intervals:

 
```
(0; 10 ^ -6], (10 ^ -6; 10 ^ -5], (10 ^ -5; 10 ^ -4], ..., 
  (10 ^ -1; 10 ^1], (10^1; 10^2]...(10^7; positive infinity]

```

or

 
```
(0; 0.000001], (0.000001; 0.000010], (0.000010; 0.000100], ..., 
  (0.100000; 1.0]; (1.0; 10.0]...(1000000; positive infinity]

```

For each interval, a count is made of the queries with execution times that fell into that interval.

 You can select the range of the intervals by changing the range base. For example, for base range=2 we have the following intervals:

 
```
(0; 2 ^ -19], (2 ^ -19; 2 ^ -18], (2 ^ -18; 2 ^ -17], ..., 
  (2 ^ -1; 2 ^1], (2 ^ 1; 2 ^ 2]...(2 ^ 25; positive infinity]

```

or

 
```
(0; 0.000001], (0.000001, 0.000003], ..., 
  (0.25; 0.5], (0.5; 2], (2; 4]...(8388608; positive infinity]

```

Small numbers look strange (i.e., don’t look like powers of 2), because we lose precision on division when the ranges are calculated at runtime. In the resulting table, you look at the high boundary of the range.

 For example, you may see:

 
```
SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;
+----------------+-------+----------------+
| TIME           | COUNT | TOTAL          |
+----------------+-------+----------------+
|       0.000001 |     0 |       0.000000 |
|       0.000010 |    17 |       0.000094 |
|       0.000100 |  4301         0.236555 |
|       0.001000 |  1499 |       0.824450 |
|       0.010000 | 14851 |      81.680502 |
|       0.100000 |  8066 |     443.635693 |
|       1.000000 |     0 |       0.000000 |
|      10.000000 |     0 |       0.000000 |
|     100.000000 |     1 |      55.937094 |
|    1000.000000 |     0 |       0.000000 |
|   10000.000000 |     0 |       0.000000 |
|  100000.000000 |     0 |       0.000000 |
| 1000000.000000 |     0 |       0.000000 |
| TOO LONG       |     0 | TOO LONG       |
+----------------+-------+----------------+

```

This means there were:

 
```
* 17 queries with 0.000001 < query execution time < = 0.000010 seconds; total execution time of the 17 queries = 0.000094 seconds

* 4301 queries with 0.000010 < query execution time < = 0.000100 seconds; total execution time of the 4301 queries = 0.236555 seconds

* 1499 queries with 0.000100 < query execution time < = 0.001000 seconds; total execution time of the 1499 queries = 0.824450 seconds

* 14851 queries with 0.001000 < query execution time < = 0.010000 seconds; total execution time of the 14851 queries = 81.680502 seconds

* 8066 queries with 0.010000 < query execution time < = 0.100000 seconds; total execution time of the 8066 queries = 443.635693 seconds

* 1 query with 10.000000 < query execution time < = 100.0000 seconds; total execution time of the 1 query = 55.937094 seconds

```

Using the Plugin
----------------

 ### Using the Information Schema Table

 You can get the distribution by querying the the [QUERY\_RESPONSE\_TIME](../information-schema-query_response_time-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. For example:

 
```
SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME;

```

You can also write more complex queries. For example:

 
```
SELECT c.count, c.time,
(SELECT SUM(a.count) FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as a 
   WHERE a.count != 0) as query_count,
(SELECT COUNT(*)     FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as b 
  WHERE b.count != 0) as not_zero_region_count,
(SELECT COUNT(*)     FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME) as region_count
FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME as c 
  WHERE c.count > 0;

```

Note: If [query\_response\_time\_stats](#query_response_time_stats) is set to `ON`, then the execution times for these two SELECT queries will also be collected.

 ### Using the SHOW Statement

 As an alternative to the [QUERY\_RESPONSE\_TIME](../information-schema-query_response_time-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database, you can also use the [SHOW QUERY\_RESPONSE\_TIME](../show-query_response_time/index) statement. For example:

 
```
SHOW QUERY_RESPONSE_TIME;

```

### Flushing Plugin Data

 Flushing the plugin data does two things:

 * Clears the collected times from the [QUERY\_RESPONSE\_TIME](../information-schema-query_response_time-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database.
* Reads the value of [query\_response\_time\_range\_base](#query_response_time_range_base) and uses it to set the range base for the table.

 Plugin data can be flushed with the [FLUSH QUERY\_RESPONSE\_TIME](../flush/index) statement. For example:

 
```
FLUSH QUERY_RESPONSE_TIME;

```

Setting the [query\_response\_time\_flush](#query_response_time_flush) system variable has the same effect. For example:

 
```
SET GLOBAL query_response_time_flush=1;

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |

 
System Variables
----------------

 ### `query_response_time_flush`

 * **Description:** Updating this variable flushes the statistics and re-reads [query\_response\_time\_range\_base](#query_response_time_range_base).
* **Commandline:** None
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 ### `query_response_time_range_base`

 * **Description:** Select base of log for `QUERY_RESPONSE_TIME` ranges. WARNING: variable change takes affect only after flush.
* **Commandline:** `--query-response-time-range-base=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `2` to `1000`

 

---

 ### `query_response_time_exec_time_debug`

 * **Description:** Pretend queries take this many microseconds. When 0 (the default) use the actual execution time.
	+ This system variable is only available when the plugin is a [debug build](../compiling-mariadb-for-debugging/index).
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `31536000`

 

---

 ### `query_response_time_stats`

 * **Description:** Enable or disable query response time statistics collecting
* **Commandline:** `query-response-time-stats[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 Options
-------

 ### `query_response_time`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--query-response-time=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 ### `query_response_time_audit`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--query-response-time-audit=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-response-time-plugin/>

MyRocks System Variables
========================

     This page documents system variables related to the [MyRocks](../myrocks/index) storage engine. See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `rocksdb_access_hint_on_compaction_start`

 * **Description:** DBOptions::access\_hint\_on\_compaction\_start for RocksDB. Specifies the file access pattern, applied to all input files, once a compaction starts.
* **Commandline:** `--rocksdb-access-hint-on-compaction-start=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `3`

 

---

 #### `rocksdb_advise_random_on_open`

 * **Description:** DBOptions::advise\_random\_on\_open for RocksDB.
* **Commandline:** `--rocksdb-advise-random-on-open={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_allow_concurrent_memtable_write`

 * **Description:** DBOptions::allow\_concurrent\_memtable\_write for RocksDB.
* **Commandline:** `--rocksdb-allow-concurrent-memtable-write={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_allow_mmap_reads`

 * **Description:** DBOptions::allow\_mmap\_reads for RocksDB
* **Commandline:** `--rocksdb-allow-mmap-reads={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_allow_mmap_writes`

 * **Description:** DBOptions::allow\_mmap\_writes for RocksDB
* **Commandline:** `--rocksdb-allow-mmap-writes={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_allow_to_start_after_corruption`

 * **Description:** Allow server still to start successfully even if RocksDB corruption is detected.
* **Commandline:** `--rocksdb-allow-to-start-after-corruption={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/)

 

---

 #### `rocksdb_background_sync`

 * **Description:** Turns on background syncs for RocksDB
* **Commandline:** `--rocksdb-background-sync={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_base_background_compactions`

 * **Description:** DBOptions::base\_background\_compactions for RocksDB
* **Commandline:** `--rocksdb-base-background-compactions=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `-1` to `64`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_blind_delete_primary_key`

 * **Description:** Deleting rows by primary key lookup, without reading rows (Blind Deletes). Blind delete is disabled if the table has secondary key.
* **Commandline:** `--rocksdb-blind-delete-primary-key={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_block_cache_size`

 * **Description:** Block\_cache size for RocksDB (block size 1024)
* **Commandline:** `--rocksdb-block-cache-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `536870912`
* **Range:** `1024` to `9223372036854775807`

 To see the statistics of block cache usage, check `SHOW ENGINE ROCKSDB STATUS` output (search for lines starting with `rocksdb.block.cache`).

 One can check the size of data of the block cache in `DB_BLOCK_CACHE_USAGE` column of the `INFORMATION_SCHEMA.ROCKSDB_DBSTATS` table.

 

---

 #### `rocksdb_block_restart_interval`

 * **Description:** BlockBasedTableOptions::block\_restart\_interval for RocksDB
* **Commandline:** `--rocksdb-block-restart-interval=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `16`
* **Range:** `1` to `2147483647`

 

---

 #### `rocksdb_block_size`

 * **Description:** BlockBasedTableOptions::block\_size for RocksDB
* **Commandline:** `--rocksdb-block-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `4096`
* **Range:** `1` to `18446744073709551615`

 

---

 #### `rocksdb_block_size_deviation`

 * **Description:** BlockBasedTableOptions::block\_size\_deviation for RocksDB
* **Commandline:** `--rocksdb-block-size-deviation=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `2147483647`

 

---

 #### `rocksdb_bulk_load`

 * **Description:** Use bulk-load mode for inserts. This disables unique\_checks and enables rocksdb\_commit\_in\_the\_middle.
* **Commandline:** `--rocksdb-bulk-load={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_bulk_load_allow_sk`

 * **Description:** Allow bulk loading of sk keys during bulk-load. Can be changed only when bulk load is disabled.
* **Commandline:** `--rocksdb-bulk-load_allow_sk={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_bulk_load_allow_unsorted`

 * **Description:** Allow unsorted input during bulk-load. Can be changed only when bulk load is disabled.
* **Commandline:** `--rocksdb-bulk-load_allow_unsorted={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_bulk_load_size`

 * **Description:** Maximum number of records in a batch for bulk-load mode.
* **Commandline:** `--rocksdb-bulk-load-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `1` to `1073741824`

 

---

 #### `rocksdb_bytes_per_sync`

 * **Description:** DBOptions::bytes\_per\_sync for RocksDB.
* **Commandline:** `--rocksdb-bytes-per-sync=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_cache_dump`

 * **Description:** Include RocksDB block cache content in core dump.
* **Commandline:** `--rocksdb-cache-dump={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_cache_high_pri_pool_ratio`

 * **Description:** Specify the size of block cache high-pri pool.
* **Commandline:** `--rocksdb-cache-high-pri-pool-ratio=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `double`
* **Default Value:** `0.000000`
* **Range:** `0` to `1`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_cache_index_and_filter_blocks`

 * **Description:** BlockBasedTableOptions::cache\_index\_and\_filter\_blocks for RocksDB.
* **Commandline:** `--rocksdb-cache-index-and-filter-blocks={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_cache_index_and_filter_with_high_priority`

 * **Description:** cache\_index\_and\_filter\_blocks\_with\_high\_priority for RocksDB.
* **Commandline:** `--rocksdb-cache-index-and-filter-with-high-priority={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_checksums_pct`

 * **Description:** Percentage of rows to be checksummed.
* **Commandline:** `--rocksdb-checksums-pct=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `100`
* **Range:** `0` to `100`

 

---

 #### `rocksdb_collect_sst_properties`

 * **Description:** Enables collecting SST file properties on each flush.
* **Commandline:** `--rocksdb-collect-sst-properties={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_commit_in_the_middle`

 * **Description:** Commit rows implicitly every rocksdb\_bulk\_load\_size, on bulk load/insert, update and delete.
* **Commandline:** `--rocksdb-commit-in-the-middle={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_commit_time_batch_for_recovery`

 * **Description:** TransactionOptions::commit\_time\_batch\_for\_recovery for RocksDB.
* **Commandline:** `--rocksdb-commit-time-batch-for-recovery={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_compact_cf`

 * **Description:** Compact column family.
* **Commandline:** `--rocksdb-compact-cf=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_compaction_readahead_size`

 * **Description:** DBOptions::compaction\_readahead\_size for RocksDB.
* **Commandline:** `--rocksdb-compaction-readahead-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_compaction_sequential_deletes`

 * **Description:** RocksDB will trigger compaction for the file if it has more than this number sequential deletes per window.
* **Commandline:** `--rocksdb-compaction-sequential-deletes=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2000000`

 

---

 #### `rocksdb_compaction_sequential_deletes_count_sd`

 * **Description:** Counting SingleDelete as rocksdb\_compaction\_sequential\_deletes.
* **Commandline:** `--rocksdb-compaction-sequential-deletes-count-sd={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_compaction_sequential_deletes_file_size`

 * **Description:** Minimum file size required for compaction\_sequential\_deletes.
* **Commandline:** `--rocksdb-compaction-sequential-deletes-file-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-1` to `9223372036854775807`

 

---

 #### `rocksdb_compaction_sequential_deletes_window`

 * **Description:** Size of the window for counting rocksdb\_compaction\_sequential\_deletes.
* **Commandline:** `--rocksdb-compaction-sequential-deletes-window=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2000000`

 

---

 #### `rocksdb_concurrent_prepare`

 * **Description:** DBOptions::concurrent\_prepare for RocksDB.
* **Commandline:** `--rocksdb-coconcurrent-prepare={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `1`
* **Removed:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/)

 

---

 #### `rocksdb_create_checkpoint`

 * **Description:** Checkpoint directory.
* **Commandline:** `--rocksdb-create-checkpoint=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_create_if_missing`

 * **Description:** DBOptions::create\_if\_missing for RocksDB.
* **Commandline:** `--rocksdb-create-if-missing={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_create_missing_column_families`

 * **Description:** DBOptions::create\_missing\_column\_families for RocksDB.
* **Commandline:** `--rocksdb-create-missing-column-families={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_datadir`

 * **Description:** RocksDB data directory.
* **Commandline:** `--rocksdb-datadir[=value]`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `./#rocksdb`

 

---

 #### `rocksdb_db_write_buffer_size`

 * **Description:** DBOptions::db\_write\_buffer\_size for RocksDB.
* **Commandline:** `--rocksdb-db-write-buffer-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_deadlock_detect`

 * **Description:** Enables deadlock detection.
* **Commandline:** `--rocksdb-deadlock-detect={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_deadlock_detect_depth`

 * **Description:** Number of transactions deadlock detection will traverse through before assuming deadlock.
* **Commandline:** `--rocksdb-deadlock-detect-depth=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `50`
* **Range:** `2` to `18446744073709551615`

 

---

 #### `rocksdb_debug_manual_compaction_delay`

 * **Description:** For debugging purposes only. Sleeping specified seconds for simulating long running compactions.
* **Commandline:** `--rocksdb-debug_manual_compaction_delay=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_debug_optimizer_no_zero_cardinality`

 * **Description:** If cardinality is zero, override it with some value.
* **Commandline:** `--rocksdb-debug-optimizer-no-zero-cardinality={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_debug_ttl_ignore_pk`

 * **Description:** For debugging purposes only. If true, compaction filtering will not occur on PK TTL data. This variable is a no-op in non-debug builds.
* **Commandline:** `--rocksdb-debug-ttl-ignore-pk={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_debug_ttl_read_filter_ts`

 * **Description:** For debugging purposes only. Overrides the TTL read filtering time to time + debug\_ttl\_read\_filter\_ts. A value of 0 denotes that the variable is not set. This variable is a no-op in non-debug builds.
* **Commandline:** `--rocksdb-debug-ttl-read-filter-ts=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-3600` to `3600`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_debug_ttl_rec_ts`

 * **Description:** For debugging purposes only. Overrides the TTL of records to now() + debug\_ttl\_rec\_ts. The value can be +/- to simulate a record inserted in the past vs a record inserted in the 'future'. A value of 0 denotes that the variable is not set. This variable is a no-op in non-debug builds.
* **Commandline:** `--rocksdb-debug-ttl-read-filter-ts=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-3600` to `3600`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_debug_ttl_snapshot_ts`

 * **Description:** For debugging purposes only. Sets the snapshot during compaction to now() + debug\_set\_ttl\_snapshot\_ts. The value can be positive or negative to simulate a snapshot in the past vs a snapshot created in the 'future'. A value of 0 denotes that the variable is not set. This variable is a no-op in non-debug builds.
* **Commandline:** `--rocksdb-debug-ttl-snapshot-ts=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `-3600` to `3600`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_default_cf_options`

 * **Description:** Default cf options for RocksDB.
* **Commandline:** `--rocksdb-default-cf-options=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_delayed_write_rate`

 * **Description:** DBOptions::delayed\_write\_rate.
* **Commandline:** `--rocksdb-delayed-write-rate=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0` (Previously `16777216`)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_delete_cf`

 * **Description:** Delete column family.
* **Commandline:** `--rocksdb-delete-cf=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty string)
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_delete_obsolete_files_period_micros`

 * **Description:** DBOptions::delete\_obsolete\_files\_period\_micros for RocksDB.
* **Commandline:** `--rocksdb-delete-obsolete-files-period-micros=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `21600000000`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_enable_2pc`

 * **Description:** Enable two phase commit for MyRocks. When set, MyRocks will keep its data consistent with the [binary log](../binary-log/index) (in other words, the server will be a crash-safe master). The consistency is achieved by doing two-phase XA commit with the binary log.
* **Commandline:** `--rocksdb-enable-2pc={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_enable_bulk_load_api`

 * **Description:** Enables using SstFileWriter for bulk loading.
* **Commandline:** `--rocksdb-enable-bulk-load-api={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_enable_insert_with_update_caching`

 * **Description:** Whether to enable optimization where we cache the read from a failed insertion attempt in [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index).
* **Commandline:** `--rocksdb-enable-insert-with-update-caching={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_enable_thread_tracking`

 * **Description:** DBOptions::enable\_thread\_tracking for RocksDB.
* **Commandline:** `--rocksdb-enable-thread-tracking={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_enable_ttl`

 * **Description:** Enable expired TTL records to be dropped during compaction.
* **Commandline:** `--rocksdb-enable-ttl={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_enable_ttl_read_filtering`

 * **Description:** For tables with TTL, expired records are skipped/filtered out during processing and in query results. Disabling this will allow these records to be seen, but as a result rows may disappear in the middle of transactions as they are dropped during compaction. Use with caution.
* **Commandline:** `--rocksdb-enable-ttl-read-filtering={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_enable_write_thread_adaptive_yield`

 * **Description:** DBOptions::enable\_write\_thread\_adaptive\_yield for RocksDB.
* **Commandline:** `--rocksdb-enable-write-thread-adaptive-yield={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_error_if_exists`

 * **Description:** DBOptions::error\_if\_exists for RocksDBB.
* **Commandline:** `--rocksdb-error-if-exists={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_error_on_suboptimal_collation`

 * **Description:** Raise an error instead of warning if a sub-optimal collation is used.
* **Commandline:** `--rocksdb-error-on-suboptimal-collation={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_flush_log_at_trx_commit`

 * **Description:** Sync on transaction commit. Similar to [innodb\_flush\_log\_at\_trx\_commit](../innodb-system-variables/index#innodb_flush_log_at_trx_commit). One can check the flushing by examining the [rocksdb\_wal\_synced](../myrocks-status-variables/index#rocksdb_wal_synced) and [rocksdb\_wal\_bytes](../myrocks-status-variables/index#rocksdb_wal_bytes) status variables.
	+ **1**: Always sync on commit (the default).
	+ **0**: Never sync.
	+ **2**: Sync based on a timer controlled via rocksdb-background-sync.
* **Commandline:** `--rocksdb-flush-log-at-trx-commit=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `2`

 

---

 #### `rocksdb_flush_memtable_on_analyze`

 * **Description:** Forces memtable flush on ANALZYE table to get accurate cardinality.
* **Commandline:** `--rocksdb-flush-memtable-on-analyze={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Removed:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/)

 

---

 #### `rocksdb_force_compute_memtable_stats`

 * **Description:** Force to always compute memtable stats.
* **Commandline:** `--rocksdb-force-compute-memtable-stats={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_force_compute_memtable_stats_cachetime`

 * **Description:** Time in usecs to cache memtable estimates.
* **Commandline:** `--rocksdb-force-compute-memtable-stats-cachetime=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `60000000`
* **Range:** `0` to `2147483647`

 

---

 #### `rocksdb_force_flush_memtable_and_lzero_now`

 * **Description:** Acts similar to force\_flush\_memtable\_now, but also compacts all L0 files.
* **Commandline:** `--rocksdb-force-flush-memtable-and-lzero-now={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_force_flush_memtable_now`

 * **Description:** Forces memstore flush which may block all write requests so be careful.
* **Commandline:** `--rocksdb-force-flush-memtable-now={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_force_index_records_in_range`

 * **Description:** Used to override the result of records\_in\_range() when [FORCE INDEX](../force-index/index) is used.
* **Commandline:** `--rocksdb-force-index-records-in-range=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2147483647`

 

---

 #### `rocksdb_git_hash`

 * **Description:** Git revision of the RocksDB library used by MyRocks.
* **Commandline:** `--rocksdb-git-hash=value=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** As per git revision.

 

---

 #### `rocksdb_hash_index_allow_collision`

 * **Description:** BlockBasedTableOptions::hash\_index\_allow\_collision for RocksDB.
* **Commandline:** `--rocksdb-hash-index-allow-collision={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_ignore_unknown_options`

 * **Description:** Enable ignoring unknown options passed to RocksDB.
* **Commandline:** `--rocksdb-ignore-unknown-options={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/)

 

---

 #### `rocksdb_index_type`

 * **Description:** BlockBasedTableOptions::index\_type for RocksDB.
* **Commandline:** `--rocksdb-index-type=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enum`
* **Default Value:** `kBinarySearch`
* **Valid Values:** `kBinarySearch`, `kHashSearch`

 

---

 #### `rocksdb_info_log_level`

 * **Description:** Filter level for info logs to be written mysqld error log. Valid values include 'debug\_level', 'info\_level', 'warn\_level', 'error\_level' and 'fatal\_level'.
* **Commandline:** `--rocksdb-info-log-level=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `enum`
* **Default Value:** `error_level`
* **Valid Values:** `error_level`, `debug_level`, `info_level`, `warn_level`, `fatal_level`

 

---

 #### `rocksdb_io_write_timeout`

 * **Description:** Timeout for experimental I/O watchdog.
* **Commandline:** `--rocksdb-io-write-timeout=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Valid Values:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_is_fd_close_on_exec`

 * **Description:** DBOptions::is\_fd\_close\_on\_exec for RocksDB.
* **Commandline:** `--rocksdb-is-fd-close-on-exec={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_keep_log_file_num`

 * **Description:** DBOptions::keep\_log\_file\_num for RocksDB.
* **Commandline:** `--rocksdb-keep-log-file-num=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_large_prefix`

 * **Description:** Support large index prefix length of 3072 bytes. If off, the maximum index prefix length is 767.
* **Commandline:** `--rocksdb-large_prefix={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_lock_scanned_rows`

 * **Description:** Take and hold locks on rows that are scanned but not updated.
* **Commandline:** `--rocksdb-lock-scanned-rows={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_lock_wait_timeout`

 * **Description:** Number of seconds to wait for lock.
* **Commandline:** `--rocksdb-lock-wait-timeout=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `1073741824`

 

---

 #### `rocksdb_log_dir`

 * **Description:** DBOptions::log\_dir for RocksDB. Where the log files are stored. An empty value implies `rocksdb_datadir` is used as the directory.
* **Commandline:** `--rocksdb-log-dir=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)
* **Introduced:** [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/)

 

---

 #### `rocksdb_log_file_time_to_roll`

 * **Description:** DBOptions::log\_file\_time\_to\_roll for RocksDB.
* **Commandline:** `--rocksdb-log-file-time-to_roll=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_manifest_preallocation_size`

 * **Description:** DBOptions::manifest\_preallocation\_size for RocksDB.
* **Commandline:** `--rocksdb-manifest-preallocation-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `4194304`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_manual_compaction_threads`

 * **Description:** How many rocksdb threads to run for manual compactions.
* **Commandline:** `--rocksdb-manual-compation-threads=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `128`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_manual_wal_flush`

 * **Description:** DBOptions::manual\_wal\_flush for RocksDB.
* **Commandline:** `--rocksdb-manual-wal-flush={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_master_skip_tx_api`

 * **Description:** Skipping holding any lock on row access. Not effective on slave.
* **Commandline:** `--rocksdb-master-skip-tx-api={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_max_background_compactions`

 * **Description:** DBOptions::max\_background\_compactions for RocksDB.
* **Commandline:** `--rocksdb-max-background-compactions=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `64`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_max_background_flushes`

 * **Description:** DBOptions::max\_background\_flushes for RocksDB.
* **Commandline:** `--rocksdb-max-background-flushes=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `64`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_max_background_jobs`

 * **Description:** DBOptions::max\_background\_jobs for RocksDB.
* **Commandline:** `--rocksdb-max-background-jobs=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `2`
* **Range:** `-1` to `64`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_max_latest_deadlocks`

 * **Description:** Maximum number of recent deadlocks to store.
* **Commandline:** `--rocksdb-max-latest-deadlocks=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `5`
* **Range:** `0` to `4294967295`

 

---

 #### `rocksdb_max_log_file_size`

 * **Description:** DBOptions::max\_log\_file\_size for RocksDB.
* **Commandline:** `--rocksdb-max-log-file-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_max_manifest_file_size`

 * **Description:** DBOptions::max\_manifest\_file\_size for RocksDB.
* **Commandline:** `--rocksdb-manifest-log-file-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1073741824`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_max_manual_compactions`

 * **Description:** Maximum number of pending + ongoing number of manual compactions..
* **Commandline:** `--rocksdb-manual_compactions=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_max_open_files`

 * **Description:** DBOptions::max\_open\_files for RocksDB.
* **Commandline:** `--rocksdb-max-open-files=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `-2`
* **Range:** `-2` to `2147483647`

 

---

 #### `rocksdb_max_row_locks`

 * **Description:** Maximum number of locks a transaction can have.
* **Commandline:** `--rocksdb-max-row-locks=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1048576`
* **Range:**
	+ `1` to `1073741824` (>= [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/))
	+ `1` to `1048576` (<= [MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/))

 

---

 #### `rocksdb_max_subcompactions`

 * **Description:** DBOptions::max\_subcompactions for RocksDB.
* **Commandline:** `--rocksdb-max-subcompactions=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `1` to `64`

 

---

 #### `rocksdb_max_total_wal_size`

 * **Description:** DBOptions::max\_total\_wal\_size for RocksDB. The maximum size limit for write-ahead-log files. Once this limit is reached, RocksDB forces the flushing of memtables.
* **Commandline:** `--rocksdb-max-total-wal-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_merge_buf_size`

 * **Description:** Size to allocate for merge sort buffers written out to disk during inplace index creation.
* **Commandline:** `--rocksdb-merge-buf-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `67108864`
* **Range:** `100` to `18446744073709551615`

 

---

 #### `rocksdb_merge_combine_read_size`

 * **Description:** Size that we have to work with during combine (reading from disk) phase of external sort during fast index creation.
* **Commandline:** `--rocksdb-merge-combine-read-size=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1073741824`
* **Range:** `100` to `18446744073709551615`

 

---

 #### `rocksdb_merge_tmp_file_removal_delay_ms`

 * **Description:** Fast index creation creates a large tmp file on disk during index creation. Removing this large file all at once when index creation is complete can cause trim stalls on Flash. This variable specifies a duration to sleep (in milliseconds) between calling chsize() to truncate the file in chunks. The chunk size is the same as merge\_buf\_size.
* **Commandline:** `--rocksdb-merge-tmp-file-removal-delay-ms=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_new_table_reader_for_compaction_inputs`

 * **Description:** DBOptions::new\_table\_reader\_for\_compaction\_inputs for RocksDB.
* **Commandline:** `--rocksdb-new-table-reader-for-compaction-inputs={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_no_block_cache`

 * **Description:** BlockBasedTableOptions::no\_block\_cache for RocksDB.
* **Commandline:** `--rocksdb-no-block-cache={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_override_cf_options`

 * **Description:** Option overrides per cf for RocksDB. Note that the `rocksdb-override-cf-options` syntax is quite strict, and any typos will result in a parse error, and the MyRocks plugin will not be loaded. Depending on your configuration, the server may still start. If it does start, you can use this command to check if the plugin is loaded: `select * from information_schema.plugins where plugin_name='ROCKSDB'` (note that you need the "ROCKSDB" plugin. Other auxiliary plugins like "ROCKSDB\_TRX" might still get loaded). Another way is to detect the error is check the error log.
* **Commandline:** `--rocksdb-override-cf-options=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_paranoid_checks`

 * **Description:** DBOptions::paranoid\_checks for RocksDB.
* **Commandline:** `--rocksdb-paranoid-checks={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_pause_background_work`

 * **Description:** Disable all rocksdb background operations.
* **Commandline:** `--rocksdb-pause-background-work={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_perf_context_level`

 * **Description:** Perf Context Level for rocksdb internal timer stat collection.
* **Commandline:** `--rocksdb-perf-context-level=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `5`

 

---

 #### `rocksdb_persistent_cache_path`

 * **Description:** Path for BlockBasedTableOptions::persistent\_cache for RocksDB.
* **Commandline:** `--rocksdb-persistent-cache-path=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_persistent_cache_size_mb`

 * **Description:** Size of cache in MB for BlockBasedTableOptions::persistent\_cache for RocksDB.
* **Commandline:** `--rocksdb-persistent-cache-size-mb=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_pin_l0_filter_and_index_blocks_in_cache`

 * **Description:** pin\_l0\_filter\_and\_index\_blocks\_in\_cache for RocksDB.
* **Commandline:** `--rocksdb-pin-l0-filter-and-index-blocks-in-cache={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_print_snapshot_conflict_queries`

 * **Description:** Logging queries that got snapshot conflict errors into \*.err log.
* **Commandline:** `--rocksdb-print-snapshot-conflict-queries={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_rate_limiter_bytes_per_sec`

 * **Description:** DBOptions::rate\_limiter bytes\_per\_sec for RocksDB.
* **Commandline:** `--rocksdb-rate-limiter-bytes-per-sec=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_read_free_rpl_tables`

 * **Description:** List of tables that will use read-free replication on the slave (i.e. not lookup a row during replication).
* **Commandline:** `--rocksdb-read-free-rpl-tables=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)
* **Removed:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_records_in_range`

 * **Description:** Used to override the result of records\_in\_range(). Set to a positive number to override.
* **Commandline:** `--rocksdb-records-in-range=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2147483647`

 

---

 #### `rocksdb_remove_mariabackup_checkpoint`

 * **Description:** Remove [mariabackup](../mariabackup/index) checkpoint.
* **Commandline:** `--rocksdb-remove-mariabackup-checkpoint={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/), [MariaDB 10.2.16](https://mariadb.com/kb/en/mariadb-10216-release-notes/)

 

---

 #### `rocksdb_reset_stats`

 * **Description:** Reset the RocksDB internal statistics without restarting the DB.
* **Commandline:** `--rocksdb-reset-stats={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_rollback_on_timeout`

 * **Description:** Whether to roll back the complete transaction or a single statement on lock wait timeout (a single statement by default).
* **Commandline:** `--rocksdb-rollback-on-timeout={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_seconds_between_stat_computes`

 * **Description:** Sets a number of seconds to wait between optimizer stats recomputation. Only changed indexes will be refreshed.
* **Commandline:** `--rocksdb-seconds-between-stat-computes=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `3600`
* **Range:** `0` to `4294967295`

 

---

 #### `rocksdb_signal_drop_index_thread`

 * **Description:** Wake up drop index thread.
* **Commandline:** `--rocksdb-signal-drop-index-thread={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_sim_cache_size`

 * **Description:** Simulated cache size for RocksDB.
* **Commandline:** `--rocksdb-sim-cache-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_skip_bloom_filter_on_read`

 * **Description:** Skip using bloom filter for reads.
* **Commandline:** `--rocksdb-skip-bloom-filter-on_read={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_skip_fill_cache`

 * **Description:** Skip filling block cache on read requests.
* **Commandline:** `--rocksdb-skip-fill-cache={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_skip_unique_check_tables`

 * **Description:** Skip unique constraint checking for the specified tables.
* **Commandline:** `--rocksdb-skip-unique-check-tables=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `.*`

 

---

 #### `rocksdb_sst_mgr_rate_bytes_per_sec`

 * **Description:** DBOptions::sst\_file\_manager rate\_bytes\_per\_sec for RocksDB
* **Commandline:** `--rocksdb-sst-mgr-rate-bytes-per-sec=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_stats_dump_period_sec`

 * **Description:** DBOptions::stats\_dump\_period\_sec for RocksDB.
* **Commandline:** `--rocksdb-stats-dump-period-sec=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `600`
* **Range:** `0` to `2147483647`

 

---

 #### `rocksdb_stats_level`

 * **Description:** Statistics Level for RocksDB. Default is 0 (kExceptHistogramOrTimers).
* **Commandline:** `--rocksdb-stats-level=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/)

 

---

 #### `rocksdb_stats_recalc_rate`

 * **Description:** The number of indexes per second to recalculate statistics for. 0 to disable background recalculation.
* **Commandline:** `--rocksdb-stats-recalc_rate=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4294967295`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

 #### `rocksdb_store_row_debug_checksums`

 * **Description:** Include checksums when writing index/table records.
* **Commandline:** `--rocksdb-store-row-debug-checksums={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_strict_collation_check`

 * **Description:** Enforce case sensitive collation for MyRocks indexes.
* **Commandline:** `--rocksdb-strict-collation-check={0|1}`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_strict_collation_exceptions`

 * **Description:** List of tables (using regex) that are excluded from the case sensitive collation enforcement.
* **Commandline:** `--rocksdb-strict-collation-exceptions=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_supported_compression_types`

 * **Description:** Compression algorithms supported by RocksDB. Note that RocksDB does not make use of [MariaDB 10.7](../what-is-mariadb-107/index) [compression-plugins](../compression-plugins/index).
* **Commandline:** `--rocksdb-supported-compression-types=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `Snappy,Zlib,ZSTDNotFinal`

 

---

 #### `rocksdb_table_cache_numshardbits`

 * **Description:** DBOptions::table\_cache\_numshardbits for RocksDB.
* **Commandline:** `--rocksdb-table-cache-numshardbits=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `6`
* **Range:** `0` to `19`

 

---

 #### `rocksdb_table_stats_sampling_pct`

 * **Description:** Percentage of entries to sample when collecting statistics about table properties. Specify either 0 to sample everything or percentage [1..100]. By default 10% of entries are sampled.
* **Commandline:** `--rocksdb-table-stats-sampling-pct=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `0` to `100`

 

---

 #### `rocksdb_tmpdir`

 * **Description:** Directory for temporary files during DDL operations.
* **Commandline:** `--rocksdb-tmpdir[=value]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_trace_sst_api`

 * **Description:** Generate trace output in the log for each call to the SstFileWriter.
* **Commandline:** `--rocksdb-trace-sst-api={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_two_write_queues`

 * **Description:** DBOptions::two\_write\_queues for RocksDB.
* **Commandline:** `--rocksdb-two-write-queues={0|1}`
* **Scope:** Global,
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/)

 

---

 #### `rocksdb_unsafe_for_binlog`

 * **Description:** Allowing statement based binary logging which may break consistency.
* **Commandline:** `--rocksdb-unsafe-for-binlog={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_update_cf_options`

 * **Description:** Option updates per column family for RocksDB.
* **Commandline:** `--rocksdb-update-cf-options=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `varchar`
* **Default Value:** (Empty)
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_use_adaptive_mutex`

 * **Description:** DBOptions::use\_adaptive\_mutex for RocksDB.
* **Commandline:** `--rocksdb-use-adaptive-mutex={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_use_clock_cache`

 * **Description:** Use ClockCache instead of default LRUCache for RocksDB.
* **Commandline:** `--rocksdb-use-clock-cache={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_use_direct_io_for_flush_and_compaction`

 * **Description:** DBOptions::use\_direct\_io\_for\_flush\_and\_compaction for RocksDB.
* **Commandline:** `--rocksdb-use-direct-io-for-flush-and-compaction={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_use_direct_reads`

 * **Description:** DBOptions::use\_direct\_reads for RocksDB.
* **Commandline:** `--rocksdb-use-direct-reads={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_use_direct_writes`

 * **Description:** DBOptions::use\_direct\_writes for RocksDB.
* **Commandline:** `--rocksdb-use-direct-reads={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `rocksdb_use_fsync`

 * **Description:** DBOptions::use\_fsync for RocksDB.
* **Commandline:** `--rocksdb-use-fsync={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_validate_tables`

 * **Description:** Verify all .frm files match all RocksDB tables (0 means no verification, 1 means verify and fail on error, and 2 means verify but continue.
* **Commandline:** `--rocksdb-validate-tables=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `2`

 

---

 #### `rocksdb_verify_row_debug_checksums`

 * **Description:** Verify checksums when reading index/table records.
* **Commandline:** `--rocksdb-verify-row-debug-checksums={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_wal_bytes_per_sync`

 * **Description:** DBOptions::wal\_bytes\_per\_sync for RocksDB.
* **Commandline:** `--rocksdb-wal-bytes-per-sync=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_wal_dir`

 * **Description:** DBOptions::wal\_dir for RocksDB. Directory where the write-ahead-log files are stored.
* **Commandline:** `--rocksdb-wal-dir=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** (Empty)

 

---

 #### `rocksdb_wal_recovery_mode`

 * **Description:** DBOptions::wal\_recovery\_mode for RocksDB. Default is kAbsoluteConsistency. Records that are not yet committed are stored in the Write-Ahead-Log (WAL). If the server is not cleanly shut down, the recovery mode will determine the WAL recovery behavior.
	+ **1**: kAbsoluteConsistency. Will not start if any corrupted entries (including incomplete writes) are detected (the default).
	+ **0**: kTolerateCorruptedTailRecords. Ignores any errors found at the end of the WAL
	+ **2**: kPointInTimeRecovery. Replay of the WAL is halted after finding an error. The system will be recovered to the latest consistent point-in-time. Data from a replica can used to replay past the point-in-time.
	+ **3**: kSkipAnyCorruptedRecords. A risky option where any corrupted entries are skipped while subsequent healthy WAL entries are applied.
* **Commandline:** `--rocksdb-wal-recovery-mode=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `3`

 

---

 #### `rocksdb_wal_size_limit_mb`

 * **Description:** DBOptions::WAL\_size\_limit\_MB for RocksDB. Write-ahead-log files are moved to an archive directory once their memtables are flushed. This variable specifies the largest size, in MB, that the archive can be.
* **Commandline:** `--rocksdb-wal-size-limit-mb=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_wal_ttl_seconds`

 * **Description:** DBOptions::WAL\_ttl\_seconds for RocksDB. Oldest time, in seconds, that a write-ahead-log file should exist.
* **Commandline:** `--rocksdb-wal-ttl-seconds=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `9223372036854775807`

 

---

 #### `rocksdb_whole_key_filtering`

 * **Description:** BlockBasedTableOptions::whole\_key\_filtering for RocksDB. If set (the default), the bloomfilter to use the whole key (rather than only the prefix) for filtering is enabled. Lookups should use the whole key for matching to make best use of this setting.
* **Commandline:** `--rocksdb-whole-key-filtering={0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `rocksdb_write_batch_max_bytes`

 * **Description:** Maximum size of write batch in bytes. 0 means no limit.
* **Commandline:** `--rocksdb-write-batch-max-bytes=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `rocksdb_write_disable_wal`

 * **Description:** WriteOptions::disableWAL for RocksDB.
* **Commandline:** `--rocksdb-write-disable-wal={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_write_ignore_missing_column_families`

 * **Description:** WriteOptions::ignore\_missing\_column\_families for RocksDB.
* **Commandline:** `--rocksdb-write-ignore-missing-column-families={0|1}`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `rocksdb_write_policy`

 * **Description:** DBOptions::write\_policy for RocksDB.
* **Commandline:** `--rocksdb-write-policy=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enum`
* **Default Value:** `write_committed`
* **Valid Values:** `write_committed`, `write_prepared`, `write_unprepared`
* **Introduced:** [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-system-variables/>

MyRocks Status Variables
========================

    This page documents status variables related to the [MyRocks](../myrocks/index) storage engine. See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Rocksdb_block_cache_add`

 * **Description:** Number of blocks added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_add_failures`

 * **Description:** Number of failures when adding blocks to Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_bytes_read`

 * **Description:** Bytes read from Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_bytes_write`

 * **Description:** Bytes written to Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_data_add`

 * **Description:** Number of data blocks added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_data_bytes_insert`

 * **Description:** Bytes added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_data_hit`

 * **Description:** Number of hits when accessing the data block from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_data_miss`

 * **Description:** Number of misses when accessing the data block from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_filter_add`

 * **Description:** Number of bloom filter blocks added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_filter_bytes_evict`

 * **Description:** Bytes of bloom filter blocks evicted from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_filter_bytes_insert`

 * **Description:** Bytes of bloom filter blocks added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_filter_hit`

 * **Description:** Number of hits when accessing the filter block from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_filter_miss`

 * **Description:** Number of misses when accessing the filter block from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_hit`

 * **Description:** Total number of hits for the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_index_add`

 * **Description:** Number of index blocks added to Block Cache index.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_index_bytes_evict`

 * **Description:** Bytes of index blocks evicted from the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_index_bytes_insert`

 * **Description:** Bytes of index blocks added to the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_block_cache_index_hit`

 * **Description:** Number of hits for the Block Cache index.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_index_miss`

 * **Description:** Number of misses for the Block Cache index.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cache_miss`

 * **Description:** Total number of misses for the Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cachecompressed_hit`

 * **Description:** Number of hits for the compressed Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_block_cachecompressed_miss`

 * **Description:** Number of misses for the compressed Block Cache.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_bloom_filter_full_positive`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/)

 

---

 #### `Rocksdb_bloom_filter_full_true_positive`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/)

 

---

 #### `Rocksdb_bloom_filter_prefix_checked`

 * **Description:** Number of times the Bloom Filter checked before creating an iterator on a file.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_bloom_filter_prefix_useful`

 * **Description:** Number of times the Bloom Filter check used to avoid creating an iterator on a file.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_bloom_filter_useful`

 * **Description:** Number of times the Bloom Filter used instead of reading form file.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_bytes_read`

 * **Description:** Total number of uncompressed bytes read from memtables, cache or table files.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_bytes_written`

 * **Description:** Total number of uncompressed bytes written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_compact_read_bytes`

 * **Description:** Number of bytes read during compaction.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_compact_write_bytes`

 * **Description:** Number of bytes written during compaction.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_compaction_key_drop_new`

 * **Description:** Number of keys dropped during compaction due their being overwritten by new values.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_compaction_key_drop_obsolete`

 * **Description:** Number of keys dropped during compaction due to their being obsolete.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_compaction_key_drop_user`

 * **Description:** Number of keys dropped during compaction due to user compaction.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_covered_secondary_key_lookups`

 * **Description:** Incremented when avoiding reading a record via a keyread. This indicates lookups that were performed via a secondary index containing a field that is only a prefix of the [VARCHAR](../varchar/index) column, and that could return all requested fields directly from the secondary index.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_flush_write_bytes`

 * **Description:** Number of bytes written during flush.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_get_hit_l0`

 * **Description:** Number of times reads got data from the L0 compaction layer.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_get_hit_l1`

 * **Description:** Number of times reads got data from the L1 compaction layer.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_get_hit_l2_and_up`

 * **Description:** Number of times reads got data from the L2 and up compaction layer.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_getupdatessince_calls`

 * **Description:** Number of calls to the `GetUpdatesSince` function. You may find this useful when monitoring refreshes of the transaction log.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_iter_bytes_read`

 * **Description:** Total uncompressed bytes read from an iterator, including the size of both key and value.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_l0_num_files_stall_micros`

 * **Description:** Shows how long in microseconds throttled due to too mnay files in L0.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `Rocksdb_l0_slowdown_micros`

 * **Description:** Total time spent waiting in microseconds while performing L0-L1 compactions.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `Rocksdb_manual_compactions_processed`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/)

 

---

 #### `Rocksdb_manual_compactions_running`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/)

 

---

 #### `Rocksdb_memtable_compaction_micros`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Removed:** [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)

 

---

 #### `Rocksdb_memtable_hit`

 * **Description:** Number of memtable hits.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_memtable_miss`

 * **Description:** Number of memtable misses.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_memtable_total`

 * **Description:** Memory used, in bytes, of all memtables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_memtable_unflushed`

 * **Description:** Memory used, in bytes, of all unflushed memtables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_no_file_closes`

 * **Description:** Number of times files were closed.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_no_file_errors`

 * **Description:** Number of errors encountered while trying to read data from an SST file.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_no_file_opens`

 * **Description:** Number of times files were opened.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_num_iterators`

 * **Description:** Number of iterators currently open.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_block_not_compressed`

 * **Description:** Number of uncompressed blocks.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_db_next`

 * **Description:** Number of `next` calls.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_db_next_found`

 * **Description:** Number of `next` calls that returned data.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_db_prev`

 * **Description:** Number of `prev` calls.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_db_prev_found`

 * **Description:** Number of `prev` calls that returned data.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_db_seek`

 * **Description:** Number of `seek` calls.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_db_seek_found`

 * **Description:** Number of `seek` calls that returned data.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_number_deletes_filtered`

 * **Description:** Number of deleted records were not written to storage due to a nonexistent key.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_keys_read`

 * **Description:** Number of keys have been read.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_keys_updated`

 * **Description:** Number of keys have been updated.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_keys_written`

 * **Description:** Number of keys have been written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_merge_failures`

 * **Description:** Number of failures encountered while performing merge operator actions.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_multiget_bytes_read`

 * **Description:** Number of bytes read during RocksDB `MultiGet()` calls.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_multiget_get`

 * **Description:** Number of RocksDB `MultiGet()` requests made.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_multiget_keys_read`

 * **Description:** Number of keys read through RocksDB `MultiGet()` calls.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_reseeks_iteration`

 * **Description:** Number of reseeks that have occurred inside an iteration that skipped over a large number of keys with the same user key.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_sst_entry_delete`

 * **Description:** Number of delete markers written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_sst_entry_merge`

 * **Description:** Number of merge keys written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_sst_entry_other`

 * **Description:** Number of keys written that are not delete, merge or put keys.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_sst_entry_put`

 * **Description:** Number of put keys written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_sst_entry_singledelete`

 * **Description:** Number of single-delete keys written.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_superversion_acquires`

 * **Description:** Number of times the superversion structure acquired. This is useful when tracking files for the database.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_superversion_cleanups`

 * **Description:** Number of times the superversion structure performed cleanups.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_number_superversion_releases`

 * **Description:** Number of times the superversion structure released.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_queries_point`

 * **Description:** Number of single-row queries.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_queries_range`

 * **Description:** Number of multi-row queries.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_row_lock_deadlocks`

 * **Description:** Number of deadlocks.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_row_lock_wait_timeouts`

 * **Description:** Number of row lock wait timeouts.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_rows_deleted`

 * **Description:** Number of rows deleted.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_rows_deleted_blind`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_rows_expired`

 * **Description:** Number of expired rows.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_rows_filtered`

 * **Description:** Number of TTL filtered rows.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)

 

---

 #### `Rocksdb_rows_inserted`

 * **Description:** Number of rows inserted.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_rows_read`

 * **Description:** Number of rows read.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_rows_updated`

 * **Description:** Number of rows updated.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_snapshot_conflict_errors`

 * **Description:** Number of snapshot conflict errors that have occurred during transactions that forced a rollback.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_l0_file_count_limit_slowdowns`

 * **Description:** Write slowdowns due to L0 being near to full.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_l0_file_count_limit_stops`

 * **Description:** Write stops due to L0 being to full.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_locked_l0_file_count_limit_slowdowns`

 * **Description:** Write slowdowns due to L0 being near to full and L0 compaction in progress.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_locked_l0_file_count_limit_stops`

 * **Description:** Write stops due to L0 being full and L0 compaction in progress.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_memtable_limit_slowdowns`

 * **Description:** Write slowdowns due to approaching maximum permitted number of memtables.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/), [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Rocksdb_stall_memtable_limit_stops`

 * **Description:** \* **Description:** Write stops due to reaching maximum permitted number of memtables.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/), [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Rocksdb_stall_micros`

 * **Description:** Time in microseconds that the writer had to wait for the compaction or flush to complete.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_pending_compaction_limit_slowdowns`

 * **Description:** Write slowdowns due to nearing the limit for the maximum number of pending compaction bytes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_pending_compaction_limit_stops`

 * **Description:** Write stops due to reaching the limit for the maximum number of pending compaction bytes.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_total_slowdowns`

 * **Description:** Total number of write slowdowns.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_stall_total_stops`

 * **Description:** Total number of write stops.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_system_rows_deleted`

 * **Description:** Number of rows deleted from system tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_system_rows_inserted`

 * **Description:** Number of rows inserted into system tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_system_rows_read`

 * **Description:** Number of rows read from system tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_system_rows_updated`

 * **Description:** Number of rows updated for system tables.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_wal_bytes`

 * **Description:** Number of bytes written to WAL.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_wal_group_syncs`

 * **Description:** Number of group commit WAL file syncs have occurred. This is provided by MyRocks and is not a view of a RocksDB counter. Increased in `rocksdb_flush_wal()` when doing the `rdb->FlushWAL()` call.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_wal_synced`

 * **Description:** Number of syncs made on RocksDB WAL file.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_write_other`

 * **Description:** Number of writes processed by a thread other than the requesting thread.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_write_self`

 * **Description:** Number of writes processed by requesting thread.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_write_timedout`

 * **Description:** Number of writes that timed out.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Rocksdb_write_wal`

 * **Description:** Number of write calls that requested WAL.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-status-variables/>

Sphinx Status Variables
=======================

    This page documents status variables related to the [Sphinx storage engine](../sphinx-storage-engine/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Sphinx_error`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sphinx_time`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sphinx_total`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sphinx_total_found`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sphinx_word_count`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Sphinx_words`

 * **Description:** See [SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status).
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sphinx-status-variables/>

Semisynchronous Replication Plugin Status Variables
===================================================

    This page documents status variables related to the [Semisynchronous Replication Plugin](../semisynchronous-replication/index) (which has been merged into the main server from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Rpl_semi_sync_master_clients`

 * **Description:** Number of semisynchronous slaves.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_net_avg_wait_time`

 * **Description:** Average time the master waited for a slave to reply, in microseconds.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_net_wait_time`

 * **Description:** Total time the master waited for slave replies, in microseconds.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_net_waits`

 * **Description:** Total number of times the master waited for slave replies.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_no_times`

 * **Description:** Number of times the master turned off semisynchronous replication. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_no_tx`

 * **Description:** Number of commits that have not been successfully acknowledged by a slave. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_status`

 * **Description:** Whether or not semisynchronous replication is currently operating on the master. The value will be `ON` if both the plugin has been enabled and a commit acknowledgment has occurred. It will be `OFF` if either the plugin has not been enabled, or the master is replicating asynchronously due to a commit acknowledgment timeout.
* **Data Type:** `boolean`

 

---

 #### `Rpl_semi_sync_master_timefunc_failures`

 * **Description:** Number of times the master failed when calling a time function, such as gettimeofday(). The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_tx_avg_wait_time`

 * **Description:** Average time the master waited for each transaction, in microseconds.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_tx_wait_time`

 * **Description:** Total time the master waited for transactions, in microseconds.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_tx_waits`

 * **Description:** Total number of times the master waited for transactions.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_wait_pos_backtraverse`

 * **Description:** Total number of times the master waited for an event that had binary coordinates lower than previous events waited for. Occurs if the order in which transactions start waiting for a reply is different from the order in which their binary log events were written. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_wait_sessions`

 * **Description:** Number of sessions that are currently waiting for slave replies.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_master_yes_tx`

 * **Description:** Number of commits that have been successfully acknowledged by a slave. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Data Type:** `numeric`

 

---

 #### `Rpl_semi_sync_slave_status`

 * **Description:** Whether or not semisynchronous replication is currently operating on the slave. `ON` if both the plugin has been enabled and the slave I/O thread is running.
* **Data Type:** `boolean`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/semisynchronous-replication-plugin-status-variables/>

S3 Storage Engine System Variables
==================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

   This page documents system variables related to the [S3 storage engine](../s3-storage-engine/index).

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting system variables.

 Also see the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index)

 Variables
---------

 #### `s3_access_key`

 * **Description:** The AWS access key to access your data. See [mysqld startup options for S3](../using-the-s3-storage-engine/index#mysqld-startup-options-for-s3).
* **Commandline:** `--s3-access-key=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** (Empty)
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_block_size`

 * **Description:** The default block size for a table, if not specified in [CREATE TABLE](../create-table/index). Set to 4M as default. See [mysqld startup options for S3](../using-the-s3-storage-engine/index#mysqld-startup-options-for-s3).
* **Commandline:** `--s3-block-size=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `4194304`
* **Range:** `4194304` to `16777216`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_bucket`

 * **Description:** The AWS bucket where your data should be stored. All MariaDB table data is stored in this bucket. See [mysqld startup options for S3](../using-the-s3-storage-engine/index#mysqld-startup-options-for-s3).
* **Commandline:** `--s3-bucket=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** `MariaDB`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_debug`

 * **Description:** Generates a trace file from libmarias3 on stderr (mysqld.err) for debugging the S3 protocol.
* **Commandline:** `--s3-debug{=0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Boolean
* **Valid Values:** 0 or 1
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_host_name`

 * **Description:** Hostname for the S3 service. "s3.amazonaws.com", Amazon S3 service, by default
* **Commandline:** `--s3-host-name=val`
* **Scope:** Globa;
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** `s3.amazonaws.com`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_pagecache_age_threshold`

 * **Description:** 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.
* **Commandline:** `--s3-pagecache-age-threshold=val`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `300`
* **Range:** `100` to `18446744073709551615`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_pagecache_buffer_size`

 * **Description:** The size of the buffer used for index blocks for S3 tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford. Size can be adjusted in blocks of `8192`.
* **Commandline:** `--s3-pagecache-buffer-size=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Numeric
* **Default Value:** `134217728` (128M)
* **Range:** `33554432` to `18446744073709551615`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_pagecache_division_limit`

 * **Description:** The minimum percentage of warm blocks in key cache.
* **Commandline:** `--s3-pagecache-division-limit=val`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Numeric
* **Default Value:** `100`
* **Range:** `1` to `100`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_pagecache_file_hash_size`

 * **Description:** Number of hash buckets for open files. Default 512. If you have a lot of S3 files open you should increase this for faster flush of changes. A good value is probably 1/10 of number of possible open S3 files.
* **Commandline:** `--s3-pagecache-file-hash-size=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Numeric
* **Default Value:** `512`
* **Range:** `32` to `16384`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_port`

 * **Description:** The TCP port number on the S3 host to connect to. A values of 0 means determine automatically.
* **Commandline:** `--s3-port=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Numeric
* **Default Value:** `0`
* **Range:** `0` to `65535`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/)

 

---

 #### `s3_protocol_version`

 * **Description:** Protocol used to communication with S3. One of "Auto", "Amazon" or "Original" where "Auto" is the default. If you get errors like "8 Access Denied" when you are connecting to another service provider, then try to change this option. The reason for this variable is that Amazon has changed some parts of the S3 protocol since they originally introduced it but other service providers are still using the original protocol.
* **Commandline:** `--s3-protocol-version=val`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** Enum
* **Valid Values:** `Auto`, `Amazon` or `Original`
* **Default Value:** `Auto`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_region`

 * **Description:** The AWS region where your data should be stored. See [mysqld startup options for S3](../using-the-s3-storage-engine/index#mysqld-startup-options-for-s3).
* **Commandline:** `--s3-region=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** (Empty)
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_replicate_alter_as_create_select`

 * **Description:** When converting S3 table to local table, log all rows in binary log. This allows the slave to replicate `CREATE TABLE .. SELECT FROM s3_table` even it the slave doesn't have access to the original `s3_table`.
* **Commandline:** `--s3-replicate-alter-as-create-select{=0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Boolean
* **Default Value:** `1`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_secret_key`

 * **Description:** The AWS secret key to access your data. See [mysqld startup options for S3](../using-the-s3-storage-engine/index#mysqld-startup-options-for-s3).
* **Commandline:** `--s3-secret-key=val`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** String
* **Default Value:** (Empty)
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_slave_ignore_updates`

 * **Description:** Should be set if master and slave share the same S3 instance. This tells the slave that it can ignore any updates to the S3 tables as they are already applied on the master.
* **Commandline:** `--s3-slave-ignore-updates{=0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Boolean
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `s3_use_http`

 * **Description:** If enabled, HTTP will be used instead of HTTPS.
* **Commandline:** `--s3-use-http{=0|1}`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** Boolean
* **Default Value:** `0`
* **Introduced:** [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/)

 

---

 See Also
--------

 [Using the S3 Storage Engine](../using-the-s3-storage-engine/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/s3-storage-engine-system-variables/>

Simple Password Check Plugin
============================

    `simple_password_check` is a [password validation](../password-validation-plugin-api/index) plugin. It can check whether a password contains at least a certain number of characters of a specific type. When first installed, a password is required to be at least eight characters, and requires at least one digit, one uppercase character, one lowercase character, and one character that is neither a digit nor a letter.

 Note that passwords can be directly set as a hash, bypassing the password validation, if the [strict\_password\_validation](../server-system-variables/index#strict_password_validation) variable is `OFF` (it is `ON` by default).

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'simple_password_check';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = simple_password_check

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'simple_password_check';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 When creating a new password, if the criteria are not met, the following error is returned:

 
```
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('abc');
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

```

Known Issues
------------

 ### Issues with PAM Authentication Plugin

 Prior to [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), all [password validation plugins](../password-validation-plugins/index) are incompatible with the `[pam](../pam-authentication-plugin/index)` authentication plugin. See [Authentication Plugin - PAM: Conflicts with Password Validation](../authentication-plugin-pam/index#conflicts-with-password-validation) for more information.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Beta | [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |

 
System Variables
----------------

 #### `simple_password_check_digits`

 * **Description:** A password must contain at least this many digits.
* **Commandline:** `--simple-password-check-digits=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1000`

 

---

 #### `simple_password_check_letters_same_case`

 * **Description:** A password must contain at least this many upper-case and this many lower-case letters.
* **Commandline:** `--simple-password-check-letters-same-case=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1000`

 

---

 #### `simple_password_check_minimal_length`

 * **Description:** A password must contain at least this many characters.
* **Commandline:** `--simple-password-check-minimal-length=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `8`
* **Range:** `0` to `1000`

 

---

 #### `simple_password_check_other_characters`

 * **Description:** A password must contain at least this many characters that are neither digits nor letters.
* **Commandline:** `--simple-password-check-other-characters=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1000`

 

---

 Options
-------

 #### `simple_password_check`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--simple-password-check=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 See Also
--------

 * [Password Validation](../password-validation/index)
* [cracklib\_password\_check plugin](../cracklib_password_check/index) - use the Cracklib password-strength checking library

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/simple_password_check/>

System-Versioned Tables
=======================

     MariaDB supports temporal data tables in the form of system-versioning tables (allowing you to query and operate on historic data, discussed below), [application-time periods](../application-time-periods/index) (allow you to query and operate on a temporal range of data), and [bitemporal tables](../bitemporal-tables/index) (which combine both system-versioning and [application-time periods](../application-time-periods/index)).

 System-Versioned Tables
-----------------------

 System-versioned tables store the history of all changes, not only data which is currently valid. This allows data analysis for any point in time, auditing of changes and comparison of data from different points in time. Typical uses cases are:

 * Forensic analysis & legal requirements to store data for N years.
* Data analytics (retrospective, trends etc.), e.g. to get your staff information as of one year ago.
* Point-in-time recovery - recover a table state as of particular point in time.

 System-versioned tables were first introduced in the SQL:2011 standard. 

 ### Creating a System-Versioned Table

   
 The [CREATE TABLE](../create-table/index) syntax has been extended to permit creating a system-versioned table. To be system-versioned, according to SQL:2011, a table must have two generated columns, a period, and a special table option clause:   
  


 
```
CREATE TABLE t(
   x INT,
   start_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
   end_timestamp TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
   PERIOD FOR SYSTEM_TIME(start_timestamp, end_timestamp)
) WITH SYSTEM VERSIONING;

```

In MariaDB one can also use a simplified syntax:

 
```
CREATE TABLE t (
   x INT
) WITH SYSTEM VERSIONING;

```

In the latter case no extra columns will be created and they won't clutter the output of, say, `SELECT * FROM t`. The versioning information will still be stored, and it can be accessed via the pseudo-columns `ROW_START` and `ROW_END`:

 
```
SELECT x, ROW_START, ROW_END FROM t;

```

### Adding or Removing System Versioning To/From a Table

 An existing table can be [altered](../alter-table/index) to enable system versioning for it.

 
```
CREATE TABLE t(
  x INT
);

```


```
ALTER TABLE t ADD SYSTEM VERSIONING;

```


```
SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING

```

Similarly, system versioning can be removed from a table:

 
```
ALTER TABLE t DROP SYSTEM VERSIONING;

```


```
SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `x` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

One can also add system versioning with all columns created explicitly:

 
```
ALTER TABLE t ADD COLUMN ts TIMESTAMP(6) GENERATED ALWAYS AS ROW START,
              ADD COLUMN te TIMESTAMP(6) GENERATED ALWAYS AS ROW END,
              ADD PERIOD FOR SYSTEM_TIME(ts, te),
              ADD SYSTEM VERSIONING;

```


```
SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `x` int(11) DEFAULT NULL,
  `ts` timestamp(6) GENERATED ALWAYS AS ROW START,
  `te` timestamp(6) GENERATED ALWAYS AS ROW END,
  PERIOD FOR SYSTEM_TIME (`ts`, `te`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING

```

### Inserting Data

 When data is inserted into a system-versioned table, it is given a *row\_start* value of the current timestamp, and a *row\_end* value of [FROM\_UNIXTIME](../from_unixtime/index)(2147483647.999999). The current timestamp can be adjusted by setting the [timestamp system variable](../server-system-variables/index#timestamp), for example:

 
```
SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2022-10-24 23:09:38 |
+---------------------+
 
INSERT INTO t VALUES(1);
 
SET @@timestamp = UNIX_TIMESTAMP('2033-10-24');

INSERT INTO t VALUES(2);
 
SET @@timestamp = default;

INSERT INTO t VALUES(3);
 
SELECT a,row_start,row_end FROM t;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:09:38.951347 | 2038-01-19 05:14:07.999999 |
|    2 | 2033-10-24 00:00:00.000000 | 2038-01-19 05:14:07.999999 |
|    3 | 2022-10-24 23:09:38.961857 | 2038-01-19 05:14:07.999999 |
+------+----------------------------+----------------------------+

```

### Querying Historical Data

 #### `SELECT`

 To query the historical data one uses the clause `FOR SYSTEM_TIME` directly after the table name (before the table alias, if any). SQL:2011 provides three syntactic extensions:

 * `AS OF` is used to see the table as it was at a specific point in time in the past:

 
```
SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

```

* `BETWEEN start AND end` will show all rows that were visible at any point between two specified points in time. It works inclusively, a row visible exactly at *start* or exactly at *end* will be shown too.

 
```
SELECT * FROM t FOR SYSTEM_TIME BETWEEN (NOW() - INTERVAL 1 YEAR) AND NOW();

```

* `FROM start TO end` will also show all rows that were visible at any point between two specified points in time, including *start*, but **excluding** *end*.

 
```
SELECT * FROM t FOR SYSTEM_TIME FROM '2016-01-01 00:00:00' TO '2017-01-01 00:00:00';

```

Additionally MariaDB implements a non-standard extension:

 * `ALL` will show all rows, historical and current.

 
```
SELECT * FROM t FOR SYSTEM_TIME ALL;

```

If the `FOR SYSTEM_TIME` clause is not used, the table will show the *current* data. This is usually the same as if one had specified `FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP`, unless one has adjusted the *row\_start* value (until [MariaDB 10.11](../what-is-mariadb-1011/index), only possible by setting the [secure\_timestamp](../server-system-variables/index#secure_timestamp) variable). For example:

 
```
CREATE OR REPLACE TABLE t (a int) WITH SYSTEM VERSIONING;

SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2022-10-24 23:43:37 |
+---------------------+

INSERT INTO t VALUES (1);

SET @@timestamp = UNIX_TIMESTAMP('2033-03-03');

INSERT INTO t VALUES (2);

DELETE FROM t;

SET @@timestamp = default;


SELECT a, row_start, row_end FROM t FOR SYSTEM_TIME ALL;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |
|    2 | 2033-03-03 00:00:00.000000 | 2033-03-03 00:00:00.000000 |
+------+----------------------------+----------------------------+
2 rows in set (0.000 sec)


SELECT a, row_start, row_end FROM t FOR SYSTEM_TIME AS OF CURRENT_TIMESTAMP;
+------+----------------------------+----------------------------+
| a    | row_start                  | row_end                    |
+------+----------------------------+----------------------------+
|    1 | 2022-10-24 23:43:37.192725 | 2033-03-03 00:00:00.000000 |
+------+----------------------------+----------------------------+
1 row in set (0.000 sec)


SELECT a, row_start, row_end FROM t;
Empty set (0.001 sec)

```

#### Views and Subqueries

 When a system-versioned tables is used in a view or in a subquery in the from clause, `FOR SYSTEM_TIME` can be used directly in the view or subquery body, or (non-standard) applied to the whole view when it's being used in a `SELECT`:

 
```
CREATE VIEW v1 AS SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

```

Or

 
```
CREATE VIEW v1 AS SELECT * FROM t;
SELECT * FROM v1 FOR SYSTEM_TIME AS OF TIMESTAMP'2016-10-09 08:07:06';

```

#### Use in Replication and Binary Logs

 Tables that use system-versioning implicitly add the `row_end` column to the Primary Key. While this is generally not an issue for most use cases, it can lead to problems when re-applying write statements from the binary log or in replication environments, where a primary retries an SQL statement on the replica. 

 Specifically, these writes include a value on the `row_end` column containing the timestamp from when the write was initially made. The re-occurrence of the Primary Key with the old system-versioning columns raises an error due to the duplication. 

 To mitigate this with MariaDB Replication, set the [secure\_timestamp](../server-system-variables/index#secure_timestamp) system variable to `YES` on the replica. When set, the replica uses its own system clock when applying to the row log, meaning that the primary can retry as many times as needed without causing a conflict. The retries generate new historical rows with new values for the `row_start` and `row_end` columns.

 ### Transaction-Precise History in InnoDB

 A point in time when a row was inserted or deleted does not necessarily mean that a change became visible at the same moment. With transactional tables, a row might have been inserted in a long transaction, and became visible hours after it was inserted.

 For some applications — for example, when doing data analytics on one-year-old data — this distinction does not matter much. For others — forensic analysis — it might be crucial.

 MariaDB supports transaction-precise history (only for the [InnoDB storage engine](../innodb/index)) that allows seeing the data exactly as it would've been seen by a new connection doing a `SELECT` at the specified point in time — rows inserted *before* that point, but committed *after* will not be shown.

 To use transaction-precise history, InnoDB needs to remember not timestamps, but transaction identifier per row. This is done by creating generated columns as `BIGINT UNSIGNED`, not `TIMESTAMP(6)`:

 
```
CREATE TABLE t(
   x INT,
   start_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW START,
   end_trxid BIGINT UNSIGNED GENERATED ALWAYS AS ROW END,
   PERIOD FOR SYSTEM_TIME(start_trxid, end_trxid)
) WITH SYSTEM VERSIONING;

```

These columns must be specified explicitly, but they can be made [INVISIBLE](../invisible-columns/index) to avoid cluttering `SELECT *` output.

 When one uses transaction-precise history, one can optionally use transaction identifiers in the `FOR SYSTEM_TIME` clause:

 
```
SELECT * FROM t FOR SYSTEM_TIME AS OF TRANSACTION 12345;

```

This will show the data, exactly as it was seen by the transaction with the identifier 12345.

 ### Storing the History Separately

 When the history is stored together with the current data, it increases the size of the table, so current data queries — table scans and index searches — will take more time, because they will need to skip over historical data. If most queries on that table use only current data, it might make sense to store the history separately, to reduce the overhead from versioning.

 This is done by partitioning the table by `SYSTEM_TIME`. Because of the [partition pruning](../partition-pruning-and-selection/index) optimization, all current data queries will only access one partition, the one that stores current data.

 This example shows how to create such a partitioned table:

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME (
    PARTITION p_hist HISTORY,
    PARTITION p_cur CURRENT
  );

```

In this example all history will be stored in the partition `p_hist` while all current data will be in the partition `p_cur`. The table must have exactly one current partition and at least one historical partition.

 Partitioning by `SYSTEM_TIME` also supports automatic partition rotation. One can rotate historical partitions by time or by size. This example shows how to rotate partitions by size:

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME LIMIT 100000 (
    PARTITION p0 HISTORY,
    PARTITION p1 HISTORY,
    PARTITION pcur CURRENT
  );

```

MariaDB will start writing history rows into partition `p0`, and when it reaches a size of 100000 rows, MariaDB will switch to partition `p1`. There are only two historical partitions, so when `p1` overflows, MariaDB will issue a warning, but will continue writing into it.

 Similarly, one can rotate partitions by time:

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 WEEK (
    PARTITION p0 HISTORY,
    PARTITION p1 HISTORY,
    PARTITION p2 HISTORY,
    PARTITION pcur CURRENT
  );

```

This means that the history for the first week after the table was created will be stored in `p0`. The history for the second week — in `p1`, and all later history will go into `p2`. One can see the exact rotation time for each partition in the [INFORMATION\_SCHEMA.PARTITIONS](../information-schema-partitions-table/index) table.

 It is possible to combine partitioning by `SYSTEM_TIME` and subpartitions:

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME
    SUBPARTITION BY KEY (x)
    SUBPARTITIONS 4 (
    PARTITION ph HISTORY,
    PARTITION pc CURRENT
  );

```

#### Default Partitions

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**Since partitioning by current and historical data is such a typical usecase, from [MariaDB 10.5](../what-is-mariadb-105/index), it is possible to use a simplified statement to do so. For example, instead of

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
  PARTITION BY SYSTEM_TIME (
    PARTITION p0 HISTORY,  
    PARTITION pn CURRENT 
);

```

you can use

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
  PARTITION BY SYSTEM_TIME;

```

You can also specify the number of partitions, which is useful if you want to rotate history by time, for example:

 
```
CREATE TABLE t (x INT) WITH SYSTEM VERSIONING 
  PARTITION BY SYSTEM_TIME 
    INTERVAL 1 MONTH 
    PARTITIONS 12;

```

Specifying the number of partitions without specifying a rotation condition will result in a warning:

 
```
CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME PARTITIONS 12;
Query OK, 0 rows affected, 1 warning (0.518 sec)

Warning (Code 4115): Maybe missing parameters: no rotation condition for multiple HISTORY partitions.

```

while specifying only 1 partition will result in an error:

 
```
CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME PARTITIONS 1;
ERROR 4128 (HY000): Wrong partitions for `t`: must have at least one HISTORY and exactly one last CURRENT

```


#### Automatically Creating Partitions

 
**MariaDB starting with [10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/)**From [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/), the `AUTO` keyword can be used to automatically create history partitions.

 For example

 
```
CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
    PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
   PARTITION BY SYSTEM_TIME INTERVAL 1 MONTH
   STARTS '2021-01-01 00:00:00' AUTO PARTITIONS 12;

CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME LIMIT 1000 AUTO;

```

Or with explicit partitions:

 
```
CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO
  (PARTITION p0 HISTORY, PARTITION pn CURRENT);

```

To disable or enable auto-creation one can use ALTER TABLE by adding or removing AUTO from the partitioning specification:

 
```
CREATE TABLE t1 (x int) WITH SYSTEM VERSIONING
  PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

# Disables auto-creation:
ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR;

# Enables auto-creation:
ALTER TABLE t1 PARTITION BY SYSTEM_TIME INTERVAL 1 HOUR AUTO;

```

If the rest of the partitioning specification is identical to CREATE TABLE, no repartitioning will be done (for details see [MDEV-27328](https://jira.mariadb.org/browse/MDEV-27328)).

 
### Removing Old History

 Because it stores all the history, a system-versioned table might grow very large over time. There are many options to trim down the space and remove the old history.

 One can completely drop the versioning from the table and add it back again, this will delete all the history:

 
```
ALTER TABLE t DROP SYSTEM VERSIONING;
ALTER TABLE t ADD SYSTEM VERSIONING;

```

It might be a rather time-consuming operation, though, as the table will need to be rebuilt, possibly twice (depending on the storage engine).

 Another option would be to use partitioning and drop some of historical partitions:

 
```
ALTER TABLE t DROP PARTITION p0;

```

Note, that one cannot drop a current partition or the only historical partition.

 And the third option; one can use a variant of the [DELETE](../delete/index) statement to prune the history:

 
```
DELETE HISTORY FROM t;

```

or only old history up to a specific point in time:

 
```
DELETE HISTORY FROM t BEFORE SYSTEM_TIME '2016-10-09 08:07:06';

```

or to a specific transaction (with `BEFORE SYSTEM_TIME TRANSACTION xxx`).

 To protect the integrity of the history, this statement requires a special [DELETE HISTORY](../grant/index#table-privileges) privilege.

 Currently, using the DELETE HISTORY statement with a BEFORE SYSTEM\_TIME greater than the ROW\_END of the active records (as a [TIMESTAMP](../timestamp/index), this has a maximum value of '2038-01-19 03:14:07' [UTC](../coordinated-universal-time/index)) will result in the historical records being dropped, and the active records being deleted and moved to history. See [MDEV-25468](https://jira.mariadb.org/browse/MDEV-25468).

 Prior to [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), the [TRUNCATE TABLE](../truncate-table/index) statement drops all historical records from a system-versioned-table.

 From [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), historic data is protected from TRUNCATE statements, as per the SQL standard, and an Error 4137 is instead raised:

 
```
TRUNCATE t;
ERROR 4137 (HY000): System-versioned tables do not support TRUNCATE TABLE

```

### Excluding Columns From Versioning

 Another MariaDB extension allows to version only a subset of columns in a table. This is useful, for example, if you have a table with user information that should be versioned, but one column is, let's say, a login counter that is incremented often and is not interesting to version. Such a column can be excluded from versioning by declaring it `WITHOUT VERSIONING`

 
```
CREATE TABLE t (
   x INT,
   y INT WITHOUT SYSTEM VERSIONING
) WITH SYSTEM VERSIONING;

```

A column can also be declared `WITH VERSIONING`, that will automatically make the table versioned. The statement below is equivalent to the one above:

 
```
CREATE TABLE t (
   x INT WITH SYSTEM VERSIONING,
   y INT
);

```


Changes in other sections: [https://mariadb.com/kb/en/create-table/](../create-table/index) [https://mariadb.com/kb/en/alter-table/](../alter-table/index) [https://mariadb.com/kb/en/join-syntax/](../join-syntax/index) [https://mariadb.com/kb/en/partitioning-types-overview/](../partitioning-types-overview/index) [https://mariadb.com/kb/en/date-and-time-units/](../date-and-time-units/index) [https://mariadb.com/kb/en/delete/](../delete/index) [https://mariadb.com/kb/en/grant/](../grant/index)

 they all reference back to this page

 Also, TODO:

 * limitations (size, speed, adding history to unique not nullable columns)

 
System Variables
----------------

 There are a number of system variables related to system-versioned tables:

 #### system\_versioning\_alter\_history

 * **Description:** SQL:2011 does not allow [ALTER TABLE](../alter-table/index) on system-versioned tables. When this variable is set to `ERROR`, an attempt to alter a system-versioned table will result in an error. When this variable is set to `KEEP`, ALTER TABLE will be allowed, but the history will become incorrect — querying historical data will show the new table structure. This mode is still useful, for example, when adding new columns to a table. Note that if historical data contains or would contain nulls, attempting to ALTER these columns to be `NOT NULL` will return an error (or warning if [strict\_mode](../sql-mode/index#strict-mode) is not set).
* **Commandline:** `--system-versioning-alter-history=value`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** Enum
* **Default Value:** `ERROR`
* **Valid Values:** `ERROR`, `KEEP`

 

---

 #### `system_versioning_asof`

 * **Description:** If set to a specific timestamp value, an implicit `FOR SYSTEM_TIME AS OF` clause will be applied to all queries. This is useful if one wants to do many queries for history at the specific point in time. Set it to `DEFAULT` to restore the default behavior. Has no effect on DML, so queries such as [INSERT .. SELECT](../insert-select/index) and [REPLACE .. SELECT](../replace/index) need to state AS OF explicitly.
* **Commandline:** None
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** Varchar
* **Default Value:** `DEFAULT`

 

---

 #### system\_versioning\_innodb\_algorithm\_simple

 * **Description:** Never fully implemented and removed in the following release.
* **Commandline:** `--system-versioning-innodb-algorithm-simple[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** Boolean
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/)
* **Removed:** [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)

 

---

 #### system\_versioning\_insert\_history

 * **Description:** Allows direct inserts into ROW\_START and ROW\_END columns if [secure\_timestamp](../server-system-variables/index#secure_timestamp) allows changing [timestamp](../server-system-variables/index#timestamp).
* **Commandline:** `--system-versioning-insert-history[={0|1}]`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Type:** Boolean
* **Default Value:** `OFF`
* **Introduced:** [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/)

 

---

 Limitations
-----------

 * Versioning clauses can not be applied to [generated (virtual and persistent) columns](../generated-columns/index).
* Before [MariaDB 10.11](../what-is-mariadb-1011/index), [mariadb-dump](../mariadb-dumpmysqldump/index) did not read historical rows from versioned tables, and so historical data would not be backed up. Also, a restore of the timestamps would not be possible as they cannot be defined by an insert/a user. From [MariaDB 10.11](../what-is-mariadb-1011/index), use the `-H` or `--dump-history` options to include the history.

 See Also
--------

 * [Application-Time Periods](../application-time-periods/index)
* [Bitemporal Tables](../bitemporal-tables/index)
* [mysql.transaction\_registry Table](../mysqltransaction_registry-table/index)
* [MariaDB Temporal Tables](https://youtu.be/uBoUlTsU1Tk) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-versioned-tables/>

Spider Status Variables
=======================

    The following status variables are associated with the [Spider storage engine](../spider/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Spider_direct_aggregate`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Spider_direct_delete`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Spider_direct_order_limit`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Spider_direct_update`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `Spider_mon_table_cache_version`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Spider_mon_table_cache_version_req`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Spider_parallel_search`

 * **Description:**
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-server-status-variables/>

AWS Key Management Encryption Plugin
====================================

    
Due to license incompatibilities between the MariaDB server source code and the Amazon AWS C++ SDK we can only distribute the plugin in source code form, and not as ready-to-use binaries. See [Installing the Plugin's Package](#installing-the-plugins-package) for details.

 
MariaDB's [data-at-rest encryption](../data-at-rest-encryption/index) requires the use of a [key management and encryption plugin](../encryption-key-management/index). These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of [multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports [key rotation](../encryption-key-management/index#key-rotation), then encryption keys can also be rotated, which creates a new version of the encryption key.

 The AWS Key Management plugin is a [key management and encryption plugin](../encryption-key-management/index) that uses the [Amazon Web Services (AWS) Key Management Service (KMS)](https://aws.amazon.com/kms/).

 Overview
--------

 The AWS Key Management plugin uses the [Amazon Web Services (AWS) Key Management Service (KMS)](https://aws.amazon.com/kms/) to generate and store AES keys on disk, in encrypted form, using the Customer Master Key (CMK) kept in AWS KMS. When MariaDB Server starts, the plugin will decrypt the encrypted keys, using the AWS KMS "Decrypt" API function. MariaDB data will then be encrypted and decrypted using the AES key. It supports multiple encryption keys. It supports key rotation.

 Tutorials
---------

 Tutorials related to the AWS Key Management plugin can be found at the following pages:

 * [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide](../aws-key-management-encryption-plugin-setup-guide/index)
* [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Advanced Usage](../aws-key-management-encryption-plugin-advanced-usage/index)

 Preparation
-----------

 * Before you use the plugin, you need to create a Customer Master Key (CMK). Create a key using the AWS Console as described in the [AMS KMS developer guide](http://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html).
* The easiest way to give the AWS key management plugin access to the key is to create an IAM Role with access to the key, and to apply that IAM Role to an EC2 instance where MariaDB Server runs.
* Make sure that MariaDB Server runs under the correct AWS identity that has access to the above key. For example, you can store the AWS credentials in a AWS credentials file for the user who runs `mysqld`. More information about the credentials file can be found in [the AWS CLI Getting Started Guide](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-config-file).

 Installing the Plugin's Package
-------------------------------

 The AWS Key Management plugin depends on the [AWS SDK for C++](https://github.com/aws/aws-sdk-cpp), which uses the [Apache License, Version 2.0](https://github.com/aws/aws-sdk-cpp/blob/master/LICENSE). This license is not compatible with MariaDB Server's [GPL 2.0 license](../mariadb-license/index), so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from source.

 ### Installing from Source

 When [compiling MariaDB from source](../compiling-mariadb-from-source/index), the AWS Key Management plugin is not built by default in [MariaDB 10.1](../what-is-mariadb-101/index), but it is built by default in [MariaDB 10.2](../what-is-mariadb-102/index) and later, on systems that support it.

 Compilation is controlled by the following `[cmake](../generic-build-instructions/index#using-cmake)` arguments:

 * `-DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC` to build a loadable plugin library
* `-DAWS_SDK_EXTERNAL_PROJECT=ON` to download the AWS C++ SDK code
* `-DNOT_FOR_DISTRIBUTION=ON` to confirm that you know to not distribute the resulting binaries

 The plugin uses [AWS C++ SDK](https://github.com/awslabs/aws-sdk-cpp), which introduces the following restrictions:

 * The plugin can only be built on Windows, Linux and macOS.
* The plugin requires that one of the following compilers is used: `gcc` 4.8 or later, `clang` 3.3 or later, Visual Studio 2013 or later.
* On Unix, the `libcurl` development package (e.g. `libcurl3-dev` on Debian Jessie), `uuid` development package and `openssl` need to be installed.
* You may need to use a newer version of `[cmake](../generic-build-instructions/index#using-cmake)` than is provided by default in your OS.

 You do not need to download / install the AWS C++ SDK yourself, the correct version of the SDK github repository will be cloned into the build directory at build time, and only the libraries for AWS components actually needed by the key management plugin will be built, which takes much less time than building the full AWS C++ SDK.

 #### Building on Linux

 With all prerequisites installed the actual build process pretty much comes down to:

 
```
# clone the MariaDB Server source code repository
git clone https://github.com/MariaDB/server.git
cd server

# prepare the build
mkdir _build
cd _build
cmake .. -DNOT_FOR_DISTRIBUTION=ON \
  -DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC \
  -DAWS_SDK_EXTERNAL_PROJECT=1

# build the plugin only
cd plugin/aws_key_management
make 

```


Cmake will print the following warning as part of its output, please take it serious and do not distribute the `aws_key_management.so` file to any third parties:

 **You have linked MariaDB with Apache 2.0 libraries! You may not distribute the resulting binary. If you do, you will put yourself into a legal problem with the Free Software Foundation.**

 
After `make` succeeded you can copy the created `aws_key_management.so` plugin library file to the plugin directory of your actual MariaDB Server machines installation, e.g. `/usr/lib64/mysql/plugin` on RedHat/Fedora based systems or `/usr/lib/mysql/plugin` on Debian based systems. 

 Installing the Plugin
---------------------

 Even after the package that contains the plugin's shared library is installed on the operating system, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'aws_key_management';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = aws_key_management

```

Uninstalling the Plugin
-----------------------

 Before you uninstall the plugin, you should ensure that [data-at-rest encryption](../data-at-rest-encryption/index) is completely disabled, and that MariaDB no longer needs the plugin to decrypt tables or other files.

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'aws_key_management';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Configuring the AWS Key Management Plugin
-----------------------------------------

 To enable the AWS Key Management plugin, you also need to set the plugin's system variables. The `[aws\_key\_management\_master\_key\_id](#aws_key_management_master_key_id)` system variable is the primary one to set. These system variables can be specified as command-line arguments to `[mysqld](../mysqld-options/index)` or they can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
aws_key_management_master_key_id=alias/<your key's alias>

```

Once you've updated the configuration file, [restart](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) the MariaDB server to apply the changes and make the key management and encryption plugin available for use.

 Using the AWS Key Management Plugin
-----------------------------------

 Once the AWS Key Management Plugin is enabled, you can use it by creating an encrypted table:

 
```
CREATE TABLE t (i int) ENGINE=InnoDB ENCRYPTED=YES

```

Now, table `t` will be encrypted using the encryption key generated by AWS.

 For more information on how to use encryption, see [Data at Rest Encryption](../data-at-rest-encryption/index).

 Using Multiple Encryption Keys
------------------------------

 The AWS Key Management Plugin supports [using multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key can be defined with a different 32-bit integer as a key identifier. If a previously unused identifier is used, then the plugin will automatically generate a new key.

 When [encrypting InnoDB tables](../innodb-encryption/index), the key that is used to encrypt tables [can be changed](../innodb-xtradb-encryption-keys/index).

 When [encrypting Aria tables](../aria-encryption/index), the key that is used to encrypt tables [cannot currently be changed](../aria-encryption-keys/index).

 Key Rotation
------------

 The AWS Key Management plugin does support [key rotation](../encryption-key-management/index#key-rotation). To rotate a key, set the `[aws\_key\_management\_rotate\_key](#aws_key_management_rotate_key)` system variable. For example, to rotate key with ID 2:

 
```
SET GLOBAL aws_key_management_rotate_key=2;

```

Or to rotate all keys, set the value to -1:

 
```
SET GLOBAL aws_key_management_rotate_key=-1;

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/) |
| 1.0 | Beta | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Experimental | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |

 
System Variables
----------------

 ### `aws_key_management_key_spec`

 * **Description:** Encryption algorithm used to create new keys
* **Commandline:** `--aws-key-management-key-spec=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `AES_128`
* **Valid Values:** `AES_128`, `AES_256`

 

---

 ### `aws_key_management_log_level`

 * **Description:** Dump log of the AWS SDK to MariaDB error log. Permitted values, in increasing verbosity, are **Off** (default), **Fatal**, **Error**, **Warn**, **Info**, **Debug**, and **Trace**.
* **Commandline:** `--aws-key-management-log-level=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `Off`
* **Valid Values:** `Off`, `Fatal`, `Warn`, `Info`, `Debug` and `Trace`

 

---

 ### `aws_key_management_master_key_id`

 * **Description:** AWS KMS Customer Master Key ID (ARN or alias prefixed by alias/) for the master encryption key. Used to create new data keys. If not set, no new data keys will be created.
* **Commandline:** `--aws-key-management-master-key-id=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:**

 

---

 ### `aws_key_management_mock`

 * **Description:** Mock AWS KMS calls (for testing). Must be enabled at compile-time.
* **Commandline:** `--aws-key-management-mock`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`
* **Valid Values:** `OFF`, `ON`

 

---

 ### `aws_key_management_region`

 * **Description:** AWS region name, e.g us-east-1 . Default is SDK default, which is us-east-1.
* **Commandline:** `--aws-key-management-region=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `'us-east-1'`

 

---

 ### `aws_key_management_request_timeout`

 * **Description:** Timeout in milliseconds for create HTTPS connection or execute AWS request. Specify 0 to use SDK default.
* **Commandline:** `--aws-key-management-request-timeout=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `integer`
* **Default Value:** 0

 

---

 ### `aws_key_management_rotate_key`

 * **Description:** Set this variable to a data key ID to perform rotation of the key to the master key given in `aws_key_management_master_key_id`. Specify -1 to rotate all keys.
* **Commandline:** `--aws-key-management-rotate-key=value`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `integer`
* **Default Value:**

 

---

 Options
-------

 ### `aws_key_management`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--aws-key-management=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aws-key-management-encryption-plugin/>

System and Status Variables Added By Major Release
===================================================

   
No new variables added in 10.7 and 10.8.

   

| Title | Description |
| --- | --- |
|  [System Variables Added in MariaDB 11.2](../system-variables-added-in-mariadb-11-2/index) |  List of system variables that were added in the MariaDB 11.2 series.  |
|  [System Variables Added in MariaDB 11.1](../system-variables-added-in-mariadb-11-1/index) |  List of system variables that were added in the MariaDB 11.1 series.  |
|  [System Variables Added in MariaDB 11.0](../system-variables-added-in-mariadb-11-0/index) |  List of system variables that were added in the MariaDB 11.0 series.  |
|  [System Variables Added in MariaDB 10.11](../system-variables-added-in-mariadb-10-11/index) |  List of system variables that were added in the MariaDB 10.11 series.  |
|  [System Variables Added in MariaDB 10.10](../system-variables-added-in-mariadb-10-10/index) |  List of system variables that were added in the MariaDB 10.10 series.  |
|  [System Variables Added in MariaDB 10.9](../system-variables-added-in-mariadb-10-9/index) |  List of system variables that were added in the MariaDB 10.9 series.  |
|  [System Variables Added in MariaDB 10.8](../system-variables-added-in-mariadb-10-8/index) |  List of system variables that were added in the MariaDB 10.8 series.  |
|  [System Variables Added in MariaDB 10.6](../system-variables-added-in-mariadb-106/index) |  List of system variables that were added in the MariaDB 10.6 series.  |
|  [Status Variables Added in MariaDB 10.6](../status-variables-added-in-mariadb-106/index) |  List of status variables that were added in the MariaDB 10.6 series.  |
|  [System Variables Added in MariaDB 10.5](../system-variables-added-in-mariadb-105/index) |  List of system variables that were added in the MariaDB 10.5 series.  |
|  [Status Variables Added in MariaDB 10.5](../status-variables-added-in-mariadb-105/index) |  List of status variables that were added in the MariaDB 10.5 series.  |
|  [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-104/index) |  List of system variables that were added in the MariaDB 10.4 series.  |
|  [Status Variables Added in MariaDB 10.4](../status-variables-added-in-mariadb-104/index) |  List of status variables that were added in the MariaDB 10.4 series.  |
|  [System and Status Variables Added By Major Unmaintained Release](../system-and-status-variables-added-by-major-unmaintained-release/index) |  Lists of status and system variables added in unmaintained MariaDB major releases.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-and-status-variables-added-by-major-release/>

Query Cache Information Plugin
==============================

    The `QUERY_CACHE_INFO` plugin creates the [QUERY\_CACHE\_INFO](../information-schema-query_cache_info-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. This table shows all queries in the [query cache](../query-cache/index). Querying this table acquires the query cache lock and will result in lock waits for queries that are using or expiring from the query cache. You must have the [PROCESS](../grant/index#global-privileges) privilege to query this table.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'query_cache_info';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = query_cache_info

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'query_cache_info';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
select statement_schema, statement_text, result_blocks_count, 
  result_blocks_size from information_schema.query_cache_info;
+------------------+------------------+---------------------+--------------------+
| statement_schema | statement_text   | result_blocks_count | result_blocks_size |
+------------------+------------------+---------------------+--------------------+
| test             | select * from t1 |                   1 |                512 |
+------------------+------------------+---------------------+--------------------+

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.1 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.1 | Gamma | [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.0 | Alpha | [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/) |

 
Options
-------

 ### `query_cache_info`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--query-cache-info=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-cache-information-plugin/>

SHOW STATUS
===========

    Syntax
------

 
```
SHOW [GLOBAL | SESSION] STATUS
    [LIKE 'pattern' | WHERE expr]

```

Description
-----------

 `SHOW STATUS` provides server status information. This information also can be obtained using the [mariadb-admin extended-status](../mariadb-admin/index) command, or by querying the [Information Schema GLOBAL\_STATUS and SESSION\_STATUS](../information-schema-global_status-and-session_status-tables/index) tables. The `LIKE` clause, if present, indicates which variable names to match. The `WHERE` clause can be given to select rows using more general conditions.

 With the `GLOBAL` modifier, `SHOW STATUS` displays the status values for all connections to MariaDB. With `SESSION`, it displays the status values for the current connection. If no modifier is present, the default is `SESSION`. `LOCAL` is a synonym for `SESSION`. If you see a lot of 0 values, the reason is probably that you have used `SHOW STATUS` with a new connection instead of `SHOW GLOBAL STATUS`.

 Some status variables have only a global value. For these, you get the same value for both `GLOBAL` and `SESSION`.

 See [Server Status Variables](../server-status-variables/index) for a full list, scope and description of the variables that can be viewed with `SHOW STATUS`.

 The `LIKE` clause, if present on its own, indicates which variable name to match.

 The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 Examples
--------

 
```
SHOW GLOBAL STATUS;
+--------------------------------------------------------------+----------------------------------------+
| Variable_name                                                | Value                                  |
+--------------------------------------------------------------+----------------------------------------+
| Aborted_clients                                              | 0                                      |
| Aborted_connects                                             | 0                                      |
| Access_denied_errors                                         | 0                                      |
| Acl_column_grants                                            | 0                                      |
| Acl_database_grants                                          | 2                                      |
| Acl_function_grants                                          | 0                                      |
| Acl_procedure_grants                                         | 0                                      |
| Acl_proxy_users                                              | 2                                      |
| Acl_role_grants                                              | 0                                      |
| Acl_roles                                                    | 0                                      |
| Acl_table_grants                                             | 0                                      |
| Acl_users                                                    | 6                                      |
| Aria_pagecache_blocks_not_flushed                            | 0                                      |
| Aria_pagecache_blocks_unused                                 | 15706                                  |
...
| wsrep_local_index                                            | 18446744073709551615                   |
| wsrep_provider_name                                          |                                        |
| wsrep_provider_vendor                                        |                                        |
| wsrep_provider_version                                       |                                        |
| wsrep_ready                                                  | OFF                                    |
| wsrep_thread_count                                           | 0                                      |
+--------------------------------------------------------------+----------------------------------------+
516 rows in set (0.00 sec)

```

Example of filtered output:

 
```
SHOW STATUS LIKE 'Key%';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| Key_blocks_not_flushed | 0      |
| Key_blocks_unused      | 107163 |
| Key_blocks_used        | 0      |
| Key_blocks_warm        | 0      |
| Key_read_requests      | 0      |
| Key_reads              | 0      |
| Key_write_requests     | 0      |
| Key_writes             | 0      |
+------------------------+--------+
8 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-status/>

Information Schema GLOBAL\_STATUS and SESSION\_STATUS Tables
============================================================

    The [Information Schema](../information_schema/index) `GLOBAL_STATUS` and `SESSION_STATUS` tables store a record of all [status variables](../server-status-variables/index) and their global and session values respectively. This is the same information as displayed by the `[SHOW STATUS](../show-status/index)` commands `SHOW GLOBAL STATUS` and `SHOW SESSION STATUS`.

 They contain the following columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | Status variable name. |
| `VARIABLE_VALUE` | Global or session value. |

 
Example
-------

 
```
SELECT * FROM information_schema.GLOBAL_STATUS;
+-----------------------------------------------+--------------------+
| VARIABLE_NAME                                 | VARIABLE_VALUE     |
+-----------------------------------------------+--------------------+
...
| BINLOG_SNAPSHOT_FILE                          | mariadb-bin.000208 |
| BINLOG_SNAPSHOT_POSITION                      | 369                |
...
| THREADS_CONNECTED                             | 1                  |
| THREADS_CREATED                               | 1                  |
| THREADS_RUNNING                               | 1                  |
| UPTIME                                        | 57358              |
| UPTIME_SINCE_FLUSH_STATUS                     | 57358              |
+-----------------------------------------------+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-global_status-and-session_status-tables/>

mysql.db Table
==============

    The `mysql.db` table contains information about database-level privileges. The table can be queried and although it is possible to directly update it, it is best to use [GRANT](../grant/index) for setting privileges. 

 Note that the MariaDB privileges occur at many levels. A user may not be granted a privilege at the database level, but may still have permission on a table level, for example. See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.db` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description | Introduced |
| --- | --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User` and `Db` makes up the unique identifier for this record. Until [MariaDB 5.5](../what-is-mariadb-55/index), if the host field was blank, the corresponding record in the [mysql.host](../mysqlhost-table/index) table would be examined. From [MariaDB 10.0](../what-is-mariadb-100/index), a blank host field is the same as the `%` wildcard. |  |
| `Db` | `char(64)` | NO | PRI |  | Database (together with `User` and `Host` makes up the unique identifier for this record. |  |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host` and `Db` makes up the unique identifier for this record. |  |
| `Select_priv` | `enum('N','Y')` | NO |  | N | Can perform [SELECT](../select/index) statements. |  |
| `Insert_priv` | `enum('N','Y')` | NO |  | N | Can perform [INSERT](../insert/index) statements. |  |
| `Update_priv` | `enum('N','Y')` | NO |  | N | Can perform [UPDATE](../update/index) statements. |  |
| `Delete_priv` | `enum('N','Y')` | NO |  | N | Can perform [DELETE](../delete/index) statements. |  |
| `Create_priv` | `enum('N','Y')` | NO |  | N | Can [CREATE TABLE's](../create-table/index). |  |
| `Drop_priv` | `enum('N','Y')` | NO |  | N | Can [DROP DATABASE's](../drop-database/index) or [DROP TABLE's](../drop-table/index). |  |
| `Grant_priv` | `enum('N','Y')` | NO |  | N | User can [grant](../grant/index) privileges they possess. |  |
| `References_priv` | `enum('N','Y')` | NO |  | N | Unused |  |
| `Index_priv` | `enum('N','Y')` | NO |  | N | Can create an index on a table using the [CREATE INDEX](../create-index/index) statement. Without the `INDEX` privilege, user can still create indexes when creating a table using the [CREATE TABLE](../create-table/index) statement if the user has have the `CREATE` privilege, and user can create indexes using the [ALTER TABLE](../alter-table/index) statement if they have the `ALTER` privilege. |  |
| `Alter_priv` | `enum('N','Y')` | NO |  | N | Can perform [ALTER TABLE](../alter-table/index) statements. |  |
| `Create_tmp_table_priv` | `enum('N','Y')` | NO |  | N | Can create temporary tables with the [CREATE TEMPORARY TABLE](../create-table/index) statement. |  |
| `Lock_tables_priv` | `enum('N','Y')` | NO |  | N | Acquire explicit locks using the [LOCK TABLES](../transactions-lock/index) statement; user also needs to have the `SELECT` privilege on a table in order to lock it. |  |
| `Create_view_priv` | `enum('N','Y')` | NO |  | N | Can create a view using the [CREATE\_VIEW](../create-view/index) statement. |  |
| `Show_view_priv` | `enum('N','Y')` | NO |  | N | Can show the [CREATE VIEW](../create-view/index) statement to create a view using the [SHOW CREATE VIEW](../show-create-view/index) statement. |  |
| `Create_routine_priv` | `enum('N','Y')` | NO |  | N | Can create stored programs using the [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) statements. |  |
| `Alter_routine_priv` | `enum('N','Y')` | NO |  | N | Can change the characteristics of a stored function using the [ALTER FUNCTION](../alter-function/index) statement. |  |
| `Execute_priv` | `enum('N','Y')` | NO |  | N | Can execute [stored procedure](../stored-procedures/index) or functions. |  |
| `Event_priv` | `enum('N','Y')` | NO |  | N | Create, drop and alter [events](../stored-programs-and-views-events/index). |  |
| `Trigger_priv` | `enum('N','Y')` | NO |  | N | Can execute [triggers](../triggers/index) associated with tables the user updates, execute the [CREATE TRIGGER](../create-trigger/index) and [DROP TRIGGER](../drop-trigger/index) statements. |  |
| `Delete_history_priv` | `enum('N','Y')` | NO |  | N | Can delete rows created through [system versioning](../system-versioned-tables/index). | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |

 
The [Acl\_database\_grants](../server-status-variables/index#acl_database_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.db` table contains.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqldb-table/>

mysql.columns\_priv Table
=========================

    The `mysql.columns_priv` table contains information about column-level privileges. The table can be queried and although it is possible to directly update it, it is best to use [GRANT](../grant/index) for setting privileges. 

 Note that the MariaDB privileges occur at many levels. A user may be granted a privilege at the column level, but may still not have permission on a table level, for example. See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 The [INFORMATION\_SCHEMA.COLUMN\_PRIVILEGES](../information-schema-column_privileges-table/index) table derives its contents from `mysql.columns_priv`.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.columns_priv` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User`, `Db` , `Table_name` and`Column_name` makes up the unique identifier for this record. |
| `Db` | `char(64)` | NO | PRI |  | Database name (together with `User`, `Host` , `Table_name` and`Column_name` makes up the unique identifier for this record. |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host`, `Db` , `Table_name` and`Column_name` makes up the unique identifier for this record. |
| `Table_name` | `char(64)` | NO | PRI |  | Table name (together with `User`, `Db` , `Host` and`Column_name` makes up the unique identifier for this record. |
| `Column_name` | `char(64)` | NO | PRI |  | Column name (together with `User`, `Db` , `Table_name` and`Host` makes up the unique identifier for this record. |
| `Timestamp` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` |  |
| `Column_priv` | `set('Select', 'Insert', 'Update', 'References')` | NO |  |  | The privilege type. See [Column Privileges](../grant/index#column-privileges) for details. |

 
The [Acl\_column\_grants](../server-status-variables/index#acl_column_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.columns_priv` table contains.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlcolumns_priv-table/>

mysql.procs\_priv Table
=======================

    The `mysql.procs_priv` table contains information about [stored procedure](../stored-procedures/index) and [stored function](../stored-functions/index) privileges. See [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) on creating these. 

 The [INFORMATION\_SCHEMA.ROUTINES](../information-schema-routines-table/index) table derives its contents from `mysql.procs_priv`.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.procs_priv` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `Db`, `User`, `Routine_name` and `Routine_type` makes up the unique identifier for this record). |
| `Db` | `char(64)` | NO | PRI |  | Database (together with `Host`, `User`, `Routine_name` and `Routine_type` makes up the unique identifier for this record). |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host`, `Db`, `Routine_name` and `Routine_type` makes up the unique identifier for this record). |
| `Routine_name` | `char(64)` | NO | PRI |  | Routine\_name (together with `Host`, `Db` `User` and `Routine_type` makes up the unique identifier for this record). |
| `Routine_type` | `enum('FUNCTION','PROCEDURE', 'PACKAGE', 'PACKAGE BODY')` | NO | PRI | `NULL` | Whether the routine is a [stored procedure](../stored-procedures/index), [stored function](../stored-functions/index), or, from [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), a [package](../create-package/index) or [package body](../create-package-body/index). |
| `Grantor` | `char(141)` | NO | MUL |  |  |
| `Proc_priv` | `set('Execute','Alter Routine','Grant')` | NO |  |  | The routine privilege. See [Function Privileges](../grant/index#function-privileges) and [Procedure Privileges](../grant/index#procedure-privileges) for details. |
| `Timestamp` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` |  |

 
The [Acl\_function\_grants](../server-status-variables/index#acl_function_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.columns_priv` table contains with the `FUNCTION` routine type.

 The [Acl\_procedure\_grants](../server-status-variables/index#acl_procedure_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.columns_priv` table contains with the `PROCEDURE` routine type.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlprocs_priv-table/>

mysql.proxies\_priv Table
=========================

    The `mysql.proxies_priv` table contains information about proxy privileges. The table can be queried and although it is possible to directly update it, it is best to use [GRANT](../grant/index) for setting privileges. 

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.proxies_priv` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  |  |
| `User` | `char(80)` | NO | PRI |  |  |
| `Proxied_host` | `char(60)` | NO | PRI |  |  |
| `Proxied_user` | `char(80)` | NO | PRI |  |  |
| `With_grant` | `tinyint(1)` | NO |  | 0 |  |
| `Grantor` | `char(141)` | NO | MUL |  |  |
| `Timestamp` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` |  |

 
The [Acl\_proxy\_users](../server-status-variables/index#acl_proxy_users) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.proxies_priv` table contains.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlproxies_priv-table/>

ALTER FUNCTION
==============

    Syntax
------

 
```
ALTER FUNCTION func_name [characteristic ...]

characteristic:
    { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

```
 Description
-----------

 This statement can be used to change the characteristics of a stored function. More than one change may be specified in an `ALTER FUNCTION` statement. However, you cannot change the parameters or body of a stored function using this statement; to make such changes, you must drop and re-create the function using [DROP FUNCTION](../drop-function/index) and [CREATE FUNCTION](../create-function/index).

 You must have the `ALTER ROUTINE` privilege for the function. (That privilege is granted automatically to the function creator.) If binary logging is enabled, the `ALTER FUNCTION` statement might also require the `SUPER` privilege, as described in [Binary Logging of Stored Routines](../binary-logging-of-stored-routines/index).

 Example
-------

 
```
ALTER FUNCTION hello SQL SECURITY INVOKER;

```

See Also
--------

 * [CREATE FUNCTION](../create-function/index)
* [SHOW CREATE FUNCTION](../show-create-function/index)
* [DROP FUNCTION](../drop-function/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-function/>

ALTER DATABASE
==============

    Modifies a database, changing its overall characteristics.

 Syntax
------

 
```
ALTER {DATABASE | SCHEMA} [db_name]
    alter_specification ...
ALTER {DATABASE | SCHEMA} db_name
    UPGRADE DATA DIRECTORY NAME

alter_specification:
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | COMMENT [=] 'comment'

```
 Description
-----------

 `ALTER DATABASE` enables you to change the overall characteristics of a database. These characteristics are stored in the `db.opt` file in the database directory. To use `ALTER DATABASE`, you need the `ALTER` privilege on the database. `ALTER SCHEMA` is a synonym for ALTER DATABASE.

 The `CHARACTER SET` clause changes the default database character set. The `COLLATE` clause changes the default database collation. See [Character Sets and Collations](../data-types-character-sets-and-collations/index) for more.

 You can see what character sets and collations are available using, respectively, the [SHOW CHARACTER SET](../show-character-set/index) and [SHOW COLLATION](../show-collation/index) statements.

 Changing the default character set/collation of a database does not change the character set/collation of any [stored procedures](../stored-procedures/index) or [stored functions](../stored-functions/index) that were previously created, and relied on the defaults. These need to be dropped and recreated in order to apply the character set/collation changes.

 The database name can be omitted from the first syntax, in which case the statement applies to the default database.

 The syntax that includes the `UPGRADE DATA DIRECTORY NAME` clause was added in MySQL 5.1.23. It updates the name of the directory associated with the database to use the encoding implemented in MySQL 5.1 for mapping database names to database directory names (see [Identifier to File Name Mapping](../identifier-to-file-name-mapping/index)). This clause is for use under these conditions:

 * It is intended when upgrading MySQL to 5.1 or later from older versions.
* It is intended to update a database directory name to the current encoding format if the name contains special characters that need encoding.
* The statement is used by [mariadb-check](../mariadb-check/index) (as invoked by [mariadb-upgrade](../mariadb-upgrade/index)).

 For example,if a database in MySQL 5.0 has a name of a-b-c, the name contains instance of the `-' character. In 5.0, the database directory is also named a-b-c, which is not necessarily safe for all file systems. In MySQL 5.1 and up, the same database name is encoded as a@002db@002dc to produce a file system-neutral directory name.

 When a MySQL installation is upgraded to MySQL 5.1 or later from an older version,the server displays a name such as a-b-c (which is in the old format) as #mysql50#a-b-c, and you must refer to the name using the #mysql50# prefix. Use `UPGRADE DATA DIRECTORY NAME` in this case to explicitly tell the server to re-encode the database directory name to the current encoding format:

 
```
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;

```

After executing this statement, you can refer to the database as a-b-c without the special #mysql50# prefix.

 #### COMMENT

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), it is possible to add a comment of a maximum of 1024 bytes. If the comment length exceeds this length, a error/warning code 4144 is thrown. The database comment is also added to the db.opt file, as well as to the [information\_schema.schemata table](../information-schema-schemata-table/index).

 
Examples
--------

 
```
ALTER DATABASE test CHARACTER SET='utf8'  COLLATE='utf8_bin';

```

From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 
```
ALTER DATABASE p COMMENT='Presentations';

```

See Also
--------

 * [CREATE DATABASE](../create-database/index)
* [DROP DATABASE](../drop-database/index)
* [SHOW CREATE DATABASE](../show-create-database/index)
* [SHOW DATABASES](../show-databases/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [Information Schema SCHEMATA Table](../information-schema-schemata-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-database/>

ALTER PROCEDURE
===============

    Syntax
------

 
```
ALTER PROCEDURE proc_name [characteristic ...]

characteristic:
    { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

```

Description
-----------

 This statement can be used to change the characteristics of a [stored procedure](../stored-procedures/index). More than one change may be specified in an `ALTER PROCEDURE` statement. However, you cannot change the parameters or body of a stored procedure using this statement. To make such changes, you must drop and re-create the procedure using either [CREATE OR REPLACE PROCEDURE](../create-procedure/index) (since [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)) or [DROP PROCEDURE](../drop-procedure/index) and [CREATE PROCEDURE](../create-procedure/index) ([MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) and before).

 You must have the `ALTER ROUTINE` privilege for the procedure. By default, that privilege is granted automatically to the procedure creator. See [Stored Routine Privileges](../stored-routine-privileges/index).

 Example
-------

 
```
ALTER PROCEDURE simpleproc SQL SECURITY INVOKER;

```

See Also
--------

 * [Stored Procedure Overview](../stored-procedure-overview/index)
* [CREATE PROCEDURE](../create-procedure/index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [DROP PROCEDURE](../drop-procedure/index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-procedure/>

ALTER EVENT
===========

    Modifies one or more characteristics of an existing event.

 Syntax
------

 
```
ALTER
    [DEFINER = { user | CURRENT_USER }]
    EVENT event_name
    [ON SCHEDULE schedule]
    [ON COMPLETION [NOT] PRESERVE]
    [RENAME TO new_event_name]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    [DO sql_statement]

```
 Description
-----------

 The `ALTER EVENT` statement is used to change one or more of the characteristics of an existing [event](../events/index) without the need to drop and recreate it. The syntax for each of the `DEFINER`, `ON SCHEDULE`, `ON COMPLETION`, `COMMENT`, `ENABLE` `/` `DISABLE`, and `DO` clauses is exactly the same as when used with [CREATE EVENT](../create-event/index).

 This statement requires the [EVENT](../grant/index#database-privileges) privilege. When a user executes a successful `ALTER EVENT` statement, that user becomes the definer for the affected event.

 (In MySQL 5.1.11 and earlier, an event could be altered only by its definer, or by a user having the [SUPER](../grant/index#global-privileges) privilege.)

 `ALTER EVENT` works only with an existing event:

 
```
ALTER EVENT no_such_event ON SCHEDULE EVERY '2:3' DAY_HOUR;
ERROR 1539 (HY000): Unknown event 'no_such_event'

```

Examples
--------

 
```
ALTER EVENT myevent 
  ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 2 HOUR 
  DO 
    UPDATE myschema.mytable SET mycol = mycol + 1;

```

See Also
--------

 * [Events Overview](../events-overview/index)
* [CREATE EVENT](../create-event/index)
* [SHOW CREATE EVENT](../show-create-event/index)
* [DROP EVENT](../drop-event/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-event/>

SSL/TLS Status Variables
========================

    The status variables listed on this page relate to encrypting data during transfer with the Transport Layer Security (TLS) protocol. Often, the term Secure Socket Layer (SSL) is used interchangeably with TLS, although strictly speaking, the SSL protocol is a predecessor to TLS and is no longer considered secure. 

 For compatibility reasons, the TLS status variables in MariaDB still use the `Ssl_` prefix, but MariaDB only supports its more secure successors. For more information on SSL/TLS in MariaDB, see [Secure Connections Overview](../secure-connections-overview/index).

 Variables
---------

 #### `Ssl_accept_renegotiates`

 * **Description:** Number of negotiations needed to establish the TLS connection. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_accepts`

 * **Description:** Number of accepted TLS handshakes. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_callback_cache_hits`

 * **Description:** Number of sessions retrieved from the session cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_cipher`

 * **Description:** The TLS cipher currently in use.
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

 #### `Ssl_cipher_list`

 * **Description:** List of the available TLS ciphers.
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

 #### `Ssl_client_connects`

 * **Description:** Number of TLS handshakes started in client mode. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_connect_renegotiates`

 * **Description:** Number of negotiations needed to establish the connection to a TLS-enabled master. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_ctx_verify_depth`

 * **Description:** Number of tested TLS certificates in the chain. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_ctx_verify_mode`

 * **Description:** Mode used for TLS context verification.The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_default_timeout`

 * **Description:** Default timeout for TLS, in seconds.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Ssl_finished_accepts`

 * **Description:** Number of successful TLS sessions in server mode. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_finished_connects`

 * **Description:** Number of successful TLS sessions in client mode. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_server_not_after`

 * **Description:** Last valid date for the TLS certificate.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** `[MariaDB 10.0](../what-is-mariadb-100/index)`

 

---

 #### `Ssl_server_not_before`

 * **Description:** First valid date for the TLS certificate.
* **Scope:** Global, Session
* **Data Type:** `numeric`
* **Introduced:** `[MariaDB 10.0](../what-is-mariadb-100/index)`

 

---

 #### `Ssl_session_cache_hits`

 * **Description:** Number of TLS sessions found in the session cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_session_cache_misses`

 * **Description:** Number of TLS sessions not found in the session cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_session_cache_mode`

 * **Description:** Mode used for TLS caching by the server.
* **Scope:** Global
* **Data Type:** `string`

 

---

 #### `Ssl_session_cache_overflows`

 * **Description:** Number of sessions removed from the session cache because it was full. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_session_cache_size`

 * **Description:** Size of the session cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_session_cache_timeouts`

 * **Description:** Number of sessions which have timed out. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_sessions_reused`

 * **Description:** Number of sessions reused. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Ssl_used_session_cache_entries`

 * **Description:** Current number of sessions in the session cache. The global value can be flushed by `[FLUSH STATUS](../flush/index)`.
* **Scope:** Global
* **Data Type:** `numeric`

 

---

 #### `Ssl_verify_depth`

 * **Description:** TLS verification depth.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Ssl_verify_mode`

 * **Description:** TLS verification mode.
* **Scope:** Global, Session
* **Data Type:** `numeric`

 

---

 #### `Ssl_version`

 * **Description:** TLS version in use.
* **Scope:** Global, Session
* **Data Type:** `string`

 

---

 See Also
--------

 * [Server Status Variables](../server-status-variables/index) - complete list of status variables.
* [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ssl-status-variables/>

mysql.roles\_mapping Table
==========================

    The `mysql.roles_mapping` table contains information about mariaDB [roles](../roles/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.roles_mapping` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User` and `Role` makes up the unique identifier for this record. |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host` and `Role` makes up the unique identifier for this record. |
| `Role` | `char(80)` | NO | PRI |  | Role (together with `Host` and `User` makes up the unique identifier for this record. |
| `Admin_option` | `enum('N','Y')` | NO |  | N | Whether the role can be granted (see the [CREATE ROLE](../create-role/index) `WITH ADMIN` clause). |

 
The [Acl\_role\_grants](../server-status-variables/index#acl_role_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.roles_mapping` table contains.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlroles_mapping-table/>

ALTER SEQUENCE
==============

    Syntax
------

 
```
ALTER SEQUENCE [IF EXISTS] sequence_name
[ INCREMENT [ BY | = ] increment ]
[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]
[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]
[ START [ WITH | = ] start ] [ CACHE [=] cache ] [ [ NO ] CYCLE ]
[ RESTART [[WITH | =] restart]
```
 `ALTER SEQUENCE` allows one to change any values for a `SEQUENCE` created with [CREATE SEQUENCE](../create-sequence/index).

 The options for `ALTER SEQUENCE` can be given in any order.

 Description
-----------

 `ALTER SEQUENCE` changes the parameters of an existing sequence generator. Any parameters not specifically set in the `ALTER SEQUENCE` command retain their prior settings.

 `ALTER SEQUENCE` requires the [ALTER privilege](../grant/index).

 ### Arguments to `ALTER SEQUENCE`

 The following options may be used:

 


| Option | Default value | Description |
| --- | --- | --- |
| `INCREMENT` | 1 | Increment to use for values. May be negative. |
| `MINVALUE` | 1 if `INCREMENT` > 0 and -9223372036854775807 if `INCREMENT` < 0 | Minimum value for the sequence. |
| `MAXVALUE` | 9223372036854775806 if `INCREMENT` > 0 and -1 if `INCREMENT` < 0 | Max value for sequence. |
| `START` | `MINVALUE` if `INCREMENT` > 0 and `MAX_VALUE` if `INCREMENT`< 0 | First value that the sequence will generate. |
| `CACHE` | 1000 | Number of values that should be cached. 0 if no `CACHE`. The underlying table will be updated first time a new sequence number is generated and each time the cache runs out. |
| `CYCLE` | 0 (= `NO CYCLE`) | 1 if the sequence should start again from `MINVALUE`# after it has run out of values. |
| `RESTART` | `START` if `restart` value not is given |  If `RESTART` option is used, `NEXT VALUE` will return the restart value. |

 
The optional clause `RESTART [ WITH restart ]` sets the next value for the sequence. This is equivalent to calling the [SETVAL()](../setval/index) function with the `is_used` argument as 0. The specified value will be returned by the next call of nextval. Using `RESTART` with no restart value is equivalent to supplying the start value that was recorded by [CREATE SEQUENCE](../create-sequence/index) or last set by `ALTER SEQUENCE START WITH`.

 `ALTER SEQUENCE` will not allow you to change the sequence so that it's inconsistent. For example:

 
```
CREATE SEQUENCE s1;
ALTER SEQUENCE s1 MINVALUE 10;
ERROR 4061 (HY000): Sequence 'test.t1' values are conflicting

ALTER SEQUENCE s1 MINVALUE 10 RESTART 10;
ERROR 4061 (HY000): Sequence 'test.t1' values are conflicting

ALTER SEQUENCE s1 MINVALUE 10 START 10 RESTART 10;

```

### INSERT

 To allow `SEQUENCE` objects to be backed up by old tools, like [mariadb-dump](../mariadb-dump/index), one can use `SELECT` to read the current state of a `SEQUENCE` object and use an `INSERT` to update the `SEQUENCE` object. `INSERT` is only allowed if all fields are specified:

 
```
CREATE SEQUENCE s1;
INSERT INTO s1 VALUES(1000,10,2000,1005,1,1000,0,0);
SELECT * FROM s1;

+------------+-----------+-----------+-------+-----------+-------+-------+-------+
| next_value | min_value | max_value | start | increment | cache | cycle | round |
+------------+-----------+-----------+-------+-----------+-------+-------+-------+
|       1000 |        10 |      2000 |  1005 |         1 |  1000 |     0 |     0 |
+------------+-----------+-----------+-------+-----------+-------+-------+-------+

SHOW CREATE SEQUENCE s1;
+-------+--------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                 |
+-------+--------------------------------------------------------------------------------------------------------------+
| s1    | CREATE SEQUENCE `s1` start with 1005 minvalue 10 maxvalue 2000 increment by 1 cache 1000 nocycle ENGINE=Aria |
+-------+--------------------------------------------------------------------------------------------------------------+

```

### Notes

 `ALTER SEQUENCE` will instantly affect all future `SEQUENCE` operations. This is in contrast to some other databases where the changes requested by `ALTER SEQUENCE` will not be seen until the sequence cache has run out.

 `ALTER SEQUENCE` will take a full table lock of the sequence object during its (brief) operation. This ensures that `ALTER SEQUENCE` is replicated correctly. If you only want to set the next sequence value to a higher value than current, then you should use [SETVAL()](../setval/index) instead, as this is not blocking.

 If you want to change storage engine, sequence comment or rename the sequence, you can use [ALTER TABLE](../alter-table/index) for this.

 See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [DROP SEQUENCE](../drop-sequence/index)
* [NEXT VALUE FOR](../next-value-for-sequence_name/index)
* [PREVIOUS VALUE FOR](../previous-value-for-sequence_name/index)
* [SETVAL()](../setval/index). Set next value for the sequence.
* [AUTO INCREMENT](../auto_increment/index)
* [ALTER TABLE](../alter-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-sequence/>

ALTER TABLESPACE
================

    
The `ALTER TABLESPACE` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See [MDEV-19294](https://jira.mariadb.org/browse/MDEV-19294) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-tablespace/>

ANALYZE TABLE
=============

    Syntax
------

 
```
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [,tbl_name ...]
  [PERSISTENT FOR 
    { ALL
      | COLUMNS ([col_name [,col_name ...]]) INDEXES ([index_name [,index_name ...]])
    }
  ]         

```
 Description
-----------

 `ANALYZE TABLE` analyzes and stores the key distribution for a table ([index statistics](../index-statistics/index)). This statement works with [MyISAM](../myisam/index), [Aria](../aria/index) and [InnoDB](../innodb/index) tables. During the analysis, InnoDB will allow reads/writes, and MyISAM/Aria reads/inserts. For MyISAM tables, this statement is equivalent to using [myisamchk --analyze](../myisamchk/index).

 For more information on how the analysis works within InnoDB, see [InnoDB Limitations](../innodb-limitations/index#table-analysis).

 MariaDB uses the stored key distribution to decide the order in which tables should be joined when you perform a join on something other than a constant. In addition, key distributions can be used when deciding which indexes to use for a specific table within a query.

 This statement requires [SELECT and INSERT privileges](../grant/index) for the table.

 By default, ANALYZE TABLE statements are written to the [binary log](../binary-log/index) and will be [replicated](../replication/index). The `NO_WRITE_TO_BINLOG` keyword (`LOCAL` is an alias) will ensure the statement is not written to the binary log. 

 From [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), `ANALYZE TABLE` statements are not logged to the binary log if [read\_only](../server-system-variables/index#read_only) is set. See also [Read-Only Replicas](../read-only-replicas/index).

 `ANALYZE TABLE` is also supported for partitioned tables. You can use `[ALTER TABLE](../alter-table/index) ... ANALYZE PARTITION` to analyze one or more partitions.

 The [Aria](../aria/index) storage engine supports [progress reporting](../progress-reporting/index) for the `ANALYZE TABLE` statement.

 Engine-Independent Statistics
-----------------------------

 `ANALYZE TABLE` supports [engine-independent statistics](../engine-independent-table-statistics/index). See [Engine-Independent Table Statistics: Collecting Statistics with the ANALYZE TABLE Statement](../engine-independent-table-statistics/index#collecting-statistics-with-the-analyze-table-statement) for more information.

 Useful Variables
----------------

 For calculating the number of duplicates, `ANALYZE TABLE` uses a buffer of [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size) bytes per column. You can slightly increase the speed of `ANALYZE TABLE` by increasing this variable.

 Examples
--------

 
```
-- update all engine-independent statistics for all columns and indexes
ANALYZE TABLE tbl PERSISTENT FOR ALL;

-- update specific columns and indexes:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES (idx1,idx2,...);

-- empty lists are allowed:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES ();
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES (idx1,idx2,...);

-- the following will only update mysql.table_stats fields:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES ();

-- when use_stat_tables is set to 'COMPLEMENTARY' or 'PREFERABLY', 
-- a simple ANALYZE TABLE  collects engine-independent statistics for all columns and indexes.
SET SESSION use_stat_tables='COMPLEMENTARY';
ANALYZE TABLE tbl;

```

See Also
--------

 * [This one trick can make MariaDB 30x faster!](https://mariadb.org/mariadb-30x-faster/) (mariadb.org blog)
* [Index Statistics](../index-statistics/index)
* [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [Progress Reporting](../progress-reporting/index)
* [Engine-independent Statistics](../engine-independent-table-statistics/index)
* [Histogram-based Statistics](../histogram-based-statistics/index)
* [ANALYZE Statement](../analyze-statement/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/analyze-table/>

START TRANSACTION
=================

    Syntax
------

 
```
START TRANSACTION [transaction_property [, transaction_property] ...] | BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}

transaction_property:
    WITH CONSISTENT SNAPSHOT
  | READ WRITE
  | READ ONLY

```
 Description
-----------

 The `START TRANSACTION` or `BEGIN` statement begins a new transaction. [COMMIT](../transactions-commit-statement/index) commits the current transaction, making its changes permanent. [ROLLBACK](../rollback/index) rolls back the current transaction, canceling its changes. The [SET](../set-variable/index) [autocommit](../server-system-variables/index#autocommit) statement disables or enables the default autocommit mode for the current session.

 START TRANSACTION and SET autocommit = 1 implicitly commit the current transaction, if any.

 The optional `WORK` keyword is supported for `COMMIT` and `ROLLBACK`, as are the `CHAIN` and `RELEASE` clauses. `CHAIN` and `RELEASE` can be used for additional control over transaction completion. The value of the [completion\_type](../server-system-variables/index#completion_type) system variable determines the default completion behavior.

 The `AND CHAIN` clause causes a new transaction to begin as soon as the current one ends, and the new transaction has the same isolation level as the just-terminated transaction. The `RELEASE` clause causes the server to disconnect the current client session after terminating the current transaction. Including the `NO` keyword suppresses `CHAIN` or `RELEASE` completion, which can be useful if the [completion\_type](../server-system-variables/index#completion_type) system variable is set to cause chaining or release completion by default.

 ### Access Mode

 The access mode specifies whether the transaction is allowed to write data or not. By default, transactions are in `READ WRITE` mode (see the [tx\_read\_only](../server-system-variables/index#tx_read_only) system variable). `READ ONLY` mode allows the storage engine to apply optimizations that cannot be used for transactions which write data. Note that unlike the global `[read\_only](../server-system-variables/index#read_only)` mode, `[READ\_ONLY ADMIN](../grant/index#read_only-admin)` (and `[SUPER](../grant/index#super)` before [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/)) privilege doesn't allow writes and DDL statements on temporary tables are not allowed either.

 It is not permitted to specify both `READ WRITE` and `READ ONLY` in the same statement.

 `READ WRITE` and `READ ONLY` can also be specified in the `[SET TRANSACTION](../set-transaction/index)` statement, in which case the specified mode is valid for all sessions, or for all subsequent transaction used by the current session.

 ### autocommit

 By default, MariaDB runs with [autocommit](../server-system-variables/index#autocommit) mode enabled. This means that as soon as you execute a statement that updates (modifies) a table, MariaDB stores the update on disk to make it permanent. To disable autocommit mode, use the following statement:

 
```
SET autocommit=0;

```

After disabling autocommit mode by setting the autocommit variable to zero, changes to transaction-safe tables (such as those for InnoDB or `NDBCLUSTER`) are not made permanent immediately. You must use `COMMIT` to store your changes to disk or ROLLBACK to ignore the changes.

 To disable autocommit mode for a single series of statements, use the `START TRANSACTION` statement.

 ### DDL Statements

 DDL statements (`CREATE`, `ALTER`, `DROP`) and administrative statements (`FLUSH`, `RESET`, `OPTIMIZE`, `ANALYZE`, `CHECK`, `REPAIR`, `CACHE INDEX`), transaction management statements (`BEGIN`, `START TRANSACTION`) and `LOAD DATA INFILE`, cause an implicit `COMMIT` and start a new transaction. An exception to this rule are the DDL that operate on temporary tables: you can `CREATE`, `ALTER` and `DROP` them without causing any `COMMIT`, but those actions cannot be rolled back. This means that if you call `ROLLBACK`, the temporary tables you created in the transaction will remain, while the rest of the transaction will be rolled back.

 Transactions cannot be used in Stored Functions or Triggers. In Stored Procedures and Events BEGIN is not allowed, so you should use START TRANSACTION instead.

 A transaction acquires a [metadata lock](../metadata-locking/index) on every table it accesses to prevent other connections from altering their structure. The lock is released at the end of the transaction. This happens even with non-transactional storage engines (like [MEMORY](../memory-storage-engine/index) or [CONNECT](../connect/index)), so it makes sense to use transactions with non-transactional tables.

 ### in\_transaction

 The [in\_transaction](../server-system-variables/index#in_transaction) system variable is a session-only, read-only variable that returns `1` inside a transaction, and `0` if not in a transaction.

 ### WITH CONSISTENT SNAPSHOT

 The `WITH CONSISTENT SNAPSHOT` option starts a consistent read for storage engines such as [InnoDB](../innodb/index) that can do so, the same as if a START TRANSACTION followed by a SELECT from any InnoDB table was issued. 

 See [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index).

 Examples
--------

 
```
START TRANSACTION;
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT;

```

See Also
--------

 * [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index)
* [MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT](../myrocks-and-start-transaction-with-consistent-snapshot/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/start-transaction/>

ALTER USER
==========

    Syntax
------

 
```
ALTER USER [IF EXISTS] 
 user_specification [,user_specification] ...
  [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
  [WITH resource_option [resource_option] ...]
  [lock_option] [password_option] 

user_specification:
  username [authentication_option]

authentication_option:
  IDENTIFIED BY 'password' 
  | IDENTIFIED BY PASSWORD 'password_hash'
  | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule] ... 
 
authentication_rule:
  authentication_plugin
  | authentication_plugin {USING|AS} 'authentication_string'
  | authentication_plugin {USING|AS} PASSWORD('password')

tls_option
  SSL 
  | X509
  | CIPHER 'cipher'
  | ISSUER 'issuer'
  | SUBJECT 'subject'

resource_option
  MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
  | MAX_STATEMENT_TIME time

password_option:
  PASSWORD EXPIRE
  | PASSWORD EXPIRE DEFAULT
  | PASSWORD EXPIRE NEVER
  | PASSWORD EXPIRE INTERVAL N DAY

lock_option:
    ACCOUNT LOCK
  | ACCOUNT UNLOCK
}

```
 Description
-----------

 The `ALTER USER` statement modifies existing MariaDB accounts. To use it, you must have the global [CREATE USER](../grant/index#global-privileges) privilege or the [UPDATE](../grant/index#table-privileges) privilege for the [mysql](../the-mysql-database-tables/index) database. The global [SUPER](../grant/index#global-privileges) privilege is also required if the [read\_only](../server-system-variables/index#read_only) system variable is enabled.

 If any of the specified user accounts do not yet exist, an error results. If an error occurs, `ALTER USER` will still modify the accounts that do not result in an error. Only one error is produced for all users which have not been modified.

 For renaming an existing account (user name and/or host), see [RENAME USER](../rename-user/index).

 IF EXISTS
---------

 When the `IF EXISTS` clause is used, MariaDB will return a warning instead of an error for each specified user that does not exist.

 Account Names
-------------

 For `ALTER USER` statements, account names are specified as the `username` argument in the same way as they are for [CREATE USER](../create-user/index) statements. See [account names](../create-user/index#account-names) from the `CREATE USER` page for details on how account names are specified.

 [CURRENT\_USER](../current_user/index) or `CURRENT_USER()` can also be used to alter the account logged into the current session. For example, to change the current user's password to `mariadb`:

 
```
ALTER USER CURRENT_USER() IDENTIFIED BY 'mariadb';

```

Authentication Options
----------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**From [MariaDB 10.4](../what-is-mariadb-104/index), it is possible to use more than one authentication plugin for each user account. For example, this can be useful to slowly migrate users to the more secure ed25519 authentication plugin over time, while allowing the old mysql\_native\_password authentication plugin as an alternative for the transitional period. See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for more.

 When running `ALTER USER`, not specifying an authentication option in the IDENTIFIED VIA clause will remove that authentication method. (However this was not the case before [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), see [MDEV-21928](https://jira.mariadb.org/browse/MDEV-21928))

 For example, a user is created with the ability to authenticate via both a password and unix\_socket:

 
```
CREATE USER 'bob'@'localhost' 
  IDENTIFIED VIA mysql_native_password USING PASSWORD('pwd') 
  OR unix_socket;

SHOW CREATE USER 'bob'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for bob@localhost: CREATE USER `bob`@`localhost` 
  IDENTIFIED VIA mysql_native_password 
  USING '*975B2CD4FF9AE554FE8AD33168FBFC326D2021DD' 
  OR unix_socket

```

If the user's password is updated, but unix\_socket authentication is not specified in the `IDENTIFIED VIA` clause, unix\_socket authentication will no longer be permitted.

 
```
ALTER USER 'bob'@'localhost' IDENTIFIED VIA mysql_native_password 
  USING PASSWORD('pwd2');

SHOW CREATE USER 'bob'@'localhost'\G
*************************** 1. row ***************************
CREATE USER for bob@localhost: CREATE USER `bob`@`localhost` 
  IDENTIFIED BY PASSWORD '*38366FDA01695B6A5A9DD4E428D9FB8F7EB75512'

```


### IDENTIFIED BY 'password'

 The optional `IDENTIFIED BY` clause can be used to provide an account with a password. The password should be specified in plain text. It will be hashed by the [PASSWORD](../password/index) function prior to being stored to the [mysql.user](../mysqluser-table/index) table.

 For example, if our password is `mariadb`, then we can set the account's password with:

 
```
ALTER USER foo2@test IDENTIFIED BY 'mariadb';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 ### IDENTIFIED BY PASSWORD 'password\_hash'

 The optional `IDENTIFIED BY PASSWORD` clause can be used to provide an account with a password that has already been hashed. The password should be specified as a hash that was provided by the [PASSWORD](../password/index)#function. It will be stored to the [mysql.user](../mysqluser-table/index) table as-is.

 For example, if our password is `mariadb`, then we can find the hash with:

 
```
SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+

```

And then we can set an account's password with the hash:

 
```
ALTER USER foo2@test 
  IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 ### IDENTIFIED {VIA|WITH} authentication\_plugin

 The optional `IDENTIFIED VIA authentication_plugin` allows you to specify that the account should be authenticated by a specific [authentication plugin](../authentication-plugins/index). The plugin name must be an active authentication plugin as per [SHOW PLUGINS](../show-plugins/index). If it doesn't show up in that output, then you will need to install it with [INSTALL PLUGIN](../install-plugin/index) or [INSTALL SONAME](../install-soname/index).

 For example, this could be used with the [PAM authentication plugin](../authentication-plugin-pam/index):

 
```
ALTER USER foo2@test IDENTIFIED VIA pam;

```

Some authentication plugins allow additional arguments to be specified after a `USING` or `AS` keyword. For example, the [PAM authentication plugin](../authentication-plugin-pam/index) accepts a [service name](../authentication-plugin-pam/index#configuring-the-pam-service):

 
```
ALTER USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

```

The exact meaning of the additional argument would depend on the specific authentication plugin.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the `USING` or `AS` keyword can also be used to provide a plain-text password to a plugin if it's provided as an argument to the [PASSWORD()](../password/index) function. This is only valid for [authentication plugins](../authentication-plugins/index) that have implemented a hook for the [PASSWORD()](../password/index) function. For example, the [ed25519](../authentication-plugin-ed25519/index) authentication plugin supports this:

 
```
ALTER USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');

```

TLS Options
-----------

 By default, MariaDB transmits data between the server and clients without encrypting it. This is generally acceptable when the server and client run on the same host or in networks where security is guaranteed through other means. However, in cases where the server and client exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt data in transit between the server and clients using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix ssl\_, but internally, MariaDB only supports its secure successors.

 See [Secure Connections Overview](../secure-connections-overview/index) for more information about how to determine whether your MariaDB server has TLS support.

 You can set certain TLS-related restrictions for specific user accounts. For instance, you might use this with user accounts that require access to sensitive data while sending it across networks that you do not control. These restrictions can be enabled for a user account with the [CREATE USER](../create-user/index), [ALTER USER](index), or [GRANT](../grant/index) statements. The following options are available:

 


| Option | Description |
| --- | --- |
| `REQUIRE NONE` | TLS is not required for this account, but can still be used. |
| `REQUIRE SSL` | The account must use TLS, but no valid X509 certificate is required. This option cannot be combined with other TLS options. |
| `REQUIRE X509` | The account must use TLS and must have a valid X509 certificate. This option implies `REQUIRE SSL`. This option cannot be combined with other TLS options. |
| `REQUIRE ISSUER 'issuer'` | The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be the one specified via the string `issuer`. This option implies `REQUIRE X509`. This option can be combined with the `SUBJECT`, and `CIPHER` options in any order. |
| `REQUIRE SUBJECT 'subject'` | The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be the one specified via the string `subject`. This option implies `REQUIRE X509`. This option can be combined with the `ISSUER`, and `CIPHER` options in any order. |
| `REQUIRE CIPHER 'cipher'` | The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the connection must use a specific cipher method specified in the string `cipher`. This option implies `REQUIRE SSL`. This option can be combined with the `ISSUER`, and `SUBJECT` options in any order. |

 
The `REQUIRE` keyword must be used only once for all specified options, and the `AND` keyword can be used to separate individual options, but it is not required.

 For example, you can alter a user account to require these TLS options with the following:

 
```
ALTER USER 'alice'@'%'
 REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland' AND
 ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com'
 AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

```

If any of these options are set for a specific user account, then any client who tries to connect with that user account will have to be configured to connect with TLS.

 See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to enable TLS on the client and server.

 Resource Limit Options
----------------------

 It is possible to set per-account limits for certain server resources. The following table shows the values that can be set per account:

 


| Limit Type | Description |
| --- | --- |
| `MAX_QUERIES_PER_HOUR` | Number of statements that the account can issue per hour (including updates) |
| `MAX_UPDATES_PER_HOUR` | Number of updates (not queries) that the account can issue per hour |
| `MAX_CONNECTIONS_PER_HOUR` | Number of connections that the account can start per hour |
| `MAX_USER_CONNECTIONS` | Number of simultaneous connections that can be accepted from the same account; if it is 0, `max_connections` will be used instead; if `max_connections` is 0, there is no limit for this account's simultaneous connections. |
| `MAX_STATEMENT_TIME` | Timeout, in seconds, for statements executed by the user. See also [Aborting Statements that Exceed a Certain Time to Execute](../aborting-statements/index). |

 
If any of these limits are set to `0`, then there is no limit for that resource for that user.

 Here is an example showing how to set an account's resource limits:

 
```
ALTER USER 'someone'@'localhost' WITH
    MAX_USER_CONNECTIONS 10
    MAX_QUERIES_PER_HOUR 200;

```

The resources are tracked per account, which means `'user'@'server'`; not per user name or per connection.

 The count can be reset for all users using [FLUSH USER\_RESOURCES](../flush/index), [FLUSH PRIVILEGES](../flush/index) or [mysqladmin reload](../mysqladmin/index).

 Per account resource limits are stored in the [user](../mysqluser-table/index) table, in the [mysql](../the-mysql-database-tables/index) database. Columns used for resources limits are named `max_questions`, `max_updates`, `max_connections` (for `MAX_CONNECTIONS_PER_HOUR`), and `max_user_connections` (for `MAX_USER_CONNECTIONS`).

 Password Expiry
---------------

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Besides automatic password expiry, as determined by [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime), password expiry times can be set on an individual user basis, overriding the global setting, for example:

 
```
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE NEVER;
ALTER USER 'monty'@'localhost' PASSWORD EXPIRE DEFAULT;

```

See [User Password Expiry](../user-password-expiry/index) for more details.

 
Account Locking
---------------

 
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**Account locking permits privileged administrators to lock/unlock user accounts. No new client connections will be permitted if an account is locked (existing connections are not affected). For example:

 
```
ALTER USER 'marijn'@'localhost' ACCOUNT LOCK;

```

See [Account Locking](../account-locking/index) for more details.

 
From [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) and [MariaDB 10.5.8](https://mariadb.com/kb/en/mariadb-1058-release-notes/), the *lock\_option* and *password\_option* clauses can occur in either order.

 See Also
--------

 * [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [GRANT](../grant/index)
* [CREATE USER](../create-user/index)
* [DROP USER](../drop-user/index)
* [SET PASSWORD](../set-password/index)
* [SHOW CREATE USER](../show-create-user/index)
* [mysql.user table](../mysqluser-table/index)
* [Password Validation Plugins](../password-validation-plugins/index) - permits the setting of basic criteria for passwords
* [Authentication Plugins](../authentication-plugins/index) - allow various authentication methods to be used, and new ones to be developed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-user/>

TokuDB Status Variables
=======================

    
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

  This page documents status variables related to the [TokuDB storage engine](../tokudb/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `Tokudb_basement_deserialization_fixed_key`

 * **Description:** Number of deserialized basement nodes where all keys were the same size. This leaves the basement in an optimal format for in-memory workloads.

 

---

 #### `Tokudb_basement_deserialization_variable_key`

 * **Description:** Number of deserialized basement nodes where all keys had different size keys, which are not eligible for in-memory optimization.

 

---

 #### `Tokudb_basements_decompressed_for_write`

 * **Description:** Number of basement nodes decompressed for write operations.

 

---

 #### `Tokudb_basements_decompressed_prefetch`

 * **Description:** Number of basement nodes decompressed by a prefetch thread. See [tokudb\_disable\_prefetching](../tokudb-system-variables/index#tokudb_disable_prefetching).

 

---

 #### `Tokudb_basements_decompressed_prelocked_range`

 * **Description:** Number of basement nodes aggressively decompressed by queries.

 

---

 #### `Tokudb_basements_decompressed_target_query`

 * **Description:** Number of basement nodes decompressed for queries

 

---

 #### `Tokudb_basements_fetched_for_write`

 * **Description:** Number of basement nodes fetched for writes off the disk.

 

---

 #### `Tokudb_basements_fetched_for_write_bytes`

 * **Description:** Total basement node bytes fetched for writes off the disk.

 

---

 #### `Tokudb_basements_fetched_for_write_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching basement nodes from disk for writes.

 

---

 #### `Tokudb_basements_fetched_prefetch`

 * **Description:** Number of basement nodes fetched off the disk by a prefetch thread.

 

---

 #### `Tokudb_basements_fetched_prefetch_bytes`

 * **Description:** Total basement node bytes fetched off the disk by a prefetch thread..

 

---

 #### `Tokudb_basements_fetched_prefetch_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching off the disk by a prefetch thread.

 

---

 #### `Tokudb_basements_fetched_prelocked_range`

 * **Description:** Number of basement nodes aggressively fetched from disk.

 

---

 #### `Tokudb_basements_fetched_prelocked_range_bytes`

 * **Description:** Total basement node bytes aggressively fetched off the disk.

 

---

 #### `Tokudb_basements_fetched_prelocked_range_seconds`

 * **Description:** Time in seconds spent waiting for IO while aggressively fetching basement nodes from disk.

 

---

 #### `Tokudb_basements_fetched_target_query`

 * **Description:** Number of basement nodes fetched for queries off the disk.

 

---

 #### `Tokudb_basements_fetched_target_query_bytes`

 * **Description:** Total basement node bytes fetched for queries off the disk.

 

---

 #### `Tokudb_basements_fetched_target_query_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching basement nodes from disk for queries.

 

---

 #### `Tokudb_broadcase_messages_injected_at_root`

 * **Description:** Number of broadcast messages injected at root.

 

---

 #### `Tokudb_buffers_decompressed_for_write`

 * **Description:** Number of buffers decompressed for writes.

 

---

 #### `Tokudb_buffers_decompressed_prefetch`

 * **Description:** Number of buffers decompressed by a prefetch thread.

 

---

 #### `Tokudb_buffers_decompressed_prelocked_range`

 * **Description:** Number of buffers decompressed for queries.

 

---

 #### `Tokudb_buffers_decompressed_target_query`

 * **Description:** Number of buffers aggressively decompressed by queries.

 

---

 #### `Tokudb_buffers_fetched_for_write`

 * **Description:** Number of buffers fetched for write off the disk.

 

---

 #### `Tokudb_buffers_fetched_for_write_bytes`

 * **Description:** Total buffer bytes fetched for writes off the disk.

 

---

 #### `Tokudb_buffers_fetched_for_write_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching buffers from disk for writes.

 

---

 #### `Tokudb_buffers_fetched_prefetch`

 * **Description:** Number of buffers fetched for queries off the disk by a prefetch thread.

 

---

 #### `Tokudb_buffers_fetched_prefetch_bytes`

 * **Description:** Total buffer bytes fetched for queries off the disk by a prefetch thread.

 

---

 #### `Tokudb_buffers_fetched_prefetch_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching buffers from disk for queries by a prefetch thread.

 

---

 #### `Tokudb_buffers_fetched_prelocked_range`

 * **Description:** Number of buffers aggressively fetched for queries off the disk.

 

---

 #### `Tokudb_buffers_fetched_prelocked_range_bytes`

 * **Description:** Total buffer bytes aggressively fetched for queries off the disk.

 

---

 #### `Tokudb_buffers_fetched_prelocked_range_seconds`

 * **Description:** Time in seconds spent waiting for IO while aggressively fetching buffers from disk for queries.

 

---

 #### `Tokudb_buffers_fetched_target_query`

 * **Description:** Number of buffers fetched for queries off the disk.

 

---

 #### `Tokudb_buffers_fetched_target_query_bytes`

 * **Description:** Total buffer bytes fetched for queries off the disk.

 

---

 #### `Tokudb_buffers_fetched_target_query_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching buffers from disk for queries.

 

---

 #### `Tokudb_cachetable_cleaner_executions`

 * **Description:** Number of times the cleaner thread loop has executed.

 

---

 #### `Tokudb_cachetable_cleaner_iterations`

 * **Description:** Number of cleaner operations performed each cleaner period.

 

---

 #### `Tokudb_cachetable_cleaner_period`

 * **Description:** Time in seconds between the end of a group of cleaner operations and the beginning of the next. The TokuDB cleaner thread runs in the background, optimizing indexes and performing work not needing to be done by the client thread.

 

---

 #### `Tokudb_cachetable_evictions`

 * **Description:** Number of blocks evicted from the cache.

 

---

 #### `Tokudb_cachetable_long_wait_pressure_count`

 * **Description:** Number of times a thread was stalled for more than one second due to cache pressure.

 

---

 #### `Tokudb_cachetable_long_wait_pressure_time`

 * **Description:** Time in microseconds spent waiting for more than one second for cache pressure to ease.

 

---

 #### `Tokudb_cachetable_miss`

 * **Description:** Number of times the system failed to access data in the internal cache.

 

---

 #### `Tokudb_cachetable_miss_time`

 * **Description:** Total time in microseconds spent waiting for disk reads (when the cache could not supply the data) to finish.

 

---

 #### `Tokudb_cachetable_prefetches`

 * **Description:** Total number of times that a block of memory was prefetched into the database cache. This happens when it's determined that a block of memory is likely to be accessed by the application.

 

---

 #### `Tokudb_cachetable_size_cachepressure`

 * **Description:** Size in bytes of data causing cache pressure, or the sum of the buffers and workdone counters.

 

---

 #### `Tokudb_cachetable_size_cloned`

 * **Description:** Memory in bytes currently used for cloned nodes. Dirty nodes are cloned before serialization/compression during checkpoint operations, after which they are written to disk and the memory freed for re-use.

 

---

 #### `Tokudb_cachetable_size_current`

 * **Description:** Size in bytes of the uncompressed data in the cache.

 

---

 #### `Tokudb_cachetable_size_leaf`

 * **Description:** Size in bytes of the leaf nodes in the cache.

 

---

 #### `Tokudb_cachetable_size_limit`

 * **Description:** Size in bytes of the uncompressed data that could fit in the cache.

 

---

 #### `Tokudb_cachetable_size_nonleaf`

 * **Description:** Size in bytes of the nonleaf nodes in the cache.

 

---

 #### `Tokudb_cachetable_size_rollback`

 * **Description:** Size in bytes of the rollback nodes in the cache.

 

---

 #### `Tokudb_cachetable_size_writing`

 * **Description:** Size in bytes currently queued to be written to disk.

 

---

 #### `Tokudb_cachetable_wait_pressure_count`

 * **Description:** Number of times a thread was stalled due to cache pressure.

 

---

 #### `Tokudb_cachetable_wait_pressure_time`

 * **Description:** Time in microseconds spent waiting for cache pressure to ease.

 

---

 #### `Tokudb_checkpoint_begin_time`

 * **Description:** Cumulative time in microseconds needed to mark all dirty nodes as pending a checkpoint.

 

---

 #### `Tokudb_checkpoint_duration`

 * **Description:** Time in seconds needed to complete all checkpoints.

 

---

 #### `Tokudb_checkpoint_duration_last`

 * **Description:** Time in seconds needed to complete the last checkpoint.

 

---

 #### `Tokudb_checkpoint_failed`

 * **Description:** Total number of checkpoints failed.

 

---

 #### `Tokudb_checkpoint_last_began`

 * **Description:** Date and time the most recent checkpoint began, for example `Wed May 14 11:26:42 2014` Will be `Dec 31, 1969` on Linux if no checkpoint has ever begun.

 

---

 #### `Tokudb_checkpoint_last_complete_began`

 * **Description:** Date and time the last complete checkpoint started.

 

---

 #### `Tokudb_checkpoint_last_complete_ended`

 * **Description:** Date and time the last complete checkpoint ended.

 

---

 #### `Tokudb_checkpoint_long_begin_count`

 * **Description:** Number of long checkpoint begins (checkpoint begins taking more than 1 second).

 

---

 #### `Tokudb_checkpoint_long_begin_time`

 * **Description:** Total time in microseconds of long checkpoint begins (checkpoint begins taking more than 1 second).

 

---

 #### `Tokudb_checkpoint_period`

 * **Description:** Time in seconds between the end of one automatic checkpoint and the beginning of the next.

 

---

 #### `Tokudb_checkpoint_taken`

 * **Description:** Total number of checkpoints taken.

 

---

 #### `Tokudb_cursor_skip_deleted_leaf_entry`

 * **Description:** Deleted leaf entries skipped during a range scan.
* **Introduced:** TokuDB 7.5.4

 

---

 #### `Tokudb_db_closes`

 * **Description:** Number of db\_close operations.

 

---

 #### `Tokudb_db_open_current`

 * **Description:** Number of databases currently open.

 

---

 #### `Tokudb_db_open_max`

 * **Description:** Maximum of number of databases open at the same time.

 

---

 #### `Tokudb_db_opens`

 * **Description:** Number of db\_open operations.

 

---

 #### `Tokudb_descriptor_set`

 * **Description:** Number of times a descriptor was updated when the entire dictionary was updated.

 

---

 #### `Tokudb_dictionary_broadcast_updates`

 * **Description:** Number of successful broadcast updates (an update that affects all rows in a dictionary).

 

---

 #### `Tokudb_dictionary_updates`

 * **Description:** Total number of rows updated in all primary and secondary indexes that have been done with a separate recovery log entry per index.

 

---

 #### `Tokudb_filesystem_fsync_num`

 * **Description:** Total number of times the database has flushed the operating system’s file buffers to disk.

 

---

 #### `Tokudb_filesystem_fsync_time`

 * **Description:** Total time in microseconds used to fsync to disk.

 

---

 #### `Tokudb_filesystem_long_fsync_num`

 * **Description:** Total number of times the database has flushed the operating system’s file buffers to disk when the operation took more than one second.

 

---

 #### `Tokudb_filesystem_long_fsync_time`

 * **Description:** Total time in microseconds used to fsync to disk when the operation took more than one second.

 

---

 #### `Tokudb_filesystem_threads_blocked_by_full_disk`

 * **Description:** Number of threads currently blocked due to attempting to write to a full disk. A warning appears in the `disk free space` field if not zero.

 

---

 #### `Tokudb_leaf_compression_to_memory_seconds`

 * **Description:** Time in seconds spent on compressing leaf nodes.

 

---

 #### `Tokudb_leaf_decompression_to_memory_seconds`

 * **Description:** Time in seconds spent on decompressing leaf nodes.

 

---

 #### `Tokudb_leaf_deserialization_to_memory_seconds`

 * **Description:** Time in seconds spent on deserializing leaf nodes.

 

---

 #### `Tokudb_leaf_node_compression_ratio`

 * **Description:** Ratio of uncompressed bytes in-memory to compressed bytes on-disk for leaf nodes.

 

---

 #### `Tokudb_leaf_node_full_evictions`

 * **Description:** Number of times a full leaf node was evicted from the cache.

 

---

 #### `Tokudb_leaf_node_full_evictions_bytes`

 * **Description:** Total bytes freed when a full leaf node was evicted from the cache.

 

---

 #### `Tokudb_leaf_node_partial_evictions`

 * **Description:** Number of times part of a leaf node (a partition) was evicted from the cache.

 

---

 #### `Tokudb_leaf_node_partial_evictions_bytes`

 * **Description:** Total bytes freed when part of a leaf node (a partition) was evicted from the cache.

 

---

 #### `Tokudb_leaf_nodes_created`

 * **Description:** Total number of leaf nodes created.

 

---

 #### `Tokudb_leaf_nodes_destroyed`

 * **Description:** Total number of leaf nodes destroyed.

 

---

 #### `Tokudb_leaf_nodes_flushed_checkpoint`

 * **Description:** Number of leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_checkpoint_bytes`

 * **Description:** Size in bytes of leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_checkpoint_seconds`

 * **Description:** Time in seconds spent waiting for IO while writing leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_checkpoint_uncompressed_bytes`

 * **Description:** Size in uncompressed bytes of leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_not_checkpoint`

 * **Description:** Number of leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_not_checkpoint_bytes`

 * **Description:** Size in bytes of leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_not_checkpoint_seconds`

 * **Description:** Time in seconds spent waiting for IO while writing leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_leaf_nodes_flushed_not_checkpoint_uncompressed_bytes`

 * **Description:** Size in uncompressed bytes of leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_leaf_serialization_to_memory_seconds`

 * **Description:** Time in seconds spent on serializing leaf nodes.

 

---

 #### `Tokudb_loader_num_created`

 * **Description:** Number of times a loader has been created.

 

---

 #### `Tokudb_loader_num_current`

 * **Description:** Number of currently existing loaders.

 

---

 #### `Tokudb_loader_num_max`

 * **Description:** Maximum number of loaders that existed at one time.

 

---

 #### `Tokudb_locktree_escalation_num`

 * **Description:** Number of times the locktree needed reduce its memory footprint by running lock escalation.

 

---

 #### `Tokudb_locktree_escalation_seconds`

 * **Description:** Time in seconds spent performing locktree escalation.

 

---

 #### `Tokudb_locktree_latest_post_escalation_memory_size`

 * **Description:** Memory size in bytes of the locktree after most recent locktree escalation.

 

---

 #### `Tokudb_locktree_long_wait_count`

 * **Description:** Number of times of more than one second duration that a lock could not be acquired as a result of a conflict with another transaction.

 

---

 #### `Tokudb_locktree_long_wait_escalation_count`

 * **Description:** Number of times a client thread waited for more than one second for lock escalation to free up memory.

 

---

 #### `Tokudb_locktree_long_wait_escalation_time`

 * **Description:** Time in microseconds of long waits (more than one second) for lock escalation to free up memory.

 

---

 #### `Tokudb_locktree_long_wait_time`

 * **Description:**Total time in microseconds spent by clients waiting for more than one second for a lock conflict to be resolved.

 

---

 #### `Tokudb_locktree_memory_size`

 * **Description:** Memory in bytes currently being used by the locktree.

 

---

 #### `Tokudb_locktree_memory_size_limit`

 * **Description:** Maximum memory in bytes the locktree can use.

 

---

 #### `Tokudb_locktree_open_current`

 * **Description:** Number of currently open locktrees.

 

---

 #### `Tokudb_locktree_pending_lock_requests`

 * **Description:** Number of requests waiting for a lock to be granted.

 

---

 #### `Tokudb_locktree_sto_eligible_num`

 * **Description:** Number of locktrees eligible for single transaction optimizations.

 

---

 #### `Tokudb_locktree_sto_ended_num`

 * **Description:** Total number of times a single transaction optimization completed early as a result of another transaction beginning.

 

---

 #### `Tokudb_locktree_sto_ended_seconds`

 * **Description:** Time in seconds spent ending single transaction optimizations.

 

---

 #### `Tokudb_locktree_timeout_count`

 * **Description:** Number of times a lock request timed out.

 

---

 #### `Tokudb_locktree_wait_count`

 * **Description:** Number of times a lock could not be acquired as a result of a conflict with another transaction.

 

---

 #### `Tokudb_locktree_wait_escalation_count`

 * **Description:** Number of times a client thread has waited on lock escalation. Lock escalation is run on a background thread when the sum of the acquired lock sizes reaches the lock tree limit.

 

---

 #### `Tokudb_locktree_wait_escalation_time`

 * **Description:** Time in microseconds that a client thread spent waiting for lock escalation.

 

---

 #### `Tokudb_locktree_wait_time`

 * **Description:** Total time in microseconds spent by clients waiting for a lock conflict to be resolved.

 

---

 #### `Tokudb_logger_wait_long`

 * **Description:**

 

---

 #### `Tokudb_logger_writes`

 * **Description:** Number of times the logger has written to disk.

 

---

 #### `Tokudb_logger_writes_bytes`

 * **Description:** Total bytes the logger has written to disk.

 

---

 #### `Tokudb_logger_writes_seconds`

 * **Description:** Time in seconds spent waiting for IO while writing logs to disk.

 

---

 #### `Tokudb_logger_writes_uncompressed_bytes`

 * **Description:** Total uncompressed bytes the logger has written to disk.

 

---

 #### `Tokudb_mem_estimated_maximum_memory_footprint`

 * **Description:**

 

---

 #### `Tokudb_messages_flushed_from_h1_to_leaves_bytes`

 * **Description:** Total bytes of the messages flushed from h1 nodes to leaves.

 

---

 #### `Tokudb_messages_ignored_by_leaf_due_to_msn`

 * **Description:** Number of messages ignored by a leaf because it had already been applied.

 

---

 #### `Tokudb_messages_in_trees_estimate_bytes`

 * **Description:** Estimate of the total bytes of messages currently in trees.

 

---

 #### `Tokudb_messages_injected_at_root`

 * **Description:** Number of messages injected at root.

 

---

 #### `Tokudb_messages_injected_at_root_bytes`

 * **Description:** Total bytes of messages injected at root for all trees.

 

---

 #### `Tokudb_nonleaf_compression_to_memory_seconds`

 * **Description:** Time in seconds spent on compressing non-leaf nodes.

 

---

 #### `Tokudb_nonleaf_decompression_to_memory_seconds`

 * **Description:** Time in seconds spent on decompressing non-leaf nodes.

 

---

 #### `Tokudb_nonleaf_deserialization_to_memory_seconds`

 * **Description:** Time in seconds spent on deserializing non-leaf nodes.

 

---

 #### `Tokudb_nonleaf_node_compression_ratio`

 * **Description:** Ratio of uncompressed bytes in-memory to compressed bytes on-disk for nonleaf nodes.

 

---

 #### `Tokudb_nonleaf_node_full_evictions`

 * **Description:** Number of times a full non-leaf node was evicted from the cache.

 

---

 #### `Tokudb_nonleaf_node_full_evictions_bytes`

 * **Description:** Total bytes freed when a full non-leaf node was evicted from the cache.

 

---

 #### `Tokudb_nonleaf_node_partial_evictions`

 * **Description:** Number of times part of a non-leaf node (a partition) was evicted from the cache.

 

---

 #### `Tokudb_nonleaf_node_partial_evictions_bytes`

 * **Description:** Total bytes freed when part of a non-leaf node (a partition) was evicted from the cache.

 

---

 #### `Tokudb_nonleaf_nodes_created`

 * **Description:** Total number of non-leaf nodes created.

 

---

 #### `Tokudb_nonleaf_nodes_destroyed`

 * **Description:** Total number of non-leaf nodes destroyed.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_checkpoint`

 * **Description:** Number of non-leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_bytes`

 * **Description:** Size in bytes of non-leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_seconds`

 * **Description:** Time in seconds spent waiting for IO while writing non-leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_checkpoint_uncompressed_bytes`

 * **Description:** Size in uncompressed bytes of non-leaf nodes flushed to disk as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint`

 * **Description:** Number of non-leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_bytes`

 * **Description:** Size in bytes of non-leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_seconds`

 * **Description:** Time in seconds spent waiting for IO while writing non-leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_nodes_flushed_to_disk_not_checkpoint_uncompressed_bytes`

 * **Description:** Size in uncompressed bytes of non-leaf nodes flushed to disk not as part of a checkpoint.

 

---

 #### `Tokudb_nonleaf_serialization_to_memory_seconds`

 * **Description:** Time in seconds spent on serializing nonleaf nodes.

 

---

 #### `Tokudb_overall_node_compression_ratio`

 * **Description:** Ratio of uncompressed bytes in-memory to compressed bytes on-disk for all nodes.

 

---

 #### `Tokudb_pivots_fetched_for_query`

 * **Description:** Total number of pivot nodes fetched for queries.

 

---

 #### `Tokudb_pivots_fetched_for_query_bytes`

 * **Description:** Number of bytes of pivot nodes fetched for queries.

 

---

 #### `Tokudb_pivots_fetched_for_query_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching pivot nodes for queries.

 

---

 #### `Tokudb_pivots_fetched_for_prefetch`

 * **Description:** Total number of pivot nodes fetched by a prefetch thread.

 

---

 #### `Tokudb_pivots_fetched_for_prefetch_bytes`

 * **Description:** Number of bytes of pivot nodes fetched by a prefetch thread.

 

---

 #### `Tokudb_pivots_fetched_for_prefetch_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching pivot nodes by a prefetch thread.

 

---

 #### `Tokudb_pivots_fetched_for_write`

 * **Description:** Total number of pivot nodes fetched for writes.

 

---

 #### `Tokudb_pivots_fetched_for_write_bytes`

 * **Description:** Number of bytes of pivot nodes fetched for writes.

 

---

 #### `Tokudb_pivots_fetched_for_write_seconds`

 * **Description:** Time in seconds spent waiting for IO while fetching pivot nodes for writes.

 

---

 #### `Tokudb_promotion_h1_roots_injected_into`

 * **Description:** Number of times a message stopped at a root with a height of 1.

 

---

 #### `Tokudb_promotion_injections_at_depth_0`

 * **Description:** Number of times a message stopped at a depth of zero.

 

---

 #### `Tokudb_promotion_injections_at_depth_1`

 * **Description:** Number of times a message stopped at a depth of one.

 

---

 #### `Tokudb_promotion_injections_at_depth_2`

 * **Description:** Number of times a message stopped at a depth of two.

 

---

 #### `Tokudb_promotion_injections_at_depth_3`

 * **Description:** Number of times a message stopped at a depth of three.

 

---

 #### `Tokudb_promotion_injections_lower_than_depth_3`

 * **Description:** Number of times a message stopped at a depth of greater than three.

 

---

 #### `Tokudb_promotion_leaf_roots_injected_into`

 * **Description:** Number of times a message stopped at a root with a height of 0.

 

---

 #### `Tokudb_promotion_roots_split`

 * **Description:** Number of times the root split during promotion.

 

---

 #### `Tokudb_promotion_stopped_after_locking_child`

 * **Description:** Number of times a message stopped before a locked child.

 

---

 #### `Tokudb_promotion_stopped_at_height_1`

 * **Description:** Number of times a message stopped due to reaching a height of one.

 

---

 #### `Tokudb_promotion_stopped_child_locked_or_not_in_memory`

 * **Description:** Number of times a message stopped due to being unable to cheaply access (locked or not stored in memory) a child.

 

---

 #### `Tokudb_promotion_stopped_child_not_fully_in_memory`

 * **Description:** Number of times a message stopped due to being unable to cheaply access (not fully stored in memory) a child.

 

---

 #### `Tokudb_promotion_stopped_nonempty_buffer`

 * **Description:** Number of times a message stopped due to reaching a buffer that wasn't empty.

 

---

 #### `Tokudb_txn_aborts`

 * **Description:** Number of transactions that have been aborted.

 

---

 #### `Tokudb_txn_begin`

 * **Description:** Number of transactions that have been started.

 

---

 #### `Tokudb_txn_begin_read_only`

 * **Description:** Number of read-only transactions that have been started.

 

---

 #### `Tokudb_txn_commits`

 * **Description:** Number of transactions that have been committed.

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tokudb-status-variables/>

S3 Storage Engine Status Variables
==================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

  This page documents status variables related to the [S3 storage engine](../s3-storage-engine/index). See [Server Status Variables](../server-status-variables/index) for a complete list of status variables that can be viewed with [SHOW STATUS](../show-status/index).

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `S3_pagecache_blocks_not_flushed`

 * **Description:**
* **Scope:**
* **Data Type:**
* **Introduced:** [MariaDB 10.5](../what-is-mariadb-105/index)

 

---

 #### `S3_pagecache_blocks_unused`

 * **Description:**
* **Scope:**
* **Data Type:**
* **Introduced:** [MariaDB 10.5](../what-is-mariadb-105/index)

 

---

 #### `S3_pagecache_blocks_used`

 * **Description:**
* **Scope:**
* **Data Type:**
* **Introduced:** [MariaDB 10.5](../what-is-mariadb-105/index)

 

---

 #### `S3_pagecache_reads`

 * **Description:**
* **Scope:**
* **Data Type:**
* **Introduced:** [MariaDB 10.5](../what-is-mariadb-105/index)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/s3-storage-engine-status-variables/>

CALL
====

    Syntax
------

 
```
CALL sp_name([parameter[,...]])
CALL sp_name[()]

```

Description
-----------

 The `CALL` statement invokes a [stored procedure](../stored-procedures/index) that was defined previously with [CREATE PROCEDURE](../create-procedure/index). 

 Stored procedure names can be specified as `database_name.procedure_name`. Procedure names and database names can be quoted with backticks (). This is necessary if they are reserved words, or contain special characters. See [identifier qualifiers](../identifier-qualifiers/index) for details.

 `CALL p()` and `CALL p` are equivalent.

 If parentheses are used, any number of spaces, tab characters and newline characters are allowed between the procedure's name and the open parenthesis.

 `CALL` can pass back values to its caller using parameters that are declared as `OUT` or `INOUT` parameters. If no value is assigned to an `OUT` parameter, `NULL` is assigned (and its former value is lost). To pass such values from another stored program you can use [user-defined variables](../user-defined-variables/index), [local variables](../declare-variable/index) or routine's parameters; in other contexts, you can only use user-defined variables. 

 `CALL` can also be executed as a prepared statement. Placeholders can be used for `IN` parameters in all versions of MariaDB; for `OUT` and `INOUT` parameters, placeholders can be used since [MariaDB 5.5](../what-is-mariadb-55/index).

 When the procedure returns, a client program can also obtain the number of rows affected for the final statement executed within the routine: At the SQL level, call the `[ROW\_COUNT()](../row_count/index)` function; from the C API, call the `mysql_affected_rows()` function.

 If the `CLIENT_MULTI_RESULTS` API flag is set, `CALL` can return any number of resultsets and the called stored procedure can execute prepared statements. If it is not set, at most one resultset can be returned and prepared statements cannot be used within procedures.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/call/>

BINLOG
======

    Syntax
------

 
```
BINLOG 'str'

```

Description
-----------

 `BINLOG` is an internal-use statement. It is generated by the [mariadb-binlog](../mariadb-binlog/index) program as the printable representation of certain events in [binary log](../binary-log/index) files. The `'str'` value is a base 64-encoded string that the server decodes to determine the data change indicated by the corresponding event. This statement requires the [SUPER](../grant/index#super) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) or the [BINLOG REPLAY](../grant/index#binlog-replay) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)).

 See Also
--------

 * [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binlog/>

User Statistics
===============

    The User Statistics feature was first released in [MariaDB 5.2.0](https://mariadb.com/kb/en/mariadb-520-release-notes/), and moved to the `userstat` plugin in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/).

 The `userstat` plugin creates the [USER\_STATISTICS](../information-schema-user_statistics-table/index), [CLIENT\_STATISTICS](../information-schema-client_statistics-table/index), the [INDEX\_STATISTICS](../information-schema-index_statistics-table/index), and the [TABLE\_STATISTICS](../information-schema-table_statistics-table/index) tables in the [INFORMATION\_SCHEMA](../information-schema/index) database. As an alternative to these tables, the plugin also adds the [SHOW USER\_STATISTICS](../show-user-statistics/index), the [SHOW CLIENT\_STATISTICS](../show-client-statistics/index), the [SHOW INDEX\_STATISTICS](../show-index-statistics/index), and the [SHOW TABLE\_STATISTICS](../show-table-statistics/index) statements.

 These tables and commands can be used to understand the server activity better and to identify the sources of your database's load.

 The plugin also adds the [FLUSH USER\_STATISTICS](../flush/index), [FLUSH CLIENT\_STATISTICS](../flush/index), [FLUSH INDEX\_STATISTICS](../flush/index), and [FLUSH TABLE\_STATISTICS](../flush/index) statements.

 The MariaDB implementation of this plugin is based on the [userstatv2 patch](http://www.percona.com/docs/wiki/patches:userstatv2) from Percona and Ourdelta. The original code comes from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta, and Weldon Whipple. The MariaDB implementation provides the same functionality as the userstatv2 patch but a lot of changes have been made to make it faster and to better fit the MariaDB infrastructure.

 How it Works
------------

 The `userstat` plugin works by keeping several hash tables in memory. All variables are incremented while the query is running. At the end of each statement the global values are updated.

 Enabling the Plugin
-------------------

 By default statistics are not collected. This is to ensure that statistics collection does not cause any extra load on the server unless desired.

 Set the [userstat=ON](#userstat) system variable in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) to enable the plugin. For example:

 
```
[mariadb]
...
userstat = 1

```

The value can also be changed dynamically. For example:

 
```
SET GLOBAL userstat=1;

```

Using the Plugin
----------------

 ### Using the Information Schema Table

 The `userstat` plugin creates the [USER\_STATISTICS](../information-schema-user_statistics-table/index), [CLIENT\_STATISTICS](../information-schema-client_statistics-table/index), the [INDEX\_STATISTICS](../information-schema-index_statistics-table/index), and the [TABLE\_STATISTICS](../information-schema-table_statistics-table/index) tables in the [INFORMATION\_SCHEMA](../information-schema/index) database. 

 
```
SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS\G
*************************** 1. row ***************************
                  USER: root
     TOTAL_CONNECTIONS: 1
CONCURRENT_CONNECTIONS: 0
        CONNECTED_TIME: 297
             BUSY_TIME: 0.001725
              CPU_TIME: 0.001982
        BYTES_RECEIVED: 388
            BYTES_SENT: 2327
  BINLOG_BYTES_WRITTEN: 0
             ROWS_READ: 0
             ROWS_SENT: 12
          ROWS_DELETED: 0
         ROWS_INSERTED: 13
          ROWS_UPDATED: 0
       SELECT_COMMANDS: 4
       UPDATE_COMMANDS: 0
        OTHER_COMMANDS: 3
   COMMIT_TRANSACTIONS: 0
 ROLLBACK_TRANSACTIONS: 0
    DENIED_CONNECTIONS: 0
      LOST_CONNECTIONS: 0
         ACCESS_DENIED: 0
         EMPTY_QUERIES: 1

```


```
SELECT * FROM INFORMATION_SCHEMA.CLIENT_STATISTICS\G
*************************** 1. row ***************************
                CLIENT: localhost
     TOTAL_CONNECTIONS: 3
CONCURRENT_CONNECTIONS: 0
        CONNECTED_TIME: 4883
             BUSY_TIME: 0.009722
              CPU_TIME: 0.0102131
        BYTES_RECEIVED: 841
            BYTES_SENT: 13897
  BINLOG_BYTES_WRITTEN: 0
             ROWS_READ: 0
             ROWS_SENT: 214
          ROWS_DELETED: 0
         ROWS_INSERTED: 207
          ROWS_UPDATED: 0
       SELECT_COMMANDS: 10
       UPDATE_COMMANDS: 0
        OTHER_COMMANDS: 13
   COMMIT_TRANSACTIONS: 0
 ROLLBACK_TRANSACTIONS: 0
    DENIED_CONNECTIONS: 0
      LOST_CONNECTIONS: 0
         ACCESS_DENIED: 0
         EMPTY_QUERIES: 1
1 row in set (0.00 sec)

```


```
SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME = "author";
+--------------+------------+------------+-----------+
| TABLE_SCHEMA | TABLE_NAME | INDEX_NAME | ROWS_READ |
+--------------+------------+------------+-----------+
| books        | author     | by_name    |        15 |
+--------------+------------+------------+-----------+

```


```
SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='user';
+--------------+------------+-----------+--------------+------------------------+
| TABLE_SCHEMA | TABLE_NAME | ROWS_READ | ROWS_CHANGED | ROWS_CHANGED_X_INDEXES |
+--------------+------------+-----------+--------------+------------------------+
| mysql        | user       |         5 |            2 |                      2 |
+--------------+------------+-----------+--------------+------------------------+

```

### Using the SHOW Statements

 As an alternative to the [INFORMATION\_SCHEMA](../information_schema/index) tables, the `userstat` plugin also adds the [SHOW USER\_STATISTICS](../show-user-statistics/index), the [SHOW CLIENT\_STATISTICS](../show-client-statistics/index), the [SHOW INDEX\_STATISTICS](../show-index-statistics/index), and the [SHOW TABLE\_STATISTICS](../show-table-statistics/index) statements.

 These commands are another way to display the information stored in the information schema tables. WHERE clauses are accepted. LIKE clauses are accepted but ignored.

 
```
SHOW USER_STATISTICS
SHOW CLIENT_STATISTICS
SHOW INDEX_STATISTICS
SHOW TABLE_STATISTICS

```

### Flushing Plugin Data

 The `userstat` plugin also adds the [FLUSH USER\_STATISTICS](../flush/index), [FLUSH CLIENT\_STATISTICS](../flush/index), [FLUSH INDEX\_STATISTICS](../flush/index), and [FLUSH TABLE\_STATISTICS](../flush/index) statements, which discard the information stored in the specified information schema table.

 
```
FLUSH USER_STATISTICS
FLUSH CLIENT_STATISTICS
FLUSH INDEX_STATISTICS
FLUSH TABLE_STATISTICS

```

Versions
--------

 ### USER\_STATISTICS

 


| Version | Status | Introduced |
| --- | --- | --- |
| 2.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 2.0 | Gamma | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |

 
### CLIENT\_STATISTICS

 


| Version | Status | Introduced |
| --- | --- | --- |
| 2.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 2.0 | Gamma | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |

 
### INDEX\_STATISTICS

 


| Version | Status | Introduced |
| --- | --- | --- |
| 2.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 2.0 | Gamma | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |

 
### TABLE\_STATISTICS

 


| Version | Status | Introduced |
| --- | --- | --- |
| 2.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 2.0 | Gamma | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |

 
System Variables
----------------

 ### `userstat`

 * **Description:** If set to `1`, [user statistics](index) will be activated.
* **Commandline:** `--userstat=1`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-statistics/>

BACKUP TABLE (removed)
======================

    
**MariaDB until [5.3](../what-is-mariadb-53/index)**BACKUP TABLE was removed in [MariaDB 5.5](../what-is-mariadb-55/index).

 
Syntax
------

 
```
BACKUP TABLE tbl_name [, tbl_name] ... TO '/path/to/backup/directory'

```

Description
-----------

 
**Note:** Like [RESTORE TABLE](../restore-table/index), this command was not reliable and has been removed in current versions of MariaDB.

 
For doing a backup of MariaDB use [mysqldump](../mysqldump/index) or [MariaDB Backup](../mariadb-backup/index). See [Backing Up and Restoring](../backing-up-and-restoring/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-table-deprecated/>

CHECK TABLE
===========

    Syntax
------

 
```
CHECK TABLE tbl_name [, tbl_name] ... [option] ...

option = {FOR UPGRADE | QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

```

Description
-----------

 `CHECK TABLE` checks a table or tables for errors. `CHECK TABLE` works for [Archive](../archive/index), [Aria](../aria/index), [CSV](../csv/index), [InnoDB](../innodb/index) and [MyISAM](../myisam/index) tables. For Aria and MyISAM tables, the key statistics are updated as well. For CSV, see also [Checking and Repairing CSV Tables](../checking-and-repairing-csv-tables/index).

 As an alternative, [myisamchk](../myisamchk/index) is a commandline tool for checking MyISAM tables when the tables are not being accessed. For Aria tables, there is a similar tool: [aria\_chk](../aria_chk/index).

 For checking [dynamic columns](../dynamic-columns/index) integrity, [COLUMN\_CHECK()](../dynamic-columns-in-mariadb-10/index#column_check) can be used.

 `CHECK TABLE` can also check views for problems, such as tables that are referenced in the view definition that no longer exist.

 `CHECK TABLE` is also supported for partitioned tables. You can use `[ALTER TABLE](../alter-table/index) ... CHECK PARTITION` to check one or more partitions.

 The meaning of the different options are as follows - note that this can vary a bit between storage engines:

 


|  |  |
| --- | --- |
| FOR UPGRADE | Do a very quick check if the storage format for the table has changed so that one needs to do a REPAIR. This is only needed when one upgrades between major versions of MariaDB or MySQL. This is usually done by [running mariadb-upgrade](../upgrading-to-mariadb-from-mysql/index). |
| FAST | Only check tables that has not been closed properly or are marked as corrupt. Only supported by the MyISAM and Aria engines. For other engines the table is checked normally |
| CHANGED | Check only tables that has changed since last REPAIR / CHECK. Only supported by the MyISAM and Aria engines. For other engines the table is checked normally. |
| QUICK | Do a fast check. For MyISAM and Aria, this means skipping the check of the delete link chain, which may take some time. |
| MEDIUM | Scan also the data files. Checks integrity between data and index files with checksums. In most cases this should find all possible errors. |
| EXTENDED | Does a full check to verify every possible error. For InnoDB, Aria, and MyISAM, verify for each row that all its keys exists, and for those index keys, they point back to the primary clustered key. This may take a long time on large tables. This option was previously ignored by InnoDB before [MariaDB 10.6.11](https://mariadb.com/kb/en/mariadb-10611-release-notes/), [MariaDB 10.7.7](https://mariadb.com/kb/en/mariadb-1077-release-notes/), [MariaDB 10.8.6](https://mariadb.com/kb/en/mariadb-10-8-6-release-notes/) and [MariaDB 10.9.4](https://mariadb.com/kb/en/mariadb-10-9-4-release-notes/). |

 
For most cases running `CHECK TABLE` without options or `MEDIUM` should be good enough.

 The [Aria](../aria/index) storage engine supports [progress reporting](../progress-reporting/index) for this statement.

 If you want to know if two tables are identical, take a look at [CHECKSUM TABLE](../checksum-table/index).

 InnoDB
------

 If `CHECK TABLE` finds an error in an InnoDB table, MariaDB might shutdown to prevent the error propagation. In this case, the problem will be reported in the error log. Otherwise the table or an index might be marked as corrupted, to prevent use. This does not happen with some minor problems, like a wrong number of entries in a secondary index. Those problems are reported in the output of `CHECK TABLE`.

 Each tablespace contains a header with metadata. This header is not checked by this statement.

 During the execution of `CHECK TABLE`, other threads may be blocked.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/check-table/>

CHECKSUM TABLE
==============

    Syntax
------

 
```
CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ]

```
 Description
-----------

 `CHECKSUM TABLE` reports a table checksum. This is very useful if you want to know if two tables are the same (for example on a master and slave).

 With `QUICK`, the live table checksum is reported if it is available, or `NULL` otherwise. This is very fast. A live checksum is enabled by specifying the `CHECKSUM=1` table option when you [create the table](../create-table/index); currently, this is supported only for [Aria](../aria/index) and [MyISAM](../myisam/index) tables.

 With `EXTENDED`, the entire table is read row by row and the checksum is calculated. This can be very slow for large tables.

 If neither `QUICK` nor `EXTENDED` is specified, MariaDB returns a live checksum if the table storage engine supports it and scans the table otherwise.

 `CHECKSUM TABLE` requires the [SELECT privilege](../grant/index#table-privileges) for the table.

 For a nonexistent table, `CHECKSUM TABLE` returns `NULL` and generates a warning.

 The table row format affects the checksum value. If the row format changes, the checksum will change. This means that when a table created with a MariaDB/MySQL version is upgraded to another version, the checksum value will probably change.

 Two identical tables should always match to the same checksum value; however, also for non-identical tables there is a very slight chance that they will return the same value as the hashing algorithm is not completely collision-free.

 Identical Tables
----------------

 Identical tables mean that the CREATE statement is identical and that the following variable, which affects the storage formats, was the same when the tables were created:

 * [mysql56-temporal-format](../server-system-variables/index#mysql56_temporal_format)

 Differences Between MariaDB and MySQL
-------------------------------------

 `CHECKSUM TABLE` may give a different result as MariaDB doesn't ignore `NULL`s in the columns as MySQL 5.1 does (Later MySQL versions should calculate checksums the same way as MariaDB). You can get the 'old style' checksum in MariaDB by starting mysqld with the `--old` option. Note however that that the MyISAM and Aria storage engines in MariaDB are using the new checksum internally, so if you are using `--old`, the `CHECKSUM` command will be slower as it needs to calculate the checksum row by row. Starting from MariaDB Server 10.9, `--old` is deprecated and will be removed in a future release. Set `--old-mode` or `OLD_MODE` to `COMPAT_5_1_CHECKSUM` to get 'old style' checksum.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/checksum-table/>

ALTER SERVER
============

    Syntax
------

 
```
ALTER SERVER server_name
    OPTIONS (option [, option] ...)

```
 Description
-----------

 Alters the server information for *server\_name*, adjusting the specified options as per the [CREATE SERVER](../create-server/index) command. The corresponding fields in the [mysql.servers table](../mysqlservers-table/index) are updated accordingly. This statement requires the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [FEDERATED ADMIN](../grant/index#federated-admin) privilege.

 ALTER SERVER is not written to the [binary log](../binary-log/index), irrespective of the [binary log format](../binary-log-formats/index) being used. From [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), [Galera](../galera/index) replicates the [CREATE SERVER](../create-server/index), ALTER SERVER and [DROP SERVER](../drop-server/index) statements.

 Examples
--------

 
```
ALTER SERVER s OPTIONS (USER 'sally');

```

See Also
--------

 * [CREATE SERVER](../create-server/index)
* [DROP SERVER](../drop-server/index)
* [Spider Storage Engine](../spider/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-server/>

CREATE DATABASE
===============

    Syntax
------

 
```
CREATE [OR REPLACE] {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
    [create_specification] ...

create_specification:
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name
  | COMMENT [=] 'comment'

```
 Description
-----------

 `CREATE DATABASE` creates a database with the given name. To use this statement, you need the [CREATE privilege](../grant/index) for the database. `CREATE SCHEMA` is a synonym for `CREATE DATABASE`.

 For valid identifiers to use as database names, see [Identifier Names](../identifier-names/index).

 #### OR REPLACE

 
**MariaDB starting with [10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)**The `OR REPLACE` clause was added in [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/)

 
If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP DATABASE IF EXISTS db_name;
CREATE DATABASE db_name ...;

```

#### IF NOT EXISTS

 When the `IF NOT EXISTS` clause is used, MariaDB will return a warning instead of an error if the specified database already exists.

 #### COMMENT

 
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), it is possible to add a comment of a maximum of 1024 bytes. If the comment length exceeds this length, a error/warning code 4144 is thrown. The database comment is also added to the db.opt file, as well as to the [information\_schema.schemata table](../information-schema-schemata-table/index).

 
Examples
--------

 
```
CREATE DATABASE db1;
Query OK, 1 row affected (0.18 sec)

CREATE DATABASE db1;
ERROR 1007 (HY000): Can't create database 'db1'; database exists

CREATE OR REPLACE DATABASE db1;
Query OK, 2 rows affected (0.00 sec)

CREATE DATABASE IF NOT EXISTS db1;
Query OK, 1 row affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------+
| Level | Code | Message                                      |
+-------+------+----------------------------------------------+
| Note  | 1007 | Can't create database 'db1'; database exists |
+-------+------+----------------------------------------------+

```

Setting the [character sets and collation](../data-types-character-sets-and-collations/index). See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for more details.

 
```
CREATE DATABASE czech_slovak_names 
  CHARACTER SET = 'keybcs2'
  COLLATE = 'keybcs2_bin';

```

Comments, from [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 
```
CREATE DATABASE presentations COMMENT 'Presentations for conferences';

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [DROP DATABASE](../drop-database/index)
* [SHOW CREATE DATABASE](../show-create-database/index)
* [ALTER DATABASE](../alter-database/index)
* [SHOW DATABASES](../show-databases/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [Information Schema SCHEMATA Table](../information-schema-schemata-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-database/>

USE [DATABASE]
==============

    Syntax
------

 
```
USE db_name

```

In [MariaDB 11.3](../what-is-mariadb-113/index) one can also use

 
```
USE DATABASE db_name;

```

Description
-----------

 The `'USE db_name'` statement tells MariaDB to use the `db_name` database as the default (current) database for subsequent statements. The database remains the default until the end of the session or another `USE` statement is issued:

 
```
USE db1;
SELECT COUNT(*) FROM mytable;   # selects from db1.mytable
USE db2;
SELECT COUNT(*) FROM mytable;   # selects from db2.mytable

```

The [DATABASE()](../database/index) function ([SCHEMA()](../schema/index) is a synonym) returns the default database.

 Another way to set the default database is specifying its name at [mariadb](../mariadb-command-line-client/index) command line client startup.

 One cannot use `USE DATABASE` to a database one has no privileges to. The reason is that a user with no privileges to a database should not be able to know if a database exists or not.

 See Also
--------

 * [Identifier Qualifiers](../identifier-qualifiers/index)
* [USE CATALOG](../changing-catalog/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/use/>

CREATE EVENT
============

    Syntax
------

 
```
CREATE [OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    EVENT 
    [IF NOT EXISTS]
    event_name    
    ON SCHEDULE schedule
    [ON COMPLETION [NOT] PRESERVE]
    [ENABLE | DISABLE | DISABLE ON SLAVE]
    [COMMENT 'comment']
    DO sql_statement;

schedule:
    AT timestamp [+ INTERVAL interval] ...
  | EVERY interval 
    [STARTS timestamp [+ INTERVAL interval] ...] 
    [ENDS timestamp [+ INTERVAL interval] ...]

interval:
    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

```
 Description
-----------

 This statement creates and schedules a new [event](../events/index). It requires the `[EVENT](../grant/index#database-privileges)` privilege for the schema in which the event is to be created.

 The minimum requirements for a valid CREATE EVENT statement are as follows:

 * The keywords `CREATE EVENT` plus an event name, which uniquely identifies the event in the current schema. (Prior to MySQL 5.1.12, the event name needed to be unique only among events created by the same user on a given database.)
* An `ON SCHEDULE` clause, which determines when and how often the event executes.
* A `DO` clause, which contains the SQL statement to be executed by an event.

 Here is an example of a minimal `CREATE EVENT` statement:

 
```
CREATE EVENT myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;

```

The previous statement creates an event named myevent. This event executes once — one hour following its creation — by running an SQL statement that increments the value of the myschema.mytable table's mycol column by 1.

 The event\_name must be a valid MariaDB identifier with a maximum length of 64 characters. It may be delimited using back ticks, and may be qualified with the name of a database schema. An event is associated with both a MariaDB user (the definer) and a schema, and its name must be unique among names of events within that schema. In general, the rules governing event names are the same as those for names of stored routines. See [Identifier Names](../identifier-names/index).

 If no schema is indicated as part of event\_name, the default (current) schema is assumed.

 For valid identifiers to use as event names, see [Identifier Names](../identifier-names/index).

 #### OR REPLACE

 The `OR REPLACE` clause was included in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/). If used and the event already exists, instead of an error being returned, the existing event will be dropped and replaced by the newly defined event.

 #### IF NOT EXISTS

 If the `IF NOT EXISTS` clause is used, MariaDB will return a warning instead of an error if the event already exists. Cannot be used together with OR REPLACE.

 #### ON SCHEDULE

 The `ON SCHEDULE` clause can be used to specify when the event must be triggered.

 #### AT

 If you want to execute the event only once (one time event), you can use the `AT` keyword, followed by a timestamp. If you use `[CURRENT\_TIMESTAMP](../current_timestamp/index)`, the event acts as soon as it is created. As a convenience, you can add one or more intervals to that timestamp. You can also specify a timestamp in the past, so that the event is stored but not triggered, until you modify it via [ALTER EVENT](../alter-event/index).

 The following example shows how to create an event that will be triggered tomorrow at a certain time:

 
```
CREATE EVENT example
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR
DO something;

```

You can also specify that an event must be triggered at a regular interval (recurring event). In such cases, use the `EVERY` clause followed by the interval.

 If an event is recurring, you can specify when the first execution must happen via the `STARTS` clause and a maximum time for the last execution via the `ENDS` clause. `STARTS` and `ENDS` clauses are followed by a timestamp and, optionally, one or more intervals. The `ENDS` clause can specify a timestamp in the past, so that the event is stored but not executed until you modify it via [ALTER EVENT](../alter-event/index).

 In the following example, next month a recurring event will be triggered hourly for a week:

 
```
CREATE EVENT example
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
DO some_task;

```

Intervals consist of a quantity and a time unit. The time units are the same used for other staments and time functions, except that you can't use microseconds for events. For simple time units, like `HOUR` or `MINUTE`, the quantity is an integer number, for example '10 MINUTE'. For composite time units, like `HOUR_MINUTE` or `HOUR_SECOND`, the quantity must be a string with all involved simple values and their separators, for example '2:30' or '2:30:30'.

 #### ON COMPLETION [NOT] PRESERVE

 The `ON COMPLETION` clause can be used to specify if the event must be deleted after its last execution (that is, after its `AT` or `ENDS` timestamp is past). By default, events are dropped when they are expired. To explicitly state that this is the desired behaviour, you can use `ON COMPLETION NOT PRESERVE`. Instead, if you want the event to be preserved, you can use `ON COMPLETION PRESERVE`.

 In you specify `ON COMPLETION NOT PRESERVE`, and you specify a timestamp in the past for `AT` or `ENDS` clause, the event will be immediatly dropped. In such cases, you will get a Note 1558: "Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation".

 #### ENABLE/DISABLE/DISABLE ON SLAVE

 Events are `ENABLE`d by default. If you want to stop MariaDB from executing an event, you may specify `DISABLE`. When it is ready to be activated, you may enable it using `[ALTER EVENT](../alter-event/index)`. Another option is `DISABLE ON SLAVE`, which indicates that an event was created on a master and has been replicated to the slave, which is prevented from executing the event. If `DISABLE ON SLAVE` is specifically set, the event will be disabled everywhere. It will not be executed on the mater or the slaves.

 #### COMMENT

 The `COMMENT` clause may be used to set a comment for the event. Maximum length for comments is 64 characters. The comment is a string, so it must be quoted. To see events comments, you can query the [INFORMATION\_SCHEMA.EVENTS table](../information-schema-events-table/index) (the column is named `EVENT_COMMENT`).

 Examples
--------

 Minimal `CREATE EVENT` statement:

 
```
CREATE EVENT myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;

```

An event that will be triggered tomorrow at a certain time:

 
```
CREATE EVENT example
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY + INTERVAL 3 HOUR
DO something;

```

Next month a recurring event will be triggered hourly for a week:

 
```
CREATE EVENT example
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH + INTERVAL 1 WEEK
DO some_task;

```

OR REPLACE and IF NOT EXISTS:

 
```
CREATE EVENT myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;
ERROR 1537 (HY000): Event 'myevent' already exists

CREATE OR REPLACE EVENT myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;;
Query OK, 0 rows affected (0.00 sec)

CREATE EVENT IF NOT EXISTS myevent
    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
    DO
      UPDATE myschema.mytable SET mycol = mycol + 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

 SHOW WARNINGS;
+-------+------+--------------------------------+
| Level | Code | Message                        |
+-------+------+--------------------------------+
| Note  | 1537 | Event 'myevent' already exists |
+-------+------+--------------------------------+

```

See Also
--------

 * [Event Limitations](../event-limitations/index)
* [Identifier Names](../identifier-names/index)
* [Events Overview](../events-overview/index)
* [SHOW CREATE EVENT](../show-create-event/index)
* [ALTER EVENT](../alter-event/index)
* [DROP EVENT](../drop-event/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-event/>

CREATE INDEX
============

    Syntax
------

 
```
CREATE [OR REPLACE] [UNIQUE|FULLTEXT|SPATIAL] INDEX 
  [IF NOT EXISTS] index_name
    [index_type]
    ON tbl_name (index_col_name,...)
    [WAIT n | NOWAIT]
    [index_option]
    [algorithm_option | lock_option] ...

index_col_name:
    col_name [(length)] [ASC | DESC]

index_type:
    USING {BTREE | HASH | RTREE}

index_option:
    [ KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | CLUSTERING={YES| NO} ]
  [ IGNORED | NOT IGNORED ]

algorithm_option:
    ALGORITHM [=] {DEFAULT|INPLACE|COPY|NOCOPY|INSTANT}

lock_option:
    LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}

```
 Description
-----------

 The *CREATE INDEX* statement is used to add indexes to a table. Indexes can be created at the same as the table, with the [[|create-table|CREATE TABLE]] statement. In some cases, such as for InnoDB primary keys, doing so during creation is preferable, as adding a primary key will involve rebuilding the table.

 The statement is mapped to an ALTER TABLE statement to create [indexes](../optimization-and-indexes/index). See [ALTER TABLE](../alter-table/index). CREATE INDEX cannot be used to create a PRIMARY KEY; use ALTER TABLE instead.

 If another connection is using the table, a [metadata lock](../metadata-locking/index) is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.

 Another shortcut, [DROP INDEX](../drop-index/index), allows the removal of an index.

 For valid identifiers to use as index names, see [Identifier Names](../identifier-names/index).

 
Note that KEY\_BLOCK\_SIZE is currently ignored in CREATE INDEX, although it is included in the output of [SHOW CREATE TABLE](../show-create-table/index).

 
Privileges
----------

 Executing the `CREATE INDEX` statement requires the `[INDEX](../grant/index#table-privileges)` privilege for the table or the database.

 Online DDL
----------

 Online DDL is supported with the [ALGORITHM](#algorithm) and [LOCK](#lock) clauses.

 See [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index) for more information on online DDL with [InnoDB](../innodb/index).

 CREATE OR REPLACE INDEX
-----------------------

 If the `OR REPLACE` clause is used and if the index already exists, then instead of returning an error, the server will drop the existing index and replace it with the newly defined index.

 CREATE INDEX IF NOT EXISTS
--------------------------

 If the `IF NOT EXISTS` clause is used, then the index will only be created if an index with the same name does not already exist. If the index already exists, then a warning will be triggered by default.

 Index Definitions
-----------------

 See [CREATE TABLE: Index Definitions](../create-table/index#index-definitions) for information about index definitions.

 WAIT/NOWAIT
-----------

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 ALGORITHM
---------

 See [ALTER TABLE: ALGORITHM](../alter-table/index#algorithm) for more information.

 LOCK
----

 See [ALTER TABLE: LOCK](../alter-table/index#lock) for more information.

 Progress Reporting
------------------

 MariaDB provides progress reporting for `CREATE INDEX` statement for clients that support the new progress reporting protocol. For example, if you were using the [mariadb](../mariadb-command-line-client/index) client, then the progress report might look like this::

 
```
CREATE INDEX i ON tab (num);
Stage: 1 of 2 'copy to tmp table'    46% of stage

```

The progress report is also shown in the output of the [SHOW PROCESSLIST](../show-processlist/index) statement and in the contents of the [information\_schema.PROCESSLIST](../information-schema-processlist-table/index) table.

 See [Progress Reporting](../progress-reporting/index) for more information.

 WITHOUT OVERLAPS
----------------

 
**MariaDB starting with [10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/)**The [WITHOUT OVERLAPS](../application-time-periods/index#without-overlaps) clause allows one to constrain a primary or unique index such that [application-time periods](../application-time-periods/index) cannot overlap.

 
Examples
--------

 Creating a unique index:

 
```
CREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);

```

OR REPLACE and IF NOT EXISTS:

 
```
CREATE INDEX xi ON xx5 (x);
Query OK, 0 rows affected (0.03 sec)

CREATE INDEX xi ON xx5 (x);
ERROR 1061 (42000): Duplicate key name 'xi'

CREATE OR REPLACE INDEX xi ON xx5 (x);
Query OK, 0 rows affected (0.03 sec)

CREATE INDEX IF NOT EXISTS xi ON xx5 (x);
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+-------------------------+
| Level | Code | Message                 |
+-------+------+-------------------------+
| Note  | 1061 | Duplicate key name 'xi' |
+-------+------+-------------------------+

```

From [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/), creating a unique index for an [application-time period table](../application-time-periods/index) with a [WITHOUT OVERLAPS](../application-time-periods/index#without-overlaps) constraint:

 
```
CREATE UNIQUE INDEX u ON rooms (room_number, p WITHOUT OVERLAPS);

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [Getting Started with Indexes](../getting-started-with-indexes/index)
* [What is an Index?](../what-is-an-index/index)
* [ALTER TABLE](../alter-table/index)
* [DROP INDEX](../drop-index/index)
* [SHOW INDEX](../show-index/index)
* [SPATIAL INDEX](../spatial-index/index)
* [Full-text Indexes](../full-text-indexes/index)
* [WITHOUT OVERLAPS](../application-time-periods/index#without-overlaps)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-index/>

CREATE FUNCTION
===============

    Syntax
------

 
```
CREATE [OR REPLACE]
    [DEFINER = {user | CURRENT_USER | role | CURRENT_ROLE }]
    [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...]
    RETURN func_body
func_parameter:
    [ IN | OUT | INOUT | IN OUT ]  param_name type
type:
    Any valid MariaDB data type
characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'
func_body:
    Valid SQL procedure statement
```
 Description
-----------

 Use the `CREATE FUNCTION` statement to create a new [stored function](../stored-functions/index). You must have the [CREATE ROUTINE](../grant/index#database-privileges) database privilege to use `CREATE FUNCTION`. A function takes any number of arguments and returns a value from the function body. The function body can be any valid SQL expression as you would use, for example, in any select expression. If you have the appropriate privileges, you can call the function exactly as you would any built-in function. See [Security](#security) below for details on privileges.

 You can also use a variant of the `CREATE FUNCTION` statement to install a user-defined function (UDF) defined by a plugin. See [CREATE FUNCTION (UDF)](../create-function-udf/index) for details.

 You can use a [SELECT](../select/index) statement for the function body by enclosing it in parentheses, exactly as you would to use a subselect for any other expression. The `SELECT` statement must return a single value. If more than one column is returned when the function is called, error 1241 results. If more than one row is returned when the function is called, error 1242 results. Use a `LIMIT` clause to ensure only one row is returned.

 You can also replace the `RETURN` clause with a [BEGIN...END](../begin-end/index) compound statement. The compound statement must contain a `RETURN` statement. When the function is called, the `RETURN` statement immediately returns its result, and any statements after `RETURN` are effectively ignored.

 By default, a function is associated with the current database. To associate the function explicitly with a given database, specify the fully-qualified name as `*db\_name*.*func\_name*` when you create it. If the function name is the same as the name of a built-in function, you must use the fully qualified name when you call it.

 The parameter list enclosed within parentheses must always be present. If there are no parameters, an empty parameter list of () should be used. Parameter names are not case sensitive.

 Each parameter can be declared to use any valid data type, except that the COLLATE attribute cannot be used.

 For valid identifiers to use as function names, see [Identifier Names](../identifier-names/index).

 #### IN | OUT | INOUT | IN OUT

 
**MariaDB starting with [10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/)**The function parameter qualifiers for `IN`, `OUT`, `INOUT`, and `IN OUT` were added in a 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only in procedures.

 
`OUT`, `INOUT` and its equivalent `IN OUT`, are only valid if called from `SET` and not `SELECT`. These quantifiers are especially useful for creating functions with more than one return value. This allows functions to be more complex and nested.

 
```
DELIMITER $$
CREATE FUNCTION add_func3(IN a INT, IN b INT, OUT c INT) RETURNS INT
BEGIN
  SET c = 100;
  RETURN a + b;
END;
$$
DELIMITER ;
 
SET @a = 2;
SET @b = 3;
SET @c = 0;
SET @res= add_func3(@a, @b, @c);

SELECT add_func3(@a, @b, @c);
ERROR 4186 (HY000): OUT or INOUT argument 3 for function add_func3 is not allowed here

DELIMITER $$
CREATE FUNCTION add_func4(IN a INT, IN b INT, d INT) RETURNS INT
BEGIN
  DECLARE c, res INT;
  SET res = add_func3(a, b, c) + d;
  if (c > 99) then
    return  3;
  else
    return res;
  end if;
END;
$$

DELIMITER ;

SELECT add_func4(1,2,3);
+------------------+
| add_func4(1,2,3) |
+------------------+
|                3 |
+------------------+

```

#### AGGREGATE

 It is possible to create stored aggregate functions as well. See [Stored Aggregate Functions](../stored-aggregate-functions/index) for details.

 #### RETURNS

 The `RETURNS` clause specifies the return type of the function. `NULL` values are permitted with all return types.

 What happens if the `RETURN` clause returns a value of a different type? It depends on the [SQL\_MODE](../sql-mode/index) in effect at the moment of the function creation.

 If the SQL\_MODE is strict (STRICT\_ALL\_TABLES or STRICT\_TRANS\_TABLES flags are specified), a 1366 error will be produced.

 Otherwise, the value is coerced to the proper type. For example, if a function specifies an `ENUM` or `SET` value in the `RETURNS` clause, but the `RETURN` clause returns an integer, the value returned from the function is the string for the corresponding `ENUM` member of set of `SET` members.

 MariaDB stores the SQL\_MODE system variable setting that is in effect at the time a routine is created, and always executes the routine with this setting in force, regardless of the server SQL mode in effect when the routine is invoked.

 #### LANGUAGE SQL

 `LANGUAGE SQL` is a standard SQL clause, and it can be used in MariaDB for portability. However that clause has no meaning, because SQL is the only supported language for stored functions.

 A function is deterministic if it can produce only one result for a given list of parameters. If the result may be affected by stored data, server variables, random numbers or any value that is not explicitly passed, then the function is not deterministic. Also, a function is non-deterministic if it uses non-deterministic functions like [NOW()](../now/index) or [CURRENT\_TIMESTAMP()](../current_user/index). The optimizer may choose a faster execution plan if it known that the function is deterministic. In such cases, you should declare the routine using the `DETERMINISTIC` keyword. If you want to explicitly state that the function is not deterministic (which is the default) you can use the `NOT DETERMINISTIC` keywords.

 If you declare a non-deterministic function as `DETERMINISTIC`, you may get incorrect results. If you declare a deterministic function as `NOT DETERMINISTIC`, in some cases the queries will be slower.

 #### OR REPLACE

 If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP FUNCTION IF EXISTS function_name;
CREATE FUNCTION function_name ...;

```

with the exception that any existing [privileges](../stored-routine-privileges/index) for the function are not dropped.

 #### IF NOT EXISTS

 If the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the function already exists. Cannot be used together with OR REPLACE.

 #### [NOT] DETERMINISTIC

 The `[NOT] DETERMINISTIC` clause also affects [binary logging](../binary-log/index), because the `STATEMENT` format can not be used to store or replicate non-deterministic statements.

 `CONTAINS SQL`, `NO SQL`, `READS SQL DATA`, and `MODIFIES SQL DATA` are informative clauses that tell the server what the function does. MariaDB does not check in any way whether the specified clause is correct. If none of these clauses are specified, `CONTAINS SQL` is used by default.

 #### MODIFIES SQL DATA

 `MODIFIES SQL DATA` means that the function contains statements that may modify data stored in databases. This happens if the function contains statements like [DELETE](../delete/index), [UPDATE](../update/index), [INSERT](../insert/index), [REPLACE](../replace/index) or DDL.

 #### READS SQL DATA

 `READS SQL DATA` means that the function reads data stored in databases, but does not modify any data. This happens if [SELECT](../select/index) statements are used, but there no write operations are executed.

 #### CONTAINS SQL

 `CONTAINS SQL` means that the function contains at least one SQL statement, but it does not read or write any data stored in a database. Examples include [SET](../set/index) or [DO](../do/index).

 #### NO SQL

 `NO SQL` means nothing, because MariaDB does not currently support any language other than SQL.

 #### Oracle Mode

 A subset of Oracle's PL/SQL language is supported in addition to the traditional SQL/PSM-based MariaDB syntax. See [Oracle mode](../sql_modeoracle-from-mariadb-103/index#stored-procedures-and-stored-functions) for details on changes when running Oracle mode.

 Security
--------

 You must have the [EXECUTE](../grant/index#function-privileges) privilege on a function to call it. MariaDB automatically grants the `EXECUTE` and `ALTER ROUTINE` privileges to the account that called `CREATE FUNCTION`, even if the `DEFINER` clause was used.

 Each function has an account associated as the definer. By default, the definer is the account that created the function. Use the `DEFINER` clause to specify a different account as the definer. You must have the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [SET USER](../grant/index#set-user) privilege, to use the `DEFINER` clause. See [Account Names](../create-user/index#account-names) for details on specifying accounts.

 The `SQL SECURITY` clause specifies what privileges are used when a function is called. If `SQL SECURITY` is `INVOKER`, the function body will be evaluated using the privileges of the user calling the function. If `SQL SECURITY` is `DEFINER`, the function body is always evaluated using the privileges of the definer account. `DEFINER` is the default.

 This allows you to create functions that grant limited access to certain data. For example, say you have a table that stores some employee information, and that you've granted `SELECT` privileges [only on certain columns](../grant/index#column-privileges) to the user account `roger`.

 
```
CREATE TABLE employees (name TINYTEXT, dept TINYTEXT, salary INT);
GRANT SELECT (name, dept) ON employees TO roger;

```

To allow the user the get the maximum salary for a department, define a function and grant the `EXECUTE` privilege:

 
```
CREATE FUNCTION max_salary (dept TINYTEXT) RETURNS INT RETURN
  (SELECT MAX(salary) FROM employees WHERE employees.dept = dept);
GRANT EXECUTE ON FUNCTION max_salary TO roger;

```

Since `SQL SECURITY` defaults to `DEFINER`, whenever the user `roger` calls this function, the subselect will execute with your privileges. As long as you have privileges to select the salary of each employee, the caller of the function will be able to get the maximum salary for each department without being able to see individual salaries.

 Character sets and collations
-----------------------------

 Function return types can be declared to use any valid [character set and collation](../character-sets/index). If used, the COLLATE attribute needs to be preceded by a CHARACTER SET attribute.

 If the character set and collation are not specifically set in the statement, the database defaults at the time of creation will be used. If the database defaults change at a later stage, the stored function character set/collation will not be changed at the same time; the stored function needs to be dropped and recreated to ensure the same character set/collation as the database is used.

 Examples
--------

 The following example function takes a parameter, performs an operation using an SQL function, and returns the result.

 
```
CREATE FUNCTION hello (s CHAR(20))
    RETURNS CHAR(50) DETERMINISTIC
    RETURN CONCAT('Hello, ',s,'!');

SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!  |
+----------------+

```

You can use a compound statement in a function to manipulate data with statements like `INSERT` and `UPDATE`. The following example creates a counter function that uses a temporary table to store the current value. Because the compound statement contains statements terminated with semicolons, you have to first change the statement delimiter with the `DELIMITER` statement to allow the semicolon to be used in the function body. See [Delimiters in the mariadb client](../delimiters/index) for more.

 
```
CREATE TEMPORARY TABLE counter (c INT);
INSERT INTO counter VALUES (0);
DELIMITER //
CREATE FUNCTION counter () RETURNS INT
  BEGIN
    UPDATE counter SET c = c + 1;
    RETURN (SELECT c FROM counter LIMIT 1);
  END //
DELIMITER ;

```

Character set and collation:

 
```
CREATE FUNCTION hello2 (s CHAR(20))
  RETURNS CHAR(50) CHARACTER SET 'utf8' COLLATE 'utf8_bin' DETERMINISTIC
  RETURN CONCAT('Hello, ',s,'!');

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [Stored Aggregate Functions](../stored-aggregate-functions/index)
* [CREATE FUNCTION (UDF)](../create-function-udf/index)
* [SHOW CREATE FUNCTION](../show-create-function/index)
* [ALTER FUNCTION](../alter-function/index)
* [DROP FUNCTION](../drop-function/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-function/>

CREATE PROCEDURE
================

    Syntax
------

 
```
CREATE
    [OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    PROCEDURE [IF NOT EXISTS] sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

type:
    Any valid MariaDB data type

characteristic:
    LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
  | COMMENT 'string'

routine_body:
    Valid SQL procedure statement

```
 Description
-----------

 Creates a [stored procedure](../stored-procedures/index). By default, a routine is associated with the default database. To associate the routine explicitly with a given database, specify the name as db\_name.sp\_name when you create it.

 When the routine is invoked, an implicit USE db\_name is performed (and undone when the routine terminates). The causes the routine to have the given default database while it executes. USE statements within stored routines are disallowed.

 When a stored procedure has been created, you invoke it by using the `CALL` statement (see [CALL](../call/index)).

 To execute the `CREATE PROCEDURE` statement, it is necessary to have the `CREATE ROUTINE` privilege. By default, MariaDB automatically grants the `ALTER ROUTINE` and `EXECUTE` privileges to the routine creator. See also [Stored Routine Privileges](../stored-routine-privileges/index).

 The `DEFINER` and SQL SECURITY clauses specify the security context to be used when checking access privileges at routine execution time, as described [here](../stored-routine-privileges/index). Requires the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [SET USER](../grant/index#set-user) privilege.

 If the routine name is the same as the name of a built-in SQL function, you must use a space between the name and the following parenthesis when defining the routine, or a syntax error occurs. This is also true when you invoke the routine later. For this reason, we suggest that it is better to avoid re-using the names of existing SQL functions for your own stored routines.

 The IGNORE\_SPACE SQL mode applies to built-in functions, not to stored routines. It is always allowable to have spaces after a routine name, regardless of whether IGNORE\_SPACE is enabled.

 The parameter list enclosed within parentheses must always be present. If there are no parameters, an empty parameter list of () should be used. Parameter names are not case sensitive.

 Each parameter can be declared to use any valid data type, except that the COLLATE attribute cannot be used.

 For valid identifiers to use as procedure names, see [Identifier Names](../identifier-names/index).

 ### Things to be Aware of With CREATE OR REPLACE

 * One can't use `OR REPLACE` together with `IF EXISTS`.

 CREATE PROCEDURE IF NOT EXISTS
------------------------------

 If the `IF NOT EXISTS` clause is used, then the procedure will only be created if a procedure with the same name does not already exist. If the procedure already exists, then a warning will be triggered by default.

 ### IN/OUT/INOUT

 Each parameter is an `IN` parameter by default. To specify otherwise for a parameter, use the keyword `OUT` or `INOUT` before the parameter name.

 An `IN` parameter passes a value into a procedure. The procedure might modify the value, but the modification is not visible to the caller when the procedure returns. An `OUT` parameter passes a value from the procedure back to the caller. Its initial value is NULL within the procedure, and its value is visible to the caller when the procedure returns. An `INOUT` parameter is initialized by the caller, can be modified by the procedure, and any change made by the procedure is visible to the caller when the procedure returns.

 For each `OUT` or `INOUT` parameter, pass a user-defined variable in the `CALL` statement that invokes the procedure so that you can obtain its value when the procedure returns. If you are calling the procedure from within another stored procedure or function, you can also pass a routine parameter or local routine variable as an `IN` or `INOUT` parameter.

 ### DETERMINISTIC/NOT DETERMINISTIC

 `DETERMINISTIC` and `NOT DETERMINISTIC` apply only to [functions](../stored-functions/index). Specifying `DETERMINISTC` or `NON-DETERMINISTIC` in procedures has no effect. The default value is `NOT DETERMINISTIC`. Functions are `DETERMINISTIC` when they always return the same value for the same input. For example, a truncate or substring function. Any function involving data, therefore, is always `NOT DETERMINISTIC`.

 ### CONTAINS SQL/NO SQL/READS SQL DATA/MODIFIES SQL DATA

 `CONTAINS SQL`, `NO SQL`, `READS SQL DATA`, and `MODIFIES SQL DATA` are informative clauses that tell the server what the function does. MariaDB does not check in any way whether the specified clause is correct. If none of these clauses are specified, `CONTAINS SQL` is used by default.

 `MODIFIES SQL DATA` means that the function contains statements that may modify data stored in databases. This happens if the function contains statements like [DELETE](../delete/index), [UPDATE](../update/index), [INSERT](../insert/index), [REPLACE](../replace/index) or DDL.

 `READS SQL DATA` means that the function reads data stored in databases, but does not modify any data. This happens if [SELECT](../select/index) statements are used, but there no write operations are executed.

 `CONTAINS SQL` means that the function contains at least one SQL statement, but it does not read or write any data stored in a database. Examples include [SET](../set/index) or [DO](../do/index).

 `NO SQL` means nothing, because MariaDB does not currently support any language other than SQL.

 The routine\_body consists of a valid SQL procedure statement. This can be a simple statement such as [SELECT](../select/index) or [INSERT](../insert/index), or it can be a compound statement written using [BEGIN and END](../begin-end/index). Compound statements can contain declarations, loops, and other control structure statements. See [Programmatic and Compound Statements](../programmatic-and-compound-statements/index) for syntax details.

 MariaDB allows routines to contain DDL statements, such as `CREATE` and DROP. MariaDB also allows [stored procedures](../stored-procedures/index) (but not [stored functions](../stored-functions/index)) to contain SQL transaction statements such as `COMMIT`.

 For additional information about statements that are not allowed in stored routines, see [Stored Routine Limitations](../stored-routine-limitations/index).

 ### Invoking stored procedure from within programs

 For information about invoking [stored procedures](../stored-procedures/index) from within programs written in a language that has a MariaDB/MySQL interface, see [CALL](../call/index).

 ### OR REPLACE

 If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP PROCEDURE IF EXISTS name;
CREATE PROCEDURE name ...;

```

with the exception that any existing [privileges](../stored-routine-privileges/index) for the procedure are not dropped.

 ### sql\_mode

 MariaDB stores the [sql\_mode](../server-system-variables/index#sql_mode) system variable setting that is in effect at the time a routine is created, and always executes the routine with this setting in force, regardless of the server [SQL mode](../sql_mode/index) in effect when the routine is invoked.

 ### Character Sets and Collations

 Procedure parameters can be declared with any character set/collation. If the character set and collation are not specifically set, the database defaults at the time of creation will be used. If the database defaults change at a later stage, the stored procedure character set/collation will not be changed at the same time; the stored procedure needs to be dropped and recreated to ensure the same character set/collation as the database is used.

 ### Oracle Mode

 A subset of Oracle's PL/SQL language is supported in addition to the traditional SQL/PSM-based MariaDB syntax. See [Oracle mode](../sql_modeoracle-from-mariadb-103/index#stored-procedures-and-stored-functions) for details on changes when running Oracle mode.

 Examples
--------

 The following example shows a simple stored procedure that uses an `OUT` parameter. It uses the DELIMITER command to set a new delimiter for the duration of the process — see [Delimiters in the mariadb client](../delimiters/index).

 
```
DELIMITER //

CREATE PROCEDURE simpleproc (OUT param1 INT)
 BEGIN
  SELECT COUNT(*) INTO param1 FROM t;
 END;
//

DELIMITER ;

CALL simpleproc(@a);

SELECT @a;
+------+
| @a   |
+------+
|    1 |
+------+

```

Character set and collation:

 
```
DELIMITER //

CREATE PROCEDURE simpleproc2 (
  OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
  SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//

DELIMITER ;

```

CREATE OR REPLACE:

 
```
DELIMITER //

CREATE PROCEDURE simpleproc2 (
  OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
  SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//
ERROR 1304 (42000): PROCEDURE simpleproc2 already exists

DELIMITER ;

DELIMITER //

CREATE OR REPLACE PROCEDURE simpleproc2 (
  OUT param1 CHAR(10) CHARACTER SET 'utf8' COLLATE 'utf8_bin'
)
 BEGIN
  SELECT CONCAT('a'),f1 INTO param1 FROM t;
 END;
//
ERROR 1304 (42000): PROCEDURE simpleproc2 already exists

DELIMITER ;
Query OK, 0 rows affected (0.03 sec)

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [Stored Procedure Overview](../stored-procedure-overview/index)
* [ALTER PROCEDURE](../alter-procedure/index)
* [DROP PROCEDURE](../drop-procedure/index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-procedure/>

CREATE SERVER
=============

    Syntax
------

 
```
CREATE [OR REPLACE] SERVER [IF NOT EXISTS] server_name
    FOREIGN DATA WRAPPER wrapper_name
    OPTIONS (option [, option] ...)

option:
  { HOST character-literal
  | DATABASE character-literal
  | USER character-literal
  | PASSWORD character-literal
  | SOCKET character-literal
  | OWNER character-literal
  | PORT numeric-literal }

```
 Description
-----------

 This statement creates the definition of a server for use with the [Spider](../spider/index), [Connect](../connect/index), [FEDERATED](../federated-storage-engine/index) or [FederatedX](../federatedx/index) storage engine. The CREATE SERVER statement creates a new row within the [servers](../mysqlservers-table/index) table within the mysql database. This statement requires the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [FEDERATED ADMIN](../grant/index#federated-admin) privilege.

 The server\_name should be a unique reference to the server. Server definitions are global within the scope of the server, it is not possible to qualify the server definition to a specific database. server\_name has a maximum length of 64 characters (names longer than 64 characters are silently truncated), and is case insensitive. You may specify the name as a quoted string.

 The wrapper\_name may be quoted with single quotes. Supported values are:

 * `mysql`
* `mariadb` (in [MariaDB 10.3](../what-is-mariadb-103/index) and later)

 For each option you must specify either a character literal or numeric literal. Character literals are UTF-8, support a maximum length of 64 characters and default to a blank (empty) string. String literals are silently truncated to 64 characters. Numeric literals must be a number between 0 and 9999, default value is 0.

 **Note**: The `OWNER` option is currently not applied, and has no effect on the ownership or operation of the server connection that is created.

 The CREATE SERVER statement creates an entry in the [mysql.servers](../mysqlservers-table/index) table that can later be used with the CREATE TABLE statement when creating a [Spider](../spider/index), [Connect](../connect/index), [FederatedX](../federatedx/index) or [FEDERATED](../federated-storage-engine/index) table. The options that you specify will be used to populate the columns in the mysql.servers table. The table columns are Server\_name, Host, Db, Username, Password, Port and Socket.

  [DROP SERVER](../drop-server/index) removes a previously created server definition. 

 CREATE SERVER is not written to the [binary log](../binary-log/index), irrespective of the [binary log format](../binary-log-formats/index) being used. From [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), [Galera](../galera/index) replicates the CREATE SERVER, [ALTER SERVER](../alter-server/index) and [DROP SERVER](../drop-server/index) statements.

 For valid identifiers to use as server names, see [Identifier Names](../identifier-names/index).

 #### OR REPLACE

 If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP SERVER IF EXISTS name;
CREATE SERVER server_name ...;

```

#### IF NOT EXISTS

 If the IF NOT EXISTS clause is used, MariaDB will return a warning instead of an error if the server already exists. Cannot be used together with OR REPLACE.

 Examples
--------

 
```
CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');

```

OR REPLACE and IF NOT EXISTS:

 
```
CREATE SERVER s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
ERROR 1476 (HY000): The foreign server, s, you are trying to create already exists

CREATE OR REPLACE SERVER s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
Query OK, 0 rows affected (0.00 sec)

CREATE SERVER IF NOT EXISTS s 
FOREIGN DATA WRAPPER mysql 
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------------------------+
| Level | Code | Message                                                        |
+-------+------+----------------------------------------------------------------+
| Note  | 1476 | The foreign server, s, you are trying to create already exists |
+-------+------+----------------------------------------------------------------+

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [ALTER SERVER](../alter-server/index)
* [DROP SERVER](../drop-server/index)
* [Spider Storage Engine](../spider/index)
* [Connect Storage Engine](../connect/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-server/>

COMMIT
======

    The `COMMIT` statement ends a transaction, saving any changes to the data so that they become visible to subsequent transactions. Also, [unlocks metadata](../metadata-locking/index) changed by current transaction. If [autocommit](../server-system-variables/index#autocommit) is set to 1, an implicit commit is performed after each statement. Otherwise, all transactions which don't end with an explicit `COMMIT` are implicitly rollbacked and the changes are lost. The `[ROLLBACK](../rollback/index)` statement can be used to do this explicitly.

 The required syntax for the `COMMIT` statement is as follows:

 
```
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]

```

`COMMIT` is the more important transaction terminator, as well as the more interesting one. The basic form of the `COMMIT` statement is simply the keyword `COMMIT` (the keyword `WORK` is simply noise and can be omitted without changing the effect).

 The optional `AND CHAIN` clause is a convenience for initiating a new transaction as soon as the old transaction terminates. If `AND CHAIN` is specified, then there is effectively nothing between the old and new transactions, although they remain separate. The characteristics of the new transaction will be the same as the characteristics of the old one — that is, the new transaction will have the same access mode, isolation level and diagnostics area size (we'll discuss all of these shortly) as the transaction just terminated. 

 `RELEASE` tells the server to disconnect the client immediately after the current transaction.

 There are `NO RELEASE` and `AND NO CHAIN` options. By default, commits do not `RELEASE` or `CHAIN`, but it's possible to change this default behavior with the [completion\_type](../server-system-variables/index#completion_type) server system variable. In this case, the `AND NO CHAIN` and `NO RELEASE` options override the server default.

 See Also
--------

 * [autocommit](../server-system-variables/index#autocommit) - server system variable that determines whether statements are automatically committed.
* [completion\_type](../server-system-variables/index#completion_type) - server system variable that determines whether COMMIT's are standard, COMMIT AND CHAIN or COMMIT RELEASE.
* [SQL statements that cause an implicit commit](../sql-statements-that-cause-an-implicit-commit/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-commit-statement/>

CREATE TRIGGER
==============

    Syntax
------

 
```
CREATE [OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    TRIGGER [IF NOT EXISTS] trigger_name trigger_time trigger_event
    ON tbl_name FOR EACH ROW
   [{ FOLLOWS | PRECEDES } other_trigger_name ]
   trigger_stmt;

```
 Description
-----------

 This statement creates a new [trigger](../triggers/index). A trigger is a named database object that is associated with a table, and that activates when a particular event occurs for the table. The trigger becomes associated with the table named `tbl_name`, which must refer to a permanent table. You cannot associate a trigger with a `TEMPORARY` table or a view.

 `CREATE TRIGGER` requires the [TRIGGER](../grant/index#table-privileges) privilege for the table associated with the trigger.

 You can have multiple triggers for the same `trigger_time` and `trigger_event`.

 For valid identifiers to use as trigger names, see [Identifier Names](../identifier-names/index).

 ### OR REPLACE

 If used and the trigger already exists, instead of an error being returned, the existing trigger will be dropped and replaced by the newly defined trigger.

 ### DEFINER

 The `DEFINER` clause determines the security context to be used when checking access privileges at trigger activation time. Usage requires the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [SET USER](../grant/index#set-user) privilege.

 ### IF NOT EXISTS

 If the `IF NOT EXISTS` clause is used, the trigger will only be created if a trigger of the same name does not exist. If the trigger already exists, by default a warning will be returned.

 ### trigger\_time

 `trigger_time` is the trigger action time. It can be `BEFORE` or `AFTER` to indicate that the trigger activates before or after each row to be modified.

 ### trigger\_event

 `trigger_event` indicates the kind of statement that activates the trigger. The `trigger_event` can be one of the following:

 * `INSERT`: The trigger is activated whenever a new row is inserted into the table; for example, through [INSERT](../insert-commands/index), [LOAD DATA](../load-data-infile/index), and [REPLACE](../replace/index) statements.
* `UPDATE`: The trigger is activated whenever a row is modified; for example, through [UPDATE](../update/index) statements.
* `DELETE`: The trigger is activated whenever a row is deleted from the table; for example, through [DELETE](../delete/index) and [REPLACE](../replace/index) statements. However, `DROP TABLE` and `TRUNCATE` statements on the table do not activate this trigger, because they do not use `DELETE`. Dropping a partition does not activate `DELETE` triggers, either.

 #### FOLLOWS/PRECEDES other\_trigger\_name

 The `FOLLOWS other_trigger_name` and `PRECEDES other_trigger_name` options were added in [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) as part of supporting multiple triggers per action time. This is the same syntax used by MySQL 5.7, although MySQL 5.7 does not have multi-trigger support.

 `FOLLOWS` adds the new trigger after another trigger while `PRECEDES` adds the new trigger before another trigger. If neither option is used, the new trigger is added last for the given action and time.

 `FOLLOWS` and `PRECEDES` are not stored in the trigger definition. However the trigger order is guaranteed to not change over time. [mariadb-dump](../mariadb-dump/index) and other backup methods will not change trigger order. You can verify the trigger order from the `ACTION_ORDER` column in [INFORMATION\_SCHEMA.TRIGGERS](../information-schema-triggers-table/index) table.

 
```
SELECT trigger_name, action_order FROM information_schema.triggers 
  WHERE event_object_table='t1';

```

### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index) and `CREATE TRIGGER` is atomic.

 
Examples
--------

 
```
CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
  AFTER INSERT ON animals FOR EACH ROW 
   UPDATE animal_count SET animal_count.animals = animal_count.animals+1;

```

OR REPLACE and IF NOT EXISTS

 
```
CREATE DEFINER=`root`@`localhost` TRIGGER increment_animal
  AFTER INSERT ON animals FOR EACH ROW
    UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
ERROR 1359 (HY000): Trigger already exists

CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER increment_animal
  AFTER INSERT ON animals  FOR EACH ROW
    UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
Query OK, 0 rows affected (0.12 sec)

CREATE DEFINER=`root`@`localhost` TRIGGER IF NOT EXISTS increment_animal
  AFTER INSERT ON animals FOR EACH ROW
    UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1359 | Trigger already exists |
+-------+------+------------------------+
1 row in set (0.00 sec)

```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [Trigger Overview](../trigger-overview/index)
* [DROP TRIGGER](../drop-trigger/index)
* [Information Schema TRIGGERS Table](../information-schema-triggers-table/index)
* [SHOW TRIGGERS](../show-triggers/index)
* [SHOW CREATE TRIGGER](../show-create-trigger/index)
* [Trigger Limitations](../trigger-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-trigger/>

CREATE USER
===========

    Syntax
------

 
```
CREATE [OR REPLACE] USER [IF NOT EXISTS] 
 user_specification [,user_specification ...] 
  [REQUIRE {NONE | tls_option [[AND] tls_option ...] }]
  [WITH resource_option [resource_option ...] ]
  [lock_option] [password_option] 

user_specification:
  username [authentication_option]

authentication_option:
  IDENTIFIED BY 'password' 
  | IDENTIFIED BY PASSWORD 'password_hash'
  | IDENTIFIED {VIA|WITH} authentication_rule [OR authentication_rule  ...]

authentication_rule:
    authentication_plugin
  | authentication_plugin {USING|AS} 'authentication_string'
  | authentication_plugin {USING|AS} PASSWORD('password')

tls_option:
  SSL 
  | X509
  | CIPHER 'cipher'
  | ISSUER 'issuer'
  | SUBJECT 'subject'

resource_option:
  MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
  | MAX_STATEMENT_TIME time

password_option:
  PASSWORD EXPIRE
  | PASSWORD EXPIRE DEFAULT
  | PASSWORD EXPIRE NEVER
  | PASSWORD EXPIRE INTERVAL N DAY

lock_option:
    ACCOUNT LOCK
  | ACCOUNT UNLOCK
}

```
 Description
-----------

 The `CREATE USER` statement creates new MariaDB accounts. To use it, you must have the global [CREATE USER](../grant/index#create-user) privilege or the [INSERT](../grant/index#table-privileges) privilege for the [mysql](../the-mysql-database-tables/index) database. For each account, `CREATE USER` creates a new row in [mysql.user](../mysqluser-table/index) (until [MariaDB 10.3](../what-is-mariadb-103/index) this is a table, from [MariaDB 10.4](../what-is-mariadb-104/index) it's a view) or [mysql.global\_priv\_table](../mysqlglobal_priv-table/index) (from [MariaDB 10.4](../what-is-mariadb-104/index)) that has no privileges.

 If any of the specified accounts, or any permissions for the specified accounts, already exist, then the server returns `ERROR 1396 (HY000)`. If an error occurs, `CREATE USER` will still create the accounts that do not result in an error. Only one error is produced for all users which have not been created:

 
```
ERROR 1396 (HY000): 
  Operation CREATE USER failed for 'u1'@'%','u2'@'%'

```

`CREATE USER`, [DROP USER](../drop-user/index), [CREATE ROLE](../create-role/index), and [DROP ROLE](../drop-role/index) all produce the same error code when they fail.

 See [Account Names](#account-names) below for details on how account names are specified. 

 OR REPLACE
----------

 If the optional `OR REPLACE` clause is used, it is basically a shortcut for:

 
```
DROP USER IF EXISTS name;
CREATE USER name ...;

```

For example:

 
```
CREATE USER foo2@test IDENTIFIED BY 'password';
ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test'

CREATE OR REPLACE USER foo2@test IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)

```

IF NOT EXISTS
-------------

 When the `IF NOT EXISTS` clause is used, MariaDB will return a warning instead of an error if the specified user already exists.

 For example:

 
```
CREATE USER foo2@test IDENTIFIED BY 'password';
ERROR 1396 (HY000): Operation CREATE USER failed for 'foo2'@'test'

CREATE USER IF NOT EXISTS foo2@test IDENTIFIED BY 'password';
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+----------------------------------------------------+
| Level | Code | Message                                            |
+-------+------+----------------------------------------------------+
| Note  | 1973 | Can't create user 'foo2'@'test'; it already exists |
+-------+------+----------------------------------------------------+

```

Authentication Options
----------------------

 ### IDENTIFIED BY 'password'

 The optional `IDENTIFIED BY` clause can be used to provide an account with a password. The password should be specified in plain text. It will be hashed by the [PASSWORD](../password/index) function prior to being stored in the [mysql.user](../mysqluser-table/index)/[mysql.global\_priv\_table](../mysqlglobal_priv-table/index) table.

 For example, if our password is `mariadb`, then we can create the user with:

 
```
CREATE USER foo2@test IDENTIFIED BY 'mariadb';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 ### IDENTIFIED BY PASSWORD 'password\_hash'

 The optional `IDENTIFIED BY PASSWORD` clause can be used to provide an account with a password that has already been hashed. The password should be specified as a hash that was provided by the [PASSWORD](../password/index) function. It will be stored in the [mysql.user](../mysqluser-table/index)/[mysql.global\_priv\_table](../mysqlglobal_priv-table/index) table as-is.

 For example, if our password is `mariadb`, then we can find the hash with:

 
```
SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+
1 row in set (0.00 sec)

```

And then we can create a user with the hash:

 
```
CREATE USER foo2@test IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

```

If you do not specify a password with the `IDENTIFIED BY` clause, the user will be able to connect without a password. A blank password is not a wildcard to match any password. The user must connect without providing a password if no password is set.

 The only [authentication plugins](../authentication-plugins/index) that this clause supports are [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index).

 ### IDENTIFIED {VIA|WITH} authentication\_plugin

 The optional `IDENTIFIED VIA authentication_plugin` allows you to specify that the account should be authenticated by a specific [authentication plugin](../authentication-plugins/index). The plugin name must be an active authentication plugin as per [SHOW PLUGINS](../show-plugins/index). If it doesn't show up in that output, then you will need to install it with [INSTALL PLUGIN](../install-plugin/index) or [INSTALL SONAME](../install-soname/index).

 For example, this could be used with the [PAM authentication plugin](../authentication-plugin-pam/index):

 
```
CREATE USER foo2@test IDENTIFIED VIA pam;

```

Some authentication plugins allow additional arguments to be specified after a `USING` or `AS` keyword. For example, the [PAM authentication plugin](../authentication-plugin-pam/index) accepts a [service name](../authentication-plugin-pam/index#configuring-the-pam-service):

 
```
CREATE USER foo2@test IDENTIFIED VIA pam USING 'mariadb';

```

The exact meaning of the additional argument would depend on the specific authentication plugin.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**The `USING` or `AS` keyword can also be used to provide a plain-text password to a plugin if it's provided as an argument to the [PASSWORD()](../password/index) function. This is only valid for [authentication plugins](../authentication-plugins/index) that have implemented a hook for the [PASSWORD()](../password/index) function. For example, the [ed25519](../authentication-plugin-ed25519/index) authentication plugin supports this:

 
```
CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret');

```



**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**One can specify many authentication plugins, they all work as alternatives ways of authenticating a user:

 
```
CREATE USER safe@'%' IDENTIFIED VIA ed25519 USING PASSWORD('secret') OR unix_socket;

```


By default, when you create a user without specifying an authentication plugin, MariaDB uses the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) plugin.

 TLS Options
-----------

 By default, MariaDB transmits data between the server and clients without encrypting it. This is generally acceptable when the server and client run on the same host or in networks where security is guaranteed through other means. However, in cases where the server and client exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt data in transit between the server and clients using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix ssl\_, but internally, MariaDB only supports its secure successors.

 See [Secure Connections Overview](../secure-connections-overview/index) for more information about how to determine whether your MariaDB server has TLS support.

 You can set certain TLS-related restrictions for specific user accounts. For instance, you might use this with user accounts that require access to sensitive data while sending it across networks that you do not control. These restrictions can be enabled for a user account with the [CREATE USER](index), [ALTER USER](../alter-user/index), or [GRANT](../grant/index) statements. The following options are available:

 


| Option | Description |
| --- | --- |
| `REQUIRE NONE` | TLS is not required for this account, but can still be used. |
| `REQUIRE SSL` | The account must use TLS, but no valid X509 certificate is required. This option cannot be combined with other TLS options. |
| `REQUIRE X509` | The account must use TLS and must have a valid X509 certificate. This option implies `REQUIRE SSL`. This option cannot be combined with other TLS options. |
| `REQUIRE ISSUER 'issuer'` | The account must use TLS and must have a valid X509 certificate. Also, the Certificate Authority must be the one specified via the string `issuer`. This option implies `REQUIRE X509`. This option can be combined with the `SUBJECT`, and `CIPHER` options in any order. |
| `REQUIRE SUBJECT 'subject'` | The account must use TLS and must have a valid X509 certificate. Also, the certificate's Subject must be the one specified via the string `subject`. This option implies `REQUIRE X509`. This option can be combined with the `ISSUER`, and `CIPHER` options in any order. |
| `REQUIRE CIPHER 'cipher'` | The account must use TLS, but no valid X509 certificate is required. Also, the encryption used for the connection must use a specific cipher method specified in the string `cipher`. This option implies `REQUIRE SSL`. This option can be combined with the `ISSUER`, and `SUBJECT` options in any order. |

 
The `REQUIRE` keyword must be used only once for all specified options, and the `AND` keyword can be used to separate individual options, but it is not required.

 For example, you can create a user account that requires these TLS options with the following:

 
```
CREATE USER 'alice'@'%'
 REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
 AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com'
 AND CIPHER 'SHA-DES-CBC3-EDH-RSA';

```

If any of these options are set for a specific user account, then any client who tries to connect with that user account will have to be configured to connect with TLS.

 See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to enable TLS on the client and server.

 Resource Limit Options
----------------------

 It is possible to set per-account limits for certain server resources. The following table shows the values that can be set per account:

 


| Limit Type | Decription |
| --- | --- |
| `MAX_QUERIES_PER_HOUR` | Number of statements that the account can issue per hour (including updates) |
| `MAX_UPDATES_PER_HOUR` | Number of updates (not queries) that the account can issue per hour |
| `MAX_CONNECTIONS_PER_HOUR` | Number of connections that the account can start per hour |
| `MAX_USER_CONNECTIONS` | Number of simultaneous connections that can be accepted from the same account; if it is 0, `max_connections` will be used instead; if `max_connections` is 0, there is no limit for this account's simultaneous connections. |
| `MAX_STATEMENT_TIME` | Timeout, in seconds, for statements executed by the user. See also [Aborting Statements that Exceed a Certain Time to Execute](../aborting-statements/index). |

 
If any of these limits are set to `0`, then there is no limit for that resource for that user.

 Here is an example showing how to create a user with resource limits:

 
```
CREATE USER 'someone'@'localhost' WITH
    MAX_USER_CONNECTIONS 10
    MAX_QUERIES_PER_HOUR 200;

```

The resources are tracked per account, which means `'user'@'server'`; not per user name or per connection.

 The count can be reset for all users using [FLUSH USER\_RESOURCES](../flush/index), [FLUSH PRIVILEGES](../flush/index) or [mariadb-admin reload](../mariadb-admin/index).

 Per account resource limits are stored in the [user](../mysqluser-table/index) table, in the [mysql](../the-mysql-database-tables/index) database. Columns used for resources limits are named `max_questions`, `max_updates`, `max_connections` (for `MAX_CONNECTIONS_PER_HOUR`), and `max_user_connections` (for `MAX_USER_CONNECTIONS`).

 Account Names
-------------

 Account names have both a user name component and a host name component, and are specified as `'user_name'@'host_name'`.

 The user name and host name may be unquoted, quoted as strings using double quotes (`"`) or single quotes (`'`), or quoted as identifiers using backticks (```). You must use quotes when using special characters (such as a hyphen) or wildcard characters. If you quote, you must quote the user name and host name separately (for example `'user_name'@'host_name'`).

 ### Host Name Component

 If the host name is not provided, it is assumed to be `'%'`.

 Host names may contain the wildcard characters `%` and `_`. They are matched as if by the [LIKE](../like/index) clause. If you need to use a wildcard character literally (for example, to match a domain name with an underscore), prefix the character with a backslash. See `LIKE` for more information on escaping wildcard characters.

 Host name matches are case-insensitive. Host names can match either domain names or IP addresses. Use `'localhost'` as the host name to allow only local client connections. On Linux, the loopback interface (127.0.0.1) will not match 'localhost' as it is not considered a local connection: this means that only connections via UNIX-domain sockets will match 'localhost'.

 You can use a netmask to match a range of IP addresses using `'base_ip/netmask'` as the host name. A user with an IP address *ip\_addr* will be allowed to connect if the following condition is true:

 
```
ip_addr & netmask = base_ip

```

For example, given a user:

 
```
CREATE USER 'maria'@'247.150.130.0/255.255.255.0';

```

the IP addresses satisfying this condition range from 247.150.130.0 to 247.150.130.255. 

 Using `255.255.255.255` is equivalent to not using a netmask at all. Netmasks cannot be used for IPv6 addresses. 

 Note that the credentials added when creating a user with the `'%'` wildcard host will not grant access in all cases. For example, some systems come with an anonymous localhost user, and when connecting from localhost this will take precedence.

 Before [MariaDB 10.6](../what-is-mariadb-106/index), the host name component could be up to 60 characters in length. Starting from [MariaDB 10.6](../what-is-mariadb-106/index), it can be up to 255 characters.

 ### User Name Component

 User names must match exactly, including case. A user name that is empty is known as an anonymous account and is allowed to match a login attempt with any user name component. These are described more in the next section.

 For valid identifiers to use as user names, see [Identifier Names](../identifier-names/index).

 It is possible for more than one account to match when a user connects. MariaDB selects the first matching account after sorting according to the following criteria:

 * Accounts with an exact host name are sorted before accounts using a wildcard in the host name. Host names using a netmask are considered to be exact for sorting.
* Accounts with a wildcard in the host name are sorted according to the position of the first wildcard character. Those with a wildcard character later in the host name sort before those with a wildcard character earlier in the host name.
* Accounts with a non-empty user name sort before accounts with an empty user name.
* Accounts with an empty user name are sorted last. As mentioned previously, these are known as anonymous accounts. These are described more in the next section.

 The following table shows a list of example account as sorted by these criteria:

 
```
+---------+-------------+
| User    | Host        |
+---------+-------------+
| joffrey | 192.168.0.3 |
|         | 192.168.0.% |
| joffrey | 192.168.%   |
|         | 192.168.%   |
+---------+-------------+

```

Once connected, you only have the privileges granted to the account that matched, not all accounts that could have matched. For example, consider the following commands:

 
```
CREATE USER 'joffrey'@'192.168.0.3';
CREATE USER 'joffrey'@'%';
GRANT SELECT ON test.t1 to 'joffrey'@'192.168.0.3';
GRANT SELECT ON test.t2 to 'joffrey'@'%';

```

If you connect as joffrey from `192.168.0.3`, you will have the `SELECT` privilege on the table `test.t1`, but not on the table `test.t2`. If you connect as joffrey from any other IP address, you will have the `SELECT` privilege on the table `test.t2`, but not on the table `test.t1`.

 Usernames can be up to 80 characters long before 10.6 and starting from 10.6 it can be 128 characters long.

 ### Anonymous Accounts

 Anonymous accounts are accounts where the user name portion of the account name is empty. These accounts act as special catch-all accounts. If a user attempts to log into the system from a host, and an anonymous account exists with a host name portion that matches the user's host, then the user will log in as the anonymous account if there is no more specific account match for the user name that the user entered.

 For example, here are some anonymous accounts:

 
```
CREATE USER ''@'localhost';
CREATE USER ''@'192.168.0.3';

```

#### Fixing a Legacy Default Anonymous Account

 On some systems, the [mysql.db](../mysqldb-table/index) table has some entries for the `''@'%'` anonymous account by default. Unfortunately, there is no matching entry in the [mysql.user](../mysqluser-table/index)/[mysql.global\_priv\_table](../mysqlglobal_priv-table/index) table, which means that this anonymous account doesn't exactly exist, but it does have privileges--usually on the default `test` database created by [mariadb-install-db](../mariadb-install-db/index). These account-less privileges are a legacy that is leftover from a time when MySQL's privilege system was less advanced.

 This situation means that you will run into errors if you try to create a `''@'%'` account. For example:

 
```
CREATE USER ''@'%';
ERROR 1396 (HY000): Operation CREATE USER failed for ''@'%'

```

The fix is to [DELETE](../delete/index) the row in the [mysql.db](../mysqldb-table/index) table and then execute [FLUSH PRIVILEGES](../flush/index):

 
```
DELETE FROM mysql.db WHERE User='' AND Host='%';
FLUSH PRIVILEGES;

```

And then the account can be created:

 
```
CREATE USER ''@'%';
Query OK, 0 rows affected (0.01 sec)

```

See [MDEV-13486](https://jira.mariadb.org/browse/MDEV-13486) for more information.

 Password Expiry
---------------

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Besides automatic password expiry, as determined by [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime), password expiry times can be set on an individual user basis, overriding the global setting, for example:

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

```

See [User Password Expiry](../user-password-expiry/index) for more details.

 
Account Locking
---------------

 
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**Account locking permits privileged administrators to lock/unlock user accounts. No new client connections will be permitted if an account is locked (existing connections are not affected). For example:

 
```
CREATE USER 'marijn'@'localhost' ACCOUNT LOCK;

```

See [Account Locking](../account-locking/index) for more details.

 
From [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) and [MariaDB 10.5.8](https://mariadb.com/kb/en/mariadb-1058-release-notes/), the *lock\_option* and *password\_option* clauses can occur in either order.

 See Also
--------

 * [Troubleshooting Connection Issues](../troubleshooting-connection-issues/index)
* [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [Identifier Names](../identifier-names/index)
* [GRANT](../grant/index)
* [ALTER USER](../alter-user/index)
* [RENAME USER](../rename-user/index)
* [DROP USER](../drop-user/index)
* [SET PASSWORD](../set-password/index)
* [SHOW CREATE USER](../show-create-user/index)
* [mysql.user table](../mysqluser-table/index)
* [mysql.global\_priv\_table](../mysqlglobal_priv-table/index)
* [Password Validation Plugins](../password-validation-plugins/index) - permits the setting of basic criteria for passwords
* [Authentication Plugins](../authentication-plugins/index) - allow various authentication methods to be used, and new ones to be developed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-user/>

CREATE ROLE
===========

    Syntax
------

 
```
CREATE [OR REPLACE] ROLE [IF NOT EXISTS] role 
  [WITH ADMIN 
    {CURRENT_USER | CURRENT_ROLE | user | role}]

```
 Description
-----------

 The `CREATE ROLE` statement creates one or more MariaDB [roles](../roles/index). To use it, you must have the global [CREATE USER](../grant/index#create-user) privilege or the [INSERT](../grant/index#table-privileges) privilege for the mysql database. For each account, `CREATE ROLE` creates a new row in the [mysql.user](../mysqluser-table/index) table that has no privileges, and with the corresponding `is_role` field set to `Y`. It also creates a record in the [mysql.roles\_mapping](../mysqlroles_mapping-table/index) table.

 If any of the specified roles already exist, `ERROR 1396 (HY000)` results. If an error occurs, `CREATE ROLE` will still create the roles that do not result in an error. The maximum length for a role is 128 characters. Role names can be quoted, as explained in the [Identifier names](../identifier-names/index) page. Only one error is produced for all roles which have not been created:

 
```
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'a','b','c'

```

Failed `CREATE` or `DROP` operations, for both users and roles, produce the same error code.

 `PUBLIC` and `NONE` are reserved, and cannot be used as role names. `NONE` is used to [unset a role](../set-role/index) and `PUBLIC` has a special use in other systems, such as Oracle, so is reserved for compatibility purposes.

 For valid identifiers to use as role names, see [Identifier Names](../identifier-names/index).

 #### WITH ADMIN

 The optional `WITH ADMIN` clause determines whether the current user, the current role or another user or role has use of the newly created role. If the clause is omitted, `WITH ADMIN CURRENT_USER` is treated as the default, which means that the current user will be able to [GRANT](../grant/index#roles) this role to users.

 #### OR REPLACE

 If the optional `OR REPLACE` clause is used, it acts as a shortcut for:

 
```
DROP ROLE IF EXISTS name;
CREATE ROLE name ...;

```

#### IF NOT EXISTS

 When the `IF NOT EXISTS` clause is used, MariaDB will return a warning instead of an error if the specified role already exists. Cannot be used together with the `OR REPLACE` clause.

 Examples
--------

 
```
CREATE ROLE journalist;

CREATE ROLE developer WITH ADMIN lorinda@localhost;

```

Granting the role to another user. Only user `lorinda@localhost` has permission to grant the `developer` role:

 
```
 SELECT USER();
+-------------------+
| USER()            |
+-------------------+
| henning@localhost |
+-------------------+
...
GRANT developer TO ian@localhost;
Access denied for user 'henning'@'localhost'

 SELECT USER();
+-------------------+
| USER()            |
+-------------------+
| lorinda@localhost |
+-------------------+

GRANT m_role TO ian@localhost;

```

The `OR REPLACE` and `IF NOT EXISTS` clauses. The `journalist` role already exists:

 
```
CREATE ROLE journalist;
ERROR 1396 (HY000): Operation CREATE ROLE failed for 'journalist'

CREATE OR REPLACE ROLE journalist;
Query OK, 0 rows affected (0.00 sec)

CREATE ROLE IF NOT EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)

```


```
SHOW WARNINGS;
+-------+------+---------------------------------------------------+
| Level | Code | Message                                           |
+-------+------+---------------------------------------------------+
| Note  | 1975 | Can't create role 'journalist'; it already exists |
+-------+------+---------------------------------------------------+


```

See Also
--------

 * [Identifier Names](../identifier-names/index)
* [Roles Overview](../roles-overview/index)
* [DROP ROLE](../drop-role/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-role/>

CREATE SEQUENCE
===============

    Syntax
------

 
```
CREATE [OR REPLACE] [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name
[ INCREMENT [ BY | = ] increment ]
[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]
[ MAXVALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]
[ START [ WITH | = ] start ] 
[ CACHE [=] cache | NOCACHE ] [ CYCLE | NOCYCLE] 
[table_options]
```

 The options for `CREATE SEQUENCE` can be given in any order, optionally followed by `table_options`.

 *table\_options* can be any of the normal table options in [CREATE TABLE](../create-table/index) but the most usable ones are `ENGINE=...` and `COMMENT=`.

 `NOMAXVALUE` and `NOMINVALUE` are there to allow one to create SEQUENCEs using the Oracle syntax.

 Description
-----------

 CREATE SEQUENCE will create a sequence that generates new values when called with `NEXT VALUE FOR sequence_name`. It's an alternative to [AUTO INCREMENT](../auto_increment/index) when one wants to have more control of how the numbers are generated. As the SEQUENCE caches values (up to `CACHE`) it can in some cases be much faster than [AUTO INCREMENT](../auto_increment/index). Another benefit is that one can access the last value generated by all used sequences, which solves one of the limitations with [LAST\_INSERT\_ID()](../last_insert_id/index).

 CREATE SEQUENCE requires the [CREATE privilege](../grant/index).

 [DROP SEQUENCE](../drop-sequence/index) can be used to drop a sequence, and [ALTER SEQUENCE](../alter-sequence/index) to change it.

 ### Arguments to Create

 The following options may be used:

 


| Option | Default value |  Description |
| --- | --- | --- |
| INCREMENT |  1 | Increment to use for values. May be negative. Setting an increment of 0 causes the sequence to use the value of the [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) system variable at the time of creation, which is always a positive number. (see [MDEV-16035](https://jira.mariadb.org/browse/MDEV-16035)). |
| MINVALUE | 1 if INCREMENT > 0 and -9223372036854775807 if INCREMENT < 0 | Minimum value for the sequence |
| MAXVALUE | 9223372036854775806 if INCREMENT > 0 and -1 if INCREMENT < 0 | Max value for sequence |
| START | MINVALUE if INCREMENT > 0 and MAX\_VALUE if INCREMENT< 0 | First value that the sequence will generate |
| CACHE | 1000 |  Number of values that should be cached. 0 if no CACHE. The underlying table will be updated first time a new sequence number is generated and each time the cache runs out. |

 
If `CYCLE` is used then the sequence should start again from `MINVALUE` after it has run out of values. Default value is `NOCYCLE`.

 ### Constraints on Create Arguments

 To be able to create a legal sequence, the following must hold:

 * MAXVALUE >= start
* MAXVALUE > MINVALUE
* START >= MINVALUE
* MAXVALUE <= 9223372036854775806 (LONGLONG\_MAX-1)
* MINVALUE >= -9223372036854775807 (LONGLONG\_MIN+1)

 Note that sequences can't generate the maximum/minimum 64 bit number because of the constraint of `MINVALUE` and `MAXVALUE`. 

 ### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index) and `CREATE SEQUENCE` is atomic.

 
Examples
--------

 
```
CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

CREATE SEQUENCE s2 START WITH -100 INCREMENT BY -10;

```

The following statement fails, as the increment conflicts with the defaults

 
```
CREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10;
ERROR 4082 (HY000): Sequence 'test.s3' values are conflicting

```

The sequence can be created by specifying workable minimum and maximum values:

 
```
CREATE SEQUENCE s3 START WITH -100 INCREMENT BY 10 MINVALUE=-100 MAXVALUE=1000;

```

See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [DROP SEQUENCE](../drop-sequence/index)
* [NEXT VALUE FOR](../next-value-for-sequence_name/index)
* [PREVIOUS VALUE FOR](../previous-value-for-sequence_name/index)
* [SETVAL()](../setval/index). Set next value for the sequence.
* [AUTO INCREMENT](../auto_increment/index)
* [SHOW CREATE SEQUENCE](../show-create-sequence/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-sequence/>

DROP DATABASE
=============

    Syntax
------

 
```
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

```
 Description
-----------

 `DROP DATABASE` drops all tables in the database and deletes the database. Be very careful with this statement! To use DROP DATABASE, you need the [DROP privilege](../grant/index#table-privileges) on the database. `DROP SCHEMA` is a synonym for `DROP DATABASE`.

 **Important:** When a database is dropped, user privileges on the database are not automatically dropped. See [GRANT](../grant/index).

 #### IF EXISTS

 Use `IF EXISTS` to prevent an error from occurring for databases that do not exist. A `NOTE` is generated for each non-existent database when using `IF EXISTS`. See [SHOW WARNINGS](../show-warnings/index).

 ### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index). 

 `DROP DATABASE` is implemented as

 
```
loop over all tables
  DROP TABLE table

```

Each individual [DROP TABLE](../drop-table/index) is atomic while `DROP DATABASE` as a whole is crash-safe.

 
Examples
--------

 
```
DROP DATABASE bufg;
Query OK, 0 rows affected (0.39 sec)

DROP DATABASE bufg;
ERROR 1008 (HY000): Can't drop database 'bufg'; database doesn't exist

 \W
Show warnings enabled.

DROP DATABASE IF EXISTS bufg;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Note (Code 1008): Can't drop database 'bufg'; database doesn't exist

```

See Also
--------

 * [CREATE DATABASE](../create-database/index)
* [ALTER DATABASE](../alter-database/index)
* [SHOW DATABASES](../show-databases/index)
* [Information Schema SCHEMATA Table](../information-schema-schemata-table/index)
* [SHOW CREATE DATABASE](../show-create-database/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-database/>

DO
==

    Syntax
------

 
```
DO expr [, expr] ...

```

Description
-----------

  `DO` executes the expressions but does not return any results. In most respects, `DO` is shorthand for `SELECT expr, ...,` but has the advantage that it is slightly faster when you do not care about the result.

  `DO` is useful primarily with functions that have side effects, such as `[RELEASE\_LOCK()](../release_lock/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/do/>

DROP INDEX
==========

    Syntax
------

 
```
DROP INDEX [IF EXISTS] index_name ON tbl_name 
    [WAIT n |NOWAIT]

```
 Description
-----------

 `DROP INDEX` drops the [index](../optimization-and-indexes/index) named `index_name` from the table `tbl_name`. This statement is mapped to an `ALTER TABLE` statement to drop the index.

 If another connection is using the table, a [metadata lock](../metadata-locking/index) is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.

 See [ALTER TABLE](../alter-table/index).

 Another shortcut, [CREATE INDEX](../create-index/index), allows the creation of an index.

 To remove the primary key, ``PRIMARY`` must be specified as index\_name. Note that [the quotes](../identifier-qualifiers/index) are necessary, because `PRIMARY` is a keyword.

 Privileges
----------

 Executing the `DROP INDEX` statement requires the `[INDEX](../grant/index#table-privileges)` privilege for the table or the database.

 Online DDL
----------

 Online DDL is used by default with InnoDB, when the drop index operation supports it.

 See [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index) for more information on online DDL with [InnoDB](../innodb/index).

 DROP INDEX IF EXISTS ...
------------------------

 If the `IF EXISTS` clause is used, then MariaDB will return a warning instead of an error if the index does not exist.

 WAIT/NOWAIT
-----------

 Sets the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 Progress Reporting
------------------

 MariaDB provides progress reporting for `DROP INDEX` statement for clients that support the new progress reporting protocol. For example, if you were using the [mariadb](../mariadb-command-line-client/index) client, then the progress report might look like this::

 See Also
--------

 * [Getting Started with Indexes](../getting-started-with-indexes/index)
* [CREATE INDEX](../create-index/index)
* [ALTER TABLE](../alter-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-index/>

DROP FUNCTION
=============

    Syntax
------

 
```
DROP FUNCTION [IF EXISTS] f_name

```
 Description
-----------

 The DROP FUNCTION statement is used to drop a [stored function](../stored-functions/index) or a user-defined function (UDF). That is, the specified routine is removed from the server, along with all privileges specific to the function. You must have the `ALTER ROUTINE` [privilege](../grant/index) for the routine in order to drop it. If the [automatic\_sp\_privileges](../server-system-variables/index#automatic_sp_privileges) server system variable is set, both the `ALTER ROUTINE` and `EXECUTE` privileges are granted automatically to the routine creator - see [Stored Routine Privileges](../stored-routine-privileges/index).

 #### IF EXISTS

 The `IF EXISTS` clause is a MySQL/MariaDB extension. It prevents an error from occurring if the function does not exist. A `NOTE` is produced that can be viewed with [SHOW WARNINGS](../show-warnings/index).

 For dropping a [user-defined functions](../user-defined-functions/index) (UDF), see [DROP FUNCTION UDF](../drop-function-udf/index).

 Examples
--------

 
```
DROP FUNCTION hello;
Query OK, 0 rows affected (0.042 sec)

DROP FUNCTION hello;
ERROR 1305 (42000): FUNCTION test.hello does not exist

DROP FUNCTION IF EXISTS hello;
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1305 | FUNCTION test.hello does not exist |
+-------+------+------------------------------------+

```

See Also
--------

 * [DROP PROCEDURE](../drop-procedure/index)
* [Stored Function Overview](../stored-function-overview/index)
* [CREATE FUNCTION](../create-function/index)
* [CREATE FUNCTION UDF](../create-function-udf/index)
* [ALTER FUNCTION](../alter-function/index)
* [SHOW CREATE FUNCTION](../show-create-function/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [INFORMATION\_SCHEMA ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-function/>

DROP PROCEDURE
==============

    Syntax
------

 
```
DROP PROCEDURE [IF EXISTS] sp_name

```
 Description
-----------

 This statement is used to drop a [stored procedure](../stored-procedures/index). That is, the specified routine is removed from the server along with all privileges specific to the [procedure](../grant/index). You must have the `ALTER ROUTINE` privilege for the routine. If the `[automatic\_sp\_privileges](../server-system-variables/index#automatic_sp_privileges)` server system variable is set, that privilege and `EXECUTE` are granted automatically to the routine creator - see [Stored Routine Privileges](../stored-routine-privileges/index).

 The `IF EXISTS` clause is a MySQL/MariaDB extension. It prevents an error from occurring if the procedure or function does not exist. A `NOTE` is produced that can be viewed with `[SHOW WARNINGS](../show-warnings/index)`.

 While this statement takes effect immediately, threads which are executing a procedure can continue execution.

 Examples
--------

 
```
DROP PROCEDURE simpleproc;

```

IF EXISTS:

 
```
DROP PROCEDURE simpleproc;
ERROR 1305 (42000): PROCEDURE test.simpleproc does not exist

DROP PROCEDURE IF EXISTS simpleproc;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Note  | 1305 | PROCEDURE test.simpleproc does not exist |
+-------+------+------------------------------------------+

```

See Also
--------

 * [DROP FUNCTION](../drop-function/index)
* [Stored Procedure Overview](../stored-procedure-overview/index)
* [CREATE PROCEDURE](../create-procedure/index)
* [ALTER PROCEDURE](index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-procedure/>

DEALLOCATE / DROP PREPARE
=========================

    Syntax
------

 
```
{DEALLOCATE | DROP} PREPARE stmt_name

```

Description
-----------

 To deallocate a prepared statement produced with `[PREPARE](../prepare-statement/index)`, use a `DEALLOCATE PREPARE` statement that refers to the prepared statement name.

 A prepared statement is implicitly deallocated when a new `PREPARE` command is issued. In that case, there is no need to use `DEALLOCATE`.

 Attempting to execute a prepared statement after deallocating it results in an error, as if it was not prepared at all:

 
```
ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to EXECUTE

```

If the specified statement has not been PREPAREd, an error similar to the following will be produced:

 
```
ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to DEALLOCATE PREPARE

```

Example
-------

 See [example in PREPARE](../prepare-statement/index#example).

 See Also
--------

 * [PREPARE Statement](../prepare-statement/index)
* [EXECUTE Statement](../execute-statement/index)
* [EXECUTE IMMEDIATE](../execute-immediate/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/deallocate-drop-prepared-statement/>

DROP ROLE
=========

    Syntax
------

 
```
DROP ROLE [IF EXISTS] role_name [,role_name ...]

```
 Description
-----------

 The `DROP ROLE` statement removes one or more MariaDB [roles](../roles/index). To use this statement, you must have the global [CREATE USER](../grant/index#create-user) privilege or the [DELETE](../grant/index#table-privileges) privilege for the mysql database.

 `DROP ROLE` does not disable roles for connections which selected them with [SET ROLE](../set-role/index). If a role has previously been set as a [default role](../set-default-role/index), `DROP ROLE` does not remove the record of the default role from the [mysql.user](../mysqluser-table/index) table. If the role is subsequently recreated and granted, it will again be the user's default. Use [SET DEFAULT ROLE NONE](../set-default-role/index) to explicitly remove this.

 If any of the specified user accounts do not exist, `ERROR 1396 (HY000)` results. If an error occurs, `DROP ROLE` will still drop the roles that do not result in an error. Only one error is produced for all roles which have not been dropped:

 
```
ERROR 1396 (HY000): Operation DROP ROLE failed for 'a','b','c'

```

Failed `CREATE` or `DROP` operations, for both users and roles, produce the same error code.

 #### IF EXISTS

 If the `IF EXISTS` clause is used, MariaDB will return a warning instead of an error if the role does not exist.

 Examples
--------

 
```
DROP ROLE journalist;

```

The same thing using the optional `IF EXISTS` clause:

 
```
DROP ROLE journalist;
ERROR 1396 (HY000): Operation DROP ROLE failed for 'journalist'

DROP ROLE IF EXISTS journalist;
Query OK, 0 rows affected, 1 warning (0.00 sec)

Note (Code 1975): Can't drop role 'journalist'; it doesn't exist

```

See Also
--------

 * [Roles Overview](../roles-overview/index)
* [CREATE ROLE](../create-role/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-role/>

DROP EVENT
==========

    Syntax
------

 
```
DROP EVENT [IF EXISTS] event_name

```

Description
-----------

 This statement drops the [event](../events/index) named `event_name`. The event immediately ceases being active, and is deleted completely from the server.

 If the event does not exist, the error `ERROR 1517 (HY000): Unknown event 'event_name'` results. You can override this and cause the statement to generate a `NOTE` for non-existent events instead by using `IF EXISTS`. See `[SHOW WARNINGS](../show-warnings/index)`.

 This statement requires the `[EVENT](../grant/index#database-privileges)` privilege. In MySQL 5.1.11 and earlier, an event could be dropped only by its definer, or by a user having the `[SUPER](../grant/index#global-privileges)` privilege.

 Examples
--------

 
```
DROP EVENT myevent3;

```

Using the IF EXISTS clause:

 
```
DROP EVENT IF EXISTS myevent3;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1305 | Event myevent3 does not exist |
+-------+------+-------------------------------+

```

See also
--------

 * [Events Overview](../events-overview/index)
* [CREATE EVENT](../create-event/index)
* [SHOW CREATE EVENT](../show-create-event/index)
* [ALTER EVENT](../alter-event/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-event/>

DROP SEQUENCE
=============

    Syntax
------

 
```
DROP [TEMPORARY] SEQUENCE [IF EXISTS] [/*COMMENT TO SAVE*/]
    sequence_name [, sequence_name] ...
```
 Description
-----------

 `DROP SEQUENCE` removes one or more [sequences](../sequences/index) created with [CREATE SEQUENCE](../create-sequence/index). You must have the `DROP` privilege for each sequence. MariaDB returns an error indicating by name which non-existing tables it was unable to drop, but it also drops all of the tables in the list that do exist.

 Important: When a table is dropped, user privileges on the table are not automatically dropped. See [GRANT](../grant/index).

 If another connection is using the sequence, a metadata lock is active, and this statement will wait until the lock is released. This is also true for non-transactional tables.

 For each referenced sequence, DROP SEQUENCE drops a temporary sequence with that name, if it exists. If it does not exist, and the `TEMPORARY` keyword is not used, it drops a non-temporary sequence with the same name, if it exists. The `TEMPORARY` keyword ensures that a non-temporary sequence will not accidentally be dropped.

 Use `IF EXISTS` to prevent an error from occurring for sequences that do not exist. A NOTE is generated for each non-existent sequence when using `IF EXISTS`. See [SHOW WARNINGS](../show-warnings/index).

 DROP SEQUENCE requires the [DROP privilege](../grant/index).

 Notes
-----

 DROP SEQUENCE only removes sequences, not tables. However, [DROP TABLE](../drop-table/index) can remove both sequences and tables.

 See Also
--------

 * [Sequence Overview](../sequence-overview/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [DROP TABLE](../drop-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-sequence/>

DROP TABLE
==========

    Syntax
------

 
```
DROP [TEMPORARY] TABLE [IF EXISTS] [/*COMMENT TO SAVE*/]
    tbl_name [, tbl_name] ...
    [WAIT n|NOWAIT]
    [RESTRICT | CASCADE]

```
 Description
-----------

 `DROP TABLE` removes one or more tables. You must have the `DROP` privilege for each table. All table data and the table definition are removed, as well as [triggers](../triggers/index) associated to the table, so be careful with this statement! If any of the tables named in the argument list do not exist, MariaDB returns an error indicating by name which non-existing tables it was unable to drop, but it also drops all of the tables in the list that do exist.

 **Important**: When a table is dropped, user privileges on the table are not automatically dropped. See [GRANT](../grant/index).

 If another thread is using the table in an explicit transaction or an autocommit transaction, then the thread acquires a [metadata lock (MDL)](../metadata-locking/index) on the table. The `DROP TABLE` statement will wait in the "Waiting for table metadata lock" [thread state](../thread-states/index) until the MDL is released. MDLs are released in the following cases:

 * If an MDL is acquired in an explicit transaction, then the MDL will be released when the transaction ends.
* If an MDL is acquired in an autocommit transaction, then the MDL will be released when the statement ends.
* Transactional and non-transactional tables are handled the same.

 Note that for a partitioned table, `DROP TABLE` permanently removes the table definition, all of its partitions, and all of the data which was stored in those partitions. It also removes the partitioning definition (.par) file associated with the dropped table.

 For each referenced table, `DROP TABLE` drops a temporary table with that name, if it exists. If it does not exist, and the `TEMPORARY` keyword is not used, it drops a non-temporary table with the same name, if it exists. The `TEMPORARY` keyword ensures that a non-temporary table will not accidentally be dropped.

 Use `IF EXISTS` to prevent an error from occurring for tables that do not exist. A `NOTE` is generated for each non-existent table when using `IF EXISTS`. See [SHOW WARNINGS](../show-warnings/index).

 If a [foreign key](../foreign-keys/index) references this table, the table cannot be dropped. In this case, it is necessary to drop the foreign key first.

 `RESTRICT` and `CASCADE` are allowed to make porting from other database systems easier. In MariaDB, they do nothing.

 The comment before the table names (`/*COMMENT TO SAVE*/`) is stored in the [binary log](../binary-log/index). That feature can be used by replication tools to send their internal messages.

 It is possible to specify table names as `db_name`.`tab_name`. This is useful to delete tables from multiple databases with one statement. See [Identifier Qualifiers](../identifier-qualifiers/index) for details.

 The [DROP privilege](../grant/index#table-privileges) is required to use `DROP TABLE` on non-temporary tables. For temporary tables, no privilege is required, because such tables are only visible for the current session.

 **Note:** `DROP TABLE` automatically commits the current active transaction, unless you use the `TEMPORARY` keyword.

 
**MariaDB starting with [10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)**From [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/), `DROP TABLE` reliably deletes table remnants inside a storage engine even if the `.frm` file is missing. Before then, a missing `.frm` file would result in the statement failing.

 

**MariaDB starting with [10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)**### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 
DROP TABLE in replication
-------------------------

 `DROP TABLE` has the following characteristics in [replication](../replication/index):

 * `DROP TABLE IF EXISTS` are always logged.
* `DROP TABLE` without `IF EXISTS` for tables that don't exist are not written to the [binary log](../binary-log/index).
* Dropping of `TEMPORARY` tables are prefixed in the log with `TEMPORARY`. These drops are only logged when running [statement](../binary-log-formats/index#statement-based) or [mixed mode](../binary-log-formats/index#mixed) replication.
* One `DROP TABLE` statement can be logged with up to 3 different `DROP` statements:
	+ `DROP TEMPORARY TABLE list_of_non_transactional_temporary_tables`
	+ `DROP TEMPORARY TABLE list_of_transactional_temporary_tables`
	+ `DROP TABLE list_of_normal_tables`

 `DROP TABLE` on the primary is treated on the replica as `DROP TABLE IF EXISTS`. You can change that by setting [slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode) to `STRICT`.

 Dropping an Internal #sql-... Table
-----------------------------------

 From [MariaDB 10.6](../what-is-mariadb-106/index), [DROP TABLE is atomic](#atomic-drop-table) and the following does not apply. Until [MariaDB 10.5](../what-is-mariadb-105/index), if the [mariadbd/mysqld process](../mysqld-options/index) is killed during an [ALTER TABLE](../alter-table/index) you may find a table named #sql-... in your data directory. In [MariaDB 10.3](../what-is-mariadb-103/index), InnoDB tables with this prefix will be deleted automatically during startup. From [MariaDB 10.4](../what-is-mariadb-104/index), these temporary tables will always be deleted automatically.

 If you want to delete one of these tables explicitly you can do so by using the following syntax:

 
```
DROP TABLE `#mysql50##sql-...`;

```

When running an `ALTER TABLE…ALGORITHM=INPLACE` that rebuilds the table, InnoDB will create an internal `#sql-ib` table. Until [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), for these tables, the `.frm` file will be called something else. In order to drop such a table after a server crash, you must rename the `#sql*.frm` file to match the `#sql-ib*.ibd` file.

 From [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), the same name as the .frm file is used for the intermediate copy of the table. The #sql-ib names are used by TRUNCATE and delayed DROP.

 From [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), the #sql-ib tables will be deleted automatically.

 Dropping All Tables in a Database
---------------------------------

 The best way to drop all tables in a database is by executing [DROP DATABASE](../drop-database/index), which will drop the database itself, and all tables in it.

 However, if you want to drop all tables in the database, but you also want to keep the database itself and any other non-table objects in it, then you would need to execute `DROP TABLE` to drop each individual table. You can construct these `DROP TABLE` commands by querying the [TABLES](../information-schema-tables-table/index) table in the [information\_schema](../information-schema-tables/index) database. For example:

 
```
SELECT CONCAT('DROP TABLE IF EXISTS `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb';

```

Atomic DROP TABLE
-----------------

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**From [MariaDB 10.6](../what-is-mariadb-106/index), `DROP TABLE` for a single table is atomic ([MDEV-25180](https://jira.mariadb.org/browse/MDEV-25180)) for most engines, including InnoDB, MyRocks, MyISAM and Aria.

 This means that if there is a crash (server down or power outage) during `DROP TABLE`, all tables that have been processed so far will be completely dropped, including related trigger files and status entries, and the [binary log](../binary-log/index) will include a `DROP TABLE` statement for the dropped tables. Tables for which the drop had not started will be left intact.

 In older MariaDB versions, there was a small chance that, during a server crash happening in the middle of `DROP TABLE`, some storage engines that were using multiple storage files, like [MyISAM](../myisam-storage-engine/index), could have only a part of its internal files dropped.

 In [MariaDB 10.5](../what-is-mariadb-105/index), `DROP TABLE` was extended to be able to delete a table that was only partly dropped ([MDEV-11412](https://jira.mariadb.org/browse/MDEV-11412)) as explained above. Atomic `DROP TABLE` is the final piece to make `DROP TABLE` fully reliable.

 Dropping multiple tables is crash-safe.

 See [Atomic DDL](../atomic-ddl/index) for more information.

 
Examples
--------

 
```
DROP TABLE Employees, Customers;

```

Notes
-----

 Beware that `DROP TABLE` can drop both tables and [sequences](../create-sequence/index). This is mainly done to allow old tools like [mariadb-dump](../mariadb-dump/index) (previously mysqldump) to work with sequences.

 See Also
--------

 * [CREATE TABLE](../create-table/index)
* [ALTER TABLE](../alter-table/index)
* [SHOW CREATE TABLE](../show-create-table/index)
* [DROP SEQUENCE](../drop-sequence/index)
* Variable [slave-ddl-exec-mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-table/>

DROP TRIGGER
============

    Syntax
------

 
```
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

```
 Description
-----------

 This statement drops a [trigger](../triggers/index). The schema (database) name is optional. If the schema is omitted, the trigger is dropped from the default schema. Its use requires the `TRIGGER` privilege for the table associated with the trigger.

 Use `IF EXISTS` to prevent an error from occurring for a trigger that does not exist. A `NOTE` is generated for a non-existent trigger when using `IF EXISTS`. See [SHOW WARNINGS](../show-warnings/index).

 **Note:** Triggers for a table are also dropped if you drop the table.

 ### Atomic DDL

 
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**[MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) supports [Atomic DDL](../atomic-ddl/index) and `DROP TRIGGER` is atomic.

 
Examples
--------

 
```
DROP TRIGGER test.example_trigger;

```

Using the IF EXISTS clause:

 
```
DROP TRIGGER IF EXISTS test.example_trigger;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1360 | Trigger does not exist |
+-------+------+------------------------+

```

See Also
--------

 * [Trigger Overview](../trigger-overview/index)
* [CREATE TRIGGER](../create-trigger/index)
* [Information Schema TRIGGERS Table](../information-schema-triggers-table/index)
* [SHOW TRIGGERS](../show-triggers/index)
* [SHOW CREATE TRIGGER](../show-create-trigger/index)
* [Trigger Limitations](../trigger-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-trigger/>

EXECUTE Statement
=================

    Syntax
------

 
```
EXECUTE stmt_name
    [USING expression[, expression] ...]

```
 
**MariaDB starting with [10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)**`EXECUTE` with expression as parameters was introduced in [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/). Before that one could only use variables (@var\_name) as parameters.

 
Description
-----------

 After preparing a statement with `[PREPARE](../prepare-statement/index)`, you execute it with an `EXECUTE` statement that refers to the prepared statement name. If the prepared statement contains any parameter markers, you must supply a `USING` clause that lists user variables containing the values to be bound to the parameters. Parameter values can be supplied only by user variables, and the `USING` clause must name exactly as many variables as the number of parameter markers in the statement.

 You can execute a given prepared statement multiple times, passing different variables to it or setting the variables to different values before each execution.

 If the specified statement has not been PREPAREd, an error similar to the following is produced:

 
```
ERROR 1243 (HY000): Unknown prepared statement handler (stmt_name) given to EXECUTE

```

Example
-------

 See [example in PREPARE](../prepare-statement/index#example).

 See Also
--------

 * [EXECUTE IMMEDIATE](../execute-immediate/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/execute-statement/>

DROP USER
=========

    Syntax
------

 
```
DROP USER [IF EXISTS] user_name [, user_name] ...

```
 Description
-----------

 The `DROP USER` statement removes one or more MariaDB accounts. It removes privilege rows for the account from all grant tables. To use this statement, you must have the global [CREATE USER](../grant/index#create-user) privilege or the [DELETE](../grant/index#table-privileges) privilege for the mysql database. Each account is named using the same format as for the `CREATE USER` statement; for example, `'jeffrey'@'localhost'`. If you specify only the user name part of the account name, a host name part of `'%'` is used. For additional information about specifying account names, see [CREATE USER](../create-user/index).

 Note that, if you specify an account that is currently connected, it will not be deleted until the connection is closed. The connection will not be automatically closed.

 If any of the specified user accounts do not exist, `ERROR 1396 (HY000)` results. If an error occurs, `DROP USER` will still drop the accounts that do not result in an error. Only one error is produced for all users which have not been dropped:

 
```
ERROR 1396 (HY000): Operation DROP USER failed for 'u1'@'%','u2'@'%'

```

Failed `CREATE` or `DROP` operations, for both users and roles, produce the same error code.

 #### IF EXISTS

 If the `IF EXISTS` clause is used, MariaDB will return a note instead of an error if the user does not exist.

 Examples
--------

 
```
DROP USER bob;

DROP USER foo2@localhost,foo2@'127.%';

```

`IF EXISTS`:

 
```
DROP USER bob;
ERROR 1396 (HY000): Operation DROP USER failed for 'bob'@'%'

DROP USER IF EXISTS bob;
Query OK, 0 rows affected, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+---------------------------------------------+
| Level | Code | Message                                     |
+-------+------+---------------------------------------------+
| Note  | 1974 | Can't drop user 'bob'@'%'; it doesn't exist |
+-------+------+---------------------------------------------+

```

See Also
--------

 * [CREATE USER](../create-user/index)
* [ALTER USER](../alter-user/index)
* [GRANT](../grant/index)
* [SHOW CREATE USER](../show-create-user/index)
* [mysql.user table](../mysqluser-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-user/>

EXECUTE IMMEDIATE
=================

    
**MariaDB starting with [10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)**EXECUTE IMMEDIATE was introduced in [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/).

 
Syntax
------

 
```
EXECUTE IMMEDIATE statement

```

Description
-----------

 `EXECUTE IMMEDIATE` executes a dynamic SQL statement created on the fly, which can reduce performance overhead.

 For example:

 
```
EXECUTE IMMEDIATE 'SELECT 1' 

```

which is shorthand for:

 
```
prepare stmt from "select 1";
execute stmt;
deallocate prepare stmt;

```

EXECUTE IMMEDIATE supports complex expressions as prepare source and parameters:

 
```
EXECUTE IMMEDIATE CONCAT('SELECT COUNT(*) FROM ', 't1', ' WHERE a=?') USING 5+5;

```

Limitations: subselects and stored function calls are not supported as a prepare source.

 The following examples return an error:

 
```
CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1';
EXECUTE IMMEDIATE f1();
ERROR 1970 (42000): EXECUTE IMMEDIATE does not support subqueries or stored functions

EXECUTE IMMEDIATE (SELECT 'SELECT * FROM t1');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
  corresponds to your MariaDB server version for the right syntax to use near 
  'SELECT 'SELECT * FROM t1')' at line 1

CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING f1();
ERROR 1970 (42000): EXECUTE..USING does not support subqueries or stored functions

EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING (SELECT 10);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
  corresponds to your MariaDB server version for the right syntax to use near 
  'SELECT 10)' at line 1

```

One can use a user or an SP variable as a workaround:

 
```
CREATE OR REPLACE FUNCTION f1() RETURNS VARCHAR(64) RETURN 'SELECT * FROM t1';
SET @stmt=f1();
EXECUTE IMMEDIATE @stmt;

SET @stmt=(SELECT 'SELECT 1');
EXECUTE IMMEDIATE @stmt;

CREATE OR REPLACE FUNCTION f1() RETURNS INT RETURN 10;
SET @param=f1();
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param;

SET @param=(SELECT 10);
EXECUTE IMMEDIATE 'SELECT * FROM t1 WHERE a=?' USING @param;

```

EXECUTE IMMEDIATE supports user variables and SP variables as OUT parameters

 
```
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1(OUT a INT)
BEGIN
  SET a:= 10;
END;
$$
DELIMITER ;
SET @a=2;
EXECUTE IMMEDIATE 'CALL p1(?)' USING @a;
SELECT @a;
+------+
| @a   |
+------+
|   10 |
+------+

```

Similar to PREPARE, EXECUTE IMMEDIATE is allowed in stored procedures but is not allowed in stored functions.

 This example uses EXECUTE IMMEDIATE inside a stored procedure:

 
```
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1()
BEGIN
  EXECUTE IMMEDIATE 'SELECT 1';
END;
$$
DELIMITER ;
CALL p1;
+---+
| 1 |
+---+
| 1 |
+---+

```

This script returns an error:

 
```
DELIMITER $$
CREATE FUNCTION f1() RETURNS INT
BEGIN
  EXECUTE IMMEDIATE 'DO 1';
  RETURN 1;
END;
$$
ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger

```

EXECUTE IMMEDIATE can use DEFAULT and IGNORE indicators as bind parameters:

 
```
CREATE OR REPLACE TABLE t1 (a INT DEFAULT 10);
EXECUTE IMMEDIATE 'INSERT INTO t1 VALUES (?)' USING DEFAULT;
SELECT * FROM t1;
+------+
| a    |
+------+
|   10 |
+------+

```

EXECUTE IMMEDIATE increments the [Com\_execute\_immediate](../server-status-variables/index#com_execute_immediate) status variable, as well as the [Com\_stmt\_prepare](../server-status-variables/index#com_stmt_prepare), [Com\_stmt\_execute](../server-status-variables/index#com_stmt_execute) and [Com\_stmt\_close](../server-status-variables/index#com_stmt_close) status variables.

 Note, EXECUTE IMMEDIATE does not increment the [Com\_execute\_sql](../server-status-variables/index#com_execute_sql) status variable. *Com\_execute\_sql* is used only for [PREPARE](../prepare-statement/index)..[EXECUTE](../execute-statement/index).

 This session screenshot demonstrates how EXECUTE IMMEDIATE affects status variables:

 
```
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE 
  ('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');

+-----------------------+----------------+
| VARIABLE_NAME         | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 0              |
| COM_EXECUTE_SQL       | 0              |
| COM_STMT_CLOSE        | 0              |
| COM_STMT_EXECUTE      | 0              |
| COM_STMT_PREPARE      | 0              |
+-----------------------+----------------+

EXECUTE IMMEDIATE 'SELECT 1';
+---+
| 1 |
+---+
| 1 |
+---+

SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME RLIKE 
  ('COM_(EXECUTE|STMT_PREPARE|STMT_EXECUTE|STMT_CLOSE)');
+-----------------------+----------------+
| VARIABLE_NAME         | VARIABLE_VALUE |
+-----------------------+----------------+
| COM_EXECUTE_IMMEDIATE | 1              |
| COM_EXECUTE_SQL       | 0              |
| COM_STMT_CLOSE        | 1              |
| COM_STMT_EXECUTE      | 1              |
| COM_STMT_PREPARE      | 1              |
+-----------------------+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/execute-immediate/>

TokuDB System Variables
=======================

    
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

  This page lists system variables that are related to [TokuDB](../tokudb/index). 

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them, and [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index) for a complete list of all options, statis variable and system variables in MariaDB.

 System Variables
----------------

 #### `tokudb_alter_print_error`

 * **Description:** Print errors for alter table operations.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_analyze_time`

 * **Description:** Time in seconds that [ANALYZE](../analyze-table/index) operations spend on each index when calculating cardinality. Accurate cardinality helps in particular with the performance of complex queries. If no analyzes are run, cardinality will be 1 for primary indexes, and unknown (NULL) for other types of indexes.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `5`
* **Range:** `0` to `4294967295`

 

---

 #### `tokudb_block_size`

 * **Description:** Uncompressed size of internal fractal tree and leaf nodes. Changing will only affect tables created after the new setting is in effect. Existing tables will keep the setting they were created with unless the table is dumped and reloaded.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `4194304` (4MB)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_bulk_fetch`

 * **Description:** If set to `1` (the default), the bulk fetch algorithm is used for SELECT's and DELETE's, including related statements such as INSERT INTO.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_cache_size`

 * **Description:** Size in bytes of the TokuDB cache. This variable is read-only and cannot be changed dynamically. To change the value, either set the value in the `my.cnf` file prior to loading TokuDB or restart MariaDB after modifying the configuration. If you have loaded the plugin but not used TokuDB yet, you can unload the plugin then reload it and MariaDB will reload the plugin with the setting from the configuration file. Setting to at least half of the available memory is recommended, although if using directIO instead of buffered IO (see [tokudb\_directio](#tokudb_directio)) , up to 80% of the available memory is recommended. Decrease if other applications require significant memory or swapping is degrading performance.
* **Dynamic:** No
* **Data Type:** numeric
* **Default Value:** Half of the total system memory

 

---

 #### `tokudb_check_jemalloc`

 * **Description:** Check if jemalloc is linked.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `1`
* **Valid Values:** `0` and `1`

 

---

 #### `tokudb_checkpoint_lock`

 * **Description:** Mechanism to lock out TokuDB checkpoints. When set to `1`, TokuDB checkpoints are locked out. Setting to `0`, or disconnecting the client, releases the lock.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_checkpoint_on_flush_logs`

 * **Description:** TokuDB checkpoint on flush logs.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_checkpointing_period`

 * **Description:** Time in seconds between the beginning of each checkpoint. It is recommended to leave this at the default setting of 1 minute.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `60`
* **Range:** `0` to `4294967295`

 

---

 #### `tokudb_cleaner_iterations`

 * **Description:** Number of internal nodes processed in each cleaner thread period (see [tokudb\_cleaner\_period](#tokudb_cleaner_period)). Setting to `0` turns off cleaner threads.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `5`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_cleaner_period`

 * **Description:** Frequency in seconds for the running of the cleaner thread. Setting to `0` turns off cleaner threads.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `1`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_commit_sync`

 * **Description:** Whether or not the transaction log is flushed upon transaction commit. Flushing has a minor performance penalty, but switching it off means that committed transactions may not survive a server crash.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_create_index_online`

 * **Description:** Whether indexes are hot or not. Hot, or online, indexes (the default) mean that the table is available for inserting and updates while the index is being created. It is slower to create hot indexes.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_data_dir`

 * **Description:** Directory where the TokuDB data is stored. By default the variable is empty, in which case the regular [datadir](../server-system-variables/index#datadir) is used.
* **Dynamic:** No
* **Data Type:** string
* **Default Value:** Empty (the MariaDB datadir is used)

 

---

 #### `tokudb_debug`

 * **Description:** Setting to a non-zero value turns on various TokuDB debug traces.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_directio`

 * **Description:** When set to ON, TokuDB writes use Direct IO instead of Buffered IO. [tokudb\_cache\_size](#tokudb_cache_size) should be adjusted when using DirectIO.
* **Dynamic:** No
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_disable_hot_alter`

 * **Description:** If set to `ON` (`OFF` is default), hot alter table is disabled.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_disable_prefetching`

 * **Description:** If prefetching is not disabled (the default), range queries usually benefit from aggressive prefetching of blocks of rows. For range queries with LIMIT clauses, this can create unnecessary IO, and so prefetching can be disabled if these make up a majority of range queries.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_disable_slow_alter`

 * **Description:** Usually, TokuDB permits column addition, deletion, expansion, and renaming with minimal locking, very quickly. This variable determines whether certain slow [alter|ALTER]] table statements that cannot take advantage of this feature are permitted. Statements that are slow are those that include a mix of column additions, deletions or expansions, for example, `ALTER TABLE t1 ADD COLUMN c1 int, DROP COLUMN c2`.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `OFF`

 

---

 #### `tokudb_empty_scan`

 * **Description:** TokuDB algorithm to check if the table is empty when opened. Setting to `disabled` will reduce this overhead.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** enum
* **Default Value:** `rl`
* **Valid Values:** `lr`, `rl`, `disabled`

 

---

 #### `tokudb_fs_reserve_percent`

 * **Description:** If this percentage of the filesystem is not free, inserts will be prohibited. Recommended value is half the size of the available memory. Once disabled, inserts will be re-enabled once twice the reserve is available. TokuDB will freeze entirely if the disk becomes entirely full.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** numeric
* **Default Value:** `5`

 

---

 #### `tokudb_fsync_log_period`

 * **Description:** fsync() operations frequency in milliseconds. If set to `0`, the default, [tokudb\_commit\_sync](#tokudb_commit_sync) control fsync() behavior.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`

 
**Warning**: currently values in the 1000-2000 range seem to cause server crashes, see [MDEV-16732](https://jira.mariadb.org/browse/MDEV-16732)

 


---

 #### `tokudb_hide_default_row_format`

 * **Description:** Hide the default row format.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_killed_time`

 * **Description:** Control lock tree kill callback frequency.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `4000`
* **Range:** `0` to `18446744073709551615`
* **Introduced:** TokuDB 7.1.5

 

---

 #### `tokudb_last_lock_timeout`

 * **Description:** Empty by default, when a lock deadlock is detected, or a lock request times out, set to a JSON document describing the most recent lock conflict. Only set when the first bit of [tokudb\_lock\_timeout\_debug](#tokudb_lock_timeout_debug) is set.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** text
* **Default Value:** Empty

 

---

 #### `tokudb_load_save_space`

 * **Description:** If set to `1`, the default, bulk loader intermediate data is compressed, otherwise it is uncompressed. Also see [tokudb\_tmp\_dir](#tokudb_tmp_dir).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_loader_memory_size`

 * **Description:** Memory limit for each loader instance used by the TokuDB bulk loader. Memory is taken from the TokuDB cache ([tokudb\_cache\_size](#tokudb_cache_size)), so current cache data may need to be cleared for the loader to begin. Increase if tables are very larger, with multiple secondary indexes.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `100000000` (100M)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_lock_timeout`

 * **Description:** Time in milliseconds that a transaction will wait for a lock held by another transaction to be released before timing out with a `lock wait timeout` error (-30994). Setting to `0` disables lock waits.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `4000` (4 seconds)
* **Range:** `0` to `18446744073709551615`

 

---

 #### `tokudb_lock_timeout_debug`

 * **Description:** When bit zero is set (default `1`), a JSON document describing the most recent lock conflict is reported to [tokudb\_last\_lock\_timeout](#tokudb_last_lock_timeout). When set to `0`, no lock conflicts are reported. When bit one is set, the JSON document is printed to the [error log](../error-log/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `1`

 

---

 #### `tokudb_log_dir`

 * **Description:** Directory where the TokuDB log files are stored. By default the variable is empty, in which case the regular [datadir](../server-system-variables/index#datadir) is used.
* **Dynamic:** No
* **Data Type:** string
* **Default Value:** Empty (the MariaDB datadir is used)

 

---

 #### `tokudb_max_lock_memory`

 * **Description:** Max memory for locks.
* **Scope:** Global, Session
* **Dynamic:** No
* **Data Type:** numeric
* **Default Value:** `130653952`

 

---

 #### `tokudb_optimize_index_fraction`

 * **Description:** When deleting a percentage of the tree (useful when the left side of the tree has many deletions, such as a pattern with increasing ids or dates), it's possible to optimize a subset of the fractal tree, as determined by the value of this variable, which ranges from `0.0` to `1.0` (indicating the whole tree).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `1.000000`
* **Range:** `0.0` to `1.0`
* **Introduced:** TokuDB 7.5.5

 

---

 #### `tokudb_optimize_index_name`

 * **Description:** If set to an index name, will optimize that single index in a table. Empty by default.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** string
* **Default Value:** None
* **Introduced:** TokuDB 7.5.5

 

---

 #### `tokudb_optimize_throttle`

 * **Description:** Table optimization utilizes all available resources by default. This variable allows the table optimization speed to be limited in order to reduce the overall resources used. The limit places an upper bound on the number of fractal tree leaf nodes that are optimized per second. `0`, the default, imposes no limit.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`
* **Range:** `0` to `18446744073709551615`
* **Introduced:** TokuDB 7.5.5

 

---

 #### `tokudb_pk_insert_mode`

 * **Description:** Mode for primary key inserts using either [REPLACE INTO](../replace/index) or [INSERT IGNORE](../ignore/index) on tables with no secondary index, or where all columns in the secondary index are in the primary key. For example `PRIMARY KEY (a,b,c), key (b,c)`
	+ `0`: Fast inserts. [Triggers](../triggers/index) may not work, and [row-based replication](../binary-log-formats/index) will not work
	+ `1`: Fast inserts if no triggers are defined, otherwise inserts may be slow. Row-based replication will not work.
	+ `2`: Slow inserts. Triggers and row-based replication work normally.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** enumerated
* **Default Value:** `1`
* **Valid Values:** `0`, `1`, `2`

 

---

 #### `tokudb_prelock_empty`

 * **Description:** If set to `0` (`1` is default), fast bulk loading will be switched off. Usually, TokuDB obtains a table lock on empty tables. If, as is usual, only one transaction is loading the table, this speeds up the inserts. However, if many transactions are loading, only one can have access at a time, so setting this to `0`, avoiding the lock, will speed inserts up in that situation.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_read_block_size`

 * **Description:** Uncompressed size in bytes of the read blocks of the fractal tree leaves. Changing will only affect tables created after the new setting is in effect. Existing tables will keep the setting they were created with unless the table is dumped and reloaded. Larger values are better for large range scans and higher compressions, while smaller values are better for point and small range scans.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `65536` (64KB)
* **Range:** `4096` to `4294967295`

 

---

 #### `tokudb_read_buf_size`

 * **Description:** Per-client size in bytes of the buffer used for storing bulk fetched values as part of a large range query. Reduce if there are many simultaneous clients. Setting to `0` disables bulk fetching.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `131072` (128KB)
* **Range:** `0` to `1048576`

 

---

 #### `tokudb_read_status_frequency`

 * **Description:** Progress is measured every this many reads for display by [SHOW PROCESSLIST](../show-processlist/index). Useful to set to `1` to examine slow queries.
* **Scope:** Global,
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `10000`
* **Range:** `0` to `4294967295`

 

---

 #### `tokudb_row_format`

 * **Description:** Compression algorithm used by default to compress data. Can be overridden by a row format specified in the [CREATE TABLE](../create-table/index) statement. note that the library can be specified directly, or an alias used, the mapping of which may change in future. Note that in [MariaDB 5.5](../what-is-mariadb-55/index), and before [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/), the compression type did not default to this value. See [TokuDB Differences](../tokudb-differences/index).
	+ `tokudb_default`, `tokudb_zlib`: Use the zlib library,
	+ `tokudb_fast`, `tokudb_quicklz`: Use the quicklz library, the lightest compression with low CPU usage,
	+ `tokudb_small`, `tokudb_lzma`: Use the lzma library. the highest compression and highest CPU usage
	+ `tokudb_uncompressed`: No compression is used.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** enumerated
* **Default Value:** `tokudb_zlib`
* **Valid Values:** `tokudb_default`, `tokudb_fast`, `tokudb_small`, `tokudb_zlib`, `tokudb_quicklz`, `tokudb_lzma`, `tokudb_uncompressed`

 

---

 #### `tokudb_rpl_check_readonly`

 * **Description:** By default, when the slave is in read only mode, row events will be run from the binary log using TokuDB's read-free replication (RFR). Setting this variable to `OFF` turns off the slave read only check, allowing RFR to run when the slave is not read-only. Be careful that you understand the consequences if setting this variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_rpl_lookup_rows`

 * **Description:** If set to `OFF` (`ON` is default), and [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) to `ROW` and [read\_only](../server-system-variables/index#read_only) to `ON`, TokuDB replication slaves will not perform row lookups for update or delete row log events, removing the need for the associated IO.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_rpl_lookup_rows_delay`

 * **Description:** Can be used to simulate long disk reads by sleeping for the specified time, in microseconds, before the row lookup query. Only useful to change in a test environment.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`

 

---

 #### `tokudb_rpl_unique_checks`

 * **Description:** If set to `OFF` (`ON` is default), and [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) to `ROW` and [read\_only](../server-system-variables/index#read_only) to `ON`, TokuDB replication slaves will skip uniqueness checks on inserts and updates, removing the associated IO.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_rpl_unique_checks_delay`

 * **Description:** Can be used to simulate long disk reads by sleeping for the specified time, in microseconds, before the row lookup query. Only useful to change in a test environment.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** numeric
* **Default Value:** `0`

 

---

 #### `tokudb_support_xa`

 * **Description:** Whether or not the prepare phase of an XA transaction performs an fsync().
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** boolean
* **Default Value:** `ON`

 

---

 #### `tokudb_tmp_dir`

 * **Description:** Directory where the TokuDB bulk loaders temporary files are stored. Can be very large, and useful to place on a separate disk. By default the variable is empty, in which case the regular [datadir](../server-system-variables/index#datadir) is used. [tokudb\_load\_save\_space](#tokudb_load_save_space) determines whether the data is compressed or not. The error message `ERROR 1030 (HY000): Got error 1 from storage engine` could indicate that the disk has run out of space.
* **Dynamic:** No
* **Data Type:** `directory name`
* **Default Value:** Empty (the MariaDB datadir is used)

 

---

 #### `tokudb_version`

 * **Description:** The TokuDB version of the plugin included on MariaDB.
* **Dynamic:** No
* **Data Type:** `string`

 #### `tokudb_write_status_frequency`

 * **Description:** Progress is measured every this many writes for display by [SHOW PROCESSLIST](../show-processlist/index). Useful to set to `1` to examine slow queries.
* **Scope:** Global,
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1000`
* **Range:** `0` to `4294967295`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tokudb-system-and-status-variables/>

GET DIAGNOSTICS
===============

    
```
GET [CURRENT] DIAGNOSTICS
{
    statement_property
    [, statement_property] ... 
  | CONDITION condition_number
    condition_property
    [, condition_property] ...
}

statement_property:
    variable = statement_property_name

condition_property:
    variable  = condition_property_name

statement_property_name:
    NUMBER
  | ROW_COUNT

condition_property_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | RETURNED_SQLSTATE
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME
  | ROW_NUMBER

```
 The [diagnostics area](../diagnostics-area/index) contains information about the errors, warnings and notes which were produced by the last SQL statement. If that statement didn't produce any warnings, the diagnostics area contains information about the last executed statement which involved a table. The GET DIAGNOSTICS statement copies the requested information from the diagnostics area to the specified variables. It is possible to use both user variables or [local variables](../declare-variable/index).

 To use GET DIAGNOSTICS, it is important to know how the diagnostics area is structured. It has two sub-areas: the statement information area and the error conditions information area. For details, please refer to the [diagnostics area](../diagnostics-area/index) page.

 Each single GET DIAGNOSTICS command can read information from the statement information area or from a single error condition. This means that, if you have two warnings and you want to know the number of warnings, and read both the warnings, you need to issue GET DIAGNOSTICS three times.

 The CURRENT keywords adds nothing to the statement, because MariaDB has only one diagnostics area.

 If GET DIAGNOSTICS produces an error condition (because the command is properly parsed but not correctly used), the diagnostics area is not emptied, and the new condition is added.

 Getting Information from a Condition
------------------------------------

 To read information from a condition, the CONDITION keyword must be specified and it must be followed by the condition number. This number can be specified as a constant value or as a variable. The first condition's index is 1. If the error condition does not exist, the variables will not change their value and a 1758 error will be produced ("Invalid condition number").

 The condition properties that can be read with GET DIAGNOSTICS are the same that can be set with SIGNAL and RESIGNAL statements. They are explained in the [diagnostics area](../diagnostics-area/index) page. However, there is one more property: RETURNED\_SQLSTATE, which indicates the condition's [SQLSTATE](../sqlstate/index).

 For a list of SQLSTATE values and MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).

 The type for all the condition properties is VARCHAR(64), except for MYSQL\_ERRNO, whose valid range is 1 to 65534.

   


 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**ROW\_NUMBER
-----------

 Until [MariaDB 10.7](../what-is-mariadb-107/index), there was no way, short of parsing the error text, to know in what row an error had happened. From 10.7, one can use the ROW\_NUMBER property to retrieve the row number too, even if the error text does not mention it. Note that this property was named ERROR\_INDEX in the [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/) preview release. As a result, ROW\_NUMBER is a [reserved word](../reserved-words/index) from [MariaDB 10.7](../what-is-mariadb-107/index).

 
Examples
--------

 In the following example, a statement generates two warnings, and GET DIAGNOSTICS is used to get the number of warnings:

 
```
CREATE TABLE `test`.`t` (`c` INT) ENGINE = x;
Query OK, 0 rows affected, 2 warnings (0.19 sec)

GET DIAGNOSTICS @num_conditions = NUMBER;

SELECT @num_conditions;
+-----------------+
| @num_conditions |
+-----------------+
|               2 |
+-----------------+

```

Then, we can see the warnings:

 
```
GET DIAGNOSTICS CONDITION 1 @sqlstate = RETURNED_SQLSTATE,
  @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;

SELECT @sqlstate, @errno, @text;
+-----------+--------+----------------------------+
| @sqlstate | @errno | @text                      |
+-----------+--------+----------------------------+
| 42000     |   1286 | Unknown storage engine 'x' |
+-----------+--------+----------------------------+

GET DIAGNOSTICS CONDITION 2 @sqlstate = RETURNED_SQLSTATE,
  @errno = MYSQL_ERRNO, @text = MESSAGE_TEXT;

SELECT @sqlstate, @errno, @text;
+-----------+--------+-------------------------------------------+
| @sqlstate | @errno | @text                                     |
+-----------+--------+-------------------------------------------+
| HY000     |   1266 | Using storage engine InnoDB for table 't' |
+-----------+--------+-------------------------------------------+

```

From [MariaDB 10.7](../what-is-mariadb-107/index):

 
```
INSERT INTO t1 VALUES (4,'d',1.00104),(1,'a',1.00101),(2,'b',1.00102);
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'

GET DIAGNOSTICS CONDITION 1 @row_num= ROW_NUMBER;

SELECT @row_num;
+----------+
| @row_num |
+----------+
|        2 |
+----------+

```

See Also
--------

 * [Diagnostics Area](../diagnostics-area/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/get-diagnostics/>

HANDLER Commands
================

    Syntax
------

 
```
HANDLER tbl_name OPEN [ [AS] alias]
HANDLER tbl_name READ index_name { = | >= | <= | < } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name CLOSE

```
 Description
-----------

 The `HANDLER` statement provides direct access to table storage engine interfaces for key lookups and key or table scans. It is available for at least [Aria](../aria-formerly-known-as-maria/index), [Memory](../memory-storage-engine/index), [MyISAM](../myisam-storage-engine/index) and [InnoDB](../xtradb-and-innodb/index) tables (and should work with most 'normal' storage engines, but not with system tables, [MERGE](../merge/index) or [views](../views/index)).

 `HANDLER ... OPEN` opens a table, allowing it to be accessible to subsequent `HANDLER ... READ` statements. The table can either be opened using an alias (which must then be used by `HANDLER ... READ`, or a table name.

 The table object is only closed when `HANDLER ... CLOSE` is called by the session, and is not shared by other sessions.

 [Prepared statements](../prepared-statements/index) work with `HANDLER READ`, which gives a much higher performance (50% speedup) as there is no parsing and all data is transformed in binary (without conversions to text, as with the normal protocol).

 The HANDLER command does not work with [partitioned tables](../managing-mariadb-partitioning/index).

 Key Lookup
----------

 A key lookup is started with:

 
```
HANDLER tbl_name READ index_name { = | >= | <= | < }  (value,value) [LIMIT...]

```

The values stands for the value of each of the key columns. For most key types (except for HASH keys in MEMORY storage engine) you can use a prefix subset of it's columns.

 If you are using LIMIT, then in case of >= or > then there is an implicit NEXT implied, while if you are using <= or < then there is an implicit PREV implied.

 After the initial read, you can use

 
```
HANDLER tbl_name READ index_name NEXT [ LIMIT ... ]
or
HANDLER tbl_name READ index_name PREV [ LIMIT ... ]

```

to scan the rows in key order.

 Note that the row order is not defined for keys with duplicated values and will vary from engine to engine.

 Key Scans
---------

 You can scan a table in key order by doing:

 
```
HANDLER tbl_name READ index_name FIRST [ LIMIT ... ]
HANDLER tbl_name READ index_name NEXT  [ LIMIT ... ]

```

or, if the handler supports backwards key scans (most do):

 
```
HANDLER tbl_name READ index_name LAST [ LIMIT ... ]
HANDLER tbl_name READ index_name PREV [ LIMIT ... ]

```

Table Scans
-----------

 You can scan a table in row order by doing:

 
```
HANDLER tbl_name READ FIRST [ LIMIT ... ]
HANDLER tbl_name READ NEXT  [ LIMIT ... ]

```

Limitations
-----------

 As this is a direct interface to the storage engine, some limitations may apply for what you can do and what happens if the table changes. Here follows some of the common limitations:

 ### Finding 'Old Rows'

 HANDLER READ is not transaction safe, consistent or atomic. It's ok for the storage engine to returns rows that existed when you started the scan but that were later deleted. This can happen as the storage engine may cache rows as part of the scan from a previous read.

 You may also find rows committed since the scan originally started.

 ### Invisible Columns

 `HANDLER ... READ` also reads the data of [invisible-columns](../invisible-columns/index).

 ### System-Versioned Tables

 `HANDLER ... READ` reads everything from [system-versioned tables](../system-versioned-tables/index), and so includes `row_start` and `row_end` fields, as well as all rows that have since been deleted or changed, including when history partitions are used. 

 ### Other Limitations

 * If you do an [ALTER TABLE](../alter-table/index), all your HANDLERs for that table are automatically closed.
* If you do an ALTER TABLE for a table that is used by some other connection with HANDLER, the ALTER TABLE will wait for the HANDLER to be closed.
* For HASH keys, you must use all key parts when searching for a row.
* For HASH keys, you can't do a key scan of all values. You can only find all rows with the same key value.
* While each HANDLER READ command is atomic, if you do a scan in many steps, then some engines may give you error 1020 if the table changed between the commands. Please refer to the [specific engine handler page](../handler-handler/index) if this happens.

 Error Codes
-----------

 * Error 1031 (ER\_ILLEGAL\_HA) Table storage engine for 't1' doesn't have this option
	+ If you get this for HANDLER OPEN it means the storage engine doesn't support HANDLER calls.
	+ If you get this for HANDLER READ it means you are trying to use an incomplete HASH key.
* Error 1020 (ER\_CHECKREAD) Record has changed since last read in table '...'
	+ This means that the table changed between two reads and the handler can't handle this case for the given scan.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handler-commands/>

INSERT SELECT
=============

    Syntax
------

 
```
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

```
 Description
-----------

 With `INSERT ... SELECT`, you can quickly insert many rows into a table from one or more other tables. For example:

 
```
INSERT INTO tbl_temp2 (fld_id)
  SELECT tbl_temp1.fld_order_id
  FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;

```

`tbl_name` can also be specified in the form `db_name`.`tbl_name` (see [Identifier Qualifiers](../identifier-qualifiers/index)). This allows to copy rows between different databases.

 If the new table has a primary key or UNIQUE indexes, you can use [IGNORE](../ignore/index) to handle duplicate key errors during the query. The newer values will not be inserted if an identical value already exists.

 `[REPLACE](../replace/index)` can be used instead of `INSERT` to prevent duplicates on `UNIQUE` indexes by deleting old values. In that case, `ON DUPLICATE KEY UPDATE` cannot be used.

 `INSERT ... SELECT` works for tables which already exist. To create a table for a given resultset, you can use [CREATE TABLE ... SELECT](../create-table/index).

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-select/>

INSTALL PLUGIN
==============

    Syntax
------

 
```
INSTALL PLUGIN [IF NOT EXISTS] plugin_name SONAME 'plugin_library'
```
 Description
-----------

 This statement installs an individual [plugin](../mariadb-plugins/index) from the specified library. To install the whole library (which could be required), use [INSTALL SONAME](../install-soname/index). See also [Installing a Plugin](../plugin-overview/index#installing-a-plugin).

 `plugin_name` is the name of the plugin as defined in the plugin declaration structure contained in the library file. Plugin names are not case sensitive. For maximal compatibility, plugin names should be limited to ASCII letters, digits, and underscore, because they are used in C source files, shell command lines, M4 and Bourne shell scripts, and SQL environments.

 `plugin_library` is the name of the shared library that contains the plugin code. The file name extension can be omitted (which makes the statement look the same on all architectures).

 The shared library must be located in the plugin directory (that is, the directory named by the [plugin\_dir](../server-system-variables/index#plugin_dir) system variable). The library must be in the plugin directory itself, not in a subdirectory. By default, `plugin_dir` is plugin directory under the directory named by the `pkglibdir` configuration variable, but it can be changed by setting the value of `plugin_dir` at server startup. For example, set its value in a `my.cnf` file:

 
```
[mysqld]
plugin_dir=/path/to/plugin/directory
```

If the value of [plugin\_dir](../server-system-variables/index#plugin_dir) is a relative path name, it is taken to be relative to the MySQL base directory (the value of the basedir system variable).

 `INSTALL PLUGIN` adds a line to the `mysql.plugin` table that describes the plugin. This table contains the plugin name and library file name.

 `INSTALL PLUGIN` causes the server to read option (`my.cnf`) files just as during server startup. This enables the plugin to pick up any relevant options from those files. It is possible to add plugin options to an option file even before loading a plugin (if the loose prefix is used). It is also possible to uninstall a plugin, edit `my.cnf`, and install the plugin again. Restarting the plugin this way enables it to the new option values without a server restart.

 `INSTALL PLUGIN` also loads and initializes the plugin code to make the plugin available for use. A plugin is initialized by executing its initialization function, which handles any setup that the plugin must perform before it can be used.

 To use `INSTALL PLUGIN`, you must have the [INSERT privilege](../grant/index) for the `mysql.plugin` table.

 At server startup, the server loads and initializes any plugin that is listed in the `mysql.plugin` table. This means that a plugin is installed with `INSTALL PLUGIN` only once, not every time the server starts. Plugin loading at startup does not occur if the server is started with the `--skip-grant-tables` option.

 When the server shuts down, it executes the de-initialization function for each plugin that is loaded so that the plugin has a chance to perform any final cleanup.

 If you need to load plugins for a single server startup when the `--skip-grant-tables` option is given (which tells the server not to read system tables), use the `--plugin-load` [mysqld option](../mysqld-options-full-list/index).

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**#### IF NOT EXISTS

 When the `IF NOT EXISTS` clause is used, MariaDB will return a note instead of an error if the specified plugin already exists. See [SHOW WARNINGS](../show-warnings/index).

 
Examples
--------

 
```
INSTALL PLUGIN sphinx SONAME 'ha_sphinx.so';

```

The extension can also be omitted:

 
```
INSTALL PLUGIN innodb SONAME 'ha_xtradb';

```

From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/):

 
```
INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
Query OK, 0 rows affected (0.104 sec)

INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example';
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+------------------------------------+
| Level | Code | Message                            |
+-------+------+------------------------------------+
| Note  | 1968 | Plugin 'example' already installed |
+-------+------+------------------------------------+

```

See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [Plugin Overview](../plugin-overview/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [mariadb-plugin](../mariadb-plugin/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/install-plugin/>

OPTIMIZE TABLE
==============

    Syntax
------

 
```
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE
    tbl_name [, tbl_name] ...
    [WAIT n | NOWAIT]

```
 Description
-----------

 `OPTIMIZE TABLE` has two main functions. It can either be used to defragment tables, or to update the InnoDB fulltext index.

 #### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 ### Defragmenting

 `OPTIMIZE TABLE` works for [InnoDB](../innodb/index) (before [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), only if the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) server system variable is set), [Aria](../aria/index), [MyISAM](../myisam/index) and [ARCHIVE](../archive/index) tables, and should be used if you have deleted a large part of a table or if you have made many changes to a table with variable-length rows (tables that have [VARCHAR](../varchar/index), [VARBINARY](../varbinary/index), [BLOB](../blob/index), or [TEXT](../text/index) columns). Deleted rows are maintained in a linked list and subsequent `INSERT` operations reuse old row positions.

 This statement requires [SELECT and INSERT privileges](../grant/index) for the table.

 By default, `OPTIMIZE TABLE` statements are written to the [binary log](../binary-log/index) and will be [replicated](../replication/index). The `NO_WRITE_TO_BINLOG` keyword (`LOCAL` is an alias) will ensure the statement is not written to the binary log.

 `OPTIMIZE TABLE` statements are not logged to the binary log if [read\_only](../server-system-variables/index#read_only) is set. See also [Read-Only Replicas](../read-only-replicas/index).

 `OPTIMIZE TABLE` is also supported for partitioned tables. You can use `[ALTER TABLE](../alter-table/index) ... OPTIMIZE PARTITION` to optimize one or more partitions.

 You can use `OPTIMIZE TABLE` to reclaim the unused space and to defragment the data file. With other storage engines, `OPTIMIZE TABLE` does nothing by default, and returns this message: " The storage engine for the table doesn't support optimize". However, if the server has been started with the `--skip-new` option, `OPTIMIZE TABLE` is linked to [ALTER TABLE](../alter-table/index), and recreates the table. This operation frees the unused space and updates index statistics.

 The [Aria](../aria/index) storage engine supports [progress reporting](../progress-reporting/index) for this statement.

 If a [MyISAM](../myisam/index) table is fragmented, [concurrent inserts](../concurrent-inserts/index) will not be performed until an `OPTIMIZE TABLE` statement is executed on that table, unless the [concurrent\_insert](../server-system-variables/index#concurrent_insert) server system variable is set to `ALWAYS`.

 ### Updating an InnoDB fulltext index

 When rows are added or deleted to an InnoDB [fulltext index](../full-text-indexes/index), the index is not immediately re-organized, as this can be an expensive operation. Change statistics are stored in a separate location . The fulltext index is only fully re-organized when an `OPTIMIZE TABLE` statement is run.

 By default, an OPTIMIZE TABLE will defragment a table. In order to use it to update fulltext index statistics, the [innodb\_optimize\_fulltext\_only](../innodb-system-variables/index#innodb_optimize_fulltext_only) system variable must be set to `1`. This is intended to be a temporary setting, and should be reset to `0` once the fulltext index has been re-organized.

 Since fulltext re-organization can take a long time, the [innodb\_ft\_num\_word\_optimize](../innodb-system-variables/index#innodb_ft_num_word_optimize) variable limits the re-organization to a number of words (2000 by default). You can run multiple OPTIMIZE statements to fully re-organize the index.

 ### Defragmenting InnoDB tablespaces

 [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) merged the Facebook/Kakao defragmentation patch, allowing one to use `OPTIMIZE TABLE` to defragment InnoDB tablespaces. For this functionality to be enabled, the [innodb\_defragment](../innodb-system-variables/index#innodb_defragment) system variable must be enabled. No new tables are created and there is no need to copy data from old tables to new tables. Instead, this feature loads `n` pages (determined by [innodb-defragment-n-pages](../innodb-system-variables/index#innodb_defragment_n_pages)) and tries to move records so that pages would be full of records and then frees pages that are fully empty after the operation. Note that tablespace files (including ibdata1) will not shrink as the result of defragmentation, but one will get better memory utilization in the InnoDB buffer pool as there are fewer data pages in use.

 See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index) for more details.

 See Also
--------

 * [Optimize Table in InnoDB with ALGORITHM set to INPLACE](../innodb-online-ddl-operations-with-the-inplace-alter-algorithm/index#optimize-table)
* [Optimize Table in InnoDB with ALGORITHM set to NOCOPY](../innodb-online-ddl-operations-with-the-nocopy-alter-algorithm/index#optimize-table)
* [Optimize Table in InnoDB with ALGORITHM set to INSTANT](../innodb-online-ddl-operations-with-the-instant-alter-algorithm/index#optimize-table)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimize-table/>

PREPARE Statement
=================

    Syntax
------

 
```
PREPARE stmt_name FROM preparable_stmt

```
 Description
-----------

 The `PREPARE` statement prepares a statement and assigns it a name, `stmt_name`, by which to refer to the statement later. Statement names are not case sensitive. `preparable_stmt` is either a string literal or a [user variable](../user-defined-variables/index) (not a [local variable](../declare-variable/index), an SQL expression or a subquery) that contains the text of the statement. The text must represent a single SQL statement, not multiple statements. Within the statement, "?" characters can be used as parameter markers to indicate where data values are to be bound to the query later when you execute it. The "?" characters should not be enclosed within quotes, even if you intend to bind them to string values. Parameter markers can be used only where expressions should appear, not for SQL keywords, identifiers, and so forth.

 The scope of a prepared statement is the session within which it is created. Other sessions cannot see it.

 If a prepared statement with the given name already exists, it is deallocated implicitly before the new statement is prepared. This means that if the new statement contains an error and cannot be prepared, an error is returned and no statement with the given name exists.

 Prepared statements can be PREPAREd and EXECUTEd in a stored procedure, but not in a stored function or trigger. Also, even if the statement is PREPAREd in a procedure, it will not be deallocated when the procedure execution ends.

 A prepared statement can access [user-defined variables](../user-defined-variables/index), but not [local variables](../declare-variable/index) or procedure's parameters.

 If the prepared statement contains a syntax error, PREPARE will fail. As a side effect, stored procedures can use it to check if a statement is valid. For example:

 
```
CREATE PROCEDURE `test_stmt`(IN sql_text TEXT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
                SELECT CONCAT(sql_text, ' is not valid');
        END;
        SET @SQL := sql_text;
        PREPARE stmt FROM @SQL;
        DEALLOCATE PREPARE stmt;
END;

```

The [FOUND\_ROWS()](../found_rows/index) and [ROW\_COUNT()](../information-functions-row_count/index) functions, if called immediatly after EXECUTE, return the number of rows read or affected by the prepared statements; however, if they are called after DEALLOCATE PREPARE, they provide information about this statement. If the prepared statement produces errors or warnings, [GET DIAGNOSTICS](../get-diagnostics/index) return information about them. DEALLOCATE PREPARE shouldn't clear the [diagnostics area](../diagnostics-area/index), unless it produces an error.

 A prepared statement is executed with `[EXECUTE](../execute-statement/index)` and released with `[DEALLOCATE PREPARE](../deallocate-drop-prepared-statement/index)`.

 The [max\_prepared\_stmt\_count](../server-system-variables/index#max_prepared_stmt_count) server system variable determines the number of allowed prepared statements that can be prepared on the server. If it is set to 0, prepared statements are not allowed. If the limit is reached, an error similar to the following will be produced:

 
```
ERROR 1461 (42000): Can't create more than max_prepared_stmt_count statements 
  (current value: 0)

```

### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#prepared-statements), `PREPARE stmt FROM 'SELECT :1, :2'` is used, instead of `?`.

 
Permitted Statements
--------------------

 
**MariaDB starting with [10.6.2](https://mariadb.com/kb/en/mariadb-1062-release-notes/)**All statements can be prepared, except [PREPARE](index), [EXECUTE](../execute-statement/index), and [DEALLOCATE / DROP PREPARE](../deallocate-drop-prepare/index).

 
Prior to this, not all statements can be prepared. Only the following SQL commands are permitted:

 * [ALTER TABLE](../alter-table/index)
* [ANALYZE TABLE](../analyze-table/index)
* [BINLOG](../binlog/index)
* [CACHE INDEX](../cache-index/index)
* [CALL](../call/index)
* [CHANGE MASTER](../change-master-to/index)
* [CHECKSUM {TABLE | TABLES}](../checksum-table/index)
* [COMMIT](../commit/index)
* {[CREATE](../create-database/index) | [DROP](../drop-database/index)} DATABASE
* {[CREATE](../create-index/index) | [DROP](../drop-index/index)} INDEX
* {[CREATE](../create-table/index) | [RENAME](../rename-table/index) | [DROP](../drop-table/index)} TABLE
* {[CREATE](../create-user/index) | [RENAME](../rename-user/index) | [DROP](../drop-user/index)} USER
* {[CREATE](../create-view/index) | [DROP](../drop-view/index)} VIEW
* [DELETE](../delete/index)
* [DESCRIBE](../describe/index)
* [DO](../do/index)
* [EXPLAIN](../explain/index)
* [FLUSH](../flush/index) {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES | LOGS | STATUS | MASTER | SLAVE | DES\_KEY\_FILE | USER\_RESOURCES | [QUERY CACHE](../flush-query-cache/index) | TABLE\_STATISTICS | INDEX\_STATISTICS | USER\_STATISTICS | CLIENT\_STATISTICS}
* [GRANT](../grant/index)
* [INSERT](../insert/index)
* INSTALL {[PLUGIN](../install-plugin/index) | [SONAME](../install-soname/index)}
* [HANDLER READ](../handler-commands/index)
* [KILL](../kill/index)
* [LOAD INDEX INTO CACHE](../load-index/index)
* [OPTIMIZE TABLE](../optimize-table/index)
* [REPAIR TABLE](../repair-table/index)
* [REPLACE](../replace/index)
* [RESET](../reset/index) {[MASTER](../reset-master/index) | [SLAVE](../reset-slave-connection_name/index) | [QUERY CACHE](../reset/index)}
* [REVOKE](../revoke/index)
* [ROLLBACK](../rollback/index)
* [SELECT](../select/index)
* [SET](../set/index)
* [SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER](../set-global-sql_slave_skip_counter/index)
* [SET ROLE](../set-role/index)
* [SET SQL\_LOG\_BIN](../set-sql_log_bin/index)
* [SET TRANSACTION ISOLATION LEVEL](../set-transaction/index)
* [SHOW EXPLAIN](../show-explain/index)
* SHOW {[DATABASES](../show-databases/index) | [TABLES](../show-tables/index) | [OPEN TABLES](../show-open-tables/index) | [TABLE STATUS](../show-table-status/index) | [COLUMNS](../show-columns/index) | [INDEX](../show-index/index) | [TRIGGERS](../show-triggers/index) | [EVENTS](../show-events/index) | [GRANTS](../show-grants/index) | [CHARACTER SET](../show-character-set/index) | [COLLATION](../show-collation/index) | [ENGINES](../show-events/index) | [PLUGINS [SONAME](../show-plugins/index)] | [PRIVILEGES](../show-privileges/index) | [PROCESSLIST](../show-processlist/index) | [PROFILE](../show-profile/index) | [PROFILES](../show-profiles/index) | [VARIABLES](../show-variables/index) | [STATUS](../show-status/index) | [WARNINGS](../show-warnings/index) | [ERRORS](../show-errors/index) | [TABLE\_STATISTICS](../show-table-statistics/index) | [INDEX\_STATISTICS](../show-index-statistics/index) | [USER\_STATISTICS](../show-user-statistics/index) | [CLIENT\_STATISTICS](../show-client-statistics/index) | [AUTHORS](../show-authors/index) | [CONTRIBUTORS](../show-contributors/index)}
* SHOW CREATE {[DATABASE](../show-create-database/index) | [TABLE](../show-create-table/index) | [VIEW](../show-create-view/index) | [PROCEDURE](../show-create-procedure/index) | [FUNCTION](../show-create-function/index) | [TRIGGER](../show-create-trigger/index) | [EVENT](../show-create-event/index)}
* SHOW {[FUNCTION](../show-function-code/index) | [PROCEDURE](../show-procedure-code/index)} CODE
* [SHOW BINLOG EVENTS](../show-binlog-events/index)
* [SHOW SLAVE HOSTS](../show-replica-hosts/index)
* SHOW {MASTER | BINARY} LOGS
* SHOW {MASTER | SLAVE | TABLES | INNODB | FUNCTION | PROCEDURE} STATUS
* SLAVE {[START](../start-slave/index) | [STOP](../stop-slave/index)}
* [TRUNCATE TABLE](../truncate-table/index)
* [SHUTDOWN](../shutdown/index)
* UNINSTALL {PLUGIN | SONAME}
* [UPDATE](../update/index)

 Synonyms are not listed here, but can be used. For example, DESC can be used instead of DESCRIBE.

 [Compound statements](../using-compound-statements-outside-of-stored-programs/index) can be prepared too.

 Note that if a statement can be run in a stored routine, it will work even if it is called by a prepared statement. For example, [SIGNAL](../signal/index) can't be directly prepared. However, it is allowed in [stored routines](../stored-routines/index). If the x() procedure contains SIGNAL, you can still prepare and execute the 'CALL x();' prepared statement.

 PREPARE supports most kinds of expressions as well, for example:

 
```
PREPARE stmt FROM CONCAT('SELECT * FROM ', table_name);

```

When PREPARE is used with a statement which is not supported, the following error is produced:

 
```
ERROR 1295 (HY000): This command is not supported in the prepared statement protocol yet

```

Example
-------

 
```
create table t1 (a int,b char(10));
insert into t1 values (1,"one"),(2, "two"),(3,"three");
prepare test from "select * from t1 where a=?";
set @param=2;
execute test using @param;
+------+------+
| a    | b    |
+------+------+
|    2 | two  |
+------+------+
set @param=3;
execute test using @param;
+------+-------+
| a    | b     |
+------+-------+
|    3 | three |
+------+-------+
deallocate prepare test;

```

Since identifiers are not permitted as prepared statements parameters, sometimes it is necessary to dynamically compose an SQL statement. This technique is called *dynamic SQL*). The following example shows how to use dynamic SQL:

 
```
CREATE PROCEDURE test.stmt_test(IN tab_name VARCHAR(64))
BEGIN
	SET @sql = CONCAT('SELECT COUNT(*) FROM ', tab_name);
	PREPARE stmt FROM @sql;
	EXECUTE stmt;
	DEALLOCATE PREPARE stmt;
END;

CALL test.stmt_test('mysql.user');
+----------+
| COUNT(*) |
+----------+
|        4 |
+----------+

```

Use of variables in prepared statements:

 
```
PREPARE stmt FROM 'SELECT @x;';

SET @x = 1;

EXECUTE stmt;
+------+
| @x   |
+------+
|    1 |
+------+

SET @x = 0;

EXECUTE stmt;
+------+
| @x   |
+------+
|    0 |
+------+

DEALLOCATE PREPARE stmt;

```

See Also
--------

 * [Out parameters in PREPARE](../out-parameters-in-prepare/index)
* [EXECUTE Statement](../execute-statement/index)
* [DEALLOCATE / DROP Prepared Statement](../deallocate-drop-prepared-statement/index)
* [EXECUTE IMMEDIATE](../execute-immediate/index)
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#prepared-statements)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/prepare-statement/>

REPAIR TABLE
============

    Syntax
------

 
```
REPAIR [NO_WRITE_TO_BINLOG | LOCAL] TABLE
    tbl_name [, tbl_name] ...
    [QUICK] [EXTENDED] [USE_FRM]

```

Description
-----------

 `REPAIR TABLE` repairs a possibly corrupted table. By default, it has the same effect as

 
```
myisamchk --recover tbl_name

```

or

 
```
aria_chk --recover tbl_name

```

See [aria\_chk](../aria_chk/index) and [myisamchk](../myisamchk/index) for more.

 `REPAIR TABLE` works for [Archive](../archive/index), [Aria](../aria/index), [CSV](../csv/index) and [MyISAM](../myisam/index) tables. For [InnoDB](../innodb/index), see [recovery modes](../innodb-recovery-modes/index). For CSV, see also [Checking and Repairing CSV Tables](../checking-and-repairing-csv-tables/index). For Archive, this statement also improves compression. If the storage engine does not support this statement, a warning is issued.

 This statement requires [SELECT and INSERT privileges](../grant/index) for the table.

 By default, `REPAIR TABLE` statements are written to the [binary log](../binary-log/index) and will be [replicated](../replication/index). The `NO_WRITE_TO_BINLOG` keyword (`LOCAL` is an alias) will ensure the statement is not written to the binary log.

 From [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), `REPAIR TABLE` statements are not logged to the binary log if [read\_only](../server-system-variables/index#read_only) is set. See also [Read-Only Replicas](../read-only-replicas/index).

 When an index is recreated, the storage engine may use a configurable buffer in the process. Incrementing the buffer speeds up the index creation. [Aria](../aria/index) and [MyISAM](../myisam/index) allocate a buffer whose size is defined by `[aria\_sort\_buffer\_size](../aria-server-system-variables/index#aria_sort_buffer_size)` or `[myisam\_sort\_buffer\_size](../myisam-server-system-variables/index#myisam_sort_buffer_size)`, also used for `[ALTER TABLE](../alter-table/index)`.

 `REPAIR TABLE` is also supported for partitioned tables. However, the `USE_FRM` option cannot be used with this statement on a partitioned table.

  `[ALTER TABLE ... REPAIR PARTITION](../alter-table/index)` can be used to repair one or more partitions.

 The [Aria](../aria/index) storage engine supports [progress reporting](../progress-reporting/index) for this statement.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/repair-table/>

RENAME USER
===========

    Syntax
------

 
```
RENAME USER old_user TO new_user
    [, old_user TO new_user] ...

```

Description
-----------

 The RENAME USER statement renames existing MariaDB accounts. To use it, you must have the global [CREATE USER](../grant/index#global-privileges) privilege or the `[UPDATE](../grant/index#table-privileges)` privilege for the `mysql` database. Each account is named using the same format as for the [CREATE USER](../create-user/index) statement; for example, `'jeffrey'@'localhost'`. If you specify only the user name part of the account name, a host name part of `'%'` is used.

 If any of the old user accounts do not exist or any of the new user accounts already exist, `ERROR 1396 (HY000)` results. If an error occurs, `RENAME USER` will still rename the accounts that do not result in an error.

 For modifying an existing account, see [ALTER USER](../alter-user/index).

 Examples
--------

 
```
CREATE USER 'donald', 'mickey';
RENAME USER 'donald' TO 'duck'@'localhost', 'mickey' TO 'mouse'@'localhost';

```

Renaming the host component of a user

 
```
RENAME USER 'foo'@'1.2.3.4' TO 'foo'@'10.20.30.40';

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rename-user/>

SAVEPOINT
=========

    Syntax
------

 
```
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

```
 Description
-----------

 InnoDB supports the SQL statements `SAVEPOINT`, `ROLLBACK TO SAVEPOINT`, `RELEASE SAVEPOINT` and the optional `WORK` keyword for `ROLLBACK`.

 Each savepoint must have a legal [MariaDB identifier](../identifier-names/index). A savepoint is a named sub-transaction.

 Normally [ROLLBACK](../rollback/index) undoes the changes performed by the whole transaction. When used with the TO clause, it undoes the changes performed after the specified savepoint, and erases all subsequent savepoints. However, all locks that have been acquired after the save point will survive. RELEASE SAVEPOINT does not rollback or commit any changes, but removes the specified savepoint.

 When the execution of a trigger or a stored function begins, it is not possible to use statements which reference a savepoint which was defined from out of that stored program.

 When a [COMMIT](../commit/index) (including implicit commits) or a ROLLBACK statement (with no TO clause) is performed, they act on the whole transaction, and all savepoints are removed.

 Errors
------

 If COMMIT or ROLLBACK is issued and no transaction was started, no error is reported.

 If SAVEPOINT is issued and no transaction was started, no error is reported but no savepoint is created. When ROLLBACK TO SAVEPOINT or RELEASE SAVEPOINT is called for a savepoint that does not exist, an error like this is issued:

 
```
ERROR 1305 (42000): SAVEPOINT svp_name does not exist

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/savepoint/>

RESET
=====

    Syntax
------

 
```
RESET reset_option [, reset_option] ...

```

Description
-----------

 The `RESET` statement is used to clear the state of various server operations. You must have the `[RELOAD privilege](../grant/index)` to execute `RESET`.

 `RESET` acts as a stronger version of the [FLUSH](../flush/index) statement.

 The different `RESET` options are:

 


| Option | Description |
| --- | --- |
| [SLAVE ["connection\_name"] [ALL](../reset-slave/index)] | Deletes all [relay logs](../relay-log/index) from the slave and reset the replication position in the master [binary log](../binary-log/index). |
| [MASTER](../reset-master/index) | Deletes all old binary logs, makes the binary index file ([--log-bin-index](../mysqld-options-full-list/index)) empty and creates a new binary log file. This is useful when you want to reset the master to an initial state. If you want to just delete old, not used binary logs, you should use the [PURGE BINARY LOGS](../sql-commands-purge-logs/index) command. |
| QUERY CACHE | Removes all queries from [the query cache](../the-query-cache/index). See also [FLUSH QUERY CACHE](../flush-query-cache/index). |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/reset/>

SET
===

    Syntax
------

 
```
SET variable_assignment [, variable_assignment] ...

variable_assignment:
      user_var_name = expr
    | [GLOBAL | SESSION] system_var_name = expr
    | [@@global. | @@session. | @@]system_var_name = expr

```
 One can also set a user variable in any expression with this syntax:

 
```
user_var_name:= expr

```

Description
-----------

 The `SET` statement assigns values to different types of variables that affect the operation of the server or your client. Older versions of MySQL employed `SET OPTION`, but this syntax was deprecated in favor of `SET` without `OPTION`, and was removed in [MariaDB 10.0](../what-is-mariadb-100/index).

 Changing a system variable by using the SET statement does not make the change permanently. To do so, the change must be made in a [configuration file](../mysqld-configuration-files-and-groups/index).

 For setting variables on a per-query basis, see [SET STATEMENT](../set-statement/index).

 See [SHOW VARIABLES](../show-variables/index) for documentation on viewing server system variables.

 See [Server System Variables](../server-system-variables/index) for a list of all the system variables.

 ### GLOBAL / SESSION

 When setting a system variable, the scope can be specified as either GLOBAL or SESSION.

 A global variable change affects all new sessions. It does not affect any currently open sessions, including the one that made the change. 

 A session variable change affects the current session only.

 If the variable has a session value, not specifying either GLOBAL or SESSION will be the same as specifying SESSION. If the variable only has a global value, not specifying GLOBAL or SESSION will apply to the change to the global value.

 ### DEFAULT

 Setting a global variable to DEFAULT will restore it to the server default, and setting a session variable to DEFAULT will restore it to the current global value.

 Examples
--------

 * [innodb\_sync\_spin\_loops](../innodb-system-variables/index#innodb_sync_spin_loops) is a global variable.
* [skip\_parallel\_replication](../replication-and-binary-log-server-system-variables/index#skip_parallel_replication) is a session variable.
* [max\_error\_count](../server-system-variables/index#max_error_count) is both global and session.

 
```
SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication', 'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 64           |
| SKIP_PARALLEL_REPLICATION | OFF           | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

```

Setting the session values:

 
```
SET max_error_count=128;Query OK, 0 rows affected (0.000 sec)

SET skip_parallel_replication=ON;Query OK, 0 rows affected (0.000 sec)

SET innodb_sync_spin_loops=60;
ERROR 1229 (HY000): Variable 'innodb_sync_spin_loops' is a GLOBAL variable 
  and should be set with SET GLOBAL

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication', 'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 128           | 64           |
| SKIP_PARALLEL_REPLICATION | ON            | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

```

Setting the global values:

 
```
SET GLOBAL max_error_count=256;

SET GLOBAL skip_parallel_replication=ON;
ERROR 1228 (HY000): Variable 'skip_parallel_replication' is a SESSION variable 
  and can't be used with SET GLOBAL

SET GLOBAL innodb_sync_spin_loops=120;

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
 INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE 
  VARIABLE_NAME IN ('max_error_count', 'skip_parallel_replication', 'innodb_sync_spin_loops');
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 128           | 256          |
| SKIP_PARALLEL_REPLICATION | ON            | NULL         |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 120          |
+---------------------------+---------------+--------------+

```

[SHOW VARIABLES](../show-variables/index) will by default return the session value unless the variable is global only.

 
```
SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 128   |
+-----------------+-------+

SHOW VARIABLES LIKE 'skip_parallel_replication';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| skip_parallel_replication | ON    |
+---------------------------+-------+

SHOW VARIABLES LIKE 'innodb_sync_spin_loops';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_sync_spin_loops | 120   |
+------------------------+-------+

```

Using the inplace syntax:

 
```
SELECT (@a:=1);
+---------+
| (@a:=1) |
+---------+
|       1 |
+---------+

SELECT @a;
+------+
| @a   |
+------+
|    1 |
+------+

```

See Also
--------

 * [Using last\_value() to return data of used rows](../last_value/index)
* [SET STATEMENT](../set-statement/index)
* [SET Variable](../set-variable/index)
* [SET Data Type](../set-data-type/index)
* [DECLARE Variable](../declare-variable/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set/>

DROP SERVER
===========

    Syntax
------

 
```
DROP SERVER [ IF EXISTS ] server_name

```
 Description
-----------

 Drops the server definition for the server named *server\_name*. The corresponding row within the [mysql.servers table](../mysqlservers-table/index) will be deleted. This statement requires the [SUPER](../grant/index#super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [FEDERATED ADMIN](../grant/index#federated-admin) privilege.

 Dropping a server for a table does not affect any [FederatedX](../federatedx/index), [FEDERATED](../federated-storage-engine/index), [Connect](../connect/index) or [Spider](../spider/index) tables that used this connection information when they were created. 

 DROP SERVER is not written to the [binary log](../binary-log/index), irrespective of the [binary log format](../binary-log-formats/index) being used. From [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), [Galera](../galera/index) replicates the [CREATE SERVER](../create-server/index), [ALTER SERVER](../alter-server/index) and DROP SERVER statements.

 #### IF EXISTS

 If the IF EXISTS clause is used, MariaDB will not return an error if the server does not exist. Unlike all other statements, DROP SERVER IF EXISTS does not issue a note if the server does not exist. See [MDEV-9400](https://jira.mariadb.org/browse/MDEV-9400).

 Examples
--------

 
```
DROP SERVER s;

```

IF EXISTS:

 
```
DROP SERVER s;
ERROR 1477 (HY000): The foreign server name you are trying to reference 
  does not exist. Data source error:  s

DROP SERVER IF EXISTS s;
Query OK, 0 rows affected (0.00 sec)

```

See Also
--------

 * [CREATE SERVER](../create-server/index)
* [ALTER SERVER](../alter-server/index)
* [Spider Storage Engine](../spider/index)
* [FederatedX Storage Engine](../federatedx/index)
* [Connect Storage Engine](../connect/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-server/>

ROLLBACK
========

    The `ROLLBACK` statement rolls back (ends) a transaction, destroying any changes to SQL-data so that they never become visible to subsequent transactions. The required syntax for the `ROLLBACK` statement is as follows. 

 
```
ROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] 
[ TO [ SAVEPOINT ] {<savepoint name> | <simple target specification>} ]

```

The `ROLLBACK` statement will either end a transaction, destroying all data changes that happened during any of the transaction, or it will just destroy any data changes that happened since you established a savepoint. The basic form of the `ROLLBACK` statement is just the keyword `ROLLBACK` (the keyword `WORK` is simply noise and can be omitted without changing the effect). 

 The optional `AND CHAIN` clause is a convenience for initiating a new transaction as soon as the old transaction terminates. If `AND CHAIN` is specified, then there is effectively nothing between the old and new transactions, although they remain separate. The characteristics of the new transaction will be the same as the characteristics of the old one — that is, the new transaction will have the same access mode, isolation level and diagnostics area size (we'll discuss all of these shortly) as the transaction just terminated. The `AND NO CHAIN` option just tells your DBMS to end the transaction — that is, these four SQL statements are equivalent: 

 
```
ROLLBACK; 
ROLLBACK WORK; 
ROLLBACK AND NO CHAIN; 
ROLLBACK WORK AND NO CHAIN; 

```

All of them end a transaction without saving any transaction characteristics. The only other options, the equivalent statements: 

 
```
ROLLBACK AND CHAIN;
ROLLBACK WORK AND CHAIN;

```

both tell your DBMS to end a transaction, but to save that transaction's characteristics for the next transaction. 

 `ROLLBACK` is much simpler than `COMMIT`: it may involve no more than a few deletions (of Cursors, locks, prepared SQL statements and log-file entries). It's usually assumed that `ROLLBACK` can't fail, although such a thing is conceivable (for example, an encompassing transaction might reject an attempt to `ROLLBACK` because it's lining up for a `COMMIT`). 

 `ROLLBACK` cancels all effects of a transaction. It does not cancel effects on objects outside the DBMS's control (for example the values in host program variables or the settings made by some SQL/CLI function calls). But in general, it is a convenient statement for those situations when you say "oops, this isn't working" or when you simply don't care whether your temporary work becomes permanent or not.

 Here is a moot question. If all you've been doing is `SELECT`s, so that there have been no data changes, should you end the transaction with `ROLLBACK` or `COMMIT`? It shouldn't really matter because both `ROLLBACK` and `COMMIT` do the same transaction-terminating job. However, the popular conception is that `ROLLBACK` implies failure, so after a successful series of `SELECT` statements the convention is to end the transaction with `COMMIT` rather than `ROLLBACK`.

 MariaDB (and most other DBMSs) supports rollback of SQL-data change statements, but not of SQL-Schema statements. This means that if you use any of `CREATE`, `ALTER`, `DROP`, `GRANT`, `REVOKE`, you are implicitly committing at execution time.

 
```
INSERT INTO Table_2 VALUES(5); 
DROP TABLE Table_3 CASCADE; 
ROLLBACK; 

```

The result will be that both the `INSERT` and the `DROP` will go through as separate transactions so the `ROLLBACK` will have no effect. 

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rollback/>

REVOKE
======

    Privileges
----------

 ### Syntax

 
```
REVOKE 
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    FROM user [, user] ...

REVOKE ALL PRIVILEGES, GRANT OPTION
    FROM user [, user] ...

```

### Description

 The `REVOKE` statement enables system administrators to revoke privileges (or roles - see [section below](#roles)) from MariaDB accounts. Each account is named using the same format as for the `GRANT` statement; for example, '`jeffrey'@'localhost`'. If you specify only the user name part of the account name, a host name part of '``%``' is used. For details on the levels at which privileges exist, the allowable `priv_type` and `priv_level` values, and the syntax for specifying users and passwords, see [GRANT](../grant/index).

 To use the first `REVOKE` syntax, you must have the `GRANT OPTION` privilege, and you must have the privileges that you are revoking.

 To revoke all privileges, use the second syntax, which drops all global, database, table, column, and routine privileges for the named user or users:

 
```
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user [, user] ...

```

To use this `REVOKE` syntax, you must have the global [CREATE USER](../create-user/index) privilege or the [UPDATE](../update/index) privilege for the mysql database. See [GRANT](../grant/index).

 ### Examples

 
```
REVOKE SUPER ON *.* FROM 'alexander'@'localhost';

```

Roles
-----

 ### Syntax

 
```
REVOKE role  [, role ...]
    FROM grantee [, grantee2 ... ]

REVOKE ADMIN OPTION FOR role FROM grantee [, grantee2]

```

### Description

 `REVOKE` is also used to remove a [role](../roles/index) from a user or another role that it's previously been assigned to. If a role has previously been set as a [default role](../set-default-role/index), `REVOKE` does not remove the record of the default role from the [mysql.user](../mysqluser-table/index) table. If the role is subsequently granted again, it will again be the user's default. Use [SET DEFAULT ROLE NONE](../set-default-role/index) to explicitly remove this.

 Before [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/), the `REVOKE role` statement was not permitted in [prepared statements](../prepared-statements/index).

 ### Example

 
```
REVOKE journalist FROM hulda

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/revoke/>

RESTORE TABLE (removed)
=======================

    
**MariaDB until [5.3](../what-is-mariadb-53/index)**RESTORE TABLE was removed in [MariaDB 5.5](../what-is-mariadb-55/index).

 
Syntax
------

 
```
RESTORE TABLE tbl_name [, tbl_name] ... FROM '/path/to/backup/directory'
```

Description
-----------

 
**Note:** Like [BACKUP TABLE](../backup-table/index), this command was not reliable and has been removed in current versions of MariaDB. For doing a backup of MariaDB use [mysqldump](../mysqldump/index), [mysqlhotcopy](../mysqlhotcopy/index) or [XtraBackup](../backup-restore-and-import-xtrabackup/index). See [Backing Up and Restoring](../backing-up-and-restoring/index).

 
`RESTORE TABLE` restores the table or tables from a backup that was made with `[BACKUP TABLE](../backup-table/index)`. The directory should be specified as a full path name.

 Existing tables are not overwritten; if you try to restore over an existing table, an error occurs. Just as for `BACKUP TABLE`, `RESTORE TABLE` works only for [MyISAM](../myisam/index) tables. Restored tables are not replicated from master to slave.

 The backup for each table consists of its .frm format file and .MYD data file. The restore operation restores those files, and then uses them to rebuild the .MYI index file. Restoring takes longer than backing up due to the need to rebuild the indexes. The more indexes the table has, the longer it takes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/restore-table-removed/>

PURGE BINARY LOGS
=================

    Syntax
------

 
```
PURGE { BINARY | MASTER } LOGS
    { TO 'log_name' | BEFORE datetime_expr }

```

Description
-----------

 The `PURGE BINARY LOGS` statement deletes all the [binary log](../binary-log/index) files listed in the log index file prior to the specified log file name or date. `BINARY` and `MASTER` are synonyms. Deleted log files also are removed from the list recorded in the index file, so that the given log file becomes the first in the list.

 The datetime expression is in the format 'YYYY-MM-DD hh:mm:ss'. 

 
If a replica is active but has yet to read from a binary log file you attempt to delete, the statement will fail with an error. However, if the replica is not connected and has yet to read from a log file you delete, the file will be deleted, but the replica will be unable to continue replicating once it connects again.

 
This statement has no effect if the server was not started with the [--log-bin](../replication-and-binary-log-system-variables/index#log_bin) option to enable binary logging.

 To list the binary log files on the server, use [SHOW BINARY LOGS](../show-binary-logs/index). To see which files they are reading, use [SHOW SLAVE STATUS](../show-slave-status/index) (or [SHOW REPLICA STATUS](../show-replica-status/index) from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)). You can only delete the files that are older than the oldest file that is used by the slaves.

 To delete all binary log files, use [RESET MASTER](../reset-master/index). To move to a new log file (for example if you want to remove the current log file), use [FLUSH LOGS](../flush/index) before you execute `PURGE LOGS`.

 If the [expire\_logs\_days](../server-system-variables/index#expire_logs_days) server system variable is not set to 0, the server automatically deletes binary log files after the given number of days. From [MariaDB 10.6](../what-is-mariadb-106/index), the [binlog\_expire\_logs\_seconds](../replication-and-binary-log-system-variables/index#binlog_expire_logs_seconds) variable allows more precise control over binlog deletion, and takes precedence if both are non-zero.

 Requires the [SUPER](super) privilege or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [BINLOG ADMIN](../grant/index#binlog-admin) privilege, to run.

 Examples
--------

 
```
PURGE BINARY LOGS TO 'mariadb-bin.000063';

```


```
PURGE BINARY LOGS BEFORE '2013-04-21';

```


```
PURGE BINARY LOGS BEFORE '2013-04-22 09:55:22';

```

See Also
--------

 * [Using and Maintaining the Binary Log](../using-and-maintaining-the-binary-log/index)
* [FLUSH LOGS](../flush/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-commands-purge-logs/>

SHOW AUTHORS
============

    Syntax
------

 
```
SHOW AUTHORS

```

Description
-----------

 The `SHOW AUTHORS` statement displays information about the people who work on MariaDB. For each author, it displays Name, Location, and Comment values. All columns are encoded as latin1.

 These include:

 * First the active people in MariaDB are listed.
* Then the active people in MySQL.
* Last the people that have contributed to MariaDB/MySQL in the past.

 The order is somewhat related to importance of the contribution given to the MariaDB project, but this is not 100% accurate. There is still room for improvement and debate...

 Example
-------

 
```
SHOW AUTHORS\G
*************************** 1. row ***************************
    Name: Michael (Monty) Widenius
Location: Tusby, Finland
 Comment: Lead developer and main author
*************************** 2. row ***************************
    Name: Sergei Golubchik
Location: Kerpen, Germany
 Comment: Architect, Full-text search, precision math, plugin framework, merges etc
*************************** 3. row ***************************
    Name: Igor Babaev
Location: Bellevue, USA
 Comment: Optimizer, keycache, core work
*************************** 4. row ***************************
    Name: Sergey Petrunia
Location: St. Petersburg, Russia
 Comment: Optimizer
*************************** 5. row ***************************
    Name: Oleksandr Byelkin
Location: Lugansk, Ukraine
 Comment: Query Cache (4.0), Subqueries (4.1), Views (5.0)
*************************** 6. row ***************************
    Name: Timour Katchaounov
Location: Sofia , Bulgaria
 Comment: Optimizer
*************************** 7. row ***************************
    Name: Kristian Nielsen
Location: Copenhagen, Denmark
 Comment: Replication, Async client prototocol, General buildbot stuff
*************************** 8. row ***************************
    Name: Alexander (Bar) Barkov
Location: Izhevsk, Russia
 Comment: Unicode and character sets
*************************** 9. row ***************************
    Name: Alexey Botchkov (Holyfoot)
Location: Izhevsk, Russia
 Comment: GIS extensions, embedded server, precision math
*************************** 10. row ***************************
    Name: Daniel Bartholomew
Location: Raleigh, USA
 Comment: MariaDB documentation, Buildbot, releases
*************************** 11. row ***************************
    Name: Colin Charles
Location: Selangor, Malesia
 Comment: MariaDB documentation, talks at a LOT of conferences
*************************** 12. row ***************************
    Name: Sergey Vojtovich
Location: Izhevsk, Russia
 Comment: initial implementation of plugin architecture, maintained native storage engines (MyISAM, MEMORY, ARCHIVE, etc), rewrite of table cache
*************************** 13. row ***************************
    Name: Vladislav Vaintroub
Location: Mannheim, Germany
 Comment: MariaDB Java connector, new thread pool, Windows optimizations
*************************** 14. row ***************************
    Name: Elena Stepanova
Location: Sankt Petersburg, Russia
 Comment: QA, test cases
*************************** 15. row ***************************
    Name: Georg Richter
Location: Heidelberg, Germany
 Comment: New LGPL C connector, PHP connector
*************************** 16. row ***************************
    Name: Jan Lindström
Location: Ylämylly, Finland
 Comment: Working on InnoDB
*************************** 17. row ***************************
    Name: Lixun Peng
Location: Hangzhou, China
 Comment: Multi Source replication
*************************** 18. row ***************************
    Name: Olivier Bertrand
Location: Paris, France
 Comment: CONNECT storage engine
*************************** 19. row ***************************
    Name: Kentoku Shiba
Location: Tokyo, Japan
 Comment: Spider storage engine, metadata_lock_info Information schema
*************************** 20. row ***************************
    Name: Percona
Location: CA, USA
 Comment: XtraDB, microslow patches, extensions to slow log
*************************** 21. row ***************************
    Name: Vicentiu Ciorbaru
Location: Bucharest, Romania
 Comment: Roles
*************************** 22. row ***************************
    Name: Sudheera Palihakkara
Location: 
 Comment: PCRE Regular Expressions
*************************** 23. row ***************************
    Name: Pavel Ivanov
Location: USA
 Comment: Some patches and bug fixes
*************************** 24. row ***************************
    Name: Konstantin Osipov
Location: Moscow, Russia
 Comment: Prepared statements (4.1), Cursors (5.0), GET_LOCK (10.0)
*************************** 25. row ***************************
    Name: Ian Gilfillan
Location: South Africa
 Comment: MariaDB documentation
*************************** 26. row ***************************
    Name: Federico Razolli
Location: Italy
 Comment: MariaDB documentation Italian translation
*************************** 27. row ***************************
    Name: Guilhem Bichot
Location: Bordeaux, France
 Comment: Replication (since 4.0)
*************************** 28. row ***************************
    Name: Andrei Elkin
Location: Espoo, Finland
 Comment: Replication
*************************** 29. row ***************************
    Name: Dmitri Lenev
Location: Moscow, Russia
 Comment: Time zones support (4.1), Triggers (5.0)
*************************** 30. row ***************************
    Name: Marc Alff
Location: Denver, CO, USA
 Comment: Signal, Resignal, Performance schema
*************************** 31. row ***************************
    Name: Mikael Ronström
Location: Stockholm, Sweden
 Comment: NDB Cluster, Partitioning, online alter table
*************************** 32. row ***************************
    Name: Ingo Strüwing
Location: Berlin, Germany
 Comment: Bug fixing in MyISAM, Merge tables etc
*************************** 33. row ***************************
    Name: Marko Mäkelä
Location: Helsinki, Finland
 Comment: InnoDB core developer
...

```

### See Also

 * [SHOW CONTRIBUTORS](../show-contributors/index). This list [all members and sponsors of the MariaDB Foundation](https://mariadb.org/en/supporters) and other sponsors.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-authors/>

SHOW BINARY LOGS
================

    Syntax
------

 
```
SHOW BINARY LOGS
SHOW MASTER LOGS

```

Description
-----------

 Lists the [binary log](../binary-log/index) files on the server. This statement is used as part of the procedure described in `[PURGE BINARY LOGS](../purge-logs/index)`, that shows how to determine which logs can be purged.

 This statement requires the [SUPER](../grant/index#super) privilege, the [REPLICATION\_CLIENT](../grant/index#replication-client) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [BINLOG MONITOR](../grant/index#binlog-monitor) privilege.

 Examples
--------

 
```
SHOW BINARY LOGS;
+--------------------+-----------+
| Log_name           | File_size |
+--------------------+-----------+
| mariadb-bin.000001 |     19039 |
| mariadb-bin.000002 |    717389 |
| mariadb-bin.000003 |       300 |
| mariadb-bin.000004 |       333 |
| mariadb-bin.000005 |       899 |
| mariadb-bin.000006 |       125 |
| mariadb-bin.000007 |     18907 |
| mariadb-bin.000008 |     19530 |
| mariadb-bin.000009 |       151 |
| mariadb-bin.000010 |       151 |
| mariadb-bin.000011 |       125 |
| mariadb-bin.000012 |       151 |
| mariadb-bin.000013 |       151 |
| mariadb-bin.000014 |       125 |
| mariadb-bin.000015 |       151 |
| mariadb-bin.000016 |       314 |
+--------------------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-binary-logs/>

SHOW CONTRIBUTORS
=================

    Syntax
------

 
```
SHOW CONTRIBUTORS
```

Description
-----------

 The `SHOW CONTRIBUTORS` statement displays information about the companies and people who financially contribute to MariaDB. For each contributor, it displays `Name`, `Location`, and `Comment` values. All columns are encoded as `latin1`.

 It displays all [members and sponsors of the MariaDB Foundation](https://mariadb.org/en/supporters) as well as other financial contributors.

 Example
-------

 
```
SHOW CONTRIBUTORS;
+---------------------+-------------------------------+-------------------------------------------------------------+
| Name                | Location                      | Comment                                                     |
+---------------------+-------------------------------+-------------------------------------------------------------+
| Alibaba Cloud       | https://www.alibabacloud.com/ | Platinum Sponsor of the MariaDB Foundation                  |
| Tencent Cloud       | https://cloud.tencent.com     | Platinum Sponsor of the MariaDB Foundation                  |
| Microsoft           | https://microsoft.com/        | Platinum Sponsor of the MariaDB Foundation                  |
| MariaDB Corporation | https://mariadb.com           | Founding member, Platinum Sponsor of the MariaDB Foundation |
| ServiceNow          | https://servicenow.com        | Platinum Sponsor of the MariaDB Foundation                  |
| Intel               | https://www.intel.com         | Platinum Sponsor of the MariaDB Foundation                  |
| SIT                 | https://sit.org               | Platinum Sponsor of the MariaDB Foundation                  |
| Visma               | https://visma.com             | Gold Sponsor of the MariaDB Foundation                      |
| DBS                 | https://dbs.com               | Gold Sponsor of the MariaDB Foundation                      |
| IBM                 | https://www.ibm.com           | Gold Sponsor of the MariaDB Foundation                      |
| Automattic          | https://automattic.com        | Silver Sponsor of the MariaDB Foundation                    |
| Percona             | https://www.percona.com/      | Sponsor of the MariaDB Foundation                           |
| Galera Cluster      | https://galeracluster.com     | Sponsor of the MariaDB Foundation                           |
| Google              | USA                           | Sponsoring encryption, parallel replication and GTID        |
| Facebook            | USA                           | Sponsoring non-blocking API, LIMIT ROWS EXAMINED etc        |
| Ronald Bradford     | Brisbane, Australia           | EFF contribution for UC2006 Auction                         |
| Sheeri Kritzer      | Boston, Mass. USA             | EFF contribution for UC2006 Auction                         |
| Mark Shuttleworth   | London, UK.                   | EFF contribution for UC2006 Auction                         |
+---------------------+-------------------------------+-------------------------------------------------------------+

```

See Also
--------

 * [Log of MariaDB contributors](../log-of-mariadb-contributions/index).
* [SHOW AUTHORS](../show-authors/index) list the authors of MariaDB (including documentation, QA etc).
* [MariaDB Foundation page on contributing financially](https://mariadb.org/donate/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-contributors/>

SHOW CREATE EVENT
=================

    Syntax
------

 
```
SHOW CREATE EVENT event_name

```

Description
-----------

 This statement displays the `[CREATE EVENT](../create-event/index)` statement needed to re-create a given [event](../events/index), as well as the `[SQL\_MODE](../sql-mode/index)` that was used when the trigger has been created and the character set used by the connection. To find out which events are present, use `[SHOW EVENTS](../show-events/index)`.

 The output of this statement is unreliably affected by the `[sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create)` server system variable - see <http://bugs.mysql.com/bug.php?id=12719>

 The `[information\_schema.EVENTS](../information-schema-events-table/index)` table provides similar, but more complete, information.

 Examples
--------

 
```
SHOW CREATE EVENT test.e_daily\G
*************************** 1. row ***************************
               Event: e_daily
            sql_mode: 
           time_zone: SYSTEM
        Create Event: CREATE EVENT `e_daily`
                        ON SCHEDULE EVERY 1 DAY
                        STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR
                        ON COMPLETION NOT PRESERVE
                        ENABLE
                        COMMENT 'Saves total number of sessions then
                                clears the table each day'
                        DO BEGIN
                          INSERT INTO site_activity.totals (time, total)
                            SELECT CURRENT_TIMESTAMP, COUNT(*) 
                            FROM site_activity.sessions;
                          DELETE FROM site_activity.sessions;
                        END
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

```

See also
--------

 * [Events Overview](../events-overview/index)
* `[CREATE EVENT](../create-event/index)`
* `[ALTER EVENT](../alter-event/index)`
* `[DROP EVENT](../drop-event/index)`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-event/>

SHOW BINLOG EVENTS
==================

    Syntax
------

 
```
SHOW BINLOG EVENTS
   [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

```

Description
-----------

 Shows the events in the [binary log](../binary-log/index). If you do not specify '`log_name`', the first binary log is displayed.

 Requires the [BINLOG MONITOR](../grant/index#binlog-monitor) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) or the [REPLICATION SLAVE](../grant/index#replication-slave) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)).

 Example
-------

 
```
SHOW BINLOG EVENTS IN 'mysql_sandbox10019-bin.000002';
+-------------------------------+-----+-------------------+-----------+-------------+------------------------------------------------+
| Log_name                      | Pos | Event_type        | Server_id | End_log_pos | Info                                           |
+-------------------------------+-----+-------------------+-----------+-------------+------------------------------------------------+
| mysql_sandbox10019-bin.000002 |   4 | Format_desc       |         1 |         248 | Server ver: 10.0.19-MariaDB-log, Binlog ver: 4 |
| mysql_sandbox10019-bin.000002 | 248 | Gtid_list         |         1 |         273 | []                                             |
| mysql_sandbox10019-bin.000002 | 273 | Binlog_checkpoint |         1 |         325 | mysql_sandbox10019-bin.000002                  |
| mysql_sandbox10019-bin.000002 | 325 | Gtid              |         1 |         363 | GTID 0-1-1                                     |
| mysql_sandbox10019-bin.000002 | 363 | Query             |         1 |         446 | CREATE DATABASE blog                           |
| mysql_sandbox10019-bin.000002 | 446 | Gtid              |         1 |         484 | GTID 0-1-2                                     |
| mysql_sandbox10019-bin.000002 | 484 | Query             |         1 |         571 | use `blog`; CREATE TABLE bb (id INT)           |
+-------------------------------+-----+-------------------+-----------+-------------+------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-binlog-events/>

SHOW CREATE FUNCTION
====================

    Syntax
------

 
```
SHOW CREATE FUNCTION func_name

```

Description
-----------

 This statement is similar to [SHOW CREATE PROCEDURE](../show-create-procedure/index) but for [stored functions](../stored-functions/index).

 The output of this statement is unreliably affected by the [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) server system variable - see <http://bugs.mysql.com/bug.php?id=12719>

 Example
-------

 
```
SHOW CREATE FUNCTION VatCents\G
*************************** 1. row ***************************
            Function: VatCents
            sql_mode: 
     Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION `VatCents`(price DECIMAL(10,2)) RETURNS int(11)
    DETERMINISTIC
BEGIN
 DECLARE x INT;
 SET x = price * 114;
 RETURN x;
END
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [Stored Functions](../stored-functions/index)
* `[CREATE FUNCTION](../create-function/index)`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-function/>

Information Schema plugins: SHOW and FLUSH statements
=====================================================

    Information Schema plugins can support [SHOW](../show/index) and [FLUSH](../flush/index) statements.

 SHOW
----

 `SHOW` statements support is enabled automatically. A plugin only needs to specify column names for the `SHOW` statement in the `old_name` member of the field declaration structure. Columns with the `old_name` set to 0 will be hidden from the `SHOW` statement. If all columns are hidden, the `SHOW` statement will not work for this plugin.

 Note that `SHOW` statement is a user-friendly shortcut; it's easier to type and should be easier to view — if the Information Schema table contains many columns, the `SHOW` statement is supposed to display only most important columns and fit nicely on the 80x25 terminal screen.

 Consider an example, [LOCALES plugin](../locales-plugin/index):

 
```
static ST_FIELD_INFO locale_info_locale_fields_info[]=
{
  {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", 0},
  {"NAME", 255, MYSQL_TYPE_STRING, 0, 0, "Name", 0},
  {"DESCRIPTION", 255,  MYSQL_TYPE_STRING, 0, 0, "Description", 0},
  {"MAX_MONTH_NAME_LENGTH", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, 0},
  {"MAX_DAY_NAME_LENGTH", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, 0},
  {"DECIMAL_POINT", 2, MYSQL_TYPE_STRING, 0, 0, 0, 0},
  {"THOUSAND_SEP", 2, MYSQL_TYPE_STRING, 0, 0, 0, 0},
  {"ERROR_MESSAGE_LANGUAGE", 64, MYSQL_TYPE_STRING, 0, 0, "Error_Message_Language", 0},
  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0}
};

```

While the the [INFORMATION\_SCHEMA.LOCALES](../information-schema-locales-table/index) table has 8 columns, the [SHOW LOCALES](../show-locales/index) statement will only display 4 of them:

 
```
MariaDB [test]> show locales;
+-----+-------+-------------------------------------+------------------------+
| Id  | Name  | Description                         | Error_Message_Language |
+-----+-------+-------------------------------------+------------------------+
|   0 | en_US | English - United States             | english                |
|   1 | en_GB | English - United Kingdom            | english                |
|   2 | ja_JP | Japanese - Japan                    | japanese               |
|   3 | sv_SE | Swedish - Sweden                    | swedish                |
...

```

FLUSH
-----

 To support the `FLUSH` statement a plugin must declare the `reset_table` callback. For example, in the [QUERY\_RESPONSE\_TIME](../query_response_time-plugin/index) plugin:

 
```
static int query_response_time_info_init(void *p)
{
  ST_SCHEMA_TABLE *i_s_query_response_time= (ST_SCHEMA_TABLE *) p;
  i_s_query_response_time->fields_info= query_response_time_fields_info;
  i_s_query_response_time->fill_table= query_response_time_fill;
  i_s_query_response_time->reset_table= query_response_time_flush;
  query_response_time_init();
  return 0;
}

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-plugins-show-and-flush-statements/>

SHOW DATABASES
==============

    Syntax
------

 
```
SHOW {DATABASES | SCHEMAS}
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 `SHOW DATABASES` lists the databases on the MariaDB server host. `SHOW SCHEMAS` is a synonym for `SHOW DATABASES`. The `LIKE` clause, if present on its own, indicates which database names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 You see only those databases for which you have some kind of privilege, unless you have the global [SHOW DATABASES privilege](../grant/index). You can also get this list using the [mariadb-show](../mariadb-show/index) command.

 If the server was started with the `--skip-show-database` option, you cannot use this statement at all unless you have the [SHOW DATABASES privilege](../grant/index).

 The list of results returned by `SHOW DATABASES` is based on directories in the data directory, which is how MariaDB implements databases. It's possible that output includes directories that do not correspond to actual databases.

 The [Information Schema SCHEMATA table](../information-schema-schemata-table/index) also contains database information. 

 Examples
--------

 
```
SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+

```


```
SHOW DATABASES LIKE 'm%';
+---------------+
| Database (m%) |
+---------------+
| mysql         |
+---------------+

```

See Also
--------

 * [CREATE DATABASE](../create-database/index)
* [ALTER DATABASE](../alter-database/index)
* [DROP DATABASE](../drop-database/index)
* [SHOW CREATE DATABASE](../show-create-database/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [Information Schema SCHEMATA Table](../information-schema-schemata-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-databases/>

SHOW CREATE USER
================

    Syntax
------

 
```
SHOW CREATE USER user_name

```

Description
-----------

 Shows the [CREATE USER](../create-user/index) statement that created the given user. The statement requires the [SELECT](../grant/index#table-privileges) privilege for the [mysql](../the-mysql-database-tables/index) database, except for the current user.

 Examples
--------

 
```
CREATE USER foo4@test require cipher 'text' 
  issuer 'foo_issuer' subject 'foo_subject';

SHOW CREATE USER foo4@test\G
*************************** 1. row ***************************
CREATE USER 'foo4'@'test' 
  REQUIRE ISSUER 'foo_issuer' 
  SUBJECT 'foo_subject' 
  CIPHER 'text'

```

[User Password Expiry](../user-password-expiry/index):

 
```
CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY;

SHOW CREATE USER 'monty'@'localhost';
+------------------------------------------------------------------+
| CREATE USER for monty@localhost                                  |
+------------------------------------------------------------------+
| CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 120 DAY |
+------------------------------------------------------------------+

```

See Also
--------

 * [CREATE USER](../create-user/index)
* [ALTER USER](../alter-user/index)
* [SHOW GRANTS](../show-grants/index) shows the `GRANTS/PRIVILEGES` for a user.
* [SHOW PRIVILEGES](../show-privileges/index) shows the privileges supported by MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-user/>

SHOW EVENTS
===========

    Syntax
------

 
```
SHOW EVENTS [{FROM | IN} schema_name]
    [LIKE 'pattern' | WHERE expr]

```

Description
-----------

 Shows information about Event Manager [events](../events/index) (created with `[CREATE EVENT](../create-event/index)`). Requires the `[EVENT](../grant/index#database-privileges)` privilege. Without any arguments, `SHOW EVENTS` lists all of the events in the current schema:

 
```
SELECT CURRENT_USER(), SCHEMA();
+----------------+----------+
| CURRENT_USER() | SCHEMA() |
+----------------+----------+
| jon@ghidora    | myschema |
+----------------+----------+

SHOW EVENTS\G
*************************** 1. row ***************************
                  Db: myschema
                Name: e_daily
             Definer: jon@ghidora
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 10
      Interval field: SECOND
              Starts: 2006-02-09 10:41:23
                Ends: NULL
              Status: ENABLED
          Originator: 0
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

```

To see the event action, use `[SHOW CREATE EVENT](../show-create-event/index)` instead, or look at the `[information\_schema.EVENTS](../information-schema-events-table/index)` table.

 To see events for a specific schema, use the `FROM` clause. For example, to see events for the test schema, use the following statement:

 
```
SHOW EVENTS FROM test;

```

The `LIKE` clause, if present, indicates which event names to match. The `WHERE` clause can be given to select rows using more general conditions, as discussed in [Extended Show](../extended-show/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-events/>

SHOW CREATE DATABASE
====================

    Syntax
------

 
```
SHOW CREATE {DATABASE | SCHEMA} db_name

```
 Description
-----------

 Shows the [CREATE DATABASE](../create-database/index) statement that creates the given database. `SHOW CREATE SCHEMA` is a synonym for `SHOW CREATE DATABASE`. `SHOW CREATE DATABASE` quotes database names according to the value of the [sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create) server system variable.

 Examples
--------

 
```
SHOW CREATE DATABASE test;
+----------+-----------------------------------------------------------------+
| Database | Create Database                                                 |
+----------+-----------------------------------------------------------------+
| test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-----------------------------------------------------------------+

SHOW CREATE SCHEMA test;
+----------+-----------------------------------------------------------------+
| Database | Create Database                                                 |
+----------+-----------------------------------------------------------------+
| test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-----------------------------------------------------------------+

```

With `[sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create)` off:

 
```
SHOW CREATE DATABASE test;
+----------+---------------------------------------------------------------+
| Database | Create Database                                               |
+----------+---------------------------------------------------------------+
| test     | CREATE DATABASE test /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+---------------------------------------------------------------+

```

With a comment, from [MariaDB 10.5](../what-is-mariadb-105/index):

 
```
SHOW CREATE DATABASE p;
+----------+--------------------------------------------------------------------------------------+
| Database | Create Database                                                                      |
+----------+--------------------------------------------------------------------------------------+
| p        | CREATE DATABASE `p` /*!40100 DEFAULT CHARACTER SET latin1 */ COMMENT 'presentations' |
+----------+--------------------------------------------------------------------------------------+

```

See Also
--------

 * [CREATE DATABASE](../create-database/index)
* [ALTER DATABASE](../alter-database/index)
* [Character Sets and Collations](../character-sets-and-collations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-database/>

SHOW ERRORS
===========

    Syntax
------

 
```
SHOW ERRORS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) ERRORS

```
 Description
-----------

 This statement is similar to [SHOW WARNINGS](../show-warnings/index), except that instead of displaying errors, warnings, and notes, it displays only errors.

 The `LIMIT` clause has the same syntax as for the [SELECT](../select/index) statement.

 The `SHOW COUNT(*) ERRORS` statement displays the number of errors. You can also retrieve this number from the [error\_count](../server-system-variables/index#error_count) variable.

 
```
SHOW COUNT(*) ERRORS;
SELECT @@error_count;

```

The value of [error\_count](../server-system-variables/index#error_count) might be greater than the number of messages displayed by [SHOW WARNINGS](../show-warnings/index) if the [max\_error\_count](../server-system-variables/index#max_error_count) system variable is set so low that not all messages are stored.

 For a list of MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).

 Examples
--------

 
```
SELECT f();
ERROR 1305 (42000): FUNCTION f does not exist

SHOW COUNT(*) ERRORS;
+-----------------------+
| @@session.error_count |
+-----------------------+
|                     1 |
+-----------------------+

SHOW ERRORS;
+-------+------+---------------------------+
| Level | Code | Message                   |
+-------+------+---------------------------+
| Error | 1305 | FUNCTION f does not exist |
+-------+------+---------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-errors/>

SHOW CLIENT\_STATISTICS
=======================

    Syntax
------

 
```
SHOW CLIENT_STATISTICS

```

Description
-----------

 The `SHOW CLIENT_STATISTICS` statement is part of the [User Statistics](../user-statistics/index) feature. It was removed as a separate statement in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), but effectively replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index) statement. The [information\_schema.CLIENT\_STATISTICS](../information-schema-client_statistics-table/index) table holds statistics about client connections.

 The [userstat](../server-system-variables/index#userstat) system variable must be set to 1 to activate this feature. See the [User Statistics](../user-statistics/index) and [information\_schema.CLIENT\_STATISTICS](../information-schema-client_statistics-table/index) articles for more information.

 Example
-------

 
```
SHOW CLIENT_STATISTICS\G
*************************** 1. row ***************************
                Client: localhost
     Total_connections: 35
Concurrent_connections: 0
        Connected_time: 708
             Busy_time: 2.5557979999999985
              Cpu_time: 0.04123740000000002
        Bytes_received: 3883
            Bytes_sent: 21595
  Binlog_bytes_written: 0
             Rows_read: 18
             Rows_sent: 115
          Rows_deleted: 0
         Rows_inserted: 0
          Rows_updated: 0
       Select_commands: 70
       Update_commands: 0
        Other_commands: 0
   Commit_transactions: 1
 Rollback_transactions: 0
    Denied_connections: 0
      Lost_connections: 0
         Access_denied: 0
         Empty_queries: 35

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-client_statistics/>

KILL [CONNECTION | QUERY]
=========================

    Syntax
------

 
```
KILL [HARD | SOFT] { {CONNECTION|QUERY} thread_id | QUERY ID query_id | USER user_name }


```
 Description
-----------

 Each connection to mysqld runs in a separate thread. You can see which threads are running with the `SHOW PROCESSLIST` statement and kill a thread with the `KILL thread_id` statement. `KILL` allows the optional `CONNECTION` or `QUERY` modifier:

 * `KILL CONNECTION` is the same as `KILL` with no modifier: It terminates the connection associated with the given thread or query id.
* `KILL QUERY` terminates the statement that the connection thread\_id is currently executing, but leaves the connection itself intact.
* `KILL QUERY ID` terminates the query by query\_id, leaving the connection intact.

 If a connection is terminated that has an active transaction, the transaction will be rolled back. If only a query is killed, the current transaction will stay active. See also [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout).

 If you have the [PROCESS](../grant/index#process) privilege, you can see all threads. If you have the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [CONNECTION ADMIN](../grant/index#connection-admin) privilege, you can kill all threads and statements. Otherwise, you can see and kill only your own threads and statements.

 
Killing queries that repair or create indexes on MyISAM and Aria tables may result in corrupted tables. Use the `SOFT` option to avoid this!

 
The `HARD` option (default) kills a command as soon as possible. If you use `SOFT`, then critical operations that may leave a table in an inconsistent state will not be interrupted. Such operations include `REPAIR` and `INDEX` creation for [MyISAM](../myisam/index) and [Aria](../aria/index) tables ([REPAIR TABLE](../repair-table/index), [OPTIMIZE TABLE](../optimize-table/index)).

 `KILL ... USER username` will kill all connections/queries for a given user. `USER` can be specified one of the following ways:

 * username (Kill without regard to hostname)
* username@hostname
* [CURRENT\_USER](../current_user/index) or [CURRENT\_USER()](../current_user/index)

 If you specify a thread id and that thread does not exist, you get the following error:

 
```
ERROR 1094 (HY000): Unknown thread id: <thread_id>

```

If you specify a query id that doesn't exist, you get the following error:

 
```
ERROR 1957 (HY000): Unknown query id: <query_id>

```

However, if you specify a user name, no error is issued for non-connected (or even non-existing) users. To check if the connection/query has been killed, you can use the [ROW\_COUNT()](../row_count/index) function.

 A client whose connection is killed receives the following error:

 
```
ERROR 1317 (70100): Query execution was interrupted

```

To obtain a list of existing sessions, use the [SHOW PROCESSLIST](../show-processlist/index) statement or query the [Information Schema](../information-schema/index) [PROCESSLIST](../information-schema-processlist-table/index) table.

 **Note:** You cannot use `KILL` with the Embedded MariaDB Server library because the embedded server merely runs inside the threads of the host application. It does not create any connection threads of its own.

 **Note:** You can also use `mariadb-admin kill thread_id [,thread_id...]` to kill connections. To get a list of running queries, use `mariadb-admin processlist`. See [mariadb-admin](../mariadb-admin/index).

 [Percona Toolkit](http://www.percona.com/doc/percona-toolkit/) contains a program, [pt-kill](http://www.percona.com/doc/percona-toolkit/pt-kill.html) that can be used to automatically kill connections that match certain criteria. For example, it can be used to terminate idle connections, or connections that have been busy for more than 60 seconds.

 See Also
--------

 * [Query limits and timeouts](../query-limits-and-timeouts/index)
* [Aborting statements that exceed a certain time to execute](../aborting-statements/index)
* [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/kill/>

SHOW EXPLAIN
============

    Syntax
------

 
```
SHOW EXPLAIN [FORMAT=JSON] FOR <connection_id>;
EXPLAIN [FORMAT=JSON] FOR CONNECTION <connection_id>;

```

Description
-----------

 The `SHOW EXPLAIN` command allows one to get an [EXPLAIN](../explain/index) (that is, a description of a query plan) of a query running in a certain connection.

 
```
SHOW EXPLAIN FOR <connection_id>;

```

will produce an `EXPLAIN` output for the query that connection number `connection_id` is running. The connection id can be obtained with [SHOW PROCESSLIST](../show-processlist/index).

 
```
SHOW EXPLAIN FOR 1;
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows    | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
|    1 | SIMPLE      | tbl   | index | NULL          | a    | 5       | NULL | 1000107 | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
1 row in set, 1 warning (0.00 sec)

```

The output is always accompanied with a warning which shows the query the target connection is running (this shows what the `EXPLAIN` is for):

 
```
SHOW WARNINGS;
+-------+------+------------------------+
| Level | Code | Message                |
+-------+------+------------------------+
| Note  | 1003 | select sum(a) from tbl |
+-------+------+------------------------+
1 row in set (0.00 sec)

```

### EXPLAIN FOR CONNECTION

 
**MariaDB starting with [10.9](../what-is-mariadb-109/index)**The `EXPLAIN FOR CONNECTION` syntax was added for MySQL compatibility.

 
### FORMAT=JSON

 
**MariaDB starting with [10.9](../what-is-mariadb-109/index)**`SHOW EXPLAIN [FORMAT=JSON] FOR <connection_id>` extends `SHOW EXPLAIN` to return more detailed JSON output. 

 
### Possible Errors

 The output can be only produced if the target connection is *currently* running a query, which has a ready query plan. If this is not the case, the output will be:

 
```
SHOW EXPLAIN FOR 2;
ERROR 1932 (HY000): Target is not running an EXPLAINable command

```

You will get this error when:

 * the target connection is not running a command for which one can run `EXPLAIN`
* the target connection is running a command for which one can run `EXPLAIN`, but
	+ there is no query plan yet (for example, tables are open and locks are acquired before the query plan is produced)

 ### Differences Between SHOW EXPLAIN and EXPLAIN Outputs

 #### Background

 In MySQL, `EXPLAIN` execution takes a slightly different route from the way the real query (typically the `SELECT`) is optimized. This is unfortunate, and has caused a number of bugs in `EXPLAIN`. (For example, see [MDEV-326](https://jira.mariadb.org/browse/MDEV-326), [MDEV-410](https://jira.mariadb.org/browse/MDEV-410), and [lp:1013343](https://bugs.launchpad.net/maria/+bug/1013343). [lp:992942](https://bugs.launchpad.net/maria/+bug/992942) is not directly about `EXPLAIN`, but it also would not have existed if MySQL didn't try to delete parts of a query plan in the middle of the query) 

 `SHOW EXPLAIN` examines a running `SELECT`, and hence its output may be slightly different from what `EXPLAIN SELECT` would produce. We did our best to make sure that either the difference is negligible, or `SHOW EXPLAIN`'s output is closer to reality than `EXPLAIN`'s output.

 #### List of Recorded Differences

 * `SHOW EXPLAIN` may have Extra='`no matching row in const table`', where `EXPLAIN` would produce Extra='`Impossible WHERE ...`'
* For queries with subqueries, `SHOW EXPLAIN` may print `select_type==PRIMARY` where regular `EXPLAIN` used to print `select_type==SIMPLE`, or vice versa.

 #### Required Permissions

 Running `SHOW EXPLAIN` requires the same permissions as running `SHOW PROCESSLIST` would.

 See Also
--------

 * [EXPLAIN](../explain/index)
* [EXPLAIN ANALYZE](../explain-analyze/index), which will perform a query and outputs enhanced `EXPLAIN` results.
* It is also possible to [save EXPLAIN into the slow query log](../explain-in-the-slow-query-log/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-explain/>

SHOW COLUMNS
============

    Syntax
------

 
```
SHOW [FULL] {COLUMNS | FIELDS} FROM tbl_name [FROM db_name]
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 `SHOW COLUMNS` displays information about the columns in a given table. It also works for views. The `LIKE` clause, if present on its own, indicates which column names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 If the data types differ from what you expect them to be based on a `CREATE TABLE` statement, note that MariaDB sometimes changes data types when you create or alter a table. The conditions under which this occurs are described in the [Silent Column Changes](../silent-column-changes/index) article.

 The `FULL` keyword causes the output to include the column collation and comments, as well as the privileges you have for each column.

 You can use `db_name.tbl_name` as an alternative to the `tbl_name FROM db_name` syntax. In other words, these two statements are equivalent:

 
```
SHOW COLUMNS FROM mytable FROM mydb;
SHOW COLUMNS FROM mydb.mytable;

```

`SHOW COLUMNS` displays the following values for each table column:

 **Field** indicates the column name.

 **Type** indicates the column data type.

 **Collation** indicates the collation for non-binary string columns, or NULL for other columns. This value is displayed only if you use the FULL keyword.

 The **Null** field contains YES if NULL values can be stored in the column, NO if not.

 The **Key** field indicates whether the column is indexed:

 * If **Key** is empty, the column either is not indexed or is indexed only as a secondary column in a multiple-column, non-unique index.
* If **Key** is ***PRI***, the column is a `PRIMARY KEY` or is one of the columns in a multiple-column `PRIMARY KEY`.
* If **Key** is ***UNI***, the column is the first column of a unique-valued index that cannot contain `NULL` values.
* If **Key** is ***MUL***, multiple occurrences of a given value are allowed within the column. The column is the first column of a non-unique index or a unique-valued index that can contain `NULL` values.

 If more than one of the **Key** values applies to a given column of a table, **Key** displays the one with the highest priority, in the order PRI, UNI, MUL.

 A `UNIQUE` index may be displayed as `PRI` if it cannot contain `NULL` values and there is no `PRIMARY KEY` in the table. A `UNIQUE` index may display as `MUL` if several columns form a composite `UNIQUE` index; although the combination of the columns is unique, each column can still hold multiple occurrences of a given value.

 The **Default** field indicates the default value that is assigned to the column.

 The **Extra** field contains any additional information that is available about a given column.

 


| Value | Description |
| --- | --- |
| `AUTO_INCREMENT` | The column was created with the `AUTO_INCREMENT` keyword. |
| `PERSISTENT` | The column was created with the `PERSISTENT` keyword. (New in 5.3) |
| `VIRTUAL` | The column was created with the `VIRTUAL` keyword. (New in 5.3) |
| on update `CURRENT_TIMESTAMP` | The column is a `TIMESTAMP` column that is automatically updated on `INSERT` and `UPDATE`. |

 
**Privileges** indicates the privileges you have for the column. This value is displayed only if you use the `FULL` keyword.

 **Comment** indicates any comment the column has. This value is displayed only if you use the `FULL` keyword.

 `SHOW FIELDS` is a synonym for `SHOW COLUMNS`. Also [DESCRIBE](../describe/index) and [EXPLAIN](../explain/index) can be used as shortcuts.

 You can also list a table's columns with: 

 
```
mariadb-show db_name tbl_name

```

See the [mariadb-show](../mariadb-show/index) command for more details.

 The [DESCRIBE](../describe/index) statement provides information similar to `SHOW COLUMNS`. The [information\_schema.COLUMNS](../information-schema-columns-table/index) table provides similar, but more complete, information.

 The [SHOW CREATE TABLE](../show-create-table/index), [SHOW TABLE STATUS](../show-table-status/index), and [SHOW INDEX](../show-index/index) statements also provide information about tables.

 Examples
--------

 
```
SHOW COLUMNS FROM city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | NO   |     |         |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | NO   |     | 0       |                |
+------------+----------+------+-----+---------+----------------+

```


```
SHOW COLUMNS FROM employees WHERE Type LIKE 'Varchar%';
+---------------+-------------+------+-----+---------+-------+
| Field         | Type        | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| first_name    | varchar(30) | NO   | MUL | NULL    |       |
| last_name     | varchar(40) | NO   |     | NULL    |       |
| position      | varchar(25) | NO   |     | NULL    |       |
| home_address  | varchar(50) | NO   |     | NULL    |       |
| home_phone    | varchar(12) | NO   |     | NULL    |       |
| employee_code | varchar(25) | NO   | UNI | NULL    |       |
+---------------+-------------+------+-----+---------+-------+

```

See Also
--------

 * [DESCRIBE](../describe/index)
* [mariadb-show](../mariadb-show/index)
* [SHOW CREATE TABLE](../show-create-table/index)
* [SHOW TABLE STATUS](../show-table-status/index)
* [SHOW INDEX](../show-index/index)
* [Extended SHOW](../extended-show/index)
* [Silent Column Changes](../silent-column-changes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-columns/>

SHOW FUNCTION STATUS
====================

    Syntax
------

 
```
SHOW FUNCTION STATUS
    [LIKE 'pattern' | WHERE expr]

```

Description
-----------

 This statement is similar to `[SHOW PROCEDURE STATUS](../show-procedure-status/index)` but for [stored functions](../stored-functions/index).

 The LIKE clause, if present on its own, indicates which function names to match. 

 The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The `[information\_schema.ROUTINES](../information-schema-routines-table/index)` table contains more detailed information.

 Examples
--------

 Showing all stored functions:

 
```
SHOW FUNCTION STATUS\G
*************************** 1. row ***************************
                  Db: test
                Name: VatCents
                Type: FUNCTION
             Definer: root@localhost
            Modified: 2013-06-01 12:40:31
             Created: 2013-06-01 12:40:31
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Stored functions whose name starts with 'V': 

 
```
SHOW FUNCTION STATUS LIKE 'V%' \G
*************************** 1. row ***************************
                  Db: test
                Name: VatCents
                Type: FUNCTION
             Definer: root@localhost
            Modified: 2013-06-01 12:40:31
             Created: 2013-06-01 12:40:31
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Stored functions with a security type of 'DEFINER':

 
```
SHOW FUNCTION STATUS WHERE Security_type LIKE 'DEFINER' \G
*************************** 1. row ***************************
                  Db: test
                Name: VatCents
                Type: FUNCTION
             Definer: root@localhost
            Modified: 2013-06-01 12:40:31
             Created: 2013-06-01 12:40:31
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-function-status/>

SHOW ENGINE
===========

    Syntax
------

 
```
SHOW ENGINE engine_name {STATUS | MUTEX}

```

Description
-----------

 `SHOW ENGINE` displays operational information about a storage engine. The following statements currently are supported:

 
```
SHOW ENGINE INNODB STATUS
SHOW ENGINE INNODB MUTEX
SHOW ENGINE PERFORMANCE_SCHEMA STATUS
SHOW ENGINE ROCKSDB STATUS

```

If the [Sphinx Storage Engine](../sphinxse/index) is installed, the following is also supported:

 
```
SHOW ENGINE SPHINX STATUS

```

See `[SHOW ENGINE SPHINX STATUS](../about-sphinxse/index#show-engine-sphinx-status)`.

 Older (and now removed) synonyms were `SHOW INNODB STATUS` for `SHOW ENGINE INNODB STATUS` and `SHOW MUTEX STATUS` for `SHOW ENGINE INNODB MUTEX`.

 ### SHOW ENGINE INNODB STATUS

 `SHOW ENGINE INNODB STATUS` displays extensive information from the standard InnoDB Monitor about the state of the InnoDB storage engine. See `[SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index)` for more.

 ### SHOW ENGINE INNODB MUTEX

 `SHOW ENGINE INNODB MUTEX` displays InnoDB mutex statistics.

 The statement displays the following output fields:

 * **Type:** Always InnoDB.
* **Name:** The source file where the mutex is implemented, and the line number in the file where the mutex is created. The line number is dependent on the MariaDB version.
* **Status:** This field displays the following values if `UNIV_DEBUG` was defined at compilation time (for example, in include/univ.h in the InnoDB part of the source tree). Only the `os_waits` value is displayed if `UNIV_DEBUG` was not defined. Without `UNIV_DEBUG`, the information on which the output is based is insufficient to distinguish regular mutexes and mutexes that protect rw-locks (which allow multiple readers or a single writer). Consequently, the output may appear to contain multiple rows for the same mutex.
	+ **count** indicates how many times the mutex was requested.
	+ **spin\_waits** indicates how many times the spinlock had to run.
	+ **spin\_rounds** indicates the number of spinlock rounds. (spin\_rounds divided by spin\_waits provides the average round count.)
	+ **os\_waits** indicates the number of operating system waits. This occurs when the spinlock did not work (the mutex was not locked during the spinlock and it was necessary to yield to the operating system and wait).
	+ **os\_yields** indicates the number of times a the thread trying to lock a mutex gave up its timeslice and yielded to the operating system (on the presumption that allowing other threads to run will free the mutex so that it can be locked).
	+ **os\_wait\_times** indicates the amount of time (in ms) spent in operating system waits, if the timed\_mutexes system variable is 1 (ON). If timed\_mutexes is 0 (OFF), timing is disabled, so os\_wait\_times is 0. timed\_mutexes is off by default.

 Information from this statement can be used to diagnose system problems. For example, large values of spin\_waits and spin\_rounds may indicate scalability problems.

 The `[information\_schema](../information-schema/index).[INNODB\_MUTEXES](../information-schema-innodb_mutexes-table/index)` table provides similar information.

 ### SHOW ENGINE PERFORMANCE\_SCHEMA STATUS

 This statement shows how much memory is used for `[performance\_schema](../performance-schema/index)` tables and internal buffers.

 The output contains the following fields:

 * **Type:** Always `performance_schema`.
* **Name:** The name of a table, the name of an internal buffer, or the `performance_schema` word, followed by a dot and an attribute. Internal buffers names are enclosed by parenthesis. `performance_schema` means that the attribute refers to the whole database (it is a total).
* **Status:** The value for the attribute.

 The following attributes are shown, in this order, for all tables:

 * **row\_size:** The memory used for an individual record. This value will never change.
* **row\_count:** The number of rows in the table or buffer. For some tables, this value depends on a server system variable.
* **memory:** For tables and `performance_schema`, this is the result of `row_size` \* `row_count`.

 For internal buffers, the attributes are:

 * **count**
* **size**

 ### SHOW ENGINE ROCKSDB STATUS

 See also [MyRocks Performance Troubleshooting](../myrocks-performance-troubleshooting/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-engine/>

SHOW GRANTS
===========

    Syntax
------

 
```
SHOW GRANTS [FOR user|role]

```

Description
-----------

 The `SHOW GRANTS` statement lists privileges granted to a particular user or role.

 ### Users

 The statement lists the [GRANT](../grant/index) statement or statements that must be issued to duplicate the privileges that are granted to a MariaDB user account. The account is named using the same format as for the `GRANT` statement; for example, '`jeffrey'@'localhost`'. If you specify only the user name part of the account name, a host name part of '`%`' is used. For additional information about specifying account names, see [GRANT](../grant/index).

 
```
SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

```

To list the privileges granted to the account that you are using to connect to the server, you can use any of the following statements:

 
```
SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

```

If `SHOW GRANTS FOR CURRENT_USER` (or any of the equivalent syntaxes) is used in `DEFINER` context (such as within a stored procedure that is defined with `SQL SECURITY DEFINER`), the grants displayed are those of the definer and not the invoker.

 Note that the `DELETE HISTORY` privilege, introduced in [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/), was displayed as `DELETE VERSIONING ROWS` when running `SHOW GRANTS` until [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/) ([MDEV-17655](https://jira.mariadb.org/browse/MDEV-17655)).

 ### Roles

 `SHOW GRANTS` can also be used to view the privileges granted to a [role](../roles/index).

 #### Example

 
```
SHOW GRANTS FOR journalist;
+------------------------------------------+
| Grants for journalist                    |
+------------------------------------------+
| GRANT USAGE ON *.* TO 'journalist'       |
| GRANT DELETE ON `test`.* TO 'journalist' |
+------------------------------------------+

```

### FOR PUBLIC

 
**MariaDB starting with [10.11](../what-is-mariadb-1011/index)**[GRANT ... TO PUBLIC](../grant/index#to-public) was introduced in [MariaDB 10.11](../what-is-mariadb-1011/index) to grant privileges to all users. `SHOW GRANTS FOR PUBLIC` shows all these grants.

 
```
SHOW GRANTS FOR public;
+------------------------------------------------+
| Grants for PUBLIC                              |
+------------------------------------------------+
| GRANT ALL PRIVILEGES ON `dev_db`.* TO `PUBLIC` |
+------------------------------------------------+

```


See Also
--------

 * [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [SHOW CREATE USER](../show-create-user/index) shows how the user was created.
* [SHOW PRIVILEGES](../show-privileges/index) shows the privileges supported by MariaDB.
* [Roles](../roles/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-grants/>

SHOW OPEN TABLES
================

    Syntax
------

 
```
SHOW OPEN TABLES [FROM db_name]
    [LIKE 'pattern' | WHERE expr]

```

Description
-----------

  `SHOW OPEN TABLES` lists the non-`TEMPORARY` tables that are currently open in the table cache. See <http://dev.mysql.com/doc/refman/5.1/en/table-cache.html>.

 The `FROM` and `LIKE` clauses may be used.

 The `FROM` clause, if present, restricts the tables shown to those present in the `db_name` database. 

 The `LIKE` clause, if present on its own, indicates which table names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The following information is returned:

 


| Column | Description |
| --- | --- |
| Database | Database name. |
| Name | Table name. |
| In\_use | Number of table instances being used. |
| Name\_locked | `1` if the table is name-locked, e.g. if it is being dropped or renamed, otherwise `0`. |

 
Before [MariaDB 5.5](../what-is-mariadb-55/index), each use of, for example, [LOCK TABLE ... WRITE](../lock-tables-and-unlock-tables/index) would increment `In_use` for that table. With the implementation of the metadata locking improvements in [MariaDB 5.5](../what-is-mariadb-55/index), `LOCK TABLE... WRITE` acquires a strong MDL lock, and concurrent connections will wait on this MDL lock, so any subsequent `LOCK TABLE... WRITE` will not increment `In_use`.

 Example
-------

 
```
SHOW OPEN TABLES;
+----------+---------------------------+--------+-------------+
| Database | Table                     | In_use | Name_locked |
+----------+---------------------------+--------+-------------+
...
| test     | xjson                     |      0 |           0 |
| test     | jauthor                   |      0 |           0 |
| test     | locks                     |      1 |           0 |
...
+----------+---------------------------+--------+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-open-tables/>

SHOW INDEX
==========

    Syntax
------

 
```
SHOW {INDEX | INDEXES | KEYS} 
 FROM tbl_name [FROM db_name]
 [WHERE expr]

```
 Description
-----------

 `SHOW INDEX` returns table index information. The format resembles that of the SQLStatistics call in ODBC.

 You can use `db_name.tbl_name` as an alternative to the `tbl_name FROM db_name` syntax. These two statements are equivalent:

 
```
SHOW INDEX FROM mytable FROM mydb;
SHOW INDEX FROM mydb.mytable;

```

`SHOW KEYS` and `SHOW INDEXES` are synonyms for `SHOW INDEX`.

 You can also list a table's indexes with the [mariadb-show](../mariadb-show/index) command: 

 
```
mariadb-show -k db_name tbl_name

```

The [information\_schema.STATISTICS](../information-schema-statistics-table/index) table stores similar information.

 The following fields are returned by `SHOW INDEX`.

 


| Field | Description |
| --- | --- |
| **`Table`** | Table name |
| **`Non_unique`** | `1` if the index permits duplicate values, `0` if values must be unique. |
| **`Key_name`** | Index name. The primary key is always named `PRIMARY`. |
| **`Seq_in_index`** | The column's sequence in the index, beginning with `1`. |
| **`Column_name`** | Column name. |
| **`Collation`** | Either `A`, if the column is sorted in ascending order in the index, or `NULL` if it's not sorted. |
| **`Cardinality`** | Estimated number of unique values in the index. The cardinality statistics are calculated at various times, and can help the optimizer make improved decisions. |
| **`Sub_part`** | `NULL` if the entire column is included in the index, or the number of included characters if not. |
| **`Packed`** | `NULL` if the index is not packed, otherwise how the index is packed. |
| **`Null`** | `NULL` if `NULL` values are permitted in the column, an empty string if `NULL`s are not permitted. |
| **`Index_type`** | The index type, which can be `BTREE`, `FULLTEXT`, `HASH` or `RTREE`. See [Storage Engine Index Types](../storage-engine-index-types/index). |
| **`Comment`** | Other information, such as whether the index is disabled. |
| **`Index_comment`** | Contents of the `COMMENT` attribute when the index was created. |
| **`Ignored`** | Whether or not an index will be ignored by the optimizer. See [Ignored Indexes](../ignored-indexes/index). From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). |

 
The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 Examples
--------

 
```
CREATE TABLE IF NOT EXISTS `employees_example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(30) NOT NULL,
  `last_name` varchar(40) NOT NULL,
  `position` varchar(25) NOT NULL,
  `home_address` varchar(50) NOT NULL,
  `home_phone` varchar(12) NOT NULL,
  `employee_code` varchar(25) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `employee_code` (`employee_code`),
  KEY `first_name` (`first_name`,`last_name`)
) ENGINE=Aria;

INSERT INTO `employees_example` (`first_name`, `last_name`, `position`, `home_address`, `home_phone`, `employee_code`)
  VALUES
  ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza', '326-555-3492', 'MM1'),
  ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847', 'HF1'),
  ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456', 'BM1'),
  ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349', 'LC1'),
  ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329', 'FC1'),
  ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478', 'HW1');

```


```
SHOW INDEXES FROM employees_example\G
*************************** 1. row ***************************
        Table: employees_example
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 6
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: NO
*************************** 2. row ***************************
        Table: employees_example
   Non_unique: 0
     Key_name: employee_code
 Seq_in_index: 1
  Column_name: employee_code
    Collation: A
  Cardinality: 6
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: NO
*************************** 3. row ***************************
        Table: employees_example
   Non_unique: 1
     Key_name: first_name
 Seq_in_index: 1
  Column_name: first_name
    Collation: A
  Cardinality: NULL
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: NO
*************************** 4. row ***************************
        Table: employees_example
   Non_unique: 1
     Key_name: first_name
 Seq_in_index: 2
  Column_name: last_name
    Collation: A
  Cardinality: NULL
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: NO

```

See Also
--------

 * [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-index/>

SHOW PROFILES
=============

    Syntax
------

 
```
SHOW PROFILES

```

Description
-----------

 The `SHOW PROFILES` statement displays profiling information that indicates resource usage for statements executed during the course of the current session. It is used together with `[SHOW PROFILE](../show-profile/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-profiles/>

SHOW PROFILE
============

    Syntax
------

 
```
SHOW PROFILE [type [, type] ... ]
    [FOR QUERY n]
    [LIMIT row_count [OFFSET offset]]

type:
    ALL
  | BLOCK IO
  | CONTEXT SWITCHES
  | CPU
  | IPC
  | MEMORY
  | PAGE FAULTS
  | SOURCE
  | SWAPS

```

Description
-----------

 The `SHOW PROFILE` and `[SHOW PROFILES](../show-profiles/index)` statements display profiling information that indicates resource usage for statements executed during the course of the current session.

 Profiling is controlled by the [profiling](../server-system-variables/index#profiling) session variable, which has a default value of `0` (`OFF`). Profiling is enabled by setting profiling to `1` or `ON`:

 
```
SET profiling = 1;

```

`SHOW PROFILES` displays a list of the most recent statements sent to the master. The size of the list is controlled by the `[profiling\_history\_size](../server-system-variables/index#profiling_history_size)` session variable, which has a default value of `15`. The maximum value is `100`. Setting the value to `0` has the practical effect of disabling profiling.

 All statements are profiled except `SHOW PROFILES` and `SHOW PROFILE`, so you will find neither of those statements in the profile list. Malformed statements are profiled. For example, `SHOW PROFILING` is an illegal statement, and a syntax error occurs if you try to execute it, but it will show up in the profiling list.

  `SHOW PROFILE` displays detailed information about a single statement. Without the `FOR QUERY *n*` clause, the output pertains to the most recently executed statement. If `FOR QUERY *n*` is included, `SHOW PROFILE` displays information for statement *n*. The values of *n* correspond to the `Query_ID` values displayed by `SHOW PROFILES`.

 The `LIMIT *row\_count*` clause may be given to limit the output to *row\_count* rows. If `LIMIT` is given, `OFFSET *offset*` may be added to begin the output offset rows into the full set of rows.

 By default, `SHOW PROFILE` displays Status and Duration columns. The Status values are like the State values displayed by `[SHOW PROCESSLIST](../show-processlist/index)`, although there might be some minor differences in interpretation for the two statements for some status values (see <http://dev.mysql.com/doc/refman/5.6/en/thread-information.html>).

 Optional type values may be specified to display specific additional types of information:

 * `**ALL**` displays all information
* `**BLOCK IO**` displays counts for block input and output operations
* `**CONTEXT SWITCHES**` displays counts for voluntary and involuntary context switches
* `**CPU**` displays user and system CPU usage times
* `**IPC**` displays counts for messages sent and received
* `**MEMORY**` is not currently implemented
* `**PAGE FAULTS**` displays counts for major and minor page faults
* `**SOURCE**` displays the names of functions from the source code, together with the name and line number of the file in which the function occurs
* `**SWAPS**` displays swap counts

 Profiling is enabled per session. When a session ends, its profiling information is lost.

 The `[information\_schema.PROFILING](../information-schema-profiling-table/index) table contains similar information.`

 Examples
--------

 
```
SELECT @@profiling;
+-------------+
| @@profiling |
+-------------+
|           0 |
+-------------+

SET profiling = 1;

USE test;

DROP TABLE IF EXISTS t1;

CREATE TABLE T1 (id INT);

SHOW PROFILES;
+----------+------------+--------------------------+
| Query_ID | Duration   | Query                    |
+----------+------------+--------------------------+
|        1 | 0.00009200 | SELECT DATABASE()        |
|        2 | 0.00023800 | show databases           |
|        3 | 0.00018900 | show tables              |
|        4 | 0.00014700 | DROP TABLE IF EXISTS t1  |
|        5 | 0.24476900 | CREATE TABLE T1 (id INT) |
+----------+------------+--------------------------+

SHOW PROFILE;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000042 |
| checking permissions | 0.000044 |
| creating table       | 0.244645 |
| After create         | 0.000013 |
| query end            | 0.000003 |
| freeing items        | 0.000016 |
| logging slow query   | 0.000003 |
| cleaning up          | 0.000003 |
+----------------------+----------+

SHOW PROFILE FOR QUERY 4;
+--------------------+----------+
| Status             | Duration |
+--------------------+----------+
| starting           | 0.000126 |
| query end          | 0.000004 |
| freeing items      | 0.000012 |
| logging slow query | 0.000003 |
| cleaning up        | 0.000002 |
+--------------------+----------+

SHOW PROFILE CPU FOR QUERY 5;
+----------------------+----------+----------+------------+
| Status               | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| starting             | 0.000042 | 0.000000 |   0.000000 |
| checking permissions | 0.000044 | 0.000000 |   0.000000 |
| creating table       | 0.244645 | 0.000000 |   0.000000 |
| After create         | 0.000013 | 0.000000 |   0.000000 |
| query end            | 0.000003 | 0.000000 |   0.000000 |
| freeing items        | 0.000016 | 0.000000 |   0.000000 |
| logging slow query   | 0.000003 | 0.000000 |   0.000000 |
| cleaning up          | 0.000003 | 0.000000 |   0.000000 |
+----------------------+----------+----------+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-profile/>

SHOW PRIVILEGES
===============

    Syntax
------

 
```
SHOW PRIVILEGES

```

Description
-----------

  `SHOW PRIVILEGES` shows the list of [system privileges](../grant/index) that the MariaDB server supports. The exact list of privileges depends on the version of your server.

 Note that before [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/) and [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) , the [Delete history](../grant/index#table-privileges) privilege displays as `Delete versioning rows` ([MDEV-20382](https://jira.mariadb.org/browse/MDEV-20382)).

 Example
-------

 From [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/)

 
```
SHOW PRIVILEGES;
+--------------------------+---------------------------------------+--------------------------------------------------------------------+
| Privilege                | Context                               | Comment                                                            |
+--------------------------+---------------------------------------+--------------------------------------------------------------------+
| Alter                    | Tables                                | To alter the table                                                 |
| Alter routine            | Functions,Procedures                  | To alter or drop stored functions/procedures                       |
| Create                   | Databases,Tables,Indexes              | To create new databases and tables                                 |
| Create routine           | Databases                             | To use CREATE FUNCTION/PROCEDURE                                   |
| Create temporary tables  | Databases                             | To use CREATE TEMPORARY TABLE                                      |
| Create view              | Tables                                | To create new views                                                |
| Create user              | Server Admin                          | To create new users                                                |
| Delete                   | Tables                                | To delete existing rows                                            |
| Delete history           | Tables                                | To delete versioning table historical rows                         |
| Drop                     | Databases,Tables                      | To drop databases, tables, and views                               |
| Event                    | Server Admin                          | To create, alter, drop and execute events                          |
| Execute                  | Functions,Procedures                  | To execute stored routines                                         |
| File                     | File access on server                 | To read and write files on the server                              |
| Grant option             | Databases,Tables,Functions,Procedures | To give to other users those privileges you possess                |
| Index                    | Tables                                | To create or drop indexes                                          |
| Insert                   | Tables                                | To insert data into tables                                         |
| Lock tables              | Databases                             | To use LOCK TABLES (together with SELECT privilege)                |
| Process                  | Server Admin                          | To view the plain text of currently executing queries              |
| Proxy                    | Server Admin                          | To make proxy user possible                                        |
| References               | Databases,Tables                      | To have references on tables                                       |
| Reload                   | Server Admin                          | To reload or refresh tables, logs and privileges                   |
| Binlog admin             | Server                                | To purge binary logs                                               |
| Binlog monitor           | Server                                | To use SHOW BINLOG STATUS and SHOW BINARY LOG                      |
| Binlog replay            | Server                                | To use BINLOG (generated by mariadb-binlog)                        |
| Replication master admin | Server                                | To monitor connected slaves                                        |
| Replication slave admin  | Server                                | To start/stop slave and apply binlog events                        |
| Slave monitor            | Server                                | To use SHOW SLAVE STATUS and SHOW RELAYLOG EVENTS                  |
| Replication slave        | Server Admin                          | To read binary log events from the master                          |
| Select                   | Tables                                | To retrieve rows from table                                        |
| Show databases           | Server Admin                          | To see all databases with SHOW DATABASES                           |
| Show view                | Tables                                | To see views with SHOW CREATE VIEW                                 |
| Shutdown                 | Server Admin                          | To shut down the server                                            |
| Super                    | Server Admin                          | To use KILL thread, SET GLOBAL, CHANGE MASTER, etc.                |
| Trigger                  | Tables                                | To use triggers                                                    |
| Create tablespace        | Server Admin                          | To create/alter/drop tablespaces                                   |
| Update                   | Tables                                | To update existing rows                                            |
| Set user                 | Server                                | To create views and stored routines with a different definer       |
| Federated admin          | Server                                | To execute the CREATE SERVER, ALTER SERVER, DROP SERVER statements |
| Connection admin         | Server                                | To bypass connection limits and kill other users' connections      |
| Read_only admin          | Server                                | To perform write operations even if @@read_only=ON                 |
| Usage                    | Server Admin                          | No privileges - allow connect only                                 |
+--------------------------+---------------------------------------+--------------------------------------------------------------------+
41 rows in set (0.000 sec)

```

See Also
--------

 * [SHOW CREATE USER](../show-create-user/index) shows how the user was created.
* [SHOW GRANTS](../show-grants/index) shows the `GRANTS/PRIVILEGES` for a user.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-privileges/>

SHOW PROCEDURE STATUS
=====================

    Syntax
------

 
```
SHOW PROCEDURE STATUS
    [LIKE 'pattern' | WHERE expr]

```

Description
-----------

 This statement is a MariaDB extension. It returns characteristics of a stored procedure, such as the database, name, type, creator, creation and modification dates, and character set information. A similar statement, `[SHOW FUNCTION STATUS](../show-function-status/index)`, displays information about stored functions.

 The `LIKE` clause, if present, indicates which procedure or function names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The [ROUTINES table](../information-schema-routines-table/index) in the INFORMATION\_SCHEMA database contains more detailed information.

 Examples
--------

 
```
SHOW PROCEDURE STATUS LIKE 'p1'\G
*************************** 1. row ***************************
                  Db: test
                Name: p1
                Type: PROCEDURE
             Definer: root@localhost
            Modified: 2010-08-23 13:23:03
             Created: 2010-08-23 13:23:03
       Security_type: DEFINER
             Comment: 
character_set_client: latin1
collation_connection: latin1_swedish_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [Stored Procedure Overview](../stored-procedure-overview/index)
* [CREATE PROCEDURE](../create-procedure/index)
* [ALTER PROCEDURE](../alter-procedure/index)
* [DROP PROCEDURE](../drop-procedure/index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-procedure-status/>

SHOW
=====

    Articles on the various SHOW commands.

  

| Title | Description |
| --- | --- |
|  [About SHOW](../about-show/index) |  General information about the SHOW statement.  |
|  [Extended Show](../extended-show/index) |  Extended SHOW with WHERE and LIKE.  |
|  [SHOW AUTHORS](../show-authors/index) |  Information about the people who work on MariaDB.  |
|  [SHOW BINARY LOGS](../show-binary-logs/index) |  SHOW BINARY LOGS lists all binary logs on the server.  |
|  [SHOW BINLOG EVENTS](../show-binlog-events/index) |  Show events in the binary log.  |
|  [SHOW CHARACTER SET](../show-character-set/index) |  Available character sets.  |
|  [SHOW CLIENT\_STATISTICS](../show-client-statistics/index) |  Statistics about client connections.  |
|  [SHOW COLLATION](../show-collation/index) |  Supported collations.  |
|  [SHOW COLUMNS](../show-columns/index) |  Column information.  |
|  [SHOW CONTRIBUTORS](../show-contributors/index) |  Companies and people who financially contribute to MariaDB.  |
|  [SHOW CREATE DATABASE](../show-create-database/index) |  Shows the CREATE DATABASE statement that created the database.  |
|  [SHOW CREATE EVENT](../show-create-event/index) |  Displays the CREATE EVENT statement needed to re-create a given event  |
|  [SHOW CREATE FUNCTION](../show-create-function/index) |  Statement that created the function.  |
|  [SHOW CREATE PACKAGE](../show-create-package/index) |  Show the CREATE statement that creates the given package specification.  |
|  [SHOW CREATE PACKAGE BODY](../show-create-package-body/index) |  Show the CREATE statement that creates the given package body (i.e. implementation).  |
|  [SHOW CREATE PROCEDURE](../show-create-procedure/index) |  Returns the string used for creating a stored procedure.  |
|  [SHOW CREATE SEQUENCE](../show-create-sequence/index) |  Shows the CREATE SEQUENCE statement that created the sequence.  |
|  [SHOW CREATE TABLE](../show-create-table/index) |  Shows the CREATE TABLE statement that created the table.  |
|  [SHOW CREATE TRIGGER](../show-create-trigger/index) |  Shows the CREATE TRIGGER statement used to create the trigger  |
|  [SHOW CREATE USER](../show-create-user/index) |  Show the CREATE USER statement for a specified user.  |
|  [SHOW CREATE VIEW](../show-create-view/index) |  Show the CREATE VIEW statement that created a view.  |
|  [SHOW DATABASES](../show-databases/index) |  Lists the databases on the server.  |
|  [SHOW ENGINE](../show-engine/index) |  Show storage engine information.  |
|  [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) |  Display extensive InnoDB information.  |
|  [SHOW ENGINES](../show-engines/index) |  Server storage engine info  |
|  [SHOW ERRORS](../show-errors/index) |  Displays errors.  |
|  [SHOW EVENTS](../show-events/index) |  Shows information about events  |
|  [SHOW EXPLAIN](../show-explain/index) |  Shows an execution plan for a running query.  |
|  [SHOW FUNCTION CODE](../show-function-code/index) |  Representation of the internal implementation of the stored function  |
|  [SHOW FUNCTION STATUS](../show-function-status/index) |  Stored function characteristics  |
|  [SHOW GRANTS](../show-grants/index) |  View GRANT statements.  |
|  [SHOW INDEX](../show-index/index) |  Information about table indexes.  |
|  [SHOW INDEX\_STATISTICS](../show-index-statistics/index) |  Index usage statistics.  |
|  [SHOW INNODB STATUS (removed)](../show-innodb-status-removed/index) |  Removed synonym for SHOW ENGINE INNODB STATUS  |
|  [SHOW LOCALES](../show-locales/index) |  View locales information.  |
|  [SHOW MASTER STATUS](../show-binlog-status/index) |  Status information about the binary log.  |
|  [SHOW OPEN TABLES](../show-open-tables/index) |  List non-temporary open tables.  |
|  [SHOW PACKAGE BODY STATUS](../show-package-body-status/index) |  Returns characteristics of stored package bodies (implementations).  |
|  [SHOW PACKAGE STATUS](../show-package-status/index) |  Returns characteristics of stored package specifications.  |
|  [SHOW PLUGINS](../show-plugins/index) |  Display information about installed plugins.  |
|  [SHOW PLUGINS SONAME](../show-plugins-soname/index) |  Information about all available plugins, installed or not.  |
|  [SHOW PRIVILEGES](../show-privileges/index) |  Shows the list of supported system privileges.  |
|  [SHOW PROCEDURE CODE](../show-procedure-code/index) |  Display internal implementation of a stored procedure.  |
|  [SHOW PROCEDURE STATUS](../show-procedure-status/index) |  Stored procedure characteristics.  |
|  [SHOW PROCESSLIST](../show-processlist/index) |  Running threads and information about them.  |
|  [SHOW PROFILE](../show-profile/index) |  Display statement resource usage  |
|  [SHOW PROFILES](../show-profiles/index) |  Show statement resource usage  |
|  [SHOW QUERY\_RESPONSE\_TIME](../show-query_response_time/index) |  Retrieving information from the QUERY\_RESPONSE\_TIME plugin.  |
|  [SHOW RELAYLOG EVENTS](../show-relaylog-events/index) |  Show events in the relay log.  |
|  [SHOW SLAVE HOSTS](../show-replica-hosts/index) |  Display replicas currently registered with the primary.  |
|  [SHOW SLAVE STATUS](../show-replica-status/index) |  Show status for one or all primaries.  |
|  [SHOW STATUS](../show-status/index) |  Server status information.  |
|  [SHOW TABLE STATUS](../show-table-status/index) |  SHOW TABLES with information about non-temporary tables.  |
|  [SHOW TABLES](../show-tables/index) |  List of non-temporary tables, views or sequences.  |
|  [SHOW TABLE\_STATISTICS](../show-table-statistics/index) |  Table usage statistics.  |
|  [SHOW TRIGGERS](../show-triggers/index) |  Shows currently-defined triggers  |
|  [SHOW USER\_STATISTICS](../show-user-statistics/index) |  User activity statistics.  |
|  [SHOW VARIABLES](../show-variables/index) |  Displays the values of system variables.  |
|  [SHOW WARNINGS](../show-warnings/index) |  Displays errors, warnings and notes.  |
|  [SHOW WSREP\_MEMBERSHIP](../show-wsrep_membership/index) |  Galera node cluster membership information.  |
|  [SHOW WSREP\_STATUS](../show-wsrep_status/index) |  Galera node cluster status information.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show/>

SHOW VARIABLES
==============

    Syntax
------

 
```
SHOW [GLOBAL | SESSION] VARIABLES
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 `SHOW VARIABLES` shows the values of MariaDB [system variables](../server-system-variables/index). This information also can be obtained using the [mariadb-admin variables](../mariadb-admin/index) command. The `LIKE` clause, if present, indicates which variable names to match. The `WHERE` clause can be given to select rows using more general conditions.

 With the `GLOBAL` modifier, `SHOW VARIABLES` displays the values that are used for new connections to MariaDB. With `SESSION`, it displays the values that are in effect for the current connection. If no modifier is present, the default is `SESSION`. `LOCAL` is a synonym for `SESSION`. With a `LIKE` clause, the statement displays only rows for those variables with names that match the pattern. To obtain the row for a specific variable, use a `LIKE` clause as shown:

 
```
SHOW VARIABLES LIKE 'maria_group_commit';
SHOW SESSION VARIABLES LIKE 'maria_group_commit';

```

To get a list of variables whose name match a pattern, use the "`%`" wildcard character in a `LIKE` clause:

 
```
SHOW VARIABLES LIKE '%maria%';
SHOW GLOBAL VARIABLES LIKE '%maria%';

```

Wildcard characters can be used in any position within the pattern to be matched. Strictly speaking, because "`_`" is a wildcard that matches any single character, you should escape it as "`\_`" to match it literally. In practice, this is rarely necessary.

 The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 See `[SET](../set/index)` for information on setting server system variables.

 See [Server System Variables](../server-system-variables/index) for a list of all the variables that can be set.

 You can also see the server variables by querying the [Information Schema GLOBAL\_VARIABLES and SESSION\_VARIABLES](../information-schema-global_variables-and-session_variables-tables/index) tables.

 Examples
--------

 
```
SHOW VARIABLES LIKE 'aria%';
+------------------------------------------+---------------------+
| Variable_name                            | Value               |
+------------------------------------------+---------------------+
| aria_block_size                          | 8192                |
| aria_checkpoint_interval                 | 30                  |
| aria_checkpoint_log_activity             | 1048576             |
| aria_force_start_after_recovery_failures | 0                   |
| aria_group_commit                        | none                |
| aria_group_commit_interval               | 0                   |
| aria_log_file_size                       | 1073741824          |
| aria_log_purge_type                      | immediate           |
| aria_max_sort_file_size                  | 9223372036853727232 |
| aria_page_checksum                       | ON                  |
| aria_pagecache_age_threshold             | 300                 |
| aria_pagecache_buffer_size               | 134217728           |
| aria_pagecache_division_limit            | 100                 |
| aria_recover                             | NORMAL              |
| aria_repair_threads                      | 1                   |
| aria_sort_buffer_size                    | 134217728           |
| aria_stats_method                        | nulls_unequal       |
| aria_sync_log_dir                        | NEWFILE             |
| aria_used_for_temp_tables                | ON                  |
+------------------------------------------+---------------------+

```


```
SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
  INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
  VARIABLE_NAME LIKE 'max_error_count' OR
  VARIABLE_NAME LIKE 'innodb_sync_spin_loops';
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 64           |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

SET GLOBAL max_error_count=128;

SELECT VARIABLE_NAME, SESSION_VALUE, GLOBAL_VALUE FROM
  INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE
  VARIABLE_NAME LIKE 'max_error_count' OR
  VARIABLE_NAME LIKE 'innodb_sync_spin_loops';
+---------------------------+---------------+--------------+
| VARIABLE_NAME             | SESSION_VALUE | GLOBAL_VALUE |
+---------------------------+---------------+--------------+
| MAX_ERROR_COUNT           | 64            | 128          |
| INNODB_SYNC_SPIN_LOOPS    | NULL          | 30           |
+---------------------------+---------------+--------------+

SET GLOBAL max_error_count=128;

SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+

SHOW GLOBAL VARIABLES LIKE 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 128   |
+-----------------+-------+

```

Because the following variable only has a global scope, the global value is returned even when specifying SESSION (in this case by default):

 
```
SHOW VARIABLES LIKE 'innodb_sync_spin_loops';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_sync_spin_loops | 30    |
+------------------------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-variables/>

SHOW TABLE\_STATISTICS
======================

    Syntax
------

 
```
SHOW TABLE_STATISTICS

```

Description
-----------

 The `SHOW TABLE_STATISTICS` statementis part of the [User Statistics](../user-statistics/index) feature. It was removed as a separate statement in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), but effectively replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index) statement. The [information\_schema.TABLE\_STATISTICS](../information-schema-table_statistics-table/index) table shows statistics on table usage

 The [userstat](../server-system-variables/index#userstat) system variable must be set to 1 to activate this feature. See the [User Statistics](../user-statistics/index) and [information\_schema.TABLE\_STATISTICS](../information-schema-table_statistics-table/index) articles for more information.

 Example
-------

 
```
SHOW TABLE_STATISTICS\G
*************************** 1. row ***************************
           Table_schema: mysql
             Table_name: proxies_priv
              Rows_read: 2
           Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 2. row ***************************
           Table_schema: test
             Table_name: employees_example
              Rows_read: 7
           Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 3. row ***************************
           Table_schema: mysql
             Table_name: user
              Rows_read: 16
           Rows_changed: 0
Rows_changed_x_#indexes: 0
*************************** 4. row ***************************
           Table_schema: mysql
             Table_name: db
              Rows_read: 2
           Rows_changed: 0
Rows_changed_x_#indexes: 0


```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-table_statistics/>

SHOW RELAYLOG EVENTS
====================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Syntax
------

 
```
SHOW RELAYLOG ['connection_name'] EVENTS
    [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
    [ FOR CHANNEL 'channel_name']

```

Description
-----------

 On [replicas](../standard-replication/index), this command shows the events in the [relay log](../relay-log/index). If `'log_name'` is not specified, the first relay log is shown.

 Syntax for the `LIMIT` clause is the same as for [SELECT ... LIMIT](../select/index#limit).

 
Using the `LIMIT` clause is highly recommended because the `SHOW RELAYLOG EVENTS` command returns the complete contents of the relay log, which can be quite large.

 
This command does not return events related to setting user and system variables. If you need those, use [mariadb-binlog](../mariadb-binlog/index).

 On the primary, this command does nothing.

 Requires the [REPLICA MONITOR](../grant/index#replica-monitor) privilege (>= [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/)), the [REPLICATION SLAVE ADMIN](../grant/index#replication-slave-admin) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) or the [REPLICATION SLAVE](../grant/index#replication-slave) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)).

 #### connection\_name

 If there is only one nameless primary, or the default primary (as specified by the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable) is intended, `connection_name` can be omitted. If provided, the `SHOW RELAYLOG` statement will apply to the specified primary. `connection_name` is case-insensitive.

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical as using the channel\_name directly after `SHOW RELAYLOG`.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-relaylog-events/>

UNINSTALL PLUGIN
================

    Syntax
------

 
```
UNINSTALL PLUGIN [IF EXISTS] plugin_name
```
 Description
-----------

 This statement removes a single installed [plugin](../mariadb-plugins/index). To uninstall the whole library which contains the plugin, use [UNINSTALL SONAME](../uninstall-soname/index). You cannot uninstall a plugin if any table that uses it is open.

 `plugin_name` must be the name of some plugin that is listed in the [mysql.plugin](../mysqlplugin-table/index) table. The server executes the plugin's deinitialization function and removes the row for the plugin from the `mysql.plugin` table, so that subsequent server restarts will not load and initialize the plugin. `UNINSTALL PLUGIN` does not remove the plugin's shared library file.

 To use `UNINSTALL PLUGIN`, you must have the [DELETE](../grant/index) privilege for the [mysql.plugin](../mysqlplugin-table/index) table.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**#### IF EXISTS

 If the `IF EXISTS` clause is used, MariaDB will return a note instead of an error if the plugin does not exist. See [SHOW WARNINGS](../show-warnings/index).

 
Examples
--------

 
```
UNINSTALL PLUGIN example;

```

From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/):

 
```
UNINSTALL PLUGIN IF EXISTS example;
Query OK, 0 rows affected (0.099 sec)

UNINSTALL PLUGIN IF EXISTS example;
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1305 | PLUGIN example does not exist |
+-------+------+-------------------------------+

```

See Also
--------

 * [Plugin Overview](../plugin-overview/index)
* [mysql\_plugin](../mysql_plugin/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [List of Plugins](../list-of-plugins/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uninstall-plugin/>

SHOW INDEX\_STATISTICS
======================

    Syntax
------

 
```
SHOW INDEX_STATISTICS

```

Description
-----------

 The `SHOW INDEX_STATISTICS` statement was introduced in [MariaDB 5.2](../what-is-mariadb-52/index) as part of the [User Statistics](../user-statistics/index) feature. It was removed as a separate statement in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), but effectively replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index) statement. The [information\_schmea.INDEX\_STATISTICS](../information-schema-index_statistics-table/index) table shows statistics on index usage and makes it possible to do such things as locating unused indexes and generating the commands to remove them. 

 The [userstat](../server-system-variables/index#userstat) system variable must be set to 1 to activate this feature. See the [User Statistics](../user-statistics/index) and [information\_schema.INDEX\_STATISTICS](../information-schema-index_statistics-table/index) table for more information.

 Example
-------

 
```
SHOW INDEX_STATISTICS;
+--------------+-------------------+------------+-----------+
| Table_schema | Table_name        | Index_name | Rows_read |
+--------------+-------------------+------------+-----------+
| test         | employees_example | PRIMARY    |         1 |
+--------------+-------------------+------------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-index_statistics/>

SHOW ENGINES
============

    Syntax
------

 
```
SHOW [STORAGE] ENGINES

```

Description
-----------

 `SHOW ENGINES` displays status information about the server's storage engines. This is particularly useful for checking whether a storage engine is supported, or to see what the default engine is. `SHOW TABLE TYPES` is a deprecated synonym.

 The `[information\_schema.ENGINES](../information-schema-engines-table/index)` table provides the same information.

 Since storage engines are plugins, different information about them is also shown in the `[information\_schema.PLUGINS](../information_schemaplugins-table/index)` table and by the `[SHOW PLUGINS](../show-plugins/index)` statement.

 Note that both MySQL's InnoDB and Percona's XtraDB replacement are labeled as `InnoDB`. However, if XtraDB is in use, it will be specified in the `COMMENT` field. See [XtraDB and InnoDB](../xtradb-and-innodb/index). The same applies to [FederatedX](../federatedx/index).

 The output consists of the following columns:

 * `Engine` indicates the engine's name.
* `Support` indicates whether the engine is installed, and whether it is the default engine for the current session.
* `Comment` is a brief description.
* `Transactions`, `XA` and `Savepoints` indicate whether [transactions](../transactions/index), [XA transactions](../xa-transactions/index) and [transaction savepoints](../savepoint/index) are supported by the engine.

 Examples
--------

 
```
SHOW ENGINES\G
*************************** 1. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 2. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: FEDERATED
     Support: YES
     Comment: FederatedX pluggable storage engine
Transactions: YES
          XA: NO
  Savepoints: YES
*************************** 6. row ***************************
      Engine: MRG_MyISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 9. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 10. row ***************************
      Engine: Aria
     Support: YES
     Comment: Crash-safe tables with MyISAM heritage
Transactions: NO
          XA: NO
  Savepoints: NO
10 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-engines/>

SHOW WARNINGS
=============

    Syntax
------

 
```
SHOW WARNINGS [LIMIT [offset,] row_count]
SHOW ERRORS [LIMIT row_count OFFSET offset]
SHOW COUNT(*) WARNINGS

```
 Description
-----------

  `SHOW WARNINGS` shows the error, warning, and note messages that resulted from the last statement that generated messages in the current session. It shows nothing if the last statement used a table and generated no messages. (That is, a statement that uses a table but generates no messages clears the message list.) Statements that do not use tables and do not generate messages have no effect on the message list.

 A note is different to a warning in that it only appears if the `[sql\_notes](../server-system-variables/index#sql_notes)` variable is set to 1 (the default), and is not converted to an error if `[strict mode](../sql_mode/index)` is enabled.

 A related statement, `[SHOW ERRORS](../show-errors/index)`, shows only the errors.

 The `SHOW COUNT(*) WARNINGS` statement displays the total number of errors, warnings, and notes. You can also retrieve this number from the [warning\_count](../server-system-variables/index#warning_count) variable:

 
```
SHOW COUNT(*) WARNINGS;
SELECT @@warning_count;

```

The value of `[warning\_count](../server-system-variables/index#warning_count)` might be greater than the number of messages displayed by `SHOW WARNINGS` if the `[max\_error\_count](../server-system-variables/index#max_error_count)` system variable is set so low that not all messages are stored.

 The `LIMIT` clause has the same syntax as for the `[SELECT statement](../select/index)`.

 `SHOW WARNINGS` can be used after `[EXPLAIN EXTENDED](../explain/index)` to see how a query is internally rewritten by MariaDB.

 If the `[sql\_notes](../server-system-variables/index#sql_notes)` server variable is set to 1, Notes are included in the output of `SHOW WARNINGS`; if it is set to 0, this statement will not show (or count) Notes.

 The results of `SHOW WARNINGS` and `SHOW COUNT(*) WARNINGS` are directly sent to the client. If you need to access those information in a stored program, you can use the `[GET DIAGNOSTICS](../get-diagnostics/index)` statement instead.

 For a list of MariaDB error codes, see [MariaDB Error Codes](../mariadb-error-codes/index).

 The [mariadb](../mariadb-command-line-client/index) client also has a number of options related to warnings. The `\W` command will show warnings after every statement, while `\w` will disable this. Starting the client with the `--show-warnings` option will show warnings after every statement.

 MariaDB implements a stored routine error stack trace. `SHOW WARNINGS` can also be used to show more information. See the example below.

 Examples
--------

 
```
SELECT 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+

SHOW COUNT(*) WARNINGS;
+-------------------------+
| @@session.warning_count |
+-------------------------+
|                       1 |
+-------------------------+

SHOW WARNINGS;
+---------+------+---------------+
| Level   | Code | Message       |
+---------+------+---------------+
| Warning | 1365 | Division by 0 |
+---------+------+---------------+

```

### Stack Trace

 Displaying a stack trace:

 
```
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1()
  BEGIN
    DECLARE c CURSOR FOR SELECT * FROM not_existing;
    OPEN c;
    CLOSE c;
  END;
$$
CREATE OR REPLACE PROCEDURE p2()
  BEGIN
    CALL p1;
  END;
$$
DELIMITER ;
CALL p2;
ERROR 1146 (42S02): Table 'test.not_existing' doesn't exist

SHOW WARNINGS;
+-------+------+-----------------------------------------+
| Level | Code | Message                                 |
+-------+------+-----------------------------------------+
| Error | 1146 | Table 'test.not_existing' doesn't exist |
| Note  | 4091 | At line 6 in test.p1                    |
| Note  | 4091 | At line 4 in test.p2                    |
+-------+------+-----------------------------------------+

```

`SHOW WARNINGS` displays a stack trace, showing where the error actually happened:

 * Line 4 in test.p1 is the OPEN command which actually raised the error
* Line 3 in test.p2 is the CALL statement, calling p1 from p2.

 See Also
--------

 * [SHOW ERRORS](../show-errors/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-warnings/>

INSERT DELAYED
==============

    Syntax
------

 
```
INSERT DELAYED ...

```
 Description
-----------

 The `DELAYED` option for the `[INSERT](../insert/index)` statement is a MariaDB/MySQL extension to standard SQL that is very useful if you have clients that cannot or need not wait for the `INSERT` to complete. This is a common situation when you use MariaDB for logging and you also periodically run `SELECT` and `UPDATE` statements that take a long time to complete.

 When a client uses `INSERT DELAYED`, it gets an okay from the server at once, and the row is queued to be inserted when the table is not in use by any other thread.

 Another major benefit of using `INSERT DELAYED` is that inserts from many clients are bundled together and written in one block. This is much faster than performing many separate inserts.

 Note that `INSERT DELAYED` is slower than a normal `INSERT` if the table is not otherwise in use. There is also the additional overhead for the server to handle a separate thread for each table for which there are delayed rows. This means that you should use `INSERT DELAYED` only when you are really sure that you need it.

 The queued rows are held only in memory until they are inserted into the table. This means that if you terminate mysqld forcibly (for example, with kill -9) or if mysqld dies unexpectedly, any queued rows that have not been written to disk are lost.

 The number of concurrent `INSERT DELAYED` threads is limited by the `[max\_delayed\_threads](../server-system-variables/index#max_delayed_threads)` server system variables. If it is set to 0, `INSERT DELAYED` is disabled. The session value can be equal to the global value, or 0 to disable this statement for the current session. If this limit has been reached, the `DELAYED` clause will be silently ignore for subsequent statements (no error will be produced).

 ### Limitations

 There are some limitations on the use of `DELAYED`:

 * `INSERT DELAYED` works only with [MyISAM](../myisam-storage-engine/index), [MEMORY](../memory-storage-engine/index), [ARCHIVE](../archive/index), and [BLACKHOLE](../blackhole/index) tables. If you execute INSERT DELAYED with another storage engine, you will get an error like this: `ERROR 1616 (HY000): DELAYED option not supported for table 'tab_name'`
* For MyISAM tables, if there are no free blocks in the middle of the data file, concurrent SELECT and INSERT statements are supported. Under these circumstances, you very seldom need to use `INSERT DELAYED` with MyISAM.
* `INSERT DELAYED` should be used only for `INSERT` statements that specify value lists. The server ignores `DELAYED` for `INSERT ... SELECT` or `INSERT ... ON DUPLICATE KEY UPDATE` statements.
* Because the `INSERT DELAYED` statement returns immediately, before the rows are inserted, you cannot use `LAST_INSERT_ID()` to get the `AUTO_INCREMENT` value that the statement might generate.
* `DELAYED` rows are not visible to `SELECT` statements until they actually have been inserted.
* After `INSERT DELAYED`, [ROW\_COUNT()](../row_count/index) returns the number of the rows you tried to insert, not the number of the successful writes.
* `DELAYED` is ignored on slave replication servers, so that `INSERT DELAYED` is treated as a normal `INSERT` on slaves. This is because `DELAYED` could cause the slave to have different data than the master. `INSERT DELAYED` statements are not [safe for replication](../unsafe-statements-for-replication/index).
* Pending `INSERT DELAYED` statements are lost if a table is write locked and ALTER TABLE is used to modify the table structure.
* `INSERT DELAYED` is not supported for views. If you try, you will get an error like this: `ERROR 1347 (HY000): 'view_name' is not BASE TABLE`
* `INSERT DELAYED` is not supported for [partitioned tables](../managing-mariadb-partitioning/index).
* `INSERT DELAYED` is not supported within [stored programs](../stored-programs-and-views/index).
* `INSERT DELAYED` does not work with [triggers](../triggers/index).
* `INSERT DELAYED` does not work if there is a check constraint in place.
* `INSERT DELAYED` does not work if [skip-new](../mysqld-options/index#-skip-new) mode is active.

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT SELECT](../insert-select/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-delayed/>

CONSTRAINT
==========

    MariaDB supports the implementation of constraints at the table-level using either [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statements. A table constraint restricts the data you can add to the table. If you attempt to insert invalid data on a column, MariaDB throws an error. 

 Syntax
------

 
```
[CONSTRAINT [symbol]] constraint_expression

constraint_expression:
  | PRIMARY KEY [index_type] (index_col_name, ...) [index_option] ...
  | FOREIGN KEY [index_name] (index_col_name, ...) 
       REFERENCES tbl_name (index_col_name, ...)
       [ON DELETE reference_option]
       [ON UPDATE reference_option]
  | UNIQUE [INDEX|KEY] [index_name]
       [index_type] (index_col_name, ...) [index_option] ...
  | CHECK (check_constraints)

index_type:
  USING {BTREE | HASH | RTREE}

index_col_name:
  col_name [(length)] [ASC | DESC]

index_option:
  | KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | CLUSTERING={YES|NO}

reference_option:
  RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

```
 Description
-----------

 Constraints provide restrictions on the data you can add to a table. This allows you to enforce data integrity from MariaDB, rather than through application logic. When a statement violates a constraint, MariaDB throws an error.

 There are four types of table constraints:

 


| Constraint | Description |
| --- | --- |
| `PRIMARY KEY` | Sets the column for referencing rows. Values must be unique and not null. |
| `FOREIGN KEY` | Sets the column to reference the primary key on another table. |
| `UNIQUE` | Requires values in column or columns only occur once in the table. |
| `CHECK` | Checks whether the data meets the given condition. |

 
The [Information Schema TABLE\_CONSTRAINTS Table](../information-schema-table_constraints-table/index) contains information about tables that have constraints.

 ### FOREIGN KEY Constraints

 [InnoDB](../innodb/index) supports [foreign key](../foreign-keys/index) constraints. The syntax for a foreign key constraint definition in InnoDB looks like this:

 
```
[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

```

The [Information Schema REFERENTIAL\_CONSTRAINTS](../information-schema-referential_constraints-table/index) table has more information about foreign keys.

 ### CHECK Constraints

 Constraints are enforced. Before [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) constraint expressions were accepted in the syntax but ignored.

 You can define constraints in 2 different ways:

 * `CHECK(expression)` given as part of a column definition.
* `CONSTRAINT [constraint_name] CHECK (expression)`

 Before a row is inserted or updated, all constraints are evaluated in the order they are defined. If any constraint expression returns false, then the row will not be inserted or updated. One can use most deterministic functions in a constraint, including [UDFs](../user-defined-functions/index).

 
```
CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

```

If you use the second format and you don't give a name to the constraint, then the constraint will get an automatically generated name. This is done so that you can later delete the constraint with [ALTER TABLE DROP constraint\_name](../alter-table/index).

 One can disable all constraint expression checks by setting the [check\_constraint\_checks](../server-system-variables/index#check_constraint_checks) variable to `OFF`. This is useful for example when loading a table that violates some constraints that you want to later find and fix in SQL.

 ### Replication

 In [row-based](../binary-log-formats/index#row-based) [replication](../replication/index), only the master checks constraints, and failed statements will not be replicated. In [statement-based](../binary-log-formats/index#statement-based) replication, the slaves will also check constraints. Constraints should therefore be identical, as well as deterministic, in a replication environment.

 ### Auto\_increment

 [auto\_increment](../auto_increment/index) columns are not permitted in check constraints. Before [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), they were permitted, but would not work correctly. See [MDEV-11117](https://jira.mariadb.org/browse/MDEV-11117).

 Examples
--------

 
```
CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) ENGINE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                       PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                            product_category INT NOT NULL,
                            product_id INT NOT NULL,
                            customer_id INT NOT NULL,
                            PRIMARY KEY(no),
                            INDEX (product_category, product_id),
                            FOREIGN KEY (product_category, product_id)
                              REFERENCES product(category, id)
                              ON UPDATE CASCADE ON DELETE RESTRICT,
                            INDEX (customer_id),
                            FOREIGN KEY (customer_id)
                              REFERENCES customer(id)) ENGINE=INNODB;

```

The following examples will work from [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) onwards.

 Numeric constraints and comparisons:

 
```
CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

INSERT INTO t1(a) VALUES (1);
ERROR 4022 (23000): CONSTRAINT `a` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (3,4);
ERROR 4022 (23000): CONSTRAINT `a_greater` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (4,3);
Query OK, 1 row affected (0.04 sec)

```

Dropping a constraint:

 
```
ALTER TABLE t1 DROP CONSTRAINT a_greater;

```

Adding a constraint:

 
```
ALTER TABLE t1 ADD CONSTRAINT a_greater CHECK (a>b);

```

Date comparisons and character length:

 
```
CREATE TABLE t2 (name VARCHAR(30) CHECK (CHAR_LENGTH(name)>2), start_date DATE, 
  end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR start_date<end_date));

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2003-12-15', '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Io', '2003-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `name` failed for `test`.`t2`

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', NULL, '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2015-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `end_date` failed for `test`.`t2`

```

A misplaced parenthesis:

 
```
CREATE TABLE t3 (name VARCHAR(30) CHECK (CHAR_LENGTH(name>2)), start_date DATE, 
  end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR start_date<end_date));
Query OK, 0 rows affected (0.32 sec)

INSERT INTO t3(name, start_date, end_date) VALUES('Io', '2003-12-15', '2014-11-09');
Query OK, 1 row affected, 1 warning (0.04 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'Io' |
+---------+------+----------------------------------------+

```

Compare the definition of table *t2* to table *t3*. `CHAR_LENGTH(name)>2` is very different to `CHAR_LENGTH(name>2)` as the latter mistakenly performs a numeric comparison on the *name* field, leading to unexpected results.

 See Also
--------

 * [Foreign Keys](../foreign-keys/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/constraint/>

ANALYZE Statement
=================

    Description
-----------

 The `ANALYZE statement` is similar to the `EXPLAIN statement`. `ANALYZE statement` will invoke the optimizer, execute the statement, and then produce `EXPLAIN` output instead of the result set. The `EXPLAIN` output will be annotated with statistics from statement execution.

 This lets one check how close the optimizer's estimates about the query plan are to the reality. `ANALYZE` produces an overview, while the [ANALYZE FORMAT=JSON](../analyze-formatjson/index) command provides a more detailed view of the query plan and the query execution.

 The syntax is 

 
```
ANALYZE explainable_statement;

```

where the statement is any statement for which one can run [EXPLAIN](../explain/index).

 Command Output
--------------

 Consider an example:

 
```
ANALYZE SELECT * FROM tbl1 
WHERE key1 
  BETWEEN 10 AND 200 AND 
  col1 LIKE 'foo%'\G

```


```
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: tbl1
         type: range
possible_keys: key1
          key: key1
      key_len: 5
          ref: NULL
         rows: 181
       r_rows: 181
     filtered: 100.00
   r_filtered: 10.50
        Extra: Using index condition; Using where

```

Compared to `EXPLAIN`, `ANALYZE` produces two extra columns:

 * **`r_rows`** is an observation-based counterpart of the **rows** column. It shows how many rows were actually read from the table.
* **`r_filtered`** is an observation-based counterpart of the **filtered** column. It shows which fraction of rows was left after applying the WHERE condition.

 Interpreting the Output
-----------------------

 ### Joins

 Let's consider a more complicated example.

 
```
ANALYZE SELECT *
FROM orders, customer 
WHERE
  customer.c_custkey=orders.o_custkey AND
  customer.c_acctbal < 0 AND
  orders.o_totalprice > 200*1000

```


```
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
| id | select_type | table    | type | possible_keys | key         | key_len | ref                | rows   | r_rows | filtered | r_filtered | Extra       |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
|  1 | SIMPLE      | customer | ALL  | PRIMARY,...   | NULL        | NULL    | NULL               | 149095 | 150000 |    18.08 |       9.13 | Using where |
|  1 | SIMPLE      | orders   | ref  | i_o_custkey   | i_o_custkey | 5       | customer.c_custkey |      7 |     10 |   100.00 |      30.03 | Using where |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+

```

Here, one can see that

 * For table customer, **customer.rows=149095, customer.r\_rows=150000**. The estimate for number of rows we will read was fairly precise
* **customer.filtered=18.08, customer.r\_filtered=9.13**. The optimizer somewhat overestimated the number of records that will match selectivity of condition attached to `customer` table (in general, when you have a full scan and r\_filtered is less than 15%, it's time to consider adding an appropriate index).
* For table orders, **orders.rows=7, orders.r\_rows=10**. This means that on average, there are 7 orders for a given c\_custkey, but in our case there were 10, which is close to the expectation (when this number is consistently far from the expectation, it may be time to run ANALYZE TABLE, or even edit the table statistics manually to get better query plans).
* **orders.filtered=100, orders.r\_filtered=30.03**. The optimizer didn't have any way to estimate which fraction of records will be left after it checks the condition that is attached to table orders (it's orders.o\_totalprice > 200\*1000). So, it used 100%. In reality, it is 30%. 30% is typically not selective enough to warrant adding new indexes. For joins with many tables, it might be worth to collect and use [column statistics](../engine-independent-table-statistics/index) for columns in question, this may help the optimizer to pick a better query plan.

 ### Meaning of NULL in r\_rows and r\_filtered

 Let's modify the previous example slightly

 
```
ANALYZE SELECT * 
FROM orders, customer 
WHERE
  customer.c_custkey=orders.o_custkey AND
  customer.c_acctbal < -0 AND 
  customer.c_comment LIKE '%foo%' AND
  orders.o_totalprice > 200*1000;

```


```
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
| id | select_type | table    | type | possible_keys | key         | key_len | ref                | rows   | r_rows | filtered | r_filtered | Extra       |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+
|  1 | SIMPLE      | customer | ALL  | PRIMARY,...   | NULL        | NULL    | NULL               | 149095 | 150000 |    18.08 |       0.00 | Using where |
|  1 | SIMPLE      | orders   | ref  | i_o_custkey   | i_o_custkey | 5       | customer.c_custkey |      7 |   NULL |   100.00 |       NULL | Using where |
+----+-------------+----------+------+---------------+-------------+---------+--------------------+--------+--------+----------+------------+-------------+

```

Here, one can see that **orders.r\_rows=NULL** and **orders.r\_filtered=NULL**. This means that table orders was not scanned even once. Indeed, we can also see customer.r\_filtered=0.00. This shows that a part of WHERE attached to table `customer` was never satisfied (or, satisfied in less than 0.01% of cases).

 ANALYZE FORMAT=JSON
-------------------

 [ANALYZE FORMAT=JSON](../analyze-formatjson/index) produces JSON output. It produces much more information than tabular `ANALYZE`.

 Notes
-----

 * `ANALYZE UPDATE` or `ANALYZE DELETE` will actually make updates/deletes (`ANALYZE SELECT` will perform the select operation and then discard the resultset).
* PostgreSQL has a similar command, `EXPLAIN ANALYZE`.
* The [EXPLAIN in the slow query log](../explain-in-the-slow-query-log/index) feature allows MariaDB to have `ANALYZE` output of slow queries printed into the [slow query log](../slow-query-log/index) (see [MDEV-6388](https://jira.mariadb.org/browse/MDEV-6388)).

 See Also
--------

 * [ANALYZE FORMAT=JSON](../analyze-formatjson/index)
* [ANALYZE TABLE](../analyze-table/index)
* JIRA task for ANALYZE statement, [MDEV-406](https://jira.mariadb.org/browse/MDEV-406)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/analyze-statement/>

LOCK TABLES
===========

    Syntax
------

 
```
LOCK TABLE[S]
    tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...
    [WAIT n|NOWAIT]

lock_type:
    READ [LOCAL]
  | [LOW_PRIORITY] WRITE
  | WRITE CONCURRENT

UNLOCK TABLES

```
 Description
-----------

 The *lock\_type* can be one of:

 


| Option | Description |
| --- | --- |
| READ | Read lock, no writes allowed |
| READ LOCAL | Read lock, but allow [concurrent inserts](../concurrent-inserts/index) |
| WRITE | Exclusive write lock. No other connections can read or write to this table |
| LOW\_PRIORITY WRITE | Exclusive write lock, but allow new read locks on the table until we get the write lock. |
| WRITE CONCURRENT | Exclusive write lock, but allow READ LOCAL locks to the table. |

 
MariaDB enables client sessions to acquire table locks explicitly for the purpose of cooperating with other sessions for access to tables, or to prevent other sessions from modifying tables during periods when a session requires exclusive access to them. A session can acquire or release locks only for itself. One session cannot acquire locks for another session or release locks held by another session.

 Locks may be used to emulate transactions or to get more speed when updating tables.

 `LOCK TABLES` explicitly acquires table locks for the current client session. Table locks can be acquired for base tables or views. To use `LOCK TABLES`, you must have the `LOCK TABLES` privilege, and the `SELECT` privilege for each object to be locked. See `[GRANT](../grant/index)`

 For view locking, `LOCK TABLES` adds all base tables used in the view to the set of tables to be locked and locks them automatically. If you lock a table explicitly with `LOCK TABLES`, any tables used in triggers are also locked implicitly, as described in [Triggers and Implicit Locks](../triggers-and-implicit-locks/index).

 [UNLOCK TABLES](../transactions-unlock-tables/index) explicitly releases any table locks held by the current session.   
  


 
**MariaDB starting with [10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)**### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 
Limitations
-----------

 * `LOCK TABLES` [doesn't work when using Galera cluster](../mariadb-galera-cluster-known-limitations/index). You may experience crashes or locks when used with Galera.
* `LOCK TABLES` works on XtraDB/InnoDB tables only if the [innodb\_table\_locks](../xtradbinnodb-server-system-variables/index#innodb_table_locks) system variable is set to 1 (the default) and [autocommit](../server-system-variables/index#autocommit) is set to 0 (1 is default). Please note that no error message will be returned on LOCK TABLES with innodb\_table\_locks = 0.
* `LOCK TABLES` [implicitly commits](../sql-statements-that-cause-an-implicit-commit/index) the active transaction, if any. Also, starting a transaction always releases all table locks acquired with LOCK TABLES. This means that there is no way to have table locks and an active transaction at the same time. The only exceptions are the transactions in [autocommit](../start-transaction/index#autocommit) mode. To preserve the data integrity between transactional and non-transactional tables, the [GET\_LOCK()](../get_lock/index) function can be used.
* When using `LOCK TABLES` on a `TEMPORARY` table, it will always be locked with a `WRITE` lock.
* While a connection holds an explicit read lock on a table, it cannot modify it. If you try, the following error will be produced:

 
```
ERROR 1099 (HY000): Table 'tab_name' was locked with a READ lock and can't be updated

```

* While a connection holds an explicit lock on a table, it cannot access a non-locked table. If you try, the following error will be produced:

 
```
ERROR 1100 (HY000): Table 'tab_name' was not locked with LOCK TABLES

```

* While a connection holds an explicit lock on a table, it cannot issue the following: INSERT DELAYED, CREATE TABLE, CREATE TABLE ... LIKE, and DDL statements involving stored programs and views (except for triggers). If you try, the following error will be produced:

 
```
ERROR 1192 (HY000): Can't execute the given command because you have active locked tables or an active transaction

```

* `LOCK TABLES` can not be used in stored routines - if you try, the following error will be produced on creation:

 
```
ERROR 1314 (0A000): LOCK is not allowed in stored procedures

```

See Also
--------

 * [UNLOCK TABLES](../transactions-unlock-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-lock/>

Coordinated Universal Time
==========================

    UTC stands for Coordinated Universal Time, and is the world standard for regulating time.

 MariaDB stores values internally in UTC, converting them to the required time zone as required.

 In general terms it is equivalent to Greenwich Mean Time (GMT), but UTC is used in technical contexts as it is precisely defined at the subsecond level.

 [Time zones](../time-zones/index) are offset relative to UTC. For example, time in Tonga is UTC + 13, so 03h00 UTC will be 16h00 in Tonga.

 See Also
--------

 * [UTC\_DATE](../utc_date/index)
* [UTC\_TIME](../utc_time/index)
* [UTC\_TIMESTAMP](../utc_timestamp/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/coordinated-universal-time/>

Multi Range Read Optimization
=============================

    Multi Range Read is an optimization aimed at improving performance for IO-bound queries that need to scan lots of rows.

 Multi Range Read can be used with

 * `range` access
* `ref` and `eq_ref` access, when they are using [Batched Key Access](../block-based-join-algorithms/index#batch-key-access-join)

 as shown in this diagram:

 ![possible-mrr-uses]

 The Idea
--------

 ### Case 1: Rowid Sorting for Range Access

 Consider a range query:

 
```
explain select * from tbl where tbl.key1 between 1000 and 2000;
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
|  1 | SIMPLE      | tbl   | range | key1          | key1 | 5       | NULL |  960 | Using index condition |
+----+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

```

When this query is executed, disk IO access pattern will follow the red line in this figure:

 ![no-mrr-access-pattern]

 Execution will hit the table rows in random places, as marked with the blue line/numbers in the figure. 

 When the table is sufficiently big, each table record read will need to actually go to disk (and be served from buffer pool or OS cache), and query execution will be too slow to be practical. For example, a 10,000 RPM disk drive is able to make 167 seeks per second, so in the worst case, query execution will be capped at reading about 167 records per second.

 SSD drives do not need to do disk seeks, so they will not be hurt as badly, however the performance will still be poor in many cases.

 Multi-Range-Read optimization aims to make disk access faster by sorting record read requests and then doing one ordered disk sweep. If one enables Multi Range Read, `EXPLAIN` will show that a "`Rowid-ordered scan`" is used:

 
```
set optimizer_switch='mrr=on';
Query OK, 0 rows affected (0.06 sec)

explain select * from tbl where tbl.key1 between 1000 and 2000;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                     |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
|  1 | SIMPLE      | tbl   | range | key1          | key1 | 5       | NULL |  960 | Using index condition; Rowid-ordered scan |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------------------------------------+
1 row in set (0.03 sec)

```

and the execution will proceed as follows:

 ![mrr-access-pattern]

 Reading disk data sequentially is generally faster, because

 * Rotating drives do not have to move the head back and forth
* One can take advantage of IO-prefetching done at various levels
* Each disk page will be read exactly once, which means we won't rely on disk cache (or buffer pool) to save us from reading the same page multiple times.

 The above can make a huge difference on performance. There is also a catch, though:

 * If you're scanning small data ranges in a table that is sufficiently small so that it completely fits into the OS disk cache, then you may observe that the only effect of MRR is that extra buffering/sorting adds some CPU overhead.

 * `LIMIT n` and `ORDER BY ... LIMIT n` queries with small values of `n` may become slower. The reason is that MRR reads data *in disk order*, while `ORDER BY ... LIMIT n` wants first `n` records *in index order*.

 ### Case 2: Rowid Sorting for Batched Key Access

 Batched Key Access can benefit from rowid sorting in the same way as range access does. If one has a join that uses index lookups:

 
```
explain select * from t1,t2 where t2.key1=t1.col1;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL         | 1000 | Using where |
|  1 | SIMPLE      | t2    | ref  | key1          | key1 | 5       | test.t1.col1 |    1 |             |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+
2 rows in set (0.00 sec)

```

Execution of this query will cause table `t2` to be hit in random locations by lookups made through `t2.key1=t1.col`. If you enable Multi Range and and Batched Key Access, you will get table `t2` to be accessed using a `Rowid-ordered scan`:

 
```
set optimizer_switch='mrr=on';
Query OK, 0 rows affected (0.06 sec)

set join_cache_level=6;
Query OK, 0 rows affected (0.00 sec)

explain select * from t1,t2 where t2.key1=t1.col1;
+----+-------------+-------+------+---------------+------+---------+--------------+------+--------------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra                                                  |
+----+-------------+-------+------+---------------+------+---------+--------------+------+--------------------------------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL         | 1000 | Using where                                            |
|  1 | SIMPLE      | t2    | ref  | key1          | key1 | 5       | test.t1.col1 |    1 | Using join buffer (flat, BKA join); Rowid-ordered scan |
+----+-------------+-------+------+---------------+------+---------+--------------+------+--------------------------------------------------------+
2 rows in set (0.00 sec)

```

The benefits will be similar to those listed for `range` access. 

 An additional source of speedup is this property: if there are multiple records in `t1` that have the same value of `t1.col1`, then regular Nested-Loops join will make multiple index lookups for the same value of `t2.key1=t1.col1`. The lookups may or may not hit the cache, depending on how big the join is. With Batched Key Access and Multi-Range Read, no duplicate index lookups will be made.

 ### Case 3: Key Sorting for Batched Key Access

 Let us consider again the nested loop join example, with `ref` access on the second table:

 
```
explain select * from t1,t2 where t2.key1=t1.col1;
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref          | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL         | 1000 | Using where |
|  1 | SIMPLE      | t2    | ref  | key1          | key1 | 5       | test.t1.col1 |    1 |             |
+----+-------------+-------+------+---------------+------+---------+--------------+------+-------------+

```

Execution of this query plan will cause random hits to be made into the index `t2.key1`, as shown in this picture:

 ![key-sorting-regular-nl-join]

 In particular, on step #5 we'll read the same index page that we've read on step #2, and the page we've read on step #4 will be re-read on step#6. If all pages you're accessing are in the cache (in the buffer pool, if you're using InnoDB, and in the key cache, if you're using MyISAM), this is not a problem. However, if your hit ratio is poor and you're going to hit the disk, it makes sense to sort the lookup keys, like shown in this figure:

 ![key-sorting-join]

 This is roughly what `Key-ordered scan` optimization does. In EXPLAIN, it looks as follows:

 
```
set optimizer_switch='mrr=on,mrr_sort_keys=on';
Query OK, 0 rows affected (0.00 sec)

set join_cache_level=6;
Query OK, 0 rows affected (0.02 sec)
explain select * from t1,t2 where t2.key1=t1.col1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t1
         type: ALL
possible_keys: a
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1000
        Extra: Using where
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: t2
         type: ref
possible_keys: key1
          key: key1
      key_len: 5
          ref: test.t1.col1
         rows: 1
        Extra: Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
2 rows in set (0.00 sec)

```

((TODO: a note about why sweep-read over InnoDB's clustered primary index scan (which is, actually the whole InnoDB table itself) will use `Key-ordered scan` algorithm, but not `Rowid-ordered scan` algorithm, even though conceptually they are the same thing in this case))

 Buffer Space Management
-----------------------

 As was shown above, Multi Range Read requires sort buffers to operate. The size of the buffers is limited by system variables. If MRR has to process more data than it can fit into its buffer, it will break the scan into multiple passes. The more passes are made, the less is the speedup though, so one needs to balance between having too big buffers (which consume lots of memory) and too small buffers (which limit the possible speedup).

 ### Range Access

 When MRR is used for `range` access, the size of its buffer is controlled by the [mrr\_buffer\_size](../server-system-variables/index#mrr_buffer_size) system variable. Its value specifies how much space can be used for each table. For example, if there is a query which is a 10-way join and MRR is used for each table, `10*@@mrr_buffer_size` bytes may be used.

 ### Batched Key Access

 When Multi Range Read is used by Batched Key Access, then buffer space is managed by BKA code, which will automatically provide a part of its buffer space to MRR. You can control the amount of space used by BKA by setting 

 * [join\_buffer\_size](../server-system-variables/index#join_buffer_size) to limit how much memory BKA uses for each table, and
* [join\_buffer\_space\_limit](../server-system-variables/index#join_buffer_space_limit) to limit the total amount of memory used by BKA in the join.

 Status Variables
----------------

 There are three status variables related to Multi Range Read:

 


| Variable name | Meaning |
| --- | --- |
| [Handler\_mrr\_init](../server-status-variables/index#handler_mrr_init) | Counts how many Multi Range Read scans were performed |
| [Handler\_mrr\_key\_refills](../server-status-variables/index#handler_mrr_key_refills) | Number of times key buffer was refilled (not counting the initial fill) |
| [Handler\_mrr\_rowid\_refills](../server-status-variables/index#handler_mrr_rowid_refills) | Number of times rowid buffer was refilled (not counting the initial fill) |

 
Non-zero values of `Handler_mrr_key_refills` and/or `Handler_mrr_rowid_refills` mean that Multi Range Read scan did not have enough memory and had to do multiple key/rowid sort-and-sweep passes. The greatest speedup is achieved when Multi Range Read runs everything in one pass, if you see lots of refills it may be beneficial to increase sizes of relevant buffers [mrr\_buffer\_size](../server-system-variables/index#mrr_buffer_size) [join\_buffer\_size](../server-system-variables/index#join_buffer_size) and [join\_buffer\_space\_limit](../server-system-variables/index#join_buffer_space_limit)

 ### Effect on Other Status Variables

 When a Multi Range Read scan makes an index lookup (or some other "basic" operation), the counter of the "basic" operation, e.g. [Handler\_read\_key](../server-status-variables/index#handler_read_key), will also be incremented. This way, you can still see total number of index accesses, including those made by MRR. [Per-user/table/index statistics](../user-statistics/index) counters also include the row reads made by Multi Range Read scans.

 ### Why Using Multi Range Read Can Cause Higher Values in Status Variables

 Multi Range Read is used for scans that do full record reads (i.e., they are not "Index only" scans). A regular non-index-only scan will read 

 1. an index record, to get a rowid of the table record
2. a table record Both actions will be done by making one call to the storage engine, so the effect of the call will be that the relevan `Handler_read_XXX` counter will be incremented BY ONE, and [Innodb\_rows\_read](../xtradbinnodb-server-status-variables/index#innodb_rows_read) will be incremented BY ONE.

 Multi Range Read will make separate calls for steps #1 and #2, causing TWO increments to `Handler_read_XXX` counters and TWO increments to `Innodb_rows_read` counter. To the uninformed, this looks as if Multi Range Read was making things worse. Actually, it doesn't - the query will still read the same index/table records, and actually Multi Range Read may give speedups because it reads data in disk order.

 Multi Range Read Factsheet
--------------------------

 * Multi Range Read is used by
	+ `range` access method for range scans.
	+ [Batched Key Access](batched_key_access) for joins
* Multi Range Read can cause slowdowns for small queries over small tables, so it is disabled by default.
* There are two strategies:
	+ Rowid-ordered scan
	+ Key-ordered scan
* : and you can tell if either of them is used by checking the `Extra` column in `EXPLAIN` output.
* There are three [optimizer\_switch](../server-system-variables/index#optimizer_switch) flags you can switch ON:
	+ `mrr=on` - enable MRR and rowid ordered scans
	+ `mrr_sort_keys=on` - enable Key-ordered scans (you must also set `mrr=on` for this to have any effect)
	+ `mrr_cost_based=on` - enable cost-based choice whether to use MRR. Currently not recommended, because cost model is not sufficiently tuned yet.

 Differences from MySQL
----------------------

 * MySQL supports only `Rowid ordered scan` strategy, which it shows in `EXPLAIN` as `Using MRR`.
* EXPLAIN in MySQL shows `Using MRR`, while in MariaDB it may show
	+ `Rowid-ordered scan`
	+ `Key-ordered scan`
	+ `Key-ordered Rowid-ordered scan`
* MariaDB uses [mrr\_buffer\_size](../server-system-variables/index#mrr_buffer_size) as a limit of MRR buffer size for `range` access, while MySQL uses [read\_rnd\_buffer\_size](../server-system-variables/index#read_rnd_buffer_size).
* MariaDB has three MRR counters: [Handler\_mrr\_init](../server-status-variables/index#handler_mrr_init), `Handler_mrr_extra_rowid_sorts`, `Handler_mrr_extra_key_sorts`, while MySQL has only `Handler_mrr_init`, and it will only count MRR scans that were used by BKA. MRR scans used by range access are not counted.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [Multi-Range Read Optimization](http://dev.mysql.com/doc/refman/5.6/en/mrr-optimization.html) page in MySQL manual

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/multi-range-read-optimization/>

Spider Server System Variables
==============================

    The following variables are available when the [Spider](../spider/index) storage engine has been installed.

 See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index).

 
**MariaDB starting with [10.4.31](https://mariadb.com/kb/en/mariadb-10431-release-notes/)**Starting from [MariaDB 10.4.31](https://mariadb.com/kb/en/mariadb-10431-release-notes/), [MariaDB 10.5.22](https://mariadb.com/kb/en/mariadb-10522-release-notes/), [MariaDB 10.6.15](https://mariadb.com/kb/en/mariadb-10615-release-notes/), [MariaDB 10.9.8](https://mariadb.com/kb/en/mariadb-10-9-8-release-notes/), [MariaDB 10.10.6](https://mariadb.com/kb/en/mariadb-10-10-6-release-notes/), [MariaDB 10.11.5](https://mariadb.com/kb/en/mariadb-10-11-5-release-notes/), [MariaDB 11.0.3](https://mariadb.com/kb/en/mariadb-11-0-3-release-notes/), all spider system variables with the value -1 for deferring to table parameter values follow the correct overriding mechanism: table parameter (if set) overrides system variables (if not -1) overrides actual variable default. As a side effect, all such system variables in all versions have the same default value as the table param default value.

 Before this change, a non-minus-one system variable value would override the table parameter value. That is, if both the system variable value and the table parameter value were set to be non-minus-one, the system variable value would prevail. For [MariaDB 10.7](../what-is-mariadb-107/index)+ where the system variable default values were the same as table param default instead of -1, this means that if the system variable were not set, but a table param is set to a non-default value, the default would override the non-default value.

 The descriptions of `-1` and default values below in affected variables will be updated accordingly after the release of affected versions.

  #### `spider_auto_increment_mode`

 * **Description:** The [auto increment](../auto_increment/index) mode.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Normal Mode. Uses a counter that Spider gets from the remote backend server with an exclusive lock for the auto-increment value. This mode is slow. Use Quick Mode (`2`), if you use Spider tables with the table partitioning feature and the auto-increment column is the first column of the index. Before [MariaDB 10.3](../what-is-mariadb-103/index), this value works as "1" for partitioned Spider tables.
	+ `1` Quick Mode. Uses an internal Spider counter for the auto-increment value. This mode is fast, but it is possible for duplicates to occur when updating the same table from multiple Spider proxies.
	+ `2` Set Zero Mode. The auto-increment value is given by the remote backend. Sets the column to `0`, even if you set the value to the auto-increment column in your statement. If you use the table with the table partitioning feature, it sets to zero after choosing an inserted partition.
	+ `3` When the auto-increment column is set to `NULL`, the value is given by the remote backend server. If you set the auto-increment column to `0`,the value is given by the local server. Set [spider\_reset\_auto\_incremnet](#spider_reset_auto_increment) to `2` or `3` if you want to use an auto-increment column on the remote server.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>= [MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `3`
* **DSN Parameter Name:** `aim`

 

---

 #### `spider_bgs_first_read`

 * **Description:** Number of first read records to use when performing a concurrent background search. To start a range scan on the remote backend, the storage engine first needs to send the first record. Fetching a second record in the same query can save a network round trip stopping the plan if the backend has a single record. The first and second reads are used to warm up for background search. When not using [spider\_split\_read](#spider_split_read) and [spider\_semi\_split\_read](#spider_semi_split_read), the third read fetches the remaining data source in a single fetch.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Records are usually retrieved.
	+ `1` and greater: Number of records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `2`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `bfr`

 

---

 #### `spider_bgs_mode`

 * **Description:** Background search mode. This enables the use of a thread per data server connection if the query is not shard-based and must be distributed across shards. The partitioning plugin scans partitions one after the other to optimize memory usage. Because the shards are external, reading all shards can be performed in parallel when the plan prunes multiple partitions.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Disables background search.
	+ `1` Uses background search when searching without locks
	+ `2` Uses background search when searching without locks or with shared locks.
	+ `3` Uses background search regardless of locks.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `3`
* **DSN Parameter Name:** `bmd`

 

---

 #### `spider_bgs_second_read`

 * **Description:** Number of second read records on the backend server when using background search. When the first records are found from [spider\_bgs\_first\_read](#spider_bgs_first_read), the engine continues scanning a range adding a `LIMIT` of [spider\_bgs\_first\_read](#spider_bgs_first_read) and [spider\_bgs\_second\_read](#spider_bgs_second_read).
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Records are usually retrieved.
	+ `1` and greater: Number of records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Default Session Value:** `100` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `100`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `bsr`

 

---

 #### `spider_bka_engine`

 * **Description:** Storage engine used with temporary tables when the [spider\_bka\_mode](#spider_bka_mode) system variable is set to `1`. Defaults to the value of the [table parameter](../spider-table-parameters/index), which is [MEMORY](../memory-storage-engine/index) by default.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Session Value:** `""`
* **Default Table Value:** `Memory`
* **DSN Parameter Name:** `bke`

 

---

 #### `spider_bka_mode`

 * **Description:** Internal action to perform when multi-split reads are disabled. If the [spider\_multi\_split\_read](#spider_multi_split_read) system variable is set to `0`, Spider uses this variable to determine how to handle statements when the optimizer resolves range retrieval to multiple conditions.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Uses "union all".
	+ `1` Uses a temporary table, if it is judged acceptable.
	+ `2` Uses a temporary table, if it is judged acceptable and avoids replication delay.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `bkm`

 

---

 #### `spider_bka_table_name_type`

 * **Description:** The type of temporary table name for bka.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`

 

---

 #### `spider_block_size`

 * **Description:** Size of memory block used in MariaDB. Can usually be left unchanged.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `16384`
* **Range:** `0` to `4294967295`
* **DSN Parameter Name:** `bsz`

 

---

 #### `spider_buffer_size`

 * **Description:** Buffer size. `-1`, the default, will use the [table parameter](../spider-table-parameters/index).
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `16000` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `2147483647`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `spider_bulk_size`

 * **Description:** Size in bytes of the buffer when multiple grouping multiple `INSERT` statements in a batch, (that is, bulk inserts).
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` or greater: Size of the buffer.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `16000` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `16000`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `bsz`

 

---

 #### `spider_bulk_update_mode`

 * **Description:** Bulk update and delete mode. Note: If you use a non-default value for the [spider\_bgs\_mode](#spider_bgs_mode) or [spider\_split\_read](#spider_split_read) system variables, Spider sets this variable to `2`.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Sends `UPDATE` and `DELETE` statements one by one.
	+ `1` Collects multiple `UPDATE` and `DELETE` statements, then sends the collected statements one by one.
	+ `2` Collects multiple `UPDATE` and `DELETE` statements and sends them together.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `bum`

 

---

 #### `spider_bulk_update_size`

 * **Description:** Size in bytes for `UPDATE` and `DELETE` queries when generating bulk updates.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` or greater: Size of buffer.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `16000` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `16000`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `bus`

 

---

 #### `spider_casual_read`

 * **Description:** Casual Reads enables all isolation levels, (such as repeatable reads) to work with transactions on multiple backends. With auto-commit queries, you can relax read consistency and run on multiple connections to the backends. This enables parallel queries across partitions, even if multiple shards are stored on the same physical server.
	+ `-1` Use [table parameter](../spider-table-parameters/index).
	+ `0` Use casual read.
	+ `1` Choose connection channel automatically.
	+ `2` to `63` Number of connection channels.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `63`
* **DSN Parameter Name:** `##`

 

---

 #### `spider_conn_recycle_mode`

 * **Description:** Connection recycle mode.
	+ `0` Disconnect.
	+ `1` Recycle by all sessions.
	+ `2` Recycle in the same session.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Range:** `0` to `2`
* **Default Session Value:** `0`

 

---

 #### `spider_conn_recycle_strict`

 * **Description:** Whether to force the creation of new connections.
	+ `1` Don't force.
	+ `0` Force new connection
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0`
* **Range:** `0` to `1`

 

---

 #### `spider_conn_wait_timeout`

 * **Description:** Max waiting time in seconds for Spider to get a remote connection.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `10`
* **Range:** `0` to `1000`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_connect_error_interval`

 * **Description:** Return same error code until interval passes if connection is failed
* **Scope:** Global,
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `4294967295`

 

---

 #### `spider_connect_mutex`

 * **Description:** Whether to serialize remote servers connections (use mutex at connecting). Use this parameter if you get an error or slowdown due to too many connection processes.
	+ `0` Not serialized.
	+ `1` : Serialized.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `0`

 

---

 #### `spider_connect_retry_count`

 * **Description:** Number of times to retry connections that fail due to too many connection processes.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1000`
* **Range:** `0` to `2147483647`

 

---

 #### `spider_connect_retry_interval`

 * **Description:** Interval in microseconds for connection failure due to too many connection processes.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1000`
* **Range:** `-1` to `9223372036854775807`

 

---

 #### `spider_connect_timeout`

 * **Description:** Timeout in seconds to declare remote backend unresponsive when opening a connection. Change for high-latency networks.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` Less than 1.
	+ `1` and greater: Number of seconds.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `6` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `cto`

 

---

 #### `spider_crd_bg_mode`

 * **Description:** Indexes cardinality statistics in the background. Disable when the [spider\_crd\_mode](#spider_crd_mode) system variable is set to `3` or when the [spider\_crd\_interval](#spider_crd_interval) variable is set to `0`.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Disables background confirmation.
	+ `2` Enables background confirmation.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `cbm`

 

---

 #### `spider_crd_interval`

 * **Description:** Time interval in seconds of index cardinality statistics. Set to `0` to always get the latest information from remote servers.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `1` or more: Interval in seconds table state confirmation.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `51` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `51`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `civ`

 

---

 #### `spider_crd_mode`

 * **Description:** Mode for index cardinality statistics. By default, uses `SHOW` at the table-level.
	+ `-1,0` Uses the [table parameter](../spider-table-parameters/index).
	+ `1` Uses the `SHOW` command.
	+ `2` Uses the Information Schema.
	+ `3` Uses the `EXPLAIN` command.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `3`
* **DSN Parameter Name:** `cmd`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_crd_sync`

 * **Description:** Synchronize index cardinality statistics in partitioned tables.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Disables synchronization.
	+ `1` Uses table state synchronization when opening a table, but afterwards performs no synchronization.
	+ `2` Enables synchronization.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `csy`

 

---

 #### `spider_crd_type`

 * **Description:** Type of cardinality calculation. Only effective when the [spider\_crd\_mode](#spider_crd_mode) system variable is set to use `SHOW` (`1`) or to use the Information Schema (`2`).
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Uses the value of the [spider\_crd\_weight](#spider_crd_weight) system variable, as a fixed value.
	+ `1` Uses the value of the [spider\_crd\_weight](#spider_crd_weight) system variable, as an addition value.
	+ `2` Uses the value of the [spider\_crd\_weight](#spider_crd_weight) system variable, as a multiplication value.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `2`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `ctp`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_crd_weight`

 * **Description:** Weight coefficient used to calculate effectiveness of index from the cardinality of column. For more information, see the description for the [spider\_crd\_type](#spider_crd_type) system variable.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` or greater: Weight.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `2`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `cwg`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_delete_all_rows_type`

 * **Description:** The type of delete\_all\_rows.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`

 

---

 #### `spider_direct_dup_insert`

 * **Description:** Manages duplicate key check for [REPLACE](../replace/index), [INSERT IGNORE](../ignore/index) and [LOAD DATA LOCAL INFILE](../load-data-infile/index) to remote servers. This can save on network roundtrips if the key always maps to a single partition. For bulk operations, records are checked for duplicate key errors one by one on the remote server, unless you set it to avoid duplicate checks on local servers (`1`).
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Performs duplicate checks on the local server.
	+ `1` Avoids duplicate checks on the local server.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `ddi`

 

---

 #### `spider_direct_order_limit`

 * **Description:** Pushes `ORDER BY` and `LIMIT` operations to the remote server.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Uses local execution.
	+ `1` Uses push down execution.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `dol`

 

---

 #### `spider_dry_access`

 * **Description:** Simulates an empty result-set. No queries are sent to the backend. Use for performance tuning.
	+ `0` Normal access.
	+ `1` All access from Spider to data node is suppressed.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `spider_error_read_mode`

 * **Description:** Sends an empty result-set when reading a backend server raises an error. Useful with applications that don't implement transaction replays.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Returns an error.
	+ `1` Returns an empty result.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `erm`

 

---

 #### `spider_error_write_mode`

 * **Description:** Sends an empty result-set when writing to a backend server raises an error. Useful with applications that don't implement transaction replays.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Returns an error.
	+ `1` Returns an empty result-set on error.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `ewm`

 

---

 #### `spider_first_read`

 * **Description:** Number of first read records to start a range scan on the backend server. Spider needs to send the first record. Fetching the second record saves network round-trips, stopping the plan if the backend has a single record. First read and second read are used to warm up for background searches, third reads without using the [spider\_split\_read](#spider_split_read) and [spider\_semi\_split\_read](#spider_semi_split_read) system variables fetches the remaining data source in a single last fetch.
	+ `-1` Use the [table parameter](../spider-table-parameters/index).
	+ `0` Usually retrieves records.
	+ `1` and greater: Sets the number of first read records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `2`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `frd`

 

---

 #### `spider_force_commit`

 * **Description:** Behavior when error occurs on `XA PREPARE`, `XA COMMIT`, and `XA ROLLBACK` statements.
	+ `0` Returns the error.
	+ `1` Returns the error when the `xid` doesn't exist, otherwise it continues processing the XA transaction.
	+ `2` Continues processing the XA transaction, disregarding all errors.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0`
* **Range:** `0` to `2`

 

---

 #### `spider_general_log`

 * **Description:** Whether Spider logs all commands to the General Log. Spider logs error codes according to the [spider\_log\_result\_errors](#spider_log_result_errors) system variable.
	+ `OFF` Logs no commands.
	+ `ON` Logs commands to the General Log.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`

 

---

 #### `spider_index_hint_pushdown`

 * **Description:** Whether to use pushdown index hints, like `force_index`.
	+ `0` Do not use pushdown hints
	+ `1` Use pushdown hints
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_init_sql_alloc_size`

 * **Description:** Initial size of the local SQL buffer.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` or greater: Size of the buffer.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1024` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1024`
* **DSN Parameter Name:** `isa`
* **Range:** `-1` to `2147483647`
* **Deprecated:** [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-1075-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/), [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/)

 

---

 #### `spider_internal_limit`

 * **Description:** Limits the number of records when acquired from a remote server.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` or greater: Records limit.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `9223372036854775807` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `ilm`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_internal_offset`

 * **Description:** Skip records when acquired from the remote server.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` or more : Number of records to skip.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `ios`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_internal_optimize`

 * **Description:** Whether to perform push down operations for [OPTIMIZE TABLE](../optimize-table/index) statements.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Transmitted.
	+ `1` Not transmitted.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `iom`

 

---

 #### `spider_internal_optimize_local`

 * **Description:** Whether to transmit to remote servers when [OPTIMIZE TABLE](optimize_table) statements are executed on the local server.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Not transmitted.
	+ `1` Transmitted.
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `iol`

 

---

 #### `spider_internal_sql_log_off`

 * **Description:** Whether to log SQL statements sent to the remote server in the [General Query Log](../general-query-log/index).
	+ Explicitly setting this system variable to either `ON` or `OFF` causes the Spider node to send a `SET sql_log_off` statement to each of the data nodes using the `SUPER` privilege.
	+ `-1` Don't know or does not matter; don't send 'SET SQL\_LOG\_OFF' statement
	+ `0` Send 'SET SQL\_LOG\_OFF 0' statement to data nodes (logs SQL statements to the remote server)
	+ `1` Send 'SET SQL\_LOG\_OFF 1' statement to data nodes (doesn't log SQL statements to the remote server)
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric` (previously `boolean`)
* **Range:** `-1` to `1`
* **Default Session Value:** `-1` (previously `ON`)

 

---

 #### `spider_internal_unlock`

 * **Description:** Whether to transmit unlock tables to the connection of the table used with `SELECT` statements.
	+ `0` Not transmitted.
	+ `1` Transmitted.
* **Data Type:** `boolean`
* **Default Session Value:** `0`

 

---

 #### `spider_internal_xa`

 * **Description:** Whether to implement XA at the server- or storage engine-level. When using the server-level, set different values for the [server\_id](../server-system-variables/index#server_id) system variable on all server instances to generate different `xid` values.
	+ `OFF` Uses the storage engine protocol.
	+ `ON` Uses the server protocol.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`

 

---

 #### `spider_internal_xa_id_type`

 * **Description:** The type of internal\_xa id.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0`
* **Range:** `-1` to `1`

 

---

 #### `spider_internal_xa_snapshot`

 * **Description:** Limitation for reading consistent data on all backend servers when using MariaDB's internal XA implementation and `START TRANSACTION WITH CONSISTENT SNAPSHOT`.
	+ `0` Raise error when using a Spider table.
	+ `1` Raise error when issued a `START TRANSACTION` statement.
	+ `2` Takes a consistent snapshot on each backend, but loses global consistency.
	+ `3` Starts transactions with XA, but removes `CONSISTENT SNAPSHOT`.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Range:** `0` to `3`
* **Default Session Value:** `0`

 

---

 #### `spider_load_crd_at_startup`

 * **Description:** Whether to load CRD from the system table at startup.
	+ `-1` Use [table parameter](../spider-table-parameters/index)
	+ `0` Do not load
	+ `1` Load
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_load_sts_at_startup`

 * **Description:** Whether to load STS from the system table at startup.
	+ `-1` Use [table parameter](../spider-table-parameters/index)
	+ `0` Do not load
	+ `1` Load
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_local_lock_table`

 * **Description:** Whether to push [LOCK TABLES](../transactions-lock/index) statements down to the remote server.
	+ `0` Transmitted.
	+ `1` Not transmitted.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `spider_lock_exchange`

 * **Description:** Whether to convert [SELECT... LOCK IN SHARE MODE](../lock-in-share-mode/index) and [SELECT... FOR UPDATE](../for-update/index) statements into a [LOCK TABLE](../lock/index) statement.
	+ `0` Not converted.
	+ `1` Converted.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `0`

 

---

 #### `spider_log_result_error_with_sql`

 * **Description:** How to log SQL statements with result errors.
	+ `0` No log
	+ `1` Log error
	+ `2` Log warning summary
	+ `3` Log warning
	+ `4` Log info (Added in [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/))
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4`

 

---

 #### `spider_log_result_errors`

 * **Description:** Log results from data nodes to the Spider node in the [Error Log](../error-log/index). Performs no logging by default.
	+ `0` : Logs no errors from data nodes.
	+ `1` : Logs errors from data nodes.
	+ `2` : Logs errors from data nodes, as well as warning summaries.
	+ `3` : Logs errors from data nodes, as well as warning summaries and details.
	+ `4` : Logs errors from data nodes, as well as warning summaries and details, and result summaries.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `4`

 

---

 #### `spider_low_mem_read`

 * **Description:** Whether to use low memory mode when executing queries issued internally to remote servers that return result-sets.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't use low memory mode.
	+ `1` Uses low memory mode.
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `1`

 

---

 #### `spider_max_connections`

 * **Description:** Maximum number of connections from Spider to a remote MariaDB servers. Defaults to `0`, which is no limit.
* **Command-line:** `--spider-max-connections`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0`
* **Range:** `0` to `99999`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_max_order`

 * **Description:** Maximum number of columns for `ORDER BY` operations.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` and greater: Maximum number of columns.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `32767` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `32767`
* **Range:** `-1` to `32767`
* **DSN Parameter Name:** `mod`

 

---

 #### `spider_multi_split_read`

 * **Description:** Whether to divide a statement into multiple SQL statements sent to the remote backend server when the optimizer resolves range retrievals to multiple conditions.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't divide statements.
	+ `1` Divides statements.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `100` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `msr`

 

---

 #### `spider_net_read_timeout`

 * **Description:** TCP timeout in seconds to declare remote backend servers unresponsive when reading from a connection. Change for high latency networks.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Less than 1 second timeout.
	+ `1` and greater: Timeout in seconds.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `600` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `600`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `nrt`

 

---

 #### `spider_net_write_timeout`

 * **Description:** TCP timeout in seconds to declare remote backend servers unresponsive when writing to a connection. Change for high latency networks.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` Less than 1 second timeout.
	+ `1` and more: Timeout in seconds.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `600` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `600`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `nwt`

 

---

 #### `spider_ping_interval_at_trx_start`

 * **Description:** Resets the connection with keepalive timeout in seconds by sending a ping.
	+ `0` At every transaction.
	+ `1` and greater: Number of seconds.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `3600`
* **Range:** `0` to `2147483647`

 

---

 #### `spider_quick_mode`

 * **Description:** Sets the backend query buffering to cache on the remote backend server or in the local buffer.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Local buffering, it acquires records collectively with `store_result`.
	+ `1` Remote buffering, it acquires records one by one. Interrupts don't wait and recovery on context switch back.
	+ `2` Remote buffering, it acquires records one by one. Interrupts wait to the end of the acquisition.
	+ `3` Local buffering, uses a temporary table on disk when the result-set is greater than the value of the [spider\_quick\_page\_size](#spider_quick_page_size) system variable.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `3` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `3`
* **DSN Parameter Name:** `qmd`

 

---

 #### `spider_quick_page_byte`

 * **Description:** Memory limit by size in bytes in a page when acquired record by record.
	+ `-1` The [table parameter](../spider-table-parameters/index) is used. When quick\_mode is 1 or 2, Spider stores at least 1 record even if quick\_page\_byte is smaller than 1 record. When quick\_mode is 3, quick\_page\_byte is used for judging using temporary tables. That is given priority when spider\_quick\_page\_byte is set.
	+ `0` or greater: Memory limit.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `10485760` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `9223372036854775807`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/)

 

---

 #### `spider_quick_page_size`

 * **Description:** Number of records in a page when acquired record by record.
	+ `-1` The [table parameter](../spider-table-parameters/index) is adopted.
	+ `0` or greater: Number of records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1024` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `100`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `qps`

 

---

 #### `spider_read_only_mode`

 * **Description:** Whether to allow writes on Spider tables.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Allows writes to Spider tables.
	+ `1` Makes tables read- only.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `rom`

 

---

 #### `spider_remote_access_charset`

 * **Description:** Forces the specified session [character set](../character-sets/index) when connecting to the backend server. This can improve connection time performance.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Session Value:** `null`

 

---

 #### `spider_remote_autocommit`

 * **Description:** Sets the auto-commit mode when connecting to backend servers. This can improve connection time performance.
	+ `-1` Doesn't change the auto-commit mode.
	+ `0` Sets the auto-commit mode to `0`.
	+ `1` Sets the auto-commit mode to `1`.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `-1`
* **Range:** `-1` to `1`

 

---

 #### `spider_remote_default_database`

 * **Description:** Sets the local default database when connecting to backend servers. This can improve connection time performance.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Session Value:** Empty string

 

---

 #### `spider_remote_sql_log_off`

 * **Description:** Sets the [sql\_log\_off](../server-system-variables/index#sql_log_off) system variable to use when connecting to backend servers.
	+ `-1` Doesn't set the value.
	+ `0` Doesn't log Spider SQL statements to remote backend servers.
	+ `1` Logs SQL statements on remote backend
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `-1`
* **Range:** `-1` to `1`

 

---

 #### `spider_remote_time_zone`

 * **Description:** Forces the specified [time zone](../time-zones/index) setting when connecting to backend servers. This can improve connection performance when you know the time zone.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Session Value:** `null`

 

---

 #### `spider_remote_trx_isolation`

 * **Description:** Sets the [Transaction Isolation Level](../set-transaction/index#isolation-levels) when connecting to the backend server.
	+ `-1` Doesn't set the Isolation Level.
	+ `0` Sets to the `READ UNCOMMITTED` level.
	+ `1` Sets to the `READ COMMITTED` level.
	+ `2` Sets to the `REPEATABLE READ` level.
	+ `3` Sets to the `SERIALIZABLE` level.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `-1`
* **Range:** `-1` to `3`

 

---

 #### `spider_remote_wait_timeout`

 * **Description:** Wait timeout in seconds on remote server. `-1` means not set.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `2147483647`
* **Introduced:** [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)

 

---

 #### `spider_reset_sql_alloc`

 * **Description:** Resets the per connection SQL buffer after an SQL statement executes.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't reset.
	+ `1` Resets.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `rsa`

 

---

 #### `spider_same_server_link`

 * **Description:** Enables the linking of a table to the same local instance.
	+ `0` Disables linking.
	+ `1` Enables linking.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`

 

---

 #### `spider_second_read`

 * **Description:** Number of second read records on the backend server when the first records are found from the first read. Spider continues scanning a range, adding a `LIMIT` using the [spider\_first\_read](#spider_first_read) and [spider\_second\_read](#spider_second_read) variables.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Usually retrieves records.
	+ `1` and greater: Number of records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `srd`

 

---

 #### `spider_select_column_mode`

 * **Description:** Mode for column retrieval from remote backend server.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Uses index columns when the `SELECT` statement can resolve with an index, otherwise uses all columns.
	+ `1` Uses all columns judged necessary to resolve the query.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `scm`

 

---

 #### `spider_selupd_lock_mode`

 * **Description:** Local lock mode on `INSERT SELECT`.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Takes no locks.
	+ `1` Takes shared locks.
	+ `2` Takes exclusive locks.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `slm#`

 

---

 #### `spider_semi_split_read`

 * **Description:** Whether to use chunk retrieval with offset and limit parameters on SQL statements sent to the remote backend server when using the [spider\_split\_read](#spider_split_read) system variable.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't use chunk retrieval.
	+ `1 or more`  Uses chunk retrieval.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `ssr#`

 

---

 #### `spider_semi_split_read_limit`

 * **Description:** Sets the limit value for the [spider\_semi\_split\_read](#spider_semi_split_read) system variable.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` or more: The limit value.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `9223372036854775807` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `ssl#`

 

---

 #### `spider_semi_table_lock`

 * **Description:** Enables semi-table locking. This adds a [LOCK TABLES](../transactions-lock/index) statement to SQL executions sent to the remote backend server when using non-transactional storage engines to preserve consistency between roundtrips.
	+ `0` Disables semi-table locking.
	+ `1` Enables semi-table locking.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.8](../what-is-mariadb-108/index)), `1` (<= [MariaDB 10.7](../what-is-mariadb-107/index))
* **Range:** `0` to `1`
* **DSN Parameter Name:** `stl#`

 

---

 #### `spider_semi_table_lock_connection`

 * **Description:** Whether to use multiple connections with semi-table locking. To enable semi-table locking, use the [spider\_semi\_table\_lock](#spider_semi_table_lock) system variable.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Uses the same connection.
	+ `1` Uses different connections.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `stc#`

 

---

 #### `spider_semi_trx`

 * **Description:** Enables semi-transactions. This controls transaction consistency when an SQL statement is split into multiple statements issued to the backend servers. You can preserve or relax consistency as need. Spider encapsulates auto-committed SQL statements within a transaction on the remote backend server. When using `READ COMMITTED` or `READ UNCOMMITTED` [transaction isolation levels](../set-transaction/index#isolation-levels) to force consistency, set the [spider\_semi\_trx\_isolation](#spider_semi_trx_isolation) system variable to `2`.
	+ `0` Disables semi-transaction consistency.
	+ `1` Enables semi-transaction consistency.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `ON`

 

---

 #### `spider_semi_trx_isolation`

 * **Description:** Set consistency during range SQL execution when [spider\_sync\_trx\_isolation](#spider_sync_trx_isolation) is 1
	+ `-1` OFF
	+ `0` READ UNCOMMITTED
	+ `1` READ COMMITTED
	+ `2` REPEATABLE READ
	+ `3` SERIALIZABLE
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `-1`
* **Range:** `-1` to `3`

 

---

 #### `spider_skip_default_condition`

 * **Description:** Whether to compute condition push downs.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Computes condition push downs.
	+ `1` Doesn't compute condition push downs.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `sdc`

 

---

 #### `spider_skip_parallel_search`

 * **Description:** Whether to skip parallel search by specific conditions.
	+ `-1` :use [table parameter](../spider-table-parameters/index)
	+ `0` :not skip
	+ `1` :skip parallel search if query is not SELECT statement
	+ `2` :skip parallel search if query has SQL\_NO\_CACHE
	+ `3` :1+2
* **Commandline:** `--spider-skip-parallel-search=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `3`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_slave_trx_isolation`

 * **Description:** Transaction isolation level when Spider table is used by slave SQL thread.
	+ `-1` off
	+ `0` read uncommitted
	+ `1` read committed
	+ `2` repeatable read
	+ `3` serializable
* **Commandline:** `--spider-slave-trx-isolation=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `-1`
* **Range:** `-1` to `3`
* **Introduced:** [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/)

 

---

 #### `spider_split_read`

 * **Description:** Number of records in chunk to retry the result when a range query is sent to remote backend servers.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` or more: Number of records.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `9223372036854775807` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **DSN Parameter Name:** `srd`

 

---

 #### `spider_store_last_crd`

 * **Description:** Whether to store last CRD result in the system table.
	+ `-1` Use [table parameter](../spider-table-parameters/index).
	+ `0` Do not store last CRD result in the system table.
	+ `1` Store last CRD result in the system table.
* **Commandline:** `--spider-store-last-crd=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_store_last_sts`

 * **Description:** Whether to store last STS result in the system table.
	+ `-1` Use [table parameter](../spider-table-parameters/index).
	+ `0` Do not store last STS result in the system table.
	+ `1` Store last STS result in the system table.
* **Commandline:** `--spider-store-last-sts=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_strict_group_by`

 * **Description:** Whether to use columns in select clause strictly for group by clause
	+ `-1` Use the [table parameter](../spider-table-parameters/index).
	+ `0` Do not strictly use columns in select clause for group by clause
	+ `1` Use columns in select clause strictly for group by clause
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `1`
* **Introduced:** [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)

 

---

 #### `spider_sts_bg_mode`

 * **Description:** Enables background confirmation for table statistics. When background confirmation is enabled, Spider uses one thread per partition to maintain table status. Disable when the [spider\_sts\_interval](#spider_sts_interval) system variable is set to `0`, which causes Spider to always retrieve the latest information as need. It is effective, when the [spider\_sts\_interval](#spider_sts_interval) system variable is set to `10`.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Disables background confirmation.
	+ `1` Enables background confirmation (create thread per table/partition).
	+ `2` Enables background confirmation (use static threads). (from MariaDB 10.)
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `2` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `sbm`

 

---

 #### `spider_sts_interval`

 * **Description:** Time interval of table statistics from the remote backend servers.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Retrieves the latest table statistics on request.
	+ `1` or more: Interval in seconds for table state confirmation.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `10` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `10`
* **Range:** `-1` to `2147483647`
* **DSN Parameter Name:** `siv`

 

---

 #### `spider_sts_mode`

 * **Description:** Table statistics mode. Mode for table statistics. The [SHOW](../show/index) command is used at the table level default.
	+ `-1,0` Uses the [table parameter](../spider-table-parameters/index).
	+ `1` Uses the `SHOW` command.
	+ `2` Uses the Information Schema.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `1` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `1`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `smd`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

 

---

 #### `spider_sts_sync`

 * **Description:** Synchronizes table statistics in partitioned tables.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't synchronize table statistics in partitioned tables.
	+ `1` Synchronizes table state when opening a table, doesn't synchronize after opening.
	+ `2` Synchronizes table statistics.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Session Value:** `0` (>=[MariaDB 10.7](../what-is-mariadb-107/index)), `-1` (<= [MariaDB 10.6](../what-is-mariadb-106/index))
* **Default Table Value:** `0`
* **Range:** `-1` to `2`
* **DSN Parameter Name:** `ssy`

 

---

 #### `spider_support_xa`

 * **Description:** XA Protocol for mirroring and for multi-shard transactions.
	+ `1` Enables XA Protocol for these Spider operations.
	+ `0` Disables XA Protocol for these Spider operations.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Table Value:** `1`

 

---

 #### `spider_sync_autocommit`

 * **Description:** Whether to push down local auto-commits to remote backend servers.
	+ `OFF` Pushes down local auto-commits.
	+ `ON` Doesn't push down local auto-commits.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `ON`

 

---

 #### `spider_sync_sql_mode`

 * **Description:** Whether to sync [sql\_mode](../sql-mode/index).
	+ `OFF` No sync
	+ `ON` Sync
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`
* **Introduced:** [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)

 

---

 #### `spider_sync_time_zone`

 * **Description:** Whether to push the local time zone down to remote backend servers.
	+ `OFF` Doesn't synchronize time zones.
	+ `ON` Synchronize time zones.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`
* **Removed:** [MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/)

 

---

 #### `spider_sync_trx_isolation`

 * **Description:** Pushes local transaction isolation levels down to remote backend servers.
	+ `OFF` Doesn't push down local isolation levels.
	+ `ON` Pushes down local isolation levels.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `ON`

 

---

 #### `spider_table_crd_thread_count`

 * **Description:** Static thread count of table crd.
* **Commandline:** `--spider-table-crd-thread-count=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `1` to `4294967295`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_table_init_error_interval`

 * **Description:** Interval in seconds where the same error code is returned if table initialization fails. Use to protect against infinite loops in table links.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `4294967295`

 

---

 #### `spider_table_sts_thread_count`

 * **Description:** Static thread count of table sts.
* **Commandline:** `--spider-table-sts-thread-count=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `10`
* **Range:** `1` to `4294967295`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 

---

 #### `spider_udf_ct_bulk_insert_interval`

 * **Description:** Interval in milliseconds between bulk inserts at copying. For use with the UDF spider\_copy\_tables, which copies table data linked to a Spider table from the source server to destination server using bulk insert. If this interval is 0, it may cause higher write traffic.
	+ `-1` Uses the UDF parameter.
	+ `0` and more: Time in milliseconds.
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `2147483647`
* **Range:** `-1` to `2147483647`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_udf_ct_bulk_insert_rows`

 * **Description:** Number of rows to insert at a time when copying during bulk inserts.
	+ `-1, 0`: Uses the [table parameter](../spider-table-parameters/index).
	+ `1` and more: Number of rows
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `18446744073709551615`
* **Range:** `-1` to `9223372036854775807`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_udf_ds_bulk_insert_rows`

 * **Description:** Number of rows inserted at a time during bulk inserts when the result-set is stored in a temporary table on executing a UDF.
	+ `-1, 0` Uses the UDF parameter.
	+ `1` or more: Number of rows
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `9223372036854775807`
* **Range:** `-1` to `9223372036854775807`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_udf_ds_table_loop_mode`

 * **Description:** Whether to store the result-set in the same temporary table when the temporary table list count for UDF is less than the result-set count on UDF execution.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Drops records.
	+ `1` Inserts the last table.
	+ `2` Inserts the first table and loops again.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `2`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_udf_ds_use_real_table`

 * **Description:** Whether to use real table for temporary table list.
	+ `-1` Use UDF parameter.
	+ `0` Do not use real table.
	+ `1` Use real table.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Range:** `-1` to `1`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_udf_table_lock_mutex_count`

 * **Description:** Mutex count of table lock for Spider UDFs.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `1` to `4294967295`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 #### `spider_udf_table_mon_mutex_count`

 * **Description:** Mutex count of table mon for Spider UDFs.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `20`
* **Range:** `1` to `4294967295`
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_use_all_conns_snapshot`

 * **Description:** Whether to pass `START TRANSACTION WITH SNAPSHOT` statements to all connections.
	+ `OFF` Doesn't pass statement to all connections.
	+ `ON` Passes statement to all connections.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Session Value:** `OFF`

 

---

 #### `spider_use_cond_other_than_pk_for_update`

 * **Description:** Whether to use all conditions even if condition has a primary key.
	+ `0` Don't use all conditions
	+ `1` Use all conditions
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1`
* **Introduced:** [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)

 

---

 #### `spider_use_consistent_snapshot`

 * **Description:** Whether to push a local `START TRANSACTION WITH CONSISTENT` statement down to remote backend servers.
	+ `OFF` Doesn't push the local statement down.
	+ `ON` Pushes the local statement down.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `spider_use_default_database`

 * **Description:** Whether to use the default database.
	+ `OFF` Doesn't use the default database.
	+ `ON` Uses the default database.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `ON`

 

---

 #### `spider_use_flash_logs`

 * **Description:** Whether to push [FLUSH LOGS](flush-logs) statements down to remote backend servers.
	+ `OFF` Doesn't push the statement down.
	+ `ON` Pushes the statement down.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `spider_use_handler`

 * **Description:** Converts [HANDLER](../handler/index) SQL statements. When the [spider\_sync\_trx\_isolation](#spider_sync_trx_isolation) system variable is set to `0`, Spider disables [HANDLER](../handler/index) conversions to prevent use of the statement on the [SERIALIZABLE](../set-transaction/index#serializable) isolation level.
	+ `-1` Uses [table parameter](../spider-table-parameters/index).
	+ `0` Converts [HANDLER](../handler/index) statements into [SELECT](../select/index) statements.
	+ `1` Passes [HANDLER](../handler/index) to the remote backend server.
	+ `2` Converts SQL statements to [HANDLER](../handler/index) statements.
	+ `3` Converts SQL statements to [HANDLER](../handler/index) statements and [HANDLER](../handler/index) statements to SQL statements.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `0`
* **Range:** `-1` to `3`
* **DSN Parameter Name:** `uhd`
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)
* **Removed:** [MariaDB 10.10](../what-is-mariadb-1010/index)

 

---

 #### `spider_use_pushdown_udf`

 * **Description:** When using a UDF function in a condition and the [engine\_condition\_pushdown](../server-system-variables/index#engine_condition_pushdown) system variable is set to `1`, whether to execute the UDF function locally or push it down.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Doesn't transmit the UDF
	+ `1` Transmits the UDF.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `1`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `upu`

 

---

 #### `spider_use_snapshot_with_flush_tables`

 * **Description:** Whether to encapsulate [FLUSH LOGS](flush-logs) and [UNLOCK TABLES](../lock-tables-and-unlock-tables/index) statements when `START TRANSACTION WITH CONSISTENT` and `FLUSH TABLE WITH READ LOCK` statements are sent to the remote backend servers.
	+ `0` : No encapsulation.
	+ `1` : Encapsulates, only when the [spider\_use\_all\_conns\_snapshot](#spider_use_all_conns_snapshot) system variable i set to `1`.
	+ `2` : Synchronizes the snapshot using a [LOCK TABLES](../lock-tables-and-unlock-tables/index) statement and [flush|FLUSH TABLES]] at the XA transaction level. This is only effective when the [spider\_use\_all\_cons\_snapshot](#spider_use_all_cons_snapshot) system variable is set to `1`.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `0`
* **Range:** `0` to `2`

 

---

 #### `spider_use_table_charset`

 * **Description:** Whether to use the local table [character set](../data-types-character-sets-and-collations/index) for the remote backend server connections.
	+ `-1` Uses the [table parameter](../spider-table-parameters/index).
	+ `0` Use `utf8`.
	+ `1` Uses the table character set.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `-1`
* **Default Table Value:** `1`
* **Range:** `-1` to `1`
* **DSN Parameter Name:** `utc`

 

---

 #### `spider_version`

 * **Description:** The current Spider version. Removed in [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/) when the Spider version number was matched with the server version.
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Removed:** [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/)

 

---

 #### `spider_wait_timeout`

 * **Description:** Wait timeout in seconds of setting to remote server. `-1` means not set.
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `604800`
* **Range:** `-1` to `2147483647`
* **Introduced:** [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)

 

---

 #### `spider_xa_register_mode`

 * **Description:** Mode of XA transaction register into system table.
	+ `0` Register all XA transactions
	+ `1` Register only write XA transactions
* **Command-line:** `--spider-xa-register-mode=#`
* **Scope:** Global, Session
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `1`
* **Range:** `0` to `1`
* **Introduced:** [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)
* **Deprecated:** [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/), [MariaDB 10.8.3](https://mariadb.com/kb/en/mariadb-1083-release-notes/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-server-system-variables/>

SHOW TRIGGERS
=============

    Syntax
------

 
```
SHOW TRIGGERS [FROM db_name]
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

  `SHOW TRIGGERS` lists the triggers currently defined for tables in a database (the default database unless a `FROM` clause is given). This statement requires the `[TRIGGER](../show-privileges/index)` privilege (prior to MySQL 5.1.22, it required the `SUPER` privilege). 

 The `LIKE` clause, if present on its own, indicates which table names to match and causes the statement to display triggers for those tables. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 Similar information is stored in the `[information\_schema.TRIGGERS](../information-schema-triggers-table/index)` table.

 
**MariaDB starting with [10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)**If there are multiple triggers for the same action, then the triggers are shown in action order.

 
Examples
--------

 For the trigger defined at [Trigger Overview](../trigger-overview/index):

 
```
SHOW triggers Like 'animals' \G
*************************** 1. row ***************************
             Trigger: the_mooses_are_loose
               Event: INSERT
               Table: animals
           Statement: BEGIN
 IF NEW.name = 'Moose' THEN
  UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END
              Timing: AFTER
             Created: 2016-09-29 13:53:34.35
            sql_mode: 
             Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Listing all triggers associated with a certain table:

 
```
SHOW TRIGGERS FROM test WHERE `Table` = 'user' \G
*************************** 1. row ***************************
             Trigger: user_ai
               Event: INSERT
               Table: user
           Statement: BEGIN END
              Timing: AFTER
             Created:  2016-09-29 13:53:34.35
            sql_mode: 
             Definer: root@%
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```


```
SHOW triggers WHERE Event Like 'Insert' \G
*************************** 1. row ***************************
             Trigger: the_mooses_are_loose
               Event: INSERT
               Table: animals
           Statement: BEGIN
 IF NEW.name = 'Moose' THEN
  UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END
              Timing: AFTER
             Created: 2016-09-29 13:53:34.35
            sql_mode: 
             Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

* `character_set_client` is the session value of the `[character\_set\_client](../server-system-variables/index#character_set_client)` system variable when the trigger was created.
* `collation_connection` is the session value of the `[collation\_connection](../server-system-variables/index#collation_connection)` system variable when the trigger was created.
* `Database Collation` is the collation of the database with which the trigger is associated.

 These columns were added in MariaDB/MySQL 5.1.21.

 Old triggers created before MySQL 5.7 and [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) has NULL in the `Created` column.

 See also
--------

 * [Trigger Overview](../trigger-overview/index)
* `[CREATE TRIGGER](../create-trigger/index)`
* `[DROP TRIGGER](../drop-trigger/index)`
* `[information\_schema.TRIGGERS](../information-schema-triggers-table/index)` table
* `[SHOW CREATE TRIGGER](../show-create-trigger/index)`
* [Trigger Limitations](../trigger-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-triggers/>

SHOW USER\_STATISTICS
=====================

    Syntax
------

 
```
SHOW USER_STATISTICS

```

Description
-----------

 The `SHOW USER_STATISTICS` statement is part of the [User Statistics](../user-statistics/index) feature. It was removed as a separate statement in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), but effectively replaced by the generic [SHOW information\_schema\_table](../information-schema-plugins-show-and-flush-statements/index) statement. The [information\_schema.USER\_STATISTICS](../information-schema-user_statistics-table/index) table holds statistics about user activity. You can use this table to find out such things as which user is causing the most load and which users are being abusive. You can also use this table to measure how close to capacity the server may be.

 The [userstat](../server-system-variables/index#userstat) system variable must be set to 1 to activate this feature. See the [User Statistics](../user-statistics/index) and [information\_schema.USER\_STATISTICS](../information-schema-user_statistics-table/index) table for more information.

 Example
-------

 
```
SHOW USER_STATISTICS\G
*************************** 1. row ***************************
                  User: root
     Total_connections: 1
Concurrent_connections: 0
        Connected_time: 3297
             Busy_time: 0.14113400000000006
              Cpu_time: 0.017637000000000003
        Bytes_received: 969
            Bytes_sent: 22355
  Binlog_bytes_written: 0
             Rows_read: 10
             Rows_sent: 67
          Rows_deleted: 0
         Rows_inserted: 0
          Rows_updated: 0
       Select_commands: 7
       Update_commands: 0
        Other_commands: 0
   Commit_transactions: 1
 Rollback_transactions: 0
    Denied_connections: 0
      Lost_connections: 0
         Access_denied: 0
         Empty_queries: 7

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-user_statistics/>

Index Condition Pushdown
========================

    Index Condition Pushdown is an optimization that is applied for access methods that access table data through indexes: `range`, `ref`, `eq_ref`, `ref_or_null`, and [Batched Key Access](../block-based-join-algorithms/index#batch-key-access-join).

 The idea is to check part of the WHERE condition that refers to index fields (we call it *Pushed Index Condition*) as soon as we've accessed the index. If the *Pushed Index Condition* is not satisfied, we won't need to read the whole table record.

 Index Condition Pushdown is **on** by default. To disable it, set its optimizer\_switch flag like so:

 
```
SET optimizer_switch='index_condition_pushdown=off'

```

When Index Condition Pushdown is used, EXPLAIN will show "Using index condition":

 
```
MariaDB [test]> explain select * from tbl where key_col1 between 10 and 11 and key_col2 like '%foo%';
+----+-------------+-------+-------+---------------+----------+---------+------+------+-----------------------+
| id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows | Extra                 |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-----------------------+
|  1 | SIMPLE      | tbl   | range | key_col1      | key_col1 | 5       | NULL |    2 | Using index condition |
+----+-------------+-------+-------+---------------+----------+---------+------+------+-----------------------+

```

The Idea Behind Index Condition Pushdown
----------------------------------------

 In disk-based storage engines, making an index lookup is done in two steps, like shown on the picture:

 ![index-access-2phases]

 Index Condition Pushdown optimization tries to cut down the number of full record reads by checking whether index records satisfy part of the WHERE condition that can be checked for them:

 ![index-access-with-icp]

 How much speed will be gained depends on - How many records will be filtered out - How expensive it was to read them

 The former depends on the query and the dataset. The latter is generally bigger when table records are on disk and/or are big, especially when they have [blobs](../blob/index).

 Example Speedup
---------------

 I used DBT-3 benchmark data, with scale factor=1. Since the benchmark defines very few indexes, we've added a multi-column index (index condition pushdown is usually useful with multi-column indexes: the first component(s) is what index access is done for, the subsequent have columns that we read and check conditions on).

 
```
alter table lineitem add index s_r (l_shipdate, l_receiptdate);

```

The query was to find big (l\_quantity > 40) orders that were made in January 1993 that took more than 25 days to ship:

 
```
select count(*) from lineitem
where
  l_shipdate between '1993-01-01' and '1993-02-01' and
  datediff(l_receiptdate,l_shipdate) > 25 and
  l_quantity > 40;

```

EXPLAIN without Index Condition Pushdown:

 
```
-+----------+-------+----------------------+-----+---------+------+--------+-------------+
 | table    | type | possible_keys         | key | key_len | ref | rows    | Extra       |
-+----------+-------+----------------------+-----+---------+------+--------+-------------+
 | lineitem | range | s_r                  | s_r | 4       | NULL | 152064 | Using where |
-+----------+-------+----------------------+-----+---------+------+--------+-------------+

```

with Index Condition Pushdown:

 
```
-+-----------+-------+---------------+-----+---------+------+--------+------------------------------------+
 | table     | type | possible_keys | key | key_len | ref | rows     | Extra                              |
-+-----------+-------+---------------+-----+---------+------+--------+------------------------------------+
 | lineitem | range | s_r            | s_r | 4       | NULL | 152064 | Using index condition; Using where |
-+-----------+-------+---------------+-----+---------+------+--------+------------------------------------+

```

The speedup was:

 * Cold buffer pool: from 5 min down to 1 min
* Hot buffer pool: from 0.19 sec down to 0.07 sec

 Status Variables
----------------

 There are two server status variables:

 


| Variable name | Meaning |
| --- | --- |
| [Handler\_icp\_attempts](../server-status-variables/index#handler_icp_attempts) | Number of times pushed index condition was checked. |
| [Handler\_icp\_match](../server-status-variables/index#handler_icp_match) | Number of times the condition was matched. |

 
That way, the value `Handler_icp_attempts - Handler_icp_match` shows the number records that the server did not have to read because of Index Condition Pushdown.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [Index Condition Pushdown](http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html) in MySQL 5.6 manual (MariaDB's and MySQL 5.6's Index Condition Pushdown implementations have the same ancestry so are very similar to one another).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/index-condition-pushdown/>

ORDER BY
========

    Description
-----------

 Use the `ORDER BY` clause to order a resultset, such as that are returned from a [SELECT](../select/index) statement. You can specify just a column or use any expression with functions. If you are using the `GROUP BY` clause, you can use grouping functions in `ORDER BY`. Ordering is done after grouping.

 You can use multiple ordering expressions, separated by commas. Rows will be sorted by the first expression, then by the second expression if they have the same value for the first, and so on.

 You can use the keywords `ASC` and `DESC` after each ordering expression to force that ordering to be ascending or descending, respectively. Ordering is ascending by default.

 You can also use a single integer as the ordering expression. If you use an integer *n*, the results will be ordered by the *n*th column in the select expression.

 When string values are compared, they are compared as if by the [STRCMP](../strcmp/index) function. `STRCMP` ignores trailing whitespace and may normalize characters and ignore case, depending on the [collation](../data-types-character-sets-and-collations/index) in use.

 Duplicated entries in the `ORDER BY` clause are removed.

 `ORDER BY` can also be used to order the activities of a [DELETE](../delete/index) or [UPDATE](../update/index) statement (usually with the [LIMIT](../limit/index) clause). 

 
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), it was not possible to use `ORDER BY` (or [LIMIT](../limit/index)) in a multi-table [UPDATE](../update/index) statement. This restriction was lifted in [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/).

 

**MariaDB starting with [10.5](../what-is-mariadb-105/index)**From [MariaDB 10.5](../what-is-mariadb-105/index), MariaDB allows packed sort keys and values of non-sorted fields in the sort buffer. This can make filesort temporary files much smaller when VARCHAR, CHAR or BLOBs are used, notably speeding up some ORDER BY sorts.

 
Examples
--------

 
```
CREATE TABLE seq (i INT, x VARCHAR(1));
INSERT INTO seq VALUES (1,'a'), (2,'b'), (3,'b'), (4,'f'), (5,'e');

SELECT * FROM seq ORDER BY i;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | b    |
|    4 | f    |
|    5 | e    |
+------+------+

SELECT * FROM seq ORDER BY i DESC;
+------+------+
| i    | x    |
+------+------+
|    5 | e    |
|    4 | f    |
|    3 | b    |
|    2 | b    |
|    1 | a    |
+------+------+

SELECT * FROM seq ORDER BY x,i;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | b    |
|    5 | e    |
|    4 | f    |
+------+------+

```

ORDER BY in an [UPDATE](../update/index) statement, in conjunction with [LIMIT](../limit/index):

 
```
UPDATE seq SET x='z' WHERE x='b' ORDER BY i DESC LIMIT 1;

SELECT * FROM seq;
+------+------+
| i    | x    |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | z    |
|    4 | f    |
|    5 | e    |
+------+------+

```

From [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), `ORDER BY` can be used in a multi-table update:

 
```
CREATE TABLE warehouse (product_id INT, qty INT);
INSERT INTO warehouse VALUES (1,100),(2,100),(3,100),(4,100);

CREATE TABLE store (product_id INT, qty INT);
INSERT INTO store VALUES (1,5),(2,5),(3,5),(4,5);

UPDATE warehouse,store SET warehouse.qty = warehouse.qty-2, store.qty = store.qty+2 
  WHERE (warehouse.product_id = store.product_id AND store.product_id  >= 1) 
    ORDER BY store.product_id DESC LIMIT 2;

SELECT * FROM warehouse;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |  100 |
|          2 |  100 |
|          3 |   98 |
|          4 |   98 |
+------------+------+

SELECT * FROM store;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |    5 |
|          2 |    5 |
|          3 |    7 |
|          4 |    7 |
+------------+------+

```

See Also
--------

 * [Why is ORDER BY in a FROM subquery ignored?](../why-is-order-by-in-a-from-subquery-ignored/index)
* [SELECT](../select/index)
* [UPDATE](../update/index)
* [DELETE](../delete/index)
* [Improvements to ORDER BY Optimization](../improvements-to-order-by/index)
* [Joins and Subqueries](../joins-subqueries/index)
* [LIMIT](../limit/index)
* [GROUP BY](../group-by/index)
* [Common Table Expressions](../common-table-expressions/index)
* [SELECT WITH ROLLUP](../select-with-rollup/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* [FOR UPDATE](../for-update/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [Optimizer Hints](../optimizer-hints/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/order-by/>

Optimizing key\_buffer\_size
============================

    [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) is a [MyISAM](../myisam/index) variable which determines the size of the index buffers held in memory, which affects the speed of index reads. Note that Aria tables by default make use of an alternative setting, [aria-pagecache-buffer-size](../aria-server-system-variables/index#aria_pagecache_buffer_size).

 A good rule of thumb for servers consisting particularly of MyISAM tables is for about 25% or more of the available server memory to be dedicated to the key buffer.

 A good way to determine whether to adjust the value is to compare the [key\_read\_requests](../server-status-variables/index#key_read_requests) value, which is the total value of requests to read an index, and the [key\_reads](../server-status-variables/index#key_reads) values, the total number of requests that had to be read from disk.

 The ratio of key\_reads to key\_read\_requests should be as low as possible, 1:100 is the highest acceptable, 1:1000 is better, and 1:10 is terrible.

 The effective maximum size might be lower than what is set, depending on the server's available physical RAM and the per-process limit determined by the operating system.

 If you don't make use of MyISAM tables at all, you can set this to a very low value, such as 64K.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-key_buffer_size/>

Filesort with Small LIMIT Optimization
======================================

    Optimization Description
------------------------

 When `n` is sufficiently small, the optimizer will use a [priority queue](http://en.wikipedia.org/wiki/Priority_queue) for sorting. Before the optimization's porting to [MariaDB 10.0](../what-is-mariadb-100/index), the alternative was, roughly speaking, to sort the entire output and then pick only first `n` rows.

 Optimization Visibility in MariaDB
----------------------------------

 There are two ways to check whether filesort has used a priority queue.

 ### Status Variable

 The first way is to check the [Sort\_priority\_queue\_sorts](../server-status-variables/index#sort_priority_queue_sorts) status variable. It shows the number of times that sorting was done through a priority queue. (The total number of times sorting was done is a sum [Sort\_range](../server-status-variables/index#sort_range) and [Sort\_scan](../server-status-variables/index#sort_scan)).

 ### Slow Query Log

 The second way is to check the slow query log. When one uses [Extended statistics in the slow query log](../slow-query-log-extended-statistics/index) and specifies [log\_slow\_verbosity=query\_plan](../server-system-variables/index#log_slow_verbosity), [slow query log](../slow-query-log/index) entries look like this

 
```
# Time: 140714 18:30:39
# User@Host: root[root] @ localhost []
# Thread_id: 3  Schema: test  QC_hit: No
# Query_time: 0.053857  Lock_time: 0.000188  Rows_sent: 11  Rows_examined: 100011
# Full_scan: Yes  Full_join: No  Tmp_table: No  Tmp_table_on_disk: No
# Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0  Priority_queue: Yes
SET timestamp=1405348239;SET timestamp=1405348239;
select * from t1 where col1 between 10 and 20 order by col2 limit 100;

```

Note the "Priority\_queue: Yes" on the last comment line. (`pt-query-digest` is able to parse slow query logs with the Priority\_queue field)

 As for `EXPLAIN`, it will give no indication whether filesort uses priority queue or the generic quicksort and merge algorithm. `Using filesort` will be shown in both cases, by both MariaDB and MySQL.

 See Also
--------

 * [LIMIT Optimization](http://dev.mysql.com/doc/refman/5.6/en/limit-optimization.html) page in the MySQL 5.6 manual (search for "priority queue").
* MySQL WorkLog entry, [WL#1393](http://dev.mysql.com/worklog/task/?id=1393)
* [MDEV-415](https://jira.mariadb.org/browse/MDEV-415), [MDEV-6430](https://jira.mariadb.org/browse/MDEV-6430)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/filesort-with-small-limit-optimization/>

Subquery Cache
==============

     The goal of the subquery cache is to optimize the evaluation of correlated subqueries by storing results together with correlation parameters in a cache and avoiding re-execution of the subquery in cases where the result is already in the cache.

 Administration
--------------

 The cache is on by default. One can switch it off using the [optimizer\_switch](../server-system-variables/index#optimizer_switch) `subquery_cache` setting, like so:

 
```
SET optimizer_switch='subquery_cache=off';

```

The efficiency of the subquery cache is visible in 2 statistical variables:

 * [Subquery\_cache\_hit](../server-status-variables/index#subquery_cache_hit) - Global counter for all subquery cache hits.
* [Subquery\_cache\_miss](../server-status-variables/index#subquery_cache_miss) - Global counter for all subquery cache misses.

 The session variables [tmp\_table\_size](../server-system-variables/index#tmp_table_size) and [max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size) influence the size of in-memory temporary tables in the table used for caching. It cannot grow more than the minimum of the above variables values (see the [Implementation](#implementation) section for details).

 Visibility
----------

 Your usage of the cache is visible in `EXTENDED EXPLAIN` output (warnings) as `"<expr_cache><//list of parameters//>(//cached expression//)"`. For example:

 
```
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (SELECT b FROM t2);
+----+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type        | table | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | PRIMARY            | t1    | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | Using where |
|  2 | DEPENDENT SUBQUERY | t2    | ALL  | NULL          | NULL | NULL    | NULL |    2 |   100.00 | Using where |
+----+--------------------+-------+------+---------------+------+---------+------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)

SHOW WARNINGS;
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message                                                                                                                                                                                                    |
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Note  | 1003 | SELECT `test`.`t1`.`a` AS `a` from `test`.`t1` WHERE <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(SELECT 1 FROM `test`.`t2` WHERE (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`b`)))) |
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

```

In the example above the presence of `"<expr_cache><`test`.`t1`.`a`>(...)"` is how you know you are using the subquery cache.

 Implementation
--------------

 Every subquery cache creates a temporary table where the results and all parameters are stored. It has a unique index over all parameters. First the cache is created in a [MEMORY](../memory-storage-engine/index) table (if doing this is impossible the cache becomes disabled for that expression). When the table grows up to the minimum of `tmp_table_size` and `max_heap_table_size`, the hit rate will be checked:

 * if the hit rate is really small (<0.2) the cache will be disabled.
* if the hit rate is moderate (<0.7) the table will be cleaned (all records deleted) to keep the table in memory
* if the hit rate is high the table will be converted to a disk table (for 5.3.0 it can only be converted to a disk table).

 
```
hit rate = hit / (hit + miss)

```

Performance Impact
------------------

 Here are some examples that show the performance impact of the subquery cache (these tests were made on a 2.53 GHz Intel Core 2 Duo MacBook Pro with dbt-3 scale 1 data set).

 


| example | cache on | cache off | gain | hit | miss | hit rate |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | 1.01sec | 1 hour 31 min 43.33sec | 5445x | 149975 | 25 | 99.98% |
| 2 | 0.21sec | 1.41sec | 6.71x | 6285 | 220 | 96.6% |
| 3 | 2.54sec | 2.55sec | 1.00044x | 151 | 461 | 24.67% |
| 4 | 1.87sec | 1.95sec | 0.96x | 0 | 23026 | 0% |

 
### Example 1

 Dataset from DBT-3 benchmark, a query to find customers with balance near top in their nation:

 
```
select count(*) from customer 
where 
   c_acctbal > 0.8 * (select max(c_acctbal) 
                      from customer C 
                      where C.c_nationkey=customer.c_nationkey
                      group by c_nationkey);

```

### Example 2

 DBT-3 benchmark, Query #17

 
```
select sum(l_extendedprice) / 7.0 as avg_yearly 
from lineitem, part 
where 
  p_partkey = l_partkey and 
  p_brand = 'Brand#42' and p_container = 'JUMBO BAG' and 
  l_quantity < (select 0.2 * avg(l_quantity) from lineitem 
                where l_partkey = p_partkey);

```

### Example 3

 DBT-3 benchmark, Query #2

 
```
select
        s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment
from
        part, supplier, partsupp, nation, region
where
        p_partkey = ps_partkey and s_suppkey = ps_suppkey and p_size = 33
        and p_type like '%STEEL' and s_nationkey = n_nationkey
        and n_regionkey = r_regionkey and r_name = 'MIDDLE EAST'
        and ps_supplycost = (
                select
                        min(ps_supplycost)
                from
                        partsupp, supplier, nation, region
                where
                        p_partkey = ps_partkey and s_suppkey = ps_suppkey
                        and s_nationkey = n_nationkey and n_regionkey = r_regionkey
                        and r_name = 'MIDDLE EAST'
        )
order by
        s_acctbal desc, n_name, s_name, p_partkey;

```

### Example 4

 DBT-3 benchmark, Query #20

 
```
select
        s_name, s_address
from
        supplier, nation
where
        s_suppkey in (
                select
                        distinct (ps_suppkey)
                from
                        partsupp, part
                where
                        ps_partkey=p_partkey
                        and p_name like 'indian%'
                        and ps_availqty > (
                                select
                                        0.5 * sum(l_quantity)
                                from
                                        lineitem
                                where
                                        l_partkey = ps_partkey
                                        and l_suppkey = ps_suppkey
                                        and l_shipdate >= '1995-01-01'
                                        and l_shipdate < date_ADD('1995-01-01',interval 1 year)
                                )
        )
        and s_nationkey = n_nationkey and n_name = 'JAPAN'
order by
        s_name;

```

See Also
--------

 * [Query cache](../query-cache/index)
* <http://mysqlmaniac.com/2012/what-about-the-subqueries/> blog post describing impact of subquery cache optimization on queries used by DynamicPageList MediaWiki extension
* <http://varokism.blogspot.ru/2013/06/mariadb-subquery-cache-in-real-use-case.html> Another use case from the real world
* [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subquery-cache/>

Thread Pool in MariaDB
======================

    Problem That Thread Pools Solve
-------------------------------

 The task of scalable server software (and a DBMS like MariaDB is an example of such software) is to maintain top performance with an increasing number of clients. MySQL traditionally assigned a thread for every client connection, and as the number of concurrent users grows this model shows performance drops. Many active threads are a performance killer, because increasing the number of threads leads to extensive context switching, bad locality for CPU caches, and increased contention for hot locks. An ideal solution that would help to reduce context switching is to maintain a lower number of threads than the number of clients. But this number should not be too low either, since we also want to utilize CPUs to their fullest, so ideally, there should be a single active thread for each CPU on the machine.

 MariaDB Thread Pool Features
----------------------------

 The current MariaDB thread pool was implemented in [MariaDB 5.5](../what-is-mariadb-55/index). It replaced the legacy thread pool that was introduced in [MariaDB 5.1](../what-is-mariadb-51/index). The main drawback of the previous solution was that this pool was static–it had a fixed number of threads. Static thread pools can have their merits, for some limited use cases, such as cases where callbacks executed by the threads never block and do not depend on each other. For example, iimagine something like an echo server.

 However, DBMS clients are more complicated. For example, a thread may depend on another thread's completion, and they may block each other via locks and/or I/O. Thus it is very hard, and sometimes impossible, to predict how many threads would be ideal or even sufficient to prevent deadlocks in every situation. [MariaDB 5.5](../what-is-mariadb-55/index) implements a dynamic/adaptive pool that itself takes care of creating new threads in times of high demand and retiring threads if they have nothing to do. This is a complete reimplementation of the legacy `pool-of-threads` scheduler, with the following goals:

 * Make the pool dynamic, so that it will grow and shrink whenever required.
* Minimize the amount of overhead that is required to maintain the thread pool itself.
* Make the best use of underlying OS capabilities. For example, if a native thread pool implementation is available, then it should be used, and if not, then the best I/O multiplexing method should be used.
* Limit the resources used by threads.

 There are currently two different low-level implementations – depending on OS. One implementation is designed specifically for Windows which utilizes a native `[CreateThreadpool](https://docs.microsoft.com/en-us/windows/desktop/api/threadpoolapiset/nf-threadpoolapiset-createthreadpool)` API. The second implementation is primarily intended to be used in Unix-like systems. Because the implementations are different, some system variables differ between Windows and Unix.

 When to Use the Thread Pool
---------------------------

 Thread pools are most efficient in situations where queries are relatively short and the load is CPU-bound, such as in OLTP workloads. If the workload is not CPU-bound, then you might still benefit from limiting the number of threads to save memory for the database memory buffers.

 When the Thread Pool is Less Efficient
--------------------------------------

 There are special, rare cases where the thread pool is likely to be less efficient.

 * If you have a **very bursty workload**, then the thread pool may not work well for you. These tend to be workloads in which there are long periods of inactivity followed by short periods of very high activity by many users. These also tend to be workloads in which delays cannot be tolerated, so the throttling of thread creation that the thread pool uses is not ideal. Even in this situation, performance can be improved by tweaking how often threads are retired. For example, with `[thread\_pool\_idle\_timeout](../thread-pool-system-and-status-variables/index#thread_pool_idle_timeout)` on Unix, or with `[thread\_pool\_min\_threads](../thread-pool-system-and-status-variables/index#thread_pool_min_threads)` on Windows.

 * If you have **many concurrent, long, non-yielding** queries, then the thread pool may not work well for you. In this context, a "non-yielding" query is one that never waits or which does not indicate waits to the thread pool. These kinds of workloads are mostly used in data warehouse scenarios. Long-running, non-yielding queries will delay execution of other queries. However, the thread pool has stall detection to prevent them from totally monopolizing the thread pool. See [Thread Groups in the Unix Implementation of the Thread Pool: Thread Group Stalls](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-group-stalls) for more information. Even when the whole thread pool is blocked by non-yielding queries, you can still connect to the server through the `[extra-port](../thread-pool-system-and-status-variables/index#extra_port)` TCP/IP port.

 * If you rely on the fact that **simple queries always finish quickly**, no matter how loaded your database server is, then the thread pool may not work well for you. When the thread pool is enabled on a busy server, even simple queries might be queued to be executed later. This means that even if the statement itself doesn't take much time to execute, even a simple `SELECT 1`, might take a bit longer when the thread pool is enabled than with `one-thread-per-connection` if it gets queued.

 Configuring the Thread Pool
---------------------------

 The `[thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling)` system variable is the primary system variable that is used to configure the thread pool.

 There are several other system variables as well, which are described in the sections below. Many of the system variables documented below are dynamic, meaning that they can be changed with `[SET GLOBAL](../set/index#global-session)` on a running server. 

 Generally, there is no need to tweak many of these system variables. The goal of the thread pool was to provide good performance out-of-the box. However, the system variable values can be changed, and we intended to expose as many knobs from the underlying implementation as we could. Feel free to tweak them as you see fit.

 If you find any issues with any of the default behavior, then we encourage you to [submit a bug report](../reporting-bugs/index). 

 See [Thread Pool System and Status Variables](../thread-pool-system-status-variables/index) for the full list of the thread pool's system variables.

 ### Configuring the Thread Pool on Unix

 On Unix, if you would like to use the thread pool, then you can use the thread pool by setting the `[thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling)` system variable to `pool-of-threads` in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
thread_handling=pool-of-threads

```

The following system variables can also be configured on Unix:

 * `[thread\_pool\_size](../thread-pool-system-and-status-variables/index#thread_pool_size)` – The number of [thread groups](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) in the thread pool, which determines how many statements can execute simultaneously. The default value is the number of CPUs on the system. When setting this system variable's value at system startup, the max value is 100000. However, it is not a good idea to set it that high. When setting this system variable's value dynamically, the max value is either 128 or the value that was set at system startup--whichever value is higher. See [Thread Groups in the Unix Implementation of the Thread Pool](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) for more information.

 * `[thread\_pool\_max\_threads](../thread-pool-system-and-status-variables/index#thread_pool_max_threads)` – The maximum number of threads in the thread pool. Once this limit is reached, no new threads will be created in most cases. In rare cases, the actual number of threads can slightly exceed this, because each [thread group](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) needs at least two threads (i.e. at least one worker thread and at least one listener thread) to prevent deadlocks. The default value in [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.0](../what-is-mariadb-100/index) is `500`. The default value in [MariaDB 10.1](../what-is-mariadb-101/index) is `1000` in [MariaDB 10.1](../what-is-mariadb-101/index). The default value in [MariaDB 10.2](../what-is-mariadb-102/index) and later is `65536`.

 * `[thread\_pool\_stall\_limit](../thread-pool-system-and-status-variables/index#thread_pool_stall_limit)` – The number of milliseconds between each stall check performed by the timer thread. The default value is `500`. Stall detection is used to prevent a single client connection from monopolizing a thread group. When the timer thread detects that a thread group is stalled, it wakes up a sleeping worker thread in the thread group, if one is available. If there isn't one, then it creates a new worker thread in the thread group. This temporarily allows several client connections in the thread group to run in parallel. However, note that the timer thread will not create a new worker thread if the number of threads in the thread pool is already greater than or equal to the maximum defined by the `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)` variable, unless the thread group does not already have a listener thread. See [Thread Groups in the Unix Implementation of the Thread Pool: Thread Group Stalls](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-group-stalls) for more information.

 * `[thread\_pool\_oversubscribe](../thread-pool-system-and-status-variables/index#thread_pool_oversubscribe)` – Determines how many worker threads in a thread group can remain active at the same time once a thread group is oversubscribed due to stalls. The default value is `3`. Usually, a thread group only has one active worker thread at a time. However, the timer thread can add more active worker threads to a thread group if it detects a stall. There are trade-offs to consider when deciding whether to allow **only one** thread per CPU to run at a time, or whether to allow **more than one** thread per CPU to run at a time. Allowing only one thread per CPU means that the thread can have unrestricted access to the CPU while its running, but it also means that there is additional overhead from putting threads to sleep or waking them up more frequently. Allowing more than one thread per CPU means that the threads have to share the CPU, but it also means that there is less overhead from putting threads to sleep or waking them up. This is primarily for **internal** use, and it is **not** meant to be changed for most users. See [Thread Groups in the Unix Implementation of the Thread Pool: Thread Group Oversubscription](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-group-oversubscription) for more information.

 * `[thread\_pool\_idle\_timeout](../thread-pool-system-and-status-variables/index#thread_pool_idle_timeout)` – The number of seconds before an idle worker thread exits. The default value is `60`. If there is currently no work to do, how long should an idle thread wait before exiting?

 ### Configuring the Thread Pool on Windows

 The Windows implementation of the thread pool uses a native thread pool created with the `[CreateThreadpool](https://docs.microsoft.com/en-us/windows/desktop/api/threadpoolapiset/nf-threadpoolapiset-createthreadpool)` API.

 On Windows, if you would like to use the thread pool, then you do not need to do anything, because the default for the `[thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling)` system variable is already preset to `pool-of-threads`. 

 However, if you would like to use the old one thread per-connection behavior on Windows, then you can use use that by setting the `[thread\_handling](../thread-pool-system-and-status-variables/index#thread_handling)` system variable to `one-thread-per-connection` in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
thread_handling=one-thread-per-connection

```


On older versions of Windows, such as XP and 2003, `pool-of-threads` is not implemented, and the server will silently switch to using the legacy `one-thread-per-connection` method.

 
The native `[CreateThreadpool](https://docs.microsoft.com/en-us/windows/desktop/api/threadpoolapiset/nf-threadpoolapiset-createthreadpool)` API allows applications to set the minimum and maximum number of threads in the pool. The following system variables can be used to configure those values on Windows:

 * `[thread\_pool\_min\_threads](../thread-pool-system-and-status-variables/index#thread_pool_min_threads)` – The minimum number of threads in the pool. Default is 1. This applicable in a special case of very “bursty” workloads. Imagine having longer periods of inactivity after periods of high activity. While the thread pool is idle, Windows would decide to retire pool threads (based on experimentation, this seems to happen after thread had been idle for 1 minute). Next time high load comes, it could take some milliseconds or seconds until the thread pool size stabilizes again to optimal value. To avoid thread retirement, one could set the parameter to a higher value.

 * `[thread\_pool\_max\_threads](../thread-pool-system-and-status-variables/index#thread_pool_max_threads)` – The maximum number of threads in the pool. Threads are not created when this value is reached. The default from [MariaDB 5.5](../what-is-mariadb-55/index) to [MariaDB 10.0](../what-is-mariadb-100/index) is 500 (this has been increased to 1000 in [MariaDB 10.1](../what-is-mariadb-101/index)). This parameter can be used to prevent the creation of new threads if the pool can have short periods where many or all clients are blocked (for example, with “FLUSH TABLES WITH READ LOCK”, high contention on row locks, or similar). New threads are created if a blocking situation occurs (such as after a throttling interval), but sometimes you want to cap the number of threads, if you’re familiar with the application and need to, for example, save memory. If your application constantly pegs at 500 threads, it might be a strong indicator for high contention in the application, and the thread pool does not help much.

 ### Configuring Priority Scheduling

 Starting with [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), it is possible to configure connection prioritization. The priority behavior is configured by the `[thread\_pool\_priority](../thread-pool-system-and-status-variables/index#thread_pool_priority)` system variable.

 By default, if `[thread\_pool\_priority](../thread-pool-system-and-status-variables/index#thread_pool_priority)` is set to `auto`, then queries would be given a higher priority, in case the current connection is inside a transaction. This allows the running transaction to finish faster, and has the effect of lowering the number of transactions running in parallel. The default setting will generally improve throughput for transactional workloads. But it is also possible to explicitly set the priority for the current connection to either 'high' or 'low'.

 There is also a mechanism in place to ensure that higher priority connections are not monopolizing the worker threads in the pool (which would cause indefinite delays for low priority connections). On Unix, low priority connections are put into the high priority queue after the timeout specified by the `[thread\_pool\_prio\_kickup\_timer](../thread-pool-system-and-status-variables/index#thread_pool_prio_kickup_timer)` system variable. 

 ### Configuring the Extra Port

 MariaDB allows you to configure an extra port for administrative connections. This is primarily intended to be used in situations where all threads in the thread pool are blocked, and you still need a way to access the server. However, it can also be used to ensure that monitoring systems (including MaxScale's monitors) always have access to the system, even when all connections on the main port are used. This extra port uses the old `one-thread-per-connection` thread handling.

 You can enable this and configure a specific port by setting the `[extra\_port](../thread-pool-system-status-variables/index#extra_port)` system variable.

 You can configure a specific number of connections for this port by setting the `[extra\_max\_connections](../thread-pool-system-status-variables/index#extra_max_connections)` system variable.

 These system variables can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
extra_port = 8385
extra_max_connections = 10

```

Once you have the extra port configured, you can use the [mariadb](../mariadb-command-line-client/index) client with the `-P` option to connect to the port.

 
```
$ mariadb -u root -P 8385 -p

```

Monitoring Thread Pool Activity
-------------------------------

 Currently there are two status variables exposed to monitor pool activity.

 


| Variable | Description |
| --- | --- |
| `[Threadpool\_threads](../thread-pool-system-and-status-variables/index#threadpool_threads)` | Number of threads in the thread pool. In rare cases, this can be slightly higher than `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)`, because each thread group needs at least two threads (i.e. at least one worker thread and at least one listener thread) to prevent deadlocks. |
| `[Threadpool\_idle\_threads](../thread-pool-system-and-status-variables/index#threadpool_idle_threads)` | Number of inactive threads in the thread pool. Threads become inactive for various reasons, such as by waiting for new work. However, an inactive thread is not necessarily one that has not been assigned work. Threads are also considered inactive if they are being blocked while waiting on disk I/O, or while waiting on a lock, etc. This status variable is only meaningful on **Unix**. |

 
Thread Groups in the Unix Implementation of the Thread Pool
-----------------------------------------------------------

 On Unix, the thread pool implementation uses objects called thread groups to divide up client connections into many independent sets of threads. See [Thread Groups in the Unix Implementation of the Thread Pool](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) for more information.

 Fixing a Blocked Thread Pool
----------------------------

 When using global locks, even with a high value on the [thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads) system variable, it is still possible to block the entire pool. 

 Imagine the case where a client performs [FLUSH TABLES WITH READ LOCK](../flush/index) then pauses. If then the number of other clients connecting to the server to start write operations exceeds the maximum number of threads allowed in the pool, it can block the Server. This makes it impossible to issue the [UNLOCK TABLES](lock-and-unlock-tables) statement. It can also block MaxScale from monitoring the Server.

 To mitigate the issue, MariaDB allows you to configure an extra port for administrative connections. See [Configuring the Extra Port](#configuring-the-extra-port) for information on how to configure this.

 Once you have the extra port configured, you can use the [mariadb](../mariadb-command-line-client/index) client with the `-P` option to connect to the port.

 
```
$ mariadb -u root -P 8385 -p

```

This ensures that your administrators can access the server in cases where the number of threads is already equal to the configured value of the [thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads) system variable, and all threads are blocked. It also ensures that MaxScale can still access the server in such situations for monitoring information.

 Once you are connected to the extra port, you can solve the issue by increasing the value on the [thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads) system variable, or by killing the offending connection, (that is, the connection that holds the global lock, which would be in the `sleep` state).

 MariaDB Thread Pool vs Oracle MySQL Enterprise Thread Pool
----------------------------------------------------------

 Commercial editions of MySQL since 5.5 include an Oracle MySQL Enterprise thread pool implemented as a plugin, which delivers similar functionality. A detailed discussion about the design of the feature is at [Mikael Ronstrom's blog](http://mikaelronstrom.blogspot.com/2011/10/mysql-thread-pool-summary.html). Here is the summary of similarities and differences, based on the above materials.

 ### Similarities

 * On Unix, both MariaDB and Oracle MySQL Enterprise Threadpool will partition client connections into groups. The [thread\_pool\_size](../thread-pool-system-and-status-variables/index#thread_pool_size) parameter thus has the same meaning for both MySQL and MariaDB.

 * Both implementations use similar schema checking for thread stalls, and both have the same parameter name for [thread\_pool\_stall\_limit](../thread-pool-system-and-status-variables/index#thread_pool_stall_limit) (though in MariaDB it is measured using millisecond units, not 10ms units like in Oracle MySQL).

 ### Differences

 * The Windows implementation is completely different – MariaDB's uses native Windows threadpooling, while Oracle's implementation includes a convenience function *WSAPoll()* (provided for convenience to port Unix applications). As a consequence of relying on *WSAPoll()*, Oracle's implementation will not work with named pipes and shared memory connections.

 * MariaDB uses the most efficient I/O multiplexing facilities for each operating system: Windows (the I/O completion port is used internally by the native threadpool), Linux (epoll), Solaris (event ports), FreeBSD and OSX (kevent). Oracle uses optimized I/O multiplexing only on Linux, with epoll, and uses poll() otherwise.

 * Unlike Oracle MySQL Enterprise Threadpool, MariaDB's one is builtin, not a plugin.

 MariaDB Thread Pool vs Percona Thread Pool
------------------------------------------

 [Percona's implementation](https://www.percona.com/doc/percona-server/5.7/performance/threadpool.html) is a port of the MariaDB's threadpool with some added features. In particular, Percona added priority scheduling to its 5.5-5.7 releases. [MariaDB 10.2](../what-is-mariadb-102/index) and Percona priority scheduling work in a similar fashion, but there are some differences in details.

 * MariaDB's 10.2 thread\_pool\_priority=auto,high, low correspond to Percona's thread\_pool\_high\_prio\_mode=transactions,statements,none
* Percona has a thread\_pool\_high\_prio\_tickets connection variable to allow every nth low priority query to be put into the high priority queue. MariaDB does not have corresponding settings.
* MariaDB has a thread\_pool\_prio\_kickup\_timer setting, which Percona does not have.

 Thread Pool Internals
---------------------

 Low-level implementation details are documented in the [WL#246](https://web.archive.org/web/20160526152157/http://worklog.askmonty.org/worklog/Server-BackLog/?tid=246)

 Running Benchmarks
------------------

 When running sysbench and maybe other benchmarks, that create many threads on the same machine as the server, it is advisable to run benchmark driver and server on different CPUs to get the realistic results. Running lots of driver threads and only several server threads on the same CPUs will have the effect that OS scheduler will schedule benchmark driver threads to run with much higher probability than the server threads, that is driver will pre-empt the server. Use "taskset –c" on Linuxes, and "set /affinity" on Windows to separate benchmark driver and server CPUs, as the preferred method to fix this situation.

 A possible alternative on Unix (if taskset or a separate machine running the benchmark is not desired for some reason) would be to increase thread\_pool\_size to make the server threads more "competitive" against the client threads.

 When running sysbench, a good rule of thumb could be to give 1/4 of all CPUs to the sysbench, and 3/4 of CPUs to mysqld. It is also good idea to run sysbench and mysqld on different NUMA nodes, if possible.

 Notes
-----

 The [thread\_cache\_size](../server-system-variables/index#thread_cache_size) system variable is not used when the thread pool is used and the [Threads\_cached](../server-status-variables/index#threads_cached) status variable will have a value of 0.

 See Also
--------

 * [Thread Pool System and Status Variables](../thread-pool-system-and-status-variables/index)
* [Threadpool Benchmarks](../threadpool-benchmarks/index)
* [Thread Pool in MariaDB 5.1 - 5.3](../thread-pool-in-mariadb-51-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-pool-in-mariadb/>

Handling Too Many Connections
=============================

    Systems that get too busy can return the `too_many_connections` error.

 When the number of [threads\_connected](../server-status-variables/index#threads_connected) exceeds the `[max\_connections](../server-system-variables/index#max_connections)` server variable, it's time to make a change. Viewing the [threads\_connected](../server-status-variables/index#threads_connected) status variable shows only the current number of connections, but it's more useful to see what the value has peaked at, and this is shown by the [max\_used\_connections](../server-status-variables/index#max_used_connections) status variable.

 This error may be a symptom of slow queries and other bottlenecks, but if the system is running smoothly this can be addressed by increasing the value of max\_connections.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handling-too-many-connections/>

Thread Command Values
=====================

    A thread can have any of the following `COMMAND` values (displayed by the `COMMAND` field listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index), as well as the `PROCESSLIST_COMMAND` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index)). These indicate the nature of the thread's activity.

 


| Value | Description |
| --- | --- |
| Binlog Dump | Master thread for sending [binary log](../binary-log/index) contents to a slave. |
| Change user | Executing a change user operation. |
| Close stmt | Closing a [prepared statement](../prepared-statements/index). |
| Connect | [Replication](../replication/index) slave is connected to its master. |
| Connect Out | Replication slave is in the process of connecting to its master. |
| Create DB | Executing an operation to create a database. |
| Daemon | Internal server thread rather than for servicing a client connection. |
| Debug | Generating debug information. |
| Delayed insert | A delayed-insert handler. |
| Drop DB | Executing an operation to drop a database. |
| Error | Error. |
| Execute | Executing a [prepared statement](../prepared-statements/index). |
| Fetch | Fetching the results of an executed [prepared statement](../prepared-statements/index). |
| Field List | Retrieving table column information. |
| Init DB | Selecting default database. |
| Kill | Killing another thread. |
| Long Data | Retrieving long data from the result of executing a [prepared statement](../prepared-statements/index). |
| Ping | Handling a server ping request. |
| Prepare | Preparing a [prepared statement](../prepared-statements/index). |
| Processlist | Preparing processlist information about server threads. |
| Query | Executing a statement. |
| Quit | In the process of terminating the thread. |
| Refresh | [Flushing](../flush/index) a table, logs or caches, or refreshing replication server or [status variable](../server-status-variables/index) information. |
| Register Slave | Registering a slave server. |
| Reset stmt | Resetting a [prepared statement](../prepared-statements/index). |
| Set option | Setting or resetting a client statement execution option. |
| Sleep | Waiting for the client to send a new statement. |
| Shutdown | Shutting down the server. |
| Statistics | Preparing status information about the server. |
| Table Dump | Sending the contents of a table to a slave. |
| Time | Not used. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-command-values/>

SQL\_ERROR\_LOG Plugin System Variables
=======================================

     This page documents system variables related to the [SQL\_Error\_Log Plugin](../sql_error_log-plugin/index). See [Server System Variables](../server-system-variables/index) for a complete list of system variables and instructions on setting them.

 See also the [Full list of MariaDB options, system and status variables](../full-list-of-mariadb-options-system-and-status-variables/index). 

 #### `sql_error_log_filename`

 * **Description:** The name (and optionally path) of the logfile containing the errors. Rotation will use a naming convention such as `sql_error_log_filename.001`. If no path is specified, the log file will be written to the [data directory](../server-system-variables/index#datadir).
* **Commandline:** `--sql-error-log-filename=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `sql_errors.log`

 

---

 #### `sql_error_log_rate`

 * **Description:** The logging sampling rate. Setting to `10`, for example, means that one in ten errors will be logged. If set to zero, logging is disabled. The default, `1`, logs every error.
* **Commandline:** `--sql-error-log-rate=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `string`
* **Default Value:** `1`

 

---

 #### `sql_error_log_rotate`

 * **Description:** Setting to #1 `forces log rotation.`
* **Commandline:** `--sql-error-log-rate[={0|1}]`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `boolean`
* **Default Value:** `OFF`

 

---

 #### `sql_error_log_rotations`

 * **Description:** Number of rotations before the log is removed. When rotated, the current log file is stored and a new, empty, log is created. Any rotations older than this setting are removed.
* **Commandline:** `--sql-error-log-rotations=#`
* **Scope:** Global
* **Dynamic:** Yes
* **Data Type:** `numeric`
* **Default Value:** `9`
* **Range:** `1` to `999`

 

---

 #### `sql_error_log_size_limit`

 * **Description:** The log file size limit in bytes. After reaching this size, the log file is rotated.
* **Commandline:** `--sql-error-log-size-limit=#`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `numeric`
* **Default Value:** `1000000`
* **Range:** `100` to `9223372036854775807`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql_error_log-plugin-system-variables/>

CONNECT JSON Table Type
=======================

    Overview
--------

 JSON (JavaScript Object Notation) is a lightweight data-interchange format widely used on the Internet. Many applications, generally written in JavaScript or PHP use and produce JSON data, which are exchanged as files of different physical formats. JSON data is often returned from REST queries.

 It is also possible to query, create or update such information in a database-like manner. MongoDB does it using a JavaScript-like language. PostgreSQL includes these facilities by using a specific data type and related functions like dynamic columns.

 The CONNECT engine adds this facility to MariaDB by supporting tables based on JSON data files. This is done like for XML tables by creating tables describing what should be retrieved from the file and how it should be processed.

 Starting with 1.07.0002, the internal way JSON was parsed and handled was changed. The main advantage of the new way is to reduce the memory required to parse JSON. It was from 6 to 10 times the size of the JSON source and is now only 2 to 4 times. However, this is in Beta mode and JSON tables are still handled using the old mode. To use the new mode, tables should be created with TABLE\_TYPE=BSON. Another way is the set the [connect\_force\_bson](../connect-system-variables/index#connect_force_bson) session variable to 1 or ON. Then all JSON tables will be handled as BSON. Of course, this is temporary and when successfully tested, the new way will replace the old way and all tables be created as JSON.

 Let us start from the file “biblio3.json” that is the JSON equivalent of the XML Xsample file described in the XML table chapter:

 
```
[
  {
    "ISBN": "9782212090819",
    "LANG": "fr",
    "SUBJECT": "applications",
    "AUTHOR": [
      {
        "FIRSTNAME": "Jean-Christophe",
        "LASTNAME": "Bernadac"
      },
      {
        "FIRSTNAME": "François",
        "LASTNAME": "Knab"
      }
    ],
    "TITLE": "Construire une application XML",
    "PUBLISHER": {
      "NAME": "Eyrolles",
      "PLACE": "Paris"
    },
    "DATEPUB": 1999
  },
  {
    "ISBN": "9782840825685",
    "LANG": "fr",
    "SUBJECT": "applications",
    "AUTHOR": [
      {
        "FIRSTNAME": "William J.",
        "LASTNAME": "Pardi"
      }
    ],
    "TITLE": "XML en Action",
    "TRANSLATED": {
       "PREFIX": "adapté de l'anglais par",
       "TRANSLATOR": {
          "FIRSTNAME": "James",
        "LASTNAME": "Guerin"
        }
    },
    "PUBLISHER": {
      "NAME": "Microsoft Press",
      "PLACE": "Paris"
    },
    "DATEPUB": 1999
  }
]

```

This file contains the different items existing in JSON.

 * `Arrays`: They are enclosed in square brackets and contain a list of comma separated values.
* `Objects`: They are enclosed in curly brackets. They contain a comma separated list of pairs, each pair composed of a key name between double quotes, followed by a ‘:’ character and followed by a value.
* `Values`: Values can be an array or an object. They also can be a string between double quotes, an integer or float number, a Boolean value or a null value. The simplest way for CONNECT to locate a table in such a file is by an array containing a list of objects (this is what MongoDB calls a collection of documents). Each array value will be a table row and each pair of the row objects will represent a column, the key being the column name and the value the column value.

 A first try to create a table on this file will be to take the outer array as the table:

 
```
create table jsample (
ISBN char(15),
LANG char(2),
SUBJECT char(32),
AUTHOR char(128),
TITLE char(32),
TRANSLATED char(80),
PUBLISHER char(20),
DATEPUB int(4))
engine=CONNECT table_type=JSON
File_name='biblio3.json';

```

If we execute the query:

 
```
select isbn, author, title, publisher from jsample;

```

We get the result:

 


| isbn | author | title | publisher |
| --- | --- | --- | --- |
| 9782212090819 | Jean-Christophe Bernadac | Construire une application XML | Eyrolles Paris |
| 9782840825685 | William J. Pardi | XML en Action | Microsoft Press Pari |

 
Note that by default, column values that are objects have been set to the concatenation of all the string values of the object separated by a blank. When a column value is an array, only the first item of the array is retrieved (This will change in later versions of Connect).

 However, things are generally more complicated. If JSON files do not contain attributes (although object pairs are similar to attributes) they contain a new item, arrays. We have seen that they can be used like XML multiple nodes, here to specify several authors, but they are more general because they can contain objects of different types, even it may not be advisable to do so.

 This is why CONNECT enables the specification of a column field\_format option “JPATH” (FIELD\_FORMAT until Connect 1.6) that is used to describe exactly where the items to display are and how to handles arrays.

 Here is an example of a new table that can be created on the same file, allowing choosing the column names, to get some sub-objects and to specify how to handle the author array.

 Until Connect 1.5:

 
```
create table jsampall (
ISBN char(15),
Language char(2) field_format='LANG',
Subject char(32) field_format='SUBJECT',
Author char(128) field_format='AUTHOR:[" and "]',
Title char(32) field_format='TITLE',
Translation char(32) field_format='TRANSLATOR:PREFIX',
Translator char(80) field_format='TRANSLATOR',
Publisher char(20) field_format='PUBLISHER:NAME',
Location char(16) field_format='PUBLISHER:PLACE',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

From Connect 1.6:

 
```
create table jsampall (
ISBN char(15),
Language char(2) field_format='LANG',
Subject char(32) field_format='SUBJECT',
Author char(128) field_format='AUTHOR.[" and "]',
Title char(32) field_format='TITLE',
Translation char(32) field_format='TRANSLATOR.PREFIX',
Translator char(80) field_format='TRANSLATOR',
Publisher char(20) field_format='PUBLISHER.NAME',
Location char(16) field_format='PUBLISHER.PLACE',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

From Connect 1.07.0002

 
```
create table jsampall (
ISBN char(15),
Language char(2) jpath='$.LANG',
Subject char(32) jpath='$.SUBJECT',
Author char(128) jpath='$.AUTHOR[" and "]',
Title char(32) jpath='$.TITLE',
Translation char(32) jpath='$.TRANSLATOR.PREFIX',
Translator char(80) jpath='$.TRANSLATOR',
Publisher char(20) jpath='$.PUBLISHER.NAME',
Location char(16) jpath='$.PUBLISHER.PLACE',
Year int(4) jpath='$.DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

Given the query:

 
```
select title, author, publisher, location from jsampall;

```

The result is:

 


| title | author | publisher | location |
| --- | --- | --- | --- |
| Construire une application XML | Jean-Christophe Bernadac and François Knab | Eyrolles | Paris |
| XML en Action | William J. Pardi | Microsoft Press | Paris |

 
Note: The JPATH was not specified for column ISBN because it defaults to the column name.

 Here is another example showing that one can choose what to extract from the file and how to “expand” an array, meaning to generate one row for each array value:

 Until Connect 1.5:

 
```
create table jsampex (
ISBN char(15),
Title char(32) field_format='TITLE',
AuthorFN char(128) field_format='AUTHOR:[X]:FIRSTNAME',
AuthorLN char(128) field_format='AUTHOR:[X]:LASTNAME',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

From Connect 1.6:

 
```
create table jsampex (
ISBN char(15),
Title char(32) field_format='TITLE',
AuthorFN char(128) field_format='AUTHOR.[X].FIRSTNAME',
AuthorLN char(128) field_format='AUTHOR.[X].LASTNAME',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

From Connect 1.06.006:

 
```
create table jsampex (
ISBN char(15),
Title char(32) field_format='TITLE',
AuthorFN char(128) field_format='AUTHOR[*].FIRSTNAME',
AuthorLN char(128) field_format='AUTHOR[*].LASTNAME',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

From Connect 1.07.0002

 
```
create table jsampex (
ISBN char(15),
Title char(32) jpath='TITLE',
AuthorFN char(128) jpath='AUTHOR[*].FIRSTNAME',
AuthorLN char(128) jpath='AUTHOR[*].LASTNAME',
Year int(4) jpath='DATEPUB')
engine=CONNECT table_type=JSON File_name='biblio3.json';

```

It is displayed as:

 


| ISBN | Title | AuthorFN | AuthorLN | Year |
| --- | --- | --- | --- | --- |
| 9782212090819 | Construire une application XML | Jean-Christophe | Bernadac | 1999 |
| 9782212090819 | Construire une application XML | François | Knab | 1999 |
| 9782840825685 | XML en Action | William J. | Pardi | 1999 |

 
Note: The example above shows that the ‘$.’, that means the beginning of the path, can be omitted.

 The Jpath Specification
-----------------------

 
From Connect 1.6, the Jpath specification has changed to be the one of the native JSON functions and more compatible with what is generally used. It is close to the standard definition and compatible to what MongoDB and other products do. The ‘:’ separator is replaced by ‘.’. Position in array is accepted MongoDB style with no square brackets. Array specification specific to CONNECT are still accepted but [\*] is used for expanding and [x] for multiply. However, tables created with the previous syntax can still be used by adding SEP\_CHAR=’:’ (can be done with alter table). Also, it can be now specified as JPATH (was FIELD\_FORMAT) but FIELD\_FORMAT is still accepted.

 
Until Connect 1.5, it is the description of the path to follow to reach the required item. Each step is the key name (case sensitive) of the pair when crossing an object, and the number of the value between square brackets when crossing an array. Each specification is separated by a ‘:’ character.

 From Connect 1.6, It is the description of the path to follow to reach the required item. Each step is the key name (case sensitive) of the pair when crossing an object, and the position number of the value when crossing an array. Key specifications are separated by a ‘.’ character.

 For instance, in the above file, the last name of the second author of a book is reached by:

 $.AUTHOR[1].LASTNAME  *standard style $AUTHOR.1.LASTNAME*  MongoDB style AUTHOR:[1]:LASTNAME  *old style when SEP\_CHAR=’:’ or until Connect 1.5*

 The ‘$’ or “$.” prefix specifies the root of the path and can be omitted with CONNECT.

 The array specification can also indicate how it must be processed:

 For instance, in the above file, the last name of the second author of a book is reached by:

 
```
AUTHOR:[1]:LASTNAME

```

The array specification can also indicate how it must be processed:

 


| Specification | Array Type | Limit | Description |
| --- | --- | --- | --- |
| n (Connect >= 1.6) or [n][[1](#_note-0)] | All | N.A | Take the nth value of the array. |
| [\*] (Connect >= 1.6), [X] or [x] (Connect <= 1.5) | All |  | Expand. Generate one row for each array value. |
| ["string"] | String |  | Concatenate all values separated by the specified string. |
| [+] | Numeric |  | Make the sum of all the non-null array values. |
| [x] (Connect >= 1.6), [\*] (Connect <= 1.5) | Numeric |  | Make the product of all non-null array values. |
| [!] | Numeric |  | Make the average of all the non-null array values. |
| [>] or [<] | All |  | Return the greatest or least non-null value of the array. |
| [#] | All | N.A | Return the number of values in the array. |
| [] | All |  | Expand if under an expanded object. Otherwise sum if numeric, else concatenation separated by “, “. |
|  | All |  | Between two separators, if an array, expand it if under an expanded object or take the first value of it. |

 
Note 1: When the LIMIT restriction is applicable, only the first *m* array items are used, *m* being the value of the LIMIT option (to be specified in option\_list). The LIMIT default value is 10.

 Note 2: An alternative way to indicate what is to be expanded is to use the expand option in the option list, for instance:

 
```
OPTION_LIST='Expand=AUTHOR'

```

`AUTHOR` is here the key of the pair that has the array as a value (case sensitive). Expand is limited to only one branch (expanded arrays must be under the same object).

 Let us take as an example the file `expense.json` ([found here](../json-sample-files/index)). The table jexpall expands all under and including the week array:

 From Connect 1.07.0002

 
```
create table jexpall (
WHO char(12),
WEEK int(2) jpath='$.WEEK[*].NUMBER',
WHAT char(32) jpath='$.WEEK[*].EXPENSE[*].WHAT',
AMOUNT double(8,2) jpath='$.WEEK[*].EXPENSE[*].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

From Connect.1.6

 
```
create table jexpall (
WHO char(12),
WEEK int(2) field_format='$.WEEK[*].NUMBER',
WHAT char(32) field_format='$.WEEK[*].EXPENSE[*].WHAT',
AMOUNT double(8,2) field_format='$.WEEK[*].EXPENSE[*].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

Until Connect 1.5:

 
```
create table jexpall (
WHO char(12),
WEEK int(2) field_format='WEEK:[x]:NUMBER',
WHAT char(32) field_format='WEEK:[x]:EXPENSE:[x]:WHAT',
AMOUNT double(8,2) field_format='WEEK:[x]:EXPENSE:[x]:AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```




| WHO | WEEK | WHAT | AMOUNT |
| --- | --- | --- | --- |
| Joe | 3 | Beer | 18.00 |
| Joe | 3 | Food | 12.00 |
| Joe | 3 | Food | 19.00 |
| Joe | 3 | Car | 20.00 |
| Joe | 4 | Beer | 19.00 |
| Joe | 4 | Beer | 16.00 |
| Joe | 4 | Food | 17.00 |
| Joe | 4 | Food | 17.00 |
| Joe | 4 | Beer | 14.00 |
| Joe | 5 | Beer | 14.00 |
| Joe | 5 | Food | 12.00 |
| Beth | 3 | Beer | 16.00 |
| Beth | 4 | Food | 17.00 |
| Beth | 4 | Beer | 15.00 |
| Beth | 5 | Food | 12.00 |
| Beth | 5 | Beer | 20.00 |
| Janet | 3 | Car | 19.00 |
| Janet | 3 | Food | 18.00 |
| Janet | 3 | Beer | 18.00 |
| Janet | 4 | Car | 17.00 |
| Janet | 5 | Beer | 14.00 |
| Janet | 5 | Car | 12.00 |
| Janet | 5 | Beer | 19.00 |
| Janet | 5 | Food | 12.00 |

 
The table `jexpw` shows what was bought and the sum and average of amounts for each person and week:

 From Connect 1.07.0002

 
```
create table jexpw (
WHO char(12) not null,
WEEK int(2) not null jpath='$.WEEK[*].NUMBER',
WHAT char(32) not null jpath='$.WEEK[].EXPENSE[", "].WHAT',
SUM double(8,2) not null jpath='$.WEEK[].EXPENSE[+].AMOUNT',
AVERAGE double(8,2) not null jpath='$.WEEK[].EXPENSE[!].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

From Connect 1.6:

 
```
create table jexpw (
WHO char(12) not null,
WEEK int(2) not null field_format='$.WEEK[*].NUMBER',
WHAT char(32) not null field_format='$.WEEK[].EXPENSE[", "].WHAT',
SUM double(8,2) not null field_format='$.WEEK[].EXPENSE[+].AMOUNT',
AVERAGE double(8,2) not null field_format='$.WEEK[].EXPENSE[!].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

Until Connect 1.5:

 
```
create table jexpw (
WHO char(12) not null,
WEEK int(2) not null field_format='WEEK:[x]:NUMBER',
WHAT char(32) not null field_format='WEEK::EXPENSE:[", "]:WHAT',
SUM double(8,2) not null field_format='WEEK::EXPENSE:[+]:AMOUNT',
AVERAGE double(8,2) not null field_format='WEEK::EXPENSE:[!]:AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```




| WHO | WEEK | WHAT | SUM | AVERAGE |
| --- | --- | --- | --- | --- |
| Joe | 3 | Beer, Food, Food, Car | 69.00 | 17.25 |
| Joe | 4 | Beer, Beer, Food, Food, Beer | 83.00 | 16.60 |
| Joe | 5 | Beer, Food | 26.00 | 13.00 |
| Beth | 3 | Beer | 16.00 | 16.00 |
| Beth | 4 | Food, Beer | 32.00 | 16.00 |
| Beth | 5 | Food, Beer | 32.00 | 16.00 |
| Janet | 3 | Car, Food, Beer | 55.00 | 18.33 |
| Janet | 4 | Car | 17.00 | 17.00 |
| Janet | 5 | Beer, Car, Beer, Food | 57.00 | 14.25 |

 
Let us see what the table `jexpz` does:

 From Connect 1.6:

 
```
create table jexpz (
WHO char(12) not null,
WEEKS char(12) not null field_format='WEEK[", "].NUMBER',
SUMS char(64) not null field_format='WEEK["+"].EXPENSE[+].AMOUNT',
SUM double(8,2) not null field_format='WEEK[+].EXPENSE[+].AMOUNT',
AVGS char(64) not null field_format='WEEK["+"].EXPENSE[!].AMOUNT',
SUMAVG double(8,2) not null field_format='WEEK[+].EXPENSE[!].AMOUNT',
AVGSUM double(8,2) not null field_format='WEEK[!].EXPENSE[+].AMOUNT',
AVERAGE double(8,2) not null field_format='WEEK[!].EXPENSE[*].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

From Connect 1.07.0002

 
```
create table jexpz (
WHO char(12) not null,
WEEKS char(12) not null jpath='WEEK[", "].NUMBER',
SUMS char(64) not null jpath='WEEK["+"].EXPENSE[+].AMOUNT',
SUM double(8,2) not null jpath='WEEK[+].EXPENSE[+].AMOUNT',
AVGS char(64) not null jpath='WEEK["+"].EXPENSE[!].AMOUNT',
SUMAVG double(8,2) not null jpath='WEEK[+].EXPENSE[!].AMOUNT',
AVGSUM double(8,2) not null jpath='WEEK[!].EXPENSE[+].AMOUNT',
AVERAGE double(8,2) not null jpath='WEEK[!].EXPENSE[*].AMOUNT')
engine=CONNECT table_type=JSON File_name='expense.json';

```

Until Connect 1.5:

 
```
create table jexpz (
WHO char(12) not null,
WEEKS char(12) not null field_format='WEEK:[", "]:NUMBER',
SUMS char(64) not null field_format='WEEK:["+"]:EXPENSE:[+]:AMOUNT',
SUM double(8,2) not null field_format='WEEK:[+]:EXPENSE:[+]:AMOUNT',
AVGS char(64) not null field_format='WEEK:["+"]:EXPENSE:[!]:AMOUNT',
SUMAVG double(8,2) not null field_format='WEEK:[+]:EXPENSE:[!]:AMOUNT',
AVGSUM double(8,2) not null field_format='WEEK:[!]:EXPENSE:[+]:AMOUNT',
AVERAGE double(8,2) not null field_format='WEEK:[!]:EXPENSE:[x]:AMOUNT')
engine=CONNECT table_type=JSON
File_name='E:/Data/Json/expense2.json';

```




| WHO | WEEKS | SUMS | SUM | AVGS | SUMAVG | AVGSUM | AVERAGE |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Joe | 3, 4, 5 | 69.00+83.00+26.00 | 178.00 | 17.25+16.60+13.00 | 46.85 | 59.33 | 16.18 |
| Beth | 3, 4, 5 | 16.00+32.00+32.00 | 80.00 | 16.00+16.00+16.00 | 48.00 | 26.67 | 16.00 |
| Janet | 3, 4, 5 | 55.00+17.00+57.00 | 129.00 | 18.33+17.00+14.25 | 49.58 | 43.00 | 16.12 |

 
For all persons:

 * Column 1 show the person name.
* Column 2 shows the weeks for which values are calculated.
* Column 3 lists the sums of expenses for each week.
* Column 4 calculates the sum of all expenses by person.
* Column 5 shows the week’s expense averages.
* Column 6 calculates the sum of these averages.
* Column 7 calculates the average of the week’s sum of expenses.
* Column 8 calculates the average expense by person.

 It would be very difficult, if even possible, to obtain this result from table `jexpall` using an SQL query.

 Handling of NULL Values
-----------------------

 Json has a null explicit value that can be met in arrays or object key values. When regarding json as a relational table, a column value can be null because the corresponding json item is explicitly null, or implicitly because the corresponding item is missing in an array or object. CONNECT does not make any distinction between explicit and implicit nulls.

 However, it is possible to specify how nulls are handled and represented. This is done by setting the string session variable [connect\_json\_null](../connect-system-variables/index#connect_json_null). The default value of connect\_json\_null is “<null>”; it can be changed, for instance, by:

 
```
SET connect_json_null='NULL';

```

This changes its representation when a column displays the text of an object or the concatenation of the values of an array.

 It is also possible to tell CONNECT to ignore nulls by:

 
```
SET connect_json_null=NULL;

```

When doing so, nulls do not appear in object text or array lists. However, this does not change the behavior of array calculation nor the result of array count.

 Having Columns defined by Discovery
-----------------------------------

 It is possible to let the MariaDB discovery process do the job of column specification. When columns are not defined in the create table statement, CONNECT endeavors to analyze the JSON file and to provide the column specifications. This is possible only for tables represented by an array of objects because CONNECT retrieves the column names from the object pair keys and their definition from the object pair values. For instance, the jsample table could be created saying:

 
```
create table jsample engine=connect table_type=JSON file_name='biblio3.json';

```

Let’s check how it was actually specified using the show create table statement:

 
```
CREATE TABLE `jsample` (
  `ISBN` char(13) NOT NULL,
  `LANG` char(2) NOT NULL,
  `SUBJECT` char(12) NOT NULL,
  `AUTHOR` varchar(256) DEFAULT NULL,
  `TITLE` char(30) NOT NULL,
  `TRANSLATED` varchar(256) DEFAULT NULL,
  `PUBLISHER` varchar(256) DEFAULT NULL,
  `DATEPUB` int(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='JSON' `FILE_NAME`='biblio3.json';

```

It is equivalent except for the column sizes that have been calculated from the file as the maximum length of the corresponding column when it was a normal value. For columns that are json arrays or objects, the column is specified as a varchar string of length 256, supposedly big enough to contain the sub-object's concatenated values. Nullable is set to true if the column is null or missing in some rows or if its JPATH contains arrays.

 If a more complex definition is desired, you can ask CONNECT to analyse the JPATH up to a given depth using the DEPTH or LEVEL option in the option list. Its default value is 0 but can be changed setting the [connect\_default\_depth](../connect-system-variables/index#connect_default_depth) session variable (in future versions the default will be 5). The depth value is the number of sub-objects that are taken in the JPATH2 (this is different from what is defined and returned by the native [Json\_Depth](../json_depth/index) function).

 For instance:

 
```
create table jsampall2 engine=connect table_type=JSON 
  file_name='biblio3.json' option_list='level=1';

```

This will define the table as:

 From Connect 1.07.0002

 
```
CREATE TABLE `jsampall2` (
  `ISBN` char(13) NOT NULL,
  `LANG` char(2) NOT NULL,
  `SUBJECT` char(12) NOT NULL,
  `AUTHOR_FIRSTNAME` char(15) NOT NULL `JPATH`='$.AUTHOR.[0].FIRSTNAME',
  `AUTHOR_LASTNAME` char(8) NOT NULL `JPATH`='$.AUTHOR.[0].LASTNAME',
  `TITLE` char(30) NOT NULL,
  `TRANSLATED_PREFIX` char(23) DEFAULT NULL `JPATH`='$.TRANSLATED.PREFIX',
  `TRANSLATED_TRANSLATOR` varchar(256) DEFAULT NULL `JPATH`='$.TRANSLATED.TRANSLATOR',
  `PUBLISHER_NAME` char(15) NOT NULL `JPATH`='$.PUBLISHER.NAME',
  `PUBLISHER_PLACE` char(5) NOT NULL `JPATH`='$.PUBLISHER.PLACE',
  `DATEPUB` int(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='JSON' 
  `FILE_NAME`='biblio3.json' `OPTION_LIST`='depth=1';

```

From Connect 1.6:

 
```
CREATE TABLE `jsampall2` (
  `ISBN` char(13) NOT NULL,
  `LANG` char(2) NOT NULL,
  `SUBJECT` char(12) NOT NULL,
  `AUTHOR_FIRSTNAME` char(15) NOT NULL `FIELD_FORMAT`='AUTHOR..FIRSTNAME',
  `AUTHOR_LASTNAME` char(8) NOT NULL `FIELD_FORMAT`='AUTHOR..LASTNAME',
  `TITLE` char(30) NOT NULL,
  `TRANSLATED_PREFIX` char(23) DEFAULT NULL `FIELD_FORMAT`='TRANSLATED.PREFIX',
  `TRANSLATED_TRANSLATOR` varchar(256) DEFAULT NULL `FIELD_FORMAT`='TRANSLATED.TRANSLATOR',
  `PUBLISHER_NAME` char(15) NOT NULL `FIELD_FORMAT`='PUBLISHER.NAME',
  `PUBLISHER_PLACE` char(5) NOT NULL `FIELD_FORMAT`='PUBLISHER.PLACE',
  `DATEPUB` int(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='JSON' 
  `FILE_NAME`='biblio3.json' `OPTION_LIST`='level=1';

```

Until Connect 1.5:

 
```
CREATE TABLE `jsampall2` (
  `ISBN` char(13) NOT NULL,
  `LANG` char(2) NOT NULL,
  `SUBJECT` char(12) NOT NULL,
  `AUTHOR_FIRSTNAME` char(15) NOT NULL `FIELD_FORMAT`='AUTHOR::FIRSTNAME',
  `AUTHOR_LASTNAME` char(8) NOT NULL `FIELD_FORMAT`='AUTHOR::LASTNAME',
  `TITLE` char(30) NOT NULL,
  `TRANSLATED_PREFIX` char(23) DEFAULT NULL `FIELD_FORMAT`='TRANSLATED:PREFIX',
  `TRANSLATED_TRANSLATOR` varchar(256) DEFAULT NULL `FIELD_FORMAT`='TRANSLATED:TRANSLATOR',
  `PUBLISHER_NAME` char(15) NOT NULL `FIELD_FORMAT`='PUBLISHER:NAME',
  `PUBLISHER_PLACE` char(5) NOT NULL `FIELD_FORMAT`='PUBLISHER:PLACE',
  `DATEPUB` int(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='JSON' `
  FILE_NAME`='biblio3.json' `OPTION_LIST`='level=1';

```

For columns that are a simple value, the Json path is the column name. This is the default when the Jpath option is not specified, so it was not specified for such columns. However, you can force discovery to specify it by setting the connect\_all\_path variable to 1 or ON. This can be useful if you plan to change the name of such columns and relieves you of manually specifying the path (otherwise it would default to the new name and cause the column to not or wrongly be found).

 Another problem is that CONNECT cannot guess what you want to do with arrays. Here the AUTHOR array is set to 0, which means that only its first value will be retrieved unless you also had specified “Expand=AUTHOR” in the option list. But of course, you can replace it with anything else.

 This method can be used as a quick way to make a “template” table definition that can later be edited to make the desired definition. In particular, column names are constructed from all the object keys of their path in order to have distinct column names. This can be manually edited to have the desired names, provided their JPATH key names are not modified.

 DEPTH can also be given the value -1 to create only columns that are simple values (no array or object). It normally defaults to 0 but this can be modified setting the [connect\_default\_depth](../connect-system-variables/index#connect_default_depth) variable.

 Note: Since version 1.6.4, CONNECT eliminates columns that are “void” or whose type cannot be determined. For instance given the file sresto.json:

 
```
{"_id":1,"name":"Corner Social","cuisine":"American","grades":[{"grade":"A","score":6}]}
{"_id":2,"name":"La Nueva Clasica Antillana","cuisine":"Spanish","grades":[]}

```

Previously, when using discovery, creating the table by:

 
```
create table sjr0
engine=connect table_type=JSON file_name='sresto.json'
option_list='Pretty=0,Depth=1' lrecl=128;

```

The table was previously created as:

 
```
CREATE TABLE `sjr0` (
  `_id` bigint(1) NOT NULL,
  `name` char(26) NOT NULL,
  `cuisine` char(8) NOT NULL,
  `grades` char(1) DEFAULT NULL,
  `grades_grade` char(1) DEFAULT NULL `JPATH`='$.grades[0].grade',
  `grades_score` bigint(1) DEFAULT NULL `JPATH`='$.grades[0].score'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='JSON'
  `FILE_NAME`='sresto.json' 
  `OPTION_LIST`='Pretty=0,Depth=1,Accept=1' `LRECL`=128;

```

The column “grades” was added because of the void array in line 2. Now this column is skipped and does not appear anymore (unless the option `Accept=1` is added in the option list).

 JSON Catalogue Tables
---------------------

 Another way to see JSON table column specifications is to use a catalogue table. For instance:

 
```
create table bibcol engine=connect table_type=JSON file_name='biblio3.json' 
  option_list='level=2' catfunc=columns;
select column_name, type_name type, column_size size, jpath from bibcol;

```

which returns:

 From Connect 1.07.0002:

 


| column\_name | type | size | jpath |
| --- | --- | --- | --- |
| ISBN | CHAR | 13 | $.ISBN |
| LANG | CHAR | 2 | $.LANG |
| SUBJECT | CHAR | 12 | $.SUBJECT |
| AUTHOR\_FIRSTNAME | CHAR | 15 | $.AUTHOR[0].FIRSTNAME |
| AUTHOR\_LASTNAME | CHAR | 8 | $.AUTHOR[0].LASTNAME |
| TITLE | CHAR | 30 | $.TITLE |
| TRANSLATED\_PREFIX | CHAR | 23 | $.TRANSLATED.PREFIX |
| TRANSLATED\_TRANSLATOR\_FIRSTNAME | CHAR | 5 | $TRANSLATED.TRANSLATOR.FIRSTNAME |
| TRANSLATED\_TRANSLATOR\_LASTNAME | CHAR | 6 | $.TRANSLATED.TRANSLATOR.LASTNAME |
| PUBLISHER\_NAME | CHAR | 15 | $.PUBLISHER.NAME |
| PUBLISHER\_PLACE | CHAR | 5 | $.PUBLISHER.PLACE |
| DATEPUB | INTEGER | 4 | $.DATEPUB |

 
From Connect 1.6:

 


| column\_name | type | size | jpath |
| --- | --- | --- | --- |
| ISBN | CHAR | 13 |  |
| LANG | CHAR | 2 |  |
| SUBJECT | CHAR | 12 |  |
| AUTHOR\_FIRSTNAME | CHAR | 15 | AUTHOR..FIRSTNAME |
| AUTHOR\_LASTNAME | CHAR | 8 | AUTHOR..LASTNAME |
| TITLE | CHAR | 30 |  |
| TRANSLATED\_PREFIX | CHAR | 23 | TRANSLATED.PREFIX |
| TRANSLATED\_TRANSLATOR\_FIRSTNAME | CHAR | 5 | TRANSLATED.TRANSLATOR.FIRSTNAME |
| TRANSLATED\_TRANSLATOR\_LASTNAME | CHAR | 6 | TRANSLATED.TRANSLATOR.LASTNAME |
| PUBLISHER\_NAME | CHAR | 15 | PUBLISHER.NAME |
| PUBLISHER\_PLACE | CHAR | 5 | PUBLISHER.PLACE |
| DATEPUB | INTEGER | 4 |  |

 
Until Connect 1.5:

 


| column\_name | type | size | jpath |
| --- | --- | --- | --- |
| ISBN | CHAR | 13 |  |
| LANG | CHAR | 2 |  |
| SUBJECT | CHAR | 12 |  |
| AUTHOR\_FIRSTNAME | CHAR | 15 | AUTHOR::FIRSTNAME |
| AUTHOR\_LASTNAME | CHAR | 8 | AUTHOR::LASTNAME |
| TITLE | CHAR | 30 |  |
| TRANSLATED\_PREFIX | CHAR | 23 | TRANSLATED:PREFIX |
| TRANSLATED\_TRANSLATOR\_FIRSTNAME | CHAR | 5 | TRANSLATED:TRANSLATOR:FIRSTNAME |
| TRANSLATED\_TRANSLATOR\_LASTNAME | CHAR | 6 | TRANSLATED:TRANSLATOR:LASTNAME |
| PUBLISHER\_NAME | CHAR | 15 | PUBLISHER:NAME |
| PUBLISHER\_PLACE | CHAR | 5 | PUBLISHER:PLACE |
| DATEPUB | INTEGER | 4 |  |

 
All this is mostly useful when creating a table on a remote file that you cannot easily see.

 Finding the table within a JSON file
------------------------------------

 Given the file “facebook.json”:

 
```
{
   "data": [
      {
         "id": "X999_Y999",
         "from": {
            "name": "Tom Brady", "id": "X12"
         },
         "message": "Looking forward to 2010!",
         "actions": [
            {
               "name": "Comment",
               "link": "http://www.facebook.com/X999/posts/Y999"
            },
            {
               "name": "Like",
               "link": "http://www.facebook.com/X999/posts/Y999"
            }
         ],
         "type": "status",
         "created_time": "2010-08-02T21:27:44+0000",
         "updated_time": "2010-08-02T21:27:44+0000"
      },
      {
         "id": "X998_Y998",
         "from": {
            "name": "Peyton Manning", "id": "X18"
         },
         "message": "Where's my contract?",
         "actions": [
            {
               "name": "Comment",
               "link": "http://www.facebook.com/X998/posts/Y998"
            },
            {
               "name": "Like",
               "link": "http://www.facebook.com/X998/posts/Y998"
            }
         ],
         "type": "status",
         "created_time": "2010-08-02T21:27:44+0000",
         "updated_time": "2010-08-02T21:27:44+0000"
      }
   ]
}

```

The table we want to analyze is represented by the array value of the “data” object. Here is how this is specified in the create table statement:

 From Connect 1.07.0002:

 
```
create table jfacebook (
`ID` char(10) jpath='id',
`Name` char(32) jpath='from.name',
`MyID` char(16) jpath='from.id',
`Message` varchar(256) jpath='message',
`Action` char(16) jpath='actions..name',
`Link` varchar(256) jpath='actions..link',
`Type` char(16) jpath='type',
`Created` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' jpath='created_time',
`Updated` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' jpath='updated_time')
engine=connect table_type=JSON file_name='facebook.json' option_list='Object=data,Expand=actions';

```

From Connect 1.6:

 
```
create table jfacebook (
`ID` char(10) field_format='id',
`Name` char(32) field_format='from.name',
`MyID` char(16) field_format='from.id',
`Message` varchar(256) field_format='message',
`Action` char(16) field_format='actions..name',
`Link` varchar(256) field_format='actions..link',
`Type` char(16) field_format='type',
`Created` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' field_format='created_time',
`Updated` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' field_format='updated_time')
engine=connect table_type=JSON file_name='facebook.json' option_list='Object=data,Expand=actions';

```

Until Connect 1.5:

 
```
create table jfacebook (
`ID` char(10) field_format='id',
`Name` char(32) field_format='from:name',
`MyID` char(16) field_format='from:id',
`Message` varchar(256) field_format='message',
`Action` char(16) field_format='actions::name',
`Link` varchar(256) field_format='actions::link',
`Type` char(16) field_format='type',
`Created` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' field_format='created_time',
`Updated` datetime date_format='YYYY-MM-DD\'T\'hh:mm:ss' field_format='updated_time')
engine=connect table_type=JSON file_name='facebook.json' option_list='Object=data,Expand=actions';

```

This is the object option that gives the Jpath of the table. Note also an alternate way to declare the array to be expanded by the expand option of the option\_list.

 Because some string values contain a date representation, the corresponding columns are declared as datetime and the date format is specified for them.

 The Jpath of the object option has the same syntax as the column Jpath but of course all array steps must be specified using the [n] (until Connect 1.5) or n (from Connect 1.6) format.

 Note: This applies to the whole document for tables having `PRETTY = 2` (see below). Otherwise, it applies to the document objects of each file records.

 JSON File Formats
-----------------

 The examples we have seen so far are files that, even they can be formatted in different ways (blanks, tabs, carriage return and line feed are ignored when parsing them), respect the JSON syntax and are made of only one item (Object or Array). Like for XML files, they are entirely parsed and a memory representation is made used to process them. This implies that they are of reasonable size to avoid an out of memory condition. Tables based on such files are recognized by the option Pretty=2 that we did not specify above because this is the default.

 An alternate format, which is the format of exported MongoDB files, is a file where each row is physically stored in one file record. For instance:

 
```
{ "_id" : "01001", "city" : "AGAWAM", "loc" : [ -72.622739, 42.070206 ], "pop" : 15338, "state" : "MA" }
{ "_id" : "01002", "city" : "CUSHMAN", "loc" : [ -72.51564999999999, 42.377017 ], "pop" : 36963, "state" : "MA" }
{ "_id" : "01005", "city" : "BARRE", "loc" : [ -72.1083540000001, 42.409698 ], "pop" : 4546, "state" : "MA" }
{ "_id" : "01007", "city" : "BELCHERTOWN", "loc" : [ -72.4109530000001, 42.275103 ], "pop" : 10579, "state" : "MA" }
…
{ "_id" : "99929", "city" : "WRANGELL", "loc" : [ -132.352918, 56.433524 ], "pop" : 2573, "state" : "AK" }
{ "_id" : "99950", "city" : "KETCHIKAN", "loc" : [ -133.18479, 55.942471 ], "pop" : 422, "state" : "AK" }

```

The original file, “cities.json”, has 29352 records. To base a table on this file we must specify the option Pretty=0 in the option list. For instance:

 From Connect 1.07.0002:

 
```
create table cities (
`_id` char(5) key,
`city` char(32),
`lat` double(12,6) jpath='loc.0',
`long` double(12,6) jpath='loc.1',
`pop` int(8),
`state` char(2) distrib='clustered')
engine=CONNECT table_type=JSON file_name='cities.json' lrecl=128 option_list='pretty=0';

```

From Connect 1.6:

 
```
create table cities (
`_id` char(5) key,
`city` char(32),
`lat` double(12,6) field_format='loc.0',
`long` double(12,6) field_format='loc.1',
`pop` int(8),
`state` char(2) distrib='clustered')
engine=CONNECT table_type=JSON file_name='cities.json' lrecl=128 option_list='pretty=0';

```

Until Connect 1.5:

 
```
create table cities (
`_id` char(5) key,
`city` char(32),
`long` double(12,6) field_format='loc:[0]',
`lat` double(12,6) field_format='loc:[1]',
`pop` int(8),
`state` char(2) distrib='clustered')
engine=CONNECT table_type=JSON file_name='cities.json' lrecl=128 option_list='pretty=0';

```

Note the use of [n] (until Connect 1.5) or n (from Connect 1.6) array specifications for the longitude and latitude columns.

 When using this format, the table is processed by CONNECT like a DOS, CSV or FMT table. Rows are retrieved and parsed by records and the table can be very large. Another advantage is that such a table can be indexed, which can be of great value for very large tables. The “distrib” option of the “state” column tells CONNECT to use block indexing when possible.

 For such tables – as well as for *pretty=1* ones – the record size must be specified using the LRECL option. Be sure you don’t specify it too small as it is used to allocate the read/write buffers and the memory used for parsing the rows. If in doubt, be generous as it does not cost much in memory allocation.

 Another format exists, noted by Pretty=1, which is similar to this one but has some additions to represent a JSON array. A header and a trailer records are added containing the opening and closing square bracket, and all records but the last are followed by a comma. It has the same advantages for reading and updating, but inserting and deleting are executed in the pretty=2 way.

 Alternate Table Arrangement
---------------------------

 We have seen that the most natural way to represent a table in a JSON file is to make it on an array of objects. However, other possibilities exist. A table can be an array of arrays, a one column table can be an array of values, or a one row table can be just one object or one value. Single row tables are internally handled by adding a one value array around them.

 Let us see how to handle, for instance, a table that is an array of arrays. The file:

 
```
[
  [56, "Coucou", 500.00],
  [[2,0,1,4], "Hello World", 2.0316],
  ["1784", "John Doo", 32.4500],
  [1914, ["Nabucho","donosor"], 5.12],
  [7, "sept", [0.77,1.22,2.01]],
  [8, "huit", 13.0]
]

```

A table can be created on this file as:

 From Connect 1.07.0002:

 
```
create table xjson (
`a` int(6) jpath='1',
`b` char(32) jpath='2',
`c` double(10,4) jpath='3')
engine=connect table_type=JSON file_name='test.json' option_list='Pretty=1,Jmode=1,Base=1' lrecl=128;

```

From Connect 1.6:

 
```
create table xjson (
`a` int(6) field_format='1',
`b` char(32) field_format='2',
`c` double(10,4) field_format='3')
engine=connect table_type=JSON file_name='test.json' option_list='Pretty=1,Jmode=1,Base=1' lrecl=128;

```

Until Connect 1.5:

 
```
create table xjson (
`a` int(6) field_format='[1]',
`b` char(32) field_format='[2]',
`c` double(10,4) field_format='[3]')
engine=connect table_type=JSON file_name='test.json'
option_list='Pretty=1,Jmode=1,Base=1' lrecl=128;

```

Columns are specified by their position in the row arrays. By default, this is zero-based but for this table the base was set to 1 by the *Base* option of the option list. Another new option in the option list is Jmode=1. It indicates what type of table this is. The Jmode values are:

 1. An array of objects. This is the default.
2. An array of Array. Like this one.
3. An array of values.

 When reading, this is not required as the type of the array items is specified for the columns; however, it is required when inserting new rows so CONNECT knows what to insert. For instance:

 
```
insert into xjson values(25, 'Breakfast', 1.414);

```

After this, it is displayed as:

 


| a | b | c |
| --- | --- | --- |
| 56 | Coucou | 500.0000 |
| 2 | Hello World | 2.0316 |
| 1784 | John Doo | 32.4500 |
| 1914 | Nabucho | 5.1200 |
| 7 | sept | 0.7700 |
| 8 | huit | 13.0000 |
| 25 | Breakfast | 1.4140 |

 
Unspecified array values are represented by their first element.

 Getting and Setting JSON Representation of a Column
---------------------------------------------------

 We have seen that columns corresponding to a Json object or array are retrieved by default as the concatenation of all its values separated by a blank. It is also possible to retrieve and display such column contains as the full JSON string corresponding to it in the JSON file. This is specified in the JPATH by a “\*” where the object or array would be specified. 

 Note: When having columns generated by discovery, this can be specified by adding the STRINGIFY option to ON or 1 in the option list.

 For instance:

 From Connect 1.07.0002:

 
```
create table jsample2 (
ISBN char(15),
Lng char(2) jpath='LANG',
json_Author char(255) jpath='AUTHOR.*',
Title char(32) jpath='TITLE',
Year int(4) jpath='DATEPUB')
engine=CONNECT table_type=JSON file_name='biblio3.json';

```

From Connect 1.6:

 
```
create table jsample2 (
ISBN char(15),
Lng char(2) field_format='LANG',
json_Author char(255) field_format='AUTHOR.*',
Title char(32) field_format='TITLE',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON file_name='biblio3.json';

```

Until Connect 1.5:

 
```
create table jsample2 (
ISBN char(15),
Lng char(2) field_format='LANG',
json_Author char(255) field_format='AUTHOR:*',
Title char(32) field_format='TITLE',
Year int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON file_name='biblio3.json';

```

Now the query:

 
```
select json_Author from jsample2;

```

will return and display :

 


| json\_Author |
| --- |
| [{"FIRSTNAME":"Jean-Christophe","LASTNAME":"Bernadac"},{"FIRSTNAME":"François","LASTNAME":"Knab"}] |
| [{"FIRSTNAME":"William J.","LASTNAME":"Pardi"}] |

 
Note: Prefixing the column name by *json\_* is optional but is useful when using the column as argument to Connect UDF functions, making it to be surely recognized as valid Json without aliasing.

 This also works on input, a column specified so that it can be directly set to a valid JSON string.

 This feature is of great value as we will see below.

 Create, Read, Update and Delete Operations on JSON Tables
---------------------------------------------------------

 The SQL commands INSERT, UPDATE and DELETE are fully supported for JSON tables except those returned by REST queries. For INSERT and UPDATE, if the target values are simple values, there are no problems.

 However, there are some issues when the added or modified values are objects or arrays.

 Concerning objects, the same problems exist that we have already seen with the XML type. The added or modified object will have the format described in the table definition, which can be different from the one of the JSON file. Modifications should be done using a file specifying the full path of modified objects.

 New problems are raised when trying to modify the values of an array. Only updates can be done on the original table. First of all, for the values of the array to be distinct values, all update operations concerning array values must be done using a table expanding this array.

 For instance, to modify the authors of the `biblio.json` based table, the `jsampex` table must be used. Doing so, updating and deleting authors is possible using standard SQL commands. For example, to change the first name of Knab from François to John:

 
```
update jsampex set authorfn = 'John' where authorln = 'Knab';

```

However It would be wrong to do:

 
```
update jsampex set authorfn = 'John' where isbn = '9782212090819';

```

Because this would change the first name of both authors as they share the same ISBN.

 Where things become more difficult is when trying to delete or insert an author of a book. Indeed, a delete command will delete the whole book and an insert command will add a new complete row instead of adding a new author in the same array. Here we are penalized by the SQL language that cannot give us a way to specify this. Something like:

 
```
update jsampex add authorfn = 'Charles', authorln = 'Dickens'
where title = 'XML en Action';

```

However this does not exist in SQL. Does this mean that it is impossible to do it? No, but it requires us to use a table specified on the same file but adapted to this task. One way to do it is to specify a table for which the authors are no more an expanded array. Supposing we want to add an author to the “XML en Action” book. We will do it on a table containing just the author(s) of that book, which is the second book of the table.

 From Connect 1.6:

 
```
create table jauthor (
FIRSTNAME char(64),
LASTNAME char(64))
engine=CONNECT table_type=JSON File_name='biblio3.json' option_list='Object=1.AUTHOR';

```

Until Connect 1.5

 
```
create table jauthor (
FIRSTNAME char(64),
LASTNAME char(64))
engine=CONNECT table_type=JSON File_name='biblio3.json' option_list='Object=[1]:AUTHOR';

```

The command:

 
```
select * from jauthor;

```

replies:

 


| FIRSTNAME | LASTNAME |
| --- | --- |
| William J. | Pardi |

 
It is a standard JSON table that is an array of objects in which we can freely insert or delete rows.

 
```
insert into jauthor values('Charles','Dickens');

```

We can check that this was done correctly by:

 
```
select * from jsampex;

```

This will display:

 


| ISBN | Title | AuthorFN | AuthorLN | Year |
| --- | --- | --- | --- | --- |
| 9782212090819 | Construire une application XML | Jean-Christophe | Bernadac | 1999 |
| 9782212090819 | Construire une application XML | John | Knab | 1999 |
| 9782840825685 | XML en Action | William J. | Pardi | 1999 |
| 9782840825685 | XML en Action | Charles | Dickens | 1999 |

 
Note: If this table were a big table with many books, it would be difficult to know what the order of a specific book is in the table. This can be found by adding a special ROWID column in the table.

 However, an alternate way to do it is by using direct JSON column representation as in the `JSAMPLE2` table. This can be done by:

 
```
update jsample2 set json_Author =
'[{"FIRSTNAME":"William J.","LASTNAME":"Pardi"},
  {"FIRSTNAME":"Charles","LASTNAME":"Dickens"}]'
where isbn = '9782840825685';

```

Here, we didn't have to find the index of the sub array to modify. However, this is not quite satisfying because we had to manually write the whole JSON value to set to the json\_Author column.

 Therefore we need specific functions to do so. They are introduced now.

 JSON User Defined Functions
---------------------------

 Although such functions written by other parties do exist,[[2](#_note-1)] CONNECT provides its own UDFs that are specifically adapted to the JSON table type and easily available because, being inside the CONNECT library or DLL, they require no additional module to be loaded (see [CONNECT - Compiling JSON UDFs in a Separate Library](../connect-compiling-json-udfs-in-a-separate-library/index) to make these functions in a separate library module). 

 In particular, [MariaDB 10.2](../what-is-mariadb-102/index) and 10.3 feature native JSON functions. In some cases, it is possible that these native functions can be used. However, mixing native and UDF JSON functions in the same query often does not work because the way they recognize their arguments is different and might even cause a server crash. 

 Here is the list of the CONNECT functions; more can be added if required.

 


| Name | Type | Return | Description | Added |
| --- | --- | --- | --- | --- |
| jbin\_array | Function | STRING\* | Make a JSON array containing its arguments. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_array\_add | Function | STRING\* | Adds to its first array argument its second arguments. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_array\_add\_values | Function | STRING\* | Adds to its first array argument all following arguments. |  |
| jbin\_array\_delete | Function | STRING\* | Deletes the nth element of its first array argument. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_file | Function | STRING\* | Returns of a (json) file contain. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_get\_item | Function | STRING\* | Access and returns a json item by a JPATH key. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_insert\_item | Function | STRING | Insert item values located to paths. |  |
| jbin\_item\_merge | Function | STRING\* | Merges two arrays or two objects. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_object | Function | STRING\* | Make a JSON object containing its arguments. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_object\_nonull | Function | STRING\* | Make a JSON object containing its not null arguments. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_object\_add | Function | STRING\* | Adds to its first object argument its second argument. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_object\_delete | Function | STRING\* | Deletes the nth element of its first object argument. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_object\_key | Function | STRING\* | Make a JSON object for key/value pairs. |  |
| jbin\_object\_list | Function | STRING\* | Returns the list of object keys as an array. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jbin\_set\_item | Function | STRING | Set item values located to paths. |  |
| jbin\_update\_item | Function | STRING | Update item values located to paths. |  |
| jfile\_bjson | Function | STRING | Convert a pretty=0 file to another BJson file. | [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/) |
| jfile\_convert | Function | STRING | Convert a Json file to another pretty=0 file. | [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/) |
| jfile\_make | Function | STRING | Make a json file from its json item first argument. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_array | Function | STRING | Make a JSON array containing its arguments. | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) until Connect 1.5 |
| json\_array\_add | Function | STRING | Adds to its first array argument its second arguments (before [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/), all following arguments). |  |
| json\_array\_add\_values | Function | STRING | Adds to its first array argument all following arguments. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_array\_delete | Function | STRING | Deletes the nth element of its first array argument. |  |
| json\_array\_grp | Aggregate | STRING | Makes JSON arrays from coming argument. |  |
| json\_file | Function | STRING | Returns the contains of (json) file. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_get\_item | Function | STRING | Access and returns a json item by a JPATH key. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_insert\_item | Function | STRING | Insert item values located to paths. |  |
| json\_item\_merge | Function | STRING | Merges two arrays or two objects. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_locate\_all | Function | STRING | Returns the JPATH’s of all occurrences of an element. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_make\_array | Function | STRING | Make a JSON array containing its arguments. | From Connect 1.6 |
| json\_make\_object | Function | STRING | Make a JSON object containing its arguments. | From Connect 1.6 |
| json\_object | Function | STRING | Make a JSON object containing its arguments. | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) until Connect 1.5 |
| json\_object\_delete | Function | STRING | Deletes the nth element of its first object argument. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_object\_grp | Aggregate | STRING | Makes JSON objects from coming arguments. |  |
| json\_object\_list | Function | STRING | Returns the list of object keys as an array. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_object\_nonull | Function | STRING | Make a JSON object containing its not null arguments. |  |
| json\_serialize | Function | STRING | Serializes the return of a “Jbin” function. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| json\_set\_item | Function | STRING | Set item values located to paths. |  |
| json\_update\_item | Function | STRING | Update item values located to paths. |  |
| jsonvalue | Function | STRING | Make a JSON value from its unique argument. Called json\_value until [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) and [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) |
| jsoncontains | Function | INTEGER | Returns 0 or 1 if an element is contained in the document. |  |
| jsoncontains\_path | Function | INTEGER | Returns 0 or 1 if a JPATH is contained in the document. |  |
| jsonget\_string | Function | STRING | Access and returns a string element by a JPATH key. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jsonget\_int | Function | INTEGER | Access and returns an integer element by a JPATH key. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jsonget\_real | Function | REAL | Access and returns a real element by a JPATH key. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |
| jsonlocate | Function | STRING | Returns the JPATH to access one element. | [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) |

 
String values are mapped to JSON strings. These strings are automatically escaped to conform to the JSON syntax. The automatic escaping is bypassed when the value has an alias beginning with ‘json\_’. This is automatically the case when a JSON UDF argument is another JSON UDF whose name begins with “json\_” (not case sensitive). This is why all functions that do not return a Json item are not prefixed by “json\_”.

 Argument string values, for some functions, can alternatively be json file names. When this is ambiguous, alias them as *jfile\_*. Full path should be used because UDF functions has no means to know what the current database is. Apparently, when the file name path is not full, it is based on the MariaDB data directory but I am not sure it is always true.

 Numeric values are (big) integers, double floating point values or decimal values. Decimal values are character strings containing a numeric representation and are treated as strings. Floating point values contain a decimal point and/or an exponent. Integers are written without decimal points.

 To install these functions execute the following commands :[[3](#_note-2)]

 
Note: Json function names are often written on this page with leading upper case letters for clarity. It is possible to do so in SQL queries because function names are case insensitive. However, when creating or dropping them, their names must match the case they are in the library module (lower case from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).

 
On Unix systems (from Connect 1.7.02):

 
```
create function jsonvalue returns string soname 'ha_connect.so';
create function json_make_array returns string soname 'ha_connect.so';
create function json_array_add_values returns string soname 'ha_connect.so';
create function json_array_add returns string soname 'ha_connect.so';
create function json_array_delete returns string soname 'ha_connect.so';
create function json_make_object returns string soname 'ha_connect.so';
create function json_object_nonull returns string soname 'ha_connect.so';
create function json_object_key returns string soname 'ha_connect.so';
create function json_object_add returns string soname 'ha_connect.so';
create function json_object_delete returns string soname 'ha_connect.so';
create function json_object_list returns string soname 'ha_connect.so';
create function json_object_values returns string soname 'ha_connect.so';
create function jsonset_grp_size returns integer soname 'ha_connect.so';
create function jsonget_grp_size returns integer soname 'ha_connect.so';
create aggregate function json_array_grp returns string soname 'ha_connect.so';
create aggregate function json_object_grp returns string soname 'ha_connect.so';
create function jsonlocate returns string soname 'ha_connect.so';
create function json_locate_all returns string soname 'ha_connect.so';
create function jsoncontains returns integer soname 'ha_connect.so';
create function jsoncontains_path returns integer soname 'ha_connect.so';
create function json_item_merge returns string soname 'ha_connect.so';
create function json_get_item returns string soname 'ha_connect.so';
create function jsonget_string returns string soname 'ha_connect.so';
create function jsonget_int returns integer soname 'ha_connect.so';
create function jsonget_real returns real soname 'ha_connect.so';
create function json_set_item returns string soname 'ha_connect.so';
create function json_insert_item returns string soname 'ha_connect.so';
create function json_update_item returns string soname 'ha_connect.so';
create function json_file returns string soname 'ha_connect.so';
create function jfile_make returns string soname 'ha_connect.so';
create function jfile_convert returns string soname 'ha_connect.so';
create function jfile_bjson returns string soname 'ha_connect.so';
create function json_serialize returns string soname 'ha_connect.so';
create function jbin_array returns string soname 'ha_connect.so';
create function jbin_array_add_values returns string soname 'ha_connect.so';
create function jbin_array_add returns string soname 'ha_connect.so';
create function jbin_array_delete returns string soname 'ha_connect.so';
create function jbin_object returns string soname 'ha_connect.so';
create function jbin_object_nonull returns string soname 'ha_connect.so';
create function jbin_object_key returns string soname 'ha_connect.so';
create function jbin_object_add returns string soname 'ha_connect.so';
create function jbin_object_delete returns string soname 'ha_connect.so';
create function jbin_object_list returns string soname 'ha_connect.so';
create function jbin_item_merge returns string soname 'ha_connect.so';
create function jbin_get_item returns string soname 'ha_connect.so';
create function jbin_set_item returns string soname 'ha_connect.so';
create function jbin_insert_item returns string soname 'ha_connect.so';
create function jbin_update_item returns string soname 'ha_connect.so';
create function jbin_file returns string soname 'ha_connect.so';

```

On Unix systems (from Connect 1.6):

 
```
create function jsonvalue returns string soname 'ha_connect.so';
create function json_make_array returns string soname 'ha_connect.so';
create function json_array_add_values returns string soname 'ha_connect.so';
create function json_array_add returns string soname 'ha_connect.so';
create function json_array_delete returns string soname 'ha_connect.so';
create function json_make_object returns string soname 'ha_connect.so';
create function json_object_nonull returns string soname 'ha_connect.so';
create function json_object_key returns string soname 'ha_connect.so';
create function json_object_add returns string soname 'ha_connect.so';
create function json_object_delete returns string soname 'ha_connect.so';
create function json_object_list returns string soname 'ha_connect.so';
create function jsonset_grp_size returns integer soname 'ha_connect.so';
create function jsonget_grp_size returns integer soname 'ha_connect.so';
create aggregate function json_array_grp returns string soname 'ha_connect.so';
create aggregate function json_object_grp returns string soname 'ha_connect.so';
create function jsonlocate returns string soname 'ha_connect.so';
create function json_locate_all returns string soname 'ha_connect.so';
create function jsoncontains returns integer soname 'ha_connect.so';
create function jsoncontains_path returns integer soname 'ha_connect.so';
create function json_item_merge returns string soname 'ha_connect.so';
create function json_get_item returns string soname 'ha_connect.so';
create function jsonget_string returns string soname 'ha_connect.so';
create function jsonget_int returns integer soname 'ha_connect.so';
create function jsonget_real returns real soname 'ha_connect.so';
create function json_set_item returns string soname 'ha_connect.so';
create function json_insert_item returns string soname 'ha_connect.so';
create function json_update_item returns string soname 'ha_connect.so';
create function json_file returns string soname 'ha_connect.so';
create function jfile_make returns string soname 'ha_connect.so';
create function json_serialize returns string soname 'ha_connect.so';
create function jbin_array returns string soname 'ha_connect.so';
create function jbin_array_add_values returns string soname 'ha_connect.so';
create function jbin_array_add returns string soname 'ha_connect.so';
create function jbin_array_delete returns string soname 'ha_connect.so';
create function jbin_object returns string soname 'ha_connect.so';
create function jbin_object_nonull returns string soname 'ha_connect.so';
create function jbin_object_key returns string soname 'ha_connect.so';
create function jbin_object_add returns string soname 'ha_connect.so';
create function jbin_object_delete returns string soname 'ha_connect.so';
create function jbin_object_list returns string soname 'ha_connect.so';
create function jbin_item_merge returns string soname 'ha_connect.so';
create function jbin_get_item returns string soname 'ha_connect.so';
create function jbin_set_item returns string soname 'ha_connect.so';
create function jbin_insert_item returns string soname 'ha_connect.so';
create function jbin_update_item returns string soname 'ha_connect.so';
create function jbin_file returns string soname 'ha_connect.so';

```

On Unix systems (from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/) until Connect 1.5):

 
```
create function jsonvalue returns string soname 'ha_connect.so';
create function json_array returns string soname 'ha_connect.so';
create function json_array_add_values returns string soname 'ha_connect.so';
create function json_array_add returns string soname 'ha_connect.so';
create function json_array_delete returns string soname 'ha_connect.so';
create function json_object returns string soname 'ha_connect.so';
create function json_object_nonull returns string soname 'ha_connect.so';
create function json_object_key returns string soname 'ha_connect.so';
create function json_object_add returns string soname 'ha_connect.so';
create function json_object_delete returns string soname 'ha_connect.so';
create function json_object_list returns string soname 'ha_connect.so';
create function jsonset_grp_size returns integer soname 'ha_connect.so';
create function jsonget_grp_size returns integer soname 'ha_connect.so';
create aggregate function json_array_grp returns string soname 'ha_connect.so';
create aggregate function json_object_grp returns string soname 'ha_connect.so';
create function jsonlocate returns string soname 'ha_connect.so';
create function json_locate_all returns string soname 'ha_connect.so';
create function jsoncontains returns integer soname 'ha_connect.so';
create function jsoncontains_path returns integer soname 'ha_connect.so';
create function json_item_merge returns string soname 'ha_connect.so';
create function json_get_item returns string soname 'ha_connect.so';
create function jsonget_string returns string soname 'ha_connect.so';
create function jsonget_int returns integer soname 'ha_connect.so';
create function jsonget_real returns real soname 'ha_connect.so';
create function json_set_item returns string soname 'ha_connect.so';
create function json_insert_item returns string soname 'ha_connect.so';
create function json_update_item returns string soname 'ha_connect.so';
create function json_file returns string soname 'ha_connect.so';
create function jfile_make returns string soname 'ha_connect.so';
create function json_serialize returns string soname 'ha_connect.so';
create function jbin_array returns string soname 'ha_connect.so';
create function jbin_array_add_values returns string soname 'ha_connect.so';
create function jbin_array_add returns string soname 'ha_connect.so';
create function jbin_array_delete returns string soname 'ha_connect.so';
create function jbin_object returns string soname 'ha_connect.so';
create function jbin_object_nonull returns string soname 'ha_connect.so';
create function jbin_object_key returns string soname 'ha_connect.so';
create function jbin_object_add returns string soname 'ha_connect.so';
create function jbin_object_delete returns string soname 'ha_connect.so';
create function jbin_object_list returns string soname 'ha_connect.so';
create function jbin_item_merge returns string soname 'ha_connect.so';
create function jbin_get_item returns string soname 'ha_connect.so';
create function jbin_set_item returns string soname 'ha_connect.so';
create function jbin_insert_item returns string soname 'ha_connect.so';
create function jbin_update_item returns string soname 'ha_connect.so';
create function jbin_file returns string soname 'ha_connect.so';

```

On WIndows (from Connect 1.7.02):

 
```
create function jsonvalue returns string soname 'ha_connect';
create function json_make_array returns string soname 'ha_connect';
create function json_array_add_values returns string soname 'ha_connect';
create function json_array_add returns string soname 'ha_connect';
create function json_array_delete returns string soname 'ha_connect';
create function json_make_object returns string soname 'ha_connect';
create function json_object_nonull returns string soname 'ha_connect';
create function json_object_key returns string soname 'ha_connect';
create function json_object_add returns string soname 'ha_connect';
create function json_object_delete returns string soname 'ha_connect';
create function json_object_list returns string soname 'ha_connect';
create function json_object_values returns string soname 'ha_connect';
create function jsonset_grp_size returns integer soname 'ha_connect';
create function jsonget_grp_size returns integer soname 'ha_connect';
create aggregate function json_array_grp returns string soname 'ha_connect';
create aggregate function json_object_grp returns string soname 'ha_connect';
create function jsonlocate returns string soname 'ha_connect';
create function json_locate_all returns string soname 'ha_connect';
create function jsoncontains returns integer soname 'ha_connect';
create function jsoncontains_path returns integer soname 'ha_connect';
create function json_item_merge returns string soname 'ha_connect';
create function json_get_item returns string soname 'ha_connect';
create function jsonget_string returns string soname 'ha_connect';
create function jsonget_int returns integer soname 'ha_connect';
create function jsonget_real returns real soname 'ha_connect';
create function json_set_item returns string soname 'ha_connect';
create function json_insert_item returns string soname 'ha_connect';
create function json_update_item returns string soname 'ha_connect';
create function json_file returns string soname 'ha_connect';
create function jfile_make returns string soname 'ha_connect';
create function jfile_convert returns string soname 'ha_connect';
create function jfile_bjson returns string soname 'ha_connect';
create function json_serialize returns string soname 'ha_connect';
create function jbin_array returns string soname 'ha_connect';
create function jbin_array_add_values returns string soname 'ha_connect';
create function jbin_array_add returns string soname 'ha_connect';
create function jbin_array_delete returns string soname 'ha_connect';
create function jbin_object returns string soname 'ha_connect';
create function jbin_object_nonull returns string soname 'ha_connect';
create function jbin_object_key returns string soname 'ha_connect';
create function jbin_object_add returns string soname 'ha_connect';
create function jbin_object_delete returns string soname 'ha_connect';
create function jbin_object_list returns string soname 'ha_connect';
create function jbin_item_merge returns string soname 'ha_connect';
create function jbin_get_item returns string soname 'ha_connect';
create function jbin_set_item returns string soname 'ha_connect';
create function jbin_insert_item returns string soname 'ha_connect';
create function jbin_update_item returns string soname 'ha_connect';
create function jbin_file returns string soname 'ha_connect';

```

On WIndows (from Connect 1.6):

 
```
create function jsonvalue returns string soname 'ha_connect';
create function json_make_array returns string soname 'ha_connect';
create function json_array_add_values returns string soname 'ha_connect';
create function json_array_add returns string soname 'ha_connect';
create function json_array_delete returns string soname 'ha_connect';
create function json_make_object returns string soname 'ha_connect';
create function json_object_nonull returns string soname 'ha_connect';
create function json_object_key returns string soname 'ha_connect';
create function json_object_add returns string soname 'ha_connect';
create function json_object_delete returns string soname 'ha_connect';
create function json_object_list returns string soname 'ha_connect';
create function jsonset_grp_size returns integer soname 'ha_connect';
create function jsonget_grp_size returns integer soname 'ha_connect';
create aggregate function json_array_grp returns string soname 'ha_connect';
create aggregate function json_object_grp returns string soname 'ha_connect';
create function jsonlocate returns string soname 'ha_connect';
create function json_locate_all returns string soname 'ha_connect';
create function jsoncontains returns integer soname 'ha_connect';
create function jsoncontains_path returns integer soname 'ha_connect';
create function json_item_merge returns string soname 'ha_connect';
create function json_get_item returns string soname 'ha_connect';
create function jsonget_string returns string soname 'ha_connect';
create function jsonget_int returns integer soname 'ha_connect';
create function jsonget_real returns real soname 'ha_connect';
create function json_set_item returns string soname 'ha_connect';
create function json_insert_item returns string soname 'ha_connect';
create function json_update_item returns string soname 'ha_connect';
create function json_file returns string soname 'ha_connect';
create function jfile_make returns string soname 'ha_connect';
create function json_serialize returns string soname 'ha_connect';
create function jbin_array returns string soname 'ha_connect';
create function jbin_array_add_values returns string soname 'ha_connect';
create function jbin_array_add returns string soname 'ha_connect';
create function jbin_array_delete returns string soname 'ha_connect';
create function jbin_object returns string soname 'ha_connect';
create function jbin_object_nonull returns string soname 'ha_connect';
create function jbin_object_key returns string soname 'ha_connect';
create function jbin_object_add returns string soname 'ha_connect';
create function jbin_object_delete returns string soname 'ha_connect';
create function jbin_object_list returns string soname 'ha_connect';
create function jbin_item_merge returns string soname 'ha_connect';
create function jbin_get_item returns string soname 'ha_connect';
create function jbin_set_item returns string soname 'ha_connect';
create function jbin_insert_item returns string soname 'ha_connect';
create function jbin_update_item returns string soname 'ha_connect';
create function jbin_file returns string soname 'ha_connect';

```

On WIndows (until Connect 1.5):

 
```
create function jsonvalue returns string soname 'ha_connect';
create function json_array returns string soname 'ha_connect';
create function json_array_add_values returns string soname 'ha_connect';
create function json_array_add returns string soname 'ha_connect';
create function json_array_delete returns string soname 'ha_connect';
create function json_object returns string soname 'ha_connect';
create function json_object_nonull returns string soname 'ha_connect';
create function json_object_key returns string soname 'ha_connect';
create function json_object_add returns string soname 'ha_connect';
create function json_object_delete returns string soname 'ha_connect';
create function json_object_list returns string soname 'ha_connect';
create function jsonset_grp_size returns integer soname 'ha_connect';
create function jsonget_grp_size returns integer soname 'ha_connect';
create aggregate function json_array_grp returns string soname 'ha_connect';
create aggregate function json_object_grp returns string soname 'ha_connect';
create function jsonlocate returns string soname 'ha_connect';
create function json_locate_all returns string soname 'ha_connect';
create function jsoncontains returns integer soname 'ha_connect';
create function jsoncontains_path returns integer soname 'ha_connect';
create function json_item_merge returns string soname 'ha_connect';
create function json_get_item returns string soname 'ha_connect';
create function jsonget_string returns string soname 'ha_connect';
create function jsonget_int returns integer soname 'ha_connect';
create function jsonget_real returns real soname 'ha_connect';
create function json_set_item returns string soname 'ha_connect';
create function json_insert_item returns string soname 'ha_connect';
create function json_update_item returns string soname 'ha_connect';
create function json_file returns string soname 'ha_connect';
create function jfile_make returns string soname 'ha_connect';
create function json_serialize returns string soname 'ha_connect';
create function jbin_array returns string soname 'ha_connect';
create function jbin_array_add_values returns string soname 'ha_connect';
create function jbin_array_add returns string soname 'ha_connect';
create function jbin_array_delete returns string soname 'ha_connect';
create function jbin_object returns string soname 'ha_connect';
create function jbin_object_nonull returns string soname 'ha_connect';
create function jbin_object_key returns string soname 'ha_connect';
create function jbin_object_add returns string soname 'ha_connect';
create function jbin_object_delete returns string soname 'ha_connect';
create function jbin_object_list returns string soname 'ha_connect';
create function jbin_item_merge returns string soname 'ha_connect';
create function jbin_get_item returns string soname 'ha_connect';
create function jbin_set_item returns string soname 'ha_connect';
create function jbin_insert_item returns string soname 'ha_connect';
create function jbin_update_item returns string soname 'ha_connect';
create function jbin_file returns string soname 'ha_connect';

```

### Jfile\_Bjson

 
**MariaDB starting with [10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/)**JFile\_Bjson was introduced in [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/) and [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/).

 

```
Jfile_Bjson(in_file_name, out_file_name, lrecl)

```

Converts the first argument pretty=0 json file to Bjson file. B(inary)json is a pre-parsed json format. It is described below in the Performance chapter (available in next Connect versions).

 ### Jfile\_Convert

 
**MariaDB starting with [10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/)**JFile\_Convert was introduced in [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/) and [MariaDB 10.2.36](https://mariadb.com/kb/en/mariadb-10236-release-notes/).

 

```
Jfile_Convert(in_file_name, out_file_name, lrecl)

```

Converts the first argument json file to another *pretty=0* json file. The third integer argument is the record length to use. This is often required to process huge json files that would be very slow if they were in *pretty=2* format.

 This is done without completely parsing the file, is very fast and requires no big memory.

 ### Jfile\_Make

 
**MariaDB starting with [10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)**Jfile\_Make was added in CONNECT 1.4 (from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).

 

```
Jfile_Make(arg1, arg2, [arg3], …)

```

The first argument must be a json item (if it is just a string, Jfile\_Make will try its best to see if it is a json item or an input file name). The following arguments are a string file name and an integer pretty value (defaulting to 2) in any order. This function creates a json file containing the first argument item.

 The returned string value is the created file name. If not specified as an argument, the file name can in some cases be retrieved from the first argument; in such cases the file itself is modified. 

 This function can be used to create or format a json file. For instance, supposing we want to format the file tb.json, this can be done with the query:

 
```
select Jfile_Make('tb.json' jfile_, 2);

```

The tb.json file will be changed to:

 
```
[
  {
    "_id": 5,
    "type": "food",
    "ratings": [
      5,
      8,
      9
    ]
  },
  {
    "_id": 6,
    "type": "car",
    "ratings": [
      5,
      9
    ]
  }
]

```

### Json\_Array\_Add

 
```
Json_Array_Add(arg1, arg2, [arg3][, arg4][, ...])

```

Note: In CONNECT version 1.3 (before [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)), this function behaved like the new `Json_Array_Add_Values` function. The following describes this function for CONNECT version 1.4 (from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)) only. The first argument must be a JSON array. The second argument is added as member of this array. For example:

 
```
select Json_Array_Add(Json_Array(56,3.1416,'machin',NULL),
'One more') Array;

```




| Array |
| --- |
| [56,3.141600,"machin",null,"One more"] |

 
Note: The first array is not escaped, its (alias) name beginning with ‘json\_’.

 Now we can see how adding an author to the JSAMPLE2 table can alternatively be done:

 
```
update jsample2 set 
  json_author = json_array_add(json_author, json_object('Charles' FIRSTNAME, 'Dickens' LASTNAME)) 
  where isbn = '9782840825685';

```

Note: Calling a column returning JSON a name prefixed by json\_ (like json\_author here) is good practice and removes the need to give it an alias to prevent escaping when used as an argument.

 Additional arguments: If a third integer argument is given, it specifies the position (zero based) of the added value:

 
```
select Json_Array_Add('[5,3,8,7,9]' json_, 4, 2) Array;

```




| Array |
| --- |
| [5,3,4,8,7,9] |

 
If a string argument is added, it specifies the Json path to the array to be modified. For instance:

 
```
select Json_Array_Add('{"a":1,"b":2,"c":[3,4]}' json_, 5, 1, 'c');

```




| Json\_Array\_Add('{"a":1,"b":2,"c":[3, 4]}' json\_, 5, 1, 'c') |
| --- |
| {"a":1,"b":2,"c":[3,5,4]} |

 
### Json\_Array\_Add\_Values

 Json\_Array\_Add\_Values added in CONNECT 1.4 replaces the function Json\_Array\_Add of CONNECT version 1.3 (before [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).

 
```
Json_Array_Add_Values(arg, arglist)

```

The first argument must be a JSON array string. Then all other arguments are added as members of this array. For example:

 
```
select Json_Array_Add_Values
  (Json_Array(56, 3.1416, 'machin', NULL), 'One more', 'Two more') Array;

```




| Array |
| --- |
| [56,3.141600,"machin",null,"One more","Two more"] |

 
### Json\_Array\_Delete

 
```
Json_Array_Delete(arg1, arg2 [,arg3] [...])

```

The first argument should be a JSON array. The second argument is an integer indicating the rank (0 based conforming to general json usage) of the element to delete. For example:

 
```
select Json_Array_Delete(Json_Array(56,3.1416,'foo',NULL),1) Array;

```




| Array |
| --- |
| [56,"foo",null] |

 
Now we can see how to delete the second author from the JSAMPLE2 table:

 
```
update jsample2 set json_author = json_array_delete(json_author, 1) 
  where isbn = '9782840825685';

```

A Json path can be specified as a third string argument 

 ### Json\_Array\_Grp

 
```
Json_Array_Grp(arg)

```

This is an aggregate function that makes an array filled from values coming from the rows retrieved by a query. Let us suppose we have the pet table:

 


| name | race | number |
| --- | --- | --- |
| John | dog | 2 |
| Bill | cat | 1 |
| Mary | dog | 1 |
| Mary | cat | 1 |
| Lisbeth | rabbit | 2 |
| Kevin | cat | 2 |
| Kevin | bird | 6 |
| Donald | dog | 1 |
| Donald | fish | 3 |

 
The query:

 
```
select name, json_array_grp(race) from pet group by name;

```

will return:

 


|  |  |
| --- | --- |
| name | json\_array\_grp(race) |
| Bill | ["cat"] |
| Donald | ["dog","fish"] |
| John | ["dog"] |
| Kevin | ["cat","bird"] |
| Lisbeth | ["rabbit"] |
| Mary | ["dog","cat"] |

 
One problem with the JSON aggregate functions is that they construct their result in memory and cannot know the needed amount of storage, not knowing the number of rows of the used table.

 Therefore, the number of values for each group is limited. This limit is the value of JsonGrpSize whose default value is 10 but can be set using the JsonSet\_Grp\_Size function. Nevertheless, working on a larger table is possible, but only after setting JsonGrpSize to the ceiling of the number of rows per group for the table. Try not to set it to a very large value to avoid memory exhaustion.

 ### JsonContains

 
```
JsonContains(json_doc, item [, int])<

```

This function can be used to check whether an item is contained in a document. Its arguments are the same than the ones of the JsonLocate function; only the return value changes. The integer returned value is 1 is the item is contained in the document or 0 otherwise.

 ### JsonContains\_Path

 
```
JsonContains_Path(json_doc, path)

```

This function can be used to check whether a Json path is contained in the document. The integer returned value is 1 is the path is contained in the document or 0 otherwise.

 ### Json\_File

 
```
Json_File(arg1, [arg2, [arg3]], …)

```

The first argument must be a file name. This function returns the text of the file that is supposed to be a json file. If only one argument is specified, the file text is returned without being parsed. Up to two additional arguments can be specified:

 A string argument is the path to the sub-item to be returned. An integer argument specifies the pretty format value of the file.

 This function is chiefly used to get the json item argument of other json functions from a json file. For instance, supposing the file tb.json is:

 
```
{ "_id" : 5, "type" : "food", "ratings" : [ 5, 8, 9 ] }
{ "_id" : 6, "type" : "car", "ratings" : [ 5, 9 ] }

```

Extracting a value from it can be done with a query such as:

 
```
select JsonGet_String(Json_File('tb.json', 0), '[1]:type') "Type";

```

or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 
```
select JsonGet_String(Json_File('tb.json', 0), '$[1].type') "Type";

```

This query returns:

 


| Type |
| --- |
| car |

 
However, we’ll see that, most of the time, it is better to use Jbin\_File or to directly specify the file name in queries. In particular this function should not be used for queries that must modify the json item because, even if the modified json is returned, the file itself would be unchanged.

 ### Json\_Get\_Item

 
**MariaDB starting with [10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)**Json\_Get\_Item was added in CONNECT 1.4 (from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).

 

```
Json_Get_Item(arg1, arg2, …)

```

This function returns a subset of the json document passed as first argument. The second argument is the json path of the item to be returned and should be one returning a json item (terminated by a ‘\*’). If not, the function will try to make it right but this is not foolproof. For instance:

 
```
select Json_Get_Item(Json_Object('foo' as "first", Json_Array('a', 33) 
  as "json_second"), 'second') as "item";

```

The correct path should have been ‘second:\*’ (or from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), ‘second.\*’), but in this simple case the function was able to make it right. The returned item:

 


| item |
| --- |
| ["a",33] |

 
Note: The array is aliased “json\_second” to indicate it is a json item and avoid escaping it. However, the “json\_” prefix is skipped when making the object and must not be added to the path.

 ### JsonGet\_Grp\_Size

 
```
JsonGet_Grp_Size(val)

```

This function returns the JsonGrpSize value.

 ### JsonGet\_String / JsonGet\_Int / JsonGet\_Real

 
**MariaDB starting with [10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)**JsonGet\_String, JsonGet\_Int and JsonGet\_Real were added in CONNECT 1.4 (from [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/)).

 

```
JsonGet_String(arg1, arg2, [arg3] …)
JsonGet_Int(arg1, arg2, [arg3] …)
JsonGet_Real(arg1, arg2, [arg3] …)

```

The first argument should be a JSON item. If it is a string with no alias, it will be converted as a json item. The second argument is the path of the item to be located in the first argument and returned, eventually converted according to the used function. For example:

 
```
select 
JsonGet_String('{"qty":7,"price":29.50,"garanty":null}','price') "String",
JsonGet_Int('{"qty":7,"price":29.50,"garanty":null}','price') "Int",
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price') "Real";

```

This query returns:

 


| String | Int | Real |
| --- | --- | --- |
| 29.50 | 29 | 29.500000000000000 |

 
The function *JsonGet\_Real* can be given a third argument to specify the number of decimal digits of the returned value. For instance:

 
```
select 
JsonGet_Real('{"qty":7,"price":29.50,"garanty":null}','price',4) "Real";

```

This query returns:

 


| String |
| --- |
| 29.50 |

 
The given path can specify all operators for arrays except the “expand” [X] operator (or from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), the“expand” [\*] operator). For instance:

 
```
select 
JsonGet_Int(Json_Array(45,28,36,45,89), '[4]') "Rank",
JsonGet_Int(Json_Array(45,28,36,45,89), '[#]') "Number",
JsonGet_String(Json_Array(45,28,36,45,89), '[","]') "Concat",
JsonGet_Int(Json_Array(45,28,36,45,89), '[+]') "Sum",
JsonGet_Real(Json_Array(45,28,36,45,89), '[!]', 2) "Avg";

```

The result:

 


| Rank | Number | Concat | Sum | Avg |
| --- | --- | --- | --- | --- |
| 89 | 5 | 45,28,36,45,89 | 243 | 48.60 |

 
### Json\_Item\_Merge

 
```
Json_Item_Merge(arg1, arg2, …)

```

This function merges two arrays or two objects. For arrays, this is done by adding to the first array all the values of the second array. For instance:

 
```
select Json_Item_Merge(Json_Array('a','b','c'), Json_Array('d','e','f')) as "Result"; 

```

The function returns:

 


| Result |
| --- |
| ["a","b","c","d","e","f"] |

 
For objects, the pairs of the second object are added to the first object if the key does not yet exist in it; otherwise the pair of the first object is set with the value of the matching pair of the second object. For instance:

 
```
select Json_Item_Merge(Json_Object(1 "a", 2 "b", 3 "c"), Json_Object(4 "d",5 "b",6 "f")) 
  as "Result"; 

```

The function returns:

 


| Result |
| --- |
| {"a":1,"b":5,"c":3,"d":4,"f":6} |

 
### JsonLocate

 
```
JsonLocate(arg1, arg2, [arg3], …):

```

The first argument must be a JSON tree. The second argument is the item to be located. The item to be located can be a constant or a json item. Constant values must be equal in type and value to be found. This is "shallow equality" – strings, integers and doubles won't match. 

 This function returns the json path to the located item or null if it is not found. For example:

 
```
select JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, 
  {"FN":"Jack", "LN":"London"}]}' json_, 'Jack') Path;

```

This query returns:

 


| Path |
| --- |
| AUTHORS:[1]:FN |

 
or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 


| Path |
| --- |
| $.AUTHORS[1].FN |

 
The path syntax is the same used in JSON CONNECT tables.

 By default, the path of the first occurrence of the item is returned. The third parameter can be used to specify the occurrence whose path is to be returned. For instance:

 
```
select 
JsonLocate('[45,28,[36,45],89]',45) first,
JsonLocate('[45,28,[36,45],89]',45,2) second,
JsonLocate('[45,28,[36,45],89]',45.0) `wrong type`,
JsonLocate('[45,28,[36,45],89]','[36,45]' json_) json;

```




| first | second | wrong type | json |
| --- | --- | --- | --- |
| [0] | [2]:[1] | <null> | [2] |

 
or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 


| first | second | wrong type | json |
| --- | --- | --- | --- |
| $[0] | $[2][1] | <null> | $[2] |

 
For string items, the comparison is case sensitive by default. However, it is possible to specify a string to be compared case insensitively by giving it an alias beginning by “ci”:

 
```
select JsonLocate('{"AUTHORS":[{"FN":"Jules", "LN":"Verne"}, 
  {"FN":"Jack", "LN":"London"}]}' json_, 'VERNE' ci) Path;

```




| Path |
| --- |
| AUTHORS:[0]:LN |

 
or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 


| Path |
| --- |
| $.AUTHORS[0].LN |

 
### Json\_Locate\_All

 
```
Json_Locate_All(arg1, arg2, [arg3], …):

```

The first argument must be a JSON item. The second argument is the item to be located. This function returns the paths to all locations of the item as an array of strings. For example:

 
```
select Json_Locate_All('[[45,28],[[36,45],89]]',45);

```

This query returns:

 


| All paths |
| --- |
| ["[0]:[0]","[1]:[0]:[1]"] |

 
or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 


| All paths |
| --- |

 ["$[0][0]","$[1][0][1]"]

 
The returned array can be applied other functions. For instance, to get the number of occurrences of an item in a json tree, you can do:

 
```
select JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '[#]') "Nb of occurs";

```

or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 
```
select JsonGet_Int(Json_Locate_All('[[45,28],[[36,45],89]]',45), '$[#]') "Nb of occurs";

```

The displayed result:

 


| Nb of occurs |
| --- |
| 2 |

 
If specified, the third integer argument set the depth to search in the document. This means the maximum items in the paths (until [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), the number of ‘:’ separator characters in them plus one). This value defaults to 10 but can be increased for complex documents or reduced to set the maximum wanted depth of the returned paths.

 ### Json\_Make\_Array

 
```
Json_Make_Array(val1, …, valn)

```

This function was named “Json\_Array” in previous versions of CONNECT. It was renamed because [MariaDB 10.2](../what-is-mariadb-102/index) features native JSON functions including a [Json\_Array](../json_array/index) function. The native function does almost the same as the UDF one, but does not accept CONNECT-specific arguments such as the result from JBIN functions.

 Json\_Make\_Array returns a string denoting a JSON array with all its arguments as members. For example:

 
```
select Json_Make_Array(56, 3.1416, 'My name is "Foo"', NULL);

```




| Json\_Make\_Array(56, 3.1416, 'My name is "Foo"',N ULL) |
| --- |
| [56,3.141600,"My name is \"Foo\"",null] |

 
Note: The argument list can be void. If so, a void array is returned.

 This function was named “Json\_Array” in previous versions of CONNECT. It was renamed because [MariaDB 10.2](../what-is-mariadb-102/index) features native JSON functions including a “Json\_Array” function. The native function does almost the same as the UDF one but does not accept CONNECT specific arguments such as the result from JBIN functions.

 ### Json\_Make\_Object

 
```
Json_Make_Object(arg1, …, argn)

```

This function was named “Json\_Object” in previous versions of CONNECT. It was renamed because [MariaDB 10.2](../what-is-mariadb-102/index) features native JSON functions including a [Json\_Object](../json_object/index) function. The native function does what the UDF Json\_Object\_Key does. 

 Json\_Make\_Object returns a string denoting a JSON object. For instance:

 
```
select Json_Make_Object(56, 3.1416, 'machin', NULL);

```

The object is filled with pairs corresponding to the given arguments. The key of each pair is made from the argument (default or specified) alias. 

 


| Json\_Make\_Object(56, 3.1416, 'machin', NULL) |
| --- |
| {"56":56,"3.1416":3.141600,"machin":"machin","NULL":null} |

 
When needed, it is possible to specify the keys by giving an alias to the arguments:

 
```
select Json_Make_Object(56 qty, 3.1416 price, 'machin' truc, NULL garanty);

```




| Json\_Make\_Object(56 qty,3.1416 price,'machin' truc, NULL garanty) |
| --- |
| {"qty":56,"price":3.141600,"truc":"machin","garanty":null} |

 
If the alias is prefixed by ‘json\_’ (to prevent escaping) the key name is stripped from that prefix.

 This function is chiefly useful when entering values retrieved from a table, the key being by default the column name:

 
```
select Json_Make_Object(matricule, nom, titre, salaire) from connect.employe where nom = 'PANTIER';

```




| Json\_Make\_Object(matricule, nom, titre, salaire) |
| --- |
| {"matricule":40567,"nom":"PANTIER","titre":"DIRECTEUR","salaire":14000.000000} |

 
This function was named “Json\_Object” in previous versions of CONNECT. It was renamed because [MariaDB 10.2](../what-is-mariadb-102/index) features native JSON functions including a “Json\_Object” function. The native function does what the UDF Json\_Object\_Key does. 

 ### Json\_Object\_Add

 
```
Json_Object_Add(arg1, arg2, [arg3] …)

```

The first argument must be a JSON object. The second argument is added as a pair to this object. For example:

 
```
select Json_Object_Add
  ('{"item":"T-shirt","qty":27,"price":24.99}' json_old,'blue' color) newobj;

```




| newobj |
| --- |
| {"item":"T-shirt","qty":27,"price":24.990000,"color":"blue"} |

 
Note: If the specified key already exists in the object, its value is replaced by the new one.

 The third string argument is a Json path to the target object.

 ### Json\_Object\_Delete

 
```
Json_Object_Delete(arg1, arg2, [arg3] …):

```

The first argument must be a JSON object. The second argument is the key of the pair to delete. For example:

 
```
select Json_Object_Delete('{"item":"T-shirt","qty":27,"price":24.99}' json_old, 'qty') newobj;

```




| newobj |
| --- |
| {"item":"T-shirt","price":24.99} |

 
The third string argument is a Json path to the object to be the target of deletion.

 ### Json\_Object\_Grp

 
```
Json_Object_Grp(arg1,arg2)

```

This function works like Json\_Array\_Grp. It makes a JSON object filled with value pairs whose keys are passed from its first argument and values are passed from its second argument.

 This can be seen with the query:

 
```
select name, json_object_grp(number,race) from pet group by name;

```

This query returns:

 


| name | json\_object\_grp(number,race) |
| --- | --- |
| Bill | {"cat":1} |
| Donald | {"dog":1,"fish":3} |
| John | {"dog":2} |
| Kevin | {"cat":2,"bird":6} |
| Lisbeth | {"rabbit":2} |
| Mary | {"dog":1,"cat":1} |

 
### Json\_Object\_Key

 
```
Json_Object_Key([key1, val1 [, …, keyn, valn]])

```

Return a string denoting a JSON object. For instance:

 
```
select Json_Object_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL);

```

The object is filled with pairs made from each key/value arguments.

 


| Json\_Object\_Key('qty', 56, 'price', 3.1416, 'truc', 'machin', 'garanty', NULL) |
| --- |
| {"qty":56,"price":3.141600,"truc":"machin","garanty":null} |

 
### Json\_Object\_List

 
```
Json_Object_List(arg1, …):

```

The first argument must be a JSON object. This function returns an array containing the list of all keys existing in the object. For example:

 
```
select Json_Object_List(Json_Object(56 qty,3.1416 price,'machin' truc, NULL garanty))
  "Key List";

```




| Key List |
| --- |
| ["qty","price","truc","garanty"] |

 
### Json\_Object\_Nonull

 
```
Json_Object_Nonull(arg1, …, argn)

```

This function works like [Json\_Make\_Object](#json_make_object) but “null” arguments are ignored and not inserted in the object. Arguments are regarded as “null” if they are JSON null values, void arrays or objects, or arrays or objects containing only null members.

 It is mainly used to avoid constructing useless null items when converting tables (see later).

 ### Json\_Object\_Values

 
```
Json_Object_Values(json_object)

```

The first argument must be a JSON object. This function returns an array containing the list of all values existing in the object. For example:

 
```
select Json_Object_Values('{"One":1,"Two":2,"Three":3}') "Value List";

```




| Value List |
| --- |
| [1,2,3] |

 
### JsonSet\_Grp\_Size

 
```
JsonSet_Grp_Size(val)

```

This function is used to set the JsonGrpSize value. This value is used by the following aggregate functions as a ceiling value of the number of items in each group. It returns the JsonGrpSize value that can be its default value when passed 0 as argument. 

 ### Json\_Set\_Item / Json\_Insert\_Item / Json\_Update\_Item

 
```
Json_{Set | Insert | Update}_Item(json_doc, [item, path [, val, path …]])

```

These functions insert or update data in a JSON document and return the result. The value/path pairs are evaluated left to right. The document produced by evaluating one pair becomes the new value against which the next pair is evaluated.

 * Json\_Set\_Item replaces existing values and adds non-existing values.
* Json\_Insert\_Item inserts values without replacing existing values.
* Json\_Update\_Item replaces only existing values.

 Example:

 
```
set @j = Json_Array(1, 2, 3, Json_Object_Key('quatre', 4));
select Json_Set_Item(@j, 'foo', '[1]', 5, '[3]:cinq') as "Set",
Json_Insert_Item(@j, 'foo', '[1]', 5, '[3]:cinq') as "Insert",
Json_Update_Item(@j, 'foo', '[1]', 5, '[3]:cinq') as "Update";

```

or, from [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/):

 
```
set @j = Json_Array(1, 2, 3, Json_Object_Key('quatre', 4));
select Json_Set_Item(@j, 'foo', '$[1]', 5, '$[3].cinq') as "Set",
Json_Insert_Item(@j, 'foo', '$[1]', 5, '$[3].cinq') as "Insert",
Json_Update_Item(@j, 'foo', '$[1]', 5, '$[3].cinq') as "Update";

```

This query returns:

 


| Set | Insert | Update |
| --- | --- | --- |
| [1,"foo",3,{"quatre":4,"cinq":5}] | [1,2,3,{"quatre":4,"cinq":5}] | [1,"foo",3,{"quatre":4}] |

 
### JsonValue

 
```
JsonValue (val)

```

Returns a JSON value as a string, for instance:

 
```
select JsonValue(3.1416);

```




| JsonValue(3.1416) |
| --- |
| 3.141600 |

 
Before [MariaDB 10.1.9](https://mariadb.com/kb/en/mariadb-1019-release-notes/), this function was called Json\_Value, but was renamed to avoid clashing with the [JSON\_VALUE](../json_value/index) function. 

 The “JBIN” return type
----------------------

 Almost all functions returning a json string - whose name begins with *Json\_* - have a counterpart with a name beginning with *Jbin\_*. This is both for performance (speed and memory) as well as for better control of what the functions should do.

 This is due to the way CONNECT UDFs work internally. The Json functions, when receiving json strings as parameters, parse them and construct a binary tree in memory. They work on this tree and before returning; serialize this tree to return a new json string.

 If the json document is large, this can take up a large amount of time and storage space. It is all right when one simple json function is called – it must be done anyway – but is a waste of time and memory when json functions are used as parameters to other json functions.

 To avoid multiple serializing and parsing, the Jbin functions should be used as parameters to other functions. Indeed, they do not serialize the memory document tree, but return a structure allowing the receiving function to have direct access to the memory tree. This saves the serialize-parse steps otherwise needed to pass the argument and removes the need to reallocate the memory of the binary tree, which by the way is 6 to 7 times the size of the json string. For instance:

 
```
select Json_Object(Jbin_Array_Add(Jbin_Array('a','b','c'), 'd') as "Jbin_foo") as "Result";

```

This query returns:

 


| Result |
| --- |
| {"foo":["a","b","c","d"]} |

 
Here the binary json tree allocated by *Jbin\_Array* is completed by *Jbin\_Array\_Add* and *Json\_Object* and serialized only once to make the final result string. It would be serialized and parsed two more times if using “Json” functions.

 Note that Jbin results are recognized as such because they are aliased beginning with “Jbin\_”. This is why in the *Json\_Object* function the alias is specified as “Jbin\_foo”.

 What happens if it is not recognized as such? These functions are declared as returning a string and to take care of this, the returned structure begins with a zero-terminated string. For instance:

 
```
select Jbin_Array('a','b','c');

```

This query replies:

 


| Jbin\_Array('a','b','c') |
| --- |
| Binary Json array |

 
Note: When testing, the tree returned by a “Jbin” function can be seen using the *Json\_Serialize* function whose unique parameter must be a “Jbin” result. For instance:

 
```
select Json_Serialize(Jbin_Array('a','b','c'));

```

This query returns:

 


| Json\_Serialize(Jbin\_Array('a','b','c')) |
| --- |
| ["a","b","c"] |

 
Note: For this simple example, this is equivalent to using the *Json\_Array* function.

 ### Using a file as json UDF first argument

 We have seen that many json UDFs can have an additional argument not yet described. This is in the case where the json item argument was referring to a file. Then the additional integer argument is the pretty value of the json file. It matters only when the first argument is just a file name (to make the UDF understand this argument is a file name, it should be aliased with a name beginning with jfile\_) or if the function modifies the file, in which case it will be rewritten with this pretty format. 

 The json item is created by extracting the required part from the file. This can be the whole file but more often only some of it. There are two ways to specify the sub-item of the file to be used:

 1. Specifying it in the *Json\_File* or *Jbin\_File* arguments.
2. Specifying it in the receiving function (not possible for all functions).

 It doesn’t make any difference when the *Jbin\_File* is used but it does with *Json\_File*. For instance:

 
```
select Jfile_Make('{"a":1, "b":[44, 55]}' json_, 'test.json');
select Json_Array_Add(Json_File('test.json', 'b'), 66);

```

The second query returns:

 


| Json\_Array\_Add(Json\_File('test.json', 'b'), 66) |
| --- |
| [44,55,66] |

 
It just returns the – modified -- subset returned by the Json\_File function, while the query:

 
```
select Json_Array_Add(Json_File('test.json'), 66, 'b');

```

returns what was received from *Json\_File* with the modification made on the subset.

 


| Json\_Array\_Add(Json\_File('test.json'), 66, 'b') |
| --- |
| {"a":1,"b":[44,55,66]} |

 
Note that in both case the test.json file is not modified. This is because the *Json\_File* function returns a string representing all or part of the file text but no information about the file name. This is all right to check what would be the effect of the modification to the file.

 However, to have the file modified, use the *Jbin\_File* function or directly give the file name. *Jbin\_File* returns a structure containing the file name, a pointer to the file parsed tree and eventually a pointer to the subset when a path is given as a second argument: 

 
```
select Json_Array_Add(Jbin_File('test.json', 'b'), 66);

```

This query returns:

 


| Json\_Array\_Add(Jbin\_File('test.json', 'b'), 66) |
| --- |
| test.json |

 
This time the file is modified. This can be checked with:

 
```
select Json_File('test.json', 3);

```




| Json\_File('test.json', 3) |
| --- |
| {"a":1,"b":[44,55,66]} |

 The reason why the first argument is returned by such a query is because of tables such as:

 
```
create table tb (
n int key,
jfile_cols char(10) not null);
insert into tb values(1,'test.json');

```

In this table, the *jfile\_cols* column just contains a file name. If we update it by:

 
```
update tb set jfile_cols = select Json_Array_Add(Jbin_File('test.json', 'b'), 66)
where n = 1;

```

This is the test.json file that must be modified, not the jfile\_cols column. This can be checked by:

 
```
select JsonGet_String(jfile_cols, '[1]:*') from tb;

```



| JsonGet\_String(jfile\_cols, '[1]:\*') |
| --- |
| {"a":1,"b":[44,55,66]} |

 
Note: It was an important facility to name the second column of the table beginning by “jfile\_” so the json functions knew it was a file name without obliging to specify an alias in the queries.

 ### Using “Jbin” to control what the query execution does

 This is applying in particular when acting on json files. We have seen that a file was not modified when using the *Json\_File* function as an argument to a modifying function because the modifying function just received a copy of the json file. This is not true when using the *Jbin\_File* function that does not serialize the binary document and make it directly accessible. Also, as we have seen earlier, json functions that modify their first file parameter modify the file and return the file name. This is done by directly serializing the internal binary document as a file.

 However, the “Jbin” counterpart of these functions does not serialize the binary document and thus does not modify the json file. For example let us compare these two queries:

 /\* First query \*/

 
```
select Json_Object(Jbin_Object_Add(Jbin_File('bt2.json'), 4 as "d") as "Jbin_bt1")
  as "Result";

```

/\* Second query \*/

 
```
select Json_Object(Json_Object_Add(Jbin_File('bt2.json'), 4 as "d") as "Jfile_bt1")
  as "Result";

```

Both queries return:

 


| Result |
| --- |
| {"bt1":{"a":1,"b":2,"c":3,"d":4}} |

 
In the first query *Jbin\_Object\_Add* does not serialize the document (no “Jbin” functions do) and *Json\_Object* just returns a serialized modified tree. Consequently, the file bt2.json is not modified. This query is all right to copy a modified version of the json file without modifying it.

 However, in the second query *Json\_Object\_Add* does modify the json file and returns the file name. The *Json\_Object* function receives this file name, reads and parses the file, makes an object from it and returns the serialized result. This modification can be done willingly but can be an unwanted side effect of the query.

 Therefore, using “Jbin” argument functions, in addition to being faster and using less memory, are also safer when dealing with json files that should not be modified.

 Using JSON as Dynamic Columns
-----------------------------

 The JSON nosql language has all the features to be used as an alternative to dynamic columns. For instance, take the following example of dynamic columns:

 
```
create table assets (
   item_name varchar(32) primary key, /* A common attribute for all items */
   dynamic_cols  blob  /* Dynamic columns will be stored here */
 );

INSERT INTO assets VALUES
   ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL'));

INSERT INTO assets VALUES
   ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500));

SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) AS color FROM assets;
+-----------------+-------+
| item_name       | color |
+-----------------+-------+
| MariaDB T-shirt | blue  |
| Thinkpad Laptop | black |
+-----------------+-------+

```

/\* Remove a column: \*/

 
```
UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, "price")
  WHERE COLUMN_GET(dynamic_cols, 'color' as char)='black';

```

/\* Add a column: \*/

 
```
UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years')
   WHERE item_name='Thinkpad Laptop';

```

/\* You can also list all columns, or get them together with their values in JSON format: \*/

 
```
SELECT item_name, column_list(dynamic_cols) FROM assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB T-shirt | `size`,`color`            |
| Thinkpad Laptop | `color`,`warranty`        |
+-----------------+---------------------------+

SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

```

The same result can be obtained with json columns using the json UDF’s:

 /\* JSON equivalent \*/

 
```
create table jassets (
   item_name varchar(32) primary key, /* A common attribute for all items */
   json_cols varchar(512)  /* Jason columns will be stored here */
 );

INSERT INTO jassets VALUES
   ('MariaDB T-shirt', Json_Object('blue' color, 'XL' size));

INSERT INTO jassets VALUES
   ('Thinkpad Laptop', Json_Object('black' color, 500 price));

SELECT item_name, JsonGet_String(json_cols, 'color') AS color FROM jassets;
+-----------------+-------+
| item_name       | color |
+-----------------+-------+
| MariaDB T-shirt | blue  |
| Thinkpad Laptop | black |
+-----------------+-------+

```

/\* Remove a column: \*/

 
```
UPDATE jassets SET json_cols=Json_Object_Delete(json_cols, 'price')
 WHERE JsonGet_String(json_cols, 'color')='black';

```

/\* Add a column \*/

 
```
UPDATE jassets SET json_cols=Json_Object_Add(json_cols, '3 years' warranty)
 WHERE item_name='Thinkpad Laptop';

```

/\* You can also list all columns, or get them together with their values in JSON format: \*/

 
```
SELECT item_name, Json_Object_List(json_cols) FROM jassets;
+-----------------+-----------------------------+
| item_name       | Json_Object_List(json_cols) |
+-----------------+-----------------------------+
| MariaDB T-shirt | ["color","size"]            |
| Thinkpad Laptop | ["color","warranty"]        |
+-----------------+-----------------------------+

SELECT item_name, json_cols FROM jassets;
+-----------------+----------------------------------------+
| item_name       | json_cols                              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"color":"blue","size":"XL"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

```

However, using JSON brings features not existing in dynamic columns:

 * Use of a language used by many implementation and developers.
* Full support of arrays, currently missing from dynamic columns.
* Access of subpart of json by JPATH that can include calculations on arrays.
* Possible references to json files.

 With more experience, additional UDFs can be easily written to support new needs.

 New Set of BSON Functions
-------------------------

 All these functions have been rewritten using the new JSON handling way and are temporarily available changing the J starting name to B. Then Json\_Make\_Array new style is called using Bson\_Make\_Array. Some, such as Bson\_Item\_Delete, are new and some fix bugs found in their Json counterpart.

 Converting Tables to JSON
-------------------------

 The JSON UDF’s and the direct Jpath “\*” facility are powerful tools to convert table and files to the JSON format. For instance, the file `biblio3.json` we used previously can be obtained by converting the `xsample.xml file`. This can be done like this:

 From Connect 1.07.0002

 
```
create table xj1 (row varchar(500) jpath='*') engine=connect table_type=JSON file_name='biblio3.json' option_list='jmode=2';

```

Before Connect 1.07.0002

 
```
create table xj1 (row varchar(500) field_format='*') 
 engine=connect table_type=JSON file_name='biblio3.json' option_list='jmode=2';

```

And then :

 
```
insert into xj1
  select json_object_nonull(ISBN, language LANG, SUBJECT, 
    json_array_grp(json_object(authorfn FIRSTNAME, authorln LASTNAME)) json_AUTHOR, TITLE,
    json_object(translated PREFIX, json_object(tranfn FIRSTNAME, tranln LASTNAME) json_TRANSLATOR) 
    json_TRANSLATED, json_object(publisher NAME, location PLACE) json_PUBLISHER, date DATEPUB) 
from xsampall2 group by isbn;

```

The xj1 table rows will directly receive the Json object made by the select statement used in the insert statement and the table file will be made as shown (xj1 is pretty=2 by default) Its mode is Jmode=2 because the values inserted are strings even if they denote json objects.

 Another way to do this is to create a table describing the file format we want before the `biblio3.json` file existed:

 From Connect 1.07.0002

 
```
create table jsampall3 (
ISBN char(15),
LANGUAGE char(2) jpath='LANG',
SUBJECT char(32),
AUTHORFN char(128) jpath='AUTHOR:[X]:FIRSTNAME',
AUTHORLN char(128) jpath='AUTHOR:[X]:LASTNAME',
TITLE char(32),
TRANSLATED char(32) jpath='TRANSLATOR:PREFIX',
TRANSLATORFN char(128) jpath='TRANSLATOR:FIRSTNAME',
TRANSLATORLN char(128) jpath='TRANSLATOR:LASTNAME',
PUBLISHER char(20) jpath='PUBLISHER:NAME',
LOCATION char(20) jpath='PUBLISHER:PLACE',
DATE int(4) jpath='DATEPUB')
engine=CONNECT table_type=JSON file_name='biblio3.json';

```

Before Connect 1.07.0002

 
```
create table jsampall3 (
ISBN char(15),
LANGUAGE char(2) field_format='LANG',
SUBJECT char(32),
AUTHORFN char(128) field_format='AUTHOR:[X]:FIRSTNAME',
AUTHORLN char(128) field_format='AUTHOR:[X]:LASTNAME',
TITLE char(32),
TRANSLATED char(32) field_format='TRANSLATOR:PREFIX',
TRANSLATORFN char(128) field_format='TRANSLATOR:FIRSTNAME',
TRANSLATORLN char(128) field_format='TRANSLATOR:LASTNAME',
PUBLISHER char(20) field_format='PUBLISHER:NAME',
LOCATION char(20) field_format='PUBLISHER:PLACE',
DATE int(4) field_format='DATEPUB')
engine=CONNECT table_type=JSON file_name='biblio3.json';

```

and to populate it by:

 
```
insert into jsampall3 select * from xsampall;

```

This is a simpler method. However, the issue is that this method cannot handle the multiple column values. This is why we inserted from `xsampall` not from `xsampall2`. How can we add the missing multiple authors in this table? Here again we must create a utility table able to handle JSON strings. From Connect 1.07.0002

 
```
create table xj2 (ISBN char(15), author varchar(150) jpath='AUTHOR:*') engine=connect table_type=JSON file_name='biblio3.json' option_list='jmode=1';

```

Before Connect 1.07.0002

 
```
create table xj2 (ISBN char(15), author varchar(150) field_format='AUTHOR:*') 
  engine=connect table_type=JSON file_name='biblio3.json' option_list='jmode=1';

```


```
update xj2 set author =
(select json_array_grp(json_object(authorfn FIRSTNAME, authorln LASTNAME)) 
  from xsampall2 where isbn = xj2.isbn);

```

Voilà !

 Converting json files
---------------------

 We have seen that json files can be formatted differently depending on the pretty option. In particular, big data files should be formatted with pretty equal to 0 when used by a CONNECT json table. The best and simplest way to convert a file from one format to another is to use the *Jfile\_Make* function. Indeed this function makes a file of specified format using the syntax:

 
```
Jfile_Make(json_document, [file_name], [pretty]);

```

The file name is optional when the json document comes from a Jbin\_File function because the returned structure makes it available. For instance, to convert back the json file tb.json to pretty= 0, this can be simply done by:

 
```
select Jfile_Make(Jbin_File('tb.json'), 0);

```

Performance Consideration
-------------------------

 MySQL and PostgreSQL have a JSON data type that is not just text but an internal encoding of JSON data. This is to save parsing time when executing JSON functions. Of course, the parse must be done anyway when creating the data and serializing must be done to output the result.

 CONNECT directly works on character strings impersonating JSON values with the need of parsing them all the time but with the advantage of working easily on external data. Generally, this is not too penalizing because JSON data are often of some or reasonable size. The only case where it can be a serious problem is when working on a big JSON file.

 Then, the file should be formatted or converted to *pretty=0*.

 From Connect 1.7.002, this easily done using the Jfile\_Convert function, for instance:

 
```
select jfile_convert('bibdoc.json','bibdoc0.json',350);

```

Such a json file should not be used directly by JSON UDFs because they parse the whole file, even when only a subset is used. Instead, it should be used by a JSON table created on it. Indeed, JSON tables do not parse the whole document but just the item corresponding to the row they are working on. In addition, indexing can be used by the table as explained previously on this page.

 Generally speaking, the maximum flexibility offered by CONNECT is by using JSON tables and JSON UDFs together. Some things are better handled by tables, other by UDFs. The tools are there but it is up to you to discover the best way to resolve your problems. 

 ### Bjson files

 Starting with Connect 1.7.002, *pretty=0* json files can be converted to a binary format that is a pre-parsed representation of json. This can be done with the Jfile\_Bjson UDF function, for instance:

 
```
select jfile_bjson('bigfile.json','binfile.json',3500);

```

Here the third argument, the record length, must 6 to 10 times larger than the lrecl of the initial json file because the parsed representation is bigger than the original json text representation.

 Tables using such Bjson files must specify ‘Pretty=-1’ in the option list.

 It is probably similar to the BSON used by MongoDB and PostgreSQL and permits to process queries up to 10 times faster than working on text json files. Indexing is also available for tables using this format making even more performance improvement. For instance, some queries on a json table of half a million rows, that were previously done in more than 10 seconds, took only 0.1 second when converted and indexed.

 Here again, this has been remade to use the new way Json is handled. The files made using the bfile\_bjson function are only from two to four times the size of the source files. This new representation is not compatible with the old one. Therefore, these files must be used with BSON tables only. 

 Specifying a JSON table Encoding
--------------------------------

 An important feature of JSON is that strings should in UNICODE. As a matter of fact, all examples we have found on the Internet seemed to be just ASCII. This is because UNICODE is generally encoded in JSON files using UTF8 or UTF16 or UTF32.

 To specify the required encoding, just use the data\_charset CONNECT option or the native DEFAULT CHARSET option.

 Retrieving JSON data from MongoDB
---------------------------------

 Classified as a NoSQL database program, MongoDB uses JSON-like documents (BSON) grouped in collections. The simplest way, and only method available before Connect 1.6, to access MongoDB data was to export a collection to a JSON file. This produces a file having the pretty=0 format. Viewed as SQL, a collection is a table and documents are table rows.

 Since CONNECT version 1.6, it is now possible to directly access MongoDB collections via their MongoDB C Driver. This is the purpose of the MONGO table type described later. However, JSON tables can also do it in a somewhat different way (providing MONGO support is installed as described for MONGO tables).

 It is achieved by specifying the MongoDB connection URI while creating the table. For instance:

 From Connect 1.7.002

 
```
create or replace table jinvent (
_id char(24) not null, 
item char(12) not null,
instock varchar(300) not null jpath='instock.*')
engine=connect table_type=JSON tabname='inventory' lrecl=512
connection='mongodb://localhost:27017';

```

Before Connect 1.7.002

 
```
create or replace table jinvent (
_id char(24) not null, 
item char(12) not null,
instock varchar(300) not null field_format='instock.*')
engine=connect table_type=JSON tabname='inventory' lrecl=512
connection='mongodb://localhost:27017';

```

In this statement, the *file\_name* option was replaced by the *connection* option. It is the URI enabling to retrieve data from a local or remote MongoDB server. The *tabname* option is the name of the MongoDB collection that will be used and the *dbname* option could have been used to indicate the database containing the collection (it defaults to the current database).

 The way it works is that the documents retrieved from MongoDB are serialized and CONNECT uses them as if they were read from a file. This implies serializing by MongoDB and parsing by CONNECT and is not the best performance wise. CONNECT tries its best to reduce the data transfer when a query contains a reduced column list and/or a where clause. This way makes all the possibilities of the JSON table type available, such as calculated arrays.

 However, to work on large JSON collations, using the MONGO table type is generally the normal way.

 Note: JSON tables using the MongoDB access accept the specific MONGO options [colist](../connect-mongo-table-type/index#colist-option), [filter](../connect-mongo-table-type/index#filter-option) and [pipeline](../connect-mongo-table-type/index#pipeline-option). They are described in the MONGO table chapter.

 Summary of Options and Variables Used with Json Tables
------------------------------------------------------

 Options and variables that can be used when creating Json tables are listed here:

 


| Table Option | Type | Description |
| --- | --- | --- |
| ENGINE | String | Must be specified as CONNECT. |
| TABLE\_TYPE | String | Must be JSON or BSON. |
| FILE\_NAME | String | The optional file (path) name of the Json file. Can be absolute or relative to the current data directory. If not specified, it defaults to the table name and json file type. |
| DATA\_CHARSET | String | Set it to ‘utf8’ for most Unicode Json documents. |
| LRECL | Number | The file record size for pretty < 2 json files. |
| HTTP | String | The HTTP of the server of REST queries. |
| URI | String | THE URI of REST queries |
| CONNECTION\* | String | Specifies a connection to `MONGODB`. |
| ZIPPED | Boolean | True if the json file(s) is/are zipped in one or several zip files. |
| MULTIPLE | Number | Used to specify a multiple file table. |
| SEP\_CHAR | String | Set it to ‘:’ for old tables using the old json path syntax. |
| CATFUNC | String | The catalog function (column) used when creating a catalog table. |
| OPTION\_LIST | String | Used to specify all other options listed below. |

 
(\*) For Json tables connected to MongoDB, Mongo specific options can also be used.

 Other options must be specified in the option list:

 


| Table Option | Type | Description |
| --- | --- | --- |
| DEPTHLEVEL | Number | Specifies the depth in the document CONNECT looks when defining columns by discovery or in catalog tables |
| PRETTY | Number | Specifies the format of the Json file (-1 for Bjson files) |
| EXPAND | String | The name of the column to expand. |
| OBJECT | String | The json path of the sub-document used for the table. |
| BASE | Number | The numbering base for arrays: 0 (the default) or 1. |
| LIMIT | Number | The maximum number of array values to use when concatenating, calculating or expanding arrays. Defaults to 50 (>= Connect 1.7.0003), 10 (<= Connect 1.7.0002). |
| FULLARRAY | Boolean | Used when creating with Discovery. Make a column for each value of arrays (up to LIMIT). |
| JMODE | Number | The Json mode (array of objects, array of arrays, or array of values) Only used when inserting new rows. |
| ACCEPT | Boolean | Keep null columns (for discovery). |
| AVGLEN | Number | An estimate average length of rows. This is used only when indexing and can be set if indexing fails by miscalculating the table max size. |
| STRINGIFY | String | Ask discovery to make a column to return the Json representation of this object. |

 
Column options:

 


| Column Option | Type | Description |
| --- | --- | --- |
| JPATHFIELD\_FORMAT | String | Defaults to the column name. |
| DATE\_FORMAT | String | Specifies the date format into the Json file when defining a DATE, DATETIME or TIME column. |

 
Variables used with Json tables are:

 * [connect\_default\_depth](../connect-system-variables/index#connect_default_depth)
* [connect\_json\_null](../connect-system-variables/index#connect_json_null)
* [connect\_json\_all\_path](../connect-system-variables/index#connect_json_all_path)
* [connect\_force\_bson](../connect-system-variables/index#connect_force_bson)

 Notes
-----

 1. [↑](#_ref-0) The value n can be 0 based or 1 based depending on the base table option. The default is 0 to match what is the current usage in the Json world but it can be set to 1 for tables created in old versions.
2. [↑](#_ref-1) See for instance: [json-functions](../json-functions/index), <https://github.com/mysqludf/lib_mysqludf_json#readme> and <https://blogs.oracle.com/svetasmirnova/entry/json_udf_functions_version_04>
3. [↑](#_ref-2) This will not work when CONNECT is compiled embedded

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-json-table-type/>

InnoDB Change Buffering
=======================

    
The change buffer has been disabled by default from [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10515-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-1067-release-notes/), [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-1073-release-notes/) and [MariaDB 10.8.2](https://mariadb.com/kb/en/mariadb-1082-release-notes/) ([MDEV-27734](https://jira.mariadb.org/browse/MDEV-27734)), was deprecated and ignored from [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/) ([MDEV-27735](https://jira.mariadb.org/browse/MDEV-27735)), and was removed in [MariaDB 11.0.0](../mdb-11-0-0-rn/index) ([MDEV-29694](https://jira.mariadb.org/browse/MDEV-29694)).

 Benchmarks attached to [MDEV-19514](https://jira.mariadb.org/browse/MDEV-19514) show that the change buffer sometimes reduces performance, and in the best case seem to bring a few per cent improvement to throughput. However, such improvement could come with a price: If the buffered changes are never merged ([MDEV-19514](https://jira.mariadb.org/browse/MDEV-19514), motivated by the reduction of random crashes and the removal of an innodb\_force\_recovery option that can inflict further corruption), then the InnoDB system tablespace can grow out of control ([MDEV-21952](https://jira.mariadb.org/browse/MDEV-21952)).

 
 INSERT, UPDATE and DELETE statements can be particularly heavy operations to perform, as all indexes need to be updated after each change. For this reason these changes are often buffered.

 Pages are modified in the [buffer pool](../innodb-buffer-pool/index), and not immediately on disk. When rows are deleted, a flag is set, thus rows are not immediately deleted on disk. Later the changes will be written to disk (''flushed'') by InnoDB background threads. Pages that have been modified in memory and not yet flushed are called dirty pages. The buffering of data changes is called Change Buffer.

 Before [MariaDB 5.5](../what-is-mariadb-55/index), only inserted rows could be buffered, so this buffer was called Insert Buffer. The old name still appears in several places, for example in the output of [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index).

 The change buffer only contains changes to the indexes. Inserts to UNIQUE secondary indexes cannot be buffered unless unique\_checks=0 is used. Delete-mark and purge buffering of UNIQUE secondary indexes is allowed.

 The Change Buffer is an optimization because:

 * A page can be modified several times in memory and be flushed to disk only once.
* Dirty pages are flushed together, so the number of IO operations is lower.

 If the server crashes, usually the Change Buffer is not empty. However, changes are not lost because they are written to the transaction logs, so they can be applied at server restart.

 The main server system variable here is [innodb\_change\_buffering](../innodb-system-variables/index#innodb_change_buffering), which determines which form of change buffering, if any, to use.

 The following settings are available:

 * inserts
	+ Only buffer insert operations
* deletes
	+ Only buffer delete operations
* changes
	+ Buffer both insert and delete operations
* purges
	+ Buffer the actual physical deletes that occur in the background
* all
	+ Buffer inserts, deletes and purges. Default setting from [MariaDB 5.5](../what-is-mariadb-55/index) until [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/) and [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/).
* none
	+ Don't buffer any operations. Default from [MariaDB 10.5.15](https://mariadb.com/kb/en/mariadb-10515-release-notes/), [MariaDB 10.6.7](https://mariadb.com/kb/en/mariadb-1067-release-notes/), [MariaDB 10.7.3](https://mariadb.com/kb/en/mariadb-1073-release-notes/) and [MariaDB 10.8.2](https://mariadb.com/kb/en/mariadb-1082-release-notes/).

 Modifying the value of this variable only affects the buffering of new operations. The merging of already buffered changes is not affected.

 The [innodb\_change\_buffer\_max\_size](../innodb-system-variables/index#innodb_change_buffer_max_size) system variable determines the maximum size of the change buffer, expressed as a percentage of the buffer pool.

 See Also
--------

 * [InnoDB Buffer Pool](../innodb-buffer-pool/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-change-buffering/>

InnoDB Buffer Pool
==================

     The [InnoDB](../innodb/index) buffer pool is a key component for optimizing MariaDB. It stores data and indexes, and you usually want it as large as possible so as to keep as much of the data and indexes in memory, reducing disk IO, as main bottleneck.

 How the Buffer Pool Works
-------------------------

 The buffer pool attempts to keep frequently-used blocks in the buffer, and so essentially works as two sublists, a *new* sublist of recently-used information, and an *old* sublist of older information. By default, 37% of the list is reserved for the old list.

 When new information is accessed that doesn't appear in the list, it is placed at the top of the old list, the oldest item in the old list is removed, and everything else bumps back one position in the list.

 When information is accessed that appears in the *old* list, it is moved to the top the new list, and everything above moves back one position.

 innodb\_buffer\_pool\_size
--------------------------

 The most important [server system variable](../server-system-variables/index) is [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size). This size should contain most of the active data set of your server so that SQL request can work directly with information in the buffer pool cache. Starting at several gigabytes of memory is a good starting point if you have that RAM available. Once warmed up to its normal load there should be very few [innodb\_buffer\_pool\_reads](../innodb-status-variables/index#innodb_buffer_pool_reads) compared to [innodb\_buffer\_pool\_read\_requests](../innodb-status-variables/index#innodb_buffer_pool_read_requests). Look how these values change over a minute. If the change in [innodb\_buffer\_pool\_reads](../innodb-status-variables/index#innodb_buffer_pool_reads) is less than 1% of the change in [innodb\_buffer\_pool\_read\_requests](../innodb-status-variables/index#innodb_buffer_pool_read_requests) then you have a good amount of usage. If you are getting the status variable [innodb\_buffer\_pool\_wait\_free](../innodb-status-variables/index#innodb_buffer_wait_free) increasing then you don't have enough buffer pool (or your flushing isn't occurring frequently enough).

 Be aware that before [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/) the total memory allocated is about 10% more than the specified size as extra space is also reserved for control structures and buffers.

 The larger the size, the longer it will take to initialize. On a modern 64-bit server with a 10GB memory pool, this can take five seconds or more. Increasing [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) by several factors will reduce this significantly.

 Make sure that the size is not too large, causing swapping. The benefit of a larger buffer pool size is more than undone if your operating system is regularly swapping.

 Since [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), the buffer pool can be set dynamically, and new variables are introduced that may affect the size and performance. See [Setting Innodb Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index).

 innodb\_buffer\_pool\_instances
-------------------------------

 The functionality described below was disabled in [MariaDB 10.5](../what-is-mariadb-105/index), and removed in [MariaDB 10.6](../what-is-mariadb-106/index), as the original reasons for for splitting the buffer pool have mostly gone away. 

 If innodb\_buffer\_pool\_size is set to more than 1GB, [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) divides the InnoDB buffer pool into a specific number of instances. The default was 1 in [MariaDB 5.5](../what-is-mariadb-55/index), but for large systems with buffer pools of many gigabytes, many instances can help reduce contention concurrency. The default is 8 in [MariaDB 10.0](../what-is-mariadb-100/index), with the exception of 32-bit Windows, where it depends on the value of [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size). Each instance manages its own data structures and takes an equal portion of the total buffer pool size, so for example if innodb\_buffer\_pool\_size is 4GB and innodb\_buffer\_pool\_instances is set to 4, each instance will be 1GB. Each instance should ideally be at least 1GB in size. 

 innodb\_old\_blocks\_pct and innodb\_old\_blocks\_time
------------------------------------------------------

 The default 37% reserved for the old list can be adjusted by changing the value of [innodb\_old\_blocks\_pct](../innodb-system-variables/index#innodb_old_blocks_pct). It can accept anything between between 5% and 95%. 

 The [innodb\_old\_blocks\_time](../innodb-system-variables/index#innodb_old_blocks_time) variable specifies the delay before a block can be moved from the old to the new sublist. `0` means no delay, while the default has been set to `1000`.

 Before changing either of these values from their defaults, make sure you understand the impact and how your system currently uses the buffer. Their main reason for existence is to reduce the impact of full table scans, which are usually infrequent, but large, and previously could clear everything from the buffer. Setting a non-zero delay could help in situations where full table scans are performed in quick succession.

 Temporarily changing these values can also be useful to avoid the negative impact of a full table scan, as explained in [InnoDB logical backups](../backup-and-restore-overview/index#innodb-logical-backups).

 Dumping and Restoring the Buffer Pool
-------------------------------------

 When the server starts, the buffer pool is empty. As it starts to access data, the buffer pool will slowly be populated. As more data will be accessed, the most frequently accessed data will be put into the buffer pool, and old data may be evicted. This means that a certain period of time is necessary before the buffer pool is really useful. This period of time is called the warmup.

 Since [MariaDB 10.0](../what-is-mariadb-100/index), InnoDB can dump the buffer pool before the server shuts down, and restore it when it starts again. If this feature is used (default since [MariaDB 10.2](../what-is-mariadb-102/index)), no warmup is necessary. Use the [innodb\_buffer\_pool\_dump\_at\_shutdown](../innodb-system-variables/index#innodb_buffer_pool_dump_at_shutdown) and [innodb\_buffer\_pool\_load\_at\_startup](../innodb-system-variables/index#innodb_buffer_pool_load_at_startup) system variables to enable or disable the buffer pool dump at shutdown and the restore at startup respectively. 

 It is also possible to dump the InnoDB buffer pool at any moment while the server is running, and it is possible to restore the last buffer pool dump at any moment. To do this, the special [innodb\_buffer\_pool\_dump\_now](../innodb-system-variables/index#innodb_buffer_pool_dump_now) and [innodb\_buffer\_pool\_load\_now](../innodb-system-variables/index#innodb_buffer_pool_load_now) system variables can be set to ON. When selected, their value is always OFF.

 A buffer pool restore, both at startup or at any other moment, can be aborted by setting [innodb\_buffer\_pool\_load\_abort](../innodb-system-variables/index#innodb_buffer_pool_load_abort) to ON.

 The file which contains the buffer pool dump is specified via the [innodb\_buffer\_pool\_filename](../innodb-system-variables/index#innodb_buffer_pool_filename) system variable.

 See Also
--------

 * [InnoDB Change Buffering](../innodb-change-buffering/index)
* [Information Schema INNODB\_BUFFER\_POOL\_STATS Table](../information-schema-innodb_buffer_pool_stats-table/index)
* [Setting Innodb Buffer Pool Size Dynamically](../setting-innodb-buffer-pool-size-dynamically/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-buffer-pool/>

Sample my.cnf Files
===================

    Place holder for sample my.cnf files, customized for different memory size and storage engines. In addition, we'd like to hear from you what works for you, so the knowledge can be crowd-sourced and shared.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sample-mycnf-files/>

Information Schema GLOBAL\_VARIABLES and SESSION\_VARIABLES Tables
==================================================================

    The [Information Schema](../information_schema/index) `GLOBAL_VARIABLES` and `SESSION_VARIABLES` tables stores a record of all [system variables](../server-system-variables/index) and their global and session values respectively. This is the same information as displayed by the `[SHOW VARIABLES](../show-variables/index)` commands `SHOW GLOBAL VARIABLES` and `SHOW SESSION VARIABLES`.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | System variable name. |
| `VARIABLE_VALUE` | Global or session value. |

 
Example
-------

 
```
SELECT * FROM information_schema.GLOBAL_VARIABLES ORDER BY VARIABLE_NAME\G
*************************** 1. row *****************************
 VARIABLE_NAME: ARIA_BLOCK_SIZE
VARIABLE_VALUE: 8192
*************************** 2. row *****************************
 VARIABLE_NAME: ARIA_CHECKPOINT_LOG_ACTIVITY
VARIABLE_VALUE: 1048576
*************************** 3. row *****************************
 VARIABLE_NAME: ARIA_CHECKPOINT_INTERVAL
VARIABLE_VALUE: 30
...
*************************** 455. row ***************************
 VARIABLE_NAME: VERSION_COMPILE_MACHINE
VARIABLE_VALUE: x86_64
*************************** 456. row ***************************
 VARIABLE_NAME: VERSION_COMPILE_OS
VARIABLE_VALUE: debian-linux-gnu
*************************** 457. row ***************************
 VARIABLE_NAME: WAIT_TIMEOUT
VARIABLE_VALUE: 600

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-global_variables-and-session_variables-tables/>

Aborting Statements that Exceed a Certain Time to Execute
=========================================================

    Overview
--------

 [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) introduced the [max\_statement\_time](../server-system-variables/index#max_statement_time) system variable. When set to a non-zero value, any queries taking longer than this time in seconds will be aborted. The default is zero, and no limits are then applied. The aborted query has no effect on any larger transaction or connection contexts. The variable is of type double, thus you can use subsecond timeout. For example you can use value 0.01 for 10 milliseconds timeout.

 The value can be set globally or per session, as well as per user or per query (see below). Slave's are not affected by this variable.

 An associated status variable, [max\_statement\_time\_exceeded](../server-status-variables/index#max_statement_time_exceeded), stores the number of queries that have exceeded the execution time specified by [max\_statement\_time](../server-system-variables/index#max_statement_time), and a `MAX_STATEMENT_TIME_EXCEEDED` column was added to the [CLIENT\_STATISTICS](../information-schema-client_statistics-table/index) and [USER STATISTICS](../information-schema-user_statistics-table/index) Information Schema tables.

 The feature was based upon a patch by Davi Arnaut. 

 User [max\_statement\_time](../server-system-variables/index#max_statement_time)
--------------------------------------------------------------------------------

 [max\_statement\_time](../server-system-variables/index#max_statement_time) can be stored per user with the [GRANT ... MAX\_STATEMENT\_TIME](../grant/index) syntax.

 Per-query [max\_statement\_time](../server-system-variables/index#max_statement_time)
-------------------------------------------------------------------------------------

 By using [max\_statement\_time](../server-system-variables/index#max_statement_time) in conjunction with [SET STATEMENT](../set-statement/index), it is possible to limit the execution time of individual queries. For example:

 
```
SET STATEMENT max_statement_time=100 FOR 
  SELECT field1 FROM table_name ORDER BY field1;

```


max\_statement\_time per query Individual queries can also be limited by adding a `MAX_STATEMENT_TIME` clause to the query. For example:

 
```
SELECT MAX_STATEMENT_TIME=2 * FROM t1;

```


Limitations
-----------

 * [max\_statement\_time](../server-system-variables/index#max_statement_time) does not work in embedded servers.
* [max\_statement\_time](../server-system-variables/index#max_statement_time) does not work for [COMMIT](../commit/index) statements in a Galera cluster (see [MDEV-18673](https://jira.mariadb.org/browse/MDEV-18673) for discussion).

 Differences Between the MariaDB and MySQL Implementations
---------------------------------------------------------

 MySQL 5.7.4 introduced similar functionality, but the MariaDB implementation differs in a number of ways.

 * The MySQL version of [max\_statement\_time](../server-system-variables/index#max_statement_time) (`max_execution_time`) is defined in millseconds, not seconds
* MySQL's implementation can only kill SELECTs, while MariaDB's can kill any queries (excluding stored procedures).
* MariaDB only introduced the [max\_statement\_time\_exceeded](../server-status-variables/index#max_statement_time_exceeded) status variable, while MySQL also introduced a number of other variables which were not seen as necessary in MariaDB.
* The `SELECT MAX_STATEMENT_TIME = N ...` syntax is not valid in MariaDB. In MariaDB one should use `SET STATEMENT MAX_STATEMENT_TIME=N FOR...`.

 See Also
--------

 * [Query limits and timeouts](../query-limits-and-timeouts/index)
* [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) variable

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aborting-statements-that-take-longer-than-a-certain-time-to-execute/>

MariaDB Optimization for MySQL Users
====================================

    MariaDB contains many new options and optimizations which, for compatibility or other reasons, are not enabled in the default install. Enabling them helps you gain extra performance from the same hardware when upgrading from MySQL to MariaDB. This article contains information on options and settings which you should enable, or at least look in to, when making the switch.

 
```
aria-pagecache-buffer-size=##

```

If you are using a log of on-disk temporary tables, increase the above to as much as you can afford. See [Aria Storage Engine](../aria-storage-engine/index) for more details.

 
```
key-cache-segments=8

```

If you use/have a lot of MyISAM files, increase the above to 4 or 8. See [Segmented Key Cache](../segmented-key-cache/index) and [Segmented Key Cache Performance](../segmented-key-cache-performance/index) for more information.

 
```
thread-handling=pool-of-threads

```

Threadpool is a great way to increase performance in situations where queries are relatively short and the load is CPU bound (e.g. OLTP workloads). To enable it, add the above to your my.cnf file. See [Threadpool in 5.5](../threadpool-in-55/index) for more information.

 
```
innodb-buffer-pool-instances=

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-optimization-for-mysql-users/>

Big Query Settings
==================

    [MariaDB 5.3](../what-is-mariadb-53/index) and beyond have a number of features that are targeted at big queries and so are disabled by default.

 This page describes recommended settings for IO-bound queries that shovel through lots of records.

 First, turn on [Batched Key Access](../block-based-join-algorithms/index): 

 
```
# Turn on disk-ordered reads
optimizer_switch='mrr=on'
optimizer_switch='mrr_cost_based=off'

# Turn on Batched Key Access (BKA)
join_cache_level = 6

```

Give BKA buffer space to operate on. Ideally, it should have enough space to fit all the data examined by the query. 

 
```
# Size limit for the whole join
join_buffer_space_limit = 300M

# Limit for each individual table
join_buffer_size = 100M

```

Turn on [index\_merge/sort-intersection](../index_merge_sort_intersection/index):

 
```
optimizer_switch='index_merge_sort_intersection=on'

```

If your queries examine big fraction of the tables (somewhere more than ~ 30%), turn on [hash join](hash-join):

 
```
# Turn on both Hash Join and Batched Key Access
join_cache_level = 8

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/big-query-settings/>

Optimizing table\_open\_cache
=============================

    *[table\_open\_cache](../server-system-variables/index#table_open_cache)* can be a useful variable to adjust to improve performance. 

 Each concurrent session accessing the same table does so independently. This improves performance, although it comes at a cost of extra memory usage.

 *table\_open\_cache* indicates the maximum number of tables the server can keep open in any one table cache instance. Ideally, you'd like this set so as to re-open a table as infrequently as possible.

 However, note that this is not a hard limit. When the server needs to open a table, it evicts the least recently used closed table from the cache, and adds the new table. If all tables are used, the server adds the new table and does not evict any table. As soon as a table is not used anymore, it will be evicted from the list even if no table needs to be open, until the number of open tables will be equal to *table\_open\_cache*

 *table\_open\_cache* has defaulted to 2000 since [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/). Before that, the default was 400.

 You can view the current setting in the my.cnf file, or by running:

 
```
select @@table_open_cache;
+--------------------+
| @@table_open_cache |
+--------------------+
|                400 |
+--------------------+

```

To evaluate whether you could do with a higher table\_open\_cache, look at the number of opened tables, in conjunction with the server uptime ([Opened\_tables](../server-status-variables/index#opened_tables) and [Uptime](../server-status-variables/index#uptime) status variables):

 
```
show global status like 'opened_tables';
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| Opened_tables | 354858 |
+---------------+--------+

```

If the number of opened tables is increasing rapidly, you should look at increasing the table\_open\_cache value. Try to find a value that sees a slow, or possibly even no, increase in the number of opened tables.

 
Make sure that your operating system can cope with the number of open file descriptors required by the table\_open\_cache setting. If table\_open\_cache is set too high, MariaDB may start to refuse connections as the operating system runs out of file descriptors. Also note that the MyISAM (and Aria?) storage engines need two file descriptors per open table.

 
It's possible that the open\_table\_cache can even be reduced.

 If your number of open\_tables has not yet reached the table\_open\_cache\_size, and the server has been up a while, you can look at decreasing the value.

 
```
show global status like 'open_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables   | 354   |
+---------------+-------+

```

The open table cache can be emptied with [FLUSH TABLES](../flush/index) or with the `flush-tables` or `refresh` [mariadb-admin](../mariadb-admin/index) commands.

 Automatic Creation of New Table Open Cache Instances
----------------------------------------------------

 MariaDB Server can create multiple instances of the table open cache. It initially creates just a single instance. However, whenever it detects contention on the existing instances, it will automatically create a new instance. When the number of instances has been increased due to contention, it does not decrease again.

 When MariaDB Server creates a new instance, it prints a message like the following to the [error log](../error-log/index):

 
```
[Note] Detected table cache mutex contention at instance 1: 25% waits. Additional 
  table cache instance activated. Number of instances after activation: 2.

```

The maximum number of instances is defined by the [table\_open\_cache\_instances](../server-system-variables/index#table_open_cache_instances) system variable. The default value of the [table\_open\_cache\_instances](../server-system-variables/index#table_open_cache_instances) system variable is `8`, which is expected to handle up to 100 CPU cores. If your system is larger than this, then you may benefit from increasing the value of this system variable.

 Depending on the ratio of actual available file handles, and [table\_open\_cache](../server-system-variables/index#table_open_cache) size, the max. instance count may be auto adjusted to a lower value on server startup.

 The implementation and behavior of this feature is different than the same feature in MySQL 5.6.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-table_open_cache/>

Setting Innodb Buffer Pool Size Dynamically
===========================================

    Resizing the buffer pool is performed in chunks determined by the size of the [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) variable.

 The resize operation waits until all active transactions and operations are completed, and new transactions and operations that need to access the buffer pool must wait until the resize is complete (although when decreasing the size, access is permitted when defragmenting and withdrawing pages).

 Nested transactions may fail if started after the buffer pool resize has begun.

 The new buffer pool size must be a multiple of [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) \* [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) (note that `innodb_buffer_pool_instances` is ignored from [MariaDB 10.5](../what-is-mariadb-105/index), and removed in [MariaDB 10.6](../what-is-mariadb-106/index), as the buffer pool is no longer split into multiple instances). If you attempt to set a different figure, the value is automatically adjusted to a multiple of at least the attempted size. Note that adjusting the [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) setting can result in a change in the buffer pool size.

 The number of chunks as calculated by [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) / [innodb\_buffer\_pool\_chunk\_size](../innodb-system-variables/index#innodb_buffer_pool_chunk_size) should not exceed 1000 in order to avoid performance issues.

 A background thread performs the resizing operation. The [Innodb\_buffer\_pool\_resize\_status](../innodb-status-variables/index#innodb_buffer_pool_resize_status) status variable shows the progress of the resizing operation, for example:

 
```
SHOW STATUS LIKE 'Innodb_buffer_pool_resize_status';
+----------------------------------+----------------------------------+
| Variable_name                    | Value                            |
+----------------------------------+----------------------------------+
| Innodb_buffer_pool_resize_status | Resizing also other hash tables. |
+----------------------------------+----------------------------------+

```

or 

 
```
SHOW STATUS LIKE 'Innodb_buffer_pool_resize_status';
+----------------------------------+----------------------------------------------------+
| Variable_name                    | Value                                              |
+----------------------------------+----------------------------------------------------+
| Innodb_buffer_pool_resize_status | Completed resizing buffer pool at 161103 16:26:54. |
+----------------------------------+----------------------------------------------------+

```

Progress is also logged in the [error log](../error-log/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-innodb-buffer-pool-size-dynamically/>

Segmented Key Cache
===================

    About Segmented Key Cache
-------------------------

 A segmented key cache is a collection of structures for regular [MyISAM](../myisam/index) key caches called key cache segments. Segmented key caches mitigate one of the major problems of the simple key cache: thread contention for key cache lock (mutex). With regular key caches, every call of a key cache interface function must acquire this lock. So threads compete for this lock even in the case when they have acquired shared locks for the file and the pages they want to read from are in the key cache buffers.

 When working with a segmented key cache any key cache interface function that needs only one page has to acquire the key cache lock only for the segment the page is assigned to. This makes the chances for threads not having to compete for the same key cache lock better.

 Any page from a file can be placed into a buffer of only one segment. The number of the segment is calculated from the file number and the position of the page in the file, and it's always the same for the page. Pages are evenly distributed among segments.

 The idea and the original code of the segmented key cache was provided by Fredrik Nylander from Stardoll.com. The code was extensively reworked, improved, and eventually merged into MariaDB by Igor Babaev from Monty Program (now MariaDB Corporation).

 You can find some benchmark results comparing various settings on the [Segmented Key Cache Performance](../segmented-key-cache-performance/index) page.

 Segmented Key Cache Syntax
--------------------------

 New global variable: [key\_cache\_segments](../myisam-system-variables/index#key_cache_segments). This variable sets the number of segments in a key cache. Valid values for this variable are whole numbers between `0` and `64`. If the number of segments is set to a number greater than `64` the number of segments will be truncated to 64 and a warning will be issued.

 A value of `0` means the key cache is a regular (i.e. non-segmented) key cache. This is the default. If `key_cache_segments` is `1` (or higher) then the new key cache segmentation code is used. In practice there is no practical use of a single-segment segmented key cache except for testing purposes, and setting `key_cache_segments = 1` should be slower than any other option and should not be used in production.

 Other global variables used when working with regular key caches also apply to segmented key caches: [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size), [key\_cache\_age\_threshold](../myisam-system-variables/index#key_cache_age_threshold), [key\_cache\_block\_size](../myisam-system-variables/index#key_cache_block_size), and [key\_cache\_division\_limit](../myisam-system-variables/index#key_cache_division_limit).

 Segmented Key Cache Statistics
------------------------------

 Statistics about the key cache can be found by looking at the [KEY\_CACHES](../information-schema-key_caches-table/index) table in the [INFORMATION\_SCHEMA](../information_schema/index) database. Columns in this table are:

 


| Column Name | Description |
| --- | --- |
| `KEY_CACHE_NAME` | The name of the key cache |
| `SEGMENTS` | total number of segments (set to `NULL` for regular key caches) |
| `SEGMENT_NUMBER` | segment number (set to `NULL` for any regular key caches and for rows containing aggregation statistics for segmented key caches) |
| `FULL_SIZE` | memory for cache buffers/auxiliary structures |
| `BLOCK_SIZE` | size of the blocks |
| `USED_BLOCKS` | number of currently used blocks |
| `UNUSED_BLOCKS` | number of currently unused blocks |
| `DIRTY_BLOCKS` | number of currently dirty blocks |
| `READ_REQUESTS` | number of read requests |
| `READS` | number of actual reads from files into buffers |
| `WRITE_REQUESTS` | number of write requests |
| `WRITES` | number of actual writes from buffers into files |

 
See Also
--------

 * [Segmented Key Cache Performance](../segmented-key-cache-performance/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/segmented-key-cache/>

Information Schema SYSTEM\_VARIABLES Table
==========================================

    The [Information Schema](../information_schema/index) `SYSTEM_VARIABLES` table shows current values and various metadata of all [system variables](../server-system-variables/index).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | System variable name. |
| `SESSION_VALUE` | Session value of the variable or NULL if the variable only has a global scope. |
| `GLOBAL_VALUE` | Global value of the variable or NULL if the variable only has a session scope. |
| `GLOBAL_VALUE_ORIGIN` | How the global value was set — a compile-time default, auto-configured by the server, configuration file (or a command line), with the SQL statement. |
| `DEFAULT_VALUE` | Compile-time default value of the variable. |
| `VARIABLE_SCOPE` | Global, session, or session-only. |
| `VARIABLE_TYPE` | Data type of the variable value. |
| `VARIABLE_COMMENT` | Help text, usually shown in `mysqld --help --verbose`. |
| `NUMERIC_MIN_VALUE` | For numeric variables — minimal allowed value. |
| `NUMERIC_MAX_VALUE` | For numeric variables — maximal allowed value. |
| `NUMERIC_BLOCK_SIZE` | For numeric variables — a valid value must be a multiple of the "block size". |
| `ENUM_VALUE_LIST` | For `ENUM`, `SET`, and `FLAGSET` variables — the list of recognized values. |
| `READ_ONLY` | Whether a variable can be set with the SQL statement. Note that many "read only" variables can still be set on the command line. |
| `COMMAND_LINE_ARGUMENT` | Whether an argument is required when setting the variable on the command line. `NULL` when a variable can not be set on the command line. |
| `GLOBAL_VALUE_PATH` | Which config file the variable got its value from. `NULL` if not set in any config file. Added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). |

 
Example
-------

 
```
SELECT * FROM information_schema.SYSTEM_VARIABLES 
  WHERE VARIABLE_NAME='JOIN_BUFFER_SIZE'\G
*************************** 1. row *****************************
        VARIABLE_NAME: JOIN_BUFFER_SIZE
        SESSION_VALUE: 131072
         GLOBAL_VALUE: 131072
  GLOBAL_VALUE_ORIGIN: COMPILE-TIME
        DEFAULT_VALUE: 131072
       VARIABLE_SCOPE: SESSION
        VARIABLE_TYPE: BIGINT UNSIGNED
     VARIABLE_COMMENT: The size of the buffer that is used for joins
    NUMERIC_MIN_VALUE: 128
    NUMERIC_MAX_VALUE: 18446744073709551615
   NUMERIC_BLOCK_SIZE: 128
      ENUM_VALUE_LIST: NULL
            READ_ONLY: NO
COMMAND_LINE_ARGUMENT: REQUIRED

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-system_variables-table/>

LOCK IN SHARE MODE
==================

    InnoDB supports row-level locking. Selected rows can be locked using `LOCK IN SHARE MODE` or [FOR UPDATE](../for-update/index). In both cases, a lock is acquired on the rows read by the query, and it will be released when the current transaction is committed.

 When `LOCK IN SHARE MODE` is specified in a [SELECT](../select/index) statement, MariaDB will wait until all transactions that have modified the rows are committed. Then, a write lock is acquired. All transactions can read the rows, but if they want to modify them, they have to wait until your transaction is committed.

 If [autocommit](../server-system-variables/index#autocommit) is set to 1 (the default), the LOCK IN SHARE MODE and [FOR UPDATE](../for-update/index) clauses have no effect.

 See Also
--------

 * [SELECT](../select/index)
* [FOR UPDATE](../for-update/index)
* [InnoDB Lock Modes](../innodb-lock-modes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lock-in-share-mode/>

LOAD DATA INFILE
================

    Syntax
------

 
```
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES|ROWS}]
    [(col_name_or_user_var,...)]
    [SET col_name = expr,...]

```
 Description
-----------

 
`LOAD DATA INFILE` is [unsafe](../unsafe-statements-for-replication/index) for statement-based replication.

 
Reads rows from a text file into the designated table on the database at a very high speed. The file name must be given as a literal string. 

 Files are written to disk using the [SELECT INTO OUTFILE](../select-into-outfile/index) statement. You can then read the files back into a table using the `LOAD DATA INFILE` statement. The `FIELDS` and `LINES` clauses are the same in both statements. These clauses are optional, but if both are specified then the `FIELDS` clause must precede `LINES`.

 Executing this statement activates `INSERT` [triggers](../triggers/index).

 One must have the [FILE](../grant/index#file) privilege to be able to execute LOAD DATA INFILE. This is to ensure normal users cannot read system files. LOAD DATA LOCAL INFILE does not have this requirement.

 If the [secure\_file\_priv](../server-system-variables/index#secure_file_priv) system variable is set (by default it is not), the loaded file must be present in the specified directory.

 Note that MariaDB's [systemd](../systemd/index) unit file restricts access to `/home`, `/root`, and `/run/user` by default. See [Configuring access to home directories](../systemd/index#configuring-access-to-home-directories).

 ### `LOAD DATA LOCAL INFILE`

 When you execute the `LOAD DATA INFILE` statement, MariaDB Server attempts to read the input file from its own file system. By contrast, when you execute the `LOAD DATA LOCAL INFILE` statement, the client attempts to read the input file from its file system, and it sends the contents of the input file to the MariaDB Server. This allows you to load files from the client's local file system into the database.

 If you don't want to permit this operation (perhaps for security reasons), you can disable the `LOAD DATA LOCAL INFILE` statement on either the server or the client.

 * The `LOAD DATA LOCAL INFILE` statement can be disabled on the server by setting the [local\_infile](../server-system-variables/index#local_infile) system variable to `0`.
* The `LOAD DATA LOCAL INFILE` statement can be disabled on the client. If you are using [MariaDB Connector/C](../about-mariadb-connector-c/index), this can be done by unsetting the `CLIENT_LOCAL_FILES` capability flag with the [mysql\_real\_connect](../mysql_real_connect/index) function or by unsetting the `MYSQL_OPT_LOCAL_INFILE` option with [mysql\_optionsv](../mysql_optionsv/index) function. If you are using a different client or client library, then see the documentation for your specific client or client library to determine how it handles the `LOAD DATA LOCAL INFILE` statement.

 If the `LOAD DATA LOCAL INFILE` statement is disabled by either the server or the client and if the user attempts to execute it, then the server will cause the statement to fail with the following error message:

 
```
The used command is not allowed with this MariaDB version

```

Note that it is not entirely accurate to say that the MariaDB version does not support the command. It would be more accurate to say that the MariaDB configuration does not support the command. See [MDEV-20500](https://jira.mariadb.org/browse/MDEV-20500) for more information.

 From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the error message is more accurate:

 
```
The used command is not allowed because the MariaDB server or client 
  has disabled the local infile capability

```

### 
`REPLACE` and `IGNORE`

 If you load data from a file into a table that already contains data and has a [primary key](../getting-started-with-indexes/index#primary-key), you may encounter issues where the statement attempts to insert a row with a primary key that already exists. When this happens, the statement fails with Error 1064, protecting the data already on the table. If you want MariaDB to overwrite duplicates, use the `REPLACE` keyword.

 The `REPLACE` keyword works like the [REPLACE](../replace/index) statement. Here, the statement attempts to load the data from the file. If the row does not exist, it adds it to the table. If the row contains an existing primary key, it replaces the table data. That is, in the event of a conflict, it assumes the file contains the desired row. 

 This operation can cause a degradation in load speed by a factor of 20 or more if the part that has already been loaded is larger than the capacity of the [InnoDB Buffer Pool](../innodb-buffer-pool/index). This happens because it causes a lot of turnaround in the buffer pool.

 Use the `IGNORE` keyword when you want to skip any rows that contain a conflicting primary key. Here, the statement attempts to load the data from the file. If the row does not exist, it adds it to the table. If the row contains an existing primary key, it ignores the addition request and moves on to the next. That is, in the event of a conflict, it assumes the table contains the desired row.

 ### Character-sets

 When the statement opens the file, it attempts to read the contents using the default character-set, as defined by the [character\_set\_database](../server-system-variables/index#character_set_database) system variable. 

 In the cases where the file was written using a character-set other than the default, you can specify the character-set to use with the `CHARACTER SET` clause in the statement. It ignores character-sets specified by the [SET NAMES](../set-names/index) statement and by the [character\_set\_client](../server-system-variables/index#character_set_client) system variable. Setting the `CHARACTER SET` clause to a value of `binary` indicates "no conversion."

 The statement interprets all fields in the file as having the same character-set, regardless of the column data type. To properly interpret file contents, you must ensure that it was written with the correct character-set. If you write a data file with [mariadb-dump -T](../mariadb-dump/index) or with the [SELECT INTO OUTFILE](../select-into-outfile/index) statement with the [mariadb](../mariadb-command-line-client/index) client, be sure to use the `--default-character-set` option, so that the output is written with the desired character-set.

 When using mixed character sets, use the `CHARACTER SET` clause in both [SELECT INTO OUTFILE](../select-into-outfile/index) and `LOAD DATA INFILE` to ensure that MariaDB correctly interprets the escape sequences.

 
The [character\_set\_filesystem](../server-system-variables/index#character_set_filesystem) system variable controls the interpretation of the filename.

 It is currently not possible to load data files that use the `ucs2` character set.

 
### Preprocessing Inputs

 *col\_name\_or\_user\_var* can be a column name, or a user variable. In the case of a variable, the [SET](../set/index) statement can be used to preprocess the value before loading into the table.

 ### Priority and Concurrency

 In storage engines that perform table-level locking ([MyISAM](../myisam/index), [MEMORY](../memory/index) and [MERGE](../merge/index)), using the [LOW\_PRIORITY](../high_priority-and-low_priority-clauses/index) keyword, MariaDB delays insertions until no other clients are reading from the table. Alternatively, when using the [MyISAM](../myisam/index) storage engine, you can use the [CONCURRENT](../concurrent-inserts/index) keyword to perform concurrent insertion.

 
The `LOW_PRIORITY` and `CONCURRENT` keywords are mutually exclusive. They cannot be used in the same statement.

 
### Progress Reporting

 The `LOAD DATA INFILE` statement supports [progress reporting](../progress-reporting/index). You may find this useful when dealing with long-running operations. Using another client you can issue a [SHOW PROCESSLIST](../show-processlist/index) query to check the progress of the data load.

 ### Using mariadb-import

 MariaDB ships with a separate utility for loading data from files: [mariadb-import](../mariadb-import/index) (or `mysqlimport` before [MariaDB 10.5](../what-is-mariadb-105/index)). It operates by sending `LOAD DATA INFILE` statements to the server.

 Using [mariadb-import](../mariadb-import/index) you can compress the file using the `--compress` option, to get better performance over slow networks, providing both the client and server support the compressed protocol. Use the `--local` option to load from the local file system.

 ### Indexing

 In cases where the storage engine supports [ALTER TABLE... DISABLE KEYS](../alter-table/index#enable-disable-keys) statements ([MyISAM](../myisam/index) and [Aria](../aria/index)), the `LOAD DATA INFILE` statement automatically disables indexes during the execution.

 Examples
--------

 You have a file with this content (note the the separator is ',', not tab, which is the default):

 
```
2,2
3,3
4,4
5,5
6,8

```


```
CREATE TABLE t1 (a int, b int, c int, d int, PRIMARY KEY (a));
LOAD DATA LOCAL INFILE 
 '/tmp/loaddata7.dat' INTO TABLE t1 FIELDS TERMINATED BY ',' (a,b) SET c=a+b;
SELECT * FROM t1;
+------+------+------+
| a    | b    | c    |
+------+------+------+
|    2 |    2 |    4 |
|    3 |    3 |    6 |
|    4 |    4 |    8 |
|    5 |    5 |   10 |
|    6 |    8 |   14 |
+------+------+------+

```

Another example, given the following data (the separator is a tab):

 
```
1       a
2       b

```

The value of the first column is doubled before loading:

 
```
LOAD DATA INFILE 'ld.txt' INTO TABLE ld (@i,v) SET i=@i*2;

SELECT * FROM ld;
+------+------+
| i    | v    |
+------+------+
|    2 | a    |
|    4 | b    |
+------+------+

```

See Also
--------

 * [How to quickly insert data into MariaDB](../how-to-quickly-insert-data-into-mariadb/index)
* [Character Sets and Collations](../character-sets-and-collations/index)
* [SELECT ... INTO OUTFILE](../select-into-outfile/index)
* [mariadb-import](../mariadb-import/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-data-infile/>

Concurrent Inserts
==================

     The [MyISAM](../myisam/index) storage engine supports concurrent inserts. This feature allows [SELECT](../select/index) statements to be executed during [INSERT](../insert/index) operations, reducing contention.

 Whether concurrent inserts can be used or not depends on the value of the [concurrent\_insert](../server-system-variables/index#concurrent_insert) server system variable:

 * `NEVER` (0) disables concurrent inserts.
* `AUTO` (1) allows concurrent inserts only when the target table has no free blocks (no data in the middle of the table has been deleted after the last [OPTIMIZE TABLE](../optimize-table/index)). This is the default.
* `ALWAYS` (2) always enables concurrent inserts, in which case new rows are added at the end of a table if the table is being used by another thread.

 If the [binary log](../binary-log/index) is used, [CREATE TABLE ... SELECT](../create-table/index#create-table-select) and [INSERT ... SELECT](../insert-select/index) statements cannot use concurrent inserts. These statements acquire a read lock on the table, so concurrent inserts will need to wait. This way the log can be safely used to restore data.

 Concurrent inserts are not used by replicas with the row based [replication](../replication/index) (see [binary log formats](../binary-log-formats/index)).

 If an [INSERT](../insert/index) statement contain the [HIGH\_PRIORITY](../high_priority-and-low_priority-clauses/index) clause, concurrent inserts cannot be used. [INSERT ... DELAYED](../insert-delayed/index) is usually unneeded if concurrent inserts are enabled.

 [LOAD DATA INFILE](../load-data-infile/index) uses concurrent inserts if the `CONCURRENT` keyword is specified and [concurrent\_insert](../server-system-variables/index#concurrent_insert) is not `NEVER`. This makes the statement slower (even if no other sessions access the table) but reduces contention.

 [LOCK TABLES](../transactions-lock/index) allows non-conflicting concurrent inserts if a `READ LOCAL` lock is used. Concurrent inserts are not allowed if the `LOCAL` keyword is omitted.

 Notes
-----

 The decision to enable concurrent insert for a table is done when the table is opened. If you change the value of [concurrent\_insert](../server-system-variables/index#concurrent_insert) it will only affect new opened tables. If you want it to work for also for tables in use or cached, you should do [FLUSH TABLES](../flush/index) after setting the variable.

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/concurrent-inserts/>

Enabling Core Dumps
===================

    Enabling in an Option File
--------------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, core dumps are enabled by default on **Windows**, so **this step can be skipped on Windows** in those versions. See [MDEV-18439](https://jira.mariadb.org/browse/MDEV-18439) for more information.

 
In order to enable core dumps, you need to set the `[core\_file](../server-system-variables/index#core_file)` system variable either on the command-line or in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
core_file

```

You can check your current value by executing:

 
```
my_print_defaults --mysqld

```


**MariaDB starting with [10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/)**In [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/), and [MariaDB 10.3.9](https://mariadb.com/kb/en/mariadb-1039-release-notes/) and later, `[core\_file](../server-system-variables/index#core_file)` has also been made into a system variable. Previously it was just an option. It's value can be checked at runtime by executing the following:

 
```
SHOW GLOBAL VARIABLES LIKE 'core_file';

```


Core Files on Linux
-------------------

 There are some additional details related to using core files on Linux.

 ### Disabling Core File Size Restrictions on Linux

 On some systems there is a limit on the sizes of core files that can be dumped. You can check the system's current system-wide limit by executing the following:

 
```
ulimit -c

```

You can check the current limit of the `mysqld` process specifically by executing the following:

 
```
sudo cat /proc/$(pidof mysqld)/limits | grep "core file"

```

If you need to change the core size limit, the method you use depends on how you start `mysqld`. See the sections below for more details.

 
**MariaDB starting with [10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/)**In [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) and later, the resource limits for the `mysqld` process are printed to the [error log](../error-log/index) when the `mysqld` process crashes. That way, users can confirm whether the process may have been allowed to dump a core file. See [MDEV-15051](https://jira.mariadb.org/browse/MDEV-15051) for more information.

 
#### Running mysqld Using mysqld\_safe

 If you are starting MariaDB by running `[mysqld\_safe](../mysqld_safe/index)`, then configuring the following in the `[mysqld_safe]` option group in an option file should allow for unlimited sized core files:

 
```
[mysqld_safe]
...
core_file_size=unlimited

```

You can check your current values by executing:

 
```
my_print_defaults mysqld_safe

```

See [mysqld\_safe: Configuring the Core File Size](../mysqld_safe/index#configuring-the-core-file-size) for more details.

 
**Note:** If you are using `[mysqld\_safe](../mysqld_safe/index)` and running `mysqld` as the `root` user, then no core file is created on some systems. The solution is to run `mysqld` as another user.

 
#### Running mysqld Manually

 If you are starting mysqld manually or in a custom script, then you can allow for unlimited sized core files by executing the following in the same shell or script in which mysqld is executed:

 
```
ulimit -c unlimited

```

#### Running mysqld Using systemd

 If you are starting `mysqld` using `[systemd](../systemd/index)`, then you may need to customize the MariaDB service to allow for unlimited size core files. For example, you could execute the following:

 Using `sudo systemctl edit mariadb.service` add the contents:

 
```
[Service]

LimitCORE=infinity

```

See [systemd: Configuring the Core File Size](../systemd/index#configuring-the-core-file-size) for more details.

 #### Changing the System-Wide Limit

 If you want to change the system-wide limit to allow for unlimited size core files for for the `mysql` user account, then you can do so by adding the following lines to a file in `[/etc/security/limits.d/](https://linux.die.net/man/5/limits.conf)`. For example:

 
```
sudo tee /etc/security/limits.d/mariadb_core.conf <<EOF
mysql soft core unlimited
mysql hard core unlimited
EOF

```

The system would have to be restarted for this change to take effect.

 See [Configuring Linux for MariaDB: Configuring the Core File Size](../configuring-linux-for-mariadb/index#configuring-the-core-file-size) for more details.

 ### Setting the Path on Linux

 If you are using Linux, then it can be helpful to change a few settings to alter where the core files is written and what file name is used. This is done by setting the `kernel.core_pattern` and `kernel.core_uses_pid` attributes. You can check the current values by executing the following:

 
```
sysctl kernel.core_pattern
sysctl kernel.core_uses_pid

```

If you are using `mysql-test-run` and want to have the core as part of the test result, the optimal setting is probably the following (store cores in the current directory as `core.number-of-process-id`):

 
```
sudo sysctl kernel.core_pattern=core.%p kernel.core_uses_pid=0

```

If you are using a production system, you probably want to have the core files in a specific directory, not in the data directory. They place to store cores can be temporarily altered using the `[sysctl](https://linux.die.net/man/8/sysctl)` utility, but it is often more common to alter them via the `[/proc](https://linux.die.net/man/5/proc)` file system. See the following example:

 
```
sudo mkdir /tmp/corefiles
sudo chmod 777 /tmp/corefiles
sudo echo /tmp/corefiles/core > /proc/sys/kernel/core_pattern
sudo echo 1 > /proc/sys/kernel/core_uses_pid

```

The above commands will tell the system to put core files in `/tmp/corefiles`, and it also tells the system to put the process ID in the file name.

 If you want to make these changes permanent, then you can add the following to a file in `[/etc/sysctl.conf.d/](https://linux.die.net/man/5/sysctl.conf)`. For example:

 
```
sudo tee /etc/sysctl.d/mariadb_core.conf <<EOF
kernel.core_pattern=/tmp/corefiles/core
kernel.core_uses_pid=1
EOF

```


**MariaDB starting with [10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/)**In [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) and later, the value of `kernel.core_pattern` is printed to the [error log](../error-log/index) when the `mysqld` process crashes. That way, users can determine where the process may have dumped a core file. See [MDEV-15051](https://jira.mariadb.org/browse/MDEV-15051) for more information.

 

**MariaDB until [10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/)**In [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/) and before, the [error log](../error-log/index) contains a message indicating that a core file would be written in the `[datadir](../server-system-variables/index#datadir)` when the `mysqld` process crashes, even if this was not true because the `kernel.core_pattern` actually configured the process to write the core file in a different directory.

 

**Note:** Ensure that you have enough free disk space in the path pointed to by `kernel.core_pattern`. 

 
#### Extracting Linux core dumps with systemd-coredump

 Core dump management can be automated using `[coredumpctl](#)` utility.

 This is enabled per default on Red Hat Enterprise Linux 8 and CentOS 8, and maybe other contemporary Linux distribution releases by now, too. It can be easily checked for by looking at the `kernel.core_pattern setting`. If it looks like this systemd-coredump is enabled:

 
```
# sysctl kernel.core_pattern
kernel.core_pattern = |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e

```

On other distributions like Ubuntu (at least up to 21.10) it is not enabled by default, but can be set up manually.

 To see all recent core dumps on the system you can then simply run

 
```
# coredumpctl list

```

Or you can check for MariaDB Server core dumps specifically with:

 
```
# coredumpctl list /usr/sbin/mariadbd 

```

If an actual core file got stored you'll see `present` in the COREFILE column of the output, you can then extract the core file with:

 
```
# coredump dump -o mariadbd.core ...PID...

```

using the process id number from the PID column, or when you just want to retrieve the latest MariaDB Server related entry:

 
```
# coredump dump -o mariadb.core /usr/sbin/mariadbd

```

Starting with `systemd` 248 it is also possible to invoke the `gdb` debugger directly using the new `--debugger-arguments=...` option, e.g. making the extraction of all thread backtraces from the most recent MariaDB server crash a one liner without even having to extract the core dump file first (requires `gdb` to be installed):

 
```
# coredumpctl debug --debugger-arguments="-batch -ex 'thread apply all bt full'" /usr/sbin/mariadbd

```

So far none of the long term support Linux distribution releases have a new enough `systemd` version for this, the (as of this writing) still upcoming Ubuntu 22.04 "Jammy Jellyfish" will probably the first to support this.

 ### Core Dumps and setuid on Linux

 Since `mysqld` executes `[setuid](https://linux.die.net/man/2/setuid)`, you may have to set `fs.suid_dumpable=2` to allow core dumps on Linux. You can check the current `fs.suid_dumpable` value by using the `[sysctl](https://linux.die.net/man/8/sysctl)` utility. For example:

 
```
sysctl fs.suid_dumpable

```

You can temporarily set it to `2` by using the `[sysctl](https://linux.die.net/man/8/sysctl)` utility. For example:

 
```
sudo sysctl -w fs.suid_dumpable=2

```

Or you can temporarily set it to `2` by writing to the `[/proc](https://linux.die.net/man/5/proc)` file system. For example:

 
```
sudo echo 2 > /proc/sys/fs/suid_dumpable

```

If you want to permanently set it to `2` then you can add the following to a file in `[/etc/sysctl.conf.d/](https://linux.die.net/man/5/sysctl.conf)`:

 
```
sudo tee /etc/sysctl.d/mariadb_fs_suid_dumpable.conf <<EOF
fs.suid_dumpable=2
EOF

```


**Note:** If you don't want to change `fs.suid_dumpable`, then another solution is to start `mysqld` directly as the `mysql` user, so that the `[setuid](https://linux.die.net/man/2/setuid)` call is not needed.

 
### Forcing a Core File on Linux

 To force a core file for `mysqld` you can send the process the `sigabrt` signal, which has the signal code `6`. This is very useful to get the state of the unresponsive `mysqld` process. However, this will cause `mysqld` to crash, and crash recovery will be run on restart.

 You can send the signal with the `[kill](https://linux.die.net/man/1/kill)` command. For example:

 
```
sudo kill -6 $(pidof mysqld)

```

As an alternative to `$(pidof mysqld)`, you can find the process ID either by using the `[ps](https://linux.die.net/man/1/ps)` utility or by checking the file defined by the `[pid\_file](../server-system-variables/index#pid_file)` system variable.

 Core Files on Windows
---------------------

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, core dumps are enabled by default on Windows. See [MDEV-18439](https://jira.mariadb.org/browse/MDEV-18439) for more information.

 There are some additional details related to using core files on Windows. 

 Core Files on Kubernetes
------------------------

 See the IBM [Core Dump Handler](https://github.com/IBM/core-dump-handler) project.

 ### Minidump Files on Windows

 On Windows, the core file is created as a [minidump file](https://docs.microsoft.com/en-us/windows/desktop/debug/minidump-files).

 For details on how to configure and read the [minidump file](https://docs.microsoft.com/en-us/windows/desktop/debug/minidump-files), see [How to read the small memory dump file that is created by Windows if a crash occurs](https://support.microsoft.com/en-us/help/315263/how-to-read-the-small-memory-dump-file-that-is-created-by-windows-if-a).

 Core Files and Address Sanitizer (ASAN)
---------------------------------------

 If your `mysqld` binary is built with [Address Sanitizer (ASAN)](../how-to-compile-and-use-mariadb-with-addresssanitizer-asan/index) then it will not be able to generate a core file.

 What's Included in Core Files
-----------------------------

 Core files usually contain a dump of all memory in the process's full address space. This means that if a server has some large buffers configured (such as a large [InnoDB buffer pool](../xtradbinnodb-buffer-pool/index)), then the server's core files can get very large.

 However, in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) and later, some large buffers have been excluded from core files on some systems as a way to reduce the size.

 The following buffers are excluded:

 * [InnoDB buffer pool](../xtradbinnodb-buffer-pool/index)
* [InnoDB log buffer](../innodb-system-variables/index#innodb_log_buffer_size)
* InnoDB Redo log buffer (fixed 2M)
* [Query cache](../query-cache/index)

 The buffers are only excluded on Linux when using kernel version 3.4 and above and when using a non-debug build of `mysqld`. Some Linux kernel versions have a [bug](https://lists.launchpad.net/maria-discuss/msg05245.html) which would cause the following warning to be printed to the log:

 
```
Sep 25 10:41:19 srv1 mysqld: 2018-09-25 10:41:19 0 [Warning] InnoDB: Failed to set memory to DODUMP: Invalid argument ptr 0x2aaac3400000 size 33554432

```

In those cases, the core dump may exclude some additional data. If that is not a concern, then the warning can be ignored. The problem can be fixed by upgrading to a Linux kernel version in which the bug is fixed.

 See Also
--------

 * [How to Produce a Full Stack Trace for mysqld](../how-to-produce-a-full-stack-trace-for-mysqld/index)
* [HowTo: Debug Crashed Linux Application Core Files Like A Pro](http://www.cyberciti.biz/tips/linux-core-dumps.html)
* [A Nice Feature in MariaDB 10.3: no InnoDB Buffer Pool in Core Dumps](https://www.percona.com/community-blog/2018/06/28/nice-feature-in-mariadb-103-no-innodb-buffer-pool-in-coredumps/)
* [Getting MySQL Core file on Linux](https://www.percona.com/blog/2011/08/26/getting-mysql-core-file-on-linux/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/enabling-core-dumps/>

FOR UPDATE
==========

    InnoDB supports row-level locking. Selected rows can be locked using [LOCK IN SHARE MODE](../lock-in-share-mode/index) or FOR UPDATE. In both cases, a lock is acquired on the rows read by the query, and it will be released when the current transaction is committed.

 The `FOR UPDATE` clause of [SELECT](../select/index) applies only when [autocommit](../server-system-variables/index#autocommit) is set to 0 or the `SELECT` is enclosed in a transaction. A lock is acquired on the rows, and other transactions are prevented from writing the rows, acquire locks, and from reading them (unless their isolation level is `[READ UNCOMMITTED](../set-transaction-isolation-level/index#read-uncommitted)`).

 If `autocommit` is set to 1, the [LOCK IN SHARE MODE](../lock-in-share-mode/index) and `FOR UPDATE` clauses have no effect.

 If the isolation level is set to [SERIALIZABLE](../set-transaction-isolation-level/index#serializable), all plain `SELECT` statements are converted to `SELECT ... LOCK IN SHARE MODE`.

 Example
-------

 
```
SELECT * FROM trans WHERE period=2001 FOR UPDATE;

```

See Also
--------

 * [SELECT](../select/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [InnoDB Lock Modes](../innodb-lock-modes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/for-update/>

The Debug Sync Facility
=======================

     The Debug Sync Facility allows placement of synchronization points in the server code by using the DEBUG\_SYNC macro:

 
```
open_tables(...)

DEBUG_SYNC(thd, "after_open_tables");

lock_tables(...)

```

When activated, a sync point can

 * Emit a signal and/or
* Wait for a signal

 


| Nomenclature | Description |
| --- | --- |
| signal | A value of a global variable that persists until overwritten by a new signal. The global variable can also be seen as a "signal post" or "flag mast". Then the signal is what is attached to the "signal post" or "flag mast". |
| emit a signal | Assign the value (the signal) to the global variable ("set a flag") and broadcast a global condition to wake those waiting for a signal. |
| wait for a signal | Loop over waiting for the global condition until the global value matches the wait-for signal. |

 
By default, all sync points are inactive. They do nothing (except to burn a couple of CPU cycles for checking if they are active).

 A sync point becomes active when an action is requested for it. To do so, put a line like this in the test case file:

 
```
SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';

```

This activates the sync point `'after_open_tables'`. It requests it to emit the signal `'opened'` and wait for another thread to emit the signal `'flushed'` when the thread's execution runs through the sync point.

 For every sync point there can be one action per thread only. Every thread can request multiple actions, but only one per sync point. In other words, a thread can activate multiple sync points.

 Here is an example how to activate and use the sync points:

 
```
--connection conn1
SET DEBUG_SYNC= 'after_open_tables SIGNAL opened WAIT_FOR flushed';
send INSERT INTO t1 VALUES(1);
    --connection conn2
    SET DEBUG_SYNC= 'now WAIT_FOR opened';
    SET DEBUG_SYNC= 'after_abort_locks SIGNAL flushed';
    FLUSH TABLE t1;

```

When `conn1` runs through the `INSERT` statement, it hits the sync point `'after_open_tables'`. It notices that it is active and executes its action. It emits the signal `'opened'` and waits for another thread to emit the signal `'flushed'`.

 `conn2` waits immediately at the special sync point `'now'` for another thread to emit the `'opened'` signal.

 A signal remains in effect until it is overwritten. If `conn1` signals `'opened'` before `conn2` reaches `'now'`, `conn2` will still find the `'opened'` signal. It does not wait in this case.

 When `conn2` reaches `'after_abort_locks'`, it signals `'flushed'`, which lets `conn1` awake.

 Normally the activation of a sync point is cleared when it has been executed. Sometimes it is necessary to keep the sync point active for another execution. You can add an execute count to the action:

 
```
SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 3';

```

This sets the signal point's activation counter to 3. Each execution decrements the counter. After the third execution the sync point becomes inactive.

 One of the primary goals of this facility is to eliminate sleeps from the test suite. In most cases it should be possible to rewrite test cases so that they do not need to sleep. (But this facility cannot synchronize multiple processes.) However, to support test development, and as a last resort, sync point waiting times out. There is a default timeout, but it can be overridden:

 
```
SET DEBUG_SYNC= 'name WAIT_FOR sig TIMEOUT 10 EXECUTE 2';

```

`TIMEOUT 0` is special: If the signal is not present, the wait times out immediately.

 When a wait timed out (even on `TIMEOUT 0`), a warning is generated so that it shows up in the test result.

 You can throw an error message and kill the query when a synchronization point is hit a certain number of times:

 
```
SET DEBUG_SYNC= 'name HIT_LIMIT 3';

```

Or combine it with signal and/or wait:

 
```
SET DEBUG_SYNC= 'name SIGNAL sig EXECUTE 2 HIT_LIMIT 3';

```

Here the first two hits emit the signal, the third hit returns the error message and kills the query.

 For cases where you are not sure that an action is taken and thus cleared in any case, you can force to clear (deactivate) a sync point:

 
```
SET DEBUG_SYNC= 'name CLEAR';

```

If you want to clear all actions and clear the global signal, use:

 
```
SET DEBUG_SYNC= 'RESET';

```

This is the only way to reset the global signal to an empty string.

 For testing of the facility itself you can execute a sync point just as if it had been hit:

 
```
SET DEBUG_SYNC= 'name TEST';

```

### Formal Syntax

 The string to "assign" to the DEBUG\_SYNC variable can contain:

 
```
RESET |
<sync point name> TEST |
<sync point name> CLEAR |
<sync point name> {{SIGNAL <signal name> |
                   WAIT_FOR <signal name> [TIMEOUT <seconds>]}
                   [EXECUTE <count>] &| HIT_LIMIT <count>}

```

Here '&|' means 'and/or'. This means that one of the sections separated by '&|' must be present or both of them.

 ### Activation/Deactivation

 With a [MariaDB for debug build](../compiling-mariadb-for-debugging/index), it can be enabled by a mysqld command line option:

 
```
 --debug-sync-timeout[=default_wait_timeout_value_in_seconds]

```

`'default_wait_timeout_value_in_seconds'` is the default timeout for the `WAIT_FOR` action. If set to zero, the facility stays disabled.

 The facility is enabled by default in the test suite, but can be disabled with:

 
```
mariadb-test-run.pl ... --debug-sync-timeout=0 ...

```

Likewise the default wait timeout can be set:

 
```
mariadb-test-run.pl ... --debug-sync-timeout=10 ...

```

The command line option influences the readable value of the [debug\_sync](../server-system-variables/index#debug_sync) system variable.

 * If the facility is not compiled in, the system variable does not exist.

 * If `--debug-sync-timeout=0` the value of the variable reads as `"OFF"`.

 * Otherwise the value reads as `"ON - current signal: "` followed by the current signal string, which can be empty.

 The readable variable value is the same, regardless if read as a global or session value.

 Setting the [debug\_sync](../server-system-variables/index#debug_sync) system variable requires the `'SUPER'` privilege. You can never read back the string that you assigned to the variable, unless you assign the value that the variable already has. But that would give a parse error. A syntactically correct string is parsed into a debug sync action and stored apart from the variable value.

 ### Implementation

 Pseudo code for a sync point:

 
```
#define DEBUG_SYNC(thd, sync_point_name)
        if (unlikely(opt_debug_sync_timeout))
          debug_sync(thd, STRING_WITH_LEN(sync_point_name))

```

The sync point performs a binary search in a sorted array of actions for this thread.

 The `SET DEBUG_SYNC` statement adds a requested action to the array or overwrites an existing action for the same sync point. When it adds a new action, the array is sorted again.

 ### A typical synchronization pattern

 There are quite a few places in MariaDB and MySQL where we use a synchronization pattern like this:

 
```
mysql_mutex_lock(&mutex);
thd->enter_cond(&condition_variable, &mutex, new_message);
#if defined(ENABLE_DEBUG_SYNC)
if (!thd->killed && !end_of_wait_condition)
   DEBUG_SYNC(thd, "sync_point_name");
#endif
while (!thd->killed && !end_of_wait_condition)
  mysql_cond_wait(&condition_variable, &mutex);
thd->exit_cond(old_message);

```

Here are some explanations:

 `thd->enter_cond()` is used to register the condition variable and the mutex in `thd->mysys_var`. This is done to allow the thread to be interrupted (killed) from its sleep. Another thread can find the condition variable to signal and mutex to use for synchronization in this thread's `THD::mysys_var`.

 `thd->enter_cond()` requires the mutex to be acquired in advance.

 `thd->exit_cond()` unregisters the condition variable and mutex and releases the mutex.

 If you want to have a Debug Sync point with the wait, please place it behind `enter_cond()`. Only then you can safely decide, if the wait will be taken. Also you will have `THD::proc_info` correct when the sync point emits a signal. `DEBUG_SYNC` sets its own proc\_info, but restores the previous one before releasing its internal mutex. As soon as another thread sees the signal, it does also see the proc\_info from before entering the sync point. In this case it will be "new\_message", which is associated with the wait that is to be synchronized.

 In the example above, the wait condition is repeated before the sync point. This is done to skip the sync point, if no wait takes place. The sync point is before the loop (not inside the loop) to have it hit once only. It is possible that the condition variable is signaled multiple times without the wait condition to be true.

 A bit off-topic: At some places, the loop is taken around the whole synchronization pattern:

 
```
while (!thd->killed && !end_of_wait_condition)
{
  mysql_mutex_lock(&mutex);
  thd->enter_cond(&condition_variable, &mutex, new_message);
  if (!thd->killed [&& !end_of_wait_condition])
  {
    [DEBUG_SYNC(thd, "sync_point_name");]
    mysql_cond_wait(&condition_variable, &mutex);
  }
  thd->exit_cond(old_message);
}

```

Note that it is important to repeat the test for thd->killed after `enter_cond()`. Otherwise the killing thread may kill this thread after it tested `thd->killed` in the loop condition and before it registered the condition variable and mutex in `enter_cond()`. In this case, the killing thread does not know that this thread is going to wait on a condition variable. It would just set `THD::killed`. But if we would not test it again, we would go asleep though we are killed. If the killing thread would kill us when we are after the second test, but still before sleeping, we hold the mutex, which is registered in mysys\_var. The killing thread would try to acquire the mutex before signaling the condition variable. Since the mutex is only released implicitly in `mysql_cond_wait()`, the signaling happens at the right place. We have a safe synchronization.

 ### Co-work with the DBUG facility

 When running the MariaDB test suite with the `--debug-dbug` command line option, the Debug Sync Facility writes trace messages to the DBUG trace. The following shell commands proved very useful in extracting relevant information:

 
```
egrep 'query:|debug_sync_exec:' mysql-test/var/log/mysqld.1.trace

```

It shows all executed SQL statements and all actions executed by synchronization points.

 Sometimes it is also useful to see, which synchronization points have been run through (hit) with or without executing actions. Then add `"|debug_sync_point:"` to the egrep pattern.

 ### Synchronizing DEBUG\_SYNC Actions

 Tests may need additional synchronization mechanisms between `DEBUG_SYNC` actions, because certain combinations of actions can result in lost signals. More specifically, once a `SIGNAL` action is issued, it is stored in a global variable for any waiting threads to determine if they are depending on that signal for continuing. However, if a subsequent action overwrites that variable before a waiting thread is able to check against it, the original signal is lost. Examples of actions which would change the variable state are another `SIGNAL` or a `RESET`. Therefore, before issuing these commands, the test writer should verify the previous signal has been acknowledged. The following code snippets show an example of a problematic pattern and a potential solution.

 
```
SET DEBUG_SYNC='now SIGNAL sig';
SET DEBUG_SYNC='RESET'; # Problematic because sig can be cleared before a waiting thread can acknowledge it

```


```
SET DEBUG_SYNC='now SIGNAL sig';

# Don't issue the RESET until we have proven the waiting thread has received the signal
let $wait_condition= select count(*)=0 from information_schema.processlist where state like "debug sync point%";
source include/wait_condition.inc;

SET DEBUG_SYNC='RESET'; # Now this is safe

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-debug-sync-facility/>

Events Overview
===============

     [Events](stored-programs-and-views-event) are named database objects containing SQL statements that are to be executed at a later stage, either once off, or at regular intervals.

 They function very similarly to the Windows Task Scheduler or Unix cron jobs.

 Creating, modifying or deleting events requires the [EVENT privilege](../grant/index#database-privileges).

 Creating Events
---------------

 Events are created with the [CREATE EVENT](../create-event/index) statement.

 ### Example

 
```
CREATE EVENT test_event 
  ON SCHEDULE EVERY 1 MINUTE DO 
   UPDATE test.t1 SET a = a + 1;

```

Executing Events
----------------

 Events are only executed if the event scheduler is running. This is determined by the value of the [event\_scheduler](../server-system-variables/index#event_scheduler) system variable, which needs to be set to `On` for the event scheduler to be running.

 You can check if the Event scheduler is running with:

 
```
SHOW PROCESSLIST;
+----+-----------------+-----------+------+---------+------+-----------------------------+------------------+----------+
| Id | User            | Host      | db   | Command | Time | State                       | Info             | Progress |
+----+-----------------+-----------+------+---------+------+-----------------------------+------------------+----------+
| 40 | root            | localhost | test | Sleep   | 4687 |                             | NULL             |    0.000 |
| 41 | root            | localhost | test | Query   |    0 | init                        | SHOW PROCESSLIST |    0.000 |
| 42 | event_scheduler | localhost | NULL | Daemon  |   30 | Waiting for next activation | NULL             |    0.000 |
+----+-----------------+-----------+------+---------+------+-----------------------------+------------------+----------+

```

If the event scheduler is not running and `event_scheduler` has been set to `OFF`, use:

 
```
SET GLOBAL event_scheduler = ON;

```

to activate it. If `event_scheduler` has been set to `Disabled`, you cannot change the value at runtime. Changing the value of the `event_scheduler` variable requires the SUPER privilege.

 Since [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/), setting the [event\_scheduler](../server-system-variables/index#event_scheduler) system variable will also try to reload the [mysql.event table](../mysqlevent-table/index) if it was not properly loaded at startup.

 Viewing Current Events
----------------------

 A list of current events can be obtained with the [SHOW EVENTS](../show-events/index) statement. This only shows the event name and interval - the full event details, including the SQL, can be seen by querying the [Information Schema EVENTS table](../information-schema-events-table/index), or with [SHOW CREATE EVENT](../show-create-event/index).

 If an event is currently being executed, it can be seen by querying the [Information Schema PROCESSLIST table](../information-schema-processlist-table/index), or with the [SHOW PROCESSLIST](../show-processlist/index) statement.

 ### Example

 
```
SHOW EVENTS\G;
*************************** 1. row ***************************
                  Db: test
                Name: test_event
             Definer: root@localhost
           Time zone: SYSTEM
                Type: RECURRING
          Execute at: NULL
      Interval value: 1
      Interval field: MINUTE
              Starts: 2013-05-20 13:46:56
                Ends: NULL
              Status: ENABLED
          Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```


```
SHOW CREATE EVENT test_event\G
*************************** 1. row ***************************
               Event: test_event
            sql_mode: 
           time_zone: SYSTEM
        Create Event: CREATE DEFINER=`root`@`localhost` EVENT `test_event` ON SCHEDULE EVERY 1 MINUTE STARTS '2013-05-20 13:46:56' ON COMPLETION NOT PRESERVE ENABLE DO UPDATE test.t1 SET a = a + 1
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Altering Events
---------------

 An event can be changed with the [ALTER EVENT](../alter-event/index) statement.

 ### Example

 
```
ALTER EVENT test_event ON SCHEDULE EVERY '2:3' DAY_HOUR;

```

Dropping Events
---------------

 Events are dropped with the [DROP EVENT](../drop-event/index) statement. Events are also also automatically dropped once they have run for the final time according to their schedule, unless the ON COMPLETION PRESERVE clause has been specified.

 ### Example

 
```
DROP EVENT test_event;
Query OK, 0 rows affected (0.00 sec)

```

See Also
--------

 * [CREATE EVENT](../create-event/index)
* [SHOW CREATE EVENT](../show-create-event/index)
* [ALTER EVENT](../alter-event/index)
* [DROP EVENT](../drop-event/index)
* [Event Limitations](../event-limitations/index)
* [Automating MariaDB Tasks with Events](../automating-mariadb-tasks-with-events/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/events/>

Full-Text Indexes
==================

   MariaDB has support for full-text indexing and searching.

  

| Title | Description |
| --- | --- |
|  [Full-Text Index Overview](../full-text-index-overview/index) |  Full-text indexing and searching overview.  |
|  [Full-Text Index Stopwords](../full-text-index-stopwords/index) |  Default list of full-text stopwords used by MATCH...AGAINST.  |
|  [MATCH AGAINST](../match-against/index) |  Perform a fulltext search on a fulltext index.  |
|  [myisam\_ftdump](../myisam_ftdump/index) |  A tool for displaying information on MyISAM FULLTEXT indexes.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/full-text-indexes/>

Differences in MariaDB in Debian (and Ubuntu)
=============================================

    The `[.deb](../installing-mariadb-deb-files/index)` packages provided by MariaDB Foundation's and MariaDB Corporation's repositories are not identical to the official `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories. 

 The packages provided by MariaDB Foundation's and MariaDB Corporation's repositories are generated using the Debian packaging in MariaDB's official [source code](../getting-the-mariadb-source-code/index). The Debian packaging scripts are specifically in the `debian/` directory.

 The packages provided by Debian's and Ubuntu's default repositories are generated using the Debian packaging in Debian's mirror of MariaDB's source code, which contains some custom changes. The source tree can be found here:

 * <https://salsa.debian.org/mariadb-team/mariadb-server>

 As a consequence, MariaDB behaves a bit differently if it is installed from Debian's and Ubuntu's default repositories.

 Option File Locations
---------------------

 * The [option file](../configuring-mariadb-with-option-files/index) located at `/etc/mysql/my.cnf` is handled by the `[update-alternatives](http://manpages.ubuntu.com/manpages/trusty/en/man8/update-alternatives.8.html)` mechanism when the `mysql-common` package is installed. It is a symbolic link that references either `mysql.cnf` or `mariadb.cnf` depending on whether MySQL or MariaDB is installed. Most of the MariaDB [option files](../configuring-mariadb-with-option-files/index) are therefore actually located in `/etc/mysql/mariadb.d/`.

 System Variables
----------------

 


| Variable | MariaDB in Debian | Standard MariaDB | Notes |
| --- | --- | --- | --- |
| [character\_set\_server](../server-system-variables/index#character_set_server) | utf8mb4 | latin1 | Debian sets a default character set that can support emojis etc. |
| [collation\_server](../server-system-variables/index#collation_server) | utf8mb4\_general\_ci | latin1\_swedish\_ci |  |

 
Options
-------

 


| Option | MariaDB in Debian | Standard MariaDB | Notes |
| --- | --- | --- | --- |
| `[plugin-load-add](../mysqld-options/index#-plugin-load-add)` | `auth_socket.so` | - | Before [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), MariaDB did not enable the `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin by default.This is default in Debian, allowing passwordless login. |

 
TLS
---

 * MariaDB binaries from `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories are linked with a different TLS library than MariaDB binaries from `[.deb](../installing-mariadb-deb-files/index)` packages provided by MariaDB Foundation's and MariaDB Corporation's repositories.

 * MariaDB Server binaries:
	+ In [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) and later, MariaDB Server is statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories.
	+ In [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) and before, MariaDB Server is statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories.
	+ In contrast, MariaDB Server is dynamically linked with the system's [OpenSSL](https://www.openssl.org/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by MariaDB Foundation and MariaDB Corporation.

 * MariaDB [client and utility](../clients-utilities/index) binaries:
	+ In [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [GnuTLS](https://www.gnutls.org/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) libraries.
	+ In [MariaDB 10.2](../what-is-mariadb-102/index) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [GnuTLS](https://www.gnutls.org/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) libraries.
	+ In [MariaDB 10.1](../what-is-mariadb-101/index) and earlier, MariaDB's [clients and utilities](../clients-utilities/index) and [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) are statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories.
	+ In contrast, MariaDB's [clients and utilities](../clients-utilities/index), [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html), and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [OpenSSL](https://www.openssl.org/) libraries in `[.deb](../installing-mariadb-deb-files/index)` packages provided by MariaDB Foundation's and MariaDB Corporation's repositories.

 * See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 Authentication
--------------

 * The `[unix\_socket](../authentication-plugin-unix-socket/index)` authentication plugin is installed by default in **new installations** that use the `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's default repositories in Debian 9 and later and Ubuntu's default repositories in Ubuntu 15.10 and later.

 * The `root@localhost` created by [mariadb-install-db](../mariadb-install-db/index) will also be created to authenticate via the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin in these builds.

 See Also
--------

 * [Moving from MySQL to MariaDB in Debian 9](../moving-from-mysql-to-mariadb-in-debian-9/index)

 More Information
----------------

 For details, check out the Debian and Ubuntu official repositories:

 * <https://packages.debian.org/search?keywords=mariadb-server&searchon=names&suite=all&section=all>
* <http://packages.ubuntu.com/search?keywords=mariadb-server&searchon=names&suite=all&section=all>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/differences-in-mariadb-in-debian/>

Perl Compatible Regular Expressions (PCRE) Documentation
========================================================

    PCRE Versions
-------------

 


| PCRE Version | Introduced | Maturity |
| --- | --- | --- |
| [PCRE2](http://www.pcre.org/) 10.34 | [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) | Stable |
| PCRE 8.43 | [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/) | Stable |
| PCRE 8.42 | [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10133-release-notes/), [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10035-release-notes/) | Stable |
| PCRE 8.41 | [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/), [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/), [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10032-release-notes/) | Stable |
| PCRE 8.40 | [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/), [MariaDB 10.0.30](https://mariadb.com/kb/en/mariadb-10030-release-notes/) | Stable |
| PCRE 8.39 | [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10026-release-notes/) | Stable |
| PCRE 8.38 | [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/) | Stable |
| PCRE 8.37 | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) | Stable |
| PCRE 8.36 | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) | Stable |
| PCRE 8.35 | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/), [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/) | Stable |
| PCRE 8.34 | [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-1008-release-notes/) | Stable |

  PCRE Enhancements
-----------------

 [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) switched to the PCRE library, which significantly improved the power of the [REGEXP/RLIKE](../regexp/index) operator.

 The switch to PCRE added a number of features, including recursive patterns, named capture, look-ahead and look-behind assertions, non-capturing groups, non-greedy quantifiers, Unicode character properties, extended syntax for characters and character classes, multi-line matching, and many other.

 Additionally, [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) introduced three new functions that work with regular expressions: [REGEXP\_REPLACE()](../regexp_replace/index), [REGEXP\_INSTR()](../regexp_instr/index) and [REGEXP\_SUBSTR()](../regexp_substr/index).

 Also, REGEXP/RLIKE, and the new functions, now work correctly with all multi-byte [character sets](../data-types-character-sets-and-collations/index) supported by MariaDB, including East-Asian character sets (big5, gb2313, gbk, eucjp, eucjpms, cp932, ujis, euckr), and Unicode character sets (utf8, utf8mb4, ucs2, utf16, utf16le, utf32). In earlier versions of MariaDB (and all MySQL versions) REGEXP/RLIKE works correctly only with 8-bit character sets.

 New Regular Expression Functions
--------------------------------

 * [REGEXP\_REPLACE(subject, pattern, replace)](../regexp_replace/index) - Replaces all occurrences of a pattern.
* [REGEXP\_INSTR(subject, pattern)](../regexp_instr/index) - Position of the first appearance of a regex .
* [REGEXP\_SUBSTR(subject,pattern)](../regexp_substr/index) - Returns the matching part of a string.

 See the individual articles for more details and examples.

 PCRE Syntax
-----------

 In most cases PCRE is backward compatible with the old POSIX 1003.2 compliant regexp library (see [Regular Expressions Overview](../regular-expressions-overview/index)), so you won't need to change your applications that use SQL queries with the REGEXP/RLIKE predicate.

 [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) introduced the [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable to address the remaining compatibilities between PCRE and the old regex library. 

 This section briefly describes the most important extended PCRE features. For more details please refer to the documentation on the [PCRE site](http://www.pcre.org/), or to the documentation which is bundled in the /pcre/doc/html/ directory of a MariaDB sources distribution. The pages pcresyntax.html and pcrepattern.html should be a good start. [Regular-Expressions.Info](http://www.regular-expressions.info/tutorial.html) is another good resource to learn about PCRE and regular expressions generally.

 ### Special Characters

 PCRE supports the following escape sequences to match special characters:

 


| Sequence | Description |
| --- | --- |
| \a | 0x07 (BEL) |
| \cx | "control-x", where x is any ASCII character |
| \e | 0x1B (escape) |
| \f | 0x0C (form feed) |
| \n | 0x0A (newline) |
| \r | 0x0D (carriage return) |
| \t | 0x09 (TAB) |
| \ddd | character with octal code ddd |
| \xhh | character with hex code hh |
| \x{hhh..} | character with hex code hhh.. |

 
Note, the backslash characters (here, and in all examples in the sections below) must be escaped with another backslash, unless you're using the [SQL\_MODE](../sql-mode/index) `NO_BACKSLASH_ESCAPES`.

 This example tests if a character has hex code 0x61:

 
```
SELECT 'a' RLIKE '\\x{61}';
-> 1

```

### Character Classes

 PCRE supports the standard POSIX character classes such as `alnum`, `alpha`, `blank`, `cntrl`, `digit`, `graph`, `lower`, `print`, `punct`, `space`, `upper`, `xdigit`, with the following additional classes:

 


| Class | Description |
| --- | --- |
| ascii | any ASCII character (0x00..0x7F) |
| word | any "word" character (a letter, a digit, or an underscore) |

 
This example checks if the string consists of ASCII characters only:

 
```
SELECT 'abc' RLIKE '^[[:ascii:]]+$';
-> 1

```

### Generic Character Types

 Generic character types complement the POSIX character classes and serve to simplify writing patterns:

 


| Class | Description |
| --- | --- |
| \d | a decimal digit (same as [:digit:]) |
| \D | a character that is not a decimal digit |
| \h | a horizontal white space character |
| \H | a character that is not a horizontal white space character |
| \N | a character that is not a new line |
| \R | a newline sequence |
| \s | a white space character |
| \S | a character that is not a white space character |
| \v | a vertical white space character |
| \V | a character that is not a vertical white space character |
| \w | a "word" character (same as [:word:]) |
| \W | a "non-word" character |

 
This example checks if the string consists of "word" characters only:

 
```
SELECT 'abc' RLIKE '^\\w+$';
-> 1

```

### Unicode Character Properties

 `\p{xx}` is a character with the `xx` property, and `\P{xx}` is a character without the `xx` property.

 The property names represented by `xx` above are limited to the Unicode script names, the general category properties, and "Any", which matches any character (including newline). Those that are not part of an identified script are lumped together as "Common".

 #### General Category Properties For \p and \P

 


| Property | Description |
| --- | --- |
| C | Other |
| Cc | Control |
| Cf | Format |
| Cn | Unassigned |
| Co | Private use |
| Cs | Surrogate |
| L | Letter |
| Ll | Lower case letter |
| Lm | Modifier letter |
| Lo | Other letter |
| Lt | Title case letter |
| Lu | Upper case letter |
| L& | Ll, Lu, or Lt |
| M | Mark |
| Mc | Spacing mark |
| Me | Enclosing mark |
| Mn | Non-spacing mark |
| N | Number |
| Nd | Decimal number |
| Nl | Letter number |
| No | Other number |
| P | Punctuation |
| Pc | Connector punctuation |
| Pd | Dash punctuation |
| Pe | Close punctuation |
| Pf | Final punctuation |
| Pi | Initial punctuation |
| Po | Other punctuation |
| Ps | Open punctuation |
| S | Symbol |
| Sc | Currency symbol |
| Sk | Modifier symbol |
| Sm | Mathematical symbol |
| So | Other symbol |
| Z | Separator |
| Zl | Line separator |
| Zp | Paragraph separator |
| Zs | Space separator |

 
This example checks if the string consists only of characters with property N (number):

 
```
SELECT '1¼①' RLIKE '^\\p{N}+$';
-> 1

```

#### Special Category Properties For \p and \P

 


| Property | Description |
| --- | --- |
| Xan | Alphanumeric: union of properties L and N |
| Xps | POSIX space: property Z or tab, NL, VT, FF, CR |
| Xsp | Perl space: property Z or tab, NL, FF, CR |
| Xuc | A character than can be represented by a Universal Character Name |
| Xwd | Perl word: property Xan or underscore |

 
The property `Xuc` matches any character that can be represented by a Universal Character Name (in C++ and other programming languages). These include `$`, `@`, ```, and all characters with Unicode code points greater than `U+00A0`, excluding the surrogates `U+D800`..`U+DFFF`.

 #### Script Names For \p and \P

 Arabic, Armenian, Avestan, Balinese, Bamum, Batak, Bengali, Bopomofo, Brahmi, Braille, Buginese, Buhid, Canadian\_Aboriginal, Carian, Chakma, Cham, Cherokee, Common, Coptic, Cuneiform, Cypriot, Cyrillic, Deseret, Devanagari, Egyptian\_Hieroglyphs, Ethiopic, Georgian, Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Imperial\_Aramaic, Inherited, Inscriptional\_Pahlavi, Inscriptional\_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah\_Li, Kharoshthi, Khmer, Lao, Latin, Lepcha, Limbu, Linear\_B, Lisu, Lycian, Lydian, Malayalam, Mandaic, Meetei\_Mayek, Meroitic\_Cursive, Meroitic\_Hieroglyphs, Miao, Mongolian, Myanmar, New\_Tai\_Lue, Nko, Ogham, Old\_Italic, Old\_Persian, Old\_South\_Arabian, Old\_Turkic, Ol\_Chiki, Oriya, Osmanya, Phags\_Pa, Phoenician, Rejang, Runic, Samaritan, Saurashtra, Sharada, Shavian, Sinhala, Sora\_Sompeng, Sundanese, Syloti\_Nagri, Syriac, Tagalog, Tagbanwa, Tai\_Le, Tai\_Tham, Tai\_Viet, Takri, Tamil, Telugu, Thaana, Thai, Tibetan, Tifinagh, Ugaritic, Vai, Yi.

 This example checks if the string consists only of Greek characters:

 
```
SELECT 'ΣΦΩ' RLIKE '^\\p{Greek}+$';
-> 1

```

### Extended Unicode Grapheme Sequence

 The `\X` escape sequence matches a character sequence that makes an "extended grapheme cluster", i.e. a composite character that consists of multiple Unicode code points.

 One of the examples of a composite character can be a letter followed by non-spacing accent marks. This example demonstrates that `U+0045 LATIN CAPITAL LETTER E` followed by `U+0302 COMBINING CIRCUMFLEX ACCENT` followed by `U+0323 COMBINING DOT BELOW` together form an extended grapheme cluster:

 
```
SELECT _ucs2 0x004503020323 RLIKE '^\\X$';
-> 1

```

See the [PCRE documentation](http://www.pcre.org) for the other types of extended grapheme clusters.

 ### Simple Assertions

 An assertion specifies a certain condition that must match at a particular point, but without consuming characters from the subject string. In addition to the standard POSIX simple assertions `^` (that matches at the beginning of a line) and `$` (that matches at the end of a line), PCRE supports a number of other assertions:

 


| Assertion | Description |
| --- | --- |
| \b | matches at a word boundary |
| \B | matches when not at a word boundary |
| \A | matches at the start of the subject |
| \Z | matches at the end of the subject, also matches before a newline at the end of the subject |
| \z | matches only at the end of the subject |
| \G | matches at the first matching position in the subject |

 
This example cuts a word that consists only of 3 characters from a string:

 
```
SELECT REGEXP_SUBSTR('---abcd---xyz---', '\\b\\w{3}\\b');
-> xyz

```

Notice that the two `\b` assertions checked the word boundaries but did not get into the matching pattern.

 The `\b` assertions work well in the beginning and the end of the subject string:

 
```
SELECT REGEXP_SUBSTR('xyz', '\\b\\w{3}\\b');
-> xyz

```

By default, the `^` and `$` assertions have the same meaning with `\A`, `\Z`, and `\z`. However, the meanings of `^` and `$` can change in multiline mode (see below). By contrast, the meanings of `\A`, `\Z`, and `\z` are always the same; they are independent of the multiline mode.

 ### Option Setting

 A number of options that control the default match behavior can be changed within the pattern by a sequence of option letters enclosed between `(?` and `)`.

 


| Option | Description |
| --- | --- |
| (?i) | case insensitive match |
| (?m) | multiline mode |
| (?s) | dotall mode (dot matches newline characters) |
| (?x) | extended (ignore white space) |
| (?U) | ungreedy (lazy) match |
| (?J) | allow named subpatterns with duplicate names |
| (?X) | extra PCRE functionality (e.g. force error on unknown escaped character) |
| (?-...) | unset option(s) |

 
For example, `(?im)` sets case insensitive multiline matching.

 A hyphen followed by the option letters unset the options. For example, `(?-im)` means case sensitive single line match.

 A combined setting and unsetting is also possible, e.g. `(?im-sx)`.

 If an option is set outside of subpattern parentheses, the option applies to the remainder of the pattern that follows the option. If an option is set inside a subpattern, it applies to the part of this subpattern that follows the option.

 In this example the pattern `(?i)m((?-i)aria)db` matches the words `MariaDB`, `Mariadb`, `mariadb`, but not `MARIADB`:

 
```
SELECT 'MariaDB' RLIKE '(?i)m((?-i)aria)db';
-> 1

SELECT 'mariaDB' RLIKE '(?i)m((?-i)aria)db';
-> 1

SELECT 'Mariadb' RLIKE '(?i)m((?-i)aria)db';
-> 1

SELECT 'MARIADB' RLIKE '(?i)m((?-i)aria)db';
-> 0

```

This example demonstrates that the `(?x)` option makes the regexp engine ignore all white spaces in the pattern (other than in a class).

 
```
SELECT 'ab' RLIKE '(?x)a b';
-> 1

```

Note, putting spaces into a pattern in combination with the (?x) option can be useful to split different logical parts of a complex pattern, to make it more readable.

 ### Multiline Matching

 Multiline matching changes the meaning of `^` and `$` from "the beginning of the subject string" and "the end of the subject string" to "the beginning of any line in the subject string" and "the end of any line in the subject string" respectively.

 This example checks if the subject string contains two consequent lines that fully consist of digits:

 
```
SELECT 'abc\n123\n456\nxyz\n' RLIKE '(?m)^\\d+\\R\\d+$';
-> 1

```

Notice the `(?m)` option in the beginning of the pattern, which switches to the multiline matching mode.

 ### Newline Conventions

 PCRE supports five line break conventions:

 * `CR (\r)` - a single carriage return character
* `LF (\n)` - a single linefeed character
* `CRLF (\r\n)` - a carriage return followed by a linefeed
* any of the previous three
* any Unicode newline sequence

 By default, the newline convention is set to any Unicode newline sequence, which includes:

 


| Sequence | Description |
| --- | --- |
| LF | (U+000A, carriage return) |
| CR | (U+000D, carriage return) |
| CRLF | (a carriage return followed by a linefeed) |
| VT | (U+000B, vertical tab) |
| FF | (U+000C, form feed) |
| NEL | (U+0085, next line) |
| LS | (U+2028, line separator) |
| PS | (U+2029, paragraph separator) |

 
The newline convention can be set by starting a pattern with one of the following sequences:

 


| Sequence | Description |
| --- | --- |
| (\*CR) | carriage return |
| (\*LF) | linefeed |
| (\*CRLF) | carriage return followed by linefeed |
| (\*ANYCRLF) | any of the previous three |
| (\*ANY) | all Unicode newline sequences |

 
The newline conversion affects the `^` and `$` assertions, the interpretation of the dot metacharacter, and the behavior of `\N`.

 Note, the new line convention does not affect the meaning of `\R`.

 This example demonstrates that the dot metacharacter matches `\n`, because it is not a newline sequence anymore:

 
```
SELECT 'a\nb' RLIKE '(*CR)a.b';
-> 1

```

### Newline Sequences

 By default, the escape sequence `\R` matches any Unicode newline sequences.

 The meaning of `\R` can be set by starting a pattern with one of the following sequences:

 


| Sequence | Description |
| --- | --- |
| (\*BSR\_ANYCRLF) | any of CR, LF or CRLF |
| (\*BSR\_UNICODE) | any Unicode newline sequence |

  It's possible to include comments inside a pattern. Comments do not participate in the pattern matching. Comments start at the `(?`# sequence and continue up to the next closing parenthesis:

 
```
SELECT 'ab12' RLIKE 'ab(?#expect digits)12';
-> 1

```

### Quoting

 POSIX uses the backslash to remove a special meaning from a character. PCRE introduces a syntax to remove special meaning from a sequence of characters. The characters inside `\Q` ... `\E` are treated literally, without their special meaning.

 This example checks if the string matches a dollar sign followed by a parenthesized name (a variable reference in some languages):

 
```
SELECT '$(abc)' RLIKE '^\\Q$(\\E\\w+\\Q)\\E$';
-> 1

```

Note that the leftmost dollar sign and the parentheses are used literally, while the rightmost dollar sign is still used to match the end of the string.

 ### Resetting the Match Start

 The escape sequence `\K` causes any previously matched characters to be excluded from the final matched sequence. For example, the pattern: `(foo)\Kbar` matches `foobar`, but reports that it has matched `bar`. This feature is similar to a look-behind assertion. However, in this case, the part of the subject before the real match does not have to be of fixed length:

 
```
SELECT REGEXP_SUBSTR('aaa123', '[a-z]*\\K[0-9]*');
-> 123

```

### Non-Capturing Groups

 The question mark and the colon after the opening parenthesis create a non-capturing group: `(?:...)`.

 This example removes an optional article from a word, for example for better sorting of the results.

 
```
SELECT REGEXP_REPLACE('The King','(?:the|an|a)[^a-z]([a-z]+)','\\1');
-> King

```

Note that the articles are listed inside the left parentheses using the alternation operator `|` but they do not produce a captured subpattern, so the word followed by the article is referenced by `'  
1'` in the third argument to the function. Using non-capturing groups can be useful to save numbers on the sup-patterns that won't be used in the third argument of [REGEXP\_REPLACE()](../regexp_replace/index), as well as for performance purposes.

 ### Non-Greedy Quantifiers

 By default, the repetition quantifiers `?`, `*`, `+` and `{n,m}` are "greedy", that is, they try to match as much as possible. Adding a question mark after a repetition quantifier makes it "non-greedy", so the pattern matches the minimum number of times possible.

 This example cuts C comments from a line:

 
```
SELECT REGEXP_REPLACE('/* Comment1 */ i+= 1; /* Comment2 */', '/[*].*?[*]/','');
->  i+= 1;

```

The pattern without the non-greedy flag to the quantifier `/[*].*[*]/` would match the entire string between the leftmost `/*` and the rightmost `*/`.

 ### Atomic Groups

 A sequence inside `(?>`...`)` makes an atomic group. Backtracking inside an atomic group is prevented once it has matched; however, backtracking past to the previous items works normally.

 Consider the pattern `\d+foo` applied to the subject string `123bar`. Once the engine scans `123` and fails on the letter `b`, it would normally backtrack to `2` and try to match again, then fail and backtrack to `1` and try to match and fail again, and finally fail the entire pattern. In case of an atomic group `(?>\d+)foo` with the same subject string `123bar`, the engine gives up immediately after the first failure to match `foo`. An atomic group with a quantifier can match all or nothing.

 Atomic groups produce faster false results (i.e. in case when a long subject string does not match the pattern), because the regexp engine saves performance on backtracking. However, don't hurry to put everything into atomic groups. This example demonstrates the difference between atomic and non-atomic match:

 
```
SELECT 'abcc' RLIKE 'a(?>bc|b)c' AS atomic1;
-> 1

SELECT 'abc' RLIKE 'a(?>bc|b)c' AS atomic2;
-> 0
 
SELECT 'abcc' RLIKE 'a(bc|b)c' AS non_atomic1;
-> 1

SELECT 'abc' RLIKE 'a(bc|b)c' AS non_atomic2;
-> 1

```

The non-atomic pattern matches both `abbc` and `abc`, while the atomic pattern matches `abbc` only.

 The atomic group `(?>bc|b)` in the above example can be "translated" as "if there is `bc`, then don't try to match as `b`". So `b` can match only if `bc` is not found.

 Atomic groups are not capturing. To make an atomic group capturing, put it into parentheses:

 
```
SELECT REGEXP_REPLACE('abcc','a((?>bc|b))c','\\1');
-> bc

```

### Possessive quantifiers

 An atomic group which ends with a quantifier can be rewritten using a so called "possessive quantifier" syntax by putting an additional `+` sign following the quantifier.

 The pattern `(?>\d+)foo` from the previous section's example can be rewritten as `\d++foo`.

 ### Absolute and Relative Numeric Backreferences

 Backreferences match the same text as previously matched by a capturing group. Backreferences can be written using:

 * a backslash followed by a digit
* the `\g` escape sequence followed by a positive or negative number
* the `\g` escape sequence followed by a positive or negative number enclosed in braces

 The following backreferences are identical and refer to the first capturing group:

 * `\1`
* `\g1`
* `\g{1}`

 This example demonstrates a pattern that matches "sense and sensibility" and "response and responsibility", but not "sense and responsibility":

 
```
SELECT 'sense and sensibility' RLIKE '(sens|respons)e and \\1ibility';
-> 1

```

This example removes doubled words that can unintentionally creep in when you edit a text in a text editor:

 
```
SELECT REGEXP_REPLACE('using using the the regexp regexp',
 '\\b(\\w+)\\s+\\1\\b','\\1');
-> using the regexp

```

Note that all double words were removed, in the beginning, in the middle and in the end of the subject string.

 A negative number in a `\g` sequence means a relative reference. Relative references can be helpful in long patterns, and also in patterns that are created by joining fragments together that contain references within themselves. The sequence `\g{-1}` is a reference to the most recently started capturing subpattern before `\g`.

 In this example `\g{-1}` is equivalent to `\2`:

 
```
SELECT 'abc123def123' RLIKE '(abc(123)def)\\g{-1}';     
-> 1

SELECT 'abc123def123' RLIKE '(abc(123)def)\\2';
-> 1

```

### Named Subpatterns and Backreferences

 Using numeric backreferences for capturing groups can be hard to track in a complicated regular expression. Also, the numbers can change if an expression is modified. To overcome these difficulties, PCRE supports named subpatterns.

 A subpattern can be named in one of three ways: `(?<name>`...`)` or `(?'name'`...`)` as in Perl, or `(?P<name>`...`)` as in Python. References to capturing subpatterns from other parts of the pattern, can be made by name as well as by number.

 Backreferences to a named subpattern can be written using the .NET syntax `\k{name}`, the Perl syntax `\k<name>` or `\k'name'` or `\g{name}`, or the Python syntax `(?P=name)`.

 This example tests if the string is a correct HTML tag:

 
```
SELECT '<a href="../">Up</a>' RLIKE '<(?<tag>[a-z][a-z0-9]*)[^>]*>[^<]*</(?P=tag)>';
-> 1 

```

### Positive and Negative Look-Ahead and Look-Behind Assertions

 Look-ahead and look-behind assertions serve to specify the context for the searched regular expression pattern. Note that the assertions only check the context, they do not capture anything themselves!

 This example finds the letter which is not followed by another letter (negative look-ahead):

 
```
SELECT REGEXP_SUBSTR('ab1','[a-z](?![a-z])');
-> b

```

This example finds the letter which is followed by a digit (positive look-ahead):

 
```
SELECT REGEXP_SUBSTR('ab1','[a-z](?=[0-9])');
-> b

```

This example finds the letter which does not follow a digit character (negative look-behind):

 
```
SELECT REGEXP_SUBSTR('1ab','(?<![0-9])[a-z]');
-> b

```

This example finds the letter which follows another letter character (positive look-behind):

 
```
SELECT REGEXP_SUBSTR('1ab','(?<=[a-z])[a-z]');
-> b

```

Note that look-behind assertions can only be of fixed length; you cannot have repetition operators or alternations with different lengths:

 
```
SELECT 'aaa' RLIKE '(?<=(a|bc))a';
ERROR 1139 (42000): Got error 'lookbehind assertion is not fixed length at offset 10' from regexp

```

### Subroutine Reference and Recursive Patterns

 PCRE supports a special syntax to recourse the entire pattern or its individual subpatterns:

 


| Syntax | Description |
| --- | --- |
| (?R) | Recourse the entire pattern |
| (?n) | call subpattern by absolute number |
| (?+n) | call subpattern by relative number |
| (?-n) | call subpattern by relative number |
| (?&name) | call subpattern by name (Perl) |
| (?P>name) | call subpattern by name (Python) |
| \g<name> | call subpattern by name (Oniguruma) |
| \g'name' | call subpattern by name (Oniguruma) |
| \g<n> | call subpattern by absolute number (Oniguruma) |
| \g'n' | call subpattern by absolute number (Oniguruma) |
| \g<+n> | call subpattern by relative number |
| \g<-n> | call subpattern by relative number |
| \g'+n' | call subpattern by relative number |
| \g'-n' | call subpattern by relative number |

 
This example checks for a correct additive arithmetic expression consisting of numbers, unary plus and minus, binary plus and minus, and parentheses:

 
```
SELECT '1+2-3+(+(4-1)+(-2)+(+1))' RLIKE  '^(([+-]?(\\d+|[(](?1)[)]))(([+-](?1))*))$';
-> 1

```

The recursion is done using `(?1)` to call for the first parenthesized subpattern, which includes everything except the leading `^` and the trailing `$`.

 The regular expression in the above example implements the following BNF grammar:

 1. `<expression> ::= <term> [(<sign> <term>)...]`
2. `<term> ::= [ <sign> ] <primary>`
3. `<primary> ::= <number> | <left paren> <expression> <right paren>`
4. `<sign> ::= <plus sign> | <minus sign>`

 ### Defining Subpatterns For Use By Reference

 Use the `(?(DEFINE)`...`)` syntax to define subpatterns that can be referenced from elsewhere.

 This example defines a subpattern with the name `letters` that matches one or more letters, which is further reused two times:

 
```
SELECT 'abc123xyz' RLIKE '^(?(DEFINE)(?<letters>[a-z]+))(?&letters)[0-9]+(?&letters)$';
-> 1

```

The above example can also be rewritten to define the digit part as a subpattern as well:

 
```
SELECT 'abc123xyz' RLIKE
 '^(?(DEFINE)(?<letters>[a-z]+)(?<digits>[0-9]+))(?&letters)(?&digits)(?&letters)$';
-> 1

```

### Conditional Subpatterns

 There are two forms of conditional subpatterns:

 
```
(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)

```

The `yes-pattern` is used if the condition is satisfied, otherwise the `no-pattern` (if any) is used.

 #### Conditions With Subpattern References

 If a condition consists of a number, it makes a condition with a subpattern reference. Such a condition is true if a capturing subpattern corresponding to the number has previously matched.

 This example finds an optionally parenthesized number in a string:

 
```
SELECT REGEXP_SUBSTR('a(123)b', '([(])?[0-9]+(?(1)[)])');
-> (123)

```

The `([(])?` part makes a capturing subpattern that matches an optional opening parenthesis; the `[0-9]+` part matches a number, and the `(?(1)[)])` part matches a closing parenthesis, but only if the opening parenthesis has been previously found.

 #### Other Kinds of Conditions

 The other possible condition kinds are: recursion references and assertions. See the [PCRE documentation](http://www.pcre.org) for details.

 ### Matching Zero Bytes (0x00)

 PCRE correctly works with zero bytes in the subject strings:

 
```
SELECT 'a\0b' RLIKE '^a.b$';
-> 1

```

Zero bytes, however, are not supported literally in the pattern strings and should be escaped using the `\xhh` or `\x{hh}` syntax:

 
```
SELECT 'a\0b' RLIKE '^a\\x{00}b$';
-> 1

```

### Other PCRE Features

 PCRE provides other extended features that were not covered in this document, such as duplicate subpattern numbers, backtracking control, breaking utf-8 sequences into individual bytes, setting the match limit, setting the recursion limit, optimization control, recursion conditions, assertion conditions and more types of extended grapheme clusters. Please refer to the [PCRE documentation](http://www.pcre.org) for details. 

 Enhanced regex was implemented as a GSoC 2013 project by Sudheera Palihakkara.

 ### default\_regex\_flags Examples

 The [default\_regex\_flags](../server-system-variables/index#default_regex_flags) variable was introduced to address the remaining incompatibilities between PCRE and the old regex library. Here are some examples of its usage:

 The default behaviour (multiline match is off)

 
```
SELECT 'a\nb\nc' RLIKE '^b$';
+---------------------------+
| '(?m)a\nb\nc' RLIKE '^b$' |
+---------------------------+
|                         0 |
+---------------------------+

```

Enabling the multiline option using the PCRE option syntax:

 
```
SELECT 'a\nb\nc' RLIKE '(?m)^b$';
+---------------------------+
| 'a\nb\nc' RLIKE '(?m)^b$' |
+---------------------------+
|                         1 |
+---------------------------+

```

Enabling the miltiline option using default\_regex\_flags

 
```
SET default_regex_flags='MULTILINE';
SELECT 'a\nb\nc' RLIKE '^b$';
+-----------------------+
| 'a\nb\nc' RLIKE '^b$' |
+-----------------------+
|                     1 |
+-----------------------+ 

```

### See Also

 * [MariaDB upgrades to PCRE-8.34](https://blog.mariadb.org/mariadb-upgrades-to-pcre-8-34/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pcre-regular-expressions/>

Data-at-Rest Encryption Overview
================================

    Overview
--------

 Having tables encrypted makes it almost impossible for someone to access or steal a hard disk and get access to the original data. MariaDB got Data-at-Rest Encryption with [MariaDB 10.1](../what-is-mariadb-101/index). This functionality is also known as "Transparent Data Encryption (TDE)".

 This assumes that encryption keys are stored on another system.

 Using encryption has an overhead of roughly *3-5%*.

 Which Storage Engines Does MariaDB Encryption Support?
------------------------------------------------------

 MariaDB encryption is fully supported for the [InnoDB](../innodb/index) storage engines. Encryption is also supported for the Aria storage engine, but only for tables created with `ROW_FORMAT=PAGE` (the default), and for the binary log (replication log).

 MariaDB allows the user to configure flexibly what to encrypt. In or InnoDB, one can choose to encrypt:

 * everything — all tablespaces (with all tables)
* individual tables
* everything, excluding individual tables

 Additionally, one can choose to encrypt InnoDB log files (recommended).

 Limitations
-----------

 These limitations exist in the data-at-rest encryption implementation:

 * Only **data** and only **at rest** is encrypted. Metadata (for example `.frm` files) and data sent to the client are not encrypted (but see [Secure Connections](../secure-connections/index)).
* Only the MariaDB server knows how to decrypt the data, in particular
	+ [mariadb-binlog](../mariadb-binlog/index) can read encrypted binary logs only when --read-from-remote-server is used ([MDEV-8813](https://jira.mariadb.org/browse/MDEV-8813)).
	+ [Percona XtraBackup](../percona-xtrabackup/index) cannot back up instances that use encrypted InnoDB. However, MariaDB's fork, [MariaDB Backup](../mariadb-backup/index), can back up encrypted instances.
* The disk-based [Galera gcache](https://galeracluster.com/library/documentation/state-transfer.html#write-set-cache-gcache) is not encrypted in the community version of MariaDB Server ([MDEV-9639](https://jira.mariadb.org/browse/MDEV-9639)). However, this file is encrypted in [MariaDB Enterprise Server 10.4](https://mariadb.com/docs/features/mariadb-enterprise-server/).
* The [Audit plugin](../mariadb-audit-plugin/index) cannot create encrypted output. Send it to syslog and configure the protection there instead.
* File-based [general query log](../general-query-log/index) and [slow query log](../slow-query-log/index) cannot be encrypted ([MDEV-9639](https://jira.mariadb.org/browse/MDEV-9639)).
* The Aria log is not encrypted ([MDEV-8587](https://jira.mariadb.org/browse/MDEV-8587)). This affects only non-temporary Aria tables though.
* The MariaDB [error log](../error-log/index) is not encrypted. The error log can contain query text and data in some cases, including crashes, assertion failures, and cases where InnoDB write monitor output to the log to aid in debugging. It can be sent to syslog too, if needed.

 Encryption Key Management
-------------------------

 MariaDB's data-at-rest encryption requires the use of a [key management and encryption plugin](../encryption-key-management/index). These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of [multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports [key rotation](../encryption-key-management/index#rotating-keys), then encryption keys can also be rotated, which creates a new version of the encryption key.

 How MariaDB manages encryption keys depends on which encryption key management solution you choose. Currently, MariaDB has three options:

 * [File Key Management Plugin](../file-key-management-encryption-plugin/index)
* [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index)
* [Eperi Key Management Plugin](../eperi-key-management-encryption-plugin/index)
* [Hashicorp Key Management Plugin](../hashicorp-key-management-plugin/index)

 Once you have an key management and encryption plugin set up and configured for your server, you can begin using encryption options to better secure your data.

 Encrypting Data
---------------

 Encryption occurs whenever MariaDB writes pages to disk. Encrypting table data requires that you install a [key management and encryption plugin](../encryption-key-management/index), such as the [File Key Management](../file-key-management-encryption-plugin/index) plugin. Once you have a plugin set up and configured, you can enable encryption for your InnoDB and Aria tables.

 ### Encrypting Table Data

 MariaDB supports data-at-rest encryption for InnoDB and Aria storage engines. Additionally, it supports encrypting the [InnoDB redo log](../xtradbinnodb-redo-log/index) and internal on-disk temporary tables that use the Aria storage engine..

 * [Encrypting Data for InnoDB](../encrypting-data-for-innodb-xtradb/index)
* [Encrypting Data for Aria](../encrypting-data-for-aria/index)

 ### Encrypting Temporary Files

 MariaDB also creates temporary files on disk. For example, a binary log cache will be written to a temporary file if the binary log cache exceeds `[binlog\_cache\_size](../replication-and-binary-log-system-variables/index#binlog_cache_size)` or `[binlog\_stmt\_cache\_size](../replication-and-binary-log-system-variables/index#binlog_stmt_cache_size)`, and temporary files are also often used for filesorts during query execution. Since [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), these temporary files can also be encrypted if [encrypt\_tmp\_files=ON](../server-system-variables/index#encrypt_tmp_files) is set.

 Since [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/), [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), temporary files created internally by InnoDB, such as those used for merge sorts and row logs can also be encrypted if [innodb\_encrypt\_log=ON](../xtradbinnodb-server-system-variables/index#innodb_encrypt_log) is set. These files are encrypted regardless of whether the tables involved are encrypted or not, and regardless of whether [encrypt\_tmp\_files](../server-system-variables/index#encrypt_tmp_files) is set or not.

 ### Encrypting Binary Logs

 MariaDB can also encrypt [binary logs](../binary-log/index) (including [relay logs](../relay-log/index)).

 * [Encrypting Binary Logs](../encrypting-binary-logs/index)

 Encryption and Page Compression
-------------------------------

 Data-at-rest encryption and [InnoDB page compression](../compression/index) can be used together. When they are used together, data is first compressed, and then it is encrypted. In this case you save space and still have your data protected.

 Thanks
------

 * Tablespace encryption was donated to the MariaDB project by Google.
* Per-table encryption and key identifier support was donated to the MariaDB project by [eperi](http://eperi.de/en).

 We are grateful to these companies for their support of MariaDB!

 See Also
--------

 * [Encryption functions](../encryption-functions/index)
* [DES\_DECRYPT()](../des_decrypt/index)
* [DES\_ENCRYPT()](../des_encrypt/index)
* A [blog post about table encryption](https://mariadb.com/blog/table-and-tablespace-encryption-mariadb-101/) with benchmark results

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-at-rest-encryption/>

NDB in MariaDB
==============

    NDB (MySQL Cluster) has been removed completely from [MariaDB 10.1](../what-is-mariadb-101/index). From [MariaDB 10.0](../what-is-mariadb-100/index) and below, it was disabled due to it not being in the main upstream MySQL releases. Upstream has NDB available as a separate download, because Cluster is updated more frequently compared to baseline MySQL.

 
For an actively developed alternative, see [Galera Cluster](../galera/index).

 
One of the prerequisites to having NDB working in MariaDB is for us to get an active maintainer of the NDB code.

 The [MariaDB community](../community/index) has not had much interest in this feature. If there is interest in this feature, please send email to the [maria-discuss](http://launchpad.net/~maria-discuss) mailing list, or file a request in [Jira](http://jira.mariadb.org).

 In 'theory' it should be easy for anyone to get ndb in MariaDB to work as well as in MySQL as all the ndb code is still in the tree. If you are interested in (and capable of) doing this, please join the MariaDB project!

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ndb-disabled-in-mariadb/>

SPATIAL INDEX
=============

    Description
-----------

 On [MyISAM](../myisam/index), [Aria](../aria/index) and [InnoDB](../innodb/index) tables, MariaDB can create spatial indexes (an R-tree index) using syntax similar to that for creating regular indexes, but extended with the `SPATIAL` keyword. Currently, columns in spatial indexes must be declared `NOT NULL`.

 Spatial indexes can be created when the table is created, or added after the fact like so:

 * with [CREATE TABLE](../create-table/index): 
```
CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));

```
* with [ALTER TABLE](../alter-table/index): 
```
ALTER TABLE geom ADD SPATIAL INDEX(g);

```
* with [CREATE INDEX](../create-index/index): 
```
CREATE SPATIAL INDEX sp_index ON geom (g);

```

 `SPATIAL INDEX` creates an `R-tree` index. For storage engines that support non-spatial indexing of spatial columns, the engine creates a `B-tree` index. A `B-tree` index on spatial values is useful for exact-value lookups, but not for range scans.

 For more information on indexing spatial columns, see [CREATE INDEX](../create-index/index).

 To drop spatial indexes, use [ALTER TABLE](../alter-table/index) or [DROP INDEX](../drop-index/index):

 * with [ALTER TABLE](../alter-table/index): 
```
ALTER TABLE geom DROP INDEX g;

```
* with [DROP INDEX](../drop-index/index): 
```
DROP INDEX sp_index ON geom;

```

 ### Data-at-Rest Encyption

 Before [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), InnoDB's spatial indexes could not be [encrypted](../encryption/index). If an InnoDB table was encrypted and if it contained spatial indexes, then those indexes would be unencrypted.

 In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, if `[innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm)` is set to `full_crc32` or `strict_full_crc32`, and if the table does not use `[ROW\_FORMAT=COMPRESSED](../xtradbinnodb-storage-formats/index)`, then InnoDB spatial indexes will be encrypted if the table is encrypted.

 See [MDEV-12026](https://jira.mariadb.org/browse/MDEV-12026) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spatial-index/>

Performance Schema host\_cache Table
====================================

    The `host_cache` table contains host and IP information from the host\_cache, used for avoiding DNS lookups for new client connections.

 The host\_cache table contains the following columns:

 


| Column | Description |
| --- | --- |
| `IP` | Client IP address. |
| `HOST` | IP's resolved DNS host name, or `NULL` if unknown. |
| `HOST_VALIDATED` | YES if the IP-to-host DNS lookup was successful, and the `HOST` column can be used to avoid DNS calls, or NO if unsuccessful, in which case DNS lookup is performed for each connect until either successful or a permanent error. |
| `SUM_CONNECT_ERRORS` | Number of connection errors. Counts only protocol handshake errors for hosts that passed validation. These errors count towards [max\_connect\_errors](../server-system-variables/index#max_connect_errors). |
| `COUNT_HOST_BLOCKED_ERRORS` | Number of blocked connections because `SUM_CONNECT_ERRORS` exceeded the [max\_connect\_errors](../server-system-variables/index#max_connect_errors) system variable. |
| `COUNT_NAMEINFO_TRANSIENT_ERRORS` | Number of transient errors during IP-to-host DNS lookups. |
| `COUNT_NAMEINFO_PERMANENT_ERRORS` | Number of permanent errors during IP-to-host DNS lookups. |
| `COUNT_FORMAT_ERRORS` | Number of host name format errors, for example a numeric host column. |
| `COUNT_ADDRINFO_TRANSIENT_ERRORS` | Number of transient errors during host-to-IP reverse DNS lookups. |
| `COUNT_ADDRINFO_PERMANENT_ERRORS` | Number of permanent errors during host-to-IP reverse DNS lookups. |
| `COUNT_FCRDNS_ERRORS` | Number of forward-confirmed reverse DNS errors, which occur when IP-to-host DNS lookup does not match the originating IP address. |
| `COUNT_HOST_ACL_ERRORS` | Number of errors occurring because no user from the host is permitted to log in. These attempts return [error code](../mariadb-error-codes/index) `1130 ER_HOST_NOT_PRIVILEGED` and do not proceed to username and password authentication. |
| `COUNT_NO_AUTH_PLUGIN_ERRORS` | Number of errors due to requesting an authentication plugin that was not available. This can be due to the plugin never having been loaded, or the load attempt failing. |
| `COUNT_AUTH_PLUGIN_ERRORS` | Number of errors reported by an authentication plugin. Plugins can increment `COUNT_AUTHENTICATION_ERRORS` or `COUNT_HANDSHAKE_ERRORS` instead, but, if specified or the error is unknown, this column is incremented. |
| `COUNT_HANDSHAKE_ERRORS` | Number of errors detected at the wire protocol level. |
| `COUNT_PROXY_USER_ERRORS` | Number of errors detected when a proxy user is proxied to a user that does not exist. |
| `COUNT_PROXY_USER_ACL_ERRORS` | Number of errors detected when a proxy user is proxied to a user that exists, but the proxy user doesn't have the PROXY privilege. |
| `COUNT_AUTHENTICATION_ERRORS` | Number of errors where authentication failed. |
| `COUNT_SSL_ERRORS` | Number of errors due to TLS problems. |
| `COUNT_MAX_USER_CONNECTIONS_ERRORS` | Number of errors due to the per-user quota being exceeded. |
| `COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS` | Number of errors due to the per-hour quota being exceeded. |
| `COUNT_DEFAULT_DATABASE_ERRORS` | Number of errors due to the user not having permission to access the specified default database, or it not existing. |
| `COUNT_INIT_CONNECT_ERRORS` | Number of errors due to statements in the [init\_connect](../server-system-variables/index#init_connect) system variable. |
| `COUNT_LOCAL_ERRORS` | Number of local server errors, such as out-of-memory errors, unrelated to network, authentication, or authorization. |
| `COUNT_UNKNOWN_ERRORS` | Number of unknown errors that cannot be allocated to another column. |
| `FIRST_SEEN` | Timestamp of the first connection attempt by the IP. |
| `LAST_SEEN` | Timestamp of the most recent connection attempt by the IP. |
| `FIRST_ERROR_SEEN` | Timestamp of the first error seen from the IP. |
| `LAST_ERROR_SEEN` | Timestamp of the most recent error seen from the IP. |

 
The `host_cache` table, along with the `host_cache`, is cleared with [FLUSH HOSTS](../flush/index), [TRUNCATE TABLE](../truncate-table/index) `host_cache` or by setting the [host\_cache\_size](../server-system-variables/index#host_cache_size) system variable at runtime.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-host_cache-table/>

Transaction Timeouts
====================

    MariaDB has always had the [wait\_timeout](../server-system-variables/index#wait_timeout) and [interactive\_timeout](../server-system-variables/index#interactive_timeout) settings, which close connections after a certain period of inactivity.

 However, these are by default set to a long wait period. In situations where transactions may be started, but not committed or rolled back, more granular control and a shorter timeout may be desirable so as to avoid locks being held for too long.

 [MariaDB 10.3](../what-is-mariadb-103/index) introduced three new variables to handle this situation.

 * [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout) (all transactions)
* [idle\_write\_transaction\_timeout](../server-system-variables/index#idle_write_transaction_timeout) (write transactions - called `idle_readwrite_transaction_timeout` until [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/))
* [idle\_readonly\_transaction\_timeout](../server-system-variables/index#idle_readonly_transaction_timeout) (read transactions)

 These accept a time in seconds to time out, by closing the connection, transactions that are idle for longer than this period. By default all are set to zero, or no timeout.

 [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout) affects all transactions, [idle\_write\_transaction\_timeout](../server-system-variables/index#idle_write_transaction_timeout) affects write transactions only and [idle\_readonly\_transaction\_timeout](../server-system-variables/index#idle_readonly_transaction_timeout) affects read transactions only. The latter two variables work independently. However, if either is set along with [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout), the settings for [idle\_write\_transaction\_timeout](../server-system-variables/index#idle_write_transaction_timeout) or [idle\_readonly\_transaction\_timeout](../server-system-variables/index#idle_readonly_transaction_timeout) will take precedence.

 Examples
--------

 
```
SET SESSION idle_transaction_timeout=2;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
## wait 3 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

```


```
SET SESSION idle_write_transaction_timeout=2;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
## wait 3 seconds
SELECT * FROM t;
Empty set (0.000 sec)
INSERT INTO t VALUES(1);
## wait 3 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

```


```
SET SESSION idle_transaction_timeout=2, SESSION idle_readonly_transaction_timeout=10;
BEGIN;
SELECT * FROM t;
Empty set (0.000 sec)
 ## wait 3 seconds
SELECT * FROM t;
Empty set (0.000 sec)
## wait 11 seconds
SELECT * FROM t;
ERROR 2006 (HY000): MySQL server has gone away

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transaction-timeouts/>

Block-Based Join Algorithms
===========================

    In the versions of MariaDB/MySQL before 5.3 only one block-based join algorithm was implemented: the Block Nested Loops (BNL) join algorithm which could only be used for inner joins.

 [MariaDB 5.3](../what-is-mariadb-53/index) enhanced the implementation of BNL joins and provides a variety of block-based join algorithms that can be used for inner joins, outer joins, and semi-joins. Block-based join algorithms in MariaDB employ a join buffer to accumulate records of the first join operand before they start looking for matches in the second join operand.

 This page documents the various block-based join algorithms.

 * Block Nested Loop (BNL) join
* Block Nested Loop Hash (BNLH) join
* Block Index join known as Batch Key Access (BKA) join
* Block Index Hash join known as Batch Key Access Hash (BKAH) join

 Block Nested Loop Join
----------------------

 The major difference between the implementation of BNL join in [MariaDB 5.3](../what-is-mariadb-53/index) compared to earlier versions of MariaDB/MySQL is that the former uses a new format for records written into join buffers. This new format allows:

 * More efficient use of buffer space for null field values and field values of flexible length types (like the varchar type)
* Support for so-called *incremental* join buffers saving buffer space for multi-way joins
* Use of the algorithm for outer joins and semi-joins

 ### How Block Nested Loop Join Works

 The algorithm performs a join operation of tables t1 and t2 according to the following schema.   
The records of the first operand are written into the join buffer one by one until the buffer is full.   
The records of the second operand are read from the base/temporary table one by one. For every read record r2 of table t2 the join buffer is scanned, and, for any record r1 from the buffer such that r2 matches r1 the concatenation of the interesting fields of r1 and r2 is sent to the result stream of the corresponding partial join.   
To read the records of t2 a full table scan, a full index scan or a range index scan is performed. Only the records that meet the condition pushed to table t2 are checked for a match of the records from the join buffer.   
When the scan of the table t2 is finished a new portion of the records of the first operand fills the buffer and matches for these records are looked for in t2.   
The buffer refills and scans of the second operand that look for matches in the join buffer are performed again and again until the records of first operand are exhausted.   
In total the algorithm scans the second operand as many times as many refills of the join buffer occur. 

 ### More Efficient Usage of Join Buffer Space

 No join buffer space is used for null field values.   
Any field value of a flexible length type is not padded by 0 up to the maximal field size anymore.

 ### Incremental Join Buffers

 If we have a query with a join of three tables t1, t2, t3 such that table t1 is joined with table t2 and the result of this join operation is joined with table t3 then two join buffers can be used to execute the query. The first join buffer B1 is used to store the records comprising interesting fields of table t1, while the second join buffer B2 contains the records with fields from the partial join of t1 and t2. The interesting fields of any record r1 from B1 are copied into B2 for any record record r1,r2 from the partial join of t1 and t2. One could suggest storing in B2 just a pointer to the position of the r1 fields in B1 together with the interesting fields from t2. So for any record r2 matching the record r1 the buffer B2 would contain a reference to the fields of r1 in B1 and the fields of r2. In this case the buffer B2 is called incremental. Incremental buffers allow to avoid copying field values from one buffer into another. They also allow to save a significant amount of buffer space if for a record from t1 several matches from t2 are expected. 

 ### Using Join Buffers for Simple Outer Joins and Semi-joins

 If a join buffer is used for a simple left outer join of tables t1 and t1 t1 LEFT JOIN t2 ON P(t1,t2) then each record r1 stored in the buffer is provided with a match flag. Initially this flag is set off. As soon as the first match for r1 is found this flag is set on. When all matching candidates from t2 have been check, the record the join buffer are scanned and for those of them that still have there match flags off null-complemented rows are generated. The same match flag is used for any record in the join buffer is a semi-join operation t1 SEMI JOIN t2 ON P(t1,t2) is performed with a block based join algorithm. When this match flag is set to on for a record r1 in the buffer no matches from table t2 for record r1 are looked for anymore.

 Block Hash Join
---------------

 Block based hash join algorithm is a new option to be used for join operations in [MariaDB 5.3](../what-is-mariadb-53/index). It can be employed in the cases when there are equi-join sub-condition for the joined tables, in the other words when equalities of the form t2.f1= e1(t1),...,t2.fn=en(t1) can be extracted from the full join condition. As any block based join algorithm this one used a join buffer filled with the records of the first operand and looks through the records of the second operand to find matches for the records in the buffer.

 ### How Block Hash Join Works

 For each refill of the join buffer and each record r1 from it the algorithm builds a hash table with the keys constructed over the values e1(r1),...en(r1). Then the records of t2 are looked through. For each record r2 from t2 that the condition pushed to the table t2 a hash key over the fields r2.f1,..., r2.fn is calculated to probe into the hash table. The probing returns those records from the buffer to which r2 matches. As for BNL join algorithm this algorithm scans the second operand as many time as many refills of the buffer occur. Yet it has to look only through the records of one bucket in the hash table when looking for the records to which a record from t2 matches, not through all records in the join buffer as BNL join algorithm does. The implementation of this algorithm in MariaDB builds the hash table with hash keys at the very end of the join buffer. That's why the number of records written into the buffer at one refill is less then for BNL join algorithms. However a much shorter list of possible matching candidates makes this the block hash join algorithm usually much faster then BNL join.

 Batch Key Access Join
---------------------

 Batch Keys Access join algorithm performs index look-ups when looking for possible matching candidates provided by the second join operand. With this respect the algorithm behave itself as the regular join algorithm. Yet BKA performs index look-ups for a batch of the records from the join buffer. For conventional database engines like InnoDB/MyISAM it allows to fetch matching candidates in an optimal way. For the engines with remote data store such as FederateX/Spider the algorithm allows to save on transfers between the MySQL node and the data store nodes.

 ### How Batch Keys Access Join Works

 The implementation of the algorithm in 5.3 heavily exploits the multi-range-read interface and its properties. The interface hides the actual mechanism of fetching possible candidates for matching records from the table to be joined. As any block based join algorithm the BKA join repeatedly fills the join buffer with records of the first operand and for each refill it finds records from the join table that could match the records in the buffer. To find such records it asks the MRR interface to perform index look-ups with the keys constructed over all records from the buffer. Together with each key the interface receives a return address - a reference to the record over which this key has been constructed. The actual implementation functions of the MRR interface organize and optimize somehow the process of fetching the records of the joined table by the received keys. Each fetched record r2 is appended with the return address associated with the key by which the record has been found and the result is passed to the BKA join procedure. The procedure takes the record r1 from the join buffer by the return address, joins it with r2 and checks the join condition. If the condition is evaluated to true the joined records is sent to the result stream of the join operation. So for each record returned by the MRR interface only one record from the join buffer is accessed. The number of records from table t2 fetched by the BKA join is exactly the same as for the regular nested loops join algorithm. Yet BKA join allows to optimize the order in which the records are fetched.

 ### Interaction of BKA Join With the MRR Functions

 BKA join interacts with the MRR functions respecting the following contract. The join procedure calls the MRR function multi\_range\_read\_init passing it the callback functions that allows to initialize reading keys for the records in the join buffer and to iterate over these keys. It also passes the parameters of the buffer for MRR needs allocated within the join buffer space. Then BKA join repeatedly calls the MRR function multi\_range\_read\_next. The function works as an iterator function over the records fetched by index look-ups with the keys produced by a callback function set in the call of multi\_range\_read\_init. A call of the function multi\_range\_read\_next returns the next fetched record through the dedicated record buffer, and the associated reference to the matched record from the join buffer as the output parameter of the function. 

 Managing Usage of Block-Based Join Algorithms
---------------------------------------------

 Currently 4 different types of block-based join algorithms are supported. For a particular join operation each of them can be employed with a regular (flat) join buffer or with an incremental join buffer.

 Three optimizer switches - `join_cache_incremental`, `join_cache_hashed`, `join_cache_bka` – and the system variable [join\_cache\_level](../server-system-variables/index#join_cache_level) control which of the 8 variants of the block-based algorithms will be used for join operations.

 If `join_cache_bka` is off then BKA and BKAH join algorithms are not allowed. If `join_cache_hashed` is off then BNLH and BKAH join algorithms are not allowed. If `join_cache_incremental` is off then no incremental variants of the block-based join algorithms are allowed.

 By default the switches `join_cache_incremental`, `join_cache_hashed`, `join_cache_bka` are set to 'on'. However it does not mean that by default any of block-based join algorithms is allowed to be used. All of them are allowed only if the system variable [join\_cache\_level](../server-system-variables/index#join_cache_level) is set to 8. This variable can take an integer value in the interval from 0 to 8.

 If the value is set to 0 no block-based algorithm can be used for a join operation. The values from 1 to 8 correspond to the following variants of block-based join algorithms :

 * 1 – Flat BNL
* 2 – Incremental BNL
* 3 – Flat BNLH
* 4 – Incremental BNLH
* 5 – Flat BKA
* 6 – Incremental BKA
* 7 – Flat BKAH
* 8 – Incremental BKAH

 If the value of [join\_cache\_level](../server-system-variables/index#join_cache_level) is set to N, any of block-based algorithms with the level greater than N is disallowed.

 So if [join\_cache\_level](../server-system-variables/index#join_cache_level) is set to 5, no usage of BKAH is allowed and usage of incremental BKA is not allowed either while usage of all remaining variants are controlled by the settings of the optimizer switches `join_cache_incremental`, `join_cache_hashed`, `join_cache_bka`.

 By default [join\_cache\_level](../server-system-variables/index#join_cache_level) is set to 2. In other words only usage of flat or incremental BNL is allowed.

 By default block-based algorithms can be used only for regular (inner) join operations. To allow them for outer join operations (left outer joins and right outer joins) the optimizer switch `outer_join_with_cache` has to be set to 'on'. Setting the optimizer switch `semijoin_with_cache` to 'on' allows using these algorithms for semi-join operations.

 Currently, only incremental variants of the block-based join algorithms can be used for nested outer joins and nested semi-joins.

 ### Size of Join Buffers

 The maximum size of join buffers used by block-based algorithms is controlled by setting the [join\_buffer\_size](../server-system-variables/index#join_buffer_size) system variable. This value must be large enough in order for the join buffer employed for a join operation to contain all relevant fields for at least one joined record.

 [MariaDB 5.3](../what-is-mariadb-53/index) introduced the system variable [join\_buffer\_space\_limit](../server-system-variables/index#join_buffer_space_limit) that limits the total memory used for join buffers in a query.

 To optimize the usage of the join buffers within the limit set by `join_buffer_space_limit`, one should use the [optimizer switch](../server-system-variables/index#optimizer_switch) `optimize_join_buffer_size=on`. When this flag is set to 'off' (default until [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)), the size of the used join buffer is taken directly from the [join\_buffer\_size](../server-system-variables/index#join_buffer_size) system variable. When this flag is set to 'on' (default from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)) then the size of the buffer depends on the estimated number of rows in the partial join whose records are to be stored in the buffer. 

 ### Related MRR Settings

 To use BKA/BKAH join algorithms for InnoDB/MyISAM, one must set the optimizer switch `mrr` to 'on'. When using these algorithms for InnoDB/MyISAM the overall performance of the join operations can be dramatically improved if the optimizer switch `mrr_sort_keys` is set 'on'.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/block-based-join-algorithms/>

Server Locale
=============

    The [lc\_time\_names](../server-system-variables/index#lc_time_names) server system variable sets the language used by the date and time functions [DAYNAME()](../dayname/index), [MONTHNAME()](../monthname/index) and [DATE\_FORMAT()](../date_format/index) and [lc\_messages](../server-system-variables/index#lc_messages) sets the language for error messages.

 The list of the locales supported by the current MariaDB installation can be obtained via the [LOCALES](../locales-plugin/index) plugin.

 MariaDB supports the following locale values:

 


| Locale | Language | Territory |
| --- | --- | --- |
| ar\_AE | Arabic | United Arab Emirates |
| ar\_BH | Arabic | Bahrain |
| ar\_DZ | Arabic | Algeria |
| ar\_EG | Arabic | Egypt |
| ar\_IN | Arabic | Iran |
| ar\_IQ | Arabic | Iraq |
| ar\_JO | Arabic | Jordan |
| ar\_KW | Arabic | Kuwait |
| ar\_LB | Arabic | Lebanon |
| ar\_LY | Arabic | Libya |
| ar\_MA | Arabic | Morocco |
| ar\_OM | Arabic | Oman |
| ar\_QA | Arabic | Qatar |
| ar\_SA | Arabic | Saudi Arabia |
| ar\_SD | Arabic | Sudan |
| ar\_SY | Arabic | Syria |
| ar\_TN | Arabic | Tunisia |
| ar\_YE | Arabic | Yemen |
| be\_BY | Belarusian | Belarus |
| bg\_BG | Bulgarian | Bulgaria |
| ca\_ES | Catalan | Catalan |
| cs\_CZ | Czech | Czech Republic |
| da\_DK | Danish | Denmark |
| de\_AT | German | Austria |
| de\_BE | German | Belgium |
| de\_CH | German | Switzerland |
| de\_DE | German | Germany |
| de\_LU | German | Luxembourg |
| el\_GR | Greek | Greece |
| en\_AU | English | Australia |
| en\_CA | English | Canada |
| en\_GB | English | United Kingdom |
| en\_IN | English | India |
| en\_NZ | English | New Zealand |
| en\_PH | English | Philippines |
| en\_US | English | United States |
| en\_ZA | English | South Africa |
| en\_ZW | English | Zimbabwe |
| es\_AR | Spanish | Argentina |
| es\_BO | Spanish | Bolivia |
| es\_CL | Spanish | Chile |
| es\_CO | Spanish | Columbia |
| es\_CR | Spanish | Costa Rica |
| es\_DO | Spanish | Dominican Republic |
| es\_EC | Spanish | Ecuador |
| es\_ES | Spanish | Spain |
| es\_GT | Spanish | Guatemala |
| es\_HN | Spanish | Honduras |
| es\_MX | Spanish | Mexico |
| es\_NI | Spanish | Nicaragua |
| es\_PA | Spanish | Panama |
| es\_PE | Spanish | Peru |
| es\_PR | Spanish | Puerto Rico |
| es\_PY | Spanish | Paraguay |
| es\_SV | Spanish | El Salvador |
| es\_US | Spanish | United States |
| es\_UY | Spanish | Uruguay |
| es\_VE | Spanish | Venezuela |
| et\_EE | Estonian | Estonia |
| eu\_ES | Basque | Basque |
| fi\_FI | Finnish | Finland |
| fo\_FO | Faroese | Faroe Islands |
| fr\_BE | French | Belgium |
| fr\_CA | French | Canada |
| fr\_CH | French | Switzerland |
| fr\_FR | French | France |
| fr\_LU | French | Luxembourg |
| gl\_ES | Galician | Galician |
| gu\_IN | Gujarati | India |
| he\_IL | Hebrew | Israel |
| hi\_IN | Hindi | India |
| hr\_HR | Croatian | Croatia |
| hu\_HU | Hungarian | Hungary |
| id\_ID | Indonesian | Indonesia |
| is\_IS | Icelandic | Iceland |
| it\_CH | Italian | Switzerland |
| it\_IT | Italian | Italy |
| ja\_JP | Japanese | Japan |
| ka\_GE | Georgian | Georgia (From [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/)) |
| ko\_KR | Korean | Republic of Korea |
| lt\_LT | Lithuanian | Lithuania |
| lv\_LV | Latvian | Latvia |
| mk\_MK | Macedonian | FYROM |
| mn\_MN | Mongolia | Mongolian |
| ms\_MY | Malay | Malaysia |
| nb\_NO | Norwegian(Bokmål) | Norway |
| nl\_BE | Dutch | Belgium |
| nl\_NL | Dutch | The Netherlands |
| no\_NO | Norwegian | Norway |
| pl\_PL | Polish | Poland |
| pt\_BR | Portugese | Brazil |
| pt\_PT | Portugese | Portugal |
| rm\_CH | Romansh | Switzerland |
| ro\_RO | Romanian | Romania |
| ru\_RU | Russian | Russia |
| ru\_UA | Russian | Ukraine |
| sk\_SK | Slovak | Slovakia |
| sl\_SI | Slovenian | Slovenia |
| sq\_AL | Albanian | Albania |
| sr\_YU | Serbian | Serbia |
| sv\_FI | Swedish | Finland |
| sv\_SE | Swedish | Sweden |
| sw\_KE | Swahili | Kenya (from [MariaDB 11.1.2](https://mariadb.com/kb/en/mariadb-11-1-2-release-notes/)) |
| ta\_IN | Tamil | India |
| te\_IN | Telugu | India |
| th\_TH | Thai | Thailand |
| tr\_TR | Turkish | Turkey |
| uk\_UA | Ukrainian | Ukraine |
| ur\_PK | Urdu | Pakistan |
| vi\_VN | Vietnamese | Viet Nam |
| zh\_CN | Chinese | China |
| zh\_HK | Chinese | Hong Kong |
| zh\_TW | Chinese | Taiwan Province of China |

 
Examples
--------

 Setting the [lc\_time\_names](../server-system-variables/index#lc_time_names) and [lc\_messages](../server-system-variables/index#lc_messages) variables to localize the units of date and time, and the server error messages.

 
```
SELECT DAYNAME('2013-04-01'), MONTHNAME('2013-04-01');
+-----------------------+-------------------------+
| DAYNAME('2013-04-01') | MONTHNAME('2013-04-01') |
+-----------------------+-------------------------+
| Monday                | April                   |
+-----------------------+-------------------------+

SET lc_time_names = 'fr_CA';

SELECT DAYNAME('2013-04-01'), MONTHNAME('2013-04-01');
+-----------------------+-------------------------+
| DAYNAME('2013-04-01') | MONTHNAME('2013-04-01') |
+-----------------------+-------------------------+
| lundi                 | avril                   |
+-----------------------+-------------------------+

SELECT blah;
ERROR 1054 (42S22): Unknown column 'blah' in 'field' list'

SET lc_messages = 'nl_NL';

SELECT blah;
ERROR 1054 (42S22): Onbekende kolom 'blah' in field list

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/server-locale/>

Metadata Locking
================

    MariaDB supports metadata locking. This means that when a transaction (including [XA transactions](../xa-transactions/index)) uses a table, it locks its metadata until the end of transaction. Non-transactional tables are also locked, as well as views and objects which are related to locked tables/views (stored functions, triggers, etc). When a connection tries to use a DDL statement (like an [ALTER TABLE](../alter-table/index)) which modifies a table that is locked, that connection is queued, and has to wait until it's unlocked. Using savepoints and performing a partial rollback does not release metadata locks.

 [LOCK TABLES ... WRITE](../transactions-lock/index) are also queued. Some wrong statements which produce an error may not need to wait for the lock to be freed.

 The metadata lock's timeout is determined by the value of the [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) server system variable (in seconds). However, note that its default value is 31536000 (1 year, MariaDB <= 10.2.3), or 86400 (1 day, MariaDB >= 10.2.4). If this timeout is exceeded, the following error is returned:

 
```
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

```

If the [metadata\_lock\_info](../metadata-lock-info/index) plugin is installed, the [Information Schema](../information-schema/index) [metadata\_lock\_info](../information-schema-metadata_lock_info-table/index) table stores information about existing metadata locks.

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5](../what-is-mariadb-105/index), the [Performance Schema metadata\_locks](../performance-schema-metadata_locks-table/index) table contains metadata lock information.

 
Example
-------

 Let's use the following MEMORY (non-transactional) table:

 
```
CREATE TABLE t (a INT) ENGINE = MEMORY;

```

Connection 1 starts a transaction, and INSERTs a row into t:

 
```
START TRANSACTION;

INSERT INTO t SET a=1;

```

`t`'s metadata is now locked by connection 1. Connection 2 tries to alter `t`, but has to wait:

 
```
ALTER TABLE t ADD COLUMN b INT;

```

Connection 2's prompt is blocked now.

 Now connection 1 ends the transaction:

 
```
COMMIT;

```

...and connection 2 finally gets the output of its command:

 
```
Query OK, 1 row affected (35.23 sec)
Records: 1  Duplicates: 0  Warnings: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/metadata-locking/>

Conversion of Big IN Predicates Into Subqueries
===============================================

    Starting from [MariaDB 10.3](../what-is-mariadb-103/index), the optimizer converts certain big IN predicates into IN subqueries.

 That is, an IN predicate in the form

 
```
column [NOT] IN (const1, const2, .... )

```

is converted into an equivalent IN-subquery:

 
```
column [NOT] IN (select ... from temporary_table)

```

which opens new opportunities for the query optimizer.

 The conversion happens if the following conditions are met:

 * the IN list has more than 1000 elements (One can control it through the [in\_predicate\_conversion\_threshold](../server-system-variables/index#in_predicate_conversion_threshold) parameter).
* the [NOT] IN condition is at the top level of the WHERE/ON clause.

 Controlling the Optimization
----------------------------

 * The optimization is on by default. [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/) (and debug builds prior to that) introduced the [in\_predicate\_conversion\_threshold](../server-system-variables/index#in_predicate_conversion_threshold) variable. Set to `0` to disable the optimization.

 Benefits of the Optimization
----------------------------

 If `column` is a key-prefix, MariaDB optimizer will process the condition

 
```
column [NOT] IN (const1, const2, .... )

```

by trying to construct a range access. If the list is large, the analysis may take a lot of memory and CPU time. The problem gets worse when `column` is a part of a multi-column index and the query has conditions on other parts of the index.

 Conversion of IN predicates into a subqueries bypass the range analysis, which means the query optimization phase will use less CPU and memory.

 Possible disadvantages of the conversion are are:

 * The optimization may convert 'IN LIST elements' key accesses to a table scan (if there is no other usable index for the table)
* The estimates for the number of rows matching the `IN (...)` are less precise.

 See Also
--------

 * [IN operator](../in/index)

 Links
-----

 <https://jira.mariadb.org/browse/MDEV-12176>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/conversion-of-big-in-predicates-into-subqueries/>

Information Schema PLUGINS Table
================================

    The [Information Schema](../information_schema/index) `PLUGINS` table contains information about [server plugins](../mariadb-plugins/index).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `PLUGIN_NAME` | Name of the plugin. |
| `PLUGIN_VERSION` | Version from the plugin's general type descriptor. |
| `PLUGIN_STATUS` | Plugin status, one of `ACTIVE`, `INACTIVE`, `DISABLED` or `DELETED`. |
| `PLUGIN_TYPE` | Plugin type; `STORAGE ENGINE`, `INFORMATION_SCHEMA`, `AUTHENTICATION`, `REPLICATION`, `DAEMON` or `AUDIT`. |
| `PLUGIN_TYPE_VERSION` | Version from the plugin's type-specific descriptor. |
| `PLUGIN_LIBRARY` | Plugin's shared object file name, located in the directory specified by the [plugin\_dir](../server-system-variables/index#plugin_dir) system variable, and used by the [INSTALL PLUGIN](../install-plugin/index) and [UNINSTALL PLUGIN](../uninstall-plugin/index) statements. `NULL` if the plugin is complied in and cannot be uninstalled. |
| `PLUGIN_LIBRARY_VERSION` | Version from the plugin's API interface. |
| `PLUGIN_AUTHOR` | Author of the plugin. |
| `PLUGIN_DESCRIPTION` | Description. |
| `PLUGIN_LICENSE` | Plugin's licence. |
| `LOAD_OPTION` | How the plugin was loaded; one of `OFF`, `ON`, `FORCE` or `FORCE_PLUS_PERMANENT`. See [Installing Plugins](../plugin-overview/index#installing-plugins). |
| `PLUGIN_MATURITY` | Plugin's maturity level; one of `Unknown`, `Experimental`, `Alpha`, `Beta`,`'Gamma`, and `Stable`. |
| `PLUGIN_AUTH_VERSION` | Plugin's version as determined by the plugin author. An example would be '0.99 beta 1'. |

 
It provides a superset of the information shown by the [SHOW PLUGINS](../show-plugins/index) statement. For specific information about storage engines (a particular type of plugins), see the [information\_schema.ENGINES](../information-schema-engines-table/index) table and the [SHOW ENGINES](../show-engines/index) statement.

 This table provides a subset of the Information Schema [information\_schema.ALL\_PLUGINS](../information-schema-all_plugins-table/index) table, which contains all available plugins, installed or not.

 The table is not a standard Information Schema table, and is a MariaDB extension.

 #### Examples

 The easiest way to get basic information on plugins is with [SHOW PLUGINS](../show-plugins/index):

 
```
SHOW PLUGINS;

+----------------------------+----------+--------------------+-------------+---------+
| Name                       | Status   | Type               | Library     | License |
+----------------------------+----------+--------------------+-------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL        | GPL     |
| mysql_old_password         | ACTIVE   | AUTHENTICATION     | NULL        | GPL     |
| MRG_MyISAM                 | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| FEDERATED                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| Aria                       | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_INSERTED         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL        | GPL     |
| SPHINX                     | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| FEEDBACK                   | DISABLED | INFORMATION SCHEMA | NULL        | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL        | GPL     |
| pam                        | ACTIVE   | AUTHENTICATION     | auth_pam.so | GPL     |
+----------------------------+----------+--------------------+-------------+---------+

```


```
SELECT LOAD_OPTION 
FROM INFORMATION_SCHEMA.PLUGINS 
WHERE PLUGIN_NAME LIKE 'tokudb';
Empty set

```

The equivalent [SELECT](../select/index) query would be:

 
```
SELECT PLUGIN_NAME, PLUGIN_STATUS, 
PLUGIN_TYPE, PLUGIN_LIBRARY, PLUGIN_LICENSE
FROM INFORMATION_SCHEMA.PLUGINS;

```

Other [SELECT](../select/index) queries can be used to see additional information. For example:

 
```
SELECT PLUGIN_NAME, PLUGIN_DESCRIPTION, 
PLUGIN_MATURITY, PLUGIN_AUTH_VERSION
FROM INFORMATION_SCHEMA.PLUGINS
WHERE PLUGIN_TYPE='STORAGE ENGINE'
ORDER BY PLUGIN_MATURITY \G

*************************** 1. row ***************************
        PLUGIN_NAME: FEDERATED
 PLUGIN_DESCRIPTION: FederatedX pluggable storage engine
    PLUGIN_MATURITY: Beta
PLUGIN_AUTH_VERSION: 2.1
*************************** 2. row ***************************
        PLUGIN_NAME: Aria
 PLUGIN_DESCRIPTION: Crash-safe tables with MyISAM heritage
    PLUGIN_MATURITY: Gamma
PLUGIN_AUTH_VERSION: 1.5
*************************** 3. row ***************************
        PLUGIN_NAME: PERFORMANCE_SCHEMA
 PLUGIN_DESCRIPTION: Performance Schema
    PLUGIN_MATURITY: Gamma
PLUGIN_AUTH_VERSION: 0.1
*************************** 4. row ***************************
        PLUGIN_NAME: binlog
 PLUGIN_DESCRIPTION: This is a pseudo storage engine to represent the binlog in a transaction
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 5. row ***************************
        PLUGIN_NAME: MEMORY
 PLUGIN_DESCRIPTION: Hash based, stored in memory, useful for temporary tables
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 6. row ***************************
        PLUGIN_NAME: MyISAM
 PLUGIN_DESCRIPTION: MyISAM storage engine
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 7. row ***************************
        PLUGIN_NAME: MRG_MyISAM
 PLUGIN_DESCRIPTION: Collection of identical MyISAM tables
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 8. row ***************************
        PLUGIN_NAME: CSV
 PLUGIN_DESCRIPTION: CSV storage engine
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 9. row ***************************
        PLUGIN_NAME: InnoDB
 PLUGIN_DESCRIPTION: Supports transactions, row-level locking, and foreign keys
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.2.5
*************************** 10. row ***************************
        PLUGIN_NAME: BLACKHOLE
 PLUGIN_DESCRIPTION: /dev/null storage engine (anything you write to it disappears)
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 11. row ***************************
        PLUGIN_NAME: ARCHIVE
 PLUGIN_DESCRIPTION: Archive storage engine
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0
*************************** 12. row ***************************
        PLUGIN_NAME: partition
 PLUGIN_DESCRIPTION: Partition Storage Engine Helper
    PLUGIN_MATURITY: Stable
PLUGIN_AUTH_VERSION: 1.0

```

Check if a given plugin is available:

 
```
SELECT LOAD_OPTION 
FROM INFORMATION_SCHEMA.PLUGINS 
WHERE PLUGIN_NAME LIKE 'tokudb';
Empty set

```

Show authentication plugins:

 
```
SELECT PLUGIN_NAME, LOAD_OPTION 
FROM INFORMATION_SCHEMA.PLUGINS 
WHERE PLUGIN_TYPE LIKE 'authentication' \G

*************************** 1. row ***************************
PLUGIN_NAME: mysql_native_password
LOAD_OPTION: FORCE
*************************** 2. row ***************************
PLUGIN_NAME: mysql_old_password
LOAD_OPTION: FORCE

```

See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [Plugin Overview](../plugin-overview/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-plugins-table/>

Aria Encryption Overview
========================

    MariaDB can encrypt data in tables that use the [Aria storage engine](../aria/index). This includes both user-created tables and internal on-disk temporary tables that use the Aria storage engine. This ensures that your Aria data is only accessible through MariaDB.

 For encryption with the InnoDB and XtraDB storage engines, see [Encrypting Data for InnoDB/XtraDB](../encrypting-data-for-innodb-xtradb/index).

 Basic Configuration
-------------------

 In order to enable encryption for tables using the [Aria storage engine](../aria/index), there are a couple server system variables that you need to set and configure. Most users will want to set `[aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables)` and `[encrypt\_tmp\_disk\_tables](../server-system-variables/index#encrypt_tmp_disk_tables)`.

 Users of data-at-rest encryption will also need to have a [key management and encryption plugin](../encryption-key-management/index) configured. Some examples are [File Key Management Plugin](../file-key-management-encryption-plugin/index) and [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index).

 
```
[mariadb]
...

# File Key Management
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/encryption/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
file_key_management_encryption_algorithm = AES_CTR

# Aria Encryption
aria_encrypt_tables=ON
encrypt_tmp_disk_tables=ON

```

Determining Whether a Table is Encrypted
----------------------------------------

 The [InnoDB storage engine](../xtradb-and-innodb/index) has the [information\_schema.INNODB\_TABLESPACES\_ENCRYPTION table](../information-schema-innodb_tablespaces_encryption-table/index) that can be used to get information about which tables are encrypted. Aria does not currently have anything like that (see [MDEV-17324](https://jira.mariadb.org/browse/MDEV-17324) about that).

 To determine whether an Aria table is encrypted, you currently have to search the data file for some plain text that you know is in the data.

 For example, let's say that we have the following table:

 
```
SELECT * FROM db1.aria_tab LIMIT 1;
+----+------+
| id | str  |
+----+------+
|  1 | str1 |
+----+------+
1 row in set (0.00 sec


```

Then, we could search the data file that belongs to `db1.aria_tab` for `str1` using a command-line tool, such as [strings](https://linux.die.net/man/1/strings):

 
```
$ sudo strings /var/lib/mysql/db1/aria_tab.MAD | grep "str1"
str1

```

If you can find the plain text of the string, then you know that the table is not encrypted.

 Encryption and the Aria Log
---------------------------

 Only Aria tables are currently encrypted. The [Aria log](../aria-faq/index#differences-between-aria-and-myisam) is not yet encrypted. See [MDEV-8587](https://jira.mariadb.org/browse/MDEV-8587) about that.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encrypting-data-for-aria/>

mysql.general\_log Table
========================

    The `mysql.general_log` table stores the contents of the [General Query Log](../general-query-log/index) if general logging is active and the output is being written to table (see [Writing logs into tables](../writing-logs-into-tables/index)).

 It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `event_time` | `timestamp(6)` | NO |  | `CURRENT_TIMESTAMP(6)` | Time the query was executed. |
| `user_host` | `mediumtext` | NO |  | `NULL` | User and host combination. |
| `thread_id` | `int(11)` | NO |  | `NULL` | Thread id. |
| `server_id` | `int(10) unsigned` | NO |  | `NULL` | Server id. |
| `command_type` | `varchar(64)` | NO |  | `NULL` | Type of command. |
| `argument` | `mediumtext` | NO |  | `NULL` | Full query. |

 
Example
-------

 
```
SELECT * FROM mysql.general_log\G
*************************** 1. row ***************************
  event_time: 2014-11-11 08:40:04.117177
   user_host: root[root] @ localhost []
   thread_id: 74
   server_id: 1
command_type: Query
    argument: SELECT * FROM test.s
*************************** 2. row ***************************
  event_time: 2014-11-11 08:40:10.501131
   user_host: root[root] @ localhost []
   thread_id: 74
   server_id: 1
command_type: Query
    argument: SELECT * FROM mysql.general_log
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlgeneral_log-table/>

WAIT and NOWAIT
===============

    Extended syntax so that it is possible to set [innodb\_lock\_wait\_timeout](../innodb-system-variables/index#innodb_lock_wait_timeout) and [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) for the following statements:

 Syntax
------

 
```
ALTER TABLE tbl_name [WAIT n|NOWAIT] ...
CREATE ... INDEX ON tbl_name (index_col_name, ...) [WAIT n|NOWAIT] ...
DROP INDEX ... [WAIT n|NOWAIT]
DROP TABLE tbl_name [WAIT n|NOWAIT] ...
LOCK TABLE ... [WAIT n|NOWAIT]
OPTIMIZE TABLE tbl_name [WAIT n|NOWAIT]
RENAME TABLE tbl_name [WAIT n|NOWAIT] ...
SELECT ... FOR UPDATE [WAIT n|NOWAIT]
SELECT ... LOCK IN SHARE MODE [WAIT n|NOWAIT]
TRUNCATE TABLE tbl_name [WAIT n|NOWAIT]

```

Description
-----------

 The lock wait timeout can be explicitly set in the statement by using either `WAIT n` (to set the wait in seconds) or `NOWAIT`, in which case the statement will immediately fail if the lock cannot be obtained. `WAIT 0` is equivalent to `NOWAIT`.

 See Also
--------

 * [Query Limits and Timeouts](../query-limits-and-timeouts/index)
* [ALTER TABLE](../alter-table/index)
* [CREATE INDEX](../create-index/index)
* [DROP INDEX](../drop-index/index)
* [DROP TABLE](../drop-table/index)
* [LOCK TABLES and UNLOCK TABLES](../lock-tables-and-unlock-tables/index)
* [OPTIMIZE TABLE](../optimize-table/index)
* [RENAME TABLE](../rename-table/index)
* [SELECT](../select/index)
* [TRUNCATE TABLE](../truncate-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wait-and-nowait/>

mysql.slow\_log Table
=====================

    The `mysql.slow_log` table stores the contents of the [Slow Query Log](../slow-query-log/index) if slow logging is active and the output is being written to table (see [Writing logs into tables](../writing-logs-into-tables/index)).

 It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `start_time` | `timestamp(6)` | NO |  | `CURRENT_TIMESTAMP(6)` | Time the query began. |
| `user_host` | `mediumtext` | NO |  | `NULL` | User and host combination. |
| `query_time` | `time(6)` | NO |  | `NULL` | Total time the query took to execute. |
| `lock_time` | `time(6)` | NO |  | `NULL` | Total time the query was locked. |
| `rows_sent` | `int(11)` | NO |  | `NULL` | Number of rows sent. |
| `rows_examined` | `int(11)` | NO |  | `NULL` | Number of rows examined. |
| `db` | `varchar(512)` | NO |  | `NULL` | Default database. |
| `last_insert_id` | `int(11)` | NO |  | `NULL` | [last\_insert\_id](../last_insert_id/index). |
| `insert_id` | `int(11)` | NO |  | `NULL` | Insert id. |
| `server_id` | `int(10) unsigned` | NO |  | `NULL` | The server's id. |
| `sql_text` | `mediumtext` | NO |  | `NULL` | Full query. |
| `thread_id` | `bigint(21) unsigned` | NO |  | `NULL` | Thread id. |
| `rows_affected` | `int(11)` | NO |  | `NULL` | Number of rows affected by an [UPDATE](../update/index) or [DELETE](../delete/index) (from [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)) |

 
Example
-------

 
```
SELECT * FROM mysql.slow_log\G
...
*************************** 2. row ***************************
    start_time: 2014-11-11 07:56:28.721519
     user_host: root[root] @ localhost []
    query_time: 00:00:12.000215
     lock_time: 00:00:00.000000
     rows_sent: 1
 rows_examined: 0
            db: test
last_insert_id: 0
     insert_id: 0
     server_id: 1
      sql_text: SELECT SLEEP(12)
     thread_id: 74
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlslow_log-table/>

ALTER
======

   This category is for documentation on the various ALTER statements.

  

| Title | Description |
| --- | --- |
|  [ALTER TABLE](../alter-table/index) |  Modify a table's definition.  |
|  [ALTER DATABASE](../alter-database/index) |  Change the overall characteristics of a database.  |
|  [ALTER EVENT](../alter-event/index) |  Change an existing event.  |
|  [ALTER FUNCTION](../alter-function/index) |  Change the characteristics of a stored function.  |
|  [ALTER LOGFILE GROUP](../alter-logfile-group/index) |  Only useful with MySQL Cluster, and has no effect in MariaDB.  |
|  [ALTER PROCEDURE](../alter-procedure/index) |  Change stored procedure characteristics.  |
|  [ALTER SEQUENCE](../alter-sequence/index) |  Change options for a SEQUENCE.  |
|  [ALTER SERVER](../alter-server/index) |  Updates mysql.servers table.  |
|  [ALTER TABLESPACE](../alter-tablespace/index) |  ALTER TABLESPACE is not available in MariaDB.  |
|  [ALTER USER](../alter-user/index) |  Modify an existing MariaDB account.  |
|  [ALTER VIEW](../alter-view/index) |  Change a view definition.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter/>

Slow Query Log Overview
=======================

    The slow query log is a record of SQL queries that took a long time to perform.

 Note that, if your queries contain user's passwords, the slow query log may contain passwords too. Thus, it should be protected.

 The number of rows affected by the slow query are also recorded in the slow query log.

 Enabling the Slow Query Log
---------------------------

 The slow query log is disabled by default. 

 To enable the slow query log, set the [slow\_query\_log](../server-system-variables/index#slow_query_log) system variable to `1`. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL slow_query_log=1;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
slow_query_log

```

Configuring the Slow Query Log Filename
---------------------------------------

 By default, the slow query log is written to `${hostname}-slow.log` in the [datadir](../server-system-variables/index#datadir) directory. However, this can be changed.

 One way to configure the slow query log filename is to set the [slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL slow_query_log_file='mariadb-slow.log';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
slow_query_log
slow_query_log_file=mariadb-slow.log

```

If it is a relative path, then the [slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file) is relative to the [datadir](../server-system-variables/index#datadir) directory.

 However, the [slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file) system variable can also be an absolute path. For example:

 
```
[mariadb]
...
slow_query_log
slow_query_log_file=/var/log/mysql/mariadb-slow.log

```

Another way to configure the slow query log filename is to set the [log-basename](../mysqld-options/index#-log-basename) option, which configures MariaDB to use a common prefix for all log files (e.g. slow query log, [general query log](../general-query-log/index), [error log](../error-log/index), [binary logs](../binary-log/index), etc.). The slow query log filename will be built by adding `-slow.log` to this prefix. This option cannot be set dynamically. It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log-basename=mariadb
slow_query_log

```

The [log-basename](../mysqld-options/index#-log-basename) cannot be an absolute path. The log file name is relative to the [datadir](../server-system-variables/index#datadir) directory.

 Choosing the Slow Query Log Output Destination
----------------------------------------------

 The slow query log can either be written to a file on disk, or it can be written to the [slow\_log](../mysqlslow_log-table/index) table in the [mysql](../the-mysql-database-tables/index) database. To choose the slow query log output destination, set the [log\_output](../server-system-variables/index#log_output) system variable.

 ### Writing the Slow Query Log to a File

 The slow query log is output to a file by default. However, it can be explicitly chosen by setting the [log\_output](../server-system-variables/index#log_output) system variable to `FILE`. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_output='FILE';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log

```

### Writing the Slow Query Log to a Table

 The slow query log can either be written to the [slow\_log](../mysqlslow_log-table/index) table in the [mysql](../the-mysql-database-tables/index) database by setting the [log\_output](../server-system-variables/index#log_output) system variable to `TABLE`. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_output='TABLE';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=TABLE
slow_query_log

```

Some rows in this table might look like this:

 
```
SELECT * FROM mysql.slow_log\G
...
*************************** 2. row ***************************
    start_time: 2014-11-11 07:56:28.721519
     user_host: root[root] @ localhost []
    query_time: 00:00:12.000215
     lock_time: 00:00:00.000000
     rows_sent: 1
 rows_examined: 0
            db: test
last_insert_id: 0
     insert_id: 0
     server_id: 1
      sql_text: SELECT SLEEP(12)
     thread_id: 74
...

```

See [Writing logs into tables](../writing-logs-into-tables/index) for more information.

 Disabling the Slow Query Log for a Session
------------------------------------------

 A user can disable logging to the slow query log for a connection by setting the [slow\_query\_log](../server-system-variables/index#slow_query_log) system variable to `0`. For example:

 
```
SET SESSION slow_query_log=0;

```

Disabling the Slow Query Log for Specific Statements
----------------------------------------------------

 In [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) and later, it is possible to disable logging to the slow query log for specific types of statements by setting the [log\_slow\_disabled\_statements](../server-system-variables/index#log_slow_disabled_statements) system variable. This option cannot be set dynamically. It can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
general_log
general_log_file=queries.log
log_slow_disabled_statements='admin,call,slave,sp'

```

Configuring the Slow Query Log Time
-----------------------------------

 The time that defines a slow query can be configured by setting the [long\_query\_time](../server-system-variables/index#long_query_time) system variable. It uses a units of seconds, with an optional milliseconds component. The default value is `10`. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL long_query_time=5.0;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0

```

Logging Queries That Don't Use Indexes
--------------------------------------

 It can be beneficial to log queries that don't use indexes to the slow query log, since queries that don't use indexes can usually be optimized either by adding an index or by doing a slight rewrite. The slow query log can be configured to log queries that don't use indexes regardless of their execution time by setting the [log\_queries\_not\_using\_indexes](../server-system-variables/index#log_queries_not_using_indexes) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_queries_not_using_indexes=ON;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
log_queries_not_using_indexes=ON

```

As a significant number of queries can run quickly even without indexes, you can use the [min\_examined\_row\_limit](../server-system-variables/index#min_examined_row_limit) system variable with [log\_queries\_not\_using\_indexes](../server-system-variables/index#log_queries_not_using_indexes) to limit the logged queries to those having a material impact on the server.

 Logging Queries That Examine a Minimum Row Limit
------------------------------------------------

 It can be beneficial to log queries that examine a minimum number of rows. The slow query log can be configured to log queries that examine a minimum number of rows regardless of their execution time by setting the [min\_examined\_row\_limit](../server-system-variables/index#min_examined_row_limit) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL min_examined_row_limit=100000;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
min_examined_row_limit=100000

```

Logging Slow Administrative Statements
--------------------------------------

 By default, the Slow Query Log only logs slow non-administrative statements. To log administrative statements, set the [log\_slow\_admin\_statements](../server-system-variables/index#log_slow_admin_statements) system variable. The Slow Query Log considers the following statements administrative: [ALTER TABLE](../alter-table/index), [ANALYZE TABLE](../analyze-table/index), [CHECK TABLE](../sql-commands-check-table/index), [CREATE INDEX](../create-index/index), [DROP INDEX](../drop-index/index), [OPTIMIZE TABLE](../optimize-table/index), and [REPAIR TABLE](../repair-table/index). In [MariaDB 10.3](../what-is-mariadb-103/index) and later, this also includes [ALTER SEQUENCE](../alter-sequence/index) statements.

 You can dynamically enable this feature using a [SET GLOBAL](../set/index#global-session) statement. For example: 

 
```
SET GLOBAL log_slow_admin_statements=ON;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
log_slow_admin_statements=ON

```

Enabling the Slow Query Log for Specific Criteria
-------------------------------------------------

 It is possible to enable logging to the slow query log for queries that meet specific criteria by configuring the [log\_slow\_filter](../server-system-variables/index#log_slow_filter) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_slow_filter='filesort,filesort_on_disk,tmp_table,tmp_table_on_disk';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
log_slow_filter=filesort,filesort_on_disk,tmp_table,tmp_table_on_disk

```

Throttling the Slow Query Log
-----------------------------

 The slow query log can create a lot of I/O, so it can be beneficial to throttle it in some cases. The slow query log can be throttled by configuring the [log\_slow\_rate\_limit](../server-system-variables/index#log_slow_rate_limit) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_slow_rate_limit=5;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
log_slow_rate_limit=5

```

Configuring the Slow Query Log Verbosity
----------------------------------------

 There are a few optional pieces of information that can be included in the slow query log for each query. This optional information can be included by configuring the [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity) system variable. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL log_slow_verbosity='query_plan,explain';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
log_output=FILE
slow_query_log
slow_query_log_file=slow-queries.log
long_query_time=5.0
log_slow_verbosity=query_plan,explain

```

It is possible to have [EXPLAIN output printed in the slow query log](../explain-in-the-slow-query-log/index).

 Viewing the Slow Query Log
--------------------------

 Slow query logs written to file can be viewed with any text editor, or you can use the [mariadb-dumpslow](../mariadb-dumpslow/index) tool to ease the process by summarizing the information.

 Queries that you find in the log are key queries to try to optimize by constructing a [more efficient query](../query-optimizations/index) or by making [better use of indexes](../optimization-and-indexes/index). 

 For queries that appear in the log that cannot be optimized in the above ways, perhaps because they are simply very large selects, due to slow hardware, or very high lock/cpu/io contention, using shard/clustering/load balancing solutions, better hardware, or stats tables may help to improve these queries.

 Slow query logs written to table can be viewed by querying the [slow\_log](../mysqlslow_log-table/index) table.

 Variables Related to the Slow Query Log
---------------------------------------

 * [slow\_query\_log](../server-system-variables/index#slow_query_log) - enable/disable the slow query log. Renamed to [log\_slow\_query](../server-system-variables/index#log_slow_query) from [MariaDB 10.11.0](../mdb-10-11-0-rn/index).
* [log\_output](../server-system-variables/index#log_output) - how the output will be written
* [slow\_query\_log\_file](../server-system-variables/index#slow_query_log_file) - name of the slow query log file. Renamed to [log\_slow\_query\_file\_name](../server-system-variables/index#log_slow_query_file_name) from [MariaDB 10.11.0](../mdb-10-11-0-rn/index).
* [long\_query\_time](../server-system-variables/index#long_query_time) - time in seconds/microseconds defining a slow query. Renamed to [log\_slow\_query\_time](../server-system-variables/index#log_slow_query_time) from [MariaDB 10.11.0](../mdb-10-11-0-rn/index).
* [log\_queries\_not\_using\_indexes](../server-system-variables/index#log_queries_not_using_indexes) - whether to log queries that don't use indexes
* [log\_slow\_admin\_statements](../server-system-variables/index#log_slow_admin_statements) - whether to log certain admin statements
* [log\_slow\_disabled\_statements](../server-system-variables/index#log_slow_disabled_statements) - types of statements that should not be logged in the slow query log
* [min\_examined\_row\_limit](../server-system-variables/index#min_examined_row_limit) - minimum rows a query must examine to be slow. Renamed to [log\_slow\_min\_examined\_row\_limit](../server-system-variables/index#log_slow_min_examined_row_limit) from [MariaDB 10.11.0](../mdb-10-11-0-rn/index).
* [log\_slow\_rate\_limit](../server-system-variables/index#log_slow_rate_limit) - permits a fraction of slow queries to be logged
* [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity) - amount of detail in the log
* [log\_slow\_filter](../server-system-variables/index#log_slow_filter) - limit which queries to log
* [log\_slow\_slave\_statements](../replication-and-binary-log-system-variables/index#log_slow_slave_statements) - log slow statements executed by replica thread to the slow log if it is open.

 Rotating the Slow Query Log on Unix and Linux
---------------------------------------------

 Unix and Linux distributions offer the [logrotate](https://linux.die.net/man/8/logrotate) utility, which makes it very easy to rotate log files. See [Rotating Logs on Unix and Linux](../rotating-logs-on-unix-and-linux/index) for more information on how to use this utility to rotate the slow query log.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slow-query-log-overview/>

EXPLAIN in the Slow Query Log
=============================

    Switching it On
---------------

 [EXPLAIN](../explain/index) output can be switched on by specifying the "`explain`" keyword in the [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity) system variable. Alternatively, you can set with the `log-slow-verbosity` command line argument.

 
```
[mysqld]
log-slow-verbosity=query_plan,explain

```

EXPLAIN output will only be recorded if the slow query log is written to a file (and not to a table - see [Writing logs into tables](../writing-logs-into-tables/index)). This limitation also applies to other extended statistics that are written into the slow query log.

 What it Looks Like
------------------

 When explain recording is on, slow query log entries look like this:

 
```
# Time: 131112 17:03:32
# User@Host: root[root] @ localhost []
# Thread_id: 2  Schema: dbt3sf1  QC_hit: No
# Query_time: 5.524103  Lock_time: 0.000337  Rows_sent: 1  Rows_examined: 65633
#
# explain: id   select_type     table   type    possible_keys   key     key_len ref     rows    Extra
# explain: 1    SIMPLE  nation  ref     PRIMARY,n_name  n_name  26      const   1       Using where; Using index
# explain: 1    SIMPLE  customer        ref     PRIMARY,i_c_nationkey   i_c_nationkey   5       dbt3sf1.nation.n_nationkey      3145    Using index
# explain: 1    SIMPLE  orders  ref     i_o_custkey     i_o_custkey     5       dbt3sf1.customer.c_custkey      7       Using index
#
SET timestamp=1384261412;
select count(*) from customer, orders, nation where c_custkey=o_custkey and c_nationkey=n_nationkey and n_name='GERMANY';

```

EXPLAIN lines start with `# explain:`.

 See Also
--------

 * [MDEV-407](https://jira.mariadb.org/browse/MDEV-407)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-in-the-slow-query-log/>

CHANGE MASTER TO
================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Syntax
------

 
```
CHANGE MASTER ['connection_name'] TO master_def  [, master_def] ... 
  [FOR CHANNEL 'channel_name']

master_def:
    MASTER_BIND = 'interface_name'
  | MASTER_HOST = 'host_name'
  | MASTER_USER = 'user_name'
  | MASTER_PASSWORD = 'password'
  | MASTER_PORT = port_num
  | MASTER_CONNECT_RETRY = interval
  | MASTER_HEARTBEAT_PERIOD = interval
  | MASTER_LOG_FILE = 'master_log_name'
  | MASTER_LOG_POS = master_log_pos
  | RELAY_LOG_FILE = 'relay_log_name'
  | RELAY_LOG_POS = relay_log_pos
  | MASTER_DELAY = interval
  | MASTER_SSL = {0|1}
  | MASTER_SSL_CA = 'ca_file_name'
  | MASTER_SSL_CAPATH = 'ca_directory_name'
  | MASTER_SSL_CERT = 'cert_file_name'
  | MASTER_SSL_CRL = 'crl_file_name'
  | MASTER_SSL_CRLPATH = 'crl_directory_name'
  | MASTER_SSL_KEY = 'key_file_name'
  | MASTER_SSL_CIPHER = 'cipher_list'
  | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}
  | MASTER_USE_GTID = {current_pos|slave_pos|no}
  | MASTER_DEMOTE_TO_SLAVE = bool
  | IGNORE_SERVER_IDS = (server_id_list)
  | DO_DOMAIN_IDS = ([N,..])
  | IGNORE_DOMAIN_IDS = ([N,..])

```
 Description
-----------

 The `CHANGE MASTER` statement sets the options that a [replica](../replication/index) uses to connect to and replicate from a [primary](../replication/index). 

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical to using the channel\_name directly after `CHANGE MASTER`.

 
Multi-Source Replication
------------------------

 If you are using [multi-source replication](../multi-source-replication/index), then you need to specify a connection name when you execute `CHANGE MASTER`. There are two ways to do this:

 * Setting the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable prior to executing `CHANGE MASTER`.
* Setting the `connection_name` parameter when executing `CHANGE MASTER`.

 ### default\_master\_connection

 
```
SET default_master_connection = 'gandalf';
STOP SLAVE;
CHANGE MASTER TO 
   MASTER_PASSWORD='new3cret';
START SLAVE;

```

### connection\_name

 
```
STOP SLAVE 'gandalf';
CHANGE MASTER 'gandalf' TO 
   MASTER_PASSWORD='new3cret';
START SLAVE 'gandalf';

```

Options
-------

 ### Connection Options

 #### MASTER\_USER

 The `MASTER_USER` option for `CHANGE MASTER` defines the user account that the [replica](../replication/index) will use to connect to the [primary](../replication/index).

 This user account will need the [REPLICATION SLAVE](../grant/index#replication-slave) privilege (or, from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), the [REPLICATION REPLICA](../grant/index#replication-replica) on the primary.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_USER='repl',
   MASTER_PASSWORD='new3cret';
START SLAVE;

```

The maximum length of the `MASTER_USER` string is 96 characters until [MariaDB 10.5](../what-is-mariadb-105/index), and 128 characters from [MariaDB 10.6](../what-is-mariadb-106/index).

 #### MASTER\_PASSWORD

 The `MASTER_PASSWORD` option for `CHANGE MASTER` defines the password that the [replica](../replication/index) will use to connect to the [primary](../replication/index) as the user account defined by the [MASTER\_USER](#master_user) option.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   MASTER_PASSWORD='new3cret';
START SLAVE;

```

The maximum length of the `MASTER_PASSWORD` string is 32 characters. The effective maximum length of the string depends on how many bytes are used per character and can be up to 96 characters.

 
Due to [MDEV-29994](https://jira.mariadb.org/browse/MDEV-29994), the password can be silently truncated to 41 characters when MariaDB is restarted. For this reason it is recommended to use a password that is shorter than this.

 
#### MASTER\_HOST

 The `MASTER_HOST` option for `CHANGE MASTER` defines the hostname or IP address of the [primary](../replication/index).

 If you set the value of the `MASTER_HOST` option to the empty string, then that is not the same as not setting the option's value at all. If you set the value of the `MASTER_HOST` option to the empty string, then the `CHANGE MASTER` command will fail with an error. In [MariaDB 5.3](../what-is-mariadb-53/index) and before, if you set the value of the `MASTER_HOST` option to the empty string, then the `CHANGE MASTER` command would succeed, but the subsequent [START SLAVE](../start-slave/index) command would fail.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_HOST='dbserver1.example.com',
   MASTER_USER='repl',
   MASTER_PASSWORD='new3cret',
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```


If you set the value of the `MASTER_HOST` option in a `CHANGE MASTER` command, then the replica assumes that the primary is different from before, even if you set the value of this option to the same value it had previously. In this scenario, the replica will consider the old values for the primary's [binary log](../binary-log/index) file name and position to be invalid for the new primary. As a side effect, if you do not explicitly set the values of the [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options in the statement, then the statement will be implicitly appended with `MASTER_LOG_FILE=''` and `MASTER_LOG_POS=4`. However, if you enable [GTID](../gtid/index) mode for replication by setting the [MASTER\_USE\_GTID](#master_use_gtid) option to some value other than `no` in the statement, then these values will effectively be ignored anyway.

 

Replicas cannot connect to primaries using Unix socket files or Windows named pipes. The replica must connect to the primary using TCP/IP.

 
The maximum length of the `MASTER_HOST` string is 60 characters until [MariaDB 10.5](../what-is-mariadb-105/index), and 255 characters from [MariaDB 10.6](../what-is-mariadb-106/index).

 #### MASTER\_PORT

 The `MASTER_PORT` option for `CHANGE MASTER` defines the TCP/IP port of the [primary](../replication/index).

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_HOST='dbserver1.example.com',
   MASTER_PORT=3307,
   MASTER_USER='repl',
   MASTER_PASSWORD='new3cret',
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```


If you set the value of the `MASTER_PORT` option in a `CHANGE MASTER` command, then the replica assumes that the primary is different from before, even if you set the value of this option to the same value it had previously. In this scenario, the replica will consider the old values for the primary's [binary log](../binary-log/index) file name and position to be invalid for the new primary. As a side effect, if you do not explicitly set the values of the [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options in the statement, then the statement will be implicitly appended with `MASTER_LOG_FILE=''` and `MASTER_LOG_POS=4`. However, if you enable [GTID](../gtid/index) mode for replication by setting the [MASTER\_USE\_GTID](#master_use_gtid) option to some value other than `no` in the statement, then these values will effectively be ignored anyway.

 

Replicas cannot connect to primaries using Unix socket files or Windows named pipes. The replica must connect to the primary using TCP/IP.

 
#### MASTER\_CONNECT\_RETRY

 The `MASTER_CONNECT_RETRY` option for `CHANGE MASTER` defines how many seconds that the replica will wait between connection retries. The default is `60`.

 
```
STOP SLAVE;
CHANGE MASTER TO 
   MASTER_CONNECT_RETRY=20;
START SLAVE;

```

The number of connection attempts is limited by the [master\_retry\_count](../mysqld-options/index#-master-retry-count) option. It can be set either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
master_retry_count=4294967295

```

#### MASTER\_BIND

 
The `MASTER_BIND` option for `CHANGE MASTER` is only supported by MySQL 5.6.2 and later and by MySQL NDB Cluster 7.3.1 and later. This option is not supported by MariaDB. See [MDEV-19248](https://jira.mariadb.org/browse/MDEV-19248) for more information.

 

The `MASTER_BIND` option for `CHANGE MASTER` can be used on replicas that have multiple network interfaces to choose which network interface the replica will use to connect to the primary.

 
#### MASTER\_HEARTBEAT\_PERIOD

 The `MASTER_HEARTBEAT_PERIOD` option for `CHANGE MASTER` can be used to set the interval in seconds between replication heartbeats. Whenever the primary's [binary log](../binary-log/index) is updated with an event, the waiting period for the next heartbeat is reset.

 This option's *interval* argument has the following characteristics:

 * It is a decimal value with a range of `0` to `4294967` seconds.
* It has a resolution of hundredths of a second.
* Its smallest valid non-zero value is `0.001`.
* Its default value is the value of the [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) system variable divided by 2.
* If it's set to `0`, then heartbeats are disabled.

 Heartbeats are sent by the primary only if there are no unsent events in the binary log file for a period longer than the interval.

 If the [RESET SLAVE](../reset-slave-connection_name/index) statement is executed, then the heartbeat interval is reset to the default.

 
If the [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) system variable is set to a value that is lower than the current heartbeat interval, then a warning will be issued.

 
### TLS Options

 The TLS options are used for providing information about [TLS](../data-in-transit-encryption/index). The options can be set even on replicas that are compiled without TLS support. The TLS options are saved to either the default `master.info` file or the file that is configured by the [master\_info\_file](../mysqld-options/index#-master-info-file) option, but these TLS options are ignored unless the replica supports TLS.

 See [Replication with Secure Connections](../replication-with-secure-connections/index) for more information.

 #### MASTER\_SSL

 The `MASTER_SSL` option for `CHANGE MASTER` tells the replica whether to force [TLS](../data-in-transit-encryption/index) for the connection. The valid values are `0` or `1`. Required to be set to `1` for the other `MASTER_SSL*` options to have any effect.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL=1;
START SLAVE;

```

#### MASTER\_SSL\_CA

 The `MASTER_SSL_CA` option for `CHANGE MASTER` defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

```

See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information.

 The maximum length of `MASTER_SSL_CA` string is 511 characters.

 #### MASTER\_SSL\_CAPATH

 The `MASTER_SSL_CAPATH` option for `CHANGE MASTER` defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CAPATH='/etc/my.cnf.d/certificates/ca/',
   MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

```

See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information.

 The maximum length of `MASTER_SSL_CA_PATH` string is 511 characters.

 #### MASTER\_SSL\_CERT

 The `MASTER_SSL_CERT` option for `CHANGE MASTER` defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

```

The maximum length of `MASTER_SSL_CERT` string is 511 characters.

 #### MASTER\_SSL\_CRL

 The `MASTER_SSL_CRL` option for `CHANGE MASTER` defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path.

 This option is only supported if the server was built with OpenSSL. If the server was built with yaSSL, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1,
   MASTER_SSL_CRL='/etc/my.cnf.d/certificates/crl.pem';
START SLAVE;

```

See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.

 The maximum length of `MASTER_SSL_CRL` string is 511 characters.

 #### MASTER\_SSL\_CRLPATH

 The `MASTER_SSL_CRLPATH` option for `CHANGE MASTER` defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this variable needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command.

 This option is only supported if the server was built with OpenSSL. If the server was built with yaSSL, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1,
   MASTER_SSL_CRLPATH='/etc/my.cnf.d/certificates/crl/';
START SLAVE;

```

See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.

 The maximum length of `MASTER_SSL_CRL_PATH` string is 511 characters.

 #### MASTER\_SSL\_KEY

 The `MASTER_SSL_KEY` option for `CHANGE MASTER` defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

```

The maximum length of `MASTER_SSL_KEY` string is 511 characters.

 #### MASTER\_SSL\_CIPHER

 The `MASTER_SSL_CIPHER` option for `CHANGE MASTER` defines the list of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). Besides cipher names, if MariaDB was compiled with OpenSSL, this option could be set to "SSLv3" or "TLSv1.2" to allow all SSLv3 or all TLSv1.2 ciphers. Note that the TLSv1.3 ciphers cannot be excluded when using OpenSSL, even by using this option. See [Using TLSv1.3](../using-tlsv13/index) for details.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1,
   MASTER_SSL_CIPHER='TLSv1.2';
START SLAVE;

```

The maximum length of `MASTER_SSL_CIPHER` string is 511 characters.

 #### MASTER\_SSL\_VERIFY\_SERVER\_CERT

 The `MASTER_SSL_VERIFY_SERVER_CERT` option for `CHANGE MASTER` enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_SSL_CERT='/etc/my.cnf.d/certificates/server-cert.pem',
   MASTER_SSL_KEY='/etc/my.cnf.d/certificates/server-key.pem',
   MASTER_SSL_CA='/etc/my.cnf.d/certificates/ca.pem',
   MASTER_SSL_VERIFY_SERVER_CERT=1;
START SLAVE;

```

See [Secure Connections Overview: Server Certificate Verification](../secure-connections-overview/index#server-certificate-verification) for more information.

 ### Binary Log Options

 These options are related to the [binary log](../binary-log/index) position on the primary.

 #### MASTER\_LOG\_FILE

 The `MASTER_LOG_FILE` option for `CHANGE MASTER` can be used along with `MASTER_LOG_POS` to specify the coordinates at which the [replica's I/O thread](../replication-threads/index#slave-io-thread) should begin reading from the primary's [binary logs](../binary-log/index) the next time the thread starts.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_LOG_FILE='master2-bin.001',
   MASTER_LOG_POS=4;
START SLAVE;

```


The [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options cannot be specified if the [RELAY\_LOG\_FILE](#relay_log_file) and [RELAY\_LOG\_POS](#relay_log_pos) options were also specified.

 

The [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options are effectively ignored if you enable [GTID](../gtid/index) mode for replication by setting the [MASTER\_USE\_GTID](#master_use_gtid) option to some value other than `no` in the statement.

 
#### MASTER\_LOG\_POS

 The `MASTER_LOG_POS` option for `CHANGE MASTER` can be used along with `MASTER_LOG_FILE` to specify the coordinates at which the [replica's I/O thread](../replication-threads/index#slave-io-thread) should begin reading from the primary's [binary logs](../binary-log/index) the next time the thread starts.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_LOG_FILE='master2-bin.001',
   MASTER_LOG_POS=4;
START SLAVE;

```


The [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options cannot be specified if the [RELAY\_LOG\_FILE](#relay_log_file) and [RELAY\_LOG\_POS](#relay_log_pos) options were also specified.

 

The [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options are effectively ignored if you enable [GTID](../gtid/index) mode for replication by setting the [MASTER\_USE\_GTID](#master_use_gtid) option to some value other than `no` in the statement.

 
### Relay Log Options

 These options are related to the [relay log](../relay-log/index) position on the replica.

 #### RELAY\_LOG\_FILE

 The `RELAY_LOG_FILE` option for `CHANGE MASTER` can be used along with the [RELAY\_LOG\_POS](#relay_log_pos) option to specify the coordinates at which the [replica's SQL thread](../replication-threads/index#slave-sql-thread) should begin reading from the [relay log](../relay-log/index) the next time the thread starts.

 The `CHANGE MASTER` statement usually deletes all [relay log](../relay-log/index) files. However, if the `RELAY_LOG_FILE` and/or `RELAY_LOG_POS` options are specified, then existing [relay log](../relay-log/index) files are kept.

 When you want to change the [relay log](../relay-log/index) position, you only need to stop the [replica's SQL thread](../replication-threads/index#slave-sql-thread). The [replica's I/O thread](../replication-threads/index#slave-io-thread) can continue running. The [STOP SLAVE](../stop-slave/index) and [START SLAVE](../start-slave/index) statements support the `SQL_THREAD` option for this scenario. For example:

 
```
STOP SLAVE SQL_THREAD;
CHANGE MASTER TO
   RELAY_LOG_FILE='slave-relay-bin.006',
   RELAY_LOG_POS=4025;
START SLAVE SQL_THREAD;

```

When the value of this option is changed, the metadata about the [replica's SQL thread's](../replication-threads/index#slave-sql-thread) position in the [relay logs](../relay-log/index) will also be changed in the `relay-log.info` file or the file that is configured by the [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable.

 
The [RELAY\_LOG\_FILE](#relay_log_file) and [RELAY\_LOG\_POS](#relay_log_pos) options cannot be specified if the [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options were also specified.

 
#### RELAY\_LOG\_POS

 The `RELAY_LOG_POS` option for `CHANGE MASTER` can be used along with the [RELAY\_LOG\_FILE](#relay_log_file) option to specify the coordinates at which the [replica's SQL thread](../replication-threads/index#slave-sql-thread) should begin reading from the [relay log](../relay-log/index) the next time the thread starts.

 The `CHANGE MASTER` statement usually deletes all [relay log](../relay-log/index) files. However, if the `RELAY_LOG_FILE` and/or `RELAY_LOG_POS` options are specified, then existing [relay log](../relay-log/index) files are kept.

 When you want to change the [relay log](../relay-log/index) position, you only need to stop the [replica's SQL thread](../replication-threads/index#slave-sql-thread). The [replica's I/O thread](../replication-threads/index#slave-io-thread) can continue running. The [STOP SLAVE](../stop-slave/index) and [START SLAVE](../start-slave/index) statements support the `SQL_THREAD` option for this scenario. For example:

 
```
STOP SLAVE SQL_THREAD;
CHANGE MASTER TO
   RELAY_LOG_FILE='slave-relay-bin.006',
   RELAY_LOG_POS=4025;
START SLAVE SQL_THREAD;

```

When the value of this option is changed, the metadata about the [replica's SQL thread's](../replication-threads/index#slave-sql-thread) position in the [relay logs](../relay-log/index) will also be changed in the `relay-log.info` file or the file that is configured by the [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable.

 
The [RELAY\_LOG\_FILE](#relay_log_file) and [RELAY\_LOG\_POS](#relay_log_pos) options cannot be specified if the [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options were also specified.

 
### GTID Options

 #### MASTER\_USE\_GTID

 The `MASTER_USE_GTID` option for `CHANGE MASTER` can be used to configure the replica to use the [global transaction ID (GTID)](../global-transaction-id/index) when connecting to a primary. The possible values are:

 * `current_pos` - Replicate in [GTID](../gtid/index) mode and use [gtid\_current\_pos](../gtid/index#gtid_current_pos) as the position to start downloading transactions from the primary. Deprecated from [MariaDB 10.10](../what-is-mariadb-1010/index). Using to transition to primary can break the replication state if the replica executes local transactions due to actively updating gtid\_current\_pos with gtid\_binlog\_pos and gtid\_slave\_pos. Use the new, safe, [MASTER\_DEMOTE\_TO\_SLAVE=<bool>](#master_demote_to_slave) option instead.
* `slave_pos` - Replicate in [GTID](../gtid/index) mode and use [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) as the position to start downloading transactions from the primary. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), `replica_pos` is an alias for `slave_pos`.
* `no` - Don't replicate in [GTID](../gtid/index) mode.

 For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_USE_GTID = current_pos;
START SLAVE;

```

Or:

 
```
STOP SLAVE;
SET GLOBAL gtid_slave_pos='0-1-153';
CHANGE MASTER TO
   MASTER_USE_GTID = slave_pos;
START SLAVE;

```

#### MASTER\_DEMOTE\_TO\_SLAVE

 
**MariaDB starting with [10.10](../what-is-mariadb-1010/index)**Used to transition a primary to become a replica. Replaces the old [MASTER\_USE\_GTID=current\_pos](#master_use_gtid) with a safe alternative by forcing users to set `Using_Gtid=Slave_Pos` and merging `gtid_binlog_pos` into `gtid_slave_pos` once at `CHANGE MASTER TO` time. If `gtid_slave_pos` is more recent than `gtid_binlog_pos` (as in the case of chain replication), the replication state should be preserved.

 
For example:

 
```
STOP SLAVE;
CHANGE MASTER TO
   MASTER_DEMOTE_TO_SLAVE = 1;
START SLAVE;

```

### Replication Filter Options

 Also see [Replication filters](../replication-filters/index).

 #### IGNORE\_SERVER\_IDS

 The `IGNORE_SERVER_IDS` option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to ignore [binary log](binary_log) events that originated from certain servers. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 The option's value can be specified by providing a comma-separated list of [server\_id](../replication-and-binary-log-system-variables/index#server_id) values. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   IGNORE_SERVER_IDS = (3,5);
START SLAVE;

```

If you would like to clear a previously set list, then you can set the value to an empty list. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   IGNORE_SERVER_IDS = ();
START SLAVE;

```

#### DO\_DOMAIN\_IDS

 The `DO_DOMAIN_IDS` option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to only apply [binary log](binary_log) events if the transaction's [GTID](../global-transaction-id/index) is in a specific [gtid\_domain\_id](../gtid/index#gtid_domain_id) value. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 The option's value can be specified by providing a comma-separated list of [gtid\_domain\_id](../gtid/index#gtid_domain_id) values. Duplicate values are automatically ignored. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   DO_DOMAIN_IDS = (1,2);
START SLAVE;

```

If you would like to clear a previously set list, then you can set the value to an empty list. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   DO_DOMAIN_IDS = ();
START SLAVE;

```


The [DO\_DOMAIN\_IDS](#do_domain_ids) option and the [IGNORE\_DOMAIN\_IDS](#ignore_domain_ids) option cannot both be set to non-empty values at the same time. If you want to set the [DO\_DOMAIN\_IDS](#do_domain_ids) option, and the [IGNORE\_DOMAIN\_IDS](#ignore_domain_ids) option was previously set, then you need to clear the value of the [IGNORE\_DOMAIN\_IDS](#ignore_domain_ids) option. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   IGNORE_DOMAIN_IDS = (), 
   DO_DOMAIN_IDS = (1,2);
START SLAVE;

```



The `DO_DOMAIN_IDS` option can only be specified if the replica is replicating in [GTID](../gtid/index) mode. Therefore, the [MASTER\_USE\_GTID](#master_use_gtid) option must also be set to some value other than `no` in order to use this option.

 
#### IGNORE\_DOMAIN\_IDS

 The `IGNORE_DOMAIN_IDS` option for `CHANGE MASTER` can be used to configure a [replica](../replication/index) to ignore [binary log](binary_log) events if the transaction's [GTID](../global-transaction-id/index) is in a specific [gtid\_domain\_id](../gtid/index#gtid_domain_id) value. Filtered [binary log](binary_log) events will not get logged to the replica’s [relay log](../relay-log/index), and they will not be applied by the replica.

 The option's value can be specified by providing a comma-separated list of [gtid\_domain\_id](../gtid/index#gtid_domain_id) values. Duplicate values are automatically ignored. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   IGNORE_DOMAIN_IDS = (1,2);
START SLAVE;

```

If you would like to clear a previously set list, then you can set the value to an empty list. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   IGNORE_DOMAIN_IDS = ();
START SLAVE;

```


The [DO\_DOMAIN\_IDS](#do_domain_ids) option and the [IGNORE\_DOMAIN\_IDS](#ignore_domain_ids) option cannot both be set to non-empty values at the same time. If you want to set the [IGNORE\_DOMAIN\_IDS](#ignore_domain_ids) option, and the [DO\_DOMAIN\_IDS](#do_domain_ids) option was previously set, then you need to clear the value of the [DO\_DOMAIN\_IDS](#do_domain_ids) option. For example:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   DO_DOMAIN_IDS = (), 
   IGNORE_DOMAIN_IDS = (1,2);
START SLAVE;

```



The `IGNORE_DOMAIN_IDS` option can only be specified if the replica is replicating in [GTID](../gtid/index) mode. Therefore, the [MASTER\_USE\_GTID](#master_use_gtid) option must also be set to some value other than `no` in order to use this option.

 
### Delayed Replication Options

 #### MASTER\_DELAY

 The `MASTER_DELAY` option for `CHANGE MASTER` can be used to enable [delayed replication](../delayed-replication/index). This option specifies the time in seconds (at least) that a replica should lag behind the primary up to a maximum value of 2147483647, or about 68 years. Before executing an event, the replica will first wait, if necessary, until the given time has passed since the event was created on the primary. The result is that the replica will reflect the state of the primary some time back in the past. The default is zero, no delay.

 
```
STOP SLAVE;
CHANGE MASTER TO 
   MASTER_DELAY=3600;
START SLAVE;

```

Changing Option Values
----------------------

 If you don't specify a given option when executing the `CHANGE MASTER` statement, then the option keeps its old value in most cases. Most of the time, there is no need to specify the options that do not need to change. For example, if the password for the user account that the replica uses to connect to its primary has changed, but no other options need to change, then you can just change the [MASTER\_PASSWORD](#master_password) option by executing the following commands:

 
```
STOP SLAVE;
CHANGE MASTER TO 
   MASTER_PASSWORD='new3cret';
START SLAVE;

```

There are some cases where options are implicitly reset, such as when the [MASTER\_HOST](#master_host) and [MASTER\_PORT](#master_port) options are changed.

 Option Persistence
------------------

 The values of the [MASTER\_LOG\_FILE](#master_log_file) and [MASTER\_LOG\_POS](#master_log_pos) options (i.e. the [binary log](../binary-log/index) position on the primary) and most other options are written to either the default `master.info` file or the file that is configured by the [master\_info\_file](../mysqld-options/index#-master-info-file) option. The [replica's I/O thread](../replication-threads/index#slave-io-thread) keeps this [binary log](../binary-log/index) position updated as it downloads events only when [MASTER\_USE\_GTID](#master_use_gtid) option is set to `NO`. Otherwise the file is not updated on a per event basis.

 The [master\_info\_file](../mysqld-options/index#-master-info-file) option can be set either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
master_info_file=/mariadb/myserver1-master.info

```

The values of the [RELAY\_LOG\_FILE](#relay_log_file) and [RELAY\_LOG\_POS](#relay_log_pos) options (i.e. the [relay log](../relay-log/index) position) are written to either the default `relay-log.info` file or the file that is configured by the [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable. The [replica's SQL thread](../replication-threads/index#slave-sql-thread) keeps this [relay log](../relay-log/index) position updated as it applies events.

 The [relay\_log\_info\_file](../replication-and-binary-log-system-variables/index#relay_log_info_file) system variable can be set either on the command-line or in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
relay_log_info_file=/mariadb/myserver1-relay-log.info

```

GTID Persistence
----------------

 If the replica is replicating [binary log](../binary-log/index) events that contain [GTIDs](../gtid/index), then the [replica's SQL thread](../replication-threads/index#slave-sql-thread) will write every GTID that it applies to the [mysql.gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) table. This GTID can be inspected and modified through the [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) system variable.

 If the replica has the [log\_slave\_updates](../replication-and-binary-log-system-variables/index#log_slave_updates) system variable enabled and if the replica has the [binary log](../binary-log/index) enabled, then every write by the [replica's SQL thread](../replication-threads/index#slave-sql-thread) will also go into the replica's [binary log](../binary-log/index). This means that [GTIDs](../gtid/index) of replicated transactions would be reflected in the value of the [gtid\_binlog\_pos](../gtid/index#gtid_binlog_pos) system variable.

 Creating a Replica from a Backup
--------------------------------

 The `CHANGE MASTER` statement is useful for setting up a replica when you have a backup of the primary and you also have the [binary log](../binary-log/index) position or [GTID](../gtid/index) position corresponding to the backup.

 After restoring the backup on the replica, you could execute something like this to use the [binary log](../binary-log/index) position:

 
```
CHANGE MASTER TO
   MASTER_LOG_FILE='master2-bin.001',
   MASTER_LOG_POS=4;
START SLAVE;

```

Or you could execute something like this to use the [GTID](../gtid/index) position:

 
```
SET GLOBAL gtid_slave_pos='0-1-153';
CHANGE MASTER TO
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

See [Setting up a Replication Slave with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index) for more information on how to do this with [Mariabackup](../mariabackup/index).

 Example
-------

 The following example changes the primary and primary's binary log coordinates. This is used when you want to set up the replica to replicate the primary:

 
```
CHANGE MASTER TO
   MASTER_HOST='master2.mycompany.com',
   MASTER_USER='replication',
   MASTER_PASSWORD='bigs3cret',
   MASTER_PORT=3306,
   MASTER_LOG_FILE='master2-bin.001',
   MASTER_LOG_POS=4,
   MASTER_CONNECT_RETRY=10;
START SLAVE;

```

See Also
--------

 * [Setting up replication](../setting-up-replication/index)
* [START SLAVE](../start-slave/index)
* [Multi-source replication](../multi-source-replication/index)
* [RESET SLAVE](../reset-slave-connection_name/index). Removes a connection created with `CHANGE MASTER TO`.
* [Global Transaction ID](../global-transaction-id/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/change-master-to/>

Derived Table Merge Optimization
================================

    Background
----------

 Users of "big" database systems are used to using `FROM` subqueries as a way to structure their queries. For example, if one's first thought was to select cities with population greater than 10,000 people, and then that from these cities to select those that are located in Germany, one could write this SQL:

 
```
SELECT * 
FROM 
  (SELECT * FROM City WHERE Population > 10*1000) AS big_city
WHERE 
  big_city.Country='DEU'

```

For MySQL, using such syntax was taboo. If you run [EXPLAIN](../explain/index) for this query, you can see why:

 
```
mysql> EXPLAIN SELECT * FROM (SELECT * FROM City WHERE Population > 1*1000) 
  AS big_city WHERE big_city.Country='DEU' ;
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
|  1 | PRIMARY     | <derived2> | ALL  | NULL          | NULL | NULL    | NULL | 4068 | Using where |
|  2 | DERIVED     | City       | ALL  | Population    | NULL | NULL    | NULL | 4079 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
2 rows in set (0.60 sec)

```

It plans to do the following actions:

 ![derived-inefficent]

 From left to right:

 1. Execute the subquery: `(SELECT * FROM City WHERE Population > 1*1000)`, exactly as it was written in the query.
2. Put result of the subquery into a temporary table.
3. Read back, and apply a `WHERE` condition from the upper select, `big_city.Country='DEU'`

 Executing a subquery like this is very inefficient, because the highly-selective condition from the parent select, (`Country='DEU'`) is not used when scanning the base table `City`. We read too many records from the `City` table, and then we have to write them into a temporary table and read them back again, before finally filtering them out.

 Derived table merge in action
-----------------------------

 If one runs this query in MariaDB/MySQL 5.6, they get this:

 
```
MariaDB [world]> EXPLAIN SELECT * FROM (SELECT * FROM City WHERE Population > 1*1000) 
  AS big_city WHERE big_city.Country='DEU';
+----+-------------+-------+------+--------------------+---------+---------+-------+------+------------------------------------+
| id | select_type | table | type | possible_keys      | key     | key_len | ref   | rows | Extra                              |
+----+-------------+-------+------+--------------------+---------+---------+-------+------+------------------------------------+
|  1 | SIMPLE      | City  | ref  | Population,Country | Country | 3       | const |   90 | Using index condition; Using where |
+----+-------------+-------+------+--------------------+---------+---------+-------+------+------------------------------------+
1 row in set (0.00 sec)

```

From the above, one can see that:

 1. The output has only one line. This means that the subquery has been merged into the top-level `SELECT`.
2. Table `City` is accessed through an index on the `Country` column. Apparently, the `Country='DEU'` condition was used to construct `ref` access on the table.
3. The query will read about 90 rows, which is a big improvement over the 4079 row reads plus 4068 temporary table reads/writes we had before.

 Factsheet
---------

 * Derived tables (subqueries in the `FROM` clause) can be merged into their parent select when they have no grouping, aggregates, or `ORDER BY ... LIMIT` clauses. These requirements are the same as requirements for `VIEW`s to allow `algorithm=merge`.
* The optimization is enabled by default. It can be disabled with: 
```
set @@optimizer_switch='derived_merge=OFF'

```
* Versions of MySQL and MariaDB which do not have support for this optimization will execute subqueries even when running `EXPLAIN`. This can result in a well-known problem (see e.g. [MySQL Bug #44802](http://bugs.mysql.com/bug.php?id=44802)) of `EXPLAIN` statements taking a very long time. Starting from [MariaDB 5.3](../what-is-mariadb-53/index)+ and MySQL 5.6+ `EXPLAIN` commands execute instantly, regardless of the `derived_merge` setting.

 See Also
--------

 * FAQ entry: [Why is ORDER BY in a FROM subquery ignored?](../why-is-order-by-in-a-from-subquery-ignored/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/derived-table-merge-optimization/>

Histogram-Based Statistics
==========================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Histograms are collected by default from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

  Histogram-based statistics are a mechanism to improve the query plan chosen by the optimizer in certain situations. Before their introduction, all conditions on non-indexed columns were ignored when searching for the best execution plan. Histograms can be collected for both indexed and non-indexed columns, and are made available to the optimizer.

 Histogram statistics are stored in the [mysql.column\_stats](../mysqlcolumn_stats-table/index) table, which stores data for [engine-independent table statistics](../engine-independent-table-statistics/index), and so are essentially a subset of engine-independent table statistics.

 Consider this example, using the following query:

 
```
SELECT * FROM t1,t2 WHERE t1.a=t2.a and t2.b BETWEEN 1 AND 3;

```

Let's assume that 

 * table t1 contains 100 records
* table t2 contains 1000 records
* there is a primary index on t1(a)
* there is a secondary index on t2(a)
* there is no index defined on column t2.b
* the selectivity of the condition t2.b BETWEEN (1,3) is high (~ 1%)

 Before histograms were introduced, the optimizer would choose the plan that:

 * accesses t1 using a table scan
* accesses t2 using index t2(a)
* checks the condition t2.b BETWEEN 1 AND 3

 This plan examines all rows of both tables and performs 100 index look-ups.

 With histograms available, the optimizer can choose the following, more efficient plan:

 * accesses table t2 in a table scan
* checks the condition t2.b BETWEEN 1 AND 3
* accesses t1 using index t1(a)

 This plan also examine all rows from t2, but it performs only 10 look-ups to access 10 rows of table t1.

 System Variables
----------------

 There are a number of system variables that affect histograms. 

 ### histogram\_size

 The [histogram\_size](../server-system-variables/index#histogram_size) variable determines the size, in bytes, from 0 to 255, used for a histogram. This is effectively the number of bins for `histogram_type=SINGLE_PREC_HB` or number of bins/2 for `histogram_type=DOUBLE_PREC_HB`. If it is set to 0 (the default for [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) and below), no histograms are created when running an [ANALYZE TABLE](../analyze-table/index).

 ### histogram\_type

 The [histogram\_type](../server-system-variables/index#histogram_type) variable determines whether single precision (`SINGLE_PREC_HB`) or double precision (`DOUBLE_PREC_HB`) height-balanced histograms are created. From [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), double precision is the default. For [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) and below, single precision is the default. 

 From [MariaDB 10.8](../what-is-mariadb-108/index), `JSON_HB`, JSON-format histograms, are accepted.

 ### optimizer\_use\_condition\_selectivity

 The [optimizer\_use\_condition\_selectivity](../server-system-variables/index#optimizer_use_condition_selectivity) controls which statistics can be used by the optimizer when looking for the best query execution plan.

 * `1` Use selectivity of predicates as in [MariaDB 5.5](../what-is-mariadb-55/index).
* `2` Use selectivity of all range predicates supported by indexes.
* `3` Use selectivity of all range predicates estimated without histogram.
* `4` Use selectivity of all range predicates estimated with histogram.
* `5` Additionally use selectivity of certain non-range predicates calculated on record sample.

 From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/), the default is `4`. Until [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), the default is `1`.

 
Example
-------

 Here is an example of the dramatic impact histogram-based statistics can make. The query is based on [DBT3 Benchmark Q20](../dbt3-benchmark-queries/index#q20) with 60 millions records in the `lineitem` table.

 
```
select sql_calc_found_rows s_name, s_address from 
supplier, nation where 
  s_suppkey in
    (select ps_suppkey from partsupp where
      ps_partkey in (select p_partkey from part where 
         p_name like 'forest%') and 
    ps_availqty > 
      (select 0.5 * sum(l_quantity) from lineitem where
        l_partkey = ps_partkey and l_suppkey = ps_suppkey and
        l_shipdate >= date('1994-01-01') and
        l_shipdate < date('1994-01-01') + interval '1' year ))
  and s_nationkey = n_nationkey
  and n_name = 'CANADA'
  order by s_name
  limit 10;

```

First,

 
```
set optimizer_switch='materialization=off,semijoin=off';

```


```
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows | filt | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | nation   | ALL   |...| 25   |100.00 | Using where;...
| 1 | PRIMARY | supplier | ref   |...| 1447 |100.00 | Using where; Subq
| 2 | DEP SUBQ| partsupp | idxsq |...| 38   |100.00 | Using where
| 4 | DEP SUBQ| lineitem | ref   |...| 3    |100.00 | Using where
| 3 | DEP SUBQ| part     | unqsb |...| 1    |100.00 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(51.78 sec)

```

Next, a really bad plan, yet one sometimes chosen:

 
```
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows | filt | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | supplier | ALL   |...|100381|100.00 | Using where; Subq
| 1 | PRIMARY | nation   | ref   |...| 1    |100.00 | Using where
| 2 | DEP SUBQ| partsupp | idxsq |...| 38   |100.00 | Using where
| 4 | DEP SUBQ| lineitem | ref   |...| 3    |100.00 | Using where
| 3 | DEP SUBQ| part     | unqsb |...| 1    |100.00 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(7 min 33.42 sec)

```

[Persistent statistics](../engine-independent-table-statistics/index) don't improve matters:

 
```
set use_stat_tables='preferably';
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows | filt | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | supplier | ALL   |...|10000 |100.00 | Using where;
| 1 | PRIMARY | nation   | ref   |...| 1    |100.00 | Using where
| 2 | DEP SUBQ| partsupp | idxsq |...| 80   |100.00 | Using where
| 4 | DEP SUBQ| lineitem | ref   |...| 7    |100.00 | Using where
| 3 | DEP SUBQ| part     | unqsb |...| 1    |100.00 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(7 min 40.44 sec)

```

The default flags for [optimizer\_switch](../server-system-variables/index#optimizer_switch) do not help much:

 
```
set optimizer_switch='materialization=default,semijoin=default';
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows  | filt  | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | supplier | ALL   |...|10000  |100.00 | Using where;
| 1 | PRIMARY | nation   | ref   |...| 1     |100.00 | Using where
| 1 | PRIMARY | <subq2>  | eq_ref|...| 1     |100.00 |
| 2 | MATER   | part     | ALL   |.. |2000000|100.00 | Using where
| 2 | MATER   | partsupp | ref   |...| 4     |100.00 | Using where; Subq
| 4 | DEP SUBQ| lineitem | ref   |...| 7     |100.00 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(5 min 21.44 sec)

```

Using statistics doesn't help either:

 
```
set optimizer_switch='materialization=default,semijoin=default';
set optimizer_use_condition_selectivity=4;

+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows  | filt  | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | nation   | ALL   |...| 25    |4.00   | Using where
| 1 | PRIMARY | supplier | ref   |...| 4000  |100.00 | Using where;
| 1 | PRIMARY | <subq2>  | eq_ref|...| 1     |100.00 |
| 2 | MATER   | part     | ALL   |.. |2000000|1.56   | Using where
| 2 | MATER   | partsupp | ref   |...| 4     |100.00 | Using where; Subq
| 4 | DEP SUBQ| lineitem | ref   |...| 7     | 30.72 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(5 min 22.41 sec)

```

Now, taking into account the cost of the dependent subquery:

 
```
set optimizer_switch='materialization=default,semijoin=default';
set optimizer_use_condition_selectivity=4;
set optimizer_switch='expensive_pred_static_pushdown=on';
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows | filt  | Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | nation   | ALL   |...| 25   | 4.00  | Using where
| 1 | PRIMARY | supplier | ref   |...| 4000 |100.00 | Using where;
| 2 | PRIMARY | partsupp | ref   |...| 80   |100.00 |
| 2 | PRIMARY | part     | eq_ref|...| 1    | 1.56  | where; Subq; FM
| 4 | DEP SUBQ| lineitem | ref   |...| 7    | 30.72 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(49.89 sec)

```

Finally, using [join\_buffer](../server-system-variables/index#join_buffer_size) as well:

 
```
set optimizer_switch= 'materialization=default,semijoin=default';
set optimizer_use_condition_selectivity=4;
set optimizer_switch='expensive_pred_static_pushdown=on';
set join_cache_level=6;
set optimizer_switch='mrr=on';
set optimizer_switch='mrr_sort_keys=on';
set join_buffer_size=1024*1024*16;
set join_buffer_space_limit=1024*1024*32;
+---+-------- +----------+-------+...+------+----------+------------
| id| sel_type| table    | type  |...| rows | filt |  Extra
+---+-------- +----------+-------+...+------+----------+------------
| 1 | PRIMARY | nation   | AL  L |...| 25   | 4.00  | Using where
| 1 | PRIMARY | supplier | ref   |...| 4000 |100.00 | where; BKA
| 2 | PRIMARY | partsupp | ref   |...| 80   |100.00 | BKA
| 2 | PRIMARY | part     | eq_ref|...| 1    | 1.56  | where Sq; FM; BKA
| 4 | DEP SUBQ| lineitem | ref   |...| 7    | 30.72 | Using where
+---+-------- +----------+-------+...+------+----------+------------

10 rows in set
(35.71 sec)

```


See Also
--------

 * [DECODE\_HISTOGRAM()](../decode_histogram/index)
* [Index Statistics](../index-statistics/index)
* [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [Engine-independent Statistics](../engine-independent-table-statistics/index)
* [JSON Histograms](https://mariadb.org/10-7-preview-feature-json-histograms/) (mariadb.org blog)
* [Improved histograms in MariaDB 10.8](https://youtu.be/uz3rr3WnQOs) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/histogram-based-statistics/>

Slow Query Log Extended Statistics
==================================

    Overview
--------

 * Added extra logging to slow log of 'Thread\_id, Schema, Query Cache hit, Rows sent and Rows examined'
* Added optional logging to slow log, through log\_slow\_verbosity, of query plan statistics
* Added new session variables log\_slow\_rate\_limit, log\_slow\_verbosity, log\_slow\_filter
* Added log-slow-file as synonym for 'slow-log-file', as most slow-log variables starts with 'log-slow'
* Added log-slow-time as synonym for long-query-time.

 New Session Variables
---------------------

 ### log\_slow\_verbosity

 You can set the verbosity of what's logged to the slow query log by setting the the [log\_slow\_verbosity](../server-system-variables/index#log_slow_verbosity) variable to a combination of the following values:

 * `Query_plan`
	+ For select queries, log information about the query plan. This includes "Full\_scan", "Full\_join", "Tmp\_table", "Tmp\_table\_on\_disk", "Filesort", "Filesort\_on\_disk" and number of "Merge\_passes during sorting"
* `explain`
	+ EXPLAIN output is logged in the slow query log. See [explain-in-the-slow-query-log](../explain-in-the-slow-query-log/index) for details.
* `Innodb` (From [MariaDB 10.6.15](https://mariadb.com/kb/en/mariadb-10615-release-notes/). Before that this option did nothing)
	+ Kept for compatibility. Same as `engine`.
* `engine` (From [MariaDB 10.6.15](https://mariadb.com/kb/en/mariadb-10615-release-notes/))
	+ Writes statistics from the storage engine. This includes:

 


| Option | Description | Engine |
| --- | --- | --- |
| `Pages_accessed` | Number of pages accessed from page buffer (innodb-buffer-pool / key cache) | InnoDB |
| `Pages_updated` | Number of pages updated in memory | InnoDB |
| `Pages_read_time` | Milliseconds spend reading pages from storage | InnoDB |
| `Old_rows_read` | Number of retrieval of old versions of rows in the engine (versioning) | InnoDB |
| `Engine_time` | Milliseconds spent inside engine calls (read\_row / read\_next\_row etc) | All |

 
* `full`
	+ Shortcut to enable all the verbosity options

 The default value for `log_slow_verbosity` is ' ', to be compatible with MySQL 5.1.

 Multiple options are separated by ','. 

 log\_slow\_verbosity is not supported when log\_output='TABLE'.

 In the future we will add more `engine` statistics and also support for other engines.

 ### log\_slow\_filter

 You can define which queries to log to the slow query log by setting the variable [log\_slow\_filter](../server-system-variables/index#log_slow_filter) to a combination of the following values:

 * `admin`
	+ Log administrative statements (create, optimize, drop etc...)
* `filesort`
	+ Log statement if it uses filesort
* `filesort_on_disk`
	+ Log statement if it uses filesort that needs temporary tables on disk
* `full_join`
	+ Log statements that doesn't uses indexes to join tables
* `full_scan`
	+ Log statements that uses full table scans
* `query_cache`
	+ Log statements that are resolved by the query cache
* `query_cache_miss`
	+ Log statements that are not resolved by the query cache
* `tmp_table`
	+ Log statements that uses in memory temporary tables
* `tmp_table_on_disk`
	+ Log statements that uses temporary tables on disk

 Multiple options are separated by ','. If you don't specify any options everything will be logged.

 ### log\_slow\_rate\_limit

 The [log\_slow\_rate\_limit](../server-system-variables/index#log_slow_rate_limit) variable limits logging to the slow query log by not logging every query (only one query / log\_slow\_rate\_limit is logged). This is mostly useful when debugging and you get too much information to the slow query log.

 Note that in any case, only queries that takes longer than **log\_slow\_time** or **long\_query\_time**' are logged (as before).

 This addition is based on the [microslow](http://www.percona.com/percona-builds/Percona-SQL-5.0/Percona-SQL-5.0-5.0.87-b20/patches/microslow_innodb.patch) patch from [Percona](http://www.percona.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slow-query-log-extended-statistics/>

Recursive Common Table Expressions Overview
===========================================

     Common Table Expressions (CTEs) are a standard SQL feature, and are essentially temporary named result sets. CTEs first appeared in the SQL standard in 1999, and the first implementations began appearing in 2007.

 There are two kinds of CTEs:

 * [Non-recursive](../common-table-expressions-overview/index)
* Recursive, which this article covers.

 SQL is generally poor at recursive structures.

 ![trees_and_graphs]

 CTEs permit a query to reference itself. A recursive CTE will repeatedly execute subsets of the data until it obtains the complete result set. This makes it particularly useful for handing hierarchical or tree-structured data. [max\_recursive\_iterations](../server-system-variables/index#max_recursive_iterations) avoids infinite loops.

 ### Syntax example

 [WITH RECURSIVE](../with/index) signifies a recursive CTE. It is given a name, followed by a body (the main query) as follows:

 ![rcte_syntax]

 ![cte_syntax]

 ### Computation

 Given the following structure: ![rcte_computation]

 First execute the anchor part of the query: ![rcte1]

 Next, execute the recursive part of the query: ![rcte_computation_2]

 ![rcte_computation_2b]

 ![rcte_computation_3]

 ![rcte_computation_3b]

 ![rcte_computation_4]

 ### Summary so far

 
```
with recursive R as (
  select anchor_data
  union [all]
  select recursive_part
  from R, ...
)
select ...

```

1. Compute anchor\_data
2. Compute recursive\_part to get the new data
3. if (new data is non-empty) goto 2;

 ### CAST to avoid truncating data

 As currently implemented by MariaDB and by the SQL Standard, data may be truncated if not correctly cast. It is necessary to [CAST](../cast/index) the column to the correct width if the CTE's recursive part produces wider values for a column than the CTE's nonrecursive part. Some other DBMS give an error in this situation, and MariaDB's behavior may change in future - see [MDEV-12325](https://jira.mariadb.org/browse/MDEV-12325). See the [examples below](#cast-to-avoid-data-truncation).

 ### Examples

 #### Transitive closure - determining bus destinations

 Sample data:

 ![tc_1]

 
```
CREATE TABLE bus_routes (origin varchar(50), dst varchar(50));
INSERT INTO bus_routes VALUES 
  ('New York', 'Boston'), 
  ('Boston', 'New York'), 
  ('New York', 'Washington'), 
  ('Washington', 'Boston'), 
  ('Washington', 'Raleigh');

```

Now, we want to return the bus destinations with New York as the origin:

 
```
WITH RECURSIVE bus_dst as ( 
    SELECT origin as dst FROM bus_routes WHERE origin='New York' 
  UNION
    SELECT bus_routes.dst FROM bus_routes JOIN bus_dst ON bus_dst.dst= bus_routes.origin 
) 
SELECT * FROM bus_dst;
+------------+
| dst        |
+------------+
| New York   |
| Boston     |
| Washington |
| Raleigh    |
+------------+

```

The above example is computed as follows:

 First, the anchor data is calculated:

 * Starting from New York
* Boston and Washington are added

 Next, the recursive part:

 * Starting from Boston and then Washington
* Raleigh is added
* UNION excludes nodes that are already present.

 #### Computing paths - determining bus routes

 This time, we are trying to get bus routes such as “New York -> Washington -> Raleigh”.

 Using the same sample data as the previous example:

 
```
WITH RECURSIVE paths (cur_path, cur_dest) AS (
    SELECT origin, origin FROM bus_routes WHERE origin='New York' 
  UNION
    SELECT CONCAT(paths.cur_path, ',', bus_routes.dst), bus_routes.dst 
     FROM paths
     JOIN bus_routes 
       ON paths.cur_dest = bus_routes.origin AND 
         NOT FIND_IN_SET(bus_routes.dst, paths.cur_path)
) 
SELECT * FROM paths;
+-----------------------------+------------+
| cur_path                    | cur_dest   |
+-----------------------------+------------+
| New York                    | New York   |
| New York,Boston             | Boston     |
| New York,Washington         | Washington |
| New York,Washington,Boston  | Boston     |
| New York,Washington,Raleigh | Raleigh    |
+-----------------------------+------------+

```

#### CAST to avoid data truncation

 In the following example, data is truncated because the results are not specifically cast to a wide enough type:

 
```
WITH RECURSIVE tbl AS (
  SELECT NULL AS col
  UNION
  SELECT "THIS NEVER SHOWS UP" AS col FROM tbl
)
SELECT col FROM tbl
+------+
| col  |
+------+
| NULL |
|      |
+------+

```

Explicitly use [CAST](../cast/index) to overcome this:

 
```
WITH RECURSIVE tbl AS (
  SELECT CAST(NULL AS CHAR(50)) AS col
  UNION SELECT "THIS NEVER SHOWS UP" AS col FROM tbl
)  
SELECT * FROM tbl;
+---------------------+
| col                 |
+---------------------+
| NULL                |
| THIS NEVER SHOWS UP |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/recursive-common-table-expressions-overview/>

SET STATEMENT
=============

    
**MariaDB starting with [10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)**Per-query variables were introduced in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)

 
`SET STATEMENT` can be used to set the value of a system variable for the duration of the statement. It is also possible to set multiple variables.

 Syntax
------

 
```
SET STATEMENT var1=value1 [, var2=value2, ...] 
  FOR <statement>

```

where `varN` is a system variable (list of allowed variables is provided below), and `valueN` is a constant literal.

 Description
-----------

 `SET STATEMENT var1=value1 FOR stmt`

 is roughly equivalent to

 
```
SET @save_value=@@var1;
SET SESSION var1=value1;
stmt;
SET SESSION var1=@save_value;

```

The server parses the whole statement before executing it, so any variables set in this fashion that affect the parser may not have the expected effect. Examples include the charset variables, sql\_mode=ansi\_quotes, etc.

 Examples
--------

 One can limit statement execution time `[max\_statement\_time](../server-system-variables/index#max_statement_time)`:

 
```
SET STATEMENT max_statement_time=1000 FOR SELECT ... ;

```

One can switch on/off individual optimizations:

 
```
SET STATEMENT optimizer_switch='materialization=off' FOR SELECT ....;

```

It is possible to enable MRR/BKA for a query: 

 
```
SET STATEMENT  join_cache_level=6, optimizer_switch='mrr=on'  FOR SELECT ...

```

Note that it makes no sense to try to set a session variable inside a `SET STATEMENT`:

 
```
#USELESS STATEMENT
SET STATEMENT sort_buffer_size = 100000 for SET SESSION sort_buffer_size = 200000;

```

For the above, after setting sort\_buffer\_size to 200000 it will be reset to its original state (the state before the `SET STATEMENT` started) after the statement execution.

 Limitations
-----------

 There are a number of variables that cannot be set on per-query basis. These include:

 * `autocommit`
* `character_set_client`
* `character_set_connection`
* `character_set_filesystem`
* `collation_connection`
* `default_master_connection`
* `debug_sync`
* `interactive_timeout`
* `gtid_domain_id`
* `last_insert_id`
* `log_slow_filter`
* `log_slow_rate_limit`
* `log_slow_verbosity`
* `long_query_time`
* `min_examined_row_limit`
* `profiling`
* `profiling_history_size`
* `query_cache_type`
* `rand_seed1`
* `rand_seed2`
* `skip_replication`
* `slow_query_log`
* `sql_log_off`
* `tx_isolation`
* `wait_timeout`

 Source
------

 * The feature was originally implemented as a Google Summer of Code 2009 project by Joseph Lukas.
* Percona Server 5.6 included it as [Per-query variable statement](http://www.percona.com/doc/percona-server/5.6/flexibility/per_query_variable_statement.html)
* MariaDB ported the patch and fixed *many* bugs. The task in MariaDB Jira is [MDEV-5231](https://jira.mariadb.org/browse/MDEV-5231).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-statement/>

Authentication Plugin - mysql\_native\_password
===============================================

    The `mysql_native_password` authentication plugin is the default authentication plugin that will be used for an account created when no authentication plugin is explicitly mentioned and [old\_passwords=0](../server-system-variables/index#old_passwords) is set. It uses the password hashing algorithm introduced in MySQL 4.1, which is also used by the [PASSWORD()](../password/index) function when [old\_passwords=0](../server-system-variables/index#old_passwords) is set. This hashing algorithm is based on [SHA-1](https://en.wikipedia.org/wiki/SHA-1).

 
It is not recommended to use the `mysql_native_password` authentication plugin for new installations that require **high password security**. If someone is able to both listen to the connection protocol and get a copy of the mysql.user table, then the person would be able to use this information to connect to the MariaDB server. The [ed25519](../authentication-plugin-ed25519/index) authentication plugin is a more modern authentication plugin that provides simple password authentication using a more secure algorithm.

  Installing the Plugin
---------------------

 The `mysql_native_password` authentication plugin is statically linked into the server, so no installation is necessary.

 Creating Users
--------------

 The easiest way to create a user account with the `mysql_native_password` authentication plugin is to make sure that [old\_passwords=0](../server-system-variables/index#old_passwords) is set, and then create a user account via [CREATE USER](../create-user/index) that does not specify an authentication plugin, but does specify a password via the [IDENTIFIED BY](../create-user/index#identified-by-password) clause. For example:

 
```
SET old_passwords=0;
CREATE USER username@hostname IDENTIFIED BY 'mariadb';

```

If [SQL\_MODE](../sql-mode/index) does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via [GRANT](../grant/index). For example:

 
```
SET old_passwords=0;
GRANT SELECT ON db.* TO username@hostname IDENTIFIED BY 'mariadb';

```

You can also create the user account by providing a password hash via the [IDENTIFIED BY PASSWORD](../create-user/index#identified-by-password-password_hash) clause, and MariaDB will validate whether the password hash is one that is compatible with `mysql_native_password`. For example:

 
```
SET old_passwords=0;

SELECT PASSWORD('mariadb');
+-------------------------------------------+
| PASSWORD('mariadb')                       |
+-------------------------------------------+
| *54958E764CE10E50764C2EECBB71D01F08549980 |
+-------------------------------------------+

CREATE USER username@hostname
  IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

```

Similar to all other [authentication plugins](../authentication-plugins/index), you could also specify the name of the plugin in the [IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin) clause while providing the password hash as the `USING` clause. For example:

 
```
CREATE USER username@hostname
  IDENTIFIED VIA mysql_native_password USING '*54958E764CE10E50764C2EECBB71D01F08549980';

```

Changing User Passwords
-----------------------

 You can change a user account's password with the [SET PASSWORD](../set-password/index) statement while providing the plain-text password as an argument to the [PASSWORD()](../password/index) function. For example:

 
```
SET PASSWORD =  PASSWORD('new_secret')

```

You can also change the user account's password with the [ALTER USER](../alter-user/index) statement. You would have to make sure that [old\_passwords=0](../server-system-variables/index#old_passwords) is set, and then you would have to specify a password via the [IDENTIFIED BY](../alter-user/index#identified-by-password) clause. For example:

 
```
SET old_passwords=0;
ALTER USER username@hostname IDENTIFIED BY 'new_secret';

```

Client Authentication Plugins
-----------------------------

 For clients that use the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries, MariaDB provides one client authentication plugin that is compatible with the `mysql_native_password` authentication plugin:

 * `mysql_native_password`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `mysql_native_password` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mysql --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```

However, the `mysql_native_password` client authentication plugin is generally statically linked into client libraries like `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index), so this is not usually necessary.

 ### `mysql_native_password`

 The `mysql_native_password` client authentication plugin hashes the password before sending it to the server.

 Support in Client Libraries
---------------------------

 The `mysql_native_password` authentication plugin is one of the conventional authentication plugins, so all client libraries should support it.

 Known Old Issues (Only Relevant for Old Installations)
------------------------------------------------------

 ### Mismatches Between Password and authentication\_string Columns

 For compatibility reasons,the `mysql_native_password` authentication plugin tries to read the password hash from both the `Password` and `authentication_string` columns in the [mysql.user](../mysqluser-table/index) table. This has caused issues in the past if one of the columns had a different value than the other.

 Starting with [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10311-release-notes/), [CREATE USER](../create-user/index), [ALTER USER](../alter-user/index), [GRANT](../grant/index), and [SET PASSWORD](../set-password/index) will set both columns whenever an account's password is changed.

 See [MDEV-16774](https://jira.mariadb.org/browse/MDEV-16774) for more information.

 See Also
--------

 * [ed25519](../authentication-plugin-ed25519/index) secure connection plugin
* [History of MySQL and MariaDB authentication protocols](https://mariadb.org/history-of-mysql-mariadb-authentication-protocols)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-mysql_native_password/>

optimizer\_switch
=================

     [optimizer\_switch](../server-system-variables/index#optimizer_switch) is a server variable that one can use to enable/disable specific optimizations.

 ### Syntax

 To set or unset the various optimizations, use the following syntax:

 
```
SET [GLOBAL|SESSION] optimizer_switch='cmd[,cmd]...';

```

The *cmd* takes the following format:

 


| Syntax | Description |
| --- | --- |
| default | Reset all optimizations to their default values. |
| optimization\_name=default | Set the specified optimization to its default value. |
| optimization\_name=on | Enable the specified optimization. |
| optimization\_name=off | Disable the specified optimization. |

 
There is no need to list all flags - only those that are specified in the command will be affected.

 ### Available Flags

 Below is a list of all *optimizer\_switch* flags available in MariaDB:

 


| Flag and MariaDB default | Supported in MariaDB since | Supported in MySQL since |
| --- | --- | --- |
| condition\_pushdown\_for\_derived=on | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) | - |
| [condition\_pushdown\_for\_subquery=on](../condition-pushdown-into-in-subqueries/index) | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) | - |
| condition\_pushdown\_from\_having=on | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) | - |
| [derived\_merge=on](../derived-table-merge-optimization/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.7 |
| [derived\_with\_keys](../derived-table-with-key-optimization/index)=on | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| default | [MariaDB 5.1](../what-is-mariadb-51/index) | MySQL 5.1 |
| engine\_condition\_pushdown=off | [MariaDB 5.5](../what-is-mariadb-55/index) (deprecated in 10.1) | MySQL 5.5 |
| [exists\_to\_in=on](../exists-to-in-optimization/index) | [MariaDB 10.0](../what-is-mariadb-100/index) | - |
| [extended\_keys=on](../extended-keys/index) | [MariaDB 5.5.21](https://mariadb.com/kb/en/mariadb-5521-release-notes/) | - |
| [firstmatch=on](../firstmatch-strategy/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [index\_condition\_pushdown=on](../index-condition-pushdown/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [hash\_join\_cardinality=off](../hash_join_cardinality-optimizer_switch-flag/index) | [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/) ([MDEV-30812](https://jira.mariadb.org/browse/MDEV-30812)) | - |
| index\_merge=on | [MariaDB 5.1](../what-is-mariadb-51/index) | MySQL 5.1 |
| index\_merge\_intersection=on | [MariaDB 5.1](../what-is-mariadb-51/index) | MySQL 5.1 |
| [index\_merge\_sort\_intersection=off](../index_merge_sort_intersection/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| index\_merge\_sort\_union=on | [MariaDB 5.1](../what-is-mariadb-51/index) | MySQL 5.1 |
| index\_merge\_union=on# | [MariaDB 5.1](../what-is-mariadb-51/index) | MySQL 5.1 |
| [in\_to\_exists=on](../non-semi-join-subquery-optimizations/index#the-in-to-exists-transformation) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [join\_cache\_bka=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [join\_cache\_hashed=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [join\_cache\_incremental=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [loosescan=on](../loosescan-strategy/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| materialization=on ([semi-join](../semi-join-materialization-strategy/index), [non-semi-join](../non-semi-join-subquery-optimizations/index#materialization-for-non-correlated-in-subqueries)) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [mrr=off](../multi-range-read-optimization/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [mrr\_cost\_based=off](../multi-range-read-optimization/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [mrr\_sort\_keys=off](../multi-range-read-optimization/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [not\_null\_range\_scan=off](../not_null_range_scan-optimization/index) | [MariaDB 10.5](../what-is-mariadb-105/index) | - |
| [optimize\_join\_buffer\_size=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index), Defaults to ON from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) | - |
| [orderby\_uses\_equalities=on](../improvements-to-order-by/index) | [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/) | - |
| [outer\_join\_with\_cache=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [partial\_match\_rowid\_merge=on](../non-semi-join-subquery-optimizations/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [partial\_match\_table\_scan=on](../non-semi-join-subquery-optimizations/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| reorder | [MariaDB 10.7](../what-is-mariadb-107/index) | - |
| [rowid\_filter=on](../rowid-filtering-optimization/index) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) | - |
| [semijoin=on](../semi-join-subquery-optimizations/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | MySQL 5.6 |
| [semijoin\_with\_cache=on](../block-based-join-algorithms/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [split\_materialized=on](https://jira.mariadb.org/browse/MDEV-13369)[[1](#_note-0)] | [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) | - |
| [subquery\_cache=on](../subquery-cache/index) | [MariaDB 5.3](../what-is-mariadb-53/index) | - |
| [table\_elimination=on](../table-elimination-user-interface/index) | [MariaDB 5.1](../what-is-mariadb-51/index) | - |

 
1. [↑](#_ref-0) replaced [split\_grouping\_derived](https://github.com/MariaDB/server/commit/b14e2b044b), introduced in [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/)

 ### Defaults

 


| From version | Default optimizer\_switch setting |
| --- | --- |
| [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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 |
| [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/), [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off |
| [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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 |
| [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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 |
| [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, 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 |
| [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=on, exists\_to\_in=on, orderby\_uses\_equalities=on, condition\_pushdown\_for\_derived=on, split\_materialized=on |
| [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=on, exists\_to\_in=on, orderby\_uses\_equalities=on, condition\_pushdown\_for\_derived=on |
| [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=on, exists\_to\_in=on, orderby\_uses\_equalities=off |
| [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=on, exists\_to\_in=on |
| [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=on, exists\_to\_in=off |
| [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=off, exists\_to\_in=off |
| [MariaDB 5.5.21](https://mariadb.com/kb/en/mariadb-5521-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on, extended\_keys=off |
| [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, engine\_condition\_pushdown=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=off, table\_elimination=on |
| [MariaDB 5.3.3](https://mariadb.com/kb/en/mariadb-533-release-notes/) | 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=off, table\_elimination=on |
| [MariaDB 5.3.0](https://mariadb.com/kb/en/mariadb-530-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on, index\_merge\_sort\_intersection=off, index\_condition\_pushdown=off, derived\_merge=off, derived\_with\_keys=off, firstmatch=off, loosescan=off, materialization=off, in\_to\_exists=on, semijoin=off, partial\_match\_rowid\_merge=on, partial\_match\_table\_scan=on, subquery\_cache=off, mrr=off, mrr\_cost\_based=off, mrr\_sort\_keys=off, outer\_join\_with\_cache=off, semijoin\_with\_cache=off, join\_cache\_incremental=on, join\_cache\_hashed=on, join\_cache\_bka=on, optimize\_join\_buffer\_size=off, table\_elimination=on |
| < [MariaDB 5.3.0](https://mariadb.com/kb/en/mariadb-530-release-notes/) | index\_merge=on, index\_merge\_union=on, index\_merge\_sort\_union=on, index\_merge\_intersection=on |

 
See also
--------

 * [Quickly finding optimizer\_switch values that are on or off](../optimizer_switch-helper-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-switch/>

Authentication Plugin - mysql\_old\_password
============================================

    The `mysql_old_password` authentication plugin is the default authentication plugin that will be used for an account created when no authentication plugin is explicitly mentioned and `[old\_passwords=1](../server-system-variables/index#old_passwords)` is set. It uses the pre-MySQL 4.1 password hashing algorithm, which is also used by the `[OLD\_PASSWORD()](../old_password/index)` function and by the `[PASSWORD()](../password/index)` function when `[old\_passwords=1](../server-system-variables/index#old_passwords)` is set.

 
It is not recommended to use the `mysql_old_password` authentication plugin for new installations. The password hashing algorithm is no longer as secure as it used to be, and the plugin is primarily provided for backward-compatibility. The `[ed25519](../authentication-plugin-ed25519/index)` authentication plugin is a more modern authentication plugin that provides simple password authentication.

  Installing the Plugin
---------------------

 The `mysql_old_password` authentication plugin is statically linked into the server, so no installation is necessary.

 Creating Users
--------------

 The easiest way to create a user account with the `mysql_old_password` authentication plugin is to make sure that `[old\_passwords=1](../server-system-variables/index#old_passwords)` is set, and then create a user account via `[CREATE USER](../create-user/index)` that does not specify an authentication plugin, but does specify a password via the `[IDENTIFIED BY](../create-user/index#identified-by-password)` clause. For example:

 
```
SET old_passwords=1;
CREATE USER username@hostname IDENTIFIED BY 'mariadb';

```

If `[SQL\_MODE](../sql-mode/index)` does not have `NO_AUTO_CREATE_USER` set, then you can also create the user via `[GRANT](../grant/index)`. For example:

 
```
SET old_passwords=1;
GRANT SELECT ON db.* TO username@hostname IDENTIFIED BY 'mariadb';

```

You can also create the user account by providing a password hash via the `[IDENTIFIED BY PASSWORD](../create-user/index#identified-by-password-password_hash)` clause, and MariaDB will validate whether the password hash is one that is compatible with `mysql_old_password`. For example:

 
```
SET old_passwords=1;
Query OK, 0 rows affected (0.000 sec)

SELECT PASSWORD('mariadb');
+---------------------+
| PASSWORD('mariadb') |
+---------------------+
| 021bec665bf663f1    |
+---------------------+
1 row in set (0.000 sec)

CREATE USER username@hostname IDENTIFIED BY PASSWORD '021bec665bf663f1';
Query OK, 0 rows affected (0.000 sec)

```

Similar to all other [authentication plugins](../authentication-plugins/index), you could also specify the name of the plugin in the `[IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin)` clause while providing the password hash as the `USING` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA mysql_old_password USING '021bec665bf663f1';
Query OK, 0 rows affected (0.000 sec)

```

Changing User Passwords
-----------------------

 You can change a user account's password with the `[SET PASSWORD](../set-password/index)` statement while providing the plain-text password as an argument to the `[PASSWORD()](../password/index)` function. For example:

 
```
SET PASSWORD =  PASSWORD('new_secret')

```

You can also change the user account's password with the `[ALTER USER](../alter-user/index)` statement. You would have to make sure that `[old\_passwords=1](../server-system-variables/index#old_passwords)` is set, and then you would have to specify a password via the `[IDENTIFIED BY](../alter-user/index#identified-by-password)` clause. For example:

 
```
SET old_passwords=1;
ALTER USER username@hostname IDENTIFIED BY 'new_secret';

```

Client Authentication Plugins
-----------------------------

 For clients that use the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries, MariaDB provides one client authentication plugin that is compatible with the `mysql_old_password` authentication plugin:

 * `mysql_old_password`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `mysql_old_password` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mysql --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```

However, the `mysql_old_password` client authentication plugin is generally statically linked into client libraries like `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index), so this is not usually necessary.

 ### `mysql_old_password`

 The `mysql_old_password` client authentication plugin hashes the password before sending it to the server.

 Support in Client Libraries
---------------------------

 The `mysql_old_password` authentication plugin is one of the conventional authentication plugins, so all client libraries should support it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-mysql_old_password/>

Derived Table with Key Optimization
===================================

    The idea
--------

 If a derived table cannot be merged into its parent SELECT, it will be materialized in a temporary table, and then parent select will treat it as a regular base table.

 Before [MariaDB 5.3](../what-is-mariadb-53/index)/MySQL 5.6, the temporary table would never have any indexes, and the only way to read records from it would be a full table scan. Starting from the mentioned versions of the server, the optimizer has an option to create an index and use it for joins with other tables.

 Example
-------

 Consider a query: we want to find countries in Europe, that have more than one million people living in cities. This is accomplished with this query:

 
```
select * 
from
   Country, 
   (select 
       sum(City.Population) as urban_population, 
       City.Country 
    from City 
    group by City.Country 
    having 
    urban_population > 1*1000*1000
   ) as cities_in_country
where 
  Country.Code=cities_in_country.Country and Country.Continent='Europe';

```

The EXPLAIN output for it will show:

 
```
+----+-------------+------------+------+-------------------+-----------+---------+--------------------+------+---------------------------------+
| id | select_type | table      | type | possible_keys     | key       | key_len | ref                | rows | Extra                           |
+----+-------------+------------+------+-------------------+-----------+---------+--------------------+------+---------------------------------+
|  1 | PRIMARY     | Country    | ref  | PRIMARY,continent | continent | 17      | const              |   60 | Using index condition           |
|  1 | PRIMARY     | <derived2> | ref  | key0              | key0      | 3       | world.Country.Code |   17 |                                 |
|  2 | DERIVED     | City       | ALL  | NULL              | NULL      | NULL    | NULL               | 4079 | Using temporary; Using filesort |
+----+-------------+------------+------+-------------------+-----------+---------+--------------------+------+---------------------------------+

```

One can see here that 

 * table `<derived2>` is accessed through `key0`.
* `ref` column shows `world.Country.Code`
* if we look that up in the original query, we find the equality that was used to construct `ref` access: `Country.Code=cities_in_country.Country`.

 Factsheet
---------

 * The idea of "derived table with key" optimization is to let the materialized derived table have one key which is used for joins with other tables.
* The optimization is applied then the derived table could not be merged into its parent SELECT
	+ which happens when the derived table doesn't meet criteria for mergeable VIEW
* The optimization is ON by default, it can be switched off like so:

 
```
set optimizer_switch='derived_with_keys=off'

```

See Also
--------

 * [Optimizing Subqueries in the FROM Clause](http://dev.mysql.com/doc/refman/5.6/en/from-clause-subquery-optimization.html) in MySQL 5.6 manual
* [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [Subquery Optimizations Map](../subquery-optimizations-map/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/derived-table-with-key-optimization/>

EXISTS-to-IN Optimization
=========================

    MySQL (including MySQL 5.6) has only one execution strategy for EXISTS subqueries. The strategy is essentially the straightforward, "naive" execution, without any rewrites.

 [MariaDB 5.3](../what-is-mariadb-53/index) introduced a rich set of optimizations for IN subqueries. Since then, it makes sense to convert an EXISTS subquery into an IN so that the new optimizations can be used.

 `EXISTS` will be converted into `IN` in two cases: 

 1. Trivially correlated EXISTS subqueries
2. Semi-join EXISTS

 We will now describe these two cases in detail

 Trivially-correlated EXISTS subqueries
--------------------------------------

 Often, EXISTS subquery is correlated, but the correlation is trivial. The subquery has form

 
```
EXISTS (SELECT ...  FROM ... WHERE outer_col= inner_col AND inner_where)

```

and "outer\_col" is the only place where the subquery refers to outside fields. In this case, the subquery can be re-written into uncorrelated IN:

 
```
outer_col IN (SELECT inner_col FROM ... WHERE inner_where)

```

(`NULL` values require some special handling, see below). For uncorrelated IN subqueries, MariaDB is able a cost-based choice between two execution strategies:

 * [IN-to-EXISTS](../non-semi-join-subquery-optimizations/index#the-in-to-exists-transformation) (basically, convert back into EXISTS)
* [Materialization](../non-semi-join-subquery-optimizations/index#materialization-for-non-correlated-in-subqueries)

 That is, converting trivially-correlated `EXISTS` into uncorrelated `IN` gives query optimizer an option to use Materialization strategy for the subquery.

 Currently, EXISTS->IN conversion works only for subqueries that are at top level of the WHERE clause, or are under NOT operation which is directly at top level of the WHERE clause.

 Semi-join EXISTS subqueries
---------------------------

 If `EXISTS` subquery is an AND-part of the `WHERE` clause:

 
```
SELECT ... FROM outer_tables WHERE EXISTS (SELECT ...) AND ...

```

then it satisfies the main property of [semi-join subqueries](../semi-join-subquery-optimizations/index):

 *with semi-join subquery, we're only interested in records of outer\_tables that have matches in the subquery*

 Semi-join optimizer offers a rich set of execution strategies for both correlated and uncorrelated subqueries. The set includes FirstMatch strategy which is an equivalent of how EXISTS suqueries are executed, so we do not lose any opportunities when converting an EXISTS subquery into a semi-join.

 In theory, it makes sense to convert all kinds of EXISTS subqueries: convert both correlated and uncorrelated ones, convert irrespectively of whether the subquery has inner=outer equality.

 In practice, the subquery will be converted only if it has inner=outer equality. Both correlated and uncorrelated subqueries are converted.

 Handling of NULL values
-----------------------

 TODO: rephrase this:

 * IN has complicated NULL-semantics. NOT EXISTS doesn't.
* EXISTS-to-IN adds IS NOT NULL before the subquery predicate, when required

 Control
-------

 The optimization is controlled by the `exists_to_in` flag in [optimizer\_switch](../server-system-variables/index#optimizer_switch). Before [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/), the optimization was OFF by default. Since [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/), it has been ON by default.

 Limitations
-----------

 EXISTS-to-IN doesn't handle

 * subqueries that have GROUP BY, aggregate functions, or HAVING clause
* subqueries are UNIONs
* a number of degenerate edge cases

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/exists-to-in-optimization/>

Extended Keys
=============

    Syntax
------

 Enable:

 
```
set optimizer_switch='extended_keys=on';

```

Disable:

 
```
set optimizer_switch='extended_keys=off';

```

Description
-----------

 Extended Keys is an optimization set with the [optimizer\_switch](../server-system-variables/index#optimizer_switch) system variable, which makes use of existing components of InnoDB keys to generate more efficient execution plans. Using these components in many cases allows the server to generate execution plans which employ index-only look-ups. It is set by default.

 Extended keys can be used with:

 * ref and eq-ref accesses
* range scans
* index-merge scans
* loose scans
* min/max optimizations

 Examples
--------

 An example of how extended keys could be employed for a query built over a [DBT-3/TPC-H database](http://www.tpc.org/tpch/specs.asp) with one added index defined on `p_retailprice`:

 
```
select o_orderkey
from part, lineitem, orders
where p_retailprice > 2095 and o_orderdate='1992-07-01'
      and o_orderkey=l_orderkey and p_partkey=l_partkey;

```

The above query asks for the `orderkeys` of the orders placed on 1992-07-01 which contain parts with a retail price greater than $2095.

 Using Extended Keys, the query could be executed by the following execution plan:

 1. Scan the entries of the index `i_p_retailprice` where `p_retailprice>2095` and read `p_partkey` values from the extended keys.
2. For each value `p_partkey` make an index look-up into the table lineitem employing index `i_l_partkey` and fetch the values of `l_orderkey` from the extended index.
3. For each fetched value of `l_orderkey`, append it to the date `'1992-07-01'` and use the resulting key for an index look-up by index `i_o_orderdate` to fetch the values of `o_orderkey` from the found index entries.

 All access methods of this plan do not touch table rows, which results in much better performance.

 Here is the explain output for the above query:

 
```
MariaDB [dbt3sf10]> explain
   -> select o_orderkey
   ->   from part, lineitem, orders
   ->   where p_retailprice > 2095 and o_orderdate='1992-07-01'
   ->         and o_orderkey=l_orderkey and p_partkey=l_partkey\G
*************************** 1. row ***************************
          id: 1
 select_type: SIMPLE
       table: part
        type: range
possible_keys: PRIMARY,i_p_retailprice
         key: i_p_retailprice
     key_len: 9
         ref: NULL
        rows: 100
       Extra: Using where; Using index
*************************** 2. row ***************************
          id: 1
 select_type: SIMPLE
       table: lineitem
        type: ref
possible_keys: PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_orderkey,i_l_orderkey_quantity
         key: i_l_partkey
     key_len: 5
         ref: dbt3sf10.part.p_partkey
        rows: 15
       Extra: Using index
*************************** 3. row ***************************
          id: 1
 select_type: SIMPLE
       table: orders
        type: ref
possible_keys: PRIMARY,i_o_orderdate
         key: i_o_orderdate
     key_len: 8
         ref: const,dbt3sf10.lineitem.l_orderkey
        rows: 1
       Extra: Using index
3 rows in set (0.00 sec)

```

See Also
--------

 * [MWL#247](http://askmonty.org/worklog/?tid=247)
* [Blog post about the development of this feature](http://igors-notes.blogspot.com/2011/12/3-way-join-that-touches-only-indexes.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extended-keys/>

FirstMatch Strategy
===================

    `FirstMatch` is an execution strategy for [Semi-join subqueries](../semi-join-subquery-optimizations/index).

 The idea
--------

 It is very similar to how `IN/EXISTS` subqueries were executed in MySQL 5.x. 

 Let's take the usual example of a search for countries with big cities:

 
```
select * from Country 
where Country.code IN (select City.Country 
                       from City 
                       where City.Population > 1*1000*1000)
      and Country.continent='Europe'

```

Suppose, our execution plan is to find countries in Europe, and then, for each found country, check if it has any big cities. Regular inner join execution will look as follows:

 ![firstmatch-inner-join]

 Since Germany has two big cities (in this diagram), it will be put into the query output twice. This is not correct, `SELECT ... FROM Country` should not produce the same country record twice. The `FirstMatch` strategy avoids the production of duplicates by short-cutting execution as soon as the first genuine match is found:

 ![firstmatch-firstmatch]

 Note that the short-cutting has to take place after "Using where" has been applied. It would have been wrong to short-cut after we found Trier.

 FirstMatch in action
--------------------

 The `EXPLAIN` for the above query will look as follows:

 
```
MariaDB [world]> explain select * from Country where Country.code IN 
  (select City.Country from City where City.Population > 1*1000*1000)
    and Country.continent='Europe';
+----+-------------+---------+------+--------------------+-----------+---------+--------------------+------+----------------------------------+
| id | select_type | table   | type | possible_keys      | key       | key_len | ref                | rows | Extra                            |
+----+-------------+---------+------+--------------------+-----------+---------+--------------------+------+----------------------------------+
|  1 | PRIMARY     | Country | ref  | PRIMARY,continent  | continent | 17      | const              |   60 | Using index condition            |
|  1 | PRIMARY     | City    | ref  | Population,Country | Country   | 3       | world.Country.Code |   18 | Using where; FirstMatch(Country) |
+----+-------------+---------+------+--------------------+-----------+---------+--------------------+------+----------------------------------+
2 rows in set (0.00 sec)


```

`FirstMatch(Country)` in the Extra column means that *as soon as we have produced one matching record combination, short-cut the execution and jump back to the Country* table.

 `FirstMatch`'s query plan is very similar to one you would get in MySQL:

 
```
MySQL [world]> explain select * from Country  where Country.code IN 
  (select City.Country from City where City.Population > 1*1000*1000) 
   and Country.continent='Europe';
+----+--------------------+---------+----------------+--------------------+-----------+---------+-------+------+------------------------------------+
| id | select_type        | table   | type           | possible_keys      | key       | key_len | ref   | rows | Extra                              |
+----+--------------------+---------+----------------+--------------------+-----------+---------+-------+------+------------------------------------+
|  1 | PRIMARY            | Country | ref            | continent          | continent | 17      | const |   60 | Using index condition; Using where |
|  2 | DEPENDENT SUBQUERY | City    | index_subquery | Population,Country | Country   | 3       | func  |   18 | Using where                        |
+----+--------------------+---------+----------------+--------------------+-----------+---------+-------+------+------------------------------------+
2 rows in set (0.01 sec)

```

and these two particular query plans will execute in the same time. 

 Difference between FirstMatch and IN->EXISTS
--------------------------------------------

 The general idea behind the `FirstMatch` strategy is the same as the one behind the `IN->EXISTS` transformation, however, `FirstMatch` has several advantages:

 * Equality propagation works across semi-join bounds, but not subquery bounds. Therefore, converting a subquery to semi-join and using `FirstMatch` can still give a better execution plan. (TODO example)

 * There is only one way to apply the `IN->EXISTS` strategy and MySQL will do it unconditionally. With `FirstMatch`, the optimizer can make a choice between whether it should run the `FirstMatch` strategy as soon as all tables used in the subquery are in the join prefix, or at some later point in time. (TODO: example)

 FirstMatch factsheet
--------------------

 * The `FirstMatch` strategy works by executing the subquery and short-cutting its execution as soon as the first match is found.
* This means, subquery tables must be after all of the parent select's tables that are referred from the subquery predicate.
* `EXPLAIN` shows `FirstMatch` as "`FirstMatch(tableN)`".
* The strategy can handle correlated subqueries.
* But it cannot be applied if the subquery has meaningful `GROUP BY` and/or aggregate functions.
* Use of the `FirstMatch` strategy is controlled with the `firstmatch=on|off` flag in the [optimizer\_switch](../server-system-variables/index#optimizer_switch) variable.

 See Also
--------

 * [Semi-join subquery optimizations](../semi-join-subquery-optimizations/index)

 In-depth material:

 * [WL#3750: initial specification for FirstMatch](http://forge.mysql.com/worklog/task.php?id=3750)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/firstmatch-strategy/>

hash\_join\_cardinality optimizer\_switch Flag
==============================================

    
**MariaDB starting with [10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/)**The hash\_join\_cardinality optimizer\_switch flag was added in [MariaDB 11.0.2](https://mariadb.com/kb/en/mariadb-11-0-2-release-notes/), [MariaDB 10.11.3](https://mariadb.com/kb/en/mariadb-10-11-3-release-notes/), [MariaDB 10.10.4](https://mariadb.com/kb/en/mariadb-10-10-4-release-notes/), [MariaDB 10.9.6](https://mariadb.com/kb/en/mariadb-10-9-6-release-notes/), [MariaDB 10.8.8](https://mariadb.com/kb/en/mariadb-10-8-8-release-notes/) and [MariaDB 10.6.13](https://mariadb.com/kb/en/mariadb-10613-release-notes/).

 
In MySQL and MariaDB, the output cardinality of a part of query has historically been tied to the used access method(s). This is different from the approach used in database textbooks. There, the cardinality "x JOIN y" is the same regardless of which access methods are used to compute it.

 Example
-------

 Consider a query joining customers with their orders:

 
```
select * 
from 
  customer, orders, ...
where 
  customer.id = orders.customer_id and ...

```

Suppose, table orders has an index `IDX` on `orders.customer_id`. 

 If the query plan is using this index to fetch orders for each customer, the optimizer will use index statistics from `IDX` to estimate the number of rows in the customer-joined-with-orders.

 On the other hand, if the optimizer considers a query plan that joins customer with orders without use of indexes, it will ignore the `customer.id = orders.customer_id` equality completely and will compute the output cardinality as if customer was cross-joined with orders.

 Hash Join
---------

 MariaDB supports [Block Hash Join](../block-based-join-algorithms/index#block-hash-join). It is not enabled by default, one needs to set it [join\_cache\_level](../server-system-variables/index#join_cache_level) to 3 or a bigger value to enable it.

 Before [MDEV-30812](https://jira.mariadb.org/browse/MDEV-30812), Query optimization for Block Hash Join would work as described in the above example: It would assume that the join operation is a cross join.

 [MDEV-30812](https://jira.mariadb.org/browse/MDEV-30812) introduces a new [optimizer\_switch](../server-system-variables/index#optimizer_switch) flag, `hash_join_cardinality`. In MariaDB versions before 11.0, it is off by default.

 If one sets it to ON, the optimizer will make use of column histograms when computing the cardinality of hash join operation output.

 One can see the computation in the Optimizer Trace, search for `hash_join_cardinality`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hash_join_cardinality-optimizer_switch-flag/>

Non-semi-join Subquery Optimizations
====================================

     Certain kinds of IN-subqueries cannot be flattened into [semi-joins](../semi-join-subquery-optimizations/index). These subqueries can be both correlated or non-correlated. In order to provide consistent performance in all cases, MariaDB provides several alternative strategies for these types of subqueries. Whenever several strategies are possible, the optimizer chooses the optimal one based on cost estimates.

 The two primary non-semi-join strategies are materialization (also called outside-in materialization), and in-to-exists transformation. Materialization is applicable only for non-correlated subqueries, while in-to-exist can be used both for correlated and non-correlated subqueries.

 Applicability
-------------

 An IN subquery cannot be flattened into a semi-join in the following cases. The examples below use the *World* database from the MariaDB regression test suite.

 ### Subquery in a disjunction (OR)

 The subquery is located directly or indirectly under an OR operation in the WHERE clause of the outer query.

 Query pattern:

 
```
SELECT ... FROM ... WHERE (expr1, ..., exprN) [NOT] IN (SELECT ... ) OR expr;

```

Example:

 
```
SELECT Name FROM Country
WHERE (Code IN (select Country from City where City.Population > 100000) OR
       Name LIKE 'L%') AND
      surfacearea > 1000000;

```

### Negated subquery predicate (NOT IN)

 The subquery predicate itself is negated.

 Query pattern:

 
```
SELECT ... FROM ... WHERE ... (expr1, ..., exprN) NOT IN (SELECT ... ) ...;

```

Example:

 
```
SELECT Country.Name
FROM Country, CountryLanguage 
WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
  AND CountryLanguage.Language = 'French'
  AND Code = Country;

```

### Subquery in the SELECT or HAVING clause

 The subquery is located in the SELECT or HAVING clauses of the outer query.

 Query pattern:

 
```
SELECT field1, ..., (SELECT ...)  WHERE ...;
SELECT ...  WHERE ... HAVING (SELECT ...);

```

Example:

 
```
select Name, City.id in (select capital from Country where capital is not null) as is_capital
from City
where City.population > 10000000;

```

### Subquery with a UNION

 The subquery itself is a UNION, while the IN predicate may be anywhere in the query where IN is allowed.

 Query pattern:

 
```
... [NOT] IN (SELECT ... UNION SELECT ...)

```

Example:

 
```
SELECT * from City where (Name, 91) IN
(SELECT Name, round(Population/1000) FROM City WHERE Country = "IND" AND Population > 2500000
UNION
 SELECT Name, round(Population/1000) FROM City WHERE Country = "IND" AND Population < 100000);

```

Materialization for non-correlated IN-subqueries
------------------------------------------------

 ### Materialization basics

 The basic idea of subquery materialization is to execute the subquery and store its result in an internal temporary table indexed on all its columns. Naturally, this is possible only when the subquery is non-correlated. The IN predicate tests whether its left operand is present in the subquery result. Therefore it is not necessary to store duplicate subquery result rows in the temporary table. Storing only unique subquery rows provides two benefits - the size of the temporary table is smaller, and the index on all its columns can be unique.

 If the size of the temporary table is less than the tmp\_table\_size system variable, the table is a hash-indexed in-memory HEAP table. In the rare cases when the subquery result exceeds this limit, the temporary table is stored on disk in an ARIA or MyISAM B-tree indexed table (ARIA is the default).

 Subquery materialization happens on demand during the first execution of the IN predicate. Once the subquery is materialized, the IN predicate is evaluated very efficiently by index lookups of the outer expression into the unique index of the materialized temporary table. If there is a match, IN is TRUE, otherwise IN is FALSE.

 ### NULL-aware efficient execution

 An IN predicate may produce a NULL result if there is a NULL value in either of its arguments. Depending on its location in a query, a NULL predicate value is equivalent to FALSE. These are the cases when substituting NULL with FALSE would reject exactly the same result rows. A NULL result of IN is indistinguishable from a FALSE if the IN predicate is:

 * not negated,
* not a function argument,
* inside a WHERE or ON clause.

 In all these cases the evaluation of IN is performed as described in the previous paragraph via index lookups into the materialized subquery. In all remaining cases when NULL cannot be substituted with FALSE, it is not possible to use index lookups. This is not a limitation in the server, but a consequence of the NULL semantics in the ANSI SQL standard.

 Suppose an IN predicate is evaluated as 



```
NULL IN (select
not_null_col from t1)

```

, that is, the left operand of IN is a NULL value, and there are no NULLs in the subquery. In this case the value of IN is neither FALSE, nor TRUE. Instead it is NULL. If we were to perform an index lookup with the NULL as a key, such a value would not be found in not\_null\_col, and the IN predicate would incorrectly produce a FALSE.

 In general, an NULL value on either side of an IN acts as a "wildcard" that matches any value, and if a match exists, the result of IN is NULL. Consider the following example:

 If the left argument of IN is the row: `(7, NULL, 9)`, and the result of the right subquery operand of IN is the table:

 
```
(7, 8, 10)
(6, NULL, NULL)
(7, 11, 9)

```

The the IN predicate matches the row `(7, 11, 9)`, and the result of IN is NULL. Matches where the differing values on either side of the IN arguments are matched by a NULL in the other IN argument, are called *partial matches*.

 In order to efficiently compute the result of an IN predicate in the presence of NULLs, MariaDB implements two special algorithms for [partial matching, described here in detail](http://askmonty.org/worklog/Server-Sprint/?tid=68).

 * Rowid-merge partial matching  
 This technique is used when the number of rows in the subquery result is above a certain limit. The technique creates special indexes on some of the columns of the temporary table, and merges them by alternative scanning of each index thus performing an operation similar to set-intersection.

 * Table scan partial matching  
 This algorithm is used for very small tables when the overhead of the rowid-merge algorithm is not justifiable. Then the server simply scans the materialized subquery, and checks for partial matches. Since this strategy doesn't need any in-memory buffers, it is also used when there is not enough memory to hold the indexes of the rowid-merge strategy.

 ### Limitations

 In principle the subquery materialization strategy is universal, however, due to some technical limitations in the MariaDB server, there are few cases when the server cannot apply this optimization. 

 * BLOB fields  
 Either the left operand of an IN predicate refers to a BLOB field, or the subquery selects one or more BLOBs.

 * Incomparable fields  
 TODO

 In the above cases, the server reverts to the [IN-TO-EXISTS](index#the-in-to-exists-transformation) transformation.

 The IN-TO-EXISTS transformation
-------------------------------

 This optimization is the only subquery execution strategy that existed in older versions of MariaDB and MySQL prior to [MariaDB 5.3](../what-is-mariadb-53/index). We have made various changes and fixed a number of bugs in this code as well, but in essence it remains the same.

 Performance discussion
----------------------

 ### Example speedup over MySQL 5.x and [MariaDB 5.1](../what-is-mariadb-51/index)/5.2

 Depending on the query and data, either of the two strategies described here may result in orders of magnitude better/worse plan than the other strategy.

 Older versions of MariaDB and any current MySQL version (including MySQL 5.5, and MySQL 5.6 DMR as of July 2011) implement only the IN-TO-EXISTS transformation. As illustrated below, this strategy is inferior in many common cases to subquery materialization.

 Consider the following query over the data of the DBT3 benchmark scale 10. Find customers with top balance in their nations:

 
```
SELECT * FROM part
WHERE p_partkey IN
      (SELECT l_partkey FROM lineitem
       WHERE l_shipdate between '1997-01-01' and '1997-02-01')
ORDER BY p_retailprice DESC LIMIT 10;

```

The times to run this query is as follows:

 * Execution time in [MariaDB 5.2](../what-is-mariadb-52/index)/MySQL 5.x (any MySQL): **> 1 h**  
 The query takes more than one hour (we didn't wait longer), which makes it impractical to use subqueries in such cases. The EXPLAIN below shows that the subquery was transformed into a correlated one, which indicates an IN-TO-EXISTS transformation.

 
```
+--+------------------+--------+--------------+-------------------+----+------+---------------------------+
|id|select_type       |table   |type          |key                |ref |rows  |Extra                      |
+--+------------------+--------+--------------+-------------------+----+------+---------------------------+
| 1|PRIMARY           |part    |ALL           |NULL               |NULL|199755|Using where; Using filesort|
| 2|DEPENDENT SUBQUERY|lineitem|index_subquery|i_l_suppkey_partkey|func|    14|Using where                |
+--+------------------+--------+--------------+-------------------+----+------+---------------------------+

```

* Execution time in [MariaDB 5.3](../what-is-mariadb-53/index): **43 sec**  
 In [MariaDB 5.3](../what-is-mariadb-53/index) it takes less than a minute to run the same query. The EXPLAIN shows that the subquery remains uncorrelated, which is an indication that it is being executed via subquery materialization.

 
```
+--+------------+-----------+------+------------------+----+------+-------------------------------+
|id|select_type |table      |type  |key               |ref |rows  |Extra                          |
+--+------------+-----------+------+------------------+----+------+-------------------------------+
| 1|PRIMARY     |part       |ALL   |NULL              |NULL|199755|Using temporary; Using filesort|
| 1|PRIMARY     |<subquery2>|eq_ref|distinct_key      |func|     1|                               |
| 2|MATERIALIZED|lineitem   |range |l_shipdate_partkey|NULL|160060|Using where; Using index       |
+--+------------+-----------+------+------------------+----+------+-------------------------------+

```

The speedup here is practically infinite, because both MySQL and older MariaDB versions cannot complete the query in any reasonable time.

 In order to show the benefits of partial matching we extended the *customer* table from the DBT3 benchmark with two extra columns:

 * c\_pref\_nationkey - preferred nation to buy from,
* c\_pref\_brand - preferred brand.

 Both columns are prefixed with the percent NULL values in the column, that is, c\_pref\_nationkey\_05 contains 5% NULL values.

 Consider the query "Find all customers that didn't buy from a preferred country, and from a preferred brand withing some date ranges":

 
```
SELECT count(*)
FROM customer
WHERE (c_custkey, c_pref_nationkey_05, c_pref_brand_05) NOT IN
  (SELECT o_custkey, s_nationkey, p_brand
   FROM orders, supplier, part, lineitem
   WHERE l_orderkey = o_orderkey and
         l_suppkey = s_suppkey and
         l_partkey = p_partkey and
         p_retailprice < 1200 and
         l_shipdate >= '1996-04-01' and l_shipdate < '1996-04-05' and
         o_orderdate >= '1996-04-01' and o_orderdate < '1996-04-05');

```

* Execution time in [MariaDB 5.2](../what-is-mariadb-52/index)/MySQL 5.x (any MySQL): **40 sec**
* Execution time in [MariaDB 5.3](../what-is-mariadb-53/index): **2 sec**

 The speedup for this query is 20 times.

 ### Performance guidelines

  TODO

 Optimizer control
-----------------

 In certain cases it may be necessary to override the choice of the optimizer. Typically this is needed for benchmarking or testing purposes, or to mimic the behavior of an older version of the server, or if the optimizer made a poor choice.

 All the above strategies can be controlled via the following switches in [optimizer\_switch](../server-system-variables/index#optimizer_switch) system variable.

 * materialization=on/off  
 In some very special cases, even if materialization was forced, the optimizer may still revert to the IN-TO-EXISTS strategy if materialization is not applicable. In the cases when materialization requres partial matching (because of the presense of NULL values), there are two subordinate switches that control the two partial matching strategies:  

	+ partial\_match\_rowid\_merge=on/off  
	 This switch controls the Rowid-merge strategy. In addition to this switch, the system variable [rowid\_merge\_buff\_size](../server-system-variables/index#rowid_merge_buff_size) controls the maximum memory available to the Rowid-merge strategy.
	+ partial\_match\_table\_scan=on/off  
	 Controls the alternative partial match strategy that performs matching via a table scan.

 * in\_to\_exists=on/off  
 This switch controls the IN-TO-EXISTS transformation.

 * tmp\_table\_size and max\_heap\_table\_size system variables  
 The *tmp\_table\_size* system variable sets the upper limit for internal MEMORY temporary tables. If an internal temporary table exceeds this size, it is converted automatically into a Aria or MyISAM table on disk with a B-tree index. Notice however, that a MEMORY table cannot be larger than *max\_heap\_table\_size*.

 The two main optimizer switches - *materialization* and *in\_to\_exists* cannot be simultaneously off. If both are set to off, the server will issue an error.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/non-semi-join-subquery-optimizations/>

LooseScan Strategy
==================

    LooseScan is an execution strategy for [Semi-join subqueries](../semi-join-subquery-optimizations/index).

 The idea
--------

 We will demonstrate the `LooseScan` strategy by example. Suppose, we're looking for countries that have satellites. We can get them using the following query (for the sake of simplicity we ignore satellites that are owned by consortiums of multiple countries):

 
```
select * from Country  
where 
  Country.code in (select country_code from Satellite)

```

Suppose, there is an index on `Satellite.country_code`. If we use that index, we will get satellites in the order of their owner country:

 ![loosescan-satellites-ordered-r2]

 The `LooseScan` strategy doesn't really need ordering, what it needs is grouping. In the above figure, satellites are grouped by country. For instance, all satellites owned by Australia come together, without being mixed with satellites of other countries. This makes it easy to select just one satellite from each group, which you can join with its country and get a list of countries without duplicates:

 ![loosescan-diagram-no-where]

 LooseScan in action
-------------------

 The `EXPLAIN` output for the above query looks as follows:

 
```
MariaDB [world]> explain select * from Country where Country.code in 
  (select country_code from Satellite);
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
| id | select_type | table     | type   | possible_keys | key          | key_len | ref                          | rows | Extra                               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+
|  1 | PRIMARY     | Satellite | index  | country_code  | country_code | 9       | NULL                         |  932 | Using where; Using index; LooseScan |
|  1 | PRIMARY     | Country   | eq_ref | PRIMARY       | PRIMARY      | 3       | world.Satellite.country_code |    1 | Using index condition               |
+----+-------------+-----------+--------+---------------+--------------+---------+------------------------------+------+-------------------------------------+

```

Factsheet
---------

 * LooseScan avoids the production of duplicate record combinations by putting the subquery table first and using its index to select one record from multiple duplicates
* Hence, in order for LooseScan to be applicable, the subquery should look like:

 
```
expr IN (SELECT tbl.keypart1 FROM tbl ...)

```

or

 
```
expr IN (SELECT tbl.keypart2 FROM tbl WHERE tbl.keypart1=const AND ...)

```

* LooseScan can handle correlated subqueries
* LooseScan can be switched off by setting the `loosescan=off` flag in the [optimizer\_switch](../server-system-variables/index#optimizer_switch) variable.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/loosescan-strategy/>

Semi-join Materialization Strategy
==================================

    Semi-join Materialization is a special kind of subquery materialization used for [Semi-join subqueries](../semi-join-subquery-optimizations/index). It actually includes two strategies:

 * Materialization/lookup
* Materialization/scan

 The idea
--------

 Consider a query that finds countries in Europe which have big cities:

 
```
select * from Country 
where Country.code IN (select City.Country 
                       from City 
                       where City.Population > 7*1000*1000)
      and Country.continent='Europe'

```

The subquery is uncorrelated, that is, we can run it independently of the upper query. The idea of semi-join materialization is to do just that, and fill a temporary table with possible values of the City.country field of big cities, and then do a join with countries in Europe:

 ![sj-materialization1]

 The join can be done in two directions:

 1. From the materialized table to countries in Europe
2. From countries in Europe to the materialized table

 The first way involves doing a full scan on the materialized table, so we call it "Materialization-scan".

 If you run a join from Countries to the materialized table, the cheapest way to find a match in the materialized table is to make a lookup on its primary key (it has one: we used it to remove duplicates). Because of that, we call the strategy "Materialization-lookup".

 Semi-join materialization in action
-----------------------------------

 ### Materialization-Scan

 If we chose to look for cities with a population greater than 7 million, the optimizer will use Materialization-Scan and `EXPLAIN` will show this:

 
```
MariaDB [world]> explain select * from Country where Country.code IN 
  (select City.Country from City where  City.Population > 7*1000*1000);
+----+--------------+-------------+--------+--------------------+------------+---------+--------------------+------+-----------------------+
| id | select_type  | table       | type   | possible_keys      | key        | key_len | ref                | rows | Extra                 |
+----+--------------+-------------+--------+--------------------+------------+---------+--------------------+------+-----------------------+
|  1 | PRIMARY      | <subquery2> | ALL    | distinct_key       | NULL       | NULL    | NULL               |   15 |                       |
|  1 | PRIMARY      | Country     | eq_ref | PRIMARY            | PRIMARY    | 3       | world.City.Country |    1 |                       |
|  2 | MATERIALIZED | City        | range  | Population,Country | Population | 4       | NULL               |   15 | Using index condition |
+----+--------------+-------------+--------+--------------------+------------+---------+--------------------+------+-----------------------+
3 rows in set (0.01 sec)

```

Here, you can see:

 * There are still two `SELECT`s (look for columns with `id=1` and `id=2`)
* The second select (with `id=2`) has `select_type=MATERIALIZED`. This means it will be executed and its results will be stored in a temporary table with a unique key over all columns. The unique key is there to prevent the table from containing any duplicate records.
* The first select received the table name `&lt;subquery2&gt;`. This is the table that we got as a result of the materialization of the select with `id=2`.

 The optimizer chose to do a full scan over the materialized table, so this is an example of a use of the Materialization-Scan strategy.

 As for execution costs, we're going to read 15 rows from table City, write 15 rows to materialized table, read them back (the optimizer assumes there won't be any duplicates), and then do 15 eq\_ref accesses to table Country. In total, we'll do 45 reads and 15 writes.

 By comparison, if you run the `EXPLAIN` in MySQL, you'll get this:

 
```
MySQL [world]> explain select * from Country where Country.code IN 
  (select City.Country from City where  City.Population > 7*1000*1000);
+----+--------------------+---------+-------+--------------------+------------+---------+------+------+------------------------------------+
| id | select_type        | table   | type  | possible_keys      | key        | key_len | ref  | rows | Extra                              |
+----+--------------------+---------+-------+--------------------+------------+---------+------+------+------------------------------------+
|  1 | PRIMARY            | Country | ALL   | NULL               | NULL       | NULL    | NULL |  239 | Using where                        |
|  2 | DEPENDENT SUBQUERY | City    | range | Population,Country | Population | 4       | NULL |   15 | Using index condition; Using where |
+----+--------------------+---------+-------+--------------------+------------+---------+------+------+------------------------------------+

```

...which is a plan to do `(239 + 239*15) = 3824` table reads.

 ### Materialization-Lookup

 Let's modify the query slightly and look for countries which have cities with a population over one millon (instead of seven): 

 
```
MariaDB [world]> explain select * from Country where Country.code IN 
  (select City.Country from City where  City.Population > 1*1000*1000) ;
+----+--------------+-------------+--------+--------------------+--------------+---------+------+------+-----------------------+
| id | select_type  | table       | type   | possible_keys      | key          | key_len | ref  | rows | Extra                 |
+----+--------------+-------------+--------+--------------------+--------------+---------+------+------+-----------------------+
|  1 | PRIMARY      | Country     | ALL    | PRIMARY            | NULL         | NULL    | NULL |  239 |                       |
|  1 | PRIMARY      | <subquery2> | eq_ref | distinct_key       | distinct_key | 3       | func |    1 |                       |
|  2 | MATERIALIZED | City        | range  | Population,Country | Population   | 4       | NULL |  238 | Using index condition |
+----+--------------+-------------+--------+--------------------+--------------+---------+------+------+-----------------------+
3 rows in set (0.00 sec)

```

The `EXPLAIN` output is similar to the one which used Materialization-scan, except that:

 * the `<subquery2>` table is accessed with the `eq_ref` access method
* the access uses an index named `distinct_key`

 This means that the optimizer is planning to do index lookups into the materialized table. In other words, we're going to use the Materialization-lookup strategy.

 In MySQL (or with `optimizer_switch='semijoin=off,materialization=off'`), one will get this `EXPLAIN`:

 
```
MySQL [world]> explain select * from Country where Country.code IN 
  (select City.Country from City where  City.Population > 1*1000*1000) ;
+----+--------------------+---------+----------------+--------------------+---------+---------+------+------+-------------+
| id | select_type        | table   | type           | possible_keys      | key     | key_len | ref  | rows | Extra       |
+----+--------------------+---------+----------------+--------------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | Country | ALL            | NULL               | NULL    | NULL    | NULL |  239 | Using where |
|  2 | DEPENDENT SUBQUERY | City    | index_subquery | Population,Country | Country | 3       | func |   18 | Using where |
+----+--------------------+---------+----------------+--------------------+---------+---------+------+------+-------------+

```

One can see that both plans will do a full scan on the `Country` table. For the second step, MariaDB will fill the materialized table (238 rows read from table City and written to the temporary table) and then do a unique key lookup for each record in table `Country`, which works out to 238 unique key lookups. In total, the second step will cost `(239+238) = 477` reads and `238` temp.table writes.

 MySQL's plan for the second step is to read 18 rows using an index on `City.Country` for each record it receives for table `Country`. This works out to a cost of `(18*239) = 4302` reads. Had there been fewer subquery invocations, this plan would have been better than the one with Materialization. By the way, MariaDB has an option to use such a query plan, too (see [FirstMatch Strategy](../firstmatch-strategy/index)), but it did not choose it.

 Subqueries with grouping
------------------------

 MariaDB is able to use Semi-join materialization strategy when the subquery has grouping (other semi-join strategies are not applicable in this case).

 This allows for efficient execution of queries that search for the best/last element in a certain group. 

 For example, let's find cities that have the biggest population on their continent: 

 
```
explain 
select * from City 
where City.Population in (select max(City.Population) from City, Country 
                          where City.Country=Country.Code 
                          group by Continent)
+------+--------------+-------------+------+---------------+------------+---------+----------------------------------+------+-----------------+
| id   | select_type  | table       | type | possible_keys | key        | key_len | ref                              | rows | Extra           |
+------+--------------+-------------+------+---------------+------------+---------+----------------------------------+------+-----------------+
|    1 | PRIMARY      | <subquery2> | ALL  | distinct_key  | NULL       | NULL    | NULL                             |  239 |                 |
|    1 | PRIMARY      | City        | ref  | Population    | Population | 4       | <subquery2>.max(City.Population) |    1 |                 |
|    2 | MATERIALIZED | Country     | ALL  | PRIMARY       | NULL       | NULL    | NULL                             |  239 | Using temporary |
|    2 | MATERIALIZED | City        | ref  | Country       | Country    | 3       | world.Country.Code               |   18 |                 |
+------+--------------+-------------+------+---------------+------------+---------+----------------------------------+------+-----------------+
4 rows in set (0.00 sec)

```

the cities are:

 
```
+------+-------------------+---------+------------+
| ID   | Name              | Country | Population |
+------+-------------------+---------+------------+
| 1024 | Mumbai (Bombay)   | IND     |   10500000 |
| 3580 | Moscow            | RUS     |    8389200 |
| 2454 | Macao             | MAC     |     437500 |
|  608 | Cairo             | EGY     |    6789479 |
| 2515 | Ciudad de México | MEX     |    8591309 |
|  206 | São Paulo        | BRA     |    9968485 |
|  130 | Sydney            | AUS     |    3276207 |
+------+-------------------+---------+------------+

```

Factsheet
---------

 Semi-join materialization

 * Can be used for uncorrelated IN-subqueries. The subselect may use grouping and/or aggregate functions.
* Is shown in `EXPLAIN` as `type=MATERIALIZED` for the subquery, and a line with `table=<subqueryN>` in the parent subquery.
* Is enabled when one has both `materialization=on` and `semijoin=on` in the [optimizer\_switch](../server-system-variables/index#optimizer_switch) variable.
* The `materialization=on|off` flag is shared with [Non-semijoin materialization](../non-semi-join-subquery-optimizations/index#materialization-for-non-correlated-in-subqueries).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/semi-join-materialization-strategy/>

index\_merge sort\_intersection
===============================

    Prior to [MariaDB 5.3](../what-is-mariadb-53/index), the `index_merge` access method supported `union`, `sort-union`, and `intersection` operations. Starting from [MariaDB 5.3](../what-is-mariadb-53/index), the `sort-intersection` operation is also supported. This allows the use of `index_merge` in a broader number of cases.

 This feature is disabled by default. To enable it, turn on the optimizer switch `index_merge_sort_intersection` like so:

 
```
SET optimizer_switch='index_merge_sort_intersection=on'

```

Limitations of index\_merge/intersection
----------------------------------------

 Prior to [MariaDB 5.3](../what-is-mariadb-53/index), the `index_merge` access method had one intersection strategy called `intersection`. That strategy can only be used when merged index scans produced rowid-ordered streams. In practice this means that an `intersection` could only be constructed from equality (=) conditions.

 For example, the following query will use `intersection`:

 
```
MySQL [ontime]> EXPLAIN SELECT AVG(arrdelay) FROM ontime WHERE depdel15=1 AND OriginState ='CA';
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+-------------------------------------------------+
|id|select_type|table |type       |possible_keys       |key                 |key_len|ref |rows |Extra                                            |
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+-------------------------------------------------+
| 1|SIMPLE     |ontime|index_merge|OriginState,DepDel15|OriginState,DepDel15|3,5    |NULL|76952|Using intersect(OriginState,DepDel15);Using where|
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+-------------------------------------------------+

```

but if you replace `OriginState ='CA'` with `OriginState IN ('CA', 'GB')` (which matches the same number of records), then `intersection` is not usable anymore:

 
```
MySQL [ontime]> explain select avg(arrdelay) from ontime where depdel15=1 and OriginState IN ('CA', 'GB');
+--+-----------+------+----+--------------------+--------+-------+-----+-----+-----------+
|id|select_type|table |type|possible_keys       |key     |key_len|ref  |rows |Extra      |
+--+-----------+------+----+--------------------+--------+-------+-----+-----+-----------+
| 1|SIMPLE     |ontime|ref |OriginState,DepDel15|DepDel15|5      |const|36926|Using where|
+--+-----------+------+----+--------------------+--------+-------+-----+-----+-----------+

```

The latter query would also run 5.x times slower (from 2.2 to 10.8 seconds) in our experiments.

 How index\_merge/sort\_intersection improves the situation
----------------------------------------------------------

 In [MariaDB 5.3](../what-is-mariadb-53/index), when `index_merge_sort_intersection` is enabled, `index_merge` intersection plans can be constructed from non-equality conditions:

 
```
MySQL [ontime]> explain select avg(arrdelay) from ontime where depdel15=1 and OriginState IN ('CA', 'GB');
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+--------------------------------------------------------+
|id|select_type|table |type       |possible_keys       |key                 |key_len|ref |rows |Extra                                                   |
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+--------------------------------------------------------+
| 1|SIMPLE     |ontime|index_merge|OriginState,DepDel15|DepDel15,OriginState|5,3    |NULL|60754|Using sort_intersect(DepDel15,OriginState); Using where |
+--+-----------+------+-----------+--------------------+--------------------+-------+----+-----+--------------------------------------------------------+

```

In our tests, this query ran in 3.2 seconds, which is not as good as the case with two equalities, but still much better than 10.8 seconds we were getting without `sort_intersect`.

 The `sort_intersect` strategy has higher overhead than `intersect` but is able to handle a broader set of `WHERE` conditions.

 ![intersect-vs-sort-intersect]

 When to Use
-----------

 `index_merge/sort_intersection` works best on tables with lots of records and where intersections are sufficiently large (but still small enough to make a full table scan overkill).

 The benefit is expected to be bigger for io-bound loads.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/index_merge_sort_intersection/>

not\_null\_range\_scan Optimization
===================================

     The NOT NULL range scan optimization enables the optimizer to construct range scans from NOT NULL conditions that it was able to infer from the WHERE clause.

 The optimization appeared in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). It is not enabled by default; one needs to set an `optimizer_switch` flag to enable it.

 Description
-----------

 A basic (but slightly artificial) example:

 
```
create table items (
  price  decimal(8,2),
  weight decimal(8,2),
  ...
  index(weight)
);

```


```
-- Find items that cost more than 1000 $currency_units per kg:
set optimizer_switch='not_null_range_scan=on';
explain
select * from items where items.price > items.weight / 1000;

```

The WHERE condition in this form cannot be used for range scans. However, one can infer that it will reject rows that NULL for `weight`. That is, infer an additional condition that

 
```
weight IS NOT NULL

```

and pass it to the range optimizer. The range optimizer can, in turn, evaluate whether it makes sense to construct range access from the condition:

 
```
+------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key    | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+
|    1 | SIMPLE      | items | range | NULL          | weight | 5       | NULL | 1    | Using where |
+------+-------------+-------+-------+---------------+--------+---------+------+------+-------------+

```

Here's another example that's more complex but is based on a real-world query. Consider a join query

 
```
-- Find orders that were returned
select * from current_orders as O, order_returns as RET
where 
  O.return_id= RET.id;

```

Here, the optimizer can infer the condition "return\_id IS NOT NULL". If most of the orders are not returned (and so have NULL for return\_id), one can use range access to scan only those orders that had a return.

 Controlling the Optimization
----------------------------

 The optimization is not enabled by default. One can enable it like so 



```
 set optimizer_switch='not_null_range_scan=on';

```
 Optimizer Trace
---------------

 TODO.

 See Also
--------

 * [MDEV-15777](https://jira.mariadb.org/browse/MDEV-15777) - JIRA bug report which resulted in the optimization
* [NULL Filtering Optimization](https://dev.mysql.com/doc/internals/en/optimizer-nulls-filtering.html) is a related optimization in MySQL and MariaDB. It uses inferred NOT NULL conditions to perform filtering (but not index access)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/not_null_range_scan-optimization/>

Rowid Filtering Optimization
============================

    
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**Rowid filtering is an optimization available from [MariaDB 10.4](../what-is-mariadb-104/index). 

  The target use case for rowid filtering is as follows:

 * a table uses ref access on index IDX1
* but it also has a fairly restrictive range predicate on another index IDX2.

 In this case, it is advantageous to:

 * Do an index-only scan on index IDX2 and collect rowids of index records into a data structure that allows filtering (let's call it $FILTER).
* When doing ref access on IDX1, check $FILTER before reading the full record.

 Example
-------

 Consider a query

 
```
SELECT ...
FROM orders JOIN lineitem ON o_orderkey=l_orderkey
WHERE
  l_shipdate BETWEEN '1997-01-01' AND '1997-01-31' AND
  o_totalprice between 200000 and 230000;

```

Suppose the condition on `l_shipdate` is very restrictive, which means lineitem table should go first in the join order. Then, the optimizer can use `o_orderkey=l_orderkey` equality to do an index lookup to get the order the line item is from. On the other hand `o_totalprice between ...` can also be rather selective.

 With filtering, the query plan would be:

 
```
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: lineitem
         type: range
possible_keys: PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity
          key: i_l_shipdate
      key_len: 4
          ref: NULL
         rows: 98
        Extra: Using index condition
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: orders
         type: eq_ref|filter
possible_keys: PRIMARY,i_o_totalprice
          key: PRIMARY|i_o_totalprice
      key_len: 4|9
          ref: dbt3_s001.lineitem.l_orderkey
         rows: 1 (5%)
        Extra: Using where; Using rowid filter

```

Note that table `orders` has "Using rowid filter". The `type` column has `"|filter"`, the `key` column shows the index that is used to construct the filter. `rows` column shows the expected filter selectivity, it is 5%.

 ANALYZE FORMAT=JSON output for table orders will show

 
```
    "table": {
      "table_name": "orders",
      "access_type": "eq_ref",
      "possible_keys": ["PRIMARY", "i_o_totalprice"],
      "key": "PRIMARY",
      "key_length": "4",
      "used_key_parts": ["o_orderkey"],
      "ref": ["dbt3_s001.lineitem.l_orderkey"],
      "rowid_filter": {
        "range": {
          "key": "i_o_totalprice",
          "used_key_parts": ["o_totalprice"]
        },
        "rows": 69,
        "selectivity_pct": 4.6,
        "r_rows": 71,
        "r_selectivity_pct": 10.417,
        "r_buffer_size": 53,
        "r_filling_time_ms": 0.0716
      }

```

Note the `rowid_filter` element. It has a `range` element inside it. `selectivity_pct` is the expected selectivity, accompanied by the `r_selectivity_pct` showing the actual observed selectivity.

 Details
-------

 * The optimizer makes a cost-based decision about when the filter should be used.
* The filter data structure is currently an ordered array of rowids. (a Bloom filter would be better here and will probably be introduced in the future versions).
* The optimization needs to be supported by the storage engine. At the moment, it is supported by [InnoDB](../innodb/index) and [MyISAM](../myisam/index). It is not supported in [partitioned tables](../partitioning-tables/index).

 Control
-------

 Rowid filtering can be switched on/off using `rowid_filter` flag in the [optimizer\_switch](../server-system-variables/index#optimizer_switch) variable. By default, the optimization is enabled.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rowid-filtering-optimization/>

Semi-join Subquery Optimizations
================================

    MariaDB has a set of optimizations specifically targeted at *semi-join subqueries*.

 What is a Semi-Join Subquery
----------------------------

 A semi-join subquery has a form of

 
```
SELECT ... FROM outer_tables WHERE expr IN (SELECT ... FROM inner_tables ...) AND ...

```

that is, the subquery is an IN-subquery and it is located in the WHERE clause. The most important part here is

 *with semi-join subquery, we're only interested in records of outer\_tables that have matches in the subquery*

 Let's see why this is important. Consider a semi-join subquery:

 
```
select * from Country 
where 
  Continent='Europe' and 
  Country.Code in (select City.country 
                   from City 
                   where City.Population>1*1000*1000);

```

One can execute it "naturally", by starting from countries in Europe and checking if they have populous Cities:

 ![semi-join-outer-to-inner]

 The semi-join property also allows "backwards" execution: we can start from big cities, and check which countries they are in:

 ![semi-join-inner-to-outer]

 To contrast, let's change the subquery to be non-semi-join:

 
```
select * from Country 
where 
   Country.Continent='Europe' and 
   (Country.Code in (select City.country 
                   from City where City.Population>1*1000*1000) 
    or Country.SurfaceArea > 100*1000  -- Added this part
   );

```

It is still possible to start from countries, and then check

 * if a country has any big cities
* if it has a large surface area:

 ![non-semi-join-subquery]

 The opposite, city-to-country way is not possible. This is not a semi-join.

 ### Difference from Inner Joins

 Semi-join operations are similar to regular relational joins. There is a difference though: with semi-joins, you don't care how many matches an inner table has for an outer row. In the above countries-with-big-cities example, Germany will be returned once, even if it has three cities with populations of more than one million each.

 Semi-Join Optimizations in MariaDB
----------------------------------

 MariaDB uses semi-join optimizations to run IN subqueries.The optimizations are enabled by default. You can disable them by turning off their [optimizer\_switch](../server-system-variables/index#optimizer_switch) like so:

 
```
SET optimizer_switch='semijoin=off'

```

MariaDB has five different semi-join execution strategies:

 * [Table pullout optimization](../table-pullout-optimization/index)
* [FirstMatch execution strategy](../firstmatch-strategy/index)
* [Semi-join Materialization execution strategy](../semi-join-materialization-strategy/index)
* [LooseScan execution strategy](../loosescan-strategy/index)
* [DuplicateWeedout execution strategy](../duplicateweedout-strategy/index)

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [Subquery Optimizations Map](../subquery-optimizations-map/index)
* ["Observations about subquery use cases"](http://s.petrunia.net/blog/?p=35) blog post
* [http:*en.wikipedia.org/wiki/Semijoin*](http://en.wikipedia.org/wiki/Semijoin)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/semi-join-subquery-optimizations/>

Table Elimination User Interface
================================

    One can check that table elimination is working by looking at the output of `EXPLAIN [EXTENDED]` and not finding there the tables that were eliminated:

 
```
explain select ACRAT_rating from actors where ACNAM_name=’Gary Oldman’;
+----+--------------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
| id | select_type        | table     | type   | possible_keys | key     | key_len | ref                  | rows | Extra       |
+----+--------------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
|  1 | PRIMARY            | ac_anchor | index  | PRIMARY       | PRIMARY | 4       | NULL                 |    2 | Using index |
|  1 | PRIMARY            | ac_name   | eq_ref | PRIMARY       | PRIMARY | 4       | test.ac_anchor.AC_ID |    1 | Using where |
|  1 | PRIMARY            | ac_rating | ref    | PRIMARY       | PRIMARY | 4       | test.ac_anchor.AC_ID |    1 |             |
|  3 | DEPENDENT SUBQUERY | sub       | ref    | PRIMARY       | PRIMARY | 4       | test.ac_rating.AC_ID |    1 | Using index |
+----+--------------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+

```

Note that `ac_dob` table is not in the output. Now let's try getting birthdate instead:

 
```
explain select ACDOB_birthdate from actors where ACNAM_name=’Gary Oldman’;
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
| id | select_type | table     | type   | possible_keys | key     | key_len | ref                  | rows | Extra       |
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
|  1 | PRIMARY     | ac_anchor | index  | PRIMARY       | PRIMARY | 4       | NULL                 |    2 | Using index |
|  1 | PRIMARY     | ac_name   | eq_ref | PRIMARY       | PRIMARY | 4       | test.ac_anchor.AC_ID |    1 | Using where |
|  1 | PRIMARY     | ac_dob    | eq_ref | PRIMARY       | PRIMARY | 4       | test.ac_anchor.AC_ID |    1 |             |
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
3 rows in set (0.01 sec)

```

The `ac_dob` table is there while `ac_rating` and the subquery are gone. Now, if we just want to check the name of the actor:

 
```
explain select count(*) from actors where ACNAM_name=’Gary Oldman’;
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
| id | select_type | table     | type   | possible_keys | key     | key_len | ref                  | rows | Extra       |
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
|  1 | PRIMARY     | ac_anchor | index  | PRIMARY       | PRIMARY | 4       | NULL                 |    2 | Using index |
|  1 | PRIMARY     | ac_name   | eq_ref | PRIMARY       | PRIMARY | 4       | test.ac_anchor.AC_ID |    1 | Using where |
+----+-------------+-----------+--------+---------------+---------+---------+----------------------+------+-------------+
2 rows in set (0.01 sec)

```

In this case it will eliminate both the `ac_dob` and `ac_rating` tables.

 Removing tables from a query does not make the query slower, and it does not cut off any optimization opportunities, so table elimination is unconditional and there are no plans on having any kind of query hints for it.

 For debugging purposes there is a `table_elimination=on|off` switch in debug builds of the server.

 See Also
--------

 * This page is based on the following blog post about table elimination: <http://s.petrunia.net/blog/?p=58>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-elimination-user-interface/>

Progress Reporting
==================

     MariaDB supports progress reporting for some long running commands.

 What is Progress Reporting?
---------------------------

 Progress reporting means that:

 * There is a `Progress` column in [SHOW PROCESSLIST](../show-processlist/index) which shows the total progress (0-100%)
* [INFORMATION\_SCHEMA.PROCESSLIST](../information-schema-processlist-table/index) has three columns which allow you to see in which process stage we are and how much of that stage is completed:
	+ `STAGE`
	+ `MAX_STAGE`
	+ `PROGRESS` (within current stage).
* The client receives progress messages which it can display to the user to indicate how long the command will take.

 We have separate progress reporting for stages because different stages take different amounts of time.

 Supported Commands
------------------

 Currently, the following commands can send progress report messages to the client:

 * [ALTER TABLE](../alter-table/index)
* [CREATE INDEX](../create-index/index)
* [DROP INDEX](../drop-index/index)
* [LOAD DATA INFILE](../load-data-infile/index) (not `LOAD DATA LOCAL INFILE`, as in that case we don't know the size of the file).

 Some Aria storage engine operations also support progress messages:

 * [CHECK TABLE](../check-table/index)
* [REPAIR TABLE](../repair-table/index)
* [ANALYZE TABLE](../analyze-table/index)
* [OPTIMIZE TABLE](../optimize-table/index)

 ### Limitations

 Although the above commands support progress reporting, there are some limitations to what progress is reported. To be specific, when executing one of these commands against an InnoDB table with [ALGORITHM=INPLACE](../innodb-online-ddl-operations-with-algorithminplace/index) (which is the default in [MariaDB 10.0](../what-is-mariadb-100/index)+), progress is only reported during the merge sort phase while reconstructing indexes.

 Enabling and Disabling Progress Reporting
-----------------------------------------

 `mysqld` (the MariaDB server) automatically sends progress report messages to clients that support the new protocol, using the value of the [progress\_report\_time](../server-system-variables/index#progress_report_time) variable. They are sent every max(`global.progress_report_time` , `progress_report_time`) seconds (by default 5). You can disable the sending of progress report messages to the client by setting either the local variable (affects only the current connection) or the global variable (affects all connections) to `0`.

 If the extra column in `SHOW PROCESSLIST` gives you a compatibility problem, you can disable it by starting `mysqld` with the `--old` flag.

 Clients Which Support Progress Reporting
----------------------------------------

 * The [`mariadb` command line client](../mariadb-command-line-client/index)
* The `mytop` that comes with MariaDB has a `'%'` column which shows the progress.

 Progress Reporting in the mysql Command Line Client
---------------------------------------------------

 Progress reporting is enabled by default in the [mariadb client](../mariadb-command-line-client/index). You can disable it with `--disable-progress-reports`. It is automatically disabled in batch mode.

 When enabled, for every supported command you get a progress report like:

 
```
ALTER TABLE my_mail ENGINE=aria;
Stage: 1 of 2 'copy to tmp table'  5.37% of stage done

```

This is updated every [progress\_report\_time](../server-system-variables/index#progress_report_time) seconds (the default is 5). If the global `progress_report_time` is higher, this will be used. You can also disable error reporting by setting the variable to `0`.

 How to Add Support for Progress Reporting to a Client
-----------------------------------------------------

 You need to use the [MariaDB 5.3](../what-is-mariadb-53/index) or later client library. You can check that the library supports progress reporting by doing:

 
```
#ifdef CLIENT_PROGRESS

```

To enable progress reporting to the client you need to add `CLIENT_PROGRESS` to the `connect_flag` in `mysql_real_connect()`:

 
```
mysql_real_connect(mysql, host, user, password,
                   database, opt_mysql_port, opt_mysql_unix_port,
                   connect_flag | CLIENT_PROGRESS);

```

Then you need to provide a callback function for progress reports:

 
```
static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
                            double progress, const char *proc_info,
                            uint proc_info_length);

mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);

```

The above `report_progress` function will be called for each progress message.

 This is the implementation used by `mysql.cc`:

 
```
uint last_progress_report_length;

static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
                            double progress, const char *proc_info,
                            uint proc_info_length)
{
  uint length= printf("Stage: %d of %d '%.*s' %6.3g%% of stage done",
                      stage, max_stage, proc_info_length, proc_info, 
                      progress);
  if (length < last_progress_report_length)
    printf("%*s", last_progress_report_length - length, "");
  putc('\r', stdout);
  fflush(stdout);
  last_progress_report_length= length;
}

```

If you want only one number for the total progress, you can calculate it with:

 
```
double total_progress=
 ((stage -1) / (double) max_stage * 100.00 + progress / max_stage);

```


**Note:** `proc_info` is totally independent of stage. You can have many different `proc_info` values within a stage. The idea behind `proc_info` is to give the user more information about what the server is doing.

 
How to Add Support for Progress Reporting to a Storage Engine
-------------------------------------------------------------

 The functions to use for progress reporting are:

 
```
void thd_progress_init(MYSQL_THD thd, unsigned int max_stage);

```

Initialize progress reporting with stages. This is mainly used for commands that are totally executed within the engine, like `CHECK TABLE`. You should not use this for operations that could be called by, for example, `ALTER TABLE` as this has already called the function.

 `max_stage` is the number of stages your storage engine will have.

 
```
void thd_progress_report(MYSQL_THD thd, unsigned long long progress,
                         unsigned long long max_progress);

```

The above is used for reporting progress.

 * `progress` is how much of the file/rows/keys you have gone through.
* `max_progress` is the max number of rows you will go through.

 You can call this with varying numbers, but normally the ratio `progress/max_progress` should be increasing.

 This function can be called even if you are not using stages, for example when enabling keys as part of `ALTER TABLE` or `ADD INDEX`.

 
```
void thd_progress_next_stage(MYSQL_THD thd);

```

To go to the next stage in a multi-stage process initiated by `thd_progress_init()`:

 
```
void thd_progress_end(MYSQL_THD thd);

```

End progress reporting; Sets 'Progress' back to 0 in `SHOW PROCESSLIST`.

 
```
const char *thd_proc_info(thd, 'stage name');

```

This sets the name of the current status/stage that is displayed in `SHOW PROCESSLIST` and in the client. It's recommended that you call this between stages and thus before `thd_progress_report()` and `thd_progress_next_stage()`.

 This functions returns the last used `proc_info`. It's recommended that you restore `proc_info` to its original value when you are done processing.

 
**Note:** `thd_proc_info()` is totally independent of stage. You can have many different `proc_info` values within a stage to give the user more information about what is going on.

 
Examples to Look at in the MariaDB Source:
------------------------------------------

 * `client/mysql.cc` for an example of how to use reporting.
* `libmysql/client.c:cli_safe_read()` to see how progress packets are handled in client
* `sql/protocol.cc::net_send_progress_packet()` for how progress packets are handled in server.

 Format of Progress Packets
--------------------------

 The progress packet is sent as an error packet with error number `65535`.

 It contains the following data (in addition to the error header):

 


| Option | Number of bytes | Other info |
| --- | --- | --- |
| 1 | 1 | Number of strings. For future |
| Stage | 1 | Stage from 1 - Max\_stage |
| Max\_stage | 1 | Max number of stages |
| Progress | 3 | Progress in `% * 1000` |
| Status\_length | 1-2 | Packet length of string in `net_field_length()` format |
| Status | Status\_length | Status / Stage name |

 
See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/progress-reporting/>

SET PASSWORD
============

    Syntax
------

 
```
SET PASSWORD [FOR user] =
    {
        PASSWORD('some password')
      | OLD_PASSWORD('some password')
      | 'encrypted password'
    }

```
 Description
-----------

 The `SET PASSWORD` statement assigns a password to an existing MariaDB user account.

 If the password is specified using the `[PASSWORD()](../password/index)` or `[OLD\_PASSWORD()](../old_password/index)` function, the literal text of the password should be given. If the password is specified without using either function, the password should be the already-encrypted password value as returned by `[PASSWORD()](../password/index)`.

 `[OLD\_PASSWORD()](../old_password/index)` should only be used if your MariaDB/MySQL clients are very old (< 4.0.0).

 With no `FOR` clause, this statement sets the password for the current user. Any client that has connected to the server using a non-anonymous account can change the password for that account.

 With a `FOR` clause, this statement sets the password for a specific account on the current server host. Only clients that have the `UPDATE` privilege for the `mysql` database can do this. The user value should be given in `user_name@host_name` format, where `user_name` and `host_name` are exactly as they are listed in the User and Host columns of the `[mysql.user](../mysqluser-table/index)` table (or view in MariaDB-10.4 onwards) entry. 

 The argument to `[PASSWORD()](../password/index)` and the password given to MariaDB clients can be of arbitrary length.

 Authentication Plugin Support
-----------------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, `SET PASSWORD` (with or without `PASSWORD()`) works for accounts authenticated via any [authentication plugin](../authentication-plugins/index) that supports passwords stored in the `[mysql.global\_priv](../mysqlglobal_priv-table/index)` table.

 The `[ed25519](../authentication-plugin-ed25519/index)`, `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)`, and `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` authentication plugins store passwords in the `[mysql.global\_priv](../mysqlglobal_priv-table/index)` table.

 If you run `SET PASSWORD` on an account that authenticates with one of these authentication plugins that stores passwords in the `[mysql.global\_priv](../mysqlglobal_priv-table/index)` table, then the `PASSWORD()` function is evaluated by the specific authentication plugin used by the account. The authentication plugin hashes the password with a method that is compatible with that specific authentication plugin.

 The `[unix\_socket](../authentication-plugin-unix-socket/index)`, `[named\_pipe](../authentication-plugin-named-pipe/index)`, `[gssapi](../authentication-plugin-gssapi/index)`, and `[pam](../authentication-plugin-pam/index)` authentication plugins do **not** store passwords in the `[mysql.global\_priv](../mysqlglobal_priv-table/index)` table. These authentication plugins rely on other methods to authenticate the user.

 If you attempt to run `SET PASSWORD` on an account that authenticates with one of these authentication plugins that doesn't store a password in the `[mysql.global\_priv](../mysqlglobal_priv-table/index)` table, then MariaDB Server will raise a warning like the following:

 
```
SET PASSWORD is ignored for users authenticating via unix_socket plugin

```

See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for an overview of authentication changes in [MariaDB 10.4](../what-is-mariadb-104/index).

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, `SET PASSWORD` (with or without `PASSWORD()`) only works for accounts authenticated via `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` or `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` authentication plugins

 
Passwordless User Accounts
--------------------------

 User accounts do not always require passwords to login.

 The `[unix\_socket](../authentication-plugin-unix-socket/index)` , `[named\_pipe](../authentication-plugin-named-pipe/index)` and `[gssapi](../authentication-plugin-gssapi/index)` authentication plugins do not require a password to authenticate the user.

 The `[pam](../authentication-plugin-pam/index)` authentication plugin may or may not require a password to authenticate the user, depending on the specific configuration.

 The `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` and `[mysql\_old\_password](../authentication-plugin-mysql_old_password/index)` authentication plugins require passwords for authentication, but the password can be blank. In that case, no password is required.

 If you provide a password while attempting to log into the server as an account that doesn't require a password, then MariaDB server will simply ignore the password.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, a user account can be defined to use multiple authentication plugins in a specific order of preference. This specific scenario may be more noticeable in these versions, since an account could be associated with some authentication plugins that require a password, and some that do not.

 
Example
-------

 For example, if you had an entry with User and Host column values of '`bob`' and '`%.loc.gov`', you would write the statement like this:

 
```
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');

```

If you want to delete a password for a user, you would do:

 
```
SET PASSWORD FOR 'bob'@localhost = PASSWORD("");

```

See Also
--------

 * [Password Validation Plugins](../password-validation-plugins/index) - permits the setting of basic criteria for passwords
* `[ALTER USER](../alter-user/index)`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-password/>

Securing Connections for Client and Server
==========================================

    By default, MariaDB transmits data between the server and clients without encrypting it. This is generally acceptable when the server and client run on the same host or in networks where security is guaranteed through other means. However, in cases where the server and client exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt data in transit between the server and clients using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix `ssl_`, but internally, MariaDB only supports its secure successors.

 In order to secure connections between the server and client, you need to ensure that your server was compiled with TLS support. See [Secure Connections Overview](../secure-connections-overview/index) to determine how to check whether a server was compiled with TLS support.

 You also need an X509 certificate, a private key, and the Certificate Authority (CA) chain to verify the X509 certificate for the server. If you want to use two-way TLS, then you will also need an X509 certificate, a private key, and the Certificate Authority (CA) chain to verify the X509 certificate for the client. If you want to use self-signed certificates that are created with OpenSSL, then see [Certificate Creation with OpenSSL](../certificate-creation-with-openssl/index) for information on how to create those. 

 Enabling TLS
------------

 ### Enabling TLS for MariaDB Server

 In order to enable TLS on a MariaDB server that was compiled with TLS support, there are a number of system variables that you need to set, such as:

 * You need to set the path to the server's X509 certificate by setting the [ssl\_cert](../ssltls-system-variables/index#ssl_cert) system variable.
* You need to set the path to the server's private key by setting the [ssl\_key](../ssltls-system-variables/index#ssl_key) system variable.
* You need to set the path to the certificate authority (CA) chain that can verify the server's certificate by setting either the [ssl\_ca](../ssltls-system-variables/index#ssl_ca) or the [ssl\_capath](../ssltls-system-variables/index#ssl_capath) system variables.
* If you want to restrict the server to certain ciphers, then you also need to set the [ssl\_cipher](../ssltls-system-variables/index#ssl_cipher) system variable.

 For example, to set these variables for the server, add the system variables to a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index):

 
```
[mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/server-cert.pem
ssl_key = /etc/my.cnf.d/certificates/server-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem

```

And then [restart the server](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) to make the changes persistent.

 Once the server is back up, you can check that TLS is enabled by checking the value of the [have\_ssl](../ssltls-system-variables/index#have_ssl) system variable. For example:

 
```
SHOW VARIABLES LIKE 'have_ssl';

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_ssl      | YES   |
+---------------+-------+

```

#### Reloading the Server's Certificates and Keys Dynamically

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**The `FLUSH SSL` command was first added in [MariaDB 10.4](../what-is-mariadb-104/index).

 
In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the `FLUSH SSL` command can be used to dynamically reinitialize the server's [TLS](../data-in-transit-encryption/index) context.

 See [FLUSH SSL](../flush/index#flush-ssl) for more information.

 ### Enabling TLS for MariaDB Clients

 Different [clients and utilities](../clients-utilities/index) may use different methods to enable TLS.

 For many of the standard [clients and utilities](../clients-utilities/index) that come bundled with MariaDB, you can enable two-way TLS by adding the same options that were set for the server to a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[client-mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/client-cert.pem
ssl_key = /etc/my.cnf.d/certificates/client-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem

```

The specific options that you would need to set would depend on whether you want one-way TLS or two-way TLS, and whether you want to verify the server certificate.

 The same options may also enable TLS on non-standard [clients and utilities](../clients-utilities/index) that are linked with either [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) or [MariaDB Connector/C](../mariadb-connector-c/index).

 #### Enabling Two-Way TLS for MariaDB Clients

 Two-way TLS means that both the client and server provide a private key and an X509 certificate. It is called "two-way" TLS because both the client and server can be authenticated. For example, to specify these options in a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), you could set the following:

 
```
[client-mariadb]
...
ssl_cert = /etc/my.cnf.d/certificates/client-cert.pem
ssl_key = /etc/my.cnf.d/certificates/client-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl-verify-server-cert

```

Or if you wanted to specify them on the command-line with the [mariadb](../mariadb-command-line-client/index) client, then you could execute something like this:

 
```
$ mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-verify-server-cert

```

Two-way SSL is required for an account if the `REQUIRE X509`, `REQUIRE SUBJECT`, and/or `REQUIRE ISSUER` clauses are specified for the account.

 #### Enabling One-Way TLS for MariaDB Clients

 ##### Enabling One-Way TLS for MariaDB Clients with Server Certificate Verification

 One-way TLS means that only the server provides a private key and an X509 certificate. When TLS is used without a client certificate, it is called "one-way" TLS, because only the server can be authenticated, so authentication is only possible in one direction. However, encryption is still possible in both directions. [Server certificate verification](../secure-connections-overview/index#server-certificate-verification) means that the client verifies that the certificate belongs to the server. For example, to specify these options in a a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), you could set the following:

 
```
[client-mariadb]
...
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
ssl-verify-server-cert

```

Or if you wanted to specify them on the command-line with the [mariadb](../mariadb-command-line-client/index) client, then you could execute something like this:

 
```
$ mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-verify-server-cert

```

##### Enabling One-Way TLS for MariaDB Clients without Server Certificate Verification

 One-way TLS means that only the server provides a private key and an X509 certificate. When TLS is used without a client certificate, it is called "one-way" TLS, because only the server can be authenticated, so authentication is only possible in one direction. However, encryption is still possible in both directions. For example, to specify these options in a a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), you could set the following:

 
```
[client-mariadb]
...
ssl

```

Or if you wanted to specify them on the command-line with the [mariadb](../mariadb-command-line-client/index) client, then you could execute something like this:

 
```
$ mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl

```

### Enabling TLS for MariaDB Connector/C Clients

 See the documentation on MariaDB Connector/C's [TLS Options](../mysql_optionsv/index#tlsssl-options) for information on how to enable TLS for clients that use MariaDB Connector/C.

 ### Enabling TLS for MariaDB Connector/ODBC Clients

 See the documentation on MariaDB Connector/ODBC's [TLS-Related Connection Parameters](../about-mariadb-connector-odbc/index#tls-related-connection-parameters) for information on how to enable TLS for clients that use MariaDB Connector/ODBC.

 ### Enabling TLS for MariaDB Connector/J Clients

 See the documentation on [Using TLS/SSL with MariaDB Connector/J](../using-tls-ssl-with-mariadb-java-connector/index) for information on how to enable TLS for clients that use MariaDB Connector/J.

 Verifying that a Connection is Using TLS
----------------------------------------

 You can verify that a connection is using TLS by checking the connection's [Ssl\_cipher](../library/ssltls-status-variables/index#ssl_cipher) status variable. If it is non-empty, then the connection is using TLS. For example:

 
```
SHOW SESSION STATUS LIKE 'Ssl_cipher';
+---------------+---------------------------+
| Variable_name | Value                     |
+---------------+---------------------------+
| Ssl_cipher    | DHE-RSA-AES256-GCM-SHA384 |
+---------------+---------------------------+
1 row in set (0.00 sec)

```

Requiring TLS
-------------

 From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [require\_secure\_transport](../server-system-variables/index#require_secure_transport) system variable is available. When set (by default it is off), connections attempted using insecure transport will be rejected. Secure transports are SSL/TLS, Unix sockets or named pipes. Note that requirements set for specific user accounts will take precedence over this setting.

 ### Requiring TLS for Specific User Accounts

 You can set certain TLS-related restrictions for specific user accounts. For instance, you might use this with user accounts that require access to sensitive data while sending it across networks that you do not control. These restrictions can be enabled for a user account with the [CREATE USER](../create-user/index), [ALTER USER](../alter-user/index), or [GRANT](../grant/index) statements. For example:

 * A user account must connect via TLS if the user account is defined with the `REQUIRE SSL` clause.

 
```
ALTER USER 'alice'@'%' 
   REQUIRE SSL;

```

* A user account must connect via TLS with a specific cipher if the user account is defined with the `REQUIRE CIPHER` clause.

 
```
ALTER USER 'alice'@'%' 
   REQUIRE CIPHER 'ECDH-RSA-AES256-SHA384';

```

* A user account must connect via TLS with a valid client certificate if the user account is defined with the `REQUIRE X509` clause.

 
```
ALTER USER 'alice'@'%' 
   REQUIRE X509;

```

* A user account must connect via TLS with a specific client certificate if the user account is defined with the `REQUIRE SUBJECT` clause.

 
```
ALTER USER 'alice'@'%' 
   REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland';

```

* A user account must connect via TLS with a client certificate that must be signed by a specific certificate authority if the user account is defined with the `REQUIRE ISSUER` clause.

 
```
ALTER USER 'alice'@'%' 
   REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
   AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com';

```

### Requiring TLS for Specific User Accounts from Specific Hosts

 A user account can have different definitions depending on what host the user account is logging in from. Therefore, it is possible to have different TLS requirements for the same username for different hosts. For example:

 
```
CREATE USER 'alice'@'localhost' 
   REQUIRE NONE;

CREATE USER 'alice'@'%'
   REQUIRE SUBJECT '/CN=alice/O=My Dom, Inc./C=US/ST=Oregon/L=Portland'
   AND ISSUER '/C=FI/ST=Somewhere/L=City/ O=Some Company/CN=Peter Parker/emailAddress=p.parker@marvel.com'
   AND CIPHER 'ECDHE-ECDSA-AES256-SHA384';

```

In the above example, the `alice` user account does not require TLS when logging in from localhost. However, when the `alice` user account logs in from any other host, they must use TLS with the given cipher, and they must provide a valid client certificate with the given subject that must have been signed by the given issuer.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/securing-connections-for-client-and-server/>

Common Table Expressions
=========================

  

| Title | Description |
| --- | --- |
|  [WITH](../with/index) |  Allows reference to subqueries as temporary tables within queries.  |
|  [Non-Recursive Common Table Expressions Overview](../non-recursive-common-table-expressions-overview/index) |  Common Table Expressions (CTEs) are essentially Temporary Named Result Sets.  |
|  [Recursive Common Table Expressions Overview](../recursive-common-table-expressions-overview/index) |  A recursive CTE will repeatedly execute subsets of the data until obtaining the complete results.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/common-table-expressions/>

Password Validation Plugin API
==============================

     “Password validation” means ensuring that user passwords meet certain minimal security requirements. A dedicated plugin API allows the creation of password validation plugins that will check user passwords as they are set (in [SET PASSWORD](../set-password/index) and [GRANT](../grant/index) statements) and either allow or reject them.

 SQL-Level Extensions
--------------------

 MariaDB comes with three password validation plugins — the [simple\_password\_check](../simple_password_check/index) plugin, the [cracklib\_password\_check](../cracklib_password_check/index) plugin and the [password\_reuse\_check](../password-reuse-check-plugin/index) plugin. They are not enabled by default; use [INSTALL SONAME](../install-soname/index) (or [INSTALL PLUGIN](../install-plugin/index)) statement to install them.

 When at least one password plugin is loaded, all new passwords will be validated and password-changing statements will fail if the password will not pass validation checks. Several password validation plugin can be loaded at the same time — in this case a password must pass **all** validation checks by **all** plugins.

 ### Password-Changing Statements

 One can use various SQL statements to change a user password:

 #### With Plain Text Password

 
```
SET PASSWORD = PASSWORD('plain-text password');
SET PASSWORD FOR `user`@`host` = PASSWORD('plain-text password');
SET PASSWORD = OLD_PASSWORD('plain-text password');
SET PASSWORD FOR `user`@`host` = OLD_PASSWORD('plain-text password');
CREATE USER `user`@`host` IDENTIFIED BY 'plain-text password';
GRANT privileges TO `user`@`host` IDENTIFIED BY 'plain-text password';

```

These statements are subject to password validation. If at least one password validation plugin is loaded, plain-text passwords specified in these statements will be validated.

 #### With Password Hash

 
```
SET PASSWORD = 'password hash';
SET PASSWORD FOR `user`@`host` = 'password hash';
CREATE USER `user`@`host` IDENTIFIED BY PASSWORD 'password hash';
CREATE USER `user`@`host` IDENTIFIED VIA mysql_native_password USING 'password hash';
CREATE USER `user`@`host` IDENTIFIED VIA mysql_old_password USING 'password hash';
GRANT privileges TO `user`@`host` IDENTIFIED BY PASSWORD 'password hash';
GRANT privileges TO `user`@`host` IDENTIFIED VIA mysql_native_password USING 'password hash';
GRANT privileges TO `user`@`host` IDENTIFIED VIA mysql_old_password USING 'password hash';

```

These statements can not possibly use password validation — there is nothing to validate, the original plain-text password is not available. MariaDB introduces a **strict password validation** mode — controlled by a [strict\_password\_validation](../server-system-variables/index#strict_password_validation) global server variable. If the strict password validation is enabled and at least one password validation plugin is loaded then these “unvalidatable” passwords will be rejected. Otherwise they will be accepted. By default a strict password validation is enabled (but note that it has no effect if no password validation plugin is loaded).

 Examples
--------

 Failed password validation:

 
```
GRANT SELECT ON *.* to foobar IDENTIFIED BY 'raboof';
ERROR HY000: Your password does not satisfy the current policy requirements

SHOW WARNINGS;
+---------+------+----------------------------------------------------------------+
| Level	  | Code | Message                                                        |
+---------+------+----------------------------------------------------------------+
| Warning | 1819 | cracklib: it is based on your username                         |
| Error	  | 1819 | Your password does not satisfy the current policy requirements |
+---------+------+----------------------------------------------------------------+

```

Strict password validation:

 
```
GRANT SELECT ON *.* TO foo IDENTIFIED BY PASSWORD '2222222222222222';
ERROR HY000: The MariaDB server is running with the --strict-password-validation option so it cannot execute this statement

```

Plugin API
----------

 Password validation plugin API is very simple. A plugin must implement only one method — `validate_password()`. This method takes two arguments — user name and the plain-text password. And it returns 0 when the password has passed the validation and 1 otherwise,

 See also `mysql/plugin_password_validation.h` and password validation plugins in `plugin/simple_password_check/` and `plugins/cracklib_password_check/`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/password-validation/>

Thread Pool
============

   [MariaDB 5.1](../what-is-mariadb-51/index) introduced a thread pool, while [MariaDB 5.5](../what-is-mariadb-55/index) introduced an improved version.

  

| Title | Description |
| --- | --- |
|  [Thread Pool in MariaDB](../thread-pool-in-mariadb/index) |  Thread pool introduced in MariaDB 5.5.  |
|  [Thread Groups in the Unix Implementation of the Thread Pool](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index) |  On Unix, the thread pool divides up client connections into independent sets of threads.  |
|  [Thread Pool System and Status Variables](../thread-pool-system-status-variables/index) |  System and status variables related to the MariaDB thread pool.  |
|  [Thread Pool in MariaDB 5.1 - 5.3](../thread-pool-in-mariadb-51-53/index) |  The old thread pool introduced in MariaDB 5.1  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-pool/>

SET TRANSACTION
===============

    Syntax
------

 
```
SET [GLOBAL | SESSION] TRANSACTION
    transaction_property [, transaction_property] ...

transaction_property:
    ISOLATION LEVEL level
  | READ WRITE
  | READ ONLY

level:
     REPEATABLE READ
   | READ COMMITTED
   | READ UNCOMMITTED
   | SERIALIZABLE

```
 Description
-----------

 This statement sets the transaction isolation level or the transaction access mode globally, for the current session, or for the next transaction:

 * With the `GLOBAL` keyword, the statement sets the default transaction level globally for all subsequent sessions. Existing sessions are unaffected.
* With the `SESSION` keyword, the statement sets the default transaction level for all subsequent transactions performed within the current session.
* Without any `SESSION` or `GLOBAL` keyword, the statement sets the isolation level for only the next (not started) transaction performed within the current session. After that it reverts to using the session value.

 A change to the global default isolation level requires the `[SUPER](../grant/index)` privilege. Any session is free to change its session isolation level (even in the middle of a transaction), or the isolation level for its next transaction.

 ### Isolation Level

 To set the global default isolation level at server startup, use the [--transaction-isolation=level](../server-system-variables/index#tx_isolation) option on the command line or in an option file. Values of level for this option use dashes rather than spaces, so the allowable values are [READ\_UNCOMMITTED](#read-uncommitted), [READ-COMMITTED](#read-committed), [REPEATABLE-READ](#repeatable-read), or [SERIALIZABLE](#serializable). For example, to set the default isolation level to `REPEATABLE READ`, use these lines in the [mariadb] section of an option file:

 
```
[mariadb]
transaction-isolation = REPEATABLE-READ
```

To determine the global and session transaction isolation levels at runtime, check the value of the [tx\_isolation](../server-system-variables/index#tx_isolation) system variable (note that the variable has been renamed [transaction\_isolation](../server-system-variables/index#transaction_isolation) from [MariaDB 11.1.1](https://mariadb.com/kb/en/mariadb-11-1-1-release-notes/), to match the option, and the old name deprecated).

 
```
SELECT @@GLOBAL.tx_isolation, @@tx_isolation;

```

From [MariaDB 11.1.1](https://mariadb.com/kb/en/mariadb-11-1-1-release-notes/):

 
```
SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;

```

InnoDB supports each of the translation isolation levels described here using different locking strategies. The default level is `REPEATABLE READ`. For additional information about InnoDB record-level locks and how it uses them to execute various types of statements, see [InnoDB Lock Modes](../innodb-lock-modes/index), and <http://dev.mysql.com/doc/refman/en/innodb-locks-set.html>.

 ### Isolation Levels

 The following sections describe how MariaDB supports the different transaction levels.

 #### READ UNCOMMITTED

 `SELECT` statements are performed in a non-locking fashion, but a possible earlier version of a row might be used. Thus, using this isolation level, such reads are not consistent. This is also called a "dirty read." Otherwise, this isolation level works like `READ COMMITTED`.

 #### READ COMMITTED

 A somewhat Oracle-like isolation level with respect to consistent (non-locking) reads: Each consistent read, even within the same transaction, sets and reads its own fresh snapshot. See <http://dev.mysql.com/doc/refman/en/innodb-consistent-read.html>.

 For locking reads (`SELECT` with `FOR UPDATE` or `LOCK IN SHARE MODE`), InnoDB locks only index records, not the gaps before them, and thus allows the free insertion of new records next to locked records. For `UPDATE` and `DELETE` statements, locking depends on whether the statement uses a unique index with a unique search condition (such as `WHERE id = 100`), or a range-type search condition (such as `WHERE id > 100`). For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For range-type searches, InnoDB locks the index range scanned, using gap locks or next-key (gap plus index-record) locks to block insertions by other sessions into the gaps covered by the range. This is necessary because "phantom rows" must be blocked for MariaDB replication and recovery to work.

 **Note:** If the `READ COMMITTED` isolation level is used or the [innodb\_locks\_unsafe\_for\_binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog) system variable is enabled, there is no InnoDB gap locking except for [foreign-key](../foreign-keys/index) constraint checking and duplicate-key checking. Also, record locks for non-matching rows are released after MariaDB has evaluated the `WHERE` condition.If you use `READ COMMITTED` or enable innodb\_locks\_unsafe\_for\_binlog, you must use row-based binary logging.

 #### REPEATABLE READ

 This is the default isolation level for InnoDB. For consistent reads, there is an important difference from the `READ COMMITTED` isolation level: All consistent reads within the same transaction read the snapshot established by the first read. This convention means that if you issue several plain (non-locking) `SELECT` statements within the same transaction, these `SELECT` statements are consistent also with respect to each other. See <http://dev.mysql.com/doc/refman/en/innodb-consistent-read.html>.

 For locking reads (SELECT with FOR UPDATE or LOCK IN SHARE MODE), UPDATE, and DELETE statements, locking depends on whether the statement uses a unique index with a unique search condition, or a range-type search condition. For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it. For other search conditions, InnoDB locks the index range scanned, using gap locks or next-key (gap plus index-record) locks to block insertions by other sessions into the gaps covered by the range.

 This is the minimum isolation level for non-distributed [XA transactions](../xa-transactions/index).

 #### SERIALIZABLE

 This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to [SELECT ... LOCK IN SHARE MODE](../select/index#lock-in-share-mode-and-for-update-clauses) if [autocommit](../server-system-variables/index#autocommit) is disabled. If autocommit is enabled, the SELECT is its own transaction. It therefore is known to be read only and can be serialized if performed as a consistent (non-locking) read and need not block for other transactions. (This means that to force a plain SELECT to block if other transactions have modified the selected rows, you should disable autocommit.)

 Distributed [XA transactions](../xa-transactions/index) should always use this isolation level.

 ### Access Mode

 The access mode specifies whether the transaction is allowed to write data or not. By default, transactions are in `READ WRITE` mode (see the [tx\_read\_only](../server-system-variables/index#tx_read_only) system variable). `READ ONLY` mode allows the storage engine to apply optimizations that cannot be used for transactions which write data. Note that unlike the global [read\_only](../server-system-variables/index#read_only) mode, [READ\_ONLY ADMIN](../grant/index#read_only-admin) (and [SUPER](../grant/index#super) before [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/)) privilege doesn't allow writes and DDL statements on temporary tables are not allowed either.

 It is not permitted to specify both `READ WRITE` and `READ ONLY` in the same statement.

 `READ WRITE` and `READ ONLY` can also be specified in the [START TRANSACTION](../start-transaction/index) statement, in which case the specified mode is only valid for one transaction.

 Examples
--------

 
```
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

```

Attempting to set the isolation level within an existing transaction without specifying `GLOBAL` or `SESSION`.

 
```
START TRANSACTION;

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
ERROR 1568 (25001): Transaction characteristics can't be changed while a transaction is in progress

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-transaction/>

Engine-Independent Table Statistics
===================================

    
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**The engine-independent table statistics feature was first implemented in [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) and was first enabled for queries by default in [MariaDB 10.4](../what-is-mariadb-104/index).

  Introduction
------------

 Before [MariaDB 10.0](../what-is-mariadb-100/index), the MySQL/MariaDB optimizer relied on storage engines (e.g. InnoDB) to provide statistics for the query optimizer. This approach worked; however it had some deficiencies:

 * Storage engines provided poor statistics (this was fixed to some degree with the introduction of [Persistent Statistics](../innodb-persistent-statistics/index)).
* The statistics were supplied through the MySQL Storage Engine Interface, which puts a lot of restrictions on what kind of data is supplied (for example, there is no way to get any data about value distribution in a non-indexed column)
* There was little control of the statistics. There was no way to "pin" current statistic values, or provide some values on your own, etc.

 Engine-independent table statistics lift these limitations. 

 * Statistics are stored in regular tables in the `mysql` database.
	+ it is possible for a DBA to read and update the values.
* More data is collected/used.

 Statistics are stored in three tables, [mysql.table\_stats](../mysqltable_stats-table/index), [mysql.column\_stats](../mysqlcolumn_stats-table/index) and [mysql.index\_stats](../mysqlindex_stats-table/index).

 Use or update of data from these tables is controlled by [use\_stat\_tables](../server-system-variables/index#use_stat_tables) variable. Possible values are listed below:

 


| Value | Meaning |
| --- | --- |
| 'never' | The optimizer doesn't use data from statistics tables. Default for [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) and below. |
| 'complementary' | The optimizer uses data from statistics tables if the same kind of data is not provided by the storage engine. |
| 'preferably' | Prefer the data from statistics tables, if it's not available there, use the data from the storage engine. |
| 'complementary\_for\_queries' | Same as `complementary`, but for queries only (to avoid needlessly collecting for [ANALYZE TABLE](../analyze-table/index)). From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/). |
| 'preferably\_for\_queries' | Same as `preferably`, but for queries only (to avoid needlessly collecting for [ANALYZE TABLE](../analyze-table/index)). Available and default from [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/). |

 
Collecting Statistics with the ANALYZE TABLE Statement
------------------------------------------------------

 The [ANALYZE TABLE](../analyze-table/index) statement can be used to collect table statistics. For example:

 
```
ANALYZE TABLE table_name;

```

When the [ANALYZE TABLE](../analyze-table/index) statement is executed, MariaDB makes a call to the table's storage engine, and the storage engine collects its own statistics for the table. The specific behavior depends on the storage engine. For [InnoDB](../innodb/index), see [InnoDB Persistent Statistics](../innodb-persistent-statistics/index) for more information.

 When the [ANALYZE TABLE](../analyze-table/index) statement is executed, MariaDB may also collect engine-independent statistics for the table. The specific behavior depends on the value of the [use\_stat\_tables](../server-system-variables/index#use_stat_tables) system variable. Engine-independent statistics will only be collected by the [ANALYZE TABLE](../analyze-table/index) statement if one of the following is true:

 * The [use\_stat\_tables](../server-system-variables/index#use_stat_tables) system variable is set to `complementary` or `preferably`.
* The [ANALYZE TABLE](../analyze-table/index) statement includes the `PERSISTENT FOR` clause.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the [use\_stat\_tables](../server-system-variables/index#use_stat_tables) system variable is set to `preferably_for_queries` by default. With this value, engine-independent statistics are used by default, but they are not collected by default. If you want to use engine-independent statistics with the default configuration, then you will have to collect them by executing the [ANALYZE TABLE](../analyze-table/index) statement and by specifying the `PERSISTENT FOR` clause. It is recommended to collect engine-independent statistics on as-needed basis, so typically one will not have engine-independent statistics for all indexes/all columns. 

 

Engine-independent statistics are collected by doing full table and full index scans, and this process can be quite expensive.

 
### Collecting Statistics for Specific Columns or Indexes

 The syntax for the [ANALYZE TABLE](../analyze-table/index) statement has been extended with the `PERSISTENT FOR` clause. This clause allows one to collect engine-independent statistics only for particular columns or indexes. This clause also allows one to collect engine-independent statistics, regardless of the value of the [use\_stat\_tables](../server-system-variables/index#use_stat_tables) system variable. For example:

 
```
ANALYZE TABLE table_name PERSISTENT FOR ALL;

```


Statistics for columns using the [BLOB](../blob/index) and [TEXT](../text/index) data types are not collected. If a column using one of these types is explicitly specified, then a warning is returned.

 
### Examples of Statistics Collection

 
```
-- update all engine-independent statistics for all columns and indexes
ANALYZE TABLE tbl PERSISTENT FOR ALL;

-- update specific columns and indexes:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES (idx1,idx2,...);

-- empty lists are allowed:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS (col1,col2,...) INDEXES ();
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES (idx1,idx2,...);

-- the following will only update mysql.table_stats fields:
ANALYZE TABLE tbl PERSISTENT FOR COLUMNS () INDEXES ();

-- when use_stat_tables is set to 'COMPLEMENTARY' or 'PREFERABLY', 
-- a simple ANALYZE TABLE  collects engine-independent statistics for all columns and indexes.
SET SESSION use_stat_tables='COMPLEMENTARY';
ANALYZE TABLE tbl;

```

Manual Updates to Statistics Tables
-----------------------------------

 Statistics are stored in three tables, [mysql.table\_stats](../mysqltable_stats-table/index), [mysql.column\_stats](../mysqlcolumn_stats-table/index) and [mysql.index\_stats](../mysqlindex_stats-table/index).

 It is possible to update statistics tables manually. One should modify the table(s) with regular [INSERT](../insert/index)/[UPDATE](../update/index)/[DELETE](../delete/index) statements. Statistics data will be re-read when the tables are re-opened. One way to force all tables to be re-opened is to issue [FLUSH TABLES](../flush/index) command.

 A few scenarios where one might need to update statistics tables manually:

 * Deleting the statistics. Currently, the [ANALYZE TABLE](../analyze-table/index) command will collect the statistics, but there is no special command to delete statistics.
* Running ANALYZE on a different server. ANALYZE TABLE does a full table scan, which can put too much load on the server. It is possible to run ANALYZE on the slave, and then take the data from statistics tables on the slave and apply it on the master.
* In some cases, knowledge of the database allows one to compute statistics manually in a more efficient way than ANALYZE does. One can compute the statistics manually and put it into the database.

 See Also
--------

 * [Index Statistics](../index-statistics/index)
* [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [Histogram-based Statistics](../histogram-based-statistics/index)
* [JSON histograms](https://mariadb.org/10-7-preview-feature-json-histograms/) (mariadb.org blog)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/engine-independent-table-statistics/>

DECODE\_ORACLE
==============

    
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**`DECODE_ORACLE` is a synonym for the [Oracle mode](../sql_modeoracle/index) version of the [DECODE function](../decode/index), and is available in all modes.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/decode_oracle/>

TRUE FALSE
==========

    Description
-----------

 The constants TRUE and FALSE evaluate to 1 and 0, respectively. The constant names can be written in any lettercase.

 Examples
--------

 
```
SELECT TRUE, true, FALSE, false;
+------+------+-------+-------+
| TRUE | TRUE | FALSE | FALSE |
+------+------+-------+-------+
|    1 |    1 |     0 |     0 |
+------+------+-------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/true-false/>

PROCEDURE ANALYSE
=================

    Syntax
------

 
```
analyse([max_elements[,max_memory]])

```

Description
-----------

 This procedure is defined in the sql/sql\_analyse.cc file. It examines the result from a query and returns an analysis of the results that suggests optimal data types for each column. To obtain this analysis, append PROCEDURE ANALYSE to the end of a [SELECT](../select/index) statement:

 
```
SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max_elements,[max_memory]])

```

For example:

 
```
SELECT col1, col2 FROM table1 PROCEDURE ANALYSE(10, 2000);

```

The results show some statistics for the values returned by the query, and propose an optimal data type for the columns. This can be helpful for checking your existing tables, or after importing new data. You may need to try different settings for the arguments so that PROCEDURE ANALYSE() does not suggest the ENUM data type when it is not appropriate.

 The arguments are optional and are used as follows:

 * max\_elements (default 256) is the maximum number of distinct values that analyse notices per column. This is used by analyse to check whether the optimal data type should be of type ENUM; if there are more than max\_elements distinct values, then ENUM is not a suggested type.
* max\_memory (default 8192) is the maximum amount of memory that analyse should allocate per column while trying to find all distinct values.

 See Also
--------

 * [PROCEDURE](../procedure/index)
* [SELECT](../select/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/procedure-analyse/>

Parentheses
===========

    Parentheses are sometimes called precedence operators - this means that they can be used to change the other [operator's precedence](../operator-precedence/index) in an expression. The expressions that are written between parentheses are computed before the expressions that are written outside. Parentheses must always contain an expression (that is, they cannot be empty), and can be nested.

 For example, the following expressions could return different results:

 * `NOT a OR b`
* `NOT (a OR b)`

 In the first case, `NOT` applies to `a`, so if `a` is `FALSE` or `b` is `TRUE`, the expression returns `TRUE`. In the second case, `NOT` applies to the result of `a OR b`, so if at least one of `a` or `b` is `TRUE`, the expression is `TRUE`.

 When the precedence of operators is not intuitive, you can use parentheses to make it immediately clear for whoever reads the statement.

 The precedence of the `NOT` operator can also be affected by the `HIGH_NOT_PRECEDENCE` [SQL\_MODE](../sql-mode/index) flag.

 Other uses
----------

 Parentheses must always be used to enclose [subqueries](../subqueries/index).

 Parentheses can also be used in a `[JOIN](../join/index)` statement between multiple tables to determine which tables must be joined first.

 Also, parentheses are used to enclose the list of parameters to be passed to built-in functions, user-defined functions and stored routines. However, when no parameter is passed to a stored procedure, parentheses are optional. For builtin functions and user-defined functions, spaces are not allowed between the function name and the open parenthesis, unless the `IGNORE_SPACE` [SQL\_MODE](../sql-mode/index) is set. For stored routines (and for functions if `IGNORE_SPACE` is set) spaces are allowed before the open parenthesis, including tab characters and new line characters.

 Syntax errors
-------------

 If there are more open parentheses than closed parentheses, the error usually looks like this:

 
```
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near '' a
t line 1

```

Note the empty string.

 If there are more closed parentheses than open parentheses, the error usually looks like this:

 
```
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use near ')'
at line 1

```

Note the quoted closed parenthesis.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/parentheses/>

Geometry Constructors
======================

   Geometry constructors

  

| Title | Description |
| --- | --- |
|  [BUFFER](../buffer/index) |  Synonym for ST\_BUFFER.  |
|  [CONVEXHULL](../convexhull/index) |  Synonym for ST\_CONVEXHULL.  |
|  [GEOMETRYCOLLECTION](../geometrycollection/index) |  Constructs a WKB GeometryCollection.  |
|  [LINESTRING](../linestring/index) |  Constructs a WKB LineString value from a number of WKB Point arguments.  |
|  [MULTILINESTRING](../multilinestring/index) |  Constructs a MultiLineString value.  |
|  [MULTIPOINT](../multipoint/index) |  Constructs a WKB MultiPoint value.  |
|  [MULTIPOLYGON](../multipolygon/index) |  Constructs a WKB MultiPolygon.  |
|  [POINT](../point/index) |  Constructs a WKB Point.  |
|  [PointOnSurface](../pointonsurface/index) |  Synonym for ST\_PointOnSurface.  |
|  [POLYGON](../polygon/index) |  Constructs a WKB Polygon value from a number of WKB LineString arguments.  |
|  [ST\_BUFFER](../st_buffer/index) |  A new geometry with a buffer added to the original geometry.  |
|  [ST\_CONVEXHULL](../st_convexhull/index) |  The minimum convex geometry enclosing all geometries within the set.  |
|  [ST\_INTERSECTION](../st_intersection/index) |  The intersection, or shared portion, of two geometries.  |
|  [ST\_POINTONSURFACE](../st_pointonsurface/index) |  Returns a POINT guaranteed to intersect a surface.  |
|  [ST\_SYMDIFFERENCE](../st_symdifference/index) |  Portions of two geometries that don't intersect.  |
|  [ST\_UNION](../st_union/index) |  Union of two geometries.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-constructors/>

NVL2
====

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**The NLV2 function was introduced in [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/).

 
Syntax
------

 
```
NVL2(expr1,expr2,expr3)

```
 Description
-----------

 The `NVL2` function returns a value based on whether a specified expression is NULL or not. If *expr1* is not NULL, then NVL2 returns *expr2*. If *expr1* is NULL, then NVL2 returns *expr3*.

 Examples
--------

 
```
SELECT NVL2(NULL,1,2);
+----------------+
| NVL2(NULL,1,2) |
+----------------+
|              2 |
+----------------+

SELECT NVL2('x',1,2);
+---------------+
| NVL2('x',1,2) |
+---------------+
|             1 |
+---------------+

```

See Also
--------

 * [IFNULL (or NVL)](../ifnull/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nvl2/>

\_rowid
=======

    Syntax
------

 \_rowid

 Description
-----------

 The `_rowid` pseudo column is mapped to the primary key in the related table. This can be used as a replacement of the `rowid` pseudo column in other databases. Another usage is to simplify sql queries as one doesn't have to know the name of the primary key.

 Examples
--------

 
```
create table t1 (a int primary key, b varchar(80));
insert into t1 values (1,"one"),(2,"two");
select * from t1 where _rowid=1;

```


```
+---+------+
| a | b    |
+---+------+
| 1 | one  |
+---+------+

```


```
update t1 set b="three" where _rowid=2;
select * from t1 where _rowid>=1 and _rowid<=10;

```


```
+---+-------+
| a | b     |
+---+-------+
| 1 | one   |
| 2 | three |
+---+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/_rowid/>

Optimizer Trace Overview
========================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Optimizer Trace was introduced in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

  Usage
-----

 This feature produces a trace as a JSON document for any [SELECT](../select/index)/[UPDATE](../update/index)/[DELETE](../delete/index) containing information about decisions taken by the optimizer during the optimization phase (choice of table access method, various costs, transformations, etc). This feature helps to explain why some decisions were taken by the optimizer and why some were rejected.

 Associated System Variables
---------------------------

 * [optimizer\_trace=’enabled=on/off’](../server-system-variables/index#optimizer_trace)
	+ Default value is off
* [optimizer\_trace\_max\_mem\_size](../server-system-variables/index#optimizer_trace_max_mem_size)= value
	+ Default value: 1048576

 INFORMATION\_SCHEMA.OPTIMIZER\_TRACE
------------------------------------

 Each connection stores a trace from the last executed statement. One can view the trace by reading the [Information Schema OPTIMIZER\_TRACE table](../information-schema-optimizer_trace-table/index).

 Structure of the optimizer trace table:

 
```
SHOW CREATE TABLE INFORMATION_SCHEMA.OPTIMIZER_TRACE \G
*************************** 1. row ***************************
       Table: OPTIMIZER_TRACE
Create Table: CREATE TEMPORARY TABLE `OPTIMIZER_TRACE` (
  `QUERY` longtext NOT NULL DEFAULT '',
  `TRACE` longtext NOT NULL DEFAULT '',
  `MISSING_BYTES_BEYOND_MAX_MEM_SIZE` int(20) NOT NULL DEFAULT 0,
  `INSUFFICIENT_PRIVILEGES` tinyint(1) NOT NULL DEFAULT 0
) ENGINE=Aria DEFAULT CHARSET=utf8 PAGE_CHECKSUM=0

```

Optimizer Trace Contents
------------------------

 See [Optimizer Trace Guide](../optimizer-trace-guide/index) for an overview of what one can find in the trace.

 Traceable Queries
-----------------

 These include [SELECT](../select/index), [UPDATE](../update/index), [DELETE](../delete/index) as well as their multi-table variants and all of the preceding prefixed by [EXPLAIN](../explain/index) and [ANALYZE](../analyze-statement/index).

 Enabling Optimizer Trace
------------------------

 To enable optimizer trace run:

 
```
SET optimizer_trace='enabled=on';

```

Memory Usage
------------

 Each trace is stored as a string. It is extended (with realloc()) as the optimization progresses and appends data to it. The [optimizer\_trace\_max\_mem\_size](../server-system-variables/index#optimizer_trace_max_mem_size) variable sets a limit on the total amount of memory used by the current trace. If this limit is reached, the current trace isn't extended (so it will be incomplete), and the MISSING\_BYTES\_BEYOND\_MAX\_MEM\_SIZE column will show the number of bytes missing from this trace.

 Privilege Checking
------------------

 In complex scenarios where the query uses SQL SECURITY DEFINER views or stored routines, it may be that a user is denied from seeing the trace of its query because it lacks some extra privileges on those objects. In that case, the trace will be shown as empty and the INSUFFICIENT\_PRIVILEGES column will show "1".

 Limitations
-----------

 Currently, only one trace is stored. It is not possible to trace the sub-statements of a stored routine; only the statement at the top level is traced.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-trace/>

Geometry Relations
===================

   Geometry relations

  

| Title | Description |
| --- | --- |
|  [CONTAINS](../contains/index) |  Whether one geometry contains another.  |
|  [CROSSES](../crosses/index) |  Whether two geometries spatially cross  |
|  [DISJOINT](../disjoint/index) |  Whether the two elements do not intersect.  |
|  [EQUALS](../equals/index) |  Indicates whether two geometries are spatially equal.  |
|  [INTERSECTS](../intersects/index) |  Indicates whether two geometries spatially intersect.  |
|  [OVERLAPS](../overlaps/index) |  Indicates whether two elements spatially overlap.  |
|  [ST\_CONTAINS](../st-contains/index) |  Whether one geometry is contained by another.  |
|  [ST\_CROSSES](../st-crosses/index) |  Whether two geometries spatially cross.  |
|  [ST\_DIFFERENCE](../st_difference/index) |  Point set difference.  |
|  [ST\_DISJOINT](../st_disjoint/index) |  Whether one geometry is spatially disjoint from another.  |
|  [ST\_DISTANCE](../st_distance/index) |  The distance between two geometries.  |
|  [ST\_DISTANCE\_SPHERE](../st_distance_sphere/index) |  Spherical distance between two geometries (point or multipoint) on a sphere.  |
|  [ST\_EQUALS](../st-equals/index) |  Whether two geometries are spatoially equal.  |
|  [ST\_INTERSECTS](../st-intersects/index) |  Whether two geometries spatially intersect.  |
|  [ST\_LENGTH](../st_length/index) |  Length of a LineString value.  |
|  [ST\_OVERLAPS](../st-overlaps/index) |  Whether two geometries overlap.  |
|  [ST\_TOUCHES](../st-touches/index) |  Whether one geometry g1 spatially touches another.  |
|  [ST\_WITHIN](../st-within/index) |  Whether one geometry is within another.  |
|  [TOUCHES](../touches/index) |  Whether two geometries spatially touch.  |
|  [WITHIN](../within/index) |  Indicate whether a geographic element is spacially within another.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-relations/>

RANDOM\_BYTES
=============

    
**MariaDB starting with [10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/)**The RANDOM\_BYTES function generates a binary string of random bytes. It was added in [MariaDB 10.10.0](https://mariadb.com/kb/en/mariadb-10100-release-notes/).

 
Syntax
------

 
```
RANDOM_BYTES(length)

```

Description
-----------

 Given a *length* from 1 to 1024, generates a binary string of *length* consisting of random bytes generated by the SSL library's random number generator.

 See the RAND\_bytes() function documentation of your SSL library for information on the random number generator. In the case of [OpenSSL](https://www.openssl.org/docs/man1.1.1/man3/RAND_bytes.html), a cryptographically secure pseudo random generator (CSPRNG) is used.

 Statements containing the RANDOM\_BYTES function are [unsafe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 An error occurs if *length* is outside the range 1 to 1024.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/random_bytes/>

Operator Precedence
===================

    The precedence is the order in which the SQL operators are evaluated.

 The following list shows the SQL operator precedence. Operators that appear first in the list have a higher precedence. Operators which are listed together have the same precedence.

 * `[INTERVAL](../date-and-time-units/index)`
* `[BINARY](../binary-operator/index)`, `[COLLATE](../setting-character-sets-and-collations/index#literals)`
* `[!](../not/index)`
* `[-](../subtraction-operator-/index)` (unary minus), [[bitwise-not|]] (unary bit inversion)
* `||` (string concatenation)
* `[^](../bitwise-xor/index)`
* `[\*](../multiplication-operator/index)`, `[/](../division-operator/index)`, `[DIV](../div/index)`, `[%](../modulo-operator/index)`, `[MOD](../mod/index)`
* `[-](../subtraction-operator-/index)`, `[+](../addition-operator/index)`
* `[<<](../shift-left/index)`, `[>>](../shift-right/index)`
* `[&](bitwise-and)`
* `[|](../bitwise-or/index)`
* `[=](../equal/index)` (comparison), `[<=>](../null-safe-equal/index)`, `[>=](../greater-than-or-equal/index)`, `[>](../greater-than/index)`, `[<=](../less-than-or-equal/index)`, `[<](../less-than/index)`, `[<>](../not-equal/index)`, `[!=](../not-equal/index)`, `[IS](../is/index)`, `[LIKE](../like/index)`, `[REGEXP](../regexp/index)`, `[IN](../in/index)`
* `[BETWEEN](../between-and/index)`, [`CASE`, `WHEN`, `THEN`, `ELSE`, `END`](../case-operator/index)
* `[NOT](../not/index)`
* `[&&](../and/index)`, `[AND](../and/index)`
* `[XOR](../xor/index)`
* `[||](../or/index)` (logical or), `[OR](../or/index)`
* `[=](../assignment-operators-assignment-operator/index)` (assignment), `[:=](../assignment-operator/index)`

 Functions precedence is always higher than operators precedence.

 In this page `CASE` refers to the [CASE operator](../case-operator/index), not to the [CASE statement](../case-statement/index)`.`

 If the `HIGH_NOT_PRECEDENCE` [SQL\_MODE](../sql-mode/index) is set, `NOT` has the same precedence as `!`.

 The `||` operator's precedence, as well as its meaning, depends on the `PIPES_AS_CONCAT` [SQL\_MODE](../sql-mode/index) flag: if it is on, `||` can be used to concatenate strings (like the [CONCAT()](../concat/index) function) and has a higher precedence.

 The `=` operator's precedence depends on the context - it is higher when `=` is used as a comparison operator.

 [Parenthesis](../parenthesis/index) can be used to modify the operators precedence in an expression.

 Short-circuit evaluation
------------------------

 The `AND`, `OR`, `&&` and `||` operators support short-circuit evaluation. This means that, in some cases, the expression on the right of those operators is not evaluated, because its result cannot affect the result. In the following cases, short-circuit evaluation is used and `x()` is not evaluated:

 * `FALSE AND x()`
* `FALSE && x()`
* `TRUE OR x()`
* `TRUE || x()`
* `NULL BETWEEN x() AND x()`

 Note however that the short-circuit evaluation does *not* apply to `NULL AND x()`. Also, `BETWEEN`'s right operands are not evaluated if the left operand is `NULL`, but in all other cases all the operands are evaluated.

 This is a speed optimization. Also, since functions can have side-effects, this behavior can be used to choose whether execute them or not using a concise syntax:

 
```
SELECT some_function() OR log_error();

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/operator-precedence/>

ROWNUM
======

    
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), the `ROWNUM()` function is supported.

  Syntax
------

 
```
ROWNUM()

```

In [Oracle mode](../sql_modeoracle/index) one can just use `ROWNUM`, without the parentheses.

 Description
-----------

 `ROWNUM()` returns the current number of accepted rows in the current context. It main purpose is to emulate the `ROWNUM` [pseudo column in Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/ROWNUM-Pseudocolumn.html#GUID-2E40EC12-3FCF-4A4F-B5F2-6BC669021726). For MariaDB native applications, we recommend the usage of [LIMIT](../limit/index), as it is easier to use and gives more predictable results than the usage of `ROWNUM()`.

 The main difference between using `LIMIT` and `ROWNUM()` to limit the rows in the result is that `LIMIT` works on the result set while `ROWNUM` works on the number of accepted rows (before any `ORDER` or `GROUP BY` clauses).

 The following queries will return the same results:

 
```
SELECT * from t1 LIMIT 10;
SELECT * from t1 WHERE ROWNUM() <= 10;

```

While the following may return different results based on in which orders the rows are found:

 
```
SELECT * from t1 ORDER BY a LIMIT 10;
SELECT * from t1 ORDER BY a WHERE ROWNUM() <= 10;

```

The recommended way to use `ROWNUM` to limit the number of returned rows and get predictable results is to have the query in a subquery and test for `ROWNUM()` in the outer query:

 
```
SELECT * FROM (select * from t1 ORDER BY a) WHERE ROWNUM() <= 10;

```

`ROWNUM()` can be used in the following contexts:

 * [SELECT](../select/index)
* [INSERT](../insert/index)
* [UPDATE](../update/index)
* [DELETE](../delete/index)
* [LOAD DATA INFILE](../load-data-infile/index)

 Used in other contexts, `ROWNUM()` will return 0.

 Examples
--------

 
```
INSERT INTO t1 VALUES (1,ROWNUM()),(2,ROWNUM()),(3,ROWNUM());

INSERT INTO t1 VALUES (1),(2) returning a, ROWNUM();

UPDATE t1 SET row_num_column=ROWNUM();

DELETE FROM t1 WHERE a < 10 AND ROWNUM() < 2;

LOAD DATA INFILE 'filename' into table t1 fields terminated by ',' 
  lines terminated by "\r\n" (a,b) set c=ROWNUM();

```

Optimizations
-------------

 In many cases where `ROWNUM()` is used, MariaDB will use the same optimizations it uses with [LIMIT](../limit/index).

 `LIMIT` optimization is possible when using `ROWNUM` in the following manner:

 * When one is in a top level `WHERE` clause comparing `ROWNUM()` with a numerical constant using any of the following expressions:
	+ `ROWNUM()` < number
	+ `ROWNUM()` <= number
	+ `ROWNUM()` = 1 `ROWNUM()` can be also be the right argument to the comparison function.

 In the above cases, `LIMIT` optimization can be done in the following cases:

 * For the current sub query when the ROWNUM comparison is done on the top level:

 
```
SELECT * from t1 WHERE ROWNUM() <= 2 AND t1.a > 0

```

* For an inner sub query, when the upper level has only a `ROWNUM()` comparison in the `WHERE` clause:

 
```
SELECT * from (select * from t1) as t WHERE ROWNUM() <= 2

```

Other Changes Related to ROWNUM
-------------------------------

 When `ROWNUM()` is used anywhere in a query, the optimization to ignore `ORDER BY` in subqueries are disabled.

 This was done to get the following common Oracle query to work as expected:

 
```
 select * from (select * from t1 order by a desc) as t where rownum() <= 2;

```

By default MariaDB ignores any `ORDER BY` in subqueries both because the SQL standard defines results sets in subqueries to be un-ordered and because of performance reasons (especially when using views in subqueries). See [MDEV-3926](https://jira.mariadb.org/browse/MDEV-3926) "Wrong result with GROUP BY ... WITH ROLLUP" for a discussion of this topic.

 Other Considerations
--------------------

 While MariaDB tries to emulate Oracle's usage of `ROWNUM()` as closely as possible, there are cases where the result is different:

 * When the optimizer finds rows in a different order (because of different storage methods or optimization). This may also happen in Oracle if one adds or deletes an index, in which case the rows may be found in a different order.

 Note that usage of `ROWNUM()` in functions or [stored procedures](../stored-procedures/index) will use their own context, not the caller's context.

 See Also
--------

 * [MDEV-24089](https://jira.mariadb.org/browse/MDEV-24089) support oracle syntax: rownum
* [LIMIT clause](../limit/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rownum/>

LineString Properties
======================

   LineString properties

  

| Title | Description |
| --- | --- |
|  [ENDPOINT](../linestring-properties-endpoint/index) |  Synonym for ST\_ENDPOINT.  |
|  [GLENGTH](../glength/index) |  Length of a LineString value.  |
|  [NumPoints](../linestring-properties-numpoints/index) |  Synonym for ST\_NumPoints.  |
|  [PointN](../linestring-properties-pointn/index) |  Synonym for PointN.  |
|  [STARTPOINT](../linestring-properties-startpoint/index) |  Synonym for ST\_StartPoint.  |
|  [ST\_ENDPOINT](../st_endpoint/index) |  Returns the endpoint of a LineString.  |
|  [ST\_NUMPOINTS](../st_numpoints/index) |  Returns the number of Point objects in a LineString.  |
|  [ST\_POINTN](../st_pointn/index) |  Returns the N-th Point in the LineString.  |
|  [ST\_STARTPOINT](../st_startpoint/index) |  Returns the start point of a LineString  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring-properties/>

NVL
===

    
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**From [MariaDB 10.3](../what-is-mariadb-103/index), NVL is a synonym for [IFNULL](../ifnull/index).

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nvl/>

Geometry Properties
====================

   Geometry properties

  

| Title | Description |
| --- | --- |
|  [BOUNDARY](../geometry-properties-boundary/index) |  Synonym for ST\_BOUNDARY.  |
|  [DIMENSION](../dimension/index) |  Synonym for ST\_DIMENSION.  |
|  [ENVELOPE](../geometry-properties-envelope/index) |  Synonym for ST\_ENVELOPE.  |
|  [GeometryN](../geometry-properties-geometryn/index) |  Synonym for ST\_GeometryN.  |
|  [GeometryType](../geometry-properties-geometrytype/index) |  Synonym for ST\_GeometryType.  |
|  [IsClosed](../isclosed/index) |  Synonym for ST\_IsClosed.  |
|  [IsEmpty](../geometry-properties-isempty/index) |  Synonym for ST\_IsEmpty.  |
|  [IsRing](../isring/index) |  Synonym for ST\_IsRing.  |
|  [IsSimple](../geometry-properties-issimple/index) |  Synonym for ST\_IsSimple.  |
|  [NumGeometries](../geometry-properties-numgeometries/index) |  Synonym for ST\_NumGeometries.  |
|  [SRID](../geometry-properties-srid/index) |  Synonym for ST\_SRID.  |
|  [ST\_BOUNDARY](../st_boundary/index) |  Returns a geometry that is the closure of a combinatorial boundary.  |
|  [ST\_DIMENSION](../st_dimension/index) |  Inherent dimension of a geometry value.  |
|  [ST\_ENVELOPE](../st_envelope/index) |  Returns the Minimum Bounding Rectangle for a geometry value.  |
|  [ST\_GEOMETRYN](../st_geometryn/index) |  Returns the N-th geometry in a GeometryCollection.  |
|  [ST\_GEOMETRYTYPE](../st_geometrytype/index) |  Returns name of the geometry type of which a given geometry instance is a member.  |
|  [ST\_ISCLOSED](../st_isclosed/index) |  Returns true if a given LINESTRING's start and end points are the same.  |
|  [ST\_ISEMPTY](../st_isempty/index) |  Indicated validity of geometry value.  |
|  [ST\_IsRing](../st_isring/index) |  Returns true if a given LINESTRING is both ST\_IsClosed and ST\_IsSimple.  |
|  [ST\_IsSimple](../st_issimple/index) |  Returns true if the given Geometry has no anomalous geometric points.  |
|  [ST\_NUMGEOMETRIES](../st_numgeometries/index) |  Number of geometries in a GeometryCollection.  |
|  [ST\_RELATE](../st_relate/index) |  Returns true if two geometries are related  |
|  [ST\_SRID](../st_srid/index) |  Returns a Spatial Reference System ID.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties/>

Point Properties
=================

   Point properties

  

| Title | Description |
| --- | --- |
|  [ST\_X](../st_x/index) |  X-coordinate value for a point.  |
|  [ST\_Y](../st_y/index) |  Y-coordinate for a point.  |
|  [X](../point-properties-x/index) |  Synonym for ST\_X.  |
|  [Y](../point-properties-y/index) |  Synonym for ST\_Y.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/point-properties/>

Polygon Properties
===================

   Polygon properties

  

| Title | Description |
| --- | --- |
|  [AREA](../polygon-properties-area/index) |  Synonym for ST\_AREA.  |
|  [CENTROID](../centroid/index) |  Synonym for ST\_CENTROID.  |
|  [ExteriorRing](../polygon-properties-exteriorring/index) |  Synonym for ST\_ExteriorRing.  |
|  [InteriorRingN](../polygon-properties-interiorringn/index) |  Synonym for ST\_InteriorRingN.  |
|  [NumInteriorRings](../polygon-properties-numinteriorrings/index) |  Synonym for NumInteriorRings.  |
|  [ST\_AREA](../st_area/index) |  Area of a Polygon.  |
|  [ST\_CENTROID](../st_centroid/index) |  The mathematical centroid (geometric center) for a MultiPolygon.  |
|  [ST\_ExteriorRing](../st_exteriorring/index) |  Returns the exterior ring of a Polygon as a LineString.  |
|  [ST\_InteriorRingN](../st_interiorringn/index) |  Returns the N-th interior ring for a Polygon.  |
|  [ST\_NumInteriorRings](../st_numinteriorrings/index) |  Number of interior rings in a Polygon.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon-properties/>

Dynamic Columns
===============

       
  
 Dynamic columns allow one to store different sets of columns for each row in a table. It works by storing a set of columns in a blob and having a small set of functions to manipulate it.   
  
 Dynamic columns should be used when it is not possible to use regular columns.   
  
 A typical use case is when one needs to store items that may have many different attributes (like size, color, weight, etc), and the set of possible attributes is very large and/or unknown in advance. In that case, attributes can be put into dynamic columns.   
  


 Dynamic Columns Basics
----------------------

   
  
 The table should have a blob column which will be used as storage for dynamic columns:

 
```
create table assets (
  item_name varchar(32) primary key, -- A common attribute for all items
  dynamic_cols  blob  -- Dynamic columns will be stored here
);

```

Once created, one can access dynamic columns via dynamic column functions:

 Insert a row with two dynamic columns: color=blue, size=XL

 
```
INSERT INTO assets VALUES 
  ('MariaDB T-shirt', COLUMN_CREATE('color', 'blue', 'size', 'XL'));

```

Insert another row with dynamic columns: color=black, price=500

 
```
INSERT INTO assets VALUES
  ('Thinkpad Laptop', COLUMN_CREATE('color', 'black', 'price', 500));

```

Select dynamic column 'color' for all items:

 
```
SELECT item_name, COLUMN_GET(dynamic_cols, 'color' as char) 
  AS color FROM assets;
+-----------------+-------+
| item_name       | color |
+-----------------+-------+
| MariaDB T-shirt | blue  |
| Thinkpad Laptop | black |
+-----------------+-------+

```

It is possible to add and remove dynamic columns from a row:

 
```
-- Remove a column:
UPDATE assets SET dynamic_cols=COLUMN_DELETE(dynamic_cols, "price") 
WHERE COLUMN_GET(dynamic_cols, 'color' as char)='black'; 

-- Add a column:
UPDATE assets SET dynamic_cols=COLUMN_ADD(dynamic_cols, 'warranty', '3 years')
WHERE item_name='Thinkpad Laptop';

```

You can also list all columns, or get them together with their values in JSON format:

 
```
SELECT item_name, column_list(dynamic_cols) FROM assets;
+-----------------+---------------------------+
| item_name       | column_list(dynamic_cols) |
+-----------------+---------------------------+
| MariaDB T-shirt | `size`,`color`            |
| Thinkpad Laptop | `color`,`warranty`        |
+-----------------+---------------------------+

SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

```

Dynamic Columns Reference
-------------------------

 The rest of this page is a complete reference of dynamic columns in MariaDB

 ### Dynamic Columns Functions

 #### COLUMN\_CREATE

 
```
COLUMN_CREATE(column_nr, value [as type], [column_nr, value 
  [as type]]...);
COLUMN_CREATE(column_name, value [as type], [column_name, value 
  [as type]]...);

```


 Return a dynamic columns blob that stores the specified columns with values.

  
 The return value is suitable for 

  * + storing in a table
	+ further modification with other dynamic columns functions

 
 The **`as type`** part allows one to specify the value type. In most cases, this is redundant because MariaDB will be able to deduce the type of the value. Explicit type specification may be needed when the type of the value is not apparent. For example, a literal `'2012-12-01'` has a CHAR type by default, one will need to specify `'2012-12-01' AS DATE` to have it stored as a date. See the [Datatypes](#Datatypes) section for further details. Note also [MDEV-597](https://jira.mariadb.org/browse/MDEV-597).

  
 Typical usage:

  
```
-- MariaDB 5.3+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE(1 /*column id*/, "value");
-- MariaDB 10.0.1+:
INSERT INTO tbl SET dyncol_blob=COLUMN_CREATE("column_name", "value");

```

#### COLUMN\_ADD

 
```
COLUMN_ADD(dyncol_blob, column_nr, value [as type], 
  [column_nr, value [as type]]...);
COLUMN_ADD(dyncol_blob, column_name, value [as type], 
  [column_name, value [as type]]...);

```


 Adds or updates dynamic columns.

  * + **`dyncol_blob`** must be either a valid dynamic columns blob (for example, `COLUMN_CREATE` returns such blob), or an empty string.
	+ **`column_name`** specifies the name of the column to be added. If `dyncol_blob` already has a column with this name, it will be overwritten.
	+ **`value`** specifies the new value for the column. Passing a NULL value will cause the column to be deleted.
	+ **`as type`** is optional. See <#datatypes> section for a discussion about types.

 
 The return value is a dynamic column blob after the modifications.

  
 Typical usage:

  
```
-- MariaDB 5.3+:
UPDATE tbl SET dyncol_blob=COLUMN_ADD(dyncol_blob, 1 /*column id*/, "value") 
  WHERE id=1;
-- MariaDB 10.0.1+:
UPDATE t1 SET dyncol_blob=COLUMN_ADD(dyncol_blob, "column_name", "value") 
  WHERE id=1;

```


 Note: `COLUMN_ADD()` is a regular function (just like `[CONCAT()](../concat/index)`), hence, in order to update the value in the table you have to use the `UPDATE ... SET dynamic_col=COLUMN_ADD(dynamic_col,
 ....)`  pattern.

  #### COLUMN\_GET

 
```
COLUMN_GET(dyncol_blob, column_nr as type);
COLUMN_GET(dyncol_blob, column_name as type);

```


 Get the value of a dynamic column by its name. If no column with the given name exists, `NULL` will be returned.

  
 **`column_name as type`** requires that one specify the datatype of the dynamic column they are reading. 

  
 This may seem counter-intuitive: why would one need to specify which datatype they're retrieving? Can't the dynamic columns system figure the datatype from the data being stored?

  
 The answer is: SQL is a statically-typed language. The SQL interpreter needs to know the datatypes of all expressions before the query is run (for example, when one is using prepared statements and runs `"select COLUMN_GET(...)"`, the prepared statement API requires the server to inform the client about the datatype of the column being read before the query is executed and the server can see what datatype the column actually has).

  
 See the [Datatypes](#datatypes) section for more information about datatypes.

  #### COLUMN\_DELETE

 
```
COLUMN_DELETE(dyncol_blob, column_nr, column_nr...);
COLUMN_DELETE(dyncol_blob, column_name, column_name...);

```


 Delete a dynamic column with the specified name. Multiple names can be given.

  
 The return value is a dynamic column blob after the modification.

  #### COLUMN\_EXISTS

 
```
COLUMN_EXISTS(dyncol_blob, column_nr);
COLUMN_EXISTS(dyncol_blob, column_name);

```


 Check if a column with name `column_name` exists in `dyncol_blob`. If yes, return `1`, otherwise return `0`.

  #### COLUMN\_LIST

 
```
COLUMN_LIST(dyncol_blob);

```


 Return a comma-separated list of column names. The names are quoted with backticks.

  
```
SELECT column_list(column_create('col1','val1','col2','val2'));
+---------------------------------------------------------+
| column_list(column_create('col1','val1','col2','val2')) |
+---------------------------------------------------------+
| `col1`,`col2`                                           |
+---------------------------------------------------------+

```

#### COLUMN\_CHECK

 
```
COLUMN_CHECK(dyncol_blob);

```


 Check if `dyncol_blob` is a valid packed dynamic columns blob. Return value of 1 means the blob is valid, return value of 0 means it is not.

  
 **Rationale:** Normally, one works with valid dynamic column blobs. Functions like `COLUMN_CREATE`, `COLUMN_ADD`, `COLUMN_DELETE` always return valid dynamic column blobs. However, if a dynamic column blob is accidentally truncated, or transcoded from one character set to another, it will be corrupted. This function can be used to check if a value in a blob field is a valid dynamic column blob.

  
 **Note:** It is possible that a truncation cut a Dynamic Column "clearly" so that COLUMN\_CHECK will not notice the corruption, but in any case of truncation a warning is issued during value storing.

  #### COLUMN\_JSON

 
```
COLUMN_JSON(dyncol_blob);

```


 Return a JSON representation of data in `dyncol_blob`.

  
 Example:

  
```
SELECT item_name, COLUMN_JSON(dynamic_cols) FROM assets;
+-----------------+----------------------------------------+
| item_name       | COLUMN_JSON(dynamic_cols)              |
+-----------------+----------------------------------------+
| MariaDB T-shirt | {"size":"XL","color":"blue"}           |
| Thinkpad Laptop | {"color":"black","warranty":"3 years"} |
+-----------------+----------------------------------------+

```


 Limitation: `COLUMN_JSON` will decode nested dynamic columns at a nesting level of not more than 10 levels deep. Dynamic columns that are nested deeper than 10 levels will be shown as BINARY string, without encoding.

  ### Nesting Dynamic Columns

 It is possible to use nested dynamic columns by putting one dynamic column blob inside another. The `COLUMN_JSON` function will display nested columns.

 
```
SET @tmp= column_create('parent_column', 
  column_create('child_column', 12345));
Query OK, 0 rows affected (0.00 sec)

SELECT column_json(@tmp);
+------------------------------------------+
| column_json(@tmp)                        |
+------------------------------------------+
| {"parent_column":{"child_column":12345}} |
+------------------------------------------+

SELECT column_get(column_get(@tmp, 'parent_column' AS char), 
  'child_column' AS int);
+------------------------------------------------------------------------------+
| column_get(column_get(@tmp, 'parent_column' as char), 'child_column' as int) |
+------------------------------------------------------------------------------+
|                                                                        12345 |
+------------------------------------------------------------------------------+

```

If you are trying to get a nested dynamic column as a string use 'as BINARY' as the last argument of COLUMN\_GET (otherwise problems with character set conversion and illegal symbols are possible):

 
```
select column_json( column_get(
  column_create('test1', 
    column_create('key1','value1','key2','value2','key3','value3')),
  'test1' as BINARY));

```

### Datatypes

 In SQL, one needs to define the type of each column in a table. Dynamic columns do not provide any way to declare a type in advance ("whenever there is a column 'weight', it should be integer" is not possible). However, each particular dynamic column value is stored together with its datatype.

 The set of possible datatypes is mostly the same as that used by the SQL `[CAST](../cast/index)` and `[CONVERT](../convert/index)` functions. However, note that there are currently some differences - see [MDEV-597](https://jira.mariadb.org/browse/MDEV-597).

 


| type | dynamic column internal type | description |
| --- | --- | --- |
| `BINARY[(N)]` | `DYN_COL_STRING` | (variable length string with binary charset) |
| `CHAR[(N)]` | `DYN_COL_STRING` | (variable length string with charset) |
| `DATE` | `DYN_COL_DATE` | (date - 3 bytes) |
| `DATETIME[(D)]` | `DYN_COL_DATETIME` | (date and time (with [microseconds](../microseconds-in-mariadb/index)) - 9 bytes) |
| `DECIMAL[(M[,D])]` | `DYN_COL_DECIMAL` | (variable length binary decimal representation with MariaDB limitation) |
| `DOUBLE[(M,D)]` | `DYN_COL_DOUBLE` | (64 bit double-precision floating point) |
| `INTEGER` | `DYN_COL_INT` | (variable length, up to 64 bit signed integer) |
| `SIGNED [INTEGER]` | `DYN_COL_INT` | (variable length, up to 64 bit signed integer) |
| `TIME[(D)]` | `DYN_COL_TIME` | (time (with [microseconds](../microseconds-in-mariadb/index), may be negative) - 6 bytes) |
| `UNSIGNED [INTEGER]` | `DYN_COL_UINT` | (variable length, up to 64bit unsigned integer) |

 
#### A Note About Lengths

 If you're running queries like

 
```
SELECT COLUMN_GET(blob, 'colname' as CHAR) ... 

```

without specifying a maximum length (i.e. using #as CHAR#, not `as CHAR(n)`), MariaDB will report the maximum length of the resultset column to be `53,6870,911` (bytes or characters?) for [MariaDB 5.3](../what-is-mariadb-53/index)-10.0.0 and `16,777,216` for [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/)+. This may cause excessive memory usage in some client libraries, because they try to pre-allocate a buffer of maximum resultset width. If you suspect you're hitting this problem, use `CHAR(n)` whenever you're using `COLUMN_GET` in the select list.

 ### 
[MariaDB 5.3](../what-is-mariadb-53/index) vs [MariaDB 10.0](../what-is-mariadb-100/index)

 The dynamic columns feature was introduced into MariaDB in two steps:

 1. [MariaDB 5.3](../what-is-mariadb-53/index) was the first version to support dynamic columns. Only numbers could be used as column names in this version.
2. In [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/), column names can be either numbers or strings. Also, the `COLUMN_JSON` and `COLUMN_CHECK` functions were added.

 See also [Dynamic Columns in MariaDB 10](../dynamic-columns-in-mariadb-10/index).

 ### Client-side API

 It is also possible to create or parse dynamic columns blobs on the client side. `libmysql` client library now includes an API for writing/reading dynamic column blobs. See [dynamic-columns-api](../dynamic-columns-api/index) for details.

 ### Limitations

 


| Description | Limit |
| --- | --- |
| Max number of columns |  65535 |
| Max total length of packed dynamic column | [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) (1G) |

 
See Also
--------

 * [Dynamic Columns from MariaDB 10](../dynamic-columns-from-mariadb-10/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dynamic-columns/>

MBR (Minimum Bounding Rectangle)
=================================

  

| Title | Description |
| --- | --- |
|  [MBR Definition](../mbr-definition/index) |  Minimum Bounding Rectangle.  |
|  [MBRContains](../mbrcontains/index) |  Indicates one Minimum Bounding Rectangle contains another.  |
|  [MBRDisjoint](../mbrdisjoint/index) |  Indicates whether the Minimum Bounding Rectangles of two geometries are disjoint.  |
|  [MBREqual](../mbrequal/index) |  Whether the Minimum Bounding Rectangles of two geometries are the same.  |
|  [MBRIntersects](../mbrintersects/index) |  Indicates whether the Minimum Bounding Rectangles of the two geometries intersect.  |
|  [MBROverlaps](../mbroverlaps/index) |  Whether the Minimum Bounding Rectangles of two geometries overlap.  |
|  [MBRTouches](../mbrtouches/index) |  Whether the Minimum Bounding Rectangles of two geometries touch.  |
|  [MBRWithin](../mbrwithin/index) |  Indicates whether one Minimum Bounding Rectangle is within another  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbr-minimum-bounding-rectangle/>

WKB
====

   WKB stands for Well-Known Binary, a standard representation for geometric values.

  

| Title | Description |
| --- | --- |
|  [Well-Known Binary (WKB) Format](../well-known-binary-wkb-format/index) |  Well-Known Binary format for representing geometric data.  |
|  [AsBinary](../wkb-asbinary/index) |  Synonym for ST\_AsBinary.  |
|  [AsWKB](../aswkb/index) |  Synonym for ST\_AsBinary.  |
|  [MLineFromWKB](../mlinefromwkb/index) |  Constructs a MULTILINESTRING.  |
|  [MPointFromWKB](../mpointfromwkb/index) |  Constructs a MULTIPOINT value using its WKB representation and SRID.  |
|  [MPolyFromWKB](../mpolyfromwkb/index) |  Constructs a MULTIPOLYGON value using its WKB representation and SRID.  |
|  [GeomCollFromWKB](../wkb-geomcollfromwkb/index) |  Synonym for ST\_GeomCollFromWKB.  |
|  [GeometryCollectionFromWKB](../geometrycollectionfromwkb/index) |  Synonym for ST\_GeomCollFromWKB.  |
|  [GeometryFromWKB](../geometryfromwkb/index) |  Synonym for ST\_GeomFromWKB.  |
|  [GeomFromWKB](../wkb-geomfromwkb/index) |  Synonym for ST\_GeomFromWKB.  |
|  [LineFromWKB](../wkb-linefromwkb/index) |  Synonym for ST\_LineFromWKB.  |
|  [LineStringFromWKB](../linestringfromwkb/index) |  Synonym for ST\_LineFromWKB.  |
|  [MultiLineStringFromWKB](../multilinestringfromwkb/index) |  A synonym for MLineFromWKB.  |
|  [MultiPointFromWKB](../multipointfromwkb/index) |  Synonym for MPointFromWKB.  |
|  [MultiPolygonFromWKB](../multipolygonfromwkb/index) |  Synonym for MPolyFromWKB.  |
|  [PointFromWKB](../wkb-pointfromwkb/index) |  Synonym for PointFromWKB.  |
|  [PolyFromWKB](../wkb-polyfromwkb/index) |  Synonym for ST\_PolyFromWKB.  |
|  [PolygonFromWKB](../polygonfromwkb/index) |  Synonym for ST\_PolyFromWKB.  |
|  [ST\_AsBinary](../st_asbinary/index) |  Converts a value to its WKB representation.  |
|  [ST\_AsWKB](../st_aswkb/index) |  Synonym for ST\_AsBinary.  |
|  [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index) |  Constructs a GEOMETRYCOLLECTION value from a WKB.  |
|  [ST\_GeometryCollectionFromWKB](../st_geometrycollectionfromwkb/index) |  Synonym for ST\_GeomCollFromWKB.  |
|  [ST\_GeometryFromWKB](../st_geometryfromwkb/index) |  Synonym for ST\_GeomFromWKB.  |
|  [ST\_GeomFromWKB](../st_geomfromwkb/index) |  Constructs a geometry value using its WKB representation and SRID.  |
|  [ST\_LineFromWKB](../st_linefromwkb/index) |  Constructs a LINESTRING using its WKB and SRID.  |
|  [ST\_LineStringFromWKB](../st_linestringfromwkb/index) |  Synonym for ST\_LineFromWKB.  |
|  [ST\_PointFromWKB](../st_pointfromwkb/index) |  Constructs POINT using its WKB and SRID.  |
|  [ST\_PolyFromWKB](../st_polyfromwkb/index) |  Constructs POLYGON value using its WKB representation and SRID.  |
|  [ST\_PolygonFromWKB](../st_polygonfromwkb/index) |  Synonym for ST\_PolyFromWKB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb/>

WKT
====

   The Well-Known Text (WKT) representation of Geometry is designed to exchange geometry data in ASCII form. This section has articles on WKT in MariaDB.

  

| Title | Description |
| --- | --- |
|  [WKT Definition](../wkt-definition/index) |  Well-Known Text for exchanging geometry data in ASCII form.  |
|  [AsText](../wkt-astext/index) |  Synonym for ST\_AsText.  |
|  [AsWKT](../wkt-aswkt/index) |  Synonym for ST\_AsText.  |
|  [GeomCollFromText](../wkt-geomcollfromtext/index) |  Synonym for ST\_GeomCollFromText.  |
|  [GeometryCollectionFromText](../geometrycollectionfromtext/index) |  Synonym for ST\_GeomCollFromText.  |
|  [GeometryFromText](../geometryfromtext/index) |  Synonym for ST\_GeomFromText.  |
|  [GeomFromText](../wkt-geomfromtext/index) |  Synonym for ST\_GeomFromText.  |
|  [LineFromText](../wkt-linefromtext/index) |  Synonym for ST\_LineFromText.  |
|  [LineStringFromText](../linestringfromtext/index) |  Synonym for ST\_LineFromText.  |
|  [MLineFromText](../mlinefromtext/index) |  Constructs MULTILINESTRING using its WKT representation and SRID.  |
|  [MPointFromText](../mpointfromtext/index) |  Constructs a MULTIPOINT value using its WKT and SRID.  |
|  [MPolyFromText](../mpolyfromtext/index) |  Constructs a MULTIPOLYGON value.  |
|  [MultiLineStringFromText](../multilinestringfromtext/index) |  Synonym for MLineFromText.  |
|  [MultiPointFromText](../multipointfromtext/index) |  Synonym for MPointFromText.  |
|  [MultiPolygonFromText](../multipolygonfromtext/index) |  Synonym for MPolyFromText.  |
|  [PointFromText](../wkt-pointfromtext/index) |  Synonym for ST\_PointFromText.  |
|  [PolyFromText](../wkt-polyfromtext/index) |  Synonym for ST\_PolyFromText.  |
|  [PolygonFromText](../polygonfromtext/index) |  Synonym for ST\_PolyFromText.  |
|  [ST\_AsText](../st_astext/index) |  Converts a value to its WKT-Definition.  |
|  [ST\_ASWKT](../st_aswkt/index) |  Synonym for ST\_ASTEXT().  |
|  [ST\_GeomCollFromText](../st_geomcollfromtext/index) |  Constructs a GEOMETRYCOLLECTION value.  |
|  [ST\_GeometryCollectionFromText](../st_geometrycollectionfromtext/index) |  Synonym for ST\_GeomCollFromText.  |
|  [ST\_GeometryFromText](../st_geometryfromtext/index) |  Synonym for ST\_GeomFromText.  |
|  [ST\_GeomFromText](../st_geomfromtext/index) |  Constructs a geometry value using its WKT and SRID.  |
|  [ST\_LineFromText](../st_linefromtext/index) |  Creates a linestring value.  |
|  [ST\_LineStringFromText](../st_linestringfromtext/index) |  Synonym for ST\_LineFromText.  |
|  [ST\_PointFromText](../st_pointfromtext/index) |  Constructs a POINT value.  |
|  [ST\_PolyFromText](../st_polyfromtext/index) |  Constructs a POLYGON value.  |
|  [ST\_PolygonFromText](../st_polygonfromtext/index) |  Synonym for ST\_PolyFromText.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt/>

Differences between JSON\_QUERY and JSON\_VALUE
===============================================

    The primary difference between the two functions is that *JSON\_QUERY* returns an object or an array, while *JSON\_VALUE* returns a scalar. 

 Take the following JSON document as an example

 
```
SET @json='{ "x": [0,1], "y": "[0,1]", "z": "Monty" }';

```

Note that data member "x" is an array, and data members "y" and "z" are strings. The following examples demonstrate the differences between the two functions.

 
```
SELECT JSON_QUERY(@json,'$'), JSON_VALUE(@json,'$');
+--------------------------------------------+-----------------------+
| JSON_QUERY(@json,'$')                      | JSON_VALUE(@json,'$') |
+--------------------------------------------+-----------------------+
| { "x": [0,1], "y": "[0,1]", "z": "Monty" } | NULL                  |
+--------------------------------------------+-----------------------+

SELECT JSON_QUERY(@json,'$.x'), JSON_VALUE(@json,'$.x');
+-------------------------+-------------------------+
| JSON_QUERY(@json,'$.x') | JSON_VALUE(@json,'$.x') |
+-------------------------+-------------------------+
| [0,1]                   | NULL                    |
+-------------------------+-------------------------+

SELECT JSON_QUERY(@json,'$.y'), JSON_VALUE(@json,'$.y');
+-------------------------+-------------------------+
| JSON_QUERY(@json,'$.y') | JSON_VALUE(@json,'$.y') |
+-------------------------+-------------------------+
| NULL                    | [0,1]                   |
+-------------------------+-------------------------+

SELECT JSON_QUERY(@json,'$.z'), JSON_VALUE(@json,'$.z');
+-------------------------+-------------------------+
| JSON_QUERY(@json,'$.z') | JSON_VALUE(@json,'$.z') |
+-------------------------+-------------------------+
| NULL                    | Monty                   |
+-------------------------+-------------------------+

SELECT JSON_QUERY(@json,'$.x[0]'), JSON_VALUE(@json,'$.x[0]');
+----------------------------+----------------------------+
| JSON_QUERY(@json,'$.x[0]') | JSON_VALUE(@json,'$.x[0]') |
+----------------------------+----------------------------+
| NULL                       | 0                          |
+----------------------------+----------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/differences-between-json_query-and-json_value/>

RELEASE\_ALL\_LOCKS
===================

    
**MariaDB until [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**RELEASE\_ALL\_LOCKS was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
Syntax
------

 
```
RELEASE_ALL_LOCKS()

```
 Description
-----------

 Releases all named locks held by the current session. Returns the number of locks released, or `0` if none were held. 

 Statements using the `RELEASE_ALL_LOCKS` function are [not safe for statement-based replication](../unsafe-statements-for-statement-based-replication/index).

 Examples
--------

 
```
SELECT RELEASE_ALL_LOCKS();
+---------------------+
| RELEASE_ALL_LOCKS() | 
+---------------------+
|                   0 |
+---------------------+

SELECT GET_LOCK('lock1',10);
+----------------------+
| GET_LOCK('lock1',10) |
+----------------------+
|                    1 |
+----------------------+

SELECT RELEASE_ALL_LOCKS();
+---------------------+
| RELEASE_ALL_LOCKS() | 
+---------------------+
|                   1 |
+---------------------+

```

See Also
--------

 * [GET\_LOCK](../get_lock/index)
* [IS\_FREE\_LOCK](../is_free_lock/index)
* [IS\_USED\_LOCK](../is_used_lock/index)
* [RELEASE\_LOCK](../release_lock/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/release_all_locks/>

JSON\_MERGE\_PRESERVE
=====================

    
**MariaDB starting with [10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/)**`JSON_MERGE_PRESERVE` was introduced in [MariaDB 10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/) and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/).

 
Syntax
------

 
```
JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)

```

Description
-----------

 Merges the given JSON documents, returning the merged result, or NULL if any argument is NULL.

 `JSON_MERGE_PRESERVE` was introduced in [MariaDB 10.2.25](https://mariadb.com/kb/en/mariadb-10225-release-notes/), [MariaDB 10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/) and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) as a synonym for [JSON\_MERGE](../json_merge/index), which has been deprecated.

 Example
-------

 
```
SET @json1 = '[1, 2]';
SET @json2 = '[2, 3]';
SELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);
+---------------------------------+------------------------------------+
| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |
+---------------------------------+------------------------------------+
| [2, 3]                          | [1, 2, 2, 3]                       |
+---------------------------------+------------------------------------+

```

See Also
--------

 * [JSON\_MERGE\_PATCH](../json_merge_patch/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_merge_preserve/>

JSONPath Expressions
====================

    A number of [JSON functions](../json-functions/index) accept JSON Path expressions. MariaDB defines this path as follows:

 JSON Path Syntax
----------------

 
```
path : ['lax'] '$' [step]*

```

The path starts with an optional *path mode*. At the moment, MariaDB supports only the "lax" mode, which is also the mode that is used when it is not explicitly specified. 

 The `$` symbol represents the context item. The search always starts from the context item; because of that, the path always starts with `$`. 

 Then, it is followed by zero or more steps, which select element(s) in the JSON document. A step may be one of the following:

 * Object member selector
* Array element selector
* Wildcard selector

 ### Object Member Selector

 To select member(s) in a JSON object, one can use one of the following:

 * `.memberName` selects the value of the member with name memberName.
* `."memberName"` - the same as above but allows one to select a member with a name that's not a valid identifier (that is, has space, dot, and/or other characters)
* `.*` - selects the values of all members of the object.

 If the current item is an array (instead of an object), nothing will be selected.

 ### Array Element Selector

 To select elements of an array, one can use one of the following:

 * `[N]` selects element number N in the array. The elements are counted from zero.
* `[*]` selects all elements in the array.

 If the current item is an object (instead of an array), nothing will be selected.

 Starting from MariaDB server 10.9, JSON path also supports negative index in array, 'last' keyword and range notation ('to' keyword) for accessing array elements. Negative index starts from -1.

 * `[-N]` selects n th element from end.
* `[last-N]` selects n th element from the last element.
* `[M to N]` selects range of elements starting from index M to N.

 Example:

 
```

SET @json='{
            "A": [0,
                  [1, 2, 3],
                  [4, 5, 6],
                  "seven",
                   0.8,
                   true,
                   false,
                   "eleven",
                  [12, [13, 14], {"key1":"value1"},[15]],
                  true],
            "B": {"C": 1},
            "D": 2
           }';
SELECT JSON_EXTRACT(@json, '$.A[-8][1]');
+--------------------------------------------------+
| JSON_EXTRACT(@json, '$.A[-8][1]')                |
+--------------------------------------------------+
| 5                                                |
+--------------------------------------------------+

SELECT JSON_EXTRACT(@json, '$.A[last-7][1]');
+-----------------------------------------------+
| SELECT JSON_EXTRACT(@json, '$.A[last-7][1]'); |
+-----------------------------------------------+
| 5                                             |
+-----------------------------------------------+


SET @json= '[
             [1, {"key1": "value1"}, 3],
             [false, 5, 6],
             [7, 8, [9, {"key2": 2}, 11]],
             [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
             [19, 20],
             21, 22
            ]';

SELECT JSON_EXTRACT(@json, '$[0 to 3][2]');
+-----------------------------------------------+
| JSON_EXTRACT(@json, '$[0 to 3][2]')           |
+-----------------------------------------------+
| [3, 6, [9, {"key2": 2}, 11], [14]]            |
+-----------------------------------------------+

```

This will produce output for first index of eighth from last element of a two dimensional array.

 Note: In range notation, when M > N ( when M,N are greater than or equal to 0) or (size of array - M or size of array - N when M, N are less than 0), then it is treated as an impossible range and NULL is returned.

 
```
SET @json= '[1, 2, 3, 4, 5]';
SELECT JSON_EXTRACT(@json, '$[4 to 2]');
+-----------------------------------+
| JSON_EXTRACT(@json, '$[4 to 2]')  |
+-----------------------------------+
| NULL                              |
+-----------------------------------+

```

### Wildcard

 The wildcard step, `**`, recursively selects all child elements of the current element. Both array elements and object members are selected.

 The wildcard step must not be the last step in the JSONPath expression. It must be followed by an array or object member selector step.

 For example:

 
```
select json_extract(@json_doc, '$**.price');

```

will select all object members in the document that are named `price`, while

 
```
select json_extract(@json_doc, '$**[2]');

```

will select the second element in each of the arrays present in the document.

 Compatibility
-------------

 MariaDB's JSONPath syntax supports a subset of JSON Path's definition in the SQL Standard. The most notable things not supported are the `strict` mode and filters. 

 MariaDB's JSONPath is close to MySQL's JSONPath. The wildcard step ( `**` ) is a non-standard extension that has the same meaning as in MySQL. The difference between MariaDB and MySQL's JSONPath is: MySQL doesn't allow one to specify the mode explicitly (but uses `lax`  mode implicitly).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/jsonpath-expressions/>

JSON\_MERGE\_PATCH
==================

    
**MariaDB starting with [10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/)**`JSON_MERGE_PATCH` was introduced in [MariaDB 10.3.16](https://mariadb.com/kb/en/mariadb-10316-release-notes/) and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/).

 
Syntax
------

 
```
JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)

```

Description
-----------

 Merges the given JSON documents, returning the merged result, or NULL if any argument is NULL.

 `JSON_MERGE_PATCH` is an RFC 7396-compliant replacement for [JSON\_MERGE](../json_merge/index), which has been deprecated.

 Example
-------

 
```
SET @json1 = '[1, 2]';
SET @json2 = '[2, 3]';
SELECT JSON_MERGE_PATCH(@json1,@json2),JSON_MERGE_PRESERVE(@json1,@json2);
+---------------------------------+------------------------------------+
| JSON_MERGE_PATCH(@json1,@json2) | JSON_MERGE_PRESERVE(@json1,@json2) |
+---------------------------------+------------------------------------+
| [2, 3]                          | [1, 2, 2, 3]                       |
+---------------------------------+------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json_merge_patch/>

Spider Storage Engine Core Concepts
===================================

    A typical Spider deployment has a shared-nothing clustered architecture. The system works with any inexpensive hardware, and with a minimum of specific requirements for hardware or software. It consists of a set of computers, with one or more MariaDB processes known as nodes. 

 The nodes that store the data will be designed as `Backend Nodes`, and can be any MariaDB, MySQL, Oracle server instances using any storage engine available inside the backend. 

 The `Spider Proxy Nodes` are instances running at least MariaDB 10. `Spider Proxy Nodes` are used to declare per table attachment to the backend nodes. In addition `Spider Proxy Nodes` can be setup to enable the tables to be split and mirrored to multiple `Backend Nodes`. 

 Spider Common Usage
-------------------

 ![Spider3]

 In the default high availability setup #Spider Nodes# produce SQL errors when a backend server is not responding. Per table monitoring can be setup to enable availability in case of unresponsive backends `monotoring_bg_kind=1` or `monotoring_bg_kind=2`. The Monitoring Spider Nodes will be inter-connected with usage of the system table `mysql.link_mon_servers` to manage network partitioning. Better known as split brain, an even number of `Spider Monitor Nodes` should be setup to allow a consensus based on the majority. Rather a single separated shared `Monitoring Node` instance or a minimum set of 3 `Spider Nodes`. More information can be found [here](http://fr.slideshare.net/Kentoku/spider-ha-20100922dtt7). 

 Spider Storage Engine Federation
--------------------------------

 Spider is a pluggable Storage Engine, acting as a proxy between the optimizer and the remote backends. When the optimizer requests multiple calls to the storage engine, Spider enforces consistency using the 2 phase commit protocol to the backends and by creating transactions on the backends to preserve atomic operations for a single SQL execution. Preserving atomic operation during execution is used at multiple levels in the architecture,. For the regular optimizer plan, it refers to `multiple split reads` and for concurrent partition scans, it will refer to `semi transactions`. 

 Costly queries can be more efficient when it is possible to fully push down part of the execution plan on each backend and reduce the result afterwards. Spider enables such execution with some direct execution shortcuts. 

 ![Spider1]

 Spider Threading Model
----------------------

 Spider uses the per partitions and per table model to concurrently access the remote backend nodes. For memory workload that property can be used to define multiple partitions on a single remote backend node to better adapt the concurrency to available CPUs in the hardware. 

 ![Spider2]

 Spider maintains an internal dictionary of Table and Index statistics based on separated threads. The statistics are pulled per default on a time line basis and refer to `crd` for cardinality and `sts` for table status. 

 Spider Memory Model
-------------------

 Spider stores resultsets into memory, but [spider\_quick\_mode](../spider-server-system-variables/index#spider_quick_mode)=3 stores resultsets into internal temporary tables if the resultsets are larger than quick\_table\_size.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-storage-engine-core-concepts/>

LASTVAL
=======

    `LASTVAL` is a synonym for [PREVIOUS VALUE for sequence\_name](../previous-value-for-sequence_name/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lastval/>

NEXTVAL
=======

    `NEXTVAL` is a synonym for [NEXT VALUE for sequence\_name](../next-value-for-sequence_name/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nextval/>

Sequence Overview
=================

    
This page is about sequence objects. For details about the storage engine, see [Sequence Storage Engine](../sequence-storage-engine/index).

 
Introduction
------------

 A sequence is an object that generates a sequence of numeric values, as specified by the [CREATE SEQUENCE](../create-sequence/index) statement. 

 CREATE SEQUENCE will create a sequence that generates new values when called with NEXT VALUE FOR sequence\_name. It's an alternative to [AUTO INCREMENT](../auto_increment/index) when one wants to have more control of how the numbers are generated. As the SEQUENCE caches values (up to the CACHE value in the [CREATE SEQUENCE](../create-sequence/index) statement, by default 1000) it can in some cases be much faster than AUTO INCREMENT. Another benefit is that one can access the last value generated by all used sequences, which solves one of the limitations with [LAST\_INSERT\_ID()](../last_insert_id/index).

 Creating a Sequence
-------------------

 The [CREATE SEQUENCE](../create-sequence/index) statement is used to create a sequence. Here is an example of a sequence starting at 100, incrementing by 10 each time:

 
```
CREATE SEQUENCE s START WITH 100 INCREMENT BY 10;

```

The CREATE SEQUENCE statement, along with defaults, can be viewd with the [SHOW CREATE SEQUENCE STATEMENT](../show-create-sequence/index), for example:

 
```
SHOW CREATE SEQUENCE s\G
*************************** 1. row ***************************
       Table: s
Create Table: CREATE SEQUENCE `s` start with 100 minvalue 1 maxvalue 9223372036854775806 
  increment by 10 cache 1000 nocycle ENGINE=InnoDB

```

Using Sequence Objects
----------------------

 To get the [next value from a sequence](../next-value-for-sequence_name/index), use

 
```
NEXT VALUE FOR sequence_name

```

or

 
```
NEXTVAL(sequence_name)

```

or in Oracle mode ([SQL\_MODE=ORACLE](../sql-mode/index))

 
```
sequence_name.nextval

```

For [retrieving the last value](../previous-value-for-sequence_name/index) used by the current connection from a sequence use:

 
```
PREVIOUS VALUE FOR sequence_name

```

or

 
```
LASTVAL(sequence_name)

```

or in Oracle mode ([SQL\_MODE=ORACLE](../sql-mode/index))

 
```
sequence_name.currval

```

For example:

 
```
SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        100 |
+------------+

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|        110 |
+------------+

SELECT LASTVAL(s);
+------------+
| LASTVAL(s) |
+------------+
|        110 |
+------------+

```

### Using Sequences in DEFAULT

 Sequences can be used in DEFAULT:

 
```
create sequence s1;
create table t1 (a int primary key default (next value for s1), b int);
insert into t1 (b) values (1),(2);
select * from t1;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    2 |
+---+------+

```

Changing a Sequence
-------------------

 The [ALTER SEQUENCE](../alter-sequence/index) statement is used for changing sequences. For example, to restart the sequence at another value:

 
```
ALTER SEQUENCE s RESTART 50;

SELECT NEXTVAL(s);
+------------+
| NEXTVAL(s) |
+------------+
|         50 |
+------------+

```

The [SETVAL function](../setval/index) can also be used to set the next value to be returned for a SEQUENCE, for example:

 
```
SELECT SETVAL(s, 100);
+----------------+
| SETVAL(s, 100) |
+----------------+
|            100 |
+----------------+

```

`SETVAL` can only be used to increase the sequence value. Attempting to set a lower value will fail, returning NULL:

 
```
SELECT SETVAL(s, 50);
+---------------+
| SETVAL(s, 50) |
+---------------+
|          NULL |
+---------------+

```

Dropping a Sequence
-------------------

 The [DROP SEQUENCE](../drop-sequence/index) statement is used to drop a sequence, for example:

 
```
DROP SEQUENCE s;

```

Replication
-----------

 If one wants to use Sequences in a master-master setup or with Galera one should use `INCREMENT=0`. This will tell the Sequence to use [auto\_increment\_increment](../replication-and-binary-log-server-system-variables/index#auto_increment_increment) and [auto\_increment\_offset](../replication-and-binary-log-server-system-variables/index#auto_increment_offset) to generate unique values for each server.

 Standards Compliance
--------------------

 MariaDB supports both ANSI SQL and Oracle syntax for sequences.

 However as `SEQUENCE` is implemented as a special kind of table, it uses the same namespace as tables. The benefits are that sequences show up in [SHOW TABLES](../show-tables/index), and one can also create a sequence with [CREATE TABLE](../create-table/index) and drop it with [DROP TABLE](../drop-table/index). One can [SELECT](../select/index) from it as from any other table. This ensures that all old tools that work with tables should work with sequences.

 Since sequence objects act as regular tables in many contexts, they will be affected by [LOCK TABLES](../lock-tables/index). This is not the case in other DBMS, such as Oracle, where LOCK TABLE does not affect sequences.

 Notes
-----

 One of the goals with the Sequence implementation is that all old tools, such as [mariadb-dump](../mariadb-dump/index) (previously mysqldump), should work unchanged, while still keeping the normal usage of sequence standard compatibly.

 To make this possible, `sequence` is currently implemented as a table with a few exclusive properties.

 The special properties for sequence tables are:

 * A sequence table has always one row.
* When one creates a sequence, either with [CREATE TABLE](../create-table/index) or [CREATE SEQUENCE](../create-sequence/index), one row will be inserted.
* If one tries to insert into a sequence table, the single row will be updated. This allows [mariadb-dump](../mariadb-dump/index) to work but also gives the additional benefit that one can change all properties of a sequence with a single insert. New applications should of course also use `ALTER SEQUENCE`.
* [UPDATE](../update/index) or [DELETE](../delete/index) can't be performed on Sequence objects.
* Doing a select on the sequence shows the current state of the sequence, except the values that are reserved in the cache. The `next_value` column shows the next value not reserved by the cache.
* [FLUSH TABLES](../flush/index) will close the sequence and the next sequence number generated will be according to what's stored in the Sequence object. In effect, this will discard the cached values.
* A number of normal table operations work on Sequence tables. See next section.

 Table Operations that Work with Sequences
-----------------------------------------

 * [SHOW CREATE TABLE sequence\_name](../show-create-table/index). This shows the table structure that is behind the `SEQUENCE` including the field names that can be used with [SELECT](../select/index) or even [CREATE TABLE](../create-table/index).
* [CREATE TABLE sequence-structure ... SEQUENCE=1](../create-table/index)
* [ALTER TABLE sequence RENAME TO sequence2](../alter-table/index)
* [RENAME TABLE sequence\_name TO new\_sequence\_name](../rename-table/index)
* [DROP TABLE sequence\_name](../drop-table/index). This is allowed mainly to get old tools like [mariadb-dump](../mariadb-dump/index) to work with sequence tables.
* [SHOW TABLES](../show-tables/index)

 Implementation
--------------

 Internally, sequence tables are created as a normal table without rollback (the [InnoDB](../innodb/index), [Aria](../aria/index) and [MySAM](../myisam/index) engines support this), wrapped by a sequence engine object. This allowed us to create sequences with almost no performance impact for normal tables. (The cost is one 'if' per insert if the [binary log](../binary-log/index) is enabled).

 Underlying Table Structure
--------------------------

 The following example shows the table structure of sequences and how it can be used as a table. (Output of results are slightly edited to make them easier to read)

 
```
create sequence t1;
show create sequence t1\G
*************************** 1. row ***************************
  CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806
  increment by 1 cache 1000 nocycle ENGINE=InnoDB

show create table t1\G
*************************** 1. row ***************************
Create Table: CREATE TABLE `t1` (
  `next_not_cached_value` bigint(21) NOT NULL,
  `minimum_value` bigint(21) NOT NULL,
  `maximum_value` bigint(21) NOT NULL,
  `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
  `increment` bigint(21) NOT NULL COMMENT 'increment value',
  `cache_size` bigint(21) unsigned NOT NULL,
  `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
  `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=InnoDB SEQUENCE=1


select * from t1\G
next_not_cached_value: 1
 minimum_value: 1
 maximum_value: 9223372036854775806
  start_value: 1
  increment: 1
  cache_size: 1000
  cycle_option: 0
  cycle_count: 0

```

The `cycle_count` column is incremented every time the sequence wraps around.

 Credits
-------

 * Thanks to Jianwe Zhao from Aliyun for his work on SEQUENCE in AliSQL, which gave ideas and inspiration for this work.
* Thanks to Peter Gulutzan,who helped test and gave useful comments about the implementation.

 See Also
--------

 * [CREATE SEQUENCE](../create-sequence/index)
* [ALTER SEQUENCE](../alter-sequence/index)
* [DROP SEQUENCE](../drop-sequence/index)
* [NEXT VALUE FOR](../next-value-for-sequence_name/index)
* [PREVIOUS VALUE FOR](../previous-value-for-sequence_name/index)
* [SETVAL()](../setval/index). Set next value for the sequence.
* [AUTO INCREMENT](../auto_increment/index)
* [Sequence Storage Engine](../sequence-storage-engine/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sequence-overview/>

SHOW CREATE SEQUENCE
====================

    Syntax
------

 
```
SHOW CREATE SEQUENCE sequence_name;

```
 Description
-----------

 Shows the [CREATE SEQUENCE](../create-sequence/index) statement that created the given [sequence](../sequences/index). The statement requires the `SELECT` privilege for the table.

 Example
-------

 
```
CREATE SEQUENCE s1 START WITH 50;
SHOW CREATE SEQUENCE s1\G;
*************************** 1. row ***************************
       Table: s1
Create Table: CREATE SEQUENCE `s1` start with 50 minvalue 1 maxvalue 9223372036854775806 
  increment by 1 cache 1000 nocycle ENGINE=InnoDB

```

Notes
-----

 If you want to see the underlying table structure used for the `SEQUENCE` you can use [SHOW CREATE TABLE](../show-create-table/index) on the `SEQUENCE`. You can also use `SELECT` to read the current recorded state of the `SEQUENCE`:

 
```
SHOW CREATE TABLE s1\G
*************************** 1. row ***************************
       Table: s1
Create Table: CREATE TABLE `s1` (
  `next_not_cached_value` bigint(21) NOT NULL,
  `minimum_value` bigint(21) NOT NULL,
  `maximum_value` bigint(21) NOT NULL,
  `start_value` bigint(21) NOT NULL COMMENT 'start value when sequences is created 
     or value if RESTART is used',
  `increment` bigint(21) NOT NULL COMMENT 'increment value',
  `cache_size` bigint(21) unsigned NOT NULL,
  `cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 
     1 if the sequence should begin a new cycle when maximum_value is passed',
  `cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=InnoDB SEQUENCE=1

SELECT * FROM s1\G
*************************** 1. row ***************************
next_not_cached_value: 50
        minimum_value: 1
        maximum_value: 9223372036854775806
          start_value: 50
            increment: 1
           cache_size: 1000
         cycle_option: 0
          cycle_count: 0

```

See Also
--------

 * [CREATE SEQUENCE](../create-sequence/index)
* [ALTER SEQUENCE](../alter-sequence/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-sequence/>

Spider mysql Database Tables
=============================

   The [Spider storage engine](../spider/index) installs the following system tables in the `mysql` database.

  

| Title | Description |
| --- | --- |
|  [mysql.spider\_link\_failed\_log Table](../mysqlspider_link_failed_log-table/index) |  The mysql.spider\_link\_failed\_log table.  |
|  [mysql.spider\_link\_mon\_servers Table](../mysqlspider_link_mon_servers-table/index) |  The mysql.spider\_link\_mon\_servers table.  |
|  [mysql.spider\_tables Table](../mysqlspider_tables-table/index) |  The mysql.spider\_tables table.  |
|  [mysql.spider\_table\_crd Table](../mysqlspider_table_crd-table/index) |  The mysql.spider\_table\_crd table.  |
|  [mysql.spider\_table\_position\_for\_recovery Table](../mysqlspider_table_position_for_recovery-table/index) |  The mysql.spider\_table\_position\_for\_recovery table.  |
|  [mysql.spider\_table\_sts Table](../mysqlspider_table_sts-table/index) |  The mysql.spider\_table\_sts table.  |
|  [mysql.spider\_xa Table](../mysqlspider_xa-table/index) |  The mysql.spider\_xa table.  |
|  [mysql.spider\_xa\_failed\_log Table](../mysqlspider_xa_failed_log-table/index) |  The mysql.spider\_xa\_failed\_log table.  |
|  [mysql.spider\_xa\_member Table](../mysqlspider_xa_member-table/index) |  The mysql.spider\_xa\_member table.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-mysql-database-tables/>

Spider Storage Engine Overview
==============================

    About
-----

 ![spider_overview]

 The Spider storage engine is a [storage engine](../storage-engines/index) with built-in sharding features. It supports partitioning and [xa transactions](../xa-transactions/index), and allows tables of different MariaDB 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.

 When a table is created with the Spider storage engine, the table links to the table on a remote server. The remote table can be of any storage engine. The table link is concretely achieved by the establishment of the connection from a local MariaDB server to a remote MariaDB server. The link is shared for all tables that are part of a the same transaction.

 
The Spider documentation on the MariaDB Knowledge Base is currently incomplete. See the Spider website for more: <http://spiderformysql.com/>, as well as the [spider-1.0-doc](http://bazaar.launchpad.net/~kentokushiba/spiderformysql/spider-1.0-doc/files) and [spider-2.0-doc](http://bazaar.launchpad.net/~kentokushiba/spiderformysql/spider-2.0-doc/files) repositories.

 
Spider Versions in MariaDB
--------------------------

 


| Spider Version | Introduced | Maturity |
| --- | --- | --- |
| Spider 3.3.15 | [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) | Stable |
| Spider 3.3.15 | [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/) | Gamma |
| Spider 3.3.14 | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) | Stable |
| Spider 3.3.13 | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) | Stable |
| Spider 3.3.13 | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) | Gamma |
| Spider 3.2.37 | [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/), [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/) | Gamma |
| Spider 3.2.21 | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/), [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) | Gamma |
| Spider 3.2.18 | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) | Gamma |
| Spider 3.2.11 | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) | Gamma |
| Spider 3.2.4 | [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/) | Gamma |
| Spider 3.2 | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) | Gamma |
| Spider 3.0 | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) | Beta |

  ### Some Server Variables to Set When Using Spider

 
**MariaDB starting with [10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/)**If you are using Spider with [replication](../replication/index), you can expand the list of transaction errors to be retried by setting [slave\_transaction\_retry\_errors](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_errors) to the following to avoid network problems:

 * 1158: Got an error reading communication packets
* 1159: Got timeout reading communication packets
* 1160: Got an error writing communication packets
* 1161: Got timeout writing communication packets
* 1429: Unable to connect to foreign data source
* 2013: Lost connection to MySQL server during query
* 12701: Remote MySQL server has gone away

 Do this as follows in your my.cnf file:

 
```
slave_transaction_retry_errors="1158,1159,1160,1161,1429,2013,12701"

```

From [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), the above is included the default.

 
Usage
-----

 ### Basic Usage

 To create a table in the Spider storage engine format, the COMMENT and/or CONNECTION clauses of the [CREATE TABLE](../create-table/index) statement are used to pass connection information about the remote server.

 For example, the following table exists on a remote server (in this example, the remote node was created with the [MySQL Sandbox](../mysql-sandbox/index) tool, an easy way to test with multiple installations)::

 
```
node1 >CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id));

```

On the local server, a Spider table can be created as follows:

 
```
CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id)
)
ENGINE=SPIDER 
COMMENT 'host "127.0.0.1", user "msandbox", password "msandbox", port "8607"';

```

Records can now be inserted on the local server, and they will be stored on the remote server:

 
```
INSERT INTO s(code) VALUES ('a');

node1 > SELECT * FROM s;
+----+------+
| id | code |
+----+------+
|  1 | a    |
+----+------+

```


**MariaDB starting with [10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/)**Alternative to specifying the data node information in the COMMENT, certain information (server, database, table) can also be specified using Table Options, like so:

 
```
CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS(
  HOST '127.0.0.1',
  USER 'msandbox',
  PASSWORD 'msandbox',
  PORT 8607);

CREATE TABLE s(
  id INT NOT NULL AUTO_INCREMENT,
  code VARCHAR(10),
  PRIMARY KEY(id)
)
ENGINE=SPIDER REMOTE_SERVER="srv" REMOTE_DATABASE="db" REMOTE_TABLE="s";

```


### Further Examples

 Preparing 10M record table using the [sysbench](http://sysbench.sourceforge.net/) utility 

 
```
/usr/local/skysql/sysbench/bin/sysbench --test=oltp  --db-driver=mysql  --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.202 --mysql-port=5054 --oltp-table-size=10000000  --mysql-db=test  prepare

```

Make a first read only benchmark to check the initial single node performance.

 
```
/usr/local/skysql/sysbench/bin/sysbench --test=oltp  --db-driver=mysql  --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.202 --mysql-port=5054 --mysql-db=test --oltp-table-size=10000000 --num-threads=4 --max-requests=100000 --oltp-read-only=on run

```


```
sysbench 0.4.12:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 4

Doing OLTP test.
Running mixed OLTP test
Doing read-only test
Using Special distribution (12 iterations,  1 pct of values are returned in 75 pct cases)
Using "BEGIN" for starting transactions
Using auto_inc on the id column
Maximum number of requests for OLTP test is limited to 100000
Threads started!
Done.

OLTP test statistics:
    queries performed:
        read:                            1400196
        write:                           0
        other:                           200028
        total:                           1600224
    transactions:                        100014 (1095.83 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 1400196 (15341.58 per sec.)
    other operations:                    200028 (2191.65 per sec.)

Test execution summary:
    total time:                          91.2681s
    total number of events:              100014
    total time taken by event execution: 364.3693
    per-request statistics:
         min:                                  1.85ms
         avg:                                  3.64ms
         max:                                 30.70ms
         approx.  95 percentile:               4.66ms

Threads fairness:
    events (avg/stddev):           25003.5000/84.78
    execution time (avg/stddev):   91.0923/0.00

```

Define an easy way to access the nodes from the MariaDB or MySQL client.

 
```
alias backend1='/usr/local/skysql/mysql-client/bin/mysql  --user=skysql --password=skyvodka --host=192.168.0.202 --port=5054'
alias backend2='/usr/local/skysql/mysql-client/bin/mysql  --user=skysql --password=skyvodka --host=192.168.0.203 --port=5054' 
alias spider1='/usr/local/skysql/mysql-client/bin/mysql  --user=skysql --password=skyvodka --host=192.168.0.201 --port=5054' 

```

Create the empty tables to hold the data and repeat for all available backend nodes.

 
```
backend1 << EOF 
CREATE DATABASE backend;
CREATE TABLE backend.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF

backend2 << EOF 
CREATE DATABASE backend;
CREATE TABLE backend.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF

```

#### Federation Setup

 ![Spider7]

 
```
spider1 << EOF
CREATE SERVER backend 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.202', 
  DATABASE 'test',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);

CREATE  TABLE test.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql",srv "backend"';
SELECT * FROM test.sbtest LIMIT 10;
EOF

```

![spbench10]

 Without connection pool or MariaDB thread pool, HaProxy and Spider have been protecting the tcp socket overflow without specific TCP tuning. In reality with a well tuned TCP stack or thread pool the curve should not decrease so abruptly to 0. Refer to the [MariaDB Thread Pool](../threadpool-in-55/index) to explore this feature. 

 #### Sharding Setup

 ![spider8]

 Create the spider table on the Spider Node 

 
```
#spider1 << EOF
CREATE SERVER backend1 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.202', 
  DATABASE 'backend',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE SERVER backend2 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.203', 
  DATABASE 'backend',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE DATABASE IF NOT EXISTS backend;
CREATE  TABLE backend.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1"',
 PARTITION pt2 COMMENT = 'srv "backend2"' 
) ;
EOF

```

Copy the data from the original sysbench table to the spider table

 
```
#/usr/local/skysql/mariadb/bin/mysqldump  --user=skysql --password=skyvodka --host=192.168.0.202 --port=5054 --no-create-info test sbtest | spider1 backend 

#backend2 -e"select count(*) from backend.sbtest;"
+----------+
| count(*) |
+----------+
|  3793316 |
+----------+
#backend1 -e"select count(*) from backend.sbtest;"
+----------+
| count(*) |
+----------+
|  6206684 |
+----------+

```

We observe a common issue with partitioning is a non uniform distribution of data between the backends. based on the partition key hashing algorithm.

 Rerun the Benchmark with less queries 

 
```
#/usr/local/skysql/sysbench/bin/sysbench --test=oltp  --db-driver=mysql  --mysql-table-engine=innodb --mysql-user=skysql --mysql-password=skyvodka --mysql-host=192.168.0.201 --mysql-port=5054 --mysql-db=backend --mysql-engine-trx=yes --oltp-table-size=10000000 --num-threads=4 --max-requests=100 --oltp-read-only=on run

```


```
OLTP test statistics:
    queries performed:
        read:                            1414
        write:                           0
        other:                           202
        total:                           1616
    transactions:                        101    (22.95 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 1414   (321.30 per sec.)
    other operations:                    202    (45.90 per sec.)

Test execution summary:
    total time:                          4.4009s
    total number of events:              101
    total time taken by event execution: 17.2960
    per-request statistics:
         min:                                114.48ms
         avg:                                171.25ms
         max:                                200.98ms
         approx.  95 percentile:             195.12ms

Threads fairness:
    events (avg/stddev):           25.2500/0.43
    execution time (avg/stddev):   4.3240/0.04

```

The response time decreases to 0.04. This is expected because the query latency is increased from multiple network round trips and condition push down is not implemented yet. Sysbench doing a lot of range queries. Just consider for now that this range query can be a badly optimized query. 

 We need to increase the concurrency to get better throughput. 

 ![spbench11]

 #### Background Setup

 We have no background search available in MariaDB. It won't be available before [MariaDB 10.2](../what-is-mariadb-102/index), but the next table definition mainly enables improving the performance of a single complex query plan with background search that can be found via the upstream spiral binaries MariaDB branch. 

 We have 4 cores per backend and 2 backends . 

 On `backend1` 

 
```
#backend1 << EOF 
CREATE DATABASE bsbackend1;
CREATE DATABASE bsbackend2;
CREATE DATABASE bsbackend3;
CREATE DATABASE bsbackend4;
CREATE TABLE bsbackend1.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend2.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend3.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend4.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF

```

On `backend2` 

 
```
#backend2 << EOF 
CREATE DATABASE bsbackend5;
CREATE DATABASE bsbackend6;
CREATE DATABASE bsbackend7;
CREATE DATABASE bsbackend8;
CREATE TABLE bsbackend5.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend6.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend7.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
CREATE TABLE bsbackend8.sbtest (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=InnoDB;
EOF

```

On `Spider Node`

 
```
#spider2 << EOF
CREATE SERVER bsbackend1 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.202', DATABASE 'bsbackend1',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend2 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.202', DATABASE 'bsbackend2',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend3 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.202', DATABASE 'bsbackend3',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend4 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.202', DATABASE 'bsbackend4',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend5 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.203', DATABASE 'bsbackend5',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend6 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.203', DATABASE 'bsbackend6',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend7 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.203', DATABASE 'bsbackend7',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);
CREATE SERVER bsbackend8 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.0.203', DATABASE 'bsbackend8',USER 'skysql', PASSWORD 'skyvodka',PORT 5054);

CREATE DATABASE IF NOT EXISTS bsbackend;
CREATE  TABLE bsbackend.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "bsbackend1"',
 PARTITION pt2 COMMENT = 'srv "bsbackend2"', 
 PARTITION pt3 COMMENT = 'srv "bsbackend3"',
 PARTITION pt4 COMMENT = 'srv "bsbackend4"', 
 PARTITION pt5 COMMENT = 'srv "bsbackend5"',
 PARTITION pt6 COMMENT = 'srv "bsbackend6"',
 PARTITION pt7 COMMENT = 'srv "bsbackend7"',
 PARTITION pt8 COMMENT = 'srv "bsbackend8"'
) ;
EOF
INSERT INTO  bsbackend.sbtest SELECT * FROM backend.sbtest;

```

Now test the following query :

 
```
select count(*) from sbtest;
+----------+
| count(*) |
+----------+
| 10000001 |
+----------+
1 row in set (8,38 sec)

set spider_casual_read=1;
set spider_bgs_mode=2;

select count(*) from sbtest;
+----------+
| count(*) |
+----------+
| 10000001 |
+----------+
1 row in set (4,25 sec)

mysql> select sum(k) from sbtest;
+--------+
| sum(k) |
+--------+
|      0 |
+--------+
1 row in set (5,67 sec)

mysql> set spider_casual_read=0;
mysql> select sum(k) from sbtest;
+--------+
| sum(k) |
+--------+
|      0 |
+--------+
1 row in set (12,56 sec)

```

![spbench8]

 #### High Availability Setup

 ![spider9]

 
```
#backend1 -e "CREATE DATABASE backend_rpl"
#backend2 -e "CREATE DATABASE backend_rpl"

#/usr/local/skysql/mariadb/bin/mysqldump  --user=skysql --password=skyvodka --host=192.168.0.202 --port=5054  backend sbtest | backend1 backend_rpl
#/usr/local/skysql/mariadb/bin/mysqldump  --user=skysql --password=skyvodka --host=192.168.0.203 --port=5054  backend sbtest | backend2 backend_rpl

#spider1 << EOF
DROP TABLE backend.sbtest;
CREATE SERVER backend1_rpl 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.202', 
  DATABASE 'backend_rpl',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE SERVER backend2_rpl 
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.203', 
  DATABASE 'backend_rpl',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
CREATE  TABLE backend.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1 backend2_rpl"',
 PARTITION pt2 COMMENT = 'srv "backend2 backend1_rpl"' 
) ;
INSERT INTO backend.sbtest select 10000001, 0, '' ,'replicas test';
EOF
#backend1 -e "SELECT * FROM backend.sbtest WHERE id=10000001";
+----------+---+---+---------------+
| id       | k | c | pad           |
+----------+---+---+---------------+
| 10000001 | 0 |   | replicas test |
+----------+---+---+---------------+
# backend2 -e "SELECT * FROM backend.sbtest where id=10000001";
# backend2 -e "SELECT * FROM backend_rpl.sbtest where id=10000001";
+----------+---+---+---------------+
| id       | k | c | pad           |
+----------+---+---+---------------+
| 10000001 | 0 |   | replicas test |
+----------+---+---+---------------+

```

What is happening if we stop one backend?

 
```
#spider1 -e "SELECT * FROM backend.sbtest where id=10000001";
ERROR 1429 (HY000) at line 1: Unable to connect to foreign data source: backend1

```

Let's fix this with spider monitoring. Note that msi is the list of spider nodes @@server\_id variable participating in the quorum. 

 
```
#spider1 << EOF
DROP  TABLE backend.sbtest;
CREATE  TABLE backend.sbtest
(
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1 backend2_rpl",  mbk "2", mkd "2", msi "5054", link_status "0 0"',
 PARTITION pt2 COMMENT = 'srv "backend2 backend1_rpl",  mbk "2", mkd "2", msi "5054", link_status "0 0" ' 
) ;

CREATE SERVER mon
  FOREIGN DATA WRAPPER mysql 
OPTIONS( 
  HOST '192.168.0.201’, 
  DATABASE 'backend',
  USER 'skysql',
  PASSWORD 'skyvodka',
  PORT 5054
);
INSERT INTO `mysql`.`spider_link_mon_servers` VALUES
('%','%','%',5054,'mon',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL);
SELECT spider_flush_table_mon_cache();
EOF

```

Monitoring should be setup between Spider nodes participating in the cluster. We only have one `Spider Node` and spider\_link\_mon\_servers represent the inter-connection of all Spider nodes in our setup. 

 This simple setup does not bring HA in case the `Spider Node` is not available. In a production setup the number of `Spider Nodes` in the spider\_link\_mon\_servers table should be at least 3 to get a majority consensus.

 
```
#spider1 -e "SELECT * FROM backend.sbtest WHERE id=10000001"
+----------+---+---+---------------+
| id       | k | c | pad           |
+----------+---+---+---------------+
| 10000001 | 0 |   | replicas test |
+----------+---+---+---------------+

```

Checking the state of the nodes:

 
```
#spider1 -e "SELECT db_name, table_name,server  FROM mysql.spider_tables WHERE link_status=3"
+---------+--------------+----------+
| db_name | table_name   | server   |
+---------+--------------+----------+
| backend | sbtest#P#pt1 | backend1 |
+---------+--------------+----------+

```

![spiderha]

 No change has been made to cluster, so let's create a divergence:

 
```
# spider1 -e "INSERT INTO backend.sbtest select 10000003, 0, '' ,'replicas test';"
# backend1 -e "SELECT * FROM backend.sbtest WHERE id=10000003"
# backend2 -e "SELECT * FROM backend_rpl.sbtest WHERE id=10000003"
+----------+---+---+---------------+
| id       | k | c | pad           |
+----------+---+---+---------------+
| 10000003 | 0 |   | replicas test |
+----------+---+---+---------------+

```

Reintroducing the failed backend1 in the cluster:

 
```
#spider1 << EOF
ALTER TABLE backend.sbtest 
ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1 backend2_rpl"  mbk "2", mkd "2", msi "5054", link_status "2 0"',
 PARTITION pt2 COMMENT = 'srv "backend2 backend1_rpl"  mbk "2", mkd "2", msi "5054", link_status "0 2" ' 
) ;
select spider_copy_tables('backend.sbtest#P#pt1','0','1');
select spider_copy_tables('backend.sbtest#P#pt2','1','0');
ALTER TABLE backend.sbtest 
ENGINE=spider COMMENT='wrapper "mysql", table "sbtest"'
 PARTITION BY KEY (id) 
(
 PARTITION pt1 COMMENT = 'srv "backend1 backend2_rpl"  mbk "2", mkd "2", msi "5054", link_status "1 0"',
 PARTITION pt2 COMMENT = 'srv "backend2 backend1_rpl"  mbk "2", mkd "2", msi "5054", link_status "0 1" ' 
) ;
EOF

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-storage-engine-overview/>

Spider Installation
===================

    The Spider storage engine supports partitioning and XA transactions, and allows tables of different MariaDB instances to be handled as if they were on the same instance.

 To use Spider, you need two or more instances of MariaDB, typically running on separate hosts. The Spider node is the MariaDB server that receives queries from your application. It then processes these queries, connecting to one or more data nodes. The data nodes are the MariaDB servers that actually store the table data.

 In order for this to work, you need to configure the data nodes to accept queries from the Spider node and you need to configure the Spider node to use the data nodes as remote storage. 

 You don't need to install any additional packages to use it, but it does require some configuration.

 Configuring Data Nodes
----------------------

 Spider deployments use data nodes to store the actual table data. In order for a MariaDB server to operate as a data node for Spider, you need to create a table or tables on which to store the data and configure the server to accept client connections from the Spider node.

 For instance, first create the table:

 
```
CREATE TABLE test.spider_example (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(50)
) ENGINE=InnoDB;

```

Next, create a user for the Spider node and set a password for that user. For the sake of the example, assume the Spider node is at the IP address 192.168.1.1:

 
```
CREATE USER spider@192.168.1.1;

SET PASSWORD FOR spider@192.168.1.1 = PASSWORD('passwd');

```

Then grant the `spider` user privileges on the example table.

 
```
GRANT ALL ON test.spider_example TO spider@192.168.1.1;

```

The data node is now ready for use. You can test it by attempting to connect the MariaDB client to the data from the Spider node. For instance, assuming the data node is at the IP address 192.168.1.5, SSH into the Spider node then try to establish a client connection.

 
```
$ mysql -u spider -p -h 192.168.1.5 test -e "SHOW TABLES;"

+----------------+
| Tables_in_test |
+----------------+
| spider_example |
+----------------+

```

Install Spider on Spider Node
-----------------------------

 The Spider storage engine must be installed on the Spider node. The Spider node is the MariaDB server that receives queries for the table, (in this case `test.spider_example`). It then uses the Spider storage engine to connect to the tables on the data nodes to retrieve data and return the result-set.

 To install the Spider storage engine, complete the installation process shown below.

 ### Step 1: Install Spider Package (Debian/Ubuntu)

 On Debian and Ubuntu, the Spider storage engine is installed via a separate `mariadb-plugin-spider` package. To install the package via APT, execute the following command:

 
```
$ sudo apt install mariadb-plugin-spider

```

On other Linux distributions, the Spider storage engine is installed with MariaDB Server.

 ### Step 2a: Load the Spider Plugin ([MariaDB 10.4](../what-is-mariadb-104/index) and Later)

 With [MariaDB 10.4](../what-is-mariadb-104/index) and later, the Spider storage engine can be loaded as a normal plugin, and Spider automatically creates its dependencies. There are two primary ways to load the plugin.

 The plugin can be loaded dynamically without a server restart by executing `INSTALL SONAME` or `INSTALL PLUGIN`:

 
```
INSTALL SONAME "ha_spider";

```

Alternatively, the plugin can be loaded by adding `plugin_load_add=ha_spider` to a configuration file:

 
```
<<quote>>
[mariadb]
...
plugin_load_add = "ha_spider"
<</quote>>
```

If the plugin is loaded in a configuration file, then the server will load the plugin after the server has been restarted.

 Loading the plugin also creates a series of new tables in the `mysql` database, including:

 


| table name | added version |
| --- | --- |
| spider\_xa | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_xa\_member | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_xa\_failed\_log | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| spider\_tables | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_link\_mon\_servers | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_link\_failed\_log | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_table\_position\_for\_recovery | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| spider\_table\_sts | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| spider\_table\_crd | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |

 
### Step 2b: Load the Spider Plugin ([MariaDB 10.3](../what-is-mariadb-103/index) and Before)

 With [MariaDB 10.3](../what-is-mariadb-103/index) and before, the Spider storage engine can be loaded by executing the included `install_spider.sql` script:

 
```
$ mysql --user root --password < /usr/share/mysql/install_spider.sql

```

Running this configuration script also creates a series of new tables in the `mysql` database, including:

 


| table name | added version |
| --- | --- |
| spider\_xa | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_xa\_member | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_xa\_failed\_log | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| spider\_tables | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_link\_mon\_servers | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_link\_failed\_log | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| spider\_table\_position\_for\_recovery | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| spider\_table\_sts | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| spider\_table\_crd | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |

 
### Step 3: Verify Loading of the Spider Plugin

 You can verify that the Spider plugin has been loaded by querying the `information_schema.ENGINES` table:

 
```
SELECT ENGINE, SUPPORT
FROM information_schema.ENGINES
WHERE ENGINE = 'SPIDER';

+--------------------+---------+
| ENGINE             | SUPPORT |
+--------------------+---------+
| SPIDER             | YES     |
+--------------------+---------+

```

If the Spider plugin is not loaded, then the query will not return any results. 

 Configuring Spider Nodes
------------------------

 With the data node or data nodes configured, you can set up the Spider node to use them. The Spider node is the MariaDB server that receives queries for the table, (in this case `test.spider_example`). It then uses the Spider storage engine to connect to the tables on the data nodes to retrieve data and return the result-set.

 ### Configure the Server

 In order to connect the Spider node to the data nodes, you need to issue a `[CREATE SERVER](../create-server/index)` statement for each data node. You can then use the server definition in creating the Spider table.

 
```
CREATE SERVER dataNode1 FOREIGN DATA WRAPPER mysql
OPTIONS (
   HOST '192.168.1.5',
   DATABASE 'test',
   USER 'spider',
   PASSWORD 'passwd',
   PORT 3306);

```

In the event that you need to modify or replace this server after setting up the Spider table, remember to issue a `[FLUSH](../flush/index)` statement to update the server definition. 

 
```
FLUSH TABLES;

```

### Create the Table

 With the data nodes set up and the Spider node configured for use, you can create the Spider table. The Spider table must have the same column definitions as the InnoDB tables on the data nodes. Spider is configured through table system variables passed to the `COMMENT` option.

 
```
CREATE TABLE test.spider_example (
   id INT PRIMARY KEY AUTO_INCREMENT,
   name VARCHAR(50)
) ENGINE=Spider
COMMENT='wrapper "mysql", srv "dataNode1", table "spider_example"';

```

This configures Spider to use the server `dataNode1`, (defined above), as a remote table. Any data you write to this table is actually stored on the MariaDB server at 192.168.1.5.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-installation/>

Spider Use Cases
================

    Introduction
============

 This article will cover simple working examples for some standard use cases for Spider. The example will be illustrated using a sales opportunities table to be consistent throughout. In some cases the actual examples will be contrived but are used to illustrate the varying syntax options.

 Basic setup
===========

 Have 3 or more servers available and Install MariaDB on each of these servers:

 * **spider** server which will act as the front end server hosting the spider storage engine.
* **backend1** which will act as a backed server storing data
* **backend2** which will act as a second backend server storing data

 Follow the instructions [here](../spider-storage-engine-overview/index#installing) to enable the Spider storage engine on the spider server:

 
```
mysql  -u root -p < /usr/share/mysql/install_spider.sql

```

Enable use of non root connections
----------------------------------

 When using the [General Query Log](../general-query-log/index), non-root users may encounter issues when querying Spider tables. Explicitly setting the `[spider\_internal\_sql\_log\_off](../spider-server-system-variables/index#spider_internal_sql_log_off)` system variable causes the Spider node to execute `SET sql_log_off` statements on the data nodes to enable or disable the General Query Log. When this is done, queries issued by users without the `SUPER` privilege raise an error.

 To avoid this, don't explicitly set the `[spider\_internal\_sql\_log\_off](../spider-server-system-variables/index#spider_internal_sql_log_off)` system variable.

 Create accounts for spider to connect with on backend servers
-------------------------------------------------------------

 Spider needs a remote connection to the backend server to actually perform the remote query. So this should be setup on each backend server. In this case 172.21.21.2 is the ip address of the spider node limiting access to just that server.

 
```
backend1> mysql
grant all on test.* to spider@'172.21.21.2' identified by 'spider';
backend2> mysql
grant all on test.* to spider@'172.21.21.2' identified by 'spider';

```

Now verify that these connections can be used from the spider node (here 172.21.21.3 = backend1 and 172.21.21.4 = backend2):

 
```
spider> mysql -u spider -p -h 172.21.21.3 test
spider> mysql -u spider -p -h 172.21.21.4 test

```

Create table on backend servers
-------------------------------

 The table definition should be created in the test database on both backend1 and backend2 servers:

 
```
create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11),
primary key (id),
key (accountName)
) engine=InnoDB;

```

Create server entries on spider server
--------------------------------------

 While the connection information can also be specified inline in the comment, it is cleaner to define a server object representing each remote backend server connection:

 
```
create server backend1 foreign data wrapper mysql options 
(host '172.21.21.3', database 'test', user 'spider', password 'spider', port 3306);
create server backend2 foreign data wrapper mysql options 
(host '172.21.21.4', database 'test', user 'spider', password 'spider', port 3306);

```

### Unable to Connect Errors

 Bear in mind, if you ever need to remove, recreate or otherwise modify the server definition for any reason, you need to also execute a `FLUSH TABLES` statement. Otherwise, Spider continues to use the old server definition, which can result in queries raising the error 

 
```
Error 1429: Unable to connect to foreign data source

```

If you encounter this error when querying Spider tables, issue a `FLUSH TABLES` statement to update the server definitions.

 
```
FLUSH TABLES;

```

Use case 1: remote table
========================

 In this case, a spider table is created to allow remote access to the opportunities table hosted on backend1. This then allows for queries and remote dml into the backend1 server from the spider server:

 
```
create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11),
primary key (id),
key (accountName)
) engine=spider comment='wrapper "mysql", srv "backend1" , table "opportunities"';

```

Use case 2: sharding by hash
============================

 In this case a spider table is created to distribute data across backend1 and backend2 by hashing the id column. Since the id column is an incrementing numeric value the hashing will ensure even distribution across the 2 nodes.

 
```
create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11),
primary key (id),
key (accountName)
) engine=spider COMMENT='wrapper "mysql", table "opportunities"'
 PARTITION BY HASH (id)
(
 PARTITION pt1 COMMENT = 'srv "backend1"',
 PARTITION pt2 COMMENT = 'srv "backend2"'
) ;

```

Use case 3: sharding by range
=============================

 In this case a spider table is created to distribute data across backend1 and backend2 based on the first letter of the accountName field. All accountNames that start with the letter L and prior will be stored in backend1 and all other values stored in backend2. Note that the accountName column must be added to the primary key which is a requirement of MariaDB partitioning:

 
```
create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11),
primary key (id, accountName),
key(accountName)
) engine=spider COMMENT='wrapper "mysql", table "opportunities"'
 PARTITION BY range columns (accountName)
(
 PARTITION pt1 values less than ('M') COMMENT = 'srv "backend1"',
 PARTITION pt2 values less than (maxvalue) COMMENT = 'srv "backend2"'
) ;

```

Use case 4: sharding by list
============================

 In this case a spider table is created to distribute data across backend1 and backend2 based on specific values in the owner field. Bill, Bob, and Chris will be stored in backend1 and Maria and Olivier stored in backend2. Note that the owner column must be added to the primary key which is a requirement of MariaDB partitioning:

 
```
create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11),
primary key (id, owner),
key(accountName)
) engine=spider COMMENT='wrapper "mysql", table "opportunities"'
 PARTITION BY list columns (owner)
(
 PARTITION pt1 values in ('Bill', 'Bob', 'Chris') COMMENT = 'srv "backend1"',
 PARTITION pt2 values in ('Maria', 'Olivier') COMMENT = 'srv "backend2"'
) ;

```

With [MariaDB 10.2](../what-is-mariadb-102/index) the following partition clause can be used to specify a default partition for all other values, however this must be a distinct partition / shard:

 
```
PARTITION partition_name DEFAULT

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-use-cases/>

Spider Cluster Management
=========================

    Direct SQL
----------

 Direct SQL is a way to map reduced execution on remote backends and store the results in a local table. This can either be sequential, using the UDF function [spider\_direct\_sql](../spider_direct_sql/index), or concurrently, using [spider\_bg\_direct\_sql](../spider_bg_direct_sql/index).   
  


 
```
spider1 backend << EOF 
CREATE TEMPORARY TABLE res
(
  id int(10) unsigned NOT NULL,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT ''
) ENGINE=MEMORY;
 
SELECT spider_direct_sql(
'SELECT * FROM sbtest s  WHERE s.id IN(10,12,13)',
  'res',   
  concat('host "', host, '", port "', port, '", user "', username, '", password "', password, '", database "', tgt_db_name, '"')
) a 
FROM 
  mysql.spider_tables 
WHERE 
  db_name = 'backend' and table_name like 'sbtest#P#pt%';

SELECT * FROM res; 
EOF

```

Or if you are using a [SERVER](../create-server/index):

 
```
SELECT spider_direct_sql( 
  'SELECT * FROM sbtest s  WHERE s.id IN(10,12,13)',
  'res',
  concat('server "', server, '"')
) a
  FROM mysql.spider_tables
  WHERE db_name = 'backend' and table_name like 'sbtest#P#pt%' ;

```

The default for [spider\_bg\_direct\_sql](../spider_bg_direct_sql/index) is to access concurrently all backends. If you have multiple partitions store inside a single backend, you still can increase parallelism affecting different channels to each partitions.

 
```
CREATE TEMPORARY TABLE res
(
  id int(10) unsigned NOT NULL , 
  col_microsec DATETIME(6) default NOW(8),
  db varchar(20)
) ENGINE=MEMORY;

SELECT spider_bg_direct_sql( 'SELECT count(*) ,min(NOW(6)),min(DATABASE())) FROM sbtest',   'res',  concat('srv "', server,'" cch ',@rn:=@rn+1  ) ) a  FROM    mysql.spider_tables,(SELECT @rn:=1) t2  WHERE    db_name = 'bsbackend' and table_name like 'sbtest#P#pt%';

```

Direct Handler Socket
---------------------

 Check that [Handler Socket](../handlersocket/index) is running on the backend nodes 

 
```
:~# backend2 -e "show variables like 'handler%'"
+-------------------------------+---------------+
| Variable_name                 | Value         |
+-------------------------------+---------------+
| handlersocket_accept_balance  | 0             |
| handlersocket_address         | 192.168.0.201 |
| handlersocket_backlog         | 32768         |
| handlersocket_epoll           | 1             |
| handlersocket_plain_secret    |               |
| handlersocket_plain_secret_wr |               |
| handlersocket_port            | 20500         |
| handlersocket_port_wr         | 20501         |
| handlersocket_rcvbuf          | 0             |
| handlersocket_readsize        | 0             |
| handlersocket_sndbuf          | 0             |
| handlersocket_threads         | 4            |
| handlersocket_threads_wr      | 1             |
| handlersocket_timeout         | 300           |
| handlersocket_verbose         | 10            |
| handlersocket_wrlock_timeout  | 12            |
+-------------------------------+---------------+

```


```
spider1 backend << EOF 
CREATE TEMPORARY TABLE res
(
  id int(10) unsigned NOT NULL,
  k int(10) unsigned NOT NULL DEFAULT '0',
  c char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT ''
) ENGINE=MEMORY;
 
SELECT spider_direct_sql('1\t=\t1\t2\t100000\t0','res', 'host "192.168.0.202", table "sbtest", database "test", port "20500", access_mode "1"');

```

Inter Nodes Copy Table
----------------------

 The UDF function [spider\_copy\_tables](../spider_copy_tables/index) is available for copying table data from the source link ID to the destination link ID list without stopping your service for copying

 `spider_copy_tables(Spider table name, source link ID, destination link ID list[, parameters])`

 * `Returns 1` if copying data succeeded.
* `Returns 0` if copying data failed.

 If the Spider table is partitioned, you must set "Spider table name" with a part name such as "table\_name#P#part\_name". 

 You can check the table name and the link ID with the part name using the following SQL:

 
```
SELECT table_name FROM mysql.spider_tables;

```

Resharding
----------

 General Log
-----------

 To capture all queries sent to remote backends on a `Spider Node` :

 
```
SET GLOBAL general_log=ON; 
SET GLOBAL spider_general_log=ON;
SET GLOBAL spider_log_result_errors=1;
SET GLOBAL spider_log_result_error_with_sql=3;

```

Compiling in Debug Mode
-----------------------

 Compile MariaDB in debug mode 

 
```
#cmake -DBUILD_CONFIG=mysql_release -DCMAKE_BUILD_TYPE=Debug  -DWITH_FAST_MUTEXES=ON  -DWITH_VALGRIND=ON

```

Run MariaDB the following way to have a detailed command trace file 

 
```
mysqld --debug=S:T:t:r:p:n:L:i:F:f:D:d,info,error,query,qcache,my,exit,general,where:O,/tmp/mysqld.trace 

```

Or with Valgrind to get a complete stack trace on a crash.

 
```
valgrind /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/inetbase/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/inetbase/mysql/lucifer.err --open-files-limit=65000 --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306

```

Report the issue in [MariaDB JIRA](https://jira.mariadb.org) (see [Reporting Bugs](../reporting-bugs/index)) or to the MariaDB Corporation support center.

 Compiling in Static
-------------------

 Available since version 3.1.14

 To activate spider as a static plugin change "MODULE\_ONLY" to "MANDATORY" in storage/spider/CMakeList.txt before compiling 

 Note that Spider UDF functions will not work with such settings. 

 Status Variables
----------------

 A number of new [status variables](../server-status-variables/index) have been introduced:

 * [Spider\_direct\_aggregate](../spider-server-status-variables/index#spider_direct_aggregate)
* [Spider\_direct\_order\_limit](../spider-server-status-variables/index#spider_direct_order_limit)
* [Spider\_mon\_table\_cache\_version](../spider-server-status-variables/index#spider_mon_table_cache_version)
* [Spider\_mon\_table\_cache\_version\_req](../spider-server-status-variables/index#spider_mon_table_cache_version_req)

 Information Schema Tables
-------------------------

 * A new [Information Schema](../information-schema/index) table is installed - [SPIDER\_ALLOC\_MEM](../information-schema-spider_alloc_mem-table/index).

 
```
+-------------------+---------------------+------+-----+---------+-------+
| Field             | Type                | Null | Key | Default | Extra |
+-------------------+---------------------+------+-----+---------+-------+
| ID                | int(10) unsigned    | NO   |     | 0       |       |
| FUNC_NAME         | varchar(64)         | YES  |     | NULL    |       |
| FILE_NAME         | varchar(64)         | YES  |     | NULL    |       |
| LINE_NO           | int(10) unsigned    | YES  |     | NULL    |       |
| TOTAL_ALLOC_MEM   | bigint(20) unsigned | YES  |     | NULL    |       |
| CURRENT_ALLOC_MEM | bigint(20)          | YES  |     | NULL    |       |
| ALLOC_MEM_COUNT   | bigint(20) unsigned | YES  |     | NULL    |       |
| FREE_MEM_COUNT    | bigint(20) unsigned | YES  |     | NULL    |       |
+-------------------+---------------------+------+-----+---------+-------+

```

Performance Schema
------------------

 The [Performance schema](../performance-schema/index) is commonly used to troubleshoot issues that consume time inside your workload. The Performance schema should not be activated for servers that are experimenting constant heavy load, but most of time it is acceptable to lose 5% to 20% additional CPU to keep track of server internals execution. 

 To activate the performance schema, use the [performance\_schema](../performance-schema-system-variables/index#performance_schema) system variable and add the following to the server section of the [MariaDB configuration file](../configuring-mariadb-with-mycnf/index).

 
```
performance_schema=on

```

Activate the Spider probes to be monitored. 

 
```
UPDATE performance_schema.setup_instruments SET 
  ENABLED='YES', TIMED='yes' WHERE NAME LIKE '%spider%';

```

Run your queries ...

 And check the performance metrics. Remove specific Spider metrics to have a more global view. 

 
```
SELECT * FROM performance_schema.events_waits_summary_global_by_event_name 
  WHERE COUNT_STAR<>0 AND EVENT_NAME LIKE '%spider%' 
  ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-cluster-management/>

Spider Feature Matrix
=====================

    Not complete yet - still being updated

 F(\*) Federation only , P(\*)partioning only . Spider column is for SpiderForMySQL found on the Spider web sIte. 

 


| Feature | Spider | 10.0 |
| --- | --- | --- |
| **Clustering and High Availability** |  |  |
| Commit, Rollback transactions on multiple backend | Yes | Yes |
| Multiplexing to a number of replicas using xa protocol 2PC | Yes | Yes |
| Split brain resolution based on a majority decision, failed node is remove from the list of replicas | Yes | Yes |
| Enable a failed backend to re enter the cluster transparently | No | No |
| Synchronize DDL to backend, table modification, schema changes | No | No |
| Synchronize DDL to other Spider | No | No |
| GTID tracking per table on XA error | No | Yes |
| Transparent partitioning | No | No |
| Covered by generic SQL test case | Yes | Yes |
| **Heterogenous Backends** |  |  |
| MariaDB and MySQL database backend | Yes | Yes |
| Oracle database backend, if build from source against the client library 'ORACLE\_HOME' | Yes | Yes |
| Local table attachment | Yes | Yes |
| **Performance** |  |  |
| Index Condition Pushdown | No | No |
| Engine Condition Pushdown | Yes | Yes |
| Concurrent backend scan | Yes | No |
| Concurrent partition scan | Yes | No |
| Batched key access | Yes | Yes |
| Block hash join | No | Yes |
| HANDLER backend propagation | Yes | Yes |
| HANDLER backend translation from SQL | Yes | Yes |
| HANDLER OPEN cache per connection | No | Yes |
| HANDLER use prepared statement | No | Yes |
| HANDLER\_SOCKET protocol backend propagation | Yes | Yes |
| HANDLER\_SOCKET backend translation from SQL | No | No |
| Map reduce for `ORDER BY` ... LIMIT | Yes | Yes |
| Map reduce for `MAX & MIN & SUM` | Yes | Yes |
| Map reduce for some `GROUP BY` | Yes | Yes |
| Batch multiple WRITES in auto commit to reduce network round trip | Yes | Yes |
| Relaxing backend consistency | Yes | Yes |
| **Execution Control** |  |  |
| Configuration at table and partition level, settings can change per data collection | Yes | Yes |
| Configurable empty result set on errors. For API that does not have transactions replay | Yes | Yes |
| Query Cache tuning per table of the on remote backend | Yes | Yes |
| Index Hint per table imposed on remote backend | Yes | Yes |
| SSL connections to remote backend connections | Yes | Yes |
| Table definition discovery from remote backend | Yes | F(\*) |
| Direct SQL execution to backend via UDF | Yes | Yes |
| Table re synchronization between backends via UDF | Yes | Yes |
| Maintain Index and Table Statistics of remote backends | Yes | Yes |
| Can use Independent Index and Table Statistics | No | Yes |
| Maintain local or remote table increments | Yes | Yes |
| LOAD DATA INFILE translate to bulk inserting | Yes | Yes |
| Performance Schema Probes | Yes | Yes |
| Load Balance Reads to replicate weight control | Yes | Yes |
| Fine tuning tcp timeout, connections retry | Yes | Yes |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-feature-matrix/>

Spider Table Parameters
=======================

    When a table uses the [Spider](../spider/index) storage engine, the following Spider table parameters can be set in the `COMMENT` clause of the [CREATE TABLE](../create-table/index) statement. Many Spider table parameters have corresponding system variables, so they can be set for all Spider tables on the node. For additional information, see the [Spider System Variables](../spider-server-system-variables/index) page. 

 #### `access_balances`

 * **Description:** Connection load balancing integer weight.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `abl`

 #### `active_link_count`

 * **Description:** Number of active remote servers, for use in load balancing read connections
* **Default Table Value:** `all backends`
* **DSN Parameter Name:** `alc`

 #### `casual_read`

 * **Description:**
* **Default Table Value:**
* **DSN Parameter Name:**
* **Introduced:** Spider 3.2

 #### `database`

 * **Description:** Database name for reference table that exists on remote backend server.
* **Default Table Value:** `local table database`
* **DSN Parameter Name:** `database`

 #### `default_file`

 * **Description:** Configuration file used when connecting to remote servers. When the `[default\_group](#default_group)` table variable is set, this variable defaults to the values of the `--defaults-extra-file` or `--defaults-file` options. When the `[default\_group](#default_group)` table variable is not set, it defaults to `none`.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `dff`

 #### `default_group`

 * **Description:** Group name in configuration file used when connecting to remote servers.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `dfg`

 #### `delete_all_rows_type`

 * **Description:**
* **Default Table Value:**
* **DSN Parameter Name:**
* **Introduced:** Spider 3.2

 #### `host`

 * **Description:** Host name of remote server.
* **Default Table Value:** `localhost`
* **DSN Parameter Name:** `host`

 #### `idx000`

 * **Description:** When using an index on Spider tables for searching, Spider uses this hint to search the remote table. The remote table index is related to the Spider table index by this hint. The number represented by `000` is the index ID, which is the number of the index shown by the `[SHOW CREATE TABLE](../show-create-table/index)` statement. `000` is the Primary Key. For instance, `idx000 "force index(PRIMARY)"` (in abbreviated format `idx000 "f PRIMARY"`).
	+ `f` force index
	+ `u` use index
	+ `ig` ignore index
* **Default Table Value:** `none`

 #### `internal_delayed`

 * **Description:** Whether to transmit existence of delay to remote servers when executing an `[INSERT DELAYED](../insert-delayed/index)` statement on local server.
	+ `0` Doesn't transmit.
	+ `1` Transmits.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `idl`

 #### `link_status`

 * **Description:** Change status of the remote backend server link.
	+ `0` Doesn't change status.
	+ `1` Changes status to `OK`.
	+ `2` Changes status to `RECOVERY`.
	+ `3` Changes status to no more in group communication.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `lst`

 #### `monitoring_bg_interval`

 * **Description:** Interval of background monitoring in microseconds.
* **Default Table Value:** `10000000`
* **DSN Parameter Name:** `mbi`

 ####  `monitoring_bg_kind`

 * **Description:** Kind of background monitoring to use.
	+ `0` Disables background monitoring.
	+ `1` Monitors connection state.
	+ `2` Monitors state of table without `WHERE` clause.
	+ `3` Monitors state of table with `WHERE` clause (currently unsupported).
* **Default Table Value:** `0`
* **DSN Parameter Name:** `mbk`

 #### `monitoring_kind`

 * **Description:** Kind of monitoring.
	+ `0` Disables monitoring
	+ `1` Monitors connection state.
	+ `2` Monitors state of table without `WHERE` clause.
	+ `3` Monitors state of table with `WHERE` clause (currently unsupported).
* **Default Table Value:** `0`
* **DSN Parameter Name:** `mkd`

 #### `monitoring_limit`

 * **Description:** Limits the number of records in the monitoring table. This is only effective when Spider monitors the state of a table, which occurs when the `[monitoring\_kind](#monitoring_kind)` table variable is set to a value greater than `1`.
* **Default Table Value:** `1`
* **Range:**  `0` upwards
* **DSN Parameter Name:** `mlt`

 #### `monitoring_server_id`

 * **Description:** Preferred monitoring `@@server_id` for each backend failure. You can use this to geo-localize backend servers and set the first Spider monitoring node to contact for failover. In the event that this monitor fails, other monitoring nodes are contacted. For multiple copy backends, you can set a lazy configuration with a single MSI instead of one per backend.
* **Default Table Value:** `server_id`
* **DSN Parameter Name:** `msi`

 #### `password`

 * **Description:** Remote server password.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `password`

 #### `port`

 * **Description:** Remote server port.
* **Default Table Value:** `3306`
* **DSN Parameter Name:** `port`

 #### `priority`

 * **Description:** Priority. Used to define the order of execution. For instance, Spider uses priority when deciding the order in which to lock tables on a remote server.
* **Default Table Value:** `1000000`
* **DSN Parameter Name:** `prt`

 #### `query_cache`

 * **Description:** Passes the option for the [Query Cache](../query-cache/index) when issuing `[SELECT](../select/index)` statements to the remote server.
	+ `0` No option passed.
	+ `1` Passes the `[SQL\_CACHE](../optimizer-hints/index#sql_cache-sql_no_cache)` option.
	+ `2` Passes the `[SQL\_NO\_CACHE](../optimizer-hints/index#sql_cache-sql_no_cache)` option.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `qch`

 #### `read_rate`

 * **Description:** Rate used to calculate the amount of time Spider requires when executing index scans.
* **Default Table Value:** `0.0002`
* **DSN Parameter Name:** `rrt`

 #### `scan_rate`

 * **Description:** Rate used to calculate the amount of time Spider requires when scanning tables.
* **Default Table Value:**  `0.0001`
* **DSN Parameter Name:** `srt`

 #### `server`

 * **Description:** Server name. Used when generating connection information with `[CREATE SERVER](../create-server/index)` statements.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `srv`

 #### `socket`

 * **Description:** Remote server socket.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `socket`

 #### `ssl_ca`

 * **Description:** Path to the Certificate Authority file.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `sca`

 #### `ssl_capath`

 * **Description:** Path to directory containing trusted TLS CA certificates in PEM format.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `scp`

 #### `ssl_cert`

 * **Description:** Path to the certificate file.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `scr`

 #### `ssl_cipher`

 * **Description:** List of allowed ciphers to use with [TLS encryption](../secure-connections-overview/index).
* **Default Table Value:** `none`
* **DSN Parameter Name:** `sch`

 #### `ssl_key`

 * **Description:** Path to the key file.
* **Default Table Value:** `none`
* **DSN Parameter Name:** `sky`

 #### `ssl_verify_server_cert`

 * **Description:** Enables verification of the server's Common Name value in the certificate against the host name used when connecting to the server.
	+ `0` Disables verification.
	+ `1` Enables verification.
* **Default Table Value:** `0`
* **DSN Parameter Name:** `svc`

 #### `table`

 * **Description:** Destination table name.
* **Default Table Value:** `Same table name`
* **DSN Parameter Name:** `tbl`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-table-parameters/>

Information Schema SPIDER\_ALLOC\_MEM Table
===========================================

    The [Information Schema](../information_schema/index) `SPIDER_ALLOC_MEM` table is installed along with the [Spider](../spider/index) storage engine. It shows information about Spider's memory usage.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `ID` |  |
| `FUNC_NAME` |  |
| `FILE_NAME` |  |
| `LINE_NO` |  |
| `TOTAL_ALLOC_MEM` |  |
| `CURRENT_ALLOC_MEM` |  |
| `ALLOC_MEM_COUNT` |  |
| `FREE_MEM_COUNT` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-spider_alloc_mem-table/>

Information Schema SPIDER\_WRAPPER\_PROTOCOLS Table
===================================================

    
**MariaDB starting with [10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/)**The [Information Schema](../information_schema/index) `SPIDER_WRAPPER_PROTOCOLS` table is installed along with the [Spider](../spider/index) storage engine from [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/). 

 
It contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| `WRAPPER_NAME` | varchar(64) |  |
| `WRAPPER_VERSION` | varchar(20) |  |
| `WRAPPER_DESCRIPTION` | longtext |  |
| `WRAPPER_MATURITY` | varchar(12) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-spider_wrapper_protocols-table/>

Spider Differences Between SpiderForMySQL and MariaDB
=====================================================

    ### SQL Syntax

 * With `SpiderForMySQL`, the [CREATE TABLE](../create-table/index) statement uses `CONNECTION` to define spider table variables whereas MariaDB uses `COMMENT`.

 ### Features

 * `[HANDLER](../handler/index)` can not be translated to SQL in MariaDB
* Concurrent background search is not yet implemented in MariaDB
* Vertical partitioning storage engine VP is not implemented in MariaDB
* `CREATE TABLE` can use [table discovery](../table-discovery/index) in MariaDB
* `[JOIN](../join-syntax/index)` performance improvement using `[join\_cache\_level](../server-system-variables/index#join_cache_level)>1` and `[join\_buffer\_size](../server-system-variables/index#join_buffer_size)` in MariaDB

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-differences-between-spiderformysql-and-mariadb/>

Spider Case Studies
===================

    A list of users or clients that are using Spider and agree to be referenced:

 * Tencent Games. They handle 100TB data on 396 Spider nodes and 2800 data nodes. They use this cluster for their online games.
* Kadokawa Corporation
* MicroAd, Inc.
* Sansan, Inc.
* teamLab Inc.
* CCM Benchmark <http://www.slideshare.net/skysql/ccm-escape-case-study-skysql-paris-meetup-17122013>
* Softlink <http://fr.slideshare.net/skysql/galaxy-big-data-with-mariadb>
* Gavo <http://wiki.ivoa.net/internal/IVOA/InterOpMay2014NewTechnologies/Spider-MariaDB.pdf>
* Blablacar Using for storing various logs
* Believe Digital Using for back office analytics queries to aggregate multi billions tables in real time

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-case-studies/>

Spider Benchmarks
=================

    This is best run on a cluster of 3 nodes intel NUC servers 12 virtual cores model name : Intel® Core(TM) i3-3217U CPU @ 1.80GHz

 All nodes have been running a mysqlslap client attached to the local spider node in the best run. 

 
```
/usr/local/skysql/mysql-client/bin/mysqlslap --user=skysql --password=skyvodka --host=192.168.0.201 --port=5012 -i1000000 -c32 -q "insert into test(c) values('0-31091-138522330')" --create-schema=test

```

`spider_conn_recycle_mode=1;`

 ![spbench4]

 The read point select is produce with a 10M rows sysbench table 

 ![spbench5]

 The write insert a single string into a memory table 

 ![spbench6]

 Before Engine Condition Push Down patch . 

 ![benchspider7]

 Spider can benefit by 10% additional performance with Independent Storage Engine Statistics.

 
```
set global use_stat_tables='preferably';
USE backend; 
ANALYZE TABLE sbtest; 

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-benchmarks/>

Spider FAQ
==========

    ### What does "[ERROR] mysqld: Can't find record in 'spider\_tables'" mean?

 This happens when you have a Spider table defined that does not point to an existing table on a data node. 

 ### Are there minimum Spider settings?

 
```
myisam-recover=FORCE,BACKUP

```


**MariaDB until [10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)**
```
optimizer_switch='engine_condition_pushdown=on'

```



**MariaDB until [10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)**When using spider\_autoincrement\_mode = 0, partitioned Spider tables work as spider\_autoincrement\_mode = 1 see : [MDEV-21404](https://jira.mariadb.org/browse/MDEV-21404)

 
### What does "select spider\_ping\_table()" in the general log mean?

 This is used by Spider monitoring to ask other monitoring nodes the status of a table.

 ### Do I need a primary key on physical tables?

 Not having a primary key will generate errors for resynchronizing tables via spider\_copy\_table().

 ### Can I use Spider on top of Galera shards?

 Yes, XA transactions can be disabled from Spider. Until Galera 4.0 fully supports xa transactions, spider can point to a maxscale proxy that can manage transparent node election in case of failure inside a shard group. Note that disabling XA will break cross shard WRITES in case of transaction ROLLBACK. This architecture need to be used with care if you have a highly transactional workload that can generate cross shard deadlocks. 

 ### What are the most used architectures for Spider HA?

 * Delegation of shard node replication using asynchronous replication and slave election with GTID.
* Delegation of shard node replication via active passive HA solutions.
* Shard builds via replication into Spider tables is interesting when you can route READS to a pool of Spider nodes reattaching the shards.

 ### What are the most used architectures for Spider Map Reduce?

 * Map reduce in Spider is limited to a single table. Building spider on top of some views can eliminate the need to use joins.
* Replication to universal tables to every shard is commonly used to enable the views on each shard.

 ### What about Grants on shards?

 * When using MRR and BKA (and you do so with network storage), when Spider needs to create temporary tables on the backends, use the CREATE TEMPORARY TABLES privilege. Spider can still switch to a lower performance solution using [spider\_bka\_mode=2](../spider-server-system-variables/index#spider_bka_mode), or Query push down or range predicate using [spider\_bka\_mode=0](../spider-server-system-variables/index#spider_bka_mode)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/spider-faq/>

Window Functions Overview
=========================

    Introduction
------------

 Window functions allow calculations to be performed across a set of rows related to the current row.

 ### Syntax

 
```
function (expression) OVER (
  [ PARTITION BY expression_list ]
  [ ORDER BY order_list [ frame_clause ] ] ) 

function:
  A valid window function

expression_list:
  expression | column_name [, expr_list ]

order_list:
  expression | column_name [ ASC | DESC ] 
  [, ... ]

frame_clause:
  {ROWS | RANGE} {frame_border | BETWEEN frame_border AND frame_border}

frame_border:
  | UNBOUNDED PRECEDING
  | UNBOUNDED FOLLOWING
  | CURRENT ROW
  | expr PRECEDING
  | expr FOLLOWING

```

### Description

 In some ways, window functions are similar to [aggregate functions](../aggregate-functions/index) in that they perform calculations across a set of rows. However, unlike aggregate functions, the output is not grouped into a single row. 

 Non-aggregate window functions include 

 * [CUME\_DIST](../cume_dist/index)
* [DENSE\_RANK](../dense_rank/index)
* [FIRST\_VALUE](../first_value/index)
* [LAG](../lag/index)
* [LAST\_VALUE](../last_value/index)
* [LEAD](../lead/index)
* [MEDIAN](../median/index)
* [NTH\_VALUE](../nth_value/index)
* [NTILE](../ntile/index)
* [PERCENT\_RANK](../percent_rank/index)
* [PERCENTILE\_CONT](../percentile_cont/index)
* [PERCENTILE\_DISC](../percentile_disc/index)
* [RANK](../rank/index), [ROW\_NUMBER](../row_number/index)

 [Aggregate functions](../aggregate-functions/index) that can also be used as window functions include 

 * [AVG](../avg/index)
* [BIT\_AND](../bit_and/index)
* [BIT\_OR](../bit_or/index)
* [BIT\_XOR](../bit_xor/index)
* [COUNT](../count/index)
* [MAX](../max/index)
* [MIN](../min/index)
* [STD](../std/index)
* [STDDEV](../stddev/index)
* [STDDEV\_POP](../stddev_pop/index)
* [STDDEV\_SAMP](../stddev_samp/index)
* [SUM](../sum/index)
* [VAR\_POP](../var_pop/index)
* [VAR\_SAMP](../var_samp/index)
* [VARIANCE](../variance/index)

 Window function queries are characterised by the OVER keyword, following which the set of rows used for the calculation is specified. By default, the set of rows used for the calculation (the "window) is the entire dataset, which can be ordered with the ORDER BY clause. The PARTITION BY clause is used to reduce the window to a particular group within the dataset.

 For example, given the following data:

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

```

the following two queries return the average partitioned by test and by name respectively:

 
```
SELECT name, test, score, AVG(score) OVER (PARTITION BY test) 
  AS average_by_test FROM student;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_test |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         65.2500 |
| Chun    | Tuning |    73 |         68.7500 |
| Esben   | SQL    |    43 |         65.2500 |
| Esben   | Tuning |    31 |         68.7500 |
| Kaolin  | SQL    |    56 |         65.2500 |
| Kaolin  | Tuning |    88 |         68.7500 |
| Tatiana | SQL    |    87 |         65.2500 |
| Tatiana | Tuning |    83 |         68.7500 |
+---------+--------+-------+-----------------+

SELECT name, test, score, AVG(score) OVER (PARTITION BY name) 
  AS average_by_name FROM student;
+---------+--------+-------+-----------------+
| name    | test   | score | average_by_name |
+---------+--------+-------+-----------------+
| Chun    | SQL    |    75 |         74.0000 |
| Chun    | Tuning |    73 |         74.0000 |
| Esben   | SQL    |    43 |         37.0000 |
| Esben   | Tuning |    31 |         37.0000 |
| Kaolin  | SQL    |    56 |         72.0000 |
| Kaolin  | Tuning |    88 |         72.0000 |
| Tatiana | SQL    |    87 |         85.0000 |
| Tatiana | Tuning |    83 |         85.0000 |
+---------+--------+-------+-----------------+

```

It is also possible to specify which rows to include for the window function (for example, the current row and all preceding rows). See [Window Frames](../window-frames/index) for more details.

 Scope
-----

 Window functions were introduced in SQL:2003, and their definition was expanded in subsequent versions of the standard. The last expansion was in the latest version of the standard, SQL:2011. 

 Most database products support a subset of the standard, they implement some functions defined as late as in SQL:2011, and at the same time leave some parts of SQL:2008 unimplemented.

 MariaDB:

 * Supports ROWS and RANGE-type frames
	+ All kinds of frame bounds are supported, including `RANGE PRECEDING|FOLLOWING n` frame bounds (unlike PostgreSQL or MS SQL Server)
	+ Does not yet support DATE[TIME] datatype and arithmetic for RANGE-type frames ([MDEV-9727](https://jira.mariadb.org/browse/MDEV-9727))
* Does not support GROUPS-type frames (it seems that no popular database supports it, either)

 * Does not support frame exclusion (no other database seems to support it, either) ([MDEV-9724](https://jira.mariadb.org/browse/MDEV-9724))
* Does not support explicit `NULLS FIRST` or `NULLS LAST`.
* Does not support nested navigation in window functions (this is `VALUE_OF(expr AT row_marker [, default_value)` syntax)

 * The following window functions are supported:
	+ "Streamable" window functions: [ROW\_NUMBER](../row_number/index), [RANK](../rank/index), [DENSE\_RANK](../dense_rank/index),
	+ Window functions that can be streamed once the number of rows in partition is known: [PERCENT\_RANK](../percent_rank/index), [CUME\_DIST](../cume_dist/index), [NTILE](../ntile/index)

 * Aggregate functions that are currently supported as window functions are: [COUNT](../count/index), [SUM](../sum/index), [AVG](../avg/index), [BIT\_OR](../bit_or/index), [BIT\_AND](../bit_and/index), [BIT\_XOR](../bit_xor/index).
* Aggregate functions with the `DISTINCT` specifier (e.g. `COUNT( DISTINCT x)`) are not supported as window functions.

 Links
-----

 * [MDEV-6115](https://jira.mariadb.org/browse/MDEV-6115) is the main jira task for window functions development. Other tasks are are attached as sub-tasks
* [bb-10.2-mdev9543](https://github.com/MariaDB/server/commits/bb-10.2-mdev9543) is the feature tree for window functions. Development is ongoing, and this tree has the newest changes.
* Testcases are in `mysql-test/t/win*.test`

 Examples
--------

 Given the following sample data:

 
```
CREATE TABLE users (
  email VARCHAR(30), 
  first_name VARCHAR(30), 
  last_name VARCHAR(30), 
  account_type VARCHAR(30)
);

INSERT INTO users VALUES 
  ('admin@boss.org', 'Admin', 'Boss', 'admin'), 
  ('bob.carlsen@foo.bar', 'Bob', 'Carlsen', 'regular'),
  ('eddie.stevens@data.org', 'Eddie', 'Stevens', 'regular'),
  ('john.smith@xyz.org', 'John', 'Smith', 'regular'), 
  ('root@boss.org', 'Root', 'Chief', 'admin')

```

First, let's order the records by email alphabetically, giving each an ascending *rnum* value starting with 1. This will make use of the [ROW\_NUMBER](../row_number/index) window function:

 
```
SELECT row_number() OVER (ORDER BY email) AS rnum,
    email, first_name, last_name, account_type
FROM users ORDER BY email;
+------+------------------------+------------+-----------+--------------+
| rnum | email                  | first_name | last_name | account_type |
+------+------------------------+------------+-----------+--------------+
|    1 | admin@boss.org         | Admin      | Boss      | admin        |
|    2 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |
|    3 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |
|    4 | john.smith@xyz.org     | John       | Smith     | regular      |
|    5 | root@boss.org          | Root       | Chief     | admin        |
+------+------------------------+------------+-----------+--------------

```

We can generate separate sequences based on account type, using the PARTITION BY clause:

 
```

SELECT row_number() OVER (PARTITION BY account_type ORDER BY email) AS rnum, 
  email, first_name, last_name, account_type 
FROM users ORDER BY account_type,email;
+------+------------------------+------------+-----------+--------------+
| rnum | email                  | first_name | last_name | account_type |
+------+------------------------+------------+-----------+--------------+
|    1 | admin@boss.org         | Admin      | Boss      | admin        |
|    2 | root@boss.org          | Root       | Chief     | admin        |
|    1 | bob.carlsen@foo.bar    | Bob        | Carlsen   | regular      |
|    2 | eddie.stevens@data.org | Eddie      | Stevens   | regular      |
|    3 | john.smith@xyz.org     | John       | Smith     | regular      |
+------+------------------------+------------+-----------+--------------+

```

Given the following structure and data, we want to find the top 5 salaries from each department. 

 
```
CREATE TABLE employee_salaries (dept VARCHAR(20), name VARCHAR(20), salary INT(11));

INSERT INTO employee_salaries VALUES
('Engineering', 'Dharma', 3500),
('Engineering', 'Binh', 3000),
('Engineering', 'Adalynn', 2800),
('Engineering', 'Samuel', 2500),
('Engineering', 'Cveta', 2200),
('Engineering', 'Ebele', 1800),
('Sales', 'Carbry', 500),
('Sales', 'Clytemnestra', 400),
('Sales', 'Juraj', 300),
('Sales', 'Kalpana', 300),
('Sales', 'Svantepolk', 250),
('Sales', 'Angelo', 200);

```

We could do this without using window functions, as follows:

 
```
select dept, name, salary
from employee_salaries as t1
where (select count(t2.salary)
       from employee_salaries as t2
       where t1.name != t2.name and
             t1.dept = t2.dept and
             t2.salary > t1.salary) < 5
order by dept, salary desc;

+-------------+--------------+--------+
| dept        | name         | salary |
+-------------+--------------+--------+
| Engineering | Dharma       |   3500 |
| Engineering | Binh         |   3000 |
| Engineering | Adalynn      |   2800 |
| Engineering | Samuel       |   2500 |
| Engineering | Cveta        |   2200 |
| Sales       | Carbry       |    500 |
| Sales       | Clytemnestra |    400 |
| Sales       | Juraj        |    300 |
| Sales       | Kalpana      |    300 |
| Sales       | Svantepolk   |    250 |
+-------------+--------------+--------+

```

This has a number of disadvantages:

 * if there is no index, the query could take a long time if the employee\_salary\_table is large
* Adding and maintaining indexes adds overhead, and even with indexes on *dept* and *salary*, each subquery execution adds overhead by performing a lookup through the index.

 Let's try achieve the same with window functions. First, generate a rank for all employees, using the [RANK](../rank/index) function.

 
```
select rank() over (partition by dept order by salary desc) as ranking,
    dept, name, salary
    from employee_salaries
    order by dept, ranking;
+---------+-------------+--------------+--------+
| ranking | dept        | name         | salary |
+---------+-------------+--------------+--------+
|       1 | Engineering | Dharma       |   3500 |
|       2 | Engineering | Binh         |   3000 |
|       3 | Engineering | Adalynn      |   2800 |
|       4 | Engineering | Samuel       |   2500 |
|       5 | Engineering | Cveta        |   2200 |
|       6 | Engineering | Ebele        |   1800 |
|       1 | Sales       | Carbry       |    500 |
|       2 | Sales       | Clytemnestra |    400 |
|       3 | Sales       | Juraj        |    300 |
|       3 | Sales       | Kalpana      |    300 |
|       5 | Sales       | Svantepolk   |    250 |
|       6 | Sales       | Angelo       |    200 |
+---------+-------------+--------------+--------+

```

Each department has a separate sequence of ranks due to the *PARTITION BY* clause. This particular sequence of values for *rank()* is given by the *ORDER BY* clause inside the window function’s *OVER* clause. Finally, to get our results in a readable format we order the data by *dept* and the newly generated *ranking* column.

 Now, we need to reduce the results to find only the top 5 per department. Here is a common mistake:

 
```
select
rank() over (partition by dept order by salary desc) as ranking,
dept, name, salary
from employee_salaries
where ranking <= 5
order by dept, ranking;

ERROR 1054 (42S22): Unknown column 'ranking' in 'where clause'

```

Trying to filter only the first 5 values per department by putting a where clause in the statement does not work, due to the way window functions are computed. The computation of window functions happens after all WHERE, GROUP BY and HAVING clauses have been completed, right before ORDER BY, so the WHERE clause has no idea that the ranking column exists. It is only present after we have filtered and grouped all the rows.

 To counteract this problem, we need to wrap our query into a derived table. We can then attach a where clause to it:

 
```
select *from (select rank() over (partition by dept order by salary desc) as ranking,
  dept, name, salary
from employee_salaries) as salary_ranks
where (salary_ranks.ranking <= 5)
  order by dept, ranking;
+---------+-------------+--------------+--------+
| ranking | dept        | name         | salary |
+---------+-------------+--------------+--------+
|       1 | Engineering | Dharma       |   3500 |
|       2 | Engineering | Binh         |   3000 |
|       3 | Engineering | Adalynn      |   2800 |
|       4 | Engineering | Samuel       |   2500 |
|       5 | Engineering | Cveta        |   2200 |
|       1 | Sales       | Carbry       |    500 |
|       2 | Sales       | Clytemnestra |    400 |
|       3 | Sales       | Juraj        |    300 |
|       3 | Sales       | Kalpana      |    300 |
|       5 | Sales       | Svantepolk   |    250 |
+---------+-------------+--------------+--------+

```

See Also
--------

 * [Window Frames](../window-frames/index)
* [Introduction to Window Functions in MariaDB Server 10.2](https://mariadb.com/resources/blog/introduction-window-functions-mariadb-server-102)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/window-functions-overview/>

FIRST\_VALUE
============

    Syntax
------

 
```
FIRST_VALUE(expr) OVER (
  [ PARTITION BY partition_expression ]
  [ ORDER BY order_list ]
) 

```

Description
-----------

 `FIRST_VALUE` returns the first result from an ordered set, or NULL if no such result exists.

 Examples
--------

 
```
CREATE TABLE t1 (
  pk int primary key,
  a int,
  b int,
  c char(10),
  d decimal(10, 3),
  e real
);

INSERT INTO t1 VALUES
( 1, 0, 1,    'one',    0.1,  0.001),
( 2, 0, 2,    'two',    0.2,  0.002),
( 3, 0, 3,    'three',  0.3,  0.003),
( 4, 1, 2,    'three',  0.4,  0.004),
( 5, 1, 1,    'two',    0.5,  0.005),
( 6, 1, 1,    'one',    0.6,  0.006),
( 7, 2, NULL, 'n_one',  0.5,  0.007),
( 8, 2, 1,    'n_two',  NULL, 0.008),
( 9, 2, 2,    NULL,     0.7,  0.009),
(10, 2, 0,    'n_four', 0.8,  0.010),
(11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, FIRST_VALUE(pk) OVER (ORDER BY pk) AS first_asc,
           LAST_VALUE(pk) OVER (ORDER BY pk) AS last_asc,
           FIRST_VALUE(pk) OVER (ORDER BY pk DESC) AS first_desc,
           LAST_VALUE(pk) OVER (ORDER BY pk DESC) AS last_desc
FROM t1
ORDER BY pk DESC;

+----+-----------+----------+------------+-----------+
| pk | first_asc | last_asc | first_desc | last_desc |
+----+-----------+----------+------------+-----------+
| 11 |         1 |       11 |         11 |        11 |
| 10 |         1 |       10 |         11 |        10 |
|  9 |         1 |        9 |         11 |         9 |
|  8 |         1 |        8 |         11 |         8 |
|  7 |         1 |        7 |         11 |         7 |
|  6 |         1 |        6 |         11 |         6 |
|  5 |         1 |        5 |         11 |         5 |
|  4 |         1 |        4 |         11 |         4 |
|  3 |         1 |        3 |         11 |         3 |
|  2 |         1 |        2 |         11 |         2 |
|  1 |         1 |        1 |         11 |         1 |
+----+-----------+----------+------------+-----------+

```


```
CREATE OR REPLACE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

SELECT i,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS f_1f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN CURRENT ROW and 1 FOLLOWING) AS l_1f,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS f_1p1f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS l_1p1f,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS f_2p1p,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) AS l_2p1p,
  FIRST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS f_1f2f,
  LAST_VALUE(i) OVER (ORDER BY i ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) AS l_1f2f
FROM t1;

+------+------+------+--------+--------+--------+--------+--------+--------+
| i    | f_1f | l_1f | f_1p1f | l_1p1f | f_2p1p | l_2p1p | f_1f2f | l_1f2f |
+------+------+------+--------+--------+--------+--------+--------+--------+
|    1 |    1 |    2 |      1 |      2 |   NULL |   NULL |      2 |      3 |
|    2 |    2 |    3 |      1 |      3 |      1 |      1 |      3 |      4 |
|    3 |    3 |    4 |      2 |      4 |      1 |      2 |      4 |      5 |
|    4 |    4 |    5 |      3 |      5 |      2 |      3 |      5 |      6 |
|    5 |    5 |    6 |      4 |      6 |      3 |      4 |      6 |      7 |
|    6 |    6 |    7 |      5 |      7 |      4 |      5 |      7 |      8 |
|    7 |    7 |    8 |      6 |      8 |      5 |      6 |      8 |      9 |
|    8 |    8 |    9 |      7 |      9 |      6 |      7 |      9 |     10 |
|    9 |    9 |   10 |      8 |     10 |      7 |      8 |     10 |     10 |
|   10 |   10 |   10 |      9 |     10 |      8 |      9 |   NULL |   NULL |
+------+------+------+--------+--------+--------+--------+--------+--------+

```

See Also
--------

 * [LAST\_VALUE](../last_value/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/first_value/>

LAG
===

    Syntax
------

 
```
LAG (expr[, offset]) OVER ( 
  [ PARTITION BY partition_expression ] 
  < ORDER BY order_list >
)

```

Description
-----------

 The *LAG* function accesses data from a previous row according to the ORDER BY clause without the need for a self-join. The specific row is determined by the *offset* (default *1*), which specifies the number of rows behind the current row to use. An offset of *0* is the current row.

 Examples
--------

 
```
CREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10, 3), e real);

INSERT INTO t1 VALUES
 ( 1, 0, 1,    'one',    0.1,  0.001),
 ( 2, 0, 2,    'two',    0.2,  0.002),
 ( 3, 0, 3,    'three',  0.3,  0.003),
 ( 4, 1, 2,    'three',  0.4,  0.004),
 ( 5, 1, 1,    'two',    0.5,  0.005),
 ( 6, 1, 1,    'one',    0.6,  0.006),
 ( 7, 2, NULL, 'n_one',  0.5,  0.007),
 ( 8, 2, 1,    'n_two',  NULL, 0.008),
 ( 9, 2, 2,    NULL,     0.7,  0.009),
 (10, 2, 0,    'n_four', 0.8,  0.010),
 (11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, LAG(pk) OVER (ORDER BY pk) AS l,
  LAG(pk,1) OVER (ORDER BY pk) AS l1,
  LAG(pk,2) OVER (ORDER BY pk) AS l2,
  LAG(pk,0) OVER (ORDER BY pk) AS l0,
  LAG(pk,-1) OVER (ORDER BY pk) AS lm1,
  LAG(pk,-2) OVER (ORDER BY pk) AS lm2 
FROM t1;
+----+------+------+------+------+------+------+
| pk | l    | l1   | l2   | l0   | lm1  | lm2  |
+----+------+------+------+------+------+------+
|  1 | NULL | NULL | NULL |    1 |    2 |    3 |
|  2 |    1 |    1 | NULL |    2 |    3 |    4 |
|  3 |    2 |    2 |    1 |    3 |    4 |    5 |
|  4 |    3 |    3 |    2 |    4 |    5 |    6 |
|  5 |    4 |    4 |    3 |    5 |    6 |    7 |
|  6 |    5 |    5 |    4 |    6 |    7 |    8 |
|  7 |    6 |    6 |    5 |    7 |    8 |    9 |
|  8 |    7 |    7 |    6 |    8 |    9 |   10 |
|  9 |    8 |    8 |    7 |    9 |   10 |   11 |
| 10 |    9 |    9 |    8 |   10 |   11 | NULL |
| 11 |   10 |   10 |    9 |   11 | NULL | NULL |
+----+------+------+------+------+------+------+

```

See Also
--------

 * [LEAD](../lead/index) - Window function to access a following row

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lag/>

FLUSH Commands
===============

   Commands to reset (flush) various caches in MariaDB.

  

| Title | Description |
| --- | --- |
|  [FLUSH](../flush/index) |  Clear or reload various internal caches.  |
|  [FLUSH QUERY CACHE](../flush-query-cache/index) |  Defragmenting the query cache  |
|  [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index) |  Flushes changes to disk for specific tables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/flush-commands/>

Inserting & Loading Data
=========================

   The `INSERT` statement is the primary SQL statement for adding data into a table in MariaDB.

  

| Title | Description |
| --- | --- |
|  [INSERT](../insert/index) |  Insert rows into a table.  |
|  [INSERT DELAYED](../insert-delayed/index) |  Queue row to be inserted when thread is free.  |
|  [INSERT SELECT](../insert-select/index) |  Insert the rows returned by a SELECT into a table  |
|  [LOAD Data into Tables or Index](../load-data-into-tables-or-index/index) |  Loading data quickly into MariaDB  |
|  [Concurrent Inserts](../concurrent-inserts/index) |  Under some circumstances, MyISAM allows INSERTs and SELECTs to be executed concurrently.  |
|  [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index) |  Modifying statement priority in storage engines supporting table-level locks.  |
|  [IGNORE](../ignore/index) |  Suppress errors while trying to violate a UNIQUE constraint.  |
|  [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index) |  Default and duplicate values when inserting.  |
|  [INSERT IGNORE](../insert-ignore/index) |  Convert errors to warnings, permitting inserts of additional rows to continue.  |
|  [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) |  INSERT if no duplicate key is found, otherwise UPDATE.  |
|  [INSERT...RETURNING](../insertreturning/index) |  Returns a resultset of the inserted rows.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inserting-loading-data/>

TRUNCATE TABLE
==============

    Syntax
------

 
```
TRUNCATE [TABLE] tbl_name
  [WAIT n | NOWAIT]

```
 Description
-----------

 `TRUNCATE TABLE` empties a table completely. It requires the `DROP` privilege. See [GRANT](../grant/index).

 `tbl_name` can also be specified in the form `db_name`.`tbl_name` (see [Identifier Qualifiers](../identifier-qualifiers/index)).

 Logically, `TRUNCATE TABLE` is equivalent to a [DELETE](../delete/index) statement that deletes all rows, but there are practical differences under some circumstances.

 `TRUNCATE TABLE` will fail for an [InnoDB table](../innodb/index) if any FOREIGN KEY constraints from other tables reference the table, returning the error:

 
```
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint

```

Foreign Key constraints between columns in the same table are permitted.

 For an InnoDB table, if there are no `FOREIGN KEY` constraints, InnoDB performs fast truncation by dropping the original table and creating an empty one with the same definition, which is much faster than deleting rows one by one. The [AUTO\_INCREMENT](../auto_increment/index) counter is reset by `TRUNCATE TABLE`, regardless of whether there is a `FOREIGN KEY` constraint.

 The count of rows affected by `TRUNCATE TABLE` is accurate only when it is mapped to a `DELETE` statement.

 For other storage engines, `TRUNCATE TABLE` differs from `DELETE` in the following ways:

 * Truncate operations drop and re-create the table, which is much faster than deleting rows one by one, particularly for large tables.
* Truncate operations cause an implicit commit.
* Truncation operations cannot be performed if the session holds an active table lock.
* Truncation operations do not return a meaningful value for the number of deleted rows. The usual result is "0 rows affected," which should be interpreted as "no information."
* As long as the table format file `tbl_name.frm` is valid, the table can be re-created as an empty table with `TRUNCATE TABLE`, even if the data or index files have become corrupted.
* The table handler does not remember the last used [AUTO\_INCREMENT](../auto_increment/index) value, but starts counting from the beginning. This is true even for MyISAM and InnoDB, which normally do not reuse sequence values.
* When used with partitioned tables, `TRUNCATE TABLE` preserves the partitioning; that is, the data and index files are dropped and re-created, while the partition definitions (.par) file is unaffected.
* Since truncation of a table does not make any use of `DELETE`, the `TRUNCATE` statement does not invoke `ON DELETE` triggers.
* `TRUNCATE TABLE` will only reset the values in the [Performance Schema summary tables](../list-of-performance-schema-tables/index) to zero or null, and will not remove the rows.

 For the purposes of binary logging and [replication](../replication/index), `TRUNCATE TABLE` is treated as [DROP TABLE](../drop-table/index) followed by [CREATE TABLE](../create-table/index) (DDL rather than DML).

 `TRUNCATE TABLE` does not work on [views](../views/index). Currently, `TRUNCATE TABLE` drops all historical records from a [system-versioned table](../system-versioned-tables/index).

 #### WAIT/NOWAIT

 Set the lock wait timeout. See [WAIT and NOWAIT](../wait-and-nowait/index).

 ### Oracle-mode

 [Oracle-mode](../sql_modeoracle/index) from [MariaDB 10.3](../what-is-mariadb-103/index) permits the optional keywords REUSE STORAGE or DROP STORAGE to be used.

 
```
TRUNCATE [TABLE] tbl_name [{DROP | REUSE} STORAGE] [WAIT n | NOWAIT]

```

These have no effect on the operation.

 ### Performance

 `TRUNCATE TABLE` is faster than [DELETE](delete-table), because it drops and re-creates a table.

 With [InnoDB](../innodb/index), `TRUNCATE TABLE` is slower if [innodb\_file\_per\_table=ON](../innodb-system-variables/index#innodb_file_per_table) is set (the default). This is because `TRUNCATE TABLE` unlinks the underlying tablespace file, which can be an expensive operation. See [MDEV-8069](https://jira.mariadb.org/browse/MDEV-8069) for more details.

 The performance issues with [innodb\_file\_per\_table=ON](../innodb-system-variables/index#innodb_file_per_table) can be exacerbated in cases where the [InnoDB buffer pool](../innodb-buffer-pool/index) is very large and [innodb\_adaptive\_hash\_index=ON](../innodb-system-variables/index#innodb_adaptive_hash_index) is set. In that case, using [DROP TABLE](../drop-table/index) followed by [CREATE TABLE](../create-table/index) instead of `TRUNCATE TABLE` may perform better. Setting [innodb\_adaptive\_hash\_index=OFF](../innodb-system-variables/index#innodb_adaptive_hash_index) (it defaults to ON before [MariaDB 10.5](../what-is-mariadb-105/index)) can also help. In [MariaDB 10.2](../what-is-mariadb-102/index) only, from [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/), this performance can also be improved by setting [innodb\_safe\_truncate=OFF](../innodb-system-variables/index#innodb_safe_truncate). See [MDEV-9459](https://jira.mariadb.org/browse/MDEV-9459) for more details.

 Setting [innodb\_adaptive\_hash\_index=OFF](../innodb-system-variables/index#innodb_adaptive_hash_index) can also improve `TRUNCATE TABLE` performance in general. See [MDEV-16796](https://jira.mariadb.org/browse/MDEV-16796) for more details.

 See Also
--------

 * [TRUNCATE function](../truncate/index)
* [innodb\_safe\_truncate](../innodb-system-variables/index#innodb_safe_truncate) system variable
* [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#simple-syntax-compatibility)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/truncate-table/>

Aggregate Functions as Window Functions
=======================================

    It is possible to use [aggregate functions](../aggregate-functions/index) as window functions. An aggregate function used as a window function must have the `OVER` clause. For example, here's [COUNT()](../count/index) used as a window function:

 
```
select COUNT(*) over  (order by column) from table;

```

MariaDB currently allows these aggregate functions to be used as window functions: 

 * [AVG](../avg/index)
* [BIT\_AND](../bit_and/index)
* [BIT\_OR](../bit_or/index)
* [BIT\_XOR](../bit_xor/index)
* [COUNT](../count/index)
* [JSON\_ARRAYAGG](../json_arrayagg/index)
* [JSON\_OBJECTAGG](../json_objectagg/index)
* [MAX](../max/index)
* [MIN](../min/index)
* [STD](../std/index)
* [STDDEV](../stddev/index)
* [STDDEV\_POP](../stddev_pop/index)
* [STDDEV\_SAMP](../stddev_samp/index)
* [SUM](../sum/index)
* [VAR\_POP](../var_pop/index)
* [VAR\_SAMP](../var_samp/index)
* [VARIANCE](../variance/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aggregate-functions-as-window-functions/>

SET DEFAULT ROLE
================

    Syntax
------

 
```
SET DEFAULT ROLE { role | NONE } [ FOR user@host ]

```

Description
-----------

 The `SET DEFAULT ROLE` statement sets a **default [role](../roles/index)** for a specified (or current) user. A default role is automatically enabled when a user connects (an implicit [SET ROLE](../set-role/index) statement is executed immediately after a connection is established).

 To be able to set a role as a default, the role must already have been granted to that user, and one needs the privileges to enable this role (if you cannot do `SET ROLE X`, you won't be able to do `SET DEFAULT ROLE X`). To set a default role for another user one needs to have write access to the `mysql` database.

 To remove a user's default role, use `SET DEFAULT ROLE NONE [ FOR user@host ]`. The record of the default role is not removed if the role is [dropped](../drop-role/index) or [revoked](../revoke/index#roles), so if the role is subsequently re-created or granted, it will again be the user's default role.

 The default role is stored in the `default_role` column in the [mysql.user](../mysqluser-table/index) table/view, as well as in the [Information Schema APPLICABLE\_ROLES table](../information-schema-applicable_roles-table/index), so these can be viewed to see which role has been assigned to a user as the default. 

 Examples
--------

 Setting a default role for the current user:

 
```
SET DEFAULT ROLE journalist;

```

Removing a default role from the current user:

 
```
SET DEFAULT ROLE NONE;

```

Setting a default role for another user. The role has to have been granted to the user before it can be set as default:

 
```
CREATE ROLE journalist;
CREATE USER taniel;

SET DEFAULT ROLE journalist FOR taniel;
ERROR 1959 (OP000): Invalid role specification `journalist`

GRANT journalist TO taniel;
SET DEFAULT ROLE journalist FOR taniel;

```

Viewing mysql.user:

 
```
select * from mysql.user where user='taniel'\G
*************************** 1. row ***************************
                  Host: %
                  User: taniel
...
               is_role: N
          default_role: journalist
...

```

Removing a default role for another user

 
```
SET DEFAULT ROLE NONE FOR taniel; 

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-default-role/>

CREATE
=======

   Articles on the various CREATE statements.

  

| Title | Description |
| --- | --- |
|  [CREATE DATABASE](../create-database/index) |  Create a database.  |
|  [CREATE EVENT](../create-event/index) |  Create and schedule a new event.  |
|  [CREATE FUNCTION](../create-function/index) |  Creates a stored function.  |
|  [CREATE FUNCTION UDF](../create-function-udf/index) |  Create a user-defined function.  |
|  [CREATE INDEX](../create-index/index) |  Create an index on one or more columns.  |
|  [CREATE LOGFILE GROUP](../create-logfile-group/index) |  The CREATE LOGFILE GROUP statement is not supported by MariaDB. It was orig...  |
|  [CREATE PACKAGE](../create-package/index) |  Create a stored package, in Oracle-mode.  |
|  [CREATE PACKAGE BODY](../create-package-body/index) |  Creates the package body for a stored package.  |
|  [CREATE PROCEDURE](../create-procedure/index) |  Creates a stored procedure.  |
|  [CREATE ROLE](../create-role/index) |  Add new roles.  |
|  [CREATE SEQUENCE](../create-sequence/index) |  Creates a sequence that generates new values when called with NEXT VALUE FOR.  |
|  [CREATE SERVER](../create-server/index) |  Define a server.  |
|  [CREATE TABLE](../create-table/index) |  Creates a new table.  |
|  [CREATE TABLESPACE](../create-tablespace/index) |  CREATE TABLESPACE is not available in MariaDB.  |
|  [CREATE TRIGGER](../create-trigger/index) |  Create a new trigger.  |
|  [CREATE USER](../create-user/index) |  Create new MariaDB accounts.  |
|  [CREATE VIEW](../create-view/index) |  Create or replace a view.  |
|  [Silent Column Changes](../silent-column-changes/index) |  MariaDB silently changes column specifications in certain situations.  |
|  [Generated (Virtual and Persistent/Stored) Columns](../generated-columns/index) |  Generated (virtual and persistent/stored) columns.  |
|  [Invisible Columns](../invisible-columns/index) |  Invisible columns are hidden in certain contexts.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create/>

SET ROLE
========

    Syntax
------

 
```
SET ROLE { role | NONE }

```
 Description
-----------

 The `SET ROLE` statement enables a [role](../roles/index), along with all of its associated permissions, for the current session. To unset a role, use `NONE` .

 If a role that doesn't exist, or to which the user has not been assigned, is specified, an `ERROR 1959 (OP000): Invalid role specification` error occurs.

 An automatic SET ROLE is implicitly performed when a user connects if that user has been assigned a default role. See [SET DEFAULT ROLE](../set-default-role/index).

 Example
-------

 
```
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE staff;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| staff        |
+--------------+

SET ROLE NONE;

SELECT CURRENT_ROLE();
+----------------+
| CURRENT_ROLE() |
+----------------+
| NULL           |
+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-role/>

NTH\_VALUE
==========

    Syntax
------

 
```
NTH_VALUE (expr[, num_row]) OVER ( 
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

```
 Description
-----------

 The `NTH_VALUE` function returns the value evaluated at row number `num_row` of the window frame, starting from 1, or NULL if the row does not exist.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/nth_value/>

ANALYZE and EXPLAIN Statements
===============================

  

| Title | Description |
| --- | --- |
|  [ANALYZE FORMAT=JSON](../analyze-format-json/index) |  Mix of the EXPLAIN FORMAT=JSON and ANALYZE statement features.  |
|  [ANALYZE FORMAT=JSON Examples](../analyze-formatjson-examples/index) |  Examples with ANALYZE FORMAT=JSON.  |
|  [ANALYZE Statement](../analyze-statement/index) |  Invokes the optimizer, executes the statement, and then produces EXPLAIN output.  |
|  [EXPLAIN](../explain/index) |  EXPLAIN returns information about index usage, as well as being a synonym for DESCRIBE.  |
|  [EXPLAIN ANALYZE](../explain-analyze/index) |  Old implementation, now ANALYZE statement  |
|  [EXPLAIN FORMAT=JSON](../explain-format-json/index) |  Variant of EXPLAIN that produces output in JSON form  |
|  [SHOW EXPLAIN](../show-explain/index) |  Shows an execution plan for a running query.  |
|  [Using Buffer UPDATE Algorithm](../using-buffer-update-algorithm/index) |  Explanation of UPDATE's "Using Buffer" algorithm.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/analyze-and-explain-statements/>

DROP
=====

   Articles on various DROP commands.

  

| Title | Description |
| --- | --- |
|  [DROP DATABASE](../drop-database/index) |  Drop all tables and delete database.  |
|  [DROP EVENT](../drop-event/index) |  Removes an existing event.  |
|  [DROP FUNCTION](../drop-function/index) |  Drop a stored function.  |
|  [DROP FUNCTION UDF](../drop-function-udf/index) |  Drop a user-defined function.  |
|  [DROP INDEX](../drop-index/index) |  Drops an index from a table.  |
|  [DROP LOGFILE GROUP](../drop-logfile-group/index) |  The DROP LOGFILE GROUP statement is not supported by MariaDB. It was origin...  |
|  [DROP PACKAGE](../drop-package/index) |  Drops a stored package entirely.  |
|  [DROP PACKAGE BODY](../drop-package-body/index) |  Drops a package body (i.e the implementation) previously created using the CREATE PACKAGE BODY.  |
|  [DROP PROCEDURE](../drop-procedure/index) |  Drop stored procedure.  |
|  [DROP ROLE](../drop-role/index) |  Drop a role.  |
|  [DROP SEQUENCE](../drop-sequence/index) |  Deleting a SEQUENCE.  |
|  [DROP SERVER](../drop-server/index) |  Dropping a server definition.  |
|  [DROP TABLE](../drop-table/index) |  Removes definition and data from one or more tables.  |
|  [DROP TABLESPACE](../drop-tablespace/index) |  DROP TABLESPACE is not available in MariaDB.  |
|  [DROP TRIGGER](../drop-trigger/index) |  Drops a trigger.  |
|  [DROP USER](../drop-user/index) |  Remove one or more MariaDB accounts.  |
|  [DROP VIEW](../drop-view/index) |  Removes one or more views.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop/>

CACHE INDEX
===========

    Syntax
------

 
```
CACHE INDEX                      
  tbl_index_list [, tbl_index_list] ...
  IN key_cache_name                    

tbl_index_list:
  tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]

```

Description
-----------

 The `CACHE INDEX` statement assigns table indexes to a specific key cache. It is used only for [MyISAM](../myisam/index) tables.

 A default key cache exists and cannot be destroyed. To create more key caches, the [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) server system variable.

 The associations between tables indexes and key caches are lost on server restart. To recreate them automatically, it is necessary to configure caches in a [configuration file](../mysqld-configuration-files-and-groups/index) and include some `CACHE INDEX` (and optionally `[LOAD INDEX](../load-index/index)`) statements in the init file.

 Examples
--------

 The following statement assigns indexes from the tables t1, t2, and t3 to the key cache named hot\_cache:

 
```
CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+

```

Implementation (for MyISAM)
---------------------------

 Normally CACHE INDEX should not take a long time to execute. Internally it's implemented the following way:

 * Find the right key cache (under LOCK\_global\_system\_variables)
* Open the table with a TL\_READ\_NO\_INSERT lock.
* Flush the original key cache for the given file (under key cache lock)
* Flush the new key cache for the given file (safety)
* Move the file to the new key cache (under file share lock)

 The only possible long operations are getting the locks for the table and flushing the original key cache, if there were many key blocks for the file in it.

 We plan to also add CACHE INDEX for Aria tables if there is a need for this.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cache-index/>

ColumnStore Window Functions
============================

    Introduction
============

 MariaDB ColumnStore provides support for window functions broadly following the SQL 2003 specification. A window function allows for calculations relating to a window of data surrounding the current row in a result set. This capability provides for simplified queries in support of common business questions such as cumulative totals, rolling averages, and top 10 lists.

 Aggregate functions are utilized for window functions however differ in behavior from a group by query because the rows remain ungrouped. This provides support for cumulative sums and rolling averages, for example.

 Two key concepts for window functions are Partition and Frame:

 * A Partition is a group of rows, or window, that have the same value for a specific column, for example a Partition can be created over a time period such as a quarter or lookup values.
* The Frame for each row is a subset of the row's Partition. The frame typically is dynamic allowing for a sliding frame of rows within the Partition. The Frame determines the range of rows for the windowing function. A Frame could be defined as the last X rows and next Y rows all the way up to the entire Partition.

 Window functions are applied after joins, group by, and having clauses are calculated.

 Syntax
======

 A window function is applied in the select clause using the following syntax:

 
```

function_name ([expression [, expression ... ]]) OVER ( window_definition )

```
 where *window\_definition* is defined as:

 
```

[ PARTITION BY expression [, ...] ]
[ ORDER BY expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ frame_clause ]

```
 PARTITION BY:

 * Divides the window result set into groups based on one or more *expressions*.
* An expression may be a constant, column, and non window function expressions.
* A query is not limited to a single partition by clause. Different partition clauses can be used across different window function applications.
* The partition by columns do not need to be in the select list but do need to be available from the query result set.
* If there is no PARTITION BY clause, all rows of the result set define the group.

 ORDER BY

 * Defines the ordering of values within the partition.
* Can be ordered by multiple keys which may be a constant, column or non window function expression.
* The order by columns do not need to be in the select list but need to be available from the query result set.
* Use of a select column alias from the query is not supported.
* ASC (default) and DESC options allow for ordering ascending or descending.
* NULLS FIRST and NULL\_LAST options specify whether null values come first or last in the ordering sequence. NULLS\_FIRST is the default for ASC order, and NULLS\_LAST is the default for DESC order.

 and the optional *frame\_clause* is defined as:

 
```

{ RANGE | ROWS } frame_start
{ RANGE | ROWS } BETWEEN frame_start AND frame_end

```
 and the optional *frame\_start* and *frame\_end* are defined as (value being a numeric expression):

 
```

UNBOUNDED PRECEDING
value PRECEDING
CURRENT ROW
value FOLLOWING
UNBOUNDED FOLLOWING

```
 RANGE/ROWS:

 * Defines the windowing clause for calculating the set of rows that the function applies to for calculating a given rows window function result.
* Requires an ORDER BY clause to define the row order for the window.
* ROWS specify the window in physical units, i.e. result set rows and must be a constant or expression evaluating to a positive numeric value.
* RANGE specifies the window as a logical offset. If the the expression evaluates to a numeric value then the ORDER BY expression must be a numeric or DATE type. If the expression evaluates to an interval value then the ORDER BY expression must be a DATE data type.
* UNBOUNDED PRECEDING indicates the window starts at the first row of the partition.
* UNBOUNDED FOLLOWING indicates the window ends at the last row of the partition.
* CURRENT ROW specifies the window start or ends at the current row or value.
* If omitted, the default is ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

 Supported Functions
===================

 

| Function | Description |
| --- | --- |
| AVG() | The average of all input values. |
| COUNT() | Number of input rows. |
| CUME\_DIST() | Calculates the cumulative distribution, or relative rank, of the current row to other rows in the same partition. Number of peer or preceding rows / number of rows in partition. |
| DENSE\_RANK() | Ranks items in a group leaving no gaps in ranking sequence when there are ties. |
| FIRST\_VALUE() | The value evaluated at the row that is the first row of the window frame (counting from 1); null if no such row. |
| LAG() | The value evaluated at the row that is offset rows before the current row within the partition; if there is no such row, instead return default. Both offset and default are evaluated with respect to the current row. If omitted, offset defaults to 1 and default to null. LAG provides access to more than one row of a table at the same time without a self-join. Given a series of rows returned from a query and a position of the cursor, LAG provides access to a row at a given physical offset prior to that position. |
| LAST\_VALUE() | The value evaluated at the row that is the last row of the window frame (counting from 1); null if no such row. |
| LEAD() | Provides access to a row at a given physical offset beyond that position. Returns value evaluated at the row that is offset rows after the current row within the partition; if there is no such row, instead return default. Both offset and default are evaluated with respect to the current row. If omitted, offset defaults to 1 and default to null. |
| MAX() | Maximum value of expression across all input values. |
| MEDIAN() | An inverse distribution function that assumes a continuous distribution model. It takes a numeric or datetime value and returns the middle value or an interpolated value that would be the middle value once the values are sorted. Nulls are ignored in the calculation. |
| MIN() | Minimum value of expression across all input values. |
| NTH\_VALUE() | The value evaluated at the row that is the nth row of the window frame (counting from 1); null if no such row. |
| NTILE() | Divides an ordered data set into a number of buckets indicated by expr and assigns the appropriate bucket number to each row. The buckets are numbered 1 through expr. The expr value must resolve to a positive constant for each partition. Integer ranging from 1 to the argument value, dividing the partition as equally as possible. |
| PERCENT\_RANK() | relative rank of the current row: (rank - 1) / (total rows - 1). |
| PERCENTILE\_CONT() | An inverse distribution function that assumes a continuous distribution model. It takes a percentile value and a sort specification, and returns an interpolated value that would fall into that percentile value with respect to the sort specification. Nulls are ignored in the calculation. |
| PERCENTILE\_DISC() | An inverse distribution function that assumes a discrete distribution model. It takes a percentile value and a sort specification and returns an element from the set. Nulls are ignored in the calculation. |
| RANK() | rank of the current row with gaps; same as row\_number of its first peer. |
| ROW\_NUMBER() | number of the current row within its partition, counting from 1 |
| STDDEV() STDDEV\_POP() | Computes the population standard deviation and returns the square root of the population variance. |
| STDDEV\_SAMP() | Computes the cumulative sample standard deviation and returns the square root of the sample variance. |
| SUM() | Sum of expression across all input values. |
| VARIANCE() VAR\_POP() | Population variance of the input values (square of the population standard deviation). |
| VAR\_SAMP() | Sample variance of the input values (square of the sample standard deviation). |

 Examples
========

 Example Schema
--------------

 The examples are all based on the following simplified sales opportunity table:

 
```

create table opportunities (
id int,
accountName varchar(20),
name varchar(128),
owner varchar(7),
amount decimal(10,2),
closeDate date,
stageName varchar(11)
) engine=columnstore;

```
 Some example values are (thanks to <https://www.mockaroo.com> for sample data generation):

 

| id | accountName | name | owner | amount | closeDate | stageName |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | Browseblab | Multi-lateral executive function | Bob | 26444.86 | 2016-10-20 | Negotiating |
| 2 | Mita | Organic demand-driven benchmark | Maria | 477878.41 | 2016-11-28 | ClosedWon |
| 3 | Miboo | De-engineered hybrid groupware | Olivier | 80181.78 | 2017-01-05 | ClosedWon |
| 4 | Youbridge | Enterprise-wide bottom-line Graphic Interface | Chris | 946245.29 | 2016-07-02 | ClosedWon |
| 5 | Skyba | Reverse-engineered fresh-thinking standardization | Maria | 696241.82 | 2017-02-17 | Negotiating |
| 6 | Eayo | Fundamental well-modulated artificial intelligence | Bob | 765605.52 | 2016-08-27 | Prospecting |
| 7 | Yotz | Extended secondary infrastructure | Chris | 319624.20 | 2017-01-06 | ClosedLost |
| 8 | Oloo | Configurable web-enabled data-warehouse | Chris | 321016.26 | 2017-03-08 | ClosedLost |
| 9 | Kaymbo | Multi-lateral web-enabled definition | Bob | 690881.01 | 2017-01-02 | Developing |
| 10 | Rhyloo | Public-key coherent infrastructure | Chris | 965477.74 | 2016-11-07 | Prospecting |

 The schema, sample data, and queries are available as an attachment to this article.

 Cumulative Sum and Running Max Example
--------------------------------------

 Window functions can be used to achieve cumulative / running calculations on a detail report. In this case a won opportunity report for a 7 day period adds columns to show the accumulated won amount as well as the current highest opportunity amount in preceding rows. 

 
```

select owner, 
accountName, 
CloseDate, 
amount, 
sum(amount) over (order by CloseDate rows between unbounded preceding and current row) cumeWon, 
max(amount) over (order by CloseDate rows between unbounded preceding and current row) runningMax
from opportunities 
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09' 
order by CloseDate;

```
 with example results:

 

| owner | accountName | CloseDate | amount | cumeWon | runningMax |
| --- | --- | --- | --- | --- | --- |
| Bill | Babbleopia | 2016-10-02 | 437636.47 | 437636.47 | 437636.47 |
| Bill | Thoughtworks | 2016-10-04 | 146086.51 | 583722.98 | 437636.47 |
| Olivier | Devpulse | 2016-10-05 | 834235.93 | 1417958.91 | 834235.93 |
| Chris | Linkbridge | 2016-10-07 | 539977.45 | 2458738.65 | 834235.93 |
| Olivier | Trupe | 2016-10-07 | 500802.29 | 1918761.20 | 834235.93 |
| Bill | Latz | 2016-10-08 | 857254.87 | 3315993.52 | 857254.87 |
| Chris | Avamm | 2016-10-09 | 699566.86 | 4015560.38 | 857254.87 |

 Partitioned Cumulative Sum and Running Max Example
--------------------------------------------------

 The above example can be partitioned, so that the window functions are over a particular field grouping such as owner and accumulate within that grouping. This is achieved by adding the syntax "partition by <columns>" in the window function clause. 

 
```

select owner,  
accountName,  
CloseDate,  
amount,  
sum(amount) over (partition by owner order by CloseDate rows between unbounded preceding and current row) cumeWon,  
max(amount) over (partition by owner order by CloseDate rows between unbounded preceding and current row) runningMax 
from opportunities  
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09'  
order by owner, CloseDate;

```
 with example results:

 

| owner | accountName | CloseDate | amount | cumeWon | runningMax |
| --- | --- | --- | --- | --- | --- |
| Bill | Babbleopia | 2016-10-02 | 437636.47 | 437636.47 | 437636.47 |
| Bill | Thoughtworks | 2016-10-04 | 146086.51 | 583722.98 | 437636.47 |
| Bill | Latz | 2016-10-08 | 857254.87 | 1440977.85 | 857254.87 |
| Chris | Linkbridge | 2016-10-07 | 539977.45 | 539977.45 | 539977.45 |
| Chris | Avamm | 2016-10-09 | 699566.86 | 1239544.31 | 699566.86 |
| Olivier | Devpulse | 2016-10-05 | 834235.93 | 834235.93 | 834235.93 |
| Olivier | Trupe | 2016-10-07 | 500802.29 | 1335038.22 | 834235.93 |

 Ranking / Top Results
---------------------

 The rank window function allows for ranking or assigning a numeric order value based on the window function definition. Using the Rank() function will result in the same value for ties / equal values and the next rank value skipped. The Dense\_Rank() function behaves similarly except the next consecutive number is used after a tie rather than skipped. The Row\_Number() function will provide a unique ordering value. The example query shows the Rank() function being applied to rank sales reps by the number of opportunities for Q4 2016.

 
```

select owner, 
wonCount, 
rank() over (order by wonCount desc) rank 
from (
  select owner, 
  count(*) wonCount 
  from opportunities 
  where stageName='ClosedWon' 
  and closeDate >= '2016-10-01' and closeDate < '2016-12-31'  
  group by owner
) t
order by rank;

```
 with example results (note the query is technically incorrect by using closeDate < '2016-12-31' however this creates a tie scenario for illustrative purposes):

 

| owner | wonCount | rank |
| --- | --- | --- |
| Bill | 19 | 1 |
| Chris | 15 | 2 |
| Maria | 14 | 3 |
| Bob | 14 | 3 |
| Olivier | 10 | 5 |

 If the dense\_rank function is used the rank values would be 1,2,3,3,4 and for the row\_number function the values would be 1,2,3,4,5.

 First and Last Values
---------------------

 The first\_value and last\_value functions allow determining the first and last values of a given range. Combined with a group by this allows summarizing opening and closing values. The example shows a more complex case where detailed information is presented for first and last opportunity by quarter.

 
```

select a.year, 
a.quarter, 
f.accountName firstAccountName, 
f.owner firstOwner, 
f.amount firstAmount, 
l.accountName lastAccountName, 
l.owner lastOwner, 
l.amount lastAmount 
from (
  select year, 
  quarter, 
  min(firstId) firstId, 
  min(lastId) lastId 
  from (
    select year(closeDate) year, 
    quarter(closeDate) quarter, 
    first_value(id) over (partition by year(closeDate), quarter(closeDate) order by closeDate rows between unbounded preceding and current row) firstId, 
    last_value(id) over (partition by year(closeDate), quarter(closeDate) order by closeDate rows between current row and unbounded following) lastId 
    from opportunities  where stageName='ClosedWon'
  ) t 
  group by year, quarter order by year,quarter
) a 
join opportunities f on a.firstId = f.id 
join opportunities l on a.lastId = l.id 
order by year, quarter;

```
 with example results:

 

| year | quarter | firstAccountName | firstOwner | firstAmount | lastAccountName | lastOwner | lastAmount |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 2016 | 3 | Skidoo | Bill | 523295.07 | Skipstorm | Bill | 151420.86 |
| 2016 | 4 | Skimia | Chris | 961513.59 | Avamm | Maria | 112493.65 |
| 2017 | 1 | Yombu | Bob | 536875.51 | Skaboo | Chris | 270273.08 |

 Prior and Next Example
----------------------

 Sometimes it useful to understand the previous and next values in the context of a given row. The lag and lead window functions provide this capability. By default the offset is one providing the prior or next value but can also be provided to get a larger offset. The example query is a report of opportunities by account name showing the opportunity amount, and the prior and next opportunity amount for that account by close date.

 
```

select accountName, 
closeDate,  
amount currentOppAmount, 
lag(amount) over (partition by accountName order by closeDate) priorAmount, lead(amount) over (partition by accountName order by closeDate) nextAmount 
from opportunities 
order by accountName, closeDate 
limit 9;

```
 with example results:

 

| accountName | closeDate | currentOppAmount | priorAmount | nextAmount |
| --- | --- | --- | --- | --- |
| Abata | 2016-09-10 | 645098.45 | NULL | 161086.82 |
| Abata | 2016-10-14 | 161086.82 | 645098.45 | 350235.75 |
| Abata | 2016-12-18 | 350235.75 | 161086.82 | 878595.89 |
| Abata | 2016-12-31 | 878595.89 | 350235.75 | 922322.39 |
| Abata | 2017-01-21 | 922322.39 | 878595.89 | NULL |
| Abatz | 2016-10-19 | 795424.15 | NULL | NULL |
| Agimba | 2016-07-09 | 288974.84 | NULL | 914461.49 |
| Agimba | 2016-09-07 | 914461.49 | 288974.84 | 176645.52 |
| Agimba | 2016-09-20 | 176645.52 | 914461.49 | NULL |

 Quartiles Example
-----------------

 The NTile window function allows for breaking up a data set into portions assigned a numeric value to each portion of the range. NTile(4) breaks the data up into quartiles (4 sets). The example query produces a report of all opportunities summarizing the quartile boundaries of amount values.

 
```

select t.quartile, 
min(t.amount) min, 
max(t.amount) max 
from (
  select amount, 
  ntile(4) over (order by amount asc) quartile 
  from opportunities 
  where closeDate >= '2016-10-01' and closeDate <= '2016-12-31'
  ) t 
group by quartile 
order by quartile;

```
 With example results:

 

| quartile | min | max |
| --- | --- | --- |
| 1 | 6337.15 | 287634.01 |
| 2 | 288796.14 | 539977.45 |
| 3 | 540070.04 | 748727.51 |
| 4 | 753670.77 | 998864.47 |

 Percentile Example
------------------

 The percentile functions have a slightly different syntax from other window functions as can be seen in the example below. These functions can be only applied against numeric values. The argument to the function is the percentile to evaluate. Following 'within group' is the sort expression which indicates the sort column and optionally order. Finally after 'over' is an optional partition by clause, for no partition clause use 'over ()'. The example below utilizes the value 0.5 to calculate the median opportunity amount in the rows. The values differ sometimes because percentile\_cont will return the average of the 2 middle rows for an even data set while percentile\_desc returns the first encountered in the sort.

 
```

select owner,  
accountName,  
CloseDate,  
amount,
percentile_cont(0.5) within group (order by amount) over (partition by owner) pct_cont,
percentile_disc(0.5) within group (order by amount) over (partition by owner) pct_disc
from opportunities  
where stageName='ClosedWon' 
and closeDate >= '2016-10-02' and closeDate <= '2016-10-09'  
order by owner, CloseDate;

```
 With example results:

 

| owner | accountName | CloseDate | amount | pct\_cont | pct\_disc |
| --- | --- | --- | --- | --- | --- |
| Bill | Babbleopia | 2016-10-02 | 437636.47 | 437636.4700000000 | 437636.47 |
| Bill | Thoughtworks | 2016-10-04 | 146086.51 | 437636.4700000000 | 437636.47 |
| Bill | Latz | 2016-10-08 | 857254.87 | 437636.4700000000 | 437636.47 |
| Chris | Linkbridge | 2016-10-07 | 539977.45 | 619772.1550000000 | 539977.45 |
| Chris | Avamm | 2016-10-09 | 699566.86 | 619772.1550000000 | 539977.45 |
| Olivier | Devpulse | 2016-10-05 | 834235.93 | 667519.1100000000 | 500802.29 |
| Olivier | Trupe | 2016-10-07 | 500802.29 | 667519.1100000000 | 500802.29 |

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/window-functions-columnstore-window-functions/>

SET Commands
=============

  

| Title | Description |
| --- | --- |
|  [SET](../set/index) |  Set a variable value.  |
|  [SET CHARACTER SET](../set-character-set/index) |  Maps all strings sent between the current client and the server with the given mapping.  |
|  [SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER](../set-global-sql_slave_skip_counter/index) |  Skips a number of events from the primary.  |
|  [SET NAMES](../set-names/index) |  The character set used to send statements to the server, and results back to the client.  |
|  [SET PASSWORD](../set-password/index) |  Assign password to an existing MariaDB user.  |
|  [SET ROLE](../set-role/index) |  Enable a role.  |
|  [SET SQL\_LOG\_BIN](../set-sql_log_bin/index) |  Set binary logging for the current connection.  |
|  [SET STATEMENT](../set-statement/index) |  Set variable values on a per-query basis  |
|  [SET TRANSACTION](../set-transaction/index) |  Sets the transaction isolation level.  |
|  [SET Variable](../set-variable/index) |  Used to insert a value into a variable with a code block.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-commands/>

BACKUP Commands
================

   Commands used by backup tools

  

| Title | Description |
| --- | --- |
|  [BACKUP STAGE](../backup-stage/index) |  Commands to be used by a MariaDB backup tool.  |
|  [BACKUP LOCK](../backup-lock/index) |  Blocks a table from DDL statements.  |
|  [Mariabackup and BACKUP STAGE Commands](../mariabackup-and-backup-stage-commands/index) |  How Mariabackup could use BACKUP STAGE commands.  |
|  [Storage Snapshots and BACKUP STAGE Commands](../storage-snapshots-and-backup-stage-commands/index) |  How storage snapshots could use BACKUP STAGE commands.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-commands/>

DESCRIBE
========

    Syntax
------

 
```
{DESCRIBE | DESC} tbl_name [col_name | wild]

```
 Description
-----------

 `DESCRIBE` provides information about the columns in a table. It is a shortcut for `[SHOW COLUMNS FROM](../show-columns/index)`. These statements also display information for [views](../views/index).

 `col_name` can be a column name, or a string containing the SQL "`%`" and "`_`" wildcard characters to obtain output only for the columns with names matching the string. There is no need to enclose the string within quotes unless it contains spaces or other special characters.

 
```
DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| Id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name       | char(35) | YES  |     | NULL    |                |
| Country    | char(3)  | NO   | UNI |         |                |
| District   | char(20) | YES  | MUL |         |                |
| Population | int(11)  | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

```

The description for `[SHOW COLUMNS](../show-columns/index)` provides more information about the output columns.

 See Also
--------

 * [SHOW COLUMNS](../show-columns/index)
* [INFORMATION\_SCHEMA.COLUMNS Table](../information-schema-columns-table/index)
* [mysqlshow](../mysqlshow/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/describe/>

LEAD
====

    Syntax
------

 
```
LEAD (expr[, offset]) OVER ( 
  [ PARTITION BY partition_expression ] 
  [ ORDER BY order_list ]
)

```

Description
-----------

 The *LEAD* function accesses data from a following row in the same result set without the need for a self-join. The specific row is determined by the *offset* (default *1*), which specifies the number of rows ahead the current row to use. An offset of *0* is the current row.

 Example
-------

 
```
CREATE TABLE t1 (pk int primary key, a int, b int, c char(10), d decimal(10, 3), e real);

INSERT INTO t1 VALUES
 ( 1, 0, 1,    'one',    0.1,  0.001),
 ( 2, 0, 2,    'two',    0.2,  0.002),
 ( 3, 0, 3,    'three',  0.3,  0.003),
 ( 4, 1, 2,    'three',  0.4,  0.004),
 ( 5, 1, 1,    'two',    0.5,  0.005),
 ( 6, 1, 1,    'one',    0.6,  0.006),
 ( 7, 2, NULL, 'n_one',  0.5,  0.007),
 ( 8, 2, 1,    'n_two',  NULL, 0.008),
 ( 9, 2, 2,    NULL,     0.7,  0.009),
 (10, 2, 0,    'n_four', 0.8,  0.010),
 (11, 2, 10,   NULL,     0.9,  NULL);

SELECT pk, LEAD(pk) OVER (ORDER BY pk) AS l,
  LEAD(pk,1) OVER (ORDER BY pk) AS l1,
  LEAD(pk,2) OVER (ORDER BY pk) AS l2,
  LEAD(pk,0) OVER (ORDER BY pk) AS l0,
  LEAD(pk,-1) OVER (ORDER BY pk) AS lm1,
  LEAD(pk,-2) OVER (ORDER BY pk) AS lm2 
FROM t1;
+----+------+------+------+------+------+------+
| pk | l    | l1   | l2   | l0   | lm1  | lm2  |
+----+------+------+------+------+------+------+
|  1 |    2 |    2 |    3 |    1 | NULL | NULL |
|  2 |    3 |    3 |    4 |    2 |    1 | NULL |
|  3 |    4 |    4 |    5 |    3 |    2 |    1 |
|  4 |    5 |    5 |    6 |    4 |    3 |    2 |
|  5 |    6 |    6 |    7 |    5 |    4 |    3 |
|  6 |    7 |    7 |    8 |    6 |    5 |    4 |
|  7 |    8 |    8 |    9 |    7 |    6 |    5 |
|  8 |    9 |    9 |   10 |    8 |    7 |    6 |
|  9 |   10 |   10 |   11 |    9 |    8 |    7 |
| 10 |   11 |   11 | NULL |   10 |    9 |    8 |
| 11 | NULL | NULL | NULL |   11 |   10 |    9 |
+----+------+------+------+------+------+------+

```

See Also
--------

 * [LAG](../lag/index) - Window function to access a previous row

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lead/>

Atomic DDL
==========

    From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), we have improved readability for DDL (Data Definition Language) operations to make most of them atomic, and the rest crash-safe, even if the server crashes in the middle of an operation.

 The design of Atomic/Crash-safe DDL ([MDEV-17567](https://jira.mariadb.org/browse/MDEV-17567)) allows it to work with all storage engines.

 Definitions
-----------

 * Atomic means that either the operation succeeds (and is logged to the [binary log](../binary-log/index) or is completely reversed.
* Crash-safe means that in case of a crash, after the server has restarted, all tables are consistent, there are no temporary files or tables on disk and the binary log matches the status of the server.
* DDL Data definition language.
* DML Data manipulation language.
* 'DDL recovery log' or 'DDL log' for short, is the new log file, `ddl_recovery.log` by default, that stores all DDL operations in progress. This is used to recover the state of the server in case of sudden crash.

 Background
----------

 Before 10.6, in case of a crash, there was a small possibility that one of the following things could happen:

 * There could be temporary tables starting with `#sql-alter` or `#sql-shadow` or temporary files ending with '' left.
* The table in the storage engine and the table's .frm file could be out of sync.
* During a multi-table rename, only some of the tables were renamed.

 Which DDL Operations are Now Atomic
-----------------------------------

 * [CREATE TABLE](../create-table/index), except when used with [CREATE OR REPLACE](../create-table/index), which is only crash safe.
* [RENAME TABLE](../rename-table/index) and [RENAME TABLES](../rename-table/index).
* [CREATE VIEW](../create-view/index)
* [CREATE SEQUENCE](../create-sequence/index)
* [CREATE TRIGGER](../create-trigger/index)
* [DROP TRIGGER](../drop-trigger/index)
* [DROP TABLE](../drop-table/index) and [DROP VIEW](../drop-view/index). Dropping multiple tables is only crash safe.
* [ALTER TABLE](../alter-table/index)

 * [ALTER SEQUENCE](../alter-sequence/index) is not listed above as it is internally implemented as a DML.

 Which DDL Operations are Now Crash Safe
---------------------------------------

 ### DROP TABLE of Multiple Tables.

 [DROP TABLE](../drop-table/index) over multiple tables is treated as if every DROP is a separate, atomic operation. This means that after a crash, all fully, or partly, dropped tables will be dropped and logged to the binary log. The undropped tables will be left untouched.

 ### CREATE OR REPLACE TABLE

 [CREATE OR REPLACE TABLE foo](../create-table/index) is implemented as:

 
```
DROP TABLE IF EXISTS foo;
CREATE TABLE foo ...

```

This means that if there is a crash during `CREATE TABLE` then the original table 'foo' will be dropped even if the new table was not created. If the table was not re-created, the binary log will contain the `DROP TABLE`.

 #### DROP DATABASE

 [DROP DATABASE](../drop-database/index) is implemented as:

 
```
loop over all tables
  DROP TABLE table

```

Each [DROP TABLE](../drop-table/index) is atomic, but in case of a crash, things will work the same way as [DROP TABLE](../drop-table/index) with multiple tables.

 ### Atomic with Different Storage Engines

 Atomic/Crash-safe DDL works with all storage engines that either have atomic DDLs internally or are able to re-execute `DROP` or `RENAME` in case of failure.

 This should be true for most storage engines. The ones that still need some work are:

 * The [S3 storage engine](../s3-storage-engine/index).
* The [partitioning engine](../partitioning-tables/index). Partitioning should be atomic for most cases, but there are still some known issues that need to be tested and fixed.

 ### The DDL Log Recovery File

 The new startup option [--log-ddl-recovery=path](../mysqld-options/index#-log-ddl-recovery) (`ddl_recovery.log` by default) can be used to specify the place for the DDL log file. This is mainly useful in the case when one has a filesystem on persistent memory, as there is a lot of sync on this file during DDL operations.

 This file contains all DDL operations that are in progress.

 At MariaDB server startup, the DDL log file is copied to a file with the same base name but with a `-backup.log` suffix. This is mainly done to be able to find out what went wrong if recovery fails.

 If the server crashes during recovery (unlikely but possible), the recovery will continue where it was before. The recovery will retry each entry up to 3 times before giving up and proceeding with the next entry.

 ### Conclusions

 * We believe that a clean separation of layers leads to an easier-to-maintain solution. The Atomic DDL implementation in [MariaDB 10.6](../what-is-mariadb-106/index) introduced minimal changes to the storage engine API, mainly for native ALTER TABLE.
* In our InnoDB implementation, no file format changes were needed on top of the RENAME undo log that was introduced in [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) for a backup-safe TRUNCATE re-implementation. Correct use of sound design principles (write-ahead logging and transactions; also file creation now follows the ARIES protocol) is sufficient. We removed the hacks (at most one CREATE or DROP per transaction) and correctly implemented `rollback` and `purge` triggers for the InnoDB SYS\_INDEXES table.
* Numerous DDL recovery bugs in InnoDB were found and fixed quickly thanks to <https://rr-project.org>. We are still working on one: data files must not be deleted before the DDL transaction is committed.

 Thanks to Atomic/Crash-safe DDL, the MariaDB server is now much more stable and reliable in unstable environments. There is still ongoing work to fix the few remaining issues mentioned above to make all DDL operations Atomic. The target for these is [MariaDB 10.7](../what-is-mariadb-107/index).

 ### See Also

 * [MDEV-17567](https://jira.mariadb.org/browse/MDEV-17567) Atomic DDL. This MDEV entry links to all other entries related to Atomic operations that contains a lot of information how things are implemented.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/atomic-ddl/>

Changing & Deleting Data
=========================

  

| Title | Description |
| --- | --- |
|  [DELETE](../delete/index) |  Delete rows from one or more tables.  |
|  [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index) |  Modifying statement priority in storage engines supporting table-level locks.  |
|  [IGNORE](../ignore/index) |  Suppress errors while trying to violate a UNIQUE constraint.  |
|  [REPLACE](../replace/index) |  Equivalent to DELETE + INSERT, or just an INSERT if no rows are returned.  |
|  [REPLACE...RETURNING](../replacereturning/index) |  Returns a resultset of the replaced rows.  |
|  [TRUNCATE TABLE](../truncate-table/index) |  DROP and re-CREATE a table.  |
|  [UPDATE](../update/index) |  Modify rows in one or more tables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/changing-deleting-data/>

LOAD INDEX
==========

    Syntax
------

 
```
LOAD INDEX INTO CACHE
  tbl_index_list [, tbl_index_list] ...

tbl_index_list:
  tbl_name
    [[INDEX|KEY] (index_name[, index_name] ...)]
    [IGNORE LEAVES]

```

Description
-----------

 The `LOAD INDEX INTO CACHE` statement preloads a table index into the key cache to which it has been assigned by an explicit [`CACHE INDEX`](../cache-index/index) statement, or into the default key cache otherwise. `LOAD INDEX INTO CACHE` is used only for [MyISAM](../myisam/index) or [Aria](../aria/index) tables.

 The `IGNORE LEAVES` modifier causes only blocks for the nonleaf nodes of the index to be preloaded.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-index/>

Selecting Data
===============

   The `SELECT` statement is used for retrieving data from tables, for select specific data, often based on a criteria given in the `WHERE` clause.

  

| Title | Description |
| --- | --- |
|  [SELECT](../select/index) |  SQL statement used primarily for retrieving data from a MariaDB database.  |
|  [Joins & Subqueries](../joins-subqueries/index) |  Documentation on the JOIN, UNION, EXCEPT and INTERSECT clauses, and on subqueries.  |
|  [LIMIT](../limit/index) |  Documentation of the LIMIT clause.  |
|  [ORDER BY](../order-by/index) |  Order the results returned from a resultset.  |
|  [GROUP BY](../group-by/index) |  Aggregate data in a SELECT statement with the GROUP BY clause.  |
|  [Common Table Expressions](../common-table-expressions/index) |  Common table expressions are temporary named result sets.  |
|  [SELECT WITH ROLLUP](../select-with-rollup/index) |  Adds extra rows to the resultset that represent super-aggregate summaries  |
|  [SELECT INTO OUTFILE](../select-into-outfile/index) |  Write the resultset to a formatted file  |
|  [SELECT INTO DUMPFILE](../select-into-dumpfile/index) |  Write a binary string into file  |
|  [FOR UPDATE](../for-update/index) |  Acquires a lock on the rows  |
|  [LOCK IN SHARE MODE](../lock-in-share-mode/index) |  Acquires a write lock.  |
|  [Optimizer Hints](../optimizer-hints/index) |  Optimizer hints There are some options available in SELECT to affect the ex...  |
|  [PROCEDURE](../procedure/index) |  The PROCEDURE Clause of the SELECT Statement.  |
|  [HANDLER](../handler/index) |  Direct access to reading rows from the storage engine.  |
|  [DUAL](../dual/index) |  Dummy table name  |
|  [SELECT ... OFFSET ... FETCH](../select-offset-fetch/index) |  Allows one to specify an offset, a number of rows to be returned, and wheth...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/selecting-data/>

Window Frames
=============

    Syntax
------

 
```
frame_clause:
  {ROWS | RANGE} {frame_border | BETWEEN frame_border AND frame_border}

frame_border:
  | UNBOUNDED PRECEDING
  | UNBOUNDED FOLLOWING
  | CURRENT ROW
  | expr PRECEDING
  | expr FOLLOWING

```

Description
-----------

 A basic overview of [window functions](../window-functions/index) is described in [Window Functions Overview](../window-functions-overview/index). Window frames expand this functionality by allowing the function to include a specified a number of rows around the current row.

 These include:

 * All rows before the current row (UNBOUNDED PRECEDING), for example `RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`
* All rows after the current row (UNBOUNDED FOLLOWING), for example `RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING`
* A set number of rows before the current row (expr PRECEDING) for example `RANGE BETWEEN 6 PRECEDING AND CURRENT ROW`
* A set number of rows after the current row (expr PRECEDING AND expr FOLLOWING) for example `RANGE BETWEEN CURRENT ROW AND 2 FOLLOWING`
* A specified number of rows both before and after the current row, for example `RANGE BETWEEN 6 PRECEDING AND 3 FOLLOWING`

 The following functions operate on window frames:

 * [AVG](../avg/index)
* [BIT\_AND](../bit_and/index)
* [BIT\_OR](../bit_or/index)
* [BIT\_XOR](../bit_xor/index)
* [COUNT](../count/index)
* [LEAD](../lead/index)
* [MAX](../max/index)
* [MIN](../min/index)
* [NTILE](../ntile/index)
* [STD](../std/index)
* [STDDEV](../stddev/index)
* [STDDEV\_POP](../stddev_pop/index)
* [STDDEV\_SAMP](../stddev_samp/index)
* [SUM](../sum/index)
* [VAR\_POP](../var_pop/index)
* [VAR\_SAMP](../var_samp/index)
* [VARIANCE](../variance/index)

 Window frames are determined by the *frame\_clause* in the window function request. 

 Take the following example:

 
```
CREATE TABLE `student_test` (
  name char(10),
  test char(10),
  score tinyint(4)
);

INSERT INTO student_test VALUES 
    ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
    ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
    ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
    ('Tatiana', 'SQL', 87);

SELECT name, test, score, SUM(score) 
  OVER () AS total_score 
  FROM student_test;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Chun    | SQL    |    75 |         453 |
| Chun    | Tuning |    73 |         453 |
| Esben   | SQL    |    43 |         453 |
| Esben   | Tuning |    31 |         453 |
| Kaolin  | SQL    |    56 |         453 |
| Kaolin  | Tuning |    88 |         453 |
| Tatiana | SQL    |    87 |         453 |
+---------+--------+-------+-------------+

```

By not specifying an OVER clause, the [SUM](../sum/index) function is run over the entire dataset. However, if we specify an ORDER BY condition based on score (and order the entire result in the same way for clarity), the following result is returned:

 
```
SELECT name, test, score, SUM(score) 
  OVER (ORDER BY score) AS total_score 
  FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |         130 |
| Chun    | Tuning |    73 |         203 |
| Chun    | SQL    |    75 |         278 |
| Tatiana | SQL    |    87 |         365 |
| Kaolin  | Tuning |    88 |         453 |
+---------+--------+-------+-------------+

```

The total\_score column represents a running total of the current row, and all previous rows. The window frame in this example expands as the function proceeds.

 The above query makes use of the default to define the window frame. It could be written explicitly as follows:

 
```
SELECT name, test, score, SUM(score) 
  OVER (ORDER BY score RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_score 
  FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |         130 |
| Chun    | Tuning |    73 |         203 |
| Chun    | SQL    |    75 |         278 |
| Tatiana | SQL    |    87 |         365 |
| Kaolin  | Tuning |    88 |         453 |
+---------+--------+-------+-------------+

```

Let's look at some alternatives:

 Firstly, applying the window function to the current row and all following rows can be done with the use of UNBOUNDED FOLLOWING:

 
```
SELECT name, test, score, SUM(score) 
  OVER (ORDER BY score RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS total_score 
  FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |         453 |
| Esben   | SQL    |    43 |         422 |
| Kaolin  | SQL    |    56 |         379 |
| Chun    | Tuning |    73 |         323 |
| Chun    | SQL    |    75 |         250 |
| Tatiana | SQL    |    87 |         175 |
| Kaolin  | Tuning |    88 |          88 |
+---------+--------+-------+-------------+

```

It's possible to specify a number of rows, rather than the entire unbounded following or preceding set. The following example takes the current row, as well as the previous row:

 
```
SELECT name, test, score, SUM(score) 
  OVER (ORDER BY score ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS total_score 
  FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          31 |
| Esben   | SQL    |    43 |          74 |
| Kaolin  | SQL    |    56 |          99 |
| Chun    | Tuning |    73 |         129 |
| Chun    | SQL    |    75 |         148 |
| Tatiana | SQL    |    87 |         162 |
| Kaolin  | Tuning |    88 |         175 |
+---------+--------+-------+-------------+

```

The current row and the following row:

 
```
SELECT name, test, score, SUM(score) 
  OVER (ORDER BY score ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS total_score 
  FROM student_test ORDER BY score;
+---------+--------+-------+-------------+
| name    | test   | score | total_score |
+---------+--------+-------+-------------+
| Esben   | Tuning |    31 |          74 |
| Esben   | SQL    |    43 |         130 |
| Kaolin  | SQL    |    56 |         172 |
| Chun    | Tuning |    73 |         204 |
| Chun    | SQL    |    75 |         235 |
| Tatiana | SQL    |    87 |         250 |
| Kaolin  | Tuning |    88 |         175 |
+---------+--------+-------+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/window-frames/>

Out Parameters in PREPARE
=========================

    
**MariaDB [10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)**Out parameters in PREPARE were only available in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 
One can use question mark placeholders for out-parameters in the [PREPARE](../prepare-statement/index) statement. Only [SELECT … INTO](../select/index#into) can be used this way:

 
```
prepare test from "select id into ? from t1 where val=?";
execute test using @out, @in;

```

This is particularly convenient when used with [compound statements](../using-compound-statements-outside-of-stored-programs/index):

 
```
PREPARE stmt FROM "BEGIN NOT ATOMIC
  DECLARE v_res INT;
  SELECT COUNT(*) INTO v_res FROM t1;
  SELECT 'Hello World', v_res INTO ?,?;
END"|

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/out-parameters-in-prepare/>

SQL statements That Cause an Implicit Commit
============================================

    Some SQL statements cause an implicit commit. As a rule of thumb, such statements are DDL statements. The same statements (except for [SHUTDOWN](../shutdown/index)) produce a 1400 error ([SQLSTATE](../sqlstate/index) 'XAE09') if a XA transaction is in effect.

 Here is the list:

 
```
ALTER DATABASE ... UPGRADE DATA DIRECTORY NAME
ALTER EVENT
ALTER FUNCTION
ALTER PROCEDURE
ALTER SEQUENCE
ALTER SERVER
ALTER TABLE
ALTER VIEW
ANALYZE TABLE
BEGIN
CACHE INDEX
CHANGE MASTER TO
CHECK TABLE
CREATE DATABASE
CREATE EVENT
CREATE FUNCTION
CREATE INDEX
CREATE PROCEDURE
CREATE ROLE
CREATE SEQUENCE
CREATE SERVER
CREATE TABLE
CREATE TRIGGER
CREATE USER
CREATE VIEW
DROP DATABASE
DROP EVENT
DROP FUNCTION
DROP INDEX
DROP PROCEDURE
DROP ROLE
DROP SEQUENCE
DROP SERVER
DROP TABLE
DROP TRIGGER
DROP USER
DROP VIEW
FLUSH
GRANT
LOAD INDEX INTO CACHE
LOCK TABLES
OPTIMIZE TABLE
RENAME TABLE
RENAME USER
REPAIR TABLE
RESET
REVOKE
SET PASSWORD
SHUTDOWN
START SLAVE
START TRANSACTION
STOP SLAVE
TRUNCATE TABLE

```

`SET autocommit = 1` causes an implicit commit if the value was 0.

 All these statements cause an implicit commit before execution. This means that, even if the statement fails with an error, the transaction is committed. Some of them, like `CREATE TABLE ... SELECT`, also cause a commit immediatly after execution. Such statements couldn't be rollbacked in any case.

 If you are not sure whether a statement has implicitly committed the current transaction, you can query the [in\_transaction](../server-system-variables/index#in_transaction) server system variable.

 Note that when a transaction starts (not in autocommit mode), all locks acquired with [LOCK TABLES](../lock-tables-and-unlock-tables/index) are released. And acquiring such locks always commits the current transaction. To preserve the data integrity between transactional and non-transactional tables, the [GET\_LOCK()](../get_lock/index) function can be used.

 Exceptions
----------

 These statements do not cause an implicit commit in the following cases:

 * `CREATE TABLE` and `DROP TABLE`, when the `TEMPORARY` keyword is used.
	+ However, TRUNCATE TABLE causes an implicit commit even when used on a temporary table.
* `CREATE FUNCTION` and `DROP FUNCTION`, when used to create a UDF (instead of a stored function). However, `CREATE INDEX` and `DROP INDEX` cause commits even when used with temporary tables.
* `UNLOCK TABLES` causes a commit only if a `LOCK TABLES` was used on non-transactional tables.
* `START SLAVE`, `STOP SLAVE`, `RESET SLAVE` and `CHANGE MASTER TO` only cause implicit commit since [MariaDB 10.0](../what-is-mariadb-100/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-statements-that-cause-an-implicit-commit/>

ACID: Concurrency Control with Transactions
===========================================

    Database requests happen in linear fashion, one after another. When many users are accessing a database, or one user has a related set of requests to run, it becomes important to ensure that the results remain consistent. To achieve this, you use *transactions*, which are groups of database requests that are processed as a whole. Put another way, they are logical units of work.

 To ensure data integrity, transactions need to adhere to four conditions: atomicity, consistency, isolation and durability (ACID).

 ### Atomicity

 *Atomicity* means the entire transaction must complete. If this is not the case, the entire transaction is aborted. This ensures that the database can never be left with partially completed transactions, which lead to poor data integrity. If you remove money out of one bank account, for example, but the second request fails and the system cannot place the money in another bank, both requests must fail. The money cannot simply be lost, or taken from one account without going into the other.

 ### Consistency

 *Consistency* refers to the state the data is in when certain conditions are met. For example, one rule may be that each invoice must relate to a customer in the customer table. These rules may be broken during the course of a transaction if, for example the invoice is inserted without a related customer, which is added at a later stage in the transaction. These temporary violations are not visible outside of the transaction, and will always be resolved by the time the transaction is complete.

 ### Isolation

 *Isolation* means that any data being used during the processing of one transaction cannot be used by another transaction until the first transaction is complete. For example, if two people deposit $100 into another account with a balance of $900, the first transaction must add $100 to $900, and the second must add $100 to $1000. If the second transaction reads the $900 before the first transaction has completed, both transactions will seem to succeed, but $100 will have gone missing. The second transaction must wait until it alone is accessing the data.

 ### Durability

 *Durability* refers to the fact that once data from a transaction has been committed, its effects will remain, even after a system failure. While a transaction is under way, the effects are not persistent. If the database crashes, backups will always restore it to a consistent state prior to the transaction commencing. Nothing a transaction does should be able to change this fact.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/acid-concurrency-control-with-transactions/>

UNLOCK TABLES
=============

    Syntax
------

 
```
UNLOCK TABLES

```
 Description
-----------

 `UNLOCK TABLES` explicitly releases any table locks held by the current session. See `[LOCK TABLES](../lock-tables/index)` for more information.

 In addition to releasing table locks acquired by the `[LOCK TABLES](../lock-tables/index)` statement, the `UNLOCK TABLES` statement also releases the global read lock acquired by the `FLUSH TABLES WITH READ LOCK` statement. The `FLUSH TABLES WITH READ LOCK` statement is very useful for performing backups. See `[FLUSH](../flush/index)` for more information about `FLUSH TABLES WITH READ LOCK`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-unlock-tables/>

mysql.help\_relation Table
==========================

    `mysql.help_relation` is one of the four tables used by the [HELP command](../help-command/index). It is populated when the server is installed by the `fill_help_tables.sql` script. The other help tables are [help\_topic](../mysqlhelp_topic-table/index), [help\_category](../mysqlhelp_category-table/index) and [help\_keyword](../mysqlhelp_keyword-table/index).

 This table uses the [Aria](../aria/index) storage engine. Prior to [MariaDB 10.4](../what-is-mariadb-104/index) it used the [MyISAM](../myisam/index) engine.

 The `mysql.help_relation` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `help_topic_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `help_keyword_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |

 
Example
-------

 
```
...
|           106 |             456 |
|           463 |             456 |
|           468 |             456 |
|           463 |             457 |
|           194 |             458 |
|           478 |             458 |
|           374 |             459 |
|           459 |             459 |
|            39 |             460 |
|            58 |             460 |
|           185 |             460 |
|           264 |             460 |
|           269 |             460 |
|           209 |             461 |
|           468 |             461 |
|           201 |             462 |
|           468 |             463 |
+---------------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhelp_relation-table/>

XA Transactions
===============

    Overview
--------

 The MariaDB XA implementation is based on the X/Open CAE document Distributed Transaction Processing: The XA Specification. This document is published by The Open Group and available at <http://www.opengroup.org/public/pubs/catalog/c193.htm>.

 XA transactions are designed to allow distributed transactions, where a transaction manager (the application) controls a transaction which involves multiple resources. Such resources are usually DBMSs, but could be resources of any type. The whole set of required transactional operations is called a global transaction. Each subset of operations which involve a single resource is called a local transaction. XA used a 2-phases commit (2PC). With the first commit, the transaction manager tells each resource to prepare an effective commit, and waits for a confirm message. The changes are not still made effective at this point. If any of the resources encountered an error, the transaction manager will rollback the global transaction. If all resources communicate that the first commit is successful, the transaction manager can require a second commit, which makes the changes effective.

 In MariaDB, XA transactions can only be used with storage engines that support them. At least [InnoDB](../innodb/index), [TokuDB](../tokudb/index), [SPIDER](../spider/index) and [MyRocks](../myrocks/index) support them. For InnoDB, until [MariaDB 10.2](../what-is-mariadb-102/index), XA transactions can be disabled by setting the [innodb\_support\_xa](../innodb-system-variables/index#innodb_support_xa) server system variable to 0. From [MariaDB 10.3](../what-is-mariadb-103/index), XA transactions are always supported.

 Like regular transactions, XA transactions create [metadata locks](../metadata-locking/index) on accessed tables.

 XA transactions require [REPEATABLE READ](../set-transaction/index#repeatable-read) as a minimum isolation level. However, distributed transactions should always use [SERIALIZABLE](../set-transaction/index#serializable).

 Trying to start more than one XA transaction at the same time produces a 1400 error ([SQLSTATE](../sqlstate/index) 'XAE09'). The same error is produced when attempting to start an XA transaction while a regular transaction is in effect. Trying to start a regular transaction while an XA transaction is in effect produces a 1399 error ([SQLSTATE](../sqlstate/index) 'XAE07').

 The [statements that cause an implicit COMMIT](../sql-statements-that-cause-an-implicit-commit/index) for regular transactions produce a 1400 error ([SQLSTATE](../sqlstate/index) 'XAE09') if a XA transaction is in effect.

 Internal XA vs External XA
--------------------------

 XA transactions are an overloaded term in MariaDB. If a [storage engine](../storage-engines/index) is XA-capable, it can mean one or both of these:

 * It supports MariaDB's internal two-phase commit API. This is transparent to the user. Sometimes this is called "internal XA", since MariaDB's internal [transaction coordinator log](../transaction-coordinator-log/index) can handle coordinating these transactions.

 * It supports XA transactions, with the `XA START`, `XA PREPARE`, `XA COMMIT`, etc. statements. Sometimes this is called "external XA", since it requires the use of an external transaction coordinator to use this feature properly.

 Transaction Coordinator Log
---------------------------

 If you have two or more XA-capable storage engines enabled, then a transaction coordinator log must be available.

 There are currently two implementations of the transaction coordinator log:

 * Binary log-based transaction coordinator log
* Memory-mapped file-based transaction coordinator log

 If the [binary log](../binary-log/index) is enabled on a server, then the server will use the binary log-based transaction coordinator log. Otherwise, it will use the memory-mapped file-based transaction coordinator log.

 See [Transaction Coordinator Log](../transaction-coordinator-log/index) for more information.

 Syntax
------

 
```
XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER [FORMAT=['RAW'|'SQL']]

xid: gtrid [, bqual [, formatID ]]

```

The interface to XA transactions is a set of SQL statements starting with `XA`. Each statement changes a transaction's state, determining which actions it can perform. A transaction which does not exist is in the `NON-EXISTING` state.

 `XA START` (or `BEGIN`) starts a transaction and defines its `xid` (a transaction identifier). The `JOIN` or `RESUME` keywords have no effect. The new transaction will be in `ACTIVE` state.

 The `xid` can have 3 components, though only the first one is mandatory. `gtrid` is a quoted string representing a global transaction identifier. `bqual` is a quoted string representing a local transaction identifier. `formatID` is an unsigned integer indicating the format used for the first two components; if not specified, defaults to 1. MariaDB does not interpret in any way these components, and only uses them to identify a transaction. `xid`s of transactions in effect must be unique.

 `XA END` declares that the specified `ACTIVE` transaction is finished and it changes its state to `IDLE`. `SUSPEND [FOR MIGRATE]` has no effect.

 `XA PREPARE` prepares an `IDLE` transaction for commit, changing its state to `PREPARED`. This is the first commit.

 `XA COMMIT` definitely commits and terminates a transaction which has already been `PREPARED`. If the `ONE PHASE` clause is specified, this statements performs a 1-phase commit on an `IDLE` transaction.

 `XA ROLLBACK` rolls back and terminates an `IDLE` or `PREPARED` transaction.

 `XA RECOVER` shows information about all `PREPARED` transactions.

 When trying to execute an operation which is not allowed for the transaction's current state, an error is produced:

 
```
XA COMMIT 'test' ONE PHASE;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state

XA COMMIT 'test2';
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  NON-EXISTING state

```

XA RECOVER
----------

 The `XA RECOVER` statement shows information about all transactions which are in the `PREPARED` state. It does not matter which connection created the transaction: if it has been `PREPARED`, it appears. But this does not mean that a connection can commit or rollback a transaction which was started by another connection. Note that transactions using a 1-phase commit are never in the `PREPARED` state, so they cannot be shown by `XA RECOVER`.

 `XA RECOVER` produces four columns:

 
```
XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            4 |            0 | test |
+----------+--------------+--------------+------+

```


**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**You can use `XA RECOVER FORMAT='SQL'` to get the data in a human readable form that can be directly copy-pasted into `XA COMMIT` or `XA ROLLBACK`. This is particularly useful for binary `xid` generated by some transaction coordinators.

 
`formatID` is the `formatID` part of `xid`.

 `data` are the `gtrid` and `bqual` parts of `xid`, concatenated.

 `gtrid_length` and `bqual_length` are the lengths of `gtrid` and `bqual`, respectevely.

 Examples
--------

 2-phases commit:

 
```
XA START 'test';

INSERT INTO t VALUES (1,2);

XA END 'test';

XA PREPARE 'test';

XA COMMIT 'test';

```

1-phase commit:

 
```
XA START 'test';

INSERT INTO t VALUES (1,2);

XA END 'test';

XA COMMIT 'test' ONE PHASE;

```

Human-readable:

 
```
xa start '12\r34\t67\v78', 'abc\ndef', 3;

insert t1 values (40);

xa end '12\r34\t67\v78', 'abc\ndef', 3;

xa prepare '12\r34\t67\v78', 'abc\ndef', 3;

xa recover format='RAW';
+----------+--------------+--------------+--------------------+
| formatID | gtrid_length | bqual_length | data               |
+----------+--------------+--------------+--------------------+
34      67v78abc       11 |            7 | 12
def |
+----------+--------------+--------------+--------------------+

xa recover format='SQL';
+----------+--------------+--------------+-----------------------------------------------+
| formatID | gtrid_length | bqual_length | data                                          |
+----------+--------------+--------------+-----------------------------------------------+
|        3 |           11 |            7 | X'31320d3334093637763738',X'6162630a646566',3 |
+----------+--------------+--------------+-----------------------------------------------+

xa rollback X'31320d3334093637763738',X'6162630a646566',3;

```

Known Issues
------------

 ### MariaDB Galera Cluster

 [MariaDB Galera Cluster](../galera-cluster/index) does not support XA transactions.

 However, [MariaDB Galera Cluster](../galera-cluster/index) builds include a built-in plugin called `wsrep`. Prior to [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), this plugin was internally considered an [XA-capable](index) [storage engine](../storage-engines/index). Consequently, these [MariaDB Galera Cluster](../galera-cluster/index) builds have multiple XA-capable storage engines by default, even if the only "real" storage engine that supports external [XA transactions](index) enabled on these builds by default is [InnoDB](../innodb/index). Therefore, when using one these builds MariaDB would be forced to use a [transaction coordinator log](../transaction-coordinator-log/index) by default, which could have performance implications.

 See [Transaction Coordinator Log Overview: MariaDB Galera Cluster](../transaction-coordinator-log-overview/index#mariadb-galera-cluster) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xa-transactions/>

mysql.help\_category Table
==========================

    `mysql.help_category` is one of the four tables used by the [HELP command](../help-command/index). It is populated when the server is installed by the `fill_help_tables.sql` script. The other help tables are [help\_relation](../mysqlhelp_relation-table/index), [help\_topic](../mysqlhelp_topic-table/index) and [help\_keyword](../mysqlhelp_keyword-table/index).

 This table uses the [Aria](../aria/index) storage engine. Prior to [MariaDB 10.4](../what-is-mariadb-104/index) it used the [MyISAM](../myisam/index) engine.

 The `mysql.help_category` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `help_category_id` | `smallint(5) unsigned` | NO | PRI | `NULL` |  |
| `name` | `char(64)` | NO | UNI | `NULL` |  |
| `parent_category_id` | `smallint(5) unsigned` | YES |  | `NULL` |  |
| `url` | `char(128)` | NO |  | `NULL` |  |

 
Example
-------

 
```
SELECT * FROM help_category;
+------------------+-----------------------------------------------+--------------------+-----+
| help_category_id | name                                          | parent_category_id | url |
+------------------+-----------------------------------------------+--------------------+-----+
|                1 | Geographic                                    |                  0 |     |
|                2 | Polygon properties                            |                 34 |     |
|                3 | WKT                                           |                 34 |     |
|                4 | Numeric Functions                             |                 38 |     |
|                5 | Plugins                                       |                 35 |     |
|                6 | MBR                                           |                 34 |     |
|                7 | Control flow functions                        |                 38 |     |
|                8 | Transactions                                  |                 35 |     |
|                9 | Help Metadata                                 |                 35 |     |
|               10 | Account Management                            |                 35 |     |
|               11 | Point properties                              |                 34 |     |
|               12 | Encryption Functions                          |                 38 |     |
|               13 | LineString properties                         |                 34 |     |
|               14 | Miscellaneous Functions                       |                 38 |     |
|               15 | Logical operators                             |                 38 |     |
|               16 | Functions and Modifiers for Use with GROUP BY |                 35 |     |
|               17 | Information Functions                         |                 38 |     |
|               18 | Comparison operators                          |                 38 |     |
|               19 | Bit Functions                                 |                 38 |     |
|               20 | Table Maintenance                             |                 35 |     |
|               21 | User-Defined Functions                        |                 35 |     |
|               22 | Data Types                                    |                 35 |     |
|               23 | Compound Statements                           |                 35 |     |
|               24 | Geometry constructors                         |                 34 |     |
|               25 | GeometryCollection properties                 |                  1 |     |
|               26 | Administration                                |                 35 |     |
|               27 | Data Manipulation                             |                 35 |     |
|               28 | Utility                                       |                 35 |     |
|               29 | Language Structure                            |                 35 |     |
|               30 | Geometry relations                            |                 34 |     |
|               31 | Date and Time Functions                       |                 38 |     |
|               32 | WKB                                           |                 34 |     |
|               33 | Procedures                                    |                 35 |     |
|               34 | Geographic Features                           |                 35 |     |
|               35 | Contents                                      |                  0 |     |
|               36 | Geometry properties                           |                 34 |     |
|               37 | String Functions                              |                 38 |     |
|               38 | Functions                                     |                 35 |     |
|               39 | Data Definition                               |                 35 |     |
+------------------+-----------------------------------------------+--------------------+-----+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhelp_category-table/>

mysql.help\_keyword Table
=========================

    `mysql.help_keyword` is one of the four tables used by the [HELP command](../help-command/index). It is populated when the server is installed by the `fill_help_tables.sql` script. The other help tables are [help\_relation](../mysqlhelp_relation-table/index), [help\_category](../mysqlhelp_category-table/index) and [help\_topic](../mysqlhelp_topic-table/index).

 This table uses the [Aria](../aria/index) storage engine. Prior to [MariaDB 10.4](../what-is-mariadb-104/index) it used the [MyISAM](../myisam/index) engine.

 The `mysql.help_keyword` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `help_keyword_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `name` | `char(64)` | NO | UNI | `NULL` |  |

 
Example
-------

 
```
SELECT * FROM help_keyword;
+-----------------+-------------------------------+
| help_keyword_id | name                          |
+-----------------+-------------------------------+
|               0 | JOIN                          |
|               1 | HOST                          |
|               2 | REPEAT                        |
|               3 | SERIALIZABLE                  |
|               4 | REPLACE                       |
|               5 | AT                            |
|               6 | SCHEDULE                      |
|               7 | RETURNS                       |
|               8 | STARTS                        |
|               9 | MASTER_SSL_CA                 |
|              10 | NCHAR                         |
|              11 | COLUMNS                       |
|              12 | COMPLETION                    |
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhelp_keyword-table/>

mysql.help\_topic Table
=======================

    `mysql.help_topic` is one of the four tables used by the [HELP command](../help-command/index). It is populated when the server is installed by the `fill_help_tables.sql` script. The other help tables are [help\_relation](../mysqlhelp_relation-table/index), [help\_category](../mysqlhelp_category-table/index) and [help\_keyword](../mysqlhelp_keyword-table/index).

 This table uses the [Aria](../aria/index) storage engine. Prior to [MariaDB 10.4](../what-is-mariadb-104/index) it used the [MyISAM](../myisam/index) engine.

 The `mysql.help_topic` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `help_topic_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `name` | `char(64)` | NO | UNI | `NULL` |  |
| `help_category_id` | `smallint(5) unsigned` | NO |  | `NULL` |  |
| `description` | `text` | NO |  | `NULL` |  |
| `example` | `text` | NO |  | `NULL` |  |
| `url` | `char(128)` | NO |  | `NULL` |  |

 
Example
-------

 
```
SELECT * FROM help_topic\G;
...
*************************** 704. row ***************************
   help_topic_id: 692
            name: JSON_DEPTH
help_category_id: 41
     description: JSON functions were added in MariaDB 10.2.3.
 
Syntax
------ 
JSON_DEPTH(json_doc)
 
Description
----------- 
Returns the maximum depth of the given JSON document, or
NULL if the argument is null. An error will occur if the
argument is an invalid JSON document.
Scalar values or empty arrays or objects have a depth of 1.
Arrays or objects that are not empty but contain only
elements or member values of depth 1 will have a depth of 2.
In other cases, the depth will be greater than 2.
 
Examples
-------- 
SELECT JSON_DEPTH('[]'), JSON_DEPTH('true'),
JSON_DEPTH('{}');
+------------------+--------------------+------------------+
| JSON_DEPTH('[]') | JSON_DEPTH('true') |
JSON_DEPTH('{}') |
+------------------+--------------------+------------------+
| 1 | 1 | 1 |
+------------------+--------------------+------------------+
 
SELECT JSON_DEPTH('[1, 2, 3]'), JSON_DEPTH('[[], {},
[]]');
+-------------------------+----------------------------+
| JSON_DEPTH('[1, 2, 3]') | JSON_DEPTH('[[], {}, []]') |
+-------------------------+----------------------------+
| 2 | 2 |
+-------------------------+----------------------------+
 
SELECT JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]');
+---------------------------------------+
| JSON_DEPTH('[1, 2, [3, 4, 5, 6], 7]') |
+---------------------------------------+
| 3 |
+---------------------------------------+

URL: https://mariadb.com/kb/en/json_depth/
         example: 
             url: https://mariadb.com/kb/en/json_depth/

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhelp_topic-table/>

Binary Log Formats
==================

    Supported Binary Log Formats
----------------------------

 There are three supported formats for [binary log](../binary-log/index) events:

 * Statement-Based Logging
* Row-Based Logging
* Mixed Logging

 Regardless of the format, [binary log](../binary-log/index) events are always stored in a binary format, rather than in plain text. MariaDB includes the [mariadb-binlog](../mariadb-binlog/index) utility that can be used to output [binary log](../binary-log/index) events in a human-readable format.

 You may want to set the binary log format in the following cases:

 * If you execute single statements that update many rows, then statement-based logging will be more efficient than row-based logging for the replica to download.
* If you execute many statements that don't affect any rows, then row-based logging will be more efficient than statement-based logging for the replica to download.
* If you execute statements that take a long time to complete, but they ultimately only insert, update, or delete a few rows in the table, then row-based logging will be more efficient than statement-based logging for the replica to apply.

 The default is [mixed logging](index#mixed-logging) which is replication-safe and requires less storage space than [row logging](index#row-based-logging).

 The storage engine API also allows storage engines to set or limit the logging format, which helps reduce errors with replicating between primaries and replicas with different storage engines.

 ### Statement-Based Logging

 In [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) and before, statement-based logging was the default. [Mixed logging](index#mixed-logging) is now the default.

 When statement-based logging is enabled, statements are logged to the [binary log](../binary-log/index) exactly as they were executed. Temporary tables created on the primary will also be created on the replica. This mode is only recommended where one needs to keep the binary log as small as possible, the primary and replica have identical data (including using the same storage engines for all tables), and all functions being used are deterministic (repeatable with the same arguments). Statements and tables using timestamps or auto\_increment are safe to use with statement-based logging.

 This mode can be enabled by setting the [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) system variable to `STATEMENT`.

 In certain cases when it would be impossible to execute the statement on the replica, the server will switch to row-based logging for the statement. Some cases of this are:

 * When replication has been changed from row-based to statement-based and a statement uses data from a temporary table created during row-based mode. In this case, the temporary tables are not stored on the replica, so row logging is the only alternative.
* [ALTER TABLE](../alter-table/index) of a table using a storage engine that stores data remotely, such as the [S3 storage engine](../s3-storage-engine/index), to another storage engine.
* One is using [SEQUENCE's](../sequences/index) in the statement or the [CREATE TABLE](../create-table/index) definition.

 In certain cases, a statement may not be deterministic, and therefore not safe for [replication](../replication/index). If MariaDB determines that an unsafe statement has been executed, then it will issue a warning. For example:

 
```
[Warning] Unsafe statement written to the binary log using statement format since 
  BINLOG_FORMAT = STATEMENT. The statement is unsafe because it uses a LIMIT clause. This 
  is unsafe because the set of rows included cannot be predicted.

```

See [Unsafe Statements for Statement-based Replication](../unsafe-statements-for-statement-based-replication/index) for more information.

 If you need to execute non-deterministic statements, then it is safer to use mixed logging or row-based.

 ### Mixed Logging

 Mixed logging is the default binary log format.

 When mixed logging is enabled, the server uses a combination of statement-based logging and row-based logging. Statement-based logging is used by default, but when the server determines a statement may not be safe for statement-based logging, it will use row-based logging instead. See [Unsafe Statements for Statement-based Replication: Unsafe Statements](../unsafe-statements-for-statement-based-replication/index#unsafe-statements) for a list of unsafe statements.

 During one transaction, some statements may be logged with row logging while others are logged with statement-based logging.

 This mode can be enabled by setting the [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) system variable to `MIXED`.

 ### Row-Based Logging

 When row-based logging is enabled, DML statements are **not** logged to the [binary log](../binary-log/index). Instead, each insert, update, or delete performed by the statement for each row is logged to the [binary log](../binary-log/index) separately. DDL statements are still logged to the [binary log](../binary-log/index).

 Row-based logging uses more storage than the other log formats but is the safest to use. In practice [mixed logging](index#mixed-logging) should be as safe.

 If one wants to be able to see the original query that was logged, one can enable [annotated rows events](../annotate_rows_event/index), that is shown with [mariadb-binlog](../mariadb-binlog/index), with [--binlog-annotate-row-events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events). This option is on by default.

 This mode can be enabled by setting the [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) system variable to `ROW`.

 Compression of the Binary Log
-----------------------------

 [Compression of the binary log](../compressing-events-to-reduce-size-of-the-binary-log/index) can be used with any of the binary log formats, but the best results come from using mixed or row-based logging. You can enable compression by using the [--log\_bin\_compress](../replication-and-binary-log-server-system-variables/index#log_bin_compress) startup option.

 Configuring the Binary Log Format
---------------------------------

 The format for [binary log](../binary-log/index) events can be configured by setting the [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) system variable. If you have the [SUPER](../grant/index#global-privileges) privilege, then you can change it dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL binlog_format='ROW';

```

You can also change it dynamically for just a specific session with [SET SESSION](../set/index#global-session). For example:

 
```
SET SESSION binlog_format='ROW';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
binlog_format=ROW

```


Be careful when changing the binary log format when using [replication](../replication/index). When you change the binary log format on a server, it only changes the format for that server. Changing the binary log format on a primary has no effect on the replica's binary log format. This can cause replication to give inconsistent results or to fail. 

 

Be careful changing the binary log format dynamically when the server is a replica and [parallel replication](../parallel-replication/index) is enabled. If you change the global value dynamically, then that does not also affect the session values of any currently running threads. This can cause problems with [parallel replication](../parallel-replication/index), because the [worker threads](../replication-threads/index#worker-threads) will remain running even after [STOP SLAVE](../stop-slave/index) is executed. This can be worked around by resetting the [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) system variable. For example:

 
```
STOP SLAVE;
SET GLOBAL slave_parallel_threads=0;
SET GLOBAL binlog_format='ROW';
SET GLOBAL slave_parallel_threads=4;
START SLAVE

```


Effect of the Binary Log Format on Replicas
-------------------------------------------

 In [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) and later, a replica will apply any events it gets from the primary, regardless of the binary log format. The [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) system variable only applies to normal (not replicated) updates.

 
If you are running MySQL or an older MariaDB than 10.0.22, you should be aware of that if you are running the replica in `binlog_format=STATEMENT` mode, the replica will stop if the primary is used with `binlog_format` set to anything else than `STATEMENT`.

 
The binary log format is upwards-compatible. This means replication should always work if the replica is the same or a newer version of MariaDB than the primary.

 The mysql Database
------------------

 Statements that affect the `mysql` database can be logged in a different way to that expected.

 If the mysql database is edited directly, logging is performed as expected according to the [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format). Statements that directly edit the mysql database include [INSERT](../insert/index), [UPDATE](../update/index), [DELETE](../delete/index), [REPLACE](../replace/index), [DO](../do/index), [LOAD DATA INFILE](../load-data-infile/index), [SELECT](../select/index), and [TRUNCATE TABLE](../truncate-table/index).

 If the `mysql` database is edited indirectly, statement logging is used regardless of [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) setting. Statements editing the `mysql` database indirectly include [GRANT](../grant/index), [REVOKE](../revoke/index), [SET PASSWORD](../set-password/index), [RENAME USER](../rename-user/index), [ALTER](../alter/index), [DROP](../drop/index) and [CREATE](../create/index) (except for the situation described below). 

 CREATE TABLE ... SELECT can use a combination of logging formats. The [CREATE TABLE](../create-table/index) portion of the statement is logged using statement-based logging, while the [SELECT](../select/index) portion is logged according to the value of `binlog_format`.

 See Also
--------

 * [Setting up replication](../setting-up-replication/index)
* [Compressing the binary log](../compressing-events-to-reduce-size-of-the-binary-log/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-log-formats/>

REPEATABLE READ
===============

    `REPEATABLE READ` is one of the transaction isolation levels. All consistent reads within the same transaction read the snapshot established by the first read.

 See [SET TRANSACTION#Isolation Levels](../set-transaction/index#isolation-levels) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-repeatable-read/>

Activating the Binary Log
=========================

     To enable binary logging, start the server with the `[--log-bin[=name](../replication-and-binary-log-server-system-variables/index#log_bin)]` option. 

 If you specify a filename with an extension (for example `.log`), the extension will be silently ignored.

 If you don't provide a name (which can, optionally, include an absolute path), the default will be `datadir/log-basename-bin`, `datadir/mysql-bin` or `datadir/mariadb-bin` (the latter two if [--log-basename](../mysqld-options-full-list/index#-log-basename) is not specified, and dependent on server version). Datadir is determined by the value of the [datadir](../server-system-variables/index#datadir) system variable.

 We strongly recommend you use either [--log-basename](../mysqld-options-full-list/index#-log-basename) or specify a filename to ensure that [replication](../replication/index) doesn't stop if the hostname of the computer changes.

 The directory storing the binary logs will contain a binary log index, as well as the individual binary log files.

 The binary log files will have a series of numbers as filename extensions. Each additional binary log will increment the extension number, so the oldest binary logs will have lower numbers, the most recent, higher numbers.

 A new binary log, with a new extension, is created every time the server starts, the logs are flushed, or the maximum size is reached (determined by [max\_binlog\_size](../replication-and-binary-log-system-variables/index#max_binlog_size)).

 The binary log index file contains a master list of all the binary logs, in order.

 A sample listing from a directory containing the binary logs:

 
```
shell> ls -l 
total 100
...
-rw-rw---- 1 mysql adm 2098 Apr 19 00:46 mariadb-bin.000079
-rw-rw---- 1 mysql adm  332 Apr 19 00:56 mariadb-bin.000080
-rw-rw---- 1 mysql adm  347 Apr 19 07:36 mariadb-bin.000081
-rw-rw---- 1 mysql adm  306 Apr 20 07:15 mariadb-bin.000082
-rw-rw---- 1 mysql adm  332 Apr 20 07:41 mariadb-bin.000083
-rw-rw---- 1 mysql adm  373 Apr 21 07:56 mariadb-bin.000084
-rw-rw---- 1 mysql adm  347 Apr 21 09:09 mariadb-bin.000085
-rw-rw---- 1 mysql adm  398 Apr 21 21:24 mariadb-bin.000086
-rw-rw---- 1 mysql adm  816 Apr 21 17:05 mariadb-bin.index

```

The binary log index file will by default have the same name as the individual binary logs, with the extension .index. You can specify an alternative name with the `--log-bin-index[=filename]` [option](../replication-and-binary-log-system-variables/index#log_bin_index).

 Clients with the SUPER privilege can disable and re-enable the binary log for the current session by setting the [sql\_log\_bin](../replication-and-binary-log-server-system-variables/index#sql_log_bin) variable.

 
```
SET sql_log_bin = 0;

SET sql_log_bin = 1;

```

Binary Log Format
-----------------

 There are three formats for the binary log. The default is [mixed logging](../binary-log-formats/index#mixed-logging), which is a mix of [statement-based](../binary-log-formats/index#statement-based-logging) and [row-based logging](../binary-log-formats/index#row-based-logging). See [Binary Log Formats](../binary-log-formats/index) for a full discussion.

 See Also
--------

 * [Setting sql\_log\_bin](../set-sql_log_bin/index)
* [PURGE LOGS](../sql-commands-purge-logs/index) - Delete logs
* [FLUSH LOGS](../flush/index) - Close and rotate logs

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/activating-the-binary-log/>

mysql Command-line Client
=========================

    mysql is a simple SQL shell (with GNU readline capabilities).

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb](../mariadb/index) is a symlink to `mysql`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb](../mariadb/index) is the name of the script, with `mysql` a symlink .

 
See [mariadb](../mariadb-command-line-client/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql-command-line-client/>

READ COMMITTED
==============

    `READ COMMITTED` is one of the transaction isolation levels. Each consistent read, even within the same transaction, sets and reads its own fresh snapshot.

 See [SET TRANSACTION#Isolation Levels](../set-transaction/index#isolation-levels) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-read-committed/>

SERIALIZABLE
============

    `SERIALIZABLE` is one of the transaction isolation levels. Similar to REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... LOCK IN SHARE MODE if autocommit is disabled.

 See [SET TRANSACTION#Isolation Levels](../set-transaction/index#isolation-levels) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-serializable/>

READ UNCOMMITTED
================

    `READ UNCOMMITTED` is one of the transaction isolation levels. SELECT statements are performed in a non-locking fashion, but a possible earlier version of a row might be used

 See [SET TRANSACTION#Isolation Levels](../set-transaction/index#isolation-levels) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transactions-read-uncommitted/>

mysqlcheck
==========

    `mariadb-check` is a tool for checking, repairing, analyzing and optimizing tables.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-check` is a symlink to `mysqlcheck, the old name for the tool`. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-check` is the name of the tool, with `mysqlcheck` a symlink .

 
See [mariadb-check](../mariadb-check/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlcheck/>

CHECK VIEW
==========

    Syntax
------

 
```
CHECK VIEW view_name

```

Description
-----------

 The `CHECK VIEW` statement was introduced in [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) to assist with fixing [MDEV-6916](https://jira.mariadb.org/browse/MDEV-6916), an issue introduced in [MariaDB 5.2](../what-is-mariadb-52/index) where the view algorithms were swapped. It checks whether the view algorithm is correct. It is run as part of [mariadb-upgrade](../mariadb-upgrade/index), and should not normally be required in regular use.

 See Also
--------

 * [REPAIR VIEW](../repair-view/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/check-view/>

SHOW MASTER STATUS
==================

    Syntax
------

 
```
SHOW MASTER STATUS
SHOW BINLOG STATUS -- From MariaDB 10.5.2

```

Description
-----------

 Provides status information about the [binary log](../binary-log/index) files of the primary.

 This statement requires the [SUPER](../grant/index#super) privilege, the [REPLICATION\_CLIENT](../grant/index#replication-client) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [BINLOG MONITOR](../grant/index#binlog-monitor) privilege.

 To see information about the current GTIDs in the binary log, use the [gtid\_binlog\_pos](../global-transaction-id/index#gtid_binlog_pos) variable.

 `SHOW MASTER STATUS` was renamed to `SHOW BINLOG STATUS` in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), but the old name remains an alias for compatibility purposes.

 Example
-------

 
```
SHOW MASTER STATUS;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000016 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
SELECT @@global.gtid_binlog_pos;
+--------------------------+
| @@global.gtid_binlog_pos |
+--------------------------+
| 0-1-2                    |
+--------------------------+

```

See Also
--------

 * [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index)
* [Using and Maintaining the Binary Log](../using-and-maintaining-the-binary-log/index)
* [The gtid\_binlog\_pos variable](../global-transaction-id/index#gtid_binlog_pos)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-master-status/>

SHOW SLAVE STATUS
=================

    Syntax
------

 
```
SHOW SLAVE ["connection_name"] STATUS [FOR CHANNEL "connection_name"]
SHOW REPLICA ["connection_name"] STATUS -- From MariaDB 10.5.1

```

or

 
```
SHOW ALL SLAVES STATUS
SHOW ALL REPLICAS STATUS -- From MariaDB 10.5.1

```
 Description
-----------

 This statement is to be run on a replica and provides status information on essential parameters of the [replica](../replication/index) threads.

 This statement requires the [SUPER](../grant/index#super) privilege, the [REPLICATION\_CLIENT](../grant/index#replication-client) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [REPLICATION SLAVE ADMIN](../grant/index#binlog-monitor) privilege, or, from [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/), the [REPLICA MONITOR](../grant/index#replica-monitor) privilege.

 ### Multi-Source

 The `ALL` and `"connection_name"` options allow you to connect to [many primaries at the same time](../multi-source-replication/index).

 `ALL SLAVES` (or `ALL REPLICAS` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) gives you a list of all connections to the primary nodes.

 The rows will be sorted according to `Connection_name`.

 If you specify a `connection_name`, you only get the information about that connection. If `connection_name` is not used, then the name set by `default_master_connection` is used. If the connection name doesn't exist you will get an error: `There is no master connection for 'xxx'`.

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical to using the channel\_name directly after `SHOW SLAVE`.

 
### Column Descriptions

 The order in which the columns appear depends on the MariaDB version. This means that extracting a column value is best done by comparing the field name instead of using a fixed offset into the row.

 


| Name | Description |
| --- | --- |
| Connection\_name | Name of the primary connection. Returned with `SHOW ALL SLAVES STATUS` (or `SHOW ALL REPLICAS STATUS` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) only. |
| Slave\_SQL\_State | State of SQL thread. Returned with `SHOW ALL SLAVES STATUS` (or `SHOW ALL REPLICAS STATUS` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) only. See [Slave SQL Thread States](../slave-sql-thread-states/index). |
| Slave\_IO\_State | State of I/O thread. See [Slave I/O Thread States](../slave-io-thread-states/index). |
| Master\_host | Master host that the replica is connected to. |
| Master\_user | Account user name being used to connect to the primary. |
| Master\_port | The port being used to connect to the primary. |
| Connect\_Retry | Time in seconds between retries to connect. The default is 60. The [CHANGE MASTER TO](../change-master-to/index) statement can set this. The [master-retry-count](../mysqld-options/index#-master-retry-count) option determines the maximum number of reconnection attempts. |
| Master\_Log\_File | Name of the primary [binary log](../binary-log/index) file that the I/O thread is currently reading from. |
| Read\_Master\_Log\_Pos | Position up to which the I/O thread has read in the current primary [binary log](../binary-log/index) file. |
| Relay\_Log\_File | Name of the relay log file that the SQL thread is currently processing. |
| Relay\_Log\_Pos | Position up to which the SQL thread has finished processing in the current relay log file. |
| Relay\_Master\_Log\_File | Name of the primary [binary log](../binary-log/index) file that contains the most recent event executed by the SQL thread. |
| Slave\_IO\_Running | Whether the replica I/O thread is running and connected (`Yes`), running but not connected to a primary (`Connecting`) or not running (`No`). |
| Slave\_SQL\_Running | Whether or not the SQL thread is running. |
| Replicate\_Rewrite\_DB | Databases specified for replicating and rewriting with the `[replicate\_rewrite\_db](../replication-and-binary-log-server-system-variables/index#replicate_rewrite_db)` option. Added in [MariaDB 10.11](../what-is-mariadb-1011/index) |
| Replicate\_Do\_DB | Databases specified for replicating with the `[replicate\_do\_db](../replication-and-binary-log-server-system-variables/index#replicate_do_db)` option. |
| Replicate\_Ignore\_DB | Databases specified for ignoring with the `[replicate\_ignore\_db](../replication-and-binary-log-server-system-variables/index#replicate_ignore_db)` option. |
| Replicate\_Do\_Table | Tables specified for replicating with the `[replicate\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_do_table)` option. |
| Replicate\_Ignore\_Table | Tables specified for ignoring with the `[replicate\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_ignore_table)` option. |
| Replicate\_Wild\_Do\_Table | Tables specified for replicating with the `[replicate\_wild\_do\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_do_table)` option. |
| Replicate\_Wild\_Ignore\_Table | Tables specified for ignoring with the `[replicate\_wild\_ignore\_table](../replication-and-binary-log-server-system-variables/index#replicate_wild_ignore_table)` option. |
| Last\_Errno | Alias for `Last_SQL_Errno` (see below) |
| Last Error | Alias for `Last_SQL_Error` (see below) |
| Skip\_Counter | Number of events that a replica skips from the master, as recorded in the [sql\_slave\_skip\_counter](../replication-and-binary-log-server-system-variables/index#sql_slave_skip_counter) system variable. |
| Exec\_Master\_Log\_Pos | Position up to which the SQL thread has processed in the current master [binary log](../binary-log/index) file. Can be used to start a new replica from a current replica with the [CHANGE MASTER TO ... MASTER\_LOG\_POS](../change-master-to/index) option. |
| Relay\_Log\_Space | Total size of all relay log files combined. |
| Until\_Condition |  |
| Until\_Log\_File | The `MASTER_LOG_FILE` value of the [START SLAVE UNTIL](../start-slave/index) condition. |
| Until\_Log\_Pos | The `MASTER_LOG_POS` value of the [START SLAVE UNTIL](../start-slave/index) condition. |
| Master\_SSL\_Allowed | Whether an SSL connection is permitted (`Yes`), not permitted (`No`) or permitted but without the replica having SSL support enabled (`Ignored`) |
| Master\_SSL\_CA\_File | The `MASTER_SSL_CA` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Master\_SSL\_CA\_Path | The `MASTER_SSL_CAPATH` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Master\_SSL\_Cert | The `MASTER_SSL_CERT` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Master\_SSL\_Cipher | The `MASTER_SSL_CIPHER` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Master\_SSL\_Key | The `MASTER_SSL_KEY` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Seconds\_Behind\_Master | Difference between the timestamp logged on the master for the event that the replica is currently processing, and the current timestamp on the replica. Zero if the replica is not currently processing an event. With serial replication, `seconds_behind_master` is updated when the SQL thread begins executing a transaction. With [parallel replication](../parallel-replication/index), `seconds_behind_master` is updated only after transactions commit. Starting in [MariaDB 10.3.38](https://mariadb.com/kb/en/mariadb-10338-release-notes/), [10.4.28](https://mariadb.com/kb/en/mariadb-10-4-28-release-notes/), [10.5.19](https://mariadb.com/kb/en/mariadb-10-5-19-release-notes/), [10.6.12](https://mariadb.com/kb/en/mariadb-10-6-12-release-notes/), [10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [10.10.3](https://mariadb.com/kb/en/mariadb-10-10-3-release-notes/), and [10.11.2](https://mariadb.com/kb/en/mariadb-10-11-2-release-notes/), an exception is drawn on the parallel replica to additionally update `seconds_behind_master` when the first transaction received after idling is queued to a worker for execution, to provide a reliable initial value for the duration until a transaction commits. Additional behaviors to be aware of are as follows: 1) `Seconds_Behind_Master` will update for ignored events, e.g. those skipped due to [sql\_slave\_skip\_counter](../set-global-sql_slave_skip_counter/index). 2) On the serial replica, transactions with prior timestamps can update `Seconds_Behind_Master` such that it can go backwards, though this is not true for the parallel replica. 3) When configured with [MASTER\_DELAY](../delayed-replication/index), as a replicated transaction begins executing (i.e. on a serial or post-idle parallel replica), `Seconds_Behind_Master` will update before delaying, and while delaying occurs will grow to encompass the configured value. 4) There is a known issue, tracked by [MDEV-17516](https://jira.mariadb.org/browse/MDEV-17516), such that `Seconds_Behind_Master` will initially present as `0` on replica restart until a replicated transaction begins executing, even if the last replica session was lagging behind when stopped. |
| Master\_SSL\_Verify\_Server\_Cert | The `MASTER_SSL_VERIFY_SERVER_CERT` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Last\_IO\_Errno | [Error code](../mariadb-error-codes/index) of the most recent error that caused the I/O thread to stop (also recorded in the replica's error log). `0` means no error. [RESET SLAVE](../reset-slave/index) or [RESET MASTER](../reset-master/index) will reset this value. |
| Last\_IO\_Error | [Error message](../mariadb-error-codes/index) of the most recent error that caused the I/O thread to stop (also recorded in the replica's error log). An empty string means no error. [RESET SLAVE](../reset-slave/index) or [RESET MASTER](../reset-master/index) will reset this value. |
| Last\_SQL\_Errno | [Error code](../mariadb-error-codes/index) of the most recent error that caused the SQL thread to stop (also recorded in the replica's error log). `0` means no error. [RESET SLAVE](../reset-slave/index) or [RESET MASTER](../reset-master/index) will reset this value. |
| Last\_SQL\_Error | [Error message](../mariadb-error-codes/index) of the most recent error that caused the SQL thread to stop (also recorded in the replica's error log). An empty string means no error. [RESET SLAVE](../reset-slave/index) or [RESET MASTER](../reset-master/index) will reset this value. |
| Replicate\_Ignore\_Server\_Ids | List of [server\_ids](../replication-and-binary-log-server-system-variables/index#server_id) that are currently being ignored for replication purposes, or an empty string for none, as specified in the `IGNORE_SERVER_IDS` option of the `[CHANGE MASTER TO](../change-master-to/index#ignore_server_ids)` statement. |
| Master\_Server\_Id | The master's [server\_id](../replication-and-binary-log-server-system-variables/index#server_id) value. |
| Master\_SSL\_Crl | The `MASTER_SSL_CRL` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Master\_SSL\_Crlpath | The `MASTER_SSL_CRLPATH` option of the `[CHANGE MASTER TO](../change-master-to/index)` statement. |
| Using\_Gtid | Whether or not [global transaction ID's](../global-transaction-id/index) are being used for replication (can be `No`, `Slave_Pos`, or `Current_Pos`). |
| Gtid\_IO\_Pos | Current [global transaction ID](../global-transaction-id/index) value. |
| Retried\_transactions | Number of retried transactions for this connection. Returned with `SHOW ALL SLAVES STATUS` only. |
| Max\_relay\_log\_size | Max [relay log](../relay-log/index) size for this connection. Returned with `SHOW ALL SLAVES STATUS` only. |
| Executed\_log\_entries | How many log entries the replica has executed. Returned with `SHOW ALL SLAVES STATUS` only. |
| Slave\_received\_heartbeats | How many heartbeats we have got from the master. Returned with `SHOW ALL SLAVES STATUS` only. |
| Slave\_heartbeat\_period | How often to request a heartbeat packet from the master (in seconds). Returned with `SHOW ALL SLAVES STATUS` only. |
| Gtid\_Slave\_Pos | GTID of the last event group replicated on a replica server, for each replication domain, as stored in the [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) system variable. Returned with `SHOW ALL SLAVES STATUS` only. |
| SQL\_Delay | Value specified by `MASTER_DELAY` in `[CHANGE MASTER](../change-master-to/index)` (or 0 if none). |
| SQL\_Remaining\_Delay | When the replica is delaying the execution of an event due to `MASTER_DELAY`, this is the number of seconds of delay remaining before the event will be applied. Otherwise, the value is `NULL`. |
| Slave\_SQL\_Running\_State | The state of the SQL driver threads, same as in [SHOW PROCESSLIST](../show-processlist/index). When the replica is delaying the execution of an event due to `MASTER_DELAY`, this field displays: "`Waiting until MASTER_DELAY seconds after master executed event`". |
| Slave\_DDL\_Groups | This status variable counts the occurrence of DDL statements. This is a replica-side counter for optimistic parallel replication. |
| Slave\_Non\_Transactional\_Groups | This status variable counts the occurrence of non-transactional event groups. This is a replica-side counter for optimistic parallel replication. |
| Slave\_Transactional\_Groups | This status variable counts the occurrence of transactional event groups. This is a replica-side counter for optimistic parallel replication. |

 
### SHOW REPLICA STATUS

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`SHOW REPLICA STATUS` is an alias for `SHOW SLAVE STATUS` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

 
Examples
--------

 If you issue this statement using the [mariadb](../mariadb-client/index) client, you can use a ``\G`` statement terminator rather than a semicolon to obtain a more readable vertical layout.

 
```
SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: db01.example.com
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000010
          Read_Master_Log_Pos: 548
               Relay_Log_File: relay-bin.000004
                Relay_Log_Pos: 837
        Relay_Master_Log_File: mariadb-bin.000010
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 548
              Relay_Log_Space: 1497
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 101
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
                   Using_Gtid: No
                  Gtid_IO_Pos: 

```


```
SHOW ALL SLAVES STATUS\G
*************************** 1. row ***************************
              Connection_name: 
              Slave_SQL_State: Slave has read all relay log; waiting for the slave I/O thread to update it
               Slave_IO_State: Waiting for master to send event
                  Master_Host: db01.example.com
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000010
          Read_Master_Log_Pos: 3608
               Relay_Log_File: relay-bin.000004
                Relay_Log_Pos: 3897
        Relay_Master_Log_File: mariadb-bin.000010
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 3608
              Relay_Log_Space: 4557
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 101
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
                   Using_Gtid: No
                  Gtid_IO_Pos:
         Retried_transactions: 0
           Max_relay_log_size: 104857600
         Executed_log_entries: 40
    Slave_received_heartbeats: 11
       Slave_heartbeat_period: 1800.000
               Gtid_Slave_Pos: 0-101-2320

```

You can also access some of the variables directly from status variables:

 
```
SET @@default_master_connection="test" ;
show status like "%slave%"

Variable_name   Value
Com_show_slave_hosts    0
Com_show_slave_status   0
Com_start_all_slaves    0
Com_start_slave 0
Com_stop_all_slaves     0
Com_stop_slave  0
Rpl_semi_sync_slave_status      OFF
Slave_connections       0
Slave_heartbeat_period  1800.000
Slave_open_temp_tables  0
Slave_received_heartbeats       0
Slave_retried_transactions      0
Slave_running   OFF
Slaves_connected        0
Slaves_running  1

```

See Also
--------

 * [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-slave-status/>

RESET REPLICA/SLAVE
===================

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Syntax
------

 
```
RESET REPLICA ["connection_name"] [ALL]  [FOR CHANNEL "connection_name"] -- from MariaDB 10.5.1         
RESET SLAVE ["connection_name"] [ALL]  [FOR CHANNEL "connection_name"]              

```
 Description
-----------

 RESET REPLICA/SLAVE makes the replica forget its [replication](../replication/index) position in the master's [binary log](../binary-log/index). This statement is meant to be used for a clean start. It deletes the master.info and relay-log.info files, all the [relay log](../relay-log/index) files, and starts a new relay log file. To use RESET REPLICA/SLAVE, the replica threads must be stopped (use [STOP REPLICA/SLAVE](../stop-replica/index) if necessary).

 
Note: All relay log files are deleted, even if they have not been completely executed by the slave SQL thread. (This is a condition likely to exist on a replication slave if you have issued a STOP REPLICA/SLAVE statement or if the slave is highly loaded.)

 

Note: `RESET REPLICA` does not reset the global `gtid_slave_pos` variable. This means that a replica server configured with `CHANGE MASTER TO MASTER_USE_GTID=slave_pos` will not receive events with GTIDs occurring before the state saved in `gtid_slave_pos`. If the intent is to reprocess these events, `gtid_slave_pos` must be manually reset, e.g. by executing `set global gtid_slave_pos=""`.

 
Connection information stored in the master.info file is immediately reset using any values specified in the corresponding startup options. This information includes values such as master host, master port, master user, and master password. If the replica SQL thread was in the middle of replicating temporary tables when it was stopped, and RESET REPLICA/SLAVE is issued, these replicated temporary tables are deleted on the slave.

 The `ALL` also resets the `PORT`, `HOST`, `USER` and `PASSWORD` parameters for the slave. If you are using a connection name, it will permanently delete it and it will not show up anymore in [SHOW ALL REPLICAS/SLAVE STATUS](../show-replica-status/index).

 #### connection\_name

 The `connection_name` option is used for [multi-source replication](../multi-source-replication/index).

 If there is only one nameless primary, or the default primary (as specified by the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable) is intended, `connection_name` can be omitted. If provided, the `RESET REPLICA/SLAVE` statement will apply to the specified primary. `connection_name` is case-insensitive.

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical as using the channel\_name directly after `RESET REPLICA`.

 
#### RESET REPLICA

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`RESET REPLICA` is an alias for `RESET SLAVE` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

 
See Also
--------

 * [STOP REPLICA/SLAVE](../stop-replica/index) stops the replica, but it can be restarted with [START REPLICA/SLAVE](../start-replica/index) or after next MariaDB server restart.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/reset-slave/>

STOP SLAVE
==========

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Syntax
------

 
```
STOP SLAVE ["connection_name"] [thread_type [, thread_type] ... ] [FOR CHANNEL "connection_name"]

STOP ALL SLAVES [thread_type [, thread_type]]

STOP REPLICA ["connection_name"] [thread_type [, thread_type] ... ] -- from 10.5.1

STOP ALL REPLICAS [thread_type [, thread_type]] -- from 10.5.1

thread_type: IO_THREAD | SQL_THREAD

```
 Description
-----------

 Stops the replica threads. `STOP SLAVE` requires the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [REPLICATION SLAVE ADMIN](../grant/index#replication-slave-admin) privilege.

 Like [START SLAVE](../start-slave/index), this statement may be used with the `IO_THREAD` and `SQL_THREAD` options to name the thread or threads to be stopped. In almost all cases, one never need to use the `thread_type` options.

 `STOP SLAVE` waits until any current replication event group affecting one or more non-transactional tables has finished executing (if there is any such replication group), or until the user issues a [KILL QUERY](../kill-connection-query/index) or [KILL CONNECTION](../kill-connection-query/index) statement.

 Note that `STOP SLAVE` doesn't delete the connection permanently. Next time you execute [START SLAVE](../start-slave/index) or the MariaDB server restarts, the replica connection is restored with it's [original arguments](../change-master-to/index). If you want to delete a connection, you should execute [RESET SLAVE](../reset-slave/index).

 #### STOP ALL SLAVES

 `STOP ALL SLAVES` stops all your running replicas. It will give you a `note` for every stopped connection. You can check the notes with [SHOW WARNINGS](../show-warnings/index).

 #### connection\_name

 The `connection_name` option is used for [multi-source replication](../multi-source-replication/index).

 If there is only one nameless master, or the default master (as specified by the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable) is intended, `connection_name` can be omitted. If provided, the `STOP SLAVE` statement will apply to the specified master. `connection_name` is case-insensitive.

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical as using the channel\_name directly after `STOP SLAVE`.

 
#### STOP REPLICA

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`STOP REPLICA` is an alias for `STOP SLAVE` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

 
See Also
--------

 * [CHANGE MASTER TO](../change-master-to/index) is used to create and change connections.
* [START SLAVE](../start-slave/index) is used to start a predefined connection.
* [RESET SLAVE](../reset-slave/index) is used to reset parameters for a connection and also to permanently delete a master connection.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stop-slave/>

REPAIR VIEW
===========

    Syntax
------

 
```
REPAIR [NO_WRITE_TO_BINLOG | LOCAL] VIEW  view_name[, view_name] ... [FROM MYSQL]

```
 Description
-----------

 The `REPAIR VIEW` statement was introduced to assist with fixing [MDEV-6916](https://jira.mariadb.org/browse/MDEV-6916), an issue introduced in [MariaDB 5.2](../what-is-mariadb-52/index) where the view algorithms were swapped compared to their MySQL on disk representation. It checks whether the view algorithm is correct. It is run as part of [mariadb-upgrade](../mariadb-upgrade/index), and should not normally be required in regular use.

 By default it corrects the checksum and if necessary adds the mariadb-version field. If the optional `FROM MYSQL` clause is used, and no mariadb-version field is present, the MERGE and TEMPTABLE algorithms are toggled.

 By default, `REPAIR VIEW` statements are written to the [binary log](../binary-log/index) and will be [replicated](../replication/index). The `NO_WRITE_TO_BINLOG` keyword (`LOCAL` is an alias) will ensure the statement is not written to the binary log.

 See Also
--------

 * [CHECK VIEW](../check-view/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/repair-view/>

Obsolete Table Commands
========================

   Table commands that have been removed from MariaDB

  

| Title | Description |
| --- | --- |
|  [BACKUP TABLE (removed)](../backup-table-removed/index) |  For backing up tables. Removed.  |
|  [RESTORE TABLE (removed)](../restore-table-removed/index) |  Restores a table from a backup. Removed.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/obsolete-table-commands/>

RESET MASTER
============

    
```
RESET MASTER [TO #]

```

Deletes all [binary log](../binary-log/index) files listed in the index file, resets the binary log index file to be empty, and creates a new binary log file with a suffix of .000001.

 If `TO #` is given, then the first new binary log file will start from number #.

 
This statement is for use only when the master is started for the first time, and should never be used if any slaves are actively [replicating](../replication/index) from the binary log.

 
See Also
--------

 * The [PURGE BINARY LOGS](../sql-commands-purge-logs/index) statement is intended for use in active replication.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/reset-master/>

SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER
====================================

    Syntax
------

 
```
SET GLOBAL sql_slave_skip_counter = N

```
 Description
-----------

 This statement skips the next `*N*` events from the primary. This is useful for recovering from [replication](../replication/index) stops caused by a statement.

 If multi-source replication is used, this statement applies to the default connection. It could be necessary to change the value of the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable.

 Note that, if the event is a [transaction](../transactions/index), the whole transaction will be skipped. With non-transactional engines, an event is always a single statement.

 This statement is valid only when the replica threads are not running. Otherwise, it produces an error.

 The statement does not automatically restart the replica threads.

 Example
-------

 
```
SHOW SLAVE STATUS \G
...
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;

```

Multi-source replication:

 
```
SET @@default_master_connection = 'master_01';
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

```

Multiple Replication Domains
----------------------------

 `sql_slave_skip_counter` can't be used to skip transactions on a replica if [GTID replication](../gtid/index) is in use and if [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) contains multiple [gtid\_domain\_id](../gtid/index#gtid_domain_id) values. In that case, you'll get an error like the following:

 
```
ERROR 1966 (HY000): When using parallel replication and GTID with multiple 
 replication domains, @@sql_slave_skip_counter can not be used. Instead, 
 setting @@gtid_slave_pos explicitly can be  used to skip to after a given GTID 
 position.

```

In order to skip transactions in cases like this, you will have to manually change [gtid\_slave\_pos](../gtid/index#gtid_slave_pos).

 See Also
--------

 * [Selectively Skipping Replication of Binlog Events](../selectively-skipping-replication-of-binlog-events/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-global-sql_slave_skip_counter/>

SHOW SLAVE HOSTS
================

    Syntax
------

 
```
SHOW SLAVE HOSTS
SHOW REPLICA HOSTS -- from MariaDB 10.5.1

```

Description
-----------

 This command is run on the primary and displays a list of replicas that are currently registered with it. Only replicas started with the `--report-host=host_name` option are visible in this list.

 The output looks like this:

 
```
SHOW SLAVE HOSTS;
+------------+-----------+------+-----------+
| Server_id  | Host      | Port | Master_id |
+------------+-----------+------+-----------+
|  192168010 | iconnect2 | 3306 | 192168011 |
| 1921680101 | athena    | 3306 | 192168011 |
+------------+-----------+------+-----------+

```

* **`Server_id`**: The unique server ID of the replica server, as configured in the server's option file, or on the command line with [--server-id=value](../replication-and-binary-log-server-system-variables/index#server_id).
* **`Host`**: The host name of the replica server, as configured in the server's option file, or on the command line with `--report-host=host_name`. Note that this can differ from the machine name as configured in the operating system.
* **`Port`**: The port the replica server is listening on.
* **`Master_id`**: The unique server ID of the primary server that the replica server is replicating from.

 Some MariaDB and MySQL versions report another variable, [rpl\_recovery\_rank](../server-system-variables/index#rpl_recovery_rank). This variable was never used, and was eventually removed in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) .

 Requires the [REPLICATION MASTER ADMIN](../grant/index#replication-master-admin) privilege (>= [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) or the [REPLICATION SLAVE](../grant/index#replication-slave) privilege (<= [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)).

 #### SHOW REPLICA HOSTS

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`SHOW REPLICA HOSTS` is an alias for `SHOW SLAVE HOSTS` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

 
See Also
--------

 * [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index)
* [Replication threads](../replication-threads/index)
* [SHOW PROCESSLIST](../show-processlist/index). In `[SHOW PROCESSLIST](../show-processlist/index)` output, replica threads are identified by `Binlog Dump`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-replica-hosts/>

Full Backup and Restore with Mariabackup
========================================

     When using Mariabackup, you have the option of performing a full or an incremental backup. Full backups create a complete backup of the database server in an empty directory while incremental backups update a previous backup with whatever changes to the data have occurred since the backup. This page documents how to perform full backups.

 Backing up the Database Server
------------------------------

 In order to back up the database, you need to run Mariabackup with the `[--backup](../mariabackup-options/index#-backup)` option to tell it to perform a backup and with the `[--target-dir](../mariabackup-options/index#-target-dir)` option to tell it where to place the backup files. When taking a full backup, the target directory must be empty or it must not exist.

 To take a backup, run the following command:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

The time the backup takes depends on the size of the databases or tables you're backing up. You can cancel the backup if you need to, as the backup process does not modify the database.

 Mariabackup writes the backup files the target directory. If the target directory doesn't exist, then it creates it. If the target directory exists and contains files, then it raises an error and aborts.

 Here is an example backup directory:

 
```
$ ls /var/mariadb/backup/

aria_log.0000001  mysql                   xtrabackup_checkpoints
aria_log_control  performance_schema      xtrabackup_info
backup-my.cnf     test                    xtrabackup_logfile
ibdata1           xtrabackup_binlog_info

```

Preparing the Backup for Restoration
------------------------------------

 The data files that Mariabackup creates in the target directory are not point-in-time consistent, given that the data files are copied at different times during the backup operation. If you try to restore from these files, InnoDB notices the inconsistencies and crashes to protect you from corruption

 Before you can restore from a backup, you first need to **prepare** it to make the data files consistent. You can do so with the `[--prepare](../mariabackup-options/index#-prepare)` option. 

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup/

```

Restoring the Backup
--------------------

 Once the backup is complete and you have prepared the backup for restoration (previous step), you can restore the backup using either the `[--copy-back](../mariabackup-options/index#-copy-back)` or the `[--move-back](../mariabackup-options/index#-move-back)` options. The `[--copy-back](../mariabackup-options/index#-copy-back)` option allows you to keep the original backup files. The `[--move-back](../mariabackup-options/index#-move-back)` option actually moves the backup files to the `[datadir](../server-system-variables/index#datadir)`, so the original backup files are lost.

 * First, [stop the MariaDB Server process](../starting-and-stopping-mariadb/index).

 * Then, ensure that the `[datadir](../server-system-variables/index#datadir)` is empty.

 * Then, run Mariabackup with one of the options mentioned above:

 
```
$ mariabackup --copy-back \
   --target-dir=/var/mariadb/backup/

```

* Then, you may need to fix the file permissions.

 When Mariabackup restores a database, it preserves the file and directory privileges of the backup. However, it writes the files to disk as the user and group restoring the database. As such, after restoring a backup, you may need to adjust the owner of the data directory to match the user and group for the MariaDB Server, typically `mysql` for both. For example, to recursively change ownership of the files to the `mysql` user and group, you could execute:

 
```
$ chown -R mysql:mysql /var/lib/mysql/

```

* Finally, [start the MariaDB Server process](../starting-and-stopping-mariadb/index).

 ### Restoring with Other Tools

 Once a full backup is prepared, it is a fully functional MariaDB data directory. Therefore, as long as the MariaDB Server process is stopped on the target server, you can technically restore the backup using any file copying tool, such as `cp` or `rysnc`. For example, you could also execute the following to restore the backup:

 
```
$ rsync -avrP /var/mariadb/backup /var/lib/mysql/
$ chown -R mysql:mysql /var/lib/mysql/
$ rm /var/lib/mysql/ib_logfile*

```

When using Mariabackup from versions prior to [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/), you would also have to remove any pre-existing [InnoDB redo log](../xtradbinnodb-redo-log/index) files. For example:

 
```
$ rm /var/lib/mysql/ib_logfile*

```

See [Mariabackup Internal Details: Redo Log Files](../mariabackup-overview/index#redo-log-files) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/full-backup-and-restore-with-mariabackup/>

Configuring MariaDB Replication between MariaDB Galera Cluster and MariaDB Server
=================================================================================

    [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index) can be used to replicate between [MariaDB Galera Cluster](../galera-cluster/index) and MariaDB Server. This article will discuss how to do that.

 Configuring the Cluster
-----------------------

 Before we set up replication, we need to ensure that the cluster is configured properly. This involves the following steps:

 * Set `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` on all nodes in the cluster. See [Configuring MariaDB Galera Cluster: Writing Replicated Write Sets to the Binary Log](../configuring-mariadb-galera-cluster/index#writing-replicated-write-sets-to-the-binary-log) and [Using MariaDB Replication with MariaDB Galera Cluster: Configuring a Cluster Node as a Replication Master](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#configuring-a-cluster-node-as-a-replication-master) for more information on why this is important. This is also needed to [enable wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#enabling-wsrep-gtid-mode).

 * Set `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` to the same value on all nodes in the cluster. See [Using MariaDB Replication with MariaDB Galera Cluster: Setting server\_id on Cluster Nodes](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#setting-server_id-on-cluster-nodes) for more information on what this means.

 ### Configuring Wsrep GTID Mode

 If you want to use [GTID](../gtid/index) replication, then you also need to configure some things to [enable wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#enabling-wsrep-gtid-mode). For example:

 * `[wsrep\_gtid\_mode=ON](../galera-cluster-system-variables/index#wsrep_gtid_mode)` needs to be set on all nodes in the cluster.

 * `[wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)` needs to be set to the same value on all nodes in the cluster, so that each cluster node uses the same domain when assigning [GTIDs](../gtid/index) for Galera Cluster's write sets.

 * `[log\_slave\_updates](../replication-and-binary-log-system-variables/index#log_slave_updates)` needs to be enabled on all nodes in the cluster. See [MDEV-9855](https://jira.mariadb.org/browse/MDEV-9855) about that.

 * `[log\_bin](../replication-and-binary-log-server-system-variables/index#log_bin)` needs to be set to the same path on all nodes in the cluster. See [MDEV-9856](https://jira.mariadb.org/browse/MDEV-9856) about that.

 And as an extra safety measure:

 * [gtid\_domain\_id](../gtid/index#gtid_domain_id) should be set to a different value on all nodes in a given cluster, and each of these values should be different than the configured [wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id) value. This is to prevent a node from using the same domain used for Galera Cluster's write sets when assigning [GTIDs](../gtid/index) for non-Galera transactions, such as DDL executed with [wsrep\_sst\_method=RSU](../galera-cluster-system-variables/index#wsrep_sst_method) set or DML executed with [wsrep\_on=OFF](../galera-cluster-system-variables/index#wsrep_on) set.

 Configuring the Replica
-----------------------

 Before we set up replication, we also need to ensure that the MariaDB Server replica is configured properly. This involves the following steps:

 * Set [server\_id](../replication-and-binary-log-system-variables/index#server_id) to a different value than the one that the cluster nodes are using.

 * Set [gtid\_domain\_id](../gtid/index#gtid_domain_id) to a value that is different than the [wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id) and [gtid\_domain\_id](../gtid/index#gtid_domain_id) values that the cluster nodes are using.

 * Set [log\_bin](../replication-and-binary-log-server-system-variables/index#log_bin) and [log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates) if you want the replica to log the transactions that it replicates.

 Setting up Replication
----------------------

 Our process to set up replication is going to be similar to the process described at [Setting up a Replication Slave with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index), but it will be modified a bit to work in this context.

 ### Start the Cluster

 The very first step is to start the nodes in the first cluster. The first node will have to be [bootstrapped](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster). The other nodes can be [started normally](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Once the nodes are started, you need to pick a specific node that will act as the replication primary for the MariaDB Server.

 ### Backup the Database on the Cluster's Primary Node and Prepare It

 The first step is to simply take and prepare a fresh [full backup](../full-backup-and-restore-with-mariabackup/index) of the node that you have chosen to be the replication primary. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

And then you would prepare the backup as you normally would. For example:

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup/ 

```

### Copy the Backup to the Replica

 Once the backup is done and prepared, you can copy it to the MariaDB Server that will be acting as replica. For example:

 
```
$ rsync -avrP /var/mariadb/backup dc2-dbserver1:/var/mariadb/backup

```

### Restore the Backup on the Second Cluster's Replica

 At this point, you can restore the backup to the [datadir](../server-system-variables/index#datadir), as you normally would. For example:

 
```
$ mariabackup --copy-back \
   --target-dir=/var/mariadb/backup/ 

```

And adjusting file permissions, if necessary:

 
```
$ chown -R mysql:mysql /var/lib/mysql/

```

### Start the New Replica

 Now that the backup has been restored to the MariaDB Server replica, you can [start the MariaDB Server process](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 ### Create a Replication User on the Cluster's Primary

 Before the MariaDB Server replica can begin replicating from the cluster's primary, you need to [create a user account](../create-user/index) on the primary that the replica can use to connect, and you need to [grant](../grant/index) the user account the [REPLICATION SLAVE](../grant/index#global-privileges) privilege. For example:

 
```
CREATE USER 'repl'@'dc2-dbserver1' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'dc2-dbserver1';

```

### Start Replication on the New Replica

 At this point, you need to get the replication coordinates of the primary from the original backup.

 The coordinates will be in the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file.

 Mariabackup dumps replication coordinates in two forms: [GTID strings](../gtid/index) and [binary log](../binary-log/index) file and position coordinates, like the ones you would normally see from [SHOW MASTER STATUS](../show-master-status/index) output. In this case, it is probably better to use the [GTID](../gtid/index) coordinates.

 For example:

 
```
mariadb-bin.000096 568 0-1-2

```

Regardless of the coordinates you use, you will have to set up the primary connection using [CHANGE MASTER TO](../change-master-to/index) and then start the replication threads with [START SLAVE](../start-slave/index).

 #### GTIDs

 If you want to use GTIDs, then you will have to first set [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) to the [GTID](../gtid/index) coordinates that we pulled from the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file, and we would set `MASTER_USE_GTID=slave_pos` in the [CHANGE MASTER TO](../change-master-to/index) command. For example:

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO 
   MASTER_HOST="c1dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

#### File and Position

 If you want to use the [binary log](../binary-log/index) file and position coordinates, then you would set `MASTER_LOG_FILE` and `MASTER_LOG_POS` in the [CHANGE MASTER TO](../change-master-to/index) command to the file and position coordinates that we pulled the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file. For example:

 
```
CHANGE MASTER TO 
   MASTER_HOST="c1dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_LOG_FILE='mariadb-bin.000096',
   MASTER_LOG_POS=568,
START SLAVE;

```

### Check the Status of the New Replica

 You should be done setting up the replica now, so you should check its status with [SHOW SLAVE STATUS](../show-slave-status/index). For example:

 
```
SHOW SLAVE STATUS\G

```

Now that the MariaDB Server is up, ensure that it does not start accepting writes yet if you want to set up [circular replication](../replication-overview/index#ring-replication) between the cluster and the MariaDB Server.

 Setting up Circular Replication
-------------------------------

 You can also set up [circular replication](../replication-overview/index#ring-replication) between the cluster and MariaDB Server, which means that the MariaDB Server replicates from the cluster, and the cluster also replicates from the MariaDB Server.

 ### Create a Replication User on the MariaDB Server Primary

 Before circular replication can begin, you also need to [create a user account](../create-user/index) on the MariaDB Server, since it will be acting as replication primary to the cluster's replica, and you need to [grant](../grant/index) the user account the [REPLICATION SLAVE](../grant/index#global-privileges) privilege. For example:

 
```
CREATE USER 'repl'@'c1dbserver1' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'c1dbserver1';

```

### Start Circular Replication on the Cluster

 How this is done would depend on whether you want to use the [GTID](../gtid/index) coordinates or the [binary log](../binary-log/index) file and position coordinates.

 Regardless, you need to ensure that the second cluster is not accepting any writes other than those that it replicates from the cluster at this stage.

 #### GTIDs

 To get the GTID coordinates on the MariaDB Server you can check `[gtid\_current\_pos](../gtid/index#gtid_current_pos)` by executing:

 
```
SHOW GLOBAL VARIABLES LIKE 'gtid_current_pos';

```

Then on the node acting as replica in the cluster, you can set up replication by setting [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) to the GTID that was returned and then executing [CHANGE MASTER TO](../change-master-to/index):

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO 
   MASTER_HOST="c2dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

#### File and Position

 To get the [binary log](../binary-log/index) file and position coordinates on the MariaDB Server, you can execute [SHOW MASTER STATUS](../show-master-status/index):

 
```
SHOW MASTER STATUS

```

Then on the node acting as replica in the cluster, you would set `master_log_file` and `master_log_pos` in the [CHANGE MASTER TO](../change-master-to/index) command. For example:

 
```
CHANGE MASTER TO 
   MASTER_HOST="c2dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_LOG_FILE='mariadb-bin.000096',
   MASTER_LOG_POS=568;
START SLAVE;

```

### Check the Status of the Circular Replication

 You should be done setting up the circular replication on the node in the first cluster now, so you should check its status with [SHOW SLAVE STATUS](../show-slave-status/index). For example:

 
```
SHOW SLAVE STATUS\G

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-replication-with-mariadb-galera-cluster-configuring-mariadb-r/>

Mariabackup Options
===================

    There are a number of options available in `Mariabackup`.

 List of Options
---------------

 ### `--apply-log`

 Prepares an existing backup to restore to the MariaDB Server. This is only valid in `innobackupex` mode, which can be enabled with the `[--innobackupex](#-innobackupex)` option.

 Files that Mariabackup generates during `[--backup](#-backup)` operations in the target directory are not ready for use on the Server. Before you can restore the data to MariaDB, you first need to prepare the backup.

 In the case of full backups, the files are not point in time consistent, since they were taken at different times. If you try to restore the database without first preparing the data, InnoDB rejects the new data as corrupt. Running Mariabackup with the `--prepare` command readies the data so you can restore it to MariaDB Server. When working with incremental backups, you need to use the `--prepare` command and the `[--incremental-dir](#-incremental-dir)` option to update the base backup with the deltas from an incremental backup.

 
```
$ mariabackup --innobackupex --apply-log

```

Once the backup is ready, you can use the `[--copy-back](#-copy-back)` or the `[--move-back](#-move-back)` commands to restore the backup to the server.

 ### `--apply-log-only`

 If this option is used when preparing a backup, then only the redo log apply stage will be performed, and other stages of crash recovery will be ignored. This option is used with [incremental backups](../incremental-backup-and-restore-with-mariabackup/index).

 This option is only supported in [MariaDB 10.1](../what-is-mariadb-101/index). In [MariaDB 10.2](../what-is-mariadb-102/index) and later, this option is not needed or supported. 

 ### `--backup`

 Backs up your databases.

 Using this command option, Mariabackup performs a backup operation on your database or databases. The backups are written to the target directory, as set by the `[--target-dir](#-target-dir)` option.

 
```
$ mariabackup --backup 
      --target-dir /path/to/backup \
      --user user_name --password user_passwd

```

Mariabackup can perform full and incremental backups. A full backup creates a snapshot of the database in the target directory. An incremental backup checks the database against a previously taken full backup, (defined by the `[--incremental-basedir](#-incremental-basedir)` option) and creates delta files for these changes. 

 In order to restore from a backup, you first need to run Mariabackup with the `[--prepare](#-prepare)` command option, to make a full backup point-in-time consistent or to apply incremental backup deltas to base. Then you can run Mariabackup again with either the `[--copy-back](#-copy-back)` or `[--move-back](#-move-back)` commands to restore the database.

 For more information, see [Full Backup and Restore](../full-backup-and-restore-with-mariadb-backup/index) and [Incremental Backup and Restore](../incremental-backup-and-restore-with-mariadb-backup/index).

 ### `--binlog-info`

 Defines how Mariabackup retrieves the binary log coordinates from the server.

 
```
--binlog-info[=OFF | ON | LOCKLESS | AUTO]

```

The `--binlog-info` option supports the following retrieval methods. When no retrieval method is provided, it defaults to `AUTO`.

 


| Option | Description |
| --- | --- |
| `OFF` | Disables the retrieval of binary log information |
| `ON` | Enables the retrieval of binary log information, performs locking where available to ensure consistency |
| `LOCKLESS` | Unsupported option |
| `AUTO` | Enables the retrieval of binary log information using `ON` or `LOCKLESS` where supported |

 
Using this option, you can control how Mariabackup retrieves the server's binary log coordinates corresponding to the backup.

 When enabled, whether using `ON` or `AUTO`, Mariabackup retrieves information from the binlog during the backup process. When disabled with `OFF`, Mariabackup runs without attempting to retrieve binary log information. You may find this useful when you need to copy data without metadata like the binlog or replication coordinates.

 
```
$ mariabackup --binlog-info --backup

```

Currently, the `LOCKLESS` option depends on features unsupported by MariaDB Server. See the description of the `[xtrabackup\_binlog\_pos\_innodb](../files-created-by-mariabackup/index#xtrabackup_binlog_pos_innodb)` file for more information. If you attempt to run Mariabackup with this option, then it causes the utility to exit with an error. 

 ### `--close-files`

 Defines whether you want to close file handles.

 Using this option, you can tell Mariabackup that you want to close file handles. Without this option, Mariabackup keeps files open in order to manage DDL operations. When working with particularly large tablespaces, closing the file can make the backup more manageable. However, it can also lead to inconsistent backups. Use at your own risk.

 
```
$ mariabackup --close-files --prepare

```

### `--compress`

 
**MariaDB starting with [10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/)**
This option is deprecated staring with [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and 10.2.13 as relies on the no longer maintained [QuickLZ](http://www.quicklz.com/) library. It is recommended to instead backup to a stream (stdout), and use a 3rd party compression library to compress the stream, as described in [Using Encryption and Compression Tools With Mariabackup](../using-encryption-and-compression-tools-with-mariabackup/index).

 

Defines the compression algorithm for backup files. 

 
```
--compress[=compression_algorithm]

```

The `--compress` option only supports the now deprecated `quicklz` algorithm.

 


| Option | Description |
| --- | --- |
| `quicklz` | Uses the QuickLZ compression algorithm |

 

```
$ mariabackup --compress --backup

```

If a backup is compressed using this option, then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--compress-chunk-size`

 
Deprecated, for details see the `[--compress](#compress)` option.

 
Defines the working buffer size for compression threads.

 
```
--compress-chunk-size=#

```

Mariabackup can perform compression operations on the backup files before writing them to disk. It can also use multiple threads for parallel data compression during this process. Using this option, you can set the chunk size each thread uses during compression. It defaults to 64K.

 
```
$ mariabackup --backup --compress \
     --compress-threads=12 --compress-chunk-size=5M

```

To further configure backup compression, see the `[--compress](#-compress)` and `[--compress-threads](#-compress-threads)` options.

 ### `--compress-threads`

 
Deprecated, for details see the `[--compress](#compress)` option.

 
Defines the number of threads to use in compression.

 
```
--compress-threads=#

```

Mariabackup can perform compression operations on the backup files before writing them to disk. Using this option, you can define the number of threads you want to use for this operation. You may find this useful in speeding up the compression of particularly large databases. It defaults to single-threaded.

 
```
$ mariabackup --compress --compress-threads=12 --backup

```

To further configure backup compression, see the `[--compress](#-compress)` and `[--compress-chunk-size](#-compress-chunk-size)` options.

 ### `--copy-back`

 Restores the backup to the data directory.

 Using this command, Mariabackup copies the backup from the target directory to the data directory, as defined by the `[--datadir](#-h-datadir)` option. You must stop the MariaDB Server before running this command. The data directory must be empty. If you want to overwrite the data directory with the backup, use the `[--force-non-empty-directories](#-force-non-empty-directories)` option.

 Bear in mind, before you can restore a backup, you first need to run Mariabackup with the `[--prepare](#-prepare)` option. In the case of full backups, this makes the files point-in-time consistent. With incremental backups, this applies the deltas to the base backup. Once the backup is prepared, you can run `--copy-back` to apply it to MariaDB Server.

 
```
$ mariabackup --copy-back --force-non-empty-directories

```

Running the `--copy-back` command copies the backup files to the data directory. Use this command if you want to save the backup for later. If you don't want to save the backup for later, use the `[--move-back](#-move-back)` command.

 ### `--core-file`

 Defines whether to write a core file.

 Using this option, you can configure Mariabackup to dump its core to file in the event that it encounters fatal signals. You may find this useful for review and debugging purposes.

 
```
$ mariabackup --core-file --backup

```

### `--databases`

 Defines the databases and tables you want to back up.

 
```
--databases="database[.table][ database[.table] ...]"

```

Using this option, you can define the specific database or databases you want to back up. In cases where you have a particularly large database or otherwise only want to back up a portion of it, you can optionally also define the tables on the database. 

 
```
$ mariabackup --backup \
      --databases="example.table1 example.table2"

```

In cases where you want to back up most databases on a server or tables on a database, but not all, you can set the specific databases or tables you don't want to back up using the `[--databases-exclude](#-databases-exclude)` option. 

 If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 In `innobackupex` mode, which can be enabled with the `[--innobackupex](#-innobackupex)` option, the `--databases` option can be used as described above, or it can be used to refer to a file, just as the `[--databases-file](-databases-file)` option can in the normal mode.

 ### `--databases-exclude`

 Defines the databases you don't want to back up.

 
```
--databases-exclude="database[.table][ database[.table] ...]"

```

Using this option, you can define the specific database or databases you want to exclude from the backup process. You may find it useful when you want to back up most databases on the server or tables on a database, but would like to exclude a few from the process.

 
```
$ mariabackup --backup \
      --databases="example" \
      --databases-exclude="example.table1 example.table2"

```

To include databases in the backup, see the `[--databases](#-databases)` option option

 If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--databases-file`

 Defines the path to a file listing databases and/or tables you want to back up.

 
```
--databases-file="/path/to/database-file"

```

Format the databases file to list one element per line, with the following syntax:

 
```
database[.table]

```

In cases where you need to back up a number of databases or specific tables in a database, you may find the syntax for the `[--databases](#-databases)` and `[--databases-exclude](#-databases-exclude)` options a little cumbersome. Using this option you can set the path to a file listing the databases or databases and tables you want to back up.

 For instance, imagine you list the databases and tables for a backup in a file called `main-backup`.

 
```
$ cat main-backup
example1
example2.table1
example2.table2

$ mariabackup --backup --databases-file=main-backup

```

If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `-h, --datadir`

 Defines the path to the database root. 

 
```
--datadir=PATH

```

Using this option, you can define the path to the source directory. This is the directory that Mariabackup reads for the data it backs up. It should be the same as the MariaDB Server `[datadir](../server-system-variables/index#datadir)` system variable.

 
```
$ mariabackup --backup -h /var/lib64/mysql

```

### `--debug-sleep-before-unlock`

 This is a debug-only option used by the Xtrabackup test suite.

 ### `--decompress`

 
Deprecated, for details see the `[--compress](#compress)` option.

 

This option requires that you have the `qpress` utility installed on your system.

 
Defines whether you want to decompress previously compressed backup files. 

 When you run Mariabackup with the `[--compress](#-compress)` option, it compresses the subsequent backup files, using the QuickLZ algorithm. Using this option, Mariabackup decompresses the compressed files from a previous backup. 

 For instance, run a backup with compression,

 
```
$ mariabackup --compress --backup

```

Then decompress the backup,

 
```
$ mariabackup --decompress

```

You can enable the decryption of multiple files at a time using the `[--parallel](#-parallel)` option. By default, Mariabackup does not remove the compressed files from the target directory. If you want to delete these files, use the `[--remove-original](#-remove-original)` option.

 ### `--debug-sync`

 Defines the debug sync point. This option is only used by the Mariabackup test suite.

 ### `--defaults-extra-file`

 Defines the path to an extra default [option file](../configuring-mariadb-with-option-files/index).

 
```
--defaults-extra-file=/path/to/config

```

Using this option, you can define an extra default [option file](../configuring-mariadb-with-option-files/index) for Mariabackup. Unlike `[--defaults-file](#-defaults-file)`, this file is read after the default [option files](../configuring-mariadb-with-option-files/index) are read, allowing you to only overwrite the existing defaults.

 
```
$ mariabackup --backup \
      --defaults-file-extra=addition-config.cnf \
      --defaults-file=config.cnf

```

### `--defaults-file`

 Defines the path to the default [option file](../configuring-mariadb-with-option-files/index).

 
```
--defaults-file=/path/to/config

```

Using this option, you can define a default [option file](../configuring-mariadb-with-option-files/index) for Mariabackup. Unlike the `[--defaults-extra-file](#-defaults-extra-file)` option, when this option is provided, it completely replaces all default [option files](../configuring-mariadb-with-option-files/index).

 
```
$ mariabackup --backup \
     --defaults-file="config.cnf

```

### `--defaults-group`

 Defines the [option group](../configuring-mariadb-with-option-files/index#option-groups) to read in the [option file](../configuring-mariadb-with-option-files/index).

 
```
--defaults-group="name"

```

In situations where you find yourself using certain Mariabackup options consistently every time you call it, you can set the options in an [option file](../configuring-mariadb-with-option-files/index). The `--defaults-group` option defines what option group Mariabackup reads for its options.

 Options you define from the command-line can be set in the configuration file using minor formatting changes. For instance, if you find yourself perform compression operations frequently, you might set `[--compress-threads](#-compress-threads)` and `[--compress-chunk-size](#-compress-chunk-size)` options in this way:

 
```
[mariabackup]
compress_threads = 12
compress_chunk_size = 64K

```

Now whenever you run a backup with the `[--compress](#-compress)` option, it always performs the compression using 12 threads and 64K chunks.

 
```
$ mariabackup --compress --backup

```

See [Mariabackup Overview: Server Option Groups](../mariabackup-overview/index#server-option-groups) and [Mariabackup Overview: Client Option Groups](../mariabackup-overview/index#client-option-groups) for a list of the option groups read by Mariabackup by default.

 ### `--encrypted-backup`

 When this option is used with `--backup`, if Mariabackup encounters a page that has a non-zero `key_version` value, then Mariabackup assumes that the page is encrypted.

 Use `--skip-encrypted-backup` instead to allow Mariabackup to copy unencrypted tables that were originally created before MySQL 5.1.48.

 This option was added in [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), and [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

 ### `--export`

 If this option is provided during the `--prepare` stage, then it tells Mariabackup to create `.cfg` files for each [InnoDB file-per-table tablespace](../innodb-file-per-table-tablespaces/index). These `.cfg` files are used to [import transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) in the process of [restoring partial backups](../partial-backup-and-restore-with-mariabackup/index) and [restoring individual tables and partitions](../restoring-individual-tables-and-partitions-with-mariabackup/index). .

 
```
$ mariabackup --prepare --export

```


**MariaDB until [10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)**In [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/) and before, Mariabackup did not support the `[--export](index#-export)` option. See [MDEV-13466](https://jira.mariadb.org/browse/MDEV-13466) about that. In earlier versions of MariaDB, this means that Mariabackup could not create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index) during the `--prepare` stage. You can still [import file-per-table tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) without the `.cfg` files in many cases, so it may still be possible in those versions to [restore partial backups](../partial-backup-and-restore-with-mariabackup/index) or to [restore individual tables and partitions](../restoring-individual-tables-and-partitions-with-mariabackup/index) with just the `.ibd` files. If you have a [full backup](../full-backup-and-restore-with-mariabackup/index) and you need to create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index), then you can do so by preparing the backup as usual without the `--export` option, and then restoring the backup, and then starting the server. At that point, you can use the server's built-in features to [copy the transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces).

 
### `--extra-lsndir`

 Saves an extra copy of the `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` and `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` files into the given directory.

 
```
--extra-lsndir=PATH

```

When using the `[--backup](#-backup)` command option, Mariabackup produces a number of backup files in the target directory. Using this option, you can have Mariabackup produce additional copies of the `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` and `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` files in the given directory.

 
```
$ mariabackup --extra-lsndir=extras/ --backup

```

This is especially usefull when using `[--stream](#-stream)` for streaming output, e.g. for [compression and/or encryption using external tools](../using-encryption-and-compression-tools-with-mariabackup/index) in combination with [incremental backups](../incremental-backup-and-restore-with-mariabackup/index), as the `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` file necessary to determine the LSN to continue the incremental backup from is still accessible without uncompressing / decrypting the backup file first. Simply pass in the `--extra-lsndir` of the previous backup as `[--incremental-basedir](#-incremental-basedir)`

 ### `--force-non-empty-directories`

 Allows `[--copy-back](#-copy-back)` or `[--move-back](#-move-back)` command options to use non-empty target directories.

 When using Mariabackup with the `[--copy-back](#-copy-back)` or `[--move-back](#-move-back)` command options, they normally require a non-empty target directory to avoid conflicts. Using this option with either of command allows Mariabackup to use a non-empty directory.

 
```
$ mariabackup --force-on-empty-directories --copy-back

```

Bear in mind that this option does not enable overwrites. When copying or moving files into the target directory, if Mariabackup finds that the target file already exists, it fails with an error.

 ### `--ftwrl-wait-query-type`

 Defines the type of query allowed to complete before Mariabackup issues the global lock.

 
```
--ftwrl-wait-query-type=[ALL | UPDATE | SELECT]

```

The `--ftwrl-wait-query-type` option supports the following query types. The default value is `ALL`.

 


| Option | Description |
| --- | --- |
| `ALL` | Waits until all queries complete before issuing the global lock |
| `SELECT` | Waits until `[SELECT](../select/index)` statements complete before issuing the global lock |
| `UPDATE` | Waits until `[UPDATE](../update/index)` statements complete before issuing the global lock |

 
When Mariabackup runs, it issues a global lock to prevent data from changing during the backup process. When it encounters a statement in the process of executing, it waits until the statement is finished before issuing the global lock. Using this option, you can modify this default behavior to ensure that it waits only for certain query types, such as for `[SELECT](../select/index)` and `[UPDATE](../update/index)` statements.

 
```
$ mariabackup --backup  \
      --ftwrl-wait-query-type=UPDATE

```

### `--ftwrl-wait-threshold`

 Defines the minimum threshold for identifying long-running queries for FTWRL.

 
```
--ftwrl-wait-threshold=#

```

When Mariabackup runs, it issues a global lock to prevent data from changing during the backup process and ensure a consistent record. If it encounters statements still in the process of executing, it waits until they complete before setting the lock. Using this option, you can set the threshold at which Mariabackup engages FTWRL. When it `[--ftwrl-wait-timeout](#-ftwrl-wait-timeout)` is not 0 and a statement has run for at least the amount of time given this argument, Mariabackup waits until the statement completes or until the `[--ftwrl-wait-timeout](#-ftwrl-wait-timeout)` expires before setting the global lock and starting the backup.

 
```
$ mariabackup --backup \
     --ftwrl-wait-timeout=90 \
     --ftwrl-wait-threshold=30

```

### `--ftwrl-wait-timeout`

 Defines the timeout to wait for queries before trying to acquire the global lock. In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the global lock refers to `[BACKUP STAGE BLOCK\_COMMIT](../backup-stage/index#backup-stage-block_commit)`. In [MariaDB 10.3](../what-is-mariadb-103/index) and before, the global lock refers to `[FLUSH TABLES WITH READ LOCK (FTWRL)](../flush/index#the-purpose-of-flush-tables-table_list-with-read-lock)`.

 
```
--ftwrl-wait-timeout=#

```

When Mariabackup runs, it acquires a global lock to prevent data from changing during the backup process and ensure a consistent record. If it encounters statements still in the process of executing, it can be configured to wait until the statements complete before trying to acquire the global lock.

 If the `--ftwrl-wait-timeout` is set to 0, then Mariabackup tries to acquire the global lock immediately without waiting. This is the default value.

 If the `--ftwrl-wait-timeout` is set to a non-zero value, then Mariabackup waits for the configured number of seconds until trying to acquire the global lock.

 Starting in [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), and [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), Mariabackup will exit if it can't acquire the global lock after waiting for the configured number of seconds. In earlier versions, it could wait for the global lock indefinitely, even if `--ftwrl-wait-timeout` was set to a non-zero value.

 
```
$ mariabackup --backup \
      --ftwrl-wait-query-type=UPDATE \
      --ftwrl-wait-timeout=5

```

### `--galera-info`

 Defines whether you want to back up information about a [Galera Cluster](../galera/index) node's state.

 When this option is used, Mariabackup creates an additional file called `[xtrabackup\_galera\_info](../files-created-by-mariabackup/index#xtrabackup_galera_info)`, which records information about a [Galera Cluster](../galera/index) node's state. It records the values of the `[wsrep\_local\_state\_uuid](../galera-cluster-status-variables/index#wsrep_local_state_uuid)` and `[wsrep\_last\_committed](../galera-cluster-status-variables/index#wsrep_last_committed)` status variables.

 You should only use this option when backing up a [Galera Cluster](../galera/index) node. If the server is not a [Galera Cluster](../galera/index) node, then this option has no effect.

 
```
$ mariabackup --backup --galera-info

```

### `--history`

 Defines whether you want to track backup history in the `PERCONA_SCHEMA.xtrabackup_history` table.

 
```
--history[=name]

```

When using this option, Mariabackup records its operation in a table on the MariaDB Server. Passing a name to this option allows you group backups under arbitrary terms for later processing and analysis. 

 
```
$ mariabackup --backup --history=backup_all

```

Currently, the table it uses by default is named `mysql.mariadb_backup_history`. Prior to [MariaDB 10.11](../what-is-mariadb-1011/index), the default table was `PERCONA_SCHEMA.xtrabackup_history`.

 Mariabackup will also record this in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `-H, --host`

 Defines the host for the MariaDB Server you want to backup.

 
```
--host=name

```

Using this option, you can define the host to use when connecting to a MariaDB Server over TCP/IP. By default, Mariabackup attempts to connect to the local host. 

 
```
$ mariabackup --backup \
      --host="example.com"

```

### `--include`

 This option is a regular expression to be matched against table names in databasename.tablename format. It is equivalent to the `[--tables](#-tables)` option. This is only valid in `innobackupex` mode, which can be enabled with the `[--innobackupex](#-innobackupex)` option.

 ### `--incremental`

 Defines whether you want to take an increment backup, based on another backup. This is only valid in `innobackupex` mode, which can be enabled with the `[--innobackupex](#-innobackupex)` option.

 
```
mariabackup --innobackupex --incremental

```

Using this option with the `[--backup](#-backup)` command option makes the operation incremental rather than a complete overwrite. When this option is specified, either the `[--incremental-lsn](#-incremental-lsn) or` [--incremental-basedir](#-incremental-basedir) `options can also be given. If neither option is given, option` [--incremental-basedir](#-incremental-basedir) `is used by default, set to the first timestamped backup directory in the backup base directory.`

 
```
$ mariabackup --innobackupex --backup --incremental \
     --incremental-basedir=/data/backups \
     --target-dir=/data/backups

```

If a backup is a [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--incremental-basedir`

 Defines whether you want to take an incremental backup, based on another backup. 

 
```
--incremental-basedir=PATH

```

Using this option with the `[--backup](#-backup)` command option makes the operation incremental rather than a complete overwrite. Mariabackup will only copy pages from `.ibd` files if they are newer than the backup in the specified directory.

 
```
$ mariabackup --backup \
     --incremental-basedir=/data/backups \
     --target-dir=/data/backups

```

If a backup is a [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--incremental-dir`

 Defines whether you want to take an incremental backup, based on another backup. 

 
```
--increment-dir=PATH

```

Using this option with `[--prepare](#-prepare)` command option makes the operation incremental rather than a complete overwrite. Mariabackup will apply `.delta` files and log files into the target directory.

 
```
$ mariabackup --prepare \
      --increment-dir=backups/

```

If a backup is a [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--incremental-force-scan`

 Defines whether you want to force a full scan for incremental backups. 

 When using Mariabackup to perform an incremental backup, this option forces it to also perform a full scan of the data pages being backed up, even when there's bitmap data on the changes. [MariaDB 10.2](../what-is-mariadb-102/index) and later does not support changed page bitmaps, so this option is useless in those versions. See [MDEV-18985](https://jira.mariadb.org/browse/MDEV-18985) for more information.

 
```
$ mariabackup --backup \
     --incremental-basedir=/path/to/target \
     --incremental-force-scan

```

### `--incremental-history-name`

 Defines a logical name for the backup.

 
```
--incremental-history-name=name

```

Mariabackup can store data about its operations on the MariaDB Server. Using this option, you can define the logical name it uses in identifying the backup.

 
```
$ mariabackup --backup \
     --incremental-history-name=morning_backup

```

Currently, the table it uses by default is named `mysql.mariadb_backup_history`. Prior to [MariaDB 10.11](../what-is-mariadb-1011/index), the default table was `PERCONA_SCHEMA.xtrabackup_history`.

 Mariabackup will also record this in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--incremental-history-uuid`

 Defines a UUID for the backup.

 
```
--incremental-history-uuid=name

```

Mariabackup can store data about its operations on the MariaDB Server. Using this option, you can define the UUID it uses in identifying a previous backup to increment from. It checks `[--incremental-history-name](#-incremental-history-name)`, `[--incremental-basedir](#-incremental-basedir)`, and `[--incremental-lsn](#-incremental-lsn)`. If Mariabackup fails to find a valid lsn, it generates an error.

 
```
$ mariabackup --backup \
      --incremental-history-uuid=main-backup012345678

```

Currently, the table it uses is named `PERCONA_SCHEMA.xtrabackup_history`, but expect that name to change in future releases. See [MDEV-19246](https://jira.mariadb.org/browse/MDEV-19246) for more information.

 Mariabackup will also record this in the `[xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info)` file.

 ### `--incremental-lsn`

 Defines the sequence number for incremental backups.

 
```
--incremental-lsn=name

```

Using this option, you can define the sequence number (LSN) value for `[--backup](#-backup)` operations. During backups, Mariabackup only copies `.ibd` pages newer than the specified values.

 **WARNING**: Incorrect LSN values can make the backup unusable. It is impossible to diagnose this issue.

 ### `--innobackupex`

 Enables `innobackupex` mode, which is a compatibility mode.

 
```
$ mariabackup --innobackupex

```

In `innobackupex` mode, Mariabackup has the following differences:

 * To prepare a backup, the `[--apply-log](#-apply-log)` option is used instead of the `[--prepare](#-prepare)` option.
* To create an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), the `[--incremental](#-incremental)` option is supported.
* The `[--no-timestamp](#-no-timestamp)` option is supported.
* To create a [partial backup](../partial-backup-and-restore-with-mariabackup/index), the `[--include](#--include)` option is used instead of the `[--tables](#-tables)` option.
* To create a [partial backup](../partial-backup-and-restore-with-mariabackup/index), the `[--databases](#--databases)` option can still be used, but it's behavior changes slightly.
* The `[--target-dir](#-target-dir)` option is not used to specify the backup directory. The backup directory should instead be specified as a standalone argument.

 The primary purpose of `innobackupex` mode is to allow scripts and tools to more easily migrate to Mariabackup if they were originally designed to use the `innobackupex` utility that is included with [Percona XtraBackup](../percona-xtrabackup-overview/index). It is not recommended to use this mode in new scripts, since it is not guaranteed to be supported forever. See [MDEV-20552](https://jira.mariadb.org/browse/MDEV-20552) for more information.

 ### `--innodb`

 This option has no effect. Set only for MySQL option compatibility.

 ### `--innodb-adaptive-hash-index`

 Enables InnoDB Adaptive Hash Index.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option you can explicitly enable the InnoDB Adaptive Hash Index. This feature is enabled by default for Mariabackup. If you want to disable it, use `[--skip-innodb-adaptive-hash-index](#-skip-innodb-adaptive-hash-index)`.

 
```
$ mariabackup --backup \
      --innodb-adaptive-hash-index

```

### `--innodb-autoextend-increment`

 Defines the increment in megabytes for auto-extending the size of tablespace file.

 
```
--innodb-autoextend-increment=36

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can set the increment in megabytes for automatically extending the size of tablespace data file in InnoDB.

 
```
$ mariabackup --backup \
     --innodb-autoextend-increment=35

```

### `--innodb-buffer-pool-filename`

 Using this option has no effect. It is available to provide compatibility with the MariaDB Server.

 ### `--innodb-buffer-pool-size`

 Defines the memory buffer size InnoDB uses the cache data and indexes of the table.

 
```
--innodb-buffer-pool-size=124M

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can configure the buffer pool for InnoDB operations. 

 
```
$ mariabackup --backup \
      --innodb-buffer-pool-size=124M

```

### `--innodb-checksum-algorithm`

 [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) was deprecated in [MariaDB 10.3.29](https://mariadb.com/kb/en/mariadb-10329-release-notes/), [MariaDB 10.4.19](https://mariadb.com/kb/en/mariadb-10419-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/) and removed in [MariaDB 10.6](../what-is-mariadb-106/index).

 In earlier versions, it is used to define the checksum algorithm.

 
```
--innodb-checksum-algorithm=crc32
                           | strict_crc32
                           | innodb
                           | strict_innodb
                           | none
                           | strict_none 

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can specify the algorithm Mariabackup uses when checksumming on InnoDB tables. Currently, MariaDB supports the following algorithms `CRC32`, `STRICT_CRC32`, `INNODB`, `STRICT_INNODB`, `NONE`, `STRICT_NONE`.

 
```
$ mariabackup --backup \
      ---innodb-checksum-algorithm=strict_innodb

```

### `--innodb-data-file-path`

 Defines the path to individual data files.

 
```
--innodb-data-file-path=/path/to/file

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option you can define the path to InnoDB data files. Each path is appended to the `[--innodb-data-home-dir](#-innodb-data-home-dir)` option.

 
```
$ mariabackup --backup \
     --innodb-data-file-path=ibdata1:13M:autoextend \
     --innodb-data-home-dir=/var/dbs/mysql/data

```

### `--innodb-data-home-dir`

 Defines the home directory for InnoDB data files.

 
```
--innodb-data-home-dir=PATH

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option you can define the path to the directory containing InnoDB data files. You can specific the files using the `[--innodb-data-file-path](#-innodb-data-file-path)` option.

 
```
$ mariabackup --backup \
     --innodb-data-file-path=ibdata1:13M:autoextend \
     --innodb-data-home-dir=/var/dbs/mysql/data

```

### `--innodb-doublewrite`

 Enables doublewrites for InnoDB tables.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. When using this option, Mariabackup improves fault tolerance on InnoDB tables with a doublewrite buffer. By default, this feature is enabled. Use this option to explicitly enable it. To disable doublewrites, use the `[--skip-innodb-doublewrite](#-skip-innodb-doublewrite)` option. 

 
```
$ mariabackup --backup \
     --innodb-doublewrite

```

### `--innodb-encrypt-log`

 Defines whether you want to encrypt InnoDB logs.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can tell Mariabackup that you want to encrypt logs from its InnoDB activity.

 ### `--innodb-file-io-threads`

 Defines the number of file I/O threads in InnoDB.

 
```
--innodb-file-io-threads=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the number of file I/O threads Mariabackup uses on InnoDB tables.

 
```
$ mariabackup --backup \
     --innodb-file-io-threads=5

```

### `--innodb-file-per-table`

 Defines whether you want to store each InnoDB table as an `.ibd` file.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option causes Mariabackup to store each InnoDB table as an `.ibd` file in the target directory.

 ### `--innodb-flush-method`

 Defines the data flush method. Ignored from [MariaDB 11.0](../what-is-mariadb-110/index).

 
```
--innodb-flush-method=fdatasync 
                     | O_DSYNC 
                     | O_DIRECT 
                     | O_DIRECT_NO_FSYNC 
                     | ALL_O_DIRECT

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the data flush method Mariabackup uses with InnoDB tables.

 
```
$ mariabackup --backup \
      --innodb-flush-method==_DIRECT_NO_FSYNC

```

Note, the `0_DIRECT_NO_FSYNC` method is only available with [MariaDB 10.0](../what-is-mariadb-100/index) and later. The `ALL_O_DIRECT` method available with version 5.5 and later, but only with tables using the XtraDB storage engine.

 ### `--innodb-io-capacity`

 Defines the number of IOP's the utility can perform.

 
```
--innodb-io-capacity=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can limit the I/O activity for InnoDB background tasks. It should be set around the number of I/O operations per second that the system can handle, based on drive or drives being used. 

 
```
$ mariabackup --backup \
     --innodb-io-capacity=200

```

### `--innodb-log-checksums`

 Defines whether to include checksums in the InnoDB logs.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can explicitly set Mariabackup to include checksums in the InnoDB logs. The feature is enabled by default. To disable it, use the `[--skip-innodb-log-checksums](#-skip-innodb-log-checksums)` option.

 
```
$ mariabackup --backup \
      --innodb-log-checksums

```

### `--innodb-log-buffer-size`

 This option has no functionality in Mariabackup. It exists for MariaDB Server compatibility.

 ### `--innodb-log-files-in-group`

 This option has no functionality in Mariabackup. It exists for MariaDB Server compatibility.

 ### `--innodb-log-group-home-dir`

 Defines the path to InnoDB log files.

 
```
--innodb-log-group-home-dir=PATH

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the path to InnoDB log files.

 
```
$ mariabackup --backup \
     --innodb-log-group-home-dir=/path/to/logs

```

### `--innodb-max-dirty-pages-pct`

 Defines the percentage of dirty pages allowed in the InnoDB buffer pool.

 
```
--innodb-max-dirty-pages-pct=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the maximum percentage of dirty, (that is, unwritten) pages that Mariabackup allows in the InnoDB buffer pool.

 
```
$ mariabackup --backup \
     --innodb-max-dirty-pages-pct=80

```

### `--innodb-open-files`

 Defines the number of files kept open at a time.

 
```
--innodb-open-files=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can set the maximum number of files InnoDB keeps open at a given time during backups.

 
```
$ mariabackup --backup \
      --innodb-open-files=10

```

### `--innodb-page-size`

 Defines the universal page size.

 
```
--innodb-page-size=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the universal page size in bytes for Mariabackup.

 
```
$ mariabackup --backup \
     --innodb-page-size=16k

```

### `--innodb-read-io-threads`

 Defines the number of background read I/O threads in InnoDB.

 
```
--innodb-read-io-threads=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can set the number of I/O threads MariaDB uses when reading from InnoDB.

 
```
$ mariabackup --backup \
      --innodb-read-io-threads=4

```

### `--innodb-undo-directory`

 Defines the directory for the undo tablespace files.

 
```
--innodb-undo-directory=PATH

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the path to the directory where you want MariaDB to store the undo tablespace on InnoDB tables. The path can be absolute.

 
```
$ mariabackup --backup \
     --innodb-undo-directory=/path/to/innodb_undo

```

### `--innodb-undo-tablespaces`

 Defines the number of undo tablespaces to use.

 
```
--innodb-undo-tablespaces=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can define the number of undo tablespaces you want to use during the backup.

 
```
$ mariabackup --backup \
      --innodb-undo-tablespaces=10

```

### `--innodb-use-native-aio`

 Defines whether you want to use native AI/O.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can enable the use of the native asynchronous I/O subsystem. It is only available on Linux operating systems.

 
```
$ mariabackup --backup \
      --innodb-use-native-aio

```

### `--innodb-write-io-threads`

 Defines the number of background write I/O threads in InnoDB.

 
```
--innodb-write-io-threads=#

```

Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can set the number of background write I/O threads Mariabackup uses.

 
```
$ mariabackup --backup \
     --innodb-write-io-threads=4

```

### `--kill-long-queries-timeout`

 Defines the timeout for blocking queries.

 
```
--kill-long-queries-timeout=#

```

When Mariabackup runs, it issues a `FLUSH TABLES WITH READ LOCK` statement. It then identifies blocking queries. Using this option you can set a timeout in seconds for these blocking queries. When the time runs out, Mariabackup kills the queries.

 The default value is 0, which causes Mariabackup to not attempt killing any queries.

 
```
$ mariabackup --backup \
      --kill-long-queries-timeout=10

```

### `--kill-long-query-type`

 Defines the query type the utility can kill to unblock the global lock.

 
```
--kill-long-query-type=ALL | UPDATE | SELECT

```

When Mariabackup encounters a query that sets a global lock, it can kill the query in order to free up MariaDB Server for the backup. Using this option, you can choose the types of query it kills: `[SELECT](../select/index)`, `[UPDATE](../update/index)`, or both set with `ALL`. The default is `ALL`.

 
```
$ mariabackup --backup \
      --kill-long-query-type=UPDATE

```

### `--lock-ddl-per-table`

 Prevents DDL for each table to be backed up by acquiring MDL lock on that. NOTE: Unless --no-lock option was also specified, conflicting DDL queries , will be killed at the end of backup This is done avoid deadlock between "FLUSH TABLE WITH READ LOCK", user's DDL query (ALTER, RENAME), and MDL lock on table. Only available in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and later.

 ### `--log`

 This option has no functionality. It is set to ensure compatibility with MySQL.

 ### `--log-bin`

 Defines the base name for the log sequence.

 
```
--log-bin[=name]

```

Using this option you, you can set the base name for Mariabackup to use in log sequences.

 ### `--log-copy-interval`

 Defines the copy interval between checks done by the log copying thread.

 
```
--log-copy-interval=#

```

Using this option, you can define the copy interval Mariabackup uses between checks done by the log copying thread. The given value is in milliseconds.

 
```
$ mariabackup --backup \
      --log-copy-interval=50

```

### `--log-innodb-page-corruption`

 Continue backup if InnoDB corrupted pages are found. The pages are logged in `innodb_corrupted_pages` and backup is finished with error. [--prepare](#-prepare) will try to fix corrupted pages. If `innodb_corrupted_pages` exists after [--prepare](#-prepare) in base backup directory, backup still contains corrupted pages and can not be considered as consistent.

 Added in [MariaDB 10.2.37](https://mariadb.com/kb/en/mariadb-10237-release-notes/), [MariaDB 10.3.28](https://mariadb.com/kb/en/mariadb-10328-release-notes/), [MariaDB 10.4.18](https://mariadb.com/kb/en/mariadb-10418-release-notes/), [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/)

 ### `--move-back`

 Restores the backup to the data directory.

 Using this command, Mariabackup moves the backup from the target directory to the data directory, as defined by the `[--datadir](#-h-datadir)` option. You must stop the MariaDB Server before running this command. The data directory must be empty. If you want to overwrite the data directory with the backup, use the `[--force-non-empty-directories](#-force-non-empty-directories)` option.

 Bear in mind, before you can restore a backup, you first need to run Mariabackup with the `[--prepare](#-prepare)` option. In the case of full backups, this makes the files point-in-time consistent. With incremental backups, this applies the deltas to the base backup. Once the backup is prepared, you can run `--move-back` to apply it to MariaDB Server.

 
```
$ mariabackup --move-back \
      --datadir=/var/mysql

```

Running the `--move-back` command moves the backup files to the data directory. Use this command if you don't want to save the backup for later. If you do want to save the backup for later, use the `[--copy-back](#-copy-back)` command.

 ### `--mysqld`

 Used internally to prepare a backup.

 ### `--no-backup-locks`

 Mariabackup locks the database by default when it runs. This option disables support for Percona Server's backup locks.

 When backing up Percona Server, Mariabackup would use backup locks by default. To be specific, backup locks refers to the `LOCK TABLES FOR BACKUP` and `LOCK BINLOG FOR BACKUP` statements. This option can be used to disable support for Percona Server's backup locks. This option has no effect when the server does not support Percona's backup locks.

 This option may eventually be removed. See [MDEV-19753](https://jira.mariadb.org/browse/MDEV-19753) for more information.

 
```
$ mariabackup --backup --no-backup-locks

```

### `--no-lock`

 Disables table locks with the `FLUSH TABLE WITH READ LOCK` statement.

 Using this option causes Mariabackup to disable table locks with the `FLUSH TABLE WITH READ LOCK` statement. Only use this option if:

 * You are not executing DML statements on non-InnoDB tables during the backup. This includes the `mysql` database system tables (which are MyISAM).
* You are not executing any DDL statements during the backup.
* You **do not care** if the binary log position included with the backup in `[xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info)` is consistent with the data.
* **All** tables you're backing up use the InnoDB storage engine.

 
```
$ mariabackup --backup --no-lock

```

If you're considering `--no-lock` due to backups failing to acquire locks, this may be due to incoming replication events preventing the lock. Consider using the [--safe-slave-backup](#-safe-slave-backup) option to momentarily stop the replica thread. This alternative may help the backup to succeed without resorting to `--no-lock`. 

 
Do not use this option. This option may cause data consistency issues. This option is not supported.

 
### `--no-timestamp`

 This option prevents creation of a time-stamped subdirectory of the BACKUP-ROOT-DIR given on the command line. When it is specified, the backup is done in BACKUP-ROOT-DIR instead. This is only valid in `innobackupex` mode, which can be enabled with the `[--innobackupex](#-innobackupex)` option.

 ### `--no-version-check`

 Disables version check.

 Using this option, you can disable Mariabackup version check. 

 
```
$ mariabackup --backup --no-version-check

```

### `--open-files-limit`

 Defines the maximum number of file descriptors.

 
```
--open-files-limit=#

```

Using this option, you can define the maximum number of file descriptors Mariabackup reserves with `setrlimit()`.

 
```
$ mariabackup --backup \
      --open-files-limit=

```

### `--parallel`

 Defines the number of threads to use for parallel data file transfer.

 
```
--parallel=#

```

Using this option, you can set the number of threads Mariabackup uses for parallel data file transfers. By default, it is set to 1.

 ### `-p, --password`

 Defines the password to use to connect to MariaDB Server.

 
```
--password=passwd

```

When you run Mariabackup, it connects to MariaDB Server in order to access and back up the databases and tables. Using this option, you can set the password Mariabackup uses to access the server. To set the user, use the `[--user](#-u-user)` option.

 
```
$ mariabackup --backup \
      --user=root \
      --password=root_password

```

### `--plugin-dir`

 Defines the directory for server plugins.

 
```
--plugin-dir=PATH

```

Using this option, you can define the path Mariabackup reads for MariaDB Server plugins. It only uses it during the `[--prepare](#-prepare)` phase to load the encryption plugin. It defaults to the `[plugin\_dir](../server-system-variables/index#plugin_dir)` server system variable.

 
```
$ mariabackup --backup \
      --plugin-dir=/var/mysql/lib/plugin

```

### `--plugin-load`

 Defines the encryption plugins to load.

 
```
--plugin-load=name

```

Using this option, you can define the encryption plugin you want to load. It is only used during the `[--prepare](#-prepare)` phase to load the encryption plugin. It defaults to the server `--plugin-load` option. 

 The option was removed starting from [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/)

 ### `-P, --port`

 Defines the server port to connect to.

 
```
--port=#

```

When you run Mariabackup, it connects to MariaDB Server in order to access and back up your databases and tables. Using this option, you can set the port the utility uses to access the server over TCP/IP. To set the host, see the `[--host](#-h-host)` option. Use `mysql --help` for more details.

 
```
$ mariabackup --backup \
      --host=192.168.11.1 \
      --port=3306

```

### `--prepare`

 Prepares an existing backup to restore to the MariaDB Server.

 Files that Mariabackup generates during `[--backup](#-backup)` operations in the target directory are not ready for use on the Server. Before you can restore the data to MariaDB, you first need to prepare the backup.

 In the case of full backups, the files are not point in time consistent, since they were taken at different times. If you try to restore the database without first preparing the data, InnoDB rejects the new data as corrupt. Running Mariabackup with the `--prepare` command readies the data so you can restore it to MariaDB Server. When working with incremental backups, you need to use the `--prepare` command and the `[--incremental-dir](#-incremental-dir)` option to update the base backup with the deltas from an incremental backup.

 
```
$ mariabackup --prepare

```

Once the backup is ready, you can use the `[--copy-back](#-copy-back)` or the `[--move-back](#-move-back)` commands to restore the backup to the server.

 ### `--print-defaults`

 Prints the utility argument list, then exits.

 Using this argument, MariaDB prints the argument list to stdout and then exits. You may find this useful in debugging to see how the options are set for the utility.

 
```
$ mariabackup --print-defaults

```

### `--print-param`

 Prints the MariaDB Server options needed for copyback.

 Using this option, Mariabackup prints to stdout the MariaDB Server options that the utility requires to run the `[--copy-back](#-copy-back)` command option.

 
```
$ mariabackup --print-param

```

### `--rollback-xa`

 By default, Mariabackup will not commit or rollback uncommitted XA transactions, and when the backup is restored, any uncommitted XA transactions must be manually committed using `XA COMMIT` or manually rolled back using `XA ROLLBACK`.

 In [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.3](../what-is-mariadb-103/index), and [MariaDB 10.4](../what-is-mariadb-104/index), Mariabackup's `--rollback-xa` option can be used to rollback uncommitted XA transactions while performing a `--prepare` operation, so that they do not need to be manually committed or rolled back when the backup is restored.

 This option is not present from [MariaDB 10.5](../what-is-mariadb-105/index), because the server has more robust ways of handling uncommitted XA transactions in later versions.

 
This is an experimental option. Do not use this option in versions older than [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), and [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/). Older implementation can cause corruption of InnoDB data.

 
### `--rsync`

 Defines whether to use rsync.

 During normal operation, Mariabackup transfers local non-InnoDB files using a separate call to `cp` for each file. Using this option, you can optimize this process by performing this transfer with rsync, instead.

 
```
$ mariabackup --backup --rsync

```

This option is not compatible with the `[--stream](#-stream)` option.

 ### `--safe-slave-backup`

 Stops replica SQL threads for backups.

 When running Mariabackup on a server that uses replication, you may occasionally encounter locks that block backups. Using this option, it stops replica SQL threads and waits until the `Slave_open_temp_tables` in the `SHOW STATUS` statement is zero. If there are no open temporary tables, the backup runs, otherwise the SQL thread starts and stops until there are no open temporary tables.

 
```
$ mariabackup --backup \
      --safe-slave-backup \
      --safe-slave-backup-timeout=500

```

The backup fails if the `Slave_open_temp_tables` doesn't reach zero after the timeout period set by the [--safe-slave-backup-timeout](#-safe-slave-backup-timeout) option.

 ### `--safe-slave-backup-timeout`

 Defines the timeout for replica backups.

 
```
--safe-slave-backup-timeout=#

```

When running Mariabackup on a server that uses replication, you may occasionally encounter locks that block backups. With the [--safe-slave-backup](#-safe-slave-backup) option, it waits until the `Slave_open_temp_tables` in the `SHOW STATUS` statement reaches zero. Using this option, you set how long it waits. It defaults to 300.

 
```
$ mariabackup --backup \
      --safe-slave-backup \
      --safe-slave-backup-timeout=500

```

### `--secure-auth`

 Refuses client connections to servers using the older protocol.

 Using this option, you can set it explicitly to refuse client connections to the server when using the older protocol, from before 4.1.1. This feature is enabled by default. Use the [--skip-secure-auth](#-skip-secure-auth) option to disable it.

 
```
$ mariabackup --backup --secure-auth

```

### `--skip-innodb-adaptive-hash-index`

 Disables InnoDB Adaptive Hash Index.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option you can explicitly disable the InnoDB Adaptive Hash Index. This feature is enabled by default for Mariabackup. If you want to explicitly enable it, use `[--innodb-adaptive-hash-index](#-innodb-adaptive-hash-index)`.

 
```
$ mariabackup --backup \
      --skip-innodb-adaptive-hash-index

```

### `--skip-innodb-doublewrite`

 Disables doublewrites for InnoDB tables.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. When doublewrites are enabled, InnoDB improves fault tolerance with a doublewrite buffer. By default this feature is turned on. Using this option you can disable it for Mariabackup. To explicitly enable doublewrites, use the `[--innodb-doublewrite](#-innodb-doublewrite)` option. 

 
```
$ mariabackup --backup \
     --skip-innodb-doublewrite

```

### `--skip-innodb-log-checksums`

 Defines whether to exclude checksums in the InnoDB logs.

 Mariabackup initializes its own embedded instance of InnoDB using the same configuration as defined in the configuration file. Using this option, you can set Mariabackup to exclude checksums in the InnoDB logs. The feature is enabled by default. To explicitly enable it, use the `[--innodb-log-checksums](#-innodb-log-checksums)` option.

 ### `--skip-secure-auth`

 Refuses client connections to servers using the older protocol.

 Using this option, you can set it accept client connections to the server when using the older protocol, from before 4.1.1. By default, it refuses these connections. Use the `[--secure-auth](#-secure-auth)` option to explicitly enable it.

 
```
$ mariabackup --backup --skip-secure-auth

```

### `--slave-info`

 Prints the binary log position and the name of the primary server.

 If the server is a [replica](../replication/index), then this option causes Mariabackup to print the hostname of the replica's replication primary and the [binary log](../binary-log/index) file and position of the [replica's SQL thread](../replication-threads/index#replica-sql-thread) to `stdout`.

 This option also causes Mariabackup to record this information as a [CHANGE MASTER](../change-master-to/index) command that can be used to set up a new server as a replica of the original server's primary after the backup has been restored. This information will be written to to the [xtrabackup\_slave\_info](../files-created-by-mariabackup/index#xtrabackup_slave_info) file.

 Mariabackup does **not** check if [GTIDs](../gtid/index) are being used in replication. It takes a shortcut and assumes that if the [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) system variable is non-empty, then it writes the [CHANGE MASTER](../change-master-to/index) command with the [MASTER\_USE\_GTID](../change-master-to/index#master_use_gtid) option set to `slave_pos`. Otherwise, it writes the [CHANGE MASTER](../change-master-to/index) command with the [MASTER\_LOG\_FILE](../change-master-to/index#master_log_file) and [MASTER\_LOG\_POS](../change-master-to/index#master_log_pos) options using the primary's [binary log](../binary-log/index) file and position. See [MDEV-19264](https://jira.mariadb.org/browse/MDEV-19264) for more information.

 
```
$ mariabackup --slave-info

```

### `-S, --socket`

 Defines the socket for connecting to local database.

 
```
--socket=name

```

Using this option, you can define the UNIX domain socket you want to use when connecting to a local database server. The option accepts a string argument. For more information, see the `mysql --help` command.

 
```
$ mariabackup --backup \
      --socket=/var/mysql/mysql.sock

```

### `--ssl`

 Enables [TLS](../data-in-transit-encryption/index). By using this option, you can explicitly configure Mariabackup to to encrypt its connection with [TLS](../data-in-transit-encryption/index) when communicating with the server. You may find this useful when performing backups in environments where security is extra important or when operating over an insecure network. 

 TLS is also enabled even without setting this option when certain other TLS options are set. For example, see the descriptions of the following options:

 * `[--ssl-ca](#-ssl-ca)`
* `[--ssl-capath](#-ssl-capath)`
* `[--ssl-cert](#-ssl-cert)`
* `[--ssl-cipher](#-ssl-cipher)`
* `[--ssl-key](#-ssl-key)`

 ### `--ssl-ca`

 Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-ca=/etc/my.cnf.d/certificates/ca.pem

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem 

```

See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. 

 This option implies the [--ssl](#-ssl) option.

 ### `--ssl-capath`

 Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-capath=/etc/my.cnf.d/certificates/ca/

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-capath=/etc/my.cnf.d/certificates/ca/

```

The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command.

 See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information

 This option implies the [--ssl](#-ssl) option.

 ### `--ssl-cert`

 Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem

```

This option implies the [--ssl](#-ssl) option.

 ### `--ssl-cipher`

 Defines the list of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). For example:

 
```
--ssl-cipher=name

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem
   --ssl-cipher=TLSv1.2

```

To determine if the server restricts clients to specific ciphers, check the [ssl\_cipher](../ssltls-system-variables/index#ssl_cipher) system variable.

 This option implies the [--ssl](#-ssl) option.

 ### `--ssl-crl`

 Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-crl=/etc/my.cnf.d/certificates/crl.pem

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-crl=/etc/my.cnf.d/certificates/crl.pem

```

See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.

 This option is only supported if Mariabackup was built with OpenSSL. If Mariabackup was built with yaSSL, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. 

 ### `--ssl-crlpath`

 Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-crlpath=/etc/my.cnf.d/certificates/crl/

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-crlpath=/etc/my.cnf.d/certificates/crl/ 

```

The directory specified by this option needs to be run through the [openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html) command.

 See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information.

 This option is only supported if Mariabackup was built with OpenSSL. If Mariabackup was built with yaSSL, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 ### `--ssl-key`

 Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. For example:

 
```
--ssl-key=/etc/my.cnf.d/certificates/client-key.pem

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem

```

This option implies the [--ssl](#-ssl) option.

 ### `--ssl-verify-server-cert`

 Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default.

 This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --ssl-verify-server-cert

```

### `--stream`

 Streams backup files to stdout.

 
```
--stream=xbstream

```

Using this command option, you can set Mariabackup to stream the backup files to stdout in the given format. Currently, the supported format is `xbstream`.

 
```
$ mariabackup --stream=xbstream > backup.xb

```

To extract all files from the xbstream archive into a directory use the `mbstream` utility

 
```
$ mbstream  -x < backup.xb

```

If a backup is streamed, then Mariabackup will record the format in the [xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info) file.

 ### `--tables`

 Defines the tables you want to include in the backup.

 
```
--tables=REGEX

```

Using this option, you can define what tables you want Mariabackup to back up from the database. The table values are defined using Regular Expressions. To define the tables you want to exclude from the backup, see the [--tables-exclude](#-tables-exclude) option.

 
```
$ mariabackup --backup \
     --databases=example
     --tables=nodes_* \
     --tables-exclude=nodes_tmp

```

If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the [xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info) file.

 ### `--tables-exclude`

 Defines the tables you want to exclude from the backup.

 
```
--tables-exclude=REGEX

```

Using this option, you can define what tables you want Mariabackup to exclude from the backup. The table values are defined using Regular Expressions. To define the tables you want to include from the backup, see the [--tables](#-tables) option.

 
```
$ mariabackup --backup \
     --databases=example
     --tables=nodes_* \
     --tables-exclude=nodes_tmp

```

If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the [xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info) file.

 ### `--tables-file`

 Defines path to file with tables for backups.

 
```
--tables-file=/path/to/file

```

Using this option, you can set a path to a file listing the tables you want to back up. Mariabackup iterates over each line in the file. The format is `database.table`.

 
```
$ mariabackup --backup \
     --databases=example \
     --tables-file=/etc/mysql/backup-file

```

If a backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then Mariabackup will record that detail in the [xtrabackup\_info](../files-created-by-mariabackup/index#xtrabackup_info) file.

 ### `--target-dir`

 Defines the destination directory.

 
```
--target-dir=/path/to/target

```

Using this option you can define the destination directory for the backup. Mariabackup writes all backup files to this directory. Mariabackup will create the directory, if it does not exist (but it will not create the full path recursively, i.e. at least parent directory if the --target-dir must exist=

 
```
$ mariabackup --backup \
       --target-dir=/data/backups

```

### `--throttle`

 Defines the limit for I/O operations per second in IOS values.

 
```
--throttle=#

```

Using this option, you can set a limit on the I/O operations Mariabackup performs per second in IOS values. It is only used during the [--backup](#-backup) command option.

 ### `--tls-version`

 This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. For example:

 
```
--tls-version="TLSv1.2,TLSv1.3"

```

This option is usually used with other TLS options. For example:

 
```
$ mariabackup --backup \
   --ssl-cert=/etc/my.cnf.d/certificates/client-cert.pem \
   --ssl-key=/etc/my.cnf.d/certificates/client-key.pem \
   --ssl-ca=/etc/my.cnf.d/certificates/ca.pem \
   --tls-version="TLSv1.2,TLSv1.3"

```

This option was added in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/).

 See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. 

 ### `-t, --tmpdir`

 Defines path for temporary files.

 
```
--tmpdir=/path/tmp[;/path/tmp...]

```

Using this option, you can define the path to a directory Mariabackup uses in writing temporary files. If you want to use more than one, separate the values by a semicolon (that is, `;`). When passing multiple temporary directories, it cycles through them using round-robin.

 
```
$ mariabackup --backup \
     --tmpdir=/data/tmp;/tmp

```

### `--use-memory`

 Defines the buffer pool size that is used during the prepare stage.

 
```
--use-memory=124M

```

Using this option, you can define the buffer pool size for Mariabackup. Use it instead of `buffer_pool_size`.

 
```
$ mariabackup --prepare \
      --use-memory=124M

```

### `--user`

 Defines the username for connecting to the MariaDB Server.

 
```
--user=name
-u name

```

When Mariabackup runs it connects to the specified MariaDB Server to get its backups. Using this option, you can define the database user uses for authentication.

 
```
$ mariabackup --backup \
      --user=root \
      --password=root_passwd

```

### `--version`

 Prints version information.

 Using this option, you can print the Mariabackup version information to stdout.

 
```
$ mariabackup --version

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariabackup-options/>

Configuring MariaDB Replication between Two MariaDB Galera Clusters
===================================================================

    [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index) can be used to replication between two [MariaDB Galera Clusters](../galera-cluster/index). This article will discuss how to do that.

 Configuring the Clusters
------------------------

 Before we set up replication, we need to ensure that the clusters are configured properly. This involves the following steps:

 * Set `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` on all nodes in both clusters. See [Configuring MariaDB Galera Cluster: Writing Replicated Write Sets to the Binary Log](../configuring-mariadb-galera-cluster/index#writing-replicated-write-sets-to-the-binary-log) and [Using MariaDB Replication with MariaDB Galera Cluster: Configuring a Cluster Node as a Replication Master](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#configuring-a-cluster-node-as-a-replication-master) for more information on why this is important. This is also needed to [enable wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#enabling-wsrep-gtid-mode).

 * Set `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` to the same value on all nodes in a given cluster, but be sure to use a different value in each cluster. See [Using MariaDB Replication with MariaDB Galera Cluster: Setting server\_id on Cluster Nodes](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#setting-server_id-on-cluster-nodes) for more information on what this means.

 ### Configuring Wsrep GTID Mode

 If you want to use [GTID](../gtid/index) replication, then you also need to configure some things to [enable wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#enabling-wsrep-gtid-mode). For example:

 * `[wsrep\_gtid\_mode=ON](../galera-cluster-system-variables/index#wsrep_gtid_mode)` needs to be set on all nodes in each cluster.

 * `[wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)` needs to be set to the same value on all nodes in a given cluster, so that each cluster node uses the same domain when assigning [GTIDs](../gtid/index) for Galera Cluster's write sets. Each cluster should have this set to a different value, so that each cluster uses different domains when assigning [GTIDs](../gtid/index) for their write sets.

 * `[log\_slave\_updates](../replication-and-binary-log-system-variables/index#log_slave_updates)` needs to be enabled on all nodes in the cluster. See [MDEV-9855](https://jira.mariadb.org/browse/MDEV-9855) about that.

 * `[log\_bin](../replication-and-binary-log-server-system-variables/index#log_bin)` needs to be set to the same path on all nodes in the cluster. See [MDEV-9856](https://jira.mariadb.org/browse/MDEV-9856) about that.

 And as an extra safety measure:

 * `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` should be set to a different value on all nodes in a given cluster, and each of these values should be different than the configured `[wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)` value. This is to prevent a node from using the same domain used for Galera Cluster's write sets when assigning [GTIDs](../gtid/index) for non-Galera transactions, such as DDL executed with `[wsrep\_sst\_method=RSU](../galera-cluster-system-variables/index#wsrep_sst_method)` set or DML executed with `[wsrep\_on=OFF](../galera-cluster-system-variables/index#wsrep_on)` set.

 Setting up Replication
----------------------

 Our process to set up replication is going to be similar to the process described at [Setting up a Replication Slave with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index), but it will be modified a bit to work in this context.

 ### Start the First Cluster

 The very first step is to start the nodes in the first cluster. The first node will have to be [bootstrapped](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster). The other nodes can be [started normally](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 Once the nodes are started, you need to pick a specific node that will act as the replication primary for the second cluster.

 ### Backup the Database on the First Cluster's Primary Node and Prepare It

 The first step is to simply take and prepare a fresh [full backup](../full-backup-and-restore-with-mariabackup/index) of the node that you have chosen to be the replication primary. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

And then you would prepare the backup as you normally would. For example:

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup/ 

```

### Copy the Backup to the Second Cluster's Replica

 Once the backup is done and prepared, you can copy it to the node in the second cluster that will be acting as replica. For example:

 
```
$ rsync -avrP /var/mariadb/backup c2dbserver:/var/mariadb/backup

```

### Restore the Backup on the Second Cluster's Replica

 At this point, you can restore the backup to the [datadir](../server-system-variables/index#datadir), as you normally would. For example:

 
```
$ mariabackup --copy-back \
   --target-dir=/var/mariadb/backup/

```

And adjusting file permissions, if necessary:

 
```
$ chown -R mysql:mysql /var/lib/mysql/

```

### Bootstrap the Second Cluster's Replica

 Now that the backup has been restored to the second cluster's replica, you can start the server by [bootstrapping](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster) the node.

 ### Create a Replication User on the First Cluster's Primary

 Before the second cluster's replica can begin replicating from the first cluster's primary, you need to [create a user account](../create-user/index) on the primary that the replica can use to connect, and you need to [grant](../grant/index) the user account the [REPLICATION SLAVE](../grant/index#global-privileges) privilege. For example:

 
```
CREATE USER 'repl'@'c2dbserver1' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'c2dbserver1';

```

### Start Replication on the Second Cluster's Replica

 At this point, you need to get the replication coordinates of the primary from the original backup.

 The coordinates will be in the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file.

 Mariabackup dumps replication coordinates in two forms: [GTID strings](../gtid/index) and [binary log](../binary-log/index) file and position coordinates, like the ones you would normally see from [SHOW MASTER STATUS](../show-master-status/index) output. In this case, it is probably better to use the [GTID](../gtid/index) coordinates.

 For example:

 
```
mariadb-bin.000096 568 0-1-2

```

Regardless of the coordinates you use, you will have to set up the primary connection using [CHANGE MASTER TO](../change-master-to/index) and then start the replication threads with [START SLAVE](../start-slave/index).

 #### GTIDs

 If you want to use GTIDs, then you will have to first set [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) to the [GTID](../gtid/index) coordinates that we pulled from the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file, and we would set `MASTER_USE_GTID=slave_pos` in the [CHANGE MASTER TO](../change-master-to/index) command. For example:

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO 
   MASTER_HOST="c1dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

#### File and Position

 If you want to use the [binary log](../binary-log/index) file and position coordinates, then you would set `MASTER_LOG_FILE` and `MASTER_LOG_POS` in the [CHANGE MASTER TO](../change-master-to/index) command to the file and position coordinates that we pulled the [xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info) file. For example:

 
```
CHANGE MASTER TO 
   MASTER_HOST="c1dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_LOG_FILE='mariadb-bin.000096',
   MASTER_LOG_POS=568,
START SLAVE;

```

### Check the Status of the Second Cluster's Replica

 You should be done setting up the replica now, so you should check its status with [SHOW SLAVE STATUS](../show-slave-status/index). For example:

 
```
SHOW SLAVE STATUS\G

```

### Start the Second Cluster

 If the replica is replicating normally, then the next step would be to [start the MariaDB Server process](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) on the other nodes in the second cluster.

 Now that the second cluster is up, ensure that it does not start accepting writes yet if you want to set up [circular replication](../replication-overview/index#ring-replication) between the two clusters.

 Setting up Circular Replication
-------------------------------

 You can also set up [circular replication](../replication-overview/index#ring-replication) between the two clusters, which means that the second cluster replicates from the first cluster, and the first cluster also replicates from the second cluster.

 ### Create a Replication User on the Second Cluster's Primary

 Before circular replication can begin, you also need to [create a user account](../create-user/index) on the second cluster's primary that the first cluster's replica can use to connect, and you need to [grant](../grant/index) the user account the [REPLICATION SLAVE](../grant/index#global-privileges) privilege. For example:

 
```
CREATE USER 'repl'@'c1dbserver1' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.*  TO 'repl'@'c1dbserver1';

```

### Start Circular Replication on the First Cluster

 How this is done would depend on whether you want to use the [GTID](../gtid/index) coordinates or the [binary log](../binary-log/index) file and position coordinates.

 Regardless, you need to ensure that the second cluster is not accepting any writes other than those that it replicates from the first cluster at this stage.

 #### GTIDs

 To get the GTID coordinates on the second cluster, you can check `[gtid\_current\_pos](../gtid/index#gtid_current_pos)` by executing:

 
```
SHOW GLOBAL VARIABLES LIKE 'gtid_current_pos';

```

Then on the first cluster, you can set up replication by setting [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) to the GTID that was returned and then executing [CHANGE MASTER TO](../change-master-to/index):

 
```
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO 
   MASTER_HOST="c2dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_USE_GTID=slave_pos;
START SLAVE;

```

#### File and Position

 To get the [binary log](../binary-log/index) file and position coordinates on the second cluster, you can execute [SHOW MASTER STATUS](../show-master-status/index):

 
```
SHOW MASTER STATUS

```

Then on the first cluster, you would set `master_log_file` and `master_log_pos` in the [CHANGE MASTER TO](../change-master-to/index) command. For example:

 
```
CHANGE MASTER TO 
   MASTER_HOST="c2dbserver1", 
   MASTER_PORT=3310, 
   MASTER_USER="repl",  
   MASTER_PASSWORD="password", 
   MASTER_LOG_FILE='mariadb-bin.000096',
   MASTER_LOG_POS=568;
START SLAVE;

```

### Check the Status of the Circular Replication

 You should be done setting up the circular replication on the node in the first cluster now, so you should check its status with [SHOW SLAVE STATUS](../show-slave-status/index). For example:

 
```
SHOW SLAVE STATUS\G

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-mariadb-replication-between-two-mariadb-galera-clusters/>

Files Created by Mariabackup
============================

    Mariabackup creates the following files:

 `backup-my.cnf`
---------------

 During the backup, any server options relevant to Mariabackup are written to the `backup-my.cnf` [option file](../configuring-mariadb-with-option-files/index), so that they can be re-read later during the `--prepare` stage.

 `ib_logfile0`
-------------

 In [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/) and later, Mariabackup creates an empty [InnoDB redo log](../xtradbinnodb-redo-log/index) file called `ib_logfile0` as part of the `[--prepare](../mariabackup-options/index#-prepare)` stage. This file has 3 roles:

 1. In the source server, `ib_logfile0` is the first (and possibly the only) [InnoDB redo log](../xtradbinnodb-redo-log/index) file.
2. In the non-prepared backup, `ib_logfile0` contains all of the [InnoDB redo log](../xtradbinnodb-redo-log/index) copied during the backup. Previous versions of Mariabackup would use a file called `[xtrabackup\_logfile](#xtrabackup_logfile)` for this.
3. During the `[--prepare](../mariabackup-options/index#-prepare)` stage, `ib_logfile0` would previously be deleted. Now during the `--prepare` stage, `ib_logfile0` is initialized as an empty [InnoDB redo log](../xtradbinnodb-redo-log/index) file. That way, if the backup is manually restored, any pre-existing [InnoDB redo log](../xtradbinnodb-redo-log/index) files would get overwritten by the empty one. This helps to prevent certain kinds of known issues. For example, see [Mariabackup Overview: Manual Restore with Pre-existing InnoDB Redo Log files](../mariabackup-overview/index#manual-restore-with-pre-existing-innodb-redo-log-files).

 `xtrabackup_logfile`
--------------------

 In [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and before, Mariabackup creates `xtrabackup_logfile` to store the [InnoDB redo log](../xtradbinnodb-redo-log/index), In later versions, `[ib\_logfile0](#ib_logfile0)` is created instead.

 `xtrabackup_binlog_info`
------------------------

 This file stores the [binary log](../binary-log/index) file name and position that corresponds to the backup.

 This file also stores the value of the `[gtid\_current\_pos](../gtid/index#gtid_current_pos)` system variable that correspond to the backup.

 For example:

 
```
mariadb-bin.000096 568 0-1-2

```

The values in this file are only guaranteed to be consistent with the backup if the `[--no-lock](../mariabackup-options/index#-no-lock)` option was **not** provided when the backup was taken.

 `xtrabackup_binlog_pos_innodb`
------------------------------

 Mariabackup inherited this file from Percona XtraBackup 2.3. However, this file is only safe to use with Percona Server versions that have a special lockless binary log feature.

 This feature is described by the [Percona Server documentation](https://www.percona.com/doc/percona-server/5.6/management/backup_locks.html#backup-safe-binlog-information):

 
Starting with Percona Server for MySQL 5.6.26-74.0 LOCK TABLES FOR BACKUP flushes the current binary log coordinates to InnoDB. Thus, under active LOCK TABLES FOR BACKUP, the binary log coordinates in InnoDB are consistent with its redo log and any non-transactional updates (as the latter are blocked by LOCK TABLES FOR BACKUP). It is planned that this change will enable Percona XtraBackup to avoid issuing the more invasive LOCK BINLOG FOR BACKUP command under some circumstances.

 
And the way it's used by Percona XtraBackup 2.3 is described by the [Percona XtraBackup 2.3 documentation](https://www.percona.com/doc/percona-xtrabackup/2.3/advanced/lockless_bin-log.html):

 
Percona XtraBackup implemented support for lock-less binary log information in 2.3.2. When the Lockless binary log information feature is available [1] on the server, Percona XtraBackup can trust binary log information stored in the InnoDB system header and avoid executing LOCK BINLOG FOR BACKUP (and thus, blocking commits for the duration of finalizing the REDO log copy) under a number of circumstances:

 * when the server is not a GTID-enabled Galera cluster node
* when the replication I/O thread information should not be stored as a part of the backup (i.e. when the xtrabackup --slave-info option is not specified)

 
Mariabackup no longer creates this file starting with [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/).

 See [MDEV-18917](https://jira.mariadb.org/browse/MDEV-18917) for more information.

 `xtrabackup_checkpoints`
------------------------

 The `xtrabackup_checkpoints` file contains metadata about the backup. 

 For example:

 
```
backup_type = full-backuped
from_lsn = 0
to_lsn = 1635102
last_lsn = 1635102
recover_binlog_info = 0

```

See below for a description of the fields.

 If the `[--extra-lsndir](../mariabackup-options/index#-extra-lsndir)` option is provided, then an extra copy of this file will be saved in that directory.

 ### `backup_type`

 If the backup is a non-prepared [full backup](../full-backup-and-restore-with-mariabackup/index) or a non-prepared [partial backup](../partial-backup-and-restore-with-mariabackup/index), then `backup_type` is set to `full-backuped`.

 If the backup is a non-prepared [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then `backup_type` is set to `incremental`.

 If the backup has already been prepared, then `backup_type` is set to `log-applied`.

 ### `from_lsn`

 If `backup_type` is `full-backuped`, then `from_lsn` has the value of `0`.

 If `backup_type` is `incremental`, then `from_lsn` has the value of the [log sequence number (LSN)](../innodb-redo-log/index#log-sequence-number-lsn) at which the backup started reading from the [InnoDB redo log](../innodb-redo-log/index). This is internally used by Mariabackup when preparing incremental backups.

 This value can be manually set during an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index) with the `[--incremental-lsn](../mariabackup-options/index#-incremental-lsn)` option. However, it is generally better to let Mariabackup figure out the `from_lsn` automatically by specifying a parent backup with the `[--incremental-basedir](../mariabackup-options/index#-incremental-basedir)` option.

 ### `to_lsn`

 `to_lsn` has the value of the [log sequence number (LSN)](../innodb-redo-log/index#log-sequence-number-lsn) of the last checkpoint in the [InnoDB redo log](../innodb-redo-log/index). This is internally used by Mariabackup when preparing incremental backups.

 ### `last_lsn`

 `last_lsn` has the value of the last [log sequence number (LSN)](../innodb-redo-log/index#log-sequence-number-lsn) read from the [InnoDB redo log](../innodb-redo-log/index). This is internally used by Mariabackup when preparing incremental backups.

 `xtrabackup_info`
-----------------

 The `xtrabackup_info` file contains information about the backup. The fields in this file are listed below.

 If the `[--extra-lsndir](../mariabackup-options/index#-extra-lsndir)` option is provided, then an extra copy of this file will be saved in that directory.

 ### `uuid`

 If a UUID was provided by the `[--incremental-history-uuid](../mariabackup-options/index#-incremental-history-uuid)` option, then it will be saved here. Otherwise, this will be the empty string.

 ### `name`

 If a name was provided by the `[--history](../mariabackup-options/index#-history)` or the `[---incremental-history-name](../mariabackup-options/index#-incremental-history-name)` options, then it will be saved here. Otherwise, this will be the empty string.

 ### `tool_name`

 The name of the Mariabackup executable that performed the backup. This is generally `mariabackup`.

 ### `tool_command`

 The arguments that were provided to Mariabackup when it performed the backup.

 ### `tool_version`

 The version of Mariabackup that performed the backup.

 ### `ibbackup_version`

 The version of Mariabackup that performed the backup.

 ### `server_version`

 The version of MariaDB Server that was backed up.

 ### `start_time`

 The time that the backup started.

 ### `end_time`

 The time that the backup ended.

 ### `lock_time`

 The amount of time that Mariabackup held its locks.

 ### `binlog_pos`

 This field stores the [binary log](../binary-log/index) file name and position that corresponds to the backup.

 This field also stores the value of the `[gtid\_current\_pos](../gtid/index#gtid_current_pos)` system variable that correspond to the backup.

 The values in this field are only guaranteed to be consistent with the backup if the `[--no-lock](../mariabackup-options/index#-no-lock)` option was **not** provided when the backup was taken.

 ### `innodb_from_lsn`

 This is identical to `from_lsn` in `[xtrabackup\_checkpoints](#xtrabackup_checkpoints)`.

 If the backup is a [full backup](../full-backup-and-restore-with-mariabackup/index), then `innodb_from_lsn` has the value of `0`.

 If the backup is an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then `innodb_from_lsn` has the value of the [log sequence number (LSN)](../innodb-redo-log/index#log-sequence-number-lsn) at which the backup started reading from the [InnoDB redo log](../innodb-redo-log/index).

 ### `innodb_to_lsn`

 This is identical to `to_lsn` in `[xtrabackup\_checkpoints](#xtrabackup_checkpoints)`.

 `innodb_to_lsn` has the value of the [log sequence number (LSN)](../innodb-redo-log/index#log-sequence-number-lsn) of the last checkpoint in the [InnoDB redo log](../innodb-redo-log/index).

 ### `partial`

 If the backup is a [partial backup](../partial-backup-and-restore-with-mariabackup/index), then this value will be `Y`.

 Otherwise, this value will be `N`.

 ### `incremental`

 If the backup is an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then this value will be `Y`.

 Otherwise, this value will be `N`.

 ### `format`

 This field's value is the format of the backup.

 If the `[--stream](../mariabackup-options/index#-stream)` option was set to `xbstream`, then this value will be `xbstream`.

 If the `[--stream](../mariabackup-options/index#-stream)` option was **not** provided, then this value will be `file`.

 ### `compressed`

 If the `[--compress](../mariabackup-options/index#-compress)` option was provided, then this value will be `compressed`.

 Otherwise, this value will be `N`.

 `xtrabackup_slave_info`
-----------------------

 If the `[--slave-info](../mariabackup-options/index#-slave-info)` option is provided, then this file contains the `[CHANGE MASTER](../change-master-to/index)` command that can be used to set up a new server as a slave of the original server's master after the backup has been restored.

 Mariabackup does **not** check if [GTIDs](../gtid/index) are being used in replication. It takes a shortcut and assumes that if the `[gtid\_slave\_pos](../gtid/index#gtid_slave_pos)` system variable is non-empty, then it writes the `[CHANGE MASTER](../change-master-to/index)` command with the `[MASTER\_USE\_GTID](../change-master-to/index#master_use_gtid)` option set to `slave_pos`. Otherwise, it writes the `[CHANGE MASTER](../change-master-to/index)` command with the `[MASTER\_LOG\_FILE](../change-master-to/index#master_log_file)` and `[MASTER\_LOG\_POS](../change-master-to/index#master_log_pos)` options using the master's [binary log](../binary-log/index) file and position. See [MDEV-19264](https://jira.mariadb.org/browse/MDEV-19264) for more information.

 `xtrabackup_galera_info`
------------------------

 If the `[--galera-info](../mariabackup-options/index#-galera-info)` option is provided, then this file contains information about a [Galera Cluster](../galera/index) node's state.

 The file contains the values of the `[wsrep\_local\_state\_uuid](../galera-cluster-status-variables/index#wsrep_local_state_uuid)` and `[wsrep\_last\_committed](../galera-cluster-status-variables/index#wsrep_last_committed)` status variables.

 The values are written in the following format:

 
```
wsrep_local_state_uuid:wsrep_last_committed

```

For example:

 
```
d38587ce-246c-11e5-bcce-6bbd0831cc0f:1352215

```

`<table>.delta`
---------------

 If the backup is an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then this file contains changed pages for the table.

 `<table>.delta.meta`
--------------------

 If the backup is an [incremental backup](../incremental-backup-and-restore-with-mariabackup/index), then this file contains metadata about `<table>.delta` files. The fields in this file are listed below.

 ### `page_size`

 This field contains either the value of `[innodb\_page\_size](../innodb-system-variables/index#innodb_page_size)` or the value of the `[KEY\_BLOCK\_SIZE](../create-table/index#key_block_size)` table option for the table if the `[ROW\_FORMAT](../create-table/index#row_format)` table option for the table is set to `[COMPRESSED](../innodb-storage-formats/index#compressed)`.

 ### `zip_size`

 If the `[ROW\_FORMAT](../create-table/index#row_format)` table option for this table is set to `[COMPRESSED](../innodb-storage-formats/index#compressed)`, then this field contains the value of the compressed page size.

 ### `space_id`

 This field contains the value of the table's `space_id`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/files-created-by-mariabackup/>

Mariabackup Overview
====================

    **Mariabackup** is an open source tool provided by MariaDB for performing physical online backups of [InnoDB](../innodb/index), [Aria](../aria/index) and [MyISAM](../myisam/index) tables. For InnoDB, “hot online” backups are possible. It was originally forked from [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) 2.3.8. It is available on Linux and Windows.

 Backup Support for MariaDB-Exclusive Features
---------------------------------------------

 [MariaDB 10.1](../what-is-mariadb-101/index) introduced features that are exclusive to MariaDB, such as [InnoDB Page Compression](innodb_compression) and [Data-at-Rest Encryption](../data-at-rest-encryption/index). These exclusive features have been very popular with MariaDB users. However, existing backup solutions from the MySQL ecosystem, such as [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index), did not support full backup capability for these features.

 To address the needs of our users, we decided to develop a backup solution that would fully support these popular MariaDB-exclusive features. We did this by creating Mariabackup, which is based on the well-known and commonly used backup tool called [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index). Mariabackup was originally extended from version 2.3.8. 

 ### Supported Features

 Mariabackup supports all of the main features of [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) 2.3.8, plus:

 * Backup/Restore of tables using [Data-at-Rest Encryption](../data-at-rest-encryption/index).
* Backup/Restore of tables using [InnoDB Page Compression](innodb_compression).
* [mariabackup SST method](../mariabackup-sst-method/index) with Galera Cluster.
* Microsoft Windows support.
* Backup/Restore of tables using the [MyRocks](../myrocks/index) storage engine starting with [MariaDB 10.2.16](https://mariadb.com/kb/en/mariadb-10216-release-notes/) and [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/). See [Files Backed up by Mariabackup: MyRocks Data Files](../files-backed-up-by-mariabackup/index#myrocks-data-files) for more information.

 #### Supported Features in MariaDB Enterprise Backup

 [MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/) supports some additional features, such as:

 * Minimizes locks during the backup to permit more concurrency and to enable faster backups.
	+ This relies on the usage of `[BACKUP STAGE](../backup-stage/index)` commands and DDL logging.
	+ This includes no locking during the copy phase of `[ALTER TABLE](../alter-table/index)` statements, which tends to be the longest phase of these statements.
* Provides optimal backup support for all storage engines that store things on local disk.

 ### Differences Compared to Percona XtraBackup

 * Percona XtraBackup copies its [InnoDB redo log](../xtradbinnodb-redo-log/index) files to the file `xtrabackup_logfile`, while Mariabackup uses the file `[ib\_logfile0](../files-created-by-mariabackup/index#ib_logfile0)`.

 * Percona XtraBackup's [libgcrypt-based encryption of backups](https://www.percona.com/doc/percona-xtrabackup/2.3/backup_scenarios/encrypted_backup.html) is not supported by Mariabackup.

 * There is no symbolic link from `mariabackup` to `[innobackupex](https://www.percona.com/doc/percona-xtrabackup/2.3/innobackupex/innobackupex_option_reference.html)`, as there is for `[xtrabackup](https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html)`. Instead, `mariabackup` has the `[--innobackupex](../mariabackup-options/index#-innobackupex)` command-line option to enable innobackupex-compatible options.

 * The `[--compact](https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html#cmdoption-xtrabackup-compact)` and `[--rebuild\_indexes](https://www.percona.com/doc/percona-xtrabackup/2.3/xtrabackup_bin/xbk_option_reference.html#cmdoption-xtrabackup-rebuild-indexes)` options are not supported.

 * Support for `[--stream=tar](https://www.percona.com/doc/percona-xtrabackup/2.3/howtos/recipes_ibkx_stream.html)` was removed from Mariabackup in [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/).

 * The `[xbstream](https://www.percona.com/doc/percona-xtrabackup/2.3/xbstream/xbstream.html)` utility has been renamed to `mbstream`. However, to select this output format when creating a backup, Mariabackup's `[--stream](../mariabackup-options/index#-stream)` option still expects the `xbstream` value.

 * Mariabackup does not support [lockless binlog](https://www.percona.com/doc/percona-xtrabackup/2.3/advanced/lockless_bin-log.html).

 #### Difference in Versioning Schemes

 Each Percona XtraBackup release has two version numbers--the Percona XtraBackup version number and the version number of the MySQL Server release that it is based on. For example:

 
```
xtrabackup version 2.2.8 based on MySQL server 5.6.22

```

Each Mariabackup release only has one version number, and it is the same as the version number of the MariaDB Server release that it is based on. For example:

 
```
mariabackup based on MariaDB server 10.2.15-MariaDB Linux (x86_64)

```

See [Compatibility of Mariabackup Releases with MariaDB Server Releases](#compatibility-of-mariabackup-releases-with-mariadb-server-releases) for more information on Mariabackup versions.

 Compatibility of Mariabackup Releases with MariaDB Server Releases
------------------------------------------------------------------

 
It is not generally possible, or supported, to prepare a backup in a different MariaDB version than the database version at the time when backup was taken. For example, if you backup [MariaDB 10.4](../what-is-mariadb-104/index), you should use mariabackup version 10.4, rather than e.g 10.5.

 
A MariaDB Server version can often be backed up with most other Mariabackup releases in the same release series. For example, [MariaDB 10.2.21](https://mariadb.com/kb/en/mariadb-10221-release-notes/) and [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/) are both in the [MariaDB 10.2](../what-is-mariadb-102/index) release series, so MariaDB Server from [MariaDB 10.2.21](https://mariadb.com/kb/en/mariadb-10221-release-notes/) could be backed up by Mariabackup from [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), or vice versa.

 However, occasionally, a MariaDB Server or Mariabackup release will include bug fixes that will break compatibility with previous releases. For example, the fix for [MDEV-13564](https://jira.mariadb.org/browse/MDEV-13564) changed the [InnoDB redo log](../innodb-redo-log/index) format in [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) which broke compatibility with previous releases. To be safest, a MariaDB Server release should generally be backed up with the Mariabackup release that has the same version number.

 
Mariabackup from [MariaDB 10.1](../what-is-mariadb-101/index) releases may also be able to back up MariaDB Server from [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.0](../what-is-mariadb-100/index) releases in many cases. However, this is not fully supported. See [MDEV-14936](https://jira.mariadb.org/browse/MDEV-14936) for more information.

 
Installing Mariabackup
----------------------

 ### Installing on Linux

 The `mariabackup` executable is included in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 #### Installing with a Package Manager

 Mariabackup can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 ##### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-backup

```

##### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 
```
sudo apt-get install mariadb-backup

```

##### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-backup

```

### Installing on Windows

 The `mariabackup` executable is included in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 When using the [Windows MSI installer](../installing-mariadb-msi-packages-on-windows/index), `mariabackup` can be installed by selecting *Backup utilities*:

 ![mariadb_backup_windows]

 Using Mariabackup
-----------------

 The command to use `mariabackup` and the general syntax is:

 
```
mariabackup <options>

```

For in-depth explanations on how to use Mariabackup, see:

 * [Full Backup and Restore with Mariabackup](../full-backup-and-restore-with-mariabackup/index)
* [Incremental Backup and Restore with Mariabackup](../incremental-backup-and-restore-with-mariabackup/index)
* [Partial Backup and Restore with Mariabackup](../partial-backup-and-restore-with-mariabackup/index)
* [Restoring Individual Tables and Partitions with Mariabackup](../restoring-individual-tables-and-partitions-with-mariabackup/index)
* [Setting up a Replication Slave with Mariabackup](../setting-up-a-replication-slave-with-mariabackup/index)
* [Using Encryption and Compression Tools With Mariabackup](../using-encryption-and-compression-tools-with-mariabackup/index)

 ### Options

 Options supported by Mariabackup can be found [here](../mariabackup-options/index).

 `mariabackup` will currently silently ignore unknown command-line options, so be extra careful about accidentally including typos in options or accidentally using options from later `mariabackup` versions. The reason for this is that `mariabackup` currently treats command-line options and options from [option files](../configuring-mariadb-with-option-files/index) equivalently. When it reads from these [option files](../configuring-mariadb-with-option-files/index), it has to read a lot of options from the [server option groups](#server-option-groups) read by `[mysqld](../mysqld-options/index)`. However, `mariabackup` does not know about many of the options that it normally reads in these option groups. If `mariabackup` raised an error or warning when it encountered an unknown option, then this process would generate a large amount of log messages under normal use. Therefore, `mariabackup` is designed to silently ignore the unknown options instead. See [MDEV-18215](https://jira.mariadb.org/browse/MDEV-18215) about that.

 ### Option Files

 In addition to reading options from the command-line, Mariabackup can also read options from [option files](../configuring-mariadb-with-option-files/index).

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--defaults-file=#`  | Only read default options from the given option file. |
| `--defaults-extra-file=#`  | Read this file after the global files are read. |
| `--defaults-group-suffix=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
#### Server Option Groups

 Mariabackup reads server options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mariabackup]` | Options read by Mariabackup. Available starting with [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/). |
| `[mariadb-backup]` | Options read by Mariabackup. Available starting with [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/). |
| `[xtrabackup]` | Options read by Mariabackup and [Percona XtraBackup](../percona-xtrabackup-overview/index). |
| `[server]` | Options read by MariaDB Server. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-10.4]`. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mariadb]` | Options read by MariaDB Server. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. For example, `[mariadb-10.4]`. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mariadbd]` | Options read by MariaDB Server. Available starting with [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/). |
| `[mariadbd-X.Y]` |  Options read by a specific version of MariaDB Server. For example, `[mariadbd-10.4]`. Available starting with [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/). |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[galera]` |  Options read by MariaDB Server, but only if it is compiled with [Galera Cluster](../galera/index) support. In [MariaDB 10.1](../what-is-mariadb-101/index) and later, all builds on Linux are compiled with [Galera Cluster](../galera/index) support. When using one of these builds, options from this option group are read even if the [Galera Cluster](../galera/index) functionality is not enabled. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) on systems compiled with [Galera Cluster](../galera/index) support. |

 
#### Client Option Groups

 Mariabackup reads client options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mariabackup]` | Options read by Mariabackup. Available starting with [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/). |
| `[mariadb-backup]` | Options read by Mariabackup. Available starting with [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/). |
| `[xtrabackup]` | Options read by Mariabackup and [Percona XtraBackup](../percona-xtrabackup-overview/index). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |

 
### Authentication and Privileges

 Mariabackup needs to authenticate with the database server when it performs a backup operation (i.e. when the `[--backup](../mariabackup-options/index#-backup)` option is specified). For most use cases, the user account that performs the backup needs to have the following [global privileges](../grant/index#global-privileges) on the database server.

 In 10.5 and later the required privileges are:

 
```
CREATE USER 'mariabackup'@'localhost' IDENTIFIED BY 'mypassword';
GRANT RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR ON *.* TO 'mariabackup'@'localhost';

```

Prior to 10.5, the required privileges are:

 
```
CREATE USER 'mariabackup'@'localhost' IDENTIFIED BY 'mypassword';
GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mariabackup'@'localhost';

```

If your database server is also using the [MyRocks](../myrocks/index) storage engine, then the user account that performs the backup will also need the `SUPER` [global privilege](../grant/index#global-privileges). This is because Mariabackup creates a checkpoint of this data by setting the `[rocksdb\_create\_checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint)` system variable, which requires this privilege. See [MDEV-20577](https://jira.mariadb.org/browse/MDEV-20577) for more information.

 To use the `[--history](../mariabackup-options/index#-history)` option, the backup user also needs to have the following privileges granted:

 
```
GRANT CREATE, INSERT ON mysql.* TO 'mariabackup'@'localhost';

```

Prior to [MariaDB 10.11](../what-is-mariadb-1011/index), the necessary permissions to use `[--history](../mariabackup-options/index#-history)` were:

 
```
GRANT CREATE, INSERT ON PERCONA_SCHEMA.* TO 'mariabackup'@'localhost';

```

If you're upgrading from an older version and you want to use the new default table without losing your backup history, you can move and rename the current table in this way:

 
```
RENAME TABLE PERCONA_SCHEMA.xtrabackup_history TO mysql.mariadb_backup_history;

```

The user account information can be specified with the `[--user](../mariabackup-options/index#-user)` and `[--password](../mariabackup-options/index#-p-password)` command-line options. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

The user account information can also be specified in a supported [client option group](#client-option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariabackup]
user=mariabackup
password=mypassword

```

Mariabackup does not need to authenticate with the database server when preparing or restoring a backup.

 ### File System Permissions

 Mariabackup has to read MariaDB's files from the file system. Therefore, when you run Mariabackup as a specific operating system user, you should ensure that user account has sufficient permissions to read those files.

 If you are using Linux and if you installed MariaDB with a package manager, then MariaDB's files will probably be owned by the `mysql` user and the `mysql` group.

 ### Using Mariabackup with Data-at-Rest Encryption

 Mariabackup supports [Data-at-Rest Encryption](../data-at-rest-encryption/index).

 Mariabackup will query the server to determine which [key management and encryption plugin](../encryption-key-management/index) is being used, and then it will load that plugin itself, which means that Mariabackup needs to be able to load the key management and encryption plugin's shared library.

 Mariabackup will also query the server to determine which [encryption keys](../encryption-key-management/index#using-multiple-encryption-keys) it needs to use.

 In other words, Mariabackup is able to figure out a lot of encryption-related information on its own, so normally one doesn't need to provide any extra options to backup or restore encrypted tables.

 Mariabackup backs up encrypted and unencrypted tables as they are on the original server. If a table is encrypted, then the table will remain encrypted in the backup. Similarly, if a table is unencrypted, then the table will remain unencrypted in the backup.

 The primary reason that Mariabackup needs to be able to encrypt and decrypt data is that it needs to apply [InnoDB redo log](../xtradbinnodb-redo-log/index) records to make the data consistent when the backup is prepared. As a consequence, Mariabackup does not perform many encryption or decryption operations when the backup is initially taken. MariaDB performs more encryption and decryption operations when the backup is prepared. This means that some encryption-related problems (such as using the wrong encryption keys) may not become apparent until the backup is prepared.

 ### Using Mariabackup for Galera SSTs

 The `mariabackup` SST method uses the [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) utility for performing SSTs. See [mariabackup SST method](../mariabackup-sst-method/index) for more information.

 Files Backed up by Mariabackup
------------------------------

 Mariabackup backs up many different files in order to perform its backup operation. See [Files Backed up by Mariabackup](../files-backed-up-by-mariabackup/index) for a list of these files.

 Files Created by Mariabackup
----------------------------

 Mariabackup creates several different types of files during the backup and prepare phases. See [Files Created by Mariabackup](../files-created-by-mariabackup/index) for a list of these files.

 Known Issues
------------

 ### Unsupported Server Option Groups

 Prior to [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), Mariabackup doesn't read server options from all [option groups](../configuring-mariadb-with-option-files/index#option-groups) supported by the server. In those versions, it only looks for server options in the following server option groups:

 


| Group | Description |
| --- | --- |
| `[xtrabackup]` | Options read by Percona XtraBackup and Mariabackup. |
| `[mariabackup]` | Options read by Percona XtraBackup and Mariabackup. Available starting with [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/). |
| `[mysqld]` |  Options read by `mysqld`, which includes both MariaDB Server and MySQL Server. |

 
Those versions do not read server options from the following option groups supported by the server:

 


| Group | Description |
| --- | --- |
| `[server]` | Options read by MariaDB Server. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mysqld-X.Y]` |  Options read by a specific version of `mysqld`, which includes both MariaDB Server and MySQL Server. For example, `[mysqld-5.5]` Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mariadb]` | Options read by MariaDB Server. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[mariadb-X.Y]` |  Options read by a specific version of MariaDB Server. For example, `[mariadb-10.3]` Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/). |
| `[galera]` |  Options read by MariaDB Server, but only if it is compiled with [Galera Cluster](../galera/index) support. In [MariaDB 10.1](../what-is-mariadb-101/index) and later, all builds on Linux are compiled with [Galera Cluster](../galera/index) support. When using one of these builds, options from this option group are read even if the [Galera Cluster](../galera/index) functionality is not enabled. Available starting with [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), and [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) on systems compiled with [Galera Cluster](../galera/index) support. |

 
See [MDEV-18347](https://jira.mariadb.org/browse/MDEV-18347) for more information.

 ### No Default Datadir

 Prior to [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10136-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), and [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), if you were performing a `[--copy-back](../mariabackup-options/index#-copy-back)` operation, and if you did not explicitly specify a value for the `[datadir](../mariabackup-options/index#datadir)` option either on the command line or one of the supported [server option groups](#server-option-group) in an [option file](../configuring-mariadb-with-option-files/index), then Mariabackup would not default to the server's default `datadir`. Instead, Mariabackup would fail with an error. For example:

 
```
Error: datadir must be specified.

```

The solution is to explicitly specify a value for the `[datadir](../mariabackup-options/index#datadir)` option either on the command line or in one of the supported [server option groups](#server-option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mysqld]
datadir=/var/lib/mysql

```

In [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10136-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), and [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) and later, Mariabackup will default to the server's default `[datadir](../server-system-variables/index#datadir)` value.

 See [MDEV-12956](https://jira.mariadb.org/browse/MDEV-12956) for more information.

 ### Concurrent DDL and Backup Issues

 Prior to [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), if concurrent DDL was executed while the backup was taken, then that could cause various kinds of problems to occur.

 One example is that if DDL caused any tablespace IDs to change (such as `[TRUNCATE TABLE](../truncate-table/index)` or `[RENAME TABLE](../rename-table/index)`), then that could cause the effected tables to be inconsistent in the backup. In this scenario, you might see errors about mismatched tablespace IDs when the backup is prepared.

 For example, the errors might look like this:

 
```
2018-12-07 07:49:32 7f51b3184820  InnoDB: Error: table 'DB1/TAB_TEMP'
InnoDB: in InnoDB data dictionary has tablespace id 1355633,
InnoDB: but a tablespace with that id does not exist. There is
InnoDB: a tablespace of name DB1/TAB_TEMP and id 1354713, though. Have
InnoDB: you deleted or moved .ibd files?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting-datadict.html
InnoDB: for how to resolve the issue.

```

Or they might look like this:

 
```
2018-07-12 21:24:14 139666981324672 [Note] InnoDB: Ignoring data file 'db1/tab1.ibd' with space ID 200485, since the redo log references db1/tab1.ibd with space ID 200484.

```

Some of the problems related to concurrent DDL are described below.

 Problems solved by setting `[--lock-ddl-per-table](../mariabackup-options/index#-lock-ddl-per-table)` (Mariabackup command-line option added in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/)):

 * If a table is dropped during the backup, then it might still exists after the backup is prepared.
* If a table exists when the backup starts, but it is dropped before the backup copies it, then the tablespace file can't be copied, so the backup would fail.

 Problems solved by setting `[innodb\_log\_optimize\_ddl=OFF](../innodb-system-variables/index#innodb_log_optimize_ddl)` (MariaDB Server system variable added in [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/) and removed in 10.6.0):

 * If the backup noticed concurrent DDL, then it might fail with "ALTER TABLE or OPTIMIZE TABLE was executed during backup".

 Problems solved by `[innodb\_safe\_truncate=ON](../innodb-system-variables/index#innodb_safe_truncate)` (MariaDB Server system variable in [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and removed in 10.3.0):

 * If a table is created during the backup, then it might not exist in the backup after prepare.
* If a table is renamed during the backup after the tablespace file was copied, then the table may not exist after the backup is prepared.
* If a table is dropped and created under the same name during the backup after the tablespace file was copied, then the table will have the wrong tablespace ID when the backup is prepared.

 Note that, with the removal of `innodb_log_optimize_ddl` and `innodb_safe_truncate`, the above problems were definitely solved.

 Problems solved by other bug fixes:

 * If `[--lock-ddl-per-table](../mariabackup-options/index#-lock-ddl-per-table)` is used and if a table is concurrently being dropped or renamed, then Mariabackup can fail to acquire the MDL lock.

 These problems are only fixed in [MariaDB 10.2](../what-is-mariadb-102/index) and later, so it is not recommended to execute concurrent DDL when using Mariabackup with [MariaDB 10.1](../what-is-mariadb-101/index).

 See [MDEV-13563](https://jira.mariadb.org/browse/MDEV-13563), [MDEV-13564](https://jira.mariadb.org/browse/MDEV-13564), [MDEV-16809](https://jira.mariadb.org/browse/MDEV-16809), and [MDEV-16791](https://jira.mariadb.org/browse/MDEV-16791) for more information.

 ### Manual Restore with Pre-existing InnoDB Redo Log files

 Prior to [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/), Mariabackup users could run into issues if they restored a backup by manually copying the files from the backup into the `[datadir](../server-system-variables/index#datadir)` while the directory still contained pre-existing [InnoDB redo log](../xtradbinnodb-redo-log/index) files. The backup itself did not contain [InnoDB redo log](../xtradbinnodb-redo-log/index) files with the traditional `ib_logfileN` file names, so the pre-existing log files would remain in the `[datadir](../server-system-variables/index#datadir)`. If the server were started with these pre-existing log files, then it could perform crash recovery with them, which could cause the database to become inconsistent or corrupt.

 In these MariaDB versions, this problem could be avoided by not restoring the backup by manually copying the files and instead restoring the backup by using Mariabackup and providing the `[--copy-back](../mariabackup-options/index#-copy-back)` option, since Mariabackup deletes pre-existing [InnoDB redo log](../xtradbinnodb-redo-log/index) files from the `[datadir](../server-system-variables/index#datadir)` during the restore process.

 In [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/) and later, Mariabackup prevents this issue by creating an empty [InnoDB redo log](../xtradbinnodb-redo-log/index) file called `[ib\_logfile0](../files-created-by-mariabackup/index#ib_logfile0)` as part of the `[--prepare](../mariabackup-options/index#-prepare)` stage. That way, if the backup is manually restored, any pre-existing [InnoDB redo log](../xtradbinnodb-redo-log/index) files would get overwritten by the empty one.

 See [MDEV-13311](https://jira.mariadb.org/browse/MDEV-13311) for more information.

 ### Too Many Open Files

 If Mariabackup uses more file descriptors than the system is configured to allow, then users can see errors like the following:

 
```
2019-02-12 09:48:38 7ffff7fdb820  InnoDB: Operating system error number 23 in a file operation.
InnoDB: Error number 23 means 'Too many open files in system'.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.6/en/operating-system-error-codes.html
InnoDB: Error: could not open single-table tablespace file ./db1/tab1.ibd
InnoDB: We do not continue the crash recovery, because the table may become
InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.
InnoDB: To fix the problem and start mysqld:
InnoDB: 1) If there is a permission problem in the file and mysqld cannot
InnoDB: open the file, you should modify the permissions.
InnoDB: 2) If the table is not needed, or you can restore it from a backup,
InnoDB: then you can remove the .ibd file, and InnoDB will do a normal
InnoDB: crash recovery and ignore that table.
InnoDB: 3) If the file system or the disk is broken, and you cannot remove
InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf
InnoDB: and force InnoDB to continue crash recovery here.

```

Prior to [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), and [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), Mariabackup would actually ignore the error and continue the backup. In some of those cases, Mariabackup would even report a successful completion of the backup to the user. In later versions, Mariabackup will properly throw an error and abort when this error is encountered. See [MDEV-19060](https://jira.mariadb.org/browse/MDEV-19060) for more information.

 When this error is encountered, one solution is to explicitly specify a value for the `[open-files-limit](../mariabackup-options/index#-open-files-limit)` option either on the command line or in one of the supported [server option groups](#server-option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariabackup]
open_files_limit=65535

```

An alternative solution is to set the soft and hard limits for the user account that runs Mariabackup by adding new limits to `[/etc/security/limits.conf](https://linux.die.net/man/5/limits.conf)`. For example, if Mariabackup is run by the `mysql` user, then you could add lines like the following:

 
```
mysql soft nofile 65535
mysql hard nofile 65535

```

After the system is rebooted, the above configuration should set new open file limits for the `mysql` user, and the user's `ulimit` output should look like the following:

 
```
$ ulimit -Sn
65535
$ ulimit -Hn
65535

```

Versions
--------

 


| Mariabackup/Server Version | Maturity |
| --- | --- |
| [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/)+, [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/)+ | Stable |
| [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/)+, [MariaDB 10.1.25](https://mariadb.com/kb/en/mariadb-10125-release-notes/) | Beta |
| [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/) | Alpha |

 
See Also
--------

 * [mariadb-dump/mysqldump](../mysqldump/index)
* [How to backup with MariaDB](https://www.youtube.com/watch?v=xB4ImmmzXqU) (video)
* [MariaDB point-in-time recovery](https://www.youtube.com/watch?v=ezHmnNmmcDo) (video)
* [Mariabackup and Restic](https://www.youtube.com/watch?v=b-KFj8GfvzE) (video)
* [MariaDB Enterprise backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/). An updated version of mariabackup.
* [Percona Xtrabackup 2.3 documentation](https://www.percona.com/doc/percona-xtrabackup/2.3/index.html/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariabackup-overview/>

Files Backed Up By Mariabackup
==============================

    Files Included in Backup
------------------------

 Mariabackup backs up the files listed below.

 ### InnoDB Data Files

 Mariabackup backs up the following InnoDB data files:

 * [InnoDB system tablespace](../innodb-system-tablespaces/index)
* [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index)

 ### MyRocks Data Files

 Starting with [MariaDB 10.2.16](https://mariadb.com/kb/en/mariadb-10216-release-notes/) and [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/), Mariabackup will back up tables that use the [MyRocks](../myrocks/index) storage engine. This data data is located in the directory defined by the `[rocksdb\_datadir](../myrocks-system-variables/index#rocksdb_datadir)` system variable. Mariabackup backs this data up by performing a checkpoint using the `[rocksdb\_create\_checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint)` system variable.

 Mariabackup does not currently support [partial backups](../partial-backup-and-restore-with-mariabackup/index) for MyRocks.

 ### Other Data Files

 Mariabackup also backs up files with the following extensions:

 * `frm`
* `isl`
* `MYD`
* `MYI`
* `MAD`
* `MAI`
* `MRG`
* `TRG`
* `TRN`
* `ARM`
* `ARZ`
* `CSM`
* `CSV`
* `opt`
* `par`

 Files Excluded From Backup
--------------------------

 Mariabackup does **not** back up the files listed below.

 * [InnoDB Temporary Tablespaces](../innodb-temporary-tablespaces/index)
* [Binary logs](../binary-log/index)
* [Relay logs](../relay-log/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/files-backed-up-by-mariabackup/>

Incremental Backup and Restore with Mariabackup
===============================================

     When using Mariabackup, you have the option of performing a full or incremental backup. Full backups create a complete copy in an empty directory while incremental backups update a previous backup with new data. This page documents incremental backups.

 InnoDB pages contain log sequence numbers, or LSN's. Whenever you modify a row on any InnoDB table on the database, the storage engine increments this number. When performing an incremental backup, Mariabackup checks the most recent LSN for the backup against the LSN's contained in the database. It then updates any of the backup files that have fallen behind.

 Backing up the Database Server
------------------------------

 In order to take an incremental backup, you first need to take a [full backup](../full-backup-and-restore-with-mariabackup/index). In order to back up the database, you need to run Mariabackup with the `[--backup](../mariabackup-options/index#-backup)` option to tell it to perform a backup and with the `[--target-dir](../mariabackup-options/index#-target-dir)` option to tell it where to place the backup files. When taking a full backup, the target directory must be empty or it must not exist.

 To take a backup, run the following command:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

This backs up all databases into the target directory `/var/mariadb/backup`. If you look in that directory at the `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` file, you can see the LSN data provided by InnoDB.

 For example:

 
```
backup_type = full-backuped
from_lsn = 0
to_lsn = 1635102
last_lsn = 1635102
recover_binlog_info = 0

```

Backing up the Incremental Changes
----------------------------------

 Once you have created a full backup on your system, you can also back up the incremental changes as often as you would like.

 In order to perform an incremental backup, you need to run Mariabackup with the `[--backup](../mariabackup-options/index#-backup)` option to tell it to perform a backup and with the `[--target-dir](../mariabackup-options/index#-target-dir)` option to tell it where to place the incremental changes. The target directory must be empty. You also need to run it with the `[--incremental-basedir](../mariabackup-options/index#-incremental-basedir)` option to tell it the path to the full backup taken above. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/inc1/ \
   --incremental-basedir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

This command creates a series of delta files that store the incremental changes in `/var/mariadb/inc1`. You can find a similar `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` file in this directory, with the updated LSN values.

 For example:

 
```
backup_type = incremental
from_lsn = 1635102
to_lsn = 1635114
last_lsn = 1635114
recover_binlog_info = 0

```

To perform additional incremental backups, you can then use the target directory of the previous incremental backup as the incremental base directory of the next incremental backup. For example:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/inc2/ \
   --incremental-basedir=/var/mariadb/inc1/ \
   --user=mariabackup --password=mypassword

```

Combining with `--stream` output
--------------------------------

 When using `[--stream](../mariabackup-options/index#-stream)`, e.g for [compression or encryption using external tools](../using-encryption-and-compression-tools-with-mariabackup/index), the `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` file containing the information where to continue from on the next incremental backup will also be part of the compressed/encrypted backup file, and so not directly accessible by default.

 A directory containing an extra copy of the file can be created using the `[--extra-lsndir=...](../mariabackup-options/index#-extra-lsndir)` option though, and this directory can then be passed to the next incremental backup `[--incremental-basedir=...](../mariabackup-options/index#-incremental-basedir)`, for example:

 
```
# initial full backup
$ mariabackup --backup --stream=mbstream \
  --user=mariabackup --password=mypassword \
  --extra-lsndir=backup_base | gzip > backup_base.gz

# incremental backup
$ mariabackup --backup --stream=mbstream \
  --incremental-basedir=backup_base \
  --user=mariabackup --password=mypassword \
  --extra-lsndir=backup_inc1 | gzip > backup-inc1.gz 

```

Preparing the Backup
--------------------

 Following the above steps, you have three backups in `/var/mariadb`: The first is a full backup, the others are increments on this first backup. In order to restore a backup to the database, you first need to apply the incremental backups to the base full backup. This is done using the `[--prepare](../mariabackup-options/index#-prepare)` command option. In [MariaDB 10.1](../what-is-mariadb-101/index), you would also have to use the the `[--apply-log-only](../mariabackup-options/index#-apply-log-only)` option.

 
**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and later, perform the following process:

 First, prepare the base backup:

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup

```

Running this command brings the base full backup, that is, `/var/mariadb/backup`, into sync with the changes contained in the [InnoDB redo log](../innodb-redo-log/index) collected while the backup was taken.

 Then, apply the incremental changes to the base full backup:

 
```
$ mariabackup --prepare \
   --target-dir=/var/mariadb/backup \
   --incremental-dir=/var/mariadb/inc1

```

Running this command brings the base full backup, that is, `/var/mariadb/backup`, into sync with the changes contained in the first incremental backup.

 For each remaining incremental backup, repeat the last step to bring the base full backup into sync with the changes contained in that incremental backup.

 

**MariaDB until [10.1](../what-is-mariadb-101/index)**In [MariaDB 10.1](../what-is-mariadb-101/index), perform the following process:

 First, prepare the base backup:

 
```
$ mariabackup --prepare --apply-log-only \
   --target-dir=/var/mariadb/backup

```

Running this command brings the base full backup, that is, `/var/mariadb/backup`, into sync with the changes contained in the [InnoDB redo log](../innodb-redo-log/index) collected while the backup was taken.

 Then, apply the incremental changes to the base full backup:

 
```
$ mariabackup --prepare --apply-log-only \
   --target-dir=/var/mariadb/backup \
   --incremental-dir=/var/mariadb/inc1

```

Running this command brings the base full backup, that is, `/var/mariadb/backup`, into sync with the changes contained in the first incremental backup.

 For each remaining incremental backup, repeat the last step to bring the base full backup into sync with the changes contained in that incremental backup.

 
Restoring the Backup
--------------------

 Once you've applied all incremental backups to the base, you can restore the backup using either the `[--copy-back](../mariabackup-options/index#-copy-back)` or the `[--move-back](../mariabackup-options/index#-move-back)` options. The `[--copy-back](../mariabackup-options/index#-copy-back)` option allows you to keep the original backup files. The `[--move-back](../mariabackup-options/index#-move-back)` option actually moves the backup files to the `[datadir](../server-system-variables/index#datadir)`, so the original backup files are lost.

 * First, [stop the MariaDB Server process](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 * Then, ensure that the `[datadir](../server-system-variables/index#datadir)` is empty.

 * Then, run Mariabackup with one of the options mentioned above:

 
```
$ mariabackup --copy-back \
   --target-dir=/var/mariadb/backup/

```

* Then, you may need to fix the file permissions.

 When Mariabackup restores a database, it preserves the file and directory privileges of the backup. However, it writes the files to disk as the user and group restoring the database. As such, after restoring a backup, you may need to adjust the owner of the data directory to match the user and group for the MariaDB Server, typically `mysql` for both. For example, to recursively change ownership of the files to the `mysql` user and group, you could execute:

 
```
$ chown -R mysql:mysql /var/lib/mysql/

```

* Finally, [start the MariaDB Server process](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/incremental-backup-and-restore-with-mariabackup/>

Partial Backup and Restore with Mariabackup
===========================================

    When using Mariabackup, you have the option of performing partial backups. Partial backups allow you to choose which databases or tables to backup, as long as the table or partition involved is in an [InnoDB file-per-table tablespace](../innodb-file-per-table-tablespaces/index).This page documents how to perform partial backups.

 Backing up the Database Server
------------------------------

 Just like with [full backups](../full-backup-and-restore-with-mariabackup/index), in order to back up the database, you need to run Mariabackup with the `[--backup](../mariabackup-options/index#-backup)` option to tell it to perform a backup and with the `[--target-dir](../mariabackup-options/index#-target-dir)` option to tell it where to place the backup files. The target directory must be empty or not exist.

 For a partial backup, there are a few other arguments that you can provide as well:

 * To tell it which databases to backup, you can provide the `[--databases](../mariabackup-options/index#-databases)` option.
* To tell it which databases to exclude from the backup, you can provide the `[--databases-exclude](../mariabackup-options/index#-databases-exclude)` option.
* To tell it to check a file for the databases to backup, you can provide the `[--databases-file](../mariabackup-options/index#-databases-file)` option.
* To tell it which tables to backup, you can use the `[--tables](../mariabackup-options/index#-tables)` option.
* To tell it which tables to exclude from the backup, you can provide the `[--tables-exclude](../mariabackup-options/index#-tables-exclude)` option.
* To tell it to check a file for specific tables to backup, you can provide the `[--tables-file](../mariabackup-options/index#-tables-file)` option.

 The non-file partial backup options support regex in the database and table names.

 For example, to take a backup of any database that starts with the string `app1_` and any table in those databases that start with the string `tab_`, run the following command:

 
```
$ mariabackup --backup \
   --target-dir=/var/mariadb/backup/ \
   --databases='app1_*' --tables='tab_*' \
   --user=mariabackup --password=mypassword

```


Mariabackup cannot currently backup a subset of partitions from a partitioned table. Backing up a partitioned table is currently an all-or-nothing selection. See [MDEV-17132](https://jira.mariadb.org/browse/MDEV-17132) about that. If you need to backup a subset of partitions, then one possibility is that instead of using Mariabackup, you can [export the file-per-table tablespaces of the partitions](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces).

 
The time the backup takes depends on the size of the databases or tables you're backing up. You can cancel the backup if you need to, as the backup process does not modify the database.

 Mariabackup writes the backup files the target directory. If the target directory doesn't exist, then it creates it. If the target directory exists and contains files, then it raises an error and aborts.

 Preparing the Backup
--------------------

 Just like with [full backups](../full-backup-and-restore-with-mariabackup/index), the data files that Mariabackup creates in the target directory are not point-in-time consistent, given that the data files are copied at different times during the backup operation. If you try to restore from these files, InnoDB notices the inconsistencies and crashes to protect you from corruption. In fact, for partial backups, the backup is not even a completely functional MariaDB data directory, so InnoDB would raise more errors than it would for full backups. This point will also be very important to keep in mind during the restore process.

 Before you can restore from a backup, you first need to **prepare** it to make the data files consistent. You can do so with the `[--prepare](../mariabackup-options/index#-prepare)` command option.

 Partial backups rely on [InnoDB's transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces). For MariaDB to import tablespaces like these, [InnoDB](../xtradb-and-innodb/index) looks for a file with a `.cfg` extension. For Mariabackup to create these files, you also need to add the `[--export](../mariabackup-options/index#-export)` option during the prepare step.

 For example, you might execute the following command:

 
```
$ mariabackup --prepare --export \
   --target-dir=/var/mariadb/backup/

```

If this operation completes without error, then the backup is ready to be restored.

 
**MariaDB until [10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)**In [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/) and before, Mariabackup did not support the `[--export](../mariabackup-options/index#-export)` option. See [MDEV-13466](https://jira.mariadb.org/browse/MDEV-13466) about that. In these versions of MariaDB, this means that Mariabackup could not create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index) during the `--prepare` stage. You can still [import file-per-table tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) without the `.cfg` files in many cases, so it may still be possible in those versions to [restore partial backups](index) or to [restore individual tables and partitions](../restoring-individual-tables-and-partitions-with-mariabackup/index) with just the `.ibd` files. If you have a [full backup](../full-backup-and-restore-with-mariabackup/index) and you need to create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index), then you can do so by preparing the backup as usual without the `--export` option, and then restoring the backup, and then starting the server. At that point, you can use the server's built-in features to [copy the transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces).

 
Restoring the Backup
--------------------

 The restore process for partial backups is quite different than the process for [full backups](../full-backup-and-restore-with-mariabackup/index). A partial backup is not a completely functional data directory. The data dictionary in the [InnoDB system tablespace](../innodb-system-tablespaces/index) will still contain entries for the databases and tables that were not included in the backup.

 Rather than using the `[--copy-back](../mariabackup-options/index#-copy-back)` or the `[--move-back](../mariabackup-options/index#-move-back)`, each individual [InnoDB file-per-table tablespace](../innodb-file-per-table-tablespaces/index) file will have to be manually imported into the target server. The process that is used to import the file will depend on whether partitioning is involved.

 ### Restoring Individual Non-Partitioned Tables

 To restore individual non-partitioned tables from a backup, find the `.ibd` and `.cfg` files for the table in the backup, and then import them using the [Importing Transportable Tablespaces for Non-partitioned Tables](../innodb-file-per-table-tablespaces/index#importing-transportable-tablespaces-for-non-partitioned-tables) process.

 ### Restoring Individual Partitions and Partitioned Tables

 To restore individual partitions or partitioned tables from a backup, find the `.ibd` and `.cfg` files for the partition(s) in the backup, and then import them using the [Importing Transportable Tablespaces for Partitioned Tables](../innodb-file-per-table-tablespaces/index#importing-transportable-tablespaces-for-partitioned-tables) process.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/partial-backup-and-restore-with-mariabackup/>

Using Encryption and Compression Tools With Mariabackup
=======================================================

     [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) supports streaming to stdout with the `--stream=xbstream` option. This option allows easy integration with popular encryption and compression tools. Below are several examples.

 Encrypting and Decrypting Backup With openssl
---------------------------------------------

 The following example creates an AES-encrypted backup, protected with the password "mypass" and stores it in a file "backup.xb.enc":   
  
  


 
```
mariabackup --user=root --backup --stream=xbstream  | openssl  enc -aes-256-cbc -k mypass > backup.xb.enc

```

To decrypt and unpack this backup into the current directory, the following command can be used:

 
```
openssl  enc -d -aes-256-cbc -k mypass -in backup.xb.enc | mbstream -x

```

Compressing and Decompressing Backup With gzip
----------------------------------------------

 This example compresses the backup without encrypting:

 
```
mariabackup --user=root --backup --stream=xbstream | gzip > backupstream.gz

```

We can decompress and unpack the backup as follows:

 
```
gunzip -c backupstream.gz | mbstream -x

```

Compressing and Encrypting Backup, Using gzip and openssl
---------------------------------------------------------

 This example adds a compression step before the encryption, otherwise looks almost identical to the previous example:

 
```
mariabackup --user=root --backup --stream=xbstream | gzip | openssl  enc -aes-256-cbc -k mypass > backup.xb.gz.enc

```

We can decrypt, decompress and unpack the backup as follow (note `gzip -d` in the pipeline):

 
```
openssl  enc -d -aes-256-cbc -k mypass -in backup.xb.gz.enc |gzip -d| mbstream -x

```

Compressing and Encrypting with 7Zip
------------------------------------

 7zip archiver is a popular utility (especially on Windows) that supports reading from standard output, with the -`-si` option, and writing to stdout with the `-so` option, and can thus be used together with Mariabackup.

 Compressing backup with the 7z command line utility works as follows:

 
```
mariabackup --user=root --backup --stream=xbstream | 7z a -si backup.xb.7z

```

Uncompress and unpack the archive with 

 
```
7z e backup.xb.7z -so |mbstream -x

```

7z also has builtin AES-256 encryption. To encrypt the backup from the previous example using password SECRET, add `-pSECRET` to the 7z command line.

 Encrypting With GPG
-------------------

 Encryption

 
```
mariabackup --user=root --backup --stream=xbstream | gpg -c --passphrase SECRET --batch --yes -o backup.xb.gpg

```

Decrypt, unpack

 
```
gpg --decrypt --passphrase SECRET --batch --yes  backup.xb.gpg | mbstream -x

```

Interactive Input for Passphrases
---------------------------------

 Most of the described tools also provide a way to enter a passphrase interactively (although 7zip does not seem to work well when reading input from stdin). Please consult documentation of the tools for more info.

 Writing extra status files
--------------------------

 By default files like `[xtrabackup\_checkpoints](../files-created-by-mariabackup/index#xtrabackup_checkpoints)` are also written to the output stream only, and so would not be available for taking further incremental backups without prior extraction from the compressed or encrypted stream output file.

 To avoid this these files can additionally be written to a directory that can then be used as input for further incremental backups using the `[--extra-lsndir=...](../mariabackup-options/index#-extra-lsndir)` option.

 See also e.g: [Combining incremental backups with streaming output](../incremental-backup-and-restore-with-mariabackup/index#combining-with-stream-output)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-encryption-and-compression-tools-with-mariabackup/>

How Mariabackup Works
=====================

     This is a description of the different stages in Mariabackup, what they do and why they are needed.

 Note that a few items are marked with `TODO`; these are things we are working on and will be in next version of Mariabackup.

 Execution Stages
----------------

 ### Initialization Phase

 * Connect to mysqld instance, find out important variables (datadir ,InnoDB pagesize, encryption keys, encryption plugin etc)
* Scan the database directory, `datadir`, looking for InnoDB tablespaces, load the tablespaces (basically, it is an “open” in InnoDB sense)
* If --lock-ddl-per-table is used:
	+ Do MDL locks, for InnoDB tablespaces that we want to copy. This is to ensure that there are no ALTER, RENAME , TRUNCATE or DROP TABLE on any of the tables that we want to copy.
	+ This is implemented with:

 
```
BEGIN
For each affected table
SELECT 1 from <table> LIMIT 0

```

* If lock-ddl-per-table is not done, then Mariabackup would have to know all tables that were created or altered during the backup. See [MDEV-16791](https://jira.mariadb.org/browse/MDEV-16791).

 ### Redo Log Handling

 Start a dedicated thread in Mariabackup to copy InnoDB redo log (`ib_logfile*`).

 * This is needed to record all changes done while the backup is running. (The redo log logically is a single circular file, split into [innodb\_log\_files\_in\_group](../xtradbinnodb-server-system-variables/index#innodb_log_files_in_group) files.)
* The log is also used to see detect if any truncate or online alter tables are used.
* The assumption is that the copy thread will be able to keep up with server. It should always be able keep up, if the redo log is big enough.

 ### Copy-phase for InnoDB Tablespaces

 * Copy all selected tablespaces, file by file, in dedicated threads in Mariabackup without involving the mysqld server.
* This is special “careful” copy, it looks for page-level consistency by checking the checksum.
* The files are not point-in-time consistent as data may change during copy.
* The idea is that InnoDB recovery would make it point-in-time consistent.
* Copy Aria log files (TODO)

 ### Create a Consistent Backup Point

 * Execute [FLUSH TABLE WITH READ LOCK](../flush/index). This is default, but may be omitted with the `-–no-lock` parameter. The reason why `FLUSH` is needed is to ensure that all tables are in a consistent state at the exact same point in time, independent of storage engine.
* If `--lock-ddl-per-table` is used and there is a user query waiting for MDL, the user query will be killed to resolve a deadlock. Note that these are only queries of type ALTER, DROP, TRUNCATE or RENAME TABLE. ([MDEV-15636](https://jira.mariadb.org/browse/MDEV-15636))

 ### Last Copy Phase

 * Copy `.frm`, `MyISAM`, `Aria` and other storage engine files
* If `MyRocks` is used, create rocksdb checkpoint via "set rocksdb\_create\_checkpoint=$rocksdb\_data\_dir/mariabackup\_rocksdb\_checkpoint " command. The result of it is a directory with hardlinks to MyRocks files. Copy the checkpoint directory to the backup (or create hardlinks in backup directory is on the same partition as data directory). Remove the checkpoint directory.
* Copy tables that were created while the backup was running and do rename files that were changed during backup (since [MDEV-16791](https://jira.mariadb.org/browse/MDEV-16791))
* Copy the rest of InnoDB redo log, stop redo-log-copy thread
* Copy changes to Aria log files (They are append only, so this is easy to do) (TODO)
* Write some metadata info (binlog position)

 ### Release Locks

 * If [FLUSH TABLE WITH READ LOCK](../flush/index) was done:
	+ execute: `UNLOCK TABLES`
* If `--lock-ddl-per-table` was done:
	+ execute `COMMIT`

 ### Handle Log Tables (TODO)

 * If log tables exists:
	+ Take MDL lock for log tables
	+ Copy part of log tables that wasn't copied before
	+ Unlock log tables

 Notes
-----

 * If [FLUSH TABLE WITH READ LOCK](../flush/index) is not used, then only InnoDB tables will be consistent (not the privilege tables in the mysql database or the binary log). The backup point depends on the content of the redo log within the backup itself.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-mariabackup-works/>

Mariabackup and BACKUP STAGE Commands
=====================================

    
**MariaDB starting with [10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)**The `[BACKUP STAGE](../backup-stage/index)` commands were introduced in [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).

  The `[BACKUP STAGE](../backup-stage/index)` commands are a set of commands to make it possible to make an efficient external backup tool. How Mariabackup uses these commands depends on whether you are using the version that is bundled with MariaDB Community Server or the version that is bundled with [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/).

 Mariabackup and `BACKUP STAGE` Commands in MariaDB Community Server
-------------------------------------------------------------------

 
**MariaDB starting with [10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)**In MariaDB Community Server, Mariabackup first supported `[BACKUP STAGE](../backup-stage/index)` commands in [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).

 
In [MariaDB 10.3](../what-is-mariadb-103/index) and before, the `[BACKUP STAGE](../backup-stage/index)` commands are **not** supported, so Mariabackup executes the `[FLUSH TABLES WITH READ LOCK](../flush/index)` command to lock the database. When the backup is complete, it executes the `[UNLOCK TABLES](../transactions-unlock-tables/index)` command to unlock the database.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the `[BACKUP STAGE](../backup-stage/index)` commands are supported. However, the version of Mariabackup that is bundled with MariaDB Community Server does not yet use the `[BACKUP STAGE](../backup-stage/index)` commands in the most efficient way. Mariabackup simply executes the following `[BACKUP STAGE](../backup-stage/index)` commands to lock the database:

 
```
BACKUP STAGE START;
BACKUP STAGE BLOCK_COMMIT;

```

When the backup is complete, it executes the following `[BACKUP STAGE](../backup-stage/index)` command to unlock the database:

 
```
BACKUP STAGE END;

```


If you would like to use a version of Mariabackup that uses the `[BACKUP STAGE](../backup-stage/index)` commands in the most efficient way, then your best option is to use [MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/) that is bundled with [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/).

 
### Tasks Performed Prior to `BACKUP STAGE` in MariaDB Community Server

 * Copy some transactional tables.
	+ [InnoDB](../innodb/index) (i.e. `ibdataN` and file extensions `.ibd` and `.isl`)
* Copy the tail of some transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.

 ### 
`BACKUP STAGE START` in MariaDB Community Server

 Mariabackup from MariaDB Community Server does not currently perform any tasks in the `START` stage.

 ### 
`BACKUP STAGE FLUSH` in MariaDB Community Server

 Mariabackup from MariaDB Community Server does not currently perform any tasks in the `FLUSH` stage.

 ### 
`BACKUP STAGE BLOCK_DDL` in MariaDB Community Server

 Mariabackup from MariaDB Community Server does not currently perform any tasks in the `BLOCK_DDL` stage.

 ### 
`BACKUP STAGE BLOCK_COMMIT` in MariaDB Community Server

 Mariabackup from MariaDB Community Server performs the following tasks in the `BLOCK_COMMIT` stage:

 * Copy other files.
	+ i.e. file extensions `.frm`, `.isl`, `.TRG`, `.TRN`, `.opt`, `.par`
* Copy some transactional tables.
	+ [Aria](../aria/index) (i.e. `aria_log_control` and file extensions `.MAD` and `.MAI`)
* Copy the non-transactional tables.
	+ [MyISAM](../myisam/index) (i.e. file extensions `.MYD` and `.MYI`)
	+ [MERGE](../merge/index) (i.e. file extensions `.MRG`)
	+ [ARCHIVE](../archive/index) (i.e. file extensions `.ARM` and `.ARZ`)
	+ [CSV](../csv/index) (i.e. file extensions `.CSM` and `.CSV`)
* Create a [MyRocks](../myrocks/index) checkpoint using the `[rocksdb\_create\_checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint)` system variable.
* Copy the tail of some transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.
* Save the [binary log](../binary-log/index) position to `[xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info)`.
* Save the [Galera Cluster](../galera/index) state information to `[xtrabackup\_galera\_info](../files-created-by-mariabackup/index#xtrabackup_galera_info)`.

 ### 
`BACKUP STAGE END` in MariaDB Community Server

 Mariabackup from MariaDB Community Server performs the following tasks in the `END` stage:

 * Copy the [MyRocks](../myrocks/index) checkpoint into the backup.

 Mariabackup and `BACKUP STAGE` Commands in MariaDB Enterprise Server
--------------------------------------------------------------------

 
**MariaDB starting with [10.2.25](https://mariadb.com/kb/en/mariadb-10225-release-notes/)**[MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/) first supported `[BACKUP STAGE](../backup-stage/index)` commands in [MariaDB Enterprise Server 10.4.6-1](https://mariadb.com/docs/appendix/release-notes/mariadb-enterprise-server-10-4-6-1-release-notes/), [MariaDB Enterprise Server 10.3.16-1](https://mariadb.com/docs/appendix/release-notes/mariadb-enterprise-server-10-3-16-1-release-notes/), and [MariaDB Enterprise Server 10.2.25-1](https://mariadb.com/docs/appendix/release-notes/mariadb-enterprise-server-10-2-25-1-release-notes/).

 
The following sections describe how the [MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/) version of Mariabackup that is bundled with [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/) uses each `[BACKUP STAGE](../backup-stage/index)` command in an efficient way.

 ### 
`BACKUP STAGE START` in MariaDB Enterprise Server

 Mariabackup from MariaDB Enterprise Server performs the following tasks in the `START` stage:

 * Copy all transactional tables.
	+ [InnoDB](../innodb/index) (i.e. `ibdataN` and file extensions `.ibd` and `.isl`)
	+ [Aria](../aria/index) (i.e. `aria_log_control` and file extensions `.MAD` and `.MAI`)
* Copy the tail of all transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.
	+ The tail of the Aria redo log (i.e. `aria_log.N` files) will be copied for [Aria](../aria/index) tables.

 ### 
`BACKUP STAGE FLUSH` in MariaDB Enterprise Server

 Mariabackup from MariaDB Enterprise Server performs the following tasks in the `FLUSH` stage:

 * Copy all non-transactional tables that are not in use. This list of used tables is found with `[SHOW OPEN TABLES](../show-open-tables/index)`.
	+ [MyISAM](../myisam/index) (i.e. file extensions `.MYD` and `.MYI`)
	+ [MERGE](../merge/index) (i.e. file extensions `.MRG`)
	+ [ARCHIVE](../archive/index) (i.e. file extensions `.ARM` and `.ARZ`)
	+ [CSV](../csv/index) (i.e. file extensions `.CSM` and `.CSV`)
* Copy the tail of all transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.
	+ The tail of the Aria redo log (i.e. `aria_log.N` files) will be copied for [Aria](../aria/index) tables.

 ### 
`BACKUP STAGE BLOCK_DDL` in MariaDB Enterprise Server

 Mariabackup from MariaDB Enterprise Server performs the following tasks in the `BLOCK_DDL` stage:

 * Copy other files.
	+ i.e. file extensions `.frm`, `.isl`, `.TRG`, `.TRN`, `.opt`, `.par`
* Copy the non-transactional tables that were in use during `BACKUP STAGE FLUSH`.
	+ [MyISAM](../myisam/index) (i.e. file extensions `.MYD` and `.MYI`)
	+ [MERGE](../merge/index) (i.e. file extensions `.MRG`)
	+ [ARCHIVE](../archive/index) (i.e. file extensions `.ARM` and `.ARZ`)
	+ [CSV](../csv/index) (i.e. file extensions `.CSM` and `.CSV`)
* Check `ddl.log` for DDL executed before the `BLOCK DDL` stage.
	+ The file names of newly created tables can be read from `ddl.log`.
	+ The file names of dropped tables can also be read from `ddl.log`.
	+ The file names of renamed tables can also be read from `ddl.log`, so the files can be renamed instead of re-copying them.
* Copy changes to system log tables.
	+ `[mysql.general\_log](../mysqlgeneral_log-table/index)`
	+ `[mysql.slow\_log](../mysqlslow_log-table/index)`
	+ This is easy as these are append only.
* Copy the tail of all transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.
	+ The tail of the Aria redo log (i.e. `aria_log.N` files) will be copied for [Aria](../aria/index) tables.

 ### 
`BACKUP STAGE BLOCK_COMMIT` in MariaDB Enterprise Server

 Mariabackup from MariaDB Enterprise Server performs the following tasks in the `BLOCK_COMMIT` stage:

 * Create a [MyRocks](../myrocks/index) checkpoint using the `[rocksdb\_create\_checkpoint](../myrocks-system-variables/index#rocksdb_create_checkpoint)` system variable.
* Copy changes to system log tables.
	+ `[mysql.general\_log](../mysqlgeneral_log-table/index)`
	+ `[mysql.slow\_log](../mysqlslow_log-table/index)`
	+ This is easy as these are append only.
* Copy changes to statistics tables.
	+ `[mysql.table\_stats](../mysqltable_stats-table/index)`
	+ `[mysql.column\_stats](../mysqlcolumn_stats-table/index)`
	+ `[mysql.index\_stats](../mysqlindex_stats-table/index)`
* Copy the tail of all transaction logs.
	+ The tail of the [InnoDB redo log](../innodb-redo-log/index) (i.e. `ib_logfileN` files) will be copied for [InnoDB](../innodb/index) tables.
	+ The tail of the Aria redo log (i.e. `aria_log.N` files) will be copied for [Aria](../aria/index) tables.
* Save the [binary log](../binary-log/index) position to `[xtrabackup\_binlog\_info](../files-created-by-mariabackup/index#xtrabackup_binlog_info)`.
* Save the [Galera Cluster](../galera/index) state information to `[xtrabackup\_galera\_info](../files-created-by-mariabackup/index#xtrabackup_galera_info)`.

 ### 
`BACKUP STAGE END` in MariaDB Enterprise Server

 Mariabackup from MariaDB Enterprise Server performs the following tasks in the `END` stage:

 * Copy the [MyRocks](../myrocks/index) checkpoint into the backup.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariabackup-and-backup-stage-commands/>

Individual Database Restores with MariaBackup from Full Backup
==============================================================

    This method is to solve a flaw with Mariabackup; it cannot do single database restores from a full backup easily. There is a [blog post that details a way to do this](https://mariadb.com/resources/blog/how-to-restore-a-single-database-from-mariadb-backup/), but it's a manual process which is fine for a few tables but if you have hundreds or even thousands of tables then it would be impossible to do quickly. 

 We can't just move the data files to the datadir as the tables are not registered in the engines, so the database will error. Currently, the only effective method is to a do full restore in a test database and then dump the database that requires restoring or running a partial backup. **This has only been tested with InnoDB. Also, if you have stored procedures or triggers then these will need to be deleted and recreated.**

 Some of the issues that this method overcomes:

 * Tables not registered in the InnoDB engine so will error when you try to select from a table if you move the data files into the datadir
* Tables with foreign keys need to be created without keys, otherwise it will error when you discard the tablespace

 Single Node
-----------

 Below is the process to perform a single database restore.

 Firstly, we will need the table structure from a mariadb-dump backup with the [--no-data](../mariadb-dump/index#options) option. I recommend this is done at least once per day or every six hours via a cronjob. As it is just the structure, it will be very fast. 

 
```
mariadb-dump -u root -p --all-databases --no-data > nodata.sql

```

Using SED to return only the table structure we require, then use vim or another text editor to make sure nothing is left.

 
```
sed -n '/Current Database: `DATABASENAME`/, /Current Database:/p' nodata.sql > trimednodata.sql
vim trimednodata.sql

```

I won’t go over the backup process, as this is done earlier in other documents, such as [full-backup-and-restore-with-mariabackup](../full-backup-and-restore-with-mariabackup/index). Prepare the backup with any [incremental-backup-and-restores](../incremental-backup-and-restore-with-mariabackup/index#backing-up-the-incremental-changes) that you have, and then run the following on the full backup folder using the --export option to generate files with .cfg extensions which InnoDB will look for.

 
```
Mariabackup --prepare --export --target-dir=/media/backups/fullbackupfolder

```

Once we have done these steps, we can then import the table structure. If you have used the [--all-databases](../mariadb-dump/index#options) option, then you will need to either use SED or open it in a text editor and export out tables that you require. You will also need to log in to the database and create the database if the dump file doesn't. Run the following command below:

 
```
Mysql -u root -p schema_name < nodata.sql

```

Once the structure is in the database, we have now registered the tables to the engine. Next, we will run the following statements in the information\_schema database, to export statements to import/discard table spaces and drop and create foreign keys which we will use later. (edit the CONSTRAINT\_SCHEMA and TABLE\_SCHEMA WHERE clause to the database you are restoring. Also, add the following lines after your SELECT and before the FROM to have MariaDB export the files to the OS)

 
```
SELECT ...
into outfile '/tmp/filename.sql'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
FROM ...

```

The following are the statements that we will need later.

 
```
USE information_schema;
select concat("ALTER TABLE ",table_name," DISCARD TABLESPACE;")  AS discard_tablespace
from information_schema.tables 
where TABLE_SCHEMA="DATABASENAME";

select concat("ALTER TABLE ",table_name," IMPORT TABLESPACE;") AS import_tablespace
from information_schema.tables 
where TABLE_SCHEMA="DATABASENAME";

SELECT 
concat ("ALTER TABLE ", rc.CONSTRAINT_SCHEMA, ".",rc.TABLE_NAME," DROP FOREIGN KEY ", rc.CONSTRAINT_NAME,";") AS drop_keys
FROM REFERENTIAL_CONSTRAINTS AS rc
where CONSTRAINT_SCHEMA = 'DATABASENAME';

SELECT
CONCAT ("ALTER TABLE ", 
KCU.CONSTRAINT_SCHEMA, ".",
KCU.TABLE_NAME," 
ADD CONSTRAINT ", 
KCU.CONSTRAINT_NAME, " 
FOREIGN KEY ", "
(`",KCU.COLUMN_NAME,"`)", " 
REFERENCES `",REFERENCED_TABLE_NAME,"` 
(`",REFERENCED_COLUMN_NAME,"`)" ," 
ON UPDATE " ,(SELECT UPDATE_RULE FROM REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA)," 
ON DELETE ",(SELECT DELETE_RULE FROM REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = KCU.CONSTRAINT_NAME AND CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA),";") AS add_keys
FROM KEY_COLUMN_USAGE AS KCU
WHERE KCU.CONSTRAINT_SCHEMA = 'DATABASENAME'
AND KCU.POSITION_IN_UNIQUE_CONSTRAINT >= 0
AND KCU.CONSTRAINT_NAME NOT LIKE 'PRIMARY';

```

Once we have run those statements, and they have been exported to a Linux directory or copied from a GUI interface.

 Run the ALTER DROP KEYS statements in the database

 
```
ALTER TABLE schemaname.tablename DROP FOREIGN KEY key_name;
...

```

Once completed, run the DROP TABLE SPACE statements in the database

 
```
ALTER TABLE test DISCARD TABLESPACE;
...

```

Exit out the database and change into the directory of the full backup location. Run the following commands to copy all the .cfg and .ibd files to the datadir such as /var/lib/mysql/testdatabase (Change the datadir location if needed). Learn more about files that Mariabackup generates with [files-created-by-mariabackup](../files-created-by-mariabackup/index)

 
```
cp *.cfg /var/lib/mysql
cp *.ibd /var/lib/mysql

```

After moving the files, it is very important that MySQL is the owner of the files, otherwise it won't have access to them and will error when we import the tablespaces.

 
```
sudo chown -R mysql:mysql /var/lib/mysql

```

Run the import table spaces statements in the database.

 
```
ALTER TABLE test IMPORT TABLESPACE;
...

```

Run the add key statements in the database

 
```
ALTER TABLE schmeaname.tablename ADD CONSTRAINT key_name FOREIGN KEY (`column_name`) REFERENCES `foreign_table` (`colum_name`) ON UPDATE NO ACTION ON DELETE NO ACTION;
...

```

We have successfully restored a single database. To test that this has worked, we can do a basic check on some tables.

 
```
use database
SELECT * from test limit 10;

```

Replica nodes
-------------

 If you have a primary-replica set up, it would be best to follow the sets above for the primary node and then either take a full mariadb-dump or take a new full mariabackup and restore this to the replica. You can find more information about restoring a replica with mariabackup in [Setting up a Replica with Mariabackup](../setting-up-a-replica-with-mariabackup/index#backup-the-database-and-prepare-it)

 After running the below command, copy to the replica and use the LESS linux command to grab the change master statement. Remember to follow this process: Stop replica > restore data > run CHANGE MASTER statement > start replica again.

 
```
mariadb-dump -u user -p --single-transaction --master-data=2 > fullbackup.sql

```

Please follow [Setting up a Replica with Mariabackup](../setting-up-a-replica-with-mariabackup/index#backup-the-database-and-prepare-it) on restoring a replica with Mariabackup 

 
```
$ mariabackup --backup \
   --slave-info --safe-slave-backup \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

Galera cluster
--------------

 For this process to work with Galera cluster, we first need to understand that some statements are not replicated across Galera nodes. One of which is the DISCARD and IMPORT for ALTER TABLES statements, and these statements will need to be ran on all nodes. We also need to run the OS level steps on each server as seen below.

 Run the ALTER DROP KEYS statements on ONE NODE as these are replicated.

 
```
ALTER TABLE schemaname.tablename DROP FOREIGN KEY key_name;
...

```

Once completed, run the DROP TABLE SPACE statements on EVERY NODE, as these are not replicated.

 
```
ALTER TABLE test DISCARD TABLESPACE;
...

```

Exit out the database and change into the directory of the full backup location. Run the following commands to copy all the .cfg and .ibd files to the datadir such as /var/lib/mysql/testdatabase (Change the datadir location if needed). Learn more about files that Mariabackup generates with [files-created-by-mariabackup](../files-created-by-mariabackup/index). This step needs to be done on all nodes. You will need to copy the backup files to each node, we can use the same backup on all nodes.

 
```
cp *.cfg /var/lib/mysql
cp *.ibd /var/lib/mysql

```

After moving the files, it is very important that MySQL is the owner of the files, otherwise it won't have access to them and will error when we import the tablespaces.

 
```
sudo chown -R mysql:mysql /var/lib/mysql

```

Run the import table spaces statements on EVERY NODE.

 
```
ALTER TABLE test IMPORT TABLESPACE;
...

```

Run the add key statements on ONE NODE

 
```
ALTER TABLE schmeaname.tablename ADD CONSTRAINT key_name FOREIGN KEY (`column_name`) REFERENCES `foreign_table` (`colum_name`) ON UPDATE NO ACTION ON DELETE NO ACTION;
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/individual-database-restores-with-mariabackup-from-full-backup/>

mysql.gtid\_slave\_pos Table
============================

    The `mysql.gtid_slave_pos` table is used in [replication](../replication/index) by replica servers to keep track of their current position (the [global transaction ID](../gtid/index) of the last transaction applied). Using the table allows the replica to maintain a consistent value for the [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) system variable across server restarts. See [Global Transaction ID](../global-transaction-id/index). 

 You should never attempt to modify the table directly. If you do need to change the global gtid\_slave\_pos value, use `SET GLOBAL gtid_slave_pos = ...` instead.

 The table is updated with the new position as part of each transaction committed during replication. This makes it preferable that the table is using the same storage engine as the tables otherwise being modified in the transaction, since otherwise a multi-engine transaction is needed that can reduce performance.

 Starting from [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), multiple versions of this table are supported, each using a different storage engine. This is selected with the [gtid\_pos\_auto\_engines option](../global-transaction-id/index#gtid_pos_auto_engines), by giving a comma-separated list of engine names. The server will then on-demand create an extra version of the table using the appropriate storage engine, and select the table version using the same engine as the rest of the transaction, avoiding multi-engine transactions.

 For example, when `gtid_pos_auto_engines=innodb,rocksdb`, tables `mysql.gtid_slave_pos_InnoDB` and `mysql.gtid_slave_pos_RocksDB` will be created and used, if needed. If there is no match to the storage engine, the default `mysql.gtid_slave_pos` table will be used; this also happens if non-transactional updates (like MyISAM) are replicated, since there is then no active transaction at the time of the `mysql.gtid_slave_pos` table update.

 Prior to [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), only the default `mysql.gtid_slave_pos` table is available. In these versions, the table should preferably be using the storage engine that is used for most replicated transactions.

 The default `mysql.gtid_slave_pos` table will be initially created using the default storage engine set for the server (which itself defaults to InnoDB). If the application load is primarily non-transactional MyISAM or Aria tables, it can be beneficial to change the storage engine to avoid including an InnoDB update with every operation:

 
```
ALTER TABLE mysql.gtid_slave_pos ENGINE=MyISAM;

```

The `mysql.gtid_slave_pos` table should not be changed manually in any other way. From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), it is preferable to use the `gtid_pos_auto_engines` server variable to get the GTID position updates to use the TokuDB or RocksDB storage engine.

 Note that for scalability reasons, the automatic creation of a new `mysql.gtid_slave_posXXX` table happens asynchronously when the first transaction with the new storage engine is committed. So the very first few transactions will update the old version of the table, until the new version is created and available.

 The table `mysql.gtid_slave_pos` contains the following fields

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `domain_id` | `int(10) unsigned` | NO | PRI | `NULL` | Domain id (see [Global Transaction ID domain ID](../global-transaction-id/index#the-domain-id). |
| `sub_id` | `bigint(20) unsigned` | NO | PRI | `NULL` | This field enables multiple parallel transactions within same `domain_id` to update this table without contention. At any instant, the replication state corresponds to records with largest `sub_id` for each `domain_id`. |
| `server_id` | `int(10) unsigned` | NO |  | `NULL` | [Server id](../global-transaction-id/index#server_id). |
| `seq_no` | `bigint(20) unsigned` | NO |  | `NULL` | Sequence number, an integer that is monotonically increasing for each new event group logged into the binlog. |

 
From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), some status variables are available to monitor the use of the different `gtid_slave_pos` table versions:

 [Transactions\_gtid\_foreign\_engine](../replication-and-binary-log-status-variables/index#transactions_gtid_foreign_engine)

  Number of replicated transactions where the update of the `gtid_slave_pos` table had to choose a storage engine that did not otherwise participate in the transaction. This can indicate that setting gtid\_pos\_auto\_engines might be useful.

 [Rpl\_transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#rpl_transactions_multi_engine)

  Number of replicated transactions that involved changes in multiple (transactional) storage engines, before considering the update of `gtid_slave_pos`. These are transactions that were already cross-engine, independent of the GTID position update introduced by replication

 [Transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#transactions_multi_engine)

  Number of transactions that changed data in multiple (transactional) storage engines. If this is significantly larger than Rpl\_transactions\_multi\_engine, it indicates that setting `gtid_pos_auto_engines` could reduce the need for cross-engine transactions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlgtid_slave_pos-table/>

Using MariaDB GTIDs with MariaDB Galera Cluster
===============================================

    MariaDB's [global transaction IDs (GTIDs)](../gtid/index) are very useful when used with [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index), which is primarily what that feature was developed for. [Galera Cluster](http://galeracluster.com/), on the other hand, was developed by Codership for all MySQL and MariaDB variants, and the initial development of the technology pre-dated MariaDB's [GTID](../gtid/index) implementation. As a side effect, [MariaDB Galera Cluster](../galera-cluster/index) (at least until [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) only partially supports MariaDB's [GTID](../gtid/index) implementation.

 GTID Support for Write Sets Replicated by Galera Cluster
--------------------------------------------------------

 Galera Cluster has its own [certification-based replication method](../about-galera-replication/index) that is substantially different from [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index). However, it would still be beneficial if [MariaDB Galera Cluster](../galera-cluster/index) was able to associate a Galera Cluster write set with a [GTID](../gtid/index) that is globally unique, but that is also consistent for that write set on each cluster node.

 Before [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), [MariaDB Galera Cluster](../galera-cluster/index) did not replicate the original [GTID](../gtid/index) with the write set except in cases where the transaction was originally applied by a [slave SQL thread](../replication-threads/index#slave-sql-thread). Each node independently generated its own [GTID](../gtid/index) for each write set in most cases. See [MDEV-20720](https://jira.mariadb.org/browse/MDEV-20720).

 ### Wsrep GTID Mode

 
**MariaDB starting with [10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)**MariaDB has supported `[wsrep\_gtid\_mode](../galera-cluster-system-variables/index#wsrep_gtid_mode)` since version 10.1.4.

 
[MariaDB 10.1](../what-is-mariadb-101/index) and above has a feature called wsrep GTID mode. When this mode is enabled, MariaDB uses some tricks to try to associate each Galera Cluster write set with a [GTID](../gtid/index) that is globally unique, but that is also consistent for that write set on each cluster node. These tricks work in some cases, but [GTIDs](../gtid/index) can still become inconsistent among cluster nodes.

 #### Enabling Wsrep GTID Mode

 Several things need to be configured for wsrep GTID mode to work, such as:

 * `[wsrep\_gtid\_mode=ON](../galera-cluster-system-variables/index#wsrep_gtid_mode)` needs to be set on all nodes in the cluster.

 * `[wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)` needs to be set to the same value on all nodes in a given cluster, so that each cluster node uses the same domain when assigning [GTIDs](../gtid/index) for Galera Cluster's write sets. When replicating between two clusters, each cluster should have this set to a different value, so that each cluster uses different domains when assigning [GTIDs](../gtid/index) for their write sets.

 * `[log\_slave\_updates](../replication-and-binary-log-system-variables/index#log_slave_updates)` needs to be enabled on all nodes in the cluster. See [MDEV-9855](https://jira.mariadb.org/browse/MDEV-9855).

 * `[log\_bin](../replication-and-binary-log-server-system-variables/index#log_bin)` needs to be set to the same path on all nodes in the cluster. See [MDEV-9856](https://jira.mariadb.org/browse/MDEV-9856).

 And as an extra safety measure:

 * `[gtid\_domain\_id](../gtid/index#gtid_domain_id)` should be set to a different value on all nodes in a given cluster, and each of these values should be different than the configured `[wsrep\_gtid\_domain\_id](../galera-cluster-system-variables/index#wsrep_gtid_domain_id)` value. This is to prevent a node from using the same domain used for Galera Cluster's write sets when assigning [GTIDs](../gtid/index) for non-Galera transactions, such as DDL executed with `[wsrep\_sst\_method=RSU](../galera-cluster-system-variables/index#wsrep_sst_method)` set or DML executed with `[wsrep\_on=OFF](../galera-cluster-system-variables/index#wsrep_on)` set.

 For information on setting `[server\_id](../replication-and-binary-log-system-variables/index#server_id)`, see [Using MariaDB Replication with MariaDB Galera Cluster: Setting server\_id on Cluster Nodes](../using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/index#setting-server_id-on-cluster-nodes).

 #### Known Problems with Wsrep GTID Mode

 Until [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), there were known cases where [GTIDs](../gtid/index) could become inconsistent across the cluster nodes.

 A known issue (fixed in [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) is:

 * Implicitly dropped temporary tables can make GTIDs inconsistent. See [MDEV-14153](https://jira.mariadb.org/browse/MDEV-14153) and [MDEV-20720](https://jira.mariadb.org/browse/MDEV-20720).

 This does not necessarily imply that wsrep GTID mode works perfectly in all other situations. If you discover any other issues with it, please [report a bug](../mariadb-community-bug-reporting/index#reporting-a-bug).

 ### GTIDs for Transactions Applied by Slave Thread

 If a Galera Cluster node is also a [replication slave](../replication-overview/index), then that node's [slave SQL thread](../replication-threads/index#slave-sql-thread) will be applying transactions that it replicates from its replication master. If the node has `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` set, then each transaction that the [slave SQL thread](../replication-threads/index#slave-sql-thread) applies will also generate a Galera Cluster write set that is replicated to the rest of the nodes in the cluster.

 In [MariaDB 10.1.30](https://mariadb.com/kb/en/mariadb-10130-release-notes/) and earlier, the node acting as slave would apply the transaction with the original GTID that it received from the master, and the other Galera Cluster nodes would generate their own GTIDs for the transaction when they replicated the write set.

 In [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) and later, the node acting as slave will include the transaction's original `Gtid_Log_Event` in the replicated write set, so all nodes should associate the write set with its original GTID. See [MDEV-13431](https://jira.mariadb.org/browse/MDEV-13431) about that.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-gtids-with-mariadb-galera-cluster/>

START SLAVE
===========

    
The terms *master* and *slave* have historically been used in replication, but the terms terms *primary* and *replica* are now preferred. The old terms are used still used in parts of the documentation, and in MariaDB commands, although [MariaDB 10.5](../what-is-mariadb-105/index) has begun the process of renaming. The documentation process is ongoing. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to follow progress on this effort.

  Syntax
------

 
```
START SLAVE ["connection_name"] [thread_type [, thread_type] ... ] [FOR CHANNEL "connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL                
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos [FOR CHANNEL "connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos [FOR CHANNEL "connection_name"]
START SLAVE ["connection_name"] [SQL_THREAD] UNTIL
    MASTER_GTID_POS = <GTID position> [FOR CHANNEL "connection_name"]
START ALL SLAVES [thread_type [, thread_type]]

START REPLICA ["connection_name"] [thread_type [, thread_type] ... ] -- from 10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL                
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos -- from 10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos -- from 10.5.1
START REPLICA ["connection_name"] [SQL_THREAD] UNTIL
    MASTER_GTID_POS = <GTID position> -- from 10.5.1
START ALL REPLICAS [thread_type [, thread_type]] -- from 10.5.1

thread_type: IO_THREAD | SQL_THREAD

```
 Description
-----------

 `START SLAVE` (`START REPLICA` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)) with no thread\_type options starts both of the replica threads (see [replication](../replication/index)). The I/O thread reads events from the primary server and stores them in the [relay log](../relay-log/index). The SQL thread reads events from the relay log and executes them. `START SLAVE` requires the [SUPER](../grant/index#super) privilege, or, from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), the [REPLICATION SLAVE ADMIN](../grant/index#replication-slave-admin) privilege.

 If `START SLAVE` succeeds in starting the replica threads, it returns without any error. However, even in that case, it might be that the replica threads start and then later stop (for example, because they do not manage to connect to the primary or read its [binary log](../binary-log/index), or some other problem). `START SLAVE` does not warn you about this. You must check the replica's [error log](../error-log/index) for error messages generated by the replica threads, or check that they are running satisfactorily with [SHOW SLAVE STATUS](../show-replica-status/index) ([SHOW REPLICA STATUS](../show-replica-status/index) from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)).

 #### START SLAVE UNTIL

 `START SLAVE UNTIL` refers to the `SQL_THREAD` replica position at which the `SQL_THREAD` replication will halt. If `SQL_THREAD` isn't specified both threads are started.

 `START SLAVE UNTIL master_gtid_pos=xxx` is also supported. See [Global Transaction ID/START SLAVE UNTIL master\_gtid\_pos=xxx](../global-transaction-id/index#start-slave-until-master_gtid_posxxx) for more details.

 #### connection\_name

 If there is only one nameless primary, or the default primary (as specified by the [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) system variable) is intended, `connection_name` can be omitted. If provided, the `START SLAVE` statement will apply to the specified primary. `connection_name` is case-insensitive.

 
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The `FOR CHANNEL` keyword was added for MySQL compatibility. This is identical as using the channel\_name directly after `START SLAVE`.

 
#### START ALL SLAVES

 `START ALL SLAVES` starts all configured replicas (replicas with master\_host not empty) that were not started before. It will give a `note` for all started connections. You can check the notes with [SHOW WARNINGS](../show-warnings/index).

 #### START REPLICA

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**`START REPLICA` is an alias for `START SLAVE` from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/). 

 
See Also
--------

 * [Setting up replication](../setting-up-replication/index).
* [CHANGE MASTER TO](../change-master-to/index) is used to create and change connections.
* [STOP SLAVE](../stop-slave/index) is used to stop a running connection.
* [RESET SLAVE](../reset-slave/index) is used to reset parameters for a connection and also to permanently delete a primary connection.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/start-slave/>

Restoring Individual Tables and Partitions with Mariabackup
===========================================================

    When using Mariabackup, you don't necessarily need to restore every table and/or partition that was backed up. Even if you're starting from a [full backup](../full-backup-and-restore-with-mariabackup/index), it is certainly possible to restore only certain tables and/or partitions from the backup, as long as the table or partition involved is in an [InnoDB file-per-table tablespace](../innodb-file-per-table-tablespaces/index). This page documents how to restore individual tables and partitions.

 Preparing the Backup
--------------------

 Before you can restore from a backup, you first need to **prepare** it to make the data files consistent. You can do so with the `[--prepare](../mariabackup-options/index#-prepare)` command option.

 The ability to restore individual tables and partitions relies on [InnoDB's transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces). For MariaDB to import tablespaces like these, [InnoDB](../xtradb-and-innodb/index) looks for a file with a `.cfg` extension. For Mariabackup to create these files, you also need to add the `[--export](../mariabackup-options/index#-export)` option during the prepare step.

 For example, you might execute the following command:

 
```
$ mariabackup --prepare --export \
   --target-dir=/var/mariadb/backup/ \
   --user=mariabackup --password=mypassword

```

If this operation completes without error, then the backup is ready to be restored.

 
**MariaDB until [10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/)**Before [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/), Mariabackup did not support the `[--export](../mariabackup-options/index#-export)` option. See [MDEV-13466](https://jira.mariadb.org/browse/MDEV-13466) about that. In earlier versions of MariaDB, this means that Mariabackup could not create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index) during the `--prepare` stage. You can still [import file-per-table tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces) without the `.cfg` files in many cases, so it may still be possible in those versions to [restore partial backups](../partial-backup-and-restore-with-mariabackup/index) or to [restore individual tables and partitions](index) with just the `.ibd` files. If you have a [full backup](../full-backup-and-restore-with-mariabackup/index) and you need to create `.cfg` files for [InnoDB file-per-table tablespaces](../innodb-file-per-table-tablespaces/index), then you can do so by preparing the backup as usual without the `--export` option, and then restoring the backup, and then starting the server. At that point, you can use the server's built-in features to [copy the transportable tablespaces](../innodb-file-per-table-tablespaces/index#copying-transportable-tablespaces).

 
Restoring the Backup
--------------------

 The restore process for restoring individual tables and/or partitions is quite different than the process for [full backups](../full-backup-and-restore-with-mariabackup/index).

 Rather than using the `[--copy-back](../mariabackup-options/index#-copy-back)` or the `[--move-back](../mariabackup-options/index#-move-back)`, each individual [InnoDB file-per-table tablespace](../innodb-file-per-table-tablespaces/index) file will have to be manually imported into the target server. The process that is used to restore the backup will depend on whether partitioning is involved.

 ### Restoring Individual Non-Partitioned Tables

 To restore individual non-partitioned tables from a backup, find the `.ibd` and `.cfg` files for the table in the backup, and then import them using the [Importing Transportable Tablespaces for Non-partitioned Tables](../innodb-file-per-table-tablespaces/index#importing-transportable-tablespaces-for-non-partitioned-tables) process.

 ### Restoring Individual Partitions and Partitioned Tables

 To restore individual partitions or partitioned tables from a backup, find the `.ibd` and `.cfg` files for the partition(s) in the backup, and then import them using the [Importing Transportable Tablespaces for Partitioned Tables](../innodb-file-per-table-tablespaces/index#importing-transportable-tablespaces-for-partitioned-tables) process.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/restoring-individual-tables-and-partitions-with-mariabackup/>

Manual SST of Galera Cluster Node With Mariabackup
==================================================

    Sometimes it can be helpful to perform a "manual SST" when Galera's [normal SSTs](../introduction-to-state-snapshot-transfers-ssts/index) fail. This can be especially useful when the cluster's `[datadir](../server-system-variables/index#datadir)` is very large, since a normal SST can take a long time to fail in that case.

 A manual SST essentially consists of taking a backup of the donor, loading the backup on the joiner, and then manually editing the cluster state on the joiner node. This page will show how to perform this process with [Mariabackup](../mariabackup/index).

 Process
-------

 * Check that the donor and joiner nodes have the same Mariabackup version.

 
```
mariabackup --version

```

* Create backup directory on donor.

 
```
MYSQL_BACKUP_DIR=/mysql_backup
mkdir $MYSQL_BACKUP_DIR

```

* Take a [full backup](../full-backup-and-restore-with-mariabackup/index) the of the donor node with `mariabackup`. The `[--galera-info](../mariabackup-options/index#-galera-info)` option should also be provided, so that the node's cluster state is also backed up.

 
```
DB_USER=sstuser
DB_USER_PASS=password
mariabackup --backup  --galera-info \
   --target-dir=$MYSQL_BACKUP_DIR \
   --user=$DB_USER \
   --password=$DB_USER_PASS

```

* Verify that the MariaDB Server process is stopped on the joiner node. This will depend on your [service manager](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 For example, on [systemd](../systemd/index) systems, you can execute::

 
```
systemctl status mariadb

```

* Create the backup directory on the joiner node.

 
```
MYSQL_BACKUP_DIR=/mysql_backup
mkdir $MYSQL_BACKUP_DIR

```

* Copy the backup from the donor node to the joiner node.

 
```
OS_USER=dba
JOINER_HOST=dbserver2.mariadb.com
rsync -av $MYSQL_BACKUP_DIR/* ${OS_USER}@${JOINER_HOST}:${MYSQL_BACKUP_DIR}

```

* [Prepare the backup](../full-backup-and-restore-with-mariabackup/index#preparing-the-backup) on the joiner node.

 
```
mariabackup --prepare \
   --target-dir=$MYSQL_BACKUP_DIR

```

* Get the Galera Cluster version ID from the donor node's `grastate.dat` file.

 
```
MYSQL_DATADIR=/var/lib/mysql
cat $MYSQL_DATADIR/grastate.dat | grep version

```

For example, a very common version number is "2.1".

 * Get the node's cluster state from the `[xtrabackup\_galera\_info](../mariabackup-options/index#-galera-info)` file in the backup that was copied to the joiner node.

 
```
cat $MYSQL_BACKUP_DIR/xtrabackup_galera_info

```

The file contains the values of the `[wsrep\_local\_state\_uuid](../galera-cluster-status-variables/index#wsrep_local_state_uuid)` and `[wsrep\_last\_committed](../galera-cluster-status-variables/index#wsrep_last_committed)` status variables.

 The values are written in the following format:

 
```
wsrep_local_state_uuid:wsrep_last_committed

```

For example:

 
```
d38587ce-246c-11e5-bcce-6bbd0831cc0f:1352215

```

* Create a `grastate.dat` file in the backup directory of the joiner node. The Galera Cluster version ID, the cluster uuid, and the seqno from previous steps will be used to fill in the relevant fields.

 For example, with the example values from the last two steps, we could do:

 
```
sudo tee $MYSQL_BACKUP_DIR/grastate.dat <<EOF
# GALERA saved state
version: 2.1
uuid:    d38587ce-246c-11e5-bcce-6bbd0831cc0f
seqno:   1352215
safe_to_bootstrap: 0
EOF

```

* Remove the existing contents of the `[datadir](../server-system-variables/index#datadir)` on the joiner node.

 
```
MYSQL_DATADIR=/var/lib/mysql
rm -Rf $MYSQL_DATADIR/*

```

* Copy the contents of the backup directory to the `[datadir](../server-system-variables/index#datadir)` the on joiner node.

 
```
mariabackup --copy-back \
   --target-dir=$MYSQL_BACKUP_DIR

```

* Make sure the permissions of the `[datadir](../server-system-variables/index#datadir)` are correct on the joiner node.

 
```
chown -R mysql:mysql $MYSQL_DATADIR/

```

* Start the MariaDB Server process on the joiner node. This will depend on your [service manager](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 For example, on [systemd](../systemd/index) systems, you can execute::

 
```
systemctl start mariadb

```

* Watch the MariaDB [error log](../error-log/index) on the joiner node and verify that the node does not need to perform a [normal SSTs](../introduction-to-state-snapshot-transfers-ssts/index) due to the manual SST.

 
```
tail -f /var/log/mysql/mysqld.log

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/manual-sst-of-galera-cluster-node-with-mariabackup/>

Thread States
==============

   Thread states can be viewed with the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). `Slave_IO_State` shown by [SHOW SLAVE STATUS](../show-slave-status/index) also shows slave-related thread states. 

  

| Title | Description |
| --- | --- |
|  [Delayed Insert Connection Thread States](../delayed-insert-connection-thread-states/index) |  Thread states related to the connection thread that processes INSERT DELAYED statements  |
|  [Delayed Insert Handler Thread States](../delayed-insert-handler-thread-states/index) |  Thread states related to the handler thread that inserts the results of INSERT DELAYED statements  |
|  [Event Scheduler Thread States](../event-scheduler-thread-states/index) |  Thread states related to the Event Scheduler  |
|  [General Thread States](../general-thread-states/index) |  Thread states  |
|  [Master Thread States](../master-thread-states/index) |  Thread states related to replication master threads  |
|  [Query Cache Thread States](../query-cache-thread-states/index) |  Thread states related to the query cache  |
|  [Slave Connection Thread States](../slave-connection-thread-states/index) |  Thread states related to slave connection threads  |
|  [Slave I/O Thread States](../slave-io-thread-states/index) |  Thread states related to replication slave I/O threads  |
|  [Slave SQL Thread States](../slave-sql-thread-states/index) |  Thread states related to replication slave SQL threads.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-states/>

Encrypting Binary Logs
======================

    MariaDB Server can encrypt the server's [binary logs](../binary-log/index) and [relay logs](../relay-log/index). This ensures that your binary logs are only accessible through MariaDB.

 Basic Configuration
-------------------

 Since [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), MariaDB can also encrypt [binary logs](../binary-log/index) (including [relay logs](../relay-log/index)). Encryption of binary logs is configured by the [encrypt\_binlog](../replication-and-binary-log-system-variables/index#encrypt_binlog) system variable.

 Users of data-at-rest encryption will also need to have a [key management and encryption plugin](../encryption-key-management/index) configured. Some examples are [File Key Management Plugin](../file-key-management-encryption-plugin/index) and [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index).

 
```
[mariadb]
...

# File Key Management
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/encryption/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
file_key_management_encryption_algorithm = AES_CTR

# Binary Log Encryption
encrypt_binlog=ON

```

Encryption Keys
---------------

 [Key management and encryption plugins](../encryption-key-management/index) support [using multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key can be defined with a different 32-bit integer as a key identifier.

 MariaDB uses the encryption key with ID 1 to encrypt [binary logs](../binary-log/index).

 ### Key Rotation

 Some [key management and encryption plugins](../encryption-key-management/index) allow you to automatically rotate and version your encryption keys. If a plugin support key rotation, and if it rotates the encryption keys, then InnoDB's [background encryption threads](../innodb-background-encryption-threads/index) can re-encrypt InnoDB pages that use the old key version with the new key version. However, the binary log does **not** have a similar mechanism, which means that existing binary logs remain encrypted with the older key version, but new binary logs will be encrypted with the new key version. For more information, see [MDEV-20098](https://jira.mariadb.org/browse/MDEV-20098).

 
In order for key rotation to work, both the backend key management service (KMS) and the corresponding [key management and encryption plugin](../encryption-key-management/index) have to support key rotation. See [Encryption Key Management: Support for Key Rotation in Encryption Plugins](../encryption-key-management/index#support-for-key-rotation-in-encryption-plugins) to determine which plugins currently support key rotation.

 
Enabling Encryption
-------------------

 Encryption of binary logs can be enabled by doing the following process.

 * First, stop the server.

 * Then, set `[encrypt\_binlog=ON](../replication-and-binary-log-system-variables/index#encrypt_binlog)` in the MariaDB configuration file.

 * Then, start the server.

 From that point forward, any new [binary logs](../binary-log/index) will be encrypted. To delete old unencrypted [binary logs](../binary-log/index), you can use [RESET MASTER](../reset-master/index) or [PURGE BINARY LOGS](../sql-commands-purge-logs/index).

 Disabling Encryption
--------------------

 Encryption of [binary logs](../binary-log/index) can be disabled by doing the following process.

 * First, stop the server.

 * Then, set `[encrypt\_binlog=OFF](../replication-and-binary-log-system-variables/index#encrypt_binlog)` in the MariaDB configuration file.

 * Then, start the server.

 From that point forward, any new [binary logs](../binary-log/index) will be unencrypted. If you would like the server to continue to have access to old encrypted [binary logs](../binary-log/index), then make sure to keep your [key management and encryption plugin](../encryption-key-management/index) loaded. 

 Understanding Binlog Encryption
-------------------------------

 When starting with binary log encryption, MariaDB Server logs a `Format_descriptor_log_event` and a `START_ENCRYPTION_EVENT`, then encrypts all subsequent events for the binary log.

 Each event's header and footer are created and processed to produce encrypted blocks. These encrypted blocks are produced before transactions are committed and before the events are flushed to the binary log. As such, they exist in an encrypted state in memory buffers and in the `IO_CACHE` files for user connections.

 ### Effects of Data-at-Rest Encryption on Replication

 When using encrypted binary logs with [replication](../replication/index), it is completely supported to have different encryption keys on the master and slave. The master decrypts encrypted binary log events as it reads them from disk, and before its [binary log dump thread](../replication-threads/index#binary-log-dump-thread) sends them to the slave, so the slave actually receives the unencrypted binary log events.

 If you want to ensure that binary log events are encrypted as they are transmitted between the master and slave, then you will have to use [TLS with the replication connection](../replication-with-secure-connections/index).

 ### Effects of Data-at-Rest Encryption on mariadb-binlog

 [mariadb-binlog](../mariadb-binlog/index) does not currently have the ability to decrypt encrypted [binary logs](../binary-log/index) on its own (see [MDEV-8813](https://jira.mariadb.org/browse/MDEV-8813) about that). In order to use mariadb-binlog with encrypted [binary logs](../binary-log/index), you have to use the [--read-from-remote-server](../mariadb-binlog-options/index) command-line option, so that the server can decrypt the [binary logs](../binary-log/index) for mariadb-binlog.

 Note, using the `--read-from-remote-server` option on versions of the `mariadb-binlog` utility that do not have the [MDEV-20574](https://jira.mariadb.org/browse/MDEV-20574) fix (<=[MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-1049-release-notes/), [MariaDB 10.3.19](https://mariadb.com/kb/en/mariadb-10319-release-notes/), [MariaDB 10.2.28](https://mariadb.com/kb/en/mariadb-10228-release-notes/)) can corrupt binlog positions when the binary log is encrypted.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encrypting-binary-logs/>

PBXT
=====

   PrimeBase XT (PBXT) is a general purpose transactional storage engine designed for high concurrency environments.

 PBXT is no longer maintained, and is not part of [MariaDB 5.5](../what-is-mariadb-55/index) or later.

  

| Title | Description |
| --- | --- |
|  [About PBXT](../about-pbxt/index) |  A storage engine that was included by default until MariaDB 5.3.  |
|  [Building PBXT](../building-pbxt/index) |  The commands to use for building PBXT  |
|  [File Organization in PBXT](../file-organization-in-pbxt/index) |  How files are organized in PBXT  |
|  [xtstat](../xtstat/index) |  Used to monitor all internal activity of PBXT  |
|  [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index) |  Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT.  |
|  [PBXT System Variables](../pbxt-system-variables/index) |  PBXT System Variables  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pbxt-storage-engine/>

Overview of the Binary Log
==========================

    The binary log contains a record of all changes to the databases, both data and structure, as well as how long each statement took to execute. It consists of a set of binary log files and an index.

 This means that statements such as [CREATE](../create/index), [ALTER](../alter/index), [INSERT](../insert/index), [UPDATE](../update/index) and [DELETE](../delete/index) will be logged, but statements that have no effect on the data, such as SELECT and SHOW, will not be logged. If you want to log these (at a cost in performance), use the [general query log](../general-query-log/index).

 If a statement may potentially have an effect, but doesn't, such as an UPDATE or DELETE that returns no rows, it will still be logged (this applies to the default statement-based logging, not to row-based logging - see [Binary Log Formats](../binary-log-formats/index)).

 The purpose of the binary log is to allow [replication](../replication/index), where data is sent from one or more masters to one or more slave servers based on the contents of the binary log, as well as assisting in backup operations.

 A MariaDB server with the binary log enabled will run slightly more slowly.

 It is important to protect the binary log, as it may contain sensitive information, including passwords.

 Binary logs are stored in a binary, not plain text, format, and so are not viewable with a regular editor. However, MariaDB includes [mariadb-binlog](../mariadb-binlog/index), a commandline tool for plain text processing of binary logs.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/overview-of-the-binary-log/>

INSERT ON DUPLICATE KEY UPDATE
==============================

    Syntax
------

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
  [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
  {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
  [ ON DUPLICATE KEY UPDATE
    col=expr
      [, col=expr] ... ]

```

Or:

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)]
    SET col={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ]

```

Or:

 
```
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ]

```
 Description
-----------

 INSERT ... ON DUPLICATE KEY UPDATE is a MariaDB/MySQL extension to the [INSERT](../insert/index) statement that, if it finds a duplicate unique or primary key, will instead perform an [UPDATE](../update/index).

 The row/s affected value is reported as 1 if a row is inserted, and 2 if a row is updated, unless the API's `CLIENT_FOUND_ROWS` flag is set.

 If more than one unique index is matched, only the first is updated. It is not recommended to use this statement on tables with more than one unique index.

 If the table has an [AUTO\_INCREMENT](../auto_increment/index) primary key and the statement inserts or updates a row, the [LAST\_INSERT\_ID()](../last_insert_id/index) function returns its AUTO\_INCREMENT value.

 The [VALUES()](../values/index) function can only be used in a `ON DUPLICATE KEY UPDATE` clause and has no meaning in any other context. It returns the column values from the `INSERT` portion of the statement. This function is particularly useful for multi-rows inserts.

 The [IGNORE](../ignore/index) and [DELAYED](../insert-delayed/index) options are ignored when you use `ON DUPLICATE KEY UPDATE`.

 See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details on the PARTITION clause.

 This statement activates INSERT and UPDATE triggers. See [Trigger Overview](../trigger-overview/index) for details.

 See also a similar statement, [REPLACE](../replace/index).

 Examples
--------

 
```
CREATE TABLE ins_duplicate (id INT PRIMARY KEY, animal VARCHAR(30));
INSERT INTO ins_duplicate VALUES (1,'Aardvark'), (2,'Cheetah'), (3,'Zebra');

```

If there is no existing key, the statement runs as a regular INSERT:

 
```
INSERT INTO ins_duplicate VALUES (4,'Gorilla') 
  ON DUPLICATE KEY UPDATE animal='Gorilla';
Query OK, 1 row affected (0.07 sec)

```


```
SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Aardvark |
|  2 | Cheetah  |
|  3 | Zebra    |
|  4 | Gorilla  |
+----+----------+

```

A regular INSERT with a primary key value of 1 will fail, due to the existing key:

 
```
INSERT INTO ins_duplicate VALUES (1,'Antelope');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

```

However, we can use an INSERT ON DUPLICATE KEY UPDATE instead:

 
```
INSERT INTO ins_duplicate VALUES (1,'Antelope') 
  ON DUPLICATE KEY UPDATE animal='Antelope';
Query OK, 2 rows affected (0.09 sec)

```

Note that there are two rows reported as affected, but this refers only to the UPDATE.

 
```
SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Antelope |
|  2 | Cheetah  |
|  3 | Zebra    |
|  4 | Gorilla  |
+----+----------+

```

Adding a second unique column:

 
```
ALTER TABLE ins_duplicate ADD id2 INT;
UPDATE ins_duplicate SET id2=id+10;
ALTER TABLE ins_duplicate ADD UNIQUE KEY(id2);

```

Where two rows match the unique keys match, only the first is updated. This can be unsafe and is not recommended unless you are certain what you are doing.

 
```
INSERT INTO ins_duplicate VALUES (2,'Lion',13) 
  ON DUPLICATE KEY UPDATE animal='Lion';
Query OK, 2 rows affected (0.004 sec)

SELECT * FROM ins_duplicate;
+----+----------+------+
| id | animal   | id2  |
+----+----------+------+
|  1 | Antelope |   11 |
|  2 | Lion     |   12 |
|  3 | Zebra    |   13 |
|  4 | Gorilla  |   14 |
+----+----------+------+

```

Although the third row with an id of 3 has an id2 of 13, which also matched, it was not updated.

 Changing id to an auto\_increment field. If a new row is added, the auto\_increment is moved forward. If the row is updated, it remains the same.

 
```
ALTER TABLE `ins_duplicate` CHANGE `id` `id` INT( 11 ) NOT NULL AUTO_INCREMENT;
ALTER TABLE ins_duplicate DROP id2;
SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
  WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              5 |
+----------------+

INSERT INTO ins_duplicate VALUES (2,'Leopard') 
  ON DUPLICATE KEY UPDATE animal='Leopard';
Query OK, 2 rows affected (0.00 sec)

SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
  WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              5 |
+----------------+

INSERT INTO ins_duplicate VALUES (5,'Wild Dog') 
  ON DUPLICATE KEY UPDATE animal='Wild Dog';
Query OK, 1 row affected (0.09 sec)

SELECT * FROM ins_duplicate;
+----+----------+
| id | animal   |
+----+----------+
|  1 | Antelope |
|  2 | Leopard  |
|  3 | Zebra    |
|  4 | Gorilla  |
|  5 | Wild Dog |
+----+----------+

SELECT Auto_increment FROM INFORMATION_SCHEMA.TABLES 
  WHERE TABLE_NAME='ins_duplicate';
+----------------+
| Auto_increment |
+----------------+
|              6 |
+----------------+

```

Refering to column values from the INSERT portion of the statement: 

 
```
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
    ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

```

See the [VALUES()](../values/index) function for more.

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [VALUES()](../values/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-on-duplicate-key-update/>

Using and Maintaining the Binary Log
====================================

     See [Overview of the Binary Log](../overview-of-the-binary-log/index) for a general overview of what the binary log is, and [Activating the Binary Log](../activating-the-binary-log/index) for how to make sure it's running on your system.

 For details on using the binary log for replication, see the [Replication](../replication/index) section.

 Purging Log Files
-----------------

 To delete all binary log files on the server, run the [RESET MASTER](../reset-master/index) command. To delete all binary logs before a certain datetime, or up to a certain number, use [PURGE BINARY LOGS](../sql-commands-purge-logs/index).

 
If a replica is active but has yet to read from a binary log file you attempt to delete, the statement will fail with an error. However, if the replica is not connected and has yet to read from a log file you delete, the file will be deleted, but the replica will be unable to continue replicating once it connects again.

 
Log files can also be removed automatically with the [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days) system variable. This is set to 0 by default (no removal), but can be set to a time, in days, after which a binary log file will be automatically removed. Log files will only be checked for being older than [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days) upon log rotation, so if your binary log only fills up slowly and does not reach [max\_binlog\_size](../replication-and-binary-log-system-variables/index#max_binlog_size) on a daily basis, you may see older log files still being kept. You can also force log rotation, and so expiry deletes, by running [FLUSH BINARY LOGS](../flush/index) on a regular basis. Always set [expire\_logs\_days](../replication-and-binary-log-system-variables/index#expire_logs_days) higher than any possible replica lag.

 From [MariaDB 10.6](../what-is-mariadb-106/index), the [binlog\_expire\_logs\_seconds](../replication-and-binary-log-system-variables/index#binlog_expire_logs_seconds) variable allows more precise control over binlog deletion, and takes precedence if both are non-zero.

 
If the binary log index file has been removed, or incorrectly manually edited, all of the above forms of purging log files will fail. The .index file is a plain text file, and can be manually recreated or edited so that it lists only the binary log files that are present, in numeric/age order.

 
### Examples

 
```
PURGE BINARY LOGS TO 'mariadb-bin.000063';

```


```
PURGE BINARY LOGS BEFORE '2013-04-22 09:55:22';

```

### Safely Purging Binary Log Files While Replicating

 To be sure replication is not broken while deleting log files, perform the following steps:

 * Get a listing of binary log files on the primary by running [SHOW BINARY LOGS](../show-binary-logs/index).
* Go to each replica server and run [SHOW SLAVE STATUS](../show-slave-status/index) to check which binary log file each replica is currently reading.
* Find the earliest log file still being read by a replica. No log files before this one will be needed.
* If you wish, make a backup of the log files to be deleted
* Purge all log files before (not including) the file identified above.

 Binary Log Format
-----------------

 There are three formats for the binary log. The default is statement-based logging, while row-based logging and a mix of the two formats are also possible. See [Binary Log Formats](../binary-log-formats/index) for a full discussion.

 Selectively Logging to the Binary Log
-------------------------------------

 By default, all changes to data or data structure are logged. This behavior can be changed by starting the server with the `--binlog-ignore-db=database_name` or `--binlog-do-db=database_name` [options](../mysqld-options-full-list/index).

 `--binlog-ignore-db=database_name` specified a database to ignore for logging purposes, while `--binlog-do-db=database_name` will not log any statements unless they apply to the specified database.

 
Neither option accepts comma-delimited lists of multiple databases as an option, since a database name can contain a comma. To apply to multiple databases, use the option multiple times.

 
`--binlog-ignore-db=database_name` behaves differently depending on whether statement-based or row-based logging is used. For statement-based logging, the server will not log any statement where the *default database* is database\_name. The default database is set with the [USE](../use/index) statement.

 Similarly, `--binlog-do-db=database_name` also behaves differently depending on whether statement-based or row-based logging is used. 

 For statement-based logging, the server will only log statement where the *default database* is database\_name. The default database is set with the [USE](../use/index) statement.

 For row-based logging, the server will log any updates to any tables in the named database/s, irrespective of the current database.

 ### Examples

 Assume the server has started with the option `--binlog-ignore-db=employees`. The following example *is* logged if statement-based logging is used, and *is not* logged with row-based logging.

 
```
USE customers;
UPDATE employees.details SET bonus=bonus*1.2;

```

This is because statement-based logging examines the default database, in this case, `customers`. Since `customers` is not specified in the ignore list, the statement will be logged. If row-based logging is used, the example will not be logged as updates are written to the tables in the `employees` database.

 Assume instead the server started with the option `--binlog-do-db=employees`. The following example *is not* logged if statement-based logging is used, and *is* logged with row-based logging.

 
```
USE customers;
UPDATE employees.details SET bonus=bonus*1.2;

```

This is again because statement-based logging examines the default database, in this case, `customers`. Since `customers` is not specified in the do list, the statement will not be logged. If row-based logging is used, the example will be logged as updates are written to the tables in the `employees` database.

 Effects of Full Disk Errors on Binary Logging
---------------------------------------------

 If MariaDB encounters a full disk error while trying to write to a binary log file, then it will keep retrying the write every 60 seconds. Log messages will get written to the error log every 600 seconds. For example:

 
```
2018-11-27  2:46:46 140278181563136 [Warning] mysqld: Disk is full writing '/var/lib/mariadb-bin.00001' (Errcode: 28 "No space left on device"). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space)
2018-11-27  2:46:46 140278181563136 [Warning] mysqld: Retry in 60 secs. Message reprinted in 600 secs

```

However, if MariaDB encounters a full disk error while trying to open a new binary log file, then it will disable binary logging entirely. A log message like the following will be written to the error log:

 
```
2018-11-27  3:30:49 140278181563136 [ERROR] Could not open '/var/lib/mariadb-bin.00002 for logging (error 28). Turning logging off for the whole duration of the MySQL server process. To turn it on again: fix the cause, shutdown the MySQL server and restart it.
2018-11-27  3:30:49 140278181563136 [ERROR] mysqld: Error writing file '(null)' (errno: 9 "Bad file descriptor")
2018-11-27  3:30:49 140278181563136 [ERROR] mysqld: Error writing file '(null)' (errno: 28 "No space left on device")

```

See Also
--------

 * [PURGE LOGS](../sql-commands-purge-logs/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-and-maintaining-the-binary-log/>

SET SQL\_LOG\_BIN
=================

    Syntax
------

 
```
SET [SESSION] sql_log_bin = {0|1}

```

Description
-----------

 Sets the [sql\_log\_bin](../replication-and-binary-log-system-variables/index#sql_log_bin) system variable, which disables or enables [binary logging](../binary-log/index) for the current connection, if the client has the `SUPER` [privilege](../grant/index). The statement is refused with an error if the client does not have that privilege.

 Before [MariaDB 5.5](../what-is-mariadb-55/index) and before MySQL 5.6 one could also set `sql_log_bin` as a global variable. This was disabled as this was too dangerous as it could damage replication.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/set-sql_log_bin/>

MyRocks and START TRANSACTION WITH CONSISTENT SNAPSHOT
======================================================

    FB/MySQL has added new syntax:

 
```
START TRANSACTION WITH CONSISTENT ROCKSDB|INNODB SNAPSHOT;

```

The statement returns the binlog coordinates pointing at the snapshot.

 MariaDB (and Percona Server) support extension to the regular 

 
```
START TRANSACTION WITH CONSISTENT SNAPSHOT;

```

syntax as documented in [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index).

 After issuing the statement, one can examine the [binlog\_snapshot\_file](../replication-and-binary-log-status-variables/index#binlog_snapshot_file) and [binlog\_snapshot\_position](../replication-and-binary-log-status-variables/index#binlog_snapshot_position) status variables to see the binlog position that corresponds to the snapshot.

 See Also
--------

 * [START TRANSACTION](../start-transaction/index)
* [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent-snapshot/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-start-transaction-with-consistent-snapshot/>

Compressing Events to Reduce Size of the Binary Log
===================================================

    Selected events in the [binary log](../binary-log/index) can be optionally compressed, to save space in the binary log on disk and in network transfers.

 The events that can be compressed are the events that normally can be of a significant size: Query events (for DDL and DML in [statement-based](../binary-log-formats/index#statement-based) [replication](../standard-replication/index)), and row events (for DML in [row-based](../binary-log-formats/index#row-based) [replication](../standard-replication/index)).

 Compression is fully transparent. Events are compressed on the primary before being written into the binary log, and are uncompressed by the I/O thread on the replica before being written into the relay log. The [mariadb-binlog](../mariadb-binlog/index) command will likewise uncompress events for its output.

 Currently, the zlib compression algorithm is used to compress events.

 Compression will have the most impact when events are of a non-negligible size, as each event is compressed individually. For example, batch INSERT statements that insert many rows or large values, or row-based events that touch a number of rows in one query.

 The [log\_bin\_compress](../replication-and-binary-log-server-system-variables/index#log_bin_compress) option is used to enable compression of events. Only events with data (query text or row data) above a certain size are compressed; the limit is set with the [log\_bin\_compress\_min\_len](../replication-and-binary-log-server-system-variables/index#log_bin_compress_min_len) option.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compressing-events-to-reduce-size-of-the-binary-log/>

Using MariaDB Replication with MariaDB Galera Cluster
=====================================================

    [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index) and [MariaDB Galera Cluster](../galera-cluster/index) can be used together. However, there are some things that have to be taken into account.

 Tutorials
---------

 If you want to use [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index) and [MariaDB Galera Cluster](../galera-cluster/index) together, then the following tutorials may be useful:

 * [Configuring MariaDB Replication between MariaDB Galera Cluster and MariaDB Server](../using-mariadb-replication-with-mariadb-galera-cluster-configuring-mariadb-r/index)
* [Configuring MariaDB Replication between Two MariaDB Galera Clusters](../configuring-mariadb-replication-between-two-mariadb-galera-clusters/index)

 Configuring a Cluster Node as a Replication Master
--------------------------------------------------

 If a Galera Cluster node is also a [replication master](../replication-overview/index), then some additional configuration may be needed.

 Like with [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index), write sets that are received by a node with [Galera Cluster's certification-based replication](../about-galera-replication/index) are not written to the [binary log](../binary-log/index) by default.

 If the node is a replication master, then its replication slaves only replicate transactions which are in the binary log, so this means that the transactions that correspond to Galera Cluster write-sets would not be replicated by any replication slaves by default. If you would like a node to write its replicated write sets to the [binary log](../binary-log/index), then you will have to set `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)`. If the node has any replication slaves, then this would also allow those slaves to replicate the transactions that corresponded to those write sets.

 See [Configuring MariaDB Galera Cluster: Writing Replicated Write Sets to the Binary Log](../configuring-mariadb-galera-cluster/index#writing-replicated-write-sets-to-the-binary-log) for more information.

 Configuring a Cluster Node as a Replication Slave
-------------------------------------------------

 If a Galera Cluster node is also a [replication slave](../replication-overview/index), then some additional configuration may be needed.

 If the node is a replication slave, then the node's [slave SQL thread](../replication-threads/index#slave-sql-thread) will be applying transactions that it replicates from its replication master. Transactions applied by the slave SQL thread will only generate Galera Cluster write-sets if the node has `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` set. Therefore, in order to replicate these transactions to the rest of the nodes in the cluster, `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` must be set.

 If the node is a replication slave, then it is probably also a good idea to enable `[wsrep\_restart\_slave](../galera-cluster-system-variables/index#wsrep_restart_slave)`. When this is enabled, the node will restart its [slave threads](../replication-threads/index#threads-on-the-slave) whenever it rejoins the cluster.

 Replication Filters
-------------------

 Both [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index) and [MariaDB Galera Cluster](../galera-cluster/index) support [replication filters](../replication-filters/index), so extra caution must be taken when using all of these features together. See [Configuring MariaDB Galera Cluster: Replication Filters](../configuring-mariadb-galera-cluster/index#replication-filters) for more details on how MariaDB Galera Cluster interprets replication filters.

 Setting server\_id on Cluster Nodes
-----------------------------------

 ### Setting the Same server\_id on Each Cluster Node

 It is most common to set `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` to the same value on each node in a given cluster. Since [MariaDB Galera Cluster](../galera-cluster/index) uses a [virtually synchronous certification-based replication](../about-galera-replication/index), all nodes should have the same data, so in a logical sense, a cluster can be considered in many cases a single logical server for purposes related to [MariaDB replication](../high-availability-performance-tuning-mariadb-replication/index). The [binary logs](../binary-log/index) of each cluster node might even contain roughly the same transactions and [GTIDs](../gtid/index) if `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` is set and if [wsrep GTID mode](../using-mariadb-gtids-with-mariadb-galera-cluster/index#wsrep-gtid-mode) is enabled and if non-Galera transactions are not being executed on any nodes.

 ### Setting a Different server\_id on Each Cluster Node

 There are cases when it might make sense to set a different `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` value on each node in a given cluster. For example, if `[log\_slave\_updates=OFF](../replication-and-binary-log-system-variables/index#log_slave_updates)` is set and if another cluster or a standard MariaDB Server is using [multi-source replication](../multi-source-replication/index) to replicate transactions from each cluster node individually, then it would be required to set a different `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` value on each node for this to work.

 Keep in mind that if replication is set up in a scenario where each cluster node has a different `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` value, and if the replication topology is set up in such a way that a cluster node can replicate the same transactions through Galera and through MariaDB replication, then you may need to configure the cluster node to ignore these transactions when setting up MariaDB replication. You can do so by setting `[IGNORE\_SERVER\_IDS](../change-master-to/index#ignore_server_ids)` to the server IDs of all nodes in the same cluster when executing `[CHANGE MASTER TO](../change-master-to/index)`. For example, this might be required when circular replication is set up between two separate clusters, and each cluster node as a different `[server\_id](../replication-and-binary-log-system-variables/index#server_id)` value, and each cluster has `[log\_slave\_updates=ON](../replication-and-binary-log-system-variables/index#log_slave_updates)` set.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-replication-with-mariadb-galera-cluster-using-mariadb-replica/>

Flashback
=========

    Flashback is a feature that allows instances, databases or tables to be rolled back to an old snapshot. 

 Flashback is currently supported only over DML statements ([INSERT](../insert/index), [DELETE](../delete/index), [UPDATE](../update/index)). An upcoming version of MariaDB will add support for flashback over DDL statements ([DROP](../drop-table/index), [TRUNCATE](../truncate-table/index), [ALTER](../alter-table/index), etc.) by copying or moving the current table to a reserved and hidden database, and then copying or moving back when using flashback. See [MDEV-10571](https://jira.mariadb.org/browse/MDEV-10571).

 Flashback is achieved in MariaDB Server using existing support for full image format binary logs ([binlog\_row\_image=FULL](../replication-and-binary-log-system-variables/index#binlog_row_image)), so it supports all engines.

 The real work of Flashback is done by [mariadb-binlog](../mariadb-binlog/index) with `--flashback`. This causes events to be translated: INSERT to DELETE, DELETE to INSERT, and for UPDATEs, the before and after images are swapped.

 When executing `mariadb-binlog` with `--flashback`, the Flashback events will be stored in memory. You should make sure your server has enough memory for this feature.

 Arguments
---------

 * [mariadb-binlog](../mariadb-binlog/index) has the option `--flashback` or `-B` that will let it work in flashback mode.
* [mariadbd / mysqld](../mysqld-options/index) has the option [--flashback](../mysqld-options/index#-flashback) that enables the binary log and sets `binlog_format=ROW`. It is not mandatory to use this option if you have already enabled those options directly.

 
Do not use `-v` `-vv` options, as this adds verbose information to the binary log which can cause problems when importing. See [MDEV-12066](https://jira.mariadb.org/browse/MDEV-12066) and [MDEV-12067](https://jira.mariadb.org/browse/MDEV-12067).

 
Example
-------

 With a table "mytable" in database "test", you can compare the output with `--flashback` and without.

 
```
 mariadb-binlog /var/lib/mysql/mysql-bin.000001 -vv -d test -T mytable \
    --start-datetime="2013-03-27 14:54:00" > review.sql

```


```
 mariadb-binlog /var/lib/mysql/mysql-bin.000001 -vv -d test -T mytable \
    --start-datetime="2013-03-27 14:54:00" --flashback > flashback.sql

```

If you know the exact position, `--start-position` can be used instead of `--start-datetime`.

 Then, by importing the output file (`mysql < flashback.sql`), you can flash your database/table back to the specified time or position.

 Common Use Case
---------------

 A common use case for Flashback is the following scenario:

 * You have one primary and two replicas, one started with `--flashback` (i.e. with binary logging enabled, using [binlog\_format=ROW](../replication-and-binary-log-system-variables/index#binlog_format), and [binlog\_row\_image=FULL](../replication-and-binary-log-system-variables/index#binlog_row_image)).
* Something goes wrong on the primary (like a wrong update or delete) and you would like to revert to a state of the database (or just a table) at a certain point in time.
* Remove the flashback-enabled replica from replication.
* Invoke [mariadb-binlog](../mariadb-binlog/index) to find the exact log position of the first offending operation after the state you want to revert to.
* Run `mariadb-binlog --flashback --start-position=xyz | mysql` to pipe the output of `mariadb-binlog` directly to the `mariadb` client, or save the output to a file and then direct the file to the command-line client.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/flashback/>

MariaDB Error Codes
===================

    MariaDB shares error codes with MySQL, as well as adding a number of new error codes specific to MariaDB.

 An example of an error code is as follows:

 
```
SELECT * FROM x;
ERROR 1046 (3D000): No database selected

```

 There are three pieces of information returned in an error:

 * A numeric error code, in this case `1046`. Error codes from 1900 and up are specific to MariaDB, while error codes from 1000 to 1800 are shared by MySQL and MariaDB.
* An [SQLSTATE](../sqlstate/index) value, consisting of five characters, in this case `3D000`. These codes are standard to ODBC and ANSI SQL. When MariaDB cannot allocate a standard SQLSTATE code, a generic `HY000`, or general error, is used.
* A string describing the error, in this case `No database selected`.

 New error codes are being continually being added as new features are added. For a definitive list, see the file `sql/share/errmsg-utf8.txt`, as well as `include/mysqld_error.h` in the build directory, generated by the `comp_err` tool. Also, the [perror](../perror/index) tool can be used to get the error message which is associated with a given error code.

 Shared MariaDB/MySQL error codes
--------------------------------

 


| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1000 | HY000 | ER\_HASHCHK | hashchk |
| 1001 | HY000 | ER\_NISAMCHK | isamchk |
| 1002 | HY000 | ER\_NO | NO |
| 1003 | HY000 | ER\_YES | YES |
| 1004 | HY000 | ER\_CANT\_CREATE\_FILE | Can't create file '%s' (errno: %d) |
| 1005 | HY000 | ER\_CANT\_CREATE\_TABLE | Can't create table '%s' (errno: %d) |
| 1006 | HY000 | ER\_CANT\_CREATE\_DB | Can't create database '%s' (errno: %d |
| 1007 | HY000 | ER\_DB\_CREATE\_EXISTS | Can't create database '%s'; database exists |
| 1008 | HY000 | ER\_DB\_DROP\_EXISTS | Can't drop database '%s'; database doesn't exist |
| 1009 | HY000 | ER\_DB\_DROP\_DELETE | Error dropping database (can't delete '%s', errno: %d) |
| 1010 | HY000 | ER\_DB\_DROP\_RMDIR | Error dropping database (can't rmdir '%s', errno: %d) |
| 1011 | HY000 | ER\_CANT\_DELETE\_FILE | Error on delete of '%s' (errno: %d) |
| 1012 | HY000 | ER\_CANT\_FIND\_SYSTEM\_REC | Can't read record in system table |
| 1013 | HY000 | ER\_CANT\_GET\_STAT | Can't get status of '%s' (errno: %d) |
| 1014 | HY000 | ER\_CANT\_GET\_WD | Can't get working directory (errno: %d) |
| 1015 | HY000 | ER\_CANT\_LOCK | Can't lock file (errno: %d) |
| 1016 | HY000 | ER\_CANT\_OPEN\_FILE | Can't open file: '%s' (errno: %d) |
| 1017 | HY000 | ER\_FILE\_NOT\_FOUND | Can't find file: '%s' (errno: %d) |
| 1018 | HY000 | ER\_CANT\_READ\_DIR | Can't read dir of '%s' (errno: %d) |
| 1019 | HY000 | ER\_CANT\_SET\_WD | Can't change dir to '%s' (errno: %d) |
| 1020 | HY000 | ER\_CHECKREAD | Record has changed since last read in table '%s' |
| 1021 | HY000 | ER\_DISK\_FULL | Disk full (%s); waiting for someone to free some space... |
| 1022 | 23000 | ER\_DUP\_KEY | Can't write; duplicate key in table '%s' |
| 1023 | HY000 | ER\_ERROR\_ON\_CLOSE | Error on close of '%s' (errno: %d) |
| 1024 | HY000 | ER\_ERROR\_ON\_READ | Error reading file '%s' (errno: %d) |
| 1025 | HY000 | ER\_ERROR\_ON\_RENAME | Error on rename of '%s' to '%s' (errno: %d) |
| 1026 | HY000 | ER\_ERROR\_ON\_WRITE | Error writing file '%s' (errno: %d) |
| 1027 | HY000 | ER\_FILE\_USED | '%s' is locked against change |
| 1028 | HY000 | ER\_FILSORT\_ABORT | Sort aborted |
| 1029 | HY000 | ER\_FORM\_NOT\_FOUND | View '%s' doesn't exist for '%s' |
| 1030 | HY000 | ER\_GET\_ERRN | Got error %d from storage engine |
| 1031 | HY000 | ER\_ILLEGAL\_HA | Table storage engine for '%s' doesn't have this option |
| 1032 | HY000 | ER\_KEY\_NOT\_FOUND | Can't find record in '%s' |
| 1033 | HY000 | ER\_NOT\_FORM\_FILE | Incorrect information in file: '%s' |
| 1034 | HY000 | ER\_NOT\_KEYFILE | Incorrect key file for table '%s'; try to repair it |
| 1035 | HY000 | ER\_OLD\_KEYFILE | Old key file for table '%s'; repair it! |
| 1036 | HY000 | ER\_OPEN\_AS\_READONLY | Table '%s' is read only |
| 1037 | HY001 | ER\_OUTOFMEMORY | Out of memory; restart server and try again (needed %d bytes) |
| 1038 | HY001 | ER\_OUT\_OF\_SORTMEMORY | Out of sort memory, consider increasing server sort buffer size |
| 1039 | HY000 | ER\_UNEXPECTED\_EOF | Unexpected EOF found when reading file '%s' (Errno: %d) |
| 1040 | 08004 | ER\_CON\_COUNT\_ERROR | Too many connections |
| 1041 | HY000 | ER\_OUT\_OF\_RESOURCES | Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space |
| 1042 | 08S01 | ER\_BAD\_HOST\_ERROR | Can't get hostname for your address |
| 1043 | 08S01 | ER\_HANDSHAKE\_ERROR | Bad handshake |
| 1044 | 42000 | ER\_DBACCESS\_DENIED\_ERROR | Access denied for user '%s'@'%s' to database '%s' |
| 1045 | 28000 | ER\_ACCESS\_DENIED\_ERROR | Access denied for user '%s'@'%s' (using password: %s) |
| 1046 | 3D000 | ER\_NO\_DB\_ERROR | No database selected |
| 1047 | 08S01 | ER\_UNKNOWN\_COM\_ERROR | Unknown command |
| 1048 | 23000 | ER\_BAD\_NULL\_ERROR | Column '%s' cannot be null |
| 1049 | 42000 | ER\_BAD\_DB\_ERROR | Unknown database '%s' |
| 1050 | 42S01 | ER\_TABLE\_EXISTS\_ERROR | Table '%s' already exists |
| 1051 | 42S02 | ER\_BAD\_TABLE\_ERROR | Unknown table '%s' |
| 1052 | 23000 | ER\_NON\_UNIQ\_ERROR | Column '%s' in %s is ambiguous |
| 1053 | 08S01 | ER\_SERVER\_SHUTDOWN | Server shutdown in progress |
| 1054 | 42S22 | ER\_BAD\_FIELD\_ERROR | Unknown column '%s' in '%s' |
| 1055 | 42000 | ER\_WRONG\_FIELD\_WITH\_GROUP | '%s' isn't in GROUP BY |
| 1056 | 42000 | ER\_WRONG\_GROUP\_FIELD | Can't group on '%s' |
| 1057 | 42000 | ER\_WRONG\_SUM\_SELECT | Statement has sum functions and columns in same statement |
| 1058 | 21S01 | ER\_WRONG\_VALUE\_COUNT | Column count doesn't match value count |
| 1059 | 42000 | ER\_TOO\_LONG\_IDENT | Identifier name '%s' is too long |
| 1060 | 42S21 | ER\_DUP\_FIELDNAME | Duplicate column name '%s' |
| 1061 | 42000 | ER\_DUP\_KEYNAME | Duplicate key name '%s' |
| 1062 | 23000 | ER\_DUP\_ENTRY | Duplicate entry '%s' for key %d |
| 1063 | 42000 | ER\_WRONG\_FIELD\_SPEC | Incorrect column specifier for column '%s' |
| 1064 | 42000 | ER\_PARSE\_ERROR | %s near '%s' at line %d |
| 1065 | 42000 | ER\_EMPTY\_QUERY | Query was empty |
| 1066 | 42000 | ER\_NONUNIQ\_TABLE | Not unique table/alias: '%s' |
| 1067 | 42000 | ER\_INVALID\_DEFAULT | Invalid default value for '%s' |
| 1068 | 42000 | ER\_MULTIPLE\_PRI\_KEY | Multiple primary key defined |
| 1069 | 42000 | ER\_TOO\_MANY\_KEYS | Too many keys specified; max %d keys allowed |
| 1070 | 42000 | ER\_TOO\_MANY\_KEY\_PARTS | Too many key parts specified; max %d parts allowed |
| 1071 | 42000 | ER\_TOO\_LONG\_KEY | Specified key was too long; max key length is %d bytes |
| 1072 | 42000 | ER\_KEY\_COLUMN\_DOES\_NOT\_EXITS | Key column '%s' doesn't exist in table |
| 1073 | 42000 | ER\_BLOB\_USED\_AS\_KEY | BLOB column '%s' can't be used in key specification with the used table type |
| 1074 | 42000 | ER\_TOO\_BIG\_FIELDLENGTH | Column length too big for column '%s' (max = %lu); use BLOB or TEXT instead |
| 1075 | 42000 | ER\_WRONG\_AUTO\_KEY | Incorrect table definition; there can be only one auto column and it must be defined as a key |
| 1076 | HY000 | ER\_READY | %s: ready for connections. Version: '%s' socket: '%s' port: %d |
| 1077 | HY000 | ER\_NORMAL\_SHUTDOWN | %s: Normal shutdown |
| 1078 | HY000 | ER\_GOT\_SIGNAL | %s: Got signal %d. Aborting! |
| 1079 | HY000 | ER\_SHUTDOWN\_COMPLETE | %s: Shutdown complete |
| 1080 | 08S01 | ER\_FORCING\_CLOSE | %s: Forcing close of thread %ld user: '%s' |
| 1081 | 08S01 | ER\_IPSOCK\_ERROR | Can't create IP socket |
| 1082 | 42S12 | ER\_NO\_SUCH\_INDEX | Table '%s' has no index like the one used in CREATE INDEX; recreate the table |
| 1083 | 42000 | ER\_WRONG\_FIELD\_TERMINATORS | Field separator argument is not what is expected; check the manual |
| 1084 | 42000 | ER\_BLOBS\_AND\_NO\_TERMINATED | You can't use fixed rowlength with BLOBs; please use 'fields terminated by' |
| 1085 | HY000 | ER\_TEXTFILE\_NOT\_READABLE | The file '%s' must be in the database directory or be readable by all |
| 1086 | HY000 | ER\_FILE\_EXISTS\_ERROR | File '%s' already exists |
| 1087 | HY000 | ER\_LOAD\_INF | Records: %ld Deleted: %ld Skipped: %ld Warnings: %ld |
| 1088 | HY000 | ER\_ALTER\_INF | Records: %ld Duplicates: %ld |
| 1089 | HY000 | ER\_WRONG\_SUB\_KEY | Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys |
| 1090 | 42000 | ER\_CANT\_REMOVE\_ALL\_FIELDS | You can't delete all columns with ALTER TABLE; use DROP TABLE instead |
| 1091 | 42000 | ER\_CANT\_DROP\_FIELD\_OR\_KEY | Can't DROP '%s'; check that column/key exists |
| 1092 | HY000 | ER\_INSERT\_INF | Records: %ld Duplicates: %ld Warnings: %ld |
| 1093 | HY000 | ER\_UPDATE\_TABLE\_USED | You can't specify target table '%s' for update in FROM clause |
| 1094 | HY000 | ER\_NO\_SUCH\_THREAD | Unknown thread id: %lu |
| 1095 | HY000 | ER\_KILL\_DENIED\_ERROR | You are not owner of thread %lu |
| 1096 | HY000 | ER\_NO\_TABLES\_USED | No tables used |
| 1097 | HY000 | ER\_TOO\_BIG\_SET | Too many strings for column %s and SET |
| 1098 | HY000 | ER\_NO\_UNIQUE\_LOGFILE | Can't generate a unique log-filename %s.(1-999) |
| 1099 | HY000 | ER\_TABLE\_NOT\_LOCKED\_FOR\_WRITE | Table '%s' was locked with a READ lock and can't be updated |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1100 | HY000 | ER\_TABLE\_NOT\_LOCKED | Table '%s' was not locked with LOCK TABLES |
| 1101 |  | ER\_UNUSED\_17 | You should never see it |
| 1102 | 42000 | ER\_WRONG\_DB\_NAME | Incorrect database name '%s' |
| 1103 | 42000 | ER\_WRONG\_TABLE\_NAME | Incorrect table name '%s' |
| 1104 | 42000 | ER\_TOO\_BIG\_SELECT | The SELECT would examine more than MAX\_JOIN\_SIZE rows; check your WHERE and use SET SQL\_BIG\_SELECTS=1 or SET MAX\_JOIN\_SIZE=# if the SELECT is okay |
| 1105 | HY000 | ER\_UNKNOWN\_ERROR | Unknown error |
| 1106 | 42000 | ER\_UNKNOWN\_PROCEDURE | Unknown procedure '%s' |
| 1107 | 42000 | ER\_WRONG\_PARAMCOUNT\_TO\_PROCEDURE | Incorrect parameter count to procedure '%s' |
| 1108 | HY000 | ER\_WRONG\_PARAMETERS\_TO\_PROCEDURE | Incorrect parameters to procedure '%s' |
| 1109 | 42S02 | ER\_UNKNOWN\_TABLE | Unknown table '%s' in %s |
| 1110 | 42000 | ER\_FIELD\_SPECIFIED\_TWICE | Column '%s' specified twice |
| 1111 | HY000 | ER\_INVALID\_GROUP\_FUNC\_USE | Invalid use of group function |
| 1112 | 42000 | ER\_UNSUPPORTED\_EXTENSION | Table '%s' uses an extension that doesn't exist in this MariaDB version |
| 1113 | 42000 | ER\_TABLE\_MUST\_HAVE\_COLUMNS | A table must have at least 1 column |
| 1114 | HY000 | ER\_RECORD\_FILE\_FULL | The table '%s' is full |
| 1115 | 42000 | ER\_UNKNOWN\_CHARACTER\_SET | Unknown character set: '%s' |
| 1116 | HY000 | ER\_TOO\_MANY\_TABLES | Too many tables; MariaDB can only use %d tables in a join |
| 1117 | HY000 | ER\_TOO\_MANY\_FIELDS | Too many columns |
| 1118 | 42000 | ER\_TOO\_BIG\_ROWSIZE | Row size too large. The maximum row size for the used table type, not counting BLOBs, is %ld. You have to change some columns to TEXT or BLOBs |
| 1119 | HY000 | ER\_STACK\_OVERRUN | Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld --thread\_stack=#' to specify a bigger stack if needed |
| 1120 | 42000 | ER\_WRONG\_OUTER\_JOIN | Cross dependency found in OUTER JOIN; examine your ON conditions |
| 1121 | 42000 | ER\_NULL\_COLUMN\_IN\_INDEX | Table handler doesn't support NULL in given index. Please change column '%s' to be NOT NULL or use another handler |
| 1122 | HY000 | ER\_CANT\_FIND\_UDF | Can't load function '%s' |
| 1123 | HY000 | ER\_CANT\_INITIALIZE\_UDF | Can't initialize function '%s'; %s |
| 1124 | HY000 | ER\_UDF\_NO\_PATHS | No paths allowed for shared library |
| 1125 | HY000 | ER\_UDF\_EXISTS | Function '%s' already exists |
| 1126 | HY000 | ER\_CANT\_OPEN\_LIBRARY | Can't open shared library '%s' (Errno: %d %s) |
| 1127 | HY000 | ER\_CANT\_FIND\_DL\_ENTRY | Can't find symbol '%s' in library |
| 1128 | HY000 | ER\_FUNCTION\_NOT\_DEFINED | Function '%s' is not defined |
| 1129 | HY000 | ER\_HOST\_IS\_BLOCKED | Host '%s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' |
| 1130 | HY000 | ER\_HOST\_NOT\_PRIVILEGED | Host '%s' is not allowed to connect to this MariaDB server |
| 1131 | 42000 | ER\_PASSWORD\_ANONYMOUS\_USER | You are using MariaDB as an anonymous user and anonymous users are not allowed to change passwords |
| 1132 | 42000 | ER\_PASSWORD\_NOT\_ALLOWED | You must have privileges to update tables in the mysql database to be able to change passwords for others |
| 1133 | 42000 | ER\_PASSWORD\_NO\_MATCH | Can't find any matching row in the user table |
| 1134 | HY000 | ER\_UPDATE\_INF | Rows matched: %ld Changed: %ld Warnings: %ld |
| 1135 | HY000 | ER\_CANT\_CREATE\_THREAD | Can't create a new thread (Errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug |
| 1136 | 21S01 | ER\_WRONG\_VALUE\_COUNT\_ON\_ROW | Column count doesn't match value count at row %ld |
| 1137 | HY000 | ER\_CANT\_REOPEN\_TABLE | Can't reopen table: '%s' |
| 1138 | 22004 | ER\_INVALID\_USE\_OF\_NULL | Invalid use of NULL value |
| 1139 | 42000 | ER\_REGEXP\_ERROR | Got error '%s' from regexp |
| 1140 | 42000 | ER\_MIX\_OF\_GROUP\_FUNC\_AND\_FIELDS | Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause |
| 1141 | 42000 | ER\_NONEXISTING\_GRANT | There is no such grant defined for user '%s' on host '%s' |
| 1142 | 42000 | ER\_TABLEACCESS\_DENIED\_ERROR | %s command denied to user '%s'@'%s' for table '%s' |
| 1143 | 42000 | ER\_COLUMNACCESS\_DENIED\_ERROR | %s command denied to user '%s'@'%s' for column '%s' in table '%s' |
| 1144 | 42000 | ER\_ILLEGAL\_GRANT\_FOR\_TABLE | Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used |
| 1145 | 42000 | ER\_GRANT\_WRONG\_HOST\_OR\_USER | The host or user argument to GRANT is too long |
| 1146 | 42S02 | ER\_NO\_SUCH\_TABLE | Table '%s.%s' doesn't exist |
| 1147 | 42000 | ER\_NONEXISTING\_TABLE\_GRANT | There is no such grant defined for user '%s' on host '%s' on table '%s' |
| 1148 | 42000 | ER\_NOT\_ALLOWED\_COMMAND | The used command is not allowed with this MariaDB version |
| 1149 | 42000 | ER\_SYNTAX\_ERROR | You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use |
| 1150 | HY000 | ER\_DELAYED\_CANT\_CHANGE\_LOCK | Delayed insert thread couldn't get requested lock for table %s |
| 1151 | HY000 | ER\_TOO\_MANY\_DELAYED\_THREADS | Too many delayed threads in use |
| 1152 | 08S01 | ER\_ABORTING\_CONNECTION | Aborted connection %ld to db: '%s' user: '%s' (%s) |
| 1153 | 08S01 | ER\_NET\_PACKET\_TOO\_LARGE | Got a packet bigger than 'max\_allowed\_packet' bytes |
| 1154 | 08S01 | ER\_NET\_READ\_ERROR\_FROM\_PIPE | Got a read error from the connection pipe |
| 1155 | 08S01 | ER\_NET\_FCNTL\_ERROR | Got an error from fcntl() |
| 1156 | 08S01 | ER\_NET\_PACKETS\_OUT\_OF\_ORDER | Got packets out of order |
| 1157 | 08S01 | ER\_NET\_UNCOMPRESS\_ERROR | Couldn't uncompress communication packet |
| 1158 | 08S01 | ER\_NET\_READ\_ERROR | Got an error reading communication packets |
| 1159 | 08S01 | ER\_NET\_READ\_INTERRUPTED | Got timeout reading communication packets |
| 1160 | 08S01 | ER\_NET\_ERROR\_ON\_WRITE | Got an error writing communication packets |
| 1161 | 08S01 | ER\_NET\_WRITE\_INTERRUPTED | Got timeout writing communication packets |
| 1162 | 42000 | ER\_TOO\_LONG\_STRING | Result string is longer than 'max\_allowed\_packet' bytes |
| 1163 | 42000 | ER\_TABLE\_CANT\_HANDLE\_BLOB | The used table type doesn't support BLOB/TEXT columns |
| 1164 | 42000 | ER\_TABLE\_CANT\_HANDLE\_AUTO\_INCREMENT | The used table type doesn't support AUTO\_INCREMENT columns |
| 1165 | HY000 | ER\_DELAYED\_INSERT\_TABLE\_LOCKED | INSERT DELAYED can't be used with table '%s' because it is locked with LOCK TABLES |
| 1166 | 42000 | ER\_WRONG\_COLUMN\_NAME | Incorrect column name '%s' |
| 1167 | 42000 | ER\_WRONG\_KEY\_COLUMN | The used storage engine can't index column '%s' |
| 1168 | HY000 | ER\_WRONG\_MRG\_TABLE | Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist |
| 1169 | 23000 | ER\_DUP\_UNIQUE | Can't write, because of unique constraint, to table '%s' |
| 1170 | 42000 | ER\_BLOB\_KEY\_WITHOUT\_LENGTH | BLOB/TEXT column '%s' used in key specification without a key length |
| 1171 | 42000 | ER\_PRIMARY\_CANT\_HAVE\_NULL | All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead |
| 1172 | 42000 | ER\_TOO\_MANY\_ROWS | Result consisted of more than one row |
| 1173 | 42000 | ER\_REQUIRES\_PRIMARY\_KEY | This table type requires a primary key |
| 1174 | HY000 | ER\_NO\_RAID\_COMPILED | This version of MariaDB is not compiled with RAID support |
| 1175 | HY000 | ER\_UPDATE\_WITHOUT\_KEY\_IN\_SAFE\_MODE | You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column |
| 1176 | 42000 | ER\_KEY\_DOES\_NOT\_EXITS | Key '%s' doesn't exist in table '%s' |
| 1177 | 42000 | ER\_CHECK\_NO\_SUCH\_TABLE | Can't open table |
| 1178 | 42000 | ER\_CHECK\_NOT\_IMPLEMENTED | The storage engine for the table doesn't support %s |
| 1179 | 25000 | ER\_CANT\_DO\_THIS\_DURING\_AN\_TRANSACTION | You are not allowed to execute this command in a transaction |
| 1180 | HY000 | ER\_ERROR\_DURING\_COMMIT | Got error %d during COMMIT |
| 1181 | HY000 | ER\_ERROR\_DURING\_ROLLBACK | Got error %d during ROLLBACK |
| 1182 | HY000 | ER\_ERROR\_DURING\_FLUSH\_LOGS | Got error %d during FLUSH\_LOGS |
| 1183 | HY000 | ER\_ERROR\_DURING\_CHECKPOINT | Got error %d during CHECKPOINT |
| 1184 | 08S01 | ER\_NEW\_ABORTING\_CONNECTION | Aborted connection %ld to db: '%s' user: '%s' host: '%s' (%s) |
| 1185 |  | ER\_UNUSED\_10 | You should never see it |
| 1186 | HY000 | ER\_FLUSH\_MASTER\_BINLOG\_CLOSED | Binlog closed, cannot RESET MASTER |
| 1187 | HY000 | ER\_INDEX\_REBUILD | Failed rebuilding the index of dumped table '%s' |
| 1188 | HY000 | ER\_MASTER | Error from master: '%s' |
| 1189 | 08S01 | ER\_MASTER\_NET\_READ | Net error reading from master |
| 1190 | 08S01 | ER\_MASTER\_NET\_WRITE | Net error writing to master |
| 1191 | HY000 | ER\_FT\_MATCHING\_KEY\_NOT\_FOUND | Can't find FULLTEXT index matching the column list |
| 1192 | HY000 | ER\_LOCK\_OR\_ACTIVE\_TRANSACTION | Can't execute the given command because you have active locked tables or an active transaction |
| 1193 | HY000 | ER\_UNKNOWN\_SYSTEM\_VARIABLE | Unknown system variable '%s' |
| 1194 | HY000 | ER\_CRASHED\_ON\_USAGE | Table '%s' is marked as crashed and should be repaired |
| 1195 | HY000 | ER\_CRASHED\_ON\_REPAIR | Table '%s' is marked as crashed and last (automatic?) repair failed |
| 1196 | HY000 | ER\_WARNING\_NOT\_COMPLETE\_ROLLBACK | Some non-transactional changed tables couldn't be rolled back |
| 1197 | HY000 | ER\_TRANS\_CACHE\_FULL | Multi-statement transaction required more than 'max\_binlog\_cache\_size' bytes of storage; increase this mysqld variable and try again |
| 1198 | HY000 | ER\_SLAVE\_MUST\_STOP | This operation cannot be performed with a running slave; run STOP SLAVE first |
| 1199 | HY000 | ER\_SLAVE\_NOT\_RUNNING | This operation requires a running slave; configure slave and do START SLAVE |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1200 | HY000 | ER\_BAD\_SLAVE | The server is not configured as slave; fix in config file or with CHANGE MASTER TO |
| 1201 | HY000 | ER\_MASTER\_INFO | Could not initialize master info structure; more error messages can be found in the MariaDB error log |
| 1202 | HY000 | ER\_SLAVE\_THREAD | Could not create slave thread; check system resources |
| 1203 | 42000 | ER\_TOO\_MANY\_USER\_CONNECTIONS | User %s already has more than 'max\_user\_connections' active connections |
| 1204 | HY000 | ER\_SET\_CONSTANTS\_ONLY | You may only use constant expressions with SET |
| 1205 | HY000 | ER\_LOCK\_WAIT\_TIMEOUT | Lock wait timeout exceeded; try restarting transaction |
| 1206 | HY000 | ER\_LOCK\_TABLE\_FULL | The total number of locks exceeds the lock table size |
| 1207 | 25000 | ER\_READ\_ONLY\_TRANSACTION | Update locks cannot be acquired during a READ UNCOMMITTED transaction |
| 1208 | HY000 | ER\_DROP\_DB\_WITH\_READ\_LOCK | DROP DATABASE not allowed while thread is holding global read lock |
| 1209 | HY000 | ER\_CREATE\_DB\_WITH\_READ\_LOCK | CREATE DATABASE not allowed while thread is holding global read lock |
| 1210 | HY000 | ER\_WRONG\_ARGUMENTS | Incorrect arguments to %s |
| 1211 | 42000 | ER\_NO\_PERMISSION\_TO\_CREATE\_USER | '%s'@'%s' is not allowed to create new users |
| 1212 | HY000 | ER\_UNION\_TABLES\_IN\_DIFFERENT\_DIR | Incorrect table definition; all MERGE tables must be in the same database |
| 1213 | 40001 | ER\_LOCK\_DEADLOCK | Deadlock found when trying to get lock; try restarting transaction |
| 1214 | HY000 | ER\_TABLE\_CANT\_HANDLE\_FT | The used table type doesn't support FULLTEXT indexes |
| 1215 | HY000 | ER\_CANNOT\_ADD\_FOREIGN | Cannot add foreign key constraint |
| 1216 | 23000 | ER\_NO\_REFERENCED\_ROW | Cannot add or update a child row: a foreign key constraint fails |
| 1217 | 23000 | ER\_ROW\_IS\_REFERENCED | Cannot delete or update a parent row: a foreign key constraint fails |
| 1218 | 08S01 | ER\_CONNECT\_TO\_MASTER | Error connecting to master: %s |
| 1219 | HY000 | ER\_QUERY\_ON\_MASTER | Error running query on master: %s |
| 1220 | HY000 | ER\_ERROR\_WHEN\_EXECUTING\_COMMAND | Error when executing command %s: %s |
| 1221 | HY000 | ER\_WRONG\_USAGE | Incorrect usage of %s and %s |
| 1222 | 21000 | ER\_WRONG\_NUMBER\_OF\_COLUMNS\_IN\_SELECT | The used SELECT statements have a different number of columns |
| 1223 | HY000 | ER\_CANT\_UPDATE\_WITH\_READLOCK | Can't execute the query because you have a conflicting read lock |
| 1224 | HY000 | ER\_MIXING\_NOT\_ALLOWED | Mixing of transactional and non-transactional tables is disabled |
| 1225 | HY000 | ER\_DUP\_ARGUMENT | Option '%s' used twice in statement |
| 1226 | 42000 | ER\_USER\_LIMIT\_REACHED | User '%s' has exceeded the '%s' resource (current value: %ld) |
| 1227 | 42000 | ER\_SPECIFIC\_ACCESS\_DENIED\_ERROR | Access denied; you need (at least one of) the %s privilege(s) for this operation |
| 1228 | HY000 | ER\_LOCAL\_VARIABLE | Variable '%s' is a SESSION variable and can't be used with SET GLOBAL |
| 1229 | HY000 | ER\_GLOBAL\_VARIABLE | Variable '%s' is a GLOBAL variable and should be set with SET GLOBAL |
| 1230 | 42000 | ER\_NO\_DEFAULT | Variable '%s' doesn't have a default value |
| 1231 | 42000 | ER\_WRONG\_VALUE\_FOR\_VAR | Variable '%s' can't be set to the value of '%s' |
| 1232 | 42000 | ER\_WRONG\_TYPE\_FOR\_VAR | Incorrect argument type to variable '%s' |
| 1233 | HY000 | ER\_VAR\_CANT\_BE\_READ | Variable '%s' can only be set, not read |
| 1234 | 42000 | ER\_CANT\_USE\_OPTION\_HERE | Incorrect usage/placement of '%s' |
| 1235 | 42000 | ER\_NOT\_SUPPORTED\_YET | This version of MariaDB doesn't yet support '%s' |
| 1236 | HY000 | ER\_MASTER\_FATAL\_ERROR\_READING\_BINLOG | Got fatal error %d from master when reading data from binary log: '%s' |
| 1237 | HY000 | ER\_SLAVE\_IGNORED\_TABLE | Slave SQL thread ignored the query because of replicate-\*-table rules |
| 1238 | HY000 | ER\_INCORRECT\_GLOBAL\_LOCAL\_VAR | Variable '%s' is a %s variable |
| 1239 | 42000 | ER\_WRONG\_FK\_DEF | Incorrect foreign key definition for '%s': %s |
| 1240 | HY000 | ER\_KEY\_REF\_DO\_NOT\_MATCH\_TABLE\_REF | Key reference and table reference don't match |
| 1241 | 21000 | ER\_OPERAND\_COLUMNS | Operand should contain %d column(s) |
| 1242 | 21000 | ER\_SUBQUERY\_NO\_1\_ROW | Subquery returns more than 1 row |
| 1243 | HY000 | ER\_UNKNOWN\_STMT\_HANDLER | Unknown prepared statement handler (%.\*s) given to %s |
| 1244 | HY000 | ER\_CORRUPT\_HELP\_DB | Help database is corrupt or does not exist |
| 1245 | HY000 | ER\_CYCLIC\_REFERENCE | Cyclic reference on subqueries |
| 1246 | HY000 | ER\_AUTO\_CONVERT | Converting column '%s' from %s to %s |
| 1247 | 42S22 | ER\_ILLEGAL\_REFERENCE | Reference '%s' not supported (%s) |
| 1248 | 42000 | ER\_DERIVED\_MUST\_HAVE\_ALIAS | Every derived table must have its own alias |
| 1249 | 01000 | ER\_SELECT\_REDUCED | Select %u was reduced during optimization |
| 1250 | 42000 | ER\_TABLENAME\_NOT\_ALLOWED\_HERE | Table '%s' from one of the SELECTs cannot be used in %s |
| 1251 | 08004 | ER\_NOT\_SUPPORTED\_AUTH\_MODE | Client does not support authentication protocol requested by server; consider upgrading MariaDB client |
| 1252 | 42000 | ER\_SPATIAL\_CANT\_HAVE\_NULL | All parts of a SPATIAL index must be NOT NULL |
| 1253 | 42000 | ER\_COLLATION\_CHARSET\_MISMATCH | COLLATION '%s' is not valid for CHARACTER SET '%s' |
| 1254 | HY000 | ER\_SLAVE\_WAS\_RUNNING | Slave is already running |
| 1255 | HY000 | ER\_SLAVE\_WAS\_NOT\_RUNNING | Slave already has been stopped |
| 1256 | HY000 | ER\_TOO\_BIG\_FOR\_UNCOMPRESS | Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted) |
| 1257 | HY000 | ER\_ZLIB\_Z\_MEM\_ERROR | ZLIB: Not enough memory |
| 1258 | HY000 | ER\_ZLIB\_Z\_BUF\_ERROR | ZLIB: Not enough room in the output buffer (probably, length of uncompressed data was corrupted) |
| 1259 | HY000 | ER\_ZLIB\_Z\_DATA\_ERROR | ZLIB: Input data corrupted |
| 1260 | HY000 | ER\_CUT\_VALUE\_GROUP\_CONCAT | Row %u was cut by GROUP\_CONCAT() |
| 1261 | 01000 | ER\_WARN\_TOO\_FEW\_RECORDS | Row %ld doesn't contain data for all columns |
| 1262 | 01000 | ER\_WARN\_TOO\_MANY\_RECORDS | Row %ld was truncated; it contained more data than there were input columns |
| 1263 | 22004 | ER\_WARN\_NULL\_TO\_NOTNULL | Column set to default value; NULL supplied to NOT NULL column '%s' at row %ld |
| 1264 | 22003 | ER\_WARN\_DATA\_OUT\_OF\_RANGE | Out of range value for column '%s' at row %ld |
| 1265 | 01000 | WARN\_DATA\_TRUNCATED | Data truncated for column '%s' at row %ld |
| 1266 | HY000 | ER\_WARN\_USING\_OTHER\_HANDLER | Using storage engine %s for table '%s' |
| 1267 | HY000 | ER\_CANT\_AGGREGATE\_2COLLATIONS | Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s' |
| 1268 | HY000 | ER\_DROP\_USER | Cannot drop one or more of the requested users |
| 1269 | HY000 | ER\_REVOKE\_GRANTS | Can't revoke all privileges for one or more of the requested users |
| 1270 | HY000 | ER\_CANT\_AGGREGATE\_3COLLATIONS | Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s' |
| 1271 | HY000 | ER\_CANT\_AGGREGATE\_NCOLLATIONS | Illegal mix of collations for operation '%s' |
| 1272 | HY000 | ER\_VARIABLE\_IS\_NOT\_STRUCT | Variable '%s' is not a variable component (can't be used as XXXX.variable\_name) |
| 1273 | HY000 | ER\_UNKNOWN\_COLLATION | Unknown collation: '%s' |
| 1274 | HY000 | ER\_SLAVE\_IGNORED\_SSL\_PARAMS | SSL parameters in CHANGE MASTER are ignored because this MariaDB slave was compiled without SSL support; they can be used later if MariaDB slave with SSL is started |
| 1275 | HY000 | ER\_SERVER\_IS\_IN\_SECURE\_AUTH\_MODE | Server is running in --secure-auth mode, but '%s'@'%s' has a password in the old format; please change the password to the new format |
| 1276 | HY000 | ER\_WARN\_FIELD\_RESOLVED | Field or reference '%s%s%s%s%s' of SELECT #%d was resolved in SELECT #%d |
| 1277 | HY000 | ER\_BAD\_SLAVE\_UNTIL\_COND | Incorrect parameter or combination of parameters for START SLAVE UNTIL |
| 1278 | HY000 | ER\_MISSING\_SKIP\_SLAVE | It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL; otherwise, you will get problems if you get an unexpected slave's mysqld restart |
| 1279 | HY000 | ER\_UNTIL\_COND\_IGNORED | SQL thread is not to be started so UNTIL options are ignored |
| 1280 | 42000 | ER\_WRONG\_NAME\_FOR\_INDEX | Incorrect index name '%s' |
| 1281 | 42000 | ER\_WRONG\_NAME\_FOR\_CATALOG | Incorrect catalog name '%s' |
| 1282 | HY000 | ER\_WARN\_QC\_RESIZE | Query cache failed to set size %lu; new query cache size is %lu |
| 1283 | HY000 | ER\_BAD\_FT\_COLUMN | Column '%s' cannot be part of FULLTEXT index |
| 1284 | HY000 | ER\_UNKNOWN\_KEY\_CACHE | Unknown key cache '%s' |
| 1285 | HY000 | ER\_WARN\_HOSTNAME\_WONT\_WORK | MariaDB is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work |
| 1286 | 42000 | ER\_UNKNOWN\_STORAGE\_ENGINE | Unknown storage engine '%s' |
| 1287 | HY000 | ER\_WARN\_DEPRECATED\_SYNTAX | '%s' is deprecated and will be removed in a future release. Please use %s instead |
| 1288 | HY000 | ER\_NON\_UPDATABLE\_TABLE | The target table %s of the %s is not updatable |
| 1289 | HY000 | ER\_FEATURE\_DISABLED | The '%s' feature is disabled; you need MariaDB built with '%s' to have it working |
| 1290 | HY000 | ER\_OPTION\_PREVENTS\_STATEMENT | The MariaDB server is running with the %s option so it cannot execute this statement |
| 1291 | HY000 | ER\_DUPLICATED\_VALUE\_IN\_TYPE | Column '%s' has duplicated value '%s' in %s |
| 1292 | 22007 | ER\_TRUNCATED\_WRONG\_VALUE | Truncated incorrect %s value: '%s' |
| 1293 | HY000 | ER\_TOO\_MUCH\_AUTO\_TIMESTAMP\_COLS | Incorrect table definition; there can be only one TIMESTAMP column with CURRENT\_TIMESTAMP in DEFAULT or ON UPDATE clause |
| 1294 | HY000 | ER\_INVALID\_ON\_UPDATE | Invalid ON UPDATE clause for '%s' column |
| 1295 | HY000 | ER\_UNSUPPORTED\_PS | This command is not supported in the prepared statement protocol yet |
| 1296 | HY000 | ER\_GET\_ERRMSG | Got error %d '%s' from %s |
| 1297 | HY000 | ER\_GET\_TEMPORARY\_ERRMSG | Got temporary error %d '%s' from %s |
| 1298 | HY000 | ER\_UNKNOWN\_TIME\_ZONE | Unknown or incorrect time zone: '%s' |
| 1299 | HY000 | ER\_WARN\_INVALID\_TIMESTAMP | Invalid TIMESTAMP value in column '%s' at row %ld |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1300 | HY000 | ER\_INVALID\_CHARACTER\_STRING | Invalid %s character string: '%s' |
| 1301 | HY000 | ER\_WARN\_ALLOWED\_PACKET\_OVERFLOWED | Result of %s() was larger than max\_allowed\_packet (%ld) - truncated |
| 1302 | HY000 | ER\_CONFLICTING\_DECLARATIONS | Conflicting declarations: '%s%s' and '%s%s' |
| 1303 | 2F003 | ER\_SP\_NO\_RECURSIVE\_CREATE | Can't create a %s from within another stored routine |
| 1304 | 42000 | ER\_SP\_ALREADY\_EXISTS | %s %s already exists |
| 1305 | 42000 | ER\_SP\_DOES\_NOT\_EXIST | %s %s does not exist |
| 1306 | HY000 | ER\_SP\_DROP\_FAILED | Failed to DROP %s %s |
| 1307 | HY000 | ER\_SP\_STORE\_FAILED | Failed to CREATE %s %s |
| 1308 | 42000 | ER\_SP\_LILABEL\_MISMATCH | %s with no matching label: %s |
| 1309 | 42000 | ER\_SP\_LABEL\_REDEFINE | Redefining label %s |
| 1310 | 42000 | ER\_SP\_LABEL\_MISMATCH | End-label %s without match |
| 1311 | 01000 | ER\_SP\_UNINIT\_VAR | Referring to uninitialized variable %s |
| 1312 | 0A000 | ER\_SP\_BADSELECT | PROCEDURE %s can't return a result set in the given context |
| 1313 | 42000 | ER\_SP\_BADRETURN | RETURN is only allowed in a FUNCTION |
| 1314 | 0A000 | ER\_SP\_BADSTATEMENT | %s is not allowed in stored procedures |
| 1315 | 42000 | ER\_UPDATE\_LOG\_DEPRECATED\_IGNORED | The update log is deprecated and replaced by the binary log; SET SQL\_LOG\_UPDATE has been ignored. This option will be removed in [MariaDB 5.6](../what-is-mariadb-56/index). |
| 1316 | 42000 | ER\_UPDATE\_LOG\_DEPRECATED\_TRANSLATED | The update log is deprecated and replaced by the binary log; SET SQL\_LOG\_UPDATE has been translated to SET SQL\_LOG\_BIN. This option will be removed in [MariaDB 5.6](../what-is-mariadb-56/index). |
| 1317 | 70100 | ER\_QUERY\_INTERRUPTED | Query execution was interrupted |
| 1318 | 42000 | ER\_SP\_WRONG\_NO\_OF\_ARGS | Incorrect number of arguments for %s %s; expected %u, got %u |
| 1319 | 42000 | ER\_SP\_COND\_MISMATCH | Undefined CONDITION: %s |
| 1320 | 42000 | ER\_SP\_NORETURN | No RETURN found in FUNCTION %s |
| 1321 | 2F005 | ER\_SP\_NORETURNEND | FUNCTION %s ended without RETURN |
| 1322 | 42000 | ER\_SP\_BAD\_CURSOR\_QUERY | Cursor statement must be a SELECT |
| 1323 | 42000 | ER\_SP\_BAD\_CURSOR\_SELECT | Cursor SELECT must not have INTO |
| 1324 | 42000 | ER\_SP\_CURSOR\_MISMATCH | Undefined CURSOR: %s |
| 1325 | 24000 | ER\_SP\_CURSOR\_ALREADY\_OPEN | Cursor is already open |
| 1326 | 24000 | ER\_SP\_CURSOR\_NOT\_OPEN | Cursor is not open |
| 1327 | 42000 | ER\_SP\_UNDECLARED\_VAR | Undeclared variable: %s |
| 1328 | HY000 | ER\_SP\_WRONG\_NO\_OF\_FETCH\_ARGS | Incorrect number of FETCH variables |
| 1329 | 02000 | ER\_SP\_FETCH\_NO\_DATA | No data - zero rows fetched, selected, or processed |
| 1330 | 42000 | ER\_SP\_DUP\_PARAM | Duplicate parameter: %s |
| 1331 | 42000 | ER\_SP\_DUP\_VAR | Duplicate variable: %s |
| 1332 | 42000 | ER\_SP\_DUP\_COND | Duplicate condition: %s |
| 1333 | 42000 | ER\_SP\_DUP\_CURS | Duplicate cursor: %s |
| 1334 | HY000 | ER\_SP\_CANT\_ALTER | Failed to ALTER %s %s |
| 1335 | 0A000 | ER\_SP\_SUBSELECT\_NYI | Subquery value not supported |
| 1336 | 0A000 | ER\_STMT\_NOT\_ALLOWED\_IN\_SF\_OR\_TRG | %s is not allowed in stored function or trigger |
| 1337 | 42000 | ER\_SP\_VARCOND\_AFTER\_CURSHNDLR | Variable or condition declaration after cursor or handler declaration |
| 1338 | 42000 | ER\_SP\_CURSOR\_AFTER\_HANDLER | Cursor declaration after handler declaration |
| 1339 | 20000 | ER\_SP\_CASE\_NOT\_FOUND | Case not found for CASE statement |
| 1340 | HY000 | ER\_FPARSER\_TOO\_BIG\_FILE | Configuration file '%s' is too big |
| 1341 | HY000 | ER\_FPARSER\_BAD\_HEADER | Malformed file type header in file '%s' |
| 1342 | HY000 | ER\_FPARSER\_EOF\_IN\_COMMENT | Unexpected end of file while parsing comment '%s' |
| 1343 | HY000 | ER\_FPARSER\_ERROR\_IN\_PARAMETER | Error while parsing parameter '%s' (line: '%s') |
| 1344 | HY000 | ER\_FPARSER\_EOF\_IN\_UNKNOWN\_PARAMETER | Unexpected end of file while skipping unknown parameter '%s' |
| 1345 | HY000 | ER\_VIEW\_NO\_EXPLAIN | EXPLAIN/SHOW can not be issued; lacking privileges for underlying table |
| 1346 | HY000 | ER\_FRM\_UNKNOWN\_TYPE | File '%s' has unknown type '%s' in its header |
| 1347 | HY000 | ER\_WRONG\_OBJECT | '%s.%s' is not %s |
| 1348 | HY000 | ER\_NONUPDATEABLE\_COLUMN | Column '%s' is not updatable |
| 1349 | HY000 | ER\_VIEW\_SELECT\_DERIVED | View's SELECT contains a subquery in the FROM clause |
| 1350 | HY000 | ER\_VIEW\_SELECT\_CLAUSE | View's SELECT contains a '%s' clause |
| 1351 | HY000 | ER\_VIEW\_SELECT\_VARIABLE | View's SELECT contains a variable or parameter |
| 1352 | HY000 | ER\_VIEW\_SELECT\_TMPTABLE | View's SELECT refers to a temporary table '%s' |
| 1353 | HY000 | ER\_VIEW\_WRONG\_LIST | View's SELECT and view's field list have different column counts |
| 1354 | HY000 | ER\_WARN\_VIEW\_MERGE | View merge algorithm can't be used here for now (assumed undefined algorithm) |
| 1355 | HY000 | ER\_WARN\_VIEW\_WITHOUT\_KEY | View being updated does not have complete key of underlying table in it |
| 1356 | HY000 | ER\_VIEW\_INVALID | View '%s.%s' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them |
| 1357 | HY000 | ER\_SP\_NO\_DROP\_SP | Can't drop or alter a %s from within another stored routine |
| 1358 | HY000 | ER\_SP\_GOTO\_IN\_HNDLR | GOTO is not allowed in a stored procedure handler |
| 1359 | HY000 | ER\_TRG\_ALREADY\_EXISTS | Trigger already exists |
| 1360 | HY000 | ER\_TRG\_DOES\_NOT\_EXIST | Trigger does not exist |
| 1361 | HY000 | ER\_TRG\_ON\_VIEW\_OR\_TEMP\_TABLE | Trigger's '%s' is view or temporary table |
| 1362 | HY000 | ER\_TRG\_CANT\_CHANGE\_ROW | Updating of %s row is not allowed in %strigger |
| 1363 | HY000 | ER\_TRG\_NO\_SUCH\_ROW\_IN\_TRG | There is no %s row in %s trigger |
| 1364 | HY000 | ER\_NO\_DEFAULT\_FOR\_FIELD | Field '%s' doesn't have a default value |
| 1365 | 22012 | ER\_DIVISION\_BY\_ZER | Division by 0 |
| 1366 | HY000 | ER\_TRUNCATED\_WRONG\_VALUE\_FOR\_FIELD | Incorrect %s value: '%s' for column '%s' at row %ld |
| 1367 | 22007 | ER\_ILLEGAL\_VALUE\_FOR\_TYPE | Illegal %s '%s' value found during parsing |
| 1368 | HY000 | ER\_VIEW\_NONUPD\_CHECK | CHECK OPTION on non-updatable view '%s.%s' |
| 1369 | HY000 | ER\_VIEW\_CHECK\_FAILED | CHECK OPTION failed '%s.%s' |
| 1370 | 42000 | ER\_PROCACCESS\_DENIED\_ERROR | %s command denied to user '%s'@'%s' for routine '%s' |
| 1371 | HY000 | ER\_RELAY\_LOG\_FAIL | Failed purging old relay logs: %s |
| 1372 | HY000 | ER\_PASSWD\_LENGTH | Password hash should be a %d-digit hexadecimal number |
| 1373 | HY000 | ER\_UNKNOWN\_TARGET\_BINLOG | Target log not found in binlog index |
| 1374 | HY000 | ER\_IO\_ERR\_LOG\_INDEX\_READ | I/O error reading log index file |
| 1375 | HY000 | ER\_BINLOG\_PURGE\_PROHIBITED | Server configuration does not permit binlog purge |
| 1376 | HY000 | ER\_FSEEK\_FAIL | Failed on fseek() |
| 1377 | HY000 | ER\_BINLOG\_PURGE\_FATAL\_ERR | Fatal error during log purge |
| 1378 | HY000 | ER\_LOG\_IN\_USE | A purgeable log is in use, will not purge |
| 1379 | HY000 | ER\_LOG\_PURGE\_UNKNOWN\_ERR | Unknown error during log purge |
| 1380 | HY000 | ER\_RELAY\_LOG\_INIT | Failed initializing relay log position: %s |
| 1381 | HY000 | ER\_NO\_BINARY\_LOGGING | You are not using binary logging |
| 1382 | HY000 | ER\_RESERVED\_SYNTAX | The '%s' syntax is reserved for purposes internal to the MariaDB server |
| 1383 | HY000 | ER\_WSAS\_FAILED | WSAStartup Failed |
| 1384 | HY000 | ER\_DIFF\_GROUPS\_PROC | Can't handle procedures with different groups yet |
| 1385 | HY000 | ER\_NO\_GROUP\_FOR\_PROC | Select must have a group with this procedure |
| 1386 | HY000 | ER\_ORDER\_WITH\_PROC | Can't use ORDER clause with this procedure |
| 1387 | HY000 | ER\_LOGGING\_PROHIBIT\_CHANGING\_OF | Binary logging and replication forbid changing the global server %s |
| 1388 | HY000 | ER\_NO\_FILE\_MAPPING | Can't map file: %s, errno: %d |
| 1389 | HY000 | ER\_WRONG\_MAGIC | Wrong magic in %s |
| 1390 | HY000 | ER\_PS\_MANY\_PARAM | Prepared statement contains too many placeholders |
| 1391 | HY000 | ER\_KEY\_PART\_0 | Key part '%s' length cannot be 0 |
| 1392 | HY000 | ER\_VIEW\_CHECKSUM | View text checksum failed |
| 1393 | HY000 | ER\_VIEW\_MULTIUPDATE | Can not modify more than one base table through a join view '%s.%s' |
| 1394 | HY000 | ER\_VIEW\_NO\_INSERT\_FIELD\_LIST | Can not insert into join view '%s.%s' without fields list |
| 1395 | HY000 | ER\_VIEW\_DELETE\_MERGE\_VIEW | Can not delete from join view '%s.%s' |
| 1396 | HY000 | ER\_CANNOT\_USER | Operation %s failed for %s |
| 1397 | XAE04 | ER\_XAER\_NOTA | XAER\_NOTA: Unknown XID |
| 1398 | XAE05 | ER\_XAER\_INVAL | XAER\_INVAL: Invalid arguments (or unsupported command) |
| 1399 | XAE07 | ER\_XAER\_RMFAIL | XAER\_RMFAIL: The command cannot be executed when global transaction is in the %s state |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1400 | XAE09 | ER\_XAER\_OUTSIDE | XAER\_OUTSIDE: Some work is done outside global transaction |
| 1401 | XAE03 | ER\_XAER\_RMERR | XAER\_RMERR: Fatal error occurred in the transaction branch - check your data for consistency |
| 1402 | XA100 | ER\_XA\_RBROLLBACK | XA\_RBROLLBACK: Transaction branch was rolled back |
| 1403 | 42000 | ER\_NONEXISTING\_PROC\_GRANT | There is no such grant defined for user '%s' on host '%s' on routine '%s' |
| 1404 | HY000 | ER\_PROC\_AUTO\_GRANT\_FAIL | Failed to grant EXECUTE and ALTER ROUTINE privileges |
| 1405 | HY000 | ER\_PROC\_AUTO\_REVOKE\_FAIL | Failed to revoke all privileges to dropped routine |
| 1406 | 22001 | ER\_DATA\_TOO\_LONG | Data too long for column '%s' at row %ld |
| 1407 | 42000 | ER\_SP\_BAD\_SQLSTATE | Bad SQLSTATE: '%s' |
| 1408 | HY000 | ER\_STARTUP | %s: ready for connections. Version: '%s' socket: '%s' port: %d %s |
| 1409 | HY000 | ER\_LOAD\_FROM\_FIXED\_SIZE\_ROWS\_TO\_VAR | Can't load value from file with fixed size rows to variable |
| 1410 | 42000 | ER\_CANT\_CREATE\_USER\_WITH\_GRANT | You are not allowed to create a user with GRANT |
| 1411 | HY000 | ER\_WRONG\_VALUE\_FOR\_TYPE | Incorrect %s value: '%s' for function %s |
| 1412 | HY000 | ER\_TABLE\_DEF\_CHANGED | Table definition has changed, please retry transaction |
| 1413 | 42000 | ER\_SP\_DUP\_HANDLER | Duplicate handler declared in the same block |
| 1414 | 42000 | ER\_SP\_NOT\_VAR\_ARG | OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger |
| 1415 | 0A000 | ER\_SP\_NO\_RETSET | Not allowed to return a result set from a %s |
| 1416 | 22003 | ER\_CANT\_CREATE\_GEOMETRY\_OBJECT | Cannot get geometry object from data you send to the GEOMETRY field |
| 1417 | HY000 | ER\_FAILED\_ROUTINE\_BREAK\_BINLOG | A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes |
| 1418 | HY000 | ER\_BINLOG\_UNSAFE\_ROUTINE | This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you \*might\* want to use the less safe log\_bin\_trust\_function\_creators variable) |
| 1419 | HY000 | ER\_BINLOG\_CREATE\_ROUTINE\_NEED\_SUPER | You do not have the SUPER privilege and binary logging is enabled (you \*might\* want to use the less safe log\_bin\_trust\_function\_creators variable) |
| 1420 | HY000 | ER\_EXEC\_STMT\_WITH\_OPEN\_CURSOR | You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it. |
| 1421 | HY000 | ER\_STMT\_HAS\_NO\_OPEN\_CURSOR | The statement (%lu) has no open cursor. |
| 1422 | HY000 | ER\_COMMIT\_NOT\_ALLOWED\_IN\_SF\_OR\_TRG | Explicit or implicit commit is not allowed in stored function or trigger. |
| 1423 | HY000 | ER\_NO\_DEFAULT\_FOR\_VIEW\_FIELD | Field of view '%s.%s' underlying table doesn't have a default value |
| 1424 | HY000 | ER\_SP\_NO\_RECURSION | Recursive stored functions and triggers are not allowed. |
| 1425 | 42000 | ER\_TOO\_BIG\_SCALE | Too big scale %d specified for column '%s'. Maximum is %lu. |
| 1426 | 42000 | ER\_TOO\_BIG\_PRECISION | Too big precision %d specified for column '%s'. Maximum is %lu. |
| 1427 | 42000 | ER\_M\_BIGGER\_THAN\_D | For float(M,D, double(M,D or decimal(M,D, M must be >= D (column '%s'). |
| 1428 | HY000 | ER\_WRONG\_LOCK\_OF\_SYSTEM\_TABLE | You can't combine write-locking of system tables with other tables or lock types |
| 1429 | HY000 | ER\_CONNECT\_TO\_FOREIGN\_DATA\_SOURCE | Unable to connect to foreign data source: %s |
| 1430 | HY000 | ER\_QUERY\_ON\_FOREIGN\_DATA\_SOURCE | There was a problem processing the query on the foreign data source. Data source error: %s |
| 1431 | HY000 | ER\_FOREIGN\_DATA\_SOURCE\_DOESNT\_EXIST | The foreign data source you are trying to reference does not exist. Data source error: %s |
| 1432 | HY000 | ER\_FOREIGN\_DATA\_STRING\_INVALID\_CANT\_CREATE | Can't create federated table. The data source connection string '%s' is not in the correct format |
| 1433 | HY000 | ER\_FOREIGN\_DATA\_STRING\_INVALID | The data source connection string '%s' is not in the correct format |
| 1434 | HY000 | ER\_CANT\_CREATE\_FEDERATED\_TABLE | Can't create federated table. Foreign data src error: %s |
| 1435 | HY000 | ER\_TRG\_IN\_WRONG\_SCHEMA | Trigger in wrong schema |
| 1436 | HY000 | ER\_STACK\_OVERRUN\_NEED\_MORE | Thread stack overrun: %ld bytes used of a %ld byte stack, and %ld bytes needed. Use 'mysqld --thread\_stack=#' to specify a bigger stack. |
| 1437 | 42000 | ER\_TOO\_LONG\_BODY | Routine body for '%s' is too long |
| 1438 | HY000 | ER\_WARN\_CANT\_DROP\_DEFAULT\_KEYCACHE | Cannot drop default keycache |
| 1439 | 42000 | ER\_TOO\_BIG\_DISPLAYWIDTH | Display width out of range for column '%s' (max = %lu) |
| 1440 | XAE08 | ER\_XAER\_DUPID | XAER\_DUPID: The XID already exists |
| 1441 | 22008 | ER\_DATETIME\_FUNCTION\_OVERFLOW | Datetime function: %s field overflow |
| 1442 | HY000 | ER\_CANT\_UPDATE\_USED\_TABLE\_IN\_SF\_OR\_TRG | Can't update table '%s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. |
| 1443 | HY000 | ER\_VIEW\_PREVENT\_UPDATE | The definition of table '%s' prevents operation %s on table '%s'. |
| 1444 | HY000 | ER\_PS\_NO\_RECURSION | The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner |
| 1445 | HY000 | ER\_SP\_CANT\_SET\_AUTOCOMMIT | Not allowed to set autocommit from a stored function or trigger |
| 1446 | HY000 | ER\_MALFORMED\_DEFINER | Definer is not fully qualified |
| 1447 | HY000 | ER\_VIEW\_FRM\_NO\_USER | View '%s'.'%s' has no definer information (old table format). Current user is used as definer. Please recreate the view! |
| 1448 | HY000 | ER\_VIEW\_OTHER\_USER | You need the SUPER privilege for creation view with '%s'@'%s' definer |
| 1449 | HY000 | ER\_NO\_SUCH\_USER | The user specified as a definer ('%s'@'%s') does not exist |
| 1450 | HY000 | ER\_FORBID\_SCHEMA\_CHANGE | Changing schema from '%s' to '%s' is not allowed. |
| 1451 | 23000 | ER\_ROW\_IS\_REFERENCED\_2 | Cannot delete or update a parent row: a foreign key constraint fails (%s) |
| 1452 | 23000 | ER\_NO\_REFERENCED\_ROW\_2 | Cannot add or update a child row: a foreign key constraint fails (%s) |
| 1453 | 42000 | ER\_SP\_BAD\_VAR\_SHADOW | Variable '%s' must be quoted with `...`, or renamed |
| 1454 | HY000 | ER\_TRG\_NO\_DEFINER | No definer attribute for trigger '%s'.'%s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger. |
| 1455 | HY000 | ER\_OLD\_FILE\_FORMAT | '%s' has an old format, you should re-create the '%s' object(s) |
| 1456 | HY000 | ER\_SP\_RECURSION\_LIMIT | Recursive limit %d (as set by the max\_sp\_recursion\_depth variable) was exceeded for routine %s |
| 1457 | HY000 | ER\_SP\_PROC\_TABLE\_CORRUPT | Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d) |
| 1458 | 42000 | ER\_SP\_WRONG\_NAME | Incorrect routine name '%s' |
| 1459 | HY000 | ER\_TABLE\_NEEDS\_UPGRADE | Table upgrade required. Please do "REPAIR TABLE `%s`" or dump/reload to fix it! |
| 1460 | 42000 | ER\_SP\_NO\_AGGREGATE | AGGREGATE is not supported for stored functions |
| 1461 | 42000 | ER\_MAX\_PREPARED\_STMT\_COUNT\_REACHED | Can't create more than max\_prepared\_stmt\_count statements (current value: %lu) |
| 1462 | HY000 | ER\_VIEW\_RECURSIVE | `%s`.`%s` contains view recursion |
| 1463 | 42000 | ER\_NON\_GROUPING\_FIELD\_USED | Non-grouping field '%s' is used in %s clause |
| 1464 | HY000 | ER\_TABLE\_CANT\_HANDLE\_SPKEYS | The used table type doesn't support SPATIAL indexes |
| 1465 | HY000 | ER\_NO\_TRIGGERS\_ON\_SYSTEM\_SCHEMA | Triggers can not be created on system tables |
| 1466 | HY000 | ER\_REMOVED\_SPACES | Leading spaces are removed from name '%s' |
| 1467 | HY000 | ER\_AUTOINC\_READ\_FAILED | Failed to read auto-increment value from storage engine |
| 1468 | HY000 | ER\_USERNAME | user name |
| 1469 | HY000 | ER\_HOSTNAME | host name |
| 1470 | HY000 | ER\_WRONG\_STRING\_LENGTH | String '%s' is too long for %s (should be no longer than %d) |
| 1471 | HY000 | ER\_NON\_INSERTABLE\_TABLE | The target table %s of the %s is not insertable-into |
| 1472 | HY000 | ER\_ADMIN\_WRONG\_MRG\_TABLE | Table '%s' is differently defined or of non-MyISAM type or doesn't exist |
| 1473 | HY000 | ER\_TOO\_HIGH\_LEVEL\_OF\_NESTING\_FOR\_SELECT | Too high level of nesting for select |
| 1474 | HY000 | ER\_NAME\_BECOMES\_EMPTY | Name '%s' has become '' |
| 1475 | HY000 | ER\_AMBIGUOUS\_FIELD\_TERM | First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY |
| 1476 | HY000 | ER\_FOREIGN\_SERVER\_EXISTS | The foreign server, %s, you are trying to create already exists. |
| 1477 | HY000 | ER\_FOREIGN\_SERVER\_DOESNT\_EXIST | The foreign server name you are trying to reference does not exist. Data source error: %s |
| 1478 | HY000 | ER\_ILLEGAL\_HA\_CREATE\_OPTION | Table storage engine '%s' does not support the create option '%s' |
| 1479 | HY000 | ER\_PARTITION\_REQUIRES\_VALUES\_ERROR | Syntax error: %s PARTITIONING requires definition of VALUES %s for each partition |
| 1480 | HY000 | ER\_PARTITION\_WRONG\_VALUES\_ERROR | Only %s PARTITIONING can use VALUES %s in partition definition |
| 1481 | HY000 | ER\_PARTITION\_MAXVALUE\_ERROR | MAXVALUE can only be used in last partition definition |
| 1482 | HY000 | ER\_PARTITION\_SUBPARTITION\_ERROR | Subpartitions can only be hash partitions and by key |
| 1483 | HY000 | ER\_PARTITION\_SUBPART\_MIX\_ERROR | Must define subpartitions on all partitions if on one partition |
| 1484 | HY000 | ER\_PARTITION\_WRONG\_NO\_PART\_ERROR | Wrong number of partitions defined, mismatch with previous setting |
| 1485 | HY000 | ER\_PARTITION\_WRONG\_NO\_SUBPART\_ERROR | Wrong number of subpartitions defined, mismatch with previous setting |
| 1486 | HY000 | ER\_CONST\_EXPR\_IN\_PARTITION\_FUNC\_ERROR | Constant/Random expression in (sub)partitioning function is not allowed |
| 1486 | HY000 | ER\_WRONG\_EXPR\_IN\_PARTITION\_FUNC\_ERROR | Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed |
| 1487 | HY000 | ER\_NO\_CONST\_EXPR\_IN\_RANGE\_OR\_LIST\_ERROR | Expression in RANGE/LIST VALUES must be constant |
| 1488 | HY000 | ER\_FIELD\_NOT\_FOUND\_PART\_ERROR | Field in list of fields for partition function not found in table |
| 1489 | HY000 | ER\_LIST\_OF\_FIELDS\_ONLY\_IN\_HASH\_ERROR | List of fields is only allowed in KEY partitions |
| 1490 | HY000 | ER\_INCONSISTENT\_PARTITION\_INFO\_ERROR | The partition info in the frm file is not consistent with what can be written into the frm file |
| 1491 | HY000 | ER\_PARTITION\_FUNC\_NOT\_ALLOWED\_ERROR | The %s function returns the wrong type |
| 1492 | HY000 | ER\_PARTITIONS\_MUST\_BE\_DEFINED\_ERROR | For %s partitions each partition must be defined |
| 1493 | HY000 | ER\_RANGE\_NOT\_INCREASING\_ERROR | VALUES LESS THAN value must be strictly increasing for each partition |
| 1494 | HY000 | ER\_INCONSISTENT\_TYPE\_OF\_FUNCTIONS\_ERROR | VALUES value must be of same type as partition function |
| 1495 | HY000 | ER\_MULTIPLE\_DEF\_CONST\_IN\_LIST\_PART\_ERROR | Multiple definition of same constant in list partitioning |
| 1496 | HY000 | ER\_PARTITION\_ENTRY\_ERROR | Partitioning can not be used stand-alone in query |
| 1497 | HY000 | ER\_MIX\_HANDLER\_ERROR | The mix of handlers in the partitions is not allowed in this version of MariaDB |
| 1498 | HY000 | ER\_PARTITION\_NOT\_DEFINED\_ERROR | For the partitioned engine it is necessary to define all %s |
| 1499 | HY000 | ER\_TOO\_MANY\_PARTITIONS\_ERROR | Too many partitions (including subpartitions) were defined |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1500 | HY000 | ER\_SUBPARTITION\_ERROR | It is only possible to mix RANGE/LIST partitioning with HASH/KEY partitioning for subpartitioning |
| 1501 | HY000 | ER\_CANT\_CREATE\_HANDLER\_FILE | Failed to create specific handler file |
| 1502 | HY000 | ER\_BLOB\_FIELD\_IN\_PART\_FUNC\_ERROR | A BLOB field is not allowed in partition function |
| 1503 | HY000 | ER\_UNIQUE\_KEY\_NEED\_ALL\_FIELDS\_IN\_PF | A %s must include all columns in the table's partitioning function |
| 1504 | HY000 | ER\_NO\_PARTS\_ERROR | Number of %s = 0 is not an allowed value |
| 1505 | HY000 | ER\_PARTITION\_MGMT\_ON\_NONPARTITIONED | Partition management on a not partitioned table is not possible |
| 1506 | HY000 | ER\_FOREIGN\_KEY\_ON\_PARTITIONED | Foreign key clause is not yet supported in conjunction with partitioning |
| 1507 | HY000 | ER\_DROP\_PARTITION\_NON\_EXISTENT | Error in list of partitions to %s |
| 1508 | HY000 | ER\_DROP\_LAST\_PARTITION | Cannot remove all partitions, use DROP TABLE instead |
| 1509 | HY000 | ER\_COALESCE\_ONLY\_ON\_HASH\_PARTITION | COALESCE PARTITION can only be used on HASH/KEY partitions |
| 1510 | HY000 | ER\_REORG\_HASH\_ONLY\_ON\_SAME\_N | REORGANIZE PARTITION can only be used to reorganize partitions not to change their numbers |
| 1511 | HY000 | ER\_REORG\_NO\_PARAM\_ERROR | REORGANIZE PARTITION without parameters can only be used on auto-partitioned tables using HASH PARTITIONs |
| 1512 | HY000 | ER\_ONLY\_ON\_RANGE\_LIST\_PARTITION | %s PARTITION can only be used on RANGE/LIST partitions |
| 1513 | HY000 | ER\_ADD\_PARTITION\_SUBPART\_ERROR | Trying to Add partition(s) with wrong number of subpartitions |
| 1514 | HY000 | ER\_ADD\_PARTITION\_NO\_NEW\_PARTITION | At least one partition must be added |
| 1515 | HY000 | ER\_COALESCE\_PARTITION\_NO\_PARTITION | At least one partition must be coalesced |
| 1516 | HY000 | ER\_REORG\_PARTITION\_NOT\_EXIST | More partitions to reorganize than there are partitions |
| 1517 | HY000 | ER\_SAME\_NAME\_PARTITION | Duplicate partition name %s |
| 1518 | HY000 | ER\_NO\_BINLOG\_ERROR | It is not allowed to shut off binlog on this command |
| 1519 | HY000 | ER\_CONSECUTIVE\_REORG\_PARTITIONS | When reorganizing a set of partitions they must be in consecutive order |
| 1520 | HY000 | ER\_REORG\_OUTSIDE\_RANGE | Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range |
| 1521 | HY000 | ER\_PARTITION\_FUNCTION\_FAILURE | Partition function not supported in this version for this handler |
| 1522 | HY000 | ER\_PART\_STATE\_ERROR | Partition state cannot be defined from CREATE/ALTER TABLE |
| 1523 | HY000 | ER\_LIMITED\_PART\_RANGE | The %s handler only supports 32 bit integers in VALUES |
| 1524 | HY000 | ER\_PLUGIN\_IS\_NOT\_LOADED | Plugin '%s' is not loaded |
| 1525 | HY000 | ER\_WRONG\_VALUE | Incorrect %s value: '%s' |
| 1526 | HY000 | ER\_NO\_PARTITION\_FOR\_GIVEN\_VALUE | Table has no partition for value %s |
| 1527 | HY000 | ER\_FILEGROUP\_OPTION\_ONLY\_ONCE | It is not allowed to specify %s more than once |
| 1528 | HY000 | ER\_CREATE\_FILEGROUP\_FAILED | Failed to create %s |
| 1529 | HY000 | ER\_DROP\_FILEGROUP\_FAILED | Failed to drop %s |
| 1530 | HY000 | ER\_TABLESPACE\_AUTO\_EXTEND\_ERROR | The handler doesn't support autoextend of tablespaces |
| 1531 | HY000 | ER\_WRONG\_SIZE\_NUMBER | A size parameter was incorrectly specified, either number or on the form 10M |
| 1532 | HY000 | ER\_SIZE\_OVERFLOW\_ERROR | The size number was correct but we don't allow the digit part to be more than 2 billion |
| 1533 | HY000 | ER\_ALTER\_FILEGROUP\_FAILED | Failed to alter: %s |
| 1534 | HY000 | ER\_BINLOG\_ROW\_LOGGING\_FAILED | Writing one row to the row-based binary log failed |
| 1535 | HY000 | ER\_BINLOG\_ROW\_WRONG\_TABLE\_DEF | Table definition on master and slave does not match: %s |
| 1536 | HY000 | ER\_BINLOG\_ROW\_RBR\_TO\_SBR | Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events |
| 1537 | HY000 | ER\_EVENT\_ALREADY\_EXISTS | Event '%s' already exists |
| 1538 | HY000 | ER\_EVENT\_STORE\_FAILED | Failed to store event %s. Error code %d from storage engine. |
| 1539 | HY000 | ER\_EVENT\_DOES\_NOT\_EXIST | Unknown event '%s' |
| 1540 | HY000 | ER\_EVENT\_CANT\_ALTER | Failed to alter event '%s' |
| 1541 | HY000 | ER\_EVENT\_DROP\_FAILED | Failed to drop %s |
| 1542 | HY000 | ER\_EVENT\_INTERVAL\_NOT\_POSITIVE\_OR\_TOO\_BIG | INTERVAL is either not positive or too big |
| 1543 | HY000 | ER\_EVENT\_ENDS\_BEFORE\_STARTS | ENDS is either invalid or before STARTS |
| 1544 | HY000 | ER\_EVENT\_EXEC\_TIME\_IN\_THE\_PAST | Event execution time is in the past. Event has been disabled |
| 1545 | HY000 | ER\_EVENT\_OPEN\_TABLE\_FAILED | Failed to open [mysql.event](../mysqlevent-table/index) |
| 1546 | HY000 | ER\_EVENT\_NEITHER\_M\_EXPR\_NOR\_M\_AT | No datetime expression provided |
| 1547 | HY000 | ER\_COL\_COUNT\_DOESNT\_MATCH\_CORRUPTED | Column count of mysql.%s is wrong. Expected %d, found %d. The table is probably corrupted |
| 1548 | HY000 | ER\_CANNOT\_LOAD\_FROM\_TABLE | Cannot load from mysql.%s. The table is probably corrupted |
| 1549 | HY000 | ER\_EVENT\_CANNOT\_DELETE | Failed to delete the event from [mysql.event](../mysqlevent-table/index) |
| 1550 | HY000 | ER\_EVENT\_COMPILE\_ERROR | Error during compilation of event's body |
| 1551 | HY000 | ER\_EVENT\_SAME\_NAME | Same old and new event name |
| 1552 | HY000 | ER\_EVENT\_DATA\_TOO\_LONG | Data for column '%s' too long |
| 1553 | HY000 | ER\_DROP\_INDEX\_FK | Cannot drop index '%s': needed in a foreign key constraint |
| 1554 | HY000 | ER\_WARN\_DEPRECATED\_SYNTAX\_WITH\_VER | The syntax '%s' is deprecated and will be removed in MariaDB %s. Please use %s instead |
| 1555 | HY000 | ER\_CANT\_WRITE\_LOCK\_LOG\_TABLE | You can't write-lock a log table. Only read access is possible |
| 1556 | HY000 | ER\_CANT\_LOCK\_LOG\_TABLE | You can't use locks with log tables. |
| 1557 | 23000 | ER\_FOREIGN\_DUPLICATE\_KEY | Upholding foreign key constraints for table '%s', entry '%s', key %d would lead to a duplicate entry |
| 1558 | HY000 | ER\_COL\_COUNT\_DOESNT\_MATCH\_PLEASE\_UPDATE | Column count of mysql.%s is wrong. Expected %d, found %d. Created with MariaDB %d, now running %d. Please use mysql\_upgrade to fix this error. |
| 1559 | HY000 | ER\_TEMP\_TABLE\_PREVENTS\_SWITCH\_OUT\_OF\_RBR | Cannot switch out of the row-based binary log format when the session has open temporary tables |
| 1560 | HY000 | ER\_STORED\_FUNCTION\_ PREVENTS\_SWITCH\_BINLOG\_FORMAT | Cannot change the binary logging format inside a stored function or trigger |
| 1561 |  | ER\_UNUSED\_13 | You should never see it |
| 1562 | HY000 | ER\_PARTITION\_NO\_TEMPORARY | Cannot create temporary table with partitions |
| 1563 | HY000 | ER\_PARTITION\_CONST\_DOMAIN\_ERROR | Partition constant is out of partition function domain |
| 1564 | HY000 | ER\_PARTITION\_FUNCTION\_IS\_NOT\_ALLOWED | This partition function is not allowed |
| 1565 | HY000 | ER\_DDL\_LOG\_ERROR | Error in DDL log |
| 1566 | HY000 | ER\_NULL\_IN\_VALUES\_LESS\_THAN | Not allowed to use NULL value in VALUES LESS THAN |
| 1567 | HY000 | ER\_WRONG\_PARTITION\_NAME | Incorrect partition name |
| 1568 | 25001 | ER\_CANT\_CHANGE\_TX\_ISOLATION | Transaction isolation level can't be changed while a transaction is in progress |
| 1569 | HY000 | ER\_DUP\_ENTRY\_AUTOINCREMENT\_CASE | ALTER TABLE causes auto\_increment resequencing, resulting in duplicate entry '%s' for key '%s' |
| 1570 | HY000 | ER\_EVENT\_MODIFY\_QUEUE\_ERROR | Internal scheduler error %d |
| 1571 | HY000 | ER\_EVENT\_SET\_VAR\_ERROR | Error during starting/stopping of the scheduler. Error code %u |
| 1572 | HY000 | ER\_PARTITION\_MERGE\_ERROR | Engine cannot be used in partitioned tables |
| 1573 | HY000 | ER\_CANT\_ACTIVATE\_LOG | Cannot activate '%s' log |
| 1574 | HY000 | ER\_RBR\_NOT\_AVAILABLE | The server was not built with row-based replication |
| 1575 | HY000 | ER\_BASE64\_DECODE\_ERROR | Decoding of base64 string failed |
| 1576 | HY000 | ER\_EVENT\_RECURSION\_FORBIDDEN | Recursion of EVENT DDL statements is forbidden when body is present |
| 1577 | HY000 | ER\_EVENTS\_DB\_ERROR | Cannot proceed because system tables used by Event Scheduler were found damaged at server start |
| 1578 | HY000 | ER\_ONLY\_INTEGERS\_ALLOWED | Only integers allowed as number here |
| 1579 | HY000 | ER\_UNSUPORTED\_LOG\_ENGINE | This storage engine cannot be used for log tables" |
| 1580 | HY000 | ER\_BAD\_LOG\_STATEMENT | You cannot '%s' a log table if logging is enabled |
| 1581 | HY000 | ER\_CANT\_RENAME\_LOG\_TABLE | Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s' |
| 1582 | 42000 | ER\_WRONG\_PARAMCOUNT\_TO\_NATIVE\_FCT | Incorrect parameter count in the call to native function '%s' |
| 1583 | 42000 | ER\_WRONG\_PARAMETERS\_TO\_NATIVE\_FCT | Incorrect parameters in the call to native function '%s' |
| 1584 | 42000 | ER\_WRONG\_PARAMETERS\_TO\_STORED\_FCT | Incorrect parameters in the call to stored function '%s' |
| 1585 | HY000 | ER\_NATIVE\_FCT\_NAME\_COLLISION | This function '%s' has the same name as a native function |
| 1586 | 23000 | ER\_DUP\_ENTRY\_WITH\_KEY\_NAME | Duplicate entry '%s' for key '%s' |
| 1587 | HY000 | ER\_BINLOG\_PURGE\_EMFILE | Too many files opened, please execute the command again |
| 1588 | HY000 | ER\_EVENT\_CANNOT\_CREATE\_IN\_THE\_PAST | Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. |
| 1589 | HY000 | ER\_EVENT\_CANNOT\_ALTER\_IN\_THE\_PAST | Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation. |
| 1590 | HY000 | ER\_SLAVE\_INCIDENT | The incident %s occured on the master. Message: %s |
| 1591 | HY000 | ER\_NO\_PARTITION\_FOR\_GIVEN\_VALUE\_SILENT | Table has no partition for some existing values |
| 1592 | HY000 | ER\_BINLOG\_UNSAFE\_STATEMENT | Unsafe statement written to the binary log using statement format since BINLOG\_FORMAT = STATEMENT. %s |
| 1593 | HY000 | ER\_SLAVE\_FATAL\_ERROR | Fatal error: %s |
| 1594 | HY000 | ER\_SLAVE\_RELAY\_LOG\_READ\_FAILURE | Relay log read failure: %s |
| 1595 | HY000 | ER\_SLAVE\_RELAY\_LOG\_WRITE\_FAILURE | Relay log write failure: %s |
| 1596 | HY000 | ER\_SLAVE\_CREATE\_EVENT\_FAILURE | Failed to create %s |
| 1597 | HY000 | ER\_SLAVE\_MASTER\_COM\_FAILURE | Master command %s failed: %s |
| 1598 | HY000 | ER\_BINLOG\_LOGGING\_IMPOSSIBLE | Binary logging not possible. Message: %s |
| 1599 | HY000 | ER\_VIEW\_NO\_CREATION\_CTX | View `%s`.`%s` has no creation context |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1600 | HY000 | ER\_VIEW\_INVALID\_CREATION\_CTX | Creation context of view `%s`.`%s' is invalid |
| 1601 | HY000 | ER\_SR\_INVALID\_CREATION\_CTX | Creation context of stored routine `%s`.`%s` is invalid |
| 1602 | HY000 | ER\_TRG\_CORRUPTED\_FILE | Corrupted TRG file for table `%s`.`%s` |
| 1603 | HY000 | ER\_TRG\_NO\_CREATION\_CTX | Triggers for table `%s`.`%s` have no creation context |
| 1604 | HY000 | ER\_TRG\_INVALID\_CREATION\_CTX | Trigger creation context of table `%s`.`%s` is invalid |
| 1605 | HY000 | ER\_EVENT\_INVALID\_CREATION\_CTX | Creation context of event `%s`.`%s` is invalid |
| 1606 | HY000 | ER\_TRG\_CANT\_OPEN\_TABLE | Cannot open table for trigger `%s`.`%s` |
| 1607 | HY000 | ER\_CANT\_CREATE\_SROUTINE | Cannot create stored routine `%s`. Check warnings |
| 1608 |  | ER\_UNUSED\_11 | You should never see it |
| 1609 | HY000 | ER\_NO\_FORMAT\_DESCRIPTION\_EVENT \_BEFORE\_BINLOG\_STATEMENT | The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement. |
| 1610 | HY000 | ER\_SLAVE\_CORRUPT\_EVENT | Corrupted replication event was detected |
| 1611 | HY000 | ER\_LOAD\_DATA\_INVALID\_COLUMN | Invalid column reference (%s) in LOAD DATA |
| 1612 | HY000 | ER\_LOG\_PURGE\_NO\_FILE | Being purged log %s was not found |
| 1613 | XA106 | ER\_XA\_RBTIMEOUT | XA\_RBTIMEOUT: Transaction branch was rolled back: took too long |
| 1614 | XA102 | ER\_XA\_RBDEADLOCK | XA\_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected |
| 1615 | HY000 | ER\_NEED\_REPREPARE | Prepared statement needs to be re-prepared |
| 1616 | HY000 | ER\_DELAYED\_NOT\_SUPPORTED | DELAYED option not supported for table '%s' |
| 1617 | HY000 | WARN\_NO\_MASTER\_INF | The master info structure does not exist |
| 1618 | HY000 | WARN\_OPTION\_IGNORED | <%s> option ignored |
| 1619 | HY000 | WARN\_PLUGIN\_DELETE\_BUILTIN | Built-in plugins cannot be deleted |
| 1620 | HY000 | WARN\_PLUGIN\_BUSY | Plugin is busy and will be uninstalled on shutdown |
| 1621 | HY000 | ER\_VARIABLE\_IS\_READONLY | %s variable '%s' is read-only. Use SET %s to assign the value |
| 1622 | HY000 | ER\_WARN\_ENGINE\_TRANSACTION\_ROLLBACK | Storage engine %s does not support rollback for this statement. Transaction rolled back and must be restarted |
| 1623 | HY000 | ER\_SLAVE\_HEARTBEAT\_FAILURE | Unexpected master's heartbeat data: %s |
| 1624 | HY000 | ER\_SLAVE\_HEARTBEAT\_VALUE\_OUT\_OF\_RANGE | The requested value for the heartbeat period is either negative or exceeds the maximum allowed (%s seconds). |
| 1625 |  | ER\_UNUSED\_14 | You should never see it |
| 1626 | HY000 | ER\_CONFLICT\_FN\_PARSE\_ERROR | Error in parsing conflict function. Message: %s |
| 1627 | HY000 | ER\_EXCEPTIONS\_WRITE\_ERROR | Write to exceptions table failed. Message: %s" |
| 1628 | HY000 | ER\_TOO\_LONG\_TABLE\_COMMENT | Comment for table '%s' is too long (max = %lu) |
| 1629 | HY000 | ER\_TOO\_LONG\_FIELD\_COMMENT | Comment for field '%s' is too long (max = %lu) |
| 1630 | 42000 | ER\_FUNC\_INEXISTENT\_NAME\_COLLISION | FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual |
| 1631 | HY000 | ER\_DATABASE\_NAME | Database |
| 1632 | HY000 | ER\_TABLE\_NAME | Table |
| 1633 | HY000 | ER\_PARTITION\_NAME | Partition |
| 1634 | HY000 | ER\_SUBPARTITION\_NAME | Subpartition |
| 1635 | HY000 | ER\_TEMPORARY\_NAME | Temporary |
| 1636 | HY000 | ER\_RENAMED\_NAME | Renamed |
| 1637 | HY000 | ER\_TOO\_MANY\_CONCURRENT\_TRXS | Too many active concurrent transactions |
| 1638 | HY000 | WARN\_NON\_ASCII\_SEPARATOR\_NOT\_IMPLEMENTED | Non-ASCII separator arguments are not fully supported |
| 1639 | HY000 | ER\_DEBUG\_SYNC\_TIMEOUT | debug sync point wait timed out |
| 1640 | HY000 | ER\_DEBUG\_SYNC\_HIT\_LIMIT | debug sync point hit limit reached |
| 1641 | 42000 | ER\_DUP\_SIGNAL\_SET | Duplicate condition information item '%s' |
| 1642 | 01000 | ER\_SIGNAL\_WARN | Unhandled user-defined warning condition |
| 1643 | 02000 | ER\_SIGNAL\_NOT\_FOUND | Unhandled user-defined not found condition |
| 1644 | HY000 | ER\_SIGNAL\_EXCEPTION | Unhandled user-defined exception condition |
| 1645 | 0K000 | ER\_RESIGNAL\_WITHOUT\_ACTIVE\_HANDLER | RESIGNAL when handler not active |
| 1646 | HY000 | ER\_SIGNAL\_BAD\_CONDITION\_TYPE | SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE |
| 1647 | HY000 | WARN\_COND\_ITEM\_TRUNCATED | Data truncated for condition item '%s' |
| 1648 | HY000 | ER\_COND\_ITEM\_TOO\_LONG | Data too long for condition item '%s' |
| 1649 | HY000 | ER\_UNKNOWN\_LOCALE | Unknown locale: '%s' |
| 1650 | HY000 | ER\_SLAVE\_IGNORE\_SERVER\_IDS | The requested server id %d clashes with the slave startup option --replicate-same-server-id |
| 1651 | HY000 | ER\_QUERY\_CACHE\_DISABLED | Query cache is disabled; restart the server with query\_cache\_type=1 to enable it |
| 1652 | HY000 | ER\_SAME\_NAME\_PARTITION\_FIELD | Duplicate partition field name '%s' |
| 1653 | HY000 | ER\_PARTITION\_COLUMN\_LIST\_ERROR | Inconsistency in usage of column lists for partitioning |
| 1654 | HY000 | ER\_WRONG\_TYPE\_COLUMN\_VALUE\_ERROR | Partition column values of incorrect type |
| 1655 | HY000 | ER\_TOO\_MANY\_PARTITION\_FUNC\_FIELDS\_ERROR | Too many fields in '%s' |
| 1656 | HY000 | ER\_MAXVALUE\_IN\_VALUES\_IN | Cannot use MAXVALUE as value in VALUES IN |
| 1657 | HY000 | ER\_TOO\_MANY\_VALUES\_ERROR | Cannot have more than one value for this type of %s partitioning |
| 1658 | HY000 | ER\_ROW\_SINGLE\_PARTITION\_FIELD\_ERROR | Row expressions in VALUES IN only allowed for multi-field column partitioning |
| 1659 | HY000 | ER\_FIELD\_TYPE\_NOT\_ALLOWED\_AS\_PARTITION\_FIELD | Field '%s' is of a not allowed type for this type of partitioning |
| 1660 | HY000 | ER\_PARTITION\_FIELDS\_TOO\_LONG | The total length of the partitioning fields is too large |
| 1661 | HY000 | ER\_BINLOG\_ROW\_ENGINE\_AND\_STMT\_ENGINE | Cannot execute statement: impossible to write to binary log since both row-incapable engines and statement-incapable engines are involved. |
| 1662 | HY000 | ER\_BINLOG\_ROW\_MODE\_AND\_STMT\_ENGINE | Cannot execute statement: impossible to write to binary log since BINLOG\_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging. |
| 1663 | HY000 | ER\_BINLOG\_UNSAFE\_AND\_STMT\_ENGINE | Cannot execute statement: impossible to write to binary log since statement is unsafe, storage engine is limited to statement-based logging, and BINLOG\_FORMAT = MIXED. %s |
| 1664 | HY000 | ER\_BINLOG\_ROW\_INJECTION\_AND\_STMT\_ENGINE | Cannot execute statement: impossible to write to binary log since statement is in row format and at least one table uses a storage engine limited to statement-based logging. |
| 1665 | HY000 | ER\_BINLOG\_STMT\_MODE\_AND\_ROW\_ENGINE | Cannot execute statement: impossible to write to binary log since BINLOG\_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.%s |
| 1666 | HY000 | ER\_BINLOG\_ROW\_INJECTION\_AND\_STMT\_MODE | Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG\_FORMAT = STATEMENT. |
| 1667 | HY000 | ER\_BINLOG\_MULTIPLE\_ENGINES \_AND\_SELF\_LOGGING\_ENGINE | Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging. |
| 1668 | HY000 | ER\_BINLOG\_UNSAFE\_LIMIT | The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted. |
| 1669 | HY000 | ER\_BINLOG\_UNSAFE\_INSERT\_DELAYED | The statement is unsafe because it uses INSERT DELAYED. This is unsafe because the times when rows are inserted cannot be predicted. |
| 1670 | HY000 | ER\_BINLOG\_UNSAFE\_SYSTEM\_TABLE | The statement is unsafe because it uses the general log, slow query log, or performance\_schema table(s). This is unsafe because system tables may differ on slaves. |
| 1671 | HY000 | ER\_BINLOG\_UNSAFE\_AUTOINC\_COLUMNS | Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO\_INCREMENT column. Inserted values cannot be logged correctly. |
| 1672 | HY000 | ER\_BINLOG\_UNSAFE\_UDF | Statement is unsafe because it uses a UDF which may not return the same value on the slave. |
| 1673 | HY000 | ER\_BINLOG\_UNSAFE\_SYSTEM\_VARIABLE | Statement is unsafe because it uses a system variable that may have a different value on the slave. |
| 1674 | HY000 | ER\_BINLOG\_UNSAFE\_SYSTEM\_FUNCTION | Statement is unsafe because it uses a system function that may return a different value on the slave. |
| 1675 | HY000 | ER\_BINLOG\_UNSAFE\_NONTRANS\_AFTER\_TRANS | Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction. |
| 1676 | HY000 | ER\_MESSAGE\_AND\_STATEMENT | %s Statement: %s |
| 1677 | HY000 | ER\_SLAVE\_CONVERSION\_FAILED | Column %d of table '%s.%s' cannot be converted from type '%s' to type '%s' |
| 1678 | HY000 | ER\_SLAVE\_CANT\_CREATE\_CONVERSION | Can't create conversion table for table '%s.%s' |
| 1679 | HY000 | ER\_INSIDE\_TRANSACTION \_PREVENTS\_SWITCH\_BINLOG\_FORMAT | Cannot modify @@session.binlog\_format inside a transaction |
| 1680 | HY000 | ER\_PATH\_LENGTH | The path specified for %s is too long. |
| 1681 | HY000 | ER\_WARN\_DEPRECATED\_SYNTAX\_NO\_REPLACEMENT | '%s' is deprecated and will be removed in a future release. |
| 1682 | HY000 | ER\_WRONG\_NATIVE\_TABLE\_STRUCTURE | Native table '%s'.'%s' has the wrong structure |
| 1683 | HY000 | ER\_WRONG\_PERFSCHEMA\_USAGE | Invalid performance\_schema usage. |
| 1684 | HY000 | ER\_WARN\_I\_S\_SKIPPED\_TABLE | Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement |
| 1685 | HY000 | ER\_INSIDE\_TRANSACTION \_PREVENTS\_SWITCH\_BINLOG\_DIRECT | Cannot modify @@session.binlog\_direct\_non\_transactional\_updates inside a transaction |
| 1686 | HY000 | ER\_STORED\_FUNCTION\_PREVENTS \_SWITCH\_BINLOG\_DIRECT | Cannot change the binlog direct flag inside a stored function or trigger |
| 1687 | 42000 | ER\_SPATIAL\_MUST\_HAVE\_GEOM\_COL | A SPATIAL index may only contain a geometrical type column |
| 1688 | HY000 | ER\_TOO\_LONG\_INDEX\_COMMENT | Comment for index '%s' is too long (max = %lu) |
| 1689 | HY000 | ER\_LOCK\_ABORTED | Wait on a lock was aborted due to a pending exclusive lock |
| 1690 | 22003 | ER\_DATA\_OUT\_OF\_RANGE | %s value is out of range in '%s' |
| 1691 | HY000 | ER\_WRONG\_SPVAR\_TYPE\_IN\_LIMIT | A variable of a non-integer based type in LIMIT clause |
| 1692 | HY000 | ER\_BINLOG\_UNSAFE\_MULTIPLE\_ENGINES \_AND\_SELF\_LOGGING\_ENGINE | Mixing self-logging and non-self-logging engines in a statement is unsafe. |
| 1693 | HY000 | ER\_BINLOG\_UNSAFE\_MIXED\_STATEMENT | Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them. |
| 1694 | HY000 | ER\_INSIDE\_TRANSACTION\_ PREVENTS\_SWITCH\_SQL\_LOG\_BIN | Cannot modify @@session.sql\_log\_bin inside a transaction |
| 1695 | HY000 | ER\_STORED\_FUNCTION\_ PREVENTS\_SWITCH\_SQL\_LOG\_BIN | Cannot change the sql\_log\_bin inside a stored function or trigger |
| 1696 | HY000 | ER\_FAILED\_READ\_FROM\_PAR\_FILE | Failed to read from the .par file |
| 1697 | HY000 | ER\_VALUES\_IS\_NOT\_INT\_TYPE\_ERROR | VALUES value for partition '%s' must have type INT |
| 1698 | 28000 | ER\_ACCESS\_DENIED\_NO\_PASSWORD\_ERROR | Access denied for user '%s'@'%s' |
| 1699 | HY000 | ER\_SET\_PASSWORD\_AUTH\_PLUGIN | SET PASSWORD has no significance for users authenticating via plugins |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1700 | HY000 | ER\_GRANT\_PLUGIN\_USER\_EXISTS | GRANT with IDENTIFIED WITH is illegal because the user %-.\*s already exists |
| 1701 | 42000 | ER\_TRUNCATE\_ILLEGAL\_FK | Cannot truncate a table referenced in a foreign key constraint (%s) |
| 1702 | HY000 | ER\_PLUGIN\_IS\_PERMANENT | Plugin '%s' is force\_plus\_permanent and can not be unloaded |
| 1703 | HY000 | ER\_SLAVE\_HEARTBEAT\_VALUE\_OUT\_OF\_RANGE\_MIN | The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled. |
| 1704 | HY000 | ER\_SLAVE\_HEARTBEAT\_VALUE\_OUT\_OF\_RANGE\_MAX | The requested value for the heartbeat period exceeds the value of [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) seconds. A sensible value for the period should be less than the timeout. |
| 1705 | HY000 | ER\_STMT\_CACHE\_FULL | Multi-row statements required more than 'max\_binlog\_stmt\_cache\_size' bytes of storage; increase this mysqld variable and try again |
| 1706 | HY000 | ER\_MULTI\_UPDATE\_KEY\_CONFLICT | Primary key/partition key update is not allowed since the table is updated both as '%s' and '%s'. |
| 1707 | HY000 | ER\_TABLE\_NEEDS\_REBUILD | Table rebuild required. Please do "ALTER TABLE `%s` FORCE" or dump/reload to fix it! |
| 1708 | HY000 | WARN\_OPTION\_BELOW\_LIMIT | The value of '%s' should be no less than the value of '%s' |
| 1709 | HY000 | ER\_INDEX\_COLUMN\_TOO\_LONG | Index column size too large. The maximum column size is %lu bytes. |
| 1710 | HY000 | ER\_ERROR\_IN\_TRIGGER\_BODY | Trigger '%s' has an error in its body: '%s' |
| 1711 | HY000 | ER\_ERROR\_IN\_UNKNOWN\_TRIGGER\_BODY | Unknown trigger has an error in its body: '%s' |
| 1712 | HY000 | ER\_INDEX\_CORRUPT | Index %s is corrupted |
| 1713 | HY000 | ER\_UNDO\_RECORD\_TOO\_BIG | [Undo log](../undo-log/index) record is too big. |
| 1714 | HY000 | ER\_BINLOG\_UNSAFE\_INSERT\_IGNORE\_SELECT | INSERT IGNORE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. |
| 1715 | HY000 | ER\_BINLOG\_UNSAFE\_INSERT\_SELECT\_UPDATE | INSERT... SELECT... ON DUPLICATE KEY UPDATE is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are updated. This order cannot be predicted and may differ on master and the slave. |
| 1716 | HY000 | ER\_BINLOG\_UNSAFE\_REPLACE\_SELECT | REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave. |
| 1717 | HY000 | ER\_BINLOG\_UNSAFE\_CREATE\_IGNORE\_SELECT | CREATE... IGNORE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. |
| 1718 | HY000 | ER\_BINLOG\_UNSAFE\_CREATE\_REPLACE\_SELECT | CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave. |
| 1719 | HY000 | ER\_BINLOG\_UNSAFE\_UPDATE\_IGNORE | UPDATE IGNORE is unsafe because the order in which rows are updated determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. |
| 1720 |  | ER\_UNUSED\_15 | You should never see it |
| 1721 |  | ER\_UNUSED\_16 | You should never see it |
| 1722 | HY000 | ER\_BINLOG\_UNSAFE\_WRITE\_AUTOINC\_SELECT | Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave. |
| 1723 | HY000 | ER\_BINLOG\_UNSAFE\_CREATE\_SELECT\_AUTOINC | CREATE TABLE... SELECT... on a table with an auto-increment column is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are inserted. This order cannot be predicted and may differ on master and the slave. |
| 1724 | HY000 | ER\_BINLOG\_UNSAFE\_INSERT\_TWO\_KEYS | INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe |
| 1725 | HY000 | ER\_TABLE\_IN\_FK\_CHECK | Table is being used in foreign key check. |
| 1726 | HY000 | ER\_UNSUPPORTED\_ENGINE | Storage engine '%s' does not support system tables. [%s.%s] |
| 1727 | HY000 | ER\_BINLOG\_UNSAFE\_AUTOINC\_NOT\_FIRST | INSERT into autoincrement field which is not the first part in the composed primary key is unsafe. |
| 1728 | HY000 | ER\_CANNOT\_LOAD\_FROM\_TABLE\_V2 | Cannot load from %s.%s. The table is probably corrupted |
| 1729 | HY000 | ER\_MASTER\_DELAY\_VALUE\_OUT\_OF\_RANGE | The requested value %s for the master delay exceeds the maximum %u |
| 1730 | HY000 | ER\_ONLY\_FD\_AND\_RBR\_EVENTS\_ALLOWED\_IN\_BINLOG\_STATEMENT | Only Format\_description\_log\_event and row events are allowed in BINLOG statements (but %s was provided |
| 1731 | HY000 | ER\_PARTITION\_EXCHANGE\_DIFFERENT\_OPTION | Non matching attribute '%s' between partition and table |
| 1732 | HY000 | ER\_PARTITION\_EXCHANGE\_PART\_TABLE | Table to exchange with partition is partitioned: '%s' |
| 1733 | HY000 | ER\_PARTITION\_EXCHANGE\_TEMP\_TABLE | Table to exchange with partition is temporary: '%s' |
| 1734 | HY000 | ER\_PARTITION\_INSTEAD\_OF\_SUBPARTITION | Subpartitioned table, use subpartition instead of partition |
| 1735 | HY000 | ER\_UNKNOWN\_PARTITION | Unknown partition '%s' in table '%s' |
| 1736 | HY000 | ER\_TABLES\_DIFFERENT\_METADATA | Tables have different definitions |
| 1737 | HY000 | ER\_ROW\_DOES\_NOT\_MATCH\_PARTITION | Found a row that does not match the partition |
| 1738 | HY000 | ER\_BINLOG\_CACHE\_SIZE\_GREATER\_THAN\_MAX | Option binlog\_cache\_size (%lu) is greater than max\_binlog\_cache\_size (%lu); setting binlog\_cache\_size equal to max\_binlog\_cache\_size. |
| 1739 | HY000 | ER\_WARN\_INDEX\_NOT\_APPLICABLE | Cannot use %s access on index '%s' due to type or collation conversion on field '%s' |
| 1740 | HY000 | ER\_PARTITION\_EXCHANGE\_FOREIGN\_KEY | Table to exchange with partition has foreign key references: '%s' |
| 1741 | HY000 | ER\_NO\_SUCH\_KEY\_VALUE | Key value '%s' was not found in table '%s.%s' |
| 1742 | HY000 | ER\_RPL\_INFO\_DATA\_TOO\_LONG | Data for column '%s' too long |
| 1743 | HY000 | ER\_NETWORK\_READ\_EVENT\_CHECKSUM\_FAILURE | Replication event checksum verification failed while reading from network. |
| 1744 | HY000 | ER\_BINLOG\_READ\_EVENT\_CHECKSUM\_FAILURE | Replication event checksum verification failed while reading from a log file. |
| 1745 | HY000 | ER\_BINLOG\_STMT\_CACHE\_SIZE\_GREATER\_THAN\_MAX | Option binlog\_stmt\_cache\_size (%lu) is greater than max\_binlog\_stmt\_cache\_size (%lu); setting binlog\_stmt\_cache\_size equal to max\_binlog\_stmt\_cache\_size. |
| 1746 | HY000 | ER\_CANT\_UPDATE\_TABLE\_IN\_CREATE\_TABLE\_SELECT | Can't update table '%s' while '%s' is being created. |
| 1747 | HY000 | ER\_PARTITION\_CLAUSE\_ON\_NONPARTITIONED | PARTITION () clause on non partitioned table |
| 1748 | HY000 | ER\_ROW\_DOES\_NOT\_MATCH\_GIVEN\_PARTITION\_SET | Found a row not matching the given partition set |
| 1749 | HY000 | ER\_NO\_SUCH\_PARTITION\_UNUSED | partition '%s' doesn't exist |
| 1750 | HY000 | ER\_CHANGE\_RPL\_INFO\_REPOSITORY\_FAILURE | Failure while changing the type of replication repository: %s. |
| 1751 | HY000 | ER\_WARNING\_NOT\_COMPLETE\_ROLLBACK\_WITH\_CREATED\_TEMP\_TABLE | The creation of some temporary tables could not be rolled back. |
| 1752 | HY000 | ER\_WARNING\_NOT\_COMPLETE\_ROLLBACK\_WITH\_DROPPED\_TEMP\_TABLE | Some temporary tables were dropped, but these operations could not be rolled back. |
| 1753 | HY000 | ER\_MTS\_FEATURE\_IS\_NOT\_SUPPORTED | %s is not supported in multi-threaded slave mode. %s |
| 1754 | HY000 | ER\_MTS\_UPDATED\_DBS\_GREATER\_MAX | The number of modified databases exceeds the maximum %d; the database names will not be included in the replication event metadata. |
| 1755 | HY000 | ER\_MTS\_CANT\_PARALLEL | Cannot execute the current event group in the parallel mode. Encountered event %s, relay-log name %s, position %s which prevents execution of this event group in parallel mode. Reason: %s. |
| 1756 | HY000 | ER\_MTS\_INCONSISTENT\_DATA | %s |
| 1757 | HY000 | ER\_FULLTEXT\_NOT\_SUPPORTED\_WITH\_PARTITIONING | FULLTEXT index is not supported for partitioned tables. |
| 1758 | 35000 | ER\_DA\_INVALID\_CONDITION\_NUMBER | Invalid condition number |
| 1759 | HY000 | ER\_INSECURE\_PLAIN\_TEXT | Sending passwords in plain text without SSL/TLS is extremely insecure. |
| 1760 | HY000 | ER\_INSECURE\_CHANGE\_MASTER | Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. |
| 1761 | 23000 | ER\_FOREIGN\_DUPLICATE\_KEY\_WITH\_CHILD\_INFO | Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in table '%s', key '%s' |
| 1762 | 23000 | ER\_FOREIGN\_DUPLICATE\_KEY\_WITHOUT\_CHILD\_INFO | Foreign key constraint for table '%s', record '%s' would lead to a duplicate entry in a child table |
| 1763 | HY000 | ER\_SQLTHREAD\_WITH\_SECURE\_SLAVE | Setting authentication options is not possible when only the Slave SQL Thread is being started. |
| 1764 | HY000 | ER\_TABLE\_HAS\_NO\_FT | The table does not have FULLTEXT index to support this query |
| 1765 | HY000 | ER\_VARIABLE\_NOT\_SETTABLE\_IN\_SF\_OR\_TRIGGER | The system variable %s cannot be set in stored functions or triggers. |
| 1766 | HY000 | ER\_VARIABLE\_NOT\_SETTABLE\_IN\_TRANSACTION | The system variable %s cannot be set when there is an ongoing transaction. |
| 1767 | HY000 | ER\_GTID\_NEXT\_IS\_NOT\_IN\_GTID\_NEXT\_LIST | The system variable @@SESSION.GTID\_NEXT has the value %s, which is not listed in @@SESSION.GTID\_NEXT\_LIST. |
| 1768 | HY000 | ER\_CANT\_CHANGE\_GTID\_NEXT\_IN\_TRANSACTION\_WHEN\_GTID\_NEXT\_LIST\_IS\_NULL | The system variable @@SESSION.GTID\_NEXT cannot change inside a transaction. |
| 1769 | HY000 | ER\_SET\_STATEMENT\_CANNOT\_INVOKE\_FUNCTION | The statement 'SET %s' cannot invoke a stored function. |
| 1770 | HY000 | ER\_GTID\_NEXT\_CANT\_BE\_AUTOMATIC\_IF\_GTID\_NEXT\_LIST\_IS\_NON\_NULL | The system variable @@SESSION.GTID\_NEXT cannot be 'AUTOMATIC' when @@SESSION.GTID\_NEXT\_LIST is non-NULL. |
| 1771 | HY000 | ER\_SKIPPING\_LOGGED\_TRANSACTION | Skipping transaction %s because it has already been executed and logged. |
| 1772 | HY000 | ER\_MALFORMED\_GTID\_SET\_SPECIFICATION | Malformed GTID set specification '%s'. |
| 1773 | HY000 | ER\_MALFORMED\_GTID\_SET\_ENCODING | Malformed GTID set encoding. |
| 1774 | HY000 | ER\_MALFORMED\_GTID\_SPECIFICATION | Malformed GTID specification '%s'. |
| 1775 | HY000 | ER\_GNO\_EXHAUSTED | Impossible to generate Global Transaction Identifier: the integer component reached the maximal value. Restart the server with a new server\_uuid. |
| 1776 | HY000 | ER\_BAD\_SLAVE\_AUTO\_POSITION | Parameters MASTER\_LOG\_FILE, MASTER\_LOG\_POS, RELAY\_LOG\_FILE and RELAY\_LOG\_POS cannot be set when MASTER\_AUTO\_POSITION is active. |
| 1777 | HY000 | ER\_AUTO\_POSITION\_REQUIRES\_GTID\_MODE\_ON | CHANGE MASTER TO MASTER\_AUTO\_POSITION = 1 can only be executed when @@GLOBAL.GTID\_MODE = ON. |
| 1778 | HY000 | ER\_CANT\_DO\_IMPLICIT\_COMMIT\_IN\_TRX\_WHEN\_GTID\_NEXT\_IS\_SET | Cannot execute statements with implicit commit inside a transaction when @@SESSION.GTID\_NEXT != AUTOMATIC. |
| 1779 | HY000 | ER\_GTID\_MODE\_2\_OR\_3\_REQUIRES\_DISABLE\_GTID\_UNSAFE\_STATEMENTS\_ON | GTID\_MODE = ON or GTID\_MODE = UPGRADE\_STEP\_2 requires DISABLE\_GTID\_UNSAFE\_STATEMENTS = 1. |
| 1779 | HY000 | ER\_GTID\_MODE\_2\_OR\_3\_REQUIRES\_ENFORCE\_GTID\_CONSISTENCY\_ON | @@GLOBAL.GTID\_MODE = ON or UPGRADE\_STEP\_2 requires @@GLOBAL.ENFORCE\_GTID\_CONSISTENCY = 1. |
| 1780 | HY000 | ER\_GTID\_MODE\_REQUIRES\_BINLOG | @@GLOBAL.GTID\_MODE = ON or UPGRADE\_STEP\_1 or UPGRADE\_STEP\_2 requires --log-bin and --log-slave-updates. |
| 1781 | HY000 | ER\_CANT\_SET\_GTID\_NEXT\_TO\_GTID\_WHEN\_GTID\_MODE\_IS\_OFF | @@SESSION.GTID\_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID\_MODE = OFF. |
| 1782 | HY000 | ER\_CANT\_SET\_GTID\_NEXT\_TO\_ANONYMOUS\_WHEN\_GTID\_MODE\_IS\_ON | @@SESSION.GTID\_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID\_MODE = ON. |
| 1783 | HY000 | ER\_CANT\_SET\_GTID\_NEXT\_LIST\_TO\_NON\_NULL\_WHEN\_GTID\_MODE\_IS\_OFF | @@SESSION.GTID\_NEXT\_LIST cannot be set to a non-NULL value when @@GLOBAL.GTID\_MODE = OFF. |
| 1784 | HY000 | ER\_FOUND\_GTID\_EVENT\_WHEN\_GTID\_MODE\_IS\_OFF | Found a Gtid\_log\_event or Previous\_gtids\_log\_event when @@GLOBAL.GTID\_MODE = OFF. |
| 1785 | HY000 | ER\_GTID\_UNSAFE\_NON\_TRANSACTIONAL\_TABLE | When @@GLOBAL.ENFORCE\_GTID\_CONSISTENCY = 1, updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as updates to transactional tables. |
| 1786 | HY000 | ER\_GTID\_UNSAFE\_CREATE\_SELECT | CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE\_GTID\_CONSISTENCY = 1. |
| 1787 | HY000 | ER\_GTID\_UNSAFE\_CREATE\_DROP\_TEMPORARY\_TABLE\_IN\_TRANSACTION | When @@GLOBAL.ENFORCE\_GTID\_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1. |
| 1788 | HY000 | ER\_GTID\_MODE\_CAN\_ONLY\_CHANGE\_ONE\_STEP\_AT\_A\_TIME | The value of @@GLOBAL.GTID\_MODE can only change one step at a time: OFF <-> UPGRADE\_STEP\_1 <-> UPGRADE\_STEP\_2 <-> ON. Also note that this value must be stepped up or down simultaneously on all servers; see the Manual for instructions. |
| 1789 | HY000 | ER\_MASTER\_HAS\_PURGED\_REQUIRED\_GTIDS | The slave is connecting using CHANGE MASTER TO MASTER\_AUTO\_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires. |
| 1790 | HY000 | ER\_CANT\_SET\_GTID\_NEXT\_WHEN\_OWNING\_GTID | @@SESSION.GTID\_NEXT cannot be changed by a client that owns a GTID. The client owns %s. Ownership is released on COMMIT or ROLLBACK. |
| 1791 | HY000 | ER\_UNKNOWN\_EXPLAIN\_FORMAT | Unknown EXPLAIN format name: '%s' |
| 1792 | 25006 | ER\_CANT\_EXECUTE\_IN\_READ\_ONLY\_TRANSACTION | Cannot execute statement in a READ ONLY transaction. |
| 1793 | HY000 | ER\_TOO\_LONG\_TABLE\_PARTITION\_COMMENT | Comment for table partition '%s' is too long (max = %lu |
| 1794 | HY000 | ER\_SLAVE\_CONFIGURATION | Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log. |
| 1795 | HY000 | ER\_INNODB\_FT\_LIMIT | InnoDB presently supports one FULLTEXT index creation at a time |
| 1796 | HY000 | ER\_INNODB\_NO\_FT\_TEMP\_TABLE | Cannot create FULLTEXT index on temporary InnoDB table |
| 1797 | HY000 | ER\_INNODB\_FT\_WRONG\_DOCID\_COLUMN | Column '%s' is of wrong type for an InnoDB FULLTEXT index |
| 1798 | HY000 | ER\_INNODB\_FT\_WRONG\_DOCID\_INDEX | Index '%s' is of wrong type for an InnoDB FULLTEXT index |
| 1799 | HY000 | ER\_INNODB\_ONLINE\_LOG\_TOO\_BIG | Creating index '%s' required more than 'innodb\_online\_alter\_log\_max\_size' bytes of modification log. Please try again. |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1800 | HY000 | ER\_UNKNOWN\_ALTER\_ALGORITHM | Unknown ALGORITHM '%s' |
| 1801 | HY000 | ER\_UNKNOWN\_ALTER\_LOCK | Unknown LOCK type '%s' |
| 1802 | HY000 | ER\_MTS\_CHANGE\_MASTER\_CANT\_RUN\_WITH\_GAPS | CHANGE MASTER cannot be executed when the slave was stopped with an error or killed in MTS mode. Consider using RESET SLAVE or START SLAVE UNTIL. |
| 1803 | HY000 | ER\_MTS\_RECOVERY\_FAILURE | Cannot recover after SLAVE errored out in parallel execution mode. Additional error messages can be found in the MySQL error log. |
| 1804 | HY000 | ER\_MTS\_RESET\_WORKERS | Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log. |
| 1805 | HY000 | ER\_COL\_COUNT\_DOESNT\_MATCH\_CORRUPTED\_V2 | Column count of %s.%s is wrong. Expected %d, found %d. The table is probably corrupted |
| 1806 | HY000 | ER\_SLAVE\_SILENT\_RETRY\_TRANSACTION | Slave must silently retry current transaction |
| 1807 | HY000 | ER\_DISCARD\_FK\_CHECKS\_RUNNING | There is a foreign key check running on table '%s'. Cannot discard the table. |
| 1808 | HY000 | ER\_TABLE\_SCHEMA\_MISMATCH | Schema mismatch (%s |
| 1809 | HY000 | ER\_TABLE\_IN\_SYSTEM\_TABLESPACE | Table '%s' in system tablespace |
| 1810 | HY000 | ER\_IO\_READ\_ERROR | IO Read error: (%lu, %s) %s |
| 1811 | HY000 | ER\_IO\_WRITE\_ERROR | IO Write error: (%lu, %s) %s |
| 1812 | HY000 | ER\_TABLESPACE\_MISSING | Tablespace is missing for table '%s' |
| 1813 | HY000 | ER\_TABLESPACE\_EXISTS | Tablespace for table '%s' exists. Please DISCARD the tablespace before IMPORT. |
| 1814 | HY000 | ER\_TABLESPACE\_DISCARDED | Tablespace has been discarded for table '%s' |
| 1815 | HY000 | ER\_INTERNAL\_ERROR | Internal error: %s |
| 1816 | HY000 | ER\_INNODB\_IMPORT\_ERROR | ALTER TABLE '%s' IMPORT TABLESPACE failed with error %lu : '%s' |
| 1817 | HY000 | ER\_INNODB\_INDEX\_CORRUPT | Index corrupt: %s |
| 1818 | HY000 | ER\_INVALID\_YEAR\_COLUMN\_LENGTH | YEAR(%lu) column type is deprecated. Creating YEAR(4) column instead. |
| 1819 | HY000 | ER\_NOT\_VALID\_PASSWORD | Your password does not satisfy the current policy requirements |
| 1820 | HY000 | ER\_MUST\_CHANGE\_PASSWORD | You must SET PASSWORD before executing this statement |
| 1821 | HY000 | ER\_FK\_NO\_INDEX\_CHILD | Failed to add the foreign key constaint. Missing index for constraint '%s' in the foreign table '%s' |
| 1822 | HY000 | ER\_FK\_NO\_INDEX\_PARENT | Failed to add the foreign key constaint. Missing index for constraint '%s' in the referenced table '%s' |
| 1823 | HY000 | ER\_FK\_FAIL\_ADD\_SYSTEM | Failed to add the foreign key constraint '%s' to system tables |
| 1824 | HY000 | ER\_FK\_CANNOT\_OPEN\_PARENT | Failed to open the referenced table '%s' |
| 1825 | HY000 | ER\_FK\_INCORRECT\_OPTION | Failed to add the foreign key constraint on table '%s'. Incorrect options in FOREIGN KEY constraint '%s' |
| 1826 | HY000 | ER\_FK\_DUP\_NAME | Duplicate foreign key constraint name '%s' |
| 1827 | HY000 | ER\_PASSWORD\_FORMAT | The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function. |
| 1828 | HY000 | ER\_FK\_COLUMN\_CANNOT\_DROP | Cannot drop column '%s': needed in a foreign key constraint '%s' |
| 1829 | HY000 | ER\_FK\_COLUMN\_CANNOT\_DROP\_CHILD | Cannot drop column '%s': needed in a foreign key constraint '%s' of table '%s' |
| 1830 | HY000 | ER\_FK\_COLUMN\_NOT\_NULL | Column '%s' cannot be NOT NULL: needed in a foreign key constraint '%s' SET NULL |
| 1831 | HY000 | ER\_DUP\_INDEX | Duplicate index '%s' defined on the table '%s.%s'. This is deprecated and will be disallowed in a future release. |
| 1832 | HY000 | ER\_FK\_COLUMN\_CANNOT\_CHANGE | Cannot change column '%s': used in a foreign key constraint '%s' |
| 1833 | HY000 | ER\_FK\_COLUMN\_CANNOT\_CHANGE\_CHILD | Cannot change column '%s': used in a foreign key constraint '%s' of table '%s' |
| 1834 | HY000 | ER\_FK\_CANNOT\_DELETE\_PARENT | Cannot delete rows from table which is parent in a foreign key constraint '%s' of table '%s' |
| 1835 | HY000 | ER\_MALFORMED\_PACKET | Malformed communication packet. |
| 1836 | HY000 | ER\_READ\_ONLY\_MODE | Running in read-only mode |
| 1837 | HY000 | ER\_GTID\_NEXT\_TYPE\_UNDEFINED\_GROUP | When @@SESSION.GTID\_NEXT is set to a GTID, you must explicitly set it to a different value after a COMMIT or ROLLBACK. Please check GTID\_NEXT variable manual page for detailed explanation. Current @@SESSION.GTID\_NEXT is '%s'. |
| 1838 | HY000 | ER\_VARIABLE\_NOT\_SETTABLE\_IN\_SP | The system variable %s cannot be set in stored procedures. |
| 1839 | HY000 | ER\_CANT\_SET\_GTID\_PURGED\_WHEN\_GTID\_MODE\_IS\_OFF | @@GLOBAL.GTID\_PURGED can only be set when @@GLOBAL.GTID\_MODE = ON. |
| 1840 | HY000 | ER\_CANT\_SET\_GTID\_PURGED\_WHEN\_GTID\_EXECUTED\_IS\_NOT\_EMPTY | @@GLOBAL.GTID\_PURGED can only be set when @@GLOBAL.GTID\_EXECUTED is empty. |
| 1841 | HY000 | ER\_CANT\_SET\_GTID\_PURGED\_WHEN\_OWNED\_GTIDS\_IS\_NOT\_EMPTY | @@GLOBAL.GTID\_PURGED can only be set when there are no ongoing transactions (not even in other clients). |
| 1842 | HY000 | ER\_GTID\_PURGED\_WAS\_CHANGED | @@GLOBAL.GTID\_PURGED was changed from '%s' to '%s'. |
| 1843 | HY000 | ER\_GTID\_EXECUTED\_WAS\_CHANGED | @@GLOBAL.GTID\_EXECUTED was changed from '%s' to '%s'. |
| 1844 | HY000 | ER\_BINLOG\_STMT\_MODE\_AND\_NO\_REPL\_TABLES | Cannot execute statement: impossible to write to binary log since BINLOG\_FORMAT = STATEMENT, and both replicated and non replicated tables are written to. |
| 1845 | 0A000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED | %s is not supported for this operation. Try %s. |
| 1846 | 0A000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON | %s is not supported. Reason: %s. Try %s. |
| 1847 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_COPY | COPY algorithm requires a lock |
| 1848 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_PARTITION | Partition specific operations do not yet support LOCK/ALGORITHM |
| 1849 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_FK\_RENAME | Columns participating in a foreign key are renamed |
| 1850 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_COLUMN\_TYPE | Cannot change column type INPLACE |
| 1851 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_FK\_CHECK | Adding foreign keys needs foreign\_key\_checks=OFF |
| 1852 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_IGNORE | Creating unique indexes with IGNORE requires COPY algorithm to remove duplicate rows |
| 1853 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_NOPK | Dropping a primary key is not allowed without also adding a new primary key |
| 1854 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_AUTOINC | Adding an auto-increment column requires a lock |
| 1855 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_HIDDEN\_FTS | Cannot replace hidden FTS\_DOC\_ID with a user-visible one |
| 1856 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_CHANGE\_FTS | Cannot drop or rename FTS\_DOC\_ID |
| 1857 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_FTS | Fulltext index creation requires a lock |
| 1858 | HY000 | ER\_SQL\_SLAVE\_SKIP\_COUNTER\_NOT\_SETTABLE\_IN\_GTID\_MODE | sql\_slave\_skip\_counter can not be set when the server is running with @@GLOBAL.GTID\_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction |
| 1859 | 23000 | ER\_DUP\_UNKNOWN\_IN\_INDEX | Duplicate entry for key '%s' |
| 1860 | HY000 | ER\_IDENT\_CAUSES\_TOO\_LONG\_PATH | Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'. |
| 1861 | HY000 | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_NOT\_NULL | cannot silently convert NULL values, as required in this SQL\_MODE |
| 1862 | HY000 | ER\_MUST\_CHANGE\_PASSWORD\_LOGIN | Your password has expired. To log in you must change it using a client that supports expired passwords. |
| 1863 | HY000 | ER\_ROW\_IN\_WRONG\_PARTITION | Found a row in wrong partition %s |
| 1864 | HY000 | ER\_MTS\_EVENT\_BIGGER\_PENDING\_JOBS\_SIZE\_MAX | Cannot schedule event %s, relay-log name %s, position %s to Worker thread because its size %lu exceeds %lu of slave\_pending\_jobs\_size\_max. |
| 1865 | HY000 | ER\_INNODB\_NO\_FT\_USES\_PARSER | Cannot CREATE FULLTEXT INDEX WITH PARSER on InnoDB table |
| 1866 | HY000 | ER\_BINLOG\_LOGICAL\_CORRUPTION | The binary log file '%s' is logically corrupted: %s |
| 1867 | HY000 | ER\_WARN\_PURGE\_LOG\_IN\_USE | file %s was not purged because it was being read by %d thread(s), purged only %d out of %d files. |
| 1868 | HY000 | ER\_WARN\_PURGE\_LOG\_IS\_ACTIVE | file %s was not purged because it is the active log file. |
| 1869 | HY000 | ER\_AUTO\_INCREMENT\_CONFLICT | Auto-increment value in UPDATE conflicts with internally generated values |
| 1870 | HY000 | WARN\_ON\_BLOCKHOLE\_IN\_RBR | Row events are not logged for %s statements that modify BLACKHOLE tables in row format. Table(s): '%s' |
| 1871 | HY000 | ER\_SLAVE\_MI\_INIT\_REPOSITORY | Slave failed to initialize master info structure from the repository |
| 1872 | HY000 | ER\_SLAVE\_RLI\_INIT\_REPOSITORY | Slave failed to initialize relay log info structure from the repository |
| 1873 | 28000 | ER\_ACCESS\_DENIED\_CHANGE\_USER\_ERROR | Access denied trying to change to user '%s'@'%s' (using password: %s). Disconnecting. |
| 1874 | HY000 | ER\_INNODB\_READ\_ONLY | InnoDB is in read only mode. |
| 1875 | HY000 | ER\_STOP\_SLAVE\_SQL\_THREAD\_TIMEOUT | STOP SLAVE command execution is incomplete: Slave SQL thread got the stop signal, thread is busy, SQL thread will stop once the current task is complete. |
| 1876 | HY000 | ER\_STOP\_SLAVE\_IO\_THREAD\_TIMEOUT | STOP SLAVE command execution is incomplete: Slave IO thread got the stop signal, thread is busy, IO thread will stop once the current task is complete. |
| 1877 | HY000 | ER\_TABLE\_CORRUPT | Operation cannot be performed. The table '%s.%s' is missing, corrupt or contains bad data. |
| 1878 | HY000 | ER\_TEMP\_FILE\_WRITE\_FAILURE | Temporary file write failure. |
| 1879 | HY000 | ER\_INNODB\_FT\_AUX\_NOT\_HEX\_ID | Upgrade index name failed, please use create index(alter table) algorithm copy to rebuild index. |
| 1880 |  | ER\_LAST\_MYSQL\_ERROR\_MESSAGE | " |

 
MariaDB-specific error codes
----------------------------

 


| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 1900 |  | ER\_UNUSED\_18 | " |
| 1901 |  | ER\_GENERATED\_COLUMN\_FUNCTION\_IS\_NOT\_ALLOWED | Function or expression '%s' cannot be used in the %s clause of %`s |
| 1902 |  | ER\_UNUSED\_19 | " |
| 1903 |  | ER\_PRIMARY\_KEY\_BASED\_ON\_GENERATED\_COLUMN | Primary key cannot be defined upon a generated column |
| 1904 |  | ER\_KEY\_BASED\_ON\_GENERATED\_VIRTUAL\_COLUMN | Key/Index cannot be defined on a virtual generated column |
| 1905 |  | ER\_WRONG\_FK\_OPTION\_FOR\_GENERATED\_COLUMN | Cannot define foreign key with %s clause on a generated column |
| 1906 |  | ER\_WARNING\_NON\_DEFAULT\_VALUE\_FOR\_GENERATED\_COLUMN | The value specified for generated column '%s' in table '%s' has been ignored |
| 1907 |  | ER\_UNSUPPORTED\_ACTION\_ON\_GENERATED\_COLUMN | This is not yet supported for generated columns |
| 1908 |  | ER\_UNUSED\_20 | " |
| 1909 |  | ER\_UNUSED\_21 | " |
| 1910 |  | ER\_UNSUPPORTED\_ENGINE\_FOR\_GENERATED\_COLUMNS | %s storage engine does not support generated columns |
| 1911 |  | ER\_UNKNOWN\_OPTION | Unknown option '%-.64s' |
| 1912 |  | ER\_BAD\_OPTION\_VALUE | Incorrect value '%-.64s' for option '%-.64s' |
| 1913 |  | ER\_UNUSED\_6 | You should never see it |
| 1914 |  | ER\_UNUSED\_7 | You should never see it |
| 1915 |  | ER\_UNUSED\_8 | You should never see it |
| 1916 |  | ER\_DATA\_OVERFLOW 22003 | Got overflow when converting '%-.128s' to %-.32s. Value truncated. |
| 1917 |  | ER\_DATA\_TRUNCATED 22003 | Truncated value '%-.128s' when converting to %-.32s |
| 1918 |  | ER\_BAD\_DATA 22007 | Encountered illegal value '%-.128s' when converting to %-.32s |
| 1919 |  | ER\_DYN\_COL\_WRONG\_FORMAT | Encountered illegal format of dynamic column string |
| 1920 |  | ER\_DYN\_COL\_IMPLEMENTATION\_LIMIT | Dynamic column implementation limit reached |
| 1921 |  | ER\_DYN\_COL\_DATA 22007 | Illegal value used as argument of dynamic column function |
| 1922 |  | ER\_DYN\_COL\_WRONG\_CHARSET | Dynamic column contains unknown character set |
| 1923 |  | ER\_ILLEGAL\_SUBQUERY\_OPTIMIZER\_SWITCHES | At least one of the 'in\_to\_exists' or 'materialization' optimizer\_switch flags must be 'on'. |
| 1924 |  | ER\_QUERY\_CACHE\_IS\_DISABLED | Query cache is disabled (resize or similar command in progress); repeat this command later |
| 1925 |  | ER\_QUERY\_CACHE\_IS\_GLOBALY\_DISABLED | Query cache is globally disabled and you can't enable it only for this session |
| 1926 |  | ER\_VIEW\_ORDERBY\_IGNORED | View '%-.192s'.'%-.192s' ORDER BY clause ignored because there is other ORDER BY clause already. |
| 1927 |  | ER\_CONNECTION\_KILLED 70100 | Connection was killed |
| 1928 | ER\_UNUSED\_11 | You should never see it |
| 1929 |  | ER\_INSIDE\_TRANSACTION\_PREVENTS\_SWITCH\_SKIP\_REPLICATION | Cannot modify @@session.skip\_replication inside a transaction |
| 1930 |  | ER\_STORED\_FUNCTION\_PREVENTS\_SWITCH\_SKIP\_REPLICATION | Cannot modify @@session.skip\_replication inside a stored function or trigger |
| 1931 |  | ER\_QUERY\_EXCEEDED\_ROWS\_EXAMINED\_LIMIT | Query execution was interrupted. The query examined at least %llu rows, which exceeds LIMIT ROWS EXAMINED (%llu). The query result may be incomplete. |
| 1932 |  | ER\_NO\_SUCH\_TABLE\_IN\_ENGINE 42S02 | Table '%-.192s.%-.192s' doesn't exist in engine |
| 1933 |  | ER\_TARGET\_NOT\_EXPLAINABLE | Target is not running an EXPLAINable command |
| 1934 |  | ER\_CONNECTION\_ALREADY\_EXISTS | Connection '%.\*s' conflicts with existing connection '%.\*s' |
| 1935 |  | ER\_MASTER\_LOG\_PREFIX | Master '%.\*s': |
| 1936 |  | ER\_CANT\_START\_STOP\_SLAVE | Can't %s SLAVE '%.\*s' |
| 1937 |  | ER\_SLAVE\_STARTED | SLAVE '%.\*s' started |
| 1938 |  | ER\_SLAVE\_STOPPED | SLAVE '%.\*s' stopped |
| 1939 |  | ER\_SQL\_DISCOVER\_ERROR | Engine %s failed to discover table %`-.192s.%`-.192s with '%s' |
| 1940 |  | ER\_FAILED\_GTID\_STATE\_INIT | Failed initializing replication GTID state |
| 1941 |  | ER\_INCORRECT\_GTID\_STATE | Could not parse GTID list |
| 1942 |  | ER\_CANNOT\_UPDATE\_GTID\_STATE | Could not update replication slave gtid state |
| 1943 |  | ER\_DUPLICATE\_GTID\_DOMAIN | GTID %u-%u-%llu and %u-%u-%llu conflict (duplicate domain id %u) |
| 1944 |  | ER\_GTID\_OPEN\_TABLE\_FAILED | Failed to open %s.%s |
| 1945 |  | ER\_GTID\_POSITION\_NOT\_FOUND\_IN\_BINLOG | Connecting slave requested to start from GTID %u-%u-%llu, which is not in the master's binlog |
| 1946 |  | ER\_CANNOT\_LOAD\_SLAVE\_GTID\_STATE | Failed to load replication slave GTID position from table %s.%s |
| 1947 |  | ER\_MASTER\_GTID\_POS\_CONFLICTS\_WITH\_BINLOG | Specified GTID %u-%u-%llu conflicts with the binary log which contains a more recent GTID %u-%u-%llu. If MASTER\_GTID\_POS=CURRENT\_POS is used, the binlog position will override the new value of @@gtid\_slave\_pos. |
| 1948 |  | ER\_MASTER\_GTID\_POS\_MISSING\_DOMAIN | Specified value for @@gtid\_slave\_pos contains no value for replication domain %u. This conflicts with the binary log which contains GTID %u-%u-%llu. If MASTER\_GTID\_POS=CURRENT\_POS is used, the binlog position will override the new value of @@gtid\_slave\_pos. |
| 1949 |  | ER\_UNTIL\_REQUIRES\_USING\_GTID | START SLAVE UNTIL master\_gtid\_pos requires that slave is using GTID |
| 1950 |  | ER\_GTID\_STRICT\_OUT\_OF\_ORDER | An attempt was made to binlog GTID %u-%u-%llu which would create an out-of-order sequence number with existing GTID %u-%u-%llu, and gtid strict mode is enabled. |
| 1951 |  | ER\_GTID\_START\_FROM\_BINLOG\_HOLE | The binlog on the master is missing the GTID %u-%u-%llu requested by the slave (even though a subsequent sequence number does exist), and GTID strict mode is enabled |
| 1952 |  | ER\_SLAVE\_UNEXPECTED\_MASTER\_SWITCH | Unexpected GTID received from master after reconnect. This normally indicates that the master server was replaced without restarting the slave threads. %s |
| 1953 |  | ER\_INSIDE\_TRANSACTION\_PREVENTS\_SWITCH\_GTID\_DOMAIN\_ID\_SEQ\_NO | Cannot modify @@session.gtid\_domain\_id or @@session.gtid\_seq\_no inside a transaction |
| 1954 |  | ER\_STORED\_FUNCTION\_PREVENTS\_SWITCH\_GTID\_DOMAIN\_ID\_SEQ\_NO | Cannot modify @@session.gtid\_domain\_id or @@session.gtid\_seq\_no inside a stored function or trigger |
| 1955 |  | ER\_GTID\_POSITION\_NOT\_FOUND\_IN\_BINLOG2 | Connecting slave requested to start from GTID %u-%u-%llu, which is not in the master's binlog. Since the master's binlog contains GTIDs with higher sequence numbers, it probably means that the slave has diverged due to executing extra errorneous transactions |
| 1956 |  | ER\_BINLOG\_MUST\_BE\_EMPTY | This operation is not allowed if any GTID has been logged to the binary log. Run RESET MASTER first to erase the log |
| 1957 |  | ER\_NO\_SUCH\_QUERY | Unknown query id: %lld |
| 1958 |  | ER\_BAD\_BASE64\_DATA | Bad base64 data as position %u |
| 1959 |  | ER\_INVALID\_ROLE | Invalid role specification %`s. |
| 1960 |  | ER\_INVALID\_CURRENT\_USER | The current user is invalid. |
| 1961 |  | ER\_CANNOT\_GRANT\_ROLE | Cannot grant role '%s' to: %s. |
| 1962 |  | ER\_CANNOT\_REVOKE\_ROLE | Cannot revoke role '%s' from: %s. |
| 1963 |  | ER\_CHANGE\_SLAVE\_PARALLEL\_THREADS\_ACTIVE | Cannot change @@slave\_parallel\_threads while another change is in progress |
| 1964 |  | ER\_PRIOR\_COMMIT\_FAILED | Commit failed due to failure of an earlier commit on which this one depends |
| 1965 |  | ER\_IT\_IS\_A\_VIEW | '%-.192s' is a view |
| 1966 |  | ER\_SLAVE\_SKIP\_NOT\_IN\_GTID | When using GTID, @@sql\_slave\_skip\_counter can not be used. Instead, setting @@gtid\_slave\_pos explicitly can be used to skip to after a given GTID position. |
| 1967 |  | ER\_TABLE\_DEFINITION\_TOO\_BIG | The definition for table %`s is too big |
| 1968 |  | ER\_PLUGIN\_INSTALLED | Plugin '%-.192s' already installed |
| 1969 |  | ER\_STATEMENT\_TIMEOUT | Query execution was interrupted (max\_statement\_time exceeded) |
| 1970 |  | ER\_SUBQUERIES\_NOT\_SUPPORTED | %s does not support subqueries or stored functions. |
| 1971 |  | ER\_SET\_STATEMENT\_NOT\_SUPPORTED | The system variable %.200s cannot be set in SET STATEMENT. |
| 1972 |  | ER\_UNUSED\_9 | You should never see it |
| 1973 |  | ER\_USER\_CREATE\_EXISTS | Can't create user '%-.64s'@'%-.64s'; it already exists |
| 1974 |  | ER\_USER\_DROP\_EXISTS | Can't drop user '%-.64s'@'%-.64s'; it doesn't exist |
| 1975 |  | ER\_ROLE\_CREATE\_EXISTS | Can't create role '%-.64s'; it already exists |
| 1976 |  | ER\_ROLE\_DROP\_EXISTS | Can't drop role '%-.64s'; it doesn't exist |
| 1977 |  | ER\_CANNOT\_CONVERT\_CHARACTER | Cannot convert '%s' character 0x%-.64s to '%s' |
| 1978 |  | ER\_INVALID\_DEFAULT\_VALUE\_FOR\_FIELD | Incorrect default value '%-.128s' for column '%.192s' |
| 1979 |  | ER\_KILL\_QUERY\_DENIED\_ERROR | You are not owner of query %lu |
| 1980 |  | ER\_NO\_EIS\_FOR\_FIELD | Engine-independent statistics are not collected for column '%s' |
| 1981 |  | ER\_WARN\_AGGFUNC\_DEPENDENCE | Aggregate function '%-.192s)' of SELECT #%d belongs to SELECT #%d |
| 1982 |  | WARN\_INNODB\_PARTITION\_OPTION\_IGNORED | <%-.64s> option ignored for InnoDB partition |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 3000 |  | ER\_FILE\_CORRUPT | File %s is corrupted |
| 3001 |  | ER\_ERROR\_ON\_MASTER | Query partially completed on the master (error on master: %d) and was aborted. There is a chance that your master is inconsistent at this point. If you are sure that your master is ok, run this query manually on the slave and then restart the slave with SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER=1; START SLAVE;. Query:'%s'" |
| 3002 |  | ER\_INCONSISTENT\_ERROR | Query caused different errors on master and slave. Error on master: message (format)='%s' error code=%d; Error on slave:actual message='%s', error code=%d. Default database:'%s'. Query:'%s' |
| 3003 |  | ER\_STORAGE\_ENGINE\_NOT\_LOADED | Storage engine for table '%s'.'%s' is not loaded. |
| 3004 |  | ER\_GET\_STACKED\_DA\_WITHOUT\_ACTIVE\_HANDLER 0Z002 | GET STACKED DIAGNOSTICS when handler not active |
| 3005 |  | ER\_WARN\_LEGACY\_SYNTAX\_CONVERTED | %s is no longer supported. The statement was converted to %s. |
| 3006 |  | ER\_BINLOG\_UNSAFE\_FULLTEXT\_PLUGIN | Statement is unsafe because it uses a fulltext parser plugin which may not return the same value on the slave. |
| 3007 |  | ER\_CANNOT\_DISCARD\_TEMPORARY\_TABLE | Cannot DISCARD/IMPORT tablespace associated with temporary table |
| 3008 |  | ER\_FK\_DEPTH\_EXCEEDED | Foreign key cascade delete/update exceeds max depth of %d. |
| 3009 |  | ER\_COL\_COUNT\_DOESNT\_MATCH\_PLEASE\_UPDATE\_V2 | Column count of %s.%s is wrong. Expected %d, found %d. Created with MariaDB %d, now running %d. Please use mysql\_upgrade to fix this error. |
| 3010 |  | ER\_WARN\_TRIGGER\_DOESNT\_HAVE\_CREATED | Trigger %s.%s.%s does not have CREATED attribute. |
| 3011 |  | ER\_REFERENCED\_TRG\_DOES\_NOT\_EXIST\_MYSQL | Referenced trigger '%s' for the given action time and event type does not exist. |
| 3012 |  | ER\_EXPLAIN\_NOT\_SUPPORTED | EXPLAIN FOR CONNECTION command is supported only for SELECT/UPDATE/INSERT/DELETE/REPLACE |
| 3013 |  | ER\_INVALID\_FIELD\_SIZE | Invalid size for column '%-.192s'. |
| 3014 |  | ER\_MISSING\_HA\_CREATE\_OPTION | Table storage engine '%-.64s' found required create option missing |
| 3015 |  | ER\_ENGINE\_OUT\_OF\_MEMORY | Out of memory in storage engine '%-.64s'. |
| 3016 |  | ER\_PASSWORD\_EXPIRE\_ANONYMOUS\_USER | The password for anonymous user cannot be expired. |
| 3017 |  | ER\_SLAVE\_SQL\_THREAD\_MUST\_STOP | This operation cannot be performed with a running slave sql thread; run STOP SLAVE SQL\_THREAD first |
| 3018 |  | ER\_NO\_FT\_MATERIALIZED\_SUBQUERY | Cannot create FULLTEXT index on materialized subquery |
| 3019 |  | ER\_INNODB\_UNDO\_LOG\_FULL | Undo Log error: %s |
| 3020 |  | ER\_INVALID\_ARGUMENT\_FOR\_LOGARITHM | Invalid argument for logarithm |
| 3021 |  | ER\_SLAVE\_CHANNEL\_IO\_THREAD\_MUST\_STOP | This operation cannot be performed with a running slave io thread; run STOP SLAVE IO\_THREAD FOR CHANNEL '%s' first. |
| 3022 |  | ER\_WARN\_OPEN\_TEMP\_TABLES\_MUST\_BE\_ZERO | This operation may not be safe when the slave has temporary tables. The tables will be kept open until the server restarts or until the tables are deleted by any replicated DROP statement. Suggest to wait until slave\_open\_temp\_tables = 0. |
| 3023 |  | ER\_WARN\_ONLY\_MASTER\_LOG\_FILE\_NO\_POS | CHANGE MASTER TO with a MASTER\_LOG\_FILE clause but no MASTER\_LOG\_POS clause may not be safe. The old position value may not be valid for the new binary log file. |
| 3024 |  | ER\_QUERY\_TIMEOUT | Query execution was interrupted, maximum statement execution time exceeded |
| 3025 |  | ER\_NON\_RO\_SELECT\_DISABLE\_TIMER | Select is not a read only statement, disabling timer |
| 3026 |  | ER\_DUP\_LIST\_ENTRY | Duplicate entry '%-.192s'. |
| 3027 |  | ER\_SQL\_MODE\_NO\_EFFECT | '%s' mode no longer has any effect. Use STRICT\_ALL\_TABLES or STRICT\_TRANS\_TABLES instead. |
| 3028 |  | ER\_AGGREGATE\_ORDER\_FOR\_UNION | Expression #%u of ORDER BY contains aggregate function and applies to a UNION |
| 3029 |  | ER\_AGGREGATE\_ORDER\_NON\_AGG\_QUERY | Expression #%u of ORDER BY contains aggregate function and applies to the result of a non-aggregated query |
| 3030 |  | ER\_SLAVE\_WORKER\_STOPPED\_PREVIOUS\_THD\_ERROR | Slave worker has stopped after at least one previous worker encountered an error when slave-preserve-commit-order was enabled. To preserve commit order, the last transaction executed by this thread has not been committed. When restarting the slave after fixing any failed threads, you should fix this worker as well. |
| 3031 |  | ER\_DONT\_SUPPORT\_SLAVE\_PRESERVE\_COMMIT\_ORDER | slave\_preserve\_commit\_order is not supported %s. |
| 3032 |  | ER\_SERVER\_OFFLINE\_MODE | The server is currently in offline mode |
| 3033 |  | ER\_GIS\_DIFFERENT\_SRIDS | Binary geometry function %s given two geometries of different srids: %u and %u, which should have been identical. |
| 3034 |  | ER\_GIS\_UNSUPPORTED\_ARGUMENT | Calling geometry function %s with unsupported types of arguments. |
| 3035 |  | ER\_GIS\_UNKNOWN\_ERROR | Unknown GIS error occurred in function %s. |
| 3036 |  | ER\_GIS\_UNKNOWN\_EXCEPTION | Unknown exception caught in GIS function %s. |
| 3037 |  | ER\_GIS\_INVALID\_DATA | Invalid GIS data provided to function %s. |
| 3038 |  | ER\_BOOST\_GEOMETRY\_EMPTY\_INPUT\_EXCEPTION | The geometry has no data in function %s. |
| 3039 |  | ER\_BOOST\_GEOMETRY\_CENTROID\_EXCEPTION | Unable to calculate centroid because geometry is empty in function %s. |
| 3040 |  | ER\_BOOST\_GEOMETRY\_OVERLAY\_INVALID\_INPUT\_EXCEPTION | Geometry overlay calculation error: geometry data is invalid in function %s. |
| 3041 |  | ER\_BOOST\_GEOMETRY\_TURN\_INFO\_EXCEPTION | Geometry turn info calculation error: geometry data is invalid in function %s. |
| 3042 |  | ER\_BOOST\_GEOMETRY\_SELF\_INTERSECTION\_POINT\_EXCEPTION | Analysis procedures of intersection points interrupted unexpectedly in function %s. |
| 3043 |  | ER\_BOOST\_GEOMETRY\_UNKNOWN\_EXCEPTION | Unknown exception thrown in function %s. |
| 3044 |  | ER\_STD\_BAD\_ALLOC\_ERROR | Memory allocation error: %-.256s in function %s. |
| 3045 |  | ER\_STD\_DOMAIN\_ERROR | Domain error: %-.256s in function %s. |
| 3046 |  | ER\_STD\_LENGTH\_ERROR | Length error: %-.256s in function %s. |
| 3047 |  | ER\_STD\_INVALID\_ARGUMENT | Invalid argument error: %-.256s in function %s. |
| 3048 |  | ER\_STD\_OUT\_OF\_RANGE\_ERROR | Out of range error: %-.256s in function %s. |
| 3049 |  | ER\_STD\_OVERFLOW\_ERROR | Overflow error error: %-.256s in function %s. |
| 3050 |  | ER\_STD\_RANGE\_ERROR | Range error: %-.256s in function %s. |
| 3051 |  | ER\_STD\_UNDERFLOW\_ERROR | Underflow error: %-.256s in function %s. |
| 3052 |  | ER\_STD\_LOGIC\_ERROR | Logic error: %-.256s in function %s. |
| 3053 |  | ER\_STD\_RUNTIME\_ERROR | Runtime error: %-.256s in function %s. |
| 3054 |  | ER\_STD\_UNKNOWN\_EXCEPTION | Unknown exception: %-.384s in function %s. |
| 3055 |  | ER\_GIS\_DATA\_WRONG\_ENDIANESS | Geometry byte string must be little endian. |
| 3056 |  | ER\_CHANGE\_MASTER\_PASSWORD\_LENGTH | The password provided for the replication user exceeds the maximum length of 32 characters |
| 3057 | 42000 | ER\_USER\_LOCK\_WRONG\_NAME | Incorrect user-level lock name '%-.192s'. |
| 3058 |  | ER\_USER\_LOCK\_DEADLOCK | Deadlock found when trying to get user-level lock; try rolling back transaction/releasing locks and restarting lock acquisition. |
| 3059 |  | ER\_REPLACE\_INACCESSIBLE\_ROWS | REPLACE cannot be executed as it requires deleting rows that are not in the view |
| 3060 |  | ER\_ALTER\_OPERATION\_NOT\_SUPPORTED\_REASON\_GIS | Do not support online operation on table with GIS index |

 



| Error Code | SQLSTATE | Error | Description |
| --- | --- | --- | --- |
| 4000 | 0A000 | ER\_COMMULTI\_BADCONTEXT | COM\_MULTI can't return a result set in the given context |
| 4001 |  | ER\_BAD\_COMMAND\_IN\_MULTI | Command '%s' is not allowed for COM\_MULTI |
| 4002 |  | ER\_WITH\_COL\_WRONG\_LIST | WITH column list and SELECT field list have different column counts |
| 4003 |  | ER\_TOO\_MANY\_DEFINITIONS\_IN\_WITH\_CLAUSE | Too many WITH elements in WITH clause |
| 4004 |  | ER\_DUP\_QUERY\_NAME | Duplicate query name %`-.64s in WITH clause |
| 4005 |  | ER\_RECURSIVE\_WITHOUT\_ANCHORS | No anchors for recursive WITH element '%s' |
| 4006 |  | ER\_UNACCEPTABLE\_MUTUAL\_RECURSION | Unacceptable mutual recursion with anchored table '%s' |
| 4007 |  | ER\_REF\_TO\_RECURSIVE\_WITH\_TABLE\_IN\_DERIVED | Reference to recursive WITH table '%s' in materialized derived |
| 4008 |  | ER\_NOT\_STANDARD\_COMPLIANT\_RECURSIVE | Restrictions imposed on recursive definitions are violated for table '%s'"R\_WRONG\_WINDOW\_SPEC\_NAME |
| 4009 |  | ER\_WRONG\_WINDOW\_SPEC\_NAME | Window specification with name '%s' is not defined |
| 4010 |  | ER\_DUP\_WINDOW\_NAME | Multiple window specifications with the same name '%s' |
| 4011 |  | ER\_PARTITION\_LIST\_IN\_REFERENCING\_WINDOW\_SPEC | Window specification referencing another one '%s' cannot contain partition list |
| 4012 |  | ER\_ORDER\_LIST\_IN\_REFERENCING\_WINDOW\_SPEC | Referenced window specification '%s' already contains order list |
| 4013 |  | ER\_WINDOW\_FRAME\_IN\_REFERENCED\_WINDOW\_SPEC | Referenced window specification '%s' cannot contain window frame |
| 4014 |  | ER\_BAD\_COMBINATION\_OF\_WINDOW\_FRAME\_BOUND\_SPECS | Unacceptable combination of window frame bound specifications |
| 4015 |  | ER\_WRONG\_PLACEMENT\_OF\_WINDOW\_FUNCTION | Window function is allowed only in SELECT list and ORDER BY clause |
| 4016 |  | ER\_WINDOW\_FUNCTION\_IN\_WINDOW\_SPEC | Window function is not allowed in window specification |
| 4017 |  | ER\_NOT\_ALLOWED\_WINDOW\_FRAME | Window frame is not allowed with '%s' |
| 4018 |  | ER\_NO\_ORDER\_LIST\_IN\_WINDOW\_SPEC | No order list in window specification for '%s' |
| 4019 |  | ER\_RANGE\_FRAME\_NEEDS\_SIMPLE\_ORDERBY | RANGE-type frame requires ORDER BY clause with single sort key |
| 4020 |  | ER\_WRONG\_TYPE\_FOR\_ROWS\_FRAME | Integer is required for ROWS-type frame |
| 4021 |  | ER\_WRONG\_TYPE\_FOR\_RANGE\_FRAME | Numeric datatype is required for RANGE-type frame |
| 4022 |  | ER\_FRAME\_EXCLUSION\_NOT\_SUPPORTED | Frame exclusion is not supported yet |
| 4023 |  | ER\_WINDOW\_FUNCTION\_DONT\_HAVE\_FRAME | This window function may not have a window frame |
| 4024 |  | ER\_INVALID\_NTILE\_ARGUMENT | Argument of NTILE must be greater than 0 |
| 4025 | 23000 | ER\_CONSTRAINT\_FAILED | CONSTRAINT %`s failed for %`-.192s.%`-.192s |
| 4026 |  | ER\_EXPRESSION\_IS\_TOO\_BIG | Expression in the %s clause is too big |
| 4027 |  | ER\_ERROR\_EVALUATING\_EXPRESSION | Got an error evaluating stored expression %s |
| 4028 |  | ER\_CALCULATING\_DEFAULT\_VALUE | Got an error when calculating default value for %`s |
| 4029 |  | ER\_EXPRESSION\_REFERS\_TO\_UNINIT\_FIELD | Expression for field %`-.64s is referring to uninitialized field %`s |
| 4030 |  | ER\_PARTITION\_DEFAULT\_ERROR | Only one DEFAULT partition allowed |
| 4031 |  | ER\_REFERENCED\_TRG\_DOES\_NOT\_EXIST | Referenced trigger '%s' for the given action time and event type does not exist |
| 4032 |  | ER\_INVALID\_DEFAULT\_PARAM | Default/ignore value is not supported for such parameter usage |
| 4033 |  | ER\_BINLOG\_NON\_SUPPORTED\_BULK | Only row based replication supported for bulk operations |
| 4034 |  | ER\_BINLOG\_UNCOMPRESS\_ERROR | Uncompress the compressed binlog failed |
| 4035 |  | ER\_JSON\_BAD\_CHR | Broken JSON string in argument %d to function '%s' at position %d |
| 4036 |  | ER\_JSON\_NOT\_JSON\_CHR | Character disallowed in JSON in argument %d to function '%s' at position %d |
| 4037 |  | ER\_JSON\_EOS | Unexpected end of JSON text in argument %d to function '%s' |
| 4038 |  | ER\_JSON\_SYNTAX | Syntax error in JSON text in argument %d to function '%s' at position %d |
| 4039 |  | ER\_JSON\_ESCAPING | Incorrect escaping in JSON text in argument %d to function '%s' at position %d |
| 4040 |  | ER\_JSON\_DEPTH | Limit of %d on JSON nested strucures depth is reached in argument %d to function '%s' at position %d |
| 4041 |  | ER\_JSON\_PATH\_EOS | Unexpected end of JSON path in argument %d to function '%s' |
| 4042 |  | ER\_JSON\_PATH\_SYNTAX | Syntax error in JSON path in argument %d to function '%s' at position %d |
| 4043 |  | ER\_JSON\_PATH\_DEPTH | Limit of %d on JSON path depth is reached in argument %d to function '%s' at position %d |
| 4044 |  | ER\_JSON\_PATH\_NO\_WILDCARD | Wildcards in JSON path not allowed in argument %d to function '%s' |
| 4045 |  | ER\_JSON\_PATH\_ARRAY | JSON path should end with an array identifier in argument %d to function '%s' |
| 4046 |  | ER\_JSON\_ONE\_OR\_ALL | Argument 2 to function '%s' must be "one" or "all". |
| 4047 |  | ER\_UNSUPPORT\_COMPRESSED\_TEMPORARY\_TABLE | CREATE TEMPORARY TABLE is not allowed with ROW\_FORMAT=COMPRESSED or KEY\_BLOCK\_SIZE. |
| 4048 |  | ER\_GEOJSON\_INCORRECT | Incorrect GeoJSON format specified for st\_geomfromgeojson function. |
| 4049 |  | ER\_GEOJSON\_TOO\_FEW\_POINTS | Incorrect GeoJSON format - too few points for linestring specified. |
| 4050 |  | ER\_GEOJSON\_NOT\_CLOSED | Incorrect GeoJSON format - polygon not closed. |
| 4051 |  | ER\_JSON\_PATH\_EMPTY | Path expression '$' is not allowed in argument %d to function '%s'. |
| 4052 |  | ER\_SLAVE\_SAME\_ID | A slave with the same server\_uuid/server\_id as this slave has connected to the master |
| 4053 |  | ER\_FLASHBACK\_NOT\_SUPPORTED | Flashback does not support %s %s |
| 4054 |  | ER\_KEYS\_OUT\_OF\_ORDER | Keys are out order during bulk load |
| 4055 |  | ER\_OVERLAPPING\_KEYS | Bulk load rows overlap existing rows |
| 4056 |  | ER\_REQUIRE\_ROW\_BINLOG\_FORMAT | Can't execute updates on master with binlog\_format != ROW. |
| 4057 |  | ER\_ISOLATION\_MODE\_NOT\_SUPPORTED | MyRocks supports only READ COMMITTED and REPEATABLE READ isolation levels. Please change from current isolation level %s |
| 4058 |  | ER\_ON\_DUPLICATE\_DISABLED | When unique checking is disabled in MyRocks, INSERT,UPDATE,LOAD statements with clauses that update or replace the key (i.e. INSERT ON DUPLICATE KEY UPDATE, REPLACE) are not allowed. Query: %s |
| 4059 |  | ER\_UPDATES\_WITH\_CONSISTENT\_SNAPSHOT | Can't execute updates when you started a transaction with START TRANSACTION WITH CONSISTENT [ROCKSDB] SNAPSHOT. |
| 4060 |  | ER\_ROLLBACK\_ONLY | This transaction was rolled back and cannot be committed. Only supported operation is to roll it back, so all pending changes will be discarded. Please restart another transaction. |
| 4061 |  | ER\_ROLLBACK\_TO\_SAVEPOINT | MyRocks currently does not support ROLLBACK TO SAVEPOINT if modifying rows. |
| 4062 |  | ER\_ISOLATION\_LEVEL\_WITH\_CONSISTENT\_SNAPSHOT | Only REPEATABLE READ isolation level is supported for START TRANSACTION WITH CONSISTENT SNAPSHOT in RocksDB Storage Engine. |
| 4063 |  | ER\_UNSUPPORTED\_COLLATION | Unsupported collation on string indexed column %s.%s Use binary collation (%s). |
| 4064 |  | ER\_METADATA\_INCONSISTENCY | Table '%s' does not exist, but metadata information exists inside MyRocks. This is a sign of data inconsistency. Please check if '%s.frm' exists, and try to restore it if it does not exist. |
| 4065 |  | ER\_CF\_DIFFERENT | Column family ('%s') flag (%d) is different from an existing flag (%d). Assign a new CF flag, or do not change existing CF flag. |
| 4066 |  | ER\_RDB\_TTL\_DURATION\_FORMAT | TTL duration (%s) in MyRocks must be an unsigned non-null 64-bit integer. |
| 4067 |  | ER\_RDB\_STATUS\_GENERAL | Status error %d received from RocksDB: %s |
| 4068 |  | ER\_RDB\_STATUS\_MSG | %s, Status error %d received from RocksDB: %s |
| 4069 |  | ER\_RDB\_TTL\_UNSUPPORTED | TTL support is currently disabled when table has a hidden PK. |
| 4070 |  | ER\_RDB\_TTL\_COL\_FORMAT | TTL column (%s) in MyRocks must be an unsigned non-null 64-bit integer, exist inside the table, and have an accompanying ttl duration. |
| 4071 |  | ER\_PER\_INDEX\_CF\_DEPRECATED | The per-index column family option has been deprecated |
| 4072 |  | ER\_KEY\_CREATE\_DURING\_ALTER | MyRocks failed creating new key definitions during alter. |
| 4073 |  | ER\_SK\_POPULATE\_DURING\_ALTER | MyRocks failed populating secondary key during alter. |
| 4074 |  | ER\_SUM\_FUNC\_WITH\_WINDOW\_FUNC\_AS\_ARG | Window functions can not be used as arguments to group functions. |
| 4075 |  | ER\_NET\_OK\_PACKET\_TOO\_LARGE | OK packet too large |
| 4076 |  | ER\_GEOJSON\_EMPTY\_COORDINATES | Incorrect GeoJSON format - empty 'coordinates' array. |
| 4077 |  | ER\_MYROCKS\_CANT\_NOPAD\_COLLATION | MyRocks doesn't currently support collations with \"No pad\" attribute. |
| 4078 |  | ER\_ILLEGAL\_PARAMETER\_DATA\_TYPES2\_FOR\_OPERATION | Illegal parameter data types %s and %s for operation '%s' |
| 4079 |  | ER\_ILLEGAL\_PARAMETER\_DATA\_TYPE\_FOR\_OPERATION | Illegal parameter data type %s for operation '%s' |
| 4080 |  | ER\_WRONG\_PARAMCOUNT\_TO\_CURSOR | Incorrect parameter count to cursor '%-.192s' |
| 4081 |  | ER\_UNKNOWN\_STRUCTURED\_VARIABLE | Unknown structured system variable or ROW routine variable '%-.\*s' |
| 4082 |  | ER\_ROW\_VARIABLE\_DOES\_NOT\_HAVE\_FIELD | Row variable '%-.192s' does not have a field '%-.192s' |
| 4083 |  | ER\_END\_IDENTIFIER\_DOES\_NOT\_MATCH | END identifier '%-.192s' does not match '%-.192s' |
| 4084 |  | ER\_SEQUENCE\_RUN\_OUT | Sequence '%-.64s.%-.64s' has run out |
| 4085 |  | ER\_SEQUENCE\_INVALID\_DATA | Sequence '%-.64s.%-.64s' values are conflicting |
| 4086 |  | ER\_SEQUENCE\_INVALID\_TABLE\_STRUCTURE | Sequence '%-.64s.%-.64s' table structure is invalid (%s) |
| 4087 |  | ER\_SEQUENCE\_ACCESS\_ERROR | Sequence '%-.64s.%-.64s' access error |
| 4088 |  | ER\_SEQUENCE\_BINLOG\_FORMAT | Sequences requires binlog\_format mixed or row |
| 4089 |  | ER\_NOT\_SEQUENCE | '%-.64s.%-.64s' is not a SEQUENCE |
| 4090 |  | ER\_NOT\_SEQUENCE2 | '%-.192s' is not a SEQUENCE |
| 4091 |  | ER\_UNKNOWN\_SEQUENCES | Unknown SEQUENCE: '%-.300s' |
| 4092 |  | ER\_UNKNOWN\_VIEW | Unknown VIEW: '%-.300s' |
| 4093 |  | ER\_WRONG\_INSERT\_INTO\_SEQUENCE | Wrong INSERT into a SEQUENCE. One can only do single table INSERT into a sequence object (like with mysqldump). If you want to change the SEQUENCE, use ALTER SEQUENCE instead. |
| 4094 |  | ER\_SP\_STACK\_TRACE | At line %u in %s |
| 4095 |  | ER\_PACKAGE\_ROUTINE\_IN\_SPEC\_NOT\_DEFINED\_IN\_BODY | Subroutine '%-.192s' is declared in the package specification but is not defined in the package body |
| 4096 |  | ER\_PACKAGE\_ROUTINE\_FORWARD\_DECLARATION\_NOT\_DEFINED | Subroutine '%-.192s' has a forward declaration but is not defined |
| 4097 |  | ER\_COMPRESSED\_COLUMN\_USED\_AS\_KEY | Compressed column '%-.192s' can't be used in key specification |
| 4098 |  | ER\_UNKNOWN\_COMPRESSION\_METHOD | Unknown compression method: %s |
| 4099 |  | ER\_WRONG\_NUMBER\_OF\_VALUES\_IN\_TVC | The used table value constructor has a different number of values |
| 4100 |  | ER\_FIELD\_REFERENCE\_IN\_TVC | Field reference '%-.192s' can't be used in table value constructor |
| 4101 |  | ER\_WRONG\_TYPE\_FOR\_PERCENTILE\_FUNC | Numeric datatype is required for %s function |
| 4102 |  | ER\_ARGUMENT\_NOT\_CONSTANT | Argument to the %s function is not a constant for a partition |
| 4103 |  | ER\_ARGUMENT\_OUT\_OF\_RANGE | Argument to the %s function does not belong to the range [0,1] |
| 4104 |  | ER\_WRONG\_TYPE\_OF\_ARGUMENT | %s function only accepts arguments that can be converted to numerical types |
| 4105 |  | ER\_NOT\_AGGREGATE\_FUNCTION | Aggregate specific instruction (FETCH GROUP NEXT ROW) used in a wrong context |
| 4106 |  | ER\_INVALID\_AGGREGATE\_FUNCTION | Aggregate specific instruction(FETCH GROUP NEXT ROW) missing from the aggregate function |
| 4107 |  | ER\_INVALID\_VALUE\_TO\_LIMIT | Limit only accepts integer values |
| 4108 |  | ER\_INVISIBLE\_NOT\_NULL\_WITHOUT\_DEFAULT | Invisible column %`s must have a default value |
| 4109 |  | ER\_UPDATE\_INFO\_WITH\_SYSTEM\_VERSIONING | Rows matched: %ld Changed: %ld Inserted: %ld Warnings: %ld |
| 4110 |  | ER\_VERS\_FIELD\_WRONG\_TYPE | %`s must be of type %s for system-versioned table %`s |
| 4111 |  | ER\_VERS\_ENGINE\_UNSUPPORTED | Transaction-precise system versioning for %`s is not supported |
| 4112 |  | ER\_UNUSED\_23 | You should never see it |
| 4113 |  | ER\_PARTITION\_WRONG\_TYPE | Wrong partitioning type, expected type: %`s |
| 4114 |  | WARN\_VERS\_PART\_FULL | Versioned table %`s.%`s: last HISTORY partition (%`s) is out of %s, need more HISTORY partitions |
| 4115 |  | WARN\_VERS\_PARAMETERS | Maybe missing parameters: %s |
| 4116 |  | ER\_VERS\_DROP\_PARTITION\_INTERVAL | Can only drop oldest partitions when rotating by INTERVAL |
| 4117 |  | ER\_UNUSED\_25 | You should never see it |
| 4118 |  | WARN\_VERS\_PART\_NON\_HISTORICAL | Partition %`s contains non-historical data |
| 4119 |  | ER\_VERS\_ALTER\_NOT\_ALLOWED | Not allowed for system-versioned %`s.%`s. Change @@system\_versioning\_alter\_history to proceed with ALTER. |
| 4120 |  | ER\_VERS\_ALTER\_ENGINE\_PROHIBITED | Not allowed for system-versioned %`s.%`s. Change to/from native system versioning engine is not supported. |
| 4121 |  | ER\_VERS\_RANGE\_PROHIBITED | SYSTEM\_TIME range selector is not allowed |
| 4122 |  | ER\_CONFLICTING\_FOR\_SYSTEM\_TIME | Conflicting FOR SYSTEM\_TIME clauses in WITH RECURSIVE |
| 4123 |  | ER\_VERS\_TABLE\_MUST\_HAVE\_COLUMNS | Table %`s must have at least one versioned column |
| 4124 |  | ER\_VERS\_NOT\_VERSIONED | Table %`s is not system-versioned |
| 4125 |  | ER\_MISSING | Wrong parameters for %`s: missing '%s' |
| 4126 |  | ER\_VERS\_PERIOD\_COLUMNS | PERIOD FOR SYSTEM\_TIME must use columns %`s and %`s |
| 4127 |  | ER\_PART\_WRONG\_VALUE | Wrong parameters for partitioned %`s: wrong value for '%s' |
| 4128 |  | ER\_VERS\_WRONG\_PARTS | Wrong partitions for %`s: must have at least one HISTORY and exactly one last CURRENT |
| 4129 |  | ER\_VERS\_NO\_TRX\_ID | TRX\_ID %llu not found in `mysql.transaction\_registry` |
| 4130 |  | ER\_VERS\_ALTER\_SYSTEM\_FIELD | Can not change system versioning field %`s |
| 4131 |  | ER\_DROP\_VERSIONING\_SYSTEM\_TIME\_PARTITION | Can not DROP SYSTEM VERSIONING for table %`s partitioned BY SYSTEM\_TIME |
| 4132 |  | ER\_VERS\_DB\_NOT\_SUPPORTED | System-versioned tables in the %`s database are not supported |
| 4133 |  | ER\_VERS\_TRT\_IS\_DISABLED | Transaction registry is disabled |
| 4134 |  | ER\_VERS\_DUPLICATE\_ROW\_START\_END | Duplicate ROW %s column %`s |
| 4135 |  | ER\_VERS\_ALREADY\_VERSIONED | Table %`s is already system-versioned |
| 4136 |  | ER\_UNUSED\_24 | You should never see it |
| 4137 |  | ER\_VERS\_NOT\_SUPPORTED | System-versioned tables do not support %s |
| 4138 |  | ER\_VERS\_TRX\_PART\_HISTORIC\_ROW\_NOT\_SUPPORTED | Transaction-precise system-versioned tables do not support partitioning by ROW START or ROW END |
| 4139 |  | ER\_INDEX\_FILE\_FULL | The index file for table '%-.192s' is full |
| 4140 |  | ER\_UPDATED\_COLUMN\_ONLY\_ONCE | The column %`s.%`s cannot be changed more than once in a single UPDATE statement |
| 4141 |  | ER\_EMPTY\_ROW\_IN\_TVC | Row with no elements is not allowed in table value constructor in this context |
| 4142 |  | ER\_VERS\_QUERY\_IN\_PARTITION | SYSTEM\_TIME partitions in table %`s does not support historical query |
| 4143 |  | ER\_KEY\_DOESNT\_SUPPORT | %s index %`s does not support this operation |
| 4144 |  | ER\_ALTER\_OPERATION\_TABLE\_OPTIONS\_NEED\_REBUILD | Changing table options requires the table to be rebuilt |
| 4145 |  | ER\_BACKUP\_LOCK\_IS\_ACTIVE | Can't execute the command as you have a BACKUP STAGE active |
| 4146 |  | ER\_BACKUP\_NOT\_RUNNING | You must start backup with \"BACKUP STAGE START\" |
| 4147 |  | ER\_BACKUP\_WRONG\_STAGE | Backup stage '%s' is same or before current backup stage '%s' |
| 4148 |  | ER\_BACKUP\_STAGE\_FAILED | Backup stage '%s' failed |
| 4149 |  | ER\_BACKUP\_UNKNOWN\_STAGE | Unknown backup stage: '%s'. Stage should be one of START, FLUSH, BLOCK\_DDL, BLOCK\_COMMIT or END |
| 4150 |  | ER\_USER\_IS\_BLOCKED | User is blocked because of too many credential errors; unblock with 'FLUSH PRIVILEGES' |
| 4151 |  | ER\_ACCOUNT\_HAS\_BEEN\_LOCKED | Access denied, this account is locked |
| 4152 |  | ER\_PERIOD\_TEMPORARY\_NOT\_ALLOWED | Application-time period table cannot be temporary |
| 4153 |  | ER\_PERIOD\_TYPES\_MISMATCH | Fields of PERIOD FOR %`s have different types |
| 4154 |  | ER\_MORE\_THAN\_ONE\_PERIOD | Cannot specify more than one application-time period |
| 4155 |  | ER\_PERIOD\_FIELD\_WRONG\_ATTRIBUTES | Period field %`s cannot be %s |
| 4156 |  | ER\_PERIOD\_NOT\_FOUND | Period %`s is not found in table |
| 4157 |  | ER\_PERIOD\_COLUMNS\_UPDATED | Column %`s used in period %`s specified in update SET list |
| 4158 |  | ER\_PERIOD\_CONSTRAINT\_DROP | Can't DROP CONSTRAINT `%s`. Use DROP PERIOD `%s` for this |
| 4159 | 42000 S1009 | ER\_TOO\_LONG\_KEYPART | Specified key part was too long; max key part length is %u bytes |
| 4160 |  | ER\_TOO\_LONG\_DATABASE\_COMMENT | Comment for database '%-.64s' is too long (max = %u) |
| 4161 |  | ER\_UNKNOWN\_DATA\_TYPE | Unknown data type: '%-.64s' |
| 4162 |  | ER\_UNKNOWN\_OPERATOR | Operator does not exists: '%-.128s' |
| 4163 |  | ER\_WARN\_HISTORY\_ROW\_START\_TIME | Table `%s.%s` history row start '%s' is later than row end '%s' |
| 4164 |  | ER\_PART\_STARTS\_BEYOND\_INTERVAL | %`s: STARTS is later than query time, first history partition may exceed INTERVAL value |
| 4165 |  | ER\_GALERA\_REPLICATION\_NOT\_SUPPORTED | DDL-statement is forbidden as table storage engine does not support Galera replication |
| 4166 | HY000 | ER\_LOAD\_INFILE\_CAPABILITY\_DISABLED | The used command is not allowed because the MariaDB server or client has disabled the local infile capability |
| 4167 |  | ER\_NO\_SECURE\_TRANSPORTS\_CONFIGURED | No secure transports are configured, unable to set --require\_secure\_transport=ON |
| 4168 |  | ER\_SLAVE\_IGNORED\_SHARED\_TABLE | Slave SQL thread ignored the '%s' because table is shared |
| 4169 |  | ER\_NO\_AUTOINCREMENT\_WITH\_UNIQUE | AUTO\_INCREMENT column %`s cannot be used in the UNIQUE index %`s |
| 4170 |  | ER\_KEY\_CONTAINS\_PERIOD\_FIELDS | Key %`s cannot explicitly include column %`s |
| 4171 |  | ER\_KEY\_CANT\_HAVE\_WITHOUT\_OVERLAPS | Key %`s cannot have WITHOUT OVERLAPS |
| 4172 |  | ER\_NOT\_ALLOWED\_IN\_THIS\_CONTEXT | '%-.128s' is not allowed in this context |
| 4173 |  | ER\_DATA\_WAS\_COMMITED\_UNDER\_ROLLBACK | Engine %s does not support rollback. Changes where commited during rollback call |
| 4174 |  | ER\_PK\_INDEX\_CANT\_BE\_IGNORED | A primary key cannot be marked as IGNORE |
| 4175 |  | ER\_BINLOG\_UNSAFE\_SKIP\_LOCKED | SKIP LOCKED makes this statement unsafe |
| 4176 |  | ER\_JSON\_TABLE\_ERROR\_ON\_FIELD | Field '%s' can't be set for JSON\_TABLE '%s'. |
| 4177 |  | ER\_JSON\_TABLE\_ALIAS\_REQUIRED | Every table function must have an alias. |
| 4178 |  | ER\_JSON\_TABLE\_SCALAR\_EXPECTED | Can't store an array or an object in the scalar column '%s' of JSON\_TABLE '%s'. |
| 4179 |  | ER\_JSON\_TABLE\_MULTIPLE\_MATCHES | Can't store multiple matches of the path in the column '%s' of JSON\_TABLE '%s'. |
| 4180 |  | ER\_WITH\_TIES\_NEEDS\_ORDER | FETCH ... WITH TIES requires ORDER BY clause to be present |
| 4181 |  | ER\_REMOVED\_ORPHAN\_TRIGGER | Dropped orphan trigger '%-.64s', originally created for table: '%-.192s' |
| 4182 |  | ER\_STORAGE\_ENGINE\_DISABLED | Storage engine %s is disabled |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-error-codes/>

InnoDB Strict Mode
==================

    [InnoDB](../innodb/index) strict mode is similar to [SQL strict mode](../sql-mode/index#strict-mode). When it is enabled, certain InnoDB warnings become errors instead.

 Configuring InnoDB Strict Mode
------------------------------

 InnoDB strict mode is enabled by default.

 InnoDB strict mode can be enabled or disabled by configuring the [innodb\_strict\_mode](../xtradbinnodb-server-system-variables/index#innodb_strict_mode) server system variable.

 Its global value can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_strict_mode=ON;

```

Its value for the current session can also be changed dynamically with [SET SESSION](../set/index#global-session). For example:

 
```
SET SESSION innodb_strict_mode=ON;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_strict_mode=ON

```

InnoDB Strict Mode Errors
-------------------------

 ### Wrong Create Options

 If InnoDB strict mode is enabled, and if a DDL statement is executed and invalid or conflicting [table options](../create-table/index#table-options) are specified, then an error is raised. The error will only be a generic error that says the following:

 
```
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

```

However, more details about the error can be found by executing [SHOW WARNINGS](../show-warnings/index).

 For example, the error is raised in the following cases:

 * The [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value, but the [ROW\_FORMAT](../create-table/index#row_format) table option is set to some row format other than the [COMPRESSED](../innodb-compressed-row-format/index) row format. For example:

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
KEY_BLOCK_SIZE=4
ROW_FORMAT=DYNAMIC;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE.   |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value, but the configured value is larger than either `16` or the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable, whichever is smaller.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
KEY_BLOCK_SIZE=16;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: KEY_BLOCK_SIZE=16 cannot be larger than 8.                 |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value, but the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is not set to `ON`.

 
```
SET GLOBAL innodb_file_per_table=OFF;
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
KEY_BLOCK_SIZE=4;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table.             |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value, but it is not set to one of the supported values: [1, 2, 4, 8, 16].

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
KEY_BLOCK_SIZE=5;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------+
| Level   | Code | Message                                                               |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1478 | InnoDB: invalid KEY_BLOCK_SIZE = 5. Valid values are [1, 2, 4, 8, 16] |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options")    |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB       |
+---------+------+-----------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [ROW\_FORMAT](../create-table/index#row_format) table option is set to the [COMPRESSED](../innodb-compressed-row-format/index) row format, but the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is not set to `ON`.

 
```
SET GLOBAL innodb_file_per_table=OFF;
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
ROW_FORMAT=COMPRESSED;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table.      |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [ROW\_FORMAT](../create-table/index#row_format) table option is set to a value, but it is not set to one of the values supported by InnoDB: [REDUNDANT](../innodb-redundant-row-format/index), [COMPACT](../innodb-compact-row-format/index), [DYNAMIC](../innodb-dynamic-row-format/index), and [COMPRESSED](../innodb-compressed-row-format/index).

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
ROW_FORMAT=PAGE;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: invalid ROW_FORMAT specifier.                              |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* Either the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value or the [ROW\_FORMAT](../create-table/index#row_format) table option is set to the [COMPRESSED](../innodb-compressed-row-format/index) row format, but the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable is set to a value greater than `16k`.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
ROW_FORMAT=COMPRESSED;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------+
| Level   | Code | Message                                                               |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1478 | InnoDB: Cannot create a COMPRESSED table when innodb_page_size > 16k. |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options")    |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB       |
+---------+------+-----------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

* The [DATA DIRECTORY](../create-table/index#data-directoryindex-directory) table option is set, but the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is not set to `ON`.

 
```
SET GLOBAL innodb_file_per_table=OFF;
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
DATA DIRECTORY='/mariadb';
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: DATA DIRECTORY requires innodb_file_per_table.             |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [DATA DIRECTORY](../create-table/index#data-directoryindex-directory) table option is set, but the table is a [temporary table](../create-table/index#create-temporary-table).

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TEMPORARY TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
DATA DIRECTORY='/mariadb';
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: DATA DIRECTORY cannot be used for TEMPORARY tables.        |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [INDEX DIRECTORY](../create-table/index#data-directoryindex-directory) table option is set.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
INDEX DIRECTORY='/mariadb';
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: INDEX DIRECTORY is not supported                           |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [PAGE\_COMPRESSED](#page_compressed) table option is set to `1`, so [InnoDB page compression](../compression/index) is enabled, but the [ROW\_FORMAT](../create-table/index#row_format) table option is set to some row format other than the [COMPACT](../innodb-compact-row-format/index) or [DYNAMIC](../innodb-dynamic-row-format/index) row formats.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
PAGE_COMPRESSED=1
ROW_FORMAT=COMPRESSED;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning |  140 | InnoDB: PAGE_COMPRESSED table can't have ROW_TYPE=COMPRESSED       |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [PAGE\_COMPRESSED](#page_compressed) table option is set to `1`, so [InnoDB page compression](../compression/index) is enabled, but the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is not set to `ON`.

 
```
SET GLOBAL innodb_file_per_table=OFF;
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
PAGE_COMPRESSED=1;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning |  140 | InnoDB: PAGE_COMPRESSED requires innodb_file_per_table.            |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [PAGE\_COMPRESSED](#page_compressed) table option is set to `1`, so [InnoDB page compression](../compression/index) is enabled, but the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is also specified.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
PAGE_COMPRESSED=1
KEY_BLOCK_SIZE=4;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning |  140 | InnoDB: PAGE_COMPRESSED table can't have key_block_size            |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```

* The [PAGE\_COMPRESSION\_LEVEL](../create-table/index#page_compression_level) table option is set, but the [PAGE\_COMPRESSED](#page_compressed) table option is set to `0`, so [InnoDB page compression](../compression/index) is disabled.

 
```
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
PAGE_COMPRESSED=0
PAGE_COMPRESSION_LEVEL=9;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning |  140 | InnoDB: PAGE_COMPRESSION_LEVEL requires PAGE_COMPRESSED            |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.000 sec)

```


**MariaDB until [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the error is raised in the following additional cases:

 * The [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to a non-zero value, but the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable is not set to `Barracuda`.

 
```
SET GLOBAL innodb_file_format='Antelope';
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
KEY_BLOCK_SIZE=4;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope.     |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

* The [ROW\_FORMAT](../create-table/index#row_format) table option is set to either the [COMPRESSED](../innodb-compressed-row-format/index) or the [DYNAMIC](../innodb-dynamic-row-format/index) row format, but the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable is not set to `Barracuda`.

 
```
SET GLOBAL innodb_file_format='Antelope';
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
ROW_FORMAT=COMPRESSED;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------+
| Level   | Code | Message                                                               |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1478 | InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options")    |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB       |
+---------+------+-----------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

* The [PAGE\_COMPRESSED](#page_compressed) table option is set to `1`, so [InnoDB page compression](../compression/index) is enabled, but the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable is not set to `Barracuda`.

 
```
SET GLOBAL innodb_file_format='Antelope';
SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   id int PRIMARY KEY,
   str varchar(50)
)
PAGE_COMPRESSED=1;
SHOW WARNINGS;
ERROR 1005 (HY000): Can't create table `db1`.`tab` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+--------------------------------------------------------------------+
| Level   | Code | Message                                                            |
+---------+------+--------------------------------------------------------------------+
| Warning |  140 | InnoDB: PAGE_COMPRESSED requires innodb_file_format > Antelope.    |
| Error   | 1005 | Can't create table `db1`.`tab` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB    |
+---------+------+--------------------------------------------------------------------+
3 rows in set (0.00 sec)

```


### COMPRESSED Row Format

 If InnoDB strict mode is enabled, and if a table uses the [COMPRESSED](../innodb-compressed-row-format/index) row format, and if the table's [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) is too small to contain a row, then an error is returned by the statement.

 ### Row Size Too Large

 If InnoDB strict mode is enabled, and if a table exceeds its row format's [maximum row size](../innodb-row-formats-overview/index#maximum-row-size), then InnoDB will return an error.

 
```
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

```

See [Troubleshooting Row Size Too Large Errors with InnoDB](../troubleshooting-row-size-too-large-errors-with-innodb/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-strict-mode/>

Percona XtraBackup
===================

   
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

  Open source tool for performing hot backups of MariaDB, MySQL and Percona Server databases.

  

| Title | Description |
| --- | --- |
|  [Percona XtraBackup Overview](../percona-xtrabackup-overview/index) |  Open source tool for performing hot backups of MariaDB, MySQL and Percona Server databases.  |
|  [xtrabackup-v2 SST Method](../xtrabackup-v2-sst-method/index) |  The xtrabackup-v2 SST method uses the Percona XtraBackup utility for performing SSTs.  |
|  [Manual SST of Galera Cluster Node With Percona XtraBackup](../manual-sst-of-galera-cluster-node-with-percona-xtrabackup/index) |  It can be helpful to perform a "manual SST" with Xtrabackup when Galera's normal SSTs fail.  |
|  [Percona XtraBackup Build Instructions](../percona-xtrabackup-build-instructions/index) |  Build instructions for Xtrabackup  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-restore-and-import-clients-percona-xtrabackup/>

mariadb-binlog Options
======================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-binlog` is a symlink to `mysqlbinlog`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-binlog` is the name of the tool, with `mysqlbinlog` a symlink .

  [mariadb-binlog](../mariadb-binlog/index) is a utility included with MariaDB for processing [binary log](../binary-log/index) and [relay log](../relay-log/index) files.

 Options
-------

 The following options are supported by [mariadb-binlog](../mariadb-binlog/index). They can be specified on the command line or in option files:

 


| Option | default value | Description | Introduced
 |
| --- | --- | --- | --- |
| `-?`, `--help` |  | Display a help statement. |  |
| `--base64-output=name` (>= [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), [MariaDB 10.5.11](https://mariadb.com/kb/en/mariadb-10511-release-notes/)) | `auto` | Determine when the output statements should be base64-encoded BINLOG statements. Options (case-insensitive) include `auto`, `unspec`, `never` and `decode-rows`. `never` neither prints base64 encodings nor verbose event data, and will exit on error if a [row-based event](../binary-log-formats/index) is found. This option is useful for binlogs that are entirely statement based. `decode-rows` decodes row events into commented SQL statements if the `--verbose` option is also given. It can enhance the debugging experience with large binary log files, as the raw data will be omitted. Unlike *never*, *mariadb-binlog* will not exit with an error if a row event is found. `auto` (synonymous with *unspec*) outputs base64 encoded entries for [row-based](../binary-log-formats/index) and format description events; it should be used when ROW-format events are processed for re-executing on the MariaDB server. This behavior is presumed, such that `auto` is the default value when no option specification is provided. The other option values are intended only for debugging or testing purposes because they may produce output that does not include all events in executable form. |  |
| `--base64-output[=name]` (<= [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/)) | *(No default Value)* | Determine when the output statements should be base64-encoded BINLOG statements. Options (case-insensitive) include `auto`, `unspec`, `always` (deprecated), `never` and `decode-rows`. `never` disables it and works only for binlogs without [row-based events](../binary-log-formats/index); `decode-rows` decodes row events into commented SQL statements if the `--verbose` option is also given; Unlike *never*, *mariadb-binlog* does not exit with an error if a row event is found `auto` or `unspec`, the default, prints base64 only when necessary (i.e., for [row-based events](../binary-log-formats/index) and format description events), and is the only safe behavior if you intend to use the output of mariadb-binlog to re-execute binary log file contents. The other option values are intended only for debugging or testing purposes because they may produce output that does not include all events in executable form.; `always` prints base64 whenever possible, and is for debugging only and should not be used in a production system. If this option is not given, the default is `auto`; if it is given with no argument, `always` is used. |  |
| `--binlog-row-event-max-size=val` | 4294967040 (4GB) | The maximum size in bytes of a row-based [binary log](../binary-log/index) event. Should be a multiple of 256. Minimum 256, maximum 18446744073709547520. |  |
| `--character-sets-dir=name` | *(No default value)* | Directory where the [character sets](../data-types-character-sets-and-collations/index) are. |  |
| `-d`, `--database=name` | *(No default value)* | Output entries from the binary log (local log only) that occur while *name* has been selected as the default database by [USE](../use/index). Only one database can be specified. The effects depend on whether the [statement-based or row-based logging format](../binary-log-formats/index) is in use. For statement-based logging, the server will only log statements where the default database is *name*. The default database is set with the [USE](../use/index) statement. For row-based logging, the server will log any updates to any tables in the named database, irrespective of the current database. Ignored in `--raw` mode. |  |
| `-# [options]`, `--debug[=options]` | `d:t:o,/tmp/mariadb-binlog.trace` | In a debug build, write a debugging log. A typical debug options string is `d:t:o,file_name`. |  |
| `--debug-check` | FALSE | Print some debug info at exit.. |  |
| `--debug-info` | FALSE | Print some debug info and memory and CPU info at exit. |  |
| `--default-auth=name` |  | Default authentication client-side plugin to use. |  |
| `--defaults-extra-file=name` |  | Read the file *name*, which can be the full path, or the path relative to the current directory, after the global files are read. |  |
| `--defaults-file=name` |  | Only read default options from the given file name, which can be the full path, or the path relative to the current directory. |  |
| `--defaults-group-suffix=str` |  | Also read groups with a suffix of *str*. For example, since *mariadb-binlog* normally reads the [client] and [mysqlbinlog] groups, `--defaults-group-suffix=x` would cause it to also read the groups [mysqlbinlog\_x] and [client\_x]. |  |
| `-D`, `--disable-log-bin` | FALSE | Disable binary log. This is useful, if you enabled `--to-last-log` and are sending the output to the same MariaDB server. This way you could avoid an endless loop. You would also like to use it when restoring after a crash to avoid duplication of the statements you already have. NOTE: you will need a SUPER privilege to use this option. |  |
| `--do-domain-ids=name` | *(No default value)* | A list of positive integers, separated by commas, that form a whitelist of domain ids. Any log event with a [GTID](../gtid/index) that originates from a domain id specified in this list is displayed. Cannot be used with `--ignore-domain-ids`. When used with `--ignore-server-ids` or `--do-server-ids`, the result is the intersection between the two datasets | [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/) |
| `--do-server-ids=name` | *(No default value)* | A list of positive integers, separated by commas, that form a whitelist of server ids. Any log event originating from a server id specified in this list is displayed. Cannot be used with `--ignore-server-ids`. When used with `--ignore-domain-ids` or `do-domain-ids`, the result is the intersection between the two datasets. Alias for `--server-id`. | [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/) |
| `-B`, `--flashback` | FALSE | Support [flashback](../flashback/index) mode. | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |
| `-F`, `--force-if-open` | TRUE | Force if binlog was not closed properly. Defaults to ON; use `--skip-force-if-open` to disable. |  |
| `-f`, `--force-read` | FALSE | If *mariadb-binlog* reads a binary log event that it does not recognize, it prints a warning, ignores the event, and continues. Without this option, mariadb-binlog stops if it reads such an event. |  |
| `--gtid-strict-mode` | TRUE | Process binlog according to gtid-strict-mode specification. The start, stop positions are verified to satisfy start < stop comparison condition. Sequence numbers of any [gtid](../gtid/index) domain must comprise monotically growing sequence, Defaults to on; use `--skip-gtid-strict-mode` to disable. | [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/) |
| `-H`, `--hexdump` | FALSE | Augment output with hexadecimal and ASCII event dump. |  |
| `-h`, `--host=name` | *(No default value)* | Get the binlog from the MariaDB server on the given host. |  |
| `--ignore-domain-ids=name` | *(No default value)* | A list of positive integers, separated by commas, that form a blacklist of domain ids. Any log event with a [GTID](../gtid/index) that originates from a domain id specified in this list is hidden. Cannot be used with `--do-domain-ids`. When used with `--ignore-server-ids` or `--do-server-ids`, the result is the intersection between the two datasets. | [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/) |
| `--ignore-server-ids=name` | *(No default value)* | A list of positive integers, separated by commas, that form a blacklist of server ids. Any log event originating from a server id specified in this list is hidden. Cannot be used with `--do-server-ids`. When used with `--ignore-domain-ids` or `--do-domain-ids`, the result is the intersection between the two datasets. | [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/) |
| `-l path`, `--local-load=path` | *(No default value)* | Prepare local temporary files for [LOAD DATA INFILE](../load-data-infile/index) in the specified directory. The temporary files are not automatically removed. |  |
| `--no-defaults` |  | Don't read default options from any option file |  |
| `-o value`, `--offset=value` | 0 | Skip the first *value* entries in the log. |  |
| `--open_files_limit=#`  | 64 | Reserve file descriptors for usage by *mariadb-binlog*. |  |
| `-p[passwd]`, `--password[=passwd]` | *(No default value)* | Password to connect to the remote server. The password can be omitted allow it be entered from the prompt, or an option file can be used to avoid the security risk of passing a password on the commandline. |  |
| `--plugin-dir=dir_name`, |  | Directory for client-side plugins. |  |
| `-P num`, `--port=num` | 0 | 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). |  |
| `--position=#`  | 4 | Removed in [MariaDB 5.5](../what-is-mariadb-55/index). Use `--start-position` instead. |  |
| `--print-defaults` |  | Print the program argument list from all option files and exit. |  |
| `--print-row-count` | TRUE | Print row counts for each row events. (Defaults to on; use `--skip-print-row-count` to disable.) | [MariaDB 10.3](../what-is-mariadb-103/index) |
| `--print-row-event-positions` | TRUE | Print row event positions. Defaults to on; use `--skip-print-row-event-positions` to disable.) | [MariaDB 10.3](../what-is-mariadb-103/index) |
| `print-table-metadata` |  | Print metadata stored in Table\_map\_log\_event. | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| `--protocol=name` | *(No default value)* | The protocol of the connection (tcp,socket,pipe,memory). |  |
| `--raw` |  | Requires -R. Output raw binlog data instead of SQL statements. Output files named after server logs. | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| `-R`, `--read-from-remote-server` | FALSE | Read binary logs from a remote MariaDB server rather than reading a local log file. Any connection parameter options are ignored unless this option is given as well. These options are `--host`, `--password`, `--port`, `--protocol`, `--socket`, and `--user`. This option requires that the remote server be running. It works only for binary log files on the remote server, not relay log files. |  |
| `-r name`, `--result-file=name` | *(No default value)* | Direct output to a given file. With --raw this is a prefix for the file names. |  |
| `--rewrite-db=name` | *(No default value)* | Updates to a database with a different name than the original. Example: `rewrite-db='from->to'`  For events that are binlogged as statements, rewriting the database constitutes changing a statement's default database from `db1` to `db2`. There is no statement analysis or rewrite of any kind, that is, if one specifies "`db1.tbl`" in the statement explicitly, that occurrence won't be changed to "`db2.tbl`". Row-based events are rewritten correctly to use the new database name. Filtering (e.g. with `--database=name` ) happens *before* the database rewrites have been performed. If you use this option on the command line and "`>`" has a special meaning to your command interpreter, quote the value (e.g. `--rewrite-db="oldname->newname"`). |  |
| `--server-id=idnum` | 0 | Extract only binlog entries created by the server having the given id. From [MariaDB 10.9.0](https://mariadb.com/kb/en/mariadb-1090-release-notes/), alias for --do-server-ids. |  |
| `--set-charset=character_set` | *(No default value)* | Add '`SET NAMES character_set`' to the output to specify the [character set](../data-types-character-sets-and-collations/index) to be used for processing log files. |  |
| `--shared-memory-base-name=name` | MYSQL | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. |  |
| `-s`, `--short-form` | FALSE | Just show regular queries: no extra info and no row-based events. This is for testing only, and should not be used in production systems. If you want to suppress base64-output, consider using `--base64-output=never` instead. |  |
| `--skip-annotate-row-events` |  | Skip all [Annotate\_rows](../annotate_rows_log_event/index) events in the mariadb-binlog output (by default, mariadb-binlog prints Annotate\_rows events, if the binary log does contain them). |  |
| `-S`, `--socket=name` | *(No default value)* | For connections to localhost, the Unix socket file to use, or, on Windows, the name of the named pipe to use. |  |
| `--ssl` | `FALSE` | Enables [TLS](../data-in-transit-encryption/index). TLS is also enabled even without setting this option when certain other TLS options are set. Starting with [MariaDB 10.2](../what-is-mariadb-102/index), the `--ssl` option will not enable [verifying the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option. |  |
| `--ssl-ca=name` |  | Defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option implies the `--ssl` option. |  |
| `--ssl-capath=name` |  | Defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA) to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Authorities (CAs)](../secure-connections-overview/index#certificate-authorities-cas) for more information. This option is only supported if the client was built with OpenSSL or yaSSL. If the client was built with GnuTLS or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. This option implies the `--ssl` option. |  |
| `--ssl-cert=name` |  | Defines a path to the X509 certificate file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |  |
| `--ssl-cipher=name` |  | List of permitted ciphers or cipher suites to use for [TLS](../data-in-transit-encryption/index). This option implies the `--ssl` option. |  |
| `--ssl-crl=name` |  | Defines a path to a PEM file that should contain one or more revoked X509 certificates to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL or Schannel. If the client was built with yaSSL or GnuTLS, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |  |
| `--ssl-crlpath=name` |  | Defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. The directory specified by this option needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. See [Secure Connections Overview: Certificate Revocation Lists (CRLs)](../secure-connections-overview/index#certificate-revocation-lists-crls) for more information. This option is only supported if the client was built with OpenSSL. If the client was built with yaSSL, GnuTLS, or Schannel, then this option is not supported. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms. |  |
| `--ssl-key=name` |  | Defines a path to a private key file to use for [TLS](../data-in-transit-encryption/index). This option requires that you use the absolute path, not a relative path. This option implies the `--ssl` option. |  |
| `--ssl-verify-server-cert` | `FALSE` | Enables [server certificate verification](../secure-connections-overview/index#server-certificate-verification). This option is disabled by default. |  |
| `--start-datetime=datetime` | *(No default value)* | Start reading the binlog at first event having a datetime equal to or later than the argument; the argument must be a date and time in the local time zone, in any format accepted by the MariaDB server for [DATETIME](../datetime/index) and [TIMESTAMP](../timestamp/index) types, for example: 2014-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). This option is useful for point-in-time recovery. |  |
| `-j pos`, `--start-position=pos` | 4 | Start reading the binlog at this position. Type can either be a positive integer or, from [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/), a [GTID](../gtid/index) list. When using a positive integer, the value only applies to the first binlog passed on the command line. In GTID mode, multiple GTIDs can be passed as a comma separated list, where each must have a unique domain id. The list represents the gtid binlog state that the client (another "replica" server) is aware of. Therefore, each GTID is exclusive; only events after a given sequence number will be printed to allow users to receive events after their current state. |  |
| `--stop-datetime=name` | *(No default value)* | Stop reading the binlog at first event having a datetime equal or posterior to the argument; the argument must be a date and time in the local time zone, in any format accepted by the MariaDB server for DATETIME and TIMESTAMP types, for example: 2014-12-25 11:25:56 (you should probably use quotes for your shell to set it properly). Ignored in `--raw` mode. |  |
| `--stop-never` |  | Wait for more data from the server instead of stopping at the end of the last log. Implies `--to-last-log`. | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| `--stop-never-slave-server-id` |  | The slave [server\_id](../replication-and-binary-log-server-system-variables/index#server_id) used for `--read-from-remote-server` `--stop-never`. | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| `--stop-position=pos` | 18446744073709551615 | Stop reading the binlog at this position. Type can either be a positive integer or, from [MariaDB 10.8](../what-is-mariadb-108/index), a [GTID](../gtid/index) list. When using a positive integer, the value only applies to the last binlog passed on the command line. In GTID mode, multiple GTIDs can be passed as a comma separated list, where each must have a unique domain id. Each GTID is inclusive; only events up to the given sequence numbers are printed. Ignored in `--raw` mode. |  |
| `-T`, `--table` |  | List entries for just this table (local log only). | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |
| `--tls-version=name` | TLSv1.1,TLSv1.2,TLSv1.3 | This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. See [Secure Connections Overview: TLS Protocol Versions](../secure-connections-overview/index#tls-protocol-versions) for more information. | [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) |
| `-t`, `--to-last-log` | FALSE | Requires `-R` or `--read-from-remote-server` . Will not stop at the end of the requested binlog but rather continue printing until the end of the last binlog of the MariaDB server. If you send the output to the same MariaDB server, that may lead to an endless loop. |  |
| `-u`, `--user=username` | *(No default value)* | Connect to the remote server as username. |  |
| `-v`, `--verbose` |  | Reconstruct SQL statements out of row events. -v -v adds comments on column data types |  |
| `-V`, `--version` |  | Print version and exit. |  |
| `--verify-binlog-checksum` |  | Verify [binlog event checksums](../binlog-event-checksums/index) when reading a binlog file. |  |

 
Option Files
------------

 In addition to reading options from the command-line, `mariadb-binlog` can also read options from [option files](../configuring-mariadb-with-option-files/index). If an unknown option is provided to `mariadb-binlog` in an option file, then it is ignored.

 The following options relate to how MariaDB command-line tools handles option files. They must be given as the first argument on the command-line:

 


| Option | Description |
| --- | --- |
| `--print-defaults` | Print the program argument list and exit. |
| `--no-defaults` | Don't read default options from any option file. |
| `--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=#`  | In addition to the default option groups, also read option groups with this suffix. |

 
In [MariaDB 10.2](../what-is-mariadb-102/index) and later, `mariadb-binlog` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 ### Option Groups

 `mariadb-binlog` reads options from the following [option groups](../configuring-mariadb-with-option-files/index#option-groups) from [option files](../configuring-mariadb-with-option-files/index):

 


| Group | Description |
| --- | --- |
| `[mysqlbinlog]` |  Options read by `mariadb-binlog`, which includes both MariaDB Server and MySQL Server. |
| `[mariadb-binlog]` | Options read by `mariadb-binlog`. Available starting with [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/). |
| `[client]` |  Options read by all MariaDB and MySQL [client programs](../clients-utilities/index), which includes both MariaDB and MySQL clients. For example, `mysqldump`. |
| `[client-server]` | Options read by all MariaDB [client programs](../clients-utilities/index) and the MariaDB Server. This is useful for options like socket and port, which is common between the server and the clients. |
| `[client-mariadb]` | Options read by all MariaDB [client programs](../clients-utilities/index). |

 
`mariadb-binlog` is linked with [MariaDB Connector/C](../about-mariadb-connector-c/index). However, MariaDB Connector/C does not yet handle the parsing of option files for this client. That is still performed by the server option file parsing code. See [MDEV-19035](https://jira.mariadb.org/browse/MDEV-19035) for more information.

 See Also
--------

 * [Using mariadb-binlog](../using-mariadb-binlog/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-binlog-options/>

Using mariadb-binlog
====================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-binlog` is a symlink to `mysqlbinlog`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-binlog` is the name of the tool, with `mysqlbinlog` a symlink .

 
The MariaDB server's [binary log](../binary-log/index) is a set of files containing "events" which represent modifications to the contents of a MariaDB database. These events are written in a binary (i.e. non-human-readable) format. The *mariadb-binlog* utility is used to view these events in plain text.

 Run [mariadb-binlog](../mariadb-binlog/index) from a command-line like this:

 
```
shell> mariadb-binlog [options] log_file ...

```

See [mariadb-binlog Options](../mariadb-binlog-options/index) for details on the available options.

 As an example, here is how you could display the contents of a [binary log](../binary-log/index) file named "mariadb-bin.000152":

 
```
shell> mariadb-binlog mariadb-bin.000152

```

If you are using statement-based logging (the default) the output includes the SQL statement, the ID of the server the statement was executed on, a timestamp, and how much time the statement took to execute. If you are using row-based logging the output of an event will not include an SQL statement but will instead output how individual rows were changed.

 The output from mariadb-binlog can be used as input to the mariadb client to redo the statements contained in a [binary log](../binary-log/index). This is useful for recovering after a server crash. Here is an example:

 
```
shell> mariadb-binlog binlog-filenames | mysql -u root -p

```

If you would like to view and possibly edit the file before applying it to your database, use the '-r' flag to redirect the output to a file:

 
```
shell> mariadb-binlog -r filename binlog-filenames

```

You can then open the file and view it and delete any statements you don't want executed (such as an accidental DROP DATABASE). Once you are satisfied with the contents you can execute it with:

 
```
shell> mariadb -u root -p < filename

```

Be careful to process multiple log files in a single connection, especially if one or more of them have any `CREATE TEMPORARY TABLE ...` statements. Temporary tables are dropped when the mariadb client terminates, so if you are processing multiple log files one at a time (i.e. multiple connections) and one log file creates a temporary table and then a subsequent log file refers to the table you will get an 'unknown table' error.

 To execute multiple logfiles using a single connection, list them all on the mariadb-binlog command line:

 
```
shell> mariadb-binlog mariadb-bin.000001 mariadb-bin.000002 | mariadb -u root -p

```

If you need to manually edit the binlogs before executing them, combine them all into a single file before processing. Here is an example:

 
```
shell> mariadb-binlog mariadb-bin.000001 > /tmp/mariadb-bin.sql
shell> mariadb-binlog mariadb-bin.000002 >> /tmp/mariadb-bin.sql
shell> # make any edits
shell> mysql -u root -p -e "source /tmp/mariadb-bin.sql"

```

See Also
--------

 * [mysqlbinlog](../mysqlbinlog/index)
* [mariadb-binlog Options](../mariadb-binlog-options/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-binlog/>

Troubleshooting Row Size Too Large Errors with InnoDB
=====================================================

    With InnoDB, users can see the following message as an error or warning:

 
```
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored 
inline.

```

And they can also see the following message as an error or warning in the [error log](../error-log/index):

 
```
[Warning] InnoDB: Cannot add field col in table db1.tab because after adding it, 
the row size is 8478 which is greater than maximum allowed size (8126) for a 
record on index leaf page.

```

  
 These messages indicate that the table's definition allows rows that the table's InnoDB row format can't actually store.

 These messages are raised in the following cases:

 * If [InnoDB strict mode](../innodb-strict-mode/index) is **enabled** and if a [DDL](../data-definition/index) statement is executed that touches the table, such as [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index), then InnoDB will raise an **error** with this message
* If [InnoDB strict mode](../innodb-strict-mode/index) is **disabled** and if a [DDL](../data-definition/index) statement is executed that touches the table, such as [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index), then InnoDB will raise a **warning** with this message.
* Regardless of whether [InnoDB strict mode](../innodb-strict-mode/index) is enabled, if a [DML](../data-manipulation/index) statement is executed that attempts to write a row that the table's InnoDB row format can't store, then InnoDB will raise an **error** with this message.

 Example of the Problem
----------------------

 Here is an example of the problem:

 
```
SET GLOBAL innodb_default_row_format='dynamic';

SET SESSION innodb_strict_mode=ON;

CREATE OR REPLACE TABLE tab (
   col1 varchar(40) NOT NULL,
   col2 varchar(40) NOT NULL,
   col3 varchar(40) NOT NULL,
   col4 varchar(40) NOT NULL,
   col5 varchar(40) NOT NULL,
   col6 varchar(40) NOT NULL,
   col7 varchar(40) NOT NULL,
   col8 varchar(40) NOT NULL,
   col9 varchar(40) NOT NULL,
   col10 varchar(40) NOT NULL,
   col11 varchar(40) NOT NULL,
   col12 varchar(40) NOT NULL,
   col13 varchar(40) NOT NULL,
   col14 varchar(40) NOT NULL,
   col15 varchar(40) NOT NULL,
   col16 varchar(40) NOT NULL,
   col17 varchar(40) NOT NULL,
   col18 varchar(40) NOT NULL,
   col19 varchar(40) NOT NULL,
   col20 varchar(40) NOT NULL,
   col21 varchar(40) NOT NULL,
   col22 varchar(40) NOT NULL,
   col23 varchar(40) NOT NULL,
   col24 varchar(40) NOT NULL,
   col25 varchar(40) NOT NULL,
   col26 varchar(40) NOT NULL,
   col27 varchar(40) NOT NULL,
   col28 varchar(40) NOT NULL,
   col29 varchar(40) NOT NULL,
   col30 varchar(40) NOT NULL,
   col31 varchar(40) NOT NULL,
   col32 varchar(40) NOT NULL,
   col33 varchar(40) NOT NULL,
   col34 varchar(40) NOT NULL,
   col35 varchar(40) NOT NULL,
   col36 varchar(40) NOT NULL,
   col37 varchar(40) NOT NULL,
   col38 varchar(40) NOT NULL,
   col39 varchar(40) NOT NULL,
   col40 varchar(40) NOT NULL,
   col41 varchar(40) NOT NULL,
   col42 varchar(40) NOT NULL,
   col43 varchar(40) NOT NULL,
   col44 varchar(40) NOT NULL,
   col45 varchar(40) NOT NULL,
   col46 varchar(40) NOT NULL,
   col47 varchar(40) NOT NULL,
   col48 varchar(40) NOT NULL,
   col49 varchar(40) NOT NULL,
   col50 varchar(40) NOT NULL,
   col51 varchar(40) NOT NULL,
   col52 varchar(40) NOT NULL,
   col53 varchar(40) NOT NULL,
   col54 varchar(40) NOT NULL,
   col55 varchar(40) NOT NULL,
   col56 varchar(40) NOT NULL,
   col57 varchar(40) NOT NULL,
   col58 varchar(40) NOT NULL,
   col59 varchar(40) NOT NULL,
   col60 varchar(40) NOT NULL,
   col61 varchar(40) NOT NULL,
   col62 varchar(40) NOT NULL,
   col63 varchar(40) NOT NULL,
   col64 varchar(40) NOT NULL,
   col65 varchar(40) NOT NULL,
   col66 varchar(40) NOT NULL,
   col67 varchar(40) NOT NULL,
   col68 varchar(40) NOT NULL,
   col69 varchar(40) NOT NULL,
   col70 varchar(40) NOT NULL,
   col71 varchar(40) NOT NULL,
   col72 varchar(40) NOT NULL,
   col73 varchar(40) NOT NULL,
   col74 varchar(40) NOT NULL,
   col75 varchar(40) NOT NULL,
   col76 varchar(40) NOT NULL,
   col77 varchar(40) NOT NULL,
   col78 varchar(40) NOT NULL,
   col79 varchar(40) NOT NULL,
   col80 varchar(40) NOT NULL,
   col81 varchar(40) NOT NULL,
   col82 varchar(40) NOT NULL,
   col83 varchar(40) NOT NULL,
   col84 varchar(40) NOT NULL,
   col85 varchar(40) NOT NULL,
   col86 varchar(40) NOT NULL,
   col87 varchar(40) NOT NULL,
   col88 varchar(40) NOT NULL,
   col89 varchar(40) NOT NULL,
   col90 varchar(40) NOT NULL,
   col91 varchar(40) NOT NULL,
   col92 varchar(40) NOT NULL,
   col93 varchar(40) NOT NULL,
   col94 varchar(40) NOT NULL,
   col95 varchar(40) NOT NULL,
   col96 varchar(40) NOT NULL,
   col97 varchar(40) NOT NULL,
   col98 varchar(40) NOT NULL,
   col99 varchar(40) NOT NULL,
   col100 varchar(40) NOT NULL,
   col101 varchar(40) NOT NULL,
   col102 varchar(40) NOT NULL,
   col103 varchar(40) NOT NULL,
   col104 varchar(40) NOT NULL,
   col105 varchar(40) NOT NULL,
   col106 varchar(40) NOT NULL,
   col107 varchar(40) NOT NULL,
   col108 varchar(40) NOT NULL,
   col109 varchar(40) NOT NULL,
   col110 varchar(40) NOT NULL,
   col111 varchar(40) NOT NULL,
   col112 varchar(40) NOT NULL,
   col113 varchar(40) NOT NULL,
   col114 varchar(40) NOT NULL,
   col115 varchar(40) NOT NULL,
   col116 varchar(40) NOT NULL,
   col117 varchar(40) NOT NULL,
   col118 varchar(40) NOT NULL,
   col119 varchar(40) NOT NULL,
   col120 varchar(40) NOT NULL,
   col121 varchar(40) NOT NULL,
   col122 varchar(40) NOT NULL,
   col123 varchar(40) NOT NULL,
   col124 varchar(40) NOT NULL,
   col125 varchar(40) NOT NULL,
   col126 varchar(40) NOT NULL,
   col127 varchar(40) NOT NULL,
   col128 varchar(40) NOT NULL,
   col129 varchar(40) NOT NULL,
   col130 varchar(40) NOT NULL,
   col131 varchar(40) NOT NULL,
   col132 varchar(40) NOT NULL,
   col133 varchar(40) NOT NULL,
   col134 varchar(40) NOT NULL,
   col135 varchar(40) NOT NULL,
   col136 varchar(40) NOT NULL,
   col137 varchar(40) NOT NULL,
   col138 varchar(40) NOT NULL,
   col139 varchar(40) NOT NULL,
   col140 varchar(40) NOT NULL,
   col141 varchar(40) NOT NULL,
   col142 varchar(40) NOT NULL,
   col143 varchar(40) NOT NULL,
   col144 varchar(40) NOT NULL,
   col145 varchar(40) NOT NULL,
   col146 varchar(40) NOT NULL,
   col147 varchar(40) NOT NULL,
   col148 varchar(40) NOT NULL,
   col149 varchar(40) NOT NULL,
   col150 varchar(40) NOT NULL,
   col151 varchar(40) NOT NULL,
   col152 varchar(40) NOT NULL,
   col153 varchar(40) NOT NULL,
   col154 varchar(40) NOT NULL,
   col155 varchar(40) NOT NULL,
   col156 varchar(40) NOT NULL,
   col157 varchar(40) NOT NULL,
   col158 varchar(40) NOT NULL,
   col159 varchar(40) NOT NULL,
   col160 varchar(40) NOT NULL,
   col161 varchar(40) NOT NULL,
   col162 varchar(40) NOT NULL,
   col163 varchar(40) NOT NULL,
   col164 varchar(40) NOT NULL,
   col165 varchar(40) NOT NULL,
   col166 varchar(40) NOT NULL,
   col167 varchar(40) NOT NULL,
   col168 varchar(40) NOT NULL,
   col169 varchar(40) NOT NULL,
   col170 varchar(40) NOT NULL,
   col171 varchar(40) NOT NULL,
   col172 varchar(40) NOT NULL,
   col173 varchar(40) NOT NULL,
   col174 varchar(40) NOT NULL,
   col175 varchar(40) NOT NULL,
   col176 varchar(40) NOT NULL,
   col177 varchar(40) NOT NULL,
   col178 varchar(40) NOT NULL,
   col179 varchar(40) NOT NULL,
   col180 varchar(40) NOT NULL,
   col181 varchar(40) NOT NULL,
   col182 varchar(40) NOT NULL,
   col183 varchar(40) NOT NULL,
   col184 varchar(40) NOT NULL,
   col185 varchar(40) NOT NULL,
   col186 varchar(40) NOT NULL,
   col187 varchar(40) NOT NULL,
   col188 varchar(40) NOT NULL,
   col189 varchar(40) NOT NULL,
   col190 varchar(40) NOT NULL,
   col191 varchar(40) NOT NULL,
   col192 varchar(40) NOT NULL,
   col193 varchar(40) NOT NULL,
   col194 varchar(40) NOT NULL,
   col195 varchar(40) NOT NULL,
   col196 varchar(40) NOT NULL,
   col197 varchar(40) NOT NULL,
   col198 varchar(40) NOT NULL,
   PRIMARY KEY (col1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

```

Root Cause of the Problem
-------------------------

 The root cause is that InnoDB has a maximum row size that is roughly equivalent to half of the value of the [innodb\_page\_size](../xtradbinnodb-server-system-variables/index#innodb_page_size) system variable. See [InnoDB Row Formats Overview: Maximum Row Size](../innodb-row-formats-overview/index#maximum-row-size) for more information.

 InnoDB's row formats work around this limit by storing certain kinds of variable-length columns on overflow pages. However, different row formats can store different types of data on overflow pages. Some row formats can store more data in overflow pages than others. For example, the [DYNAMIC](../innodb-dynamic-row-format/index) and [COMPRESSED](../innodb-compressed-row-format/index) row formats can store the most data in overflow pages. To learn how the various InnoDB row formats use overflow pages, see the following pages:

 * [InnoDB REDUNDANT Row Format: Overflow Pages with the REDUNDANT Row Format](../innodb-redundant-row-format/index#overflow-pages-with-the-redundant-row-format)
* [InnoDB COMPACT Row Format: Overflow Pages with the COMPACT Row Format](../innodb-compact-row-format/index#overflow-pages-with-the-compact-row-format)
* [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format)
* [InnoDB COMPRESSED Row Format: Overflow Pages with the COMPRESSED Row Format](../innodb-compressed-row-format/index#overflow-pages-with-the-compressed-row-format)

 Checking Existing Tables for the Problem
----------------------------------------

 InnoDB does not currently have an easy way to check all existing tables to determine which tables have this problem. See [MDEV-20400](https://jira.mariadb.org/browse/MDEV-20400) for more information.

 One method to check a single existing table for this problem is to enable [InnoDB strict mode](../innodb-strict-mode/index), and then try to create a duplicate of the table with [CREATE TABLE ... LIKE](../create-table/index#create-table-like). If the table has this problem, then the operation will fail. For example:

 
```
SET SESSION innodb_strict_mode=ON;

CREATE TABLE tab_dup LIKE tab;
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

```

Finding All Tables That Currently Have the Problem
--------------------------------------------------

 The following shell script will read through a MariaDB server to identify every table that has a row size definition that is too large for its row format and the server's page size. It runs on most common distributions of Linux.

 To run the script, copy the code below to a shell-script named `rowsize.sh`, make it executable with the command `chmod 755 ./rowsize.sh`, and invoke it with the following parameters:

 
```
./rowsize.sh host user password

```

When the script runs, it displays the name of the temporary database it creates, so that if the script is interrupted before cleaning up, the database can be easily identified and removed manually.

 As the script runs it will output one line reporting the database and tablename for each table it finds that has the oversize row problem. If it finds none, it will print the following message: "No tables with rows size too big found."

 In either case, the script prints one final line to announce when it's done: `./rowsize.sh done.`

 
```
#!/bin/bash

[ -z "$3" ] && echo "Usage: $0 host user password" >&2 && exit 1

dt="tmp_$RANDOM$RANDOM"

mysql -h $1 -u $2 -p$3 -ABNe "create database $dt;"
[ $? -ne 0 ] && echo "Error: $0 terminating" >&2 exit 1

echo
echo "Created temporary database ${dt} on host $1"
echo

c=0
for d in $(mysql -h $1 -u $2 -p$3 -ABNe "show databases;" | egrep -iv "information_schema|mysql|performance_schema|$dt")
do
	for t in $(mysql -h $1 -u $2 -p$3 -ABNe "show tables;" $d)
	do
		tc=$(mysql -h $1 -u $2 -p$3 -ABNe "show create table $t\\G" $d | egrep -iv "^\*|^$t")
		
		echo $tc | grep -iq "ROW_FORMAT"
		if [ $? -ne 0 ]
		then
			tf=$(mysql -h $1 -u $2 -p$3 -ABNe "select row_format from information_schema.innodb_sys_tables where name = '${d}/${t}';")
			tc="$tc ROW_FORMAT=$tf"
		fi
		
		ef="/tmp/e$RANDOM$RANDOM"
		mysql -h $1 -u $2 -p$3 -ABNe "set innodb_strict_mode=1; set foreign_key_checks=0; ${tc};" $dt >/dev/null  2>$ef
		[ $? -ne 0 ] && cat $ef | grep -q "Row size too large" && echo "${d}.${t}" && let c++ || mysql -h $1 -u $2 -p$3 -ABNe "drop table if exists ${t};" $dt
		rm -f $ef
	done
done
mysql -h $1 -u $2 -p$3 -ABNe "set innodb_strict_mode=1; drop database $dt;"
[ $c -eq 0 ] && echo "No tables with rows size too large found." || echo && echo "$c tables found with row size too large."
echo
echo "$0 done."

```

Solving the Problem
-------------------

 There are several potential solutions available to solve this problem.

 ### Converting the Table to the DYNAMIC Row Format

 If the table is using either the [REDUNDANT](../innodb-redundant-row-format/index) or the [COMPACT](../innodb-compact-row-format/index) row format, then one potential solution to this problem is to convert the table to use the [DYNAMIC](../innodb-dynamic-row-format/index) row format instead.

 If your tables were originally created on an older version of MariaDB or MySQL, then your table may be using one of InnoDB's older row formats:

 * In [MariaDB 10.1](../what-is-mariadb-101/index) and before, and in MySQL 5.6 and before, the [COMPACT](../innodb-compact-row-format/index) row format was the default row format.
* In MySQL 4.1 and before, the [REDUNDANT](../innodb-redundant-row-format/index) row format was the default row format.

 The [DYNAMIC](../innodb-dynamic-row-format/index) row format can store more data on overflow pages than these older row formats, so this row format may actually be able to store the table's data safely. See [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format) for more information.

 Therefore, a potential solution to the *Row size too large* error is to convert the table to use the [DYNAMIC](../innodb-dynamic-row-format/index) row format. For example:

 
```
ALTER TABLE tab ROW_FORMAT=DYNAMIC;

```

You can use the [INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table in the [information\_schema](../information-schema-tables/index) database to find all tables that use the [REDUNDANT](../innodb-redundant-row-format/index) or the [COMPACT](../innodb-compact-row-format/index) row formats. This is helpful if you would like to convert all of your tables that you still use the older row formats to the [DYNAMIC](../innodb-dynamic-row-format/index) row format. For example, the following query can find those tables, while excluding [InnoDB's internal system tables](../innodb-system-tablespaces/index#system-tables-within-the-innodb-system-tablespace):

 
```
SELECT NAME, ROW_FORMAT
FROM information_schema.INNODB_SYS_TABLES
WHERE ROW_FORMAT IN('Redundant', 'Compact')
AND NAME NOT IN('SYS_DATAFILES', 'SYS_FOREIGN', 'SYS_FOREIGN_COLS', 'SYS_TABLESPACES', 'SYS_VIRTUAL', 'SYS_ZIP_DICT', 'SYS_ZIP_DICT_COLS');

```

In [MariaDB 10.2](../what-is-mariadb-102/index) and later, the [DYNAMIC](../innodb-dynamic-row-format/index) row format is the default row format. If your tables were originally created on one of these newer versions, then they may already be using this row format. In that case, you may need to try the next solution.

 ### Fitting More Columns on Overflow Pages

 If the table is already using the [DYNAMIC](../innodb-dynamic-row-format/index) row format, then another potential solution to this problem is to change the table schema, so that the row format can store more columns on overflow pages.

 In order for InnoDB to store some variable-length columns on overflow pages, the length of those columns may need to be increased.

 Therefore, a counter-intuitive solution to the *Row size too large* error in a lot of cases is actually to **increase** the length of some variable-length columns, so that InnoDB's row format can store them on overflow pages. 

 Some possible ways to change the table schema are listed below.

 #### Converting Some Columns to `BLOB` or `TEXT`

 For [BLOB](../blob/index) and [TEXT](../text/index) columns, the [DYNAMIC](../innodb-dynamic-row-format/index) row format can store these columns on overflow pages. See [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format) for more information.

 Therefore, a potential solution to the *Row size too large* error is to convert some columns to the [BLOB](../blob/index) or [TEXT](../text/index) data types.

 #### Increasing the Length of `VARBINARY` Columns

 For [VARBINARY](../varbinary/index) columns, the [DYNAMIC](../innodb-dynamic-row-format/index) row format can only store these columns on overflow pages if the maximum length of the column is 256 bytes or longer. See [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format) for more information.

 Therefore, a potential solution to the *Row size too large* error is to ensure that all [VARBINARY](../varbinary/index) columns are at least as long as `varbinary(256)`.

 #### Increasing the Length of `VARCHAR` Columns

 For [VARCHAR](../varchar/index) columns, the [DYNAMIC](../innodb-dynamic-row-format/index) row format can only store these columns on overflow pages if the maximum length of the column is 256 bytes or longer. See [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format) for more information.

 The original table schema shown earlier on this page causes the *Row size too large* error, because all of the table's [VARCHAR](../varchar/index) columns are smaller than 256 bytes, which means that they have to be stored on the row's main data page.

 Therefore, a potential solution to the *Row size too large* error is to ensure that all [VARCHAR](../varchar/index) columns are at least as long as 256 bytes. The number of characters required to reach the 256 byte limit depends on the [character set](../character-sets/index) used by the column.

 For example, when using InnoDB's [DYNAMIC](../innodb-dynamic-row-format/index) row format and a default character set of [latin1](../supported-character-sets-and-collations/index) (which requires up to 1 byte per character), the 256 byte limit means that a [VARCHAR](../varchar/index) column will only be stored on overflow pages if it is at least as large as a `varchar(256)`:

 
```
SET GLOBAL innodb_default_row_format='dynamic';
SET SESSION innodb_strict_mode=ON;
CREATE OR REPLACE TABLE tab (
   col1 varchar(256) NOT NULL,
   col2 varchar(256) NOT NULL,
   col3 varchar(256) NOT NULL,
   col4 varchar(256) NOT NULL,
   col5 varchar(256) NOT NULL,
   col6 varchar(256) NOT NULL,
   col7 varchar(256) NOT NULL,
   col8 varchar(256) NOT NULL,
   col9 varchar(256) NOT NULL,
   col10 varchar(256) NOT NULL,
   col11 varchar(256) NOT NULL,
   col12 varchar(256) NOT NULL,
   col13 varchar(256) NOT NULL,
   col14 varchar(256) NOT NULL,
   col15 varchar(256) NOT NULL,
   col16 varchar(256) NOT NULL,
   col17 varchar(256) NOT NULL,
   col18 varchar(256) NOT NULL,
   col19 varchar(256) NOT NULL,
   col20 varchar(256) NOT NULL,
   col21 varchar(256) NOT NULL,
   col22 varchar(256) NOT NULL,
   col23 varchar(256) NOT NULL,
   col24 varchar(256) NOT NULL,
   col25 varchar(256) NOT NULL,
   col26 varchar(256) NOT NULL,
   col27 varchar(256) NOT NULL,
   col28 varchar(256) NOT NULL,
   col29 varchar(256) NOT NULL,
   col30 varchar(256) NOT NULL,
   col31 varchar(256) NOT NULL,
   col32 varchar(256) NOT NULL,
   col33 varchar(256) NOT NULL,
   col34 varchar(256) NOT NULL,
   col35 varchar(256) NOT NULL,
   col36 varchar(256) NOT NULL,
   col37 varchar(256) NOT NULL,
   col38 varchar(256) NOT NULL,
   col39 varchar(256) NOT NULL,
   col40 varchar(256) NOT NULL,
   col41 varchar(256) NOT NULL,
   col42 varchar(256) NOT NULL,
   col43 varchar(256) NOT NULL,
   col44 varchar(256) NOT NULL,
   col45 varchar(256) NOT NULL,
   col46 varchar(256) NOT NULL,
   col47 varchar(256) NOT NULL,
   col48 varchar(256) NOT NULL,
   col49 varchar(256) NOT NULL,
   col50 varchar(256) NOT NULL,
   col51 varchar(256) NOT NULL,
   col52 varchar(256) NOT NULL,
   col53 varchar(256) NOT NULL,
   col54 varchar(256) NOT NULL,
   col55 varchar(256) NOT NULL,
   col56 varchar(256) NOT NULL,
   col57 varchar(256) NOT NULL,
   col58 varchar(256) NOT NULL,
   col59 varchar(256) NOT NULL,
   col60 varchar(256) NOT NULL,
   col61 varchar(256) NOT NULL,
   col62 varchar(256) NOT NULL,
   col63 varchar(256) NOT NULL,
   col64 varchar(256) NOT NULL,
   col65 varchar(256) NOT NULL,
   col66 varchar(256) NOT NULL,
   col67 varchar(256) NOT NULL,
   col68 varchar(256) NOT NULL,
   col69 varchar(256) NOT NULL,
   col70 varchar(256) NOT NULL,
   col71 varchar(256) NOT NULL,
   col72 varchar(256) NOT NULL,
   col73 varchar(256) NOT NULL,
   col74 varchar(256) NOT NULL,
   col75 varchar(256) NOT NULL,
   col76 varchar(256) NOT NULL,
   col77 varchar(256) NOT NULL,
   col78 varchar(256) NOT NULL,
   col79 varchar(256) NOT NULL,
   col80 varchar(256) NOT NULL,
   col81 varchar(256) NOT NULL,
   col82 varchar(256) NOT NULL,
   col83 varchar(256) NOT NULL,
   col84 varchar(256) NOT NULL,
   col85 varchar(256) NOT NULL,
   col86 varchar(256) NOT NULL,
   col87 varchar(256) NOT NULL,
   col88 varchar(256) NOT NULL,
   col89 varchar(256) NOT NULL,
   col90 varchar(256) NOT NULL,
   col91 varchar(256) NOT NULL,
   col92 varchar(256) NOT NULL,
   col93 varchar(256) NOT NULL,
   col94 varchar(256) NOT NULL,
   col95 varchar(256) NOT NULL,
   col96 varchar(256) NOT NULL,
   col97 varchar(256) NOT NULL,
   col98 varchar(256) NOT NULL,
   col99 varchar(256) NOT NULL,
   col100 varchar(256) NOT NULL,
   col101 varchar(256) NOT NULL,
   col102 varchar(256) NOT NULL,
   col103 varchar(256) NOT NULL,
   col104 varchar(256) NOT NULL,
   col105 varchar(256) NOT NULL,
   col106 varchar(256) NOT NULL,
   col107 varchar(256) NOT NULL,
   col108 varchar(256) NOT NULL,
   col109 varchar(256) NOT NULL,
   col110 varchar(256) NOT NULL,
   col111 varchar(256) NOT NULL,
   col112 varchar(256) NOT NULL,
   col113 varchar(256) NOT NULL,
   col114 varchar(256) NOT NULL,
   col115 varchar(256) NOT NULL,
   col116 varchar(256) NOT NULL,
   col117 varchar(256) NOT NULL,
   col118 varchar(256) NOT NULL,
   col119 varchar(256) NOT NULL,
   col120 varchar(256) NOT NULL,
   col121 varchar(256) NOT NULL,
   col122 varchar(256) NOT NULL,
   col123 varchar(256) NOT NULL,
   col124 varchar(256) NOT NULL,
   col125 varchar(256) NOT NULL,
   col126 varchar(256) NOT NULL,
   col127 varchar(256) NOT NULL,
   col128 varchar(256) NOT NULL,
   col129 varchar(256) NOT NULL,
   col130 varchar(256) NOT NULL,
   col131 varchar(256) NOT NULL,
   col132 varchar(256) NOT NULL,
   col133 varchar(256) NOT NULL,
   col134 varchar(256) NOT NULL,
   col135 varchar(256) NOT NULL,
   col136 varchar(256) NOT NULL,
   col137 varchar(256) NOT NULL,
   col138 varchar(256) NOT NULL,
   col139 varchar(256) NOT NULL,
   col140 varchar(256) NOT NULL,
   col141 varchar(256) NOT NULL,
   col142 varchar(256) NOT NULL,
   col143 varchar(256) NOT NULL,
   col144 varchar(256) NOT NULL,
   col145 varchar(256) NOT NULL,
   col146 varchar(256) NOT NULL,
   col147 varchar(256) NOT NULL,
   col148 varchar(256) NOT NULL,
   col149 varchar(256) NOT NULL,
   col150 varchar(256) NOT NULL,
   col151 varchar(256) NOT NULL,
   col152 varchar(256) NOT NULL,
   col153 varchar(256) NOT NULL,
   col154 varchar(256) NOT NULL,
   col155 varchar(256) NOT NULL,
   col156 varchar(256) NOT NULL,
   col157 varchar(256) NOT NULL,
   col158 varchar(256) NOT NULL,
   col159 varchar(256) NOT NULL,
   col160 varchar(256) NOT NULL,
   col161 varchar(256) NOT NULL,
   col162 varchar(256) NOT NULL,
   col163 varchar(256) NOT NULL,
   col164 varchar(256) NOT NULL,
   col165 varchar(256) NOT NULL,
   col166 varchar(256) NOT NULL,
   col167 varchar(256) NOT NULL,
   col168 varchar(256) NOT NULL,
   col169 varchar(256) NOT NULL,
   col170 varchar(256) NOT NULL,
   col171 varchar(256) NOT NULL,
   col172 varchar(256) NOT NULL,
   col173 varchar(256) NOT NULL,
   col174 varchar(256) NOT NULL,
   col175 varchar(256) NOT NULL,
   col176 varchar(256) NOT NULL,
   col177 varchar(256) NOT NULL,
   col178 varchar(256) NOT NULL,
   col179 varchar(256) NOT NULL,
   col180 varchar(256) NOT NULL,
   col181 varchar(256) NOT NULL,
   col182 varchar(256) NOT NULL,
   col183 varchar(256) NOT NULL,
   col184 varchar(256) NOT NULL,
   col185 varchar(256) NOT NULL,
   col186 varchar(256) NOT NULL,
   col187 varchar(256) NOT NULL,
   col188 varchar(256) NOT NULL,
   col189 varchar(256) NOT NULL,
   col190 varchar(256) NOT NULL,
   col191 varchar(256) NOT NULL,
   col192 varchar(256) NOT NULL,
   col193 varchar(256) NOT NULL,
   col194 varchar(256) NOT NULL,
   col195 varchar(256) NOT NULL,
   col196 varchar(256) NOT NULL,
   col197 varchar(256) NOT NULL,
   col198 varchar(256) NOT NULL,
   PRIMARY KEY (col1)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

```

And when using InnoDB's [DYNAMIC](../innodb-dynamic-row-format/index) row format and a default character set of [utf8](../unicode/index) (which requires up to 3 bytes per character), the 256 byte limit means that a [VARCHAR](../varchar/index) column will only be stored on overflow pages if it is at least as large as a `varchar(86)`:

 
```
SET GLOBAL innodb_default_row_format='dynamic';
SET SESSION innodb_strict_mode=ON;
CREATE OR REPLACE TABLE tab (
   col1 varchar(86) NOT NULL,
   col2 varchar(86) NOT NULL,
   col3 varchar(86) NOT NULL,
   col4 varchar(86) NOT NULL,
   col5 varchar(86) NOT NULL,
   col6 varchar(86) NOT NULL,
   col7 varchar(86) NOT NULL,
   col8 varchar(86) NOT NULL,
   col9 varchar(86) NOT NULL,
   col10 varchar(86) NOT NULL,
   col11 varchar(86) NOT NULL,
   col12 varchar(86) NOT NULL,
   col13 varchar(86) NOT NULL,
   col14 varchar(86) NOT NULL,
   col15 varchar(86) NOT NULL,
   col16 varchar(86) NOT NULL,
   col17 varchar(86) NOT NULL,
   col18 varchar(86) NOT NULL,
   col19 varchar(86) NOT NULL,
   col20 varchar(86) NOT NULL,
   col21 varchar(86) NOT NULL,
   col22 varchar(86) NOT NULL,
   col23 varchar(86) NOT NULL,
   col24 varchar(86) NOT NULL,
   col25 varchar(86) NOT NULL,
   col26 varchar(86) NOT NULL,
   col27 varchar(86) NOT NULL,
   col28 varchar(86) NOT NULL,
   col29 varchar(86) NOT NULL,
   col30 varchar(86) NOT NULL,
   col31 varchar(86) NOT NULL,
   col32 varchar(86) NOT NULL,
   col33 varchar(86) NOT NULL,
   col34 varchar(86) NOT NULL,
   col35 varchar(86) NOT NULL,
   col36 varchar(86) NOT NULL,
   col37 varchar(86) NOT NULL,
   col38 varchar(86) NOT NULL,
   col39 varchar(86) NOT NULL,
   col40 varchar(86) NOT NULL,
   col41 varchar(86) NOT NULL,
   col42 varchar(86) NOT NULL,
   col43 varchar(86) NOT NULL,
   col44 varchar(86) NOT NULL,
   col45 varchar(86) NOT NULL,
   col46 varchar(86) NOT NULL,
   col47 varchar(86) NOT NULL,
   col48 varchar(86) NOT NULL,
   col49 varchar(86) NOT NULL,
   col50 varchar(86) NOT NULL,
   col51 varchar(86) NOT NULL,
   col52 varchar(86) NOT NULL,
   col53 varchar(86) NOT NULL,
   col54 varchar(86) NOT NULL,
   col55 varchar(86) NOT NULL,
   col56 varchar(86) NOT NULL,
   col57 varchar(86) NOT NULL,
   col58 varchar(86) NOT NULL,
   col59 varchar(86) NOT NULL,
   col60 varchar(86) NOT NULL,
   col61 varchar(86) NOT NULL,
   col62 varchar(86) NOT NULL,
   col63 varchar(86) NOT NULL,
   col64 varchar(86) NOT NULL,
   col65 varchar(86) NOT NULL,
   col66 varchar(86) NOT NULL,
   col67 varchar(86) NOT NULL,
   col68 varchar(86) NOT NULL,
   col69 varchar(86) NOT NULL,
   col70 varchar(86) NOT NULL,
   col71 varchar(86) NOT NULL,
   col72 varchar(86) NOT NULL,
   col73 varchar(86) NOT NULL,
   col74 varchar(86) NOT NULL,
   col75 varchar(86) NOT NULL,
   col76 varchar(86) NOT NULL,
   col77 varchar(86) NOT NULL,
   col78 varchar(86) NOT NULL,
   col79 varchar(86) NOT NULL,
   col80 varchar(86) NOT NULL,
   col81 varchar(86) NOT NULL,
   col82 varchar(86) NOT NULL,
   col83 varchar(86) NOT NULL,
   col84 varchar(86) NOT NULL,
   col85 varchar(86) NOT NULL,
   col86 varchar(86) NOT NULL,
   col87 varchar(86) NOT NULL,
   col88 varchar(86) NOT NULL,
   col89 varchar(86) NOT NULL,
   col90 varchar(86) NOT NULL,
   col91 varchar(86) NOT NULL,
   col92 varchar(86) NOT NULL,
   col93 varchar(86) NOT NULL,
   col94 varchar(86) NOT NULL,
   col95 varchar(86) NOT NULL,
   col96 varchar(86) NOT NULL,
   col97 varchar(86) NOT NULL,
   col98 varchar(86) NOT NULL,
   col99 varchar(86) NOT NULL,
   col100 varchar(86) NOT NULL,
   col101 varchar(86) NOT NULL,
   col102 varchar(86) NOT NULL,
   col103 varchar(86) NOT NULL,
   col104 varchar(86) NOT NULL,
   col105 varchar(86) NOT NULL,
   col106 varchar(86) NOT NULL,
   col107 varchar(86) NOT NULL,
   col108 varchar(86) NOT NULL,
   col109 varchar(86) NOT NULL,
   col110 varchar(86) NOT NULL,
   col111 varchar(86) NOT NULL,
   col112 varchar(86) NOT NULL,
   col113 varchar(86) NOT NULL,
   col114 varchar(86) NOT NULL,
   col115 varchar(86) NOT NULL,
   col116 varchar(86) NOT NULL,
   col117 varchar(86) NOT NULL,
   col118 varchar(86) NOT NULL,
   col119 varchar(86) NOT NULL,
   col120 varchar(86) NOT NULL,
   col121 varchar(86) NOT NULL,
   col122 varchar(86) NOT NULL,
   col123 varchar(86) NOT NULL,
   col124 varchar(86) NOT NULL,
   col125 varchar(86) NOT NULL,
   col126 varchar(86) NOT NULL,
   col127 varchar(86) NOT NULL,
   col128 varchar(86) NOT NULL,
   col129 varchar(86) NOT NULL,
   col130 varchar(86) NOT NULL,
   col131 varchar(86) NOT NULL,
   col132 varchar(86) NOT NULL,
   col133 varchar(86) NOT NULL,
   col134 varchar(86) NOT NULL,
   col135 varchar(86) NOT NULL,
   col136 varchar(86) NOT NULL,
   col137 varchar(86) NOT NULL,
   col138 varchar(86) NOT NULL,
   col139 varchar(86) NOT NULL,
   col140 varchar(86) NOT NULL,
   col141 varchar(86) NOT NULL,
   col142 varchar(86) NOT NULL,
   col143 varchar(86) NOT NULL,
   col144 varchar(86) NOT NULL,
   col145 varchar(86) NOT NULL,
   col146 varchar(86) NOT NULL,
   col147 varchar(86) NOT NULL,
   col148 varchar(86) NOT NULL,
   col149 varchar(86) NOT NULL,
   col150 varchar(86) NOT NULL,
   col151 varchar(86) NOT NULL,
   col152 varchar(86) NOT NULL,
   col153 varchar(86) NOT NULL,
   col154 varchar(86) NOT NULL,
   col155 varchar(86) NOT NULL,
   col156 varchar(86) NOT NULL,
   col157 varchar(86) NOT NULL,
   col158 varchar(86) NOT NULL,
   col159 varchar(86) NOT NULL,
   col160 varchar(86) NOT NULL,
   col161 varchar(86) NOT NULL,
   col162 varchar(86) NOT NULL,
   col163 varchar(86) NOT NULL,
   col164 varchar(86) NOT NULL,
   col165 varchar(86) NOT NULL,
   col166 varchar(86) NOT NULL,
   col167 varchar(86) NOT NULL,
   col168 varchar(86) NOT NULL,
   col169 varchar(86) NOT NULL,
   col170 varchar(86) NOT NULL,
   col171 varchar(86) NOT NULL,
   col172 varchar(86) NOT NULL,
   col173 varchar(86) NOT NULL,
   col174 varchar(86) NOT NULL,
   col175 varchar(86) NOT NULL,
   col176 varchar(86) NOT NULL,
   col177 varchar(86) NOT NULL,
   col178 varchar(86) NOT NULL,
   col179 varchar(86) NOT NULL,
   col180 varchar(86) NOT NULL,
   col181 varchar(86) NOT NULL,
   col182 varchar(86) NOT NULL,
   col183 varchar(86) NOT NULL,
   col184 varchar(86) NOT NULL,
   col185 varchar(86) NOT NULL,
   col186 varchar(86) NOT NULL,
   col187 varchar(86) NOT NULL,
   col188 varchar(86) NOT NULL,
   col189 varchar(86) NOT NULL,
   col190 varchar(86) NOT NULL,
   col191 varchar(86) NOT NULL,
   col192 varchar(86) NOT NULL,
   col193 varchar(86) NOT NULL,
   col194 varchar(86) NOT NULL,
   col195 varchar(86) NOT NULL,
   col196 varchar(86) NOT NULL,
   col197 varchar(86) NOT NULL,
   col198 varchar(86) NOT NULL,
   PRIMARY KEY (col1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

```

And when using InnoDB's [DYNAMIC](../innodb-dynamic-row-format/index) row format and a default character set of [utf8mb4](../unicode/index) (which requires up to 4 bytes per character), the 256 byte limit means that a [VARCHAR](../varchar/index) column will only be stored on overflow pages if it is at least as large as a `varchar(64)`:

 
```
SET GLOBAL innodb_default_row_format='dynamic';
SET SESSION innodb_strict_mode=ON;
CREATE OR REPLACE TABLE tab (
   col1 varchar(64) NOT NULL,
   col2 varchar(64) NOT NULL,
   col3 varchar(64) NOT NULL,
   col4 varchar(64) NOT NULL,
   col5 varchar(64) NOT NULL,
   col6 varchar(64) NOT NULL,
   col7 varchar(64) NOT NULL,
   col8 varchar(64) NOT NULL,
   col9 varchar(64) NOT NULL,
   col10 varchar(64) NOT NULL,
   col11 varchar(64) NOT NULL,
   col12 varchar(64) NOT NULL,
   col13 varchar(64) NOT NULL,
   col14 varchar(64) NOT NULL,
   col15 varchar(64) NOT NULL,
   col16 varchar(64) NOT NULL,
   col17 varchar(64) NOT NULL,
   col18 varchar(64) NOT NULL,
   col19 varchar(64) NOT NULL,
   col20 varchar(64) NOT NULL,
   col21 varchar(64) NOT NULL,
   col22 varchar(64) NOT NULL,
   col23 varchar(64) NOT NULL,
   col24 varchar(64) NOT NULL,
   col25 varchar(64) NOT NULL,
   col26 varchar(64) NOT NULL,
   col27 varchar(64) NOT NULL,
   col28 varchar(64) NOT NULL,
   col29 varchar(64) NOT NULL,
   col30 varchar(64) NOT NULL,
   col31 varchar(64) NOT NULL,
   col32 varchar(64) NOT NULL,
   col33 varchar(64) NOT NULL,
   col34 varchar(64) NOT NULL,
   col35 varchar(64) NOT NULL,
   col36 varchar(64) NOT NULL,
   col37 varchar(64) NOT NULL,
   col38 varchar(64) NOT NULL,
   col39 varchar(64) NOT NULL,
   col40 varchar(64) NOT NULL,
   col41 varchar(64) NOT NULL,
   col42 varchar(64) NOT NULL,
   col43 varchar(64) NOT NULL,
   col44 varchar(64) NOT NULL,
   col45 varchar(64) NOT NULL,
   col46 varchar(64) NOT NULL,
   col47 varchar(64) NOT NULL,
   col48 varchar(64) NOT NULL,
   col49 varchar(64) NOT NULL,
   col50 varchar(64) NOT NULL,
   col51 varchar(64) NOT NULL,
   col52 varchar(64) NOT NULL,
   col53 varchar(64) NOT NULL,
   col54 varchar(64) NOT NULL,
   col55 varchar(64) NOT NULL,
   col56 varchar(64) NOT NULL,
   col57 varchar(64) NOT NULL,
   col58 varchar(64) NOT NULL,
   col59 varchar(64) NOT NULL,
   col60 varchar(64) NOT NULL,
   col61 varchar(64) NOT NULL,
   col62 varchar(64) NOT NULL,
   col63 varchar(64) NOT NULL,
   col64 varchar(64) NOT NULL,
   col65 varchar(64) NOT NULL,
   col66 varchar(64) NOT NULL,
   col67 varchar(64) NOT NULL,
   col68 varchar(64) NOT NULL,
   col69 varchar(64) NOT NULL,
   col70 varchar(64) NOT NULL,
   col71 varchar(64) NOT NULL,
   col72 varchar(64) NOT NULL,
   col73 varchar(64) NOT NULL,
   col74 varchar(64) NOT NULL,
   col75 varchar(64) NOT NULL,
   col76 varchar(64) NOT NULL,
   col77 varchar(64) NOT NULL,
   col78 varchar(64) NOT NULL,
   col79 varchar(64) NOT NULL,
   col80 varchar(64) NOT NULL,
   col81 varchar(64) NOT NULL,
   col82 varchar(64) NOT NULL,
   col83 varchar(64) NOT NULL,
   col84 varchar(64) NOT NULL,
   col85 varchar(64) NOT NULL,
   col86 varchar(64) NOT NULL,
   col87 varchar(64) NOT NULL,
   col88 varchar(64) NOT NULL,
   col89 varchar(64) NOT NULL,
   col90 varchar(64) NOT NULL,
   col91 varchar(64) NOT NULL,
   col92 varchar(64) NOT NULL,
   col93 varchar(64) NOT NULL,
   col94 varchar(64) NOT NULL,
   col95 varchar(64) NOT NULL,
   col96 varchar(64) NOT NULL,
   col97 varchar(64) NOT NULL,
   col98 varchar(64) NOT NULL,
   col99 varchar(64) NOT NULL,
   col100 varchar(64) NOT NULL,
   col101 varchar(64) NOT NULL,
   col102 varchar(64) NOT NULL,
   col103 varchar(64) NOT NULL,
   col104 varchar(64) NOT NULL,
   col105 varchar(64) NOT NULL,
   col106 varchar(64) NOT NULL,
   col107 varchar(64) NOT NULL,
   col108 varchar(64) NOT NULL,
   col109 varchar(64) NOT NULL,
   col110 varchar(64) NOT NULL,
   col111 varchar(64) NOT NULL,
   col112 varchar(64) NOT NULL,
   col113 varchar(64) NOT NULL,
   col114 varchar(64) NOT NULL,
   col115 varchar(64) NOT NULL,
   col116 varchar(64) NOT NULL,
   col117 varchar(64) NOT NULL,
   col118 varchar(64) NOT NULL,
   col119 varchar(64) NOT NULL,
   col120 varchar(64) NOT NULL,
   col121 varchar(64) NOT NULL,
   col122 varchar(64) NOT NULL,
   col123 varchar(64) NOT NULL,
   col124 varchar(64) NOT NULL,
   col125 varchar(64) NOT NULL,
   col126 varchar(64) NOT NULL,
   col127 varchar(64) NOT NULL,
   col128 varchar(64) NOT NULL,
   col129 varchar(64) NOT NULL,
   col130 varchar(64) NOT NULL,
   col131 varchar(64) NOT NULL,
   col132 varchar(64) NOT NULL,
   col133 varchar(64) NOT NULL,
   col134 varchar(64) NOT NULL,
   col135 varchar(64) NOT NULL,
   col136 varchar(64) NOT NULL,
   col137 varchar(64) NOT NULL,
   col138 varchar(64) NOT NULL,
   col139 varchar(64) NOT NULL,
   col140 varchar(64) NOT NULL,
   col141 varchar(64) NOT NULL,
   col142 varchar(64) NOT NULL,
   col143 varchar(64) NOT NULL,
   col144 varchar(64) NOT NULL,
   col145 varchar(64) NOT NULL,
   col146 varchar(64) NOT NULL,
   col147 varchar(64) NOT NULL,
   col148 varchar(64) NOT NULL,
   col149 varchar(64) NOT NULL,
   col150 varchar(64) NOT NULL,
   col151 varchar(64) NOT NULL,
   col152 varchar(64) NOT NULL,
   col153 varchar(64) NOT NULL,
   col154 varchar(64) NOT NULL,
   col155 varchar(64) NOT NULL,
   col156 varchar(64) NOT NULL,
   col157 varchar(64) NOT NULL,
   col158 varchar(64) NOT NULL,
   col159 varchar(64) NOT NULL,
   col160 varchar(64) NOT NULL,
   col161 varchar(64) NOT NULL,
   col162 varchar(64) NOT NULL,
   col163 varchar(64) NOT NULL,
   col164 varchar(64) NOT NULL,
   col165 varchar(64) NOT NULL,
   col166 varchar(64) NOT NULL,
   col167 varchar(64) NOT NULL,
   col168 varchar(64) NOT NULL,
   col169 varchar(64) NOT NULL,
   col170 varchar(64) NOT NULL,
   col171 varchar(64) NOT NULL,
   col172 varchar(64) NOT NULL,
   col173 varchar(64) NOT NULL,
   col174 varchar(64) NOT NULL,
   col175 varchar(64) NOT NULL,
   col176 varchar(64) NOT NULL,
   col177 varchar(64) NOT NULL,
   col178 varchar(64) NOT NULL,
   col179 varchar(64) NOT NULL,
   col180 varchar(64) NOT NULL,
   col181 varchar(64) NOT NULL,
   col182 varchar(64) NOT NULL,
   col183 varchar(64) NOT NULL,
   col184 varchar(64) NOT NULL,
   col185 varchar(64) NOT NULL,
   col186 varchar(64) NOT NULL,
   col187 varchar(64) NOT NULL,
   col188 varchar(64) NOT NULL,
   col189 varchar(64) NOT NULL,
   col190 varchar(64) NOT NULL,
   col191 varchar(64) NOT NULL,
   col192 varchar(64) NOT NULL,
   col193 varchar(64) NOT NULL,
   col194 varchar(64) NOT NULL,
   col195 varchar(64) NOT NULL,
   col196 varchar(64) NOT NULL,
   col197 varchar(64) NOT NULL,
   col198 varchar(64) NOT NULL,
   PRIMARY KEY (col1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

```

Working Around the Problem
--------------------------

 There are a few ways to work around this problem.

 If you would like a solution for the problem instead of just working around it, then see the solutions mentioned in the previous section.

 ### Refactoring the Table into Multiple Tables

 A *safe* workaround is to refactor the single wide table, so that its columns are spread among multiple tables.

 This workaround can even work if your table is so wide that the previous solutions have failed to solve them problem for your table.

 ### Refactoring Some Columns into JSON

 A *safe* workaround is to refactor some of the columns into a JSON document.

 The JSON document can be queried and manipulated using MariaDB's [JSON functions](../json-functions/index).

 The JSON document can be stored in a column that uses one of the following data types:

 * [TEXT](../text/index): The maximum size of a [TEXT](../text/index) column is 64 KB.
* [MEDIUMTEXT](../mediumtext/index): The maximum size of a [MEDIUMTEXT](../mediumtext/index) column is 16 MB.
* [LONGTEXT](../longtext/index): The maximum size of a [LONGTEXT](../longtext/index) column is 4 GB.
* [JSON](../json-data-type/index): This is just an alias for the [LONGTEXT](../longtext/index) data type.

 This workaround can even work if your table is so wide that the previous solutions have failed to solve them problem for your table.

 ### Disabling InnoDB Strict Mode

 An *unsafe* workaround is to disable [InnoDB strict mode](../innodb-strict-mode/index). [InnoDB strict mode](../innodb-strict-mode/index) can be disabled by setting the [innodb\_strict\_mode](../xtradbinnodb-server-system-variables/index#innodb_strict_mode) system variable to `OFF`.

 For example, even though the following table schema is too large for most InnoDB row formats to store, it can still be created when [InnoDB strict mode](../innodb-strict-mode/index) is disabled:

 
```
SET GLOBAL innodb_default_row_format='dynamic';
SET SESSION innodb_strict_mode=OFF;
CREATE OR REPLACE TABLE tab (
   col1 varchar(40) NOT NULL,
   col2 varchar(40) NOT NULL,
   col3 varchar(40) NOT NULL,
   col4 varchar(40) NOT NULL,
   col5 varchar(40) NOT NULL,
   col6 varchar(40) NOT NULL,
   col7 varchar(40) NOT NULL,
   col8 varchar(40) NOT NULL,
   col9 varchar(40) NOT NULL,
   col10 varchar(40) NOT NULL,
   col11 varchar(40) NOT NULL,
   col12 varchar(40) NOT NULL,
   col13 varchar(40) NOT NULL,
   col14 varchar(40) NOT NULL,
   col15 varchar(40) NOT NULL,
   col16 varchar(40) NOT NULL,
   col17 varchar(40) NOT NULL,
   col18 varchar(40) NOT NULL,
   col19 varchar(40) NOT NULL,
   col20 varchar(40) NOT NULL,
   col21 varchar(40) NOT NULL,
   col22 varchar(40) NOT NULL,
   col23 varchar(40) NOT NULL,
   col24 varchar(40) NOT NULL,
   col25 varchar(40) NOT NULL,
   col26 varchar(40) NOT NULL,
   col27 varchar(40) NOT NULL,
   col28 varchar(40) NOT NULL,
   col29 varchar(40) NOT NULL,
   col30 varchar(40) NOT NULL,
   col31 varchar(40) NOT NULL,
   col32 varchar(40) NOT NULL,
   col33 varchar(40) NOT NULL,
   col34 varchar(40) NOT NULL,
   col35 varchar(40) NOT NULL,
   col36 varchar(40) NOT NULL,
   col37 varchar(40) NOT NULL,
   col38 varchar(40) NOT NULL,
   col39 varchar(40) NOT NULL,
   col40 varchar(40) NOT NULL,
   col41 varchar(40) NOT NULL,
   col42 varchar(40) NOT NULL,
   col43 varchar(40) NOT NULL,
   col44 varchar(40) NOT NULL,
   col45 varchar(40) NOT NULL,
   col46 varchar(40) NOT NULL,
   col47 varchar(40) NOT NULL,
   col48 varchar(40) NOT NULL,
   col49 varchar(40) NOT NULL,
   col50 varchar(40) NOT NULL,
   col51 varchar(40) NOT NULL,
   col52 varchar(40) NOT NULL,
   col53 varchar(40) NOT NULL,
   col54 varchar(40) NOT NULL,
   col55 varchar(40) NOT NULL,
   col56 varchar(40) NOT NULL,
   col57 varchar(40) NOT NULL,
   col58 varchar(40) NOT NULL,
   col59 varchar(40) NOT NULL,
   col60 varchar(40) NOT NULL,
   col61 varchar(40) NOT NULL,
   col62 varchar(40) NOT NULL,
   col63 varchar(40) NOT NULL,
   col64 varchar(40) NOT NULL,
   col65 varchar(40) NOT NULL,
   col66 varchar(40) NOT NULL,
   col67 varchar(40) NOT NULL,
   col68 varchar(40) NOT NULL,
   col69 varchar(40) NOT NULL,
   col70 varchar(40) NOT NULL,
   col71 varchar(40) NOT NULL,
   col72 varchar(40) NOT NULL,
   col73 varchar(40) NOT NULL,
   col74 varchar(40) NOT NULL,
   col75 varchar(40) NOT NULL,
   col76 varchar(40) NOT NULL,
   col77 varchar(40) NOT NULL,
   col78 varchar(40) NOT NULL,
   col79 varchar(40) NOT NULL,
   col80 varchar(40) NOT NULL,
   col81 varchar(40) NOT NULL,
   col82 varchar(40) NOT NULL,
   col83 varchar(40) NOT NULL,
   col84 varchar(40) NOT NULL,
   col85 varchar(40) NOT NULL,
   col86 varchar(40) NOT NULL,
   col87 varchar(40) NOT NULL,
   col88 varchar(40) NOT NULL,
   col89 varchar(40) NOT NULL,
   col90 varchar(40) NOT NULL,
   col91 varchar(40) NOT NULL,
   col92 varchar(40) NOT NULL,
   col93 varchar(40) NOT NULL,
   col94 varchar(40) NOT NULL,
   col95 varchar(40) NOT NULL,
   col96 varchar(40) NOT NULL,
   col97 varchar(40) NOT NULL,
   col98 varchar(40) NOT NULL,
   col99 varchar(40) NOT NULL,
   col100 varchar(40) NOT NULL,
   col101 varchar(40) NOT NULL,
   col102 varchar(40) NOT NULL,
   col103 varchar(40) NOT NULL,
   col104 varchar(40) NOT NULL,
   col105 varchar(40) NOT NULL,
   col106 varchar(40) NOT NULL,
   col107 varchar(40) NOT NULL,
   col108 varchar(40) NOT NULL,
   col109 varchar(40) NOT NULL,
   col110 varchar(40) NOT NULL,
   col111 varchar(40) NOT NULL,
   col112 varchar(40) NOT NULL,
   col113 varchar(40) NOT NULL,
   col114 varchar(40) NOT NULL,
   col115 varchar(40) NOT NULL,
   col116 varchar(40) NOT NULL,
   col117 varchar(40) NOT NULL,
   col118 varchar(40) NOT NULL,
   col119 varchar(40) NOT NULL,
   col120 varchar(40) NOT NULL,
   col121 varchar(40) NOT NULL,
   col122 varchar(40) NOT NULL,
   col123 varchar(40) NOT NULL,
   col124 varchar(40) NOT NULL,
   col125 varchar(40) NOT NULL,
   col126 varchar(40) NOT NULL,
   col127 varchar(40) NOT NULL,
   col128 varchar(40) NOT NULL,
   col129 varchar(40) NOT NULL,
   col130 varchar(40) NOT NULL,
   col131 varchar(40) NOT NULL,
   col132 varchar(40) NOT NULL,
   col133 varchar(40) NOT NULL,
   col134 varchar(40) NOT NULL,
   col135 varchar(40) NOT NULL,
   col136 varchar(40) NOT NULL,
   col137 varchar(40) NOT NULL,
   col138 varchar(40) NOT NULL,
   col139 varchar(40) NOT NULL,
   col140 varchar(40) NOT NULL,
   col141 varchar(40) NOT NULL,
   col142 varchar(40) NOT NULL,
   col143 varchar(40) NOT NULL,
   col144 varchar(40) NOT NULL,
   col145 varchar(40) NOT NULL,
   col146 varchar(40) NOT NULL,
   col147 varchar(40) NOT NULL,
   col148 varchar(40) NOT NULL,
   col149 varchar(40) NOT NULL,
   col150 varchar(40) NOT NULL,
   col151 varchar(40) NOT NULL,
   col152 varchar(40) NOT NULL,
   col153 varchar(40) NOT NULL,
   col154 varchar(40) NOT NULL,
   col155 varchar(40) NOT NULL,
   col156 varchar(40) NOT NULL,
   col157 varchar(40) NOT NULL,
   col158 varchar(40) NOT NULL,
   col159 varchar(40) NOT NULL,
   col160 varchar(40) NOT NULL,
   col161 varchar(40) NOT NULL,
   col162 varchar(40) NOT NULL,
   col163 varchar(40) NOT NULL,
   col164 varchar(40) NOT NULL,
   col165 varchar(40) NOT NULL,
   col166 varchar(40) NOT NULL,
   col167 varchar(40) NOT NULL,
   col168 varchar(40) NOT NULL,
   col169 varchar(40) NOT NULL,
   col170 varchar(40) NOT NULL,
   col171 varchar(40) NOT NULL,
   col172 varchar(40) NOT NULL,
   col173 varchar(40) NOT NULL,
   col174 varchar(40) NOT NULL,
   col175 varchar(40) NOT NULL,
   col176 varchar(40) NOT NULL,
   col177 varchar(40) NOT NULL,
   col178 varchar(40) NOT NULL,
   col179 varchar(40) NOT NULL,
   col180 varchar(40) NOT NULL,
   col181 varchar(40) NOT NULL,
   col182 varchar(40) NOT NULL,
   col183 varchar(40) NOT NULL,
   col184 varchar(40) NOT NULL,
   col185 varchar(40) NOT NULL,
   col186 varchar(40) NOT NULL,
   col187 varchar(40) NOT NULL,
   col188 varchar(40) NOT NULL,
   col189 varchar(40) NOT NULL,
   col190 varchar(40) NOT NULL,
   col191 varchar(40) NOT NULL,
   col192 varchar(40) NOT NULL,
   col193 varchar(40) NOT NULL,
   col194 varchar(40) NOT NULL,
   col195 varchar(40) NOT NULL,
   col196 varchar(40) NOT NULL,
   col197 varchar(40) NOT NULL,
   col198 varchar(40) NOT NULL,
   PRIMARY KEY (col1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

```

But as mentioned above, if [InnoDB strict mode](../innodb-strict-mode/index) is **disabled** and if a [DDL](../data-definition/index) statement is executed, then InnoDB will still raise a **warning** with this message. The [SHOW WARNINGS](../show-warnings/index) statement can be used to view the warning. For example:

 
```
SHOW WARNINGS;
+---------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 139 | Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline. |
+---------+------+----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

```

As mentioned above, even though InnoDB is allowing the table to be created, there is still an opportunity for errors. Regardless of whether [InnoDB strict mode](../innodb-strict-mode/index) is enabled, if a [DML](../data-manipulation/index) statement is executed that attempts to write a row that the table's InnoDB row format can't store, then InnoDB will raise an **error** with this message. This creates a somewhat *unsafe* situation, because it means that the application has the chance to encounter an additional error while executing [DML](../data-manipulation/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/troubleshooting-row-size-too-large-errors-with-innodb/>

INSTALL SONAME
==============

    Syntax
------

 
```
INSTALL SONAME 'plugin_library'
```
 Description
-----------

 This statement is a variant of [INSTALL PLUGIN](../install-plugin/index). It installs **all** [plugins](../mariadb-plugins/index) from a given `plugin_library`. See [INSTALL PLUGIN](../install-plugin/index) for details.

 `plugin_library` is the name of the shared library that contains the plugin code. The file name extension (for example, `libmyplugin.so` or `libmyplugin.dll`) can be omitted (which makes the statement look the same on all architectures).

 The shared library must be located in the plugin directory (that is, the directory named by the `[plugin\_dir](../server-system-variables/index#plugin_dir)` system variable). The library must be in the plugin directory itself, not in a subdirectory. By default, `plugin_dir` is plugin directory under the directory named by the `pkglibdir` configuration variable, but it can be changed by setting the value of `plugin_dir` at server startup. For example, set its value in a `my.cnf` file:

 
```
[mysqld]
plugin_dir=/path/to/plugin/directory
```

If the value of [plugin\_dir](../server-system-variables/index#plugin_dir) is a relative path name, it is taken to be relative to the MySQL base directory (the value of the `basedir` system variable).

 `INSTALL SONAME` adds one or more lines to the `mysql.plugin` table that describes the plugin. This table contains the plugin name and library file name.

 `INSTALL SONAME` causes the server to read option (`my.cnf`) files just as during server startup. This enables the plugin to pick up any relevant options from those files. It is possible to add plugin options to an option file even before loading a plugin (if the loose prefix is used). It is also possible to uninstall a plugin, edit `my.cnf`, and install the plugin again. Restarting the plugin this way enables it to the new option values without a server restart.

 `INSTALL SONAME` also loads and initializes the plugin code to make the plugin available for use. A plugin is initialized by executing its initialization function, which handles any setup that the plugin must perform before it can be used.

 To use `INSTALL SONAME`, you must have the [INSERT privilege](../grant/index) for the `mysql.plugin` table.

 At server startup, the server loads and initializes any plugin that is listed in the `mysql.plugin` table. This means that a plugin is installed with `INSTALL SONAME` only once, not every time the server starts. Plugin loading at startup does not occur if the server is started with the `--skip-grant-tables` option.

 When the server shuts down, it executes the de-initialization function for each plugin that is loaded so that the plugin has a chance to perform any final cleanup.

 If you need to load plugins for a single server startup when the `--skip-grant-tables` option is given (which tells the server not to read system tables), use the `--plugin-load` [mysqld option](../mysqld-options-full-list/index).

 If you need to install only one plugin from a library, use the [INSTALL PLUGIN](../install-plugin/index) statement.

 Examples
--------

 To load the XtraDB storage engine and all of its `information_schema` tables with one statement, use

 
```
INSTALL SONAME 'ha_xtradb';

```

This statement can be used instead of `INSTALL PLUGIN` even when the library contains only one plugin:

 
```
INSTALL SONAME 'ha_sequence';

```

See Also
--------

 * [List of Plugins](../list-of-plugins/index)
* [Plugin Overview](../plugin-overview/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [mysql\_plugin](../mysql_plugin/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/install-soname/>

UNINSTALL SONAME
================

    Syntax
------

 
```
UNINSTALL SONAME  [IF EXISTS] 'plugin_library'
```
 Description
-----------

 This statement is a variant of [UNINSTALL PLUGIN](../uninstall-plugin/index) statement, that removes all [plugins](../mariadb-plugins/index) belonging to a specified `plugin_library`. See [UNINSTALL PLUGIN](../uninstall-plugin/index) for details.

 `plugin_library` is the name of the shared library that contains the plugin code. The file name extension (for example, `libmyplugin.so` or `libmyplugin.dll`) can be omitted (which makes the statement look the same on all architectures).

 To use `UNINSTALL SONAME`, you must have the [DELETE privilege](../grant/index) for the `mysql.plugin` table.

 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**#### IF EXISTS

 If the `IF EXISTS` clause is used, MariaDB will return a note instead of an error if the plugin library does not exist. See [SHOW WARNINGS](../show-warnings/index).

 
Examples
--------

 To uninstall the XtraDB plugin and all of its `information_schema` tables with one statement, use

 
```
UNINSTALL SONAME 'ha_xtradb';

```

From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/):

 
```
UNINSTALL SONAME IF EXISTS 'ha_example';
Query OK, 0 rows affected (0.099 sec)

UNINSTALL SONAME IF EXISTS 'ha_example';
Query OK, 0 rows affected, 1 warning (0.000 sec)

SHOW WARNINGS;
+-------+------+-------------------------------------+
| Level | Code | Message                             |
+-------+------+-------------------------------------+
| Note  | 1305 | SONAME ha_example.so does not exist |
+-------+------+-------------------------------------+

```

See Also
--------

 * [INSTALL SONAME](../install-soname/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [mysql\_plugin](../mysql_plugin/index)
* [List of Plugins](../list-of-plugins/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uninstall-soname/>

mysqlbinlog
===========

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-binlog](../mariadb-binlog/index) is a symlink to `mysqlbinlog`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-binlog](../mariadb-binlog/index) is the name of the tool, with `mysqlbinlog` a symlink .

 
See [mariadb-binlog](../mariadb-binlog/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-binlog-mysqlbinlog/>

Binary Log Group Commit and InnoDB Flushing Performance
=======================================================

    [MariaDB 10.0](../what-is-mariadb-100/index) introduced a performance improvement related to [group commit](../group-commit-for-the-binary-log/index) that affects the performance of flushing [InnoDB](../xtradb-and-innodb/index) transactions when the [binary log](../binary-log/index) is enabled.

 Overview
--------

 In [MariaDB 10.0](../what-is-mariadb-100/index) and above, when both [innodb\_flush\_log\_at\_trx\_commit=1](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) (the default) is set and the [binary log](../binary-log/index) is enabled, there is now one less sync to disk inside InnoDB during commit (2 syncs shared between a group of transactions instead of 3).

 Durability of commits is not decreased — this is because even if the server crashes before the commit is written to disk by InnoDB, it will be recovered from the binary log at next server startup (and it is guaranteed that sufficient information is synced to disk so that such a recovery is always possible).

 Switching to Old Flushing Behavior
----------------------------------

 The old behavior, with 3 syncs to disk per (group) commit (and consequently lower performance), can be selected with the new [innodb\_flush\_log\_at\_trx\_commit=3](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) option. There is normally no benefit to doing this, however there are a couple of edge cases to be aware of.

 ### Non-durable Binary Log Settings

 If [innodb\_flush\_log\_at\_trx\_commit=1](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) is set and the [binary log](../binary-log/index) is enabled, but [sync\_binlog=0](../replication-and-binary-log-server-system-variables/index#sync_binlog) is set, then commits are not guaranteed durable inside InnoDB after commit. This is because if [sync\_binlog=0](../replication-and-binary-log-server-system-variables/index#sync_binlog) is set and if the server crashes, then transactions that were not flushed to the binary log prior to the crash will be missing from the binary log.

 In this specific scenario, [innodb\_flush\_log\_at\_trx\_commit=3](../innodb-system-variables/index#innodb_flush_log_at_trx_commit) can be set to ensure that transactions will be durable in InnoDB, even if they are not necessarily durable from the perspective of the binary log.

 One should be aware that if [sync\_binlog=0](../replication-and-binary-log-server-system-variables/index#sync_binlog) is set, then a crash is nevertheless likely to cause transactions to be missing from the binary log. This will cause the binary log and InnoDB to be inconsistent with each other. This is also likely to cause any [replication slaves](../high-availability-performance-tuning-mariadb-replication/index) to become inconsistent, since transactions are replicated through the [binary log](../binary-log/index). Thus it is recommended to set [sync\_binlog=1](../replication-and-binary-log-server-system-variables/index#sync_binlog). With the [group commit](../group-commit-for-the-binary-log/index) improvements introduced in [MariaDB 5.3](../what-is-mariadb-53/index), this setting has much less penalty in recent versions compared to older versions of MariaDB and MySQL.

 ### Recent Transactions Missing from Backups

 [Mariabackup](../mariabackup/index) and [Percona XtraBackup](../backup-restore-and-import-xtrabackup/index) only see transactions that have been flushed to the [redo log](../xtradbinnodb-redo-log/index). With the [group commit](../group-commit-for-the-binary-log/index) improvements, there may be a small delay (defined by the [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec) system variable) between when a commit happens and when the commit will be included in a backup.

 Note that the backup will still be fully consistent with itself and the [binary log](../binary-log/index). This problem is normally not an issue in practice. A backup usually takes a long time to complete (relative to the 1 second or so that [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec) is normally set to), and a backup usually includes a lot of transactions that were committed during the backup. With this in mind, it is not generally noticeable if the backup does not include transactions that were committed during the last 1 second or so of the backup process. It is just mentioned here for completeness.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-log-group-commit-and-innodb-flushing-performance/>

Secure Connections Overview
===========================

    By default, MariaDB transmits data between the server and clients without encrypting it. This is generally acceptable when the server and client run on the same host or in networks where security is guaranteed through other means. However, in cases where the server and client exist on separate networks or they are in a high-risk network, the lack of encryption does introduce security concerns as a malicious actor could potentially eavesdrop on the traffic as it is sent over the network between them.

 To mitigate this concern, MariaDB allows you to encrypt data in transit between the server and clients using the Transport Layer Security (TLS) protocol. TLS was formerly known as Secure Socket Layer (SSL), but strictly speaking the SSL protocol is a predecessor to TLS and, that version of the protocol is now considered insecure. The documentation still uses the term SSL often and for compatibility reasons TLS-related server system and status variables still use the prefix `ssl_`, but internally, MariaDB only supports its secure successors.

 Checking MariaDB Server for TLS Support
---------------------------------------

 In order for MariaDB Server to use TLS, it needs to be compiled with TLS support. All MariaDB packages distributed by MariaDB Foundation and MariaDB Corporation are compiled with TLS support.

 If you aren't sure whether your MariaDB Server binary was compiled with TLS support, then you can check the value of the `[have\_ssl](../ssl-system-variables/index#have_ssl)` system variable. For example:

 
```
SHOW GLOBAL VARIABLES LIKE 'have_ssl';
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_ssl      | DISABLED |
+---------------+----------+

```

The possible values are:

 * If it is `DISABLED`, then the server was compiled with TLS support, but TLS is not enabled.
* If it is `YES`, then the server was compiled with TLS support, and TLS is enabled.
* If it is `NO`, then the server was not compiled with TLS support.

 TLS Libraries
-------------

 When MariaDB is compiled with TLS and cryptography support, it is usually either statically linked with MariaDB's bundled TLS and cryptography library, which might be [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), or dynamically linked with the system's TLS and cryptography library, which might be [OpenSSL](https://www.openssl.org/), [GnuTLS](https://www.gnutls.org/), or [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel).

 See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 TLS Protocol Versions
---------------------

 There are 4 versions of the TLS protocol:

 * `TLSv1.0`
* `TLSv1.1`
* `TLSv1.2`
* `TLSv1.3`

 ### Enabling Specific TLS Protocol Versions

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**The `[tls\_version](../ssltls-system-variables/index#tls_version)` system variable was first introduced in [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/).

 
In some cases, it might make sense to only enable specific TLS protocol versions. For example, it would make sense if your organization has to comply with a specific security standard. It would also make sense if a vulnerability is found in a specific TLS protocol version, and you would like to ensure that your server does not use the vulnerable protocol version.

 
The [PCI DSS v3.2](https://blog.pcisecuritystandards.org/resource-guide-migrating-from-ssl-and-early-tls) recommends using a minimum protocol version of TLSv1.2.

 
On the **server** side, users can enable specific TLS protocol versions by setting the `[tls\_version](../ssltls-system-variables/index#tls_version)` system variable. This system variable accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. This system variable can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
tls_version = TLSv1.2,TLSv1.3

```

You can check which TLS protocol versions are enabled on a server by executing `[SHOW GLOBAL VARIABLES](../show-variables/index)`. For example:

 
```
SHOW GLOBAL VARIABLES LIKE 'tls_version';

```

On the **client** side, users can enable specific TLS protocol versions by setting the `--tls-version` option. This option accepts a comma-separated list of TLS protocol versions. A TLS protocol version will only be enabled if it is present in this list. All other TLS protocol versions will not be permitted. For example, to specify this option in a relevant client [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), you could set the following:

 
```
[client-mariadb]
...
tls_version = TLSv1.2,TLSv1.3

```

Or if you wanted to specify it on the command-line with the [mariadb](../mariadb-command-line-client/index) client, then you could execute something like this:

 
```
$ mariadb -u myuser -p -h myserver.mydomain.com \
   --ssl \
   --tls-version="TLSv1.2,TLSv1.3"

```

### TLS Protocol Version Support

 The TLS protocol versions that are supported depend on the underlying TLS library used by the specific MariaDB binary.

 


| TLS Library | Supported TLS Protocol Versions |
| --- | --- |
| openSSL | TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 |
| wolfSSL | TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 |
| yaSSL | TLSv1, TLSv1.1 |
| Schannel | TLSv1, TLSv1.1, TLSv1.2 |
| GnuTLS | TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 |

 
See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used by the server and by clients on each platform.

 #### TLS Protocol Version Support in OpenSSL

 MariaDB binaries built with the [OpenSSL](https://www.openssl.org/) library ([OpenSSL 1.0.1](https://www.openssl.org/news/changelog.html) or later) support TLSv1.1 and TLSv1.2 since [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/), and [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/).

 MariaDB binaries built with the [OpenSSL](https://www.openssl.org/) library ([OpenSSL 1.1.1](https://www.openssl.org/news/changelog.html) or later) support TLSv1.3 since [MariaDB 10.2.16](https://mariadb.com/kb/en/mariadb-10216-release-notes/) and [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/).

 If your MariaDB Server binary is built with [OpenSSL](https://www.openssl.org/), then you can set the `[ssl\_cipher](../ssl-system-variables/index#ssl_cipher)` system variable to values like `SSLv3` or `TLSv1.2` to allow all SSLv3.0 or all TLSv1.2 ciphers. However, this does not necessarily limit the protocol version to TLSv1.2. See [MDEV-14101](https://jira.mariadb.org/browse/MDEV-14101) for more information about that.

 Note that the `TLSv1.3` ciphers cannot be excluded when using [OpenSSL](https://www.openssl.org/), even by using the `[ssl\_cipher](../ssl-system-variables/index#ssl_cipher)` system variable. See [Using TLSv1.3](../using-tlsv13/index) for details.

 
SSLv3.0 is known to be vulnerable to the [POODLE attack](https://en.wikipedia.org/wiki/POODLE), so it should not be used. SSLv2.0 and SSLv3.0 are disabled for MariaDB Server binaries linked with [OpenSSL](https://www.openssl.org/) since [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/), and [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/). If you are using a MariaDB version older than that and you cannot upgrade, then please see the section titled "SSL 3.0 Fallback protection" in [OpenSSL Security Advisory - 15 Oct 2014](https://www.openssl.org/news/secadv/20141015.txt).

 
#### TLS Protocol Version Support in wolfSSL

 MariaDB binaries built with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library support TLSv1.0, TLSv1.1, TLSv1.2, and TLSv1.3.

 #### TLS Protocol Version Support in yaSSL

 MariaDB binaries built with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library support SSLv3.0, TLSv1.0, and TLSv1.1.

 
SSLv3.0 is known to be vulnerable to the [POODLE attack](https://en.wikipedia.org/wiki/POODLE), so it should not be used. SSLv2.0 and SSLv3.0 are disabled for MariaDB Server binaries linked with [yaSSL](https://www.wolfssl.com/products/yassl/) since [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/), [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/), and [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/).

 
#### TLS Protocol Version Support in Schannel

 MariaDB binaries built with the [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel) library support different versions of TLS on different versions of Windows. See the [Protocols in TLS/SSL (Schannel SSP)](https://docs.microsoft.com/en-us/windows/desktop/secauthn/protocols-in-tls-ssl--schannel-ssp-) documentation from Microsoft to determine which versions of TLS are supported on each version of Windows.

 #### TLS Protocol Version Support in GnuTLS

 MariaDB binaries built with the [GnuTLS](https://www.gnutls.org/) library support TLSv1.0, TLSv1.1, TLSv1.2, and TLSv1.3.

 Enabling TLS
------------

 See [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index) for information on how to enable TLS on the client and server.

 Certificate Verification
------------------------

 Certificate verification is how TLS authenticates its connections by verifying that it is talking to who it says it is. There are multiple components to this verification process:

 * Was the certificate signed by a trusted Certificate Authority (CA)?
* Is the certificate expired?
* Is the certificate on my Certificate Revocation List (CRL)?
* Does the certificate belong to who I believe that I'm communicating with?

 ### Certificate Authorities (CAs)

 Certificate Authorities (CAs) are entities that you trust to sign TLS certificates. Your organization might have its own internal CA, or it might use trusted third-party CAs.

 CAs are specified on the server and client by using the `[ssl\_ca](../ssltls-system-variables/index#ssl_ca)` and `[ssl\_capath](../ssltls-system-variables/index#ssl_capath)` options.

 The `[ssl\_ca](../ssltls-system-variables/index#ssl_ca)` option defines a path to a PEM file that should contain one or more X509 certificates for trusted Certificate Authorities (CAs). This option requires that you use the absolute path, not a relative path.

 The `[ssl\_capath](../ssltls-system-variables/index#ssl_capath)` option defines a path to a directory that contains one or more PEM files that should each contain one X509 certificate for a trusted Certificate Authority (CA). This option requires that you use the absolute path, not a relative path. The `[ssl\_capath](../ssltls-system-variables/index#ssl_capath)` option is only supported if the server or client was built with [OpenSSL](https://www.openssl.org/), [wolfSSL](https://www.wolfssl.com/products/wolfssl/), or [yaSSL](https://www.wolfssl.com/products/yassl/). If the client was built with [GnuTLS](https://www.gnutls.org/) or [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel), then the `[ssl\_capath](../ssltls-system-variables/index#ssl_capath)` option is not supported.

 See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 The directory specified by `[ssl\_capath](../ssltls-system-variables/index#ssl_capath)` needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. For example, if the following is configured:

 
```
ssl_capath=/etc/my.cnf.d/certificates/ca/

```

Then you would have to execute the following:

 
```
openssl rehash /etc/my.cnf.d/certificates/ca/

```

#### Requiring a Specific Certificate Authority (CA)

 The server can require a specific Certificate Authority (CA) for a client if the client's user account has been defined with `REQUIRE ISSUER`. See [Securing Connections for Client and Server: Requiring TLS](../securing-connections-for-client-and-server/index#requiring-tls) for more information.

 ### Certificate Revocation Lists (CRLs)

 Certificate Revocation Lists (CRLs) are lists of certificates that have been revoked by the Certificate Authority (CA) before they were due to expire.

 CRLs are specified on the server and client by using the `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` and `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` options.

 The `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` option defines a path to a PEM file that should contain one or more X509 revoked certificates. This option requires that you use the absolute path, not a relative path. For servers, the `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` option is only valid if the server was built with OpenSSL. If the server was built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then the `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` option is not supported. For clients, the `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` option is only valid if the client was built with [OpenSSL](https://www.openssl.org/) or [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel). Likewise, if the client was built with [GnuTLS](https://www.gnutls.org/), [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then the `[ssl\_crl](../ssltls-system-variables/index#ssl_crl)` option is not supported.

 The `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` option defines a path to a directory that contains one or more PEM files that should each contain one revoked X509 certificate. This option requires that you use the absolute path, not a relative path. The `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` option is only supported if the server or client was built with [OpenSSL](https://www.openssl.org/). If the server was built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then the `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` option is not supported. Likewise, if the client was built with [GnuTLS](https://www.gnutls.org/), [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel), [wolfSSL](https://www.wolfssl.com/products/wolfssl/), or [yaSSL](https://www.wolfssl.com/products/yassl/), then the `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` option is not supported.

 See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 The directory specified by `[ssl\_crlpath](../ssltls-system-variables/index#ssl_crlpath)` needs to be run through the `[openssl rehash](https://www.openssl.org/docs/man1.1.1/man1/rehash.html)` command. For example, if the following is configured:

 
```
ssl_crlpath=/etc/my.cnf.d/certificates/crl/

```

Then you would have to execute the following:

 
```
openssl rehash /etc/my.cnf.d/certificates/crl/

```

### Server Certificate Verification

 [Clients and utilities](../clients-utilities/index) verify a server certificate by checking the server's host name and IP address against certain attributes in the certificate. For most [clients and utilities](../clients-utilities/index), server certificate verification is disabled by default, and it is only enabled if an option, such as `ssl-verify-server-cert` is specified.

 To verify the server's certificate, [clients and utilities](../clients-utilities/index) will check the **Common Name (CN)** attribute located in the **[Subject](https://tools.ietf.org/html/rfc5280#section-4.1.2.6)** field of the certificate against the server's host name and IP address. If the **Common Name (CN)** matches either of those, then the certificate is verified.

 #### Server Certificate Verification with Subject Alternative Names (SANs)

 The **[Subject Alternative Name (SAN)](https://tools.ietf.org/html/rfc5280#section-4.2.1.6)** field, which is an X.509v3 extension, can also be used for server certificate verification, if it is present in the server certificate. This field is also sometimes called **subjectAltName**. When using a [client or utility](../clients-utilities/index) that supports server certificate verification with **subjectAltName** fields, if the server certificate contains any **subjectAltName** fields, then those fields will also be checked against the server's host name and IP address.

 Whether server certificate verification with **subjectAltName** fields is supported depends on the underlying TLS library used by the [client or utility](../clients-utilities/index).

 See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.

 ##### SAN Support with OpenSSL, wolfSSL, and yaSSL

 For [clients and utilities](../clients-utilities/index) built with [OpenSSL](https://www.openssl.org/) ([OpenSSL 1.0.2](https://www.openssl.org/news/changelog.html) or later), support for server certificate verification with **subjectAltName** fields that contain the server's **host name** was added in [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/) and [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/). See [MDEV-10594](https://jira.mariadb.org/browse/MDEV-10594) for more information.

 For [clients and utilities](../clients-utilities/index) built with [OpenSSL](https://www.openssl.org/) ([OpenSSL 1.0.2](https://www.openssl.org/news/changelog.html) or later), support for server certificate verification with **subjectAltName** fields that contain the server's **IP address** was added in [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/). See [MDEV-18131](https://jira.mariadb.org/browse/MDEV-18131) for more information.

 This support also applies to other TLS libraries that use OpenSSL's API. In OpenSSL's API, server certificate verification with **subjectAltName** fields depends on the `[X509\_check\_host](https://www.openssl.org/docs/man1.1.1/man3/X509_check_host.html)` and `[X509\_check\_ip](https://www.openssl.org/docs/man1.1.1/man3/X509_check_host.html)` functions. These functions are supported in the following TLS libraries:

 * [OpenSSL](https://www.openssl.org/) 1.0.2 or later
* [wolfSSL](https://www.wolfssl.com/products/wolfssl/)

 And they are **not** supported in the following TLS libraries:

 * [yaSSL](https://www.wolfssl.com/products/yassl/)

 
MariaDB's [RPM packages](../rpm/index) were built with [OpenSSL](https://www.openssl.org/) 1.0.1 on RHEL 7 and CentOS 7, even after OpenSSL 1.0.2 became available on those distributions. As a side effect, the [clients and utilities](../clients-utilities/index) bundled in these packages did not support server certificate verification with the **subjectAltName** field, even if the packages were installed on a system that had OpenSSL 1.0.2 installed. Starting with MariaDB [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/), MariaDB's [RPM packages](../rpm/index) on RHEL 7 and CentOS 7 are built with OpenSSL 1.0.2. See [MDEV-18277](https://jira.mariadb.org/browse/MDEV-18277) for more information.

 
##### SAN Support with Schannel

 For [clients and utilities](../clients-utilities/index) linked with [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel), support for server certificate verification with **subjectAltName** fields was added in [MariaDB Connector/C](../mariadb-connector-c/index) 3.0.2. See [CONC-250](https://jira.mariadb.org/browse/CONC-250) for more information.

 ##### SAN Support with GnuTLS

 For [clients and utilities](../clients-utilities/index) linked with GnuTLS, support for server certificate verification with **subjectAltName** fields was added in [MariaDB Connector/C](../mariadb-connector-c/index) 3.0.0. See [CONC-250](https://jira.mariadb.org/browse/CONC-250) for more information.

 ### Client Certificate Verification

 The server verifies a client certificate by checking the client's known `SUBJECT` against the **Subject** attribute in the client's certificate. This is only done for user accounts that have been defined with `REQUIRE SUBJECT`. See [Securing Connections for Client and Server: Requiring TLS](../securing-connections-for-client-and-server/index#requiring-tls) for more information.

 See Also
--------

 * [Securing Connections for Client and Server](../securing-connections-for-client-and-server/index)
* [Using TLSv1.3](../using-tlsv13/index)
* [Certificate Creation with OpenSSL](../certificate-creation-with-openssl/index)
* [Replication with Secure Connections](../replication-with-secure-connections/index)
* [Securing Communications in Galera Cluster](../securing-communications-in-galera-cluster/index)
* [SSL/TLS System Variables](../ssltls-system-variables/index)
* [Data-at-Rest Encryption](../data-at-rest-encryption/index)
* [Cyberciti tutorial: How to setup MariaDB SSL and secure connections from clients](https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/secure-connections-overview/>

Certificate Creation with OpenSSL
=================================

    
**Warning**: the instructions below generate version 1 certificates only. These work fine with servers and clients using OpenSSL, but fail if WolfSSL is used instead, as is the case for our Windows MSI packages and our binary tarballs for Linux.

 WolfSSL requires version 3 certificates instead when using TLS v1.2 or higher, and so won't work with certificates generated as shown here when using two-way TLS with explicit client certificates.

 Generating version 3 certificates requires a few more minor steps, we will upgrade the instructions below soon to include these.

 See also: [MDEV-25701](https://jira.mariadb.org/browse/MDEV-25701) 

 
In order to secure communications with the MariaDB Server using TLS, you need to create a private key and an X509 certificate for the server. You may also want to create additional private keys and X509 certificates for any clients that need to connect to the server with TLS. This guide covers how to create a private key and a self-signed X509 certificate with OpenSSL. 

 Certificate Creation
--------------------

 The [OpenSSL](https://www.openssl.org/) library provides a command-line tool called `[openssl](https://www.openssl.org/docs/man1.1.1/man1/openssl.html)`, which can be used for performing various tasks with the library, such as generating private keys, creating X509 certificate requests, signing X509 certificates as a Certificate Authority (CA), and verifying X509 certificates.

 ### Creating a Certificate Authority Private Key and Certificate

 The Certificate Authority (CA) is typically an organization (such as [Let's Encrypt](https://letsencrypt.org/)) that signs the X509 certificate and validates ownership of the domain. However, when you would like to use self-signed certificates, you need to create the private key and certificate for the CA yourself, and then you can use them to sign your own X509 certificates.

 To start, generate a private key for the CA using the `[openssl genrsa](https://www.openssl.org/docs/man1.1.1/man1/genrsa.html)` command. For example:

 
```
# openssl genrsa 2048 > ca-key.pem

```

After that, you can use the private key to generate the X509 certificate for the CA using the `[openssl req](https://www.openssl.org/docs/man1.1.1/man1/req.html)` command. For example:

 
```
# openssl req -new -x509 -nodes -days 365000 \
      -key ca-key.pem -out ca.pem

```

The above commands create two files in the working directory: The `ca-key.pem` private key and the `ca.pem` X509 certificate are both are used by the CA to create self-signed X509 certificates below.

 ### Creating a Private Key and a Self-signed Certificate

 Once you have the CA's private key and X509 certificate, you can create the self-signed X509 certificates to use for the MariaDB Server, client, replication and other purposes.

 To start, generate a private key and create a certificate request using the `[openssl req](https://www.openssl.org/docs/man1.1.1/man1/req.html)` command. For example:

 
```
# openssl req -newkey rsa:2048 -days 365000 \
      -nodes -keyout server-key.pem -out server-req.pem

```

After that, process the key to remove the passphrase using the `[openssl rsa](https://www.openssl.org/docs/man1.1.1/man1/rsa.html)` command. For example:

 
```
# openssl rsa -in server-key.pem -out server-key.pem

```

Lastly, using the certificate request and the CA's private key and X509 certificate, you can generate a self-signed X509 certificate from the certificate request using the `[openssl x509](https://www.openssl.org/docs/man1.1.1/man1/x509.html)` command. For example:

 
```
# openssl x509 -req -in server-req.pem -days 365000 \
      -CA ca.pem -CAkey ca-key.pem -set_serial 01 \
      -out server-cert.pem

```

This creates a `server-cert.pem` file, which is the self-signed X509 certificate.

 Certificate Verification
------------------------

 Once you have created the CA's X509 certificate and a self-signed X509 certificate, you can verify that the X509 certificate was correctly generated using the `[openssl verify](https://www.openssl.org/docs/man1.1.1/man1/openssl-verify.html)` command. For example:

 
```
# openssl verify -CAfile ca.pem server-cert.pem
server-cert.pem: OK

```

You can add as many X509 certificates to check against the CA's X509 certificate as you want to verify. A value of `OK` indicates that you can use it was correctly generated and is ready for use with MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/certificate-creation-with-openssl/>

Using TLSv1.3
=============

    OpenSSL 1.1.1 introduced support for TLSv1.3. TLSv1.3 is a major rewrite of the TLS protocol. Some even argued it should've been called TLSv2.0. One of the changes is that it introduces a new set of cipher suites that only work with TLSv1.3. Additionally, TLSv1.3 does not support cipher suites from previous TLS protocol versions.

 This incompatible change had a non-obvious consequence. If a user had been explicitly specifying cipher suites to disable old and obsolete TLS protocol version, then that user may have also inadvertently prevented TLSv1.3 from working, unless the user remembered to add the TLSv1.3 cipher suites to their cipher list. After upgrading to OpenSSL 1.1.1, this user might believe they are using TLSv1.3, when their existing cipher suite configuration might be preventing it.

 To avoid this problem, OpenSSL developers decided that TLSv1.3 cipher suites should not be affected by the normal cipher-selecting API. This means that `[ssl\_cipher](../ssltls-system-variables/index#ssl_cipher)` system variable has no effect on the TLSv1.3 cipher suites.

 See this [OpenSSL blog post](https://www.openssl.org/blog/blog/2018/02/08/tlsv1.3/) and [GitHub issue](https://github.com/openssl/openssl/issues/5359) for more information.

 ### See Also

 * [Secure Connections Overview](../secure-connections-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-tlsv13/>

XtraDB option --innodb-release-locks-early
==========================================

    The --innodb-release-locks-early feature ([MWL#163](http://askmonty.org/worklog/?tid=163)) was included in the [5.2 replication preview](../mariadb-52-replication-feature-preview/index). However, it was omitted from [MariaDB 5.3](../what-is-mariadb-53/index) due to the bug [lp:798213](https://bugs.launchpad.net/maria/+bug/798213).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xtradb-option-innodb-release-locks-early/>

Authentication Plugin - Unix Socket
===================================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, the `unix_socket` authentication plugin is installed by default, and it is used by the `'root'@'localhost'` user account by default. See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for more information.

 
The `unix_socket` authentication plugin allows the user to use operating system credentials when connecting to MariaDB via the local Unix socket file. This Unix socket file is defined by the [socket](../server-system-variables/index#socket) system variable.

 The `unix_socket` authentication plugin works by calling the [getsockopt](http://man7.org/linux/man-pages/man7/socket.7.html) system call with the `SO_PEERCRED` socket option, which allows it to retrieve the `uid` of the process that is connected to the socket. It is then able to get the user name associated with that `uid`. Once it has the user name, it will authenticate the connecting user as the MariaDB account that has the same user name.

 The `unix_socket` authentication plugin is not suited to multiple Unix users accessing a single MariaDB user account.

 Security
--------

 A `unix_socket` authentication plugin is a passwordless security mechanism. Its security is in the strength of the access to the Unix user rather than the complexity and the secrecy of the password. As the security is different from passwords, the strengths and weaknesses need to be considered, and these aren't the same in every installation.

 ### Strengths

 * Access is limited to the Unix user so, for example, a `www-data` user cannot access `root` with the `unix_socket` authentication plugin.
* There is no password to brute force.
* There is no password that can be accidentally exposed by user accident, poor security on backups, or poor security on passwords in configuration files.
* Default Unix user security is usually strong on preventing remote access and password brute force attempts.

 ### Weaknesses

 The strength of a `unix_socket` authentication plugin is effectively the strength of the security of the Unix users on the system. The Unix user default installation in most cases is sufficiently secure, however, business requirements or unskilled management may expose risks. The following is a non-exhaustive list of potential Unix user security issues that may arise.

 * Common access areas without screen locks, where an unauthorized user accesses the logged in Unix user of an authorized user.
* Extensive sudo access grants that provide users with access to execute commands of a different Unix user.
* Scripts writable by Unix users other than the Unix user that are executed (cron or directly) by the unix user.
* Web pages that are susceptible to command injection, where the Unix user running the web page has elevated privileges in the database that weren't intended to be used.
* Poor Unix user password practices including weak user passwords, password exposure and password reuse accompanied by an access vulnerability/mechanism of an unauthorized user to exploit this weakness.
* Weak remote access mechanisms and network file system privileges.
* Poor user security behavior including running untrusted scripts and software.

 In some of these scenarios a database password may prevent these security exploits, however it will remove all the strengths of the `unix_socket` authentication plugin previously mentioned.

 Disabling the Plugin
--------------------

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, the `unix_socket` authentication plugin is installed by default, so **if you do not want it to be available by default on those versions, then you will need to disable it**.

 

The `unix_socket` authentication plugin is also installed by default in **new installations** that use the `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's default repositories in Debian 9 and later and Ubuntu's default repositories in Ubuntu 15.10 and later, so **if you do not want it to be available by default on those systems when those packages are used, then you will need to disable it**. See [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) for more information.

 
The `unix_socket` authentication plugin can be disabled by starting the server with the `[unix\_socket](#unix_socket)` option set to `OFF`. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
unix_socket=OFF

```

As an alternative, the `[unix\_socket](#unix_socket)` option can also be set to `OFF` by pairing the option with the `disable` [option prefix](../configuring-mariadb-with-option-files/index#option-prefixes). For example:

 
```
[mariadb]
...
disable_unix_socket

```

Installing the Plugin
---------------------

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, the `unix_socket` authentication plugin is installed by default, so **this step can be skipped on those versions**.

 

The `unix_socket` authentication plugin is also installed by default in **new installations** that use the `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's default repositories in Debian 9 and later and Ubuntu's default repositories in Ubuntu 15.10 and later, so **this step can be skipped on those systems when those packages are used**. See [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) for more information.

 
In other systems, although the plugin's shared library is distributed with MariaDB by default as `auth_socket.so`, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'auth_socket';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = auth_socket

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'auth_socket';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Creating Users
--------------

 To create a user account via `[CREATE USER](../create-user/index)`, specify the name of the plugin in the `[IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin)` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA unix_socket;

```

If `[SQL\_MODE](../sql-mode/index)` does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via `[GRANT](../grant/index)`. For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA unix_socket;

```

Switching to Password-based Authentication
------------------------------------------

 Sometimes Unix socket authentication does not meet your needs, so it can be desirable to switch a user account back to password-based authentication. This can easily be done by telling MariaDB to use another [authentication plugin](../authentication-plugins/index) for the account by executing the `[ALTER USER](../alter-user/index)` statement. The specific authentication plugin is specified with the `[IDENTIFIED VIA](../alter-user/index#identified-viawith-authentication_plugin)` clause. For example, if you wanted to switch to the `[mysql\_native\_password](../authentication-plugin-mysql_native_password/index)` authentication plugin, then you could execute:

 
```
ALTER USER root@localhost IDENTIFIED VIA mysql_native_password;
SET PASSWORD = PASSWORD('foo');

```

Note that if your operating system has scripts that require password-less access to MariaDB, then this may break those scripts. You may be able to fix that by setting a password in the `[client]` [option group](../configuring-mariadb-with-option-files/index#option-groups) in your /root/.my.cnf [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[client]
password=foo

```

Client Authentication Plugins
-----------------------------

 The `unix_socket` authentication plugin does not require any specific client authentication plugins. It should work with all clients.

 Support in Client Libraries
---------------------------

 The `unix_socket` authentication plugin does not require any special support in client libraries. It should work with all client libraries.

 Example
-------

 
```
$ mysql -uroot
MariaDB []> CREATE USER serg IDENTIFIED VIA unix_socket;
MariaDB []> CREATE USER monty IDENTIFIED VIA unix_socket;
MariaDB []> quit
Bye
$ whoami
serg
$ mysql --user=serg
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.2.0-MariaDB-alpha-debug Source distribution
MariaDB []> quit
Bye
$ mysql --user=monty
ERROR 1045 (28000): Access denied for user 'monty'@'localhost' (using password: NO)

```

In this example, a user `serg` is already logged into the operating system and has full shell access. He has already authenticated with the operating system and his MariaDB account is configured to use the `unix_socket` authentication plugin, so he does not need to authenticate again for the database. MariaDB accepts his operating system credentials and allows him to connect. However, any attempt to connect to the database as another operating system user will be denied.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) |
| 1.0 | Beta | [MariaDB 5.2.0](https://mariadb.com/kb/en/mariadb-520-release-notes/) |

 
Options
-------

 ### `unix_socket`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugin](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--unix-socket=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 See Also
--------

 * [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index)
* [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [Authentication from MariaDB 10 4 video tutorial](https://www.youtube.com/watch?v=aWFG4uLbimM)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-unix-socket/>

LOAD DATA FROM MASTER (removed)
===============================

    Syntax
------

 
```
LOAD DATA FROM MASTER

```

Description
-----------

 This feature has been removed from recent versions of MariaDB.

 Since the current implementation of `LOAD DATA FROM MASTER` and `[LOAD TABLE FROM MASTER](../load-table-from-master/index)` is very limited, these statements are deprecated in versions 4.1 of MySQL and above. We will introduce a more advanced technique (called "online backup") in a future version. That technique will have the additional advantage of working with more storage engines.

 For MySQL 5.1 and earlier, the recommended alternative solution to using `LOAD DATA FROM MASTER` or `LOAD TABLE FROM MASTER` is using [mysqldump](../mysqldump/index) or [mysqlhotcopy](../mysqlhotcopy/index). The latter requires Perl and two Perl modules (DBI and DBD:mysql) and works for [MyISAM](../myisam/index) and [ARCHIVE](../archive/index) tables only. With mysqldump, you can create SQL dumps on the master and pipe (or copy) these to a mysql client on the slave. This has the advantage of working for all storage engines, but can be quite slow, since it works using `SELECT`.

 This statement takes a snapshot of the master and copies it to the slave. It updates the values of `MASTER_LOG_FILE` and `MASTER_LOG_POS` so that the slave starts replicating from the correct position. Any table and database exclusion rules specified with the `--replicate-*-do-*` and `--replicate-*-ignore-*` options are honored. `--replicate-rewrite-db` is not taken into account because a user could use this option to set up a non-unique mapping such as `--replicate-rewrite-db="db1->db3"` and `--replicate-rewrite-db="db2->db3"`, which would confuse the slave when loading tables from the master.

 Use of this statement is subject to the following conditions:

 * It works only for MyISAM tables. Attempting to load a non-MyISAM table results in the following error: `ERROR 1189 (08S01): Net error reading from master`
* It acquires a global read lock on the master while taking the snapshot, which prevents updates on the master during the load operation.

 If you are loading large tables, you might have to increase the values of `net_read_timeout` and `net_write_timeout` on both the master and slave servers. See [Server System Variables](../server-system-variables/index).

 Note that `LOAD DATA FROM MASTER` does not copy any tables from the mysql database. This makes it easy to have different users and privileges on the master and the slave.

 To use `LOAD DATA FROM MASTER`, the replication account that is used to connect to the master must have the `RELOAD` and `[SUPER](../grant/index#global-privileges)` privileges on the master and the `SELECT` privilege for all master tables you want to load. All master tables for which the user does not have the `SELECT` privilege are ignored by `LOAD DATA FROM MASTER`. This is because the master hides them from the user: `LOAD DATA FROM MASTER` calls `SHOW DATABASES` to know the master databases to load, but `[SHOW DATABASES](../show-databases/index)` returns only databases for which the user has some privilege. On the slave side, the user that issues `LOAD DATA FROM MASTER` must have privileges for dropping and creating the databases and tables that are copied.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-data-from-master-removed/>

LOAD TABLE FROM MASTER (removed)
================================

    Syntax
------

 
```
LOAD TABLE tbl_name FROM MASTER

```

Description
-----------

 This feature has been removed from recent versions of MariaDB.

 Since the current implementation of `[LOAD DATA FROM MASTER](../load-data-from-master-removed/index)` and `LOAD TABLE FROM MASTER` is very limited, these statements are deprecated in versions 4.1 of MySQL and above. We will introduce a more advanced technique (called "online backup") in a future version. That technique will have the additional advantage of working with more storage engines.

 For MariaDB and MySQL 5.1 and earlier, the recommended alternative solution to using `LOAD DATA FROM MASTER` or `LOAD TABLE FROM MASTER` is using [mysqldump](../mysqldump/index) or [mysqlhotcopy](../mysqlhotcopy/index). The latter requires Perl and two Perl modules (DBI and DBD:mysql) and works for [MyISAM](../myisam/index) and [ARCHIVE](../archive/index) tables only. With mysqldump, you can create SQL dumps on the master and pipe (or copy) these to a mysql client on the slave. This has the advantage of working for all storage engines, but can be quite slow, since it works using `SELECT`.

 Transfers a copy of the table from the master to the slave. This statement is implemented mainly debugging `LOAD DATA FROM MASTER` operations. To use `LOAD TABLE`, the account used for connecting to the master server must have the `RELOAD` and `[SUPER](../grant/index#global-privileges)` privileges on the master and the `SELECT` privilege for the master table to load. On the slave side, the user that issues `LOAD TABLE FROM MASTER` must have privileges for dropping and creating the table.

 The conditions for `LOAD DATA FROM MASTER` apply here as well. For example, `LOAD TABLE FROM MASTER` works only for MyISAM tables. The timeout notes for `LOAD DATA FROM MASTER` apply as well.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-table-from-master-removed/>

Ansible and MariaDB
====================

   General information and hints on how to automate MariaDB deployments and configuration with Ansible.

 Ansible is an open source tool to automate deployment, configuration and operations.

  

| Title | Description |
| --- | --- |
|  [Ansible Overview for MariaDB Users](../ansible-overview-for-mariadb-users/index) |  Overview of Ansible and how it works with MariaDB.  |
|  [Deploying to Remote Servers with Ansible](../deploying-to-remote-servers-with-ansible/index) |  How to invoke Ansible to run commands or apply roles on remote hosts.  |
|  [Deploying Docker Containers with Ansible](../deploying-docker-containers-with-ansible/index) |  How to deploy and manage Docker containers with Ansible.  |
|  [Existing Ansible Modules and Roles for MariaDB](../existing-ansible-modules-and-roles-for-mariadb/index) |  Links to existing Ansible modules and roles for MariaDB.  |
|  [Installing MariaDB .deb Files with Ansible](../installing-mariadb-deb-files-with-ansible/index) |  How to install MariaDB from .deb files using Ansible.  |
|  [Running mariadb-tzinfo-to-sql with Ansible](../running-mariadb-tzinfo-to-sql-with-ansible/index) |  Updating the timezone tables with mariadb-tzinfo-to-sql using Ansible.  |
|  [Managing Secrets in Ansible](../managing-secrets-in-ansible/index) |  How to store passwords as part of an Ansible repository.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ansible-and-mariadb/>

mysql.plugin Table
==================

    The `mysql.plugin` table can be queried to get information about installed [plugins](../plugins/index).

 This table only contains information about [plugins](../plugins/index) that have been installed via the following methods:

 * The [INSTALL SONAME](../install-soname/index) statement.
* The [INSTALL PLUGIN](../install-plugin/index) statement.
* The [mariadb-plugin](../mariadb-plugin/index) utility.

 This table does not contain information about:

 * Built-in plugins.
* Plugins loaded with the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) option.
* Plugins loaded with the [--plugin-load](../mysqld-options/index#-plugin-load) option.

 This table only contains enough information to reload the plugin when the server is restarted, which means it only contains the plugin name and the plugin library.

 This table uses the [Aria](../aria/index) storage engine.

 The `mysql.plugin` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `name` | `varchar(64)` | NO | PRI |  | Plugin name. |
| `dl` | `varchar(128)` | NO |  |  | Name of the plugin library. |

 
Example
-------

 
```
SELECT * FROM mysql.plugin;
+---------------------------+------------------------+
| name                      | dl                     |
+---------------------------+------------------------+
| spider                    | ha_spider.so           |
| spider_alloc_mem          | ha_spider.so           |
| METADATA_LOCK_INFO        | metadata_lock_info.so  |
| OQGRAPH                   | ha_oqgraph.so          |
| cassandra                 | ha_cassandra.so        |
| QUERY_RESPONSE_TIME       | query_response_time.so |
| QUERY_RESPONSE_TIME_AUDIT | query_response_time.so |
| LOCALES                   | locales.so             |
| sequence                  | ha_sequence.so         |
+---------------------------+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlplugin-table/>

mysqldumpslow
=============

    `mysqldumpslow` is a tool to examine the [slow query log](../slow-query-log/index).

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-dumpslow](../mariadb-dumpslow/index) is a symlink to `mysqldumpslow`. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-dumpslow](../mariadb-dumpslow/index) is the name of the tool, with `mysqldumpslow` a symlink .

  See [mariadb-dumpslow](../mariadb-dumpslow/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqldumpslow/>

SHOW ENGINE INNODB STATUS
=========================

    `SHOW ENGINE INNODB STATUS` is a specific form of the [SHOW ENGINE](../show-engine/index) statement that displays the [InnoDB Monitor](../innodb-monitors/index) output, which is extensive InnoDB information which can be useful in diagnosing problems.

 The following sections are displayed

 * **Status:** Shows the timestamp, monitor name and the number of seconds, or the elapsed time between the current time and the time the InnoDB Monitor output was last displayed. The per-second averages are based upon this time.
* **BACKGROUND THREAD:** srv\_master\_thread lines show work performed by the main background thread.
* **SEMAPHORES:** Threads waiting for a semaphore and stats on how the number of times threads have needed a spin or a wait on a mutex or rw-lock semaphore. If this number of threads is large, there may be I/O or contention issues. Reducing the size of the [innodb\_thread\_concurrency](../xtradbinnodb-server-system-variables/index#innodb_thread_concurrency) system variable may help if contention is related to thread scheduling. `Spin rounds per wait` shows the number of spinlock rounds per OS wait for a mutex.
* **LATEST FOREIGN KEY ERROR:** Only shown if there has been a foreign key constraint error, it displays the failed statement and information about the constraint and the related tables.
* **LATEST DETECTED DEADLOCK:** Only shown if there has been a deadlock, it displays the transactions involved in the deadlock and the statements being executed, held and required locked and the transaction rolled back to.
* **TRANSACTIONS:** The output of this section can help identify lock contention, as well as reasons for the deadlocks.
* **FILE I/O:** InnoDB thread information as well as pending I/O operations and I/O performance statistics.
* **INSERT BUFFER AND ADAPTIVE HASH INDEX:** InnoDB insert buffer (old name for the [change buffer](../innodb-change-buffering/index)) and adaptive hash index status information, including the number of each type of operation performed, and adaptive hash index performance.
* **LOG:** InnoDB log information, including current log sequence number, how far the log has been flushed to disk, the position at which InnoDB last took a checkpoint, pending writes and write performance statistics.
* **BUFFER POOL AND MEMORY:** Information on buffer pool pages read and written, which allows you to see the number of data file I/O operations performed by your queries. See [InnoDB Buffer Pool](../innodb-buffer-pool/index) for more. Similar information is also available from the [INFORMATION\_SCHEMA.INNODB\_BUFFER\_POOL\_STATS](../information-schema-innodb_buffer_pool_stats-table/index) table.
* **ROW OPERATIONS:**Information about the main thread, including the number and performance rate for each type of row operation.

 If the [innodb\_status\_output\_locks](../xtradbinnodb-server-system-variables/index#innodb_status_output_locks) system variable is set to `1`, extended lock information will be displayed.

 Example output:

 
```
=====================================
2019-09-06 12:44:13 0x7f93cc236700 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 4 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 2 srv_active, 0 srv_shutdown, 83698 srv_idle
srv_master_thread log flush and writes: 83682
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 15
OS WAIT ARRAY INFO: signal count 8
RW-shared spins 0, rounds 20, OS waits 7
RW-excl spins 0, rounds 0, OS waits 0
RW-sx spins 0, rounds 0, OS waits 0
Spin rounds per wait: 20.00 RW-shared, 0.00 RW-excl, 0.00 RW-sx
------------
TRANSACTIONS
------------
Trx id counter 236
Purge done for trx's n:o < 236 undo n:o < 0 state: running
History list length 22
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421747401994584, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421747401990328, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
--------
FILE I/O
--------
I/O thread 0 state: waiting for completed aio requests (insert buffer thread)
I/O thread 1 state: waiting for completed aio requests (log thread)
I/O thread 2 state: waiting for completed aio requests (read thread)
I/O thread 3 state: waiting for completed aio requests (read thread)
I/O thread 4 state: waiting for completed aio requests (read thread)
I/O thread 5 state: waiting for completed aio requests (read thread)
I/O thread 6 state: waiting for completed aio requests (write thread)
I/O thread 7 state: waiting for completed aio requests (write thread)
I/O thread 8 state: waiting for completed aio requests (write thread)
I/O thread 9 state: waiting for completed aio requests (write thread)
Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,
 ibuf aio reads:, log i/o's:, sync i/o's:
Pending flushes (fsync) log: 0; buffer pool: 0
286 OS file reads, 171 OS file writes, 22 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 0, seg size 2, 0 merges
merged operations:
 insert 0, delete mark 0, delete 0
discarded operations:
 insert 0, delete mark 0, delete 0
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
Hash table size 34679, node heap has 0 buffer(s)
0.00 hash searches/s, 0.00 non-hash searches/s
---
LOG
---
Log sequence number 445926
Log flushed up to   445926
Pages flushed up to 445926
Last checkpoint at  445917
0 pending log flushes, 0 pending chkp writes
18 log i/o's done, 0.00 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 167772160
Dictionary memory allocated 50768
Buffer pool size   8012
Free buffers       7611
Database pages     401
Old database pages 0
Modified db pages  0
Percent of dirty pages(LRU & free pages): 0.000
Max dirty pages percent: 75.000
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 264, created 137, written 156
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 401, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Process ID=4267, Main thread ID=140272021272320, state: sleeping
Number of rows inserted 1, updated 0, deleted 0, read 1
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
Number of system rows inserted 0, updated 0, deleted 0, read 0
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-engine-innodb-status/>

InnoDB Troubleshooting
=======================

   Guidelines when troubleshooting problems with InnoDB.

  

| Title | Description |
| --- | --- |
|  [InnoDB Troubleshooting Overview](../innodb-troubleshooting-overview/index) |  Overview of InnoDB errors experienced and steps to take.  |
|  [InnoDB Data Dictionary Troubleshooting](../innodb-data-dictionary-troubleshooting/index) |  Troubleshooting the InnoDB Data Dictionary.  |
|  [InnoDB Recovery Modes](../innodb-recovery-modes/index) |  Modes for recovering from emergency situations in InnoDB.  |
|  [Troubleshooting Row Size Too Large Errors with InnoDB](../troubleshooting-row-size-too-large-errors-with-innodb/index) |  Fixing "Row size too large (> 8126). Changing some columns to TEXT or BLOB may help."  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-troubleshooting/>

InnoDB Versions
===============

    
**MariaDB starting with [10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)**In [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) and later, the InnoDB implementation has diverged substantially from the InnoDB in MySQL. Therefore, in these versions, the InnoDB version is no longer associated with a MySQL release version.

 

**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and later, the default InnoDB implementation is based on InnoDB from MySQL 5.7. See [Why MariaDB uses InnoDB instead of XtraDB from MariaDB 10.2](../why-does-mariadb-102-use-innodb-instead-of-xtradb/index) for more information.

 

**MariaDB until [10.1](../what-is-mariadb-101/index)**In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the default InnoDB implementation is based on Percona's XtraDB. XtraDB is a performance enhanced fork of InnoDB. For compatibility reasons, the [system variables](../xtradbinnodb-server-system-variables/index) still retain their original `innodb` prefixes. If the documentation says that something applies to InnoDB, then it usually also applies to the XtraDB fork, unless explicitly stated otherwise. In these versions, it is still possible to use InnoDB instead of XtraDB. See [Using InnoDB instead of XtraDB](../using-innodb-instead-of-xtradb/index) for more information.

 
Divergences
-----------

 Some examples of divergences between MariaDB's InnoDB and MySQL's InnoDB are:

 * [MariaDB 10.1](../what-is-mariadb-101/index) (which is based on MySQL 5.6) included encryption and variable-size page compression before MySQL 5.7 introduced them.

 * [MariaDB 10.2](../what-is-mariadb-102/index) (based on MySQL 5.7) introduced persistent AUTO\_INCREMENT ([MDEV-6076](https://jira.mariadb.org/browse/MDEV-6076)) in a GA release before MySQL 8.0.

 * [MariaDB 10.3](../what-is-mariadb-103/index) (based on MySQL 5.7) introduced instant ADD COLUMN ([MDEV-11369](https://jira.mariadb.org/browse/MDEV-11369)) before MySQL.

 InnoDB Versions Included in MariaDB Releases
--------------------------------------------

 ### [MariaDB 10.3](../what-is-mariadb-103/index)

 


| InnoDB Version | Introduced |
| --- | --- |
| No longer reported | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| InnoDB 5.7.20 | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| InnoDB 5.7.19 | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| InnoDB 5.7.14 | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |

 
### [MariaDB 10.2](../what-is-mariadb-102/index)

 


| InnoDB Version | Introduced |
| --- | --- |
| InnoDB 5.7.29 | [MariaDB 10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/) |
| InnoDB 5.7.23 | [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/) |
| InnoDB 5.7.22 | [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/) |
| InnoDB 5.7.21 | [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/) |
| InnoDB 5.7.20 | [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/) |
| InnoDB 5.7.19 | [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/) |
| InnoDB 5.7.18 | [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/) |
| InnoDB 5.7.14 | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |

 
### [MariaDB 10.1](../what-is-mariadb-101/index)

 


| InnoDB Version | Introduced |
| --- | --- |
| InnoDB 5.6.49 | [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/) |
| InnoDB 5.6.47 | [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10144-release-notes/) |
| InnoDB 5.6.44 | [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/) |
| InnoDB 5.6.42 | [MariaDB 10.1.37](https://mariadb.com/kb/en/mariadb-10137-release-notes/) |
| InnoDB 5.6.39 | [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/) |
| InnoDB 5.6.37 | [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) |
| InnoDB 5.6.36 | [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/) |
| InnoDB 5.6.35 | [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) |
| InnoDB 5.6.33 | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| InnoDB 5.6.32 | [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/) |
| InnoDB 5.6.31 | [MariaDB 10.1.16](https://mariadb.com/kb/en/mariadb-10116-release-notes/) |
| InnoDB 5.6.30 | [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10114-release-notes/) |
| InnoDB 5.6.29 | [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10112-release-notes/) |

 
### [MariaDB 10.0](../what-is-mariadb-100/index)

 


| InnoDB Version | Introduced |
| --- | --- |
| InnoDB 5.6.43 | [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10038-release-notes/) |
| InnoDB 5.6.42 | [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10037-release-notes/) |
| InnoDB 5.6.40 | [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10035-release-notes/) |
| InnoDB 5.6.39 | [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10034-release-notes/) |
| InnoDB 5.6.38 | [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10033-release-notes/) |
| InnoDB 5.6.37 | [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10032-release-notes/) |
| InnoDB 5.6.36 | [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10031-release-notes/) |
| InnoDB 5.6.35 | [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10029-release-notes/) |
| InnoDB 5.6.33 | [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10028-release-notes/) |
| InnoDB 5.6.32 | [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/) |
| InnoDB 5.6.31 | [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10026-release-notes/) |
| InnoDB 5.6.30 | [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10025-release-notes/) |
| InnoDB 5.6.29 | [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10024-release-notes/) |
| InnoDB 5.6.28 | [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/) |
| InnoDB 5.6.27 | [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/) |
| InnoDB 5.6.26 | [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10021-release-notes/) |
| InnoDB 5.6.25 | [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10020-release-notes/) |
| InnoDB 5.6.24 | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) |
| InnoDB 5.6.23 | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) |
| InnoDB 5.6.22 | [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/) |
| InnoDB 5.6.21 | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| InnoDB 5.6.20 | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) |
| InnoDB 5.6.19 | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| InnoDB 5.6.17 | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) |
| InnoDB 5.6.15 | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| InnoDB 5.6.14 | [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-1008-release-notes/) |

 
See Also
--------

 * [Why MariaDB uses InnoDB instead of XtraDB from MariaDB 10.2](../why-does-mariadb-102-use-innodb-instead-of-xtradb/index)
* [XtraDB Versions](../about-xtradb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-versions/>

InnoDB Doublewrite Buffer
=========================

    The [InnoDB](../innodb/index) doublewrite buffer was implemented to recover from half-written pages. This can happen when there's a power failure while InnoDB is writing a page to disk. On reading that page, InnoDB can discover the corruption from the mismatch of the page checksum. However, in order to recover, an intact copy of the page would be needed. 

 The double write buffer provides such a copy. 

 Whenever InnoDB flushes a page to disk, it is first written to the double write buffer. Only when the buffer is safely flushed to disk will InnoDB write the page to the final destination. When recovering, InnoDB scans the double write buffer and for each valid page in the buffer checks if the page in the data file is valid too.

 Doublewrite Buffer Settings
---------------------------

 To turn off the doublewrite buffer, set the [innodb\_doublewrite](../innodb-system-variables/index#innodb_doublewrite) system variable to `0`. This is safe on filesystems that write pages atomically - that is, a page write fully succeeds or fails. But with other filesystems, it is not recommended for production systems. An alternative option is atomic writes. See [atomic write support](../atomic-write-support/index) for more details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-doublewrite-buffer/>

Heuristic Recovery with the Transaction Coordinator Log
=======================================================

    The transaction coordinator log (tc\_log) is used to coordinate transactions that affect multiple [XA-capable](../xa-transactions/index) [storage engines](../storage-engines/index). One of the main purposes of this log is in crash recovery.

 Modes of Crash Recovery
-----------------------

 There are two modes of crash recovery:

 * Automatic crash recovery.
* Manual heuristic recovery when `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` is set to some value other than `OFF`.

 Automatic Crash Recovery
------------------------

 Automatic crash recovery occurs during startup when MariaDB needs to recover from a crash and `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` is set to `OFF`, which is the default value.

 ### Automatic Crash Recovery with the Binary Log-Based Transaction Coordinator Log

 If MariaDB needs to perform automatic crash recovery and if the [binary log](../binary-log/index) is enabled, then the [error log](../error-log/index) will contain messages like this:

 
```
[Note] Recovering after a crash using cmdb-mariadb-0-bin
[Note] InnoDB: Buffer pool(s) load completed at 190313 11:24:29
[Note] Starting crash recovery...
[Note] Crash recovery finished.

```

### Automatic Crash Recovery with the Memory-Mapped File-Based Transaction Coordinator Log

 If MariaDB needs to perform automatic crash recovery and if the [binary log](../binary-log/index) is **not** enabled, then the [error log](../error-log/index) will contain messages like this:

 
```
[Note] Recovering after a crash using tc.log
[Note] InnoDB: Buffer pool(s) load completed at 190313 11:26:32
[Note] Starting crash recovery...
[Note] Crash recovery finished.

```

Manual Heuristic Recovery
-------------------------

 Manual heuristic recovery occurs when `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` is set to some value other than `OFF`. This might be needed if the server finds prepared transactions during crash recovery that are not in the transaction coordinator log. For example, the [error log](../error-log/index) might contain an error like this:

 
```
[ERROR] Found 1 prepared transactions! It means that mysqld was not shut down properly last time and critical recovery information (last binlog or tc.log file) was manually deleted after a crash. You have to start mysqld with --tc-heuristic-recover switch to commit or rollback pending transactions.

```

When manual heuristic recovery is initiated, MariaDB will ignore information about transactions in the transaction coordinator log during the recovery process. Prepared transactions that are encountered during the recovery process will either be rolled back or committed, depending on the value of `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)`.

 When manual heuristic recovery is initiated, the [error log](../error-log/index) will contain a message like this:

 
```
[Note] Heuristic crash recovery mode

```

### Manual Heuristic Recovery with the Binary Log-Based Transaction Coordinator Log

 If `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` is set to some value other than `OFF` and if the [binary log](../binary-log/index) is enabled, then MariaDB will ignore information about transactions in the [binary log](../binary-log/index) during the recovery process. Prepared transactions that are encountered during the recovery process will either be rolled back or committed, depending on the value of `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)`.

 After the recovery process is complete, MariaDB will create a new empty [binary log](../binary-log/index) file, so that the old corrupt ones can be ignored.

 ### Manual Heuristic Recovery with the Memory-Mapped File-Based Transaction Coordinator Log

 If `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` is set to some value other than `OFF` and if the [binary log](../binary-log/index) is **not** enabled, then MariaDB will ignore information about transactions in the the memory-mapped file defined by the `[--log-tc](../mysqld-options/index#-log-tc)` option during the recovery process. Prepared transactions that are encountered during the recovery process will either be rolled back or committed, depending on the value of `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/heuristic-recovery-with-the-transaction-coordinator-log/>

AUTO\_INCREMENT Handling in InnoDB
==================================

    AUTO\_INCREMENT Lock Modes
--------------------------

 The [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) system variable determines the lock mode when generating [AUTO\_INCREMENT](../auto_increment/index) values for [InnoDB](../innodb/index) tables. These modes allow [InnoDB](../innodb/index) to make significant performance optimizations in certain circumstances. 

 The [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) system variable may be removed in a future release. See [MDEV-19577](https://jira.mariadb.org/browse/MDEV-19577) for more information.

 ### Traditional Lock Mode

 When [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) is set to `0`, [InnoDB](../innodb/index) uses the traditional lock mode.

 In this mode, [InnoDB](../innodb/index) holds a table-level lock for all [INSERT](../insert/index) statements until the statement completes.

 ### Consecutive Lock Mode

 When [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) is set to `1`, [InnoDB](../innodb/index) uses the consecutive lock mode.

 In this mode, [InnoDB](../innodb/index) holds a table-level lock for all bulk [INSERT](../insert/index) statements (such as [LOAD DATA](../load-data-infile/index) or [INSERT ... SELECT](../insert-select/index)) until the end of the statement. For simple [INSERT](../insert/index) statements, no table-level lock is held. Instead, a lightweight mutex is used which scales significantly better. This is the default setting.

 ### Interleaved Lock Mode

 When [innodb\_autoinc\_lock\_mode](../innodb-system-variables/index#innodb_autoinc_lock_mode) is set to `2`, [InnoDB](../innodb/index) uses the interleaved lock mode.

 In this mode, [InnoDB](../innodb/index) does not hold any table-level locks at all. This is the fastest and most scalable mode, but is not safe for [statement-based](../binary-log-formats/index#statement-based) replication.

 Setting AUTO\_INCREMENT Values
------------------------------

 The [AUTO\_INCREMENT](../auto_increment/index) value for an [InnoDB](../innodb/index) table can be set for a table by executing the [ALTER TABLE](../alter-table/index) statement and specifying the [AUTO\_INCREMENT](../create-table/index#auto_increment) table option. For example:

 
```
ALTER TABLE tab AUTO_INCREMENT=100;

```

However, in [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) and before, [InnoDB](../innodb/index) stores the table's [AUTO\_INCREMENT](../auto_increment/index) counter in memory. In these versions, when the server restarts, the counter is re-initialized to the highest value found in the table. This means that the above operation can be undone if the server is restarted before any rows are written to the table.

 In [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) and later, the [AUTO\_INCREMENT](../auto_increment/index) counter is persistent, so this restriction is no longer present. Persistent, however, does not mean transactional. Gaps may still occur in some cases, such as if a [INSERT IGNORE](../insert-ignore/index) statement fails, or if a user executes [ROLLBACK](../rollback/index) or [ROLLBACK TO SAVEPOINT](../savepoint/index).

 For example:

 
```
CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, i INT, UNIQUE (i)) ENGINE=InnoDB;

INSERT INTO t1 (i) VALUES (1),(2),(3);
INSERT IGNORE INTO t1 (pk, i) VALUES (100,1);
Query OK, 0 rows affected, 1 warning (0.099 sec)

SELECT * FROM t1;
+----+------+
| pk | i    |
+----+------+
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+

SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `pk` int(11) NOT NULL AUTO_INCREMENT,
  `i` int(11) DEFAULT NULL,
  PRIMARY KEY (`pk`),
  UNIQUE KEY `i` (`i`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

```

If the server is restarted at this point, then the [AUTO\_INCREMENT](../auto_increment/index) counter will revert to `101`, which is the persistent value set as part of the failed [INSERT IGNORE](../insert-ignore/index).

 
```
# Restart server
SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `pk` int(11) NOT NULL AUTO_INCREMENT,
  `i` int(11) DEFAULT NULL,
  PRIMARY KEY (`pk`),
  UNIQUE KEY `i` (`i`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=latin1

```

See Also
--------

 * [AUTO\_INCREMENT](../auto_increment/index)
* [AUTO\_INCREMENT FAQ](../autoincrement-faq/index)
* [LAST\_INSERT\_ID](../last_insert_id/index)
* [Sequences](../sequences/index) - an alternative to auto\_increment available from [MariaDB 10.3](../what-is-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/auto_increment-handling-in-innodb/>

InnoDB Limitations
==================

     The [InnoDB storage engine](../innodb/index) has the following limitations.

 Limitations on Schema
---------------------

 * InnoDB tables can have a maximum of 1,017 columns. This includes [virtual generated columns](../generated-columns/index).
* InnoDB tables can have a maximum of 64 secondary indexes.
* A multicolumn index on InnoDB can use a maximum of 16 columns. If you attempt to create a multicolumn index that uses more than 16 columns, MariaDB returns an Error 1070.

 Limitations on Size
-------------------

 * With the exception of variable-length columns (that is, [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index)), rows in InnoDB have a maximum length of roughly half the page size for 4KB, 8KB, 16KB and 32KB page sizes.
* The maximum size for [BLOB](../blob/index) and [TEXT](../text/index) columns is 4GB. This also applies to [LONGBLOB](../longblob/index) and [LONGTEXT](../longtext/index).
* MariaDB imposes a row-size limit of 65,535 bytes for the combined sizes of all columns. If the table contains [BLOB](../blob/index) or [TEXT](../text/index) columns, these only count for 9 - 12 bytes in this calculation, given that their content is stored separately.
* 32-bit operating systems have a maximum file size limit of 2GB. When working with large tables using this architecture, configure InnoDB to use smaller data files.
* The maximum size for the combined InnoDB log files is 512GB.
* With tablespaces, the minimum size is 10MB, the maximum varies depending on the InnoDB Page Size.

 


| InnoDB Page Size | Maximum Tablespace Size |
| --- | --- |
| 4KB | 16TB |
| 8KB | 32TB |
| 16KB | 64TB |
| 32KB | 128TB |
| 64KB | 256TB |

 
### Page Sizes

 Using the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable, you can configure the size in bytes for InnoDB pages. Pages default to 16KB. There are certain limitations on how you use this variable.

 * MariaDB instances using one page size cannot use data files or log files from an instance using a different page size.
* When using a Page Size of 4KB or 8KB, the maximum index key length is lowered proportionately.

 


| InnoDB Page Size | Index Key Length |
| --- | --- |
| 4KB | 768B |
| 8KB | 1536B |
| 16KB | 3072B |

 
### Large Prefix Size

 Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), the [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) system variable enabled large prefix sizes. That is, when enabled (the default from [MariaDB 10.2](../what-is-mariadb-102/index)), InnoDB uses 3072B index key prefixes for `DYNAMIC` and `COMPRESSED` row formats. When disabled, it uses 787B key prefixes for tables of any row format. Using an index key that exceeds this limit throws an error.

 From [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), InnoDB always uses large index key prefixes.

 Limitations on Tables
---------------------

 InnoDB has the following table-specific limitations.

 * When you issue a [DELETE](../delete/index) statement, InnoDB doesn't regenerate the table, rather it deletes each row from the table one by one.
* When running MariaDB on Windows, InnoDB stores databases and tables in lowercase. When moving databases and tables in a binary format from Windows to a Unix-like system or from a Unix system to Windows, you need to rename these to use lowercase.
* When using cascading [foreign keys](../foreign-keys/index), operations in the cascade don't activate triggers.

 ### Table Analysis

 MariaDB supports the use of the [ANALYZE TABLE](../analyze-table/index) SQL statement to analyze and store table key distribution. When MariaDB executes this statement, it calculates index cardinality through random dives on index trees. This makes it fast, but not always accurate as it does not check all rows. The data is only an estimate and repeated executions of this statement may return different results.

 
In situations where accurate data from [ANALYZE TABLE](../analyze-table/index) statements is important, enable the [innodb\_stats\_persistent](../innodb-system-variables/index#innodb_stats_persistent) system variable. Additionally, you can use the [innodb\_stats\_transient\_sample\_pages](../innodb-system-variables/index#innodb_stats_transient_sample_pages) system variable to change the number of random dives it performs. 

 
When running [ANALYZE TABLE](../analyze-table/index) twice on a table in which statements or transactions are running, MariaDB blocks the second [ANALYZE TABLE](../analyze-table/index) until the statement or transaction is complete. This occurs because the statement or transaction blocks the second [ANALYZE TABLE](../analyze-table/index) statement from reloading the table definition, which it must do since the old one was marked as obsolete after the first statement.

 ### Table Status

 Similar to the [ANALYZE TABLE](../analyze-table/index) statement, [SHOW TABLE STATUS](../show-table-status/index) statements do not provide accurate statistics for InnoDB, except for the physical table size.

 The InnoDB storage engine does not maintain internal row counts. Transactions isolate writes, which means that concurrent transactions will not have the same row counts. 

 ### Auto-incrementing Columns

 * When defining an index on an auto-incrementing column, it must be defined in a way that allows the equivalent of `SELECT MAX(col)` lookups on the table.
* Restarting MariaDB may cause InnoDB to reuse old auto-increment values, such as in the case of a transaction that was rolled back.
* When auto-incrementing columns run out of values, [INSERT](../insert/index) statements generate duplicate-key errors.

 Transactions and Locks
----------------------

 * You can modify data on a maximum of 96 \* 1023 concurrent transactions that generate undo records.
* Of the 128 rollback segments, InnoDB assigns 32 to non-redo logs for transactions that modify temporary tables and related objects, reducing the maximum number of concurrent data-modifying transactions to 96,000, from 128.000.
* The limit is 32,000 concurrent transactions when all data-modifying transactions also modify temporary tables.
* Issuing a [LOCK TABLES](../lock-tables/index) statement sets two locks on each table when the [innodb\_table\_locks](../innodb-system-variables/index#innodb_table_locks) system variable is enabled (the default).
* When you commit or roll back a transaction, any locks set in the transaction are released. You don't need to issue [LOCK TABLES](../lock-tables/index) statements when the [autocommit](../server-system-variables/index#autocommit) variable is enabled, as InnoDB would immediately release the table locks.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-limitations/>

InnoDB Tablespaces
===================

   Tables that use the InnoDB storage engine are written to disk in data files called tablespaces. An individual tablespace can contain data from one or more InnoDB tables as well as the associated indexes.

  

| Title | Description |
| --- | --- |
|  [InnoDB System Tablespaces](../innodb-system-tablespaces/index) |  The system tablespace, how to change its size, and the use of raw disk partitions.  |
|  [InnoDB File-Per-Table Tablespaces](../innodb-file-per-table-tablespaces/index) |  InnoDB file-per-table tablespaces: what they are, where they're located, ho...  |
|  [InnoDB Temporary Tablespaces](../innodb-temporary-tablespaces/index) |  Information on tablespaces for user-created temporary tables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-tablespaces/>

InnoDB Page Flushing
====================

    Page Flushing with InnoDB Page Cleaner Threads
----------------------------------------------

 InnoDB page cleaner threads flush dirty pages from the [InnoDB buffer pool](../innodb-buffer-pool/index). These dirty pages are flushed using a least-recently used (LRU) algorithm.

 ### innodb\_max\_dirty\_pages\_pct

 The [innodb\_max\_dirty\_pages\_pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct) variable specifies the maximum percentage of unwritten (dirty) pages in the [buffer pool](../innodb-buffer-pool/index). If this percentage is exceeded, flushing will take place.

 ### innodb\_max\_dirty\_pages\_pct\_lwm

 The [innodb\_max\_dirty\_pages\_pct\_lwm](../innodb-system-variables/index#innodb_max_dirty_pages_pct_lwm) variable determines the low-water mark percentage of dirty pages that will enable preflushing to lower the dirty page ratio. The value 0 (the default) means that there will be no separate background flushing so long as: 

 * the share of dirty pages does not exceed [innodb\_max\_dirty\_pages\_pct](../innodb-system-variables/index#innodb_max_dirty_pages_pct)
* the last checkpoint age (LSN difference since the latest checkpoint) does not exceed [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) (minus some safety margin)
* the [buffer pool](../innodb-buffer-pool/index) is not running out of space, which could trigger eviction flushing

 Note that in [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) and [MariaDB 10.5.8](https://mariadb.com/kb/en/mariadb-1058-release-notes/) only, flushing was more aggressive, and the page cleaner thread would always run in the background, as long as dirty pages exist in the buffer pool. To make flushing more eager, set to a higher value, for example `SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.001;` (the default until [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)).

 ### Page Flushing with Multiple InnoDB Page Cleaner Threads

 
**MariaDB [10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) - [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**The [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) system variable was added in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), and makes it possible to use multiple InnoDB page cleaner threads. It is deprecated and ignored from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), as the original reasons for for splitting the buffer pool have mostly gone away. 

 
The number of InnoDB page cleaner threads can be configured by setting the [innodb\_page\_cleaners](../innodb-system-variables/index#innodb_page_cleaners) system variable. This system variable can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_page_cleaners=8

```

In [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) and later, this system variable can also be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_page_cleaners=8;

```

This system variable's default value is either `4` or the configured value of the [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) system variable, whichever is lower. 

 ### Page Flushing with a Single InnoDB Page Cleaner Thread

 In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, and from [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), when the original reasons for splitting the buffer pool have mostly gone away, only a single InnoDB page cleaner thread is supported.

 Page Flushing with Multi-threaded Flush Threads
-----------------------------------------------

 
**MariaDB [10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) - [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**InnoDB's multi-thread flush feature was first added in [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/). It was deprecated in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and removed in [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/).

 
In [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) and before, InnoDB's multi-thread flush feature can be used. This is especially useful in [MariaDB 10.1](../what-is-mariadb-101/index), which only supports a single page cleaner thread.

 InnoDB's multi-thread flush feature can be enabled by setting the [innodb\_use\_mtflush](../innodb-system-variables/index#innodb_use_mtflush) system variable. The number of threads cane be configured by setting the [innodb\_mtflush\_threads](../innodb-system-variables/index#innodb_mtflush_threads) system variable. This system variable can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_use_mtflush = ON
innodb_mtflush_threads = 8

```

The [innodb\_mtflush\_threads](../innodb-system-variables/index#innodb_mtflush_threads) system variable's default value is `8`. The maximum value is `64`. In multi-core systems, it is recommended to set its value close to the configured value of the [innodb\_buffer\_pool\_instances](../innodb-system-variables/index#innodb_buffer_pool_instances) system variable. However, it is also recommended to use your own benchmarks to find a suitable value for your particular application.

 InnoDB's multi-thread flush feature was deprecated in [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) and removed from [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/). In later versions of MariaDB, use multiple InnoDB page cleaner threads instead.

 Configuring the InnoDB I/O Capacity
-----------------------------------

 Increasing the amount of I/O capacity available to InnoDB can also help increase the performance of page flushing.

 The amount of I/O capacity available to InnoDB can be configured by setting the [innodb\_io\_capacity](../innodb-system-variables/index#innodb_io_capacity) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_io_capacity=20000;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_io_capacity=20000

```

The maximum amount of I/O capacity available to InnoDB in an emergency defaults to either `2000` or twice [innodb\_io\_capacity](../innodb-system-variables/index#innodb_io_capacity), whichever is higher, or can be directly configured by setting the [innodb\_io\_capacity\_max](../innodb-system-variables/index#innodb_io_capacity_max) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_io_capacity_max=20000;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_io_capacity_max=20000

```

See Also
--------

 * [Significant performance boost with new MariaDB page compression on FusionIO](https://blog.mariadb.org/significant-performance-boost-with-new-mariadb-page-compression-on-fusionio/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-page-flushing/>

InnoDB Purge
============

    When a transaction updates a row in an InnoDB table, InnoDB's MVCC implementation keeps old versions of the row in the [InnoDB undo log](../innodb-undo-log/index). The old versions are kept at least until all transactions older than the transaction that updated the row are no longer open. At that point, the old versions can be deleted. InnoDB has purge process that is used to delete these old versions.

 Optimizing Purge Performance
----------------------------

 ### Configuring the Purge Threads

 The number of purge threads can be set by configuring the [innodb\_purge\_threads](../innodb-system-variables/index#innodb_purge_threads) system variable. This system variable can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_purge_threads = 6

```

### Configuring the Purge Batch Size

 The purge batch size is defined as the number of [InnoDB redo log](../innodb-redo-log/index) records that must be written before triggering purge. The purge batch size can be set by configuring the [innodb\_purge\_batch\_size](../innodb-system-variables/index#innodb_purge_batch_size) system variable. This system variable can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_purge_batch_size = 50

```

### Configuring the Max Purge Lag

 If purge operations are lagging on a busy server, then this can be a tough situation to recover from. As a solution, InnoDB allows you to set the max purge lag. The max purge lag is defined as the maximum number of [InnoDB undo log](../innodb-undo-log/index) that can be waiting to be purged from the history until InnoDB begins delaying DML statements.

 The max purge lag can be set by configuring the [innodb\_max\_purge\_lag](../innodb-system-variables/index#innodb_max_purge_lag) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_max_purge_lag=1000;

```

This system variable can also be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_max_purge_lag = 1000

```

The maximum delay can be set by configuring the [innodb\_max\_purge\_lag\_delay](../innodb-system-variables/index#innodb_max_purge_lag_delay) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_max_purge_lag_delay=100;

```

This system variable can also be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_max_purge_lag_delay = 100

```

### Configuring the Purge Rollback Segment Truncation Frequency

 The purge rollback segment truncation frequency is defined as the number of purge loops that are run before unnecessary rollback segments are truncated. The purge rollback segment truncation frequency can be set by configuring the [innodb\_purge\_rseg\_truncate\_frequency](../innodb-system-variables/index#innodb_purge_rseg_truncate_frequency) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_purge_rseg_truncate_frequency=64;

```

This system variable can also be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_purge_rseg_truncate_frequency = 64

```

### Configuring the Purge Undo Log Truncation

 Purge undo log truncation occurs when InnoDB truncates an entire [InnoDB undo log](../innodb-undo-log/index) tablespace, rather than deleting individual [InnoDB undo log](../innodb-undo-log/index) records.

 Purge undo log truncation can be enabled by configuring the [innodb\_undo\_log\_truncate](../innodb-system-variables/index#innodb_undo_log_truncate) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_undo_log_truncate=ON;

```

This system variable can also be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_undo_log_truncate = ON

```

An [InnoDB undo log](../innodb-undo-log/index) tablespace is truncated when it exceeds the maximum size that is configured for [InnoDB undo log](../innodb-undo-log/index) tablespaces. The maximum size can be set by configuring the [innodb\_max\_undo\_log\_size](../innodb-system-variables/index#innodb_max_undo_log_size) system variable. This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_max_undo_log_size='64M';

```

This system variable can also be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_max_undo_log_size = 64M

```

Purge's Effect on Row Metadata
------------------------------

 An InnoDB table's clustered index has three hidden system columns that are automatically generated. These hidden system columns are:

 * `DB_ROW_ID` - If the table has no other `PRIMARY KEY` or no other `UNIQUE KEY` defined as `NOT NULL` that can be promoted to the table's `PRIMARY KEY`, then InnoDB will use a hidden system column called `DB_ROW_ID`. InnoDB will automatically generated the value for the column from a global InnoDB-wide 48-bit sequence (instead of being table-local).
* `DB_TRX_ID` - The transaction ID of either the transaction that last changed the row or the transaction that currently has the row locked.
* `DB_ROLL_PTR` - A pointer to the [InnoDB undo log](../innodb-undo-log/index) that contains the row's previous record. The value of `DB_ROLL_PTR` is only valid if `DB_TRX_ID` belongs to the current read view. The oldest valid read view is the purge view.

 If a row's last [InnoDB undo log](../innodb-undo-log/index) record is purged, this can obviously effect the value of the row's `DB_ROLL_PTR` column, because there would no longer be any [InnoDB undo log](../innodb-undo-log/index) record for the pointer to reference.

 In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the purge process wouldn't touch the value of the row's `DB_TRX_ID` column.

 However, in [MariaDB 10.3](../what-is-mariadb-103/index) and later, the purge process will set a row's `DB_TRX_ID` column to `0` after all of the row's associated [InnoDB undo log](../innodb-undo-log/index) records have been deleted. This change allows InnoDB to perform an optimization: if a query wants to read a row, and if the row's `DB_TRX_ID` column is set to `0`, then it knows that no other transaction has the row locked. Usually, InnoDB needs to lock the transaction system's mutex in order to safely check whether a row is locked, but this optimization allows InnoDB to confirm that the row can be safely read without any heavy internal locking.

 This optimization can speed up reads, but it come at a noticeable cost at other times. For example, it can cause the purge process to use more I/O after inserting a lot of rows, since the value of each row's `DB_TRX_ID` column will have to be reset.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-purge/>

InnoDB Row Formats
===================

  

| Title | Description |
| --- | --- |
|  [InnoDB Row Formats Overview](../innodb-row-formats-overview/index) |  InnoDB's row formats are REDUNDANT, COMPACT, DYNAMIC, and COMPRESSED.  |
|  [InnoDB REDUNDANT Row Format](../innodb-redundant-row-format/index) |  The REDUNDANT row format is the original non-compacted row format.  |
|  [InnoDB COMPACT Row Format](../innodb-compact-row-format/index) |  Similar to the REDUNDANT row format, but stores data in a more compact manner.  |
|  [InnoDB DYNAMIC Row Format](../innodb-dynamic-row-format/index) |  Similar to the COMPACT row format, but can store even more data on overflow pages.  |
|  [InnoDB COMPRESSED Row Format](../innodb-compressed-row-format/index) |  Similar to the COMPACT row format, but can store even more data on overflow pages.  |
|  [Troubleshooting Row Size Too Large Errors with InnoDB](../troubleshooting-row-size-too-large-errors-with-innodb/index) |  Fixing "Row size too large (> 8126). Changing some columns to TEXT or BLOB may help."  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-row-formats/>

InnoDB File Format
==================

    Prior to [MariaDB 10.3](../what-is-mariadb-103/index), the [InnoDB](../innodb/index) storage engine supports two different file formats.

 Setting a Table's File Format
-----------------------------

 In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the default file format for InnoDB tables can be chosen by setting the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format). 

 In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, the default file format is`Antelope`. In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, the default file format is `Barracuda` and `Antelope` is deprecated.

 
A table's tablespace is tagged with the lowest InnoDB file format that supports the table's [row format](../innodb-storage-formats/index). So, even if the `Barracuda` file format is enabled, tables that use the `COMPACT` or `REDUNDANT` row formats will be tagged with the `Antelope` file format in the [information\_schema.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table.

 
Supported File Formats
----------------------

 The [InnoDB](../innodb/index) storage engine supports two different file formats:

 * `Antelope`
* `Barracuda`

 ### Antelope

 In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, the default file format is `Antelope`. In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, the `Antelope` file format is deprecated.

 `Antelope` is the original InnoDB file format. It supports the `COMPACT` and `REDUNDANT` row formats, but not the `DYNAMIC` or `COMPRESSED` row formats.

 ### Barracuda

 In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the `Barracuda` file format is only supported if the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is set to `ON`. In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, the default file format is `Barracuda` and `Antelope` is deprecated.

 `Barracuda` is a newer InnoDB file format. It supports the `COMPACT`, `REDUNDANT`, `DYNAMIC` and `COMPRESSED` row formats. Tables with large BLOB or TEXT columns in particular could benefit from the dynamic row format.

 ### Future Formats

 InnoDB might use new file formats in the future. Each format will have an identifier from 0 to 25, and a name. The names have already been decided, and are animal names listed in an alphabetical order: Antelope, Barracuda, Cheetah, Dragon, Elk, Fox, Gazelle, Hornet, Impala, Jaguar, Kangaroo, Leopard, Moose, Nautilus, Ocelot, Porpoise, Quail, Rabbit, Shark, Tiger, Urchin, Viper, Whale, Xenops, Yak and Zebra.

 Checking a Table's File Format.
-------------------------------

 The [information\_schema.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table can be queried to see the file format used by a table.

 
A table's tablespace is tagged with the lowest InnoDB file format that supports the table's [row format](../innodb-storage-formats/index). So, even if the `Barracuda` file format is enabled, tables that use the `COMPACT` or `REDUNDANT` row formats will be tagged with the `Antelope` file format in the [information\_schema.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table.

 
Compatibility
-------------

 Each tablespace is tagged with the id of the most recent file format used by one of its tables. All versions of InnoDB can read tables that use an older file format. However, it can not read from more recent formats. For this reason, each time InnoDB opens a table it checks the tablespace's format, and returns an error if a newer format is used.

 This check can be skipped via the [innodb\_file\_format\_check](../innodb-system-variables/index#innodb_file_format_check) variable. Beware that, is InnoDB tries to repair a table in an unknown format, the table will be corrupted! This happens on restart if innodb\_file\_format\_check is disabled and the server crashed, or it was closed with fast shutdown.

 To downgrade a table from the Barracuda format to Antelope, the table's `ROW_FORMAT` can be set to a value supported by Antelope, via an [ALTER TABLE](../alter-table/index) statement. This recreates the indexes.

 The Antelope format can be used to make sure that tables work on MariaDB and MySQL servers which are older than 5.5.

 See Also
--------

 * [InnoDB Storage Formats](../innodb-storage-formats/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-file-format/>

InnoDB Online DDL
==================

  

| Title | Description |
| --- | --- |
|  [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index) |  All about online DDL operations with InnoDB.  |
|  [InnoDB Online DDL Operations with the INPLACE Alter Algorithm](../innodb-online-ddl-operations-with-the-inplace-alter-algorithm/index) |  These DDL operations can be done in-place with InnoDB.  |
|  [InnoDB Online DDL Operations with the NOCOPY Alter Algorithm](../innodb-online-ddl-operations-with-the-nocopy-alter-algorithm/index) |  These DDL operations can be done without copying the table with InnoDB.  |
|  [InnoDB Online DDL Operations with the INSTANT Alter Algorithm](../innodb-online-ddl-operations-with-the-instant-alter-algorithm/index) |  These DDL operations can be done instantly with InnoDB.  |
|  [Instant ADD COLUMN for InnoDB](../instant-add-column-for-innodb/index) |  Instantly add a new column to a table  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-online-ddl/>

InnoDB Data Scrubbing
=====================

    
Note that most of the background and redo log scrubbing code has been removed in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). See [MDEV-15528](https://jira.mariadb.org/browse/MDEV-15528) and [MDEV-21870](https://jira.mariadb.org/browse/MDEV-21870).

 
Sometimes there is a requirement that when some data is deleted, it is really gone. This might be the case when one stores user's personal information or some other sensitive data. Normally though, when a row is deleted, the space is only marked as free on the page. It may eventually be overwritten, but there is no guarantee when that will happen. A copy of the deleted rows may also be present in the log files.

 [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) introduced support for [InnoDB](../innodb/index) data scrubbing. Background threads periodically scan tablespaces and logs and remove all data that should be deleted. The number of background threads for tablespace scans is set by [innodb-encryption-threads](../xtradbinnodb-server-system-variables/index#innodb_encryption_threads). Log scrubbing happens in a separate thread.

 To configure scrubbing one can use the following variables:

 


|  |  |  |
| --- | --- | --- |
| [innodb-background-scrub-data-check-interval](../innodb-system-variables/index#innodb_background_scrub_data_check_interval) | Seconds | Check at this intervall if tablespaces needs scrubbing. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |
| [innodb-background-scrub-data-compressed](../innodb-system-variables/index#innodb_background_scrub_data_compressed) | Boolean | Enable scrubbing of compressed data by background threads. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |
| [innodb-background-scrub-data-interval](../innodb-system-variables/index#innodb_background_scrub_data_interval) | Seconds | Scrub spaces that were last scrubbed longer than this many seconds ago. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |
| [innodb-background-scrub-data-uncompressed](../innodb-system-variables/index#innodb_background_scrub_data_uncompressed) | Boolean | Enable scrubbing of uncompressed data by background threads. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |
| [innodb-immediate-scrub-data-uncompressed](../innodb-system-variables/index#innodb_immediate_scrub_data_uncompressed) | Boolean | Enable scrubbing of uncompressed data |
| [innodb-scrub-log](../innodb-system-variables/index#innodb_scrub_log) | Boolean | Enable redo log scrubbing. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |
| [innodb-scrub-log-speed](../innodb-system-variables/index#innodb_scrub_log_speed) | Bytes/sec | Redo log scrubbing speed in bytes/sec. Deprecated and ignored from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/). |

 
Redo log scrubbing did not fully work as intended, and was deprecated and ignored in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) ([MDEV-21870](https://jira.mariadb.org/browse/MDEV-21870)). If old log contents should be kept secret, then enabling [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) or setting a smaller [innodb\_log\_file\_size](../innodb-system-variables/index#innodb_log_file_size) could help.

 The [Information Schema INNODB\_TABLESPACES\_SCRUBBING table](../information-schema-innodb_tablespaces_scrubbing-table/index) contains scrubbing information.

 Thanks
------

 * Scrubbing was donated to the MariaDB project by Google.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-data-scrubbing/>

InnoDB Page Compression
=======================

    Overview
--------

 InnoDB page compression provides a way to compress InnoDB tables.

 Use Cases
---------

 * InnoDB page compression can be used on any storage device and any file system.

 * InnoDB page compression is most efficient on file systems that support sparse files. See [Saving Storage Space with Sparse Files](#saving-storage-space-with-sparse-files) for more information.

 * InnoDB page compression is most beneficial on solid state drives (SSDs) and other flash storage. See [Optimized for Flash Storage](#optimized-for-flash-storage) for more information.

 * InnoDB page compression performs best when your storage device and file system support atomic writes, since that allows the [InnoDB doublewrite buffer](../xtradbinnodb-doublewrite-buffer/index) to be disabled. See [Atomic Write Support](../atomic-write-support/index) for more information.

 Comparison with the `COMPRESSED` Row Format
-------------------------------------------

 InnoDB page compression is a modern way to compress your InnoDB tables. It is similar to InnoDB's [COMPRESSED](../innodb-compressed-row-format/index) row format, but it has many advantages. Some of the differences are:

 * With InnoDB page compression, compressed pages are immediately decompressed after being read from the tablespace file, and only uncompressed pages are stored in the buffer pool. In contrast, with InnoDB's [COMPRESSED](../innodb-compressed-row-format/index) row format, compressed pages are decompressed immediately after they are read from the tablespace file, and both the uncompressed and compressed pages are stored in the buffer pool. This means that the [COMPRESSED](../innodb-compressed-row-format/index) row format uses more space in the buffer pool than InnoDB page compression does.
* With InnoDB page compression, pages are compressed just before being written to the tablespace file. In contrast, with InnoDB's [COMPRESSED](../innodb-compressed-row-format/index) row format, pages are re-compressed immediately after any changes, and the compressed pages are stored in the buffer pool alongside the uncompressed pages. These changes are then occasionally flushed to disk. This means that the [COMPRESSED](../innodb-compressed-row-format/index) row format re-compresses data more frequently than InnoDB page compression does.
* With InnoDB page compression, multiple compression algorithms are supported. In contrast, with InnoDB's [COMPRESSED](../innodb-compressed-row-format/index) row format, [zlib](https://www.zlib.net/) is the only supported compression algorithm. This means that the [COMPRESSED](../innodb-compressed-row-format/index) row format has less compression options than InnoDB page compression does.

 In general, InnoDB page compression is superior to the [COMPRESSED](../innodb-compressed-row-format/index) row format.

 Comparison with Storage Engine-Independent Column Compression
-------------------------------------------------------------

 * See [Storage Engine-Independent Column Compression - Comparison with InnoDB Page Compression](../storage-engine-independent-column-compression/index#comparison-with-innodb-page-compression).

 Configuring the InnoDB Page Compression Algorithm
-------------------------------------------------

 There is not currently a table option to set different InnoDB page compression algorithms for individual tables.

 However, the server-wide InnoDB page compression algorithm can be configured by setting the [innodb\_compression\_algorithm](../innodb-system-variables/index#innodb_compression_algorithm) system variable.

 When this system variable is changed, the InnoDB page compression algorithm does not change for existing pages that were already compressed with a different InnoDB page compression algorithm. InnoDB is able to handle this situation without issues, because every page in an InnoDB tablespace contains metadata about the InnoDB page compression algorithm in the page header. This means that InnoDB supports having uncompressed pages and pages compressed with different InnoDB page compression algorithms in the same InnoDB tablespace at the same time.

 This system variable can be set to one of the following values:

 


| System Variable Value | Description |
| --- | --- |
| `none` | Pages are not compressed. This is the default value in [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) and before, and [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) and before. |
| `zlib` | Pages are compressed using the bundled [zlib](https://www.zlib.net/) compression algorithm. This is the default value in [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) and later, and [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/) and later. |
| `lz4` | Pages are compressed using the [lz4](https://code.google.com/p/lz4/) compression algorithm. |
| `lzo` | Pages are compressed using the [lzo](http://www.oberhumer.com/opensource/lzo/) compression algorithm. |
| `lzma` | Pages are compressed using the [lzma](http://tukaani.org/xz/) compression algorithm. |
| `bzip2` | Pages are compressed using the [bzip2](http://www.bzip.org/) compression algorithm. |
| `snappy` | Pages are compressed using the [snappy](http://google.github.io/snappy/) algorithm. |

 
However, on many distributions, the standard MariaDB builds do not support all InnoDB page compression algorithms by default. From [MariaDB 10.7](../what-is-mariadb-107/index), algorithms can be [installed as a plugin](../compression-plugins/index).

 This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_compression_algorithm='lzma';

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_compression_algorithm=lzma

```

### Checking Supported InnoDB Page Compression Algorithms

 On many distributions, the standard MariaDB builds do not support all InnoDB page compression algorithms by default. Therefore, if you want to use a specific InnoDB page compression algorithm, then you should check whether your MariaDB build supports it.

 The [zlib](https://www.zlib.net/) compression algorithm is always supported. From [MariaDB 10.7](../what-is-mariadb-107/index), algorithms can be [installed as a plugin](../compression-plugins/index).

 A MariaDB build's support for other InnoDB page compression algorithms can be checked by querying the following status variables with [SHOW GLOBAL STATUS](../show-status/index):

 


| Status Variable | Description |
| --- | --- |
| [Innodb\_have\_lz4](../innodb-server-status-variables/index#innodb_have_lz4) | Whether InnoDB supports the [lz4](https://code.google.com/p/lz4/) compression algorithm. |
| [Innodb\_have\_lzo](../innodb-server-status-variables/index#innodb_have_lzo) | Whether InnoDB supports the [lzo](http://www.oberhumer.com/opensource/lzo/) compression algorithm. |
| [Innodb\_have\_lzma](../innodb-server-status-variables/index#innodb_have_lzma) | Whether InnoDB supports the [lzma](http://tukaani.org/xz/) compression algorithm. |
| [Innodb\_have\_bzip2](../innodb-server-status-variables/index#innodb_have_bzip2) | Whether InnoDB supports the [bzip2](http://www.bzip.org/) compression algorithm. |
| [Innodb\_have\_snappy](../innodb-server-status-variables/index#innodb_have_snappy) | Whether InnoDB supports the [snappy](http://google.github.io/snappy/) compression algorithm. |

 
For example:

 
```
SHOW GLOBAL STATUS WHERE Variable_name IN (
   'Innodb_have_lz4', 
   'Innodb_have_lzo', 
   'Innodb_have_lzma', 
   'Innodb_have_bzip2', 
   'Innodb_have_snappy'
);
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| Innodb_have_lz4    | OFF   |
| Innodb_have_lzo    | OFF   |
| Innodb_have_lzma   | ON    |
| Innodb_have_bzip2  | OFF   |
| Innodb_have_snappy | OFF   |
+--------------------+-------+

```

### Adding Support for an InnoDB Page Compression Algorithm

 On many distributions, the standard MariaDB builds do not support all InnoDB page compression algorithms by default. From [MariaDB 10.7](../what-is-mariadb-107/index), algorithms can be [installed as a plugin](../compression-plugins/index), but in earlier versions, if you want to use certain InnoDB page compression algorithms, then you may need to do the following:

 * Download the package for the desired compression library from the above links.
* Install the package for the desired compression library.
* Compile MariaDB from the source distribution.

 The general steps for compiling MariaDB are:

 * Download and unpack the source code distribution:

 
```
wget https://downloads.mariadb.com/MariaDB/mariadb-10.4.8/source/mariadb-10.4.8.tar.gz
tar -xvzf mariadb-10.4.8.tar.gz
cd mariadb-10.4.8/

```

* Configure the build using [cmake](../generic-build-instructions/index#using-cmake):

 
```
cmake .

```

* Check [CMakeCache.txt](https://cmake.org/runningcmake/) to confirm that it has found the desired compression library on your system.

 * Compile the build:

 
```
make

```

* Either install the build:

 
```
make install

```

Or make a package to install:

 
```
make package

```

See [Compiling MariaDB From Source](../compiling-mariadb-from-source/index) for more information.

 Enabling InnoDB Page Compression
--------------------------------

 InnoDB page compression is not enabled by default. However, InnoDB page compression can be enabled for just individual InnoDB tables or it can be enabled for all new InnoDB tables by default.

 InnoDB page compression is also only supported if the InnoDB table is in a [file per-table](../innodb-file-per-table-tablespaces/index) tablespace. Therefore, the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable must be set to `ON` to use InnoDB page compression.

 InnoDB page compression is only supported if the InnoDB table uses the `Barracuda` [file format](../xtradbinnodb-file-format/index).Therefore, in [MariaDB 10.1](../what-is-mariadb-101/index) and before, the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable must be set to `Barracuda` to use InnoDB page compression.

 InnoDB page compression is also only supported if the InnoDB table's [row format](../innodb-row-formats-overview/index) is [COMPACT](../innodb-compact-row-format/index) or [DYNAMIC](../innodb-dynamic-row-format/index).

 ### Enabling InnoDB Page Compression by Default

 In [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) and later, InnoDB page compression can be enabled for all new InnoDB tables by default by setting the [innodb\_compression\_default](../innodb-system-variables/index#innodb_compression_default) system variable to `ON`.

 This system variable can be set to one of the following values:

 


| System Variable Value | Description |
| --- | --- |
| `OFF` | New InnoDB tables do not use InnoDB page compression. This is the default value. |
| `ON` | New InnoDB tables use InnoDB page compression. |

 
This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_compression_default=ON;

```

This system variable's session value can be changed dynamically with [SET SESSION](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

SET GLOBAL innodb_default_row_format='dynamic';

SET GLOBAL innodb_compression_algorithm='lzma';

SET SESSION  innodb_compression_default=ON;

CREATE TABLE users (
   user_id int not null, 
   b varchar(200), 
   primary key(user_id)
) 
   ENGINE=InnoDB;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_compression_default=ON

```

### Enabling InnoDB Page Compression for Individual Tables

 InnoDB page compression can be enabled for individual tables by setting the [PAGE\_COMPRESSED](../create-table/index#page_compressed) table option to `1`. For example:

 
```
SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

SET GLOBAL innodb_default_row_format='dynamic';

SET GLOBAL innodb_compression_algorithm='lzma';

CREATE TABLE users (
   user_id int not null, 
   b varchar(200), 
   primary key(user_id)
) 
   ENGINE=InnoDB
   PAGE_COMPRESSED=1;

```

Configuring the Compression Level
---------------------------------

 Some InnoDB page compression algorithms support a compression level option, which configures how the InnoDB page compression algorithm will balance speed and compression.

 The compression level's supported values range from `1` to `9`. The range goes from the fastest to the most compact, which means that `1` is the fastest and `9` is the most compact.

 Only the following InnoDB page compression algorithms currently support compression levels:

 * [zlib](https://www.zlib.net/)
* [lzma](http://tukaani.org/xz/)

 If an InnoDB page compression algorithm does not support compression levels, then it ignores any provided compression level value.

 ### Configuring the Default Compression Level

 The default compression level can be configured by setting the [innodb\_compression\_level](../innodb-system-variables/index#innodb_compression_level) system variable.

 This system variable's default value is `6`.

 This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_compression_level=9;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_compression_level=9

```

### Configuring the Compression Level for Individual Tables

 The compression level for individual tables can also be configured by setting the [PAGE\_COMPRESSION\_LEVEL](../create-table/index#page_compression_level) table option for the table. For example:

 
```
SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

SET GLOBAL innodb_default_row_format='dynamic';

SET GLOBAL innodb_compression_algorithm='lzma';

CREATE TABLE users (
   user_id int not null, 
   b varchar(200), 
   primary key(user_id)
) 
   ENGINE=InnoDB
   PAGE_COMPRESSED=1
   PAGE_COMPRESSION_LEVEL=9;

```

Configuring the Failure Threshold and Maximum Padding
-----------------------------------------------------

 InnoDB page compression can encounter compression failures.

 InnoDB page compression's failure threshold can be configured. If InnoDB encounters more compression failures than the failure threshold, then it pads pages with zeroed out bytes before attempting to compress them as a way to reduce failures. If the failure rate stays above the failure threshold, then InnoDB pads pages with more zeroed out bytes in 128 byte increments. 

 InnoDB page compression's maximum padding can also be configured.

 ### Configuring the Failure Threshold

 The failure threshold can be configured by setting the [innodb\_compression\_failure\_threshold\_pct](../innodb-system-variables/index#innodb_compression_failure_threshold_pct) system variable.

 This system variable's supported values range from `0` to `100`.

 This system variable's default value is `5`.

 This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_compression_failure_threshold_pct=10;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_compression_failure_threshold_pct=10

```

### Configuring the Maximum Padding

 The maximum padding can be configured by setting the [innodb\_compression\_pad\_pct\_max](../innodb-system-variables/index#innodb_compression_pad_pct_max) system variable.

 This system variable's supported values range from `0` to `75`.

 This system variable's default value is `50`.

 This system variable can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_compression_pad_pct_max=75;

```

This system variable can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_compression_pad_pct_max=75

```

Saving Storage Space with Sparse Files
--------------------------------------

 When InnoDB page compression is used, InnoDB may still write the compressed page to the tablespace file with the original size of the uncompressed page, which would be equivalent to the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable. This is done by design, because when InnoDB's I/O code needs to read the page from disk, it can only read the full page size. However, this is obviously not optimal.

 On file systems that support sparse files, this problem is solved by writing the tablespace file as a sparse file using the *punch hole* technique. With the *punch hole* technique, InnoDB will only write the actual compressed page size to the tablespace file, aligned to sector size. The rest of the page is trimmed.

 This *punch hole* technique allows InnoDB to read the compressed page from disk as the full page size, even though the compressed page really takes up less space on the file system.

 There are some potential disadvantages to using sparse files:

 * Some utilities may require special options in order to handle sparse files in an efficient manner.
* Most existing file systems are slow to [unlink()](https://linux.die.net/man/2/unlink) sparse files. As a consequence, if a tablespace file is a sparse file, then dropping the table can be very slow.

 ### Sparse File Support on Linux

 On Linux, the following file systems support sparse files:

 * `ext3`
* `ext4`
* `xfs`
* `btrfs`
* `nvmfs`

 On Linux, file systems need to support the [fallocate()](https://linux.die.net/man/2/fallocate) system call with the `FALLOC_FL_PUNCH_HOLE` and `FALLOC_FL_KEEP_SIZE` flags. For example:

 
```
fallocate(file_handle, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, file_offset, remainder_len);

```

Some Linux utilities may require special options in order to work with sparse files efficiently. For example:

 * The [ls](https://linux.die.net/man/1/ls) utility will report the non-sparse size of the tablespace file when executed with default behavior, but `[ls -s](https://linux.die.net/man/1/ls)` will report the actual amount of storage allocated for the tablespace file.
* The [cp](https://linux.die.net/man/1/cp) utility is pretty good at auto-detecting sparse files, but it also provides the [cp --sparse=always](https://linux.die.net/man/1/cp) and [cp --sparse=never](https://linux.die.net/man/1/cp) options, if the auto-detection is not desired.
* The [tar](https://linux.die.net/man/1/tar) utility will archive sparse files with their non-sparse size when executed with default behavior, but [tar --sparse](https://linux.die.net/man/1/tar) will auto-detect sparse files, and archive them with their sparse size.

 ### Sparse File Support on Windows

 On Windows, the following file systems support sparse files:

 * `NTFS`

 On Windows, file systems need to support the [DeviceIoControl()](https://docs.microsoft.com/en-us/windows/win32/api/ioapiset/nf-ioapiset-deviceiocontrol) function with the [FSCTL\_SET\_SPARSE](https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-fsctl_set_sparse) and [FSCTL\_SET\_ZERO\_DATA](https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-fsctl_set_zero_data) control codes. For example:

 
```
DeviceIoControl(file_handle, FSCTL_SET_SPARSE, inbuf, inbuf_size, 
   outbuf, outbuf_size,  NULL, &overlapped)
...
DeviceIoControl(file_handle, FSCTL_SET_ZERO_DATA, inbuf, inbuf_size, 
   outbuf, outbuf_size,  NULL, &overlapped)

```

### Configuring InnoDB to use Sparse Files

 In [MariaDB 10.3](../what-is-mariadb-103/index) and later, InnoDB uses the *punch hole* technique to create sparse files used automatically when the underlying file system supports sparse files.

 In [MariaDB 10.2](../what-is-mariadb-102/index) and before, InnoDB can be configured to use the *punch hole* technique to create sparse files by configuring the [innodb\_use\_trim](../innodb-system-variables/index#innodb_use_trim) and [innodb\_use\_fallocate](../innodb-system-variables/index#innodb_use_fallocate) system variables. These system variables can be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
...
innodb_use_trim=ON
innodb_use_fallocate=ON

```

Optimized for Flash Storage
---------------------------

 InnoDB page compression was designed to be optimized on solid state drives (SSDs) and other flash storage.

 InnoDB page compression was originally developed by collaborating with [Fusion-io](http://fusionio.com). As a consequence, it was originally designed to work best on [FusionIO devices](../fusion-io-introduction/index) using [NVMFS](https://ieeexplore.ieee.org/document/6558434). [Fusion-io](http://fusionio.com) has since been acquired by [Western Digital](https://www.westerndigital.com/), and they have decided not to continue supporting [NVMFS](https://ieeexplore.ieee.org/document/6558434).

 However, InnoDB page compression is still likely to be most optimized on solid state drives (SSDs) and other flash storage.

 InnoDB page compression works without any issues on hard disk drives (HDDs). However, since its compression relies on the use of sparse files, the data may be somewhat fragmented on disk. This fragmentation may hurt performance on HDDs, since they handle random reads and writes much more slowly than flash storage.

 Configuring InnoDB Page Flushing
--------------------------------

 With InnoDB page compression, pages are compressed when they are flushed to disk. Therefore, it can be helpful to optimize the configuration of InnoDB's page flushing. See [InnoDB Page Flushing](../innodb-page-flushing/index) for more information.

 Monitoring InnoDB Page Compression
----------------------------------

 InnoDB page compression can be monitored by querying the following status variables with [SHOW GLOBAL STATUS](../show-status/index):

 


| Status Variable | Description |
| --- | --- |
| [Innodb\_page\_compression\_saved](../xtradbinnodb-server-status-variables/index#innodb_page_compression_saved) | Bytes saved by compression |
| [Innodb\_page\_compression\_trim\_sect512](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect512) | Number of 512 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect1024](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect1024) | Number of 1024 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect2048](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect2048) | Number of 2048 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect4096](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect4096) | Number of 4096 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect8192](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect8192) | Number of 8192 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect16384](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect16384) | Number of 16384 sectors trimmed |
| [Innodb\_page\_compression\_trim\_sect32768](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect32768) | Number of 32768 sectors trimmed |
| [Innodb\_num\_pages\_page\_compressed](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_compressed) | Number of pages compressed |
| [Innodb\_num\_page\_compressed\_trim\_op](../xtradbinnodb-server-status-variables/index#innodb_num_page_compressed_trim_op) | Number of trim operations |
| [Innodb\_num\_page\_compressed\_trim\_op\_saved](../xtradbinnodb-server-status-variables/index#innodb_num_page_compressed_trim_op_saved) | Number of trim operations saved |
| [Innodb\_num\_pages\_page\_decompressed](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_decompressed) | Number of pages decompressed |
| [Innodb\_num\_pages\_page\_compression\_error](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_compression_error) | Number of compression errors |

 
With InnoDB page compression, a page is only compressed when it is flushed to disk. This means that if you are monitoring InnoDB page compression via these status variables, then the status variables values will only get incremented when the dirty pages are flushed to disk, which does not necessarily happen immediately. For example:

 
```
CREATE TABLE `tab` (
     `id` int(11) NOT NULL,
     `str` varchar(50) DEFAULT NULL,
     PRIMARY KEY (`id`)
   ) ENGINE=InnoDB;
 
INSERT INTO tab VALUES (1, 'str1');

SHOW GLOBAL STATUS LIKE 'Innodb_num_pages_page_compressed';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_num_pages_page_compressed | 0     |
+----------------------------------+-------+
 
SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

SET GLOBAL innodb_default_row_format='dynamic';

SET GLOBAL innodb_compression_algorithm='lzma';
 
ALTER TABLE tab PAGE_COMPRESSED=1;

SHOW GLOBAL STATUS LIKE 'Innodb_num_pages_page_compressed';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_num_pages_page_compressed | 0     |
+----------------------------------+-------+
 
SELECT SLEEP(10);
+-----------+
| SLEEP(10) |
+-----------+
|         0 |
+-----------+
 
SHOW GLOBAL STATUS LIKE 'Innodb_num_pages_page_compressed';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_num_pages_page_compressed | 3     |
+----------------------------------+-------+

```

Compatibility with Backup Tools
-------------------------------

 [Mariabackup](../mariabackup/index) supports InnoDB page compression.

 [Percona XtraBackup](../percona-xtrabackup/index) does not support InnoDB page compression.

 Acknowledgements
----------------

 * InnoDB page compression was developed by collaborating with [Fusion-io](http://fusionio.com). Special thanks especially to Dhananjoy Das and Torben Mathiasen.

 See Also
--------

 * [Storage-Engine Independent Column Compression](../storage-engine-independent-column-compression/index)
* [Atomic Write Support](../atomic-write-support/index)
* [MariaDB Introduces Atomic Writes](https://blog.mariadb.org/mariadb-introduces-atomic-writes/)
* [Small Datum: Third day with InnoDB transparent page compression](http://smalldatum.blogspot.com/2015/09/third-day-with-innodb-transparent-page.html)
* [InnoDB holepunch compression vs the filesystem in MariaDB 10.1](https://blog.mariadb.org/innodb-holepunch-compression-vs-the-filesystem-in-mariadb-10-1/)
* [Significant performance boost with new MariaDB page compression on FusionIO](https://blog.mariadb.org/significant-performance-boost-with-new-mariadb-page-compression-on-fusionio/)
* [INFLOW '14: NVM Compression—Hybrid Flash-Aware Application Level Compression](https://www.usenix.org/conference/inflow14/workshop-program/presentation/das)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-page-compression/>

Information Schema InnoDB Tables
=================================

   List of Information Schema tables specifically related to [InnoDB](../innodb/index). Tables that are specific to XtraDB shares with InnoDB are listed in [Information Schema XtraDB Tables](../information-schema-xtradb-tables/index).

  

| Title | Description |
| --- | --- |
|  [Information Schema INNODB\_BUFFER\_PAGE Table](../information-schema-innodb_buffer_page-table/index) |  Buffer pool page information.  |
|  [Information Schema INNODB\_BUFFER\_PAGE\_LRU Table](../information-schema-innodb_buffer_page_lru-table/index) |  Buffer pool pages and their eviction order.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES Table](../information-schema-innodb_buffer_pool_pages-table/index) |  XtraDB buffer pool page information.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES\_BLOB Table](../information-schema-innodb_buffer_pool_pages_blob-table/index) |  XtraDB buffer pool blob pages.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES\_INDEX Table](../information-schema-innodb_buffer_pool_pages_index-table/index) |  XtraDB buffer pool index pages.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_STATS Table](../information-schema-innodb_buffer_pool_stats-table/index) |  InnoDB buffer pool information.  |
|  [Information Schema INNODB\_CHANGED\_PAGES Table](../information-schema-innodb_changed_pages-table/index) |  Modified pages from the bitmap file data.  |
|  [Information Schema INNODB\_CMP and INNODB\_CMP\_RESET Tables](../information-schema-innodb_cmp-and-innodb_cmp_reset-tables/index) |  XtraDB/InnoDB compression performances with different page sizes.  |
|  [Information Schema INNODB\_CMPMEM and INNODB\_CMPMEM\_RESET Tables](../information-schema-innodb_cmpmem-and-innodb_cmpmem_reset-tables/index) |  Number of InnoDB compressed pages of different page sizes.  |
|  [Information Schema INNODB\_CMP\_PER\_INDEX and INNODB\_CMP\_PER\_INDEX\_RESET Tables](../information-schema-innodb-tables-information-schema-innodb_cmp_per_index-an/index) |  XtraDB/InnoDB compression performances for different indexes and tables.  |
|  [Information Schema INNODB\_FT\_BEING\_DELETED Table](../information-schema-innodb_ft_being_deleted-table/index) |  Fulltext being deleted.  |
|  [Information Schema INNODB\_FT\_CONFIG Table](../information-schema-innodb_ft_config-table/index) |  InnoDB fulltext metadata.  |
|  [Information Schema INNODB\_FT\_DEFAULT\_STOPWORD Table](../information-schema-innodb_ft_default_stopword-table/index) |  Default InnoDB stopwords.  |
|  [Information Schema INNODB\_FT\_DELETED Table](../information-schema-innodb_ft_deleted-table/index) |  Deleted InnoDB fulltext rows.  |
|  [Information Schema INNODB\_FT\_INDEX\_CACHE Table](../information-schema-innodb_ft_index_cache-table/index) |  Newly added fulltext row information.  |
|  [Information Schema INNODB\_FT\_INDEX\_TABLE Table](../information-schema-innodb_ft_index_table-table/index) |  InnoDB fulltext information.  |
|  [Information Schema INNODB\_LOCK\_WAITS Table](../information-schema-innodb_lock_waits-table/index) |  Blocked InnoDB transactions.  |
|  [Information Schema INNODB\_LOCKS Table](../information-schema-innodb_locks-table/index) |  InnoDB lock information.  |
|  [Information Schema INNODB\_METRICS Table](../information-schema-innodb_metrics-table/index) |  InnoDB performance metrics.  |
|  [Information Schema INNODB\_MUTEXES Table](../information-schema-innodb_mutexes-table/index) |  Monitor mutex waits.  |
|  [Information Schema INNODB\_SYS\_COLUMNS Table](../information-schema-innodb_sys_columns-table/index) |  InnoDB column information.  |
|  [Information Schema INNODB\_SYS\_DATAFILES Table](../information-schema-innodb_sys_datafiles-table/index) |  InnoDB tablespace paths.  |
|  [Information Schema INNODB\_SYS\_FIELDS Table](../information-schema-innodb_sys_fields-table/index) |  Fields part of an InnoDB index.  |
|  [Information Schema INNODB\_SYS\_FOREIGN Table](../information-schema-innodb_sys_foreign-table/index) |  InnoDB foreign key information.  |
|  [Information Schema INNODB\_SYS\_FOREIGN\_COLS Table](../information-schema-innodb_sys_foreign_cols-table/index) |  Foreign key column information.  |
|  [Information Schema INNODB\_SYS\_INDEXES Table](../information-schema-innodb_sys_indexes-table/index) |  InnoDB index information.  |
|  [Information Schema INNODB\_SYS\_SEMAPHORE\_WAITS Table](../information-schema-innodb_sys_semaphore_waits-table/index) |  Information about current semaphore waits.  |
|  [Information Schema INNODB\_SYS\_TABLES Table](../information-schema-innodb_sys_tables-table/index) |  InnoDB table information.  |
|  [Information Schema INNODB\_SYS\_TABLESPACES Table](../information-schema-innodb_sys_tablespaces-table/index) |  InnoDB tablespace information.  |
|  [Information Schema INNODB\_SYS\_TABLESTATS Table](../information-schema-innodb_sys_tablestats-table/index) |  InnoDB status for high-level performance monitoring.  |
|  [Information Schema INNODB\_SYS\_VIRTUAL Table](../information-schema-innodb_sys_virtual-table/index) |  Information about base columns of virtual columns.  |
|  [Information Schema INNODB\_TABLESPACES\_ENCRYPTION Table](../information-schema-innodb_tablespaces_encryption-table/index) |  Encryption metadata for InnoDB tablespaces.  |
|  [Information Schema INNODB\_TABLESPACES\_SCRUBBING Table](../information-schema-innodb_tablespaces_scrubbing-table/index) |  Data scrubbing information.  |
|  [Information Schema INNODB\_TRX Table](../information-schema-innodb_trx-table/index) |  Currently-executing InnoDB locks.  |
|  [Information Schema TEMP\_TABLES\_INFO Table](../information-schema-temp_tables_info-table/index) |  Information about active InnoDB temporary tables.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb-tables/>

InnoDB Monitors
===============

     The [InnoDB](../innodb/index) Monitor refers to particular kinds of monitors included in MariaDB and since the early versions of MySQL.

 There are four types: the standard InnoDB monitor, the InnoDB Lock Monitor, InnoDB Tablespace Monitor and the InnoDB Table Monitor.

 Standard InnoDB Monitor
-----------------------

 The standard InnoDB Monitor returns extensive InnoDB information, particularly lock, semaphore, I/O and buffer activity:

 To enable the standard InnoDB Monitor, from [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), set the [innodb\_status\_output](../xtradbinnodb-server-system-variables/index#innodb_status_output) system variable to 1. Before [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), running the following statement was the method used:

 
```
CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;

```

To disable the standard InnoDB monitor, either set the system variable to zero, or, before [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), drop the table

 
```
DROP TABLE innodb_monitor;

```


The CREATE TABLE and DROP TABLE method of enabling and disabling the InnoDB Monitor has been deprecated, and may be removed in a future version of MariaDB.

 
For a description of the output, see [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index).

 InnoDB Lock Monitor
-------------------

 The InnoDB Lock Monitor displays additional lock information.

 To enable the InnoDB Lock Monitor, the standard InnoDB monitor must be enabled. Then, from [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), set the [innodb\_status\_output\_locks](../xtradbinnodb-server-system-variables/index#innodb_status_output_locks) system variable to 1. Before [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), running the following statement was the method used:

 
```
CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;

```

To disable the standard InnoDB monitor, either set the system variable to zero, or, before [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/), drop the table

 
```
DROP TABLE innodb_lock_monitor;

```


The CREATE TABLE and DROP TABLE method of enabling and disabling the InnoDB Lock Monitor has been deprecated, and may be removed in a future version of MariaDB.

 
InnoDB Tablespace Monitor
-------------------------

 
The InnoDB Tablespace Monitor is deprecated, and may be removed in a future version of MariaDB.

 
Enabling the Tablespace Monitor outputs a list of file segments in the shared tablespace to the error log, and validates the tablespace allocation data structures.

 To enable the Tablespace Monitor, run the following statement:

 
```
CREATE TABLE innodb_tablespace_monitor (a INT) ENGINE=INNODB;

```

To disable it, drop the table:

 
```
DROP TABLE innodb_tablespace_monitor;

```

InnoDB Table Monitor
--------------------

 
The InnoDB Table Monitor is deprecated, and may be removed in a future version of MariaDB.

 
Enabling the Table Monitor outputs the contents of the InnoDB internal data dictionary to the error log every fifteen seconds.

 To enable the Table Monitor, run the following statement:

 
```
CREATE TABLE innodb_table_monitor (a INT) ENGINE=INNODB;

```

To disable it, drop the table:

 
```
DROP TABLE innodb_table_monitor;

```

SHOW ENGINE INNODB STATUS
-------------------------

 The [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index) statement can be used to obtain the standard InnoDB Monitor output when required, rather than sending it to the error log. It will also display the InnoDB Lock Monitor information if the [innodb\_status\_output\_locks](../xtradbinnodb-server-system-variables/index#innodb_status_output_locks) system variable is set to `1`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-monitors/>

Locales Plugin
==============

    The `LOCALES` plugin creates the [LOCALES](../information-schema-locales-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. The plugin also adds the [SHOW LOCALES](../show-locales/index) statement.The table and statement can be queried to see all [locales](../server-locale/index) that are compiled into the server.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'locales';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = locales

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'locales';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.LOCALES;
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+
| ID  | NAME  | DESCRIPTION                         | MAX_MONTH_NAME_LENGTH | MAX_DAY_NAME_LENGTH | DECIMAL_POINT | THOUSAND_SEP | ERROR_MESSAGE_LANGUAGE |
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+
|   0 | en_US | English - United States             |                     9 |                   9 | .             | ,            | english                |
|   1 | en_GB | English - United Kingdom            |                     9 |                   9 | .             | ,            | english                |
|   2 | ja_JP | Japanese - Japan                    |                     3 |                   3 | .             | ,            | japanese               |
|   3 | sv_SE | Swedish - Sweden                    |                     9 |                   7 | ,             |              | swedish                |
|   4 | de_DE | German - Germany                    |                     9 |                  10 | ,             | .            | german                 |
|   5 | fr_FR | French - France                     |                     9 |                   8 | ,             |              | french                 |
|   6 | ar_AE | Arabic - United Arab Emirates       |                     6 |                   8 | .             | ,            | english                |
|   7 | ar_BH | Arabic - Bahrain                    |                     6 |                   8 | .             | ,            | english                |
|   8 | ar_JO | Arabic - Jordan                     |                    12 |                   8 | .             | ,            | english                |
...
| 106 | no_NO | Norwegian - Norway                  |                     9 |                   7 | ,             | .            | norwegian              |
| 107 | sv_FI | Swedish - Finland                   |                     9 |                   7 | ,             |              | swedish                |
| 108 | zh_HK | Chinese - Hong Kong SAR             |                     3 |                   3 | .             | ,            | english                |
| 109 | el_GR | Greek - Greece                      |                    11 |                   9 | ,             | .            | greek                  |
| 110 | rm_CH | Romansh - Switzerland               |                     9 |                   9 | ,             | .            | english                |
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |

 
Options
-------

 ### `locales`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--locales=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/locales-plugin/>

InnoDB Encryption Overview
==========================

    MariaDB supports data-at-rest encryption for tables using the [InnoDB](../innodb/index) storage engines. When enabled, the server encrypts data when it writes it to and decrypts data when it reads it from the file system. You can [configure InnoDB encryption](../innodb-enabling-encryption/index) to automatically have all new InnoDB tables automatically encrypted, or specify encrypt per table.

 For encrypting data with the Aria storage engine, see [Encrypting Data for Aria](../encrypting-data-for-aria/index).

 Basic Configuration
-------------------

 Using data-at-rest encryption requires that you first configure an [Encryption Key Management](../encryption-key-management/index) plugin, such as the `[file\_key\_management](../file-key-management-encryption-plugin/index)` or `[aws\_key\_management](../aws-key-management-encryption-plugin/index)` plugins. MariaDB uses this plugin to store, retrieve and manage the various keys it uses when encrypting data to and decrypting data from the file system.

 Once you have the plugin configured, you need to set a few additional system variables to enable encryption on InnoDB and XtraDB tables, including `[innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables)`, `[innodb\_encrypt\_logs](../innodb-system-variables/index#innodb_encrypt_logs)`, `[innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads)`, and `[innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age)`.

 
```
[mariadb]
...

# File Key Management
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/encryption/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
file_key_management_encryption_algorithm = AES_CTR

# InnoDB/XtraDB Encryption
innodb_encrypt_tables = ON
innodb_encrypt_temporary_tables = ON
innodb_encrypt_log = ON
innodb_encryption_threads = 4
innodb_encryption_rotate_key_age = 1

```

For more information on system variables for encryption and other features, see the InnoDB [system variables](../innodb-system-variables/index) page.

 Finding Encrypted Tables
------------------------

 When using data-at-rest encryption with the InnoDB or XtraDB storage engines, it is not necessary that you encrypt every table in your database. You can check which tables are encrypted and which are not by querying the `[INNODB\_TABLESPACES\_ENCRYPTION](../information-schema-innodb_tablespaces_encryption-table/index)` table in the [Information Schema](../information-schema/index). This table provides information on which tablespaces are encrypted, which encryption key each tablespace is encrypted with, and whether the background encryption threads are currently working on the tablespace. Since the [system tablespace](../innodb-system-tablespaces/index) can also contain tables, it can be helpful to join the `[INNODB\_TABLESPACES\_ENCRYPTION](../information-schema-innodb_tablespaces_encryption-table/index)` table with the `[INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index)` table to find out the encryption status of each specific table, rather than each tablespace. For example:

 
```
SELECT st.SPACE, st.NAME, te.ENCRYPTION_SCHEME, te.ROTATING_OR_FLUSHING
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION te
JOIN information_schema.INNODB_SYS_TABLES st
   ON te.SPACE = st.SPACE \G
*************************** 1. row ***************************
               SPACE: 0
                NAME: SYS_DATAFILES
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 2. row ***************************
               SPACE: 0
                NAME: SYS_FOREIGN
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 3. row ***************************
               SPACE: 0
                NAME: SYS_FOREIGN_COLS
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 4. row ***************************
               SPACE: 0
                NAME: SYS_TABLESPACES
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 5. row ***************************
               SPACE: 0
                NAME: SYS_VIRTUAL
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 6. row ***************************
               SPACE: 0
                NAME: db1/default_encrypted_tab1
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 7. row ***************************
               SPACE: 416
                NAME: db1/default_encrypted_tab2
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 8. row ***************************
               SPACE: 402
                NAME: db1/tab
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 9. row ***************************
               SPACE: 185
                NAME: db1/tab1
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 10. row ***************************
               SPACE: 184
                NAME: db1/tab2
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 11. row ***************************
               SPACE: 414
                NAME: db1/testgb2
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 12. row ***************************
               SPACE: 4
                NAME: mysql/gtid_slave_pos
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 13. row ***************************
               SPACE: 2
                NAME: mysql/innodb_index_stats
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 14. row ***************************
               SPACE: 1
                NAME: mysql/innodb_table_stats
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
*************************** 15. row ***************************
               SPACE: 3
                NAME: mysql/transaction_registry
   ENCRYPTION_SCHEME: 1
ROTATING_OR_FLUSHING: 0
15 rows in set (0.000 sec)

```

Redo Logs
---------

 Using data-at-rest encryption with InnoDB, the `[innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables)` system variable only encrypts the InnoDB tablespaces. In order to also encrypt the InnoDB Redo Logs, you also need to set the `[innodb\_encrypt\_logs](innodb-server-system-variables#innodb_encrypt_logs)` system variable.

 Beginning in [MariaDB 10.4](../what-is-mariadb-104/index), where the encryption key management plugin supports key rotation the InnoDB Redo Log can also rotate encryption keys. In previous releases, the Redo Log can only use the first encryption key. 

 See Also
--------

 * [Data at Rest Encryption](../data-at-rest-encryption/index)
* [Why Encrypt MariaDB Data?](../why-encrypt-mariadb-data/index)
* [Encryption Key Management](../encryption-key-management/index)
* [Information Schema INNODB\_TABLESPACES\_ENCRYPTION table](../information-schema-innodb_tablespaces_encryption-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-encryption-overview/>

myisamlog
=========

    `myisamlog` processes and returns the contents of a [MyISAM log file](../myisam-log/index).

 Invoke `myisamlog` like this:

 
```
shell> myisamlog [options] [log_file [tbl_name] ...]
shell> isamlog [options] [log_file [tbl_name] ...]

```

The default operation is update (`-u`). If a recovery is done (`-r`), all writes and possibly updates and deletes are done and errors are only counted. The default log file name is `myisam.log` for `myisamlog` and `isam.log` for `isamlog` if no `log_file` argument is given. If tables are named on the command line, only those tables are updated.

 `myisamlog` supports the following options:

 


| Option | Description |
| --- | --- |
| `-?`, `-I` | Display a help message and exit. |
| `-c *N*` | Execute only *`N`* commands. |
| `-f *N*` | Specify the maximum number of open files. |
| `-i` | Display extra information before exiting. |
| `-o *offset*` | Specify the starting offset. |
| `-p *N*` | Remove *`N`* components from path. |
| `-r` | Perform a recovery operation. |
| `-R *record\_pos\_file record\_pos*` | Specify record position file and record position. |
| `-u` | Displays update operations. |
| `-v` | Verbose mode. Print more output about what the program does. This option can be given multiple times (*-vv*, *-vvv*) to produce more and more output. |
| `-w *write\_file*` | Specify the write file. |
| `-V` | Display version information. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisamlog/>

InnoDB Lock Modes
=================

     Locks are acquired by a transaction to prevent concurrent transactions from modifying, or even reading, some rows or ranges of rows. This is done to make sure that concurrent write operations never collide.

 [InnoDB](../innodb/index) supports a number of lock modes.

 Shared and Exclusive Locks
--------------------------

 The two standard row-level locks are *share locks*(S) and *exclusive locks*(X).

 A shared lock is obtained to read a row, and allows other transactions to read the locked row, but not to write to the locked row. Other transactions may also acquire their own shared locks.

 An exclusive lock is obtained to write to a row, and stops other transactions from locking the same row. It's specific behavior depends on the [isolation level](../set-transaction-isolation-level/index#isolation-level); the default (REPEATABLE READ), allows other transactions to read from the exclusively locked row.

 Intention Locks
---------------

 InnoDB also permits table locking, and to allow locking at both table and row level to co-exist gracefully, a series of locks called *intention locks* exist. 

 An *intention shared lock*(IS) indicates that a transaction intends to set a shared lock.

 An *intention exclusive lock*(IX) indicates that a transaction intends to set an exclusive lock.

 Whether a lock is granted or not can be summarised as follows:

 * An X lock is not granted if any other lock (X, S, IX, IS) is held.
* An S lock is not granted if an X or IX lock is held. It is granted if an S or IS lock is held.
* An IX lock is not granted if in X or S lock is held. It is granted if an IX or IS lock is held.
* An IS lock is not granted if an X lock is held. It is granted if an S, IX or IS lock is held.

 AUTO\_INCREMENT Locks
---------------------

 Locks are also required for auto-increments - see [AUTO\_INCREMENT handling in InnoDB](../auto_increment-handling-in-innodb/index).

 Gap Locks
---------

 With the default [isolation level](../set-transaction-isolation-level/index#isolation-level), `REPEATABLE READ`, and, until [MariaDB 10.4](../what-is-mariadb-104/index), the default setting of the [innodb\_locks\_unsafe\_for\_binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog) variable, a method called gap locking is used. When InnoDB sets a shared or exclusive lock on a record, it's actually on the index record. Records will have an internal InnoDB index even if they don't have a unique index defined. At the same time, a lock is held on the gap before the index record, so that another transaction cannot insert a new index record in the gap between the record and the preceding record.

 The gap can be a single index value, multiple index values, or not exist at all depending on the contents of the index.

 If a statement uses all the columns of a unique index to search for unique row, gap locking is not used. 

 Similar to the shared and exclusive intention locks described above, there can be a number of types of gap locks. These include the shared gap lock, exclusive gap lock, intention shared gap lock and intention exclusive gap lock.

 Gap locks are disabled if the [innodb\_locks\_unsafe\_for\_binlog](../innodb-system-variables/index#innodb_locks_unsafe_for_binlog) system variable is set (until [MariaDB 10.4](../what-is-mariadb-104/index)), or the [isolation level](../set-transaction-isolation-level/index#isolation-level) is set to `READ COMMITTED`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-lock-modes/>

InnoDB - Unmaintained
======================

   Articles that apply only to old, unmaintained versions of MariaDB.

  

| Title | Description |
| --- | --- |
|  [Information Schema XtraDB Tables](../information-schema-xtradb-tables/index) |  All XtraDB-specific Information Schema tables.  |
|  [About XtraDB](../about-xtradb/index) |  XtraDB was an enhanced version of the InnoDB storage engine used until MariaDB 10.2.  |
|  [Using InnoDB Instead of XtraDB](../using-innodb-instead-of-xtradb/index) |  Using the InnoDB plugin instead of XtraDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-unmaintained/>

Optimizing MEMORY Tables
========================

    [MEMORY tables](../memory-storage-engine/index) are a good choice for data that needs to be accessed often, and is rarely updated. Being in memory, it's not suitable for critical data or for storage, but if data can be moved to memory for reading without needing to be regenerated often, if at all, it can provide a significant performance boost.

 The [MEMORY Storage Engine](../memory-storage-engine/index) has a key feature in that it permits its indexes to be either B-tree or Hash. Choosing the best index type can lead to better performance. See [Storage Engine index types](../storage-engine-index-types/index) for more on the characteristics of each index type.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-memory-tables/>

Numeric vs String Fields
========================

    A large numeric value is stored in far fewer bytes than the equivalent string value. It is therefore faster to move and compare numeric data, so it's best to choose numeric columns for unique id's and other similar fields.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numeric-vs-string-fields/>

Transaction Coordinator Log Overview
====================================

    The transaction coordinator log (tc\_log) is used to coordinate transactions that affect multiple [XA-capable](../xa-transactions/index) [storage engines](../storage-engines/index). If you have two or more XA-capable storage engines enabled, then a transaction coordinator log must be available.

 Types of Transaction Coordinator Logs
-------------------------------------

 There are currently two implementations of the transaction coordinator log:

 * Binary log-based transaction coordinator log
* Memory-mapped file-based transaction coordinator log

 If the [binary log](../binary-log/index) is enabled on a server, then the server will use the binary log-based transaction coordinator log. Otherwise, it will use the memory-mapped file-based transaction coordinator log.

 ### Binary Log-Based Transaction Coordinator Log

 This transaction coordinator uses the [binary log](../binary-log/index), which is enabled by the `[log\_bin](../replication-and-binary-log-system-variables/index#log_bin)` server option.

 ### Memory-Mapped File-Based Transaction Coordinator Log

 This transaction coordinator uses the memory-mapped file defined by the `[--log-tc](../mysqld-options/index#-log-tc)` server option. The size is defined by the `[log\_tc\_size](../server-system-variables/index#log_tc_size)` system variable.

 Some facts about this log:

 * The log consists of a memory-mapped file that is divided into pages of 8KB size.
* The usable size of the first page is smaller because of the log header. There is a PAGE control structure for each page.
* Each page (or rather its PAGE control structure) can be in one of the three states - active, syncing, pool.
* There could be only one page in the active or syncing state, but many in the pool state - pool is a fifo queue.
* The usual lifecycle of a page is pool->active->syncing->pool.
* The "active" page is a page where new xid's are logged.
* The page stays active as long as the syncing slot is taken.
* The "syncing" page is being synced to disk. no new xid can be added to it.
* When the syncing is done the page is moved to a pool and an active page becomes "syncing".

 The result of such an architecture is a natural "commit grouping" - If commits are coming faster than the system can sync, they do not stall. Instead, all commits that came since the last sync are logged to the same "active" page, and they all are synced with the next - one - sync. Thus, thought individual commits are delayed, throughput is not decreasing.

 When an xid is added to an active page, the thread of this xid waits for a page's condition until the page is synced. When a syncing slot becomes vacant one of these waiters is awakened to take care of syncing. It syncs the page and signals all waiters that the page is synced. The waiters are counted, and a page may never become active again until waiters==0, which means that is all waiters from the previous sync have noticed that the sync was completed.

 Note that a page becomes "dirty" and has to be synced only when a new xid is added into it. Removing a xid from a page does not make it dirty - we don't sync xid removals to disk.

 #### Monitoring the Memory-Mapped File-Based Transaction Coordinator Log

 The memory-mapped transaction coordinator log can be monitored with the following status variables:

 * `[Tc\_log\_max\_pages\_used](../server-status-variables/index#tc_log_max_pages_used)`
* `[Tc\_log\_page\_size](../server-status-variables/index#tc_log_page_size)`
* `[Tc\_log\_page\_waits](../server-status-variables/index#tc_log_page_waits)`

 Heuristic Recovery with the Transaction Coordinator Log
-------------------------------------------------------

 One of the main purposes of the transaction coordinator log is in crash recovery. See [Heuristic Recovery with the Transaction Coordinator Log](../heuristic-recovery-with-the-transaction-coordinator-log/index) for more information about that.

 Known Issues
------------

 ### You must enable exactly N storage engines

 Prior to [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/), if you were using the memory-mapped file-based transaction coordinator log, and then if the server crashed and you changed the number of XA-capable storage engines that it loaded, then you could see errors like the following:

 
```
2018-11-30 23:08:49 140046048638848 [Note] Recovering after a crash using tc.log          
2018-11-30 23:08:49 140046048638848 [ERROR] Recovery failed! You must enable exactly 3 storage engines that support two-phase commit protocol
2018-11-30 23:08:49 140046048638848 [ERROR] Crash recovery failed. Either correct the problem (if it's, for example, out of memory error) and restart, or delete tc log and start mysqld with --tc-heuristic-recover={commit|rollback}
2018-11-30 23:08:49 140046048638848 [ERROR] Can't init tc log
2018-11-30 23:08:49 140046048638848 [ERROR] Aborting

```

To recover from this error, delete the file defined by the `[--log-tc](../mysqld-options/index#-log-tc)` server option, and then restart the server with the `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` option set.

 See [MDEV-9214](https://jira.mariadb.org/browse/MDEV-9214) for more information.

 ### Bad magic header in tc log

 If you are using the memory-mapped file-based transaction coordinator log, then it is possible to see errors like the following:

 
```
2018-09-19  4:29:31 0 [Note] Recovering after a crash using tc.log                                                               
2018-09-19  4:29:31 0 [ERROR] Bad magic header in tc log
2018-09-19  4:29:31 0 [ERROR] Crash recovery failed. Either correct the problem (if it's, for example, out of memory error) and restart, or delete tc log and start mysqld with --tc-heuristic-recover={commit|rollback}                                           
2018-09-19  4:29:31 0 [ERROR] Can't init tc log
2018-09-19  4:29:31 0 [ERROR] Aborting

```

This means that the header of the memory-mapped file-based transaction coordinator log is corrupt. To recover from this error, delete the file defined by the `[--log-tc](../mysqld-options/index#-log-tc)` server option, and then restart the server with the `[--tc-heuristic-recover](../mysqld-options/index#-tc-heuristic-recover)` option set.

 This issue is known to occur when using docker. In that case, the problem may be caused by using a MariaDB container version with a data directory from a different MariaDB or MySQL version. Therefore, some potential fixes are:

 * Pinning the docker instance to a specific MariaDB version in the docker compose file, so that it consistently uses the same version.
* Running [mariadb-upgrade](../mariadb-upgrade/index) to ensure that the data directory is upgraded to match the server version.

 See [this docker issue](https://github.com/docker-library/mariadb/issues/201) for more information.

 ### MariaDB Galera Cluster

 [MariaDB Galera Cluster](../galera-cluster/index) builds include a built-in plugin called `wsrep`. Prior to [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), this plugin was internally considered an [XA-capable](../xa-transactions/index) [storage engine](../storage-engines/index). Consequently, these [MariaDB Galera Cluster](../galera-cluster/index) builds have multiple XA-capable storage engines by default, even if the only "real" storage engine that supports external [XA transactions](../xa-transactions/index) enabled on these builds by default is [InnoDB](../innodb/index). Therefore, when using one these builds MariaDB would be forced to use a transaction coordinator log by default, which could have performance implications.

 For example, [MDEV-16509](https://jira.mariadb.org/browse/MDEV-16509) describes performance problems where [MariaDB Galera Cluster](../galera-cluster/index) actually performs better when the [binary log](../binary-log/index) is enabled. It is possible that this is caused by the fact that MariaDB is forced to use the memory-mapped file-based transaction coordinator log in this case, which may not perform as well.

 This became a bigger issue in [MariaDB 10.1](../what-is-mariadb-101/index) when the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch that powers [MariaDB Galera Cluster](../galera-cluster/index) was enabled on most MariaDB builds on Linux by default. Consequently, this built-in `wsrep` plugin would exist on those MariaDB builds on Linux by default. Therefore, MariaDB users might pay a performance penalty, even if they never actually intended to use the [MariaDB Galera Cluster](../galera-cluster/index) features included in [MariaDB 10.1](../what-is-mariadb-101/index).

 In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, the built-in `wsrep` plugin has been changed to a replication plugin. Therefore, it is no longer considered an [XA-capable](../xa-transactions/index) storage engine, so it no longer forces MariaDB to use a transaction coordinator log by default.

 See [MDEV-16442](https://jira.mariadb.org/browse/MDEV-16442) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/transaction-coordinator-log-overview/>

Optimizing String and Character Fields
======================================

    Comparing String Columns
------------------------

 When values from different columns are compared, the comparison runs more quickly when the columns are of the same character set and collation. If they are different, the strings need to be converted while the query runs. So, where possible, declare string columns using the same character set and collation when you may need to compare them.

 VARCHAR vs BLOB
---------------

 ORDER BY and GROUP BY clauses can generate temporary tables in memory (see [MEMORY Storage Engine](../memory-storage-engine/index)) if the original table doesn't contain any BLOB fields. If a column is less than 8KB, you can make use of a Binary VARCHAR rather than a BLOB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-string-and-character-fields/>

MariaDB 5.2 Replication Feature Preview
=======================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  
This page describes a *"feature preview release"* which previewed some replication-related features which are included in [MariaDB 5.3](../what-is-mariadb-53/index). If you would like to try out the features mentioned here, it is recommended that you use [MariaDB 5.3](../what-is-mariadb-53/index) ([download MariaDB 5.3 here](http://downloads.askmonty.org/mariadb/5.3/)) instead of the actual release described below. Likewise, the code is available in the [MariaDB 5.3 tree on Launchpad](https://launchpad.net/maria/5.3).

  About this release
------------------

 There has been quite a lot of interest in these features, and providing this feature preview release allows the developers to get more and earlier feedback, as well as allowing more users an early opportunity to evaluate the new features.

 This feature preview release is based on [MariaDB 5.2](../what-is-mariadb-52/index), adding a number of fairly isolated features that are considered complete and fairly well-tested. It is however not a stable or GA release, nor is it planned to be so.

 The stable release including these features will be **[MariaDB 5.3](../what-is-mariadb-53/index)**. That being said, we greatly welcome any feedback / bug reports, and will strive to fix any issues found and we will update the feature preview until [MariaDB 5.3](../what-is-mariadb-53/index) stable is ready.

 Download/Installation
---------------------

 These packages are generated the same way as "official" MariaDB releases. Please see the [main download pages](../downloads/index) for more detailed instructions on installation etc.

 The instructions below use the mirror [ftp.osuosl.org](http://ftp.osuosl.org/), but any of the MariaDB mirrors can be used by replacing the appropriate part of the URLs. See the [main download page](http://downloads.askmonty.org) for what mirrors are available.

 ### Debian/Ubuntu

 For Debian and Ubuntu, it is highly recommended to install from the repositories, using `apt-get`, `aptitude`, or other favorite package managers.

 First import the [public key](http://ftp.osuosl.org/pub/mariadb/PublicKey) with which the repositories are signed, so that `apt` can verify the integrity of the packages it downloads. For example like this:

 
```
wget -O- http://ftp.osuosl.org/pub/mariadb/PublicKey | sudo apt-key add -

```

Now add the appropriate repository. An easy way is to create a file called `mariadb-5.2-rpl.list` in `/etc/apt/sources.list.d/` with contents like this for Debian:

 
```
deb http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/debian squeeze main
deb-src http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/debian squeeze main

```

Or this for Ubuntu:

 
```
deb http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/ubuntu maverick main
deb-src http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/ubuntu maverick main

```

Replace "squeeze" or "maverick" in the examples above with the appropriate distribution name. Supported are "lenny" and "squeeze" for Debian, and "hardy", "jaunty", "karmic", "lucid", and "maverick" for Ubuntu.

 Now run

 
```
sudo apt-get update

```

The packages can now be installed with your package manager of choice, for example:

 
```
sudo apt-get install mariadb-server-5.2

```

(To manually download and install packages, browse the directories below <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/> - the .debs are in `debian/pool/` and `ubuntu/pool/`, respectively.)

 ### Generic Linux binary tarball

 Generic linux binary tarballs can be downloaded here:

 * i386 (32-bit): <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-bintar-hardy-x86/>
* amd64 (64-bit): <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-bintar-hardy-amd64/>

 ### Centos 5 RPMs

 * i386 (32-bit): <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-rpm-centos5-x86/>
* amd64 (64-bit): <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-rpm-centos5-amd64/>

 ### Windows (32-bit)

 * <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-zip-winxp-x86/>

 ### Source tarball

 * <http://ftp.osuosl.org/pub/mariadb/mariadb-5.2-rpl/misc/kvm-tarbake-jaunty-x86/>

 ### Launchpad bzr branch:

 * [`lp:~maria-captains/maria/mariadb-5.2-rpl`](https://code.launchpad.net/~maria-captains/maria/mariadb-5.2-rpl)

 New Features in the [MariaDB 5.2](../what-is-mariadb-52/index) replication feature preview
------------------------------------------------------------------------------------------

 Here is a summary of the new features included in this preview release. The headings link to more detailed information.

 ### [Group commit for the binary log](../group-commit/index)

 This preview release implements group commit which works when using XtraDB with the binary log enabled. (In previous MariaDB releases, and all MySQL releases at the time of writing, group commit works in InnoDB/XtraDB when the binary log is disabled, but stops working when the binary log is enabled).

 ### [Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT](../enhancements-for-start-transaction-with-consistent/index)

 `START TRANSACTION WITH CONSISTENT SNAPSHOT` now also works with the binary log. This means it is possible to obtain the binlog position corresponding to a transactional snapshot of the database without blocking any other queries. This is used by `mysqldump --single-transaction --master-data` to do a fully non-blocking backup which can be used to provision a new slave.

 `START TRANSACTION WITH CONSISTENT SNAPSHOT` now also works consistently between transactions involving more than one storage engine (currently XTraDB and PBXT support this).

 ### [Annotation of row-based replication events with the original SQL statement](../annotate_rows_log_event/index)

 When using row-based replication, the binary log does not contain SQL statements, only discrete single-row insert/update/delete *events*. This can make it harder to read mysqlbinlog output and understand where in an application a given event may have originated, complicating analysis and debugging.

 This feature adds an option to include the original SQL statement as a comment in the binary log (and shown in mysqlbinlog output) for row-based replication events.

 ### [Row-based replication for tables with no primary key](../row-based-replication-with-no-primary-key/index)

 This feature can improve the performance of row-based replication on tables that do not have a primary key (or other unique key), but which do have another index that can help locate rows to update or delete. With this feature, index cardinality information from `ANALYZE TABLE` is considered when selecting the index to use (before this feature is implemented, the first index was selected unconditionally).

 ### [PBXT consistent commit ordering](../enhancements-for-start-transaction-with-consistent/index)

 This feature implements the new commit ordering storage engine API in PBXT. With this feature, it is possible to use `START TRANSACTION WITH
CONSISTENT SNAPSHOT` and get consistency among transactions which involve both XtraDB and InnoDB. (Without this feature, there is no such consistency guarantee. For example, even after running `START TRANSACTION WITH CONSISTENT
SNAPSHOT` it was still possible for the InnoDB/XtraDB part of some transaction *T* to be visible and the PBXT part of the same transaction *T* to not be visible.)

 ### Miscellaneous

 * This preview also includes a small change to make mysqlbinlog omit redundant `use` statements around `BEGIN`, `SAVEPOINT`, `COMMIT`, and `ROLLBACK` events when reading MySQL 5.0 binlogs.
* The preview included a feature [--innodb-release-locks-early](../innodb-release-locks-early/index). However we decided to omit this feature from future MariaDB releases because of a fundamental design bug, [lp:798213](https://bugs.launchpad.net/maria/+bug/798213).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-52-replication-feature-preview/>

Information Schema PROCESSLIST Table
====================================

     The [Information Schema](../information_schema/index) `PROCESSLIST` table contains information about running threads.

 Similar information can also be returned with the [SHOW [FULL] PROCESSLIST](../show-processlist/index) statement, or the [mariadb-admin processlist](../mariadb-admin/index) command.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `ID` | Connection identifier. |
| `USER` | MariaDB User. |
| `HOST` | The hostname from which this thread is connected.For Unix socket connections, `localhost`. For TCP/IP connections, the TCP port is appended (e.g. `192.168.1.17:58061` or `other-host.company.com:58061`). For `system user`, this column is blank (`''`). |
| `DB` | Default database, or `NULL` if none. |
| `COMMAND` | Type of command running, corresponding to the `Com_` [status variables](../server-status-variables/index). See [Thread Command Values](../thread-command-values/index). |
| `TIME` | Seconds that the thread has spent on the current `COMMAND` so far. |
| `STATE` | Current state of the thread. See [Thread States](../thread-states/index). |
| `INFO` | Statement the thread is executing, or `NULL` if none. |
| `TIME_MS` | Time in milliseconds with microsecond precision that the thread has spent on the current `COMMAND` so far ([see more](../time_ms-column-in-information_schemaprocesslist/index)). |
| `STAGE` | The stage the process is currently in. |
| `MAX_STAGE` | The maximum number of stages. |
| `PROGRESS` | The progress of the process within the current stage (0-100%). |
| `MEMORY_USED` | Memory in bytes used by the thread. |
| `MAX_MEMORY_USED` | Maximum memory in bytes used by the thread. |
| `EXAMINED_ROWS` | Rows examined by the thread. Only updated by UPDATE, DELETE, and similar statements. For SELECT and other statements, the value remains zero. |
| `QUERY_ID` | Query ID. |
| `INFO_BINARY` | Binary data information |
| `TID` | Thread ID ([MDEV-6756](https://jira.mariadb.org/browse/MDEV-6756)) |

 
Note that as a difference to MySQL, in MariaDB the `TIME` column (and also the `TIME_MS` column) are not affected by any setting of `[@TIMESTAMP](../server-system-variables/index#timestamp)`. This means that it can be reliably used also for threads that change `@TIMESTAMP` (such as the [replication](../replication/index) SQL thread). See also [MySQL Bug #22047](http://bugs.mysql.com/bug.php?id=22047).

 As a consequence of this, the `TIME` column of `SHOW FULL PROCESSLIST` and `INFORMATION_SCHEMA.PROCESSLIST` can not be used to determine if a slave is lagging behind. For this, use instead the `Seconds_Behind_Master` column in the output of [SHOW SLAVE STATUS](../show-slave-status/index).

 Note that the `PROGRESS` field from the information schema, and the `PROGRESS` field from `SHOW PROCESSLIST` display different results. `SHOW PROCESSLIST` shows the total progress, while the information schema shows the progress for the current stage only.. To retrieve a similar "total" Progress value from `information_schema.PROCESSLIST` as the one from `SHOW PROCESSLIST`, use 



```
SELECT CASE WHEN Max_Stage < 2 THEN Progress ELSE (Stage-1)/Max_Stage*100+Progress/Max_Stage END 
  AS Progress FROM INFORMATION_SCHEMA.PROCESSLIST;

```
 Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST\G
*************************** 1. row ***************************
           ID: 9
         USER: msandbox
         HOST: localhost
           DB: NULL
      COMMAND: Query
         TIME: 0
        STATE: Filling schema table
         INFO: SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
      TIME_MS: 0.351
        STAGE: 0
    MAX_STAGE: 0
     PROGRESS: 0.000
  MEMORY_USED: 85392
EXAMINED_ROWS: 0
     QUERY_ID: 15
  INFO_BINARY: SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
          TID: 11838
*************************** 2. row ***************************
           ID: 5
         USER: system user
         HOST: 
           DB: NULL
      COMMAND: Daemon
         TIME: 0
        STATE: InnoDB shutdown handler
         INFO: NULL
      TIME_MS: 0.000
        STAGE: 0
    MAX_STAGE: 0
     PROGRESS: 0.000
  MEMORY_USED: 24160
EXAMINED_ROWS: 0
     QUERY_ID: 0
  INFO_BINARY: NULL
          TID: 3856
...

```

See Also
--------

 * [TIME\_MS column in Information Schema SHOW PROCESSLIST](../time_ms-column-in-information_schemaprocesslist/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-processlist-table/>

Benchmark Results
==================

   This section is for the posting of benchmark results.

  

| Title | Description |
| --- | --- |
|  [Threadpool Benchmarks](../threadpool-benchmarks/index) |  Here are some benchmarks of some development threadpool code (the 5.5 thre...  |
|  [Sysbench Results](../sysbench-results/index) |  Results from various Sysbench runs. The data is in OpenDocument Spreadsheet...  |
|  [sysbench v0.5 - Single Five Minute Runs on T500 Laptop](../1643/index) |  MariDB/MySQL sysbench benchmark comparison in % Number of threads  |
|  [sysbench v0.5 - Single Five Minute Runs on perro](../sysbench-v05-single-five-minute-runs-on-perro/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes.  |
|  [sysbench v0.5 - Single Five Minute Runs on work](../sysbench-v05-single-five-minute-runs-on-work/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes.  |
|  [sysbench v0.5 - Three Times Five Minutes Runs on work with 5.1.42](../1646/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes 3 times  |
|  [sysbench v0.5 - 3x Five Minute Runs on work with 5.2-wl86](../1647/index) |  3x Five Minute Runs on work with 5.2-wl86 key cache partitions on and off M...  |
|  [sysbench v0.5 - 3x Five Minute Runs on work with 5.1 vs. 5.2-wl86](../1648/index) |  3x Five Minute Runs on work with 5.1 vs. 5.2-wl86 key cache partitions off ...  |
|  [sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 a](../1649/index) |  sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 key cache partitio...  |
|  [sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 b](../1650/index) |  3x 15 Minute Runs on perro with 5.2-wl86 key cache partitions off, 8, and 3...  |
|  [Select Random Ranges and Select Random Point](../select-random-ranges-and-select-random-point/index) |  select\_random\_ranges (select 10 ranges with a delta as parameter) select\_ra...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmark-results/>

Filesystem Optimizations
========================

    Which filesystem is best?
-------------------------

 The filesystem is not the most important aspect of MariaDB performance. Far more important are available RAM, drive speed, the system variable settings (see [Hardware Optimization](../hardware-optimization/index) and [System Variables](../system-variables/index)). 

 Optimizing the filesystem can however in some cases make a noticeable difference. Currently, the best Linux filesystems are generally regarded as ext4, XFS and Btrfs. They are all included in the mainline Linux kernel, and are widely supported and available on most Linux distributions. Red Hat though regards Brtfs as a technology preview, not yet ready for production systems.

 The following theoretical file size and filesystem size limits apply to the three filesystems:

 


|  |  |  |  |
| --- | --- | --- | --- |
|  | ext4 | XFS | Brtfs |
| Max file size | 16TB | 8EB | 16EB |
| Max filesystem size | 1 EB | 8EB | 16EB |

 
Each has unique characteristics that are worth understanding to get the most from.

 Disabling access time
---------------------

 It's unlikely you'll need to record file access time on a database server, and mounting your filesystem with this disabled can give an easy improvement in performance. To do so, use the `noatime` option.

 If you want to keep access time for [log files](../log-files/index) or other system files, these can be stored on a separate drive.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/filesystem-optimizations/>

Fair Choice Between Range and Index\_merge Optimizations
========================================================

    `index_merge` is a method used by the optimizer to retrieve rows from a single table using several index scans. The results of the scans are then merged.

 When using [EXPLAIN](../explain/index), if `index_merge` is the plan chosen by the optimizer, it will show up in the "type" column. For example:

 
```
MariaDB [ontime]> SELECT COUNT(*) FROM ontime;
+--------+
|count(*)|
+--------+
| 1578171|
+--------+

MySQL [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' OR Dest='SEA');
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+--------------------------------------+
|id|select_type|table |type       |possible_keys|key        |key_len|ref |rows |Extra                                 |
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+--------------------------------------+
| 1|SIMPLE     |ontime|index_merge|Origin,Dest  |Origin,Dest|6,6    |NULL|92800|Using union (Origin,Dest); Using where|
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+--------------------------------------+

```

The "rows" column gives us a way to compare efficiency between `index_merge` and other plans.

 It is sometimes necessary to discard index\_merge in favor of a different plan to avoid a combinatorial explosion of possible range and/or index\_merge strategies. But, the old logic in MySQL for when index\_merge was rejected caused some good index\_merge plans to not even be considered. Specifically, additional `AND` predicates in `WHERE` clauses could cause an index\_merge plan to be rejected in favor of a less efficient plan. The slowdown could be anywhere from 10x to over 100x. Here are two examples (based on the previous query) using MySQL:

 
```
MySQL [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' OR Dest='SEA') AND securitydelay=0;
+--+-----------+------+----+-------------------------+-------------+-------+-----+------+-----------+
|id|select_type|table |type|possible_keys            |key          |key_len|ref  |rows  |Extra      |
+--+-----------+------+----+-------------------------+-------------+-------+-----+------+-----------+
| 1|SIMPLE     |ontime|ref |Origin,Dest,SecurityDelay|SecurityDelay|5      |const|791546|Using where|
+--+-----------+------+----+-------------------------+-------------+-------+-----+------+-----------+

MySQL [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' OR Dest='SEA') AND depdelay < 12*60;
+--+-----------+------+----+--------------------+----+-------+----+-------+-----------+
|id|select_type|table |type|possible_keys       |key |key_len|ref |rows   |Extra      |
+--+-----------+------+----+--------------------+----+-------+----+-------+-----------+
| 1|SIMPLE     |ontime|ALL |Origin,DepDelay,Dest|NULL|NULL   |NULL|1583093|Using where|
+--+-----------+------+----+--------------------+----+-------+----+-------+-----------

```

In the above output, the "rows" column shows that the first is almost 10x less efficient and the second is over 15x less efficient than `index_merge`.

 Starting in [MariaDB 5.3](../what-is-mariadb-53/index), the optimizer will delay discarding potential `index_merge` plans until the point where it is really necessary. See [MWL#24](http://askmonty.org/worklog/?tid=24) for more information.

 By not discarding potential `index_merge` plans until absolutely necessary, the two queries stay just as efficient as the original:

 
```
MariaDB [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' or Dest='SEA');
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+-------------------------------------+
|id|select_type|table |type       |possible_keys|key        |key_len|ref |rows |Extra                                |
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+-------------------------------------+
| 1|SIMPLE     |ontime|index_merge|Origin,Dest  |Origin,Dest|6,6    |NULL|92800|Using union(Origin,Dest); Using where|
+--+-----------+------+-----------+-------------+-----------+-------+----+-----+-------------------------------------+

MariaDB [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' or Dest='SEA') AND securitydelay=0;
+--+-----------+------+-----------+-------------------------+-----------+-------+----+-----+-------------------------------------+
|id|select_type|table |type       |possible_keys            |key        |key_len|ref |rows |Extra                                |
+--+-----------+------+-----------+-------------------------+-----------+-------+----+-----+-------------------------------------+
| 1|SIMPLE     |ontime|index_merge|Origin,Dest,SecurityDelay|Origin,Dest|6,6    |NULL|92800|Using union(Origin,Dest); Using where|
+--+-----------+------+-----------+-------------------------+-----------+-------+----+-----+-------------------------------------+

MariaDB [ontime]> EXPLAIN SELECT * FROM ontime WHERE (Origin='SEA' or Dest='SEA') AND depdelay < 12*60;
+--+-----------+------+-----------+--------------------+-----------+-------+----+-----+-------------------------------------+
|id|select_type|table |type       |possible_keys       |key        |key_len|ref |rows |Extra                                |
+--+-----------+------+-----------+--------------------+-----------+-------+----+-----+-------------------------------------+
| 1|SIMPLE     |ontime|index_merge|Origin,DepDelay,Dest|Origin,Dest|6,6    |NULL|92800|Using union(Origin,Dest); Using where|
+--+-----------+------+-----------+--------------------+-----------+-------+----+-----+-------------------------------------+

```

This new behavior is always on and there is no need to enable it. There are no known issues or gotchas with this new optimization.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/fair-choice-between-range-and-index_merge-optimizations/>

Defragmenting InnoDB Tablespaces
================================

    Overview
--------

 When rows are deleted from an [InnoDB](../innodb/index) table, the rows are simply marked as deleted and not physically deleted. The free space is not returned to the operating system for re-use. 

 The purge thread will physically delete index keys and rows, but the free space introduced is still not returned to operating system. This can lead to gaps in the pages. If you have variable length rows, new rows may be larger than old rows and cannot make use of the available space.

 You can run [OPTIMIZE TABLE](../optimize-table/index) or [ALTER TABLE <table> ENGINE=InnoDB](../alter-table/index) to reconstruct the table. Unfortunately running `OPTIMIZE TABLE` against an InnoDB table stored in the shared table-space file `ibdata1` does two things:

 * Makes the table’s data and indexes contiguous inside `ibdata1`.
* Increases the size of `ibdata1` because the contiguous data and index pages are appended to `ibdata1`.

 InnoDB Defragmentation
----------------------

 
The feature described below has been deprecated in [MariaDB 11.0](../what-is-mariadb-110/index) and was removed in [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/). See [MDEV-30544](https://jira.mariadb.org/browse/MDEV-30544) and [MDEV-30545](https://jira.mariadb.org/browse/MDEV-30545).

 
[MariaDB 10.1](../what-is-mariadb-101/index) merged Facebook's defragmentation code prepared for MariaDB by Matt, Seong Uck Lee from Kakao. The only major difference to Facebook's code and Matt’s patch is that MariaDB does not introduce new literals to SQL and makes no changes to the server code. Instead, [OPTIMIZE TABLE](../optimize-table/index) is used and all code changes are inside the InnoDB/XtraDB storage engines. 

 The behaviour of `OPTIMIZE TABLE` is unchanged by default, and to enable this new feature, you need to set the [innodb\_defragment](../innodb-system-variables/index#innodb_defragment) system variable to `1`. 

 
```
[mysqld]
...
innodb-defragment=1

```

No new tables are created and there is no need to copy data from old tables to new tables. Instead, this feature loads `n` pages (determined by [innodb-defragment-n-pages](../innodb-system-variables/index#innodb_defragment_n_pages)) and tries to move records so that pages would be full of records and then frees pages that are fully empty after the operation. 

 Note that tablespace files (including ibdata1) will not shrink as the result of defragmentation, but one will get better memory utilization in the InnoDB buffer pool as there are fewer data pages in use.

 A number of new system and status variables for controlling and monitoring the feature are introduced.

 ### System Variables

 * [innodb\_defragment](../innodb-system-variables/index#innodb_defragment): Enable InnoDB defragmentation.
* [innodb\_defragment\_n\_pages](../innodb-system-variables/index#innodb_defragment_n_pages): Number of pages considered at once when merging multiple pages to defragment.
* [innodb\_defragment\_stats\_accuracy](../innodb-system-variables/index#innodb_defragment_stats_accuracy): Number of defragment stats changes there are before the stats are written to persistent storage.
* [innodb\_defragment\_fill\_factor\_n\_recs](../innodb-system-variables/index#innodb_defragment_fill_factor_n_recs): Number of records of space that defragmentation should leave on the page.
* [innodb\_defragment\_fill\_factor](../innodb-system-variables/index#innodb_defragment_fill_factor): Indicates how full defragmentation should fill a page.
* [innodb\_defragment\_frequency](../innodb-system-variables/index#innodb_defragment_frequency): Maximum times per second for defragmenting a single index.

 ### Status Variables

 * [Innodb\_defragment\_compression\_failures](../innodb-status-variables/index#innodb_defragment_compression_failures): Number of defragment re-compression failures
* [Innodb\_defragment\_failures](../innodb-status-variables/index#innodb_defragment_failures): Number of defragment failures.
* [Innodb\_defragment\_count](../innodb-status-variables/index#innodb_defragment_count): Number of defragment operations.

 Example
-------

 
```
set @@global.innodb_file_per_table = 1;
set @@global.innodb_defragment_n_pages = 32;
set @@global.innodb_defragment_fill_factor = 0.95;
CREATE TABLE tb_defragment (
pk1 bigint(20) NOT NULL,
pk2 bigint(20) NOT NULL,
fd4 text,
fd5 varchar(50) DEFAULT NULL,
PRIMARY KEY (pk1),
KEY ix1 (pk2)
) ENGINE=InnoDB;
 
delimiter //
create procedure innodb_insert_proc (repeat_count int)
begin
  declare current_num int;
  set current_num = 0;
  while current_num < repeat_count do
    INSERT INTO tb_defragment VALUES (current_num, 1, REPEAT('Abcdefg', 20), REPEAT('12345',5));
    INSERT INTO tb_defragment VALUES (current_num+1, 2, REPEAT('HIJKLM', 20), REPEAT('67890',5));
    INSERT INTO tb_defragment VALUES (current_num+2, 3, REPEAT('HIJKLM', 20), REPEAT('67890',5));
    INSERT INTO tb_defragment VALUES (current_num+3, 4, REPEAT('HIJKLM', 20), REPEAT('67890',5));
    set current_num = current_num + 4;
  end while;
end//
delimiter ;
commit;
 
set autocommit=0;
call innodb_insert_proc(50000);
commit;
set autocommit=1;

```

After these CREATE and INSERT operations, the following information can be seen from the INFORMATION SCHEMA:

 
```
select count(*) as Value from information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name = 'PRIMARY';
Value
313
 
select count(*) as Value from information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name = 'ix1';
Value
72
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_pages_freed');
count(stat_value)
0
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_page_split');
count(stat_value)
0
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value)
0
 
SELECT table_name, data_free/1024/1024 AS data_free_MB, table_rows FROM information_schema.tables 
  WHERE engine LIKE 'InnoDB' and table_name like '%tb_defragment%';
table_name data_free_MB table_rows
tb_defragment 4.00000000 50051
 
SELECT table_name, index_name, sum(number_records), sum(data_size) FROM information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name like 'PRIMARY';
table_name index_name sum(number_records) sum(data_size)
`test`.`tb_defragment` PRIMARY 25873 4739939
 
SELECT table_name, index_name, sum(number_records), sum(data_size) FROM information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name like 'ix1';
table_name index_name sum(number_records) sum(data_size)
`test`.`tb_defragment` ix1 50071 1051775

```

Deleting three-quarters of the records, leaving gaps, and then optimizing:

 
```
delete from tb_defragment where pk2 between 2 and 4;
 
optimize table tb_defragment;
Table	Op	Msg_type	Msg_text
test.tb_defragment	optimize	status	OK
show status like '%innodb_def%';
Variable_name	Value
Innodb_defragment_compression_failures	0
Innodb_defragment_failures	1
Innodb_defragment_count	4

```

Now some pages have been freed, and some merged:

 
```
select count(*) as Value from information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name = 'PRIMARY';
Value
0
 
select count(*) as Value from information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name = 'ix1';
Value
0
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_pages_freed');
count(stat_value)
2
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_page_split');
count(stat_value)
2
 
select count(stat_value) from mysql.innodb_index_stats 
  where table_name like '%tb_defragment%' and stat_name in ('n_leaf_pages_defrag');
count(stat_value)
2
 
SELECT table_name, data_free/1024/1024 AS data_free_MB, table_rows FROM information_schema.tables 
  WHERE engine LIKE 'InnoDB';
table_name data_free_MB table_rows
innodb_index_stats 0.00000000 8
innodb_table_stats 0.00000000 0
tb_defragment 4.00000000 12431
 
SELECT table_name, index_name, sum(number_records), sum(data_size) FROM information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name like 'PRIMARY';
table_name index_name sum(number_records) sum(data_size)
`test`.`tb_defragment` PRIMARY 690 102145
 
SELECT table_name, index_name, sum(number_records), sum(data_size) FROM information_schema.innodb_buffer_page 
  where table_name like '%tb_defragment%' and index_name like 'ix1';
table_name index_name sum(number_records) sum(data_size)
`test`.`tb_defragment` ix1 5295 111263

```

See [Defragmenting unused space on InnoDB tablespace](https://blog.mariadb.org/defragmenting-unused-space-on-innodb-tablespace/) on the Mariadb.org blog for more details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/defragmenting-innodb-tablespaces/>

Improvements to ORDER BY Optimization
=====================================

    
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**[MariaDB 10.1](../what-is-mariadb-101/index) includes several improvements to the [ORDER BY](../order-by/index) optimizer. 

 
The fixes were made as a response to complaints by MariaDB customers, so they fix real-world optimization problems. The fixes are a bit hard to describe (as the `ORDER BY` optimizer is complicated), but here's a short description: 

 The [ORDER BY](../order-by/index) optimizer in [MariaDB 10.1](../what-is-mariadb-101/index):

 * Doesn’t make stupid choices when several multi-part keys and potential range accesses are present ([MDEV-6402](https://jira.mariadb.org/browse/MDEV-6402)).
	+ This also fixes [MySQL Bug#12113](http://bugs.mysql.com/bug.php?id=12113).
* Always uses “range” and (not full “index” scan) when it switches to an index to satisfy `ORDER BY … LIMIT` ([MDEV-6657](https://jira.mariadb.org/browse/MDEV-6657)).
* Tries hard to be smart and use cost/number of records estimates from other parts of the optimizer ([MDEV-6384](https://jira.mariadb.org/browse/MDEV-6384), [MDEV-465](https://jira.mariadb.org/browse/MDEV-465)).
	+ This change also fixes [MySQL Bug#36817](http://bugs.mysql.com/bug.php?id=36817).
* Takes full advantage of InnoDB’s Extended Keys feature when checking if filesort() can be skipped ([MDEV-6796](https://jira.mariadb.org/browse/MDEV-6796)).

 Extra optimizations
-------------------

 Starting from [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/)

 * The [ORDER BY](../order-by/index) optimizer takes multiple-equalities into account ([MDEV-8989](https://jira.mariadb.org/browse/MDEV-8989)). This optimization is not enabled by default in [MariaDB 10.1](../what-is-mariadb-101/index). You need to explicitly switch it ON by setting the [optimizer\_switch](../optimizer-switch/index) system variable, as follows:

 
```
optimizer_switch='orderby_uses_equalities=on'

```

Setting the switch ON is considered safe. It is off by default in [MariaDB 10.1](../what-is-mariadb-101/index) in order to avoid changing query plans in a stable release. It is on by default from [MariaDB 10.2](../what-is-mariadb-102/index)

 Comparison with MySQL 5.7
-------------------------

 In [MySQL 5.7 changelog](http://mysqlserverteam.com/whats-new-in-mysql-5-7-generally-available/), one can find this passage:

 
 Make switching of index due to small limit cost-based ([WL#6986](http://askmonty.org/worklog/?tid=6986)) : We have made the decision in make\_join\_select() of whether to switch to a new index in order to support "ORDER BY ... LIMIT N" cost-based. This work fixes Bug#73837.

  MariaDB is not using Oracle's fix (we believe `make_join_select` is not the right place to do ORDER BY optimization), but the effect is the same: this case is covered by [MariaDB 10.1](../what-is-mariadb-101/index)'s optimizer.

 See Also
--------

 * Blog post [MariaDB 10.1: Better query optimization for ORDER BY … LIMIT](http://s.petrunia.net/blog/?p=103)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/improvements-to-order-by/>

Performance Schema Overview
===========================

     The Performance Schema is a feature for monitoring server performance.   
  
  


 Introduction
------------

 It is implemented as a storage engine, and so will appear in the list of storage engines available.

 
```
SHOW ENGINES;
+--------------------+---------+----------------------------------+--------------+------+------------+
| Engine             | Support | Comment                          | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------+--------------+------+------------+
| ...                |         |                                  |              |      |            |
| PERFORMANCE_SCHEMA | YES     | Performance Schema               | NO           | NO   | NO         |
| ...                |         |                                  |              |      |            |
+--------------------+---------+----------------------------------+--------------+------+------------+

```

However, `performance_schema` is not a regular storage engine for storing data, it's a mechanism for implementing the Performance Schema feature.

 The storage engine contains a database called `performance_schema`, which in turn consists of a number of tables that can be queried with regular SQL statements, returning specific performance information.

 
```
USE performance_schema

```


```
SHOW TABLES;
+----------------------------------------------------+
| Tables_in_performance_schema                       |
+----------------------------------------------------+
| accounts                                           |
...
| users                                              |
+----------------------------------------------------+
80 rows in set (0.00 sec)

```

See [List of Performance Schema Tables](../list-of-performance-schema-tables/index) for a full list and links to detailed descriptions of each table. From [MariaDB 10.5](../what-is-mariadb-105/index), there are 80 Performance Schema tables, while until [MariaDB 10.4](../what-is-mariadb-104/index), there are 52.

 Activating the Performance Schema
---------------------------------

 The performance schema is disabled by default for performance reasons. You can check its current status by looking at the value of the [performance\_schema](../performance-schema-system-variables/index#performance_schema) system variable.

 
```
SHOW VARIABLES LIKE 'performance_schema';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| performance_schema | ON    |
+--------------------+-------+

```

The performance schema cannot be activated at runtime - it must be set when the server starts by adding the following line in your `my.cnf` configuration file.

 
```
performance_schema=ON

```

Until [MariaDB 10.4](../what-is-mariadb-104/index), all memory used by the Performance Schema is allocated at startup. From [MariaDB 10.5](../what-is-mariadb-105/index), some memory is allocated dynamically, depending on load, number of connections, number of tables open etc.

 Enabling the Performance Schema
-------------------------------

 You need to set up all consumers (starting collection of data) and instrumentations (what to collect):

 
```
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES';
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES';

```

You can decide what to enable/disable with `WHERE NAME like "%what_to_enable"`; You can disable instrumentations by setting `ENABLED` to `"NO"`.

 You can also do this in your my.cnf file. The following enables all instrumentation of all stages (computation units) in MariaDB:

 
```
[mysqld]
performance_schema=ON
performance-schema-instrument='stage/%=ON'
performance-schema-consumer-events-stages-current=ON
performance-schema-consumer-events-stages-history=ON
performance-schema-consumer-events-stages-history-long=ON

```

Listing Performance Schema Variables
------------------------------------

 
```
SHOW VARIABLES LIKE "perf%";
+--------------------------------------------------------+-------+
| Variable_name                                          | Value |
+--------------------------------------------------------+-------+
| performance_schema                                     | ON    |
...
| performance_schema_users_size                          | 100   |
+--------------------------------------------------------+-------+

```

See [Performance Schema System Variables](../performance-schema-system-variables/index) for a full list of available system variables.

 Note that the "consumer" events are not shown on this list, as they are only available as options, not as system variables, and they can only be enabled at [startup](../mysqld-options/index#performance-schema-options).

 Column Comments
---------------

 
**MariaDB starting with [10.7.1](https://mariadb.com/kb/en/mariadb-1071-release-notes/)**From [MariaDB 10.7.1](https://mariadb.com/kb/en/mariadb-1071-release-notes/), comments have been added to table columns in the Performance Schema. These can be viewed with, for example:

 
```
SELECT column_name, column_comment FROM information_schema.columns 
  WHERE table_schema='performance_schema' AND table_name='file_instances';
...
*************************** 2. row ***************************
   column_name: EVENT_NAME
column_comment: Instrument name associated with the file.
*************************** 3. row ***************************
   column_name: OPEN_COUNT
column_comment: Open handles on the file. A value of greater than zero means 
                that the file is currently open.
...

```


See Also
--------

 * [Performance schema options](../mysqld-options/index#performance-schema-options)
* [SHOW ENGINE STATUS](../show-engine/index)
* [SHOW PROFILE](../show-profile/index)
* [ANALYZE STATEMENT](https://mariadb.com/analyze-statement)
* [Performance schema in MySQL 5.6](https://dev.mysql.com/doc/refman/5.6/en/performance-schema.html). All things here should also work for MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-overview/>

IP Range Table Performance
==========================

    The situation
-------------

 Your data includes a large set of non-overlapping 'ranges'. These could be IP addresses, datetimes (show times for a single station), zipcodes, etc.

 You have pairs of start and end values; one 'item' belongs to each such 'range'. So, instinctively, you create a table with start and end of the range, plus info about the item. Your queries involve a WHERE clause that compares for being between the start and end values.

 The problem
-----------

 Once you get a large set of items, performance degrades. You play with the indexes, but find nothing that works well. The indexes fail to lead to optimal functioning because the database does not understand that the ranges are non-overlapping.

 The solution
------------

 I will present a solution that enforces the fact that items cannot have overlapping ranges. The solution builds a table to take advantage of that, then uses Stored Routines to get around the clumsiness imposed by it.

 Performance
-----------

 The instinctive solution often leads to scanning half the table to do just about anything, such as finding the item containing an 'address'. In complexity terms, this is Order(N).

 The solution here can usually get the desired information by fetching a single row, or a small number of rows. It is Order(1).

 In a large table, "counting the disk hits" is the important part of performance. Since InnoDB is used, and the PRIMARY KEY (clustered) is used, most operations hit only 1 block.

 Finding the 'block' where a given IP address lives:

 * For start of block: One single-row fetch using the PRIMARY KEY
* For end of block: Ditto. The record containing this will be 'adjacent' to the other record.

 For allocating or freeing a block:

 * 2-7 SQL statements, hitting the clustered PRIMARY KEY for the rows containing and immediately adjacent to the block.
* One SQL statement is a DELETE; if hits as many rows as are needed for the block.
* The other statements hit one row each.

 Design decisions
----------------

 This is crucial to the design and its performance:

 * Having just one address in the row. These were alternative designs; they seemed to be no better, and possibly worse:
* That one address could have been the 'end' address.
* The routine parameters for a 'block' could have be start of this block and start of next block.
* The IPv4 parameters could have been dotted quads; I chose to keep the reference implemetation simpler instead.
* The IPv6 parameters are 32-digit hex because it was the simpler that BINARY(16) or IPv5 for a reference implementation.

 The interesting work is in the Ips, not the second table, so I focus on it. The inconvenience of JOINing to the second table is small compared to the performance gains.

 Details
-------

 Two, not one, tables will be used. The first table (`Ips` in the reference implementations) is carefully designed to be optimal for all the basic operations needed. The second table contains other infomation about the 'owner' of each 'item'. In the reference implementations `owner` is an id used to JOIN the two tables. This discussion centers around `Ips` and how to efficiently map IP(s) to/from owner(s). The second table has "PRIMARY KEY(owner)".

 In addition to the two-table schema, there are a set of Stored Routines to encapsulate the necessary code.

 One row of Ips represents one 'item' by specifying the starting IP address and the 'owner'. The next row gives the starting IP address of the next "address block", thereby indirectly providing the ending address for the current block.

 This lack of explicitly stating the "end address" leads to some clumsiness. The stored routines hide it from the user.

 A special owner (indicated by '0') is reserved for "free" or "not-owned" blocks. Hence, sparse allocation of address blocks is no problem. Also, the 'free' owner is handled no differently than real owners, so there are no extra Stored Routines for such.

 Links below give "reference" implementations for IPv4 and IPv6. You will need to make changes for non-IP situations, and may need to make changes even for IP situations.

 These are the main stored routines provided:

 * IpIncr, IpDecr -- for adding/subtracting 1
* IpStore -- for allocating/freeing a range
* IpOwner, IpRangeOwners, IpFindRanges, Owner2IpStarts, Owner2IpRanges -- for lookups
* IpNext, IpEnd -- IP of start of next block, or end of current block

 None of the provided routines JOIN to the other table; you may wish to develop custom queries based on the given reference Stored Procedures.

 The Ips table's size is proportional to the number of blocks. A million 'owned' blocks may be 20-50MB. This varies due to

 * number of 'free' gaps (between zero and the number of owned blocks)
* datatypes used for `ip` and `owner`
* [InnoDB](../innodb/index) overhead Even 100M blocks is quite manageable in today's hardware. Once things are cached, most operations would take only a few milliseconds. A trillion blocks would work, but most operations would hit the disk a few times -- only a few times.

 Reference implementation of IPv4
--------------------------------

 This specific to IPv4 (32 bit, a la '196.168.1.255'). It can handle anywhere from 'nothing assigned' (1 row) to 'everything assigned' (4B rows) 'equally' well. That is, to ask the question "who owns '11.22.33.44'" is equally efficient regardless of how many blocks of IP addresses exist in the table. (OK, caching, disk hits, etc may make a slight difference.) The one function that can vary is the one that reassigns a range to a new owner. Its speed is a function of how many existing ranges need to be consumed, since those rows will be DELETEd. (It helps that they are, by schema design, 'clustered'.)

 Notes on the [Reference implementation for IPv4](http://mysql.rjweb.org/doc.php/ipv4.sql):

 * Externally, the user may use the dotted quad notation (11.22.33.44), but needs to convert to INT UNSIGNED for calling the Stored Procs.
* The user is responsible for converting to/from the calling datatype (INT UNSIGNED) when accessing the stored routine; suggest [INET\_ATON](../inet_aton/index)/[INET\_NTOA](../inet_ntoa/index).
* The internal datatype for addresses is the same as the calling datatype (INT UNSIGNED).
* Adding and subtracting 1 (simple arithmetic).
* The datatype of an 'owner' (MEDIUMINT UNSIGNED: 0..16M) -- adjust if needed.
* The address "Off the end" (255.255.255.255+1 - represented as NULL).
* The table is initialized to one row: (ip=0, owner=0), meaning "all addresses are free See the comments in the code for more details.

 (The reference implementation does not handle CDRs. Such should be easy to add on, by first turning it into an IP range.)

 Reference implementation of IPv6
--------------------------------

 The code for handling IP address is more complex, but the overall structure is the same as for IPv4. Launch into it only if you need IPv6.

 Notes on the [reference implementation for IPv6](http://mysql.rjweb.org/doc.php/ipv6.sql):

 * Externally, IPv6 has a complex string, VARCHAR(39) CHARACTER SET ASCII. The Stored Procedure IpStr2Hex() is provided.
* The user is responsible for converting to/from the calling datatype (BINARY(16)) when accessing the stored routine; suggest [INET6\_ATON](../inet6_aton/index)/[INET6\_NTOA](../inet6_ntoa/index).
* The internal datatype for addresses is the same as the calling datatype (BINARY(16)).
* Communication with the Stored routines is via 32-char hex strings.
* Inside the Procedures, and in the Ips table, an address is stored as BINARY(16) for efficiency. HEX() and UNHEX() are used at the boundaries.
* Adding/subtracting 1 is rather complex (see the code).
* The datatype of an 'owner' (MEDIUMINT UNSIGNED: 0..16M); 'free' is represented by 0. You may need a bigger datatype.
* The address "Off the end" (ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff+1 is represented by NULL).
* The table is initialized to one row: (UNHEX('00000000000000000000000000000000'), 0), meaning "all addresses are free.
* You may need to decide on a canonical representation of IPv4 in IPv6. See the comments in the code for more details.

 The INET6\* functions were first available in MySQL 5.6.3 and [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/)

 Adapting to a different non-IP 'address range' data

 * The external datatype for an 'address' should be whatever is convenient for the application.
* The datatype for the 'address' in the table must be ordered, and should be as compact as possible.
* You must write the Stored functions (IpIncr, IpDecr) for incrementing/decrementing an 'address'.
* An 'owner' is an id of your choosing, but smaller is better.
* A special value (such as 0 or '') must be provided for 'free'.
* The table must be initialized to one row: (SmallestAddress, Free)

 "Owner" needs a special value to represent "not owned". The reference implementations use "=" and "!=" to compare two 'owners'. Numeric values and strings work nicely with those operators; NULL does not. Hence, please do not use NULL for "not owned".

 Since the datatypes are pervasive in the stored routines, adapting a reference implementation to a different concept of 'address' would require multiple minor changes.

 The code enforces that consecutive blocks never have the same 'owner', so the table is of 'minimal' size. Your application can assume that such is always the case.

 Postlog
-------

 Original writing -- Oct, 2012; Notes on INET6 functions -- May, 2015.

 See also
--------

 * [Related blog](http://jorgenloland.blogspot.co.uk/2011/09/tips-and-tricks-killer-response-time.html)
* [Another approach](http://dba.stackexchange.com/questions/83458/mysql-select-with-between-optimization/83471#83471)
* [Free IP tables](https://lite.ip2location.com/)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/ipranges>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ip-range-table-performance/>

Performance Schema Digests
==========================

    The Performance Schema digest is a normalized form of a statement, with the specific data values removed. It allows statistics to be gathered for similar kinds of statements.

 For example:

 
```
SELECT * FROM customer WHERE age < 20
SELECT * FROM customer WHERE age < 30

```

With the data values removed, both of these statements normalize to:

 
```
SELECT * FROM customer WHERE age < ?

```

which is the digest text. The digest text is then MD5 hashed, resulting in a digest. For example:

 
```
DIGEST_TEXT: SELECT * FROM `performance_schema` . `users`
DIGEST: 0f70cec4015f2a346df4ac0e9475d9f1

```

By contrast, the following two statements would not have the same digest as, while the data values are the same, they call upon different tables.

 
```
SELECT * FROM customer1 WHERE age < 20
SELECT * FROM customer2 WHERE age < 20

```

The digest text is limited to 1024 bytes. Queries exceeding this limit are truncated with '...', meaning that long queries that would otherwise have different digests may share the same digest.

 Digest information is used in a number of performance scheme tables. These include

 * [events\_statements\_current](../performance-schema-events_statements_current-table/index)
* [events\_statements\_history](../performance-schema-events_statements_history-table/index)
* [events\_statements\_history\_long](../performance-schema-events_statements_history_long-table/index)
* [events\_statements\_summary\_by\_digest](../performance-schema-events_statements_summary_by_digest-table/index) (a summary table by schema and digest)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-digests/>

Sys Schema
===========

   
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**The sys\_schema is a collection of views, functions and procedures to help administrators get insight into database usage.

 

This article is currently incomplete.

   

| Title | Description |
| --- | --- |
|  [Sys Schema sys\_config Table](../sys-schema-sys_config-table/index) |  Configuration options for the Sys Schema.  |
|  [Sys Schema Stored Functions](../sys-schema-stored-functions/index) |  Stored functions available in the Sys Schema.  |
|  [Sys Schema Stored Procedures](../sys-schema-stored-procedures/index) |  Stored procedures available in the Sys Schema.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys-schema/>

InnoDB COMPRESSED Row Format
============================

    
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, an alternative (and usually superior) way to compress InnoDB tables is by using [InnoDB Page Compression](../innodb-page-compression/index). See [Comparison with the COMPRESSED Row Format](../innodb-page-compression/index#comparison-with-the-compressed-row-format).

 
The `COMPRESSED` row format is similar to the `COMPACT` row format, but tables using the `COMPRESSED` row format can store even more data on overflow pages than tables using the `COMPACT` row format. This results in more efficient data storage than tables using the `COMPACT` row format, especially for tables containing columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types.

 The `COMPRESSED` row format also supports compression of all data and index pages.

 Using the `COMPRESSED` Row Format
---------------------------------

 An InnoDB table that uses the `COMPRESSED` row format can be created by setting the [ROW\_FORMAT](../create-table/index#row_format) table option to `COMPRESSED` and by setting the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option to one of the following values in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement, where the units are in `KB`:

 * `1`
* `2`
* `4`
* `8`
* `16`

 `16k` is the default value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable, so using `16` will usually result in minimal compression unless one of the following is true:

 * The table has many columns that can be stored in overflow pages, such as columns that use the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types.
* The server is using a non-default [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) value that is greater than `16k`.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and later, the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable can be set to `32k` and `64k`. This is especially useful because the larger page size permits more columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types. Regardless, even when the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable is set to some value higher than `16k`, `16` is still the maximum value for the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option for InnoDB tables using the `COMPRESSED` row format.

 The `COMPRESSED` row format cannot be set as the default row format with the [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) system variable.

 The `COMPRESSED` row format is only supported by the `Barracuda` [file format](../innodb-file-format/index). As a side effect, in [MariaDB 10.1](../what-is-mariadb-101/index) and before, the `COMPRESSED` row format is only supported if the [InnoDB file format](../xtradbinnodb-file-format/index) is `Barracuda`. Therefore, the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable must be set to `Barracuda` to use these row formats in those versions.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the `COMPRESSED` row format is also only supported if the table is in a [file per-table](../innodb-file-per-table-tablespaces/index) tablespace. Therefore, the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable must be set to `ON` to use this row format in those versions.

 It is also recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this row format.

 InnoDB automatically uses the `COMPRESSED` row format for a table if the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is set to some value in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement. For example:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB KEY_BLOCK_SIZE=4;

```

If the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option is **not** set to some value, but the [ROW\_FORMAT](../create-table/index#row_format) table option is set to `COMPRESSED` in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement, then InnoDB uses a default value of `8` for the [KEY\_BLOCK\_SIZE](../create-table/index#key_block_size) table option. For example:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;

```

Compression with the `COMPRESSED` Row Format
--------------------------------------------

 The `COMPRESSED` row format supports compression of all data and index pages.

 To avoid compressing and uncompressing pages too many times, InnoDB tries to keep both compressed and uncompressed pages in the [buffer pool](../xtradbinnodb-memory-buffer/index) when there is enough room. This results in a bigger cache. When there is not enough room, an adaptive LRU algorithm is used to decide whether compressed or uncompressed pages should be evicted from the buffer: for CPU-bound workloads, the compressed pages are evicted first; for I/O-bound workloads, the uncompressed pages are evicted first. Of course, when necessary, both the compressed and uncompressed version of the same data can be evicted from the buffer.

 Each compressed page has an uncompressed *modification log*, stored within the page itself. InnoDB writes small changes into it. When the space in the modification log runs out, the page is uncompressed, changes are applied, and the page is recompressed again. This is done to avoid some unnecessary decompression and compression operations.

 Sometimes a *compression failure* might happen, because the data has grown too much to fit the page. When this happens, the page (and the index node) is split into two different pages. This process can be repeated recursively until the data fit the pages. This can be CPU-consuming on some busy servers which perform many write operations.

 Before writing a compressed page into a data file, InnoDB writes it into the [redo log](../innodb-redo-log/index). This ensures that the [redo log](../innodb-redo-log/index) can always be used to recover tables after a crash, even if the compression library is updated and some incompatibilities are introduced. But this also means that the [redo log](../innodb-redo-log/index) will grow faster and might need more space, or the frequency of checkpoints might need to increase.

 Monitoring Performance of the `COMPRESSED` Row Format
-----------------------------------------------------

 The following `INFORMATION_SCHEMA` tables can be used to monitor the performances of InnoDB compressed tables:

 * [INNODB\_CMP and INNODB\_CMP\_RESET](../information_schemainnodb_cmp-and-innodb_cmp_reset-tables/index)
* [INNODB\_CMP\_PER\_INDEX and INNODB\_CMP\_PER\_INDEX\_RESET](../information_schemainnodb_cmp_per_index-and-innodb_cmp_per_index_reset-table/index)
* [INNODB\_CMPMEM and INNODB\_CMPMEM\_RESET](../information_schemainnodb_cmpmem-and-innodb_cmpmem_reset-tables/index)

 Index Prefixes with the `COMPRESSED` Row Format
-----------------------------------------------

 The `COMPRESSED` row format supports index prefixes up to 3072 bytes. In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) system variable is used to configure the maximum index prefix length. In these versions, if [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) is set to `ON`, then the maximum prefix length is 3072 bytes, and if it is set to `OFF`, then the maximum prefix length is 767 bytes.

 Overflow Pages with the `COMPRESSED` Row Format
-----------------------------------------------

 All InnoDB row formats can store certain kinds of data in overflow pages. This allows for the maximum row size of an InnoDB table to be larger than the maximum amount of data that can be stored in the row's main data page. See [Maximum Row Size](#maximum-row-size) for more information about the other factors that can contribute to the maximum row size for InnoDB tables.

 In the `COMPRESSED` row format variable-length columns, such as columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types, can be completely stored in overflow pages.

 InnoDB only considers using overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If the row size is greater than this, then InnoDB chooses variable-length columns to be stored on overflow pages until the row size is less than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size).

 For [BLOB](../blob/index) and [TEXT](../text/index) columns, only values longer than 40 bytes are considered for storage on overflow pages. For [VARBINARY](../varbinary/index) and [VARCHAR](../varchar/index) columns, only values longer than 255 bytes are considered for storage on overflow pages. Bytes that are stored to track a value's length do not count towards these limits. These limits are only based on the length of the actual column's data.

 These limits differ from the limits for the `COMPACT` row format, where the limit is 767 bytes for all types.

 Fixed-length columns greater than 767 bytes are encoded as variable-length columns, so they can also be stored in overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). Even though a column using the [CHAR](../char/index) data type can hold at most 255 characters, a [CHAR](../char/index) column can still exceed 767 bytes in some cases. For example, a `char(255)` column can exceed 767 bytes if the [character set](../character-sets/index) is `utf8mb4`.

 If a column is chosen to be stored on overflow pages, then the entire value of the column is stored on overflow pages, and only a 20-byte pointer to the column's first overflow page is stored on the main page. Each overflow page is the size of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If a column is too large to be stored on a single overflow page, then it is stored on multiple overflow pages. Each overflow page contains part of the data and a 20-byte pointer to the next overflow page, if a next page exists.

 This behavior differs from the behavior of the `COMPACT` row format, which always stores the column prefix on the main page. This allows tables using the `COMPRESSED` row format to contain a high number of columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types.

 Read-Only
---------

 
**MariaDB starting with [10.6](../what-is-mariadb-106/index)**From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) until [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/), tables that are of the `COMPRESSED` row format are read-only by default. This was intended to be the first step towards removing write support and deprecating the feature.

 This plan has been scrapped, and from [MariaDB 10.6.6](https://mariadb.com/kb/en/mariadb-1066-release-notes/), `COMPRESSED` tables are no longer read-only by default.

 From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) to [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/), set the [innodb\_read\_only\_compressed](../innodb-system-variables/index#innodb_read_only_compressed) variable to `OFF` to make the tables writable.

 
See Also
--------

 * [InnoDB Page Compression](../innodb-page-compression/index)
* [Storage-Engine Independent Column Compression](../storage-engine-independent-column-compression/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-compressed-row-format/>

The Essentials of an Index
==========================

    Imagine you've created a table with the following rows (this is the same table as used in the [More Advanced Joins](../more-advanced-joins/index) tutorial).

 
```
+----+------------+-----------+-------------------------+---------------------------+--------------+
| ID | First_Name | Last_Name | Position                | Home_Address              | Home_Phone   |
+----+------------+-----------+-------------------------+---------------------------+--------------+
|  1 | Mustapha   | Mond      | Chief Executive Officer | 692 Promiscuous Plaza     | 326-555-3492 |
|  2 | Henry      | Foster    | Store Manager           | 314 Savage Circle         | 326-555-3847 |
|  3 | Bernard    | Marx      | Cashier                 | 1240 Ambient Avenue       | 326-555-8456 |
|  4 | Lenina     | Crowne    | Cashier                 | 281 Bumblepuppy Boulevard | 328-555-2349 |
|  5 | Fanny      | Crowne    | Restocker               | 1023 Bokanovsky Lane      | 326-555-6329 |
|  6 | Helmholtz  | Watson    | Janitor                 | 944 Soma Court            | 329-555-2478 |
+----+------------+-----------+-------------------------+---------------------------+--------------+

```

Now, imagine you've been asked to return the home phone of Fanny Crowne. Without indexes, the only way to do it is to go through every row until you find the matching first name and surname. Now imagine there are millions of records and you can see that, even for a speedy database server, this is highly inefficient.

 The answer is to sort the records. If they were stored in alphabetical order by surname, even a human could quickly find a record amongst a large number. But we can't sort the entire record by surname. What if we want to also look a record by ID, or by first name? The answer is to create separate indexes for each column we wish to sort by. An index simply contains the sorted data (such as surname), and a link to the original record.

 For example, an index on Last\_Name:

 
```
+-----------+----+
| Last_Name | ID |
+-----------+----+
| Crowne    |  4 |
| Crowne    |  5 |
| Foster    |  2 |
| Marx      |  3 |
| Mond      |  1 |
| Watson    |  6 |
+-----------+----+

```

and an index on Position

 
```
+-------------------------+----+
| Position                | ID |
+-------------------------+----+
| Cashier                 |  3 |
| Cashier                 |  4 |
| Chief Executive Officer |  1 |
| Janitor                 |  6 |
| Restocker               |  5 |
| Store Manager           |  2 |
+-------------------------+----+

```

would allow you to quickly find the phone numbers of all the cashiers, or the phone number of the employee with the surname Marx, very quickly.

 Where possible, you should create an index for each column that you search for records by, to avoid having the server read every row of a table.

 See [CREATE INDEX](../create-index/index) and [Getting Started with Indexes](../getting-started-with-indexes/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-essentials-of-an-index/>

Performance Schema Tables
==========================

   Tables that are part of the [MariaDB Performance Schema](../performance-schema/index), a feature for monitoring the performance of MariaDB server.

  

| Title | Description |
| --- | --- |
|  [List of Performance Schema Tables](../list-of-performance-schema-tables/index) |  List and short description of all performance\_schema tables.  |
|  [Performance Schema accounts Table](../performance-schema-accounts-table/index) |  Account connection information.  |
|  [Performance Schema cond\_instances Table](../performance-schema-cond_instances-table/index) |  List of instrumented condition objects.  |
|  [Performance Schema events\_stages\_current Table](../performance-schema-events_stages_current-table/index) |  Current stage events.  |
|  [Performance Schema events\_stages\_history Table](../performance-schema-events_stages_history-table/index) |  Most recent stage events per thread.  |
|  [Performance Schema events\_stages\_history\_long Table](../performance-schema-events_stages_history_long-table/index) |  Most recent completed stage events.  |
|  [Performance Schema events\_stages\_summary\_by\_account\_by\_event\_name Table](../performance-schema-events_stages_summary_by_account_by_event_name-table/index) |  Stage events, summarized by account and event name.  |
|  [Performance Schema events\_stages\_summary\_by\_host\_by\_event\_name Table](../performance-schema-events_stages_summary_by_host_by_event_name-table/index) |  Stage events summarized by host and event name.  |
|  [Performance Schema events\_stages\_summary\_by\_thread\_by\_event\_name Table](../performance-schema-events_stages_summary_by_thread_by_event_name-table/index) |  Stage events summarized by thread and event name.  |
|  [Performance Schema events\_stages\_summary\_by\_user\_by\_event\_name Table](../performance-schema-events_stages_summary_by_user_by_event_name-table/index) |  Stage events summarized by user and event name.  |
|  [Performance Schema events\_stages\_summary\_global\_by\_event\_name Table](../performance-schema-events_stages_summary_global_by_event_name-table/index) |  Event summaries.  |
|  [Performance Schema events\_statements\_current Table](../performance-schema-events_statements_current-table/index) |  Current statement events.  |
|  [Performance Schema events\_statements\_history Table](../performance-schema-events_statements_history-table/index) |  Most recent statement events per thread  |
|  [Performance Schema events\_statements\_history\_long Table](../performance-schema-events_statements_history_long-table/index) |  Most recent statement events.  |
|  [Performance Schema events\_statements\_summary\_by\_account\_by\_event\_name Table](../performance-schema-events_statements_summary_by_account_by_event_name-table/index) |  Statement events summarized by account and event name.  |
|  [Performance Schema events\_statements\_summary\_by\_digest Table](../performance-schema-events_statements_summary_by_digest-table/index) |  Statement events summarized by schema and digest.  |
|  [Performance Schema events\_statements\_summary\_by\_host\_by\_event\_name Table](../performance-schema-events_statements_summary_by_host_by_event_name-table/index) |  Statement events summarized by host and event name.  |
|  [Performance Schema events\_statements\_summary\_by\_program Table](../performance-schema-events_statements_summary_by_program-table/index) |  Summarizes events for a particular stored program.  |
|  [Performance Schema events\_statements\_summary\_by\_thread\_by\_event\_name Table](../performance-schema-events_statements_summary_by_thread_by_event_name-table/index) |  Statement events summarized by thread and event name.  |
|  [Performance Schema events\_statements\_summary\_by\_user\_by\_event\_name Table](../performance-schema-events_statements_summary_by_user_by_event_name-table/index) |  Statement events summarized by user and event name.  |
|  [Performance Schema events\_statements\_summary\_global\_by\_event\_name Table](../performance-schema-events_statements_summary_global_by_event_name-table/index) |  Statement events summarized by event name.  |
|  [Performance Schema events\_transactions\_current Table](../performance-schema-events_transactions_current-table/index) |  Current transaction events for each thread.  |
|  [Performance Schema events\_transactions\_history Table](../performance-schema-events_transactions_history-table/index) |  Most recent completed transaction events for each thread.  |
|  [Performance Schema events\_transactions\_history\_long Table](../performance-schema-events_transactions_history_long-table/index) |  Most recent completed transaction events that have ended globally.  |
|  [Performance Schema events\_transactions\_summary\_by\_account\_by\_event\_name Table](../performance-schema-tables-performance-schema-events_transactions_summary_by/index) |  Transaction events aggregated by account and event name.  |
|  [Performance Schema events\_transactions\_summary\_by\_host\_by\_event\_name Table](../performance-schema-events_transactions_summary_by_host_by_event_name-table/index) |  Transaction events aggregated by host and event name.  |
|  [Performance Schema events\_transactions\_summary\_by\_thread\_by\_event\_name Table](../performance-schema-events_transactions_summary_by_thread_by_event_name-tabl/index) |  Transaction events aggregated by thread and event name.  |
|  [Performance Schema events\_transactions\_summary\_by\_user\_by\_event\_name Table](../performance-schema-events_transactions_summary_by_user_by_event_name-table/index) |  Transaction events aggregated by user and event name.  |
|  [Performance Schema events\_transactions\_summary\_global\_by\_event\_name Table](../performance-schema-events_transactions_summary_global_by_event_name-table/index) |  Transaction events aggregated by event name.  |
|  [Performance Schema events\_waits\_current Table](../performance-schema-events_waits_current-table/index) |  Current wait events  |
|  [Performance Schema events\_waits\_history Table](../performance-schema-events_waits_history-table/index) |  Most recent wait events per thread  |
|  [Performance Schema events\_waits\_history\_long Table](../performance-schema-events_waits_history_long-table/index) |  Most recent completed wait events  |
|  [Performance Schema events\_waits\_summary\_by\_account\_by\_event\_name Table](../performance-schema-events_waits_summary_by_account_by_event_name-table/index) |  Wait events summarized by account and event name.  |
|  [Performance Schema events\_waits\_summary\_by\_host\_by\_event\_name Table](../performance-schema-events_waits_summary_by_host_by_event_name-table/index) |  Wait events summarized by host and event name.  |
|  [Performance Schema events\_waits\_summary\_by\_instance Table](../performance-schema-events_waits_summary_by_instance-table/index) |  Wait events summarized by instance  |
|  [Performance Schema events\_waits\_summary\_by\_thread\_by\_event\_name Table](../performance-schema-events_waits_summary_by_thread_by_event_name-table/index) |  Wait events summarized by thread and event name.  |
|  [Performance Schema events\_waits\_summary\_by\_user\_by\_event\_name Table](../performance-schema-events_waits_summary_by_user_by_event_name-table/index) |  Wait events summarized by user and event name.  |
|  [Performance Schema events\_waits\_summary\_global\_by\_event\_name Table](../performance-schema-events_waits_summary_global_by_event_name-table/index) |  Wait events summarized by event name.  |
|  [Performance Schema file\_instances Table](../performance-schema-file_instances-table/index) |  List of file instruments.  |
|  [Performance Schema file\_summary\_by\_event\_name Table](../performance-schema-file_summary_by_event_name-table/index) |  File events summarized by event name.  |
|  [Performance Schema file\_summary\_by\_instance Table](../performance-schema-file_summary_by_instance-table/index) |  File events summarized by instance.  |
|  [Performance Schema global\_status Table](../performance-schema-global_status-table/index) |  Status variables and their global values.  |
|  [Performance Schema hosts Table](../performance-schema-hosts-table/index) |  Hosts used to connect to the server.  |
|  [Performance Schema host\_cache Table](../performance-schema-host_cache-table/index) |  Host\_cache information.  |
|  [Performance Schema memory\_summary\_by\_account\_by\_event\_name Table](../performance-schema-memory_summary_by_account_by_event_name-table/index) |  Memory usage statistics aggregated by account and event.  |
|  [Performance Schema memory\_summary\_by\_host\_by\_event\_name Table](../performance-schema-memory_summary_by_host_by_event_name-table/index) |  Memory usage statistics aggregated by host and event.  |
|  [Performance Schema memory\_summary\_by\_thread\_by\_event\_name Table](../performance-schema-memory_summary_by_thread_by_event_name-table/index) |  Memory usage statistics aggregated by thread and event.  |
|  [Performance Schema memory\_summary\_by\_user\_by\_event\_name Table](../performance-schema-memory_summary_by_user_by_event_name-table/index) |  Memory usage statistics aggregated by user and event.  |
|  [Performance Schema memory\_summary\_global\_by\_event\_name Table](../performance-schema-memory_summary_global_by_event_name-table/index) |  Memory usage statistics aggregated by event and event.  |
|  [Performance Schema metadata\_locks Table](../performance-schema-metadata_locks-table/index) |  Metadata lock information.  |
|  [Performance Schema mutex\_instances Table](../performance-schema-mutex_instances-table/index) |  Seen mutexes  |
|  [Performance Schema objects\_summary\_global\_by\_type Table](../performance-schema-objects_summary_global_by_type-table/index) |  Aggregates object wait events.  |
|  [Performance Schema performance\_timers Table](../performance-schema-performance_timers-table/index) |  Available event timers  |
|  [Performance Schema prepared\_statements\_instances Table](../performance-schema-prepared_statements_instances-table/index) |  Aggregated statistics of prepared statements.  |
|  [Performance Schema replication\_applier\_configuration Table](../performance-schema-replication_applier_configuration-table/index) |  Configuration settings affecting replica transactions.  |
|  [Performance Schema replication\_applier\_status Table](../performance-schema-replication_applier_status-table/index) |  Information about the general transaction execution status on the slave.  |
|  [Performance Schema replication\_applier\_status\_by\_coordinator Table](../performance-schema-replication_applier_status_by_coordinator-table/index) |  Coordinator thread status used in multi-threaded replicas to manage multiple workers.  |
|  [Performance Schema replication\_applier\_status\_by\_worker Table](../performance-schema-replication_applier_status_by_worker-table/index) |  Slave worker thread specific information.  |
|  [Performance Schema replication\_connection\_configuration Table](../performance-schema-replication_connection_configuration-table/index) |  Replica configuration settings used for connecting to the primary.  |
|  [Performance Schema rwlock\_instances Table](../performance-schema-rwlock_instances-table/index) |  Seen read-write locks  |
|  [Performance Schema session\_account\_connect\_attrs Table](../performance-schema-session_account_connect_attrs-table/index) |  Connection attributes for the current session.  |
|  [Performance Schema session\_connect\_attrs Table](../performance-schema-session_connect_attrs-table/index) |  Connection attributes for all sessions.  |
|  [Performance Schema session\_status Table](../performance-schema-session_status-table/index) |  Status variables and their session values.  |
|  [Performance Schema setup\_actors Table](../performance-schema-setup_actors-table/index) |  Determines whether monitoring is enabled for host/user combinations.  |
|  [Performance Schema setup\_consumers Table](../performance-schema-setup_consumers-table/index) |  Lists the types of consumers for which event information is available.  |
|  [Performance Schema setup\_instruments Table](../performance-schema-setup_instruments-table/index) |  List of instrumented object classes  |
|  [Performance Schema setup\_objects Table](../performance-schema-setup_objects-table/index) |  Which objects are monitored.  |
|  [Performance Schema setup\_timers Table](../performance-schema-setup_timers-table/index) |  Currently selected event timers  |
|  [Performance Schema socket\_instances Table](../performance-schema-socket_instances-table/index) |  Active server connections.  |
|  [Performance Schema socket\_summary\_by\_event\_name Table](../performance-schema-socket_summary_by_event_name-table/index) |  Aggregates timer and byte count statistics for all socket I/O operations by socket instrument.  |
|  [Performance Schema socket\_summary\_by\_instance Table](../performance-schema-socket_summary_by_instance-table/index) |  Aggregates timer and byte count statistics for all socket I/O operations by socket instance.  |
|  [Performance Schema status\_by\_account Table](../performance-schema-status_by_account-table/index) |  Status variable information by user/host account.  |
|  [Performance Schema status\_by\_host Table](../performance-schema-status_by_host-table/index) |  Status variable information by host.  |
|  [Performance Schema status\_by\_thread Table](../performance-schema-status_by_thread-table/index) |  Status variable information about active foreground threads.  |
|  [Performance Schema status\_by\_user Table](../performance-schema-status_by_user-table/index) |  Status variable information by user.  |
|  [Performance Schema table\_handles Table](../performance-schema-table_handles-table/index) |  Table lock information.  |
|  [Performance Schema table\_io\_waits\_summary\_by\_index\_usage Table](../performance-schema-table_io_waits_summary_by_index_usage-table/index) |  Table I/O waits by index.  |
|  [Performance Schema table\_io\_waits\_summary\_by\_table Table](../performance-schema-table_io_waits_summary_by_table-table/index) |  Table I/O waits by table.  |
|  [Performance Schema table\_lock\_waits\_summary\_by\_table Table](../performance-schema-table_lock_waits_summary_by_table-table/index) |  Table lock waits by table.  |
|  [Performance Schema threads Table](../performance-schema-threads-table/index) |  Each server thread is represented as a row in the threads table.  |
|  [Performance Schema users Table](../performance-schema-users-table/index) |  User connection information.  |
|  [Performance Schema user\_variables\_by\_thread Table](../performance-schema-user_variables_by_thread-table/index) |  User-defined variables and the threads that defined them.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-tables/>

mysql.proc Table
================

    The `mysql.proc` table contains information about [stored procedures](../stored-procedures/index) and [stored functions](../stored-functions/index). It contains similar information to that stored in the [INFORMATION SCHEMA.ROUTINES](../information-schema-routines-table/index) table.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.proc` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `db` | `char(64)` | NO | PRI |  | Database name. |
| `name` | `char(64)` | NO | PRI |  | Routine name. |
| `type` | `enum('FUNCTION','PROCEDURE','PACKAGE', 'PACKAGE BODY')` | NO | PRI | `NULL` | Whether [stored procedure](../stored-procedures/index), [stored function](../stored-functions/index) or, from [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/), a [package](../create-package/index) or [package body](../create-package-body/index). |
| `specific_name` | `char(64)` | NO |  |  |  |
| `language` | `enum('SQL')` | NO |  | SQL | Always `SQL`. |
| `sql_data_access` | `enum('CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA')` | NO |  | `CONTAINS_SQL` |  |
| `is_deterministic` | `enum('YES','NO')` | NO |  | NO | Whether the routine is deterministic (can produce only one result for a given list of parameters) or not. |
| `security_type` | `enum('INVOKER','DEFINER')` | NO |  | `DEFINER` | `INVOKER` or `DEFINER`. Indicates which user's privileges apply to this routine. |
| `param_list` | `blob` | NO |  | `NULL` | List of parameters. |
| `returns` | `longblob` | NO |  | `NULL` | What the routine returns. |
| `body` | `longblob` | NO |  | `NULL` | Definition of the routine. |
| `definer` | `char(141)` | NO |  |  | If the `security_type` is `DEFINER`, this value indicates which user defined this routine. |
| `created` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` | Date and time the routine was created. |
| `modified` | `timestamp` | NO |  | 0000-00-00 00:00:00 | Date and time the routine was modified. |
| `sql_mode` | `set('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', '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')` | NO |  |  | The [SQL\_MODE](../sql-mode/index) at the time the routine was created. |
| `comment` | `text` | NO |  | `NULL` | Comment associated with the routine. |
| `character_set_client` | `char(32)` | YES |  | `NULL` | The [character set](../data-types-character-sets-and-collations/index) used by the client that created the routine. |
| `collation_connection` | `char(32)` | YES |  | `NULL` | The [collation](../data-types-character-sets-and-collations/index) (and character set) used by the connection that created the routine. |
| `db_collation` | `char(32)` | YES |  | `NULL` | The default [collation](../data-types-character-sets-and-collations/index) (and character set) for the database, at the time the routine was created. |
| `body_utf8` | `longblob` | YES |  | `NULL` | Definition of the routine in utf8. |
| `aggregate` | `enum('NONE', 'GROUP')` | NO |  | `NONE` | From [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| Field | Type | Null | Key | Default | Description |

 
See Also
--------

 * [Stored Procedure Internals](../stored-procedure-internals/index)
* [MySQL to MariaDB migration: handling privilege table differences when using mysqldump](https://mariadb.com/blog/mysql-mariadb-migration-handling-privilege-table-differences-when-using-mysqldump)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlproc-table/>

Compression Plugins
===================

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**Compressions plugins were added in a [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/) preview release.

 
 The various MariaDB storage engines, such as [InnoDB](../innodb/index), [RocksDB](../myrocks/index), [Mroonga](../mroonga/index), can use different compression libraries. 

 Before [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/), each separate library would have to be compiled in in order to be available for use, resulting in numerous runtime/rpm/deb dependencies, most of which would never be used by users. 

 From [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/), five additional MariaDB compression libraries (besides the default zlib) are available as plugins (note that these affect InnoDB and Mroonga only; RocksDB still uses the compression algorithms from its own library):

 * bzip2
* lzma
* lz4
* lzo
* snappy

 Installing
----------

 To use, these simply need to be [installed as a plugin](../install-soname/index):

 
```
INSTALL SONAME 'provider_lz4';

```

The compression algorithm can then be used, for example, in [InnoDB compression](../innodb-page-compression/index):

 
```
SET GLOBAL innodb_compression_algorithm = lz4;

```

Upgrading
---------

 When upgrading from a release without compression plugins, if a non-zlib compression algorithm was used, those tables will be unreadable until the appropriate compression library is installed. [mariadb-upgrade](../mysql_upgrade/index) should be run. The `--force` option (to run [mariadb-check](../mysqlcheck/index)) or `mariadb-check` itself will indicate any problems with compression, for example:

 
```
Warning  : MariaDB tried to use the LZMA compression, but its provider plugin is not loaded

Error    : Table 'test.t' doesn't exist in engine

status   : Operation failed

```

or

 
```
Error    : Table test/t is compressed with lzma, which is not currently loaded. 
  Please load the lzma provider plugin to open the table

error    : Corrupt

```

In this case, the appropriate compression plugin should be installed, and the server restarted.

 See Also
--------

 * [10.7 preview feature: Compression Provider Plugins](https://mariadb.org/10-7-preview-feature-provider-plugins/) (mariadb.org blog)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compression-plugins/>

Building the best INDEX for a given SELECT
==========================================

    The problem
-----------

 You have a SELECT and you want to build the best INDEX for it. This blog is a "cookbook" on how to do that task.

 * A short algorithm that works for many simpler SELECTs and helps in complex queries.
* Examples of the algorithm, plus digressions into exceptions and variants
* Finally a long list of "other cases".

 The hope is that a newbie can quickly get up to speed, and his/her INDEXes will no longer smack of "newbie".

 Many edge cases are explained, so even an expert may find something useful here.

 Algorithm
---------

 Here's the way to approach creating an INDEX, given a SELECT. Follow the steps below, gathering columns to put in the INDEX in order. When the steps give out, you usually have the 'perfect' index.

  1. Given a WHERE with a bunch of expressions connected by AND: Include the columns (if any), in any order, that are compared to a constant and not hidden in a function. 2. You get one more chance to add to the INDEX; do the first of these that applies:

 * 2a. One column used in a 'range' -- BETWEEN, '>', LIKE w/o leading wildcard, etc.
* 2b. All columns, in order, of the GROUP BY.
* 2c. All columns, in order, of the ORDER BY if there is no mixing of ASC and DESC.

 Digression
----------

 This blog assumes you know the basic idea behind having an INDEX. Here is a refresher on some of the key points.

 Virtually all INDEXes in MySQL are structured as BTrees BTrees allow very efficient for

 * Given a key, find the corresponding row(s);
* "Range scans" -- That is start at one value for the key and repeatedly find the "next" (or "previous") row.

 A PRIMARY KEY is a UNIQUE KEY; a UNIQUE KEY is an INDEX. ("KEY" == "INDEX".)

 InnoDB "clusters" the PRIMARY KEY with the data. Hence, given the value of the PK ("PRIMARY KEY"), after drilling down the BTree to find the index entry, you have all the columns of the row when you get there. A "secondary key" (any UNIQUE or INDEX other than the PK) in InnoDB first drills down the BTree for the secondary index, where it finds a copy of the PK. Then it drills down the PK to find the row.

 Every InnoDB table has a PRIMARY KEY. While there is a default if you do not specify one, it is best to explicitly provide a PK.

 For completeness: MyISAM works differently. All indexes (including the PK) are in separate BTrees. The leaf node of such BTrees have a pointer (usually a byte offset) into the data file.

 All discussion here assumes InnoDB tables, however most statements apply to other Engines.

 First, some examples
--------------------

 Think of a list of names, sorted by last\_name, then first\_name. You have undoubtedly seen such lists, and they often have other information such as address and phone number. Suppose you wanted to look me up. If you remember my full name ('James' and 'Rick'), it is easy to find my entry. If you remembered only my last name ('James') and first initial ('R'). You would quickly zoom in on the Jameses and find the Rs in them. There, you might remember 'Rick' and ignore 'Ronald'. But, suppose you remembered my first name ('Rick') and only my last initial ('J'). Now you are in trouble. You would be scanning all the Js -- Jones, Rick; Johnson, Rick; Jamison, Rick; etc, etc. That's much less efficient.

 Those equate to

 
```
    INDEX(last_name, first_name) -- the order of the list.
    WHERE last_name = 'James' AND first_name = 'Rick'  -- best case
    WHERE last_name = 'James' AND first_name LIKE 'R%' -- pretty good
    WHERE last_name LIKE 'J%' AND first_name = 'Rick'  -- pretty bad

```

Think about this example as I talk about "=" versus "range" in the Algorithm, below.

 Algorithm, step 1 (WHERE "column = const")
------------------------------------------

 * `WHERE aaa = 123 AND ...` : an INDEX starting with aaa is good.
* `WHERE aaa = 123 AND bbb = 456 AND ...` : an INDEX starting with aaa and bbb is good. In this case, it does not matter whether aaa or bbb comes first in the INDEX.
* `xxx IS NULL` : this acts like "= const" for this discussion.
* `WHERE t1.aa = 123 AND t2.bb = 456` -- You must only consider columns in the current table.

 Note that the expression must be of the form of `column\_name` = (constant). These do not apply to this step in the Algorithm: DATE(dt) = '...', LOWER(s) = '...', CAST(s ...) = '...', x='...' COLLATE...

 (If there are no "=" parts AND'd in the WHERE clause, move on to step 2 without any columns in your putative INDEX.)

 Algorithm, step 2
-----------------

 Find the first of 2a / 2b / 2c that applies; use it; then quit. If none apply, then you are through gathering columns for the index.

 In some cases it is optimal to do step 1 (all equals) plus step 2c (ORDER BY).

 Algorithm, step 2a (one range)
------------------------------

 A "range" shows up as

 * `aaa >= 123` -- any of <, <=, >=, >; but not <>, !=
* `aaa BETWEEN 22 AND 44`
* `sss LIKE 'blah%'` -- but not `sss LIKE '%blah'`
* `xxx IS NOT NULL` Add the column in the range to your putative INDEX.

 If there are more parts to the WHERE clause, you must stop now.

 Complete examples (assume nothing else comes after the snippet)

 * `WHERE aaa >= 123 AND bbb = 1 ⇒ INDEX(bbb, aaa)` (WHERE order does not matter; INDEX order does)
* `WHERE aaa >= 123 ⇒ INDEX(aaa)`
* `WHERE aaa >= 123 AND ccc > 'xyz' ⇒ INDEX(aaa) or INDEX(ccc)` (only one range)
* `WHERE aaa >= 123 ORDER BY aaa ⇒ INDEX(aaa)` -- Bonus: The ORDER BY will use the INDEX.
* `WHERE aaa >= 123 ORDER BY aaa ⇒ INDEX(aaa) DESC` -- Same Bonus.

 Algorithm, step 2b (GROUP BY)
-----------------------------

 If there is a GROUP BY, all the columns of the GROUP BY should now be added, in the specified order, to the INDEX you are building. (I do not know what happens if one of the columns is already in the INDEX.)

 If you are GROUPing BY an expression (including function calls), you cannot use the GROUP BY; stop.

 Complete examples (assume nothing else comes after the snippet)

 * `WHERE aaa = 123 AND bbb = 1 GROUP BY ccc ⇒ INDEX(bbb, aaa, ccc) or INDEX(aaa, bbb, ccc)` (='s first, in any order; then the GROUP BY)
* `WHERE aaa >= 123 GROUP BY xxx ⇒ INDEX(aaa)` (You should have stopped with Step 2a)
* `GROUP BY x,y ⇒ INDEX(x,y)` (no WHERE)
* `WHERE aaa = 123 GROUP BY xxx, (a+b) ⇒ INDEX(aaa)` -- expression in GROUP BY, so no use including even xxx.

 Algorithm, step 2c (ORDER BY)
-----------------------------

 If there is a ORDER BY, all the columns of the ORDER BY should now be added, in the specified order, to the INDEX you are building.

 If there are multiple columns in the ORDER BY, and there is a mixture of ASC and DESC, do not add the ORDER BY columns; they won't help; stop.

 If you are ORDERing BY an expression (including function calls), you cannot use the ORDER BY; stop.

 Complete examples (assume nothing else comes after the snippet)

 * `WHERE aaa = 123 GROUP BY ccc ORDER BY ddd ⇒ INDEX(aaa, ccc)` -- should have stopped with Step 2b
* `WHERE aaa = 123 GROUP BY ccc ORDER BY ccc ⇒ INDEX(aaa, ccc)` -- the ccc will be used for both GROUP BY and ORDER BY
* `WHERE aaa = 123 ORDER BY xxx ASC, yyy DESC ⇒ INDEX(aaa)` -- mixture of ASC and DESC.

 The following are especially good. Normally a LIMIT cannot be applied until after lots of rows are gathered and then sorted according to the ORDER BY. But, if the INDEX gets all they way through the ORDER BY, only (OFFSET + LIMIT) rows need to be gathered. So, in these cases, you win the lottery with your new index:

 * `WHERE aaa = 123 GROUP BY ccc ORDER BY ccc LIMIT 10 ⇒ INDEX(aaa, ccc)`
* `WHERE aaa = 123 ORDER BY ccc LIMIT 10 ⇒ INDEX(aaa, ccc)`
* `ORDER BY ccc LIMIT 10 ⇒ INDEX(ccc)`
* `WHERE ccc > 432 ORDER BY ccc LIMIT 10 ⇒ INDEX(ccc)` -- This "range" is compatible with ORDER BY

 (It does not make much sense to have a LIMIT without an ORDER BY, so I do not discuss that case.)

 Algorithm end
-------------

 You have collected a few columns; put them in INDEX and ADD that to the table. That will often produce a "good" index for the SELECT you have. Below are some other suggestions that may be relevant.

 An example of the Algorithm being 'wrong':

 
```
    SELECT ... FROM t WHERE flag = true;

```

This would (according to the Algorithm) call for INDEX(flag). However, indexing a column that has two (or a small number of) values is almost always useless. This is called 'low cardinality'. The Optimizer would prefer to do a table scan than to bounce between the index BTree and the data.

 On the other hand, the Algorithm is 'right' with

 
```
    SELECT ... FROM t WHERE flag = true AND date >= '2015-01-01';

```

That would call for a compound index starting with a flag: INDEX(flag, date). Such an index is likely to be very beneficial. And it is likely to be more beneficial than INDEX(date).

 If your resulting INDEX include column(s) that are likely to be UPDATEd, note that the UPDATE will have extra work to remove a 'row' from one place in the INDEX's BTree and insert a 'row' back into the BTree. For example:

 
```
INDEX(x)
UPDATE t SET x = ... WHERE ...;

```

There are too many variables to say whether it is better to keep the index or to toss it.

 In this case, shortening the index may may be beneficial:

 
```
INDEX(z, x)
UPDATE t SET x = ... WHERE ...;

```

Changing to INDEX(z) would make for less work for the UPDATE, but might hurt some SELECT. It depends on the frequency of each, plus many more factors.

 Limitations
-----------

 (There are exceptions to some of these.)

 * You may not create an index bigger than 3KB.
* You may not include a column that equates to bigger than some value (767 bytes -- VARCHAR(255) CHARACTER SET utf8).
* You can deal with big fields using "prefix" indexing; but see below.
* You should not have more than 5 columns in an index. (This is just a Rule of Thumb; nothing prevents having more.)
* You should not have redundant indexes. (See below.)

 Flags and low cardinality
-------------------------

 `INDEX(flag)` is almost never useful if `flag` has very few values. More specifically, when you say WHERE flag = 1 and "1" occurs more than 20% of the time, such an index will be shunned. The Optimizer would prefer to scan the table instead of bouncing back and forth between the index and the data for more than 20% of the rows.

 ("20%" is really somewhere between 10% and 30%, depending on the phase of the moon.)

 "Covering" indexes
------------------

 A "Covering" index is an index that contains all the columns in the SELECT. It is special in that the SELECT can be completed by looking only at the INDEX BTree. (Since InnoDB's PRIMARY KEY is clustered with the data, "covering" is of no benefit when considering at the PRIMARY KEY.)

 Mini-cookbook: 1. Gather the list of column(s) according to the "Algorithm", above. 2. Add to the end of the list the rest of the columns seen in the SELECT, in any order.

 Examples:

 * `SELECT x FROM t WHERE y = 5; ⇒ INDEX(y,x)` -- The algorithm said just INDEX(y)
* `SELECT x,z FROM t WHERE y = 5 AND q = 7; ⇒ INDEX(y,q,x,z)` -- y and q in either order (Algorithm), then x and z in either order (covering).
* `SELECT x FROM t WHERE y > 5 AND q > 7; ⇒ INDEX(y,q,x)` -- y or q first (that's as far as the Algorithm goes), then the other two fields afterwards.

 The speedup you get might be minor, or it might be spectacular; it is hard to predict.

 But...

 * It is not wise to build an index with lots of columns. Let's cut it off at 5 (Rule of Thumb).
* Prefix indexes cannot 'cover', so don't use them anywhere in a 'covering' index.
* There are limits (3KB?) on how 'wide' an index can be, so "covering" may not be possible.

 Redundant/excessive indexes
---------------------------

 INDEX(a,b) can find anything that INDEX(a) could find. So you don't need both. Get rid of the shorter one.

 If you have lots of SELECTs and they generate lots of INDEXes, this may cause a different problem. Each index must be updated (sooner or later) for each INSERT. More indexes ⇒ slower INSERTs. Limit the number of indexes on a table to about 6 (Rule of Thumb).

 Notice in the cookbook how it says "in any order" in a few places. If, for example, you have both of these (in different SELECTs):

 * `WHERE a=1 AND b=2` begs for either INDEX(a,b) or INDEX(b,a)
* `WHERE a>1 AND b=2` begs only for INDEX(b,a) Include only INDEX(b,a) since it handles both cases with only one INDEX.

 Suppose you have a lot of indexes, including (a,b,c,dd) and (a,b,c,ee). Those are getting rather long. Consider either picking one of them, or having simply (a,b,c). Sometimes the selectivity of (a,b,c) is so good that tacking on 'dd' or 'ee' does make enough difference to matter.

 Optimizer picks ORDER BY
------------------------

 The main cookbook skips over an important optimization that is sometimes used. The optimizer will sometimes ignore the WHERE and, instead, use an INDEX that matches the ORDER BY. This, of course, needs to be a perfect match -- all columns, in the same order. And all ASC or all DESC.

 This becomes especially beneficial if there is a LIMIT.

 But there is a problem. There could be two situations, and the Optimizer is sometimes not smart enough to see which case applies:

 * If the WHERE does very little filtering, fetching the rows in ORDER BY order avoids a sort and has little wasted effort (because of 'little filtering'). Using the INDEX matching the ORDER BY is better in this case.
* If the WHERE does a lot of filtering, the ORDER BY is wasting a lot of time fetching rows only to filter them out. Using an INDEX matching the WHERE clause is better.

 What should you do? If you think the "little filtering" is likely, then create an index with the ORDER BY columns in order and hope that the Optimizer uses it when it should.

 OR
--

 Cases...

 * `WHERE a=1 OR a=2` -- This is turned into WHERE a IN (1,2) and optimized that way.
* `WHERE a=1 OR b=2` usually cannot be optimized.
* `WHERE x.a=1 OR y.b=2` This is even worse because of using two different tables.

 A workaround is to use UNION. Each part of the UNION is optimized separately. For the second case:

 
```
   ( SELECT ... WHERE a=1 )   -- and have INDEX(a)
   UNION DISTINCT -- "DISTINCT" is assuming you need to get rid of dups
   ( SELECT ... WHERE b=2 )   -- and have INDEX(b)
   GROUP BY ... ORDER BY ...  -- whatever you had at the end of the original query

```

Now the query can take good advantage of two different indexes. Note: "Index merge" might kick in on the original query, but it is not necessarily any faster than the UNION. Sister blog on compound indexes, including 'Index Merge'

 The third case (OR across 2 tables) is similar to the second.

 If you originally had a LIMIT, UNION gets complicated. If you started with ORDER BY z LIMIT 190, 10, then the UNION needs to be

 
```
   ( SELECT ... LIMIT 200 )   -- Note: OFFSET 0, LIMIT 190+10
   UNION DISTINCT -- (or ALL)
   ( SELECT ... LIMIT 200 )
   LIMIT 190, 10              -- Same as originally

```

TEXT / BLOB
-----------

 You cannot directly index a TEXT or BLOB or large VARCHAR or large BINARY column. However, you can use a "prefix" index: INDEX(foo(20)). This says to index the first 20 characters of `foo`. But... It is rarely useful.

 Example of a prefix index:

 
```
    INDEX(last_name(2), first_name)

```

The index for me would contain 'Ja', 'Rick'. That's not useful for distinguishing between 'Jamison', 'Jackson', 'James', etc., so the index is so close to useless that the optimizer often ignores it.

 Probably never do UNIQUE(foo(20)) because this applies a uniqueness constraint on the first 20 characters of the column, not the whole column!

 [More on prefix indexing](http://dev.mysql.com/doc/refman/5.6/en/create-index.html)

 Dates
-----

 DATE, DATETIME, etc. are tricky to compare against.

 Some tempting, but inefficient, techniques:

  `date_col LIKE '2016-01%'` -- must convert date\_col to a string, so acts like a function `LEFT(date_col, 4) = '2016-01'` -- hiding the column in function `DATE(date_col) = 2016` -- hiding the column in function

 All must do a full scan. (On the other hand, it can handy to use GROUP BY LEFT(date\_col, 7) for monthly grouping, but that is not an INDEX issue.)

 This is efficient, and can use an index:

 
```
        date_col >= '2016-01-01'
    AND date_col  < '2016-01-01' + INTERVAL 3 MONTH

```

This case works because both right-hand values are converted to constants, then it is a "range". I like the design pattern with INTERVAL because it avoids computing the last day of the month. And it avoids tacking on '23:59:59', which is wrong if you have microsecond times. (And other cases.)

 EXPLAIN Key\_len
----------------

 Perform EXPLAIN SELECT... (and EXPLAIN FORMAT=JSON SELECT... if you have 5.6.5). Look at the Key that it chose, and the Key\_len. From those you can deduce how many columns of the index are being used for filtering. (JSON makes it easier to get the answer.) From that you can decide whether it is using as much of the INDEX as you thought. Caveat: Key\_len only covers the WHERE part of the action; the non-JSON output won't easily say whether GROUP BY or ORDER BY was handled by the index.

 IN
--

 `IN (1,99,3)` is sometimes optimized as efficiently as "=", but not always. Older versions of MySQL did not optimize it as well as newer versions. (5.6 is possibly the main turning point.)

 IN ( SELECT ... )

 From version 4.1 through 5.5, IN ( SELECT ... ) was very poorly optimized. The SELECT was effectively re-evaluated every time. Often it can be transformed into a JOIN, which works much faster. Heres is a pattern to follow:

 
```
SELECT  ...
    FROM  a
    WHERE  test_a
      AND  x IN (
        SELECT  x
            FROM  b
            WHERE  test_b
                );
⇒
SELECT  ...
    FROM  a
    JOIN  b USING(x)
    WHERE  test_a
      AND  test_b;

```

The SELECT expressions will need "a." prefixing the column names.

 Alas, there are cases where the pattern is hard to follow.

 5.6 does some optimizing, but probably not as good as the JOIN.

 If there is a JOIN or GROUP BY or ORDER BY LIMIT in the subquery, that complicates the JOIN in new format. So, it might be better to use this pattern:

 
```
SELECT  ...
    FROM  a
    WHERE  test_a
      AND  x IN ( SELECT  x  FROM ... );
⇒
SELECT  ...
    FROM  a
    JOIN        ( SELECT  x  FROM ... ) b
        USING(x)
    WHERE  test_a;

```

Caveat: If you end up with two subqueries JOINed together, note that neither has any indexes, hence performance can be very bad. (5.6 improves on it by dynamically creating indexes for subqueries.)

 There is work going on in MariaDB and Oracle 5.7, in relation to "NOT IN", "NOT EXISTS", and "LEFT JOIN..IS NULL"; here is an old discussion on the topic So, what I say here may not be the final word.

 Explode/Implode
---------------

 When you have a JOIN and a GROUP BY, you may have the situation where the JOIN exploded more rows than the original query (due to many:many), but you wanted only one row from the original table, so you added the GROUP BY to implode back to the desired set of rows.

 This explode + implode, itself, is costly. It would be better to avoid them if possible.

 Sometimes the following will work.

 Using DISTINCT or GROUP BY to counteract the explosion

 
```
SELECT  DISTINCT
        a.*,
        b.y
    FROM a
    JOIN b
⇒
SELECT  a.*,
        ( SELECT GROUP_CONCAT(b.y) FROM b WHERE b.x = a.x ) AS ys
    FROM a

```

When using second table just to check for existence:

 
```
SELECT  a.*
    FROM a
    JOIN b  ON b.x = a.x
    GROUP BY a.id
⇒
SELECT  a.*,
    FROM a
    WHERE EXISTS ( SELECT *  FROM b  WHERE b.x = a.x )

```

[Another variant](http://dba.stackexchange.com/questions/115059/mysql-query-causing-high-cpu-and-taking-forever-to-execute/115120#115120)

 Many-to-many mapping table
--------------------------

 Do it this way.

 
```
    CREATE TABLE XtoY (
        # No surrogate id for this table
        x_id MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to one table
        y_id MEDIUMINT UNSIGNED NOT NULL,   -- For JOINing to the other table
        # Include other fields specific to the 'relation'
        PRIMARY KEY(x_id, y_id),            -- When starting with X
        INDEX      (y_id, x_id)             -- When starting with Y
    ) ENGINE=InnoDB;

```

Notes:

 * Lack of an AUTO\_INCREMENT id for this table -- The PK given is the 'natural' PK; there is no good reason for a surrogate.
* "MEDIUMINT" -- This is a reminder that all INTs should be made as small as is safe (smaller ⇒ faster). Of course the declaration here must match the definition in the table being linked to.
* "UNSIGNED" -- Nearly all INTs may as well be declared non-negative
* "NOT NULL" -- Well, that's true, isn't it?
* "InnoDB" -- More effecient than MyISAM because of the way the PRIMARY KEY is clustered with the data in InnoDB.
* "INDEX(y\_id, x\_id)" -- The PRIMARY KEY makes it efficient to go one direction; this index makes the other direction efficient. No need to say UNIQUE; that would be extra effort on INSERTs.
* In the secondary index, saying justINDEX(y\_id) would work because it would implicit include x\_id. But I would rather make it more obvious that I am hoping for a 'covering' index.

 To conditionally INSERT new links, use [IODKU](http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html)

 Note that if you had an AUTO\_INCREMENT in this table, IODKU would "burn" ids quite rapidly.

 Subqueries and UNIONs
---------------------

 Each subquery SELECT and each SELECT in a UNION can be considered separately for finding the optimal INDEX.

 Exception: In a "correlated" ("dependent") subquery, the part of the WHERE that depends on the outside table is not easily factored into the INDEX generation. (Cop out!)

 JOINs
-----

 The first step is to decide what order the optimizer will go through the tables. If you cannot figure it out, then you may need to be pessimistic and create two indexes for each table -- one assuming the table will be used first, one assiming that it will come later in the table order.

 The optimizer usually starts with one table and extracts the data needed from it. As it finds a useful (that is, matches the WHERE clause, if any) row, it reaches into the 'next' table. This is called NLJ ("Nested Loop Join"). The process of filtering and reaching to the next table continues through the rest of the tables.

 The optimizer usually picks the "first" table based on these hints:

 * STRAIGHT\_JOIN forces the the table order.
* The WHERE clause limits which rows needed (whether indexed or not).
* The table to the "left" in a LEFT JOIN usually comes before the "right" table. (By looking at the table definitions, the optimizer may decide that "LEFT" is irrelevant.)
* The current INDEXes will encourage an order.
* etc.

 Running EXPLAIN tells you the table order that the Optimizer is very likely to use today. After adding a new INDEX, the optimizer may pick a different table order. You should anticipate the order changing, guess at what order makes the most sense, and build the INDEXes accordingly. Then rerun EXPLAIN to see if the Optimizer's brain was on the same wavelength you were on.

 You should build the INDEX for the "first" table based on any parts of the WHERE, GROUP BY, and ORDER BY clauses that are relevant to it. If a GROUP/ORDER BY mentions a different table, you should ignore that clause.

 The second (and subsequent) table will be reached into based on the ON clause. (Instead of using commajoin, please write JOINs with the JOIN keyword and ON clause!) In addition, there could be parts of the WHERE clause that are relevant. GROUP/ORDER BY are not to be considered in writing the optimal INDEX for subsequent tables.

 PARTITIONing
------------

 PARTITIONing is rarely a substitute for a good INDEX.

 PARTITION BY RANGE is a technique that is sometimes useful when indexing fails to be good enough. In a two-dimensional situation such as nearness in a geographical sense, one dimension can partially be handled by partition pruning; then the other dimension can be handled by a regular index (preferrably the PRIMARY KEY). This goes into more detail: [Find nearest 10 pizza parlors](../mariadb/partition-maintenance/index).

 FULLTEXT
--------

 FULLTEXT is now implemented in InnoDB as well as MyISAM. It provides a way to search for "words" in TEXT columns. This is much faster (when it is applicable) than col LIKE '%word%'.

 
```
    WHERE x = 1
      AND MATCH (...) AGAINST (...)

```

always(?) uses the FULLTEXT index first. That is, the whole Algorithm is invalidated when one of the ANDs is a MATCH.

 Signs of a Newbie
-----------------

 * No "compound" (aka "composite") indexes
* No PRIMARY KEY
* Redundant indexes (especially blatant is PRIMARY KEY(id), KEY(id))
* Most or all columns individually indexes ("But I indexed everything")
* "Commajoin" -- That is `FROM a, b WHERE a.x=b.x` instead of `FROM a JOIN b ON a.x=b.x`

 Speeding up wp\_postmeta
------------------------

 The published table (see Wikipedia) is

 
```
    CREATE TABLE wp_postmeta (
      meta_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      post_id bigint(20) unsigned NOT NULL DEFAULT '0',
      meta_key varchar(255) DEFAULT NULL,
      meta_value longtext,
      PRIMARY KEY (meta_id),
      KEY post_id (post_id),
      KEY meta_key (meta_key)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

```

The problems:

 * The AUTO\_INCREMENT provides no benefit; in fact it slows down most queries and clutters disk.
* Much better is PRIMARY KEY(post\_id, meta\_key) -- clustered, handles both parts of usual JOIN.
* BIGINT is overkill, but that can't be fixed without changing other tables.
* VARCHAR(255) can be a problem in 5.6 with utf8mb4; see workarounds below.
* When would `meta\_key` or `meta\_value` ever be NULL?

 The solutions:

 
```
    CREATE TABLE wp_postmeta (
        post_id BIGINT UNSIGNED NOT NULL,
        meta_key VARCHAR(255) NOT NULL,
        meta_value LONGTEXT NOT NULL,
        PRIMARY KEY(post_id, meta_key),
        INDEX(meta_key)
        ) ENGINE=InnoDB;

```

Postlog
-------

 Initial posting: March, 2015; Refreshed Feb, 2016; Add DATE June, 2016; Add WP example May, 2017.

 The tips in this document apply to MySQL, MariaDB, and Percona.

 See also
--------

 * [Percona 2015 Tutorial Slides](http://mysql.rjweb.org/slides/IndexCookbook.pdf)
* Some info in the MySQL manual: [ORDER BY Optimization](http://dev.mysql.com/doc/refman/5.6/en/order-by-optimization.html)
* A short, but complicated, [example](http://stackoverflow.com/questions/28974572/mysql-index-for-order-by-with-date-range-in-where)
* [MySQL manual page on range accesses in composite indexes](http://dev.mysql.com/doc/refman/5.7/en/range-optimization.html#range-access-multi-part)
* [Some discussion of JOIN](http://dba.stackexchange.com/questions/120551/very-slow-query-not-sure-if-mysql-index-is-being-used)
* [Indexing 101: Optimizing MySQL queries on a single table](https://www.percona.com/blog/2015/04/27/indexing-101-optimizing-mysql-queries-on-a-single-table/) (Stephane Combaudon - Percona)
* [A complex query, well explained.](http://stackoverflow.com/a/37024870/1766831)

 This blog is the consolidation of a Percona tutorial I gave in 2013, plus many years of experience in fixing thousands of slow queries on hundreds of systems. I apologize that this does not tell you how create INDEXes for all SELECTs. Some are just too complex.

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/random>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-the-best-index-for-a-given-select/>

Data-at-Rest Encryption
========================

   MariaDB supports the use of data-at-rest encryption for tables and tablespaces. For a minor performance overhead of 3-5%, this makes it almost impossible for someone with access to the host system or who steals a hard drive to read the original data.

  

| Title | Description |
| --- | --- |
|  [Data-at-Rest Encryption Overview](../data-at-rest-encryption-overview/index) |  Having data encrypted will make it hard for someone to steal your data.  |
|  [Why Encrypt MariaDB Data?](../why-encrypt-mariadb-data/index) |  When to use encryption for MariaDB data.  |
|  [Key Management and Encryption Plugins](../key-management-and-encryption-plugins/index) |  MariaDB uses plugins to handle key management and encryption of data.  |
|  [Encrypting Binary Logs](../encrypting-binary-logs/index) |  Data-at-rest encryption for binary logs and relay logs.  |
|  [Aria Encryption](../aria-encryption/index) |  Configuration and use of data-at-rest encryption with the Aria storage engine.  |
|  [InnoDB Encryption](../innodb-encryption/index) |  Articles on using data-at-rest encryption with the InnoDB storage engine.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encryption/>

mariadb\_schema
===============

     `mariadb_schema` is a data type qualifier that allows one to create MariaDB native date types in an [SQL\_MODE](../sql-mode/index) that has conflicting data type translations.

 `mariadb_schema` was introduced in [MariaDB 10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [MariaDB 10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [MariaDB 10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/).

 For example, in [SQL\_MODE=ORACLE](../sql_modeoracle/index), if one creates a table with the [DATE](../date/index) type, it will actually create a [DATETIME](../datetime/index#oracle-mode) column to match what an Oracle user is expecting. To be able to create a MariaDB DATE in Oracle mode one would have to use `mariadb_schema`:

 
```
CREATE TABLE t1 (d mariadb_schema.DATE);

```

`mariadb_schema` is also shown if one creates a table with `DATE` in MariaDB native mode and then does a [SHOW CREATE TABLE](../show-create-table/index) in `ORACLE` mode:

 
```
SET sql_mode=DEFAULT;
CREATE OR REPLACE TABLE t1 (
  d DATE
);
SET SQL_mode=ORACLE;
SHOW CREATE TABLE t1;
+-------+--------------------------------------------------------------+
| Table | Create Table                                                 |
+-------+--------------------------------------------------------------+
| t1    | CREATE TABLE "t1" (
  "d" mariadb_schema.date DEFAULT NULL
) |
+-------+--------------------------------------------------------------+

```

When the server sees the `mariadb_schema` qualifier, it disables sql\_mode-specific data type translation and interprets the data type literally, so for example `mariadb_schema.DATE` is interpreted as the traditional MariaDB `DATE` data type, no matter what the current sql\_mode is.

 The `mariadb_schema` prefix is displayed only when the data type name would be ambiguous otherwise. The prefix is displayed together with MariaDB `DATE` when [SHOW CREATE TABLE](../show-create-table/index) is executed in [SQL\_MODE=ORACLE](../sql_modeoracle/index). The prefix is not displayed when [SHOW CREATE TABLE](../show-create-table/index) is executed in SQL\_MODE=DEFAULT, or when a non-ambiguous data type is displayed.

 Note, the `mariadb_schema` prefix can be used with any data type, including non-ambiguous ones:

 
```
CREATE OR REPLACE TABLE t1 (a mariadb_schema.INT);
SHOW CREATE TABLE t1;
+-------+--------------------------------------------------+
| Table | Create Table                                     |
+-------+--------------------------------------------------+
| t1    | CREATE TABLE "t1" (
  "a" int(11) DEFAULT NULL
) |
+-------+--------------------------------------------------+

```

Currently the `mariadb_schema` prefix is only used in the following case:

 * For a MariaDB native [DATE](../date/index) type when running [SHOW CREATE TABLE](../show-create-table/index) in [Oracle mode](../sql_modeoracle/index).

 History
-------

 When running with [SQL\_MODE=ORACLE](../sql_modeoracle/index), MariaDB server translates the data type `DATE` to `DATETIME`, for better Oracle compatibility:

 
```
SET SQL_mode=ORACLE;
CREATE OR REPLACE TABLE t1 (
  d DATE
);
SHOW CREATE TABLE t1;
+-------+---------------------------------------------------+
| Table | Create Table                                      |
+-------+---------------------------------------------------+
| t1    | CREATE TABLE "t1" (
  "d" datetime DEFAULT NULL
) |
+-------+---------------------------------------------------+

```

Notice, `DATE` was translated to `DATETIME`.

 This translation may cause some ambiguity. Suppose a user creates a table with a column of the traditional MariaDB `DATE` data type using the default sql\_mode, but then switches to [SQL\_MODE=ORACLE](../sql_modeoracle/index) and runs a [SHOW CREATE TABLE](../show-create-table/index) statement:

 
```
SET sql_mode=DEFAULT;
CREATE OR REPLACE TABLE t1 (
  d DATE
);
SET SQL_mode=ORACLE;
SHOW CREATE TABLE t1;

```

Before `mariadb_schema` was introduced, the above script displayed:

 
```
CREATE TABLE "t1" (
  "d" date DEFAULT NULL
);

```

which had two problems:

 * It was confusing for the reader: its not clear if it is the traditional MariaDB `DATE`, or is it Oracle-alike date (which is actually `DATETIME`);
* It broke replication and caused data type mismatch on the master and on the slave (see [MDEV-19632](https://jira.mariadb.org/browse/MDEV-19632)).

 To address this problem, starting from the mentioned versions, MariaDB uses the idea of qualified data types:

 
```
SET sql_mode=DEFAULT;
CREATE OR REPLACE TABLE t1 (
  d DATE
);
SET SQL_mode=ORACLE;
SHOW CREATE TABLE t1;
+-------+--------------------------------------------------------------+
| Table | Create Table                                                 |
+-------+--------------------------------------------------------------+
| t1    | CREATE TABLE "t1" (
  "d" mariadb_schema.date DEFAULT NULL
) |
+-------+--------------------------------------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb_schema/>

Storage Engine Index Types
==========================

     This refers to the index\_type definition when creating an index, i.e. BTREE, HASH or RTREE.

 For more information on general types of indexes, such as primary keys, unique indexes etc, go to [Getting Started with Indexes](../getting-started-with-indexes/index).

 


| Storage Engine | Permitted Indexes |
| --- | --- |
| [Aria](../aria/index) | BTREE, RTREE |
| [MyISAM](../myisam/index) | BTREE, RTREE |
| [InnoDB](../innodb/index) | BTREE |
| [MEMORY/HEAP](../memory-storage-engine/index) | HASH, BTREE |

 
BTREE is generally the default index type. For [MEMORY](../memory-storage-engine/index) tables, HASH is the default. [TokuDB](../tokudb/index) uses a particular data structure called *fractal trees*, which is optimized for data that do not entirely fit memory.

  Understanding the B-tree and hash data structures can help predict how different queries perform on different storage engines that use these data structures in their indexes, particularly for the MEMORY storage engine that lets you choose B-tree or hash indexes. B-Tree Index Characteristics

 B-tree Indexes
--------------

 B-tree indexes are used for column comparisons using the >, >=, =, >=, < or BETWEEN operators, as well as for LIKE comparisons that begin with a constant.

 For example, the query `SELECT * FROM Employees WHERE First_Name LIKE 'Maria%';` can make use of a B-tree index, while `SELECT * FROM Employees WHERE First_Name LIKE '%aria';` cannot.

 B-tree indexes also permit leftmost prefixing for searching of rows.

 If the number or rows doesn't change, hash indexes occupy a fixed amount of memory, which is lower than the memory occupied by BTREE indexes.

 Hash Indexes
------------

 Hash indexes, in contrast, can only be used for equality comparisons, so those using the = or <=> operators. They cannot be used for ordering, and provide no information to the optimizer on how many rows exist between two values.

 Hash indexes do not permit leftmost prefixing - only the whole index can be used.

 R-tree Indexes
--------------

 See [SPATIAL](../spatial/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engine-index-types/>

Primary Keys with Nullable Columns
==================================

    
**MariaDB starting with [10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/)**[MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) introduced new behavior for dealing with primary keys over nullable columns.

 
Take the following table structure:

 
```
CREATE TABLE t1(
  c1 INT NOT NULL AUTO_INCREMENT, 
  c2 INT NULL DEFAULT NULL, 
  PRIMARY KEY(c1,c2)
);

```

Column c2 is part of a primary key, and thus it cannot be [NULL](../null-values/index).

 Before [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), MariaDB (as well as versions of MySQL before MySQL 5.7) would silently convert it into a NOT NULL column with a default value of *0*.

 Since [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/), the column is converted to NOT NULL, but without a default value. If we then attempt to insert a record without explicitly setting *c2*, a warning (or, in strict mode, an error), will be thrown, for example:

 
```
INSERT INTO t1() VALUES();
Query OK, 1 row affected, 1 warning (0.00 sec)
Warning (Code 1364): Field 'c2' doesn't have a default value

SELECT * FROM t1;
+----+----+
| c1 | c2 |
+----+----+
|  1 |  0 |
+----+----+

```

MySQL, since 5.7, will abort such a CREATE TABLE with an error.

 The [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) behavior adheres to the SQL 2003 standard.

 SQL-2003, Part II, “Foundation” says:

 **11.7 <unique constraint definition>**  
**Syntax Rules**

 …

 *5) If the <unique specification> specifies PRIMARY KEY, then for each <column name> in the explicit or implicit <unique column list> for which NOT NULL is not specified, NOT NULL is implicit in the <column definition>.*

 Essentially this means that all PRIMARY KEY columns are automatically converted to NOT NULL. Furthermore:

 **11.5 <default clause>**  
 **General Rules**

  …

 *3) When a site S is set to its default value,*

  …

 *b) If the data descriptor for the site includes a <default option>, then S is set to the value specified by that <default option>.*

  …

 *e) Otherwise, S is set to the null value.*

 There is no concept of “no default value” in the standard. Instead, a column always has an implicit default value of NULL. On insertion it might however fail the NOT NULL constraint. MariaDB and MySQL instead mark such a column as “not having a default value”. The end result is the same — a value must be specified explicitly or an INSERT will fail.

 MariaDB since 10.1.7 behaves in a standard compatible manner — being part of a PRIMARY KEY, the nullable column gets an automatic NOT NULL constraint, on insertion one must specify a value for such a column. MariaDB before 10.1.7 was automatically assigning a default value of 0 — this behavior was non-standard. Issuing an error at CREATE TABLE time is also non-standard.

 See Also
--------

 * [MDEV-12248](https://jira.mariadb.org/browse/MDEV-12248) describes an edge-case that may result in replication problems when replicating from a master server before this change to a slave server after this change.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/primary-keys-with-nullable-columns/>

Latitude/Longitude Indexing
===========================

    The problem
-----------

 You want to find the nearest 10 pizza parlors, but you cannot figure out how to do it efficiently in your huge database. Database indexes are good at one-dimensional indexing, but poor at two-dimensions.

 You might have tried

 * INDEX(lat), INDEX(lon) -- but the optimizer used only one
* INDEX(lat,lon) -- but it still had to work too hard
* Sometimes you ended up with a full table scan -- Yuck.

 WHERE [SQRT(...)](../sqrt/index)< ... -- No chance of using any index.

 WHERE lat BETWEEN ... AND lng BETWEEN... -- This has some chance of using such indexes.

 The goal is to look only at records "close", in both directions, to the target lat/lng.

 A solution -- first, the principles
-----------------------------------

 [PARTITIONs](../managing-mariadb-partitioning/index) in MariaDB and MySQL sort of give you a way to have two clustered indexes. So, if we could slice up (partition) the globe in one dimension and use ordinary indexing in the other dimension, maybe we can get something approximating a 2D index. This 2D approach keeps the number of disk hits significantly lower than 1D approaches, thereby speeding up "find nearest" queries.

 It works. Not perfectly, but better than the alternatives.

 What to PARTITION on? It seems like latitude or longitude would be a good idea. Note that longitudes vary in width, from 69 miles (111 km) at the equator, to 0 at the poles. So, latitude seems like a better choice.

 How many PARTITIONs? It does not matter a lot. Some thoughts:

 * 90 partitions - 2 degrees each. (I don't like tables with too many partitions; 90 seems like plenty.)
* 50-100 - evenly populated. (This requires code. For 2.7M placenames, 85 partitions varied from 0.5 degrees to very wide partitions at the poles.)
* Don't have more than 100 partitions, there are inefficiencies in the partition implementation.

 How to PARTITION? Well, MariaDB and MySQL are very picky. So [FLOAT](../float/index)/[DOUBLE](../double/index) are out. [DECIMAL](../decimal/index) is out. So, we are stuck with some kludge. Essentially, we need to convert Lat/Lng to some size of [INT](../int/index) and use PARTITION BY RANGE.

 Representation choices
----------------------

 To get to a datatype that can be used in PARTITION, you need to "scale" the latitude and longitude. (Consider only the \*INTs; the other datatypes are included for comparison)

 
```
   Datatype           Bytes       resolution
   ------------------ -----  --------------------------------
   Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
   DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
   SMALLINT scaled        4   682 m    0.4 mi  Cities
   Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
   DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
   MEDIUMINT scaled       6   2.7 m    8.8 ft
   FLOAT                  8   1.7 m    5.6 ft
   DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
   Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
   DOUBLE                16   3.5nm     ...    Fleas on a dog

```

(Sorted by resolution)

 What these mean...

 Deg\*100 ([SMALLINT](../smallint/index)) -- you take the lat/lng, multiply by 100, round, and store into a SMALLINT. That will take 2 bytes for each dimension, for a total of 4 bytes. Two items might be 1570 meters apart, but register as having the same latitude and longitude.

 [DECIMAL(4,2)](../decimal/index) for latitude and DECIMAL(5,2) for longitude will take 2+3 bytes and have no better resolution than Deg\*100.

 SMALLINT scaled -- Convert latitude into a SMALLINT SIGNED by doing (degrees / 90 \* 32767) and rounding; longitude by (degrees / 180 \* 32767).

 [FLOAT](../float/index) has 24 significant bits; [DOUBLE](../double/index) has 53. (They don't work with PARTITIONing but are included for completeness. Often people use DOUBLE without realizing how much an overkill it is, and how much space it takes.)

 Sure, you could do DEG\*1000 and other "in between" cases, but there is no advantage. DEG\*1000 takes as much space as DEG\*10000, but has less resolution.

 So, go down the list to see how much resolution you need, then pick an encoding you are comfortable with. However, since we are about to use latitude as a "partition key", it must be limited to one of the INTs. For the sample code, I will use Deg\*10000 ([MEDIUMINT](../mediumint/index)).

 GCDist -- compute "great circle distance"
-----------------------------------------

 GCDist is a helper FUNCTION that correctly computes the distance between two points on the globe.

 The code has been benchmarked at about 20 microseconds per call on a 2011-vintage PC. If you had to check a million points, that would take 20 seconds -- far too much for a web application. So, one goal of the Procedure that uses it will be to minimize the usage of this function. With the code presented here, the function need be called only a few dozen or few hundred times, except in pathological cases.

 Sure, you could use the Pythagorean formula. And it would work for most applications. But it does not take extra effort to do the GC. Furthermore, GC works across a pole and across the dateline. And, a Pythagorean function is not that much faster.

 For efficiency, GCDist understands the scaling you picked and has that stuff hardcoded. I am picking "Deg\*10000", so the function expects 350000 for representing 35 degrees. If you choose a different scaling, you will need to change the code.

 GCDist() takes 4 scaled DOUBLEs -- lat1, lon1, lat2, lon2 -- and returns a scaled number of "degrees" representing the distance.

 The table of representation choices says 52 feet of resolution for Deg\*10000 and DECIMAL(x,4). Here is how it was calculated: To measuring a diagonal between lat/lng (0,0) and (0.0001,00001) (one 'unit in the last place'): GCDist(0,0,1,1) \* 69.172 / 10000 \* 5280 = 51.65, where

 * 69.172 miles/degree of latitude
* 10000 units per degree for the scaling chosen
* 5280 feet / mile.

 (No, this function does not compensate for the Earth being an oblate spheroid, etc.)

 Required table structure
------------------------

 There will be one table (plus normalization tables as needed). The one table must be partitioned and indexed as indicated below.

 Fields and indexes

 * PARTITION BY RANGE(lat)
* lat -- scaled latitude (see above)
* lon -- scaled longitude
* PRIMARY KEY(lon, lat, ...) -- lon must be first; something must be added to make it UNIQUE
* id -- (optional) you may need to identify the rows for your purposes; AUTO\_INCREMENT if you like
* INDEX(id) -- if `id` is [AUTO\_INCREMENT](../auto_increment/index), then this plain INDEX (not UNIQUE, not PRIMARY KEY) is necessary
* ENGINE=[InnoDB](../innodb/index) -- so the PRIMARY KEY will be "clustered"
* Other indexes -- keep to a minimum (this is a general performance rule for large tables)

 For most of this discussion, lat is assumed to be MEDIUMINT -- scaled from -90 to +90 by multiplying by 10000. Similarly for lon and -180 to +180.

 The PRIMARY KEY must

 * start with `lon` since the algorithm needs the "clustering" that InnoDB will provide, and
* include `lat` somewhere, since it is the PARTITION key, and
* contain something to make the key UNIQUE (lon+lat is unlikely to be sufficient).

 The FindNearest PROCEDURE will do multiple SELECTs something like this:

 
```
      WHERE lat    BETWEEN @my_lat - @dlat
                       AND @my_lat + @dlat   -- PARTITION Pruning and bounding box
        AND lon    BETWEEN @my_lon - @dlon
                       AND @my_lon + @dlon   -- first part of PK
        AND condition                        -- filter out non-pizza parlors

```

The query planner will

 * Do PARTITION "pruning" based on the latitude; then
* Within a PARTITION (which is effectively a table), use lon do a 'clustered' range scan; then
* Use the "condition" to filter down to the rows you desire, plus recheck lat. This design leads to very few disk blocks needing to be read, which is the main goal of the design.

 Note that this does not even call GCDist. That comes in the last pass when the ORDER BY and LIMIT are used.

 The [stored procedure](../stored-procedures/index) has a loop. At least two SELECTs will be executed, but with proper tuning; usually no more than about 6 SELECTs will be performed. Because of searching by the PRIMARY KEY, each SELECT hits only one block, sometimes more, of the table. Counting the number of blocks hit is a crude, but effective way, of comparing the performance of multiple designs. By comparison, a full table scan will probably touch thousands of blocks. A simple INDEX(lat) probably leads to hitting hundreds of blocks.

 Filtering... An argument to the FindNearest procedure includes a boolean expression ("condition") for a WHERE clause. If you don't need any filtering, pass in "1". To avoid "SQL injection", do not let web users put arbitrary expressions; instead, construct the "condition" from inputs they provide, thereby making sure it is safe.

 The algorithm
-------------

 The algorithm is embodied in a [stored procedure](../stored-procedures/index) because of its complexity.

 * You feed it a starting width for a "square" and a number of items to find.
* It builds a "square" around where you are.
* A SELECT is performed to see how many items are in the square.
* Loop, doubling the width of the square, until enough items are found.
* Now, a 'last' SELECT is performed to get the exact distances, sort them (ORDER BY) and LIMIT to the desired number.
* If spanning a pole or the dateline, a more complex SELECT is used.

 The next section ("Performance") should make this a bit clearer as it walks through some examples.

 Performance
-----------

 Because of all the variations, it is hard to get a meaningful benchmark. So, here is some hand-waving instead.

 Each SELECT is constrained by a "square" defined by a latitude range and a longitude range. (See the WHERE clause mentioned above, or in the sample code below.) Because of the way longitude lines warp, the longitude range of the "square" will be more degrees than the latitude range. Let's say the latitude partitioning is 3 degrees wide in the area where you are searching. That is over 200 miles (over 300km), so you are very likely to have a latitude range smaller than the partition width. Still, if you are reaching from the edge of a latitude stripe, the square could span two partitions. After partition pruning down to one (sometimes more) partition, the query is then constrained by a longitude range. (Remember, the PRIMARY KEY starts with `lon`.) If an InnoDB data block contains 100 rows (a handy Rule of Thumb), the select will touch one (or a few) block. If the square spans two (or more) partitions, then the same logic applies to each partition.

 So, scanning the square will involve as little as one block; rarely more than a few blocks. The number of blocks is mostly independent of the dataset size.

 The primary use case for this algorithm is when the data is significantly larger than will fit into cache (the buffer\_pool). Hence, the main goal is to minimize the number of disk hits.

 Now let's look at some edge cases, and argue that the number of blocks is still better (usually) than with traditional indexing techniques.

 What if you are looking for Starbucks in a dense city? There would be dozens, maybe hundreds per square mile. If you start the guess at 100 miles, the SELECTs would be hitting lots of blocks -- not efficient. In this case, the "starting distance" should be small, say, 2 miles. Let's say your app wants the closest 10 stores. In this example, you would probably find more than 10 Starbucks within 2 miles in 1 InnoDB block in one partition. Even though there is a second SELECT to finish off the query, it would be hitting the same block. Total: One block hit == cheap.

 Let's say you start with a 5 mile square. Since there are upwards of 200 Starbucks within a 5-miles radius in some dense cities of the world, that might imply 300 in our "square". That maps to about 4 disk blocks, and a modest amount of CPU to chew through the 300 records. Still not bad.

 Now, suppose you are on an ocean liner somewhere in the Pacific. And there is one Starbucks onboard, but you are looking for the nearest 10. If you again start with 2 miles, it will take several iterations to find 10 sites. But, let's walk through it anyway. The first probe will hit one partition (maybe 2), and find just one hit. The second probe doubles the width of the square; 4 miles will still give you one hit -- the same hit in the same block, which is now cached, so we won't count it as a second disk I/O. Eventually the square will be wide enough to span multiple partitions. Each extra partition will be one new disk hit to discover no sites in the square. Finally, the square will hit Chile or Hawaii or Fiji and find some more sites, perhaps enough to stop the iteration. Since the main criteria in determining the number of disk hits is the number of partitions hit, we do not want to split the world into too many partitions. If there are, say, 40 partitions, then I have just described a case where there might be 20 disk hits.

 2-degree partitions might be good for a global table of stores or restaurants. A 5-mile starting distance might be good when filtering for Starbucks. 20 miles might be better for a department store.

 Now, let's discuss the 'last' SELECT, wherein the square is expanded by SQRT(2) and it uses the Great Circle formula to precisely order the N results. The SQRT(2) is in case that the N items were all at the corners of the 'square'. Growing the square by this much allows us to catch any other sites that were just outside the old square.

 First, note that this 'last' SELECT is hitting the same block(s) that the iteration hit, plus possibly hitting some more blocks. It is hard to predict how many extra blocks might be hit. Here's a pathological case. You are in the middle of a desert; the square grows and grows. Eventually it finds N sites. There is a big city just outside the final square from the iterating. Now the 'last' SELECT kicks in, and it includes lots of sites in this big city. "Lots of sites" --> lots of blocks --> lots of disk hits.

 Discussion of reference code
----------------------------

 Here's the gist of the [stored procedure](../stored-procedures/index) FindNearest().

 * Make a guess at how close to "me" to look.
* See how many items are in a 'square' around me, after filtering.
* If not enough, repeat, doubling the width of the square.
* After finding enough, or giving up because we are looking "too far", make one last pass to get all the data, ORDERed and LIMITed

 Note that the loop merely uses 'squares' of lat/lng ranges. This is crude, but works well with the partitioning and indexing, and avoids calling to GCDist (until the last step). In the sample code, I picked 15 miles as starting value. Adjusting this will have some impact on the Procedure's performance, but the impact will vary with the use cases. A rough way to set the radius is to guess what will find the desired LIMIT about half the time. (This value is hardcoded in the PROCEDURE.)

 Parameters passed into FindNearest():

 * your Latitude -- -90..90 (not scaled -- see hardcoded conversion in PROCEDURE)
* your Longitude -- -180..180 (not scaled)
* Start distance -- (miles or km) -- see discussion below
* Max distance -- in miles or km -- see hardcoded conversion in PROCEDURE
* Limit -- maximum number of items to return
* Condition -- something to put after 'AND' (more discussion above)

 The function will find the nearest items, up to Limit that meet the Condition. But it will give up at Max distance. (If you are at the South Pole, why bother searching very far for the tenth pizza parlor?)

 Because of the "scaling", "hardcoding", "Condition", the table name, etc, this PROCEDURE is not truly generic; the code must be modified for each application. Yes, I could have designed it to pass all that stuff in. But what a mess.

 The "\_start\_dist" gives some control over the performance. Making this too small leads to extra iterations; too big leads to more rows being checked. If you choose to tune the Stored Procedure, do the following. "SELECT @iterations" after calling the SP for a number of typical values. If the value is usually 1, then decrease \_start\_dist. If it is usually 2 or more, then increase it.

 Timing: Under 10ms for "typical" usage; any dataset size. Slower for pathological cases (low min distance, high max distance, crossing dateline, bad filtering, cold cache, etc)

 End-cases:

 * By using GC distance, not Pythagoras, distances are 'correct' even near poles.
* Poles -- Even if the "nearest" is almost 360 degrees away (longitude), it can find it.
* Dateline -- There is a small, 'contained', piece of code for crossing the Dateline. Example: you are at +179 deg longitude, and the nearest item is at -179.

 The procedure returns one resultset, SELECT \*, distance.

 * Only rows that meet your Condition, within Max distance are returned
* At most Limit rows are returned
* The rows will be ordered, "closest" first.
* "dist" will be in miles or km (based on a hardcoded constant in the SP)

 Reference code, assuming deg\*10000 and 'miles'
-----------------------------------------------

 This version is based on scaling "Deg\*10000 (MEDIUMINT)".

 
```
DELIMITER //

drop function if exists GCDist //
CREATE FUNCTION GCDist (
        _lat1 DOUBLE,  -- Scaled Degrees north for one point
        _lon1 DOUBLE,  -- Scaled Degrees west for one point
        _lat2 DOUBLE,  -- other point
        _lon2 DOUBLE
    ) RETURNS DOUBLE
    DETERMINISTIC
    CONTAINS SQL  -- SQL but does not read or write
    SQL SECURITY INVOKER  -- No special privileges granted
-- Input is a pair of latitudes/longitudes multiplied by 10000.
--    For example, the south pole has latitude -900000.
-- Multiply output by .0069172 to get miles between the two points
--    or by .0111325 to get kilometers
BEGIN
    -- Hardcoded constant:
    DECLARE _deg2rad DOUBLE DEFAULT PI()/1800000;  -- For scaled by 1e4 to MEDIUMINT
    DECLARE _rlat1 DOUBLE DEFAULT _deg2rad * _lat1;
    DECLARE _rlat2 DOUBLE DEFAULT _deg2rad * _lat2;
    -- compute as if earth's radius = 1.0
    DECLARE _rlond DOUBLE DEFAULT _deg2rad * (_lon1 - _lon2);
    DECLARE _m     DOUBLE DEFAULT COS(_rlat2);
    DECLARE _x     DOUBLE DEFAULT COS(_rlat1) - _m * COS(_rlond);
    DECLARE _y     DOUBLE DEFAULT               _m * SIN(_rlond);
    DECLARE _z     DOUBLE DEFAULT SIN(_rlat1) - SIN(_rlat2);
    DECLARE _n     DOUBLE DEFAULT SQRT(
                        _x * _x +
                        _y * _y +
                        _z * _z    );
    RETURN  2 * ASIN(_n / 2) / _deg2rad;   -- again--scaled degrees
END;
//
DELIMITER ;

DELIMITER //
-- FindNearest (about my 6th approach)
drop procedure if exists FindNearest6 //
CREATE
PROCEDURE FindNearest (
        IN _my_lat DOUBLE,  -- Latitude of me [-90..90] (not scaled)
        IN _my_lon DOUBLE,  -- Longitude [-180..180]
        IN _START_dist DOUBLE,  -- Starting estimate of how far to search: miles or km
        IN _max_dist DOUBLE,  -- Limit how far to search: miles or km
        IN _limit INT,     -- How many items to try to get
        IN _condition VARCHAR(1111)   -- will be ANDed in a WHERE clause
    )
    DETERMINISTIC
BEGIN
    -- lat and lng are in degrees -90..+90 and -180..+180
    -- All computations done in Latitude degrees.
    -- Thing to tailor
    --   *Locations* -- the table
    --   Scaling of lat, lon; here using *10000 in MEDIUMINT
    --   Table name
    --   miles versus km.

    -- Hardcoded constant:
    DECLARE _deg2rad DOUBLE DEFAULT PI()/1800000;  -- For scaled by 1e4 to MEDIUMINT

    -- Cannot use params in PREPARE, so switch to @variables:
    -- Hardcoded constant:
    SET @my_lat := _my_lat * 10000,
        @my_lon := _my_lon * 10000,
        @deg2dist := 0.0069172,  -- 69.172 for miles; 111.325 for km  *** (mi vs km)
        @start_deg := _start_dist / @deg2dist,  -- Start with this radius first (eg, 15 miles)
        @max_deg := _max_dist / @deg2dist,
        @cutoff := @max_deg / SQRT(2),  -- (slightly pessimistic)
        @dlat := @start_deg,  -- note: must stay positive
        @lon2lat := COS(_deg2rad * @my_lat),
        @iterations := 0;        -- just debugging

    -- Loop through, expanding search
    --   Search a 'square', repeat with bigger square until find enough rows
    --   If the inital probe found _limit rows, then probably the first
    --   iteration here will find the desired data.
    -- Hardcoded table name:
    -- This is the "first SELECT":
    SET @sql = CONCAT(
        "SELECT COUNT(*) INTO @near_ct
            FROM Locations
            WHERE lat    BETWEEN @my_lat - @dlat
                             AND @my_lat + @dlat   -- PARTITION Pruning and bounding box
              AND lon    BETWEEN @my_lon - @dlon
                             AND @my_lon + @dlon   -- first part of PK
              AND ", _condition);
    PREPARE _sql FROM @sql;
    MainLoop: LOOP
        SET @iterations := @iterations + 1;
        -- The main probe: Search a 'square'
        SET @dlon := ABS(@dlat / @lon2lat);  -- good enough for now  -- note: must stay positive
        -- Hardcoded constants:
        SET @dlon := IF(ABS(@my_lat) + @dlat >= 900000, 3600001, @dlon);  -- near a Pole
        EXECUTE _sql;
        IF ( @near_ct >= _limit OR         -- Found enough
             @dlat >= @cutoff ) THEN       -- Give up (too far)
            LEAVE MainLoop;
        END IF;
        -- Expand 'square':
        SET @dlat := LEAST(2 * @dlat, @cutoff);   -- Double the radius to search
    END LOOP MainLoop;
    DEALLOCATE PREPARE _sql;

    -- Out of loop because found _limit items, or going too far.
    -- Expand range by about 1.4 (but not past _max_dist),
    -- then fetch details on nearest 10.

    -- Hardcoded constant:
    SET @dlat := IF( @dlat >= @max_deg OR @dlon >= 1800000,
                @max_deg,
                GCDist(ABS(@my_lat), @my_lon,
                       ABS(@my_lat) - @dlat, @my_lon - @dlon) );
            -- ABS: go toward equator to find farthest corner (also avoids poles)
            -- Dateline: not a problem (see GCDist code)

    -- Reach for longitude line at right angle:
    -- sin(dlon)*cos(lat) = sin(dlat)
    -- Hardcoded constant:
    SET @dlon := IFNULL(ASIN(SIN(_deg2rad * @dlat) /
                             COS(_deg2rad * @my_lat))
                            / _deg2rad -- precise
                        , 3600001);    -- must be too near a pole

    -- This is the "last SELECT":
    -- Hardcoded constants:
    IF (ABS(@my_lon) + @dlon < 1800000 OR    -- Usual case - not crossing dateline
        ABS(@my_lat) + @dlat <  900000) THEN -- crossing pole, so dateline not an issue
        -- Hardcoded table name:
        SET @sql = CONCAT(
            "SELECT *,
                    @deg2dist * GCDist(@my_lat, @my_lon, lat, lon) AS dist
                FROM Locations
                WHERE lat BETWEEN @my_lat - @dlat
                              AND @my_lat + @dlat   -- PARTITION Pruning and bounding box
                  AND lon BETWEEN @my_lon - @dlon
                              AND @my_lon + @dlon   -- first part of PK
                  AND ", _condition, "
                HAVING dist <= ", _max_dist, "
                ORDER BY dist
                LIMIT ", _limit
                        );
    ELSE
        -- Hardcoded constants and table name:
        -- Circle crosses dateline, do two SELECTs, one for each side
        SET @west_lon := IF(@my_lon < 0, @my_lon, @my_lon - 3600000);
        SET @east_lon := @west_lon + 3600000;
        -- One of those will be beyond +/- 180; this gets points beyond the dateline
        SET @sql = CONCAT(
            "( SELECT *,
                    @deg2dist * GCDist(@my_lat, @west_lon, lat, lon) AS dist
                FROM Locations
                WHERE lat BETWEEN @my_lat - @dlat
                              AND @my_lat + @dlat   -- PARTITION Pruning and bounding box
                  AND lon BETWEEN @west_lon - @dlon
                              AND @west_lon + @dlon   -- first part of PK
                  AND ", _condition, "
                HAVING dist <= ", _max_dist, " )
            UNION ALL
            ( SELECT *,
                    @deg2dist * GCDist(@my_lat, @east_lon, lat, lon) AS dist
                FROM Locations
                WHERE lat BETWEEN @my_lat - @dlat
                              AND @my_lat + @dlat   -- PARTITION Pruning and bounding box
                  AND lon BETWEEN @east_lon - @dlon
                              AND @east_lon + @dlon   -- first part of PK
                  AND ", _condition, "
                HAVING dist <= ", _max_dist, " )
            ORDER BY dist
            LIMIT ", _limit
                        );
    END IF;

    PREPARE _sql FROM @sql;
    EXECUTE _sql;
    DEALLOCATE PREPARE _sql;
END;
//
DELIMITER ;
<<code>>

== Sample

Find the 5 cities with non-zero population (out of 3 million) nearest to (+35.15, -90.15). Start with a 10-mile bounding box and give up at 100 miles.

<<code>>
CALL FindNearestLL(35.15, -90.05, 10, 100, 5, 'population > 0');
+---------+--------+---------+---------+--------------+--------------+-------+------------+--------------+---------------------+------------------------+
| id      | lat    | lon     | country | ascii_city   | city         | state | population | @gcd_ct := 0 | dist                | @gcd_ct := @gcd_ct + 1 |
+---------+--------+---------+---------+--------------+--------------+-------+------------+--------------+---------------------+------------------------+
| 3023545 | 351494 | -900489 | us      | memphis      | Memphis      | TN    |     641608 |            0 | 0.07478733189367963 |                      3 |
| 2917711 | 351464 | -901844 | us      | west memphis | West Memphis | AR    |      28065 |            0 |   7.605683607627499 |                      2 |
| 2916457 | 352144 | -901964 | us      | marion       | Marion       | AR    |       9227 |            0 |     9.3994963998986 |                      1 |
| 3020923 | 352044 | -898739 | us      | bartlett     | Bartlett     | TN    |      43264 |            0 |  10.643941157860604 |                      7 |
| 2974644 | 349889 | -900125 | us      | southaven    | Southaven    | MS    |      38578 |            0 |  11.344042217329935 |                      5 |
+---------+--------+---------+---------+--------------+--------------+-------+------------+--------------+---------------------+------------------------+
5 rows in set (0.00 sec)
Query OK, 0 rows affected (0.04 sec)

SELECT COUNT(*) FROM ll_table;
+----------+
| COUNT(*) |
+----------+
|  3173958 |
+----------+
1 row in set (5.04 sec)

FLUSH STATUS;
CALL...
SHOW SESSION STATUS LIKE 'Handler%';

show session status like 'Handler%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Handler_read_first         | 1     |
| Handler_read_key           | 3     |
| Handler_read_next          | 1307  |  -- some index, some tmp, but far less than 3 million.
| Handler_read_rnd           | 5     |
| Handler_read_rnd_next      | 13    |
| Handler_write              | 12    |  -- it needed a tmp
+----------------------------+-------+

```

Postlog
-------

 There is a "Haversine" algorithm that is twice as fast as the GCDist function here. But it has a fatal flaw of sometimes returning NULL for the distance between a point and itself. (This is because of computing a number slightly bigger than 1.0, then trying to take the ACOS of it.)

 See also
--------

 * [Cities used for testing](https://www.maxmind.com/en/worldcities)
* [A forum thread](http://forums.mysql.com/read.php?20,619712,619712)
* [StackOverflow discussion](http://stackoverflow.com/questions/29058863/mysql-query-takes-long-time/)
* [Sample](http://dba.stackexchange.com/questions/134028/select-the-minimum-of-a-calculated-distance-value-without-sorting)
* [Z-ordering](https://en.wikipedia.org/wiki/Geohash)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/latlng>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/latitudelongitude-indexing/>

Index Hints: How to Force Query Plans
=====================================

     The optimizer is largely cost-based and will try to choose the optimal plan for any query. However in some cases it does not have enough information to choose a perfect plan and in these cases you may have to provide hints to force the optimizer to use another plan.

 You can examine the query plan for a [SELECT](../select/index) by writing [EXPLAIN](../explain/index) before the statement. [SHOW EXPLAIN](../show-explain/index) shows the output of a running query. In some cases, its output can be closer to reality than `EXPLAIN`.

 For the following queries, we will use the world database for the examples.

 Setting up the World Example Database
-------------------------------------

 Download it from <ftp://ftp.askmonty.org/public/world.sql.gz>

 Install it with:

 
```
mariadb-admin create world
zcat world.sql.gz | ../client/mysql world

```

or

 
```
mariadb-admin create world
gunzip world.sql.gz
../client/mysql world < world.sql

```

Forcing Join Order
------------------

 You can force the join order by using [STRAIGHT\_JOIN](../join/index) either in the [SELECT](../select/index) or [JOIN](../join/index) part.

 The simplest way to force the join order is to put the tables in the correct order in the `FROM` clause and use `SELECT STRAIGHT_JOIN` like so:

 
```
SELECT STRAIGHT_JOIN SUM(City.Population) FROM Country,City WHERE
City.CountryCode=Country.Code AND Country.HeadOfState="Volodymyr Zelenskyy";

```

If you only want to force the join order for a few tables, use `STRAIGHT_JOIN` in the `FROM` clause. When this is done, only tables connected with `STRAIGHT_JOIN` will have their order forced. For example:

 
```
SELECT SUM(City.Population) FROM Country STRAIGHT_JOIN City WHERE
City.CountryCode=Country.Code AND Country.HeadOfState="Volodymyr Zelenskyy";

```

In both of the above cases `Country` will be scanned first and for each matching country (one in this case) all rows in `City` will be checked for a match. As there is only one matching country this will be faster than the original query.

 The output of [EXPLAIN](../explain/index) for the above cases is:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | Country | ALL | PRIMARY | NULL | NULL | NULL | 239 | Using where |
| 1 | SIMPLE | City | ALL | NULL | NULL | NULL | NULL | 4079 | Using where; Using join buffer (flat, BNL join) |

 
This is one of the few cases where `ALL` is ok, as the scan of the `Country` table will only find one matching row.

 Forcing Usage of a Specific Index for the WHERE Clause
------------------------------------------------------

 In some cases the optimizer may choose a non-optimal index or it may choose to not use an index at all, even if some index could theoretically be used.

 In these cases you have the option to either tell the optimizer to only use a limited set of indexes, ignore one or more indexes, or force the usage of some particular index.

 ### USE INDEX: Use a Limited Set of Indexes

 You can limit which indexes are considered with the [USE INDEX](../use-index/index) option.

 
```
USE INDEX [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

```

The default is '`FOR JOIN`', which means that the hint only affects how the `WHERE` clause is optimized.

 `USE INDEX` is used after the table name in the `FROM` clause.

 Example:

 
```
CREATE INDEX Name ON City (Name);
CREATE INDEX CountryCode ON City (Countrycode);
EXPLAIN SELECT Name FROM City USE INDEX (CountryCode)
WHERE name="Helsingborg" AND countrycode="SWE";

```

This produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | ref | CountryCode | CountryCode | 3 | const | 14 | Using where |

 
If we had not used [USE INDEX](../use-index/index), the `Name` index would have been in `possible keys`.

 ### IGNORE INDEX: Don't Use a Particular Index

 You can tell the optimizer to not consider some particular index with the [IGNORE INDEX](../ignore-index/index) option.

 
```
IGNORE INDEX [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

```

This is used after the table name in the `FROM` clause:

 
```
CREATE INDEX Name ON City (Name);
CREATE INDEX CountryCode ON City (Countrycode);
EXPLAIN SELECT Name FROM City IGNORE INDEX (Name)
WHERE name="Helsingborg" AND countrycode="SWE";

```

This produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | ref | CountryCode | CountryCode | 3 | const | 14 | Using where |

 
The benefit of using `IGNORE_INDEX` instead of `USE_INDEX` is that it will not disable a new index which you may add later.

 Also see [Ignored Indexes](../ignored-indexes/index) for an option to specify in the index definition that indexes should be ignored.

 ### FORCE INDEX: Forcing an Index

 [Forcing an index](../force-index/index) to be used is mostly useful when the optimizer decides to do a table scan even if you know that using an index would be better. (The optimizer could decide to do a table scan even if there is an available index when it believes that most or all rows will match and it can avoid the overhead of using the index).

 
```
CREATE INDEX Name ON City (Name);
EXPLAIN SELECT Name,CountryCode FROM City FORCE INDEX (Name)
WHERE name>="A" and CountryCode >="A";

```

This produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | range | Name | Name | 35 | NULL | 4079 | Using where |

 
`FORCE_INDEX` works by only considering the given indexes (like with `USE_INDEX`) but in addition it tells the optimizer to regard a table scan as something very expensive. However if none of the 'forced' indexes can be used, then a table scan will be used anyway.

 ### Index Prefixes

 When using index hints (USE, FORCE or [IGNORE INDEX](../ignore-index/index)), the index name value can also be an unambiguous prefix of an index name.

 Forcing an Index to be Used for ORDER BY or GROUP BY
----------------------------------------------------

 The optimizer will try to use indexes to resolve [ORDER BY](../order-by/index) and [GROUP BY](../group-by/index).

 You can use [USE INDEX](../use-index/index), [IGNORE INDEX](../ignore-index/index) and [FORCE INDEX](../force-index/index) as in the `WHERE` clause above to ensure that some specific index used:

 
```
USE INDEX [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

```

This is used after the table name in the `FROM` clause.

 Example:

 
```
CREATE INDEX Name ON City (Name);
EXPLAIN SELECT Name,Count(*) FROM City
FORCE INDEX FOR GROUP BY (Name)
WHERE population >= 10000000 GROUP BY Name;

```

This produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | index | NULL | Name | 35 | NULL | 4079 | Using where |

 
Without the [FORCE INDEX](../force-index/index) option we would have '`Using where; Using temporary; Using filesort`' in the 'Extra' column, which means that the optimizer would created a temporary table and sort it.

 ### Help the Optimizer Optimize GROUP BY and ORDER BY

 The optimizer uses several strategies to optimize [GROUP BY](../group-by/index) and [ORDER BY](../order-by/index):

 * Resolve with an index:
	+ Scan the table in index order and output data as we go. (This only works if the [ORDER BY](../order-by/index) / [GROUP BY](../group-by/index) can be resolved by an index after constant propagation is done).

 * Filesort:
	+ Scan the table to be sorted and collect the sort keys in a temporary file.
	+ Sort the keys + reference to row (with filesort)
	+ Scan the table in sorted order

 * Use a temporary table for [ORDER BY](../order-by/index):
	+ Create a temporary (in memory) table for the 'to-be-sorted' data. (If this gets bigger than `max_heap_table_size` or contains blobs then an [Aria](../aria/index) or [MyISAM](../myisam/index) disk based table will be used)
	+ Sort the keys + reference to row (with filesort)
	+ Scan the table in sorted order

 A temporary table will always be used if the fields which will be sorted are not from the first table in the [JOIN](../join/index) order.

 * Use a temporary table for [GROUP BY](../group-by/index):
	+ Create a temporary table to hold the [GROUP BY](../group-by/index) result with an index that matches the [GROUP BY](../group-by/index) fields.
	+ Produce a result row
	+ If a row with the [GROUP BY](../group-by/index) key exists in the temporary table, add the new result row to it. If not, create a new row.
	+ Before sending the results to the user, sort the rows with filesort to get the results in the [GROUP BY](../group-by/index) order.

 ### Forcing/Disallowing TemporaryTables to be Used for GROUP BY:

 Using an in-memory table (as described above) is usually the fastest option for [GROUP BY](../group-by/index) if the result set is small. It is not optimal if the result set is very big. You can tell the optimizer this by using `SELECT SQL_SMALL_RESULT` or `SELECT SQL_BIG_RESULT`.

 For example: 

 
```
EXPLAIN SELECT SQL_SMALL_RESULT Name,Count(*) AS Cities FROM City GROUP BY Name HAVING Cities > 2;

```

produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | ALL | NULL | NULL | NULL | NULL | 4079 | Using temporary; Using filesort |

 
while: 

 
```
EXPLAIN SELECT SQL_BIG_RESULT Name,Count(*) AS Cities FROM City
GROUP BY Name HAVING Cities > 2;

```

produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | ALL | NULL | NULL | NULL | NULL | 4079 | Using filesort |

 
The difference is that with `SQL_SMALL_RESULT` a temporary table is used.

 Forcing Usage of Temporary Tables
---------------------------------

 In some cases you may want to force the use of a temporary table for the result to free up the table/row locks for the used tables as quickly as possible.

 You can do this with the `SQL_BUFFER_RESULT` option:

 
```
CREATE INDEX Name ON City (Name);
EXPLAIN SELECT SQL_BUFFER_RESULT Name,Count(*) AS Cities FROM City
GROUP BY Name HAVING Cities > 2;

```

This produces:

 


| id | select\_type | table | type | possible\_keys | key | key\_len | ref | rows | Extra |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | SIMPLE | City | index | NULL | Name | 35 | NULL | 4079 | Using index; Using temporary |

 
Without `SQL_BUFFER_RESULT`, the above query would not use a temporary table for the result set.

 Optimizer Switch
----------------

 In [MariaDB 5.3](../what-is-mariadb-53/index) we added an [optimizer switch](../server-system-variables/index#optimizer_switch) which allows you to specify which algorithms will be considered when optimizing a query.

 See the [optimizer](../optimizer/index) section for more information about the different algorithms which are used.

 See Also
--------

 * [FORCE INDEX](../force-index/index)
* [USE INDEX](../use-index/index)
* [IGNORE INDEX](../ignore-index/index)
* [GROUP BY](../group-by/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/index-hints-how-to-force-query-plans/>

Subquery Optimizations
=======================

   Articles about subquery optimizations in MariaDB.

  

| Title | Description |
| --- | --- |
|  [Subquery Optimizations Map](../subquery-optimizations-map/index) |  Map showing types of subqueries and the optimizer strategies available to handle them  |
|  [Semi-join Subquery Optimizations](../semi-join-subquery-optimizations/index) |  MariaDB has a set of optimizations specifically targeted at semi-join subqueries.  |
|  [Table Pullout Optimization](../table-pullout-optimization/index) |  Table pullout is an optimization for Semi-join subqueries.  |
|  [Non-semi-join Subquery Optimizations](../non-semi-join-subquery-optimizations/index) |  Alternative strategies for IN-subqueries that cannot be flattened into semi-joins  |
|  [Subquery Cache](../subquery-cache/index) |  Subquery cache for optimizing the evaluation of correlated subqueries.  |
|  [Condition Pushdown Into IN subqueries](../condition-pushdown-into-in-subqueries/index) |  This article describes Condition Pushdown into IN subqueries as implemented...  |
|  [Conversion of Big IN Predicates Into Subqueries](../conversion-of-big-in-predicates-into-subqueries/index) |  The optimizer will convert big IN predicates into subqueries.  |
|  [EXISTS-to-IN Optimization](../exists-to-in-optimization/index) |  Optimizations for IN subqueries.  |
|  [Optimizing GROUP BY and DISTINCT Clauses in Subqueries](../optimizing-group-by/index) |  MariaDB removes DISTINCT and GROUP BY without HAVING in certain cases  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subquery-optimizations/>

Ignored Indexes
===============

    
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**Ignored indexes were added in [MariaDB 10.6](../what-is-mariadb-106/index).

 
Ignored indexes are indexes that are visible and maintained, but which are not used by the optimizer. MySQL 8 has a similar feature which they call "invisible indexes".

 Syntax
------

 By default, an index is not ignored. One can mark existing index as ignored (or not ignored) with an [ALTER TABLE](../alter-table/index) statement:

 
```
ALTER TABLE table_name ALTER {KEY|INDEX} [IF EXISTS] key_name [NOT] IGNORED;

```

It is also possible to specify IGNORED attribute when creating an index with a [CREATE TABLE](../create-table/index), or [CREATE INDEX](../create-index/index) statement:

 
```
CREATE TABLE table_name (
  ...
  INDEX index_name ( ...) [NOT] IGNORED
  ...

```


```
CREATE INDEX index_name (...) [NOT] IGNORED ON tbl_name (...);

```

table's primary key cannot be ignored. This applies to both explicitly defined primary key, as well as implicit primary key - if there is no explicit primary key defined but the table has a unique key containing only NOT NULL columns, the first of such keys becomes the implicitly defined primary key.

 Handling for ignored indexes
----------------------------

 The optimizer will treats ignored indexes as if they didn't exist. They will not be used in the query plans, or as a source of statistical information. Also, an attempt to use an ignored index in a `USE INDEX`, `FORCE INDEX`, or `IGNORE INDEX` hint will result in an error - the same what would have if one used a name of a non-existent index.

 Information about whether or not indexes are ignored can be viewed in the IGNORED column in the [Information Schema STATISTICS table](../information-schema-statistics-table/index) or the [SHOW INDEX](../show-index/index) statement.

 Intended Usage
--------------

 The primary use case is as follows: a DBA sees an index that seems to have little or no usage and considers whether to remove it. Dropping the index is a risk as it may still be needed in a few cases. For example, the optimizer may rely on the estimates provided by the index without using the index in query plans. If dropping an index causes an issue, it will take a while to re-create the index. On the other hand, marking the index as ignored (or not ignored) is instant, so the suggested workflow is: 

 1. Mark the index as ignored
2. Check if everything continues to work
3. If not, mark the index as not ignored.
4. If everything continues to work, one can safely drop the index.

 Examples
--------

 
```
CREATE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b) IGNORED);

```


```
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b));
ALTER TABLE t1 ALTER INDEX k1 IGNORED;

```


```
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT);
CREATE INDEX k1 ON t1(b) IGNORED;

```


```
SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_NAME = 't1'\G
*************************** 1. row ***************************
TABLE_CATALOG: def
 TABLE_SCHEMA: test
   TABLE_NAME: t1
   NON_UNIQUE: 0
 INDEX_SCHEMA: test
   INDEX_NAME: PRIMARY
 SEQ_IN_INDEX: 1
  COLUMN_NAME: id
    COLLATION: A
  CARDINALITY: 0
     SUB_PART: NULL
       PACKED: NULL
     NULLABLE: 
   INDEX_TYPE: BTREE
      COMMENT: 
INDEX_COMMENT: 
      IGNORED: NO
*************************** 2. row ***************************
TABLE_CATALOG: def
 TABLE_SCHEMA: test
   TABLE_NAME: t1
   NON_UNIQUE: 1
 INDEX_SCHEMA: test
   INDEX_NAME: k1
 SEQ_IN_INDEX: 1
  COLUMN_NAME: b
    COLLATION: A
  CARDINALITY: 0
     SUB_PART: NULL
       PACKED: NULL
     NULLABLE: YES
   INDEX_TYPE: BTREE
      COMMENT: 
INDEX_COMMENT: 
      IGNORED: YES

```


```
SHOW INDEXES FROM t1\G
*************************** 1. row ***************************
        Table: t1
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: NO
*************************** 2. row ***************************
        Table: t1
   Non_unique: 1
     Key_name: k1
 Seq_in_index: 1
  Column_name: b
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
      Ignored: YES

```

The optimizer does not make use of an index when it is ignored, while if the index is not ignored (the default), the optimizer will consider it in the optimizer plan, as shown in the [EXPLAIN](../explain/index) output.

 
```
CREATE OR REPLACE TABLE t1 (id INT PRIMARY KEY, b INT, KEY k1(b) IGNORED);

EXPLAIN SELECT * FROM t1 ORDER BY b;
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id   | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+
|    1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL | 1    | Using filesort |
+------+-------------+-------+------+---------------+------+---------+------+------+----------------+

ALTER TABLE t1 ALTER INDEX k1 NOT IGNORED;

EXPLAIN SELECT * FROM t1 ORDER BY b;
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | t1    | index | NULL          | k1   | 5       | NULL | 1    | Using index |
+------+-------------+-------+-------+---------------+------+---------+------+------+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ignored-indexes/>

Optimization Strategies
========================

   Various optimization strategies used by [the query optimizer](../the-query-optimizer/index).

  

| Title | Description |
| --- | --- |
|  [DuplicateWeedout Strategy](../duplicateweedout-strategy/index) |  DuplicateWeedout is an execution strategy for Semi-join subqueries.  |
|  [FirstMatch Strategy](../firstmatch-strategy/index) |  FirstMatch is an execution strategy for Semi-join subqueries  |
|  [LooseScan Strategy](../loosescan-strategy/index) |  LooseScan is an execution strategy for Semi-join subqueries  |
|  [Semi-join Materialization Strategy](../semi-join-materialization-strategy/index) |  Semi-join Materialization is a subquery materialization used for Semi-join subqueries.  |
|  [Improvements to ORDER BY Optimization](../improvements-to-order-by/index) |  Several Improvements to the ORDER BY Optimizer in Version 10.1 of MariaDB.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimization-strategies/>

Compound (Composite) Indexes
============================

    A mini-lesson in "compound indexes" ("composite indexes")
---------------------------------------------------------

 This document starts out trivial and perhaps boring, but builds up to more interesting information, perhaps things you did not realize about how MariaDB and MySQL indexing works.

 This also explains [EXPLAIN](../explain/index) (to some extent).

 (Most of this applies to other databases, too.)

 The query to discuss
--------------------

 The question is "When was Andrew Johnson president of the US?".

 The available table `Presidents` looks like:

 
```
+-----+------------+----------------+-----------+
| seq | last_name  | first_name     | term      |
+-----+------------+----------------+-----------+
|   1 | Washington | George         | 1789-1797 |
|   2 | Adams      | John           | 1797-1801 |
...
|   7 | Jackson    | Andrew         | 1829-1837 |
...
|  17 | Johnson    | Andrew         | 1865-1869 |
...
|  36 | Johnson    | Lyndon B.      | 1963-1969 |
...

```

("Andrew Johnson" was picked for this lesson because of the duplicates.)

 What index(es) would be best for that question? More specifically, what would be best for

 
```
    SELECT  term
        FROM  Presidents
        WHERE  last_name = 'Johnson'
          AND  first_name = 'Andrew';

```

Some INDEXes to try...

 * No indexes
* INDEX(first\_name), INDEX(last\_name) (two separate indexes)
* "Index Merge Intersect"
* INDEX(last\_name, first\_name) (a "compound" index)
* INDEX(last\_name, first\_name, term) (a "covering" index)
* Variants

 No indexes
----------

 Well, I am fudging a little here. I have a PRIMARY KEY on `seq`, but that has no advantage on the query we are studying.

 
```
SHOW CREATE TABLE Presidents \G
CREATE TABLE `presidents` (
  `seq` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  `last_name` varchar(30) NOT NULL,
  `first_name` varchar(30) NOT NULL,
  `term` varchar(9) NOT NULL,
  PRIMARY KEY (`seq`)
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8

EXPLAIN  SELECT  term
   FROM  Presidents
   WHERE  last_name = 'Johnson'
   AND  first_name = 'Andrew';
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | Presidents | ALL  | NULL          | NULL | NULL    | NULL |   44 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+------+-------------+

# Or, using the other form of display:  EXPLAIN ... \G
           id: 1
  select_type: SIMPLE
        table: Presidents
         type: ALL        <-- Implies table scan
possible_keys: NULL
          key: NULL       <-- Implies that no index is useful, hence table scan
      key_len: NULL
          ref: NULL
         rows: 44         <-- That's about how many rows in the table, so table scan
        Extra: Using where

```

Implementation Details
----------------------

 First, let's describe how InnoDB stores and uses indexes.

 * The data and the PRIMARY KEY are "clustered" together in on BTree.
* A BTree lookup is quite fast and efficient. For a million-row table there might be 3 levels of BTree, and the top two levels are probably cached.
* Each secondary index is in another BTree, with the PRIMARY KEY at the leaf.
* Fetching 'consecutive' (according to the index) items from a BTree is very efficient because they are stored consecutively.
* For the sake of simplicity, we can count each BTree lookup as 1 unit of work, and ignore scans for consecutive items. This approximates the number of disk hits for a large table in a busy system.

 For MyISAM, the PRIMARY KEY is not stored with the data, so think of it as being a secondary key (over-simplified).

 INDEX(first\_name), INDEX(last\_name)
-------------------------------------

 The novice, once he learns about indexing, decides to index lots of columns, one at a time. But...

 MariaDB rarely uses more than one index at a time in a query. So, it will analyze the possible indexes.

 * first\_name -- there are 2 possible rows (one BTree lookup, then scan consecutively)
* last\_name -- there are 2 possible rows Let's say it picks last\_name. Here are the steps for doing the SELECT: 1. Using INDEX(last\_name), find 2 index entries with last\_name = 'Johnson'. 2. Get the PRIMARY KEY (implicitly added to each secondary index in InnoDB); get (17, 36). 3. Reach into the data using seq = (17, 36) to get the rows for Andrew Johnson and Lyndon B. Johnson. 4. Use the rest of the WHERE clause filter out all but the desired row. 5. Deliver the answer (1865-1869).

 
```
EXPLAIN  SELECT  term
  FROM  Presidents
  WHERE  last_name = 'Johnson'
  AND  first_name = 'Andrew'  \G
  select_type: SIMPLE
        table: Presidents
         type: ref
possible_keys: last_name, first_name
          key: last_name
      key_len: 92                 <-- VARCHAR(30) utf8 may need 2+3*30 bytes
          ref: const
         rows: 2                  <-- Two 'Johnson's
        Extra: Using where

```

"Index Merge Intersect"
-----------------------

 OK, so you get really smart and decide that MariaDB should be smart enough to use both name indexes to get the answer. This is called "Intersect". 1. Using INDEX(last\_name), find 2 index entries with last\_name = 'Johnson'; get (7, 17) 2. Using INDEX(first\_name), find 2 index entries with first\_name = 'Andrew'; get (17, 36) 3. "And" the two lists together (7,17) & (17,36) = (17) 4. Reach into the data using seq = (17) to get the row for Andrew Johnson. 5. Deliver the answer (1865-1869).

 
```
           id: 1
  select_type: SIMPLE
        table: Presidents
         type: index_merge
possible_keys: first_name,last_name
          key: first_name,last_name
      key_len: 92,92
          ref: NULL
         rows: 1
        Extra: Using intersect(first_name,last_name); Using where

```

The EXPLAIN fails to give the gory details of how many rows collected from each index, etc.

 INDEX(last\_name, first\_name)
------------------------------

 This is called a "compound" or "composite" index since it has more than one column. 1. Drill down the BTree for the index to get to exactly the index row for Johnson+Andrew; get seq = (17). 2. Reach into the data using seq = (17) to get the row for Andrew Johnson. 3. Deliver the answer (1865-1869). This is much better. In fact this is usually the "best".

 
```
    ALTER TABLE Presidents
        (drop old indexes and...)
        ADD INDEX compound(last_name, first_name);

           id: 1
  select_type: SIMPLE
        table: Presidents
         type: ref
possible_keys: compound
          key: compound
      key_len: 184             <-- The length of both fields
          ref: const,const     <-- The WHERE clause gave constants for both
         rows: 1               <-- Goodie!  It homed in on the one row.
        Extra: Using where

```

"Covering": INDEX(last\_name, first\_name, term)
------------------------------------------------

 Surprise! We can actually do a little better. A "Covering" index is one in which \_all\_ of the fields of the SELECT are found in the index. It has the added bonus of not having to reach into the "data" to finish the task. 1. Drill down the BTree for the index to get to exactly the index row for Johnson+Andrew; get seq = (17). 2. Deliver the answer (1865-1869). The "data" BTree is not touched; this is an improvement over "compound".

 
```
    ... ADD INDEX covering(last_name, first_name, term);

           id: 1
  select_type: SIMPLE
        table: Presidents
         type: ref
possible_keys: covering
          key: covering
      key_len: 184
          ref: const,const
         rows: 1
        Extra: Using where; Using index   <-- Note

```

Everything is similar to using "compound", except for the addition of "Using index".

 Variants
--------

 * What would happen if you shuffled the fields in the WHERE clause? Answer: The order of ANDed things does not matter.
* What would happen if you shuffled the fields in the INDEX? Answer: It may make a huge difference. More in a minute.
* What if there are extra fields on the the end? Answer: Minimal harm; possibly a lot of good (eg, 'covering').
* Reduncancy? That is, what if you have both of these: INDEX(a), INDEX(a,b)? Answer: Reduncy costs something on INSERTs; it is rarely useful for SELECTs.
* Prefix? That is, INDEX(last\_name(5). first\_name(5)) Answer: Don't bother; it rarely helps, and often hurts. (The details are another topic.)

 More examples:
--------------

 
```
    INDEX(last, first)
    ... WHERE last = '...' -- good (even though `first` is unused)
    ... WHERE first = '...' -- index is useless

    INDEX(first, last), INDEX(last, first)
    ... WHERE first = '...' -- 1st index is used
    ... WHERE last = '...' -- 2nd index is used
    ... WHERE first = '...' AND last = '...' -- either could be used equally well

    INDEX(last, first)
    Both of these are handled by that one INDEX:
    ... WHERE last = '...'
    ... WHERE last = '...' AND first = '...'

    INDEX(last), INDEX(last, first)
    In light of the above example, don't bother including INDEX(last).

```

Postlog
-------

 Refreshed -- Oct, 2012; more links -- Nov 2016

 See also
--------

 * [Cookbook on designing the best index for a SELECT](http://mysql.rjweb.org/doc.php/index_cookbook_mysql)
* [Sheeri's discussing of Indexes](http://technocation.org/files/doc/2013_02_MySQLindexes.pdf)
* [Slides on EXPLAIN](http://www.slideshare.net/phpcodemonkey/mysql-explain-explained)
* [Mysql manual page on range accesses in composite indexes](http://dev.mysql.com/doc/refman/5.7/en/range-optimization.html#range-access-multi-part)
* [Overhead of Composite Indexes](http://stackoverflow.com/questions/32418812/overhead-of-composite-indexes)
* [Size and other limits on Indexes](http://mysql.rjweb.org/doc.php/limits)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/index1>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compound-composite-indexes/>

Optimizations for Derived Tables
=================================

   Derived tables are subqueries in the `FROM` clause. Prior to [MariaDB 5.3](../what-is-mariadb-53/index)/MySQL 5.6, they were too slow to be usable. In [MariaDB 5.3](../what-is-mariadb-53/index)/MySQL 5.6, there are two optimizations which provide adequate performance:

  

| Title | Description |
| --- | --- |
|  [Condition Pushdown into Derived Table Optimization](../condition-pushdown-into-derived-table-optimization/index) |  If a query uses a derived table (or a view), the first action that the que...  |
|  [Derived Table Merge Optimization](../derived-table-merge-optimization/index) |  MariaDB 5.3 introduced the derived table merge optimization.  |
|  [Derived Table with Key Optimization](../derived-table-with-key-optimization/index) |  Since MariaDB 5.3, the optimizer can create an index and use it for joins with other tables.  |
|  [Lateral Derived Optimization](../lateral-derived-optimization/index) |  Lateral Derived optimization, also referred to as "Split Grouping Optimization".  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizations-for-derived-tables/>

Table Elimination
==================

   Articles about Table Elimination, the idea that it is sometimes possible to resolve a query without accessing some of the tables the query refers to.

  

| Title | Description |
| --- | --- |
|  [What is Table Elimination?](../what-is-table-elimination/index) |  Resolving a query without accessing some of the tables that the query refers to.  |
|  [Table Elimination in MariaDB](../table-elimination-in-mariadb/index) |  Table elimination in the MariaDB optimizer.  |
|  [Table Elimination User Interface](../table-elimination-user-interface/index) |  Table Elimination User Interface and EXPLAIN.  |
|  [Table Elimination in Other Databases](../table-elimination-in-other-databases/index) |  Table Elimination in SQL Server and Oracle.  |
|  [Table Elimination External Resources](../table-elimination-external-resources/index) |  an example of how to do this in MariaDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-elimination/>

Entity-Attribute-Value Implementation
=====================================

    The desires
-----------

 * Open-ended set of "attributes" (key=value) for each "entity". That is, the list of attributes is not known at development time, and will grow in the future. (This makes one column per attribute impractical.)
* "ad hoc" queries testing attributes.
* Attribute values come in different types (numbers, strings, dates, etc.)
* Scale to lots of entities, yet perform well.

 It goes by various names

 * EAV -- Entity - Attribute - Value
* key-value
* RDF -- This is a flavor of EAV
* MariaDB has dynamic columns that look something like the solution below, with the added advantage of being able to index the columns otherwise hidden in the blob. (There are caveats.)
* MySQL 5.7 Has JSON datatype, plus functions to access parts
* MongoDB, CouchDB -- and others -- Not SQL-based.

 Bad solution
------------

 * Table with 3 columns: entity\_id, key, value
* The "value" is a string, or maybe multiple columns depending on datatype or other kludges.
* a JOIN b ON a.entity=b.entity AND b.key='x' JOIN c ON ... WHERE a.value=... AND b.value=...

 The problems
------------

 * The SELECTs get messy -- multiple JOINs
* Datatype issues -- It's clumsy to be putting numbers into strings
* Numbers stored in [VARCHAR](../varchar/index) do not compare 'correctly', especially for range tests.
* Bulky.
* Dedupping the values is clumsy.

 A solution
----------

 Decide which columns need to be searched/sorted by SQL queries. No, you don't need all the columns to be searchable or sortable. Certain columns are frequently used for selection; identify these. You probably won't use all of them in all queries, but you will use some of them in every query.

 The solution uses one table for all the EAV stuff. The columns include the searchable fields plus one [BLOB](../blob/index). Searchable fields are declared appropriately ([INT](../int/index), [TIMESTAMP](../timestamp/index), etc). The BLOB contains JSON-encoding of all the extra fields.

 The table should be [InnoDB](../innodb/index), hence it should have a PRIMARY KEY. The entitity\_id is the 'natural' PK. Add a small number of other indexes (often 'composite') on the searchable fields. [PARTITIONing](../managing-mariadb-partitioning/index) is unlikely to be of any use, unless the Entities should purged after some time. (Example: News Articles)

 But what about the ad hoc queries?
----------------------------------

 You have included the most important fields to search on -- date, category, etc. These should filter the data down significantly. When you also need to filter on something more obscure, that will be handled differently. The application code will look at the BLOB for that; more on this later.

 Why it works
------------

 * You are not really going to search on more than a few fields.
* The disk footprint is smaller; Smaller --> More cacheable --> Faster
* It needs no JOINs
* The indexes are useful
* The one table has one row per entity, and can grow as needed. (EAV needs many rows per entity.)
* Performance is as good as the indexes you have on the 'searchable fields'.
* Optionally, you can duplicate the indexed fields in the BLOB.
* Values missing from 'searchable fields' would need to be NULL (or whatever), and the code would need to deal with such.

 Details on the BLOB/JSON
------------------------

 * Build the extra (or all) key-value pairs in a hash (associative array) in your application. Encode it. COMPRESS it. Insert that string into the [BLOB](../blob/index).
* JSON is recommended, but not mandatory; it is simpler than XML. Other serializations (eg, YAML) could be used.
* COMPRESS the JSON and put it into a [BLOB](../blob/index) (or [MEDIUMBLOB](../mediumblob/index)) instead of a [TEXT](../text/index) field. Compression gives about 3x shrinkage.
* When SELECTing, UNCOMPRESS the blob. Decode the string into a hash. You are now ready to interrogate/display any of the extra fields.
* If you choose to use the JSON features of MariaDB or 5.7, you will have to forgo the compression feature described.
* MySQL 5.7.8's JSON native JSON datatype uses a binary format for more efficient access.

 Conclusions
-----------

 * Schema is reasonably compact (compression, real datatypes, less redundancy, etc, than EAV)
* Queries are fast (since you have picked 'good' indexes)
* Expandable (JSON is happy to have new fields)
* Compatible (No 3rd party products, just supported products)
* Range tests work (unlike storing [INTs](../int/index) in [VARCHARs](../varchar/index))
* (Drawback) Cannot use the non-indexed attributes in WHERE or ORDER BY clauses, must deal with that in the app. (MySQL 5.7 partially alleviates this.)

 Postlog
-------

 Posted Jan, 2014; Refreshed Feb, 2016.

 * MariaDB's [Dynamic Columns](../dynamic-columns/index)
* [MySQL 5.7's JSON](https://dev.mysql.com/doc/refman/5.7/en/json.html)

 This looks very promising; I will need to do more research to see how much of this article is obviated by it: [Using MySQL as a Document Store in 5.7](http://dev.mysql.com/doc/refman/5.7/en/document-store.html), [more DocStore discussion](http://mysqlserverteam.com/mysql-5-7-12-part-6-mysql-document-store-a-new-chapter-in-the-mysql-story/)

 If you insist on EAV, set [optimizer\_search\_depth=1](../server-system-variables/index#optimizer_search_depth).

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/eav>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/entity-attribute-value-implementation/>

Index Statistics
================

    How Index Statistics Help the Query Optimizer
---------------------------------------------

 The MariaDB query optimizer decides how best to execute each query based largely on the details of the indexes involved.

 The index statistics help inform these decisions. Imagine yourself choosing whether to look up a number in a phone book, or in your personal address book. You'd choose the personal phone book if at all possible, as it would (usually!) contain far fewer records and be quicker to search.

 Now imagine getting to your personal address book and finding it has twice the number of entries as the phone book. Your search would be slower. The same process applies to the query optimizer, so having access to up-to-date and accurate statistics is critical.

 Value Groups
------------

 The statistics are mainly based on groups of index elements of the same value. In a primary key, every index is unique, so every group size is one. In a non-unique index, you may have multiple keys with the same value. A worst-case example would be having large groups with the same value, for example an index on a boolean field.

 MariaDB makes heavy use of the average group size statistic. For example, if there are 100 rows, and twenty groups with the same index values, the average group size would be five.

 However, averages can be skewed by extremes, and the usual culprit is NULL values. The row of 100 may have 19 groups with an average size of 1, while the other 81 values are all NULL. MariaDB may think five is a good average size and choose to use that index, and then end up having to read through 81 rows with identical keys, taking longer than an alternative.

 Dealing with NULLs
------------------

 There are three main approaches to the problem of NULLs. NULL index values can be treated as a single group (nulls\_equal). This is usually fine, but if you have large numbers of NULLs the average group size is slanted higher, and the optimizer may miss using the index for ref accesses when it would be useful. This is the default used by XtraDB/InnoDB and MyISAM. Nulls\_unequal is the opposite approach, with each NULL forming its own group of one. Conversely, the average group size is slanted lower, and the optimizer may use the index for ref accesses when not suitable. This is the default used by the Aria storage engine. A third options sees NULL's ignored altogether from index group calculations.

 The default approaches can be changed by setting the [aria\_stats\_method](../aria-server-system-variables/index#aria_stats_method), [myisam\_stats\_method](../myisam-server-system-variables/index#myisam_stats_method) and [innodb\_stats\_method](../xtradbinnodb-server-system-variables/index#innodb_stats_method) server variables.

 Null-Safe and Regular Comparisons
---------------------------------

 The comparison operator used plays an important role. If two values are compared with <=> (see the [null-safe-equal](../null-safe-equal/index) comparison operator), and both are null, 1 is returned. If the same values are compared with = (see the [equal](../equal/index) comparison operator) null is returned. For example: 

 
```
SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
+---------+---------------+------------+
| 1 <=> 1 | NULL <=> NULL | 1 <=> NULL |
+---------+---------------+------------+
|       1 |             1 |          0 |
+---------+---------------+------------+

SELECT 1 = 1, NULL = NULL, 1 = NULL;
+-------+-------------+----------+
| 1 = 1 | NULL = NULL | 1 = NULL |
+-------+-------------+----------+
|     1 |        NULL |     NULL |
+-------+-------------+----------+

```

  


 Engine-Independent Statistics
-----------------------------

 [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) introduced a way to gather statistics independently of the storage engine. See [Engine-independent table statistics](../engine-independent-table-statistics/index).

   


 Histogram-Based Statistics
--------------------------

 [Histogram-Based Statistics](../histogram-based-statistics/index) were introduced in [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/), and are collected by default from [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

 See Also
--------

 * [User Statistics](../user-statistics/index). This plugin provides user, client, table and index usage statistics.
* [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [Engine-independent Statistics](../engine-independent-table-statistics/index)
* [Histogram-based Statistics](../histogram-based-statistics/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/index-statistics/>

Getting Started with Indexes
============================

     For a very basic overview, see [The Essentials of an Index](../the-essentials-of-an-index/index).

 There are four main kinds of indexes; primary keys (unique and not null), unique indexes (unique and can be null), plain indexes (not necessarily unique) and full-text indexes (for full-text searching).

 The terms 'KEY' and 'INDEX' are generally used interchangeably, and statements should work with either keyword.

 Primary Key
-----------

 A primary key is unique and can never be null. It will always identify only one record, and each record must be represented. Each table can only have one primary key.

 In [InnoDB](../innodb/index) tables, all indexes contain the primary key as a suffix. Thus, when using this storage engine, keeping the primary key as small as possible is particularly important. If a primary key does not exist and there are no UNIQUE indexes, InnoDB creates a 6-bytes clustered index which is invisible to the user.

 Many tables use a numeric ID field as a primary key. The [AUTO\_INCREMENT](../auto_increment/index) attribute can be used to generate a unique identity for new rows, and is commonly-used with primary keys.

 Primary keys are usually added when the table is created with the [CREATE TABLE](../create-table/index#indexes) statement. For example, the following creates a primary key on the ID field. Note that the ID field had to be defined as NOT NULL, otherwise the index could not have been created.

 
```
CREATE TABLE `Employees` (
  `ID` TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `First_Name` VARCHAR(25) NOT NULL,
  `Last_Name` VARCHAR(25) NOT NULL,
  `Position` VARCHAR(25) NOT NULL,
  `Home_Address` VARCHAR(50) NOT NULL,
  `Home_Phone` VARCHAR(12) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=Aria;

```

You cannot create a primary key with the [CREATE INDEX](../create-index/index) command. If you do want to add one after the table has already been created, use [ALTER TABLE](../alter-table/index), for example:

 
```
ALTER TABLE Employees ADD PRIMARY KEY(ID);

```

### Finding Tables Without Primary Keys

 Tables in the `[information\_schema](../information-schema-tables/index)` database can be queried to find tables that do not have primary keys. For example, here is a query using the [TABLES](../information-schema-tables-table/index) and [KEY\_COLUMN\_USAGE](../information-schema-key_column_usage-table/index) tables that can be used:

 
```
SELECT t.TABLE_SCHEMA, t.TABLE_NAME
FROM information_schema.TABLES AS t
LEFT JOIN information_schema.KEY_COLUMN_USAGE AS c 
ON t.TABLE_SCHEMA = c.CONSTRAINT_SCHEMA
   AND t.TABLE_NAME = c.TABLE_NAME
   AND c.CONSTRAINT_NAME = 'PRIMARY'
WHERE t.TABLE_SCHEMA != 'information_schema'
   AND t.TABLE_SCHEMA != 'performance_schema'
   AND t.TABLE_SCHEMA != 'mysql'
   AND c.CONSTRAINT_NAME IS NULL;

```

Unique Index
------------

 A Unique Index must be unique, but it can have columns that may be NULL. So each key value identifies only one record, but not each record needs to be represented.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**Unique, if index type is not specified, is normally a BTREE index that can also be used by the optimizer to find rows. If the key is longer than the max key length for the used storage engine and the storage engine supports long unique index, a HASH key will be created. This enables MariaDB to enforce uniqueness for any type or number of columns.

 
For example, to create a unique key on the Employee\_Code field, as well as a primary key, use:

 
```
CREATE TABLE `Employees` (
  `ID` TINYINT(3) UNSIGNED NOT NULL,
  `First_Name` VARCHAR(25) NOT NULL,
  `Last_Name` VARCHAR(25) NOT NULL,
  `Position` VARCHAR(25) NOT NULL,
  `Home_Address` VARCHAR(50) NOT NULL,
  `Home_Phone` VARCHAR(12) NOT NULL,
  `Employee_Code` VARCHAR(25) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY (`Employee_Code`)
) ENGINE=Aria;

```

Unique keys can also be added after the table is created with the [CREATE INDEX](../create-index/index) command, or with the [ALTER TABLE](../alter-table/index) command, for example:

 
```
ALTER TABLE Employees ADD UNIQUE `EmpCode`(`Employee_Code`); 

```

and

 
```
CREATE UNIQUE INDEX HomePhone ON Employees(Home_Phone);

```

Indexes can contain more than one column. MariaDB is able to use one or more columns on the leftmost part of the index, if it cannot use the whole index. (except for the HASH index type).

 Take another example:

 
```
CREATE TABLE t1 (a INT NOT NULL, b INT, UNIQUE (a,b));

INSERT INTO t1 values (1,1), (2,2);

SELECT * FROM t1;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    2 |
+---+------+

```

Since the index is defined as unique over both columns *a* and *b*, the following row is valid, as while neither *a* nor *b* are unique on their own, the combination is unique:

 
```
INSERT INTO t1 values (2,1);

SELECT * FROM t1;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    1 |
| 2 |    2 |
+---+------+

```

The fact that a `UNIQUE` constraint can be `NULL` is often overlooked. In SQL any `NULL` is never equal to anything, not even to another `NULL`. Consequently, a `UNIQUE` constraint will not prevent one from storing duplicate rows if they contain null values:

 
```
INSERT INTO t1 values (3,NULL), (3, NULL);

SELECT * FROM t1;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    1 |
| 2 |    2 |
| 3 | NULL |
| 3 | NULL |
+---+------+

```

Indeed, in SQL two last rows, even if identical, are not equal to each other:

 
```
SELECT (3, NULL) = (3, NULL);

+---------------------- +
| (3, NULL) = (3, NULL) |
+---------------------- +
| 0                     |
+---------------------- +

```

In MariaDB you can combine this with [virtual columns](../virtual-columns/index) to enforce uniqueness over a subset of rows in a table:

 
```
create table Table_1 (
  user_name varchar(10),
  status enum('Active', 'On-Hold', 'Deleted'),
  del char(0) as (if(status in ('Active', 'On-Hold'),'', NULL)) persistent,
  unique(user_name,del)
)

```

This table structure ensures that all *active* or *on-hold* users have distinct names, but as soon as a user is *deleted*, his name is no longer part of the uniqueness constraint, and another user may get the same name.

 If a unique index consists of a column where trailing pad characters are stripped or ignored, inserts into that column where values differ only by the number of trailing pad characters will result in a duplicate-key error.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**For some engines, like InnoDB, `UNIQUE` can be used with any type of columns or any number of columns.

 
```
create table t1 (a int primary key,
b blob,
c1 varchar(1000),
c2 varchar(1000),
c3 varchar(1000),
c4 varchar(1000),
c5 varchar(1000),
c6 varchar(1000),
c7 varchar(1000),
c8 varchar(1000),
c9 varchar(1000),
unique key `b` (b),
unique key `all_c` (c1,c2,c3,c4,c6,c7,c8,c9)) engine=myisam;

```

If the key length is longer than the max key length supported by the engine, a HASH key will be created. This can be seen with `SHOW CREATE TABLE table_name` or `SHOW INDEX FROM table_name`:

 
```
show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `a` int(11) NOT NULL,
  `b` blob DEFAULT NULL,
  `c1` varchar(1000) DEFAULT NULL,
  `c2` varchar(1000) DEFAULT NULL,
  `c3` varchar(1000) DEFAULT NULL,
  `c4` varchar(1000) DEFAULT NULL,
  `c5` varchar(1000) DEFAULT NULL,
  `c6` varchar(1000) DEFAULT NULL,
  `c7` varchar(1000) DEFAULT NULL,
  `c8` varchar(1000) DEFAULT NULL,
  `c9` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`a`),
  UNIQUE KEY `b` (`b`) USING HASH,
  UNIQUE KEY `all_c` (`c1`,`c2`,`c3`,`c4`,`c6`,`c7`,`c8`,`c9`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci


```


Plain Indexes
-------------

 Indexes do not necessarily need to be unique. For example:

 
```
CREATE TABLE t2 (a INT NOT NULL, b INT, INDEX (a,b));

INSERT INTO t2 values (1,1), (2,2), (2,2);

SELECT * FROM t2;
+---+------+
| a | b    |
+---+------+
| 1 |    1 |
| 2 |    2 |
| 2 |    2 |
+---+------+

```

Full-Text Indexes
-----------------

 Full-text indexes support full-text indexing and searching. See the [Full-Text Indexes](../full-text-indexes/index) section. 

 Choosing Indexes
----------------

 In general you should only add indexes to match the queries your application uses. Any extra will waste resources. In an application with very small tables, indexes will not make much difference but as soon as your tables are larger than your buffer sizes the indexes will start to speed things up dramatically.

 Using the [EXPLAIN](../explain/index) statement on your queries can help you decide which columns need indexing. 

 If you query contains something like `LIKE '%word%'`, without a fulltext index you are using a full table scan every time, which is very slow.

 If your table has a large number of reads and writes, consider using delayed writes. This uses the db engine in a "batch" write mode, which cuts down on disk io, therefore increasing performance.

 Use the [CREATE INDEX](../create-index/index) command to create an index.

 If you are building a large table then for best performance add the index after the table is populated with data. This is to increase the insert performance and remove the index overhead during inserts.

 Viewing Indexes
---------------

 You can view which indexes are present on a table, as well as details about them, with the [SHOW INDEX](../show-index/index) statement.

 If you want to know how to re-create an index, run `[SHOW CREATE TABLE](../show-create-table/index)`.

 When to Remove an Index
-----------------------

 If an index is rarely used (or not used at all) then remove it to increase INSERT, and UPDATE performance.

 If [user statistics](../user-statistics/index) are enabled, the [Information Schema](../information-schema/index) [INDEX\_STATISTICS](../information-schema-index_statistics-table/index) table stores the index usage.

 If the [slow query log](../slow-query-log/index) is enabled and the `[log\_queries\_not\_using\_indexes](../server-system-variables/index#log_queries_not_using_indexes)` server system variable is `ON`, the queries which do not use indexes are logged.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Proper_Indexing_Strategy> on 2012-10-30.*

 
See Also
--------

 * [AUTO\_INCREMENT](../auto_increment/index)
* [The Essentials of an Index](../the-essentials-of-an-index/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/getting-started-with-indexes/>

LIMIT ROWS EXAMINED
===================

    Syntax
------

 
```
SELECT ... FROM ... WHERE ...
[group_clause] [order_clause]
LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;

```

Similar to the parameters of `LIMIT`, *`rows_limit`* can be both a prepared statement parameter, or a stored program parameter.

 Description
-----------

 The purpose of this optimization is to provide the means to terminate the execution of `[SELECT](../select/index)` statements which examine too many rows, and thus use too many resources. This is achieved through an extension of the `[LIMIT](../select/index#limit)` clause — `LIMIT ROWS EXAMINED number_of_rows` . Whenever possible the semantics of `LIMIT ROWS EXAMINED` is the same as that of normal `LIMIT` (for instance for aggregate functions).

 The `LIMIT ROWS EXAMINED` clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:

 * If a query is `[EXPLAIN](../explain/index)`-ed.
* During query optimization.
* During auxiliary operations such as writing to system tables (e.g. logs).

 The clause is not applicable to `[DELETE](../delete/index)` or `[UPDATE](../update/index)` statements, and if used in those statements produces a syntax error.

 The effects of this clause are as follows:

 * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.
* Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.
* The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
	+ The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
	+ A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
	+ If query processing was interrupted during filesort, an error is returned in addition to the warning.
	+ If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
	+ Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
	+ If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

 The `LIMIT ROWS EXAMINED` clause cannot be specified on a per-subquery basis. There can be only one `LIMIT ROWS EXAMINED` clause for the whole `SELECT` statement. If a `SELECT` statement contains several subqueries with `LIMIT ROWS EXAMINED`, the one that is parsed last is taken into account.

 Examples
--------

 A simple example of the clause is:

 
```
SELECT * from t1, t2 LIMIT 10 ROWS EXAMINED 10000;

```

The `LIMIT ROWS EXAMINED` clause is global for the whole statement.

 If a composite query (such as `UNION`, or query with derived tables or with subqueries) contains more than one `LIMIT ROWS EXAMINED`, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account. For instance, in the query:

 
```
SELECT * FROM t1
WHERE c1 IN (SELECT * FROM t2 WHERE c2 > ' ' LIMIT ROWS EXAMINED 0)
LIMIT ROWS EXAMINED 11;

```

The limit that is taken into account is 11, not 0.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/limit-rows-examined/>

How to Quickly Insert Data Into MariaDB
=======================================

    This article describes different techniques for inserting data quickly into MariaDB.

 Background
----------

 When inserting new data into MariaDB, the things that take time are: (in order of importance):

 * Syncing data to disk (as part of the end of transactions)
* Adding new keys. The larger the index, the more time it takes to keep keys updated.
* Checking against foreign keys (if they exist).
* Adding rows to the storage engine.
* Sending data to the server.

 The following describes the different techniques (again, in order of importance) you can use to quickly insert data into a table.

 Disabling Keys
--------------

 You can temporarily disable updating of non unique indexes. This is mostly useful when there are zero (or very few) rows in the table into which you are inserting data.

 
```
ALTER TABLE table_name DISABLE KEYS;
BEGIN;
... inserting data with INSERT or LOAD DATA ....
COMMIT;
ALTER TABLE table_name ENABLE KEYS;

```

In many storage engines (at least MyISAM and Aria), `ENABLE KEYS` works by scanning through the row data and collecting keys, sorting them, and then creating the index blocks. This is an order of magnitude faster than creating the index one row at a time and it also uses less key buffer memory.

 
**Note:** When you insert into an **empty table** with [INSERT](../insert/index) or [LOAD DATA](../load-data-infile/index), MariaDB **automatically** does an [DISABLE KEYS](../alter-table/index) before and an [ENABLE KEYS](../alter-table/index) afterwards.

 
When inserting big amounts of data, integrity checks are sensibly time-consuming. It is possible to disable the `UNIQUE` indexes and the [foreign keys](../foreign-keys/index) checks using the [unique\_checks](../server-system-variables/index#unique_checks) and the [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) system variables:

 
```
SET @@session.unique_checks = 0;
SET @@session.foreign_key_checks = 0;

```

For InnoDB tables, the [AUTO\_INCREMENT lock mode](../auto_increment-handling-in-innodb/index) can be temporarily set to 2, which is the fastest setting:

 
```
SET @@global.innodb_autoinc_lock_mode = 2;

```

Also, if the table has [INSERT triggers](../triggers/index) or [PERSISTENT](../virtual-columns/index) columns, you may want to drop them, insert all data, and recreate them.

 Loading Text Files
------------------

 The **fastest way** to insert data into MariaDB is through the [LOAD DATA INFILE](../load-data-infile/index) command.

 The simplest form of the command is:

 
```
LOAD DATA INFILE 'file_name' INTO TABLE table_name;

```

You can also read a file locally on the machine where the client is running by using:

 
```
LOAD DATA LOCAL INFILE 'file_name' INTO TABLE table_name;

```

This is not as fast as reading the file on the server side, but the difference is not that big.

 `LOAD DATA INFILE` is very fast because:

 1. there is no parsing of SQL.
2. data is read in big blocks.
3. if the table is empty at the beginning of the operation, all non unique indexes are disabled during the operation.
4. the engine is told to cache rows first and then insert them in big blocks (At least MyISAM and Aria support this).
5. for empty tables, some transactional engines (like Aria) do not log the inserted data in the transaction log because one can rollback the operation by just doing a [TRUNCATE](../truncate-table/index) on the table.

 Because of the above speed advantages there are many cases, when you need to insert **many** rows at a time, where it may be faster to create a file locally, add the rows there, and then use `LOAD DATA INFILE` to load them; compared to using `INSERT` to insert the rows.

 You will also get [progress reporting](../progress-reporting/index) for `LOAD DATA INFILE`.

 ### mariadb-import

 You can import many files in parallel with [mariadb-import](../mariadb-import/index) (`mysqlimport` before [MariaDB 10.5](../what-is-mariadb-105/index)). For example:

 
```
mariadb-import --use-threads=10 database text-file-name [text-file-name...]

```

Internally [mariadb-import](../mariadb-import/index) uses [LOAD DATA INFILE](../load-data-infile/index) to read in the data.

 Inserting Data with INSERT Statements
-------------------------------------

 ### Using Big Transactions

 When doing many inserts in a row, you should wrap them with `BEGIN / END` to avoid doing a full transaction (which includes a disk sync) for every row. For example, doing a begin/end every 1000 inserts will speed up your inserts by almost 1000 times.

 
```
BEGIN;
INSERT ...
INSERT ...
END;
BEGIN;
INSERT ...
INSERT ...
END;
...

```

The reason why you may want to have many `BEGIN/END` statements instead of just one is that the former will use up less transaction log space.

 ### Multi-Value Inserts

 You can insert many rows at once with multi-value row inserts:

 
```
INSERT INTO table_name values(1,"row 1"),(2, "row 2"),...;

```

The limit for how much data you can have in one statement is controlled by the [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) server variable.

 Inserting Data Into Several Tables at Once
------------------------------------------

 If you need to insert data into several tables at once, the best way to do so is to enable multi-row statements and send many inserts to the server at once:

 
```
INSERT INTO table_name_1 (auto_increment_key, data) VALUES (NULL,"row 1");
INSERT INTO table_name_2 (auto_increment, reference, data) values (NULL, LAST_INSERT_ID(), "row 2");

```

[LAST\_INSERT\_ID()](../last_insert_id/index) is a function that returns the last `auto_increment` value inserted.

 By default, the command line `mariadb` client will send the above as multiple statements.

 To test this in the `mariadb` client you have to do:

 
```
delimiter ;;
select 1; select 2;;
delimiter ;

```


**Note:** for multi-query statements to work, your client must specify the `CLIENT_MULTI_STATEMENTS` flag to `mysql_real_connect()`.

 
Server Variables That Can be Used to Tune Insert Speed
------------------------------------------------------

 


| Option | Description |
| --- | --- |
| [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) | Increase this if you have many indexes in InnoDB/XtraDB tables |
| [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) | Increase this if you have many indexes in MyISAM tables |
| [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) | Increase this to allow bigger multi-insert statements |
| [read\_buffer\_size](../server-system-variables/index#read_buffer_size) | Read block size when reading a file with `LOAD DATA` |

 
See [Server System Variables](../server-system-variables/index) for the full list of server variables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-to-quickly-insert-data-into-mariadb/>

Statistics for Optimizing Queries
==================================

   Different statistics provided by MariaDB to help you optimize your queries

  

| Title | Description |
| --- | --- |
|  [Engine-Independent Table Statistics](../engine-independent-table-statistics/index) |  Table statistics independent of the storage engine.  |
|  [Histogram-Based Statistics](../histogram-based-statistics/index) |  Histogram-based statistics can improve the optimizer query plan in certain situations.  |
|  [Index Statistics](../index-statistics/index) |  Index statistics and the query optimizer.  |
|  [InnoDB Persistent Statistics](../innodb-persistent-statistics/index) |  InnoDB persistent statistics are stored on disk, leading to more consistent query plans.  |
|  [Slow Query Log Extended Statistics](../slow-query-log-extended-statistics/index) |  The slow query log makes extended statistics available.  |
|  [User Statistics](../user-statistics/index) |  User Statistics.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/statistics-for-optimizing-queries/>

MariaDB 5.3 Optimizer Debugging
===============================

    [MariaDB 5.3](../what-is-mariadb-53/index) has an optimizer debugging patch. The patch is pushed into

 [lp:maria-captains/maria/5.3-optimizer-debugging](https://code.launchpad.net/~maria-captains/maria/5.3-optimizer-debugging)

 The patch is wrapped in #ifdef, but there is a #define straight in mysql\_priv.h so simply compiling that tree should produce a binary with optimizer debugging enabled.

 The patch adds two system variables:

 * `@@debug_optimizer_prefer_join_prefix`
* `@@debug_optimizer_dupsweedout_penalized`

 the variables are present as session/global variables, and are also settable via the server command line.

 debug\_optimizer\_prefer\_join\_prefix
--------------------------------------

 If this variable is non-NULL, it is assumed to specify a join prefix as a comma-separated list of table aliases:

 
```
set debug_optimizer_prefer_join_prefix='tbl1,tbl2,tbl3';

```

The optimizer will try its best to build a join plan which matches the specified join prefix. It does this by comparing join prefixes it is considering with `@@debug_optimizer_prefer_join_prefix`, and multiplying cost by a million if the plan doesn't match the prefix.

 As a result, you can more-or-less control the join order. For example, let's take this query:

 
```
MariaDB [test]> explain select * from ten A, ten B, ten C;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                              |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
|  1 | SIMPLE      | A     | ALL  | NULL          | NULL | NULL    | NULL |   10 |                                    |
|  1 | SIMPLE      | B     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using join buffer (flat, BNL join) |
|  1 | SIMPLE      | C     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using join buffer (flat, BNL join) |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
3 rows in set (0.00 sec)

```

and request a join order of C,A,B:

 
```
MariaDB [test]> set debug_optimizer_prefer_join_prefix='C,A,B';
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> explain select * from ten A, ten B, ten C;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                              |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
|  1 | SIMPLE      | C     | ALL  | NULL          | NULL | NULL    | NULL |   10 |                                    |
|  1 | SIMPLE      | A     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using join buffer (flat, BNL join) |
|  1 | SIMPLE      | B     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using join buffer (flat, BNL join) |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------------+
3 rows in set (0.00 sec)

```

We got it. 

 Note that this is still a *best-effort* approach:

 * you won't be successful in forcing join orders which the optimizer considers invalid (e.g. for "t1 LEFT JOIN t2" you won't be able to get a join order of t2,t1).
* The optimizer does various plan pruning and may discard the requested join order before it has a chance to find out that it is a million-times cheaper than any other.

 ### Semi-joins

 It is possible to force the join order of joins plus semi-joins. This may cause a different strategy to be used:

 
```
MariaDB [test]> set debug_optimizer_prefer_join_prefix=NULL;
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> explain select * from ten A where a in (select B.a from ten B, ten C where C.a + A.a < 4);
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                      |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------+
|  1 | PRIMARY     | A     | ALL  | NULL          | NULL | NULL    | NULL |   10 |                            |
|  1 | PRIMARY     | B     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using where                |
|  1 | PRIMARY     | C     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using where; FirstMatch(A) |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------+
3 rows in set (0.00 sec)

MariaDB [test]> set debug_optimizer_prefer_join_prefix='C,A,B';
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> explain select * from ten A where a in (select B.a from ten B, ten C where C.a + A.a < 4);
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                           |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------------------------------+
|  1 | PRIMARY     | C     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Start temporary                                 |
|  1 | PRIMARY     | A     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using where; Using join buffer (flat, BNL join) |
|  1 | PRIMARY     | B     | ALL  | NULL          | NULL | NULL    | NULL |   10 | Using where; End temporary                      |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------------------------------+
3 rows in set (0.00 sec)


```

Semi-join materialization is a somewhat special case, because "join prefix" is not exactly what you see in the EXPLAIN output. For semi-join materialization:

 * don't put "`<subqueryN>`" into `@@debug_optimizer_prefer_join_prefix`
* instead, put all of the materialization tables into the place where you want the `<subqueryN>` line.
* Attempts to control the join order inside the materialization nest will be unsuccessful. Example: we want A-C-B-AA:

 
```
MariaDB [test]> set debug_optimizer_prefer_join_prefix='A,C,B,AA';
Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> explain select * from ten A, ten AA where A.a in (select B.a from ten B, ten C);
+----+-------------+-------------+--------+---------------+--------------+---------+------+------+------------------------------------+
| id | select_type | table       | type   | possible_keys | key          | key_len | ref  | rows | Extra                              |
+----+-------------+-------------+--------+---------------+--------------+---------+------+------+------------------------------------+
|  1 | PRIMARY     | A           | ALL    | NULL          | NULL         | NULL    | NULL |   10 |                                    |
|  1 | PRIMARY     | <subquery2> | eq_ref | distinct_key  | distinct_key | 5       | func |    1 |                                    |
|  1 | PRIMARY     | AA          | ALL    | NULL          | NULL         | NULL    | NULL |   10 | Using join buffer (flat, BNL join) |
|  2 | SUBQUERY    | B           | ALL    | NULL          | NULL         | NULL    | NULL |   10 |                                    |
|  2 | SUBQUERY    | C           | ALL    | NULL          | NULL         | NULL    | NULL |   10 |                                    |
+----+-------------+-------------+--------+---------------+--------------+---------+------+------+------------------------------------+
5 rows in set (0.00 sec)

```

but we get A-B-C-AA.

 debug\_optimizer\_dupsweedout\_penalized
----------------------------------------

 There are four semi-join execution strategies:

 1. `FirstMatch`
2. `Materialization`
3. `LooseScan`
4. `DuplicateWeedout`

 The first three strategies have flags in @@optimizer\_switch that can be used to disable them. The `DuplicateWeedout` strategy does not have a flag. This was done for a reason, as that strategy is the catch-all strategy and it can handle all kinds of subqueries, in all kinds of join orders. (We're slowly moving to the point where it will be possible to run with `FirstMatch` enabled and everything else disabled but we are not there yet.)

 Since `DuplicateWeedout` cannot be disabled, there are cases where it "gets in the way" by being chosen over the strategy you need. This is what `debug_optimizer_dupsweedout_penalized` is for. if you set:

 
```
MariaDB [test]> set debug_optimizer_dupsweedout_penalized=TRUE;

```

...the costs of query plans that use `DuplicateWeedout` will be multiplied by a millon. This doesn't mean that you will get rid of `DuplicateWeedout` — due to [Bug #898747](https://bugs.launchpad.net/bugs/898747) it is still possible to have `DuplicateWeedout` used even if a cheaper plan exits. A partial remedy to this is to run with

 
```
MariaDB [test]> set optimizer_prune_level=0;

```

It is possible to use both `debug_optimizer_dupsweedout_penalized` and `debug_optimizer_prefer_join_prefix` at the same time. This should give you the desired strategy and join order.

 Further reading
---------------

 * See mysql-test/t/debug\_optimizer.test (in the MariaDB source code) for examples

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-53-optimizer-debugging/>

Query Limits and Timeouts
=========================

    This article describes the different methods MariaDB provides to limit/timeout a query: 

 [LIMIT](../select/index#limit)
------------------------------

 
```
SELECT ... LIMIT row_count
or
SELECT ... LIMIT offset, row_count
or
SELECT ... LIMIT row_count OFFSET offset

```

The [LIMIT](../select/index#limit) clause restricts the number of returned rows.

 [LIMIT ROWS EXAMINED](../limit-rows-examined/index)
---------------------------------------------------

 
```
SELECT ... LIMIT ROWS EXAMINED rows_limit;

```

Stops the query after 'rows\_limit' number of rows have been examined.

 sql\_safe\_updates
------------------

 If the [sql\_safe\_updates](../server-system-variables/index#sql_safe_updates) variable is set, one can't execute an [UPDATE](../update/index) or [DELETE](../delete/index) statement unless one specifies a key constraint in the `WHERE` clause or provide a `LIMIT` clause (or both).

 
```
SET @@SQL_SAFE_UPDATES=1
UPDATE tbl_name SET not_key_column=val;
-> ERROR 1175 (HY000): You are using safe update mode 
  and you tried to update a table without a WHERE that uses a KEY column

```

sql\_select\_limit
------------------

 [sql\_select\_limit](../server-system-variables/index#sql_select_limit) acts as an automatic `LIMIT row_count` to any [SELECT](../select/index) query.

 
```
SET @@SQL_SELECT_LIMIT=1000
SELECT * from big_table;

```

The above is the same as:

 
```
SELECT * from big_table LIMIT 1000;

```

max\_join\_size
---------------

 If the [max\_join\_size](../server-system-variables/index#max_join_size) variable (also called `sql_max_join_size`) is set, then it will limit any SELECT statements that probably need to examine more than `MAX_JOIN_SIZE` rows.

 
```
SET @@MAX_JOIN_SIZE=1000;
SELECT count(null_column) from big_table;
->ERROR 1104 (42000): The SELECT would examine more than MAX_JOIN_SIZE rows; 
  check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay

```

max\_statement\_time
--------------------

 If the [max\_statement\_time](../server-system-variables/index#max_statement_time) variable is set, any query (excluding stored procedures) taking longer than the value of `max_statement_time` (specified in seconds) to execute will be aborted. This can be set globally, by session, as well as per user and per query. See [Aborting statements that take longer than a certain time to execute](../aborting-statements-that-take-longer-than-a-certain-time-to-execute/index).

 See Also
--------

 * [WAIT and NOWAIT](../wait-and-nowait/index)
* [Aborting statements that take longer than a certain time to execute](../aborting-statements/index)
* [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) variable

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-limits-and-timeouts/>

Data Sampling: Techniques for Efficiently Finding a Random Row
==============================================================

    Fetching random rows from a table (beyond ORDER BY RAND())
----------------------------------------------------------

 ### The problem

 One would like to do "SELECT ... ORDER BY RAND() LIMIT 10" to get 10 rows at random. But this is slow. The optimizer does

 * Fetch all the rows -- this is costly
* Append [RAND()](../rand/index) to the rows
* Sort the rows -- also costly
* Pick the first 10.

 All the algorithms given below are "fast", but most introduce flaws:

 * Bias -- some rows are more like to be fetched than others.
* Repetitions -- If two random sets contain the same row, they are likely to contain other dups.
* Sometimes failing to fetch the desired number of rows.

 "Fast" means avoiding reading all the rows. There are many techniques that require a full table scan, or at least an index scan. They are not acceptable for this list. There is even a technique that averages half a scan; it is relegated to a footnote.

 ### Metrics

 Here's a way to measure performance without having a big table.

 
```
    FLUSH STATUS;
    SELECT ...;
    SHOW SESSION STATUS LIKE 'Handler%';

```

If some of the "Handler" numbers look like the number of rows in the table, then there was a table scan.

 None of the queries presented here need a full table (or index) scan. Each has a time proportional to the number of rows returned.

 Virtually all published algorithms involve a table scan. The previously published version of this blog had, embarrassingly, several algorithms that had table scans.

 Sometimes the scan can be avoided via a subquery. For example, the first of these will do a table scan; the second will not.

 
```
SELECT *  FROM RandTest AS a
  WHERE id = FLOOR(@min + (@max - @min + 1) * RAND());  -- BAD: table scan
SELECT *
 FROM RandTest AS a
 JOIN (
   SELECT FLOOR(@min + (@max - @min + 1) * RAND()) AS id -- Good; single eval.
      ) b  USING (id);

```

### Case: Consecutive AUTO\_INCREMENT without gaps, 1 row returned

 * Requirement: [AUTO\_INCREMENT](../auto_increment/index) id
* Requirement: No gaps in id

 
```
  SELECT r.*
      FROM (
          SELECT FLOOR(mm.min_id + (mm.max_id - mm.min_id + 1) * RAND()) AS id
              FROM (
                  SELECT MIN(id) AS min_id,
                         MAX(id) AS max_id
                      FROM RandTest
                   ) AS mm
           ) AS init
      JOIN  RandTest AS r  ON r.id = init.id;

```

(Of course, you might be able to simplify this. For example, min\_id is likely to be 1. Or precalculate limits into @min and @max.)

 ### Case: Consecutive AUTO\_INCREMENT without gaps, 10 rows

 * Requirement: AUTO\_INCREMENT id
* Requirement: No gaps in id
* Flaw: Sometimes delivers fewer than 10 rows

 
```
  -- First select is one-time:
  SELECT @min := MIN(id),
         @max := MAX(id)
      FROM RandTest;
  SELECT DISTINCT *
      FROM RandTest AS a
      JOIN (
          SELECT FLOOR(@min + (@max - @min + 1) * RAND()) AS id
              FROM RandTest
              LIMIT 11    -- more than 10 (to compensate for dups)
           ) b  USING (id)
      LIMIT 10;           -- the desired number of rows

```

The FLOOR expression could lead to duplicates, hence the inflated inner LIMIT. There could (rarely) be so many duplicates that the inflated LIMIT leads to fewer than the desired 10 different rows. One approach to that Flaw is to rerun the query if it delivers too few rows.

 A variant:

 
```
  SELECT r.*
      FROM (
          SELECT FLOOR(mm.min_id + (mm.max_id - mm.min_id + 1) * RAND()) AS id
              FROM (
                  SELECT MIN(id) AS min_id,
                         MAX(id) AS max_id
                      FROM RandTest
                   ) AS mm
              JOIN ( SELECT id dummy FROM RandTest LIMIT 11 ) z
           ) AS init
      JOIN  RandTest AS r  ON r.id = init.id
      LIMIT 10;

```

Again, ugly but fast, regardless of table size.

 ### Case: AUTO\_INCREMENT with gaps, 1 or more rows returned

 * Requirement: AUTO\_INCREMENT, possibly with gaps due to DELETEs, etc
* Flaw: Only semi-random (rows do not have an equal chance of being picked), but it does partially compensate for the gaps
* Flaw: The first and last few rows of the table are less likely to be delivered.

 This gets 50 "consecutive" ids (possibly with gaps), then delivers a random 10 of them.

 
```
-- First select is one-time:
SELECT @min := MIN(id),
       @max := MAX(id)
    FROM RandTest;
SELECT a.*
    FROM RandTest a
    JOIN ( SELECT id FROM
            ( SELECT id
                FROM ( SELECT @min + (@max - @min + 1 - 50) * RAND() 
                  AS start FROM DUAL ) AS init
                JOIN RandTest y
                WHERE    y.id > init.start
                ORDER BY y.id
                LIMIT 50         -- Inflated to deal with gaps
            ) z ORDER BY RAND()
           LIMIT 10              -- number of rows desired (change to 1 if looking for a single row)
         ) r ON a.id = r.id;

```

Yes, it is complex, but yes, it is fast, regardless of the table size.

 ### Case: Extra FLOAT column for randomizing

 (Unfinished: need to check these.)

 Assuming `rnd` is a FLOAT (or DOUBLE) populated with RAND() and INDEXed:

 * Requirement: extra, indexed, FLOAT column
* Flaw: Fetches 10 adjacent rows (according to `rnd`), hence not good randomness
* Flaw: Near 'end' of table, can't find 10 rows.

 
```
  SELECT r.*
      FROM ( SELECT RAND() AS start FROM DUAL ) init
      JOIN RandTest r
      WHERE r.rnd >= init.start
      ORDER BY r.rnd
      LIMIT 10;

```

* These two variants attempt to resolve the end-of-table flaw:

 
```
  SELECT r.*
      FROM ( SELECT RAND() * ( SELECT rnd
                        FROM RandTest
                        ORDER BY rnd DESC
                        LIMIT 10,1 ) AS start
           ) AS init
      JOIN RandTest r
      WHERE r.rnd > init.start
      ORDER BY r.rnd
      LIMIT 10;


  SELECT @start := RAND(),
         @cutoff := CAST(1.1 * 10 + 5 AS DECIMAL(20,8)) / TABLE_ROWS
      FROM information_schema.TABLES
      WHERE TABLE_SCHEMA = 'dbname'
        AND TABLE_NAME = 'RandTest'; -- 0.0030
  SELECT d.*
      FROM (
          SELECT a.id
              FROM RandTest a
              WHERE rnd BETWEEN @start AND @start + @cutoff
           ) sample
      JOIN RandTest d USING (id)
      ORDER BY rand()
      LIMIT 10;

```

### Case: UUID or MD5 column

 * Requirement: UUID/GUID/MD5/SHA1 column exists and is indexed.
* Similar code/benefits/flaws to AUTO\_INCREMENT with gaps.
* Needs 7 random HEX digits:

 
```
RIGHT( HEX( (1<<24) * (1+RAND()) ), 6)

```

can be used as a `start` for adapting a gapped AUTO\_INCREMENT case. If the field is BINARY instead of hex, then 

 
```
UNHEX(RIGHT( HEX( (1<<24) * (1+RAND()) ), 6))

```

See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/random>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-sampling-techniques-for-efficiently-finding-a-random-row/>

Data Warehousing High Speed Ingestion
=====================================

    The problem
-----------

 You are ingesting lots of data. Performance is bottlenecked in the INSERT area.

 This will be couched in terms of Data Warehousing, with a huge `Fact` table and Summary (aggregation) tables.

 Overview of solution
--------------------

 * Have a separate staging table.
* Inserts go into `Staging`.
* Normalization and Summarization reads Staging, not Fact.
* After normalizing, the data is copied from Staging to Fact.

 `Staging` is one (or more) tables in which the data lives only long enough to be handed off to Normalization, Summary, and the Fact tables.

 Since we are probably talking about a billion-row table, shrinking the width of the Fact table by normalizing (as mentioned here). Changing an [INT](../int/index) to a [MEDIUMINT](../mediumint/index) will save a GB. Replacing a string by an id (normalizing) saves many GB. This helps disk space and cacheability, hence speed.

 Injection speed
---------------

 Some variations:

 * Big dump of data once an hour, versus continual stream of records.
* The input stream could be single-threaded or multi-threaded.
* You might have 3rd party software tying your hands.

 Generally the fastest injection rate can be achieved by "staging" the INSERTs in some way, then batch processing the staged records. This blog discusses various techniques for staging and batch processing.

 Normalization
-------------

 Let's say your Input has a [VARCHAR](../varchar/index) `host\_name` column, but you need to turn that into a smaller [MEDIUMINT](../mediumint/index) `host\_id` in the Fact table. The "Normalization" table, as I call it, looks something like

 
```
CREATE TABLE Hosts (
    host_id  MEDIUMINT UNSIGNED  NOT NULL AUTO_INCREMENT,
    host_name VARCHAR(99) NOT NULL,
    PRIMARY KEY (host_id),      -- for mapping one direction
    INDEX(host_name, host_id)   -- for mapping the other direction
) ENGINE=InnoDB;                -- InnoDB works best for Many:Many mapping table

```

Here's how you can use `Staging` as an efficient way achieve the swap from name to id.

 Staging has two fields (for this normalization example):

 
```
    host_name VARCHAR(99) NOT NULL,     -- Comes from the insertion proces
    host_id  MEDIUMINT UNSIGNED  NULL,  -- NULL to start with; see code below

```

Meawhile, the Fact table has:

 
```
    host_id  MEDIUMINT UNSIGNED NOT NULL,

```

SQL #1 (of 2):

 
```
    # This should not be in the main transaction, and it should be done with autocommit = ON
    # In fact, it could lead to strange errors if this were part
    #    of the main transaction and it ROLLBACKed.
    INSERT IGNORE INTO Hosts (host_name)
        SELECT DISTINCT s.host_name
            FROM Staging AS s
            LEFT JOIN Hosts AS n  ON n.host_name = s.host_name
            WHERE n.host_id IS NULL;

```

By isolating this as its own transaction, we get it finished in a hurry, thereby minimizing blocking. By saying IGNORE, we don't care if other threads are 'simultaneously' inserting the same host\_names.

 There is a subtle reason for the LEFT JOIN. If, instead, it were INSERT IGNORE..SELECT DISTINCT, then the INSERT would preallocate auto\_increment ids for as many rows as the SELECT provides. This is very likely to "burn" a lot of ids, thereby leading to overflowing MEDIUMINT unnecessarily. The LEFT JOIN leads to finding just the new ids that are needed (except for the rare possibility of a 'simultaneous' insert by another thread). More rationale: [Mapping table](../building-the-best-index-for-a-given-select/index)

 SQL #2:

 
```
    # Also not in the main transaction, and it should be with autocommit = ON
    # This multi-table UPDATE sets the ids in Staging:
    UPDATE   Hosts AS n
        JOIN Staging AS s  ON s.host_name = n host_name
        SET s.host_id = n.host_id

```

This gets the IDs, whether already existing, set by another thread, or set by SQL #1.

 If the size of `Staging` changes depending on the busy versus idle times of the day, this pair of SQL statements has another comforting feature. The more rows in `Staging`, the more efficient the SQL runs, thereby helping compensate for the "busy" times.

 The companion [Data Warehouse article](../data-warehousing-techniques/index) folds SQL #2 into the INSERT INTO Fact. But you may need host\_id for further normalization steps and/or Summarization steps, so this explicit UPDATE shown here is often better.

 Flip-flop staging
-----------------

 The simple way to stage is to ingest for a while, then batch-process what is in `Staging`. But that leads to new records piling up waiting to be staged. To avoid that issue, have 2 processes:

 * one process (or set of processes) for INSERTing into `Staging`;
* one process (or set of processes) to do the batch processing (normalization, summarization).

 To keep the processes from stepping on each other, we have a pair of staging tables:

 * `Staging` is being INSERTed into;
* `StageProcess` is one being processed for normalization, summarization, and moving to the Fact table. A separate process does the processing, then swaps the tables:

 
```
    DROP   TABLE StageProcess;
    CREATE TABLE StageProcess LIKE Staging;
    RENAME TABLE Staging TO tmp, StageProcess TO Staging, tmp TO StageProcess;

```

This may not seem like the shortest way to do it, but has these features:

 * The DROP + CREATE might be faster than TRUNCATE, which is the desired effect.
* The RENAME is atomic, so the INSERT process(es) never find that `Staging` is missing.

 A variant on the 2-table flip-flop is to have a separate `Staging` table for each Insertion process. The Processing process would run around to each Staging in turn.

 A variant on that would be to have a separate processing process for each Insertion process.

 The choice depends on which is faster (insertion or processing). There are tradeoffs; a single processing thread avoids some locks, but lacks some parallelism.

 Engine choice
-------------

 `Fact` table -- [InnoDB](../innodb/index), if for no other reason than that a system crash would not need a REPAIR TABLE. (REPAIRing a billion-row [MyISAM](../myisam/index) table can take hours or days.)

 Normalization tables -- InnoDB, primarily because it can be done efficiently with 2 indexes, whereas, MyISAM would need 4 to achieve the same efficiency.

 `Staging` -- Lots of options here.

 * If you have multiple Inserters and a single Staging table, InnoDB is desirable due to row-level, not table-level, locking.
* MEMORY may be the fastest and it avoids I/O. This is good for a single staging table.
* For multiple Inserters, a separate Staging table for each Inserter is desired.
* For multiple Inserters into a single Staging table, InnoDB may be faster. (MEMORY does table-level locking.)
* With one non-InnoDB Staging table per Inserter, using an explicit LOCK TABLE avoids repeated implicit locks on each INSERT.
* But, if you are doing LOCK TABLE and the Processing thread is separate, an UNLOCK is necessary periodically to let the RENAME grab the table.
* "Batch INSERTs" (100-1000 rows per SQL) eliminates much of the issues of the above bullet items.

 Confused? Lost? There are enough variations in applications that make it impractical to predict what is best. Or, simply good enough. Your ingestion rate may be low enough that you don't hit the brick walls that I am helping you avoid.

 Should you do "CREATE TEMPORARY TABLE"? Probably not. Consider `Staging` as part of the data flow, not to be DROPped.

 Summarization
-------------

 This is mostly covered here: [Summary Tables](../data-warehousing-summary-tables/index)  
 Summarize from the Staging table instead of the Fact table.

 Replication Issues
------------------

 Row Based Replication (RBR) is probably the best option.

 The following allows you to keep more of the Ingestion process in the Master, thereby not bogging down the Slave(s) with writes to the Staging table.

 * RBR
* `Staging` is in a separate database
* That database is not replicated (binlog-ignore-db on Master)
* In the Processing steps, USE that database, reach into the main db via syntax like "MainDb.Hosts". (Otherwise, the binlog-ignore-db does the wrong thing.)

 That way

 * Writes to `Staging` are not replicated.
* Normalization sends only the few updates to the normalization tables.
* Summarization sends only the updates to the summary tables.
* Flip-flop does not replicate the DROP, CREATE or RENAME.

 Sharding
--------

 You could possibly spread the data you are trying ingest across multiple machines in a predictable way (sharding on hash, range, etc). Running "reports" on a sharded Fact table is a challenge unto itself. On the other hand, Summary Tables rarely get too big to manage on a single machine.

 For now, Sharding is beyond the scope of this blog.

 Push me vs pull me
------------------

 I have implicitly assumed the data is being pushed into the database. If, instead, you are "pulling" data from some source(s), then there are some different considerations.

 Case 1: An hourly upload; run via cron

  1. Grab the upload, parse it 2. Put it into the Staging table 3. Normalize -- each SQL in its own transaction (autocommit) 4. BEGIN 5. Summarize 6. Copy from Staging to Fact. 7. COMMIT

 If you need parallelism in Summarization, you will have to sacrifice the transactional integrity of steps 4-7.

 Caution: If these steps add up to more than an hour, you are in deep dodo.

 Case 2: You are polling for the data

 It is probably reasonable to have multiple processes doing this, so it will be detailed about locking.

  0. Create a Staging table for this polling processor. Loop: 1. With some locked mechanism, decide which 'thing' to poll. 2. Poll for the data, pull it in, parse it. (Potentially polling and parsing are significantly costly) 3. Put it into the process-specific Staging table 4. Normalize -- each SQL in its own transaction (autocommit) 5. BEGIN 6. Summarize 7. Copy from Staging to Fact. 8. COMMIT 9. Declare that you are finished with this 'thing' (see step 1) EndLoop.

 iblog\_file\_size should be larger than the change in the STATUS "Innodb\_os\_log\_written" across the BEGIN...COMMIT transaction (for either Case).

 See also
--------

 * [companion Data Warehouse blog](../mariadb/data-warehousing-techniques/index)
* [companion Summary Table blog](../mariadb/data-warehousing-summary-tables/index)
* [a forum thread that prodded me into writing this blog](http://forums.mysql.com/read.php?106,623744)
* [StackExchange discussion](http://dba.stackexchange.com/a/108726/1876)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/staging_table>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-warehousing-high-speed-ingestion/>

Data Warehousing Summary Tables
===============================

    Preface
-------

 This document discusses the creation and maintenance of "Summary Tables". It is a companion to the document on [Data Warehousing Techniques](../data-warehousing-techniques/index).

 The basic terminology ("Fact Table", "[Normalization](../database-normalization/index)", etc) is covered in that document.

 Summary tables for data warehouse "reports"
-------------------------------------------

 Summary tables are a performance necessity for large tables. MariaDB and MySQL do not provide any automated way to create such, so I am providing techniques here.

 (Other vendors provide something similar with "materialized views".)

 When you have millions or billions of rows, it takes a long time to summarize the data to present counts, totals, averages, etc, in a size that is readily digestible by humans. By computing and saving subtotals as the data comes in, one can make "reports" run much faster. (I have seen 10x to 1000x speedups.) The subtotals go into a "summary table". This document guides you on efficiency in both creating and using such tables.

 General structure of a summary table
------------------------------------

 A summary table includes two sets of columns:

 * Main KEY: date + some dimension(s)
* Subtotals: COUNT(\*), SUM(...), ...; but not AVG()

 The "date" might be a DATE (a 3-byte native datatype), or an hour, or some other time interval. A 3-byte MEDIUMINT UNSIGNED 'hour' can be derived from a DATETIME or TIMESTAMP via

 
```
   FLOOR(UNIX_TIMESTAMP(dt) / 3600)
   FROM_UNIXTIME(hour * 3600)

```

The "dimensions" (a DW term) are some of the columns of the "Fact" table. Examples: Country, Make, Product, Category, Host Non-dimension examples: Sales, Quantity, TimeSpent

 There would be one or more indexes, usually starting with some dimensions and ending with the date field. By ending with the date, one can efficiently get a range of days/weeks/etc. even when each row summarizes only one day.

 There will typically be a "few" summary tables. Often one summary table can serve multiple purposes sufficiently efficiently.

 As a rule of thumb, a summary table will have one-tenth the number of rows as the Fact table. (This number is very loose.)

 Example
-------

 Let's talk about a large chain of car dealerships. The Fact table has all the sales with columns such as datetime, salesman\_id, city, price, customer\_id, make, model, model\_year. One Summary table might focus on sales:

 
```
   PRIMARY KEY(city, datetime),
   Aggregations: ct, sum_price
   
   # Core of INSERT..SELECT:
   DATE(datetime) AS date, city, COUNT(*) AS ct, SUM(price) AS sum_price
   
   # Reporting average price for last month, broken down by city:
   SELECT city,
          SUM(sum_price) / SUM(ct) AS 'AveragePrice'
      FROM SalesSummary
      WHERE datetime BETWEEN ...
      GROUP BY city;
   
   # Monthly sales, nationwide, from same summary table:
   SELECT MONTH(datetime) AS 'Month',
          SUM(ct)         AS 'TotalSalesCount'
          SUM(sum_price)  AS 'TotalDollars'
      FROM SalesSummary
      WHERE datetime BETWEEN ...
      GROUP BY MONTH(datetime);
   # This might benefit from a secondary INDEX(datetime)

```

When to augment the summary table(s)?
-------------------------------------

 "Augment" in this section means to add new rows into the summary table or increment the counts in existing rows.

 Plan A: "While inserting" rows into the Fact table, augment the summary table(s). This is simple, and workable for a smaller DW database (under 10 Fact table rows per second). For larger DW databases, Plan A likely to be too costly to be practical.

 Plan B: "Periodically", via cron or an EVENT.

 Plan C: "As needed". That is, when someone asks for a report, the code first updates the summary tables that will be needed.

 Plan D: "Hybrid" of B and C. C, by itself, can led to long delays for the report. By also doing B, those delays can be kept low.

 Plan E: (This is not advised.) "Rebuild" the entire summary table from the entire Fact table. The cost of this is prohibitive for large tables. However, Plan E may be needed when you decide to change the columns of a Summary Table, or discover a flaw in the computations. To lessen the impact of an entire build, adapt the chunking techniques in [Deleting in chunks](../big-deletes/index#deleting_in_chunks) .

 Plan F: "Staging table". This is primarily for very high speed ingestion. It is mentioned briefly in this blog, and discussed more thoroughly in the companion blog: High Speed Ingestion

 Summarizing while Inserting (one row at a time)
-----------------------------------------------

 
```
    INSERT INTO Fact ...;
    INSERT INTO Summary (..., ct, foo, ...) VALUES (..., 1, foo, ...)
        ON DUPLICATE KEY UPDATE ct = ct+1, sum_foo = sum_foo + VALUES(foo), ...;

```

IODKU (Insert On Duplicate Key Update) will update an existing row or create a new row. It knows which to do based on the Summary table's PRIMARY KEY.

 Caution: This approach is costly, and will not scale to an ingestion rate of over, say, 10 rows per second (Or maybe 50/second on SSDs). More discussion later.

 Summarizing periodically vs as-needed
-------------------------------------

 If your reports need to be up-to-the-second, you need "as needed" or "hybrid". If your reports have less urgency (eg, weekly reports that don't include 'today'), then "periodically" might be best.

 For a daily summaries, augmenting the summary tables could be done right after midnight. But, beware of data coming "late".

 For both "periodic" and "as needed", you need a definitive way of keeping track of where you "left off".

 Case 1: You insert into the Fact table first and it has an AUTO\_INCREMENT id: Grab MAX(id) as the upper bound for summarizing and put it either into some other secure place (an extra table), or put it into the row(s) in the Summary table as you insert them. (Caveat: AUTO\_INCREMENT ids do not work well in multi-master, including Galera, setups.)

 Case 2: If you are using a 'staging' table, there is no issue. (More on staging tables later.)

 Summarizing while batch inserting
---------------------------------

 This applies to multi-row (batch) INSERT and LOAD DATA.

 The Fact table needs an AUTO\_INCREMENT id, and you need to be able to find the exact range of ids inserted. (This may be impractical in any multi-master setup.)

 Then perform bulk summarization using

 
```
   FROM Fact
   WHERE id BETWEEN min_id and max_id

```

Summarizing when using a staging table
--------------------------------------

 Load the data (via INSERTs or [LOAD DATA) en masse into a "staging table". Then perform batch summarization from the Staging table. And batch copy from the Staging table to the Fact table. Note that the Staging table is handy for batching "normalization" during ingestion. See also [[data-warehousing-high-speed-ingestion|High Speed Ingestion](../load-data-infile/index)

 Summary table: PK or not?
-------------------------

 Let's say your summary table has a DATE, `dy`, and a dimension, `foo`. The question is: Should (foo, dy) be the PRIMARY KEY? Or a non-UNIQUE index?

 Case 1: PRIMARY KEY (foo, dy) and summarization is in lock step with, say, changes in `dy`.

 This case is clean and simple -- until you get to endcases. How will you handle the case of data arriving 'late'? Maybe you will need to recalculate some chunks of data? If so, how?

 Case 2: (foo, dy) is a non-UNIQUE INDEX.

 This case is clean and simple, but it can clutter the summary table because multiple rows can occur for a given (foo, dy) pair. The report will always have to [SUM()](../sum/index) up values because it cannot assume there is only one row, even when it is reporting on a single `foo` for a single `dy`. This forced-SUM is not really bad -- you should do it anyway; that way all your reports are written with one pattern.

 Case 3: PRIMARY KEY (foo, dy) and summarization can happen anytime.

 Since you should be using InnoDB, there needs to be an explicit PRIMARY KEY. One approach when you do not have a 'natural' PK is this:

 
```
   id INT UNSIGNED AUTO_INCREMENT NOT NULL,
   ...
   PRIMARY KEY(foo, dy, id),  -- `id` added to make unique
   INDEX(id)                  -- sufficient to keep AUTO_INCREMENT happy

```

This case pushes the complexity onto the summarization by doing a IODKU.

 Advice? Avoid Case 1; too messy. Case 2 is ok if the extra rows are not too common. Case 3 may be the closest to "once size fits all".

 Averages, etc.
--------------

 When summarizing, include `COUNT(*) AS ct and SUM(foo) AS sum_foo`. When reporting, the "average" is computed as SUM(sum\_foo) / SUM(ct). That is mathematically correct.

 Exception... Let's say you are looking at weather temperatures. And you monitoring station gets the temp periodically, but unreliably. That is, the number of readings for a day varies. Further, you decide that the easiest way to compensate for the inconsistency is to do something like: Compute the avg temp for each day, then average those across the month (or other timeframe).

 Formula for Standard Deviation:

 
```
    SQRT( SUM(sum_foo2)/SUM(ct) - POWER(SUM(sum_foo)/SUM(ct), 2) )

```

Where sum\_foo2 is SUM(foo \* foo) from the summary table. sum\_foo and sum\_foo2 should be FLOAT. FLOAT gives you about 7 significant digits, which is more than enough for things like average and standard deviation. FLOAT occupies 4 bytes. DOUBLE would give you more precision, but occupies 8 bytes. INT and BIGINT are not practical because they may lead to complaints about overflow.

 Staging table
-------------

 The idea here is to first load a set of Fact records into a "staging table", with the following characteristics (at least):

 * The table is repeatedly populated and truncated
* Inserts could be individual or batched, and from one or many clients
* SELECTs will be table scans, so no indexes needed
* Inserting will be fast (InnoDB may be the fastest)
* Normalization can be done in bulk, hence efficiently
* Copying to the Fact table will be fast
* Summarization can be done in bulk, hence efficiently
* "Bursty" ingestion is smoothed by this process
* Flip-flop a pair of Staging tables

 If you have bulk inserts (Batch INSERT or LOAD DATA) then consider doing the normalization and summarization immediately after each bulk insert.

 More details: High Speed Ingestion

 Extreme design
--------------

 Here is a more complex way to design the system, with the goal of even more scaling.

 * Use master-slave setup: ingest into master; report from slave(s).
* Feed ingestion through a staging table (as described above)
* Single-source of data: ENGINE=MEMORY; multiple sources: InnoDB
* [binlog\_format = ROW](../replication-and-binary-log-server-system-variables/index#binlog_format)
* Use [binlog\_ignore\_db](../replication-and-binary-log-server-system-variables/index#binlog_ignore_db) to avoid replicating staging -- necessitating putting it in a separate database.
* Do the summarization from Staging
* Load Fact via INSERT INTO Fact ... SELECT FROM Staging ...

 Explanation and comments:

 * ROW + ignore\_db avoids replicating Staging, yet replicates the INSERTs based on it. Hence, it lightens the write load on the Slaves
* If using MEMORY, remember that it is volatile -- recover from a crash by starting the ingestion over.
* To aid with debugging, TRUNCATE or re-CREATE Staging at the start of the next cycle.
* Staging needs no indexes -- all operations read all rows from it.

 Stats on the system that this 'extreme design' came from: Fact Table: 450GB, 100M rows/day (batch of 4M/hour), 60 day retention (60+24 partitions), 75B/row, 7 summary tables, under 10 minutes to ingest and summarize the hourly batch. The INSERT..SELECT handled over 20K rows/sec going into the Fact table. Spinning drives (not SSD) with RAID-10.

 "Left Off"
----------

 One technique involves summarizing some of the data, then recording where you "left off", so that next time, you can start there. There are some subtle issues with "left off" that you should be cautious of.

 If you use a DATETIME or TIMESTAMP as "left off", beware of multiple rows with the same value.

 * Plan A: Use a compound "left off" (eg, TIMESTAMP + ID). This is messy, error prone, etc.
* Plan B: WHERE ts >= $left\_off AND ts < $max\_ts -- avoids dups, but has other problems (below)
* Separate threads could COMMIT TIMESTAMPs out of order.

 If you use an AUTO\_INCREMENT as "left off" beware of:

 * In InnoDB, separate threads could COMMIT ids in the 'wrong' order.
* Multi-master (including Galera and InnoDB Cluster), could lead to ordering issues.

 So, nothing works, at least not in a multi-threaded environment?

 If you can live with an occasional hiccup (skipped record), then maybe this is 'not a problem' for you.

 The "Flip-Flop Staging" is a safe alternative, optionally combined with the "Extreme Design".

 Flip-flop staging
-----------------

 If you have many threads simultaneously INSERTing into one staging table, then here is an efficient way to handle a large load: Have a process that flips that staging table with another, identical, staging table, and performs bulk normalization, Fact insertion, and bulk summarization.

 The flipping step uses a fast, atomic, RENAME.

 Here is a sketch of the code:

 
```
    # Prep for flip:
    CREATE TABLE new LIKE Staging;

    # Swap (flip) Staging tables:
    RENAME TABLE Staging TO old, new TO Staging;

    # Normalize new `foo`s:
    # (autocommit = 1)
    INSERT IGNORE INTO Foos SELECT fpp FROM old LEFT JOIN Foos ...

    # Prep for possible deadlocks, etc
    while...
    START TRANSACTION;

    # Add to Fact:
    INSERT INTO Fact ... FROM old JOIN Foos ...

    # Summarize:
    INSERT INTO Summary ... FROM old ... GROUP BY ...

    COMMIT;
    end-while

    # Cleanup:
    DROP TABLE old;

```

Meanwhile, ingestion can continue writing to `Staging`. The ingestion INSERTs will conflict with the RENAME, but will be resolved gracefully and silently and quickly.

 How fast should you flip-flop? Probably the best scheme is to

 * Have a job that flip-flops in a tight loop (no delay, or a small delay, between iterations), and
* Have a CRON that serves only as a "keep-alive" to restart the job if it dies.

 If Staging is 'big', an iteration will take longer, but run more efficiently. Hence, it is self-regulating.

 In a [Galera](../galera/index) (or InnoDB Cluster?) environment, each node could be receiving input. If can afford to loose a few rows, have `Staging` be a non-replicated MEMORY table. Otherwise, have one `Staging` per node and be InnoDB; it will be more secure, but slower and not without problems. In particular, if a node dies completely, you somehow need to process its `Staging` table.

 Multiple summary tables
-----------------------

 * Look at the reports you will need.
* Design a summary table for each.
* Then look at the summary tables -- you are likely to find some similarities.
* Merge similar ones.

 To look at what a report needs, look at the WHERE clause that would provide the data. Some examples, assuming data about service records for automobiles: The GROUP BY to gives a clue of what the report might be about.

  1. WHERE make = ? AND model\_year = ? GROUP BY service\_date, service\_type 2. WHERE make = ? AND model = ? GROUP BY service\_date, service\_type 3. WHERE service\_type = ? GROUP BY make, model, service\_date 4. WHERE service\_date between ? and ? GROUP BY make, model, model\_year

 You need to allow for 'ad hoc' queries? Well, look at all the ad hoc queries -- they all have a date range, plus nail down one or two other things. (I rarely see something as ugly as '%CL%' for nailing down another dimension.) So, start by thinking of date plus one or two other dimensions as the 'key' into a new summary table. Then comes the question of what data might be desired -- counts, sums, etc. Eventually you have a small set of summary tables. Then build a front end to allow them to pick only from those possibilities. It should encourage use of the existing summary tables, not not be truly 'open ended'.

 Later, another 'requirement' may surface. So, build another summary table. Of course, it may take a day to initially populate it.

 Games on summary tables
-----------------------

 Does one ever need to summarize a summary table? Yes, but only in extreme situations. Usually a 'weekly' report can be derived from a 'daily' summary table; building a separate weekly summary table not being worth the effort.

 Would one ever PARTITION a Summary Table? Yes, in extreme situations, such as the table being large, and

 * Need to purge old data (unlikely), or
* Recent' data is usually requested, and the index(es) fail to prevent table scans (rare). ("Partition pruning" to the rescue.)

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/summarytables>

 Examples

 * <http://dba.stackexchange.com/a/144723/1876>
* <http://stackoverflow.com/a/39403194/1766831>
* <http://stackoverflow.com/a/40310314/1766831>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-warehousing-summary-tables/>

Data Warehousing Techniques
===========================

    Preface
-------

 This document discusses techniques for improving performance for data-warehouse-like tables in MariaDB and MySQL.

 * How to load large tables.
* [Normalization](../database-normalization/index).
* Developing 'summary tables' to make 'reports' efficient.
* Purging old data.

 Details on summary tables is covered in the companion document: [Summary Tables](../data-warehousing-summary-tables/index).

 Terminology
-----------

 This list mirrors "Data Warehouse" terminology.

 * Fact table -- The one huge table with the 'raw' data.
* Summary table -- a redundant table of summarized data that could -- use for efficiency
* Dimension -- columns that identify aspects of the dataset (region, country, user, SKU, zipcode, ...)
* Normalization table (dimension table) -- mapping between strings an ids; used for space and speed.
* Normalization -- The process of building the mapping ('New York City' <-> 123)

 Fact table
----------

 Techniques that should be applied to the huge Fact table.

 * id INT/BIGINT UNSIGNED NOT NULL AUTO\_INCREMENT
* PRIMARY KEY (id)
* Probably no other INDEXes
* Accessed only via id
* All VARCHARs are "normalized"; ids are stored instead
* ENGINE = InnoDB
* All "reports" use summary tables, not the Fact table
* Summary tables may be populated from ranges of id (other techniques described below)

 There are exceptions where the Fact table must be accessed to retrieve multiple rows. However, you should minimize the number of INDEXes on the table because they are likely to be costly on INSERT.

 Why keep the Fact table?
------------------------

 Once you have built the Summary table(s), there is not much need for the Fact table. One option that you should seriously consider is to not have a Fact table. Or, at least, you could purge old data from it sooner than you purge the Summary tables. Maybe even keep the Summary tables forever.

 Case 1: You need to find the raw data involved in some event. But how will you find those row(s)? This is where a secondary index may be required.

 If a secondary index is bigger than can be cached in RAM, and if the column(s) being indexed is random, then each row inserted may cause a disk hit to update the index. This limits insert speed to something like 100 rows per second (on ordinary disks). Multiple random indexes slow down insertion further. RAID striping and/or SSDs speed up insertion. Write caching helps, but only for bursts.

 Case 2: You need some event, but you did not plan ahead with the optimal INDEX. Well, if the data is PARTITIONed on date, so even if you have a clue of when the event occurred, "partition pruning" will keep the query from being too terribly slow.

 Case 3: Over time, the application is likely to need new 'reports', which may lead to a new Summary table. At this point, it would be handy to scan through the old data to fill up the new table.

 Case 4: You find a flaw in the summarization, and need to rebuild an existing Summary table.

 Cases 3 and 4 both need the "raw" data. But they don't necessarily need the data sitting in a database table. It could be in the pre-database format (such as log files). So, consider not building the Fact table, but simply keep the raw data, comressed, on some file system.

 Batching the load of the Fact table
-----------------------------------

 When talking about billions of rows in the Fact table, it is essentially mandatory that you "batch" the inserts. There are two main ways:

 * INSERT INTO Fact (.,.,.) VALUES (.,.,.), (.,.,.), ...; -- "Batch insert"
* LOAD DATA ...;

 A third way is to INSERT or LOAD into a Staging table, then

 * INSERT INTO Fact SELECT \* FROM Staging; This INSERT..SELECT allows you to do other things, such as normalization. More later.

 Batched INSERT Statement
------------------------

 Chunk size should usually be 100-1000 rows.

 * 100-1000 an insert will run 10 times as fast as single-row inserts.
* Beyond 100, you may be interfering replication and SELECTs.
* Beyond 1000, you are into diminishing returns -- virtually no further performance gains.
* Don't go past, say, 1MB for the constructed INSERT statement. This deals with packet sizes, etc. (1MB is unlikely to be hit for a Fact table.) Decide whether your application should lean toward the 100 or the 1000.

 If your data is coming in continually, and you are adding a batching layer, let's do some math. Compute your ingestion rate -- R rows per second.

 * If R < 10 (= 1M/day = 300M/year) -- single-row INSERTs would probably work fine (that is, batching is optional)
* If R < 100 (3B records per year) -- secondary indexes on Fact table may be ok
* If R < 1000 (100M records/day) -- avoid secondary indexes on Fact table.
* If R > 1000 -- Batching may not work. Decide how long (S seconds) you can stall loading the data in order to collect a batch of rows.
* If S < 0.1s -- May not be able to keep up

 If batching seems viable, then design the batching layer to gather for S seconds or 100-1000 rows, whichever comes first.

 (Note: Similar math applies to rapid UPDATEs of a table.)

 Normalization (Dimension) table
-------------------------------

 Normalization is important in Data Warehouse applications because it significantly cuts down on the disk footprint and improves performance. There are other reasons for normalizing, but space is the important one for DW.

 Here is a typical pattern for a Dimension table:

 
```
    CREATE TABLE Emails (
        email_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,  -- don't make bigger than needed
        email VARCHAR(...) NOT NULL,
        PRIMARY KEY (email),  -- for looking up one way
        INDEX(email_id)  -- for looking up the other way (UNIQUE is not needed)
    ) ENGINE = InnoDB;  -- to get clustering

```

Notes:

 * MEDIUMINT is 3 bytes with UNSIGNED range of 0..16M; pick SMALLINT, INT, etc, based on a conservative estimate of how many 'foo's you will eventually have.
* datatype sizes
* There may be more than one VARCHAR in the table. Example: For cities, you might have City and Country.
* InnoDB is better than MyISAM because of way the two keys are structured.
* The secondary key is effectively (email\_id, email), hence 'covering' for certain queries.
* It is OK to not specify an AUTO\_INCREMENT to be UNIQUE.

 Batched normalization
---------------------

 I bring this up as a separate topic because of some of the subtle issues that can happen.

 You may be tempted to do

 
```
    INSERT IGNORE INTO Foos
        SELECT DISTINCT foo FROM Staging;  -- not wise

```

It has the problem of "burning" AUTO\_INCREMENT ids. This is because MariaDB pre-allocates ids before getting to "IGNORE". That could rapidly increase the AUTO\_INCREMENT values beyond what you expected.

 Better is this...

 
```
    INSERT IGNORE INTO Foos
        SELECT DISTINCT foo
            FROM Staging
            LEFT JOIN Foos ON Foos.foo = Staging.foo
            WHERE Foos.foo_id IS NULL;

```

Notes:

 * The LEFT JOIN .. IS NULL finds the `foo`s that are not yet in Foos.
* This INSERT..SELECT must not be done inside the transaction with the rest of the processing. Otherwise, you add to deadlock risks, leading to burned ids.
* IGNORE is used in case you are doing the INSERT from multiple processes simultaneously.

 Once that INSERT is done, this will find all the foo\_ids it needs:

 
```
    INSERT INTO Fact (..., foo_id, ...)
        SELECT ..., Foos.foo_id, ...
            FROM Staging
            JOIN Foos ON Foos.foo = Staging.foo;

```

An advantage of "Batched Normalization" is that you can summarize directly from the Staging table. Two approaches:

 Case 1: PRIMARY KEY (dy, foo) and summarization is in lock step with, say, changes in `dy`.

 * This approach can have troubles if new data arrives after you have summarized the day's data.

 
```
    INSERT INTO Summary (dy, foo, ct, blah_total)
        SELECT  DATE(dt) as dy, foo,
                COUNT(*) as ct, SUM(blah) as blah_total)
            FROM Staging
            GROUP BY 1, 2;

```

Case 2: (dy, foo) is a non-UNIQUE INDEX.

 * Same code as Case 1.
* By having the index be non-UNIQUE, delayed data simply shows up as extra rows.
* You need to take care to avoid summarizing the data twice. (The id on the Fact table may be a good tool for that.)

 Case 3: PRIMARY KEY (dy, foo) and summarization can happen anytime.

 
```
    INSERT INTO Summary (dy, foo, ct, blah_total)
        ON DUPLICATE KEY UPDATE
            ct = ct + VALUE(ct),
            blah_total = blah_total + VALUE(bt)
        SELECT  DATE(dt) as dy, foo,
                COUNT(*) as ct, SUM(blah) as bt)
            FROM Staging
            GROUP BY 1, 2;

```

Too many choices?
-----------------

 This document lists a number of ways to do things. Your situation may lead to one approach being more/less acceptable. But, if you are thinking "Just tell me what to do!", then here:

 * Batch load the raw data into a temporary table (`Staging`).
* Normalize from `Staging` -- use code in Case 3.
* INSERT .. SELECT to move the data from `Staging` into the Fact table
* Summarize from `Staging` to Summary table(s) via IODKU (Insert ... On Duplicate Key Update).
* Drop the Staging

 Those techniques should perform well and scale well in most cases. As you develop your situation, you may discover why I described alternative solutions.

 Purging old data
----------------

 Typically the Fact table is PARTITION BY RANGE (10-60 ranges of days/weeks/etc) and needs purging (DROP PARTITION) periodically. This discusses a safe/clean way to design the partitioning and do the DROPs: Purging PARTITIONs

 Master / slave
--------------

 For "read scaling", backup, and failover, use master-slave replication or something fancier. Do ingestion only on a single active master; it replicate to the slave(s). Generate reports on the slave(s).

 Sharding
--------

 "Sharding" is the splitting of data across multiple servers. (In contrast, [replication](../replication/index) and [Galera](../galera/index) have the same data on all servers, requiring all data to be written to all servers.)

 With the non-sharding techniques described here, terabyte(s) of data can be handled by a single machine. Tens of terabytes probably requires sharding.

 Sharding is beyond the scope of this document.

 How fast? How big?
------------------

 With the techniques described here, you may be able to achieve the following performance numbers. I say "may" because every data warehouse situation is different, and you may require performance-hurting deviations from what I describe here. I give multiple options for some aspects; these may cover some of your deviations.

 One big performance killer is UUID/GUID keys. Since they are very 'random', updates of them (at scale) are limited to 1 row = 1 disk hit. Plain disks can handle only 100 hits/second. RAID and/or SSD can increase that to something like 1000 hits/sec. Huge amounts of RAM (for caching the random index) are a costly solution. It is possible to turn type-1 UUIDs into roughly-chronological keys, thereby mittigating the performance problems if the UUIDs are written/read with some chronological clustering. UUID discussion

 Hardware, etc:

 * Single SATA drive: 100 IOPs (Input/Output operations per second)
* RAID with N physical drives -- 100\*N IOPs (roughly)
* SSD -- 5 times as fast as rotating media (in this context)
* Batch INSERT -- 100-1000 rows is 10 times as fast as INSERTing 1 row at a time (see above)
* Purge "old" data -- Do not use DELETE or TRUNCATE, design so you can use DROP PARTITION (see above)
* Think of each INDEX (except the PRIMARY KEY on InnoDB) as a separate table
* Consider access patterns of each table/index: random vs at-the-end vs something in between

 "Count the disk hits" -- back-of-envelope performance analysis

 * Random accesses to a table/index -- count each as a disk hit.
* At-the-end accesses (INSERT chronologically or with AUTO\_INCREMENT; range SELECT) -- count as zero hits.
* In between (hot/popular ids, etc) -- count as something in between
* For INSERTs, do the analysis on each index; add them up.
* For SELECTs, do the analysis on the one index used, plus the table. (Use of 2 indexes is rare.) Insert cost, based on datatype of first column in an index:
* AUTO\_INCREMENT -- essentially 0 IOPs
* DATETIME, TIMESTAMP -- essentially 0 for 'current' times
* UUID/GUID -- 1 per insert (terrible)
* Others -- depends on their patterns SELECT cost gets a little tricky:
* Range on PRIMARY KEY -- think of it as getting 100 rows per disk hit.
* IN on PRIMARY KEY -- 1 disk hit per item in IN
* "=" -- 1 hit (for 1 row)
* Secondary key -- First compute the hits for the index, then...
* Think of each row as needing 1 disk hit.
* However, if the rows are likely to be 'near' each other (based on the PRIMARY KEY), then it could be < 1 disk hit/row.

 More on Count the Disk Hits

 How fast?
---------

 Look at your data; compute raw rows per second (or hour or day or year). There are about 30M seconds in a year; 86,400 seconds per day. Inserting 30 rows per second becomes a billion rows per year.

 10 rows per second is about all you can expect from an ordinary machine (after allowing for various overheads). If you have less than that, you don't have many worries, but still you should probably create Summary tables. If more than 10/sec, then batching, etc, becomes vital. Even on spiffy hardware, 100/sec is about all you can expect without utilizing the techniques here.

 Not so fast?
------------

 Let's say your insert rate is only one-tenth of your disk IOPs (eg, 10 rows/sec vs 100 IOPs). Also, let's say your data is not "bursty"; that is, the data comes in somewhat soothly throughout the day.

 Note that 10 rows/sec (300M/year) implies maybe 30GB for data + indexes + normalization tables + summary tables for 1 year. I would call this "not so big".

 Still, the [normalization](../database-normalization/index) and summarization are important. Normalization keeps the data from being, say, twice as big. Summarization speeds up the reports by orders of magnitude.

 Let's design and analyse a "simple ingestion scheme" for 10 rows/second, without 'batching'.

 
```
    # Normalize:
    $foo_id = SELECT foo_id FROM Foos WHERE foo = $foo;
    if no $foo_id, then
        INSERT IGNORE INTO Foos ...

    # Inserts:
    BEGIN;
        INSERT INTO Fact ...;
        INSERT INTO Summary ... ON DUPLICATE KEY UPDATE ...;
    COMMIT;
    # (plus code to deal with errors on INSERTs or COMMIT)

```

Depending on the number and randomness of your indexes, etc, 10 Fact rows may (or may not) take less than 100 IOPs.

 Also, note that as the data grows over time, random indexes will become less and less likely to be cached. That is, even if runs fine with 1 year's worth of data, it may be in trouble with 2 year's worth.

 For those reasons, I started this discussion with a wide margin (10 rows versus 100 IOPs).

 References
----------

 * [sec. 3.3.2: Dimensional Model and "Star schema"](http://www.redbooks.ibm.com/redbooks/pdfs/sg247138.pdf)
* Summary Tables

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/datawarehouse>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/data-warehousing-techniques/>

Equality propagation optimization
=================================

    Basic idea
----------

 Consider a query with a WHERE clause:

 
```
WHERE col1=col2 AND ...

```

the WHERE clause will compute to true only if `col1=col2`. This means that in the rest of the WHERE clause occurrences of `col1` can be substituted with `col2` (with some limitations which are discussed in the next section). This allows the optimizer to infer additional restrictions. 

 For example:

 
```
WHERE col1=col2 AND col1=123

```

allows to infer a new equality: `col2=123`

 
```
WHERE col1=col2 AND col1 < 10 

```

allows to infer that `col2<10`. 

 Identity and comparison substitution
------------------------------------

 There are some limitations to where one can do the substitution, though.

 The first and obvious example is the string datatype and collations. Most commonly-used collations in SQL are "case-insensitive", that is `'A'='a'`. Also, most collations have a "PAD SPACE" attribute, which means that comparison ignores the spaces at the end of the value, `'a'='a '`.

 Now, consider a query:

 
```
INSERT INTO t1 (col1, col2) VALUES ('ab', 'ab   ');
SELECT * FROM t1 WHERE col1=col2 AND LENGTH(col1)=2

```

Here, `col1=col2`, the values are "equal". At the same time `LENGTH(col1)=2`, while `LENGTH(col2)=4`, which means one can't perform the substiution for the argument of LENGTH(...). 

 It's not only collations. There are similar phenomena when equality compares columns of different datatypes. The exact criteria of when thy happen are rather convoluted.

 The take-away is: **sometimes, X=Y does not mean that one can replace any reference to X with Y**. What one CAN do is still replace the occurrence in the comparisons `<`, `>`, `>=`, `<=`, etc.

 This is how we get two kinds of substitution:

 * **Identity substitution**: X=Y, and any occurrence of X can be replaced with Y.
* **Comparison substitution**: X=Y, and an occurrence of X in a comparison (X<Z) can be replaced with Y (Y<Z).

 Place in query optimization
---------------------------

 (A draft description): Let's look at how Equality Propagation is integrated with the rest of the query optimization process.

 * First, multiple-equalities are built (TODO example from optimizer trace)
	+ If multiple-equality includes a constant, fields are substituted with a constant if possible.

 * From this point, all optimizations like range optimization, ref access, etc make use of multiple equalities: when they see a reference to `tableX.columnY` somewhere, they also look at all the columns that tableX.columnY is equal to.

 * After the join order is picked, the optimizer walks through the WHERE clause and substitutes each field reference with the "best" one - the one that can be checked as soon as possible.
	+ Then, the parts of the WHERE condition are attached to the tables where they can be checked.

 ### Interplay with ORDER BY optimization

 Consider a query:

 
```
SELECT ... FROM ... WHERE col1=col2 ORDER BY col2

```

Suppose, there is an `INDEX(col1)`. MariaDB optimizer is able to figure out that it can use an index on `col1` (or sort by the value of `col1`) in order to resolve `ORDER BY col2`.

 Optimizer trace
---------------

 Look at these elements:

 * `condition_processing`
* `attaching_conditions_to_tables`

 More details
------------

 Equality propagation doesn't just happen at the top of the WHERE clause. It is done "at all levels" where a level is: 

 * A top level of the WHERE clause.
* If the WHERE clause has an OR clause, each branch of the OR clause.
* The top level of any ON expression
* (the same as above about OR-levels)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/equality-propagation-optimization/>

FORCE INDEX
===========

    Description
-----------

 Forcing an index to be used is mostly useful when the optimizer decides to do a table scan even if you know that using an index would be better. (The optimizer could decide to do a table scan even if there is an available index when it believes that most or all rows will match and it can avoid the overhead of using the index).

 FORCE INDEX works by only considering the given indexes (like with USE\_INDEX) but in addition it tells the optimizer to regard a table scan as something very expensive. However if none of the 'forced' indexes can be used, then a table scan will be used anyway.

 FORCE INDEX cannot force an [ignored index](../ignored-indexes/index) to be used - it will be treated as if it doesn't exist.

 Example
-------

 
```
CREATE INDEX Name ON City (Name);
EXPLAIN SELECT Name,CountryCode FROM City FORCE INDEX (Name)
WHERE name>="A" and CountryCode >="A";

```

This produces:

 
```
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	City	range	Name	Name	35	NULL	4079	Using where

```

### Index Prefixes

 When using index hints (USE, FORCE or IGNORE INDEX), the index name value can also be an unambiguous prefix of an index name.

 See Also
--------

 * [Index Hints: How to Force Query Plans](../index-hints-how-to-force-query-plans/index) for more details
* [USE INDEX](../use-index/index)
* [IGNORE INDEX](../ignore-index/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/force-index/>

Groupwise Max in MariaDB
========================

    The problem
-----------

 You want to find the largest row in each group of rows. An example is looking for the largest city in each state. While it is easy to find the MAX(population) ... GROUP BY state, it is hard to find the name of the `city` associated with that `population`. Alas, MySQL and MariaDB do not have any syntax to provide the solution directly.

 This article is under construction, mostly for cleanup. The content is reasonably accurate during construction.

 The article presents two "good" solutions. They differ in ways that make neither of them 'perfect'; you should try both and weigh the pros and cons.

 Also, a few "bad" solutions will be presented, together with why they were rejected.

 MySQL manual gives 3 solutions; only the "Uncorrelated" one is "good", the other two are "bad".

 Sample data
-----------

 To show how the various coding attempts work, I have devised this simple task: Find the largest city in each Canadian province. Here's a sample of the source data (5493 rows):

 
```
+------------------+----------------+------------+
| province         | city           | population |
+------------------+----------------+------------+
| Saskatchewan     | Rosetown       |       2309 |
| British Columbia | Chilliwack     |      51942 |
| Nova Scotia      | Yarmouth       |       7500 |
| Alberta          | Grande Prairie |      41463 |
| Quebec           | Sorel          |      33591 |
| Ontario          | Moose Factory  |       2060 |
| Ontario          | Bracebridge    |       8238 |
| British Columbia | Nanaimo        |      84906 |
| Manitoba         | Neepawa        |       3151 |
| Alberta          | Grimshaw       |       2560 |
| Saskatchewan     | Carnduff       |        950 |
...

```

Here's the desired output (13 rows):

 
```
+---------------------------+---------------+------------+
| province                  | city          | population |
+---------------------------+---------------+------------+
| Alberta                   | Calgary       |     968475 |
| British Columbia          | Vancouver     |    1837970 |
| Manitoba                  | Winnipeg      |     632069 |
| New Brunswick             | Saint John    |      87857 |
| Newfoundland and Labrador | Corner Brook  |      18693 |
| Northwest Territories     | Yellowknife   |      15866 |
| Nova Scotia               | Halifax       |     266012 |
| Nunavut                   | Iqaluit       |       6124 |
| Ontario                   | Toronto       |    4612187 |
| Prince Edward Island      | Charlottetown |      42403 |
| Quebec                    | Montreal      |    3268513 |
| Saskatchewan              | Saskatoon     |     198957 |
| Yukon                     | Whitehorse    |      19616 |
+---------------------------+---------------+------------+

```

Duplicate max
-------------

 One thing to consider is whether you want -- or do not want -- to see multiple rows for tied winners. For the dataset being used here, that would imply that the two largest cities in a province had identical populations. For this case, a duplicate would be unlikely. But there are many groupwise-max use cases where duplictes are likely.

 The two best algorithms differ in whether they show duplicates.

 Using an uncorrelated subquery
------------------------------

 Characteristics:

 * Superior performance or medium performance
* It will show duplicates
* Needs an extra index
* Probably requires 5.6
* If all goes well, it will run in O(M) where M is the number of output rows.

 An 'uncorrelated subquery':

 
```
SELECT  c1.province, c1.city, c1.population
    FROM  Canada AS c1
    JOIN
      ( SELECT  province, MAX(population) AS population
            FROM  Canada
            GROUP BY  province
      ) AS c2 USING (province, population)
    ORDER BY c1.province;

```

But this also 'requires' an extra index: INDEX(province, population). In addition, MySQL has not always been able to use that index effectively, hence the "requires 5.6". (I am not sure of the actual version.)

 Without that extra index, you would need 5.6, which has the ability to create indexes for subqueries. This is indicated by <auto\_key0> in the EXPLAIN. Even so, the performance is worse with the auto-generated index than with the manually generated one.

 With neither the extra index, nor 5.6, this 'solution' would belong in 'The Duds' because it would run in O(N\*N) time.

 Using @variables
----------------

 Characteristics:

 * Good performance
* Does not show duplicates (picks one to show)
* Consistent O(N) run time (N = number of input rows)
* Only one scan of the data

 
```
SELECT
        province, city, population   -- The desired columns
    FROM
      ( SELECT  @prev := '' ) init
    JOIN
      ( SELECT  province != @prev AS first,  -- `province` is the 'GROUP BY'
                @prev := province,           -- The 'GROUP BY'
                province, city, population   -- Also the desired columns
            FROM  Canada           -- The table
            ORDER BY
                province,          -- The 'GROUP BY'
                population DESC    -- ASC for MIN(population), DESC for MAX
      ) x
    WHERE  first
    ORDER BY  province;     -- Whatever you like

```

For your application, change the lines with comments.

 The duds
--------

 **\* 'correlated subquery' (from MySQL doc):**

 
```
SELECT  province, city, population
    FROM  Canada AS c1
    WHERE  population =
      ( SELECT  MAX(c2.population)
            FROM  Canada AS c2
            WHERE  c2.province= c1.province
      )
    ORDER BY  province;

```

O(N\*N) (that is, terrible) performance

 **\* LEFT JOIN (from MySQL doc):**

 
```
SELECT  c1.province, c1.city, c1.population
    FROM  Canada AS c1
    LEFT JOIN  Canada AS c2 ON c2.province = c1.province
      AND  c2.population > c1.population
    WHERE  c2.province IS NULL
    ORDER BY province;

```

Medium performance (2N-3N, depending on join\_buffer\_size).

 For O(N\*N) time,... It will take one second to do a groupwise-max on a few thousand rows; a million rows could take hours.

 Top-N in each group
-------------------

 This is a variant on "groupwise-max" wherein you desire the largest (or smallest) N items in each group. Do these substitutions for your use case:

 * province --> your 'GROUP BY'
* Canada --> your table
* 3 --> how many of each group to show
* population --> your numeric field for determining "Top-N"
* city --> more field(s) you want to show
* Change the SELECT and ORDER BY if you desire
* DESC to get the 'largest'; ASC for the 'smallest'

 
```
SELECT
        province, n, city, population
    FROM
      ( SELECT  @prev := '', @n := 0 ) init
    JOIN
      ( SELECT  @n := if(province != @prev, 1, @n + 1) AS n,
                @prev := province,
                province, city, population
            FROM  Canada
            ORDER BY
                province   ASC,
                population DESC
      ) x
    WHERE  n <= 3
    ORDER BY  province, n;

```

Output:

 
```
+---------------------------+------+------------------+------------+
| province                  | n    | city             | population |
+---------------------------+------+------------------+------------+
| Alberta                   |    1 | Calgary          |     968475 |
| Alberta                   |    2 | Edmonton         |     822319 |
| Alberta                   |    3 | Red Deer         |      73595 |
| British Columbia          |    1 | Vancouver        |    1837970 |
| British Columbia          |    2 | Victoria         |     289625 |
| British Columbia          |    3 | Abbotsford       |     151685 |
| Manitoba                  |    1 | ...

```

The performance of this is O(N), actually about 3N, where N is the number of source rows.

 EXPLAIN EXTENDED gives

 
```
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
| id | select_type | table      | type   | possible_keys | key  | key_len | ref  | rows | filtered | Extra          |
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using filesort |
|  1 | PRIMARY     | <derived3> | ALL    | NULL          | NULL | NULL    | NULL | 5484 |   100.00 | Using where    |
|  3 | DERIVED     | Canada     | ALL    | NULL          | NULL | NULL    | NULL | 5484 |   100.00 | Using filesort |
|  2 | DERIVED     | NULL       | NULL   | NULL          | NULL | NULL    | NULL | NULL |     NULL | No tables used |
+----+-------------+------------+--------+---------------+------+---------+------+------+----------+----------------+

```

Explanation, shown in the same order as the EXPLAIN, but numbered chronologically: 3. Get the subquery id=2 (init) 4. Scan the the output from subquery id=3 (x) 2. Subquery id=3 -- the table scan of Canada 1. Subquery id=2 -- `init` for simply initializing the two @variables Yes, it took two sorts, though probably in RAM.

 Main Handler values:

 
```
| Handler_read_rnd           | 39    |
| Handler_read_rnd_next      | 10971 |
| Handler_write              | 5485  |  -- #rows in Canada (+1)

```

Top-n in each group, take II
----------------------------

 This variant is faster than the previous, but depends on `city` being unique across the dataset. (from openark.org)

 
```
    SELECT  province, city, population
        FROM  Canada
        JOIN
          ( SELECT  GROUP_CONCAT(top_in_province) AS top_cities
                FROM
                  ( SELECT  SUBSTRING_INDEX(
                                   GROUP_CONCAT(city ORDER BY  population DESC),
                            ',', 3) AS top_in_province
                        FROM  Canada
                        GROUP BY  province
                  ) AS x
          ) AS y
        WHERE  FIND_IN_SET(city, top_cities)
        ORDER BY  province, population DESC;

```

Output. Note how there can be more than 3 cities per province:

 
```
| Alberta                   | Calgary          |     968475 |
| Alberta                   | Edmonton         |     822319 |
| Alberta                   | Red Deer         |      73595 |
| British Columbia          | Vancouver        |    1837970 |
| British Columbia          | Victoria         |     289625 |
| British Columbia          | Abbotsford       |     151685 |
| British Columbia          | Sydney           |          0 | -- Nova Scotia's second largest is Sydney
| Manitoba                  | Winnipeg         |     632069 |

```

Main Handler values:

 
```
| Handler_read_next          | 5484  | -- table size
| Handler_read_rnd_next      | 5500  | -- table size + number of provinces
| Handler_write              | 14    | -- number of provinces (+1)

```

Top-n using MyISAM
------------------

 (This does not need your table to be MyISAM, but it does need MyISAM tmp table for its 2-column PRIMARY KEY feature.) See previous section for what changes to make for your use case.

 
```
    -- build tmp table to get numbering
    -- (Assumes auto_increment_increment = 1)
    CREATE TEMPORARY TABLE t (
        nth MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
        PRIMARY KEY(province, nth)
    ) ENGINE=MyISAM
        SELECT province, NULL AS nth, city, population
            FROM Canada
            ORDER BY population DESC;
    -- Output the biggest 3 cities in each province:
    SELECT province, nth, city, population
        FROM t
        WHERE nth <= 3
        ORDER BY province, nth;

+---------------------------+-----+------------------+------------+
| province                  | nth | city             | population |
+---------------------------+-----+------------------+------------+
| Alberta                   |   1 | Calgary          |     968475 |
| Alberta                   |   2 | Edmonton         |     822319 |
| Alberta                   |   3 | Red Deer         |      73595 |
| British Columbia          |   1 | Vancouver        |    1837970 |
| British Columbia          |   2 | Victoria         |     289625 |
| British Columbia          |   3 | Abbotsford       |     151685 |
| Manitoba                  |  ...

SELECT for CREATE:
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | Canada | ALL  | NULL          | NULL | NULL    | NULL | 5484 | Using filesort |
+----+-------------+--------+------+---------------+------+---------+------+------+----------------+
Other SELECT:
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t     | index | NULL          | PRIMARY | 104     | NULL |   22 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

```

The main handler values (total of all operations):

 
```
| Handler_read_rnd_next      | 10970 |
| Handler_write              | 5484  |  -- number of rows in Canada (write tmp table)

```

Both "Top-n" formulations probably take about the same amount of time.

 Windowing functions
-------------------

 Hot off the press from Percona Live... [MariaDB 10.2](../what-is-mariadb-102/index) has "windowing functions", which make "groupwise max" much more straightforward.

 The code:

 TBD

 Postlog
-------

 Developed an first posted, Feb, 2015; Add MyISAM approach: July, 2015; Openark's method added: Apr, 2016; Windowing: Apr 2016

 I did not include the technique(s) using GROUP\_CONCAT. They are useful in some situations with small datasets. They can be found in the references below.

 See also
--------

 * This has some of these algorithms, plus some others: [Peter Brawley's blog](http://www.artfulsoftware.com/infotree/queries.php?&bw=1179#101)
* [Jan Kneschke's blog from 2007](http://jan.kneschke.de/projects/mysql/groupwise-max)
* [StackOverflow discussion of 'Uncorrelated'](http://stackoverflow.com/questions/14770671/mysql-order-by-before-group-by)
* Other references: [Inner ORDER BY thrown away](../mariadb/group-by-trick-has-been-optimized-away/index)
* Adding a large LIMIT to a subquery may make things work. [Why ORDER BY in subquery is ignored](../mariadb/why-is-order-by-in-a-from-subquery-ignored/index)
* [StackOverflow thread](http://stackoverflow.com/questions/36485072/select-with-order-and-group-by-in-maria-dbmysql)
* [row\_number(), rank(), dense\_rank()](http://kennethxu.blogspot.com/2016/04/analytical-function-in-mysql-rownumber.html)
* [http://rpbouman.blogspot.de/2008/07/calculating-nth-percentile-in-mysql.html][Perentile blog](#)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/groupwise_max>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/groupwise-max-in-mariadb/>

GUID/UUID Performance
=====================

    The problem
-----------

 GUIDs/UUIDs (Globally/Universally Unique Identifiers) are very random. Therefore, INSERTing into an index means jumping around a lot. Once the index is too big to be cached, most INSERTs involve a disk hit. Even on a beefy system, this limits you to a few hundred INSERTs per second.

 [MariaDB's UUID function](../uuid/index).

 This blog is mostly eliminated in MySQL 8.0 with the advent of the following function: [UUID\_TO\_BIN(str, swap\_flag)](https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-to-bin).

 Why it is a problem
-------------------

 A 'standard' GUID/UUID is composed of the time, machine identification and some other stuff. The combination should be unique, even without coordination between different computers that could be generating UUIDs simultaneously.

 The top part of the GUID/UUID is the bottom part of the current time. The top part is the primary part of what would be used for placing the value in an ordered list (INDEX). This cycles in about 7.16 minutes.

 Some math... If the index is small enough to be cached in RAM, each insert into the index is CPU only, with the writes being delayed and batched. If the index is 20 times as big as can be cached, then 19 out of 20 inserts will be a cache miss. (This math applies to any "random" index.)

 Second problem
--------------

 36 characters is bulky. If you are using that as a PRIMARY KEY in InnoDB and you have secondary keys, remember that each secondary key has an implicit copy of the PK, thereby making it bulky.

 It is tempting to declare the UUID [VARCHAR(36)](../varchar/index). And, since you probably are thinking globally, so you have [CHARACTER SET](../character-sets/index) utf8 (or utf8mb4). For utf8:

 * 2 - Overhead for VAR
* 36 - chars
* 3 (or 4) bytes per character for utf8 (or utf8mb4) So, max length = 2+3\*36 = 110 (or 146) bytes. For temp tables 108 (or 144) is actually used if a [MEMORY](mariadb/memory-storage-engine) table is used.

 To compress

 * utf8 is unnecessary (ascii would do); but this is obviated by the next two steps
* Toss dashes
* [UNHEX](../unhex/index) Now it will fit in 16 bytes: [BINARY(16)](../binary/index)

 Combining the problems and crafting a solution
----------------------------------------------

 But first, a caveat. This solution only works for ["Time based" / "Version 1" UUIDs](https://en.wikipedia.org/wiki/Universally_unique_identifier) They are recognizable by the "1" at the beginning of the third clump.

 The manual's sample: 6ccd780c-baba-1026-9564-0040f4311e29 . A more current value (after a few years): 49ea2de3-17a2-11e2-8346-001eecac3efa . Notice how the 3rd part has slowly changed over time? Let's data is rearranged, thus:

 
```
      1026-baba-6ccd780c-9564-0040f4311e29
      11e2-17a2-49ea2de3-8346-001eecac3efa
      11e2-17ac-106762a5-8346-001eecac3efa -- after a few more minutes

```

Now we have a number that increases nicely over time. Multiple sources won't be quite in time order, but they will be close. The "hot" spot for inserting into an INDEX(uuid) will be rather narrow, thereby making it quite cacheable and efficient.

 If your SELECTs tend to be for "recent" uuids, then they, too, will be easily cached. If, on the other hand, your SELECTs often reach for old uuids, they will be random and not well cached. Still, improving the INSERTs will help the system overall.

 Code to do it
-------------

 Let's make [Stored Functions](../stored-functions/index) to do the messy work of the two actions:

 * Rearrange fields
* Convert to/from BINARY(16)

 
```
    DELIMITER //

    CREATE FUNCTION UuidToBin(_uuid BINARY(36))
        RETURNS BINARY(16)
        LANGUAGE SQL  DETERMINISTIC  CONTAINS SQL  SQL SECURITY INVOKER
    RETURN
        UNHEX(CONCAT(
            SUBSTR(_uuid, 15, 4),
            SUBSTR(_uuid, 10, 4),
            SUBSTR(_uuid,  1, 8),
            SUBSTR(_uuid, 20, 4),
            SUBSTR(_uuid, 25) ));
    //
    CREATE FUNCTION UuidFromBin(_bin BINARY(16))
        RETURNS BINARY(36)
        LANGUAGE SQL  DETERMINISTIC  CONTAINS SQL  SQL SECURITY INVOKER
    RETURN
        LCASE(CONCAT_WS('-',
            HEX(SUBSTR(_bin,  5, 4)),
            HEX(SUBSTR(_bin,  3, 2)),
            HEX(SUBSTR(_bin,  1, 2)),
            HEX(SUBSTR(_bin,  9, 2)),
            HEX(SUBSTR(_bin, 11))
                 ));

    //
    DELIMITER ;

```

Then you would do things like

 
```
    -- Letting MySQL create the UUID:
    INSERT INTO t (uuid, ...) VALUES (UuidToBin(UUID()), ...);

    -- Creating the UUID elsewhere:
    INSERT INTO t (uuid, ...) VALUES (UuidToBin(?), ...);

    -- Retrieving (point query using uuid):
    SELECT ... FROM t WHERE uuid = UuidToBin(?);

    -- Retrieving (other):
    SELECT UuidFromBin(uuid), ... FROM t ...;

```

Do not flip the WHERE; this will be inefficent because it won't use INDEX(uuid):

 
```
    WHERE UuidFromBin(uuid) = '1026-baba-6ccd780c-9564-0040f4311e29' -- NO

```

TokuDB
------

 
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

  [TokuDB](../tokudb/index) is a viable engine if you must have UUIDs (even non-type-1) in a huge table. TokuDB is available in MariaDB as a 'standard' engine, making the barrier to entry very low. There are a small number of differences between [InnoDB](../innodb/index) and TokuDB; I will not go into them here.

 Tokudb, with its “fractal” indexing strategy builds the indexes in stages. In contrast, InnoDB inserts index entries “immediately” — actually that indexing is buffered by most of the size of the buffer\_pool. To elaborate…

 When adding a record to an InnoDB table, here are (roughly) the steps performed to write the data (and PK) and secondary indexes to disk. (I leave out logging, provision for rollback, etc.) First the PRIMARY KEY and data:

 * Check for UNIQUEness constraints
* Fetch the BTree block (normally 16KB) that should contain the row (based on the PRIMARY KEY).
* Insert the row (overflow typically occurs 1% of the time; this leads to a block split).
* Leave the page “dirty” in the buffer\_pool, hoping that more rows are added before it is bumped out of cache (buffer\_pool).. Note that for AUTO\_INCREMENT and TIMESTAMP-based PKs, the “last” block in the data will be updated repeatedly before splitting; hence, this delayed write adds greatly to the efficiency. OTOH, a UUID will be very random; when the table is big enough, the block will almost always be flushed before a second insert occurs in that block. <– This is the inefficiency in UUIDs. Now for any secondary keys:
* All the steps are the same, since an index is essentially a "table" except that the "data" is a copy of the PRIMARY KEY.
* UNIQUEness must be checked immediately — cannot delay the read.
* There are (I think) some other "delays" that avoid some I/O.

 Tokudb, on the other hand, does something like

 * Write data/index partially sorted records to disk before finding out exactly where it belongs.
* In the background, combine these partially digested blocks. Repeat as needed.
* Eventually move the info into the real table/indexes.

 If you are familiar with how sort-merge works, consider the parallels to Tokudb. Each "sort" does some work of ordering things; each "merge" is quite efficient.

 To summarize:

 * In the extreme (data/index much larger than buffer\_pool), InnoDB must read-modify-write one 16KB disk block for each UUID entry.
* Tokudb makes each I/O "count" by merging several UUIDs for each disk block. (Yeah, Toku rereads blocks, but it comes out ahead in the long run.)
* Tokudb excels when the table is really big, which implies high ingestion rate.

 Wrapup
------

 This shows three thing for speeding up usage of GUIDs/UUIDs:

 * Shrink footprint (Smaller -> more cacheable -> faster).
* Rearrange uuid to make a "hot spot" to improve cachability.
* Use TokuDB (MyRocks shares some architectural traits which may also be beneficial in handling UUIDs, but this is hypothetical and hasn't been tested)

 Note that the benefit of the "hot spot" is only partial:

 * Chronologically ordered (or approximately ordered) INSERTs benefit; random ones don't.
* SELECTs/UPDATEs by "recent" uuids benefit; old ones don't benefit.

 Postlog
-------

 Thanks to Trey for some of the ideas here.

 The tips in this document apply to MySQL, MariaDB, and Percona.

 Written Oct, 2012. Added TokuDB, Jan, 2015. 

 See Also
--------

 * [UUID data type](../uuid-data-type/index)
* [Detailed discussion of UUID indexing](http://stackoverflow.com/questions/28084901/how-does-mysql-determine-if-an-insert-is-unique/28547410#28547410)
* [Graphical display of the random nature of UUID on PRIMARY KEY](http://www.percona.com/blog/2015/04/03/illustrating-primary-key-models-in-innodb-and-their-impact-on-disk-usage/)
* [Benchmarks, etc, by Karthik Appigatla](https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/)
* [More details on the clock](https://www.famkruithof.net/guid-uuid-timebased.html)
* [Percona benchmarks](https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/)
* [NHibernate can generate sequential GUIDs](http://nhibernate.info/blog/2009/05/21/using-the-guid-comb-identifier-strategy.html) , but it seems to be backwards.

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/uuid>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/guiduuid-performance/>

IGNORE INDEX
============

    Syntax
------

 
```
IGNORE INDEX [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

```
 Description
-----------

 You can tell the optimizer to not consider a particular index with the IGNORE INDEX option.

 The benefit of using IGNORE\_INDEX instead of [USE\_INDEX](../use-index/index) is that it will not disable a new index which you may add later.

 Also see [Ignored Indexes](../ignored-indexes/index) for an option to specify in the index definition that indexes should be ignored.

 ### Index Prefixes

 When using index hints (USE, FORCE or IGNORE INDEX), the index name value can also be an unambiguous prefix of an index name.

 Example
-------

 This is used after the table name in the FROM clause:

 
```
CREATE INDEX Name ON City (Name);
CREATE INDEX CountryCode ON City (Countrycode);
EXPLAIN SELECT Name FROM City IGNORE INDEX (Name)
WHERE name="Helsingborg" AND countrycode="SWE";

```

This produces:

 
```
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	City	ref	CountryCode	CountryCode	3	const	14	Using where

```

See Also
--------

 * See [Index Hints: How to Force Query Plans](../index-hints-how-to-force-query-plans/index) for more details
* [USE INDEX](../use-index/index)
* [FORCE INDEX](../force-index/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ignore-index/>

Optimizing for "Latest News"-style Queries
==========================================

    The problem space
-----------------

 Let's say you have "news articles" (rows in a table) and want a web page showing the latest ten articles about a particular topic.

 Variants on "topic":

 * Category
* Tag
* Provider (of news article)
* Manufacturer (of item for sale)
* Ticker (financial stock)

 Variants on "news article"

 * Item for sale
* Blog comment
* Blog thread

 Variants on "latest"

 * Publication date (unix\_timestamp)
* Most popular (keep the count)
* Most emailed (keep the count)
* Manual ranking (1..10 -- 'top ten')

 Variants on "10" - there is nothing sacred about "10" in this discussion.

 The performance issues
----------------------

 Currently you have a table (or a column) that relates the topic to the article. The SELECT statement to find the latest 10 articles has grown in complexity, and performance is poor. You have focused on what index to add, but nothing seems to work.

 * If there are multiple topics for each article, you need a many-to-many table.
* You have a flag "is\_deleted" that needs filtering on.
* You want to "paginate" the list (ten articles per page, for as many pages as necessary).

 The solution
------------

 First, let me give you the solution, then I will elaborate on why it works well.

 * One new table called, say, Lists.
* Lists has \_exactly\_ 3 columns: topic, article\_id, sequence
* Lists has \_exactly\_ 2 indexes: PRIMARY KEY(topic, sequence, article\_id), INDEX(article\_id)
* Only viewable articles are in Lists. (This avoids the filtering on "is\_deleted", etc)
* Lists is [InnoDB](../innodb/index). (This gets "clustering".)
* "sequence" is typically the date of the article, but could be some other ordering.
* "topic" should probably be normalized, but that is not critical to this discussion.
* "article\_id" is a link to the bulky row in another table(s) that provide all the details about the article.

 The queries
-----------

 Find the latest 10 articles for a topic:

 
```
SELECT  a.*
    FROM  Articles a
    JOIN  Lists s ON s.article_id = a.article_id
    WHERE  s.topic = ?
    ORDER BY  s.sequence DESC
    LIMIT  10;

```

You must *not* have any WHERE condition touching columns in Articles.

 When you mark an article for deletion; you *must* remove it from Lists:

 
```
DELETE  FROM  Lists
    WHERE  article_id = ?;

```

I emphasize "must" because flags and other filtering is often the root of performance issues.

 Why it works
------------

 By now, you may have discovered why it works.

 The big goal is to minimize the disk hits. Let's itemize how few disk hits are needed. When finding the latest articles with 'normal' code, you will probably find that it is doing significant scans of the Articles table, failing to quickly home in on the 10 rows you want. With this design, there is only one extra disk hit:

 * 1 disk hit: 10 adjacent, narrow, rows in Lists -- probably in a single "block".
* 10 disk hits: The 10 articles. (These hits are unavoidable, but may be cached.) The PRIMARY KEY, and using InnoDB, makes these quite efficient.

 OK, you pay for this by removing things that you should avoid.

 * 1 disk hit: INDEX(article\_id) - finding a few ids
* A few more disk hits to DELETE rows from Lists. This is a small price to pay -- and you are not paying it while the user is waiting for the page to render.

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/lists>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-for-latest-news-style-queries/>

Pagination Optimization
=======================

    The Desire
----------

 You have a website with news articles, or a blog, or some other thing with a list of things that might be too long for a single page. So, you decide to break it into chunks of, say, 10 items and provide a [Next] button to go the next "page".

 You spot [OFFSET and LIMIT](../limit/index) in MariaDB and decide that is the obvious way to do it.

 
```
    SELECT  *
        FROM  items
        WHERE  messy_filtering
        ORDER BY  date DESC
        OFFSET  $M  LIMIT $N

```

Note that the problem requirement needs a [Next] link on each page so that the user can 'page' through the data. He does not really need "GoTo Page #". Jump to the [First] or [Last] page may be useful.

 The Problem
-----------

 All is well -- until you have 50,000 items in a list. And someone tries to walk through all 5000 pages. That 'someone' could be a search engine crawler.

 Where's the problem? Performance. Your web page is doing "SELECT ... OFFSET 49990 LIMIT 10" (or the equivalent "LIMIT 49990,10"). MariaDB has to find all 50,000 rows, step over the first 49,990, then deliver the 10 for that distant page.

 If it is a crawler ('spider') that read all the pages, then it actually touched about 125,000,000 items to read all 5,000 pages.

 Reading the entire table, just to get a distant page, can be so much I/O that it can cause timeouts on the web page. Or it can interfere with other activity, causing other things to be slow.

 Other Bugs
----------

 In addition to a performance problem, ...

 * If an item is inserted or deleted between the time you look at one page and the next, you could miss an item, or see an item duplicated.
* The pages are not easily bookmarked or sent to someone else because the contents shift over time.
* The WHERE clause and the [ORDER BY](../order-by/index) may even make it so that all 50,000 items have to be read, just to find the 10 items for page 1!

 What to Do?
-----------

 Hardware? No, that's just a bandaid. The data will continue to grow and even the new hardware won't handle it.

 Better INDEX? No. You must get away from reading the entire table to get the 5000th page.

 Build another table saying where the pages start? Get real! That would be a maintenance nightmare, and expensive.

 Bottom line: Don't use OFFSET; instead remember where you "left off".

 
```
First page (latest 10 items):
    SELECT ... WHERE ... ORDER BY id DESC LIMIT 10
Next page (second 10):
    SELECT ... WHERE ... AND id < $left_off ORDER BY id DESC LIMIT 10

```

With INDEX(id), this suddenly becomes very efficient.

 Implementation -- Getting Rid of OFFSET
---------------------------------------

 You are probably doing this now: [ORDER BY](../order-by/index) datetime DESC LIMIT 49990,10 You probably have some unique id on the table. This can probably be used for "left off".

 Currently, the [Next] button probably has a url something like ?topic=xyz&page=4999&limit=10 The 'topic' (or 'tag' or 'provider' or 'user' or etc) says which set of items are being displayed. The product of page\*limit gives the OFFSET. (The "limit=10" might be in the url, or might be hard-coded; this choice is not relevant to this discussion.)

 The new variant would be ?topic=xyz&id=12345&limit=10. (Note: the 12345 is not computable from 4999.) By using INDEX(topic, id) you can efficiently say

 
```
    WHERE topic = 'xyz'
      AND id >= 1234
    ORDER BY id
    LIMIT 10

```

That will hit only 10 rows. This is a huge improvement for later pages. Now for more details.

 Implementation -- "Left Off"
----------------------------

 What if there are exactly 10 rows left when you display the current page? It would make the UI nice if you grayed out the [Next] button, wouldn't it. (Or you could suppress the button all together.)

 How to do that? Instead of LIMIT 10, use LIMIT 11. That will give you the 10 items needed for the current page, plus an indication of whether there is another page. And the id for that page.

 So, take the 11th id for the [Next] button: <a href=?topic=xyz&id=$id11&limit=10>Next</a>

 Implementation -- Links Beyond [Next]
-------------------------------------

 Let's extend the 11 trick to also find the next 5 pages and build links for them.

 Plan A is to say LIMIT 51. If you are on page 12, that would give you links for pages 13 (using 11th id) through pages 17 (51st).

 Plan B is to do two queries, one to get the 10 items for the current page, the other to get the next 41 ids (LIMIT 10, 41) for the next 5 pages.

 Which plan to pick? It depends on many things, so benchmark.

 A Reasonable Set of Links
-------------------------

 Reaching forward and backward by 5 pages is not too much work. It would take two separate queries to find the ids in both directions. Also, having links that take you to the First and Last pages would be easy to do. No id is needed; they can be something like

 
```
    <a href=?topic=xyz&id=FIRST&limit=10>First</a>
    <a href=?topic=xyz&id=LAST&limit=10>Last</a>

```

The UI would recognize those, then generate a SELECT with something like

 
```
    WHERE topic = 'xyz'
    ORDER BY id ASC -- ASC for First; DESC for Last
    LIMIT 10

```

The last items would be delivered in reverse order. Either deal with that in the UI, or make the SELECT more complex:

 
```
    ( SELECT ...
        WHERE topic = 'xyz'
        ORDER BY id DESC
        LIMIT 10
    ) ORDER BY id ASC

```

Let's say you are on page 12 of lots of pages. It could show these links:

 
```
    [First] ... [7] [8] [9] [10] [11] 12 [13] [14] [15] [16] [17] ... [Last]

```

where the ellipsis is really used. Some end cases:

 
```
Page one of three:
    First [2] [3]
Page one of many:
    First [2] [3] [4] [5] ... [Last]
Page two of many:
    [First] 2 [3] [4] [5] ... [Last]
If you jump to the Last page, you don't know what page number it is.
So, the best you can do is perhaps:
    [First] ... [Prev] Last

```

Why it Works
------------

 The goal is to touch only the relevant rows, not all the rows leading up to the desired rows. This is nicely achieved, except for building links to the "next 5 pages". That may (or may not) be efficiently resolved by the simple SELECT id, discussed above. The reason that may not be efficient deals with the WHERE clause.

 Let's discuss the optimal and suboptimal indexes.

 For this discussion, I am assuming

 * The datetime field might have duplicates -- this can cause troubles
* The id field is unique
* The id field is close enough to datetime-ordered to be used instead of datetime.

 Very efficient -- it does all the work in the index:

 
```
    INDEX(topic, id)
    WHERE topic = 'xyz'
      AND id >= 876
    ORDER BY id ASC
    LIMIT 10,41
<</code??
That will hit 51 consecutive index entries, 0 data rows.

Inefficient -- it must reach into the data:
<<code>>
    INDEX(topic, id)
    WHERE topic = 'xyz'
      AND id >= 876
      AND is_deleted = 0
    ORDER BY id ASC
    LIMIT 10,41

```

That will hit at least 51 consecutive index entries, plus at least 51 \_randomly\_ located data rows.

 Efficient -- back to the previous degree of efficiency:

 
```
    INDEX(topic, is_deleted, id)
    WHERE topic = 'xyz'
      AND id >= 876
      AND is_deleted = 0
    ORDER BY id ASC
    LIMIT 10,41

```

Note how all the '=' parts of the WHERE come first; then comes both the '>=' and 'ORDER BY', both on id. This means that the INDEX can be used for all the WHERE, plus the ORDER BY.

 "Items 11-20 Out of 12345"
--------------------------

 You lose the "out of" except when the count is small. Instead, say something like

 
```
    Items 11-20 out of Many

```

Alternatively... Only a few searches will have too many items to count. Keep another table with the search criteria and a count. This count can be computed daily (or hourly) by some background script. When discovering that the topic is a busy one, look it up in the table to get

 
```
    Items 11-20 out of about 49,000

```

The background script would round the count off.

 The quick way to get an \_estimated\_ number of rows for an InnoDB table is

 
```
    SELECT  table_rows
        FROM  information_schema.TABLES
        WHERE  TABLE_SCHEMA = 'database_name'
          AND  TABLE_NAME = 'table_name'

```

However, it does not allow for the WHERE clause that you probably have.

 Complex WHERE, or JOIN
----------------------

 If the search criteria cannot be confined to an INDEX in a single table, this technique is doomed. I have another paper that discusses "Lists", which solves that (which extra development work), and even improves on what is discussed here.

 How Much Faster?
----------------

 This depends on

 * How many rows (total)
* Whether the WHERE clause prevented the efficient use of the ORDER BY
* Whether the data is bigger than the cache. This last one kicks in when building one page requires reading more data from disk can be cached. At that point, the problem goes from being CPU-bound to being I/O-bound. This is likely to suddenly slow down the loading of a pages by a factor of 10.

 What is Lost
------------

 * Cannot "jump to Page N", for an arbitrary N. Why do you want to do that?
* Walking backward from the end does not know the page numbers.
* The code is more complex.

 Postlog
-------

 Designed about 2007; posted 2012.

 See Also
--------

 * [A forum discussion](http://stackoverflow.com/questions/31533414/filtering-large-db-record-grouped-by-a-column)
* [Luke calls it "seek method" or "keyset pagination"](http://use-the-index-luke.com/no-offset)
* [More by Luke](http://use-the-index-luke.com/sql/partial-results/fetch-next-page)

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

 Original source: <http://mysql.rjweb.org/doc.php/pagination>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pagination-optimization/>

Pivoting in MariaDB
===================

    The problem
-----------

 You want to "pivot" the data so that a linear list of values with two keys becomes a spreadsheet-like array. See examples, below.

 A solution
----------

 The best solution is probably to do it in some form of client code (PHP, etc). MySQL and MariaDB do not have a syntax for SELECT that will do the work for you. The code provided here uses a [stored procedure](../stored-procedures/index) to generate code to pivot the data, and then runs the code.

 You can edit the SQL generated by the stored procedure to tweak the output in a variety of ways. Or you can tweak the stored procedure to generate what you would prefer.

 Reference code for solution
---------------------------

 'Source' this into the mysql commandline tool:

 
```
DELIMITER //
DROP   PROCEDURE IF EXISTS Pivot //
CREATE PROCEDURE Pivot(
    IN tbl_name VARCHAR(99),       -- table name (or db.tbl)
    IN base_cols VARCHAR(99),      -- column(s) on the left, separated by commas
    IN pivot_col VARCHAR(64),      -- name of column to put across the top
    IN tally_col VARCHAR(64),      -- name of column to SUM up
    IN where_clause VARCHAR(99),   -- empty string or "WHERE ..."
    IN order_by VARCHAR(99)        -- empty string or "ORDER BY ..."; usually the base_cols
    )
    DETERMINISTIC
    SQL SECURITY INVOKER
BEGIN
    -- Find the distinct values
    -- Build the SUM()s
    SET @subq = CONCAT('SELECT DISTINCT ', pivot_col, ' AS val ',
                    ' FROM ', tbl_name, ' ', where_clause, ' ORDER BY 1');
    -- select @subq;

    SET @cc1 = "CONCAT('SUM(IF(&p = ', &v, ', &t, 0)) AS ', &v)";
    SET @cc2 = REPLACE(@cc1, '&p', pivot_col);
    SET @cc3 = REPLACE(@cc2, '&t', tally_col);
    -- select @cc2, @cc3;
    SET @qval = CONCAT("'\"', val, '\"'");
    -- select @qval;
    SET @cc4 = REPLACE(@cc3, '&v', @qval);
    -- select @cc4;

    SET SESSION group_concat_max_len = 10000;   -- just in case
    SET @stmt = CONCAT(
            'SELECT  GROUP_CONCAT(', @cc4, ' SEPARATOR ",\n")  INTO @sums',
            ' FROM ( ', @subq, ' ) AS top');
     select @stmt;
    PREPARE _sql FROM @stmt;
    EXECUTE _sql;                      -- Intermediate step: build SQL for columns
    DEALLOCATE PREPARE _sql;
    -- Construct the query and perform it
    SET @stmt2 = CONCAT(
            'SELECT ',
                base_cols, ',\n',
                @sums,
                ',\n SUM(', tally_col, ') AS Total'
            '\n FROM ', tbl_name, ' ',
            where_clause,
            ' GROUP BY ', base_cols,
            '\n WITH ROLLUP',
            '\n', order_by
        );
    select @stmt2;                    -- The statement that generates the result
    PREPARE _sql FROM @stmt2;
    EXECUTE _sql;                     -- The resulting pivot table ouput
    DEALLOCATE PREPARE _sql;
    -- For debugging / tweaking, SELECT the various @variables after CALLing.
END;
//
DELIMITER ;

```

Then do a CALL, like in the examples, below.

 Variants
--------

 I thought about having several extra options for variations, but decided that would be too messy. Instead, here are instructions for implementing the variations, either by capturing the SELECT that was output by the Stored Procedure, or by modifying the SP, itself.

 * The data is strings (not numeric) -- Remove "SUM" (but keep the expression); remove the SUM...AS TOTAL line.
* If you want blank output instead of 0 -- Currently the code says "SUM(IF(... 0))"; change the 0 to NULL, then wrap the SUM: IFNULL(SUM(...), ''). Note that this will distinguish between a zero total (showing '0') and no data (blank).
* Fancier output -- Use PHP/VB/Java/etc.
* No Totals at the bottom -- Remove the WITH ROLLUP line from the SELECT.
* No Total for each row -- Remove the SUM...AS Total line from the SELECT.
* Change the order of the columns -- Modify the ORDER BY 1 ('1' meaning first column) in the SELECT DISTINCT in the SP.
* Example: ORDER BY FIND\_IN\_SET(DAYOFWEEK(...), 'Sun,Mon,Tue,Wed,Thu,Fri,Sat')

 Notes about "base\_cols":

 * Multiple columns on the left, such as an ID and its meaning -- This is already handled by allowing base\_cols to be a commalist like 'id, meaning'
* You cannot call the SP with "foo AS 'blah'" in hopes of changing the labels, but you could edit the SELECT to achieve that goal.

 Notes about the "Totals":

 * If "base\_cols" is more than one column, WITH ROLLUP will be subtotals as well as a grand total.
* NULL shows up in the Totals row in the "base\_cols" column; this can be changed via something like IFNULL(..., 'Totals').

 Example 1 - Population vs Latitude in US

 
```
-- Sample input:
+-------+----------------------+---------+------------+
| state | city                 | lat     | population |
+-------+----------------------+---------+------------+
| AK    | Anchorage            | 61.2181 |     276263 |
| AK    | Juneau               | 58.3019 |      31796 |
| WA    | Monroe               | 47.8556 |      15554 |
| WA    | Spanaway             | 47.1042 |      25045 |
| PR    | Arecibo              | 18.4744 |      49189 |
| MT    | Kalispell            | 48.1958 |      18018 |
| AL    | Anniston             | 33.6597 |      23423 |
| AL    | Scottsboro           | 34.6722 |      14737 |
| HI    | Kaneohe              | 21.4181 |      35424 |
| PR    | Candelaria           | 18.4061 |      17632 |
...

-- Call the Stored Procedure:
CALL Pivot('World.US', 'state', '5*FLOOR(lat/5)', 'population', '', '');

-- SQL generated by the SP:
SELECT state,
SUM(IF(5*FLOOR(lat/5) = "15", population, 0)) AS "15",
SUM(IF(5*FLOOR(lat/5) = "20", population, 0)) AS "20",
SUM(IF(5*FLOOR(lat/5) = "25", population, 0)) AS "25",
SUM(IF(5*FLOOR(lat/5) = "30", population, 0)) AS "30",
SUM(IF(5*FLOOR(lat/5) = "35", population, 0)) AS "35",
SUM(IF(5*FLOOR(lat/5) = "40", population, 0)) AS "40",
SUM(IF(5*FLOOR(lat/5) = "45", population, 0)) AS "45",
SUM(IF(5*FLOOR(lat/5) = "55", population, 0)) AS "55",
SUM(IF(5*FLOOR(lat/5) = "60", population, 0)) AS "60",
SUM(IF(5*FLOOR(lat/5) = "70", population, 0)) AS "70",
 SUM(population) AS Total
 FROM World.US  GROUP BY state
 WITH ROLLUP

-- Output from that SQL (also comes out of the SP):
+-------+---------+--------+----------+----------+----------+----------+---------+-------+--------+------+-----------+
| state | 15      | 20     | 25       | 30       | 35       | 40       | 45      | 55    | 60     | 70   | Total     |
+-------+---------+--------+----------+----------+----------+----------+---------+-------+--------+------+-----------+
| AK    |       0 |      0 |        0 |        0 |        0 |        0 |       0 | 60607 | 360765 | 4336 |    425708 |
| AL    |       0 |      0 |        0 |  1995225 |        0 |        0 |       0 |     0 |      0 |    0 |   1995225 |
| AR    |       0 |      0 |        0 |   595537 |   617361 |        0 |       0 |     0 |      0 |    0 |   1212898 |
| AZ    |       0 |      0 |        0 |  4708346 |   129989 |        0 |       0 |     0 |      0 |    0 |   4838335 |
...
| FL    |       0 |  34706 |  9096223 |  1440916 |        0 |        0 |       0 |     0 |      0 |    0 |  10571845 |
| GA    |       0 |      0 |        0 |  2823939 |        0 |        0 |       0 |     0 |      0 |    0 |   2823939 |
| HI    |   43050 | 752983 |        0 |        0 |        0 |        0 |       0 |     0 |      0 |    0 |    796033 |
...
| WY    |       0 |      0 |        0 |        0 |        0 |   277480 |       0 |     0 |      0 |    0 |    277480 |
| NULL  | 1792991 | 787689 | 16227033 | 44213344 | 47460670 | 61110822 | 7105143 | 60607 | 360765 | 4336 | 179123400 |
+-------+---------+--------+----------+----------+----------+----------+---------+-------+--------+------+-----------+

```

Notice how Alaska (AK) has populations in high latitudes and Hawaii (HI) in low latitudes.

 Example 2 - Home Solar Power Generation

 This give the power (KWh) generated by hour and month for 2012.

 
```
-- Sample input:
+---------------------+------+
| ts                  | enwh |
+---------------------+------+
| 2012-06-06 11:00:00 |  523 |
| 2012-06-06 11:05:00 |  526 |
| 2012-06-06 11:10:00 |  529 |
| 2012-06-06 11:15:00 |  533 |
| 2012-06-06 11:20:00 |  537 |
| 2012-06-06 11:25:00 |  540 |
| 2012-06-06 11:30:00 |  542 |
| 2012-06-06 11:35:00 |  543 |
Note that it is a reading in watts for each 5 minutes.
So, summing is needed to get the breakdown by month and hour.

-- Invoke the SP:
CALL Pivot('details',    -- Table
           'MONTH(ts)',  -- `base_cols`, to put on left; SUM up over the month
           'HOUR(ts)',   -- `pivot_col` to put across the top; SUM up entries across the hour
           'enwh/1000',  -- The data -- watts converted to KWh
           "WHERE ts >= '2012-01-01' AND ts < '2012-01-01' + INTERVAL 1 year",  -- Limit to one year
           '');          -- assumes that the months stay in order

-- The SQL generated:
SELECT MONTH(ts),
SUM(IF(HOUR(ts) = "5", enwh/1000, 0)) AS "5",
SUM(IF(HOUR(ts) = "6", enwh/1000, 0)) AS "6",
SUM(IF(HOUR(ts) = "7", enwh/1000, 0)) AS "7",
SUM(IF(HOUR(ts) = "8", enwh/1000, 0)) AS "8",
SUM(IF(HOUR(ts) = "9", enwh/1000, 0)) AS "9",
SUM(IF(HOUR(ts) = "10", enwh/1000, 0)) AS "10",
SUM(IF(HOUR(ts) = "11", enwh/1000, 0)) AS "11",
SUM(IF(HOUR(ts) = "12", enwh/1000, 0)) AS "12",
SUM(IF(HOUR(ts) = "13", enwh/1000, 0)) AS "13",
SUM(IF(HOUR(ts) = "14", enwh/1000, 0)) AS "14",
SUM(IF(HOUR(ts) = "15", enwh/1000, 0)) AS "15",
SUM(IF(HOUR(ts) = "16", enwh/1000, 0)) AS "16",
SUM(IF(HOUR(ts) = "17", enwh/1000, 0)) AS "17",
SUM(IF(HOUR(ts) = "18", enwh/1000, 0)) AS "18",
SUM(IF(HOUR(ts) = "19", enwh/1000, 0)) AS "19",
SUM(IF(HOUR(ts) = "20", enwh/1000, 0)) AS "20",
 SUM(enwh/1000) AS Total
 FROM details WHERE ts >= '2012-01-01' AND ts < '2012-01-01' + INTERVAL 1 year GROUP BY MONTH(ts)
 WITH ROLLUP

-- That generated decimal places that I did like:
| MONTH(ts) | 5      | 6       | 7        | 8        | 9         | 10        | 11        | 12        | 13        | 14
     | 15        | 16       | 17       | 18       | 19      | 20     | Total      |
+-----------+--------+---------+----------+----------+-----------+-----------+-----------+-----------+-----------+------
-----+-----------+----------+----------+----------+---------+--------+------------+
|         1 | 0.0000 |  0.0000 |   1.8510 |  21.1620 |   52.3190 |   73.0420 |   89.3220 |   97.0190 |   88.9720 |   75.
4970 |   50.9270 |  12.5130 |   0.5990 |   0.0000 |  0.0000 | 0.0000 |   563.2230 |
|         2 | 0.0000 |  0.0460 |   5.9560 |  35.6330 |   72.4710 |   96.5130 |  112.7770 |  126.0850 |  117.1540 |   96.
7160 |   72.5900 |  33.6230 |   4.7650 |   0.0040 |  0.0000 | 0.0000 |   774.3330 |

```

Other variations made the math go wrong. (Note that there is no CAST to FLOAT.)

 While I was at it, I gave an alias to change "MONTH(ts)" to just "Month".

 So, I edited the SQL to this and ran it:

 
```
SELECT MONTH(ts) AS 'Month',
ROUND(SUM(IF(HOUR(ts) = "5", enwh, 0))/1000) AS "5",
...
ROUND(SUM(IF(HOUR(ts) = "20", enwh, 0))/1000) AS "20",
 ROUND(SUM(enwh)/1000) AS Total
 FROM details WHERE ts >= '2012-01-01' AND ts < '2012-01-01' + INTERVAL 1 year
 GROUP BY MONTH(ts)
 WITH ROLLUP;

```

-- Which gave cleaner output:

 
```
+-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------+
| Month | 5    | 6    | 7    | 8    | 9    | 10   | 11   | 12   | 13   | 14   | 15   | 16   | 17   | 18   | 19   | 20   | Total |
+-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------+
|     1 |    0 |    0 |    2 |   21 |   52 |   73 |   89 |   97 |   89 |   75 |   51 |   13 |    1 |    0 |    0 |    0 |   563 |
|     2 |    0 |    0 |    6 |   36 |   72 |   97 |  113 |  126 |  117 |   97 |   73 |   34 |    5 |    0 |    0 |    0 |   774 |
|     3 |    0 |    0 |    9 |   46 |   75 |  105 |  121 |  122 |  128 |  126 |  105 |   71 |   33 |   10 |    0 |    0 |   952 |
|     4 |    0 |    1 |   14 |   63 |  111 |  146 |  171 |  179 |  177 |  158 |  141 |  105 |   65 |   26 |    3 |    0 |  1360 |
|     5 |    0 |    4 |   21 |   78 |  128 |  162 |  185 |  199 |  196 |  187 |  166 |  130 |   81 |   36 |    8 |    0 |  1581 |
|     6 |    0 |    4 |   17 |   71 |  132 |  163 |  182 |  191 |  193 |  182 |  161 |  132 |   89 |   43 |   10 |    1 |  1572 |
|     7 |    0 |    3 |   17 |   57 |  121 |  160 |  185 |  197 |  199 |  189 |  168 |  137 |   92 |   44 |   11 |    1 |  1581 |
|     8 |    0 |    1 |   11 |   48 |  104 |  149 |  171 |  183 |  187 |  179 |  156 |  121 |   76 |   32 |    5 |    0 |  1421 |
|     9 |    0 |    0 |    6 |   32 |   77 |  127 |  151 |  160 |  159 |  148 |  124 |   93 |   47 |   12 |    1 |    0 |  1137 |
|    10 |    0 |    0 |    1 |   16 |   54 |   85 |  107 |  115 |  119 |  106 |   85 |   56 |   17 |    2 |    0 |    0 |   763 |
|    11 |    0 |    0 |    5 |   30 |   57 |   70 |   84 |   83 |   76 |   64 |   35 |    8 |    1 |    0 |    0 |    0 |   512 |
|    12 |    0 |    0 |    2 |   17 |   39 |   54 |   67 |   75 |   64 |   58 |   31 |    4 |    0 |    0 |    0 |    0 |   411 |
|  NULL |    0 |   13 |  112 |  516 | 1023 | 1392 | 1628 | 1728 | 1703 | 1570 | 1294 |  902 |  506 |  203 |   38 |    2 | 12629 |
+-------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+-------+

```

Midday in the summer is the best time for solar panels, as you would expect. 1-2pm in July was the best.

 Postlog
-------

 Posted, Feb. 2015

 See Also
--------

 * [Brawley's notes](http://www.artfulsoftware.com/queries.php) Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

 Original source: <http://mysql.rjweb.org/doc.php/pivot>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pivoting-in-mariadb/>

USE INDEX
=========

    You can limit which indexes are considered with the `USE INDEX` option.

 Syntax
------

 
```
USE INDEX [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])

```
 Description
-----------

 The default is 'FOR JOIN', which means that the hint only affects how the WHERE clause is optimized.

 USE INDEX is used after the table name in the FROM clause.

 USE INDEX cannot use an [ignored index](../ignored-indexes/index) - it will be treated as if it doesn't exist.

 ### Index Prefixes

 When using index hints (USE, FORCE or IGNORE INDEX), the index name value can also be an unambiguous prefix of an index name.

 Example
-------

 
```
CREATE INDEX Name ON City (Name);
CREATE INDEX CountryCode ON City (Countrycode);
EXPLAIN SELECT Name FROM City USE INDEX (CountryCode)
WHERE name="Helsingborg" AND countrycode="SWE";

```

This produces:

 
```
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	City	ref	CountryCode	CountryCode	3	const	14	Using where

```

If we had not used USE INDEX, the Name index would have been in possible keys.

 See Also
--------

 * [Index Hints: How to Force Query Plans](../index-hints-how-to-force-query-plans/index) for more details
* [IGNORE INDEX](../ignore-index/index)
* [FORCE INDEX](../force-index/index)
* [Ignored Indexes](../ignored-indexes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/use-index/>

Aria Storage Engine
===================

     The [Aria](../aria/index) storage engine is compiled in by default from [MariaDB 5.1](../what-is-mariadb-51/index) and it is required to be 'in use' when MariaDB is started.

 From [MariaDB 10.4](../what-is-mariadb-104/index), all [system tables](../system-tables/index) are Aria.

 Additionally, internal on-disk tables are in the Aria table format instead of the [MyISAM](../myisam/index) table format. This should speed up some [GROUP BY](../group-by/index) and [DISTINCT](../count-distinct/index) queries because Aria has better caching than MyISAM. 

 
Note: The ***Aria*** storage engine was previously called ***Maria*** (see [The Aria Name](../the-aria-name/index) for details on the rename) and in previous versions of [MariaDB](../mariadb/index) the engine was still called Maria.

 
The following table options to Aria tables in [CREATE TABLE](../create-table/index) and [ALTER TABLE](../alter-table/index):

 * **`TRANSACTIONAL= 0 `|` 1` :** If the `TRANSACTIONAL` table option is set for an Aria table, then the table will be crash-safe. This is implemented by logging any changes to the table to Aria's transaction log, and syncing those writes at the end of the statement. This will marginally slow down writes and updates. However, the benefit is that if the server dies before the statement ends, all non-durable changes will roll back to the state at the beginning of the statement. This also needs up to 6 bytes more for each row and key to store the transaction id (to allow concurrent insert's and selects).
	+ `TRANSACTIONAL=1` is not supported for partitioned tables.
	+ An Aria table's default value for the `TRANSACTIONAL` table option depends on the table's value for the `ROW_FORMAT` table option. See below for more details.
	+ If the `TRANSACTIONAL` table option is set for an Aria table, the table does not actually support transactions. See [MDEV-21364](https://jira.mariadb.org/browse/MDEV-21364) for more information. In this context, *transactional* just means *crash-safe*.
* **`PAGE_CHECKSUM= 0 `|` 1` :** If index and data should use page checksums for extra safety.
* **`TABLE_CHECKSUM= 0 `|` 1` :** Same as `CHECKSUM` in MySQL 5.1
* **`ROW_FORMAT=PAGE `|` FIXED `|` DYNAMIC` :** The table's [row format](../aria-storage-formats/index).
	+ The default value is `PAGE`.
	+ To emulate MyISAM, set `ROW_FORMAT=FIXED` or `ROW_FORMAT=DYNAMIC`

 The `TRANSACTIONAL` and `ROW_FORMAT` table options interact as follows:

 * If `TRANSACTIONAL=1` is set, then the only supported row format is `PAGE`. If `ROW_FORMAT` is set to some other value, then Aria issues a warning, but still forces the row format to be `PAGE`.
* If `TRANSACTIONAL=0` is set, then the table will be not be crash-safe, and any row format is supported.
* If `TRANSACTIONAL` is not set to any value, then any row format is supported. If `ROW_FORMAT` is set, then the table will use that row format. Otherwise, the table will use the default `PAGE` row format. In this case, if the table uses the `PAGE` row format, then it will be crash-safe. If it uses some other row format, then it will not be crash-safe.

 Some other improvements are:

 * [CHECKSUM TABLE](../checksum-table/index) now ignores values in NULL fields. This makes `CHECKSUM TABLE` faster and fixes some cases where same table definition could give different checksum values depending on [row format](../aria-storage-formats/index). The disadvantage is that the value is now different compared to other MySQL installations. The new checksum calculation is fixed for all table engines that uses the default way to calculate and MyISAM which does the calculation internally. Note: Old MyISAM tables with internal checksum will return the same checksum as before. To fix them to calculate according to new rules you have to do an `[ALTER TABLE](../alter-table/index)`. You can use the old ways to calculate checksums by using the option `--old` to mariadbd*mysqld or set the system variable '`@@old`' to `1` when you do `CHECKSUM TABLE ... EXTENDED;`*
* At startup Aria will check the Aria logs and automatically recover the tables from the last checkpoint if the server was not taken down correctly. See [Aria Log Files](#aria-log-files)

 Startup Options for Aria
------------------------

 For a full list, see [Aria System Variables](../aria-server-system-variables/index).

 In normal operations, the only variables you have to consider are:

 * [aria-pagecache-buffer-size](../aria-server-system-variables/index#aria_pagecache_buffer_size)
	+ This is where all index and data pages are cached. The bigger this is, the faster Aria will work.
* [aria-block-size](%5baria-server-system-variables#aria_block_size)
	+ The default value 8192, should be ok for most cases. The only problem with a higher value is that it takes longer to find a packed key in the block as one has to search roughly 8192/2 to find each key. We plan to fix this by adding a dictionary at the end of the page to be able to do a binary search within the block before starting a scan. Until this is done and key lookups takes too long time even if you are not hitting disk, then you should consider making this smaller.
	+ Possible values to try are `2048`, `4096` or `8192`
	+ Note that you can't change this without dumping, deleting old tables and deleting all log files and then restoring your Aria tables. (This is the only option that requires a dump and load)
* [aria-log-purge-type](../aria-server-system-variables/index#aria_log_purge_type)
	+ Set this to "`at_flush`" if you want to keep a copy of the transaction logs (good as an extra backup). The logs will stay around until you execute [FLUSH ENGINE LOGS](../flush/index).

 Aria Log Files
--------------

 `aria_log_control` file is a very short log file (52 bytes) that contains the current state of all Aria tables related to logging and checkpoints. In particular, it contains the following information:

 
```
Aria file version: 1
Block size: 8192
maria_uuid: ee948482-6cb7-11ed-accb-3c7c3ff16468
last_checkpoint_lsn: (1,0x235a)
last_log_number: 1
trid: 28
recovery_failures: 0

```

* The `uuid` is a unique identifier per system. All Aria files created will have a copy of this in their .MAI headers. This is mainly used to check if someone has copied an Aria file between MariaDB servers.
* `last_checkpoint_lsn` and `last_log_number` are information about the current aria\_log files.
* `trid` is the highest transaction number seen so far. Used by recovery.

 `aria_log.*` files contain the log of all operations that change Aria files (including create table, drop table, insert etc..) This is a 'normal' WAL (Write Ahead Log), similar to the InnoDB log file, except that aria\_logs contain both redo and undo. Old aria\_log files are automatically deleted when they are not needed anymore (Neither the last checkpoint or any running transaction need to refer to the old data anymore).

 ### Missing valid id

 The error `Missing valid id at start of file. File is not a valid aria control file` means that something overwrote at least the first 4 bytes in the file. This can happen due to a problem with the file system (hardware or software), or a bug in which a thread inside MariaDB wrote on the wrong file descriptor (in which case you should [report the bug](../reporting-bugs/index), attaching a copy of the control file to assist).

 In the case of a corrupted log file, with the server shut down, one should be able to fix that by deleting all aria\_log files. If the control\_file is corrupted, then one has to delete the aria\_control\_file and all aria\_log.\* files. The effect of this is that on table open of an Aria table, the server will think that it has been moved from another system and do an automatic check and repair of it. If there was no issues, the table will be opened and can be used as normal. See also [When is it safe to remove old log files](../aria-faq/index#when-is-it-safe-to-remove-old-log-files).

 See Also
--------

 * [Aria FAQ](../aria-faq/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-storage-engine/>

Installing MariaDB with zypper
==============================

    On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM packages](../rpm/index) from MariaDB's repository using `[zypper](https://en.wikipedia.org/wiki/ZYpp)`.

 This page walks you through the simple installation steps using `zypper`.

 Adding the MariaDB ZYpp repository
----------------------------------

 We currently have ZYpp repositories for the following Linux distributions:

 * SUSE Linux Enterprise Server (SLES) 12
* SUSE Linux Enterprise Server (SLES) 15
* OpenSUSE 15
* OpenSUSE 42

 ### Using the MariaDB Package Repository Setup Script

 If you want to install MariaDB with `zypper`, then you can configure `zypper` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 MariaDB Corporation provides a MariaDB Package Repository for several Linux distributions that use `zypper` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Package Repository setup script automatically configures your system to install packages from the MariaDB Package Repository.

 To use the script, execute the following command:

 
```
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

```

Note that this script also configures a repository for [MariaDB MaxScale](../maxscale/index) and a repository for MariaDB Tools, which currently only contains [Percona XtraBackup](../percona-xtrabackup/index) and its dependencies.

 See [MariaDB Package Repository Setup and Usage](../mariadb-package-repository-setup-and-usage/index) for more information.

 ### Using the MariaDB Repository Configuration Tool

 If you want to install MariaDB with `zypper`, then you can configure `zypper` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 The MariaDB Foundation provides a MariaDB repository for several Linux distributions that use `zypper` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Repository Configuration Tool can easily generate the appropriate commands to add the repository for your distribution.

 For example, if you wanted to use the repository to install [MariaDB 10.3](../what-is-mariadb-103/index) on SLES 15, then you could use the following commands to add the MariaDB `zypper` repository:

 
```
sudo zypper addrepo --gpgcheck --refresh https://yum.mariadb.org/10.3/sles/15/x86_64 mariadb
sudo zypper --gpg-auto-import-keys refresh

```

### Pinning the MariaDB Repository to a Specific Minor Release

 If you wish to pin the `zypper` repository to a specific minor release, or if you would like to downgrade to a specific minor release, then you can create a `zypper` repository with the URL hard-coded to that specific minor release. 

 The MariaDB Foundation archives repositories of old minor releases at the following URL:

 * <http://archive.mariadb.org/>

 So if you can't find the repository of a specific minor release at `yum.mariadb.org`, then it would be a good idea to check the archive.

 For example, if you wanted to pin your repository to [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/) on SLES 15, then you could use the following commands to add the MariaDB `zypper` repository:

 
```
sudo zypper removerepo mariadb
sudo zypper addrepo --gpgcheck --refresh https://yum.mariadb.org/10.3.14/sles/15/x86_64 mariadb

```

Updating the MariaDB ZYpp repository to a New Major Release
-----------------------------------------------------------

 MariaDB's `zypper` repository can be updated to a new major release. How this is done depends on how you originally configured the repository.

 ### Updating the Major Release with the MariaDB Package Repository Setup Script

 If you configured `zypper` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index), then you can update the major release that the repository uses by running the script again.

 ### Updating the Major Release with the MariaDB Repository Configuration Tool

 If you configured `zypper` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/), then you can update the major release that the repository uses by removing the repository for the old version and adding the repository for the new version.

 First, you can remove the repository for the old version by executing the following command:

 
```
sudo zypper removerepo mariadb

```

After that, you can add the repository for the new version. For example, if you wanted to use the repository to install [MariaDB 10.3](../what-is-mariadb-103/index) on SLES 15, then you could use the following commands to add the MariaDB `zypper` repository:

 
```
sudo zypper addrepo --gpgcheck --refresh https://yum.mariadb.org/10.3/sles/15/x86_64 mariadb
sudo zypper --gpg-auto-import-keys refresh

```

After that, the repository should refer to [MariaDB 10.3](../what-is-mariadb-103/index).

 Importing the MariaDB GPG Public Key
------------------------------------

 Before MariaDB can be installed, you also have to import the GPG public key that is used to verify the digital signatures of the packages in our repositories. This allows the the `zypper` and `rpm` utilities to verify the integrity of the packages that they install.

 The id of our GPG public key is `0xcbcb082a1bb943db`. The short form of the id is `0x1BB943DB`. The full key fingerprint is:

 
```
1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

```

The `[rpm](https://linux.die.net/man/8/rpm)` utility can be used to import this key. For example:

 
```
sudo rpm --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB

```

Once the GPG public key is imported, you are ready to install packages from the repository.

 Installing MariaDB Packages with ZYpp
-------------------------------------

 After the `zypper` repository is configured, you can install MariaDB by executing the `[zypper](https://en.opensuse.org/SDB:Zypper_manual_(plain))` command. The specific command that you would use would depend on which specific packages that you want to install.

 ### Installing the Most Common Packages with ZYpp

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to Install the most common packages, execute the following command:

 
```
sudo zypper install MariaDB-server galera-4 MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to Install the most common packages, execute the following command:

 
```
sudo zypper install MariaDB-server galera MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common

```


### Installing MariaDB Server with ZYpp

 To Install MariaDB Server, execute the following command:

 
```
sudo zypper install MariaDB-server

```

### Installing MariaDB Galera Cluster with ZYpp

 The process to install MariaDB Galera Cluster with the MariaDB `zypper` repository is practically the same as installing standard MariaDB Server.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and later, Galera Cluster support has been included in the standard MariaDB Server packages, so you will need to install the `MariaDB-server` package, as you normally would.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you also need to install the `galera-4` package to obtain the [Galera](../galera/index) 4 wsrep provider library.

 In [MariaDB 10.3](../what-is-mariadb-103/index) and before, you also need to install the `galera` package to obtain the [Galera](../galera/index) 3 wsrep provider library.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo zypper install MariaDB-server MariaDB-client galera-4

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo zypper install MariaDB-server MariaDB-client galera

```


If you haven't yet imported the MariaDB GPG public key, then `zypper` will prompt you to import it after it downloads the packages, but before it prompts you to install them.

 See [MariaDB Galera Cluster](../galera/index) for more information on MariaDB Galera Cluster.

 ### Installing MariaDB Clients and Client Libraries with ZYpp

 In [MariaDB 10.2](../what-is-mariadb-102/index) and later, [MariaDB Connector/C](../about-mariadb-connector-c/index) has been included as the client library. However, the package name for the client library has not been changed.

 To Install the clients and client libraries, execute the following command:

 
```
sudo zypper install MariaDB-client MariaDB-shared

```

### Installing Mariabackup with ZYpp

 To install [Mariabackup](../mariabackup/index), execute the following command:

 
```
sudo zypper install MariaDB-backup

```

### Installing Plugins with ZYpp

 Some [plugins](../plugins/index) may also need to be installed.

 For example, to install the `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin, execute the following command:

 
```
sudo zypper install MariaDB-cracklib-password-check

```

### Installing Debug Info Packages with ZYpp

 
**MariaDB starting with [5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/)**The MariaDB `zypper` repository first added `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` packages in [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/).

 
The MariaDB `zypper` repository also contains `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` packages. These package may be needed when [debugging a problem](../how-to-produce-a-full-stack-trace-for-mysqld/index).

 #### Installing Debug Info for the Most Common Packages with ZYpp

 To install [debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo) for the most common packages, execute the following command:

 
```
sudo zypper install MariaDB-server-debuginfo MariaDB-client-debuginfo MariaDB-shared-debuginfo MariaDB-backup-debuginfo MariaDB-common-debuginfo

```

#### Installing Debug Info for MariaDB Server with ZYpp

 To install `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` for MariaDB Server, execute the following command:

 
```
sudo zypper install MariaDB-server-debuginfo

```

#### Installing Debug Info for MariaDB Clients and Client Libraries with ZYpp

 In [MariaDB 10.2](../what-is-mariadb-102/index) and later, [MariaDB Connector/C](../about-mariadb-connector-c/index) has been included as the client library. However, the package name for the client library has not been changed.

 To install `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` for the clients and client libraries, execute the following command:

 
```
sudo zypper install MariaDB-client-debuginfo MariaDB-shared-debuginfo

```

#### Installing Debug Info for Mariabackup with ZYpp

 To install `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` for [Mariabackup](../mariabackup/index), execute the following command:

 
```
sudo zypper install MariaDB-backup-debuginfo

```

#### Installing Debug Info for Plugins with ZYpp

 For some [plugins](../plugins/index), `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` may also need to be installed.

 For example, to install `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` for the `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin, execute the following command:

 
```
sudo zypper install MariaDB-cracklib-password-check-debuginfo

```

### Installing Older Versions from the Repository

 The MariaDB `zypper` repository contains the last few versions of MariaDB. To show what versions are available, use the following command:

 
```
zypper search --details MariaDB-server

```

In the output you will see the available versions.

 To install an older version of a package instead of the latest version we just need to specify the package name, a dash, and then the version number. And we only need to specify enough of the version number for it to be unique from the other available versions.

 However, when installing an older version of a package, if `zypper` has to install dependencies, then it will automatically choose to install the latest versions of those packages. To ensure that all MariaDB packages are on the same version in this scenario, it is necessary to specify them all.

 The packages that the MariaDB-server package depend on are: MariaDB-client, MariaDB-shared, and MariaDB-common. Therefore, to install [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/) from this `zypper` repository, we would do the following:

 
```
sudo zypper install MariaDB-server-10.3.14 MariaDB-client-10.3.14 MariaDB-shared-10.3.14 MariaDB-backup-10.3.14 MariaDB-common-10.3.14

```

The rest of the install and setup process is as normal.

 After Installation
------------------

 After the installation is complete, you can [start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 If you are using [MariaDB Galera Cluster](../galera/index), then keep in mind that the first node will have to be [bootstrapped](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-with-zypper/>

Installing MariaDB with yum/dnf
===============================

    On RHEL, CentOS, Fedora, and other similar Linux RPM based distributions, these provide MariaDB packages. These are supported by those distributions. If you have a particular need for a later version than what is in the distribution, then MariaDB provides repositories for them.

 Using repositories rather than installing RPM allows for an ease of update when a new release is made. It is highly recommended to install the relevant [RPM packages](../rpm/index) from MariaDB's repository using [yum](https://en.wikipedia.org/wiki/Yum_(software)) or [dnf](https://en.wikipedia.org/wiki/DNF_(software)). Centos 7 still uses `yum`, most others use `dnf`, and SUSE/openSUSE use `zypper`.

 This page walks you through the simple installation steps using `dnf` and `yum`.

 Adding the MariaDB YUM repository
---------------------------------

 We currently have YUM/DNF repositories for the following Linux distributions, and for the versions that are in standard (not extended) support:

 * Red Hat Enterprise Linux (RHEL)
* CentOS
* Fedora
* openSUSE
* SUSE

 ### Using the MariaDB Package Repository Setup Script

 If you want to install MariaDB with `yum`, then you can configure `yum` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 MariaDB Corporation provides a MariaDB Package Repository for several Linux distributions that use `yum` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Package Repository setup script automatically configures your system to install packages from the MariaDB Package Repository.

 To use the script, execute the following command:

 
```
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

```

Note that this script also configures a repository for [MariaDB MaxScale](../maxscale/index) and a repository for MariaDB Tools, which currently only contains [Percona XtraBackup](../percona-xtrabackup/index) and its dependencies.

 See [MariaDB Package Repository Setup and Usage](../mariadb-package-repository-setup-and-usage/index) for more information.

 ### Using the MariaDB Repository Configuration Tool

 If you want to install MariaDB with `yum`, then you can configure `yum` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 The MariaDB Foundation provides a MariaDB repository for several Linux distributions that use `yum` to manage packages. This repository contains software packages related to MariaDB Server, including the server itself, [clients and utilities](../clients-utilities/index), [client libraries](../client-libraries/index), [plugins](../plugins/index), and [Mariabackup](../mariabackup/index). The MariaDB Repository Configuration Tool can easily generate the appropriate configuration file to add the repository for your distribution.

 Once you have the appropriate repository configuration section for your distribution, add it to a file named `MariaDB.repo` under `/etc/yum.repos.d/`.

 For example, if you wanted to use the repository to install [MariaDB 10.6](../what-is-mariadb-106/index) on RHEL (any version), then you could use the following `yum` repository configuration in `/etc/yum.repos.d/MariaDB.repo`:

 
```
[mariadb]
name = MariaDB
baseurl = https://rpm.mariadb.org/10.6/rhel/$releasever/$basearch
gpgkey= https://rpm.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

```

The example file above includes a `gpgkey` line to automatically fetch the GPG public key that is used to verify the digital signatures of the packages in our repositories. This allows the the `yum`, `dnf`, and `rpm` utilities to verify the integrity of the packages that they install.

 ### Pinning the MariaDB Repository to a Specific Minor Release

 If you wish to pin the `yum` repository to a specific minor release, or if you would like to do a `yum downgrade` to a specific minor release, then you can create a `yum` repository configuration with a `baseurl` option set to that specific minor release. 

 The MariaDB Foundation archives repositories all releases is at the following URL:

 * <http://archive.mariadb.org/>

 Note this isn't configured as a highly available server. For that purpose please use the main mirrors.

 For example, if you wanted to pin your repository to [MariaDB 10.3.34](https://mariadb.com/kb/en/mariadb-10334-release-notes/) on CentOS 7, then you could use the following `yum` repository configuration in `/etc/yum.repos.d/MariaDB.repo`:

 
```
[mariadb]
name = MariaDB-10.3.34
baseurl= http://archive.mariadb.org/mariadb-10.3.34/yum/centos/$releasever/$basearch
gpgkey= https://archive.mariadb.org/PublicKey
gpgcheck=1

```

Note that if you change an existing repository configuration, then you may need to execute the following:

 
```
sudo yum clean all

```

Updating the MariaDB YUM repository to a New Major Release
----------------------------------------------------------

 MariaDB's `yum` repository can be updated to a new major release. How this is done depends on how you originally configured the repository.

 ### Updating the Major Release with the MariaDB Package Repository Setup Script

 If you configured `yum` to install from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index), then you can update the major release that the repository uses by running the script again.

 ### Updating the Major Release with the MariaDB Repository Configuration Tool

 If you configured `yum` to install from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/), then you can update the major release that the repository uses by updating the `yum` repository configuration file in-place. For example, if you wanted to change the repository from [MariaDB 10.6](../what-is-mariadb-106/index) to [MariaDB 10.11](../what-is-mariadb-1011/index), and if the repository configuration file was at `/etc/yum.repos.d/MariaDB.repo`, then you could execute the following:

 
```
sudo sed -i 's/10.6/10.11/' /etc/yum.repos.d/MariaDB.repo

```

After that, the repository should refer to [MariaDB 10.11](../what-is-mariadb-1011/index).

 
If the `yum` repository is pinned to a specific minor release, then the above `sed` command can result in an invalid repository configuration. In that case, the recommended options are:

 * Edit the `MariaDB.repo` repository file manually.
* Or delete the `MariaDB.repo` repository file, and then install the repository of the new version with the more robust [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 
Importing the MariaDB GPG Public Key
------------------------------------

 Before MariaDB can be installed, you also have to import the GPG public key that is used to verify the digital signatures of the packages in our repositories. This allows the `yum`, `dnf` and `rpm` utilities to verify the integrity of the packages that they install.

 The id of our GPG public key is:

 * short form: `0xC74CD1D8`
* long form: `0xF1656F24C74CD1D8`
* full fingerprint: `177F 4010 FE56 CA33 3630 0305 F165 6F24 C74C D1D8`

 `yum` should prompt you to import the GPG public key the first time that you install a package from MariaDB's repository. However, if you like, the [rpm](https://linux.die.net/man/8/rpm) utility can be used to manually import this key instead. For example:

 
```
sudo rpm --import https://supplychain.mariadb.com/MariaDB-Server-GPG-KEY

```

Once the GPG public key is imported, you are ready to install packages from the repository.

 ### Old Key

 For releases before 2023 an older SHA1 based GPG key was used.

 The id of this older GPG public key was `0xcbcb082a1bb943db`. The short form was `0x1BB943DB`. The full key fingerprint was:

 
```
1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

```

Installing MariaDB Packages with YUM/DNF
----------------------------------------

 After the `dnf`/`yum` repository is configured, you can install MariaDB by executing the [dnf](https://www.man7.org/linux/man-pages/man8/dnf.8.html) or [yum](https://www.man7.org/linux/man-pages/man8/yum.8.html) command. The specific command that you would use would depend on which specific packages that you want to install.

 ### Installing the Most Common Packages

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to Install the most common packages, execute the following command:

 
```
sudo dnf install MariaDB-server galera-4 MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to Install the most common packages, execute the following command:

 
```
sudo yum install MariaDB-server galera MariaDB-client MariaDB-shared MariaDB-backup MariaDB-common

```


### Installing MariaDB Server

 To Install MariaDB Server, execute the following command:

 
```
sudo dnf install MariaDB-server

```

### Installing MariaDB Galera Cluster with YUM

 The process to install MariaDB Galera Cluster with the MariaDB `yum` repository is practically the same as installing standard MariaDB Server.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you also need to install the `galera-4` package to obtain the [Galera](../galera/index) 4 wsrep provider library.

 In [MariaDB 10.3](../what-is-mariadb-103/index) and before, you also need to install the `galera` package to obtain the [Galera](../galera/index) 3 wsrep provider library.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo yum install MariaDB-server MariaDB-client galera-4

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, to install MariaDB Galera Cluster, you could execute the following command:

 
```
sudo yum install MariaDB-server MariaDB-client galera

```


If you haven't yet imported the MariaDB GPG public key, then `yum` will prompt you to import it after it downloads the packages, but before it prompts you to install them.

 See [MariaDB Galera Cluster](../galera/index) for more information on MariaDB Galera Cluster.

 ### Installing MariaDB Clients and Client Libraries with YUM

 In [MariaDB 10.2](../what-is-mariadb-102/index) and later, [MariaDB Connector/C](../about-mariadb-connector-c/index) has been included as the client library (staticly linked). However, the package name for the client library has not been changed.

 To Install the clients and client libraries, execute the following command:

 
```
sudo yum install MariaDB-client MariaDB-shared

```

If you want compile your own programs against [MariaDB Connector/C](../about-mariadb-connector-c/index), execute the following command:

 
```
sudo yum install MariaDB-devel

```

### Installing Mariabackup with YUM

 To install [Mariabackup](../mariabackup/index), execute the following command:

 
```
sudo yum install MariaDB-backup

```

### Installing Plugins with YUM

 Some [plugins](../plugins/index) may also need to be installed.

 For example, to install the [cracklib\_password\_check](../cracklib-password-check-plugin/index) password validation plugin, execute the following command:

 
```
sudo yum install MariaDB-cracklib-password-check

```

### Installing Debug Info Packages with YUM

 
**MariaDB starting with [5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/)**The MariaDB `yum` repository first added [debuginfo](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Developer_Guide/intro.debuginfo.html) packages in [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/).

 
The MariaDB `yum` repository also contains [debuginfo](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Developer_Guide/intro.debuginfo.html) packages. These package may be needed when [debugging a problem](../how-to-produce-a-full-stack-trace-for-mysqld/index).

 #### Installing Debug Info for the Most Common Packages with YUM

 To install [debuginfo](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Developer_Guide/intro.debuginfo.html) for the most common packages, execute the following command:

 
```
sudo yum install MariaDB-server-debuginfo MariaDB-client-debuginfo MariaDB-shared-debuginfo MariaDB-backup-debuginfo MariaDB-common-debuginfo

```

All packages have their debuginfo by appending `-debuginfo` to the package name.

 #### Installing Debug Info for MariaDB Server with YUM

 To install [debuginfo](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Developer_Guide/intro.debuginfo.html) for MariaDB Server, execute the following command:

 
```
sudo yum install MariaDB-server-debuginfo

```

### Installing Older Versions from the Repository

 The MariaDB `yum` repository contains the last few versions of MariaDB. To show what versions are available, use the following command:

 
```
yum list --showduplicates MariaDB-server

```

In the output you will see the available versions. For example:

 
```
$ yum list --showduplicates MariaDB-server
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.mirrors.ovh.net
 * extras: centos.mirrors.ovh.net
 * updates: centos.mirrors.ovh.net
Available Packages
MariaDB-server.x86_64   10.3.10-1.el7.centos    mariadb
MariaDB-server.x86_64   10.3.11-1.el7.centos    mariadb
MariaDB-server.x86_64   10.3.12-1.el7.centos    mariadb
mariadb-server.x86_64   1:5.5.60-1.el7_5         base   

```

The MariaDB `yum` repository in this example contains [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10311-release-notes/), and [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/). The CentOS base `yum` repository also contains [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5560-release-notes/).

 To install an older version of a package instead of the latest version we just need to specify the package name, a dash, and then the version number. And we only need to specify enough of the version number for it to be unique from the other available versions.

 However, when installing an older version of a package, if `yum` has to install dependencies, then it will automatically choose to install the latest versions of those packages. To ensure that all MariaDB packages are on the same version in this scenario, it is necessary to specify them all.

 The packages that the MariaDB-server package depend on are: MariaDB-client, MariaDB-shared, and MariaDB-common. Therefore, to install [MariaDB 10.3.11](https://mariadb.com/kb/en/mariadb-10311-release-notes/) from this `yum` repository, we would do the following:

 
```
sudo yum install MariaDB-server-10.3.11 MariaDB-client-10.3.11 MariaDB-shared-10.3.11 MariaDB-backup-10.3.11 MariaDB-common-10.3.11

```

The rest of the install and setup process is as normal.

 After Installation
------------------

 After the installation is complete, you can [start MariaDB](../starting-and-stopping-mariadb-automatically/index).

 If you are using [MariaDB Galera Cluster](../galera/index), then keep in mind that the first node will have to be [bootstrapped](../getting-started-with-mariadb-galera-cluster/index#bootstrapping-a-new-cluster).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/yum/>

TLS and Cryptography Libraries Used by MariaDB
==============================================

    When MariaDB Server is compiled with TLS and cryptography support, it is usually either statically linked with MariaDB's bundled TLS and cryptography library or dynamically linked with the system's [OpenSSL](https://www.openssl.org/) library. MariaDB's bundled TLS library is either [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), depending on the server version.

 When a MariaDB client or client library is compiled with TLS and cryptography support, it is usually either statically linked with MariaDB's bundled TLS and cryptography library or dynamically linked with the system's TLS and cryptography library, which might be [OpenSSL](https://www.openssl.org/), [GnuTLS](https://www.gnutls.org/), or [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel).

 Checking Dynamically vs. Statically Linked
------------------------------------------

 Dynamically linking MariaDB to the system's TLS and cryptography library can often be beneficial, since this allows you to fix bugs in the system's TLS and cryptography library independently of MariaDB. For example, when information on the [Heartbleed Bug](http://heartbleed.com/) in [OpenSSL](https://www.openssl.org/) was released in 2014, the bug could be mitigated by simply updating your system to use a fixed version of the [OpenSSL](https://www.openssl.org/) library, and then restarting the MariaDB Server.

 You can verify that `mysqld` is in fact dynamically linked to the [OpenSSL](https://www.openssl.org/) shared library on your system by using the `[ldd](https://linux.die.net/man/1/ldd)` command:

 
```
$ ldd $(which mysqld) | grep -E '(libssl|libcrypto)'
        libssl.so.10 => /lib64/libssl.so.10 (0x00007f8736386000)
        libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f8735f25000)

```

If the command does not return any results, then either your `mysqld` is statically linked to the TLS and cryptography library on your system or your `mysqld` is not built with TLS and cryptography support at all.

 Checking If the Server Uses OpenSSL
-----------------------------------

 In [MariaDB 10.0](../what-is-mariadb-100/index) and later, if you aren't sure whether your server is linked with [OpenSSL](https://www.openssl.org/) or the bundled TLS library, then you can check the value of the `[have\_openssl](../ssl-system-variables/index#have_openssl)` system variable. For example:

 
```
SHOW GLOBAL VARIABLES LIKE 'have_openssl';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl  | YES   |
+---------------+-------+

```

Checking the Server's OpenSSL Version
-------------------------------------

 In [MariaDB 10.1](../what-is-mariadb-101/index) and later, if you want to see what version of [OpenSSL](https://www.openssl.org/) your server is using, then you can check the value of the `[version\_ssl\_library](../ssl-system-variables/index#version_ssl_library)` system variable. For example:

 
```
SHOW GLOBAL VARIABLES LIKE 'version_ssl_library';
+---------------------+---------------------------------+
| Variable_name       | Value                           |
+---------------------+---------------------------------+
| version_ssl_library | OpenSSL 1.0.1e-fips 11 Feb 2013 |
+---------------------+---------------------------------+

```

Note that the version returned by this system variable does not always necessarily correspond to the exact version of the [OpenSSL](https://www.openssl.org/) package installed on the system. [OpenSSL](https://www.openssl.org/) shared libraries tend to contain interfaces for multiple versions at once to allow for backward compatibility. Therefore, if the [OpenSSL](https://www.openssl.org/) package installed on the system is newer than the [OpenSSL](https://www.openssl.org/) version that the MariaDB Server binary was built with, then the MariaDB Server binary might use one of the interfaces for an older version. See [MDEV-15848](https://jira.mariadb.org/browse/MDEV-15848) for more information. For example:

 
```
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)
$ rpm -q openssl
openssl-1.0.2k-12.el7.x86_64
$ mysql -u root --batch --execute="SHOW GLOBAL VARIABLES LIKE 'version_ssl_library';"
Variable_name   Value
version_ssl_library     OpenSSL 1.0.1e-fips 11 Feb 2013
$ ldd $(which mysqld) | grep libcrypto
        libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f3dd3482000)
$ readelf -a /lib64/libcrypto.so.10 | grep SSLeay_version
  1374: 000000000006f5d0    21 FUNC    GLOBAL DEFAULT   13 SSLeay_version@libcrypto.so.10
  1375: 000000000006f5f0    21 FUNC    GLOBAL DEFAULT   13 SSLeay_version@OPENSSL_1.0.1
  1377: 000000000006f580    70 FUNC    GLOBAL DEFAULT   13 SSLeay_version@@OPENSSL_1.0.2

```

FIPS Certification
------------------

 [Federal Information Processing Standards (FIPS)](https://www.nist.gov/itl/itl-publications/federal-information-processing-standards-fips) are standards published by the U.S. federal government that are used to establish requirements for various aspects of computer systems. [FIPS 140-2](https://www.nist.gov/publications/security-requirements-cryptographic-modules-includes-change-notices-1232002?pub_id=902003) is a set of standards for security requirements for cryptographic modules.

 This standard is relevant when discussing the TLS and cryptography libraries used by MariaDB. Some of these libraries have been certified to meet the standards set by FIPS 140-2.

 ### FIPS Certification by OpenSSL

 The [OpenSSL](https://www.openssl.org/) library has a special FIPS mode that has been certified to meet the FIPS 140-2 standard. In FIPS mode, only algorithms and key sizes that meet the FIPS 140-2 standard are enabled by the library.

 MariaDB does not yet support enabling FIPS mode within the database server. See [MDEV-20260](https://jira.mariadb.org/browse/MDEV-20260) for more information. Therefore, if you would like to use OpenSSL's FIPS mode with MariaDB, then you would either need to enable FIPS mode at the kernel level or enable it via the OpenSSL configuration file, system-wide or only for the MariaDB process.. See the following resources for more information on how to do that:

 * [Red Hat Enterprise Linux 7: Security Guide: Chapter 8. Federal Standards and Regulations](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-federal_standards_and_regulations)
* [Ubuntu Security Certifications Documentation: FIPS for Ubuntu 16.04 and 18.04](https://security-certs.docs.ubuntu.com/en/fips)
* [OpenSSL 1.0.2, configuration file method](https://www.openssl.org/docs/fips/UserGuide-2.0.pdf#page=73)
* [OpenSSL 3.0 configuration file method](https://www.openssl.org/docs/man3.0/man7/fips_module.html#Making-all-applications-use-the-FIPS-module-by-default)

 ### FIPS Certification by wolfSSL

 The standard version of the [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library has not been certified to meet the FIPS 140-2 standard, but a special ["FIPS-ready"](https://www.wolfssl.com/wolfssl-fips-ready/) version has been certified. Unfortunately, the "FIPS-ready" version of wolfSSL uses a license that is incompatible with MariaDB's license, so it cannot be used with MariaDB.

 ### FIPS Certification by yaSSL

 The [yaSSL](https://www.wolfssl.com/products/yassl/) library has not been certified to meet the FIPS 140-2 standard.

 Libraries Used by Each Platform and Package
-------------------------------------------

 ### MariaDB Server

 #### MariaDB Server on Windows

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**MariaDB Server is statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 

**MariaDB until [10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)**MariaDB Server is statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 
#### MariaDB Server on Linux

 ##### MariaDB Server in Binary Tarballs

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**In [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) and later, MariaDB Server is statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 

**MariaDB until [10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/)**In [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) and before, MariaDB Server is statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 
##### MariaDB Server in DEB Packages

 MariaDB Server is dynamically linked with the system's [OpenSSL](https://www.openssl.org/) library in `[.deb](../installing-mariadb-deb-files/index)` packages.

 
**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, MariaDB Server is statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories.

 
See [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) for more information.

 ##### MariaDB Server in RPM Packages

 MariaDB Server is dynamically linked with the system's [OpenSSL](https://www.openssl.org/) library in `[.rpm](../rpm/index)` packages.

 ### MariaDB Clients and Utilities

 In [MariaDB 10.2](../what-is-mariadb-102/index) and later, [MariaDB Connector/C](../mariadb-connector-c/index) has been [included with MariaDB Server](../about-mariadb-connector-c/index#integration-with-mariadb-server), and the bundled and the [clients and utilities](../clients-utilities/index) are linked with it. On some platforms, [MariaDB Connector/C](../mariadb-connector-c/index) and these [clients and utilities](../clients-utilities/index) may use a different TLS library than the one used by MariaDB Server and [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html).

 #### MariaDB Clients and Utilities on Windows

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**In [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are are dynamically linked with the system's [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel) libraries in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library.

 

**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are are dynamically linked with the system's [Schannel](https://docs.microsoft.com/en-us/windows/desktop/secauthn/secure-channel) libraries in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library.

 

**MariaDB until [10.1](../what-is-mariadb-101/index)**In [MariaDB 10.1](../what-is-mariadb-101/index) and before, MariaDB's [clients and utilities](../clients-utilities/index) and [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) are statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 
#### MariaDB Clients and Utilities on Linux

 ##### MariaDB Clients and Utilities in Binary Tarballs

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**In [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are statically linked with the [GnuTLS](https://www.gnutls.org/) library in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [wolfSSL](https://www.wolfssl.com/products/wolfssl/) library.

 

**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and later, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are statically linked with the [GnuTLS](https://www.gnutls.org/) library in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library.

 

**MariaDB until [10.1](../what-is-mariadb-101/index)**In [MariaDB 10.1](../what-is-mariadb-101/index) and before, MariaDB's [clients and utilities](../clients-utilities/index) and [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) are statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 
##### MariaDB Clients and Utilities in DEB Packages

 MariaDB's [clients and utilities](../clients-utilities/index), [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html), and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [OpenSSL](https://www.openssl.org/) library in `[.deb](../installing-mariadb-deb-files/index)` packages.

 
**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and 10.3, MariaDB's [clients and utilities](../clients-utilities/index) and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [GnuTLS](https://www.gnutls.org/) library in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories. [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) is still statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) libraries.

 

**MariaDB until [10.1](../what-is-mariadb-101/index)**In [MariaDB 10.1](../what-is-mariadb-101/index) and earlier, MariaDB's [clients and utilities](../clients-utilities/index) and [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html) are statically linked with the bundled [yaSSL](https://www.wolfssl.com/products/yassl/) library in `[.deb](../installing-mariadb-deb-files/index)` packages provided by Debian's and Ubuntu's default repositories. 

 
See [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) for more information.

 ##### MariaDB Clients and Utilities in RPM Packages

 MariaDB's [clients and utilities](../clients-utilities/index), [libmysqlclient](https://dev.mysql.com/doc/refman/5.5/en/c-api.html), and [MariaDB Connector/C](../mariadb-connector-c/index) are dynamically linked with the system's [OpenSSL](https://www.openssl.org/) library in `[.rpm](../rpm/index)` packages.

 Updating Dynamically Linked OpenSSL Libraries on Linux
------------------------------------------------------

 When the MariaDB Server or clients and utilities are dynamically linked to the system's [OpenSSL](https://www.openssl.org/) library, it makes it very easy to update the libraries. The information below will show how to update these libraries for each platform.

 ### Updating Dynamically Linked OpenSSL Libraries with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to update the libraries using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 Update the package by executing the following command:

 
```
sudo yum update openssl

```

And then [restart](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB server and any clients or applications that use the library.

 ### Updating Dynamically Linked OpenSSL Libraries with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to recommended to update the libraries using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 First update the package cache by executing the following command:

 
```
sudo apt update

```

And then update the package by executing the following command:

 
```
sudo apt-get update openssl

```

And then [restart](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB server and any clients or applications that use the library.

 ### Updating Dynamically Linked OpenSSL Libraries with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to recommended to update the libraries using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 Update the package by executing the following command:

 
```
sudo zypper update openssl

```

And then [restart](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) MariaDB server and any clients or applications that use the library.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tls-and-cryptography-libraries-used-by-mariadb/>

Rollup Unique User Counts
=========================

    The Problem
-----------

 The normal way to count "Unique Users" is to take large log files, sort by userid, dedup, and count. This requires a rather large amount of processing. Furthermore, the count derived cannot be rolled up. That is, daily counts cannot be added to get weekly counts -- some users will be counted multiple times.

 So, the problem is to store the counts is such a way as to allow rolling up.

 The solution
------------

 Let's think about what we can do with a hash of the userid. The hash could map to a bit in a bit string. A BIT\_COUNT of the bit string would give the 1-bits, representing the number of users. But that bit string would have to be huge. What if we could use shorter bit strings? Then different userids would be folded into the same bit. Let's assume we can solve that.

 Meanwhile, what about the rollup? The daily bit strings can be OR'd together to get a similar bit string for the week.

 We have now figured out how to do the rollup, but have created another problem -- the counts are too low.

 Inflating the BIT\_COUNT
------------------------

 A sufficiently random hash (eg MD5) will fold userids into the same bits with a predictable frequency. We need to figure this out, and work backwards. That is, given that X percent of the bits are set, we need a formula that says approximately how many userids were used to get those bits.

 I simulated the problem by generating random hashes and calculated the number of bits that would be set. Then, with the help of Eureqa software, I derived the formula:

 Y = 0.5456\*X + 0.6543\*tan(1.39\*X\*X\*X)

 How good is it?
---------------

 The formula is reasonably precise. It is usually within 1% of the correct value; rarely off by 2%.

 Of course, if virtually all the bits are set, the forumla can't be very precise. Hence, you need to plan to have the bit strings big enough to handle the expected number of Uniques. In practice, you can use less than 1 bit per Unique. This would be a huge space savings over trying to save all the userids.

 Another suggestion... If you are rolling up over a big span of time (eg hourly -> monthly), the bit strings must all be the same length, and the monthly string must be big enough to handle the expected count. This is likely to lead to very sparse hourly bit strings. Hence, it may be prudent to compress the hourly stings.

 Postlog
-------

 Invented Nov, 2013; published Apr, 2014 

 Future: Rick is working on actual code (Sep, 2016) It is complicated by bit-wise operations being limited to BIGINT. However, with MySQL 8.0 (freshly released), the desired bit-wise operations can be applied to BLOB, greatly simplifying my code. I hope to publish the pre-8.0 code soon; 8.0 code later.

 See also
--------

 Rick James graciously allowed us to use this article in the Knowledge Base.

 [Rick James' site](http://mysql.rjweb.org/) has other useful tips, how-tos, optimizations, and debugging tips.

  Original source: <http://mysql.rjweb.org/doc.php/uniques>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rollup-unique-user-counts/>

Introduction to State Snapshot Transfers (SSTs)
===============================================

    In a State Snapshot Transfer (SST), the cluster provisions nodes by transferring a full data copy from one node to another. When a new node joins the cluster, the new node initiates a State Snapshot Transfer to synchronize its data with a node that is already part of the cluster.

 Types of SSTs
-------------

 There are two conceptually different ways to transfer a state from one MariaDB server to another:

 1. **Logical**

 The only SST method of this type is the `mysqldump` SST method, which actually uses the `[mysqldump](../mysqldump/index)` utility to get a logical dump of the donor. This SST method requires the joiner node to be fully initialized and ready to accept connections before the transfer. This method is, by definition, blocking, in that it blocks the donor node from modifying its own state for the duration of the transfer. It is also the slowest of all, and that might be an issue in a cluster with a lot of load.

 2. **Physical**

 SST methods of this type physically copy the data files from the donor node to the joiner node. This requires that the joiner node is initialized after the transfer. The `[mariabackup](../mariabackup-sst-method/index)` SST method and a few other SST methods fall into this category. These SST methods are much faster than the `mysqldump` SST method, but they have certain limitations. For example, they can be used only on server startup and the joiner node must be configured very similarly to the donor node (e.g. [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) should be the same and so on). Some of the SST methods in this category are non-blocking on the donor node, meaning that the donor node is still able to process queries while donating the SST (e.g. the `[mariabackup](../mariabackup-sst-method/index)` SST method is non-blocking). 

 SST Methods
-----------

 SST methods are supported via a scriptable interface. New SST methods could potentially be developed by creating new SST scripts. The scripts usually have names of the form `wsrep_sst_<method>` where `<method>` is one of the SST methods listed below.

 You can choose your SST method by setting the `[wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method)` system variable. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_method='mariabackup';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_method = mariabackup

```

For an SST to work properly, the donor and joiner node must use the same SST method. Therefore, it is recommended to set `[wsrep\_sst\_method](../galera-cluster-system-variables/index#wsrep_sst_method)` to the same value on all nodes, since any node will usually be a donor or joiner node at some point.

 MariaDB Galera Cluster comes with the following built-in SST methods:

 ### mariabackup

 This SST method uses the [Mariabackup](../backup-restore-and-import-clients-mariadb-backup/index) utility for performing SSTs. It is one of the two non-locking methods. This is the recommended SST method if you require the ability to run queries on the donor node during the SST. Note that if you use the `mariabackup` SST method, then you also need to have `socat` installed on the server. This is needed to stream the backup from the donor to the joiner. This is a limitation inherited from the `xtrabackup-v2` SST method.

 This SST method supports [GTID](../gtid/index).

 This SST method supports [Data at Rest Encryption](../data-at-rest-encryption/index).

 This SST method is available from [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/) and [MariaDB 10.2.10](https://mariadb.com/kb/en/mariadb-10210-release-notes/).

 With this SST method, it is impossible to upgrade the cluster between some major versions; see [MDEV-27437](https://jira.mariadb.org/browse/MDEV-27437).

 See [mariabackup SST method](../mariabackup-sst-method/index) for more information.

 ### rsync / rsync\_wan

 `rsync` is the default method. This method uses the `[rsync](http://www.samba.org/rsync/)` utility to create a snapshot of the donor node. `rsync` should be available by default on all modern Linux distributions. The donor node is blocked with a read lock during the SST. This is the fastest SST method, especially for large datasets since it copies binary data. Because of that, this is the recommended SST method if you do not need to allow the donor node to execute queries during the SST.

 The `rsync` method runs `rsync` in `--whole-file` mode, assuming that nodes are connected by fast local network links so that the default delta transfer mode would consume more processing time than it may save on data transfer bandwidth. When having a distributed cluster with slow links between nodes, the `rsync_wan` method runs `rsync` in the default delta transfer mode, which may reduce data transfer time substantially when an older datadir state is already present on the joiner node. Both methods are actually implemented by the same script, `wsrep_sst_rsync_wan` is just a symlink to the `wsrep_sst_rsync` script and the actual `rsync` mode to use is determined by the name the script was called by.

 This SST method supports [GTID](../gtid/index).

 This SST method supports [Data at Rest Encryption](../data-at-rest-encryption/index).

 The rsync SST method does not support tables created with the [DATA DIRECTORY or INDEX DIRECTORY](../create-table/index#data-directoryindex-directory) clause. Use the [mariabackup](../mariabackup-sst-method/index) SST method as an alternative to support this feature.

 Use of this SST method **could result in data corruption** when using [innodb\_use\_native\_aio](../innodb-system-variables/index#innodb_use_native_aio) (the default) if the donor is older than [MariaDB 10.3.35](https://mariadb.com/kb/en/mariadb-10335-release-notes/), [MariaDB 10.4.25](https://mariadb.com/kb/en/mariadb-10425-release-notes/), [MariaDB 10.5.16](https://mariadb.com/kb/en/mariadb-10516-release-notes/), [MariaDB 10.6.8](https://mariadb.com/kb/en/mariadb-1068-release-notes/), or [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/); see [MDEV-25975](https://jira.mariadb.org/browse/MDEV-25975). Starting with those donor versions, `wsrep_sst_method=rsync` is a reliable way to upgrade the cluster to a newer major version.

 As of [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10136-release-notes/), [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/), and [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/), `[stunnel](https://www.stunnel.org)` can be used to encrypt data over the wire. Be sure to have `stunnel` installed. You will also need to generate certificates and keys. See [the stunnel documentation](https://www.stunnel.org/howto.html) for information on how to do that. Once you have the keys, you will need to add the `tkey` and `tcert` options to the `[sst]` option group in your MariaDB configuration file, such as:

 
```
[sst]
tkey = /etc/my.cnf.d/certificates/client-key.pem
tcert = /etc/my.cnf.d/certificates/client-cert.pem

```

You also need to run the certificate directory through `[openssl rehash](https://www.openssl.org/docs/man1.1.0/apps/rehash.html)`.

 ### mysqldump

 This SST method runs [mysqldump](../mysqldump/index) on the donor node and pipes the output to the [mariadb](../mariadb-client/index) client connected to the joiner node. The `mysqldump` SST method needs a username/password pair set in the [wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth) variable in order to get the dump. The donor node is blocked with a read lock during the SST. This is the slowest SST method.

 This SST method supports [GTID](../gtid/index).

 This SST method supports [Data at Rest Encryption](../data-at-rest-encryption/index).

 ### xtrabackup-v2

 
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

  This SST method uses the [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) utility for performing SSTs. It is one of the two non-blocking methods. Note that if you use the `xtrabackup-v2` SST method, you also need to have `socat` installed on the server. Since Percona XtraBackup is a third party product, this SST method requires an additional installation some additional configuration. Please refer to [Percona's xtrabackup SST documentation](http://www.percona.com/doc/percona-xtradb-cluster/5.7/manual/xtrabackup_sst.html) for information from the vendor.

 This SST method does **not** support [GTID](../gtid/index).

 This SST method does **not** support [Data at Rest Encryption](../data-at-rest-encryption/index).

 This SST method is available from MariaDB Galera Cluster 5.5.37 and MariaDB Galera Cluster 10.0.10.

 See [xtrabackup-v2 SST method](../xtrabackup-v2-sst-method/index) for more information.

 ### xtrabackup

 
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

  This SST method is an older SST method that uses the [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index) utility for performing SSTs. The `xtrabackup-v2` SST method should be used instead of the `xtrabackup` SST method starting from [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/).

 This SST method does **not** support [GTID](../gtid/index).

 This SST method does **not** support [Data at Rest Encryption](../data-at-rest-encryption/index).

 Authentication
--------------

 All SST methods except `rsync` require authentication via username and password. You can tell the client what username and password to use by setting the `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` system variable. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)` on the node that you intend to be a SST donor. For example:

 
```
SET GLOBAL wsrep_sst_auth = 'mariabackup:password';

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up a node:

 
```
[mariadb]
...
wsrep_sst_auth = mariabackup:password

```

Some [authentication plugins](../authentication-plugins/index) do not require a password. For example, the `[unix\_socket](../authentication-plugin-unix-socket/index)` and `[gssapi](../authentication-plugin-gssapi/index)` authentication plugins do not require a password. If you are using a user account that does not require a password in order to log in, then you can just leave the password component of `[wsrep\_sst\_auth](../galera-cluster-system-variables/index#wsrep_sst_auth)` empty. For example:

 
```
[mariadb]
...
wsrep_sst_auth = mariabackup:

```

See the relevant description or page for each SST method to find out what privileges need to be [granted](../grant/index) to the user and whether the privileges are needed on the donor node or joiner node for that method.

 SSTs and Systemd
----------------

 MariaDB's `[systemd](../systemd/index)` unit file has a default startup timeout of about 90 seconds on most systems. If an SST takes longer than this default startup timeout on a joiner node, then `systemd` will assume that `mysqld` has failed to startup, which causes `systemd` to kill the `mysqld` process on the joiner node. To work around this, you can reconfigure the MariaDB `systemd` unit to have an infinite timeout, such as by executing one of the following commands:

 If you are using `systemd` 228 or older, then you can execute the following to set an infinite timeout:

 
```
sudo tee /etc/systemd/system/mariadb.service.d/timeoutstartsec.conf <<EOF
[Service]

TimeoutStartSec=0
EOF
sudo systemctl daemon-reload

```

[Systemd 229 added the infinity option](https://lists.freedesktop.org/archives/systemd-devel/2016-February/035748.html), so if you are using `systemd` 229 or later, then you can execute the following to set an infinite timeout:

 
```
sudo tee /etc/systemd/system/mariadb.service.d/timeoutstartsec.conf <<EOF
[Service]

TimeoutStartSec=infinity
EOF
sudo systemctl daemon-reload

```

See [Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for more details.

 Note that [systemd 236 added the `EXTEND_TIMEOUT_USEC` environment variable](https://lists.freedesktop.org/archives/systemd-devel/2017-December/039996.html) that allows services to extend the startup timeout during long-running processes. Starting with [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/), and [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/), on systems with systemd versions that support it, MariaDB uses this feature to extend the startup timeout during long SSTs. Therefore, if you are using `systemd` 236 or later, then you should not need to manually override `TimeoutStartSec`, even if your SSTs run for longer than the configured value. See [MDEV-15607](https://jira.mariadb.org/browse/MDEV-15607) for more information.

 SST Failure
-----------

 An SST failure generally renders the joiner node unusable. Therefore, when an SST failure is detected, the joiner node will abort.

 Restarting a node after a `mysqldump` SST failure may require manual restoration of the administrative tables.

 SSTs and Data at Rest Encryption
--------------------------------

 Look at the description of each SST method to determine which methods support [Data at Rest Encryption](../data-at-rest-encryption/index).

 For logical SST methods like `mysqldump`, each node should be able to have different [encryption keys](../data-at-rest-encryption/index#encryption-key-management). For physical SST methods, all nodes need to have the same [encryption keys](../data-at-rest-encryption/index#encryption-key-management), since the donor node will copy encrypted data files to the joiner node, and the joiner node will need to be able to decrypt them.

 Minimal Cluster Size
--------------------

 In order to avoid a split-brain condition, the minimum recommended number of nodes in a cluster is 3.

 When using an SST method that blocks the donor, there is yet another reason to require a minimum of 3 nodes. In a 3-node cluster, if one node is acting as an SST joiner and one other node is acting as an SST donor, then there is still one more node to continue executing queries.

 Manual SSTs
-----------

 In some cases, if Galera Cluster's automatic SSTs repeatedly fail, then it can be helpful to perform a "manual SST". See the following pages on how to do that:

 * [Manual SST of Galera Cluster node with Mariabackup](../manual-sst-of-galera-cluster-node-with-mariabackup/index)
* [Manual SST of Galera Cluster node with Percona XtraBackup](../manual-sst-of-galera-cluster-node-with-percona-xtrabackup/index)

 Known Issues
------------

 ### mysqld\_multi

 SST scripts can't currently read the `[mysqldN]` [option groups](../configuring-mariadb-with-option-files/index#option-groups) in [option files](../configuring-mariadb-with-option-files/index) that are read by instances managed by `[mysqld\_multi](../mysqld_multi/index)`.

 See [MDEV-18863](https://jira.mariadb.org/browse/MDEV-18863) for more information.

 See Also
--------

 * [Galera Cluster documentation: STATE SNAPSHOT TRANSFERS](https://galeracluster.com/library/documentation/sst.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/introduction-to-state-snapshot-transfers-ssts/>

Backup/Restore + Data Export/Import via dbForge Studio
======================================================

    
dbForge Studio is a proprietary third-party tool, not included with MariaDB Server. Content contributed by devart.

 
Without a doubt, you want your backup/restore and export/import operations to be fast, easy, and automated wherever possible. You can have it all that way with [dbForge Studio for MySQL](https://www.devart.com/dbforge/mysql/studio/). As the name implies, it is an IDE for MySQL development, management, and administration, yet it works just as perfectly as a [MariaDB GUI client](https://www.devart.com/dbforge/mysql/studio/mariadb-gui-client.html). Now, let's see how it tackles routine database backups.

 Create a MariaDB backup
-----------------------

 1. On the **Database** menu, go to **Backup and Restore**, and click **Backup Database** to open **Database Backup Wizard**. 

 2. On the **General** page, specify the required connection and database, the path for the backup file to be saved to, and the output file name in the respective fields. Optionally, you can append a timestamp to the file name, enable the auto-deletion of old files, and compress your backup into an archive. After you set it all up, click **Next**. 

 ![b1]

 3. On the **Backup content** page, select the content for your backup and click **Next**.

 ![b2]

 4. On the **Options** page, configure your detailed backup options—there are quite a few of those to match your requirements most precisely. Then click **Next**. 

 ![b3]

 5. On the **Errors handling** page, configure the **Errors handling** and **Log settings** options. Afterwards, click **Backup** to run the backup process. 

 Note that you have two more options here: you can select **Save Project** to save your current backup project with all the settings—or you can select **Save Command Line** to save a backup script that you can execute from the command line whenever you need. 

 ![b4]

 6. After you click **Backup**, wait for the backup process to be completed. 

 Note that you don't have to go through every wizard page to click **Backup**. You can do it whenever you've finished configuring your settings. 

 ![b5]

 7. Finally, confirm the successful completion by clicking **Finish**. 

 ![b6]

 As you can see, it's very easy. Furthermore, you can schedule to run regular backups using **Action > Create Basic Task** in **Windows Task Scheduler**. 

 Restore a MariaDB backup
------------------------

 This is an even faster task, done in half as many steps. 

 1. On the **Database** menu, go to **\*Backup and Restore**, and click **Restore Database** to open the **Database Restore Wizard**. 

 2. On the **Database Script File** page, specify the required connection and database, as well as the path to the previously saved backup file. 

 ![r1]

 3. After that, click **Restore**, and let the Studio do the rest for you. 

 And when it's done, click **Finish**, and there you have it. 

 ![r2]

 You can learn more about this functionality on the dedicated [backup/restore page](https://www.devart.com/dbforge/mysql/studio/mysql-backup.html). Please note: while the page focuses on MySQL databases, everything that's described there is just as perfectly applicable to MariaDB from the same Studio with the same workflow. 

 Export data from MariaDB
------------------------

 With dbForge Studio, you can export data to 14 most popular formats: HTML, TXT, XLS, XLSX, MDB, RTF, PDF, JSON, XML, CSV, OBSC, DBF, SQL, and Google Sheets. You can do it with an easy-to-follow wizard that guides you through the entire process and delivers quite a few customization options. 

 Let's see how it works. And before we start, note that different formats may have slightly different wizard pages. In our walkthrough, we'll take the HTML format as an example. 

 1. To open the export wizard, on the **Database** menu, click **Export Data**. 

 2. On the **Export format** page, pick the required format and click **Next**. 

 ![e1]

 3. On the **Source** page, select the required connection, database, as well as tables and views to be exported. Then click **Next**. 

 ![e2]

 4. On the **Output settings** page, specify the path for the output, select to export data into a single or several separate files, and configure a few other settings, such as timestamps and compression. Then click **Next**. 

 ![e3]

 5. On the **Options** page, configure and preview table grid options for exported data. Click **Next**. 

 ![e4]

 6. On the **Data formats** page, you have two tabs. On the **Columns** tab, you can check the list of columns to be exported. 

 ![e5]

 Then, on the **Formats** tab, you can adjust the default format settings for Date, Time, Date Time, Currency, Float, Integer, Boolean, Null String, as well as select the required binary encoding. 

 ![e6]

 Once you make sure everything is correct, click **Next**. 

 7. On the **Exported rows** page, select to export all rows or define a certain range of rows, and then click \*Next**.**

 ![e7]

 8. On the **Errors handling** page, configure the errors handling behavior and select to keep a log file, if necessary. 

 ![e8]

 But before you click **Export**, note that you can save templates with your settings for recurring export operations. To do that, click **Save** in the lower left corner of the wizard, specify a name and a destination for the template file to be saved to, and then click **Save**. 

 ![e9]

 Also note that you don't have to go through every wizard page to click **Export**. You can do it whenever you've finished configuring your settings. 

 9. Finally, after you click **Export**, watch the progress and click **Finish** upon completion. 

 ![e10]

 Done! Now, if you want, you can open the folder with the output file right away. 

 Import data into MariaDB
------------------------

 dbForge Studio supports 10 data formats for import, including TXT, XLS, XLSX, MDB, XML, JSON, CSV, ODBC, DBF, and Google Sheets. Just like with export, you have a helpful wizard at hand, whose pages may have differences, depending on the format. And let's pick a different format this time, say, the Microsoft Excel format (XLS). 

 1. To open the wizard, on the **Database** menu, click **Import Data**. 

 2. On the **Source file** page, choose the required format, select the file to import data from, and click **Next**. 

 ![i1]

 3. On the **Destination** page, select the target connection and database. Then you can select to import data either to a new table or to an existing table. Click **Next**. 

 ![i2]

 4. On the **Options** page, configure and preview table grid options for imported data. Click **Next**. 

 ![i3]

 5. On the **Data formats** page, you have two tabs. The first tab is called **Common Formats**, where you can specify the required formats for null strings, thousand and decimal separators, boolean variables, date and time. 

 ![i4]

 The second tab is called **Column Settings**, where you can configure format settings for separate columns. 

 ![i5]

 Once you make sure everything is correct, click **Next**. 

 6. On the **Mapping** page, you can map the source columns to the target ones and preview the results. If you're importing data into a new table, the Studio will automatically create and map all the columns, so you will only have to make adjustments if you wish. Then click **Next**. 

 ![i6]

 7. On the **Modes** page, select one of the 5 available import modes and click **Next**. 

 ![i7]

 8. On the **Output** page, select the preferred output option and click **Next**. 

 ![i8]

 9. On the **Errors handling** page, configure the errors handling behavior and select to keep a log file, if necessary. 

 ![i9]

 Similarly to export, you can save templates with your settings for recurring import operations. To do that, click **Save** in the lower left corner of the wizard, specify a name and a destination for the template file to be saved to, and then click **Save**. 

 ![i10]

 Also note that you don't have to go through every wizard page to click **Import**. You can do it whenever you've finished configuring your settings. 

 10. After you click **Import**, wait for the process to be completed. Then click **Finish** to confirm the successful completion, and check the results if you wish. That's it! 

 You can learn more about this functionality on the dedicated [data export/import page](https://www.devart.com/dbforge/mysql/studio/data-export-import.html). Please note: while the page focuses on MySQL databases, everything that's described there is just as perfectly applicable to MariaDB from the same Studio with the same workflow. 

 There is much more to dbForge Studio when it comes to MariaDB development and management. You can have a brief overview of its features and capabilities on [the Features page](https://www.devart.com/dbforge/mysql/studio/features.html). 

 That said, if you'd love to have a single IDE that doesn't need any 3rd-party extensions because it can perfectly deal with nearly any task on its own, feel free to [download dbForge Studio for a free 30-day trial](https://www.devart.com/dbforge/mysql/studio/download.html) and give it a go in your daily work.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-restore-and-import-clients-backuprestore-data-exportimport-via-dbfor/>

mysql.transaction\_registry Table
=================================

    The `mysql.transaction_registry` table was introduced in [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) as part of [system-versioned tables](../system-versioned-tables/index). It is used for transaction-precise versioning, and contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| transaction\_id | bigint(20) unsigned | NO | Primary | NULL |  |
| commit\_id | bigint(20) unsigned | NO | Unique | NULL |  |
| begin\_timestamp | timestamp(6) | NO | Multiple | 0000-00-00 00:00:00.000000 | Timestamp when the transaction began (BEGIN statement), however see [MDEV-16024](https://jira.mariadb.org/browse/MDEV-16024). |
| commit | timestamp(6) | NO | Multiple | 0000-00-00 00:00:00.000000 | Timestamp when the transaction was committed. |
| isolation\_level | enum('READ-UNCOMMITTED','READ-COMMITTED','REPEATABLE-READ','SERIALIZABLE') | NO |  | NULL | Transaction [isolation level](../set-transaction/index#isolation-levels). |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltransaction_registry-table/>

Manual SST of Galera Cluster Node With Percona XtraBackup
=========================================================

    
Mariabackup should be used instead of XtraBackup on all supported releases. See [manual SST with Mariabackup](../manual-sst-of-galera-cluster-node-with-mariabackup/index).

 

In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

  Sometimes it can be helpful to perform a "manual SST" when Galera's [normal SSTs](../introduction-to-state-snapshot-transfers-ssts/index) fail. This can be especially useful when the cluster's `[datadir](../server-system-variables/index#datadir)` is very large, since a normal SST can take a long time to fail in that case.

 A manual SST essentially consists of taking a backup of the donor, loading the backup on the joiner, and then manually editing the cluster state on the joiner node. This page will show how to perform this process with [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index).

 Process
-------

 * Check that the donor and joiner nodes have the same XtraBackup version.

 
```
innobackupex --version

```

* Create backup directory on donor.

 
```
MYSQL_BACKUP_DIR=/mysql_backup
mkdir $MYSQL_BACKUP_DIR

```

* Take a [full backup](https://www.percona.com/doc/percona-xtrabackup/2.4/howtos/recipes_ibkx_local.html) the of the donor node with `innobackupex`. The `[--galera-info](https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/innobackupex_option_reference.html#cmdoption-innobackupex-galera-info)` option should also be provided, so that the node's cluster state is also backed up.

 
```
DB_USER=sstuser
DB_USER_PASS=password
innobackupex --user=$DB_USER --password=$DB_USER_PASS --galera-info --no-timestamp $MYSQL_BACKUP_DIR

```

* Verify that the MariaDB Server process is stopped on the joiner node. This will depend on your [service manager](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 For example, on [systemd](../systemd/index) systems, you can execute::

 
```
systemctl status mariadb

```

* Create the backup directory on the joiner node.

 
```
MYSQL_BACKUP_DIR=/mysql_backup
mkdir $MYSQL_BACKUP_DIR

```

* Copy the backup from the donor node to the joiner node.

 
```
OS_USER=dba
JOINER_HOST=dbserver2.mariadb.com
rsync -av $MYSQL_BACKUP_DIR/* ${OS_USER}@${JOINER_HOST}:${MYSQL_BACKUP_DIR}

```

* [Prepare the backup](https://www.percona.com/doc/percona-xtrabackup/2.4/howtos/recipes_ibkx_local.html#prepare-the-backup) on the joiner node.

 
```
innobackupex --apply-log $MYSQL_BACKUP_DIR

```

* Get the Galera Cluster version ID from the donor node's `grastate.dat` file.

 
```
MYSQL_DATADIR=/var/lib/mysql
cat $MYSQL_DATADIR/grastate.dat | grep version

```

For example, a very common version number is "2.1".

 * Get the node's cluster state from the `[--xtrabackup\_galera\_info](https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/innobackupex_option_reference.html#cmdoption-innobackupex-galera-info)` file in the backup that was copied to the joiner node.

 
```
cat $MYSQL_BACKUP_DIR/xtrabackup_galera_info

```

Example output:

 
```
d38587ce-246c-11e5-bcce-6bbd0831cc0f:1352215

```

This output is in the format:

 
```
uuid:seqno

```

* Create a `grastate.dat` file in the backup directory of the joiner node. The Galera Cluster version ID, the cluster uuid, and the seqno from previous steps will be used to fill in the relevant fields.

 For example, with the example values from the last two steps, we could do:

 
```
sudo tee $MYSQL_BACKUP_DIR/grastate.dat <<EOF
# GALERA saved state
version: 2.1
uuid:    d38587ce-246c-11e5-bcce-6bbd0831cc0f
seqno:   1352215
safe_to_bootstrap: 0
EOF

```

* Remove the existing contents of the `[datadir](../server-system-variables/index#datadir)` on the joiner node.

 
```
MYSQL_DATADIR=/var/lib/mysql
rm -Rf $MYSQL_DATADIR/*

```

* Copy the contents of the backup directory to the `[datadir](../server-system-variables/index#datadir)` the on joiner node.

 
```
cp -R $MYSQL_BACKUP_DIR/* $MYSQL_DATADIR/

```

* Make sure the permissions of the `[datadir](../server-system-variables/index#datadir)` are correct on the joiner node.

 
```
chown -R mysql:mysql $MYSQL_DATADIR/

```

* Start the MariaDB Server process on the joiner node. This will depend on your [service manager](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).

 For example, on [systemd](../systemd/index) systems, you can execute::

 
```
systemctl start mariadb

```

* Watch the MariaDB [error log](../error-log/index) on the joiner node and verify that the node does not need to perform a [normal SSTs](../introduction-to-state-snapshot-transfers-ssts/index) due to the manual SST.

 
```
tail -f /var/log/mysql/mysqld.log

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/manual-sst-of-galera-cluster-node-with-percona-xtrabackup/>

Generated (Virtual and Persistent/Stored) Columns
=================================================

    Syntax
------

 
```
<type>  [GENERATED ALWAYS]  AS   ( <expression> )
[VIRTUAL | PERSISTENT | STORED]  [UNIQUE] [UNIQUE KEY] [COMMENT <text>]

```
 MariaDB's generated columns syntax is designed to be similar to the syntax for [Microsoft SQL Server's computed columns](https://docs.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-2017) and [Oracle Database's virtual columns](https://oracle-base.com/articles/11g/virtual-columns-11gr1). In [MariaDB 10.2](../what-is-mariadb-102/index) and later, the syntax is also compatible with the syntax for [MySQL's generated columns](https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html).

 Description
-----------

 A generated column is a column in a table that cannot explicitly be set to a specific value in a [DML query](../data-manipulation/index). Instead, its value is automatically generated based on an expression. This expression might generate the value based on the values of other columns in the table, or it might generate the value by calling [built-in functions](../built-in-functions/index) or [user-defined functions (UDFs)](../user-defined-functions/index).

 There are two types of generated columns:

 * `PERSISTENT` (a.k.a. `STORED`): This type's value is actually stored in the table.
* `VIRTUAL`: This type's value is not stored at all. Instead, the value is generated dynamically when the table is queried. This type is the default.

 Generated columns are also sometimes called computed columns or virtual columns.

 Supported Features
------------------

 ### Storage Engine Support

 * Generated columns can only be used with storage engines which support them. If you try to use a storage engine that does not support them, then you will see an error similar to the following:

 
```
ERROR 1910 (HY000): TokuDB storage engine does not support computed columns

```

* [InnoDB](../innodb/index), [Aria](../aria/index), [MyISAM](../myisam/index) and [CONNECT](../using-connect-virtual-and-special-columns/index) support generated columns.

 * A column in a [MERGE](../merge/index) table can be built on a `PERSISTENT` generated column.
	+ However, a column in a MERGE table can **not** be defined as a `VIRTUAL` and `PERSISTENT` generated column.

 ### Data Type Support

 * All data types are supported when defining generated columns.

 * Using the [ZEROFILL](../create-table/index#zerofill-column-option) column option is supported when defining generated columns.

 * Using the [AUTO\_INCREMENT](../auto_increment/index) column option is **not** supported when defining generated columns. Until [MariaDB 10.2.25](https://mariadb.com/kb/en/mariadb-10225-release-notes/), it was supported, but this support was removed, because it would not work correctly. See [MDEV-11117](https://jira.mariadb.org/browse/MDEV-11117).

 ### Index Support

 * Using a generated column as a table's primary key is **not** supported. See [MDEV-5590](https://jira.mariadb.org/browse/MDEV-5590) for more information. If you try to use one as a primary key, then you will see an error similar to the following:

 
```
ERROR 1903 (HY000): Primary key cannot be defined upon a computed column

```

* Using `PERSISTENT` generated columns as part of a [foreign key](../foreign-keys/index) is supported.

 * Referencing `PERSISTENT` generated columns as part of a [foreign key](../foreign-keys/index) is also supported.
	+ However, using the `ON UPDATE CASCADE`, `ON UPDATE SET NULL`, or `ON DELETE SET NULL` clauses is **not** supported. If you try to use an unsupported clause, then you will see an error similar to the following:

 
```
ERROR 1905 (HY000): Cannot define foreign key with ON UPDATE SET NULL clause on a computed column

```

* Defining indexes on both `VIRTUAL` and `PERSISTENT` generated columns is supported.
	+ If an index is defined on a generated column, then the optimizer considers using it in the same way as indexes based on "real" columns.

 ### Statement Support

 * Generated columns are used in [DML queries](../data-manipulation/index) just as if they were "real" columns.
	+ However, `VIRTUAL` and `PERSISTENT` generated columns differ in how their data is stored.
		- Values for `PERSISTENT` generated columns are generated whenever a [DML queries](../data-manipulation/index) inserts or updates the row with the special `DEFAULT` value. This generates the columns value, and it is stored in the table like the other "real" columns. This value can be read by other [DML queries](../data-manipulation/index) just like the other "real" columns.
		- Values for `VIRTUAL` generated columns are not stored in the table. Instead, the value is generated dynamically whenever the column is queried. If other columns in a row are queried, but the `VIRTUAL` generated column is not one of the queried columns, then the column's value is not generated.

 * The [SELECT](../select/index) statement supports generated columns.

 * Generated columns can be referenced in the [INSERT](../insert/index), [UPDATE](../update/index), and [DELETE](../delete/index) statements.
	+ However, `VIRTUAL` or `PERSISTENT` generated columns cannot be explicitly set to any other values than `NULL` or [DEFAULT](../default/index). If a generated column is explicitly set to any other value, then the outcome depends on whether [strict mode](../sql-mode/index#strict-mode) is enabled in [sql\_mode](../sql-mode/index). If it is not enabled, then a warning will be raised and the default generated value will be used instead. If it is enabled, then an error will be raised instead.

 * The [CREATE TABLE](../create-table/index) statement has limited support for generated columns.
	+ It supports defining generated columns in a new table.
	+ It supports using generated columns to [partition tables](../partitioning-tables/index).
	+ It does **not** support using the [versioning clauses](../system-versioned-tables/index) with generated columns.

 * The [ALTER TABLE](../alter-table/index) statement has limited support for generated columns.
	+ It supports the `MODIFY` and `CHANGE` clauses for `PERSISTENT` generated columns.
	+ It does **not** support the `MODIFY` clause for `VIRTUAL` generated columns if [ALGORITHM](../alter-table/index#algorithm) is not set to `COPY`. See [MDEV-15476](https://jira.mariadb.org/browse/MDEV-15476) for more information.
	+ It does **not** support the `CHANGE` clause for `VIRTUAL` generated columns if [ALGORITHM](../alter-table/index#algorithm) is not set to `COPY`. See [MDEV-17035](https://jira.mariadb.org/browse/MDEV-17035) for more information.
	+ It does **not** support altering a table if [ALGORITHM](../alter-table/index#algorithm) is not set to `COPY` if the table has a `VIRTUAL` generated column that is indexed. See [MDEV-14046](https://jira.mariadb.org/browse/MDEV-14046) for more information.
	+ It does **not** support adding a `VIRTUAL` generated column with the `ADD` clause if the same statement is also adding other columns if [ALGORITHM](../alter-table/index#algorithm) is not set to `COPY`. See [MDEV-17468](https://jira.mariadb.org/browse/MDEV-17468) for more information.
	+ It also does **not** support altering an existing column into a `VIRTUAL` generated column.
	+ It supports using generated columns to [partition tables](../partitioning-tables/index).
	+ It does **not** support using the [versioning clauses](../system-versioned-tables/index) with generated columns.

 * The [SHOW CREATE TABLE](../show-create-table/index) statement supports generated columns.

 * The [DESCRIBE](../describe/index) statement can be used to check whether a table has generated columns.
	+ You can tell which columns are generated by looking for the ones where the `Extra` column is set to either `VIRTUAL` or `PERSISTENT`. For example:

 
```
DESCRIBE table1;
+-------+-------------+------+-----+---------+------------+
| Field | Type        | Null | Key | Default | Extra      |
+-------+-------------+------+-----+---------+------------+
| a     | int(11)     | NO   |     | NULL    |            |
| b     | varchar(32) | YES  |     | NULL    |            |
| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |
| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |
+-------+-------------+------+-----+---------+------------+

```

* Generated columns can be properly referenced in the `NEW` and `OLD` rows in [triggers](../triggers/index).

 * [Stored procedures](../stored-procedures/index) support generated columns.

 * The [HANDLER](../handler-commands/index) statement supports generated columns.

 ### Expression Support

 * Most legal, deterministic expressions which can be calculated are supported in expressions for generated columns.

 * Most [built-in functions](../built-in-functions/index) are supported in expressions for generated columns.
	+ However, some [built-in functions](../built-in-functions/index) can't be supported for technical reasons. For example, If you try to use an unsupported function in an expression, an error is generated similar to the following:

 
```
ERROR 1901 (HY000): Function or expression 'dayname()' cannot be used in the GENERATED ALWAYS AS clause of `v`

```

* [Subqueries](../subqueries/index) are **not** supported in expressions for generated columns because the underlying data can change.

 * Using anything that depends on data outside the row is **not** supported in expressions for generated columns.

 * [Stored functions](../stored-functions/index) are **not** supported in expressions for generated columns. See [MDEV-17587](https://jira.mariadb.org/browse/MDEV-17587) for more information.

 * Non-deterministic [built-in functions](../built-in-functions/index) are supported in expressions for not indexed `VIRTUAL` generated columns.

 * Non-deterministic [built-in functions](../built-in-functions/index) are **not** supported in expressions for `PERSISTENT` or indexed `VIRTUAL` generated columns.

 * [User-defined functions (UDFs)](../user-defined-functions/index) are supported in expressions for generated columns.
	+ However, MariaDB can't check whether a UDF is deterministic, so it is up to the user to be sure that they do not use non-deterministic UDFs with `VIRTUAL` generated columns.

 * Defining a generated column based on other generated columns defined before it in the table definition is supported. For example:

 
```
CREATE TABLE t1 (a int as (1), b int as (a));

```

* However, defining a generated column based on other generated columns defined after in the table definition is **not** supported in expressions for generation columns because generated columns are calculated in the order they are defined.

 * Using an expression that exceeds 255 characters in length is supported in expressions for generated columns. The new limit for the entire table definition, including all expressions for generated columns, is 65,535 bytes.

 * Using constant expressions is supported in expressions for generated columns. For example:

 
```
CREATE TABLE t1 (a int as (1));

```

### Making Stored Values Consistent

 When a generated column is `PERSISTENT` or indexed, the value of the expression needs to be consistent regardless of the [SQL Mode](../sql-mode/index) flags in the current session. If it is not, then the table will be seen as corrupted when the value that should actually be returned by the computed expression and the value that was previously stored and/or indexed using a different [sql\_mode](../sql-mode/index) setting disagree.

 There are currently two affected classes of inconsistencies: character padding and unsigned subtraction:

 * For a `VARCHAR` or `TEXT` generated column the length of the value returned can vary depending on the PAD\_CHAR\_TO\_FULL\_LENGTH [sql\_mode](../sql-mode/index) flag. To make the value consistent, create the generated column using an RTRIM() or RPAD() function. Alternately, create the generated column as a `CHAR` column so that its data is always fully padded.

 * If a `SIGNED` generated column is based on the subtraction of an `UNSIGNED` value, the resulting value can vary depending on how large the value is and the NO\_UNSIGNED\_SUBTRACTION [sql\_mode](../sql-mode/index) flag. To make the value consistent, use [CAST()](../cast/index) to ensure that each `UNSIGNED` operand is `SIGNED` before the subtraction.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**Beginning in [MariaDB 10.5](../what-is-mariadb-105/index), there is a fatal error generated when trying to create a generated column whose value can change depending on the [SQL Mode](../sql-mode/index) when its data is `PERSISTENT` or indexed.

 For an existing generated column that has a potentially inconsistent value, a warning about a bad expression is generated the first time it is used (if warnings are enabled).

 Beginning in [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/), [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/), and [MariaDB 10.2.27](https://mariadb.com/kb/en/mariadb-10227-release-notes/) a potentially inconsistent generated column outputs a warning when created or first used (without restricting their creation).

 
Here is an example of two tables that would be rejected in [MariaDB 10.5](../what-is-mariadb-105/index) and warned about in the other listed versions:

 
```
CREATE TABLE bad_pad (
  txt CHAR(5),
  -- CHAR -> VARCHAR or CHAR -> TEXT can't be persistent or indexed:
  vtxt VARCHAR(5) AS (txt) PERSISTENT
);

CREATE TABLE bad_sub (
  num1 BIGINT UNSIGNED,
  num2 BIGINT UNSIGNED,
  -- The resulting value can vary for some large values
  vnum BIGINT AS (num1 - num2) VIRTUAL,
  KEY(vnum)
);

```

The warnings for the above tables look like this:

 
```
Warning (Code 1901): Function or expression '`txt`' cannot be used in the GENERATED ALWAYS AS clause of `vtxt`
Warning (Code 1105): Expression depends on the @@sql_mode value PAD_CHAR_TO_FULL_LENGTH

Warning (Code 1901): Function or expression '`num1` - `num2`' cannot be used in the GENERATED ALWAYS AS clause of `vnum`
Warning (Code 1105): Expression depends on the @@sql_mode value NO_UNSIGNED_SUBTRACTION

```

To work around the issue, force the padding or type to make the generated column's expression return a consistent value. For example:

 
```
CREATE TABLE good_pad (
  txt CHAR(5),
  -- Using RTRIM() or RPAD() makes the value consistent:
  vtxt VARCHAR(5) AS (RTRIM(txt)) PERSISTENT,
  -- When not persistent or indexed, it is OK for the value to vary by mode:
  vtxt2 VARCHAR(5) AS (txt) VIRTUAL,
  -- CHAR -> CHAR is always OK:
  txt2 CHAR(5) AS (txt) PERSISTENT
);

CREATE TABLE good_sub (
  num1 BIGINT UNSIGNED,
  num2 BIGINT UNSIGNED,
  -- The indexed value will always be consistent in this expression:
  vnum BIGINT AS (CAST(num1 AS SIGNED) - CAST(num2 AS SIGNED)) VIRTUAL,
  KEY(vnum)
);

```

### MySQL Compatibility Support

 * The `STORED` keyword is supported as an alias for the `PERSISTENT` keyword.

 * Tables created with MySQL 5.7 or later that contain [MySQL's generated columns](https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html) can be imported into MariaDB without a dump and restore.

 Implementation Differences
--------------------------

 Generated columns are subject to various constraints in other DBMSs that are not present in MariaDB's implementation. Generated columns may also be called computed columns or virtual columns in different implementations. The various details for a specific implementation can be found in the documentation for each specific DBMS.

 ### Implementation Differences Compared to Microsoft SQL Server

 MariaDB's generated columns implementation does not enforce the following restrictions that are present in [Microsoft SQL Server's computed columns](https://docs.microsoft.com/en-us/sql/relational-databases/tables/specify-computed-columns-in-a-table?view=sql-server-2017) implementation:

 * MariaDB allows [server variables](../system-variables/index) in generated column expressions, including those that change dynamically, such as [warning\_count](../server-system-variables/index#warning_count).
* MariaDB allows the [CONVERT\_TZ()](../convert_tz/index) function to be called with a named [time zone](../time-zones/index) as an argument, even though time zone names and time offsets are configurable.
* MariaDB allows the [CAST()](../cast/index) function to be used with non-unicode [character sets](../data-types-character-sets-and-collations/index), even though character sets are configurable and differ between binaries/versions.
* MariaDB allows [FLOAT](../float/index) expressions to be used in generated columns. Microsoft SQL Server considers these expressions to be "imprecise" due to potential cross-platform differences in floating-point implementations and precision.
* Microsoft SQL Server requires the [ARITHABORT](https://docs.microsoft.com/en-us/sql/t-sql/statements/set-arithabort-transact-sql?view=sql-server-2017) mode to be set, so that division by zero returns an error, and not a NULL.
* Microsoft SQL Server requires `QUOTED_IDENTIFIER` to be set in [sql\_mode](../sql-mode/index). In MariaDB, if data is inserted without `ANSI_QUOTES` set in [sql\_mode](../sql-mode/index), then it will be processed and stored differently in a generated column that contains quoted identifiers.

 Microsoft SQL Server enforces the above restrictions by doing one of the following things:

 * Refusing to create computed columns.
* Refusing to allow updates to a table containing them.
* Refusing to use an index over such a column if it can not be guaranteed that the expression is fully deterministic.

 In MariaDB, as long as the [sql\_mode](../sql-mode/index), language, and other settings that were in effect during the CREATE TABLE remain unchanged, the generated column expression will always be evaluated the same. If any of these things change, then please be aware that the generated column expression might not be evaluated the same way as it previously was.

 If you try to update a virtual column, you will get an error if the default [strict mode](../sql-mode/index#strict-mode) is enabled in [sql\_mode](../sql-mode/index), or a warning otherwise.

 Development History
-------------------

 Generated columns was originally developed by Andrey Zhakov. It was then modified by Sanja Byelkin and Igor Babaev at Monty Program for inclusion in MariaDB. Monty did the work on [MariaDB 10.2](../what-is-mariadb-102/index) to lift a some of the old limitations.

 Examples
--------

 Here is an example table that uses both `VIRTUAL` and `PERSISTENT` virtual columns:

 
```
USE TEST;

CREATE TABLE table1 (
     a INT NOT NULL,
     b VARCHAR(32),
     c INT AS (a mod 10) VIRTUAL,
     d VARCHAR(5) AS (left(b,5)) PERSISTENT);

```

If you describe the table, you can easily see which columns are virtual by looking in the "Extra" column:

 
```
DESCRIBE table1;
+-------+-------------+------+-----+---------+------------+
| Field | Type        | Null | Key | Default | Extra      |
+-------+-------------+------+-----+---------+------------+
| a     | int(11)     | NO   |     | NULL    |            |
| b     | varchar(32) | YES  |     | NULL    |            |
| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |
| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |
+-------+-------------+------+-----+---------+------------+

```

To find out what function(s) generate the value of the virtual column you can use `SHOW CREATE TABLE`:

 
```
SHOW CREATE TABLE table1;

| table1 | CREATE TABLE `table1` (
  `a` int(11) NOT NULL,
  `b` varchar(32) DEFAULT NULL,
  `c` int(11) AS (a mod 10) VIRTUAL,
  `d` varchar(5) AS (left(b,5)) PERSISTENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

```

If you try to insert non-default values into a virtual column, you will receive a warning and what you tried to insert will be ignored and the derived value inserted instead:

 
```
WARNINGS;
Show warnings enabled.

INSERT INTO table1 VALUES (1, 'some text',default,default);
Query OK, 1 row affected (0.00 sec)

INSERT INTO table1 VALUES (2, 'more text',5,default);
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1645): The value specified for computed column 'c' in table 'table1' has been ignored.

INSERT INTO table1 VALUES (123, 'even more text',default,'something');
Query OK, 1 row affected, 2 warnings (0.00 sec)

Warning (Code 1645): The value specified for computed column 'd' in table 'table1' has been ignored.
Warning (Code 1265): Data truncated for column 'd' at row 1

SELECT * FROM table1;
+-----+----------------+------+-------+
| a   | b              | c    | d     |
+-----+----------------+------+-------+
|   1 | some text      |    1 | some  |
|   2 | more text      |    2 | more  |
| 123 | even more text |    3 | even  |
+-----+----------------+------+-------+
3 rows in set (0.00 sec)

```

If the `ZEROFILL` clause is specified, it should be placed directly after the type definition, before the `AS (<expression>)`:

 
```
CREATE TABLE table2 (a INT, b INT ZEROFILL AS (a*2) VIRTUAL);
INSERT INTO table2 (a) VALUES (1);

SELECT * FROM table2;
+------+------------+
| a    | b          |
+------+------------+
|    1 | 0000000002 |
+------+------------+
1 row in set (0.00 sec)

```

You can also use virtual columns to implement a "poor man's partial index". See example at the end of [Unique Index](../getting-started-with-indexes/index#unique-index).

 See Also
--------

 * [Putting Virtual Columns to good use](https://mariadb.com/blog/putting-virtual-columns-good-use) on the mariadb.com blog.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/virtual-columns/>

Aria FAQ
========

    This FAQ provides information on the [Aria](../aria/index) storage engine.

 
The ***Aria*** storage engine was previously known as ***Maria***, (see, the [Aria Name](../the-aria-name/index)). In current releases of [MariaDB](../mariadb/index), you can refer to the engine as Maria or Aria. As this will change in future releases, please update references in your scripts and automation to use the correct name.

  What is Aria?
-------------

 Aria is a storage engine for MySQL® and MariaDB. It was originally developed with the goal of becoming the default transactional **and** non-transactional storage engine for MariaDB and MySQL. 

 It has been in development since 2007 and was first announced on Monty's [blog](http://monty-says.blogspot.com/2008/01/maria-engine-is-released.html). The same core MySQL engineers who developed the MySQL server and the [MyISAM](../myisam/index), [MERGE](../merge/index), and [MEMORY](../memory-storage-engine/index) storage engines are also working on Aria.

 Why is the engine called Aria?
------------------------------

 Originally, the storage engine was called **Maria**, after Monty's younger daughter. Monty named MySQL after his first child, **My** and his second child **Max** gave his name to MaxDB and the MySQL-Max distributions.

 In practice, having both *MariaDB* the database server and *Maria* the storage engine with such similar names proved confusing. To mitigate this, the decision was made to change the name. A Rename Maria contest was held during the first half of 2010 and names were submitted from around the world. Monty picked the name ***Aria*** from a short list of finalist. Chris Tooley, who suggested it, received the prize of a Linux-powered [System 76 Meerkat NetTop](http://www.system76.com/product_info.php?cPath=27&products_id=91) from Monty Program.

 For more information, see the [Aria Name](../the-aria-name/index).

 What's the goal for the current version?
----------------------------------------

 The current version of Aria is 1.5. The goal of this release is to develop a crash-safe alternative to MyISAM. That is, when MariaDB restarts after a crash, Aria recovers all tables to the state as of the start of a statement or at the start of the last `LOCK TABLES` statement.

 The current goal is to keep the code stable and fix all bugs.

 What's the goal for the next version?
-------------------------------------

 The next version of Aria is 2.0. The goal for this release is to develop a fully transactional storage engine with at least all the major features of InnoDB.

 Currently, Aria 2.0 is on hold as its developers are focusing on improving MariaDB. However, they are interested in working with interested customers and partners to add more features to Aria and eventually release 2.0.

 These are some of the goals for Aria 2.0:

 * ACID compliant
* Commit/Rollback
* Concurrent updates/deletes
* Row locking
* Group commit (Already in [MariaDB 5.2](../what-is-mariadb-52/index))
* Faster lookup in index pages (Page directory)

 Beginning in Aria 2.5, the plan is to focus on improving performance.

 What is the ultimate goal of Aria?
----------------------------------

 Long term, we have the following goals for Aria:

 * To create a new, ACID and Multi-Version Concurrency Control (MVCC), transactional storage engine that can function as both the default non-transactional and transactional storage engine for MariaDB and MySQL®.
* To be a MyISAM replacement. This is possible because Aria can also be run in non-transactional mode, supports the same row formats as MyISAM, and supports or will support all major features of MyISAM.
* To be the default non-transactional engine in MariaDB (instead of MyISAM).

 What are the design goals in Aria?
----------------------------------

 * Multi-Version Concurrency Control (MVCC) and ACID storage engine.
* Optionally non-transactional tables that should be 'as fast and as compact' as MyISAM tables.
* Be able to use Aria for internal temporary tables in MariaDB (instead of MyISAM).
* All indexes should have equal speed (clustered index is not on our current road map for Aria. If you need clustered index, you should use XtraDB).
* Allow 'any' length transactions to work (Having long running transactions will cause more log space to be used).
* Allow log shipping; that is, you can do incremental backups of Aria tables just by copying the Aria logs.
* Allow copying of Aria tables between different Aria servers (under some well-defined constraints).
* Better blob handling (than is currently offered in MyISAM, at a minimum).
* No memory copying or extra memory used for blobs on insert/update.
* Blobs allocated in big sequential blocks - Less fragmentation over time.
* Blobs are stored so that Aria can easily be extended to have access to any part of a blob with a single fetch in the future.
* Efficient storage on disk (that is, low row data overhead, low page data overhead and little lost space on pages). Note: There is still some more work to succeed with this goal. The disk layout is fine, but we need more in-memory caches to ensure that we get a higher fill factor on the pages.
* Small footprint, to make MariaDB + Aria suitable for desktop and embedded applications.
* Flexible memory allocation and scalable algorithms to utilize large amounts of memory efficiently, when it is available.

 Where can I find documentation and help about Aria?
---------------------------------------------------

 Documentation is available at [Aria](../aria/index) and related topics. The project is maintained on [GitHub](https://github.com/MariaDB/server).

 If you want to know what happens or be part of developing Aria, you can subscribe to the [developers](https://lists.mariadb.org/postorius/lists/developers.lists.mariadb.org/), [docs](https://lists.mariadb.org/postorius/lists/docs.lists.mariadb.org/), or [discuss](https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/) mailing lists.

 To report and check bugs in Aria, see [Reporting Bugs](../reporting-bugs/index).

 You can usually find some of the Maria developers on our Zulip instance at <https://mariadb.zulipchat.com> or on the [IRC](../irc/index) channel #maria at <https://libera.chat/>.

 Who develops Aria?
------------------

 The Core Team who develop Aria are:

 **Technical lead**

 * Michael "Monty" Widenius - Creator of MySQL and MyISAM

 **Core Developers (in alphabetical order)**

 * Guilhem Bichot - Replication expert, on line backup for MyISAM, etc.
* Kristian Nielsen - MySQL build tools, NDB, MySQL server
* Oleksandr Byelkin - Query cache, sub-queries, views.
* Sergei Golubchik - Server Architect, Full text search, keys for MyISAM-Merge, Plugin architecture, etc.

 All except Guilhem Bichot are working for [MariaDB Corporation Ab](http://mariadb.com).

 What is the release policy/schedule of Aria?
--------------------------------------------

 Aria follows the same [release criteria](../release-criteria/index) as for [MariaDB](../mariadb/index). Some clarifications, unique for the Aria storage engine:

 * Aria index and data file formats should be backwards and forwards compatible to ensure easy upgrades and downgrades.
* The [log file](../aria-storage-engine/index#aria-log-files) format should also be compatible, but we don't make any guarantees yet. In some cases when upgrading, you must remove the old `aria_log.%` and `maria_log.%` files before restarting MariaDB. (So far, this has only occurred in the upgrade from [MariaDB 5.1](../what-is-mariadb-51/index) and [MariaDB 5.2](../what-is-mariadb-52/index)).

 ### Extended commitment for Beta 1.5

 * Aria is now feature complete according to specification.

 How does Aria 1.5 Compare to MyISAM?
------------------------------------

 Aria 1.0 was basically a crash-safe non-transactional version of MyISAM. Aria 1.5 added more concurrency (multiple inserter) and some optimizations.

 Aria supports all aspects of MyISAM, except as noted below. This includes external and internal check/repair/compressing of rows, different row formats, different index compress formats, `[aria\_chk](../aria_chk/index)` etc. After a normal shutdown you can copy Aria files between servers.

 Advantages of Aria compared to MyISAM
-------------------------------------

 * Data and indexes are crash safe.
* On a crash, changes will be rolled back to state of the start of a statement or a last `LOCK TABLES` statement.
* Aria can replay almost everything from the log. (Including `CREATE`, `DROP`, `RENAME`, `TRUNCATE` tables). Therefore, you make a backup of Aria by just copying the log. The things that can't be replayed (yet) are:
	+ Batch `INSERT` into an empty table (This includes `LOAD DATA INFILE`, `SELECT... INSERT` and `INSERT` (many rows)).
	+ `ALTER TABLE`. Note that `.frm` tables are NOT recreated!
* `LOAD INDEX` can skip index blocks for unwanted indexes.
* Supports all MyISAM `ROW` formats and new `PAGE` format where data is stored in pages. (default size is 8K).
* Multiple concurrent inserters into the same table.
* When using `PAGE` format (default) row data is cached by page cache.
* Aria has unit tests of most parts.
* Supports both crash-safe (soon to be transactional) and not transactional tables. (Non-transactional tables are not logged and rows uses less space): `CREATE TABLE foo (...) TRANSACTIONAL=0|1 ENGINE=Aria`.
* `PAGE` is the only crash-safe/transactional row format.
* `PAGE` format should give a notable speed improvement on systems which have bad data caching. (For example Windows).
* From [MariaDB 10.5](../what-is-mariadb-105/index), max key length is 2000 bytes, compared to 1000 bytes in MyISAM.

 Differences between Aria and MyISAM
-----------------------------------

 * Aria uses BIG (1G by default) [log files](../aria-storage-engine/index#aria-log-files).
* Aria has a log control file (`aria_log_control`) and log files (`aria_log.%`). The log files can be automatically purged when not needed or purged on demand (after backup).
* Aria uses 8K pages by default (MyISAM uses 1K). This makes Aria a bit faster when using keys of fixed size, but slower when using variable-length packed keys (until we add a directory to index pages).

 Disadvantages of Aria compared to MyISAM
----------------------------------------

 * Aria doesn't support `INSERT DELAYED`.
* Aria does not support multiple key caches.
* Storage of very small rows (< 25 bytes) are not efficient for `PAGE` format.
* `MERGE` tables don't support Aria (should be very easy to add later).
* Aria data pages in block format have an overhead of 10 bytes/page and 5 bytes/row. Transaction and multiple concurrent-writer support will use an extra overhead of 7 bytes for new rows, 14 bytes for deleted rows and 0 bytes for old compacted rows.
* No external locking (MyISAM has external locking, but this is a rarely used feature).
* Aria has one page size for both index and data (defined when Aria is used the first time). MyISAM supports different page sizes per index.
* Small overhead (15 bytes) per index page.
* Aria doesn't support MySQL internal RAID (disabled in MyISAM too, it's a deprecated feature).
* Minimum data file size for PAGE format is 16K (with 8K pages).
* Aria doesn't support indexes on virtual fields.

 Differences between [MariaDB 5.1](../what-is-mariadb-51/index) release and the normal MySQL-5.1 release?
--------------------------------------------------------------------------------------------------------

 See:

 * [Aria storage engine](../aria-storage-engine/index)
* [MariaDB versus MySQL](../mariadb-versus-mysql/index)

 Why do you use the `TRANSACTIONAL` keyword now when Aria is not yet transactional?
----------------------------------------------------------------------------------

 In the current development phase Aria tables created with `TRANSACTIONAL=1` are crash safe and atomic but not transactional because changes in Aria tables can't be rolled back with the `ROLLBACK` command. As we planned to make Aria tables fully transactional, we decided it was better to use the `TRANSACTIONAL` keyword from the start so so that applications don't need to be changed later.

 What are the known problems with the MySQL-5.1-Maria release?
-------------------------------------------------------------

 * See `KNOWN_BUGS.txt` for open/design bugs.
* See jira.mariadb.org for newly reported bugs. Please report anything you can't find here!
* If there is a bug in the Aria recovery code or in the code that generates the logs, or if the logs become corrupted, then mysqld may fail to start because Aria can't execute the logs at start up.
* Query cache and concurrent insert using page row format have a bug, please disable query cache while using page row format and [MDEV-6817](https://jira.mariadb.org/browse/MDEV-6817) isn't complete

 If Aria doesn't start or you have an unrecoverable table (shouldn't happen):

 * Remove the `aria_log.%` files from the data directory.
* Restart `mysqld` and run [CHECK TABLE](../check-table/index), [REPAIR TABLE](../repair-table/index) or [mariadb-check](../mariadb-check/index) on your Aria tables.

 Alternatively,

 * Remove logs and run [aria\_chk](../aria_chk/index) on your `*.MAI` files.

 What is going to change in later Aria main releases?
----------------------------------------------------

 The `LOCK TABLES` statement will not start a crash-safe segment. You should use [BEGIN](begin) and [COMMIT](../commit/index) instead. 

 To make things future safe, you could do this:

 
```
BEGIN;
LOCK TABLES ....
UNLOCK TABLES;
COMMIT;

```

And later you can just remove the `LOCK TABLES` and `UNLOCK TABLES` statements. 

 How can I create a MyISAM-like (non-transactional) table in Aria?
-----------------------------------------------------------------

 Example:

 
```
CREATE TABLE t1 (a int) ROW_FORMAT=FIXED TRANSACTIONAL=0 PAGE_CHECKSUM=0;
CREATE TABLE t2 (a int) ROW_FORMAT=DYNAMIC TRANSACTIONAL=0 PAGE_CHECKSUM=0;
SHOW CREATE TABLE t1;
SHOW CREATE TABLE t2;

```

Note that the rows are not cached in the page cache for `FIXED` or `DYNAMIC` format. If you want to have the data cached (something MyISAM doesn't support) you should use `ROW_FORMAT=PAGE`:

 
```
CREATE TABLE t3 (a int) ROW_FORMAT=PAGE TRANSACTIONAL=0 PAGE_CHECKSUM=0;
SHOW CREATE TABLE t3;

```

You can use `PAGE_CHECKSUM=1` also for non-transactional tables; This puts a page checksums on all index pages. It also puts a checksum on data pages if you use `ROW_FORMAT=PAGE`.

 You may still have a speed difference (may be slightly positive or negative) between MyISAM and Aria because of different page sizes. You can change the page size for MariaDB with `--aria-block-size=\`#, where `\`# is 1024, 2048, 4096, 8192, 16384 or 32768.

 Note that if you change the page size you have to dump all your old tables into text (with [mariadb-dump](../mariadb-dump/index)) and remove the old Aria log and files: 

 
```
# rm datadir/aria_log*

```

What are the advantages/disadvantages of the new `PAGE` format compared to the old MyISAM-like row formats (`DYNAMIC` and `FIXED`)
----------------------------------------------------------------------------------------------------------------------------------

 The MyISAM-like `DYNAMIC` and `FIXED` format are extremely simple and have very little space overhead, so it's hard to beat them for when it comes to simple scanning of unmodified data. The `DYNAMIC` format does however get notably worse over time if you update the row a lot in a manner that increases the size of the row.

 The advantages of the `PAGE` format (compared to `DYNAMIC` or `FIXED`) for non-transactional tables are:

 * It's cached by the Page Cache, which gives better random performance (as it uses less system calls).
* Does not fragment as easily easily as the `DYNAMIC` format during `UPDATE` statements. The maximum number of fragments are very low.
* Code can easily be extended to only read the accessed columns (for example to skip reading blobs).
* Faster updates (compared to `DYNAMIC`).

 The disadvantages are:

 * Slight storage overhead (should only be notable for very small row sizes)
* Slower full table scan time.
* When using `row_format=PAGE`, (the default), Aria first writes the row, then the keys, at which point the check for duplicate keys happens. This makes `PAGE` format slower than `DYNAMIC` (or MyISAM) if there is a lot of duplicated keys because of the overhead of writing and removing the row. If this is a problem, you can use `row_format=DYNAMIC` to get same behavior as MyISAM.

 What's the proper way to copy a Aria table from one place to another?
---------------------------------------------------------------------

 An Aria table consists of 3 files:

 
```
XXX.frm : The definition for the table, used by MySQL.
XXX.MYI : Aria internal information about the structure of the data and index and data for all indexes.
XXX.MAD : The data.

```

It's safe to copy all the Aria files to another directory or MariaDB instance if any of the following holds:

 * If you shutdown the MariaDB Server properly with [mariadb-admin shutdown](../mariadb-admin/index), so that there is nothing for Aria to recover when it starts.

 or

 * If you have run a [FLUSH TABLES](../flush/index) statement and not accessed the table using SQL from that time until the tables have been copied.

 In addition, you must adhere the following rule for transactional tables:

 You can't copy the table to a location within the same MariaDB server if the new table has existed before and the new table is still active in the Aria recovery log (that is, Aria may need to access the old data during recovery). If you are unsure whether the old name existed, run [aria\_chk --zerofill](../aria_chk/index) on the table before you use it.

 After copying a transactional table and before you use the table, we recommend that you run the command:

 
```
$ aria_chk --zerofill table_name

```

This will overwrite all references to the logs (LSN), all transactional references (TRN) and all unused space with 0. It also marks the table as 'movable'. An additional benefit of zerofill is that the Aria files will compress better. No real data is ever removed as part of zerofill.

 Aria will automatically notice if you have copied a table from another system and do 'zerofill' for the first access of the table if it was not marked as 'movable'. The reason for using [aria\_chk --zerofill](../aria_chk/index) is that you avoid a delay in the MariaDB server for the first access of the table.

 Note that this automatic detection doesn't work if you copy tables within the same MariaDB server!

 When is it safe to remove old log files?
----------------------------------------

 If you want to remove the [Aria log files](../aria-storage-engine/index#aria-log-files) (`aria_log.%`) with `rm` or delete, then you must first shut down MariaDB cleanly (for example, with [mariadb-admin shutdown](../mariadb-admin/index)) before deleting the old files.

 The same rules apply when upgrading MariaDB; When upgrading, first take down MariaDB in a clean way and then upgrade. This will allow you to remove the old log files if there are incompatible problems between releases.

 Don't remove the `aria_log_control` file! This is not a log file, but a file that contains information about the Aria setup (current transaction id, unique id, next log file number etc.).

 If you do, Aria will generate a new `aria_log_control` file at startup and will regard all old Aria files as files moved from another system. This means that they have to be 'zerofilled' before they can be used. This will happen automatically at next access of the Aria files, which can take some time if the files are big.

 If this happens, you will see things like this in your mysqld.err file:

 
```
[Note] Zerofilling moved table: '.\database\xxxx'

```

As part of zerofilling no vital data is removed.

 How does one solve the Missing valid id error?
----------------------------------------------

 See [Aria Log Files](../aria-storage-engine/index#aria-log-files) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-faq/>

Aria Storage Formats
====================

     The [Aria](../aria/index) storage engine supports three different table storage formats.

 These are FIXED, DYNAMIC and PAGE, and they can be set with the ROW FORMAT option in the [CREATE TABLE](../create-table/index) statement. PAGE is the default format, while FIXED and DYNAMIC are essentially the same as the [MyISAM formats](../myisam-storage-formats/index).

 The [SHOW TABLE STATUS](../show-table-status/index) statement can be used to see the storage format used by a table.

 Fixed-length
------------

 Fixed-length (or static) tables contain records of a fixed-length. Each column is the same length for all records, regardless of the actual contents. It is the default format if a table has no BLOB, TEXT, VARCHAR or VARBINARY fields, and no ROW FORMAT is provided. You can also specify a fixed table with ROW\_FORMAT=FIXED in the table definition.

 
Tables containing BLOB or TEXT fields cannot be FIXED, as by design these are both dynamic fields.

 
Fixed-length tables have a number of characteristics

 * fast, since MariaDB will always know where a record begins
* easy to cache
* take up more space than dynamic tables, as the maximum amount of storage space will be allocated to each record.
* reconstructing after a crash is uncomplicated due to the fixed positions
* no fragmentation or need to re-organize, unless records have been deleted and you want to free the space up.

 Dynamic
-------

 Dynamic tables contain records of a variable length. It is the default format if a table has any BLOB, TEXT, VARCHAR or VARBINARY fields, and no ROW FORMAT is provided. You can also specify a DYNAMIC table with ROW\_FORMAT=DYNAMIC in the table definition.

 Dynamic tables have a number of characteristics

 * Each row contains a header indicating the length of the row.
* Rows tend to become fragmented easily. UPDATING a record to be longer will likely ensure it is stored in different places on the disk.
* All string columns with a length of four or more are dynamic.
* They require much less space than fixed-length tables.
* Restoring after a crash is more complicated than with FIXED tables.

 Page
----

 Page format is the default format for Aria tables, and is the only format that can be used if TRANSACTIONAL=1.

 Page tables have a number of characteristics:

 * It's cached by the page cache, which gives better random performance as it uses fewer system calls.
* Does not fragment as easily easily as the DYNAMIC format during UPDATES. The maximum number of fragments are very low.
* Updates more quickly than dynamic tables.
* Has a slight storage overhead, mainly notable on very small rows
* Slower to perform a full table scan
* Slower if there are multiple duplicated keys, as Aria will first write a row, then keys, and only then check for duplicates

 Transactional
-------------

 See [Aria Storage Engine](../aria-storage-engine/index) for the impact of the TRANSACTIONAL option on the row format.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-storage-formats/>

Aria Group Commit
=================

    Since [MariaDB 5.2](../what-is-mariadb-52/index), the [Aria storage engine](../aria/index) has included a feature to group commits to speed up concurrent threads doing many inserts into the same or different Aria tables.

 By default, group commit for Aria is turned off. It is controlled by the [aria\_group\_commit](../aria-server-system-variables/index#aria_group_commit) and [aria\_group\_commit\_interval](../aria-server-system-variables/index#aria_group_commit_interval) system variables.

 Information on setting server variables can be found on the [Server System Variables](../server-system-variables/index) page.

 Terminology
-----------

 * A `commit` is `flush of logs` followed by a sync.
* `sent to disk` means written to disk but not sync()ed,
* `flushed` mean sent to disk and synced().
* `LSN` means log serial number. It's refers to the position in the transaction log.

 Non Group commit logic (aria\_group\_commit="none")
---------------------------------------------------

 The thread which first started the `commit` is performing the actual flush of logs. Other threads set the new goal (LSN) of the next pass (if it is maximum) and wait for the pass end or just wait for the pass end.

 The effect of this is that a flush (write of logs + sync) will save all data for all threads/transactions that have been waiting since the last flush.

 If hard group commit is enabled (aria\_group\_commit="hard")
------------------------------------------------------------

 ### If hard commit and aria\_group\_commit\_interval=0

 The first thread sends all changed buffers to disk. This is repeated as long as there are new LSNs added. The process can not loop forever because we have a limited number of threads and they will wait for the data to be synced.

 Pseudo code:

 
```
do
   send changed buffers to disk
 while new_goal
sync

```

### If hard commit and aria\_group\_commit\_interval > 0

 If less than rate microseconds has passed since the last sync, then after buffers have been sent to disk, wait until rate microseconds has passed since last sync, do sync and return. This ensures that if we call sync infrequently we don't do any waits.

 If soft group commit is enabled (aria\_group\_commit="soft")
------------------------------------------------------------

 Note that soft group commit should only be used if you can afford to lose a few rows if your machine shuts down hard (as in the case of a power failure).

 Works like in `non group commit'` but the thread doesn't do any real sync(). If aria\_group\_commit\_interval is not zero, the sync() will be performed by a service thread with the given rate when needed (new LSN appears). If aria\_group\_commit\_interval is zero, there will be no sync() calls.

 Code
----

 The code for this can be found in storage/maria/ma\_loghandler.c::translog\_flush()

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-group-commit/>

Benchmarking Aria
=================

    We have not yet had time to benchmark [Aria](../aria/index) properly. Here follows some things that have been discussed on the [maria-discuss](http://launchpad.net/~maria-discuss) email list.

 Aria used for internal temporary tables
---------------------------------------

 By default Aria (instead of MyISAM) is used for the internal temporary tables when MEMORY tables overflows to disk or MEMORY tables can't be used (for example when you are using temporary results with BLOB's). In most cases Aria should give you better performance than using MyISAM, but this is not always the case.

 
```
CREATE TABLE `t1` (`id` int(11) DEFAULT NULL, `tea` text) 
  ENGINE=MyISAM DEFAULT CHARSET=latin1;
insert t1 select rand()*2e8, repeat(rand(), rand()*64) from t1;

```

Repeat the last row until you get 2097152 rows.

 The queries tested

 
```
Q1: SELECT id, tea from t1 group by left(id,1) order by null;
Q2: SELECT id, count(*), tea from t1 group by left(id,1) order by null;
Q3: SELECT id, tea from t1 group by left(id,2) order by null;
Q4: SELECT id, count(*), tea from t1 group by left(id,2) order by null;
Q5: SELECT id, tea from t1 group by id % 100 order by null;
Q6: SELECT id, count(*), tea from t1 group by id % 100 order by null;

```

Results (times in seconds, lower is better):

 


| Test | Aria 8K page size | Aria 2K page size | MyISAM |
| --- | --- | --- | --- |
| Q1 | 3.08 | 2.41 | 2.17 |
| Q2 | 6.24 | 5.21 | 12.89 |
| Q3 | 4.87 | 4.05 | 4.04 |
| Q4 | 8.20 | 7.04 | 15.14 |
| Q5 | 7.10 | 6.37 | 6.28 |
| Q6 | 10.38 | 9.09 | 17.00 |

 
The good news is that for common group by queries that is using summary functions there is a close to 50 % speedup of using Aria for internal temporary tables.

 Note that queries Q1,Q3 and Q5 are not typical queries as there is no sum functions involved. In this case rows are just written to the tmp tables and there is no updates. As soon as there are summary functions and updates the new row format in Aria gives a close to 50 % speedup.

 The above table also shows how the page size (determined by the [aria\_block\_size](../aria-system-variables/index#aria_block_size) system variable) affects the performance. The reason for the difference is that there is more data to move back/from the page cache for inserting of keys. (When reading data we are normally not copying pages). The bigger page size however allows longer keys and fewer index levels so for bigger data sets the different should be smaller. It's possible to in the future optimize Aria to not copy pages from the page cache also for index writes and then this difference should disappear.

 The default page size for Aria is 8K.

 If you want to run MariaDB with MyISAM for temporary tables, don't use the configure option '--with-aria-tmp-tables' when building MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmarking-aria/>

Aria Two-step Deadlock Detection
================================

    Description
-----------

 The [Aria](../aria/index) storage engine can automatically detect and deal with deadlocks (see the [Wikipedia deadlocks article](http://en.wikipedia.org/wiki/Deadlock)).

 This feature is controlled by four configuration variables, two that control the search depth and two that control the timeout.

 * [deadlock\_search\_depth\_long](../aria-server-system-variables/index#deadlock_search_depth_long)
* [deadlock\_search\_depth\_short](../aria-server-system-variables/index#deadlock_search_depth_short)
* [deadlock\_timeout\_long](../aria-server-system-variables/index#deadlock_timeout_long)
* [deadlock\_timeout\_short](../aria-server-system-variables/index#deadlock_timeout_short)

 How it Works
------------

 If Aria is ever unable to obtain a lock, we might have a deadlock. There are two primary ways for detecting if a deadlock has actually occurred. First is to search a wait-for graph (see the [wait-for graph on Wikipedia](http://en.wikipedia.org/wiki/Wait-for_graph)) and the second is to just wait and let the deadlock exhibit itself. Aria Two-step Deadlock Detection does a combination of both.

 First, if the lock request cannot be granted immediately, we do a short search of the wait-for graph with a small search depth as configured by the `deadlock_search_depth_short` variable. We have a depth limit because the graph can (theoretically) be arbitrarily big and we don't want to recursively search the graph arbitrarily deep. This initial, short search is very fast and most deadlocks will be detected right away. If no deadlock cycles are found with the short search the system waits for the amount of time configured in `deadlock_timeout_short` to see if the lock conflicts will be removed and the lock can be granted. Assuming this did not happen and the lock request still waits, the system then moves on to step two, which is a repeat of the process but this time searching deeper using the `deadlock_search_depth_long`. If no deadlock has been detected, it waits `deadlock_timeout_long` and times out.

 When a deadlock is detected the system uses a weighting algorithm to determine which thread in the deadlock should be killed and then kills it. 

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-two-step-deadlock-detection/>

The Aria Name
=============

     The [Aria](../aria/index) storage engine used to be called Maria. This page gives the history and background of how and why this name was changed to Aria.

 Backstory
---------

 When starting what became the MariaDB project, Monty and the initial developers only planned to work on a next generation [MyISAM](../myisam-storage-engine/index) storage engine replacement. This storage engine would be crash safe and eventually support transactions. Monty named the storage engine, and the project, after his daughter, Maria.

 Work began in earnest on the Maria storage engine but the plans quickly expanded and morphed and soon the developers were not just working on a storage engine, but on a complete branch of the MySQL database. Since the project was already called Maria, it made sense to call the whole database server MariaDB.

 Renaming Maria (the engine)
---------------------------

 So now there was the database, MariaDB, and the storage engine, Maria. To end the confusion this caused, the decision was made to rename the storage engine.

 Monty's first suggestion was to name it *Lucy*, after his dog, but few who heard it liked that idea. So the decision was made that the next best thing was for the community to suggest and vote on names.

 This was done by running a contest in 2009 through the end of May 2010. After that the best names were voted on by the community and Monty picked and [announced the winner](http://blogs.gnome.org/mneptok/2010/07/20/rename-maria-contest-winner/) (Aria) at OSCon 2010 in Portland.

 The winning entry was submitted by Chris Tooley. He received a Linux-powered [System 76](http://www.system76.com) Meerkat NetTop as his prize for suggesting the winning name from Monty Program.

 See Also
--------

 * [Why is the Software Called MariaDB?](../why-is-the-software-called-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-aria-name/>

HANDLER
========

   The `HANDLER` statements give you direct access to reading rows from the storage engine. This is much faster than normal access through [SELECT](../select/index) as there is less parsing involved and no optimizer involved.

 You can use [prepared statements](../prepared-statements/index) for `HANDLER READ`, which should give you a speed comparable to [HandlerSocket](../handlersocket/index). Also see Yoshinori Matsunobu's blog post [Using MySQL as a NoSQL - A story for exceeding 750,000 qps on a commodity server](http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html).

  

| Title | Description |
| --- | --- |
|  [HANDLER Commands](../handler-commands/index) |  Direct access to table storage engine interfaces for key lookups and key or table scans.  |
|  [HANDLER for MEMORY Tables](../handler-for-memory-tables/index) |  Using HANDLER commands efficiently with MEMORY/HEAP tables  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handler/>

HandlerSocket
==============

   HandlerSocket gives you direct access to [InnoDB](../innodb/index) and [SPIDER](../spider/index). It is included in MariaDB as a ready-to use plugin.

 HandlerSocket is a NoSQL plugin for MariaDB. It works as a daemon inside the mysqld process, accepting TCP connections, and executing requests from clients. HandlerSocket does not support SQL queries. Instead, it supports simple CRUD operations on tables.

 HandlerSocket can be much faster than mysqld/libmysql in some cases because it has lower CPU, disk, and network overhead:

 1. To lower CPU usage it does not parse SQL.
2. Next, it batch-processes requests where possible, which further reduces CPU usage and lowers disk usage.
3. Lastly, the client/server protocol is very compact compared to mysql/libmysql, which reduces network usage.

  

| Title | Description |
| --- | --- |
|  [HandlerSocket Installation](../handlersocket-installation/index) |  Installing the HandlerSocket plugin.  |
|  [HandlerSocket Configuration Options](../handlersocket-configuration-options/index) |  HandlerSocket configuration options.  |
|  [HandlerSocket Client Libraries](../handlersocket-client-libraries/index) |  Available HandlerSocket Client Libraries  |
|  [Testing HandlerSocket in a Source Distribution](../testing-handlersocket-in-a-source-distribution/index) |  Testing HandlerSocket in a source distribution.  |
|  [HandlerSocket External Resources](../handlersocket-external-resources/index) |  HandlerSocket external resources and documentation  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handlersocket/>

Dynamic Columns from MariaDB 10
===============================

    
**MariaDB starting with [10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/)**[MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) introduced the following improvements to the [dynamic columns](../dynamic-columns/index) feature.

 
Column Name Support
-------------------

 It is possible to refer to column by names. Names can be used everywhere where in [MariaDB 5.3](../what-is-mariadb-53/index) one could use only strings:

 * Create a dynamic column blob:

 
```
COLUMN_CREATE('int_col', 123 as int, 'double_col', 3.14 as double, 'string_col', 'text-data' as char);

```

* Set a column value:

 
```
COLUMN_ADD(dyncol_blob, 'intcol', 1234);

```

* Get a column value:

 
```
COLUMN_GET(dynstr, 'column1' as char(10));

```

* Check whether a column exists

 
```
COLUMN_EXISTS(dyncol_blob, 'column_name');

```

Changes in Behavior
-------------------

 * Column list output now includes quoting:

 
```
select column_list(column_create(1, 22, 2, 23));
+------------------------------------------+
| column_list(column_create(1, 22, 2, 23)) |
+------------------------------------------+
| `1`,`2`                                  |
+------------------------------------------+
select column_list(column_create('column1', 22, 'column2', 23)); 
+----------------------------------------------------------+
| column_list(column_create('column1', 22, 'column2', 23)) |
+----------------------------------------------------------+
| `column1`,`column2`                                      |
+----------------------------------------------------------+

```

* Column name interpretation has been changed so that the string now is not converted to a number. So some "magic" tricks will not work any more, for example, "1test" and "1" now become different column names:

 
```
select column_list(column_add(column_create('1a', 22), '1b', 23));
+------------------------------------------------------------+
| column_list(column_add(column_create('1a', 22), '1b', 23)) |
+------------------------------------------------------------+
| `1a`,`1b`                                                  |
+------------------------------------------------------------+

```

* Old behavior:

 
```
select column_list(column_add(column_create('1a', 22), '1b', 23));
+------------------------------------------------------------+
| column_list(column_add(column_create('1a', 22), '1b', 23)) |
+------------------------------------------------------------+
| 1                                                          |
+------------------------------------------------------------+

```

New Functions
-------------

 The following new functions have been added to dynamic columns in MariaDB 10

 ### COLUMN\_CHECK

 [COLUMN\_CHECK](../column_check/index) is used to check a column's integrity. When it encounters an error it does not return illegal format errors but returns false instead. It also checks integrity more thoroughly and finds errors in the dynamic column internal structures which might not be found by other functions.

 
```
select column_check(column_create('column1', 22));
+--------------------------------------------+
| column_check(column_create('column1', 22)) |
+--------------------------------------------+
|                                          1 |
+--------------------------------------------+
select column_check('abracadabra');
+-----------------------------+
| column_check('abracadabra') |
+-----------------------------+
|                           0 |
+-----------------------------+

```

### COLUMN\_JSON

 [COLUMN\_JSON](column-json) converts all dynamic column record content to a JSON object.

 
```
select column_json(column_create('column1', 1, 'column2', "two"));
+------------------------------------------------------------+
| column_json(column_create('column1', 1, 'column2', "two")) |
+------------------------------------------------------------+
| {"column1":1,"column2":"two"}                              |
+------------------------------------------------------------+

```

Other Changes
-------------

 * All API functions has prefix mariadb\_dyncol\_ (old prefix dynamic\_column\_ is depricated
* API changed to be able to work with the new format (\*\_named functions).
* Removed 'delete' function because deleting could be done by adding NULL value.
* 'Time' and 'datetime' in the new format are stored without microseconds if they are 0.
* New function added to API (except that two which are representing SQL level functions):
	+ 'Unpack' the dynamic columns content to an arrays of values and names.
	+ 3 functions to get any column value as string, integer (long long) or floating point (double).
* New type of "dynamic column" row added on the API level (in SQL level output it is a string but if you use dynamic column functions to construct object it will be added as dynamic column value) which allow to add dynamic columns inside dynamic columns. JSON function represent such recursive constructions correctly but limit depth of representation as current implementation limit (internally depth of dynamic columns embedding is not limited).

 Interface with Cassandra
------------------------

 
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  Some internal changes were added to dynamic columns to allow them to serve as an interface to Apache Cassandra dynamic columns. The [Cassandra engine](../cassandra-storage-engine/index) may pack all columns which were not mentioned in the MariaDB interface table definition and even bring changes in the dynamic column contents back to the cassandra columns family (the table analog in cassandra).

 See Also
--------

 * [Dynamic Columns](../dynamic-columns/index)
* [Cassandra Storage Engine](../cassandra-storage-engine/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dynamic-columns-from-mariadb-10/>

Dynamic Column API
==================

    This page describes the client-side API for reading and writing [Dynamic Columns](../dynamic-columns/index) blobs. 

 Normally, you should use [Dynamic column functions](../dynamic-columns/index#dynamic-columns-functions) which are run inside the MariaDB server and allow one to access Dynamic Columns content without any client-side libraries.

 If you need to read/write dynamic column blobs **on the client** for some reason, this API enables that.

 Where to get it
---------------

 The API is a part of `libmysql` C client library. In order to use it, you need to include this header file

 
```
#include <mysql/ma_dyncol.h>

```

and link against `libmysql`.

 Data structures
---------------

 ### DYNAMIC\_COLUMN

 `DYNAMIC_COLUMN` represents a packed dynamic column blob. It is essentially a string-with-length and is defined as follows:

 
```
/* A generic-purpose arbitrary-length string defined in MySQL Client API */
typedef struct st_dynamic_string
{
  char *str;
  size_t length,max_length,alloc_increment;
} DYNAMIC_STRING;

...

typedef DYNAMIC_STRING DYNAMIC_COLUMN;

```

### DYNAMIC\_COLUMN\_VALUE

 Dynamic columns blob stores {name, value} pairs. `DYNAMIC_COLUMN_VALUE` structure is used to represent the value in accessible form.

 
```
struct st_dynamic_column_value
{
  DYNAMIC_COLUMN_TYPE type;
  union
  {
    long long long_value;
    unsigned long long ulong_value;
    double double_value;
    struct {
      MYSQL_LEX_STRING value;
      CHARSET_INFO *charset;
    } string;
    struct {
      decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
      decimal_t value;
    } decimal;
    MYSQL_TIME time_value;
  } x;
};
typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;

```

Every value has a type, which is determined by the `type` member.

 


| type | structure field |
| --- | --- |
| `DYN_COL_NULL` | - |
| `DYN_COL_INT` | `value.x.long_value` |
| `DYN_COL_UINT` | `value.x.ulong_value` |
| `DYN_COL_DOUBLE` | `value.x.double_value` |
| `DYN_COL_STRING` | `value.x.string.value`, `value.x.string.charset` |
| `DYN_COL_DECIMAL` | `value.x.decimal.value` |
| `DYN_COL_DATETIME` | `value.x.time_value` |
| `DYN_COL_DATE` | `value.x.time_value` |
| `DYN_COL_TIME` | `value.x.time_value` |
| `DYN_COL_DYNCOL` | `value.x.string.value` |

 
Notes

 * Values with type `DYN_COL_NULL` do not ever occur in dynamic columns blobs.
* Type `DYN_COL_DYNCOL` means that the value is a packed dynamic blob. This is how nested dynamic columns are done.
* Before storing a value to `value.x.decimal.value`, one must call `mariadb_dyncol_prepare_decimal()` to initialize the space for storage.

 ### enum\_dyncol\_func\_result

 `enum enum_dyncol_func_result` is used as return value. 

 


| value | name | meaning |
| --- | --- | --- |
| 0 | `ER_DYNCOL_OK` | OK |
| 0 | `ER_DYNCOL_NO` | (the same as ER\_DYNCOL\_OK but for functions which return a YES/NO) |
| 1 | `ER_DYNCOL_YES` | YES response or success |
| 2 | `ER_DYNCOL_TRUNCATED` | Operation succeeded but the data was truncated |
| -1 | `ER_DYNCOL_FORMAT` | Wrong format of the encoded string |
| -2 | `ER_DYNCOL_LIMIT` | A limit of implementation reached |
| -3 | `ER_DYNCOL_RESOURCE` | Out of resources |
| -4 | `ER_DYNCOL_DATA` | Incorrect input data |
| -5 | `ER_DYNCOL_UNKNOWN_CHARSET` | Unknown character set |

 
Result codes that are less than zero represent error conditions.

 Function reference
------------------

 Functions come in pairs:

 * `xxx()` operates on the old (pre-MariaDB-10.0.1) dynamic column blob format where columns were identified by numbers.
* `xxx_named()` can operate on both old or new data format. If it modifies the blob, it will convert it to the new data format.

 You should use `xxx_named()` functions, unless you need to keep the data compatible with MariaDB versions before 10.0.1.

 ### mariadb\_dyncol\_create\_many

 Create a packed dynamic blob from arrays of values and names.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_create_many(DYNAMIC_COLUMN *str,
                           uint column_count,
                           uint *column_numbers,
                           DYNAMIC_COLUMN_VALUE *values,
                           my_bool new_string);
enum enum_dyncol_func_result
mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str,
                                 uint column_count,
                                 MYSQL_LEX_STRING *column_keys,
                                 DYNAMIC_COLUMN_VALUE *values,
                                 my_bool new_string);

```

where

 

|  |  |  |
| --- | --- | --- |
| `str` | `OUT` | Packed dynamic blob will be put here |
| `column_count` | `IN` | Number of columns |
| `column_numbers` | `IN` | Column numbers array (old format) |
| `column_keys` | `IN` | Column names array (new format) |
| `values` | `IN` | Column values array |
| `new_string` | `IN` | If TRUE then the `str` will be reinitialized (not freed) before usage |

 ### mariadb\_dyncol\_update\_many

 Add or update columns in a dynamic columns blob. To delete a column, update its value to a "non-value" of type `DYN_COL_NULL`

 
```
enum enum_dyncol_func_result
mariadb_dyncol_update_many(DYNAMIC_COLUMN *str,
                           uint column_count,
                           uint *column_numbers,
                           DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str,
                                 uint column_count,
                                 MYSQL_LEX_STRING *column_keys,
                                 DYNAMIC_COLUMN_VALUE *values);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN/OUT` | Dynamic columns blob to be modified. |
| `column_count` | `IN` | Number of columns in following arrays |
| `column_numbers` | `IN` | Column numbers array (old format) |
| `column_keys` | `IN` | Column names array (new format) |
| `values` | `IN` | Column values array |

 ### mariadb\_dyncol\_exists

 Check if column with given name exists in the blob

 
```
enum enum_dyncol_func_result
mariadb_dyncol_exists(DYNAMIC_COLUMN *str, uint column_number);
enum enum_dyncol_func_result
mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *column_key);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_number` | `IN` | Column number (old format) |
| `column_key` | `IN` | Column name (new format) |

 The function returns YES/NO or Error code

 ### mariadb\_dyncol\_column\_count

 Get number of columns in a dynamic column blob

 
```
enum enum_dyncol_func_result
mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_count` | `OUT` | Number of not NULL columns in the dynamic columns string |

 ### mariadb\_dyncol\_list

 List columns in a dynamic column blob.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_list(DYNAMIC_COLUMN *str, uint *column_count, uint **column_numbers);
enum enum_dyncol_func_result
mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *column_count,
                          MYSQL_LEX_STRING **column_keys);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_count` | `OUT` | Number of columns in following arrays |
| `column_numbers` | `OUT` | Column numbers array (old format). Caller should free this array. |
| `column_keys` | `OUT` | Column names array (new format). Caller should free this array. |

 ### mariadb\_dyncol\_get

 Get a value of one column

 
```
enum enum_dyncol_func_result
mariadb_dyncol_get(DYNAMIC_COLUMN *org, uint column_number,
                   DYNAMIC_COLUMN_VALUE *value);
enum enum_dyncol_func_result
mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *column_key,
                         DYNAMIC_COLUMN_VALUE *value);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_number` | `IN` | Column numbers array (old format) |
| `column_key` | `IN` | Column names array (new format) |
| `value` | `OUT` | Value of the column |

 If the column is not found NULL returned as a value of the column.

 ### mariadb\_dyncol\_unpack

 Get value of all columns 

 
```
enum enum_dyncol_func_result
mariadb_dyncol_unpack(DYNAMIC_COLUMN *str,
                      uint *column_count,
                      MYSQL_LEX_STRING **column_keys,
                      DYNAMIC_COLUMN_VALUE **values);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string to unpack. |
| `column_count` | `OUT` | Number of columns in following arrays |
| `column_keys` | `OUT` | Column names array (should be free by caller) |
| `values` | `OUT` | Values of the columns array (should be free by caller) |

 ### mariadb\_dyncol\_has\_names

 Check whether the dynamic columns blob uses new data format (the one where columns are identified by names)

 
```
my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |

 ### mariadb\_dyncol\_check

 Check whether dynamic column blob has correct data format.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_check(DYNAMIC_COLUMN *str);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |

 ### mariadb\_dyncol\_json

 Get contents od a dynamic columns blob in a JSON form

 
```
enum enum_dyncol_func_result
mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `json` | `OUT` | JSON representation |

 ### mariadb\_dyncol\_val\_TYPE

 Get dynamic column value as one of the base types

 
```
enum enum_dyncol_func_result
mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
                       CHARSET_INFO *cs, my_bool quote);
enum enum_dyncol_func_result
mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
enum enum_dyncol_func_result
mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);

```



|  |  |  |
| --- | --- | --- |
| `str` or `ll` or `dbl` | `OUT` | value of the column |
| `val` | `IN` | Value |

 ### mariadb\_dyncol\_prepare\_decimal

 Initialize `DYNAMIC_COLUMN_VALUE` before value of `value.x.decimal.value` can be set

 
```
void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value);

```



|  |  |  |
| --- | --- | --- |
| `value` | `OUT` | Value of the column |

 This function links `value.x.decimal.value` to `value.x.decimal.buffer`.

 ### mariadb\_dyncol\_value\_init

 Initialize a `DYNAMIC_COLUMN_VALUE` structure to a safe default.

 
```
#define mariadb_dyncol_value_init(V) (V)->type= DYN_COL_NULL

```

### mariadb\_dyncol\_column\_cmp\_named

 Compare two column names (currently, column names are compared with memcmp())

 
```
int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1,
                                    const MYSQL_LEX_STRING *s2);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dynamic-column-api/>

Dynamic Columns API
===================

    This page describes client-side of [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) API and MariaDB Connector/C 2.0 for reading and writing [Dynamic Columns](../dynamic-columns/index) blobs. 

 Normally, you should use [Dynamic column functions](../dynamic-columns/index#dynamic-columns-functions) which are run inside the MariaDB server and allow one to access Dynamic Columns content without any client-side libraries.

 If you need to read/write dynamic column blobs **on the client** for some reason, this API enables that.

 Where to get it
---------------

 The API is a part of `libmysql` C client library. In order to use it, one needs to include this header file

 
```
#include <mysql/ma_dyncol.h>

```

and link against `libmysql`.

 Data structures
---------------

 ### DYNAMIC\_COLUMN

 `DYNAMIC_COLUMN` represents a packed dynamic column blob. It is essentially a string-with-length and is defined as follows:

 
```
/* A generic-purpose arbitrary-length string defined in MySQL Client API */
typedef struct st_dynamic_string
{
  char *str;
  size_t length,max_length,alloc_increment;
} DYNAMIC_STRING;

...

typedef DYNAMIC_STRING DYNAMIC_COLUMN;

```

### DYNAMIC\_COLUMN\_VALUE

 Dynamic columns blob stores {name, value} pairs. `DYNAMIC_COLUMN_VALUE` structure is used to represent the value in accessible form.

 
```
struct st_dynamic_column_value
{
  DYNAMIC_COLUMN_TYPE type;
  union
  {
    long long long_value;
    unsigned long long ulong_value;
    double double_value;
    struct {
      MYSQL_LEX_STRING value;
      CHARSET_INFO *charset;
    } string;
    struct {
      decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
      decimal_t value;
    } decimal;
    MYSQL_TIME time_value;
  } x;
};
typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;

```

Every value has a type, which is determined by the `type` member.

 


| type | structure field |
| --- | --- |
| `DYN_COL_NULL` | - |
| `DYN_COL_INT` | `value.x.long_value` |
| `DYN_COL_UINT` | `value.x.ulong_value` |
| `DYN_COL_DOUBLE` | `value.x.double_value` |
| `DYN_COL_STRING` | `value.x.string.value`, `value.x.string.charset` |
| `DYN_COL_DECIMAL` | `value.x.decimal.value` |
| `DYN_COL_DATETIME` | `value.x.time_value` |
| `DYN_COL_DATE` | `value.x.time_value` |
| `DYN_COL_TIME` | `value.x.time_value` |
| `DYN_COL_DYNCOL` | `value.x.string.value` |

 
Notes

 * Values with type `DYN_COL_NULL` do not ever occur in dynamic columns blobs.
* Type `DYN_COL_DYNCOL` means that the value is a packed dynamic blob. This is how nested dynamic columns are done.
* Before storing a value to `value.x.decimal.value`, one must call `mariadb_dyncol_prepare_decimal()` to initialize the space for storage.

 ### enum\_dyncol\_func\_result

 `enum enum_dyncol_func_result` is used as return value. 

 


| value | name | meaning |
| --- | --- | --- |
| 0 | `ER_DYNCOL_OK` | OK |
| 0 | `ER_DYNCOL_NO` | (the same as ER\_DYNCOL\_OK but for functions which return a YES/NO) |
| 1 | `ER_DYNCOL_YES` | YES response or success |
| 2 | `ER_DYNCOL_TRUNCATED` | Operation succeeded but the data was truncated |
| -1 | `ER_DYNCOL_FORMAT` | Wrong format of the encoded string |
| -2 | `ER_DYNCOL_LIMIT` | A limit of implementation reached |
| -3 | `ER_DYNCOL_RESOURCE` | Out of resources |
| -4 | `ER_DYNCOL_DATA` | Incorrect input data |
| -5 | `ER_DYNCOL_UNKNOWN_CHARSET` | Unknown character set |

 
Result codes that are less than zero represent error conditions.

 Function reference
------------------

 Functions come in pairs:

 * `xxx_num()` operates on the old (pre-MariaDB-10.0.1) dynamic column blob format where columns were identified by numbers.
* `xxx_named()` can operate on both old or new data format. If it modifies the blob, it will convert it to the new data format.

 You should use `xxx_named()` functions, unless you need to keep the data compatible with MariaDB versions before 10.0.1.

 ### mariadb\_dyncol\_init

 1. define mariadb\_dyncol\_init(A) memset((A), 0, sizeof(\*(A)))

 It is correct initialization for an empty packed dynamic blob.

 ### mariadb\_dyncol\_free

 
```
void mariadb_dyncol_free(DYNAMIC_COLUMN *str);

```

where

 

|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic blob which memory should be freed. |

 ### mariadb\_dyncol\_create\_many (num|named)

 Create a packed dynamic blob from arrays of values and names.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_create_many_num(DYNAMIC_COLUMN *str,
                               uint column_count,
                               uint *column_numbers,
                               DYNAMIC_COLUMN_VALUE *values,
                               my_bool new_string);
enum enum_dyncol_func_result
mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str,
                                 uint column_count,
                                 MYSQL_LEX_STRING *column_keys,
                                 DYNAMIC_COLUMN_VALUE *values,
                                 my_bool new_string);

```

where

 

|  |  |  |
| --- | --- | --- |
| `str` | `OUT` | Packed dynamic blob will be put here |
| `column_count` | `IN` | Number of columns |
| `column_numbers` | `IN` | Column numbers array (old format) |
| `column_keys` | `IN` | Column names array (new format) |
| `values` | `IN` | Column values array |
| `new_string` | `IN` | If TRUE then the `str` will be reinitialized (not freed) before usage |

 ### mariadb\_dyncol\_update\_many (num|named)

 Add or update columns in a dynamic columns blob. To delete a column, update its value to a "non-value" of type `DYN_COL_NULL`

 
```
enum enum_dyncol_func_result
mariadb_dyncol_update_many_num(DYNAMIC_COLUMN *str,
                               uint column_count,
                               uint *column_numbers,
                               DYNAMIC_COLUMN_VALUE *values);
enum enum_dyncol_func_result
mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str,
                                 uint column_count,
                                 MYSQL_LEX_STRING *column_keys,
                                 DYNAMIC_COLUMN_VALUE *values);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN/OUT` | Dynamic columns blob to be modified. |
| `column_count` | `IN` | Number of columns in following arrays |
| `column_numbers` | `IN` | Column numbers array (old format) |
| `column_keys` | `IN` | Column names array (new format) |
| `values` | `IN` | Column values array |

 ### mariadb\_dyncol\_exists (num|named)

 Check if column with given name exists in the blob

 
```
enum enum_dyncol_func_result
mariadb_dyncol_exists_num(DYNAMIC_COLUMN *str, uint column_number);
enum enum_dyncol_func_result
mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *column_key);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_number` | `IN` | Column number (old format) |
| `column_key` | `IN` | Column name (new format) |

 The function returns YES/NO or Error code

 ### mariadb\_dyncol\_column\_count

 Get number of columns in a dynamic column blob

 
```
enum enum_dyncol_func_result
mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_count` | `OUT` | Number of not NULL columns in the dynamic columns string |

 ### mariadb\_dyncol\_list (num|named)

 List columns in a dynamic column blob.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_list_num(DYNAMIC_COLUMN *str, uint *column_count, uint **column_numbers);
enum enum_dyncol_func_result
mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *column_count,
                          MYSQL_LEX_STRING **column_keys);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_count` | `OUT` | Number of columns in following arrays |
| `column_numbers` | `OUT` | Column numbers array (old format). Caller should free this array. |
| `column_keys` | `OUT` | Column names array (new format). Caller should free this array. |

 ### mariadb\_dyncol\_get (num|named)

 Get a value of one column

 
```
enum enum_dyncol_func_result
mariadb_dyncol_get_num(DYNAMIC_COLUMN *org, uint column_number,
                       DYNAMIC_COLUMN_VALUE *value);
enum enum_dyncol_func_result
mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *column_key,
                         DYNAMIC_COLUMN_VALUE *value);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `column_number` | `IN` | Column numbers array (old format) |
| `column_key` | `IN` | Column names array (new format) |
| `value` | `OUT` | Value of the column |

 If the column is not found NULL returned as a value of the column.

 ### mariadb\_dyncol\_unpack

 Get value of all columns 

 
```
enum enum_dyncol_func_result
mariadb_dyncol_unpack(DYNAMIC_COLUMN *str,
                      uint *column_count,
                      MYSQL_LEX_STRING **column_keys,
                      DYNAMIC_COLUMN_VALUE **values);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string to unpack. |
| `column_count` | `OUT` | Number of columns in following arrays |
| `column_keys` | `OUT` | Column names array (should be free by caller) |
| `values` | `OUT` | Values of the columns array (should be free by caller) |

 ### mariadb\_dyncol\_has\_names

 Check whether the dynamic columns blob uses new data format (the one where columns are identified by names)

 
```
my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |

 ### mariadb\_dyncol\_check

 Check whether dynamic column blob has correct data format.

 
```
enum enum_dyncol_func_result
mariadb_dyncol_check(DYNAMIC_COLUMN *str);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |

 ### mariadb\_dyncol\_json

 Get contents od a dynamic columns blob in a JSON form

 
```
enum enum_dyncol_func_result
mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);

```



|  |  |  |
| --- | --- | --- |
| `str` | `IN` | Packed dynamic columns string. |
| `json` | `OUT` | JSON representation |

 mariadb\_dyncol\_json() allocates memory for the parameter json which must be explicitly freed by the mariadb\_dyncol\_free() function to prevent memory leakage.

 ### mariadb\_dyncol\_val\_TYPE

 Get dynamic column value as one of the base types

 
```
enum enum_dyncol_func_result
mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
                       CHARSET_INFO *cs, my_bool quote);
enum enum_dyncol_func_result
mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
enum enum_dyncol_func_result
mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);

```



|  |  |  |
| --- | --- | --- |
| `str` or `ll` or `dbl` | `OUT` | value of the column |
| `val` | `IN` | Value |

 ### mariadb\_dyncol\_prepare\_decimal

 Initialize `DYNAMIC_COLUMN_VALUE` before value of `value.x.decimal.value` can be set

 
```
void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value);

```



|  |  |  |
| --- | --- | --- |
| `value` | `OUT` | Value of the column |

 This function links `value.x.decimal.value` to `value.x.decimal.buffer`.

 ### mariadb\_dyncol\_value\_init

 Initialize a `DYNAMIC_COLUMN_VALUE` structure to a safe default.

 
```
#define mariadb_dyncol_value_init(V) (V)->type= DYN_COL_NULL

```

### mariadb\_dyncol\_column\_cmp\_named

 Compare two column names for equality

 
```
int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1,
                                    const MYSQL_LEX_STRING *s2);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dynamic-columns-api/>

Cassandra Storage Engine
=========================

   
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  A storage engine interface to [Cassandra](http://cassandra.apache.org/). Read the original [announcement information about CassandraSE](https://mariadb.org/announcing-the-cassandra-storage-engine/).

  

| Title | Description |
| --- | --- |
|  [Cassandra Storage Engine Overview](../cassandra-storage-engine-overview/index) |  Introduction to the Cassandra storage engine  |
|  [Cassandra Storage Engine Use Example](../cassandra-storage-engine-use-example/index) |  Short demo of what using Cassandra Storage Engine looks like.  |
|  [Cassandra Storage Engine Issues](../cassandra-storage-engine-issues/index) |  Difficulties and peculiarities of the Cassandra Storage Engine.  |
|  [Cassandra Storage Engine Future Plans](../cassandra-storage-engine-future-plans/index) |  Brainstorming possible future directions for the Cassandra Storage Engine.  |
|  [Handling Joins With Cassandra](../handling-joins-with-cassandra/index) |  Joins with data stored in a Cassandra database are only possible on the MariaDB side  |
|  [Virtual Machine to Test the Cassandra Storage Engine](../virtual-machine-to-test-the-cassandra-storage-engine/index) |  Julien Duponchelle has made a virtual machine available for testing the Cassandra storage engine.  |
|  [Building Cassandra Storage Engine](../building-cassandra-storage-engine/index) |  THIS PAGE IS OBSOLETE, it describes how to build a branch of MariaDB-5.5 w...  |
|  [Building Cassandra Storage Engine for Packaging](../building-cassandra-storage-engine-for-packaging/index) |  OBSOLETE. How to build a branch of MariaDB-5.5 with Cassandra SE  |
|  [Cassandra Status Variables](../cassandra-status-variables/index) |  Cassandra-related status variables  |
|  [Cassandra System Variables](../cassandra-system-variables/index) |  Cassandra system variables  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra/>

Identifier Names
================

     Databases, tables, indexes, columns, aliases, views, stored routines, triggers, events, variables, partitions, tablespaces, savepoints, labels, users, roles, are collectively known as identifiers, and have certain rules for naming.

 Identifiers may be quoted using the backtick character - ```. Quoting is optional for identifiers that don't contain special characters, or for identifiers that are not [reserved words](../reserved-words/index). If the `ANSI_QUOTES` [SQL\_MODE](../sql-mode/index) flag is set, double quotes (`"`) can also be used to quote identifiers. If the `[MSSQL](../sql_modemssql/index)` flag is set, square brackets (`[` and `]`) can be used for quoting.

 Even when using reserved words as names, [fully qualified names](../identifier-qualifiers/index) do not need to be quoted. For example, `test.select` has only one possible meaning, so it is correctly parsed even without quotes.

 ### Unquoted

 The following characters are valid, and allow identifiers to be unquoted:

 * ASCII: [0-9,a-z,A-Z$\_] (numerals 0-9, basic Latin letters, both lowercase and uppercase, dollar sign, underscore)
* Extended: U+0080 .. U+FFFF

 ### Quoted

 The following characters are valid, but identifiers using them must be quoted:

 * ASCII: U+0001 .. U+007F (full Unicode Basic Multilingual Plane (BMP) except for U+0000)
* Extended: U+0080 .. U+FFFF
* Identifier quotes can themselves be used as part of an identifier, as long as they are quoted.

 ### Further Rules

 There are a number of other rules for identifiers:

 * Identifiers are stored as Unicode (UTF-8)
* Identifiers may or may not be case-sensitive. See [Indentifier Case-sensitivity](../identifier-case-sensitivity/index).
* Database, table and column names can't end with space characters
* Identifier names may begin with a numeral, but can't only contain numerals unless quoted.
* An identifier starting with a numeral, followed by an 'e', may be parsed as a floating point number, and needs to be quoted.
* Identifiers are not permitted to contain the ASCII NUL character (U+0000) and supplementary characters (U+10000 and higher).
* Names such as 5e6, 9e are not prohibited, but it's strongly recommended not to use them, as they could lead to ambiguity in certain contexts, being treated as a number or expression.
* User variables cannot be used as part of an identifier, or as an identifier in an SQL statement.

 ### Quote Character

 The regular quote character is the backtick character - ```, but if the `ANSI_QUOTES` [SQL\_MODE](../sql-mode/index) option is specified, a regular double quote - `"` may be used as well.

 The backtick character can be used as part of an identifier. In that case the identifier needs to be quoted. The quote character can be the backtick, but in that case, the backtick in the name must be escaped with another backtick.

 ### Maximum Length

 * Databases, tables, columns, indexes, constraints, stored routines, triggers, events, views, tablespaces, servers and log file groups have a maximum length of 64 characters.
* Compound statement [labels](../labels/index) have a maximum length of 16 characters
* Aliases have a maximum length of 256 characters, except for column aliases in [CREATE VIEW](../create-view/index) statements, which are checked against the maximum column length of 64 characters (not the maximum alias length of 256 characters).
* Users have a maximum length of 80 characters.
* [Roles](../roles/index) have a maximum length of 128 characters.
* Multi-byte characters do not count extra towards towards the character limit.

 ### Multiple Identifiers

 MariaDB allows the column name to be used on its own if the reference will be unambiguous, or the table name to be used with the column name, or all three of the database, table and column names. A period is used to separate the identifiers, and the period can be surrounded by spaces.

 ### Examples

 Using the period to separate identifiers:

 
```
CREATE TABLE t1 (i int);

INSERT INTO t1(i) VALUES (10);

SELECT i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

SELECT t1.i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

SELECT test.t1.i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

```

The period can be separated by spaces:

 
```
SELECT test . t1 . i FROM t1;
+------+
| i    |
+------+
|   10 |
+------+

```

Resolving ambiguity:

 
```
CREATE TABLE t2 (i int);

SELECT i FROM t1 LEFT JOIN t2 ON t1.i=t2.i;
ERROR 1052 (23000): Column 'i' in field list is ambiguous

SELECT t1.i FROM t1 LEFT JOIN t2 ON t1.i=t2.i;
+------+
| i    |
+------+
|   10 |
+------+

```

Creating a table with characters that require quoting:

 
```
CREATE TABLE 123% (i int);
ERROR 1064 (42000): You have an error in your SQL syntax; 
  check the manual that corresponds to your MariaDB server version for the right syntax 
  to use near '123% (i int)' at line 1

CREATE TABLE `123%` (i int);
Query OK, 0 rows affected (0.85 sec)

CREATE TABLE `TABLE` (i int);
Query OK, 0 rows affected (0.36 sec)

```

Using double quotes as a quoting character:

 
```
CREATE TABLE "SELECT" (i int);
ERROR 1064 (42000): You have an error in your SQL syntax; 
  check the manual that corresponds to your MariaDB server version for the right syntax 
  to use near '"SELECT" (i int)' at line 1

SET sql_mode='ANSI_QUOTES';
Query OK, 0 rows affected (0.03 sec)

CREATE TABLE "SELECT" (i int);
Query OK, 0 rows affected (0.46 sec)

```

Using an identifier quote as part of an identifier name:

 
```
SHOW VARIABLES LIKE 'sql_mode';
+---------------+-------------+
| Variable_name | Value       |
+---------------+-------------+
| sql_mode      | ANSI_QUOTES |
+---------------+-------------+

CREATE TABLE "fg`d" (i int);
Query OK, 0 rows affected (0.34 sec)

```

Creating the table named `*` (Unicode number: U+002A) requires quoting.

 
```
CREATE TABLE `*` (a INT);

```

Floating point ambiguity:

 
```
CREATE TABLE 8984444cce5d (x INT);
Query OK, 0 rows affected (0.38 sec)

CREATE TABLE 8981e56cce5d (x INT);
ERROR 1064 (42000): You have an error in your SQL syntax; 
  check the manual that corresponds to your MariaDB server version for the right syntax 
  to use near '8981e56cce5d (x INT)' at line 1

CREATE TABLE `8981e56cce5d` (x INT);
Query OK, 0 rows affected (0.39 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/identifier-names/>

Identifier Case-sensitivity
===========================

    Whether objects are case-sensitive or not is partly determined by the underlying operating system. Unix-based systems are case-sensitive, Windows is not, while Mac OS X is usually case-insensitive by default, but devices can be configured as case-sensitive using Disk Utility.

 Database, table, table aliases and [trigger](../triggers/index) names are affected by the systems case-sensitivity, while index, column, column aliases, [stored routine](../stored-programs-and-views/index) and [event](../events/index) names are never case sensitive.

 Log file group name are case sensitive.

 The [lower\_case\_table\_names](../server-system-variables/index#lower_case_table_names) server system variable plays a key role. It determines whether table names, aliases and database names are compared in a case-sensitive manner. If set to 0 (the default on Unix-based systems), table names and aliases and database names are compared in a case-sensitive manner. If set to 1 (the default on Windows), names are stored in lowercase and not compared in a case-sensitive manner. If set to 2 (the default on Mac OS X), names are stored as declared, but compared in lowercase. 

 It is thus possible to make Unix-based systems behave like Windows and ignore case-sensitivity, but the reverse is not true, as the underlying Windows filesystem can not support this.

 Even on case-insensitive systems, you are required to use the same case consistently within the same statement. The following statement fails, as it refers to the table name in a different case.

 
```
SELECT * FROM a_table WHERE A_table.id>10;

```

For a full list of identifier naming rules, see [Identifier Names](../identifier-names/index).

 Please note that [lower\_case\_table\_names](../server-system-variables/index#lower_case_table_names) is a database initialization parameter. This means that, along with [innodb\_page\_size](../server-system-variables/index#innodb_page_size), this variable must be set before running [mariadb-install-db](../mariadb-install-db/index), and will not change the behavior of servers unless applied before the creation of core system databases.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/identifier-case-sensitivity/>

Binary Literals
===============

    Binary literals can be written in one of the following formats: `b'value'`, `B'value'` or `0bvalue`, where `value` is a string composed by `0` and `1` digits.

 Binary literals are interpreted as binary strings, and are convenient to represent [VARBINARY](../varbinary/index), [BINARY](../binary/index) or [BIT](../bit/index) values.

 To convert a binary literal into an integer, just add 0.

 Examples
--------

 Printing the value as a binary string:

 
```
SELECT 0b1000001;
+-----------+
| 0b1000001 |
+-----------+
| A         |
+-----------+

```

Converting the same value into a number:

 
```
SELECT 0b1000001+0;
+-------------+
| 0b1000001+0 |
+-------------+
|          65 |
+-------------+

```

See Also
--------

 * [BIN()](../bin/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/binary-literals/>

CSV Overview
============

     The CSV Storage Engine can read and append to files stored in CSV (comma-separated-values) format.

 However, since [MariaDB 10.0](../what-is-mariadb-100/index), a better storage engine is able to read and write such files: [CONNECT](../connect/index).

 The CSV storage engine and logging to tables
--------------------------------------------

 The CSV storage engine is the default storage engine when using [logging of SQL queries](../writing-logs-into-tables/index) to tables.

 
```
mysqld --log-output=table

```

CSV Storage Engine files
------------------------

 When you create a table using the CSV storage engine, three files are created:

 * `<table_name>.frm`
* `<table_name>.CSV`
* `<table_name>.CSM`

 The `.frm` file is the table format file.

 The `.CSV` file is a plain text file. Data you enter into the table is stored as plain text in comma-separated-values format.

 The `.CSM` file stores metadata about the table such as the state and the number of rows in the table.

 Limitations
-----------

 * CSV tables do not support indexing.
* CSV tables cannot be partitioned.
* Columns in CSV tables must be declared as NOT NULL.
* No [transactions](../transactions/index).
* The original CSV-format does not enable IETF-compatible parsing of embedded quote and comma characters. From [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/), it is possible to do so by setting the [IETF\_QUOTES](../create-table/index#ietf_quotes) option when creating a table.

 Examples
--------

 Forgetting to add NOT NULL:

 
```
CREATE TABLE csv_test (x INT, y DATE, z CHAR(10)) ENGINE=CSV;
ERROR 1178 (42000): The storage engine for the table doesn't support nullable columns

```

Creating, inserting and selecting:

 
```
CREATE TABLE csv_test (
  x INT NOT NULL, y DATE NOT NULL, z CHAR(10) NOT NULL
  ) ENGINE=CSV;

```


```
INSERT INTO csv_test VALUES
    (1,CURDATE(),'one'),
    (2,CURDATE(),'two'),
    (3,CURDATE(),'three');

```


```
SELECT * FROM csv_test;
+---+------------+-------+
| x | y          | z     |
+---+------------+-------+
| 1 | 2011-11-16 | one   |
| 2 | 2011-11-16 | two   |
| 3 | 2011-11-16 | three |
+---+------------+-------+

```

Viewing in a text editor:

 
```
$ cat csv_test.CSV
1,"2011-11-16","one"
2,"2011-11-16","two"
3,"2011-11-16","three"

```

See Also
--------

 * [Checking and Repairing CSV Tables](../checking-and-repairing-csv-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/csv-overview/>

Boolean Literals
================

    In MariaDB, `FALSE` is a synonym of 0 and `TRUE` is a synonym of 1. These constants are case insensitive, so `TRUE`, `True`, and `true` are equivalent.

 These terms are not synonyms of 0 and 1 when used with the `[IS](../is/index)` operator. So, for example, `10 IS TRUE` returns 1, while `10 = TRUE` returns 0 (because 1 != 10).

 The `IS` operator accepts a third constant exists: `UNKNOWN`. It is always a synonym of [NULL](../null-values-in-mariadb/index).

 `TRUE` and `FALSE` are [reserved words](../reserved-words/index), while `UNKNOWN` is not.

 See Also
--------

 * [BOOLEAN](../boolean/index) type

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-language-structure-boolean-literals/>

SQLSTATE
========

    SQLSTATE is a code which identifies SQL error conditions. It composed by five characters, which can be numbers or uppercase ASCII letters. An SQLSTATE value consists of a class (first two characters) and a subclass (last three characters).

 There are three important standard classes. They all indicate in which logical group of errors the condition falls. They match to a particular keyword which can be used with [DECLARE HANDLER](../declare-handler/index). Also, the SQLSTATE class determines the default value for the MYSQL\_ERRNO and MESSAGE\_TEXT condition properties.

 * '00' means 'success'. It can not be set in any way, and can only be read via the API.
* '01' contains all warnings, and matches to the SQLWARNING keyword. The default MYSQL\_ERRNO is 1642 and default MESSAGE\_TEXT is 'Unhandled user-defined warning condition'.
* '02' is the NOT FOUND class. The default MYSQL\_ERRNO is 1643 and default MESSAGE\_TEXT is 'Unhandled user-defined not found condition'.
* All other classes match the SQLEXCEPTION keyword. The default MYSQL\_ERRNO is 1644 and default MESSAGE\_TEXT is 'Unhandled user-defined exception condition'.

 The subclass, if it is set, indicates a particular condition, or a particular group of conditions within the class. However the '000' sequence means 'no subclass'.

 For example, if you try to [SELECT](../select/index) from a table which does not exist, a 1109 error is produced, with a '42S02' SQLSTATE. '42' is the class and 'S02' is the subclass. This value matches to the SQLEXCEPTION keyword. When FETCH is called for a [cursor](../programmatic-and-compound-statements-cursors/index) which has already reached the end, a 1329 error is produced, with a '02000' SQLSTATE. The class is '02' and there is no subclass (because '000' means 'no subclass'). It can be handled by a NOT FOUND handlers.

 The standard SQL specification says that classes beginning with 0, 1, 2, 3, 4, A, B, C, D, E, F and G are reserved for standard-defined classes, while other classes are vendor-specific. It also says that, when the class is standard-defined, subclasses starting with those characters (except for '000') are standard-defined subclasses, while other subclasses are vendor-defined. However, MariaDB and MySQL do not strictly obey this rule.

 To read the SQLSTATE of a particular condition which is in the [diagnostics area](../diagnostics-area/index), the [GET DIAGNOSTICS](../get-diagnostics/index) statement can be used: the property is called RETURNED\_SQLSTATE. For user-defined conditions ([SIGNAL](../signal/index) and [RESIGNAL](../resignal/index) statements), a SQLSTATE value must be set via the SQLSTATE clause. However, [SHOW WARNINGS](../show-warnings/index) and [SHOW ERRORS](../show-errors/index) do not display the SQLSTATE.

 For user-defined conditions, MariaDB and MySQL recommend the '45000' SQLSTATE class.

 'HY000' is called the "general error": it is the class used for builtin conditions which do not have a specific SQLSTATE class.

 A partial list of error codes and matching SQLSTATE values can be found in the page [MariaDB Error Codes](../mariadb-error-codes/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sqlstate/>

GeoJSON
========

   GeoJSON is a format for encoding various geographic data structures.

  

| Title | Description |
| --- | --- |
|  [ST\_AsGeoJSON](../geojson-st_asgeojson/index) |  Returns the given geometry as a GeoJSON element.  |
|  [ST\_GeomFromGeoJSON](../st_geomfromgeojson/index) |  Given a GeoJSON input, returns a geometry object  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geojson/>

aria\_chk
=========

     `aria_chk` is used to check, repair, optimize, sort and get information about [Aria](../aria/index) tables.

 With the MariaDB server you can use [CHECK TABLE](../sql-commands-check-table/index), [REPAIR TABLE](../repair-table/index) and [OPTIMIZE TABLE](../optimize-table/index) to do similar things.

 
Note: `aria_chk` should not be used when MariaDB is running. MariaDB assumes that no one is changing the tables it's using!

 
Usage:

 
```
aria_chk [OPTIONS] aria_tables[.MAI]

```

Aria table information is stored in 2 files: the `.MAI` file contains base table information and the index and the `.MAD` file contains the data. `aria_chk` takes one or more `.MAI` files as arguments.

 The following groups are read from the my.cnf files:

 * `[maria_chk]`
* `[aria_chk]`

 Options and Variables
---------------------

 ### Global Options

 The following options to handle option files may be given as the first argument:

 


| Option | Description |
| --- | --- |
| ``--`print-defaults` | Print the program argument list and exit. |
| ``--`no-defaults` | Don't read default options from any option file. |
| ``--`defaults-file=#`  | Only read default options from the given file #. |
| ``--`defaults-extra-file=#`  | Read this file after the global files are read. |

 
### Main Arguments

 


| Option | Description |
| --- | --- |
| `-`#``, ``--`debug=...` | Output debug log. Often this is 'd:t:o,filename'. |
| `-H`, ``--`HELP` | Display this help and exit. |
| `-?`, ``--`help` | Display this help and exit. |
| ``--`datadir=path` | Path for control file (and logs if `--logdir` not used). |
| ``--`ignore-control-file` | Don't open the control file. Only use this if you are sure the tables are not used by another program |
| ``--`logdir=path` | Path for log files. |
| ``--`require-control-file` | Abort if we can't find/read the maria\_log\_control file |
| `-s`, ``--`silent` | Only print errors. One can use two -s to make aria\_chk very silent. |
| `-t`, ``--`tmpdir=path` | Path for temporary files. Multiple paths can be specified, separated by colon (:) on Unix or semicolon (;) on Windows. They will be used in a round-robin fashion. |
| `-v`, ``--`verbose` | Print more information. This can be used with `--description` and `--check`. Use many -v for more verbosity. |
| `-V`, ``--`version` | Print version and exit. |
| `-w`, ``--`wait` | Wait if table is locked. |

 
### Check Options (--check is the Default Action for aria\_chk):

 


| Option | Description |
| --- | --- |
| `-c`, ``--`check` | Check table for errors. |
| `-e`, ``--`extend-check` | Check the table VERY throughly. Only use this in extreme cases as aria\_chk should normally be able to find out if the table is ok even without this switch. |
| `-F`, ``--`fast` | Check only tables that haven't been closed properly. |
| `-C`, ``--`check-only-changed` | Check only tables that have changed since last check. |
| `-f`, ``--`force` | Restart with '`-r`' if there are any errors in the table. States will be updated as with '`--update-state`'. |
| `-i`, ``--`information` | Print statistics information about table that is checked. |
| `-m`, ``--`medium-check` | Faster than extend-check, and finds 99.99% of all errors. Should be good enough for most cases. |
| `-U`, ``--`update-state` | Mark tables as crashed if any errors were found and clean if check didn't find any errors but table was marked as 'not clean' before. This allows one to get rid of warnings like 'table not properly closed'. If table was updated, update also the timestamp for when the check was made. This option is on by default! Use `--skip-update-state` to disable. |
| `-T`, ``--`read-only` | Don't mark table as checked. |

 
### Recover (Repair) Options (When Using '--recover' or '--safe-recover'):

 


| Option | Description |
| --- | --- |
| `-B`, ``--`backup` | Make a backup of the .MAD file as 'filename-time.BAK'. |
| ``--`correct-checksum` | Correct checksum information for table. |
| `-D`, ``--`data-file-length=`#`` | Max length of data file (when recreating data file when it's full). |
| `-e`, ``--`extend-check` | Try to recover every possible row from the data file Normally this will also find a lot of garbage rows; Don't use this option if you are not totally desperate. |
| `-f`, ``--`force` | Overwrite old temporary files. |
| `-k`, ``--`keys-used=`#`` | Tell MARIA to update only some specific keys. # is a bit mask of which keys to use. This can be used to get faster inserts. |
| ``--`max-record-length=`#`` | Skip rows bigger than this if aria\_chk can't allocate memory to hold it. |
| `-r`, ``--`recover` | Can fix almost anything except unique keys that aren't unique. |
| `-n`, ``--`sort-recover` | Forces recovering with sorting even if the temporary file would be very big. |
| `-p`, ``--`parallel-recover` | Uses the same technique as '-r' and '-n', but creates all the keys in parallel, in different threads. |
| `-o`, ``--`safe-recover` | Uses old recovery method; Slower than '-r' but can handle a couple of cases where '-r' reports that it can't fix the data file. |
| ``--`transaction-log` | Log repair command to transaction log. This is needed if one wants to use the maria\_read\_log to repeat the repair. |
| ``--`character-sets-dir=...` | Directory where character sets are. |
| ``--`set-collation=name` | Change the collation used by the index. |
| `-q`, ``--`quick` | Faster repair by not modifying the data file. One can give a second '`-q`' to force aria\_chk to modify the original datafile in case of duplicate keys. NOTE: Tables where the data file is currupted can't be fixed with this option. |
| `-u`, ``--`unpack` | Unpack file packed with [aria\_pack](../aria_pack/index). |

 
### Other Options

 


| Option | Description |
| --- | --- |
| `-a`, ``--`analyze` | Analyze distribution of keys. Will make some joins in MariaDB faster. You can check the calculated distribution by using '`--description --verbose table_name`'. |
| ``--`stats_method=name` | Specifies how index statistics collection code should treat NULLs. Possible values of name are "nulls\_unequal" (default for 4.1/5.0), "nulls\_equal" (emulate 4.0), and "nulls\_ignored". |
| `-d`, ``--`description` | Prints some information about table. |
| `-A`, ``--`set-auto-increment[=value]` | Force auto\_increment to start at this or higher value If no value is given, then sets the next auto\_increment value to the highest used value for the auto key + 1. |
| `-S`, ``--`sort-index` | Sort index blocks. This speeds up 'read-next' in applications. |
| `-R`, ``--`sort-records=`#`` | Sort records according to an index. This makes your data much more localized and may speed up things (It may be VERY slow to do a sort the first time!). |
| `-b`, ``--`block-search=`#`` | Find a record, a block at given offset belongs to. |
| `-z`, ``--`zerofill` | Remove transaction id's from the data and index files and fills empty space in the data and index files with zeroes. Zerofilling makes it possible to move the table from one system to another without the server having to do an automatic zerofill. It also allows one to compress the tables better if one want to archive them. |
| ``--`zerofill-keep-lsn` | Like `--zerofill` but does not zero out LSN of data/index pages. |

 
### Variables

 


| Option | Description |
| --- | --- |
| `page_buffer_size` | Size of page buffer. Used by `--safe-repair` |
| `read_buffer_size` | Read buffer size for sequential reads during scanning |
| `write_buffer_size` | Write buffer size for sequential writes during repair of fixed size or dynamic size rows |
| `sort_buffer_size` | Size of sort buffer. Used by `--recover` |
| `sort_key_blocks` | Internal buffer for sorting keys; Don't touch :) |

 
Usage
-----

 One main usage of `aria_chk` is when you want to do a fast check of all Aria tables in your system. This is faster than doing it in MariaDB as you can allocate all free memory to the buffers.

 Assuming you have a bit more than 2G free memory.

 The following commands, run in the MariaDB data directory, check all your tables and repairs only those that have an error:

 
```
aria_chk --check --sort_order --force --sort_buffer_size=1G */*.MAI

```

If you want to optimize all your tables: (The `--zerofill` is used here to fill up empty space with `\0` which can speed up compressed backups).

 
```
aria_chk --analyze --sort-index --page_buffer_size=1G --zerofill */*.MAI

```

In case you have a serious problem and have to use `--safe-recover`:

 
```
aria_chk --safe-recover --zerofill --page_buffer_size=2G */*.MAI

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria_chk/>

Identifier Qualifiers
=====================

     Qualifiers are used within SQL statements to reference data structures, such as databases, tables, or columns. For example, typically a SELECT query contains references to some columns and at least one table.

 Qualifiers can be composed by one or more [identifiers](../identifier-names/index), where the initial parts affect the context within which the final identifier is interpreted:

 * For a database, only the database identifier needs to be specified.
* For objects which are contained in a database (like tables, views, functions, etc) the database identifier can be specified. If no database is specified, the current database is assumed (see [USE](../use/index) and [DATABASE()](../database/index) for more details). If there is no default database and no database is specified, an error is issued.
* For column names, the table and the database are generally obvious from the context of the statement. It is however possible to specify the table identifier, or the database identifier plus the table identifier.
* An identifier is fully-qualified if it contains all possible qualifiers, for example, the following column is fully qualified: `db_name.tbl_name.col_name`.

 If a qualifier is composed by more than one identifier, a dot (.) must be used as a separator. All identifiers can be quoted individually. Extra spacing (including new lines and tabs) is allowed.

 All the following examples are valid:

 * db\_name.tbl\_name.col\_name
* tbl\_name
* `db\_name`.`tbl\_name`.`col\_name`
* `db\_name` . `tbl\_name`
* db\_name. tbl\_name

 If a table identifier is prefixed with a dot (.), the default database is assumed. This syntax is supported for ODBC compliance, but has no practical effect on MariaDB. These qualifiers are equivalent:

 * tbl\_name
* . tbl\_name
* .`tbl\_name`
* . `tbl\_name`

 For DML statements, it is possible to specify a list of the partitions using the PARTITION clause. See [Partition Pruning and Selection](../partition-pruning-and-selection/index) for details.

 See Also
--------

 * [Identifier Names](../identifier-names/index)
* [USE](../use/index)
* [DATABASE()](../database/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/identifier-qualifiers/>

GIS features in 5.3.3
=====================

    Basic information about the existing spatial features can be found in the [Geographic Features](../geographic-features/index) section of the Knowlegebase. The [Spatial Extensions page of the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html) also applies to MariaDB.

 The [MariaDB 5.3.3](https://mariadb.com/kb/en/mariadb-533-release-notes/) release , contains code improving the spatial functionality in MariaDB.

 MySQL operates on spatial data based on the OpenGIS standards, particularly the [OpenGIS SFS](http://www.opengeospatial.org/standards/sfs) (Simple feature access, SQL option).

 Initial support was based on version 05-134 of the standard. MariaDB implements a subset of the 'SQL with Geometry Types' environment proposed by the OGC. And the SQL environment was extended with a set of geometry types.

 MariaDB supports spatial extensions to operate on spatial features. These features are available for [Aria](../aria/index), [MyISAM](../myisam/index), [InnoDB](../innodb/index), NDB, and [ARCHIVE](../archive/index) tables.

 For spatial columns, Aria and MyISAM supports both [SPATIAL](../spatial-indexes/index) and non-SPATIAL indexes. Other storage engines support non-SPATIAL indexes.

 The most recent changes in the code are aimed at meeting the OpenGIS requirements. One thing missed in previous versions is that the functions which check spatial relations didn't consider the actual shape of an object, instead they operate only on their bounding rectangles. These legacy functions have been left as they are and new, properly-working functions are named with an '`ST_`' prefix, in accordance with the latest OpenGIS requirements. Also, operations over geometry features were added.

 The list of new functions:

 Spatial operators. They produce new geometries.

 


| Name | Description |
| --- | --- |
| [ST\_UNION(A, B)](../st_union/index) | union of A and B |
| [ST\_INTERSECTION(A, B)](../st_intersection/index) | intersection of A and B |
| [ST\_SYMDIFFERENCE(A, B)](../st_symdifference/index) | symdifference, notintersecting parts of A and B |
| [ST\_BUFFER(A, radius)](../st_buffer/index) | returns the shape of the area that lies in 'radius' distance from the shape A. |

 Predicates, return boolean result of the relationship

 

| Name | Description |
| --- | --- |
| [ST\_INTERSECTS(A, B)](../st_intersects/index) | if A and B have an intersection |
| [ST\_CROSSES(A, B)](../st_crosses/index) | if A and B cross |
| [ST\_EQUALS(A, B)](../st_equals/index) | if A and B are equal |
| [ST\_WITHIN(A, B)](../st_within/index) | if A lies within B |
| [ST\_CONTAINS(A,B)](../st_contains/index) | if B lies within A |
| [ST\_DISJOINT(A,B)](../st_disjoint/index) | if A and B have no intersection |
| [ST\_TOUCHES(A,B)](../st_touches/index) | if A touches B |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/gis-features-in-533/>

MariaDB Plans - GIS
===================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

 
 OpenGIS compliance:

 * create required tables: GeometryTables, GeometryColumns, related views.
* stored procedure AddGeometryColumn
* prefill the spatial\_ref\_sys table.

 Optimizer:

 * optimize simple queries with Intersects(), Within, Distance()<X
* add Distance\_sphere() and the related optimization.

 Add possible III-rd coordinate (Attitude).

 * Distance3D, related optimization.

 Precise math coordinates instead of DOUBLE-s.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-plans-gis/>

Numeric Literals
================

    Numeric literals are written as a sequence of digits from `0` to `9`. Initial zeros are ignored. A sign can always precede the digits, but it is optional for positive numbers. In decimal numbers, the integer part and the decimal part are divided with a dot (`.`).

 If the integer part is zero, it can be omitted, but the literal must begin with a dot.

 The notation with exponent can be used. The exponent is preceded by an `E` or `e` character. The exponent can be preceded by a sign and must be an integer. A number `N` with an exponent part `X`, is calculated as `N * POW(10, X)`.

 In some cases, adding zeroes at the end of a decimal number can increment the precision of the expression where the number is used. For example, `[PI()](../pi/index)` by default returns a number with 6 decimal digits. But the `PI()+0.0000000000` expression (with 10 zeroes) returns a number with 10 decimal digits.

 [Hexadecimal literals](../hexadecimal-literals/index) are interpreted as numbers when used in numeric contexts.

 Examples
--------

 
```
10
+10
-10

```

All these literals are equivalent:

 
```
0.1
.1
+0.1
+.1

```

With exponents:

 
```
0.2E3 -- 0.2 * POW(10, 3) = 200
.2e3
.2e+2
1.1e-10 -- 0.00000000011
-1.1e10 -- -11000000000

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/numeric-iterals/>

Geometry Hierarchy
==================

    Description
-----------

 Geometry is the base class. It is an abstract class. The instantiable subclasses of Geometry are restricted to zero-, one-, and two-dimensional geometric objects that exist in two-dimensional coordinate space. All instantiable geometry classes are defined so that valid instances of a geometry class are topologically closed (that is, all defined geometries include their boundary).

 The base Geometry class has subclasses for Point, Curve, Surface, and GeometryCollection:

 * [Point](../point/index) represents zero-dimensional objects.
* Curve represents one-dimensional objects, and has subclass [LineString](../linestring/index), with sub-subclasses Line and LinearRing.
* Surface is designed for two-dimensional objects and has subclass [Polygon](../polygon/index).
* [GeometryCollection](../geometrycollection/index) has specialized zero-, one-, and two-dimensional collection classes named [MultiPoint](../multipoint/index), [MultiLineString](../multilinestring/index), and [MultiPolygon](../multipolygon/index) for modeling geometries corresponding to collections of Points, LineStrings, and Polygons, respectively. MultiCurve and MultiSurface are introduced as abstract superclasses that generalize the collection interfaces to handle Curves and Surfaces.

 Geometry, Curve, Surface, MultiCurve, and MultiSurface are defined as non-instantiable classes. They define a common set of methods for their subclasses and are included for extensibility.

 [Point](../point-properties/index), [LineString](../linestring-properties/index), [Polygon](../polygon-properties/index), [GeometryCollection](../geometrycollection/index), [MultiPoint](../multipoint/index), [MultiLineString](../multilinestring/index), and [MultiPolygon](../multipolygon/index) are instantiable classes.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-hierarchy/>

User-Defined Variables
======================

     User-defined variables are variables which can be created by the user and exist in the session. This means that no one can access user-defined variables that have been set by another user, and when the session is closed these variables expire. However, these variables can be shared between several queries and [stored programs](../stored-programs-and-views/index).

 User-defined variables names must be preceded by a single *at* character (`@`). While it is safe to use a reserved word as a user-variable name, the only allowed characters are ASCII letters, digits, dollar sign (`$`), underscore (`_`) and dot (`.`). If other characters are used, the name can be quoted in one of the following ways:

 * @`var\_name`
* @'var\_name'
* @"var\_name"

 These characters can be escaped as usual.

 User-variables names are case insensitive, though they were case sensitive in MySQL 4.1 and older versions.

 User-defined variables cannot be declared. They can be read even if no value has been set yet; in that case, they are NULL. To set a value for a user-defined variable you can use:

 * [SET](../set/index) statement;
* [:=](../assignment-operator/index) operator within a SQL statement;
* [SELECT ... INTO](../select-into/index).

 Since user-defined variables type cannot be declared, the only way to force their type is using [CAST()](../cast/index) or [CONVERT()](../convert/index):

 
```
SET @str = CAST(123 AS CHAR(5));

```

If a variable has not been used yet, its value is NULL:

 
```
SELECT @x IS NULL;
+------------+
| @x IS NULL |
+------------+
|          1 |
+------------+

```

It is unsafe to read a user-defined variable and set its value in the same statement (unless the command is SET), because the order of these actions is undefined.

 User-defined variables can be used in most MariaDB's statements and clauses which accept an SQL expression. However there are some exceptions, like the [LIMIT](../select/index#limit) clause.

 They must be used to [PREPARE](../prepare-statement/index) a prepared statement:

 
```
@sql = 'DELETE FROM my_table WHERE c>1;';
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

```

Another common use is to include a counter in a query:

 
```
SET @var = 0;
SELECT a, b, c, (@var:=@var+1) AS counter FROM my_table;

```

Information Schema
------------------

 User-defined variables can be viewed in the [Information Schema USER\_VARIABLES Table](../information-schema-user_variables-table/index) (as part of the [User Variables plugin](../user-variables-plugin/index)) from [MariaDB 10.2](../what-is-mariadb-102/index).

 Flushing User-Defined Variables
-------------------------------

 User-defined variables are reset and the [Information Schema table](../information-schema-user_variables-table/index) emptied with the [FLUSH USER\_VARIABLES](../flush/index) statement.

 
```
SET @str = CAST(123 AS CHAR(5));

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| str           | 123            | VARCHAR       | utf8mb3            |
+---------------+----------------+---------------+--------------------+

FLUSH USER_VARIABLES;

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
Empty set (0.000 sec)

```

See Also
--------

 * [DECLARE VARIABLE](../declare-variable/index)
* [Performance Schema user\_variables\_by\_thread Table](../performance-schema-user_variables_by_thread-table/index)
* [Information Schema USER\_VARIABLES Table](../information-schema-user_variables-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-defined-variables/>

Hexadecimal Literals
====================

     Hexadecimal literals can be written using any of the following syntaxes:

 * x'`value`'
* X'`value`' (SQL standard)
* 0x`value` (ODBC)

 `value` is a sequence of hexadecimal digits (from `0` to `9` and from `A` to `F`). The case of the digits does not matter. With the first two syntaxes, `value` must consist of an even number of digits. With the last syntax, digits can be even, and they are treated as if they had an extra 0 at the beginning.

 Normally, hexadecimal literals are interpreted as binary string, where each pair of digits represents a character. When used in a numeric context, they are interpreted as integers. (See the example below). In no case can a hexadecimal literal be a decimal number.

 The first two syntaxes; `X'value'` and x'`value`, follow the SQL standard, and behave as a string in all contexts in MariaDB since [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/) and [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/) (fixing [MDEV-4489](https://jira.mariadb.org/browse/MDEV-4489)). The latter syntax, 0x`value`, is a MySQL/MariaDB extension for hex hybrids and behaves as a string or as a number depending on context. MySQL treats all syntaxes the same, so there may be different results in MariaDB and MySQL (see below).

 Examples
--------

 Representing the `a` character with the three syntaxes explained above:

 
```
SELECT x'61', X'61', 0x61;
+-------+-------+------+
| x'61' | X'61' | 0x61 |
+-------+-------+------+
| a     | a     | a    |
+-------+-------+------+

```

Hexadecimal literals in a numeric context:

 
```
SELECT 0 + 0xF, -0xF;
+---------+------+
| 0 + 0xF | -0xF |
+---------+------+
|      15 |  -15 |
+---------+------+

```

### Fun with Types

 
```
CREATE TABLE t1 (a INT, b VARCHAR(10));
INSERT INTO t1 VALUES (0x31, 0x61),(COALESCE(0x31), COALESCE(0x61));

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|   49 | a    |
|    1 | a    |
+------+------+

```

The reason for the differing results above is that when 0x31 is inserted directly to the column, it's treated as a number, while when 0x31 is passed to [COALESCE()](../coalesce/index), it's treated as a string, because:

 * HEX values have a string data type by default.
* COALESCE() has the same data type as the argument.

 ### Differences Between MariaDB and MySQL

 
```
SELECT x'0a'+0;
+---------+
| x'0a'+0 |
+---------+
|       0 |
+---------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: '\x0A'

SELECT X'0a'+0;
+---------+
| X'0a'+0 |
+---------+
|       0 |
+---------+
1 row in set, 1 warning (0.00 sec)

Warning (Code 1292): Truncated incorrect DOUBLE value: '\x0A'

SELECT 0x0a+0;
+--------+
| 0x0a+0 |
+--------+
|     10 |
+--------+

```

In MySQL (up until at least MySQL 8.0.26):

 
```
SELECT x'0a'+0;
+---------+
| x'0a'+0 |
+---------+
|      10 |
+---------+

SELECT X'0a'+0;
+---------+
| X'0a'+0 |
+---------+
|      10 |
+---------+

SELECT 0x0a+0;
+--------+
| 0x0a+0 |
+--------+
|     10 |
+--------+

```

See Also
--------

 * [HEX()](../hex/index)
* [UNHEX()](../unhex/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hexadecimal-literals/>

Checking and Repairing CSV Tables
=================================

    [CSV tables](../csv/index) support the [CHECK TABLE](../check-table/index) and [REPAIR TABLE](../repair-table/index) statements.

 CHECK TABLE will mark the table as corrupt if it finds a problem, while REPAIR TABLE will restore rows until the first corrupted row, discarding the rest.

 Examples
--------

 
```
CREATE TABLE csv_test (
  x INT NOT NULL, y DATE NOT NULL, z CHAR(10) NOT NULL
  ) ENGINE=CSV;

INSERT INTO csv_test VALUES
    (1,CURDATE(),'one'),
    (2,CURDATE(),'two'),
    (3,CURDATE(),'three');

```


```
SELECT * FROM csv_test;
+---+------------+-------+
| x | y          | z     |
+---+------------+-------+
| 1 | 2013-07-08 | one   |
| 2 | 2013-07-08 | two   |
| 3 | 2013-07-08 | three |
+---+------------+-------+

```

Using an editor, the actual file will look as follows

 
```
$ cat csv_test.CSV
1,"2013-07-08","one"
2,"2013-07-08","two"
3,"2013-07-08","three"

```

Let's introduce some corruption with an unwanted quote in the 2nd row:

 
```
1,"2013-07-08","one"
2","2013-07-08","two"
3,"2013-07-08","three"

```


```
CHECK TABLE csv_test;
+---------------+-------+----------+----------+
| Table         | Op    | Msg_type | Msg_text |
+---------------+-------+----------+----------+
| test.csv_test | check | error    | Corrupt  |
+---------------+-------+----------+----------+

```

We can repair this, but all rows from the corrupt row onwards will be lost:

 
```
REPAIR TABLE csv_test;
+---------------+--------+----------+----------------------------------------+
| Table         | Op     | Msg_type | Msg_text                               |
+---------------+--------+----------+----------------------------------------+
| test.csv_test | repair | Warning  | Data truncated for column 'x' at row 2 |
| test.csv_test | repair | status   | OK                                     |
+---------------+--------+----------+----------------------------------------+

SELECT * FROM csv_test;
+---+------------+-----+
| x | y          | z   |
+---+------------+-----+
| 1 | 2013-07-08 | one |
+---+------------+-----+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/checking-and-repairing-csv-tables/>

Table Value Constructors
========================

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**Table Value Constructors were introduced in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)

 
Syntax
------

 
```
VALUES ( row_value[, row_value...]), (...)...

```

Description
-----------

 In Unions, Views, and sub-queries, a Table Value Constructor (TVC) allows you to inject arbitrary values into the result-set. The given values must have the same number of columns as the result-set, otherwise it returns Error 1222.

 Examples
--------

 Using TVC's with `[UNION](../union/index)` operations:

 
```
CREATE TABLE test.t1 (val1 INT, val2 INT);
INSERT INTO test.t1 VALUES(5, 8), (3, 4), (1, 2);

SELECT * FROM test.t1
UNION
VALUES (70, 90), (100, 110);

+------+------+
| val1 | val2 |
+------+------+
|    5 |    8 | 
|    3 |    4 |
|    1 |    2 |
|   70 |   90 |
|  100 |  110 |
+------+------+

```

Using TVC's with a `[CREATE VIEW](../create-view/index)` statement:

 
```
CREATE VIEW v1 AS VALUES (7, 9), (9, 10);

SELECT * FROM v1;
+---+----+
| 7 |  9 |
+---+----+
| 7 |  9 |
| 9 | 10 |
+---+----+

```

Using TVC with an `[ORDER BY](../order-by/index)` clause:

 
```
SELECT * FROM test.t1
UNION
VALUES (10, 20), (30, 40), (50, 60), (70, 80)
ORDER BY val1 DESC;

```

Using TVC with `[LIMIT](../limit/index)` clause:

 
```
SELECT * FROM test.t1
UNION
VALUES (10, 20), (30, 40), (50, 60), (70, 80)
LIMIT 2 OFFSET 4;

+------+------+
| val1 | val2 |
+------+------+
|   30 |   40 | 
|   50 |   60 |
+------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-value-constructors/>

The maria/5.3-gis tree on Launchpad.
====================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

 
 The maria/5.3-gis tree on Launchpad.

 Basic information about the existing spatial features can be found in the [Geographic Features](../geographic-features/index) section of the Knowlegebase. The [Spatial Extensions page of the MySQL manual](http://dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html) also applies to MariaDB.

 The [maria/5.3-gis tree](https://code.launchpad.net/~maria-captains/maria/5.3-gis), contains recent code improving the spatial functionality in MariaDB.

 MySQL operates on spatial data based on the OpenGIS standards, particularly the [OpenGIS SFS](http://www.opengeospatial.org/standards/sfs) (Simple feature access, SQL option).

 Initial support was based on version 05-134 of the standard. MariaDB implements a subset of the 'SQL with Geometry Types' environment proposed by the OGC. And the SQL environment was extended with a set of geometry types.

 Now we have started to implement the newer 06-104r4 standard.

 MariaDB supports spatial extensions to operate on spatial features. These features are available for Aria, MyISAM, InnoDB, NDB, and ARCHIVE tables.

 For spatial columns, Aria and MyISAM supports both SPATIAL and non-SPATIAL indexes. Other storage engines support non-SPATIAL indexes.

 The most recent changes in the code are aimed at meeting the OpenGIS requirements. One thing missing in the present version is that the functions which check spatial relations don't consider the actual shape of an object, instead they operate only on their bounding rectangles. These legacy functions have been left as they are, and new, properly-working functions are named with an '`ST_`' prefix, in accordance with the last OpenGIS requirements. Also, operations over geometry features were added.

 The list of new functions:

 Spatial operators. They produce new geometries.

 


| Name | Description |
| --- | --- |
| `ST_UNION(A, B)` | union of A and B |
| `ST_INTERSECTION(A, B)` | intersection of A and B |
| `ST_SYMDIFFERENCE(A, B)` | symdifference, notintersecting parts of A and B |
| `ST_BUFFER(A, radius)` | returns the shape of the area that lies in 'radius' distance from the shape A. |

 Predicates, return boolean result of the relationship

 

| Name | Description |
| --- | --- |
| `ST_INTERSECTS(A, B)` | if A and B have an intersection |
| `ST_CROSSES(A, B)` | if A and B cross |
| `ST_EQUAL(A, B)` | if A nad B are equal |
| `ST_WITHIN(A, B)` | if A lies within B |
| `ST_CONTAINS(A,B)` | if B lies within A |
| `ST_DISJOINT(A,B)` | if A and B have no intersection |
| `ST_TOUCHES(A,B)` | if A touches B |

 
Geometry metadata views:

 


|  |  |
| --- | --- |
| `GEOMETRY_COLUMNS` | *this table describes the available feature tables and their Geometry properties* |
| fields: | `F_TABLE_CATALOG VARCHAR(200) NOT NULL,` |
|  | `F_TABLE_SCHEMA VARCHAR(200) NOT NULL,` |
|  | `F_TABLE_NAME VARCHAR(200) NOT NULL,` |
|  | `F_GEOMETRY_COLUMN VARCHAR(200) NOT NULL,` |
|  | `G_TABLE_CATALOG VARCHAR(200) NOT NULL,` |
|  | `G_TABLE_SCHEMA VARCHAR(200) NOT NULL,` |
|  | `G_TABLE_NAME VARCHAR(200) NOT NULL,` |
|  | `STORAGE_TYPE INTEGER,` |
|  | `GEOMETRY_TYPE INTEGER,` |
|  | `COORD_DIMENSION INTEGER,` |
|  | `MAX_PPR INTEGER,` |
|  | `SRID INTEGER NOT NULL` |
|  |  |
|  |  |
| SPATIAL\_REF\_SYS | *this table describes the coordinate system and transformations for Geometry* |
| fields: | `SRID INTEGER NOT NULL PRIMARY KEY,` |
|  | `AUTH_NAME VARCHAR(200),` |
|  | `AUTH_SRID INTEGER,` |
|  | `SRTEXT TEXT` |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-maria53-gis-tree-on-launchpad/>

GIS Resources
=============

    Here are a few resources for those interested in GIS in MariaDB.

 * [OGC Simple Feature Access](http://www.opengeospatial.org/standards/sfs) - the Open Geospatial Consortium's OpenGIS Simple Features Specifications For SQL.
* [Geo/Spatial Search with MySQL](http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL) - a presentation by Alexander Rubin, from the MySQL Conference in 2006.

 There are currently no differences between GIS in stable versions of MariaDB and GIS in MySQL. There are, however, some extensions and enhancements being worked on. See "[MariaDB Plans - GIS](../mariadb-plans-gis/index)" for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/gis-resources/>

Identifier to File Name Mapping
===============================

    Some identifiers map to a file name on the filesystem. Databases each have their own directory, while, depending on the [storage engine](storage-engine), table names and index names may map to a file name.

 Not all characters that are allowed in table names can be used in file names. Every filesystem has its own rules of what characters can be used in file names. To let the user create tables using all characters allowed in the SQL Standard and to not depend on whatever particular filesystem a particular database resides, MariaDB encodes "potentially unsafe" characters in the table name to derive the corresponding file name.

 This is implemented using a special character set. MariaDB converts a table name to the "filename" character set to get the file name for this table. And it converts the file name from the "filename" character set to, for example, utf8 to get the table name for this file name.

 The conversion rules are as follows: if the identifier is made up only of basic Latin numbers, letters and/or the underscore character, the encoding matches the name (see however [Identifier Case Sensitivity](../identifier-case-sensitivity/index)). Otherwise they are encoded according to the following table:

 


| Code Range | Pattern | Number | Used | Unused | Blocks |
| --- | --- | --- | --- | --- | --- |
| 00C0..017F | [@][0..4][g..z] | 5\*20= 100 | 97 | 3 | Latin-1 Supplement + Latin Extended-A |
| 0370..03FF | [@][5..9][g..z] | 5\*20= 100 | 88 | 12 | Greek and Coptic |
| 0400..052F | [@][g..z][0..6] | 20\*7= 140 | 137 | 3 | Cyrillic + Cyrillic Supplement |
| 0530..058F | [@][g..z][7..8] | 20\*2= 40 | 38 | 2 | Armenian |
| 2160..217F | [@][g..z][9] | 20\*1= 20 | 16 | 4 | Number Forms |
| 0180..02AF | [@][g..z][a..k] | 20\*11=220 | 203 | 17 | Latin Extended-B + IPA Extensions |
| 1E00..1EFF | [@][g..z][l..r] | 20\*7= 140 | 136 | 4 | Latin Extended Additional |
| 1F00..1FFF | [@][g..z][s..z] | 20\*8= 160 | 144 | 16 | Greek Extended |
| .... .... | [@][a..f][g..z] | 6\*20= 120 | 0 | 120 | RESERVED |
| 24B6..24E9 | [@][@][a..z] | 26 | 26 | 0 | Enclosed Alphanumerics |
| FF21..FF5A | [@][a..z][@] | 26 | 26 | 0 | Halfwidth and Fullwidth forms |

 
Code Range values are UCS-2.

 All of this encoding happens transparently at the filesystem level with one exception. Until MySQL 5.1.6, an old encoding was used. Identifiers created in a version before MySQL 5.1.6, and which haven't been updated to the new encoding, the server prefixes `mysql50` to their name.

 ### Examples

 Find the file name for a table with a non-Latin1 name:

 
```
select cast(convert("this_is_таблица" USING filename) as binary);
+------------------------------------------------------------------+
| cast(convert("this_is_таблица" USING filename) as binary)        |
+------------------------------------------------------------------+
| this_is_@y0@g0@h0@r0@o0@i1@g0                                    |
+------------------------------------------------------------------+

```

Find the table name for a file name:

 
```
select convert(_filename "this_is_@y0@g0@h0@r0@o0@i1@g0" USING utf8);
+---------------------------------------------------------------+
| convert(_filename "this_is_@y0@g0@h0@r0@o0@i1@g0" USING utf8) |
+---------------------------------------------------------------+
| this_is_таблица                                               |
+---------------------------------------------------------------+

```

An old table created before MySQL 5.1.6, with the old encoding:

 
```
SHOW TABLES;
+--------------------+
| Tables_in_test     |
+--------------------+
| #mysql50#table@1   |
+--------------------+

```

The prefix needs to be supplied to reference this table:

 
```
SHOW COLUMNS FROM `table@1`;
ERROR 1146 (42S02): Table 'test.table@1' doesn't exist

SHOW COLUMNS FROM `#mysql50#table@1`;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| i     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/identifier-to-file-name-mapping/>

Date and Time Literals
======================

    Standard syntaxes
-----------------

 MariaDB supports the SQL standard and ODBC syntaxes for [DATE](../date/index), [TIME](../time/index) and [TIMESTAMP](../timestamp/index) literals.

 SQL standard syntax:

 * DATE 'string'
* TIME 'string'
* TIMESTAMP 'string'

 ODBC syntax:

 * {d 'string'}
* {t 'string'}
* {ts 'string'}

 The timestamp literals are treated as [DATETIME](../datetime/index) literals, because in MariaDB the range of `DATETIME` is closer to the `TIMESTAMP` range in the SQL standard.

 `string` is a string in a proper format, as explained below.

 
`DATE` literals
----------------

 A `DATE` string is a string in one of the following formats: `'YYYY-MM-DD'` or `'YY-MM-DD'`. Note that any punctuation character can be used as delimiter. All delimiters must consist of 1 character. Different delimiters can be used in the same string. Delimiters are optional (but if one delimiter is used, all delimiters must be used).

 A `DATE` literal can also be an integer, in one of the following formats: `YYYYMMDD` or `YYMMDD`.

 All the following `DATE` literals are valid, and they all represent the same value:

 
```
'19940101'
'940101'
'1994-01-01'
'94/01/01'
'1994-01/01'
'94:01!01'
19940101
940101

```


`DATETIME` literals
--------------------

 A `DATETIME` string is a string in one of the following formats: `'YYYY-MM-DD HH:MM:SS'` or `'YY-MM-DD HH:MM:SS'`. Note that any punctuation character can be used as delimiter for the date part and for the time part. All delimiters must consist of 1 character. Different delimiters can be used in the same string. The hours, minutes and seconds parts can consist of one character. For this reason, delimiters are mandatory for `DATETIME` literals.

 The delimiter between the date part and the time part can be a `T` or any sequence of space characters (including tabs, new lines and carriage returns).

 A `DATETIME` literal can also be a number, in one of the following formats: `YYYYMMDDHHMMSS`, `YYMMDDHHMMSS`, `YYYYMMDD` or `YYMMDD`. In this case, all the time subparts must consist of 2 digits.

 All the following `DATE` literals are valid, and they all represent the same value:

 
```
'1994-01-01T12:30:03'
'1994/01/01\n\t 12+30+03'
'1994/01\\01\n\t 12+30-03'
'1994-01-01 12:30:3'

```


`TIME` literals
----------------

 A `TIME` string is a string in one of the following formats:  `'D HH:MM:SS'`, `'HH:MM:SS`, `'D HH:MM'`, `'HH:MM'`, `'D HH'`, or `'SS'`. `D` is a value from 0 to 34 which represents days. `:` is the only allowed delimiter for `TIME` literals. Delimiters are mandatory, with an exception: the `'HHMMSS'` format is allowed. When delimiters are used, each part of the literal can consist of one character.

 A `TIME` literal can also be a number in one of the following formats: `HHMMSS`, `MMSS`, or `SS`.

 The following literals are equivalent:

 
```
'09:05:00'
'9:05:0'
'9:5:0'
'090500'

```

2-digit years
-------------

 The year part in `DATE` and `DATETIME` literals is determined as follows:

 * `70` - `99` = `1970` - `1999`
* `00` - `69` = `2000` - `2069`

 Microseconds
------------

 `DATETIME` and `TIME` literals can have an optional microseconds part. For both string and numeric forms, it is expressed as a decimal part. Up to 6 decimal digits are allowed. Examples:

 
```
'12:30:00.123456'
123000.123456

```

See [Microseconds in MariaDB](../microseconds-in-mariadb/index) for details.

 Date and time literals and the `SQL_MODE`
-----------------------------------------

 Unless the [SQL\_MODE](../sql-mode/index) `NO_ZERO_DATE` flag is set, some special values are allowed: the `'0000-00-00'` `DATE`, the `'00:00:00'` `TIME`, and the `0000-00-00 00:00:00` `DATETIME`.

 If the `ALLOW_INVALID_DATES` flag is set, the invalid dates (for example, 30th February) are allowed. If not, if the `NO_ZERO_DATE` is set, an error is produced; otherwise, a zero-date is returned.

 Unless the `NO_ZERO_IN_DATE` flag is set, each subpart of a date or time value (years, hours...) can be set to 0.

 See also
--------

 * [Date and time units](../date-and-time-units/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/date-and-time-literals/>

aria\_read\_log
===============

    **aria\_read\_log** is a tool for displaying and applying log records from an [Aria](../aria/index) [transaction log](../aria-storage-engine/index#aria-log-files).

 Note: Aria is compiled without -DIDENTICAL\_PAGES\_AFTER\_RECOVERY which means that the table files are not byte-to-byte identical to files created during normal execution. This should be ok, except for test scripts that try to compare files before and after recovery.

 Usage:

 
```
aria_read_log OPTIONS

```

You need to use one of `-d` or `-a`.

 Options
-------

 The following variables can be set while passed as commandline options to aria\_read\_log, or set in the `[aria_read_log]` section in your [my.cnf](../configuring-mariadb-with-mycnf/index) file.

 


| Option | Description |
| --- | --- |
| -a, --apply | Apply log to tables: modifies tables! you should make a backup first! Displays a lot of information if not run with --silent. |
| --character-sets-dir=name | Directory where character sets are. |
| -c, --check | if --display-only, check if record is fully readable (for debugging). |
| -?, --help | Display help and exit. |
| -d, --display-only | Display brief info read from records' header. |
| -e, --end-lsn=# | Stop applying at this lsn. If end-lsn is used, UNDO:s will not be applied |
| -h, --aria-log-dir-path=name | Path to the directory where to store transactional log |
| -P, --page-buffer-size=# | The size of the buffer used for index blocks for Aria tables. |
| -l, --print-log-control-file | Print the content of the aria\_log\_control\_file. From [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/). |
| -o, --start-from-lsn=# | Start reading log from this lsn. |
| -C, --start-from-checkpoint | Start applying from last checkpoint. |
| -s, --silent | Print less information during apply/undo phase. |
| -T, --tables-to-redo=name | List of comma-separated tables that we should apply REDO on. Use this if you only want to recover some tables. |
| -t, --tmpdir=name | Path for temporary files. Multiple paths can be specified, separated by colon (:) |
| --translog-buffer-size=# | The size of the buffer used for transaction log for Aria tables. |
| -u, --undo | Apply UNDO records to tables. (disable with --disable-undo) (Defaults to on; use --skip-undo to disable.) |
| -v, --verbose | Print more information during apply/undo phase. |
| -V, --version | Print version and exit. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria_read_log/>

MySQL/MariaDB Spatial Support Matrix
====================================

    This table shows when different spatial features were introduced into MySQL and MariaDB. 

 

|  |  |
| --- | --- |
| My | MySQL |
| MDB | MariaDB |
| x | This feature is supported. |
| MBR | This feature is present, but operates on the Minimum Bounding Rectangle instead of the actual shape. |
| d | This feature is present, but has been deprecated and will be removed in a future version. |
| \* | This feature is present, but may not work the way you expect. |
| - | This feature is not supported. |

 


|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| InnoDB Spatial Indexes |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  x  |
| [MyISAM Spatial Indexes](../spatial-index/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [Aria Spatial Indexes](../spatial-index/index) |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |  x  |  x  |
| [Area](../st_area/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [AsBinary](../st_asbinary/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [AsText](../st_astext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [AsWKB](../st_asbinary/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [AsWKT](../st_astext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Boundary](../st_boundary/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| [Buffer](../st_buffer/index) |  -  |  -  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Centroid](../st_centroid/index) |  -  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Contains](../contains/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [ConvexHull](../st_convexhull/index) |  -  |  -  |  -  |  -  |  x  |  d  |  -  |  -  |  x  |  x  |
| [Crosses](../st_crosses/index) |  MBR  |  x  |  x  |  x  |  x  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [Dimension](../st_dimension/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Disjoint](../disjoint/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| Distance |  MBR  |  -  |  -  |  x  |  x  |  d  |  -  |  -  |  -  |  -  |
| [EndPoint](../st_endpoint/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Envelope](../st_envelope/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Equals](../equals/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [ExteriorRing](../st_exteriorring/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeomCollFromText](../st_geomcollfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeomCollFromWKB](../st_geomcollfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryCollection](../geometrycollection/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [GeometryCollectionFromText](../st_geomcollfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryCollectionFromWKB](../st_geomcollfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryFromText](../st_geomfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryFromWKB](../st_geomfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryN](../st_geometryn/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeometryType](../st_geometrytype/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeomFromText](../st_geomfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GeomFromWKB](../st_geomfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [GLength](../glength/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [InteriorRingN](../st_interiorringn/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Intersects](../intersects/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [IsClosed](../st_isclosed/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [IsEmpty](../st_isempty/index) |  -  | \* | \* | \* | \* |  d  |  x  |  x  |  x  |  x  |
| [IsRing](../st_isring/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| [IsSimple](../st_issimple/index) |  -  | \* | \* |  x  |  x  |  d  |  -  |  x  |  x  |  x  |
| [LineFromText](../st_linefromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [LineFromWKB](../st_linefromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [LineString](../linestring/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [LineStringFromText](../st_linefromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [LineStringFromWKB](../st_linefromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MBRContains](../mbrcontains/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| MBRCoveredBy |  -  |  -  |  -  |  MBR  |  MBR  |  MBR  |  -  |  -  |  -  |  -  |
| [MBRDisjoint](../mbrdisjoint/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MBREqual](../mbrequal/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MBREquals](../equals/index) |  -  |  -  |  -  |  MBR  |  MBR  |  MBR  |  -  |  -  |  -  |  MBR  |
| [MBRIntersects](../mbrintersects/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MBROverlaps](../mbroverlaps/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MBRTouches](../mbrtouches/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MBRWithin](../mbrwithin/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |
| [MLineFromText](../mlinefromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MLineFromWKB](../linefromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MPointFromText](../mpointfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MPointFromWKB](../mpointfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MPolyFromText](../mpolyfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MPolyFromWKB](../mpolyfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiLineString](../multilinestring/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [MultiLineStringFromText](../mlinefromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiLineStringFromWKB](../mlinefromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiPoint](../multipoint/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [MultiPointFromText](../mpointfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiPointFromWKB](../mpointfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiPolygon](../multipolygon/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [MultiPolygonFromText](../mpolyfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [MultiPolygonFromWKB](../mpolyfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [NumGeometries](../st_numgeometries/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [NumInteriorRings](../st_numinteriorrings/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [NumPoints](../st_numpoints/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Overlaps](../overlaps/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [Point](../point/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
| [PointFromText](../st_pointfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [PointFromWKB](../st_pointfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [PointOnSurface](../st_pointonsurface/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| [PointN](../st_pointn/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [PolyFromText](../st_polyfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [PolyFromWKB](../st_polyfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Polygon](../polygon/index) |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [PolygonFromText](../st_polyfromtext/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [PolygonFromWKB](../st_polyfromwkb/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [SRID](../srid/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [ST\_Area](../st_area/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_AsBinary](../st_asbinary/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_AsGeoJSON](../geojson-st_asgeojson/index) |  -  |  -  |  -  |  x  |  x  |  x  |  -  |  -  |  -  |  x  |
| [ST\_AsText](../st_astext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_AsWKB](../st_asbinary/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_AsWKT](../st_astext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Boundary](../st_boundary/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| [ST\_Buffer](../st_buffer/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_Buffer\_Strategy |  -  |  -  |  -  |  x  |  x  |  x  |  -  |  -  |  -  |  -  |
| [ST\_Centroid](../st_centroid/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Contains](../st_contains/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_ConvexHull](../st_convexhull/index) |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  x  |  x  |
| [ST\_Crosses](../st_crosses/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Difference](../st_difference/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Dimension](../st_dimension/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Disjoint](../st_disjoint/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Distance](../st_distance/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| ST\_Distance\_Sphere |  -  |  -  |  -  |  -  |  -  |  x  |  -  |  -  |  -  |  -  |
| [ST\_EndPoint](../st_endpoint/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Envelope](../st_envelope/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Equals](../st_equals/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_ExteriorRing](../st_exteriorring/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_GeoHash |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  -  |
| [ST\_GeomCollFromText](../st_geomcollfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryCollectionFromText](../st_geomcollfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryCollectionFromWKB](../st_geomcollfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryFromText](../st_geomfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryFromWKB](../st_geomfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryN](../st_geometryn/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeometryType](../st_geometrytype/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeomFromGeoJSON](../st_geomfromgeojson/index) |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  x  |
| [ST\_GeomFromText](../st_geomfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_GeomFromWKB](../st_geomfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_InteriorRingN](../st_interiorringn/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Intersection](../st_intersection/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Intersects](../st_intersects/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [ST\_IsClosed](../st_isclosed/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_IsEmpty](../st_isempty/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_IsRing](../st_isring/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| [ST\_IsSimple](../st_issimple/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_IsValid |  -  |  -  |  -  |  -  |  -  |  x  |  -  |  -  |  -  |  -  |
| ST\_LatFromGeoHash |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  -  |
| [ST\_Length](../st_length/index) |  -  |  -  |  -  |  -  |  -  |  x  |  -  |  x  |  x  |  x  |
| [ST\_LineFromText](../st_linefromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_LineFromWKB](../st_linefromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_LineStringFromText](../st_linefromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_LineStringFromWKB](../st_linefromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_LongFromGeoHash |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  -  |
| [ST\_NumGeometries](../st_numgeometries/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_NumInteriorRings](../st_numinteriorrings/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_NumPoints](../st_numpoints/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Overlaps](../st_overlaps/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_PointFromGeoHash |  -  |  -  |  -  |  -  |  x  |  x  |  -  |  -  |  -  |  -  |
| [ST\_PointFromText](../st_pointfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PointFromWKB](../st_pointfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PointOnSurface](../st_pointonsurface/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |
| [ST\_PointN](../st_pointn/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PolyFromText](../st_polyfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PolyFromWKB](../st_polyfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PolygonFromText](../st_polyfromtext/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_PolygonFromWKB](../st_polyfromwkb/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Relate](../st_relate/index) |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  -  |  x  |  x  |
| ST\_Simplify |  -  |  -  |  -  |  -  |  -  |  x  |  -  |  -  |  -  |  -  |
| [ST\_SRID](../st_srid/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_StartPoint](../st_startpoint/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_SymDifference](../st_symdifference/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Touches](../st_touches/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Union](../st_union/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| ST\_Validate |  -  |  -  |  -  |  -  |  -  |  x  |  -  |  -  |  -  |  -  |
| [ST\_Within](../st_within/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_X](../st_x/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [ST\_Y](../st_y/index) |  -  |  -  |  x  |  x  |  x  |  x  |  -  |  x  |  x  |  x  |
| [StartPoint](../st_startpoint/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Touches](../touches/index) |  MBR  |  x  |  x  |  x  |  x  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [Within](../within/index) |  MBR  |  MBR  |  MBR  |  MBR  |  MBR  |  d  |  MBR  |  MBR  |  MBR  |  MBR  |
| [X](../st_x/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
| [Y](../st_y/index) |  x  |  x  |  x  |  x  |  x  |  d  |  x  |  x  |  x  |  x  |
|  | My 5.4.2 | My 5.5 | My 5.6.1 | My 5.7.4 | My 5.7.5 | My 5.7.6 | MDB 5.1 | MDB 5.3.3 | MDB 10.1.2 | MDB 10.2 |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlmariadb-spatial-support-matrix/>

Comparison Operators
=====================

   The comparison operators include: !=, <, <=, <=>, >=, >, etc...

  

| Title | Description |
| --- | --- |
|  [!=](../not-equal/index) |  Not equal operator.  |
|  [<](../less-than/index) |  Less than operator.  |
|  [<=](../less-than-or-equal/index) |  Less than or equal operator.  |
|  [<=>](../null-safe-equal/index) |  NULL-safe equal operator.  |
|  [=](../equal/index) |  Equal operator.  |
|  [>](../greater-than/index) |  Greater than operator.  |
|  [>=](../greater-than-or-equal/index) |  Greater than or equal operator.  |
|  [BETWEEN AND](../between-and/index) |  True if expression between two values.  |
|  [COALESCE](../coalesce/index) |  Returns the first non-NULL parameter  |
|  [GREATEST](../greatest/index) |  Returns the largest argument.  |
|  [IN](../in/index) |  True if expression equals any of the values in the list.  |
|  [INTERVAL](../interval/index) |  Index of the argument that is less than the first argument  |
|  [IS](../is/index) |  Tests whether a boolean is TRUE, FALSE, or UNKNOWN.  |
|  [IS NOT](../is-not/index) |  Tests whether a boolean value is not TRUE, FALSE, or UNKNOWN  |
|  [IS NOT NULL](../is-not-null/index) |  Tests whether a value is not NULL  |
|  [IS NULL](../is-null/index) |  Tests whether a value is NULL  |
|  [ISNULL](../isnull/index) |  Checks if an expression is NULL  |
|  [LEAST](../least/index) |  Returns the smallest argument.  |
|  [NOT BETWEEN](../not-between/index) |  Same as NOT (expr BETWEEN min AND max)  |
|  [NOT IN](../not-in/index) |  Same as NOT (expr IN (value,...))  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/comparison-operators/>

Arithmetic Operators
=====================

   Arithmetic operators for addition, subtraction, multiplication, division and the modulo operator

  

| Title | Description |
| --- | --- |
|  [Addition Operator (+)](../addition-operator/index) |  Addition.  |
|  [DIV](../div/index) |  Integer division.  |
|  [Division Operator (/)](../division-operator/index) |  Division.  |
|  [MOD](../mod/index) |  Modulo operation. Remainder of N divided by M.  |
|  [Modulo Operator (%)](../modulo-operator/index) |  Modulo operator. Returns the remainder of N divided by M.  |
|  [Multiplication Operator (\*)](../multiplication-operator/index) |  Multiplication.  |
|  [Subtraction Operator (-)](../subtraction-operator-/index) |  Subtraction and unary minus.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/arithmetic-operators/>

Assignment Operators
=====================

   Operators for assigning a value

  

| Title | Description |
| --- | --- |
|  [Assignment Operator (:=)](../assignment-operator/index) |  Assignment operator for assigning a value.  |
|  [Assignment Operator (=)](../assignment-operators-assignment-operator/index) |  The equal sign as an assignment operator.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/assignment-operators/>

myisam\_ftdump
==============

    myisam\_ftdump is a utility for displaying information about [MyISAM](../myisam/index) [FULLTEXT](../full-text-indexes/index) indexes. It will scan and dump the entire index, and can be a lengthy process.

 If the server is running, make sure you run a [FLUSH TABLES](../flush/index) statement first.

 Usage
-----

 
```
myisam_ftdump <table_name> <index_num>

```

The table\_name can be specified with or without the .MYI index extension.

 The index number refers to the number of the index when the table was defined, starting at zero. For example, take the following table definition:

 
```
CREATE TABLE IF NOT EXISTS `employees_example` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(30) NOT NULL,
  `last_name` varchar(40) NOT NULL,
  `position` varchar(25) NOT NULL,
  `home_address` varchar(50) NOT NULL,
  `home_phone` varchar(12) NOT NULL,
  `employee_code` varchar(25) NOT NULL,
  `bio` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `employee_code` (`employee_code`),
  FULLTEXT (`bio`)
) ENGINE=MyISAM;

```

The fulltext index will be `2`. The primary key is index `0`, and the unique key index `1`.

 You can use *myisam\_ftdump* to generate a list of index entries in order of frequency of occurrence as follows:

 
```
myisam_ftdump -c mytexttable 1 | sort -r

```

Options
-------

 


| Option | Description |
| --- | --- |
| -h, --help | Display help and exit. |
| -?, --help | Synonym for -h. |
| -c, --count | Calculate per-word stats (counts and global weights). |
| -d, --dump | Dump index (incl. data offsets and word weights). |
| -l, --length | Report length distribution. |
| -s, --stats | Report global stats. |
| -v, --verbose | Be verbose. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam_ftdump/>

Memory and Disk Use With myisamchk
==================================

    myisamchk's performance can be dramatically enhanced for larger tables by making sure that its memory-related variables are set to an optimum level.

 By default, myisamchk will use very little memory (about 3MB is allocated), but can temporarily use a lot of disk space. If disk space is a limitation when repairing, the *--safe-recover* option should be used instead of *--recover*. However, if TMPDIR points to a memory file system, an out of memory error can easily be caused, as myisamchk places temporary files in TMPDIR. The *--tmpdir=path* option should be used in this case to specify a directory on disk.

 myisamchk has the following requirements for disk space:

 * When repairing, space for twice the size of the data file, available in the same directory as the original file. This is for the original file as well as a copy. This space is not required if the *--quick* option is used, in which case only the index file is re-created.
* Disk space in the temporary directory (TMPDIR or the *tmpdir=path* option) is needed for sorting if the *--recover* or *--sort-recover* options are used when not using *--safe-recover*). The space required will be approximately *(largest\_key + row\_pointer\_length) \* number\_of\_rows \* 2*. To get information about the length of the keys as well as the row pointer length, use *myisamchk -dv table\_name*.
* Space for a new index file to replace the existing one. The old index is first truncated, so unless the old index file is not present or is smaller for some reason, no significant extra space will be needed.

 There are a number of [system variables](../server-system-variables/index) that are useful to adjust when running myisamchk. They will increase memory usage, and since some are per-session variables, you don't want to increase the general value, but you can either pass an increased value to myisamchk as a commandline option, or with a [myisamchk] section in your [my.cnf](../configuring-mariadb-with-mycnf/index) file.

 * [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size). By default this is 4M, but it's very useful to increase to make myisamchk sorting much faster. Since the server won't be running when you run myisamchk, you can increase substantially. 16M is usually a minimum, but values such as 256M are not uncommon if memory is available.
* [key\_buffer\_size](../myisam-system-variables/index#key_buffer_size) (which particularly helps with the *--extend-check* and *--safe-recover* options.
* [read\_buffer\_size](../server-system-variables/index#read_buffer_size)
* [write\_buffer\_size](../server-system-variables/index#write_buffer_size)

 For example, if you have more than 512MB available to allocate to the process, the following settings could be used:

 
```
myisamchk 
  --myisam_sort_buffer_size=256M
  --key_buffer_size=512M
  --read_buffer_size=64M
  --write_buffer_size=64M
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/memory-and-disk-use-with-myisamchk/>

MariaDB Galera 10.0 Changelogs
===============================

   Changelogs for MariaDB Galera Cluster 10.0.x releases.

  

| Title | Description |
| --- | --- |
|  [MariaDB Galera Cluster 10.0.38 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10038-changelog/) |  Status: Stable (GA) | Release Date: 4 Feb 2019  |
|  [MariaDB Galera Cluster 10.0.37 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10037-changelog/) |  Status: Stable (GA) | Release Date: 6 Nov 2018  |
|  [MariaDB Galera Cluster 10.0.36 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10036-changelog/) |  Status: Stable (GA) | Release Date: 7 Aug 2018  |
|  [MariaDB Galera Cluster 10.0.35 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10035-changelog/) |  Status: Stable (GA) | Release Date: 9 May 2018  |
|  [MariaDB Galera Cluster 10.0.34 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10034-changelog/) |  Status: Stable (GA) | Release Date: 6 Feb 2018  |
|  [MariaDB Galera Cluster 10.0.33 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10033-changelog/) |  Status: Stable (GA) | Release Date: 14 Nov 2017  |
|  [MariaDB Galera Cluster 10.0.32 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10032-changelog/) |  Status: Stable (GA) | Release Date: 17 Aug 2017  |
|  [MariaDB Galera Cluster 10.0.31 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10031-changelog/) |  Status: Stable (GA) | Release Date: 2 Jun 2017  |
|  [MariaDB Galera Cluster 10.0.30 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10030-changelog/) |  Status: Stable (GA) | Release Date: 22 Mar 2017  |
|  [MariaDB Galera Cluster 10.0.29 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10029-changelog/) |  Status: Stable (GA) | Release Date: 16 Jan 2017  |
|  [MariaDB Galera Cluster 10.0.28 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10028-changelog/) |  Status: Stable (GA) | Release Date: 7 Nov 2016  |
|  [MariaDB Galera Cluster 10.0.27 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10027-changelog/) |  Status: Stable (GA) | Release Date: 29 Aug 2016  |
|  [MariaDB Galera Cluster 10.0.26 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10026-changelog/) |  Status: Stable (GA) | Release Date: 1 Jul 2016  |
|  [MariaDB Galera Cluster 10.0.25 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10025-changelog/) |  Status: Stable (GA) | Release Date: 3 May 2016  |
|  [MariaDB Galera Cluster 10.0.24 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10024-changelog/) |  Status: Stable (GA) | Release Date: 26 Feb 2015  |
|  [MariaDB Galera Cluster 10.0.23 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10023-changelog/) |  Status: Stable (GA) | Release Date: 24 Dec 2015  |
|  [MariaDB Galera Cluster 10.0.22 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10022-changelog/) |  Status: Stable (GA) | Release Date: 19 Nov 2015  |
|  [MariaDB Galera Cluster 10.0.21 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10021-changelog/) |  Status: Stable (GA) | Release Date: 18 Aug 2015  |
|  [MariaDB Galera Cluster 10.0.20 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10020-changelog/) |  Status: Stable (GA) | Release Date: 27 Jun 2015  |
|  [MariaDB Galera Cluster 10.0.19 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10019-changelog/) |  Status: Stable (GA) | Release Date: 18 May 2015  |
|  [MariaDB Galera Cluster 10.0.17 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10017-changelog/) |  Status: Stable (GA) | Release Date: 11 Mar 2015  |
|  [MariaDB Galera Cluster 10.0.16 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10016-changelog/) |  Status: Stable (GA) | Release Date: 29 Jan 2015  |
|  [MariaDB Galera Cluster 10.0.15 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10015-changelog/) |  Status: Stable (GA) | Release Date: 12 Dec 2014  |
|  [MariaDB Galera Cluster 10.0.14 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10014-changelog/) |  Status: Stable (GA) | Release Date: 16 Oct 2014  |
|  [MariaDB Galera Cluster 10.0.13 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10013-changelog/) |  Status: Stable (GA) | Release Date: 3 Sep 2014  |
|  [MariaDB Galera Cluster 10.0.12 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10012-changelog/) |  Status: Stable (GA) | Release Date: 28 Jun 2014  |
|  [MariaDB Galera Cluster 10.0.11 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10011-changelog/) |  Status: Beta | Release Date: 11 Jun 2014  |
|  [MariaDB Galera Cluster 10.0.10 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-10010-changelog/) |  Status: Beta | Release Date: 22 Apr 2014  |
|  [MariaDB Galera Cluster 10.0.7 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-1007-changelog/) |  Status: Alpha | Release Date: 24 Feb 2014  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-galera-100-changelogs/>

MyISAM Overview
===============

    The MyISAM storage engine was the default storage engine from MySQL 3.23 until it was replaced as default by [InnoDB](../innodb/index) in MariaDB and MySQL 5.5. Historically, MyISAM is a replacement for the older ISAM engine, removed in MySQL 4.1.

 It's a light, non-transactional engine with great performance, is easy to copy between systems and has a small data footprint.

 You're encouraged to rather use the [Aria](../aria/index) storage engine for new applications, which has even better performance in most cases and the goal of being crash-safe.

 A MyISAM table is stored in three files on disk. There's a table definition file with an extension of `.frm`, a data file with the extension `.MYD`, and an index file with the extension `.MYI`.

 MyISAM features
---------------

 * Does not support [transactions](../transactions/index).
* Does not support foreign keys.
* Supports [FULLTEXT indexes](../full-text-indexes/index).
* Supports [GIS](../gis-functionality/index) data types.
* Storage limit of 256TB.
* Maximum of 64 indexes per table.
* Maximum of 32 columns per index.
* Maximum index length of 1000 bytes.
* Limit of (232)2 (1.844E+19) rows per table.
* Supports large files up to 63-bits in length where the underlying system supports this.
* All data is stored with the low byte first, so all files will still work if copied to other systems or other machines.
* The data file and the index file can be placed on different devices to improve speed.
* Supports table locking, not row locking.
* Supports a key buffer that is [segmented](../segmented-key-cache/index) in MariaDB.
* Supports [concurrent inserts](../concurrent-inserts/index).
* Supports fixed length, dynamic and compressed formats - see [MyISAM Storage Formats](../myisam-storage-formats/index).
* Numeric index values are stored with the high byte first, which enables more efficient index compression.
* Data values are stored with the low byte first, making it mostly machine and operating system independent. The only exceptions are if a machine doesn't use two's-complement signed integers and the IEEE floating-point format.
* Can be copied between databases or systems with normal system tools, as long as the files are not open on either system. Use [FLUSH\_TABLES](../flush/index) to ensure files are not in use.
* There are a number of tools for working with MyISAM tables. These include:
	+ [mariadb-check](../mariadb-check/index) for checking or repairing
	+ [myisamchk](../myisamchk/index) for checking or repairing
	+ [myisampack](../myisampack/index) for compressing
* It is possible to build a [MERGE](../merge/index) table on the top of one or more MyISAM tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-overview/>

Logical Operators
==================

   NOT, AND, Exclusive OR and OR

  

| Title | Description |
| --- | --- |
|  [!](../not/index) |  Logical NOT.  |
|  [&&](../and/index) |  Logical AND.  |
|  [XOR](../xor/index) |  Logical XOR.  |
|  [||](../or/index) |  Logical OR.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/logical-operators/>

MariaDB Galera 5.5 Changelogs
==============================

   Changelogs for [MariaDB Galera 5.5](../what-is-mariadb-galera-cluster/index) releases.

  

| Title | Description |
| --- | --- |
|  [MariaDB Galera Cluster 5.5.63 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5563-changelog/) |  Status: Stable (GA) | Release Date: 1 Feb 2019  |
|  [MariaDB Galera Cluster 5.5.62 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5562-changelog/) |  Status: Stable (GA) | Release Date: 31 Oct 2018  |
|  [MariaDB Galera Cluster 5.5.61 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5561-changelog/) |  Status: Stable (GA) | Release Date: 3 Aug 2018  |
|  [MariaDB Galera Cluster 5.5.60 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5560-changelog/) |  Status: Stable (GA) | Release Date: 3 May 2018  |
|  [MariaDB Galera Cluster 5.5.59 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5559-changelog/) |  Status: Stable (GA) | Release Date: 23 Jan 2018  |
|  [MariaDB Galera Cluster 5.5.58 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5558-changelog/) |  Status: Stable (GA) | Release Date: 25 Oct 2017  |
|  [MariaDB Galera Cluster 5.5.57 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5557-changelog/) |  Status: Stable (GA) | Release Date: 26 Jul 2017  |
|  [MariaDB Galera Cluster 5.5.56 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5556-changelog/) |  Status: Stable (GA) | Release Date: 22 Apr 2017  |
|  [MariaDB Galera Cluster 5.5.55 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5555-changelog/) |  Status: Stable (GA) | Release Date: 22 Apr 2017  |
|  [MariaDB Galera Cluster 5.5.54 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5554-changelog/) |  Status: Stable (GA) | Release Date: 4 Jan 2017  |
|  [MariaDB Galera Cluster 5.5.53 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5553-changelog/) |  Status: Stable (GA) | Release Date: 20 Oct 2016  |
|  [MariaDB Galera Cluster 5.5.52 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5552-changelog/) |  Status: Stable (GA) | Release Date: 21 Sep 2016  |
|  [MariaDB Galera Cluster 5.5.51 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5551-changelog/) |  Status: Stable (GA) | Release Date: 15 Aug 2016  |
|  [MariaDB Galera Cluster 5.5.50 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5550-changelog/) |  Status: Stable (GA) | Release Date: 1 Jul 2016  |
|  [MariaDB Galera Cluster 5.5.49 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5549-changelog/) |  Status: Stable (GA) | Release Date: 26 Apr 2016  |
|  [MariaDB Galera Cluster 5.5.48 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5548-changelog/) |  Status: Stable (GA) | Release Date: 23 Feb 2016  |
|  [MariaDB Galera Cluster 5.5.47 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5547-changelog/) |  Status: Stable (GA) | Release Date: 24 Dec 2015  |
|  [MariaDB Galera Cluster 5.5.46 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5546-changelog/) |  Status: Stable (GA) | Release Date: 20 Oct 2015  |
|  [MariaDB Galera Cluster 5.5.45 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5545-changelog/) |  Status: Stable (GA) | Release Date: 18 Aug 2015  |
|  [MariaDB Galera Cluster 5.5.44 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5544-changelog/) |  Status: Stable (GA) | Release Date: 27 Jun 2015  |
|  [MariaDB Galera Cluster 5.5.43 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5543-changelog/) |  Status: Stable (GA) | Release Date: 15 May 2015  |
|  [MariaDB Galera Cluster 5.5.42 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5542-changelog/) |  Status: Stable (GA) | Release Date: 11 Mar 2015  |
|  [MariaDB Galera Cluster 5.5.41 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5541-changelog/) |  Status: Stable (GA) | Release Date: 6 Jan 2015  |
|  [MariaDB Galera Cluster 5.5.40 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5540-changelog/) |  Status: Stable (GA) | Release Date: 17 Oct 2014  |
|  [MariaDB Galera Cluster 5.5.39 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5539-changelog/) |  Status: Stable (GA) | Release Date: 21 Aug 2014  |
|  [MariaDB Galera Cluster 5.5.38 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5538-changelog/) |  Status: Stable (GA) | Release Date: 25 Jun 2014  |
|  [MariaDB Galera Cluster 5.5.37 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5537-changelog/) |  Status: Stable (GA) | Release Date: 30 Apr 2014  |
|  [MariaDB Galera Cluster 5.5.36 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5536-changelog/) |  Status: Stable (GA) | Release Date: 12 Mar 2014  |
|  [MariaDB Galera Cluster 5.5.35 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5535-changelog/) |  Status: Stable (GA) | Release Date: 14 Feb 2014  |
|  [MariaDB Galera Cluster 5.5.34 Changelog](https://mariadb.com/kb/en/mariadb-galera-cluster-5534-changelog/) |  Status: Stable (GA) | Release Date: 18 Dec 2013  |
|  [MariaDB Galera 5.5.33a Changelog](https://mariadb.com/kb/en/mariadb-galera-5533a-changelog/) |  Status: Stable (GA) | Release Date: 30 Sep 2013  |
|  [MariaDB Galera 5.5.32 Changelog](https://mariadb.com/kb/en/mariadb-galera-5532-changelog/) |  Status: Stable (GA) | Release Date: 30 Aug 2013  |
|  [MariaDB Galera 5.5.29 Changelog](https://mariadb.com/kb/en/mariadb-galera-5529-changelog/) |  Status: Stable (GA) | Release Date: 5 Mar 2013  |
|  [MariaDB Galera 5.5.28a Changelog](https://mariadb.com/kb/en/mariadb-galera-5528a-changelog/) |  Status: Release Candidate (RC) | Release Date: 21 Dec 2012  |
|  [MariaDB Galera 5.5.25 Changelog](https://mariadb.com/kb/en/mariadb-galera-5525-changelog/) |  Status: Alpha | Release Date: 4 Sep 2012  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-galera-55-changelogs/>

MyISAM Index Storage Space
==========================

    Regular [MyISAM](../myisam/index) tables make use of [B-tree indexes](../storage-engine-index-types/index#b-tree-indexes).

 String indexes are space-compressed, which reduces the size of [VARCHARs](../varchar/index) that don't use the full length, or a string that has trailing spaces. String indexes also make use of prefix-compression, where strings with identical prefixes are compressed.

 Numeric indexes can also be prefix-compressed compressed if the [PACK\_KEYS=1](../create-table/index#table-options) option is used. Regardless, the high byte is always stored first, which allows a reduced index size.

 In the worst case, with no strings being space-compressed, the total index storage space will be (index\_length+4)/0.67 per index.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-index-storage-space/>

||
==

    Syntax
------

 
```
OR, ||

```
 Description
-----------

 Logical OR. When both operands are non-NULL, the result is 1 if any operand is non-zero, and 0 otherwise. With a NULL operand, the result is 1 if the other operand is non-zero, and NULL otherwise. If both operands are NULL, the result is NULL.

 For this operator, [short-circuit evaluation](../operator-precedence/index#short-circuit-evaluation) can be used.

 Note that, if the `PIPES_AS_CONCAT` [SQL\_MODE](../sql-mode/index) is set, `||` is used as a string concatenation operator. This means that `a || b` is the same as `CONCAT(a,b)`. See `[CONCAT()](../concat/index)` for details.

 ### Oracle Mode

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#null-handling), `||` ignores [NULL](null).

 
Examples
--------

 
```
SELECT 1 || 1;
+--------+
| 1 || 1 |
+--------+
|      1 |
+--------+

SELECT 1 || 0;
+--------+
| 1 || 0 |
+--------+
|      1 |
+--------+

SELECT 0 || 0;
+--------+
| 0 || 0 |
+--------+
|      0 |
+--------+

SELECT 0 || NULL;
+-----------+
| 0 || NULL |
+-----------+
|      NULL |
+-----------+

SELECT 1 || NULL;
+-----------+
| 1 || NULL |
+-----------+
|         1 |
+-----------+

```

In [Oracle mode](../sql_modeoracle-from-mariadb-103/index#null-handling), from [MariaDB 10.3](../what-is-mariadb-103/index):

 
```
SELECT 0 || NULL;
+-----------+
| 0 || NULL |
+-----------+
| 0         |
+-----------+

```

See Also
--------

 * [Oracle mode from MariaDB 10.3](../sql_modeoracle-from-mariadb-103/index#null-handling)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/or/>

aria\_s3\_copy
==============

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

  `aria_s3_copy` is a tool for copying an [Aria](../aria/index) table to and from [S3](../s3-storage-engine/index).

 The Aria table must be non transactional and have [ROW\_FORMAT=PAGE](../aria-storage-formats/index#page).

 For `aria_s3_copy` to work reliably, the table should not be changed by the MariaDB server during the copy, and one should have first performed [FLUSH TABLES](../flush/index) to ensure that the table is properly closed.

 Example of properly created Aria table:

 
```
create table test1 (a int) transactional=0 row_format=PAGE engine=aria;

```

Note that [ALTER TABLE table\_name ENGINE=S3](../using-the-s3-storage-engine/index) will work for any kind of table. This internally converts the table to an Aria table and then moves it to S3 storage.

 ### Main Arguments

 


| Option | Description |
| --- | --- |
| -?, --help | Display this help and exit. |
| -k, --s3-access-key=name | AWS access key ID |
| -r, --s3-region=name | AWS region |
| -K, --s3-secret-key=name | AWS secret access key ID |
| -b, --s3-bucket=name | AWS prefix for tables |
| -h, --s3-host-name=name | Host name to S3 provider |
| -c, --compress | Use compression |
| -o, --op=name | Operation to execute. One of 'from\_s3', 'to\_s3' or 'delete\_from\_s3' |
| -d, --database=name | Database for copied table (second prefix). If not given, the directory of the table file is used |
| -B, --s3-block-size=# | Block size for data/index blocks in s3 |
| -L, --s3-protocol-version=name | Protocol used to communication with S3. One of "Amazon" or "Original". |
| -f, --force | Force copy even if target exists |
| -v, --verbose | Write more information |
| -V, --version | Print version and exit. |
| -#, --debug[=name] | Output debug log. Often this is 'd:t:o,filename'. |
| --s3-debug | Output debug log from marias3 to stdout |

 



|  |  |
| --- | --- |
| -p, --s3-port=# | Port number to connect to (0 means use default) |
| -P, --s3-use-http | If true, force use of HTTP protocol |

 
### Typical Configuration in a my.cnf File

 
```
[aria_s3_copy]
s3-bucket=mariadb
s3-access-key=xxxx
s3-secret-key=xxx
s3-region=eu-north-1
#s3-host-name=s3.amazonaws.com
#s3-protocol-version=Amazon
verbose=1
op=to

```

### Example Usage

 The following code will copy an existing Aria table named `test1` to S3. If the `--database` option is not given, then the directory name where the table files exist will be used as the database.

 
```
shell> aria_s3_copy --force --op=to --database=foo --compress --verbose --s3_block_size=4M test1
Delete of aria table: foo.test1
Delete of index information foo/test1/index
Delete of data information foo/test1/data
Delete of base information and frm
Copying frm file test1.frm
Copying aria table: foo.test1 to s3
Creating aria table information foo/test1/aria
Copying index information foo/test1/index
.
Copying data information foo/test1/data
.

```

When using `--verbose`, `aria_s3_copy` will write a dot for each #/79 part of the file copied.

 See Also
--------

 [Using the S3 storage engine](../using-the-s3-storage-engine/index#aria_s3_copy). This pages has examples of .my.cnf entries for using `aria_s3_copy`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria_s3_copy/>

Trigger Overview
================

     A trigger, as its name suggests, is a set of statements that run, or are triggered, when an event occurs on a table.

 Events
------

 The event can be an INSERT, an UPDATE or a DELETE. The trigger can be executed BEFORE or AFTER the event. Until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), a table could have only one trigger defined for each event/timing combination: for example, a table could only have one BEFORE INSERT trigger.

 The [LOAD DATA INFILE](../load-data-infile/index) and [LOAD XML](../load-xml/index) statements invoke INSERT triggers for each row that is being inserted.

 The [REPLACE](../replace/index) statement is executed with the following workflow:

 * BEFORE INSERT;
* BEFORE DELETE (only if a row is being deleted);
* AFTER DELETE (only if a row is being deleted);
* AFTER INSERT.

 The [INSERT ... ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) statement, when a row already exists, follows the following workflow:

 * BEFORE INSERT;
* BEFORE UPDATE;
* AFTER UPDATE.

 Otherwise, it works like a normal INSERT statement.

 Note that [TRUNCATE TABLE](../truncate-table/index) does not activate any triggers.

 Triggers and Errors
-------------------

 With non-transactional storage engines, if a BEFORE statement produces an error, the statement will not be executed. Statements that affect multiple rows will fail before inserting the current row.

 With transactional engines, triggers are executed in the same transaction as the statement that invoked them.

 If a warning is issued with the SIGNAL or RESIGNAL statement (that is, an error with an SQLSTATE starting with '01'), it will be treated like an error.

 Creating a Trigger
------------------

 Here's a simple example to demonstrate a trigger in action. Using these two tables as an example:

 
```
CREATE TABLE animals (id mediumint(9) 
NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`));

CREATE TABLE animal_count (animals int);

INSERT INTO animal_count (animals) VALUES(0);

```

We want to increment a counter each time a new animal is added. Here's what the trigger will look like:

 
```
CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.animals = animal_count.animals+1;

```

The trigger has:

 * a *name* (in this case `increment_animal`)
* a trigger time (in this case *after* the specified trigger event)
* a trigger event (an `INSERT`)
* a table with which it is associated (`animals`)
* a set of statements to run (here, just the one UPDATE statement)

 `AFTER INSERT` specifies that the trigger will run *after* an `INSERT`. The trigger could also be set to run *before*, and the statement causing the trigger could be a `DELETE` or an `UPDATE` as well.

 Now, if we insert a record into the `animals` table, the trigger will run, incrementing the animal\_count table;

 
```
SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       0 |
+---------+

INSERT INTO animals (name) VALUES('aardvark');
INSERT INTO animals (name) VALUES('baboon');

SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       2 |
+---------+

```

For more details on the syntax, see [CREATE TRIGGER](../create-trigger/index).

 Dropping Triggers
-----------------

 To drop a trigger, use the [DROP TRIGGER](../drop-trigger/index) statement. Triggers are also dropped if the table with which they are associated is also dropped.

 
```
 DROP TRIGGER increment_animal; 

```

Triggers Metadata
-----------------

 The [Information Schema TRIGGERS Table](../information-schema-triggers-table/index) stores information about triggers.

 The [SHOW TRIGGERS](../show-triggers/index) statement returns similar information.

 The [SHOW CREATE TRIGGER](../show-create-trigger/index) statement returns a CREATE TRIGGER statement that creates the given trigger.

 More Complex Triggers
---------------------

 Triggers can consist of multiple statements enclosed by a [BEGIN and END](../begin-end/index). If you're entering multiple statements on the command line, you'll want to temporarily set a new delimiter so that you can use a semicolon to delimit the statements inside your trigger. See [Delimiters in the mariadb client](../delimiters/index) for more.

 
```
DROP TABLE animals;

UPDATE animal_count SET animals=0;

CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB;

DELIMITER //
CREATE TRIGGER the_mooses_are_loose
AFTER INSERT ON animals
FOR EACH ROW
BEGIN
 IF NEW.name = 'Moose' THEN
  UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END; //

DELIMITER ;

INSERT INTO animals (name) VALUES('Aardvark');

SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       1 |
+---------+

INSERT INTO animals (name) VALUES('Moose');

SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|     101 |
+---------+

```

Trigger Errors
--------------

 If a trigger contains an error and the engine is transactional, or it is a BEFORE trigger, the trigger will not run, and will prevent the original statement from running as well. If the engine is non-transactional, and it is an AFTER trigger, the trigger will not run, but the original statement will.

 Here, we'll drop the above examples, and then recreate the trigger with an error, a field that doesn't exist, first using the default [InnoDB](../innodb/index), a transactional engine, and then again using [MyISAM](../myisam/index), a non-transactional engine.

 
```
DROP TABLE animals;

CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB;

CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.id = animal_count_id+1;

INSERT INTO animals (name) VALUES('aardvark');
ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'

SELECT * FROM animals;
Empty set (0.00 sec)

```

And now the identical procedure, but with a MyISAM table.

 
```
DROP TABLE animals;

CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=MyISAM;

CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.id = animal_count_id+1;

INSERT INTO animals (name) VALUES('aardvark');
ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'

SELECT * FROM animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | aardvark |
+----+----------+

```

The following example shows how to use a trigger to validate data. The [SIGNAL](../signal/index) statement is used to intentionally produce an error if the email field is not a valid email. As the example shows, in that case the new row is not inserted (because it is a BEFORE trigger).

 
```
CREATE TABLE user (
	id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	first_name CHAR(20),
	last_name CHAR(20),
	email CHAR(100)
)
	ENGINE = MyISAM;

DELIMITER //
CREATE TRIGGER bi_user
  BEFORE INSERT ON user
  FOR EACH ROW
BEGIN
  IF NEW.email NOT LIKE '_%@_%.__%' THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Email field is not valid';
  END IF;
END; //
DELIMITER ;

INSERT INTO user (first_name, last_name, email) VALUES ('John', 'Doe', 'john_doe.example.net');
ERROR 1644 (45000): Email field is not valid

SELECT * FROM user;
Empty set (0.00 sec)

```

See Also
--------

 * [CREATE TRIGGER](../create-trigger/index)
* [DROP TRIGGER](../drop-trigger/index)
* [Information Schema TRIGGERS Table](../information-schema-triggers-table/index)
* [SHOW TRIGGERS](../show-triggers/index)
* [SHOW CREATE TRIGGER](../show-create-trigger/index)
* [Trigger Limitations](../trigger-limitations/index)
* [Creative uses of triggers: Things you people wouldn't believe](https://www.youtube.com/watch?v=-O2up6Fr9M0) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/trigger-overview/>

Upgrading from MariaDB 10.3 to MariaDB 10.4 with Galera Cluster
===============================================================

    
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**Since [MariaDB 10.1](../what-is-mariadb-101/index), the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch has been merged into MariaDB Server. Therefore, in [MariaDB 10.1](../what-is-mariadb-101/index) and above, the functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the Galera wsrep provider library package.

 
Beginning in [MariaDB 10.1](../what-is-mariadb-101/index), [Galera Cluster](../what-is-mariadb-galera-cluster/index) ships with the MariaDB Server. Upgrading a Galera Cluster node is very similar to upgrading a server from [MariaDB 10.3](../what-is-mariadb-103/index) to [MariaDB 10.4](../what-is-mariadb-104/index). For more information on that process as well as incompatibilities between versions, see the [Upgrade Guide](../upgrading-from-mariadb-103-to-mariadb-104/index).

 Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade from [MariaDB 10.3](../what-is-mariadb-103/index) to [MariaDB 10.4](../what-is-mariadb-104/index) when using Galera Cluster. In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 First, before you get started:

 1. First, take a look at [Upgrading from MariaDB 10.3 to MariaDB 10.4](../upgrading-from-mariadb-103-to-mariadb-104/index) to see what has changed between the major versions.
	1. Check whether any system variables or options have been changed or removed. Make sure that your server's configuration is compatible with the new MariaDB version before upgrading.
	2. Check whether replication has changed in the new MariaDB version in any way that could cause issues while the cluster contains upgraded and non-upgraded nodes.
	3. Check whether any new features have been added to the new MariaDB version. If a new feature in the new MariaDB version cannot be replicated to the old MariaDB version, then do not use that feature until all cluster nodes have been upgrades to the new MariaDB version.
2. Next, make sure that the Galera version numbers are compatible.
	1. If you are upgrading from the most recent [MariaDB 10.3](../what-is-mariadb-103/index) release to [MariaDB 10.4](../what-is-mariadb-104/index), then the versions will be compatible. [MariaDB 10.3](../what-is-mariadb-103/index) uses Galera 3 (i.e. Galera wsrep provider versions 25.3.x), and [MariaDB 10.4](../what-is-mariadb-104/index) uses Galera 4 (i.e. Galera wsrep provider versions 26.4.x). This means that upgrading to [MariaDB 10.4](../what-is-mariadb-104/index) also upgrades the system to Galera 4. However, Galera 3 and Galera 4 should be compatible for the purposes of a rolling upgrade, as long as you are using Galera 26.4.2 or later.
	2. See [What is MariaDB Galera Cluster?: Galera wsrep provider Versions](../what-is-mariadb-galera-cluster/index#galera-wsrep-provider-versions) for information on which MariaDB releases uses which Galera wsrep provider versions.
3. Ideally, you want to have a large enough gcache to avoid a [State Snapshot Transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index) during the rolling upgrade. The gcache size can be configured by setting `[gcache.size](../wsrep_provider_options/index#gcachesize)` For example:   
 `wsrep_provider_options="gcache.size=2G"`

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  Then, for each node, perform the following steps:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.4](../what-is-mariadb-104/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. If you use a load balancing proxy such as MaxScale or HAProxy, make sure to drain the server from the pool so it does not receive any new connections.
3. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
4. Uninstall the old version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server galera`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server galera`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server galera`
5. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
6. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
7. On Linux distributions that use `systemd` you may need to increase the service startup timeout as the default timeout of 90 seconds may not be sufficient. See [Systemd: Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for more information.
8. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
9. Run `[mysql\_upgrade](../mysql_upgrade/index)` with the `--skip-write-binlog` option.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-103-to-mariadb-104-with-galera-cluster/>

Upgrading from MariaDB 10.2 to MariaDB 10.3 with Galera Cluster
===============================================================

    
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**Since [MariaDB 10.1](../what-is-mariadb-101/index), the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch has been merged into MariaDB Server. Therefore, in [MariaDB 10.1](../what-is-mariadb-101/index) and above, the functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the Galera wsrep provider library package.

 
Beginning in [MariaDB 10.1](../what-is-mariadb-101/index), [Galera Cluster](../what-is-mariadb-galera-cluster/index) ships with the MariaDB Server. Upgrading a Galera Cluster node is very similar to upgrading a server from [MariaDB 10.2](../what-is-mariadb-102/index) to [MariaDB 10.3](../what-is-mariadb-103/index). For more information on that process as well as incompatibilities between versions, see the [Upgrade Guide](../upgrading-from-mariadb-102-to-mariadb-103/index).

 Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade from [MariaDB 10.2](../what-is-mariadb-102/index) to [MariaDB 10.3](../what-is-mariadb-103/index) when using Galera Cluster. In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 First, before you get started:

 1. First, take a look at [Upgrading from MariaDB 10.2 to MariaDB 10.3](../upgrading-from-mariadb-102-to-mariadb-103/index) to see what has changed between the major versions.
	1. Check whether any system variables or options have been changed or removed. Make sure that your server's configuration is compatible with the new MariaDB version before upgrading.
	2. Check whether replication has changed in the new MariaDB version in any way that could cause issues while the cluster contains upgraded and non-upgraded nodes.
	3. Check whether any new features have been added to the new MariaDB version. If a new feature in the new MariaDB version cannot be replicated to the old MariaDB version, then do not use that feature until all cluster nodes have been upgrades to the new MariaDB version.
2. Next, make sure that the Galera version numbers are compatible.
	1. If you are upgrading from the most recent [MariaDB 10.2](../what-is-mariadb-102/index) release to [MariaDB 10.3](../what-is-mariadb-103/index), then the versions will be compatible. Both [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index) use Galera 3 (i.e. Galera wsrep provider versions 25.3.x), so they should be compatible.
	2. See [What is MariaDB Galera Cluster?: Galera wsrep provider Versions](../what-is-mariadb-galera-cluster/index#galera-wsrep-provider-versions) for information on which MariaDB releases uses which Galera wsrep provider versions.
3. Ideally, you want to have a large enough gcache to avoid a [State Snapshot Transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index) during the rolling upgrade. The gcache size can be configured by setting `[gcache.size](../wsrep_provider_options/index#gcachesize)` For example:   
 `wsrep_provider_options="gcache.size=2G"`

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  Then, for each node, perform the following steps:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.3](../what-is-mariadb-103/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. If you use a load balancing proxy such as MaxScale or HAProxy, make sure to drain the server from the pool so it does not receive any new connections.
3. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
4. Uninstall the old version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server galera`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server galera`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server galera`
5. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
6. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
7. On Linux distributions that use `systemd` you may need to increase the service startup timeout as the default timeout of 90 seconds may not be sufficient. See [Systemd: Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for more information.
8. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
9. Run `[mysql\_upgrade](../mysql_upgrade/index)` with the `--skip-write-binlog` option.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-102-to-mariadb-103-with-galera-cluster/>

Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster
===============================================================

    
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**Since [MariaDB 10.1](../what-is-mariadb-101/index), the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch has been merged into MariaDB Server. Therefore, in [MariaDB 10.1](../what-is-mariadb-101/index) and above, the functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the Galera wsrep provider library package.

  Beginning in [MariaDB 10.1](../what-is-mariadb-101/index), [Galera Cluster](../what-is-mariadb-galera-cluster/index) ships with the MariaDB Server. Upgrading a Galera Cluster node is very similar to upgrading a server from [MariaDB 10.1](../what-is-mariadb-101/index) to [MariaDB 10.2](../what-is-mariadb-102/index). For more information on that process as well as incompatibilities between versions, see the [Upgrade Guide](../upgrading-from-mariadb-101-to-mariadb-102/index).

 Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade from [MariaDB 10.1](../what-is-mariadb-101/index) to [MariaDB 10.2](../what-is-mariadb-102/index) when using Galera Cluster. In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 First, before you get started:

 1. First, take a look at [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index) to see what has changed between the major versions.
	1. Check whether any system variables or options have been changed or removed. Make sure that your server's configuration is compatible with the new MariaDB version before upgrading.
	2. Check whether replication has changed in the new MariaDB version in any way that could cause issues while the cluster contains upgraded and non-upgraded nodes.
	3. Check whether any new features have been added to the new MariaDB version. If a new feature in the new MariaDB version cannot be replicated to the old MariaDB version, then do not use that feature until all cluster nodes have been upgrades to the new MariaDB version.
2. Next, make sure that the Galera version numbers are compatible.
	1. If you are upgrading from the most recent [MariaDB 10.1](../what-is-mariadb-101/index) release to [MariaDB 10.2](../what-is-mariadb-102/index), then the versions will be compatible. Both [MariaDB 10.1](../what-is-mariadb-101/index) and [MariaDB 10.2](../what-is-mariadb-102/index) use Galera 3 (i.e. Galera wsrep provider versions 25.3.x), so they should be compatible.
	2. See [What is MariaDB Galera Cluster?: Galera wsrep provider Versions](../what-is-mariadb-galera-cluster/index#galera-wsrep-provider-versions) for information on which MariaDB releases uses which Galera wsrep provider versions.
3. Ideally, you want to have a large enough gcache to avoid a [State Snapshot Transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index) during the rolling upgrade. The gcache size can be configured by setting `[gcache.size](../wsrep_provider_options/index#gcachesize)` For example:   
 `wsrep_provider_options="gcache.size=2G"`

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  Then, for each node, perform the following steps:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.2](../what-is-mariadb-102/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. If you use a load balancing proxy such as MaxScale or HAProxy, make sure to drain the server from the pool so it does not receive any new connections.
3. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
	* This step is not necessary when upgrading to [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) or later. Omitting it can make the upgrade process far faster. See [MDEV-12289](https://jira.mariadb.org/browse/MDEV-12289) for more information.
4. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
5. Uninstall the old version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server galera`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server galera`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server galera`
6. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
7. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
	* In order to use Galera Cluster without problems in [MariaDB 10.2](../what-is-mariadb-102/index), the `[innodb\_lock\_schedule\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_lock_schedule_algorithm)` system variable must be set to `FCFS`. In [MariaDB 10.2.12](https://mariadb.com/kb/en/mariadb-10212-release-notes/) and later, this system variable is automatically set to this value when Galera Cluster is enabled. In [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/) and before, this system variable must be set to this value manually. See [MDEV-12837](https://jira.mariadb.org/browse/MDEV-12837) for more information.
8. On Linux distributions that use `systemd` you may need to increase the service startup timeout as the default timeout of 90 seconds may not be sufficient. See [Systemd: Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for more information.
9. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
10. Run `[mysql\_upgrade](../mysql_upgrade/index)` with the `--skip-write-binlog` option.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

 
### Additional details

 #### Checking Status of the State Transfer

 When a node rejoins the cluster after being upgraded, it may have to perform a state transfer, such as an [Incremental State Transfer (IST)](../getting-started-with-mariadb-galera-cluster/index#incremental-state-transfers-ists) or a [State Snapshot Transfer(SST)](../introduction-to-state-snapshot-transfers-ssts/index). It is recommended to ensure that the node's state transfer is complete before upgrading the next node in the cluster.

 ##### State Transfers that Provide Access to the Server

 If the node is synchronizing with the cluster by performing a state transfer that allows access to the server, such as an [Incremental State Transfer (IST)](../getting-started-with-mariadb-galera-cluster/index#incremental-state-transfers-ists) or a [State Snapshot Transfer(SST)](../introduction-to-state-snapshot-transfers-ssts/index) that uses the `[mysqldump](../mysqldump/index)` SST method, then you can check the status of the state transfer by connecting to the server through the `mysql` client, then checking the `[wsrep\_local\_state\_uuid](../galera-cluster-status-variables/index#wsrep_local_state_uuid)` and `[wsrep\_cluster\_state\_uuid](../galera-cluster-status-variables/index#wsrep_cluster_state_uuid)` status variables. When they equal each other, the node is in sync with the cluster.

 
```
select if((SELECT VARIABLE_VALUE AS "uuid"
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = "wsrep_cluster_state_uuid")=(SELECT VARIABLE_VALUE AS "uuid"
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = "wsrep_local_state_uuid"), "Synced", "Not Synced") as "Cluster Status"; 

+----------------+
| Cluster Status |
+----------------+
| Synced         |
+----------------+

```

When the local and cluster UUID's come into sync, the node is again online and functioning as a part of the cluster.

 ##### State Transfers that Require the Server to be Down

 Some state transfers require the server to be unavailable, such as all [State Snapshot Transfer(SST)](../introduction-to-state-snapshot-transfers-ssts/index) methods other than `mysqldump`, so `mysql` client access is unavailable while the state transfer is happening. In those cases, you may have to monitor the progress of the state transfer in the [error log](../error-log/index). You'll know when the SST is complete when the joiner node changes its state to `SYNCED`. For example:

 
```
2018-08-30 14:44:15 140694729484032 [Note] WSREP: Shifting JOINED -> SYNCED (TO: 210248566)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-101-to-mariadb-102-with-galera-cluster/>

Trigger Limitations
===================

     The following restrictions apply to [triggers](../triggers/index).

 * All of the restrictions listed in [Stored Routine Limitations](../stored-routine-limitations/index).
* All of the restrictions listed in [Stored Function Limitations](../stored-function-limitations/index).
* Until [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/), each table can have only one trigger for each timing/event combination (ie: you can't define two BEFORE INSERT triggers for the same table).
* Triggers are always executed for each row. The standard `FOR EACH STATEMENT` option is not supported in MariaDB,
* Triggers cannot operate on any tables in the mysql, information\_schema or performance\_schema database.
* Cannot return a resultset.
* The [RETURN](../return/index) statement is not permitted, since triggers don't return any values. Use [LEAVE](../leave/index) to immediately exit a trigger.
* Triggers are not activated by [foreign key](../foreign-keys/index) actions.
* If a trigger is loaded into cache, it is not automatically reloaded when the table metadata changes. In this case a trigger can operate using the outdated metadata.
* By default, with row-based replication, triggers run on the master, and the effects of their executions are replicated to the slaves. However, starting from [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), it is possible to run triggers on the slaves. See [Running triggers on the slave for Row-based events](../running-triggers-on-the-slave-for-row-based-events/index).

 See Also
--------

 * [Trigger Overview](../trigger-overview/index)
* [CREATE TRIGGER](../create-trigger/index)
* [DROP TRIGGER](../drop-trigger/index)
* [Information Schema TRIGGERS Table](../information-schema-triggers-table/index)
* [SHOW TRIGGERS](../show-triggers/index)
* [SHOW CREATE TRIGGER](../show-create-trigger/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/trigger-limitations/>

Upgrading from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0
========================================================================

    Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0. In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 First, before you get started:

 1. First, take a look at [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index) to see what has changed between the major versions.
	1. Check whether any system variables or options have been changed or removed. Make sure that your server's configuration is compatible with the new MariaDB version before upgrading.
	2. Check whether replication has changed in the new MariaDB version in any way that could cause issues while the cluster contains upgraded and non-upgraded nodes.
	3. Check whether any new features have been added to the new MariaDB version. If a new feature in the new MariaDB version cannot be replicated to the old MariaDB version, then do not use that feature until all cluster nodes have been upgrades to the new MariaDB version.
2. Next, make sure that the Galera version numbers are compatible.
	1. If you are upgrading from the most recent MariaDB Galera Cluster 5.5 release to MariaDB Galera Cluster 10.0, then the versions will be compatible. The latest releases of MariaDB Galera Cluster 5.5 and MariaDB Galera Cluster 10.0 use Galera 3 (i.e. Galera wsrep provider versions 25.3.x), so they should be compatible.
	2. If you are running an older MariaDB Galera Cluster 5.5 release that still uses Galera 2 (i.e. Galera wsrep provider versions 25.2.x), then it is recommended to first upgrade to the latest MariaDB Galera Cluster 5.5 release that uses Galera 3 (i.e. Galera wsrep provider versions 25.3.x).
	3. See [What is MariaDB Galera Cluster?: Galera wsrep provider Versions](../what-is-mariadb-galera-cluster/index#galera-wsrep-provider-versions) for information on which MariaDB releases uses which Galera wsrep provider versions.
3. Ideally, you want to have a large enough gcache to avoid a [State Snapshot Transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index) during the rolling upgrade. The gcache size can be configured by setting `[gcache.size](../wsrep_provider_options/index#gcachesize)` For example:   
 `wsrep_provider_options="gcache.size=2G"`

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index).

  Then, for each node, perform the following steps:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.1](../what-is-mariadb-101/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. If you use a load balancing proxy such as MaxScale or HAProxy, make sure to drain the server from the pool so it does not receive any new connections.
3. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
4. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
5. Uninstall the old version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-galera-server galera`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-Galera-server galera`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-Galera-server galera`
6. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
7. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
8. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
9. Run `[mysql\_upgrade](../mysql_upgrade/index)` with the `--skip-write-binlog` option.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

 
:

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-galera-cluster-55-to-mariadb-galera-cluster-100/>

Upgrading Between Minor Versions with Galera Cluster
====================================================

    Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade between minor versions of MariaDB (for example from [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/) to [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/)) when Galera Cluster is being used. In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

 
For each node, perform the following steps:

 1. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
2. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
3. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
4. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
5. Run [mariadb-upgrade](../mariadb-upgrade/index) with the `--skip-write-binlog` option.
	* `mariadb-upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-between-minor-versions-with-galera-cluster/>

myisamchk Table Information
===========================

     [myisamchk](../myisamchk/index) can be used to obtain information about MyISAM tables, particularly with the *-d*, *-e*, *-i* and *-v* options.

 Common options for gathering information include:

 * myisamchk -d
* myisamchk -dv
* myisamchk -dvv
* myisamchk -ei
* myisamchk -eiv

 The *-d* option returns a short description of the table and its keys. Running the option while the table is being updated, and with external locking disabled, may result in an error, but no damage will be done to the table. Each extra *v* adds more output. *-e* checks the table thoroughly (but slowly), and the *-i* options adds statistical information,

 -dvv output
-----------

 The following table describes the output from the running myisamchk with the *-dvv* option:

 


| Heading | Description |
| --- | --- |
| MyISAM file | Name and path of the MyISAM index file (without the extension) |
| Record format | [Storage format](../myisam-storage-formats/index). One of *packed* (dynamic), *fixed* or *compressed*. |
| Chararacter set | Default [character set](../data-types-character-sets-and-collations/index) for the table. |
| File-version | Always 1. |
| Creation time | Time the data file was created |
| Recover time | Most recent time the file was reconstructed. |
| Status | Table status. One or more of *analyzed*, *changed*, *crashed*, *open*, *optimized keys* and *sorted index pages*. |
| Auto increment key | Index number of the table's <auto-increment> column. Not shown if no auto-increment column exists. |
| Last value | Most recently generated auto-increment value. Not shown if no auto-increment column exists. |
| Data records | Number of records in the table. |
| Deleted blocks | Number of deleted blocks that are still reserving space. Use [OPTIMIZE TABLE](../optimize-table/index) to defragment. |
| Datafile parts | For [dynamic tables](../myisam-storage-formats/index), the number of data blocks. If the table is optimized, this will match the number of data records. |
| Deleted data | Number of bytes of unreclaimed deleted data, Use [OPTIMIZE TABLE](../optimize-table/index) to reclaim the space. |
| Datafile pointer | Size in bytes of the data file pointer. The size of the data file pointer, in bytes. |
| Keyfile pointer | Size in bytes of the index file pointer. |
| Max datafile length | Maximum length, in bytes, that the data file could become. |
| Max keyfile length | Maximum length, in bytes, that the index file could become. |
| Recordlength | Space, in bytes, that each row takes. |
| table description | Description of all indexes in the table, followed by all columns |
| Key | Index number, starting with one. If not shown, the index is part of a multiple-column index. |
| Start | Where the index part starts in the row. |
| Len | Length of the index or index part. The length of a multiple-column index is the sum of the component lengths. Indexes of string columns will be shorter than the full column length if only a string prefix is indexed. |
| Index | Whether an index value is unique or not. Either *multip.* or *unique*. |
| Type | Data type of the index of index part. |
| Rec/key | Record of the number of rows per value for the index or index part. Used by the optimizer to calculate query plans. Can be updated with [myisamchk-a](../myisamchk/index). If not present, defaults to *30*. |
| Root | Root index block address. |
| Blocksize | Index block size, in bytes. |
| Field | Column number, starting with one. The first line will contain the position and number of bytes used to store NULL flags, if any (see *Nullpos* and *Nullbit*, below). |
| Start | Column's byte position within the table row. |
| Length | Column length, in bytes. |
| Nullpos | Byte containing the flag for NULL values. Empty if column cannot be NULL. |
| Nullbit | Bit containing the flag for NULL values. Empty if column cannot be NULL. |
| Type | Data type - see the table below for a list of possible values. |
| Huff tree | Only present for packed tables, contains the Huffman tree number associated with the column. |
| Bits | Only present for packed tables, contains the number of bits used in the Huffman tree. |

 



| Data type | Description |
| --- | --- |
| constant | All rows contain the same value. |
| no endspace | No endspace is stored. |
| no endspace, not\_always | No endspace is stored, and endspace compression is not always performed for all values. |
| no endspace, no empty | No endspace is stored, no empty values are stored. |
| table-lookup | Column was converted to an [ENUM](../enum/index). |
| zerofill(N) | Most significant *N* bytes of the value are not stored, as they are always zero. |
| no zeros | Zeros are not stored. |
| always zero | Zero values are stored with one bit. |

 
-eiv output
-----------

 The following table describes the output from the running myisamchk with the *-eiv* option:

 


| Heading | Description |
| --- | --- |
| Data records | Number of records in the table. |
| Deleted blocks | Number of deleted blocks that are still reserving space. Use [OPTIMIZE TABLE](../optimize-table/index) to defragment. |
| Key | Index number, starting with one. |
| Keyblocks used | Percentage of the keyblocks that are used. Percentages will be higher for optimized tables. |
| Packed | Percentage space saved from packing key values with a common suffix. |
| Max levels | Depth of the [b-tree index](../storage-engine-index-types/index#b-tree-indexes) for the key. Larger tables and longer key values result in higher values. |
| Records | Number of records in the table. |
| M.recordlength | Average row length. For fixed rows, will be the actual length of each row. |
| Packed | Percentage saving from stripping spaces from the end of strings. |
| Recordspace used | Percentage of the data file used. |
| Empty space | Percentage of the data file unused. |
| Blocks/Record | Average number of blocks per record. Values higher than one indicate fragmentation. Use [OPTIMIZE TABLE](../optimize-table/index) to defragment. |
| Recordblocks | Number of used blocks. Will match the number of rows for fixed or optimized tables. |
| Deleteblocks | Number of deleted blocks |
| Recorddata | Used bytes in the data file. |
| Deleted data | Unused bytes in the data file. |
| Lost space | Total bytes lost, such as when a row is updated to a shorter length. |
| Linkdata | Sum of the bytes used for pointers linking disconnected blocks. Each is four to seven bytes in size. |

 
Examples
--------

 
```
myisamchk -d /var/lib/mysql/test/posts

MyISAM file:         /var/lib/mysql/test/posts
Record format:       Compressed
Character set:       utf8mb4_unicode_ci (224)
Data records:                 1680  Deleted blocks:                 0
Recordlength:                 2758
Using only keys '0' of 5 possibly keys

table description:
Key Start Len Index   Type
1   1     8   unique  ulonglong            
2   2265  80  multip. varchar prefix       
    63    80          varchar              
    17    5           binary               
    1     8           ulonglong            
3   1231  8   multip. ulonglong            
4   9     8   multip. ulonglong            
5   387   764 multip. ? prefix

```


```
myisamchk -dvv /var/lib/mysql/test/posts

MyISAM file:         /var/lib/mysql/test/posts
Record format:       Compressed
Character set:       utf8mb4_unicode_ci (224)
File-version:        1
Creation time:       2015-08-10 16:26:54
Recover time:        2015-08-10 16:26:54
Status:              checked,analyzed,optimized keys
Auto increment key:              1  Last value:                  1811
Checksum:               2299272165
Data records:                 1680  Deleted blocks:                 0
Datafile parts:               1680  Deleted data:                   0
Datafile pointer (bytes):        6  Keyfile pointer (bytes):        6
Datafile length:           4298092  Keyfile length:            156672
Max datafile length: 281474976710654  Max keyfile length: 288230376151710719
Recordlength:                 2758
Using only keys '0' of 5 possibly keys

table description:
Key Start Len Index   Type                     Rec/key         Root  Blocksize
1   1     8   unique  ulonglong                      1                    1024
2   2265  80  multip. varchar prefix               336                    1024
    63    80          varchar                      187
    17    5           binary                         1
    1     8           ulonglong                      1
3   1231  8   multip. ulonglong                     10                    1024
4   9     8   multip. ulonglong                    840                    1024
5   387   764 multip. ? prefix                       1                    4096

Field Start Length Nullpos Nullbit Type                         Huff tree  Bits
1     1     8                      zerofill(6)                          1     9
2     9     8                      zerofill(7)                          1     9
3     17    5                                                           1     9
4     22    5                                                           1     9
5     27    12                     blob                                 2     9
6     39    10                     blob                                 3     9
7     49    4                      always zero                          1     9
8     53    10                     blob                                 1     9
9     63    81                     varchar                              4     9
10    144   81                     varchar                              5     5
11    225   81                     varchar                              5     5
12    306   81                     varchar                              1     9
13    387   802                    varchar                              6     9
14    1189  10                     blob                                 1     9
15    1199  10                     blob                                 7     9
16    1209  5                                                           1     9
17    1214  5                                                           1     9
18    1219  12                     blob                                 1     9
19    1231  8                      no zeros, zerofill(6)                1     9
20    1239  1022                   varchar                              7     9
21    2261  4                      always zero                          1     9
22    2265  81                     varchar                              8     8
23    2346  402                    varchar                              2     9
24    2748  8                      no zeros, zerofill(7)                1     9

```


```
myisamchk -eiv /var/lib/mysql/test/posts
Checking MyISAM file: /var/lib/mysql/test/posts
Data records:    1680   Deleted blocks:       0
- check file-size
- check record delete-chain
No recordlinks
- check key delete-chain
block_size 1024:
block_size 2048:
block_size 3072:
block_size 4096:
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  92%  Packed:    0%  Max levels:  2
- check data record references index: 2
Key:  2:  Keyblocks used:  93%  Packed:   90%  Max levels:  2
- check data record references index: 3
Key:  3:  Keyblocks used:  92%  Packed:    0%  Max levels:  2
- check data record references index: 4
Key:  4:  Keyblocks used:  92%  Packed:    0%  Max levels:  2
- check data record references index: 5
Key:  5:  Keyblocks used:  88%  Packed:   97%  Max levels:  2
Total:    Keyblocks used:  91%  Packed:   91%

- check records and index references
Records:              1680    M.recordlength:     4102   Packed:             0%
Recordspace used:      100%   Empty space:           0%  Blocks/Record:   1.00
Record blocks:        1680    Delete blocks:         0
Record data:       6892064    Deleted data:          0
Lost space:           1284    Linkdata:           6264

User time 0.11, System time 0.00
Maximum resident set size 3036, Integral resident set size 0
Non-physical pagefaults 925, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 0, Involuntary context switches 74

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisamchk-table-information/>

Triggers and Implicit Locks
===========================

    A [trigger](../triggers/index) may reference multiple tables, and if a `[LOCK TABLES](../lock-tables/index)` statement is used on one of the tables, other tables may at the same time also implicitly be locked due to the trigger.

 If the trigger only reads from the other table, that table will be read locked. If the trigger writes to the other table, it will be write locked. If a table is read-locked for reading via `LOCK TABLES`, but needs to be write-locked because it could be modified by a trigger, a write lock is taken.

 All locks are acquired together when the `LOCK TABLES` statement is issued and they are released together on `UNLOCK TABLES`.

 Example
-------

 
```
LOCK TABLE table1 WRITE

```

Assume `table1` contains the following trigger:

 
```
CREATE TRIGGER trigger1 AFTER INSERT ON table1 FOR EACH ROW
BEGIN
  INSERT INTO table2 VALUES (1);
  UPDATE table3 SET writes = writes+1
    WHERE id = NEW.id AND EXISTS (SELECT id FROM table4);
END;

```

Not only is `table1` write locked, `table2` and `table3` are also write locked, due to the possible `[INSERT](../insert/index)` and `[UPDATE](../update/index)`, while `table4` is read locked due to the `[SELECT](../select/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/triggers-and-implicit-locks/>

MyISAM Storage Formats
======================

     The [MyISAM](../myisam/index) storage engine supports three different table storage formats.

 These are FIXED, DYNAMIC and COMPRESSED. FIXED and DYNAMIC can be set with the ROW FORMAT option in the [CREATE TABLE](../create-table/index) statement, or will be chosen automatically depending on the columns the table contains. COMPRESSED can only be set via the [myisampack](../myisampack/index) tool.

 The [SHOW TABLE STATUS](../show-table-status/index) statement can be used to see the storage format used by a table. Note that `COMPRESSED` tables are reported as `DYNAMIC` in that context.

 Fixed-length
------------

 Fixed-length (or static) tables contain records of a fixed-length. Each column is the same length for all records, regardless of the actual contents. It is the default format if a table has no [BLOB](../blob/index), [TEXT](../text/index), [VARCHAR](../varchar/index) or [VARBINARY](../varbinary/index) fields, and no ROW FORMAT is provided. You can also specify a fixed table with ROW\_FORMAT=FIXED in the table definition.

 
Tables containing BLOB or TEXT fields cannot be FIXED, as by design these are both dynamic fields. However, no error or warning will be raised if you specify FIXED.

 
Fixed-length tables have a number of characteristics

 * fast, since MariaDB will always know where a record begins
* easy to repair: [myisamchk](../myisamchk/index) is always able to recover all rows, except for the last one if it is not entirely written
* easy to cache
* take up more space than dynamic or compressed tables, as the maximum amount of storage space will be allocated to each record.
* reconstructing after a crash is uncomplicated due to the fixed positions
* no fragmentation or need to re-organize, unless records have been deleted and you want to free the space up.

 Dynamic
-------

 Dynamic tables contain records of a variable length. It is the default format if a table has any BLOB, TEXT, VARCHAR or VARBINARY fields, and no ROW FORMAT is provided. You can also specify a DYNAMIC table with ROW\_FORMAT=DYNAMIC in the table definition. If the table contains BLOB or TEXT columns, its format is always DYNAMIC, and the ROW FORMAT option is ignored.

 Dynamic tables have a number of characteristics

 * Each row contains a header indicating the length of the row.
* Rows tend to become fragmented easily. UPDATING a record to be longer will likely ensure it is stored in different places on the disk. Use [OPTIMIZE TABLE](../optimize-table/index) when the fragmentation is too high.
* All string columns with a length of four or more are dynamic.
* They require much less space than fixed-length tables.
* Restoring after a crash is more complicated than with FIXED tables. Some fragments may be lost.

 If a DYNAMIC table has some frequently-accessed fixed-length columns, it could be a good idea to move them into a separate FIXED table to avoid fragmentation.

 Compressed
----------

 Compressed tables are a read-only format, created with the [myisampack](../myisampack/index) tool. This can be done while the server is running, but external lock must not be disabled. [myisamchk](../myisamchk/index) is used to uncompress them.

 Compressed tables have a number of characteristics:

 * while the data is read-only, DDL statements such as [DROP TABLE](../drop-table/index) and [TRUNCATE TABLE](../truncate-table/index) will still function.
* take much less space than fixed or dynamic tables. Each data has usually a 40-70% compression ratio
* rows are compressed separately, reducing access overhead.
* row headers will be from one to three bytes.
* rows can be compressed with different compression types, including
	+ prefix space compression
	+ suffix space compression
	+ columns with small sets of values are converted to ENUM
	+ numeric zeros are stored with only one bit
	+ integer columns will be reduced to the smallest int type that can hold the contents

 See Also
--------

 * [Why we still need MyISAM (for read-only tables)](http://jfg-mysql.blogspot.nl/2017/08/why-we-still-need-myisam.html) describes an important use case for MyISAM compressed tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myisam-storage-formats/>

FLUSH QUERY CACHE
=================

    Description
-----------

 You can defragment [the query cache](../the-query-cache/index) to better utilize its memory with the `FLUSH QUERY CACHE` statement. The statement does not remove any queries from the cache.

 The [RESET QUERY CACHE](../reset/index) statement removes all query results from the query cache. The [FLUSH TABLES](../flush/index) statement also does this.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/flush-query-cache/>

About FederatedX
================

    The FederatedX storage engine is a fork of MySQL's [Federated storage engine](https://dev.mysql.com/doc/refman/5.5/en/federated-storage-engine.html), which is no longer being developed by Oracle. The original purpose of FederatedX was to keep this storage engine's development progressing-- to both add new features as well as fix old bugs.

 Since [MariaDB 10.0](../what-is-mariadb-100/index), the [CONNECT](../connect/index) storage engine also allows access to a remote database via MySQL or ODBC connection (table types: [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index)). However, in the current implementation there are several limitations.

 What is the FederatedX storage engine?
--------------------------------------

 The FederatedX Storage Engine is a storage engine that works with both MariaDB and MySQL. Where other storage engines are built as interfaces to lower-level file-based data stores, FederatedX uses libmysql to talk to the data source, the data source being a remote RDBMS. Currently, since FederatedX only uses libmysql, it can only talk to another MySQL RDBMS. The plan is of course to be able to use other RDBMS systems as a data source. There is an existing project Federated ODBC which was able to use PostgreSQL as a remote data source, and it is this type of functionality which will be brought to FederatedX in subsequent versions.

 History
-------

 The history of FederatedX is derived from the History of Federated. Cisco needed a MySQL storage engine that would allow them to consolidate remote tables on some sort of routing device, being able to interact with these remote tables as if they were local to the device, but not actually on the device, since the routing device had only so much storage space. The first prototype of the Federated Storage Engine was developed by JD (need to check on this- Brian Aker can verify) using the HANDLER interface. Brian handed the code to Patrick Galbraith and explained how it needed to work, and with Brian and Monty's tutelage and Patrick had a working Federated Storage Engine with MySQL 5.0. Eventually, Federated was released to the public in a MySQL 5.0 release. 

 When MySQL 5.1 became the production release of MySQL, Federated had more features and enhancements added to it, namely:

 * New Federated SERVER added to the parser. This was something Cisco needed that made it possible to change the connection parameters for numerous Federated tables at once without having to alter or re-create the Federated tables.
* Basic Transactional support-- for supporting remote transactional tables
* Various bugs that needed to be fixed from MySQL 5.0
* Plugin capability

 In [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) FederatedX got support for assisted [table discovery](../table-discovery/index).

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'ha_federatedx';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = ha_federatedx

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'ha_federatedx';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 How FederatedX works
--------------------

 Every storage engine has to implement derived standard handler class API methods for a storage engine to work. FederatedX is no different in that regard. The big difference is that FederatedX needs to implement these handler methods in such as to construct SQL statements to run on the remote server and if there is a result set, process that result set into the internal handler format so that the result is returned to the user.

 ### Internal workings of FederatedX

 Normal database files are local and as such: You create a table called 'users', a file such as 'users.MYD' is created. A handler reads, inserts, deletes, updates data in this file. The data is stored in particular format, so to read, that data has to be parsed into fields, to write, fields have to be stored in this format to write to this data file.

 With the FederatedX storage engine, there will be no local files for each table's data (such as .MYD). A foreign database will store the data that would normally be in this file. This will necessitate the use of MySQL client API to read, delete, update, insert this data. The data will have to be retrieve via an SQL call "`SELECT \* FROM users`". Then, to read this data, it will have to be retrieved via `mysql\_fetch\_row` one row at a time, then converted from the column in this select into the format that the handler expects.

 The basic functionality of how FederatedX works is:

 * The user issues an SQL statement against the local federatedX table. This statement is parsed into an item tree
* FederatedX uses the mysql handler API to implement the various methods required for a storage engine. It has access to the item tree for the SQL statement issued, as well as the Table object and each of its Field members. At
* With this information, FederatedX constructs an SQL statement
* The constructed SQL statement is sent to the Foreign data source through libmysql using the mysql client API
* The foreign database reads the SQL statement and sends the result back through the mysql client API to the origin
* If the original SQL statement has a result set from the foreign data source, the FederatedX storage engine iterates through the result set and converts each row and column to the internal handler format
* If the original SQL statement only returns the number of rows returned (affected\_rows), that number is added to the table stats which results in the user seeing how many rows were affected.

 #### FederatedX table creation

 The create table will simply create the .frm file, and within the `CREATE TABLE` SQL statement, there SHALL be any of the following :

 
```
connection=scheme://username:password@hostname:port/database/tablename
connection=scheme://username@hostname/database/tablename
connection=scheme://username:password@hostname/database/tablename
connection=scheme://username:password@hostname/database/tablename

```

Or using the syntax introduced in MySQL versions 5.1 for a Federated server (SQL/MED Spec xxxx)

 
```
connection="connection_one"
connection="connection_one/table_foo"

```

An example of a connect string specifying all the connection parameters would be:

 
```
connection=mysql://username:password@hostname:port/database/tablename

```

Or, using a Federated server, first a server is created:

 
```
create server 'server_one' foreign data wrapper 'mysql' options
  (HOST '127.0.0.1',
  DATABASE 'db1',
  USER 'root',
  PASSWORD '',
  PORT 3306,
  SOCKET '',
  OWNER 'root');

```

Then the FederatedX table is created specifying the newly created Federated server:

 
```
CREATE TABLE federatedx.t1 (
  `id` int(20) NOT NULL,
  `name` varchar(64) NOT NULL default ''
  )
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='server_one';

```

(Note that in MariaDB, the original Federated storage engine is replaced with the new FederatedX storage engine. And for backward compatibility, the old name "FEDERATED" is used in create table. So in MariaDB, the engine type should be given as "FEDERATED" without an extra "X", not "FEDERATEDX").

 The equivalent of above, if done specifying all the connection parameters

 
```
CONNECTION="mysql://root@127.0.0.1:3306/db1/t1"

```

You can also change the server to point to a new schema:

 
```
ALTER SERVER 'server_one' options(DATABASE 'db2');

```

All subsequent calls to any FederatedX table using the 'server\_one' will now be against db2.t1! Guess what? You no longer have to perform an alter table in order to point one or more FederatedX tables to a new server!

 This `connection="connection string"` is necessary for the handler to be able to connect to the foreign server, either by URL, or by server name. 

 ### Method calls

 One way to see how the FederatedX storage engine works is to compile a debug build of MariaDB and turn on a trace log. Using a two column table, with one record, the following SQL statements shown below, can be analyzed for what internal methods they result in being called.

 #### SELECT

 If the query is for instance "`SELECT \* FROM foo`", then the primary methods you would see with debug turned on would be first:

 
```
ha_federatedx::info
ha_federatedx::scan_time:
ha_federatedx::rnd_init: share->select_query SELECT * FROM foo
ha_federatedx::extra

```

Then for every row of data retrieved from the foreign database in the result set:

 
```
ha_federatedx::rnd_next
ha_federatedx::convert_row_to_internal_format
ha_federatedx::rnd_next

```

After all the rows of data that were retrieved, you would see:

 
```
ha_federatedx::rnd_end
ha_federatedx::extra
ha_federatedx::reset

```

#### INSERT

 If the query was "`INSERT INTO foo (id, ts) VALUES (2, now());`", the trace would be:

 
```
ha_federatedx::write_row
ha_federatedx::reset

```

#### UPDATE

 If the query was "`UPDATE foo SET ts = now() WHERE id = 1;`", the resultant trace would be:

 
```
ha_federatedx::index_init
ha_federatedx::index_read
ha_federatedx::index_read_idx
ha_federatedx::rnd_next
ha_federatedx::convert_row_to_internal_format
ha_federatedx::update_row

ha_federatedx::extra
ha_federatedx::extra
ha_federatedx::extra
ha_federatedx::external_lock
ha_federatedx::reset

```

FederatedX capabilities and limitations
---------------------------------------

 * Tables MUST be created on the foreign server prior to any action on those tables via the handler, first version. IMPORTANT: IF you MUST use the FederatedX storage engine type on the REMOTE end, make sure that the table you connect to IS NOT a table pointing BACK to your ORIGINAL table! You know and have heard the screeching of audio feedback? You know putting two mirrors in front of each other how the reflection continues for eternity? Well, need I say more?!
* There is no way for the handler to know if the foreign database or table has changed. The reason for this is that this database has to work like a data file that would never be written to by anything other than the database. The integrity of the data in the local table could be breached if there was any change to the foreign database.
* Support for SELECT, INSERT, UPDATE, DELETE indexes.
* No ALTER TABLE, DROP TABLE or any other Data Definition Language calls.
* Prepared statements will not be used in the first implementation, it remains to to be seen whether the limited subset of the client API for the server supports this.
* This uses SELECT, INSERT, UPDATE, DELETE and not HANDLER for its implementation.
* This will not work with the query cache.
* FederatedX does not support [GEOMETRY](../geometry/index) types. Such tables cannot be created explicitly, nor discovered.

 How do you use FederatedX?
--------------------------

 To use this handler, it's very simple. You must have two databases running, either both on the same host, or on different hosts.

 First, on the foreign database you create a table, for example:

 
```
CREATE TABLE test_table (
  id     int(20) NOT NULL auto_increment,
  name   varchar(32) NOT NULL default '',
  other  int(20) NOT NULL default '0',
  PRIMARY KEY  (id),
  KEY name (name),
  KEY other_key (other))
DEFAULT CHARSET=latin1;

```

Then, on the server that will be connecting to the foreign host (client), you create a federated table without specifying the table structure:

 
```
CREATE TABLE test_table ENGINE=FEDERATED 
  CONNECTION='mysql://root@127.0.0.1:9306/federatedx/test_federatedx';

```

Notice the "ENGINE" and "CONNECTION" fields? This is where you respectively set the engine type, "FEDERATED" and foreign host information, this being the database your 'client' database will connect to and use as the "data file". Obviously, the foreign database is running on port 9306, so you want to start up your other database so that it is indeed on port 9306, and your FederatedX database on a port other than that. In my setup, I use port 5554 for FederatedX, and port 5555 for the foreign database.

 Alternatively (or if you're using MariaDB before version 10.0.2) you specify the federated table structure explicitly:

 
```
CREATE TABLE test_table (
  id     int(20) NOT NULL auto_increment,
  name   varchar(32) NOT NULL default '',
  other  int(20) NOT NULL default '0',
  PRIMARY KEY  (id),
  KEY name (name),
  KEY other_key (other))
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:9306/federatedx/test_federatedx';

```

In this case the table structure must match exactly the table on the foreign server.

 ### How to see the storage engine in action

 When developing this handler, I compiled the FederatedX database with debugging:

 
```
./configure --with-federatedx-storage-engine \
  --prefix=/home/mysql/mysql-build/federatedx/ --with-debug

```

Once compiled, I did a 'make install' (not for the purpose of installing the binary, but to install all the files the binary expects to see in the directory I specified in the build with 

 
```
--prefix=/home/code-dev/maria

```

Then, I started the foreign server:

 
```
/usr/local/mysql/bin/mysqld_safe \
  --user=mysql --log=/tmp/mysqld.5555.log -P 5555

```

Then, I went back to the directory containing the newly compiled mysqld `<builddir>/sql/`, started up gdb:

 
```
gdb ./mysqld

```

Then, within the (gdb) prompt:

 
```
(gdb) run --gdb --port=5554 --socket=/tmp/mysqld.5554 --skip-innodb --debug

```

Next, I open several windows for each:

 1. Tail the debug trace: tail -f /tmp/mysqld.trace|grep ha\_fed
2. Tail the SQL calls to the foreign database: tail -f /tmp/mysqld.5555.log
3. A window with a client open to the federatedx server on port 5554
4. A window with a client open to the federatedx server on port 5555

 I would create a table on the client to the foreign server on port 5555, and then to the FederatedX server on port 5554. At this point, I would run whatever queries I wanted to on the FederatedX server, just always remembering that whatever changes I wanted to make on the table, or if I created new tables, that I would have to do that on the foreign server.

 Another thing to look for is 'show variables' to show you that you have support for FederatedX handler support:

 
```
show variables like '%federat%'

```

and:

 
```
show storage engines;

```

Both should display the federatedx storage handler.

 How do I create a federated server?
-----------------------------------

 A federated server is a way to have a foreign data source defined-- with all connection parameters-- so that you don't have to specify explicitly the connection parameters in a string.

 For instance, say if you wanted to create a table, t1, that you would specify with 

 
```
connection="mysql://patg@192.168.1.123/first_db/t1"

```

You could instead create this with a server:

 
```
create server 'server_one' foreign data wrapper 'mysql' options
  (HOST '192.168.1.123',		
  DATABASE 'first_db',		
  USER 'patg',
  PASSWORD '',
  PORT 3306,
  SOCKET '',		
  OWNER 'root');

```

You could now instead specify the server instead of the full URL connection string

 
```
connect="server_one"

```

How does FederatedX differ from the old Federated Engine?
---------------------------------------------------------

 FederatedX from a user point of view is the same for the most part. What is different with FederatedX and Federated is the following:

 * Rewrite of the main Federated source code from one single ha\_federated.cc file into three main abstracted components:
	+ ha\_federatedx.cc - Core implementation of FederatedX
	+ federated\_io.cc - Parent connection class to be over-ridden by derived classes for each RDBMS/client lib
	+ federatated\_io\_<driver>.cc - derived federated\_io class for a given RDBMS
	+ federated\_txn.cc - New support for using transactional engines on the foreign server using a connection poll
* Various bugs fixed (need to look at opened bugs for Federated)

 Where can I get FederatedX
--------------------------

 FederatedX is part of [MariaDB 5.1](../what-is-mariadb-51/index) and later. MariaDB merged with the latest FederatedX when there is a need to get a bug fixed. You can get the latest code/follow/participate in the project from the [FederatedX home page](http://launchpad.net/federatedx).

 ### What are the plans for FederatedX?

 * Support for other RDBMS vendors using ODBC
* Support for pushdown conditions
* Ability to limit result set sizes

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-federatedx/>

Differences Between FederatedX and Federated
============================================

    The main differences are:

 New features in FederatedX
--------------------------

 * Transactions (beta feature)
* Supports partitions (alpha feature)
* New class structure which allows developers to write connection classes for other RDBMSs without having to modify base classes for FederatedX

 Different behavior
------------------

 * FederatedX is statically compiled into MariaDB by default.
* When you create a table with FederatedX, the connection will be tested. The `CREATE` will fail if MariaDB can't connect to the remote host or if the remote table doesn't exist.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/differences-between-federatedx-and-federated/>

Stored Function Limitations
===========================

    The following restrictions apply to [stored functions](../stored-functions/index).

 * All of the restrictions listed in [Stored Routine Limitations](../stored-routine-limitations/index).
* Any statements that return a result set are not permitted. For example, a regular [SELECTs](../select/index) is not permitted, but a [SELECT INTO](../select-into/index) is. A cursor and [FETCH](../fetch/index) statement is permitted.
* [FLUSH](../flush/index) statements are not permitted.
* Statements that perform explicit or implicit commits or rollbacks are not permitted
* Cannot be used recursively.
* Cannot make changes to a table that is already in use (reading or writing) by the statement invoking the stored function.
* Cannot refer to a temporary table multiple times under different aliases, even in different statements.
* ROLLBACK TO SAVEPOINT and RELEASE SAVEPOINT statement which are in a stored function cannot refer to a savepoint which has been defined out of the current function.
* Prepared statements ([PREPARE](../prepare-statement/index), [EXECUTE](../execute-statement/index), [DEALLOCATE PREPARE](../deallocate-drop-prepared-statement/index)) cannot be used, and therefore nor can statements be constructed as strings and then executed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-function-limitations/>

Application-Time Periods
========================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Support for application-time period-versioning was added in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

 
Extending [system-versioned tables](../system-versioned-tables/index), [MariaDB 10.4](../what-is-mariadb-104/index) supports application-time period tables. Time periods are defined by a range between two temporal columns. The columns must be of the same [temporal data type](../date-and-time-data-types/index), i.e. [DATE](../date/index), [TIMESTAMP](../timestamp/index) or [DATETIME](../datetime/index) ([TIME](../time/index) and [YEAR](../year-data-type/index) are not supported), and of the same width. 

 Using time periods implicitly defines the two columns as `NOT NULL`. It also adds a constraint to check whether the first value is less than the second value. The constraint is invisible to [SHOW CREATE TABLE](../show-create-table/index) statements. The name of this constraint is prefixed by the time period name, to avoid conflict with other constraints. 

 ### Creating Tables with Time Periods

 To create a table with a time period, use a [CREATE TABLE](../create-table/index) statement with the `PERIOD` table option.

 
```
CREATE TABLE t1(
   name VARCHAR(50), 
   date_1 DATE,
   date_2 DATE,
   PERIOD FOR date_period(date_1, date_2));


```

This creates a table with a `time_period` period and populates the table with some basic temporal values.

 Examples are available in the MariaDB Server source code, at `mysql-test/suite/period/r/create.result`.

 ### Adding and Removing Time Periods

 The [ALTER TABLE](../alter-table/index) statement now supports syntax for adding and removing time periods from a table. To add a period, use the `ADD PERIOD` clause.

 For example:

 
```
CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE
 );

ALTER TABLE rooms ADD PERIOD FOR p(checkin,checkout);

```

To remove a period, use the `DROP PERIOD` clause:

 
```
ALTER TABLE rooms DROP PERIOD FOR p;

```

Both `ADD PERIOD` and `DROP PERIOD` clauses include an option to handle whether the period already exists:

 
```
ALTER TABLE rooms ADD PERIOD IF NOT EXISTS FOR p(checkin,checkout);

ALTER TABLE rooms DROP PERIOD IF EXISTS FOR p;

```

### Deletion by Portion

 You can also remove rows that fall within certain time periods.

 When MariaDB executes a `DELETE FOR PORTION` statement, it removes the row:

 * When the row period falls completely within the delete period, it removes the row.
* When the row period overlaps the delete period, it shrinks the row, removing the overlap from the first or second row period value.
* When the delete period falls completely within the row period, it splits the row into two rows. The first row runs from the starting row period to the starting delete period. The second runs from the ending delete period to the ending row period.

 To test this, first populate the table with some data to operate on:

 
```
CREATE TABLE t1(
   name VARCHAR(50), 
   date_1 DATE,
   date_2 DATE,
   PERIOD FOR date_period(date_1, date_2));

INSERT INTO t1 (name, date_1, date_2) VALUES
    ('a', '1999-01-01', '2000-01-01'),
    ('b', '1999-01-01', '2018-12-12'),
    ('c', '1999-01-01', '2017-01-01'),
    ('d', '2017-01-01', '2019-01-01');

SELECT * FROM t1;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2017-01-01 |
| d    | 2017-01-01 | 2019-01-01 |
+------+------------+------------+

```

Then, run the `DELETE FOR PORTION` statement:

 
```
DELETE FROM t1
FOR PORTION OF date_period
    FROM '2001-01-01' TO '2018-01-01';
Query OK, 3 rows affected (0.028 sec)

SELECT * FROM t1 ORDER BY name;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2001-01-01 |
| b    | 2018-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2001-01-01 |
| d    | 2018-01-01 | 2019-01-01 |
+------+------------+------------+

```

Here:

 * *a* is unchanged, as the range falls entirely out of the specified portion to be deleted.
* *b*, with values ranging from 1999 to 2018, is split into two rows, 1999 to 2000 and 2018-01 to 2018-12.
* *c*, with values ranging from 1999 to 2017, where only the upper value falls within the portion to be deleted, has been shrunk to 1999 to 2001.
* *d*, with values ranging from 2017 to 2019, where only the lower value falls within the portion to be deleted, has been shrunk to 2018 to 2019.

 The `DELETE FOR PORTION` statement has the following restrictions

 * The `FROM...TO` clause must be constant
* Multi-delete is not supported

 
If there are `DELETE` or `INSERT` triggers, it works as follows: any matched row is deleted, and then one or two rows are inserted. If the record is deleted completely, nothing is inserted. 

 
### Updating by Portion

 The [UPDATE](../update/index) syntax now supports `UPDATE FOR PORTION`, which modifies rows based on their occurrence in a range:

 To test it, first populate the table with some data:

 
```
TRUNCATE t1;

INSERT INTO t1 (name, date_1, date_2) VALUES
    ('a', '1999-01-01', '2000-01-01'),
    ('b', '1999-01-01', '2018-12-12'),
    ('c', '1999-01-01', '2017-01-01'),
    ('d', '2017-01-01', '2019-01-01');

SELECT * FROM t1;
+------+------------+------------+
| name | date_1     | date_2     |
+------+------------+------------+
| a    | 1999-01-01 | 2000-01-01 |
| b    | 1999-01-01 | 2018-12-12 |
| c    | 1999-01-01 | 2017-01-01 |
| d    | 2017-01-01 | 2019-01-01 |
+------+------------+------------+

```

Then run the update:

 
```
UPDATE t1 FOR PORTION OF date_period
  FROM '2000-01-01' TO '2018-01-01' 
SET name = CONCAT(name,'_original');

SELECT * FROM t1 ORDER BY name;
+------------+------------+------------+
| name       | date_1     | date_2     |
+------------+------------+------------+
| a          | 1999-01-01 | 2000-01-01 |
| b          | 1999-01-01 | 2000-01-01 |
| b          | 2018-01-01 | 2018-12-12 |
| b_original | 2000-01-01 | 2018-01-01 |
| c          | 1999-01-01 | 2000-01-01 |
| c_original | 2000-01-01 | 2017-01-01 |
| d          | 2018-01-01 | 2019-01-01 |
| d_original | 2017-01-01 | 2018-01-01 |
+------------+------------+------------+

```

* *a* is unchanged, as the range falls entirely out of the specified portion to be deleted.
* *b*, with values ranging from 1999 to 2018, is split into two rows, 1999 to 2000 and 2018-01 to 2018-12.
* *c*, with values ranging from 1999 to 2017, where only the upper value falls within the portion to be deleted, has been shrunk to 1999 to 2001.
* *d*, with values ranging from 2017 to 2019, where only the lower value falls within the portion to be deleted, has been shrunk to 2018 to 2019.
* Original rows affected by the update have "\_original" appended to the name.

 The `UPDATE FOR PORTION` statement has the following limitations:

 * The operation cannot modify the two temporal columns used by the time period
* The operation cannot reference period values in the `SET` expression
* `FROM...TO` expressions must be constant

 ### WITHOUT OVERLAPS

 
**MariaDB starting with [10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/)**[MariaDB 10.5](../what-is-mariadb-105/index) introduced a new clause, `WITHOUT OVERLAPS`, which allows one to create an index specifying that application time periods should not overlap.

 An index constrained by `WITHOUT OVERLAPS` is required to be either a primary key or a unique index.

 
Take the following example, an application time period table for a booking system:

 
```
CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE,
 PERIOD FOR p(checkin,checkout)
 );

INSERT INTO rooms VALUES 
 (1, 'Regina', '2020-10-01', '2020-10-03'),
 (2, 'Cochise', '2020-10-02', '2020-10-05'),
 (1, 'Nowell', '2020-10-03', '2020-10-07'),
 (2, 'Eusebius', '2020-10-04', '2020-10-06');

```

Our system is not intended to permit overlapping bookings, so the fourth record above should not have been inserted. Using `WITHOUT OVERLAPS` in a unique index (in this case based on a combination of room number and the application time period) allows us to specify this constraint in the table definition.

 
```
CREATE OR REPLACE TABLE rooms (
 room_number INT,
 guest_name VARCHAR(255),
 checkin DATE,
 checkout DATE,
 PERIOD FOR p(checkin,checkout),
 UNIQUE (room_number, p WITHOUT OVERLAPS)
 );

INSERT INTO rooms VALUES 
 (1, 'Regina', '2020-10-01', '2020-10-03'),
 (2, 'Cochise', '2020-10-02', '2020-10-05'),
 (1, 'Nowell', '2020-10-03', '2020-10-07'),
 (2, 'Eusebius', '2020-10-04', '2020-10-06');
ERROR 1062 (23000): Duplicate entry '2-2020-10-06-2020-10-04' for key 'room_number'

```

### Further Examples

 The implicit change from NULL to NOT NULL:

 
```
CREATE TABLE `t2` (
  `id` int(11) DEFAULT NULL,
  `d1` datetime DEFAULT NULL,
  `d2` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE t2 ADD PERIOD FOR p(d1,d2);

SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `id` int(11) DEFAULT NULL,
  `d1` datetime NOT NULL,
  `d2` datetime NOT NULL,
  PERIOD FOR `p` (`d1`, `d2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

```

Due to this constraint, trying to add a time period where null data already exists will fail.

 
```
CREATE OR REPLACE TABLE `t2` (
  `id` int(11) DEFAULT NULL,
  `d1` datetime DEFAULT NULL,
  `d2` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO t2(id) VALUES(1);

ALTER TABLE t2 ADD PERIOD FOR p(d1,d2);
ERROR 1265 (01000): Data truncated for column 'd1' at row 1

```

### See Also

 * [System-versioned Tables](../system-versioned-tables/index)
* [Bitemporal Tables](../bitemporal-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/application-time-periods/>

SHOW CREATE TRIGGER
===================

    Syntax
------

 
```
SHOW CREATE TRIGGER trigger_name

```
 Description
-----------

 This statement shows a `[CREATE TRIGGER](../create-trigger/index)` statement that creates the given trigger, as well as the `[SQL\_MODE](../sql-mode/index)` that was used when the trigger has been created and the character set used by the connection.

 The `[TRIGGER](../grant/index#table-privileges)` privilege is required on the table the trigger is defined for to execute this statement.

 The output of this statement is unreliably affected by the `[sql\_quote\_show\_create](../server-system-variables/index#sql_quote_show_create)` server system variable - see <http://bugs.mysql.com/bug.php?id=12719>

 Examples
--------

 
```
SHOW CREATE TRIGGER example\G
*************************** 1. row ***************************
               Trigger: example
              sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,STRICT_ALL_TABLES
,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_
ENGINE_SUBSTITUTION
SQL Original Statement: CREATE DEFINER=`root`@`localhost` TRIGGER example BEFORE
 INSERT ON t FOR EACH ROW
BEGIN
        SET NEW.c = NEW.c * 2;
END
  character_set_client: cp850
  collation_connection: cp850_general_ci
  Database Collation: utf8_general_ci
  Created: 2016-09-29 13:53:34.35

```


**MariaDB starting with [10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)**The `Created` column was added in MySQL 5.7 and [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) as part of introducing multiple trigger events per action.

 
See also
--------

 * [Trigger Overview](../trigger-overview/index)
* `[CREATE TRIGGER](../create-trigger/index)`
* `[DROP TRIGGER](../drop-trigger/index)`
* `[information\_schema.TRIGGERS Table](../information-schema-triggers-table/index)`
* `[SHOW TRIGGERS](../show-triggers/index)`
* [Trigger Limitations](../trigger-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-trigger/>

Upgrading from MariaDB Galera Cluster 10.0 to MariaDB 10.1 with Galera Cluster
==============================================================================

    
**MariaDB starting with [10.1](../what-is-mariadb-101/index)**Since [MariaDB 10.1](../what-is-mariadb-101/index), the [MySQL-wsrep](https://github.com/codership/mysql-wsrep) patch has been merged into MariaDB Server. Therefore, in [MariaDB 10.1](../what-is-mariadb-101/index) and above, the functionality of MariaDB Galera Cluster can be obtained by installing the standard MariaDB Server packages and the Galera wsrep provider library package.

 
Performing a Rolling Upgrade
----------------------------

 The following steps can be used to perform a rolling upgrade from MariaDB Galera Cluster 10.0 to [MariaDB 10.1](../what-is-mariadb-101/index). In a rolling upgrade, each node is upgraded individually, so the cluster is always operational. There is no downtime from the application's perspective.

 First, before you get started:

 1. First, take a look at [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-101/index) to see what has changed between the major versions.
	1. Check whether any system variables or options have been changed or removed. Make sure that your server's configuration is compatible with the new MariaDB version before upgrading.
	2. Check whether replication has changed in the new MariaDB version in any way that could cause issues while the cluster contains upgraded and non-upgraded nodes.
	3. Check whether any new features have been added to the new MariaDB version. If a new feature in the new MariaDB version cannot be replicated to the old MariaDB version, then do not use that feature until all cluster nodes have been upgrades to the new MariaDB version.
2. Next, make sure that the Galera version numbers are compatible.
	1. If you are upgrading from the most recent MariaDB Galera Cluster 10.0 release to [MariaDB 10.1](../what-is-mariadb-101/index), then the versions will be compatible. The latest releases of MariaDB Galera Cluster 10.0 and all releases of [MariaDB 10.1](../what-is-mariadb-101/index) use Galera 3 (i.e. Galera wsrep provider versions 25.3.x), so they should be compatible.
	2. If you are running an older MariaDB Galera Cluster 10.0 release that still uses Galera 2 (i.e. Galera wsrep provider versions 25.2.x), then it is recommended to first upgrade to the latest MariaDB Galera Cluster 10.0 release that uses Galera 3 (i.e. Galera wsrep provider versions 25.3.x).
	3. See [What is MariaDB Galera Cluster?: Galera wsrep provider Versions](../what-is-mariadb-galera-cluster/index#galera-wsrep-provider-versions) for information on which MariaDB releases uses which Galera wsrep provider versions.
3. Ideally, you want to have a large enough gcache to avoid a [State Snapshot Transfer (SST)](../introduction-to-state-snapshot-transfers-ssts/index) during the rolling upgrade. The gcache size can be configured by setting `[gcache.size](../wsrep_provider_options/index#gcachesize)` For example:   
 `wsrep_provider_options="gcache.size=2G"`

 
Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index).

  Then, for each node, perform the following steps:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.1](../what-is-mariadb-101/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. If you use a load balancing proxy such as MaxScale or HAProxy, make sure to drain the server from the pool so it does not receive any new connections.
3. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
4. [Stop MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
5. Uninstall the old version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-galera-server galera`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-Galera-server galera`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-Galera-server galera`
6. Install the new version of MariaDB and the Galera wsrep provider.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
7. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any system variables or options that are no longer supported.
	* It is important to note that a new option is needed for Galera to be active in [MariaDB 10.1](../what-is-mariadb-101/index): you must set `[wsrep\_on=ON](../galera-cluster-system-variables/index#wsrep_on)`.
8. On Linux distributions that use `systemd` you may need to increase the service startup timeout as the default timeout of 90 seconds may not be sufficient. See [Systemd: Configuring the Systemd Service Timeout](../systemd/index#configuring-the-systemd-service-timeout) for more information.
9. [Start MariaDB](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index).
10. Run `[mysql\_upgrade](../mysql_upgrade/index)` with the `--skip-write-binlog` option.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 When this process is done for one node, move onto the next node.

 
Note that when upgrading the Galera wsrep provider, sometimes the Galera protocol version can change. The Galera wsrep provider should not start using the new protocol version until all cluster nodes have been upgraded to the new version, so this is not generally an issue during a rolling upgrade. However, this can cause issues if you restart a non-upgraded node in a cluster where the rest of the nodes have been upgraded.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-galera-cluster-upgrading-from-mariadb-galera-cluster-100-to-maria/>

Bitemporal Tables
=================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Bitemporal tables are tables that use versioning both at the [system](../system-versioned-tables/index) and [application-time period](../application-time-periods/index) levels. 

  Using Bitemporal Tables
-----------------------

 To create a bitemporal table, use:

 
```
CREATE TABLE test.t3 (
   date_1 DATE,
   date_2 DATE,
   row_start TIMESTAMP(6) AS ROW START INVISIBLE,
   row_end TIMESTAMP(6) AS ROW END INVISIBLE,
   PERIOD FOR application_time(date_1, date_2),
   PERIOD FOR system_time(row_start, row_end))
WITH SYSTEM VERSIONING;

```

Note that, while `system_time` here is also a time period, it cannot be used in `DELETE FOR PORTION` or `UPDATE FOR PORTION` statements.

 
```
DELETE FROM test.t3 
FOR PORTION OF system_time 
    FROM '2000-01-01' TO '2018-01-01';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds 
  to your MariaDB server version for the right syntax to use near
  'of system_time from '2000-01-01' to '2018-01-01'' at line 1

```

See Also
--------

 * [System-versioned Tables](../system-versioned-tables/index)
* [Application-time Periods](../application-time-periods/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bitemporal-tables/>

Information Schema TRIGGERS Table
=================================

     The [Information Schema](../information_schema/index) `TRIGGERS` table contains information about [triggers](../triggers/index).

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TRIGGER_CATALOG` | Always `def`. |
| `TRIGGER_SCHEMA` | Database name in which the trigger occurs. |
| `TRIGGER_NAME` | Name of the trigger. |
| `EVENT_MANIPULATION` | The event that activates the trigger. One of `INSERT`, `UPDATE` or `'DELETE`. |
| `EVENT_OBJECT_CATALOG` | Always `def`. |
| `EVENT_OBJECT_SCHEMA` | Database name on which the trigger acts. |
| `EVENT_OBJECT_TABLE` | Table name on which the trigger acts. |
| `ACTION_ORDER` | Indicates the order that the action will be performed in (of the list of a table's triggers with identical `EVENT_MANIPULATION` and `ACTION_TIMING` values). Before [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) introduced the [FOLLOWS and PRECEDES clauses](../create-trigger/index#followsprecedes-other_trigger_name), always `0` |
| `ACTION_CONDITION` | `NULL` |
| `ACTION_STATEMENT` | Trigger body, UTF-8 encoded. |
| `ACTION_ORIENTATION` | Always `ROW`. |
| `ACTION_TIMING` | Whether the trigger acts `BEFORE` or `AFTER` the event that triggers it. |
| `ACTION_REFERENCE_OLD_TABLE` | Always `NULL`. |
| `ACTION_REFERENCE_NEW_TABLE` | Always `NULL`. |
| `ACTION_REFERENCE_OLD_ROW` | Always `OLD`. |
| `ACTION_REFERENCE_NEW_ROW` | Always `NEW`. |
| `CREATED` | Always `NULL`. |
| `SQL_MODE` | The `[SQL\_MODE](../sql-mode/index)` when the trigger was created, and which it uses for execution. |
| `DEFINER` | The account that created the trigger, in the form `user_name@host_name` |
| `CHARACTER_SET_CLIENT` | The client [character set](../data-types-character-sets-and-collations/index) when the trigger was created, from the session value of the `[character\_set\_client](../server-system-variables/index#character_set_client)` system variable. |
| `COLLATION_CONNECTION` | The client [collation](../data-types-character-sets-and-collations/index) when the trigger was created, from the session value of the [collation\_connection](../server-system-variables/index#collation_connection) system variable. |
| `DATABASE_COLLATION` | [Collation](../data-types-character-sets-and-collations/index) of the associated database. |

 
Queries to the `TRIGGERS` table will return information only for databases and tables for which you have the `TRIGGER` [privilege](../grant/index#table-privileges). Similar information is returned by the `[SHOW TRIGGERS](../show-triggers/index)` statement.

 See also
--------

 * [Trigger Overview](../trigger-overview/index)
* `[CREATE TRIGGER](../create-trigger/index)`
* `[DROP TRIGGER](../drop-trigger/index)`
* `[SHOW TRIGGERS](../show-triggers/index)`
* `[SHOW CREATE TRIGGER](../show-create-trigger/index)`
* [Trigger Limitations](../trigger-limitations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-triggers-table/>

CREATE TABLESPACE
=================

    
The `CREATE TABLESPACE` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See [MDEV-19294](https://jira.mariadb.org/browse/MDEV-19294) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-tablespace/>

Information Schema CHANGED\_PAGE\_BITMAPS Table
===============================================

    
**MariaDB starting with [10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/)**The`CHANGED_PAGE_BITMAPS` table was added in [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/).

 
The [Information Schema](../information_schema/index) `CHANGED_PAGE_BITMAPS` table is a dummy table added to [XtraDB](../xtradb/index) with reset\_table callback to allow `FLUSH NO_WRITE_TO_BINLOG CHANGED_PAGE_BITMAPS` to be called from `innobackupex`. It contains only one column, *dummy*. 

 For more information, see [MDEV-7472](https://jira.mariadb.org/browse/MDEV-7472).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-changed_page_bitmaps-table/>

InnoDB System Tablespaces
=========================

     When InnoDB needs to store general information relating to the system as a whole, rather than a specific table, the specific file it writes to is the system tablespace. By default, this is the `ibdata1` file located in the data directory, (as defined by either the `[datadir](../server-system-variables/index#datadir)` or `[innodb\_data\_home\_dir](../innodb-system-variables/index#innodb_data_home_dir)` system variables). InnoDB uses the system tablespace to store the data dictionary, change buffer, and undo logs.

 You can define the system tablespace filename or filenames, size and other options by setting the `[innodb\_data\_file\_path](../innodb-system-variables/index#innodb_data_file_path)` system variable. This system variable can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_data_file_path=ibdata1:50M:autoextend

```

This system variable defaults to the file `ibdata1`, and it defaults to a minimum size of `12M`, and it defaults with the `autoextend` attribute enabled.

 Changing Sizes
--------------

 InnoDB defaults to allocating 12M to the `ibdata1` file for the system tablespace. While this is sufficient for most use cases, it may not be for all. You may find after using MariaDB for a while that the allocation is too small for the system tablespace or it grows too large for your disk. Fortunately, you can adjust this size as need later.

 ### Increasing the Size

 When setting the `[innodb\_data\_file\_path](../innodb-system-variables/index#innodb_data_file_path)` system variable, you can define a size for each file given. In cases where you need a larger system tablespace, add the `autoextend` option to the last value.

 
```
[mariadb]
...
innodb_data_file_path=ibdata1:12M;ibdata2:50M:autoextend

```

Under this configuration, when the last system tablespace grows beyond the size allocation, InnoDB increases the size of the file by increments. To control the allocation increment, set the `[innodb\_autoextend\_increment](../innodb-system-variables/index#innodb_autoextend_increment)` system variable.

 ### Decreasing the Size

 
**MariaDB starting with [11.2.0](https://mariadb.com/kb/en/mariadb-1120-release-notes/)**From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), when MariaDB starts up, unused InnoDB tablespace is reclaimed, reducing the file size ([MDEV-14795](https://jira.mariadb.org/browse/MDEV-14795)).

 Technically, how this works is:

 1. Find the last used extent in the system tablespace by iterating through the BITMAP in the extent descriptor page.
2. Check whether the tablespace is being used within fixed size, and if the last used extent is less than the fixed size, then set the desired target size to fixed size.
3. Flush all pages belonging to the system tablespace in flush list.
4. Truncate the truncated pages from FSP\_FREE and FSP\_FREE\_FRAG list.
5. Reset the bitmap in descriptor pages for the truncated pages.
6. Update the FSP\_SIZE and FSP\_FREE\_LIMIT in header page.
7. In case of multiple files, calculate the truncated last file size and do the truncation in last file.

 

**MariaDB until [11.2.0](https://mariadb.com/kb/en/mariadb-1120-release-notes/)**In cases where the InnoDB system tablespace has grown too large, before [MariaDB 11.2](../what-is-mariadb-112/index), the process to reduce it in size is a little more complicated than increasing the size. MariaDB does not allow you to remove data from the tablespace file itself. Instead you need to delete the tablespace files themselves, then restore the database from backups.

 The backup utility [mariadb-dump](../mariadb-dump/index) produces backup files containing the SQL statements needed to recreate the database. As a result, it restores a database with the bare minimum data rather than any additional information that might have built up in the tablespace file.

 Use mariadb-dump to backup all of your InnoDB database tables, including the system tables in the `mysql` database that use InnoDB. You can find out what they are using the Information Schema.

 
```
SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mysql' AND ENGINE = 'InnoDB';

```

If you only use InnoDB, you may find it easier to back up all databases and tables.

 
```
$ mariadb-dump -u root -p --all-databases > full-backup.sql

```

Then stop the MariaDB Server and remove the InnoDB tablespace files. In the data directory or the InnoDB data home directory, delete all the `ibdata` and `ib_log` files as well as any file with an `.ibd` or `.frm` extension.

 Once this is done, restart the server and import the dump file:

 
```
$ mysql -u root -p < full-backup.sql

```


Using Raw Disk Partitions
-------------------------

 Instead of having InnoDB write to the file system, you can set it to use raw disk partitions. On Windows and some Linux distributions, this allows you to perform non-buffered I/O without the file system overhead. Note that in many use cases this may not actually improve performance. Run tests to verify if there are any real gains for your application usage.

 To enable a raw disk partition, first start MariaDB with the `newraw` option set on the tablespace. For example:

 
```
[mariadb]
...
innodb_data_file_path=/dev/sdc:10Gnewraw

```

When the MariaDB Server starts, it initializes the partition. Don't create or change any data, (any data written to InnoDB at this stage will be lost on restart). Once the server has successful started, stop it then edit the configuration file again, changing the `newraw` keyword to `raw`.

 
```
[mariadb]
...
innodb_data_file_path=/dev/sdc:10Graw

```

When you start MariaDB again, it'll read and write InnoDB data to the given disk partition instead of the file system.

 ### Raw Disk Partitions on Windows

 When defining a raw disk partition for InnoDB on the Windows operating system, use the same procedure as defined above, but when defining the path for the `[innodb\_data\_file\_path](../innodb-system-variables/index#innodb_data_file_path)` system variable, use `*./*` at the start. For example:

 
```
[mariadb]
...
innodb_data_file_path=//./E::10Graw

```

The given path is synonymous with the Windows syntax for accessing the physical drive.

 System Tables within the InnoDB System Tablespace
-------------------------------------------------

 InnoDB creates some system tables within the InnoDB System Tablespace:

 * `SYS_DATAFILES`
* `SYS_FOREIGN`
* `SYS_FOREIGN_COLS`
* `SYS_TABLESPACES`
* `SYS_VIRTUAL`
* `SYS_ZIP_DICT`
* `SYS_ZIP_DICT_COLS`

 These tables cannot be queried. However, you might see references to them in some places, such as in the [INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table in the [information\_schema](../information-schema-tables/index) database.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-system-tablespaces/>

Performance of MEMORY Tables
============================

    Between [MariaDB 5.5.21](https://mariadb.com/kb/en/mariadb-5521-release-notes/) and 5.5.22 some work was done on how the hash index for a [MEMORY](../memory-storage-engine/index) table is created. This results in better performance when inserting rows into a memory table.

 The following benchmark compares MariaDB-5.5.21 and 5.5.25. Compiled with identical settings on the same machine. The operation was loading 50 million rows into a MEMORY table with LOAD DATA INFILE. 

 Two different tables were tested: one with an indexed INT column and one with an indexed CHAR(20) column. The data files were pre-generated and located on a SSD. In order to make the effect visible, the cpu speed was set to minimum (core I5 @ 800Mhz)

 Result:

 


| Table Type | MariaDB Version | rows per second | Percent |
| --- | --- | --- | --- |
| INT | 5.5.21 | 411022 | 100% |
|  | 5.5.25 | 510016 | 124% |
| CHAR(20) | 5.5.21 | 259399 | 100% |
|  | 5.5.25 | 411535 | 159% |

 
This is how the benchmark was run:

 

```

MariaDB [test]> tee 5.5.21.txt
MariaDB [test]> set @instance="5.5.21";
MariaDB [test]> source bench.sql

```
 
The script used to generate the data files:

 
```
#!/usr/bin/perl -w                                                              
                                                                                
$ROWS=50*1024*1024;                                                             

open F, ">/tmp/hash1.txt" or die;                                               
for ($i=0; $i<$ROWS; $i++) {                                                    
    printf F "%d\n", int(rand($ROWS));                                          
}                                                                               
close F or die;                                                                 
                                                                                
open F, ">/tmp/hash2.txt" or die;                                               
for ($i=0; $i<$ROWS; $i++) {                                                    
    $s="";                                                                      
    for (1..20) { $s .= chr(ord('a')+int(rand(26))); }                          
    print F $s, "\n";                                                           
}                                                                               
close F or die;

```

The benchmark SQL script bench.sql:

 
```
use test;                                                                       
                                                                                
-- need big heap tables                                                         
set max_heap_table_size=4*1024*1024*1024;                                       
                                                                                
-- table to hold test results                                                   
create table if not exists results (                                            
  id serial,                                                                    
  operation char(32),                                                           
  opsize bigint unsigned,                                                       
  started datetime,                                                             
  ended datetime,                                                               
  instance char(20)                                                             
);                                                                              
                                                                                
-- dummy run with second data file                                              
drop table if exists t1;                                                        
create table t1 (c1 char(20), index (c1)) engine memory;                        
load data infile "/tmp/hash2.txt" into table t1;                                
drop table t1;                                                                  
                                                                                
-- do total of 5 runs for each table                                            
                                                                                
-- run #1                                                                       
create table t1 (c1 int, index (c1)) engine memory;                             
select @t1:=now();                                                              
load data infile "/tmp/hash1.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into INT table", @rows, @t1, @t2, @instance);                     
drop table t1;                                                                  
                                                                                
create table t1 (c1 char(20), index (c1)) engine memory;                        
select @t1:=now();                                                              
load data infile "/tmp/hash2.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into CHAR(20) table", @rows, @t1, @t2, @instance);                
drop table t1;                                                                  
                                                                                
-- run #2                                                                       
create table t1 (c1 int, index (c1)) engine memory;                             
select @t1:=now();                                                              
load data infile "/tmp/hash1.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into INT table", @rows, @t1, @t2, @instance);                     
drop table t1;                                                                  
                                                                                
create table t1 (c1 char(20), index (c1)) engine memory;                        
select @t1:=now();                                                              
load data infile "/tmp/hash2.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into CHAR(20) table", @rows, @t1, @t2, @instance);                
drop table t1;                                                                  
                                                                                
-- run #3                                                                       
create table t1 (c1 int, index (c1)) engine memory;                             
select @t1:=now();                                                              
load data infile "/tmp/hash1.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into INT table", @rows, @t1, @t2, @instance);                     
drop table t1;                                                                  
                                                                                
create table t1 (c1 char(20), index (c1)) engine memory;                        
select @t1:=now();                                                              
load data infile "/tmp/hash2.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into CHAR(20) table", @rows, @t1, @t2, @instance);                
drop table t1;                                                                  
                                                                                
-- run #4                                                                       
create table t1 (c1 int, index (c1)) engine memory;                             
select @t1:=now();                                                              
load data infile "/tmp/hash1.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into INT table", @rows, @t1, @t2, @instance);                     
drop table t1;                                                                  
                                                                                
create table t1 (c1 char(20), index (c1)) engine memory;                        
select @t1:=now();                                                              
load data infile "/tmp/hash2.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into CHAR(20) table", @rows, @t1, @t2, @instance);                
drop table t1;                                                                  
                                                                                
-- run #5                                                                       
create table t1 (c1 int, index (c1)) engine memory;                             
select @t1:=now();                                                              
load data infile "/tmp/hash1.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into INT table", @rows, @t1, @t2, @instance);                     
show table status like 't1';                                                    
drop table t1;                                                                  
                                                                                
create table t1 (c1 char(20), index (c1)) engine memory;                        
select @t1:=now();                                                              
load data infile "/tmp/hash2.txt" into table t1;                                
select @t2:=now();                                                              
select @rows:=count(*) from t1;                                                 
insert into results (operation, opsize, started, ended, instance)               
values ("load into CHAR(20) table", @rows, @t1, @t2, @instance);                
show table status like 't1';                                                    
drop table t1;                                                                  

-- list all results                                                             
select operation, instance, unix_timestamp(ended)-unix_timestamp(started) as duration,                                                                          
 opsize/(unix_timestamp(ended)-unix_timestamp(started)) as ops_per_sec          
from results order by operation, instance, started;                             
                                                                                
-- list average results                                                         
select operation, instance, avg(opsize/(unix_timestamp(ended)-unix_timestamp(started))) as avg_ops_per_sec                                                      
from results group by operation, instance;                                      

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-of-memory-tables/>

InnoDB Temporary Tablespaces
============================

    
**MariaDB starting with [10.2](../what-is-mariadb-102/index)**The use of the temporary tablespaces in InnoDB was introduced in [MariaDB 10.2](../what-is-mariadb-102/index). In earlier versions, temporary tablespaces exist as part of the InnoDB [system](../innodb-system-tablespaces/index) tablespace or were file-per-table depending on the configuration of the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable.

 
When the user creates a temporary table using the [CREATE TEMPORARY TABLE](../create-table/index) statement and the engine is set as InnoDB, MariaDB creates a temporary tablespace file. When the table is not compressed, MariaDB writes to a shared temporary tablespace as defined by the [innodb\_temp\_data\_file\_path](../innodb-system-variables/index#innodb_temp_data_file_path) system variable. MariaDB does not allow the creation of ROW\_FORMAT=COMPRESSED temporary tables. All temporary tables will be uncompressed. MariaDB deletes temporary tablespaces when the server shuts down gracefully and is recreated when it starts again. It cannot be placed on a raw device.

 Internal temporary tablespaces, (that is, temporary tables that cannot be kept in memory) use either Aria or MyISAM, depending on the [aria\_used\_for\_temp\_tables](../aria-system-variables/index#aria_used_for_temp_tables) system variable. You can set the default storage engine for user-created temporary tables using the [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine) system variable.

 Sizing Temporary Tablespaces
----------------------------

 In order to size temporary tablespaces, use the [innodb\_temp\_data\_file\_path](../innodb-system-variables/index#innodb_temp_data_file_path) system variable. This system variable can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_temp_data_file_path=ibtmp1:32M:autoextend

```

This system variable's syntax is the same as the [innodb\_data\_file\_path](../innodb-system-variables/index#innodb_data-_file_path) system variable. That is, a file name, size and option. By default, it writes a 12MB autoextending file to `ibtmp1` in the data directory.

 To increase the size of the temporary tablespace, you can add a path to an additional tablespace file to the value of the the [innodb\_temp\_data\_file\_path](../innodb-system-variables/index#innodb_temp_data_file_path) system variable. Providing additional paths allows you to spread the temporary tablespace between multiple tablespace files. The last file can have the `autoextend` attribute, which ensures that you won't run out of space. For example:

 
```
[mariadb]
...
innodb_temp_data_file_path=ibtmp1:32M;ibtmp2:32M:autoextend

```

Unlike normal tablespaces, temporary tablespaces are deleted when you stop MariaDB. To shrink temporary tablespaces to their minimum sizes, restart the server.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-temporary-tablespaces/>

InnoDB Online DDL Overview
==========================

    InnoDB tables support online DDL, which permits concurrent DML and uses optimizations to avoid unnecessary table copying.

 The [ALTER TABLE](../alter-table/index) statement supports two clauses that are used to implement online DDL:

 * [ALGORITHM](../alter-table/index#algorithm) - This clause controls how the DDL operation is performed.
* [LOCK](../alter-table/index#lock) - This clause controls how much concurrency is allowed while the DDL operation is being performed.

 Alter Algorithms
----------------

 InnoDB supports multiple algorithms for performing DDL operations. This offers a significant performance improvement over previous versions. The supported algorithms are:

 * `DEFAULT` - This implies the default behavior for the specific operation.
* `COPY`
* `INPLACE`
* `NOCOPY` - This was added in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).
* `INSTANT` - This was added in [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/).

 Specifying an Alter Algorithm
-----------------------------

 The set of alter algorithms can be considered as a hierarchy. The hierarchy is ranked in the following order, with *least efficient* algorithm at the top, and *most efficient* algorithm at the bottom:

 * `COPY`
* `INPLACE`
* `NOCOPY`
* `INSTANT`

 When a user specifies an alter algorithm for a DDL operation, MariaDB does not necessarily use that specific algorithm for the operation. It interprets the choice in the following way:

 * If the user specifies `COPY`, then InnoDB uses the `COPY` algorithm.
* If the user specifies any other algorithm, then InnoDB interprets that choice as the *least efficient* algorithm that the user is willing to accept. This means that if the user specifies `INPLACE`, then InnoDB will use the *most efficient* algorithm supported by the specific operation from the set (`INPLACE`, `NOCOPY`, `INSTANT`). Likewise, if the user specifies `NOCOPY`, then InnoDB will use the *most efficient* algorithm supported by the specific operation from the set (`NOCOPY`, `INSTANT`).

 There is also a special value that can be specified:

 * If the user specifies `DEFAULT`, then InnoDB uses its default choice for the operation. The default choice is to use the most efficient algorithm supported by the operation. The default choice will also be used if no algorithm is specified. Therefore, if you want InnoDB to use the most efficient algorithm supported by an operation, then you usually do not have to explicitly specify any algorithm at all.

 ### Specifying an Alter Algorithm Using the ALGORITHM Clause

 InnoDB supports the [ALGORITHM](../alter-table/index#algorithm) clause.

 The [ALGORITHM](../alter-table/index#algorithm) clause can be used to specify the *least efficient* algorithm that the user is willing to accept. It is supported by the [ALTER TABLE](../alter-table/index) and [CREATE INDEX](../create-index/index) statements.

 For example, if a user wanted to add a column to a table, but only if the operation used an algorithm that is at least as efficient as the `INPLACE`, then they could execute the following:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

ALTER TABLE tab ADD COLUMN c varchar(50), ALGORITHM=INPLACE;

```

In [MariaDB 10.3](../what-is-mariadb-103/index) and later, the above operation would actually use the `INSTANT` algorithm, because the `ADD COLUMN` operation supports the `INSTANT` algorithm, and the `INSTANT` algorithm is more efficient than the `INPLACE` algorithm.

 ### Specifying an Alter Algorithm Using System Variables

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and later, the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable can be used to pick the *least efficient* algorithm that the user is willing to accept.

 For example, if a user wanted to add a column to a table, but only if the operation used an algorithm that is at least as efficient as the `INPLACE`, then they could execute the following:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD COLUMN c varchar(50);

```

In [MariaDB 10.3](../what-is-mariadb-103/index) and later, the above operation would actually use the `INSTANT` algorithm, because the `ADD COLUMN` operation supports the `INSTANT` algorithm, and the `INSTANT` algorithm is more efficient than the `INPLACE` algorithm.

 

**MariaDB until [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the [old\_alter\_table](../server-system-variables/index#old_alter_table) system variable can be used to specify whether the `COPY` algorithm should be used.

 For example, if a user wanted to add a column to a table, but they wanted to use the `COPY` algorithm instead of the default algorithm for the operation, then they could execute the following:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION old_alter_table=1;
ALTER TABLE tab ADD COLUMN c varchar(50);

```


Supported Alter Algorithms
--------------------------

 The supported algorithms are described in more details below.

 ### DEFAULT Algorithm

 The default behavior, which occurs if `ALGORITHM=DEFAULT` is specified, or if `ALGORITHM` is not specified at all, usually only makes a copy if the operation doesn't support being done in-place at all. In this case, the *most efficient* available algorithm will usually be used.

 This means that, if an operation supports the `INSTANT` algorithm, then it will use that algorithm by default. If an operation does not support the `INSTANT` algorithm, but it does support the `NOCOPY` algorithm, then it will use that algorithm by default. If an operation does not support the `NOCOPY` algorithm, but it does support the `INPLACE` algorithm, then it will use that algorithm by default.

 ### COPY Algorithm

 The `COPY` algorithm refers to the original [ALTER TABLE](../alter-table/index) algorithm.

 When the `COPY` algorithm is used, MariaDB essentially does the following operations:

 
```
-- Create a temporary table with the new definition
CREATE TEMPORARY TABLE tmp_tab (
...
);

-- Copy the data from the original table
INSERT INTO tmp_tab
   SELECT * FROM original_tab;

-- Drop the original table
DROP TABLE original_tab;

-- Rename the temporary table, so that it replaces the original one
RENAME TABLE tmp_tab TO original_tab;

```

This algorithm is very inefficient, but it is generic, so it works for all storage engines.

 If the `COPY` algorithm is specified with the [ALGORITHM](../alter-table/index#algorithm) clause or with the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable, then the `COPY` algorithm will be used even if it is not necessary. This can result in a lengthy table copy. If multiple [ALTER TABLE](../alter-table/index) operations are required that each require the table to be rebuilt, then it is best to specify all operations in a single [ALTER TABLE](../alter-table/index) statement, so that the table is only rebuilt once.

 #### Using the COPY Algorithm with InnoDB

 If the `COPY` algorithm is used with an [InnoDB](../innodb/index) table, then the following statements apply:

 * The table will be rebuilt using the current values of the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table), [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format), and [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) system variables.

 * The operation will have to create a temporary table to perform the the table copy. This temporary table will be in the same directory as the original table, and it's file name will be in the format ``#`sql${PID}_${THREAD_ID}_${TMP_TABLE_COUNT}`, where `${PID}` is the process ID of `mysqld`, `${THREAD_ID}` is the connection ID, and `${TMP_TABLE_COUNT}` is the number of temporary tables that the connection has open. Therefore, the [datadir](../server-system-variables/index#datadir) may contain files with file names like ``#`sql1234_12_1.ibd`.

 * The operation inserts one record at a time into each index, which is very inefficient.

 * InnoDB does not use a sort buffer.

 * In [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/), [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) and later, the table copy operation creates a lot fewer [InnoDB undo log](../xtradbinnodb-undo-log/index) writes. See [MDEV-11415](https://jira.mariadb.org/browse/MDEV-11415) for more information.

 * The table copy operation creates a lot of [InnoDB redo log](../innodb-redo-log/index) writes.

 ### INPLACE Algorithm

 The `COPY` algorithm can be incredibly slow, because the whole table has to be copied and rebuilt. The `INPLACE` algorithm was introduced as a way to avoid this by performing operations in-place and avoiding the table copy and rebuild, when possible.

 When the `INPLACE` algorithm is used, the underlying storage engine uses optimizations to perform the operation while avoiding the table copy and rebuild. However, `INPLACE` is a bit of a misnomer, since some operations may still require the table to be rebuilt for some storage engines. Regardless, several operations can be performed without a full copy of the table for some storage engines.

 A more accurate name for the algorithm would have been the `ENGINE` algorithm, since the [storage engine](../storage-engines/index) decides how to implement the algorithm.

 If an [ALTER TABLE](../alter-table/index) operation supports the `INPLACE` algorithm, then it can be performed using optimizations by the underlying storage engine, but it may rebuilt.

 If the `INPLACE` algorithm is specified with the [ALGORITHM](../alter-table/index#algorithm) clause or with the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable and if the [ALTER TABLE](../alter-table/index) operation does not support the `INPLACE` algorithm, then an error will be raised. For example:

 
```
SET SESSION alter_algorithm='INPLACE';

ALTER TABLE tab MODIFY COLUMN c int;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

In this case, raising an error is preferable, if the alternative is for the operation to make a copy of the table, and perform unexpectedly slowly.

 #### Using the INPLACE Algorithm with InnoDB

 If the `INPLACE` algorithm is used with an [InnoDB](../innodb/index) table, then the following statements apply:

 * The operation might have to write sort files in the directory defined by the [innodb\_tmpdir](../innodb-system-variables/index#innodb_tmpdir) system variable.

 * The operation might also have to write a temporary log file to track data changes by [DML queries](../data-manipulation/index) executed during the operation. The maximum size for this log file is configured by the [innodb\_online\_alter\_log\_max\_size](../innodb-system-variables/index#innodb_online_alter_log_max_size) system variable.

 * Some operations require the table to be rebuilt, even though the algorithm is inaccurately called "in-place". This includes operations such as adding or dropping columns, adding a primary key, changing a column to [NULL](null-and-not-null), etc.

 * If the operation requires the table to be rebuilt, then the operation might have to create temporary tables.
	+ It may have to create a temporary intermediate table for the actual table rebuild operation.
		- In [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) and later, this temporary table will be in the same directory as the original table, and it's file name will be in the format ``#`sql${PID}_${THREAD_ID}_${TMP_TABLE_COUNT}`, where `${PID}` is the process ID of `mysqld`, `${THREAD_ID}` is the connection ID, and `${TMP_TABLE_COUNT}` is the number of temporary tables that the connection has open. Therefore, the [datadir](../server-system-variables/index#datadir) may contain files with file names like ``#`sql1234_12_1.ibd`.
		- In [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/) and before, this temporary table will be in the same directory as the original table, and it's file name will be in the format ``#`sql-ib${TABLESPACE_ID}-${RAND}`, where `${TABLESPACE_ID}` is the table's tablespace ID within InnoDB and `${RAND}` is a randomly initialized number. Therefore, the [datadir](../server-system-variables/index#datadir) may contain files with file names like ``#`sql-ib230291-1363966925.ibd`.
	+ When it replaces the original table with the rebuilt table, it may also have to rename the original table using a temporary table name.
		- If the server is [MariaDB 10.3](../what-is-mariadb-103/index) or later or if it is running [MariaDB 10.2](../what-is-mariadb-102/index) and the [innodb\_safe\_truncate](../innodb-system-variables/index#innodb_safe_truncate) system variable is set to `OFF`, then the format will actually be ``#`sql-ib${TABLESPACE_ID}-${RAND}`, where `${TABLESPACE_ID}` is the table's tablespace ID within InnoDB and `${RAND}` is a randomly initialized number. Therefore, the [datadir](../server-system-variables/index#datadir) may contain files with file names like ``#`sql-ib230291-1363966925.ibd`.
		- If the server is running [MariaDB 10.1](../what-is-mariadb-101/index) or before or if it is running [MariaDB 10.2](../what-is-mariadb-102/index) and the [innodb\_safe\_truncate](../innodb-system-variables/index#innodb_safe_truncate) system variable is set to `ON`, then the renamed table will have a temporary table name in the format ``#`sql-ib${TABLESPACE_ID}`, where `${TABLESPACE_ID}` is the table's tablespace ID within InnoDB. Therefore, the [datadir](../server-system-variables/index#datadir) may contain files with file names like ``#`sql-ib230291.ibd`.

 * The storage needed for the above items can add up to the size of the original table, or more in some cases.

 * Some operations are instantaneous, if they only require the table's metadata to be changed. This includes operations such as renaming a column, changing a column's [DEFAULT](../create-table/index#default-column-option) value, etc.

 #### Operations Supported by InnoDB with the `INPLACE` Algorithm

 With respect to the allowed operations, the `INPLACE` algorithm supports a subset of the operations supported by the `COPY` algorithm, and it supports a superset of the operations supported by the `NOCOPY` algorithm.

 See [InnoDB Online DDL Operations with ALGORITHM=INPLACE](../innodb-online-ddl-operations-with-algorithminplace/index) for more information.

 ### NOCOPY Algorithm

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and later, the `NOCOPY` algorithm is supported.

 
The `INPLACE` algorithm can sometimes be surprisingly slow in instances where it has to rebuild the clustered index, because when the clustered index has to be rebuilt, the whole table has to be rebuilt. The `NOCOPY` algorithm was introduced as a way to avoid this. 

 If an [ALTER TABLE](../alter-table/index) operation supports the `NOCOPY` algorithm, then it can be performed without rebuilding the clustered index.

 If the `NOCOPY` algorithm is specified with the [ALGORITHM](../alter-table/index#algorithm) clause or with the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable and if the [ALTER TABLE](../alter-table/index) operation does not support the `NOCOPY` algorithm, then an error will be raised. For example:

 
```
SET SESSION alter_algorithm='NOCOPY';

ALTER TABLE tab MODIFY COLUMN c int;
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

In this case, raising an error is preferable, if the alternative is for the operation to rebuild the clustered index, and perform unexpectedly slowly.

 #### Operations Supported by InnoDB with the `NOCOPY` Algorithm

 With respect to the allowed operations, the `NOCOPY` algorithm supports a subset of the operations supported by the `INPLACE` algorithm, and it supports a superset of the operations supported by the `INSTANT` algorithm.

 See [InnoDB Online DDL Operations with ALGORITHM=NOCOPY](../innodb-online-ddl-operations-with-algorithmnocopy/index) for more information.

 ### INSTANT Algorithm

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and later, the `INSTANT` algorithm is supported.

 
The `INPLACE` algorithm can sometimes be surprisingly slow in instances where it has to modify data files. The `INSTANT` algorithm was introduced as a way to avoid this.

 If an [ALTER TABLE](../alter-table/index) operation supports the `INSTANT` algorithm, then it can be performed without modifying any data files.

 If the `INSTANT` algorithm is specified with the [ALGORITHM](../alter-table/index#algorithm) clause or with the [alter\_algorithm](../server-system-variables/index#alter_algorithm) system variable and if the [ALTER TABLE](../alter-table/index) operation does not support the `INSTANT` algorithm, then an error will be raised. For example:

 
```
SET SESSION alter_algorithm='INSTANT';

ALTER TABLE tab MODIFY COLUMN c int;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

In this case, raising an error is preferable, if the alternative is for the operation to modify data files, and perform unexpectedly slowly.

 #### Operations Supported by InnoDB with the INSTANT Algorithm

 With respect to the allowed operations, the `INSTANT` algorithm supports a subset of the operations supported by the `NOCOPY` algorithm.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT](../innodb-online-ddl-operations-with-algorithminstant/index) for more information.

 Alter Locking Strategies
------------------------

 InnoDB supports multiple locking strategies for performing DDL operations. This offers a significant performance improvement over previous versions. The supported locking strategies are:

 * `DEFAULT` - This implies the default behavior for the specific operation.
* `NONE`
* `SHARED`
* `EXCLUSIVE`

 Regardless of which locking strategy is used to perform a DDL operation, InnoDB will have to exclusively lock the table for a short time at the start and end of the operation's execution. This means that any active transactions that may have accessed the table must be committed or aborted for the operation to continue. This applies to most DDL statements, such as [ALTER TABLE](../alter-table/index), [CREATE INDEX](../create-index/index), [DROP INDEX](../drop-index/index), [OPTIMIZE TABLE](../optimize-table/index), [RENAME TABLE](../rename-table/index), etc.

 Specifying an Alter Locking Strategy
------------------------------------

 ### Specifying an Alter Locking Strategy Using the `LOCK` Clause

 The [ALTER TABLE](../alter-table/index) statement supports the [LOCK](../alter-table/index#lock) clause.

 The [LOCK](../alter-table/index#lock) clause can be used to specify the locking strategy that the user is willing to accept. It is supported by the [ALTER TABLE](../alter-table/index) and [CREATE INDEX](../create-index/index) statements.

 For example, if a user wanted to add a column to a table, but only if the operation is non-locking, then they could execute the following:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

ALTER TABLE tab ADD COLUMN c varchar(50), ALGORITHM=INPLACE, LOCK=NONE;

```

If the [LOCK](../alter-table/index#lock) clause is not explicitly set, then the operation uses `LOCK=DEFAULT`.

 ### Specifying an Alter Locking Strategy Using `ALTER ONLINE TABLE`

 [ALTER ONLINE TABLE](../alter-table/index#alter-online-table) is equivalent to `LOCK=NONE`. Therefore, the [ALTER ONLINE TABLE](alter-online-table) statement can be used to ensure that your [ALTER TABLE](../alter-table/index) operation allows all concurrent DML.

 Supported Alter Locking Strategies
----------------------------------

 The supported algorithms are described in more details below.

 To see which locking strategies InnoDB supports for each operation, see the pages that describe which operations are supported for each algorithm:

 * [InnoDB Online DDL Operations with ALGORITHM=INPLACE](../innodb-online-ddl-operations-with-algorithminplace/index)
* [InnoDB Online DDL Operations with ALGORITHM=NOCOPY](../innodb-online-ddl-operations-with-algorithmnocopy/index)
* [InnoDB Online DDL Operations with ALGORITHM=INSTANT](../innodb-online-ddl-operations-with-algorithminstant/index)

 ### DEFAULT Locking Strategy

 The default behavior, which occurs if `LOCK=DEFAULT` is specified, or if `LOCK` is not specified at all, acquire the least restrictive lock on the table that is supported for the specific operation. This permits the maximum amount of concurrency that is supported for the specific operation.

 ### NONE Locking Strategy

 The `NONE` locking strategy performs the operation without acquiring any lock on the table. This permits **all** concurrent DML.

 If this locking strategy is not permitted for an operation, then an error is raised.

 ### SHARED Locking Strategy

 The `SHARED` locking strategy performs the operation after acquiring a read lock on the table. This permit **read-only** concurrent DML.

 If this locking strategy is not permitted for an operation, then an error is raised.

 ### EXCLUSIVE Locking Strategy

 The `EXCLUSIVE` locking strategy performs the operation after acquiring a write lock on the table. This does **not** permit concurrent DML.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-online-ddl-overview/>

Information Schema TABLE\_CONSTRAINTS Table
===========================================

    The [Information Schema](../information_schema/index) `TABLE_CONSTRAINTS` table contains information about tables that have [constraints](../constraint/index).

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `CONSTRAINT_CATALOG` | Always `def`. |
| `CONSTRAINT_SCHEMA` | Database name containing the constraint. |
| `CONSTRAINT_NAME` | Constraint name. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `CONSTRAINT_TYPE` | Type of constraint; one of `UNIQUE`, `PRIMARY KEY`, `FOREIGN KEY` or `CHECK`. |

 
The [REFERENTIAL\_CONSTRAINTS](../information-schema-referential_constraints-table/index) table has more information about foreign keys.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-table_constraints-table/>

InnoDB Row Formats Overview
===========================

    The [InnoDB](../innodb/index) storage engine supports four different row formats:

 * [REDUNDANT](#redundant-row-format)
* [COMPACT](#compact-row-format)
* [DYNAMIC](#dynamic-row-format)
* [COMPRESSED](#compressed-row-format)

 
In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the latter two row formats are only supported if the [InnoDB file format](../xtradbinnodb-file-format/index) is `Barracuda`. Therefore, the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable must be set to `Barracuda` to use these row formats in those versions.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the latter two row formats are also only supported if the table is in a [file per-table](../innodb-file-per-table-tablespaces/index) tablespace. Therefore, the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable must be set to `ON` to use these row formats in those versions.

 
Default Row Format
------------------

 The [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) system variable can be used to set the default row format for InnoDB tables. The possible values are:

 * `redundant`
* `compact`
* `dynamic`

 This system variable's default value is `dynamic`, which means that the default row format is `DYNAMIC`.

 This system variable cannot be set to `compressed`, which means that the default row format cannot be `COMPRESSED`.

 For example, the following statements would create a table with the `DYNAMIC` row format:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_default_row_format='dynamic';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB;

```

Setting a Table's Row Format
----------------------------

 One way to specify an InnoDB table's row format is by setting the [ROW\_FORMAT](../create-table/index#row_format) table option to the relevant row format in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement. For example:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

```


In [MariaDB 10.1](../what-is-mariadb-101/index) and before, InnoDB can silently ignore and override some row format choices if you do not have the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable set to `Barracuda` and the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable set to `ON`.

 
Checking a Table's Row Format
-----------------------------

 The [SHOW TABLE STATUS](../show-table-status/index) statement can be used to see the row format used by a table. For example:

 
```
SHOW TABLE STATUS FROM db1 WHERE Name='tab'\G
*************************** 1. row ***************************
           Name: tab
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2019-04-18 20:24:04
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
 Create_options: row_format=DYNAMIC
        Comment:

```

The [information\_schema.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table can also be queried to see the row format used by a table. For example:

 
```
SELECT * FROM information_schema.INNODB_SYS_TABLES WHERE name='db1/tab'\G
*************************** 1. row ***************************
     TABLE_ID: 42
         NAME: db1/tab
         FLAG: 33
       N_COLS: 4
        SPACE: 27
  FILE_FORMAT: Barracuda
   ROW_FORMAT: Dynamic
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: Single

```


A table's tablespace is tagged with the lowest InnoDB file format that supports the table's row format. So, even if the `Barracuda` file format is enabled, tables that use the `COMPACT` or `REDUNDANT` row formats will be tagged with the `Antelope` file format in the [information\_schema.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table.

 
Row Formats
-----------

 ### REDUNDANT Row Format

 The `REDUNDANT` row format is the original non-compacted row format.

 The `REDUNDANT` row format was the only available row format before MySQL 5.0.3. In that release, this row format was retroactively named the `REDUNDANT` row format. In the same release, the `COMPACT` row format was introduced as the new default row format.

 See [InnoDB REDUNDANT Row Format](../innodb-redundant-row-format/index) for more information.

 ### COMPACT Row Format

 Default row format in [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and earlier `COMPACT`.

 The `COMPACT` row format is similar to the `REDUNDANT` row format, but it stores data in a more compact manner that requires about 20% less storage.

 See [InnoDB COMPACT Row Format](../innodb-compact-row-format/index) for more information.

 ### DYNAMIC Row Format

 `DYNAMIC` is the default row format.

 The `DYNAMIC` row format is similar to the `COMPACT` row format, but tables using the `DYNAMIC` row format can store even more data on overflow pages than tables using the `COMPACT` row format. This results in more efficient data storage than tables using the `COMPACT` row format, especially for tables containing columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types. However, InnoDB tables using the `COMPRESSED` row format are more efficient.

 See [InnoDB DYNAMIC Row Format](../innodb-dynamic-row-format/index) for more information.

 ### COMPRESSED Row Format

 An alternative way to compress InnoDB tables is by using [InnoDB Page Compression](../innodb-page-compression/index).

 The `COMPRESSED` row format is similar to the `COMPACT` row format, but tables using the `COMPRESSED` row format can store even more data on overflow pages than tables using the `COMPACT` row format. This results in more efficient data storage than tables using the `COMPACT` row format, especially for tables containing columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types.

 The `COMPRESSED` row format also supports compression of all data and index pages.

 See [InnoDB COMPRESSED Row Format](../innodb-compressed-row-format/index) for more information.

 Maximum Row Size
----------------

 Several factors help determine the maximum row size of an InnoDB table.

 First, MariaDB enforces a 65,535 byte limit on a table's maximum row size. The total size of a table's [BLOB](../blob/index) and [TEXT](../text/index) columns do not count towards this limit. Only the pointers for a table's [BLOB](../blob/index) and [TEXT](../text/index) columns count towards this limit. MariaDB enforces this limit for all storage engines, so this limit also applies to InnoDB tables. Therefore, this limit is the absolute maximum row size for an InnoDB table. 

 If you try to create a table that exceeds MariaDB's global limit on a table's maximum row size, then you will see an error like this:

 
```
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, 
not counting BLOBs, is 65535. This includes storage overhead, check the manual. You 
have to change some columns to TEXT or BLOBs

```

However, InnoDB also has its own limits on the maximum row size, so an InnoDB table's maximum row size could be smaller than MariaDB's global limit.

 Second, the maximum amount of data that an InnoDB table can store in a row's main data page depends on the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable. At most, the data that a single row can consume on the row's main data page is half of the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) system variable. With the default value of `16k`, that would mean that a single row can consume at most around 8 KB on the row's main data page. However, the limit on the row's main data page is not the absolute limit on the row's size. 

 Third, all InnoDB row formats can store certain kinds of data in overflow pages, so the maximum row size of an InnoDB table can be larger than the maximum amount of data that can be stored in the row's main data page.

 Some row formats can store more data in overflow pages than others. For example, the `DYNAMIC` and `COMPRESSED` row formats can store the most data in overflow pages. To see how to determine the how the various InnoDB row formats can use overflow pages, see the following sections:

 * [InnoDB REDUNDANT Row Format: Overflow Pages with the REDUNDANT Row Format](../innodb-redundant-row-format/index#overflow-pages-with-the-redundant-row-format)
* [InnoDB COMPACT Row Format: Overflow Pages with the COMPACT Row Format](../innodb-compact-row-format/index#overflow-pages-with-the-compact-row-format)
* [InnoDB DYNAMIC Row Format: Overflow Pages with the DYNAMIC Row Format](../innodb-dynamic-row-format/index#overflow-pages-with-the-dynamic-row-format)
* [InnoDB COMPRESSED Row Format: Overflow Pages with the COMPRESSED Row Format](../innodb-compressed-row-format/index#overflow-pages-with-the-compressed-row-format)

 If a table's definition can allow rows that the table's InnoDB row format can't actually store, then InnoDB will raise errors or warnings in certain scenarios.

 If the table were using the `REDUNDANT` or `COMPACT` row formats, then the error or warning would be the following:

 
```
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED 
may help. In current row format, BLOB prefix of 768 bytes is stored inline.

```

And if the table were using the `DYNAMIC` or `COMPRESSED` row formats, then the error or warning would be the following:

 
```
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

```

These messages are raised in the following cases:

 * If [InnoDB strict mode](../innodb-strict-mode/index) is **enabled** and if a [DDL](../data-definition/index) statement is executed that touches the table, such as [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index), then InnoDB will raise an **error** with this message
* If [InnoDB strict mode](../innodb-strict-mode/index) is **disabled** and if a [DDL](../data-definition/index) statement is executed that touches the table, such as [CREATE TABLE](../create-table/index) `or [ALTER TABLE](../alter-table/index)`, then InnoDB will raise a **warning** with this message.
* Regardless of whether [InnoDB strict mode](../innodb-strict-mode/index) is enabled, if a [DML](../data-manipulation/index) statement is executed that attempts to write a row that the table's InnoDB row format can't store, then InnoDB will raise an **error** with this message.

 For information on how to solve the problem, see [Troubleshooting Row Size Too Large Errors with InnoDB](../troubleshooting-row-size-too-large-errors-with-innodb/index).

 Known Issues
------------

 ### Upgrading Causes Row Size Too Large Errors

 Prior to [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), and [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), MariaDB doesn't properly calculate the row sizes while executing DDL. In these versions, *unsafe* tables can be created, even if [InnoDB strict mode](../innodb-strict-mode/index) is enabled. The calculations were fixed by [MDEV-19292](https://jira.mariadb.org/browse/MDEV-19292) in [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), and [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/).

 As a side effect, some tables that could be created or altered in previous versions may get rejected with the following error in these releases and any later releases.

 
```
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to 
TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

```

And users could also see the following message as an error or warning in the [error log](../error-log/index):

 
```
[Warning] InnoDB: Cannot add field col in table db1.tab because after adding it, the row size is 8478 which is greater than maximum allowed size (8126) for a record on index leaf page.

```

InnoDB used the wrong calculations to determine row sizes for quite a long time, so a lot of users may unknowingly have *unsafe* tables that the InnoDB row format can't actually store.

 InnoDB does not currently have an easy way to check which existing tables have this problem. See [MDEV-20400](https://jira.mariadb.org/browse/MDEV-20400) for more information.

 For information on how to solve the problem, see [Troubleshooting Row Size Too Large Errors with InnoDB](../troubleshooting-row-size-too-large-errors-with-innodb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/xtradbinnodb-storage-formats/>

ALTER LOGFILE GROUP
===================

    Syntax
------

 
```
ALTER LOGFILE GROUP logfile_group
    ADD UNDOFILE 'file_name'
    [INITIAL_SIZE [=] size]
    [WAIT]
    ENGINE [=] engine_name

```


The `ALTER LOGFILE GROUP` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See [MDEV-19295](https://jira.mariadb.org/browse/MDEV-19295) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/alter-logfile-group/>

InnoDB Online DDL Operations with the INPLACE Alter Algorithm
=============================================================

    Supported Operations by Inheritance
-----------------------------------

 When the [ALGORITHM](../alter-table/index#algorithm) clause is set to `INPLACE`, the supported operations are a superset of the operations that are supported when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `NOCOPY`. Similarly, when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `NOCOPY`, the supported operations are a superset of the operations that are supported when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `INSTANT`.

 Therefore, when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `INPLACE`, some operations are supported by inheritance. See the following additional pages for more information about these supported operations:

 * [InnoDB Online DDL Operations with ALGORITHM=NOCOPY](../innodb-online-ddl-operations-with-algorithmnocopy/index)
* [InnoDB Online DDL Operations with ALGORITHM=INSTANT](../innodb-online-ddl-operations-with-algorithminstant/index)

 Column Operations
-----------------

 ### `ALTER TABLE ... ADD COLUMN`

 InnoDB supports adding columns to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 With the exception of adding an [auto-increment](../auto_increment/index) column, this operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD COLUMN c varchar(50);
Query OK, 0 rows affected (0.006 sec)

```

This applies to [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP COLUMN`

 InnoDB supports dropping columns from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP COLUMN c;
Query OK, 0 rows affected (0.021 sec)

```

This applies to [ALTER TABLE ... DROP COLUMN](../alter-table/index#drop-column) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... MODIFY COLUMN`

 This applies to [ALTER TABLE ... MODIFY COLUMN](../alter-table/index#modify-column) for [InnoDB](../innodb/index) tables.

 #### Reordering Columns

 InnoDB supports reordering columns within a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(50) AFTER a;
Query OK, 0 rows affected (0.022 sec)

```

#### Changing the Data Type of a Column

 InnoDB does **not** support modifying a column's data type with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE` in most cases. There are some exceptions:

 * In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, InnoDB supports increasing the length of `VARCHAR` columns with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, unless it would require changing the number of bytes requires to represent the column's length. A `VARCHAR` column that is between 0 and 255 bytes in size requires 1 byte to represent its length, while a `VARCHAR` column that is 256 bytes or longer requires 2 bytes to represent its length. This means that the length of a column cannot be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE` if the original length was less than 256 bytes, and the new length is 256 bytes or more.

 * In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, InnoDB supports increasing the length of `VARCHAR` columns with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Changing the Data Type of a Column](../innodb-online-ddl-operations-with-algorithminstant/index#changing-the-data-type-of-a-column) for more information.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c int;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

But this succeeds in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, because the original length of the column is less than 256 bytes, and the new length is still less than 256 bytes:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) CHARACTER SET=latin1;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(100);
Query OK, 0 rows affected (0.005 sec)

```

But this fails in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, because the original length of the column is less than 256 bytes, and the new length is greater than 256 bytes:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(255)
) CHARACTER SET=latin1;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(256);
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Changing a Column to NULL

 InnoDB supports modifying a column to allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) NOT NULL
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(50) NULL;
Query OK, 0 rows affected (0.021 sec)

```

#### Changing a Column to NOT NULL

 InnoDB supports modifying a column to **not** allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. It is required for [strict mode](../sql-mode/index#strict-mode) to be enabled in [SQL\_MODE](../sql-mode/index). The operation will fail if the column contains any `NULL` values. Changes that would interfere with referential integrity are also not permitted.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(50) NOT NULL;
Query OK, 0 rows affected (0.021 sec)

```

#### Adding a New `ENUM` Option

 InnoDB supports adding a new [ENUM](../enum/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. In order to add a new [ENUM](../enum/index) option with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, the following requirements must be met:

 * It must be added to the end of the list.
* The storage requirements must not change.

 This operation only changes the table's metadata, so the table does not have to be rebuilt..

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c ENUM('red', 'green')
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c ENUM('red', 'green', 'blue');
Query OK, 0 rows affected (0.004 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c ENUM('red', 'green')
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c ENUM('red', 'blue', 'green');
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Adding a New `SET` Option

 InnoDB supports adding a new [SET](../set-data-type/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. In order to add a new [SET](../set-data-type/index) option with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, the following requirements must be met:

 * It must be added to the end of the list.
* The storage requirements must not change.

 This operation only changes the table's metadata, so the table does not have to be rebuilt..

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c SET('red', 'green')
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c SET('red', 'green', 'blue');
Query OK, 0 rows affected (0.004 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c SET('red', 'green')
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c SET('red', 'blue', 'green');
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Removing System Versioning from a Column

 In [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/) and later, InnoDB supports removing [system versioning](../system-versioned-tables/index) from a column with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. In order for this to work, the [system\_versioning\_alter\_history](../system-versioned-tables/index#system_versioning_alter_history) system variable must be set to `KEEP`. See [MDEV-16330](https://jira.mariadb.org/browse/MDEV-16330) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) WITH SYSTEM VERSIONING
);

SET SESSION system_versioning_alter_history='KEEP';
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab MODIFY COLUMN c varchar(50) WITHOUT SYSTEM VERSIONING;
Query OK, 0 rows affected (0.005 sec)

```

### `ALTER TABLE ... ALTER COLUMN`

 This applies to [ALTER TABLE ... ALTER COLUMN](../alter-table/index#alter-column) for [InnoDB](../innodb/index) tables.

 #### Setting a Column's Default Value

 InnoDB supports modifying a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted. For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ALTER COLUMN c SET DEFAULT 'No value explicitly provided.';
Query OK, 0 rows affected (0.005 sec)

```

#### Removing a Column's Default Value

 InnoDB supports removing a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) DEFAULT 'No value explicitly provided.'
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ALTER COLUMN c DROP DEFAULT;
Query OK, 0 rows affected (0.005 sec)

```

### `ALTER TABLE ... CHANGE COLUMN`

 InnoDB supports renaming a column with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, unless the column's data type or attributes changed in addition to the name.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab CHANGE COLUMN c str varchar(50);
Query OK, 0 rows affected (0.006 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab CHANGE COLUMN c num int;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

This applies to [ALTER TABLE ... CHANGE COLUMN](../alter-table/index#change-column) for [InnoDB](../innodb/index) tables.

 Index Operations
----------------

 ### `ALTER TABLE ... ADD PRIMARY KEY`

 InnoDB supports adding a primary key to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 If the new primary key column is not defined as [NOT NULL](../create-table/index#null-and-not-null), then it is highly recommended for [strict mode](../sql-mode/index#strict-mode) to be enabled in [SQL\_MODE](../sql-mode/index). Otherwise, `NULL` values will be silently converted to the default value for the given data type, which is probably not the desired behavior in this scenario.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int,
   b varchar(50),
   c varchar(50)
);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD PRIMARY KEY (a);
Query OK, 0 rows affected (0.021 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int,
   b varchar(50),
   c varchar(50)
);

INSERT INTO tab VALUES (NULL, NULL, NULL);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD PRIMARY KEY (a);
ERROR 1265 (01000): Data truncated for column 'a' at row 1

```

And this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int,
   b varchar(50),
   c varchar(50)
);

INSERT INTO tab VALUES (1, NULL, NULL);
INSERT INTO tab VALUES (1, NULL, NULL);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD PRIMARY KEY (a);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'

```

This applies to [ALTER TABLE ... ADD PRIMARY KEY](../alter-table/index#add-primary-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP PRIMARY KEY`

 InnoDB does **not** support dropping a primary key with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE` in most cases.

 If you try to do so, then you will see an error. InnoDB only supports this operation with [ALGORITHM](../alter-table/index#algorithm) set to `COPY`. Concurrent DML is \*not\* permitted.

 However, there is an exception. If you are dropping a primary key, and adding a new one at the same time, then that operation can be performed with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP PRIMARY KEY;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Dropping a primary key is not allowed without also adding a new primary key. Try ALGORITHM=COPY

```

But this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP PRIMARY KEY, ADD PRIMARY KEY (b);
Query OK, 0 rows affected (0.020 sec)

```

This applies to [ALTER TABLE ... DROP PRIMARY KEY](../alter-table/index#drop-primary-key) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... ADD INDEX` and `CREATE INDEX`

 This applies to [ALTER TABLE ... ADD INDEX](../alter-table/index#add-index) and [CREATE INDEX](../create-index/index) for [InnoDB](../innodb/index) tables.

 #### Adding a Plain Index

 InnoDB supports adding a plain index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. The table is not rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD INDEX b_index (b);
Query OK, 0 rows affected (0.010 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
CREATE INDEX b_index ON tab (b);
Query OK, 0 rows affected (0.011 sec)

```

#### Adding a Fulltext Index

 InnoDB supports adding a [FULLTEXT](../full-text-indexes/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. The table is not rebuilt in some cases.

 However, there are some limitations, such as:

 * Adding a [FULLTEXT](../full-text-indexes/index) index to a table that does not have a user-defined `FTS_DOC_ID` column will require the table to be rebuilt once. When the table is rebuilt, the system adds a hidden `FTS_DOC_ID` column. From that point forward, adding additional [FULLTEXT](../full-text-indexes/index) indexes to the same table will not require the table to be rebuilt when [ALGORITHM](../alter-table/index#algorithm) is set to `INPLACE`.

 * Only one [FULLTEXT](../full-text-indexes/index) index may be added at a time when [ALGORITHM](../alter-table/index#algorithm) is set to `INPLACE`.

 * If a table has more than one [FULLTEXT](../full-text-indexes/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when [ALGORITHM](../alter-table/index#algorithm) is set to `INPLACE`.

 * If a table has a [FULLTEXT](../full-text-indexes/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when the [LOCK](../alter-table/index#lock) clause is set to `NONE`.

 This operation supports a read-only locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `SHARED`. When this strategy is used, read-only concurrent DML is permitted. 

 For example, this succeeds, but requires the table to be rebuilt, so that the hidden `FTS_DOC_ID` column can be added:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.055 sec)

```

And this succeeds in the same way as above:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
CREATE FULLTEXT INDEX b_index ON tab (b);
Query OK, 0 rows affected (0.041 sec)

```

And this succeeds, and the second command does not require the table to be rebuilt:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.043 sec)

ALTER TABLE tab ADD FULLTEXT INDEX c_index (c);
Query OK, 0 rows affected (0.017 sec)

```

But this second command fails, because only one [FULLTEXT](../full-text-indexes/index) index can be added at a time:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.041 sec)

ALTER TABLE tab ADD FULLTEXT INDEX c_index (c), ADD FULLTEXT INDEX d_index (d);
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY

```

And this third command fails, because a table cannot be rebuilt when it has more than one [FULLTEXT](../full-text-indexes/index) index:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.040 sec)

ALTER TABLE tab ADD FULLTEXT INDEX c_index (c);
Query OK, 0 rows affected (0.015 sec)

ALTER TABLE tab FORCE;
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY

```

#### Adding a Spatial Index

 InnoDB supports adding a [SPATIAL](../spatial-index/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 However, there are some limitations, such as:

 * If a table has a [SPATIAL](../spatial-index/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when the [LOCK](../alter-table/index#lock) clause is set to `NONE`.

 This operation supports a read-only locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `SHARED`. When this strategy is used, read-only concurrent DML is permitted. 

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD SPATIAL INDEX c_index (c);
Query OK, 0 rows affected (0.006 sec)

```

And this succeeds in the same way as above:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='INPLACE';
CREATE SPATIAL INDEX c_index ON tab (c);
Query OK, 0 rows affected (0.006 sec)

```

### 
`ALTER TABLE ... DROP INDEX` and `DROP INDEX`

 InnoDB supports dropping indexes from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   INDEX b_index (b)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP INDEX b_index;

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   INDEX b_index (b)
);

SET SESSION alter_algorithm='INPLACE';
DROP INDEX b_index ON tab;

```

This applies to [ALTER TABLE ... DROP INDEX](../alter-table/index#drop-index) and [DROP INDEX](../drop-index/index) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ADD FOREIGN KEY`

 InnoDB supports adding foreign key constraints to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. In order to add a new foreign key constraint to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, the [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) system variable needs to be set to `OFF`. If it is set to `ON`, then `ALGORITHM=COPY` is required.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int
);

CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab1 ADD FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a);
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY

```

But this succeeds:

 
```
CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int
);

CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION foreign_key_checks=OFF;
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab1 ADD FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a);
Query OK, 0 rows affected (0.011 sec)

```

This applies to [ALTER TABLE ... ADD FOREIGN KEY](../alter-table/index#add-foreign-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP FOREIGN KEY`

 InnoDB supports dropping foreign key constraints from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int,
   FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab1 DROP FOREIGN KEY tab2_fk;
Query OK, 0 rows affected (0.005 sec)

```

This applies to [ALTER TABLE ... DROP FOREIGN KEY](../alter-table/index#drop-foreign-key) for [InnoDB](../innodb/index) tables.

 Table Operations
----------------

 ### `ALTER TABLE ... AUTO_INCREMENT=...`

 InnoDB supports changing a table's [AUTO\_INCREMENT](../auto_increment/index) value with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. This operation should finish instantly. The table is not rebuilt.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab AUTO_INCREMENT=100;
Query OK, 0 rows affected (0.004 sec)

```

This applies to [ALTER TABLE ... AUTO\_INCREMENT=...](../create-table/index#auto_increment) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ROW_FORMAT=...`

 InnoDB supports changing a table's [row format](../innodb-storage-formats/index) with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=DYNAMIC;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ROW_FORMAT=COMPRESSED;
Query OK, 0 rows affected (0.025 sec)

```

This applies to [ALTER TABLE ... ROW\_FORMAT=...](../create-table/index#row_format) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... KEY_BLOCK_SIZE=...`

 InnoDB supports changing a table's [KEY\_BLOCK\_SIZE](../innodb-storage-formats/index#using-the-compressed-row-format) with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=COMPRESSED
  KEY_BLOCK_SIZE=4;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab KEY_BLOCK_SIZE=2;
Query OK, 0 rows affected (0.021 sec)

```

This applies to [KEY\_BLOCK\_SIZE=...](../create-table/index#key_block_size) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... PAGE_COMPRESSED=...` and `ALTER TABLE ... PAGE_COMPRESSION_LEVEL=...`

 In [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) and later, InnoDB supports setting a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value to `1` with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. InnoDB also supports changing a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value from `1` to `0` with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 In these versions, InnoDB also supports changing a table's [PAGE\_COMPRESSION\_LEVEL](../create-table/index#page_compression_level) value with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 See [MDEV-16328](https://jira.mariadb.org/browse/MDEV-16328) for more information.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab PAGE_COMPRESSED=1;
Query OK, 0 rows affected (0.006 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) PAGE_COMPRESSED=1;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab PAGE_COMPRESSED=0;
Query OK, 0 rows affected (0.020 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) PAGE_COMPRESSED=1
  PAGE_COMPRESSION_LEVEL=5;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab PAGE_COMPRESSION_LEVEL=4;
Query OK, 0 rows affected (0.006 sec)

```

This applies to [PAGE\_COMPRESSED=...](../create-table/index#page_compressed) and [PAGE\_COMPRESSION\_LEVEL=...](../create-table/index#page_compression_level) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP SYSTEM VERSIONING`

 InnoDB supports dropping [system versioning](../system-versioned-tables/index) from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation supports the read-only locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `SHARED`. When this strategy is used, read-only concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) WITH SYSTEM VERSIONING;

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP SYSTEM VERSIONING;

```

This applies to [ALTER TABLE ... DROP SYSTEM VERSIONING](../alter-table/index#drop-system-versioning) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP CONSTRAINT`

 In [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) and later, InnoDB supports dropping a [CHECK](../constraint/index#check-constraints) constraint from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. See [MDEV-16331](https://jira.mariadb.org/browse/MDEV-16331) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   CONSTRAINT b_not_empty CHECK (b != '')
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab DROP CONSTRAINT b_not_empty;
Query OK, 0 rows affected (0.004 sec)

```

This applies to [ALTER TABLE ... DROP CONSTRAINT](../alter-table/index#drop-constraint) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... FORCE`

 InnoDB supports forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab FORCE;
Query OK, 0 rows affected (0.022 sec)

```

This applies to [ALTER TABLE ... FORCE](../alter-table/index#force) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ENGINE=InnoDB`

 InnoDB supports forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ENGINE=InnoDB;
Query OK, 0 rows affected (0.022 sec)

```

This applies to [ALTER TABLE ... ENGINE=InnoDB](../create-table/index#storage-engine) for [InnoDB](../innodb/index) tables.

 ### `OPTIMIZE TABLE ...`

 InnoDB supports optimizing a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 If the [innodb\_defragment](../innodb-system-variables/index#innodb_defragment) system variable is set to `OFF`, and if the [innodb\_optimize\_fulltext\_only](../innodb-system-variables/index#innodb_optimize_fulltext_only) system variable is also set to `OFF`, then `OPTIMIZE TABLE` will be equivalent to `ALTER TABLE … FORCE`.

 The table is rebuilt, which means that all of the data is reorganized substantially, and the indexes are rebuilt. As a result, the operation is quite expensive.

 If either of the previously mentioned system variables is set to `ON`, then `OPTIMIZE TABLE` will optimize some data without rebuilding the table. However, the file size will not be reduced.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SHOW GLOBAL VARIABLES WHERE Variable_name IN('innodb_defragment', 'innodb_optimize_fulltext_only');
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_defragment             | OFF   |
| innodb_optimize_fulltext_only | OFF   |
+-------------------------------+-------+

SET SESSION alter_algorithm='INPLACE';
OPTIMIZE TABLE tab;
+---------+----------+----------+-------------------------------------------------------------------+
| Table   | Op       | Msg_type | Msg_text                                                          |
+---------+----------+----------+-------------------------------------------------------------------+
| db1.tab | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| db1.tab | optimize | status   | OK                                                                |
+---------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.026 sec)

```

And this succeeds, but the table is not rebuilt:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET GLOBAL innodb_defragment=ON;
SHOW GLOBAL VARIABLES WHERE Variable_name IN('innodb_defragment', 'innodb_optimize_fulltext_only');
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_defragment             | ON    |
| innodb_optimize_fulltext_only | OFF   |
+-------------------------------+-------+

SET SESSION alter_algorithm='INPLACE';
OPTIMIZE TABLE tab;
+---------+----------+----------+----------+
| Table   | Op       | Msg_type | Msg_text |
+---------+----------+----------+----------+
| db1.tab | optimize | status   | OK       |
+---------+----------+----------+----------+
1 row in set (0.004 sec)

```

This applies to [OPTIMIZE TABLE](../optimize-table/index) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... RENAME TO` and `RENAME TABLE ...`

 InnoDB supports renaming a table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.

 This operation only changes the table's metadata, so the table does not have to be rebuilt.

 This operation supports the exclusive locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `EXCLUSIVE`. When this strategy is used, concurrent DML is **not** permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab RENAME TO old_tab;
Query OK, 0 rows affected (0.011 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
RENAME TABLE tab TO old_tab;

```

This applies to [ALTER TABLE ... RENAME TO](../alter-table/index#rename-to) and [RENAME TABLE](../rename-table/index) for [InnoDB](../innodb/index) tables.

 Limitations
-----------

 ### Limitations Related to Fulltext Indexes

 * If a table has more than one [FULLTEXT](../full-text-indexes/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when [ALGORITHM](../alter-table/index#algorithm) is set to `INPLACE`.

 * If a table has a [FULLTEXT](../full-text-indexes/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when the [LOCK](../alter-table/index#lock) clause is set to `NONE`.

 ### Limitations Related to Spatial Indexes

 * If a table has a [SPATIAL](../spatial-index/index) index, then it cannot be rebuilt by any [ALTER TABLE](../alter-table/index) operations when the [LOCK](../alter-table/index#lock) clause is set to `NONE`.

 ### Limitations Related to Generated (Virtual and Persistent/Stored) Columns

 [Generated columns](../generated-columns/index) do not currently support online DDL for all of the same operations that are supported for "real" columns.

 See [Generated (Virtual and Persistent/Stored) Columns: Statement Support](../generated-columns/index#statement-support) for more information on the limitations.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-online-ddl-operations-with-the-inplace-alter-algorithm/>

About Mroonga
=============

    


| Mroonga Version | Introduced | Maturity |
| --- | --- | --- |
| 7.07 | [MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/), [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/) | Stable |
| 5.04 | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) | Stable |
| 5.02 | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/), [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/) | Stable |
| 5.0 | [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/) | Stable |
| 4.06 | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) | Stable |

 
 Mroonga is a full text search storage engine based on Groonga, which is an open-source CJK-ready (Chinese, Japanese, and Korean) fulltext search engine using column base. See <http://groonga.org> for more.

 With Mroonga, you can have a CJK-ready full text search feature, and it is faster than the [MyISAM](../myisam/index) and [InnoDB](../innodb/index) [full text search](../full-text-indexes/index) for both updating and searching.

 Mroonga also supports Groonga's fast geolocation search by using MariaDB's geolocation SQL syntax.

 Mroonga currently only supports Linux x86\_64 (Intel64/AMD64).

 How to Install
--------------

 Enable Mroonga with the following statement:

 
```
INSTALL SONAME 'ha_mroonga';

```

On Debian and Ubuntu mroonga engine will be installed with 

 
```
sudo apt-get install mariadb-plugin-mroonga

```

See [Plugin overview](../plugin-overview/index) for details on installing and uninstalling plugins.

 [SHOW ENGINES](../show-engines/index) can be used to check whether Mroonga is installed correctly:

 
```
SHOW ENGINES;
...
*************************** 8. row ***************************
      Engine: Mroonga
     Support: YES
     Comment: CJK-ready fulltext search, column store
Transactions: NO
          XA: NO
  Savepoints: NO
...

```

Once the plugin is installed, add a UDF (User-Defined Function) named "last\_insert\_grn\_id", that returns the record ID assigned by groonga in INSERT, by the following SQL.

 
```
CREATE FUNCTION last_insert_grn_id RETURNS INTEGER SONAME 'ha_mroonga.so';

```

Limitations
-----------

 * The maximum size of a single key is 4096 bytes.
* The maximum size of all keys is 4GB.
* The maximum number of records in a fulltext index is 268,435,455
* The maximum number of distinct terms in a fulltext index is 268,435,455
* The maximum size of a fulltext index is 256GB

 Note that the maximum sizes are not hard limits, and may vary according to circumstance.

 For more details, see <http://mroonga.org/docs/reference/limitations.html>.

 Available Character Sets
------------------------

 Mroonga supports a limited number of [character sets](../data-types-character-sets-and-collations/index). These include:

 * ASCII
* BINARY
* CP932
* EUCJPMS
* KOI8R
* LATIN1
* SJIS
* UJIS
* UTF8
* UTF8MB4

 More Information
----------------

 Further documentation for Mroonga can be found at <http://mroonga.org/docs/>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-mroonga/>

Mroonga User-Defined Functions
===============================

   Mroonga provides a number of User-defined functions (UDFs)

  

| Title | Description |
| --- | --- |
|  [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) |  How to install Mroonga's user-defined functions.  |
|  [last\_insert\_grn\_id](../last_insert_grn_id/index) |  Returns the unique Groonga id of the last-inserted record.  |
|  [mroonga\_command](../mroonga_command/index) |  Pass a command to Groonga to execute.  |
|  [mroonga\_escape](../mroonga_escape/index) |  Escaping a string.  |
|  [mroonga\_highlight\_html](../mroonga_highlight_html/index) |  Highlights the specified keywords in the target text.  |
|  [mroonga\_normalize](../mroonga_normalize/index) |  Uses Groonga's normalizer to normalize text.  |
|  [mroonga\_snippet](../mroonga_snippet/index) |  A keyword with surrounding text, or the keyword in context.  |
|  [mroonga\_snippet\_html](../mroonga_snippet_html/index) |  It provides a keyword with surrounding text, or the keyword in context.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga-user-defined-functions/>

Mroonga Overview
================

      
  
 Once Mroonga has been installed (see [About Mroonga](../about-mroonga/index)), its basic usage is similar to that of a [regular fulltext index](../full-text-indexes/index).   
  
  
  
 For example:  
  
  


 
```
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy)) ENGINE=Mroonga;

INSERT INTO ft_mroonga(copy) VALUES ('Once upon a time'),
    ('There was a wicked witch'), ('Who ate everybody up');

SELECT * FROM ft_mroonga WHERE MATCH(copy) AGAINST('wicked');
+--------------------------+
| copy                     |
+--------------------------+
| There was a wicked witch |
+--------------------------+

```

Score
-----

 Mroonga can also order by weighting. For example, first add another record:

 
```
INSERT INTO ft_mroonga(copy) VALUES ('She met a wicked, wicked witch');

```

Records can be returned by weighting, for example, the newly added record has two occurences of the word 'wicked' and a higher weighting:

 
```
SELECT *, MATCH(copy) AGAINST('wicked') AS score FROM ft_mroonga 
   WHERE MATCH(copy) AGAINST('wicked') ORDER BY score DESC;
+--------------------------------+--------+
| copy                           | score  |
+--------------------------------+--------+
| She met a wicked, wicked witch | 299594 |
| There was a wicked witch       | 149797 |
+--------------------------------+--------+

```

Parser
------

 Mroonga permits you to set a different parser for searching by specifying the parser in the `CREATE TABLE` statement as a comment or, in older versions, changing the value of the [mroonga\_default\_parser](../mroonga-system-variables/index#mroonga_default_parser) system variable. 

 For example:

 
```
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy) COMMENT 'parser "TokenDelimitNull"') 
  ENGINE=Mroonga;, 

```

or

 
```
SET GLOBAL mroonga_default_parser = 'TokenBigramSplitSymbol';

```

The following parser settings are available:

 


| Setting | Description |
| --- | --- |
| off | No tokenizing is performed. |
| TokenBigram | Default value. Continuous alphabetical characters, numbers or symbols are treated as a token. |
| TokenBigramIgnoreBlank | Same as `TokenBigram` except that white spaces are ignored. |
| TokenBigramIgnoreBlankSplitSymbol | Same as `TokenBigramSplitSymbol`. except that white spaces are ignore. |
| TokenBigramIgnoreBlankSplitSymbolAlpha | Same as `TokenBigramSplitSymbolAlpha` except that white spaces are ignored. |
| TokenBigramIgnoreBlankSplitSymbolAlphaDigit | Same as `TokenBigramSplitSymbolAlphaDigit` except that white spaces are ignored. |
| TokenBigramSplitSymbol | Same as `TokenBigram` except that continuous symbols are not treated as a token, but tokenised in bigram. |
| TokenBigramSplitSymbolAlpha | Same as `TokenBigram` except that continuous alphabetical characters are not treated as a token, but tokenised in bigram. |
| TokenDelimit | Tokenises by splitting on white spaces. |
| TokenDelimitNull | Tokenises by splitting on null characters (\0). |
| TokenMecab | Tokenise using MeCab. Required Groonga to be buillt with MeCab support. |
| TokenTrigram | Tokenises in trigrams but continuous alphabetical characters, numbers or symbols are treated as a token. |
| TokenUnigram | Tokenises in unigrams but continuous alphabetical characters, numbers or symbols are treated as a token. |

 
### Examples

 #### TokenBigram vs TokenBigramSplitSymbol

 `TokenBigram` failing to match partial symbols which `TokenBigramSplitSymbol` matches, since `TokenBigramSplitSymbol` does not treat continuous symbols as a token.

 
```
DROP TABLE ft_mroonga;
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy) COMMENT 'parser "TokenBigram"') 
  ENGINE=Mroonga;
INSERT INTO ft_mroonga(copy) VALUES ('Once upon a time'),   
  ('There was a wicked witch'), 
  ('Who ate everybody up'), 
  ('She met a wicked, wicked witch'), 
  ('A really wicked, wicked witch!!?!');
SELECT * FROM ft_mroonga WHERE MATCH(copy) AGAINST('!?');
Empty set (0.00 sec)

DROP TABLE ft_mroonga;
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy) COMMENT 'parser "TokenBigramSplitSymbol"') 
  ENGINE=Mroonga;
INSERT INTO ft_mroonga(copy) VALUES ('Once upon a time'),   
  ('There was a wicked witch'), 
  ('Who ate everybody up'), 
  ('She met a wicked, wicked witch'), 
  ('A really wicked, wicked witch!!?!');
SELECT * FROM ft_mroonga WHERE MATCH(copy) AGAINST('!?');
+-----------------------------------+
| copy                              |
+-----------------------------------+
| A really wicked, wicked witch!!?! |
+-----------------------------------+

```

#### TokenBigram vs TokenBigramSplitSymbolAlpha

 
```
DROP TABLE ft_mroonga;
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy) COMMENT 'parser "TokenBigram"') 
  ENGINE=Mroonga;
INSERT INTO ft_mroonga(copy) VALUES ('Once upon a time'),   
  ('There was a wicked witch'), 
  ('Who ate everybody up'), 
  ('She met a wicked, wicked witch'), 
  ('A really wicked, wicked witch!!?!');
SELECT * FROM ft_mroonga WHERE MATCH(copy) AGAINST('ick');
Empty set (0.00 sec)

DROP TABLE ft_mroonga;
CREATE TABLE ft_mroonga(copy TEXT,FULLTEXT(copy) COMMENT 'parser "TokenBigramSplitSymbolAlpha"') 
  ENGINE=Mroonga;
INSERT INTO ft_mroonga(copy) VALUES ('Once upon a time'),   
  ('There was a wicked witch'), 
  ('Who ate everybody up'), 
  ('She met a wicked, wicked witch'), 
  ('A really wicked, wicked witch!!?!');
SELECT * FROM ft_mroonga WHERE MATCH(copy) AGAINST('ick');
+-----------------------------------+
| copy                              |
+-----------------------------------+
| There was a wicked witch          |
| She met a wicked, wicked witch    |
| A really wicked, wicked witch!!?! |
+-----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga-overview/>

Information Schema MROONGA\_STATS Table
=======================================

    The [Information Schema](../information_schema/index) `MROONGA_STATS` table only exists if the [Mroonga](../mroonga/index) storage engine is installed, and contains information about its activities.

 


| Column | Description |
| --- | --- |
| `VERSION` | Mroonga version. |
| `rows_written` | Number of rows written into Mroonga tables. |
| `rows_read` | Number of rows read from all Mroonga tables. |

 
This table always contains 1 row.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-mroonga_stats-table/>

InnoDB Online DDL Operations with the NOCOPY Alter Algorithm
============================================================

    Supported Operations by Inheritance
-----------------------------------

 When the [ALGORITHM](../alter-table/index#algorithm) clause is set to `NOCOPY`, the supported operations are a superset of the operations that are supported when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `INSTANT`.

 Therefore, when the [ALGORITHM](../alter-table/index#algorithm) clause is set to `NOCOPY`, some operations are supported by inheritance. See the following additional pages for more information about these supported operations:

 * [InnoDB Online DDL Operations with ALGORITHM=INSTANT](../innodb-online-ddl-operations-with-algorithminstant/index)

 Column Operations
-----------------

 ### `ALTER TABLE ... ADD COLUMN`

 In [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) and later, InnoDB supports adding columns to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... ADD COLUMN](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-add-column) for more information.

 This applies to [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP COLUMN`

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, InnoDB supports dropping columns from a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... DROP COLUMN](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-drop-column) for more information.

 This applies to [ALTER TABLE ... DROP COLUMN](../alter-table/index#drop-column) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... MODIFY COLUMN`

 This applies to [ALTER TABLE ... MODIFY COLUMN](../alter-table/index#modify-column) for [InnoDB](../innodb/index) tables.

 #### Reordering Columns

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, InnoDB supports reordering columns within a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Reordering Columns](../innodb-online-ddl-operations-with-algorithminstant/index#reordering-columns) for more information.

 #### Changing the Data Type of a Column

 InnoDB does **not** support modifying a column's data type with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in most cases. There are a few exceptions in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Changing the Data Type of a Column](../innodb-online-ddl-operations-with-algorithminstant/index#changing-the-data-type-of-a-column) for more information.

 #### Changing a Column to NULL

 In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, InnoDB supports modifying a column to allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Changing a Column to NULL](../innodb-online-ddl-operations-with-algorithminstant/index#changing-a-column-to-null) for more information.

 #### Changing a Column to NOT NULL

 InnoDB does **not** support modifying a column to **not** allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=REDUNDANT;

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab MODIFY COLUMN c varchar(50) NOT NULL;
ERROR 1845 (0A000): ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE

```

#### Adding a New `ENUM` Option

 InnoDB supports adding a new [ENUM](../enum/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Adding a New ENUM Option](../innodb-online-ddl-operations-with-algorithminstant/index#adding-a-new-enum-option) for more information.

 #### Adding a New `SET` Option

 InnoDB supports adding a new [SET](../set-data-type/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Adding a New SET Option](../innodb-online-ddl-operations-with-algorithminstant/index#adding-a-new-set-option) for more information.

 #### Removing System Versioning from a Column

 In [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/) and later, InnoDB supports removing [system versioning](../system-versioned-tables/index) from a column with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Removing System Versioning from a Column](../innodb-online-ddl-operations-with-algorithminstant/index#removing-system-versioning-from-a-column) for more information.

 ### `ALTER TABLE ... ALTER COLUMN`

 This applies to [ALTER TABLE ... ALTER COLUMN](../alter-table/index#alter-column) for [InnoDB](../innodb/index) tables.

 #### Setting a Column's Default Value

 InnoDB supports modifying a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Setting a Column's Default Value](../innodb-online-ddl-operations-with-algorithminstant/index#setting-a-columns-default-value) for more information.

 #### Removing a Column's Default Value

 InnoDB supports removing a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: Removing a Column's Default Value](../innodb-online-ddl-operations-with-algorithminstant/index#removing-a-columns-default-value) for more information.

 ### `ALTER TABLE ... CHANGE COLUMN`

 InnoDB supports renaming a column with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... CHANGE COLUMN](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-change-column) for more information.

 This applies to [ALTER TABLE ... CHANGE COLUMN](../alter-table/index#change-column) for [InnoDB](../innodb/index) tables.

 Index Operations
----------------

 ### `ALTER TABLE ... ADD PRIMARY KEY`

 InnoDB does **not** support adding a primary key to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int,
   b varchar(50),
   c varchar(50)
);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ADD PRIMARY KEY (a);
ERROR 1845 (0A000): ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ADD PRIMARY KEY](../alter-table/index#add-primary-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP PRIMARY KEY`

 InnoDB does **not** support dropping a primary key with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab DROP PRIMARY KEY;
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: Dropping a primary key is not allowed without also adding a new primary key. Try ALGORITHM=COPY

```

This applies to [ALTER TABLE ... DROP PRIMARY KEY](../alter-table/index#drop-primary-key) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... ADD INDEX` and `CREATE INDEX`

 This applies to [ALTER TABLE ... ADD INDEX](../alter-table/index#add-index) and [CREATE INDEX](../create-index/index) for [InnoDB](../innodb/index) tables.

 #### Adding a Plain Index

 InnoDB supports adding a plain index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ADD INDEX b_index (b);
Query OK, 0 rows affected (0.009 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
CREATE INDEX b_index ON tab (b);
Query OK, 0 rows affected (0.009 sec)

```

#### Adding a Fulltext Index

 InnoDB supports adding a [FULLTEXT](../full-text-indexes/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 However, there are some limitations, such as:

 * Adding a [FULLTEXT](../full-text-indexes/index) index to a table that does not have a user-defined `FTS_DOC_ID` column will require the table to be rebuilt once. When the table is rebuilt, the system adds a hidden `FTS_DOC_ID` column. This initial operation will have to be performed with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`.From that point forward, adding additional [FULLTEXT](../full-text-indexes/index) indexes to the same table will not require the table to be rebuilt, and [ALGORITHM](../alter-table/index#algorithm) can be set to `NOCOPY`.

 * Only one [FULLTEXT](../full-text-indexes/index) index may be added at a time when [ALGORITHM](../alter-table/index#algorithm) is set to `NOCOPY`.

 This operation supports a read-only locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `SHARED`. When this strategy is used, read-only concurrent DML is permitted. 

 For example, this succeeds, but the first operation requires the table to be rebuilt [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`, so that the hidden `FTS_DOC_ID` column can be added:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.043 sec)

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ADD FULLTEXT INDEX c_index (c);
Query OK, 0 rows affected (0.017 sec)

```

And this succeeds in the same way as above:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
CREATE FULLTEXT INDEX b_index ON tab (b);
Query OK, 0 rows affected (0.048 sec)

SET SESSION alter_algorithm='NOCOPY';
CREATE FULLTEXT INDEX c_index ON tab (c);
Query OK, 0 rows affected (0.016 sec)

```

But this second command fails, because only one [FULLTEXT](../full-text-indexes/index) index can be added at a time:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.041 sec)

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ADD FULLTEXT INDEX c_index (c), ADD FULLTEXT INDEX d_index (d);
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: InnoDB presently supports one FULLTEXT index creation at a time. Try ALGORITHM=COPY

```

#### Adding a Spatial Index

 InnoDB supports adding a [SPATIAL](../spatial-index/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 This operation supports a read-only locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `SHARED`. When this strategy is used, read-only concurrent DML is permitted. 

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ADD SPATIAL INDEX c_index (c);
Query OK, 0 rows affected (0.005 sec)

```

And this succeeds in the same way as above:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='NOCOPY';
CREATE SPATIAL INDEX c_index ON tab (c);
Query OK, 0 rows affected (0.005 sec)

```

### 
`ALTER TABLE ... DROP INDEX` and `DROP INDEX`

 InnoDB supports dropping indexes from a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... DROP INDEX and DROP INDEX](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-drop-index-and-drop-index) for more information.

 This applies to [ALTER TABLE ... DROP INDEX](../alter-table/index#drop-index) and [DROP INDEX](../drop-index/index) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ADD FOREIGN KEY`

 InnoDB does supports adding foreign key constraints to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`. In order to add a new foreign key constraint to a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`, the [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) system variable needs to be set to `OFF`. If it is set to `ON`, then `ALGORITHM=COPY` is required.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int
);

CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab1 ADD FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a);
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: Adding foreign keys needs foreign_key_checks=OFF. Try ALGORITHM=COPY

```

But this succeeds:

 
```
CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int
);

CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION foreign_key_checks=OFF;
SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab1 ADD FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a);
Query OK, 0 rows affected (0.011 sec)

```

This applies to [ALTER TABLE ... ADD FOREIGN KEY](../alter-table/index#add-foreign-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP FOREIGN KEY`

 InnoDB supports dropping foreign key constraints from a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... DROP FOREIGN KEY](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-drop-foreign-key) for more information.

 This applies to [ALTER TABLE ... DROP FOREIGN KEY](../alter-table/index#drop-foreign-key) for [InnoDB](../innodb/index) tables.

 Table Operations
----------------

 ### `ALTER TABLE ... AUTO_INCREMENT=...`

 InnoDB supports changing a table's [AUTO\_INCREMENT](../auto_increment/index) value with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... AUTO\_INCREMENT=...](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-auto_increment) for more information.

 This applies to [ALTER TABLE ... AUTO\_INCREMENT=...](../create-table/index#auto_increment) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ROW_FORMAT=...`

 InnoDB does **not** support changing a table's [row format](../innodb-storage-formats/index) with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=DYNAMIC;

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ROW_FORMAT=COMPRESSED;
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ROW\_FORMAT=...](../create-table/index#row_format) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... KEY_BLOCK_SIZE=...`

 InnoDB does **not** support changing a table's [KEY\_BLOCK\_SIZE](../innodb-storage-formats/index#using-the-compressed-row-format) with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=COMPRESSED
  KEY_BLOCK_SIZE=4;

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab KEY_BLOCK_SIZE=2;
ERROR 1846 (0A000): ALGORITHM=NOCOPY is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE

```

This applies to [KEY\_BLOCK\_SIZE=...](../create-table/index#key_block_size) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... PAGE_COMPRESSED=1` and `ALTER TABLE ... PAGE_COMPRESSION_LEVEL=...`

 In [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) and later, InnoDB supports setting a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value to `1` with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 InnoDB does **not** support changing a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value from `1` to `0` with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 In these versions, InnoDB also supports changing a table's [PAGE\_COMPRESSION\_LEVEL](../create-table/index#page_compression_level) value with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause is set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... PAGE\_COMPRESSED=1 and ALTER TABLE ... PAGE\_COMPRESSION\_LEVEL=...](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-page_compressed1-and-alter-table-page_compression_level) for more information.

 This applies to [ALTER TABLE ... PAGE\_COMPRESSED=...](../create-table/index#page_compressed) and [ALTER TABLE ... PAGE\_COMPRESSION\_LEVEL=...](../create-table/index#page_compression_level) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP SYSTEM VERSIONING`

 InnoDB does **not** support dropping [system versioning](../system-versioned-tables/index) from a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) WITH SYSTEM VERSIONING;

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab DROP SYSTEM VERSIONING;
ERROR 1845 (0A000): ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... DROP SYSTEM VERSIONING](../alter-table/index#drop-system-versioning) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP CONSTRAINT`

 In [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) and later, InnoDB supports dropping a [CHECK](../constraint/index#check-constraints) constraint from a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... DROP CONSTRAINT](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-drop-constraint) for more information.

 This applies to [ALTER TABLE ... DROP CONSTRAINT](../alter-table/index#drop-constraint) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... FORCE`

 InnoDB does **not** support forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab FORCE;
ERROR 1845 (0A000): ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... FORCE](../alter-table/index#force) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ENGINE=InnoDB`

 InnoDB does **not** support forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab ENGINE=InnoDB;
ERROR 1845 (0A000): ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ENGINE=InnoDB](../create-table/index#storage-engine) for [InnoDB](../innodb/index) tables.

 ### `OPTIMIZE TABLE ...`

 InnoDB does **not** support optimizing a table with with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SHOW GLOBAL VARIABLES WHERE Variable_name IN('innodb_defragment', 'innodb_optimize_fulltext_only');
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_defragment             | OFF   |
| innodb_optimize_fulltext_only | OFF   |
+-------------------------------+-------+
2 rows in set (0.001 sec)

SET SESSION alter_algorithm='NOCOPY';
OPTIMIZE TABLE tab;
+---------+----------+----------+-----------------------------------------------------------------------------+
| Table   | Op       | Msg_type | Msg_text                                                                    |
+---------+----------+----------+-----------------------------------------------------------------------------+
| db1.tab | optimize | note     | Table does not support optimize, doing recreate + analyze instead           |
| db1.tab | optimize | error    | ALGORITHM=NOCOPY is not supported for this operation. Try ALGORITHM=INPLACE |
| db1.tab | optimize | status   | Operation failed                                                            |
+---------+----------+----------+-----------------------------------------------------------------------------+
3 rows in set, 1 warning (0.002 sec)

```

This applies to [OPTIMIZE TABLE](../optimize-table/index) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... RENAME TO` and `RENAME TABLE ...`

 InnoDB supports renaming a table with [ALGORITHM](../alter-table/index#algorithm) set to `NOCOPY` in the cases where the operation supports having the [ALGORITHM](../alter-table/index#algorithm) clause set to `INSTANT`.

 See [InnoDB Online DDL Operations with ALGORITHM=INSTANT: ALTER TABLE ... RENAME TO and RENAME TABLE ...](../innodb-online-ddl-operations-with-algorithminstant/index#alter-table-rename-to-and-rename-table) for more information.

 This applies to [ALTER TABLE ... RENAME TO](../alter-table/index#rename-to) and [RENAME TABLE](../rename-table/index) for [InnoDB](../innodb/index) tables.

 Limitations
-----------

 ### Limitations Related to Generated (Virtual and Persistent/Stored) Columns

 [Generated columns](../generated-columns/index) do not currently support online DDL for all of the same operations that are supported for "real" columns.

 See [Generated (Virtual and Persistent/Stored) Columns: Statement Support](../generated-columns/index#statement-support) for more information on the limitations.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-online-ddl-operations-with-algorithmnocopy/>

BACKUP STAGE
============

    
**MariaDB starting with [10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)**The `BACKUP STAGE` commands were introduced in [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).

  The `BACKUP STAGE` commands are a set of commands to make it possible to make an efficient external backup tool. 

 Syntax
------

 
```
BACKUP STAGE [START | FLUSH | BLOCK_DDL | BLOCK_COMMIT | END ]

```

In the following text, a transactional table means InnoDB or "InnoDB-like engine with redo log that can lock redo purges and can be copied without locks by an outside process".

 Goals with BACKUP STAGE Commands
--------------------------------

 * To be able to do a majority of the backup with the minimum possible server locks. Especially for transactional tables (InnoDB, MyRocks etc) there is only need for a very short block of new commits while copying statistics and log tables.
* DDL are only needed to be blocked for a very short duration of the backup while [mariabackup](../mariabackup/index) is copying the tables affected by DDL during the initial part of the backup.
* Most non transactional tables (those that are not in use) will be copied during `BACKUP STAGE START`. The exceptions are system statistic and log tables that are not blocked during the backup until `BLOCK_COMMIT`.
* Should work efficiently with backup tools that use disk snapshots.
* Should work as efficiently as possible for all table types that store data on the local disks.
* As little copying as possible under higher level stages/locks. For example, .frm (dictionary) and .trn (trigger) files should be copying while copying the table data.

 
`BACKUP STAGE` Commands
------------------------

 ### `BACKUP STAGE START`

 The `START` stage is designed for the following tasks:

 * Blocks purge of redo files for storage engines that needs this (Aria)
* Start logging of DDL commands into 'datadir'/ddl.log. This may take a short time as the command has to wait until there are no active DDL commands.

 ### `BACKUP STAGE FLUSH`

 The `FLUSH` stage is designed for the following tasks:

 * FLUSH all changes for inactive non-transactional tables, except for statistics and log tables.
* Close all tables that are not in use, to ensure they are marked as closed for the backup.
* BLOCK all new write locks for all non transactional tables (except statistics and log tables). The command will not wait for tables that are in use by read-only transactions.

 DDLs don't have to be blocked at this stage as they can't cause the table to be in an inconsistent state. This is true also for non-transactional tables.

 ### `BACKUP STAGE BLOCK_DDL`

 The `BLOCK_DDL` stage is designed for the following tasks:

 * Wait for all statements using write locked non-transactional tables to end.
* Blocks [CREATE TABLE](../create-table/index), [DROP TABLE](../drop-table/index), [TRUNCATE TABLE](../truncate-table/index), and [RENAME TABLE](../rename-table/index).
* Blocks also start off a **new** [ALTER TABLE](../alter-table/index) and the **final rename phase** of [ALTER TABLE](../alter-table/index). Running ALTER TABLES are not blocked.

 ### `BACKUP STAGE BLOCK_COMMIT`

 The `BLOCK_COMMIT` stage is designed for the following tasks:

 * Lock the binary log and commit/rollback to ensure that no changes are committed to any tables. If there are active commits or data to be copied to the binary log this will be allowed to finish. Active transactions will not affect `BLOCK_COMMIT`.
* This doesn't lock temporary tables that are not used by replication. However these will be blocked when it's time to write to the binary log.
* Lock system log tables and statistics tables, flush them and mark them closed.

 When the `BLOCK_COMMIT`'s stages return, this is the 'backup time'. Everything committed will be in the backup and everything not committed will roll back.

 Transactional engines will continue to do changes to the redo log during the `BLOCK COMMIT` stage, but this is not important as all of these will roll back later as the changes will not be committed.

 ### `BACKUP STAGE END`

 The `END` stage is designed for the following tasks:

 * End DDL logging
* Free resources

 Using `BACKUP STAGE` Commands with Backup Tools
-----------------------------------------------

 ### Using `BACKUP STAGE` Commands with Mariabackup

 The `BACKUP STAGE` commands are a set of commands to make it possible to make an efficient external backup tool. How [Mariabackup](../mariabackup/index) uses these commands depends on whether you are using the version that is bundled with MariaDB Community Server or the version that is bundled with [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/). See [Mariabackup and BACKUP STAGE Commands](../mariabackup-and-backup-stage-commands/index) for some examples on how [Mariabackup](../mariabackup/index) uses these commands.

 
If you would like to use a version of [Mariabackup](../mariabackup/index) that uses the [BACKUP STAGE](index) commands in an efficient way, then one option is to use [MariaDB Enterprise Backup](https://mariadb.com/docs/usage/mariadb-enterprise-backup/) that is bundled with [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/).

 
### Using `BACKUP STAGE` Commands with Storage Snapshots

 The `BACKUP STAGE` commands are a set of commands to make it possible to make an efficient external backup tool. These commands could even be used by tools that perform backups by taking a snapshot of a file system, SAN, or some other kind of storage device. See [Storage Snapshots and BACKUP STAGE Commands](../storage-snapshots-and-backup-stage-commands/index) for some examples on how to use each `BACKUP STAGE` command in an efficient way.

 Privileges
----------

 `BACKUP STAGE` requires the [RELOAD](../grant/index) privilege.

 Notes
-----

 * Only one connection can run `BACKUP STAGE START`. If a second connection tries, it will wait until the first one has executed `BACKUP STAGE END`.
* If the user skips a `BACKUP STAGE`, then all intermediate backup stages will automatically be run. This will allow us to add new stages within the `BACKUP STAGE` hierarchy in the future with even more precise locks without causing problems for tools using an earlier version of the `BACKUP STAGE` implementation.
* One can use the [max\_statement\_time](../server-system-variables/index#max_statement_time) or [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) system variables to ensure that a `BACKUP STAGE` command doesn't block the server too long.
* DDL logging will only be available in [MariaDB Enterprise Server](https://mariadb.com/docs/products/mariadb-enterprise-server/) 10.2 and later.
* A disconnect will automatically release backup stages.
* There is no easy way to see which is the current stage.

 See Also
--------

 * [BACKUP LOCK](../backup-lock/index) Locking a table from DDL's.
* [MDEV-5336](https://jira.mariadb.org/browse/MDEV-5336). Implement BACKUP STAGE for safe external backups.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-stage/>

InnoDB Online DDL Operations with the INSTANT Alter Algorithm
=============================================================

    Column Operations
-----------------

 ### `ALTER TABLE ... ADD COLUMN`

 In [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) and later, InnoDB supports adding columns to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the new column is the last column in the table. See [MDEV-11369](https://jira.mariadb.org/browse/MDEV-11369) for more information. If the table has a hidden `FTS_DOC_ID` column is present, then this is not supported.

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, InnoDB supports adding columns to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, regardless of where in the column list the new column is added.

 When this operation is performed with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, the tablespace file will have a non-canonical storage format. See [Non-canonical Storage Format Caused by Some Operations](#non-canonical-storage-format-caused-by-some-operations) for more information.

 With the exception of adding an [auto-increment](../auto_increment/index) column, this operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD COLUMN c varchar(50);
Query OK, 0 rows affected (0.004 sec)

```

And this succeeds in [MariaDB 10.4](../what-is-mariadb-104/index) and later:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD COLUMN c varchar(50) AFTER a;
Query OK, 0 rows affected (0.004 sec)

```

This applies to [ALTER TABLE ... ADD COLUMN](../alter-table/index#add-column) for [InnoDB](../innodb/index) tables.

 See [Instant ADD COLUMN for InnoDB](../instant-add-column-for-innodb/index) for more information.

 ### `ALTER TABLE ... DROP COLUMN`

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, InnoDB supports dropping columns from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. See [MDEV-15562](https://jira.mariadb.org/browse/MDEV-15562) for more information.

 When this operation is performed with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, the tablespace file will have a non-canonical storage format. See [Non-canonical Storage Format Caused by Some Operations](#non-canonical-storage-format-caused-by-some-operations) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab DROP COLUMN c;
Query OK, 0 rows affected (0.004 sec)

```

This applies to [ALTER TABLE ... DROP COLUMN](../alter-table/index#drop-column) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... MODIFY COLUMN`

 This applies to [ALTER TABLE ... MODIFY COLUMN](../alter-table/index#modify-column) for [InnoDB](../innodb/index) tables.

 #### Reordering Columns

 In [MariaDB 10.4](../what-is-mariadb-104/index) and later, InnoDB supports reordering columns within a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. See [MDEV-15562](https://jira.mariadb.org/browse/MDEV-15562) for more information.

 When this operation is performed with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, the tablespace file will have a non-canonical storage format. See [Non-canonical Storage Format Caused by Some Operations](#non-canonical-storage-format-caused-by-some-operations) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(50) AFTER a;
Query OK, 0 rows affected (0.004 sec)

```

#### Changing the Data Type of a Column

 InnoDB does **not** support modifying a column's data type with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` in most cases. There are some exceptions:

 * InnoDB supports increasing the length of `VARCHAR` columns with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, unless it would require changing the number of bytes requires to represent the column's length. A `VARCHAR` column that is between 0 and 255 bytes in size requires 1 byte to represent its length, while a `VARCHAR` column that is 256 bytes or longer requires 2 bytes to represent its length. This means that the length of a column cannot be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the original length was less than 256 bytes, and the new length is 256 bytes or more.

 * In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, InnoDB supports increasing the length of `VARCHAR` columns with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` with no restrictions if the [ROW\_FORMAT](../create-table/index#row_format) table option is set to [REDUNDANT](../innodb-storage-formats/index#redundant). See [MDEV-15563](https://jira.mariadb.org/browse/MDEV-15563) for more information.

 * In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, InnoDB also supports increasing the length of `VARCHAR` columns with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` in a more limited manner if the [ROW\_FORMAT](../create-table/index#row_format) table option is set to [COMPACT](../innodb-storage-formats/index#compact), [DYNAMIC](../innodb-storage-formats/index#dynamic), or [COMPRESSED](../innodb-storage-formats/index#compressed). In this scenario, the following limitations apply:
	+ The length can be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the original length of the column is 127 bytes or less, and the new length of the column is 256 bytes or more.
	+ The length can be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the original length of the column is 255 bytes or less, and the new length of the column is still 255 bytes or less.
	+ The length can be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the original length of the column is 256 bytes or more, and the new length of the column is still 256 bytes or more.
	+ The length can **not** be increased with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the original length was between 128 bytes and 255 bytes, and the new length is 256 bytes or more.
	+ See [MDEV-15563](https://jira.mariadb.org/browse/MDEV-15563) for more information.

 The supported operations in this category support the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c int;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

But this succeeds because the original length of the column is less than 256 bytes, and the new length is still less than 256 bytes:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) CHARACTER SET=latin1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(100);
Query OK, 0 rows affected (0.005 sec)

```

But this fails because the original length of the column is between 128 bytes and 255 bytes, and the new length is greater than 256 bytes:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(255)
) CHARACTER SET=latin1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(256);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

But this succeeds in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later because the table has `ROW_FORMAT=REDUNDANT`:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(200)
) ROW_FORMAT=REDUNDANT;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(300);
Query OK, 0 rows affected (0.004 sec)

```

And this succeeds in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later because the table has `ROW_FORMAT=DYNAMIC` and the column's original length is 127 bytes or less:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(127)
) ROW_FORMAT=DYNAMIC
  CHARACTER SET=latin1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(300);
Query OK, 0 rows affected (0.003 sec)

```

And this succeeds in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later because the table has `ROW_FORMAT=COMPRESSED` and the column's original length is 127 bytes or less:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(127)
) ROW_FORMAT=COMPRESSED
  CHARACTER SET=latin1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(300);
Query OK, 0 rows affected (0.003 sec)

```

But this fails even in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later because the table has `ROW_FORMAT=DYNAMIC` and the column's original length is between 128 bytes and 255 bytes:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(128)
) ROW_FORMAT=DYNAMIC
  CHARACTER SET=latin1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(300);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Changing a Column to NULL

 In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, InnoDB supports modifying a column to allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT` if the [ROW\_FORMAT](../create-table/index#row_format) table option is set to [REDUNDANT](../innodb-storage-formats/index#redundant). See [MDEV-15563](https://jira.mariadb.org/browse/MDEV-15563) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) NOT NULL
) ROW_FORMAT=REDUNDANT;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(50) NULL;
Query OK, 0 rows affected (0.004 sec)

```

#### Changing a Column to NOT NULL

 InnoDB does **not** support modifying a column to **not** allow [NULL](../create-table/index#null-and-not-null) values with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=REDUNDANT;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(50) NOT NULL;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE

```

#### Adding a New `ENUM` Option

 InnoDB supports adding a new [ENUM](../enum/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. In order to add a new [ENUM](../enum/index) option with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, the following requirements must be met:

 * It must be added to the end of the list.
* The storage requirements must not change.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c ENUM('red', 'green')
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c ENUM('red', 'green', 'blue');
Query OK, 0 rows affected (0.002 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c ENUM('red', 'green')
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c ENUM('red', 'blue', 'green');
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Adding a New `SET` Option

 InnoDB supports adding a new [SET](../set-data-type/index) option to a column with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. In order to add a new [SET](../set-data-type/index) option with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, the following requirements must be met:

 * It must be added to the end of the list.
* The storage requirements must not change.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c SET('red', 'green')
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c SET('red', 'green', 'blue');
Query OK, 0 rows affected (0.002 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c SET('red', 'green')
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c SET('red', 'blue', 'green');
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

#### Removing System Versioning from a Column

 In [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/) and later, InnoDB supports removing [system versioning](../system-versioned-tables/index) from a column with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. In order for this to work, the [system\_versioning\_alter\_history](../system-versioned-tables/index#system_versioning_alter_history) system variable must be set to `KEEP`. See [MDEV-16330](https://jira.mariadb.org/browse/MDEV-16330) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) WITH SYSTEM VERSIONING
);

SET SESSION system_versioning_alter_history='KEEP';
SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN c varchar(50) WITHOUT SYSTEM VERSIONING;
Query OK, 0 rows affected (0.004 sec)

```

### `ALTER TABLE ... ALTER COLUMN`

 This applies to [ALTER TABLE ... ALTER COLUMN](../alter-table/index#alter-column) for [InnoDB](../innodb/index) tables.

 #### Setting a Column's Default Value

 InnoDB supports modifying a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ALTER COLUMN c SET DEFAULT 'No value explicitly provided.';
Query OK, 0 rows affected (0.003 sec)

```

#### Removing a Column's Default Value

 InnoDB supports removing a column's [DEFAULT](../create-table/index#default-column-option) value with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50) DEFAULT 'No value explicitly provided.'
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ALTER COLUMN c DROP DEFAULT;
Query OK, 0 rows affected (0.002 sec)

```

### `ALTER TABLE ... CHANGE COLUMN`

 InnoDB supports renaming a column with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`, unless the column's data type or attributes changed in addition to the name.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab CHANGE COLUMN c str varchar(50);
Query OK, 0 rows affected (0.004 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab CHANGE COLUMN c num int;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY

```

This applies to [ALTER TABLE ... CHANGE COLUMN](../alter-table/index#change-column) for [InnoDB](../innodb/index) tables.

 Index Operations
----------------

 ### `ALTER TABLE ... ADD PRIMARY KEY`

 InnoDB does **not** support adding a primary key to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int,
   b varchar(50),
   c varchar(50)
);

SET SESSION sql_mode='STRICT_TRANS_TABLES';
SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD PRIMARY KEY (a);
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ADD PRIMARY KEY](../alter-table/index#add-primary-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP PRIMARY KEY`

 InnoDB does **not** support dropping a primary key with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab DROP PRIMARY KEY;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Dropping a primary key is not allowed without also adding a new primary key. Try ALGORITHM=COPY

```

This applies to [ALTER TABLE ... DROP PRIMARY KEY](../alter-table/index#drop-primary-key) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... ADD INDEX` and `CREATE INDEX`

 This applies to [ALTER TABLE ... ADD INDEX](../alter-table/index#add-index) and [CREATE INDEX](../create-index/index) for [InnoDB](../innodb/index) tables.

 #### Adding a Plain Index

 InnoDB does **not** support adding a plain index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD INDEX b_index (b);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

And this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
CREATE INDEX b_index ON tab (b);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

#### Adding a Fulltext Index

 InnoDB does **not** support adding a [FULLTEXT](../full-text-indexes/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD FULLTEXT INDEX b_index (b);
Query OK, 0 rows affected (0.042 sec)

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD FULLTEXT INDEX c_index (c);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

And this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INPLACE';
CREATE FULLTEXT INDEX b_index ON tab (b);
Query OK, 0 rows affected (0.040 sec)

SET SESSION alter_algorithm='INSTANT';
CREATE FULLTEXT INDEX c_index ON tab (c);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

#### Adding a Spatial Index

 InnoDB does **not** support adding a [SPATIAL](../spatial-index/index) index to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example, this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ADD SPATIAL INDEX c_index (c);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

And this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c GEOMETRY NOT NULL
);

SET SESSION alter_algorithm='INSTANT';
CREATE SPATIAL INDEX c_index ON tab (c);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

### `ALTER TABLE ... ADD FOREIGN KEY`

 InnoDB does **not** support adding foreign key constraints to a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int
);

CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

SET SESSION foreign_key_checks=OFF;
SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab1 ADD FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a);
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY

```

This applies to [ALTER TABLE ... ADD FOREIGN KEY](../alter-table/index#add-foreign-key) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP FOREIGN KEY`

 InnoDB supports dropping foreign key constraints from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab2 (
   a int PRIMARY KEY,
   b varchar(50)
);

CREATE OR REPLACE TABLE tab1 (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   d int,
   FOREIGN KEY tab2_fk (d) REFERENCES tab2 (a)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab1 DROP FOREIGN KEY tab2_fk; 
Query OK, 0 rows affected (0.004 sec)

```

This applies to [ALTER TABLE ... DROP FOREIGN KEY](../alter-table/index#drop-foreign-key) for [InnoDB](../innodb/index) tables.

 Table Operations
----------------

 ### `ALTER TABLE ... AUTO_INCREMENT=...`

 InnoDB supports changing a table's [AUTO\_INCREMENT](../auto_increment/index) value with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab AUTO_INCREMENT=100;
Query OK, 0 rows affected (0.002 sec)

```

This applies to [ALTER TABLE ... AUTO\_INCREMENT=...](../create-table/index#auto_increment) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ROW_FORMAT=...`

 InnoDB does **not** support changing a table's [row format](../innodb-storage-formats/index) with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=DYNAMIC;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ROW_FORMAT=COMPRESSED;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ROW\_FORMAT=...](../create-table/index#row_format) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... KEY_BLOCK_SIZE=...`

 InnoDB does **not** support changing a table's [KEY\_BLOCK\_SIZE](../innodb-storage-formats/index#using-the-compressed-row-format) with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) ROW_FORMAT=COMPRESSED
  KEY_BLOCK_SIZE=4;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab KEY_BLOCK_SIZE=2;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE

```

This applies to [KEY\_BLOCK\_SIZE=...](../create-table/index#key_block_size) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... PAGE_COMPRESSED=1` and `ALTER TABLE ... PAGE_COMPRESSION_LEVEL=...`

 In [MariaDB 10.3.10](https://mariadb.com/kb/en/mariadb-10310-release-notes/) and later, InnoDB supports setting a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value to `1` with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. InnoDB does **not** support changing a table's [PAGE\_COMPRESSED](../create-table/index#page_compressed) value from `1` to `0` with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 In these versions, InnoDB also supports changing a table's [PAGE\_COMPRESSION\_LEVEL](../create-table/index#page_compression_level) value with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 See [MDEV-16328](https://jira.mariadb.org/browse/MDEV-16328) for more information.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab PAGE_COMPRESSED=1;
Query OK, 0 rows affected (0.004 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) PAGE_COMPRESSED=1
  PAGE_COMPRESSION_LEVEL=5;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab PAGE_COMPRESSION_LEVEL=4;
Query OK, 0 rows affected (0.004 sec)

```

But this fails:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) PAGE_COMPRESSED=1;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab PAGE_COMPRESSED=0;
ERROR 1846 (0A000): ALGORITHM=INSTANT is not supported. Reason: Changing table options requires the table to be rebuilt. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... PAGE\_COMPRESSED=...](../create-table/index#page_compressed) and [ALTER TABLE ... PAGE\_COMPRESSION\_LEVEL=...](../create-table/index#page_compression_level) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP SYSTEM VERSIONING`

 InnoDB does **not** support dropping [system versioning](../system-versioned-tables/index) from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
) WITH SYSTEM VERSIONING;

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab DROP SYSTEM VERSIONING;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... DROP SYSTEM VERSIONING](../alter-table/index#drop-system-versioning) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... DROP CONSTRAINT`

 In [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) and later, InnoDB supports dropping a [CHECK](../constraint/index#check-constraints) constraint from a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`. See [MDEV-16331](https://jira.mariadb.org/browse/MDEV-16331) for more information.

 This operation supports the non-locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `NONE`. When this strategy is used, all concurrent DML is permitted.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50),
   CONSTRAINT b_not_empty CHECK (b != '')
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab DROP CONSTRAINT b_not_empty;
Query OK, 0 rows affected (0.002 sec)

```

This applies to [ALTER TABLE ... DROP CONSTRAINT](../alter-table/index#drop-constraint) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... FORCE`

 InnoDB does **not** support forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab FORCE;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... FORCE](../alter-table/index#force) for [InnoDB](../innodb/index) tables.

 ### `ALTER TABLE ... ENGINE=InnoDB`

 InnoDB does **not** support forcing a table rebuild with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab ENGINE=InnoDB;
ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE

```

This applies to [ALTER TABLE ... ENGINE=InnoDB](../create-table/index#storage-engine) for [InnoDB](../innodb/index) tables.

 ### `OPTIMIZE TABLE ...`

 InnoDB does **not** support optimizing a table with with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 For example:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SHOW GLOBAL VARIABLES WHERE Variable_name IN('innodb_defragment', 'innodb_optimize_fulltext_only');
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_defragment             | OFF   |
| innodb_optimize_fulltext_only | OFF   |
+-------------------------------+-------+
2 rows in set (0.001 sec)

SET SESSION alter_algorithm='INSTANT';
OPTIMIZE TABLE tab;
+---------+----------+----------+------------------------------------------------------------------------------+
| Table   | Op       | Msg_type | Msg_text                                                                     |
+---------+----------+----------+------------------------------------------------------------------------------+
| db1.tab | optimize | note     | Table does not support optimize, doing recreate + analyze instead            |
| db1.tab | optimize | error    | ALGORITHM=INSTANT is not supported for this operation. Try ALGORITHM=INPLACE |
| db1.tab | optimize | status   | Operation failed                                                             |
+---------+----------+----------+------------------------------------------------------------------------------+
3 rows in set, 1 warning (0.002 sec)

```

This applies to [OPTIMIZE TABLE](../optimize-table/index) for [InnoDB](../innodb/index) tables.

 ### 
`ALTER TABLE ... RENAME TO` and `RENAME TABLE ...`

 InnoDB supports renaming a table with [ALGORITHM](../alter-table/index#algorithm) set to `INSTANT`.

 This operation supports the exclusive locking strategy. This strategy can be explicitly chosen by setting the [LOCK](../alter-table/index#lock) clause to `EXCLUSIVE`. When this strategy is used, concurrent DML is **not** permitted.

 For example, this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab RENAME TO old_tab;
Query OK, 0 rows affected (0.008 sec)

```

And this succeeds:

 
```
CREATE OR REPLACE TABLE tab (
   a int PRIMARY KEY,
   b varchar(50),
   c varchar(50)
);

SET SESSION alter_algorithm='INSTANT';
RENAME TABLE tab TO old_tab;
Query OK, 0 rows affected (0.008 sec)

```

This applies to [ALTER TABLE ... RENAME TO](../alter-table/index#rename-to) and [RENAME TABLE](../rename-table/index) for [InnoDB](../innodb/index) tables.

 Limitations
-----------

 ### Limitations Related to Generated (Virtual and Persistent/Stored) Columns

 [Generated columns](../generated-columns/index) do not currently support online DDL for all of the same operations that are supported for "real" columns.

 See [Generated (Virtual and Persistent/Stored) Columns: Statement Support](../generated-columns/index#statement-support) for more information on the limitations.

 ### Non-canonical Storage Format Caused by Some Operations

 Some operations cause a table's tablespace file to use a non-canonical storage format when the `INSTANT` algorithm is used. The affected operations include:

 * [Adding a column.](#alter-table-add-column)
* [Dropping a column.](#alter-table-drop-column)
* [Reordering columns.](#reordering-columns)

 These operations require the following non-canonical changes to the storage format:

 * A hidden metadata record at the start of the clustered index is used to store each column's [DEFAULT](../default/index) value. This makes it possible to add new columns that have default values without rebuilding the table.
* A [BLOB](../blob/index) in the hidden metadata record is used to store column mappings. This makes it possible to drop or reorder columns without rebuilding the table. This also makes it possible to add columns to any position or drop columns from any position in the table without rebuilding the table.
* If a column is dropped, old records will contain garbage in that column's former position, and new records will be written with [NULL](../null-values/index) values, empty strings, or dummy values.

 This non-canonical storage format has the potential to incur some performance or storage overhead for all subsequent DML operations. If you notice some issues like this and you want to normalize a table's storage format to avoid this problem, then you can do so by forcing a table rebuild by executing [ALTER TABLE ... FORCE](../alter-table/index#force) with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. For example:

 
```
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab FORCE;
Query OK, 0 rows affected (0.008 sec)

```

However, keep in mind that there are certain scenarios where you may not be able to rebuild the table with [ALGORITHM](../alter-table/index#algorithm) set to `INPLACE`. See [InnoDB Online DDL Operations with ALGORITHM=INPLACE: Limitations](../innodb-online-ddl-operations-with-algorithminplace/index#limitations) for more information on those cases. If you hit one of those scenarios, but you still want to rebuild the table, then you would have to do so with [ALGORITHM](../alter-table/index#algorithm) set to `COPY`.

 ### Known Bugs

 There are some known bugs that could lead to issues when an InnoDB DDL operation is performed using the [INSTANT](../innodb-online-ddl-overview/index#instant-algorithm) algorithm. This algorithm will usually be chosen by default if the operation supports the algorithm.

 The effect of many of these bugs is that the table seems to *forget* that its tablespace file is in the [non-canonical storage format](#non-canonical-storage-format-caused-by-some-operations).

 If you are concerned that a table may be affected by one of these bugs, then your best option would be to normalize the table structure. This can be done by rebuilding the table. For example:

 
```
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab FORCE;
Query OK, 0 rows affected (0.008 sec)

```

If you are concerned about these bugs, and you want to perform an operation that supports the [INSTANT](../innodb-online-ddl-overview/index#algorithminstant) algorithm, but you want to avoid using that algorithm, then you can set the algorithm to [INPLACE](../innodb-online-ddl-overview/index#inplace-algorithm) and add the `FORCE` keyword to the [ALTER TABLE](../alter-table/index) statement:

 
```
SET SESSION alter_algorithm='INPLACE';
ALTER TABLE tab ADD COLUMN c varchar(50), FORCE;

```

#### Closed Bugs

 * [MDEV-20066](https://jira.mariadb.org/browse/MDEV-20066): This bug could cause a table to become corrupt if a column was added instantly. It is fixed in [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/) and [MariaDB 10.4.8](https://mariadb.com/kb/en/mariadb-1048-release-notes/).
* [MDEV-20117](https://jira.mariadb.org/browse/MDEV-20117): This bug could cause a table to become corrupt if a column was dropped instantly. It is fixed in [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-1049-release-notes/).
* [MDEV-19743](https://jira.mariadb.org/browse/MDEV-19743): This bug could cause a table to become corrupt during page reorganization if a column was added instantly. It is fixed in [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) and [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/).
* [MDEV-19783](https://jira.mariadb.org/browse/MDEV-19783): This bug could cause a table to become corrupt if a column was added instantly. It is fixed in [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) and [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/)
* [MDEV-20090](https://jira.mariadb.org/browse/MDEV-20090): This bug could cause a table to become corrupt if columns were added, dropped, or reordered instantly. It is fixed in [MariaDB 10.4.9](https://mariadb.com/kb/en/mariadb-1049-release-notes/).
* [MDEV-18519](https://jira.mariadb.org/browse/MDEV-18519): This bug could cause a table to become corrupt if a column was added instantly. It is fixed in [MariaDB 10.6.9](https://mariadb.com/kb/en/mariadb-1069-release-notes/), [MariaDB 10.7.5](https://mariadb.com/kb/en/mariadb-1075-release-notes/), [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/) and [MariaDB 10.9.2](https://mariadb.com/kb/en/mariadb-1092-release-notes/).
* [MDEV-18519](https://jira.mariadb.org/browse/MDEV-18519): This bug could cause a table to become corrupt if a column was added instantly. This isn't and won't be fixed in versions less than [MariaDB 10.6](../what-is-mariadb-106/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-online-ddl-operations-with-algorithminstant/>

Configuring Sphinx
==================

    Before you can get Sphinx working with the Sphinx Storage Engine on MariaDB, you need to configure it.

 * The default configuration file is called `sphinx.conf`, usually located in `/etc/sphinxsearch` (Debian/Ubuntu), `/etc/sphinx/sphinx.conf.` (Red Hat/CentOS) or `C:\Sphinx\sphinx.conf` (Windows).

 If it doesn't already exist, you can use the sample configuration file, `sphinx.conf.dist`. There is also sample data supplied that we can use for testing. Load the sample data (which creates two tables, `documents` and `tags` in the `test` database), for example:

 `mysql -u test < /usr/local/sphinx/etc/example.sql` (Red Hat, CentOS) `mysql -u test < /usr/share/doc/sphinxsearch/example-conf/example.sql` (Debian/Ubuntu)

 The sample configuration file documents the available options. You will need to make at least a few changes. A MariaDB user with permission to access the database must be created. For example:

 
```
CREATE USER 'sphinx'@localhost 
  IDENTIFIED BY 'sphinx_password';
GRANT SELECT on test.* to 'sphinx'@localhost;

```

Add these details to the `mysql` section of the config file:

 
```
sql_host = localhost 
sql_user = sphinx 
sql_pass = sphinx_password 
sql_db   = test 
sql_port = 3306 

```

On Windows, the `path` and `pid` lines will need to be changed to reflect a valid path, usually as follows:

 
```
path = C:\Sphinx\docsidx
...
pid_file = C:\Sphinx\sphinx.pid

```

The query in the configuration files is the query that will be used for building the index. In the sample data, this is:

 
```
sql_query = \
  SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content \
  FROM documents

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-sphinx/>

Installing and Testing SphinxSE with MariaDB
============================================

    To use [SphinxSE](../sphinx-storage-engine/index) with MariaDB you need to first [download and install Sphinx](../installing-sphinx/index).

 Complete Sphinx documentation is available on the [Sphinx website](http://sphinxsearch.com/docs/). 

 Tips for Installing Sphinx
--------------------------

 ### libexpat

 One library we know you will need on Linux before you can install Sphinx is `libexpat`. If it is not installed, you will get the warning `checking for libexpat... not found`. On Suse the package is called `libexpat-devel`, on Ubuntu the package is called `libexpat1-dev`.

 ### MariaDB detection

 If you run into problems with MariaDB not being detected, use the following options:

 
```
 --with-mysql            compile with MySQL support (default is enabled)
 --with-mysql-includes   path to MySQL header files
 --with-mysql-libs       path to MySQL libraries

```

The above will tell the `configure` script where your MySQL/MariaDB installation is.

 Testing Sphinx
--------------

 After installing Sphinx, you can check that things are working in MariaDB by doing the following:

 
```
cd installation-dir/mysql-test
./mysql-test-run --suite=sphinx

```

If the above test doesn't pass, check the logs in the `'var'` directory. If there is a problem with the sphinx installation, the reason can probably be found in the log file at: `var/log/sphinx.sphinx/searchd/sphinx.log`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-and-testing-sphinxse-with-mariadb/>

Installing OQGRAPH
==================

     The Open Query GRAPH computation engine, or OQGRAPH as the engine itself is called, allows you to handle hierarchies (tree structures) and complex graphs (nodes having many connections in several directions).

 Installation
------------

 The OQGRAPH storage engine exists as a separate package in the repositories for [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) and later. On Ubuntu and Debian the package is called `mariadb-oqgraph-engine-10.0` or `mariadb-plugin-oqgraph`. On Red Hat, CentOS, and Fedora the package is called `MariaDB-oqgraph-engine`. To install the plugin, first install the appropriate package and then install the plugin using the [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index) commands.

 ### Debian and Ubuntu

 On Debian and Ubuntu, install the package as follows:

 
```
sudo apt-get install mariadb-plugin-oqgraph

```

or (for [MariaDB 10.0](../what-is-mariadb-100/index))

 
```
sudo apt-get install mariadb-oqgraph-engine-10.0 

```

### Fedora/Red Hat/CentOS

 Note that OQGRAPH v3 requires libjudy, which is not in the official Red Hat/Fedora repositories. This needs to be installed first, for example:

 
```
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -Uvh epel-release-6-8.noarch.rpm

```

Then install the package, as follows:

 
```
sudo yum install MariaDB-oqgraph-engine

```

### Installing the Plugin

 On either system you can then launch the `mysql` command-line client and install the plugin in MariaDB as follows:

 
```
INSTALL SONAME 'ha_oqgraph';

```

See Also
--------

 More information on this engine is found on the OpenQuery website: <https://openquery.com.au/products/graph-engine>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-oqgraph/>

Table Discovery
===============

    In MariaDB it is not always necessary to run an explicit `CREATE TABLE` statement for a table to appear. Sometimes a table may already exist in the storage engine, but the server does not know about it, because there is no `.frm` file for this table. This can happen for various reasons; for example, for a cluster engine the table might have been created in the cluster by another MariaDB server node. Or for the engine that supports table shipping a table file might have been simply copied into the MariaDB data directory. But no matter what the reason is, there is a mechanism for an engine to tell the server that the table exists. This mechanism is called **table discovery** and if an engine wants the server to discover its tables, the engine should support the table discovery API.

 There are two different kinds of table discovery — a fully automatic discovery and a user-assisted one. In the former, the engine can automatically discover the table whenever an SQL statement needs it. In MariaDB, the [Archive](../archive/index) and [Sequence](../sequence/index) engines support this kind of discovery. For example, one can copy a `t1.ARZ` file into the database directory and immediately start using it — the corresponding `.frm` file will be created automatically. Or one can select from say, the `seq_1_to_10` table without any explicit `CREATE TABLE` statement.

 In the latter, user-assisted, discovery the engine does not have enough information to discover the table all on its own. But it can discover the table structure if the user provides certain additional information. In this case, an explicit `CREATE TABLE` statement is still necessary, but it should contain no table structure — only the table name and the table attributes. In MariaDB, the [FederatedX](../federatedx-storage-engine/index) storage engine supports this. When creating a table, one only needs to specify the `CONNECTION` attribute and the table structure — fields and indexes — will be provided automatically by the engine.

 ### Automatic Discovery

 As far as automatic table discovery is concerned, the tables, from the server point of view, may appear, disappear, or change structure anytime. Thus the server needs to be able to ask whether a given table exists and what its structure is. It needs to be notified when a table structure changes outside of the server. And it needs to be able to get a list of all (unknown to the server) tables, for statements like `SHOW TABLES`. The server does all that by invoking specific methods of the `handlerton`:

 
```
const char **tablefile_extensions;
int (*discover_table_names)(handlerton *hton, LEX_STRING *db, MY_DIR *dir,
                            discovered_list *result);
int (*discover_table_existence)(handlerton *hton, const char *db,
                                const char *table_name);
int (*discover_table)(handlerton *hton, THD* thd, TABLE_SHARE *share);

```

#### handlerton::tablefile\_extensions

 Engines that store tables in separate files (one table might occupy many files with different extensions, but having the same base file name) should store the list of possible extensions in the **tablefile\_extensions** member of the `handlerton` (earlier this list was returned by the `handler::bas_ext()` method). This will significantly simplify the discovery implementation for these engines, as you will see below.

 #### handlerton::discover\_table\_names()

 When a user asks for a list of tables in a specific database — for example, by using `SHOW TABLES` or by selecting from `INFORMATION_SCHEMA.TABLES` — the server invokes **discover\_table\_names()** method of the `handlerton`. For convenience this method, besides the database name in question, gets the list of all files in this database directory, so that the engine can look for table files without doing any filesystem i/o. All discovered tables should be added to the `result` collector object. It is defined as 

 
```
class discovered_list
{
  public:
  bool add_table(const char *tname, size_t tlen);
  bool add_file(const char *fname);
};

```

and the engine should call `result->add_table()` or `result->add_file()` for every discovered table (use `add_file()` if the name to add is in the MariaDB file name encoding, and `add_table()` if it's a true table name, as shown in `SHOW TABLES`).

 If the engine is file-based, that is, it has non-empty list in the `tablefile_extensions`, this method is optional. For any file-based engine that does not implement `discover_table_names()`, MariaDB will automatically discover the list of all tables of this engine, by looking for files with the extension `tablefile_extensions[0]`.

 #### handlerton::discover\_table\_existence()

 In some rare cases MariaDB needs to know whether a given table exists, but does not particularly care about this table structure (for example, when executing a `DROP TABLE` statement). In these cases, the server uses the **discover\_table\_existence()** method to find out whether a table with the given name exists in the engine.

 This method is optional. For the engine that does not implement it, MariaDB will look for files with the `tablefile_extensions[0]`, if possible. But if the engine is not file-based, MariaDB will use the `discover_table()` method to perform a full table discovery. While this will allow determining correctly whether a table exists, a full discovery is usually slower than the simple existence check. In other words, engines that are not file-based might want to support `discover_table_existence()` method as a useful optimization.

 #### handlerton::discover\_table()

 This is the main method of table discovery, the heart of it. The server invokes it when it wants to use the table. The **discover\_table()** method gets the `TABLE_SHARE` structure, which is not completely initialized — only the table and the database name (and a path to the table file) are filled in. It should initialize this `TABLE_SHARE` with the desired table structure.

 MariaDB provides convenient and easy to use helpers that allow the engine to initialize the `TABLE_SHARE` with minimal efforts. They are the `TABLE_SHARE` methods `init_from_binary_frm_image()` and `init_from_sql_statement_string()`.

 #### TABLE\_SHARE::init\_from\_binary\_frm\_image()

 This method is used by engines that use "frm shipping" — such as [Archive](../archive/index) or NDB Cluster in MySQL. An frm shipping engine reads the frm file for a given table, exactly as it was generated by the server, and stores it internally. Later it can discover the table structure by using this very frm image. In this sense, a separate frm file in the database directory becomes redundant, because a copy of it is stored in the engine.

 #### TABLE\_SHARE::init\_from\_sql\_statement\_string()

 This method allows initializing the `TABLE_SHARE` using a conventional SQL `CREATE TABLE` syntax.

 #### TABLE\_SHARE::read\_frm\_image()

 Engines that use frm shipping need to get the frm image corresponding to a particular table (typically in the `handler::create()` method). They do it via the **read\_frm\_image()** method. It returns an allocated buffer with the binary frm image, that the engine can use the way it needs.

 #### TABLE\_SHARE::free\_frm\_image()

 The frm image that was returned by `read_frm_image()` must be freed with the **free\_frm\_image()**.

 #### HA\_ERR\_TABLE\_DEF\_CHANGED

 One of the consequences of automatic discovery is that the table definition might change when the server doesn't expect it to. Between two `SELECT` queries, for example. If this happens, if the engine detects that the server is using an outdated version of the table definition, it should return a **HA\_ERR\_TABLE\_DEF\_CHANGED** handler error. Depending on when in the query processing this error has happened, MariaDB will either re-discover the table and execute the query with the correct table structure, or abort the query and return an error message to the user.

 #### TABLE\_SHARE::tabledef\_version

 The previous paragraph doesn't cover one important question — how can the engine know that the server uses an outdated table definition? The answer is — by checking the **tabledef\_version**, the table definition version. Every table gets a unique `tabledef_version` value. Normally it is generated automatically when a table is created. When a table is discovered the engine can force it to have a specific `tabledef_version` value (simply by setting it in the `TABLE_SHARE` before calling the `init_from_binary_frm_image()` or `init_from_sql_statement_string()` methods).

 Now the engine can compare the table definition version that the server is using (from any handler method it can be accessed as `this->table->s->tabledef_version`) with the version of the actual table definition. If they differ — it is `HA_ERR_TABLE_DEF_CHANGED`.

 ### Assisted discovery

 Assisted discovery is a lot simpler from the server point of view, a lot more controlled. The table cannot appear or disappear at will, one still needs explicit DDL statements to manipulate it. There is only one new handlerton method that the server uses to discover the table structure when a user has issued an explicit `CREATE TABLE` statement without declaring any columns or indexes.

 
```
int (*discover_table_structure)(handlerton *hton, THD* thd,
                               TABLE_SHARE *share, HA_CREATE_INFO *info);

```

The assisted discovery API is pretty much independent from the automatic discovery API. An engine can implement either of them or both (or none); there is no requirement to support automatic discovery if only assisted discovery is needed.

 #### handlerton::discover\_table\_structure()

 Much like the `discover_table()` method, the **discover\_table\_structure()** handlerton method gets a partially initialized `TABLE_SHARE` with the table name, database name, and a path to table files filled in, but without a table structure. Unlike `discover_table()`, here the `TABLE_SHARE` has all the [engine-defined table attributes](../engine-defined-new-tablefieldindex-attributes/index) in the the `TABLE_SHARE::option_struct` structure. Based on the values of these attributes the `discover_table_structure()` method should initialize the `TABLE_SHARE` with the desired set of fields and keys. It can use `TABLE_SHARE` helper methods `init_from_binary_frm_image()` and `init_from_sql_statement_string()` for that.

 ### The role of `.frm` files

 Before table discovery was introduced, MariaDB used `.frm` files to store the table definition. But now the engine can store the table definition (if the engine supports automatic discovery, of course), and `.frm` files become redundant. Still, the server *can* use `.frm` files for such an engine — but they are no longer the only source of the table definition. Now `.frm` files are merely a *cache* of the table definition, while the original authoritative table definition is stored in the engine. Like any cache, its purpose is to reduce discovery attempts for a table. The engine decides whether it makes sense to cache table definition in the `.frm` file or not (see the second argument for the `TABLE_SHARE::init_from_binary_frm_image()`). For example, the [Archive](../archive/index) engine uses `.frm` cache, while the [Sequence](../sequence/index) engine does not. In other words, MariaDB creates `.frm` files for [Archive](../archive/index) tables, but not for [Sequence](../sequence/index) tables.

 The cache is completely transparent for a user; MariaDB makes sure that it always stores the actual table definition and invalidates the `.frm` file automatically when it becomes out of date. This can happen, for example, if a user copies a new [Archive](../archive/index) table into the datadir and forgets to delete the `.frm` file of the old table with the same name.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-discovery/>

OQGRAPH Overview
================

    The Open Query GRAPH computation engine, or OQGRAPH as the engine itself is called, allows you to handle hierarchies (tree structures) and complex graphs (nodes having many connections in several directions).

 OQGRAPH is unlike other storage engines, consisting of an entirely different architecture to a regular storage engine such as Aria, MyISAM or InnoDB.

 It is intended to be used for retrieving hierarchical information, such as those used for graphs, routes or social relationships, in plain SQL.

 Installing
----------

 See [Installing OQGRAPH](../installing-oqgraph/index). Note that if the [query cache](../query-cache/index) is enabled, OQGRAPH will not use it.

 Creating a Table
----------------

 
The following documentation is based upon [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) and OQGRAPH v3.

 
Example with origin and destination nodes only
----------------------------------------------

 To create an OQGRAPH v3 table, a backing table must first be created. This backing table will store the actual data, and will be used for all INSERTs, UPDATEs and so on. It must be a regular table, not a view. Here's a simple example to start with:

 
```
CREATE TABLE oq_backing (
  origid INT UNSIGNED NOT NULL, 
  destid INT UNSIGNED NOT NULL,  
  PRIMARY KEY (origid, destid), 
  KEY (destid)
);

```

Some data can be inserted into the backing table to test with later:

 
```
INSERT INTO oq_backing(origid, destid) 
 VALUES (1,2), (2,3), (3,4), (4,5), (2,6), (5,6);

```

Now the read-only OQGRAPH table is created. The CREATE statement must match the format below - any difference will result in an error.

 
```
CREATE TABLE oq_graph (
  latch VARCHAR(32) NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq_backing' origid='origid' destid='destid';

```

An older format (prior to [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/)) has the latch field as a SMALLINT rather than a VARCHAR. The format is still valid, but gives an error by default:

 
```
CREATE TABLE oq_old (
  latch SMALLINT UNSIGNED NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq_backing' origid='origid' destid='destid';

ERROR 1005 (HY000): Can't create table `test`.`oq_old` (errno: 140 "Wrong create options")

```

The old, deprecated format can still be used if the value of the [oqgraph\_allow\_create\_integer\_latch](../oqgraph-system-and-status-variables/index#oqgraph_allow_create_integer_latch) system variable is changed from its default, `FALSE`, to `TRUE`.

 
```
SET GLOBAL oqgraph_allow_create_integer_latch=1;

CREATE TABLE oq_old (
  latch SMALLINT UNSIGNED NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq_backing' origid='origid' destid='destid';
Query OK, 0 rows affected, 1 warning (0.19 sec)

SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                           |
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------+
| Warning | 1287 | 'latch SMALLINT UNSIGNED NULL' is deprecated and will be removed in a future release. Please use 'latch VARCHAR(32) NULL' instead |
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------+

```

Data is only inserted into the backing table, not the OQGRAPH table. 

 Now, having created the `oq_graph` table linked to a backing table, it is now possible to query the `oq_graph` table directly. The `weight` field, since it was not specified in this example, defaults to `1`.

 
```
SELECT * FROM oq_graph;
+-------+--------+--------+--------+------+--------+
| latch | origid | destid | weight | seq  | linkid |
+-------+--------+--------+--------+------+--------+
|  NULL |      1 |      2 |      1 | NULL |   NULL |
|  NULL |      2 |      3 |      1 | NULL |   NULL |
|  NULL |      2 |      6 |      1 | NULL |   NULL |
|  NULL |      3 |      4 |      1 | NULL |   NULL |
|  NULL |      4 |      5 |      1 | NULL |   NULL |
|  NULL |      5 |      6 |      1 | NULL |   NULL |
+-------+--------+--------+--------+------+--------+

```

The data here represents one-directional starting and ending nodes. So node 2 has paths to node 3 and node 6, while node 6 has no paths to any other node.

 Manipulating Weight
-------------------

 There are three fields which can be manipulated: `origid`, `destid` (the example above uses these two), as well as `weight`. To create a backing table with a `weight` field as well, the following syntax can be used:

 
```
CREATE TABLE oq2_backing (
  origid INT UNSIGNED NOT NULL, 
  destid INT UNSIGNED NOT NULL, 
  weight DOUBLE NOT NULL, 
  PRIMARY KEY (origid, destid), 
  KEY (destid)
);

```


```
INSERT INTO oq2_backing(origid, destid, weight)  
 VALUES (1,2,1), (2,3,1), (3,4,3), (4,5,1), (2,6,10), (5,6,2);

```


```
CREATE TABLE oq2_graph (
  latch VARCHAR(32) NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq2_backing' origid='origid' destid='destid' weight='weight';

```


```
SELECT * FROM oq2_graph;
+-------+--------+--------+--------+------+--------+
| latch | origid | destid | weight | seq  | linkid |
+-------+--------+--------+--------+------+--------+
| NULL  |      1 |      2 |      1 | NULL |   NULL |
| NULL  |      2 |      3 |      1 | NULL |   NULL |
| NULL  |      2 |      6 |     10 | NULL |   NULL |
| NULL  |      3 |      4 |      3 | NULL |   NULL |
| NULL  |      4 |      5 |      1 | NULL |   NULL |
| NULL  |      5 |      6 |      2 | NULL |   NULL |
+-------+--------+--------+--------+------+--------+

```

See [OQGRAPH Examples](../oqgraph-examples/index) for OQGRAPH usage examples.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oqgraph-overview/>

OQGRAPH Examples
================

    Creating a Table with origid, destid Only
-----------------------------------------

 
```
CREATE TABLE oq_backing (
  origid INT UNSIGNED NOT NULL, 
  destid INT UNSIGNED NOT NULL,  
  PRIMARY KEY (origid, destid), 
  KEY (destid)
);

```

Some data can be inserted into the backing table to test with later:

 
```
INSERT INTO oq_backing(origid, destid) 
 VALUES (1,2), (2,3), (3,4), (4,5), (2,6), (5,6);

```

Now the read-only [OQGRAPH](../oqgraph/index) table is created. 

 From [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) onwards you can use the following syntax:

 
```
CREATE TABLE oq_graph
ENGINE=OQGRAPH 
data_table='oq_backing' origid='origid' destid='destid';

```

Prior to [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/), the [CREATE](../create-table/index) statement must match the format below - any difference will result in an error.

 
```
CREATE TABLE oq_graph (
  latch VARCHAR(32) NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq_backing' origid='origid' destid='destid';

```

Creating a Table with Weight
----------------------------

 For the examples on this page, we'll create a second OQGRAPH table and backing table, this time with `weight` as well.

 
```
CREATE TABLE oq2_backing (
  origid INT UNSIGNED NOT NULL, 
  destid INT UNSIGNED NOT NULL, 
  weight DOUBLE NOT NULL, 
  PRIMARY KEY (origid, destid), 
  KEY (destid)
);

```


```
INSERT INTO oq2_backing(origid, destid, weight)  
 VALUES (1,2,1), (2,3,1), (3,4,3), (4,5,1), (2,6,10), (5,6,2);

```


```
CREATE TABLE oq2_graph (
  latch VARCHAR(32) NULL,
  origid BIGINT UNSIGNED NULL,
  destid BIGINT UNSIGNED NULL,
  weight DOUBLE NULL,
  seq BIGINT UNSIGNED NULL,
  linkid BIGINT UNSIGNED NULL,
  KEY (latch, origid, destid) USING HASH,
  KEY (latch, destid, origid) USING HASH
) 
ENGINE=OQGRAPH 
data_table='oq2_backing' origid='origid' destid='destid' weight='weight';

```

Shortest Path
-------------

 A `latch` value of `'dijkstras'` and an `origid` and `destid` is used for finding the shortest path between two nodes, for example:

 
```
SELECT * FROM oq_graph WHERE latch='breadth_first' AND origid=1 AND destid=6;
+----------+--------+--------+--------+------+--------+
| latch    | origid | destid | weight | seq  | linkid |
+----------+--------+--------+--------+------+--------+
| dijkstras|      1 |      6 |   NULL |    0 |      1 |
| dijkstras|      1 |      6 |      1 |    1 |      2 |
| dijkstras|      1 |      6 |      1 |    2 |      6 |
+----------+--------+--------+--------+------+--------+

```

Note that nodes are uni-directional, so there is no path from node 6 to node 1:

 
```
SELECT * FROM oq_graph WHERE latch='dijkstras' AND origid=6 AND destid=1;
Empty set (0.00 sec)

```

Using the [GROUP\_CONCAT](../group_concat/index) function can produce more readable results, for example:

 
```
SELECT GROUP_CONCAT(linkid ORDER BY seq) AS path FROM oq_graph 
 WHERE latch='dijkstras' AND origid=1 AND destid=6;
+-------+
| path  |
+-------+
| 1,2,6 |
+-------+

```

Using the table `oq2_graph`, the shortest path is different:

 
```
SELECT GROUP_CONCAT(linkid ORDER BY seq) AS path FROM oq2_graph 
 WHERE latch='dijkstras' AND origid=1 AND destid=6;
+-------------+
| path        |
+-------------+
| 1,2,3,4,5,6 |
+-------------+

```

The reason is the weight between nodes 2 and 6 is `10` in `oq_graph2`, so the shortest path taking into account `weight` is now across more nodes.

 Possible Destinations
---------------------

 
```
SELECT GROUP_CONCAT(linkid) AS dests FROM oq_graph WHERE latch='dijkstras' AND origid=2;
+-----------+
| dests     |
+-----------+
| 5,4,6,3,2 |
+-----------+

```

Note that this returns all possible destinations along the path, not just immediate links.

 Leaf Nodes
----------

 
**MariaDB [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**Support for the `leaves` latch value was introduced in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

 
A `latch` value of `'leaves'` and either `origid` or `destid` is used for finding leaf nodes at the beginning or end of a graph.

 
```
INSERT INTO oq_backing(origid, destid)  
 VALUES (1,2), (2,3), (3,5), (4,5), (5,6), (6,7), (6,8), (2,8);

```

For example, to find all reachable nodes from `origid` that only have incoming edges:

 
```
SELECT * FROM oq_graph WHERE latch='leaves' AND origid=2;
+--------+--------+--------+--------+------+--------+
| latch  | origid | destid | weight | seq  | linkid |
+--------+--------+--------+--------+------+--------+
| leaves |      2 |   NULL |      4 |    2 |      7 |
| leaves |      2 |   NULL |      1 |    1 |      8 |
+--------+--------+--------+--------+------+--------+

```

And to find all nodes from which a path can be found to `destid` that only have outgoing edges:

 
```
SELECT * FROM oq_graph WHERE latch='leaves' AND destid=5;
+--------+--------+--------+--------+------+--------+
| latch  | origid | destid | weight | seq  | linkid |
+--------+--------+--------+--------+------+--------+
| leaves |   NULL |      5 |      3 |    2 |      1 |
| leaves |   NULL |      5 |      1 |    1 |      4 |
+--------+--------+--------+--------+------+--------+

```

Summary of Implemented Latch Commands
-------------------------------------

 

| Latch | Alternative | additional where clause fields | Graph operation |
| --- | --- | --- | --- |
| NULL | (unspecified) | (none) | List original data |
| (empty string) | 0 | (none extra) | List all vertices in linkid column |
| (empty string) | 0 | origid | List all first hop vertices from origid in linkid column |
| dijkstras | 1 | origid, destid | Find shortest path using Dijkstras algorithm between origid and destid, with traversed vertex ids in linkid column |
| dijkstras | 1 | origid | Find all vertices reachable from origid, listed in linkid column, and report sum of weights of vertices on path to given vertex in weight |
| dijkstras | 1 | destid | Find all vertices from which a path can be found to destid, listed in linkid column, and report sum of weights of vertices on path to given vertex in weight |
| breadth\_first | 2 | origid | List vertices reachable from origid in linkid column |
| breadth\_first | 2 | destid | List vertices from which a path can be found to destid in linkid column |
| breadth\_first | 2 | origid, destid | Find shortest path between origid and destid, report in linkid column |
| leaves | 4 | origid | List vertices reachable from origid, that only have incoming edges (from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)) |
| leaves | 4 | destid | List vertices from which a path can be found to destid, that only have outgoing edges (from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)) |
| leaves | 4 | origid, destid | Not supported, will return an empty result |

 

---

 Note: the use of integer latch commands is deprecated and may be phased out in a future release. Currently, numeric values in the strings are interpreted as aliases, and use of an integer column can be optionally allowed, for the latch commands column.

 The use of integer latches is controlled using the [oqgraph\_allow\_create\_integer\_latch](../oqgraph-system-and-status-variables/index#oqgraph_allow_create_integer_latch) system variable.

 See Also
--------

 * [OQGRAPH Overview](../oqgraph-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oqgraph-examples/>

Compiling OQGRAPH
=================

    To compile OQGraph v2 you need to have the boost library with the versions not earlier than 1.40 and not later than 1.55 and gcc version not earlier than 4.5.

 
**MariaDB starting with [10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/)**OQGraph v3 compiles fine with the newer boost libraries, but it additionally needs the Judy library installed.

 
When all build prerequisites are met, OQGraph is enabled and compiled automatically. To enable or disable OQGRAPH explicitly, see the generic [plugin build instructions](../specifying-what-plugins-to-build/index).

 ### Finding Out Why OQGRAPH Didn't Compile

 If OQGRAPH gets compiled properly, there should be a file like:

 
```
storage/oqgraph/ha_oqgraph.so

```

If this is not the case, then you can find out if there is any modules missing that are required by OQGRAPH by doing:

 
```
cmake . -LAH | grep -i oqgraph

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-oqgraph/>

Engine-defined New Table/Field/Index Attributes
===============================================

     In MariaDB, a storage engine can allow the user to specify additional attributes per index, field, or table. The engine needs to declare what attributes it introduces.

 API
---

 There are three new members in the `handlerton` structure, they can be set in the engine's initialization function as follows:

 
```
example_hton->table_options= example_table_option_array;
example_hton->field_options= example_field_option_array;
example_hton->index_options= example_index_option_array;

```

The arrays are declared statically, as in the following example:

 
```
static MYSQL_THDVAR_ULONG(varopt_default, PLUGIN_VAR_RQCMDARG,
  "default value of the VAROPT table option", NULL, NULL, 5, 0, 100, 0);

struct ha_table_option_struct
{
  char *strparam;
  ulonglong ullparam;
  uint enumparam;
  bool boolparam;
  ulonglong varparam;
};

ha_create_table_option example_table_option_list[]=
{
  HA_TOPTION_NUMBER("NUMBER", ullparam, UINT_MAX32, 0, UINT_MAX32, 10),
  HA_TOPTION_STRING("STR", strparam),
  HA_TOPTION_ENUM("ONE_OR_TWO", enumparam, "one,two", 0),
  HA_TOPTION_BOOL("YESNO", boolparam, 1),
  HA_TOPTION_SYSVAR("VAROPT", varopt, varparam),
  HA_TOPTION_END
};

```

The engine declares a structure `ha\_table\_option\_struct` that will hold values of these new attributes.

 And it describes these attributes to MySQL by creating an array of `HA\_TOPTION\_\*` macros. Note a detail: these macros expect a structure called `ha\_table\_option\_struct`, if the structure is called differently, a `#define` will be needed.

 There are five supported kinds of attributes:

 


| macro name | attribure value type | correspondingCtype | additional parameters of a macro |
| --- | --- | --- | --- |
| `HA_TOPTION_NUMBER` | an integer number | `unsigned long long` | a default value, minimal allowed value, maximal allowed value, a factor, that any allowed should be a multiple of. |
| `HA_TOPTION_STRING` | a string | `char *` | none. The default value is a null pointer. |
| `HA_TOPTION_ENUM` | one value from a list of allowed values | `unsigned int` | a string with a comma-separated list of allowed values, and a default value as a number, starting from 0. |
| `HA_TOPTION_BOOL` | a boolean | `bool` | a default value |
| `HA_TOPTION_SYSVAR` | defined by the system variable | defined by the system variable | system variable name |

 
*Do **not** use*  `enum`  *for your*  `HA_TOPTION_ENUM`  *C structure members, the size of the*  `enum`  *depends on the compiler, and even on the compilation options, and the plugin API uses only types with known storage sizes.*

 In all macros the first two parameters are name of the attribute as should be used in SQL in the `CREATE TABLE` statement, and the name of the corresponding member of the `ha_table_option_struct` structure.

 The `HA_TOPTION_SYSVAR` stands aside a bit. It does not specify the attribute type or the default value, instead it binds the attribute to a system variable. The attribute type and the range of allowed values will be the same as of the corresponding system variable. The attribute **default value** will be the **current value** of its system variable. And unlike other attribute types that are only stored in the `.frm` file if explicitly set in the `CREATE TABLE` statement, the `HA_TOPTION_SYSVAR` attributes are always stored. If the system variable value is changed, it will not affect existing tables. Note that for this very reason, if a table was created in the old version of a storage engine, and a new version has introduced a `HA_TOPTION_SYSVAR` attribute, the attribute value in the old tables will be the **default** value of the system variable, not its **current** value.

 The array ends with a `HA_TOPTION_END` macro.

 Field and index (key) attributes are declared similarly using `HA_FOPTION_*` and `HA_IOPTION_*` macros.

 When in a `CREATE TABLE` statement, the `::create()` handler method is called, the table attributes are available in the `table_arg->s->option_struct`, field attributes - in the `option_struct` member of the individual fields (objects of the `Field` class), index attributes - in the `option_struct` member of the individual keys (objects of the `KEY` class).

 Additionally, they are available in most other handler methods: the attributes are stored in the `.frm` file and on every open MySQL makes them available to the engine by filling the corresponding `option_struct` members of the table, fields, and keys.

 The `ALTER TABLE` needs a special support from the engine. MySQL compares old and new table definitions to decide whether it needs to rebuild the table or not. As the semantics of the engine declared attributes is unknown, MySQL cannot make this decision by analyzing attribute values - this is delegated to the engine. The `HA_CREATE_INFO` structure has three new members:

 
```
ha_table_option_struct *option_struct;           ///< structure with parsed table options
ha_field_option_struct **fields_option_struct;   ///< array of field option structures
ha_index_option_struct **indexes_option_struct;  ///< array of index option structures

```

The engine (in the `::check_if_incompatible_data()` method) is responsible for comparing new values of the attributes from the `HA_CREATE_INFO` structure with the old values from the table and returning `COMPATIBLE_DATA_NO` if they were changed in such a way that requires the table to be rebuild.

 The example of declaring the attributes and comparing the values for the `ALTER TABLE` can be found in the EXAMPLE engine.

 SQL
---

 The engine declared attributes can be specified per field, index, or table in the `CREATE TABLE` or `ALTER TABLE`. The syntax is the conventional:

 
```
CREATE TABLE ... (
  field ... [attribute=value [attribute=value ...]],
  ...
  index ... [attribute=value [attribute=value ...]],
  ...
) ...  [attribute=value [attribute=value ...]]

```

All values must be specified as literals, not expressions. The value of a boolean option may be specified as one of YES, NO, ON, OFF, 1, or 0. A string value may be specified either quoted or not, as an identifier (if it is a valid identifier, of course). Compare with the old behavior:

 
```
CREATE TABLE ... ENGINE=FEDERATED CONNECTION='mysql://root@127.0.0.1';

```

where the value of the ENGINE attribute is specified not quoted, while the value of the CONNECTION is quoted.

 When an attribute is set, it will be stored with the table definition and shown in the `SHOW CREATE TABLE;`. To remove an attribute from a table definition use `ALTER TABLE` to set its value to a `DEFAULT`.

 The values of unknown attributes or attributes with the illegal values cause an error by default. But with [ALTER TABLE](../alter-table/index) one can change the storage engine and some previously valid attributes may become unknown — to the new engine. They are not removed automatically, though, because the table might be altered back to the first engine, and these attributes will be valid again. Still [SHOW CREATE TABLE](../show-create-table/index) will comment these unknown attributes out in the output, otherwise they would make a generated [CREATE TABLE](../create-table/index) statement invalid.

 With the `IGNORE\_BAD\_TABLE\_OPTIONS` [sql mode](../sql_mode/index) this behavior changes. Unknown attributes do not cause an error, they only result in a warning. And [SHOW CREATE TABLE](../show-create-table/index) will not comment them out. This mode is implicitly enabled in the replication slave thread.

 See Also
--------

 * [Writing Plugins for MariaDB](../writing-plugins-for-mariadb/index)
* [Storage Engines](../storage-engines/index)
* [Storage Engine Development](../storage-engine-development/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/engine-defined-new-tablefieldindex-attributes/>

Building OQGRAPH Under Windows
==============================

    OQGRAPH v3 can be built on Windows.

 
**MariaDB starting with [10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/)**This has been tested using Windows 7, Microsoft Visual Studio Express 2010 (32-bit), Microsoft Windows 64-bit Platform SDK 7.1 (64-bit), the Boost library >= 1.55 and Judy 1.0.5. Probably other recent versions of Boost, Judy or MSVC may work but these combinations have not been tested.

 
* Download the source package for Boost 1.55 from the Boost project website, <http://www.boost.org>
* Download the source package for Judy 1.05 via <http://judy.sourceforge.net/>
* Follow the documented instructions for building under Windows from the command line: [Building\_MariaDB\_on\_Windows](../building_mariadb_on_windows/index)
	+ Ensure that the following variable is set to CMAKE: `JUDY_ROOT=path\to\judy\unzipped`
	+ See also comments in `storage/oqgraph/cmake/FindJudy.cmake`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-oqgraph-under-windows/>

Installing Sphinx
=================

    In order to use the [Sphinx Storage Engine](../sphinxse/index), it is necessary to install the Sphinx daemon.

 
Many Linux distributions have Sphinx in their repositories. These can be used to install Sphinx instead of following the instructions below, but these are usually quite old versions and don't all include API's for easy integration. Ubuntu users can use the updated repository at <https://launchpad.net/~builds/+archive/sphinxsearch-rel21> (see instructions below). Alternatively, download from <http://sphinxsearch.com/downloads/release/>

 
Debian and Ubuntu
-----------------

 Ubuntu users can make use of the repository, as follows:

 
```
sudo add-apt-repository ppa:builds/sphinxsearch-rel21
sudo apt-get update
sudo apt-get install sphinxsearch

```

Alternatively, install as follows:

 * The Sphinx package and daemon are named `sphinxsearch`.
* `sudo apt-get install unixodbc libpq5 mariadb-client`
* `sudo dpkg -i sphinxsearch*.deb`
* [Configure Sphinx](../configuring-sphinx/index) as required
* You may need to check `/etc/default/sphinxsearch` to see that `START=yes`
* Start with `sudo service sphinxsearch start` (and stop with `sudo service sphinxsearch stop`)

 Red Hat and CentOS
------------------

 * The package name is `sphinx` and the daemon `searchd`.
* `sudo yum install postgresql-libs unixODBC`
* `sudo rpm -Uhv sphinx*.rpm`
* [Configure Sphinx](../configuring-sphinx/index) as required
* `service searchd start`

 Windows
-------

 * Unzip and extract the downloaded zip file
* Move the extracted directory to `C:\Sphinx`
* [Configure Sphinx](../configuring-sphinx/index) as required
* Install as a service:
	+ `C:\Sphinx\bin> C:\Sphinx\bin\searchd --install --config C:\Sphinx\sphinx.conf.in --servicename SphinxSearch`

 Once Sphinx has been installed, it will need to be [configured](../configuring-sphinx/index).

 Full instructions, including details on compiling Sphinx yourself, are available at <http://sphinxsearch.com/docs/current.html>.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-sphinx/>

Storage Engine FAQ
==================

    ### Are storage engines designed for MySQL compatible with MariaDB?

 In most cases, yes. MariaDB tries to keep API compatibility with MySQL, even across major versions.

 ### Will storage engines created for MariaDB work in MySQL?

 It will mostly work. It would need #ifdef's to adjust to MySQL-5.6 API, for example, for multi-read-range API, for table discovery API, etc. But most of the code will work as is, without any changes.

 ### Do storage engine binaries need to be recompiled for MariaDB?

 Yes. You will need to recompile the storage engine against the exact version of MySQL or MariaDB you intend to run it on. This is due to the version of the server being stored in the storage engine binary, and the server will refuse to load it if it was compiled for a different version.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engine-faq/>

Table Discovery (before 10.0.2)
===============================

    
This page describes the **old** discovery API, created in MySQL for NDB Cluster. It no longer works in MariaDB. New table discovery API is documented [here](../table-discovery/index).

 
There are four parts of it.

 First, when a server finds that a table (for example, mentioned in the `SELECT` query) does not exist, it asks every engine whether it knows anything about this table. For this it uses **discover()** method of the handlerton. The method is defined as

 
```
int discover(handlerton *hton, THD* thd, const char *db, const char *name,
             unsigned char **frmblob, size_t *frmlen);

```

It takes the database and a table name as arguments and is returns 0 if the table exists in the engine and 1 otherwise. If it returned 0, it is supposed to allocate (with `my_malloc()`) a buffer and store the complete binary image of the `.frm` file of that table. The server will write it down to disk, creating table's `.frm`. The output parameters `frmblob` and `frmlen` are used to return the information about the buffer to the caller. The caller is responsible for freeing the buffer with `my_free()`.

 Second, in some cases the server only wants to know if the table exists, but it does not really need to open it and will not use its `.frm` file image. Then using the `discover()` method would be an overkill, and the server uses a lightweight **table\_exists\_in\_engine()** method. This method is defined as

 
```
int table_exists_in_engine(handlerton *hton, THD* thd,
                           const char *db, const char *name);

```

and it returns one of the `HA_ERR_` codes, typically `HA_ERR_NO_SUCH_TABLE` or `HA_ERR_TABLE_EXIST`.

 Third, there can be a situation when the server thinks that the table exists (it found and successfully read the `.frm` file), but from the engine point of view the `.frm` file is incorrect. For example, the table was already deleted from the engine, or its definition was modified (again, modified only in the engine). In this case the `.frm` file is outdated, and the server needs to re-discover the table. The engine conveys this to the server by returning `HA_ERR_TABLE_DEF_CHANGED` error code from the handler's **open()** method. On receiving this error the server will use the `discover()` method to get the new `.frm` image. This also means that *after* the table is opened, the server does not expect its metadata to change. The engine thus should ensure (with some kind of locking, perhaps) that a table metadata cannot be modified, as long as the table stays opened.

 And fourth, a user might want to retrieve a list of tables in a specific database. With `SHOW TABLES` or by quering `INFORMATION_SCHEMA` tables. The user expects to see all tables, but the server cannot discover them one by one, because it doesnt know table names. In this case, the server uses a special discovery technique. It is **find\_files()** method in the handlerton, defines as

 
```
int find_files(handlerton *hton, THD *thd,
               const char *db, const char *path,
               const char *wild, bool dir, List<LEX_STRING> *files);

```

and it, typically for Storage Engine API, returns 0 on success and 1 on failure. The arguments mean `db` - the name of the database, `path` - the path to it, `wild` an SQL wildcard pattern (for example, from `SHOW TABLES LIKE '...'`, and `dir`, if set, means to discover *databases* instead of *tables*.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-discovery-before-1002/>

BDB
===

    BDB was a storage engine included in old versions of MySQL.

 
This storage engine was removed from the 5.1 tree at some point, before the birth of MariaDB.

 
BDB permitted the use of a patched version of the Berkeley DB key-value store. It was a transactional storage engine. Locking was performed at page level.

 Limitations
-----------

 * Indexes per table: 31
* Columns per index: 16
* Index size: 1024 bytes

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bdb-obsolete/>

IBMDB2I Storage Engine
======================

    The IBMDB2I storage engine was designed to allow MySQL to store data on IBM DB2 tables running IBM i.

 
**MySQL 5.1.33 - 5.1.53**The IBMDB2I storage engine was introduced in MySQL 5.1.33, considered production-ready in MySQL 5.1.35, and was removed in MySQL 5.1.54. It is not supported in MariaDB.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ibmdb2i-storage-engine/>

EXAMPLE Storage Engine
======================

    The EXAMPLE storage engine was designed as a stub with no functionality primarily to assist developers with the source code for writing new MySQL storage engines.

 It is no longer included in MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/example-storage-engine/>

FEDERATED Storage Engine
========================

    The FEDERATED Storage Engine is a legacy storage engine no longer being supported. A fork, [FederatedX](../federatedx/index) is being actively maintained. Since [MariaDB 10.0](../what-is-mariadb-100/index), the [CONNECT](../connect/index) storage engine also permits accessing a remote database via MySQL or ODBC connection (table types: [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index)).

 The FEDERATED Storage Engine was originally designed to let one access data remotely without using clustering or replication, and perform local queries that automatically access the remote data.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/federated-storage-engine/>

About MyRocks for MariaDB
=========================

    About MyRocks for MariaDB
=========================

 MyRocks is an open source storage engine that was originally developed by Facebook.

 MyRocks has been extended by the MariaDB engineering team to be a pluggable storage engine that you use in your MariaDB solutions. It works seamlessly with MariaDB features. This openness in the storage layer allows you to use the right storage engine to optimize your usage requirements, which provides optimum performance. Community contributions are one of MariaDB’s greatest advantages over other databases. Under the lead of our developer Sergey Petrunia, MyRocks in MariaDB is occasionally being merged with upstream MyRocks from Facebook.  
 See more at: <https://mariadb.com/resources/blog/facebook-myrocks-mariadb#sthash.ZlEr7kNq.dpuf>

 ![storage engine options]

 MyRocks, typically, gives greater performance for web scale type applications. It can be an ideal storage engine solution when you have workloads that require greater compression and IO efficiency. It uses a Log Structured Merge (LSM) architecture, which has advantages over B-Tree algorithms, to provide efficient data ingestion, like read-free replication slaves, or fast bulk data loading. MyRocks distinguishing features include:

 * compaction filter
* merge operator
* backup
* column families
* bulk loading
* persistent cache

 For more MyRocks features see: <https://github.com/facebook/rocksdb/wiki/Features-Not-in-LevelDB>

 Benefits
--------

 On production workloads, MyRocks was tested to prove that it provides:

 #### Greater Space Efficiency

 * 2x more compression  
 MyRocks has 2x better compression compared to compressed InnoDB, 3-4x better compression compared to uncompressed InnoDB, meaning you use less space.

 #### Greater Writing Efficiency

 * 2x lower write rates to storage  
 MyRocks has a 10x less write amplification compared to InnoDB, giving you better endurance of flash storage and improving overall throughput.

 #### Faster Data Loading

 * faster database loads  
 MyRocks writes data directly onto the bottommost level, which avoids all compaction overheads when you enable faster data loading for a session.

 #### Faster Replication

 * No random reads for updating secondary keys, except for unique indexes. The Read-Free Replication option does away with random reads when updating primary keys, regardless of uniqueness, with a row-based binary logging format.

 <http://myrocks.io> <https://mariadb.com/resources/blog/facebook-myrocks-mariadb>

 Requirements and Limitations
----------------------------

 * MyRocks is included from [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/).
* MyRocks is available in the MariaDB Server packages for Linux and Windows.
* Maria DB optimistic parallel replication may not be supported.
* MyRocks is not available for 32-bit platforms
* [Galera Cluster](../galera/index) is tightly integrated into InnoDB storage engine (it also supports Percona's XtraDB which is a modified version of InnoDB). Galera Cluster does not work with any other storage engines, including MyRocks (or TokuDB for example).

 MyRocks builds are available on platforms that support a sufficiently modern compiler, for example:

 * Ubuntu Trusty, Xenial, (amd64 and ppc64el)
* Ubuntu Yakkety (amd64)

 * Debian Jessie, stable (amd64, ppc64el)
* Debian Stretch, Sid (testing and unstable) (amd64)

 * CentOS/RHEL 7 (amd64)
* Centos/RHEL 7.3 (amd64)
* Fedora 24 and 25 (amd64)
* OpenSUSE 42 (amd64)

 * Windows 64 (zip and MSI)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-myrocks-for-mariadb/>

About SphinxSE
==============

     The Sphinx storage engine (SphinxSE) is a storage engine that talks to searchd (the Sphinx daemon) to enable text searching. Sphinx and SphinxSE is used as a faster and more customizable alternative to MariaDB's [built-in full-text search](../full-text-indexes/index).

 Sphinx does not depend on MariaDB, and can run independently, but SphinxSE provides a convenient interface to the underlying Sphinx daemon.

 Versions of SphinxSE in MariaDB
-------------------------------

 


| SphinxSE Version | Introduced | Maturity |
| --- | --- | --- |
| [SphinxSE 2.2.6](http://sphinxsearch.com/docs/current.html) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) | Stable |
| [SphinxSE 2.1.9](http://sphinxsearch.com/docs/2.1.9/) | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) | Stable |
| SphinxSE 2.0.4 | [MariaDB 5.5](../what-is-mariadb-55/index) |  |
| SphinxSE 0.99 | [MariaDB 5.2](../what-is-mariadb-52/index) and [MariaDB 5.3](../what-is-mariadb-53/index) |  |

  Enabling SphinxSE in MariaDB
----------------------------

 The Sphinx storage engine is included in the source, binaries, and packages of MariaDB. SphinxSE is built as a dynamically loadable .so plugin. To use it, you need to perform a one-time install:

 
```
INSTALL SONAME 'ha_sphinx';

```


**MariaDB until [10.0](../what-is-mariadb-100/index)**In Debian/Ubuntu packages SphinxSE is statically compiled into the MariaDB server, there is no need to use the `INSTALL SONAME` statement.

 
Once installed, SphinxSE will show up in the list of installed storage engines:

 
```
SHOW ENGINES;
+------------+---------+--------------------------------------------+--------------+------+------------+
| Engine     | Support | Comment                                    | Transactions | XA   | Savepoints |
+------------+---------+--------------------------------------------+--------------+------+------------+
...
| SPHINX     | YES     | Sphinx storage engine 0.9.9                | NO           | NO   | NO         |
...
+------------+---------+--------------------------------------------+--------------+------+------------+

```

This is a one-time step and will not need to be performed again.

 
**Note:** SphinxSE is just the storage engine part of Sphinx. You will have to [install Sphinx](../installing-sphinx/index) itself in order to make use of SphinxSE in MariaDB.

 
Despite the name, SphinxSE does not actually store any data itself. It is actually a built-in client which allows MariaDB to talk to Sphinx, run search queries, and obtain search results. All indexing and searching happen outside MariaDB.

 Some SphinxSE applications include:

 * easier porting of MariaDB/MySQL FTS applications to Sphinx
* allowing Sphinx use with programming languages for which native APIs are not available yet
* optimizations when additional Sphinx result set processing on the MariaDB side is required (eg. JOINs with original document tables, additional MariaDB-side filtering, and etc...)

 Using SphinxSE
--------------

 ### Basic Usage

 To search via SphinxSE, you would need to create a special `ENGINE=SPHINX` "search table", and then `SELECT` from it with full text query put into the `WHERE` clause for query column.

 Here is an example create statement and search query:

 
```
CREATE TABLE t1
(
    id          BIGINT UNSIGNED NOT NULL,
    weight      INTEGER NOT NULL,
    query       VARCHAR(3072) NOT NULL,
    group_id    INTEGER,
    INDEX(query)
) ENGINE=SPHINX CONNECTION="sphinx://127.0.0.1:9312/test1";

SELECT * FROM t1 WHERE query='test it;mode=any';

```

The first three columns of the search table must have a type of `BIGINT` for the 1st column (document id), `INTEGER` or `BIGINT` for the 2nd column (match weight), and `VARCHAR` or `TEXT` for the 3rd column (your query), respectively. This mapping is fixed; you cannot omit any of these three required columns, or move them around, or change types. Also, the query column must be indexed; all the others must be kept unindexed. Column names are ignored so you can use arbitrary ones.

 Additional columns must be either `INTEGER`, `TIMESTAMP`, `BIGINT`, `VARCHAR`, or `FLOAT`. They will be bound to the attributes provided in the Sphinx result set by name, so their names must match the attribute names specified in `sphinx.conf`. If there's no such attribute name in the Sphinx search results, the additional columns will have `NULL` values.

 Special "virtual" attribute names can also be bound to SphinxSE columns. `_sph_` needs to be used instead of `@` for that. For instance, to obtain the values of '`@groupby`', '`@count`', or '`@distinct`' virtual attributes, use '`_sph_groupby`', '`_sph_count`' or '`_sph_distinct`' column names, respectively.

 The `CONNECTION` string parameter is used to specify the default `searchd` host, port, and indexes for queries issued using this table. If no connection string is specified in `CREATE
TABLE`, index name '`*`' (ie. search all indexes) and '`127.0.0.1:9312`' are assumed. The connection string syntax is as follows:

 
```
CONNECTION="sphinx://HOST:PORT/INDEXNAME"

```

You can change the default connection string later like so:

 
```
ALTER TABLE t1 CONNECTION="sphinx://NEWHOST:NEWPORT/NEWINDEXNAME";

```

You can also override all these parameters per-query.

 
**Note:** To use Linux sockets you can modify the searchd section of the Sphinx configuration file, setting the listen parameter to a socket file. Instruct SphinxSE about the socket using CONNECTION="unix:*unix/domain/socket[:index]".* 

 
### Search Options

 As seen in the example above, both query text and search options should be put into the '`WHERE`' clause of the search query column (i.e. the 3rd column); the options are separated by semicolons ('`;`') and separate names from values using an equals sign ('`=`'). Any number of options can be specified. Available options are:

 * query - query text;
* mode - matching mode. Must be one of "all", "any", "phrase", "boolean", or "extended". Default is "all";
* sort - match sorting mode. Must be one of "relevance", "attr\_desc", "attr\_asc", "time\_segments", or "extended". In all modes besides "relevance" attribute name (or sorting clause for "extended") is also required after a colon:

 
```
... WHERE query='test;sort=attr_asc:group_id';
... WHERE query='test;sort=extended:@weight desc, group_id asc';

```

* offset - offset into result set, default is 0;
* limit - amount of matches to retrieve from result set, default is 20;
* index - names of the indexes to search:

 
```
... WHERE query='test;index=test1;';
... WHERE query='test;index=test1,test2,test3;';

```

* minid, maxid - min and max document ID to match;
* weights - comma-separated list of weights to be assigned to Sphinx full-text fields:

 
```
... WHERE query='test;weights=1,2,3;';

```

* filter, !filter - comma-separated attribute name and a set of values to match:

 
```
# only include groups 1, 5 and 19
... WHERE query='test;filter=group_id,1,5,19;';

# exclude groups 3 and 11
... WHERE query='test;!filter=group_id,3,11;';

```

* range, !range - comma-separated attribute name, min and max value to match:

 
```
# include groups from 3 to 7, inclusive
... WHERE query='test;range=group_id,3,7;';

# exclude groups from 5 to 25
... WHERE query='test;!range=group_id,5,25;';

```

* maxmatches - per-query max matches value:

 
```
... WHERE query='test;maxmatches=2000;';

```

* groupby - group-by function and attribute:

 
```
... WHERE query='test;groupby=day:published_ts;';
... WHERE query='test;groupby=attr:group_id;';

```

* groupsort - group-by sorting clause:

 
```
... WHERE query='test;groupsort=@count desc;';

```

* indexweights - comma-separated list of index names and weights to use when searching through several indexes:

 
```
... WHERE query='test;indexweights=idx_exact,2,idx_stemmed,1;';

```

* comment - a string to mark this query in query log (mapping to $comment parameter in Query() API call):

 
```
... WHERE query='test;comment=marker001;';

```

* select - a string with expressions to compute (mapping to SetSelect() API call):

 
```
... WHERE query='test;select=2*a+3*b as myexpr;';

```


**Note:** It is much more efficient to allow Sphinx to perform sorting, filtering, and slicing of the result set than to raise max matches count and use '`WHERE`', '`ORDER BY`', and '`LIMIT`' clauses on the MariaDB side. This is for two reasons:

 1. Sphinx does a number of optimizations and performs better than MariaDB/MySQL on these tasks.
2. Less data would need to be packed by `searchd`, and transferred and unpacked by SphinxSE.

 
### SHOW ENGINE SPHINX STATUS

 Starting with version 0.9.9-rc1, additional query info besides the result set can be retrieved with the '`SHOW ENGINE SPHINX STATUS`' statement:

 
```
SHOW ENGINE SPHINX STATUS;
+--------+-------+-------------------------------------------------+
| Type   | Name  | Status                                          |
+--------+-------+-------------------------------------------------+
| SPHINX | stats | total: 25, total found: 25, time: 126, words: 2 | 
| SPHINX | words | sphinx:591:1256 soft:11076:15945                | 
+--------+-------+-------------------------------------------------+

```

This information can also be accessed through status variables. Note that this method does not require super-user privileges.

 
```
SHOW STATUS LIKE 'sphinx_%';
+--------------------+----------------------------------+
| Variable_name      | Value                            |
+--------------------+----------------------------------+
| sphinx_total       | 25                               | 
| sphinx_total_found | 25                               | 
| sphinx_time        | 126                              | 
| sphinx_word_count  | 2                                | 
| sphinx_words       | sphinx:591:1256 soft:11076:15945 | 
+--------------------+----------------------------------+

```

### JOINs with SphinxSE

 You can perform `JOIN`s on a SphinxSE search table and tables using other engines. Here's an example with "documents" from example.sql:

 
```
SELECT content, date_added FROM test.documents docs
    JOIN t1 ON (docs.id=t1.id) 
    WHERE query="one document;mode=any";
+-------------------------------------+---------------------+
| content                             | docdate             |
+-------------------------------------+---------------------+
| this is my test document number two | 2006-06-17 14:04:28 | 
| this is my test document number one | 2006-06-17 14:04:28 | 
+-------------------------------------+---------------------+

SHOW ENGINE SPHINX STATUS;
+--------+-------+---------------------------------------------+
| Type   | Name  | Status                                      |
+--------+-------+---------------------------------------------+
| SPHINX | stats | total: 2, total found: 2, time: 0, words: 2 | 
| SPHINX | words | one:1:2 document:2:2                        | 
+--------+-------+---------------------------------------------+

```

Building snippets (excerpts) via MariaDB
----------------------------------------

 Starting with version 0.9.9-rc2, SphinxSE also includes a UDF function that lets you create snippets through MariaDB. The functionality is fully similar to the [BuildExcerprts](http://sphinxsearch.com/docs/current.html#api-func-buildexcerpts) API call but is accessible through MariaDB+SphinxSE.

 
**MariaDB until [5.5](../what-is-mariadb-55/index)**The binary that provides the UDF is named sphinx.so and is automatically built and installed to the proper location along with SphinxSE itself. Register the UDF using the following statement:

 
```
CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME 'sphinx.so';

```



**MariaDB until [10.0](../what-is-mariadb-100/index)**The UDF is packed together with the storage engine, in the same binary named ha\_sphinx.so. Register the UDF using the following statement:

 
```
CREATE FUNCTION sphinx_snippets RETURNS STRING SONAME 'ha_sphinx.so';

```


The function name must be '`sphinx_snippets`', you can not use an arbitrary name. Function arguments are as follows:

 
```
Prototype: function sphinx_snippets ( document, index, words, [options] );

```

Document and words arguments can be either strings or table columns. Options must be specified like this: <code>'value' AS option\_name</code>. For a list of supported options, refer to the [BuildExcerprts()](http://sphinxsearch.com/docs/current.html#api-func-buildexcerpts) API call. The only UDF-specific additional option is named 'sphinx' and lets you specify searchd location (host and port).

 Usage examples:

 
```
SELECT sphinx_snippets('hello world doc', 'main', 'world',
    'sphinx://192.168.1.1/' AS sphinx, true AS exact_phrase,
    '[b]' AS before_match, '[/b]' AS after_match)
FROM documents;

SELECT title, sphinx_snippets(text, 'index', 'mysql php') AS text
    FROM sphinx, documents
    WHERE query='mysql php' AND sphinx.id=documents.id;

```

More Information
----------------

 More information on Sphinx and SphinxSE is available on the [Sphinx website](http://sphinxsearch.com/docs/current.html).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-sphinxse/>

Getting Started with MyRocks
============================

    
**MariaDB starting with [10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/)**The MyRocks storage engine was first released in [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/).

 
MyRocks is a storage engine that adds the RocksDB database to MariaDB. RocksDB is an LSM database with a great compression ratio that is optimized for flash storage.

 The storage engine must be installed before it can be used.

 Installing the Plugin's Package
-------------------------------

 The MyRocks storage engine's shared library is included in MariaDB packages as the `ha_rocksdb.so` or `ha_rocksdb.dll` shared library on systems where it can be built. The plugin was first included in [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/).

 ### Installing on Linux

 The MyRocks storage engine is included in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 #### Installing with a Package Manager

 The MyRocks storage engine can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 ##### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-rocksdb-engine

```

##### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 
```
sudo apt-get install mariadb-plugin-rocksdb

```

##### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-rocksdb-engine

```

### Installing on Windows

 The MyRocks storage engine is included in [MSI](../installing-mariadb-msi-packages-on-windows/index) and [ZIP](../installing-mariadb-windows-zip-packages/index) packages on Windows.

 Installing the Plugin
---------------------

 Once the shared library is in place, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'ha_rocksdb';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = ha_rocksdb

```

Note: When installed with a package manager, an option file that contains the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` option may also be installed. The RPM package installs it as `/etc/my.cnf.d/rocksdb.cnf`, and the DEB package installs it as `/etc/mysql/mariadb.conf.d/rocksdb.cnf`

 Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'ha_rocksdb';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Verifying the Installation
--------------------------

 After installing MyRocks you will see RocksDB in the list of plugins:

 
```
SHOW PLUGINS;
+-------------------------------+----------+--------------------+---------------+---------+
| Name                          | Status   | Type               | Library       | License |
+-------------------------------+----------+--------------------+---------------+---------+
...
| ROCKSDB                       | ACTIVE   | STORAGE ENGINE     | ha_rocksdb.so | GPL     |
| ROCKSDB_CFSTATS               | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_DBSTATS               | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_PERF_CONTEXT          | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_PERF_CONTEXT_GLOBAL   | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_CF_OPTIONS            | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_COMPACTION_STATS      | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_GLOBAL_INFO           | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_DDL                   | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_INDEX_FILE_MAP        | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_LOCKS                 | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
| ROCKSDB_TRX                   | ACTIVE   | INFORMATION SCHEMA | ha_rocksdb.so | GPL     |
...
+-------------------------------+----------+--------------------+---------------+---------+

```

Compression
-----------

 Supported compression types are listed in the [rocksdb\_supported\_compression\_types](../myrocks-system-variables/index#rocksdb_supported_compression_types) variable. For example:

 
```
SHOW VARIABLES LIKE 'rocksdb_supported_compression_types';
+-------------------------------------+-------------+
| Variable_name                       | Value       |
+-------------------------------------+-------------+
| rocksdb_supported_compression_types | Snappy,Zlib |
+-------------------------------------+-------------+

```

See [MyRocks and Data Compression](../myrocks-and-data-compression/index) for more.

 System and Status Variables
---------------------------

 All MyRocks [system variables](../myrocks-system-variables/index) and [status variables](../myrocks-status-variables/index) are prefaced with "rocksdb", so you can query them with, for example:

 
```
SHOW VARIABLES LIKE 'rocksdb%';
SHOW STATUS LIKE 'rocksdb%';

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/getting-started-with-myrocks/>

Building MyRocks in MariaDB
===========================

     This page describes how to get [MyRocks in MariaDB](../myrocks/index) when compiling MariaDB from source.

 (See <https://github.com/facebook/mysql-5.6/wiki/Build-Steps> for instructions how to build the upstream)

 Build Process and Requirements
------------------------------

 MariaDB compile process will compile [MyRocks](../myrocks/index) into `ha_rocksdb.so` by default if the platform supports it (That is, no WITH\_ROCKSDB switch is necessary).

 Platform requirements:

 * A 64-bit platform (due to some 32 bit compilers having difficulties with RocksDB)
* git installed (or git submodules fetched somehow)
* A sufficiently recent compiler:
	+ gcc >= 4.8, or
	+ clang >= 3.3, or
	+ MS Visual Studio 2015 or newer

 Building on Ubuntu 16.04
------------------------

 The steps were checked on a fresh install of Ubuntu 16.04.2 LTS Xenial.

 
```
sudo apt-get update
sudo apt-get -y install g++ cmake libbz2-dev libaio-dev bison zlib1g-dev libsnappy-dev 
sudo apt-get -y install libgflags-dev libreadline6-dev libncurses5-dev libssl-dev liblz4-dev gdb git
;

```


```
git clone https://github.com/MariaDB/server.git mariadb-10.2
cd mariadb-10.2
git checkout 10.2
git submodule init
git submodule update
cmake .
make -j10

```

This should produce `storage/rocksdb/ha_rocksdb.so` which is MyRocks storage engine in the loadable form.

 Starting MyRocks
----------------

 MyRocks does not require any special way to initialize the data directory. Minimal my.cnf flle:

 
```
cat > ~/my1.cnf <<EOF
[mysqld]

datadir=../mysql-test/var/install.db
plugin-dir=../storage/rocksdb
language=./share/english
socket=/tmp/mysql.sock
port=3307

plugin-load=ha_rocksdb
default-storage-engine=rocksdb
EOF

```

Run the server like this

 
```
(cd mysql-test; ./mtr alias)
cp -r mysql-test/var/install.db ~/data1
cd ../sql
./mysqld --defaults-file=~/my1.cnf

```

Compression libraries. Supported compression libraries are listed in [rocksdb\_supported\_compression\_types](../myrocks-system-variables/index#rocksdb_supported_compression_types). Compiling like the above, I get:

 
```
Snappy,Zlib,LZ4,LZ4HC

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-myrocks-in-mariadb/>

Loading Data Into MyRocks
=========================

    Being a write-optimized storage engine, MyRocks has special ways to load data much faster than normal INSERTs would.

 See 

 * <http://myrocks.io/docs/getting-started/>; the section about "Migrating from InnoDB to MyRocks in production" has some clues.

 * <https://github.com/facebook/mysql-5.6/wiki/Data-Loading> covers the topic in greater detail.

 Note When one loads data with [rocksdb\_bulk\_load=1](../myrocks-system-variables/index#rocksdb_bulk_load) and the data conflicts with the data already in the database, one may get non-trivial errors, for example:

 
```
ERROR 1105 (HY000): [./.rocksdb/test.t1_PRIMARY_2_0.bulk_load.tmp] bulk load error: 
  Invalid argument: External file requires flush

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/loading-data-into-myrocks/>

MyRocks Transactional Isolation
===============================

    TODO: 

 * MyRocks uses snapshot isolation
* Support do READ-COMMITTED and REPEATABLE-READ
* SERIALIZABLE is not supported
	+ There is no "Gap Locking" which makes Statement Based Replication unsafe (See MyRocks and Replication).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-transactional-isolation/>

MyRocks and Replication
=======================

     Details about how MyRocks works with [replication](../high-availability-performance-tuning-mariadb-replication/index).

 MyRocks and Statement-Based Replication
---------------------------------------

 [Statement-based](../binary-log-formats/index#statement-based) replication (SBR) works as follows: SQL statements are executed on the master (possibly concurrently). They are written into the binlog (this fixes their ordering, "a serialization"). The slave then reads the binlog and executes the statements in their binlog order.

 In order to prevent data drift, serial execution of statements on the slave must have the same effect as concurrent execution of these statements on the master. In other words, transaction isolation on the master must be close to `SERIALIZABLE` transaction isolation level (This is not a strict mathematical proof but shows the idea).

 InnoDB achieves this by (almost) supporting `SERIALIZABLE` transactional isolation level. It does so by supporting "Gap Locks". MyRocks doesn't support `SERIALIZABLE` isolation, and it doesn't support gap locks.

 Because of that, generally one cannot use MyRocks and statement-based replication.

 Updating a MyRocks table while having SBR on, will result in an error as follow:

 
```
ERROR 4056 (HY000): Can't execute updates on master with binlog_format != ROW.

```

### Can One Still Use SBR with MyRocks?

 Yes. In many cases, database applications run a restricted set of SQL statements, and it's possible to prove that lack of Gap Lock support is not a problem and data skew will not occur.

 In that case, one can set `@@rocksdb_unsafe_for_binlog=1` and MyRocks will work with SBR. The user is however responsible for making sure their queries are not causing a data skew.

 Read-Free Slave
---------------

 TODO

 Differences From Upstream MyRocks
---------------------------------

 MyRocks upstream (that is, Facebook's MySQL branch) has a number of unique replication enhancements. These are available in upstream's version of MyRocks but not in MariaDB's version of MyRocks.

 * Read-Free Replication (see <https://github.com/facebook/mysql-5.6/wiki/Read-Free-Replication>) TODO

 * `<<unique\_check\_lag\_threshold>>`. This is FB/MySQL-5.6 feature where unique checks are disabled if replication lag exceeds a certain threshold.
* `<<slave\_gtid\_info=OPTIMIZED>>`. This is said to be:

 
```
<<quote>>
"Whether SQL threads update mysql.slave_gtid_info table. If this value "
"is OPTIMIZED, updating the table is done inside storage engines to "
"avoid MySQL layer's performance overhead",
<</quote>>
```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-replication/>

MyRocks and Group Commit with Binary log
========================================

     MyRocks supports group commit with the [binary log](../binary-log/index) ([MDEV-11934](https://jira.mariadb.org/browse/MDEV-11934)).

 Counter Values to Watch
-----------------------

 (The following is only necessary if you are studying MyRocks internals)

 MariaDB's group commit counters are:

 [Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits) - how many transactions were written to the binary log

 [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits) - how many group commits happened. (e.g. if each group had two transactions, this will be twice as small as [Binlog\_commits](../replication-and-binary-log-status-variables/index#binlog_commits))

 On the RocksDB side, there is one relevant counter: [Rocksdb\_wal\_synced](../myrocks-status-variables/index#rocksdb_wal_synced) - How many times RocksDB's WAL file was synced. (TODO: this is after group commit happened, right?)

 On the Value of rocksdb\_wal\_group\_syncs
------------------------------------------

 FB/MySQL-5.6 has a [rocksdb\_wal\_group\_syncs](../myrocks-status-variables/index#rocksdb_wal_group_syncs) counter (The counter is provided by MyRocks, it is not a view of a RocksDB counter). It is increased in rocksdb\_flush\_wal() when doing the rdb->FlushWAL() call.

 rocksdb\_flush\_wal() is called by MySQL's Group Commit when it wants to make the effect of several rocksdb\_prepare() calls persistent.

 So, the value of [rocksdb\_wal\_group\_syncs](../myrocks-status-variables/index#rocksdb_wal_group_syncs) in FB/MySQL-5.6 is similar to [Binlog\_group\_commits](../replication-and-binary-log-status-variables/index#binlog_group_commits) in MariaDB.

 MariaDB doesn't have that call, each rocksdb\_prepare() call takes care of being persistent on its own.

 Because of that, [rocksdb\_wal\_group\_syncs](../myrocks-status-variables/index#rocksdb_wal_group_syncs) is zero for MariaDB. (Currently, it is only incremented when the binlog is rotated).

 Examples
--------

 So for a workload with concurrency=50, n\_queries=10K, one gets 

 * Binlog\_commits=10K
* Binlog\_group\_commits=794
* Rocksdb\_wal\_synced=8362

 This is on a RAM disk

 For a workload with concurrency=50, n\_queries=10K, rotating laptop hdd, one gets 

 * Binlog\_commits= 10K
* Binlog\_group\_commits=1403
* Rocksdb\_wal\_synced=400

 The test took 38 seconds, Number of syncs was 1400+400=1800, which gives 45 syncs/sec which looks normal for this slow rotating desktop hdd.

 Note that the WAL was synced fewer times than there were binlog commit groups (?)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-group-commit-with-binary-log/>

Optimizer Statistics in MyRocks
===============================

     This article describes how MyRocks storage engine provides statistics to the query optimizer.

 There are three kinds of statistics:

 * Table statistics (number of rows in the table, average row size)
* Index cardinality (how distinct values are in the index)
* records-in-range estimates (how many rows are in a certain range "const1 < tbl.key < const2".

 How MyRocks computes statistics
-------------------------------

 MyRocks (actually RocksDB) uses LSM files which are written once and never updated. When an LSM file is written, MyRocks will compute index cardinalities and number-of-rows for the data in the file. (The file generally has rows, index records and/or tombstones for multiple tables/indexes).

 For performance reasons, statistics are computed based on a fraction of rows in the LSM file. The percentage of rows used is controlled by [rocksdb\_table\_stats\_sampling\_pct](../myrocks-system-variables/index#rocksdb_table_stats_sampling_pct); the default value is 10%.

 Before the data is dumped into LSM file, it is stored in the MemTable. MemTable doesn't allow computing index cardinalities, but it can provide an approximate number of rows in the table. Use of MemTable data for statistics is controlled by [rocksdb\_force\_compute\_memtable\_stats](../myrocks-system-variables/index#rocksdb_force_compute_memtable_stats); the default value is `ON`.

 ### Are index statistics predictable?

 Those who create/run MTR tests, need to know whether EXPLAIN output is deterministic. For MyRocks tables, the answer is NO (just like for InnoDB). 

 Statistics are computed using sampling and GetApproximateMemTableStats() which means that the #rows column in the EXPLAIN output may vary slightly. 

 ### Records-in-range estimates

 MyRocks uses RocksDB's GetApproximateSizes() call to produce an estimate for the number of rows in the certain range. The data in MemTable is also taken into account by issuing a GetApproximateMemTableStats call.

 ANALYZE TABLE
-------------

 ANALYZE TABLE will possibly flush the MemTable (depending on the [rocksdb\_flush\_memtable\_on\_analyze](../myrocks-system-variables/index#rocksdb_flush_memtable_on_analyze) and [rocksdb\_pause\_background\_work](../myrocks-system-variables/index#rocksdb_pause_background_work) settings).

 After that, it will re-read statistics from the SST files and re-compute the summary numbers (TODO: and if the data was already on disk, the result should not be different from the one we had before ANALYZE?)

 Debugging helper variables
--------------------------

 There are a few variables that will cause MyRocks to report certain pre-defined estimate numbers to the optimizer:

 * @@rocksdb\_records\_in\_range - if not 0, report that any range has this many rows
* @@rocksdb\_force\_index\_records\_in\_range - if not 0, and FORCE INDEX hint is used, report that any range has this many rows.
* @@rocksdb\_debug\_optimizer\_n\_rows - if not 0, report that any MyRocks table has this many rows.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-statistics-in-myrocks/>

Differences Between MyRocks Variants
====================================

    MyRocks is available in 

 * Facebook's (FB) MySQL branch (originally based on MySQL 5.6)
* MariaDB (from 10.2 and 10.3)
* Percona Server from 5.7

 This page lists differences between these variants.

 
This is a work in progress. The contents are not final

  RocksDB Data Location
---------------------

 FB and Percona store RocksdDB files in $datadir/`.rocksdb`. MariaDB puts them in $datadir/`#rocksdb`. This is more friendly for packaging and OS scripts.

 Compression Algorithms
----------------------

 * FB's branch doesn't provide binaries. One needs to compile it with appropriate compression libraries.

 * In MariaDB, available compression algorithms can be seen in the [rocksdb\_supported\_compression\_types](../myrocks-system-variables/index#rocksdb_supported_compression_types) variable. From [MariaDB 10.7](../what-is-mariadb-107/index), algorithms can be [installed as a plugin](../compression-plugins/index). In earlier versions, the set of supported compression algorithms depends on the platform.
	+ On Ubuntu 16.04 (current LTS) it is `Snappy,Zlib,LZ4,LZ4HC` .
	+ On CentOS 7.4 it is `Snappy,Zlib`.
	+ In the bintar tarball it is `Snappy,Zlib`.
* Percona Server supports: `Zlib, ZSTD, LZ4 (the default), LZ4HC`. Unsupported algorithms: `Snappy, BZip2, XPress`.

 RocksDB Version Information
---------------------------

 * FB's branch provides the `rocksdb_git_hash` \*status\* variable.
* MariaDB provides the `@@rocksdb_git_hash` \*system\* variable.
* Percona Server doesn't provide either.

 RocksDB Version
---------------

 * Facebook's branch uses RocksDB 5.10.0 (the version number can be found in `include/rocksdb/version.h`)

 
```
commit ba295cda29daee3ffe58549542804efdfd969784
Author: Andrew Kryczka <andrewkr@fb.com>
Date:   Fri Jan 12 11:03:55 2018 -0800

```

* MariaDB currently uses 5.8.0

 
```
commit 9a970c81af9807071bd690f4c808c5045866291a
Author: Yi Wu <yiwu@fb.com>
Date:   Wed Sep 13 17:21:35 2017 -0700

```

* Percona Server uses 5.8.0

 
```
commit ab0542f5ec6e7c7e405267eaa2e2a603a77d570b
Author: Maysam Yabandeh <myabandeh@fb.com>
Date:   Fri Sep 29 07:55:22 2017 -0700

```

Binlog Position in information\_schema.rocksdb\_global\_info
------------------------------------------------------------

 * FB branch provides information\_schema.rocksdb\_global\_info type=BINLOG, NAME={FILE, POS, GTID}.
* Percona Server doesn't provide it.
* MariaDB doesn't provide it.

 One use of that information is to take the output of `myrocks_hotbackup` and make it a new master. 

 Gap Lock Detector
-----------------

 * FB branch has a "Gap Lock Detector" feature. It is at the SQL layer. It can be controlled with `gap_lock_XXX` variables and is disabled by default (gap-lock-raise-error=false, gap-lock-write-lock=false).

 * Percona Server has gap lock checking ON but doesn't seem to have any way to control it? Queries that use Gap Lock on MyRocks fail with an error like this:

 
```
insert into tbl2 select * from tbl1;
ERROR 1105 (HY000): Using Gap Lock without full unique key in multi-table or multi-statement transactions
is not allowed. You need to either rewrite queries to use all unique key columns in WHERE equal conditions,
or rewrite to single-table, single-statement transaction.  Query: insert into tbl2 select * from tbl1

```

* MariaDB doesn't include the Gap Lock Detector.

 Generated Columns
-----------------

 * Both MariaDB and Percona Server support [generated columns](../generated-columns/index), but neither one supports them for the MyRocks storage engine (attempts to create a table will produce an error).

 * [Invisible columns](../invisible-columns/index) in [MariaDB 10.3](../what-is-mariadb-103/index) are supported (as they are an SQL layer feature).

 rpl\_skip\_tx\_api
------------------

 Facebook's branch has a performance feature for replication slaves, `rpl_skip_tx_api`. It is not available in MariaDB or in Percona Server.

 Details
-------

 The above comparison was made using

 * FB/MySQL 5.6.35
* Percona Server 5.7.20-19-log
* [MariaDB 10.2.13](https://mariadb.com/kb/en/mariadb-10213-release-notes/) (MyRocks is beta)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/differences-between-myrocks-variants/>

MyRocks and Bloom Filters
=========================

     Bloom filters are used to reduce read amplification. Bloom filters can be set on a per-column family basis (see [myrocks-column-families](../myrocks-column-families/index)). 

 Bloom Filter Parameters
-----------------------

 * How many bits to use
* whole\_key\_filtering=true/false
* Whether the bloom filter is for the entire key or for the prefix. In case of a prefix, you need to look at the index definition and compute the desired prefix length.

 ### Computing Prefix Length

 * It's 4 bytes for `index_nr`
* Then, for fixed-size columns (integer, date[time], decimal) it is key\_length as shown by `EXPLAIN`. For VARCHAR columns, determining the length is tricky (It depends on the values stored in the table. Note that MyRocks encodes VARCHARs with "Variable-Length Space-Padded Encoding" format).

 Configuring Bloom Filter
------------------------

 To enable 10-bit bloom filter for 8-byte prefix length for column family "cf1", put this into my.cnf:

 
```
rocksdb_override_cf_options='cf1={block_based_table_factory={filter_policy=bloomfilter:10:false;whole_key_filtering=0;};prefix_extractor=capped:8};'

```

and restart the server.

 Check if the column family actually uses the bloom filter:

 
```
select * 
from information_schema.rocksdb_cf_options 
where 
  cf_name='cf1' and
  option_type IN ('TABLE_FACTORY::FILTER_POLICY','PREFIX_EXTRACTOR');

```


```
+---------+------------------------------+----------------------------+
| CF_NAME | OPTION_TYPE                  | VALUE                      |
+---------+------------------------------+----------------------------+
| cf1     | PREFIX_EXTRACTOR             | rocksdb.CappedPrefix.8     |
| cf1     | TABLE_FACTORY::FILTER_POLICY | rocksdb.BuiltinBloomFilter |
+---------+------------------------------+----------------------------+

```

Checking if Bloom Filter is Useful
----------------------------------

 Watch these status variables:

 
```
show status like '%bloom%';
+-------------------------------------+-------+
| Variable_name                       | Value |
+-------------------------------------+-------+
| Rocksdb_bloom_filter_prefix_checked | 1     |
| Rocksdb_bloom_filter_prefix_useful  | 0     |
| Rocksdb_bloom_filter_useful         | 0     |
+-------------------------------------+-------+

```

Other useful variables are: 

 * `rocksdb_force_flush_memtable_now` - bloom filter is only used when reading data from disk. If you are doing testing, flush the data to disk first.
* `rocksdb_skip_bloom_filter_on_read` - skip using the bloom filter (default is FALSE).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-bloom-filters/>

MyRocks and CHECK TABLE
=======================

    MyRocks supports the [CHECK TABLE](../check-table/index) command. 

 The command will do a number of checks to verify that the table data is self-consistent.

 The details about the errors are printed into the [error log](../error-log/index). If [log\_warnings](../server-system-variables/index#log_warnings) > 2, the error log will also have some informational messages which can help with troubleshooting.

 Besides this, RocksDB has its own (low-level) log in `#rocksdb/LOG` file.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-check-table/>

MyRocks and Data Compression
============================

       
 MyRocks supports several compression algorithms.   


 Supported Compression Algorithms
--------------------------------

 Supported compression algorithms can be checked like so:

 
```
show variables like 'rocksdb%compress%';
+-------------------------------------+------------------------------------+
| Variable_name                       | Value                              |
+-------------------------------------+------------------------------------+
| rocksdb_supported_compression_types | Snappy,Zlib,LZ4,LZ4HC,ZSTDNotFinal |
+-------------------------------------+------------------------------------+

```

Another way to make the check is to look into `#rocksdb/LOG` file in the data directory. It should have lines like:

 
```
2019/04/12-14:08:23.869919 7f839188b540 Compression algorithms supported:
2019/04/12-14:08:23.869920 7f839188b540         kZSTDNotFinalCompression supported: 1
2019/04/12-14:08:23.869922 7f839188b540         kZSTD supported: 1
2019/04/12-14:08:23.869923 7f839188b540         kXpressCompression supported: 0
2019/04/12-14:08:23.869924 7f839188b540         kLZ4HCCompression supported: 1
2019/04/12-14:08:23.869924 7f839188b540         kLZ4Compression supported: 1
2019/04/12-14:08:23.869925 7f839188b540         kBZip2Compression supported: 0
2019/04/12-14:08:23.869926 7f839188b540         kZlibCompression supported: 1
2019/04/12-14:08:23.869927 7f839188b540         kSnappyCompression supported: 1

```

Compression Settings
--------------------

 Compression is set on a per-Column Family basis. See [MyRocks Column Families](../myrocks-column-families/index).

 ### Checking Compression Settings

 To check current compression settings for a column family one can use a query like so:

 
```
select * from information_schema.rocksdb_cf_options 
where option_type like '%ompression%' and cf_name='default';

```

The output will be like:

 
```
+---------+-----------------------------------------+---------------------------+
| CF_NAME | OPTION_TYPE                             | VALUE                     |
+---------+-----------------------------------------+---------------------------+
| default | COMPRESSION_TYPE                        | kSnappyCompression        |
| default | COMPRESSION_PER_LEVEL                   | NUL                       |
| default | COMPRESSION_OPTS                        | -14:32767:0               |
| default | BOTTOMMOST_COMPRESSION                  | kDisableCompressionOption |
| default | TABLE_FACTORY::VERIFY_COMPRESSION       | 0                         |
| default | TABLE_FACTORY::ENABLE_INDEX_COMPRESSION | 1                         |
+---------+-----------------------------------------+---------------------------+

```

Current column family settings will be used for the new SST files.

 ### Modifying Compression Settings

 Compression settings are not dynamic parameters, one cannot change them by setting [rocksdb\_update\_cf\_options](../myrocks-system-variables/index#rocksdb_update_cf_options).

 The procedure to change compression settings is as follows:

 * Edit `my.cnf` to set [rocksdb\_override\_cf\_options](../myrocks-system-variables/index#rocksdb_override_cf_options).

 Example:

 
```
rocksdb-override-cf-options='cf1={compression=kZSTD;bottommost_compression=kZSTD;}'

```

* Restart the server.

 The data will not be re-compressed immediately. However, all new SST files will use the new compression settings, so as data gets inserted/updated the column family will gradually start using the new option.

 ### Caveat: Syntax Errors

 Please note that `rocksdb-override-cf-options` syntax is quite strict. Any typos will result in the parse error, and MyRocks plugin will not be loaded. Depending on your configuration, the server may still start. If it does start, you can use this command to check if the plugin is loaded:

 
```
select * from information_schema.plugins where plugin_name='ROCKSDB'

```

(note that you need the "ROCKSDB" plugin. Other auxiliary plugins like "ROCKSDB\_TRX" might still get loaded).

 Another way is to detect the error is check the error log. When option parsing fails, it will contain messages like so:

 
```
2019-04-16 11:07:57 140283675678016 [Warning] Invalid cf config for cf1 in override options (options: cf1={compression=kLZ4Compression;bottommost_compression=kZSTDCompression;})
2019-04-16 11:07:57 140283675678016 [ERROR] RocksDB: Failed to initialize CF options map.
2019-04-16 11:07:57 140283675678016 [ERROR] Plugin 'ROCKSDB' init function returned error.
2019-04-16 11:07:57 140283675678016 [ERROR] Plugin 'ROCKSDB' registration as a STORAGE ENGINE failed.

```

Checking How the Data is Compressed
-----------------------------------

 A query to check what compression is used in the SST files that store the data for a given table (test.t1):

 
```
select
  SP.sst_name, SP.compression_algo
from
  information_schema.rocksdb_sst_props SP,
  information_schema.rocksdb_ddl D,
  information_schema.rocksdb_index_file_map IFM
where
  D.table_schema='test' and D.table_name='t1' and
  D.index_number= IFM.index_number and
  IFM.sst_name=SP.sst_name;

```

Example output:

 
```
+------------+------------------+
| sst_name   | compression_algo |
+------------+------------------+
| 000028.sst | Snappy           |
| 000028.sst | Snappy           |
| 000026.sst | Snappy           |
| 000026.sst | Snappy           |
+------------+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-data-compression/>

MyRocks and Index-Only Scans
============================

     This article is about [MyRocks](../myrocks/index) and index-only scans on secondary indexes. It applies to MariaDB's MyRocks, Facebook's MyRocks, and other variants.

 Secondary Keys Only
-------------------

 The primary key in MyRocks is always the clustered key, that is, the index record is THE table record and so it's not possible to do "index only" because there isn't anything that is not in the primary key's (Key,Value) pair.

 Secondary keys may or may not support index-only scans, depending on the datatypes of the columns that the query is trying to read.

 Background: Mem-Comparable Keys
-------------------------------

 MyRocks indexes store "mem-comparable keys" (that is, the key values are compared with `memcmp`). For some datatypes, it is easily possible to convert between the column value and its mem-comparable form, while for others the conversion is one-way. 

 For example, in case-insensitive collations capital and regular letters are considered identical, i.e. 'c' ='C'. For some datatypes, MyRocks stores some extra data which allows it to restore the original value back. (For the `latin1_general_ci` [collation](../character-sets/index) and character 'c', for example, it will store one bit which says whether the original value was a small 'c' or a capital letter 'C'). This doesn't work for all datatypes, though.

 Index-Only Support for Various Datatypes
----------------------------------------

 Index-only scans are supported for numeric and date/time datatypes. For CHAR and VAR[CHAR], it depends on which collation is used, see below for details.

 Index-only scans are currently not supported for less frequently used datatypes, like

 * `[BIT(n)](../bit/index)`
* `[SET(...)](../set-data-type/index)`
* `[ENUM(...)](../enum/index)` *It is actually possible to add support for those, feel free to write a patch or at least make a case why a particular datatype is important*

 Index-Only Support for Various Collations
-----------------------------------------

 As far as Index-only support is concerned, MyRocks distinguishes three kinds of collations:

 ### 1. Binary (Reversible) Collations

 These are `binary`, `latin1_bin`, and `utf8_bin`.

 For these collations, it is possible to convert a value back from its mem-comparable form. Hence, one can restore the original value back from its index record, and index-only scans are supported.

 ### 2. Restorable Collations

 These are collations where one can store some extra information which helps to restore the original value.

 Criteria (from storage/rocksdb/rdb\_datadic.cc, rdb\_is\_collation\_supported()) are:

 * The charset should use 1-byte characters (so, unicode-based collations are not included)
* strxfrm(1 byte) = {one 1-byte weight value always}
* no binary sorting
* PAD attribute

 The examples are: `latin1_general_ci`, `latin1_general_cs`, `latin1_swedish_ci`, etc.

 Index-only scans are supported for these collations.

 ### 3. All Other Collations

 For these collations, there is no known way to restore the value from its mem-comparable form, and so index-only scans are not supported.

 MyRocks needs to fetch the clustered PK record to get the field value.

 Covering Secondary Key Lookups for VARCHARs
-------------------------------------------

 TODO: there is also this optimization:

 <https://github.com/facebook/mysql-5.6/issues/303> <https://github.com/facebook/mysql-5.6/commit/f349c95848e92b5b27b44f0e57194100eb0997e7>

 document it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-and-index-only-scans/>

MyRocks Column Families
=======================

    [MyRocks](../myrocks/index) stores data in column families. These are similar to tablespaces. By default, the data is stored in the `default` column family.

 One can specify which column family the data goes to by using index comments:

 
```
 INDEX index_name(col1, col2, ...) COMMENT 'column_family_name'

```

 If the column name starts with `rev:`, the column family is reverse-ordered.

 Reasons for Column Families
---------------------------

 Storage parameters like 

 * Bloom filter settings
* Compression settings
* Whether the data is stored in reverse order

 are specified on a per-column family basis.

 Creating a Column Family
------------------------

 When creating a table or index, you can specify the name of the column family for it. If the column family doesn't exist, it will be automatically created.

 Dropping a Column Family
------------------------

 There is currently no way to drop a column family. RocksDB supports this internally but MyRocks doesn't provide any way to do it.

 Setting Column Family Parameters
--------------------------------

 Use these variables:

 * [rocksdb\_default\_cf\_options](../myrocks-system-variables/index#rocksdb_default_cf_options) - a my.cnf parameter specifying default options for all column families.
* [rocksdb\_override\_cf\_options](../myrocks-system-variables/index#rocksdb_override_cf_options) - a my.cnf parameter specifying per-column family option overrides.
* [rocksdb\_update\_cf\_options](../myrocks-system-variables/index#rocksdb_update_cf_options) - a dynamically-settable variable which allows to change parameters online. Not all parameters can be changed.

 ### rocksdb\_override\_cf\_options

 This parameter allows one to override column family options for specific column families. Here is an example of how to set option1=value1 and option2=value for column family cf1, and option3=value3 for column family cf3:

 
```
rocksdb_override_cf_options='cf1={option1=value1;option2=value2};cf2={option3=value3}'

```

One can check the contents of `INFORMATION_SCHEMA.ROCKSDB_CF_OPTIONS` to see what options are available.

 Options that are frequently configured are:

 * Data compression. See [myrocks-and-data-compression](../myrocks-and-data-compression/index).
* Bloom Filters. See [myrocks-and-bloom-filters](../myrocks-and-bloom-filters/index).

 Examining Column Family Parameters
----------------------------------

 See the [INFORMATION\_SCHEMA.ROCKSDB\_CF\_OPTIONS](../information-schema-rocksdb_cf_options-table/index) table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-column-families/>

MyRocks in MariaDB 10.2 vs MariaDB 10.3
=======================================

    MyRocks storage engine itself is identical in [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index).

 [MariaDB 10.3](../what-is-mariadb-103/index) has a feature that should be interesting for MyRocks users. It is the [gtid\_pos\_auto\_engines](../gtid/index#gtid_pos_auto_engines) option ([MDEV-12179](https://jira.mariadb.org/browse/MDEV-12179)). This is a performance feature for replication slaves that use multiple transactional storage engines. 

 For further information, see [mysql.gtid\_slave\_pos table](../mysqlgtid_slave_pos-table/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-in-mariadb-102-vs-mariadb-103/>

MyRocks Performance Troubleshooting
===================================

     MyRocks exposes its performance metrics through several interfaces:

 * Status variables
* SHOW ENGINE ROCKSDB STATUS
* RocksDB's perf context

 the contents slightly overlap, but each source has its own unique information, so be sure to check all three.

 ### Status Variables

 Check the output of

 
```
SHOW STATUS like 'Rocksdb%'

```

See [MyRocks Status Variables](../myrocks-status-variables/index) for more information.

 ### SHOW ENGINE ROCKSDB STATUS

 This produces a lot of information.

 One particularly interesting part is compaction statistics. It shows the amount of data on each SST level and other details:

 
```
*************************** 4. row ***************************
  Type: CF_COMPACTION
  Name: default
Status: 
** Compaction Stats [default] **
Level    Files   Size     Score Read(GB)  Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
----------------------------------------------------------------------------------------------------------------------------------------------------------
  L0      3/0   30.16 MB   1.0      0.0     0.0      0.0      11.9     11.9       0.0   1.0      0.0     76.6       159       632    0.251       0      0
  L1      5/0   247.54 MB   1.0      0.7     0.2      0.5       0.5      0.0      11.6   2.6     58.5     44.1        12         4    2.926     30M    10M
  L2    112/0    2.41 GB   1.0      0.6     0.0      0.6       0.5     -0.1      11.4  43.4     55.2     45.9        11         1   10.827     21M  3588K
  L3    466/0    8.91 GB   0.4      0.0     0.0      0.0       0.0      0.0       8.9   0.0      0.0      0.0         0         0    0.000       0      0
 Sum    586/0   11.59 GB   0.0      1.3     0.2      1.0      12.8     11.8      32.0   1.1      7.1     72.6       181       637    0.284     52M    13M
 Int      0/0    0.00 KB   0.0      0.9     0.1      0.8       0.8      0.0       0.1  20.5     48.4     45.3        19         6    3.133     33M  3588K

```

### Performance Context

 RocksDB has an internal mechanism called "perf context". The counter values are exposed through two tables:

 * [INFORMATION\_SCHEMA.ROCKSDB\_PERF\_CONTEXT\_GLOBAL](../information-schema-rocksdb_perf_context_global-table/index) - global counters
* [INFORMATION\_SCHEMA.ROCKSDB\_PERF\_CONTEXT](../information-schema-rocksdb_perf_context-table/index) - Per-table/partition counters

 By default statistics are NOT collected. One needs to set [rocksdb\_perf\_context\_level](../myrocks-system-variables/index#rocksdb_perf_context_level) to some value (e.g. 3) to enable collection.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/myrocks-performance-troubleshooting/>

Information Schema Tables
==========================

  

| Title | Description |
| --- | --- |
|  [Information Schema InnoDB Tables](../information-schema-innodb-tables/index) |  All InnoDB-specific Information Schema tables.  |
|  [Information Schema MyRocks Tables](../information-schema-myrocks-tables/index) |  List of Information Schema tables specifically related to MyRocks.  |
|  [Information Schema XtraDB Tables](../information-schema-xtradb-tables/index) |  All XtraDB-specific Information Schema tables.  |
|  [ColumnStore Information Schema Tables](../columnstore-information-schema-tables/index) |  ColumnStore-related Information Schema tables  |
|  [Information Schema ALL\_PLUGINS Table](../all-plugins-table-information-schema/index) |  Information about server plugins, whether installed or not.  |
|  [Information Schema APPLICABLE\_ROLES Table](../information-schema-applicable_roles-table/index) |  Roles available to be used.  |
|  [Information Schema CHARACTER\_SETS Table](../information-schema-character_sets-table/index) |  Supported character sets.  |
|  [Information Schema CHECK\_CONSTRAINTS Table](../information-schema-check_constraints-table/index) |  Supported check constraints.  |
|  [Information Schema CLIENT\_STATISTICS Table](../information-schema-client_statistics-table/index) |  Statistics about client connections.  |
|  [Information Schema COLLATION\_CHARACTER\_SET\_APPLICABILITY Table](../information-schema-collation_character_set_applicability-table/index) |  Collations and associated character sets  |
|  [Information Schema COLLATIONS Table](../information-schema-collations-table/index) |  Supported collations.  |
|  [Information Schema COLUMN\_PRIVILEGES Table](../information-schema-column_privileges-table/index) |  Column privileges  |
|  [Information Schema COLUMNS Table](../information-schema-columns-table/index) |  Information about table fields.  |
|  [Information Schema DISKS Table](../information-schema-disks-table/index) |  Plugin that allows the disk space situation to be monitored.  |
|  [Information Schema ENABLED\_ROLES Table](../information-schema-enabled_roles-table/index) |  Enabled roles for the current session.  |
|  [Information Schema ENGINES Table](../information-schema-engines-table/index) |  Storage engine information.  |
|  [Information Schema EVENTS Table](../information-schema-events-table/index) |  Server event information  |
|  [Information Schema FEEDBACK Table](../information-schema-feedback-table/index) |  Contents submitted by the Feedback Plugin  |
|  [Information Schema FILES Table](../information-schema-files-table/index) |  The FILES tables is unused in MariaDB.  |
|  [Information Schema GEOMETRY\_COLUMNS Table](../information-schema-geometry_columns-table/index) |  Support for Spatial Reference systems for GIS data  |
|  [Information Schema GLOBAL\_STATUS and SESSION\_STATUS Tables](../information-schema-global_status-and-session_status-tables/index) |  Global and session status variables  |
|  [Information Schema GLOBAL\_VARIABLES and SESSION\_VARIABLES Tables](../information-schema-global_variables-and-session_variables-tables/index) |  Global and session system variables  |
|  [Information Schema INDEX\_STATISTICS Table](../information-schema-index_statistics-table/index) |  Statistics on index usage  |
|  [Information Schema KEY\_CACHES Table](../information-schema-key_caches-table/index) |  Segmented key cache statistics.  |
|  [Information Schema KEY\_COLUMN\_USAGE Table](../information-schema-key_column_usage-table/index) |  Key columns that have constraints.  |
|  [Information Schema KEYWORDS Table](../information-schema-keywords-table/index) |  MariaDB keywords.  |
|  [Information Schema LOCALES Table](../information-schema-locales-table/index) |  Compiled-in server locales.  |
|  [Information Schema METADATA\_LOCK\_INFO Table](../information-schema-metadata_lock_info-table/index) |  Active metadata locks.  |
|  [Information Schema MROONGA\_STATS Table](../information-schema-mroonga_stats-table/index) |  Mroonga activities statistics.  |
|  [Information Schema OPTIMIZER\_TRACE Table](../information-schema-optimizer_trace-table/index) |  Contains Optimizer Trace information.  |
|  [Information Schema PARAMETERS Table](../information-schema-parameters-table/index) |  Information about stored procedures and stored functions parameters.  |
|  [Information Schema PARTITIONS Table](../information-schema-partitions-table/index) |  Table partition information  |
|  [Information Schema PLUGINS Table](../plugins-table-information-schema/index) |  Information Schema table containing information on plugins installed on a server.  |
|  [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) |  Thread information.  |
|  [Information Schema PROFILING Table](../information-schema-profiling-table/index) |  Statement resource usage  |
|  [Information Schema QUERY\_CACHE\_INFO Table](../information-schema-query_cache_info-table/index) |  View the contents of the query cache.  |
|  [Information Schema QUERY\_RESPONSE\_TIME Table](../information-schema-query_response_time-table/index) |  Query time information.  |
|  [Information Schema REFERENTIAL\_CONSTRAINTS Table](../information-schema-referential_constraints-table/index) |  Foreign key information  |
|  [Information Schema ROUTINES Table](../information-schema-routines-table/index) |  Stored procedures and stored functions information  |
|  [Information Schema SCHEMA\_PRIVILEGES Table](../information-schema-schema_privileges-table/index) |  Database privilege information  |
|  [Information Schema SCHEMATA Table](../information-schema-schemata-table/index) |  Information about databases.  |
|  [Information Schema SPATIAL\_REF\_SYS Table](../information-schema-spatial_ref_sys-table/index) |  Information on each spatial reference system used in the database.  |
|  [Information Schema SPIDER\_ALLOC\_MEM Table](../information-schema-spider_alloc_mem-table/index) |  Information about Spider's memory usage.  |
|  [Information Schema SPIDER\_WRAPPER\_PROTOCOLS Table](../information-schema-spider_wrapper_protocols-table/index) |  Installed along with the Spider storage engine.  |
|  [Information Schema SQL\_FUNCTIONS Table](../information-schema-sql_functions-table/index) |  Functions in MariaDB.  |
|  [Information Schema STATISTICS Table](../information-schema-statistics-table/index) |  Table index information.  |
|  [Information Schema SYSTEM\_VARIABLES Table](../information-schema-system_variables-table/index) |  Current global and session values and various metadata of all system variables.  |
|  [Information Schema TABLE\_CONSTRAINTS Table](../information-schema-table_constraints-table/index) |  Tables containing constraints.  |
|  [Information Schema TABLE\_PRIVILEGES Table](../information-schema-table_privileges-table/index) |  Table privileges  |
|  [Information Schema TABLE\_STATISTICS Table](../information-schema-table_statistics-table/index) |  Statistics on table usage.  |
|  [Information Schema TABLES Table](../information-schema-tables-table/index) |  Database table information.  |
|  [Information Schema TABLESPACES Table](../information-schema-tablespaces-table/index) |  Information about active tablespaces.  |
|  [Information Schema THREAD\_POOL\_GROUPS Table](../information-schema-thread_pool_groups-table/index) |  Information Schema THREAD\_POOL\_GROUPS Table.  |
|  [Information Schema THREAD\_POOL\_QUEUES Table](../information-schema-thread_pool_queues-table/index) |  Information Schema THREAD\_POOL\_QUEUES Table.  |
|  [Information Schema THREAD\_POOL\_STATS Table](../information-schema-thread_pool_stats-table/index) |  Information Schema THREAD\_POOL\_STATS Table.  |
|  [Information Schema THREAD\_POOL\_WAITS Table](../information-schema-thread_pool_waits-table/index) |  Information Schema THREAD\_POOL\_WAITS Table.  |
|  [Information Schema TRIGGERS Table](../information-schema-triggers-table/index) |  Information about triggers  |
|  [Information Schema USER\_PRIVILEGES Table](../information-schema-user_privileges-table/index) |  Global user privilege information derived from the mysql.global\_priv grant table  |
|  [Information Schema USER\_STATISTICS Table](../information-schema-user_statistics-table/index) |  User activity  |
|  [Information Schema USER\_VARIABLES Table](../information-schema-user_variables-table/index) |  User-defined variable information.  |
|  [Information Schema VIEWS Table](../information-schema-views-table/index) |  Information about views.  |
|  [Information Schema WSREP\_MEMBERSHIP Table](../information-schema-wsrep_membership-table/index) |  Galera node cluster membership information.  |
|  [Information Schema WSREP\_STATUS Table](../information-schema-wsrep_status-table/index) |  Galera node cluster status information.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-tables/>

About XtraDB
============

     Percona XtraDB was an enhanced version of the InnoDB storage engine [used in MariaDB before MariaDB 10.2](../why-does-mariadb-102-use-innodb-instead-of-xtradb/index), designed to better scale on modern hardware, and it includes a variety of other features useful in high performance environments.

 It is fully backwards compatible, and it identifies itself to MariaDB as "`ENGINE=InnoDB`" (just like InnoDB), and so can be used as a drop-in replacement for standard InnoDB.

 Percona XtraDB includes all of InnoDB's robust, reliable [ACID](../acid-concurrency-control-with-transactions/index)-compliant design and advanced MVCC architecture, and builds on that solid foundation with more features, more tunability, more metrics, and more scalability. In particular, it is designed to scale better on many cores, to use memory more efficiently, and to be more convenient and useful. The new features are especially designed to alleviate some of InnoDB's limitations. We choose features and fixes based on customer requests and on our best judgment of real-world needs as a high-performance consulting company. 

 XtraDB was also available in MariaDB for Windows.

 Percona XtraDB versions in MariaDB
----------------------------------

 ### [MariaDB 10.1](../what-is-mariadb-101/index)

 * XtraDB from [Percona Server 5.6.49-89.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.49-89.0.html) in [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/)
* XtraDB from [Percona Server 5.6.46-86.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.46-86.2.html) in [MariaDB 10.1.44](https://mariadb.com/kb/en/mariadb-10144-release-notes/)
* XtraDB from [Percona Server 5.6.43-84.3](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.43-84.3.html) in [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/)
* XtraDB from [Percona Server 5.6.41-84.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.41-84.1.html) in [MariaDB 10.1.36](https://mariadb.com/kb/en/mariadb-10136-release-notes/)
* XtraDB from [Percona Server 5.6.38-83.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.38-83.0.html)[[1](#_note-0)] in [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/)
* XtraDB from [Percona Server 5.6.37-82.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.37-82.2.html)[[2](#_note-1)]in [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/)
* XtraDB from [Percona Server 5.6.36-82.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.1.html) in [MariaDB 10.1.26](https://mariadb.com/kb/en/mariadb-10126-release-notes/)
* XtraDB from [Percona Server 5.6.36-82.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.0.html) in [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/)
* XtraDB from [Percona Server 5.6.35-80.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.35-80.0.html) in [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/)
* XtraDB from [Percona Server 5.6.34-79.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.34-79.1.html) in [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/)
* XtraDB from [Percona Server 5.6.33-79.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.33-79.0.html)[[3](#_note-2)] in [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10119-release-notes/)
* XtraDB from [Percona Server 5.6.32-78.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.32-78.1.html) in [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/)
* XtraDB from [Percona Server 5.6.31-77.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.31-77.0.html) in [MariaDB 10.1.17](https://mariadb.com/kb/en/mariadb-10117-release-notes/)
* XtraDB from [Percona Server 5.6.30-76.3](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.30-76.3.html) in [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/)
* XtraDB from [Percona Server 5.6.29-76.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.29-76.2.html) in [MariaDB 10.1.14](https://mariadb.com/kb/en/mariadb-10114-release-notes/)
* XtraDB from [Percona Server 5.6.28-76.1](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.28-76.1.html) in [MariaDB 10.1.12](https://mariadb.com/kb/en/mariadb-10112-release-notes/)
* XtraDB from [Percona Server 5.6.26-76.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.26-76.0.html) in [MariaDB 10.1.10](https://mariadb.com/kb/en/mariadb-10110-release-notes/)
* XtraDB from [Percona Server 5.6.26-74.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.26-74.0.html) in [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/)
* XtraDB from [Percona Server 5.6.25-73.1](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.25-73.1.html) in [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/)
* XtraDB from [Percona Server 5.6.24-72.2](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.24-72.2.html) in [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/)
* XtraDB from [Percona Server 5.6.23-72.1](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.23-72.1.html) in [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/)
* XtraDB from [Percona Server 5.6.22-72.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.22-72.0.html) in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/)
* XtraDB from [Percona Server 5.6.21-70.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.21-70.0.html) in [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/)
* XtraDB from [Percona Server 5.6.17-65.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.17-65.0.html) in [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)

 ### [MariaDB 10.0](../what-is-mariadb-100/index)

 * XtraDB from [Percona Server 5.6.42-84.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.42-84.2.html) in [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10038-release-notes/)
* XtraDB from [Percona Server 5.6.41-84.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.41-84.1.html) in [MariaDB 10.0.37](https://mariadb.com/kb/en/mariadb-10037-release-notes/)
* XtraDB from [Percona Server 5.6.39-83.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.39-83.1.html) in [MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10035-release-notes/)
* XtraDB from [Percona Server 5.6.38-83.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.38-83.0.html)[[4](#_note-3)]in [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10034-release-notes/)
* XtraDB from [Percona Server 5.6.37-82.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.37-82.2.html)[[5](#_note-4)]in [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10033-release-notes/)
* XtraDB from [Percona Server 5.6.36-82.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.1.html) in [MariaDB 10.0.32](https://mariadb.com/kb/en/mariadb-10032-release-notes/)
* XtraDB from [Percona Server 5.6.36-82.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.36-82.0.html) in [MariaDB 10.0.31](https://mariadb.com/kb/en/mariadb-10031-release-notes/)
* XtraDB from [Percona Server 5.6.35-80.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.35-80.0.html) in [MariaDB 10.0.30](https://mariadb.com/kb/en/mariadb-10030-release-notes/)
* XtraDB from [Percona Server 5.6.34-79.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.34-79.1.html) in [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10029-release-notes/)
* XtraDB from [Percona Server 5.6.33-79.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.33-79.0.html)[[6](#_note-5)] in [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10028-release-notes/)
* XtraDB from [Percona Server 5.6.31-77.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.31-77.0.html) in [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/)
* XtraDB from [Percona Server 5.6.30-76.3](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.30-76.3.html) in [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10026-release-notes/)
* XtraDB from [Percona Server 5.6.29-76.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.29-76.2.html) in [MariaDB 10.0.25](https://mariadb.com/kb/en/mariadb-10025-release-notes/)
* XtraDB from [Percona Server 5.6.28-76.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.28-76.1.html) in [MariaDB 10.0.24](https://mariadb.com/kb/en/mariadb-10024-release-notes/)
* XtraDB from [Percona Server 5.6.27-76.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.27-76.0.html) in [MariaDB 10.0.23](https://mariadb.com/kb/en/mariadb-10023-release-notes/)
* XtraDB from [Percona Server 5.6.26-74.0](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.26-74.0.html) in [MariaDB 10.0.22](https://mariadb.com/kb/en/mariadb-10022-release-notes/)
* XtraDB from [Percona Server 5.6.25-73.1](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.25-73.1.html) in [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10021-release-notes/)
* XtraDB from [Percona Server 5.6.24-72.2](https://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.24-72.2.html) in [MariaDB 10.0.20](https://mariadb.com/kb/en/mariadb-10020-release-notes/)
* XtraDB from [Percona Server 5.6.23-72.1](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.23-72.1.html) in [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/)
* XtraDB from [Percona Server 5.6.22-72.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.22-72.0.html) in [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/)
* XtraDB from [Percona Server 5.6.22-71.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.22-71.0.html) in [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/)
* XtraDB from [Percona Server 5.6.21-70.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.21-70.0.html) in [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/)
* XtraDB from [Percona Server 5.6.20-68.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.20-68.0.html) in [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/)
* XtraDB from [Percona Server 5.6.19-67.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.19-67.0.html) in [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/)
* XtraDB from [Percona Server 5.6.17-65.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.17-65.0.html) in [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/)
* XtraDB from [Percona Server 5.6.14-rel62.0](http://www.percona.com/doc/percona-server/5.6/release-notes/Percona-Server-5.6.14-62.0.html) in [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/)

 ### [MariaDB 5.5](../what-is-mariadb-55/index)

 * XtraDB from [Percona Server 5.5.61-38.13](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.61-38.13.html) in [MariaDB 5.5.62](https://mariadb.com/kb/en/mariadb-5562-release-notes/)
* XtraDB from [Percona Server 5.5.59-38.11](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.59-38.11.html) in [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5560-release-notes/)
* XtraDB from [Percona Server 5.5.58-38.10](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.58-38.10.html) in [MariaDB 5.5.59](https://mariadb.com/kb/en/mariadb-5559-release-notes/)
* XtraDB from [Percona Server 5.5.55-38.9](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.55-38.9.html) in [MariaDB 5.5.58](https://mariadb.com/kb/en/mariadb-5558-release-notes/)
* XtraDB from [Percona Server 5.5.55-38.8](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.55-38.8.html) in [MariaDB 5.5.57](https://mariadb.com/kb/en/mariadb-5557-release-notes/)
* XtraDB from [Percona Server 5.5.52-38.3](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.52-38.3.html) in [MariaDB 5.5.53](https://mariadb.com/kb/en/mariadb-5553-release-notes/)
* XtraDB from [Percona Server 5.5.50-38.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.50-38.0.html) in [MariaDB 5.5.51](https://mariadb.com/kb/en/mariadb-5551-release-notes/)
* XtraDB from [Percona Server 5.5.49-37.9](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.49-37.9.html) in [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5550-release-notes/)
* XtraDB from [Percona Server 5.5.48-37.8](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.48-37.8.html) in [MariaDB 5.5.49](https://mariadb.com/kb/en/mariadb-5549-release-notes/)
* XtraDB from [Percona Server 5.5.46-37.7](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.46-37.7.html) in [MariaDB 5.5.48](https://mariadb.com/kb/en/mariadb-5548-release-notes/)
* XtraDB from [Percona Server 5.5.46-37.6](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.46-37.6.html) in [MariaDB 5.5.47](https://mariadb.com/kb/en/mariadb-5547-release-notes/)
* XtraDB from [Percona Server 5.5.45-37.4](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.45-37.4.html) in [MariaDB 5.5.46](https://mariadb.com/kb/en/mariadb-5546-release-notes/)
* XtraDB from [Percona Server 5.5.44-37.3](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.44-37.3.html) in [MariaDB 5.5.45](https://mariadb.com/kb/en/mariadb-5545-release-notes/)
* XtraDB from [Percona Server 5.5.42-37.2](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.42-37.2.html) in [MariaDB 5.5.44](https://mariadb.com/kb/en/mariadb-5544-release-notes/)
* XtraDB from [Percona Server 5.5.42-37.1](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.42-37.1.html) in [MariaDB 5.5.43](https://mariadb.com/kb/en/mariadb-5543-release-notes/)
* XtraDB from [Percona Server 5.5.40-36.1](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.40-36.1.html) in [MariaDB 5.5.40](https://mariadb.com/kb/en/mariadb-5540-release-notes/)
* XtraDB from [Percona Server 5.5.38-35.2](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.38-35.2.html) in [MariaDB 5.5.39](https://mariadb.com/kb/en/mariadb-5539-release-notes/)
* XtraDB from [Percona Server 5.5.37-35.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.37-35.0.html) in [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5538-release-notes/)
* XtraDB from [Percona Server 5.5.36-34.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.36-34.0.html) in [MariaDB 5.5.37](https://mariadb.com/kb/en/mariadb-5537-release-notes/)
* XtraDB from [Percona Server 5.5.35-33.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.35-33.0.html) in [MariaDB 5.5.35](https://mariadb.com/kb/en/mariadb-5535-release-notes/)
* XtraDB from [Percona Server 5.5.34-32.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.34-32.0.html) in [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/)
* XtraDB from [Percona Server 5.5.33-31.1](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.33-31.1.html) in [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/)
* XtraDB from [Percona Server-5.5.32-31.0](http://www.percona.com/doc/percona-server/5.5/release-notes/Percona-Server-5.5.32-31.0.html) in [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5532-release-notes/)

 ### 
[MariaDB 5.2](../what-is-mariadb-52/index) and [MariaDB 5.3](../what-is-mariadb-53/index)

 * [MariaDB 5.2](../what-is-mariadb-52/index) and 5.3 include the latest XtraDB version from [MariaDB 5.1](../what-is-mariadb-51/index) at the time they were released.

 ### [MariaDB 5.1](../what-is-mariadb-51/index)

 * version [5.1.59-13](http://www.percona.com/doc/percona-server/5.1/release-notes/Percona-Server-5.1.59-13.0.html) in [MariaDB 5.1.60](https://mariadb.com/kb/en/mariadb-5160-release-notes/)
* version 5.1.54-12.5 in [MariaDB 5.1.55](https://mariadb.com/kb/en/mariadb-5155-release-notes/)
* version 5.1.52-11.6 in [MariaDB 5.2.4](https://mariadb.com/kb/en/mariadb-524-release-notes/) and [5.1.53](https://mariadb.com/kb/en/mariadb-5153-release-notes/)
* version 5.1.49-12 in [MariaDB 5.1.50](https://mariadb.com/kb/en/mariadb-5150-release-notes/)
* version [5.1.47-11.2](http://www.percona.com/docs/wiki/percona-server:release_notes_51#release_5147-112) in [MariaDB 5.1.49](https://mariadb.com/kb/en/mariadb-5149-release-notes/)
* version 1.0.6-10 in [MariaDB 5.1.47](https://mariadb.com/kb/en/mariadb-5147-release-notes/)
* version 1.0.6-9 in [MariaDB 5.1.42](https://mariadb.com/kb/en/mariadb-5142-release-notes/), [5.1.44](https://mariadb.com/kb/en/mariadb-5144-release-notes/), and [5.1.44b](https://mariadb.com/kb/en/mariadb-5144b-release-notes/).
* version 1.0.4-8 in [MariaDB 5.1.41 RC](https://mariadb.com/kb/en/mariadb-5141-release-notes/)
* version 1.0.3-8 in [MariaDB 5.1.39 Beta](https://mariadb.com/kb/en/mariadb-5139-release-notes/)
* version 1.0.3-6 in [MariaDB 5.1.38 Beta](https://mariadb.com/kb/en/mariadb-5138-release-notes/)

 Notes
-----

 1. [↑](#_ref-0) Misidentifies itself as 5.6.36-83.0 in [MariaDB 10.1.31](https://mariadb.com/kb/en/mariadb-10131-release-notes/)
2. [↑](#_ref-1) Misidentifies itself as 5.6.36-82.2 from [MariaDB 10.1.27](https://mariadb.com/kb/en/mariadb-10127-release-notes/) to [MariaDB 10.1.30](https://mariadb.com/kb/en/mariadb-10130-release-notes/)
3. [↑](#_ref-2) Misidentifies itself as 5.6.32-79.0 in [MariaDB 10.1.19](https://mariadb.com/kb/en/mariadb-10119-release-notes/)
4. [↑](#_ref-3) Misidentifies itself as 5.6.36-83.0 in [MariaDB 10.0.34](https://mariadb.com/kb/en/mariadb-10034-release-notes/)
5. [↑](#_ref-4) Misidentifies itself as 5.6.36-82.2 in [MariaDB 10.0.33](https://mariadb.com/kb/en/mariadb-10033-release-notes/)
6. [↑](#_ref-5) Misidentifies itself as 5.6.32-79.0 in [MariaDB 10.0.28](https://mariadb.com/kb/en/mariadb-10028-release-notes/)

 See Also
--------

 More information can be found in the [Percona documentation](https://www.percona.com/doc/percona-server/5.5/percona_xtradb.html?id=percona-xtradb:start).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-xtradb/>

Information Schema INDEX\_STATISTICS Table
==========================================

    The [Information Schema](../information_schema/index) `INDEX_STATISTICS` table shows statistics on index usage and makes it possible to do such things as locating unused indexes and generating the commands to remove them.

 This is part of the [User Statistics](../user-statistics/index) feature, which is not enabled by default.

 It contains the following columns:

 


| Field | Type | Notes |
| --- | --- | --- |
| `TABLE_SCHEMA` | `VARCHAR(192)` | The schema (database) name. |
| `TABLE_NAME` | `VARCHAR(192)` | The table name. |
| `INDEX_NAME` | `VARCHAR(192)` | The index name (as visible in `[SHOW CREATE TABLE](../show-create-table/index)`). |
| `ROWS_READ` | `INT(21)` | The number of rows read from this index. |

 
Example
-------

 
```
SELECT * FROM information_schema.INDEX_STATISTICS 
WHERE TABLE_NAME = "author";
+--------------+------------+------------+-----------+
| TABLE_SCHEMA | TABLE_NAME | INDEX_NAME | ROWS_READ |
+--------------+------------+------------+-----------+
| books        | author     | by_name    |        15 |
+--------------+------------+------------+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-index_statistics-table/>

Information Schema GEOMETRY\_COLUMNS Table
==========================================

    Description
-----------

 The [Information Schema](../information_schema/index) `GEOMETRY_COLUMNS` table provides support for Spatial Reference systems for GIS data.

 It contains the following columns:

 


| Column | Type | Null | Description |
| --- | --- | --- | --- |
| `F_TABLE_CATALOG` | `VARCHAR(512)` | NO | Together with `F_TABLE_SCHEMA` and `F_TABLE_NAME`, the fully qualified name of the featured table containing the geometry column. |
| `F_TABLE_SCHEMA` | `VARCHAR(64)` | NO | Together with `F_TABLE_CATALOG` and `F_TABLE_NAME`, the fully qualified name of the featured table containing the geometry column. |
| `F_TABLE_NAME` | `VARCHAR(64)` | NO | Together with `F_TABLE_CATALOG` and `F_TABLE_SCHEMA`, the fully qualified name of the featured table containing the geometry column. |
| `F_GEOMETRY_COLUMN` | `VARCHAR(64)` | NO | Name of the column in the featured table that is the geometry golumn. |
| `G_TABLE_CATALOG` | `VARCHAR(512)` | NO |  |
| `G_TABLE_SCHEMA` | `VARCHAR(64)` | NO | Database name of the table implementing the geometry column. |
| `G_TABLE_NAME` | `VARCHAR(64)` | NO | Table name that is implementing the geometry column. |
| `G_GEOMETRY_COLUMN` | `VARCHAR(64)` | NO |  |
| `STORAGE_TYPE` | `TINYINT(2)` | NO | Binary geometry implementation. Always 1 in MariaDB. |
| `GEOMETRY_TYPE` | `INT(7)` | NO | Integer reflecting the type of geometry stored in this column (see table below). |
| `COORD_DIMENSION` | `TINYINT(2)` | NO | Number of dimensions in the spatial reference system. Always 2 in MariaDB. |
| `MAX_PPR` | `TINYINT(2)` | NO | Always 0 in MariaDB. |
| `SRID` | `SMALLINT(5)` | NO | ID of the Spatial Reference System used for the coordinate geometry in this table. It is a foreign key reference to the `[SPATIAL\_REF\_SYS table](../information-schema-spatial_ref_sys-table/index)`. |

 
Storage\_type
-------------

 The integers in the `storage_type` field match the geometry types as follows:

 


| Integer | Type |
| --- | --- |
| 0 | `GEOMETRY` |
| 1 | `POINT` |
| 3 | `LINESTRING` |
| 5 | `POLYGON` |
| 7 | `MULTIPOINT` |
| 9 | `MULTILINESTRING` |
| 11 | `MULTIPOLYGON` |

 
Example
-------

 
```
CREATE TABLE g1(g GEOMETRY(9,4) REF_SYSTEM_ID=101);

SELECT * FROM information_schema.GEOMETRY_COLUMNS\G
*************************** 1. row ***************************
  F_TABLE_CATALOG: def
   F_TABLE_SCHEMA: test
     F_TABLE_NAME: g1
F_GEOMETRY_COLUMN: 
  G_TABLE_CATALOG: def
   G_TABLE_SCHEMA: test
     G_TABLE_NAME: g1
G_GEOMETRY_COLUMN: g
     STORAGE_TYPE: 1
    GEOMETRY_TYPE: 0
  COORD_DIMENSION: 2
          MAX_PPR: 0
             SRID: 101

```

See also
--------

 * The `[SPATIAL\_REF\_SYS](../information-schema-spatial_ref_sys-table/index)` table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-geometry_columns-table/>

Information Schema APPLICABLE\_ROLES Table
==========================================

    The [Information Schema](../information_schema/index) `APPLICABLE_ROLES` table shows the [role authorizations](../roles/index) that the current user may use.

 It contains the following columns:

 


| Column | Description | Added |
| --- | --- | --- |
| `GRANTEE` | Account that the role was granted to. |  |
| `ROLE_NAME` | Name of the role. |  |
| `IS_GRANTABLE` | Whether the role can be granted or not. |  |
| `IS_DEFAULT` | Whether the role is the user's default role or not | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
The current role is in the [ENABLED\_ROLES](../information-schema-enabled_roles-table/index) Information Schema table.

 Example
-------

 
```
SELECT * FROM information_schema.APPLICABLE_ROLES;
+----------------+-------------+--------------+------------+
| GRANTEE        | ROLE_NAME   | IS_GRANTABLE | IS_DEFAULT |
+----------------+-------------+--------------+------------+
| root@localhost | journalist  | YES          | NO         |
| root@localhost | staff       | YES          | NO         |
| root@localhost | dd          | YES          | NO         |
| root@localhost | dog         | YES          | NO         |
+----------------+-------------+--------------+------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-applicable_roles-table/>

Information Schema XtraDB Tables
=================================

   List of Information Schema tables specifically related to [XtraDB](../xtradb/index). Tables that XtraDB shares with InnoDB are listed in [Information Schema InnoDB Tables](../information-schema-innodb-tables/index).

  

| Title | Description |
| --- | --- |
|  [Information Schema CHANGED\_PAGE\_BITMAPS Table](../information-schema-changed_page_bitmaps-table/index) |  Dummy table to allow FLUSH NO\_WRITE\_TO\_BINLOG CHANGED\_PAGE\_BITMAPS  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES Table](../information-schema-innodb_buffer_pool_pages-table/index) |  XtraDB buffer pool page information.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES\_BLOB Table](../information-schema-innodb_buffer_pool_pages_blob-table/index) |  XtraDB buffer pool blob pages.  |
|  [Information Schema INNODB\_BUFFER\_POOL\_PAGES\_INDEX Table](../information-schema-innodb_buffer_pool_pages_index-table/index) |  XtraDB buffer pool index pages.  |
|  [Information Schema INNODB\_UNDO\_LOGS Table](../information-schema-innodb_undo_logs-table/index) |  XtraDB undo log segments.  |
|  [Information Schema XTRADB\_INTERNAL\_HASH\_TABLES Table](../information-schema-xtradb_internal_hash_tables-table/index) |  InnoDB/XtraDB hash table memory usage information.  |
|  [Information Schema XTRADB\_READ\_VIEW Table](../information-schema-xtradb_read_view-table/index) |  Information about the oldest active transaction in the system.  |
|  [Information Schema XTRADB\_RSEG Table](../information-schema-xtradb_rseg-table/index) |  XtraDB rollback segment information.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-xtradb-tables/>

Information Schema ENABLED\_ROLES Table
=======================================

    The [Information Schema](../information_schema/index) `ENABLED_ROLES` table shows the enabled [roles](../roles/index) for the current session.

 It contains the following column:

 


| Column | Description |
| --- | --- |
| `ROLE_NAME` | The enabled role name, or `NULL`. |

 
This table lists all roles that are currently enabled, one role per row — the current role, roles granted to the current role, roles granted to these roles and so on. If no role is set, the row contains a `NULL` value.

 The roles that the current user can enable are listed in the [APPLICABLE\_ROLES](../information-schema-applicable_roles-table/index) Information Schema table.

 See also [CURRENT\_ROLE()](../current_role/index).

 Examples
--------

 
```
SELECT * FROM information_schema.ENABLED_ROLES;
+-----------+
| ROLE_NAME |
+-----------+
| NULL      |
+-----------+

SET ROLE staff;

SELECT * FROM information_schema.ENABLED_ROLES;
+-----------+
| ROLE_NAME |
+-----------+
| staff     |
+-----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-enabled_roles-table/>

Information Schema EVENTS Table
===============================

    The [Information Schema](../information_schema/index) `EVENTS` table stores information about [Events](../stored-programs-and-views-events/index) on the server.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_CATALOG` | Always `def`. |
| `EVENT_SCHEMA` | Database where the event was defined. |
| `EVENT_NAME` | Event name. |
| `DEFINER` | Event definer. |
| `TIME_ZONE` | Time zone used for the event's scheduling and execution, by default `SYSTEM`. |
| `EVENT_BODY` | `SQL`. |
| `EVENT_DEFINITION` | The SQL defining the event. |
| `EVENT_TYPE` | Either `ONE TIME` or `RECURRING`. |
| `EXECUTE_AT` | `[DATETIME](../datetime/index)` when the event is set to execute, or `NULL` if recurring. |
| `INTERVAL_VALUE` | Numeric interval between event executions for a recurring event, or `NULL` if not recurring. |
| `INTERVAL_FIELD` | Interval unit (e.g., `HOUR`) |
| `SQL_MODE` | The `[SQL\_MODE](../sql-mode/index)` at the time the event was created. |
| `STARTS` | Start `[DATETIME](../datetime/index)` for a recurring event, `NULL` if not defined or not recurring. |
| `ENDS` | End `[DATETIME](../datetime/index)` for a recurring event, `NULL` if not defined or not recurring. |
| `STATUS` | One of `ENABLED`, `DISABLED` or /`SLAVESIDE_DISABLED`. |
| `ON_COMPLETION` | The `ON COMPLETION` clause, either `PRESERVE` or `NOT PRESERVE` . |
| `CREATED` | When the event was created. |
| `LAST_ALTERED` | When the event was last changed. |
| `LAST_EXECUTED` | When the event was last run. |
| `EVENT_COMMENT` | The comment provided in the `[CREATE EVENT](../create-event/index)` statement, or an empty string if none. |
| `ORIGINATOR` | MariaDB server ID on which the event was created. |
| `CHARACTER_SET_CLIENT` | `[character\_set\_client](../server-system-variables/index#character_set_client)` system variable session value at the time the event was created. |
| `COLLATION_CONNECTION` | [collation\_connection](../server-system-variables/index#collation_connection) system variable session value at the time the event was created. |
| `DATABASE_COLLATION` | Database [collation](../data-types-character-sets-and-collations/index) with which the event is linked. |

 
The `[SHOW EVENTS](../show-events/index)` and `[SHOW CREATE EVENT](../show-create-event/index)` statements provide similar information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-events-table/>

Information Schema MyRocks Tables
==================================

   List of Information Schema tables specifically related to [MyRocks](../myrocks/index).

  

| Title | Description |
| --- | --- |
|  [Information Schema ROCKSDB\_CFSTATS Table](../information-schema-rocksdb_cfstats-table/index) |  The Information Schema ROCKSDB\_CFSTATS table is included as part of the MyR...  |
|  [Information Schema ROCKSDB\_CF\_OPTIONS Table](../information-schema-rocksdb_cf_options-table/index) |  Information about MyRocks Column Families.  |
|  [Information Schema ROCKSDB\_COMPACTION\_STATS Table](../information-schema-rocksdb_compaction_stats-table/index) |  The Information Schema ROCKSDB\_COMPACTION\_STATS table is included as part o...  |
|  [Information Schema ROCKSDB\_DBSTATS Table](../information-schema-rocksdb_dbstats-table/index) |  The Information Schema ROCKSDB\_DBSTATS table is included as part of the MyR...  |
|  [Information Schema ROCKSDB\_DDL Table](../information-schema-rocksdb_ddl-table/index) |  The Information Schema ROCKSDB\_DDL table is included as part of the MyRocks...  |
|  [Information Schema ROCKSDB\_DEADLOCK Table](../information-schema-rocksdb_deadlock-table/index) |  The Information Schema ROCKSDB\_DEADLOCK table is included as part of the My...  |
|  [Information Schema ROCKSDB\_GLOBAL\_INFO Table](../information-schema-rocksdb_global_info-table/index) |  The Information Schema ROCKSDB\_GLOBAL\_INFO table is included as part of the...  |
|  [Information Schema ROCKSDB\_INDEX\_FILE\_MAP Table](../information-schema-rocksdb_index_file_map-table/index) |  The Information Schema ROCKSDB\_INDEX\_FILE\_MAP table is included as part of ...  |
|  [Information Schema ROCKSDB\_LOCKS Table](../information-schema-rocksdb_locks-table/index) |  The Information Schema ROCKSDB\_LOCKS table is included as part of the MyRoc...  |
|  [Information Schema ROCKSDB\_PERF\_CONTEXT Table](../information-schema-rocksdb_perf_context-table/index) |  Per-table/partition counters.  |
|  [Information Schema ROCKSDB\_PERF\_CONTEXT\_GLOBAL Table](../information-schema-rocksdb_perf_context_global-table/index) |  Global counters.  |
|  [Information Schema ROCKSDB\_SST\_PROPS Table](../information-schema-rocksdb_sst_props-table/index) |  The Information Schema ROCKSDB\_SST\_PROPS table is included as part of the M...  |
|  [Information Schema ROCKSDB\_TRX Table](../information-schema-rocksdb_trx-table/index) |  The Information Schema ROCKSDB\_TRX table is included as part of the MyRocks...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-myrocks-tables/>

Information Schema COLUMN\_PRIVILEGES Table
===========================================

    The [Information Schema](../information_schema/index) `COLUMN_PRIVILEGES` table contains column privilege information derived from the `[mysql.columns\_priv](../mysqlcolumns_priv-table/index)` grant table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `GRANTEE` | In the format `user_name@host_name`. |
| `TABLE_CATALOG` | Always `def`. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `COLUMN_NAME` | Column name. |
| `PRIVILEGE_TYPE` | One of `SELECT`, `INSERT`, `UPDATE` or `REFERENCES`. |
| `IS_GRANTABLE` | Whether the user has the `[GRANT OPTION](../grant/index#the-grant-option-privilege)` for this privilege. |

 
Similar information can be accessed with the `[SHOW FULL COLUMNS](../show-columns/index)` and `[SHOW GRANTS](../show-grants/index)` statements. See the `[GRANT](../grant/index)` article for more about privileges.

 This information is also stored in the `[columns\_priv](../mysqlcolumns_priv-table/index)` table, in the `mysql` system database.

 For a description of the privileges that are shown in this table, see [column privileges](../grant/index#column-privileges).

 Example
-------

 In the following example, no column-level privilege has been explicitly assigned:

 
```
SELECT * FROM information_schema.COLUMN_PRIVILEGES;
Empty set

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-column_privileges-table/>

Information Schema COLUMNS Table
================================

    The [Information Schema](../information_schema/index) `COLUMNS` table provides information about columns in each table on the server.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_CATALOG` | Always contains the string 'def'. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `COLUMN_NAME` | Column name. |
| `ORDINAL_POSITION` | Column position in the table. Can be used for ordering. |
| `COLUMN_DEFAULT` | Default value for the column. Literals are quoted to distinguish them from expressions. `NULL` means that the column has no default. In [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) and earlier, no quotes were used for any type of default and `NULL` can either mean that there is no default, or that the default column value is `NULL`. |
| `IS_NULLABLE` | Whether the column can contain `NULL`s. |
| `DATA_TYPE` | The column's [data type](../data-types/index). |
| `CHARACTER_MAXIMUM_LENGTH` | Maximum length. |
| `CHARACTER_OCTET_LENGTH` | Same as the `CHARACTER_MAXIMUM_LENGTH` except for multi-byte [character sets](../data-types-character-sets-and-collations/index). |
| `NUMERIC_PRECISION` | For numeric types, the precision (number of significant digits) for the column. `NULL` if not a numeric field. |
| `NUMERIC_SCALE` | For numeric types, the scale (significant digits to the right of the decimal point). NULL if not a numeric field. |
| `DATETIME_PRECISION` | Fractional-seconds precision, or `NULL` if not a [time data type](../date-and-time-data-types/index). |
| `CHARACTER_SET_NAME` | [Character set](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise NULL. |
| `COLLATION_NAME` | [Collation](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise NULL. |
| `COLUMN_TYPE` | Column definition, a MySQL and MariaDB extension. |
| `COLUMN_KEY` | Index type. `PRI` for primary key, `UNI` for unique index, `MUL` for multiple index. A MySQL and MariaDB extension. |
| `EXTRA` | Additional information about a column, for example whether the column is an [invisible column](../invisible-columns/index), or `WITHOUT SYSTEM VERSIONING` if the table is not a [system-versioned table](../system-versioned-tables/index). A MySQL and MariaDB extension. |
| `PRIVILEGES` | Which privileges you have for the column. A MySQL and MariaDB extension. |
| `COLUMN_COMMENT` | Column comments. |
| `IS_GENERATED` | Indicates whether the column value is [generated (virtual, or computed)](../virtual-computed-columns/index). Can be `ALWAYS` or `NEVER`. |
| `GENERATION_EXPRESSION` | The expression used for computing the column value in a [generated (virtual, or computed)](../virtual-computed-columns/index) column. |

 
It provides information similar to, but more complete, than [SHOW COLUMNS](../show-columns/index) and [mariadb-show](../mariadb-show/index).

 Examples
--------

 
```
SELECT * FROM information_schema.COLUMNS\G
...
*************************** 9. row ***************************
           TABLE_CATALOG: def
            TABLE_SCHEMA: test
              TABLE_NAME: t2
             COLUMN_NAME: j
        ORDINAL_POSITION: 1
          COLUMN_DEFAULT: NULL
             IS_NULLABLE: YES
               DATA_TYPE: longtext
CHARACTER_MAXIMUM_LENGTH: 4294967295
  CHARACTER_OCTET_LENGTH: 4294967295
       NUMERIC_PRECISION: NULL
           NUMERIC_SCALE: NULL
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: utf8mb4
          COLLATION_NAME: utf8mb4_bin
             COLUMN_TYPE: longtext
              COLUMN_KEY: 
                   EXTRA: 
              PRIVILEGES: select,insert,update,references
          COLUMN_COMMENT: 
            IS_GENERATED: NEVER
   GENERATION_EXPRESSION: NULL
...

```


```
CREATE TABLE t (
  s1 VARCHAR(20) DEFAULT 'ABC',
  s2 VARCHAR(20) DEFAULT (concat('A','B')),
  s3 VARCHAR(20) DEFAULT ("concat('A','B')"),
  s4 VARCHAR(20),
  s5 VARCHAR(20) DEFAULT NULL,
  s6 VARCHAR(20) NOT NULL,
  s7 VARCHAR(20) DEFAULT 'NULL' NULL,
  s8 VARCHAR(20) DEFAULT 'NULL' NOT NULL
);

SELECT 
  table_name, 
  column_name, 
  ordinal_position, 
  column_default,
  column_default IS NULL
FROM information_schema.COLUMNS
WHERE table_schema=DATABASE()
AND TABLE_NAME='t';

```

From [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/):

 
```
+------------+-------------+------------------+-----------------------+------------------------+
| table_name | column_name | ordinal_position | column_default        | column_default IS NULL |
+------------+-------------+------------------+-----------------------+------------------------+
| t          | s1          |                1 | 'ABC'                 |                      0 |
| t          | s2          |                2 | concat('A','B')       |                      0 |
| t          | s3          |                3 | 'concat(''A'',''B'')' |                      0 |
| t          | s4          |                4 | NULL                  |                      0 |
| t          | s5          |                5 | NULL                  |                      0 |
| t          | s6          |                6 | NULL                  |                      1 |
| t          | s7          |                7 | 'NULL'                |                      0 |
| t          | s8          |                8 | 'NULL'                |                      0 |
+------------+-------------+------------------+-----------------------+------------------------+

```

In the results above, the two single quotes in `concat(''A'',''B'')` indicate an escaped single quote - see [string-literals](../string-literals/index). Note that while [mysql-command-line-client](../mysql-command-line-client/index) appears to show the same default value for columns `s5` and `s6`, the first is a 4-character string "NULL", while the second is the SQL NULL value.

 [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) and before:

 
```
+------------+-------------+------------------+-----------------+------------------------+
| table_name | column_name | ordinal_position | column_default  | column_default IS NULL |
+------------+-------------+------------------+-----------------+------------------------+
| t          | s1          |                1 | ABC             |                      0 |
| t          | s2          |                2 | concat('A','B') |                      0 |
| t          | s3          |                3 | concat('A','B') |                      0 |
| t          | s4          |                4 | NULL            |                      1 |
| t          | s5          |                5 | NULL            |                      1 |
| t          | s6          |                6 | NULL            |                      1 |
| t          | s7          |                7 | NULL            |                      0 |
| t          | s8          |                8 | NULL            |                      0 |
+------------+-------------+------------------+-----------------+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-columns-table/>

Information Schema DISKS Table
==============================

    Description
-----------

 The `DISKS` table is created when the [DISKS](../disks-plugin/index) plugin is enabled, and shows metadata about disks on the system.

 Before [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/) and [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/), this plugin did **not** check [user privileges](../grant/index). When it is enabled, **any** user can query the `INFORMATION_SCHEMA.DISKS` table and see all the information it provides.

 Since [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/) and [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/), it requires the [FILE privilege](../grant/index).

 The plugin only works on Linux.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `DISK` | Name of the disk itself. |
| `PATH` | Mount point of the disk. |
| `TOTAL` | Total space in KiB. |
| `USED` | Used amount of space in KiB. |
| `AVAILABLE` | Amount of space in KiB available to non-root users. |

 
Note that as the amount of space available to root (OS user) may be more that what is available to non-root users, 'available' + 'used' may be less than 'total'.

 All paths to which a particular disk has been mounted are reported. The rationale is that someone might want to take different action e.g. depending on which disk is relevant for a particular path. This leads to the same disk being reported multiple times.

 Example
-------

 
```
SELECT * FROM information_schema.DISKS;

+-----------+-------+----------+---------+-----------+
| Disk      | Path  | Total    | Used    | Available |
+-----------+-------+----------+---------+-----------+
| /dev/vda1 | /     | 26203116 | 2178424 |  24024692 |
| /dev/vda1 | /boot | 26203116 | 2178424 |  24024692 |
| /dev/vda1 | /etc  | 26203116 | 2178424 |  24024692 |
+-----------+-------+----------+---------+-----------+

```

See Also
--------

 * [Disks Plugin](../disks-plugin/index) for details on installing, options
* [Plugin Overview](../plugin-overview/index) for details on managing plugins.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-disks-table/>

Information Schema CLIENT\_STATISTICS Table
===========================================

    The [Information Schema](../information_schema/index) `CLIENT_STATISTICS` table holds statistics about client connections. This is part of the [User Statistics](../user-statistics/index) feature, which is not enabled by default.

 It contains the following columns:

 


| Field | Type | Notes |
| --- | --- | --- |
| `CLIENT` | `VARCHAR(64)` | The IP address or hostname the connection originated from. |
| `TOTAL_CONNECTIONS` | `INT(21)` | The number of connections created for this client. |
| `CONCURRENT_CONNECTIONS` | `INT(21)` | The number of concurrent connections for this client. |
| `CONNECTED_TIME` | `INT(21)` | The cumulative number of seconds elapsed while there were connections from this client. |
| `BUSY_TIME` | `DOUBLE` | The cumulative number of seconds there was activity on connections from this client. |
| `CPU_TIME` | `DOUBLE` | The cumulative CPU time elapsed while servicing this client's connections. Note that this number may be wrong on SMP system if there was a CPU migration for the thread during the execution of the query. |
| `BYTES_RECEIVED` | `INT(21)` | The number of bytes received from this client's connections. |
| `BYTES_SENT` | `INT(21)` | The number of bytes sent to this client's connections. |
| `BINLOG_BYTES_WRITTEN` | `INT(21)` | The number of bytes written to the [binary log](../binary-log/index) from this client's connections. |
| `ROWS_READ` | `INT(21)` | The number of rows read by this client's connections. |
| `ROWS_SENT` | `INT(21)` | The number of rows sent by this client's connections. |
| `ROWS_DELETED` | `INT(21)` | The number of rows deleted by this client's connections. |
| `ROWS_INSERTED` | `INT(21)` | The number of rows inserted by this client's connections. |
| `ROWS_UPDATED` | `INT(21)` | The number of rows updated by this client's connections. |
| `SELECT_COMMANDS` | `INT(21)` | The number of `[SELECT](../select/index)` commands executed from this client's connections. |
| `UPDATE_COMMANDS` | `INT(21)` | The number of `[UPDATE](../update/index)` commands executed from this client's connections. |
| `OTHER_COMMANDS` | `INT(21)` | The number of other commands executed from this client's connections. |
| `COMMIT_TRANSACTIONS` | `INT(21)` | The number of `[COMMIT](../commit/index)` commands issued by this client's connections. |
| `ROLLBACK_TRANSACTIONS` | `INT(21)` | The number of `[ROLLBACK](../rollback/index)` commands issued by this client's connections. |
| `DENIED_CONNECTIONS` | `INT(21)` | The number of connections denied to this client. |
| `LOST_CONNECTIONS` | `INT(21)` | The number of this client's connections that were terminated uncleanly. |
| `ACCESS_DENIED` | `INT(21)` | The number of times this client's connections issued commands that were denied. |
| `EMPTY_QUERIES` | `INT(21)` | The number of times this client's connections sent queries that returned no results to the server. |
| `TOTAL_SSL_CONNECTIONS` | `INT(21)` | The number of [TLS connections](../secure-connections-overview/index) created for this client. (>= [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)) |
| `MAX_STATEMENT_TIME_EXCEEDED` | `INT(21)` | The number of times a statement was aborted, because it was executed longer than its `[MAX\_STATEMENT\_TIME](../aborting-statements-that-take-longer-than-a-certain-time-to-execute/index)` threshold. (>= [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)) |

 
#### Example

 
```
SELECT * FROM information_schema.CLIENT_STATISTICS\G
*************************** 1. row ***************************
                CLIENT: localhost
     TOTAL_CONNECTIONS: 3
CONCURRENT_CONNECTIONS: 0
        CONNECTED_TIME: 4883
             BUSY_TIME: 0.009722
              CPU_TIME: 0.0102131
        BYTES_RECEIVED: 841
            BYTES_SENT: 13897
  BINLOG_BYTES_WRITTEN: 0
             ROWS_READ: 0
             ROWS_SENT: 214
          ROWS_DELETED: 0
         ROWS_INSERTED: 207
          ROWS_UPDATED: 0
       SELECT_COMMANDS: 10
       UPDATE_COMMANDS: 0
        OTHER_COMMANDS: 13
   COMMIT_TRANSACTIONS: 0
 ROLLBACK_TRANSACTIONS: 0
    DENIED_CONNECTIONS: 0
      LOST_CONNECTIONS: 0
         ACCESS_DENIED: 0
         EMPTY_QUERIES: 1

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-client_statistics-table/>

Information Schema CHECK\_CONSTRAINTS Table
===========================================

    The [Information Schema](../information_schema/index) `CHECK_CONSTRAINTS` table stores metadata about the [constraints](../constraint/index) defined for tables in all databases.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CONSTRAINT_CATALOG` | Always contains the string 'def'. |
| `CONSTRAINT_SCHEMA` | Database name. |
| `CONSTRAINT_NAME` | Constraint name. |
| `TABLE_NAME` | Table name. |
| `LEVEL` | Type of the constraint ('Column' or 'Table'). From [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/) |
| `CHECK_CLAUSE` | Constraint clause. |

 
Example
-------

 A table with a numeric table check constraint and with a default check constraint name:

 
```
CREATE TABLE t ( a int, CHECK (a>10));

```

To see check constraint call `check_constraints` table from [information schema](../information_schema/index).

 
```
SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS\G

```


```
*************************** 1. row ***************************
CONSTRAINT_CATALOG: def
 CONSTRAINT_SCHEMA: test
   CONSTRAINT_NAME: CONSTRAINT_1
        TABLE_NAME: t
      CHECK_CLAUSE: `a` > 10

```

A new table check constraint called `a_upper`:

 
```
ALTER TABLE t ADD CONSTRAINT a_upper CHECK (a<100);

```


```
SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS\G

```


```

*************************** 1. row ***************************
CONSTRAINT_CATALOG: def
 CONSTRAINT_SCHEMA: test
   CONSTRAINT_NAME: CONSTRAINT_1
        TABLE_NAME: t
      CHECK_CLAUSE: `a` > 10
*************************** 2. row ***************************
CONSTRAINT_CATALOG: def
 CONSTRAINT_SCHEMA: test
   CONSTRAINT_NAME: a_upper
        TABLE_NAME: t
      CHECK_CLAUSE: `a` < 100

```

A new table `tt` with a field check constraint called `b` , as well as a table check constraint called  `b_upper`:

 
```
CREATE TABLE tt(b int CHECK(b>0),CONSTRAINT b_upper CHECK(b<50));

SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS;
+--------------------+-------------------+-----------------+------------+--------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_NAME | CHECK_CLAUSE |
+--------------------+-------------------+-----------------+------------+--------------+
| def                | test              | b               | tt         | `b` > 0      |
| def                | test              | b_upper         | tt         | `b` < 50     |
| def                | test              | CONSTRAINT_1    | t          | `a` > 10     |
| def                | test              | a_upper         | t          | `a` < 100    |
+--------------------+-------------------+-----------------+------------+--------------+


```

*Note:*  The name of the field constraint is the same as the field name.

 After dropping the default table constraint called  `CONSTRAINT_1`:

 
```
ALTER TABLE t DROP CONSTRAINT CONSTRAINT_1;

SELECT * from INFORMATION_SCHEMA.CHECK_CONSTRAINTS;
+--------------------+-------------------+-----------------+------------+--------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_NAME | CHECK_CLAUSE |
+--------------------+-------------------+-----------------+------------+--------------+
| def                | test              | b               | tt         | `b` > 0      |
| def                | test              | b_upper         | tt         | `b` < 50     |
| def                | test              | a_upper         | t          | `a` < 100    |
+--------------------+-------------------+-----------------+------------+--------------+


```

Trying to insert invalid arguments into table `t` and `tt` generates an error.

 
```
INSERT INTO t VALUES (10),(20),(100);
ERROR 4025 (23000): CONSTRAINT `a_upper` failed for `test`.`t`

INSERT INTO tt VALUES (10),(-10),(100);
ERROR 4025 (23000): CONSTRAINT `b` failed for `test`.`tt`

INSERT INTO tt VALUES (10),(20),(100);
ERROR 4025 (23000): CONSTRAINT `b_upper` failed for `test`.`tt`

```

From [MariaDB 10.5.10](https://mariadb.com/kb/en/mariadb-10510-release-notes/):

 
```
create table majra(check(x>0), x int, y int check(y < 0), z int,
                              constraint z check(z>0), constraint xyz check(x<10 and y<10 and z<10));
Query OK, 0 rows affected (0.036 sec)

show create table majra;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                   |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| majra | CREATE TABLE `majra` (
  `x` int(11) DEFAULT NULL,
  `y` int(11) DEFAULT NULL CHECK (`y` < 0),
  `z` int(11) DEFAULT NULL,
  CONSTRAINT `CONSTRAINT_1` CHECK (`x` > 0),
  CONSTRAINT `z` CHECK (`z` > 0),
  CONSTRAINT `xyz` CHECK (`x` < 10 and `y` < 10 and `z` < 10)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)


select * from information_schema.check_constraints where table_name='majra';
+--------------------+-------------------+------------+-----------------+--------+------------------------------------+
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | TABLE_NAME | CONSTRAINT_NAME | LEVEL  | CHECK_CLAUSE                       |
+--------------------+-------------------+------------+-----------------+--------+------------------------------------+
| def                | test              | majra      | y               | Column | `y` < 0                            |
| def                | test              | majra      | CONSTRAINT_1    | Table  | `x` > 0                            |
| def                | test              | majra      | z               | Table  | `z` > 0                            |
| def                | test              | majra      | xyz             | Table  | `x` < 10 and `y` < 10 and `z` < 10 |
+--------------------+-------------------+------------+-----------------+--------+------------------------------------+
4 rows in set (0.001 sec)


```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-check_constraints-table/>

Information Schema FILES Table
==============================

    The `FILES` tables is unused in MariaDB. See [MDEV-11426](https://jira.mariadb.org/browse/MDEV-11426).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-files-table/>

Information Schema KEY\_CACHES Table
====================================

    The [Information Schema](../information_schema/index) `KEY_CACHES` table shows statistics about the [segmented key cache](../segmented-key-cache/index),.

 It contains the following columns:

 


| Column Name | Description |
| --- | --- |
| `KEY_CACHE_NAME` | The name of the key cache |
| `SEGMENTS` | total number of segments (set to `NULL` for regular key caches) |
| `SEGMENT_NUMBER` | segment number (set to `NULL` for any regular key caches and for rows containing aggregation statistics for segmented key caches) |
| `FULL_SIZE` | memory for cache buffers/auxiliary structures |
| `BLOCK_SIZE` | size of the blocks |
| `USED_BLOCKS` | number of currently used blocks |
| `UNUSED_BLOCKS` | number of currently unused blocks |
| `DIRTY_BLOCKS` | number of currently dirty blocks |
| `READ_REQUESTS` | number of read requests |
| `READS` | number of actual reads from files into buffers |
| `WRITE_REQUESTS` | number of write requests |
| `WRITES` | number of actual writes from buffers into files |

 
Example
-------

 
```
SELECT * FROM information_schema.KEY_CACHES \G
********************** 1. row **********************
KEY_CACHE_NAME: default
SEGMENTS: NULL
SEGMENT_NUMBER: NULL
     FULL_SIZE: 134217728
    BLOCK_SIZE: 1024
   USED_BLOCKS: 36
 UNUSED_BLOCKS: 107146
  DIRTY_BLOCKS: 0
 READ_REQUESTS: 40305
         READS: 21
WRITE_REQUESTS: 19239
        WRITES: 358

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-key_caches-table/>

Information Schema COLLATION\_CHARACTER\_SET\_APPLICABILITY Table
=================================================================

    The [Information Schema](../information_schema/index) `COLLATION_CHARACTER_SET_APPLICABILITY` table shows which [character sets](../data-types-character-sets-and-collations/index) are associated with which collations.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `COLLATION_NAME` | Collation name. |
| `CHARACTER_SET_NAME` | Name of the associated character set. |

 
`COLLATION_CHARACTER_SET_APPLICABILITY` is essentially a subset of the `[COLLATIONS](../information-schema-collations-table/index)` table.

 
```
SELECT COLLATION_NAME,CHARACTER_SET_NAME FROM information_schema.COLLATIONS;

```

and 

 
```
SELECT * FROM information_schema.COLLATION_CHARACTER_SET_APPLICABILITY;

```

will return identical results.

 See [Setting Character Sets and Collations](../setting-character-sets-and-collations/index) for details on specifying the character set at the server, database, table and column levels.

 Example
-------

 
```
SELECT * FROM information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 
WHERE CHARACTER_SET_NAME='utf32';
+---------------------+--------------------+
| COLLATION_NAME      | CHARACTER_SET_NAME |
+---------------------+--------------------+
| utf32_general_ci    | utf32              |
| utf32_bin           | utf32              |
| utf32_unicode_ci    | utf32              |
| utf32_icelandic_ci  | utf32              |
| utf32_latvian_ci    | utf32              |
| utf32_romanian_ci   | utf32              |
| utf32_slovenian_ci  | utf32              |
| utf32_polish_ci     | utf32              |
| utf32_estonian_ci   | utf32              |
| utf32_spanish_ci    | utf32              |
| utf32_swedish_ci    | utf32              |
| utf32_turkish_ci    | utf32              |
| utf32_czech_ci      | utf32              |
| utf32_danish_ci     | utf32              |
| utf32_lithuanian_ci | utf32              |
| utf32_slovak_ci     | utf32              |
| utf32_spanish2_ci   | utf32              |
| utf32_roman_ci      | utf32              |
| utf32_persian_ci    | utf32              |
| utf32_esperanto_ci  | utf32              |
| utf32_hungarian_ci  | utf32              |
| utf32_sinhala_ci    | utf32              |
| utf32_german2_ci    | utf32              |
| utf32_croatian_ci   | utf32              |
+---------------------+--------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-collation_character_set_applicability-table/>

Information Schema FEEDBACK Table
=================================

    The [Information Schema](../information_schema/index) `FEEDBACK` table is created when the [Feedback Plugin](../feedback-plugin/index) is enabled, and contains the complete contents submitted by the plugin.

 It contains two columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | Name of the item of information being collected. |
| `VARIABLE_VALUE` | Contents of the item of information being collected. |

 
It is possible to disable automatic collection, by setting the `[feedback\_url](../feedback-plugin/index#feedback_url)` variable to an empty string, and to submit the contents manually, as follows:

 
```
$ mysql -e 'SELECT * FROM information_schema.FEEDBACK' > report.txt

```

Then you can send it by opening `<https://mariadb.org/feedback_plugin/post>` in your browser, and uploading your generated `report.txt`. Or you can do it from the command line with (for example):

 
```
$ curl -F data=@report.txt https://mariadb.org/feedback_plugin/post

```

Manual uploading allows you to be absolutely sure that we receive only the data shown in the `information_schema.FEEDBACK` table and that no private or sensitive information is being sent.

 Example
-------

 
```
SELECT * FROM information_schema.FEEDBACK\G
...
*************************** 906. row ***************************
 VARIABLE_NAME: Uname_sysname
VARIABLE_VALUE: Linux
*************************** 907. row ***************************
 VARIABLE_NAME: Uname_release
VARIABLE_VALUE: 3.13.0-53-generic
*************************** 908. row ***************************
 VARIABLE_NAME: Uname_version
VARIABLE_VALUE: #89-Ubuntu SMP Wed May 20 10:34:39 UTC 2015
*************************** 909. row ***************************
 VARIABLE_NAME: Uname_machine
VARIABLE_VALUE: x86_64
*************************** 910. row ***************************
 VARIABLE_NAME: Uname_distribution
VARIABLE_VALUE: lsb: Ubuntu 14.04.2 LTS
*************************** 911. row ***************************
 VARIABLE_NAME: Collation used latin1_german1_ci
VARIABLE_VALUE: 1
*************************** 912. row ***************************
 VARIABLE_NAME: Collation used latin1_swedish_ci
VARIABLE_VALUE: 18
*************************** 913. row ***************************
 VARIABLE_NAME: Collation used utf8_general_ci
VARIABLE_VALUE: 567
*************************** 914. row ***************************
 VARIABLE_NAME: Collation used latin1_bin
VARIABLE_VALUE: 1
*************************** 915. row ***************************
 VARIABLE_NAME: Collation used binary
VARIABLE_VALUE: 16
*************************** 916. row ***************************
 VARIABLE_NAME: Collation used utf8_bin
VARIABLE_VALUE: 4044

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-feedback-table/>

Information Schema ALL\_PLUGINS Table
=====================================

    Description
-----------

 The [Information Schema](../information_schema/index) `ALL_PLUGINS` table contains information about [server plugins](../mariadb-plugins/index), whether installed or not.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `PLUGIN_NAME` | Name of the plugin. |
| `PLUGIN_VERSION` | Version from the plugin's general type descriptor. |
| `PLUGIN_STATUS` | Plugin status, one of `ACTIVE`, `INACTIVE`, `DISABLED`, `DELETED` or `NOT INSTALLED`. |
| `PLUGIN_TYPE` | Plugin type; `STORAGE ENGINE`, `INFORMATION_SCHEMA`, `AUTHENTICATION`, `REPLICATION`, `DAEMON` or `AUDIT`. |
| `PLUGIN_TYPE_VERSION` | Version from the plugin's type-specific descriptor. |
| `PLUGIN_LIBRARY` | Plugin's shared object file name, located in the directory specified by the `[plugin\_dir](../server-system-variables/index#plugin_dir)` system variable, and used by the `[INSTALL PLUGIN](../install-plugin/index)` and `[UNINSTALL PLUGIN](../uninstall-plugin/index)` statements. `NULL` if the plugin is complied in and cannot be uninstalled. |
| `PLUGIN_LIBRARY_VERSION` | Version from the plugin's API interface. |
| `PLUGIN_AUTHOR` | Author of the plugin. |
| `PLUGIN_DESCRIPTION` | Description. |
| `PLUGIN_LICENSE` | Plugin's licence. |
| `LOAD_OPTION` | How the plugin was loaded; one of `OFF`, `ON`, `FORCE` or `FORCE_PLUS_PERMANENT`. See [Installing Plugins](../plugin-overview/index#installing-plugins). |
| `PLUGIN_MATURITY` | Plugin's maturity level; one of `Unknown`, `Experimental`, `Alpha`, `Beta`,`'Gamma`, and `Stable`. |
| `PLUGIN_AUTH_VERSION` | Plugin's version as determined by the plugin author. An example would be '0.99 beta 1'. |

 
It provides a superset of the information shown by the `[SHOW PLUGINS SONAME](../show-plugins-soname/index)` statement, as well as the `[information\_schema.PLUGINS](../information-schema-plugins-table/index)` table. For specific information about storage engines (a particular type of plugin), see the [Information Schema ENGINES table](../information-schema-engines-table/index) and the `[SHOW ENGINES](../show-engines/index)` statement.

 The table is not a standard Information Schema table, and is a MariaDB extension.

 Example
-------

 
```
SELECT * FROM information_schema.all_plugins\G
*************************** 1. row ***************************
           PLUGIN_NAME: binlog
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: STORAGE ENGINE
   PLUGIN_TYPE_VERSION: 100314.0
        PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR: MySQL AB
    PLUGIN_DESCRIPTION: This is a pseudo storage engine to represent the binlog in a transaction
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: FORCE
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
*************************** 2. row ***************************
           PLUGIN_NAME: mysql_native_password
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: AUTHENTICATION
   PLUGIN_TYPE_VERSION: 2.1
        PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR: R.J.Silk, Sergei Golubchik
    PLUGIN_DESCRIPTION: Native MySQL authentication
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: FORCE
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
*************************** 3. row ***************************
           PLUGIN_NAME: mysql_old_password
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: AUTHENTICATION
   PLUGIN_TYPE_VERSION: 2.1
        PLUGIN_LIBRARY: NULL
PLUGIN_LIBRARY_VERSION: NULL
         PLUGIN_AUTHOR: R.J.Silk, Sergei Golubchik
    PLUGIN_DESCRIPTION: Old MySQL-4.0 authentication
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: FORCE
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
...
*************************** 104. row ***************************
           PLUGIN_NAME: WSREP_MEMBERSHIP
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: NOT INSTALLED
           PLUGIN_TYPE: INFORMATION SCHEMA
   PLUGIN_TYPE_VERSION: 100314.0
        PLUGIN_LIBRARY: wsrep_info.so
PLUGIN_LIBRARY_VERSION: 1.13
         PLUGIN_AUTHOR: Nirbhay Choubey
    PLUGIN_DESCRIPTION: Information about group members
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: OFF
       PLUGIN_MATURITY: Stable
   PLUGIN_AUTH_VERSION: 1.0
*************************** 105. row ***************************
           PLUGIN_NAME: WSREP_STATUS
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: NOT INSTALLED
           PLUGIN_TYPE: INFORMATION SCHEMA
   PLUGIN_TYPE_VERSION: 100314.0
        PLUGIN_LIBRARY: wsrep_info.so
PLUGIN_LIBRARY_VERSION: 1.13
         PLUGIN_AUTHOR: Nirbhay Choubey
    PLUGIN_DESCRIPTION: Group view information
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: OFF
       PLUGIN_MATURITY: Stable

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/all-plugins-table-information-schema/>

Information Schema METADATA\_LOCK\_INFO Table
=============================================

    The [Information Schema](../information_schema/index) `METADATA_LOCK_INFO` table is created by the [metadata\_lock\_info](../metadata_lock_info/index) plugin. It shows active [metadata locks](../metadata-locking/index) and user locks (the locks acquired with [GET\_LOCK](../get_lock/index)).

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` |  |
| `LOCK_MODE` | One of `MDL_INTENTION_EXCLUSIVE`, `MDL_SHARED`, `MDL_SHARED_HIGH_PRIO`, `MDL_SHARED_READ`, `MDL_SHARED_READ_ONLY`, `MDL_SHARED_WRITE`, `MDL_SHARED_NO_WRITE`, `MDL_SHARED_NO_READ_WRITE`, `MDL_SHARED_UPGRADABLE` or `MDL_EXCLUSIVE`. |
| `LOCK_DURATION` | One of `MDL_STATEMENT`, `MDL_TRANSACTION` or `MDL_EXPLICIT` |
| `LOCK_TYPE` | One of `Global read lock`, `Schema metadata lock`, `Table metadata lock`, `Stored function metadata lock`, `Stored procedure metadata lock`, `Trigger metadata lock`, `Event metadata lock`, `Commit lock` or `User lock`. |
| `TABLE_SCHEMA` |  |
| `TABLE_NAME` |  |

 
#### "LOCK\_MODE" Descriptions

 The `LOCK_MODE` column can have the following values:

 


| Value | Description |
| --- | --- |
| `MDL_INTENTION_EXCLUSIVE` | An intention exclusive metadata lock (IX). Used only for scoped locks. Owner of this type of lock can acquire upgradable exclusive locks on individual objects. Compatible with other IX locks, but is incompatible with scoped S and X locks. IX lock is taken in SCHEMA namespace when we intend to modify object metadata. Object may refer table, stored procedure, trigger, view/etc. |
| `MDL_SHARED` | A shared metadata lock (S). To be used in cases when we are interested in object metadata only and there is no intention to access object data (e.g. for stored routines or during preparing prepared statements). We also mis-use this type of lock for open HANDLERs, since lock acquired by this statement has to be compatible with lock acquired by LOCK TABLES ... WRITE statement, i.e. SNRW (We can't get by by acquiring S lock at HANDLER ... OPEN time and upgrading it to SR lock for HANDLER ... READ as it doesn't solve problem with need to abort DML statements which wait on table level lock while having open HANDLER in the same connection). To avoid deadlock which may occur when SNRW lock is being upgraded to X lock for table on which there is an active S lock which is owned by thread which waits in its turn for table-level lock owned by thread performing upgrade we have to use thr\_abort\_locks\_for\_thread() facility in such situation. This problem does not arise for locks on stored routines as we don't use SNRW locks for them. It also does not arise when S locks are used during PREPARE calls as table-level locks are not acquired in this case. This lock is taken for global read lock, when caching a stored procedure in memory for the duration of the transaction and for tables used by prepared statements. |
| `MDL_SHARED_HIGH_PRIO` | A high priority shared metadata lock. Used for cases when there is no intention to access object data (i.e. data in the table). "High priority" means that, unlike other shared locks, it is granted ignoring pending requests for exclusive locks. Intended for use in cases when we only need to access metadata and not data, e.g. when filling an INFORMATION\_SCHEMA table. Since SH lock is compatible with SNRW lock, the connection that holds SH lock lock should not try to acquire any kind of table-level or row-level lock, as this can lead to a deadlock. Moreover, after acquiring SH lock, the connection should not wait for any other resource, as it might cause starvation for X locks and a potential deadlock during upgrade of SNW or SNRW to X lock (e.g. if the upgrading connection holds the resource that is being waited for). |
| `MDL_SHARED_READ` | A shared metadata lock (SR) for cases when there is an intention to read data from table. A connection holding this kind of lock can read table metadata and read table data (after acquiring appropriate table and row-level locks). This means that one can only acquire TL\_READ, TL\_READ\_NO\_INSERT, and similar table-level locks on table if one holds SR MDL lock on it. To be used for tables in SELECTs, subqueries, and LOCK TABLE ... READ statements. |
| `MDL_SHARED_WRITE` | A shared metadata lock (SW) for cases when there is an intention to modify (and not just read) data in the table. A connection holding SW lock can read table metadata and modify or read table data (after acquiring appropriate table and row-level locks). To be used for tables to be modified by INSERT, UPDATE, DELETE statements, but not LOCK TABLE ... WRITE or DDL). Also taken by SELECT ... FOR UPDATE. |
| `MDL_SHARED_UPGRADABLE` | An upgradable shared metadata lock for cases when there is an intention to modify (and not just read) data in the table. Can be upgraded to MDL\_SHARED\_NO\_WRITE and MDL\_EXCLUSIVE. A connection holding SU lock can read table metadata and modify or read table data (after acquiring appropriate table and row-level locks). To be used for the first phase of ALTER TABLE. |
| `MDL_SHARED_READ_ONLY` | A shared metadata lock for cases when we need to read data from table and block all concurrent modifications to it (for both data and metadata). Used by LOCK TABLES READ statement. |
| `MDL_SHARED_NO_WRITE` | An upgradable shared metadata lock which blocks all attempts to update table data, allowing reads. A connection holding this kind of lock can read table metadata and read table data. Can be upgraded to X metadata lock. Note, that since this type of lock is not compatible with SNRW or SW lock types, acquiring appropriate engine-level locks for reading (TL\_READ\* for MyISAM, shared row locks in InnoDB) should be contention-free. To be used for the first phase of ALTER TABLE, when copying data between tables, to allow concurrent SELECTs from the table, but not UPDATEs. |
| `MDL_SHARED_NO_READ_WRITE` | An upgradable shared metadata lock which allows other connections to access table metadata, but not data. It blocks all attempts to read or update table data, while allowing INFORMATION\_SCHEMA and SHOW queries. A connection holding this kind of lock can read table metadata modify and read table data. Can be upgraded to X metadata lock. To be used for LOCK TABLES WRITE statement. Not compatible with any other lock type except S and SH. |
| `MDL_EXCLUSIVE` | An exclusive metadata lock (X). A connection holding this lock can modify both table's metadata and data. No other type of metadata lock can be granted while this lock is held. To be used for CREATE/DROP/RENAME TABLE statements and for execution of certain phases of other DDL statements. |

 
Examples
--------

 User lock:

 
```
SELECT GET_LOCK('abc',1000);
+----------------------+
| GET_LOCK('abc',1000) |
+----------------------+
|                    1 |
+----------------------+

SELECT * FROM information_schema.METADATA_LOCK_INFO;
+-----------+--------------------------+---------------+-----------+--------------+------------+
| THREAD_ID | LOCK_MODE                | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+--------------------------+---------------+-----------+--------------+------------+
|        61 | MDL_SHARED_NO_READ_WRITE | MDL_EXPLICIT  | User lock | abc          |            |
+-----------+--------------------------+---------------+-----------+--------------+------------+

```

Table metadata lock:

 
```
START TRANSACTION;

INSERT INTO t VALUES (1,2);

SELECT * FROM information_schema.METADATA_LOCK_INFO \G
*************************** 1. row ***************************
    THREAD_ID: 4
    LOCK_MODE: MDL_SHARED_WRITE
LOCK_DURATION: MDL_TRANSACTION
    LOCK_TYPE: Table metadata lock
 TABLE_SCHEMA: test
   TABLE_NAME: t

```


```
SELECT * FROM information_schema.METADATA_LOCK_INFO;
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
| THREAD_ID | LOCK_MODE | LOCK_DURATION | LOCK_TYPE | TABLE_SCHEMA | TABLE_NAME |
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+ 
| 31 | MDL_INTENTION_EXCLUSIVE | MDL_EXPLICIT | Global read lock | | |
| 31 | MDL_INTENTION_EXCLUSIVE | MDL_EXPLICIT | Commit lock | | |
| 31 | MDL_INTENTION_EXCLUSIVE | MDL_EXPLICIT | Schema metadata lock | dbname | |
| 31 | MDL_SHARED_NO_READ_WRITE | MDL_EXPLICIT | Table metadata lock | dbname | exotics |
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+

```

See Also
--------

 * [metadata locks](../metadata-locking/index)
* [Performance Schema metadata\_locks table](../performance-schema-metadata_locks-table/index)
* [GET\_LOCK](../get_lock/index)).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-metadata_lock_info-table/>

Information Schema KEY\_COLUMN\_USAGE Table
===========================================

    The [Information Schema](../information_schema/index) `KEY_COLUMN_USAGE` table shows which key columns have constraints. 

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CONSTRAINT_CATALOG` | Always `def`. |
| `CONSTRAINT_SCHEMA` | Database name of the constraint. |
| `CONSTRAINT_NAME` | Name of the constraint (`PRIMARY` for the primary key). |
| `TABLE_CATALOG` | Always #def`.` |
| `TABLE_SCHEMA` | Database name of the column constraint. |
| `TABLE_NAME` | Table name of the column constraint. |
| `COLUMN_NAME` | Column name of the constraint. |
| `ORDINAL_POSITION` | Position of the column within the constraint. |
| `POSITION_IN_UNIQUE_CONSTRAINT` | For [foreign keys](../foreign-keys/index), the position in the unique constraint. |
| `REFERENCED_TABLE_SCHEMA` | For foreign keys, the referenced database name. |
| `REFERENCED_TABLE_NAME` | For foreign keys, the referenced table name. |
| `REFERENCED_COLUMN_NAME` | For foreign keys, the referenced column name. |

 
Example
-------

 
```
SELECT * FROM information_schema.KEY_COLUMN_USAGE LIMIT 1 \G
********************** 1. row **********************
           CONSTRAINT_CATALOG: def
            CONSTRAINT_SCHEMA: my_website
              CONSTRAINT_NAME: PRIMARY
                TABLE_CATALOG: def
                 TABLE_SCHEMA: users
                  COLUMN_NAME: user_id
             ORDINAL_POSITION: 1
POSITION_IN_UNIQUE_CONSTRAINT: NULL
      REFERENCED_TABLE_SCHEMA: NULL
        REFERENCED_TABLE_NAME: NULL
       REFERENCED_COLUMN_NAME: NULL

```

See Also
--------

 * [Finding Tables Without Primary Keys](../getting-started-with-indexes/index#finding-tables-without-primary-keys)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-key_column_usage-table/>

Information Schema PARAMETERS Table
===================================

    The [Information Schema](../information_schema/index) `PARAMETERS` table stores information about [stored procedures](../stored-procedures/index) and [stored functions](../stored-functions/index) parameters.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `SPECIFIC_CATALOG` | Always `def`. |
| `SPECIFIC_SCHEMA` | Database name containing the stored routine parameter. |
| `SPECIFIC_NAME` | Stored routine name. |
| `ORDINAL_POSITION` | Ordinal position of the parameter, starting at `1`. `0` for a function RETURNS clause. |
| `PARAMETER_MODE` | One of `IN`, `OUT`, `INOUT` or `NULL` for RETURNS. |
| `PARAMETER_NAME` | Name of the parameter, or `NULL` for RETURNS. |
| `DATA_TYPE` | The column's [data type](../data-types/index). |
| `CHARACTER_MAXIMUM_LENGTH` | Maximum length. |
| `CHARACTER_OCTET_LENGTH` | Same as the `CHARACTER_MAXIMUM_LENGTH` except for multi-byte [character sets](../data-types-character-sets-and-collations/index). |
| `NUMERIC_PRECISION` | For numeric types, the precision (number of significant digits) for the column. NULL if not a numeric field. |
| `NUMERIC_SCALE` | For numeric types, the scale (significant digits to the right of the decimal point). NULL if not a numeric field. |
| `DATETIME_PRECISION` | Fractional-seconds precision, or `NULL` if not a [time data type](../date-and-time-data-types/index). |
| `CHARACTER_SET_NAME` | [Character set](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise `NULL`. |
| `COLLATION_NAME` | [Collation](../data-types-character-sets-and-collations/index) if a non-binary [string data type](../string-data-types/index), otherwise `NULL`. |
| `DTD_IDENTIFIER` | Description of the data type. |
| `ROUTINE_TYPE` | `PROCEDURE` or `FUNCTION`. |

 
Information from this table is similar to that found in the `param_list` column in the [mysql.proc](../mysqlproc-table/index) table, and the output of the `[SHOW CREATE PROCEDURE](../show-create-procedure/index)` and `[SHOW CREATE FUNCTION](../show-create-function/index)` statements.

 To obtain information about the routine itself, you can query the [Information Schema ROUTINES table](../information-schema-routines-table/index).

 Example
-------

 
```
SELECT * FROM information_schema.PARAMETERS
LIMIT 1 \G
********************** 1. row **********************
        SPECIFIC_CATALOG: def
         SPECIFIC_SCHEMA: accounts
           SPECIFIC_NAME: user_counts
        ORDINAL_POSITION: 1
          PARAMETER_MODE: IN
          PARAMETER_NAME: user_order
               DATA_TYPE: varchar
CHARACTER_MAXIMUM_LENGTH: 255
  CHARACTER_OCTET_LENGTH: 765
       NUMERIC_PRECISION: NULL
           NUMERIC_SCALE: NULL
      DATETIME_PRECISION: NULL
      CHARACTER_SET_NAME: utf8
          COLLATION_NAME: utf8_general_ci
          DTD_IDENTIFIER: varchar(255)
            ROUTINE_TYPE: PROCEDURE

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-parameters-table/>

Information Schema SCHEMA\_PRIVILEGES Table
===========================================

    The [Information Schema](../information_schema/index) `SCHEMA_PRIVILEGES` table contains information about [database privileges](../grant/index#database-privileges).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `GRANTEE` | Account granted the privilege in the format `user_name@host_name`. |
| `TABLE_CATALOG` | Always `def` |
| `TABLE_SCHEMA` | Database name. |
| `PRIVILEGE_TYPE` | The granted privilege. |
| `IS_GRANTABLE` | Whether the privilege can be granted. |

 
The same information in a different format can be found in the `[mysql.db](../mysqldb-table/index)` table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-schema_privileges-table/>

Information Schema QUERY\_RESPONSE\_TIME Table
==============================================

    Description
-----------

 The [Information Schema](../information_schema/index) `QUERY_RESPONSE_TIME` table contains information about queries that take a long time to execute . It is only available if the [QUERY\_RESPONSE\_TIME](../query_response_time-plugin/index) plugin has been installed. 

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TIME` | Time interval |
| `COUNT` | Count of queries falling into the time interval |
| `TOTAL` | Total execution time of all queries for this interval |

 
See [QUERY\_RESPONSE\_TIME](../query_response_time-plugin/index) plugin for a full description.

 The table is not a standard Information Schema table, and is a MariaDB extension.

 `SHOW QUERY_RESPONSE_TIME` is available from [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) as an alternative for retrieving the data.

 Example
-------

 
```
SELECT * FROM information_schema.QUERY_RESPONSE_TIME;
+----------------+-------+----------------+
| TIME           | COUNT | TOTAL          |
+----------------+-------+----------------+
|       0.000001 |     0 |       0.000000 |
|       0.000010 |    17 |       0.000094 |
|       0.000100 |  4301         0.236555 |
|       0.001000 |  1499 |       0.824450 |
|       0.010000 | 14851 |      81.680502 |
|       0.100000 |  8066 |     443.635693 |
|       1.000000 |     0 |       0.000000 |
|      10.000000 |     0 |       0.000000 |
|     100.000000 |     1 |      55.937094 |
|    1000.000000 |     0 |       0.000000 |
|   10000.000000 |     0 |       0.000000 |
|  100000.000000 |     0 |       0.000000 |
| 1000000.000000 |     0 |       0.000000 |
| TOO LONG       |     0 | TOO LONG       |
+----------------+-------+----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-query_response_time-table/>

Information Schema REFERENTIAL\_CONSTRAINTS Table
=================================================

    The [Information Schema](../information_schema/index) `REFERENTIAL_CONSTRAINTS` table contains information about [foreign keys](../foreign-keys/index). The single columns are listed in the `[KEY\_COLUMN\_USAGE](../information-schema-key_column_usage-table/index)` table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `CONSTRAINT_CATALOG` | Always `def`. |
| `CONSTRAINT_SCHEMA` | Database name, together with `CONSTRAINT_NAME` identifies the foreign key. |
| `CONSTRAINT_NAME` | Foreign key name, together with `CONSTRAINT_SCHEMA` identifies the foreign key. |
| `UNIQUE_CONSTRAINT_CATALOG` | Always `def`. |
| `UNIQUE_CONSTRAINT_SCHEMA` | Database name, together with `UNIQUE_CONSTRAINT_NAME` and `REFERENCED_TABLE_NAME` identifies the referenced key. |
| `UNIQUE_CONSTRAINT_NAME` | Referenced key name, together with `UNIQUE_CONSTRAINT_SCHEMA` and `REFERENCED_TABLE_NAME` identifies the referenced key. |
| `MATCH_OPTION` | Always `NONE`. |
| `UPDATE_RULE` | The Update Rule; one of `CASCADE`, `SET NULL`, `SET DEFAULT`, `RESTRICT`, `NO ACTION`. |
| `DELETE_RULE` | The Delete Rule; one of `CASCADE`, `SET NULL`, `SET DEFAULT`, `RESTRICT`, `NO ACTION`. |
| `TABLE_NAME` | Table name from the `TABLE_CONSTRAINTS` table. |
| `REFERENCED_TABLE_NAME` | Referenced key table name, together with `UNIQUE_CONSTRAINT_SCHEMA` and `UNIQUE_CONSTRAINT_NAME` identifies the referenced key. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-referential_constraints-table/>

Information Schema LOCALES Table
================================

    Description
-----------

 The [Information Schema](../information_schema/index) `LOCALES` table contains a list of all compiled-in locales. It is only available if the [LOCALES plugin](../locales-plugin/index) has been installed. 

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `ID` | Row ID. |
| `NAME` | Locale name, for example `en_GB`. |
| `DESCRIPTION` | Locale description, for example `English - United Kingdom`. |
| `MAX_MONTH_NAME_LENGTH` | Numeric length of the longest month in the locale |
| `MAX_DAY_NAME_LENGTH` | Numeric length of the longest day name in the locale. |
| `DECIMAL_POINT` | Decimal point character (some locales use a comma). |
| `THOUSAND_SEP` | Thousand's character separator, |
| `ERROR_MESSAGE_LANGUAGE` | Error message language. |

 
The table is not a standard Information Schema table, and is a MariaDB extension.

 The [SHOW LOCALES](../show-locales/index) statement returns a subset of the information.

 Example
-------

 
```
SELECT * FROM information_schema.LOCALES;
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+
| ID  | NAME  | DESCRIPTION                         | MAX_MONTH_NAME_LENGTH | MAX_DAY_NAME_LENGTH | DECIMAL_POINT | THOUSAND_SEP | ERROR_MESSAGE_LANGUAGE |
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+
|   0 | en_US | English - United States             |                     9 |                   9 | .             | ,            | english                |
|   1 | en_GB | English - United Kingdom            |                     9 |                   9 | .             | ,            | english                |
|   2 | ja_JP | Japanese - Japan                    |                     3 |                   3 | .             | ,            | japanese               |
|   3 | sv_SE | Swedish - Sweden                    |                     9 |                   7 | ,             |              | swedish                |
|   4 | de_DE | German - Germany                    |                     9 |                  10 | ,             | .            | german                 |
|   5 | fr_FR | French - France                     |                     9 |                   8 | ,             |              | french                 |
|   6 | ar_AE | Arabic - United Arab Emirates       |                     6 |                   8 | .             | ,            | english                |
|   7 | ar_BH | Arabic - Bahrain                    |                     6 |                   8 | .             | ,            | english                |
|   8 | ar_JO | Arabic - Jordan                     |                    12 |                   8 | .             | ,            | english                |
...
| 106 | no_NO | Norwegian - Norway                  |                     9 |                   7 | ,             | .            | norwegian              |
| 107 | sv_FI | Swedish - Finland                   |                     9 |                   7 | ,             |              | swedish                |
| 108 | zh_HK | Chinese - Hong Kong SAR             |                     3 |                   3 | .             | ,            | english                |
| 109 | el_GR | Greek - Greece                      |                    11 |                   9 | ,             | .            | greek                  |
+-----+-------+-------------------------------------+-----------------------+---------------------+---------------+--------------+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-locales-table/>

Information Schema SPATIAL\_REF\_SYS Table
==========================================

    Description
-----------

 The [Information Schema](../information_schema/index) `SPATIAL_REF_SYS` table stores information on each spatial reference system used in the database. 

 It contains the following columns:

 


| Column | Type | Null | Description |
| --- | --- | --- | --- |
| `SRID` | `smallint(5)` | `NO` | An integer value that uniquely identifies each Spatial Reference System within a database. |
| `AUTH_NAME` | `varchar(512)` | `NO` | The name of the standard or standards body that is being cited for this reference system. |
| `AUTH_SRID` | `smallint(5)` | `NO` | The numeric ID of the coordinate system in the above authority's catalog. |
| `SRTEXT` | `varchar(2048)` | `NO` | The [Well-known Text Representation](../wkt/index) of the Spatial Reference System. |

 
Note: See [MDEV-7540](https://jira.mariadb.org/browse/MDEV-7540).

 See Aso
-------

 * [information\_schema.GEOMETRY\_COLUMNS](../information-schema-geometry_status-table/index) table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-spatial_ref_sys-table/>

Information Schema SCHEMATA Table
=================================

    The [Information Schema](../information_schema/index) `SCHEMATA` table stores information about databases on the server.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CATALOG_NAME` | Always `def`. |
| `SCHEMA_NAME` | Database name. |
| `DEFAULT_CHARACTER_SET_NAME` | Default [character set](../data-types-character-sets-and-collations/index) for the database. |
| `DEFAULT_COLLATION_NAME` | Default [collation](../data-types-character-sets-and-collations/index). |
| `SQL_PATH` | Always `NULL`. |
| `SCHEMA_COMMENT` | Database comment. From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). |

 
Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA\G
*************************** 1. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: information_schema
DEFAULT_CHARACTER_SET_NAME: utf8
    DEFAULT_COLLATION_NAME: utf8_general_ci
                  SQL_PATH: NULL
*************************** 2. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: mysql
DEFAULT_CHARACTER_SET_NAME: latin1
    DEFAULT_COLLATION_NAME: latin1_swedish_ci
                  SQL_PATH: NULL
*************************** 3. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: performance_schema
DEFAULT_CHARACTER_SET_NAME: utf8
    DEFAULT_COLLATION_NAME: utf8_general_ci
                  SQL_PATH: NULL
*************************** 4. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: test
DEFAULT_CHARACTER_SET_NAME: latin1
    DEFAULT_COLLATION_NAME: latin1_swedish_ci
                  SQL_PATH: NULL
...

```

From [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/):

 
```
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA\G
...
*************************** 2. row ***************************
              CATALOG_NAME: def
               SCHEMA_NAME: presentations
DEFAULT_CHARACTER_SET_NAME: latin1
    DEFAULT_COLLATION_NAME: latin1_swedish_ci
                  SQL_PATH: NULL
            SCHEMA_COMMENT: Presentations for conferences
...

```

See Also
--------

 * [CREATE DATABASE](../create-database/index)
* [ALTER DATABASE](../alter-database/index)
* [DROP DATABASE](../drop-database/index)
* [SHOW CREATE DATABASE](../show-create-database/index)
* [SHOW DATABASES](../show-databases/index)
* [Character Sets and Collations](../character-sets-and-collations/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-schemata-table/>

Information Schema KEYWORDS Table
=================================

    
**MariaDB starting with [10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/)**The `KEYWORDS` table was added in [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/).

 
Description
-----------

 The [Information Schema](../information_schema/index) `KEYWORDS` table contains the list of MariaDB keywords.

 It contains a single column:

 


| Column | Description |
| --- | --- |
| `WORD` | Keyword |

 
The table is not a standard Information Schema table, and is a MariaDB extension.

 Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.KEYWORDS;
+-------------------------------+
| WORD                          |
+-------------------------------+
| &&                            |
| <=                            |
| <>                            |
| !=                            |
| >=                            |
| <<                            |
| >>                            |
| <=>                           |
| ACCESSIBLE                    |
| ACCOUNT                       |
| ACTION                        |
| ADD                           |
| ADMIN                         |
| AFTER                         |
| AGAINST                       |
| AGGREGATE                     |
| ALL                           |
| ALGORITHM                     |
| ALTER                         |
| ALWAYS                        |
| ANALYZE                       |
| AND                           |
| ANY                           |
| AS                            |
| ASC                           |
| ASCII                         |
| ASENSITIVE                    |
| AT                            |
| ATOMIC                        |
| AUTHORS                       |
| AUTO_INCREMENT                |
| AUTOEXTEND_SIZE               |
| AUTO                          |
| AVG                           |
| AVG_ROW_LENGTH                |
| BACKUP                        |
| BEFORE                        |
| BEGIN                         |
| BETWEEN                       |
| BIGINT                        |
| BINARY                        |
| BINLOG                        |
| BIT                           |
| BLOB                          |
| BLOCK                         |
| BODY                          |
| BOOL                          |
| BOOLEAN                       |
| BOTH                          |
| BTREE                         |
| BY                            |
| BYTE                          |
| CACHE                         |
| CALL                          |
| CASCADE                       |
| CASCADED                      |
| CASE                          |
| CATALOG_NAME                  |
| CHAIN                         |
| CHANGE                        |
| CHANGED                       |
| CHAR                          |
| CHARACTER                     |
| CHARSET                       |
| CHECK                         |
| CHECKPOINT                    |
| CHECKSUM                      |
| CIPHER                        |
| CLASS_ORIGIN                  |
| CLIENT                        |
| CLOB                          |
| CLOSE                         |
| COALESCE                      |
| CODE                          |
| COLLATE                       |
| COLLATION                     |
| COLUMN                        |
| COLUMN_NAME                   |
| COLUMNS                       |
| COLUMN_ADD                    |
| COLUMN_CHECK                  |
| COLUMN_CREATE                 |
| COLUMN_DELETE                 |
| COLUMN_GET                    |
| COMMENT                       |
| COMMIT                        |
| COMMITTED                     |
| COMPACT                       |
| COMPLETION                    |
| COMPRESSED                    |
| CONCURRENT                    |
| CONDITION                     |
| CONNECTION                    |
| CONSISTENT                    |
| CONSTRAINT                    |
| CONSTRAINT_CATALOG            |
| CONSTRAINT_NAME               |
| CONSTRAINT_SCHEMA             |
| CONTAINS                      |
| CONTEXT                       |
| CONTINUE                      |
| CONTRIBUTORS                  |
| CONVERT                       |
| CPU                           |
| CREATE                        |
| CROSS                         |
| CUBE                          |
| CURRENT                       |
| CURRENT_DATE                  |
| CURRENT_POS                   |
| CURRENT_ROLE                  |
| CURRENT_TIME                  |
| CURRENT_TIMESTAMP             |
| CURRENT_USER                  |
| CURSOR                        |
| CURSOR_NAME                   |
| CYCLE                         |
| DATA                          |
| DATABASE                      |
| DATABASES                     |
| DATAFILE                      |
| DATE                          |
| DATETIME                      |
| DAY                           |
| DAY_HOUR                      |
| DAY_MICROSECOND               |
| DAY_MINUTE                    |
| DAY_SECOND                    |
| DEALLOCATE                    |
| DEC                           |
| DECIMAL                       |
| DECLARE                       |
| DEFAULT                       |
| DEFINER                       |
| DELAYED                       |
| DELAY_KEY_WRITE               |
| DELETE                        |
| DELETE_DOMAIN_ID              |
| DESC                          |
| DESCRIBE                      |
| DES_KEY_FILE                  |
| DETERMINISTIC                 |
| DIAGNOSTICS                   |
| DIRECTORY                     |
| DISABLE                       |
| DISCARD                       |
| DISK                          |
| DISTINCT                      |
| DISTINCTROW                   |
| DIV                           |
| DO                            |
| DOUBLE                        |
| DO_DOMAIN_IDS                 |
| DROP                          |
| DUAL                          |
| DUMPFILE                      |
| DUPLICATE                     |
| DYNAMIC                       |
| EACH                          |
| ELSE                          |
| ELSEIF                        |
| ELSIF                         |
| EMPTY                         |
| ENABLE                        |
| ENCLOSED                      |
| END                           |
| ENDS                          |
| ENGINE                        |
| ENGINES                       |
| ENUM                          |
| ERROR                         |
| ERRORS                        |
| ESCAPE                        |
| ESCAPED                       |
| EVENT                         |
| EVENTS                        |
| EVERY                         |
| EXAMINED                      |
| EXCEPT                        |
| EXCHANGE                      |
| EXCLUDE                       |
| EXECUTE                       |
| EXCEPTION                     |
| EXISTS                        |
| EXIT                          |
| EXPANSION                     |
| EXPIRE                        |
| EXPORT                        |
| EXPLAIN                       |
| EXTENDED                      |
| EXTENT_SIZE                   |
| FALSE                         |
| FAST                          |
| FAULTS                        |
| FEDERATED                     |
| FETCH                         |
| FIELDS                        |
| FILE                          |
| FIRST                         |
| FIXED                         |
| FLOAT                         |
| FLOAT4                        |
| FLOAT8                        |
| FLUSH                         |
| FOLLOWING                     |
| FOLLOWS                       |
| FOR                           |
| FORCE                         |
| FOREIGN                       |
| FORMAT                        |
| FOUND                         |
| FROM                          |
| FULL                          |
| FULLTEXT                      |
| FUNCTION                      |
| GENERAL                       |
| GENERATED                     |
| GET_FORMAT                    |
| GET                           |
| GLOBAL                        |
| GOTO                          |
| GRANT                         |
| GRANTS                        |
| GROUP                         |
| HANDLER                       |
| HARD                          |
| HASH                          |
| HAVING                        |
| HELP                          |
| HIGH_PRIORITY                 |
| HISTORY                       |
| HOST                          |
| HOSTS                         |
| HOUR                          |
| HOUR_MICROSECOND              |
| HOUR_MINUTE                   |
| HOUR_SECOND                   |
| ID                            |
| IDENTIFIED                    |
| IF                            |
| IGNORE                        |
| IGNORED                       |
| IGNORE_DOMAIN_IDS             |
| IGNORE_SERVER_IDS             |
| IMMEDIATE                     |
| IMPORT                        |
| INTERSECT                     |
| IN                            |
| INCREMENT                     |
| INDEX                         |
| INDEXES                       |
| INFILE                        |
| INITIAL_SIZE                  |
| INNER                         |
| INOUT                         |
| INSENSITIVE                   |
| INSERT                        |
| INSERT_METHOD                 |
| INSTALL                       |
| INT                           |
| INT1                          |
| INT2                          |
| INT3                          |
| INT4                          |
| INT8                          |
| INTEGER                       |
| INTERVAL                      |
| INVISIBLE                     |
| INTO                          |
| IO                            |
| IO_THREAD                     |
| IPC                           |
| IS                            |
| ISOLATION                     |
| ISOPEN                        |
| ISSUER                        |
| ITERATE                       |
| INVOKER                       |
| JOIN                          |
| JSON                          |
| JSON_TABLE                    |
| KEY                           |
| KEYS                          |
| KEY_BLOCK_SIZE                |
| KILL                          |
| LANGUAGE                      |
| LAST                          |
| LAST_VALUE                    |
| LASTVAL                       |
| LEADING                       |
| LEAVE                         |
| LEAVES                        |
| LEFT                          |
| LESS                          |
| LEVEL                         |
| LIKE                          |
| LIMIT                         |
| LINEAR                        |
| LINES                         |
| LIST                          |
| LOAD                          |
| LOCAL                         |
| LOCALTIME                     |
| LOCALTIMESTAMP                |
| LOCK                          |
| LOCKED                        |
| LOCKS                         |
| LOGFILE                       |
| LOGS                          |
| LONG                          |
| LONGBLOB                      |
| LONGTEXT                      |
| LOOP                          |
| LOW_PRIORITY                  |
| MASTER                        |
| MASTER_CONNECT_RETRY          |
| MASTER_DELAY                  |
| MASTER_GTID_POS               |
| MASTER_HOST                   |
| MASTER_LOG_FILE               |
| MASTER_LOG_POS                |
| MASTER_PASSWORD               |
| MASTER_PORT                   |
| MASTER_SERVER_ID              |
| MASTER_SSL                    |
| MASTER_SSL_CA                 |
| MASTER_SSL_CAPATH             |
| MASTER_SSL_CERT               |
| MASTER_SSL_CIPHER             |
| MASTER_SSL_CRL                |
| MASTER_SSL_CRLPATH            |
| MASTER_SSL_KEY                |
| MASTER_SSL_VERIFY_SERVER_CERT |
| MASTER_USER                   |
| MASTER_USE_GTID               |
| MASTER_HEARTBEAT_PERIOD       |
| MATCH                         |
| MAX_CONNECTIONS_PER_HOUR      |
| MAX_QUERIES_PER_HOUR          |
| MAX_ROWS                      |
| MAX_SIZE                      |
| MAX_STATEMENT_TIME            |
| MAX_UPDATES_PER_HOUR          |
| MAX_USER_CONNECTIONS          |
| MAXVALUE                      |
| MEDIUM                        |
| MEDIUMBLOB                    |
| MEDIUMINT                     |
| MEDIUMTEXT                    |
| MEMORY                        |
| MERGE                         |
| MESSAGE_TEXT                  |
| MICROSECOND                   |
| MIDDLEINT                     |
| MIGRATE                       |
| MINUS                         |
| MINUTE                        |
| MINUTE_MICROSECOND            |
| MINUTE_SECOND                 |
| MINVALUE                      |
| MIN_ROWS                      |
| MOD                           |
| MODE                          |
| MODIFIES                      |
| MODIFY                        |
| MONITOR                       |
| MONTH                         |
| MUTEX                         |
| MYSQL                         |
| MYSQL_ERRNO                   |
| NAME                          |
| NAMES                         |
| NATIONAL                      |
| NATURAL                       |
| NCHAR                         |
| NESTED                        |
| NEVER                         |
| NEW                           |
| NEXT                          |
| NEXTVAL                       |
| NO                            |
| NOMAXVALUE                    |
| NOMINVALUE                    |
| NOCACHE                       |
| NOCYCLE                       |
| NO_WAIT                       |
| NOWAIT                        |
| NODEGROUP                     |
| NONE                          |
| NOT                           |
| NOTFOUND                      |
| NO_WRITE_TO_BINLOG            |
| NULL                          |
| NUMBER                        |
| NUMERIC                       |
| NVARCHAR                      |
| OF                            |
| OFFSET                        |
| OLD_PASSWORD                  |
| ON                            |
| ONE                           |
| ONLINE                        |
| ONLY                          |
| OPEN                          |
| OPTIMIZE                      |
| OPTIONS                       |
| OPTION                        |
| OPTIONALLY                    |
| OR                            |
| ORDER                         |
| ORDINALITY                    |
| OTHERS                        |
| OUT                           |
| OUTER                         |
| OUTFILE                       |
| OVER                          |
| OVERLAPS                      |
| OWNER                         |
| PACKAGE                       |
| PACK_KEYS                     |
| PAGE                          |
| PAGE_CHECKSUM                 |
| PARSER                        |
| PARSE_VCOL_EXPR               |
| PATH                          |
| PERIOD                        |
| PARTIAL                       |
| PARTITION                     |
| PARTITIONING                  |
| PARTITIONS                    |
| PASSWORD                      |
| PERSISTENT                    |
| PHASE                         |
| PLUGIN                        |
| PLUGINS                       |
| PORT                          |
| PORTION                       |
| PRECEDES                      |
| PRECEDING                     |
| PRECISION                     |
| PREPARE                       |
| PRESERVE                      |
| PREV                          |
| PREVIOUS                      |
| PRIMARY                       |
| PRIVILEGES                    |
| PROCEDURE                     |
| PROCESS                       |
| PROCESSLIST                   |
| PROFILE                       |
| PROFILES                      |
| PROXY                         |
| PURGE                         |
| QUARTER                       |
| QUERY                         |
| QUICK                         |
| RAISE                         |
| RANGE                         |
| RAW                           |
| READ                          |
| READ_ONLY                     |
| READ_WRITE                    |
| READS                         |
| REAL                          |
| REBUILD                       |
| RECOVER                       |
| RECURSIVE                     |
| REDO_BUFFER_SIZE              |
| REDOFILE                      |
| REDUNDANT                     |
| REFERENCES                    |
| REGEXP                        |
| RELAY                         |
| RELAYLOG                      |
| RELAY_LOG_FILE                |
| RELAY_LOG_POS                 |
| RELAY_THREAD                  |
| RELEASE                       |
| RELOAD                        |
| REMOVE                        |
| RENAME                        |
| REORGANIZE                    |
| REPAIR                        |
| REPEATABLE                    |
| REPLACE                       |
| REPLAY                        |
| REPLICA                       |
| REPLICAS                      |
| REPLICA_POS                   |
| REPLICATION                   |
| REPEAT                        |
| REQUIRE                       |
| RESET                         |
| RESIGNAL                      |
| RESTART                       |
| RESTORE                       |
| RESTRICT                      |
| RESUME                        |
| RETURNED_SQLSTATE             |
| RETURN                        |
| RETURNING                     |
| RETURNS                       |
| REUSE                         |
| REVERSE                       |
| REVOKE                        |
| RIGHT                         |
| RLIKE                         |
| ROLE                          |
| ROLLBACK                      |
| ROLLUP                        |
| ROUTINE                       |
| ROW                           |
| ROWCOUNT                      |
| ROWNUM                        |
| ROWS                          |
| ROWTYPE                       |
| ROW_COUNT                     |
| ROW_FORMAT                    |
| RTREE                         |
| SAVEPOINT                     |
| SCHEDULE                      |
| SCHEMA                        |
| SCHEMA_NAME                   |
| SCHEMAS                       |
| SECOND                        |
| SECOND_MICROSECOND            |
| SECURITY                      |
| SELECT                        |
| SENSITIVE                     |
| SEPARATOR                     |
| SEQUENCE                      |
| SERIAL                        |
| SERIALIZABLE                  |
| SESSION                       |
| SERVER                        |
| SET                           |
| SETVAL                        |
| SHARE                         |
| SHOW                          |
| SHUTDOWN                      |
| SIGNAL                        |
| SIGNED                        |
| SIMPLE                        |
| SKIP                          |
| SLAVE                         |
| SLAVES                        |
| SLAVE_POS                     |
| SLOW                          |
| SNAPSHOT                      |
| SMALLINT                      |
| SOCKET                        |
| SOFT                          |
| SOME                          |
| SONAME                        |
| SOUNDS                        |
| SOURCE                        |
| STAGE                         |
| STORED                        |
| SPATIAL                       |
| SPECIFIC                      |
| REF_SYSTEM_ID                 |
| SQL                           |
| SQLEXCEPTION                  |
| SQLSTATE                      |
| SQLWARNING                    |
| SQL_BIG_RESULT                |
| SQL_BUFFER_RESULT             |
| SQL_CACHE                     |
| SQL_CALC_FOUND_ROWS           |
| SQL_NO_CACHE                  |
| SQL_SMALL_RESULT              |
| SQL_THREAD                    |
| SQL_TSI_SECOND                |
| SQL_TSI_MINUTE                |
| SQL_TSI_HOUR                  |
| SQL_TSI_DAY                   |
| SQL_TSI_WEEK                  |
| SQL_TSI_MONTH                 |
| SQL_TSI_QUARTER               |
| SQL_TSI_YEAR                  |
| SSL                           |
| START                         |
| STARTING                      |
| STARTS                        |
| STATEMENT                     |
| STATS_AUTO_RECALC             |
| STATS_PERSISTENT              |
| STATS_SAMPLE_PAGES            |
| STATUS                        |
| STOP                          |
| STORAGE                       |
| STRAIGHT_JOIN                 |
| STRING                        |
| SUBCLASS_ORIGIN               |
| SUBJECT                       |
| SUBPARTITION                  |
| SUBPARTITIONS                 |
| SUPER                         |
| SUSPEND                       |
| SWAPS                         |
| SWITCHES                      |
| SYSDATE                       |
| SYSTEM                        |
| SYSTEM_TIME                   |
| TABLE                         |
| TABLE_NAME                    |
| TABLES                        |
| TABLESPACE                    |
| TABLE_CHECKSUM                |
| TEMPORARY                     |
| TEMPTABLE                     |
| TERMINATED                    |
| TEXT                          |
| THAN                          |
| THEN                          |
| TIES                          |
| TIME                          |
| TIMESTAMP                     |
| TIMESTAMPADD                  |
| TIMESTAMPDIFF                 |
| TINYBLOB                      |
| TINYINT                       |
| TINYTEXT                      |
| TO                            |
| TRAILING                      |
| TRANSACTION                   |
| TRANSACTIONAL                 |
| THREADS                       |
| TRIGGER                       |
| TRIGGERS                      |
| TRUE                          |
| TRUNCATE                      |
| TYPE                          |
| TYPES                         |
| UNBOUNDED                     |
| UNCOMMITTED                   |
| UNDEFINED                     |
| UNDO_BUFFER_SIZE              |
| UNDOFILE                      |
| UNDO                          |
| UNICODE                       |
| UNION                         |
| UNIQUE                        |
| UNKNOWN                       |
| UNLOCK                        |
| UNINSTALL                     |
| UNSIGNED                      |
| UNTIL                         |
| UPDATE                        |
| UPGRADE                       |
| USAGE                         |
| USE                           |
| USER                          |
| USER_RESOURCES                |
| USE_FRM                       |
| USING                         |
| UTC_DATE                      |
| UTC_TIME                      |
| UTC_TIMESTAMP                 |
| VALUE                         |
| VALUES                        |
| VARBINARY                     |
| VARCHAR                       |
| VARCHARACTER                  |
| VARCHAR2                      |
| VARIABLES                     |
| VARYING                       |
| VIA                           |
| VIEW                          |
| VIRTUAL                       |
| VISIBLE                       |
| VERSIONING                    |
| WAIT                          |
| WARNINGS                      |
| WEEK                          |
| WEIGHT_STRING                 |
| WHEN                          |
| WHERE                         |
| WHILE                         |
| WINDOW                        |
| WITH                          |
| WITHIN                        |
| WITHOUT                       |
| WORK                          |
| WRAPPER                       |
| WRITE                         |
| X509                          |
| XOR                           |
| XA                            |
| XML                           |
| YEAR                          |
| YEAR_MONTH                    |
| ZEROFILL                      |
| ||                            |
+-------------------------------+
694 rows in set (0.000 sec)

```

See Also
--------

 * [Reserved Words](../reserved-words/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-keywords-table/>

Information Schema OPTIMIZER\_TRACE Table
=========================================

    
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**[Optimizer Trace](../optimizer-trace/index) was introduced in [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/).

 
Description
-----------

 The [Information Schema](../information_schema/index) `OPTIMIZER_TRACE` table contains [Optimizer Trace](../optimizer-trace/index) information.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `QUERY` | Displays the query that was asked to be traced. |
| `TRACE` | A JSON document displaying the stats we collected when the query was run. |
| `MISSING_BYTES_BEYOND_MAX_MEM_SIZE` | For huge trace, where the trace is truncated due to the optimizer\_trace\_max\_mem\_size limit being reached, displays the bytes that are missing in the trace |
| `INSUFFICENT_PRIVILEGES` | Set to 1 if the user running the trace does not have the privileges to see the trace. |

 
Structure:

 
```
SHOW CREATE TABLE INFORMATION_SCHEMA.OPTIMIZER_TRACE \G
*************************** 1. row ***************************
       Table: OPTIMIZER_TRACE
Create Table: CREATE TEMPORARY TABLE `OPTIMIZER_TRACE` (
  `QUERY` longtext NOT NULL DEFAULT '',
  `TRACE` longtext NOT NULL DEFAULT '',
  `MISSING_BYTES_BEYOND_MAX_MEM_SIZE` int(20) NOT NULL DEFAULT 0,
  `INSUFFICIENT_PRIVILEGES` tinyint(1) NOT NULL DEFAULT 0
) ENGINE=Aria DEFAULT CHARSET=utf8 PAGE_CHECKSUM=0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-optimizer_trace-table/>

Information Schema PROFILING Table
==================================

    The [Information Schema](../information_schema/index) `PROFILING` table contains information about statement resource usage. Profiling information is only recorded if the `[profiling](../server-system-variables/index#profiling)` session variable is set to 1. 

 It contains the following columns:

 


| Column Name | Description |
| --- | --- |
| `QUERY_ID` | Query\_ID. |
| `SEQ` | Sequence number showing the display order for rows with the same `QUERY_ID`. |
| `STATE` | Profiling state. |
| `DURATION` | Time in seconds that the statement has been in the current state. |
| `CPU_USER` | User CPU usage in seconds. |
| `CPU_SYSTEM` | System CPU usage in seconds. |
| `CONTEXT_VOLUNTARY` | Number of voluntary context switches. |
| `CONTEXT_INVOLUNTARY` | Number of involuntary context switches. |
| `BLOCK_OPS_IN` | Number of block input operations. |
| `BLOCK_OPS_OUT` | Number of block output operations. |
| `MESSAGES_SENT` | Number of communications sent. |
| `MESSAGES_RECEIVED` | Number of communications received. |
| `PAGE_FAULTS_MAJOR` | Number of major page faults. |
| `PAGE_FAULTS_MINOR` | Number of minor page faults. |
| `SWAPS` | Number of swaps. |
| `SOURCE_FUNCTION` | Function in the source code executed by the profiled state. |
| `SOURCE_FILE` | File in the source code executed by the profiled state. |
| `SOURCE_LINE` | Line in the source code executed by the profiled state. |

 
It contains similar information to the `[SHOW PROFILE](../show-profile/index) and [SHOW PROFILES](../show-profiles/index)` statements.

 Profiling is enabled per session. When a session ends, its profiling information is lost.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-profiling-table/>

Information Schema QUERY\_CACHE\_INFO Table
===========================================

    Description
-----------

 The table is not a standard Information Schema table, and is a MariaDB extension.

 The `QUERY_CACHE_INFO` table is created by the [QUERY\_CACHE\_INFO](../query_cache_info-plugin/index) plugin, and allows you to see the contents of the [query cache](../query-cache/index). It creates a table in the [information\_schema](../information_schema/index) database that shows all queries that are in the cache. You must have the `PROCESS` privilege (see [GRANT](../grant/index)) to use this table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `STATEMENT_SCHEMA` | Database used when query was included |
| `STATEMENT_TEXT` | Query text |
| `RESULT_BLOCKS_COUNT` | Number of result blocks |
| `RESULT_BLOCKS_SIZE` | Size in bytes of result blocks |
| `RESULT_BLOCKS_SIZE_USED` | Size in bytes of used blocks |
| `LIMIT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `MAX_SORT_LENGTH` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `GROUP_CONCAT_MAX_LENGTH` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `CHARACTER_SET_CLIENT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `CHARACTER_SET_RESULT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `COLLATION`  | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `TIMEZONE` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `DEFAULT_WEEK_FORMAT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `DIV_PRECISION_INCREMENT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `SQL_MODE` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `LC_TIME_NAMES` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `CLIENT_LONG_FLAG` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `CLIENT_PROTOCOL_41` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `PROTOCOL_TYPE` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `MORE_RESULTS_EXISTS` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `IN_TRANS` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `AUTOCOMMIT` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `PACKET_NUMBER` | Added [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/). |
| `HITS` | Incremented each time the query cache is hit. Added [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/). |

 
For example:

 
```
SELECT * FROM information_schema.QUERY_CACHE_INFO;
+------------------+-----------------+---------------------+--------------------+-------------------------+
| STATEMENT_SCHEMA | STATEMENT_TEXT  | RESULT_BLOCKS_COUNT | RESULT_BLOCKS_SIZE | RESULT_BLOCKS_SIZE_USED |
+------------------+-----------------+---------------------+--------------------+-------------------------+
...
| test             | SELECT * FROM a |                   1 |                512 |                     143 |
| test             | select * FROM a |                   1 |                512 |                     143 |
...
+------------------+-----------------+---------------------+--------------------+-------------------------

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-query_cache_info-table/>

Information Schema STATISTICS Table
===================================

    The [Information Schema](../information_schema/index) `STATISTICS` table provides information about table indexes.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_CATALOG` | Always `def`. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `NON_UNIQUE` | `1` if the index can have duplicates, `0` if not. |
| `INDEX_SCHEMA` | Database name. |
| `INDEX_NAME` | Index name. The primary key is always named `PRIMARY`. |
| `SEQ_IN_INDEX` | The column sequence number, starting at 1. |
| `COLUMN_NAME` | Column name. |
| `COLLATION` | `A` for sorted in ascending order, or `NULL` for unsorted. |
| `CARDINALITY` | Estimate of the number of unique values stored in the index based on statistics stored as integers. Higher cardinalities usually mean a greater chance of the index being used in a join. Updated by the [ANALYZE TABLE](../analyze-table/index) statement or [myisamchk -a](../myisamchk/index). |
| `SUB_PART` | `NULL` if the whole column is indexed, or the number of indexed characters if partly indexed. |
| `PACKED` | `NULL` if not packed, otherwise how the index is packed. |
| `NULLABLE` | `YES` if the column may contain NULLs, empty string if not. |
| `INDEX_TYPE` | Index type, one of `BTREE`, `RTREE`, `HASH` or `FULLTEXT`. See [Storage Engine Index Types](../storage-engine-index-types/index). |
| `COMMENT` | Index comments from the [CREATE INDEX](../create-index/index) statement. |
| `IGNORED` | Whether or not an index will be ignored by the optimizer. See [Ignored Indexes](../ignored-indexes/index). From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). |

 
The `[SHOW INDEX](../show-index/index)` statement produces similar output.

 Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.STATISTICS\G
...
*************************** 85. row ***************************
TABLE_CATALOG: def
 TABLE_SCHEMA: test
   TABLE_NAME: table1
   NON_UNIQUE: 1
 INDEX_SCHEMA: test
   INDEX_NAME: col2
 SEQ_IN_INDEX: 1
  COLUMN_NAME: col2
    COLLATION: A
  CARDINALITY: 6
     SUB_PART: NULL
       PACKED: NULL
     NULLABLE: 
   INDEX_TYPE: BTREE
      COMMENT: 
INDEX_COMMENT:
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-statistics-table/>

Information Schema TABLE\_PRIVILEGES Table
==========================================

    The [Information Schema](../information_schema/index) `TABLE_PRIVILEGES` table contains table privilege information derived from the `[mysql.tables\_priv](../mysqltables_priv-table/index)` grant table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `GRANTEE` | In the format `user_name@host_name`. |
| `TABLE_CATALOG` | Always `def`. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `PRIVILEGE_TYPE` | One of `SELECT`, `INSERT`, `UPDATE`, `REFERENCES`, `ALTER`, `INDEX`, `DROP` or `CREATE VIEW`. |
| `IS_GRANTABLE` | Whether the user has the `[GRANT OPTION](../grant/index#the-grant-option-privilege)` for this privilege. |

 
Similar information can be accessed with the `[SHOW GRANTS](../show-grants/index)` statement. See the `[GRANT](../grant/index)` article for more about privileges.

 For a description of the privileges that are shown in this table, see [table privileges](../grant/index#table-privileges).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-table_privileges-table/>

Information Schema SQL\_FUNCTIONS Table
=======================================

    
**MariaDB starting with [10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/)**The `SQL_FUNCTIONS` table was added in [MariaDB 10.6.3](https://mariadb.com/kb/en/mariadb-1063-release-notes/).

 
Description
-----------

 The [Information Schema](../information_schema/index) `SQL_FUNCTIONS` table contains the list of [MariaDB functions](../built-in-functions/index).

 It contains a single column:

 


| Column | Description |
| --- | --- |
| `FUNCTION` | Function name |

 
The table is not a standard Information Schema table, and is a MariaDB extension.

 Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.SQL_FUNCTIONS;
+---------------------------+
| FUNCTION                  |
+---------------------------+
| ADDDATE                   |
| ADD_MONTHS                |
| BIT_AND                   |
| BIT_OR                    |
| BIT_XOR                   |
| CAST                      |
| COUNT                     |
| CUME_DIST                 |
| CURDATE                   |
| CURTIME                   |
| DATE_ADD                  |
| DATE_SUB                  |
| DATE_FORMAT               |
| DECODE                    |
| DENSE_RANK                |
| EXTRACT                   |
| FIRST_VALUE               |
| GROUP_CONCAT              |
| JSON_ARRAYAGG             |
| JSON_OBJECTAGG            |
| LAG                       |
| LEAD                      |
| MAX                       |
| MEDIAN                    |
| MID                       |
| MIN                       |
| NOW                       |
| NTH_VALUE                 |
| NTILE                     |
| POSITION                  |
| PERCENT_RANK              |
| PERCENTILE_CONT           |
| PERCENTILE_DISC           |
| RANK                      |
| ROW_NUMBER                |
| SESSION_USER              |
| STD                       |
| STDDEV                    |
| STDDEV_POP                |
| STDDEV_SAMP               |
| SUBDATE                   |
| SUBSTR                    |
| SUBSTRING                 |
| SUM                       |
| SYSTEM_USER               |
| TRIM                      |
| TRIM_ORACLE               |
| VARIANCE                  |
| VAR_POP                   |
| VAR_SAMP                  |
| ABS                       |
| ACOS                      |
| ADDTIME                   |
| AES_DECRYPT               |
| AES_ENCRYPT               |
| ASIN                      |
| ATAN                      |
| ATAN2                     |
| BENCHMARK                 |
| BIN                       |
| BINLOG_GTID_POS           |
| BIT_COUNT                 |
| BIT_LENGTH                |
| CEIL                      |
| CEILING                   |
| CHARACTER_LENGTH          |
| CHAR_LENGTH               |
| CHR                       |
| COERCIBILITY              |
| COLUMN_CHECK              |
| COLUMN_EXISTS             |
| COLUMN_LIST               |
| COLUMN_JSON               |
| COMPRESS                  |
| CONCAT                    |
| CONCAT_OPERATOR_ORACLE    |
| CONCAT_WS                 |
| CONNECTION_ID             |
| CONV                      |
| CONVERT_TZ                |
| COS                       |
| COT                       |
| CRC32                     |
| DATEDIFF                  |
| DAYNAME                   |
| DAYOFMONTH                |
| DAYOFWEEK                 |
| DAYOFYEAR                 |
| DEGREES                   |
| DECODE_HISTOGRAM          |
| DECODE_ORACLE             |
| DES_DECRYPT               |
| DES_ENCRYPT               |
| ELT                       |
| ENCODE                    |
| ENCRYPT                   |
| EXP                       |
| EXPORT_SET                |
| EXTRACTVALUE              |
| FIELD                     |
| FIND_IN_SET               |
| FLOOR                     |
| FORMAT                    |
| FOUND_ROWS                |
| FROM_BASE64               |
| FROM_DAYS                 |
| FROM_UNIXTIME             |
| GET_LOCK                  |
| GREATEST                  |
| HEX                       |
| IFNULL                    |
| INSTR                     |
| ISNULL                    |
| IS_FREE_LOCK              |
| IS_USED_LOCK              |
| JSON_ARRAY                |
| JSON_ARRAY_APPEND         |
| JSON_ARRAY_INSERT         |
| JSON_COMPACT              |
| JSON_CONTAINS             |
| JSON_CONTAINS_PATH        |
| JSON_DEPTH                |
| JSON_DETAILED             |
| JSON_EXISTS               |
| JSON_EXTRACT              |
| JSON_INSERT               |
| JSON_KEYS                 |
| JSON_LENGTH               |
| JSON_LOOSE                |
| JSON_MERGE                |
| JSON_MERGE_PATCH          |
| JSON_MERGE_PRESERVE       |
| JSON_QUERY                |
| JSON_QUOTE                |
| JSON_OBJECT               |
| JSON_REMOVE               |
| JSON_REPLACE              |
| JSON_SET                  |
| JSON_SEARCH               |
| JSON_TYPE                 |
| JSON_UNQUOTE              |
| JSON_VALID                |
| JSON_VALUE                |
| LAST_DAY                  |
| LAST_INSERT_ID            |
| LCASE                     |
| LEAST                     |
| LENGTH                    |
| LENGTHB                   |
| LN                        |
| LOAD_FILE                 |
| LOCATE                    |
| LOG                       |
| LOG10                     |
| LOG2                      |
| LOWER                     |
| LPAD                      |
| LPAD_ORACLE               |
| LTRIM                     |
| LTRIM_ORACLE              |
| MAKEDATE                  |
| MAKETIME                  |
| MAKE_SET                  |
| MASTER_GTID_WAIT          |
| MASTER_POS_WAIT           |
| MD5                       |
| MONTHNAME                 |
| NAME_CONST                |
| NVL                       |
| NVL2                      |
| NULLIF                    |
| OCT                       |
| OCTET_LENGTH              |
| ORD                       |
| PERIOD_ADD                |
| PERIOD_DIFF               |
| PI                        |
| POW                       |
| POWER                     |
| QUOTE                     |
| REGEXP_INSTR              |
| REGEXP_REPLACE            |
| REGEXP_SUBSTR             |
| RADIANS                   |
| RAND                      |
| RELEASE_ALL_LOCKS         |
| RELEASE_LOCK              |
| REPLACE_ORACLE            |
| REVERSE                   |
| ROUND                     |
| RPAD                      |
| RPAD_ORACLE               |
| RTRIM                     |
| RTRIM_ORACLE              |
| SEC_TO_TIME               |
| SHA                       |
| SHA1                      |
| SHA2                      |
| SIGN                      |
| SIN                       |
| SLEEP                     |
| SOUNDEX                   |
| SPACE                     |
| SQRT                      |
| STRCMP                    |
| STR_TO_DATE               |
| SUBSTR_ORACLE             |
| SUBSTRING_INDEX           |
| SUBTIME                   |
| SYS_GUID                  |
| TAN                       |
| TIMEDIFF                  |
| TIME_FORMAT               |
| TIME_TO_SEC               |
| TO_BASE64                 |
| TO_CHAR                   |
| TO_DAYS                   |
| TO_SECONDS                |
| UCASE                     |
| UNCOMPRESS                |
| UNCOMPRESSED_LENGTH       |
| UNHEX                     |
| UNIX_TIMESTAMP            |
| UPDATEXML                 |
| UPPER                     |
| UUID                      |
| UUID_SHORT                |
| VERSION                   |
| WEEKDAY                   |
| WEEKOFYEAR                |
| WSREP_LAST_WRITTEN_GTID   |
| WSREP_LAST_SEEN_GTID      |
| WSREP_SYNC_WAIT_UPTO_GTID |
| YEARWEEK                  |
+---------------------------+
234 rows in set (0.001 sec)

```

See Also
--------

 * [Reserved Words](../reserved-words/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-sql_functions-table/>

Information Schema TABLES Table
===============================

     The [Information Schema](../information_schema/index) table shows information about the various tables (until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), only non-`TEMPORARY` tables, except for tables from the `Information Schema` database) and [views](../views/index) on the server.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_CATALOG` | Always `def`. |
| `TABLE_SCHEMA` | Database name. |
| `TABLE_NAME` | Table name. |
| `TABLE_TYPE` | One of `BASE TABLE` for a regular table, `VIEW` for a [view](../views/index), `SYSTEM VIEW` for [Information Schema](../information_schema/index) tables, `SYSTEM VERSIONED` for [system-versioned tables](../system-versioned-tables/index), `SEQUENCE` for [sequences](../sequences/index) or, from [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), `TEMPORARY` for local temporary tables. |
| `ENGINE` | [Storage Engine](../storage-engines/index). |
| `VERSION` | Version number from the table's .frm file |
| `ROW_FORMAT` | Row format (see [InnoDB](../xtradbinnodb-storage-formats/index), [Aria](../aria-storage-formats/index) and [MyISAM](../myisam-storage-formats/index) row formats). |
| `TABLE_ROWS` | Number of rows in the table. Some engines, such as [XtraDB and InnoDB](../xtradb-and-innodb/index) may store an estimate. |
| `AVG_ROW_LENGTH` | Average row length in the table. |
| `DATA_LENGTH` | For [InnoDB/XtraDB](../innodb/index), the index size, in pages, multiplied by the page size. For [Aria](../aria/index) and [MyISAM](../myisam/index), length of the data file, in bytes. For [MEMORY](../memory-storage-engine/index), the approximate allocated memory. |
| `MAX_DATA_LENGTH` | Maximum length of the data file, ie the total number of bytes that could be stored in the table. Not used in [XtraDB and InnoDB](../innodb/index). |
| `INDEX_LENGTH` | Length of the index file. |
| `DATA_FREE` | Bytes allocated but unused. For [InnoDB](../xtradb-and-innodb/index) tables in a shared tablespace, the free space of the shared tablespace with small safety margin. An estimate in the case of partitioned tables - see the `[PARTITIONS](../information-schema-partitions-table/index)` table. |
| `AUTO_INCREMENT` | Next [AUTO\_INCREMENT](../auto_increment/index) value. |
| `CREATE_TIME` | Time the table was created. Some engines just return the `ctime` information from the file system layer here, in that case the value is not necessarily the table creation time but rather the time the file system metadata for it had last changed. |
| `UPDATE_TIME` | Time the table was last updated. On Windows, the timestamp is not updated on update, so MyISAM values will be inaccurate. In [InnoDB](../xtradb-and-innodb/index), if shared tablespaces are used, will be NULL, while buffering can also delay the update, so the value will differ from the actual time of the last `UPDATE`, `INSERT` or `DELETE`. |
| `CHECK_TIME` | Time the table was last checked. Not kept by all storage engines, in which case will be `NULL`. |
| `TABLE_COLLATION` | [Character set and collation](../data-types-character-sets-and-collations/index). |
| `CHECKSUM` | Live checksum value, if any. |
| `CREATE_OPTIONS` | Extra `[CREATE TABLE](../create-table/index)` options. |
| `TABLE_COMMENT` | Table comment provided when MariaDB created the table. |
| `MAX_INDEX_LENGTH` | Maximum index length (supported by MyISAM and Aria tables). Added in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/). |
| `TEMPORARY` | Until [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), placeholder to signal that a table is a temporary table and always "N", except "Y" for generated information\_schema tables and NULL for [views](../views/index). From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/), will also be set to "Y" for local temporary tables. Added in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/). |

 
Although the table is standard in the Information Schema, all but `TABLE_CATALOG`, `TABLE_SCHEMA`, `TABLE_NAME`, `TABLE_TYPE`, `ENGINE` and `VERSION` are MySQL and MariaDB extensions.

 [SHOW TABLES](../show-tables/index) lists all tables in a database.

 Examples
--------

 From [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/):

 
```
SELECT * FROM information_schema.tables WHERE table_schema='test'\G
*************************** 1. row ***************************
   TABLE_CATALOG: def
    TABLE_SCHEMA: test
      TABLE_NAME: xx5
      TABLE_TYPE: BASE TABLE
          ENGINE: InnoDB
         VERSION: 10
      ROW_FORMAT: Dynamic
      TABLE_ROWS: 0
  AVG_ROW_LENGTH: 0
     DATA_LENGTH: 16384
 MAX_DATA_LENGTH: 0
    INDEX_LENGTH: 0
       DATA_FREE: 0
  AUTO_INCREMENT: NULL
     CREATE_TIME: 2020-11-18 15:57:10
     UPDATE_TIME: NULL
      CHECK_TIME: NULL
 TABLE_COLLATION: latin1_swedish_ci
        CHECKSUM: NULL
  CREATE_OPTIONS: 
   TABLE_COMMENT: 
MAX_INDEX_LENGTH: 0
       TEMPORARY: N
*************************** 2. row ***************************
   TABLE_CATALOG: def
    TABLE_SCHEMA: test
      TABLE_NAME: xx4
      TABLE_TYPE: BASE TABLE
          ENGINE: MyISAM
         VERSION: 10
      ROW_FORMAT: Fixed
      TABLE_ROWS: 0
  AVG_ROW_LENGTH: 0
     DATA_LENGTH: 0
 MAX_DATA_LENGTH: 1970324836974591
    INDEX_LENGTH: 1024
       DATA_FREE: 0
  AUTO_INCREMENT: NULL
     CREATE_TIME: 2020-11-18 15:56:57
     UPDATE_TIME: 2020-11-18 15:56:57
      CHECK_TIME: NULL
 TABLE_COLLATION: latin1_swedish_ci
        CHECKSUM: NULL
  CREATE_OPTIONS: 
   TABLE_COMMENT: 
MAX_INDEX_LENGTH: 17179868160
       TEMPORARY: N
...

```

Example with temporary = 'y', from [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/):

 
```
SELECT * FROM information_schema.tables WHERE temporary='y'\G
 *************************** 1. row ***************************
   TABLE_CATALOG: def
    TABLE_SCHEMA: information_schema
      TABLE_NAME: INNODB_FT_DELETED
      TABLE_TYPE: SYSTEM VIEW
          ENGINE: MEMORY
         VERSION: 11
      ROW_FORMAT: Fixed
      TABLE_ROWS: NULL
  AVG_ROW_LENGTH: 9
     DATA_LENGTH: 0
 MAX_DATA_LENGTH: 9437184
    INDEX_LENGTH: 0
       DATA_FREE: 0
  AUTO_INCREMENT: NULL
     CREATE_TIME: 2020-11-17 21:54:02
     UPDATE_TIME: NULL
      CHECK_TIME: NULL
 TABLE_COLLATION: utf8_general_ci
        CHECKSUM: NULL
  CREATE_OPTIONS: max_rows=1864135
   TABLE_COMMENT: 
MAX_INDEX_LENGTH: 0
       TEMPORARY: Y
...

```

### View Tables in Order of Size

 Returns a list of all tables in the database, ordered by size:

 
```
SELECT table_schema as `DB`, table_name AS `Table`, 
  ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` 
  FROM information_schema.TABLES 
  ORDER BY (data_length + index_length) DESC;

+--------------------+---------------------------------------+-----------+
| DB                 | Table                                 | Size (MB) |
+--------------------+---------------------------------------+-----------+
| wordpress          | wp_simple_history_contexts            |      7.05 |
| wordpress          | wp_posts                              |      6.59 |
| wordpress          | wp_simple_history                     |      3.05 |
| wordpress          | wp_comments                           |      2.73 |
| wordpress          | wp_commentmeta                        |      2.47 |
| wordpress          | wp_simple_login_log                   |      2.03 |
...

```

From [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/)

 
```
CREATE TEMPORARY TABLE foo.t1 (a int);

SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='foo' AND TEMPORARY='y'\G
*************************** 1. row ***************************
   TABLE_CATALOG: def
    TABLE_SCHEMA: foo
      TABLE_NAME: t1
      TABLE_TYPE: TEMPORARY
...
       TEMPORARY: Y

```

See Also
--------

 * [mysqlshow](../mysqlshow/index)
* [SHOW TABLE STATUS](../show-table-status/index)
* [Finding Tables Without Primary Keys](../getting-started-with-indexes/index#finding-tables-without-primary-keys)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-tables-table/>

Information Schema TABLE\_STATISTICS Table
==========================================

    The [Information Schema](../information_schema/index) `TABLE_STATISTICS` table shows statistics on table usage.

 This is part of the [User Statistics](../user-statistics/index) feature, which is not enabled by default.

 It contains the following columns:

 


| Field | Type | Notes |
| --- | --- | --- |
| `TABLE_SCHEMA` | `varchar(192)` | The schema (database) name. |
| `TABLE_NAME` | `varchar(192)` | The table name. |
| `ROWS_READ` | `int(21)` | The number of rows read from the table. |
| `ROWS_CHANGED` | `int(21)` | The number of rows changed in the table. |
| `ROWS_CHANGED_X_INDEXES` | `int(21)` | The number of rows changed in the table, multiplied by the number of indexes changed. |

 
#### Example

 
```
SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='user';
+--------------+------------+-----------+--------------+------------------------+
| TABLE_SCHEMA | TABLE_NAME | ROWS_READ | ROWS_CHANGED | ROWS_CHANGED_X_INDEXES |
+--------------+------------+-----------+--------------+------------------------+
| mysql        | user       |         5 |            2 |                      2 |
+--------------+------------+-----------+--------------+------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-table_statistics-table/>

Information Schema TABLESPACES Table
====================================

    The [Information Schema](../information_schema/index) `TABLESPACES` table contains information about active tablespaces..

 The table is a MariaDB and MySQL extension, and does not include information about InnoDB tablespaces.

 


| Column | Description |
| --- | --- |
| `TABLESPACE_NAME` |  |
| `ENGINE` |  |
| `TABLESPACE_TYPE` |  |
| `LOGFILE_GROUP_NAME` |  |
| `EXTENT_SIZE` |  |
| `AUTOEXTEND_SIZE` |  |
| `MAXIMUM_SIZE` |  |
| `NODEGROUP_ID` |  |
| `TABLESPACE_COMMENT` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-tablespaces-table/>

Information Schema USER\_STATISTICS Table
=========================================

    The [Information Schema](../information_schema/index) `USER_STATISTICS` table holds statistics about user activity. This is part of the [User Statistics](../user-statistics/index) feature, which is not enabled by default.

 You can use this table to find out such things as which user is causing the most load and which users are being abusive. You can also use this table to measure how close to capacity the server may be.

 It contains the following columns:

 


| Field | Type | Notes |
| --- | --- | --- |
| `USER` | `varchar(48)` | The username. The value `'#mysql_system_user#'` appears when there is no username (such as for the slave SQL thread). |
| `TOTAL_CONNECTIONS` | `int(21)` | The number of connections created for this user. |
| `CONCURRENT_CONNECTIONS` | `int(21)` | The number of concurrent connections for this user. |
| `CONNECTED_TIME` | `int(21)` | The cumulative number of seconds elapsed while there were connections from this user. |
| `BUSY_TIME` | `double` | The cumulative number of seconds there was activity on connections from this user. |
| `CPU_TIME` | `double` | The cumulative CPU time elapsed while servicing this user's connections. |
| `BYTES_RECEIVED` | `int(21)` | The number of bytes received from this user's connections. |
| `BYTES_SENT` | `int(21)` | The number of bytes sent to this user's connections. |
| `BINLOG_BYTES_WRITTEN` | `int(21)` | The number of bytes written to the [binary log](../binary-log/index) from this user's connections. |
| `ROWS_READ` | `int(21)` | The number of rows read by this user's connections. |
| `ROWS_SENT` | `int(21)` | The number of rows sent by this user's connections. |
| `ROWS_DELETED` | `int(21)` | The number of rows deleted by this user's connections. |
| `ROWS_INSERTED` | `int(21)` | The number of rows inserted by this user's connections. |
| `ROWS_UPDATED` | `int(21)` | The number of rows updated by this user's connections. |
| `SELECT_COMMANDS` | `int(21)` | The number of `[SELECT](../select/index)` commands executed from this user's connections. |
| `UPDATE_COMMANDS` | `int(21)` | The number of `[UPDATE](../update/index)` commands executed from this user's connections. |
| `OTHER_COMMANDS` | `int(21)` | The number of other commands executed from this user's connections. |
| `COMMIT_TRANSACTIONS` | `int(21)` | The number of `[COMMIT](../commit/index)` commands issued by this user's connections. |
| `ROLLBACK_TRANSACTIONS` | `int(21)` | The number of `[ROLLBACK](../rollback/index)` commands issued by this user's connections. |
| `DENIED_CONNECTIONS` | `int(21)` | The number of connections denied to this user. |
| `LOST_CONNECTIONS` | `int(21)` | The number of this user's connections that were terminated uncleanly. |
| `ACCESS_DENIED` | `int(21)` | The number of times this user's connections issued commands that were denied. |
| `EMPTY_QUERIES` | `int(21)` | The number of times this user's connections sent empty queries to the server. |
| `TOTAL_SSL_CONNECTIONS` | `int(21)` | The number of [TLS connections](../secure-connections/index) created for this user. (>= [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)) |
| `MAX_STATEMENT_TIME_EXCEEDED` | `int(21)` | The number of times a statement was aborted, because it was executed longer than its `[MAX\_STATEMENT\_TIME](../aborting-statements-that-take-longer-than-a-certain-time-to-execute/index)` threshold. (>= [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)) |

 
Example
-------

 
```
SELECT * FROM information_schema.USER_STATISTICS\G
*************************** 1. row ***************************
                  USER: root
     TOTAL_CONNECTIONS: 1
CONCURRENT_CONNECTIONS: 0
        CONNECTED_TIME: 297
             BUSY_TIME: 0.001725
              CPU_TIME: 0.001982
        BYTES_RECEIVED: 388
            BYTES_SENT: 2327
  BINLOG_BYTES_WRITTEN: 0
             ROWS_READ: 0
             ROWS_SENT: 12
          ROWS_DELETED: 0
         ROWS_INSERTED: 13
          ROWS_UPDATED: 0
       SELECT_COMMANDS: 4
       UPDATE_COMMANDS: 0
        OTHER_COMMANDS: 3
   COMMIT_TRANSACTIONS: 0
 ROLLBACK_TRANSACTIONS: 0
    DENIED_CONNECTIONS: 0
      LOST_CONNECTIONS: 0
         ACCESS_DENIED: 0
         EMPTY_QUERIES: 1

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-user_statistics-table/>

Information Schema USER\_PRIVILEGES Table
=========================================

    The [Information Schema](../information_schema/index) `USER_PRIVILEGES` table contains global user privilege information derived from the [mysql.global\_priv](../mysqlglobal_priv-table/index) grant table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `GRANTEE` | In the format `user_name@host_name`. |
| `TABLE_CATALOG` | Always `def`. |
| `PRIVILEGE_TYPE` | The specific privilege, for example `SELECT`, `INSERT`, `UPDATE` or `REFERENCES`. |
| `IS_GRANTABLE` | Whether the user has the [GRANT OPTION](../grant/index#the-grant-option-privilege) for this privilege. |

 
Similar information can be accessed with the [SHOW GRANTS](../show-grants/index) statement. See the [GRANT](../grant/index) article for more about privileges.

 This information is also stored in the [mysql.global\_priv](../mysqlglobal_priv-table/index) table, in the `mysql` system database.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-user_privileges-table/>

Information Schema USER\_VARIABLES Table
========================================

    Description
-----------

 The `USER_VARIABLES` table is created when the [user\_variables](../user-variables-plugin/index) plugin is enabled, and contains information about [user-defined variables](../user-defined-variables/index).

 The table contains the following columns: 

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | Variable name. |
| `VARIABLE_VALUE` | Variable value. |
| `VARIABLE_TYPE` | Variable [type](../data-types/index). |
| `CHARACTER_SET_NAME` | [Character set](../character-sets/index). |

 
User variables are reset and the table emptied with the [FLUSH USER\_VARIABLES](../flush/index) statement.

 Example
-------

 
```
SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| var           | 0              | INT           | utf8               |
| var2          | abc            | VARCHAR       | utf8               |
+---------------+----------------+---------------+--------------------+

```

See Also
--------

 * [User-defined variables](../user-defined-variables/index)
* [Performance Schema user\_variables\_by\_thread Table](../performance-schema-user_variables_by_thread-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-user_variables-table/>

Information Schema THREAD\_POOL\_GROUPS Table
=============================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [Information Schema](../information_schema/index) `THREAD_POOL_GROUPS` table was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
The table provides information about [thread pool](../thread-pool-in-mariadb/index) groups, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `GROUP_ID` | the thread group this row is showing data for |
| `CONNECTIONS` | the number of clients currently connected to this thread group |
| `THREADS` | total number of threads in this group (ACTIVE+STANDBY+LISTENER) |
| `ACTIVE_THREADS` | number of threads currently executing a query |
| `STANDBY_THREADS` | number of threads in reserve that do not currently execute anything |
| `QUEUE_LENGTH` | number of client requests waiting for execution |
| `HAS_LISTENER` | whether there is an active listener thread right now, always 1 if [thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener) is ON |
| `IS_STALLED` | whether there's currently an active worker thread in this group that has exceeded [thread\_pool\_stall\_limit time](../thread-pool-system-status-variables/index#thread_pool_stall_limit_time) |

 
Setting [thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener) will give each group its own dedicated listener, and the listener thread will not pick up work items. As a result, the actual queue size in the table will be more exact, since IO requests are immediately dequeued from poll, without delay.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-thread_pool_groups-table/>

Installing the CONNECT Storage Engine
=====================================

    The `CONNECT` storage engine enables MariaDB to access external local or remote data (MED). This is done by defining tables based on different data types, in particular files in various formats, data extracted from other DBMS or products (such as Excel or MongoDB) via ODBC or JDBC, or data retrieved from the environment (for example DIR, WMI, and MAC tables)

 This storage engine supports table partitioning, MariaDB virtual columns and permits defining special columns such as ROWID, FILEID, and SERVID.

 The storage engine must be installed before it can be used.

 Installing the Plugin's Package
-------------------------------

 The `CONNECT` storage engine's shared library is included in MariaDB packages as the `ha_connect.so` or `ha_connect.so` shared library on systems where it can be built.

 ### Installing on Linux

 The `CONNECT` storage engine is included in [binary tarballs](../installing-mariadb-binary-tarballs/index) on Linux.

 #### Installing with a Package Manager

 The `CONNECT` storage engine can also be installed via a package manager on Linux. In order to do so, your system needs to be configured to install from one of the MariaDB repositories.

 You can configure your package manager to install it from MariaDB Corporation's MariaDB Package Repository by using the [MariaDB Package Repository setup script](../mariadb-package-repository-setup-and-usage/index).

 You can also configure your package manager to install it from MariaDB Foundation's MariaDB Repository by using the [MariaDB Repository Configuration Tool](https://downloads.mariadb.org/mariadb/repositories/).

 ##### Installing with yum/dnf

 On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-connect-engine

```

##### Installing with apt-get

 On Debian, Ubuntu, and other similar Linux distributions, it is highly recommended to install the relevant [DEB package](../installing-mariadb-deb-files/index) from MariaDB's repository using `[apt-get](https://wiki.debian.org/apt-get)`. For example:

 
```
sudo apt-get install mariadb-plugin-connect

```

##### Installing with zypper

 On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-connect-engine

```

Installing the Plugin
---------------------

 Once the shared library is in place, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'ha_connect';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = ha_connect

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'ha_connect';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Installing Dependencies
-----------------------

 The `CONNECT` storage engine has some external dependencies. 

 ### Installing unixODBC

 The `CONNECT` storage engine requires an ODBC library. On Unix-like systems, that usually means installing [unixODBC](http://www.unixodbc.org/). On some systems, this is installed as the `unixODBC` package. For example:

 
```
sudo yum install unixODBC

```

On other systems, this is installed as the `libodbc1` package. For example:

 
```
sudo apt-get install libodbc1

```

If you do not have the ODBC library installed, then you may get an error about a missing library when you attempt to install the plugin. For example:

 
```
INSTALL SONAME 'ha_connect';
ERROR 1126 (HY000): Can't open shared library '/home/ian/MariaDB_Downloads/10.1.17/lib/plugin/ha_connect.so' 
  (errno: 2, libodbc.so.1: cannot open shared object file: No such file or directory)

```

See Also
--------

 * [PLUGIN OVERVIEW](../plugin-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-the-connect-storage-engine/>

Information Schema WSREP\_MEMBERSHIP Table
==========================================

    The `WSREP_STATUS` table makes [Galera](../galera/index) node cluster membership information available through the [Information Schema](../information-schema/index). The same information can be returned using the [SHOW WSREP\_MEMBERSHIP](../show-wsrep_membership/index) statement. Only users with the [SUPER](../grant/index#super) can access information from this table.

 The `WSREP_MEMBERSHIP` table is part of the [WSREP\_INFO plugin](../wsrep_info-plugin/index).

 Example
-------

 
```
SELECT * FROM information_schema.WSREP_MEMBERSHIP;
+-------+--------------------------------------+-------+-----------------+
| INDEX | UUID                                 | NAME  | ADDRESS         |
+-------+--------------------------------------+-------+-----------------+
|     0 | 46da96e3-6e9e-11e4-95a2-f609aa5444b3 | node1 | 10.0.2.15:16000 |
|     1 | 5f6bc72a-6e9e-11e4-84ed-57ec6780a3d3 | node2 | 10.0.2.15:16001 |
|     2 | 7473fd75-6e9e-11e4-91de-0b541ad91bd0 | node3 | 10.0.2.15:16002 |
+-------+--------------------------------------+-------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-wsrep_membership-table/>

Information Schema THREAD\_POOL\_STATS Table
============================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [Information Schema](../information_schema/index) `THREAD_POOL_STATS` table was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
The table provides performance counter information for the [thread pool](../thread-pool-in-mariadb/index), and contains the following columns:

 


| Column | Description |
| --- | --- |
| `GROUP_ID` | the thread group this row is showing data for |
| `THREAD_CREATIONS` | number of threads created for this group so far |
| `THREAD_CREATIONS_DUE_TO_STALL` | number of threads created due to detected stalls |
| `WAKES` |  |
| `WAKES_DUE_TO_STALL` |  |
| `THROTTLES` | how often thread creation was throttled, see also: [thread-creation-throttling](../thread-groups-in-the-unix-implementation-of-the-thread-pool/index#thread-creation-throttling) |
| `STALLS` | number of detected stalls |
| `POLLS_BY_LISTENER` |  |
| `POLLS_BY_WORKER` |  |
| `DEQUEUES_BY_LISTENER` |  |
| `DEQUEUES_BY_WORKER` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-thread_pool_stats-table/>

mysql\_plugin
=============

    `mysql_plugin` is a tool for enabling or disabling [plugins](../mariadb-plugins/index).

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-plugin` is a symlink to `mysql_plugin`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_plugin` is the symlink, and `mariadb-plugin` the binary name.

 
See [mariadb-plugin](../mariadb-plugin/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_plugin/>

Information Schema THREAD\_POOL\_QUEUES Table
=============================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [Information Schema](../information_schema/index) `THREAD_POOL_QUEUES` table was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
The table provides information about [thread pool](../thread-pool-in-mariadb/index) queues, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `GROUP_ID` | the thread group this row is showing data for |
| `POSITION` | position in the groups queue |
| `PRIORITY` | request priority, see [priority scheduling](../thread-pool-in-mariadb/index#configuring-priority-scheduling) |
| `CONNECTION_ID` | ID of the client connection that submitted the queued request |
| `QUEUEING_TIME_MICROSECONDS` | how long the request has already been waiting in the queue in microseconds |

 
Setting [thread\_poll\_exact\_stats](../thread-pool-system-status-variables/index#thread_pool_exact_stats) will provides better queueing time statistics by using a high precision timestamp, at a small performance cost, for the time when the connection was added to the queue. This timestamp helps calculate the queuing time shown in the table.

 Setting [thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener) will give each group its own dedicated listener, and the listener thread will not pick up work items. As a result, the queueing time in the table will be more exact, since IO requests are immediately dequeued from poll, without delay.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-thread_pool_queues-table/>

Information Schema WSREP\_STATUS Table
======================================

    The WSREP\_STATUS table makes [Galera](../galera/index) node cluster status information available through the [Information Schema](../information-schema/index). The same information can be returned using the [SHOW WSREP\_STATUS](../show-wsrep_status/index) statement. Only users with the [SUPER](../grant/index#super) privilege can access information from this table.

 The `WSREP_STATUS` table is part of the [WSREP\_INFO plugin](../wsrep_info-plugin/index).

 Example
-------

 
```
SELECT * FROM information_schema.WSREP_STATUS\G
*************************** 1. row ***************************
         NODE_INDEX: 0
        NODE_STATUS: Synced
     CLUSTER_STATUS: Primary
       CLUSTER_SIZE: 3
 CLUSTER_STATE_UUID: 00b0fbad-6e84-11e4-8a8b-376f19ce8ee7
CLUSTER_STATE_SEQNO: 2
    CLUSTER_CONF_ID: 3
                GAP: NO
   PROTOCOL_VERSION: 3

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-wsrep_status-table/>

Information Schema THREAD\_POOL\_WAITS Table
============================================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [Information Schema](../information_schema/index) `THREAD_POOL_WAITS` table was introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
The table provides wait counters for the [thread pool](../thread-pool-in-mariadb/index), and contains the following columns:

 


| Column | Description |
| --- | --- |
| `REASON` | name of the reason for waiting, e.g. ROW\_LOCK, DISKIO, NET ... |
| `COUNT` | how often a wait for this specific reason has happened so far |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-thread_pool_waits-table/>

SHOW PLUGINS SONAME
===================

    Syntax
------

 
```
SHOW PLUGINS SONAME { library | LIKE 'pattern' | WHERE expr };

```

Description
-----------

 `SHOW PLUGINS SONAME` displays information about compiled-in and all server plugins in the `[plugin\_dir](../server-system-variables/index#plugin_dir)` directory, including plugins that haven't been installed.

 Examples
--------

 
```
SHOW PLUGINS SONAME 'ha_example.so';
+----------+---------------+----------------+---------------+---------+
| Name     | Status        | Type           | Library       | License |
+----------+---------------+----------------+---------------+---------+
| EXAMPLE  | NOT INSTALLED | STORAGE ENGINE | ha_example.so | GPL     |
| UNUSABLE | NOT INSTALLED | DAEMON         | ha_example.so | GPL     |
+----------+---------------+----------------+---------------+---------+

```

There is also a corresponding `[information\_schema](../information_schema/index)` table, called `[ALL\_PLUGINS](../information-schema-all_plugins-table/index)`, which contains more complete information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-plugins-soname/>

CONNECT Create Table Options
============================

     Create Table statements for “CONNECT” tables are standard MariaDB create statements specifying `engine=CONNECT`. There are a few additional table and column options specific to CONNECT.

 ### Table Options

 


| Table Option | Type | Description |
| --- | --- | --- |
| `AVG_ROW_LENGTH` | Integer | Can be specified to help CONNECT estimate the size of a variable record table length. |
| `BLOCK_SIZE` | Integer | The number of rows each block of a [FIX](../connect-dos-and-fix-table-types/index), [BIN](../connect-bin-table-type/index), [DBF](../connect-dbf-table-type/index), or [VEC](../connect-vec-table-type/index) table contains. For an [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index) table this is the RowSet size option. For a [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index) table this is the fetch size. |
| `CATFUNC` | String | The catalog function used by a [catalog table](../connect-table-types-catalog-tables/index). |
| `COLIST` | String | The column list of [OCCUR](../connect-table-types-occur-table-type/index) tables or $project of [MONGO](../connect-mongo-table-type-accessing-collections-from-mongodb/index) tables. |
| `COMPRESS` | Number | `1` or `2` if the data file is g-zip compressed. Defaults to 0. Before CONNECT 1.05.0001, this was boolean, and true if the data file is compressed. |
| `CONNECTION` | String | Specifies the connection of an [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index) or [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) table. |
| `DATA_CHARSET` | String | The character set used in the external file or data source. |
| `DBNAME` | String | The target database for [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [catalog](../connect-table-types-catalog-tables/index), and [PROXY](../connect-table-types-proxy-table-type/index) based tables. The database concept is sometimes known as a *schema*. |
| `ENGINE` | String | Must be specfied as `CONNECT`. |
| `ENDING` | Integer | End of line length. Defaults to `1` for Unix/Linux and `2` for Windows. |
| `FILE_NAME` | String | The file (path) name for all table types based on files. Can be absolute or relative to the current data directory. If not specified, this is an [Inward table](../inward-and-outward-tables/index#inward-tables) and a default value is used. |
| `FILTER` | String | To filter an external table. Currently MONGO tables only. |
| `HEADER` | Integer | Applies to [CSV](../connect-csv-and-fmt-table-types/index), [VEC](../connect-vec-table-type/index), and HTML files. Its meaning depends on the table type. |
| `HTTP` | String | The HTTP of the client of REST queries. From [Connect 1.06.0010](../connect/index). |
| `HUGE` | Boolean | To specify that a table file can be larger than 2GB. For a [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) table, prevents the result set from being stored in memory. |
| `LRECL` | Integer | The file record size (often calculated by default). |
| `MAPPED` | Boolean | Specifies whether *file mapping* is used to handle the table file. |
| `MODULE` | String | The (path) name of the DLL or shared lib implementing the access of a non-standard ([OEM](../connect-table-types-oem/index)) table type. |
| `MULTIPLE` | Integer | Used to specify multiple file tables. |
| `OPTION_LIST` | String | Used to specify all other options not yet directly defined. |
| `QCHAR` | String | Specifies the character used for quoting some fields of a [CSV](../connect-csv-and-fmt-table-types/index) table or the identifiers of an [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index)/[JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index) tables. |
| `QUOTED` | Integer | The level of quoting used in [CSV](../connect-csv-and-fmt-table-types/index) table files. |
| `READONLY` | Boolean | True if the data file must not be modified or erased. |
| `SEP_CHAR` | String | Specifies the field separator character of a [CSV](../connect-csv-and-fmt-table-types/index) or [XCOL](../connect-table-types-xcol-table-type/index) table. Also, used to specify the Jpath separator for [JSON tables](../connect-json-table-type/index). |
| `SEPINDEX` | Boolean | When true, indexes are saved in separate files. |
| `SPLIT` | Boolean | True for a [VEC](../connect-vec-table-type/index) table when all columns are in separate files. |
| `SRCDEF` | String | The source definition of a table retrieved via [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index) or the MySQL API or used by a [PIVOT](../connect-table-types-pivot-table-type/index) table. |
| `SUBTYPE` | String | The subtype of an [OEM](../connect-table-types-oem/index) table type. |
| `TABLE_LIST` | String | The comma separated list of TBL table sub-tables. |
| `TABLE_TYPE` | String | The external table [type](../connect-table-types-overview/index): [DOS](../connect-dos-and-fix-table-types/index), [FIX](../connect-dos-and-fix-table-types/index), [BIN](../connect-bin-table-type/index), [CSV](../connect-csv-and-fmt-table-types/index), [FMT](../connect-csv-and-fmt-table-types/index), [XML](../connect-xml-table-type/index), [JSON](../connect-json-table-type/index), [INI](../connect-ini-table-type/index), [DBF](../connect-dbf-table-type/index), [VEC](../connect-vec-table-type/index), [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [TBL](../connect-table-types-tbl-table-type-table-list/index), [PROXY](../connect-table-types-proxy-table-type/index), [XCOL](../connect-table-types-xcol-table-type/index), [OCCUR](../connect-table-types-occur-table-type/index), [PIVOT](../connect-table-types-pivot-table-type/index), [ZIP](../connect-zipped-file-tables/index), [VIR](../connect-table-types-vir/index), [DIR](../connect-table-types-special-virtual-tables/index#dir-type), [WMI](../connect-table-types-special-virtual-tables/index#windows-management-instrumentation-table-type-wmi), [MAC](../connect-table-types-special-virtual-tables/index#mac-address-table-type-mac), and [OEM](../connect-table-types-oem/index). Defaults to [DOS](../connect-dos-and-fix-table-types/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), or [PROXY](../connect-table-types-proxy-table-type/index) depending on what options are used. |
| `TABNAME` | String | The target table or node for [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [PROXY](../connect-table-types-proxy-table-type/index), or [catalog tables](../connect-table-types-catalog-tables/index); or the top node name for [XML](../connect-xml-table-type/index) tables. |
| `URI` | String | The URI of a REST request.. From [Connect 1.06.0010](../connect/index). |
| `XFILE_NAME` | String | The file (path) base name for table index files. Can be absolute or relative to the data directory. Defaults to the file name. |
| `ZIPPED` | Boolean | True if the table file(s) is/are zipped in one or several zip files. |

 
All integers in the above table are unsigned big integers. 

 Because CONNECT handles many table types; many table type specific options are not in the above list and must be entered using the `OPTION_LIST` option. The syntax to use is:

 
```
... option_list='opname1=opvalue1,opname2=opvalue2...'

```

Be aware that until Connect 1.5.5, no blanks should be inserted before or after the '`=`' and '`,`' characters. The option name is all that is between the start of the string or the last '`,`' character and the next '`=`' character, and the option value is all that is between this '`=`' character and the next '`,`' or end of string. For instance:

 
```
option_list='name=TABLE,coltype=HTML,attribute=border=1;cellpadding=5,headattr=bgcolor=yellow';

```

This defines four options, '`name`', '`coltype`', '`attribute`', and '`headattr`'; with values '`TABLE`', '`HTML`', '`border=1;cellpadding=5`', and '`bgcolor=yellow`', respectively. The only restriction is that values cannot contain commas, but they can contain equal signs.

 ### Column Options

 


| Column Option | Type | Description |
| --- | --- | --- |
| `DATE_FORMAT` | String | The format indicating how a date is stored in the file. |
| `DISTRIB` | Enum | “scattered”, “clustered”, “sorted” (ascending). |
| `FIELD_FORMAT` | String | The column format for some table types. |
| `FIELD_LENGTH` | Integer | Set the internal field length for DATE columns. |
| `FLAG` | Integer | An integer value whose meaning depends on the table type. |
| `JPATH` | String | The Json path of JSON table columns. |
| `MAX_DIST` | Integer | Maximum number of distinct values in this column. |
| `SPECIAL` | String | The name of the SPECIAL column that set this column value. |
| `XPATH` | String | The XML path of XML table columns. |

 
* The `MAX_DIST` and `DISTRIB` column options are used for block indexing.
* All integers in the above table are unsigned big integers.
* JPATH and XPATH were added to make CREATE TABLE statements more readable, but they do the same thing as FIELD\_FORMAT and any of them can be used with the same result.

 ### Index Options

 


| Index Option | Type | Description |
| --- | --- | --- |
| DYNAM | Boolean | Set the index as “dynamic”. |
| MAPPED | Boolean | Use index file mapping. |

 
**Note 1:** Creating a CONNECT table based on file does not erase or create the file if the file name is specified in the CREATE TABLE statement ([“outward”](../inward-and-outward-tables/index#outward-tables) table). If the file does not exist, it will be populated by subsequent INSERT or LOAD commands or by the “AS select statement” of the [CREATE TABLE](../create-table/index) command. Unlike the CSV engine, CONNECT easily permits the creation of tables based on already existing files, for instance files made by other applications. However, if the file name is not specified, a file with a name defaulting to `tablename.tabletype` will be created in the data directory ([“inward”](../inward-and-outward-tables/index#inward-tables) table).

 **Note 2:** Dropping a CONNECT table is done with a standard DROP statement. For [outward tables](../inward-and-outward-tables/index#inward-tables), this drops only the CONNECT table definition but does not erase the corresponding data file and index files. Use `DELETE` or `TRUNCATE` to do so. This is contrary to data and index files of [inward tables](../inward-and-outward-tables/index#inward-tables) are erased on DROP like for other MariaDB engines.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-create-table-options/>

Using the S3 Storage Engine
===========================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

  The [S3 storage engine](../s3-storage-engine/index) is read only and allows one to archive MariaDB tables in Amazon S3, or any third-party public or private cloud that implements S3 API (of which there are many), but still have them accessible for reading in MariaDB.

 Installing the Plugin
---------------------

 As of [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), the S3 storage engine is currently [gamma maturity](../release-criteria/index), so the following step can be omitted. 

 On earlier releases, when it was [alpha maturity](../release-criteria/index), it will not load by default on a stable release of the server due to the default value of the [plugin\_maturity](../server-system-variables/index#plugin_maturity) variable. Set to `alpha` (or below) in your config file to permit installation of the plugin:

 
```
[mysqld]
plugin-maturity = alpha

```

and restart the server.

 Now [install the plugin library](../plugin-overview/index#installing-a-plugin), for example:

 
```
INSTALL SONAME 'ha_s3';

```

If the library is not available, for example: 

 
```
INSTALL SONAME 'ha_s3';
ERROR 1126 (HY000): Can't open shared library '/var/lib/mysql/lib64/mysql/plugin/ha_s3.so' 
  (errno: 13, cannot open shared object file: No such file or directory)

```

you may need to install a separate package for the S3 storage engine, for example: 

 
```
shell> yum install MariaDB-s3-engine

```

Moving Data to S3
-----------------

 To move data from an existing table to S3, one can run:

 
```
ALTER TABLE old_table ENGINE=S3 COMPRESSION_ALGORITHM=zlib

```

To get data back to a 'normal' table one can do:

 
```
ALTER TABLE s3_table ENGINE=INNODB

```

New Options for [ALTER TABLE](../alter-table/index)
---------------------------------------------------

 * **`S3_BLOCK_SIZE` :** Set to 4M as default. This is the block size for all index and data pages stored in S3.
* **`COMPRESSION_ALGORITHM` :** Set to 'none' as default. Which compression algorithm to use for block stored in S3. Options are: `none` or `zlib`.

 [ALTER TABLE](../alter-table/index) can be used on S3 tables as normal to add columns or change column definitions.

 mysqld Startup Options for S3
-----------------------------

 To be able to use S3 for storage one **\*must**\* define how to access S3 and where data are stored in S3:

 * **[s3\_access\_key](../s3-storage-engine-system-variables/index#s3_access_key):** The AWS access key to access your data
* **[s3\_secret\_key](../s3-storage-engine-system-variables/index#s3_secret_key):** The AWS secret key to access your data
* **[s3\_bucket](../s3-storage-engine-system-variables/index#s3_bucket):**  The AWS bucket where your data should be stored. All MariaDB table data is stored in this bucket.
* **[s3\_region](../s3-storage-engine-system-variables/index#s3_region):**  The AWS region where your data should be stored.

 If you are using an S3 service that is using HTTP to connect (like <https://min.io/>) you also need the set the following variables:

 * **[s3\_port](../s3-storage-engine-system-variables/index#s3_port):** Port number to connect to (0 means use default)
* **[s3\_use\_http](../s3-storage-engine-system-variables/index#s3_use_http):** If true, force use of HTTP protocol

 If you are going to use a primary-replica setup, you should look at the following variables:

 * **[s3\_replicate\_alter\_as\_create\_select](../s3-storage-engine-system-variables/index#s3-replicate-alter-as-create-select):**  When converting an S3 table to local table, log all rows in binary log. Defaults to `TRUE`. This allows the replica to replicate `CREATE TABLE .. SELECT FROM s3_table` even it the replica doesn't have access to the original `s3_table`.
* **[s3\_slave\_ignore\_updates](../s3-storage-engine-system-variables/index#s3-slave-ignore-updates):**  Should be set if primary and replica share the same S3 instance. This tells the replica that it can ignore any updates to the S3 tables as they are already applied on the primary. Defaults to `FALSE`.

 The above defaults assume that the primary and replica don't share the same S3 instance.

 Other, less critical options, are:

 * **[s3\_host\_name](../s3-storage-engine-system-variables/index#s3_host_name):** Hostname for the S3 service. "s3.amazonaws.com", Amazon S3 service, by default.
* **[s3\_protocol\_version](../s3-storage-engine-system-variables/index#s3_protocol_version):** Protocol used to communication with S3. One of "Auto", "Amazon" or "Original" where "Auto" is the default. If you get errors like "8 Access Denied" when you are connecting to another service provider, then try to change this option. The reason for this variable is that Amazon has changed some parts of the S3 protocol since they originally introduced it but other service providers are still using the original protocol.
* **[s3\_block\_size](../s3-storage-engine-system-variables/index#s3_block_size):** Set to 4M as default. This is the default block size for a table, if not specified in [CREATE TABLE](../create-table/index).
* **[s3\_pagecache\_buffer\_size](../s3-storage-engine-system-variables/index#s3_pagecache_buffer_size):** Default 128M. The size of the buffer used for data and index blocks for S3 tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford.

 Last some options you probably don't have to ever touch:

 * **[s3\_pagecache\_age\_threshold](../s3-storage-engine-system-variables/index#s3_pagecache_age_threshold) :**  Default 300: 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.
* **[s3\_pagecache\_division\_limit](../s3-storage-engine-system-variables/index#s3_pagecache_division_limit):**  Default 100. The minimum percentage of warm blocks in key cache.
* **[s3\_pagecache\_file\_hash\_size](../s3-storage-engine-system-variables/index#s3_pagecache_file_hash_size):**  Default 512. Number of hash buckets for open files. If you have a lot of S3 files open you should increase this for faster flush of changes. A good value is probably 1/10 of number of possible open S3 files.
* **[s3\_debug](../s3-storage-engine-system-variables/index#s3_debug):**  Default 0. Generates a trace file from libmarias3 on stderr (mysqld.err) for debugging the S3 protocol.

 Typical my.cnf Entry for connecting to Amazon S3 service
--------------------------------------------------------

 
```
[mariadb]
s3=ON
s3-bucket=mariadb
s3-access-key=xxxx
s3-secret-key=xxx
s3-region=eu-north-1
s3-host-name=s3.amazonaws.com
# The following is useful if you want to use minio as a S3 server. (https://min.io/)
#s3-port=9000
#s3-use-http=ON

# Primary and replica share same S3 tables.
s3-slave-ignore-updates=1

[aria_s3_copy]
s3-bucket=mariadb
s3-access-key=xxxx
s3-secret-key=xxx
s3-region=eu-north-1
s3-host-name=s3.amazonaws.com
# The following is useful if you want to use minio as a S3 server. (https://min.io/)
#s3-port=9000
#s3-use-http=ON

```

Typical my.cnf entry for connecting to a [minio](https://min.io) S3 server
--------------------------------------------------------------------------

 
```
[mariadb]
s3=ON
s3-host-name="127.0.0.1"
s3-bucket=storage-engine
s3-access-key=minio
s3-secret-key=minioadmin
s3-port=9000
s3-use-http=ON

[aria_s3_copy]
s3=ON
s3-host-name="127.0.0.1"
s3-bucket=storage-engine
s3-access-key=minio
s3-secret-key=minioadmin
s3-port=9000
s3-use-http=ON

```

Typical Usage Case for S3 Tables
--------------------------------

 The typical use case would be that there exists tables that after some time would become fairly inactive, but are still important so that they can not be removed. In that case, an option is to move such a table to an archiving service, which is accessible through an S3 API.

 Notice that S3 means the Cloud Object Storage API defined by Amazon AWS. Often the whole of Amazon’s Cloud Object Storage is referred to as S3. In the context of the S3 archive storage engine, it refers to the API itself that defines how to store objects in a cloud service, being it Amazon’s or someone else’s. OpenStack for example provides an S3 API for storing objects.

 The main benefit of storing things in an S3 compatible storage is that the cost of storage is much cheaper than many other alternatives. Many S3 implementations also provide reliable long-term storage.

 Operations Allowed on S3 Tables
-------------------------------

 * [ALTER TABLE](../alter-table/index) S3 supports all types, keys and other options that are supported by the [Aria](../aria-storage-engine/index) engine. One can also perform [ALTER TABLE](../alter-table/index) on an S3 table to add or modify columns etc.
* [DROP TABLE](../drop-table/index)
* [SELECT](../select/index) Any SELECT operations you can perform on a normal table should work with an S3 table.
* [SHOW TABLES](../show-tables/index) will show all tables that exist in the current defined S3 location.
* S3 tables can be part of [partitions](../partitions-files/index). See Discovery below.

 Discovery
---------

 The S3 storage engine supports full [MariaDB discovery](../table-discovery/index). This means that if you have the S3 storage engine enabled and properly configured, the table stored in S3 will automatically be discovered when it's accessed with [SHOW TABLES](../show-tables/index), [SELECT](../select/index) or any other operation that tries to access it. In the case of SELECT, the .frm file from S3 will be copied to the local storage to speed up future accesses.

 When an S3 table is opened for the first time (it's not in the table cache) and there is a local .frm file, the S3 engine will check if it's still relevant, and if not, update or delete the .frm file.

 This means that if the table definition changes on S3 and it's in the local cache, one has to execute `[FLUSH TABLES](../flush/index)` to get MariaDB to notice the change and update the .frm file.

 If partitioning S3 tables are used, the partition definitions will also be stored on S3 storage and will be discovered by other servers.

 Discovery of S3 tables is not done for tables in the [mysql databases](../the-mysql-database-tables/index) to make mysqld boot faster and more securely.

 Replication
-----------

 S3 works with [replication](../replication-overview/index). One can use replication in two different scenarios:

 * The primary and replica share the same S3 storage. In this case the primary will make all changes to the S3 data and the replica will ignore any changes in the replication stream to S3 data . This scenario is achieved by setting [s3\_slave\_ignore\_updates](../s3-storage-engine-system-variables/index#s3-slave-ignore-updates) to 1.
* The primary and replica don't share the same S3 storage or the replica uses another storage engine for the S3 tables. This scenario is achieved by setting [s3\_slave\_ignore\_updates](../s3-storage-engine-system-variables/index#s3-slave-ignore-updates) to 0.

 aria\_s3\_copy
--------------

 [aria\_s3\_copy](../aria_s3_copy/index) is an external tool that one can use to copy [Aria](../aria-storage-engine/index) tables to and from S3. Use `aria_s3_copy --help` to get the options of how to use it.

 mariadb-dump
------------

 * [mariadb-dump](../mariadb-dump/index) will by default ignore S3 tables. If `mariadb-dump` is run with the `--copy-s3-tables` option, the resulting file will contain a CREATE statement for a similar [Aria](../aria-storage-engine/index) table, followed by the table data and ending with an `ALTER TABLE xxx ENGINE=S3`.

 ANALYZE TABLE
-------------

 As of [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [ANALYZE TABLE](../analyze-table/index) is supported for S3 tables. As the S3 tables are read-only, a normal `ANALYZE TABLE` will not do anything. However using `ANALYZE TABLE table_name PERSISTENT FOR...` will now work.

 CHECK TABLE
-----------

 As of [MariaDB 10.5.14](https://mariadb.com/kb/en/mariadb-10514-release-notes/), [CHECK TABLE](../check-table/index) will work. As S3 tables are read only it is very unlikely that they can become corrupted. The only known way an S3 table could be corrupted if either the original table copied to S3 was corrupted or the process of copying the original table to S3 was somehow interrupted.

 Current Limitations
-------------------

 * [mysql-test-run](../mysql-test-run/index) doesn't by default test the S3 engine as we can't embed AWS keys into mysql-test-run.
* Replicas should not access S3 tables while they are ALTERed! This is because there is no locking implemented to S3 between servers. However, after a table (either the original S3 table or the partitioned S3 table) is changed on the primary, the replica will notice this on the next access and update its local definition.

 ### Limitations in [ALTER .. PARTITION](../alter-table/index)

 All [ALTER PARTITION](../alter-table/index) operations are supported on S3 partitioning tables except:

 * REBUILD PARTITION
* TRUNCATE PARTITION
* REORGANIZE PARTITION

 Performance Considerations
--------------------------

 Depending on your connection speed to your S3 provider, there can be some notable slowdowns in some operations.

 ### Discovery

 As S3 is supporting discovery (automatically making tables available that are in S3) this can cause some small performance problems if the S3 engine is enabled. Partitioning S3 tables also support discovery.

 * CREATE TABLE is a bit slower as the S3 engine has to check if the to-be-created table is already S3.
* Queries on information\_schema tables are slower as S3 has to check if there is new tables in S3.
* DROP of non existing tables are slower as S3 has to check if the table is in S3.

 There are no performance degradation's when accessing existing tables on the server. Accessing the S3 table the first time will copy the .frm file from S3 to the local disk, speeding up future accesses to the table.

 ### Caching

 * Accessing a table on S3 can take some time , especially if you are using big packets ([s3\_block\_size](../s3-storage-engine-system-variables/index#s3_block_size)). However the second access to the same data should be fast as it's then cached in the S3 page cache.

 ### Things to Try to Increase Performance

 If you have performance problems with the S3 engine, here are some things you can try:

 * Decreasing [s3\_block\_size](../s3-storage-engine-system-variables/index#s3_block_size). This can be done both globally and per table.
* Use COMPRESSION\_ALGORITHM=zlib when creating the table. This will decrease the amount of data transferred from S3 to the local cache.
* Increasing the size of the s3 page cache: [s3\_pagecache\_buffer\_size](../s3-storage-engine-system-variables/index#s3_pagecache_buffer_size)

 Try also to execute the query twice to check if the problem is that the data was not properly cached. When data is cached locally the performance should be excellent.

 Future Development Ideas
------------------------

 * Store aws keys and region in the mysql.servers table (as [Spider](../spider/index) and [FederatedX](../federatedx/index)). This will allow one to have different tables on different S3 servers.
* Store s3 bucket, access\_key and secret key in a cache to better be able to better to reuse connections. This would save some memory and make some S3 accesses a bit faster as we could reuse old connections.

 Troubleshooting S3 on SELinux
-----------------------------

 If you get errors such as:

 
```
ERROR 3 (HY000): Got error from put_object(bubu/produkt/frm): 5 Couldn't connect to server

```

one reason could be that your system doesn't allow MariaDB to connect to ports other than 3306. To procedure to enable other ports is the following:

 Search for the ports allowed for MariaDB:

 
```
$ sudo semanage port -l | grep mysqd_port_t
mysqld_port_t                tcp   1186, 3306, 63132-63164

```

Say you want to allow MariaDB to connect to port 32768:

 
```
$ sudo semanage port -a -t mysqld_port_t -p tcp 32768

```

You can verify that the new port, 32768, is now allowed for MariaDB:

 
```
$ sudo semanage port -l | grep mysqd_port_t
mysqld_port_t                tcp   32768,1186, 3306, 63132-63164

```

See Also
--------

 * [S3 storage engine internals](../s3-storage-engine-internals/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-the-s3-storage-engine/>

Introduction to the CONNECT Engine
==================================

    CONNECT is not just a new “YASE” (Yet another Storage Engine) that provides another way to store data with additional features. It brings a new dimension to MariaDB, already one of the best products to deal with traditional database transactional applications, further into the world of business intelligence and data analysis, including NoSQL facilities. Indeed, BI is the set of techniques and tools for the transformation of raw data into meaningful and useful information. And where is this data?

 
 "It's amazing in an age where relational databases reign supreme when it comes to managing data that so much information still exists outside RDBMS engines in the form of flat files and other such constructs. In most enterprises, data is passed back and forth between disparate systems in a fashion and speed that would rival the busiest expressways in the world, with much of this data existing in common, delimited files. Target systems intercept these source files and then typically proceed to load them via ETL (extract, transform, load) processes into databases that then utilize the information for business intelligence, transactional functions, or other standard operations. ETL tasks and data movement jobs can consume quite a bit of time and resources, especially if large volumes of data are present that require loading into a database. This being the case, many DBAs welcome alternative means of accessing and managing data that exists in file format."

  

- Robin Schumacher[[1](#_note-0)]

   What he describes is known as MED (Management of External Data) enabling the handling of data not stored in a DBMS database as if it were stored in tables. An ISO standard exists that describes one way to implement and use MED in SQL by defining foreign tables for which an external FDW (Foreign Data Wrapper) has been developed in C.

 However, since this was written, a new source of data was developed as the “cloud”. Data are existing worldwide and, in particular, can be obtained in JSON or XML format in answer to REST queries. From [Connect 1.06.0010](../connect/index), it is possible to create JSON, XML or CSV tables based on data retrieved from such REST queries.

 MED as described above is a rather complex way to achieve this goal and MariaDB does not support the ISO SQL/MED standard. But, to cover the need, possibly in transactional but mostly in decision support applications, the CONNECT storage engine supports MED in a much simpler way.

 The main features of CONNECT are:

 1. No need for additional SQL language extensions.
2. Embedded wrappers for many external data types (files, data sources, virtual).
3. NoSQL query facilities for [JSON](../connect-json-table-type/index), [XML](../connect-xml-table-type/index), HTML files and using JSON UDFs.
4. NoSQL data obtained from REST queries (requires cpprestsdk).
5. NoSQL new data type [MONGO](../connect-mongo-table-type/index) accessing MongoDB collections as relational tables.
6. Read/Write access to external files of most commonly used formats.
7. Direct access to most external data sources via ODBC, JDBC and MySQL or MongoDB API.
8. Only used columns are retrieved from external scan.
9. Push-down WHERE clauses when appropriate.
10. Support of special and virtual columns.
11. Parallel execution of multi-table tables (currently unavailable).
12. Supports partitioning by sub-files or by sub-tables (enabling table sharding).
13. Support of MRR for SELECT, UPDATE and DELETE.
14. Provides remote, block, dynamic and virtual indexing.
15. Can execute complex queries on remote servers.
16. Provides an API that allows writing additional FDW in C++.

 With CONNECT, MariaDB has one of the most advanced implementations of MED and NoSQL, without the need for complex additions to the SQL syntax (foreign tables are "normal" tables using the CONNECT engine).

 Giving MariaDB easy and natural access to external data enables the use of all of its powerful functions and SQL-handling abilities for developing business intelligence applications.

 With version 1.07 of CONNECT, retrieving data from REST queries is available in all binary distributed version of MariaDB, and, from 1.07.002, CONNECT allows workspaces greater than 4GB.

 

---

 1. [↑](#_ref-0) Robin Schumacher is Vice President Products at DataStax and former Director of Product Management at MySQL. He has over 13 years of database experience in DB2, MySQL, Oracle, SQL Server and other database engines.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/introduction-to-the-connect-engine/>

Testing the Connections to S3
=============================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

   If you can't get the S3 storage engine to work, here are some steps to help verify where the problem could be.

 S3 Connection Variables
-----------------------

 In most cases the problem is to correctly set the S3 connection variables.

 The variables are:

 * **[s3\_access\_key](../s3-storage-engine-system-variables/index#s3_access_key):** The AWS access key to access your data
* **[s3\_secret\_key](../s3-storage-engine-system-variables/index#s3_secret_key):** The AWS secret key to access your data
* **[s3\_bucket](../s3-storage-engine-system-variables/index#s3_bucket):**  The AWS bucket where your data should be stored. All MariaDB table data is stored in this bucket.
* **[s3\_region](../s3-storage-engine-system-variables/index#s3_region):**  The AWS region where your data should be stored.
* **[s3\_host\_name](../s3-storage-engine-system-variables/index#s3_host_name):** Hostname for the S3 service.
* **[s3\_protocol\_version](../s3-storage-engine-system-variables/index#s3_protocol_version):** Protocol used to communicate with S3. One of "Amazon" or "Original"

 There are several ways to ensure you get them right:

 ### Using aria\_s3\_copy to Test the Connection

 [aria\_s3\_copy](../aria_s3_copy/index) is a tool that allows you to copy [aria](../aria/index) tables to and from S3. It's useful for testing the connection as it allows you to specify all s3 options on the command line.

 Execute the following sql commands to create a trivial sql table:

 
```
use test;
create table s3_test (a int) engine=aria row_format=page transactional=0;
insert into s3_test values (1),(2);
flush tables s3_test;

```

Now you can use the [aria\_s3\_copy](../aria_s3_copy/index) tool to copy this to S3 from your shell/the command line:

 
```
shell> cd mariadb-data-directory/test
shell> aria_s3_copy --op=to --verbose --force --**other*options* s3_test.frm

Copying frm file s3_test.frm
Copying aria table: test.s3_test to s3
Creating aria table information test/s3_test/aria
Copying index information test/s3_test/index
Copying data information test/s3_test/data

```

As you can see from the above, [aria\_s3\_copy](../aria_s3_copy/index) is using the current directory as the database name.

 You can also set the [aria\_s3\_copy](../aria_s3_copy/index) options in your my.cnf file to avoid some typing.

 ### Using mysql-test-run to Test the Connection and the S3 Storage Engine

 One can use the [MariaDB test system](../mysqltest/index) to run all default S3 test against your S3 storage.

 To do that you have to locate the `mysql-test` directory in your system and `cd` to it.

 The config file for the S3 test system can be found at `suite/s3/my.cnf`. To enable testing you have to edit this file and add the s3 connection options to the end of the file. It should look something like this after editing:

 
```
!include include/default_mysqld.cnf
!include include/default_client.cnf

[mysqld.1]
s3=ON
#s3-host-name=s3.amazonaws.com
#s3-protocol-version=Amazon
s3-bucket=MariaDB
s3-access-key=
s3-secret-key=
s3-region=

```

You must give values for `s3-access-key`, `s3-secret-key` and `s3-region` that reflects your S3 provider. The `s3-bucket` name is defined by your administrator.

 If you are not using Amazon Web Services as your S3 provider you must also specify `s3-hostname` and possibly change `s3-protocol-version` to "Original".

 Now you can test the configuration:

 
```
shell> cd **mysql-test** directory
shell> ./mysql-test-run --suite=s3
...
s3.no_s3                                 [ pass ]      5
s3.alter                                 [ pass ]  11073
s3.arguments                             [ pass ]   2667
s3.basic                                 [ pass ]   2757
s3.discovery                             [ pass ]   7851
s3.select                                [ pass ]   1325
s3.unsupported                           [ pass ]    363

```

Note that there may be more tests in your output as we are constantly adding more tests to S3 when needed.

 What to Do Next
---------------

 When you got the connection to work, you should add the options to your global my.cnf file. Now you can start testing S3 from your [mysql command client](../mysql-command-line-client/index) by converting some existing table to S3 with [ALTER TABLE ... ENGINE=S3](../using-the-s3-storage-engine/index).

 See Also
--------

 * [Using the S3 Storage Engine](../using-the-s3-storage-engine/index)
* [Using MinIO with mysql-test-run to test the S3 storage engine](../installing-minio-for-usage-with-mysql-test-run/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/testing-the-connections-to-s3/>

CONNECT Table Types Overview
============================

    CONNECT can handle very many table formats; it is indeed one of its main features. The Type option specifies the type and format of the table. The Type options available values and their descriptions are listed in the following table:

 


| Type | Description |
| --- | --- |
| [BIN](../connect-bin-table-type/index) | Binary file with numeric values in platform representation, also with columns at fixed offset within records and fixed record length. |
| BSON | (Temporary) JSON table handled by the new JSON handling. |
| [CSV](../connect-csv-and-fmt-table-types/index)\*$ | "Comma Separated Values" file in which each variable length record contains column values separated by a specific character (defaulting to the comma) |
| [DBF](../connect-dbf-table-type/index)\* | File having the dBASE format. |
| [DOS](../connect-dos-and-fix-table-types/index) | The table is contained in one or several files. The file format can be refined by some other options of the command or more often using a specific type as many of those described below. Otherwise, it is a flat text file where columns are placed at a fixed offset within each record, the last column being of variable length. |
| [DIR](../connect-table-types-special-virtual-tables/index#dir-type) | Virtual table that returns a file list like the Unix `ls` or DOS `dir` command. |
| [FIX](../connect-dos-and-fix-table-types/index) | Text file arranged like DOS but with fixed length records. |
| [FMT](../connect-csv-and-fmt-table-types/index) | File in which each record contains the column values in a non-standard format (the same for each record) This format is specified in the column definition. |
| [INI](../connect-ini-table-type/index) | File having the format of the initialization or configuration files used by many applications. |
| [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index)\* | Table accessed via a JDBC driver. |
| [JSON](../connect-json-table-type/index)\*$ | File having the JSON format. |
| [MAC](../connect-table-types-special-virtual-tables/index#mac-address-table-type-mac) | Virtual table returning information about the machine and network cards (Windows only). |
| [MONGO](../connect-mongo-table-type/index)\* | Table accessed via the MongoDB C Driver API. |
| [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index)\* | Table accessed using the MySQL API like the FEDERATED engine. |
| [OCCUR](../connect-table-types-occur-table-type/index)\* | A table based on another table existing on the current server, several columns of the object table containing values that can be grouped in only one column. |
| [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index)\* | Table extracted from an application accessible via ODBC or unixODBC. For example from another DBMS or from an Excel spreadsheet. |
| [OEM](../connect-table-types-oem-type-table-type-implemented-in-an-external-lib/index)\* | Table of any other formats not directly handled by CONNECT but whose access is implemented by an external FDW (foreign data wrapper) written in C++ (as a DLL or Shared Library). |
| [PIVOT](../connect-table-types-pivot-table-type/index)\* | Used to "pivot" the display of an existing table or view. |
| [PROXY](../connect-table-types-proxy-table-type/index)\* | A table based on another table existing on the current server. |
| [TBL](../connect-table-types-tbl-table-type-table-list/index)\* | Accessing a collection of tables as one table (like the MERGE engine does for MyIsam tables) |
| [VEC](../connect-vec-table-type/index) | Binary file organized in vectors, in which column values are grouped consecutively, either split in separate files or in a unique file. |
| [VIR\*](../connect-table-types-vir/index) | Virtual table containing only special and virtual columns. |
| [WMI](../connect-table-types-special-virtual-tables/index#windows-management-instrumentation-table-type-wmi)\* | Windows Management Instrumentation table displaying information coming from a WMI provider. This type enables to get in tabular format all sorts of information about the machine hardware and operating system (Windows only). |
| [XCOL](../connect-table-types-xcol-table-type/index)\* | A table based on another table existing on the current server with one of its columns containing comma separated values. |
| [XML](../connect-xml-table-type/index)\*$ | File having the XML or HTML format. |
| [ZIP](../connect-zipped-file-tables/index) | Table giving information about the contents of a zip file. |

 
Catalog Tables
--------------

 For all table types marked with a '\*' in the table above, CONNECT is able to analyze the data source to retrieve the column definition. This can be used to define a “catalog” table that display the column description of the source, or to create a table without specifying the column definition that will be automatically constructed by CONNECT when creating the table.

 When marked with a ‘$’ the file can be the result returned by a REST query.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-overview/>

CONNECT Data Types
==================

     Many data types make no or little sense when applied to plain files. This why [CONNECT](../connect/index) supports only a restricted set of data types. However, ODBC, JDBC or MYSQL source tables may contain data types not supported by CONNECT. In this case, CONNECT makes an automatic conversion to a similar supported type when it is possible.

 The data types currently supported by CONNECT are:

 


| Type name | Description | Used for |
| --- | --- | --- |
| `TYPE_STRING` | Zero ended string | [char](../char/index), [varchar](../varchar/index), [text](../text/index) |
| `TYPE_INT` | 4 bytes integer | [int](../int/index), [mediumint](../mediumint/index), [integer](../integer/index) |
| `TYPE_SHORT` | 2 bytes integer | [smallint](../smallint/index) |
| `TYPE_TINY` | 1 byte integer | [tinyint](../tinyint/index) |
| `TYPE_BIGINT` | 8 bytes integer | [bigint](../bigint/index), longlong |
| `TYPE_DOUBLE` | 8 bytes floating point | [double](../double/index), [float](../float/index), real |
| `TYPE_DECIM` | Numeric value | [decimal](../decimal/index), numeric, number |
| `TYPE_DATE` | 4 bytes integer | [date](../date/index), [datetime](../datetime/index), [time](../time/index), [timestamp](../timestamp/index), [year](../year/index) |

 
TYPE\_STRING
------------

 This type corresponds to what is generally known as [CHAR](../char/index) or [VARCHAR](../varchar/index) by database users, or as strings by programmers. Columns containing characters have a maximum length but the character string is of fixed or variable length depending on the file format.

 The DATA\_CHARSET option must be used to specify the character set used in the data source or file. Note that, unlike usually with MariaDB, when a multi-byte character set is used, the column size represents the number of bytes the column value can contain, not the number of characters.

 TYPE\_INT
---------

 The [INTEGER](../integer/index) type contains signed integer numeric 4-byte values (the *int/ of the C language) ranging from `–2,147,483,648` to `2,147,483,647` for signed type and `0` to `4,294,967,295` for unsigned type.*

 TYPE\_SHORT
-----------

 The SHORT data type contains signed [integer numeric 2-byte](../smallint/index) values (the *short integer* of the C language) ranging from `–32,768` to `32,767` for signed type and `0` to `65,535` for unsigned type.

 TYPE\_TINY
----------

 The TINY data type contains [integer numeric 1-byte](../tinyint/index) values (the *char* of the C language) ranging from `–128` to `127` for signed type and `0` to `255` for unsigned type. For some table types, TYPE\_TINY is used to represent Boolean values (0 is false, anything else is true). 

 TYPE\_BIGINT
------------

 The [BIGINT](../bigint/index) data type contains signed integer 8-byte values (the *long long* of the C language) ranging from `-9,223,372,036,854,775,808` to `9,223,372,036,854,775,807` for signed type and from `0` to `18,446,744,073,709,551,615` for unsigned type.

 Inside tables, the coding of all integer values depends on the table type. In tables represented by text files, the number is written in characters, while in tables represented by binary files (`BIN` or `VEC`) the number is directly stored in the binary representation corresponding to the platform.

 The *length* (or *precision*) specification corresponds to the length of the table field in which the value is stored for text files only. It is used to set the output field length for all table types.

 TYPE\_DOUBLE
------------

 The DOUBLE data type corresponds to the C language [double](../double/index) type, a floating-point double precision value coded with 8 bytes. Like for integers, the internal coding in tables depends on the table type, characters for text files, and platform binary representation for binary files.

 The *length* specification corresponds to the length of the table field in which the value is stored for text files only. The *scale* (was *precision*) is the number of decimal digits written into text files. For binary table types (BIN and VEC) this does not apply. The *length* and *scale* specifications are used to set the output field length and number of decimals for all types of tables.

 TYPE\_DECIM
-----------

 The DECIMAL data type corresponds to what MariaDB or ODBC data sources call NUMBER, NUMERIC, or [DECIMAL](../decimal/index): a numeric value with a maximum number of digits (the precision) some of them eventually being decimal digits (the scale). The internal coding in CONNECT is a character representation of the number. For instance:

 
```
colname decimal(14,6)

```

This defines a column *colname* as a number having a *precision* of 14 and a *scale* of 6. Supposing it is populated by:

 
```
insert into xxx values (-2658.74);

```

The internal representation of it will be the character string `-2658.740000`. The way it is stored in a file table depends on the table type. The *length* field specification corresponds to the length of the table field in which the value is stored and is calculated by CONNECT from the *precision* and the *scale* values. This length is *precision* plus 1 if *scale* is not 0 (for the decimal point) plus 1 if this column is not unsigned (for the eventual minus sign). In fix formatted tables the number is right justified in the field of width *length*, for variable formatted tables, such as CSV, the field is the representing character string.

 Because this type is mainly used by CONNECT to handle numeric or decimal fields of ODBC, JDBC and MySQL table types, CONNECT does not provide decimal calculations or comparison by itself. This is why decimal columns of CONNECT tables cannot be indexed.

 DATE Data type
--------------

 Internally, date/time values are stored by CONNECT as a signed 4-byte integer. The value 0 corresponds to 01 January 1970 12:00:00 am coordinated universal time ([UTC](../coordinated-universal-time/index)). All other date/time values are represented by the number of seconds elapsed since or before midnight (00:00:00), 1 January 1970, to that date/time value. Date/time values before midnight 1 January 1970 are represented by a negative number of seconds.

 CONNECT handles dates from **13 December 1901, 20:45:52** to **18 January 2038, 19:14:07**.

 Although date and time information can be represented in both CHAR and INTEGER data types, the DATE data type has special associated properties. For each DATE value, CONNECT can store all or only some of the following information: century, year, month, day, hour, minute, and second.

 ### Date Format in Text Tables

 Internally, date/time values are handled as a signed 4-byte integer. But in text tables (type DOS, FIX, CSV, FMT, and DBF) dates are most of the time stored as a formatted character string (although they also can be stored as a numeric string representing their internal value). Because there are infinite ways to format a date, the format to use for decoding dates, as well as the field length in the file, must be associated to date columns (except when they are stored as the internal numeric value).

 Note that this associated format is used only to describe the way the temporal value is stored internally. This format is used both for output to decode the date in a SELECT statement as well as for input to encode the date in INSERT or UPDATE statements. However, what is kept in this value depends on the data type used in the column definition (all the MariaDB temporal values can be specified). When creating a table, the format is associated to a date column using the DATE\_FORMAT option in the column definition, for instance:

 
```
create table birthday (
  Name varchar(17),
  Bday date field_length=10 date_format='MM/DD/YYYY',
  Btime time field_length=8 date_format='hh:mm tt')
engine=CONNECT table_type=CSV;

insert into birthday values ('Charlie','2012-11-12','15:30:00');

select * from birthday;

```

The SELECT query returns:

 


| Name | Bday | Btime |
| --- | --- | --- |
| Charlie | 2012-11-12 | 15:30:00 |

 
The values of the INSERT statement must be specified using the standard MariaDB syntax and these values are displayed as MariaDB temporal values. Sure enough, the column formats apply only to the way these values are represented inside the CSV files. Here, the inserted record will be:

 
```
Charlie,11/12/2012,03:30 PM

```

**Note:** The field\_length option exists because the MariaDB syntax does not allow specifying the field length between parentheses for temporal column types. If not specified, the field length is calculated from the date format (sometimes as a max value) or made equal to the default length value if there is no date format. In the above example it could have been removed as the calculated values are the ones specified. However, if the table type would have been DOS or FIX, these values could be adjusted to fit the actual field length within the file.

 A CONNECT format string consists of a series of elements that represent a particular piece of information and define its format. The elements will be recognized in the order they appear in the format string. Date and time format elements will be replaced by the actual date and time as they appear in the source string. They are defined by the following groups of characters:

 


| Element | Description |
| --- | --- |
| YY | The last two digits of the year (that is, 1996 would be coded as "96"). |
| YYYY | The full year (that is, 1996 could be entered as "96" but displayed as “1996”). |
| MM | The one or two-digit month number. |
| MMM | The three-character month abbreviation. |
| MMMM | The full month name. |
| DD | The one or two-digit month day. |
| DDD | The three-character weekday abbreviation. |
| DDDD | The full weekday name. |
| hh | The one or two-digit hour in 12-hour or 24-hour format. |
| mm | The one or two-digit minute. |
| ss | The one or two-digit second. |
| t | The one-letter AM/PM abbreviation (that is, AM is entered as "A"). |
| tt | The two-letter AM/PM abbreviation (that is, AM is entered as "AM"). |

 
### Usage Notes

 * To match the source string, you can add body text to the format string, enclosing it in single quotes or double quotes if it would be ambiguous. Punctuation marks do not need to be quoted.
* The hour information is regarded as 12-hour format if a “t” or “tt” element follows the “hh” element in the format or as 24-hour format otherwise.
* The "MM", "DD", "hh", "mm", "ss" elements can be specified with one or two letters (e.g. "MM" or "M") making no difference on input, but placing a leading zero to one-digit values on output[[1](#_note-0)] for two-letter elements.
* If the format contains elements DDD or DDDD, the day of week name is skipped on input and ignored to calculate the internal date value. On output, the correct day of week name is generated and displayed.
* Temporal values are always stored as numeric in [BIN](../connect-table-types-data-files/index#bin-table-type) and [VEC](../connect-table-types-data-files/index#vec-table-type-vecto) tables.

 ### Handling dates that are out of the range of supported CONNECT dates

 If you want to make a table containing, for instance, historical dates not being convertible into CONNECT dates, make your column CHAR or VARCHAR and store the dates in the MariaDB format. All date functions applied to these strings will convert them to MariaDB dates and will work as if they were real dates. Of course they must be inserted and will be displayed using the MariaDB format.

 NULL handling
-------------

 CONNECT handles [null values](../null-values-in-mariadb/index) for data sources able to produce nulls. Currently this concerns mainly the [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index), MONGO, [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [XML](../connect-table-types-data-files/index#xml-table-type), [JSON](../connect-json-table-type/index) and [INI](../connect-table-types-data-files/index#ini-table-type) table types. For INI, [JSON](../connect-json-table-type/index), MONGO or XML types, null values are returned when the key is missing in the section (INI) or when the corresponding node does not exist in a row (XML, JSON, MONGO).

 For other file tables, the issue is to define what a null value is. In a numeric column, 0 can sometimes be a valid value but, in some other cases, it can make no sense. The same for character columns; is a blank field a valid value or not?

 A special case is DATE columns with a DATE\_FORMAT specified. Any value not matching the format can be regarded as NULL.

 CONNECT leaves the decision to you. When declaring a column in the [CREATE TABLE](../create-table/index) statement, if it is declared NOT NULL, blank or zero values will be considered as valid values. Otherwise they will be considered as NULL values. In all cases, nulls are replaced on insert or update by pseudo null values, a zero-length character string for text types or a zero value for numeric types. Once converted to pseudo null values, they will be recognized as NULL only for columns declared as nullable.

 For instance:

 
```
create table t1 (a int, b char(10)) engine=connect;
insert into t1 values (0,'zero'),(1,'one'),(2,'two'),(null,'???');
select * from t1 where a is null;

```

The select query replies:

 


| a | b |
| --- | --- |
| NULL | zero |
| NULL | ??? |

 
Sure enough, the value 0 entered on the first row is regarded as NULL for a nullable column. However, if we execute the query:

 
```
select * from t1 where a = 0;

```

This will return no line because a NULL is not equal to 0 in an SQL where clause.

 Now let us see what happens with not null columns:

 
```
create table t1 (a int not null, b char(10) not null) engine=connect;
insert into t1 values (0,'zero'),(1,'one'),(2,'two'),(null,'???');

```

The insert statement will produce a warning saying:

 


| Level | Code | Message |
| --- | --- | --- |
| Warning | 1048 | Column 'a' cannot be null |

 
It is replaced by a pseudo null `0` on the fourth row. Let us see the result:

 
```
select * from t1 where a is null;
select * from t1 where a = 0;

```

The first query returns no rows, 0 are valid values and not NULL. The second query replies:

 


| a | b |
| --- | --- |
| 0 | zero |
| 0 | ??? |

 
It shows that the NULL inserted value was replaced by a valid 0 value.

 Unsigned numeric types
----------------------

 They are supported by CONNECT since version 1.01.0010 for fixed numeric types (TINY, SHORT, INTEGER, and BITINT).

 Data type conversion
--------------------

 CONNECT is able to convert data from one type to another in most cases. These conversions are done without warning even when this leads to truncation or loss of precision. This is true, in particular, for tables of type ODBC, JDBC, MYSQL and PROXY (via MySQL) because the source table may contain some data types not supported by CONNECT. They are converted when possible to CONNECT types.

 When converted, MariaDB types are converted as:

 


| MariaDB Types | CONNECT Type | Remark |
| --- | --- | --- |
| [integer](../integer/index), [medium integer](../mediumint/index) | TYPE\_INT | 4 byte integer |
| [small integer](../smallint/index) | TYPE\_SHORT | 2 byte integer |
| [tiny integer](../tinyint/index) | TYPE\_TINY | 1 byte integer |
| [char](../char/index), [varchar](../varchar/index) | TYPE\_STRING | Same length |
| [double](../double/index), [float](../float/index), real | TYPE\_DOUBLE | 8 byte floating point |
| [decimal](../decimal/index), numeric | TYPE\_DECIM | Length depends on precision and scale |
| all [date](../date/index) related types | TYPE\_DATE | Date format can be set accordingly |
| [bigint](../bigint/index), longlong | TYPE\_BIGINT | 8 byte integer |
| [enum](../enum/index), [set](../set-data-type/index) | TYPE\_STRING | Numeric value not accessible |
| All text types | TYPE\_STRING TYPE\_ERROR | Depending on the value of the [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) system variable value. |
| Other types | TYPE\_ERROR | Not supported, no conversion provided. |

 
For [ENUM](../enum/index), the length of the column is the length of the longest value of the enumeration. For [SET](../set-data-type/index) the length is enough to contain all the set values concatenated with comma separator.

 In the case of [TEXT](../text/index) columns, the handling depends on the values given to the [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) and [connect\_conv\_size](../connect-system-variables/index#connect_conv_size) system variables.

 Note: [BLOB](../blob/index) is currently not converted by default until a TYPE\_BIN type is added to CONNECT. However, the FORCE option (from Connect 1.06.006) can be specified for blob columns containing text and the SKIP option also applies to ODBC BLOB columns.

 ODBC SQL types are converted as:

 


| SQL Types | Connect Type | Remark |
| --- | --- | --- |
| SQL\_CHAR, SQL\_VARCHAR | TYPE\_STRING |  |
| SQL\_LONGVARCHAR | TYPE\_STRING | `len = min(abs(len), connect_conv_size)` If the column is generated by discovery (columns not specified) its length is [connect\_conv\_size](../connect-system-variables/index#connect_conv_size). |
| SQL\_NUMERIC, SQL\_DECIMAL | TYPE\_DECIM |  |
| SQL\_INTEGER | TYPE\_INT |  |
| SQL\_SMALLINT | TYPE\_SHORT |  |
| SQL\_TINYINT, SQL\_BIT | TYPE\_TINY |  |
| SQL\_FLOAT, SQL\_REAL, SQL\_DOUBLE | TYPE\_DOUBLE |  |
| SQL\_DATETIME | TYPE\_DATE | `len = 10` |
| SQL\_INTERVAL | TYPE\_STRING | `len = 8 + ((scale) ? (scale+1) : 0)` |
| SQL\_TIMESTAMP | TYPE\_DATE | `len = 19 + ((scale) ? (scale +1) : 0)` |
| SQL\_BIGINT | TYPE\_BIGINT |  |
| SQL\_GUID | TYPE\_STRING | l`len=36` |
| SQL\_BINARY, SQL\_VARBINARY, SQL\_LONG-VARBINARY | TYPE\_STRING | `len = min(abs(len), connect_conv_size`) Only if the value of [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) is `force`. The column should use the binary charset. |
| Other types | TYPE\_ERROR | *Not supported.* |

 
JDBC SQL types are converted as:

 


| JDBC Types | Connect Type | Remark |
| --- | --- | --- |
| (N)CHAR, (N)VARCHAR | TYPE\_STRING |  |
| LONG(N)VARCHAR | TYPE\_STRING | `len = min(abs(len), connect_conv_size)` If the column is generated by discovery (columns not specified), its length is [connect\_conv\_size](../connect-system-variables/index#connect_conv_size) |
| NUMERIC, DECIMAL, VARBINARY | TYPE\_DECIM |
| INTEGER | TYPE\_INT |  |
| SMALLINT | TYPE\_SHORT |  |
| TINYINT, BIT | TYPE\_TINY |  |
| FLOAT, REAL, DOUBLE | TYPE\_DOUBLE |  |
| DATE | TYPE\_DATE | `len = 10` |
| TIME | TYPE\_DATE | `len = 8 + ((scale) ? (scale+1) : 0)` |
| TIMESTAMP | TYPE\_DATE | `len = 19 + ((scale) ? (scale +1) : 0)` |
| BIGINT | TYPE\_BIGINT |  |
| UUID (specific to PostgreSQL) | TYPE\_STRINGTYPE\_ERROR | `len=36`If [connect\_type\_conv=NO](../connect-system-variables/index#connect_type_conv) |
| Other types | TYPE\_ERROR | Not supported. |

 

Note: The [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) SKIP option also applies to ODBC and JDBC tables.

 


---

 1. [↑](#_ref-0) Here input and output are used to specify respectively decoding the date to get its numeric value from the data file and encoding a date to write it in the table file. Input is performed within [SELECT](../select/index) queries; output is performed in [UPDATE](../update/index) or [INSERT](../insert/index) queries.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-data-types/>

Current Status of the CONNECT Handler
=====================================

    The current CONNECT handler is a GA (stable) release. It was written starting both from an aborted project written for MySQL in 2004 and from the “DBCONNECT” program. It was tested on all the examples described in this document, and is distributed with a set of 53 test cases. Here is a not limited list of future developments:

 1. Adding more table types.
2. Make more tests files (53 are already made)
3. Adding more data types, in particular unsigned ones (done for unsigned).
4. Supporting indexing on nullable and decimal columns.
5. Adding more optimize tools (block indexing, dynamic indexing, etc.) (done)
6. Supporting MRR (done)
7. Supporting partitioning (done)
8. Getting NOSQL data from the Net as answers from REST queries (done)

 No programs are bug free, especially new ones. Please [report all bugs](../reporting-bugs/index) or documentation errors using the means provided by MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/current-status-of-the-connect-handler/>

CONNECT DOS and FIX Table Types
===============================

    Overview
--------

 Tables of type DOS and FIX are based on text files (see [CONNECT Table Types - Data Files](../connect-table-types-data-files/index)). Within a record, column fields are positioned at a fixed offset from the beginning of the record. Except sometimes for the last field, column fields are also of fixed length. If the last field has varying length, the type of the table is DOS. For instance, having the file *dept.dat* formatted like:

 
```
0318 KINGSTON       70012 SALES       Bank/Insurance
0021 ARMONK         87777 CHQ         Corporate headquarter
0319 HARRISON       40567 SALES       Federal Administration
2452 POUGHKEEPSIE   31416 DEVELOPMENT Research & development

```

You can define a table based on it with:

 
```
create table department (
  number char(4) not null,
  location char(15) not null flag=5,
  director char(5) not null flag=20,
  function char(12) not null flag=26,
  name char(22) not null flag=38)
engine=CONNECT table_type=DOS file_name='dept.dat';

```

Here the flag column option represents the offset of this column inside the records. If the offset of a column is not specified, it defaults to the end of the previous column and defaults to 0 for the first one. The *`lrecl`* parameter that represents the maximum size of a record is calculated by default as the end of the rightmost column and can be unspecified except when some trailing information exists after the rightmost column.

 
**Note:** A special case is files having an encoding such as UTF-8 (for instance specifying `charset=UTF8`) in which some characters may be represented with several bytes. Unlike the type size that MariaDB interprets as a number of characters, the `lrecl` value is the record size in bytes and the flag value represents the offset of the field in the record in bytes. If the flag and/or the `lrecl` value are not specified, they will be calculated by the number of characters in the fields multiplied by a value that is the maximum size in bytes of a character for the corresponding charset. For UTF-8 this value is 3 which is often far too much as there are very few characters requiring 3 bytes to be represented. When creating a new file, you are on the safe side by only doubling the maximum number of characters of a field to calculate the offset of the next field. Of course, for already existing files, the offset must be specified according to what it is in it.

 
Although the field representation is always text in the table file, you can freely choose the corresponding column type, characters, date, integer or floating point according to its contents.

 Sometimes, as in the *number* column of the above *department* table, you have the choice of the type, numeric or characters. This will modify how the column is internally handled — in characters `0021` is different from `21` but not in numeric — as well as how it is displayed.

 If the last field has fixed length, the table should be referred as having the type `FIX`. For instance, to create a table on the file *boys.txt*:

 
```
John      Boston      25/01/1986  02/06/2010
Henry     Boston      07/06/1987  01/04/2008
George    San Jose    10/08/1981  02/06/2010
Sam       Chicago     22/11/1979  10/10/2007
James     Dallas      13/05/1992  14/12/2009
Bill      Boston      11/09/1986  10/02/2008

```

You can for instance use the command:

 
```
create table boys (
  name char(12) not null,
  city char(12) not null,
  birth date not null date_format='DD/MM/YYYY',
  hired date not null date_format='DD/MM/YYYY' flag=36)
engine=CONNECT table_type=FIX file_name='boys.txt' lrecl=48;

```

Here some *flag* options were not specified because the fields have no intermediate space between them except for the last column. The offsets are calculated by default adding the field length to the *offset* of the preceding field. However, for formatted date columns, the offset in the file depends on the format and cannot be calculated by default. For fixed files, the *lrecl* option is the physical length of the record including the line ending character(s). It is calculated by adding to the end of the last field 2 bytes under Windows (CRLF) or 1 byte under UNIX. If the file is imported from another operating system, the `ENDING` option will have to be specified with the proper value.

 For this table, the last offset and the record length must be specified anyway because the date columns have field length coming from their format that is not known by CONNECT. Do not forget to add the line ending length to the total length of the fields.

 This table is displayed as:

 


| name | city | birth | hired |
| --- | --- | --- | --- |
| John | Boston | 1986-01-25 | 2010-06-02 |
| Henry | Boston | 1987-06-07 | 2008-04-01 |
| George | San Jose | 1981-08-10 | 2010-06-02 |
| Sam | Chicago | 1979-11-22 | 2007-10-10 |
| James | Dallas | 1992-05-13 | 2009-12-14 |
| Bill | Boston | 1986-09-11 | 2008-02-10 |

 
Whenever possible, the fixed format should be preferred to the varying one because it is much faster to deal with fixed tables than with variable tables. Sure enough, instead of being read or written record by record, FIX tables are processed by blocks of `BLOCK_SIZE` records, resulting in far less input/output operations to execute. The block size defaults to 100 if not specified in the Create Table statement.

 **Note 1:** It is not mandatory to declare in the table all the fields existing in the source file. However, if some fields are ignored, the *flag* option of the following field and/or the *lrecl* option will have to be specified.

 **Note 2:** Some files have an EOF marker (CTRL+Z 1A) that can prevent the table to be recognized as fixed because the file length is not a multiple of the fixed record size. To indicate this, use in the option list the create option EOF. For instance, if after creating the FIX table *xtab* on the file *foo.dat* that you know have fixed record size, you get, when you try to use it, a message such as:

 
```
File foo.dat is not fixed length, len=302587 lrecl=141

```

After checking that the LRECL default or specified specification is correct, you can indicate to ignore that extra EOF character by:

 
```
alter table xtab option_list='eof=1';

```

Of course, you can specify this option directly in the Create statement. All this applies to some other table types, in particular to BIN tables.

 **Note 3:** The width of the fields is the length specified in the column declaration. For instance for a column declared as:

 
```
number int(3) not null,

```

The field width in the file is 3 characters. This is the value used to calculate the offset of the next field if it is not specified. If this length is not specified, it defaults to the MySQL default type length.

 Specifying the Field Format
---------------------------

 Some files have specific format for their numeric fields. For instance, the decimal point is absent and/or the field should be filled with leading zeros. To deal with such files, as well in reading as in writing, the format can be specified in the `CREATE TABLE` column definition. The syntax of the field format specification is:

 
```
Field_format='[Z][N][d]'

```

The optional parts of the format are:

 

|  |  |
| --- | --- |
| **Z** | The field has leading zeros |
| **N** | No decimal point exist in the file |
| ***d*** | The number of decimals, defaults to the column precision |

 Example
-------

 Let us see how it works in the following example. We define a table based on the file xfmt.txt having eight fields of 12 characters:

 
```
create table xfmt (
  col1 double(12,3) not null,
  col2 double(12,3) not null field_format='4',
  col3 double(12,2) not null field_format='N3',
  col4 double(12,3) not null field_format='Z',
  col5 double(12,3) not null field_format='Z3',
  col6 double(12,5) not null field_format='ZN5',
  col7 int(12) not null field_format='N3',
  col8 smallint(12) not null field_format='N3')
engine=CONNECT table_type=FIX file_name='xfmt.txt';

insert into xfmt values(4567.056,4567.056,4567.056,4567.056,-23456.8,
    3.14159,4567,4567);
select * from xfmt;

```

The first row is displayed as:

 


| COL1 | COL2 | COL3 | COL4 | COL5 | COL6 | COL7 | COL8 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 4567.056 | 4567.056 | 4567.06 | 4567.056 | -23456.800 | 3.14159 | 4567 | 4567 |

 
The number of decimals displayed for all float columns is the column precision, the second argument of the column type option. Of course, integer columns have no decimals, although their formats specify some.

 More interesting is the file layout. To see it let us define another table based on the same file but whose columns are all characters:

 
```
create table cfmt (
  col1 char(12) not null,
  col2 char(12) not null,
  col3 char(12) not null,
  col4 char(12) not null,
  col5 char(12) not null,
  col6 char(12) not null,
  col7 char(12) not null,
  col8 char(12) not null)
engine=CONNECT table_type=FIX file_name='xfmt.txt';
select * from cfmt;

```

The (transposed) display of the select command shows the file text layout for each field. Below a third column was added in this document to comment this result.

 


| Column | Row 1 | Comment (all numeric fields are written right justified) |
| --- | --- | --- |
| **COL1** | `4567.056` | No format, the value was entered as is. |
| **COL2** | `4567.0560` | The format ‘4’ forces to write 4 decimals. |
| **COL3** | `4567060` | N3 → No decimal point. The last 3 digits are decimals. However, the second decimal was rounded because of the column precision. |
| **COL4** | `00004567.056` | Z → Leading zeros, 3 decimals (the column precision) |
| **COL5** | `-0023456.800` | Z3 → (Minus sign) leading zeros, 3 decimals. |
| **COL6** | `000000314159` | ZN5 → Leading zeros, no decimal point, 5 decimals. |
| **COL7** | `4567000` | N3 → No decimal point. The last 3 digits are decimals. |
| **COL8** | `4567000` | Same. Any decimals would be ignored. |

 
**Note:** For columns internally using double precision floating-point numbers, MariaDB limits the decimal precision of any calculation to the column precision. The declared column precision should be at least the number of decimals of the format to avoid a loss of decimals as it happened for `col3` of the above example.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-dos-and-fix-table-types/>

CONNECT DBF Table Type
======================

    Overview
--------

 A table of type `DBF` is physically a dBASE III or IV formatted file (used by many products like dBASE, Xbase, FoxPro etc.). This format is similar to the [FIX](../connect-dos-and-fix-table-types/index) type format with in addition a prefix giving the characteristics of the file, describing in particular all the fields (columns) of the table.

 Because `DBF` files have a header that contains Meta data about the file, in particular the column description, it is possible to create a table based on an existing `DBF` file without giving the column description, for instance:

 
```
create table cust engine=CONNECT table_type=DBF file_name='cust.dbf';

```

To see what CONNECT has done, you can use the `DESCRIBE` or `SHOW CREATE TABLE` commands, and eventually modify some options with the `ALTER TABLE` command.

 The case of deleted lines is handled in a specific way for DBF tables. Deleted lines are not removed from the file but are "soft deleted" meaning they are marked as deleted. In particular, the number of lines contained in the file header does not take care of soft deleted lines. This is why if you execute these two commands applied to a DBF table named *tabdbf*:

 
```
select count(*) from tabdbf;
select count(*) from tabdbf where 1;

```

They can give a different result, the (fast) first one giving the number of physical lines in the file and the second one giving the number of line that are not (soft) deleted.

 The commands UPDATE, INSERT, and DELETE can be used with DBF tables. The DELETE command marks the deleted lines as suppressed but keeps them in the file. The INSERT command, if it is used to populate a newly created table, constructs the file header before inserting new lines.

 **Note:** For DBF tables, column name length is limited to 11 characters and field length to 256 bytes.

 Conversion of dBASE Data Types
------------------------------

 CONNECT handles only types that are stored as characters.

 


| Symbol | DBF Type | CONNECT Type | Description |
| --- | --- | --- | --- |
| B | Binary (string) | TYPE\_STRING | 10 digits representing a .DBT block number. |
| C | Character | TYPE\_STRING | All OEM code page characters - padded with blanks to the width of the field. |
| D | Date | TYPE\_DATE | 8 bytes - date stored as a string in the format YYYYMMDD. |
| N | Numeric | TYPE\_INT TYPE\_BIGINT TYPE\_DOUBLE | Number stored as a string, right justified, and padded with blanks to the width of the field. |
| L | Logical | TYPE\_STRING | 1 byte - initialized to 0x20 otherwise T or F. |
| M | Memo (string) | TYPE\_STRING | 10 digits representing a .DBT block number. |
| @ | Timestamp | Not supported | 8 bytes - two longs, first for date, second for time. It is the number of days since 01/01/4713 BC. |
| I | Long | Not supported | 4 bytes. Leftmost bit used to indicate sign, 0 negative. |
| + | Autoincrement | Not supported | Same as a Long |
| F | Float | TYPE\_DOUBLE | Number stored as a string, right justified, and padded with blanks to the width of the field. |
| O | Double | Not supported | 8 bytes - no conversions, stored as a double. |
| G | OLE | TYPE\_STRING | 10 digits representing a .DBT block number. |

 
For the N numeric type, CONNECT converts it to TYPE\_DOUBLE if the decimals value is not 0, to TYPE\_BIGINT if the length value is greater than 10, else to TYPE\_INT.

 For M, B, and G types, CONNECT just returns the DBT number.

 Reading soft deleted lines of a DBF table
-----------------------------------------

 It is possible to read these lines by changing the read mode of the table. This is specified by an option `READMODE` that can take the values:

 

|  |  |
| --- | --- |
| **0** | Standard mode. This is the default option. |
| **1** | Read all lines including soft deleted ones. |
| **2** | Read only the soft deleted lines. |

 For example, to read all lines of the tabdbf table, you can do:

 
```
alter table tabdbf option_list='Readmode=1';

```

To come back to normal mode, specify READMODE=0.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-dbf-table-type/>

CONNECT VEC Table Type
======================

    
Warning: Avoid using this table type in production applications. This file format is specific to CONNECT and may not be supported in future versions.

 
Tables of type `VEC` are binary files that in some cases can provide good performance on read-intensive query workloads. CONNECT organizes their data on disk as columns of values from the same attribute, as opposed to storing it as rows of tabular records. This organization means that when a query needs to access only a few columns of a particular table, only those columns need to be read from disk. Conversely, in a row-oriented table, all values in a table are typically read from disk, wasting I/O bandwidth.

 CONNECT provides two integral VEC formats, in which each column's data is adjacent.

 Integral vector formats
-----------------------

 In these true vertical formats, the VEC files are made of all the data of the first column, followed by all the data of the second column etc. All this can be in one physical file or each column data can be in a separate file. In the first case, the option max\_rows=m, where m is the estimate of the maximum size (number of rows) of the table, must be specified to be able to insert some new records. This leaves an empty space after each column area in which new data can be inserted. In the second case, the “Split” option can be specified[[2](#_note-1)] at table creation and each column will be stored in a file named sequentially from the table file name followed by the rank of the column. Inserting new lines can freely augment such a table.

 Differences between vector formats
----------------------------------

 These formats correspond to different needs. The integral vector format provides the best performance gain. It will be chosen when the speed of decisional queries must be optimized.

 In the case of a unique file, inserting new data will be limited but there will be only one open and close to do. However, the size of the table cannot be calculated from the file size because of the eventual unused space in the file. It must be kept in a header containing the maximum number of rows and the current number of valid rows in the table. To achieve this, specify the option Header=*n* when creating the table. If `n=1` the header will be placed at the beginning of the file, if `n=2` it will be a separate file with the type ‘.blk’, and if `n=3` the header will be place at the end of the file. This last value is provided because batch inserting is sometimes slower when the header is at the beginning of the file. If not specified, the header option will default to 2 for this table type.

 On the other hand, the "Split" format with separate files have none of these issues, and is a much safer solution when the table must frequently inserted or shared among several users.

 For instance:

 
```
create table vtab (
a int not null,
b char(10) not null)
engine=CONNECT table_type=VEC file_name='vt.vec'; 

```

This table, split by default, will have the column values in files vt1.vec and vt2.vec.

 For vector tables, the option *block\_size=n* is used for block reading and writing; however, to have a file made of blocks of equal size, the internal value of the *max\_rows=m* option is eventually increased to become a multiple of n.

 Like for BIN tables, numeric values are stored using platform internal layout, the correspondence between column types and internal format being the same than the default ones given above for BIN. However, field formats are not available for VEC tables.

 Header option
-------------

 This applies to VEC tables that are not split. Because the file size depends on the MAX\_ROWS value, CONNECT cannot know how many valid records exist in the file. Depending on the value of the HEADER option, this information is stored in a header that can be placed at the beginning of the file, at the end of the file or in a separate file called fn.blk. The valid values for the HEADER option are:

 

|  |  |
| --- | --- |
| 0 | Defaults to 2 for standard tables and to 3 for inward tables. |
| 1 | The header is at the beginning of the file. |
| 2 | The header is in a separate file. |
| 3 | The header is at the end of the file. |

 The value 2 can be used when dealing with files created by another application with no header. The value 3 makes sometimes inserting in the file faster than when the header is at the beginning of the file.

 Note: VEC being a file format specific to CONNECT, no big endian / little endian conversion is provided. These files are not portable between machines using a different byte order setting.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-vec-table-type/>

CONNECT CSV and FMT Table Types
===============================

    CSV Type
--------

 Many source data files are formatted with variable length fields and records. The simplest format, known as `CSV` (Comma Separated Variables), has column fields separated by a separator character. By default, the separator is a comma but can be specified by the `SEP_CHAR` option as any character, for instance a semi-colon.

 If the CSV file first record is the list of column names, specifying the `HEADER=1` option will skip the first record on reading. On writing, if the file is empty, the column names record is automatically written.

 For instance, given the following *people.csv* file:

 
```
Name;birth;children
"Archibald";17/05/01;3
"Nabucho";12/08/03;2

```

You can create the corresponding table by:

 
```
create table people (
  name char(12) not null,
  birth date not null date_format='DD/MM/YY',
  children smallint(2) not null)
engine=CONNECT table_type=CSV file_name='people.csv'
header=1 sep_char=';' quoted=1;

```

Alternatively the engine can attempt to automatically detect the column names, data types and widths using:

 
```
create table people
engine=CONNECT table_type=CSV file_name='people.csv'
header=1 sep_char=';' quoted=1;

```

For CSV tables, the *flag* column option is the rank of the column into the file starting from 1 for the leftmost column. This is to enable having column displayed in a different order than in the file and/or to define the table specifying only some columns of the CSV file. For instance:

 
```
create table people (
  name char(12) not null,
  children smallint(2) not null flag=3,
  birth date not null flag=2 date_format='DD/MM/YY')
engine=CONNECT table_type=CSV file_name='people.csv'
header=1 sep_char=';' quoted=1;

```

In this case the command:

 
```
select * from people;

```

will display the table as:

 


| name | children | birth |
| --- | --- | --- |
| Archibald | 3 | 2001-05-17 |
| Nabucho | 2 | 2003-08-12 |

 
Many applications produce CSV files having some fields quoted, in particular because the field text contains the separator character. For such files, specify the 'QUOTED=*n*' option to indicate the level of quoting and/or the '`QCHAR=c`' to specify what is this eventual quoting character, which is `"` by default. Quoting with single quotes must be specified as `QCHAR=''''`. On writing, fields will be quoted depending on the value of the quoting level, which is `–1` by default meaning no quoting:

 

|  |  |
| --- | --- |
| 0 | The fields between quotes are read and the quotes discarded. On writing, fields will be quoted only if they contain the separator character or begin with the quoting character. If they contain the quoting character, it will be doubled. |
| 1 | Only text fields will be written between quotes, except null fields. This includes also the column names of an eventual header. |
| 2 | All fields will be written between quotes, except null fields. |
| 3 | All fields will be written between quotes, including null fields. |

 Files written this way are successfully read by most applications including spreadsheets.

 **Note 1:** If only the QCHAR option is specified, the QUOTED option will default to 1.

 **Note 2:** For CSV tables whose separator is the tab character, specify `sep_char='\t'`.

 **Note 3:** When creating a table on an existing CSV file, you can let CONNECT analyze the file and make the column description. However, this is a not an elaborate analysis of the file and, for instance, `DATE` fields will not be recognized as such but will be regarded as string fields.

 **Note 4:** The CSV parser only reads and buffers up to 4KB per row by default, rows longer than this will be truncated when read from the file. If the rows are expected to be longer than this use `lrecl` to increase this. For example to set an 8KB maximum row read you would use `lrecl=8192`

 ### Restrictions on CSV Tables

 * If `[secure\_file\_priv](../server-system-variables/index#secure_file_priv)` is set to the path of some directory, then CSV tables can only be created with files in that directory.

 FMT Type
--------

 FMT tables handle files of various formats that are an extension of the concept of CSV files. CONNECT supports these files providing all lines have the same format and that all fields present in all records are recognizable (optional fields must have recognizable delimiters). These files are made by specific application and CONNECT handles them in read only mode.

 FMT tables must be created as CSV tables, specifying their type as FMT. In addition, each column description must be added to its format specification.

 Column Format Specification of FMT tables
-----------------------------------------

 The input format for each column is specified as a FIELD\_FORMAT option. A simple example is:

 
```
IP Char(15) not null field_format=' %n%s%n',

```

In the above example, the format for this (1st) field is `' %n%s%n'`. Note that the blank character at the beginning of this format **is** significant. No trailing blank should be specified in the column formats.

 The syntax and meaning of the column input format is the one of the C **scanf** function.

 However, CONNECT uses the input format in a specific way. Instead of using it to directly store the input value in the column buffer; it uses it to delimit the sub string of the input record that contains the corresponding column value. Retrieving this value is done later by the column functions as for standard CSV files.

 This is why all column formats are made of five components:

 1. An eventual description of what is met and ignored before the column value.
2. A marker of the beginning of the column value written as `%n`.
3. The format specification of the column value itself.
4. A marker of the end of the column value written as `%n` (or `%m` for optional fields).
5. An eventual description of what is met after the column value (not valid is `%m` was used).

 For example, taking the file *funny.txt*:

 
```
12345,'BERTRAND',#200;5009.13
 56, 'POIROT-DELMOTTE' ,#4256 ;18009
345 ,'TRUCMUCHE' , #67; 19000.25

```

You can make a table *fmtsample* with 4 columns ID, NAME, DEPNO and SALARY, using the Create Table statement and column formats:

 
```
create table FMTSAMPLE (
  ID Integer(5) not null field_format=' %n%d%n',
  NAME Char(16) not null field_format=' , ''%n%[^'']%n''',
  DEPNO Integer(4) not null field_format=' , #%n%d%n',
  SALARY Double(12,2) not null field_format=' ; %n%f%n')
Engine=CONNECT table_type=FMT file_name='funny.txt';

```

**Field 1** is an integer (`%d`) with eventual leading blanks.

 **Field 2** is separated from field 1 by optional blanks, a comma, and other optional blanks and is between single quotes. The leading quote is included in component 1 of the column format, followed by the `%n` marker. The column value is specified as `%[^']` meaning to keep any characters read until a quote is met. The ending marker (`%n`) is followed by the 5th component of the column format, the single quote that follows the column value.

 **Field 3,** also separated by a comma, is a number preceded by a pound sign.

 **Field 4,** separated by a semicolon eventually surrounded by blanks, is a number with an optional decimal point (`%f`).

 This table will be displayed as:

 


| ID | NAME | DEPNO | SALARY |
| --- | --- | --- | --- |
| 12345 | BERTRAND | 200 | 5009.13 |
| 56 | POIROT-DELMOTTE | 4256 | 18009.00 |
| 345 | TRUCMUCHE | 67 | 19000.25 |

 
Optional Fields
---------------

 To be recognized, a field normally must be at least one character long. For instance, a numeric field must have at least one digit, or a character field cannot be void. However many existing files do not follow this format.

 Let us suppose for instance that the preceding example file could be:

 
```
12345,'BERTRAND',#200;5009.13
 56, 'POIROT-DELMOTTE' ,# ;18009
345 ,'' , #67; 19000.25

```

This will display an error message such as *“Bad format line x field y of FMTSAMPLE”.* To avoid this and accept these records, the corresponding fields must be specified as "optional". In the above example, fields 2 and 3 can have null values (in lines 3 and 2 respectively). To specify them as optional, their format must be terminated by `%m` (instead of the second `%n`). A statement such as this can do the table creation:

 
```
create table FMTAMPLE (
  ID Integer(5) not null field_format=' %n%d%n',
  NAME Char(16) not null field_format=' , ''%n%[^'']%m',
  DEPNO Integer(4) field_format=''' , #%n%d%m',
  SALARY Double(12,2) field_format=' ; %n%f%n')
Engine=CONNECT table_type=FMT file_name='funny.txt';

```

Note that, because the statement must be terminated by `%m` with no additional characters, skipping the ending quote of field 2 was moved from the end of the second column format to the beginning of the third column format.

 The table result is:

 


| ID | NAME | DEPNO | SALARY |
| --- | --- | --- | --- |
| 12345 | BERTRAND | 200 | 5,009.13 |
| 56 | POIROT-DELMOTTE | NULL | 18,009.00 |
| 345 | NULL | 67 | 19,000.25 |

 
Missing fields are replaced by null values if the column is nullable, blanks for character strings and 0 for numeric fields if it is not.

 **Note 1:** Because the formats are specified between quotes, quotes belonging to the formats must be doubled or escaped to avoid a `CREATE TABLE` statement syntax error.

 **Note 2:** Characters separating columns can be included as well in component 5 of the preceding column format or in component 1 of the succeeding column format but for blanks, which should be always included in component 1 of the succeeding column format because line trailing blanks can be sometimes lost. This is also mandatory for optional fields.

 **Note 3:** Because the format is mainly used to find the sub-string corresponding to a column value, the field specification does not necessarily match the column type. For instance supposing a table contains two integer columns, NBONE and NBTWO, the two lines describing these columns could be:

 
```
NBONE integer(5) not null field_format=' %n%d%n',
NBTWO integer(5) field_format=' %n%s%n',

```

The first one specifies a required integer field (`%d`), the second line describes a field that can be an integer, but can be replaced by a "-" (or any other) character. Specifying the format specification for this column as a character field (`%s`) enables to recognize it with no error in all cases. Later on, this field will be converted to integer by the column read function, and a null 0 value will be generated for field specified in their format as non-numeric.

 Bad Record Error Processing
---------------------------

 When no match if found for a column field the process aborts with a message such as:

 
```
Bad format line 3 field 4 of funny.txt

```

This can mean as well that one line of the input line is ill formed or that the column format for this field has been wrongly specified. When you know that your file contains records that are ill formatted and should be eliminated from normal processing, set the “maxerr” option of the CREATE TABLE statement, for instance:

 
```
Option_list='maxerr=100'

```

This will indicate that no error message be raised for the 100 first wrong lines. You can set Maxerr to a number greater than the number of wrong lines in your files to ignore them and get no errors.

 Additionally, the “accept” option permit to keep those ill formatted lines with the bad field, and all succeeding fields of the record, nullified. If “accept” is specified without “maxerr”, all ill formatted lines will be accepted.

 **Note:** This error processing also applies to CSV tables.

 Fields Containing a Formatted Date
----------------------------------

 A special case is one of columns containing a formatted date. In this case, two formats must be specified:

 1. The field recognition format used to delimit the date in the input record.
2. The date format used to interpret the date.
3. The field length option if the date representation is different than the standard type size.

 For example, let us suppose we have a web log source file containing records such as:

 
```
165.91.215.31 - - [17/Jul/2001:00:01:13 -0400] - "GET /usnews/home.htm HTTP/1.1" 302

```

The create table statement shall be like this:

 
```
create table WEBSAMP (
  IP char(15) not null field_format='%n%s%n',
  DATE datetime not null field_format=' - - [%n%s%n -0400]'
  date_format='DD/MMM/YYYY:hh:mm:ss' field_length=20,
  FILE char(128) not null field_format=' - "GET %n%s%n',
  HTTP double(4,2) not null field_format=' HTTP/%n%f%n"',
  NBONE int(5) not null field_format=' %n%d%n')
Engine=CONNECT table_type=FMT lrecl=400
file_name='e:\\data\\token\\Websamp.dat';

```

**Note 1:** Here, `field_length=20` was necessary because the default size for datetime columns is only 19. The `lrecl=400` was also specified because the actual file contains more information in each records making the record size calculated by default too small.

 **Note 2:** The file name could have been specified as `'e:/data/token/Websamp.dat'`.

 **Note 3:** FMT tables are currently read only.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-csv-and-fmt-table-types/>

CONNECT BIN Table Type
======================

    Overview
--------

 A table of type BIN is physically a binary file in which each row is a logical record of fixed length[[1](#_note-0)]. Within a record, column fields are of a fixed offset and length as with [FIX tables](../connect-dos-and-fix-table-types/index). Specific to BIN tables is that numerical values are internally encoded using native platform representation, so no conversion is needed to handle numerical values in expressions.

 It is not required that the lines of a BIN file be separated by characters such as CR and/or LF but this is possible. In such an event, the *lrecl* option must be specified accordingly.

 **Note:** Unlike for the [DOS and FIX types](../connect-dos-and-fix-table-types/index), the width of the fields is the length of their internal representation in the file. For instance for a column declared as:

 
```
number int(5) not null,

```

The field width in the file is 4 characters, the size of a binary integer. This is the value used to calculate the offset of the next field if it is not specified. Therefore, if the next field is placed 5 characters after this one, this declaration is not enough, and the flag option will have to be used on the next field.

 Type Conversion in BIN Tables
-----------------------------

 Here are the correspondences between the column type and field format provided by default:

 


| Column type | File default format |
| --- | --- |
| Char(*n*) | Text of *n* characters. |
| Date | Integer (4 bytes) |
| Int(*n*) | Integer (4 bytes) |
| Smallint(*n*) | Short integer (2 bytes) |
| TinyInt(*n*) | Char (1 Byte) |
| Bigint(*n*) | Large integer (8 bytes) |
| Double(*n,d*) | Double floating point (8 bytes) |

 
However, the column type need not necessarily match the field format within the table file. In particular, this occurs for field formats that correspond to numeric types that are not handled by CONNECT[[2](#_note-1)]. Indeed, BIN table files may internally contain float numbers or binary numbers of any byte length in big-endian or little-endian representation[[3](#_note-2)]. Also, as in [DOS or FIX types](../connect-dos-and-fix-table-types/index) tables, you may want to handle some character fields as numeric or vice versa.

 This is why it is possible to specify the field format when it does not correspond to the column type default using the *field\_format* column option in the [CREATE TABLE](../create-table/index) statement. Here are the available field formats for BIN tables:

 


| Field\_format | Internal representation |
| --- | --- |
| **[n]{L or B or H}[n]** | n bytes binary number in little endian, big endian or host endian representation. |
| **C** | Characters string (*n* bytes) |
| **I** | integer (4 bytes) |
| **D** | Double float (8 bytes) |
| **S** | Short integer (2 bytes) |
| **T** | Tiny integer (1 byte) |
| **G** | Big integer (8 bytes) |
| **F** or **R** | Real or float (Floating point number on 4 bytes) |
| **X** | Use the default format field for the column type |

 
All field formats (except the first one) are a one-character specification[[4](#_note-3)]. 'X' is equivalent to not specifying the field format. For the 'C' character specification, *n* is the column width as specified with the column type. For one-column formats, the number of bytes of the numeric fields corresponds to what it is on most platforms. However, it could vary for some. The G, I, S and T formats are deprecated because they correspond to supported data types and may not be supported in future versions.

 Example
-------

 Here is an example of a BIN table. The file record layout is supposed to be:

 
```
NNNNCCCCCCCCCCIIIISSFFFFSS

```

Here N represents numeric characters, C any characters, I integer bytes, S short integer bytes, and F float number bytes. The `IIII` field contains a date in numeric format.

 The table could be created by:

 
```
create table testbal (
fig int(4) not null field_format='C',
name char(10) not null,
birth date not null field_format='L',
id char(5) not null field_format='L2',
salary double(9,2) not null default 0.00 field_format='F',
dept int(4) not null field_format='L2')
engine=CONNECT table_type=BIN block_size=5 file_name='Testbal.dat';

```

Specifying the little-endian representation for binary values is not useful on most machines, but makes the create table statement portable on a machine using big endian, as well as the table file.

 The field offsets and the file record length are calculated according the column internal format and eventually modified by the field format. It is not necessary to specify them for a packed binary file without line endings. If a line ending is desired, specify the ending option or specify the `lrecl` option adding the ending width. The table can be filled by:

 
```
insert into testbal values
  (5500,'ARCHIBALD','1980-01-25','3789',4380.50,318),
  (123,'OLIVER','1953-08-10','23456',3400.68,2158),
  (3123,'FOO','2002-07-23','888',default,318);

```

Note that the types of the inserted values must match the column type, not the field format type.

 The query:

 
```
select * from testbal;

```

returns:

 


| fig | name | birth | id | salary | dept |
| --- | --- | --- | --- | --- | --- |
| 5500 | ARCHIBALD | 1980-01-25 | 3789 | 4380.50 | 318 |
| 123 | OLIVER | 1953-08-10 | 23456 | 3400.68 | 2158 |
| 3123 | FOO | 2002-07-23 | 888 | 0.00 | 318 |

 
Numeric fields alignment
------------------------

 In binary files, numeric fields and record length can be aligned on 4-or-8-byte boundaries to optimize performance on certain processors. This can be modified in the OPTION\_LIST with an "align" option ("packed" meaning `align=1` is the default).

 

---

 1. [↑](#_ref-0) Sometimes it can be a physical record if LF or CRLF have been written in the file.
2. [↑](#_ref-1) Most of these are obsolete because CONNECT supports all column types except float
3. [↑](#_ref-2) The default endian representation used in the table file can be specified by setting the ENDIAN option as ‘L’ or ‘B’ in the option list.
4. [↑](#_ref-3) It can be specified with more than one character, but only the first one is significant.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-bin-table-type/>

CONNECT Zipped File Tables
==========================

    
**MariaDB starting with [10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)**Connect can work on table files that are compressed in one or several zip files.

 
The specific options used when creating tables based on zip files are:

 


| Table Option | Type | Description |
| --- | --- | --- |
| ZIPPED | Boolean | Required to be set as true. |
| ENTRY\* | String | The optional name or pattern of the zip entry or entries to be used with the table. If not specified, all entries or only the first one will be used depending on the *mulentries* option setting. |
| MULENTRIES\* | Boolean | True if several entries are part of the table. If not specified, it defaults to false if the *entry* option is not specified. If the entry option is specified, it defaults to true if the entry name contains wildcard characters or false if it does not. |
| APPEND\* | Boolean | Used when creating new zipped tables (see below) |
| LOAD\* | String | Used when creating new zipped tables (see below) |

 
Options marked with a ‘\*’ must be specified in the option list.

 Examples of use: 

 #### Example 1: Single CSV File Included in a Single ZIP File

 Let's suppose you have a CSV file from which you would create a table by:

 
```
create table emp
... optional column definition
engine=connect table_type=CSV file_name='E:/Data/employee.csv'
sep_char=';' header=1;

```

If the CSV file is included in a ZIP file, the CREATE TABLE becomes:

 
```
create table empzip
... optional column definition
engine=connect table_type=CSV file_name='E:/Data/employee.zip'
sep_char=';' header=1 zipped=1 option_list='Entry=emp.csv';

```

The *file\_name* option is the name of the zip file. The *entry* option is the name of the entry inside the zip file. If there is only one entry file inside the zip file, this option can be omitted.

 #### Example 2: Several CSV Files Included in a Single ZIP File

 If the table is made from several files such as emp01.csv, emp02.csv, etc., the standard create table would be:

 
```
create table empmul (
... required column definition
) engine=connect table_type=CSV file_name='E:/Data/emp*.csv' 
sep_char=';' header=1 multiple=1;

```

But if these files are all zipped inside a unique zip file, it becomes:

 
```
create table empzmul
... required column definition
engine=connect table_type=CSV file_name='E:/Data/emp.zip'
sep_char=';' header=1 zipped=1 option_list='Entry=emp*.csv';

```

Here the *entry* option is the pattern that the files inside the zip file must match. If all entry files are ok, the *entry* option can be omitted but the Boolean option *mulentries* must be specified as true.

 #### Example 3: Single CSV File included in Multiple ZIP Files (Without considering subfolders)

 If the table is created on several zip files, it is specified as for all other multiple tables:

 
```
create table zempmul (
... required column definition
) engine=connect table_type=CSV file_name='E:/Data/emp*.zip' 
sep_char=';' header=1 multiple=1 zipped=yes 
option_list='Entry=employee.csv';

```

Here again the *entry* option is used to restrict the entry file(s) to be used inside the zip files and can be omitted if all are ok.

 The column descriptions can be retrieved by the discovery process for table types allowing it. It cannot be done for multiple tables or multiple entries.

 A catalog table can be created by adding *catfunc=columns*. This can be used to show the column definitions of multiple tables. *Multiple* must be set to false and the column definitions will be the ones of the first table or entry.

 This first implementation has some restrictions:

 1. Zipped tables are read-only. [UPDATE](../update/index) and [DELETE](../delete/index) are not supported. However, [INSERT](../insert/index) is supported in a specific way when making tables.
2. The inside files are decompressed into memory. Memory problems may arise with huge files.
3. Only file types that can be handled from memory are eligible for this. This includes [DOS](../connect-dos-and-fix-table-types/index), [FIX](../connect-dos-and-fix-table-types/index), [BIN](../connect-bin-table-type/index), [CSV](../connect-csv-and-fmt-table-types/index), [FMT](../connect-csv-and-fmt-table-types/index), [DBF](../connect-dbf-table-type/index), [JSON](../connect-json-table-type/index), and [XML](../connect-xml-table-type/index) table types, as well as types based on these such as [XCOL](../connect-xcol-table-type/index), [OCCUR](../connect-occur-table-type/index) and [PIVOT](../connect-pivot-table-type/index).

 Optimization by indexing or block indexing is possible for table types supporting it. However, it applies to the uncompressed table. This means that the whole table is always uncompressed.

 Partitioning is also supported. See how to do it in the section about partitioning. 

 ### Creating New Zipped Tables

 Tables can be created to access already existing zip files. However, is it also possible to make the zip file from an existing file or table. Two ways are available to make the zip file:

 #### Insert Method

 insert can be used to make the table file for table types based on records (this excludes DBF, XML and JSON when pretty is not 0). However, the current implementation of the used package (minizip) does not support adding to an already existing zip entry. This means that when executing an insert statement the inserted records are not added but replace the existing ones. CONNECT protects existing data by not allowing such inserts, Therefore, only three ways are available to do so:

 1. Using only one insert statement to make the whole table. This is possible only for small tables and is principally useful when making tests.
2. Making the table from the data of another table. This can be done by executing an “insert into table select \* from another\_table” or by specifying “as select \* from another\_table” in the create table statement.
3. Making the table from a file whose format enables to use the “load data infile” statement.

 To add a new entry in an existing zip file, specify “append=YES” in the option list. When inserting several entries, use ALTER to specify the required options, for instance:

 
```
create table znumul (
Chiffre int(3) not null,
Lettre char(16) not null)
engine=CONNECT table_type=CSV
file_name='C:/Data/FMT/mnum.zip' header=1 lrecl=20 zipped=1
option_list='Entry=Num1';
insert into znumul select * from num1;
alter table znumul option_list='Entry=Num2,Append=YES';
insert into znumul select * from num2;
alter table znumul option_list='Entry=Num3,Append=YES';
insert into znumul select * from num3;
alter table znumul option_list='Entry=Num*,Append=YES';
select * from znumul;

```

The last ALTER is needed to display all the entries.

 #### File Zipping Method

 This method enables to make the zip file from another file when creating the table. It applies to all table types including DBF, XML and JSON. It is specified in the create table statement with the load option. For example:

 
```
create table XSERVZIP (
NUMERO varchar(4) not null,
LIEU varchar(15) not null,
CHEF varchar(5) not null,
FONCTION varchar(12) not null,
NOM varchar(21) not null)
engine=CONNECT table_type=XML file_name='E:/Xml/perso.zip' zipped=1
option_list='entry=services,load=E:/Xml/serv2.xml';

```

When executing this statement, the *serv2.xml* file will be zipped as /perso.zip*. The entry name can be specified or defaults to the source file name.* 

 If the column descriptions are specified, the table can be used later to read from the zipped table, but they are not used when creating the zip file. Thus, a fake column (there must be one) can be specified and another table created to read the zip file. This one can take advantage of the discovery process to avoid providing the columns description for table types allowing it. For instance:

 
```
create table mkzq (whatever int)
engine=connect table_type=DBF zipped=1
file_name='C:/Data/EAUX/dbf/CQUART.ZIP'
option_list='Load=C:/Data/EAUX/dbf/CQUART.DBF';

create table zquart
engine=connect table_type=DBF zipped=1
file_name='C:/Data/EAUX/dbf/CQUART.ZIP';

```

It is also possible to create a multi-entries table from several files:

 
```
CREATE TABLE znewcities (
  _id char(5) NOT NULL,
  city char(16) NOT NULL,
  lat double(18,6) NOT NULL `FIELD_FORMAT`='loc:[0]',
  lng double(18,6) NOT NULL `FIELD_FORMAT`='loc:[1]',
  pop int(6) NOT NULL,
  state char(2) NOT NULL
) ENGINE=CONNECT TABLE_TYPE=JSON FILE_NAME='E:/Json/newcities.zip' ZIPPED=1 LRECL=1000 OPTION_LIST='Load=E:/Json/city_*.json,mulentries=YES,pretty=0';

```

Here the files to load are specified with wildcard characters and the *mulentries* options must be specified. However, the *entry* option must not be specified, entry names will be made from the file names. Provide a fake column description if the files have different column layout, but specific tables will have to be created to read each of them.

 ### ZIP Table Type

 A ZIP table type is also available. It is not meant to read the inside files but to display information about the zip file contents. For instance:

 
```
create table xzipinfo2 (
entry varchar(256)not null,
cmpsize bigint not null flag=1,
uncsize bigint not null flag=2,
method int not null flag=3,
date datetime not null flag=4)
engine=connect table_type=ZIP file_name='E:/Data/Json/cities.zip';

```

This will display the name, compressed size, uncompressed size, and compress method of all entries inside the zip file. Column names are irrelevant; these are flag values that mean what information to retrieve.

 It is possible to retrieve this information from several zip files by specifying the multiple option:

 
```

create table TestZip1 (
entry varchar(260)not null,
cmpsize bigint not null flag=1,
uncsize bigint not null flag=2,
method int not null flag=3,
date datetime not null flag=4,
zipname varchar(256) special='FILEID')
engine=connect table_type=ZIP multiple=1
file_name='C:/Data/Ziptest/CCAM06300_DBF_PART*.zip';

```

Here we added the special column zipname to get the name of the zip file for each entry.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-zipped-file-tables/>

CONNECT Table Types
====================

   The main feature of [CONNECT](../connect/index) is to give MariaDB the ability to handle tables from many sources, native files, other DBMS’s tables, or special “virtual” tables. Moreover, for all tables physically represented by data files, CONNECT recognizes many different file formats, described below but not limited in the future to this list, because more can be easily added to it on demand ([OEM tables](../connect-table-types-oem/index)).

 
Note: You can download a [PDF version of the CONNECT documentation](https://mariadb.com/kb/en/connect-table-types/+attachment/connect_1_7_03) (1.7.0003).

   

| Title | Description |
| --- | --- |
|  [CONNECT Table Types Overview](../connect-table-types-overview/index) |  CONNECT can handle many table formats.  |
|  [Inward and Outward Tables](../inward-and-outward-tables/index) |  The two broad categories of CONNECT tables.  |
|  [CONNECT Table Types - Data Files](../connect-table-types-data-files/index) |  CONNECT plain DOS or UNIX data files.  |
|  [CONNECT Zipped File Tables](../connect-zipped-file-tables/index) |  When the table file or files are compressed in one or several zip files.  |
|  [CONNECT DOS and FIX Table Types](../connect-dos-and-fix-table-types/index) |  CONNECT tables based on text files  |
|  [CONNECT DBF Table Type](../connect-dbf-table-type/index) |  CONNECT dBASE III or IV tables.  |
|  [CONNECT BIN Table Type](../connect-bin-table-type/index) |  CONNECT binary files in which each row is a logical record of fixed length  |
|  [CONNECT VEC Table Type](../connect-vec-table-type/index) |  CONNECT binary files organized in vectors  |
|  [CONNECT CSV and FMT Table Types](../connect-csv-and-fmt-table-types/index) |  Variable length CONNECT data files.  |
|  [CONNECT - NoSQL Table Types](../connect-nosql-table-types/index) |  Based on files that do not match the relational format but often represent hierarchical data.  |
|  [CONNECT - Files Retrieved Using Rest Queries](../connect-files-retrieved-using-rest-queries/index) |  JSON, XML and CSV data files can be retrieved as results from REST queries.  |
|  [CONNECT JSON Table Type](../connect-json-table-type/index) |  JSON (JavaScript Object Notation) is a widely-used lightweight data-interchange format.  |
|  [CONNECT XML Table Type](../connect-xml-table-type/index) |  CONNECT XML files  |
|  [CONNECT INI Table Type](../connect-ini-table-type/index) |  CONNECT INI Windows configuration or initialization files.  |
|  [CONNECT - External Table Types](../connect-external-table-types/index) |  Access tables belonging to the current or another server.  |
|  [CONNECT ODBC Table Type: Accessing Tables From Another DBMS](../connect-odbc-table-type-accessing-tables-from-another-dbms/index) |  CONNECT Table Types - ODBC Table Type: Accessing Tables from other DBMS  |
|  [CONNECT JDBC Table Type: Accessing Tables from Another DBMS](../connect-jdbc-table-type-accessing-tables-from-another-dbms/index) |  Using JDBC to access other tables.  |
|  [CONNECT MONGO Table Type: Accessing Collections from MongoDB](../connect-mongo-table-type/index) |  Used to directly access MongoDB collections as tables.  |
|  [CONNECT MYSQL Table Type: Accessing MySQL/MariaDB Tables](../connect-mysql-table-type-accessing-mysqlmariadb-tables/index) |  Accessing a MySQL or MariaDB table or view  |
|  [CONNECT PROXY Table Type](../connect-proxy-table-type/index) |  Tables that access and read the data of another table or view  |
|  [CONNECT XCOL Table Type](../connect-xcol-table-type/index) |  Based on another table/view, used when object tables have a column that contains a list of values  |
|  [CONNECT OCCUR Table Type](../connect-occur-table-type/index) |  Extension to the PROXY type when referring to a table/view having several c...  |
|  [CONNECT PIVOT Table Type](../connect-pivot-table-type/index) |  Transform the result of another table into another table along “pivot” and "fact" columns.  |
|  [CONNECT TBL Table Type: Table List](../connect-tbl-table-type-table-list/index) |  Define a table as a list of tables of any engine and type.  |
|  [CONNECT - Using the TBL and MYSQL Table Types Together](../connect-using-the-tbl-and-mysql-table-types-together/index) |  Used together, the TBL and MYSQL types lift all the limitations of the FEDERATED and MERGE engines  |
|  [CONNECT Table Types - Special "Virtual" Tables](../connect-table-types-special-virtual-tables/index) |  VIR, WMI and MAC special table types  |
|  [CONNECT Table Types - VIR](../connect-table-types-vir/index) |  VIR virtual type for CONNECT  |
|  [CONNECT Table Types - OEM: Implemented in an External LIB](../connect-table-types-oem/index) |  CONNECT OEM table types are implemented in an external library.  |
|  [CONNECT Table Types - Catalog Tables](../connect-table-types-catalog-tables/index) |  Catalog tables return information about another table or data source  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types/>

CONNECT - Files Retrieved Using Rest Queries
============================================

    Starting with [CONNECT version 1.07.0001](../connect/index), JSON, XML and possibly CSV data files can be retrieved as results from REST queries when creating or querying such tables. This is done internally by CONNECT using the CURL program generally available on all systems (if not just install it). 

 This can also be done using the Microsoft Casablanca (cpprestsdk) package. To enable it, first, install the package as explained in <https://github.com/microsoft/cpprestsdk>. Then make the GetRest library (dll or so) as explained in [Making the GetRest Library](../connect-making-the-getrest-library/index).

 Note: If both are available, cpprestsdk is used preferably because it is faster. This can be changed by specifying ‘curl=1’ in the option list. 

 Note: If you want to use this feature with an older distributed version of MariaDB not featuring REST, it is possible to add it as an OEM module as explained in [Adding the REST Feature as a Library Called by an OEM Table](../connect-making-the-getrest-library/index). 

 ### Creating Tables using REST

 To do so, specify the HTTP of the web client and eventually the URI of the request in the [CREATE TABLE](../create-table/index) statement. For example, for a query returning JSON data:

 
```
CREATE TABLE webusers (
  id bigint(2) NOT NULL,
  name char(24) NOT NULL,
  username char(16) NOT NULL,
  email char(25) NOT NULL,
  address varchar(256) DEFAULT NULL,
  phone char(21) NOT NULL,
  website char(13) NOT NULL,
  company varchar(256) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=utf8
TABLE_TYPE=JSON FILE_NAME='users.json' HTTP='http://jsonplaceholder.typicode.com' URI='/users';

```

As with standard JSON tables, discovery is possible, meaning that you can leave CONNECT to define the columns by analyzing the JSON file. Here you could just do:

 
```
CREATE TABLE webusers
ENGINE=CONNECT DEFAULT CHARSET=utf8
TABLE_TYPE=JSON FILE_NAME='users.json'
HTTP='http://jsonplaceholder.typicode.com' URI='/users';

```

For example, executing:

 
```
SELECT name, address FROM webusers2 LIMIT 1;

```

returns:

 


| name | address |
| --- | --- |
| Leanne Graham | Kulas Light Apt. 556 Gwenborough 92998-3874 -37.3159 81.1496 |

 
Here we see that for some complex elements such as *address*, which is a Json object containing values and objects, CONNECT by default has just listed their texts separated by blanks. But it is possible to ask it to analyze in more depth the json result by adding the DEPTH option. For instance:

 
```
CREATE OR REPLACE TABLE webusers
ENGINE=CONNECT DEFAULT CHARSET=utf8
TABLE_TYPE=JSON FILE_NAME='users.json'
HTTP='http://jsonplaceholder.typicode.com' URI='/users'
OPTION_LIST='Depth=2';

```

Then the table will be created as:

 
```
CREATE TABLE `webusers3` (
  `id` bigint(2) NOT NULL,
  `name` char(24) NOT NULL,
  `username` char(16) NOT NULL,
  `email` char(25) NOT NULL,
  `address_street` char(17) NOT NULL `JPATH`='$.address.street',
  `address_suite` char(9) NOT NULL `JPATH`='$.address.suite',
  `address_city` char(14) NOT NULL `JPATH`='$.address.city',
  `address_zipcode` char(10) NOT NULL `JPATH`='$.address.zipcode',
  `address_geo_lat` char(8) NOT NULL `JPATH`='$.address.geo.lat',
  `address_geo_lng` char(9) NOT NULL `JPATH`='$.address.geo.lng',
  `phone` char(21) NOT NULL,
  `website` char(13) NOT NULL,
  `company_name` char(18) NOT NULL `JPATH`='$.company.name',
  `company_catchPhrase` char(40) NOT NULL `JPATH`='$.company.catchPhrase',
  `company_bs` varchar(36) NOT NULL `JPATH`='$.company.bs'
) ENGINE=CONNECT DEFAULT CHARSET=utf8 `TABLE_TYPE`='JSON' `FILE_NAME`='users.json' `OPTION_LIST`='Depth=2' `HTTP`='http://jsonplaceholder.typicode.com' `URI`='/users';

```

Allowing one to get all the values of the Json result, for example:

 
```
SELECT name, address_city city, company_name company FROM webusers3;

```

That results in:

 


| name | city | company |
| --- | --- | --- |
| Leanne Graham | Gwenborough | Romaguera-Crona |
| Ervin Howell | Wisokyburgh | Deckow-Crist |
| Clementine Bauch McKenziehaven | Romaguera-Jacobson |
| Patricia Lebsack | South Elvis | Robel-Corkery |
| Chelsey Dietrich | Roscoeview | Keebler LLC |
| Mrs. Dennis Schulist | South Christy | Considine-Lockman |
| Kurtis Weissnat | Howemouth | Johns Group |
| Nicholas Runolfsdottir V | Aliyaview | Abernathy Group |
| Glenna Reichert | Bartholomebury | Yost and Sons |
| Clementina DuBuque | Lebsackbury | Hoeger LLC |

 
Of course, the complete create table (obtained by SHOW CREATE TABLE) can later be edited to make your table return exactly what you want to get. See the [JSON table type](../connect-json-table-type/index) for details about what and how to specify these.

 Note that such tables are read only. In addition, the data will be retrieved from the web each time you query the table with a [SELECT](../select/index) statement. This is fine if the result varies each time, such as when you query a weather forecasting site. But if you want to use the retrieved file many times without reloading it, just create another table on the same file without specifying the HTTP option.

 Note: For JSON tables, specifying the file name is optional and defaults to tabname.type. However, you should specify it if you want to use the file later for other tables.

 See the [JSON table type](../connect-json-table-type/index) for changes that will occur in the new CONNECT versions (distributed in early 2021).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-files-retrieved-using-rest-queries/>

CONNECT - NoSQL Table Types
===========================

    They are based on files that do not match the relational format but often represent hierarchical data. CONNECT can handle [JSON](../connect-json-table-type/index), [INI-CFG](../connect-ini-table-type/index), [XML](../connect-xml-table-type/index), and some HTML files.

 The way it is done is different from what MySQL or PostgreSQL does. In addition to including in a table some column values of a specific data format (JSON, XML) to be handled by specific functions, CONNECT can directly use JSON, XML or INI files that are produced by other applications, and this is the table definition that describes where and how the contained information must be retrieved.

 This is also different from what MariaDB does with dynamic columns, which is close to what MySQL and PostgreSQL do with the JSON column type.

 Note: The LEVEL option used with these tables should, from Connect 1.07.0002, be specified as DEPTH. Also, what was specified with the FIELD\_FORMAT column option should now also be specified using JPATH or XPATH.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-nosql-table-types/>

CONNECT INI Table Type
======================

    Overview
--------

 The INI type is one of the configuration or initialization files often found on Windows machines. For instance, let us suppose you have the following contact file *contact.ini*:

 
```
[BER]
name=Bertrand
forename=Olivier
address=21 rue Ferdinand Buisson
city=Issy-les-Mlx
zipcode=92130
tel=09.54.36.29.60
cell=06.70.06.04.16

[WEL]
name=Schmitt
forename=Bernard
hired=19/02/1985
address=64 tiergarten strasse
city=Berlin
zipcode=95013
tel=03.43.377.360

[UK1]
name=Smith
forename=Henry
hired=08/11/2003
address=143 Blum Rd.
city=London
zipcode=NW1 2BP

```

CONNECT lets you view it as a table in two different ways.

 Column layout
-------------

 The first way is to regard it as a table having one line per section, the columns being the keys you want to display. In this case, the CREATE statement could be:

 
```
create table contact (
  contact char(16) flag=1,
  name char(20),
  forename char(32),
  hired date date_format='DD/MM/YYYY',
  address char(64),
  city char(20),
  zipcode char(8),
  tel char(16))
engine=CONNECT table_type=INI file_name='contact.ini';

```

The column that will contain the section name can have any name but must specify `flag=1`. All other columns must have the names of the keys we want to display (case insensitive). The type can be character or numeric depending on the key value type, and the length is the maximum expected length for the key value. Once done, the statement:

 
```
select contact, name, hired, city, tel from contact;

```

This statement will display the file in tabular format.

 


| contact | name | hired | city | tel |
| --- | --- | --- | --- | --- |
| BER | Bertrand | 1970-01-01 | Issy-les-Mlx | 09.54.36.29.60 |
| WEL | Schmitt | 1985-02-19 | Berlin | 03.43.377.360 |
| UK1 | Smith | 2003-11-08 | London | NULL |

 
Only the keys defined in the create statements are visible; keys that do not exist in a section are displayed as null or pseudo null (blank for character, 1/1/70 for dates, and 0 for numeric) for columns declared NOT NULL.

 All relational operations can be applied to this table. The table (and the file) can be updated, inserted and conditionally deleted. The only constraint is that when inserting values, the section name must be the first in the list of values.

 **Note 1:** When inserting, if a section already exists, no new section will be created but the new values will be added or replace those of the existing section. Thus, the following two commands are equivalent:

 
```
update contact set forename = 'Harry' where contact = 'UK1';
insert into contact (contact,forename) values('UK1','Harry');

```

**Note 2:** Because sections represent one line, a DELETE statement on a section key will delete the whole section.

 Row layout
----------

 To be a good candidate for tabular representation, an INI file should have often the same keys in all sections. In practice, many files commonly found on computers, such as the *win.ini* file of the Windows directory or the *my.ini* file cannot be viewed that way because each section has different keys. In this case, a second way is to regard the file as a table having one row per section key and whose columns can be the section name, the key name, and the key value.

 For instance, let us define the table:

 
```
create table xcont (
  section char(16) flag=1,
  keyname char(16) flag=2,
  value char(32))
engine=CONNECT table_type=INI file_name='contact.ini'
option_list='Layout=Row';

```

In this statement, the "Layout" option sets the display format, Column by default or anything else not beginning by 'C' for row layout display. The names of the three columns can be freely chosen. The Flag option gives the meaning of the column. Specify `flag=1` for the section name and `flag=2` for the key name. Otherwise, the column will contain the key value.

 Once done, the command:

 
```
select * from xcont;

```

Will display the following result:

 


| section | keyname | value |
| --- | --- | --- |
| BER | name | Bertrand |
| BER | forename | Olivier |
| BER | address | 21 rue Ferdinand Buisson |
| BER | city | Issy-les-Mlx |
| BER | zipcode | 92130 |
| BER | tel | 09.54.36.29.60 |
| BER | cell | 06.70.06.04.16 |
| WEL | name | Schmitt |
| WEL | forename | Bernard |
| WEL | hired | 19/02/1985 |
| WEL | address | 64 tiergarten strasse |
| WEL | city | Berlin |
| WEL | zipcode | 95013 |
| WEL | tel | 03.43.377.360 |
| UK1 | name | Smith |
| UK1 | forename | Henry |
| UK1 | hired | 08/11/2003 |
| UK1 | address | 143 Blum Rd. |
| UK1 | city | London |
| UK1 | zipcode | NW1 2BP |

 
**Note:** When processing an INI table, all section names are retrieved in a buffer of 8K bytes (2048 bytes before 10.0.17). For a big file having many sections, this size can be increased using for example:

 
```
option_list='seclen=16K';

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-ini-table-type/>

CONNECT - External Table Types
==============================

    Because so many ODBC and JDBC drivers exist and only the main ones have been heavily tested, these table types cannot be ranked as stable. Use them with care in production applications.

 These types can be used to access tables belonging to the current or another database server. Six types are currently provided:

 [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index): To be used to access tables from a database management system providing an ODBC connector. ODBC is a standard of Microsoft and is currently available on Windows. On Linux, it can also be used provided a specific application emulating ODBC is installed. Currently only unixODBC is supported.

 [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index): To be used to access tables from a database management system providing a JDBC connector. JDBC is an Oracle standard implemented in Java and principally meant to be used by Java applications. Using it directly from C or C++ application seems to be almost impossible due to an Oracle bug still not fixed. However, this can be achieved using a Java wrapper class used as an interface between C++ and JDBC. On another hand, JDBC is available on all platforms and operating systems.

 [Mongo](../connect-mongo-table-type-accessing-collections-from-mongodb/index): To access MongoDB collections as tables via their MongoDB C Driver. Because this requires both MongoDB and the C Driver to be installed and operational, this table type is not currently available in binary distributions but only when compiling MariaDB from source.

 [MySQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index): This type is the preferred way to access tables belonging to another MySQL or MariaDB server. It uses the MySQL API to access the external table. Even though this can be obtained using the FEDERATED(X) plugin, this specific type is used internally by CONNECT because it also makes it possible to access tables belonging to the current server.

 [PROXY](mariadb/connect-table-types-proxy-table-type): Internally used by some table types to access other tables from one table.

 ### External Table Specification

 The four main external table types – odbc, jdbc, mongo and mysql – are specified giving the following information:

 1. The data source. This is specified in the connection option.
2. The remote table or view to access. This can be specified within the connection string or using specific CONNECT options.
3. The column definitions. This can be also left to CONNECT to find them using the discovery MariaDB feature.
4. The optional Quoted option. Can be set to 1 to quote the identifiers in the query sent to the remote server. This is required if columns or table names can contain blanks.

 The way this works is by establishing a connection to the external data source and by sending it an SQL statement (or its equivalent using API functions for MONGO) enabling it to execute the original query. To enhance performance, it is necessary to have the remote data source do the maximum processing. This is needed in particular to reduce the amount of data returned by the data source.

 This is why, for SELECT queries, CONNECT uses the [cond\_push](../using-connect-condition-pushdown/index) MariaDB feature to retrieve the maximum of the where clause of the original query that can be added to the query sent to the data source. This is automatic and does not require anything to be done by the user.

 However, more can be done. In addition to accessing a remote table, CONNECT offers the possibility to specify what the remote server must do. This is done by specifying it as a view in the srcdef option. For example:

 
```
CREATE TABLE custnum ENGINE=CONNECT TABLE_TYPE=XXX
CONNECTION='connecton string'
SRCDEF='select pays as country, count(*) as customers from custnum group by pays';

```

Doing so, the group by clause will be done by the remote server considerably reducing the amount of data sent back on the connection.

 This may even be increased by adding to the srcdef part of the “compatible” part of the query where clauses like this are done for table-based tables. Note that for MariaDB, this table has two columns, country and customers. Supposing the original query is:

 
```
SELECT * FROM custnum WHERE (country = 'UK' OR country = 'USA') AND customers > 5;

```

How can we make the where clause be added to the sent srcdef? There are many problems:

 1. Where to include the additional information.
2. What about the use of alias.
3. How to know what will be a where clause or a having clause.

 The first problem is solved by preparing the srcdef view to receive clauses. The above example srcdef becomes:

 
```
SRCDEF='select pays as country, count(*) as customers from custnum where %s group by pays having %s';

```

The *%s* in the srcdef are place holders for eventual compatible parts of the original query where clause. If the select query does not specify a where clause, or a gives an unacceptable where clause, place holders will be filled by dummy clauses (1=1).

 The other problems must be solved by adding to the create table a list of columns that must be translated because they are aliases or/and aliases on aggregate functions that must become a having clause. For example, in this case:

 
```
CREATE TABLE custnum ENGINE=CONNECT TABLE_TYPE=XXX
CONNECTION='connecton string'
SRCDEF='select pays as country, count(*) as customers from custnum where %s group by pays having %s'
OPTION_LIST='Alias=customers=*count(*);country=pays';

```

This is specified by the alias option, to be used in the option list. It is made of a semi-colon separated list of items containing:

 1. The local column name (alias in the remote server)
2. An equal sign.
3. An eventual ‘\*’ indicating this is column correspond to an aggregate function.
4. The remote column name.

 With this information, CONNECT will be able to make the query sent to the remote data source: 

 
```
select pays as country, count(*) as customers from custnum where (pays = 'UK' OR pays = 'USA') group by country having count(*) > 5

```

Note: Some data sources, including MySQL and MariaDB, accept aliases in the having clause. In that case, the alias option could have been specified as:

 
```
OPTION_LIST='Alias=customers=*;country=pays';

```

Another option exists, phpos, enabling to specify what place holders are present and in what order. To be specified as “W”, “WH”, “H”, or “HW”. It is rarely used because by default CONNECT can set it from the srcdef content. The only cases it is needed is when the srcdef contains only a having place holder or when the having place holder occurs before the where place holder, which can occur on queries containing joins. CONNECT cannot handle more than one place holder of each type.

 SRCDEF is not available for MONGO tables, but other ways of achieving this exist and are described in the MONGO table type chapter.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-external-table-types/>

CONNECT XML Table Type
======================

    Overview
--------

 CONNECT supports tables represented by XML files. For these tables, the standard input/output functions of the operating system are not used but the parsing and processing of the file is delegated to a specialized library. Currently two such systems are supported: libxml2, a part of the GNOME framework, but which does not require GNOME and, on Windows, MS-DOM (DOMDOC), the Microsoft standard support of XML documents.

 DOMDOC is the default for the Windows version of CONNECT and libxml2 is always used on other systems. On Windows the choice can be specified using the XMLSUP [CREATE TABLE](../create-table/index) list option, for instance specifying `option_list='xmlsup=libxml2'`.

 Creating XML tables
-------------------

 First of all, it must be understood that XML is a very general language used to encode data having any structure. In particular, the tag hierarchy in an XML file describes a tree structure of the data. For instance, consider the file:

 
```
<?xml version="1.0" encoding="ISO-8859-1"?>
<BIBLIO SUBJECT="XML">
   <BOOK ISBN="9782212090819" LANG="fr" SUBJECT="applications">
      <AUTHOR>
         <FIRSTNAME>Jean-Christophe</FIRSTNAME>
         <LASTNAME>Bernadac</LASTNAME>
      </AUTHOR>
      <AUTHOR>
         <FIRSTNAME>François</FIRSTNAME>
         <LASTNAME>Knab</LASTNAME>
      </AUTHOR>
      <TITLE>Construire une application XML</TITLE>
      <PUBLISHER>
         <NAME>Eyrolles</NAME>
         <PLACE>Paris</PLACE>
      </PUBLISHER>
      <DATEPUB>1999</DATEPUB>
   </BOOK>
   <BOOK ISBN="9782840825685" LANG="fr" SUBJECT="applications">
      <AUTHOR>
         <FIRSTNAME>William J.</FIRSTNAME>
         <LASTNAME>Pardi</LASTNAME>
      </AUTHOR>
      <TRANSLATOR PREFIX="adapté de l'anglais par">
         <FIRSTNAME>James</FIRSTNAME>
         <LASTNAME>Guerin</LASTNAME>
      </TRANSLATOR>
      <TITLE>XML en Action</TITLE>
      <PUBLISHER>
         <NAME>Microsoft Press</NAME>
         <PLACE>Paris</PLACE>
      </PUBLISHER>
      <DATEPUB>1999</DATEPUB>
   </BOOK>
</BIBLIO>

```

It represents data having the structure:

 
```
                               <BIBLIO>
                        __________|_________
                       |                    |
            <BOOK:ISBN,LANG,SUBJECT>        |
         ______________|_______________     |
        |        |         |           |    |
     <AUTHOR> <TITLE> <PUBLISHER> <DATEPUB> |
    ____|____            ___|____           |
   |    |    |          |        |          |
<FIRST> | <LAST>     <NAME>   <PLACE>       |
        |                                   |
     <AUTHOR>                   <BOOK:ISBN,LANG,SUBJECT>
    ____|____         ______________________|__________________
   |         |       |            |         |        |         |
<FIRST>   <LAST>  <AUTHOR> <TRANSLATOR> <TITLE> <PUBLISHER> <DATEPUB>
                _____|_        ___|___            ___|____
               |       |      |       |          |        |
            <FIRST> <LAST> <FIRST> <LAST>     <NAME>   <PLACE>

```

This structure seems at first view far from being tabular. However, modern database management systems, including MariaDB, implement something close to the relational model and work on tables that are structurally not hierarchical but tabular with rows and columns.

 Nevertheless, CONNECT can do it. Of course, it cannot guess what you want to extract from the XML structure, but gives you the possibility to specify it when you create the table[[1](#_note-0)].

 Let us take a first example. Suppose you want to make a table from the above document, displaying the node contents.

 For this, you can define a table *xsamptag* as:

 
```
create table xsamptag (
  AUTHOR char(50),
  TITLE char(32),
  TRANSLATOR char(40),
  PUBLISHER char(40),
  DATEPUB int(4))
engine=CONNECT table_type=XML file_name='Xsample.xml';

```

It will be displayed as:

 


| AUTHOR | TITLE | TRANSLATOR | PUBLISHER | DATEPUB |
| --- | --- | --- | --- | --- |
| Jean-Christophe Bernadac | Construire une application XML | <null> | Eyrolles Paris | 1999 |
| William J. Pardi | XML en Action | James Guerin | Microsoft Press Paris | 1999 |

 
Let us try to understand what happened. By default the column names correspond to tag names. Because this file is rather simple, CONNECT was able to default the top tag of the table as the root node `<BIBLIO>` of the file, and the row tags as the `<BOOK>` children of the table tag. In a more complex file, this should have been specified, as we will see later. Note that we didn't have to worry about the sub-tags such as `<FIRSTNAME>` or `<LASTNAME>` because CONNECT automatically retrieves the entire text contained in a tag and its sub-tags[[2](#_note-1)].

 
Only the first author of the first book appears. This is because only the first occurrence of a column tag has been retrieved so the result has a proper tabular structure. We will see later what we can do about that.

 
How can we retrieve the values specified by attributes? By using a *Coltype* table option to specify the default column type. The value ‘@’ means that column names match attribute names. Therefore, we can retrieve them by creating a table such as:

 
```
create table xsampattr (
  ISBN char(15),
  LANG char(2),
  SUBJECT char(32))
engine=CONNECT table_type=XML file_name='Xsample.xml'
option_list='Coltype=@';

```

This table returns the following:

 


| ISBN | LANG | SUBJECT |
| --- | --- | --- |
| 9782212090819 | fr | applications |
| 9782840825685 | fr | applications |

 
Now to define a table that will give us all the previous information, we must specify the column type for each column. Because in the next statement the column type defaults to Node, the *field\_format* column parameter was used to indicate which columns are attributes:

 From Connect 1.7.0002

 
```
create table xsamp (
ISBN char(15) xpath='@',
LANG char(2) xpath='@',
SUBJECT char(32) xpath='@',
AUTHOR char(50),
TITLE char(32),
TRANSLATOR char(40),
PUBLISHER char(40),
DATEPUB int(4))
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK';

```

Before Connect 1.7.0002

 
```
create table xsamp (
  ISBN char(15) field_format='@',
  LANG char(2) field_format='@',
  SUBJECT char(32) field_format='@',
  AUTHOR char(50),
  TITLE char(32),
  TRANSLATOR char(40),
  PUBLISHER char(40),
  DATEPUB int(4))
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK';

```

Once done, we can enter the query:

 
```
select subject, lang, title, author from xsamp;

```

This will return the following result:

 


| SUBJECT | LANG | TITLE | AUTHOR |
| --- | --- | --- | --- |
| applications | fr | Construire une application XML | Jean-Christophe Bernadac |
| applications | fr | XML en Action | William J. Pardi |

 
Note that we have been lucky. Because unlike SQL, XML is case sensitive and the column names have matched the node names only because the column names were given in upper case. Note also that the order of the columns in the table could have been different from the order in which the nodes appear in the XML file.

 Using Xpaths with XML tables
----------------------------

 Xpath is used by XML to locate and retrieve nodes. The table's main node Xpath is specified by the `tabname` option. If just the node name is given, CONNECT constructs an Xpath such as `‘*BIBLIO’*` in the example above that should retrieve the `BIBLIO` node wherever it is within the XML file. 

 The row nodes are by default the children of the table node. However, for instance to eliminate some children nodes that are not real row nodes, the row node name can be specified using the `rownode` sub-option of the `option_list` option.

 The field\_format options we used above can be specified to locate more precisely where and what information to retrieve using an Xpath-like syntax. For instance:

 From Connect 1.7.0002

 
```
create table xsampall (
isbn char(15) xpath='@ISBN',
language char(2) xpath='@LANG',
subject char(32) xpath='@SUBJECT',
authorfn char(20) xpath='AUTHOR/FIRSTNAME',
authorln char(20) xpath='AUTHOR/LASTNAME',
title char(32) xpath='TITLE',
translated char(32) xpath='TRANSLATOR/@PREFIX',
tranfn char(20) xpath='TRANSLATOR/FIRSTNAME',
tranln char(20) xpath='TRANSLATOR/LASTNAME',
publisher char(20) xpath='PUBLISHER/NAME',
location char(20) xpath='PUBLISHER/PLACE',
year int(4) xpath='DATEPUB')
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK';

```

Before Connect 1.7.0002

 
```
create table xsampall (
  isbn char(15) field_format='@ISBN',
  language char(2) field_format='@LANG',
  subject char(32) field_format='@SUBJECT',
  authorfn char(20) field_format='AUTHOR/FIRSTNAME',
  authorln char(20) field_format='AUTHOR/LASTNAME',
  title char(32) field_format='TITLE',
  translated char(32) field_format='TRANSLATOR/@PREFIX',
  tranfn char(20) field_format='TRANSLATOR/FIRSTNAME',
  tranln char(20) field_format='TRANSLATOR/LASTNAME',
  publisher char(20) field_format='PUBLISHER/NAME',
  location char(20) field_format='PUBLISHER/PLACE',
  year int(4) field_format='DATEPUB')
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK';

```

This very flexible column parameter serves several purposes:

 * To specify the tag name, or the attribute name if different from the column name.
* To specify the type (tag or attribute) by a prefix of '@' for attributes.
* To specify the path for sub-tags using the '/' character.

 This path is always relative to the current context (the column top node) and cannot be specified as an absolute path from the document root, therefore a leading '/' cannot be used. The path cannot be variable in node names or depth, therefore using '`//`' is not allowed.

 The query:

 
```
select isbn, title, translated, tranfn, tranln, location from
    xsampall where translated is not null;

```

replies:

 


| ISBN | TITLE | TRANSLATED | TRANFN | TRANLN | LOCATION |
| --- | --- | --- | --- | --- | --- |
| 9782840825685 | XML en Action | adapté de l'anglais par | James | Guerin | Paris |

 
### Libxml2 default name space issue

 An issue with libxml2 is that some files can declare a default name space in their root node. Because Xpath only searches in that name space, the nodes will not be found if they are not prefixed. If this happens, specify the tabname option as an Xpath ignoring the current name space:

 
```
TABNAME="//*[local-name()='BIBLIO']"

```

This must also be done for the default of specified Xpath of the not attribute columns. For instance:

 
```
title char(32) field_format="*[local-name()='TITLE']",

```

Note: This raises an error (and is useless anyway) with DOMDOC.

 ### Direct access on XML tables

 Direct access is available on XML tables. This means that XML tables can be sorted and used in joins, even in the one-side of the join.

 However, building a permanent index is not yet implemented. It is unclear whether this can be useful. Indeed, the DOM implementation that is used to access these tables firstly parses the whole file and constructs a node tree in memory. This may often be the longest part of the process, so the use of an index would not be of great value. Note also that this limits the XML files to a reasonable size. Anyway, when speed is important, this table type is not the best to use. Therefore, in these cases, it is probably better to convert the file to another type by inserting the XML table into another table of a more appropriate type for performance.

 ### Accessing tags with namespaces

 With the Windows DOMDOC support, this can be done using the prefix in the tabname column option and/or xpath column option. For instance, given the file gns.xml:

 
```
<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns:gns="http:dummy">
<gns:trkseg>
<trkpt lon="-121.9822235107421875" lat="37.3884925842285156">
<gns:ele>6.610851287841797</gns:ele>
<time>2014-04-01T14:54:05.000Z</time>
</trkpt>
<trkpt lon="-121.9821929931640625" lat="37.3885803222656250">
<ele>6.787827968597412</ele>
<time>2014-04-01T14:54:08.000Z</time>
</trkpt>
<trkpt lon="-121.9821624755859375" lat="37.3886299133300781">
<ele>6.771987438201904</ele>
<time>2014-04-01T14:54:10.000Z</time>
</trkpt>
</gns:trkseg>
</gpx>

```

and the defined CONNECT table:

 
```
CREATE TABLE xgns (
`lon` double(21,16) NOT NULL `xpath`='@',
`lat` double(20,16) NOT NULL `xpath`='@',
`ele` double(21,16) NOT NULL `xpath`='gns:ele',
`time` datetime date_format="YYYY-MM-DD 'T' hh:mm:ss '.000Z'"
) 
  ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=XML 
  `file_name`='gns.xml' tabname='gns:trkseg' option_list='xmlsup=domdoc';

```


```
select * from xgns;

```

Displays:

 


| lon | lat | ele | time |
| --- | --- | --- | --- |
| -121,982223510742 | 37,3884925842285 | 6,6108512878418 | 01/04/2014 14:54:05 |
| -121,982192993164 | 37,3885803222656 | 0 | 01/04/2014 14:54:08 |
| -121,982162475586 | 37,3886299133301 | 0 | 01/04/2014 14:54:10 |

 
Only the prefixed ‘ele’ tag is recognized.

 However, this does not work with the libxml2 support. The solution is then to use a function ignoring the name space:

 
```
CREATE TABLE xgns2 (
`lon` double(21,16) NOT NULL `xpath`='@',
`lat` double(20,16) NOT NULL `xpath`='@',
`ele` double(21,16) NOT NULL `xpath`="*[local-name()='ele']",
`time` datetime date_format="YYYY-MM-DD 'T' hh:mm:ss '.000Z'"
) 
  ENGINE=CONNECT DEFAULT CHARSET=latin1 `table_type`=XML 
  `file_name`='gns.xml' tabname="*[local-name()='trkseg']" option_list='xmlsup=libxml2';

```

Then :

 
```
select * from xgns2;

```

Displays:

 


| lon | lat | ele | time |
| --- | --- | --- | --- |
| -121,982223510742 | 37,3884925842285 | 6,6108512878418 | 01/04/2014 14:54:05 |
| -121,982192993164 | 37,3885803222656 | 6.7878279685974 | 01/04/2014 14:54:08 |
| -121,982162475586 | 37,3886299133301 | 6.7719874382019 | 01/04/2014 14:54:10 |

 
This time, all ‘ele` tags are recognized. This solution does not work with DOMDOC.

 Having Columns defined by Discovery
-----------------------------------

 It is possible to let the MariaDB discovery process do the job of column specification. When columns are not defined in the [CREATE TABLE](../create-table/index) statement, CONNECT endeavours to analyze the XML file and to provide the column specifications. This is possible only for true XML tables, but not for HTML tables.

 For instance, the *xsamp* table could have been created specifying:

 
```
create table xsamp
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK';

```

Let’s check how it was actually specified using the SHOW CREATE TABLE statement:

 
```
CREATE TABLE `xsamp` (
  `ISBN` char(13) NOT NULL `FIELD_FORMAT`='@',
  `LANG` char(2) NOT NULL `FIELD_FORMAT`='@',
  `SUBJECT` char(12) NOT NULL `FIELD_FORMAT`='@',
  `AUTHOR` char(24) NOT NULL,
  `TRANSLATOR` char(12) DEFAULT NULL,
  `TITLE` char(30) NOT NULL,
  `PUBLISHER` char(21) NOT NULL,
  `DATEPUB` char(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='XML' 
  `FILE_NAME`='E:/Data/Xml/Xsample.xml' `TABNAME`='BIBLIO' `OPTION_LIST`='rownode=BOOK';

```

It is equivalent except for the column sizes that have been calculated from the file as the maximum length of the corresponding column when it was a normal value. Also, all columns are specified as type [CHAR](../char/index) because XML does not provide information about the node content data type. Nullable is set to true if the column is missing in some rows.

 If a more complex definition is desired, you can ask CONNECT to analyse the XPATH up to a given level using the level option in the option list. The level value is the number of nodes that are taken in the XPATH. For instance:

 
```
create table xsampall
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK,Level=1';

```

This will define the table as:

 From Connect 1.7.0002

 
```
CREATE TABLE `xsampall` (
  `ISBN` char(13) NOT NULL `XPATH`='@',
  `LANG` char(2) NOT NULL `XPATH`='@',
  `SUBJECT` char(12) NOT NULL `XPATH`='@',
  `AUTHOR_FIRSTNAME` char(15) NOT NULL `XPATH`='AUTHOR/FIRSTNAME',
  `AUTHOR_LASTNAME` char(8) NOT NULL `XPATH`='AUTHOR/LASTNAME',
  `TRANSLATOR_PREFIX` char(24) DEFAULT NULL `XPATH`='TRANSLATOR/@PREFIX',
  `TRANSLATOR_FIRSTNAME` char(7) DEFAULT NULL `XPATH`='TRANSLATOR/FIRSTNAME',
  `TRANSLATOR_LASTNAME` char(6) DEFAULT NULL `XPATH`='TRANSLATOR/LASTNAME',
  `TITLE` char(30) NOT NULL,
  `PUBLISHER_NAME` char(15) NOT NULL `XPATH`='PUBLISHER/NAME',
  `PUBLISHER_PLACE` char(5) NOT NULL `XPATH`='PUBLISHER/PLACE',
  `DATEPUB` char(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='XML' `FILE_NAME`='Xsample.xml' `TABNAME`='BIBLIO' `OPTION_LIST`='rownode=BOOK,Depth=1';
<</sql>>


Before Connect 1.7.0002
<<sql>>
CREATE TABLE `xsampall` (
  `ISBN` char(13) NOT NULL `FIELD_FORMAT`='@',
  `LANG` char(2) NOT NULL `FIELD_FORMAT`='@',
  `SUBJECT` char(12) NOT NULL `FIELD_FORMAT`='@',
  `AUTHOR_FIRSTNAME` char(15) NOT NULL `FIELD_FORMAT`='AUTHOR/FIRSTNAME',
  `AUTHOR_LASTNAME` char(8) NOT NULL `FIELD_FORMAT`='AUTHOR/LASTNAME',
  `TRANSLATOR_PREFIX` char(24) DEFAULT NULL `FIELD_FORMAT`='TRANSLATOR/@PREFIX',
  `TRANSLATOR_FIRSTNAME` char(7) DEFAULT NULL `FIELD_FORMAT`='TRANSLATOR/FIRSTNAME',
  `TRANSLATOR_LASTNAME` char(6) DEFAULT NULL `FIELD_FORMAT`='TRANSLATOR/LASTNAME',
  `TITLE` char(30) NOT NULL,
  `PUBLISHER_NAME` char(15) NOT NULL `FIELD_FORMAT`='PUBLISHER/NAME',
  `PUBLISHER_PLACE` char(5) NOT NULL `FIELD_FORMAT`='PUBLISHER/PLACE',
  `DATEPUB` char(4) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='XML' `FILE_NAME`='Xsample.xml' 
  `TABNAME`='BIBLIO' `OPTION_LIST`='rownode=BOOK,Level=1';
<</sql>>

This method can be used as a quick way to make a “template” table definition that can later be edited to make the desired definition. In particular, column names are constructed from all the nodes of their path in order to have distinct column names. This can be manually edited to have the desired names, provided their XPATH is not modified.

To have a preview of how columns will be defined, you can use a catalog table like this:

<<sql>>
create table xsacol
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK,Level=1' catfunc=col;
<</sql>>

And when asking:

<<sql>>
select column_name Name, type_name Type, column_size Size, nullable, xpath from xsacol;
<</sql>>

You get the description of what the table columns will be:

<<style class="darkheader-nospace-borders">>
|= Name |= Type |= Size |= nullable |= xpath |
| ISBN | CHAR | 13 | 0 | @ | 
| LANG | CHAR | 2 | 0 | @ |
| SUBJECT | CHAR | 12 | 0 | @ |
| AUTHOR_FIRSTNAME | CHAR | 15 | 0 | AUTHOR/FIRSTNAME | 
| AUTHOR_LASTNAME | CHAR | 8 | 0 | AUTHOR/LASTNAME | 
| TRANSLATOR_PREFIX | CHAR | 24 | 1 | TRANSLATOR/@PREFIX | 
| TRANSLATOR_FIRSTNAME | CHAR | 7 | 1 | TRANSLATOR/FIRSTNAME |
| TRANSLATOR_LASTNAME | CHAR | 6 | 1 | TRANSLATOR/LASTNAME | 
| TITLE | CHAR | 30 | 0 |  | 
| PUBLISHER_NAME | CHAR | 15 | 0 | PUBLISHER/NAME |
| PUBLISHER_PLACE | CHAR | 5 | 0 | PUBLISHER/PLACE |
| DATEPUB | CHAR | 4 | 0 | |
<</style>>

== Write operations on XML tables
You can freely use the Update, Delete and Insert commands with XML tables.
However, you must understand that the format of the updated or inserted data
follows the specifications of the table you created, not the ones of the
original source file. For instance, let us suppose we insert a new book using
the //xsamp// table (not the //xsampall// table) with the command:

<<code lang=mysql inline=false>>
insert into xsamp
  (isbn, lang, subject, author, title, publisher,datepub)
  values ('9782212090529','fr','général','Alain Michard',
         'XML, Langage et Applications','Eyrolles Paris',1998);

```

Then if we ask:

 
```
select subject, author, title, translator, publisher from xsamp;

```

Everything seems correct when we get the result:

 


| SUBJECT | AUTHOR | TITLE | TRANSLATOR | PUBLISHER |
| --- | --- | --- | --- | --- |
| applications | Jean-Christophe Bernadac | Construire une application XML |  | Eyrolles Paris |
| applications | William J. Pardi | XML en Action | James Guerin | Microsoft Press Paris |
| général | Alain Michard | XML, Langage et Applications |  | Eyrolles Paris |

 
However if we enter the apparently equivalent query on the *xsampall* table, based on the same file:

 
```
select subject,
concat(authorfn, ' ', authorln) author , title,
concat(tranfn, ' ', tranln) translator,
concat(publisher, ' ', location) publisher from xsampall;

```

this returns an apparently wrong answer:

 


| SUBJECT | AUTHOR | TITLE | TRANSLATOR | PUBLISHER |
| --- | --- | --- | --- | --- |
| applications | Jean-Christophe Bernadac | Construire une application XML |  | Eyrolles Paris |
| applications | William J. Pardi | XML en Action | James Guerin | Microsoft Press Paris |
| général |  | XML, Langage et Applications |  |  |

 
What happened here? Simply, because we used the *xsamp* table to do the Insert, what has been inserted within the XML file had the structure described for *xsamp*:

 
```
   <BOOK ISBN="9782212090529" LANG="fr" SUBJECT="général">
      <AUTHOR>Alain Michard</AUTHOR>
      <TITLE>XML, Langage et Applications</TITLE>
      <TRANSLATOR></TRANSLATOR>
      <PUBLISHER>Eyrolles Paris</PUBLISHER>
      <DATEPUB>1998</DATEPUB>
   </BOOK>

```

CONNECT cannot "invent" sub-tags that are not part of the *xsamp* table. Because these sub-tags do not exist, the *xsampall* table cannot retrieve the information that should be attached to them. If we want to be able to query the XML file by all the defined tables, the correct way to insert a new book to the file is to use the *xsampall* table, the only one that addresses all the components of the original document:

 
```
delete from xsamp where isbn = '9782212090529';

insert into xsampall (isbn, language, subject, authorfn, authorln,
      title, publisher, location, year)
   values('9782212090529','fr','général','Alain','Michard',
      'XML, Langage et Applications','Eyrolles','Paris',1998);

```

Now the added book, in the XML file, will have the required structure:

 
```
   <BOOK ISBN="9782212090529" LANG="fr" SUBJECT="général">
      <AUTHOR>
         <FIRSTNAME>Alain</FIRSTNAME>
         <LASTNAME>Michard</LASTNAME>
      </AUTHOR>
      <TITLE>XML, Langage et Applications</TITLE>
      <PUBLISHER>
         <NAME>Eyrolles</NAME>
         <PLACE>Paris</PLACE>
      </PUBLISHER>
      <DATEPUB>1998</DATEPUB>
   </BOOK>

```

**Note:** We used a column list in the Insert statements when creating the table to avoid generating a `<TRANSLATOR>` node with sub-nodes, all containing null values (this works on Windows only).

 Multiple nodes in the XML document
----------------------------------

 Let us come back to the above example XML file. We have seen that the author node can be "multiple" meaning that there can be more than one author of a book. What can we do to get the complete information fitting the relational model? CONNECT provides you with two possibilities, but is restricted to only one such multiple node per table.

 The first and most challenging one is to return as many rows than there are authors, the other columns being repeated as if we had make a join between the author column and the rest of the table. To achieve this, simply specify the “multiple” node name and the “expand” option when creating the table. For instance, we can create the *xsamp2* table like this:

 
```
create table xsamp2 (
  ISBN char(15) field_format='@',
  LANG char(2) field_format='@',
  SUBJECT char(32) field_format='@',
  AUTHOR char(40),
  TITLE char(32),
  TRANSLATOR char(32),
  PUBLISHER char(32),
  DATEPUB int(4))
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO'
option_list='rownode=BOOK,Expand=1,Mulnode=AUTHOR,Limit=2';

```

In this statement, the Limit option specifies the maximum number of values that will be expanded. If not specified, it defaults to `10`. Any values above the limit will be ignored and a warning message issued[[3](#_note-2)]. Now you can enter a query such as:

 
```
select isbn, subject, author, title from xsamp2;

```

This will retrieve and display the following result:

 


| ISBN | SUBJECT | AUTHOR | TITLE |
| --- | --- | --- | --- |
| 9782212090819 | applications | Jean-Christophe Bernadac | Construire une application XML |
| 9782212090819 | applications | François Knab | Construire une application XML |
| 9782840825685 | applications | William J. Pardi | XML en Action |
| 9782212090529 | général | Alain Michard | XML, Langage et Applications |

 
In this case, this is as if the table had four rows. However if we enter the query:

 
```
select isbn, subject, title, publisher from xsamp2;

```

this time the result will be:

 


| ISBN | SUBJECT | TITLE | PUBLISHER |
| --- | --- | --- | --- |
| 9782212090819 | applications | Construire une application XML | Eyrolles Paris |
| 9782840825685 | applications | XML en Action | Microsoft Press Paris |
| 9782212090529 | général | XML, Langage et Applications | Eyrolles Paris |

 
Because the author column does not appear in the query, the corresponding row was not expanded. This is somewhat strange because this would have been different if we had been working on a table of a different type. However, it is closer to the relational model for which there should not be two identical rows (tuples) in a table. Nevertheless, you should be aware of this somewhat erratic behavior. For instance:

 
```
select count(*) from xsamp2;                /* Replies 3 */
select count(author) from xsamp2;           /* Replies 4 */
select count(isbn) from xsamp2;             /* Replies 3 */
select isbn, subject, title, publisher from xsamp2 where author <> '';

```

This last query replies:

 


| ISBN | SUBJECT | TITLE | PUBLISHER |
| --- | --- | --- | --- |
| 9782212090819 | applications | Construire une application XML | Eyrolles Paris |
| 9782212090819 | applications | Construire une application XML | Eyrolles Paris |
| 9782840825685 | applications | XML en Action | Microsoft Press Paris |
| 9782212090529 | général | XML, Langage et Applications | Eyrolles Paris |

 
Even though the author column does not appear in the result, the corresponding row was expanded because the multiple column was used in the where clause.

 Intermediate multiple node
--------------------------

 The "multiple" node can be an intermediate node. If we want to do the same expanding with the *xsampall* table, there will be nothing more to do. The *xsampall2* table can be created with:

 From Connect 1.7.0002

 
```
create table xsampall2 (
isbn char(15) xpath='@ISBN',
language char(2) xpath='@LANG',
subject char(32) xpath='@SUBJECT',
authorfn char(20) xpath='AUTHOR/FIRSTNAME',
authorln char(20) xpath='AUTHOR/LASTNAME',
title char(32) xpath='TITLE',
translated char(32) xpath='TRANSLATOR/@PREFIX',
tranfn char(20) xpath='TRANSLATOR/FIRSTNAME',
tranln char(20) xpath='TRANSLATOR/LASTNAME',
publisher char(20) xpath='PUBLISHER/NAME',
location char(20) xpath='PUBLISHER/PLACE',
year int(4) xpath='DATEPUB')
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO' option_list='rownode=BOOK,Expand=1,Mulnode=AUTHOR,Limit=2';

```

Before Connect 1.7.0002

 
```
create table xsampall2 (
  isbn char(15) field_format='@ISBN',
  language char(2) field_format='@LANG',
  subject char(32) field_format='@SUBJECT',
  authorfn char(20) field_format='AUTHOR/FIRSTNAME',
  authorln char(20) field_format='AUTHOR/LASTNAME',
  title char(32) field_format='TITLE',
  translated char(32) field_format='TRANSLATOR/@PREFIX',
  tranfn char(20) field_format='TRANSLATOR/FIRSTNAME',
  tranln char(20) field_format='TRANSLATOR/LASTNAME',
  publisher char(20) field_format='PUBLISHER/NAME',
  location char(20) field_format='PUBLISHER/PLACE',
  year int(4) field_format='DATEPUB')
engine=CONNECT table_type=XML file_name='Xsample.xml'
tabname='BIBLIO'
option_list='rownode=BOOK,Expand=1,Mulnode=AUTHOR,Limit=2';

```

The only difference is that the "multiple" node is an intermediate node in the path. The resulting table can be seen with a query such as:

 
```
select subject, language lang, title, authorfn first, authorln
    last, year from xsampall2;

```

This query displays:

 


| SUBJECT | LANG | TITLE | FIRST | LAST | YEAR |
| --- | --- | --- | --- | --- | --- |
| applications | fr | Construire une application XML | Jean-Christophe | Bernadac | 1999 |
| applications | fr | Construire une application XML | François | Knab | 1999 |
| applications | fr | XML en Action | William J. | Pardi | 1999 |
| général | fr | XML, Langage et Applications | Alain | Michard | 1998 |

 
These composite tables, half array half tree, reserve some surprises for us when updating, deleting from or inserting into them. Insert just cannot generate this structure; if two rows are inserted with just a different author, two book nodes will be generated in the XML file. Delete always deletes one book node and all its children nodes even if specified against only one author. Update is more complicated:

 
```
update xsampall2 set authorfn = 'Simon' where authorln = 'Knab';
update xsampall2 set year = 2002 where authorln = 'Bernadac';
update xsampall2 set authorln = 'Mercier' where year = 2002;

```

After these three updates, the first two responding "Affected rows: 1" and the last one responding "Affected rows: 2", the last query answers:

 


| subject | lang | title | first | last | year |
| --- | --- | --- | --- | --- | --- |
| applications | fr | Construire une application XML | Jean-Christophe | Mercier | 2002 |
| applications | fr | Construire une application XML | François | Knab | 2002 |
| applications | fr | XML en Action | William J. | Pardi | 1999 |
| général | fr | XML, Langage et Applications | Alain | Michard | 1998 |

 
What must be understood here is that the Update modifies node values in the XML file, not cell values in the relational table. The first update worked normally. The second update changed the year value of the book and this shows for the two expanded rows because there is only one DATEPUB node for that book. Because the third update applies to a row having a certain date value, both author names were updated.

 Making a List of Multiple Values
--------------------------------

 Another way to see multiple values is to ask CONNECT to make a comma separated list of the multiple node values. This time, it can only be done if the "multiple" node is not intermediate. For example, we can modify the *xsamp2* table definition by:

 
```
alter table xsamp2 option_list='rownode=BOOK,Mulnode=AUTHOR,Limit=3';

```

This time 'Expand' is not specified, and Limit gives the maximum number of items in the list. Now if we enter the query:

 
```
select isbn, subject, author "AUTHOR(S)", title from xsamp2;

```

We will get the following result:

 


| ISBN | SUBJECT | AUTHOR(S) | TITLE |
| --- | --- | --- | --- |
| 9782212090819 | applications | Jean-Christophe Bernadac, François Knab | Construire une application XML |
| 9782840825685 | applications | William J. Pardi | XML en Action |
| 9782212090529 | général | Alain Michard | XML, Langage et Applications |

 
Note that updating the "multiple" column is not possible because CONNECT does not know which of the nodes to update.

 This could not have been done with the *xsampall2* table because the author node is intermediate in the path, and making two lists, one of first names and another one of last names would not make sense anyway.

 ### What if a table contains several multiple nodes

 This can be handled by creating several tables on the same file, each containing only one multiple node and constructing the desired result using joins.

 Support of HTML Tables
----------------------

 Most tables included in HTML documents cannot be processed by CONNECT because the HTML language is often not compatible with the syntax of XML. In particular, XML requires all open tags to be matched by a closing tag while it is sometimes optional in HTML. This is often the case concerning column tags.

 However, you can meet tables that respect the XML syntax but have some of the features of HTML tables. For instance:

 
```
<?xml version="1.0"?>
<Beers>
  <table>
    <th><td>Name</td><td>Origin</td><td>Description</td></th>
    <tr>
      <td><brandName>Huntsman</brandName></td>
      <td><origin>Bath, UK</origin></td>
      <td><details>Wonderful hop, light alcohol</details></td>
    </tr>
    <tr>
      <td><brandName>Tuborg</brandName></td>
      <td><origin>Danmark</origin></td>
      <td><details>In small bottles</details></td>
    </tr>
  </table>
</Beers>

```

Here the different column tags are included in `<td></td>` tags as for HTML tables. You cannot just add this tag in the Xpath of the columns, because the search is done on the first occurrence of each tag, and this would cause this search to fail for all columns except the first one. This case is handled by specifying the *Colnode* table option that gives the name of these column tags, for example:

 From Connect 1.7.0002

 
```
create table beers (
`Name` char(16) xpath='brandName',
`Origin` char(16) xpath='origin',
`Description` char(32) xpath='details')
engine=CONNECT table_type=XML file_name='beers.xml'
tabname='table' option_list='rownode=tr,colnode=td';

```

Before Connect 1.7.0002

 
```
create table beers (
  `Name` char(16) field_format='brandName',
  `Origin` char(16) field_format='origin',
  `Description` char(32) field_format='details')
engine=CONNECT table_type=XML file_name='beers.xml'
tabname='table' option_list='rownode=tr,colnode=td';

```

The table will be displayed as:

 


| Name | Origin | Description |
| --- | --- | --- |
| Huntsman | Bath, UK | Wonderful hop, light alcohol |
| Tuborg | Danmark | In small bottles |

 
However, you can deal with tables even closer to the HTML model. For example the *coffee.htm* file:

 
```
<TABLE summary="This table charts the number of cups of coffe
                consumed by each senator, the type of coffee (decaf
                or regular), and whether taken with sugar.">
  <CAPTION>Cups of coffee consumed by each senator</CAPTION>
  <TR>
    <TH>Name</TH>
    <TH>Cups</TH>
    <TH>Type of Coffee</TH>
    <TH>Sugar?</TH>
  </TR>
  <TR>
    <TD>T. Sexton</TD>
    <TD>10</TD>
    <TD>Espresso</TD>
    <TD>No</TD>
  </TR>
  <TR>
    <TD>J. Dinnen</TD>
    <TD>5</TD>
    <TD>Decaf</TD>
    <TD>Yes</TD>
  </TR>
</TABLE>

```

Here column values are directly represented by the TD tag text. You cannot declare them as tags nor as attributes. In addition, they are not located using their name but by their position within the row. Here is how to declare such a table to CONNECT:

 
```
create table coffee (
  `Name` char(16),
  `Cups` int(8),
  `Type` char(16),
  `Sugar` char(4))
engine=connect table_type=XML file_name='coffee.htm'
tabname='TABLE' header=1 option_list='Coltype=HTML';

```

You specify the fact that columns are located by position by setting the *Coltype* option to 'HTML'. Each column position (0 based) will be the value of the *flag* column parameter that is set by default in sequence. Now we are able to display the table:

 


| Name | Cups | Type | Sugar |
| --- | --- | --- | --- |
| T. Sexton | 10 | Espresso | No |
| J. Dinnen | 5 | Decaf | Yes |

 
**Note 1:** We specified '`header=n`' in the create statement to indicate that the first n rows of the table are not data rows and should be skipped.

 **Note 2:** In this last example, we did not specify the node names using the Rownode and Colnode options because when *Coltype* is set to 'HTML' they default to '`Rownode=TR`' and '`Colnode=TD`'.

 **Note 3:** The *Coltype* option is a word only the first character of which is significant. Recognized values are:

 

|  |  |
| --- | --- |
| T(ag) or N(ode) | Column names match a tag name (the default). |
| A(ttribute) or @ | Column names match an attribute name. |
| H(tml) or C(ol) or P(os) | Column are retrieved by their position. |

 ### New file setting

 Some create options are used only when creating a table on a new file, i. e. when inserting into a file that does not exist yet. When specified, the 'Header' option will create a header row with the name of the table columns. This is chiefly useful for HTML tables to be displayed on a web browser.

 Some new list-options are used in this context:

 

|  |  |
| --- | --- |
| **Encoding** | The encoding of the new document, defaulting to UTF-8. |
| **Attribute** | A list of 'attname=attvalue' separated by ';' to add to the table node. |
| **HeadAttr** | An attribute list to be added to the header row node. |

 Let us see for instance, the following create statement:

 
```
create table handlers (
  handler char(64),
  version char(20),
  author char(64),
  description char(255),
  maturity char(12))
engine=CONNECT table_type=XML file_name='handlers.htm'
tabname='TABLE' header=yes
option_list='coltype=HTML,encoding=ISO-8859-1,
attribute=border=1;cellpadding=5,headattr=bgcolor=yellow';

```

Supposing the table file does not exist yet, the first insert into that table, for instance by the following statement:

 
```
insert into handlers select plugin_name, plugin_version,
  plugin_author, plugin_description, plugin_maturity from
  information_schema.plugins where plugin_type = 'DAEMON';

```

will generate the following file:

 
```
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Created by CONNECT Version 3.05.0005 August 17, 2012 -->
<TABLE border="1" cellpadding="5">
  <TR bgcolor="yellow">
    <TH>handler</TH>
    <TH>version</TH>
    <TH>author</TH>
    <TH>description</TH>
    <TH>maturity</TH>
  </TR>
  <TR>
    <TD>Maria</TD>
    <TD>1.5</TD>
    <TD>Monty Program Ab</TD>
    <TD>Compatibility aliases for the Aria engine</TD>
    <TD>Gamma</TD>
  </TR>
</TABLE>

```

This file can be used to display the table on a web browser (encoding should be `ISO-8859-x`)

 


| handler | version | author | description | maturity |
| --- | --- | --- | --- | --- |
| Maria | 1.5 | Monty Program Ab | Compatibility aliases for the Aria engine | Gamma |

 
**Note:** The XML document encoding is generally specified in the XML header node and can be different from the DATA\_CHARSET, which is always UTF-8 for XML tables. Therefore the table DATA\_CHARSET character set should be unspecified, or specified as UTF8. The Encoding specification is useful only for new XML files and ignored for existing files having their encoding already specified in the header node.

 Notes
-----

 1. [↑](#_ref-0) CONNECT does not claim to be able to deal with any XML document. Besides, those that can usefully be processed for data analysis are likely to have a structure that can easily be transformed into a table.
2. [↑](#_ref-1) With libxml2, sub tags text can be separated by 0 or several blanks depending on the structure and indentation of the data file.
3. [↑](#_ref-2) This may cause some rows to be lost because an eventual where clause on the “multiple” column is applied only on the limited number of retrieved rows.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-xml-table-type/>

Inward and Outward Tables
=========================

    There are two broad categories of file-based CONNECT tables. Inward and Outward. They are described below.

 Outward Tables
--------------

 Tables are "outward" when their file name is specified in the CREATE TABLE statement using the *file\_name* option.

 Firstly, remember that CONNECT implements MED (Management of External Data). This means that the "true" CONNECT tables – "outward tables" – are based on data that belongs to files that can be produced by other applications or data imported from another DBMS.

 Therefore, their data is "precious" and should not be modified except by specific commands such as [INSERT](../insert/index), [UPDATE](../update/index), or [DELETE](../delete/index). For other commands such as [CREATE](../create/index), [DROP](../drop/index), or [ALTER](../alter/index) their data is never modified or erased.

 Outward tables can be created on existing files or external tables. When they are dropped, only the local description is dropped, the file or external table is not dropped or erased. Also, [DROP TABLE](../drop-table/index) does not erase the indexes.

 [ALTER TABLE](../alter-table/index) produces the following warning, as a reminder:

 
```
Warning (Code 1105): This is an outward table, table data were not modified.

```

If the specified file does not exist, it is created when data is inserted into the table. If a [SELECT](../select/index) is issued before the file is created, the following error is produced:

 
```
Warning (Code 1105): Open(rb) error 2 on <file_path>: No such file or directory

```

### Altering Outward Tables

 When an [ALTER TABLE](../alter-table/index) is issued, it just modifies the table definition accordingly without changing the data. [ALTER](../alter/index) can be used safely to, for instance, modify options such as MAPPED, HUGE or READONLY but with extreme care when modifying column definitions or order options because some column options such as FLAG should also be modified or may become wrong.

 Changing the table type with [ALTER](../alter/index) often makes no sense. But many suspicious alterations can be acceptable if they are just meant to correct an existing wrong definition.

 Translating a CONNECT table to another engine is fine but the opposite is forbidden when the target CONNECT table is not table based or when its data file exists (because when the target table data cannot be changed and if the source table is dropped, the table data would be lost). However, it can be done to create a new file-based tables when its file does not exist or is void.

 Creating or dropping indexes is accepted because it does not modify the table data. However, it is often unsafe to do it with an [ALTER TABLE](../alter-table/index) statement that does other modifications.

 Of course, all changes are acceptable for empty tables.

 **Note:** Using outward tables requires the [FILE](../grant/index#global-privileges) privilege.

 Inward Tables
-------------

 A special type of file-based CONNECT tables are “inward” tables. They are file-based tables whose file name is not specified in the [CREATE TABLE](../create-table/index) statement (no *file\_name* option).

 Their file will be located in the current database directory and their name will default to tablename.type where tablename is the table name and type is the table type folded to lower case. When they are created without using a `CREATE TABLE ... SELECT ...` statement, an empty file is made at create time and they can be populated by further inserts.

 They behave like tables of other storage engines and, unlike outward CONNECT tables, they are erased when the table is dropped. Of course they should not be read-only to be usable. Even though their utility is limited, they can be used for testing purposes or when the user does not have the [FILE](../grant/index#global-privileges) privilege.

 ### Altering Inward Tables

 One thing to know, because CONNECT builds indexes in a specific way, is that all index modifications are done using an "in-place" algorithm – meaning not using a temporary table. This is why, when indexing is specified in an [ALTER TABLE](../alter-table/index) statement containing other changes that cannot be done "in-place", the statement cannot be executed and raises an error.

 Converting an inward table to an outward table, using an ALTER TABLE statement specifying a new file name and/or a new table type, is restricted the same way it is when converting a table from another engine to an outward table. However there are no restrictions to convert another engine table to a CONNECT inward table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/inward-and-outward-tables/>

CONNECT ODBC Table Type: Accessing Tables From Another DBMS
===========================================================

    ODBC (Open Database Connectivity) is a standard API for accessing database management systems (DBMS). CONNECT uses this API to access data contained in other DBMS without having to implement a specific application for each one. An exception is the access to MySQL that should be done using the [MYSQL table type](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index).

 
Note: On Linux, unixODBC must be installed.

 
These tables are given the type ODBC. For example, if a "Customers" table is contained in an Access™ database you can define it with a command such as:

 
```
create table Customer (
  CustomerID varchar(5),
  CompanyName varchar(40),
  ContactName varchar(30),
  ContactTitle varchar(30),
  Address varchar(60),
  City varchar(15),
  Region varchar(15),
  PostalCode varchar(10),
  Country varchar(15),
  Phone varchar(24),
  Fax varchar(24))
engine=connect table_type=ODBC block_size=10
tabname='Customers'
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

Tabname option defaults to the table name. It is required if the source table name is different from the name of the CONNECT table. Note also that for some data sources this name is case sensitive.

 Often, because CONNECT can retrieve the table description using ODBC catalog functions, the column definitions can be unspecified. For instance this table can be simply created as:

 
```
create table Customer engine=connect table_type=ODBC
  block_size=10 tabname='Customers'
  Connection='DSN=MS Access Database;DBQ=C:/Program Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

The `BLOCK_SIZE` specification will be used later to set the RowsetSize when retrieving rows from the ODBC table. A reasonably large RowsetSize can greatly accelerate the fetching process.

 If you specify the column description, the column names of your table must exist in the data source table. However, you are not obliged to define all the data source columns and you can change the order of the columns. Some type conversion can also be done if appropriate. For instance, to access the FireBird sample table EMPLOYEE, you could define your table as:

 
```
create table empodbc (
  EMP_NO smallint(5) not null,
  FULL_NAME varchar(37) not null),
  PHONE_EXT varchar(4) not null,
  HIRE_DATE date,
  DEPT_NO smallint(3) not null,
  JOB_COUNTRY varchar(15),
  SALARY double(12,2) not null)
engine=CONNECT table_type=ODBC tabname='EMPLOYEE'
connection='DSN=firebird';

```

This definition ignores the FIRST\_NAME, LAST\_NAME, JOB\_CODE, and JOB\_GRADE columns. It places the FULL\_NAME last column of the original table in second position. The type of the HIRE\_DATE column was changed from *timestamp* to *date* and the type of the DEPT\_NO column was changed from *char* to *integer*.

 Currently, some restrictions apply to ODBC tables:

 1. Cursor type is forward only (sequential reading).
2. No indexing of ODBC tables (do not specify any columns as key). However, because CONNECT can often add a where clause to the query sent to the data source, indexing will be used by the data source if it supports it. (Remote indexing is available with version 1.04, released with [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/))
3. CONNECT ODBC supports [SELECT](../select/index) and [INSERT](../insert/index). [UPDATE](../update/index) and [DELETE](../delete/index) are also supported in a somewhat restricted way (see below). For other operations, use an ODBC table with the EXECSRC option (see below) to directly send proper commands to the data source.

 Random Access of ODBC Tables
----------------------------

 In CONNECT version 1.03 (until [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/)) ODBC tables are not indexable. Version 1.04 (from [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/)) adds remote indexing facility to the ODBC table type.

 However, some queries require random access to an ODBC table; for instance when it is joined to another table or used in an order by queries applied to a long column or large tables.

 There are several ways to enable random (position) access to a CONNECT ODBC table. They are dependant on the following table options:

 


| Option | Type | Used For |
| --- | --- | --- |
| Block\_Size | Integer | Specifying the rowset size. |
| Memory\* | Integer | Storing the result set in memory. |
| Scrollable\* | Boolean | Using a scrollable cursor. |

 
`*` - To be specified in the option\_list.

 When dealing with small tables, the simpler way to enable random access is to specify a rowset size equal or larger than the table size (or the result set size if a push down where clause is used). This means that the whole result is in memory on the first fetch and CONNECT will use it for further positional accesses.

 Another way to have the result set in memory is to use the memory option. This option can be set to the following values:

 **0.** No memory used (the default). Best when the table is read sequentially as in SELECT statements with only eventual WHERE clauses.  
 **1.** Memory size required is calculated during the first sequential table read. The allocated memory is filled during the second sequential read. Then the table rows are retrieved from the memory. This should be used when the table will be accessed several times randomly, such as in sub-selects or being the target table of a join.  
 **2.** A first query is executed to get the result set size and the needed memory is allocated. It is filled on the first sequential reading. Then random access of the table is possible. This can be used in the case of ORDER BY clauses, when MariaDB uses position reading.  


 Note that the best way to handle ORDER BY is to set the max\_length\_for\_sort\_data variable to a larger value (its default value is 1024 that is pretty small). Indeed, it requires less memory to be used, particularly when a WHERE clause limits the retrieved data set. This is because in the case of an order by query, MariaDB firstly retrieves the sequentially the result set and the position of each records. Often the sort can be done from the result set if it is not too big. But if too big, or if it implies some “long” columns, only the positions are sorted and MariaDB retrieves the final result from the table read in random order. If setting the max\_length\_for\_sort\_data variable is not feasible or does not work, to be able to retrieve table data from memory after the first sequential read, the memory option must be set to 2.

 For tables too large to be stored in memory another possibility is to make your table to use a scrollable cursor. In this case each randomly accessed row can be retrieved from the data source specifying its cursor position, which is reasonably fast. However, scrollable cursors are not supported by all data sources.

 With CONNECT version 1.04 (from [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/)), another way to provide random access is to specify some columns to be indexed. This should be done only when the corresponding column of the source table is also indexed. This should be used for tables too large to be stored in memory and is similar to the remote indexing used by the [MYSQL table type](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) and by the [FEDERATED engine](../federatedx-storage-engine/index). 

 There remains the possibility to extract data from the external table and to construct another table of any file format from the data source. For instance to construct a fixed formatted DOS table containing the CUSTOMER table data, create the table as

 
```
create table Custfix engine=connect File_name='customer.txt'
  table_type=fix block_size=20 as select * from customer;

```

Now you can use *custfix* for fast database operations on the copied *customer* table data.

 Retrieving data from a spreadsheet
----------------------------------

 ODBC can also be used to create tables based on tabular data belonging to an Excel spreadsheet:

 
```
create table XLCONT
engine=CONNECT table_type=ODBC tabname='CONTACT'
Connection='DSN=Excel Files;DBQ=D:/Ber/Doc/Contact_BP.xls;';

```

This supposes that a tabular zone of the sheet including column headers is defined as a table named CONTACT or using a “named reference”. Refer to the Excel documentation for how to specify tables inside sheets. Once done, you can ask:

 
```
select * from xlcont;

```

This will extract the data from Excel and display:

 


| Nom | Fonction | Societe |
| --- | --- | --- |
| Boisseau Frederic |  | 9 Telecom |
| Martelliere Nicolas |  | Vidal SA (Groupe UBM) |
| Remy Agathe |  | Price Minister |
| Du Halgouet Tanguy |  | Danone |
| Vandamme Anna |  | GDF |
| Thomas Willy |  | Europ Assistance France |
| Thomas Dominique |  | Acoss (DG des URSSAF) |
| Thomas Berengere | Responsable SI Decisionnel | DEXIA Credit Local |
| Husy Frederic | Responsable Decisionnel | Neuf Cegetel |
| Lemonnier Nathalie | Directeur Marketing Client | Louis Vuitton |
| Louis Loic | Reporting International Decisionnel | Accor |
| Menseau Eric |  | Orange France |

 
Here again, the columns description was left to CONNECT when creating the table.

 Multiple ODBC tables
--------------------

 The concept of multiple tables can be extended to ODBC tables when they are physically represented by files, for instance to Excel or Access tables. The condition is that the connect string for the table must contain a field DBQ=*filename*, in which wildcard characters can be included as for multiple=1 tables in their filename. For instance, a table contained in several Excel files CA200401.xls, CA200402.xls, ...CA200412.xls can be created by a command such as:

 
```
create table ca04mul (Date char(19), Operation varchar(64),
  Debit double(15,2), Credit double(15,2))
engine=CONNECT table_type=ODBC multiple=1
qchar= '"' tabname='bank account'
connection='DSN=Excel Files;DBQ=D:/Ber/CA/CA2004*.xls;';

```

Providing that in each file the applying information is internally set for Excel as a table named "bank account". This extension to ODBC does not support *multiple*=2. The *qchar* option was specified to make the identifiers quoted in the select statement sent to ODBC, in particular the when the table or column names contain blanks, to avoid SQL syntax errors.

 
**Caution:** Avoid accessing tables belonging to the currently running MariaDB server via the MySQL ODBC connector. This may not work and may cause the server to be restarted.

 
Performance consideration
-------------------------

 To avoid extracting entire tables from an ODBC source, which can be a lengthy process, CONNECT extracts the "compatible" part of query WHERE clauses and adds it to the ODBC query. Compatible means that it must be understood by the data source. In particular, clauses involving scalar functions are not kept because the data source may have different functions than MariaDB or use a different syntax. Of course, clauses involving sub-select are also skipped. This will transfer eventual indexing to the data source.

 
Take care with clauses involving string items because you may not know whether they are treated by the data source as case sensitive or case insensitive. If in doubt, make your queries as if the data source was processing strings as case sensitive to avoid incomplete results.

 
Using ODBC Tables inside correlated sub-queries
-----------------------------------------------

 Unlike not correlated subqueries that are executed only once, correlated subqueries are executed many times. It is what ODBC calls a "requery". Several methods can be used by CONNECT to deal with this depending on the setting of the MEMORY or SCROLLABLE Boolean options:

 


| Option | Description |
| --- | --- |
| Default | Implementing "requery" by discarding the current result set and re submitting the query (as MFC does) |
| Memory=1 or 2 | Storing the result set in memory as MYSQL tables do. |
| Scrollable=Yes | Using a scrollable cursor. |

 
Note: the MEMORY and SCROLLABLE options must be specified in the OPTION \_ LIST.

 Because the table is accessed several times, this can make queries last very long except for small tables and is almost unacceptable for big tables. However, if it cannot be avoided, using the memory method is the best choice and can be more than four times faster than the default method. If it is supported by the driver, using a scrollable cursor is slightly slower than using memory but can be an alternative to avoid memory problems when the sub-query returns a huge result set.

 If the result set is of reasonable size, it is also possible to specify the block\_size option equal or slightly larger than the result set. The whole result set being read on the first fetch, can be accessed many times without having to do anything else.

 Another good workaround is to replace within the correlated sub-query the ODBC table by a local copy of it because MariaDB is often able to optimize the query and to provide a very fast execution.

 Accessing specified views
-------------------------

 Instead of specifying a source table name via the TABNAME option, it is possible to retrieve data from a “view” whose definition is given in a new option SRCDEF. For instance:

 
```
CREATE TABLE custnum (
  country varchar(15) NOT NULL,
  customers int(6) NOT NULL)
ENGINE=CONNECT TABLE_TYPE=ODBC BLOCK_SIZE=10
CONNECTION='DSN=MS Access Database;DBQ=C:/Program Files/Microsoft Office/Office/1033/FPNWIND.MDB;'
SRCDEF='select country, count(*) as customers from customers group by country';

```

Or simply, because CONNECT can retrieve the returned column definition:

 
```
CREATE TABLE custnum ENGINE=CONNECT TABLE_TYPE=ODBC BLOCK_SIZE=10
CONNECTION='DSN=MS Access Database;DBQ=C:/Program Files/Microsoft Office/Office/1033/FPNWIND.MDB;'
SRCDEF='select country, count(*) as customers from customers group by country';

```

Then, when executing for instance:

 
```
select * from custnum where customers > 3;

```

The processing of the group by is done by the data source, which returns only the generated result set on which only the where clause is performed locally. The result:

 


| country | customers |
| --- | --- |
| Brazil | 9 |
| France | 11 |
| Germany | 11 |
| Mexico | 5 |
| Spain | 5 |
| UK | 7 |
| USA | 13 |
| Venezuela | 4 |

 
This makes possible to let the data source do complicated operations, such as joining several tables or executing procedures returning a result set. This minimizes the data transfer through ODBC.

 Data Modifying Operations
-------------------------

 The only data modifying operations are the [INSERT](../insert/index) , [UPDATE](../update/index) and [DELETE](../delete/index) commands. They can be executed successfully only if the data source database or tables are not read/only.

 ### INSERT Command

 When inserting values to an ODBC table, local values are used and sent to the ODBC table. This does not make any difference when the values are constant but in a query such as:

 
```
insert into t1 select * from t2;

```

Where t1 is an ODBC table, t2 is a locally defined table that must exist on the local server. Besides, it is a good way to create a distant ODBC table from local data.

 CONNECT does not directly support INSERT commands such as:

 
```
insert into t1 values(2,'Deux') on duplicate key update msg = 'Two';

```

Sure enough, the “on duplicate key update” part of it is ignored, and will result in error if the key value is duplicated.

 ### UPDATE and DELETE Commands

 Unlike the [INSERT](../insert/index) command, [UPDATE](../update/index) and [DELETE](../delete/index) are supported in a simplified way. Only simple table commands are supported; CONNECT does not support multi-table commands, commands sent from a procedure, or issued via a trigger. These commands are just rephrased to correspond to the data source syntax and sent to the data source for execution. Let us suppose we created the table:

 
```
create table tolite (
  id int(9) not null,
  nom varchar(12) not null,
  nais date default null,
  rem varchar(32) default null)
ENGINE=CONNECT TABLE_TYPE=ODBC tabname='lite'
CONNECTION='DSN=SQLite3 Datasource;Database=test.sqlite3'
CHARSET=utf8 DATA_CHARSET=utf8;

```

We can populate it by:

 
```
insert into tolite values(1,'Toto',now(),'First'),
(2,'Foo','2012-07-14','Second'),(4,'Machin','1968-05-30','Third');

```

The function `now()` will be executed by MariaDB and it returned value sent to the ODBC table.

 Let us see what happens when updating the table. If we use the query:

 
```
update tolite set nom = 'Gillespie' where id = 10;

```

CONNECT will rephrase the command as:

 
```
update lite set nom = 'Gillespie' where id = 10;

```

What it did is just to replace the local table name with the remote table name and change all the back ticks to blanks or to the data source identifier quoting characters if QUOTED is specified. Then this command will be sent to the data source to be executed by it.

 This is simpler and can be faster than doing a positional update using a cursor and commands such as “select ... for update of ...” that are not supported by all data sources. However, there are some restrictions that must be understood due to the way it is handled by MariaDB.

 1. MariaDB does not know about all the above. The command will be parsed as if it were to be executed locally. Therefore, it must respect the MariaDB syntax.
2. Being executed by the data source, the (rephrased) command must also respect the data source syntax.
3. All data referenced in the SET and WHERE clause belongs to the data source.

 This is possible because both MariaDB and the data source are using the SQL language. But you must use only the basic features that are part of the core SQL language. For instance, keywords like IGNORE or LOW\_PRIORITY will cause syntax error with many data source.

 Scalar function names also can be different, which severely restrict the use of them. For instance:

 
```
update tolite set nais = now() where id = 2;

```

This will not work with SQLite3, the data source returning an “unknown scalar function” error message. Note that in this particular case, you can rephrase it to:

 
```
update tolite set nais = date('now') where id = 2;

```

This understood by both parsers, and even if this function would return NULL executed by MariaDB, it does return the current date when executed by SQLite3. But this begins to become too trickery so to overcome all these restrictions, and permit to have all types of commands executed by the data source, CONNECT provides a specific ODBC table subtype described now.

 Sending commands to a Data Source
---------------------------------

 This can be done using a special subtype of ODBC table. Let us see this in an example:

 
```
create table crlite (
  command varchar(128) not null,
  number int(5) not null flag=1,
  message varchar(255) flag=2)
engine=connect table_type=odbc
connection='Driver=SQLite3 ODBC Driver;Database=test.sqlite3;NoWCHAR=yes'
option_list='Execsrc=1';

```

The key points in this create statement are the EXECSRC option and the column definition.

 The EXECSRC option tells that this table will be used to send a command to the data source. Most of the sent commands do not return result set. Therefore, the table columns are used to specify the command to be executed and to get the result of the execution. The name of these columns can be chosen arbitrarily, their function coming from the FLAG value:

 

|  |  |
| --- | --- |
| Flag=0: | The command to execute. |
| Flag=1: | The affected rows, or -1 in case of error, or the result number of column if the command returns a result set. |
| Flag=2: | The returned (eventually error) message. |

 How to use this table and specify the command to send? By executing a command such as:

 
```
select * from crlite where command = 'a command';

```

This will send the command specified in the WHERE clause to the data source and return the result of its execution. The syntax of the WHERE clause must be exactly as shown above. For instance:

 
```
select * from crlite where command =
'CREATE TABLE lite (
ID integer primary key autoincrement,
name char(12) not null,
birth date,
rem varchar(32))';

```

This command returns:

 


| command | number | message |
| --- | --- | --- |
| `CREATE TABLE lite (ID integer primary key autoincrement, name...` | 0 | Affected rows |

 
Now we can create a standard ODBC table on the newly created table:

 
```
CREATE TABLE tlite
ENGINE=CONNECT TABLE_TYPE=ODBC tabname='lite'
CONNECTION='Driver=SQLite3 ODBC Driver;Database=test.sqlite3;NoWCHAR=yes'
CHARSET=utf8 DATA_CHARSET=utf8;

```

We can populate it directly using the supported [INSERT](../insert/index) statement:

 
```
insert into tlite(name,birth) values('Toto','2005-06-12');
insert into tlite(name,birth,rem) values('Foo',NULL,'No ID');
insert into tlite(name,birth) values('Truc','1998-10-27');
insert into tlite(name,birth,rem) values('John','1968-05-30','Last');

```

And see the result:

 
```
select * from tlite;

```




| ID | name | birth | rem |
| --- | --- | --- | --- |
| 1 | Toto | 2005-06-12 | NULL |
| 2 | Foo | NULL | No ID |
| 3 | Truc | 1998-10-27 | NULL |
| 4 | John | 1968-05-30 | Last |

 
Any command, for instance [UPDATE](../update/index), can be executed from the *crlite* table:

 
```
select * from crlite where command =
'update lite set birth = ''2012-07-14'' where ID = 2';

```

This command returns:

 


| command | number | message |
| --- | --- | --- |
| `update lite set birth = '2012-07-15' where ID = 2` | 1 | Affected rows |

 
Let us verify it:

 
```
select * from tlite where ID = 2;

```




| ID | name | birth | rem |
| --- | --- | --- | --- |
| 2 | Foo | 2012-07-15 | No ID |

 
The syntax to send a command is rather strange and may seem unnatural. It is possible to use an easier syntax by defining a stored procedure such as:

 
```
create procedure send_cmd(cmd varchar(255))
MODIFIES SQL DATA
select * from crlite where command = cmd;

```

Now you can send commands like this:

 
```
call send_cmd('drop tlite');

```

This is possible only when sending one single command.

 ### Sending several commands together

 Grouping commands uses an easier syntax and is faster because only one connection is made for the all of them. To send several commands in one call, use the following syntax:

 
```
select * from crlite where command in (
  'update lite set birth = ''2012-07-14'' where ID = 2',
  'update lite set birth = ''2009-08-10'' where ID = 3');

```

When several commands are sent, the execution stops at the end of them or after a command that is in error. To continue after *n* errors, set the option maxerr=*n* (0 by default) in the option list.

 **Note 1:** It is possible to specify the SRCDEF option when creating an EXECSRC table. It will be the command sent by default when a WHERE clause is not specified.

 **Note 2:** Most data sources do not allow sending several commands separated by semi-colons.

 **Note 3:** Quotes inside commands must be escaped. This can be avoided by using a different quoting character than the one used in the command

 **Note 4:** The sent command must obey the data source syntax.

 **Note 5:** Sent commands apply in the specified database. However, they can address any table within this database, or belonging to another database using the name syntax *schema.tabname*.

 Connecting to a Data Source
---------------------------

 There are two ways to establish a connection to a data source:

 1. Using SQLDriverConnect and a Connection String
2. Using SQLConnect and a Data Source Name (DSN)

 The first way uses a Connection String whose components describe what is needed to establish the connection. It is the most complete way to do it and by default CONNECT uses it.

 The second way is a simplified way in which ODBC is just given the name of a DSN that must have been defined to ODBC or UnixOdbc and that contains the necessary information to establish the connection. Only the user name and password can be specified out of the DSN specification. 

 ### Defining the Connection String

 Using the first way, the connection string must be specified. This is sometimes the most difficult task when creating ODBC tables because, depending on the operating system and the data source, this string can widely differ.

 The format of the ODBC Connection String is:

 
```
connection-string::= empty-string[;] | attribute[;] | attribute; connection-string
empty-string ::=
attribute ::= attribute-keyword=attribute-value | DRIVER=[{]attribute-value[}]
attribute-keyword ::= DSN | UID | PWD | driver-defined-attribute-keyword
attribute-value ::= character-string
driver-defined-attribute-keyword = identifier

```

Where character-string has zero or more characters; identifier has one or more characters; attribute- keyword is not case-sensitive; attribute-value may be case-sensitive; and the value of the DSN keyword does not consist solely of blanks. Due to the connection string grammar, keywords and attribute values that contain the characters `[]{}(),;?*=!@` should be avoided. The value of the DSN keyword cannot consist only of blanks, and should not contain leading blanks. Because of the grammar of the system information, keywords and data source names cannot contain the backslash (\) character. Applications do not have to add braces around the attribute value after the DRIVER keyword unless the attribute contains a semicolon (;), in which case the braces are required. If the attribute value that the driver receives includes the braces, the driver should not remove them, but they should be part of the returned connection string.

 ### ODBC Defined Connection Attributes

 The ODBC defined attributes are:

 * DSN - the name of the data source to connect to. You must create this before attempting to refer to it. You create new DSNs through the ODBC Administrator (Windows), ODBCAdmin (unixODBC's GUI manager) or in the odbc.ini file.
* DRIVER - the name of the driver to connect to. You can use this in DSN-less connections.
* FILEDSN - the name of a file containing the connection attributes.
* UID/PWD - any username and password the database requires for authentication.
* SAVEFILE - request the DSN attributes are saved in this file.

 Other attributes are DSN dependent attributes. The connection string can give the name of the driver in the DRIVER field or the data source in the DSN field (attention! meet the spelling and case) and has other fields that depend on the data source. When specifying a file, the DBQ field must give the **full** path and name of the file containing the table. Refer to the specific ODBC connector documentation for the exact syntax of the connection string.

 ### Using a Predefined DSN

 This is done by specifying in the option list the Boolean option “UseDSN” as yes or 1. In addition, string options “user” and “password” can be optionally specified in the option list.

 When doing so, the connection string just contains the name of the predefined Data Source. For instance:

 
```
CREATE TABLE tlite ENGINE=CONNECT TABLE_TYPE=ODBC tabname='lite'
CONNECTION='SQLite3 Datasource' 
OPTION_LIST='UseDSN=Yes,User=me,Password=mypass';

```

Note: the connection data source name (limited to 32 characters) should not be preceded by “DSN=”.

 ODBC Tables on Linux/Unix
-------------------------

 In order to use ODBC tables, you will need to have unixODBC installed. Additionally, you will need the ODBC driver for your foreign server's protocol. For example, for MS SQL Server or Sybase, you will need to have FreeTDS installed.

 Make sure the user running mysqld (usually the mysql user) has permission to the ODBC data source configuration and the ODBC drivers. If you get an error on Linux/Unix when using TABLE\_TYPE=ODBC:

 
```
Error Code: 1105 [unixODBC][Driver Manager]Can't open lib
'/usr/cachesys/bin/libcacheodbc.so' : file not found

```

You must make sure that the user running mysqld (usually "mysql") has enough permission to load the ODBC driver library. It can happen that the driver file does not have enough read privileges (use chmod to fix this), or loading is prevented by SELinux configuration (see below).

 Try this command in a shell to check if the driver had enough permission:

 
```
sudo -u mysql ldd /usr/cachesys/bin/libcacheodbc.so

```

#### SELinux

 SELinux can cause various problems. If you think SELinux is causing problems, check the system log (e.g. /var/log/messages) or the audit log (e.g. /var/log/audit/audit.log).

 **mysqld can't load some executable code, so it can't use the ODBC driver.**

 Example error:

 
```
Error Code: 1105 [unixODBC][Driver Manager]Can't open lib
'/usr/cachesys/bin/libcacheodbc.so' : file not found

```

Audit log:

 
```
type=AVC msg=audit(1384890085.406:76): avc: denied { execute }
for pid=1433 comm="mysqld"
path="/usr/cachesys/bin/libcacheodbc.so" dev=dm-0 ino=3279212
scontext=unconfined_u:system_r:mysqld_t:s0
tcontext=unconfined_u:object_r:usr_t:s0 tclass=file

```

**mysqld can't open TCP sockets on some ports, so it can't connect to the foreign server.**

 Example error:

 
```
ERROR 1296 (HY000): Got error 174 '[unixODBC][FreeTDS][SQL Server]Unable to connect to data source' from CONNECT

```

Audit log:

 
```
type=AVC msg=audit(1423094175.109:433): avc:  denied  { name_connect } for  pid=3193 comm="mysqld" dest=1433 scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:mssql_port_t:s0 tclass=tcp_socket

```

ODBC Catalog Information
------------------------

 Depending on the version of the used ODBC driver, some additional information on the tables are existing, such as table QUALIFIER or OWNER for old versions, now named CATALOG or SCHEMA since version 3.

 CATALOG is apparently rarely used by most data sources, but SCHEMA (formerly OWNER) is and corresponds to the DATABASE information of MySQL.

 The issue is that if no schema name is specified, some data sources return information for all schemas while some others only return the information of the “default” schema. In addition, the used “schema” or “database” is sometimes implied by the connection string and sometimes is not. Sometimes, it also can be included in a data source definition.

 CONNECT offers two ways to specify this information:

 1. When specified, the DBNAME create table option is regarded by ODBC tables as the SCHEMA name.
2. Table names can be specified as “*cat.sch.tab*” allowing to set the catalog and schema info.

 When both are used, the qualified table name has precedence over DBNAME . For instance:

 


| Tabname | DBname | Description |
| --- | --- | --- |
| test.t1 |  | The t1 table of the test schema. |
| test.t1 | mydb | The t1 table of the test schema (test has precedence) |
| t1 | mydb | The t1 table of the mydb schema |
| %.%.% |  | All tables in all catalogs and all schemas |
| t1 |  | The t1 table in the default or all schema depending on the DSN |
| %.t1 |  | The t1 table in all schemas for all DSN |
| test.% |  | All tables in the test schema |

 
When creating a standard ODBC table, you should make sure only one source table is specified. Specifying more than one source table must be done only for CONNECT catalog tables (with CATFUNC=tables or columns).

 In particular, when column definition is left to the Discovery feature, if tables with the same name are present in several schemas and the schema name is not specified, several columns with the same name will be generated. This will make the creation fail with a not very explicit error message. 

 Note: With some ODBC drivers, the DBNAME option or qualified table name is useless because the schema implied by the connection string or the definition of the data source has priority over the specified DBNAME .

 ### Table name case

 Another issue when dealing with ODBC tables is the way table and column names are handled regarding of the case.

 For instance, Oracle follows to the SQL standard here. It converts non-quoted identifiers to upper case. This is correct and expected. PostgreSQL is not standard. It converts identifiers to lower case. MySQL/MariaDB is not standard. They preserve identifiers on Linux, and convert to lower case on Windows.

 Think about that if you fail to see a table or a column on an ODBC data source.

 Non-ASCII Character Sets with Oracle
------------------------------------

 When connecting through ODBC, the MariaDB Server operates as a client to the foreign database management system. As such, it requires that you configure MariaDB as you would configure native clients for the given database server.

 In the case of connecting to Oracle, when using non-ASCI character sets, you need to properly set the NLS\_LANG environment variable before starting the MariaDB Server.

 For instance, to test this on Oracle, create a table that contains a series of special characters:

 
```
CREATE TABLE t1 (letter VARCHAR(4000));

INSERT INTO t1 VALUES
   (UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('C4'))),
   (UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('C5'))),
   (UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW('C6')));

SELECT letter, RAWTOHEX(letter) FROM t1;

letter | RAWTOHEX(letter)
-------|-----------------
Ä     | C4
Å     | C5
Æ     | C6

```

Then create a connecting table on MariaDB and attempt the same query:

 
```
CREATE TABLE t1 (
   letter VARCHAR(4000))
ENGINE=CONNECT
DEFAULT CHARSET=utf8mb4
CONNECTION='DSN=YOUR_DSN'
TABLE_TYPE = 'ODBC'
DATA_CHARSET = latin1
TABNAME = 'YOUR_SCHEMA.T1';

SELECT letter, HEX(letter) FROM t1;

+--------+-------------+
| letter | HEX(letter) |
+--------+-------------+
| A      | 	    41 |
| ?      | 	    3F |
| ?      | 	    3F |
+--------+-------------+

```

While the character set is defined in a way that satisfies MariaDB, it has not been defined for Oracle, (that is, setting the NLS\_LANG environment variable). As a result, Oracle is not providing the characters you want to MariaDB and Connect. The specific method of setting the NLS\_LANG variable can vary depending on your operating system or distribution. If you're experiencing this issue, check your OS documentation for more details on how to properly set environment variables.

 ### Using systemd

 With Linux distributions that use [systemd](../systemd/index), you need to set the environment variable in the service file, (systemd doesn't read from the /etc/environment file).

 This is done by setting the Environment variable in the [Service] unit. For instance,

 
```
# systemctl edit mariadb.service

[Service]
Environment=NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1

```

Then restart MariaDB,

 
```
# systemctl restart mariadb.service

```

You can now retrieve the appropriate characters from Oracle tables:

 
```
SELECT letter, HEX(letter) FROM t1;

+--------+-------------+
| letter | HEX(letter) |
+--------+-------------+
| Ä      | C384        |
| Å      | C385        |
| Æ      | C386        |
+--------+-------------+

```

### Using Windows

 Microsoft Windows doesn't ignore environment variables the way systemd does on Linux, but it does require that you set the NLS\_LANG environment variable on your system. In order to do so, you need to open an elevated command-prompt, (that is, Cmd.exe with administrative privileges).

 From here, you can use the Setx command to set the variable. For instance,

 
```
Setx NLS_LANG GERMAN_GERMANY.WE8ISO8859P1 /m

```

Note: For more detail about this, see [MDEV-17501](https://jira.mariadb.org/browse/MDEV-17501).

 
`OPTION_LIST` Values Supported by the ODBC Tables
--------------------------------------------------

 The following options can be given as comma-separated string to the `OPTION_LIST` value in the `CREATE TABLE` statement. 

 


| Name | Default | Description |
| --- | --- | --- |
| MaxRes | 0 | Maximum number of rows returned by catalog functions |
| ConnectTimeout | -1 | Connection timeout in seconds, unlimited by default |
| QueryTimeout | -1 | Query timeout in seconds, unlimited by default |
| UseDSN | false | Use pre-configured DSN |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-odbc-table-type-accessing-tables-from-another-dbms/>

CONNECT MYSQL Table Type: Accessing MySQL/MariaDB Tables
========================================================

     This table type uses libmysql API to access a MySQL or MariaDB table or view. This table must be created on the current server or on another local or remote server. This is similar to what the [FederatedX](../federatedx/index) storage engine provides with some differences.

 Currently the Federated-like syntax can be used to create such a table, for instance:

 
```
create table essai (
  num integer(4) not null,
  line char(15) not null)
engine=CONNECT table_type=MYSQL
connection='mysql://root@localhost/test/people';

```

The connection string can have the same syntax as that used by FEDERATED

 
```
scheme://username:password@hostname:port/database/tablename
scheme://username@hostname/database/tablename
scheme://username:password@hostname/database/tablename
scheme://username:password@hostname/database/tablename

```

However, it can also be mixed with connect standard options. For instance:

 
```
create table essai (
  num integer(4) not null,
  line char(15) not null)
engine=CONNECT table_type=MYSQL dbname=test tabname=people
connection='mysql://root@localhost';

```

It can also be specified as a reference to a federated server:

 
```
connection="connection_one"
connection="connection_one/table_foo"

```

The pure (deprecated) CONNECT syntax is also accepted:

 
```
create table essai (
  num integer(4) not null,
  line char(15) not null)
engine=CONNECT table_type=MYSQL dbname=test tabname=people
option_list='user=root,host=localhost';

```

The specific connection items are:

 


| Option | Default value | Description |
| --- | --- | --- |
| Table | The table name | The name of the table to access. |
| Database | The current DB name | The database where the table is located. |
| Host | localhost\* | The host of the server, a name or an IP address. |
| User | The current user | The connection user name. |
| Password | No password | An optional user password. |
| Port | The currently used port | The port of the server. |
| Quoted | 0 | 1 if remote Tabname must be quoted. |

 
* - When the host is specified as “localhost”, the connection is established on Linux using Linux sockets. On Windows, the connection is established by default using shared memory if it is enabled. If not, the TCP protocol is used. An alternative is to specify the host as “.” to use a named pipe connection (if it is enabled). This makes possible to use these table types with server skipping networking.

 
**Caution:** Take care not to refer to the MYSQL table itself to avoid an infinite loop!

 
MYSQL table can refer to the current server as well as to another server. Views can be referred by name or directly giving a source definition, for instance:

 
```
create table grp engine=connect table_type=mysql
CONNECTION='mysql://root@localhost/test/people'
SRCDEF='select title, count(*) as cnt from employees group by title';

```

When specified, the columns of the mysql table must exist in the accessed table with the same name, but can be only a subset of them and specified in a different order. Their type must be a type supported by CONNECT and, if it is not identical to the type of the accessed table matching column, a conversion can be done according to the rules given in [Data type conversion](../connect-data-types/index#data-type-conversion).

 Note: For columns prone to be targeted by a where clause, keep the column type compatible with the source table column type (numeric or character) to have a correct rephrasing of the where clause.

 If you do not want to restrict or change the column definition, do not provide it and leave CONNECT get the column definition from the remote server. For instance:

 
```
create table essai engine=CONNECT table_type=MYSQL
connection='mysql://root@localhost/test/people';

```

This will create the *essai* table with the same columns than the people table. If the target table contains CONNECT incompatible type columns, see [Data type conversion](../connect-data-types/index#data-type-conversion) to know how these columns can be converted or skipped.

 Charset Specification
---------------------

 When accessing the remote table, CONNECT sets the connection charset set to the default local table charset as the FEDERATED engine does. 

 Do not specify a column character set if it is different from the table default character set even when it is the case on the remote table. This is because the remote column is translated to the local table character set when reading it. This is the default but it can be modified by the setting the [character\_set\_results](../server-system-variables/index#character_set_results) variable of the target server. If it must keep its setting, for instance to UTF8 when containing Unicode characters, specify the local default charset to its character set.

 This means that it is not possible to correctly retrieve a remote table if it contains columns having different character sets. A solution is to retrieve it by several local tables, each accessing only columns with the same character set.

 Indexing of MYSQL tables
------------------------

 Indexes are rarely useful with MYSQL tables. This is because CONNECT tries to access only the requested rows. For instance if you ask:

 
```
select * from essai where num = 23;

```

CONNECT will construct and send to the server the query:

 
```
SELECT num, line FROM people WHERE num = 23

```

If the *people* table is indexed on *num*, indexing will be used on the remote server. This, in all cases, will limit the amount of data to retrieve on the network.

 However, an index can be specified for columns that are prone to be used to join another table to the MYSQL table. For instance:

 
```
select d.id, d.name, f.dept, f.salary
from loc_tab d straight_join cnc_tab f on d.id = f.id
where f.salary > 10000;

```

If the *id* column of the remote table addressed by the *cnc\_tab* MYSQL table is indexed (which is likely if it is a key) you should also index the *id* column of the MYSQL *cnc\_tab* table. If so, using “remote” indexing as does FEDERATED, only the useful rows of the remote table will be retrieved during the join process. However, because these rows are retrieved by separate [SELECT](../select/index) statements, this will be useful only when retrieving a few rows of a big table.

 In particular, you should not specify an index for columns not used for joining and above all DO NOT index a joined column if it is not indexed in the remote table. This would cause multiple scans of the remote table to retrieve the joined rows one by one.

 Data Modifying Operations
-------------------------

 The CONNECT MYSQL type supports [SELECT](../select/index) and [INSERT](../insert/index) and a somewhat limited form of [UPDATE](../update/index) and [DELETE](../delete/index). These are described below.

 The MYSQL type uses similar methods than the ODBC type to implement the [INSERT](../insert/index), [UPDATE](../update/index) and [DELETE](../delete/index) commands. Refer to the ODBC chapter for the restrictions concerning them.

 For the [UPDATE](../update/index) and [DELETE](../delete/index) commands, there are fewer restrictions because the remote server being a MySQL server, the syntax of the command will be always acceptable by the remote server.

 For instance, you can freely use keywords like IGNORE or LOW\_PRIORITY as well as scalar functions in the SET and WHERE clauses.

 However, there is still an issue on multi-table statements. Let us suppose you have a *t1* table on the remote server and want to execute a query such as:

 
```
update essai as x set line = (select msg from t1 where id = x.num)
where num = 2;

```

When parsed locally, you will have errors if no *t1* table exists or if it does not have the referenced columns. When *t1* does not exist, you can overcome this issue by creating a local dummy *t1* table:

 
```
create table t1 (id int, msg char(1)) engine=BLACKHOLE;

```

This will make the local parser happy and permit to execute the command on the remote server. Note however that having a local MySQL table defined on the remote *t1* table does not solve the problem unless it is also names *t1* locally.

 This is why, to permit to have all types of commands executed by the data source without any restriction, CONNECT provides a specific MySQL table subtype described now.

 Sending commands to a MariaDB Server
------------------------------------

 This can be done like for ODBC or JDBC tables by defining a specific table that will be used to send commands and get the result of their execution..

 
```
create table send (
  command varchar(128) not null,
  warnings int(4) not null flag=3,
  number int(5) not null flag=1,
  message varchar(255) flag=2)
engine=connect table_type=mysql
connection='mysql://user@host/database'
option_list='Execsrc=1,Maxerr=2';

```

The key points in this create statement are the EXECSRC option and the column definition.

 The EXECSRC option tells that this table will be used to send commands to the MariaDB server. Most of the sent commands do not return result set. Therefore, the table columns are used to specify the command to be executed and to get the result of the execution. The name of these columns can be chosen arbitrarily, their function coming from the FLAG value:

 

|  |  |
| --- | --- |
| **Flag=0:** | The command to execute (the default) |
| **Flag=1:** | The number of affected rows, or the result number of columns if the command would return a result set. |
| **Flag=2:** | The returned (eventually error) message. |
| **Flag=3:** | The number of warnings. |

 How to use this table and specify the command to send? By executing a command such as:

 
```
select * from send where command = 'a command';

```

This will send the command specified in the WHERE clause to the data source and return the result of its execution. The syntax of the WHERE clause must be exactly as shown above. For instance:

 
```
select * from send where command =
'CREATE TABLE people (
num integer(4) primary key autoincrement,
line char(15) not null';

```

This command returns:

 


| command | warnings | number | message |
| --- | --- | --- | --- |
| `CREATE TABLE people (num integer(4) primary key aut...` | 0 | 0 | Affected rows |

 
### Sending several commands in one call

 It can be faster to execute because there will be only one connection for all of them. To send several commands in one call, use the following syntax:

 
```
select * from send where command in (
"update people set line = 'Two' where id = 2",
"update people set line = 'Three' where id = 3");

```

When several commands are sent, the execution stops at the end of them or after a command that is in error. To continue after n errors, set the option maxerr=*n* (0 by default) in the option list.

 **Note 1:** It is possible to specify the SRCDEF option when creating an EXECSRC table. It will be the command sent by default when a WHERE clause is not specified.

 **Note 2:** Backslashes inside commands must be escaped. Simple quotes must be escaped if the command is specified between simple quotes, and double quotes if it is specified between double quotes.

 **Note 3:** Sent commands apply in the specified database. However, they can address any table within this database.

 **Note 4:** Currently, all commands are executed in mode AUTOCOMMIT.

 ### Retrieving Warnings and Notes

 If a sent command causes warnings to be issued, it is useless to resend a “show warnings” command because the MariaDB server is opened and closed when sending commands. Therefore, getting warnings requires a specific (and tricky) way.

 To indicate that warning text must be added to the returned result, you must send a multi-command query containing “pseudo” commands that are not sent to the server but directly interpreted by the EXECSRC table. These “pseudo” commands are:

 

|  |  |
| --- | --- |
| **Warning** | To get warnings |
| **Note** | To get notes |
| **Error** | To get errors returned as warnings (?) |

 Note that they must be spelled (case insensitive) exactly as above, no final “s”. For instance:

 
```
select * from send where command in ('Warning','Note',
'drop table if exists try',
'create table try (id int key auto_increment, msg varchar(32) not
null) engine=aria',
"insert into try(msg) values('One'),(NULL),('Three') ",
"insert into try values(2,'Deux') on duplicate key update msg =
'Two'",
"insert into try(message) values('Four'),('Five'),('Six')",
'insert into try(id) values(NULL)',
"update try set msg = 'Four' where id = 4",
'select * from try');

```

This can return something like this:

 


| command | warnings | number | message |
| --- | --- | --- | --- |
| `drop table if exists try` | 1 | 0 | Affected rows |
| Note | 0 | 1051 | Unknown table 'try' |
| `create table try (id int key auto_increment, msg...` | 0 | 0 | Affected rows |
| `insert into try(msg) values('One'),(NULL),('Three')` | 1 | 3 | Affected rows |
| Warning | 0 | 1048 | Column 'msg' cannot be null |
| `insert into try values(2,'Deux') on duplicate key...` | 0 | 2 | Affected rows |
| `insert into try(msge) values('Four'),('Five'),('Six')` | 0 | 1054 | Unknown column 'msge' in 'field list' |
| `insert into try(id) values(NULL)` | 1 | 1 | Affected rows |
| Warning | 0 | 1364 | Field 'msg' doesn't have a default value |
| `update try set msg = 'Four' where id = 4` | 0 | 1 | Affected rows |
| `select * from try` | 0 | 2 | Result set columns |

 
The execution continued after the command in error because of the MAXERR option. Normally this would have stopped the execution.

 Of course, the last “select” command is useless here because it cannot return the table contain. Another MYSQL table without the EXECSRC option and with proper column definition should be used instead.

 Connection Engine Limitations
-----------------------------

 ### Data types

 There is a maximum key.index length of 255 bytes. You may be able to declare the table without an index and rely on the engine condition pushdown and remote schema.

 The following types can't be used:

 * [BIT](../bit/index)
* [BINARY](../binary/index)
* [TINYBLOB](../tinyblob/index), [BLOB](../blob/index), [MEDIUMBLOB](../mediumblob/index), [LONGBLOB](../longblob/index)
* [TINYTEXT](../tinytext/index), [MEDIUMTEXT](../mediumtext/index), [LONGTEXT](../longtext/index)
* [ENUM](../enum/index)
* [SET](../set/index)
* [Geometry types](../geometry-types/index)

 Note: [TEXT](../text/index) is allowed. However, the handling depends on the values given to the [connect\_type\_conv](../connect-system-variables/index#connect_type_conv) and [connect\_conv\_size](../connect-system-variables/index#connect_conv_size) system variables, and by default no conversion of TEXT columns is permitted.

 ### SQL Limitations

 The following SQL queries are not supported

 * [REPLACE INTO](../replace/index)
* [INSERT ... ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

 CONNECT MYSQL versus FEDERATED
------------------------------

 The CONNECT MYSQL table type should not be regarded as a replacement for the [FEDERATED(X)](../federatedx-storage-engine/index) engine. The main use of the MYSQL type is to access other engine tables as if they were CONNECT tables. This was necessary when accessing tables from some CONNECT table types such as [TBL](../connect-table-types-tbl-table-type-table-list/index), [XCOL](../connect-table-types-xcol-table-type/index), [OCCUR](../connect-table-types-occur-table-type/index), or [PIVOT](../connect-table-types-pivot-table-type/index) that are designed to access CONNECT tables only. When their target table is not a CONNECT table, these types are silently using internally an intermediate MYSQL table.

 However, there are cases where you can use MYSQL CONNECT tables yourself, for instance:

 1. When the table will be used by a [TBL](../connect-table-types-tbl-table-type-table-list/index) table. This enables you to specify the connection parameters for each sub-table and is more efficient than using a local FEDERATED sub-table.
2. When the desired returned data is directly specified by the SRCDEF option. This is great to let the remote server do most of the job, such as grouping and/or joining tables. This cannot be done with the FEDERATED engine.
3. To take advantage of the *push\_cond* facility that adds a where clause to the command sent to the remote table. This restricts the size of the result set and can be crucial for big tables.
4. For tables with the EXECSRC option on.
5. When doing tests. For instance to check a connection string.

 If you need multi-table updating, deleting, or bulk inserting on a remote table, you can alternatively use the FEDERATED engine or a “send” table specifying the EXECSRC option on.

 See also
--------

 * [Using the TBL and MYSQL types together](../connect-table-types-using-the-tbl-and-mysql-types-together/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-mysql-table-type-accessing-mysqlmariadb-tables/>

CONNECT PROXY Table Type
========================

     A `PROXY` table is a table that accesses and reads the data of another table or view. For instance, to create a table based on the boys `FIX` table:

 
```
create table xboy engine=connect 
  table_type=PROXY tabname=boys;

```

Simply, `PROXY` being the default type when `TABNAME` is specified:

 
```
create table xboy engine=connect tabname=boys;

```

Because the boys table can be directly used, what can be the use of a proxy table? Well, its main use is to be internally used by other table types such as [TBL](../connect-table-types-tbl-table-type-table-list/index), [XCOL](../connect-table-types-xcol-table-type/index), [OCCUR](../connect-table-types-occur-table-type/index), or [PIVOT](../connect-table-types-pivot-table-type/index). Sure enough, PROXY tables are CONNECT tables, meaning that they can be based on tables of any engines and accessed by table types that need to access CONNECT tables.

 Proxy on non-CONNECT Tables
---------------------------

 When the sub-table is a view or not a CONNECT table, CONNECT internally creates a temporary CONNECT table of [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) type to access it. This connection uses the same default parameters as for a `MYSQL` table. It is also possible to specify them to the `PROXY` table using in the `PROXY` declaration the same `OPTION_LIST` options as for a `MYSQL` table. Of course, it is simpler and more natural to use directly the MYSQL type in this case.

 Normally, the default parameters should enable the `PROXY` table to reconnect the server. However, an issue is when the current user was logged using a password. The security protocol prevents CONNECT to retrieve this password and requires it to be given in the `PROXY` table create statement. For instance adding to it:

 
```
... option_list='Password=mypass';

```

However, it is often not advisable to write in clear a password that can be seen by all user able to see the table declaration by show create table, in particular, if the table is used when the current user is root. To avoid this, a specific user should be created on the local host that will be used by proxy tables to retrieve local tables. This user can have minimum grant options, for instance SELECT on desired directories, and needs no password. Supposing ‘proxy’ is such a user, the option list to add will be:

 
```
... option_list='user=proxy';

```

Using a PROXY Table as a View
-----------------------------

 A `PROXY` table can also be used by itself to modify the way a table is viewed. For instance, a proxy table does not use the indexes of the object table. It is also possible to define its columns with different names or type, to use only some of them or to changes their order. For instance:

 
```
create table city (
  city varchar(11),
  boy char(12) flag=1,
  birth date)
engine=CONNECT tabname=boys;
select * from city;

```

This will display:

 


| city | boy | birth |
| --- | --- | --- |
| Boston | John | 1986-01-25 |
| Boston | Henry | 1987-06-07 |
| San Jose | George | 1981-08-10 |
| Chicago | Sam | 1979-11-22 |
| Dallas | James | 1992-05-13 |
| Boston | Bill | 1986-09-11 |

 
Here we did not have to specify column format or offset because data are retrieved from the boys table, not directly from the boys.txt file. The flag option of the *boy* column indicates that it correspond to the first column of the boys table, the *name* column.

 Avoiding PROXY table loop
-------------------------

 CONNECT is able to test whether a `PROXY`, or `PROXY`-based, table refers directly or indirectly to itself. If a direct reference can tested at table creation, an indirect reference can only be tested when executing a query on the table. However, this is possible only for local tables. When using remote tables or views, a problem can occur if the remote table or the view refers back to one of the local tables of the chain. The same caution should be used than when using `[FEDERATEDX](../federatedx-storage-engine/index)` tables.

 **Note:** All `PROXY` or `PROXY`-based tables are read-only in this version.

 Modifying Operations
--------------------

 All [INSERT](../insert/index) / [UPDATE](../update/index) / [DELETE](../delete/index) operations can be used with proxy tables. However, the same restrictions applying to the source table also apply to the proxy table.

 
Note: All PROXY and PROXY-based table types are not indexable.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-proxy-table-type/>

CONNECT JDBC Table Type: Accessing Tables from Another DBMS
===========================================================

    The JDBC table type should be distributed with all recent versions of MariaDB. However, if the automatic compilation of it is possible after the java JDK was installed, the complete distribution of it is not fully implemented in older versions. The distributed JdbcInterface.jar file contains the JdbcInterface wrapper only. New versions distribute a JavaWrappers.jar that contains all currently existing wrappers.

 This will require that:

 1. The Java SDK is installed on your system.
2. The java wrapper class files are available on your system.
3. And of course, some JDBC drivers exist to be used with the matching DBMS.

 Point 2 was made automatic in the newest versions of MariaDB.

 Compiling From Source Distribution
----------------------------------

 Even when the Java JDK has been installed, CMake sometimes cannot find the location where it stands. For instance on Linux the Oracle Java JDK package might be installed in a path not known by the CMake lookup functions causing error message such as:

 
```
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:148 (message): 
  Could NOT find Java (missing: Java_JAR_EXECUTABLE Java_JAVAC_EXECUTABLE 
  Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)

```

When this happen, provide a Java prefix as a hint on where the package was loaded. For instance on Ubuntu I was obliged to enter:

 
```
export JAVA_HOME=/usr/lib/jvm/java-8-oracle

```

After that, the compilation of the CONNECT JDBC type was completed successfully.

 ### Compiling the Java source files

 They are the source of the java wrapper classes used to access JDBC drivers. In the source distribution, they are located in the CONNECT source directory. 

 The default wrapper, JdbcInterface, is the only one distributed with binary distribution. It uses the standard way to get a connection to the drivers via the DriverManager.getConnection method. Other wrappers, only available with source distribution, enable connection to a Data Source, eventually implementing pooling. However, they must be compiled and installed manually.

 The available wrappers are:

 


| Wrapper | Description |
| --- | --- |
| JdbcInterface | Used to make the connection with available drivers the standard way. |
| ApacheInterface | Based on the Apache common-dbcp2 package this interface enables making connections to DBCP data sources with any JDBC drivers. |
| MariadbInterface | Makes connection to a MariaDB data source. |
| MysqlInterface | Makes connection to a Mysql data source. Must be used with a MySQL driver that implements data sources. |
| OracleInterface | Makes connection to an Oracle data source. |
| PostgresqlInterface | Makes connection to a Postgresql data source. |

 
The wrapper used by default is specified by the [connect\_java\_wrapper](../connect-system-variables/index#connect_java_wrapper) session variable and is initially set to `wrappers/JdbcInterface`. The wrapper to use for a table can also be specified in the option list as a wrapper option of the “create table” statements.

 Note: Conforming java naming usage, class names are preceded by the java package name with a slash separator. However, this is not mandatory for CONNECT which adds the package name if it is missing. 

 The JdbcInterface wrapper is always usable when Java is present on your machine. Binary distributions have this wrapper already compiled as a JdbcInterface.jar file installed in the plugin directory whose path is automatically included in the class path of the JVM. Recent versions also add a JavaWrappers.jar that contains all these wrappers. Therefore there is no need to worry about its path.

 Compiling the ApacheInterface wrapper requires that the Apache common-DBCP2 package be installed. Other wrappers are to be used only with the matching JDBC drivers that must be available when compiling them.

 Installing the jar file in the plugin directory is the best place because it is part of the class path. Depending on what is installed on your system, the source files can be reduced accordingly. To compile only the JdbcInterface.java file the CMAKE\_JAVA\_INCLUDE\_PATH is not required. Here the paths are the ones existing on my Windows 7 machine and should be localized. 

 Setting the Required Information
--------------------------------

 Before any operation with a JDBC driver can be made, CONNECT must initialize the environment that will make working with Java possible. This will consist of:

 1. Loading dynamically the JVM library module.
2. Creating the Java Virtual Machine.
3. Establishing contact with the java wrapper class.
4. Connecting to the used JDBC driver.

 Indeed, the JVM library module is not statically linked to the CONNECT plugin. This is to make it possible to use a CONNECT plugin that has been compiled with the JDBC table type on a machine where the Java SDK is not installed. Otherwise, users not interested in the JDBC table type would be obliged to install the Java SDK on their machine to be able to load the CONNECT storage engine.

 ### JVM Library Location

 If the JVM library (jvm.dll on Windows, libjvm.so on Linux) was not placed in the standard library load path, CONNECT cannot find it and must be told where to search for it. This happens in particular on Linux when the Oracle Javapackage was installed in a private location.

 If the JAVA\_HOME variable was exported as explained above, CONNECT can sometimes find it using this information. Otherwise, its search path can be added to the LD\_LIBRARY\_PATH environment variable. But all this is complicated because making environment variables permanent on Linux is painful (many different methods must be used depending on the Linux version and the used shell).

 This is why CONNECT introduced a new global variable connect\_jvm\_path to store this information. It can be set when starting the server as a command line option or even afterwards before the first use of the JDBC table type. For example:

 
```
set global connect_jvm_path="/usr/lib/jvm/java-8-oracle/jre/lib/i386/client"

```

or

 
```
set global connect_jvm_path="/usr/lib/jvm/java-8-oracle/jre/lib/i386/server"

```

The client library is smaller and faster for connection. The server library is more optimized and can be used in case of heavy load usage.

 Note that this may not be required on Windows because the path to the JVM library can sometimes be found in the registry.

 Once this library is loaded, CONNECT can create the required Java Virtual Machine.

 ### Java Class Path

 This is the list of paths Java searches when loading classes. With CONNECT, the classes to load will be the java wrapper classes used to communicate with the drivers , and the used JDBC driver classes that are grouped inside jar files. If the ApacheInterface wrapper must be used, the class path must also include all three jars used by the Apache package.

 
Caution: This class path is passed as a parameter to the Java Virtual Machine (JVM) when creating it and cannot be modified as it is a read only property. In addition, because MariaDB is a multi-threading application, this JVM cannot be destroyed and will be used throughout the entire life of the MariaDB server. Therefore, be sure it is correctly set before you use the JDBC table type for the first time. Otherwise, there will be practically no alternative than to shut down the server and restart it.

 
The path to the wrapper classes must point to the directory containing the wrappers sub-directory. If a JdbcInterface.jar file was made, its path is the directory where it is located followed by the jar file name. It is unclear where because this will depend on the installation process. If you start from a source distribution, it can be in the storage/connect directory where the CONNECT source files are or where you moved them or compiled the JdbcInterface.jar file.

 For binary distributions, there is nothing to do because the jar file has been installed in the mysql share directory whose path is always automatically included in the class path available to the JVM.

 Remaining are the paths of all the installed JDBC drivers that you intend to use. Remember that their path must include the jar file itself. Some applications use an environment variable CLASSPATH to contain them. Paths are separated by ‘:’ on Linux and by ‘;’ on Windows.

 If the CLASSPATH variable actually exists and if it is available inside MariaDB, so far so good. You can check this using an UDF function provided by CONNECT that returns environment variable values:

 
```
create function envar returns string soname 'ha_connect.so';
select envar('CLASSPATH');

```

Most of the time, this will return null or some required files are missing. This is why CONNECT introduced a global variable to store this information. The paths specified in this variable will be added and have precedence to the ones, if any, of the CLASSPATH environment variable. As for the jvm path, this variable connect\_class\_path should be specified when starting the server but can also be set before using the JDBC table type for the first time.

 The current directory (sql/data) is also placed by CONNECT at the beginning of the class path.

 As an example, here is how I start MariaDB when doing tests on Linux:

 
```
olivier@olivier-Aspire-8920:~$ sudo /usr/local/mysql/bin/mysqld -u root --console --default-storage-engine=myisam --skip-innodb --connect_jvm_path="/usr/lib/jvm/java-8-oracle/jre/lib/i386/server" --connect_class_path="/home/olivier/mariadb/10.1/storage/connect:/media/olivier/SOURCE/mysql-connector-java-6.0.2/mysql-connector-java-6.0.2-bin.jar"

```

CONNECT JDBC Tables
-------------------

 These tables are given the type JDBC. For instance, supposing you want to access the boys table located on and external local or remote database management system providing a JDBC connector:

 
```
create table boys (
name char(12),
city char(12),
birth date,
hired date);

```

To access this table via JDBC you can create a table such as:

 
```
create table jboys engine=connect table_type=JDBC tabname=boys
connection='jdbc:mysql://localhost/dbname?user=root';

```

The CONNECTION option is the URL used to establish the connection with the remote server. Its syntax depends on the external DBMS and in this example is the one used to connect as root to a MySQL or MariaDB local database using the MySQL JDBC connector.

 As for ODBC, the columns definition can be omitted and will be retrieved by the discovery process. The restrictions concerning column definitions are the same as for ODBC.

 Note: The dbname indicated in the URL corresponds for many DBMS to the catalog information. For MySQL and MariaDB it is the schema (often called database) of the connection.

 ### Using a Federated Server

 Alternatively, a JDBC table can specify its connection options via a Federated server. For instance, supposing you have a table accessing an external Postgresql table defined as:

 
```
create table juuid engine=connect table_type=JDBC tabname=testuuid
connection='jdbc:postgresql:test?user=postgres&password=pwd';

```

You can create a Federated server:

 
```
create server 'post1' foreign data wrapper 'postgresql' options (
HOST 'localhost',
DATABASE 'test',
USER 'postgres',
PASSWORD 'pwd',
PORT 0,
SOCKET '',
OWNER 'postgres');

```

Now the JDBC table can be created by:

 
```
create table juuid engine=connect table_type=JDBC connection='post1' tabname=testuuid;

```

or by:

 
```
create table juuid engine=connect table_type=JDBC connection='post1/testuuid';

```

In any case, the location of the remote table can be changed in the Federated server without having to alter all the tables using this server.

 JDBC needs a URL to establish a connection. CONNECT was able to construct that URL from the information contained in such Federated server definition when the URL syntax is similar to the one of MySQL, MariaDB or Postgresql. However, other DBMSs such as Oracle use a different URL syntax. In this case, simply replace the HOST information by the required URL in the Federated server definition. For instance:

 
```
create server 'oracle' foreign data wrapper 'oracle' options (
HOST 'jdbc:oracle:thin:@localhost:1521:xe',
DATABASE 'SYSTEM',
USER 'system',
PASSWORD 'manager',
PORT 0,
SOCKET '',
OWNER 'SYSTEM');

```

Now you can create an Oracle table with something like this:

 
```
create table empor engine=connect table_type=JDBC connection='oracle/HR.EMPLOYEES';

```

Note: Oracle, as Postgresql, does not seem to understand the DATABASE setting as the table schema that must be specified in the Create Table statement.

 Connecting to a JDBC driver
---------------------------

 When the connection to the driver is established by the JdbcInterface wrapper class, it uses the options that are provided when creating the CONNECT JDBC tables. Inside the default Java wrapper, the driver’s main class is loaded by the DriverManager.getConnection function that takes three arguments:

 


|  |  |
| --- | --- |
| URL | That is the URL that you specified in the CONNECTION option. |
| User | As specified in the OPTION\_LIST or NULL if not specified. |
| Password | As specified in the OPTION\_LIST or NULL if not specified. |

 
The URL varies depending on the connected DBMS. Refer to the documentation of the specific JDBC driver for a description of the syntax to use. User and password can also be specified in the option list.

 Beware that the database name in the URL can be interpreted differently depending on the DBMS. For MySQL this is the schema in which the tables are found. However, for Postgresql, this is the catalog and the schema must be specified using the CONNECT dbname option. 

 For instance a table accessing a Postgresql table via JDBC can be created with a create statement such as:

 
```
create table jt1 engine=connect table_type=JDBC
connection='jdbc:postgresql://localhost/mtr' dbname=public tabname=t1
option_list='User=mtr,Password=mtr'; 

```

Note: In previous versions of JDBC, to obtain a connection, java first had to initialize the JDBC driver by calling the method Class.forName. In this case, see the documentation of your DBMS driver to obtain the name of the class that implements the interface java.sql.Driver. This name can be specified as an option DRIVER to be put in the option list. However, most modern JDBC drivers since version 4 are self-loading and do not require this option to be specified.

 The wrapper class also creates some required items and, in particular, a statement class. Some characteristics of this statement will depend on the options specified when creating the table:

 


|  |  |
| --- | --- |
| Scrollable | To be specified in the option list. Determines the cursor type: no= forward\_only or yes=scroll\_insensitive. |
| Block\_size | Will be used to set the statement fetch size. |

 
### Fetch Size

 The fetch size determines the number of rows that are internally retrieved by the driver on each interaction with the DBMS. Its default value depends on the JDBC driver. It is equal to 10 for some drivers but not for the MySQL or MariaDB connectors.

 The MySQL/MariaDB connectors retrieve all the rows returned by one query and keep them in a memory cache. This is generally fine in most cases, but not when retrieving a large result set that can make the query fail with a memory exhausted exception.

 To avoid this, when accessing a big table and expecting large result sets, you should specify the BLOCK\_SIZE option to 1 (the only acceptable value). However a problem remains:

 Suppose you execute a query such as:

 
```
select id, name, phone from jbig limit 10;

```

Not knowing the limit clause, CONNECT sends to the remote DBMS the query:

 
```
SELECT id, name, phone FROM big;

```

In this query big can be a huge table having million rows. Having correctly specified the block size as 1 when creating the table, the wrapper just reads the 10 first rows and stops. However, when closing the statement, these MySQL/MariaDB drivers must still retrieve all the rows returned by the query. This is why, the wrapper class when closing the statement also cancels the query to stop that extra reading.

 The bad news is that if it works all right for some previous versions of the MySQL driver, it does not work for new versions as well as for the MariaDB driver that apparently ignores the cancel command. The good news is that you can use an old MySQL driver to access MariaDB databases. It is also possible that this bug will be fixed in future versions of the drivers.

 ### Connection to a Data Source

 This is the java preferred way to establish a connection because a data source can keep a pool of connections that can be re-used when necessary. This makes establishing connections much faster once it was done for the first time.

 CONNECT provide additional wrappers whose files are located in the CONNECT source directory. The wrapper to use can be specified in the global variable connect\_java\_wrapper, which defaults to “JdbcInterface”.

 It can also be specified for a table in the option list by setting the option wrapper to its name. For instance:

 
```
create table jboys 
engine=CONNECT table_type=JDBC tabname='boys'
connection='jdbc:mariadb://localhost/connect?user=root&useSSL=false'
option_list='Wrapper=MariadbInterface,Scrollable=1';

```

They can be used instead of the standard JdbcInterface and are using created data sources.

 The Apache one uses data sources implemented by the Apache-commons-dbcp2 package and can be used with all drivers including those not implementing data sources. However, the Apache package must be installed and its three required jar files accessible via the class path.

 1. commons-dbcp2-2.1.1.jar
2. commons-pool2-2.4.2.jar
3. commons-logging-1.2.jar

 Note: the versions numbers can be different on your installation.

 The other ones use data sources provided by the matching JDBC driver. There are currently four wrappers to be used with mysql-6.0.2, mariadb, oracle and postgresql.

 Unlike the class path, the used wrapper can be changed even after the JVM machine was created.

 Random Access to JDBC Tables
----------------------------

 The same methods described for ODBC tables can be used with JDBC tables.

 Note that in the case of the MySQL or MariaDB connectors, because they internally read the whole result set in memory, using the MEMORY option would be a waste of memory. It is much better to specify the use of a scrollable cursor when needed.

 Other Operations with JDBC Tables
---------------------------------

 Except for the way the connection string is specified and the table type set to JDBC, all operations with ODBC tables are done for JDBC tables the same way. Refer to the ODBC chapter to know about:

 * Accessing specified views (SRCDEF)
* Data modifying operations.
* Sending commands to a data source.
* JDBC catalog information.

 Note: Some JDBC drivers fail when the global time\_zone variable is ambiguous, which sometimes happens when it is set to SYSTEM. If so, reset it to a not ambiguous value, for instance:

 
```
set global time_zone = '+2:00';

```

JDBC Specific Restrictions
--------------------------

 Connecting via data sources created externally (for instance using Tomcat) is not supported yet.

 Other restrictions are the same as for the ODBC table type.

 Handling the UUID Data Type
---------------------------

 PostgreSQL has a native UUID data type, internally stored as BIN(16). This is neither an SQL nor a MariaDB data type. The best we can do is to handle it by its character representation.

 UUID will be translated to CHAR(36) when column definitions are set using discovery. Locally a PostgreSQL UUID column will be handled like a CHAR or VARCHAR column. Example:

 Using the PostgreSQL table testuuid in the text database:

 
```
 Table « public.testuuid »
 Column | Type | Default
--------+------+--------------------
 id     | uuid | uuid_generate_v4()
 msg    | text | 

```

Its column definitions can be queried by:

 
```
create or replace table juuidcol engine=connect table_type=JDBC tabname=testuuid catfunc=columns
connection='jdbc:postgresql:test?user=postgres&password=pwd';

```


```
select table_name "Table", column_name "Column", data_type "Type", 
  type_name "Name", column_size "Size" 
 from juuidcol;

```

This query returns:

 


| Table | Column | Type | Name | Size |
| --- | --- | --- | --- | --- |
| testuuid | id | 1111 | uuid | 2147483647 |
| testuuid | msg | 12 | text | 2147483647 |

 
Note: PostgreSQL, when a column size is undefined, returns 2147483647, which is not acceptable for MariaDB. CONNECT change it to the value of the connect\_conv\_size session variable. Also, for TEXT columns the data type returned is 12 (SQL\_VARCHAR) instead of -1 the SQL\_TEXT value.

 Accessing this table via JDBC by:

 
```
CREATE TABLE juuid ENGINE=connect TABLE_TYPE=JDBC TABNAME=testuuid
CONNECTION='jdbc:postgresql:test?user=postgres&password=pwd';

```

it will be created by discovery as:

 
```
CREATE TABLE `juuid` (
  `id` char(36) DEFAULT NULL,
  `msg` varchar(8192) DEFAULT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:postgresql:test?user=postgres&password=pwd' `TABLE_TYPE`='JDBC' `TABNAME`='testuuid';

```

Note: 8192 being here the \_connect\_conv\_size\_ value.

 Let's populate it:

 
```
insert into juuid(msg) values('First');
insert into juuid(msg) values('Second');
select * from juuid;

```

Result:

 


| id | msg |
| --- | --- |
| 4b173ee1-1488-4355-a7ed-62ba59c2b3e7 | First |
| 6859f850-94a7-4903-8d3c-fc3c874fc274 | Second |

 
Here the id column values come from the DEFAULT of the PostgreSQL column that was specified as uuid\_generate\_v4().

 It can be set from MariaDB. For instance:

 
```
insert into juuid
  values('2f835fb8-73b0-42f3-a1d3-8a532b38feca','inserted');
insert into juuid values(NULL,'null');
insert into juuid values('','random');
select * from juuid;

```

Result:

 


| id | msg |
| --- | --- |
| 4b173ee1-1488-4355-a7ed-62ba59c2b3e7 | First |
| 6859f850-94a7-4903-8d3c-fc3c874fc274 | Second |
| 2f835fb8-73b0-42f3-a1d3-8a532b38feca | inserted |
| <null> | null |
| 8fc0a30e-dc66-4b95-ba57-497a161f4180 | random |

 
The first insert specifies a valid UUID character representation. The second one set it to NULL. The third one (a void string) generates a Java random UUID. UPDATE commands obey the same specification.

 These commands both work:

 
```
select * from juuid where id = '2f835fb8-73b0-42f3-a1d3-8a532b38feca';
delete from juuid where id = '2f835fb8-73b0-42f3-a1d3-8a532b38feca';

```

However, this one fails:

 
```
select * from juuid where id like '%42f3%';

```

Returning:

 1296: Got error 174 'ExecuteQuery: org.postgresql.util.PSQLException: ERROR: operator does not exist: uuid ~ unknown hint: no operator corresponds to the data name and to the argument types.

 because CONNECT cond\_push feature added the WHERE clause to the query sent to PostgreSQL:

 
```
SELECT id, msg FROM testuuid WHERE id LIKE '%42f3%'

```

and the LIKE operator does not apply to UUID in PostgreSQL.

 To handle this, a new session variable was added to CONNECT: connect\_cond\_push. It permits to specify if cond\_push is enabled or not for CONNECT and defaults to 1 (enabled). In this case, you can execute:

 
```
set connect_cond_push=0;

```

Doing so, the where clause will be executed by MariaDB only and the query will not fail anymore. 

 Executing the JDBC tests
------------------------

 Four tests exist but they are disabled because requiring some work to localized them according to the operating system and available java package and JDBC drivers and DBMS.

 Two of them, jdbc.test and jdbc\_new.test, are accessing MariaDB via JDBC drivers that are contained in a fat jar file that is part of the test. They should be executable without anything to do on Windows; simply adding the option –enable-disabled when running the tests. 

 However, on Linux these tests can fail to locate the JVM library. Before executing them, you should export the JAVA\_HOME environment variable set to the prefix of the java installation or export the LD\_LIBRARY\_PATH containing the path to the JVM lib.

 Fixing Problem With mariadb-dump
--------------------------------

 In some case or some platform, when CONNECT is set up for use with JDBC table types, this causes [mariadb-dump](../mariadb-dump/index) with the option --all-databases to fail.

 This was reported by Robert Dyas who found the cause - see the discussion at [MDEV-11238](https://jira.mariadb.org/browse/MDEV-11238).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-jdbc-table-type-accessing-tables-from-another-dbms/>

S3 Storage Engine Internals
===========================

    
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**The [S3 storage engine](../s3-storage-engine/index) has been available since [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/).

   The [S3 storage engine](../s3-storage-engine/index) is based on the [Aria](../aria-storage-engine/index) code. Internally the S3 storage inherits from the Aria code, with hooks that change reads, so that instead of reading data from the local disk it reads things from S3.

 The S3 engine uses it's own page cache, modified to be able to handle reading blocks from S3 (of size `s3_block_size`). Internally the S3 page cache uses pages of [aria-block-size](../aria-system-variables/index#aria_block_size) for splitting the blocks read from S3.

 ALTER TABLE
-----------

 [ALTER TABLE](../alter-table/index) will first create a local table in the normal Aria on disk format and then move both index and data to S3 in buckets of S3\_BLOCK\_SIZE. The .frm file is also copied to S3 for discovery to support discovery for other MariaDB servers. One can also use ALTER TABLE to change the structure of an S3 table.

 Partitioning Tables
-------------------

 Starting from [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/), S3 tables can also be used with [Partitioning tables](../partitioning-tables/index). All [ALTER PARTITION](../alter-table/index) operations are supported except:

 * REBUILD PARTITION
* TRUNCATE PARTITION
* REORGANIZE PARTITION

 Big Reads
---------

 One of the properties of many S3 implementations is that they favor large reads. It's said that 4M gives the best performance, which is why the default value for `S3_BLOCK_SIZE` is 4M.

 Compression
-----------

 If compression (`COMPRESSION_ALGORITHM=zlib`) is used, then all index blocks and data blocks are compressed. The `.frm` file and Aria definition header (first page/pages in the index file) are not compressed as these are used by discovery/open.

 If compression is used, then the local block size is `S3_BLOCK_SIZE`, but the block stored in S3 will be the size of the compressed block.

 Typical compression we have seen is in the range of 80% saved space.

 Structure Stored on S3
----------------------

 The table will be copied in S3 into the following locations:

 
```
frm file (for discovery):
s3_bucket/database/table/frm

First index block (contains description of the Aria file):
s3_bucket/database/table/aria

Rest of the index file:
s3_bucket/database/table/index/block_number

Data file:
s3_bucket/database/table/data/block_number

```

block\_number is a 6-digit decimal number, prefixed with 0 (Can be larger than 6 numbers, the prefix is just for nice output)

 Using the awsctl Python Tool to Examine Data
--------------------------------------------

 ### Installing awsctl on Linux

 
```
# install python-pip (on an OpenSuse distribution)
# use the appropriate command for your distribution
zypper install python-pip
pip install --upgrade pip

# the following installs awscli tools in ~/.local/bin
pip install --upgrade --user awscli
export PATH=~/.local/bin:$PATH

# configure your aws credentials
aws configure

```

### Using the awsctl Tool

 One can use the `aws` python tool to see how things are stored on S3:

 
```
shell> aws s3 ls --recursive s3://mariadb-bucket/
2019-05-10 17:46:48       8192 foo/test1/aria
2019-05-10 17:46:49    3227648 foo/test1/data/000001
2019-05-10 17:46:48        942 foo/test1/frm
2019-05-10 17:46:48    1015808 foo/test1/index/000001

```

To delete an obsolete table `foo.test1` one can do:

 
```
shell> ~/.local/bin/aws s3 rm --recursive s3://mariadb-bucket/foo/test1
delete: s3://mariadb-bucket/foo/test1/aria
delete: s3://mariadb-bucket/foo/test1/data/000001
delete: s3://mariadb-bucket/foo/test1/frm
delete: s3://mariadb-bucket/foo/test1/index/000001

```

See Also
--------

 * [Using the S3 storage engine](../using-the-s3-storage-engine/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/s3-storage-engine-internals/>

CONNECT XCOL Table Type
=======================

     `XCOL` tables are based on another table or view, like `[PROXY](../connect-table-types-proxy-table-type/index)` tables. This type can be used when the object table has a column that contains a list of values.

 Suppose we have a *'children'* table that can be displayed as:

 


| name | childlist |
| --- | --- |
| Sophie | Vivian, Antony |
| Lisbeth | Lucy,Charles,Diana |
| Corinne |  |
| Claude | Marc |
| Janet | Arthur, Sandra, Peter, John |

 
We can have a different view on these data, where each child will be associated with his/her mother by creating an `XCOL` table by:

 
```
CREATE TABLE xchild (
  mother char(12) NOT NULL,
  child char(12) DEFAULT NULL flag=2
) ENGINE=CONNECT table_type=XCOL tabname='chlist'
option_list='colname=child';

```

The `COLNAME` option specifies the name of the column receiving the list items. This will return from:

 
```
select * from xchild;

```

The requested view:

 


| mother | child |
| --- | --- |
| Sophia | Vivian |
| Sophia | Antony |
| Lisbeth | Lucy |
| Lisbeth | Charles |
| Lisbeth | Diana |
| Corinne | NULL |
| Claude | Marc |
| Janet | Arthur |
| Janet | Sandra |
| Janet | Peter |
| Janet | John |

 
Several things should be noted here:

 * When the original *children* field is void, what happens depends on the NULL specification of the "multiple" column. If it is nullable, like here, a void string will generate a NULL value. However, if the column is not nullable, no row will be generated at all.
* Blanks after the separator are ignored.
* No copy of the original data was done. Both tables use the same source data.
* Specifying the column definitions in the `CREATE TABLE` statement is optional.

 The "multiple" column *child* can be used as any other column. For instance:

 
```
select * from xchild where substr(child,1,1) = 'A';

```

This will return:

 


| Mother | Child |
| --- | --- |
| Sophia | Antony |
| Janet | Arthur |

 
If a query does not involve the "multiple" column, no row multiplication will be done. For instance:

 
```
select mother from xchild;

```

This will just return all the mothers:

 


| mother |
| --- |
| Sophia |
| Lisbeth |
| Corinne |
| Claude |
| Janet |

 
The same occurs with other types of select statements, for instance:

 
```
select count(*) from xchild;      -- returns 5
select count(child) from xchild;  -- returns 10
select count(mother) from xchild; -- returns 5

```

Grouping also gives different result:

 
```
select mother, count(*) from xchild group by mother;

```

Replies:

 


| mother | count(\*) |
| --- | --- |
| Claude | 1 |
| Corinne | 1 |
| Janet | 1 |
| Lisbeth | 1 |
| Sophia | 1 |

 
While the query:

 
```
select mother, count(child) from xchild group by mother;

```

Gives the more interesting result:

 


| mother | count(child) |
| --- | --- |
| Claude | 1 |
| Corinne | 0 |
| Janet | 4 |
| Lisbeth | 3 |
| Sophia | 2 |

 
Some more options are available for this table type:

 


| Option | Description |
| --- | --- |
| Sep\_char | The separator character used in the "multiple" column, defaults to the comma. |
| Mult | Indicates the max number of multiple items. It is used to internally calculate the max size of the table and defaults to 10. (To be specified in `OPTION_LIST`). |

 
Using Special Columns with XCOL
-------------------------------

 Special columns can be used in XCOL tables. The mostly useful one is ROWNUM that gives the rank of the value in the list of values. For instance:

 
```
CREATE TABLE xchild2 (
rank int NOT NULL SPECIAL=ROWID,
mother char(12) NOT NULL,
child char(12) NOT NULL flag=2
) ENGINE=CONNECT table_type=XCOL tabname='chlist' option_list='colname=child';

```

This table will be displayed as:

 


| rank | mother | child |
| --- | --- | --- |
| 1 | Sophia | Vivian |
| 2 | Sophia | Antony |
| 1 | Lisbeth | Lucy |
| 2 | Lisbeth | Charles |
| 3 | Lisbeth | Diana |
| 1 | Claude | Marc |
| 1 | Janet | Arthur |
| 2 | Janet | Sandra |
| 3 | Janet | Peter |
| 4 | Janet | John |

 
To list only the first child of each mother you can do:

 
```
SELECT mother, child FROM xchild2 where rank = 1 ;

```

returning:

 


| mother | child |
| --- | --- |
| Sophia | Vivian |
| Lisbeth | Lucy |
| Claude | Marc |
| Janet | Arthur |

 
However, note the following pitfall: trying to get the names of all mothers having more than 2 children cannot be done by:

 
```
SELECT mother FROM xchild2 where rank > 2;

```

This is because with no row multiplication being done, the rank value is always 1. The correct way to obtain this result is longer but cannot use the ROWNUM column:

 
```
SELECT mother FROM xchild2 group by mother having count(child) > 2;

```

XCOL tables based on specified views
------------------------------------

 Instead of specifying a source table name via the TABNAME option, it is possible to retrieve data from a “view” whose definition is given in a new option SRCDEF . For instance:

 
```
create table xsvars engine=connect table_type=XCOL
srcdef='show variables like "optimizer_switch"'
option_list='Colname=Value';

```

Then, for instance:

 
```
select value from xsvars limit 10;

```

This will display something like:

 


| value |
| --- |
| index\_merge=on |
| index\_merge\_union=on |
| index\_merge\_sort\_union=on |
| index\_merge\_intersection=on |
| index\_merge\_sort\_intersection=off |
| engine\_condition\_pushdown=off |
| index\_condition\_pushdown=on |
| derived\_merge=on |
| derived\_with\_keys=on |
| firstmatch=on |

 
Note: All XCOL tables are read only.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-xcol-table-type/>

CONNECT OCCUR Table Type
========================

    Similarly to the `[XCOL](../connect-table-types-xcol-table-type/index)` table type, `OCCUR` is an extension to the `[PROXY](../connect-table-types-proxy-table-type/index)` type when referring to a table or view having several columns containing the same kind of data. It enables having a different view of the table where the data from these columns are put in a single column, eventually causing several rows to be generated from one row of the object table. For example, supposing we have a *pets* table:

 


| name | dog | cat | rabbit | bird | fish |
| --- | --- | --- | --- | --- | --- |
| John | 2 | 0 | 0 | 0 | 0 |
| Bill | 0 | 1 | 0 | 0 | 0 |
| Mary | 1 | 1 | 0 | 0 | 0 |
| Lisbeth | 0 | 0 | 2 | 0 | 0 |
| Kevin | 0 | 2 | 0 | 6 | 0 |
| Donald | 1 | 0 | 0 | 0 | 3 |

 
We can create an occur table by:

 
```
create table xpet (
  name varchar(12) not null,
  race char(6) not null,
  number int not null)
engine=connect table_type=occur tabname=pets
option_list='OccurCol=number,RankCol=race'
Colist='dog,cat,rabbit,bird,fish';

```

When displaying it by

 
```
select * from xpet;

```

We will get the result:

 


| name | race | number |
| --- | --- | --- |
| John | dog | 2 |
| Bill | cat | 1 |
| Mary | dog | 1 |
| Mary | cat | 1 |
| Lisbeth | rabbit | 2 |
| Kevin | cat | 2 |
| Kevin | bird | 6 |
| Donald | dog | 1 |
| Donald | fish | 3 |

 
First of all, the values of the column listed in the Colist option have been put in a unique column whose name is given by the OccurCol option. When several columns have non null (or pseudo-null) values, several rows are generated, with the other normal columns values repeated.

 In addition, an optional special column was added whose name is given by the RankCol option. This column contains the name of the source column from which the value of the OccurCol column comes from. It permits here to know the race of the pets whose number is given in *number*.

 This table type permit to make queries that would be more complicated to make on the original tables. For instance to know who as more than 1 pet of a kind, you can simply ask:

 
```
select * from xpet where number > 1;

```

You will get the result:

 


| name | race | number |
| --- | --- | --- |
| John | dog | 2 |
| Lisbeth | rabbit | 2 |
| Kevin | cat | 2 |
| Kevin | bird | 6 |
| Donald | fish | 3 |

 
**Note 1:** Like for [XCOL tables](../connect-table-types-xcol-table-type/index), no row multiplication for queries not implying the Occur column.

 **Note 2:** Because the OccurCol was declared "not null" no rows were generated for null or pseudo-null values of the column list. If the OccurCol is declared as nullable, rows are also generated for columns containing null or pseudo-null values.

 Occur tables can be also defined from views or source definition. Also, CONNECT is able to generate the column definitions if not specified. For example:

 
```
create table ocsrc engine=connect table_type=occur
colist='january,february,march,april,may,june,july,august,september,
october,november,december' option_list='rankcol=month,occurcol=day'
srcdef='select ''Foo'' name, 8 january, 7 february, 2 march, 1 april,
  8 may, 14 june, 25 july, 10 august, 13 september, 22 october, 28
  november, 14 december';

```

This table is displayed as:

 


| name | month | day |
| --- | --- | --- |
| Foo | january | 8 |
| Foo | february | 7 |
| Foo | march | 2 |
| Foo | april | 1 |
| Foo | may | 8 |
| Foo | june | 14 |
| Foo | july | 25 |
| Foo | august | 10 |
| Foo | september | 13 |
| Foo | october | 22 |
| Foo | november | 28 |
| Foo | december | 14 |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-occur-table-type/>

CONNECT PIVOT Table Type
========================

     This table type can be used to transform the result of another table or view (called the source table) into a pivoted table along “pivot” and “facts” columns. A pivot table is a great reporting tool that sorts and sums (by default) independent of the original data layout in the source table.

 For example, let us suppose you have the following “Expenses” table:

 


| Who | Week | What | Amount |
| --- | --- | --- | --- |
| Joe | 3 | Beer | 18.00 |
| Beth | 4 | Food | 17.00 |
| Janet | 5 | Beer | 14.00 |
| Joe | 3 | Food | 12.00 |
| Joe | 4 | Beer | 19.00 |
| Janet | 5 | Car | 12.00 |
| Joe | 3 | Food | 19.00 |
| Beth | 4 | Beer | 15.00 |
| Janet | 5 | Beer | 19.00 |
| Joe | 3 | Car | 20.00 |
| Joe | 4 | Beer | 16.00 |
| Beth | 5 | Food | 12.00 |
| Beth | 3 | Beer | 16.00 |
| Joe | 4 | Food | 17.00 |
| Joe | 5 | Beer | 14.00 |
| Janet | 3 | Car | 19.00 |
| Joe | 4 | Food | 17.00 |
| Beth | 5 | Beer | 20.00 |
| Janet | 3 | Food | 18.00 |
| Joe | 4 | Beer | 14.00 |
| Joe | 5 | Food | 12.00 |
| Janet | 3 | Beer | 18.00 |
| Janet | 4 | Car | 17.00 |
| Janet | 5 | Food | 12.00 |

 
Pivoting the table contents using the 'Who' and 'Week' fields for the left columns, and the 'What' field for the top heading and summing the 'Amount' fields for each cell in the new table, gives the following desired result:

 


| Who | Week | Beer | Car | Food |
| --- | --- | --- | --- | --- |
| Beth | 3 | 16.00 | 0.00 | 0.00 |
| Beth | 4 | 15.00 | 0.00 | 17.00 |
| Beth | 5 | 20.00 | 0.00 | 12.00 |
| Janet | 3 | 18.00 | 19.00 | 18.00 |
| Janet | 4 | 0.00 | 17.00 | 0.00 |
| Janet | 5 | 33.00 | 12.00 | 12.00 |
| Joe | 3 | 18.00 | 20.00 | 31.00 |
| Joe | 4 | 49.00 | 0.00 | 34.00 |
| Joe | 5 | 14.00 | 0.00 | 12.00 |

 
Note that SQL enables you to get the same result presented differently by using the “group by” clause, namely:

 
```
select who, week, what, sum(amount) from expenses
       group by who, week, what;

```

However there is no way to get the pivoted layout shown above just using SQL. Even using embedded SQL programming for some DBMS is not quite simple and automatic.

 The Pivot table type of CONNECT makes doing this much simpler.

 Using the PIVOT Tables Type
---------------------------

 To get the result shown in the example above, just define it as a new table with the statement:

 
```
create table pivex
engine=connect table_type=pivot tabname=expenses;

```

You can now use it as any other table, for instance to display the result shown above, just say:

 
```
select * from pivex;

```

The CONNECT implementation of the PIVOT table type does much of the work required to transform the source table:

 1. Finding the “Facts” column, by default the last column of the source table. Finding “Facts” or “Pivot” columns work only for table based pivot tables. They do not for view or srcdef based pivot tables, for which they must be explicitly specified.
2. Finding the “Pivot” column, by default the last remaining column.
3. Choosing the aggregate function to use, “SUM” by default.
4. Constructing and executing the “Group By” on the “Facts” column, getting its result in memory.
5. Getting all the distinct values in the “Pivot” column and defining a “Data” column for each.
6. Spreading the result of the intermediate memory table into the final table.

 
The source table “Pivot” column must not be nullable (there are no such things as a “null” column) The creation will be refused even is this nullable column actually does not contain null values.

 
If a different result is desired, Create Table options are available to change the defaults used by Pivot. For instance if we want to display the average expense for each person and product, spread in columns for each week, use the following statement:

 
```
create table pivex2
engine=connect table_type=pivot tabname=expenses
option_list='PivotCol=Week,Function=AVG';

```

Now saying:

 
```
select * from pivex2;

```

Will display the resulting table:

 


| Who | What | 3 | 4 | 5 |
| --- | --- | --- | --- | --- |
| Beth | Beer | 16.00 | 15.00 | 20.00 |
| Beth | Food | 0.00 | 17.00 | 12.00 |
| Janet | Beer | 18.00 | 0.00 | 16.50 |
| Janet | Car | 19.00 | 17.00 | 12.00 |
| Janet | Food | 18.00 | 0.00 | 12.00 |
| Joe | Beer | 18.00 | 16.33 | 14.00 |
| Joe | Car | 20.00 | 0.00 | 0.00 |
| Joe | Food | 15.50 | 17.00 | 12.00 |

 
Restricting the Columns in a Pivot Table
----------------------------------------

 Let us suppose that we want a Pivot table from expenses summing the expenses for all people and products whatever week it was bought. We can do this just by removing from the pivex table the week column from the column list.

 
```
alter table pivex drop column week;

```

The result we get from the new table is:

 


| Who | Beer | Car | Food |
| --- | --- | --- | --- |
| Beth | 51.00 | 0.00 | 29.00 |
| Janet | 51.00 | 48.00 | 30.00 |
| Joe | 81.00 | 20.00 | 77.00 |

 
Note: Restricting columns is also needed when the source table contains extra columns that should not be part of the pivot table. This is true in particular for key columns that prevent a proper grouping.

 PIVOT Create Table Syntax
-------------------------

 The Create Table statement for PIVOT tables uses the following syntax:

 
```
create table pivot_table_name
[(column_definition)]
engine=CONNECT table_type=PIVOT
{tabname='source_table_name' | srcdef='source_table_def'}
[option_list='pivot_table_option_list'];

```

The column definition has two sets of columns:

 1. A set of columns belonging to the source table, not including the “facts” and “pivot” columns.
2. “Data” columns receiving the values of the aggregated “facts” columns named from the values of the “pivot” column. They are indicated by the “flag” option.

 The **options** and **sub-options** available for Pivot tables are:

 


| Option | Type | Description |
| --- | --- | --- |
| **Tabname** | *[DB.]Name* | The name of the table to “pivot”. If not set SrcDef must be specified. |
| **SrcDef** | *SQL\_statement* | The statement used to generate the intermediate mysql table. |
| **DBname** | *name* | The name of the database containing the source table. Defaults to the current database. |
| **Function\***  | *name* | The name of the aggregate function used for the data columns, SUM by default. |
| **PivotCol\***  | *name* | Specifies the name of the Pivot column whose values are used to fill the “data” columns having the flag option. |
| **FncCol\***  | *[func(]name[)]* | Specifies the name of the data “Facts” column. If the form func(name) is used, the aggregate function name is set to func. |
| **Groupby\***  | *Boolean* | Set it to True (1 or Yes) if the table already has a GROUP BY format. |
| **Accept\***  | *Boolean* | To accept non matching Pivot column values. |

 
* : These options must be specified in the OPTION\_LIST.

 ### Additional Access Options

 There are four cases where pivot must call the server containing the source table or on which the SrcDef statement must be executed:

 1. The source table is not a CONNECT table. 2. The SrcDef option is specified. 3. The source table is on another server. 4. The columns are not specified.

 By default, pivot tries to call the currently used server using host=localhost, user=root not using password, and port=3306. However, this may not be what is needed, in particular if the local root user has a password in which case you can get an “access denied” error message when creating or using the pivot table.

 Specify the host, user, password and/or port options in the option\_list to override the default connection options used to access the source table, get column specifications, execute the generated group by or SrcDef query.

 Defining a Pivot Table
----------------------

 There are principally two ways to define a PIVOT table:

 1. From an existing table or view. 2. Directly giving the SQL statement returning the result to pivot.

 ### Defining a Pivot Table from a Source Table

 The **tabname** standard table option is used to give the name of the source table or view.

 For tables, the internal Group By will be internally generated, except when the GROUPBY option is specified as true. Do it only when the table or view has a valid GROUP BY format.

 ### Directly Defining the Source of a Pivot Table in SQL

 Alternatively, the internal source can be directly defined using the **SrcDef** option that must have the proper group by format.

 As we have seen above, a proper Pivot Table is made from an internal intermediate table resulting from the execution of a `GROUP BY` statement. In many cases, it is simpler or desirable to directly specify this when creating the pivot table. This may be because the source is the result of a complex process including filtering and/or joining tables.

 To do this, use the **SrcDef** option, often replacing all other options. For instance, suppose that in the first example we are only interested in weeks 4 and 5. We could of course display it by:

 
```
select * from pivex where week in (4,5);

```

However, what if this table is a huge table? In this case, the correct way to do it is to define the pivot table as this:

 
```
create table pivex4
engine=connect table_type=pivot
option_list='PivotCol=what,FncCol=amount'
SrcDef='select who, week, what, sum(amount) from expenses
where week in (4,5) group by who, week, what';

```

If your source table has millions of records and you plan to pivot only a small subset of it, doing so will make a lot of a difference performance wise. In addition, you have entire liberty to use expressions, scalar functions, aliases, join, where and having clauses in your SQL statement. The only constraint is that you are responsible for the result of this statement to have the correct format for the pivot processing.

 Using SrcDef also permits to use expressions and/or scalar functions. For instance:

 
```
create table xpivot (
Who char(10) not null,
What char(12) not null,
First double(8,2) flag=1,
Middle double(8,2) flag=1,
Last double(8,2) flag=1)
engine=connect table_type=PIVOT
option_list='PivotCol=wk,FncCol=amnt'
Srcdef='select who, what, case when week=3 then ''First'' when
week=5 then ''Last'' else ''Middle'' end as wk, sum(amount) *
6.56 as amnt from expenses group by who, what, wk';

```

Now the statement:

 
```
select * from xpivot;

```

Will display the result:

 


| Who | What | First | Middle | Last |
| --- | --- | --- | --- | --- |
| Beth | Beer | 104.96 | 98.40 | 131.20 |
| Beth | Food | 0.00 | 111.52 | 78.72 |
| Janet | Beer | 118.08 | 0.00 | 216.48 |
| Janet | Car | 124.64 | 111.52 | 78.72 |
| Janet | Food | 118.08 | 0.00 | 78.72 |
| Joe | Beer | 118.08 | 321.44 | 91.84 |
| Joe | Car | 131.20 | 0.00 | 0.00 |
| Joe | Food | 203.36 | 223.04 | 78.72 |

 
**Note 1:** to avoid multiple lines having the same fixed column values, it is mandatory in **SrcDef** to place the pivot column at the end of the group by list.

 **Note 2:** in the create statement **SrcDef**, it is mandatory to give aliases **to** the columns containing expressions so they are recognized by the other options.

 **Note 3:** in the **SrcDef** select statement, quotes must be escaped because the entire statement is passed to MariaDB between quotes. Alternatively, specify it between double quotes.

 **Note 4:** We could have left CONNECT do the column definitions. However, because they are defined from the sorted names, the Middle column had been placed at the end of them.

 Specifying the Columns Corresponding to the Pivot Column
--------------------------------------------------------

 These columns must be named from the values existing in the “pivot” column. For instance, supposing we have the following *pet* table:

 


| name | race | number |
| --- | --- | --- |
| John | dog | 2 |
| Bill | cat | 1 |
| Mary | dog | 1 |
| Mary | cat | 1 |
| Lisbeth | rabbit | 2 |
| Kevin | cat | 2 |
| Kevin | bird | 6 |
| Donald | dog | 1 |
| Donald | fish | 3 |

 
Pivoting it using *race* as the pivot column is done with:

 
```
create table pivet
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1';

```

This gives the result:

 


| name | dog | cat | rabbit | bird | fish |
| --- | --- | --- | --- | --- | --- |
| John | 2 | 0 | 0 | 0 | 0 |
| Bill | 0 | 1 | 0 | 0 | 0 |
| Mary | 1 | 1 | 0 | 0 | 0 |
| Lisbeth | 0 | 0 | 2 | 0 | 0 |
| Kevin | 0 | 2 | 0 | 6 | 0 |
| Donald | 1 | 0 | 0 | 0 | 3 |

 
By the way, does this ring a bell? It shows that in a way PIVOT tables are doing the opposite of what OCCUR tables do.

 We can alternatively define specifically the table columns but what happens if the Pivot column contains values that is not matching a “data” column? There are three cases depending on the specified options and flags.

 **First case:** If no specific options are specified, this is an error an when trying to display the table. The query will abort with an error message stating that a non-matching value was met. Note that because the column list is established when creating the table, this is prone to occur if some rows containing new values for the pivot column are inserted in the source table. If this happens, you should re-create the table or manually add the new columns to the pivot table. 

 **Second case:** The accept option was specified. For instance:

 
```
create table xpivet2 (
name varchar(12) not null,
dog int not null default 0 flag=1,
cat int not null default 0 flag=1)
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1,Accept=1';

```

No error will be raised and the non-matching values will be ignored. This table will be displayed as:

 


| name | dog | cat |
| --- | --- | --- |
| John | 2 | 0 |
| Bill | 0 | 1 |
| Mary | 1 | 1 |
| Lisbeth | 0 | 0 |
| Kevin | 0 | 2 |
| Donald | 1 | 0 |

 
**Third case:** A “dump” column was specified with the flag value equal to 2. All non-matching values will be added in this column. For instance:

 
```
create table xpivet (
name varchar(12) not null,
dog int not null default 0 flag=1,
cat int not null default 0 flag=1,
other int not null default 0 flag=2)
engine=connect table_type=pivot tabname=pet
option_list='PivotCol=race,groupby=1';

```

This table will be displayed as:

 


| name | dog | cat | other |
| --- | --- | --- | --- |
| John | 2 | 0 | 0 |
| Bill | 0 | 1 | 0 |
| Mary | 1 | 1 | 0 |
| Lisbeth | 0 | 0 | 2 |
| Kevin | 0 | 2 | 6 |
| Donald | 1 | 0 | 3 |

 

It is a good idea to provide such a “dump” column if the source table is prone to be inserted new rows that can have a value for the pivot column that did not exist when the pivot table was created.

 
Pivoting Big Source Tables
--------------------------

 This may sometimes be risky. If the pivot column contains too many distinct values, the resulting table may have too many columns. In all cases the process involved, finding distinct values when creating the table or doing the group by when using it, can be very long and sometimes can fail because of exhausted memory.

 Restrictions by a where clause should be applied to the source table when creating the pivot table rather than to the pivot table itself. This can be done by creating an intermediate table or using as source a view or a srcdef option.

 
All PIVOT tables are read only.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-pivot-table-type/>

CONNECT MONGO Table Type: Accessing Collections from MongoDB
============================================================

    Classified as a NoSQL database program, MongoDB uses JSON-like documents (BSON) grouped in collections. The MONGO type is used to directly access MongoDB collections as tables. 

 Accessing MongDB from CONNECT
-----------------------------

 Accessing MongoDB from CONNECT can be done in different ways:

 1. As a MONGO table via the MongoDB C Driver.
2. As a MONGO table via the MongoDB Java Driver.
3. As a JDBC table using some commercially available MongoDB JDBC drivers.
4. As a JSON table via the MongoDB C or Java Driver.

 #### Using the MongoDB C Driver

 This is currently not available from binary distributions but only for versions compiled from source. The preferred version of the MongoDB C Driver is 1.7, because they provide package recognition. What must be done is:

 1. Install libbson and the MongoDB C Driver 1.7.
2. Configure, compile and install MariaDB.

 With earlier versions of the Mongo C Driver, the additional include directories and libraries will have to be specified manually when compiling.

 When possible, this is the preferred means of access because it does not require all the Java path settings etc. and is faster than using the Java driver.

 #### Using the Mongo Java Driver

 This is possible with all distributions including JDBC support, or compiling from source. With a binary distribution that does not enable the MONGO table type, it is possible to access MongoDB using an OEM module. See [CONNECT OEM Table Example](../connect-oem-table-example/index) for details. The only additional things to do are:

 1. Install the MongoDB Java Driver by downloading its jar file. Several versions are available. If possible use the latest version 3 one.
2. Add the path to it in the CLASSPATH environment variable or in the connect\_class\_path variable. This is like what is done to declare JDBC drivers.

 Connection is established by new Java wrappers Mongo3Interface and Mongo2Interface. They are available in a JDBC distribution in the Mongo2.jar and Mongo3.jar files (previously JavaWrappers.jar). If version 2 of the Java Driver is used, specify “Version=2” in the option list when creating tables.

 #### Using JDBC

 See the documentation of the existing commercial JDBC Mongo drivers.

 #### Using JSON

 See the specific chapter of the JSON Table Type.

 The following describes the MONGO table type.

 CONNECT MONGO Tables
--------------------

 Creating and running MONGO tables requires a connection to a running local or remote MongoDB server.

 A MONGO table is defined to access a MongoDB collection. The table rows will be the collection documents. For instance, to create a table based on the MongoDB sample collection restaurants, you can do something such as the following:

 
```
create table resto (
_id varchar(24) not null,
name varchar(64) not null,
cuisine char(200) not null,
borough char(16) not null,
restaurant_id varchar(12) not null)
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8 connection='mongodb://localhost:27017';

```

Note: The used driver is by default the C driver if only the MongoDB C Driver is installed and the Java driver if only the MongoDB Java Driver is installed. If both are available, it can be specified by the DRIVER option to be specified in the option list and defaults to C.

 Here we did not define all the items of the collection documents but only those that are JSON values. The database is test by default. The connection value is the URI used to establish a connection to a local or remote MongoDB server. The value shown in this example corresponds to a local server started with its default port. It is the default connection value for MONGO tables so we could have omit specifying it.

 Using discovery is available. This table could have been created by:

 
```
create table resto
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8 option_list='level=-1';

```

Here “depth=-1” is used to create only columns that are simple values (no array or object). Without this, with the default value “depth=0” the table had been created as:

 
```
CREATE TABLE `resto` (
  `_id` char(24) NOT NULL,
  `address` varchar(136) NOT NULL,
  `borough` char(13) NOT NULL,
  `cuisine` char(64) NOT NULL,
  `grades` varchar(638) NOT NULL,
  `name` char(98) NOT NULL,
  `restaurant_id` char(8) NOT NULL
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `TABNAME`='restaurants' `DATA_CHARSET`='utf8';

```

### Fixing Problems With mariadb-dump

 In some case or some platforms, when CONNECT is set up for use with JDBC table types, this causes [mariadb-dump](../mariadb-dump/index) with the --all-databases option to fail.

 This was reported by Robert Dyas who found the cause of it and how to fix it (see [MDEV-11238](https://jira.mariadb.org/browse/MDEV-11238)).

 This occurs when the Java JRE “Usage Tracker” is enabled. In that case, Java creates a directory #mysql50#.oracle\_jre\_usage in the mysql data directory that shows up as a database but cannot be accessed via MySQL Workbench nor apparently backed up by mariadb-dump --all-databases.

 Per the Oracle documentation (<https://docs.oracle.com/javacomponents/usage-tracker/overview/>) the “Usage Tracker” is disabled by default. It is enabled only when creating the properties file <JRE directory>/lib/management/usagetracker.properties. This turns out to be WRONG on some platforms as the file does exist by default on a new installation, and the existence of this file enables the usage tracker.

 The solution on CentOS 7 with the Oracle JVM is to rename or delete the usagetracker.properties file (to disable it) and then delete the bogus folder it created in the mysql database directory, then restart.

 For example, the following works:

 
```
sudo mv /usr/java/default/jre/lib/management/management.properties /usr/java/default/jre/lib/management/management.properties.TRACKER-OFF
sudo reboot
sudo rm -rf  /var/lib/mysql/.oracle_jre_usage
sudo reboot

```

In this collection, the address column is a JSON object and the column grades is a JSON array. Unlike the JSON table, just specifying the column name with no Jpath result in displaying the JSON representation of them. For instance:

 
```
select name, address from resto limit 3;

```




| name | address |
| --- | --- |
| Morris Park Bake Shop | {"building":"1007","coord":[-73.8561,40.8484], "street":"Morris ParkAve", "zipcode":"10462"} |
| Wendy'S | {"building":"469","coord":[-73.9617,40.6629], "street":"Flatbush Avenue", "zipcode":"11225"} |
| Reynolds Restaurant | {"building":"351","coord":[-73.9851,40.7677], "street":"West 57Street", "zipcode":"10019"} |

 
### MongoDB Dot Notation

 To address the items inside object or arrays, specify the Jpath in MongoDB syntax (if using Discovery, specify the Depth option accordingly):

 From Connect 1.7.0002

 
```
create table newresto (
_id varchar(24) not null,
name varchar(64) not null,
cuisine char(200) not null,
borough char(16) not null,
street varchar(65) jpath='address.street',
building char(16) jpath='address.building',
zipcode char(5) jpath='address.zipcode',
grade char(1) jpath='grades.0.grade',
score int(4) not null jpath='grades.0.score', 
`date` date jpath='grades.0.date',
restaurant_id varchar(255) not null)
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8 connection='mongodb://localhost:27017';

```

Before Connect 1.7.0002

 
```
create table newresto (
_id varchar(24) not null,
name varchar(64) not null,
cuisine char(200) not null,
borough char(16) not null,
street varchar(65) field_format='address.street',
building char(16) field_format='address.building',
zipcode char(5) field_format='address.zipcode',
grade char(1) field_format='grades.0.grade',
score int(4) not null field_format='grades.0.score', 
`date` date field_format='grades.0.date',
restaurant_id varchar(255) not null)
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8 connection='mongodb://localhost:27017';

```

If this is not done, the Oracle JVM will start the usage tracker, which will create the hidden folder .oracle\_jre\_usage in the mysql home directory, which will cause a mariadb-dump of the server to fail. 

 
```
select name, street, score, date from newresto limit 5;

```




| name | street | score | date |
| --- | --- | --- | --- |
| Morris Park Bake Shop | Morris Park Ave | 2 | 03/03/2014 |
| Wendy'S | Flatbush Avenue | 8 | 30/12/2014 |
| Dj Reynolds Pub And Restaurant | West 57 Street | 2 | 06/09/2014 |
| Riviera Caterer | Stillwell Avenue | 5 | 10/06/2014 |
| Tov Kosher Kitchen | 63 Road | 20 | 24/11/2014 |

 
MONGO Specific Options
----------------------

 The MongoDB syntax for Jpath does not allow the CONNECT specific items on arrays. The same effect can still be obtained by a different way. For this, additional options are used when creating MONGO tables.

 


| Option | Type | Description |
| --- | --- | --- |
| Colist | String | Options to pass to the MongoDB cursor. |
| Filter | String | Query used by the MongoDB cursor. |
| Pipeline\* | Boolean | If True, Colist is a pipeline. |
| Fullarray\* | Boolean | Used when creating with Discovery. |
| Driver\* | String | C or Java. |
| Version\* | Integer | The Java Driver version (defaults to 3) |

 
* : To be specified in the option list.

 Note: For the content of these options, refer to the MongoDB documentation.

 ### Colist Option

 Used to pass different options when making the MongoDB cursor used to retrieve the collation documents. One of them is the projection, allowing to limit the items retrieved in documents. It is hardly useful because this limitation is made automatically by CONNECT. However, it can be used when using discovery to eliminate the \_id (or another) column when you are not willing to keep it:

 
```
create table restest
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8 option_list='depth=-1'
colist='{"projection":{"_id":0},"limit":5}';

```

In this example, we added another cursor option, the limit option that works like the limit SQL clause.

 This additional option works only with the C driver. When using the Java driver, colist should be:

 
```
colist='{"_id":0}';

```

And limit would be specified with select statements.

 Note: When used with a JSON table, to specify the projection list (or ‘all’ to get all columns) makes JPATH to be Connect Json paths, not MongoDB ones, allowing JPATH options not available to MongoDB.

 ### Filter Option

 This option is used to specify a “filter” that works as a where clause on the table. Supposing we want to create a table restricted to the restaurant making English cuisine that are not located in the Manhattan borough, we can do it by:

 
```
create table english
engine=connect table_type=MONGO tabname='restaurants'
data_charset=utf8
colist='{"projection":{"cuisine":0}}'
filter='{"cuisine":"English","borough":{"$ne":"Manhattan"}}'
option_list='Depth=-1';

```

And if we ask:

 
```
select * from english;

```

This query will return:

 


| \_id | borough | name | restaurant\_id |
| --- | --- | --- | --- |
| 58ada47de5a51ddfcd5ee1f3 | Brooklyn | The Park Slope Chipshop | 40816202 |
| 58ada47de5a51ddfcd5ee999 | Brooklyn | Chip Shop | 41076583 |
| 58ada47ee5a51ddfcd5f13d5 | Brooklyn | The Monro | 41660253 |
| 58ada47ee5a51ddfcd5f176e | Brooklyn | Dear Bushwick | 41690534 |
| 58ada47ee5a51ddfcd5f1e91 | Queens | Snowdonia Pub | 50000290 |

 
### Pipeline Option

 When this option is specified as true (by YES or 1) the Colist option contains a MongoDB pipeline applying to the table collation. This is a powerful mean for doing things such as expanding arrays like we do with JSON tables. For instance:

 
```
create table resto2 (
name varchar(64) not null,
borough char(16) not null,
date datetime not null,
grade char(1) not null,
score int(4) not null)
engine=connect table_type=MONGO tabname='restaurants' data_charset=utf8
colist='{"pipeline":[{"$match":{"cuisine":"French"}},{"$unwind":"$grades"},{"$project":{"_id":0,"name":1,"borough":1,"date":"$grades.date","grade":"$grades.grade","score":"$grades.score"}}]}'
option_list='Pipeline=1';

```

In this pipeline “$match” is an early filter, “$unwind” means that the grades array will be expanded (one Document for each array values) and “$project” eliminates the \_id and cuisine columns and gives the Jpath for the date, grade and score columns.

 
```
select name, grade, score, date from resto2
where borough = 'Bronx';

```

This query replies:

 


| name | grade | score | date |
| --- | --- | --- | --- |
| Bistro Sk | A | 10 | 21/11/2014 01:00:00 |
| Bistro Sk | A | 12 | 19/02/2014 01:00:00 |
| Bistro Sk | B | 18 | 12/06/2013 02:00:00 |

 
This make possible to get things like we do with JSON tables:

 
```
select name, avg(score) average from resto2
group by name having average >= 25;

```

Can be used to get the average score inside the grades array.

 


| name | average |
| --- | --- |
| Bouley Botanical | 25,0000 |
| Cheri | 46,0000 |
| Graine De Paris | 30,0000 |
| Le Pescadeux | 29,7500 |

 
### Fullarray Option

 This option, like the Depth option, is only interpreted when creating a table with Discovery (meaning not specifying the columns). It tells CONNECT to generate a column for all existing values in the array. For instance, let us see the MongoDB collection tar by:

 From Connect 1.7.0002

 
```
create table seetar (
Collection varchar(300) not null jpath='*')
engine=CONNECT table_type=MONGO tabname=tar;

```

Before Connect 1.7.0002

 
```
create table seetar (
Collection varchar(300) not null field_format='*')
engine=CONNECT table_type=MONGO tabname=tar;

```

The format ‘\*’ indicates we want to see the Json documents. This small collection is:

 


| Collection |
| --- |
| {"\_id":{"$oid":"58f63a5099b37d9c930f9f3b"},"item":"journal","prices":[87.0,45.0,63.0,12.0,78.0]} |
| {"\_id":{"$oid":"58f63a5099b37d9c930f9f3c"},"item":"notebook","prices":[123.0,456.0,789.0]} |

 
The Fullarray option can be used here to generate enough columns to see all the prices of the document prices array.

 
```
create table tar
engine=connect table_type=MONGO
colist='{"projection":{"_id":0}}'
option_list='depth=1,Fullarray=YES';

```

The table has been created as:

 From Connect 1.7.0002

 
```
CREATE TABLE `tar` (
  `item` char(8) NOT NULL,
  `prices_0` double(12,6) NOT NULL `JPATH`='prices.0',
  `prices_1` double(12,6) NOT NULL `JPATH`='prices.1',
  `prices_2` double(12,6) NOT NULL `JPATH`='prices.2',
  `prices_3` double(12,6) DEFAULT NULL `JPATH`='prices.3',
  `prices_4` double(12,6) DEFAULT NULL `JPATH`='prices.4'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `COLIST`='{"projection":{"_id":0}}' `OPTION_LIST`='depth=1,Fullarray=YES';

```

Before Connect 1.7.0002

 
```
CREATE TABLE `tar` (
  `item` char(8) NOT NULL,
  `prices_0` double(12,6) NOT NULL `FIELD_FORMAT`='prices.0',
  `prices_1` double(12,6) NOT NULL `FIELD_FORMAT`='prices.1',
  `prices_2` double(12,6) NOT NULL `FIELD_FORMAT`='prices.2',
  `prices_3` double(12,6) DEFAULT NULL `FIELD_FORMAT`='prices.3',
  `prices_4` double(12,6) DEFAULT NULL `FIELD_FORMAT`='prices.4'
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='MONGO' `COLIST`='{"projection":{"_id":0}}' `OPTION_LIST`='level=1,Fullarray=YES';

```

And is displayed as:

 


| item | prices\_0 | prices\_1 | prices\_2 | prices\_3 | prices\_4 |
| --- | --- | --- | --- | --- | --- |
| journal | 87.00 | 45.00 | 63.00 | 12.00 | 78.00 |
| notebook | 123.00 | 456.00 | 789.00 | NULL | NULL |

 
Create, Read, Update and Delete Operations
------------------------------------------

 All modifying operations are supported. However, inserting into arrays must be done in a specific way. Like with the Fullarray option, we must have enough columns to specify the array values. For instance, we can create a new table by:

 From Connect 1.7.0002

 
```
create table testin (
n int not null,
m char(12) not null,
surname char(16) not null jpath='person.name.first',
name char(16) not null jpath='person.name.last',
age int(3) not null jpath='person.age',
price_1 double(8,2) jpath='d.0',
price_2 double(8,2) jpath='d.1',
price_3 double(8,2) jpath='d.2')
engine=connect table_type=MONGO tabname='tin'
connection='mongodb://localhost:27017';

```

Before Connect 1.7.0002

 
```
create table testin (
n int not null,
m char(12) not null,
surname char(16) not null field_format='person.name.first',
name char(16) not null field_format='person.name.last',
age int(3) not null field_format='person.age',
price_1 double(8,2) field_format='d.0',
price_2 double(8,2) field_format='d.1',
price_3 double(8,2) field_format='d.2')
engine=connect table_type=MONGO tabname='tin'
connection='mongodb://localhost:27017';

```

Now it is possible to populate it by:

 
```
insert into testin values
(1789, 'Welcome', 'Olivier','Bertrand',56, 3.14, 2.36, 8.45),
(1515, 'Hello', 'John','Smith',32, 65.17, 98.12, NULL),
(2014, 'Coucou', 'Foo','Bar',20, -1.0, 74, 81356);

```

The result will be:

 


| n | m | surname | name | age | price\_1 | price\_2 | price\_3 |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 1789 | Welcome | Olivier | Bertrand | 56 | 3,14 | 2,36 | 8,45 |
| 1515 | Hello | John | Smith | 32 | 65,17 | 98,12 | NULL |
| 2014 | Coucou | Foo | Bar | 20 | -1 | 74 | 81356 |

 
Note: If the collection does not exist yet when creating the table and inserting in it, MongoDB creates it automatically.

 It can be updated by queries such as:

 
```
update tintin set price_3 = 83.36 where n = 2014;

```

To look how the array is generated, let us create another table:

 From Connect 1.7.0002

 
```
create table tintin (
n int not null,
name char(16) not null jpath='person.name.first',
prices varchar(255) jpath='d')
engine=connect table_type=MONGO tabname='tin';

```

Before Connect 1.7.002

 
```
create table tintin (
n int not null,
name char(16) not null field_format='person.name.first',
prices varchar(255) field_format='d')
engine=connect table_type=MONGO tabname='in';

```

This table is displayed as:

 From Connect 1.7.0002

 


| n | name | prices |
| --- | --- | --- |
| 1789 | Olivier | [3.1400000000000001243,2.3599999999999998757,8.4499999999999992895] |
| 1515 | John | [65.170000000000001705,98.120000000000004547,null] |
| 2014 | Foo | [null,74.0,83.359999999999999432] |

 
Before Connect 1.7.002

 


| n | name | prices |
| --- | --- | --- |
| 1789 | Olivier | [3.14, 2.36, 8.45] |
| 1515 | John | [65.17, 98.12] |
| 2014 | Foo | [<null>, 74.0, 83.36] |

 
Note: This last table can be used to make array calculations like with JSON tables using the JSON UDF functions. For instance:

 
```
select name, jsonget_real(prices,'[+]') sum_prices, jsonget_real(prices,'[!]') avg_prices from tintin;

```

This query returns:

 


| name | sum\_prices | avg\_prices |
| --- | --- | --- |
| Olivier | 13.95 | 4.65 |
| John | 163.29 | 81.64 |
| Foo | 157,36 | 78.68 |

 
Note: When calculating on arrays, null values are ignored.

 Status of MONGO Table Type
--------------------------

 This table type is still under development. It has significant advantages over the JSON type to access MongoDB collections. Firstly, the access being direct, tables are always up to date whether the collection has been modified by another application. Performance wise, it can be faster than JSON, because most processing is done by MongoDB on BSON, its internal representation of JSON data, which is designed to optimize all operations. Note that using the MongoDB C Driver can be faster than using the MongoDB Java Driver.

 Current Restrictions
--------------------

 * Option “CATFUNC=tables” is not implemented yet.
* Options SRCDEF and EXECSRC do not apply to MONGO tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-mongo-table-type/>

CONNECT TBL Table Type: Table List
==================================

     This type allows defining a table as a list of tables of any engine and type. This is more flexible than multiple tables that must be all of the same file type. This type does, but is more powerful than, what is done with the [MERGE](../merge/index) engine.

 The list of the columns of the TBL table may not necessarily include all the columns of the tables of the list. If the name of some columns is different in the sub-tables, the column to use can be specified by its position given by the `FLAG` option of the column. If the `ACCEPT` option is set to true (Y or 1) columns that do not exist in some of the sub-tables are accepted and their value will be null or pseudo-null (this depends on the nullability of the column) for the tables not having this column. The column types can also be different and an automatic conversion will be done if necessary.

 **Note:** If not specified, the column definitions are retrieved from the first table of the table list.

 The default database of the sub-tables is the current database or if not, can be specified in the DBNAME option. For the tables that are not in the default database, this can be specified in the table list. For instance, to create a table based on the French table *employe* in the current database and on the English table *employee* of the *db2* database, the syntax of the create statement can be:

 
```
CREATE TABLE allemp (
  SERIALNO char(5) NOT NULL flag=1,
  NAME varchar(12) NOT NULL flag=2,
  SEX smallint(1),
  TITLE varchar(15) NOT NULL flag=3,
  MANAGER char(5) DEFAULT NULL flag=4,
  DEPARTMENT char(4) NOT NULL flag=5,
  SECRETARY char(5) DEFAULT NULL flag=6,
  SALARY double(8,2) NOT NULL flag=7)
ENGINE=CONNECT table_type=TBL
table_list='employe,db2.employee' option_list='Accept=1';

```

The search for columns in sub tables is done by name and, if they exist with a different name, by their position given by a not null `FLAG` option. Column *sex* exists only in the English table (`FLAG` is `0`). Its values will null value for the French table.

 For instance, the query:

 
```
select name, sex, title, salary from allemp where department = 318;

```

Can reply:

 


| NAME | SEX | TITLE | SALARY |
| --- | --- | --- | --- |
| BARBOUD | NULL | VENDEUR | 9700.00 |
| MARCHANT | NULL | VENDEUR | 8800.00 |
| MINIARD | NULL | ADMINISTRATIF | 7500.00 |
| POUPIN | NULL | INGENIEUR | 7450.00 |
| ANTERPE | NULL | INGENIEUR | 6850.00 |
| LOULOUTE | NULL | SECRETAIRE | 4900.00 |
| TARTINE | NULL | OPERATRICE | 2800.00 |
| WERTHER | NULL | DIRECTEUR | 14500.00 |
| VOITURIN | NULL | VENDEUR | 10130.00 |
| BANCROFT | 2 | SALESMAN | 9600.00 |
| MERCHANT | 1 | SALESMAN | 8700.00 |
| SHRINKY | 2 | ADMINISTRATOR | 7500.00 |
| WALTER | 1 | ENGINEER | 7400.00 |
| TONGHO | 1 | ENGINEER | 6800.00 |
| HONEY | 2 | SECRETARY | 4900.00 |
| PLUMHEAD | 2 | TYPIST | 2800.00 |
| WERTHER | 1 | DIRECTOR | 14500.00 |
| WHEELFOR | 1 | SALESMAN | 10030.00 |

 
The first 9 rows, coming from the French table, have a null for the *sex* value. They would have 0 if the sex column had been created NOT NULL.

 ### Sub-tables of not CONNECT engines

 Sub-tables are accessed as `[PROXY](../connect-table-types-proxy-table-type/index)` tables. For not CONNECT sub-tables that are accessed via the MySQL API, it is possible like with `PROXY` to change the MYSQL default options. Of course, this will apply to all not CONNECT tables of the list.

 ### Using the TABID special column

 The TABID special column can be used to see from which table the rows come from and to restrict the access to only some of the sub-tables.

 Let us see the following example where t1 and t2 are MyISAM tables similar to the ones given in the `MERGE` description:

 
```
create table xt1 (
  a int(11) not null,
  message char(20))
engine=CONNECT table_type=MYSQL tabname='t1'
option_list='database=test,user=root';

create table xt2 (
  a int(11) not null,
  message char(20))
engine=CONNECT table_type=MYSQL tabname='t2'
option_list='database=test,user=root';

create table toto (
  tabname char(8) not null special='TABID',
  a int(11) not null,
  message char(20))
engine=CONNECT table_type=TBL table_list='xt1,xt2';

select * from total;

```

The result returned by the SELECT statement is:

 


| tabname | a | message |
| --- | --- | --- |
| xt1 | 1 | Testing |
| xt1 | 2 | table |
| xt1 | 3 | t1 |
| xt2 | 1 | Testing |
| xt2 | 2 | table |
| xt2 | 3 | t2 |

 
Now if you send the query:

 
```
select * from total where tabname = 'xt2';

```

CONNECT will analyze the where clause and only read the *xt1* table. This can save time if you want to retrieve only a few sub-tables from a TBL table containing many sub-tables.

 ### Parallel Execution

 
Parallel Execution is currently unavailable until some bugs are fixed.

 
When the sub-tables are located on different servers, it is possible to execute the remote queries simultaneously instead of sequentially. To enable this, set the thread option to yes.

 Additional options available for this table type:

 


| Option | Description |
| --- | --- |
| Maxerr | The max number of missing tables in the table list before an error is raised. Defaults to 0. |
| Accept | If true, missing columns are accepted and return null values. Defaults to false. |
| Thread | If true, enables parallel execution of remote sub-tables. |

 
These options can be specified in the `OPTION_LIST`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-tbl-table-type-table-list/>

CONNECT Table Types - Data Files
================================

     Most of the tables processed by CONNECT are just plain DOS or UNIX data files, logically regarded as tables thanks to the description given when creating the table. This description comes from the `[CREATE TABLE](../create-table/index)` statement. Depending on the application, these tables can already exist as data files, used as is by CONNECT, or can have been physically made by CONNECT as the result of a `CREATE TABLE ... SELECT ...` and/or INSERT statement(s).

 The file *path/name* is given by the `FILE_NAME` option. If it is a relative path/name, it will be relative to the database directory, the one containing the table `.FRM` file.

 Unless specified, the maturity of file table types is stable.

 Multiple File Tables
--------------------

 A **multiple** file table is one that is physically contained in several files of the same type instead of just one. These files are processed sequentially during the process of a query and the result is the same as if all the table files were merged into one. This is great to process files coming from different sources (such as cash register log files) or made at different time periods (such as bank monthly reports) regarded as one table. Note that the operations on such files are restricted to sequential Select and Update; and that VEC multiple tables are not supported by CONNECT. The file list depends on the setting of the **multiple** option of the `CREATE TABLE` statement for that table.

 Multiple tables are specified by the option MULTIPLE=*n*, which can take four values:

 


|  |  |
| --- | --- |
| 0 | Not a multiple table (the default). This can be used in an [ALTER TABLE](../alter-table/index) statement. |
| 1 | The table is made from files located in the same directory. The FILE\_NAME option is a pattern such as `'cash*.log'` that all the table file path/names verify. |
| 2 | The FILE\_NAME gives the name of a file that contains the path/names of all the table files. This file can be made using a DIR table. |
| 3 | Like multiple=1 but also including eligible files from the directory sub-folders. |

 
The `FILEID` special column, described [here](../using-connect-virtual-and-special-columns/index), allows query pruning by filtering the file list or doing some grouping on the files that make a multiple table.

 **Note:** Multiple was not initially implemented for XML tables. This restriction was removed in version 1.02.

 Record Format
-------------

 This characteristic applies to table files handled by the operating system input/output functions. It is **fixed** for table types [FIX](../connect-dos-and-fix-table-types/index), [BIN](../connect-bin-table-type/index), [DBF](../connect-dbf-table-type/index) and [VEC](../connect-vec-table-type/index), and it is variable for [DOS](../connect-dos-and-fix-table-types/index), VCT, [FMT](../connect-csv-and-fmt-table-types/index) and some [JSON](../connect-json-table-type/index) tables.

 For fixed tables, most I/O operations are done by block of BLOCK\_SIZE rows. This diminishes the number of I/O’s and enables block indexing.

 Starting with CONNECT version 1.6.6, the BLOCK\_SIZE option can also be specified for variable tables. Then, a file similar to the block indexing file is created by CONNECT that gives the size in bytes of each block of BLOCK\_SIZE rows. This enables the use of block I/Os and block indexing to variable tables. It also enables CONNECT to return the exact row number for info commands

 File Mapping
------------

 For file-based tables of reasonable size, processing time can be greatly enhanced under Windows(TM) and some flavors of UNIX or Linux by using the technique of “file mapping”, in which a file is processed as if it were entirely in memory. Mapping is specified when creating the table by the use of the `MAPPED=YES` option. This does not apply to tables not handled by system I/O functions (`[XML](%5b%5bconnect-xml-table-type)` and  `[INI](../connect-ini-table-type/index)`).

 Big File Tables
---------------

 Because all files are handled by the standard input/output functions of the operating system, their size is limited to 2GB, the maximum size handled by standard functions. For some table types, CONNECT can deal with files that are larger than 2GB, or prone to become larger than this limit. These are the [FIX](../connect-dos-and-fix-table-types/index), [BIN](../connect-bin-table-type/index) and [VEC](../connect-vec-table-type/index) types. To tell connect to use input/output functions dealing with big files, specify the option `huge=1` or `huge=YES` for that table. Note however that CONNECT cannot randomly access tables having more than 2G records.

 Compressed File Tables
----------------------

 CONNECT can make and process some tables whose data file is compressed. The only supported compression format is the gzlib format. Zip and zlib formats are supported differently. The table types that can be compressed are [DOS](../connect-dos-and-fix-table-types/index), [FIX](connect-dos-and-fix-table-typess), [BIN](../connect-bin-table-type/index), [CSV](../connect-csv-and-fmt-table-types/index) and [FMT](../connect-csv-and-fmt-table-types/index). This can save some disk space at the cost of a somewhat longer processing time.

 Some restrictions apply to compressed tables:

 * Compressed tables are not indexable.
* Update and partial delete are not supported.

 Use the numeric compress option to specify a compressed table:

 1. Not compressed
2. Compressed in gzlib format.
3. Made of compressed blocks of block\_size records (enabling block indexing)

 Relational Formatted Tables
---------------------------

 These are based on files whose records represent one table row. Only the column representation within each record can differ. The following relational formatted tables are supported:

 * [DOS and FIX Table Types](../connect-dos-and-fix-table-types/index)
* [DBF Table Type](../connect-dbf-table-type/index)
* [BIN Table Type](../connect-bin-table-type/index)
* [VEC Table Type](../connect-vec-table-type/index)
* [CSV and FMT Table Types](../connect-csv-and-fmt-table-types/index)

 NoSQL Table Types
-----------------

 These are based on files that do not match the relational format but often represent hierarchical data. CONNECT can handle JSON, INI-CFG, XML and some HTML files..

 The way it is done is different from what PostgreSQL does. In addition to including in a table some column values of a specific data format (JSON, XML) to be handled by specific functions, CONNECT can directly use JSON, XML or INI files that can be produced by other applications and this is the table definition that describes where and how the contained information must be retrieved.

 This is also different from what MariaDB does with [dynamic columns](../dynamic-columns/index), which is close to what MySQL and PostgreSQL do with the JSON column type.

 The following NoSQL types are supported:

 * [XML Table Type](../connect-xml-table-type/index)
* [JSON Table Type](../connect-json-table-type/index)
* [INI Table Type](../connect-ini-table-type/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-data-files/>

CONNECT - Using the TBL and MYSQL Table Types Together
======================================================

     Used together, these types lift all the limitations of the [FEDERATED](../federated-storage-engine/index) and [MERGE](../merge/index) engines.

 **MERGE:** Its limitation is obvious, the merged tables must be identical [MyISAM](../myisam-storage-engine/index) tables, and MyISAM is not even the default engine for MariaDB. However, [TBL](../connect-table-types-tbl-table-type-table-list/index) accesses a collection of CONNECT tables, but because these tables can be user specified or internally created [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) tables, there is no limitation to the type of the tables that can be merged.

 TBL is also much more flexible. The merged tables must not be "identical", they just should have the columns defined in the TBL table. If the type of one column in a merged table is not the one of the corresponding column of the TBL table, the column value will be converted. As we have seen, if one column of the TBL table of the TBL column does not exist in one of the merged table, the corresponding value will be set to null. If columns in a sub-table have a different name, they can be accessed by position using the FLAG column option of CONNECT.

 However, one limitation of the TBL type regarding MERGE is that TBL tables are currently read-only; INSERT is not supported by TBL. Also, keep using MERGE to access a list of identical MyISAM tables because it will be faster, not passing by the MySQL API.

 **FEDERATED(X):** The main limitation of FEDERATED is to access only MySQL/MariaDB tables. The MYSQL table type of CONNECT has the same limitation but CONNECT provides the [ODBC table type](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index) and [JDBC table type](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index) that can access tables of any RDBS providing an ODBC or JDBC driver (including MySQL even it is not really useful!)

 Another major limitation of FEDERATED is to access only one table. By combining TBL and MYSQL tables, CONNECT enables to access a collection of local or remote tables as one table. Of course the sub-tables can be on different servers. With one SELECT statement, a company manager will be able to interrogate results coming from all of his subsidiary computers. This is great for distribution, banking, and many other industries.

 Remotely executing complex queries
----------------------------------

 Many companies or administrations must deal with distributed information. CONNECT enables to deal with it efficiently without having to copy it to a centralized database. Let us suppose we have on some remote network machines *m1, m2, … mn* some information contained in two tables *t1* and *t2*.

 Suppose we want to execute on all servers a query such as:

 
```
select c1, sum(c2) from t1 a, t2 b where a.id = b.id group by c1;

```

This raises many problems. Returning the column values of the *t1* and *t2* tables from all servers can be a lot of network traffic. The group by on the possibly huge resulting tables can be a long process. In addition, the join on the *t1* and *t2* tables may be relevant only if the joined tuples belong to the same machine, obliging to add a condition on an additional tabid or servid special column.

 All this can be avoided and optimized by forcing the query to be locally executed on each server and retrieving only the small results of the group by queries. Here is how to do it. For each remote machine, create a table that will retrieve the locally executed query. For instance for m1:

 
```
create table rt1 engine=connect option_list='host=m1'
srcdef='select c1, sum(c2) as sc2 from t1 a, t2 b where a.id = b.id group by c1';

```

Note the alias for the functional column. An alias would be required for the c1 column if its name was different on some machines. The t1 and t2 table names can also be eventually different on the remote machines. The true names must be used in the `SRCDEF` parameter. This will create a set of tables with two columns named c1 and sc2[[1](#_note-0)].

 Then create the table that will retrieve the result of all these tables:

 
```
create table rtall engine=connect table_type=tbl
table_list='rt1,rt2,…,rtn' option_list='thread=yes';

```

Now you can retrieve the desired result by:

 
```
select c1, sum(sc2) from rtall;

```

Almost all the work will be done on the remote machines, simultaneously thanks to the thread option, making this query super-fast even on big tables placed on many remote machines.

 
Thread is currently experimental. Use it only for test and report any malfunction on [JIRA](../jira/index).

 
Providing a list of servers
---------------------------

 An interesting case is when the query to run on remote machines is the same for all of them. It is then possible to avoid declaring all sub-tables. In this case, the table list option will be used to specify the list of servers the `SRCDEF` query must be sent. This will be a list of URL’s and/or Federated server names.

 For instance, supposing that federated servers srv1, srv2, … srv*n* were created for all remote servers, it will be possible to create a tbl table allowing getting the result of a query executed on all of them by:

 
```
create table qall [column definition]
engine=connect table_type=TBL srcdef='a query'
table_list='srv1,srv2,…,srvn' [option_list='thread=yes'];

```

For instance:

 
```
create table verall engine=connect table_type=TBL srcdef='select @@version' table_list=',server_one';
select * from verall;

```

This reply:

 


| @@version |
| --- |
| 10.0.3-MariaDB-debug |
| 10.0.2-MariaDB |

 
Here the server list specifies a void server corresponding to the local running MariaDB and a federated server named *server\_one*.

 

---

 1. [↑](#_ref-0) To generate the columns from the `SRCDEF` query, CONNECT must execute it. This will make sure it is ok. However, if the remote server is not connected yet, or the remote table not existing yet, you can alternatively specify the columns in the create table statement.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-using-the-tbl-and-mysql-table-types-together/>

CONNECT Table Types - Special "Virtual" Tables
==============================================

     The special table types supported by CONNECT are the Virtual table type ([VIR](../connect-table-types-vir/index) - introduced in [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/)), Directory Listing table type (DIR), the Windows Management Instrumentation Table Type (WMI), and the “Mac Address” type (MAC).

 These tables are “virtual tables”, meaning they have no physical data but rather produce result data using specific algorithms. Note that this is close to what Views are, so they could be regarded as special views.

 DIR Type
--------

 A table of type DIR returns a list of file name and description as a result set. To create a DIR table, use a Create Table statement such as:

 
```
create table source (
  DRIVE char(2) NOT NULL,
  PATH varchar(256) NOT NULL,
  FNAME varchar(256) NOT NULL,
  FTYPE char(4) NOT NULL,
  SIZE double(12,0) NOT NULL flag=5,
  MODIFIED datetime NOT NULL)
engine=CONNECT table_type=DIR file_name='..\\*.cc';

```

When used in a query, the table returns the same file information listing than the system "DIR `*.cc`" statement would return if executed in the same current directory (here supposedly ..\)

 For instance, the query:

 
```
select fname, size, modified from source
  where fname like '%handler%';

```

Displays:

 


| fname | size | modified |
| --- | --- | --- |
| handler | 152177 | 2011-06-13 18:08:29 |
| sql\_handler | 25321 | 2011-06-13 18:08:31 |

 
**Note:** the important item in this table is the flag option value (set sequentially from 0 by default) because it determines which particular information item is returned in the column:

 


| Flag value | Information |
| --- | --- |
| 0 | The disk drive (Windows) |
| 1 | The file path |
| 2 | The file name |
| 3 | The file type |
| 4 | The file attribute |
| 5 | The file size |
| 6 | The last write access date |
| 7 | The last read access date |
| 8 | The file creation date |

 
### The Subdir option

 When specified in the create table statement, the subdir option indicates to list, in addition to the files contained in the specified directory, all the files verifying the filename pattern that are contained in sub-directories of the specified directory. For instance, using:

 
```
create table data (
  PATH varchar(256) NOT NULL flag=1,
  FNAME varchar(256) NOT NULL,
  FTYPE char(4) NOT NULL,
  SIZE double(12,0) NOT NULL flag=5)
engine=CONNECT table_type=DIR file_name='*.frm'
option_list='subdir=1';

select path, count(*), sum(size) from data group by path;

```

You will get the following result set showing how many tables are created in the MariaDB databases and what is the total length of the FRM files:

 


| path | count(\*) | sum(size) |
| --- | --- | --- |
| \CommonSource\mariadb-5.2.7\sql\data\connect\ | 30 | 264469 |
| \CommonSource\mariadb-5.2.7\sql\data\mysql\ | 23 | 207168 |
| \CommonSource\mariadb-5.2.7\sql\data\test\ | 22 | 196882 |

 
### The Nodir option (Windows)

 The Boolean Nodir option can be set to false (0 or no) to add directories that match the file name pattern from the listed files (it is true by default). This is an addition to CONNECT version 1.6. Previously, directory names matching pattern were listed on Windows. Directories were and are never listed on Linux.

 Note: The way file names are retrieved makes positional access to them impossible. Therefore, DIR tables cannot be indexed or sorted when it is done using positions.

 Be aware, in particular when using the subdir option, that queries on DIR tables are slow and can last almost forever if made on a directory that contains a great number of files in it and its sub-directories. 

 dir tables can be used to populate a list of files used to create a multiple=2 table. However, this is not as useful as it was when the multiple 3 did not exist.

 Windows Management Instrumentation Table Type “WMI”
---------------------------------------------------

 
**Note:** This table type is available on Windows only.

 
WMI provides an operating system interface through which instrumented components provide information. Some Microsoft tools to retrieve information through WMI are the WMIC console command and the WMI CMI Studio application.

 The CONNECT WMI table type enables administrators and operators not capable of scripting or programming on top of WMI to enjoy the benefit of WMI without even learning about it. It permits to present this information as tables that can be queried, transformed, copied in documents or other tables.

 To create a WMI table displaying information coming from a WMI provider, you must provide the namespace and the class name that characterize the information you want to retrieve. The best way to find them is to use the WMI CIM Studio that have tools to browse namespaces and classes and that can display the names of the properties of that class.

 The column names of the tables must be the names (case insensitive) of the properties you want to retrieve. For instance:

 
```
create table alias (
  friendlyname char(32) not null,
  target char(50) not null)
engine=CONNECT table_type='WMI'
option_list='Namespace=root\\cli,Class=Msft_CliAlias';

```

WMI tables returns one row for each instance of the related information. The above example is handy to get the class equivalent of the alias of the WMIC command and also to have a list of many classes commonly used.

 Because most of the useful classes belong to the 'root\cimv2' namespace, this is the default value for WMI tables when the namespace is not specified. Some classes have many properties whose name and type may not be known when creating the table. To find them, you can use the WMI CMI Studio application but his will be rarely required because CONNECT is able to retrieve them.

 Actually, the class specification also has default values for some namespaces. For the ‘root\cli’ namespace the class name defaults to ‘Msft\_CliAlias’ and for the ‘root\_cimv2’ namespace the class default value is ‘Win32\_ComputerSystemProduct’. Because many class names begin with ‘Win32\_’ it is not necessary to say it and specifying the class as ‘Product’ will effectively use class ‘Win32\_Product’.

 For example if you define a table as:

 
```
create table CSPROD engine=CONNECT table_type='WMI';

```

It will return the information on the current machine, using the class ComputerSystemProduct of the CIMV2 namespace. For instance:

 
```
select * from csprod;

```

Will return a result such as:

 


| Column | Row 1 |
| --- | --- |
| Caption | Computer system product |
| Description | Computer system product |
| IdentifyingNumber | LXAP50X32982327A922300 |
| Name | Aspire 8920 |
| SKUNumber |  |
| UUID | 00FC523D-B8F7-DC12-A70E-00B0D1A46136 |
| Vendor | Acer |
| Version | Aspire 8920 |

 
**Note:** This is a transposed display that can be obtained with some GUI.

 ### Getting column information

 An issue, when creating a WMI table, is to make its column definition. Indeed, even when you know the namespace and the class for the wanted information, it is not easy to find what are the names and types of its properties. However, because CONNECT can retrieve this information from the WMI provider, you can simply omit defining columns and CONNECT will do the job.

 Alternatively, you can get this information using a catalog table (see below).

 ### Performance Consideration

 Some WMI providers can be very slow to answer. This is not an issue for those that return few object instances, such as the ones returning computer, motherboard, or Bios information. They generally return only one row (instance). However, some can return many rows, in particular the "CIM\_DataFile" class. This is why care must be taken about them.

 Firstly, it is possible to limit the allocated result size by using the ‘Estimate’ create table option. To avoid result truncation, CONNECT allocates a result of 100 rows that is enough for almost all tables.The 'Estimate' option permits to reduce this size for all classes that return only a few rows, and in some rare case to increase it to avoid truncation.

 However, it is not possible to limit the time taken by some WMI providers to answer, in particular the CIM\_DATAFILE class. Indeed the Microsoft documentation says about it:

 
 "Avoid enumerating or querying for all instances of CIM\_DataFile on a computer because the volume of data is likely to either affect performance or cause the computer to stop responding."

  Sure enough, even a simple query such as:

 
```
select count(*) from cim where drive = 'D:' and path like '\\MariaDB\\%';

```

is prone to last almost forever (probably due to the LIKE clause). This is why, when not asking for some specific items, you should consider using the DIR table type instead.

 ### Syntax of WMI queries

 Queries to WMI providers are done using the WQL language, not the SQL language. CONNECT does the job of making the WQL query. However, because of the restriction of the WQL syntax, the WHERE clause will be generated only when respecting the following restrictions:

 1. No function.
2. No comparison between two columns.
3. No expression (currently a CONNECT restriction)
4. No BETWEEN and IN predicates.

 Filtering with WHERE clauses not respecting these conditions will still be done by MariaDB only, except in the case of CIM\_Datafile class for the reason given above.

 However, there is one point that is not covered yet, the syntax used to specify dates in queries. WQL does not recognize dates as number items but translates them to its internal format dates specified as text. Many formats are recognized as described in the Microsoft documentation but only one is useful because common to WQL and MariaDB SQL. Here is an example of a query on a table named "cim" created by:

 
```
create table cim (
  Name varchar(255) not null,
  LastModified datetime not null)
engine=CONNECT table_type='WMI'
option_list='class=CIM_DataFile,estimate=5000';

```

The date must be specified with the format in which CIM DATETIME values are stored (WMI uses the date and time formats defined by the Distributed Management Task Force).

 
```
select * from cim where drive = 'D:' and path = '\\PlugDB\\Bin\\'
     and lastmodified > '20120415000000.000000+120';

```

This syntax must be strictly respected. The text has the format:

 
```
yyyymmddHHMMSS.mmmmmmsUUU

```

It is: year, month, day, hour, minute, second, millisecond, and signed minute deviation from [UTC](../coordinated-universal-time/index). This format is locale-independent so you can write a query that runs on any machine.

 **Note 1:** The WMI table type is available only in Windows versions of CONNECT.

 **Note 2:** WMI tables are read only.

 **Note 3:** WMI tables are not indexable.

 **Note 4:** WMI consider all strings as case insensitive.

 MAC Address Table Type “MAC”
----------------------------

 
**Note:** This table type is available on Windows only.

 
This type is used to display various general information about the computer and, in particular, about its network cards. To create such a table, the syntax to use is:

 
```
create table tabname (column definition)
engine=CONNECT table_type=MAC;

```

Column names can be freely chosen because their signification, i.e. the values they will display, comes from the specified Flag option. The valid values for Flag are:

 


| Flag | Valeur | Type |
| --- | --- | --- |
| 1 | Host name | varchar(132) |
| 2 | Domain | varchar(132) |
| 3 | DNS address | varchar(24) |
| 4 | Node type | int(1) |
| 5 | Scope ID | varchar(256) |
| 6 | Routing | int(1) |
| 7 | Proxy | int(1) |
| 8 | DNS | int(1) |
| 10 | Name | varchar(260) |
| 11 | Description | varchar(132) |
| 12 | MAC address | char(24) |
| 13 | Type | int(3) |
| 14 | DHCP | int(1) |
| 15 | IP address | char(16) |
| 16 | SUBNET mask | char(16) |
| 17 | GATEWAY | char(16) |
| 18 | DHCP server | char(16) |
| 19 | Have WINS | int(1) |
| 20 | Primary WINS | char(16) |
| 21 | Secondary WINS | char(16) |
| 22 | Lease obtained | datetime |
| 23 | Lease expires | datetime |

 
**Note:** The information of columns having a Flag value less than 10 are unique for the computer, the other ones are specific to the network cards of the computer.

 For instance, you can define the table *macaddr* as:

 
```
create table macaddr (
  Host varchar(132) flag=1,
  Card varchar(132) flag=11,
  Address char(24) flag=12,
  IP char(16) flag=15,
  Gateway char(16) flag=17,
  Lease datetime flag=23)
engine=CONNECT table_type=MAC;

```

If you execute the query:

 
```
select host, address, ip, gateway, lease from macaddr;

```

It will return, for example:

 


| Host | Address | IP | Gateway | Lease |
| --- | --- | --- | --- | --- |
| OLIVIER | 00-A0-D1-A4-61-36 | 0.0.0.0 | 0.0.0.0 | 1970-01-01 00:00:00 |
| OLIVIER | 00-1D-E0-9B-90-0B | 192.168.0.10 | 192.168.0.254 | 2011-09-18 10:28:5 |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-special-virtual-tables/>

CONNECT Table Types - Catalog Tables
====================================

    A catalog table is one that returns information about another table, or data source. It is similar to what MariaDB commands such as `DESCRIBE` or `SHOW` do. Applied to local tables, this just duplicates what these commands do, with the noticeable difference that they are tables and can be used inside queries as joined tables or inside sub-selects.

 But their main interest is to enable querying the structure of external tables that cannot be directly queried with description commands. Let's see an example:

 Suppose we want to access the tables from a Microsoft Access database as an ODBC type table. The first information we must obtain is the list of tables existing in this data source. To get it, we will create a catalog table that will return it extracted from the result set of the SQLTables ODBC function:

 
```
create table tabinfo (
  table_name varchar(128) not null,
  table_type varchar(16) not null)
engine=connect table_type=ODBC catfunc=tables
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

The SQLTables function returns a result set having the following columns:

 


| Field | Data Type | Null | Info Type | Flag Value |
| --- | --- | --- | --- | --- |
| Table\_Cat | char(128) | NO | FLD\_CAT | 17 |
| Table\_Name | char(128) | NO | FLD\_SCHEM | 18 |
| Table\_Name | char(128) | NO | FLD\_NAME | 1 |
| Table\_Type | char(16) | NO | FLD\_TYPE | 2 |
| Remark | char(128) | NO | FLD\_REM | 5 |

 
**Note:** The Info Type and Flag Value are CONNECT interpretations of this result.

 Here we could have omitted the column definitions of the catalog table or, as in the above example, chose the columns returning the name and type of the tables. If specified, the columns must have the exact name of the corresponding SQLTables result set, or be given a different name with the matching flag value specification.

 (The Table\_Type can be TABLE, SYSTEM TABLE, VIEW, etc.)

 For instance, to get the tables we want to use we can ask:

 
```
select table_name from tabinfo where table_type = 'TABLE';

```

This will return:

 


| table\_name |
| --- |
| Categories |
| Customers |
| Employees |
| Products |
| Shippers |
| Suppliers |

 
Now we want to create the table to access the CUSTOMERS table. Because CONNECT can retrieve the column description of ODBC tables, it not necessary to specify them in the create table statement:

 
```
create table Customers engine=connect table_type=ODBC
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

However, if we prefer to specify them (to eventually modify them) we must know what the column definitions of that table are. We can get this information with a catalog table. This is how to do it:

 
```
create table custinfo engine=connect table_type=ODBC
tabname=customers catfunc=columns
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

Alternatively it is possible to specify what columns of the catalog table we want:

 
```
create table custinfo (
  column_name char(128) not null,
  type_name char(20) not null,
  length int(10) not null flag=7,
  prec smallint(6) not null flag=9)
  nullable smallint(6) not null)
engine=connect table_type=ODBC tabname=customers
catfunc=columns
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

To get the column info:

 
```
select * from custinfo;

```

which results in this table:

 


| column\_name | type\_name | length | prec | nullable |
| --- | --- | --- | --- | --- |
| CustomerID | VARCHAR | 5 | 0 | 1 |
| CompanyName | VARCHAR | 40 | 0 | 1 |
| ContactName | VARCHAR | 30 | 0 | 1 |
| ContactTitle | VARCHAR | 30 | 0 | 1 |
| Address | VARCHAR | 60 | 0 | 1 |
| City | VARCHAR | 15 | 0 | 1 |
| Region | VARCHAR | 15 | 0 | 1 |
| PostalCode | VARCHAR | 10 | 0 | 1 |
| Country | VARCHAR | 15 | 0 | 1 |
| Phone | VARCHAR | 24 | 0 | 1 |
| Fax | VARCHAR | 24 | 0 | 1 |

 
Now you can create the CUSTOMERS table as:

 
```
create table Customers (
  CustomerID varchar(5),
  CompanyName varchar(40),
  ContactName varchar(30),
  ContactTitle varchar(30),
  Address varchar(60),
  City varchar(15),
  Region varchar(15),
  PostalCode varchar(10),
  Country varchar(15),
  Phone varchar(24),
  Fax varchar(24))
engine=connect table_type=ODBC block_size=10
Connection='DSN=MS Access Database;DBQ=C:/Program
Files/Microsoft Office/Office/1033/FPNWIND.MDB;';

```

Let us explain what we did here: First of all, the creation of the catalog table. This table returns the result set of an ODBC SQLColumns function sent to the ODBC data source. Columns functions always return a data set having some of the following columns, depending on the table type:

 


| Field | Data Type | Null | Info Type | Flag Value | Returned by |
| --- | --- | --- | --- | --- | --- |
| Table\_Cat\* | char(128) | NO | FLD\_CAT | 17 | ODBC, JDBC |
| Table\_Schema\* | char(128) | NO | FLD\_SCEM | 18 | ODBC, JDBC |
| Table\_Name | char(128) | NO | FLD\_TABNAME | 19 | ODBC, JDBC |
| Column\_Name | char(128) | NO | FLD\_NAME | 1 | ALL |
| Data\_Type | smallint(6) | NO | FLD\_TYPE | 2 | ALL |
| Type\_Name | char(30) | NO | FLD\_TYPENAME | 3 | ALL |
| Column\_Size\* | int(10) | NO | FLD\_PREC | 4 | ALL |
| Buffer\_Length\* | int(10) | NO | FLD\_LENGTH | 5 | ALL |
| Decimal\_Digits\* | smallint(6) | NO | FLD\_SCALE | 6 | ALL |
| Radix | smallint(6) | NO | FLD\_RADIX | 7 | ODBC, JDBC, MYSQL |
| Nullable | smallint(6) | NO | FLD\_NULL | 8 | ODBC, JDBC, MYSQL |
| Remarks | char(255) | NO | FLD\_REM | 9 | ODBC, JDBC, MYSQL |
| Collation | char(32) | NO | FLD\_CHARSET | 10 | MYSQL |
| Key | char(4) | NO | FLD\_KEY | 11 | MYSQL |
| Default\_value | N.A. |  | FLD\_DEFAULT | 12 |  |
| Privilege | N.A. |  | FLD\_PRIV | 13 |  |
| Date\_fmt | char(32) | NO | FLD\_DATEFMT | 15 | MYSQL |
| Xpath/Jpath | Varchar(256) | NO | FLD\_FORMAT | 16 | XML/JSON |

 
'\*': These names have changed since earlier versions of CONNECT.

 **Note:** ALL includes the ODBC, JDBC, MYSQL, DBF, CSV, PROXY, TBL, XML, JSON, XCOL, and WMI table types. More could be added later.

 We chose among these columns the ones that were useful for our create statement, using the flag value when we gave them a different name (case insensitive).

 The options used in this definition are the same as the one used later for the actual CUSTOMERS data tables except that:

 1. The `TABNAME` option is mandatory here to specify what the queried table name is.
2. The `CATFUNC` option was added both to indicate that this is a catalog table, and to specify that we want column information.

 **Note:** If the `TABNAME` option had not been specified, this table would have returned the columns of all the tables defined in the connected data source.

 Currently the available `CATFUNC` are:

 


| Function | Specified as: | Applies to table types: |
| --- | --- | --- |
| FNC\_TAB | **tab**les | ODBC, JDBC, MYSQL |
| FNC\_COL | **col**umns | ODBC, JDBC, MYSQL, DBF, CSV, PROXY, XCOL, TBL, WMI |
| FNC\_DSN | **datasource**s**dsn****sqldatasource**s | ODBC |
| FNC\_DRIVER | **driver**s**sqldriver**s | ODBC, JDBC |

 
**Note:** Only the bold part of the function name specification is required.

 The `DATASOURCE` and `DRIVERS` functions respectively return the list of available data sources and ODBC drivers available on the system.

 The SQLDataSources function returns a result set having the following columns:

 


| Field | Data Type | Null | Info Type | Flag value |
| --- | --- | --- | --- | --- |
| Name | varchar(256) | NO | FLD\_NAME | 1 |
| Description | varchar(256) | NO | FLD\_REM | 9 |

 
To get the data source, you can do for instance:

 
```
create table datasources (
engine=CONNECT table_type=ODBC catfunc=DSN;

```

The SQLDrivers function returns a result set having the following columns:

 


| Field | Type | Null | Info Type | Flag value |
| --- | --- | --- | --- | --- |
| Description | varchar(128) | YES | FLD\_NAME | 1 |
| Attributes | varchar(256) | YES | FLD\_REM | 9 |

 
You can get the driver list with:

 
```
create table drivers
engine=CONNECT table_type=ODBC catfunc=drivers;

```

### Another example, WMI table

 To create a catalog table returning the attribute names of a WMI class, use the same table options as the ones used with the normal WMI table plus the additional option ‘catfunc=columns’. If specified, the columns of such a catalog table can be chosen among the following:

 


| Name | Type | Flag | Description |
| --- | --- | --- | --- |
| Column\_Name | CHAR | 1 | The name of the property |
| Data\_Type | INT | 2 | The SQL data type |
| Type\_Name | CHAR | 3 | The SQL type name |
| Column\_Size | INT | 4 | The field length in characters |
| Buffer\_Length | INT | 5 | Depends on the coding |
| Scale | INT | 6 | Depends on the type |

 
If you wish to use a different name for a column, set the Flag column option.

 For example, before creating the "csprod" table, you could have created the info table:

 
```
create table CSPRODCOL (
  Column_name char(64) not null,
  Data_Type int(3) not null,
  Type_name char(16) not null,
  Length int(6) not null,
  Prec int(2) not null flag=6)
engine=CONNECT table_type='WMI' catfunc=col;

```

Now the query:

 
```
select * from csprodcol;

```

will display the result:

 


| Column\_name | Data\_Type | Type\_name | Length | Prec |
| --- | --- | --- | --- | --- |
| Caption | 1 | CHAR | 255 | 1 |
| Description | 1 | CHAR | 255 | 1 |
| IdentifyingNumber | 1 | CHAR | 255 | 1 |
| Name | 1 | CHAR | 255 | 1 |
| SKUNumber | 1 | CHAR | 255 | 1 |
| UUID | 1 | CHAR | 255 | 1 |
| Vendor | 1 | CHAR | 255 | 1 |
| Version | 1 | CHAR | 255 | 1 |

 
This can help to define the columns of the matching normal table.

 **Note 1:** The column length, for the Info table as well as for the normal table, can be chosen arbitrarily, it just must be enough to contain the returned information.

 **Note 2:** The Scale column returns 1 for text columns (meaning case insensitive); 2 for float and double columns; and 0 for other numeric columns.

 ### Catalog Table result size limit

 Because catalog tables are processed like the information retrieved by “Discovery” when table columns are not specified in a Create Table statement, their result set is entirely retrieved and memory allocated.

 By default, this allocation is done for a maximum return line number of:

 


| Catfunc | Max lines |
| --- | --- |
| Drivers | 256 |
| Data Sources | 512 |
| Columns | 20,000 |
| Tables | 10,000 |

 
When the number of lines retrieved for a table is more than this maximum, a warning is issued by CONNECT. This is mainly prone to occur with columns (and also tables) with some data sources having many tables when the table name is not specified.

 If this happens, it is possible to increase the default limit using the MAXRES option, for instance:

 
```
create table allcols engine=connect table_type=odbc
connection='DSN=ORACLE_TEST;UID=system;PWD=manager'
option_list='Maxres=110000' catfunc=columns;

```

Indeed, because the entire table result is memorized before the query is executed; the returned value would be limited even on a query such as:

 
```
select count(*) from allcols;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-catalog-tables/>

CONNECT Table Types - OEM: Implemented in an External LIB
=========================================================

     Although CONNECT provides a rich set of table types, specific applications may need to access data organized in a way that is not handled by its existing foreign data wrappers (FDW). To handle these cases, CONNECT features an interface that enables developers to implement in C++ the required table wrapper and use it as if it were part of the standard CONNECT table type list. CONNECT can use these additional handlers providing the corresponding external module (dll or shared lib) be available.

 To create such a table on an existing handler, use a Create Table statement as shown below.

 
```
create table xtab (column definitions)
engine=CONNECT table_type=OEM module='libname'
subtype='MYTYPE' [standard table options]
Option_list='Myopt=foo';

```

The option module gives the name of the DLL or shared library implementing the OEM wrapper for the table type. This library must be located in the plugin directory like all other plugins or UDF’s.

 This library must export a function *GetMYTYPE*. The option subtype enables CONNECT to have the name of the exported function and to use the new table type. Other options are interpreted by the OEM type and can also be specified within the *option\_list* option.

 Column definitions can be unspecified only if the external wrapper is able to return this information. For this it must export a function ColMYTYPE returning these definitions in a format acceptable by the CONNECT discovery function.

 Which and how options must be specified and the way columns must be defined may vary depending on the OEM type used and should be documented by the OEM type implementer(s).

 An OEM Table Example
--------------------

 The OEM table REST described in [Adding the REST Feature as a Library Called by an OEM Table](../connect-adding-the-rest-feature-as-a-library-called-by-an-oem-table/index) permits using REST-like tables with MariaDB binary distributions containing but not enabling the [REST table type](../connect-files-retrieved-using-rest-queries/index)

 Of course, the mongo (dll or so) exporting the GetREST and colREST functions must be available in the plugin directory for all this to work.

 ### Some Currently Available OEM Table Modules and Subtypes

 


| Module | Subtype | Description |
| --- | --- | --- |
| libhello | HELLO | A sample OEM wrapper displaying a one line table saying “Hello world” |
| mongo | MONGO | Enables using tables based on MongoDB collections. |
| Tabfic | FIC | Handles files having the Windev HyperFile format. |
| Tabofx | OFC | Handles Open Financial Connectivity files. |
| Tabofx | QIF | Handles Quicken Interchange Format files. |
| Cirpack | CRPK | Handles CDR's from Cirpack UTP's. |
| Tabplg | PLG | Access tables from the PlugDB DBMS. |

 
How to implement an OEM handler is out of the scope of this document.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-oem/>

CONNECT Table Types - VIR
=========================

    VIR Type
--------

 A VIR table is a virtual table having only Special or Virtual columns. Its only property is its “size”, or cardinality, meaning the number of virtual rows it contains. It is created using the syntax:

 
```
CREATE TABLE name [coldef] ENGINE=CONNECT TABLE_TYPE=VIR
[BLOCK_SIZE=n];

```

The optional `BLOCK_SIZE` option gives the size of the table, defaulting to 1 if not specified. When its columns are not specified, it is almost equivalent to a [SEQUENCE](../sequence/index) table “seq\_1\_to\_Size”.

 ### Displaying constants or expressions

 Many DBMS use a no-column one-line table to do this, often call “dual”. MySQL and MariaDB use syntax where no table is specified. With CONNECT, you can achieve the same purpose with a virtual table, with the noticeable advantage of being able to display several lines. For example:

 
```
create table virt engine=connect table_type=VIR block_size=10;
select concat('The square root of ', n, ' is') what,
round(sqrt(n),16) value from virt;

```

This will return:

 


| what | value |
| --- | --- |
| The square root of 1 is | 1.0000000000000000 |
| The square root of 2 is | 1.4142135623730951 |
| The square root of 3 is | 1.7320508075688772 |
| The square root of 4 is | 2.0000000000000000 |
| The square root of 5 is | 2.2360679774997898 |
| The square root of 6 is | 2.4494897427831779 |
| The square root of 7 is | 2.6457513110645907 |
| The square root of 8 is | 2.8284271247461903 |
| The square root of 9 is | 3.0000000000000000 |
| The square root of 10 is | 3.1622776601683795 |

 
What happened here? First of all, unlike Oracle “dual” tableS that have no columns, a MariaDB table must have at least one column. By default, CONNECT creates VIR tables with one special column. This can be seen with the SHOW CREATE TABLE statement:

 
```
CREATE TABLE `virt` (
`n` int(11) NOT NULL `SPECIAL`=ROWID,
PRIMARY KEY (`n`)
) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='VIR'
`BLOCK_SIZE`=10

```

This special column is called “n” and its value is the row number starting from 1. It is purely a virtual table and no data file exists corresponding to it and to its index. It is possible to specify the columns of a VIR table but they must be CONNECT special columns or virtual columns. For instance:

 
```
create table virt2 (
n int key not null special=rowid,
sig1 bigint as ((n*(n+1))/2) virtual,
sig2 bigint as(((2*n+1)*(n+1)*n)/6) virtual)
engine=connect table_type=VIR block_size=10000000;
select * from virt2 limit 995, 5;

```

This table shows the sum and the sum of the square of the n first integers:

 


| n | sig1 | sig2 |
| --- | --- | --- |
| 996 | 496506 | 329845486 |
| 997 | 497503 | 330839495 |
| 998 | 498501 | 331835499 |
| 999 | 499500 | 332833500 |
| 1000 | 500500 | 333833500 |

 
Note that the size of the table can be made very big as there no physical data. However, the result should be limited in the queries. For instance:

 
```
select * from virt2 where n = 1664510;

```

Such a query could last very long if the rowid column were not indexed. Note that by default, CONNECT declares the “n” column as a primary key. Actually, VIR tables can be indexed but only on the ROWID (or ROWNUM) columns of the table. This is a virtual index for which no data is stored.

 ### Generating a Table filled with constant values

 An interesting use of virtual tables, which often cannot be achieved with a table of any other type, is to generate a table containing constant values. This is easily done with a virtual table. Let us define the table FILLER as:

 
```
create table filler engine=connect table_type=VIR block_size=5000000;

```

Here we choose a size larger than the biggest table we want to generate. Later if we need a table pre- filled with default and/or null values, we can do for example:

 
```
create table tp (
id int(6) key not null,
name char(16) not null,
salary float(8,2));
insert into tp select n, 'unknown', NULL from filler where n <= 10000;

```

This will generate a table having 10000 rows that can be updated later when needed. Note that a [SEQUENCE](../sequence/index) table could have been used here instead of FILLING .

 ### VIR tables vs. SEQUENCE tables

 With just its default column, a VIR table is almost equivalent to a [SEQUENCE](../sequence/index) table. The syntax used is the main difference, for instance:

 
```
select * from seq_100_to_150_step_10;

```

can be obtained with a VIR table (of size >= 15) by:

 
```
select n*10 from vir where n between 10 and 15;

```

Therefore, the main difference is to be able to define the columns of VIR tables. Unfortunately, there are currently many limitations to virtual columns that hopefully should be removed in the future.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-table-types-vir/>

CONNECT - OEM Table Example
===========================

    This is an example showing how an OEM table can be implemented.

 The header File `my_global.h`:

 
```
/***********************************************************************/
/*  Definitions needed by the included files.                          */
/***********************************************************************/
#if !defined(MY_GLOBAL_H)
#define MY_GLOBAL_H
typedef unsigned int uint;
typedef unsigned int uint32;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned long DWORD;
typedef char *LPSTR;
typedef const char *LPCSTR;
typedef int BOOL;
#if defined(__WIN__)
typedef void *HANDLE;
#else
typedef int HANDLE;
#endif
typedef char *PSZ;
typedef const char *PCSZ;
typedef unsigned char BYTE;
typedef unsigned char uchar;
typedef long long longlong;
typedef unsigned long long ulonglong;
typedef char my_bool;
struct charset_info_st {};
typedef const charset_info_st CHARSET_INFO;
#define FALSE 0
#define TRUE  1
#define Item char
#define MY_MAX(a,b) ((a>b)?(a):(b))
#define MY_MIN(a,b) ((a<b)?(a):(b))
#endif // MY_GLOBAL_H

```

Note: This is a fake `my_global.h` that just contains what is useful for the `jmgoem.cpp`source file.

 The source File `jmgoem.cpp`:

 
```
/************* jmgoem C++ Program Source Code File (.CPP) **************/
/* PROGRAM NAME: jmgoem    Version 1.0                                 */
/*  (C) Copyright to the author Olivier BERTRAND          2017         */
/*  This program is the Java MONGO OEM module definition.              */
/***********************************************************************/

/***********************************************************************/
/*  Definitions needed by the included files.                          */
/***********************************************************************/
#include "my_global.h"

/***********************************************************************/
/*  Include application header files:                                  */
/*  global.h    is header containing all global declarations.          */
/*  plgdbsem.h  is header containing the DB application declarations.  */
/*  (x)table.h  is header containing the TDBASE declarations.          */
/*  tabext.h    is header containing the TDBEXT declarations.          */
/*  mongo.h     is header containing the MONGO declarations.           */
/***********************************************************************/
#include "global.h"
#include "plgdbsem.h"
#if defined(HAVE_JMGO)
#include "csort.h"
#include "javaconn.h"
#endif   // HAVE_JMGO
#include "xtable.h"
#include "tabext.h"
#include "mongo.h"

/***********************************************************************/
/*  These functions are exported from the MONGO library.         	  */
/***********************************************************************/
extern "C" {
  PTABDEF __stdcall GetMONGO(PGLOBAL, void*);
  PQRYRES __stdcall ColMONGO(PGLOBAL, PTOS, void*, char*, char*, bool);
} // extern "C"

/***********************************************************************/
/*  DB static variables.                                               */
/***********************************************************************/
int TDB::Tnum;
int DTVAL::Shift;
#if defined(HAVE_JMGO)
int    CSORT::Limit = 0;
double CSORT::Lg2 = log(2.0);
size_t CSORT::Cpn[1000] = {0};          /* Precalculated cmpnum values */
#if defined(HAVE_JAVACONN)
char *JvmPath = NULL;
char *ClassPath = NULL;
char *GetPluginDir(void) 
{return "C:/mongo-java-driver/mongo-java-driver-3.4.2.jar;"
        "C:/MariaDB-10.1/MariaDB/storage/connect/";}
char *GetJavaWrapper(void) {return (char*)"wrappers/Mongo3Interface";}
#else   // !HAVE_JAVACONN
HANDLE JAVAConn::LibJvm;              // Handle to the jvm DLL
CRTJVM JAVAConn::CreateJavaVM;
GETJVM JAVAConn::GetCreatedJavaVMs;
#if defined(_DEBUG)
GETDEF JAVAConn::GetDefaultJavaVMInitArgs;
#endif  //  _DEBUG
#endif	// !HAVE_JAVACONN
#endif   // HAVE_JMGO

/***********************************************************************/
/*  This function returns a Mongo definition class.                    */
/***********************************************************************/
PTABDEF __stdcall GetMONGO(PGLOBAL g, void *memp)
{
  return new(g, memp) MGODEF;
} // end of GetMONGO

#ifdef NOEXP
/***********************************************************************/
/* Functions to be defined if not exported by the CONNECT version.     */
/***********************************************************************/
bool IsNum(PSZ s)
{
  for (char *p = s; *p; p++)
    if (*p == ']')
      break;
    else if (!isdigit(*p) || *p == '-')
      return false;

  return true;
}	// end of IsNum
#endif

/***********************************************************************/
/*  Return the columns definition to MariaDB.                          */
/***********************************************************************/
PQRYRES __stdcall ColMONGO(PGLOBAL g, PTOS tp, char *tab,
                                               char *db, bool info)
{
#ifdef NOMGOCOL
  // Cannot use discovery
  strcpy(g->Message, "No discovery, MGOColumns is not accessible");
  return NULL;
#else
  return MGOColumns(g, db, NULL, tp, info);
#endif
} // end of ColMONGO

```

The file `mongo.def`: (required only on Windows)

 
```
LIBRARY     MONGO
EXPORTS
   GetMONGO     @1
   ColMONGO     @2

```

### Compiling this OEM

 To compile this OEM module, first make the two or three required files by copy/pasting from the above listings.

 Even if this module is to be used with a binary distribution, you need some source files in order to successfully compile it. At least the CONNECT header files that are included in `jmgoem.cpp` and the ones they can include. This can be obtained by downloading the MariaDB source file tar.gz and extracting from it the CONNECT sources files in a directory that will be added to the additional source directories if it is not the directory containing the above files.

 The module must be linked to the `ha_connect.lib` of the binary version it will used with. Recent distributions add this lib in the plugin directory.

 The resulting module, for instance `mongo.so` or `mongo.dll`, must be placed in the plugin directory of the MariaDB server. Then, you will be able to use MONGO like tables simply replacing in the CREATE TABLE statement the option `TABLE_TYPE=MONGO` with `TABLE_TYPE=OEM SUBTYPE=MONGO MODULE=’mongo.(so|dll)’`. Actually, the module name, here supposedly ‘mongo’, can be anything you like.

 This will work with the last (not yet) distributed versions of [MariaDB 10.0](../what-is-mariadb-100/index) and 10.1 because, even it is not enabled, the MONGO type is included in them. This is also the case for [MariaDB 10.2.9](https://mariadb.com/kb/en/mariadb-1029-release-notes/) but then, on Windows, you will have to define NOEXP and NOMGOCOL because these functions are not exported by this version.

 To implement for older versions that do not contain the MONGO type, you can add the corresponding source files, namely `javaconn.cpp`, `jmgfam.cpp`, `jmgoconn.cpp`, `mongo.cpp` and `tabjmg.cpp` that you should find in the CONNECT extracted source files if you downloaded a recent version. As they include `my_global.h`, this is the reason why the included file was named this way. In addition, your compiling should define `HAVE_JMGO` and `HAVE_JAVACONN`. Of course, this is possible only if `ha_connect.lib` is available.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-oem-table-example/>

CONNECT - Security
==================

    The use of the CONNECT engine requires the `[FILE](../grant/index#global-privileges)` privilege for ["outward"](../inward-and-outward-tables/index#outward-tables) tables. This should not be an important restriction. The use of CONNECT "outward" tables on a remote server seems of limited interest without knowing the files existing on it and must be protected anyway. On the other hand, using it on the local client machine is not an issue because it is always possible to create locally a user with the `FILE` privilege.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-security/>

Using CONNECT
==============

  

| Title | Description |
| --- | --- |
|  [Using CONNECT - General Information](../using-connect-general-information/index) |  Using CONNECT - General Information.  |
|  [Using CONNECT - Virtual and Special Columns](../using-connect-virtual-and-special-columns/index) |  Virtual and special columns example usage  |
|  [Using CONNECT - Importing File Data Into MariaDB Tables](../using-connect-importing-file-data-into-mariadb-tables/index) |  Directly using external (file) data has many advantages  |
|  [Using CONNECT - Exporting Data From MariaDB](../using-connect-exporting-data-from-mariadb/index) |  Exporting data from MariaDB with CONNECT  |
|  [Using CONNECT - Indexing](../using-connect-indexing/index) |  Indexing with the CONNECT handler  |
|  [Using CONNECT - Condition Pushdown](../using-connect-condition-pushdown/index) |  Using CONNECT - Condition Pushdown.  |
|  [USING CONNECT - Offline Documentation](../using-connect-offline-documentation/index) |  CONNECT Plugin User Manual.  |
|  [Using CONNECT - Partitioning and Sharding](../using-connect-partitioning-and-sharding/index) |  Partitioning and Sharding with CONNECT  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect/>

Using CONNECT - General Information
===================================

     The main characteristic of [CONNECT](../connect/index) is to enable accessing data scattered on a machine as if it was a centralized database. This, and the fact that locking is not used by connect (data files are open and closed for each query) makes CONNECT very useful for importing or exporting data into or from a MariaDB database and also for all types of Business Intelligence applications. However, it is not suited for transactional applications.

 For instance, the index type used by CONNECT is closer to bitmap indexing than to B-trees. It is very fast for retrieving result but not when updating is done. In fact, even if only one indexed value is modified in a big table, the index is entirely remade (yet this being four to five times faster than for a b-tree index). But normally in Business Intelligence applications, files are not modified so often.

 If you are using CONNECT to analyze files that can be modified by an external process, the indexes are of course not modified by it and become outdated. Use the OPTIMIZE TABLE command to update them before using the tables based on them.

 This means also that CONNECT is not designed to be used by centralized servers, which are mostly used for transactions and often must run a long time without human intervening.

 ### Performance

 Performances vary a great deal depending on the table type. For instance, ODBC tables are only retrieved as fast as the other DBMS can do. If you have a lot of queries to execute, the best way to optimize your work can be sometime to translate the data from one type to another. Fortunately this is very simple with CONNECT. Fixed formats like FIX, BIN or VEC tables can be created from slower ones by commands such as:

 
```
Create table fastable table_specs select * from slowtable;

```

`FIX` and `BIN` are often the better choice because the I/O functions are done on blocks of `BLOCK_SIZE` rows. `VEC` tables can be very efficient for tables having many columns only a few being used in each query. Furthermore, for tables of reasonable size, the `MAPPED` option can very often speed up many queries.

 ### Create Table statement

 Be aware of the two broad kinds of CONNECT tables:

 

|  |  |
| --- | --- |
| **Inward** | They are table whose file name is not specified at create. An empty file will be given a default name (*tabname.tabtype*) and will be populated like for other engines. They do not require the FILE privilege and can be used for testing purpose. |
| **Outward** | They are all other `CONNECT` tables and access external data sources or files. They are the true useful tables but require the `FILE` privilege. |

 ### Drop Table statement

 For outward tables, the [DROP TABLE](../drop-table/index) statement just removes the table definition but does not erase the table data. However, dropping an inward tables also erase the table data as well.

 ### Alter Table statement

 Be careful using the [ALTER TABLE](../alter-table/index) statement. Currently the data compatibility is not tested and the modified definition can become incompatible with the data. In particular, Alter modifies the table definition only but does not modify the table data. Consequently, the table type should not be modified this way, except to correct an incorrect definition. Also adding, dropping or modifying columns may be wrong because the default offset values (when not explicitly given by the FLAG option) may be wrong when recompiled with missing columns.

 Safe use of ALTER is for indexing, as we have seen earlier, and to change options such as MAPPED or HUGE those do not impact the data format but just the way the data file is accessed. Modifying the BLOCK\_SIZE option is all right with FIX, BIN, DBF, split VEC tables; however it is unsafe for VEC tables that are not split (only one data file) because at their creation the estimate size has been made a multiple of the block size. This can cause errors if this estimate is not a multiple of the new value of the block size.

 In all cases, it is safer to drop and re-create the table (outward tables) or to make another one from the table that must be modified.

 ### Update and Delete for File Tables

 CONNECT can execute these commands using two different algorithms:

 * It can do it in place, directly modifying rows (update) or moving rows (delete) within the table file. This is a fast way to do it in particular when indexing is used.
* It can do it using a temporary file to make the changes. This is required when updating variable record length tables and is more secure in all cases.

 The choice between these algorithms depends on the session variable [connect\_use\_tempfile](../connect-system-variables/index#connect_use_tempfile).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-general-information/>

Using CONNECT - Exporting Data From MariaDB
===========================================

    Exporting data from MariaDB is obviously possible with CONNECT in particular for all formats not supported by the `[SELECT INTO OUTFILE](../select-into-outfile/index)` statement. Let us consider the query:

 
```
select plugin_name handler, plugin_version version, plugin_author
author, plugin_description description, plugin_maturity maturity
from information_schema.plugins where plugin_type = 'STORAGE ENGINE';

```

Supposing you want to get the result of this query into a file handlers.htm in XML/HTML format, allowing displaying it on an Internet browser, this is how you can do it:

 Just create the CONNECT table that will be used to make the file:

 
```
create table handout
engine=CONNECT table_type=XML file_name='handout.htm' header=yes
option_list='name=TABLE,coltype=HTML,attribute=border=1;cellpadding=5
     ,headattr=bgcolor=yellow'
select plugin_name handler, plugin_version version, plugin_author
author, plugin_description description, plugin_maturity maturity
from information_schema.plugins where plugin_type = 'STORAGE ENGINE';

```

Here the column definition is not given and will come from the Select statement following the Create. The CONNECT options are the same we have seen previously. This will do both actions, creating the matching *handlers* CONNECT table and 'filling' it with the query result.

 **Note 1:** This could not be done in only one statement if the table type had required using explicit CONNECT column options. In this case, firstly create the table, and then populate it with an Insert statement.

 **Note 2:** The source “plugins” table column “description” is a long text column, data type not supported for CONNECT tables. It has been silently internally replaced by varchar(256).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-exporting-data-from-mariadb/>

Using CONNECT - Importing File Data Into MariaDB Tables
=======================================================

    Directly using external (file) data has many advantages, such as to work on “fresh” data produced for instance by cash registers, telephone switches, or scientific apparatus. However, you may want in some case to import external data into your MariaDB database. This is extremely simple and flexible using the CONNECT handler. For instance, let us suppose you want to import the data of the xsample.xml XML file previously given in example into a [MyISAM](../myisam/index) table called *biblio* belonging to the connect database. All you have to do is to create it by:

 
```
create table biblio engine=myisam select * from xsampall2;

```

This last statement creates the [MyISAM](../myisam/index) table and inserts the original XML data, translated to tabular format by the *xsampall2* CONNECT table, into the MariaDB *biblio* table. Note that further transformation on the data could have been achieved by using a more elaborate Select statement in the Create statement, for instance using filters, alias or applying functions to the data. However, because the Create Table process copies table data, later modifications of the *xsample.xml* file will not change the *biblio* table and changes to the *biblio* table will not modify the *xsample.xml* file.

 All these can be combined or transformed by further SQL operations. This makes working with CONNECT much more flexible than just using the [LOAD](../load/index) statement.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-importing-file-data-into-mariadb-tables/>

Using CONNECT - Condition Pushdown
==================================

    The [ODBC](../connect-table-types-odbc-table-type-accessing-tables-from-other-dbms/index), [JDBC](../connect-jdbc-table-type-accessing-tables-from-other-dbms/index), [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index), [TBL](../connect-table-types-tbl-table-type-table-list/index) and WMI table types use engine condition pushdown in order to restrict the number of rows returned by the RDBS source or the WMI component.

 The CONDITION\_PUSHDOWN argument used in old versions of CONNECT is no longer needed because CONNECT uses condition pushdown unconditionally.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-condition-pushdown/>

Using CONNECT - Indexing
========================

    [Indexing](../optimization-and-indexes/index) is one of the main ways to optimize queries. Key columns, in particular when they are used to join tables, should be indexed. But what should be done for columns that have only few distinct values? If they are randomly placed in the table they should not be indexed because reading many rows in random order can be slower than reading the entire table sequentially. However, if the values are sorted or clustered, indexing can be acceptable because [CONNECT](../connect/index) indexes store the values in the order they appear into the table and this will make retrieving them almost as fast as reading them sequentially.

 CONNECT provides four indexing types:

 1. Standard Indexing
2. Block Indexing
3. Remote Indexing
4. Dynamic Indexing

 Standard Indexing
-----------------

 CONNECT standard indexes are created and used as the ones of other storage engines although they have a specific internal format. The CONNECT handler supports the use of standard indexes for most of the file based table types.

 You can define them in the [CREATE TABLE](../create-table/index) statement, or either using the CREATE INDEX statement or the [ALTER TABLE](../alter-table/index) statement. In all cases, the index files are automatically made. They can be dropped either using the [DROP INDEX](../drop-index/index) statement or the [ALTER TABLE](../alter-table/index) statement, and this erases the index files.

 Indexes are automatically reconstructed when the table is created, modified by INSERT, UPDATE or DELETE commands, or when the SEPINDEX option is changed. If you have a lot of changes to do on a table at one moment, you can use table locking to prevent indexes to be reconstructed after each statement. The indexes will be reconstructed when unlocking the table. For instance:

 
```
lock table t1 write;
insert into t1 values(...);
insert into t1 values(...);
...
unlock tables;

```

If a table was modified by an external application that does not handle indexing, the indexes must be reconstructed to prevent returning false or incomplete results. To do this, use the [OPTIMIZE TABLE](../optimize-table/index) command.

 For outward tables, index files are not erased when dropping the table. This is the same as for the data file and preserves the possibility of several users using the same data file via different tables.

 Unlike other storage engines, CONNECT constructs the indexes as files that are named by default from the data file name, not from the table name, and located in the data file directory. Depending on the SEPINDEX table option, indexes are saved in a unique file or in separate files (if SEPINDEX is true). For instance, if indexes are in separate files, the primary index of the table *dept.dat* of type DOS is a file named *dept\_PRIMARY.dnx*. This makes possible to define several tables on the same data file, with eventual different options such as mapped or not mapped, and to share the index files as well.

 If the index file should have a different name, for instance because several tables are created on the same data file with different indexes, specify the base index file name with the XFILE\_NAME option.

 **Note1:** Indexed columns must be declared NOT NULL; CONNECT doesn't support indexes containing null values.

 **Note 2:** MRR is used by standard indexing if it is enabled.

 **Note 3:** Prefix indexing is not supported. If specified, the CONNECT engine ignores the prefix and builds a whole index.

 ### Handling index errors

 The way CONNECT handles indexing is very specific. All table modifications are done regardless of indexing. Only after a table has been modified, or when an `OPTIMIZE TABLE` command is sent are the indexes made. If an error occurs, the corresponding index is not made. However, CONNECT being a non-transactional engine, it is unable to roll back the changes made to the table. The main causes of indexing errors are:

 * Trying to index a nullable column. In this case, you can alter the table to declare the column as not nullable or, if the column is nullable indeed, make it not indexed.

 * Entering duplicate values in a column indexed by a unique index. In this case, if the index was wrongly declared as unique, alter is declaration to reflect this. If the column should really contain unique values, you must manually remove or update the duplicate values.

 In both cases, after correcting the error, remake the indexes with the [OPTIMIZE TABLE](../optimize-table/index) command.

 ### Index file mapping

 To accelerate the indexing process, CONNECT makes an index structure in memory from the index file. This can be done by reading the index file or using it as if it was in memory by “file mapping”. On enabled versions, file mapping is used according to the boolean [connect\_indx\_map](../connect-system-variables/index#connect_indx_map) system variable. Set it to 0 (file read) or 1 (file mapping).

 Block Indexing
--------------

 To accelerate input/output, CONNECT uses when possible a read/write mode by blocks of n rows, n being the value given in the BLOCK \_ SIZE option of the Create Table, or a default value depending on the table type. This is automatic for fixed files ([FIX](../connect-table-types-data-files/index#dos-and-fix-table-types), [BIN](../connect-table-types-data-files/index#bin-table-type), [DBF](../connect-table-types-data-files/index#dbf-type) or [VEC](../connect-table-types-data-files/index#vec-table-type-vector)), but must be specified for variable files ([DOS](../connect-table-types-data-files/index#dos-and-fix-table-types) , [CSV](../connect-table-types-data-files/index#csv-and-fmt-table-types) or [FMT](../connect-table-types-data-files/index#fmt-type) ).

 For blocked tables, further optimization can be achieved if the data values for some columns are “clustered” meaning that they are not evenly scattered in the table but grouped in some consecutive rows. Block indexing permits to skip blocks in which no rows fulfill a conditional predicate without having even to read the block. This is true in particular for sorted columns.

 You indicate this when creating the table by using the DISTRIB =d column option. The enum value d can be *scattered*, *clustered*, or *sorted*. In general only one column can be sorted. Block indexing is used only for clustered and sorted columns.

 ### Difference between standard indexing and block indexing

 * Block indexing is internally handled by CONNECT while reading sequentially a table data. This means in particular that when standard indexing is used on a table, block indexing is not used.
* In a query, only one standard index can be used. However, block indexing can combine the restrictions coming from a where clause implying several clustered/sorted columns.
* The block index files are faster to make and much smaller than standard index files.

 ### Notes for this Release:

 * On all operations that create or modify a table, CONNECT automatically calculates or recalculates and saves the mini/maxi or bitmap values for each block, enabling it to skip block containing no acceptable values. In the case where the optimize file does not correspond anymore to the table, because it has been accidentally destroyed, or because some column definitions have been altered, you can use the OPTIMIZE TABLE command to reconstruct the optimization file.
* Sorted column special processing is currently restricted to ascending sort. Column sorted in descending order must be flagged as clustered. Improper sorting is not checked in Update or Insert operations but is flagged when optimizing the table.
* Block indexing can be done in two ways. Keeping the min/max values existing for each block, or keeping a bitmap allowing knowing what column distinct values are met in each blocks. This second ways often gives a better optimization, except for sorted columns for which both are equivalent. The bitmap approach can be done only on columns having not too many distinct values. This is estimated by the MAX \_ DIST option value associated to the column when creating the table. ~~Bitmap block indexing will be used if this number is not greater than the MAXBMP setting for the database~~.
* CONNECT cannot perform block indexing on case insensitive character columns. To force block indexing on a character column, specify its charset as not case insensitive, for instance as binary. However this will also apply to all other clauses, this column being now case sensitive.

 Remote Indexing
---------------

 Remote indexing is specific to the [MYSQL](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index) table type. It is equivalent to what the [FEDERATED](../federatedx-storage-engine/index) storage does. A MYSQL table does not support indexes per se. Because access to the table is handled remotely, it is the remote table that supports the indexes. What the MYSQL table does is just to add a WHERE clause to the [SELECT](../select/index) command sent to the remote server allowing the remote server to use indexing when applicable. Note however that because CONNECT adds when possible all or part of the where clause of the original query, this happens often even if the remote indexed column is not declared locally indexed. The only, but very important, case a column should be locally declared indexed is when it is used to join tables. Otherwise, the required where clause would not be added to the sent SELECT query.

 See [Indexing of MYSQL tables](../connect-table-types-mysql-table-type-accessing-mysqlmariadb-tables/index#indexing-of-mysql-tables) for more.

 Dynamic Indexing
----------------

 An indexed created as “dynamic” is a standard index which, in some cases, can be reconstructed for a specific query. This happens in particular for some queries where two tables are joined by an indexed key column. If the “from” table is big and the “to” big table reduced in size because of a where clause, it can be worthwhile to reconstruct the index on this reduced table.

 Because of the time added by reconstructing the index, this will be valuable only if the time gained by reducing the index size if more than this reconstruction time. This is why this should not be done if the “from” table is small because there will not be enough row joining to compensate for the additional time. Otherwise, the gain of using a dynamic index is:

 * Indexing time is a little faster if the index is smaller.
* The join process will return only the rows fulfilling the where clause.
* Because the table is read sequentially when reconstructing the index there no need for MRR.
* Constructing the index can be faster if the table is reduced by block indexing.
* While constructing the index, CONNECT also stores in memory the values of other used columns.

 This last point is particularly important. It means that after the index is reconstructed, the join is done on a temporary memory table.

 Unfortunately, storage engines being called independently by MariaDB for each table, CONNECT has no global information to decide when it is good to use dynamic indexing. This is why you should use it only on cases where you see that some important join queries take a very long time and only on columns used for joining the table. How to declare an index to be dynamic is by using the Boolean DYNAM index option. For instance, the query:

 
```
select d.diag, count(*) cnt from diag d, patients p where d.pnb =
p.pnb and ageyears < 17 and county = 30 and drg <> 11 and d.diag
between 4296 and 9434 group by d.diag order by cnt desc;

```

Such a query joining the diag table to the patients table may last a very long time if the tables are big. To declare the primary key on the pnb column of the patients table to be dynamic:

 
```
alter table patients drop primary key;
alter table patients add primary key (pnb) comment 'DYNAMIC' dynam=1;

```

Note 1: The comment is not mandatory here but useful to see that the index is dynamic if you use the [SHOW INDEX](../show-index/index) command.

 Note 2: There is currently no way to just change the DYNAM option without dropping and adding the index. This is unfortunate because it takes time.

 Virtual Indexing
----------------

 It applies only to the virtual tables of type [VIR](../connect-table-types-vir/index) and must be made on a column specifying `SPECIAL=ROWID` or `SPECIAL=ROWNUM`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-indexing/>

Adding DataFlex 3.1c .dat Files As An External Table Type With CONNECT
======================================================================

    I'm using MariaDB's CONNECT engine to access / utilize a set of Visual FoxPro / dBase files as part of supporting an extremely old piece of software for a client. It's works SO well, and I'm extremely happy with it. 

 In fact, my client is so happy with my support that he recommended me to a friend of his. His friend's ridiculously old piece of software uses DataFlex 3.1c files as it's tables. They're simply stored as a bunch of .dat files in a folder. 

 I've found enough documentation to pretty much nail down the file format. The CONNECT engine recognizes them just fine as DOS or BIN types files. The one and only problem is that MariaDB expects the first record to begin at the beginning of the file, but the .dat files contain a header portion that describes the table itself. I can read that and calculate the correct CREATE TABLE statement just fine, but I can't seem to find a way to compensate for the header being where MariaDB expects records to be. 

 How can I tell MariaDB where the first record actually begins? 

 I've actually written a functional parser for the .dat files in Python based of of the notes here [here](https://hwiegman.home.xs4all.nl/fileformats/dat/DATAFLEX.txt) and [here](https://code.activestate.com/lists/perl-dbi-dev/1529/).

 I also used [this](https://github.com/tforsberg/DataFlexToSQLite) GitHub project as a guide / template (being as I didn't want to convert the DataFlex files, just read and write to them in place).

 I was advised by @montywi on the Freenode IRC channel that this was the best place for my question. I will happily supply reference .dat files and support their inclusion in CONNECT however I can. I'm just at a total loss for how to proceed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/adding-dataflex-31c-dat-files-as-an-external-table-type-with-connect/>

Using CONNECT - Virtual and Special Columns
===========================================

    CONNECT supports MariaDB [virtual and persistent columns](../virtual-columns/index). It is also possible to declare a column as being a CONNECT special column. Let us see on an example how this can be done. The boys table we have seen previously can be recreated as:

 
```
create table boys (
  linenum int(6) not null default 0 special=rowid,
  name char(12) not null,
  city char(12) not null,
  birth date not null date_format='DD/MM/YYYY',
  hired date not null date_format='DD/MM/YYYY' flag=36,
  agehired int(3) as (floor(datediff(hired,birth)/365.25))
  virtual,
  fn char(100) not null default '' special=FILEID)
engine=CONNECT table_type=FIX file_name='boys.txt' mapped=YES lrecl=47;

```

We have defined two CONNECT special columns. You can give them any name; it is the field SPECIAL option that specifies the special column functional name.

 **Note:** the default values specified for the special columns do not mean anything. They are specified just to prevent getting warning messages when inserting new rows.

 For the definition of the *agehired* virtual column, no CONNECT options can be specified as it has no offset or length, not being stored in the file.

 The command:

 
```
select * from boys where city = 'boston';

```

will return:

 


| linenum | name | city | birth | hired | agehired | fn |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | John | Boston | 1986-01-25 | 2010-06-02 | 24 | d:\mariadb\sql\data\boys.txt |
| 2 | Henry | Boston | 1987-06-07 | 2008-04-01 | 20 | d:\mariadb\sql\data\boys.txt |
| 6 | Bill | Boston | 1986-09-11 | 2008-02-10 | 21 | d:\mariadb\sql\data\boys.txt |

 
Existing special columns are listed in the following table:

 


| Special Name | Type | Description of the column value |
| --- | --- | --- |
| ROWID | Integer | The row ordinal number in the table. This is not quite equivalent to a virtual column with an auto increment of 1 because rows are renumbered when deleting rows. |
| ROWNUM | Integer | The row ordinal number in the file. This is different from ROWID for multiple tables, TBL/XCOL/OCCUR/PIVOT tables, XML tables with a multiple column, and for DBF tables where ROWNUM includes soft deleted rows. |
| FILEID FDISK FPATH FNAME FTYPE | String | FILEID returns the full name of the file this row belongs to. Useful in particular for multiple tables represented by several files. The other special columns can be used to retrieve only one part of the full name. |
| TABID | String | The name of the table this row belongs to. Useful for TBL tables. |
| PARTID | String | The name of the partition this row belongs to. Specific to partitioned tables. |
| SERVID | String | The name of the federated server or server host used by a MYSQL table. “ODBC” for an ODBC table, "JDBC" for a JDBC table and “Current” for all other tables. |

 
**Note:** CONNECT does not currently support auto incremented columns. However, a `ROWID` special column will do the job of a column auto incremented by 1.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-virtual-and-special-columns/>

JSON Sample Files
=================

    ### Expense.json

 
```
[
  {
    "WHO": "Joe",
    "WEEK": [
      {
        "NUMBER": 3,
        "EXPENSE": [
          {
            "WHAT": "Beer",
            "AMOUNT": 18.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 12.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 19.00
          },
          {
            "WHAT": "Car",
            "AMOUNT": 20.00
          }
        ]
      },
      {
        "NUMBER": 4,
        "EXPENSE": [
          {
            "WHAT": "Beer",
            "AMOUNT": 19.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 16.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 17.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 17.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 14.00
          }
        ]
      },
      {
        "NUMBER": 5,
        "EXPENSE": [
          {
            "WHAT": "Beer",
            "AMOUNT": 14.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 12.00
          }
        ]
      }
    ]
  },
  {
    "WHO": "Beth",
    "WEEK": [
      {
        "NUMBER": 3,
        "EXPENSE": [
          {
            "WHAT": "Beer",
            "AMOUNT": 16.00
          }
        ]
      },
      {
        "NUMBER": 4,
        "EXPENSE": [
          {
            "WHAT": "Food",
            "AMOUNT": 17.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 15.00
          }
        ]
      },
      {
        "NUMBER": 5,
        "EXPENSE": [
          {
            "WHAT": "Food",
            "AMOUNT": 12.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 20.00
          }
        ]
      }
    ]
  },
  {
    "WHO": "Janet",
    "WEEK": [
      {
        "NUMBER": 3,
        "EXPENSE": [
          {
            "WHAT": "Car",
            "AMOUNT": 19.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 18.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 18.00
          }
        ]
      },
      {
        "NUMBER": 4,
        "EXPENSE": [
          {
            "WHAT": "Car",
            "AMOUNT": 17.00
          }
        ]
      },
      {
        "NUMBER": 5,
        "EXPENSE": [
          {
            "WHAT": "Beer",
            "AMOUNT": 14.00
          },
          {
            "WHAT": "Car",
            "AMOUNT": 12.00
          },
          {
            "WHAT": "Beer",
            "AMOUNT": 19.00
          },
          {
            "WHAT": "Food",
            "AMOUNT": 12.00
          }
        ]
      }
    ]
  }
]

```

### OEM example

 This is an example showing how an OEM table can be implemented. It is out of the scope of this document to explain how it works and to be a full guide on writing OEM tables for CONNECT.

 #### tabfic.h

 The header File tabfic.h:

 
```
// TABFIC.H     Olivier Bertrand    2008-2010
// External table type to read FIC files

#define TYPE_AM_FIC  (AMT)129

typedef class FICDEF *PFICDEF;
typedef class TDBFIC *PTDBFIC;
typedef class FICCOL *PFICCOL;

/* ------------------------- FIC classes ------------------------- */

/*******************************************************************/
/*  FIC: OEM table to read FIC files.                              */
/*******************************************************************/

/*******************************************************************/
/*  This function is exported from the Tabfic.dll 			 */
/*******************************************************************/
extern "C" PTABDEF __stdcall GetFIC(PGLOBAL g, void *memp);

/*******************************************************************/
/*  FIC table definition class.                                    */
/*******************************************************************/
class FICDEF : public DOSDEF {        /* Logical table description */
  friend class TDBFIC;
 public:
  // Constructor
  FICDEF(void) {Pseudo = 3;}

  // Implementation
  virtual const char *GetType(void) {return "FIC";}

  // Methods
  virtual BOOL DefineAM(PGLOBAL g, LPCSTR am, int poff);
  virtual PTDB GetTable(PGLOBAL g, MODE m);

 protected:
  // No Members
}; // end of class FICDEF

/*******************************************************************/
/*  This is the class declaration for the FIC table.               */
/*******************************************************************/
class TDBFIC : public TDBFIX {
  friend class FICCOL;
 public:
  // Constructor
  TDBFIC(PFICDEF tdp);

  // Implementation
  virtual AMT   GetAmType(void) {return TYPE_AM_FIC;}

  // Methods
  virtual void  ResetDB(void);
  virtual int   RowNumber(PGLOBAL g, BOOL b = FALSE);

  // Database routines
  virtual PCOL  MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
  virtual BOOL  OpenDB(PGLOBAL g, PSQL sqlp);
  virtual int   ReadDB(PGLOBAL g);
  virtual int   WriteDB(PGLOBAL g);
  virtual int   DeleteDB(PGLOBAL g, int irc);

 protected:
  // Members
  int ReadMode;				  // To read soft deleted lines
  int Rows;                           // Used for RowID
}; // end of class TDBFIC

/*******************************************************************/
/*  Class FICCOL: for Monetary columns.                            */
/*******************************************************************/
class FICCOL : public DOSCOL {
 public:
  // Constructors
  FICCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, 
         PCOL cprec, int i, PSZ am = "FIC");

  // Implementation
  virtual int  GetAmType(void) {return TYPE_AM_FIC;}

  // Methods
  virtual void ReadColumn(PGLOBAL g);

 protected:
  // Members
  char Fmt;					  // The column format
}; // end of class FICCOL

```

#### tabfic.cpp

 The source File tabfic.cpp:

 
```
/*******************************************************************/
/*  FIC: OEM table to read FIC files.                              */
/*******************************************************************/
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN      // Exclude rarely-used stuff
#include <windows.h>
#endif   // WIN32
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "filamfix.h"
#include "tabfix.h"
#include "tabfic.h"

int TDB::Tnum;
int DTVAL::Shift;

/*******************************************************************/
/*  Initialize the CSORT static members.                           */
/*******************************************************************/
int    CSORT::Limit = 0;
double CSORT::Lg2 = log(2.0);
size_t CSORT::Cpn[1000] = {0};      /* Precalculated cmpnum values */

/* ------------- Implementation of the FIC subtype --------------- */

/*******************************************************************/
/*  This function is exported from the DLL.                        */
/*******************************************************************/
PTABDEF __stdcall GetFIC(PGLOBAL g, void *memp)
{
  return new(g, memp) FICDEF;
} // end of GetFIC

/* -------------- Implementation of the FIC classes -------------- */

/*******************************************************************/
/*  DefineAM: define specific AM block values from FIC file.       */
/*******************************************************************/
BOOL FICDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
  ReadMode = GetIntCatInfo("Readmode", 0);

  // Indicate that we are a BIN format
  return DOSDEF::DefineAM(g, "BIN", poff);
} // end of DefineAM

/*******************************************************************/
/*  GetTable: makes a new TDB of the proper type.                  */
/*******************************************************************/
PTDB FICDEF::GetTable(PGLOBAL g, MODE m)
{
  return new(g) TDBFIC(this);
} // end of GetTable

/* --------------------------------------------------------------- */

/*******************************************************************/
/*  Implementation of the TDBFIC class.                            */
/*******************************************************************/
TDBFIC::TDBFIC(PFICDEF tdp) : TDBFIX(tdp, NULL)
{
  ReadMode = tdp->ReadMode;
  Rows = 0;
} // end of TDBFIC constructor

/*******************************************************************/
/*  Allocate FIC column description block.                         */
/*******************************************************************/
PCOL TDBFIC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
  PCOL colp;

  // BINCOL is alright except for the Monetary format
  if (cdp->GetFmt() && toupper(*cdp->GetFmt()) == 'M')
    colp = new(g) FICCOL(g, cdp, this, cprec, n);
  else
    colp = new(g) BINCOL(g, cdp, this, cprec, n);

  return colp;
} // end of MakeCol

/*******************************************************************/
/*  RowNumber: return the ordinal number of the current row.       */
/*******************************************************************/
int TDBFIC::RowNumber(PGLOBAL g, BOOL b)
{
  return (b) ? Txfp->GetRowID() : Rows;
} // end of RowNumber

/*******************************************************************/
/*  FIC Access Method reset table for re-opening.                  */
/*******************************************************************/
void TDBFIC::ResetDB(void)
{
  Rows = 0;
  TDBFIX::ResetDB();
} // end of ResetDB

/*******************************************************************/
/*  FIC Access Method opening routine.                             */
/*******************************************************************/
BOOL TDBFIC::OpenDB(PGLOBAL g, PSQL sqlp)
{
  if (Use == USE_OPEN) {
    // Table already open, just replace it at its beginning.          
    return TDBFIX::OpenDB(g);
    } // endif use

  if (Mode != MODE_READ) {
    // Currently FIC tables cannot be modified.
    strcpy(g->Message, "FIC tables are read only");
    return TRUE;
    } // endif Mode

  /*****************************************************************/
  /*  Physically open the FIC file.                                */
  /*****************************************************************/
  if (TDBFIX::OpenDB(g))
    return TRUE;

  Use = USE_OPEN;
  return FALSE;
} // end of OpenDB

/*******************************************************************/
/*  ReadDB: Data Base read routine for FIC access method.          */
/*******************************************************************/
int TDBFIC::ReadDB(PGLOBAL g)
{
  int rc;

  /*****************************************************************/
  /*  Now start the reading process.                               */
  /*****************************************************************/
  do {
    rc = TDBFIX::ReadDB(g);
    } while (rc == RC_OK && ((ReadMode == 0 && *To_Line == '*') ||
				     (ReadMode == 2 && *To_Line != '*')));

  Rows++;
  return rc;
} // end of ReadDB

/*******************************************************************/
/*  WriteDB: Data Base write routine for FIC access methods.       */
/*******************************************************************/
int TDBFIC::WriteDB(PGLOBAL g)
{
  strcpy(g->Message, "FIC tables are read only");
  return RC_FX;
} // end of WriteDB

/*******************************************************************/
/*  Data Base delete line routine for FIC access methods.          */
/*******************************************************************/
int TDBFIC::DeleteDB(PGLOBAL g, int irc)
{
  strcpy(g->Message, "Delete not enabled for FIC tables");
  return RC_FX;
} // end of DeleteDB

// ---------------------- FICCOL functions --------------------------

/*******************************************************************/
/*  FICCOL public constructor.                                     */
/*******************************************************************/
FICCOL::FICCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i,
               PSZ am) : DOSCOL(g, cdp, tdbp, cprec, i, am)
{
  // Set additional FIC access method information for column.
  Fmt = toupper(*cdp->GetFmt());    // Column format
} // end of FICCOL constructor

/*******************************************************************/
/*  Handle the monetary value of this column. It is a big integer  */
/*  that represents the value multiplied by 1000.                  */
/*  In this function we translate it to a double float value.      */                 
/*******************************************************************/
void FICCOL::ReadColumn(PGLOBAL g)
{
  char   *p;
  int     rc;
  uint    n;
  double  fmon;
  PTDBFIC tdbp = (PTDBFIC)To_Tdb;

  /*****************************************************************/
  /*  If physical reading of the line was deferred, do it now.     */
  /*****************************************************************/
  if (!tdbp->IsRead())
    if ((rc = tdbp->ReadBuffer(g)) != RC_OK) {
      if (rc == RC_EF)
        sprintf(g->Message, MSG(INV_DEF_READ), rc);

      longjmp(g->jumper[g->jump_level], 11);
      } // endif

  p = tdbp->To_Line + Deplac;

  /*****************************************************************/
  /*  Set Value from the line field.                               */
  /*****************************************************************/
  if (*(SHORT*)(p + 8) < 0) {
    n = ~*(SHORT*)(p + 8);
    fmon = (double)n;
    fmon *= 4294967296.0;
    n = ~*(int*)(p + 4);
    fmon += (double)n;
    fmon *= 4294967296.0;
    n = ~*(int*)p;
    fmon += (double)n;
    fmon++;
    fmon /= 1000000.0;
    fmon = -fmon;
  } else {
    fmon = ((double)*(USHORT*)(p + 8));
    fmon *= 4294967296.0;
    fmon += ((double)*(ULONG*)(p + 4));
    fmon *= 4294967296.0;
    fmon += ((double)*(ULONG*)p);
    fmon /= 1000000.0;
  } // enif neg

  Value->SetValue(fmon);
} // end of ReadColumn

```

#### tabfic.def

 The file tabfic.def: (required only on Windows)

 
```
LIBRARY     TABFIC
DESCRIPTION 'FIC files'
EXPORTS
   GetFIC       @1

```

### JSON UDFs in a separate library

 Although the JSON UDF’s can be nicely included in the CONNECT library module, there are cases when you may need to have them in a separate library.

 This is when CONNECT is compiled embedded, or if you want to test or use these UDF’s with other MariaDB versions not including them.

 To make it, you need to have access to the last MariaDB source code. Then, make a project containing these files:

 1. jsonudf.cpp
2. json.cpp
3. value.cpp
4. osutil.c
5. plugutil.c
6. maputil.cpp
7. jsonutil.cpp

 jsonutil.cpp is not distributed with the source code, you will have to make it from the following:

 
```

#include "my_global.h"
#include "mysqld.h"
#include "plugin.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include "global.h"

extern "C" int GetTraceValue(void) { return 0; }
uint GetJsonGrpSize(void) { return 100; }

/***********************************************************************/
/*  These replace missing function of the (not used) DTVAL class.      */
/***********************************************************************/
typedef struct _datpar   *PDTP;
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int) { return NULL; }
int ExtractDate(char*, PDTP, int, int val[6]) { return 0; }


#ifdef __WIN__
my_bool CloseFileHandle(HANDLE h)
{
	return !CloseHandle(h);
} /* end of CloseFileHandle */

#else  /* UNIX */
my_bool CloseFileHandle(HANDLE h)
{
	return (close(h)) ? TRUE : FALSE;
}  /* end of CloseFileHandle */

int GetLastError()
{
	return errno;
}  /* end of GetLastError */

#endif  // UNIX

/***********************************************************************/
/*  Program for sub-allocating one item in a storage area.             */
/*  Note: This function is equivalent to PlugSubAlloc except that in   */
/*  case of insufficient memory, it returns NULL instead of doing a    */
/*  long jump. The caller must test the return value for error.        */
/***********************************************************************/
void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
{
  PPOOLHEADER pph;                        // Points on area header.

  if (!memp)  	//  Allocation is to be done in the Sarea
    memp = g->Sarea;

  size = ((size + 7) / 8) * 8;  /* Round up size to multiple of 8 */
  pph = (PPOOLHEADER)memp;

  if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
    sprintf(g->Message,
     "Not enough memory in Work area for request of %d (used=%d free=%d)",
			(int)size, pph->To_Free, pph->FreeBlk);
    return NULL;
  } // endif size

  // Do the suballocation the simplest way
  memp = MakePtr(memp, pph->To_Free);   // Points to sub_allocated block
  pph->To_Free += size;                 // New offset of pool free block
  pph->FreeBlk -= size;                 // New size   of pool free block

  return (memp);
} // end of PlgDBSubAlloc

```

You can create the file by copy/paste from the above.

 Set all the additional include directories to the MariaDB include directories used in plugin compiling plus the reference of the storage/connect directories, and compile like any other UDF giving any name to the made library module (I used jsonudf.dll on Windows)

 Then you can create the functions using this name as the soname parameter.

 There are some restrictions when using the UDF’s this way:

 * The connect\_json\_grp\_size variable cannot be accessed. The group size is set to 100.
* In case of error, warnings are replaced by messages sent to stderr.
* No trace.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/json-sample-files/>

Specifying Which Plugins to Build
=================================

    By default all plugins are enabled and built as dynamic `.so` (or `.dll`) modules. If a plugin does not support dynamic builds, it is not built at all.

 Use `PLUGIN_xxx` cmake variables. They can be set on the command line with `-DPLUGIN_xxx=*value*` or in the cmake gui. Supported values are

 


| Value | Effect |
| --- | --- |
| **NO** | the plugin will be not compiled at all |
| **STATIC** | the plugin will be compiled statically, if supported. Otherwise it will be not compiled. |
| **DYNAMIC** | the plugin will be compiled dynamically, if supported. Otherwise it will be not compiled. This is the default behavior. |
| **AUTO** | the plugin will be compiled statically, if supported. Otherwise it will be compiled dynamically. |
| **YES** | same as **AUTO**, but if plugin prerequisites (for example, specific libraries) are missing, it will not be skipped, it will abort cmake with an error. |

 
Note that unlike autotools, cmake tries to configure and build incrementally. You can modify one configuration option and cmake will only rebuild the part of the tree affected by it. For example, when you do `cmake -DWITH_EMBEDDED_SERVER=1` in the already-built tree, it will make libmysqld to be built, but no other configuration options will be changed or reset to their default values.

 In particular this means that if you have run, for example `cmake -DPLUGIN_OQGRAPH=NO` and later you want to restore the default behavior (with OQGraph being built) in the same build tree, you would need to run `cmake -DPLUGIN_OQGRAPH=DYNAMIC`

 Alternatively, you might simply delete the `CMakeCache.txt` file — this is the file where cmake stores current build configuration — and rebuild everything from scratch.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/specifying-which-plugins-to-build/>

CONNECT - Making the GetRest Library
====================================

    To enable the REST feature with binary distributions of MariaDB, the function calling the cpprestsdk package is not included in CONNECT, thus allowing CONNECT normal operation when the cpprestsdk package is not installed. Therefore, it must be compiled separately as a library (so or dll) that will be loaded by CONNECT when needed.

 This library will contain only one file shown here:

 
```
/************* Restget C++ Program Source Code File (.CPP) *************/
/* Adapted from the sample program of the Casablanca tutorial.         */
/* Copyright Olivier Bertrand 2019.                                    */
/***********************************************************************/
#include <cpprest/filestream.h>
#include <cpprest/http_client.h>

using namespace utility::conversions; // String conversions utilities
using namespace web;                  // Common features like URIs.
using namespace web::http;            // Common HTTP functionality
using namespace web::http::client;    // HTTP client features
using namespace concurrency::streams; // Asynchronous streams

typedef const char* PCSZ;

extern "C" int restGetFile(char* m, bool xt, PCSZ http, PCSZ uri, PCSZ fn);

/***********************************************************************/
/*  Make a local copy of the requested file.                           */
/***********************************************************************/
int restGetFile(char *m, bool xt, PCSZ http, PCSZ uri, PCSZ fn)
{
  int  rc = 0;
  auto fileStream = std::make_shared<ostream>();

  if (!http || !fn) {
		strcpy(m, "Missing http or filename");
		return 2;
  } // endif

	if (xt)
		fprintf(stderr, "restGetFile: fn=%s\n", fn);

  // Open stream to output file.
  pplx::task<void> requestTask = fstream::open_ostream(to_string_t(fn))
    .then([=](ostream outFile) {
      *fileStream= outFile;

			if (xt)
				fprintf(stderr, "Outfile isopen=%d\n", outFile.is_open());

      // Create http_client to send the request.
      http_client client(to_string_t(http));

      if (uri) {
        // Build request URI and start the request.
        uri_builder builder(to_string_t(uri));
        return client.request(methods::GET, builder.to_string());
      } else
        return client.request(methods::GET);
    })

    // Handle response headers arriving.
    .then([=](http_response response) {
			if (xt)
				fprintf(stderr, "Received response status code:%u\n",
                                  response.status_code());

      // Write response body into the file.
      return response.body().read_to_end(fileStream->streambuf());
    })

    // Close the file stream.
    .then([=](size_t n) {
			if (xt)
				fprintf(stderr, "Return size=%zu\n", n);

      return fileStream->close();
    });

  // Wait for all the outstanding I/O to complete and handle any exceptions
  try {
		if (xt)
			fprintf(stderr, "Waiting\n");

		requestTask.wait();
  } catch (const std::exception &e) {
		if (xt)
			fprintf(stderr, "Error exception: %s\n", e.what());

		sprintf(m, "Error exception: %s", e.what());
		rc= 1;
  } // end try/catch

	if (xt)
		fprintf(stderr, "restget done: rc=%d\n", rc);

  return rc;
} // end of restGetFile

```

This file exists in the source of CONNECT as `restget.cpp`. If you have no access to the source, use your favorite editor to make it by copy/pasting from the above.

 Then, on Linux, compile the GetRest.so library:

 
```
g++ -o GetRest.so -O3 -Wall -std=c++11 -fPIC -shared restget.cpp -lcpprest

```

Note: You can replace `-O3` by `-g` to make a debug version.

 This library should be placed where it can be accessed. A good place is the directory where the `libcpprest.so` is, for instance `/usr/lib64`. You can move or copy it there.

 On windows, using Visual Studio, make an empty win32 dll project named GetRest and add it the above file. Also add it the module definition file `restget.def`:

 
```
LIBRARY REST
EXPORTS
   restGetFile     @1

```

Important: This file must be specified in the property linker input page.

 Once compiled, the release or debug versions can be copied in the `cpprestsdk` corresponding directories, bin or debug\bin.

 That is all. It is a once-off job. Once done, it will work with all new MariaDB versions featuring CONNECT version 1.07.

 Note: the xt tracing variable is true when connect\_xtrace setting includes the value “MONGO” (512).

 
Caution: If your server crashes when using this feature, this is likely because the GetRest lib is linked to the wrong cpprestsdk lib (this may only apply on Windows)

 A Release version of GetRest must be linked to the release version of the cpprestsdk lib (cpprest\_2\_10.dll) but if you make a Debug version of GetRest, make sure it is linked to the Debug version of cpprestsdk lib (cpprest\_2\_10d.dll)

 This may be automatic if you use Visual Studio to make the GetRest.dll.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-making-the-getrest-library/>

CONNECT - Adding the REST Feature as a Library Called by an OEM Table
=====================================================================

    If you are using a version of MariaDB that does not support REST, this is how the REST feature can be added as a library called by an OEM table. 

 Before making the REST OEM module, the Microsoft Casablanca package must be installed as for compiling MariaDB from source.

 Even if this module is to be used with a binary distribution, you need some CONNECT source files in order to successfully make it. It is made with four files existing in the version 1.06.0010 of CONNECT: tabrest.cpp, restget.cpp, tabrest.h and mini-global.h. It also needs the CONNECT header files that are included in tabrest.cpp and the ones they can include. This can be obtained by going to a recent download site of a version of MariaDB that includes the REST feature, downloading the MariaDB source file tar.gz and extracting from it the CONNECT sources files in a directory that will be added to the additional source directories if it is not the directory containing the above files.

 On Windows, use a recent version of Visual Studio. Make a new empty DLL project and add the source files tabrest.cpp and restget.cpp. Visual studio should automatically generate all necessary connections to the cpprest SDK. Just edit the properties of the project to add the additional include directory (the one where the CONNECT source was downloaded) et the link to the ha\_connect.lib of the binary version of MariaDB (in the same directory than ha\_connect.dll in your binary distribution). Add the preprocessor definition XML\_SUPPORT. Also set in the linker input page of the project property the Module definition File to the rest.def file (with its full path) also existing in the CONNECT source files. If you are making a debug configuration, make sure that in the C/C++ Code generation page the Runtime library line specifies Multi-threaded Debug DLL (/MDd) or your server will crash when using the feature.

 This is not really simple but it is nothing compared with Linux! Someone having made an OEM module for its own application have written:

 For whatever reason, g++ / ld on Linux are both extremely picky about what they will and won't consider a \*"library"\* for linking purposes. In order to get them to recognize and therefore find `ha\_connect.so` as a "valid" linkable library, `ha\_connect.so` must exist in a directory whose path is in `/etc/ld.so.conf` or `/etc/ld.so.conf.d/ha\_connect.conf` \*AND\* its filename must begin with "lib".

 On Fedora, you can make a link to ha\_connect.so by:

 
```
$ sudo ln -s /..path to../ha_connect.so /usr/lib64/libconnect.so

```

This provides a library whose name begins with “lib”. It was made in /usr/lib64/ because it was the directory of the libcpprest.so Casablanca library. This solved the need of a file in /etc/ld.so.conf.d as this was already done for the cpprest library. Note that the -s parameter is a must, without it all sort of nasty errors are met when using the feature.

 Then compile and install the OEM module with:

 
```
$ makdir oem
$ cd oem
$ makedir Release
$ make -f oemrest.mak
$ sudo cp rest.so /usr/local/mysql/lib/plugin

```

The oemrest.mak file:

 
```
#LINUX
CPP = g++
LD = g++
OD = ./Release/
SD = /home/olivier/MariaDB/server/storage/connect/
CD =/usr/lib64
# flags to compile object files that can be used in a dynamic library
CFLAGS= -Wall -c -O3 -std=c++11 -fPIC -fno-rtti -I$(SD) -DXML_SUPPORT
# Replace -03 by -g for debug
LDFLAGS = -L$(CD) -lcpprest -lconnect

# Flags to create a dynamic library.
DYNLINKFLAGS = -shared
# on some platforms, use '-G' instead.

# REST library's archive file
OEMREST = rest.so

SRCS_CPP = $(SD)tabrest.cpp $(SD)restget.cpp
OBJS_CPP = $(OD)tabrest.o $(OD)restget.o

# top-level rule
all: $(OEMREST)

$(OEMREST): $(OBJS_CPP)
  $(LD) $(OBJS_CPP) $(LDFLAGS) $(DYNLINKFLAGS) -o $@

#CPP Source files
$(OD)tabrest.o:   $(SD)tabrest.cpp   $(SD)mini-global.h $(SD)global.h $(SD)plgdbsem.h $(SD)xtable.h $(SD)filamtxt.h $(SD)plgxml.h $(SD)tabdos.h  $(SD)tabfmt.h $(SD)tabjson.h $(SD)tabrest.h $(SD)tabxml.h
  $(CPP) $(CFLAGS) -o $@ $(SD)$(*F).cpp
$(OD)restget.o:   $(SD)restget.cpp   $(SD)mini-global.h $(SD)global.h
  $(CPP) $(CFLAGS) -o $@ $(SD)$(*F).cpp

# clean everything
clean:
  $(RM) $(OBJS_CPP) $(OEMREST)

```

The SD and CD variables are the directories of the CONNECT source files and the one containing the libcpprest.so lib. They can be edited to match those on your machine OD is the directory that was made to contain the object files.

 A very important flag is -fno-rtti. Without it you would be in big trouble.

 The resulting module, for instance rest.so or rest.dll, must be placed in the plugin directory of the MariaDB server. Then, you will be able to use NoSQL tables simply replacing in the CREATE TABLE statement the TABLE\_TYPE option =JSON or XML by TABLE\_TYPE=OEM SUBTYPE=REST MODULE=’rest.(so|dll)’. Actually, the module name, here supposedly ‘rest’, can be anything you like.

 The file type is JSON by default. If not, it must be specified like this:

 
```
OPTION_LIST=’Ftype=XML’

```

To be added to the create table statement. For instance:

 
```
CREATE  TABLE webw
ENGINE=CONNECT TABLE_TYPE=OEM MODULE='Rest.dll' SUBTYPE=REST
FILE_NAME='weatherdata.xml'
HTTP='https://samples.openweathermap.org/data/2.5/forecast?q=London,us&mode=xml&appid=b6907d289e10d714a6e88b30761fae22'
OPTION_LIST='Ftype=XML,Depth=3,Rownode=weatherdata';

```

Note: this last example returns an XML file whose format was not recognized by old CONNECT versions. It is here the reason of the option ‘Rownode=weatherdata’.

 If you have trouble making the module, you can post an issue on [JIRA](../jira/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-adding-the-rest-feature-as-a-library-called-by-an-oem-table/>

USING CONNECT - Offline Documentation
=====================================

    
Note: You can download a [PDF version of the CONNECT documentation](https://mariadb.com/kb/en/connect-table-types/+attachment/connect_1_7_03) (1.7.0003).

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-connect-offline-documentation/>

Event Limitations
=================

    The following restrictions apply to [Events](../stored-programs-and-views-events/index).

 * All of the restrictions listed in [Stored Routine Limitations](../stored-routine-limitations/index).
* Events cannot return a resultset.
* Event names are case insensitive, so it's not possible to define two events in the same database if their case insensitive names will match. This restriction has applied since MariaDB/MySQL 5.1.8. If you are upgrading from an older version of MySQL, and have events that could clash, these events need to be renamed before the upgrade.
* Events do not support dates beyond the maximum that can be represented in the Unix epoch (2038-01-19).
* Events cannot be created, dropped or altered by another stored program, trigger or event.
* Events cannot create, drop or alter stored programs or triggers
* Event timings cannot be strictly predicted. The intervals MONTH, YEAR\_MONTH, QUARTER and YEAR are all resolved in months. All others are resolved in seconds. A delay of up to two seconds is possible in extreme cases, and events scheduled to run at the same second cannot be executed in a given order. The `LAST_EXECUTED` column in the `[INFORMATION\_SCHEMA.EVENTS](../information-schema-events-table/index)` table will however always be accurate to within a second.
* A new connection is used for each execution of statements within the body of an event, so the session counts for [server status variables](../server-status-variables/index) such as Com\_delete and Com\_select will not reflect these.
* Because the Event Scheduler depends on grant tables for its functionality, it is automatically disabled when the server is running with [`--skip-grant-tables`](../mariadbd-options/index#-skip-grant-tables).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/event-limitations/>

CONNECT - Compiling JSON UDFs in a Separate Library
===================================================

    Although the JSON UDFs can be nicely included in the CONNECT library module, there are cases when you may need to have them in a separate library.

 This is when CONNECT is compiled embedded, or if you want to test or use these UDFs with other MariaDB versions not including them.

 To make it, you need to have access to the most recent MariaDB source code. Then, make a project containing these files:

 1. jsonudf.cpp
2. json.cpp
3. value.cpp
4. osutil.c
5. plugutil.cpp
6. maputil.cpp
7. jsonutil.cpp

 `jsonutil.cpp` is not distributed with the source code, you will have to make it from the following:

 
```
#include "my_global.h"
#include "mysqld.h"
#include "plugin.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

#include "global.h"

extern "C" int GetTraceValue(void) { return 0; }
uint GetJsonGrpSize(void) { return 100; }

/***********************************************************************/
/*  These replace missing function of the (not used) DTVAL class.      */
/***********************************************************************/
typedef struct _datpar   *PDTP;
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int) { return NULL; }
int ExtractDate(char*, PDTP, int, int val[6]) { return 0; }


#ifdef __WIN__
my_bool CloseFileHandle(HANDLE h)
{
	return !CloseHandle(h);
} /* end of CloseFileHandle */

#else  /* UNIX */
my_bool CloseFileHandle(HANDLE h)
{
	return (close(h)) ? TRUE : FALSE;
}  /* end of CloseFileHandle */

int GetLastError()
{
	return errno;
}  /* end of GetLastError */

#endif  // UNIX

/***********************************************************************/
/*  Program for sub-allocating one item in a storage area.             */
/*  Note: This function is equivalent to PlugSubAlloc except that in   */
/*  case of insufficient memory, it returns NULL instead of doing a    */
/*  long jump. The caller must test the return value for error.        */
/***********************************************************************/
void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
{
  PPOOLHEADER pph;                        // Points on area header.

  if (!memp)  	//  Allocation is to be done in the Sarea
    memp = g->Sarea;

  size = ((size + 7) / 8) * 8;  /* Round up size to multiple of 8 */
  pph = (PPOOLHEADER)memp;

  if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
    sprintf(g->Message,
     "Not enough memory in Work area for request of %d (used=%d free=%d)",
			(int)size, pph->To_Free, pph->FreeBlk);
    return NULL;
  } // endif size

  // Do the suballocation the simplest way
  memp = MakePtr(memp, pph->To_Free);   // Points to sub_allocated block
  pph->To_Free += size;                 // New offset of pool free block
  pph->FreeBlk -= size;                 // New size   of pool free block

  return (memp);
} // end of PlgDBSubAlloc

```

You can create the file by copy/paste from the above.

 Set all the additional include directories to the MariaDB include directories used in plugin compiling plus the reference of the storage/connect directories, and compile like any other UDF giving any name to the made library module (I used `jsonudf.dll` on Windows).

 Then you can create the functions using this name as the soname parameter.

 There are some restrictions when using the UDFs this way:

 * The [connect\_json\_grp\_size](../connect-system-variables/index#connect_json_grp_size) variable cannot be accessed. The group size is set and retrieved using the [jsonset\_grp\_size](../connect-json-table-type/index#jsonset_grp_size) and [jsonget\_grp\_size](../connect-json-table-type/index#jsonget_grp_size) functions (previously 100).
* In case of error, warnings are replaced by messages sent to stderr.
* No trace.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-compiling-json-udfs-in-a-separate-library/>

Authentication Plugin - ed25519
===============================

    MySQL has used SHA-1 based authentication since version 4.1. Since [MariaDB 5.2](../what-is-mariadb-52/index) this authentication plugin has been called [mysql\_native\_password](../authentication-plugin-mysql_native_password/index). Over the years as computers became faster, new attacks on SHA-1 were being developed. Nowadays SHA-1 is no longer considered as secure as it was in 2001. That's why the `ed25519` authentication plugin was created.

 The `ed25519` authentication plugin uses [Elliptic Curve Digital Signature Algorithm (ECDSA)](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) to securely store users' passwords and to authenticate users. The [ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519) algorithm is the same one that is [used by OpenSSH](https://www.openssh.com/txt/release-6.5). It is based on the elliptic curve and code created by [Daniel J. Bernstein](https://en.wikipedia.org/wiki/Daniel_J._Bernstein).

 From a user's perspective, the `ed25519` authentication plugin still provides conventional password-based authentication.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default as `auth_ed25519.so` or `auth_ed25519.dll` depending on the operating system, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'auth_ed25519';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = auth_ed25519

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'auth_ed25519';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Creating Users
--------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you can create a user account by executing the [CREATE USER](../create-user/index) statement and providing the [IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin) clause followied by the the name of the plugin, which is `ed25519`, and providing the the `USING` clause followed by the [PASSWORD()](../password/index) function with the plain-text password as an argument. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('secret');

```

If [SQL\_MODE](../sql-mode/index) does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via [GRANT](../grant/index). For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('secret');

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, the [PASSWORD()](../password/index) function and [SET PASSWORD](../set-password/index) statement did not work with the `ed25519` authentication plugin. Instead, you would have to use the [UDF](../user-defined-functions/index) that comes with the authentication plugin to calculate the password hash. For example:

 
```
CREATE FUNCTION ed25519_password RETURNS STRING SONAME "auth_ed25519.so";

```

Now you can calculate a password hash by executing:

 
```
SELECT ed25519_password("secret");
+---------------------------------------------+
| SELECT ed25519_password("secret");          |
+---------------------------------------------+
| ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY |
+---------------------------------------------+

```

Now you can use it to create the user account using the new password hash.

 To create a user account via [CREATE USER](../create-user/index), specify the name of the plugin in the [IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin) clause while providing the password hash as the `USING` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA ed25519 
  USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';

```

If [SQL\_MODE](../sql-mode/index) does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via [GRANT](../grant/index). For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA ed25519 
  USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';

```


Note that users require a password in order to be able to connect. It is possible to create a user without specifying a password, but they will be unable to connect.

 Changing User Passwords
-----------------------

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, you can change a user account's password by executing the [SET PASSWORD](../set-password/index) statement followed by the [PASSWORD()](../password/index) function and providing the plain-text password as an argument. For example:

 
```
SET PASSWORD =  PASSWORD('new_secret')

```

You can also change the user account's password with the [ALTER USER](../alter-user/index) statement. You would have to specify the name of the plugin in the [IDENTIFIED VIA](../alter-user/index#identified-viawith-authentication_plugin) clause while providing the plain-text password as an argument to the [PASSWORD()](../password/index) function in the `USING` clause. For example:

 
```
ALTER USER username@hostname IDENTIFIED VIA ed25519 USING PASSWORD('new_secret');

```



**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, the [PASSWORD()](../password/index) function and [SET PASSWORD](../set-password/index) statement did not work with the `ed25519` authentication plugin. Instead, you would have to use the [UDF](../user-defined-functions/index) that comes with the authentication plugin to calculate the password hash. For example:

 
```
CREATE FUNCTION ed25519_password RETURNS STRING SONAME "auth_ed25519.so";

```

Now you can calculate a password hash by executing:

 
```
SELECT ed25519_password("secret");
+---------------------------------------------+
| SELECT ed25519_password("secret");          |
+---------------------------------------------+
| ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY |
+---------------------------------------------+

```

Now you can change the user account's password using the new password hash.

 You can change the user account's password with the [ALTER USER](../alter-user/index) statement. You would have to specify the name of the plugin in the [IDENTIFIED VIA](../alter-user/index#identified-viawith-authentication_plugin) clause while providing the password hash as the `USING` clause. For example:

 
```
ALTER USER username@hostname IDENTIFIED VIA ed25519 
  USING 'ZIgUREUg5PVgQ6LskhXmO+eZLS0nC8be6HPjYWR4YJY';

```


Client Authentication Plugins
-----------------------------

 For clients that use the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries, MariaDB provides one client authentication plugin that is compatible with the `ed25519` authentication plugin:

 * `client_ed25519`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `ed25519` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mysql --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```

### `client_ed25519`

 The `client_ed25519` client authentication plugin hashes and signs the password using the [Elliptic Curve Digital Signature Algorithm (ECDSA)](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) before sending it to the server.

 Support in Client Libraries
---------------------------

 ### Using the Plugin with MariaDB Connector/C

 [MariaDB Connector/C](../mariadb-connector-c/index) supports `ed25519` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section since MariaDB Connector/C 3.1.0.

 ### Using the Plugin with MariaDB Connector/ODBC

 [MariaDB Connector/ODBC](../mariadb-connector-odbc/index) supports `ed25519` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section since MariaDB Connector/ODBC 3.1.2.

 ### Using the Plugin with MariaDB Connector/J

 [MariaDB Connector/J](../mariadb-connector-j/index) supports `ed25519` authentication since MariaDB Connector/J 2.2.1.

 ### Using the Plugin with MariaDB Connector/Node.js

 [MariaDB Connector/Node.js](../nodejs-connector/index) supports `ed25519` authentication since MariaDB Connector/Node.js 2.1.0.

 ### Using the Plugin with MySqlConnector for .NET

 [MySqlConnector for ADO.NET](../mysqlconnector-for-adonet/index) supports `ed25519` authentication since MySqlConnector 0.56.0.

 The connector implemented support for this authentication plugin in a separate [NuGet](https://docs.microsoft.com/en-us/nuget/what-is-nuget) package called [MySqlConnector.Authentication.Ed25519](https://www.nuget.org/packages/MySqlConnector.Authentication.Ed25519/). After the package is installed, your application must call `Ed25519AuthenticationPlugin.Install` to enable it.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.1 | Stable | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) |
| 1.0 | Stable | [MariaDB 10.3.8](https://mariadb.com/kb/en/mariadb-1038-release-notes/), [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/), [MariaDB 10.1.35](https://mariadb.com/kb/en/mariadb-10135-release-notes/) |
| 1.0 | Beta | [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/), [MariaDB 10.1.22](https://mariadb.com/kb/en/mariadb-10122-release-notes/) |

 
Options
-------

 ### `ed25519`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--ed25519=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-ed25519/>

TokuDB Resources
================

    
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

 
 This page contains links to various online resources for [TokuDB](../tokudb/index).

 Website
-------

 Tokutek was the primary developer of TokuDB before being acquired by Percona. [Their website](https://www.percona.com/software/mysql-database/percona-tokudb).

 Percona's TokuDB Documentation
------------------------------

 * [TokuDB Documentation](https://www.percona.com/doc/percona-tokudb/index.html)

 Mailing Lists
-------------

 There were two TokuDB specific mailing lists run by Tokutek:

 * [tokudb-user](https://groups.google.com/forum/#!forum/tokudb-user) - a mailing list for users of TokuDB
* [tokudb-dev](https://groups.google.com/forum/#!forum/tokudb-dev) - a mailing list TokuDB contributors

 These were discontinued and redirected to [Percona's MySQL and MariaDB forum](https://forums.percona.com/categories/mysql-mariadb).

 IRC
---

 Tokutek has a  `#tokutek` [IRC](../irc/index) channel on [Freenode](http://freenode.net).

 The following link will take you to the  `#tokutek` channel using Freenode's web IRC client: 

 * <http://webchat.freenode.net/?randomnick=1&channels=tokutek&prompt=1>

 See Also
--------

 The [Where to find other MariaDB users and developers](../where-to-find-other-mariadb-users-and-developers/index) page has many great MariaDB resources listed.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tokudb-resources/>

List of Plugins
===============

    MariaDB Plugin Maturity
-----------------------

 The following table lists the various plugins included in MariaDB ordered by their maturity. Note that maturity will differ across MariaDB versions - see below for an easy way to get a complete list of plugins and their maturity in your version of MariaDB:

 


| Plugin | Version | Maturity | Version |
| --- | --- | --- | --- |
| [Archive](../archive/index) | 3.0 | Stable |  |
| [Aria](../aria-formerly-known-as-maria/index) | 1.5 | Stable |  |
| [Audit Plugin](../about-the-mariadb-audit-plugin/index) | 1.4 | Stable |  |
| [aws\_key\_management](../aws-key-management-encryption-plugin/index) | 1.0 | Stable |  |
| [binlog](../binary-log/index) | 1.0 | Stable |  |
| [Blackhole](../blackhole/index) | 1.0 | Stable |  |
| [Connect](../connect/index) | 1.7 | Stable | [MariaDB 10.4.12](https://mariadb.com/kb/en/mariadb-10412-release-notes/), [MariaDB 10.3.22](https://mariadb.com/kb/en/mariadb-10322-release-notes/) |
| [CLIENT\_STATISTICS](../user-statistics/index) | 2.0 | Stable |  |
| [cracklib\_password\_check](../cracklib_password_check/index) | 1.0 | Stable |  |
| [CSV](../csv/index) | 1.0 | Stable |  |
| [DISKS](../disks-plugin/index) | 1.1 | Stable | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) |
| [ed25519](../ed25519-authentication-plugin/index) | 1.1 | Stable | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) |
| [FederatedX](../federatedx-storage-engine/index)[[1](#_note-0)] | 2.1 | Stable |  |
| [Feedback](../feedback-plugin/index) | 1.1 | Stable |  |
| [file\_key\_management](../file-key-management-encryption-plugin/index) | 1.0 | Stable |
| [gssapi](../gssapi-authentication-plugin/index) | 1.0 | Stable |  |
| [INDEX\_STATISTICS](../user-statistics/index) | 2.0 | Stable |  |
| [INET6](../inet6/index) | 1.0 | Stable | [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10512-release-notes/) |
| [InnoDB](../xtradb-and-innodb/index) | 10.\* | Stable |  |
| [LOCALES](../locales-plugin/index) | 1.0 | Stable |  |
| [Memory](../memory-storage-engine/index) | 1.0 | Stable |  |
| [METADATA\_LOCK\_INFO](../metadata_lock_info/index) | 0.1 | Stable |  |
| [MRG\_MyISAM](../merge/index) | 1.0 | Stable |  |
| [Mroonga](../mroonga/index) | 7.7 | Stable |  |
| [MyISAM](../myisam-storage-engine/index) | 1.0 | Stable |  |
| [MyRocks](../myrocks/index) | 1.0 | Stable | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| [mysql\_json](../mysql_json/index) | 0.1 | Stable | [MariaDB 10.5.17](https://mariadb.com/kb/en/mariadb-10517-release-notes/) |
| [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) | 1.0 | Stable |  |
| [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) | 1.0 | Stable |  |
| [named\_pipe](../named_pipe-authentication-plugin/index) | 1.0 | Stable |  |
| [pam](../pam-authentication-plugin/index) | 1.0 | Stable |  |
| [password\_reuse\_check](../password_reuse_check-plugin/index) | 2.0 | Stable | [MariaDB 10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [MariaDB 10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [MariaDB 10.10.2](https://mariadb.com/kb/en/mariadb-10-10-2-release-notes/) |
| partition | 1.0 | Stable |  |
| [Performance\_Schema](../performance-schema/index) | 0.1 | Stable |  |
| [QUERY\_CACHE\_INFO](../query_cache_info-plugin/index) | 1.1 | Stable |  |
| [query\_response\_time](../query_response_time-plugin/index) | 1.0 | Stable |  |
| [S3](../s3-storage-engine/index) | 1.0 | Stable | [MariaDB 10.5.12](https://mariadb.com/kb/en/mariadb-10512-release-notes/) |
| [semisync](../semisynchronous-replication/index) | 1.0 | Stable | Built-in, no longer a plugin from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Sequence](../sequence/index) | 1.0 | Stable |  |
| [SERVER\_AUDIT](../mariadb-audit-plugin/index) | 1.4 | Stable |  |
| [simple\_password\_check](../simple_password_check/index) | 1.0 | Stable |  |
| [Spider](../spider/index) | 3.3 | Stable | <= [MariaDB 10.4](../what-is-mariadb-104/index), [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) |
| [SQL\_ERROR\_LOG](../sql_error_log-plugin/index) | 1.0 | Stable |  |
| [TABLE\_STATISTICS](../user-statistics/index) | 2.0 | Stable |  |
| [USER\_STATISTICS](../user-statistics/index) | 2.0 | Stable |  |
| [user\_variables](../user-variables-plugin/index) | 1.0 | Stable | [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) |
| [TokuDB](../tokudb/index) | 4.0 | Stable | Disabled in [MariaDB 10.5](../what-is-mariadb-105/index) and removed in [MariaDB 10.6](../what-is-mariadb-106/index) |
| [unix\_socket](../unix_socket-authentication-plugin/index) | 1.0 | Stable |  |
| [UUID](../uuid-data-type/index) | 1.0 | Stable | [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/) |
| [wsrep](../galera/index) | 1.0 | Stable |  |
| [WSREP\_INFO](../wsrep_info-plugin/index) | 1.0 | Stable |  |
| Plugin | Version | Maturity | From |
| [Federated](../federated-storage-engine/index)[[2](#_note-1)] | 1.0 | Gamma |  |
| [OQGraph](../oqgraph-storage-engine/index) | 3.0 | Gamma |  |
| [Sphinx](../sphinx-storage-engine/index) | 2.0 | Gamma |  |
| Plugin | Version | Maturity | From |
| [Columnstore](../mariadb-columnstore/index) | 1.0 | Beta | [MariaDB 10.5.4](https://mariadb.com/kb/en/mariadb-1054-release-notes/) |
| [handlersocket](../handlersocket/index) | 1.0 | Beta |  |
| Plugin | Version | Maturity | From |
| [Cassandra](../cassandra/index) | 0.1 | Experimental | Removed in [MariaDB 10.6](../what-is-mariadb-106/index) |
| [debug\_key\_management](../encryption-plugins/index) | 1.0 | Experimental |  |
| [example\_key\_management](../encryption-plugins/index) | 1.0 | Experimental |  |
| Plugin | Version | Maturity | Version |

 
Execute the following on your MariaDB server to get a complete list of plugins and their maturity for your version of MariaDB:

 
```
SELECT plugin_name, plugin_version, plugin_maturity
FROM information_schema.plugins
ORDER BY plugin_name;

```

See Also
--------

 * [Plugin Overview](../plugin-overview/index)
* [INSTALL PLUGIN](../install-plugin/index)
* [INFORMATION\_SCHEMA.PLUGINS Table](../plugins-table-information-schema/index)
* [mysql\_plugin](../mysql_plugin/index)
* [SHOW PLUGINS](../show-plugins/index)
* [INSTALL SONAME](../install-soname/index)
* [UNINSTALL PLUGIN](../uninstall-plugin/index)
* [UNINSTALL SONAME](../uninstall-soname/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/list-of-plugins/>

Writing Plugins for MariaDB
===========================

    About
-----

 Generally speaking, writing plugins for MariaDB is very similar to writing plugins for MySQL.

 Authentication Plugins
----------------------

 See [Pluggable Authentication](../pluggable-authentication/index).

 Storage Engine Plugins
----------------------

 Storage engines can extend `CREATE TABLE` syntax with optional index, field, and table attribute clauses. See [Extending CREATE TABLE](../extending-create-table/index) for more information.

 See [Storage Engine Development](../storage-engines-storage-engine-development/index).

 Information Schema Plugins
--------------------------

 Information Schema plugins can have their own [FLUSH](../flush/index) and [SHOW](../show/index) statements. See [FLUSH and SHOW for Information Schema plugins](../information-schema-plugins-show-and-flush-statements/index).

 Encryption Plugins
------------------

 [Encryption plugins](../encryption-plugins/index) in MariaDB are used for the [data at rest encryption](../data-at-rest-encryption/index) feature. They are responsible for both key management and for the actual encryption and decryption of data.

 Plugin Declaration Structure
----------------------------

 The MariaDB plugin declaration differs from the MySQL plugin declaration in the following ways:

 1. it has no useless 'reserved' field (the very last field in the MySQL plugin declaration)
2. it has a 'maturity' declaration
3. it has a field for a text representation of the version field

 MariaDB can load plugins that only have the MySQL plugin declaration but both `PLUGIN_MATURITY` and `PLUGIN_AUTH_VERSION` will show up as 'Unknown' in the [INFORMATION\_SCHEMA.PLUGINS table](../information_schemaplugins-table/index).

 For compiled-in (not dynamically loaded) plugins, the presence of the MariaDB plugin declaration is mandatory.

 ### Example Plugin Declaration

 The MariaDB plugin declaration looks like this:

 
```
/* MariaDB plugin declaration */
maria_declare_plugin(example)
{
   MYSQL_STORAGE_ENGINE_PLUGIN, /* the plugin type (see include/mysql/plugin.h) */
   &example_storage_engine_info, /* pointer to type-specific plugin descriptor   */
   "EXAMPLEDB", /* plugin name */
   "John Smith",  /* plugin author */
   "Example of plugin interface", /* the plugin description */
   PLUGIN_LICENSE_GPL, /* the plugin license (see include/mysql/plugin.h) */
   example_init_func,   /* Pointer to plugin initialization function */
   example_deinit_func,  /* Pointer to plugin deinitialization function */
   0x0001 /* Numeric version 0xAABB means AA.BB version */,
   example_status_variables,  /* Status variables */
   example_system_variables,  /* System variables */
   "0.1 example",  /* String version representation */
   MariaDB_PLUGIN_MATURITY_EXPERIMENTAL /* Maturity (see include/mysql/plugin.h)*/
}
maria_declare_plugin_end;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/development-writing-plugins-for-mariadb/>

Authentication Plugin - Named Pipe
==================================

    The `named_pipe` authentication plugin allows the user to use operating system credentials when connecting to MariaDB via named pipe on Windows. Named pipe connections are enabled by the `[named\_pipe](../server-system-variables/index#named_pipe)` system variable.

 The `named_pipe` authentication plugin works by using [named pipe impersonation](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378618%28v=vs.85%29.aspx) and calling `GetUserName()` to retrieve the user name of the process that is connected to the named pipe. Once it has the user name, it authenticates the connecting user as the MariaDB account that has the same user name.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing `[INSTALL SONAME](../install-soname/index)` or `[INSTALL PLUGIN](../install-plugin/index)`. For example:

 
```
INSTALL SONAME 'auth_named_pipe';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = auth_named_pipe

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'auth_named_pipe';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Creating Users
--------------

 To create a user account via `[CREATE USER](../create-user/index)`, specify the name of the plugin in the `[IDENTIFIED VIA](../create-user/index#identified-viawith-authentication_plugin)` clause. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA named_pipe;

```

If `[SQL\_MODE](../sql-mode/index)` does not have `NO_AUTO_CREATE_USER` set, then you can also create the user account via `[GRANT](../grant/index)`. For example:

 
```
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA named_pipe;

```

Client Authentication Plugins
-----------------------------

 The `named_pipe` authentication plugin does not require any specific client authentication plugins. It should work with all clients.

 Support in Client Libraries
---------------------------

 The `named_pipe` authentication plugin does not require any special support in client libraries. It should work with all client libraries.

 Example
-------

 
```
CREATE USER wlad IDENTIFIED VIA named_pipe;
CREATE USER monty IDENTIFIED VIA named_pipe;
quit

C:\>echo %USERNAME%
wlad

C:\> mysql --user=wlad --protocol=PIPE
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.1.12-MariaDB-debug Source distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> quit
Bye

C:\> mysql --user=monty  --protocol=PIPE
ERROR 1698 (28000): Access denied for user 'monty'@'localhost'

```

In this example, a user `wlad` is already logged into the system. Because he has identified himself to the operating system, he does not need to do it again for the database — MariaDB trusts the operating system credentials. However, he cannot connect to the database as another user.

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/) |

 
Options
-------

 ### `named_pipe`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
	+ There may be ambiguity between this option and the `[named\_pipe](../server-system-variables/index#named_pipe)` system variable. See [MDEV-19625](https://jira.mariadb.org/browse/MDEV-19625) about that.
* **Commandline:** `--named-pipe=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`
* **Introduced:** [MariaDB 10.1.11](https://mariadb.com/kb/en/mariadb-10111-release-notes/)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-named-pipe/>

Authentication with Pluggable Authentication Modules (PAM)
===========================================================

  

| Title | Description |
| --- | --- |
|  [Authentication Plugin - PAM](../authentication-plugin-pam/index) |  Uses the Pluggable Authentication Module (PAM) framework to authenticate MariaDB users.  |
|  [User and Group Mapping with PAM](../user-and-group-mapping-with-pam/index) |  Configure PAM to map a given PAM user or group to a different MariaDB user.  |
|  [Configuring PAM Authentication and User Mapping with Unix Authentication](../configuring-pam-authentication-and-user-mapping-with-unix-authentication/index) |  Walkthrough configuration of PAM authentication and user mapping with Unix authentication.  |
|  [Configuring PAM Authentication and User Mapping with LDAP Authentication](../configuring-pam-authentication-and-user-mapping-with-ldap-authentication/index) |  Configuring PAM authentication and user mapping with LDAP authentication.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-with-pluggable-authentication-modules-pam/>

Authentication Plugin - SHA-256
===============================

    MySQL 5.6 added support for the `[sha256\_password](https://dev.mysql.com/doc/refman/5.6/en/sha256-pluggable-authentication.html)` authentication plugin, and MySQL 8.0 also added support for the `[caching\_sha2\_password](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html)` authentication plugin.

 The `caching_sha2_password` plugin is now the default authentication plugin in MySQL 8.0.4 and above, based on the value of the `[default\_authentication\_plugin](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin)` system variable.

 Support in MariaDB Server
-------------------------

 
MariaDB Server does not currently support either the `[sha256\_password](https://dev.mysql.com/doc/refman/5.6/en/sha256-pluggable-authentication.html)` or the `[caching\_sha2\_password](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html)` authentication plugins. See [MDEV-9804](https://jira.mariadb.org/browse/MDEV-9804) for more information.

 
MariaDB Server does not support either of these authentication plugins. This is mainly because:

 * To use the protocol, one has to distribute the server's public key to all MariaDB users, which can be cumbersome and impractical.
* The server gets the password in clear text which can cause problems if the user is convinced to connect to a malicious server.

 Client Authentication Plugins
-----------------------------

 For clients that use the [MariaDB Connector/C](../mariadb-connector-c/index) library, MariaDB provides two client authentication plugins that are compatible with MySQL's SHA-256 authentication plugins:

 * `sha256_password`
* `caching_sha256_password`

 When connecting with a [client or utility](../clients-utilities/index) to a server as a user account that authenticates with the `sha256_password` or `caching_sha256_password` authentication plugin, you may need to tell the client where to find the relevant client authentication plugin by specifying the `--plugin-dir` option. For example:

 
```
mysql --plugin-dir=/usr/local/mysql/lib64/mysql/plugin --user=alice

```

For clients that use MariaDB's `libmysqlclient` library instead of [MariaDB Connector/C](../mariadb-connector-c/index), these client authentication plugins are not supported.

 ### `sha256_password`

 The `sha256_password` client authentication plugin is compatible with MySQL's `[sha256\_password](https://dev.mysql.com/doc/refman/5.6/en/sha256-pluggable-authentication.html)` authentication plugin, which was added in MySQL 5.6.

 ### `caching_sha256_password`

 The `caching_sha256_password` client authentication plugin is compatible with MySQL's `[caching\_sha2\_password](https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html)` authentication plugin, which was added in MySQL 8.0.

 The `caching_sha2_password` plugin is now the default authentication plugin in MySQL 8.0.4 and above, based on the value of the `[default\_authentication\_plugin](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin)` system variable.

 Support in Client Libraries
---------------------------

 ### Using the Plugin with MariaDB Connector/C

 [MariaDB Connector/C](../mariadb-connector-c/index) supports `sha256_password` and `caching_sha2_password` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section.

 It has supported the `sha256_password` client authentication plugin since MariaDB Connector/C 3.0.2. See [CONC-229](https://jira.mariadb.org/browse/CONC-229) for more information.

 It has supported the `caching_sha256_password` client authentication plugin since MariaDB Connector/C 3.0.8 and MariaDB Connector/C 3.1.0. See [CONC-312](https://jira.mariadb.org/browse/CONC-312) for more information.

 ### Using the Plugin with MariaDB Connector/ODBC

 [MariaDB Connector/ODBC](../about-mariadb-connector-odbc/index) supports `sha256_password` and `caching_sha2_password` authentication using the [client authentication plugins](client-authentication-plugins) mentioned in the previous section.

 It has supported `sha256_password` and `caching_sha2_password` authentication since MariaDB Connector/ODBC 3.1.4. See [ODBC-241](https://jira.mariadb.org/browse/ODBC-241) for more information.

 ### Using the Plugin with MariaDB Connector/J

 [MariaDB Connector/J](../about-mariadb-connector-j/index) supports `sha256_password` and `caching_sha2_password` authentication since MariaDB Connector/J 2.5.0. See [CONJ-327](https://jira.mariadb.org/browse/CONJ-327) and [CONJ-663](https://jira.mariadb.org/browse/CONJ-663) for more information.

 ### Using the Plugin with MariaDB Connector/Node.js

 [MariaDB Connector/Node.js](../nodejs-connector/index) supports `sha256_password` and `caching_sha2_password` authentication since MariaDB Connector/Node.js 2.5.0. See [CONJS-76](https://jira.mariadb.org/browse/CONJS-76) and [CONJS-77](https://jira.mariadb.org/browse/CONJS-77) for more information.

 See Also
--------

 * [MDEV-9804](https://jira.mariadb.org/browse/MDEV-9804) contains the plans to use if we ever decide to support these protocols.
* [History of MySQL and MariaDB authentication protocols](https://mariadb.org/history-of-mysql-mariadb-authentication-protocols)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/authentication-plugin-sha-256/>

Why Encrypt MariaDB Data?
=========================

    Nearly everyone owns data of immense value: customer data, construction plans, recipes, product designs and other information. These data are stored in clear text on your storage media. Everyone with file system access is able to read and modify the data. If this data falls into the wrong hands (criminals or competitors) this may result in serious consequences.

 With encryption you protect Data At Rest (see the [Wikipedia article](http://en.wikipedia.org/wiki/Data_at_Rest)). That way, the database files are protected against unauthorized access.

 When Does Encryption Help to Protect Your Data?
-----------------------------------------------

 Encryption helps in case of threats against the database files:

 * An attacker gains access to the system and copies the database files to avoid the MariaDB authorization check.
* MariaDB is operated by a service provider who should not gain access to the sensitive data.

 When is Encryption No Help?
---------------------------

 Encryption provides no additional protection against threats caused by authorized database users. Specifically, SQL injections aren’t prevented.

 What to Encrypt?
----------------

 All data that is not supposed to fall into possible attackers hands should be encrypted. Especially information, subject to strict data protection regulations, is to be protected by encryption (e.g. in the healthcare sector: patient records). Additionally data being of interest for criminals should be protected. Data which should be encrypted are:

 * Personal related information
* Customer details
* Financial and credit card data
* Public authorities data
* Construction plans and research and development results

 How to Handle Key Management?
-----------------------------

 There are currently three options for key management:

 * [File Key Management Plugin](../file-key-management-encryption-plugin/index)
* [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index)
* [eperi Gateway for Databases](../encryption-key-management/index#eperi-gateway-for-databases)

 See [Encryption Key Management](../encryption-key-management/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/why-encrypt-mariadb-data/>

Encryption Key Management
=========================

    MariaDB's [data-at-rest encryption](../data-at-rest-encryption/index) requires the use of a key management and encryption plugin. These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of multiple encryption keys. Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports key rotation, then encryption keys can also be rotated, which creates a new version of the encryption key.

 Choosing an Encryption Key Management Solution
----------------------------------------------

 How MariaDB manages encryption keys depends on which encryption key management solution you choose. Currently, MariaDB has three options:

 ### File Key Management Plugin

 The File Key Management plugin that ships with MariaDB is a basic key management and encryption plugin that reads keys from a plain-text file. It can also serve as example and as a starting point when developing a key management plugin.

 For more information, see [File Key Management Plugin](../file-key-management-encryption-plugin/index).

 ### AWS Key Management Plugin

 The AWS Key Management plugin is a key management and encryption plugin that uses the Amazon Web Services (AWS) Key Management Service (KMS). The AWS Key Management plugin depends on the [AWS SDK for C++](https://github.com/aws/aws-sdk-cpp), which uses the [Apache License, Version 2.0](https://github.com/aws/aws-sdk-cpp/blob/master/LICENSE). This license is not compatible with MariaDB Server's [GPL 2.0 license](../mariadb-license/index), so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from source.

 For more information, see [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index).

 ### Eperi Key Management Plugin

 The Eperi Key Management plugin is a key management and encryption plugin that uses the [eperi Gateway for Databases](https://eperi.com/database-encryption/). The [eperi Gateway for Databases](https://eperi.com/database-encryption/) stores encryption keys on the key server outside of the database server itself, which provides an extra level of security. The [eperi Gateway for Databases](https://eperi.com/database-encryption/) also supports performing all data encryption operations on the key server as well, but this is optional.

 For more information, see [Eperi Key Management Plugin](../eperi-key-management-encryption-plugin/index).

 Using Multiple Encryption Keys
------------------------------

 Key management and encryption plugins support using multiple encryption keys. Each encryption key can be defined with a different 32-bit integer as a key identifier.

 The support for multiple keys opens up some potential use cases. For example, let's say that a hypothetical key management and encryption plugin is configured to provide two encryption keys. One encryption key might be intended for "low security" tables. It could use short keys, which might not be rotated, and data could be encrypted with a fast encryption algorithm. Another encryption key might be intended for "high security" tables. It could use long keys, which are rotated often, and data could be encrypted with a slower, but more secure encryption algorithm. The user would specify the identifier of the key that they want to use for different tables, only using high level security where it's needed.

 There are two encryption key identifiers that have special meanings in MariaDB. Encryption key `1` is intended for encrypting system data, such as InnoDB redo logs, binary logs, and so on. It must always exist when [data-at-rest encryption](../data-at-rest-encryption/index) is enabled. Encryption key `2` is intended for encrypting temporary data, such as temporary files and temporary tables. It is optional. If it doesn't exist, then MariaDB uses encryption key `1` for these purposes instead.

 When [encrypting InnoDB tables](../innodb-encryption/index), the key that is used to encrypt tables [can be changed](../innodb-xtradb-encryption-keys/index).

 When [encrypting Aria tables](../aria-encryption/index), the key that is used to encrypt tables [cannot currently be changed](../aria-encryption-keys/index).

 Key Rotation
------------

 Encryption key rotation is optional in MariaDB Server. Key rotation is only supported if the backend key management service (KMS) supports key rotation, and if the corresponding key management and encryption plugin for MariaDB also supports key rotation. When a key management and encryption plugin supports key rotation, users can opt to rotate one or more encryption keys, which creates a new version of each rotated encryption key.

 Key rotation allows users to improve data security in the following ways:

 * If the server is configured to automatically re-encrypt table data with the newer version of the encryption key after the key is rotated, then that prevents an encryption key from being used for long periods of time.
* If the server is configured to simultaneously encrypt table data with multiple versions of the encryption key after the key is rotated, then that prevents all data from being leaked if a single encryption key version is compromised.

 The [InnoDB storage engine](../innodb/index) has [background encryption threads](../innodb-background-encryption-threads/index) that can [automatically re-encrypt pages when key rotations occur](../innodb-background-encryption-threads/index#background-operations).

 The [Aria storage engine](../aria/index) does [not currently have a similar mechanism to re-encrypt pages in the background when key rotations occur](../aria-encryption-keys/index#key-rotation).

 ### Support for Key Rotation in Encryption Plugins

 #### Encryption Plugins with Key Rotation Support

 * The [AWS Key Management Service (KMS)](https://aws.amazon.com/kms/) supports encryption key rotation, and the corresponding [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index) also supports encryption key rotation.

 * The [eperi Gateway for Databases](https://eperi.com/database-encryption/) supports encryption key rotation, and the corresponding [Eperi Key Management Plugin](../eperi-key-management-encryption-plugin/index) also supports encryption key rotation.

 #### Encryption Plugins without Key Rotation Support

 * The [File Key Management Plugin](../file-key-management-encryption-plugin/index) does not support encryption key rotation, because it does not use a backend key management service (KMS).

 Encryption Plugin API
---------------------

 New key management and encryption plugins can be developed using the [encryption plugin API](../encryption-plugin-api/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encryption-key-management/>

Password Reuse Check Plugin
===========================

    
**MariaDB starting with [10.7](../what-is-mariadb-107/index)**`password_reuse_check` is a [password validation](../password-validation-plugin-api/index) plugin introduced in [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/).

  Description
-----------

 The plugin is used to prevent a user from reusing a password, which can be a requirement in some security policies. The [password\_reuse\_check\_interval](../password_reuse_check_interval/index) system variable determines the retention period, in days, for a password. By default this is zero, meaning unlimited retention. Old passwords are stored in the [mysql.password\_reuse\_check\_history table](../mysqlpassword_reuse_check_history-table/index).

 Note that passwords can be directly set as a hash, bypassing the password validation, if the [strict\_password\_validation](../server-system-variables/index#strict_password_validation) variable is `OFF` (it is `ON` by default).

 ### Installing the Plugin

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default.

 You can install the plugin dynamically, without restarting the server, by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'password_reuse_check';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = password_reuse_check

```

### Uninstalling the Plugin

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'password_reuse_check';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
INSTALL SONAME 'password_reuse_check';

GRANT SELECT ON *.* TO user1@localhost identified by 'pwd1';
Query OK, 0 rows affected (0.038 sec)

GRANT SELECT ON *.* TO user1@localhost identified by 'pwd1';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

GRANT SELECT ON *.* TO user1@localhost identified by 'pwd2';
Query OK, 0 rows affected (0.003 sec)

GRANT SELECT ON *.* TO user1@localhost identified by 'pwd1';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Alpha | [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/) |
| 1.0 | Beta | [MariaDB 10.7.2](https://mariadb.com/kb/en/mariadb-1072-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.7.4](https://mariadb.com/kb/en/mariadb-1074-release-notes/) |
| 2.0 | Stable | [MariaDB 10.7.7](https://mariadb.com/kb/en/mariadb-1077-release-notes/), [MariaDB 10.8.7](https://mariadb.com/kb/en/mariadb-10-8-7-release-notes/), [MariaDB 10.9.5](https://mariadb.com/kb/en/mariadb-10-9-5-release-notes/), [MariaDB 10.10.2](https://mariadb.com/kb/en/mariadb-10-10-2-release-notes/) |

 The bump to version 2.0 required the change of the stored format to mitigate an implementation weakness ([MDEV-28838](https://jira.mariadb.org/browse/MDEV-28838)) and as such the bump from 1.0 to 2.0 will invalidate previously saved password reuse protections.

 
See Also
--------

 * [Password Validation](../password-validation/index)
* [10.7 preview feature: Password Reuse Check plugin](https://mariadb.org/10-7-preview-feature-password-reuse-check-plugin/) (mariadb.org blog post)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/password-reuse-check-plugin/>

METADATA\_LOCK\_INFO Plugin
===========================

    The `METADATA_LOCK_INFO` plugin creates the [METADATA\_LOCK\_INFO](../information-schema-metadata_lock_info-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. This table shows active [metadata locks](../metadata-locking/index). The table will be empty if there are no active metadata locks.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'metadata_lock_info';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = metadata_lock_info

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'metadata_lock_info';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Examples
--------

 ### Viewing all Metadata Locks

 
```
SELECT * FROM information_schema.metadata_lock_info;  
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
| THREAD_ID | LOCK_MODE                | LOCK_DURATION | LOCK_TYPE            | TABLE_SCHEMA    | TABLE_NAME  |  
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Global read lock     |                 |             |  
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Commit lock          |                 |             |
|        31 | MDL_INTENTION_EXCLUSIVE  | MDL_EXPLICIT  | Schema metadata lock | dbname          |             |
|        31 | MDL_SHARED_NO_READ_WRITE | MDL_EXPLICIT  | Table metadata lock  | dbname          | exotics     |
+-----------+--------------------------+---------------+----------------------+-----------------+-------------+
4 rows in set (0.00 sec)

```

### Matching Metadata Locks with Threads and Queries

 
```
SELECT 
CONCAT('Thread ',P.ID,' executing "',P.INFO,'" IS LOCKED BY Thread ',
M.THREAD_ID) WhoLocksWho 
FROM INFORMATION_SCHEMA.PROCESSLIST P,
INFORMATION_SCHEMA.METADATA_LOCK_INFO M 
WHERE LOCATE(lcase(LOCK_TYPE), lcase(STATE))>0;
+-----------------------------------------------------------------------------------+
| WhoLocksWho                                                                       |
+-----------------------------------------------------------------------------------+
| Thread 3 executing "INSERT INTO foo ( b ) VALUES ( 'FOO' )" IS LOCKED BY Thread 2 |
+-----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

SHOW PROCESSLIST;
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
| Id | User | Host      | db   | Command | Time | State                        | Info                                   | Progress |
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
|  2 | root | localhost | test | Sleep   |  123 |                              | NULL                                   |    0.000 |
|  3 | root | localhost | test | Query   |  103 | Waiting for global read lock | INSERT INTO foo ( b ) VALUES ( 'FOO' ) |    0.000 |
|  4 | root | localhost | test | Query   |    0 | init                         | SHOW PROCESSLIST                       |    0.000 |
+----+------+-----------+------+---------+------+------------------------------+----------------------------------------+----------+
3 rows in set (0.00 sec)

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 0.1 | Stable | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 0.1 | Beta | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| 0.1 | Alpha | [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) |

 
Options
-------

 ### `metadata_lock_info`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--metadata-lock-info=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/metadata-lock-info-plugin/>

Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Advanced Usage
=======================================================================================

    This document assumes you've already set up an Amazon Web Services (AWS) account, created a master key in the Key Management Service (KMS), and have done the basic work to set up the MariaDB AWS KMS plugin. These steps are all described in [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide](../mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/index).

 Ultimately, keeping all the credentials required to read the key on a single host means that a user who has gained access to the host has enough information to read the encrypted files in the datadir, read the encrypted keys from the datadir, interact with AWS KMS to decrypt the encrypted keys, and then used the decrypted keys to decrypt the encrypted data.

 Theoretically, a superuser can read the memory of the MariaDB server process to read the decrypted keys or restart MariaDB with password authentication disabled in order to dump data, or add new users to MariaDB in order to allow a user to connect and dump the data. Resolving these issues is beyond the scope of this document. A user who gains root access to your operating system or root access to your MariaDB server will have the ability to decrypt your data. Plan accordingly.

 Managing AWS credentials
------------------------

 Putting the AWS credentials in a file inside the MariaDB home directory is not ideal. By default, any user with the FILE privilege can read any files that the MariaDB server has permission to read, which would include the credentials file. To protect against this, you should set `secure_file_priv` to restrict the location the server will allow a user to read from when executing `LOAD DATA INFILE` or the `LOAD_FILE()` function.

 But putting them in other locations requires passing additional data to the server, which in the case of CentOS 7 requires customizing the systemd startup procedure. This is most easily done by creating a "drop-in" file in /etc/systemd/system/mariadb.service.d/. The file should end in ".conf" but can otherwise be named whatever you like. After making any changes to systemd files, execute `systemctl daemon-reload` and then start (or restart) the service as usual.

 You can place the credentials file in a location of your choosing and then refer to that file by setting the `AWS_CREDENTIAL_PROFILES_FILE` environment variable in the drop-in file:

 
```
[Service]
Environment=AWS_CREDENTIAL_PROFILES_FILE=/etc/aws-kms-credentials

```

The credentials file will need to be readable by the "mysql" user, but it does not need to be readable by any other user.

 AWS credentials can also be put directly into a "drop-in" systemd file that will be read when starting the MariaDB service:

 
```
# cat /etc/systemd/system/mariadb.service.d/aws-kms.conf
[Service]
Environment=AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
Environment=AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV

```

However, any OS user can read this information from systemd, which could be considered a security risk. Another solution is to put the credentials in a separate file that is only readable by root and then refer to that file using an `EnvironmentFile` directive in a drop-in systemd file.

 
```
# cat /etc/systemd/system/mariadb.service.d/aws-kms.env
AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV

# chown root /etc/systemd/system/mariadb.service.d/aws-kms.env
# chmod 600 /etc/systemd/system/mariadb.service.d/aws-kms.env

# cat /etc/systemd/system/mariadb.service.d/aws-kms.conf
[Service]
EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env

```

That has the advantage the the credentials can only be read directly by root. systemd adds those variables to the environment of the MariaDB server when starting it, and MariaDB can use the credentials to interact with AWS. Note, though, that any process running as the "mysql" user can still read the credentials from the proc filesystem on Linux.

 
```
$ whoami
mysql
$ cat /proc/$(pgrep mysqld)/environ | tr '\0' '\n' | grep AWS
AWS_ACCESS_KEY_ID=AKIAIRSG2XYZATCJLZ4A
AWS_SECRET_ACCESS_KEY=ux91LZIxCp4ZXabcdefgIViQNtTan42QAmJqJVqV

```

AWS KMS Key Policy
------------------

 AWS KMS allows flexible, user-editable key policy. This offers fine-grained control over which users can operate on keys. The possibilities range from simply restricting which IP addresses are allowed to perform operations on the key, to requiring a MFA (Multi-Factor Authentication) device to use the key, to enforcing separation of responsibilities by creating an additional user with limited privileges to enable and disable the key. All 3 of these options will be outlined in this section.

 For more details about customizing the Key Policy for your master keys, please consult the [AWS Key Management Service Key Policy](http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-overview) documentation.

 ### Source IP restrictions

 A simple, common-sense restriction to put in place is to restrict the range of IP addresses that are allowed to use your master key. This way, even if someone obtains API credentials, they'll be unable to use them to decrypt your encryptions keys from a different host.

 To restrict API access from only a specific IP address or range of IP addresses, you'll need to manually edit the key policy.

 1. Load the IAM console at <https://console.aws.amazon.com/iam/>.
2. Click "Encryption Keys" in the left-hand sidebar.
3. Click the name of your encryption key to view its details.
4. Click the link labeled "Switch to policy view", to the right of the heading of the "Key Policy" section.
5. Locate the section that contains `"Sid": "Allow use of the key"`.
6. Add this text below the `"Sid"` line:
```
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "10.1.2.3/32"
          ]
        }
      },

```
 ... replacing `10.1.2.3/32` above with an IP address or range of IP addresses in CIDR format. For example, a single address would be `192.168.12.34/32`, while a range of addresses might be `192.168.0.0/24`.
7. Click "Save Changes".
8. Click "Proceed" if prompted with a warning about using the default view in the future.

 Access to the API will now be restricted to requests coming from the IP address or range of IP addresses specified in the policy.

 ### Using a Multi-Factor Authentication (MFA) device

 One approach is to modify the key policy for the master key so that MFA (Multi-Factor Authentication) is required in order to use the key. This is achieved with a wrapper that handles prompting the user for an MFA token, acquires temporary, limited-privilege credentials from the AWS Security Token Service (STS), and puts those credentials into the environment of the MariaDB server process. The credentials can expire after as little as 15 minutes.

 To require an MFA token for users of the key, you'll need to manually edit the key policy.

 1. Load the IAM console at <https://console.aws.amazon.com/iam/>.
2. Click "Encryption Keys" in the left-hand sidebar.
3. Click the name of your encryption key to view its details.
4. Click the link labeled "Switch to policy view", to the right of the heading of the "Key Policy" section.
5. Locate the section that contains `"Sid": "Allow use of the key"`.
6. Add this text below the `"Sid"` line:
```
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "True"
        }
      },

```
7. Click "Save Changes".
8. Click "Proceed" if prompted with a warning about using the default view in the future.

 Now, add an MFA device for your user. You'll need to have a hardware MFA device or an application such as Google Authenticator installed on your smartphone.

 1. Click "Users" in the left-hand sidebar.
2. Click the name of your user.
3. Click the "Security Credentials" tab.
4. In the "Sign-In Credentials" section, click the "Manage MFA Device" button.
5. Complete the steps to activate your MFA device.
6. Copy the ARN for your MFA device. You will need to use this when configuring the wrapper program.

 Now, set up the wrapper program.

 1. Copy the iam-kms-wrapper file to /usr/local/bin/, and ensure that it is executable.
2. Create a drop-in systemd config file in `/etc/systemd/system/mariadb.service.d/`:
```
[Service]
EnvironmentFile=/etc/systemd/system/mariadb.service.d/aws-kms.env
ExecStart=
ExecStart=/usr/local/bin/iam-kms-wrapper --config=/etc/my.cnf.d/iam-kms-wrapper.config /usr/sbin/mysqld $MYSQLD_OPTS

```
3. Execute `systemctl daemon-reload`.
4. Create a file at `/etc/my.cnf.d/iam-kms-wrapper.config` with these contents, using the ARN for your MFA device as the value for `kms_mfa_id`:
```
[kms]
kms_mfa_id = arn:aws:iam::551888187628:mfa/MDBEnc
kms_mfa_socket = /tmp/kms_mfa_socket

```

 When you start the MariaDB service now, the wrapper will temporarily create a socket file at the location given by the `kms_mfa_socket` option. The wrapper will read the MFA code from the socket and will use it to authenticate to KMS. To give the MFA code, simply write the digits to the socket file using `echo`: `echo 111676 > /tmp/kms_mfa_socket`.

 The `systemctl` command will block until MariaDB starts, so you will need to write the code to the socket file via a separate terminal.

 Note that the temporary credentials put into the environment of the MariaDB process will expire after a period of time defined by the request to the AWS Security Token Service (STS). In the example below, they will expire after 900 seconds. After that time, MariaDB may be unable to generate new encrypted data keys, which means that, for example, an attempt to create a table with a previously-unused key ID would fail.

 #### Wrapper program example

 Here's an example wrapper program written in go. Build this into an executable named `iam-kms-wrapper` and use it as instructed above. This could of course be written in any language for which an appropriate AWS SDK exists, but go has the benefit of compiling to a static binary, which means you do not have to worry about interpreter versions or installing complex dependencies on the host that runs your MariaDB server.

 
```
package main

import (
    "syscall"
    "os"
    "log"
    "flag"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/aws/awserr"
    "github.com/aws/aws-sdk-go/service/sts"
    "github.com/robfig/config"
)

func main() {

    config_file_p := flag.String("config", "", "location of the config file")
    flag.Parse()

    if flag.NArg() < 1 {
        log.Fatal("Command to wrap must be given as first command-line argument")
    }

    cmd := flag.Arg(0)
    args := flag.Args()[0:]

    conf, err := config.ReadDefault(*config_file_p)
    if err != nil {
        log.Fatal(err)
    }

    kms_mfa_id, err := conf.String("kms","kms_mfa_id")
    mfa_socket_file, err := conf.String("kms","kms_mfa_socket")

    sess := session.New()
    svc := sts.New(sess)

    syscall.Umask(0044)

    log.Printf("Reading MFA token from %s\n",mfa_socket_file)

    if err := syscall.Mknod(mfa_socket_file, syscall.S_IFIFO|uint32(os.FileMode(0622)), 0); err != nil {
        log.Fatal(err)
    }

    file, err := os.Open(mfa_socket_file)
    if err != nil {
        log.Fatal(err)
    }

    token := make([]byte, 6)

    if _, err := file.Read(token); err != nil {
        log.Fatal(err)
    }

    file.Close()

    if err := syscall.Unlink(mfa_socket_file); err != nil {
        log.Fatal(err)
    }

    mfa_token := string(token)

    token_params := &sts.GetSessionTokenInput{
        DurationSeconds: aws.Int64(900),
        SerialNumber:    aws.String(kms_mfa_id),
        TokenCode:       aws.String(mfa_token),
    }

    resp, err := svc.GetSessionToken(token_params)
    if err != nil {
        if awsErr, ok := err.(awserr.Error); ok {
            // Prints out full error message, including original error if there was one.
            log.Fatal("Error:", awsErr.Error())
        } else {
            log.Fatal("Error:", err.Error())
        }
    }

    creds := resp.Credentials

    os.Setenv("AWS_ACCESS_KEY_ID",*creds.AccessKeyId)
    os.Setenv("AWS_SECRET_ACCESS_KEY",*creds.SecretAccessKey)
    os.Setenv("AWS_SESSION_TOKEN",*creds.SessionToken)

    execErr := syscall.Exec(cmd, args, os.Environ())
    if execErr != nil {
        panic(execErr)
    }
}

```

### Disabling keys when not needed

 Another possibility is to use the API to disable access to the master key and enable it only when a trusted administrator knows that the MariaDB service needs to be started. A specialized tool on a separate host could be used to enable the key for a very short period of time while the service starts and then quickly disable the key.

 To do this, you can create an extra IAM User that can only use the kms:EnableKey and kms:DisableKey API endpoints for your key. This user will not be able to encrypt or decrypt any data using the key.

 First, create a new user.

 1. Load the IAM console at <https://console.aws.amazon.com/iam/>.
2. Click "Users" in the left-hand sidebar.
3. Click "Create New Users".
4. Enter a new user name. (The examples will use "MDBEncAdmin".)
5. Click "Show User Security Credentials".
6. Copy the credentials and put them in a `credentials` file with this structure:
```
[MDBEncAdmin]
aws_access_key_id=AKIAJMPPNO7EBKABCDEF
aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef

```
7. Click "Close".
8. Click "Close" again if prompted.
9. Click the name of your new user to open the details view.
10. Copy the "User ARN" value for your user (for example "arn:aws:iam::551888181234:user/MDBEncAdmin"). You will need this for the next step.

 Now, give the new user permission to perform API operations on your key.

 1. Click "Encryption Keys" in the left-hand sidebar.
2. Click the name of your key to open the details view.
3. Click "Switch to policy view" if it is not already open. (The "policy view" is a large text field that contains JSON describing the key policy.)
4. Create a new item in the `Statement` array with this structure:
```
    {
      "Sid": "Allow Enable and Disable of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::551888181234:user/MDBEncAdmin"
      },
      "Action": [
        "kms:EnableKey",
        "kms:DisableKey"
      ]
    },

```
 ...so that your Key Policy looks like this:
```
{
  "Version": "2012-10-17",
  "Id": "key-consolepolicy-2",
  "Statement": [
    {
      "Sid": "Allow Enable and Disable of the key",
      "Effect": "Allow",
      "Principal": {
      ...

```
5. Click "Save Changes".

 You've now added a new IAM user and you've given that user privileges to enable and disable your key. This user will be able to perform those operations using the AWS CLI or via a script of your own design using the AWS API. For example, using the [AWS CLI](https://aws.amazon.com/cli/):

 
```
$ cat ~/.aws/credentials
[MDBEncAdmin]
aws_access_key_id=AKIAJMPPNO7EBKABCDEF
aws_secret_access_key=pVdGwbuK5/jG64aBK1oEJOXRlkdM0aAylgabCDef

$ AWS_PROFILE=MDBEncAdmin aws --region us-east-1 kms disable-key --key-id arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c

```

In order for MariaDB to start, this new user will have to enable the master key, then the DBA can start MariaDB, and this user can once again disable the master key after the service has started. Note that in this workflow, MariaDB will be unable to create new encryption keys, such as would be done when a user creates a table that refers to a non-existent key ID. The AWS KMS plugin will encounter an error if it tries to generate a new encryption key while the master key is disabled. In that scenario, the key administrator would have to enable the key before the operation could succeed. Here's what you should expect to see in the journal if MariaDB tries to interact with a disabled master key:

 
```
[ERROR] AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : DisabledException - Unable to parse ExceptionName: DisabledException Message: arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c is disabled.

```

#### Adding MFA

 It's also possible to add MFA to this technique so that the user that enables & disables the master key has to authenticate using an MFA device. Adapt the instructions in the MFA section above to add MFA to the policy section for the user with EnableKey and DisableKeys privileges, add an MFA device for that user, use Security Token Service (STS) to get temporary security credentials, and then use those credentials to make the API calls. Here's an example Python script that follows that workflow: 

 
```
#!/usr/bin/env python

import boto3
import sys

# Command-line argument processing should be more robust than this...
action= sys.argv[1]
mfa_token= sys.argv[2]

# These should perhaps go into a config file instead of here
mfa_serial= 'arn:aws:iam::551888181234:mfa/MDBEncAdmin'
key_id= 'arn:aws:kms:us-east-1:551888181234:key/abcdf8f6-084b-4cff-99ca-abcdef6c7907c'

# Make the connection to the Security Token Service to get temporary credentials
token_client= boto3.client('sts')
token_response= token_client.get_session_token(
    DurationSeconds= 900,
    SerialNumber= mfa_serial,
    TokenCode= mfa_token
)

cred= token_response['Credentials']

# Start new session using temporary, MFA-authenticated credentials
kms_session= boto3.session.Session(
    aws_access_key_id= cred['AccessKeyId'],
    aws_secret_access_key= cred['SecretAccessKey'],
    aws_session_token= cred['SessionToken'],
    region_name= key_id.split(':')[3]
)

# Start KMS client and execute operation against key
kms_client= kms_session.client('kms')
if action == 'enable' or action == 'e':
    action_f= kms_client.enable_key
elif action == 'disable' or action == 'd':
    action_f= kms_client.disable_key
else:
    raise Exception('Action must be either "disable" or "enable"')

action_f(KeyId=key_id)

```


```
$ AWS_PROFILE=MDBEncAdmin python kms-manage-key disable 575290
$ AWS_PROFILE=MDBEncAdmin python kms-manage-key enable 799870

```

Logging and auditing
--------------------

 ### CloudTrail

 Amazon's CloudTrail service creates JSON-formatted text log files for every API interaction. Enabling CloudTrail requires S3, which incurs additional fees.

 First, enable CloudTrail and add a trail.

 1. Load the CloudTrail console at <https://console.aws.amazon.com/cloudtrail/>.
2. If you've never used CloudTrail before, click "Get Started Now".
3. Enter a value for "trail name". This example uses "mariadb-encryption-key".
4. Create a new S3 bucket, using a globally unique name, or use an existing S3 bucket, according to your needs.
5. Click "Turn On".

 If you navigate to the S3 bucket you created, you should find log files that contain JSON-formatted descriptions of your API interactions.

 ### CloudWatch

 Amazon's CloudWatch service allows you to create alarms and event rules that monitor log information.

 First, send your CloudTrail logs to CloudWatch.

 1. Load the CloudTrail console at <https://console.aws.amazon.com/cloudtrail/>.
2. Click "Trails" in the left-hand navigation sidebar.
3. Click the name of your trail to open the Configuration view.
4. In the "CloudWatch Logs" section, click "Configure".
5. Click "Continue".
6. Click "Allow".

 Now, set up an SNS topic to facilitate email notifications.

 1. Open <https://console.aws.amazon.com/sns/>.
2. *Make sure the region in the console (look in the upper-right corner) is the same as the region where you created your key!*
3. Click "Get Started" is prompted.
4. Click "Events" in the left-hand sidebar.
5. Click "Create new topic".
6. Enter a *Topic name* of your choosing.
7. Enter a *Display name* of your choosing.
8. Click "Create topic".
9. Click the ARN of your new SNS topic.
10. Click "Create Subscription".
11. Select "Email" from the Protocol dropdown.
12. Enter the desired notification email address in the Endpoint field.
13. Wait for the confirmation email to show up and follow the instructions.

 Now, configure CloudWatch and create an Event Rule.

 1. Open <https://console.aws.amazon.com/cloudwatch/>.
2. *Make sure the region in the console (look in the upper-right corner) is the same as the region where you created your key and your SNS topic!*
3. Click "Events" in the left-hand sidebar.
4. Click "Create rule".
5. Choose "AWS API call" from the "Select event source" dropdown.
6. Choose "KMS" from the "Service name" dropdown.
7. Decide which operations should trigger the event. (You can eep "Any operation" selected for simplicity.)
8. Click "Add target".
9. Select "SNS target" from the dropdown.
10. Select the SNS topic you created in the previous steps.
11. Click "Configure details".
12. Enter a *Name* and *Description* of your choosing.
13. Click "Create rule".

 You should now get emails any time someone executes API calls on the KMS service in the region where you've created the CloudWatch Event rule. That means you should get email any time the key is enabled or disabled, and any time the AWS KMS plugin generates new keys or decrypts the keys stored on disk on the MariaDB server.

 You may also wish to create an event rule (or an additional event) that matches only when an unauthorized user tries to access the key. You might accomplish that by manually editing the Event selector of the rule to look something like this:

 
```
{
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "kms.amazonaws.com"
    ],
    "errorCode": [
      "AccessDenied",
      "UnauthorizedOperation"
    ]
  }
}

```

The emails are formatted as JSON. Further customization of the CloudWatch email workflow is beyond the scope of this document.

 There are many other workflows available using CloudWatch, including workflows with alarms and dashboards. Those are beyond the scope of this document.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aws-key-management-encryption-plugin-advanced-usage/>

Encryption Plugin API
=====================

    MariaDB's [data-at-rest encryption](../data-at-rest-encryption/index) requires the use of a [key management and encryption plugin](../encryption-key-management/index). These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of [multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports [key rotation](../encryption-key-management/index#rotating-keys), then encryption keys can also be rotated, which creates a new version of the encryption key.

 See [Data at Rest Encryption](../data-at-rest-encryption/index) and [Encryption Key Management](../encryption-key-management/index) for more information.

 Encryption Plugin API
---------------------

 The Encryption plugin API was created to allow a plugin to:

 * implement key management, provide encryption keys to the server on request and change them according to internal policies.
* implement actual data encryption and decryption with the algorithm defined by the plugin.

 This is how the API reflects that:

 
```
/* Returned from get_latest_key_version() */
#define ENCRYPTION_KEY_VERSION_INVALID (~(unsigned int)0)
#define ENCRYPTION_KEY_NOT_ENCRYPTED (0)

#define ENCRYPTION_KEY_SYSTEM_DATA 1
#define ENCRYPTION_KEY_TEMPORARY_DATA 2

/* Returned from get_key()  */
#define ENCRYPTION_KEY_BUFFER_TOO_SMALL (100)

#define ENCRYPTION_FLAG_DECRYPT 0
#define ENCRYPTION_FLAG_ENCRYPT 1
#define ENCRYPTION_FLAG_NOPAD 2

struct st_mariadb_encryption {
  int interface_version; /**< version plugin uses */

  /********************* KEY MANAGEMENT ***********************************/

  /**
    Function returning latest key version for a given key id.

    @return A version or ENCRYPTION_KEY_VERSION_INVALID to indicate an error.
  */
  unsigned int (*get_latest_key_version)(unsigned int key_id);

  /**
    Function returning a key for a key version

    @param key_id       The requested key id
    @param version      The requested key version
    @param key          The key will be stored there. Can be NULL -
                        in which case no key will be returned
    @param key_length   in: key buffer size
                        out: the actual length of the key

    This method can be used to query the key length - the required
    buffer size - by passing key==NULL.

    If the buffer size is less than the key length the content of the
    key buffer is undefined (the plugin is free to partially fill it with
    the key data or leave it untouched).

    @return 0 on success, or
            ENCRYPTION_KEY_VERSION_INVALID, ENCRYPTION_KEY_BUFFER_TOO_SMALL
            or any other non-zero number for errors
  */
  unsigned int (*get_key)(unsigned int key_id, unsigned int version,
                          unsigned char *key, unsigned int *key_length);

  /********************* ENCRYPTION **************************************/
  /*
    The caller uses encryption as follows:
      1. Create the encryption context object of the crypt_ctx_size() bytes.
      2. Initialize it with crypt_ctx_init().
      3. Repeat crypt_ctx_update() until there are no more data to encrypt.
      4. Write the remaining output bytes and destroy the context object
         with crypt_ctx_finish().
  */

  /**
    Returns the size of the encryption context object in bytes
  */
  unsigned int (*crypt_ctx_size)(unsigned int key_id, unsigned int key_version);
  /**
    Initializes the encryption context object.
  */
  int (*crypt_ctx_init)(void *ctx, const unsigned char *key, unsigned int klen,
                        const unsigned char *iv, unsigned int ivlen, int flags,
                        unsigned int key_id, unsigned int key_version);
  /**
    Processes (encrypts or decrypts) a chunk of data

    Writes the output to th dst buffer. note that it might write
    more bytes that were in the input. or less. or none at all.
  */
  int (*crypt_ctx_update)(void *ctx, const unsigned char *src,
                          unsigned int slen, unsigned char *dst,
                          unsigned int *dlen);
  /**
    Writes the remaining output bytes and destroys the encryption context

    crypt_ctx_update might've cached part of the output in the context,
    this method will flush these data out.
  */
  int (*crypt_ctx_finish)(void *ctx, unsigned char *dst, unsigned int *dlen);
  /**
    Returns the length of the encrypted data

    It returns the exact length, given only the source length.
    Which means, this API only supports encryption algorithms where
    the length of the encrypted data only depends on the length of the
    input (a.k.a. compression is not supported).
  */
  unsigned int (*encrypted_length)(unsigned int slen, unsigned int key_id,
                                   unsigned int key_version);
};

```

The first method is used for key rotation. A plugin that doesn't support key rotation — for example, **file\_key\_management** — can return a fixed version for any valid key id. Note that it still has to return an error for an invalid key id. The version `ENCRYPTION_KEY_NOT_ENCRYPTED` means that the data should not be encrypted.

 The second method is used for key management, the server uses it to retrieve the key corresponding to a specific key identifier and a specific key version.

 The last five methods deal with encryption. Note that they take the key to use and key identifier and version. This is needed because the server can derive a session-specific, user-specific, or a tablespace-specific key from the original encryption key as returned by `get_key()`, so the `key` argument doesn't have to match the encryption key as the plugin knows it. On the other hand, the encryption algorithm may depend on the key identifier and version (and in the **example\_key\_management** plugin it does) so the plugin needs to know them to be able to encrypt the data.

 Encryption methods are optional — if unset (as in the **debug\_key\_management** plugin), the server will fall back to AES\_CBC.

 Current Encryption Plugins
--------------------------

 The MariaDB source tree has four encryption plugins. All these plugins are fairly simple and can serve as good examples of the Encryption plugin API.

 ### file\_key\_management

 It reads encryption keys from a plain-text file. It supports two different encryption algorithms. It supports multiple encryption keys. It does not support key rotation. See the [File Key Management Plugin](../file-key-management-encryption-plugin/index) article for more details.

 #### Versions

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
### aws\_key\_management

 The AWS Key Management plugin uses the [Amazon Web Services (AWS) Key Management Service (KMS)](https://aws.amazon.com/kms/) to generate and store AES keys on disk, in encrypted form, using the Customer Master Key (CMK) kept in AWS KMS. When MariaDB Server starts, the plugin will decrypt the encrypted keys, using the AWS KMS "Decrypt" API function. MariaDB data will then be encrypted and decrypted using the AES key. It supports multiple encryption keys. It supports key rotation.

 See the [AWS Key Management Plugin](../aws-key-management-encryption-plugin/index) article for more details.

 #### Versions

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), [MariaDB 10.1.24](https://mariadb.com/kb/en/mariadb-10124-release-notes/) |
| 1.0 | Beta | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Experimental | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |

 
### example\_key\_management

 Uses random time-based generated keys, ignores key identifiers, supports key versions and key rotation. Uses AES\_ECB and AES\_CBC as encryption algorithms and changes them automatically together with key versions.

 #### Versions

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Experimental | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
### debug\_key\_management

 Key is generated from the version, user manually controls key rotation. Only supports key identifier 1, uses only AES\_CBC.

 #### Versions

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Experimental | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
Encryption Service
------------------

 Encryption is generally needed on the very low level **inside the storage engine**. That is, the storage engine needs to support encryption and have access to the encryption and key management functionality. The usual way for a plugin to access some functionality in the server is via a *service*. In this case the server provides the Encryption Service for storage engines (and other interested plugins) to use. These service functions are directly hooked into encryption plugin methods (described above).

 Service functions are declared as follows:

 
```
unsigned int encryption_key_get_latest_version(unsigned int key_id);
unsigned int encryption_key_get(unsigned int key_id, unsigned int key_version,
                                unsigned char *buffer, unsigned int *length);
unsigned int encryption_ctx_size(unsigned int key_id, unsigned int key_version);
int encryption_ctx_init(void *ctx, const unsigned char *key, unsigned int klen,
                        const unsigned char *iv, unsigned int ivlen, int flags,
                        unsigned int key_id, unsigned int key_version);
int encryption_ctx_update(void *ctx, const unsigned char *src,
                          unsigned int slen, unsigned char *dst,
                          unsigned int *dlen);
int encryption_ctx_finish(void *ctx, unsigned char *dst, unsigned int *dlen);
unsigned int encryption_encrypted_length(unsigned int slen, unsigned int key_id,
                                         unsigned int key_version);

```

There are also convenience helpers to check for a key or key version existence and to encrypt or decrypt a block of data with one function call.

 
```
unsigned int encryption_key_id_exists(unsigned int id);
unsigned int encryption_key_version_exists(unsigned int id,
                                           unsigned int version);
int encryption_crypt(const unsigned char *src, unsigned int slen,
                     unsigned char *dst, unsigned int *dlen,
                     const unsigned char *key, unsigned int klen,
                     const unsigned char *iv, unsigned int ivlen, int flags,
                     unsigned int key_id, unsigned int key_version);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/encryption-plugin-api/>

Aria Encryption
================

   Configuration and use of data-at-rest encryption with the Aria storage engine.

  

| Title | Description |
| --- | --- |
|  [Aria Encryption Overview](../aria-encryption-overview/index) |  Data-at-rest encryption for user-created tables and internal on-disk tempor...  |
|  [Aria Enabling Encryption](../aria-enabling-encryption/index) |  In order to enable data-at-rest encryption for tables using the Aria stora...  |
|  [Aria Disabling Encryption](../aria-disabling-encryption/index) |  The process involved in safely disabling data-at-rest encryption for your ...  |
|  [Aria Encryption Keys](../aria-encryption-keys/index) |  As with other storage engines that support data-at-rest encryption, Aria r...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-encryption/>

InnoDB Encryption
==================

   Data-at-rest encryption configuration and use with the InnoDB storage engine.

  

| Title | Description |
| --- | --- |
|  [InnoDB Encryption Overview](../innodb-encryption-overview/index) |  Data-at-rest encryption for tables that use the InnoDB storage engine.  |
|  [Enabling InnoDB Encryption](../innodb-enabling-encryption/index) |  Configuration and procedure for enabling data-at-rest encryption for InnoDB tables.  |
|  [Disabling InnoDB Encryption](../disabling-innodb-encryption/index) |  Configuration and procedure to disable data-at-rest encryption for InnoDB tables.  |
|  [InnoDB Background Encryption Threads](../innodb-background-encryption-threads/index) |  InnoDB performs some encryption and decryption operations with background encryption threads.  |
|  [InnoDB Encryption Keys](../innodb-encryption-keys/index) |  InnoDB uses encryption key management plugins to support the use of multiple encryption keys.  |
|  [InnoDB Encryption Troubleshooting](../innodb-encryption-troubleshooting/index) |  Troubleshooting InnoDB encryption  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-encryption/>

Stored Procedure Overview
=========================

     A Stored Procedure is a routine invoked with a [CALL](../call/index) statement. It may have input parameters, output parameters and parameters that are both input parameters and output parameters.

 Creating a Stored Procedure
---------------------------

 Here's a skeleton example to see a stored procedure in action:

 
```
DELIMITER //

CREATE PROCEDURE Reset_animal_count() 
 MODIFIES SQL DATA
 UPDATE animal_count SET animals = 0;
//

DELIMITER ;

```

First, the delimiter is changed, since the function definition will contain the regular semicolon delimiter. The procedure is named `Reset_animal_count`. `MODIFIES SQL DATA` indicates that the procedure will perform a write action of sorts, and modify data. It's for advisory purposes only. Finally, there's the actual SQL statement - an UPDATE.

 
```
SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|     101 |
+---------+

CALL Reset_animal_count();

SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       0 |
+---------+

```

A more complex example, with input parameters, from an actual procedure used by banks:

 
```
CREATE PROCEDURE
  Withdraw                             /* Routine name */
  (parameter_amount DECIMAL(6,2),     /* Parameter list */
  parameter_teller_id INTEGER,
  parameter_customer_id INTEGER)
  MODIFIES SQL DATA                   /* Data access clause */
  BEGIN                        /* Routine body */
    UPDATE Customers
        SET balance = balance - parameter_amount
        WHERE customer_id = parameter_customer_id;
    UPDATE Tellers
        SET cash_on_hand = cash_on_hand + parameter_amount
        WHERE teller_id = parameter_teller_id;
    INSERT INTO Transactions VALUES (
        parameter_customer_id,
        parameter_teller_id,
        parameter_amount);
  END;

```

See [CREATE PROCEDURE](../create-procedure/index) for full syntax details. 

 Why use Stored Procedures?
--------------------------

 Security is a key reason. Banks commonly use stored procedures so that applications and users don't have direct access to the tables. Stored procedures are also useful in an environment where multiple languages and clients are all used to perform the same operations.

 Stored Procedure listings and definitions
-----------------------------------------

 To find which stored functions are running on the server, use [SHOW PROCEDURE STATUS](../show-procedure-status/index).

 
```
SHOW PROCEDURE STATUS\G
*************************** 1. row ***************************
                  Db: test
                Name: Reset_animal_count
                Type: PROCEDURE
             Definer: root@localhost
            Modified: 2013-06-03 08:55:03
             Created: 2013-06-03 08:55:03
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

or query the [routines table](../information-schema-routines-table/index) in the INFORMATION\_SCHEMA database directly:

 
```
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES 
  WHERE ROUTINE_TYPE='PROCEDURE';
+--------------------+
| ROUTINE_NAME       |
+--------------------+
| Reset_animal_count |
+--------------------+

```

To find out what the stored procedure does, use [SHOW CREATE PROCEDURE](../show-create-procedure/index).

 
```
SHOW CREATE PROCEDURE Reset_animal_count\G
*************************** 1. row ***************************
           Procedure: Reset_animal_count
            sql_mode: 
    Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `Reset_animal_count`()
    MODIFIES SQL DATA
UPDATE animal_count SET animals = 0
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Dropping and Updating a Stored Procedure
----------------------------------------

 To drop a stored procedure, use the [DROP PROCEDURE](../drop-procedure/index) statement.

 
```
DROP PROCEDURE Reset_animal_count();

```

To change the characteristics of a stored procedure, use [ALTER PROCEDURE](../alter-procedure/index). However, you cannot change the parameters or body of a stored procedure using this statement; to make such changes, you must drop and re-create the procedure using [CREATE OR REPLACE PROCEDURE](../create-procedure/index#or-replace) (which retains existing privileges), or DROP PROCEDURE followed CREATE PROCEDURE .

 Permissions in Stored Procedures
--------------------------------

 See the article [Stored Routine Privileges](../stored-routine-privileges/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-procedure-overview/>

WSREP\_INFO Plugin
==================

    The `WSREP_INFO` plugin library contains the following plugins:

 * `WSREP_MEMBERSHIP`
* `WSREP_STATUS`

 The `WSREP_MEMBERSHIP` plugin creates the [WSREP\_MEMBERSHIP](../information-schema-wsrep_membership-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. The plugin also adds the [SHOW WSREP\_MEMBERSHIP](../show-wsrep_membership/index) statement.

 The `WSREP_STATUS` plugin creates the [WSREP\_STATUS](../information-schema-wsrep_status-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. The plugin also adds the [SHOW WSREP\_STATUS](../show-wsrep_status/index) statement.

 These tables and statements provide information about [Galera](../galera/index). Only users with the [SUPER](../grant/index#global-privileges) privilege can access this information.

 Installing the Plugin
---------------------

 Although the plugin's shared library is distributed with MariaDB by default, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'wsrep_info';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = wsrep_info

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'wsrep_info';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Example
-------

 
```
SHOW TABLES FROM information_schema LIKE 'WSREP%';
+---------------------------------------+
| Tables_in_information_schema (WSREP%) |
+---------------------------------------+
| WSREP_STATUS                          |
| WSREP_MEMBERSHIP                      |
+---------------------------------------+

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.1.18](https://mariadb.com/kb/en/mariadb-10118-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |

 
Options
-------

 ### `wsrep_membership`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--wsrep-membership=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 ### `wsrep_status`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--wsrep-status=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wsrep_info-plugin/>

MYSQL\_JSON
===========

    
**MariaDB starting with [10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/)**The `TYPE_MYSQL_JSON` plugin was first released in [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/).

 
The JSON type in MySQL stores the JSON object in its own native form, while in MariaDB the [JSON type](../json-data-type/index) is a [LONGTEXT](../longtext/index). Opening a table with a JSON type created in MySQL would result in an error:

 
```
select * from mysql_json_table;
ERROR 4161 (HY000): Unknown data type: 'MYSQL_JSON'

```

The mysql\_json plugin is used to make it easier to upgrade to MariaDB. 

 Installing
----------

 Installing can be done in a [number of ways](../plugin-overview/index#installing-a-plugin), for example:

 
```
install soname 'type_mysql_json';

```

See [Making MariaDB understand MySQL JSON](https://mariadb.org/making-mariadb-understand-mysql-json/) for a full description.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_json/>

SHOW PROCEDURE CODE
===================

    Syntax
------

 
```
SHOW PROCEDURE CODE proc_name

```
 Description
-----------

 This statement is a MariaDB extension that is available only for servers that have been built with debugging support. It displays a representation of the internal implementation of the named [stored procedure](../stored-procedures/index). A similar statement, `[SHOW FUNCTION CODE](../show-function-code/index)`, displays information about [stored functions](../stored-functions/index).

 Both statements require that you be the owner of the routine or have `[SELECT](../grant/index)` access to the `[mysql.proc](../mysqlproc-table/index)` table.

 If the named routine is available, each statement produces a result set. Each row in the result set corresponds to one "instruction" in the routine. The first column is Pos, which is an ordinal number beginning with 0. The second column is Instruction, which contains an SQL statement (usually changed from the original source), or a directive which has meaning only to the stored-routine handler.

 Examples
--------

 
```
DELIMITER //

CREATE PROCEDURE p1 ()
  BEGIN
    DECLARE fanta INT DEFAULT 55;
    DROP TABLE t2;
    LOOP
      INSERT INTO t3 VALUES (fanta);
      END LOOP;
  END//
Query OK, 0 rows affected (0.00 sec)

SHOW PROCEDURE CODE p1//
+-----+----------------------------------------+
| Pos | Instruction                            |
+-----+----------------------------------------+
|   0 | set fanta@0 55                         |
|   1 | stmt 9 "DROP TABLE t2"                 |
|   2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |
|   3 | jump 2                                 |
+-----+----------------------------------------+

```

See Also
--------

 * [Stored Procedure Overview](../stored-procedure-overview/index)
* [CREATE PROCEDURE](../create-procedure/index)
* [ALTER PROCEDURE](../alter-procedure/index)
* [DROP PROCEDURE](../drop-procedure/index)
* [SHOW CREATE PROCEDURE](../show-create-procedure/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-procedure-code/>

SHOW FUNCTION CODE
==================

    Syntax
------

 
```
SHOW FUNCTION CODE func_name

```

Description
-----------

 `SHOW FUNCTION CODE` shows a representation of the internal implementation of the stored function.

 It is similar to `[SHOW PROCEDURE CODE](../show-procedure-code/index)` but for [stored functions](../stored-functions/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-function-code/>

TokuDB Differences
==================

    
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

  Because we, the MariaDB developers, don't want to add a lot of new features or big code changes to a stable release, not all TokuDB features will be merged at once into MariaDB. Instead they will be added in stages.

 On this page we list all the known differences between the TokuDB from [Tokutek](http://www.tokutek.com) and the default MariaDB version from [MariaDB.org](https://downloads.mariadb.org):

 All MariaDB versions
--------------------

 * TokuDB is not the default storage engine.
	+ If you want to enable this, you have to start mysqld with: `--default-storage-engine=tokudb`.
* Auto increment for second part of a key behaves as documented (and as it does in MyISAM and other storage engines).
* The DDL syntax is different. While binaries from Tokutek have the patched SQL parser, TokuDB in MariaDB uses the special [Storage Engine API extension](../engine-defined-new-tablefieldindex-attributes/index). Thus in Tokutek binaries you write `CLUSTERED KEY (columns)` and, for example, `ROW_FORMAT=TOKUDB_LZMA`. And in MariaDB you write `KEY (columns) CLUSTERING=YES` and `COMPRESSION=TOKUDB_LZMA`.

 Features missing in [MariaDB 5.5](../what-is-mariadb-55/index)
--------------------------------------------------------------

 * No online [ALTER TABLE](../alter-table/index).
	+ All alter table that changes data or indexes requires a table copy.
* No online [OPTIMIZE TABLE](../optimize-table/index).
* No `INSERT NOAR` or `UPDATE NOAR` commands.
* No gdb stack trace on sigsegv
* IMPORTANT: the compression type does not default to the [tokudb\_row\_format](../tokudb-system-variables/index#tokudb_row_format) session variable as it does with Tokutek's builds. If `COMPRESSION=` is not included in `CREATE TABLE` or `ALTER TABLE ENGINE=TokuDB` then the TokuDB table will be uncompressed (before 5.5.37) or zlib-compressed (5.5.37 and later).

 Features missing in [MariaDB 10.0](../what-is-mariadb-100/index)
----------------------------------------------------------------

 [MariaDB 10.0](../what-is-mariadb-100/index) (starting from 10.0.5) has online [ALTER TABLE](../alter-table/index). So the features missing will be:

 * No `INSERT NOAR` or `UPDATE NOAR` commands.
	+ We are working with Tokutek to improve this feature before adding it to MariaDB.
* No online [OPTIMIZE TABLE](../optimize-table/index) before [10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) ([r4199](http://bazaar.launchpad.net/~maria-captains/maria/10.0/revision/4199))
* No gdb stack trace on sigsegv
* Before 10.0.10 the compression type did not default to the [tokudb\_row\_format](../tokudb-system-variables/index#tokudb_row_format) session variable. If `COMPRESSION=` was not included in `CREATE TABLE` or `ALTER TABLE ENGINE=TokuDB` then the TokuDB table was created uncompressed.

 Version of the TokuDB plugin included on MariaDB
------------------------------------------------

 This is found on the [TokuDB](../tokudb/index) page.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tokudb-differences/>

Installing TokuDB
=================

    
TokuDB has been deprecated by its upstream maintainer. It is disabled from [MariaDB 10.5](../what-is-mariadb-105/index) and has been been removed in [MariaDB 10.6](../what-is-mariadb-106/index) - [MDEV-19780](https://jira.mariadb.org/browse/MDEV-19780). We recommend [MyRocks](../myrocks/index) as a long-term migration path.

  
Note that ha\_tokudb is not included in binaries built with the "old" glibc. Binaries built with glibc 2.14+ do include it.

 
TokuDB is available on the following distributions:

 


| Distribution | Introduced |
| --- | --- |
| CentOS 6 64-bit and newer | [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5536-release-notes/) and [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| Debian 7 "wheezy"64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| Fedora 19 64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| openSUSE 13.1 64-bit and newer | [MariaDB 5.5.41](https://mariadb.com/kb/en/mariadb-5541-release-notes/) and [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| Red Hat 6 64-bit and newer | [MariaDB 5.5.36](https://mariadb.com/kb/en/mariadb-5536-release-notes/) and [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| Ubuntu 12.10 "quantal" 64-bit and newer | [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |

  
**Note:** The TokuDB version that comes from MariaDB.org differs slightly from the TokuDB version from [Tokutek](http://www.tokutek.com). Please read the [TokuDB Differences](../tokudb-differences/index) article before using TokuDB!

 
The following sections detail how to install and enable TokuDB.

 Installing TokuDB
-----------------

 
Until MariaDB versions 5.5.39 and 10.0.13, before upgrading TokuDB, the server needed to be cleanly shut down. If the server was not cleanly shut down, TokuDB would fail to start. Since 5.5.40 and 10.0.14, this has no longer been necessary. See [MDEV-6173](https://jira.mariadb.org/browse/MDEV-6173).

 
TokuDB has been included with MariaDB since [MariaDB 5.5.34](https://mariadb.com/kb/en/mariadb-5534-release-notes/) and [MariaDB 10.0.6](https://mariadb.com/kb/en/mariadb-1006-release-notes/) and does not require separate installation. Proceed straight to [Check for Transparent HugePage Support on Linux](#check-for-transparent-hugepage-support-on-linux). For older versions, see the distro-specific instructions below.

 ### Installing TokuDB on Fedora, RedHat, & CentOS

 In [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/), [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/), and starting from [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) TokuDB is in a separate RPM package called `MariaDB-tokudb-engine` and is installed as follows:

 
```
sudo yum install MariaDB-tokudb-engine

```

### Installing TokuDB on Ubuntu & Debian

 On Ubuntu, TokuDB is available on the 64-bit versions of Ubuntu 12.10 and newer. On Debian, TokuDB is available on the 64-bit versions of Debian 7 "Wheezy" and newer. 

 The package is installed as follows:

 
```
sudo apt-get install mariadb-plugin-tokudb

```

In some earlier versions, from [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) and [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/), TokuDB is in a separate package called `mariadb-tokudb-engine-x.x`, where `x.x` is the MariaDB series (`5.5` or `10.0`). The package is installed, for example on `5.5`, as follows:

 
```
sudo apt-get install mariadb-tokudb-engine-5.5

```

libjemalloc
-----------

 TokuDB requires the libjemalloc library (currently version 3.3.0 or greater).

 libjemalloc should automatically be installed when using a package manager, and is loaded by restarting MariaDB.

 It can be enabled, if not already done, by adding the following to the my.cnf configuration file:

 
```
[mysqld_safe]

malloc-lib= /path/to/jemalloc

```

If you don't do the above, you will get an error similar to the following one in your error file

 
```
2018-11-19 18:46:26 0 [ERROR] mysqld: Can't open shared library '/home/my/maria-10.3/mysql-test/var/plugins/ha_tokudb.so' (errno: 2, /usr/lib64/libjemalloc.so.2: cannot allocate memory in static TLS block)

```

Check for Transparent HugePage Support on Linux
-----------------------------------------------

 
Transparent hugepages is a feature in newer linux kernel versions that causes problems for the memory usage tracking calculations in TokuKV and can lead to memory overcommit. If you have this feature enabled, TokuKV will not start, and you should turn it off.

 
You can check the status of Transparent Hugepages as follows:

 
```
cat /sys/kernel/mm/transparent_hugepage/enabled

```

If the path does not exist, Transparent Hugepages are not enabled and you may continue. 

 Alternatively, the following will be returned:

 
```
always madvise [never]

```

indicating Transparent Hugepages are not enabled and you may continue. If the following is returned:

 
```
[always] madvise never

```

Transparent Hugepages are enabled, and you will need to disable them.

 To disable them, pass "transparent\_hugepage=never" to the kernel in your bootloader (grub, lilo, etc.). For example, for SUSE, add `transparent_hugepage=never` to Optional Kernel Command Line Parameter at the end, such as after "showopts", and press OK. The setting will take effect on the next reboot. 

 You can also disable with:

 
```
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

```

On Centos or RedHat you can do:

 Add line `GRUB_CMDLINE_LINUX_DEFAULT="transparent_hugepage=never"` to file /etc/default/grub

 Update grub (boot loader):

 
```
grub2-mkconfig -o /boot/grub2/grub.cfg "$@"

```

For more information, see <http://unix.stackexchange.com/questions/99154/disable-transparent-hugepages>

 Enabling TokuDB
---------------

 Attempting to enable TokuDB while Linux Transparent HugePages are enabled will fail with an error such as:

 
```
ERROR 1123 (HY000): Can't initialize function 'TokuDB'; Plugin initialization function failed

```

See the section above; [Check for Transparent HugePage Support on Linux](#check-for-transparent-hugepage-support-on-linux).

 The [binary log also needs to be enabled](../activating-the-binary-log/index) before attempting to enable TokuDB. Strictly speaking, the XA code requires two XA-capable storage engines, and this is checked at startup. In practice, this requires InnoDB and the binary log to be active. If it isn't, the following warning will be returned and XA features will be disabled:

 
```
Cannot enable tc-log at run-time. XA features of TokuDB are disabled

```

MariaDB's default `my.cnf` files come with a section for TokuDB. To enable TokuDB just remove the '#' comment markers from the options in the TokuDB section.

 A typical TokuDB section looks like the following:

 
```
# See https://mariadb.com/kb/en/how-to-enable-tokudb-in-mariadb/
# for instructions how to enable TokuDB
#
# See https://mariadb.com/kb/en/tokudb-differences/ for differences
# between TokuDB in MariaDB and TokuDB from http://www.tokutek.com/

plugin-load=ha_tokudb

```

By default, the `plugin-load` option is commented out. Simply un-comment it as in the example above.

 Don't forget to also enable jemalloc in the config file.

 
```
[mysqld_safe]
malloc-lib= /path/to/jemalloc

```

With these changes done, you can restart MariaDB to activate TokuDB.

 ### Enabling TokuDB on Fedora

 Instead of putting the TokuDB section in the main `my.cnf` file, it is placed in a separate file located at: `/etc/my.cnf.d/tokudb.cnf`

 ### Enabling TokuDB on Ubuntu & Debian

 Instead of putting the TokuDB section in the main `my.cnf` file, it is placed in a separate file located at: `/etc/mysql/conf.d/tokudb.cnf`

 ### Enabling TokuDB Manually From the mysql Command Line

 Generally, it is recommended to use one of the above methods to enable the TokuDB storage engine, but it is also possible to enable it manually as with other plugins. To do so, launch the mysql command-line client and connect to MariaDB as a user with the `SUPER` privilege and execute the following command:

 
```
INSTALL SONAME 'ha_tokudb';

```

TokuDB will be installed until someone executes [UNINSTALL SONAME](../uninstall-soname/index).

 ### Temporarily Enabling TokuDB When Starting MariaDB

 If you just want to test TokuDB, you can start the `mysqld` server with TokuDB with the following command:

 
```
mysqld --plugin-load=ha_tokudb --plugin-dir=/usr/local/mysql/lib/mysql/plugin

```

See Also
--------

 * [Differences between TokuDB from Tokutek.com and the TokuDB version in MariaDB from MariaDB.org](../tokudb-differences/index).
* [TokuDB System and Status Variables](../tokudb-system-and-status-variables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-tokudb/>

DECLARE CURSOR
==============

    Syntax
------

 <= [MariaDB 10.2](../what-is-mariadb-102/index)

 
```
DECLARE cursor_name CURSOR FOR select_statement

```

From [MariaDB 10.3](../what-is-mariadb-103/index)

 
```
DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR select_statement

cursor_formal_parameter:
    name type [collate clause]

```

From [MariaDB 10.8](../what-is-mariadb-108/index)

 
```
DECLARE cursor_name CURSOR [(cursor_formal_parameter[,...])] FOR select_statement

cursor_formal_parameter:
    [IN] name type [collate clause]

```
 Description
-----------

 This statement declares a [cursor](../programmatic-and-compound-statements-cursors/index). Multiple cursors may be declared in a [stored program](../stored-programs-and-views/index), but each cursor in a given block must have a unique name.

 `select_statement` is not executed until the [OPEN](../open/index) statement is executed. It is important to remember this if the query produces an error, or calls functions which have side effects.

 A `SELECT` associated to a cursor can use variables, but the query itself cannot be a variable, and cannot be dynamically composed. The `SELECT` statement cannot have an `INTO` clause.

 Cursors must be declared before [HANDLERs](../declare-handler/index), but after local variables and [CONDITIONs](../declare-condition/index).

 ### Parameters

 
**MariaDB starting with [10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)**From [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/), cursors can have parameters. This is a non-standard SQL extension. Cursor parameters can appear in any part of the DECLARE CURSOR select\_statement where a stored procedure variable is allowed (select list, WHERE, HAVING, LIMIT etc).

 
### IN

 
**MariaDB starting with [10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/)**From [MariaDB 10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/) preview release, the `IN` qualifier is supported in the `cursor_format_parameter` part of the syntax.

 
See [Cursor Overview](../cursor-overview/index) for an example.

 See Also
--------

 * [Cursor Overview](../cursor-overview/index)
* [OPEN cursor\_name](../open/index)
* [FETCH cursor\_name](../fetch/index)
* [CLOSE cursor\_name](../close/index)
* [Cursors in Oracle mode](../sql_modeoracle-from-mariadb-103/index#cursors)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/declare-cursor/>

Stored Procedure Internals
==========================

    Implementation Specification for Stored Procedures
--------------------------------------------------

 ### How Parsing and Execution of Queries Work

  In order to execute a query, the function `sql_parse.cc:mysql_parse()` is called, which in turn calls the parser (`yyparse()`) with an updated Lex structure as the result. `mysql_parse()` then calls `mysql_execute_command()` which dispatches on the command code (in Lex) to the corresponding code for executing that particular query.

  There are three structures involved in the execution of a query which are of interest to the [stored procedure](../stored-procedures/index) implementation:

 * Lex (mentioned above) is the "compiled" query, that is the output from the parser and what is then interpreted to do the actual work. It constains an enum value (sql\_command) which is the query type, and all the data collected by the parser needed for the execution (table names, fields, values, etc).
* THD is the "run-time" state of a connection, containing all that is needed for a particular client connection, and, among other things, the Lex structure currently being executed.
* `Item_*`: During parsing, all data is translated into "items", objects of the subclasses of "Item", such as `Item_int`, `Item_real`, `Item_string`, etc., for basic datatypes, and also various more specialized Item types for expressions to be evaluated (`Item_func` objects).

 ### How to Fit Stored Procedures into this Scheme

 #### Overview of the Classes and Files for Stored Procedures

  (More detailed APIs at the end of this page)

 ##### class sp\_head (sp\_head.{cc,h})

  This contains, among other things, an array of "instructions" and the method for executing the procedure.

 ##### class sp\_pcontext (sp\_pcontext.{cc,h}

  This is the parse context for the procedure. It's primarily used during parsing to keep track of local parameters, variables and labels, but it's also used at [CALL](../call/index) time to find the parameters mode (IN, OUT or INOUT) and type when setting up the runtime context.

 ##### class sp\_instr (sp\_head.{cc,h})

  This is the base class for "instructions", that is, what is generated by the parser. It turns out that we only need a minimum of 5 different sub classes:

 * sp\_instr\_stmt Execute a statement. This is the "call-out" any normal SQL statement, like a [SELECT](../select/index), [INSERT](../insert/index) etc. It contains the Lex structure for the statement in question.
* sp\_instr\_set Set the value of a local variable (or parameter)
* sp\_instr\_jump An unconditional jump.
* sp\_instr\_jump\_if\_not Jump if condition is not true. It turns out that the negative test is most convenient when generating the code for the flow control constructs.
* sp\_instr\_freturn Return a value from a FUNCTION and exit. For condition HANDLERs some special instructions are also needed, see that section below.

 ##### class sp\_rcontext (sp\_rcontext.h)

  This is the runtime context in the THD structure. It contains an array of items, the parameters and local variables for the currently executing stored procedure. This means that variable value lookup is in runtime is constant time, a simple index operation.

 ##### class Item\_splocal (Item.{cc,h})

  This is a subclass of Item. Its sole purpose is to hide the fact that the real Item is actually in the current frame (runtime context). It contains the frame offset and defers all methods to the real Item in the frame. This is what the parser generates for local variables.

 ##### Utility Functions (sp.{cc,h})

  This contains functions for creating, dropping and finding a stored procedure in the [mysql.proc table](../mysqlproc-table/index) (or the internal cache).

 #### Parsing CREATE PROCEDURE

  When parsing a [CREATE PROCEDURE](../create-procedure/index) the parser first initializes the `sphead` and `spcont` (runtime context) fields in the Lex. The sql\_command code for the result of parsing a is `SQLCOM_CREATE_PROCEDURE`.

  The parsing of the parameter list and body is relatively straightforward:

 * Parameters: name, type and mode (IN/OUT/INOUT) is pushed to `spcont`
* Declared local variables: Same as parameters (mode is then IN)
* Local Variable references: If an identifier is found in in `spcont`, an `Item_splocal` is created with the variable's frame index, otherwise an `Item_field` or `Item_ref` is created (as before).
* Statements: The Lex in THD is replaced by a new Lex structure and the statement, is parsed as usual. A `sp_instr_stmt` is created, containing the new Lex, and added to the instructions in `sphead`. Afterwards, the procedure's Lex is restored in THD.
* SET var: Setting a local variable generates a `sp_instr_set` instruction, containing the variable's frame offset, the expression (an Item), and the type.
* Flow control: Flow control constructs such as [IF](../if/index), [WHILE](../while/index), etc, generate a conditional and unconditional jumps in the "obvious" way, but a few notes may be required:
* Forward jumps: When jumping forward, the exact destination is not known at the time of the creation of the jump instruction. The
	1. sphead `therefore contains a list of instruction-label pairs for
	 each forward reference. When the position later is known, the
	 instructions in the list are updated with the correct location.`
* Loop constructs have optional labels. If a loop doesn't have a label, an anonymous label is generated to simplify the parsing.
* There are two types of CASE. The "simple" case is implemented with an anonymous variable bound to the value to be tested.

 ##### A Simple Example

  Parsing the procedure:

 
```
      create procedure a(s char(16))
      begin
        declare x int;
        set x = 3;
        while x > 0 do
          set x = x-1;
          insert into db.tab values (x, s);
        end while;
      end

```

 would generate the following structures:

 
```
            ______
      thd: |      |     _________
           | lex -+--->|         |                     ___________________
           |______|    | spcont -+------------------->| "s",in,char(16):0 |
                       | sphead -+------              |("x",in,int     :1)|
                       |_________|      |             |___________________|
                                    ____V__________________
                                   | m_name: "a"           |
                                   | m_defstr: "create ..."|
                                   | m_instr: ...          |
                                   |_______________________|

```

 Note that the contents of the `spcont` is changing during the parsing, at all times reflecting the state of the would-be runtime frame. The `m_instr` is an array of instructions:

 
```
      Pos.  Instruction
       0    sp_instr_set(1, '3')
       1    sp_instr_jump_if_not(5, 'x>0')
       2    sp_instr_set(1, 'x-1')
       3    sp_instr_stmt('insert into ...')
       4    sp_instr_jump(1)
       5    <end>

```

 Here, '3', 'x>0', etc, represent the Items or Lex for the respective expressions or statements.

 #### Parsing CREATE FUNCTION

  [Creating a function](../create-function/index) is essentially the same thing as for a PROCEDURE, with the addition that a FUNCTION has a return type and a RETURN statement, but no OUT or INOUT parameters.

  The main difference during parsing is that we store the result type in the sp\_head. However, there are big differences when it comes to invoking a FUNCTION. (See below.)

 #### Storing, Caching, Dropping

  As seen above, the entired definition string, including the "CREATE PROCEDURE" (or "FUNCTION") is kept. The procedure definition string is stored in the table mysql.proc with the name and type as the key, the type being one of the enum ("procedure","function").

  A PROCEDURE is just stored in the [mysql.proc table](../mysqlproc-table/index). A FUNCTION has an additional requirement. They will be called in expressions with the same syntax as UDFs, so UDFs and stored FUNCTIONs share the namespace. Thus, we must make sure that we do not have UDFs and FUNCTIONs with the same name (even if they are stored in different places).

  This means that we can reparse the procedure as many time as we want. The first time, the resulting Lex is used to store the procedure in the database (using the function sp.c:sp\_create\_procedure()).

  The simplest way would be to just leave it at that, and re-read the procedure from the database each time it is called. (And in fact, that's the way the earliest implementation will work.) However, this is not very efficient, and we can do better. The full implementation should work like this:

 1. Upon creation time, parse and store the procedure. Note that we still need to parse it to catch syntax errors, but we can't check if called procedures exists for instance.
2. Upon first CALL, read from the database, parse it, and cache the resulting Lex in memory. This time we can do more error checking.
3. Upon subsequent CALLs, use the cached Lex.

  Note that this implies that the Lex structure with its sphead must be reentrant, that is, reusable and shareable between different threads and calls. The runtime state for a procedure is kept in the sp\_rcontext in THD.

  The mechanisms of storing, finding, and dropping procedures are encapsulated in the files sp.{cc,h}.

 #### CALLing a Procedure

  A [CALL](../call/index) is parsed just like any statement. The resulting Lex has the sql\_command SQLCOM\_CALL, the procedure's name and the parameters are pushed to the Lex' value\_list.

  sql\_parse.cc:mysql\_execute\_command() then uses sp.cc:sp\_find() to get the sp\_head for the procedure (which may have been read from the database or fetched from the in-memory cache) and calls the sp\_head's method execute(). Note: It's important that substatements called by the procedure do not do send\_ok(). Fortunately, there is a flag in THD->net to disable this during CALLs. If a substatement fails, it will however send an error back to the client, so the CALL mechanism must return immediately and without sending an error.

  The sp\_head::execute() method works as follows:

 1. Keep a pointer to the old runtime context in THD (if any)
2. Create a new runtime context. The information about the required size is in sp\_head's parse time context.
3. Push each parameter (from the CALL's Lex->value\_list) to the new context. If it's an OUT or INOUT parameter, the parameter's offset in the caller's frame is set in the new context as well.
4. For each instruction, call its execute() method. The result is a pointer to the next instruction to execute (or NULL) if an error occurred.
5. On success, set the new values of the OUT and INOUT parameters in the caller's frame.

 #### USE database

  Before executing the instruction we also keeps the current default database (if any). If this was changed during execution (i.e. a [USE](../use/index) statement has been executed), we restore the current database to the original.

  This is the most useful way to handle USE in procedures. If we didn't, the caller would find himself in a different database after calling a function, which can be confusing. Restoring the database also gives full freedom to the procedure writer: - It's possible to write "general" procedures that are independent of the actual database name. - It's possible to write procedures that work on a particular database by calling USE, without having to use fully qualified table names everywhere (which doesn't help if you want to call other, "general", procedures anyway).

 #### Evaluating Items

  There are three occasions where we need to evaluate an expression:

 * When SETing a variable
* When CALLing a procedure
* When testing an expression for a branch (in IF, WHILE, etc)

  The semantics in stored procedures is "call-by-value", so we have to evaluate any "func" Items at the point of the CALL or SET, otherwise we would get a kind of "lazy" evaluation with unexpected results with respect to OUT parameters for instance. For this the support function, `sp_head.cc:eval_func_item()` is needed.

 #### Calling a FUNCTION

  Functions don't have an explicit call keyword like procedures. Instead, they appear in expressions with the conventional syntax "fun(arg, ...)". The problem is that we already have [User Defined Functions](../user-defined-functions/index) (UDFs) which are called the same way. A UDF is detected by the lexical analyzer (not the parser!), in the `find_keyword()` function, and returns a `UDF_*_FUNC` or `UDA_*_SUM` token with the `udf_func` object as the yylval.

  So, stored functions must be handled in a similar way, and as a consequence, UDFs and functions must not have the same name.

 #### Detecting and Parsing a FUNCTION Invocation

  The existence of UDFs are checked during the lexical analysis (in sql\_lex.cc:find\_keyword()). This has the drawback that they must exist before they are referred to, which was ok before SPs existed, but then it becomes a problem. The first implementation of SP FUNCTIONs will work the same way, but this should be fixed a.s.a.p. (This will required some reworking of the way UDFs are handled, which is why it's not done from the start.) For the time being, a FUNCTION is detected the same way, and returns the token SP\_FUNC. During the parsing we only check for the \*existence\* of the function, we don't parse it, since wa can't call the parser recursively.

  When encountering a SP\_FUNC with parameters in the expression parser, an instance of the new Item\_func\_sp class is created. Unlike UDFs, we don't have different classes for different return types, since we at this point don't know the type.

 #### Collecting FUNCTIONs to invoke

  A FUNCTION differs from a PROCEDURE in one important aspect: Whereas a PROCEDURE is CALLed as statement by itself, a FUNCTION is invoked "on-the-fly" during the execution of \*another\* statement. This makes things a lot more complicated compared to CALL: - We can't read and parse the FUNCTION from the [mysql.proc table](../mysqlproc-table/index) at the point of invocation; the server requires that all tables used are opened and locked at the beginning of the query execution. One "obvious" solution would be to simply push "mysql.proc" to the list of tables used by the query, but this implies a "join" with this table if the query is a select, so it doesn't work (and we can't exclude this table easily; since a privileged used might in fact want to search the proc table). Another solution would of course be to allow the opening and closing of the [mysql.proc table](../mysqlproc-table/index) during a query execution, but this it not possible at the present.

  So, the solution is to collect the names of the referred FUNCTIONs during parsing in the lex. Then, before doing anything else in `mysql_execute_command()`, read all functions from the database an keep them in the THD, where the function `sp_find_function()` can find them during the execution. Note: Even with an in-memory cache, we must still make sure that the functions are indeed read and cached at this point. The code that read and cache functions from the database must also be invoked recursively for each read FUNCTION to make sure we have \*all\* the functions we need.

 #### Parsing DROP PROCEDURE/FUNCTION

  The procedure name is pushed to Lex->value\_list. The sql\_command code for the result of parsing a is `SQLCOM_DROP_PROCEDURE`/`SQLCOM_DROP_FUNCTION`.

  Dropping is done by simply getting the procedure with the sp\_find() function and calling `sp_drop()` (both in `sp.{cc,h}`).

  [DROP PROCEDURE](../drop-procedure/index)/[DROP FUNCTION](../drop-function/index) also supports the non-standard "IF EXISTS", analogous to other [DROP](../drop/index) statements in MariaDB.

 #### Condition and Handlers

  Condition names are lexical entities and are kept in the parser context just like variables. But, condition are just "aliases" for SQLSTATE strings, or mysqld error codes (which is a non-standard extension in MySQL), and are only used during parsing.

  Handlers comes in three types, CONTINUE, EXIT and UNDO. The latter is like an EXIT handler with an implicit rollback, and is currently not implemented. The EXIT handler jumps to the end of its BEGIN-END block when finished. The CONTINUE handler returns to the statement following that which invoked the handler.

  The handlers in effect at any point is part of each thread's runtime state, so we need to push and pop handlers in the sp\_rcontext during execution. We use special instructions for this: - sp\_instr\_hpush\_jump Push a handler. The instruction contains the necessary information, like which conditions we handle and the location of the handler. The jump takes us to the location after the handler code. - sp\_instr\_hpop Pop the handlers of the current frame (which we are just leaving).

  It might seems strange to jump past the handlers like that, but there's no extra cost in doing this, and for technical reasons it's easiest for the parser to generate the handler instructions when they occur in the source.

  When an error occurs, one of the error routines is called and an error message is normally sent back to the client immediately. Catching a condition must be done in these error routines (there are quite a few) to prevent them from doing this. We do this by calling a method in the THD's sp\_rcontext (if there is one). If a handler is found, this is recorded in the context and the routine returns without sending the error message. The execution loop (sp\_head::execute()) checks for this after each statement and invokes the handler that has been found. If several errors or warnings occurs during one statement, only the first is caught, the rest are ignored.

  Invoking and returning from a handler is trivial in the EXIT case. We simply jump to it, and it will have an sp\_instr\_jump as its last instruction.

  Calling and returning from a CONTINUE handler poses some special problems. Since we need to return to the point after its invocation, we push the return location on a stack in the sp\_rcontext (this is done by the execution loop). The handler then ends with a special instruction, sp\_instr\_hreturn, which returns to this location.

  CONTINUE handlers have one additional problem: They are parsed at the lexical level where they occur, so variable offsets will assume that it's actually called at that level. However, a handler might be invoked from a sub-block where additional local variables have been declared, which will then share the location of any local variables in the handler itself. So, when calling a CONTINUE handler, we need to save any local variables above the handler's frame offset, and restore them upon return. (This is not a problem for EXIT handlers, since they will leave the block anyway.) This is taken care of by the execution loop and the sp\_instr\_hreturn instruction.

 ##### Examples

 EXIT handler:

 
```
      begin
        declare x int default 0;

        begin
          declare exit handler for 'XXXXX' set x = 1;

          (statement1);
          (statement2);
        end;
        (statement3);
      end

```


```
      Pos.  Instruction
       0    sp_instr_set(0, '0')
       1    sp_instr_hpush_jump(4, 1)           # location and frame size
       2    sp_instr_set(0, '1')
       3    sp_instr_jump(6)
       4    sp_instr_stmt('statement1')
       5    sp_instr_stmt('statement2')
       6    sp_instr_hpop(1)
       7    sp_instr_stmt('statement3')

```

CONTINUE handler:

 
```
      create procedure hndlr1(val int)
      begin
        declare x int default 0;
        declare foo condition for 1146;
        declare continue handler for foo set x = 1;

        insert into t3 values ("hndlr1", val);     # Non-existing table?
        if x>0 then
          insert into t1 values ("hndlr1", val);   # This instead then
        end if;
      end|

```


```
      Pos.  Instruction
       0    sp_instr_set(1, '0')
       1    sp_instr_hpush_jump(4, 2)
       2    sp_instr_set(1, '1')
       3    sp_instr_hreturn(2)                 # frame size
       4    sp_instr_stmt('insert ... t3 ...')
       5    sp_instr_jump_if_not(7, 'x>0')
       6    sp_instr_stmt('insert ... t1 ...')
       7    sp_instr_hpop(2)

```

#### Cursors

  For stored procedures to be really useful, you want to have cursors. MySQL doesn't yet have "real" cursor support (with API and ODBC support, allowing updating, arbitrary scrolling, etc), but a simple asensitive, non-scrolling, read-only cursor can be implemented in SPs using the class Protocol\_cursor. This class intecepts the creation and sending of results sets and instead stores it in-memory, as MYSQL\_FIELDS and MYSQL\_ROWS (as in the client API).

  To support this, we need the usual name binding support in sp\_pcontext (similar to variables and conditions) to keep track on declared cursor names, and a corresponding run-time mechanism in sp\_rcontext. Cursors are lexically scoped like everything with a body or BEGIN/END block, so they are pushed and poped as usual (see conditions and variables above). The basic operations on a cursor are OPEN, FETCH and CLOSE, which will each have a corresponding instruction. In addition, we need instructions to push a new cursor (this will encapsulate the LEX of the SELECT statement of the cursor), and a pop instruction: - sp\_instr\_cpush Push a cursor to the sp\_rcontext. This instruction contains the LEX for the select statement - sp\_instr\_cpop Pop a number of cursors from the sp\_rcontext. - sp\_instr\_copen Open a cursor: This will execute the select and get the result set in a sepeate memroot. - sp\_instr\_cfetch Fetch the next row from the in-memory result set. The instruction contains a list of the variables (frame offsets) to set. - sp\_instr\_cclose Free the result set.

  A cursor is a separate class, sp\_cursor (defined in sp\_rcontex.h) which encapsulates the basic operations used by the above instructions. This class contains the LEX, Protocol\_cursor object, and its memroot, as well as the cursor's current state. Compiling and executing is fairly straight-forward. sp\_instr\_copen is a subclass of sp\_instr\_stmt and uses its mechanism to execute a substatement.

 ##### Example

 
```
      begin
        declare x int;
        declare c cursor for select a from t1;

        open c;
        fetch c into x;
        close c;
      end

```


```
      Pos.  Instruction
       0    sp_instr_cpush('select a from ...')
       1    sp_instr_copen(0)                   # The 0'th cursor
       2    sp_instr_cfetch(0)                  # Contains the variable list
       3    sp_instr_cclose(0)
       4    sp_instr_cpop(1)

```

#### The SP cache

  There are two ways to cache SPs:

 1. one global cache, share by all threads/connections,
2. one cache per thread.

  There are pros and cons with both methods:

 1. * Pros: Save memory, each SP only read from table once,
	* Cons: Needs locking (= serialization at access), requires thread-safe data structures,
2. * Pros: Fast, no locking required (almost), limited thread-safe requirement,
	* Cons: Uses more memory, each SP read from table once per thread.

  Unfortunately, we cannot use alternative 1 for the time being, as most of the data structures to be cached (lex and items) are not reentrant and thread-safe. (Things are modified at execution, we have THD pointers stored everywhere, etc.) This leaves us with alternative 2, one cache per thread; or actually two, since we keep FUNCTIONs and PROCEDUREs in separate caches. This is not that terrible; the only case when it will perform significantly worse than a global cache is when we have an application where new threads are connecting, calling a procedure, and disconnecting, over and over again.

  The cache implementation itself is simple and straightforward, a hashtable wrapped in a class and a C API (see APIs below).

  There is however one issue with multiple caches: dropping and altering procedures. Normally, this should be a very rare event in a running system; it's typically something you do during development and testing, so it's not unthinkable that we would simply ignore the issue and let any threads running with a cached version of an SP keep doing so until its disconnected. But assuming we want to keep the caches consistent with respect to drop and alter, it can be done:

 1. A global counter is needed, initialized to 0 at start.
2. At each DROP or ALTER, increase the counter by one.
3. Each cache has its own copy of the counter, copied at the last read.
4. When looking up a name in the cache, first check if the global counter is larger than the local copy. If so, clear the cache and return "not found", and update the local counter; otherwise, lookup as usual.

  This minimizes the cost to a single brief lock for the access of an integer when operating normally. Only in the event of an actual drop or alter, is the cache cleared. This may seem to be drastic, but since we assume that this is a rare event, it's not a problem. It would of course be possible to have a much more fine-grained solution, keeping track of each SP, but the overhead of doing so is not worth the effort.

 #### Class and Function APIs

  This is an outline of the key types. Some types and other details in the actual files have been omitted for readability.

 ##### The parser context: sp\_pcontext.h

 
```
      typedef enum
      {
        sp_param_in,
        sp_param_out,
        sp_param_inout
      } sp_param_mode_t;

      typedef struct
      {
        LEX_STRING name;
        enum enum_field_types type;
        sp_param_mode_t mode;
        uint offset;                    // Offset in current frame
        my_bool isset;
      } sp_pvar_t;

      typedef struct sp_cond_type
      {
        enum { number, state, warning, notfound, exception } type;
        char sqlstate[6];
        uint mysqlerr;
      } sp_cond_type_t;

      class sp_pcontext
      {
        sp_pcontext();

        // Return the maximum frame size
        uint max_framesize();

        // Return the current frame size
        uint current_framesize();

        // Return the number of parameters
        uint params();

        // Set the number of parameters to the current frame size
        void set_params();

        // Set type of the variable at offset 'i' in the frame
        void set_type(uint i, enum enum_field_types type);

        // Mark the i:th variable to "set" (i.e. having a value) with
        // 'val' true.
        void set_isset(uint i, my_bool val);

        // Push the variable 'name' to the frame.
        void push_var(LEX_STRING *name,
                      enum enum_field_types type, sp_param_mode_t mode);

        // Pop 'num' variables from the frame.
        void pop_var(uint num = 1);

        // Find variable by name
        sp_pvar_t *find_pvar(LEX_STRING *name);

        // Find variable by index
        sp_pvar_t *find_pvar(uint i);

        // Push label 'name' of instruction index 'ip' to the label context
        sp_label_t *push_label(char *name, uint ip);

        // Find label 'name' in the context
        sp_label_t *find_label(char *name);

        // Return the last pushed label
        sp_label_t *last_label();

        // Return and remove the last pushed label.
        sp_label_t *pop_label();

        // Push a condition to the context
        void push_cond(LEX_STRING *name, sp_cond_type_t *val);

        // Pop a 'num' condition from the context
        void pop_cond(uint num);

        // Find a condition in the context
        sp_cond_type_t *find_cond(LEX_STRING *name);

        // Increase the handler count
        void add_handler();

        // Returns the handler count
        uint handlers();

	// Push a cursor
        void push_cursor(LEX_STRING *name);

	// Find a cursor
	my_bool find_cursor(LEX_STRING *name, uint *poff);

	// Pop 'num' cursors
	void pop_cursor(uint num);

	// Return the number of cursors
	uint cursors();
      }

```

##### Run-time context (call frame): sp\_rcontext.h:

 
```
    #define SP_HANDLER_NONE      0
    #define SP_HANDLER_EXIT      1
    #define SP_HANDLER_CONTINUE  2
    #define SP_HANDLER_UNDO      3

    typedef struct
    {
      struct sp_cond_type *cond;
      uint handler;             // Location of handler
      int type;
      uint foffset;             // Frame offset for the handlers declare level
    } sp_handler_t;

    class sp_rcontext
    {
      // 'fsize' is the max size of the context, 'hmax' the number of handlers,
      // 'cmax' the number of cursors
      sp_rcontext(uint fsize, uint hmax, , uint cmax);

      // Push value (parameter) 'i' to the frame
      void push_item(Item *i);

      // Set slot 'idx' to value 'i'
      void set_item(uint idx, Item *i);

      // Return the item in slot 'idx'
      Item *get_item(uint idx);

      // Set the "out" index 'oidx' for slot 'idx. If it's an IN slot,
      // use 'oidx' -1.
      void set_oindex(uint idx, int oidx);

      // Return the "out" index for slot 'idx'
      int get_oindex(uint idx);

      // Set the FUNCTION result
      void set_result(Item *i);

      // Get the FUNCTION result
      Item *get_result();

      // Push handler at location 'h' for condition 'cond'. 'f' is the
      // current variable frame size.
      void push_handler(sp_cond_type_t *cond, uint h, int type, uint f);

      // Pop 'count' handlers
      void pop_handlers(uint count);

      // Find a handler for this error. This sets the state for a found
      // handler in the context. If called repeatedly without clearing,
      // only the first call's state is kept.
      int find_handler(uint sql_errno);

      // Returns 1 if a handler has been found, with '*ip' and '*fp' set
      // to the handler location and frame size respectively.
      int found_handler(uint *ip, uint *fp);

      // Clear the found handler state.
      void clear_handler();

      // Push a return address for a CONTINUE handler
      void push_hstack(uint ip);

      // Pop the CONTINUE handler return stack
      uint pop_hstack();

      // Save variables from frame index 'fp' and up.
      void save_variables(uint fp);

      // Restore saved variables from to frame index 'fp' and up.
      void restore_variables(uint fp);

      // Push a cursor for the statement (lex)
      void push_cursor(LEX *lex);

      // Pop 'count' cursors
      void pop_cursors(uint count);

      // Pop all cursors
      void pop_all_cursors();

      // Get the 'i'th cursor
      sp_cursor *get_cursor(uint i);

    }

```

##### The procedure: sp\_head.h:

 
```
      #define TYPE_ENUM_FUNCTION  1
      #define TYPE_ENUM_PROCEDURE 2

      class sp_head
      {
        int m_type;             // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE

        sp_head();

        void init(LEX_STRING *name, LEX *lex, LEX_STRING *comment, char suid);

        // Store this procedure in the database. This is a wrapper around
        // the function sp_create_procedure().
        int create(THD *);

        // Invoke a FUNCTION
        int
        execute_function(THD *thd, Item **args, uint argcount, Item **resp);

        // CALL a PROCEDURE
        int
        execute_procedure(THD *thd, List<Item> *args);

        // Add the instruction to this procedure.
        void add_instr(sp_instr *);

        // Returns the number of instructions.
        uint instructions();

        // Returns the last instruction
        sp_instr *last_instruction();

        // Resets lex in 'thd' and keeps a copy of the old one.
        void reset_lex(THD *);

        // Restores lex in 'thd' from our copy, but keeps some status from the
        // one in 'thd', like ptr, tables, fields, etc.
        void restore_lex(THD *);

        // Put the instruction on the backpatch list, associated with
        // the label.
        void push_backpatch(sp_instr *, struct sp_label *);

        // Update all instruction with this label in the backpatch list to
        // the current position.
        void backpatch(struct sp_label *);

        // Returns the SP name (with optional length in '*lenp').
        char *name(uint *lenp = 0);

        // Returns the result type for a function
        Item_result result();

        // Sets various attributes
        void sp_set_info(char *creator, uint creatorlen,
                         longlong created, longlong modified,
                         bool suid, char *comment, uint commentlen);
      }

```

##### Instructions

 ##### The base class

 
```
        class sp_instr
        {
          // 'ip' is the index of this instruction
          sp_instr(uint ip);

          // Execute this instrution.
          // '*nextp' will be set to the index of the next instruction
          // to execute. (For most instruction this will be the
          // instruction following this one.)
          // Returns 0 on success, non-zero if some error occurred.
          virtual int execute(THD *, uint *nextp)
        }
<<code>>


===== Statement instruction
<<code>>
        class sp_instr_stmt : public sp_instr
        {
          sp_instr_stmt(uint ip);

          int execute(THD *, uint *nextp);

          // Set the statement's Lex
          void set_lex(LEX *);

          // Return the statement's Lex
          LEX *get_lex();
        }

```

##### SET instruction

 
```
        class sp_instr_set : public sp_instr
        {
          // 'offset' is the variable's frame offset, 'val' the value,
          // and 'type' the variable type.
          sp_instr_set(uint ip,
                       uint offset, Item *val, enum enum_field_types type);

          int execute(THD *, uint *nextp);
        }

```

##### Unconditional jump

 
```
        class sp_instr_jump : public sp_instr
        {
          // No destination, must be set.
          sp_instr_jump(uint ip);

          // 'dest' is the destination instruction index.
          sp_instr_jump(uint ip, uint dest);

          int execute(THD *, uint *nextp);

          // Set the destination instruction 'dest'.
          void set_destination(uint dest);
        }

```

##### Conditional jump

 
```
        class sp_instr_jump_if_not : public sp_instr_jump
        {
          // Jump if 'i' evaluates to false. Destination not set yet.
          sp_instr_jump_if_not(uint ip, Item *i);

          // Jump to 'dest' if 'i' evaluates to false.
          sp_instr_jump_if_not(uint ip, Item *i, uint dest)

          int execute(THD *, uint *nextp);
        }

```

##### Return a function value

 
```
        class sp_instr_freturn : public sp_instr
        {
          // Return the value 'val'
          sp_instr_freturn(uint ip, Item *val, enum enum_field_types type);
          
          int execute(THD *thd, uint *nextp);
        }

```

##### Push a handler and jump

 
```
        class sp_instr_hpush_jump : public sp_instr_jump
        {
          // Push handler of type 'htype', with current frame size 'fp'
          sp_instr_hpush_jump(uint ip, int htype, uint fp);

          int execute(THD *thd, uint *nextp);

          // Add condition for this handler
          void add_condition(struct sp_cond_type *cond);
        }

```

##### Pops handlers

 
```
        class sp_instr_hpop : public sp_instr
        {
          // Pop 'count' handlers
          sp_instr_hpop(uint ip, uint count);

          int execute(THD *thd, uint *nextp);
        }

```

##### Return from a CONTINUE handler

 
```
        class sp_instr_hreturn : public sp_instr
        {
          // Return from handler, and restore variables to 'fp'.
          sp_instr_hreturn(uint ip, uint fp);

          int execute(THD *thd, uint *nextp);
        }

```

##### Push a CURSOR

 
```
        class sp_instr_cpush : public sp_instr_stmt
	{
          // Push a cursor for statement 'lex'
	  sp_instr_cpush(uint ip, LEX *lex)

	  int execute(THD *thd, uint *nextp);
        }

```

##### Pop CURSORs

 
```
        class sp_instr_cpop : public sp_instr_stmt
	{
          // Pop 'count' cursors
	  sp_instr_cpop(uint ip, uint count)

	  int execute(THD *thd, uint *nextp);
        }

```

##### Open a CURSOR

 
```
        class sp_instr_copen : public sp_instr_stmt
	{
          // Open the 'c'th cursor
	  sp_instr_copen(uint ip, uint c);

	  int execute(THD *thd, uint *nextp);
        }

```

##### Close a CURSOR

 
```
        class sp_instr_cclose : public sp_instr
	{
          // Close the 'c'th cursor
	  sp_instr_cclose(uint ip, uint c);

	  int execute(THD *thd, uint *nextp);
        }

```

##### Fetch a row with CURSOR

 
```
        class sp_instr_cfetch : public sp_instr
	{
          // Fetch next with the 'c'th cursor
	  sp_instr_cfetch(uint ip, uint c);

	  int execute(THD *thd, uint *nextp);

	  // Add a target variable for the fetch
	  void add_to_varlist(struct sp_pvar *var);
        }

```

##### Utility functions: sp.h

 
```
      #define SP_OK                 0
      #define SP_KEY_NOT_FOUND     -1
      #define SP_OPEN_TABLE_FAILED -2
      #define SP_WRITE_ROW_FAILED  -3
      #define SP_DELETE_ROW_FAILED -4
      #define SP_GET_FIELD_FAILED  -5
      #define SP_PARSE_ERROR       -6

      // Finds a stored procedure given its name. Returns NULL if not found.
      sp_head *sp_find_procedure(THD *, LEX_STRING *name);

      // Store the procedure 'name' in the database. 'def' is the complete
      // definition string ("create procedure ...").
      int sp_create_procedure(THD *,
                              char *name, uint namelen,
                              char *def, uint deflen,
                              char *comment, uint commentlen, bool suid);

      // Drop the procedure 'name' from the database.
      int sp_drop_procedure(THD *, char *name, uint namelen);

      // Finds a stored function given its name. Returns NULL if not found.
      sp_head *sp_find_function(THD *, LEX_STRING *name);

      // Store the function 'name' in the database. 'def' is the complete
      // definition string ("create function ...").
      int sp_create_function(THD *,
                             char *name, uint namelen,
                             char *def, uint deflen,
                             char *comment, uint commentlen, bool suid);

      // Drop the function 'name' from the database.
      int sp_drop_function(THD *, char *name, uint namelen);

```

##### The cache: sp\_cache.h

 
```
      /* Initialize the SP caching once at startup */
      void sp_cache_init();

      /* Clear the cache *cp and set *cp to NULL */
      void sp_cache_clear(sp_cache **cp);

      /* Insert an SP to cache. If **cp points to NULL, it's set to a
         new cache */
      void sp_cache_insert(sp_cache **cp, sp_head *sp);

      /* Lookup an SP in cache */
      sp_head *sp_cache_lookup(sp_cache **cp, char *name, uint namelen);

      /* Remove an SP from cache */
      void sp_cache_remove(sp_cache **cp, sp_head *sp);

```

### The mysql.proc schema

 This is the [mysql.proc table](../mysqlproc-table/index) used in [MariaDB 10.4](../what-is-mariadb-104/index):

 
```
CREATE TABLE `proc` (
  `db` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
  `name` char(64) NOT NULL DEFAULT '',
  `type` enum('FUNCTION','PROCEDURE','PACKAGE','PACKAGE BODY') NOT NULL,
  `specific_name` char(64) NOT NULL DEFAULT '',
  `language` enum('SQL') NOT NULL DEFAULT 'SQL',
  `sql_data_access` enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA') NOT NULL DEFAULT 'CONTAINS_SQL',
  `is_deterministic` enum('YES','NO') NOT NULL DEFAULT 'NO',
  `security_type` enum('INVOKER','DEFINER') NOT NULL DEFAULT 'DEFINER',
  `param_list` blob NOT NULL,
  `returns` longblob NOT NULL,
  `body` longblob NOT NULL,
  `definer` char(141) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
  `created` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `sql_mode` set('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','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') NOT NULL DEFAULT '',
  `comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  `db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  `body_utf8` longblob DEFAULT NULL,
  `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE',
  PRIMARY KEY (`db`,`name`,`type`)
) ENGINE=Aria DEFAULT CHARSET=utf8 PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Stored Procedures'

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-procedure-internals/>

Delimiters
==========

    The default delimiter in the [mariadb](../mariadb-client/index) client is the semicolon.

 When creating [stored programs](../stored-programs-and-views/index) from the command-line, it is likely you will need to differentiate between the regular delimiter and a delimiter inside a [BEGIN END](../begin-end/index) block. To understand better, consider the following example:

 
```
CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
 DECLARE x TINYINT;
 SET x = 42;
 RETURN x;
END; 

```

If you enter the above line by line, the mariadb client will treat the first semicolon, at the end of the `DECLARE x TINYINT` line, as the end of the statement. Since that's only a partial definition, it will throw a syntax error, as follows:

 
```
CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
DECLARE x TINYINT;
ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version
 for the right syntax to use near '' at line 3

```

The solution is to specify a distinct delimiter for the duration of the process, using the DELIMITER command. The delimiter can be any set of characters you choose, but it needs to be a distinctive set of characters that won't cause further confusion. `//` is a common choice, and used throughout the Knowledge Base.

 Here's how the function could be successfully entered from the mariadb client with the new delimiter.

 
```
DELIMITER //

CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
  DECLARE x TINYINT;
  SET x = 42;
  RETURN x;
END 

//

DELIMITER ;

```

At the end, the delimiter is restored to the default semicolon. The `\g` and `\G` delimiters can always be used, even when a custom delimiter is specified.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/delimiters/>

Scalar Subqueries
=================

    A scalar subquery is a [subquery](../subqueries/index) that returns a single value. This is the simplest form of a subquery, and can be used in most places a literal or single column value is valid.

 The data type, length and [character set and collation](../data-types-character-sets-and-collations/index) are all taken from the result returned by the subquery. The result of a subquery can always be NULL, that is, no result returned. Even if the original value is defined as NOT NULL, this is disregarded.

 A subquery cannot be used where only a literal is expected, for example [LOAD DATA INFILE](../load-data-infile/index) expects a literal string containing the file name, and LIMIT requires a literal integer.

 Examples
--------

 
```
CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num TINYINT);

INSERT INTO sq1 VALUES (1);

INSERT INTO sq2 VALUES (10* (SELECT num FROM sq1));

SELECT * FROM sq2;
+------+
| num  |
+------+
|   10 |
+------+

```

Inserting a second row means the subquery is no longer a scalar, and this particular query is not valid:

 
```
INSERT INTO sq1 VALUES (2);

INSERT INTO sq2 VALUES (10* (SELECT num FROM sq1));
ERROR 1242 (21000): Subquery returns more than 1 row

```

No rows in the subquery, so the scalar is NULL:

 
```
INSERT INTO sq2 VALUES (10* (SELECT num FROM sq3 WHERE num='3'));

SELECT * FROM sq2;
+------+
| num  |
+------+
|   10 |
| NULL |
+------+

```

A more traditional scalar subquery, as part of a WHERE clause:

 
```
SELECT * FROM sq1 WHERE num = (SELECT MAX(num)/10 FROM sq2); 
+------+
| num  |
+------+
|    1 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-scalar-subqueries/>

Cursor Overview
===============

    Description
-----------

 A cursor is a structure that allows you to go over records sequentially, and perform processing based on the result.

 MariaDB permits cursors inside [stored programs](../stored-programs-and-views/index), and MariaDB cursors are non-scrollable, read-only and asensitive.

 * Non-scrollable means that the rows can only be fetched in the order specified by the SELECT statement. Rows cannot be skipped, you cannot jump to a specific row, and you cannot fetch rows in reverse order.
* Read-only means that data cannot be updated through the cursor.
* Asensitive means that the cursor points to the actual underlying data. This kind of cursor is quicker than the alternative, an insensitive cursor, as no data is copied to a temporary table. However, changes to the data being used by the cursor will affect the cursor data.

 Cursors are created with a [DECLARE CURSOR](../declare-cursor/index) statement and opened with an [OPEN](../open/index) statement. Rows are read with a [FETCH](../fetch/index) statement before the cursor is finally closed with a [CLOSE](../close/index) statement.

 When FETCH is issued and there are no more rows to extract, the following error is produced:

 
```
ERROR 1329 (02000): No data - zero rows fetched, selected, or processed

```

To avoid problems, a [DECLARE HANDLER](../declare-handler/index) statement is generally used. The HANDLER should handler the 1329 error, or the '02000' [SQLSTATE](../sqlstate/index), or the NOT FOUND error class.

 Only [SELECT](../select/index) statements are allowed for cursors, and they cannot be contained in a variable - so, they cannot be composed dynamically. However, it is possible to SELECT from a view. Since the [CREATE VIEW](../create-view/index) statement can be executed as a prepared statement, it is possible to dynamically create the view that is queried by the cursor.

 From [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/), cursors can have parameters. Cursor parameters can appear in any part of the [DECLARE CURSOR](../declare-cursor/index) select\_statement where a stored procedure variable is allowed (select list, WHERE, HAVING, LIMIT etc). See [DECLARE CURSOR](../declare-cursor/index) and [OPEN](../open/index) for syntax, and below for an example:

 Examples
--------

 
```
CREATE TABLE c1(i INT);

CREATE TABLE c2(i INT);

CREATE TABLE c3(i INT);

DELIMITER //

CREATE PROCEDURE p1()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE x, y INT;
  DECLARE cur1 CURSOR FOR SELECT i FROM test.c1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.c2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO x;
    FETCH cur2 INTO y;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF x < y THEN
      INSERT INTO test.c3 VALUES (x);
    ELSE
      INSERT INTO test.c3 VALUES (y);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END; //

DELIMITER ;

INSERT INTO c1 VALUES(5),(50),(500);

INSERT INTO c2 VALUES(10),(20),(30);

CALL p1;

SELECT * FROM c3;
+------+
| i    |
+------+
|    5 |
|   20 |
|   30 |
+------+

```

From [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)

 
```
DROP PROCEDURE IF EXISTS p1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b VARCHAR(10));

INSERT INTO t1 VALUES (1,'old'),(2,'old'),(3,'old'),(4,'old'),(5,'old');

DELIMITER //

CREATE PROCEDURE p1(min INT,max INT)
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE va INT;
  DECLARE cur CURSOR(pmin INT, pmax INT) FOR SELECT a FROM t1 WHERE a BETWEEN pmin AND pmax;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=TRUE;
  OPEN cur(min,max);
  read_loop: LOOP
    FETCH cur INTO va;
    IF done THEN
      LEAVE read_loop;
    END IF;
    INSERT INTO t1 VALUES (va,'new');
  END LOOP;
  CLOSE cur; 
END;
//

DELIMITER ;

CALL p1(2,4);

SELECT * FROM t1;
+------+------+
| a    | b    |
+------+------+
|    1 | old  |
|    2 | old  |
|    3 | old  |
|    4 | old  |
|    5 | old  |
|    2 | new  |
|    3 | new  |
|    4 | new  |
+------+------+

```

See Also
--------

 * [DECLARE CURSOR](../declare-cursor/index)
* [OPEN cursor\_name](../open/index)
* [FETCH cursor\_name](../fetch/index)
* [CLOSE cursor\_name](../close/index)
* [Cursors in Oracle mode](../sql_modeoracle-from-mariadb-103/index#cursors)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cursor-overview/>

Stored Function Overview
========================

     A Stored Function is a defined function that is called from within an SQL statement like a regular function, and returns a single value.   
   


 Creating Stored Functions
-------------------------

 Here's a skeleton example to see a stored function in action:   
   


 
```
DELIMITER //

CREATE FUNCTION FortyTwo() RETURNS TINYINT DETERMINISTIC
BEGIN
 DECLARE x TINYINT;
 SET x = 42;
 RETURN x;
END 

//

DELIMITER ;

```

First, the delimiter is changed, since the function definition will contain the regular semicolon delimiter. See [Delimiters in the mariadb client](../delimiters/index) for more. Then the function is named `FortyTwo` and defined to return a `tinyin`. The `DETERMINISTIC` keyword is not necessary in all cases (although if binary logging is on, leaving it out will throw an error), and is to help the query optimizer choose a query plan. A deterministic function is one that, given the same arguments, will always return the same result. 

 Next, the function body is placed between [BEGIN and END](../begin-end/index) statements. It declares a tinyint, `X`, which is simply set to 42, and this is the result returned.

 
```
SELECT FortyTwo();
+------------+
| FortyTwo() |
+------------+
|         42 |
+------------+

```

Of course, a function that doesn't take any arguments is of little use. Here's a more complex example:

 
```
DELIMITER //
CREATE FUNCTION VatCents(price DECIMAL(10,2)) RETURNS INT DETERMINISTIC
BEGIN
 DECLARE x INT;
 SET x = price * 114;
 RETURN x;
END //
Query OK, 0 rows affected (0.04 sec)
DELIMITER ;

```

This function takes an argument, `price` which is defined as a DECIMAL, and returns an INT.

 Take a look at the [CREATE FUNCTION](../create-function/index) page for more details.

 From [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), it is also possible to create [stored aggregate functions](../stored-aggregate-functions/index).

 Stored Function listings and definitions
----------------------------------------

 To find which stored functions are running on the server, use [SHOW FUNCTION STATUS](../show-function-status/index).

 
```
SHOW FUNCTION STATUS\G
*************************** 1. row ***************************
                  Db: test
                Name: VatCents
                Type: FUNCTION
             Definer: root@localhost
            Modified: 2013-06-01 12:40:31
             Created: 2013-06-01 12:40:31
       Security_type: DEFINER
             Comment: 
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)

```

or query the [routines table](../information-schema-routines-table/index) in the INFORMATION\_SCHEMA database directly:

 
```
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE
  ROUTINE_TYPE='FUNCTION';
+--------------+
| ROUTINE_NAME |
+--------------+
| VatCents     |
+--------------+

```

To find out what the stored function does, use [SHOW CREATE FUNCTION](../show-create-function/index).

 
```
SHOW CREATE FUNCTION VatCents\G
*************************** 1. row ***************************
            Function: VatCents
            sql_mode: 
     Create Function: CREATE DEFINER=`root`@`localhost` FUNCTION `VatCents`(price DECIMAL(10,2)) RETURNS int(11)
    DETERMINISTIC
BEGIN
 DECLARE x INT;
 SET x = price * 114;
 RETURN x;
END
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

Dropping and Updating Stored Functions
--------------------------------------

 To drop a stored function, use the [DROP FUNCTION](../drop-function/index) statement.

 
```
DROP FUNCTION FortyTwo;

```

To change the characteristics of a stored function, use [ALTER FUNCTION](../alter-function/index). Note that you cannot change the parameters or body of a stored function using this statement; to make such changes, you must drop and re-create the function using DROP FUNCTION and CREATE FUNCTION.

 Permissions in Stored Functions
-------------------------------

 See the article [Stored Routine Privileges](../stored-routine-privileges/index).

 See Also
--------

 * [CREATE FUNCTION](../create-function/index)
* [SHOW CREATE FUNCTION](../show-create-function/index)
* [DROP FUNCTION](../drop-function/index)
* [Stored Routine Privileges](../stored-routine-privileges/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [Information Schema ROUTINES Table](../information-schema-routines-table/index)
* [Stored Aggregate Functions](../stored-aggregate-functions/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stored-function-overview/>

LIMIT
=====

    Description
-----------

 Use the `LIMIT` clause to restrict the number of returned rows. When you use a single integer *n* with `LIMIT`, the first *n* rows will be returned. Use the [ORDER BY](../order-by/index) clause to control which rows come first. You can also select a number of rows after an offset using either of the following:

 
```
LIMIT offset, row_count
LIMIT row_count OFFSET offset

```

When you provide an offset *m* with a limit *n*, the first *m* rows will be ignored, and the following *n* rows will be returned.

 Executing an [UPDATE](../update/index) with the `LIMIT` clause is not safe for replication. `LIMIT 0` is an exception to this rule (see [MDEV-6170](https://jira.mariadb.org/browse/MDEV-6170)).

 There is a [LIMIT ROWS EXAMINED](../limit-rows-examined/index) optimization which provides the means to terminate the execution of [SELECT](../select/index) statements which examine too many rows, and thus use too many resources. See [LIMIT ROWS EXAMINED](../limit-rows-examined/index).

 ### Multi-Table Updates

 
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**Until [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/), it was not possible to use `LIMIT` (or [ORDER BY](../order-by/index)) in a multi-table [UPDATE](../update/index) statement. This restriction was lifted in [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/).

 
### GROUP\_CONCAT

 
**MariaDB starting with [10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/)**Starting from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), it is possible to use `LIMIT` with [GROUP\_CONCAT()](../group_concat/index).

 
Examples
--------

 
```
CREATE TABLE members (name VARCHAR(20));
INSERT INTO members VALUES('Jagdish'),('Kenny'),('Rokurou'),('Immaculada');

SELECT * FROM members;
+------------+
| name       |
+------------+
| Jagdish    |
| Kenny      |
| Rokurou    |
| Immaculada |
+------------+

```

Select the first two names (no ordering specified):

 
```
SELECT * FROM members LIMIT 2;
+---------+
| name    |
+---------+
| Jagdish |
| Kenny   |
+---------+

```

All the names in alphabetical order:

 
```
SELECT * FROM members ORDER BY name;
+------------+
| name       |
+------------+
| Immaculada |
| Jagdish    |
| Kenny      |
| Rokurou    |
+------------+

```

The first two names, ordered alphabetically:

 
```
SELECT * FROM members ORDER BY name LIMIT 2;
+------------+
| name       |
+------------+
| Immaculada |
| Jagdish    |
+------------+

```

The third name, ordered alphabetically (the first name would be offset zero, so the third is offset two):

 
```
SELECT * FROM members ORDER BY name LIMIT 2,1;
+-------+
| name  |
+-------+
| Kenny |
+-------+

```

From [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/), `LIMIT` can be used in a multi-table update:

 
```
CREATE TABLE warehouse (product_id INT, qty INT);
INSERT INTO warehouse VALUES (1,100),(2,100),(3,100),(4,100);

CREATE TABLE store (product_id INT, qty INT);
INSERT INTO store VALUES (1,5),(2,5),(3,5),(4,5);

UPDATE warehouse,store SET warehouse.qty = warehouse.qty-2, store.qty = store.qty+2 
  WHERE (warehouse.product_id = store.product_id AND store.product_id  >= 1) 
    ORDER BY store.product_id DESC LIMIT 2;

SELECT * FROM warehouse;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |  100 |
|          2 |  100 |
|          3 |   98 |
|          4 |   98 |
+------------+------+

SELECT * FROM store;
+------------+------+
| product_id | qty  |
+------------+------+
|          1 |    5 |
|          2 |    5 |
|          3 |    7 |
|          4 |    7 |
+------------+------+

```

From [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/), `LIMIT` can be used with [GROUP\_CONCAT](../group_concat/index), so, for example, given the following table:

 
```
CREATE TABLE d (dd DATE, cc INT);

INSERT INTO d VALUES ('2017-01-01',1);
INSERT INTO d VALUES ('2017-01-02',2);
INSERT INTO d VALUES ('2017-01-04',3);

```

the following query:

 
```
SELECT SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) FROM d;
+----------------------------------------------------------------------------+
| SUBSTRING_INDEX(GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC),",",1) |
+----------------------------------------------------------------------------+
| 2017-01-04:3                                                               |
+----------------------------------------------------------------------------+

```

can be more simply rewritten as:

 
```
SELECT GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) FROM d;
+-------------------------------------------------------------+
| GROUP_CONCAT(CONCAT_WS(":",dd,cc) ORDER BY cc DESC LIMIT 1) |
+-------------------------------------------------------------+
| 2017-01-04:3                                                |
+-------------------------------------------------------------+

```

See Also
--------

 * [ROWNUM() function](../rownum/index)
* [SELECT](../select/index)
* [UPDATE](../update/index)
* [DELETE](../delete/index)
* [Joins and Subqueries](../joins-subqueries/index)
* [ORDER BY](../order-by/index)
* [GROUP BY](../group-by/index)
* [Common Table Expressions](../common-table-expressions/index)
* [SELECT WITH ROLLUP](../select-with-rollup/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* [FOR UPDATE](../for-update/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [Optimizer Hints](../optimizer-hints/index)
* [SELECT ... OFFSET ... FETCH](../select-offset-fetch/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/limit/>

SELECT INTO OUTFILE
===================

    Syntax
------

 
```
SELECT ... INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        [export_options]

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]

```
 Description
-----------

 `SELECT INTO OUTFILE` writes the resulting rows to a file, and allows the use of column and row terminators to specify a particular output format. The default is to terminate fields with tabs (`\t`) and lines with newlines (`\n`).

 The file must not exist. It cannot be overwritten. A user needs the [FILE](../grant/index#global-privileges) privilege to run this statement. Also, MariaDB needs permission to write files in the specified location. If the [secure\_file\_priv](../server-system-variables/index#secure_file_priv) system variable is set to a non-empty directory name, the file can only be written to that directory.

 The `[LOAD DATA INFILE](../load-data-infile/index)` statement complements `SELECT INTO OUTFILE`.

 ### Character-sets

 The `CHARACTER SET` clause specifies the [character set](../data-types-character-sets-and-collations/index) in which the results are to be written. Without the clause, no conversion takes place (the binary character set). In this case, if there are multiple character sets, the output will contain these too, and may not easily be able to be reloaded.

 In cases where you have two servers using different character-sets, using `SELECT INTO OUTFILE` to transfer data from one to the other can have unexpected results. To ensure that MariaDB correctly interprets the escape sequences, use the `CHARACTER SET` clause on both the `SELECT INTO OUTFILE` statement and the subsequent `[LOAD DATA INFILE](../load-data-infile/index)` statement.

 Example
-------

 The following example produces a file in the CSV format:

 
```
SELECT customer_id, firstname, surname from customer
  INTO OUTFILE '/exportdata/customers.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n';

```

The following ANSI syntax is also supported for simple `SELECT` without `UNION`

 
```
SELECT customer_id, firstname, surname INTO OUTFILE '/exportdata/customers.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM customers;

```

If you want to use the ANSI syntax with `UNION` or similar construct you have to use the syntax:

 
```
SELECT  * INTO OUTFILE "/tmp/skr3" FROM (SELECT * FROM t1 UNION SELECT * FROM t1);

```

See Also
--------

 * [SELECT](../select/index)
* [LOAD\_DATA()](../load_file/index) function
* [LOAD DATA INFILE](../load-data-infile/index)
* [SELECT INTO Variable](../select-into-variable/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select-into-outfile/>

SELECT INTO DUMPFILE
====================

    Syntax
------

 
```
SELECT ... INTO DUMPFILE 'file_path'

```

Description
-----------

 `SELECT ... INTO DUMPFILE` is a [SELECT](../select/index) clause which writes the resultset into a single unformatted row, without any separators, in a file. The results will not be returned to the client.

 *file\_path* can be an absolute path, or a relative path starting from the data directory. It can only be specified as a [string literal](../string-literals/index), not as a variable. However, the statement can be dynamically composed and executed as a prepared statement to work around this limitation.

 This statement is binary-safe and so is particularly useful for writing [BLOB](../blob/index) values to file. It can be used, for example, to copy an image or an audio document from the database to a file. SELECT ... INTO FILE can be used to save a text file.

 The file must not exist. It cannot be overwritten. A user needs the [FILE](../grant/index#global-privileges) privilege to run this statement. Also, MariaDB needs permission to write files in the specified location. If the [secure\_file\_priv](../server-system-variables/index#secure_file_priv) system variable is set to a non-empty directory name, the file can only be written to that directory.

 Since [MariaDB 5.1](../what-is-mariadb-51/index), the [character\_set\_filesystem](../server-system-variables/index#character_set_filesystem) system variable has controlled interpretation of file names that are given as literal strings.

 Example
-------

 
```
SELECT _utf8'Hello world!' INTO DUMPFILE '/tmp/world';

SELECT LOAD_FILE('/tmp/world') AS world;
+--------------+
| world        |
+--------------+
| Hello world! |
+--------------+

```

See Also
--------

 * [SELECT](../select/index)
* [LOAD\_FILE()](../load_file/index)
* [SELECT INTO Variable](../select-into-variable/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select-into-dumpfile/>

User Variables Plugin
=====================

    The `user_variables` plugin creates the [USER\_VARIABLES](../information-schema-user_variables-table/index) table in the [INFORMATION\_SCHEMA](../information-schema/index) database. This table contains information about [user-defined variables](../user-defined-variables/index).

 Installing the Plugin
---------------------

 In current versions, the `user_variables` plugin is statically linked into the server by default, so it does not need to be installed.

 Prior to [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/), although the plugin's shared library is distributed with MariaDB by default, the plugin was not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'user_variables';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = user_variables

```

Uninstalling the Plugin
-----------------------

 You can uninstall the plugin dynamically by executing [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index). For example:

 
```
UNINSTALL SONAME 'user_variables';

```

If you installed the plugin by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Examples
--------

 
```
SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| var           | 0              | INT           | utf8               |
| var2          | abc            | VARCHAR       | utf8               |
+---------------+----------------+---------------+--------------------+

```

### Flushing User-Defined Variables

 User-defined variables are reset and the Information Schema table emptied with the [FLUSH USER\_VARIABLES](../flush/index) statement.

 
```
SET @str = CAST(123 AS CHAR(5));

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
+---------------+----------------+---------------+--------------------+
| VARIABLE_NAME | VARIABLE_VALUE | VARIABLE_TYPE | CHARACTER_SET_NAME |
+---------------+----------------+---------------+--------------------+
| str           | 123            | VARCHAR       | utf8mb3            |
+---------------+----------------+---------------+--------------------+

FLUSH USER_VARIABLES;

SELECT * FROM information_schema.USER_VARIABLES ORDER BY VARIABLE_NAME;
Empty set (0.000 sec)

```

Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Stable | [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) |
| 1.0 | Gamma | [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) |
| 1.0 | Alpha | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |

 
Options
-------

 ### `user_variables`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the [mysql.plugins](../mysqlplugin-table/index) table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with [UNINSTALL SONAME](../uninstall-soname/index) or [UNINSTALL PLUGIN](../uninstall-plugin/index) while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--user-variables=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-variables-plugin/>

CLOSE
=====

    Syntax
------

 
```
CLOSE cursor_name

```
 Description
-----------

 This statement closes a previously [opened](../open/index) cursor. The cursor must have been previously opened or else an error occurs.

 If not closed explicitly, a cursor is closed at the end of the compound statement in which it was declared.

 See [Cursor Overview](../cursor-overview/index) for an example.

 See Also
--------

 * [Cursor Overview](../cursor-overview/index)
* [DECLARE CURSOR](../declare-cursor/index)
* [OPEN cursor\_name](../open/index)
* [FETCH cursor\_name](../fetch/index)
* [Cursors in Oracle mode](../sql_modeoracle-from-mariadb-103/index#cursors)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/close/>

Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Setup Guide
====================================================================================

    Overview
--------

 MariaDB contains a robust, full instance, at-rest encryption. This feature uses a flexible plugin interface to allow actual encryption to be done using a key management approach that meets the customer's needs. MariaDB Server, starting with [MariaDB 10.2](../what-is-mariadb-102/index), includes a plugin that uses the Amazon Web Services (AWS) Key Management Service (KMS) to facilitate separation of responsibilities and remote logging & auditing of key access requests.

 Rather than storing the encryption key in a local file, this plugin keeps the master key in AWS KMS. When you first start MariaDB, the AWS KMS plugin will connect to the AWS Key Management Service and ask it to generate a new key. MariaDB will store that key on-disk in an encrypted form. The key stored on-disk cannot be used to decrypt the data; rather, on each startup, MariaDB connects to AWS KMS and has the service decrypt the locally-stored key(s). The decrypted key is stored in-memory as long as the MariaDB server process is running, and that in-memory decrypted key is used to encrypt the local data.

 This guide is based on CentOS 7, using systemd with SELinux enabled. Some steps will differ if you use other operating systems or configurations.

 Installing the Plugin's Package
-------------------------------

 The AWS Key Management plugin depends on the [AWS SDK for C++](https://github.com/aws/aws-sdk-cpp), which uses the [Apache License, Version 2.0](https://github.com/aws/aws-sdk-cpp/blob/master/LICENSE). This license is not compatible with MariaDB Server's [GPL 2.0 license](../mariadb-license/index), so we are not able to distribute packages that contain the AWS Key Management plugin. Therefore, the only way to currently obtain the plugin is to install it from source.

 ### Installing from Source

 When [compiling MariaDB from source](../compiling-mariadb-from-source/index), the AWS Key Management plugin is not built by default in [MariaDB 10.1](../what-is-mariadb-101/index), but it is built by default in [MariaDB 10.2](../what-is-mariadb-102/index) and later, on systems that support it.

 Compilation is controlled by the `-DPLUGIN_AWS_KEY_MANAGEMENT=DYNAMIC -DAWS_SDK_EXTERNAL_PROJECT=1` [cmake](../generic-build-instructions/index#using-cmake) arguments.

 The plugin uses [AWS C++ SDK](https://github.com/awslabs/aws-sdk-cpp), which introduces the following restrictions:

 * The plugin can only be built on Windows, Linux and macOS.
* The plugin requires that one of the following compilers is used: `gcc` 4.8 or later, `clang` 3.3 or later, Visual Studio 2013 or later.
* On Unix, the `libcurl` development package (e.g. `libcurl3-dev` on Debian Jessie), `uuid` development package and `openssl` need to be installed.
* You may need to use a newer version of [cmake](../generic-build-instructions/index#using-cmake) than is provided by default in your OS.

 Installing the Plugin
---------------------

 Even after the package that contains the plugin's shared library is installed on the operating system, the plugin is not actually installed by MariaDB by default. There are two methods that can be used to install the plugin with MariaDB.

 The first method can be used to install the plugin without restarting the server. You can install the plugin dynamically by executing [INSTALL SONAME](../install-soname/index) or [INSTALL PLUGIN](../install-plugin/index). For example:

 
```
INSTALL SONAME 'aws_key_management';

```

The second method can be used to tell the server to load the plugin when it starts up. The plugin can be installed this way by providing the [--plugin-load](../mysqld-options/index#-plugin-load) or the [--plugin-load-add](../mysqld-options/index#-plugin-load-add) options. This can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = aws_key_management

```

Sign up for Amazon Web Services
-------------------------------

 If you already have an AWS account, you can skip this section.

 1. Load <http://aws.amazon.com/>.
2. Click "Create a Free Account" and complete the steps.
3. You'll need to enter credit card information. Charges related only to your use of the AWS KMS service should be limited to about $1/month for the single master key we will create. If you use other services, additional charges may apply. Consult AWS Cloud Pricing Principles <https://aws.amazon.com/pricing/> for more information about pricing of AWS services.
4. You'll need to complete the AWS identify verification process.

 Create an IAM User and/or Role
------------------------------

 After creating an account or logging in to an existing account, follow these steps to create an IAM User or Role with restricted privileges that will use (but not administer) your master encryption key.

 If you intend to run MariaDB Server on an EC2 instance, you should create a Role (or modify an existing Role already attached to your instance). If you intent to run MariaDB Server outside of AWS, you may want to create a User.

 ### Creating an IAM Role

 1. Load the Identity and Access Management Console at <https://console.aws.amazon.com/iam/>.
2. Click "Roles" in the left-hand sidebar
3. Click "Create new role"
4. Select "AWS Service Role"
5. Click the "Select" button next to "Amazon EC2 / Allows EC2 instances to call AWS services on your behalf."
6. Do not select any policies on the "Attach Policy" screen. Click "Next Step"
7. Click "Next Step"
8. Give your Role a "Role name"
9. Click "Create role"

 ### Creating an IAM User

 1. Load the Identity and Access Management Console at <https://console.aws.amazon.com/iam/>.
2. Click "Users" in the left-hand sidebar.  
 [![](https://mariadb.com/kb/en/key-management-and-encryption-plugins-amazon-web-services-aws-key-managemen/+image/aws-kms-create-new-user)](https://mariadb.com/kb/en/mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/+image/aws-kms-create-new-user)
3. Click the "Create New Users" button
4. Enter a single User Name of your choosing. We'll use "MDBEnc" for this demonstration. Keep the "Generate an access key for each user" box checked.  
 [![]
5. Click "Create".
6. Click "Show User Security Credentials".  
 [![]
7. Copy the Access Key ID and Secret Access Key. Optionally, you can click "Download Credentials". We will need these in order for local programs to interact with AWS using its API.  
 [![](https://mariadb.com/kb/en/key-management-and-encryption-plugins-amazon-web-services-aws-key-managemen/+image/aws-kms-copy-security-credentials)](https://mariadb.com/kb/en/mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/+image/aws-kms-copy-security-credentials)
8. Create a file on your computer to hold the credentials for this user. We'll use this file later. It should have this structure: 
```
[default]
aws_access_key_id = AKIAIG6IZ6TKF52FVV5A
aws_secret_access_key = o7CEf7KhZfsVF9cS0a2roqqZNmuzXtIR869zpSBT

```
9. Click "Close". If prompted because you did not Download Credentials, ensure that you've saved them somewhere, and click "Close".

 Create a Master Encryption Key
------------------------------

 Now, we'll create a master encryption key. This key can *never* be retrieved by *any* application or user. This key is used remotely to encrypt (and decrypt) the actual encryption keys that will be used by MariaDB. If this key is deleted or you lose access to it, you will be unable to use the contents of your MariaDB data directory.

 1. Click "Encryption Keys" in the left-hand sidebar.
2. Click the "Get Started Now" button.
3. Use the "Filter" dropdown to choose the region where you'd like to create your master key.
4. Click the "Create Key" button.  
 [![](https://mariadb.com/kb/en/key-management-and-encryption-plugins-amazon-web-services-aws-key-managemen/+image/aws-kms-create-key)](https://mariadb.com/kb/en/mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/+image/aws-kms-create-key)
5. Enter an Alias and Description of your choosing.
6. Click "Next Step".
7. Do **not** check the box to make your IAM Role or IAM User user a Key Administrator.
8. Click "Next Step" again.
9. Check the boxes to give your IAM Role and/or IAM User permissions to use this key.  
 [![](https://mariadb.com/kb/en/key-management-and-encryption-plugins-amazon-web-services-aws-key-managemen/+image/aws-kms-key-usage-permissions)](https://mariadb.com/kb/en/mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/+image/aws-kms-key-usage-permissions)
10. Click "Next Step".
11. Click "Finish".

 You should now see your key listed in the console:

 [![](https://mariadb.com/kb/en/key-management-and-encryption-plugins-amazon-web-services-aws-key-managemen/+image/aws-kms-key-list-console)](https://mariadb.com/kb/en/mariadb-enterprise-aws-kms-encryption-plugin-setup-guide/+image/aws-kms-key-list-console)

 You'll use the "Alias" you provided when you configure MariaDB later.

 We now have a Customer Master Key and an IAM user that has privileges to access it using access credentials. This is enough to begin using the AWS KMS plugin.

 Configure AWS Credentials
-------------------------

 There are a number of ways to give the IAM credentials to the AWS KMS plugin. The plugin supports reading credentials from all standard locations used across the various AWS API clients.

 The easiest approach is to run MariaDB Server in an EC2 instance that has an IAM Role with User access to the CMK you wish to use. You can give key access privileges to a Role already attached to your EC2 instance, or you can create a new IAM Role and attach it to an already-running EC2 instance. If you've done that, no further credentials management is required and you do not need to create a `credentials` file.

 If you're not running MariaDB Server on an EC2 instance, you can also place the credentials in the MariaDB data directory. The AWS API client looks for a `credentials` file in the `.aws` subdirectory of the home directory of the user running the client process. In the case of MariaDB, its home directory is its `datadir`.

 1. Create a `credentials` file that MariaDB can read. Use the region you selected when creating the key. Master keys cannot be used across regions. For example:
```
$ cat /var/lib/mysql/.aws/credentials
[default]
aws_access_key_id = AKIAIG6IZ6TKF52FVV5A
aws_secret_access_key = o7CEf7KhZfsVF9cS0a2roqqZNmuzXtIR869zpSBT
region = us-east-1

```
2. Change the permissions of the file so that it it is owned by, and can only be read by, the `mysql` user:
```
chown mysql /var/lib/mysql/.aws/credentials
chmod 600 /var/lib/mysql/.aws/credentials

```

 Configure MariaDB
-----------------

 1. Create a new option file to tell MariaDB to enable encryption functionality and to use the AWS KMS plugin. Create a new file under `/etc/my.cnf.d/` (or wherever your OS may have you create such files) with contents like this:

 
```
[mariadb]
plugin_load_add = aws_key_management
aws-key-management = FORCE_PLUS_PERMANENT
aws-key-management-master-key-id = alias/mariadb-encryption
aws-key-management-region = us-east-1
!include /etc/my.cnf.d/enable_encryption.preset

```

1. Append the "Alias" value you copied above to `alias/` to use as the value for the `aws-key-management-master-key-id` option.

 Note that you **must** include `aws-key-management-region` in your .cnf file if you are not using the us-east-1 region.

 Now, you have told MariaDB to use the AWS KMS plugin and you've put credentials for the plugin in a location where the plugin will find them. The /etc/my.cnf.d/enable\_encryption.preset file contains a set of options that enable all available encryption functionality.

 When you start MariaDB, the AWS KMS plugin will connect to the AWS Key Management Service and ask it to generate a new key. MariaDB will store that key on-disk in an encrypted form. The key stored on-disk cannot be used to decrypt the data; rather, on each startup, MariaDB must connect to AWS KMS and have the service decrypt the locally-stored key. The decrypted version is stored in-memory as long as the MariaDB server process is running, and that in-memory decrypted key is used to encrypt the local data.

 ### SELinux and Outbound Connections from MariaDB

 Because MariaDB needs to connect to the AWS KMS service, you must ensure that the host has outbound network connectivity over port 443 to AWS and you must ensure that local policies allow the MariaDB server process to make those outbound connections. By default, SELinux restricts MariaDB from making such connections.

 The most simple way to cause SELinux to allow outbound HTTPS connections from MariaDB is to enable to mysql\_connect\_any boolean, like this:

 
```
setsebool -P mysql_connect_any 1

```

There are more complex alternatives that have a more granular effect, but those are beyond the scope of this document.

 Start MariaDB
-------------

 Start MariaDB using the `systemctl` tool:

 
```
systemctl start mariadb

```

If you do not use systemd, you may have to start MariaDB using some other mechanism.

 You should see journal output similar to this:

 
```
# journalctl --no-pager -o cat -u mariadb.service

[Note] /usr/sbin/mysqld (mysqld 10.1.9-MariaDB-enterprise-log) starting as process 19831 ...
[Note] AWS KMS plugin: generated encrypted datakey for key id=1, version=1
[Note] AWS KMS plugin: loaded key 1, version 1, key length 128 bit
[Note] InnoDB: Using mutexes to ref count buffer pool pages
[Note] InnoDB: The InnoDB memory heap is disabled
[Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
[Note] InnoDB: Memory barrier is not used
[Note] InnoDB: Compressed tables use zlib 1.2.7
[Note] InnoDB: Using CPU crc32 instructions
[Note] InnoDB: Initializing buffer pool, size = 2.0G
[Note] InnoDB: Completed initialization of buffer pool
[Note] InnoDB: Highest supported file format is Barracuda.
[Note] InnoDB: 128 rollback segment(s) are active.
[Note] InnoDB: Waiting for purge to start
[Note] InnoDB:  Percona XtraDB (http://www.percona.com) 5.6.26-74.0 started; log sequence number 1616819
[Note] InnoDB: Dumping buffer pool(s) not yet started
[Note] Plugin 'FEEDBACK' is disabled.
[Note] AWS KMS plugin: generated encrypted datakey for key id=2, version=1
[Note] AWS KMS plugin: loaded key 2, version 1, key length 128 bit
[Note] Using encryption key id 2 for temporary files
[Note] Server socket created on IP: '::'.
[Note] Reading of all Master_info entries succeded
[Note] Added new Master_info '' to hash table
[Note] /usr/sbin/mysqld: ready for connections.

```

Note the several lines of output that refer explicitly to the "AWS KMS plugin". You can see that the plugin generates a "datakey", loads that data key, and then later generates and loads a second data key. The 2nd data key is used to encrypt temporary files and temporary tables.

 You can see the encrypted keys stored on-disk in the datadir:

 
```
# ls -l /var/lib/mysql/aws*
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.1.1
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.2.1

```

Note that those keys are not useful alone. They are encrypted. When MariaDB starts up, the AWS KMS plugin decrypts those keys by interacting with AWS KMS.

 For maximum security, you should start from an empty datadir and run [mariadb-install-db](../mariadb-install-db/index) after configuring encryption. Then you should re-import your data so that it is fully encrypted. Use `sudo` to run `mariadb-install-db` so that it finds your credentials file:

 
```
# sudo -u mysql mariadb-install-db
Installing MariaDB/MySQL system tables in '/var/lib/mysql' ...
2016-02-25 23:16:06 139731553998976 [Note] /usr/sbin/mysqld (mysqld 10.1.11-MariaDB-enterprise-log) starting as process 39551 ...
2016-02-25 23:16:07 139731553998976 [Note] AWS KMS plugin: generated encrypted datakey for key id=1, version=1
2016-02-25 23:16:07 139731553998976 [Note] AWS KMS plugin: loaded key 1, version 1, key length 128 bit
...

```

Create Encrypted Tables
-----------------------

 With `innodb-encrypt-tables=ON`, new InnoDB tables will be encrypted by default, using the key ID set in `innodb_default_encryption_key_id` (default 1). With `innodb-encrypt-tables=FORCE` enabled, it is not possible to manually bypass encryption when creating a table.

 You can cause the AWS KMS plugin to create new encryption keys at-will by specifying a new ENCRYPTION\_KEY\_ID when creating a table:

 
```
MariaDB [test]> create table t1 (id serial, v varchar(32)) ENCRYPTION_KEY_ID=3;
Query OK, 0 rows affected (0.91 sec)

```


```
[Note] AWS KMS plugin: generated encrypted datakey for key id=3, version=1
[Note] AWS KMS plugin: loaded key 3, version 1, key length 128 bit

```


```
# ls -l /var/lib/mysql/aws*
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.1.1
-rw-rw----. 1 mysql mysql 188 Feb 25 18:55 /var/lib/mysql/aws-kms-key.2.1
-rw-rw----. 1 mysql mysql 188 Feb 25 19:10 /var/lib/mysql/aws-kms-key.3.1

```

Read more about encrypting data in the [Data at Rest Encryption](../data-at-rest-encryption/index#encrypting-data) section of the MariaDB Documentation.

 AWS KMS Plugin Option Reference
-------------------------------

 * `aws_key_management_master_key_id`: AWS KMS Customer Master Key ID (ARN or alias prefixed by `alias/`) for master encryption key. Used to create new data keys. If not set, no new data keys will be created.
* `aws_key_management_rotate_key`: Set this variable to a data key ID to perform rotation of the key to the master key given in `aws_key_management_master_key_id`. Specify -1 to rotate all keys.

 * `aws_key_management_key_spec`: Encryption algorithm used to create new keys. Allowed values are AES\_128 (default) or AES\_256.
* `aws_key_management_log_level`: Logging for AWS API. Allowed values, in increasing verbosity, are "Off" (default), "Fatal", "Error", "Warn", "Info", "Debug", and "Trace".

 Next Steps
----------

 For more information about advanced usage, including strategies to manage credentials, enforce separation of responsibilities, and even require 2-factor authentication to start your MariaDB server, please review [Amazon Web Services (AWS) Key Management Service (KMS) Encryption Plugin Advanced Usage](../aws-key-management-encryption-plugin-advanced-usage/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aws-key-management-encryption-plugin-setup-guide/>

Pluggable Authentication Overview
=================================

    When a user attempts to log in, the authentication plugin controls how MariaDB Server determines whether the connection is from a legitimate user.

 When creating or altering a user account with the [GRANT](../grant/index), [CREATE USER](../create-user/index) or [ALTER USER](../alter-user/index) statements, you can specify the authentication plugin you want the user account to use by providing the `IDENTIFIED VIA` clause. By default, when you create a user account without specifying an authentication plugin, MariaDB uses the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) plugin.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, there are some notable changes, such as:

 * You can specify multiple authentication plugins for each user account.
* The `root@localhost` user created by [mariadb-install-db](../mariadb-install-db/index) is created with the ability to use two authentication plugins. First, it is configured to try to use the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin. This allows the the `root@localhost` user to login without a password via the local Unix socket file defined by the [socket](../server-system-variables/index#socket) system variable, as long as the login is attempted from a process owned by the operating system `root` user account. Second, if authentication fails with the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, then it is configured to try to use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin. However, an invalid password is initially set, so in order to authenticate this way, a password must be set with [SET PASSWORD](../set-password/index).

 
Supported Authentication Plugins
--------------------------------

 The authentication process is a conversation between the server and a client. MariaDB implements both server-side and client-side authentication plugins.

 ### Supported Server Authentication Plugins

 MariaDB provides seven server-side authentication plugins:

 * [mysql\_native\_password](../authentication-plugin-mysql_native_password/index)
* [mysql\_old\_password](../authentication-plugin-mysql_old_password/index)
* [ed25519](../authentication-plugin-ed25519/index)
* [gssapi](../authentication-plugin-gssapi/index)
* [pam](../authentication-plugin-pam/index) (Unix only)
* [unix\_socket](../authentication-plugin-unix-socket/index) (Unix only)
* [named\_pipe](../authentication-plugin-named-pipe/index) (Windows only)

 ### Supported Client Authentication Plugins

 MariaDB provides eight client-side authentication plugins:

 * [mysql\_native\_password](../authentication-plugin-mysql_native_password/index#client-authentication-plugins)
* [mysql\_old\_password](../authentication-plugin-mysql_old_password/index#client-authentication-plugins)
* [client\_ed25519](../authentication-plugin-ed25519/index#client-authentication-plugins)
* [auth\_gssapi\_client](../authentication-plugin-gssapi/index#client-authentication-plugins)
* [dialog](../authentication-plugin-pam/index#client-authentication-plugins)
* [mysql\_clear\_password](../authentication-plugin-pam/index#client-authentication-plugins)
* [sha256\_password](../authentication-plugin-sha-256/index#client-authentication-plugins)
* [caching\_sha256\_password](../authentication-plugin-sha-256/index#client-authentication-plugins)

 Options Related to Authentication Plugins
-----------------------------------------

 ### Server Options Related to Authentication Plugins

 MariaDB supports the following server options related to authentication plugins:

 


| Server Option | Description |
| --- | --- |
| `[old\_passwords={1 | 0}](../server-system-variables/index#old_passwords)` | If set to `1` (`0` is default), MariaDB reverts to using the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin by default for newly created users and passwords, instead of the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin. |
| `[plugin\_dir=path](../server-system-variables/index#plugin_dir)` | Path to the [plugin](../mariadb-plugins/index) directory. For security reasons, either make sure this directory can only be read by the server, or set [secure\_file\_priv](#secure_file_priv). |
| `[plugin\_maturity=level](../server-system-variables/index#plugin_maturity)` | The lowest acceptable [plugin](../mariadb-plugins/index) maturity. MariaDB will not load plugins less mature than the specified level. |
| `[secure\_auth](../server-system-variables/index#secure_auth)` | Connections will be blocked if they use the the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin. The server will also fail to start if the privilege tables are in the old, pre-MySQL 4.1 format. |

 
### Client Options Related to Authentication Plugins

 Most [clients and utilities](../clients-utilities/index) support some command line arguments related to client authentication plugins:

 


| Client Option | Description |
| --- | --- |
| `--connect-expired-password` | Notify the server that this client is prepared to handle [expired password sandbox mode](../user-password-expiry/index) even if `--batch` was specified. From [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/). |
| `--default-auth=name` | Default authentication client-side plugin to use. |
| `--plugin-dir=path` | Directory for client-side plugins. |
| `--secure-auth` | Refuse to connect to the server if the server uses the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin. This mode is off by default, which is a difference in behavior compared to MySQL 5.6 and later, where it is on by default. |

 
Developers who are using [MariaDB Connector/C](../mariadb-connector-c/index) can implement similar functionality in their application by setting the following options with the [mysql\_optionsv](../mysql_optionsv/index) function:

 * `MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS`
* `MYSQL_PLUGIN_DIR`
* `MYSQL_DEFAULT_AUTH`
* `MYSQL_SECURE_AUTH`

 For example:

 
```
mysql_optionsv(mysql, MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, 1);
mysql_optionsv(mysql, MYSQL_DEFAULT_AUTH, "name");
mysql_optionsv(mysql, MYSQL_PLUGIN_DIR, "path");
mysql_optionsv(mysql, MYSQL_SECURE_AUTH, 1);

```

### Installation Options Related to Authentication Plugins

 [mariadb-install-db](../mariadb-install-db/index) supports the following installation options related to authentication plugins:

 


| Installation Option | Description |
| --- | --- |
| `--auth-root-authentication-method={normal `|` socket}` | If set to `normal`, it creates a `root@localhost` account that authenticates with the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin and that has no initial password set, which can be insecure. If set to `socket`, it creates a `root@localhost` account that authenticates with the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin. Set to `normal` by default. Available since [MariaDB 10.1](../what-is-mariadb-101/index). |
| `--auth-root-socket-user=USER` | Used with `--auth-root-authentication-method=socket`. It specifies the name of the second account to create with [SUPER](../grant/index#global-privileges) privileges in addition to `root`, as well as of the system account allowed to access it. Defaults to the value of `--user`. |

 
Extended SQL Syntax
-------------------

 MariaDB has extended the SQL standard [GRANT](../grant/index), [CREATE USER](../create-user/index), and [ALTER USER](../alter-user/index) statements, so that they support specifying different authentication plugins for specific users. An authentication plugin can be specified with these statements by providing the `IDENTIFIED VIA` clause.

 For example, the [GRANT](../grant/index) syntax is:

 
```
GRANT <privileges> ON <level> TO <user> 
   IDENTIFIED VIA <plugin> [ USING <string> ]

```

And the [CREATE USER](../create-user/index) syntax is:

 
```
CREATE USER <user> 
   IDENTIFIED VIA <plugin> [ USING <string> ]

```

And the [ALTER USER](../alter-user/index) syntax is:

 
```
ALTER USER <user> 
   IDENTIFIED VIA <plugin> [ USING <string> ]

```

The optional `USING` clause allows users to provide an authentication string to a plugin. The authentication string's format and meaning is completely defined by the plugin.

 For example, for the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin, the authentication string should be a password hash:

 
```
CREATE USER mysqltest_up1 
   IDENTIFIED VIA mysql_native_password USING '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';

```

Since [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) is the default authentication plugin, the above is just another way of saying the following:

 
```
CREATE USER mysqltest_up1 
   IDENTIFIED BY PASSWORD '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB';

```

In contrast, for the [pam](../authentication-plugin-pam/index) authentication plugin, the authentication string should refer to a [PAM service name](../authentication-plugin-pam/index#configuring-the-pam-service):

 
```
CREATE USER mysqltest_up1 
   IDENTIFIED VIA pam USING 'mariadb';

```


**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, a user account can be associated with multiple authentication plugins.

 For example, to configure the `root@localhost` user account to try the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, followed by the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin as a backup, you could execute the following:

 
```
CREATE USER root@localhost 
   IDENTIFIED VIA unix_socket 
   OR mysql_native_password USING PASSWORD("verysecret");

```

See [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index) for more information.

 
Authentication Plugins Installed by Default
-------------------------------------------

 ### Server Authentication Plugins Installed by Default

 Not all server-side authentication plugins are installed by default. If a specific server-side authentication plugin is not installed by default, then you can find the installation procedure on the documentation page for the specific authentication plugin.

   


 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, the following server-side authentication plugins are installed by default:

 * The [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugins authentication plugins are installed by default in all builds.

 * The [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin is installed by default in all builds on Unix and Linux.

 * The [named\_pipe](../authentication-plugin-named-pipe/index) authentication plugin is installed by default in all builds on Windows.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and below, the following server-side authentication plugins are installed by default:

 * The [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugins are installed by default in all builds.

 * The [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin is installed by default in **new installations** that use the [.deb](../installing-mariadb-deb-files/index) packages provided by Debian's default repositories in Debian 9 and later and Ubuntu's default repositories in Ubuntu 15.10 and later. See [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index) for more information.

 * The [named\_pipe](../authentication-plugin-named-pipe/index) authentication plugin is installed by default in all builds on Windows.

 
### Client Authentication Plugins Installed by Default

 Client-side authentication plugins do not need to be *installed* in the same way that server-side authentication plugins do. If the client uses either the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) library, then the library automatically loads client-side authentication plugins from the library's plugin directory whenever they are needed.

 Most [clients and utilities](../clients-utilities/index) support the `--plugin-dir` command line argument that can be used to set the path to the library's plugin directory:

 


| Client Option | Description |
| --- | --- |
| `--plugin-dir=path` | Directory for client-side plugins. |

 
Developers who are using [MariaDB Connector/C](../mariadb-connector-c/index) can implement similar functionality in their application by setting the `MYSQL_PLUGIN_DIR` option with the [mysql\_optionsv](../mysql_optionsv/index) function.

 For example:

 
```
mysql_optionsv(mysql, MYSQL_PLUGIN_DIR, "path");

```

If your client encounters errors similar to the following, then you may need to set the path to the library's plugin directory:

 
```
ERROR 2059 (HY000): Authentication plugin 'dialog' cannot be loaded: /usr/lib/mysql/plugin/dialog.so: cannot open shared object file: No such file or directory

```

If the client does **not** use either the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) library, then you will have to determine which authentication plugins are supported by the specific client library used by the client.

 If the client uses either the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) library, but the client is not bundled with either library's *optional* client authentication plugins, then you can only use the conventional authentication plugins (like [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) and [mysql\_old\_password](../authentication-plugin-mysql_old_password/index)) and the non-conventional authentication plugins that don't require special client-side authentication plugins (like [unix\_socket](../authentication-plugin-unix-socket/index) and [named\_pipe](../authentication-plugin-named-pipe/index)).

 Default Authentication Plugin
-----------------------------

 ### Default Server Authentication Plugin

 The [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin is currently the default authentication plugin in all versions of MariaDB if the [old\_passwords](../server-system-variables/index#old_passwords) system variable is set to `0`, which is the default.

 On a system with the [old\_passwords](../server-system-variables/index#old_passwords) system variable set to `0`, this means that if you create a user account with either the [GRANT](../grant/index) or [CREATE USER](../create-user/index) `statements, and if you do not specify an authentication plugin with the` IDENTIFIED VIA `clause, then MariaDB will use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin for the user account.`

 For example, this user account will use the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin:

 
```
CREATE USER username@hostname;

```

And so will this user account:

 
```
CREATE USER username@hostname IDENTIFIED BY 'notagoodpassword';

```

The [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin becomes the default authentication plugin in all versions of MariaDB if the [old\_passwords](../server-system-variables/index#old_passwords) system variable is explicitly set to `1`.

 However, the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin is not considered secure, so it is recommended to avoid using this authentication plugin. To help prevent undesired use of the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin, the server supports the [secure\_auth](../server-system-variables/index#secure_auth) system variable that can be used to configured the server to refuse connections that try to use the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin:

 


| Server Option | Description |
| --- | --- |
| `[old\_passwords={1 | 0}](../server-system-variables/index#old_passwords)` | If set to `1` (`0` is default), MariaDB reverts to using the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin by default for newly created users and passwords, instead of the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin. |
| `[secure\_auth](../server-system-variables/index#secure_auth)` | Connections will be blocked if they use the the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin. The server will also fail to start if the privilege tables are in the old, pre-MySQL 4.1 format. |

 
Most [clients and utilities](../clients-utilities/index) also support the `--secure-auth` command line argument that can also be used to configure the client to refuse to connect to servers that use the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin:

 


| Client Option | Description |
| --- | --- |
| `--secure-auth` | Refuse to connect to the server if the server uses the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin. This mode is off by default, which is a difference in behavior compared to MySQL 5.6 and later, where it is on by default. |

 
Developers who are using [MariaDB Connector/C](../mariadb-connector-c/index) can implement similar functionality in their application by setting the `MYSQL_SECURE_AUTH` option with the [mysql\_optionsv](../mysql_optionsv/index) function.

 For example:

 
```
mysql_optionsv(mysql, MYSQL_SECURE_AUTH, 1);

```

### Default Client Authentication Plugin

 The default client-side authentication plugin depends on a few factors.

 If a client doesn't explicitly set the default client-side authentication plugin, then the client will determine which authentication plugin to use by checking the length of the scramble in the server's handshake packet.

 If the server's handshake packet contains a 9-byte scramble, then the client will default to the [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin.

 If the server's handshake packet contains a 20-byte scramble, then the client will default to the [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin.

 #### Setting the Default Client Authentication Plugin

 Most [clients and utilities](../clients-utilities/index) support the `--default-auth` command line argument that can be used to set the default client-side authentication plugin:

 


| Client Option | Description |
| --- | --- |
| `--default-auth=name` | Default authentication client-side plugin to use. |

 
Developers who are using [MariaDB Connector/C](../mariadb-connector-c/index) can implement similar functionality in their application by setting the `MYSQL_DEFAULT_AUTH` option with the [mysql\_optionsv](../mysql_optionsv/index) function.

 For example:

 
```
mysql_optionsv(mysql, MYSQL_DEFAULT_AUTH, "name");

```

If you know that your user account is configured to require a client-side authentication plugin that isn't [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) or [mysql\_native\_password](../authentication-plugin-mysql_native_password/index), then it can help speed up your connection process to explicitly set the default client-side authentication plugin.

 According to the [client-server protocol](../clientserver-protocol/index), the server first sends the handshake packet to the client, then the client replies with a packet containing the user name of the user account that is requesting access. The server handshake packet initially tells the client to use the default server authentication plugin, and the client reply initially tells the server that it will use the default client authentication plugin. 

 However, the server-side and client-side authentication plugins mentioned in these initial packets may not be the correct ones for this specific user account. The server only knows what authentication plugin to use for this specific user account after reading the user name from the client reply packet and finding the appropriate row for the user account in either the [mysql.user](../mysqluser-table/index) table or the [mysql.global\_priv](../mysqlglobal_priv-table/index) table, depending on the MariaDB version.

 If the server finds that either the server-side or client-side default authentication plugin does not match the actual authentication plugin that should be used for the given user account, then the server restarts the authentication on either the server side or the client side.

 This means that, if you know what client authentication plugin your user account requires, then you can avoid an unnecessary authentication restart and you can save two packets and two round-trips.between the client and server by configuring your client to use the correct authentication plugin by default.

 Authentication Plugins
----------------------

 ### Server Authentication Plugins

 #### `mysql_native_password`

 The [mysql\_native\_password](../authentication-plugin-mysql_native_password/index) authentication plugin uses the password hashing algorithm introduced in MySQL 4.1, which is also used by the [PASSWORD()](../password/index) `function when [old\_passwords=0](../server-system-variables/index#old_passwords) is set. This hashing algorithm is based on [SHA-1](https://en.wikipedia.org/wiki/SHA-1).`

 #### `mysql_old_password`

 The [mysql\_old\_password](../authentication-plugin-mysql_old_password/index) authentication plugin uses the pre-MySQL 4.1 password hashing algorithm, which is also used by the [OLD\_PASSWORD()](../old_password/index) function and by the [PASSWORD()](../password/index) function when [old\_passwords=1](../server-system-variables/index#old_passwords) is set.

 #### `ed25519`

 The [ed25519](../authentication-plugin-ed25519/index) authentication plugin uses [Elliptic Curve Digital Signature Algorithm](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) to securely store users' passwords and to authenticate users. The [ed25519](https://en.wikipedia.org/wiki/EdDSA#Ed25519) algorithm is the same one that is [used by OpenSSH](https://www.openssh.com/txt/release-6.5). It is based on the elliptic curve and code created by [Daniel J. Bernstein](https://en.wikipedia.org/wiki/Daniel_J._Bernstein).

 From a user's perspective, the [ed25519](../authentication-plugin-ed25519/index) authentication plugin still provides conventional password-based authentication.

 #### `gssapi`

 The [gssapi](../authentication-plugin-gssapi/index) authentication plugin allows the user to authenticate with services that use the [Generic Security Services Application Program Interface (GSSAPI)](https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface). Windows has a slightly different but very similar API called [Security Support Provider Interface (SSPI)](https://docs.microsoft.com/en-us/windows/desktop/secauthn/sspi).

 On Windows, this authentication plugin supports [Kerberos](https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-kerberos) and [NTLM](https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-ntlm) authentication. Windows authentication is supported regardless of whether a [domain](https://en.wikipedia.org/wiki/Windows_domain) is used in the environment.

 On Unix systems, the most dominant GSSAPI service is [Kerberos](https://en.wikipedia.org/wiki/Kerberos_(protocol)). However, it is less commonly used on Unix systems than it is on Windows. Regardless, this authentication plugin also supports Kerberos authentication on Unix.

 The [gssapi](../authentication-plugin-gssapi/index) authentication plugin is most often used for authenticating with [Microsoft Active Directory](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview).

 #### `pam`

 The [pam](../authentication-plugin-pam/index) authentication plugin allows MariaDB to offload user authentication to the system's [Pluggable Authentication Module (PAM)](http://en.wikipedia.org/wiki/Pluggable_authentication_module) framework. PAM is an authentication framework used by Linux, FreeBSD, Solaris, and other Unix-like operating systems.

 #### `unix_socket`

 The [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin allows the user to use operating system credentials when connecting to MariaDB via the local Unix socket file. This Unix socket file is defined by the [socket](../server-system-variables/index#socket) system variable.

 The [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin works by calling the [getsockopt](http://man7.org/linux/man-pages/man7/socket.7.html) system call with the `SO_PEERCRED` socket option, which allows it to retrieve the `uid` of the process that is connected to the socket. It is then able to get the user name associated with that `uid`. Once it has the user name, it will authenticate the connecting user as the MariaDB account that has the same user name.

 For example:

 
```
$ mysql -uroot
MariaDB []> CREATE USER serg IDENTIFIED VIA unix_socket;
MariaDB []> CREATE USER monty IDENTIFIED VIA unix_socket;
MariaDB []> quit
Bye
$ whoami
serg
$ mysql --user=serg
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 5.2.0-MariaDB-alpha-debug Source distribution
MariaDB []> quit
Bye
$ mysql --user=monty
ERROR 1045 (28000): Access denied for user 'monty'@'localhost' (using password: NO)

```

In this example, a user `serg` is already logged into the operating system and has full shell access. He has already authenticated with the operating system and his MariaDB account is configured to use the [unix\_socket](../authentication-plugin-unix-socket/index) authentication plugin, so he does not need to authenticate again for the database. MariaDB accepts his operating system credentials and allows him to connect. However, any attempt to connect to the database as another operating system user will be denied.

 #### `named_pipe`

 The [named\_pipe](../authentication-plugin-named-pipe/index) authentication plugin allows the user to use operating system credentials when connecting to MariaDB via named pipe on Windows. Named pipe connections are enabled by the [named\_pipe](../server-system-variables/index#named_pipe) system variable.

 The [named\_pipe](../authentication-plugin-named-pipe/index) authentication plugin works by using [named pipe impersonation](https://msdn.microsoft.com/en-us/library/windows/desktop/aa378618%28v=vs.85%29.aspx) and calling `GetUserName()` to retrieve the user name of the process that is connected to the named pipe. Once it has the user name, it authenticates the connecting user as the MariaDB account that has the same user name.

 For example:

 
```
CREATE USER wlad IDENTIFIED VIA named_pipe;
CREATE USER monty IDENTIFIED VIA named_pipe;
quit

C:\>echo %USERNAME%
wlad

C:\> mysql --user=wlad --protocol=PIPE
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.1.12-MariaDB-debug Source distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> quit
Bye

C:\> mysql --user=monty  --protocol=PIPE
ERROR 1698 (28000): Access denied for user 'monty'@'localhost'

```

Authentication Plugin API
-------------------------

 The authentication plugin API is extensively documented in the [source code](../getting-the-mariadb-source-code/index) in the following files:

 * `mysql/plugin_auth.h` (server part)
* `mysql/client_plugin.h` (client part)
* `mysql/plugin_auth_common.h` (common parts)

 The MariaDB [source code](../getting-the-mariadb-source-code/index) also contains some authentication plugins that are intended explicitly to be examples for developers. They are located in `plugin/auth_examples`.

 The definitions of two example authentication plugins called `two_questions` and `three_attempts` can be seen in `plugin/auth_examples/dialog_examples.c`. These authentication plugins demonstrate how to communicate with the user using the [dialog](../authentication-plugin-pam/index#dialog) client authentication plugin.

 The `two_questions` authentication plugin asks the user for a password and a confirmation ("Are you sure?").

 The `three_attempts` authentication plugin gives the user three attempts to enter a correct password.

 The password for both of these plugins should be specified in the plain text in the `USING` clause:

 
```
CREATE USER insecure IDENTIFIED VIA two_questions USING 'notverysecret';

```

### Dialog Client Authentication Plugin - Client Library Extension

 The [dialog](../authentication-plugin-pam/index#dialog) client authentication plugin, strictly speaking, is not part of the client-server or authentication plugin API. But it can be loaded into any client application that uses the `libmysqlclient` or [MariaDB Connector/C](../mariadb-connector-c/index) libraries. This authentication plugin provides a way for the application to customize the UI of the dialog function.

 In order to use the [dialog](../authentication-plugin-pam/index#dialog) client authentication plugin to communicate with the user in a customized way, the application will need to implement a function with the following signature:

 
```
extern "C" char *mysql_authentication_dialog_ask(
  MYSQL *mysql, int type, const char *prompt, char *buf, int buf_len)

```

The function takes the following arguments:

 * The connection handle.
* A question "type", which has one of the following values:
	+ `1` - Normal question
	+ `2` - Password (no echo)
* A prompt.
* A buffer.
* The length of the buffer.

 The function returns a pointer to a string of characters, as entered by the user. It may be stored in `buf` or allocated with `malloc()`.

 Using this function a GUI application can pop up a dialog window, a network application can send the question over the network, as required. If no `mysql_authentication_dialog_ask` function is provided by the application, the [dialog](../authentication-plugin-pam/index#dialog) client authentication plugin falls back to [fputs()](https://linux.die.net/man/3/fputs) and [fgets()](https://linux.die.net/man/3/fgets).

 Providing this callback is particularly important on Windows, because Windows GUI applications have no associated console and the default dialog function will not be able to reach the user. An example of Windows GUI client that does it correctly is [HeidiSQL](../heidisql/index).

 See Also
--------

 * [GRANT](../grant/index)
* [CREATE USER](../create-user/index)
* [ALTER USER](../alter-user/index)
* [Authentication from MariaDB 10.4](../authentication-from-mariadb-104/index)
* [Who are you? The history of MySQL and MariaDB authentication protocols from 1997 to 2017](https://mariadb.org/history-of-mysql-mariadb-authentication-protocols/)
* [MySQL 5.6 Reference Manual: Pluggable Authentication](https://dev.mysql.com/doc/refman/5.6/en/pluggable-authentication.html)
* [MySQL 5.6 Reference Manual: Writing Authentication Plugins](http://dev.mysql.com/doc/refman/5.6/en/writing-authentication-plugins.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pluggable-authentication-overview/>

Eperi Key Management Encryption Plugin
======================================

    
Eperi's Key Management Plugin Package no longer appears to be available.

  MariaDB's [data-at-rest encryption](../data-at-rest-encryption/index) requires the use of a [key management and encryption plugin](../encryption-key-management/index). These plugins are responsible both for the management of encryption keys and for the actual encryption and decryption of data.

 MariaDB supports the use of [multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key uses a 32-bit integer as a key identifier. If the specific plugin supports [key rotation](../encryption-key-management/index#rotating-keys), then encryption keys can also be rotated, which creates a new version of the encryption key.

 The Eperi Key Management plugin is a [key management and encryption plugin](../encryption-key-management/index) that integrates with [eperi Gateway for Databases](https://eperi.com/database-encryption/).

 Overview
--------

 The Eperi Key Management plugin is one of the [key management and encryption plugins](../encryption-key-management/index) that can be set up for users who want to use [data-at-rest encryption](../data-at-rest-encryption/index). Some of the plugin's primary features are:

 * It reads encryption keys from [eperi Gateway for Databases](https://eperi.com/database-encryption/).
* It supports multiple encryption keys.
* It supports key rotation.
* It supports two different algorithms for encrypting data.

 The [eperi Gateway for Databases](https://eperi.com/database-encryption/) stores encryption keys on the key server outside of the database server itself, which provides an extra level of security. The [eperi Gateway for Databases](https://eperi.com/database-encryption/) also supports performing all data encryption operations on the key server as well, but this is optional.

 It also provides the following benefits:

 * Key management outside the database
* No keys on database server hard disk
* Graphical user interface for configuration
* Encryption and decryption outside the database, supporting HSM's for maximum security.

 Support for MariaDB is provided in [eperi Gateway for Databases 3.4](https://eperi.com/eperi-gateway-for-databases-version-3-4-offers-native-mariadb-support/).

 Installing the Eperi Key Management Plugin's Package
----------------------------------------------------

 For information on how to install the package, see Eperi's documentation at the [Eperi Customer Portal](https://customer.eperi.de/index.jsp).

 Installing the Plugin
---------------------

 Even after the package that contains the plugin's shared library is installed on the operating system, the plugin is not actually installed by MariaDB by default. The plugin can be installed by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options. This can be specified as a command-line argument to `[mysqld](../mysqld-options/index)` or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
plugin_load_add = eperi_key_management_plugin

```

Uninstalling the Plugin
-----------------------

 Before you uninstall the plugin, you should ensure that [data-at-rest encryption](../data-at-rest-encryption/index) is completely disabled, and that MariaDB no longer needs the plugin to decrypt tables or other files.

 You can uninstall the plugin dynamically by executing `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)`. For example:

 
```
UNINSTALL SONAME 'eperi_key_management_plugin';

```

If you installed the plugin by providing the `[--plugin-load](../mysqld-options/index#-plugin-load)` or the `[--plugin-load-add](../mysqld-options/index#-plugin-load-add)` options in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index), then those options should be removed to prevent the plugin from being loaded the next time the server is restarted.

 Configuring the Eperi Key Management Plugin
-------------------------------------------

 For information on how to configure the plugin, see Eperi's documentation at the [Eperi Customer Portal](https://customer.eperi.de/index.jsp).

 Using the Eperi Key Management Plugin
-------------------------------------

 Once the Eperi Key Management Plugin is enabled, you can use it by creating an encrypted table:

 
```
CREATE TABLE t (i int) ENGINE=InnoDB ENCRYPTED=YES

```

Now, table `t` will be encrypted using the encryption key from the key server.

 For more information on how to use encryption, see [Data at Rest Encryption](../data-at-rest-encryption/index).

 Using Multiple Encryption Keys
------------------------------

 The Eperi Key Management Plugin supports [using multiple encryption keys](../encryption-key-management/index#using-multiple-encryption-keys). Each encryption key can be defined with a different 32-bit integer as a key identifier.

 When [encrypting InnoDB tables](../innodb-encryption/index), the key that is used to encrypt tables [can be changed](../innodb-xtradb-encryption-keys/index).

 When [encrypting Aria tables](../aria-encryption/index), the key that is used to encrypt tables [cannot currently be changed](../aria-encryption-keys/index).

 Key Rotation
------------

 The Eperi Key Management plugin supports [key rotation](../encryption-key-management/index#key-rotation).

 Versions
--------

 


| Version | Status | Introduced |
| --- | --- | --- |
| 1.0 | Unknown | [eperi Gateway for Databases](https://eperi.com/database-encryption/) 3.4.0 |

 
System Variables
----------------

 ### `eperi_key_management_plugin_databaseId`

 * **Description:** Determines the database ID which is processed in the eperi Gateway.
* **Commandline:** `--eperi-key-management-plugin-databaseid=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `integer`
* **Default Value:** `1`

 

---

 ### `eperi_key_management_plugin_encryption_algorithm`

 * **Description:** This system variable is used to determine which algorithm the plugin will use to encrypt data.
	+ The recommended algorithm is `AES_CTR`, but this algorithm is only available when MariaDB is built with recent versions of [OpenSSL](https://www.openssl.org/). If the server is built with [wolfSSL](https://www.wolfssl.com/products/wolfssl/) or [yaSSL](https://www.wolfssl.com/products/yassl/), then this algorithm is not available. See [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index) for more information about which libraries are used on which platforms.
* **Commandline:** `--eperi-key-management-plugin-encryption-algorithm=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `AES_CBC`
* **Valid Values:** `AES_CBC`, `AES_CTR`

 

---

 ### `eperi_key_management_plugin_encryption_mode`

 * **Description:** Encryption mode.
* **Commandline:** `--eperi-key-management-plugin-encryption-mode=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `enumerated`
* **Default Value:** `database`
* **Valid Values:** `database`, `gateway`

 

---

 ### `eperi_key_management_plugin_osslmt`

 * **Description:** Determines, whether the plugin should register callback functions for OpenSSL thread support.
* **Commandline:** `--eperi-key-management-plugin-osslmt=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `0` (Linux), `1` (Windows)

 

---

 ### `eperi_key_management_plugin_port`

 * **Description:** Listener port for plugin.
* **Commandline:** `--eperi-key-management-plugin-port=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `integer`
* **Default Value:** `14332`

 

---

 ### `eperi_key_management_plugin_url`

 * **Description:** URL to key server. The expected format of the URL is <host>:<port>. The port number is optional, and the port number defaults to 14333 if it is not specified.
* **Commandline:** `--eperi-key-management-plugin-url=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `string`
* **Default Value:** `NULL`

 

---

 ### `eperi_key_management_plugin_url_check_disabled`

 * **Description:** Determines, whether the connection between plugin and eperi Gateway is tested at server startup.
* **Commandline:** `--eperi-key-management-plugin-url-check-disabled=value`
* **Scope:** Global
* **Dynamic:** No
* **Data Type:** `boolean`
* **Default Value:** `1`

 

---

 Options
-------

 ### `eperi_key_management_plugin`

 * **Description:** Controls how the server should treat the plugin when the server starts up.
	+ Valid values are:
		- `OFF` - Disables the plugin without removing it from the `[mysql.plugins](../mysqlplugin-table/index)` table.
		- `ON` - Enables the plugin. If the plugin cannot be initialized, then the server will still continue starting up, but the plugin will be disabled.
		- `FORCE` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error.
		- `FORCE_PLUS_PERMANENT` - Enables the plugin. If the plugin cannot be initialized, then the server will fail to start with an error. In addition, the plugin cannot be uninstalled with `[UNINSTALL SONAME](../uninstall-soname/index)` or `[UNINSTALL PLUGIN](../uninstall-plugin/index)` while the server is running.
	+ See [Plugin Overview: Configuring Plugin Activation at Server Startup](../plugin-overview/index#configuring-plugin-activation-at-server-startup) for more information.
* **Commandline:** `--eperi-key-management-plugin=value`
* **Data Type:** `enumerated`
* **Default Value:** `ON`
* **Valid Values:** `OFF`, `ON`, `FORCE`, `FORCE_PLUS_PERMANENT`

 

---

 See Also
--------

 * [Database Encryption - eperi](https://eperi.com/database-encryption/)
* [eperi Gateway for Databases version 3.4 offers native MariaDB support](https://eperi.com/eperi-gateway-for-databases-version-3-4-offers-native-mariadb-support/)
* [eperi Customer Portal](https://customer.eperi.de/index.jsp)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/eperi-key-management-encryption-plugin/>

Diagnostics Area
================

     The diagnostics area contains information about the error conditions which were produced by an SQL statement, as well as some information about the statement which generated them.

 Statement Information
---------------------

 The statement information area contains the following data:

 * NUMBER is the number of conditions which are present in the diagnostics area.
* ROW\_COUNT has the same value as the [ROW\_COUNT()](../row_count/index) function for the statement that produced the conditions.

 Condition Information
---------------------

 Each condition has several properties, which are explained here.

 ### Data Types and Sizes

 The following table shows the type and size of all the properties:

 


| Property name | Property type | Notes |
| --- | --- | --- |
| RETURNED\_SQLSTATE | VARCHAR(5) |  |
| MYSQL\_ERRNO | SMALLINT UNSIGNED |  |
| MESSAGE\_TEXT | VARCHAR(512) | Before [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/), was VARCHAR(128) |
| CLASS\_ORIGIN | VARCHAR(64) |  |
| SUBCLASS\_ORIGIN | VARCHAR(64) |  |
| CONSTRAINT\_CATALOG | VARCHAR(64) |  |
| CONSTRAINT\_SCHEMA | VARCHAR(64) |  |
| CONSTRAINT\_NAME | VARCHAR(64) |  |
| CATALOG\_NAME | VARCHAR(64) |  |
| SCHEMA\_NAME | VARCHAR(64) |  |
| TABLE\_NAME | VARCHAR(64) |  |
| COLUMN\_NAME | VARCHAR(64) |  |
| CURSOR\_NAME | VARCHAR(64) |  |

 
These properties can never be set to NULL. If they are empty, the empty string is used.

 ### Common Condition Properties

 The most common ones have a value for all built-in errors, and can be read both via SQL and via the API:

 RETURNED\_SQLSTATE is the SQLSTATE of the condition. It is a five characters code, composed by a class (first two characters) and a subclass (last three characters). For more information about this property, refer to the [SQLSTATE](../sqlstate/index) page.

 MYSQL\_ERRNO is the error code. Each built-in condition has a unique numeric code. 0 indicates success, but it cannot be explicitly set or read via SQL. For a list of built-in error codes, refer to [MariaDB Error Codes](../mariadb-error-codes/index). The API function to read it is mysql\_errno().

 MESSAGE\_TEXT is a descriptive, human-readable message. For built-in errors, parsing this string is the only way to get more information about the error. For example, parsing a message like "Table 'tab1' already exists", a program can find out that the missing table is tab1. The API function to read it is mysql\_error().

 For conditions generated by the user via SIGNAL, if MYSQL\_ERRNO and MESSAGE\_TEXT are not specified, their default values depend on the first two SQLSTATE characters:

 * '00' means 'success'. It can not be set in any way, and can only be read via the API.
* For '01' class, default MYSQL\_ERRNO is 1642 and default MESSAGE\_TEXT is 'Unhandled user-defined warning condition'.
* For '02' class, default MYSQL\_ERRNO is 1643 and default MESSAGE\_TEXT is 'Unhandled user-defined not found condition'.
* For all other cases, including the '45000' value, default MYSQL\_ERRNO is 1644 and default MESSAGE\_TEXT is 'Unhandled user-defined exception condition'.

 ### Special Condition Properties

 There are more condition properties, which are never set for built-in errors. They can only be set via SIGNAL and RESIGNAL statements, and can only be read via GET DIAGNOSTICS - not via the API. Such properties are:

 CLASS\_ORIGIN indicates whether the SQLSTATE uses a standard class or a software-specific class. If it is defined in the SQL standards document ISO 9075-2 (section 24.1, SQLSTATE), this property's value is supposed to be 'ISO 9075', otherwise it is supposed to be 'MySQL'. However, any string is accepted.

 SUBCLASS\_ORIGIN indicates whether the SQLSTATE uses a standard subclass or a software-specific class. If the SQLSTATE is defined in the SQL standards document ISO 9075-2 (section 24.1, SQLSTATE), this property's value is supposed to be 'ISO 9075', otherwise it is supposed to be 'MySQL'. However, any string is accepted.

 SCHEMA\_NAME indicates in which schema (database) the error occurred.

 TABLE\_NAME indicates the name of the table which was accessed by the failed statement.

 COLUMN\_NAME indicates the name of the column which was accessed by the failed statement.

 CONSTRAINT\_NAME indicates the name of the constraint that was violated.

 CONSTRAINT\_SCHEMA indicates in which schema the violated constraint is located.

 CURSOR\_NAME indicates the name of the cursor which caused the error.

 The following properties can be used and are defined in the standard SQL, but have no meaning because MariaDB doesn't currently support catalogs:

 CATALOG\_NAME is used by the standard SQL to indicate in which catalog the error occurred.

 CONSTRAINT\_CATALOG is used by the standard SQL to indicate in which catalog the violated constraint is located.

 How the Diagnostics Area is Populated and Cleared
-------------------------------------------------

 When a statement produces one or more error conditions (errors, warnings, notes) the conditions are inserted into the diagnostics area, and the statement information area is updated with that statement’s information. Usually, this also clears all the old conditions from the diagnostics area, but there is an exception: if the new statement is a correctly parsed RESIGNAL or GET DIAGNOSTICS, the old contents will remain in the diagnostics area. SIGNAL clears the old conditions.

 When a table-based statement (like INSERT) is executed, the old data in the diagnostics area is cleared even if the statement doesn't produce any condition. However, statements which don't access any table (like SET, or a SELECT with no FROM clause) is executed and produces no warnings, the diagnostics area remains unchanged.

 The maximum number of conditions that can be in the diagnostics area is `[max\_error\_count](../server-system-variables/index#max_error_count)`. If this value is 0, the diagnostics area is empty. If this variable is changed, the new value takes effect with the next statement (that is, the diagnostics area is not immediately truncated).

 How to Access the Diagnostics Area
----------------------------------

 The following statements explicitly add conditions to the diagnostics area:

 * [SIGNAL](../signal/index): produces a custom error.
* [RESIGNAL](../resignal/index): after an error is produced, generates a modified version of that error.

 The following statements read contents from the diagnostics area:

 * [GET DIAGNOSTICS](../get-diagnostics/index) is the only way to read all information
* [SHOW WARNINGS](../show-warnings/index) shows a summary of errors, warnings and notes
* [SHOW ERRORS](../show-errors/index) shows a summary of errors

 [DECLARE HANDLER](../declare-handler/index) can be used to handle error conditions within stored programs.

 [DECLARE CONDITION](../declare-condition/index) can be used to associate an SQLSTATE or an error code to a name. That name can be referenced in DECLARE HANDLER, SIGNAL and RESIGNAL statements.

 All these statements can also be executed inside a stored routine. However, only SHOW WARNINGS and SHOW ERRORS can be executed as a prepared statement. After an [EXECUTE](../execute-statement/index) statement, the diagnostics area contains information about the prepared statement, if it produces error conditions.

 See Also
--------

 * [RESIGNAL](../resignal/index)
* [SIGNAL](../signal/index)
* [HANDLER](../handler/index)
* [GET DIAGNOSTICS](../get-diagnostics/index)
* [SHOW WARNINGS](../show-warnings/index)
* [SHOW ERRORS](../show-errors/index)
* [DECLARE HANDLER](../declare-handler/index)
* [MariaDB Error Codes](../mariadb-error-codes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/diagnostics-area/>

OPEN
====

    Syntax
------

 <= [MariaDB 10.2](../what-is-mariadb-102/index)

 
```
OPEN cursor_name

```

From [MariaDB 10.3](../what-is-mariadb-103/index)

 
```
OPEN cursor_name [expression[,...]];

```
 Description
-----------

 This statement opens a [cursor](../programmatic-and-compound-statements-cursors/index) which was previously declared with [DECLARE CURSOR](../declare-cursor/index).

 The query associated to the DECLARE CURSOR is executed when OPEN is executed. It is important to remember this if the query produces an error, or calls functions which have side effects.

 This is necessary in order to [FETCH](../fetch/index) rows from a cursor.

 See [Cursor Overview](../cursor-overview/index) for an example.

 See Also
--------

 * [Cursor Overview](../cursor-overview/index)
* [DECLARE CURSOR](../declare-cursor/index)
* [FETCH cursor\_name](../fetch/index)
* [CLOSE cursor\_name](../close/index)
* [Cursors in Oracle mode](../sql_modeoracle-from-mariadb-103/index#cursors)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/open/>

FETCH
=====

    Syntax
------

 
```
FETCH cursor_name INTO var_name [, var_name] ...

```
 Description
-----------

 This statement fetches the next row (if a row exists) using the specified [open](../open/index) [cursor](../programmatic-and-compound-statements-cursors/index), and advances the cursor pointer.

 `var_name` can be a [local variable](../declare-variable/index), but *not* a [user-defined variable](../user-defined-variables/index).

 If no more rows are available, a No Data condition occurs with `SQLSTATE` value `02000`. To detect this condition, you can set up a handler for it (or for a `NOT FOUND` condition).

 See [Cursor Overview](../cursor-overview/index) for an example.

 See Also
--------

 * [Cursor Overview](../cursor-overview/index)
* [DECLARE CURSOR](../declare-cursor/index)
* [OPEN cursor\_name](../open/index)
* [CLOSE cursor\_name](../close/index)
* [Cursors in Oracle mode](../sql_modeoracle-from-mariadb-103/index#cursors)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/fetch/>

Error Codes
============

  

| Title | Description |
| --- | --- |
|  [MariaDB Error Codes](../mariadb-error-codes/index) |  MariaDB error codes reference list.  |
|  [Operating System Error Codes](../operating-system-error-codes/index) |  Linux and Windows operating system error codes.  |
|  [SQLSTATE](../sqlstate/index) |  A string which identifies a condition's class and subclass  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/error-codes/>

MySQL Sandbox
=============

    
MySQL Sandbox has been deprecated. See [dbdeployer](../dbdeployer/index) instead.

 
MySQL Sandbox is a Perl Module for installing multiple versions of MariaDB and/or MySQL in isolation from each other. It is primarily used for easily testing different server versions.

 Visit <http://mysqlsandbox.net/> for details on how to install and use it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql-sandbox/>

dbForge Studio for MariaDB
==========================

    ![dbForge-Studio-for-MySQL-new]** is a universal IDE with GUI tools that has all the necessary built-in capabilities to work with MariaDB and MySQL databases for their development, management, and administration. It allows for creating, managing, and editing the data without the need to store them locally. 

 This powerful GUI tool offers a rich visual design that is perfect for working with large scripts, preparing data reports, and database projects. At any time, you can back up or restore your data, export or import them to and from the most commonly used formats, and compare or synchronize the MariaDB databases. Apart from that, dbForge Studio supports the following servers:

 * MariaDB,
* SkySQL (the MariaDB cloud database),
* All MySQL Server versions,
* Percona servers and TokuDB,
* MySQL and MariaDB on Amazon RDS and Amazon Aurora.
* Google Cloud, Alibaba Cloud, Tencent Cloud, Galera Cluster,
* Sphinx, etc.

 Key Features:
-------------

 ### 1. Intelligent SQL Coding

 * Automatic code completion
* MariaDB syntax highlighting
* Code refactoring and formatting
* CRUD generation

 ![overview-database-developement-2023]

 ### 2. Database Compare and Sync

 * Data and schema synchronization and comparison
* Recurring database sync tasks planning
* Comparison report generation

 ### 3. Import/Export Data MariaDB

 * MariaDB data export to 14 commonly-used formats
* Data import from 10 popular formats into MariaDB table
* Rich customization ability
* Command-line automation for data tasks

 ### 4. MariaDB Admin Tools

 * MariaDB databases backing up and restoring
* User accounts and permissions configuration
* Table maintenance
* Database scripts generation

 ![overview-database-administration-2023]

 ### 5. Copy Database

 * Source and Target servers’ selection
* Database to be copied or dropped selection
* Configuration of the database copying parameters
* Progress of copying tracing and abortion of the copying

 ### 6. Database Designer

 * Schema diagrams generation
* Visual database construction
* Foreign key relations between tables

 ![overview-database-design](https://mariadb.com/kb/en/dbforge-studio-for-mariadb-universal-gui-tool-for-management-administration/+image/overview-database-design "overview-database-design")

 ### 7. Data Generator

 * Data customization supported by multiple generators
* All kinds of generators: basic, meaningful, and user-defined
* Real-time preview of generated data
* Command-line interface

 ### 8. Query Profiler

 * Visual query profiling
* Profiling results comparison

 ### 9. Visual Query Builder

 * Automatic generation of the script template for queries
* Easy navigation through the database objects
* Support for different query types
* Support for sequence tables

 ![support-sequence-table-in-query-builder]

 ### 10. Table Designer

 * Table creation and editing in MariaDB with no code
* Automatic data type setting for frequently-used column values
* Errors prevention while working with tables
* MariaDB script automatic generation according to the changes made by a user

 ### 11. Database Refactoring

 * Renaming database objects with preview
* Refactoring script

 ### 12. Database Projects

 * MariaDB version control system providing efficient database team development
* Scripts folder for exporting a database project to a MariaDB script file

 ### 13. Report and Analysis

 * Pivot tables for summarizing and viewing the data
* A powerful wizard with robust features
* Full command-line support
* 9 formats for reports' delivery

 ![overview-report-designer1-2023](https://mariadb.com/kb/en/dbforge-studio-for-mariadb-universal-gui-tool-for-management-administration/+image/overview-report-designer1-2023 "overview-report-designer1-2023")

 ### 14. Database Documenter

 * A comprehensive overview of the database structure
* Examine the internal dependencies between objects and databases
* Customize the style and generate the docs in several formats

 ### 15. Support for MariaDB objects:

 * Packages
* Sequences

 Nowadays, with the growing popularity of the MariaDB database, the demand for a convenient, multi-functional tool is increasing, too. This solution must meet users’ needs, be easy to work with and provide constant support. Fortunately, [dbForge Studio for MariaDB and MySQL](https://www.devart.com/dbforge/mysql/studio/) is such a solution. This database tool is one of the most appreciated worldwide and trusted by many people. Devart’s dbForge Studio has received a lot of awards that confirm its overwhelming popularity. 

 

---

 Download a free 30-day trial of dbForge Studio for MariaDB and MySQL [here](https://www.devart.com/dbforge/mysql/studio/download.html).

 [Documentation](https://docs.devart.com/studio-for-mysql)

 [Editions](https://www.devart.com/dbforge/mysql/studio/editions.html)

 

---

 


| Version | Introduced |
| --- | --- |
| dbForge Studio for MySQL 9.2 | Support for [MariaDB 11.3](../what-is-mariadb-113/index), enhanced code completion for application-period temporal tables, support for sequence tables in MariaDB databases |
| dbForge Studio for MySQL 9.1 | Connectivity support for [MariaDB 10.9](../what-is-mariadb-109/index) -10.10 |
| dbForge Studio for MySQL 9.0 | Connectivity support for [MariaDB 10.5](../what-is-mariadb-105/index)-10.6 |
| dbForge Studio for MySQL 8.1 | Support for [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Studio for MySQL 8.0 | Support for [MariaDB 10.3](../what-is-mariadb-103/index) |
| dbForge Studio for MySQL 7.3 | Support for [MariaDB 10.2](../what-is-mariadb-102/index), Support for [MariaDB 10.1](../what-is-mariadb-101/index), Support for MariaDB Galera Cluster 10.0 Series |
| dbForge Studio for MySQL 6.1 | [MariaDB 10.0](../what-is-mariadb-100/index), [MariaDB 5.5](../what-is-mariadb-55/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-studio-for-mariadb-universal-gui-tool-for-management-administration/>

dbForge Edge
============

    **[dbForge Edge](https://www.devart.com/dbforge/edge/)** is a versatile software solution designed to meet the needs of full-stack database specialists. It offers a wide range of features to address database challenges across major providers: MySQL/MariaDB, SQL Server, Oracle, and PostgreSQL. When it comes to MySQL and MariaDB, dbForge Edge provides a highly functional IDE that covers almost all aspects of database development and management. 

 **Key Features of dbForge Edge:** 

 **Design** 

 dbForge Edge includes a built-in Database Designer equipped with ER diagrams, allowing users to construct and edit databases. An intuitive interface facilitates the creation of database structures and generation of reusable SQL scripts for creating actual databases. Table Designer is a separate feature for visual creation and management of tables that covers the setup of columns, data types, constraints, etc. 

 **SQL Development** 

 dbForge Edge offers a powerful set of features to simplify SQL coding tasks. The code assistance module offers context-based keyword and object suggestions, code completion, instant syntax validation, customizable code formatting profiles, debugging, and code refactoring capabilities. Another feature worth mentioning is Query Builder – a tool that allows users to construct even the most complex SQL queries effortlessly in a visual mode. 

 **Database Management** 

 The solution incorporates schema and data comparison tools, enabling users to identify and manage differences in database schemas and table data. With automatically generated synchronization scripts, changes can be seamlessly deployed to target platforms. Comparison and synchronization jobs can also be automated, improving user efficiency. 

 Also, dbForge Edge supports data migration (import and export) in over 10 major data formats. Both the import and export processes can be tailored to meet any specific requirements and automated for efficient workflows. 

 **Testing** 

 The solution features a robust Data Generator capable of producing high-quality test data in varying volumes and formats. Additionally, the Query Profiler tool enables comprehensive analysis and optimization of queries, thereby saving valuable time and resources. 

 **Security Management** 

 The dedicated module deals with user management configurations. The functionality provided by the software allows easy creation, editing, and management of user accounts and privileges. 

 **Documenting and Reporting** 

 With dbForge Edge, users can create detailed database documentation in various formats and with convenient navigation. The reporting module enables the summarization and analysis of data, presenting comprehensive reports with informative graphs, diagrams, and pivot tables. 

 dbForge Edge is not just a comprehensive IDE for MySQL and MariaDB – it goes far beyond that. It serves as an all-in-one solution for database experts who work with multiple database management systems, eliminating the need to assemble toolsets for each. With its extensive feature set, dbForge Edge empowers professionals to efficiently perform their tasks across diverse database environments.

 

---

 [Download a free 30-day trial of dbForge Edge](https://www.devart.com/dbforge/edge/download.html)

 [Order now](https://www.devart.com/dbforge/edge/ordering.html)

 

---

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-edge/>

DBeaver
=======

    [DBeaver](http://dbeaver.jkiss.org/) is a free multi-platform database tool for developers, SQL programmers, database administrators and analysts. It supports all popular relational databases: MySQL, MariaDB, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, Teradata, Netezza, etc. Also, it supports NoSQL databases: MongoDB, Cassandra, Redis, Apache Hive, etc. in the Enterprise Edition version.

 A brief list of basic features can be found below:

 * Data viewer and editor: sorting, filtering, image displaying, export of selected data and much more.
* Metadata browser: possibility to view and edit existing tables, views, columns, indexes, procedures, triggers, storage entities (tablespaces, partitions, etc), security entities (users, roles, etc).
* Data transfer: export and import for files in various formats (CSV, HTML, XML, XLS, XLSX).
* ER diagrams: possibility to automatically generate ER diagrams for a database/schema (diagram will contain all schema tables) or for a single table and export the diagram in a suitable format.
* SQL editor: possibility to organize all your scripts in folders, reassign database connections for particular scripts.
* Data and metadata search: full-text data search using against all chosen tables/views.
* Database structure comparing: possibility to perform objects structure compare.

 DBeaver is actively developed and maintained. Usability is the main goal of this project, so program UI is carefully designed and implemented. Every user can send bug report and feature request on the [GitHub page](https://github.com/serge-rider/dbeaver).

 ![screen1](https://mariadb.com/kb/en/graphical-and-enhanced-clients-dbeaver/+image/screen1 "screen1")

 ![screen2](https://mariadb.com/kb/en/graphical-and-enhanced-clients-dbeaver/+image/screen2 "screen2")

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/graphical-and-enhanced-clients-dbeaver/>

ERBuilder Data Modeler
======================

    ![ERBuilder-logo]

 [ERBuilder Data Modeler](https://soft-builder.com/erbuilder-data-modeler/) is a GUI data modeling tool that allows developers to visualize, design, and model databases by using entity relationship diagrams and automatically generates the most popular SQL databases. Generate and share the data Model documentation with your team. Optimize your data model by using advanced features such as test data generation, schema compare, and schema synchronization

 **Supported DBMS include:**

 * MariaDB
* MySQL
* Microsoft SQL Server
* Microsoft Azure SQL database
* Oracle
* PostgreSQL
* SQLite
* Firebird
* Amazon Redshift
* Amazon RDS

 **Key features:**

 * Visual data modeling
* Forward and Reverse Engineering
* Data Model Validation
* Data model documentation
* Schema Comparison and Synchronization
* Test data generation
* Change Database Platform
* Generate web user interface for CRUD
* Version management

 ![ERBuilder-main-screen]

 **Freeware version**

 Feature limited free version is available for download. Advanced features are available in the commercial edition. A [feature comparison matrix](https://soft-builder.com/features/) is available for more details about features, pricing, and "trial" versions, 

 **More information**

 See <https://www.soft-builder.com> for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/erbuilder-data-modeler/>

SQLyog: Community Edition
=========================

    SQLyog (<https://webyog.com/product/sqlyog/>) is a GUI tool to manage MySQL and MariaDB servers and databases in physical, virtual, and cloud environments. DBAs, developers, and database architects alike, use SQLyog to visually compare, optimize, and document schemas.

 Key Features ● Automatically synchronize data ● Visually compare data ● Import external data

 Additional Highlights ● Runs on Microsoft Windows with no dependencies on runtimes (such as Microsoft .NET and Java) and database abstraction layers (such as ODBC and JDBC). ● Distributed as a free Community edition and as a paid, proprietary Ultimate edition. Learn about why you should consider upgrading from the Community edition to the Ultimate edition here.

 Click here for the Community version. <https://github.com/webyog/sqlyog-community/blob/master/README.md>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sqlyog-community-edition/>

HeidiSQL
========

    [HeidiSQL](http://www.heidisql.com/) is a Windows client for MariaDB and MySQL, and is bundled with the Windows version of MariaDB.

 


| HeidiSQL Version | Introduced |
| --- | --- |
| HeidiSQL 11.0 | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/), [MariaDB 5.5.68](https://mariadb.com/kb/en/mariadb-5568-release-notes/) |
| HeidiSQL 10.2 | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/), [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/), [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/), [MariaDB 10.1.41](https://mariadb.com/kb/en/mariadb-10141-release-notes/), [MariaDB 5.5.65](https://mariadb.com/kb/en/mariadb-5565-release-notes/) |
| HeidiSQL 9.5 | [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/), [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/), [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.0.38](https://mariadb.com/kb/en/mariadb-10038-release-notes/), [MariaDB 5.5.63](https://mariadb.com/kb/en/mariadb-5563-release-notes/) |
| HeidiSQL 9.4 | [MariaDB 10.1.20](https://mariadb.com/kb/en/mariadb-10120-release-notes/), [MariaDB 10.0.29](https://mariadb.com/kb/en/mariadb-10029-release-notes/), [MariaDB 5.5.54](https://mariadb.com/kb/en/mariadb-5554-release-notes/) |
| HeidiSQL 9.3 | [MariaDB 10.1.15](https://mariadb.com/kb/en/mariadb-10115-release-notes/), [MariaDB 10.0.26](https://mariadb.com/kb/en/mariadb-10026-release-notes/), [MariaDB 5.5.50](https://mariadb.com/kb/en/mariadb-5550-release-notes/) |
| HeidiSQL 9.1 | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/), [MariaDB 10.0.17](https://mariadb.com/kb/en/mariadb-10017-release-notes/), [MariaDB 5.5.42](https://mariadb.com/kb/en/mariadb-5542-release-notes/) |
| HeidiSQL 8.3 | [MariaDB 10.0.12](https://mariadb.com/kb/en/mariadb-10012-release-notes/), [MariaDB 5.5.38](https://mariadb.com/kb/en/mariadb-5538-release-notes/) |
| HeidiSQL 8.0 | [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/), [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/) |
| HeidiSQL 7.0 | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/), [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |

 
HeidiSQL can:

 * Connect to multiple servers in one window
* Connect to servers via commandline
* Create and edit tables, views, stored routines, triggers and scheduled events.
* Generate nice SQL-exports
* Export from one server/database directly to another server/database
* Manage user-privileges
* Import text-files
* Export table rows as CSV, HTML, XML, SQL, LaTeX and Wiki Markup
* Browse and edit table-data using a comfortable grid
* Bulk edit tables (move to db, change engine, collation etc.)
* Batch-insert ascii or binary files into tables
* Write queries with customizable syntax-highlighting and code-completion
* Pretty reformat disordered SQL
* Monitor and kill client-processes
* Find specific text in all tables of all databases of one server
* Optimize and repair tables in a batch manner
* And more...

 More information, including [Screenshots of HeidiSQL](http://www.heidisql.com/screenshots.php) are available at the [HeidiSQL Website](http://www.heidisql.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/heidisql/>

Navicat
=======

    [Navicat](http://www.navicat.com/products/navicat-for-mariadb) is a graphical front-end for MariaDB. It is a commercial product with several different versions (Navicat Premium, Navicat for MySQL, etc...) and different "editions" within those versions (Non-commercial, Standard, and Enterprise). Certain features are only available in certain editions/versions.

 Navicat is compatible with all versions of MariaDB and with MySQL 3.21 and above. It is available for Windows, MacOS, and Linux.

 In addition to standard client features, it includes:

 * a SQL Builder/Editor
* a Data Modeling Tool (Enterprise version only)
* Data/Structure Synchronization
* Report Builder (Windows-only)
* "Premium" version which can connect to MariaDB, MySQL, SQL Server, SQLite, Oracle, and PostgreSQL databases simultaneously.

 A [feature comparison matrix](http://www.navicat.com/products/navicat-for-mysql-feature-matrix) is available. More information, including pricing and "trial" versions, is available on the [Navicat website](http://www.navicat.com).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/navicat/>

Querious
========

    Querious is a database administration tool for macOS.

 It can be purchased/downloaded at <http://www.araelium.com/querious>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/querious/>

TablePlus
=========

    [TablePlus](https://tableplus.com/) is a modern, native app with a clean user interface that allows developers to simultaneously manage databases in a very fast and secure way. TablePlus supports most of the popular databases such as MySQL, Postgres, SQL Server, SQLite, Microsoft SQL Server, Redis, Redshift, Oracle, and many more.

 ![table](https://mariadb.com/kb/en/tableplus/+image/table "table")

 TablePlus is compatible with all versions of MariaDB. It is available for macOS, Windows, iOS, and Linux at the moment.

 Some notable features:

 * Native build
* Convenient query editor
* Multi Tabs & Code Review
* Can connect to multiples databases simultaneously.

 TablePlus is available for free, but users can purchase a license to remove some limitations and customize the tool for higher needs on [TablePlus website](https://tableplus.com/pricing).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tableplus/>

Database Workbench
==================

    [Database Workbench](http://www.upscene.com/database_workbench/) is a Windows application (*which works fine under Wine on Linux*) for database design, development, maintenance and testing for several database systems: MySQL, MariaDB, Oracle, Firebird, InterBase, Microsoft SQL Server, SQL Anywhere and NexusDB.

 With Database Workbench you can:

 * design a database
* connect to multiple databases
* view and modify meta data
* view and modify data
* import and export data
* connect to any ODBC/ADO data source
* transfer data between database systems
* migrate meta data
* compare meta data
* manage privileges
* debug stored procedure
* print meta data or data

 It includes numerous other tools, [more screen shots are available](http://www.upscene.com/database_workbench/learnmore).

 Database Workbench comes in multiple editions and is licensed on a per module basis, so there's always a version that suits you.

 ![dbwoverview](https://mariadb.com/kb/en/database-workbench/+image/dbwoverview "dbwoverview")

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-workbench/>

Luna Modeler
============

    [Luna Modeler](https://www.datensen.com/) is a database design tool for MariaDB and other relational databases. 

 Draw diagrams, reverse engineer existing database structures and generate SQL code.

 **Supported platforms include:**

 * MariaDB
* PostgreSQL
* SQLite

 **Key features:**

 * Database modeling & schema design
* Reverse engineering
* Support for database-specific settings
* Three display modes: metadata, sample data or descriptions
* Default values for newly created objects
* Export to PDF
* Dark and Light themes
* SQL script generation

 ![mariadb-database-design-luna-modeler](https://mariadb.com/kb/en/luna-modeler/+image/mariadb-database-design-luna-modeler "mariadb-database-design-luna-modeler")

 **Supported OS**

 Luna Modeler is available for Windows, Linux and macOS.

 **More information**

 See <https://www.datensen.com> for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/luna-modeler/>

phpMyAdmin
==========

    phpMyAdmin is a web-based tool for administering MariaDB and MySQL.

 It requires a web server, PHP, and a browser.

 Read more at <http://phpmyadmin.net>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/phpmyadmin/>

SQLTool Pro Database Editor
===========================

    [SQLTool Pro](http://www.sqltoolpro.com/) is an Android client for MariaDB and several other databases.

 SQLTool Pro supports:

 * Interfaces optimized for both mobile and tablet devices
* SSH tunneling with password and public key authentication
* Exporting of data to CSV files
* Customized queries using the query builder

 More information is available on the [SQLTool Pro Website](http://www.sqltoolpro.com/).

 SQLTool Pro phone interface:  
 ![SQLTool Pro phone interface]

 SQLTool Pro tablet interface:  
 ![SQLTool Pro tablet interface]

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sqltool-pro-database-editor/>

dbForge Data Compare
====================

    [**dbForge Data Compare**](https://www.devart.com/dbforge/mysql/datacompare/) helps compare and synchronize data in MariaDB, MySQL, and Percona databases and scripts folders. With this powerful GIU tool, you can easily find differences between your data, as it helps analyze comparison results, creates a synchronization script, and applies changes. Plus, MariaDB data can be compared with command-line support.

 dbForge Data Compare Tool Features:
-----------------------------------

 ### 1. Database Synchronization Features

 * Create accurate synchronization scripts
* Synchronize asynchronous data
* Create custom scripts with execution before/after the process of data synchronization
* Get warning messages on errors during synchronization

 ![synchronization-features]

 ### 2. MySQL & MariaDB Task Automation

 * Automate routine synchronizations with a command-line interface
* Plan your routine execution with Windows Scheduler
* Support for PowerShell compatibility

 ![automate-routine-task]

 ### 3. Script for Folder Data Comparison

 * Compare data from your database with the data placed in the script folder locally
* Choose any database, connection, or script folder with the new Data Comparison Wizard
* See the data comparison results in a data result grid

 ![script-folder-comparison]

 ### 4. Rich configurations for data comparison

 * Enjoy various options for automatic mapping
* Compare customized queries
* Compare custom keys

 ![data-comparsion-setup]

 ### 5. Supported Data

 * Tables
* Views
* BLOB data
* Compare databases and sync different MariaDB versions

 ### 6. Broad Compatibility Options

 * All popular MariaDB server versions
* MariaDB set up on Windows, Linux, FreeBSD, etc.
* Various cloud services: Amazon RDS, Amazon Aurora, Google Cloud, Oracle MySQL Cloud, Alibaba Cloud
* Secure Socket Layer (SSL), Secure Shell (SSH), HTTP Tunneling, PAM Percona security connections

 ### 7. Manage Comparison Results

 * Find tables by name
* Filter the comparison process results
* Enter the values of default comparison options
* Group records by type in each compared object

 ### 8. Export Comparison Results

 * Use only relevant data in your reports
* Generate comparison reports in various formats

 Download a free 30-day trial of dbForge Data Compare [here](https://www.devart.com/dbforge/mysql/datacompare/download.html).

 [Documentation](https://docs.devart.com/data-compare-for-mysql)

 


| Version | Introduced |
| --- | --- |
| dbForge Data Compare 5.7 | Connectivity support for [MariaDB 10.5](../what-is-mariadb-105/index) is added |
| dbForge Data Compare 5.5 | Support for [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Data Compare 5.4 | Support for [MariaDB 10.3](../what-is-mariadb-103/index) |
| dbForge Data Compare 5.3 | Support for [MariaDB 10.2](../what-is-mariadb-102/index), Support for [MariaDB 10.1](../what-is-mariadb-101/index) |
| dbForge Data Compare 4.1 | [MariaDB 10.0](../what-is-mariadb-100/index), [MariaDB 5.5](../what-is-mariadb-55/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-data-compare/>

dbForge Fusion: MySQL & MariaDB Plugin for VS
=============================================

    ![dbforge_fusion_for_mysql] is a powerful add-in for Visual Studio. It provides automatic and simple MariaDB database development and boosts data management capacity. With this tool integrated, it is easy to work with database development and administration tasks from Visual Studio.

 dbForge Fusion add-in Key Features:
-----------------------------------

 ### 1. MySQL & MariaDB Data Import to Visual Studio

 Import table data from multiple tables in various formats with the Data Import Wizard

 Save import configuration templates for future use

 ### 2. Data Export from Visual Studio

 Export data from multiple tables to various formats

 Create templates with export settings for later use

 ### 3. Visual Studio Schema Compare

 Generate schema synchronization scripts

 Filter the results of a comparison process

 Generate comparison reports

 ![mysql-schema-compare-wizard]

 ### 4. Data Comparison

 Sync data with a command-line interface

 Adjust and export comparison results

 Generate a schema synchronization script

 Filter objects during data comparison

 ![generatedatacomparisonreport]

 ### 5. Integration with Devart dotConnect

 Complete codes easily

 Enjoy advanced formatting

 ### 6. Drag&Drop from Database Explorer to WinForms

 Drag database objects easily

 Execute automatically generated scripts of components

 See the result in a convenient grid

 ### 7. Code Formatter and Syntax Checker

 Code snippets

 Keyword and object suggestion

 Errors highlighting 

 ### 8. Code formatting

 Embedded formatting profiles that can be swapped

 Command-line support for automatic and scheduled formatting tasks

 Bulk formatting

 ### 9. Routine Debugger

 Automate the debugging process 

 Simplify your work with stored routines and triggers

 ### 10. Object editors

 Enjoy visual creation, modification and management of any database and table objects

 Download a free 30-day trial of dbForge Fusion for MariaDB and MySQL [here](https://www.devart.com/dbforge/mysql/fusion/download.html).

 [Documentation](https://docs.devart.com/fusion-for-mysql)

 [Editions](https://www.devart.com/dbforge/mysql/fusion/editions.html)

 


| Version | Introduced |
| --- | --- |
| dbForge Fusion for MariaDB and MySQL 6.6 | [MariaDB 10.1](../what-is-mariadb-101/index)-10.5 |
| dbForge Fusion for MariaDB and MySQL 6.1 | [MariaDB 10.0](../what-is-mariadb-100/index), [MariaDB 5.5](../what-is-mariadb-55/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-fusion-mysql-mariadb-plugin-for-vs/>

dbForge Query Builder for MySQL & MariaDB
=========================================

    ![dbforge_query_builder_for_mysql] is a powerful visual tool that helps create any sort of MariaDB queries. Building a code has never been so easy – the query can be drawn on a diagram.

 dbForge Query Builder Key features:
-----------------------------------

 ### 1. Exporting Data

 Export your data to 14 popular formats

 Export data from several tables simultaneously

 Create templates for repeated operations

 ![slider-export-data]

 ### 2. Database Explorer

 Work with multiple database connections

 Easy MariaDB query management with drag&drop functionality

 Quick script generation

 ![slider-database-explorer](https://mariadb.com/kb/en/dbforge-query-builder-for-mysql-mariadb/+image/slider-database-explorer "slider-database-explorer")

 ### 3. Visual Drag and Drop Query Builder

 Enjoy zooming and keyboard support in a sophisticated diagram

 Preview and print diagrams

 Add and edit sub-queries visually

 MariaDB JOINs generator

 ![slider-query-builder](https://mariadb.com/kb/en/dbforge-query-builder-for-mysql-mariadb/+image/slider-query-builder "slider-query-builder")

 ### 4. SQL Editing and Execution

 Check the syntax automatically

 Get quick information about schema objects

 Customize formatting profiles

 Execute scripts, statements and MariaDB fragments seamlessly

 ![slider-sql-editing-and-execution]

 ### 5. Query Profiler

 Compare the results of the query visually

 Review and evaluate a query plan shown in the tree view

 Get the detailed query information

 ![slider-query-profiler]

 ### 6. Data Editor

 Enjoy advanced data filters

 Browse and edit large objects in Data Viewer and Editor windows

 Fetch asynchronous data 

 ![slider-data-editor]

 ### 7. Data Reports

 Data Report wizard supports building Data Reports and customizing them with a rich set of controls.

 ![mysql-data-reports]

 ### 8. Master-Detail Browser

 Allows users to view and analyze the data of several related database objects in a master-detail structured document. Edit data, build relationships, filter data based on specific criteria, sort data, etc. in the Design and Data views.

 ![mysql-master-detail]

 ### 9. Pivot Tables

 Let the user manipulate the data visually, including sorting, grouping, or filtering fields, building charts, and calculating totals.

 ![mysql-pivot-table]

 Download a free 30-day trial of dbForge Query Builder for MariaDB and MySQL [here](https://www.devart.com/dbforge/mysql/querybuilder/download.html).

 [Documentation](https://docs.devart.com/querybuilder-for-mysql)

 


| Version | Introduced |
| --- | --- |
| dbForge Query Builder 4.5 | [MariaDB 10.5](../what-is-mariadb-105/index) |
| dbForge Query Builder 4.4 | [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Query Builder 4.3 | [MariaDB 10.3](../what-is-mariadb-103/index) |
| dbForge Query Builder 4.2 | [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.1](../what-is-mariadb-101/index) |
| dbForge Query Builder 3.1 | [MariaDB 10.0](../what-is-mariadb-100/index), [MariaDB 5.5](../what-is-mariadb-55/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-query-builder-for-mysql-mariadb/>

Improved SQL Document Parser Performance in Updated dbForge Tools for MySQL and MariaDB
=======================================================================================

    Devart has upgraded dbForge Tools for MySQL and MariaDB with improved SQL document parser performance.

 Devart, a recognized vendor of database management software, has released new versions of dbForge tools for MySQL product line – dbForge Schema Compare for MySQL, dbForge Data Compare for MySQL, dbForge Query Builder for MySQL and dbForge Data Generator for MySQL.

 dbForge Tools for MySQL have the following new features and improvements:

 * Improved SQL document parser performance;
* Connection through Named Pipe implemented;
* Improved XML View and new JSON View for Data Editor and Viewer Window;
* Additional SQL statements are supported;
* Syntax Check supports new [MariaDB 10.0](../what-is-mariadb-100/index) - 10.1 statements;
* Styled icons are used by default.

 The upgraded versions of dbForge Schema Compare for MySQL, dbForge Data Compare for MySQL, dbForge Query Builder for MySQL and dbForge Data Generator for MySQL are provided with Syntax Check that supports new [MariaDB 10.0](../what-is-mariadb-100/index) - 10.1 statements, also additional SQL statements are supported and other improvements were made.

 For more information about dbForge tools for MySQL, please visit <https://www.devart.com/dbforge/mysql/>.

 About Devart

 Devart is one of the leading developers of database tools and administration software, ALM solutions, data providers for various database servers, data integration and backup solutions. The company also implements Web and Mobile development projects. For additional information about Devart, visit <https://www.devart.com/>.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/graphical-and-enhanced-clients-improved-sql-document-parser-performance-in-/>

SQL Diagnostic Manager & SQLyog
===============================

    SQL Diagnostic Manager (<https://www.idera.com/productssolutions/sql-diagnostic-manager-for-mysql>) A monitoring tool that gives DBAs real-time insights for optimizing the performance of MariaDB servers.

 Key Features: 1. Agentless monitoring 2. Fully customizable 3. Affordable

 Webyog’s SQL DM is fully compatible with Amazon Aurora databases, and Webyog is an Amazon launch partner.

 Features specifically for RDS and Aurora instances also available. SQL Diagnostic Manager is browser based and is a proud MariaDB Monitor and Advisor. 

 SQLyog Ultimate (<http://www.webyog.com/en>) A MySQL administration tool for DBAs, developers, and database architects. This tool enables database developers, administrators, and architects to visually compare, optimize, and document schemas.

 Key Features: 1. Automatically synchronize data 2. Visually compare data 3. Import external data

 SQLyog runs on Windows and is a graphical MariaDB manager and admin tool, combining the features of MySQL Administrator, phpMyAdmin and other MariaDB Front Ends and MariaDB GUI tools.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cost-effective-agentless-mariadb-database-performance-management/>

mycli
=====

    **mycli** is a command line interface for MariaDB, MySQL, and Percona with auto-completion and syntax highlighting.

 It is written in Python, and runs on Linux, Mac and Windows.

 ![mycli_screenshot]

 Read more at <http://mycli.net>.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mycli/>

ocelotgui
=========

    The Ocelot GUI (ocelotgui), a database client, allows users to connect to a MySQL or MariaDB DBMS server, enter SQL statements, and receive results. Some of its features are: syntax highlighting, user-settable colors and fonts for each part of the screen, result-set displays with multi-line rows and resizable columns, and a debugger.

 Visit [ocelot.ca](http://ocelot.ca/) for more information and to download.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ocelotgui/>

Sequel Pro
==========

    [Sequel Pro](https://www.sequelpro.com) is a fast, easy-to-use Mac database management application for working with MySQL and MariaDB databases.

 [Sequel Pro](https://www.sequelpro.com) is open source, so it's easy to be involved and enhance it for MariaDB. You can also help by donating to the project!

 If you have any issues with Sequel Pro on MariaDB, please use the [issue tracking](https://github.com/sequelpro/sequelpro/issues) for that!

 See Also
--------

 * [Sequal Pro home site](https://www.sequelpro.com)
* [Source code](https://github.com/sequelpro)
* [Issue tracking](https://github.com/sequelpro/sequelpro/issues)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/graphical-and-enhanced-clients-sequel-pro/>

dbForge Data Generator
======================

    ![dbforge_data_generator_for_mysql_97x97] is a powerful solution that helps create massive volumes of meaningful and realistic data. This tool performs various predefined data generators with customizable options.

 Data Generator Key Features:
----------------------------

 ### 1. Extensive support for all column data types

 Enjoy the advantage of various data types support

 ![column-data-types]

 ### 2. Multiple generators with unique test data

 Enjoy multiple customization options with individual generators for every data type supported

 ![custom-options]

 ### 3. MariaDB data generation and data integrity support

 Generate consistent random data through multiple tables

 Disable triggers and constraints to avoid interference with database logic

 ### 4. MariaDB data distribution modes

 Fine-tune the way you want your data to be generated

 ### 5. Multiple ways to generate data in MySQL

 Generate a data population script, execute it against a MariaDB database, save or edit it later

 ### 6. Basic generators

 Populate tables with a great variety of values types, like JSON, Python, XML, etc.

 ![basic-generators-1](https://mariadb.com/kb/en/dbforge-data-generator/+image/basic-generators-1 "basic-generators-1")

 ### 7. Meaningful test data generators

 Select any of 200+ real-world generators and populate tables with realistic data related to various spheres

 ![meaningful-generators-1](https://mariadb.com/kb/en/dbforge-data-generator/+image/meaningful-generators-1 "meaningful-generators-1")

 ### 8. User-defined generators

 Create, save and use your own data generators tailored for your needs

 ### 9. Real-time data generation preview

 Enjoy real-time visualization of the alterations you make

 Visually assess the data to be generated

 ### 10. Command-line interface

 Schedule your routine data generation tasks

 Create a command-line execution file for running database documentation tasks

 ### 11. Broad compatibility options

 MariaDB server versions 5.5-10.6

 Various cloud services: Amazon RDS, Amazon Aurora, Google Cloud, Oracle MySQL Cloud, Alibaba Cloud

 Security connections: Secure Socket Layer (SSL), Secure Shell (SSH), HTTP Tunneling, PAM Percona

 Download a free 30-day trial of dbForge Data Generator [here](https://www.devart.com/dbforge/mysql/data-generator/download.html).

 [Documentation](https://docs.devart.com/data-generator-for-mysql/)

 


| Version | Introduced |
| --- | --- |
| dbForge Data Generator 2.4 | Connectivity support for [MariaDB 10.5](../what-is-mariadb-105/index) is added |
| dbForge Data Generator 2.2 | Support for [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Data Generator 2.1 | Support for [MariaDB 10.3](../what-is-mariadb-103/index) |
| dbForge Data Generator 2.0 | Support for [MariaDB 10.2](../what-is-mariadb-102/index), Support for [MariaDB 10.1](../what-is-mariadb-101/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-data-generator/>

dbForge Documenter for MariaDB and MySQL
========================================

    ![dbforge_documenter_for_mysql_1]** is a useful tool for the MariaDB database that allows for the automatic generation of database documentation in such formats as HTML, PDF, and Markdown. Users can adjust the created documentation with a great variety of options.

 dbForge Documenter for MariaDB and MySQL Key Features:
------------------------------------------------------

 ### 1. Searchable MariaDB & MySQL documentation

 Get the benefits of the search as you type principle

 View the highlighted matching text after entering the name of a required object in the search field

 ![doc-search]

 ### 2. Broad compatibility options

 MariaDB server versions 5.5-10.6

 Various cloud services: Amazon RDS, Amazon Aurora, Google Cloud, Oracle MySQL Cloud, Alibaba Cloud

 Security connections: Secure Socket Layer (SSL), Secure Shell (SSH), HTTP Tunneling, PAM Percona

 ![compatiblity](https://mariadb.com/kb/en/dbforge-documenter-for-mariadb-and-mysql/+image/compatiblity "compatiblity")

 ### 3. Broad picture of database structure

 Get the detailed MariaDB database information, such as types, details, and properties of the objects, inter-object dependencies, and DDL codes

 ![database-structure]

 ### 4. Rich customization of document management

 Enjoy various style templates allowing for alteration of documentation layout

 ![custom-features]

 ### 5. Several Document Formats supported:

 * HTML and PDF (searchable formats)

 * Markdown

 ![formats]

 ### 6. Extended properties support

 Edit an object description or add it if it is not specified

 Download a free 30-day trial of dbForge Documenter for MariaDB and MySQL [here](https://www.devart.com/dbforge/mysql/documenter/download.html).

 [Documentation](https://docs.devart.com/documenter-for-mysql/)

 


| Version | Introduced |
| --- | --- |
| dbForge Documenter 2.0 | Connectivity support for [MariaDB 10.5](../what-is-mariadb-105/index) is added |
| dbForge Documenter 1.2 | Support for [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Documenter 1.1 | Support for [MariaDB 10.3](../what-is-mariadb-103/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-documenter-for-mariadb-and-mysql/>

dbForge Schema Compare for MariaDB & MySQL
==========================================

    ![dbforge_schema_compare_for_mysql] is an efficient solution that allows for the comparison of the MariaDB database structure. With this tool, you can easily find the differences in MariaDB database schemas.

 Schema Compare Tool Key features:
---------------------------------

 ### 1.Mariadb & MySQL Schema Synchronization

 Update MariaDB schemas by generating accurate synchronization scripts

 Preview sync scripts for any schema objects

 Customize the synchronization output with various options

 Get warnings on possible errors while synchronization

 Sync asynchronous structure

 ![SynchronizationFeatures]

 ### 2. MariaDB Backup and Restore

 Enjoy the advantages of MariaDB backup and restore Wizards

 Have a full or partial backup

 Restore database and schedule backups with a command-line interface

 Support for databases over 2Gb

 ![DatabaseBackup]

 ### 3. Scripts Folder Comparison

 Compare the data both in two different databases and the database data with the data placed locally 

 Choose any connection and script folder stored locally with the new Data Comparison Wizard

 View the comparison process results in a data grid

 ![script-folder-comparison]

 ### 4. Routine Tasks Automation

 Sync and compare database schemas with command-line support

 Use the Windows Scheduler to automate the sync processes

 Run synchronization and schema comparison tasks with command-line execution files

 ![HowcanIautomatemyroutinetasks]

 ### 5. Broad Compatibility

 MariaDB server versions 5.5-10.6

 All MariaDB instances set up on Windows, Linux, FreeBSD, etc.

 Various cloud services: Amazon RDS, Amazon Aurora, Google Cloud, Oracle MySQL Cloud, Alibaba Cloud

 Security connections: Secure Socket Layer (SSL), Secure Shell (SSH), HTTP Tunneling, PAM Percona

 ![broad-compatibility-new](https://mariadb.com/kb/en/dbforge-schema-compare-for-mariadb-mysql/+image/broad-compatibility-new "broad-compatibility-new")

 ### 6. Supported Schema Objects

 Packages

 Sequences

 ![SupportedSchemaObjects]

 ### 7. Database Structure Comparison Configuration

 Filter the types of objects before the comparison

 Dismiss particular table options while comparing

 Use the Schema Comparison Wizard for switching between the Target and Source databases 

 ![DatabaseStructureComparisonSetup]

 ### 8. Comparison Results Analysis

 Sort and filter the compared objects

 Get a clear view of MariaDB and MySQL schema diffs in the grid.

 Manage groups of compared objects

 ![HowcanIanalyzecomparisonresults]

 ### 9. Comparison Results Export

 Generate comparison results reports in HTML, Excel XML, XML for Excel

 Include specifically selected objects in your comparison report

 ![HowcanIexportdatacomparisonresults]

 Download a free 30-day trial of dbForge MariaDB and MySQL Schema Compare [here](https://www.devart.com/dbforge/mysql/schemacompare/download.html).

 [Documentation](https://docs.devart.com/schema-compare-for-mysql/)

 


| Version | Introduced |
| --- | --- |
| dbForge Schema Compare 5.0 | [MariaDB 10.5](../what-is-mariadb-105/index) |
| dbForge Schema Compare 4.4 | [MariaDB 10.4](../what-is-mariadb-104/index) |
| dbForge Schema Compare 4.3 | [MariaDB 10.3](../what-is-mariadb-103/index) |
| dbForge Schema Compare 4.2 | [MariaDB 10.2](../what-is-mariadb-102/index), [MariaDB 10.1](../what-is-mariadb-101/index) |
| dbForge Schema Compare 3.1 | [MariaDB 10.0](../what-is-mariadb-100/index), [MariaDB 5.5](../what-is-mariadb-55/index) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbforge-schema-compare-for-mariadb-mysql/>

DbSchema
========

    Powerful, yet easy-to-use, DbSchema helps you design, document and manage databases without having to be a SQL pro. Easily design new tables, generate HTML5 documentation, explore and edit the database data, compare and synchronize the schema over multiple databases, edit and execute SQL, generate random data.

 DbSchema is compatible with all relational and few No-SQL databases. It works on all major operating systems, including Windows, Linux and Mac.

 You can download and evaluate DbSchema 15 days for free.

 [DBSchema Webpage](https://www.dbschema.com/index.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbschema/>

OmniDB
======

    OmniDB is a browser-based tool that simplifies MariaDB database management focusing on interactivity, designed to be powerful and lightweight.

 Characteristics:

 * Browser-based Tool: Accessible from any platform, using a browser as a medium.
* Responsive Interface: All available functions in a single page.
* Unified workspace: Different technologies managed in a single workspace.
* Simplified Editing: Easy to add and remove connections.
* Safety: Multi-user support with encrypted personal information.
* Interactive Tables: All functionalities use interactive tables, allowing copying and pasting in blocks.
* Smart SQL Editor: Contextual SQL code completion.
* Beautiful SQL Editor: You can choose between many available color themes.
* Tabbed SQL Editor: Easily add, rename or delete editor tabs.

 OmniDB Web Page: <https://omnidb.org/en/>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/graphical-and-enhanced-clients-omnidb/>

TOAD Edge
=========

    #### Characteristics

 Toad Edge™ is a database management application that allows you to perform database administration tasks with ease.

 Toad Edge™ allows you to:

 * Connect to your MySQL database, view, explore and edit database structure, database objects and properties.

 * Manage database objects, easily add, edit or drop objects in Object Explorer.

 * Manage data stored in your database, add, edit or remove records.

 * Write complex SQL code comfortably in Worksheet.

 * Compare and synchronize databases using powerful Schema Compare.

 * Obtain detailed information about your databases.

 In TOAD Edge 1.2, support for [MariaDB 10.1](../what-is-mariadb-101/index) has been added.

 #### Product Information

 <https://www.toadworld.com/products/toad-edge>

 <https://www.toadworld.com/p/downloads>

 #### Download: Freeware

 <https://www.toadworld.com/m/freeware/1657>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/toad-edge/>

TOAD for MySQL
==============

    #### Features

 * Version control integration.

 * Macro record and playback.

 * Database browser.

 * Code snippet editor.

 * Security manager.

 * SQL editor.

 * Fast, multi-tabbed schema browser.

 * DB extract, compare-and-search utility.

 * Import/export utility.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/toad-for-mysql-80/>

SQLPro Studio
=============

    [SQLPro Studio](https://sqlprostudio.com/) is a fully native database client for macOS [macOS](https://sqlprostudio.com/) and [iOS](https://apps.apple.com/app/sqlpro-studio-database-client/id1273366668). It supports databases such as MySQL, Postgres, Microsoft SQL Server, SQLite, Oracle and more.

 ![SQLPro UI](https://mariadb.com/kb/en/sqlpro-studio/+image/SQLProUI "SQLPro UI")

 Features include:

 * Syntax highlighting & Autocomplete (sometimes called intellisense).
* Customizable themes allowing the query editor to be completely customized.
* The ability to run multiple queries at one time (and a customizable run query shortcut).
* Improved query error detection (errors in queries will be underlined red).
* Full dark mode & light mode support, along with custom themes.

 Other features include:

 * Complete SSH Tunnel support.
* Inline data filtering.
* Exporting & Exporting options to CSV, JSON & XML.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sqlpro-studio/>

SB Data Generator
=================

    Generate and populate databases with large volumes of realistic test data.

 [**SB Data Generator**](https://soft-builder.com/sb-data-generator/) is a simple and powerful GUI tool for creating large volumes of realistic test data to populate selected tables or entire databases. The tool reverses your database and displays tables and columns, so you can assign to them multiple data generator templates. The tool includes multiple built-in generators that allow populating MariaDB database tables with realistic data of various types. 

 **Key Benefits:**

 * Understand your database structure by visualizing the ER Diagram (tables, columns, relationships, keys, sequences, indexes, and triggers)

 * Ability to generate a large volume of realistic test data

 * Preview what data will be generated before populating the database with test data

 * Multiple built-in generators available with the ability to create custom data generators

 * Generate test data for most popular DBMS including MariaDB and MySQL

 [**Learn more about SB Data Generator**](https://soft-builder.com/sb-data-generator/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sb-data-generator/>

Beekeeper Studio
================

    [Beekeeper Studio](https://www.beekeeperstudio.io) is an open-source database GUI available for Linux, MacOS, and Windows.

 ![SQL Gui Screenshot](https://mariadb.com/kb/en/beekeeper-studio/+image/main-dark "SQL Gui Screenshot")

 Beekeeper Studio works great with MariaDB, but also works with other databases like Postgres, Redshift, SQL Server, and more.

 Beekeeper Studio has all the nice features you'd expect of a quality SQL GUI:

 * Tabbed interface
* SSH tunneling
* SQL autocomplete
* Multi-connection

 Things that make Beekeeper Studio uniquely awesome:

 * [Totally open source and free](https://github.com/beekeeper-studio/beekeeper-studio). No feature walls for any GUI features.
* [Privacy respecting](https://www.beekeeperstudio.io/mission/). No usage tracking or anything at all like that.
* Modern and easy to use - Everyone deserves a first class app experience.

 **Links**

 * Homepage - <https://beekeeperstudio.io>
* GitHub - <https://github.com/beekeeper-studio/beekeeper-studio>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/beekeeper-studio/>

LibreOffice Base
================

     [LibreOffice Base](https://www.libreoffice.org/discover/base/) is an open source RDBMS (relational database management system) front-end tool to create and manage various databases. 

 Preparing the ODBC Connection
-----------------------------

 First, make sure to prepare MariaDB Connector/ODBC as explained in [MariaDB Connector/ODBC](../about-mariadb-connector-odbc/index). 

 That includes:

 * Download [the latest MariaDB Connector/ODBC](https://mariadb.com/downloads/#connectors)
* Copy the shared library *libmaodbc.so* to */usr/lib/[multi-arch]*
* Install the *unixodbc, unixodbc-dev, openssh-client, odbcinst* packages
* Create a template file for the [ODBC driver](../creating-a-data-source-with-mariadb-connectorodbc/index#configuring-mariadb-connectorodbc-as-a-unixodbc-driver-on-linux). A sample *“MariaDB\_odbc\_driver\_template.ini”* could be:

 


|  |
| --- |
| [MariaDB ODBC 3.1 Driver] |
| Description = MariaDB Connector/ODBC v.3.1 |
| Driver = /usr/lib/x86\_64-linux-gnu/libmaodbc.so |

 
* Install the ODBC driver from the template file by running:

 
```
$ sudo odbcinst -i -d -f MariaDB_odbc_driver_template.ini
odbcinst: Driver installed. Usage count increased to 1. 
    Target directory is /etc

```

Verify successful installation in */etc/odbcinst.ini* file (this path is obtained by the config info */-j*/ option, where drivers are installed in that predefined location).

 
```
$ odbcinst -j
unixODBC 2.3.6
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /home/anel/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

$ cat /etc/odbcinst.ini 
[MariaDB ODBC 3.1 Driver]
Description=MariaDB Connector/ODBC v.3.1
Driver=/usr/lib/x86_64-linux-gnu/libmaodbc.so
UsageCount=1

```

* Create a template file for the [Data Source Name (DSN)](../creating-a-data-source-with-mariadb-connectorodbc/index#configuring-a-dsn-with-unixodbc-on-linux). A sample *“MariaDB\_odbc\_data\_source\_template.ini”* could be:

 


|  |
| --- |
| [MariaDB-server] |
| Description=MariaDB server |
| Driver=MariaDB ODBC 3.1 Driver |
| SERVER=localhost |
| USER=anel |
| PASSWORD= |
| DATABASE=test |
| PORT=3306 |

 
* Install data source:

 
```
odbcinst -i -s -h -f MariaDB_odbc_data_source_template.ini

```

* Verify successful installation in the */.odbc.ini* file

 
```
$ cat ~/.odbc.ini 
[MariaDB-server]
Description=MariaDB server
Driver=MariaDB ODBC 3.1 Driver
SERVER=MariaDB
USER=anel
PASSWORD=
DATABASE=test
PORT=3306


```

* Verify successful installation also using the [isql](../creating-a-data-source-with-mariadb-connectorodbc/index#verifying-a-dsn-configuration-with-unixodbc-on-linux) utility, for example:

 
```

$ isql MariaDB-server
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> show tables;
+--------------------------------------------------------------------------+
| Tables_in_test                                                           |
+--------------------------------------------------------------------------+
| Authors                                                                  |
| tbl_names                                                                |
| webposts                                                                 |
| webusers                                                                 |
+--------------------------------------------------------------------------+
SQLRowCount returns 4
4 rows fetched


```

Start with LibreOffice Base
---------------------------

 Start Libreoffice Base from the terminal by running *lobase* (make sure to install the *libreoffice-base* package if needed). The default option is to create a new database, which is *HSQLDB*. In order to connect to a running MariaDB server, choose *“Connect to an existing database”* and choose *“ODBC”* driver as shown below:

 ![librebase_1]

 After that, choose DSN (the one that we created in the previous step) and click *“Next”*:

 ![librebase_2]

 Provide a user name (and password if needed) and again check the connection (with the *“Test Connection”* button) and click *“Next”*:

 ![librebase_3]

 After that, we have options to register the database. Registration in this sense means that the database is viewable by other LibreOffice modules (like *LibreOffice Calc* and *LibreOffice Writer*). So this step is optional. In this example, we will save as *“fosdem21\_mariadb.odb”*. See [Using a Registered Database](##using-a-registered-database).

 ![librebase_4]

 It opens the following window:

 ![librebase_5]

 It consists of three windows/panels:

 1. *“Database”* window with the options
	1. *"Tables"*,
	2. *"Queries"*,
	3. *"Forms"*,
	4. *"Reports"*.
2. "Tasks window (dependent on what is selected in the *“Database”* window). When *“Tables”* is selected, the options are:
	1. *"Create Table in Design View"*,
	2. *"Use Wizard to Create Table"* and
	3. *"Create View"*.
3. *"Tables"* window - shows list of tables that are created.

 As we can see, there are system tables in the *“mysql”* database as well as *“test”* database.

 Let’s say we create a table using the REST API from JSON data from <http://jsonplaceholder.typicode.com/posts>, and another table using the same mechanism from <http://jsonplaceholder.typicode.com/users>, and let’s call them *webposts* and *webusers*. In order to do so, we have to enable the **CONNECT** storage engine plugin and start with REST\_API. See more in the [CONNECT - Files Retrieved Using Rest Queries](../connect-files-retrieved-using-rest-queries/index) article.

 The queries we need to run in MariaDB are:

 
```
CREATE TABLE webusers ENGINE=CONNECT TABLE_TYPE=JSON
  HTTP='http://jsonplaceholder.typicode.com/users';

CREATE TABLE webposts ENGINE=CONNECT TABLE_TYPE=JSON
  HTTP='http://jsonplaceholder.typicode.com/posts';

```

The result in LibreOffice Base will be as shown below:

 ![librebase_6]

 Double clicking on the table opens a new window with the data displayed to inspect:

 ![librebase_7]

 To create the table from the *“Tasks”* window, use the option *“Create Table in Design View”*, where one can specify specific field names and types as shown:

 ![librebase_8]

 From the “Tasks” window one can create a table using the option *“Use Wizard to Create Table”* to create some sample tables.

 One can fill the data in the existing table, or create and define the new table from the *LibreOffice Calc* module with simple copy-paste (in the *"Tasks"* window).

 Using a Registered Database
---------------------------

 Other modules can use the registered database, for example, open *"LibreOffice Calc"* and go to *"Tools"*, *"Options"* and you will see the *"odb"* file we registered when starting *"LibreOffice Base"*.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/libreoffice-base/>

Valentina Studio
================

    [Valentina Studio](https://valentina-db.com/en/valentina-studio-overview) is a graphical front end for MariaDB with two versions: a free version which supports features offered only in paid for versions of competing products and a Pro version that adds advanced features.

 Free Valentina Studio offers the following features:

 * natively available on macOS, Windows & Linux
* a feature rich, visual SQL Editor with powerful search functionality
* SQLDIFF
* a highly productive Data Editor
* support for many data sources including all versions of MariaDB and MySQL 5.0.6 and later\*
* ODBC import
* Schema Editor with powerful visual diagramming features, Diagram Editor; import diagrams from MySQL Workbench
* Report Viewer with printing, export to PDF and HTML (local reports and from Valentina Server)
* Forms Client for working with visual forms and MariaDB (locally and from Valentina Server)

 * Free supports most popular data sources, MariaDB, MySQL, SQL Server, SQLite, PostgreSQL and more

 Use the [Valentina Studio FREE vs Valentina Studio PRO feature matrix](https://valentina-db.com/en/compare-free-vs-pro) to see which version is best for your needs or [download to immediately evaluate.](https://valentina-db.com/en/all-downloads/current)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/valentina-studio/>

DbVisualizer
============

    [DbVisualizer](https://dbvis.com/) is a cross-platform database tool for developers, DBAs, analysts and SQL programmers. Both Free and paid Pro version available. 

 Supported databases: MySQL, MariaDB, PostgreSQL, Netezza, Db2, SQLite, Oracle, Amazon Redshift, Vertica, Snowflake and [more](https://www.dbvis.com/features/database-drivers/). 

 For almost two decades DbVisualizer has been carefully developed by a small and dedicated team. Development decisions are based on user feedback. 

 Example of features: 

 * Simple navigation of database objects and their properties
* Visual rendering of primary/foreign keys
* Table data editing in spreadsheet with Export and import database schema
* Flexible user interface in light and dark themes
* Query optimization with an explain plan feature
* Visual query builder using drag and drop
* Flexible SQL scripts execution with parameter support
* SQL formatting and Command-line interface for headless execution
* [All features](https://www.dbvis.com/features/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbvisualizer/>

mariadb-test Overview
=====================

    The Basics
----------

 At its core, mariadb-test is very simple. The client program `mariadb-test` executes a *test file* and compares the produced output with the *result file*. If the files match, the test is passed; otherwise the test has failed. This approach can be used to test any SQL statement, as well as other executables (with the `exec` command).

 The complete process of testing is governed and monitored by the *mariadb-test-run.pl* driver script, or *mtr* for short (for convenience, `mtr` is created as a symbolic link to `mariadb-test-run.pl`). The mtr script is responsible for preparing the test environment, creating a list of all tests to run, running them, and producing the report at the end. It can run many tests in parallel, execute tests in an order which minimizes server restarts (as they are slow), run tests in a debugger or under valgrind or strace, and so on.

 Test files are located in *suites*. A *suite* is a directory which contains test files, result files, and optional configuration files. The mtr looks for suites in the `mariadb-test/suite` directory, and in the `mariadb-test` subdirectories of plugins and storage engine directories. For example, the following are all valid suite paths:

 
```
mariadb-test/suite/rpl

```
 
```
mariadb-test/suite/handler

```
 
```
storage/example/mariadb-test/demo

```
 
```
plugin/auth_pam/mariadb-test/pam

```
 In almost all cases, the suite directory name is the suite name. A notable historical exception is the *main* suite, which is located directly in the `mariadb-test` directory.

 Test files have a `.test` extension and can be placed directly in the suite directory (for example, `mariadb-test/suite/handler/interface.test`) or in the `t` subdirectory (e.g. `mariadb-test/suite/rpl/t/rpl_alter.test` or `mariadb-test/t/grant.test`). Similarly, result files have the `.result` extension and can be placed either in the suite directory or in the `r` subdirectory.

 A test file can include other files (with the `source` command). These included files can have any name and may be placed anywhere, but customarily they have a `.inc` extension and are located either in the suite directory or in the `inc` or `include` subdirectories (for example, `mariadb-test/suite/handler/init.inc` or `mariadb-test/include/start_slave.inc`).

 Other files which affect testing, while not being tests themselves, are:

 * `disabled.def`
* `suite.opt`
* other `*.opt` files
* `my.cnf`
* other `*.cnf` files
* `combinations`
* other `*.combinations` files
* `suite.pm`
* `*.sh` files
* `*.require` files
* `*.rdiff` files
* `valgrind.supp`

 See [Auxiliary files](../mtr-auxiliary-files/index) for details on these.

 Overlays
--------

 In addition to regular suite directories, mtr supports *overlays*. An *overlay* is a directory with the same name as an existing suite, but which is located in a storage engine or plugin directory. For example, `storage/myisam/mariadb-test/rpl` could be a *myisam* overlay of the *rpl* suite in `mariadb-test/suite/rpl`. And `plugin/daemon_example/mariadb-test/demo` could be a *daemon\_example* overlay of the *demo* suite in `storage/example/mariadb-test/demo`. As a special exception, an overlay of the main suite, should be called `main`, as in `storage/pbxt/mariadb-test/main`. 

 An overlay is like a second transparent layer in a graphics editor. It can obscure, extend, or modify the background image. Also, one may notice that an overlay is very close to a *UnionFS*, but implemented in perl inside mtr.

 An overlay can replace almost any file in the overlaid suite, or add new files. For example, if some overlay of the main suite contains a `include/have_innodb.inc` file, then all tests that include it will see and use the overlaid version. Or, an overlay can create a `t/create.opt` file (even though the main suite does not have such a file), and `create.test` will be executed with the specified additional options.

 But adding an overlay never affects how the original suite is executed. That is, mtr always executes the original suite as if no overlay was present. And then, additionally, it executes a combined "union" of the overlay and the original suite. When doing that, mtr takes care to avoid re-executing tests that are not changed in the overlay. For example, creating `t/create.opt` in the overlay of the main suite will only cause `create.test` to be executed in the overlay. But creating `suite.opt` affects all tests — and it will cause all tests to be re-executed with the new options.

 Combinations
------------

 In certain cases it makes sense to run a specific test or a group of tests several times with different server settings. This can be done using so-called *combinations*. Combinations are groups of settings that are used alternatively. A combinations file defines these alternatives using `my.cnf` syntax, for example

 
```
[row]
binlog-format=row

[stmt]
binlog-format=statement

[mix]
binlog-format=mixed

```

And all tests where this combinations file applies will be run three times: once for the combination called "row", and `--binlog-format=row` on the server command line, once for the "stmt" combination, and once for the "mix" combination.

 More than one combinations file may be applicable to a given test file. In this case, mtr will run the test for all possible combinations of the given combinations. A test that uses replication (three combinations as above) and innodb (two combinations - innodb and xtradb), will be run six times.

 Sample Output
-------------

 Typical mtr output looks like this

 
```
==============================================================================
TEST                                  WORKER RESULT   TIME (ms) or COMMENT
--------------------------------------------------------------------------
rpl.rpl_row_find_row_debug                [ skipped ]  Requires debug build
main-pbxt.connect                         [ skipped ]  No PBXT engine
main-pbxt.mysqlbinlog_row                 [ disabled ]  test expects a non-transactional engine
rpl.rpl_savepoint 'mix,xtradb'            w2 [ pass ]    238
rpl.rpl_stm_innodb 'innodb_plugin,row'    w1 [ skipped ]  Neither MIXED nor STATEMENT binlog format
binlog.binlog_sf 'stmt'                   w2 [ pass ]      7
unit.dbug                                 w2 [ pass ]      1
maria.small_blocksize                     w1 [ pass ]     23
sys_vars.autocommit_func3 'innodb_plugin' w1 [ pass ]      5
sys_vars.autocommit_func3 'xtradb'        w1 [ pass ]      6
main.ipv6                                 w1 [ pass ]    131
...

```

Every test is printed as "suitename.testname", and a suite name may include an overlay name (like in `main-pbxt`). After the test name, mtr prints combinations that were applied to this test, if any.

 A similar syntax can be used on the mtr command line to specify what tests to run:

 


|  |  |
| --- | --- |
| `$ ./mtr innodb` | search for *innodb* test in every suite from the default list, and run all that was found. |
| `$ ./mtr main.innodb` | run the *innodb* test from the *main* suite |
| `$ ./mtr main-pbxt.innodb` | run the *innodb* test from the *pbxt* overlay of the *main* suite |
| `$ ./mtr main-.innodb` | run the *innodb* test from the *main* suite and all its overlays. |
| `$ ./mtr main.innodb,xtradb` | run the *innodb* test from the *main* suite, only in the *xtradb* combination |

 
Plugin Support
--------------

 The mtr driver has special support for MariaDB plugins.

 First, on startup it copies or symlinks all dynamically-built plugins into `var/plugins`. This allows one to have many plugins loaded at the same time. For example, one can load Federated and InnoDB engines together. Also, mtr creates environment variables for every plugin with the corresponding plugin name. For example, if the InnoDB engine was built, `$HA_INNODB_SO` will be set to `ha_innodb.so` (or `ha_innodb.dll` on Windows). And the test can safely use the corresponding environment variable on all platforms to refer to a plugin file; it will always have the correct platform-dependent extension.

 Second, when combining server command-line options (which may come from many different sources) into one long list before starting `mariadbd`, mtr treats `--plugin-load` specially. Normal server semantics is to use the latest value of any particular option on the command line. If one starts the server with, for example, `--port=2000 --port=3000`, the server will use the last value for the port, that is 3000. To allow different `.opt` files to require different plugins, mtr goes through the assembled server command line, and joins all `--plugin-load` options into one. Additionally it removes all empty `--plugin-load` options. For example, suppose a test is affected by three `.opt` files which contain, respectively:

 
```
--plugin-load=$HA_INNODB_SO

```


```
--plugin-load=$AUTH_PAM_SO

```


```
--plugin-load=$HA_EXAMPLE_SO

```

...and, let's assume the Example engine was not built (`$HA_EXAMPLE_SO` is empty). Then the server will get:

 
```
--plugin-load=ha_innodb.so:auth_pam.so

```

instead of

 
```
--plugin-load=ha_innodb.so --plugin-load=auth_pam.so --plugin-load=

```

Third, to allow plugin sources to be simply copied into the `plugin/` or `storage/` directories, and still not affect existing tests (even if new plugins are statically linked into the server), mtr automatically disables all optional plugins on server startup. A plugin is optional if it can be disabled with the corresponding `--skip-XXX` server command-line option. Mandatory plugins, like MyISAM or MEMORY, do not have `--skip-XXX` options (e.g. there is no `--skip-myisam` option). This mtr behavior means that no plugin, statically or dynamically built, has any effect on the server unless it was explicitly enabled. A convenient way to enable a given plugin *XXX* for specific tests is to create a `have_XXX.opt` file which contains the necessary command-line options, and a `have_XXX.inc` file which checks whether a plugin was loaded. Then any test that needs this plugin can source the `have_XXX.inc` file and have the plugin loaded automatically.

 mtr communication procedure
---------------------------

 `mtr` is first creating the server socket (`master`).

 After that, `workers` are created using `fork()`.

 For each worker `run_worker()` function is called, which is executing the following:

 * creates a new socket to connect to `server_port` obtained from the `master`
* initiate communication with the `master` using `START` command
* `master` sends first test from list of tests supplied by the user and immediately sends command `TESTCASE` to the `worker`
* `worker` gets command `TESTCASE` and processes test case, by calling `run_testcase()` function which starts(/restarts if needed) the server and sends `TESTRESULT` (in case of restart `WARNINGS` command is issued to the `master` in case some warnings/error logs are found)
* `master` accepts `TESTRESULT` command and run `mtr_report_test()` function which check does the test fail and also generates the new command `TESTCASE` if some new test case exist
* If there is no other test case `master` sends `BYE` command which gets accepted by the `worker` which is properly closing the connection.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-test-overview/>

mariadb-test Auxiliary Files
============================

    The mariadb-test framework utilizes many other files that affect the testing process, in addition to test and result files.

 

---

 
`disabled.def` file
--------------------

 This file can be used to disable certain tests temporarily. For example, if one test fails and you are working on that, you may want to push the changeset that disables the test into the test suite so that other tests won't be disturbed by this failure.

 The file contains test names and a comment (that should explain why the test was disabled), separated by a colon. Lines that start with a hash sign (`#`) are ignored. A typical `disabled.def` may look like this (note that a hash sign in the middle of a line does not start a comment):

 
```
# List of disabled tests
# test name : comment
rpl_redirect : Fails due to bug#49978
events_time_zone  : need to fix the timing

```

During testing, mtr will print disabled tests like this:

 
```
...
rpl.rpl_redirect              [ disabled ]  Fails due to bug#49978
rpl.events_time_zone          [ disabled ]  need to fix the timing
...

```

This file should be located in the suite directory.

 

---

 
`suite.opt` file
-----------------

 This file lists server options that will be added to the `mariadbd` command line for every test of this suite. It can refer to environment variables with the `$NAME` syntax. Shell meta-characters should be quoted. For example

 
```
--plugin-load=$AUTH_PAM_SO
--max-connections=40 --net_read_timeout=5
"--replicate-rewrite-db=test->rewrite"

```

Note that options may be put either on one line or on separate lines. It is a good idea to start an option name with the `--loose-` prefix if the server may or may not recognize the option depending on the configuration. An unknown option in the `.opt` file will stop the server from starting, and the test will be aborted.

 This file should be located in the suite directory.

 

---

 other `*.opt` files
-------------------

 For every test or include file `somefile.test` or `somefile.inc`, mtr will look for `somefile.opt`, `somefile-master.opt` and `somefile-slave.opt`. These files have exactly the same syntax as the `suite.opt` above. Options from these files will also be added to the server command line (all servers started for this test, only master, or only slave respectively) for all affected tests, for example, for all tests that include `somefile.inc` directly or indirectly.

 A typical usage example is `include/have_blackhole.inc` and `include/have_blackhole.opt`. The latter contains the necessary command-line options to load the Blackhole storage engine, while the former verifies that the engine was really loaded. Any test that needs the Blackhole engine needs only to start from `source include/have_blackhole.inc;` and the engine will be automatically loaded for the test.

 

---

 
`my.cnf` file
--------------

 This is not the `my.cnf` file that tests from this suite will use, but rather a *template* of it. It will be converted later to an actual `my.cnf`. If a suite contains no `my.cnf` template, a default template, — `include/default_my.cnf` — will be used. Or `suite/rpl/my.cnf` if the test includes `master-slave.inc` (it's one of the few bits of the old MySQL `mysql-test-run` magic that we have not removed yet). Typically a suite template will not contain a complete server configuration, but rather start from

 
```
!include include/default_my.cnf

```

and then add the necessary modifications.

 The syntax of `my.cnf` template is the same of a normal `my.cnf` file, with a few extensions and assumptions. They are:

 * For any group with the name `[mysqld.**N**]`, where **N** is a number, mtr will start one `mysqld` process. Usually one needs to have only `[mysqld.1]` group, and `[mysqld.2]` group for replication tests.

 * There can be groups with non-standard names (`[foo]`, `[bar]`, whatever), not used by `mysqld`. The `suite.pm` files (see below) may use them somehow.

 * Values can refer to each other using the syntax `@groupname.optionname` — these references be expanded as needed. For example
```
[mysqld.2]
master-port= @mysqld.1.port

```

 * it sets the value of the `master-port` in the `[mysqld.2]` group to the value of `port` in the `[mysqld.1]` group.

 * An option name may start with a hash sign `#`. In the resulting `my.cnf` it will look like a comment, but it still can be referred to. For example:

 
```
[example]
#location = localhost:@mysqld.1.port
bar = server:@example.#location/data

```

* There is the `[ENV]` group. It sets values for the environment variables. For example
```
[ENV]
MASTER_MYPORT = @mysqld.1.port

```

 * Also, one can refer to values of environment variables via this group:
```
[mysqld.1]
user = @ENV.LOGNAME

```

 * There is the `[OPT]` group. It allows to invoke functions and generate values. Currently it contains only one option — `@OPT.port`. Every time this option is referred to in some other group in the `my.cnf` template, a new unique port number is generated. It will not match any other port number used by this test run. For example
```
[ENV]
SPHINXSEARCH_PORT = @OPT.port

```

 This file should be located in the suite directory.

 

---

 other `*.cnf` files
-------------------

 For every test file `somefile.test` (but for not included files) mtr will look for `somefile.cnf` file. If such a file exists, it will be used as a template instead of suite `my.cnf` or a default `include/default_my.cnf` templates.

 

---

 
`combinations` file
--------------------

 The `combinations` file defines few sets of alternative configurations, and every test in this suite will be run many times - once for every configuration. This can be used, for example, to run all replication tests in the *rpl* suite for all three binlog format modes (row, statement, and mixed). A corresponding `combinations` file would look as following:

 
```
[row]
binlog-format=row

[stmt]
binlog-format=statement

[mix]
binlog-format=mixed

```

It uses `my.cnf` file syntax, with groups (where group names define combination names) and options. But, despite the similarity, it is not a `my.cnf` template, and it cannot use the templating extentions. Instead, options from the `combinations` file are added to the server command line. In this regard, combination file is closer to `suite.opt` file. And just like it, combination file can use environment variables using the `$NAME` syntax.

 Not all tests will necessarily run for all combinations. A particular test may require to be run only in one specific combination. For example, in replication, if a test can only be run with the row binlog format, it will have `--binlog-format=row` in one of the `.opt` files. In this case, mtr will notice that server command line already has an option that matches one of the combinations, and will skip all other combinations for this particular test.

 The `combinations` file should be located in the suite directory.

 

---

 other `*.combinations` files
----------------------------

 Just like with the `*.opt` files, mtr will use `somefile.combinations` file for any `somefile.test` and `somefile.inc` that is used in testing. These files have exactly the same format as a suite `combinations` file.

 This can cause many combination files affecting one test file (if a test includes two `.inc` files, and both of them have corresponding `.combinations` files). In this case, mtr will run the test for all combinations of combinations from both files. In [MariaDB 5.5](../what-is-mariadb-55/index), for example, `rpl_init.inc` adds combinations for row/statement/mixed, and `have_innodb.inc` adds combinations for innodb/xtradb. Thus any replication test that uses innodb will be run six times.

 

---

 
`suite.pm` file
----------------

 This (optional) file is a perl module. It must declare a package that inherits from `My::Suite`.

 This file must normally end with `bless {}` — that is it must return an object of that class. It can also return a string — in this case all tests in the suite will be skipped, with this string being printed as a reason (for example "PBXT engine was not compiled").

 A suite class can define the following methods:

 * `config_files()`
* `is_default()`
* `list_cases()`
* `servers()`
* `skip_combinations()`
* `start_test()`

 A `config_files()` method returns a list of additional config files (besides `my.cnf`), that this suite needs to be created. For every file it specifies a function that will create it, when given a `My::Config` object. For example:

 
```
sub config_files {(
    'config.ini' => \&write_ini,
    'new.conf'   => \&do_new
)}

```

A `servers()` method returns a list of processes that needs to be started for this suite. A process is specified as a [regex, hash] pair. The regular expression must match a section in the `my.cnf` template (for example, `qr/mysqld\./` corresponds to all `mysqld` processes), the hash contains these options:

 


|  |  |
| --- | --- |
| `SORT` | a number. Processes are started in the order of increasing `SORT` values (and stopped in the reverse order). `mysqld` has number 300. |
| `START` | a function to start a process. It takes two arguments, `My::Config::Group` and `My::Test`. If `START` is undefined a process will not be started. |
| `WAIT` | a function to wait for the process to be started. It takes `My::Config::Group` as an argument. Internally mtr first invokes `START` for all processes, then `WAIT` for all started processes. |

 

```
sub servers {(
    qr/^foo$/ => { SORT => 200,  # start foo before mysqld
                   START => \&start_foo,
                   WAIT => \&wait_foo }
)}

```

See the *sphinx* suite for a working example.

 A `list_cases()` method returns a complete list of tests for this suite. By default it will be the list of files that have `.test` extension, but without the extension. This list will be filtered by mtr, subject to different mtr options (`--big-test`, `--start-from`, etc), the suite object does not have to do it.

 A `start_test()` method starts one test process, by default it will be `mariadb-test`. See the *unit* suite for a working example of `list_cases()` and `start_test()` methods.

 A `skip_combinations()` method returns a hash that maps file names (where combinations are defined) to a list of combinations that should be skipped. As a special case, it can disable a complete file by using a string instead of a hash. For example

 
```
sub skip_combinations {(
    'combinations' => [ 'mix', 'rpl' ],
    'inc/many.combinations' => [ 'a', 'bb', 'c' ],
    'windows.inc' => "Not on windows",
)}

```

The last line will cause all tests of this suite that include `windows.inc` to be skipped with the reason being "Not on windows".

 An `is_default()` method returns 1 if this particular suite should be run by default, when the `mariadb-test-run.pl` script is run without explicitly specified test suites or test cases.

 

---

 
`*.sh` files
-------------

 For every test file `sometest.test` mtr looks for `sometest-master.sh` and `sometest-slave.sh`. If either of these files is found, it will be run before the test itself.

 

---

 
`*.require` files
------------------

 These files are obsolete. Do not use them anymore. If you need to skip a test use the `skip` command instead.

 

---

 
`*.rdiff` files
----------------

 These files also define what the test result should be. But unlike `*.result` files, they contain a patch that should be applied to one result file to create a new result file. This is very useful when a result of some test in one combination differs slightly from the result of the same test, but in another combination. Or when a result of a test in an overlay differs from the test result in the overlayed suite.

 It is quite difficult to edit `.rdiff` files to update them after the test file has changed. But luckily, it is never needed. When a test fails, mtr creates a `.reject` file. Having it, one can create `.rdiff` file as easy as (for example)

 
```
diff -u main/foo.result main/foo.reject > main/foo,comb.rdiff
or
diff -u main/foo.result main/foo,comb.reject > main/foo,comb.rdiff

```

Some example:

 
```
diff -u main/innodb_ext_key.result main/innodb_ext_key,off.reject > main/innodb_ext_key,off.rdiff

diff -u suite/sys_vars/r/sysvars_server_notembedded.result suite/sys_vars/r/sysvars_server_notembedded,32bit.reject > suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff

```

Note: This will also add a timestamp in the .rdiff file, so if you are submitting a patch you could remove it manually. If the same .rdiff file is used for multiple combinations, then it would be good to omit in the header that would identify the combination, to allow git to pack the repository better. Example:

 
```
--- testname.result
+++ testname.reject

```

Because a combination can be part of the `.result` or `.rdiff` file name, mtr has to look in many different places for a test result. For example, consider a test `foo.test` in the combination pair `aa,bb`, that is run in the overlay *rty* of the suite *qwe*, in other words, for the test that mtr prints as

 
```
qwe-rty.foo 'aa,bb'                     [ pass ]

```

For this test a result can be in

 * either `.rdiff` or `.result` file
* either in the overlay "`rty/`" or in the overlayed suite "`qwe/`"
* with or without combinations in the file name ("`,a`", "`,b`", "`,a,b`", or nothing)

 which means any of the following 15 file names can be used:

 1. `rty/r/foo,aa,bb.result`
2. `rty/r/foo,aa,bb.rdiff`
3. `qwe/r/foo,aa,bb.result`
4. `qwe/r/foo,aa,bb.rdiff`
5. `rty/r/foo,aa.result`
6. `rty/r/foo,aa.rdiff`
7. `qwe/r/foo,aa.result`
8. `qwe/r/foo,aa.rdiff`
9. `rty/r/foo,bb.result`
10. `rty/r/foo,bb.rdiff`
11. `qwe/r/foo,bb.result`
12. `qwe/r/foo,bb.rdiff`
13. `rty/r/foo.result`
14. `rty/r/foo.rdiff`
15. `qwe/r/foo.result`

 They are listed, precisely, in the order of preference, and mtr will walk that list from top to bottom and the first file that is found will be used.

 If this found file is a `.rdiff`, mtr continues walking down the list until the first `.result` file is found. A `.rdiff` is applied to that `.result`.

 

---

 
`valgrind.supp` file
---------------------

 This file defines valgrind suppressions, and it is used when mtr is started with a `--valgrind` option.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-test-auxiliary-files/>

mariadb-test-run.pl Options
===========================

    Syntax
------

 
```
./mariadb-test-run.pl [ OPTIONS ] [ TESTCASE ]

```

Where the test case can be specified as: `testcase[.test]` Runs the test case named 'testcase' from all suits

 
```
path-to-testcase
[suite.]testcase[,combination]

```

### Examples

 `alias` `main.alias` 'main' is the name of the suite for the 't' directory. 



```
rpl.rpl_invoked_features,mix,xtradb_plugin
suite/rpl/t/rpl.rpl_invoked_features

```
 Options
-------

 ### Options to Control What Engine/Variation to Run

 


| Option | Description |
| --- | --- |
| `--embedded-server` | Use the embedded server, i.e. no mysqld daemons. |
| `--ps-protocol` | Use the binary protocol between client and server. |
| `--cursor-protocol` | Use the cursor protocol between client and server (implies `--ps-protocol`). |
| `--view-protocol` | Create a view to execute all non updating queries. |
| `--sp-protocol` | Create a stored procedure to execute all queries. |
| `--compress` | Use the compressed protocol between client and server if both support it. |
| `--ssl` | If mariadb-test-run.pl is started with the `--ssl` option, it sets up a [secure connection](../secure-connections-overview/index) for all test cases. In this case, if mysqld does not support TLS, mariadb-test-run.pl exits with an error message: `Couldn´t find support for SSL`. |
| `--skip-ssl` | Dont start server with support for TLS connections. |
| `--vs-config` | Visual Studio configuration used to create executables (default: MTR\_VS\_CONFIG environment variable). |
| `--parallel=num` | How many parallel tests should be run. Default is `1`, use `--parallel=auto` for auto-setting of *num*. |
| `--defaults-file=<config template>` | Use fixed config template for all tests. |
| `--defaults_extra_file=<config template>` | Extra config template to add to all generated configs. |
| `--combination=<opt>` | Extra options to pass to mysqld. The value should consist of one or more comma-separated mysqld options. This option is similar to `--mysqld` but should be given two or more times. mariadb-test-run.pl executes multiple test runs, using the options for each instance of `--combination` in successive runs. If `--combination` is given only once, it has no effect. For test runs specific to a given test suite, an alternative to the use of `--combination` is to create a combinations file in the suite directory. The file should contain a section of options for each test run. |
| `--dry-run` | Don't run any tests, print the list of tests that were selected for execution. |

 
### Options to Control Directories to Use

 


| Option | Description |
| --- | --- |
| `--tmpdir=DIR` | The directory where temporary files are stored (default: ./var/tmp). The environment variable MYSQL\_TMP\_DIR will be set to the path for this directory, whether it has the default value or has been set explicitly. This may be referred to in tests. |
| `--vardir=DIR` | The directory where files generated from the test run is stored (default: ./var). Specifying a ramdisk or tmpfs will speed up tests. The environment variable MYSQLTEST\_VARDIR will be set to the path for this directory, whether it has the default value or has been set explicitly. This may be referred to in tests. |
| `--mem` | Run testsuite in "memory" using tmpfs or ramdisk. This can decrease test times significantly, in particular if you would otherwise be running over a remote file system. Attempts to find a suitable location using a builtin list of standard locations for tmpfs (/dev/shm). The option can also be set using environment variable MTR\_MEM=[DIR]. If DIR is given, it is added to the beginning of the list of locations to search, so it takes precedence over any built-in locations. Once you have run tests with --mem within a mariadb-testdirectory, a soflink var will have been set up to the temporary directory, and this will be re-used the next time, until the soflink is deleted. Thus, you do not have to repeat the `--mem` option next time. |
| `--client-bindir=PATH` | Path to the directory where client binaries are located. |
| `--client-libdir=PATH` | Path to the directory where client libraries are located. |

 
### Options to Control What Test Suites or Cases to Run

 


| Option | Description |
| --- | --- |
| `--force` | Normally, mariadb-test-run.pl exits if a test case fails. `--force` causes execution to continue regardless of test case failure. |
| `--with-ndbcluster-only` | Run only tests that include "ndb" in the filename. |
| `--skip-ndb[cluster]` | Skip all tests that need cluster. Default. |
| `--do-test=PREFIX or REGEX` | Run test cases with names prefixed with PREFIX or which fulfil the REGEX. For example, `--do-test=testa` matches tests that begin with *testa*, `--do-test=main.testa` matches tests in the main test suite that begin with *testa*, and `--do-test=main.*testa` matches test names that contain *main* followed by *testa* with anything in between. In the latter case, the pattern match is not anchored to the beginning of the test name, so it also matches names such as *xmainytestz*. |
| `--skip-test=PREFIX or REGEX` | Skip test cases with names prefixed with PREFIX or which fulfil the REGEX. See `-do-test` for examples. |
| `--start-from=PREFIX` | Sorts the list of names of the test cases to be run, and then starts with the test prefixed with PREFIX, where the prefix may be *suite.testname* or just *testname*. |
| `--suite[s]=NAME1,..,NAMEN` | Comma separated list of suite names to run. The default, as of [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), is:"main-, archive-, binlog-, binlog\_encryption-, csv-, compat/oracle-, encryption-, federated-, funcs\_1-, funcs\_2-, gcol-, handler-, heap-, innodb-, innodb\_fts-, innodb\_gis-, innodb\_zip-, json-, maria-, mariabackup-, multi\_source-, optimizer\_unfixed\_bugs-, parts-, perfschema-, plugins-, roles-, rpl-, sys\_vars-, sql\_sequence-, unit-, vcol-, versioning-,period-". |
| `--skip-rpl` | Skip the replication test cases. |
| `--big-test` | Allow tests marked as "big" to run. Tests can be thus marked by including the line `--source include/big_test.inc`, and they will only be run if this option is given, or if the environment variable BIG\_TEST is set to 1. Repeat this option twice to run only "big" tests. This is typically used for tests that take a very long to run, or that use many resources, so that they are not suitable for running as part of a normal test suite run |
| `--staging-run` | Run a limited number of tests (no slow tests). Used for running staging trees with valgrind. |
| `--enable-disabled` | Ignore any *disabled.def* file, and also run tests marked as disabled. Success or failure of those tests will be reported the same way as other tests. |
| `--print-testcases` | Don't run the tests but print details about all the selected tests, in the order they would be run. |
| `--skip-test-list=FILE` | Skip the tests listed in FILE. Each line in the file is an entry and should be formatted as: <TESTNAME> : <COMMENT> |

 
### Options That Specify Ports

 


| Option | Description |
| --- | --- |
| `--[mtr-]port-base=num` | Base for port numbers. Ports from this number to number+9 are reserved. Should be divisible by 10; if not it will be rounded down. May be set with environment variable MTR\_PORT\_BASE. If this value is set and is not "auto", it overrides build-thread. |
| `--[mtr-]build-thread=num` | Specify unique number to calculate port number(s) from. Can be set in environment variable MTR\_BUILD\_THREAD. Set MTR\_BUILD\_THREAD="auto" to automatically acquire a build thread id that is unique to current host. The more logical `--port-base` is supported as an alternative. |

 
### Options For Test Case Authoring

 


| Option | Description |
| --- | --- |
| `--record TESTNAME`  | (Re)generate the result file for TESTNAME. |
| `--check-testcases` | Check testcases for side-effects. This is done by checking system state before and after each test case; if there is any difference, a warning to that effect will be written, but the test case will not be marked as failed because of it. This check is enabled by default. Use `--nocheck-testcases` to disable. |
| `mark-progress` | Log line number and elapsed time to <testname>.progress |

 
### Options That Pass On Options

 


| Option | Description |
| --- | --- |
| `--mysqld=ARGS` | Specify additional arguments to "mysqld" |
| `--mysqltest=ARGS` | Specify additional arguments to "mariadb-test". Use additional `--mysqld-env` options to set more than one variable. |

 
### Options to Run Test On Running Server

 


| Option | Description |
| --- | --- |
| `extern option=value` | Use an already running server. The option/value pair is what is needed by the mariadb client to connect to the server. Each `--extern` option can only take one option/value pair as an argument, so you need to repeat `--extern` for each pair needed. Example:  `./mariadb-test-run.pl --extern socket=var/tmp/mysqld.1.sock alias`. Note: If a test case has an .opt file that requires the server to be restarted with specific options, the file will not be used. The test case likely will fail as a result. |

 
### Options For Debugging the Product

 In `mariadb-test-run.pl` there is a concept of a "debugger". A "debugger" is a tool that `mariadb-test-run.pl` will execute instead of `mariadbd`. This tool will then start `mariadbd` and can control its execution as it wants. The following "debuggers" are supported:

 


| name | Description |
| --- | --- |
| `gdb` | [GNU debugger](https://www.gnu.org/software/gdb/) |
| `ddd` | [GUI frontend for gdb](https://www.gnu.org/software/ddd/) |
| `dbx` | <https://en.wikipedia.org/wiki/Dbx_(debugger)> |
| `devenv` | [Visual Studio debugger](https://docs.microsoft.com/en-us/visualstudio/debugger/?view=vs-2019) |
| `windbg` | <https://en.wikipedia.org/wiki/WinDbg> |
| `lldb` | [Debugger from LLVM project](https://lldb.llvm.org/) |
| `valgrind` | [Detects memory management problems and more](https://www.valgrind.org/) |
| `strace` | [syscall tracer](https://strace.io/) |
| `rr` | ["record and replay" — record the program execution and then replay it forward, backward, or in any other direction](https://rr-project.org/) |

 
Every "debugger" from the list above supports the following set of options (replace XXX below with a debugger name)

 


| Option | Description |
| --- | --- |
| `--XXX` | Start `mariadbd` process under a debugger |
| `--client-XXX` | Start `mariadb-test` process under a debugger |
| `--boot-XXX` | Before running tests `mariadb-test-run` executes `mariadbd` to bootstrap, prepare the datadir. This options causes this bootstrapping `mariadbd` process to be run under a debugger. |
| `--manual-XXX` | Don't start anything, instead print the command that the user needs to run to start `mariadbd` under a debugger. Then wait. |

 
Every option from the above accepts an optional argument. It can be used to specify additional command line options to pass to the tool. Or additional commands that the tool will run on startup. Or both. Commands are separated from each other and from options with a semicolon. For example:

 
```
./mtr 1st --strace
./mtr 1st --client-rr=--chaos
./mtr 1st --manual-gdb='b mysql_parse;r'
./mtr 1st --boot-gdb='--quiet --tui;b mysql_parse;r'

```

### Misc Debugging Related Options

 


| Option | Description |
| --- | --- |
| `--debug` | Dump trace output for all servers and client programs. |
| `--debug-common` | Same as `--debug`, but sets the 'd' debug flags to "query,info,error,enter,exit" |
| `--debug-server` | Use debug version of server, but without turning on tracing. |
| `--max-save-core` | Limit the number of core files saved (to avoid filling up disks for heavily crashing server). Defaults to 5, set to 0 for no limit. Set its default with MTR\_MAX\_SAVE\_CORE. |
| `--max-save-datadir` | Limit the number of datadir saved (to avoid filling up disks for heavily crashing server). Defaults to 20, set to 0 for no limit. Set its default with MTR\_MAX\_SAVE\_DATDIR. |
| `--max-test-fail` | Limit the number of test failurs before aborting the current test run. Defaults to 10, set to 0 for no limit. Set its default with MTR\_MAX\_TEST\_FAIL. |

 
### Misc Options

 


| Option | Description |
| --- | --- |
| `--user=USER` | User for connecting to mysqld (default: root) |
| `--comment=STR` | Write STR to the output within lines filled with #, as a form of banner. |
| `--timer` | Show test case execution time. Use `no-timer` to disable. |
| `--verbose` | More verbose output(use multiple times for even more) |
| `--verbose-restart` | Write when and why servers are restarted between test cases. |
| `--start` | Only initialize and start the servers, using the startup settings for the first specified test case Example: `./mariadb-test-run.pl --start alias & start-dirty` Only start the servers (without initialization) for the first specified test case |
| `--start-and-exit` | Same as `--start`, but *mariadb-test-run* terminates and leaves just the server running. |
| `--start-dirty` | This is similar to `--start`, but will skip the database initialization phase and assume that database files are already available. Usually this means you must have run another test first. |
| `--user-args` | In combination with start\* and no test name, drops arguments to mysqld except those specified with `--mysqld` (if any). |
| `--wait-all` | If `--start` or `--start-dirty` option is used, wait for all servers to exit before finishing the process. Otherwise, it will terminate if one (of several) servers is restarted. |
| `--fast` | Do not perform controlled shutdown when servers need to be restarted or at the end of the test run. This is equivalent to using `--shutdown-timeout=0`. |
| `--force-restart` | Always restart servers between tests. |
| `--parallel=N` | Run tests in N parallel threads (default 1) Use parallel=auto for auto-setting of N. |
| `--repeat=N` | Run each test N number of times. |
| `--retry=N` | If a test fails, it is retried up to a maximum of N runs (default 1). Retries are also limited by the maximum number of failures before stopping, set with the `--retry-failure` option. This option has no effect unless `--force` is also used; without it, test execution will terminate after the first failure. The `--retry` and `--retry-failure` options do not affect how many times a test repeated with `--repeat` may fail in total, as each repetition is considered a new test case, which may in turn be retried if it fails. |
| `--retry-failure=N` | When using the --retry option to retry failed tests, stop when N failures have occured (default 2). Setting it to 0 or 1 effectively turns off retries. |
| `--reorder` | Reorder tests to get fewer server restarts. This is the default behavior. There is no guarantee that a particular set of tests will always end up in the same order. Use `-no-reorder` to disable. |
| `--help` | Display help text. |
| `--testcase-timeout=MINUTES` | Max test case run time in minutes (default 15). |
| `--suite-timeout=MINUTES` | Max test suite run time in minutes (default 360). |
| `--shutdown-timeout=SECONDS` | Max number of seconds to wait for server shutdown before killing servers (default 10). |
| `--warnings` | Scan the log files for warnings and report any suspicious ones; if any are found, the test will be marked as failed. Use `--nowarnings` to turn off. |
| `--stop-file=file` | If this file is detected, [mariadb-test](../mariadb-test/index) will not start new tests until the file is removed (also MTR\_STOP\_FILE environment variable). |
| `--stop-keep-alive=sec` | Works with `--stop-file`, print messages every *sec* seconds when mariadb-test is waiting to remove the file (for buildbot) (also MTR\_STOP\_KEEP\_ALIVE environment variable). |
| `--sleep=SECONDS` | Passed to [mariadb-test](../mariadb-test/index); will be used as fixed sleep time. |
| `--debug-sync-timeout=NUM` | Set default timeout for WAIT\_FOR debug sync actions. Disable facility with NUM=0. |
| `--gcov` | Collect coverage information after the test. The result is a [dgcov](../dgcov/index) file per source and header file and a `last_changes.dgcov` file in the vardir with the coverage for the uncommitted changes if any (or the last commit). |
| `--gprof` | Collect profiling information using the gprof profiling tool. |
| `--experimental=<file>` | Specify a file that contains a list of test cases that should be displayed with the [ exp-fail ] code rather than [ fail ] if they fail. For an example of a file that might be specified via this option, see *mariadb-test/collections/default.experimental*. |
| `--report-features` | First run a "test" that reports MariaDB features, displaying the output of [SHOW ENGINES](../show-engines/index) and [SHOW VARIABLES](../show-variables/index). This can be used to verify that binaries are built with all required features. |
| `--timestamp` | Print timestamp before each test report line, showing when the test ended. |
| `--timediff` | Used with `--timestamp`, also print time passed since the previous test started. |
| `--max-connections=N` | Maximum number of simultaneous server connections that may be used per test. Default is 128. Minimum is 8, maximum is 5120. Corresponds to the same option for [mariadb-test](../mariadb-test-and-mariadb-test-embedded/index). |
| `--default-myisam` | Set default storage engine to [MyISAM](../myisam/index) for non-innodb tests. This is needed after switching default storage engine to [InnoDB](../innodb/index). |
| `--report-times` | Report how much time has been spent on different phases of test execution. |
| `--stress=ARGS` | Run stress test, providing options to [mysql-stress-test.pl](../mysql-stress-test/index). Options are separated by comma. |
| `xml-report=<file>` | Output jUnit xml file of the results. From [MariaDB 10.1.45](https://mariadb.com/kb/en/mariadb-10145-release-notes/), [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/), [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/) |
| `tail-lines=N` | Number of lines of the result to include in a failure report. From [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/). |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-test-run-pl-options/>

Pausing mariadb-test-run.pl
===========================

     Sometimes you need to work when your computer is busy running [mariadb-test-run.pl](mariadb-test-runpl-options). The mariadb-test-run.pl script allows you to stop it temporarily so you can use your computer and then restart the tests when you're ready.

 There are two ways to enable this:

 1. **Command-line:** The `--stop-file` and `--stop-keep-alive` options.
2. **Environment Variables:** If you are calling mariadb-test-run.pl indirectly (i.e from a script or program such as buildbot) you can set `MTR_STOP_FILE` and `MTR_STOP_KEEP_ALIVE`.

 ### Keep Alive

 If you plan on using this feature with other programs, such as buildbot, you should set the <code>MTR\_STOP\_KEEP\_ALIVE</code> environment variable or the <code>--stop-keep-alive</code> command-line option with a value in seconds. This will make the script print messages to whatever program is calling mariadb-test-run.pl at the interval you set to prevent timeouts. 

 If you are calling mariadb-test-run.pl directly, you do not need to specify a timeout.

 ### The mariadb-test-run Stop File

 The stop file is a temporary file that you create on your system when you want to pause the execution of mariadb-test-run. When enabled via the command-line or environment variable options, mariadb-test-run will periodically check for the existence of the file and if it exists it will stop until the file is no longer present.

 ### Examples

 Command-line:

 
```
mariadb-test-run.pl --stop-file="/path/to/stop/file" --stop-keep-alive=120

```

Environment Variables:

 
```
export MTR_STOP_FILE="/path/to/stop/file"
export MTR_STOP_KEEP_ALIVE=120
mariadb-test-run.pl

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/pausing-mariadb-test-run-pl/>

mariadb-test and mariadb-test-embedded
======================================

     The `mariadb-test` program runs a test case against a MariaDB or MySQL server and optionally compares the output with a result file. This program reads input written in a special test language. Typically, you invoke *mariadb-test* via `[mariadb-test-run.pl](mariadb-test-runpl)` rather than invoking it directly.

 `mariadb-test_embedded` is similar but is built with support for the `libmariadbd` embedded server.

 Features of mariadb-test:

 * Can send SQL statements to the server for execution
* Can execute external shell commands
* Can test whether the result from an SQL statement or shell command is as expected
* Can connect to one or more standalone mariadbd servers and switch between connections
* Can connect to an embedded server (libmariadbd), if MariaDB is compiled with support for libmariadbd. (In this case, the executable is named mariadb-test\_embedded rather than mariadb-test.)

 By default, mariadb-test reads the test case on the standard input. To run mariadb-test this way, you normally invoke it like this:

 
```
shell> mariadb-test **[options] [db_name]** < //test_file//

```

You can also name the test case file with a `--test-file=*file\_name*` option.

 The exit value from mariadb-test is 0 for success, 1 for failure, and 62 if it skips the test case (for example, if after checking some preconditions it decides not to run the test).

 Options
-------

 mariadb-test supports the following options:

 


| Option | Description |
| --- | --- |
| `--help`, `-?` | Display a help message and exit. |
| `--basedir=dir`, `-b dir` | The base directory for tests. |
| `--character-sets-dir=path` | The directory where [character sets](../data-types-character-sets-and-collations/index) are installed. |
| `--compress`, `-C` | Compress all information sent between the client and the server if both support compression. |
| `--connect-timeout=N` | This can be used to set the MYSQL\_OPT\_CONNECT\_TIMEOUT parameter of mysql\_options to change the number of seconds before an unsuccessful connection attempt times out. |
|  `--continue-on-error` | Continue test even if we got an error. This is mostly useful when testing a storage engine to see what from a test file it can execute, or to find all syntax errors in a newly created big test file |
| `--cursor-protocol` | Use cursors for prepared statements. |
| `--database=db_name`, `-D db_name` | The default database to use. |
| `--debug[=debug_options]`, `-#[debug_options]` | Write a debugging log if MariaDB is built with debugging support. The default debug\_options value is `d:t:S:i:O,/tmp/mysqltest.trace` on Unix and `d:t:i:O,\mysqld.trace` on Windows. |
| `--debug-check` | Print some debugging information when the program exits. |
| `--debug-info` | Print debugging information and memory and CPU usage statistics when the program exits. |
| `--host=host_name`, `-h host_name` | Connect to the server on the given host. |
| `--logdir=dir_name` | The directory to use for log files. |
| `--mark-progress` | Write the line number and elapsed time to *test\_file.progress*. |
| `--max-connect-retries=num` | The maximum number of connection attempts when connecting to server. |
| `--max-connections=num` | The maximum number of simultaneous server connections per client (that is, per test). If not set, the maximum is 128. Minimum allowed limit is 8, maximum is 5120. |
| `--no-defaults` | Do not read default options from any option files. If used, this must be the first option. |
| `--non-blocking-api` | Use the non-blocking client API for communication. |
| `--overlay-dir=name` | Overlay directory. |
| `--password[=password]`, `-p[password]` | The password to use when connecting to the server. If you use the short option form (-p), you cannot have a space between the option and the password. If you omit the password value following the `--password` or `-p` option on the command line, you are prompted for one. |
| `plugin-dir` | Directory for client-side plugins. |
| `--port=port_num`, `-P port_num` | The TCP/IP port number to use for the connection, or 0 for default to, in order of preference, my.cnf, $MYSQL\_TCP\_PORT, /etc/services, built-in default (3306). |
| `--prologue=name` | Include the contents of the given file before processing the contents of the test file. The included file should have the same format as other *mariadb-test* test files. This option has the same effect as putting a --source file\_name command as the first line of the test file. |
| `--protocol=name` | The protocol to use for connection (tcp, socket, pipe, memory). |
| `--ps-protocol` | Use the prepared-statement protocol for communication. |
| `--quiet` | Suppress all normal output. This is a synonym for `--silent`. |
| `--record`, `-r` | Record the output that results from running the test file into the file named by the `--result-file` option, if that option is given. It is an error to use this option without also using `--result-file`. |
| `--result-file=file_name`, `-R file_name` | This option specifies the file for test case expected results. `--result-file`, together with `--record`, determines how mariadb-test treats the test actual and expected results for a test case:If the test produces no results, mariadb-test exits with an error message to that effect, unless `--result-file` is given and the named file is an empty file.Otherwise, if `--result-file` is not given, mariadb-test sends test results to the standard output. With `--result-file` but not `--record`, mariadb-test reads the expected results from the given file and compares them with the actual results. If the results do not match, mariadb-test writes a reject file in the same directory as the result file, outputs a diff of the two files, and exits with an error. With both `--result-file` and `--record`, mariadb-test updates the given file by writing the actual test results to it. |
| `--result-format-version=#`  | Version of the result file format to use. |
| `--server-arg=value`, `-A value` | Pass the argument as an argument to the embedded server. For example, `--server-arg=--tmpdir=/tmp` or `--server-arg=--core`. Up to 64 arguments can be given. |
| `--server-file=file_name`, `-F file_name` | Read arguments for the embedded server from the given file. The file should contain one argument per line. |
| `--shared-memory-base-name` | Shared-memory name to use for Windows connections using shared memory to a local server (started with the `--shared-memory` option). Case-sensitive. |
| `--silent`, `-s` | Suppress all normal output. |
| `--sleep=num`, `-T num` | Cause all sleep commands in the test case file to sleep num seconds. This option does not affect real\_sleep commands. An option value of 0 can be used, which effectively disables sleep commands in the test case. |
| `--socket=path`, `-S path` | The socket file to use when connecting to localhost (which is the default host). |
| `--sp-protocol` | Execute DML statements within a stored procedure. For every DML statement, mariadb-test creates and invokes a stored procedure that executes the statement rather than executing the statement directly. |
| `--ssl` | Enable [TLS for secure connection](../secure-connections-overview/index) (automatically enabled with other flags). Disable with `--skip-ssl`. |
| `--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`). |
| `--ssl-verify-server-cert` | Verify server's "Common Name" in its cert against hostname used when connecting. This option is disabled by default. |
| `--suite-dir=name` | Suite directory. |
| `--tail-lines=nn` | Specify how many lines of the result to include in the output if the test fails because an SQL statement fails. The default is 0, meaning no lines of result printed. |
| `--test-file=file_name`, `-x file_name` | Read test input from this file. The default is to read from the standard input. |
| `--timer-file=file_name`, `-m file_name` | If given, the number of microseconds spent running the test will be written to this file. This is used by [mariadb-test-run.pl](mariadb-test-runpl-options) for its reporting. |
| `--tmpdir=dir_name`, `-t dir_name` | The temporary directory where socket files are created. |
| `--user=user_name`, `-u user_name` | The user name to use when connecting to the server. |
| `--verbose`, `-v` | Verbose mode. Print out more information about what the program does. |
| `--version`, `-V` | Display version information and exit. |
| `--view-protocol` | Every SELECT statement is wrapped inside a view. |
| `--wait-longer-for-timeouts` | Wait longer for timeouts. Useful when running under valgrind. |

 
See Also
--------

 * [New Features for mysqltest in MariaDB](../new-features-for-mysqltest-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-test-and-mariadb-test-embedded/>

New Features for mysqltest in MariaDB
=====================================

    
Note that not all MariaDB-enhancements are listed on this page. See [mariadb-test and mariadb-test-embedded](../mariadb-test-and-mariadb-test-embedded/index) for a full set of options.

 
Startup Option --connect-timeout
--------------------------------

 
```
--connect-timeout=N
```

This can be used to set the MYSQL\_OPT\_CONNECT\_TIMEOUT parameter of mysql\_options, to change the number of seconds before an unsuccessful connection attempt times out.

 Test Commands for Handling Warnings During Prepare Statements
-------------------------------------------------------------

 * `enable_prepare_warnings;`
* `disable_prepare_warnings;`

 Normally, when running with the prepared statement protocol with warnings enabled and executing a statement that returns a result set (like SELECT), warnings that occur during the execute phase are shown, but warnings that occur during the prepare phase are ''not'' shown. The reason for this is that some warnings are returned both during prepare and execute; if both copies of warnings were shown, then test cases would show different number of warnings between prepared statement execution and normal execution (where there is no prepare phase).

 The `enable_prepare_warnings` command changes this so that warnings from both the prepare and execute phase are shown, regardless of whether the statement produces a result set in the execute phase. The `disable_prepare_warnings` command reverts to the default behaviour.

 These commands only have effect when running with the prepared statement protocol (--ps-protocol) *and* with warnings enabled (enable\_warnings). Furthermore, they only have effects for statements that return a result set (as for statements without result sets, warnings from are always shown when warnings are enabled).

 The `replace_regex` command supports paired delimiters (like in perl, etc). If the first non-space character in the `replace_regex` argument is one of `(`, `[`, `{`, `<`, then the pattern should end with `)`, `]`, `}`, `>` accordingly. The replacement string can use its own pair of delimiters, not necessarily the same as the pattern. If the first non-space character in the `replace_regex` argument is not one of the above, then it should also separate the pattern and the replacement string and it should end the replacement string. Backslash can be used to escape the current terminating character as usual. The examples below demonstrate valid usage of `replace_regex`:

 
```
--replace_regex (/some/path)</another/path>
--replace_regex !/foo/bar!foobar!
--replace_regex {pat\}tern}/replace\/ment/i
```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/new-features-for-mysqltest-in-mariadb/>

Debugging MariaDB With a Debugger
=================================

     If you have MariaDB [compiled for debugging](../compiling-mariadb-for-debugging/index) you can both use it in a debugger, like ddd or gdb, and get comprehensive trace files of the execution of MariaDB. The trace files allow you to both see the flow of the code and to see the differences in execution by by comparing two trace files.

 Core dumps are also much easier to investigate if they come from a debug binary.

 Note that a binary compiled for debugging and tracing is about 10-20% slower than a normal binary. If you just compile a binary for debugging (option `-g` with gcc) the speed difference compared to a normal binary is negligible.

 ### Checking That MariaDB is Compiled For Debugging

 Execute:

 
```
mariadbd --debug --help

```

If you are using MariaDB before 10.5, then you should use `mysqld` instead of `mariadbd`!

 If you get an error `unknown option '--debug`, then MariaDB is not compiled for debugging and tracing. 

 ### Building MariaDB for Debugging Starting from 5.5

 On Unix you need to pass `-DCMAKE_BUILD_TYPE=Debug` to cmake to compile with debug information.

 ### Building [MariaDB 5.3](../what-is-mariadb-53/index) and Older

 Here is how you compile with debug on older versions:

 Use the scripts in the BUILD directory that will compile MariaDB with most common debug options and plugins, for example:

 
```
./BUILD/compile-pentium64-debug-max

```

For the most common configurations there exists a fine-tuned script in the BUILD directory.

 If you want to use [valgrind](http://valgrind.org/), a very good memory instrumentation tool and memory overrun checker, you should use

 
```
./BUILD/compile-pentium64-valgrind-max

```

Some recommended debugging scripts for Intel/AMD are:

 
```
BUILD/compile-pentium64-debug-max
BUILD/compile-pentium64-valgrind-max

```

This is an example of how to compile MariaDB for debugging in your home directory with [MariaDB 5.2.9](https://mariadb.com/kb/en/mariadb-529-release-notes/) as an example:

 
```
cd ~
mkdir mariadb
cd mariadb
tar xvf mariadb-5.2.9.tar.gz
ln -s mariadb-5.2.9 current
cd current
./BUILD/compile-pentium64-debug-max

```

The last command will produce a debug version of `sql/mysqld`.

 ### Debugging MariaDB From the Source Directory

 #### Creating the MariaDB Database Directory

 The following example creates the MariaDB databases in `/data`.

 
```
./scripts/mariadb-install-db --srcdir=. --datadir=/data

```

#### Running MariaDB in a Debugger

 The following example is using `ddd`, an excellent graphical debugger in Linux. If you don't have `ddd` installed, you can use `gdb` instead.

 
```
cd sql
ddd ./mariadbd &

```

In `ddd` or `gdb`

 
```
run --datadir=/data --language=./share/english --gdb

```

You can [set the options in your /.my.cnf file](../running-mariadb-from-the-build-directory/index) so as not to have to repeat them on the `run` line.

 If you run `mysqld` with `--debug`, you will get a [trace file](../creating-a-trace-file/index) in /tmp/mysqld.trace that shows what is happening.

 Note that you can have different options in the configuration file for each MariaDB version (like having a specific language directory).

 ### Debugging MariaDB Server with mariadb-test-run

 If you get a crash while running `mariadb-test-run` you can debug this in a debugger by using one of the following options:

 
```
mariadb-test-run --gdb failing-test-name

```

or if you prefer the `ddd` debugger:

 
```
mariadb-test-run --ddd failing-test-name

```

#### Sample .my.cnf file to Make Debugging Easier

 
```
[client-server]
socket=/tmp/mysql-dbug.sock
port=3307

[mariadb]
datadir=/my/data
loose-innodb_file_per_table
server_id= 1
log-basename=master
loose-debug-mutex-deadlock-detector
max-connections=20
lc-messages=en_us

[mariadb-10.0]
lc-messages-dir=/my/maria-10.0/sql/share

[mariadb-10.1]
lc-messages-dir=/my/maria-10.1/sql/share

[mariadb-10.2]
lc-messages-dir=/my/maria-10.2/sql/share

[mariadb-10.3]
lc-messages-dir=/my/maria-10.3/sql/share

```

The above `.my.cnf` file:

 * Uses an explicit socket for both client and server.
* Assumes the server source is in /my/maria-xxx. You should change this to point to where your sources are located.
* Has a unique patch for each MariaDB version so that one doesn't have to specify [--lc-messages-dir](../server-system-variables/index#lc_messages_dir) or [--language](../server-system-variables/index#language) even if one switches between debugging different MariaDB versions.

 ### See Also

 * [Creating a trace file](../creating-a-trace-file/index)
* [Configuring MariaDB with my.cnf](../configuring-mariadb-with-mycnf/index)
* [Running mariadbd from the build director](../running-mariadb-from-the-build-directory/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/debugging-mariadb-with-a-debugger/>

Code Coverage with dgcov
========================

     The dgcov tool helps you check the coverage for new code. The dgcov.pl script is part of the [mariadb-test](../mariadb-test/index) framework (and any packages that include mariadb-test).

 Overview
--------

 The dgcov program runs gcov for code coverage analysis, aggregates the coverage data, and (optionally) reports coverage only for those lines that are changed by the commit(s). Commits are specified in the `git diff` format.

 If no commits are specified, the default is to work on all uncommitted changes, if any, otherwise on the last commit (in other words, on `git diff HEAD` or `git diff HEAD^`).

 It's recommended that a developer [runs dgcov on their new code](../code-coverage/index) before pushing it into a MariaDB repository.

 Usage
-----

 
```
./dgcov.pl --help
./dgcov.pl [options] [<commit> [<commit>]]

```

Options and Variables
---------------------

 


| Short Option | Long Option | Description |
| --- | --- | --- |
| `-h` | `--help` | Print help and exit |
| `-v` | `--verbose` | Show commands run. |
| `-p` | `--purge` | Delete all test coverage information, to prepare for a new coverage test. |
| `-o` | `--only-gcov` | Stop after running gcov, don't run git |
| `-s` | `--skip-gcov` | Do not run gcov, assume .gcov files are already in place |
| `-g` | `--generate` | Create .dgcov files for all source files |

 
How to Prepare the Code for dgcov
---------------------------------

 Prior to running this tool, MariaDB should be built with

 
```
  cmake -DENABLE_GCOV=ON

```

and the testsuite should be run. dgcov will report the coverage for all lines modified in the specified commits.

 Output
------

 Output .dgcov files have a conventional gcov format: lines not covered are prefixed with `#####`, lines without generated code are prefixed with `-`, and other lines are prefixed with the number of times they were executed. See `info gcov` for more information.

 The patch-like coverage for commits uses gcov format (as above) for lines, changed in these commits, and no prefix at all for lines that were not changed.

 Examples
--------

 Checking the coverage for all unpushed commits:

 
```
dgcov.pl @{u} HEAD

```

Checking the coverate for all uncommitted changes:

 
```
dgcov.pl HEAD

```

Checking the coverage for a specific commit 1234567:

 
```
dgcov.pl 1234567^ 1234567

```

<mariadb-test-run> can invoke dgcov automatically:

 
```
./mtr --gcov

```

in the latter case the coverate for the uncommitted changes (or the last commit) will be not printed to the stdout, but will be put into `var/last_changes.dgcov` file.

 Caveats
-------

 Note that to be able to run gcov with the [mariadb-test](../mariadb-test/index) framework you need to have gcc version 4.8 or newer.

 References
----------

 * dgcov was created by Kristian Nielsen and was first [announced here](http://kristiannielsen.livejournal.com/1885.html).
* dgcov was re-implemented to aggregate the data and to work for git and cmake by Sergei Golubchik.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dgcov/>

Installing MinIO for Usage With mariadb-test-run
================================================

    When testing the S3 storage engine with the s3 test suite, [mariadb-test-run](../mariadb-test/index) needs access to Amazon S3 compatible storage.

 The easiest way to achieve this is to install [MinIO](https://min.io), an open source S3 compatible storage.

 Here is a shell script that you can use to install MinIO with the right credentials for [mariadb-test-run](../mariadb-test/index). This should work on most Linux systems as the binaries are statically linked. You can alternatively download MinIO binaries directly from [here](https://min.io/download).

 
```
# Where to install the MinIO binaries and where to store the data
install=/my/local/minio
data=/tmp/shared

# Get the MinIO binaries. You can skip this test if you already have MinIO installed.
mkdir -p $install
wget https://dl.min.io/server/minio/release/linux-amd64/minio -O $install/minio
wget https://dl.min.io/client/mc/release/linux-amd64/mc -O $install/mc
chmod a+x $install/minio $install/mc

# Setup MinIO for usage with mariadb-test-run
MINIO_ACCESS_KEY=minio MINIO_SECRET_KEY=minioadmin $install/minio server $data 2>&1 &
$install/mc config host add local http://127.0.0.1:9000 minio minioadmin
$install/mc mb --ignore-existing local/storage-engine

```

Now you can run the S3 test suite:

 
```
cd "mysql-source-dir"/mariadb-test
./mariadb-test-run --suite=s3

```

If there is an issue while running the test suite, you can see the files created by MinIO with:

 
```
$install/mc ls -r local/storage-engine

```

or

 
```
ls $data/storage-engine

```

If you want to use MinIO with different credentials or you want to run the test against another S3 storage you ave to update the update the following files:

 
```
mariadb-test/suite/s3/my.cnf
mariadb-test/suite/s3/slave.cnf

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-minio-for-usage-with-mariadb-test-run/>

Operating System Error Codes
============================

    Below is a partial list of more common Linux and Windows operating system error codes.

 Linux Error Codes
-----------------

 The [perror](../perror/index) tool can be used to find the error message which is associated with a given error code.

 


| Number | Error Code | Description |
| --- | --- | --- |
| 1 | EPERM | Operation not permitted |
| 2 | ENOENT | No such file or directory |
| 3 | ESRCH | No such process |
| 4 | EINTR | Interrupted system call |
| 5 | EIO | I/O error |
| 6 | ENXIO | No such device or address |
| 7 | E2BIG | Argument list too long |
| 8 | ENOEXEC | Exec format error |
| 9 | EBADF | Bad file number |
| 10 | ECHILD | No child processes |
| 11 | EAGAIN | Try again |
| 12 | ENOMEM | Out of memory |
| 13 | EACCES | Permission denied |
| 14 | EFAULT | Bad address |
| 15 | ENOTBLK | Block device required |
| 16 | EBUSY | Device or resource busy |
| 17 | EEXIST | File exists |
| 18 | EXDEV | Cross-device link |
| 19 | ENODEV | No such device |
| 20 | ENOTDIR | Not a directory |
| 21 | EISDIR | Is a directory |
| 22 | EINVAL | Invalid argument |
| 23 | ENFILE | File table overflow |
| 24 | EMFILE | Too many open files |
| 25 | ENOTTY | Not a typewriter |
| 26 | ETXTBSY | Text file busy |
| 27 | EFBIG | File too large |
| 28 | ENOSPC | No space left on device |
| 29 | ESPIPE | Illegal seek |
| 30 | EROFS | Read-only file system |
| 31 | EMLINK | Too many links |
| 32 | EPIPE | Broken pipe |
| 33 | EDOM | Math argument out of domain of func |
| 34 | ERANGE | Math result not representable |
| 35 | EDEADLK | Resource deadlock would occur |
| 36 | ENAMETOOLONG | File name too long |
| 37 | ENOLCK | No record locks available |
| 38 | ENOSYS | Function not implemented |
| 39 | ENOTEMPTY | Directory not empty |
| 40 | ELOOP | Too many symbolic links encountered |
| 42 | ENOMSG | No message of desired type |
| 43 | EIDRM | Identifier removed |
| 44 | ECHRNG | Channel number out of range |
| 45 | EL2NSYNC | Level 2 not synchronized |
| 46 | EL3HLT | Level 3 halted |
| 47 | EL3RST | Level 3 reset |
| 48 | ELNRNG | Link number out of range |
| 49 | EUNATCH | Protocol driver not attached |
| 50 | ENOCSI | No CSI structure available |
| 51 | EL2HLT | Level 2 halted |
| 52 | EBADE | Invalid exchange |
| 53 | EBADR | Invalid request descriptor |
| 54 | EXFULL | Exchange full |
| 55 | ENOANO | No anode |
| 56 | EBADRQC | Invalid request code |
| 57 | EBADSLT | Invalid slot |
| 59 | EBFONT | Bad font file format |
| 60 | ENOSTR | Device not a stream |
| 61 | ENODATA | No data available |
| 62 | ETIME | Timer expired |
| 63 | ENOSR | Out of streams resources |
| 64 | ENONET | Machine is not on the network |
| 65 | ENOPKG | Package not installed |
| 66 | EREMOTE | Object is remote |
| 67 | ENOLINK | Link has been severed |
| 68 | EADV | Advertise error |
| 69 | ESRMNT | Srmount error |
| 70 | ECOMM | Communication error on send |
| 71 | EPROTO | Protocol error |
| 72 | EMULTIHOP | Multihop attempted |
| 73 | EDOTDOT | RFS specific error |
| 74 | EBADMSG | Not a data message |
| 75 | EOVERFLOW | Value too large for defined data type |
| 76 | ENOTUNIQ | Name not unique on network |
| 77 | EBADFD | File descriptor in bad state |
| 78 | EREMCHG | Remote address changed |
| 79 | ELIBACC | Can not access a needed shared library |
| 80 | ELIBBAD | Accessing a corrupted shared library |
| 81 | ELIBSCN | .lib section in a.out corrupted |
| 82 | ELIBMAX | Attempting to link in too many shared libraries |
| 83 | ELIBEXEC | Cannot exec a shared library directly |
| 84 | EILSEQ | Illegal byte sequence |
| 85 | ERESTART | Interrupted system call should be restarted |
| 86 | ESTRPIPE | Streams pipe error |
| 87 | EUSERS | Too many users |
| 88 | ENOTSOCK | Socket operation on non-socket |
| 89 | EDESTADDRREQ | Destination address required |
| 90 | EMSGSIZE | Message too long |
| 91 | EPROTOTYPE | Protocol wrong type for socket |
| 92 | ENOPROTOOPT | Protocol not available |
| 93 | EPROTONOSUPPORT | Protocol not supported |
| 94 | ESOCKTNOSUPPORT | Socket type not supported |
| 95 | EOPNOTSUPP | Operation not supported on transport endpoint |
| 96 | EPFNOSUPPORT | Protocol family not supported |
| 97 | EAFNOSUPPORT | Address family not supported by protocol |
| 98 | EADDRINUSE | Address already in use |
| 99 | EADDRNOTAVAIL | Cannot assign requested address |
| 100 | ENETDOWN | Network is down |
| 101 | ENETUNREACH | Network is unreachable |
| 102 | ENETRESET | Network dropped connection because of reset |
| 103 | ECONNABORTED | Software caused connection abort |
| 104 | ECONNRESET | Connection reset by peer |
| 105 | ENOBUFS | No buffer space available |
| 106 | EISCONN | Transport endpoint is already connected |
| 107 | ENOTCONN | Transport endpoint is not connected |
| 108 | ESHUTDOWN | Cannot send after transport endpoint shutdown |
| 109 | ETOOMANYREFS | Too many references: cannot splice |
| 110 | ETIMEDOUT | Connection timed out |
| 111 | ECONNREFUSED | Connection refused |
| 112 | EHOSTDOWN | Host is down |
| 113 | EHOSTUNREACH | No route to host |
| 114 | EALREADY | Operation already in progress |
| 115 | EINPROGRESS | Operation now in progress |
| 116 | ESTALE | Stale NFS file handle |
| 117 | EUCLEAN | Structure needs cleaning |
| 118 | ENOTNAM | Not a XENIX named type file |
| 119 | ENAVAIL | No XENIX semaphores available |
| 120 | EISNAM | Is a named type file |
| 121 | EREMOTEIO | Remote I/O error |
| 122 | EDQUOT | Quota exceeded |
| 123 | ENOMEDIUM | No medium found |
| 124 | EMEDIUMTYPE | Wrong medium type |
| 125 | ECANCELED | Operation Canceled |
| 126 | ENOKEY | Required key not available |
| 127 | EKEYEXPIRED | Key has expired |
| 128 | EKEYREVOKED | Key has been revoked |
| 129 | EKEYREJECTED | Key was rejected by service |
| 130 | EOWNERDEAD | Owner died |
| 131 | ENOTRECOVERABLE | State not recoverable |

 
Windows Error Codes
-------------------

 For a complete list, see <https://msdn.microsoft.com/en-us/library/ms681381.aspx>

 


| Number | Error Code | Description |
| --- | --- | --- |
| 1 | ERROR\_INVALID\_FUNCTION | Incorrect function. |
| 2 | ERROR\_FILE\_NOT\_FOUND | The system cannot find the file specified. |
| 3 | ERROR\_PATH\_NOT\_FOUND | The system cannot find the path specified. |
| 4 | ERROR\_TOO\_MANY\_OPEN\_FILES | The system cannot open the file. |
| 5 | ERROR\_ACCESS\_DENIED | Access is denied. |
| 6 | ERROR\_INVALID\_HANDLE | The handle is invalid. |
| 7 | ERROR\_ARENA\_TRASHED | The storage control blocks were destroyed. |
| 8 | ERROR\_NOT\_ENOUGH\_MEMORY | Not enough storage is available to process this command. |
| 9 | ERROR\_INVALID\_BLOCK | The storage control block address is invalid. |
| 10 | ERROR\_BAD\_ENVIRONMENT | The environment is incorrect. |
| 11 | ERROR\_BAD\_FORMAT | An attempt was made to load a program with an incorrect format. |
| 12 | ERROR\_INVALID\_ACCESS | The access code is invalid. |
| 13 | ERROR\_INVALID\_DATA | The data is invalid. |
| 14 | ERROR\_OUTOFMEMORY | Not enough storage is available to complete this operation. |
| 15 | ERROR\_INVALID\_DRIVE | The system cannot find the drive specified. |
| 16 | ERROR\_CURRENT\_DIRECTORY | The directory cannot be removed. |
| 17 | ERROR\_NOT\_SAME\_DEVICE | The system cannot move the file to a different disk drive. |
| 18 | ERROR\_NO\_MORE\_FILES | There are no more files. |
| 19 | ERROR\_WRITE\_PROTECT | The media is write protected. |
| 20 | ERROR\_BAD\_UNIT | The system cannot find the device specified. |
| 21 | ERROR\_NOT\_READY | The device is not ready. |
| 22 | ERROR\_BAD\_COMMAND | The device does not recognize the command. |
| 23 | ERROR\_CRC | Data error (cyclic redundancy check). |
| 24 | ERROR\_BAD\_LENGTH | The program issued a command but the command length is incorrect. |
| 25 | ERROR\_SEEK | The drive cannot locate a specific area or track on the disk. |
| 26 | ERROR\_NOT\_DOS\_DISK | The specified disk or diskette cannot be accessed. |
| 27 | ERROR\_SECTOR\_NOT\_FOUND | The drive cannot find the sector requested. |
| 28 | ERROR\_OUT\_OF\_PAPER | The printer is out of paper. |
| 29 | ERROR\_WRITE\_FAULT | The system cannot write to the specified device. |
| 30 | ERROR\_READ\_FAULT | The system cannot read from the specified device. |
| 31 | ERROR\_GEN\_FAILURE | A device attached to the system is not functioning. |
| 32 | ERROR\_SHARING\_VIOLATION | The process cannot access the file because it is being used by another process. |
| 33 | ERROR\_LOCK\_VIOLATION | The process cannot access the file because another process has locked a portion of the file. |
| 34 | ERROR\_WRONG\_DISK | The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1. |
| 36 | ERROR\_SHARING\_BUFFER\_EXCEEDED | Too many files opened for sharing. |
| 38 | ERROR\_HANDLE\_EOF | Reached the end of the file. |
| 39 | ERROR\_HANDLE\_DISK\_FULL | The disk is full. |
| 87 | ERROR\_INVALID\_PARAMETER | The parameter is incorrect. |
| 112 | ERROR\_DISK\_FULL | The disk is full. |
| 123 | ERROR\_INVALID\_NAME | The file name, directory name, or volume label syntax is incorrect. |
| 1450 | ERROR\_NO\_SYSTEM\_RESOURCES | Insufficient system resources exist to complete the requested service. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/operating-system-error-codes/>

mysql.tables\_priv Table
========================

    The `mysql.tables_priv` table contains information about table-level privileges. The table can be queried and although it is possible to directly update it, it is best to use [GRANT](../grant/index) for setting privileges. 

 Note that the MariaDB privileges occur at many levels. A user may be granted a privilege at the table level, but may still not have permission on a database level, for example. See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 The [INFORMATION\_SCHEMA.TABLE\_PRIVILEGES](../information-schema-table_privileges-table/index) table derives its contents from `mysql.tables_priv`.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.tables_priv` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User`, `Db` and `Table_name`makes up the unique identifier for this record. |
| `Db` | `char(64)` | NO | PRI |  | Database (together with `User`, `Host` and `Table_name`makes up the unique identifier for this record. |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host`, `Db` and `Table_name`makes up the unique identifier for this record. |
| `Table_name` | `char(64)` | NO | PRI |  | Table name (together with `User`, `Db` and `Table`makes up the unique identifier for this record. |
| `Grantor` | `char(141)` | NO | MUL |  |  |
| `Timestamp` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` |  |
| `Table_priv` | `set('Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter', 'Create View', 'Show view', 'Trigger', 'Delete versioning rows')` | NO |  |  | The table privilege type. See [Table Privileges](../grant/index#table-privileges) for details. |
| `Column_priv` | `set('Select', 'Insert', 'Update', 'References')` | NO |  |  | The column privilege type. See [Column Privileges](../grant/index#column-privileges) for details. |

 
The [Acl\_table\_grants](../server-status-variables/index#acl_table_grants) status variable, added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/), indicates how many rows the `mysql.tables_priv` table contains.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltables_priv-table/>

mysql.time\_zone Table
======================

    The `mysql.time_zone` table is one of the mysql system tables that can contain [time zone](../time-zones/index) information. It is usually preferable for the system to handle the time zone, in which case the table will be empty (the default), but you can populate the mysql time zone tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility. See [Time Zones](../time-zones/index) for details.

 This table uses the [Aria](../aria/index) storage engine.

 The `mysql.time_zone` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Time_zone_id` | `int(10) unsigned` | NO | PRI | `NULL` | ID field, auto\_increments. |
| `Use_leap_seconds` | `enum('Y','N')` | NO |  | N | Whether or not leap seconds are used. |

 
Example
-------

 
```
SELECT * FROM mysql.time_zone;
+--------------+------------------+
| Time_zone_id | Use_leap_seconds |
+--------------+------------------+
|            1 | N                |
|            2 | N                |
|            3 | N                |
|            4 | N                |
|            5 | N                |
|            6 | N                |
|            7 | N                |
|            8 | N                |
|            9 | N                |
|           10 | N                |
...
+--------------+------------------+

```

See Also
--------

 * [mysql.time\_zone\_leap\_second table](../mysqltime_zone_leap_second-table/index)
* [mysql.time\_zone\_name table](../mysqltime_zone_name-table/index)
* [mysql.time\_zone\_transition table](../mysqltime_zone_transition-table/index)
* [mysql.time\_zone\_transition\_type table](../mysqltime_zone_transition_type-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltime_zone-table/>

Upgrading to MariaDB From MySQL 5.0 or Older
============================================

    If you upgrade to [MariaDB 5.1](../what-is-mariadb-51/index) from MySQL 5.1 you [don't have to do anything](../how-can-i-upgrade-from-mysql-to-mariadb/index) with your data or MySQL clients. Things should "just work".

 When upgrading between different major versions of MariaDB or MySQL you need to run the [mysql\_upgrade](../mysql_upgrade/index) program to convert data that are incompatible between versions. This will also update your privilege tables in the mysql database to the latest format.

 In almost all cases [mysql\_upgrade](../mysql_upgrade/index) should be able to convert your tables, without you having to dump and restore your data.

 After installing MariaDB, just do:

 
```
mysql_upgrade --verbose

```

If you want to run with a specific TCP/IP port do:

 
```
mysql_upgrade --host=127.0.0.1 --port=3308 --protocol=tcp

```

If you want to connect with a socket do:

 
```
mysql_upgrade --socket=127.0.0.1 --protocol=socket

```

To see other options, use [--help](../mysql_upgrade/index).

 "mysql\_upgrade" reads the [my.cnf](../mysqld-configuration-files-and-groups/index) sections [mysql\_upgrade] and [client] for default values.

 There are a variety of reasons tables need to be converted; they could be any of the following:

 * The collation (sorting order) for an index column has changed
* A field type has changed storage format
	+ `[DECIMAL](../decimal/index)` and `[VARCHAR](../varchar/index)` changed format between MySQL 4.1 and MySQL 5.0
* An engine has a new storage format
	+ [ARCHIVE](../archive/index) changed storage format between 5.0 and 5.1
* The format for storing [table names](../identifier-names/index) has changed
	+ In MySQL 5.1 table names are encoded so that the file names are identical on all computers. Old table names that contains forbidden file name characters will show up prefixed with #mysql50# in `SHOW TABLES` until you convert them.

 If you don't convert the tables, one of the following things may happen:

 * You will get warnings in the error log every time you access a table with an invalid (old) file name.
* When searching on key values you may not find all rows
* You will get an error "ERROR 1459 (HY000): Table upgrade required" when accessing the table.
* You may get crashes

 "mysql\_upgrade" works by calling mysqlcheck with different options and running the "mysql\_fix\_privileges" script. If you have trouble with "mysql\_upgrade", you can run these commands separately to get more information of what is going on.

 Most of the things in the [MySQL 5.1 manual](http://dev.mysql.com/doc/refman/5.1/en/upgrading.html) section also applies to MariaDB.

 The following differences exists between "mysql\_upgrade" in MariaDB and MySQL (as of [MariaDB 5.1.50](https://mariadb.com/kb/en/mariadb-5150-release-notes/)):

 * MariaDB will convert long table names properly.
* MariaDB will convert [InnoDB](../xtradb-and-innodb/index) tables (no need to do a dump/restore or `[ALTER TABLE](../alter-table/index)`).
* MariaDB will convert old archive tables to the new 5.1 format (note: new feature in testing).
* "mysql\_upgrade --verbose" will run "mysqlcheck --verbose" so that you get more information of what is happening.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-to-mariadb-from-mysql/>

mysqlhotcopy
============

    
mysqlhotcopy is deprecated and may be removed in a future release.

 
`mysqlhotcopy` uses [FLUSH TABLES](../flush/index), [LOCK TABLES](../lock-tables/index), and cp or scp to make a database backup.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-hotcopy](../mariadb-hotcopy/index) is a symlink to `mysqlhotcopy`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-hotcopy](../mariadb-hotcopy/index) is the name of the script, with `mysqlhotcopy` a symlink .

 
See [mariadb-hotcopy](../mariadb-hotcopy/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhotcopy/>

mysqlreport
===========

    `mysqlreport` makes a friendly report of important MariaDB status values.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-report](../mariadb-report/index) is a symlink to `mysqlreport`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysqlreport` is the symlink, and [mariadb-report](../mariadb-report/index) the binary name.

 
See [mariadb-report](../mariadb-report/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlreport/>

mysql.time\_zone\_leap\_second Table
====================================

    The `mysql.time_zone_leap_second` table is one of the mysql system tables that can contain [time zone](../time-zones/index) information. It is usually preferable for the system to handle the time zone, in which case the table will be empty (the default), but you can populate the mysql time zone tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility. See [Time Zones](../time-zones/index) for details.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.time_zone_leap_second` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Transition_time` | `bigint(20)` | NO | PRI | `NULL` |  |
| `Correction` | `int(11)` | NO |  | `NULL` |  |

 
See Also
--------

 * [mysql.time\_zone table](../mysqltime_zone-table/index)
* [mysql.time\_zone\_name table](../mysqltime_zone_name-table/index)
* [mysql.time\_zone\_transition table](../mysqltime_zone_transition-table/index)
* [mysql.time\_zone\_transition\_type table](../mysqltime_zone_transition_type-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltime_zone_leap_second-table/>

mysqlaccess
===========

    `mysqlaccess` is a tool for checking access privileges, developed by Yves Carlier.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), `mariadb-access` is a symlink to `mysqlaccess`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mariadb-access` is the name of the tool, with `mysqlaccess` a symlink .

 
 See [mariadb-access](../mariadb-access/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlaccess/>

mysql.time\_zone\_transition Table
==================================

    The `mysql.time_zone_transition` table is one of the `mysql` system tables that can contain [time zone](../time-zones/index) information. It is usually preferable for the system to handle the time zone, in which case the table will be empty (the default), but you can populate the `mysql` time zone tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility. See [Time Zones](../time-zones/index) for details.

 This table uses the [Aria](../aria/index) storage engine.

 The `mysql.time_zone_transition` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Time_zone_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `Transition_time` | `bigint(20)` | NO | PRI | `NULL` |  |
| `Transition_type_id` | `int(10) unsigned` | NO |  | `NULL` |  |

 
Example
-------

 
```
SELECT * FROM mysql.time_zone_transition;
+--------------+-----------------+--------------------+
| Time_zone_id | Transition_time | Transition_type_id |
+--------------+-----------------+--------------------+
|            1 |     -1830383032 |                  1 |
|            2 |     -1640995148 |                  2 |
|            2 |     -1556841600 |                  1 |
|            2 |     -1546388400 |                  2 |
|            2 |     -1525305600 |                  1 |
|            2 |     -1514852400 |                  2 |
|            2 |     -1493769600 |                  1 |
|            2 |     -1483316400 |                  2 |
|            2 |     -1462233600 |                  1 |
|            2 |     -1451780400 |                  2 |
...
+--------------+-----------------+--------------------+

```

See Also
--------

 * [mysql.time\_zone table](../mysqltime_zone-table/index)
* [mysql.time\_zone\_leap\_second table](../mysqltime_zone_leap_second-table/index)
* [mysql.time\_zone\_name table](../mysqltime_zone_name-table/index)
* [mysql.time\_zone\_transition\_type table](../mysqltime_zone_transition_type-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltime_zone_transition-table/>

mysql.time\_zone\_name Table
============================

    The `mysql.time_zone_name` table is one of the mysql system tables that can contain [time zone](../time-zones/index) information. It is usually preferable for the system to handle the time zone, in which case the table will be empty (the default), but you can populate the mysql time zone tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility. See [Time Zones](../time-zones/index) for details.

 This table uses the [Aria](../aria/index) storage engine.

 The `mysql.time_zone_name` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Name` | `char(64)` | NO | PRI | `NULL` | Name of the time zone. |
| `Time_zone_id` | `int(10) unsigned` | NO | PRI | `NULL` | ID field, auto\_increments. |

 
Example
-------

 
```
SELECT * FROM mysql.time_zone_name;
+--------------------+--------------+
| Name               | Time_zone_id |
+--------------------+--------------+
| Africa/Abidjan     |            1 |
| Africa/Accra       |            2 |
| Africa/Addis_Ababa |            3 |
| Africa/Algiers     |            4 |
| Africa/Asmara      |            5 |
| Africa/Asmera      |            6 |
| Africa/Bamako      |            7 |
| Africa/Bangui      |            8 |
| Africa/Banjul      |            9 |
| Africa/Bissau      |           10 |
...
+--------------------+--------------+

```

See Also
--------

 * [mysql.time\_zone table](../mysqltime_zone-table/index)
* [mysql.time\_zone\_leap\_second table](../mysqltime_zone_leap_second-table/index)
* [mysql.time\_zone\_transition table](../mysqltime_zone_transition-table/index)
* [mysql.time\_zone\_transition\_type table](../mysqltime_zone_transition_type-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltime_zone_name-table/>

mysql.event Table
=================

    The `mysql.event` table contains information about MariaDB [events](../stored-programs-and-views-events/index). Similar information can be obtained by viewing the [INFORMATION\_SCHEMA.EVENTS](../information-schema-events-table/index) table, or with the [SHOW EVENTS](show-event) and [SHOW CREATE EVENT](../show-create-event/index) statements.

 The table is upgraded live, and there is no need to restart the server if the table has changed.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.event` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `db` | `char(64)` | NO | PRI |  |  |
| `name` | `char(64)` | NO | PRI |  |  |
| `body` | `longblob` | NO |  | `NULL` |  |
| `definer` | `char(141)` | NO |  |  |  |
| `execute_at` | `datetime` | YES |  | `NULL` |  |
| `interval_value` | `int(11)` | YES |  | `NULL` |  |
| `interval_field` | `enum('YEAR', 'QUARTER', 'MONTH', 'DAY', 'HOUR', 'MINUTE', 'WEEK', 'SECOND', 'MICROSECOND', 'YEAR_MONTH', 'DAY_HOUR', 'DAY_MINUTE', 'DAY_SECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'MINUTE_SECOND', 'DAY_MICROSECOND', 'HOUR_MICROSECOND', 'MINUTE_MICROSECOND', 'SECOND_MICROSECOND')` | YES |  | `NULL` |  |
| `created` | `timestamp` | NO |  | `CURRENT_TIMESTAMP` |  |
| `modified` | `timestamp` | NO |  | 0000-00-00 00:00:00 |  |
| `last_executed` | `datetime` | YES |  | `NULL` |  |
| `starts` | `datetime` | YES |  | `NULL` |  |
| `ends` | `datetime` | YES |  | `NULL` |  |
| `status` | `enum('ENABLED', 'DISABLED', 'SLAVESIDE_DISABLED')` | NO |  | `ENABLED` | Current status of the event, one of enabled, disabled, or disabled on the slaveside. |
| `on_completion` | `enum('DROP','PRESERVE')` | NO |  | `DROP` |  |
| `sql_mode` | `set('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', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH')` | NO |  |  | The [SQL\_MODE](../sql-mode/index) at the time the event was created. |
| `comment` | `char(64)` | NO |  |  |  |
| `originator` | `int(10) unsigned` | NO |  | `NULL` |  |
| `time_zone` | `char(64)` | NO |  | `SYSTEM` |  |
| `character_set_client` | `char(32)` | YES |  | `NULL` |  |
| `collation_connection` | `char(32)` | YES |  | `NULL` |  |
| `db_collation` | `char(32)` | YES |  | `NULL` |  |
| `body_utf8` | `longblob` | YES |  | `NULL` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlevent-table/>

Starting with Catalogs
======================

    
**MariaDB starting with [11.3](../what-is-mariadb-113/index)**Catalog support is planned for 11.3.

  Background
----------

 [mariadb-install-db](../mariadb-install-db/index) initializes the MariaDB data directory and creates the [system tables](../system-tables/index) in the [mysql](../the-mysql-database-tables/index) database.

 When used with the `--catalog` options it will initialize MariaDB server to use catalogs. The [mariadbd server](mysqld) will automatically discover if catalogs are used or not.

 Note that **one cannot change** a 'normal server' to a server with catalogs or a server with catalogs to a 'normal server'. In the future we will add tools that will allow one to easily move an existing server inside a catalog or move an server inside a catalog to a standalone server.

 Initializing a New Server with Catalog Support
----------------------------------------------

 To initialize a server with 4 catalogs (the `def` catalog, that holds the catalog root user (CRU) is automatically created):

 
```
mariadb_install_db --catalogs="cat1 cat2 cat3" --datadir=/my/data/

```

The above will create a directory `/my/data` and the 4 directories under it, one for each catalog.

 Adding More Catalogs to a Running Server
----------------------------------------

 When adding more catalogs to an existing server, `mariadb_install_db` will start the [mariadb client](../mariadb-command-line-client/index) to execute the needed commands on the running server. This is why one has to supply user and password to `mariadb_install_db`.

 
```
mariadb_install_db --catalogs="cat4 cat5 cat6" --datadir=/my/data --catalog-user=monty --catalog-password

```

See Also
--------

 * [mariadb-install-db](../mariadb-install-db/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/starting-with-catalogs/>

mysql\_convert\_table\_format
=============================

    `mysql-convert-table-format` converts the tables in a database to use a particular storage engine (MyISAM by default).

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-convert-table-format](../mariadb-convert-table-format/index) is a symlink to `mysql_convert_table_format`. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-convert-table-format](../mariadb-convert-table-format/index) is the name of the tool, with `mysql_convert_table_format` a symlink .

 
See [mariadb-convert-table-format](../mariadb-convert-table-format/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_convert_table_format/>

mysql.global\_priv Table
========================

    
**MariaDB starting with [10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)**The `mysql.global_priv` table was introduced in [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/) to replace the [mysql.user](../mysqluser-table/index) table.

 
The `mysql.global_priv` table contains information about users that have permission to access the MariaDB server, and their global privileges.

 Note that the MariaDB privileges occur at many levels. A user may not be granted `create` privilege at the user level, but may still have `create` permission on certain tables or databases, for example. See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 The `mysql.global_priv` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `User` makes up the unique identifier for this account). |
| `User` | `char(80)` | NO | PRI |  | User (together with `Host` makes up the unique identifier for this account). |
| `Priv` | `longtext` | NO |  |  | Global privileges, granted to the account and other account properties |

 
From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), in order to help the server understand which version a privilege record was written by, the `priv` field contains a new JSON field, `version_id` ([MDEV-21704](https://jira.mariadb.org/browse/MDEV-21704)).

 Examples
--------

 
```
select * from mysql.global_priv;
+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+
| Host      | User        | Priv                                                                                                                                  |
+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+
| localhost | root        | {"access": 18446744073709551615,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"} |
| 127.%     | msandbox    | {"access":1073740799,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}            |
| localhost | msandbox    | {"access":1073740799,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}            |
| localhost | msandbox_rw | {"access":487487,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}                |
| 127.%     | msandbox_rw | {"access":487487,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}                |
| 127.%     | msandbox_ro | {"access":262145,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}                |
| localhost | msandbox_ro | {"access":262145,"plugin":"mysql_native_password","authentication_string":"*6C387FC3893DBA1E3BA155E74754DA6682D04747"}                |
| 127.%     | rsandbox    | {"access":524288,"plugin":"mysql_native_password","authentication_string":"*B07EB15A2E7BD9620DAE47B194D5B9DBA14377AD"}                |
+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------------+

```

Readable format:

 
```
SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM mysql.global_priv;

+--------------------------------------------------------------------------------------+
| CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv))                                 |
+--------------------------------------------------------------------------------------+
| root@localhost => {
    "access": 18446744073709551615,
    "plugin": "mysql_native_password",
    "authentication_string": "*6C387FC3893DBA1E3BA155E74754DA6682D04747"
} |
| msandbox@127.% => {
    "access": 1073740799,
    "plugin": "mysql_native_password",
    "authentication_string": "*6C387FC3893DBA1E3BA155E74754DA6682D04747"
}           |
+--------------------------------------------------------------------------------------+

```

A particular user:

 
```
SELECT CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv)) FROM mysql.global_priv 
  WHERE user='marijn';
+--------------------------------------------------------------------------------------+
| CONCAT(user, '@', host, ' => ', JSON_DETAILED(priv))                                 |
+--------------------------------------------------------------------------------------+
| marijn@localhost => {
    "access": 0,
    "plugin": "mysql_native_password",
    "authentication_string": "",
    "account_locked": true,
    "password_last_changed": 1558017158
} |
+--------------------------------------------------------------------------------------+

```

From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/):

 
```
GRANT FILE ON *.* TO user1@localhost;
SELECT Host, User, JSON_DETAILED(Priv) FROM mysql.global_priv WHERE user='user1'\G

*************************** 1. row ***************************
               Host: localhost
               User: user1
JSON_DETAILED(Priv): {
    "access": 512,
    "plugin": "mysql_native_password",
    "authentication_string": "",
    "password_last_changed": 1581070979,
    "version_id": 100502
}

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlglobal_priv-table/>

mysql\_embedded
===============

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-embedded](../mariadb-embedded/index) is a symlink to `mysql_embedded`. 

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-embedded](../mariadb-embedded/index) is the name of the tool, with `mysql_embedded` a symlink.

 
See [mariadb-embedded](../mariadb-embedded/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_embedded/>

mysql.time\_zone\_transition\_type Table
========================================

    The `mysql.time_zone_transition_type` table is one of the `mysql` system tables that can contain [time zone](../time-zones/index) information. It is usually preferable for the system to handle the time zone, in which case the table will be empty (the default), but you can populate the `mysql` time zone tables using the [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) utility. See [Time Zones](../time-zones/index) for details.

 This table uses the [Aria](../aria/index) storage engine.

 The `mysql.time_zone_transition_type` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Time_zone_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `Transition_type_id` | `int(10) unsigned` | NO | PRI | `NULL` |  |
| `Offset` | `int(11)` | NO |  | 0 |  |
| `Is_DST` | `tinyint(3) unsigned` | NO |  | 0 |  |
| `Abbreviation` | `char(8)` | NO |  |  |  |

 
Example
-------

 
```
SELECT * FROM mysql.time_zone_transition_type;
+--------------+--------------------+--------+--------+--------------+
| Time_zone_id | Transition_type_id | Offset | Is_DST | Abbreviation |
+--------------+--------------------+--------+--------+--------------+
|            1 |                  0 |   -968 |      0 | LMT          |
|            1 |                  1 |      0 |      0 | GMT          |
|            2 |                  0 |    -52 |      0 | LMT          |
|            2 |                  1 |   1200 |      1 | GHST         |
|            2 |                  2 |      0 |      0 | GMT          |
|            3 |                  0 |   8836 |      0 | LMT          |
|            3 |                  1 |  10800 |      0 | EAT          |
|            3 |                  2 |   9000 |      0 | BEAT         |
|            3 |                  3 |   9900 |      0 | BEAUT        |
|            3 |                  4 |  10800 |      0 | EAT          |
...
+--------------+--------------------+--------+--------+--------------+

```

See Also
--------

 * [mysql.time\_zone table](../mysqltime_zone-table/index)
* [mysql.time\_zone\_leap\_second table](../mysqltime_zone_leap_second-table/index)
* [mysql.time\_zone\_name table](../mysqltime_zone_name-table/index)
* [mysql.time\_zone\_transition table](../mysqltime_zone_transition-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltime_zone_transition_type-table/>

mysql\_tzinfo\_to\_sql
======================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) is a symlink to `mysql_tzinfo_to_sql`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_tzinfo_to_sql` is the symlink, and [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) the binary name.

 
See [mariadb-tzinfo-to-sql](../mariadb-tzinfo-to-sql/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_tzinfo_to_sql/>

mysql\_find\_rows
=================

    `mysql_find_rows` reads files containing SQL statements and extracts statements that match a given regular expression or that contain [USE db\_name](../use/index) or [SET](../set/index) statements.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-find-rows](../mariadb-find-rows/index) is a symlink to `mysql_find_rows`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), [mariadb-find-rows](../mariadb-find-rows/index) is the name of the binary, with `mysql_find_rows` a symlink .

 
See [mariadb-find-rows](../mariadb-find-rows/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_find_rows/>

mysql\_fix\_extensions
======================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-fix-extensions](../mariadb-fix-extensions/index) is a symlink to `mysql_fix_extensions`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_fix_extensions` is the symlink, and [mariadb-fix-extensions](../mariadb-fix-extensions/index) the binary name.

 
See [mariadb-fix-extensions](../mariadb-fix-extensions/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_fix_extensions/>

mysql\_waitpid
==============

    `mysql_pid` is a utility for terminating processes. It runs on Unix-like systems, making use of the `kill()` system call.

 
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-waitpid](../mariadb-waitpid/index) is a symlink to `mysql_waitpid`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_waitpid` is the symlink, and [mariadb-waitpid](../mariadb-waitpid/index) the binary name.

  See [mariadb-waitpid](../mariadb-waitpid/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_waitpid/>

mysql\_setpermission
====================

    
**MariaDB starting with [10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/)**From [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/), [mariadb-setpermission](../mariadb-setpermission/index) is a symlink to `mysql_setpermission`.

 

**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**From [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/), `mysql_setpermission` is the symlink, and [mariadb-setpermission](../mariadb-setpermission/index) the binary name.

 
See [mariadb-setpermission](../mariadb-setpermission/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_setpermission/>

mysql\_zap
==========

    
**MariaDB until [10.1](../what-is-mariadb-101/index)**mysql\_zap was removed in [MariaDB 10.2](../what-is-mariadb-102/index). pkill can be used [as an alternative](#pkill-as-an-alternative).

 
*mysql\_zap* kills processes that match a pattern. It uses the *ps* command and Unix signals, so it runs on Unix and Unix-like systems.

 Invoke mysql\_zap like this:

 
```
shell> mysql_zap [-signal] [-?Ift] 

```

A process matches if its output line from the *ps* command contains the pattern. By default, mysql\_zap asks for confirmation for each process. Respond *y* to kill the process, or *q* to exit mysql\_zap. For any other response, mysql\_zap does not attempt to kill the process.

 If the *-signal* option is given, it specifies the name or number of the signal to send to each process. Otherwise, mysql\_zap tries first with TERM (signal 15) and then with KILL (signal 9).

 mysql\_zap supports the following additional options:

 


| Option | Description |
| --- | --- |
| `--help`, `-?`, `-I` | Display a help message and exit. |
| `-f` | Force mode. *mysql\_zap* attempts to kill each process without confirmation. |
| `-t` | Test mode. Display information about each process but do not kill it. |

 
Example
-------

 
```
localhost:~# mysql_zap -t mysql
stty: standard input: unable to perform all requested operations
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      4073  0.0  0.2   3804  1308 ?        S    08:51   0:00 /bin/bash /usr/bin/mysqld_safe
mysql     4258  3.3 15.7 939740 81236 ?        Sl   08:51  30:18 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306

```

pkill as an Alternative
-----------------------

 *pkill* can be used as an alternative to *mysql\_zap*, although an important distinction between pkill and mysql\_zap is that mysql\_zap kills the server 'gently' first (with signal 15) and only if the server doesn't die in a limited time then tries -9.

 To use pkill in the same way, one must run it twice; `pkill --signal 15 mysqld ; sleep(10) ; pkill -f --signal 9 pattern`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysql_zap/>

mysql.column\_stats Table
=========================

    The `mysql.column_stats` table is one of three tables storing data used for [Engine-independent table statistics](../engine-independent-table-statistics/index). The others are [mysql.table\_stats](../mysqltable_stats-table/index) and [mysql.index\_stats](../mysqlindex_stats-table/index).

 
Note that statistics for blob and text columns are not collected. If explicitly specified, a warning is returned.

 

**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.column_stats` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `db_name` | `varchar(64)` | NO | PRI | `NULL` | Database the table is in. |
| `table_name` | `varchar(64)` | NO | PRI | `NULL` | Table name. |
| `column_name` | `varchar(64)` | NO | PRI | `NULL` | Name of the column. |
| `min_value` | `varchar(255)` | YES |  | `NULL` | Minimum value in the table (in text form). |
| `max_value` | `varchar(255)` | YES |  | `NULL` | Maximum value in the table (in text form). |
| `nulls_ratio` | `decimal(12,4)` | YES |  | `NULL` | Fraction of `NULL` values (0- no `NULL`s, 0.5 - half values are `NULL`s, 1 - all values are `NULL`s). |
| `avg_length` | `decimal(12,4)` | YES |  | `NULL` | Average length of column value, in bytes. Counted as if one ran `SELECT AVG(LENGTH(col))`. This doesn't count `NULL` bytes, assumes endspace removal for `CHAR(n)`, etc. |
| `avg_frequency` | `decimal(12,4)` | YES |  | `NULL` | Average number of records with the same value |
| `hist_size` | `tinyint(3) unsigned` | YES |  | `NULL` | Histogram size in bytes, from 0-255, or, from [MariaDB 10.7](../what-is-mariadb-107/index), number of buckets if the histogram type is `JSON_HB`. |
| `hist_type` | `enum('SINGLE_PREC_HB', 'DOUBLE_PREC_HB')` (>= [MariaDB 10.7](../what-is-mariadb-107/index))`enum('SINGLE_PREC_HB', 'DOUBLE_PREC_HB','JSON_HB')` (<= [MariaDB 10.6](../what-is-mariadb-106/index)) | YES |  | `NULL` | Histogram type. See the [histogram\_type](../server-system-variables/index#histogram_type) system variable. |
| `histogram` | `blob` (>= [MariaDB 10.7](../what-is-mariadb-107/index))`varbinary(255)` (<=[MariaDB 10.6](../what-is-mariadb-106/index)) | YES |  | `NULL` |  |

 
It is possible to manually update the table. See [Manual updates to statistics tables](../engine-independent-table-statistics/index#manual-updates-to-statistics-tables) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlcolumn_stats-table/>

mysql.index\_stats Table
========================

    The `mysql.index_stats` table is one of three tables storing data used for [Engine-independent table statistics](../engine-independent-table-statistics/index). The others are [mysql.column\_stats](../mysqlcolumn_stats-table/index) and [mysql.table\_stats](../mysqltable_stats-table/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.index_stats` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `db_name` | `varchar(64)` | NO | PRI | `NULL` | Database the table is in. |
| `table_name` | `varchar(64)` | NO | PRI | `NULL` | Table name |
| `index_name` | `varchar(64)` | NO | PRI | `NULL` | Name of the index |
| `prefix_arity` | `int(11) unsigned` | NO | PRI | `NULL` | Index prefix length. 1 for the first keypart, 2 for the first two, and so on. InnoDB's extended keys are supported. |
| `avg_frequency` | `decimal(12,4)` | YES |  | `NULL` | Average number of records one will find for given values of (keypart1, keypart2, ..), provided the values will be found in the table. |

 
It is possible to manually update the table. See [Manual updates to statistics tables](../engine-independent-table-statistics/index#manual-updates-to-statistics-tables) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlindex_stats-table/>

mysql.innodb\_index\_stats
==========================

     The `mysql.innodb_index_stats` table stores data related to particular [InnoDB Persistent Statistics](../innodb-persistent-statistics/index), and contains multiple rows for each index.

 This table, along with the related [mysql.innodb\_table\_stats](../mysqlinnodb_table_stats/index) table, can be manually updated in order to force or test differing query optimization plans. After updating, `FLUSH TABLE innodb_index_stats` is required to load the changes.

 `mysql.innodb_index_stats` is not replicated, although any [ANALYZE TABLE](../analyze-table/index) statements on the table will be by default.. 

 It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `database_name` | `varchar(64)` | NO | PRI | `NULL` | Database name. |
| `table_name` | `varchar(64)` | NO | PRI | `NULL` | Table, partition or subpartition name. |
| `index_name` | `varchar(64)` | NO | PRI | `NULL` | Index name. |
| `last_update` | `timestamp` | NO |  | `current_timestamp()` | Time that this row was last updated. |
| `stat_name` | `varchar(64)` | NO | PRI | `NULL` | Statistic name. |
| `stat_value` | `bigint(20) unsigned` | NO |  | `NULL` | Estimated statistic value. |
| `sample_size` | `bigint(20) unsigned` | YES |  | `NULL` | Number of pages sampled for the estimated statistic value. |
| `stat_description` | `varchar(1024)` | NO |  | `NULL` | Statistic description. |

 
Example
-------

 
```
SELECT * FROM mysql.innodb_index_stats\G
*************************** 1. row ***************************
   database_name: mysql
      table_name: gtid_slave_pos
      index_name: PRIMARY
     last_update: 2017-08-19 20:38:34
       stat_name: n_diff_pfx01
      stat_value: 0
     sample_size: 1
stat_description: domain_id
*************************** 2. row ***************************
   database_name: mysql
      table_name: gtid_slave_pos
      index_name: PRIMARY
     last_update: 2017-08-19 20:38:34
       stat_name: n_diff_pfx02
      stat_value: 0
     sample_size: 1
stat_description: domain_id,sub_id
*************************** 3. row ***************************
   database_name: mysql
      table_name: gtid_slave_pos
      index_name: PRIMARY
     last_update: 2017-08-19 20:38:34
       stat_name: n_leaf_pages
      stat_value: 1
     sample_size: NULL
stat_description: Number of leaf pages in the index
*************************** 4. row ***************************
   database_name: mysql
      table_name: gtid_slave_pos
      index_name: PRIMARY
     last_update: 2017-08-19 20:38:34
       stat_name: size
      stat_value: 1
     sample_size: NULL
stat_description: Number of pages in the index
*************************** 5. row ***************************
   database_name: test
      table_name: ft
      index_name: FTS_DOC_ID_INDEX
     last_update: 2017-09-15 12:58:39
       stat_name: n_diff_pfx01
      stat_value: 0
     sample_size: 1
stat_description: FTS_DOC_ID
*************************** 6. row ***************************
   database_name: test
      table_name: ft
      index_name: FTS_DOC_ID_INDEX
     last_update: 2017-09-15 12:58:39
       stat_name: n_leaf_pages
      stat_value: 1
     sample_size: NULL
stat_description: Number of leaf pages in the index
...

```

See Also
--------

 * [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [mysql.innodb\_table\_stats](../mysqlinnodb_table_stats/index)
* [ANALYZE TABLE](../analyze-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlinnodb_index_stats/>

mysql.innodb\_table\_stats
==========================

     The `mysql.innodb_table_stats` table stores data related to [InnoDB Persistent Statistics](../innodb-persistent-statistics/index), and contains one row per table. 

 This table, along with the related [mysql.innodb\_index\_stats](../mysqlinnodb_index_stats/index) table, can be manually updated in order to force or test differing query optimization plans. After updating, `FLUSH TABLE innodb_table_stats` is required to load the changes.

 `mysql.innodb_table_stats` is not replicated, although any [ANALYZE TABLE](../analyze-table/index) statements on the table will be by default.. 

 It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `database_name` | `varchar(64)` | NO | PRI | `NULL` | Database name. |
| `table_name`  | `varchar(64)` | NO | PRI | `NULL` | Table, partition or subpartition name. |
| `last_update` | `timestamp` | NO |  | `current_timestamp()` | Time that this row was last updated. |
| `n_rows` | `bigint(20) unsigned` | NO |  | `NULL` | Number of rows in the table. |
| `clustered_index_size` | `bigint(20) unsigned` | NO |  | `NULL` | Size, in pages, of the primary index. |
| `sum_of_other_index_sizes` | `bigint(20) unsigned` | NO |  | `NULL` | Size, in pages, of non-primary indexes. |

 
Example
-------

 
```
SELECT * FROM mysql.innodb_table_stats\G
*************************** 1. row ***************************
           database_name: mysql
              table_name: gtid_slave_pos
             last_update: 2017-08-19 20:38:34
                  n_rows: 0
    clustered_index_size: 1
sum_of_other_index_sizes: 0
*************************** 2. row ***************************
           database_name: test
              table_name: ft
             last_update: 2017-09-15 12:58:39
                  n_rows: 0
    clustered_index_size: 1
sum_of_other_index_sizes: 2
...

```

See Also
--------

 * [InnoDB Persistent Statistics](../innodb-persistent-statistics/index)
* [mysql.innodb\_index\_stats](../mysqlinnodb_index_stats/index)
* [ANALYZE TABLE](../analyze-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlinnodb_table_stats/>

mysql.servers Table
===================

    The `mysql.servers` table contains information about servers as used by the [Spider](../spider/index), [FEDERATED](../federated-storage-engine/index) or [FederatedX](../federatedx/index), [Connect](../connect/index) storage engines (see [CREATE SERVER](../create-server/index)).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.servers` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Server_name` | `char(64)` | NO | PRI |  |  |
| `Host` | `char(64)` | NO |  |  |  |
| `Db` | `char(64)` | NO |  |  |  |
| `Username` | `char(80)` | NO |  |  |  |
| `Password` | `char(64)` | NO |  |  |  |
| `Port` | `int(4)` | NO |  | 0 |  |
| `Socket` | `char(64)` | NO |  |  |  |
| `Wrapper` | `char(64)` | NO |  |  | `mysql` or `mariadb` |
| `Owner` | `char(64)` | NO |  |  |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlservers-table/>

mysql.password\_reuse\_check\_history Table
===========================================

    
**MariaDB starting with [10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/)**The mysql.password\_reuse\_check\_history Table is installed as part of the [password\_reuse\_check plugin](../password_reuse_check-plugin/index), available from [MariaDB 10.7.0](https://mariadb.com/kb/en/mariadb-1070-release-notes/).

 
The `mysql.password_reuse_check_history` table stores old passwords, so that when a user sets a new password, it can be checked for purposes of preventing password reuse.

 It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| hash | binary(64) | NO | PRI | NULL |  |
| time | timestamp | NO | MUL | current\_timestamp() |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlpassword_reuse_check_history-table/>

mysql.table\_stats Table
========================

    The `mysql.table_stats` table is one of three tables storing data used for [Engine-independent table statistics](../engine-independent-table-statistics/index). The others are [mysql.column\_stats](../mysqlcolumn_stats-table/index) and [mysql.index\_stats](../mysqlindex_stats-table/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
The `mysql.table_stats` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `db_name` | `varchar(64)` | NO | PRI | `NULL` | Database the table is in . |
| `table_name` | `varchar(64)` | NO | PRI | `NULL` | Table name. |
| `cardinality` | `bigint(21) unsigned` | YES |  | `NULL` | Number of records in the table. |

 
It is possible to manually update the table. See [Manual updates to statistics tables](../engine-independent-table-statistics/index#manual-updates-to-statistics-tables) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqltable_stats-table/>

About SHOW
==========

    `SHOW` has many forms that provide information about databases, tables, columns, or status information about the server. These include:

 * [SHOW AUTHORS](../show-authors/index)
* [SHOW CHARACTER SET [like\_or\_where]](../show-character-set/index)
* [SHOW COLLATION [like\_or\_where]](../show-collation/index)
* [SHOW [FULL] COLUMNS FROM tbl\_name [FROM db\_name] [like\_or\_where]](../show-columns/index)
* [SHOW CONTRIBUTORS](../show-contributors/index)
* [SHOW CREATE DATABASE db\_name](../show-create-database/index)
* [SHOW CREATE EVENT event\_name](../show-create-event/index)
* [SHOW CREATE PACKAGE package\_name](../show-create-package/index)
* [SHOW CREATE PACKAGE BODY package\_name](../show-create-package-body/index)
* [SHOW CREATE PROCEDURE proc\_name](../show-create-procedure/index)
* [SHOW CREATE TABLE tbl\_name](../show-create-table/index)
* [SHOW CREATE TRIGGER trigger\_name](../show-create-trigger/index)
* [SHOW CREATE VIEW view\_name](../show-create-view/index)
* [SHOW DATABASES [like\_or\_where]](../show-databases/index)
* [SHOW ENGINE engine\_name {STATUS | MUTEX}](../show-engine/index)
* [SHOW [STORAGE] ENGINES](../show-engines/index)
* [SHOW ERRORS [LIMIT [offset,] row\_count]](../show-errors/index)
* [SHOW [FULL] EVENTS](../show-events/index)
* [SHOW FUNCTION CODE func\_name](../show-function-code/index)
* [SHOW FUNCTION STATUS [like\_or\_where]](../show-function-status/index)
* [SHOW GRANTS FOR user](../show-grants/index)
* [SHOW INDEX FROM tbl\_name [FROM db\_name]](../show-index/index)
* [SHOW INNODB STATUS](../show-innodb-status/index)
* [SHOW OPEN TABLES [FROM db\_name] [like\_or\_where]](../show-open-tables/index)
* [SHOW PLUGINS](../show-plugins/index)
* [SHOW PROCEDURE CODE proc\_name](../show-procedure-code/index)
* [SHOW PROCEDURE STATUS [like\_or\_where]](../show-procedure-status/index)
* [SHOW PRIVILEGES](../show-privileges/index)
* [SHOW [FULL] PROCESSLIST](../show-processlist/index)
* [SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]](../show-profile/index)
* [SHOW PROFILES](../show-profiles/index)
* [SHOW [GLOBAL | SESSION] STATUS [like\_or\_where]](../show-status/index)
* [SHOW TABLE STATUS [FROM db\_name] [like\_or\_where]](../show-table-status/index)
* [SHOW TABLES [FROM db\_name] [like\_or\_where]](../show-tables/index)
* [SHOW TRIGGERS [FROM db\_name] [like\_or\_where]](../show-triggers/index)
* [SHOW [GLOBAL | SESSION] VARIABLES [like\_or\_where]](../show-variables/index)
* [SHOW WARNINGS [LIMIT [offset,] row\_count]](../show-warnings/index)

 
```
like_or_where:
    LIKE 'pattern'
  | WHERE expr

```

If the syntax for a given `SHOW` statement includes a `LIKE 'pattern'` part, `'pattern'` is a string that can contain the SQL "`%`" and "`_`" wildcard characters. The pattern is useful for restricting statement output to matching values.

 Several `SHOW` statements also accept a `WHERE` clause that provides more flexibility in specifying which rows to display. See [Extended Show](../extended-show/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-show/>

SHOW INNODB STATUS (removed)
============================

    Syntax
------

 
```
SHOW INNODB STATUS

```

Description
-----------

 This was a deprecated synonym for `[SHOW ENGINE INNODB STATUS](../show-engine/index)`. It was removed in MariaDB and MySQL 5.5.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-innodb-status-removed/>

Obsolete mysql Database Tables
===============================

   Tables that used to be part of the `mysql` system database but are no longer present in a supported version.

  

| Title | Description |
| --- | --- |
|  [mysql.host Table](../mysqlhost-table/index) |  Obsolete/optional table that contained host-level access and privileges.  |
|  [mysql.ndb\_binlog\_index Table](../mysqlndb_binlog_index-table/index) |  Unused by MariaDB, kept until MariaDB 10.0 for MySQL compatibility reasons.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/obsolete-mysql-database-tables/>

SHOW CREATE PACKAGE
===================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
SHOW CREATE PACKAGE  [ db_name . ] package_name

```
 Description
-----------

 The `SHOW CREATE PACKAGE` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 Shows the `CREATE` statement that creates the given package specification.

 Examples
--------

 
```
SHOW CREATE PACKAGE employee_tools\G
*************************** 1. row ***************************
             Package: employee_tools
            sql_mode: PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
      Create Package: CREATE DEFINER="root"@"localhost" PACKAGE "employee_tools" AS
  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
  PROCEDURE raiseSalaryStd(eid INT);
  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [CREATE PACKAGE](../create-package/index)
* [DROP PACKAGE](../drop-package/index)
* [CREATE PACKAGE BODY](../create-package-body/index)
* [SHOW CREATE PACKAGE BODY](../show-create-package-body/index)
* [DROP PACKAGE BODY](../drop-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-package/>

SHOW CREATE PACKAGE BODY
========================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
SHOW CREATE PACKAGE BODY  [ db_name . ] package_name

```
 Description
-----------

 The `SHOW CREATE PACKAGE BODY` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 Shows the `CREATE` statement that creates the given package body (i.e. the implementation).

 Examples
--------

 
```
SHOW CREATE PACKAGE BODY employee_tools\G
*************************** 1. row ***************************
        Package body: employee_tools
            sql_mode: PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER
 Create Package Body: CREATE DEFINER="root"@"localhost" PACKAGE BODY "employee_tools" AS
  
  stdRaiseAmount DECIMAL(10,2):=500;
  
  PROCEDURE log (eid INT, ecmnt TEXT) AS
  BEGIN
    INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);
  END;
  
  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS
    eid INT;
  BEGIN
    INSERT INTO employee (name, salary) VALUES (ename, esalary);
    eid:= last_insert_id();
    log(eid, 'hire ' || ename);
  END;

  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS
    nSalary DECIMAL(10,2);
  BEGIN
    SELECT salary INTO nSalary FROM employee WHERE id=eid;
    log(eid, 'getSalary id=' || eid || ' salary=' || nSalary);
    RETURN nSalary;
  END;

  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS
  BEGIN
    UPDATE employee SET salary=salary+amount WHERE id=eid;
    log(eid, 'raiseSalary id=' || eid || ' amount=' || amount);
  END;

  PROCEDURE raiseSalaryStd(eid INT) AS
  BEGIN
    raiseSalary(eid, stdRaiseAmount);
    log(eid, 'raiseSalaryStd id=' || eid);
  END;

BEGIN  
  log(0, 'Session ' || connection_id() || ' ' || current_user || ' started');
END
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [CREATE PACKAGE](../create-package/index)
* [SHOW CREATE PACKAGE](../show-create-package/index)
* [DROP PACKAGE](../drop-package/index)
* [CREATE PACKAGE BODY](../create-package-body/index)
* [DROP PACKAGE BODY](../drop-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-create-package-body/>

SHOW WSREP\_MEMBERSHIP
======================

    `SHOW WSREP_MEMBERSHIP` is part of the `[WSREP\_INFO](../wsrep_info-plugin/index)` plugin.

 Syntax
------

 
```
SHOW WSREP_MEMBERSHIP

```

Description
-----------

 The `SHOW WSREP_MEMBERSHIP` statement returns [Galera](../galera/index) node cluster membership information. It returns the same information as found in the `[information\_schema.WSREP\_MEMBERSHIP](../information-schema-wsrep_membership-table/index)` table. Only users with the `[SUPER](../grant/index)` privilege can access this information.

 Examples
--------

 
```
SHOW WSREP_MEMBERSHIP;
+-------+--------------------------------------+----------+-----------------+
| Index | Uuid                                 | Name     | Address         |
+-------+--------------------------------------+----------+-----------------+
|     0 | 19058073-8940-11e4-8570-16af7bf8fced | my_node1 | 10.0.2.15:16001 |
|     1 | 19f2b0e0-8942-11e4-9cb8-b39e8ee0b5dd | my_node3 | 10.0.2.15:16003 |
|     2 | d85e62db-8941-11e4-b1ef-4bc9980e476d | my_node2 | 10.0.2.15:16002 |
+-------+--------------------------------------+----------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-wsrep_membership/>

SHOW QUERY\_RESPONSE\_TIME
==========================

    It is possible to use `SHOW QUERY_RESPONSE_TIME` as an alternative for retrieving information from the [QUERY\_RESPONSE\_TIME](../query_response_time-plugin/index) plugin.

 This was introduced as part of the [Information Schema plugin extension](../information-schema-plugins-show-and-flush-statements/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-query_response_time/>

SHOW WSREP\_STATUS
==================

    `SHOW WSREP_STATUS` is part of the `[WSREP\_INFO](../wsrep_info-plugin/index)` plugin.

 Syntax
------

 
```
SHOW WSREP_STATUS

```

Description
-----------

 The `SHOW WSREP_STATUS` statement returns [Galera](../galera/index) node and cluster status information. It returns the same information as found in the `[information\_schema.WSREP\_STATUS](../information-schema-wsrep_status-table/index)` table. Only users with the `[SUPER](../grant/index)` privilege can access this information.

 Examples
--------

 
```
SHOW WSREP_STATUS;
+------------+-------------+----------------+--------------+
| Node_Index | Node_Status | Cluster_Status | Cluster_Size |
+------------+-------------+----------------+--------------+
|          0 | Synced      | Primary        |            3 |
+------------+-------------+----------------+--------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-wsrep_status/>

LOAD XML
========

    Syntax
------

 
```
LOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE [db_name.]tbl_name
    [CHARACTER SET charset_name]
    [ROWS IDENTIFIED BY '<tagname>']
    [IGNORE number {LINES | ROWS}]
    [(column_or_user_var,...)]
    [SET col_name = expr,...]

```

Description
-----------

 The LOAD XML statement reads data from an XML file into a table. The `file_name` must be given as a literal string. The `tagname` in the optional ROWS IDENTIFIED BY clause must also be given as a literal string, and must be surrounded by angle brackets (< and >).

 LOAD XML acts as the complement of running the [mariadb client](../mariadb-command-line-client/index) in XML output mode (that is, starting the client with the --xml option). To write data from a table to an XML file, use a command such as the following one from the system shell:

 
```
shell> mariadb --xml -e 'SELECT * FROM mytable' > file.xml

```

To read the file back into a table, use LOAD XML INFILE. By default, the <row> element is considered to be the equivalent of a database table row; this can be changed using the ROWS IDENTIFIED BY clause.

 This statement supports three different XML formats:

 * Column names as attributes and column values as attribute values:

 
```
<row column1="value1" column2="value2" .../>

```

* Column names as tags and column values as the content of these tags:

 
```
<row>
  <column1>value1</column1>
  <column2>value2</column2>
</row>

```

* Column names are the name attributes of <field> tags, and values are the contents of these tags:

 
```
<row>
  <field name='column1'>value1</field>
  <field name='column2'>value2</field>
</row>

```

 This is the format used by other tools, such as [mariadb-dump](../mariadb-dump/index).

 All 3 formats can be used in the same XML file; the import routine automatically detects the format for each row and interprets it correctly. Tags are matched based on the tag or attribute name and the column name.

 The following clauses work essentially the same way for LOAD XML as they do for LOAD DATA:

 * LOW\_PRIORITY or CONCURRENT
* LOCAL
* REPLACE or IGNORE
* CHARACTER SET
* (column\_or\_user\_var,...)
* SET

 See [LOAD DATA](../load-data-infile/index) for more information about these clauses.

 The IGNORE number LINES or IGNORE number ROWS clause causes the first number rows in the XML file to be skipped. It is analogous to the LOAD DATA statement's IGNORE ... LINES clause.

 If the `[LOW\_PRIORITY](../high_priority-and-low_priority-clauses/index)` keyword is used, insertions are delayed until no other clients are reading from the table. The `CONCURRENT` keyword allows the use of [concurrent inserts](../concurrent-inserts/index). These clauses cannot be specified together.

 This statement activates INSERT [triggers](../triggers/index).

 See Also
--------

 * The [CONNECT](../connect/index) storage engine has an [XML table type](../connect-table-types-data-files/index#xml-table-type).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-xml/>

SHOW PACKAGE STATUS
===================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
SHOW PACKAGE STATUS
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 The `SHOW PACKAGE STATUS` statement returns characteristics of stored package specifications, such as the database, name, type, creator, creation and modification dates, and character set information. A similar statement, `[SHOW PACKAGE BODY STATUS](../show-package-body-status/index)`, displays information about stored package bodies (i.e. implementations).

 The `LIKE` clause, if present, indicates which package names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The [ROUTINES table](../information-schema-routines-table/index) in the INFORMATION\_SCHEMA database contains more detailed information.

 Examples
--------

 
```
SHOW PACKAGE STATUS LIKE 'pkg1'\G
*************************** 1. row ***************************
                  Db: test
                Name: pkg1
                Type: PACKAGE
             Definer: root@localhost
            Modified: 2018-02-27 14:38:15
             Created: 2018-02-27 14:38:15
       Security_type: DEFINER
             Comment: This is my first package
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [SHOW PACKAGE BODY](../show-package-body-status/index)
* [SHOW CREATE PACKAGE](../show-create-package/index)
* [CREATE PACKAGE](../create-package/index)
* [DROP PACKAGE](../drop-package/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-package-status/>

SHOW PACKAGE BODY STATUS
========================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
SHOW PACKAGE BODY STATUS
    [LIKE 'pattern' | WHERE expr]

```
 Description
-----------

 The `SHOW PACKAGE BODY STATUS` statement returns characteristics of stored package bodies (implementations), such as the database, name, type, creator, creation and modification dates, and character set information. A similar statement, `[SHOW PACKAGE STATUS](../show-package-status/index)`, displays information about stored package specifications.

 The `LIKE` clause, if present, indicates which package names to match. The `WHERE` and `LIKE` clauses can be given to select rows using more general conditions, as discussed in [Extended SHOW](../extended-show/index).

 The [ROUTINES table](../information-schema-routines-table/index) in the INFORMATION\_SCHEMA database contains more detailed information.

 Examples
--------

 
```
SHOW PACKAGE BODY STATUS LIKE 'pkg1'\G
*************************** 1. row ***************************
                  Db: test
                Name: pkg1
                Type: PACKAGE BODY
             Definer: root@localhost
            Modified: 2018-02-27 14:44:14
             Created: 2018-02-27 14:44:14
       Security_type: DEFINER
             Comment: This is my first package body
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: latin1_swedish_ci

```

See Also
--------

 * [SHOW PACKAGE STATUS](../show-package-status/index)
* [SHOW CREATE PACKAGE BODY](../show-create-package-body/index)
* [CREATE PACKAGE BODY](../create-package-body/index)
* [DROP PACKAGE BODY](../drop-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-package-body-status/>

Extended Show
=============

     The following `[SHOW](../show/index)` statements can be extended by using a `WHERE` clause and a `LIKE` clause to refine the results:

 * [SHOW CHARACTER SET](../show-character-set/index)
* [SHOW COLLATION](../show-collation/index)
* [SHOW COLUMNS](../show-columns/index)
* [SHOW DATABASES](../show-databases/index)
* [SHOW FUNCTION STATUS](../show-function-status/index)
* [SHOW INDEX](../show-index/index)
* [SHOW OPEN TABLES](../show-open-tables/index)
* [SHOW PACKAGE STATUS](../show-package-status/index)
* [SHOW PACKAGE BODY STATUS](../show-package-body-status/index)
* [SHOW INDEX](../show-index/index)
* [SHOW PROCEDURE STATUS](../show-procedure-status/index)
* [SHOW STATUS](../show-status/index)
* [SHOW TABLE STATUS](../show-table-status/index)
* [SHOW TABLES](../show-tables/index)
* [SHOW TRIGGERS](../show-triggers/index)
* [SHOW VARIABLES](../show-variables/index)

 As with a regular `[SELECT](../select/index)`, the `WHERE` clause can be used for the specific columns returned, and the `[LIKE](../like/index)` clause with the regular wildcards. 

 Examples
--------

 
```
SHOW TABLES;
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
| t1                   |
| view1                |
+----------------------+

```

Showing the tables beginning with *a* only.

 
```
SHOW TABLES WHERE Tables_in_test LIKE 'a%';
+----------------------+
| Tables_in_test       |
+----------------------+
| animal_count         |
| animals              |
| are_the_mooses_loose |
| aria_test2           |
+----------------------+

```

Variables whose name starts with *aria* and with a valued of greater than 8192:

 
```
SHOW VARIABLES WHERE Variable_name LIKE 'aria%' AND Value >8192;
+------------------------------+---------------------+
| Variable_name                | Value               |
+------------------------------+---------------------+
| aria_checkpoint_log_activity | 1048576             |
| aria_log_file_size           | 1073741824          |
| aria_max_sort_file_size      | 9223372036853727232 |
| aria_pagecache_buffer_size   | 134217728           |
| aria_sort_buffer_size        | 134217728           |
+------------------------------+---------------------+

```

Shortcut, just returning variables whose name begins with *aria*.

 
```
SHOW VARIABLES LIKE 'aria%';
+------------------------------------------+---------------------+
| Variable_name                            | Value               |
+------------------------------------------+---------------------+
| aria_block_size                          | 8192                |
| aria_checkpoint_interval                 | 30                  |
| aria_checkpoint_log_activity             | 1048576             |
| aria_force_start_after_recovery_failures | 0                   |
| aria_group_commit                        | none                |
| aria_group_commit_interval               | 0                   |
| aria_log_file_size                       | 1073741824          |
| aria_log_purge_type                      | immediate           |
| aria_max_sort_file_size                  | 9223372036853727232 |
| aria_page_checksum                       | ON                  |
| aria_pagecache_age_threshold             | 300                 |
| aria_pagecache_buffer_size               | 134217728           |
| aria_pagecache_division_limit            | 100                 |
| aria_recover                             | NORMAL              |
| aria_repair_threads                      | 1                   |
| aria_sort_buffer_size                    | 134217728           |
| aria_stats_method                        | nulls_unequal       |
| aria_sync_log_dir                        | NEWFILE             |
| aria_used_for_temp_tables                | ON                  |
+------------------------------------------+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/extended-show/>

SHOW LOCALES
============

    `SHOW LOCALES` was introduced as part of the [Information Schema plugin extension](../information-schema-plugins-show-and-flush-statements/index).

 `SHOW LOCALES` is used to return `[locales](../server-locale/index)` information as part of the [Locales](../locales-plugin/index) plugin. While the `[information\_schema.LOCALES](../information-schema-locales-table/index)` table has 8 columns, the `SHOW LOCALES` statement will only display 4 of them:

 Example
-------

 
```
SHOW LOCALES;
+-----+-------+-------------------------------------+------------------------+
| Id  | Name  | Description                         | Error_Message_Language |
+-----+-------+-------------------------------------+------------------------+
|   0 | en_US | English - United States             | english                |
|   1 | en_GB | English - United Kingdom            | english                |
|   2 | ja_JP | Japanese - Japan                    | japanese               |
|   3 | sv_SE | Swedish - Sweden                    | swedish                |
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/show-locales/>

UNION
=====

    `UNION` is used to combine the results from multiple [SELECT](../select/index) statements into a single result set.

 Syntax
------

 
```
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

```
 Description
-----------

 `UNION` is used to combine the results from multiple [SELECT](../select/index) statements into a single result set.

 The column names from the first `SELECT` statement are used as the column names for the results returned. Selected columns listed in corresponding positions of each SELECT statement should have the same data type. (For example, the first column selected by the first statement should have the same type as the first column selected by the other statements.)

 If they don't, the type and length of the columns in the result take into account the values returned by all of the SELECTs, so there is no need for explicit casting. Note that currently this is not the case for [recursive CTEs](../recursive-common-table-expressions-overview/index) - see [MDEV-12325](https://jira.mariadb.org/browse/MDEV-12325).

 Table names can be specified as `db_name`.`tbl_name`. This permits writing `UNION`s which involve multiple databases. See [Identifier Qualifiers](../identifier-qualifiers/index) for syntax details.

 UNION queries cannot be used with [aggregate functions](../functions-and-modifiers-for-use-with-group-by/index).

 `EXCEPT` and `UNION` have the same operation precedence and `INTERSECT` has a higher precedence, unless [running in Oracle mode](../sql_modeoracle/index), in which case all three have the same precedence.

 ### ALL/DISTINCT

 The `ALL` keyword causes duplicate rows to be preserved. The `DISTINCT` keyword (the default if the keyword is omitted) causes duplicate rows to be removed by the results.

 UNION ALL and UNION DISTINCT can both be present in a query. In this case, UNION DISTINCT will override any UNION ALLs to its left.

 
**MariaDB starting with [10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/)**Until [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), all `UNION ALL` statements required the server to create a temporary table. Since [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/), the server can in most cases execute `UNION ALL` without creating a temporary table, improving performance (see [MDEV-334](https://jira.mariadb.org/browse/MDEV-334)).

 
### ORDER BY and LIMIT

 Individual SELECTs can contain their own [ORDER BY](../order-by/index) and [LIMIT](../limit/index) clauses. In this case, the individual queries need to be wrapped between parentheses. However, this does not affect the order of the UNION, so they only are useful to limit the record read by one SELECT.

 The UNION can have global [ORDER BY](../order-by/index) and [LIMIT](../limit/index) clauses, which affect the whole resultset. If the columns retrieved by individual SELECT statements have an alias (AS), the ORDER BY must use that alias, not the real column names.

 ### HIGH\_PRIORITY

 Specifying a query as [HIGH\_PRIORITY](../select/index#high-priority) will not work inside a UNION. If applied to the first SELECT, it will be ignored. Applying to a later SELECT results in a syntax error:

 
```
ERROR 1234 (42000): Incorrect usage/placement of 'HIGH_PRIORITY'

```

### SELECT ... INTO ...

 Individual SELECTs cannot be written [INTO DUMPFILE](../select-into-dumpfile/index) or [INTO OUTFILE](../select-into-outfile/index). If the last SELECT statement specifies INTO DUMPFILE or INTO OUTFILE, the entire result of the UNION will be written. Placing the clause after any other SELECT will result in a syntax error.

 If the result is a single row, [SELECT ... INTO @var\_name](../select-into-variable/index) can also be used.   
   


 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**### Parentheses

 From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), parentheses can be used to specify precedence. Before this, a syntax error would be returned.

 
Examples
--------

 `UNION` between tables having different column names:

 
```
(SELECT e_name AS name, email FROM employees)
UNION
(SELECT c_name AS name, email FROM customers);

```

Specifying the `UNION`'s global order and limiting total rows:

 
```
(SELECT name, email FROM employees)
UNION
(SELECT name, email FROM customers)
ORDER BY name LIMIT 10;

```

Adding a constant row:

 
```
(SELECT 'John Doe' AS name, 'john.doe@example.net' AS email)
UNION
(SELECT name, email FROM customers);

```

Differing types:

 
```
SELECT CAST('x' AS CHAR(1)) UNION SELECT REPEAT('y',4);
+----------------------+
| CAST('x' AS CHAR(1)) |
+----------------------+
| x                    |
| yyyy                 |
+----------------------+

```

Returning the results in order of each individual SELECT by use of a sort column:

 
```
(SELECT 1 AS sort_column, e_name AS name, email FROM employees)
UNION
(SELECT 2, c_name AS name, email FROM customers) ORDER BY sort_column;

```

Difference between UNION, [EXCEPT](../except/index) and [INTERSECT](../intersect/index). `INTERSECT ALL` and `EXCEPT ALL` are available from [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
```
CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

```

Parentheses for specifying precedence, from [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)

 
```
CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) INTERSECT (SELECT c FROM t3);
+------+
| a    |
+------+
|    1 |
|    6 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) INTERSECT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    6 |
+------+

```

See Also
--------

 * [SELECT](../select/index)
* [EXCEPT](../except/index)
* [INTERSECT](../intersect/index)
* [Recursive Common Table Expressions Overview](../recursive-common-table-expressions-overview/index)
* [Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL](https://www.youtube.com/watch?v=UNi-fVSpRm0) (video tutorial)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/union/>

Basic SQL Debugging
===================

    Designing Queries
-----------------

 Following a few conventions makes finding errors in queries a lot easier, especially when you ask for help from people who might know SQL, but know nothing about your particular schema. A query easy to read is a query easy to debug. Use whitespace to group clauses within the query. Choose good table and field aliases to add clarity, not confusion. Choose the syntax that supports the query's meaning. 

 ### Using Whitespace

 A query hard to read is a query hard to debug. White space is free. New lines and indentation make queries easy to read, particularly when constructing a query inside a scripting language, where variables are interspersed throughout the query.

 There is a syntax error in the following. How fast can you find it?

 
```
SELECT u.id, u.name, alliance.ally FROM users u JOIN alliance ON
(u.id=alliance.userId) JOIN team ON (alliance.teamId=team.teamId
WHERE team.teamName='Legionnaires' AND u.online=1 AND ((u.subscription='paid'
AND u.paymentStatus='current') OR u.subscription='free') ORDER BY u.name;

```

Here's the same query, with correct use of whitespace. Can you find the error faster?

 
```
SELECT
    u.id
    , u.name
    , alliance.ally
FROM
    users u
    JOIN alliance ON (u.id = alliance.userId)
    JOIN team ON (alliance.teamId = team.teamId
WHERE
    team.teamName = 'Legionnaires'
    AND u.online = 1
    AND (
        (u.subscription = 'paid' AND u.paymentStatus = 'current')
        OR
        u.subscription = 'free'
    )
ORDER BY
    u.name;

```

Even if you don't know SQL, you might still have caught the missing ')' following team.teamId.

 The exact formatting style you use isn't so important. You might like commas in the select list to follow expressions, rather than precede them. You might indent with tabs or with spaces. Adherence to some particular form is not important. Legibility is the only goal.

 ### Table and Field Aliases

 Aliases allow you to rename tables and fields for use within a query. This can be handy when the original names are very long, and is required for self joins and certain subqueries. However, poorly chosen aliases can make a query harder to debug, rather than easier. Aliases should reflect the original table name, not an arbitrary string.

 Bad:

 
```
SELECT *
FROM
    financial_reportQ_1 AS a
    JOIN sales_renderings AS b ON (a.salesGroup = b.groupId)
    JOIN sales_agents AS c ON (b.groupId = c.group)
WHERE
    b.totalSales > 10000
    AND c.id != a.clientId

```

As the list of joined tables and the WHERE clause grow, it becomes necessary to repeatedly look back to the top of the query to see to which table any given alias refers.

 Better:

 
```
SELECT *
FROM
    financial_report_Q_1 AS frq1
    JOIN sales_renderings AS sr ON (frq1.salesGroup = sr.groupId)
    JOIN sales_agents AS sa ON (sr.groupId = sa.group)
WHERE
    sr.totalSales > 10000
    AND sa.id != frq1.clientId

```

Each alias is just a little longer, but the table initials give enough clues that anyone familiar with the database only need see the full table name once, and can generally remember which table goes with which alias while reading the rest of the query.

 ### Placing JOIN conditions

 The manual warns against using the JOIN condition (that is, the ON clause) for restricting rows. Some queries, particularly those using implicit joins, take the opposite extreme - all join conditions are moved to the WHERE clause. In consequence, the table relationships are mixed with the business logic.

 Bad:

 
```
SELECT *
FROM
    family,
    relationships
WHERE
    family.personId = relationships.personId
    AND relationships.relation = 'father'

```

Without digging through the WHERE clause, it is impossible to say what links the two tables.

 Better:

 
```
SELECT *
FROM
    family
    JOIN relationships ON (family.personId = relationships.personId)
WHERE
    relationships.relation = 'father'

```

The relation between the tables is immediately obvious. The WHERE clause is left to limit rows in the result set.

 Compliance with such a restriction negates the use of the comma operator to join tables. It is a small price to pay. Queries should be written using the explicit JOIN keyword anyway, and the two should never be mixed (unless you like rewriting all your queries every time a new version changes operator precedence).

 Finding Syntax Errors
---------------------

 Syntax errors are among the easiest problems to solve. MariaDB provides an error message showing the exact point where the parser became confused. Check the query, including a few words before the phrase shown in the error message. Most syntax and parsing errors are obvious after a second look, but some are more elusive, especially when the error text seems empty, points to a valid keyword, or seems to error on syntax that appears exactly correct.

 ### Interpreting the Empty Error

 Most syntax errors are easy to interpret. The error generally details the exact source of the trouble. A careful look at the query, with the error message in mind, often reveals an obvious mistake, such as mispelled field names, a missing 'AND', or an extra closing parenthesis. Sometimes the error is a little less helpful. A frequent, less-than-helpful message:

 
```
ERROR 1064: You have an error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near ' ' at line 1

```

The empty ' ' can be disheartening. Clearly there is an error, but where? A good place to look is at the end of the query. The ' ' suggests that the parser reached the end of the statement while still expecting some syntax token to appear.

 Check for missing closers, such as ' and ):

 
```
SELECT * FROM someTable WHERE field = 'value

```

Look for incomplete clauses, often indicated by an exposed comma:

 
```
SELECT * FROM someTable WHERE field = 1 GROUP BY id,

```

### Checking for keywords

 MariaDB allows table and field names and aliases that are also [reserved words](../reserved-words/index). To prevent ambiguity, such names must be enclosed in backticks (`):

 
```
SELECT * FROM actionTable WHERE `DELETE` = 1;

```

If the syntax error is shown near one of your identifiers, check if it appears on the [reserved word list](../reserved-words/index).

 A text editor with color highlighting for SQL syntax helps to find these errors. When you enter a field name, and it shows up in the same color as the SELECT keyword, you know something is amiss. Some common culprits:

 * **DESC** is a common abbreviation for "description" fields. It means "descending" in a MariaDB **ORDER** clause.
* **DATE**, **TIME**, and **TIMESTAMP** are all common field names. They are also field types.
* **ORDER** appears in sales applications. MariaDB uses it to specify sorting for results.

 Some keywords are so common that MariaDB makes a special allowance to use them unquoted. My advice: don't. If it's a keyword, quote it.

 ### Version specific syntax

 As MariaDB adds new features, the syntax must change to support them. Most of the time, old syntax will work in newer versions of MariaDB. One notable exception is the change in precedence of the comma operator relative to the JOIN keyword in version 5.0. A query that used to work, such as

 
```
SELECT * FROM a, b JOIN c ON a.x = c.x;

```

will now fail.

 More common, however, is an attempt to use new syntax in an old version. Web hosting companies are notoriously slow to upgrade MariaDB, and you may find yourself using a version several years out of date. The result can be very frustrating when a query that executes flawlessly on your own workstation, running a recent installation, fails completely in your production environment.

 This query fails in any version of MySQL prior to 4.1, when subqueries were added to the server:

 
```
SELECT * FROM someTable WHERE someId IN (SELECT id FROM someLookupTable);

```

This query fails in some early versions of MySQL, because the JOIN syntax did not originally allow an ON clause:

 
```
SELECT * FROM tableA JOIN tableB ON tableA.x = tableB.y;

```

Always check the installed version of MariaDB, and read the section of the manual relevant for that version. The manual usually indicates exactly when particular syntax became available for use.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Basic_Debugging> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/basic-sql-debugging/>

InnoDB DYNAMIC Row Format
=========================

    `DYNAMIC` is the default InnoDB row format.

 The `DYNAMIC` row format is similar to the `COMPACT` row format, but tables using the `DYNAMIC` row format can store even more data on overflow pages than tables using the `COMPACT` row format. This results in more efficient data storage than tables using the `COMPACT` row format, especially for tables containing columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types. However, InnoDB tables using the `COMPRESSED` row format are more efficient.

 The `DYNAMIC` row format was originally introduced in [MariaDB 5.5](../what-is-mariadb-55/index).

 Using the DYNAMIC Row Format
----------------------------

 
**MariaDB starting with [10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)**In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, the default row format is `DYNAMIC`, as long as the [innodb\_default\_row\_format](../innodb-system-variables/index#innodb_default_row_format) system variable has not been modified. Therefore, in these versions, the easiest way to create an InnoDB table that uses the `DYNAMIC` row format is by **not** setting the [ROW\_FORMAT](../create-table/index#row_format) table option at all in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 It is recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this row format.

 For example:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_default_row_format='dynamic';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB;

```



**MariaDB until [10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)**In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, the easiest way to create an InnoDB table that uses the `DYNAMIC` row format is by setting the [ROW\_FORMAT](../create-table/index#row_format) table option to to `DYNAMIC` in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 It is recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this row format.

 The `DYNAMIC` row format is only supported by the `Barracuda` [file format](../xtradbinnodb-file-format/index). As a side effect, in [MariaDB 10.1](../what-is-mariadb-101/index) and before, the `DYNAMIC` row format is only supported if the [InnoDB file format](../xtradbinnodb-file-format/index) is `Barracuda`. Therefore, the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable must be set to `Barracuda` to use these row formats in those versions.

 In [MariaDB 10.1](../what-is-mariadb-101/index) and before, the `DYNAMIC` row format is also only supported if the table is in a [file per-table](../innodb-file-per-table-tablespaces/index) tablespace. Therefore, the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable must be set to `ON` to use this row format in those versions.

 For example:

 
```
SET SESSION innodb_strict_mode=ON;

SET GLOBAL innodb_file_per_table=ON;

SET GLOBAL innodb_file_format='Barracuda';

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

```


Index Prefixes with the DYNAMIC Row Format
------------------------------------------

 The `DYNAMIC` row format supports index prefixes up to 3072 bytes. In [MariaDB 10.2](../what-is-mariadb-102/index) and before, the [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) system variable is used to configure the maximum index prefix length. In these versions, if [innodb\_large\_prefix](../innodb-system-variables/index#innodb_large_prefix) is set to `ON`, then the maximum prefix length is 3072 bytes, and if it is set to `OFF`, then the maximum prefix length is 767 bytes.

 Overflow Pages with the DYNAMIC Row Format
------------------------------------------

 All InnoDB row formats can store certain kinds of data in overflow pages. This allows for the maximum row size of an InnoDB table to be larger than the maximum amount of data that can be stored in the row's main data page. See [Maximum Row Size](#maximum-row-size) for more information about the other factors that can contribute to the maximum row size for InnoDB tables.

 In the `DYNAMIC` row format variable-length columns, such as columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types, can be completely stored in overflow pages.

 InnoDB only considers using overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If the row size is greater than this, then InnoDB chooses variable-length columns to be stored on overflow pages until the row size is less than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size).

 For [BLOB](../blob/index) and [TEXT](../text/index) columns, only values longer than 40 bytes are considered for storage on overflow pages. For [VARBINARY](../varbinary/index) and [VARCHAR](../varchar/index) columns, only values longer than 255 bytes are considered for storage on overflow pages. Bytes that are stored to track a value's length do not count towards these limits. These limits are only based on the length of the actual column's data.

 These limits differ from the limits for the `COMPACT` row format, where the limit is 767 bytes for all types.

 Fixed-length columns greater than 767 bytes are encoded as variable-length columns, so they can also be stored in overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). Even though a column using the [CHAR](../char/index) data type can hold at most 255 characters, a [CHAR](../char/index) column can still exceed 767 bytes in some cases. For example, a `char(255)` column can exceed 767 bytes if the [character set](../character-sets/index) is `utf8mb4`.

 If a column is chosen to be stored on overflow pages, then the entire value of the column is stored on overflow pages, and only a 20-byte pointer to the column's first overflow page is stored on the main page. Each overflow page is the size of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If a column is too large to be stored on a single overflow page, then it is stored on multiple overflow pages. Each overflow page contains part of the data and a 20-byte pointer to the next overflow page, if a next page exists.

 This behavior differs from the behavior of the `COMPACT` row format, which always stores the column prefix on the main page. This allows tables using the `DYNAMIC` row format to contain a high number of columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-dynamic-row-format/>

More Advanced Joins
===================

     This article is a follow up to the [Introduction to JOINs](../introduction-to-joins/index) page. If you're just getting started with JOINs, go through that page first and then come back here.

 The Employee Database
---------------------

 Let us begin by using an example employee database of a fairly small family business, which does not anticipate expanding in the future.

 First, we create the table that will hold all of the employees and their contact information:

 
```
CREATE TABLE `Employees` (
  `ID` TINYINT(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `First_Name` VARCHAR(25) NOT NULL,
  `Last_Name` VARCHAR(25) NOT NULL,
  `Position` VARCHAR(25) NOT NULL,
  `Home_Address` VARCHAR(50) NOT NULL,
  `Home_Phone` VARCHAR(12) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM;

```

Next, we add a few employees to the table:

 
```
INSERT INTO `Employees` (`First_Name`, `Last_Name`, `Position`, `Home_Address`, `Home_Phone`)
  VALUES
  ('Mustapha', 'Mond', 'Chief Executive Officer', '692 Promiscuous Plaza', '326-555-3492'),
  ('Henry', 'Foster', 'Store Manager', '314 Savage Circle', '326-555-3847'),
  ('Bernard', 'Marx', 'Cashier', '1240 Ambient Avenue', '326-555-8456'),
  ('Lenina', 'Crowne', 'Cashier', '281 Bumblepuppy Boulevard', '328-555-2349'),
  ('Fanny', 'Crowne', 'Restocker', '1023 Bokanovsky Lane', '326-555-6329'),
  ('Helmholtz', 'Watson', 'Janitor', '944 Soma Court', '329-555-2478'); 

```

Now, we create a second table, containing the hours which each employee clocked in and out during the week:

 
```
CREATE TABLE `Hours` (
  `ID` TINYINT(3) UNSIGNED NOT NULL,
  `Clock_In` DATETIME NOT NULL,
  `Clock_Out` DATETIME NOT NULL
) ENGINE=MyISAM;

```

Finally, although it is a lot of information, we add a full week of hours for each of the employees into the second table that we created:

 
```
INSERT INTO `Hours`
  VALUES
  ('1', '2005-08-08 07:00:42', '2005-08-08 17:01:36'),
  ('1', '2005-08-09 07:01:34', '2005-08-09 17:10:11'),
  ('1', '2005-08-10 06:59:56', '2005-08-10 17:09:29'),
  ('1', '2005-08-11 07:00:17', '2005-08-11 17:00:47'),
  ('1', '2005-08-12 07:02:29', '2005-08-12 16:59:12'),
  ('2', '2005-08-08 07:00:25', '2005-08-08 17:03:13'),
  ('2', '2005-08-09 07:00:57', '2005-08-09 17:05:09'),
  ('2', '2005-08-10 06:58:43', '2005-08-10 16:58:24'),
  ('2', '2005-08-11 07:01:58', '2005-08-11 17:00:45'),
  ('2', '2005-08-12 07:02:12', '2005-08-12 16:58:57'),
  ('3', '2005-08-08 07:00:12', '2005-08-08 17:01:32'),
  ('3', '2005-08-09 07:01:10', '2005-08-09 17:00:26'),
  ('3', '2005-08-10 06:59:53', '2005-08-10 17:02:53'),
  ('3', '2005-08-11 07:01:15', '2005-08-11 17:04:23'),
  ('3', '2005-08-12 07:00:51', '2005-08-12 16:57:52'),
  ('4', '2005-08-08 06:54:37', '2005-08-08 17:01:23'),
  ('4', '2005-08-09 06:58:23', '2005-08-09 17:00:54'),
  ('4', '2005-08-10 06:59:14', '2005-08-10 17:00:12'),
  ('4', '2005-08-11 07:00:49', '2005-08-11 17:00:34'),
  ('4', '2005-08-12 07:01:09', '2005-08-12 16:58:29'),
  ('5', '2005-08-08 07:00:04', '2005-08-08 17:01:43'),
  ('5', '2005-08-09 07:02:12', '2005-08-09 17:02:13'),
  ('5', '2005-08-10 06:59:39', '2005-08-10 17:03:37'),
  ('5', '2005-08-11 07:01:26', '2005-08-11 17:00:03'),
  ('5', '2005-08-12 07:02:15', '2005-08-12 16:59:02'),
  ('6', '2005-08-08 07:00:12', '2005-08-08 17:01:02'),
  ('6', '2005-08-09 07:03:44', '2005-08-09 17:00:00'),
  ('6', '2005-08-10 06:54:19', '2005-08-10 17:03:31'),
  ('6', '2005-08-11 07:00:05', '2005-08-11 17:02:57'),
  ('6', '2005-08-12 07:02:07', '2005-08-12 16:58:23');

```

Working with the Employee Database
----------------------------------

 Now that we have a cleanly structured database to work with, let us begin this tutorial by stepping up one notch from the last tutorial and filtering our information a little.

 ### Filtering by Name

 Earlier in the week, an anonymous employee reported that Helmholtz came into work almost four minutes late; to verify this, we will begin our investigation by filtering out employees whose first names are "Helmholtz":

 
```
SELECT
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`
FROM `Employees`
INNER JOIN `Hours` ON `Employees`.`ID` = `Hours`.`ID`
WHERE `Employees`.`First_Name` = 'Helmholtz';

```

The result:

 
```
+------------+-----------+---------------------+---------------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           |
+------------+-----------+---------------------+---------------------+
| Helmholtz  | Watson    | 2005-08-08 07:00:12 | 2005-08-08 17:01:02 |
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |
| Helmholtz  | Watson    | 2005-08-10 06:54:19 | 2005-08-10 17:03:31 |
| Helmholtz  | Watson    | 2005-08-11 07:00:05 | 2005-08-11 17:02:57 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |
+------------+-----------+---------------------+---------------------+
5 rows in set (0.00 sec)

```

This is obviously more information than we care to trudge through, considering we only care about when he arrived past 7:00:59 on any given day within this week; thus, we need to add a couple more conditions to our WHERE clause.

 ### Filtering by Name, Date and Time

 In the following example, we will filter out all of the times which Helmholtz clocked in that were before 7:01:00 and during the work week that lasted from the 8th to the 12th of August:

 
```
SELECT
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`
FROM `Employees`
INNER JOIN `Hours` ON `Employees`.`ID` = `Hours`.`ID`
WHERE `Employees`.`First_Name` = 'Helmholtz'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') >= '2005-08-08'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%Y-%m-%d') <= '2005-08-12'
AND DATE_FORMAT(`Hours`.`Clock_In`, '%H:%i:%S') > '07:00:59';

```

The result:

 
```
+------------+-----------+---------------------+---------------------+
| First_Name | Last_Name | Clock_In            | Clock_Out           |
+------------+-----------+---------------------+---------------------+
| Helmholtz  | Watson    | 2005-08-09 07:03:44 | 2005-08-09 17:00:00 |
| Helmholtz  | Watson    | 2005-08-12 07:02:07 | 2005-08-12 16:58:23 |
+------------+-----------+---------------------+---------------------+
2 rows in set (0.00 sec)

```

We have now, by merely adding a few more conditions, eliminated all of the irrelevant information; Helmholtz was late to work on the 9th and the 12th of August.

 ### Displaying Total Work Hours per Day

 Suppose you would like toâ€”based on the information stored in both of our tables in the employee databaseâ€”develop a quick list of the total hours each employee has worked for each day recorded; a simple way to estimate the time each employee worked per day is exemplified below:

 
```
SELECT
  `Employees`.`ID`,
  `Employees`.`First_Name`,
  `Employees`.`Last_Name`,
  `Hours`.`Clock_In`,
  `Hours`.`Clock_Out`,
DATE_FORMAT(`Hours`.`Clock_Out`, '%T')-DATE_FORMAT(`Hours`.`Clock_In`, '%T') AS 'Total_Hours'
FROM `Employees` INNER JOIN `Hours` ON `Employees`.`ID` = `Hours`.`ID`;

```

The result (limited by 10):

 
```
+----+------------+-----------+---------------------+---------------------+-------------+
| ID | First_Name | Last_Name | Clock_In            | Clock_Out           | Total_Hours |
+----+------------+-----------+---------------------+---------------------+-------------+
|  1 | Mustapha   | Mond      | 2005-08-08 07:00:42 | 2005-08-08 17:01:36 |          10 |
|  1 | Mustapha   | Mond      | 2005-08-09 07:01:34 | 2005-08-09 17:10:11 |          10 |
|  1 | Mustapha   | Mond      | 2005-08-10 06:59:56 | 2005-08-10 17:09:29 |          11 |
|  1 | Mustapha   | Mond      | 2005-08-11 07:00:17 | 2005-08-11 17:00:47 |          10 |
|  1 | Mustapha   | Mond      | 2005-08-12 07:02:29 | 2005-08-12 16:59:12 |           9 |
|  2 | Henry      | Foster    | 2005-08-08 07:00:25 | 2005-08-08 17:03:13 |          10 |
|  2 | Henry      | Foster    | 2005-08-09 07:00:57 | 2005-08-09 17:05:09 |          10 |
|  2 | Henry      | Foster    | 2005-08-10 06:58:43 | 2005-08-10 16:58:24 |          10 |
|  2 | Henry      | Foster    | 2005-08-11 07:01:58 | 2005-08-11 17:00:45 |          10 |
|  2 | Henry      | Foster    | 2005-08-12 07:02:12 | 2005-08-12 16:58:57 |           9 |
+----+------------+-----------+---------------------+---------------------+-------------+
10 rows in set (0.00 sec)

```

See Also
--------

 * [Introduction to JOINs](../introduction-to-joins/index)

 
*The first version of this article was copied, with permission, from <http://hashmysql.org/wiki/More_Advanced_Joins> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/more-advanced-joins/>

Database Normalization
=======================

   This section introduces you to a powerful tool for designing databases: normalization.

  

| Title | Description |
| --- | --- |
|  [Database Normalization Overview](../database-normalization-overview/index) |  A sample system going through the process of normalization  |
|  [Database Normalization: 1st Normal Form](../database-normalization-1st-normal-form/index) |  Moving from unnormalized to 1st normal form  |
|  [Database Normalization: 2nd Normal Form](../database-normalization-2nd-normal-form/index) |  From 1st to 2nd normal form  |
|  [Database Normalization: 3rd Normal Form](../database-normalization-3rd-normal-form/index) |  From 2nd to 3rd normal form  |
|  [Database Normalization: Boyce-Codd Normal Form](../database-normalization-boyce-codd-normal-form/index) |  Beyond 3rd normal form with Boyce-Codd normal form  |
|  [Database Normalization: 4th Normal Form](../database-normalization-4th-normal-form/index) |  Beyond Boyce-Codd normal form with 4th normal form  |
|  [Database Normalization: 5th Normal Form and Beyond](../database-normalization-5th-normal-form-and-beyond/index) |  Normal forms beyond 4th are mainly of academic interest  |
|  [Understanding Denormalization](../understanding-denormalization/index) |  Denormalization is the process of reversing the transformations made during...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization/>

Joining Tables with JOIN Clauses
================================

    In the absence of a more tutorial-level document, here is a simple example of three basic JOIN types, which you can experiment with in order to see what the different joins accomplish:

 
```
CREATE TABLE t1 ( a INT );
CREATE TABLE t2 ( b INT );
INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (2), (4);
SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.b;
SELECT * FROM t1 CROSS JOIN t2;
SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b;
SELECT * FROM t2 LEFT JOIN t1 ON t1.a = t2.b;

```

The first two SELECTs are (unfortunately) commonly written with an older form:

 
```
SELECT * FROM t1, t2 WHERE t1.a = t2.b;
SELECT * FROM t1, t2;

```

What you can see from this is that an **INNER JOIN** produces a result set containing only rows that have a match, in both tables (t1 and t2), for the specified join condition(s).

 A **CROSS JOIN** produces a result set in which every row in each table is joined to every row in the other table; this is also called a **cartesian product**. In MariaDB the CROSS keyword can be omitted, as it does nothing. Any JOIN without an ON clause is a CROSS JOIN.

 The **LEFT JOIN** is an **outer join**, which produces a result set with all rows from the table on the "left" (t1); the values for the columns in the other table (t2) depend on whether or not a match was found. If no match is found, all columns from that table are set to NULL for that row.

 The **RIGHT JOIN** is similar to the LEFT JOIN, though its resultset contains all rows from the right table, and the left table's columns will be filled with NULLs when needed.

 JOINs can be concatenated to read results from three or more tables.

 Here is the output of the various SELECT statements listed above:

 
```
SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.b;
------ ------ 
| a    | b    |
------ ------ 
|    2 |    2 |
------ ------ 
1 row in set (0.00 sec)


SELECT * FROM t1 CROSS JOIN t2;
------ ------ 
| a    | b    |
------ ------ 
|    1 |    2 |
|    2 |    2 |
|    3 |    2 |
|    1 |    4 |
|    2 |    4 |
|    3 |    4 |
------ ------ 
6 rows in set (0.00 sec)


SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b;
------ ------ 
| a    | b    |
------ ------ 
|    1 | NULL |
|    2 |    2 |
|    3 | NULL |
------ ------ 
3 rows in set (0.00 sec)


SELECT * FROM t2 LEFT JOIN t1 ON t1.a = t2.b;
------ ------ 
| b    | a    |
------ ------ 
|    2 |    2 |
|    4 | NULL |
------ ------ 
2 rows in set (0.00 sec)

```

That should give you a bit more understanding of how JOINS work!

 Other References
----------------

 * [JOINs Tutorial with Examples](https://blog.devart.com/mysql-joins-tutorial-with-examples.html)
* [How to write complex queries](https://blog.devart.com/how-to-write-complex-mysql-queries.html)

 See Also
--------

 * [More Advanced JOINs](../more-advanced-joins/index)
* [Comma vs JOIN](../comma-vs-join/index)
* <http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.shtml> - Nice tutorial. Part 5 covers joins.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Introduction_to_Joins> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/joining-tables-with-join-clauses/>

Database Theory
================

   Just as perhaps we take movie special effects for granted until we see what state of the art was in previous eras, so we can't fully appreciate the power of relational databases without seeing what preceded them.

 Relational databases allow any table to relate to any other table through means of common fields. It is a highly flexible system, and most modern databases are relational.

  

| Title | Description |
| --- | --- |
|  [Introduction to Relational Databases](../introduction-to-relational-databases/index) |  Brief introduction to the concept of a relational database.  |
|  [Exploring Early Database Models](../exploring-early-database-models/index) |  Before relational databases there were a number of other models  |
|  [Understanding the Hierarchical Database Model](../understanding-the-hierarchical-database-model/index) |  The earliest model was the hierarchical database model, resembling an upside-down tree.  |
|  [Understanding the Network Database Model](../understanding-the-network-database-model/index) |  A progression from the hierarchical model designed to solve some of its problems  |
|  [Understanding the Relational Database Model](../understanding-the-relational-database-model/index) |  The relational database model was a huge leap forward from the network data...  |
|  [Relational Databases: Basic Terms](../relational-databases-basic-terms/index) |  The relational database model uses certain terms to describe its components  |
|  [Relational Databases: Table Keys](../relational-databases-table-keys/index) |  A key, or index, unlocks access to the tables  |
|  [Relational Databases: Foreign Keys](../relational-databases-foreign-keys/index) |  Foreign keys are the primary key in a foreign table  |
|  [Relational Databases: Views](../relational-databases-views/index) |  Views are virtual tables  |
|  [Database Design](../database-design/index) |  Articles about the database design process  |
|  [Database Normalization](../database-normalization/index) |  Normalization is a powerful tool for designing databases  |
|  [ACID: Concurrency Control with Transactions](../acid-concurrency-control-with-transactions/index) |  Ensuring data integrity.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-theory/>

Automating MariaDB Tasks with Events
====================================

    MariaDB has an event scheduler that can be used to automate tasks, making them run at regular intervals of time. This page is about using events for [automation](../automated-mariadb-deployment-and-administration/index). For more information about events themselves, and how to work with them, see [event scheduler](../event-scheduler/index).

 Pros and Cons of Using Events for Automation
--------------------------------------------

 Events can be compared to Unix cron jobs or Windows scheduled tasks. MariaDB events have at least the following benefits compared to those tools:

 * Events are system-independent. The same code can run on any system.
* Events are written in procedural SQL. There is no need to install other languages or libraries.
* If you use [user-defined functions](../user-defined-functions/index), you can still take advantage of them in your events.
* Events run in MariaDB. An implication, for example, is that the results of queries remain in MariaDB itself and are not sent to a client. This means that network glitches don't affect events, there is no overhead due to data roundtrip, and therefore locks are held for a shorter time.

 Some drawbacks of using events are the following:

 * Events can only perform tasks that can be developed in SQL. So, for example, it is not possible to send alerts. Access to files or remote databases is limited.
* The event scheduler runs as a single thread. If any event is supposed to start while another event is running, its execution will be skipped. It cannot be just postponed. This can be a big problem when automating a number of tasks that should run in a limited time range. But this is fine when running a limited number of tasks that may occasionally be skipped without remarkable consequences.
* For more events limitations, see [Event Limitations](../event-limitations/index).

 In many cases you may prefer to develop scripts in an external programming language. However, you should know that simple tasks consisting of a few queries can easily be implemented as events.

 Good Practices
--------------

 When using events to automate tasks, there are good practices one may want to follow.

 Move your SQL code in a stored procedure. All the event will do is to call a stored procedures. Several events may call the same stored procedure, maybe with different parameters. The procedure may also be called manually, if necessary. This will avoid code duplication. This will separate the logic from the schedule, making it possible to change an event without a risk of making changes to the logic, and the other way around.

 Just like cron jobs, events should log whether if they succeed or not. Logging debug messages may also be useful for non-trivial events. This information can be logged into a dedicated table. The contents of the table can be monitored by a monitoring tool like Grafana. This allows to visualize in a dashboard the status of events, and send alerts in case of a failure.

 Examples
--------

 Some examples of tasks that could easily be automated with events:

 * Copying data from a remote table to a local table by night, using the [CONNECT](../connect/index) storage engine. This can be a good idea if many rows need be copied, because data won't be sent to an external client.
* Periodically delete historical data. For example, rows that are older than 5 years. Nothing prevents us from doing this with an external script, but probably this wouldn't add any value.
* Periodically delete invalid rows. In an e-commerce, they could be abandoned carts. In a messaging system, they could be messages to users that don't exist anymore.
* Add a new [partition](../partitioning-tables/index) to a table and drop the oldest one (partition rotation).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/automating-mariadb-tasks-with-events/>

A MariaDB Primer
================

     This primer is designed to teach you the basics of getting information into and out of an existing MariaDB database using the [mariadb](../mariadb-command-line-client/index) command-line client program. It's not a complete reference and will not touch on any advanced topics. It is just a quick jump-start into using MariaDB.

 #### Logging into MariaDB

 Log into your MariaDB server from the command-line like so:

 
```
mariadb -u user_name -p -h ip_address db_name

```

Replace *user\_name* with your database username. Replace *ip\_address* with the host name or address of your server. If you're accessing MariaDB from the same server you're logged into, then don't include `-h` and the *ip\_address*. Replace *db\_name* with the name of the database you want to access (such as *test*, which sometimes comes already created for testing purposes - note that Windows does not create this database, and some setups may also have removed the `test` database by running [mariadb-secure-installation](../mariadb-secure-installation/index), in which case you can leave the *db\_name* out). 

 When prompted to enter your password, enter it. If your login is successful you should see something that looks similar to this:

 
```
MariaDB [test]> 

```

This is where you will enter in all of your SQL statements. More about those later. For now, let's look at the components of the prompt: The "MariaDB" part means you that you are connected to a MariaDB database server. The word between the brackets is the name of your default database, the *test* database in this example.

 #### The Basics of a Database

 To make changes to a database or to retrieve data, you will need to enter an SQL statement. SQL stands for Structured Query Language. An SQL statement that requests data is called a query. Databases store information in tables. They're are similar to spreadsheets, but much more efficient at managing data. 

 Note that the *test* database may not contain any data yet. If you want to follow along with the primer, copy and paste the following into the [mariadb](../mariadb-command-line-client/index) client. This will create the tables we will use and add some data to them. Don't worry about understanding them yet; we'll get to that later.

 
```
CREATE DATABASE IF NOT EXISTS test;

USE test;

CREATE TABLE IF NOT EXISTS books (
  BookID INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
  Title VARCHAR(100) NOT NULL, 
  SeriesID INT, AuthorID INT);

CREATE TABLE IF NOT EXISTS authors 
(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT);

CREATE TABLE IF NOT EXISTS series 
(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT);

INSERT INTO books (Title,SeriesID,AuthorID) 
VALUES('The Fellowship of the Ring',1,1), 
      ('The Two Towers',1,1), ('The Return of the King',1,1),  
      ('The Sum of All Men',2,2), ('Brotherhood of the Wolf',2,2), 
      ('Wizardborn',2,2), ('The Hobbbit',0,1);

```

Notice the semi-colons used above. The [mariadb](../mariadb-command-line-client/index) client lets you enter very complex SQL statements over multiple lines. It won't send an SQL statement until you type a semi-colon and hit [Enter].

 Let's look at what you've done so far. Enter the following:

 
```
SHOW TABLES;

+----------------+
| Tables_in_test |
+----------------+
| authors        |
| books          |
| series         |
+----------------+
3 rows in set (0.00 sec)

```

Notice that this displays a list of the tables in the database. If you didn't already have tables in your `test` database, your results should look the same as above. Let's now enter the following to get information about one of these tables:

 
```
DESCRIBE books;

+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| BookID   | int(11)      | NO   | PRI | NULL    | auto_increment |
| Title    | varchar(100) | NO   |     | NULL    |                |
| SeriesID | int(11)      | YES  |     | NULL    |                |
| AuthorID | int(11)      | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

```

The main bit of information of interest to us is the *Field* column. The other columns provide useful information about the structure and type of data in the database, but the *Field* column gives us the names, which is needed to retrieve data from the table.

 Let's retrieve data from the `books` table. We'll do so by executing a [SELECT](../select/index) statement like so:

 
```
SELECT * FROM books;

+--------+----------------------------+----------+----------+
| BookID | Title                      | SeriesID | AuthorID |
+--------+----------------------------+----------+----------+
|      1 | The Fellowship of the Ring |        1 |        1 |
|      2 | The Two Towers             |        1 |        1 |
|      3 | The Return of the King     |        1 |        1 |
|      4 | The Sum of All Men         |        2 |        2 |
|      5 | Brotherhood of the Wolf    |        2 |        2 |
|      6 | Wizardborn                 |        2 |        2 |
|      7 | The Hobbbit                |        0 |        1 |
+--------+----------------------------+----------+----------+
7 rows in set (0.00 sec)

```

This SQL statement or query asks the database to show us all of the data in the `books` table. The wildcard ('`*`') character indicates to select all columns.

 #### Inserting Data

 Suppose now that we want to add another book to this table. We'll add the book, *Lair of Bones*. To insert data into a table, you would use the [INSERT](../insert/index) statement. To insert information on a book, we would enter something like this:

 
```
INSERT INTO books (Title, SeriesID, AuthorID)
VALUES ("Lair of Bones", 2, 2);

Query OK, 1 row affected (0.00 sec)

```

Notice that we put a list of columns in parentheses after the name of the table, then we enter the keyword `VALUES` followed by a list of values in parentheses--in the same order as the columns were listed. We could put the columns in a different order, as long as the values are in the same order as we list the columns. Notice the message that was returned indicates that the execution of the SQL statement went fine and one row was entered.

 Execute the following SQL statement again and see what results are returned:

 
```
SELECT * FROM books;

```

You should see the data you just entered on the last row of the results. In looking at the data for the other books, suppose we notice that the title of the seventh book is spelled wrong. It should be spelled *The Hobbit*, not *The Hobbbit*. We will need to update the data for that row.

 #### Modifying Data

 To change data in a table, you will use the [UPDATE](../update/index) statement. Let's change the spelling of the book mentioned above. To do this, enter the following:

 
```
UPDATE books 
SET Title = "The Hobbit" 
WHERE BookID = 7;

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

```

Notice the syntax of this SQL statement. The `SET` clause is where you list the columns and the values to set them. The `WHERE` clause says that you want to update only rows in which the `BookID` column has a value of `7`, of which there are only one. You can see from the message it returned that one row matched the `WHERE` clause and one row was changed. There are no warnings because everything went fine. Execute the [SELECT](../select/index) from earlier to see that the data changed.

 As you can see, using MariaDB isn't very difficult. You just have to understand the syntax of SQL since it doesn't allow for typing mistakes or things in the wrong order or other deviations.

 #### See Also

 * [MariaDB Basics](../mariadb-basics/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/a-mariadb-primer/>

MariaDB Basics
==============

    #### Connecting to MariaDB

 MariaDB is a database system, a database server. To interface with the MariaDB server, you can use a client program, or you can write a program or script with one of the popular programming languages (e.g., PHP) using an API (Application Programming Interface) to interface with the MariaDB server. For the purposes of this article, we will focus on using the default client that comes with MariaDB called `mariadb`. With this client, you can either enter queries from the command-line, or you can switch to a terminal, that is to say, monitor mode. To start, we'll use the latter.

 From the Linux command-line, you would enter the following to log in as the root user and to enter monitor mode:

 
```
mariadb -u root -p -h localhost

```

The `-u` option is for specifying the user name. You would replace `root` here if you want to use a different user name. This is the MariaDB user name, not the Linux user name. The password for the MariaDB user `root` will probably be different from the Linux user `root`. Incidentally, it's not a good security practice to use the `root` user unless you have a specific administrative task to perform for which only `root` has the needed privileges. 

 The `-p` option above instructs the `mariadb` client to prompt you for the password. If the password for the `root` user hasn't been set yet, then the password is blank and you would just hit [Enter] when prompted. The `-h` option is for specifying the host name or the IP address of the server. This would be necessary if the client is running on a different machine than the server. If you've secure-shelled into the server machine, you probably won't need to use the host option. In fact, if you're logged into Linux as `root`, you won't need the user option—the `-p` is all you'll need. Once you've entered the line above along with the password when prompted, you will be logged into MariaDB through the client. To exit, type quit or exit and press [Enter].

 #### Creating a Structure

 In order to be able to add and to manipulate data, you first have to create a database structure. Creating a database is simple. You would enter something like the following from within the [mariadb client](../mariadb-command-line-client/index):

 
```
CREATE DATABASE bookstore;

USE bookstore;

```

This very minimal, first SQL statement will create a sub-directory called bookstore on the Linux filesystem in the directory which holds your MariaDB data files. It won't create any data, obviously. It'll just set up a place to add tables, which will in turn hold data. The second SQL statement above will set this new database as the default database. It will remain your default until you change it to a different one or until you log out of MariaDB.

 The next step is to begin creating tables. This is only a little more complicated. To create a simple table that will hold basic data on books, we could enter something like the following:

 
```
CREATE TABLE books (
isbn CHAR(20) PRIMARY KEY, 
title VARCHAR(50),
author_id INT,
publisher_id INT,
year_pub CHAR(4),
description TEXT );

```

This SQL statement creates the table books with six fields, or rather columns. The first column (isbn) is an identification number for each row—this name relates to the unique identifier used in the book publishing business. It has a fixed-width character type of 20 characters. It will be the primary key column on which data will be indexed. The column data type for the book title is a variable width character column of fifty characters at most. The third and fourth columns will be used for identification numbers for the author and the publisher. They are integer data types. The fifth column is used for the publication year of each book. The last column is for entering a description of each book. It's a [TEXT](../text/index) data type, which means that it's a variable width column and it can hold up to 65535 bytes of data for each row. There are several other data types that may be used for columns, but this gives you a good sampling.

 To see how the table we created looks, enter the following SQL statement:

 
```
DESCRIBE books;
+--------------+-------------+------+-----+---------+-------+
| Field        | Type        | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+-------+
| isbn         | char(20)    | NO   | PRI | NULL    |       |
| title        | varchar(50) | YES  |     | NULL    |       |
| author_id    | int(11)     | YES  |     | NULL    |       |
| publisher_id | int(11)     | YES  |     | NULL    |       |
| year_pub     | char(4)     | YES  |     | NULL    |       |
| description  | text        | YES  |     | NULL    |       |
+--------------+-------------+------+-----+---------+-------+

```

To change the settings of a table, you can use the [ALTER TABLE](../alter-table/index) statement. I'll cover that statement in another article. To delete a table completely (including its data), you can use the [DROP TABLE](../drop-table/index) statement, followed by the table name. Be careful with this statement since it's not reversible.

 The next table we'll create for our examples is the authors table to hold author information. This table will save us from having to enter the author's name and other related data for each book written by each author. It also helps to ensure consistency of data: there's less chance of inadvertent spelling deviations.

 
```
CREATE TABLE authors
(author_id INT AUTO_INCREMENT PRIMARY KEY,
name_last VARCHAR(50),
name_first VARCHAR(50),
country VARCHAR(50) );

```

We'll join this table to the books table as needed. For instance, we would use it when we want a list of books along with their corresponding authors' names. For a real bookstore's database, both of these tables would probably have more columns. There would also be several more tables. For the examples that follow, these two tables as they are will be enough.

 #### Minor Items

 Before moving on to the next step of adding data to the tables, let me point out a few minor items that I've omitted mentioning. SQL statements end with a semi-colon (or a \G). You can spread an SQL statement over multiple lines. However, it won't be passed to the server by the client until you terminate it with a semi-colon and hit [Enter]. To cancel an SQL statement once you've started typing it, enter `\c` and press [Enter].

 As a basic convention, reserved words are printed in all capital letters. This isn't necessary, though. MariaDB is case-insensitive with regards to reserved words. Database and table names, however, are case-sensitive on Linux. This is because they reference the related directories and files on the filesystem. Column names aren't case sensitive since they're not affected by the filesystem, per se. As another convention, we use lower-case letters for structural names (e.g., table names). It's a matter of preference for deciding on names.

 #### Entering Data

 The primary method for entering data into a table is to use the [INSERT](../insert/index) statement. As an example, let's enter some information about an author into the authors table. We'll do that like so:

 
```
INSERT INTO authors
(name_last, name_first, country)
VALUES('Kafka', 'Franz', 'Czech Republic');

```

This will add the name and country of the author Franz Kafka to the authors table. We don't need to give a value for the author\_id since that column was created with the [AUTO\_INCREMENT](../auto_increment/index) option. MariaDB will automatically assign an identification number. You can manually assign one, especially if you want to start the count at a higher number than 1 (e.g., 1000). Since we are not providing data for all of the columns in the table, we have to list the columns for which we are giving data and in the order that the data is given in the set following the VALUES keyword. This means that we could give the data in a different order.

 For an actual database, we would probably enter data for many authors. We'll assume that we've done that and move on to entering data for some books. Below is an entry for one of Kafka's books:

 
```
INSERT INTO books
(title, author_id, isbn, year_pub)
VALUES('The Castle', '1', '0805211063', '1998');

```

This adds a record for Kafka's book, *The Castle*. Notice that we mixed up the order of the columns, but it still works because both sets agree. We indicate that the author is Kafka by giving a value of 1 for the author\_id. This is the value that was assigned by MariaDB when we entered the row for Kafka earlier. Let's enter a few more books for Kafka, but by a different method:

 
```
INSERT INTO books
(title, author_id, isbn, year_pub)
VALUES('The Trial', '1', '0805210407', '1995'),
('The Metamorphosis', '1', '0553213695', '1995'),
('America', '1', '0805210644', '1995');

```

In this example, we've added three books in one statement. This allows us to give the list of column names once. We also give the keyword `VALUES` only once, followed by a separate set of values for each book, each contained in parentheses and separated by commas. This cuts down on typing and speeds up the process. Either method is fine and both have their advantages. To be able to continue with our examples, let's assume that data on thousands of books has been entered. With that behind us, let's look at how to retrieve data from tables.

 #### Retrieving Data

 The primary method of retrieving data from tables is to use a [SELECT](../select/index) statement. There are many options available with the [SELECT](../select/index) statement, but you can start simply. As an example, let's retrieve a list of book titles from the books table:

 
```
SELECT title 
FROM books;

```

This will display all of the rows of books in the table. If the table has thousands of rows, MariaDB will display thousands. To limit the number of rows retrieved, we could add a [LIMIT](../select/index#limit) clause to the [SELECT](../select/index) statement like so:

 
```
SELECT title 
FROM books
LIMIT 5;

```

This will limit the number of rows displayed to five. To be able to list the author's name for each book along with the title, you will have to join the books table with the authors table. To do this, we can use the [JOIN](../join-syntax/index) clause like so:

 
```
SELECT title, name_last 
FROM books 
JOIN authors USING (author_id);

```

Notice that the primary table from which we're drawing data is given in the `FROM` clause. The table to which we're joining is given in the [JOIN](../join-syntax/index) clause along with the commonly named column (i.e., author\_id) that we're using for the join.

 To retrieve the titles of only books written by Kafka based on his name (not the author\_id), we would use the `WHERE` clause with the [SELECT](../select/index) statement. This would be entered like the following:

 
```
SELECT title AS 'Kafka Books'
FROM books 
JOIN authors USING (author_id)
WHERE name_last = 'Kafka';

+-------------------+
| Kafka Books       |
+-------------------+
| The Castle        |
| The Trial         |
| The Metamorphosis |
| America           |
+-------------------+

```

This statement will list the titles of Kafka books stored in the database. Notice that I've added the `AS` parameter next to the column name title to change the column heading in the results set to Kafka Books. This is known as an alias. Looking at the results here, we can see that the title for one of Kafka's books is incorrect. His book Amerika is spelled above with a "c" in the table instead of a "k". This leads to the next section on changing data.

 #### Changing & Deleting Data

 In order to change existing data, a common method is to use the [UPDATE](../update/index) statement. When changing data, though, we need to be sure that we change the correct rows. In our example, there could be another book with the title *America* written by a different author. Since the key column isbn has only unique numbers and we know the ISBN number for the book that we want to change, we can use it to specify the row.

 
```
UPDATE books
SET title = 'Amerika'
WHERE isbn = '0805210644';

```

This will change the value of the title column for the row specified. We could change the value of other columns for the same row by giving the column = value for each, separated by commas.

 If we want to delete a row of data, we can use the [DELETE](../delete/index) statement. For instance, suppose that our fictitious bookstore has decided no longer to carry books by John Grisham. By first running a [SELECT](../select/index) statement, we determine the identification number for the author to be 2034. Using this author identification number, we could enter the following:

 
```
DELETE FROM books
WHERE author_id = '2034';

```

This statement will delete all rows from the table books for the author\_id given. To do a clean job of it, we'll have to do the same for the authors table. We would just replace the table name in the statement above; everything else would be the same.

 #### Conclusion

 This is a very basic primer for using MariaDB. Hopefully, it gives you the idea of how to get started with MariaDB. Each of the SQL statements mentioned here have several more options and clauses each. We will cover these statements and others in greater detail in other articles. For now, though, you can learn more about them from experimenting and by further reading of the Knowledge Base online documentation. A downloadable PDF of much of the documentation is [available here](https://downloads.mariadb.org).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-basics/>

Adding and Changing Data in MariaDB
===================================

     There are several ways to add and to change data in MariaDB. There are a few SQL statements that you can use, each with a few options. Additionally, there are twists that you can do by mixing SQL statements together with various clauses. In this article, we will explore the ways in which data can be added and changed in MariaDB.

 #### Adding Data

 To add data to a table in MariaDB, you will need to use the [INSERT](../insert/index) statement. Its basic, minimal syntax is the command [INSERT](../insert/index) followed by the table name and then the keyword VALUES with a comma separated list of values contained in parentheses:

 
```
INSERT table1
VALUES('text1','text2','text3');

```

In this example, text is added to a table called table1, which contains only three columns—the same number of values that we're inserting. The number of columns must match. If you don't want to insert data into all of the columns of a table, though, you could name the columns desired:

 
```
INSERT INTO table1
(col3, col1)
VALUES('text3','text1');

```

Notice that the keyword `INTO` was added here. This is optional and has no effect on MariaDB. It's only a matter of grammatical preference. In this example we not only name the columns, but we list them in a different order. This is acceptable to MariaDB. Just be sure to list the values in the same order. If you're going to insert data into a table and want to specify all of the values except one (say the key column since it's an auto-incremented one), then you could just give a value of DEFAULT to keep from having to list the columns. Incidentally, you can give the column names even if you're naming all of them. It's just unnecessary unless you're going to reorder them as we did in this last example.

 When you have many rows of data to insert into the same table, it can be more efficient to insert all of the rows in one SQL statement. Multiple row insertions can be done like so:

 
```
INSERT IGNORE
INTO table2
VALUES('id1','text','text'),
('id2','text','text'),
('id2','text','text');

```

Notice that the keyword VALUES is used only once and each row is contained in its own set of parentheses and each set is separated by commas. We've added an intentional mistake to this example: We are attempting to insert three rows of data into table2 for which the first column happens to be a `UNIQUE` key field. The third row entered here has the same identification number for the key column as the second row. This would normally result in an error and none of the three rows would be inserted. However, since the statement has an `IGNORE` flag, duplicates will be ignored and not inserted, but the other rows will still be inserted. So, the first and second rows above will be inserted and the third one won't.

 #### Priority

 An [INSERT](../insert/index) statement takes priority over read statements (i.e., SELECT statements). An [INSERT](../insert/index) will lock the table and force other clients to wait until it's finished. On a busy MariaDB server that has many simultaneous requests for data, this could cause users to experience delays when you run a script that performs a series of [INSERT](../insert/index) statements. If you don't want user requests to be put on hold and you can wait to insert the data, you could use the `LOW_PRIORITY` flag:

 
```
INSERT LOW_PRIORITY
INTO table1
VALUES('text1','text2','text3');

```

The `LOW_PRIORITY` flag will put the [INSERT](../insert/index) statement in queue, waiting for all current and pending requests to be completed before it's performed. If new requests are made while a low priority statement is waiting, then they are put ahead of it in the queue. MariaDB does not begin to execute a low priority statement until there are no other requests waiting. Once the transaction begins, though, the table is locked and any other requests for data from the table that come in after it starts must wait until it's completed. Because it locks the table, low priority statements will prevent simultaneous insertions from other clients even if you're dealing with a MyISAM table. Incidentally, notice that the `LOW_PRIORITY` flag comes before the `INTO`.

 One potential inconvenience with an `INSERT LOW_PRIORITY` statement is that the client will be tied up waiting for the statement to be completed successfully. So if you're inserting data into a busy server with a low priority setting using the mariadb client, your client could be locked up for minutes, maybe hours depending on how busy your server is at the time. As an alternative either to making other clients with read requests wait or to having your client wait, you can use the DELAYED flag instead of the `LOW_PRIORITY` flag:

 
```
INSERT DELAYED
INTO table1
VALUES('text1','text2','text3');

```

MariaDB will take the request as a low priority one and put it on its list of tasks to perform when it has a break. However, it will immediately release the client so that the client can go on to enter other SQL statements or even exit. Another advantage of this method is that multiple `INSERT DELAYED` requests are batched together for block insertion when there is a gap, making the process potentially faster than `INSERT LOW_PRIORITY`. The flaw in this choice, however, is that the client is never told if a delayed insertion is successfully made or not. The client is informed of error messages when the statement is entered—the statement has to be valid before it will be queued—but it's not told of problems that occur after it's accepted. This brings up another flaw: delayed insertions are stored in the server's memory. So if the MariaDB daemon (mariadbd) dies or is manually killed, then the transactions are lost and the client is not notified of the failure. So DELAYED is not always a good alternative.

 #### Contingent Additions

 As an added twist to [INSERT](../insert/index), you can combine it with a SELECT statement. Suppose that you have a table called employees which contains employee information for your company. Suppose further that you have a column to indicate whether an employee is on the company's softball team. However, you one day decide to create a separate database and table for the softball team's data that someone else will administer. To get the database ready for the new administrator, you have to copy some data for team members to the new table. Here's one way you can accomplish this task:

 
```
INSERT INTO softball_team 
(last, first, telephone) 
SELECT name_last, name_first, tel_home
FROM company.employees 
WHERE softball='Y';

```

In this SQL statement the columns in which data is to be inserted into are listed, then the complete SELECT statement follows with the appropriate WHERE clause to determine if an employee is on the softball team. Since we're executing this statement from the new database and since the table employees is in a separate database called company, we have to specify it as you see here. By the way, [INSERT...SELECT](../insert-select/index) statements cannot be performed on the same table.

 #### Replacement Data

 When you're adding massive amounts of data to a table that has a key field, as mentioned earlier, you can use the `IGNORE` flag to prevent duplicates from being inserted, but still allow unique rows to be entered. However, there may be times when you actually want to replace the rows with the same key fields with the new ones. In such a situation, instead of using [INSERT](../insert/index) you can use a [REPLACE](../replace/index) statement:

 
```
REPLACE LOW_PRIORITY
INTO table2 (id, col1, col2)
VALUES('id1','text','text'),
('id2','text','text'),
('id3','text','text');

```

Notice that the syntax is the same as an [INSERT](../insert/index) statement. The flags all have the same effect, as well. Also, multiple rows may be inserted, but there's no need for the `IGNORE` flag since duplicates won't happen—the originals are just overwritten. Actually, when a row is replaced, it's first deleted completely and the new row is then inserted. Any columns without values in the new row will be given the default values for the columns. None of the values of the old row are kept. Incidentally, [REPLACE](../replace/index) will also allow you to combine it with a SELECT statement as we saw with the [INSERT](../insert/index) statement earlier.

 #### Updating Data

 If you want to change the data contained in existing records, but only for certain columns, then you would need to use an [UPDATE](../update/index) statement. The syntax for [UPDATE](../update/index) is a little bit different from the syntax shown before for [INSERT](../insert/index) and [REPLACE](../replace/index) statements:

 
```
UPDATE LOW_PRIORITY table3
SET col1 = 'text-a', col2='text-b'
WHERE id < 100;

```

In the SQL statement here, we are changing the value of the two columns named individually using the `SET` clause. Incidentally, the `SET` clause optionally can be used in [INSERT](../insert/index) and [REPLACE](../replace/index) statements, but it eliminates the multiple row option. In the statement above, we're also using a `WHERE` clause to determine which records are changed: only rows with an id that has a value less than 100 are updated. Notice that the `LOW_PRIORITY` flag can be used with this statement, too. The `IGNORE` flag can be used, as well.

 A useful feature of the [UPDATE](../update/index) statement is that it allows the use of the current value of a column to update the same column. For instance, suppose you want to add one day to the value of a date column where the date is a Sunday. You could do the following:

 
```
UPDATE table5
SET col_date = DATE_ADD(col_date, INTERVAL 1 DAY)
WHERE DAYOFWEEK(col_date) = 1;

```

For rows where the day of the week is Sunday, the DATE\_ADD() function will take the value of col\_date before it's updated and add one day to it. MariaDB will then take this sum and set col\_date to it.

 There are a couple more twists that you can now do with the [UPDATE](../update/index) statement: if you want to update the rows in a specific order, you can add an [ORDER BY](../select/index#order-by) clause. You can also limit the number of rows that are updated with a [LIMIT](../select/index#limit) clause. Below is an example of both of these clauses:

 
```
UPDATE LOW_PRIORITY table3
SET col1='text-a', col2='text-b'
WHERE id < 100
ORDER BY col3 DESC
LIMIT 10;

```

The ordering can be descending as indicated here by the `DESC` flag, or ascending with either the ASC flag or by just leaving it out, as ascending is the default. The [LIMIT](../select/index#limit) clause, of course, limits the number of rows affected to ten here.

 If you want to refer to multiple tables in one [UPDATE](../update/index) statement, you can do so like this:

 
```
UPDATE table3, table4
SET table3.col1 = table4.col1
WHERE table3.id = table4.id;

```

Here we see a join between the two tables named. In table3, the value of col1 is set to the value of the same column in table4 where the values of id from each match. We're not updating both tables here; we're just accessing both. We must specify the table name for each column to prevent an ambiguity error. Incidentally, [ORDER BY](../select/index#order-by) and [LIMIT](../select/index#limit) clauses aren't allowed with multiple table updates.

 There's another combination that you can do with the [INSERT](../insert/index) statement that we didn't mention earlier. It involves the [UPDATE](../update/index) statement. When inserting multiple rows of data, if you want to note which rows had potentially duplicate entries and which ones are new, you could add a column called status and change it's value accordingly with a statement like this one:

 
```
INSERT IGNORE INTO table1 
(id, col1, col2, status) 
VALUES('1012','text','text','new'),
('1025,'text','text','new'),
('1030,'text','text','new')
ON DUPLICATE KEY 
UPDATE status = 'old';

```

Because of the `IGNORE` flag, errors will not be generated, duplicates won't be inserted or replaced, but the rest will be added. Because of the [ON DUPLICATE KEY](../insert-on-duplicate-key-update/index), the column status of the original row will be set to old when there are duplicate entry attempts. The rest will be inserted and their status set to new.

 #### Conclusion

 As you can see from some of these SQL statements, MariaDB offers you quite a few ways to add and to change data. In addition to these methods, there are also some bulk methods of adding and changing data in a table. You could use the [LOAD DATA INFILE](../load-data-infile/index) statement and the [mariadb-dump](../mariadb-dump/index) command-line utility. These methods are covered in another article on [Importing Data into MariaDB](../importing-data-into-mariadb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/adding-and-changing-data-in-mariadb/>

Altering Tables in MariaDB
==========================

     Despite a MariaDB developer's best planning, occasionally one needs to change the structure or other aspects of tables. This is not very difficult, but some developers are unfamiliar with the syntax for the functions used in MariaDB to accomplish this. And some changes can be very frustrating. In this article we'll explore the ways to alter tables in MariaDB and we'll give some precautions about related potential data problems.

 #### Before Beginning

 For the examples in this article, we will refer to a database called `db1` containing a table called `clients`. The `clients` table is for keeping track of client names and addresses. To start off, we'll enter a [DESCRIBE](../describe/index) statement to see what the table looks like:

 
```
DESCRIBE clients; 

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| cust_id     | int(11)     |      | PRI | 0       |       |
| name        | varchar(25) | YES  |     | NULL    |       |
| address     | varchar(25) | YES  |     | NULL    |       |
| city        | varchar(25) | YES  |     | NULL    |       |
| state       | char(2)     | YES  |     | NULL    |       |
| zip         | varchar(10) | YES  |     | NULL    |       |
| client_type | varchar(4)  | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

```

This is a very simple table that will hold very little information. However, it's sufficient for the examples here in which we will change several of its columns. Before doing any structural changes to a table in MariaDB, especially if it contains data, one should make a backup of the table to be changed. There are a few ways to do this, but some choices may not be permitted by your web hosting company. Even if your database is on your own server, though, the [mariadb-dump](../mariadb-dump/index) utility is typically the best tool for making and restoring backups in MariaDB, and it's generally permitted by web hosting companies. To backup the clients table with [mariadb-dump](../mariadb-dump/index), we will enter the following from the command-line:

 
```
mariadb-dump --user='username' --password='password' --add-locks db1 clients > clients.sql

```

As you can see, the username and password are given on the first line. On the next line, the `--add-locks` option is used to lock the table before backing up and to unlock automatically it when the backup is finished. There are many other options in [mariadb-dump](../mariadb-dump/index) that could be used, but for our purposes this one is all that's necessary. Incidentally, this statement can be entered in one line from the shell (i.e., not from the `mariadb` client), or it can be entered on multiple lines as shown here by using the back-slash (i.e., `/`) to let the shell know that more is to follow. On the third line above, the database name is given, followed by the table name. The redirect (i.e., `>`) tells the shell to send the results of the dump to a text file called `clients.sql` in the current directory. A directory path could be put in front of the file name to create the file elsewhere. If the table should need to be restored, the following can be run from the shell:

 
```
mariadb --user='username' --password='password' db1 < clients.sql

```

Notice that this line does not use the `mariadb-dump` utility. It uses the `mariadb` client from the outside, so to speak. When the dump file (`clients.sql`) is read into the database, it will delete the `clients` table and it's data in MariaDB before restoring the backup copy with its data. So be sure that users haven't added data in the interim. In the examples in this article, we are assuming that there isn't any data in the tables yet.

 #### Basic Addition and More

 In order to add a column to an existing MariaDB table, one would use the [ALTER TABLE](../alter-table/index) statement. To demonstrate, suppose that it has been decided that there should be a column for the client's account status (i.e., active or inactive). To make this change, the following is entered:

 
```
ALTER TABLE clients 
ADD COLUMN status CHAR(2);

```

This will add the column `status` to the end with a fixed width of two characters (i.e., *AC* for active and *IA* for inactive). In looking over the table again, it's decided that another field for client apartment numbers or the like needs to be added. That data could be stored in the address column, but it would better for it to be in a separate column. An [ALTER TABLE](../alter-table/index) statement could be entered like above, but it will look tidier if the new column is located right after the address column. To do this, we'll use the `AFTER` option:

 
```
ALTER TABLE clients 
ADD COLUMN address2 varchar(25) 
AFTER address;

```

By the way, to add a column to the first position, you would replace the last line of the SQL statement above to read like this:

 
```
...
FIRST;

```

Before moving on, let's take a look at the table's structure so far:

 
```
DESCRIBE clients;

+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| cust_id     | int(11)     |      | PRI | 0       |       |
| name        | varchar(25) | YES  |     | NULL    |       |
| address     | varchar(25) | YES  |     | NULL    |       |
| address2    | varchar(25) | YES  |     | NULL    |       |
| city        | varchar(25) | YES  |     | NULL    |       |
| state       | char(2)     | YES  |     | NULL    |       |
| zip         | varchar(10) | YES  |     | NULL    |       |
| client_type | varchar(4)  | YES  |     | NULL    |       |
| status      | char(2)     | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+

```

#### Changing One's Mind

 After looking over the above table display, it's decided that it might be better if the status column has the choices of 'AC' and 'IA' enumerated. To make this change, we'll enter the following SQL statement:

 
```
ALTER TABLE clients 
CHANGE status status enum('AC','IA');

```

Notice that the column name status is specified twice. Although the column name isn't being changed, it still must be respecified. To change the column name (from `status` to `active`), while leaving the enumerated list the same, we specify the new column name in the second position:

 
```
ALTER TABLE clients
CHANGE status active ENUM('AC','IA');

```

Here we have the current column name and then the new column name, along with the data type specifications (i.e., `ENUM`), even though the result is only a name change. With the `CHANGE` clause everything must be stated, even items that are not to be changed.

 In checking the table structure again, more changes are decided on: The column address is to be renamed to address1 and changed to forty characters wide. Also, the enumeration of active is to have 'yes' and 'no' choices. The problem with changing enumerations is that data can be clobbered in the change if one isn't careful. We've glossed over this possibility before because we are assuming that clients is empty. Let's take a look at how the modifications suggested could be made with the table containing data:

 
```
ALTER TABLE clients
CHANGE address address1 varchar(40),
MODIFY active enum('yes','no','AC','IA');

UPDATE clients
SET active = 'yes'
WHERE active = 'AC';

UPDATE clients
SET active = 'no'
WHERE active = 'IA';

ALTER TABLE clients
MODIFY active enum('yes','no');

```

The first SQL statement above changes address and modifies active in preparation for the transition. Notice the use of a `MODIFY` clause. It works the same as `CHANGE`, but it is only used for changing data types and not column names. Therefore, the column name isn't respecified. Notice also that there is a comma after the CHANGE clause. You can string several `CHANGE` and `MODIFY` clauses together with comma separators. We've enumerated both the new choices and the old ones to be able to migrate the data. The two [UPDATE](../update/index) statements are designed to adjust the data accordingly and the last [ALTER TABLE](../alter-table/index) statement is to remove the old enumerated choices for the status column.

 In talking to the boss, we find out that the `client_type` column isn't going to be used. So we enter the following in MariaDB:

 
```
ALTER TABLE clients
DROP client_type;

```

This deletes `client_type` and its data, but not the whole table, obviously. Nevertheless, it is a permanent and non-reversible action; there won't be a confirmation request when using the mariadb client. This is how it is with all MariaDB DROP statements and clauses. So be sure that you want to delete an element and its data before using a `DROP.` As mentioned earlier, be sure that you have a backup of your tables before doing any structured changes.

 #### The Default

 You may have noticed that the results of the [DESCRIBE](../describe/index) statements shown before have a heading called 'Default' and just about all of the fields have a default value of NULL. This means that there are no default values and a null value is allowed and will be used if a value isn't specified when a row is created. To be able to specify a default value other than NULL, an [ALTER TABLE](../alter-table/index) statement can be entered with a `SET` clause. Suppose we're located in Louisiana and we want a default value of 'LA' for state since that's where our clients are usually located. We would enter the following to set the default:

 
```
ALTER TABLE clients
ALTER state SET DEFAULT 'LA';

```

Notice that the second line starts with `ALTER` and not `CHANGE`. If we change our mind about having a default value for state, we would enter the following to reset it back to NULL (or whatever the initial default value would be based on the data type):

 
```
ALTER TABLE clients
ALTER state DROP DEFAULT;

```

This particular `DROP` doesn't delete data, by the way.

 #### Indexes

 One of the most irritating tasks in making changes to a table for newcomers is dealing with indexes. If they try to rename a column that is indexed by only using an [ALTER TABLE](../alter-table/index) statement like we used earlier, they will get a frustrating and confusing error message:

 
```
ALTER TABLE clients
CHANGE cust_id client_id INT
PRIMARY KEY;
 
ERROR 1068: Multiple primary key defined

```

If they're typing this column change from memory, they will wear themselves out trying different deviations thinking that they remembered the syntax wrong. What most newcomers to MariaDB don't seem to realize is that the index is separate from the indexed column. To illustrate, let's take a look at the index for clients by using the [SHOW INDEX](../show-index/index) statement:

 
```
SHOW INDEX FROM clientsG;

*************************** 1. row ***************************
           Table: clients
      Non_unique: 0
        Key_name: PRIMARY
    Seq_in_index: 1
     Column_name: cust_id
       Collation: A
     Cardinality: 0
        Sub_part: NULL
          Packed: NULL
         Comment:
1 row in set (0.00 sec)

```

The text above shows that behind the scenes there is an index associated with `cust_id`. The column `cust_id` is not the index. Incidentally, the G at the end of the [SHOW INDEX](../show-index/index) statement is to display the results in portrait instead of landscape format. Before the name of an indexed column can be changed, the index related to it must be eliminated. The index is not automatically changed or deleted. Therefore, in the example above, MariaDB thinks that the developer is trying to create another primary key index. So, a `DROP` clause for the index must be entered first and then a `CHANGE` for the column name can be made along with the establishing of a new index:

 
```
ALTER TABLE clients
DROP PRIMARY KEY,
CHANGE cust_id
client_id INT PRIMARY KEY;

```

The order of these clauses is necessary. The index must be dropped before the column can be renamed. The syntax here is for a `PRIMARY KEY`. There are other types of indexes, of course. To change a column that has an index type other than a `PRIMARY KEY`. Assuming for a moment that `cust_id` has a `UNIQUE` index, this is what we would enter to change its name:

 
```
ALTER TABLE clients
DROP UNIQUE cust_id
CHANGE cust_id
client_id INT UNIQUE;

```

Although the index type can be changed easily, MariaDB won't permit you to do so when there are duplicate rows of data and when going from an index that allows duplicates (e.g., `INDEX`) to one that doesn't (e.g., `UNIQUE`). If you actually do want to eliminate the duplicates, though, you can add the `IGNORE` flag to force the duplicates to be deleted:

 
```
ALTER IGNORE TABLE clients
DROP INDEX cust_id
CHANGE cust_id
client_id INT UNIQUE;

```

In this example, we're not only changing the indexed column's name, but we're also changing the index type from `INDEX` to `UNIQUE`. And, again, the `IGNORE` flag tells MariaDB to ignore any records with duplicate values for `cust_id`.

 #### Renaming & Shifting Tables

 The previous sections covered how to make changes to columns in a table. Sometimes you may want to rename a table. To change the name of the `clients` table to client\_addresses we enter this:

 
```
RENAME TABLE clients 
TO client_addresses;

```

The RENAME TABLE statement will also allows a table to be moved to another database just by adding the receiving database's name in front of the new table name, separated by a dot. Of course, you can move a table without renaming it. To move the newly named `client_addresses` table to the database db2, we enter this:

 
```
RENAME TABLE client_addresses
TO db2.client_addresses;

```

Finally, with tables that contain data (excluding [InnoDB](../innodb/index) tables), occasionally it's desirable to resort the data within the table. Although the [ORDER BY](../select/index#order-by) clause in a [SELECT](../select/index) statement can do this on the fly as needed, sometimes developers want to do this somewhat permanently to the data within the table based on a particular column or columns. It can be done by entering the following:

 
```
ALTER TABLE client_addresses
ORDER BY city, name;

```

Notice that we're sorting by the city first and then by the client's name. Now when the developer enters a [SELECT](../select/index) statement without an [ORDER BY](../select/index#order-by) clause, the results are already ordered by the default of city and then name, at least until more data is added to the table.

 This is not applicable to [InnoDB](../innodb/index) tables, the default, which are ordered according to the clustered index, unless the primary key is defined on the specific columns.

 #### Summation

 Good planning is certainly important in developing a MariaDB database. However, as you can see, MariaDB is malleable enough that it can be reshaped without much trouble. Just be sure to make a backup before restructuring a table and be sure to check your work and the data when you're finished. With all of this in mind, you should feel comfortable in creating tables since they don't have to be perfect from the beginning.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/altering-tables-in-mariadb/>

Importing Data into MariaDB
===========================

     When a MariaDB developer first creates a MariaDB database for a client, often times the client has already accumulated data in other, simpler applications. Being able to convert data easily to MariaDB is critical. In the previous two articles of this MariaDB series, we explored how to set up a database and how to query one. In this third installment, we will introduce some methods and tools for bulk importing of data into MariaDB. This isn't an overly difficult task, but the processing of large amounts of data can be intimidating for a newcomer and and as a result it can be a barrier to getting started with MariaDB. Additionally, for intermediate developers, there are many nuances to consider for a clean import, which is especially important for automating regularly scheduled imports. There are also restraints to deal with that may be imposed on a developer when using a web hosting company.

 #### Foreign Data Basics

 Clients sometimes give developers raw data in formats created by simple database programs like MS Access ®. Since non-technical clients don't typically understand database concepts, new clients often give me their initial data in Excel spreadsheets. Let's first look at a simple method for importing data. The simplest way to deal with incompatible data in any format is to load it up in its original software and to export it out to a delimited text file. Most applications have the ability to export data to a text format and will allow the user to set the delimiters. We like to use the bar (i.e., `|`, a.k.a. pipe) to separate fields and the line-feed to separate records.

 For the examples in this article, we will assume that a fictitious client's data was in Excel and that the exported text file will be named `prospects.txt`. It contains contact information about prospective customers for the client's sales department, located on the client's intranet site. The data is to be imported into a MariaDB table called `prospect_contact`, in a database called `sales_dept`. To make the process simpler, the order and number of columns in MS Excel ® (the format of the data provided by the client) should be the same as the table into which the data is going to be imported. So if prospect\_contact has columns that are not included in the spreadsheet, one would make a copy of the spreadsheet and add the missing columns and leave them blank. If there are columns in the spreadsheet that aren't in `prospect_contact`, one would either add them to the MariaDB table, or, if they're not to be imported, one would delete the extra columns from the spreadsheet. One should also delete any headings and footnotes from the spreadsheet. After this is completed then the data can be exported. Since this is Unix Review, we'll skip how one would export data in Excel and assume that the task was accomplished easily enough using its export wizard.

 The next step is to upload the data text file to the client's web site by FTP. It should be uploaded in ASCII mode. Binary mode may send binary hard-returns for row-endings. Also, it's a good security habit to upload data files to non-public directories. Many web hosting companies provide virtual domains with a directory like `/public_html`, which is the document root for the Apache web server; it typically contains the site's web pages. In such a situation, `/` is a virtual root containing logs and other files that are inaccessible to the public. We usually create a directory called `tmp` in the virtual root directory to hold data files temporarily for importing into MariaDB. Once that's done, all that's required is to log into MariaDB with the [mariadb](../mariadb-client/index) client as an administrative user (if not root, then a user with `FILE` privileges), and run the proper SQL statement to import the data.

 #### Loading Data Basics

 The [LOAD DATA INFILE](../load-data-infile/index) statement is the easiest way to import data from a plain text file into MariaDB. Below is what one would enter in the [mariadb](../mariadb-client/index) client to load the data in the file called prospects.txt into the table `prospect_contact`:

 
```
LOAD DATA INFILE '/tmp/prospects.txt'
INTO TABLE prospect_contact
FIELDS TERMINATED BY '|';

```

Before entering the statement above, the MariaDB session would, of course, be switched to the sales\_dept database with a [USE](../use/index) statement. It is possible, though, to specify the database along with the table name (e.g., `sales_dept.prospect_contact`). If the server is running Windows, the forward slashes are still used for the text file's path, but a drive may need to be specified at the beginning of the path: '`c:/tmp/prospects.txt`'. Notice that the SQL statement above has `|` as the field delimiter. If the delimiter was [TAB]—which is common—then one would replace `|` with `\t` here. A line-feed (`\n`) isn't specified as the record delimiter since it's assumed. If the rows start and end with something else, though, then they will need to be stated. For instance, suppose the rows in the text file start with a double-quote and end with a double-quote and a Windows hard-return (i.e., a return and a line-feed). The statement would need to read like this:

 
```
LOAD DATA INFILE '/tmp/prospects.txt'
INTO TABLE prospect_contact
FIELDS TERMINATED BY '|'
LINES STARTING BY '"'
TERMINATED BY '"\r\n';

```

Notice that the starting double-quote is inside of single-quotes. If one needs to specify a single-quote as the start of a line, one could either put the one single-quote within double-quotes or one could escape the inner single-quote with a back-slash, thus telling MariaDB that the single-quote that follows is to be taken literally and is not part of the statement, per se:

 
```
...
LINES STARTING BY '\'' 
...

```

#### Duplicate Rows

 If the table prospect\_contact already contains some of the records that are about to be imported from prospects.txt (that is to say, records with the same primary key), then a decision should be made as to what MariaDB is to do about the duplicates. The SQL statement, as it stands above, will cause MariaDB to try to import the duplicate records and to create duplicate rows in prospect\_contact for them. If the table's properties are set not to allow duplicates, then MariaDB will kick out errors. To get MariaDB to replace the duplicate existing rows with the ones being imported in, one would add the `REPLACE` just before the `INTO TABLE` clause like this:

 
```
LOAD DATA INFILE '/tmp/prospects.txt'
REPLACE INTO TABLE prospect_contact
FIELDS TERMINATED BY '|'
LINES STARTING BY '"'
TERMINATED BY '"\n';

```

To import only records for prospects that are not already in prospect\_contact, one would substitute REPLACE with the `IGNORE` flag. This instructs MariaDB to ignore records read from the text file that already exist in the table.

 #### Live Data

 For importing data into a table while it's in use, table access needs to be addressed. If access to the table by other users may not be interrupted, then a `LOW_PRIORITY` flag can be added to the [LOAD DATA INFILE](../load-data-infile/index) statement. This tells MariaDB that the loading of this data is a low priority. One would only need to change the first line of the SQL statement above to set its priority to low:

 
```
LOAD DATA LOW_PRIORITY INFILE '/tmp/prospects.txt'
...

```

If the `LOW_PRIORITY` flag isn't included, the table will be locked temporarily during the import and other users will be prevented from accessing it.

 #### Being Difficult

 I mentioned earlier that uploading of the text file should not be done in binary mode so as to avoid the difficulties associated with Windows line endings. If this is unavoidable, however, there is an easy way to import binary row-endings with MariaDB. One would just specify the appropriate hexadecimals for a carriage-return combined with a line-feed (i.e., `CRLF`) as the value of `TERMINATED BY`:

 
```
...
TERMINATED BY 0x0d0a;

```

Notice that there are intentionally no quotes around the binary value. If there were, MariaDB would take the value for text and not a binary code. The semi-colon is not part of the value; it's the SQL statement terminator.

 Earlier we also stated that the first row in the spreadsheet containing the column headings should be deleted before exporting to avoid the difficulty of importing the headings as a record. It's actually pretty easy to tell MariaDB to just skip the top line. One would add the following line to the very end of the [LOAD DATA INFILE](../load-data-infile/index) statement:

 
```
...
IGNORE 1 LINES;

```

The number of lines for MariaDB to ignore can, of course, be more than one.

 Another difficulty arises when some Windows application wizards export data with each field surrounded by double-quotes, as well as around the start and end of records. This can be a problem when a field contains a double-quote. To deal with this, some applications use back-slash (\) to escape embedded double-quotes, to indicate that a particular double-quote is not a field ending but part of the field's content. However, some applications will use a different character (like a pound-sign) to escape embedded quotes. This can cause problems if MariaDB isn't prepared for the odd escape-character. MariaDB will think the escape character is actually text and the embedded quote-mark, although it's escaped, is a field ending. The unenclosed text that follows will be imported into the next column and the remaining columns will be one column off, leaving the last column not imported. As maddening as this can be, it's quite manageable in MariaDB by adding an `ENCLOSED BY` and an `ESCAPED BY` clause:

 
```
LOAD DATA LOW_PRIORITY INFILE '/tmp/prospects.txt'
REPLACE INTO TABLE prospect_contact
FIELDS TERMINATED BY '"'
ENCLOSED BY '"' ESCAPED BY '#'
LINES STARTING BY '"'
TERMINATED BY '"\n'
IGNORE 1 LINES;

```

In the *Foreign Data Basics* section above, we said that the columns in the spreadsheet should be put in the same order and quantity as the receiving table. This really isn't necessary if MariaDB is cued in as to what it should expect. To illustrate, let's assume that prospect\_contact has four columns in the following order: `row_id`, `name_first`, `name_last`, `telephone`. Whereas, the spreadsheet has only three columns, differently named, in this order: `Last Name`, `First Name`, `Telephone`. If the spreadsheet isn't adjusted, then the SQL statement will need to be changed to tell MariaDB the field order:

 
```
LOAD DATA LOW_PRIORITY INFILE '/tmp/prospects.txt'
REPLACE INTO TABLE sales_dept.prospect_contact
FIELDS TERMINATED BY 0x09
ENCLOSED BY '"' ESCAPED BY '#'
TERMINATED BY 0x0d0a
IGNORE 1 LINES
(name_last, name_first, telephone);

```

This SQL statement tells MariaDB the name of each table column associated with each spreadsheet column in the order that they appear in the text file. From there it will naturally insert the data into the appropriate columns in the table. As for columns that are missing like row\_id, MariaDB will fill in those fields with the default value if one has been supplied in the table's properties. If not, it will leave the field as NULL. Incidentally, we slipped in the binary `[TAB] (0x09)` as a field delimiter.

 #### mariadb-import

 For some clients and for certain situations it may be of value to be able to import data into MariaDB without using the [mariadb](../mariadb-client/index) client. This could be necessary when constructing a shell script to import text files on an automated, regular schedule. To accomplish this, the [mariadb-import](../mariadb-import/index) (`mysqlimport` before [MariaDB 10.5](../what-is-mariadb-105/index)) utility may be used as it encompasses the [LOAD DATA INFILE](../load-data-infile/index) statement and can easily be run from a script. So if one wants to enter the involved SQL statement at the end of the last section above, the following could be entered from the command-line (i.e., not in the [mariadb](../mariadb-client/index) client):

 
```
mariadb-import --user='marie_dyer' --password='angelle1207' \
--fields-terminated-by=0x09 --lines-terminated-by=0x0d0a \
--replace --low-priority --fields-enclosed-by='"' \
 --fields-escaped-by='#' --ignore-lines='1' --verbose \
--columns='name_last, name_first, telephone' \
sales_dept '/tmp/prospect_contact.txt'

```

Although this statement is written over several lines here, it either has to be on the same line when entered or a space followed by a back-slash has to be entered at the end of each line (as seen here) to indicate that more follows. Since the above is entered at the command-line prompt, the user isn't logged into MariaDB. Therefore the first line contains the user name and password for [mariadb-import](../mariadb-import/index) to give to MariaDB. The password itself is optional, but the directive `--password` (without the equal sign) isn't. If the password value is not given in the statement, then the user will be prompted for it. Notice that the order of directives doesn't matter after the initial command, except that the database and file name go last. Regarding the file name, its prefix must be the same as the table—the dot and the extension are ignored. This requires that `prospects.txt` be renamed to `prospect_contact.txt`. If the file isn't renamed, then MariaDB would create a new table called prospects and the `--replace` option would be pointless. After the file name, incidentally, one could list more text files, separated by a space, to process using [mariadb-import](../mariadb-import/index). We've added the `--verbose` directive so as to be able to see what's going on. One probably would leave this out in an automated script. By the way, `--low-priority` and `--ignore-lines` are available.

 #### Web Hosting Restraints

 Some web hosting companies do not allow the use of [LOAD DATA INFILE](../load-data-infile/index) or [mariadb-import](../mariadb-import/index) statements due to security vulnerabilities in these statements for them. To get around this, some extra steps are necessary to avoid having to manually enter the data one row at a time. First, one needs to have MariaDB installed on one's local workstation. For simplicity, we'll assume this is done and is running Linux on the main partition and MS Windows® on an extra partition. Recapping the on-going example of this article based on these new circumstances, one would boot up into Windows and start MS Excel®, load the client's spreadsheet into it and then run the export wizard as before—saving the file prospects.txt to the 'My Documents' directory. Then one would reboot into Linux and mount the Windows partition and copy the data text file to `/tmp` in Linux, locally. Next one would log into the local (not the client's) MariaDB server and import the text file using a [LOAD DATA INFILE](../load-data-infile/index) as we've extensively outline above. From there one would exit MariaDB and export the data out of MariaDB using the [mariadb-dump](../mariadb-dump/index) utility locally, from the command-line like this:

 
```
mariadb-dump --user='root' --password='geronimo' sales_dept prospect_contact > /tmp/prospects.sql

```

This creates an interesting text file complete with all of the SQL commands necessary to insert the data back into MariaDB one record, one [INSERT](../insert/index) at a time. When you run [mariadb-import](../mariadb-import/index), it's very educational to open up it in a text editor to see what it generates.

 After creating this table dump, one would upload the resulting file (in ASCII mode) to the `/tmp` directory on the client's web server. From the command prompt on the client's server one would enter the following:

 
```
mariadb --user='marie_dyer' --password='angelle12107' sales_dept < '/tmp/prospects.sql'

```

This line along with the [mariadb-dump](../mariadb-dump/index) line show above are simple approaches. Like the Windows application wizard, with mariadb-dump one can specify the format of the output file and several other factors. One important factor related to the scenario used in this article is the [CREATE TABLE](../create-table/index) statement that will be embedded in the [mariadb-dump](../mariadb-dump/index) output file. This will fail and kick out an error because of the existing table prospect\_contact in the client's database. To limit the output to only [INSERT](../insert/index) statements and no [CREATE TABLE](../create-table/index) statements, the [mariadb-dump](../mariadb-dump/index) line would look like this:

 
```
mariadb-dump -u marie_dyer -p --no-create-info sales_dept prospect_contact > /tmp/prospects.sql

```

Notice that we've used acceptable abbreviations for the user name and the password directives. Since the password was given here, the user will be prompted for it.

 The [mariadb-dump](../mariadb-dump/index) utility usually works pretty well. However, one feature it's lacking at this time is a `REPLACE` flag as is found in the [LOAD DATA INFILE](../load-data-infile/index) statement and with the [mariadb-import](../mariadb-import/index) tool. So if a record already exists in the `prospect_contact`, it won't be imported. Instead it will kick out an error message and stop at that record, which can be a mess if one has imported several hundred rows and have several hundred more to go. One easy fix for this is to open up `prospects.sql` in a text editor and do a search on the word `INSERT` and replace it with `REPLACE`. The syntax of both of these statements are the same, fortunately. So one would only need to replace the keyword for new records to be inserted and for existing records to be replaced.

 #### Concluding Observations and Admissions

 It's always amazing to me how much can be involved in the simplest of statements in MariaDB. MariaDB is deceptively powerful and feature rich. One can keep the statements pretty minimal or one can develop a fairly detailed, single statement to allow for accuracy of action. There are many other aspects of importing data into MariaDB that we did not address—in particular dealing with utilities. We also didn't talk about the Perl modules that could be used to convert data files. These can be useful in scripting imports. There are many ways in which one can handle importing data. Hopefully, this article has presented most of the basics and pertinent advanced details that may be of use to most MariaDB developers.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/importing-data-into-mariadb/>

MariaDB String Functions
========================

     MariaDB has many built-in functions that can be used to manipulate strings of data. With these functions, one can format data, extract certain characters, or use search expressions. Good developers should be aware of the string functions that are available. Therefore, in this article we will go through several string functions, grouping them by similar features, and provide examples of how they might be used.

 #### Formatting

 There are several string functions that are used to format text and numbers for nicer display. A popular and very useful function for pasting together the contents of data fields with text is the [CONCAT()](../concat/index) function. As an example, suppose that a table called contacts has a column for each sales contact's first name and another for the last name. The following SQL statement would put them together:

 
```
SELECT CONCAT(name_first, ' ', name_last)
AS Name
FROM contacts;

```

This statement will display the first name, a space, and then the last name together in one column. The AS clause will change the column heading of the results to Name.

 A less used concatenating function is [CONCAT\_WS()](../concat_ws/index). It will put together columns with a separator between each. This can be useful when making data available for other programs. For instance, suppose we have a program that will import data, but it requires the fields to be separated by vertical bars. We could just export the data, or we could use a [SELECT](../select/index) statement like the one that follows in conjunction with an interface written with an API language like Perl:

 
```
SELECT CONCAT_WS('|', col1, col2, col3)
FROM table1;

```

The first element above is the separator. The remaining elements are the columns to be strung together.

 If we want to format a long number with commas every three digits and a period for the decimal point (e.g., 100,000.00), we can use the function [FORMAT()](../format/index) like so:

 
```
SELECT CONCAT('$', FORMAT(col5, 2))
FROM table3;

```

In this statement, the [CONCAT()](../concat/index) will place a dollar sign in front of the numbers found in the `col5` column, which will be formatted with commas by [FORMAT()](../format/index). The `2` within the [FORMAT()](../format/index) stipulates two decimal places.

 Occasionally, one will want to convert the text from a column to either all upper-case letters or all lower-case letters. In the example that follows, the output of the first column is converted to upper-case and the second to lower-case:

 
```
SELECT UCASE(col1),
LCASE(col2)
FROM table4;

```

When displaying data in forms, it's sometimes useful to pad the data displayed with zeros or dots or some other filler. This can be necessary when dealing with [VARCHAR](../varchar/index) columns where the width varies to help the user to see the column limits. There are two functions that may be used for padding: [LPAD()](../lpad/index) and [RPAD()](../rpad/index).

 
```
SELECT RPAD(part_nbr, 8, '.') AS 'Part Nbr.',
LPAD(description, 15, '_') AS Description
FROM catalog;

```

In this SQL statement, dots are added to the right end of each part number. So a part number of "H200" will display as "H200....", but without the quotes. Each part's description will have under-scores preceding it. A part with a description of "brass hinge" will display as "brass hinge".

 If a column is a [CHAR](../char/index) data-type, a fixed width column, then it may be necessary to trim any leading or trailing spaces from displays. There are a few functions to accomplish this task. The [LTRIM()](../ltrim/index) function will eliminate any leading spaces to the left. So " `H200`" becomes "`H200`". For columns with trailing spaces, spaces on the right, [RTRIM()](../rtrim/index) will work: "`H500` " becomes "`H500`". A more versatile trimming function, though, is [TRIM()](../trim/index). With it one can trim left, right or both. Below are a few examples:

 
```
SELECT TRIM(LEADING '.' FROM col1),
TRIM(TRAILING FROM col2),
TRIM(BOTH '_' FROM col3),
TRIM(col4)
FROM table5;

```

In the first [TRIM()](../trim/index) clause, the padding component is specified; the leading dots are to be trimmed from the output of `col1`. The trailing spaces will be trimmed off of `col2`—space is the default. Both leading and trailing under-scores are trimmed from `col3` above. Unless specified, BOTH is the default. So leading and trailing spaces are trimmed from `col4` in the statement here.

 #### Extracting

 When there is a need to extract specific elements from a column, MariaDB has a few functions that can help. Suppose a column in the table contacts contains the telephone numbers of sales contacts, including the area-codes, but without any dashes or parentheses. The area-code of each could be extracted for sorting with the [LEFT()](../left/index) and the telephone number with the [RIGHT()](../right/index) function.

 
```
SELECT LEFT(telephone, 3) AS area_code,
RIGHT(telephone, 7) AS tel_nbr
FROM contacts
ORDER BY area_code;

```

In the [LEFT()](../left/index) function above, the column telephone is given along with the number of characters to extract, starting from the first character on the left in the column. The [RIGHT()](../right/index) function is similar, but it starts from the last character on the right, counting left to capture, in this statement, the last seven characters. In the SQL statement above, area\_code is reused to order the results set. To reformat the telephone number, it will be necessary to use the [SUBSTRING()](../substring/index) function.

 
```
SELECT CONCAT('(', LEFT(telephone, 3), ') ',
SUBSTRING(telephone, 4, 3), '-',
MID(telephone, 7)) AS 'Telephone Number'
FROM contacts
ORDER BY LEFT(telephone, 3);

```

In this SQL statement, the [CONCAT()](../concat/index) function is employed to assemble some characters and extracted data to produce a common display for telephone numbers (e.g., (504) 555-1234). The first element of the [CONCAT()](../concat/index) is an opening parenthesis. Next, a [LEFT()](../left/index) is used to get the first three characters of telephone, the area-code. After that a closing parenthesis, along with a space is added to the output. The next element uses the [SUBSTRING()](../substring/index) function to extract the telephone number's prefix, starting at the fourth position, for a total of three characters. Then a dash is inserted into the display. Finally, the function [MID()](../mid/index) extracts the remainder of the telephone number, starting at the seventh position. The functions [MID()](../mid/index) and [SUBSTRING()](../substring/index) are interchangeable and their syntax are the same. By default, for both functions, if the number of characters to capture isn't specified, then it's assumed that the remaining ones are to be extracted.

 #### Manipulating

 There are a few functions in MariaDB that can help in manipulating text. One such function is [REPLACE()](../replace-function/index). With it every occurrence of a search parameter in a string can be replaced. For example, suppose we wanted to replace the title *Mrs.* with *Ms.* in a column containing the person's title, but only in the output. The following SQL would do the trick:

 
```
SELECT CONCAT(REPLACE(title, 'Mrs.', 'Ms.'),
' ', name_first, ' ', name_last) AS Name
FROM contacts;

```

We're using the ever handy [CONCAT()](../concat/index) function to put together the contact's name with spaces. The [REPLACE()](../replace-function/index) function extracts each title and replaces *Mrs.* with *Ms.*, where applicable. Otherwise, for all other titles, it displays them unchanged.

 If we want to insert or replace certain text from a column (but not all of its contents), we could use the [INSERT()](../insert-function/index) function in conjunction with the [LOCATE()](../locate/index) function. For example, suppose another contacts table has the contact's title and full name in one column. To change the occurrences of Mrs. to Ms., we could not use [REPLACE()](../replace-function/index) since the title is embedded in this example. Instead, we would do the following:

 
```
SELECT INSERT(name, LOCATE(name, 'Mrs.'), 4, 'Ms.') 
FROM contacts;

```

The first element of the [INSERT()](../insert-function/index) function is the column. The second element which contains the [LOCATE()](../locate/index) is the position in the string that text is to be inserted. The third element is optional; it states the number of characters to overwrite. In this case, Mrs. which is four characters is overwritten with Ms. (the final element), which is only three. Incidentally, if 0 is specified, then nothing is overwritten, text is inserted only. As for the [LOCATE()](../locate/index) function, the first element is the column and the second the search text. It returns the position within the column where the text is found. If it's not found, then 0 is returned. A value of 0 for the position in the [INSERT()](../insert-function/index) function negates it and returns the value of name unchanged.

 On the odd chance that there is a need to reverse the content of a column, there's the [REVERSE()](../reverse/index) function. You would just place the column name within the function. Another minor function is the [REPEAT()](repeat) function. With it a string may be repeated in the display:

 
```
SELECT REPEAT(col1, 2)
FROM table1;

```

The first component of the function above is the string or column to be repeated. The second component states the number of times it's to be repeated.

 #### Expression Aids

 The function [CHAR\_LENGTH()](../char_length/index) is used to determine the number of characters in a string. This could be useful in a situation where a column contains different types of information of specific lengths. For instance, suppose a column in a table for a college contains identification numbers for students, faculty, and staff. If student identification numbers have eight characters while others have less, the following will count the number of student records:

 
```
SELECT COUNT(school_id)
AS 'Number of Students'
FROM table8
WHERE CHAR_LENGTH(school_id)=8;

```

The [COUNT()](../count/index) function above counts the number of rows that meet the condition of the `WHERE` clause.

 In a [SELECT](../select/index) statement, an [ORDER BY](../select/index#order-by) clause can be used to sort a results set by a specific column. However, if the column contains IP addresses, a simple sort may not produce the desired results:

 
```
SELECT ip_address 
FROM computers WHERE server='Y' 
ORDER BY ip_address LIMIT 3;

+-------------+
| ip_address  |
+-------------+
| 10.0.1.1    |
| 10.0.11.1   |
| 10.0.2.1    |
+-------------+

```

In the limited results above, the IP address 10.0.2.1 should be second. This happens because the column is being sorted lexically and not numerically. The function [INET\_ATON()](../inet_aton/index) will solve this sorting problem.

 
```
SELECT ip_address 
FROM computers WHERE server='Y' 
ORDER BY INET_ATON(ip_address) LIMIT 3;

```

Basically, the [INET\_ATON()](../inet_aton/index) function will convert IP addresses to regular numbers for numeric sorting. For instance, if we were to use the function in the list of columns in a [SELECT](../select/index) statement, instead of the `WHERE` clause, the address 10.0.1.1 would return 167772417, 10.0.11.1 will return 167774977, and 10.0.2.1 the number 167772673. As a complement to [INET\_ATON()](../inet_aton/index), the function [INET\_ATON()](../inet_aton/index) will translate these numbers back to their original IP addresses.

 MariaDB is fairly case insensitive, which usually is fine. However, to be able to check by case, the [STRCMP()](../strcmp/index) function can be used. It converts the column examined to a string and makes a comparison to the search parameter.

 
```
SELECT col1, col2 
FROM table6 
WHERE STRCMP(col3, 'text')=0;

```

If there is an exact match, the function [STRCMP()](../strcmp/index) returns 0. So if `col3` here contains "Text", it won't match. Incidentally, if `col3` alphabetically is before the string to which it's compared, a `-1` will be returned. If it's after it, a `1` is returned.

 When you have list of items in one string, the [SUBSTRING\_INDEX()](../substring_index/index) can be used to pull out a sub-string of data. As an example, suppose we have a column which has five elements, but we want to retrieve just the first two elements. This SQL statement will return them:

 
```
SELECT SUBSTRING_INDEX(col4, '|', 2)
FROM table7;

```

The first component in the function above is the column or string to be picked apart. The second component is the delimiter. The third is the number of elements to return, counting from the left. If we want to grab the last two elements, we would use a negative two to instruct MariaDB to count from the right end.

 #### Conclusion

 There are more string functions available in MariaDB. A few of the functions mentioned here have aliases or close alternatives. There are also functions for converting between ASCII, binary, hexi-decimal, and octal strings. And there are also string functions related to text encryption and decryption that were not mentioned. However, this article has given you a good collection of common string functions that will assist you in building more powerful and accurate SQL statements.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-string-functions/>

Doing Time with MariaDB
=======================

     The recording of date and time in a MariaDB database is a very common requirement. For gathering temporal data, one needs to know which type of columns to use in a table. More importantly is knowing how to record chronological data and how to retrieve it in various formats. Although this is a seemingly basic topic, there are many built-in time functions that can be used for more accurate SQL statements and better formatting of data. In this article we will explore these various aspects of how to do time with MariaDB.

 #### About Time

 Since date and time are only numeric strings, they can be stored in a regular character column. However, by using temporal data type columns, you can make use of several built-in functions offered by MariaDB. Currently, there are five temporal data types available: `DATE`, `TIME`, `DATETIME`, `TIMESTAMP`, and `YEAR`. The `DATE` column type is for recording the date only and is basically in this format: `yyyy-mm-dd`. The `TIME` column type is for recording time in this format: `hhh:mm:ss`. To record a combination of date and time, there is the `DATETIME` column type: `yyyy-mm-dd hh:mm:ss`. The `TIMESTAMP` column is similar to `DATETIME`, but it's a little limited in its range of allowable time. It starts at the Unix epoc time (i.e., 1970-01-01) and ends at the end of 2037. Finally, the `YEAR` data type is for recording only the year in a column: `yy` or `yyyy`. For the examples in this article, `DATE`, `TIME`, and `DATETIME` columns will be used. The database that will be referenced is for a fictitious psychiatry practice that keeps track of its patients and billable hours in MariaDB.

 #### Telling Time

 To record the current date and time in a MariaDB table, there are a few built-in functions that may be used. First, to record the date there are the functions [CURRENT\_DATE](../current_date/index) and [CURDATE( )](../curdate/index) (depending on your style), which both produce the same results (e.g., 2017-08-01). Notice that [CURDATE( )](../curdate/index) requires parentheses and the other does not. With many functions a column name or other variables are placed inside of the parentheses to get a result. With functions like [CURDATE( )](../curdate/index), there is nothing that may go inside the parenthesis. Since these two functions retrieve the current date in the format of the `DATE` column type, they can be used to fill in a `DATE` column when inserting a row:

 
```
INSERT INTO billable_work
(doctor_id, patient_id, session_date)
VALUES('1021', '1256', CURRENT_DATE);

```

The column *session\_date* is a `DATE` column. Notice that there are no quotes around the date function. If there were it would be taken as a literal value rather than a function. Incidentally, I've skipped discussing how the table was set up. If you're not familiar with how to set up a table, you may want to read the [MariaDB Basics](../mariadb-basics/index) article. To see what was just recorded by the [INSERT](../insert/index) statement above, the following may be entered (results follow):

 
```
SELECT rec_id, doctor_id, 
patient_id, session_date
FROM billable_work
WHERE rec_id=LAST_INSERT_ID();

+--------+-----------+------------+--------------+
| rec_id | doctor_id | patient_id | session_date |
+--------+-----------+------------+--------------+
|   2462 | 1021      | 1256       | 2017-08-23   |
+--------+-----------+------------+--------------+

```

Notice in the billable\_work table that the primary key column (i.e., `rec_id`) is an automatically generated and incremental number column (i.e., `AUTO_INCREMENT`). As long as another record is not created or the user does not exit from the mariadb client or otherwise end the session, the [LAST\_INSERT\_ID( )](../last_insert_id/index) function will retrieve the value of the `rec_id` for the last record entered by the user.

 To record the time of an appointment for a patient in a time data type column, [CURRENT\_TIME](../current_time/index) or [CURTIME( )](../curtime/index) are used in the same way to insert the time. The following is entered to update the row created above to mark the starting time of the appointment—another [SELECT](../select/index) statement follows with the results:

 
```
UPDATE billable_work
SET session_time=CURTIME()
WHERE rec_id='2462';

SELECT patient_id, session_date, session_time
FROM billable_work
WHERE rec_id='2462';

+------------+--------------+--------------+
| patient_id | session_date | session_time |
+------------+--------------+--------------+
| 1256       | 2017-08-23   | 10:30:23     |
+------------+--------------+--------------+

```

The column session\_time is a time column. To record the date and time together in the same column, [CURRENT\_TIMESTAMP](../current_timestamp/index) or [SYSDATE( )](../sysdate/index) or [NOW( )](../now/index) can be used. All three functions produce the same time format: `yyyy-mm-dd hh:mm:ss`. Therefore, the column's data type would have to be `DATETIME` to use them.

 #### How to get a Date

 Although MariaDB records the date in a fairly agreeable format, you may want to present the date when it's retrieved in a different format. Or, you may want to extract part of the date, such as only the day of the month. There are many functions for reformatting and selectively retrieving date and time information. To start off with, let's select a column with a data type of `DATE` and look at the functions available for retrieving each component. To extract the year, there's the [YEAR( )](../year/index) function. For extracting just the month, the [MONTH( )](../month/index) function could be called upon. And to grab the day of the month, [DAYOFMONTH( )](../dayofmonth/index) will work. Using the record entered above, here's what an SQL statement and its results would look like in which the session date is broken up into separate parts, but in a different order:

 
```
SELECT MONTH(session_date) AS Month,
DAYOFMONTH(session_date) AS Day,
YEAR(session_date) AS Year
FROM billable_work
WHERE rec_id='2462';

+-------+------+------+
| Month | Day  | Year |
+-------+------+------+
|     8 |   23 | 2017 |
+-------+------+------+

```

For those who aren't familiar with the keyword `AS`, it's used to label a column's output and may be referenced within an SQL statement. Splitting up the elements of a date can be useful in analyzing a particular element. If the bookkeeper of the fictitious psychiatry office needed to determine if the day of the week of each session was on a Saturday because the billing rate would be higher (time and a half), the [DAYOFWEEK( )](../dayofweek/index) function could be used. To spice up the examples, let's wrap the date function up in an [IF( )](../if-function/index) function that tests for the day of the week and sets the billing rate accordingly.

 
```
SELECT patient_id AS 'Patient ID',
session_date AS 'Date of Session',
IF(DAYOFWEEK(session_date)=6, 1.5, 1.0)
  AS 'Billing Rate' 
FROM billable_work
WHERE rec_id='2462';

+-------------+-----------------+--------------+
| Patient ID  | Date of Session | Billing Rate |
+-------------+-----------------+--------------+
|        1256 |    2017-08-23   |          1.5 |
+-------------+-----------------+--------------+

```

Since we've slipped in the [IF( )](../if-function/index) function, we should explain it's format. The test condition is listed first within the parentheses. In this case, the test is checking if the session date is the sixth day of the week. Then, what MariaDB should display is given if the test passes, followed by the result if it fails.

 Similar to the [DAYOFWEEK( )](../dayofweek/index) function, there's also [WEEKDAY( )](../weekday/index). The only difference is that for [DAYOFWEEK( )](../dayofweek/index) the first day of the week is Sunday—with [WEEKDAY( )](../weekday/index) the first day is Monday. Both functions represent the first day with 0 and the last with `6`. Having *Saturday* and *Sunday* symbolized by `5` and `6` can be handy in constructing an IF statement that has a test component like "`WEEKDAY(*session\_date*) > 4`" to determine if a date is a weekend day. This is cleaner than testing for values of `0` and `6`.

 There is a function for determining the day of the year: [DAYOFYEAR( )](../dayofyear/index). It's not used often, but it is available if you ever need it. Occasionally, though, knowing the quarter of a year for a date can be useful for financial accounting. Rather than set up a formula in a script to determine the quarter, the [QUARTER( )](../quarter/index) function can do this easily. For instance, suppose an accountant wants a list of a doctor's sessions for each patient for the previous quarter. These three SQL statements could be entered in sequence to achieve the results that follow:

 
```
SET @LASTQTR:=IF((QUARTER(CURDATE())-1)=0, 
4, QUARTER(CURDATE())-1);

SET @YR:=IF(@LASTQTR=4, 
YEAR(NOW())-1, YEAR(NOW()));

SELECT patient_id AS 'Patient ID', 
COUNT(session_time) 
  AS 'Number of Sessions'
FROM billable_work
WHERE QUARTER(session_date) = @LASTQTR
  AND YEAR(session_date) = @YR
  AND doctor_id='1021'
GROUP BY patient_id
ORDER BY patient_id LIMIT 5;

+------------+--------------------+
| Patient ID | Number of Sessions |
+------------+--------------------+
| 1104       |                 10 |
| 1142       |                  7 |
| 1203       |                 18 |
| 1244       |                  6 |
| 1256       |                 12 |
+------------+--------------------+

```

This example is the most complicated so far. But it's not too difficult to understand if we pull it apart. The first SQL statement sets up a user variable containing the previous quarter (i.e., 1, 2, 3, or 4). This variable will be needed in the other two statements. The [IF( )](../if-function/index) clause in the first statement checks if the quarter of the current date minus one is zero. It will equal zero when it's run during the first quarter of a year. During a first quarter, of course, the previous quarter is the fourth quarter of the previous year. So, if the equation equals zero, then the variable `@LASTQTR` is set to `4`. Otherwise, `@LASTQTR` is set to the value of the current quarter minus one. The second statement is necessary to ensure that the records for the correct year are selected. So, if `@LASTQTR` equals four, then `@YR` needs to equal last year. If not, `@YR` is set to the current year. With the user variables set to the correct quarter and year, the [SELECT](../select/index) statement can be entered. The [COUNT( )](../count/index) function counts the number of appointments that match the `WHERE` clause for each patient based on the [GROUP BY](../select/index#group-by) clause. The `WHERE` clause looks for sessions with a quarter that equals `@LASTQTR` and a year that equals `@YR`, as well as the doctor's identification number. In summary, what we end up with is a set of SQL statements that retrieve the desired information regardless of which quarter or year it's entered.

 #### What is the Time?

 The last section covered how to retrieve pieces of a date column. Now let's look at how to do the same with a time column. To extract just the hour of a time saved in MariaDB, the [HOUR( )](../hour/index) function could be used. For the minute and second, there's [MINUTE( )](../minute/index) and [SECOND( )](../second/index). Let's put them all together in one straightforward [SELECT](../select/index) statement:

 
```
SELECT HOUR(session_time) AS Hour, 
MINUTE(session_time) AS Minute, 
SECOND(session_time) AS Second
FROM billable_work
WHERE rec_id='2462';

+------+--------+--------+
| Hour | Minute | Second |
+------+--------+--------+
|   10 |     30 |     00 |
+------+--------+--------+

```

#### Date & Time Combined

 All of the examples given so far have involved separate columns for date and time. The [EXTRACT( )](../extract/index) function, however, will allow a particular component to be extracted from a combined column type (i.e., `DATETIME` or `TIMESTAMP`). The format is `EXTRACT(*date\_type* FROM *date\_column*)` where *date\_type* is the component to retrieve and *date\_column* is the name of the column from which to extract data. To extract the year, the *date\_type* would be `YEAR`; for month, `MONTH` is used; and for day, there's `DAY`. To extract time elements, `HOUR` is used for hour, `MINUTE` for minute, and `SECOND` for second. Although that's all pretty simple, let's look at an example. Suppose the table billable\_work has a column called `appointment` (a `datetime` column) that contains the date and time for which the appointment was scheduled (as opposed to the time it actually started in `session_time`). To get the hour and minute for a particular date, the following SQL statement will suffice:

 
```
SELECT patient_name AS Patient, 
EXTRACT(HOUR FROM appointment) AS Hour, 
EXTRACT(MINUTE FROM appointment) AS Minute
FROM billable_work, patients
WHERE doctor_id='1021' 
  AND EXTRACT(MONTH FROM appointment)='8' 
  AND EXTRACT(DAY FROM appointment)='30'
  AND billable_work.patient_id =
    patients.patient_id;

```

This statement calls upon another table (`patients`) which holds patient information such as their names. It requires a connecting point between the tables (i.e., the `patient_id` from each table). If you're confused on how to form relationships between tables in a [SELECT](../select/index) statement, you may want to go back and read the [Getting Data from MariaDB](../getting-data-from-mariadb/index) article. The SQL statement above would be used to retrieve the appointments for one doctor for one day, giving results like this:

 
```
+-------------------+------+--------+
| Patient           | Hour | Minute |
+-------------------+------+--------+
| Michael Zabalaoui |   10 |     00 |
| Jerry Neumeyer    |   11 |     00 |
| Richard Stringer  |   13 |     30 |
| Janice Sogard     |   14 |     30 |
+-------------------+------+--------+

```

In this example, the time elements are separated and they don't include the date. With the [EXTRACT( )](../extract/index) function, however, you can also return combined date and time elements. There is `DAY_HOUR` for the day and hour; there's `DAY_MINUTE` for the day, hour, and minute; `DAY_SECOND` for day, hour, minute, and second; and `YEAR_MONTH` for year and month. There are also some time only combinations: `HOUR_MINUTE` for hour and minute; `HOUR_SECOND` for hour, minute, and second; and `MINUTE_SECOND` for minute and second. However, there's not a `MONTH_DAY` to allow the combining of the two extracts in the `WHERE` clause of the last [SELECT](../select/index) statement above. Nevertheless, we'll modify the example above and use the `HOUR_MINUTE` date\_type to retrieve the hour and minute in one resulting column. It would only require the second and third lines to be deleted and replaced with this:

 
```
...
EXTRACT(HOUR_MINUTE FROM appointment) 
  AS Appointment 
...

+-------------------+-------------+
| Patient           | Appointment |
+-------------------+-------------+
| Michael Zabalaoui |        1000 |
| Jerry Neumeyer    |        1100 |
| Richard Stringer  |        1330 |
| Janice Sogard     |        1430 |
+-------------------+-------------+

```

The problem with this output, though, is that the times aren't very pleasing looking. For more natural date and time displays, there are a few simple date formatting functions available and there are the [DATE\_FORMAT( )](../date_format/index) and [TIME\_FORMAT( )](../time_format/index) functions.

 #### Fine Time Pieces

 The simple functions that we mentioned are used for reformatting the output of days and months. To get the date of patient sessions for August, but in a more wordier format, [MONTHNAME( )](../monthname/index) and [DAYNAME( )](../dayname/index) could be used:

 
```
SELECT patient_name AS Patient, 
CONCAT(DAYNAME(appointment), ' - ', 
  MONTHNAME(appointment), ' ', 
  DAYOFMONTH(appointment), ', ', 
  YEAR(appointment)) AS Appointment
FROM billable_work, patients
WHERE doctor_id='1021'
  AND billable_work.patient_id =
    patients.patient_id
  AND appointment>'2017-08-01' 
  AND appointment<'2017-08-31' 
LIMIT 1;

+-------------------+-----------------------------+
| Patient           | Appointment                 |
+-------------------+-----------------------------+
| Michael Zabalaoui | Wednesday - August 30, 2017 |
+-------------------+-----------------------------+

```

In this statement the [CONCAT( )](../concat/index) splices together the results of several date functions along with spaces and other characters. The [EXTRACT( )](../extract/index) function was eliminated from the `WHERE` clause and instead a simple numeric test for sessions in August was given. Although [EXTRACT( )](../extract/index) is fairly straightforward, this all can be accomplished with less typing by using the [DATE\_FORMAT( )](../date_format/index) function.

 The [DATE\_FORMAT( )](../date_format/index) function has over thirty options for formatting the date to your liking. Plus, you can combine the options and add your own separators and other text. The syntax is `DATE_FORMAT(date_column, 'options & characters')`. As an example, let's reproduce the last SQL statement by using the [DATE\_FORMAT( )](../date_format/index) function for formatting the date of the appointment and for scanning for appointments in July only:

 
```
SELECT patient_name AS Patient, 
DATE_FORMAT(appointment, '%W - %M %e, %Y') 
  AS Appointment
FROM billable_work, patients
WHERE doctor_id='1021'
  AND billable_work.patient_id = 
    patients.patient_id
  AND DATE_FORMAT(appointment, '%c') = 8
LIMIT 1;

```

This produces the exact same output as above, but with a more succinct statement. The option `%W` gives the name of the day of the week. The option `%M` provides the month's name. The option `%e` displays the day of the month (`%d` would work, but it left-pads single-digit dates with zeros). Finally, `%Y` is for the four character year. All other elements within the quotes (i.e., the spaces, the dash, and the comma) are literal characters for a nicer display.

 With [DATE\_FORMAT( )](../date_format/index), time elements of a field also can be formatted. For instance, suppose we also wanted the hour and minute of the appointment. We would only need to change the second line of the SQL statement above (to save space, patient\_name was eliminated):

 
```
SELECT 
DATE_FORMAT(appointment, '%W - %M %e, %Y at %r') 
  AS Appointment
...

+--------------------------------------------+
| Appointment                                |
+--------------------------------------------+
| Wednesday - August 30, 2017 at 02:11:19 AM |
+--------------------------------------------+

```

The word at was added along with the formatting option `%r` which gives the time with AM or PM at the end.

 Although it may be a little confusing at first, once you've learned some of the common formatting options, [DATE\_FORMAT( )](../date_format/index) is much easier to use than [EXTRACT( )](../extract/index). There are many more options to [DATE\_FORMAT( )](../date_format/index) that we haven't mentioned. For a complete list of the options available, see the [DATE\_FORMAT( ) documentation page](../date_format/index).

 #### Clean up Time

 In addition to [DATE\_FORMAT( )](../date_format/index), MariaDB has a comparable built-in function for formating only time: [TIME\_FORMAT( )](../time_format/index). The syntax is the same and uses the same options as [DATE\_FORMAT( )](../date_format/index), except only the time related formatting options apply. As an example, here's an SQL statement that a doctor might use at the beginning of each day to get a list of her appointments for the day:

 
```
SELECT patient_name AS Patient, 
TIME_FORMAT(appointment, '%l:%i %p') 
  AS Appointment
FROM billable_work, patients
WHERE doctor_id='1021'
  AND billable_work.patient_id = 
    patients.patient_id
  AND DATE_FORMAT(appointment, '%Y-%m-%d') =
    CURDATE();

+-------------------+-------------+
| Patient           | Appointment |
+-------------------+-------------+
| Michael Zabalaoui |    10:00 AM |
| Jerry Neumeyer    |    11:00 AM |
| Richard Stringer  |    01:30 PM |
| Janice Sogard     |    02:30 PM |
+-------------------+-------------+

```

The option `%l` provides the hours 01 through 12. The `%p` at the end indicates (with the AM or PM) whether the time is before or after noon. The `%i` option gives the minute. The colon and the space are for additional display appeal. Of course, all of this can be done exactly the same way with the [DATE\_FORMAT( )](../date_format/index) function. As for the [DATE\_FORMAT( )](../date_format/index) component in the WHERE clause here, the date is formatted exactly as it will be with [CURDATE( )](../curdate/index) (i.e., 2017-08-30) so that they may be compared properly.

 #### Time to End

 Many developers use PHP, Perl, or some other scripting language with MariaDB. Sometimes developers will solve retrieval problems with longer scripts rather than learn precisely how to extract temporal data with MariaDB. As you can see in several of the examples here (particularly the one using the [QUARTER( )](../quarter/index) function), you can accomplish a great deal within MariaDB. When faced with a potentially complicated SQL statement, try creating it in the mariadb client first. Once you get what you need (under various conditions) and in the format desired, then copy the statement into your script. This practice can greatly help you improve your MariaDB statements and scripting code.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/doing-time-with-mariadb/>

Basic SQL Queries: A Quick SQL Cheat Sheet
==========================================

     This page lists the most important SQL statements and contains links to their documentation pages. If you need a basic tutorial on how to use the MariaDB database server and how to execute simple commands, see [A MariaDB Primer](../a-mariadb-primer/index).

 Also see [Common MariaDB Queries](../common-mariadb-queries/index) for examples of commonly-used queries.

 Defining How Your Data Is Stored
--------------------------------

 * [CREATE DATABASE](../create-database/index) is used to create a new, empty database.
* [DROP DATABASE](../drop-database/index) is used to completely destroy an existing database.
* [USE](../use/index) is used to select a default database.
* [CREATE TABLE](../create-table/index) is used to create a new table, which is where your data is actually stored.
* [ALTER TABLE](../alter-table/index) is used to modify an existing table's definition.
* [DROP TABLE](../drop-table/index) is used to completely destroy an existing table.
* [DESCRIBE](../describe/index) shows the structure of a table.

 Manipulating Your Data
----------------------

 * [SELECT](../select/index) is used when you want to read (or select) your data.
* [INSERT](../insert/index) is used when you want to add (or insert) new data.
* [UPDATE](../update/index) is used when you want to change (or update) existing data.
* [DELETE](../delete/index) is used when you want to remove (or delete) existing data.
* [REPLACE](../replace/index) is used when you want to add or change (or replace) new or existing data.
* [TRUNCATE](../truncate-table/index) is used when you want to empty (or delete) all data from the template.

 Transactions
------------

 * [START TRANSACTION](../start-transaction/index) is used to begin a transaction.
* [COMMIT](../commit/index) is used to apply changes and end transaction.
* [ROLLBACK](../rollback/index) is used to discard changes and end transaction.

 ### A Simple Example

 
```
CREATE DATABASE mydb;
USE mydb;
CREATE TABLE mytable ( id INT PRIMARY KEY, name VARCHAR(20) );
INSERT INTO mytable VALUES ( 1, 'Will' );
INSERT INTO mytable VALUES ( 2, 'Marry' );
INSERT INTO mytable VALUES ( 3, 'Dean' );
SELECT id, name FROM mytable WHERE id = 1;
UPDATE mytable SET name = 'Willy' WHERE id = 1;
SELECT id, name FROM mytable;
DELETE FROM mytable WHERE id = 1;
SELECT id, name FROM mytable;
DROP DATABASE mydb;
SELECT count(1) from mytable; gives the number of records in the table

```


*The first version of this article was copied, with permission, from <http://hashmysql.org/wiki/Basic_SQL_Statements> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/basic-sql-statements/>

Restoring Data from Dump Files
==============================

     If you lose your data in MariaDB, but have been using [mariadb-dump](../mariadb-dump/index) (previously called mysqldump) to make regular backups of your data in MariaDB, you can use the dump files to restore your data. This is the point of the back-ups, after all. To restore a dump file, it's just a matter of having the mariadb client execute all of the SQL statements that the file contains. There are some things to consider before restoring from a dump file, so read this section all of the way through before restoring. One simple and perhaps clumsy method to restore from a dump file is to enter something like the following:

 
```
mariadb --user admin_restore --password < /data/backup/db1.sql

```

Again, this is not using [mariadb-dump](../mariadb-dump/index). The [mariadb-dump](../mariadb-dump/index) utility is only for making back-up copies, not restoring databases. Instead, you would use the mariadb client, which will read the dump file's content in order to batch execute the SQL statements that it contains. Notice that the redirect for `STDOUT` is not used here, but the redirect for the standard input (`STDIN`); the less-than sign is used since the dump file is an input source. Also, notice that in this example a database isn't specified. That's given within the dump file. You may want to stop MariaDB before doing a restore, and then start it again when done.

 #### Restoring One Table

 The problem with restoring from a dump file is that you may overwrite tables or databases that you wish you hadn't. For instance, your dump file might be a few days old and only one table may have been lost. If you restore all of the databases or all of the tables in a database, you would be restoring the data back to it's state at the time of the backup, a few days before. This could be quite a disaster. This is why dumping by database and table can be handy. However, that could be cumbersome.

 A simple and easy method of limiting a restoration would be to create temporarily a user who only has privileges for the table you want to restore. You would enter a [GRANT](../grant/index) statement like this:

 
```
GRANT SELECT
ON db1.* TO 'admin_restore_temp'@'localhost' 
IDENTIFIED BY 'its_pwd';

GRANT ALL ON db1.table1
TO 'admin_restore_temp'@'localhost';

```

These two SQL statements allow the temporary user to have the needed [SELECT](../select/index) privileges on all of the tables of `db1` and `ALL` privileges for the `table1` table. Now when you restore the dump file containing the whole `db1` database, only `table1` will be replaced with the back-up copy. Of course, MariaDB will generate errors. To overlook the errors and to proceed with the restoration of data where no errors are generated (i.e., `table1`), use the `--force` option. Here's what you would enter at the command-line for this situation:

 
```
mariadb --user admin_restore_temp --password --force < /data/backup/db1.sql

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/restoring-data-from-dump-files/>

Making Backups with mariadb-dump
================================

     One of the best utilities to use to make a backup copy of a server's MariaDB's data is [mariadb-dump](../mariadb-dump/index) (previously called [mysqldump](../mysqldump/index), which still works as a symlink). It comes with MariaDB, so it costs you nothing more. Best of all it doesn't require you to shut down MariaDB services to make a backup. It works very simply: it retrieves the data and schema from each database and table and builds a data text file outside of MariaDB. This data text file (known as a dump file) will contain the SQL statements necessary to reconstruct the databases and data. If you were to open a dump file generated by [mariadb-dump](../mariadb-dump/index), you would see CREATE TABLE statements and a multitude of [INSERT](../insert/index) statements, one for each row of data.

 ### Backing Up Everything

 To export all of the databases in MariaDB using [mariadb-dump](../mariadb-dump/index), the following would be entered from the filesystem command-line:

 
```
mariadb-dump -u admin_backup -p -x -A > /data/backup/dbs.sql

```

The first set of options here (`-u *admin\_backup* -p`) tell MariaDB that this utility is to be executed by the user *admin\_backup* and that the user needs to be prompted for a password, which will have to be typed in on the next line when asked. Incidentally, although you might be tempted to just use the root user, you should create a special administrative user as we're using here. If the dump is to be executed by cron by way of a shell script, this option can be changed to `-p*mypwd*`, where *mypwd* is the password—there's no space between the `-p` and the password. The `-x` option has MariaDB lock all of the tables before performing the backup. The lock won't be released until the process is finished. To bundle [INSERT](../insert/index) statements together for each table, we've added the `-e` option. This extended insert option will cause the dump file to be smaller and allow any possible future restores to be executed faster. The `-A` option specifies that all databases are to be exported. Finally, the greater-than sign is a shell redirect of the standard output (STDOUT) to the path and file named after it.

 The example given for backing up all database is the short hand version. The convention is migrating to longer options, not the single letter options. In fact, some are being deprecated and won't be available in the future. So, the above could and should be entered like this:

 
```
mariadb-dump --user=admin_backup --password --lock-tables --all-databases > /data/backup/dbs.sql

```

The longer option names are easier to follow and to remember. Again, if the backup is to be executed by a shell script, the user's password should be listed: `--password=*mypwd*`. Notice that the equal-sign is added when the password is given with the long option name.

 ### Just One Database

 Backing up all of the databases at once with [mariadb-dump](../mariadb-dump/index) may result in one large dump file. This could be take longer to complete the backup and make restoration a bit cumbersome later. Therefore, it might be more useful to stagger backups based on databases, making for possbily several smaller files. You could then backup larger databases during slower traffic times. You might also backup critical databases or ones that are changed much during slower times of the day so that you don't dimish user interaction.

 To export only one database and not all, enter something like the following from the command-line:

 
```
mariadb-dump --user=admin_backup --password --lock-tables --databases db1 > /data/backup/db1.sql

```

The only significant difference in this line is that the `-A` option has been replaced with `-B` and the database to be exported has been given. To export multiple databases, just enter them after the `-B` option, separated by spaces (e.g., `-B db1 db2`).

 ### Dumping Tables

 For very large databases, you may want to backup the data based on tables rather than the whole database. You could backup weekly an entire database and then only backup daily individual tables for which data changes often. To backup just one table, the following could be entered from the command line:

 
```
mariadb-dump --user=admin_backup --password --lock-tables db1 table1 > /data/backup/db1_table1.sql

```

First notice that the `--databases` option has not been included in the line above. The utility assumes that the first name given is a database and the second name is a table name and not another database. To backup multiple tables from a database, just list them after the database name, separated by spaces (e.g., db1 table1 table2).

 ### Conclusion

 As you can see from this article, [mariadb-dump](../mariadb-dump/index) is easy to use and very powerful. In fact, it can clobber your data if you're not careful. Therefore, you should practice using it on a test database—a test server even—a few times until you're comfortable with making backups and restoring them. Don't wait until you've lost your data and in a panic to restore your data to find out that you haven't been backing up your data properly or that you don't know how to fine tune data restoration. Develop some skills in advance and in a safe and controlled way. To learn how to restore dump files, see [Restoring Data From Dump Files](../restoring-data-from-dump-files/index).

 ### Other References

 * [Devart backup tutorial](https://blog.devart.com/mysql-backup-tutorial.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/making-backups-with-mariadb-dump/>

Connecting to MariaDB
=====================

     This article covers connecting to MariaDB and the basic connection parameters. If you are completely new to MariaDB, take a look at [A MariaDB Primer](../a-mariadb-primer/index) first.

 In order to connect to the MariaDB server, the client software must provide the correct connection parameters. The client software will most often be the [mariadb client](../mariadb-client/index), used for entering statements from the command line, but the same concepts apply to any client, such as a [graphical client](../graphical-and-enhanced-clients/index), a client to run backups such as [mariadb-dump](../mariadb-dump/index), etc. The rest of this article assumes that the mariadb command line client is used.

 If a connection parameter is not provided, it will revert to a default value.

 For example, to connect to MariaDB using only default values with the mariadb client, enter the following from the command line:

 
```
mariadb

```

In this case, the following defaults apply:

 * The host name is `localhost`.
* The user name is either your Unix login name, or `ODBC` on Windows.
* No password is sent.
* The client will connect to the server with the default socket, but not any particular database on the server.

 These defaults can be overridden by specifying a particular parameter to use. For example:

 
```
mariadb -h 166.78.144.191 -u username -ppassword database_name

```

In this case:

 * `-h` specifies a host. Instead of using `localhost`, the IP `166.78.144.191` is used.
* `-u` specifies a user name, in this case `username`
* `-p` specifies a password, `password`. Note that for passwords, unlike the other parameters, there cannot be a space between the option (`-p`) and the value (`password`). It is also not secure to use a password in this way, as other users on the system can see it as part of the command that has been run. If you include the `-p` option, but leave out the password, you will be prompted for it, which is more secure.
* The database name is provided as the first argument after all the options, in this case `database_name`.
* It will connect with the default tcp\_ip port, 3306

 Connection Parameters
---------------------

 ### host

 
```
--host=name
-h name

```

Connect to the MariaDB server on the given host. The default host is `localhost`. By default, MariaDB does not permit remote logins - see [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index).

 ### password

 
```
--password[=passwd]
-p[passwd]

```

The password of the MariaDB account. It is generally not secure to enter the password on the command line, as other users on the system can see it as part of the command that has been run. If you include the `-p` or `--password` option, but leave out the password, you will be prompted for it, which is more secure.

 ### pipe

 
```
--pipe
-W

```

On Windows systems that have been started with the `--enable-named-pipe` option, use this option to connect to the server using a named pipe.

 ### port

 
```
--port=num
-P num

```

The TCP/IP port number to use for the connection. The default is `3306`.

 ### protocol

 
```
--protocol=name

```

Specifies the protocol to be used for the connection for the connection. It can be one of `TCP`, `SOCKET`, `PIPE` or `MEMORY` (case-insensitive). Usually you would not want to change this from the default. For example on Unix, a Unix socket file (`SOCKET`) is the default protocol, and usually results in the quickest connection.

 * `TCP`: A TCP/IP connection to a server (either local or remote). Available on all operating systems.
* `SOCKET`: A Unix socket file connection, available to the local server on Unix systems only. If socket is not specified with --socket, in a config file or with the environment variable `MYSQL_UNIX_PORT` then the default `/tmp/mysql.sock` will be used.
* `PIPE`. A named-pipe connection (either local or remote). Available on Windows only.
* `MEMORY`. Shared-memory connection to the local server on Windows systems only.

 ### shared-memory-base-name

 
```
--shared-memory-base-name=name

```

Only available on Windows systems in which the server has been started with the `--shared-memory` option, this specifies the shared-memory name to use for connecting to a local server. The value is case-sensitive, and defaults to `MARIADB`.

 ### socket

 
```
--socket=name
-S name

```

For connections to localhost, this specifies either the Unix socket file to use (default `/tmp/mysql.sock`), or, on Windows where the server has been started with the `--enable-named-pipe` option, the name (case-insensitive) of the named pipe to use (default `MARIADB`).

 ### TLS Options

 A brief listing is provided below. See [Secure Connections Overview](../secure-connections-overview/index) and [TLS System Variables](../tls-system-variables/index) for more detail.

 #### ssl

 
```
--ssl

```

Enable TLS for connection (automatically enabled with other TLS flags). Disable with '`--skip-ssl`'

 #### ssl-ca

 
```
--ssl-ca=name

```

CA file in PEM format (check OpenSSL docs, implies `--ssl`).

 #### ssl-capath

 
```
--ssl-capath=name

```



|  |
| --- |
| CA directory (check OpenSSL docs, implies `--ssl`). |

 #### ssl-cert

 
```
--ssl-cert=name

```

X509 cert in PEM format (implies `--ssl`).

 #### ssl-cipher

 
```
--ssl-cipher=name

```

TLS cipher to use (implies `--ssl`).

 #### ssl-key

 
```
--ssl-key=name

```

X509 key in PEM format (implies `--ssl`).

 #### ssl-crl

 
```
--ssl-crl=name

```

Certificate revocation list (implies `--ssl`).

 #### ssl-crlpath

 
```
--ssl-crlpath=name

```

Certificate revocation list path (implies `--ssl`).

 #### ssl-verify-server-cert

 
```
--ssl-verify-server-cert

```

Verify server's "Common Name" in its cert against hostname used when connecting. This option is disabled by default.

 ### user

 
```
--user=name
-u name

```

The MariaDB user name to use when connecting to the server. The default is either your Unix login name, or `ODBC` on Windows. See the [GRANT](../grant/index) command for details on creating MariaDB user accounts.

 Option Files
------------

 It's also possible to use option files (or configuration files) to set these options. Most clients read option files. Usually, starting a client with the `--help` option will display which files it looks for as well as which option groups it recognizes. 

 See Also
--------

 * [A MariaDB Primer](../a-mariadb-primer/index)
* [mariadb client](../mariadb-client/index)
* [Clients and Utilities](../clients-and-utilities/index)
* [Configuring MariaDB for Remote Client Access](../configuring-mariadb-for-remote-client-access/index)
* [--skip-grant-tables](../mysqld-options/index#-skip-grant-tables) allows you to start MariaDB without `GRANT`. This is useful if you lost your root password.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connecting-to-mariadb/>

Development Articles
=====================

   Articles of interest to MariaDB Developers

  

| Title | Description |
| --- | --- |
|  [General Development Information](../general-development-information/index) |  |
|  [MariaDB Server Releases](../mariadb-server-release-dates/index) |  Information about MariaDB Server releases, release policies and procedures.  |
|  [MariaDB Internals Documentation](../mariadb-internals-documentation/index) |  Documentation on the internal workings of MariaDB.  |
|  [MariaDB Development Tools](../tools/index) |  Tools for developing MariaDB.  |
|  [Debugging MariaDB](../debugging-mariadb/index) |  This section is for articles on debugging MariaDB.  |
|  [Quality](../quality/index) |  This section collects articles related to MariaDB quality assurance efforts.  |
|  [Security Vulnerabilities Fixed in MariaDB](../security/index) |  Security vulnerabilities (CVEs) fixed in MariaDB  |
|  [Security Vulnerabilities Fixed in Oracle MySQL That Did Not Exist in MariaDB](../security-vulnerabilities-in-oracle-mysql-that-did-not-exist-in-mariadb/index) |  Lists of CVEs fixed in MySQL but that were never present in MariaDB.  |
|  [Using Git](../using-git/index) |  Working with the git repository for the source code of MariaDB on GitHub.  |
|  [DBT3 Benchmark Queries](../dbt3-benchmark-queries/index) |  Known things about DBT-3 benchmark and its queries Q1 A simple, one-table query. select  |
|  [EXPLAIN FORMAT=JSON in MySQL](../explain-formatjson-in-mysql/index) |  Listing of things to improve in MySQL's implementation of EXPLAIN FORMAT=JSON  |
|  [HBase Storage Engine](../hbase-storage-engine/index) |  Data mapping from HBase to SQL.  |
|  [LevelDB Storage Engine](../leveldb/index) |  Implementation details on the LevelDB storage engine  |
|  [LevelDB Storage Engine Development](../leveldb-storage-engine-development/index) |  Items under consideration for development of the LevelDB Storage Engine  |
|  [LevelDB Storage Engine MS1](../leveldb-storage-engine-ms1/index) |  MIlestone 1 LevelDB storage engine development  |
|  [LevelDB Storage Engine MS2](../leveldb-storage-engine-ms2/index) |  Milestone 2 LevelDB storage engine development  |
|  [Stuff in MySQL 5.6](../stuff-in-mysql-56/index) |  This is SergeyP's list of patches in MySQL 5.6 that he has found interesti...  |
|  [EXPLAIN FORMAT=JSON Differences From MySQL](../explain-format-json-differences/index) |  Differences between MariaDB's and MySQL's EXPLAIN JSON output.  |
|  [Profiling with Linux perf tool](../profiling-with-linux-perf-tool/index) |  Linux perf tool can be used to do non-intrusive profiling. Frequency Based ...  |
|  [Uploading Package to PPA](../uploading-package-to-ppa/index) |  After creating a Launchpad account: Docker build, cloning the MariaDB repo...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/development-articles/>

InnoDB REDUNDANT Row Format
===========================

    The `REDUNDANT` row format is the original non-compacted row format.

 The `REDUNDANT` row format was the only available row format before MySQL 5.0.3. In that release, this row format was retroactively named the `REDUNDANT` row format. In the same release, the `COMPACT` row format was introduced as the new default row format.

 Using the `REDUNDANT` Row Format
--------------------------------

 The easiest way to create an InnoDB table that uses the `REDUNDANT` row format is by setting the [ROW\_FORMAT](../create-table/index#row_format) table option to `REDUNDANT` in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 It is recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this format.

 The `REDUNDANT` row format is supported by both the `Antelope` and the `Barracuda` [file formats](../innodb-file-format/index), so tables with this row format can be created regardless of the value of the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable.

 For example:

 
```
SET SESSION innodb_strict_mode=ON;

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;

```

Index Prefixes with the `REDUNDANT` Row Format
----------------------------------------------

 The `REDUNDANT` row format supports index prefixes up to 767 bytes.

 Overflow Pages with the `REDUNDANT` Row Format
----------------------------------------------

 All InnoDB row formats can store certain kinds of data in overflow pages. This allows for the maximum row size of an InnoDB table to be larger than the maximum amount of data that can be stored in the row's main data page. See [Maximum Row Size](../innodb-row-formats-overview/index#maximum-row-size) for more information about the other factors that can contribute to the maximum row size for InnoDB tables.

 In the `REDUNDANT` row format variable-length columns, such as columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types, can be partially stored in overflow pages.

 InnoDB only considers using overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If the row size is greater than this, then InnoDB chooses variable-length columns to be stored on overflow pages until the row size is less than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size).

 For [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) columns, only values longer than 767 bytes are considered for for storage on overflow pages. Bytes that are stored to track a value's length do not count towards this limit. This limit is only based on the length of the actual column's data.

 Fixed-length columns greater than 767 bytes are encoded as variable-length columns, so they can also be stored in overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). Even though a column using the [CHAR](../char/index) data type can hold at most 255 characters, a [CHAR](../char/index) column can still exceed 767 bytes in some cases. For example, a `char(255)` column can exceed 767 bytes if the [character set](../character-sets/index) is `utf8mb4`.

 If a column is chosen to be stored on overflow pages, then the first 767 bytes of the column's value and a 20-byte pointer to the column's first overflow page are stored on the main page. Each overflow page is the size of [innodb-system-variables#innodb\_page\_size|innodb\_page\_size]]. If a column is too large to be stored on a single overflow page, then it is stored on multiple overflow pages. Each overflow page contains part of the data and a 20-byte pointer to the next overflow page, if a next page exists.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-redundant-row-format/>

External Tutorials
==================

     Here are some links to external MariaDB, MySQL and SQL tutorials that may be of interest

 MariaDB-Focused Tutorials
-------------------------

 * [Tutorialspoint MariaDB tutorial for beginners](https://www.tutorialspoint.com/mariadb/index.htm)
* [MariaDB Tutorial by "Tech on the net"](https://www.techonthenet.com/mariadb/index.php)
* [Learn MySQL / MariaDB for Beginners](https://www.tecmint.com/learn-mysql-mariadb-for-beginners)
* [MariaDB Tutorial from javatpoint](https://www.javatpoint.com/mariadb-tutorial)

 MySQL-Focused Tutorials (But Should Work For MariaDB Too)
---------------------------------------------------------

 * [mysqltutorial](http://www.mysqltutorial.org). Site with a lot of MySQL usage information and also how to connect to MySQL from different programming languages.
* [MySQL Tutorial for Beginners Learn in 7 Days](https://www.guru99.com/mysql-tutorial.htm)
* [MySQL Tutorial from javatpoint](https://www.javatpoint.com/mysql-tutorial)
* [MySQL Tutorial from w3resource](https://www.w3resource.com/mysql/mysql-tutorials.php)
* [MySQL by Examples for Beginners](http://www.ntu.edu.sg/home/ehchua/programming/sql/mysql_beginner.html)
* [MySQL Tutorial – A Beginner’s Guide To Learn MySQL](https://www.edureka.co/blog/mysql-tutorial/)
* [Php/MySQL Tutorial from tizag](http://www.tizag.com/mysqlTutorial/)
* [PHP & MySQL Tutorial from siteground](https://www.siteground.com/tutorials/php-mysql/)

 General SQL Tutorials
---------------------

 * [w3schools general SQL tutorial](https://www.w3schools.com/sql)
* [sqltutorial](http://www.sqltutorial.org/). Helps you get started with SQL quickly and effectively through many practical examples.

 See Also
--------

 * [MariaDB Knowledge Base Training and Tutorials](../training-tutorials/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/external-tutorials/>

Useful MariaDB Queries
======================

    This page is intended to be a quick reference of commonly-used and/or useful queries in MariaDB.

 Creating a Table
----------------

 
```
CREATE TABLE t1 ( a INT );
CREATE TABLE t2 ( b INT );
CREATE TABLE student_tests (
 name CHAR(10), test CHAR(10), 
 score TINYINT, test_date DATE
);

```

See [CREATE TABLE](../create-table/index) for more.

 Inserting Records
-----------------

 
```
INSERT INTO t1 VALUES (1), (2), (3);
INSERT INTO t2 VALUES (2), (4);

INSERT INTO student_tests 
 (name, test, score, test_date) VALUES
 ('Chun', 'SQL', 75, '2012-11-05'), 
 ('Chun', 'Tuning', 73, '2013-06-14'),
 ('Esben', 'SQL', 43, '2014-02-11'), 
 ('Esben', 'Tuning', 31, '2014-02-09'), 
 ('Kaolin', 'SQL', 56, '2014-01-01'),
 ('Kaolin', 'Tuning', 88, '2013-12-29'), 
 ('Tatiana', 'SQL', 87, '2012-04-28'), 
 ('Tatiana', 'Tuning', 83, '2013-09-30');

```

See [INSERT](../insert/index) for more.

 Using AUTO\_INCREMENT
---------------------

 The AUTO\_INCREMENT attribute is used to automatically generate a unique identity for new rows. 

 
```
CREATE TABLE student_details (
 id INT NOT NULL AUTO_INCREMENT, name CHAR(10), 
 date_of_birth DATE, PRIMARY KEY (id)
);

```

When inserting, the id field can be omitted, and is automatically created.

 
```
INSERT INTO student_details (name,date_of_birth) VALUES 
 ('Chun', '1993-12-31'), 
 ('Esben','1946-01-01'),
 ('Kaolin','1996-07-16'),
 ('Tatiana', '1988-04-13');

SELECT * FROM student_details;
+----+---------+---------------+
| id | name    | date_of_birth |
+----+---------+---------------+
|  1 | Chun    | 1993-12-31    |
|  2 | Esben   | 1946-01-01    |
|  3 | Kaolin  | 1996-07-16    |
|  4 | Tatiana | 1988-04-13    |
+----+---------+---------------+

```

See [AUTO\_INCREMENT](../auto_increment/index) for more.

 Querying from two tables on a common value
------------------------------------------

 
```
SELECT * FROM t1 INNER JOIN t2 ON t1.a = t2.b;

```

This kind of query is called a join - see [JOINS](../joins/index) for more.

 Finding the Maximum Value
-------------------------

 
```
SELECT MAX(a) FROM t1;
+--------+
| MAX(a) |
+--------+
|      3 |
+--------+

```

See the [MAX() function](../max/index) for more, as well as [Finding the maximum value and grouping the results](#finding-the-maximum-value-and-grouping-the-results) below for a more practical example.

 Finding the Minimum Value
-------------------------

 
```
SELECT MIN(a) FROM t1;
+--------+
| MIN(a) |
+--------+
|      1 |
+--------+

```

See the [MIN() function](../min/index) for more.

 Finding the Average Value
-------------------------

 
```
SELECT AVG(a) FROM t1;
+--------+
| AVG(a) |
+--------+
| 2.0000 |
+--------+

```

See the [AVG() function](../avg/index) for more.

 Finding the Maximum Value and Grouping the Results
--------------------------------------------------

 
```
SELECT name, MAX(score) FROM student_tests GROUP BY name;
+---------+------------+
| name    | MAX(score) |
+---------+------------+
| Chun    |         75 |
| Esben   |         43 |
| Kaolin  |         88 |
| Tatiana |         87 |
+---------+------------+

```

See the [MAX() function](../max/index) for more.

 Ordering Results
----------------

 
```
SELECT name, test, score FROM student_tests ORDER BY score DESC;
+---------+--------+-------+
| name    | test   | score |
+---------+--------+-------+
| Kaolin  | Tuning |    88 |
| Tatiana | SQL    |    87 |
| Tatiana | Tuning |    83 |
| Chun    | SQL    |    75 |
| Chun    | Tuning |    73 |
| Kaolin  | SQL    |    56 |
| Esben   | SQL    |    43 |
| Esben   | Tuning |    31 |
+---------+--------+-------+

```

See [ORDER BY](../order-by/index) for more.

 Finding the Row with the Minimum of a Particular Column
-------------------------------------------------------

 In this example, we want to find the lowest test score for any student.

 
```
SELECT name,test, score FROM student_tests WHERE score=(SELECT MIN(score) FROM student);
+-------+--------+-------+
| name  | test   | score |
+-------+--------+-------+
| Esben | Tuning |    31 |
+-------+--------+-------+

```

Finding Rows with the Maximum Value of a Column by Group
--------------------------------------------------------

 This example returns the best test results of each student:

 
```
SELECT name, test, score FROM student_tests st1 WHERE score = (
  SELECT MAX(score) FROM student st2 WHERE st1.name = st2.name
); 
+---------+--------+-------+
| name    | test   | score |
+---------+--------+-------+
| Chun    | SQL    |    75 |
| Esben   | SQL    |    43 |
| Kaolin  | Tuning |    88 |
| Tatiana | SQL    |    87 |
+---------+--------+-------+

```

Calculating Age
---------------

 The [TIMESTAMPDIFF](../timestampdiff/index) function can be used to calculate someone's age:

 
```
SELECT CURDATE() AS today;
+------------+
| today      |
+------------+
| 2014-02-17 |
+------------+

SELECT name, date_of_birth, TIMESTAMPDIFF(YEAR,date_of_birth,'2014-08-02') AS age 
  FROM student_details;
+---------+---------------+------+
| name    | date_of_birth | age  |
+---------+---------------+------+
| Chun    | 1993-12-31    |   20 |
| Esben   | 1946-01-01    |   68 |
| Kaolin  | 1996-07-16    |   18 |
| Tatiana | 1988-04-13    |   26 |
+---------+---------------+------+

```

See [TIMESTAMPDIFF()](../timestampdiff/index) for more.

 Using User-defined Variables
----------------------------

 This example sets a [user-defined variable](../user-defined-variables/index) with the average test score, and then uses it in a later query to return all results above the average.

 
```
SELECT @avg_score:= AVG(score) FROM student_tests;
+-------------------------+
| @avg_score:= AVG(score) |
+-------------------------+
|            67.000000000 |
+-------------------------+

SELECT * FROM student_tests WHERE score > @avg_score;
+---------+--------+-------+------------+
| name    | test   | score | test_date  |
+---------+--------+-------+------------+
| Chun    | SQL    |    75 | 2012-11-05 |
| Chun    | Tuning |    73 | 2013-06-14 |
| Kaolin  | Tuning |    88 | 2013-12-29 |
| Tatiana | SQL    |    87 | 2012-04-28 |
| Tatiana | Tuning |    83 | 2013-09-30 |
+---------+--------+-------+------------+

```

User-defined variables can also be used to add an incremental counter to a resultset:

 
```
SET @count = 0;

SELECT @count := @count + 1 AS counter, name, date_of_birth FROM student_details;
+---------+---------+---------------+
| counter | name    | date_of_birth |
+---------+---------+---------------+
|       1 | Chun    | 1993-12-31    |
|       2 | Esben   | 1946-01-01    |
|       3 | Kaolin  | 1996-07-16    |
|       4 | Tatiana | 1988-04-13    |
+---------+---------+---------------+

```

See [User-defined Variables](../user-defined-variables/index) for more.

 View Tables in Order of Size
----------------------------

 Returns a list of all tables in the database, ordered by size:

 
```
SELECT table_schema as `DB`, table_name AS `Table`, 
  ROUND(((data_length + index_length) / 1024 / 1024), 2) `Size (MB)` 
  FROM information_schema.TABLES 
  ORDER BY (data_length + index_length) DESC;

+--------------------+---------------------------------------+-----------+
| DB                 | Table                                 | Size (MB) |
+--------------------+---------------------------------------+-----------+
| wordpress          | wp_simple_history_contexts            |      7.05 |
| wordpress          | wp_posts                              |      6.59 |
| wordpress          | wp_simple_history                     |      3.05 |
| wordpress          | wp_comments                           |      2.73 |
| wordpress          | wp_commentmeta                        |      2.47 |
| wordpress          | wp_simple_login_log                   |      2.03 |
...

```

Removing Duplicates
-------------------

 
**MariaDB starting with [10.3](../what-is-mariadb-103/index)**The following syntax is only valid [MariaDB 10.3](../what-is-mariadb-103/index) and beyond:

 
This example assumes there's a unique ID, but that all other fields are identical. In the example below, there are 4 records, 3 of which are duplicates, so two of the three duplicates need to be removed. The intermediate SELECT is not necessary, but demonstrates what is being returned.

 
```
CREATE TABLE t (id INT, f1 VARCHAR(2));

INSERT INTO t VALUES (1,'a'), (2,'a'), (3,'b'), (4,'a');

SELECT * FROM t t1, t t2 WHERE t1.f1=t2.f1 AND t1.id<>t2.id AND t1.id=(
  SELECT MAX(id) FROM t tab WHERE tab.f1=t1.f1
);
+------+------+------+------+
| id   | f1   | id   | f1   |
+------+------+------+------+
|    4 | a    |    1 | a    |
|    4 | a    |    2 | a    |
+------+------+------+------+

DELETE FROM t WHERE id IN (
  SELECT t2.id FROM t t1, t t2 WHERE t1.f1=t2.f1 AND t1.id<>t2.id AND t1.id=(
    SELECT MAX(id) FROM t tab WHERE tab.f1=t1.f1
  )
);
Query OK, 2 rows affected (0.120 sec)

SELECT * FROM t;
+------+------+
| id   | f1   |
+------+------+
|    3 | b    |
|    4 | a    |
+------+------

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/useful-mariadb-queries/>

InnoDB COMPACT Row Format
=========================

    
**MariaDB until [10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)**In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, the default row format is `COMPACT`.

  The `COMPACT` row format is similar to the `REDUNDANT` row format, but it stores data in a more compact manner that requires about 20% less storage.

 Using the `COMPACT` Row Format
------------------------------

 
**MariaDB starting with [10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/)**In [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and later, the easiest way to create an InnoDB table that uses the `COMPACT` row format is by setting the [ROW\_FORMAT](../create-table/index#row_format) table option to to `COMPACT` in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 It is recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this row format.

 The `COMPACT` row format is supported by both the `Antelope` and the `Barracuda` [file formats](../xtradbinnodb-file-format/index), so tables with this row format can be created regardless of the value of the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable.

 For example:

 
```
SET SESSION innodb_strict_mode=ON;

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB ROW_FORMAT=COMPACT;

```



**MariaDB until [10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)**In [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/) and before, the default row format is `COMPACT`. Therefore, in these versions, the easiest way to create an InnoDB table that uses the `COMPACT` row format is by **not** setting the [ROW\_FORMAT](../create-table/index#row_format) table option at all in the [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 It is recommended to set the [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) system variable to `ON` when using this row format.

 The `COMPACT` row format is supported by both the `Antelope` and the `Barracuda` [file formats](../innodb-file-format/index), so tables with this row format can be created regardless of the value of the [innodb\_file\_format](../innodb-system-variables/index#innodb_file_format) system variable.

 For example:

 
```
SET SESSION innodb_strict_mode=ON;

CREATE TABLE tab (
   id int,
   str varchar(50)
) ENGINE=InnoDB;

```


Index Prefixes with the `COMPACT` Row Format
--------------------------------------------

 The `COMPACT` row format supports index prefixes up to 767 bytes.

 Overflow Pages with the `COMPACT` Row Format
--------------------------------------------

 All InnoDB row formats can store certain kinds of data in overflow pages. This allows for the maximum row size of an InnoDB table to be larger than the maximum amount of data that can be stored in the row's main data page. See [Maximum Row Size](#maximum-row-size) for more information about the other factors that can contribute to the maximum row size for InnoDB tables.

 In the `COMPACT` row format variable-length columns, such as columns using the [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) data types, can be partially stored in overflow pages.

 InnoDB only considers using overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If the row size is greater than this, then InnoDB chooses variable-length columns to be stored on overflow pages until the row size is less than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size).

 For [VARBINARY](../varbinary/index), [VARCHAR](../varchar/index), [BLOB](../blob/index) and [TEXT](../text/index) columns, only values longer than 767 bytes are considered for storage on overflow pages. Bytes that are stored to track a value's length do not count towards this limit. This limit is only based on the length of the actual column's data.

 Fixed-length columns greater than 767 bytes are encoded as variable-length columns, so they can also be stored in overflow pages if the table's row size is greater than half of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). Even though a column using the [CHAR](../char/index) data type can hold at most 255 characters, a [CHAR](../char/index) column can still exceed 767 bytes in some cases. For example, a `char(255)` column can exceed 767 bytes if the [character set](../character-sets/index) is `utf8mb4`.

 If a column is chosen to be stored on overflow pages, then the first 767 bytes of the column's value and a 20-byte pointer to the column's first overflow page are stored on the main page. Each overflow page is the size of [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size). If a column is too large to be stored on a single overflow page, then it is stored on multiple overflow pages. Each overflow page contains part of the data and a 20-byte pointer to the next overflow page, if a next page exists.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-compact-row-format/>

Changing Times in MariaDB
=========================

     The article entitled, [Doing Time with MariaDB](../doing-time-with-mariadb/index) dealt with time and date columns in MariaDB and how to selectively retrieve and format time and date elements. This article will go a little further by exploring special functions that are available in MariaDB to modify time and date.

 ##### The Nature of Time

 For most of us, there is a morning and an afternoon in each day. Days are measured in either two twelve-hour blocks or one twenty-four-hour block. There are twelve months in a year, with each month consisting of thirty or thirty-one days. The only exception is the month of February which contains twenty-eight days usually, but once every four years it contains twenty-nine. While this all may be rather natural, putting it into a computer program can make it seem very unnatural and frustrating.

 For the scenario in this article we have a MariaDB database in which customers enter work requests through the web. When they enter a trouble ticket, a record is entered into a MariaDB table called, tickets. This record contains several fields, one of which is the date that the ticket was entered called ticket\_date. Another contains the time the ticket was entered. It's called simply, entered. Yet another column is called promised; it's the time that the customer was promised that their problem would be resolved. Both the entered and the promised columns are time data type columns. The value of entered is determined from the current time of the server. The value of promised is determined by adding a number of hours to the value of entered, depending on the urgency of the ticket set by the customer. For instance, tickets marked "ASAP" are to be completed within two hours according to our company's policy. This all works nicely in testing, but occasionally customers create tickets at odd times and on odd days.

 ##### Around the Clock

 Setting aside the potential problems for a moment, let's look at a simple example of how we might add tickets. Suppose we wanted to write a CGI script (in Perl or PHP) that will allow users to create tickets on-line any time. We might use the following SQL statement in our script:

 
```
INSERT INTO tickets
(client_id, urgency, trouble,
ticket_date, entered, promised)
VALUES('$client_id', '$urgency', '$trouble',
CURDATE(), CURTIME(),
SEC_TO_TIME(TIME_TO_SEC(CURTIME()) + 7200));

```

If you're unfamiliar with [INSERT](../insert/index) statements and the use of script variables (e.g., $client\_id), you may want to go back and read an earlier article ([MariaDB Basics](../mariadb-basics/index)) in this series which explains both. For the purposes of this article, however, let's focus on the minor formula in the SQL statement above for calculating the promised time, the last line. The [TIME\_TO\_SEC( )](../time_to_sec/index) function converts a time to seconds so that a calculation may be performed. In this case, the current time is converted to seconds. The formula above then adds 7200 seconds (which is two hours) to that. In order to insert the seconds sum into a time column (i.e., promised), it needs to be converted to a time format. Hence, the calculation is wrapped up in the [SEC\_TO\_TIME( )](../sec_to_time/index) function.

 As nice as the SQL statement above is, a problem arises when a customer runs it at 11:00 p.m (or 23:00 in MariaDB time) and the promised time is to be two hours later. The SQL statement above will calculate a promised time of 25:00. What time is that in human or computer terms? As humans, we know that it's meant to be 1:00 a.m., but MariaDB will need this clarified. One solution would be to place the time formula above inside of an IF clause in MariaDB. To do this, the last line of the SQL statement would be replaced with these lines:

 
```
...
IF((TIME_TO_SEC(CURTIME()) + 7200) < 86400,
SEC_TO_TIME(TIME_TO_SEC(CURTIME()) + 7200),
SEC_TO_TIME((TIME_TO_SEC(CURTIME()) + 7200) - 86400)));

```

The first element in the IF clause is the test. The second piece is the value used if the test passes. The third is the value if the test fails. So, if the total seconds is less than 86,400 (i.e., the number of seconds in one day), then the total seconds of the current time, converted to the time format is to be used. Otherwise, the total seconds of the current time minus 86,400 seconds, converted to the time format is to be used. Incidentally, there's an extra closing parenthesis at the end of this SQL statement excerpt because there was an opening one as part of the `VALUES` clause that's not shown here. Although the statement above works, it's a bit excessive and can be accomplished a little more succinctly if one reconsiders the purpose of the IF clause.

 What we're trying to determine in the IF clause is the number of seconds into the day in which the work was promised to be done, meaning the excess amount of time of the day (i.e., one hour). For such a calculation, the modulo division operator (i.e., the `%`) can be used. The modulo division operator will give the remainder of a division. For instance, the result of `SELECT 14 % 5;` is `4`. That is to say, 5 goes into 14 two complete times with 4 left over. As another example, the result of `SELECT 3 % 5;` is 3; that is to say, 5 goes into 3 zero times with 3 left over. Using this arithmetic operator in the time formula above, we can eliminate the IF clause and use the following to accomplish our task:

 
```
...
SEC_TO_TIME((TIME_TO_SEC(CURTIME()) + 7200) % 86400));

```

If the current time is 23:00, then the time in seconds will be 82,800. The formula above will add 7200 to 82,800 to make 90,000 seconds. The modulo division operator will divide 86,400 into 90,000 one time, giving a remainder of 3600 seconds. The SEC\_TO\_TIME function will then convert 3600 seconds to one hour or 1:00 a.m.

 ##### Today or Tomorrow?

 There is a problem with the results from the formula at the end of the previous section. If the customer is promised 1:00 a.m., is that time today or tomorrow? Again, as humans we know that since the promised time must be after the entered time, it must be 1:00 a.m. on the following day. Since computers don't make these assumptions, though, we'll have to make some adjustments to the tickets table and the SQL statement. To be able to record the date and time in each column, we'll first change the column types of entered and promised from time to datetime. We'll do the following SQL statements to migrate the data and to clean up the table:

 
```
ALTER TABLE tickets,
CHANGE COLUMN entered entered_old TIME,
CHANGE COLUMN promised promised_old TIME,
ADD COLUMN entered DATETIME,
ADD COLUMN promised DATETIME;

UPDATE tickets
SET entered = CONCAT(ticket_date, ' ', entered_old),
promised = CONCAT(ticket_date, ' ', promised_old);

ALTER TABLE tickets,
DROP COLUMN entered_old,
DROP COLUMN promised_old,
DROP COLUMN ticket_date;

```

The first SQL statement above alters the table to change the names of the time columns temporarily and to add the new columns with datetime types. If we were instead just to change the existing time columns to datetime types without this two step process, the data would be clobbered and reset to all zeros. The next SQL statement copies the values of the ticket\_date column and pastes it together with the value of one of the old time columns to come up with the new date and time value for the entered and promised dates and times. The flaw in this statement, of course, is that it doesn't deal with the problems with some promised times that the previous layout caused. In fact, it reinforces it by giving a 1:00 a.m. promised time the date of the entered time. This will either have to be fixed manually if it's important to the developer, or with a script that will compare the two time columns. Either way, it's a little out of the scope of this article, so we'll move on. The last SQL statement above deletes the old time columns and the old date column now that the data has been migrated. By the way, it's a good practice to backup the data before altering a table. Also, you probably would run a [SELECT](../select/index) statement before the last SQL statement above to check the migrated data before dropping the old columns.

 Having changed the column types, we can now use the function [DATE\_ADD( )](../date_add/index), which can deal with times that exceed twenty-four hours so that the problem with times straddling the midnight hour won't reoccur. Therefore, our on-going SQL statement becomes this:

 
```
INSERT INTO tickets
(client_id, urgency, trouble,
entered, promised)
VALUES('$client_id', '$urgency', '$trouble',
NOW(),
DATE_ADD(NOW(), INTERVAL 2 HOUR));

```

First notice that the field ticket\_date was eliminated and [CURTIME()](../curtime/index) was replaced with [NOW( )](../now/index), which provides the date and time in one. In the last line we see [DATE\_ADD( )](../date_add/index): an interval of two hours is added to the date and time now (or rather when the record is created). If the time rolls into the next day, then the date is advanced by one and the correct hour is set accordingly.

 The [DATE\_ADD( )](../date_add/index) function will also allow for the addition of minutes. The directive `HOUR` would be replaced with `MINUTE`. To add both hours and minutes (e.g., two hours and thirty minutes), the last line of the SQL statement above could read like this:

 
```
...
DATE_ADD(NOW(), INTERVAL '2:30' HOUR_MINUTE));

```

If the time in which the statement is run is 11:00 p.m., the result would be 1:30 a.m. on the next day.

 ##### Around the Calendar

 The dilemma that can occur with calculations involving hours that wrap around the clock, can similarly occur with calculations involving days that roll into a new month. This problem was fairly easy to resolve with an arithmetic operator when dealing with a constant like the number of seconds in a day. However, a formula to deal with the various number of days in each month would be very lengthy. For instance, if we were simply to add five days to the date February 27, we would get February 32. Imagine trying to create an SQL statement to figure out whether that's supposed to be March 1, 2, 3, or 4--depending on whether the previous month is a regular month with 30 or 31 days, or the one irregular month with 28 or 29 days, depending on the year.

 Fortunately (as you probably have already guessed), [DATE\_ADD( )](../date_add/index) will solve the month dilemma, as well. If instead of promising that tickets will be resolved within a couple hours of the time they are entered, we promise resolution within five days, the SQL statement would look like this:

 
```
INSERT INTO tickets
(client_id, urgency, trouble,
entered, promised)
VALUES('$client_id', '$urgency', '$trouble',
NOW(),
DATE_ADD(NOW(), INTERVAL 5 DAY));

```

If this statement is run on February 27, then the value of promised would be March 3 or 4, depending on whether it is a leap year. Which one will be determined by the [DATE\_ADD( )](../date_add/index) function, requiring no fancy formula.

 Just as hours and minutes can be mixed with [DATE\_ADD( )](../date_add/index), days and hours can be mixed, as well. To make the value of promised two days and six hours from now, the last line of the SQL statement above would read like this:

 
```
...
DATE_ADD(NOW(), INTERVAL '2 6' DAY_HOUR));

```

The function [DATE\_ADD( )](../date_add/index) will also allow the addition of months and of years. For instance, to increase the date by one year and two months, the SQL statement would be adjusted to look like this:

 
```
...
DATE_ADD(NOW(), INTERVAL '1 2' YEAR_MONTH));

```

This increases the year by one and the month by two. These intervals have no effect on time or day values, though. So, if the value of [NOW( )](../now/index) is `2017-09-15 23:00`, then the value of promised would become 2018-11-15 23:00, regardless of whether next year is a leap year and regardless of the number of days in each intervening month.

 ##### Stepping Back

 It stands to reason that if one wants to add days to the current date, then one will want to subtract days in an equally agreeable manner. For subtracting days we can still use the DATE\_ADD function. Just put a negative sign in front of the interval value like this:

 
```
...
DATE_ADD(NOW(), INTERVAL -5 DAY));

```

This will give a value five days before the current date. An alternative would be to use the [DATE\_SUB( )](../date_sub/index) function which subtracts from the date given. The above amendment (subtracting five days from the current date) could be entered like so:

 
```
...
DATE_SUB(NOW(), INTERVAL 5 DAY));

```

Notice that the 5 is not preceded by a negative sign. If it were, it would have the effect of adding five days.

 ##### Conclusion

 This article along with the previous one on time and date in MariaDB in no way exhaust the topic. There are many more functions and tricks to manipulating temporal values in MariaDB, not to mention what can be done with the extension of a script using a programming language like PHP. Plus, new functions are occasionally being added to MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/changing-times-in-mariadb/>

Subqueries
===========

   A subquery is a query nested in another query.

  

| Title | Description |
| --- | --- |
|  [Scalar Subqueries](../subqueries-scalar-subqueries/index) |  Subquery returning a single value.  |
|  [Row Subqueries](../subqueries-row-subqueries/index) |  Subquery returning a row.  |
|  [Subqueries and ALL](../subqueries-and-all/index) |  Return true if the comparison returns true for each row, or the subquery returns no rows.  |
|  [Subqueries and ANY](../subqueries-and-any/index) |  Return true if the comparison returns true for at least one row returned by the subquery.  |
|  [Subqueries and EXISTS](../subqueries-and-exists/index) |  Returns true if the subquery returns any rows.  |
|  [Subqueries in a FROM Clause](../subqueries-in-a-from-clause/index) |  Subqueries are more commonly placed in a WHERE clause, but can also form part of the FROM clause.  |
|  [Subquery Optimizations](../subquery-optimizations/index) |  Articles about subquery optimizations in MariaDB.  |
|  [Subqueries and JOINs](../subqueries-and-joins/index) |  Rewriting subqueries as JOINs, and using subqueries instead of JOINs.  |
|  [Subquery Limitations](../subquery-limitations/index) |  There are a number of limitations regarding subqueries.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries/>

Getting Data from MariaDB
=========================

     The simplest way to retrieve data from MariaDB is to use the [SELECT](../select/index) statement. Since the [SELECT](../select/index) statement is an essential SQL statement, it has many options available with it. It's not necessary to know or use them all—you could execute very basic [SELECT](../select/index) statements if that satisfies your needs. However, as you use MariaDB more, you may need more powerful [SELECT](../select/index) statements. In this article we will go through the basics of [SELECT](../select/index) and will progress to more involved [SELECT](../select/index) statements;we will move from the beginner level to the more intermediate and hopefully you will find some benefit from this article regardless of your skill level. For absolute beginners who are just starting with MariaDB, you may want to read the [MariaDB Basics article](../mariadb-basics/index).

 #### Basic Elements

 The basic, minimal elements of the [SELECT](../select/index) statement call for the keyword `SELECT`, of course, the columns to select or to retrieve, and the table from which to retrieve rows of data. Actually, for the columns to select, we can use the asterisk as a wildcard to select all columns in a particular table. Using a database from a fictitious bookstore, we might enter the following SQL statement to get a list of all columns and rows in a table containing information on books:

 
```
SELECT * FROM books;

```

This will retrieve all of the data contained in the `books` table. If we want to retrieve only certain columns, we would list them in place of the asterisk in a comma-separated list like so:

 
```
SELECT isbn, title, author_id
FROM books;

```

This narrows the width of the results set by retrieving only three columns, but it still retrieves all of the rows in the table. If the table contains thousands of rows of data, this may be more data than we want. If we want to limit the results to just a few books, say five, we would include what is known as a [LIMIT](../select/index#limit) clause:

 
```
SELECT isbn, title, author_id
FROM books 
LIMIT 5;

```

This will give us the first five rows found in the table. If we want to get the next ten found, we would add a starting point parameter just before the number of rows to display, separated by a comma:

 
```
SELECT isbn, title, author_id
FROM books 
LIMIT 5, 10;

```

#### Selectivity and Order

 The previous statements have narrowed the number of columns and rows retrieved, but they haven't been very selective. Suppose that we want only books written by a certain author, say Dostoevsky. Looking in the authors table we find that his author identification number is 4729. Using a `WHERE` clause, we can retrieve a list of books from the database for this particular author like so:

 
```
SELECT isbn, title
FROM books
WHERE author_id = 4729
LIMIT 5;

```

I removed the author\_id from the list of columns to select, but left the basic [LIMIT](../select/index#limit) clause in because we want to point out that the syntax is fairly strict on ordering of clauses and flags. You can't enter them in any order. You'll get an error in return.

 The SQL statements we've looked at thus far will display the titles of books in the order in which they're found in the database. If we want to put the results in alphanumeric order based on the values of the title column, for instance, we would add an [ORDER BY](../select/index#order-by) clause like this:

 
```
SELECT isbn, title
FROM books
WHERE author_id = 4729
ORDER BY title ASC
LIMIT 5;

```

Notice that the [ORDER BY](../select/index#order-by) clause goes after the `WHERE` clause and before the [LIMIT](../select/index#limit) clause. Not only will this statement display the rows in order by book title, but it will retrieve only the first five based on the ordering. That is to say, MariaDB will first retrieve all of the rows based on the `WHERE` clause, order the data based on the [ORDER BY](../select/index#order-by) clause, and then display a limited number of rows based on the [LIMIT](../select/index#limit) clause. Hence the reason for the order of clauses. You may have noticed that we slipped in the ASC flag. It tells MariaDB to order the rows in ascending order for the column name it follows. It's not necessary, though, since ascending order is the default. However, if we want to display data in descending order, we would replace the flag with `DESC`. To order by more than one column, additional columns may be given in the [ORDER BY](../select/index#order-by) clause in a comma separated list, each with the `ASC` or `DESC` flags if preferred.

 #### Friendlier and More Complicated

 So far we've been working with one table of data containing information on books for a fictitious bookstore. A database will usually have more than one table, of course. In this particular database, there's also one called authors in which the name and other information on authors is contained. To be able to select data from two tables in one [SELECT](../select/index) statement, we will have to tell MariaDB that we want to join the tables and will need to provide a join point. This can be done with a [JOIN](../join-syntax/index) clause as shown in the following SQL statement, with the results following it:

 
```
SELECT isbn, title, 
CONCAT(name_first, ' ', name_last) AS author
FROM books
JOIN authors USING (author_id)
WHERE name_last = 'Dostoevsky'
ORDER BY title ASC
LIMIT 5;

+-------------+------------------------+-------------------+
| isbn        | title                  | author            |
+-------------+------------------------+-------------------+
|  0553212168 | Brothers Karamozov     | Fyodor Dostoevsky |
|  0679420290 | Crime & Punishment     | Fyodor Dostoevsky |
|  0553211757 | Crime & Punishment     | Fyodor Dostoevsky |
|  0192834118 | Idiot                  | Fyodor Dostoevsky |
|  067973452X | Notes from Underground | Fyodor Dostoevsky |
+-------------+------------------------+-------------------+
5 rows in set (0.00 sec) 

```

Our [SELECT](../select/index) statement is getting hefty, but it's the same one to which we've been adding. Don't let the clutter fluster you. Looking for the new elements, let's focus on the [JOIN](../join-syntax/index) clause first. There are a few possible ways to construct a join. This method works if you're using a newer version of MariaDB and if both tables contain a column of the same name and value. Otherwise you'll have to redo the [JOIN](../join-syntax/index) clause to look something like this:

 
```
...
JOIN authors ON author_id = row_id
...

```

This excerpt is based on the assumption that the key field in the authors table is not called author\_id, but row\_id instead. There's much more that can be said about joins, but that would make for a much longer article. If you want to learn more on joins, look at MariaDB's documentation page on [JOIN](../join-syntax/index) syntax.

 Looking again at the last full SQL statement above, you must have spotted the [CONCAT()](../concat/index) function that we added to the on-going example statement. This string function takes the values of the columns and strings given and pastes them together, to give one neat field in the results. We also employed the AS parameter to change the heading of the results set for the field to author. This is much tider. Since we joined the books and the authors tables together, we were able to search for books based on the author's last name rather than having to look up the author ID first. This is a much friendlier method, albeit more complicated. Incidentally, we can have MariaDB check columns from both tables to narrow our search. We would just add *column = value* pairs, separated by commas in the WHERE clause. Notice that the string containing the author's name is wrapped in quotes—otherwise, the string would be considered a column name and we'd get an error.

 The name Dostoevsky is sometimes spelled Dostoevskii, as well as a few other ways. If we're not sure how it's spelled in the authors table, we could use the [LIKE](../like/index) operator instead of the equal-sign, along with a wildcard. If we think the author's name is probably spelled either of the two ways mentioned, we could enter something like this:

 
```
SELECT isbn, title, 
CONCAT(name_first, ' ', name_last) AS author
FROM books
JOIN authors USING (author_id)
WHERE name_last LIKE 'Dostoevsk%'
ORDER BY title ASC
LIMIT 5;

```

This will match any author last name starting with Dostoevsk. Notice that the wildcard here is not an asterisk, but a percent-sign.

 #### Some Flags

 There are many flags or parameters that can be used in a [SELECT](../select/index) statement. To list and explain all of them with examples would make this a very lengthy article. The reality is that most people never use some of them anyway. So, let's take a look at a few that you may find useful as you get more involved with MariaDB or if you work with large tables on very active servers.

 The first flag that may be given, it goes immediately after the `SELECT` keyword, is `ALL`. By default, all rows that meet the requirements of the various clauses given are selected, so this isn't necessary. If instead we would only want the first occurrence of a particular criteria to be displayed, we could add the [DISTINCT](../select/index#distinct) option. For instance, for authors like Dostoevsky there will be several printings of a particular title. In the results shown earlier you may have noticed that there were two copies of *Crime & Punishment* listed, however they have different ISBN numbers and different publishers. Suppose that for our search we only want one row displayed for each title. We could do that like so:

 
```
SELECT DISTINCT isbn, title
FROM books
JOIN authors USING (author_id)
WHERE name_last = 'Dostoevsky'
ORDER BY title;

```

We've thinned out the ongoing SQL statement a bit for clarity. This statement will result in only one row displayed for *Crime & Punishment* and it will be the first one found.

 If we're retrieving data from an extremely busy database, by default any other SQL statements entered simultaneously which are changing or updating data will be executed before a [SELECT](../select/index) statement. [SELECT](../select/index) statements are considered to be of lower priority. However, if we would like a particular [SELECT](../select/index) statement to be given a higher priority, we can add the keyword HIGH\_PRIORITY. Modifying the previous SQL statement for this factor, we would enter it like this:

 
```
SELECT DISTINCT HIGH_PRIORITY isbn, title
FROM books
JOIN authors USING (author_id)
WHERE name_last = 'Dostoevsky'
ORDER BY title;

```

You may have noticed in the one example earlier in which the results are shown, that there's a status line displayed that specifies the number of rows in the results set. This is less than the number of rows that were found in the database that met the statement's criteria. It's less because we used a [LIMIT](../select/index#limit) clause. If we add the [SQL\_CALC\_FOUND\_ROWS](../select/index#sql_calc_found_rows) flag just before the column list, MariaDB will calculate the number of columns found even if there is a [LIMIT](../select/index#limit) clause.

 
```
SELECT SQL_CALC_FOUND_ROWS isbn, title
FROM books
JOIN authors USING (author_id)
WHERE name_last = 'Dostoevsky'
LIMIT 5;

```

To retrieve this information, though, we will have to use the [FOUND\_ROWS()](../found_rows/index) function like so:

 
```
SELECT FOUND_ROWS();

+--------------+
| FOUND_ROWS() |
+--------------+
|           26 |
+--------------+

```

This value is temporary and will be lost if the connection is terminated. It cannot be retrieved by any other client session. It relates only to the current session and the value for the variable when it was last calculated.

 #### Conclusion

 There are several more parameters and possibilities for the [SELECT](../select/index) statement that we had to skip to keep this article a reasonable length. A popular one that we left out is the [GROUP BY](../select/index#group-by) clause for calculating aggregate data for columns (e.g., an average). There are several flags for caching results and a clause for exporting a results set to a text file. If you would like to learn more about [SELECT](../select/index) and all of the options available, look at the on-line documentation for [SELECT](../select/index) statements.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/getting-data-from-mariadb/>

Invisible Columns
=================

    
**MariaDB starting with [10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/)**Invisible columns (sometimes also called hidden columns) first appeared in [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/).

 
Columns can be given an `INVISIBLE` attribute in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement. These columns will then not be listed in the results of a [SELECT \*](../select/index) statement, nor do they need to be assigned a value in an [INSERT](../insert/index) statement, unless INSERT explicitly mentions them by name.

 Since `SELECT *` does not return the invisible columns, new tables or views created in this manner will have no trace of the invisible columns. If specifically referenced in the SELECT statement, the columns will be brought into the view/new table, but the INVISIBLE attribute will not.

 Invisible columns can be declared as `NOT NULL`, but then require a `DEFAULT` value.

 It is not possible for all columns in a table to be invisible.

 Examples
--------

 
```
CREATE TABLE t (x INT INVISIBLE);
ERROR 1113 (42000): A table must have at least 1 column

CREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL);
ERROR 4106 (HY000): Invisible column `z` must have a default value

CREATE TABLE t (x INT, y INT INVISIBLE, z INT INVISIBLE NOT NULL DEFAULT 4);

INSERT INTO t VALUES (1),(2);

INSERT INTO t (x,y) VALUES (3,33);

SELECT * FROM t;
+------+
| x    |
+------+
|    1 |
|    2 |
|    3 |
+------+

SELECT x,y,z FROM t;
+------+------+---+
| x    | y    | z |
+------+------+---+
|    1 | NULL | 4 |
|    2 | NULL | 4 |
|    3 |   33 | 4 |
+------+------+---+

DESC t;
+-------+---------+------+-----+---------+-----------+
| Field | Type    | Null | Key | Default | Extra     |
+-------+---------+------+-----+---------+-----------+
| x     | int(11) | YES  |     | NULL    |           |
| y     | int(11) | YES  |     | NULL    | INVISIBLE |
| z     | int(11) | NO   |     | 4       | INVISIBLE |
+-------+---------+------+-----+---------+-----------+

ALTER TABLE t MODIFY x INT INVISIBLE, MODIFY y INT, MODIFY z INT NOT NULL DEFAULT 4;

DESC t;
+-------+---------+------+-----+---------+-----------+
| Field | Type    | Null | Key | Default | Extra     |
+-------+---------+------+-----+---------+-----------+
| x     | int(11) | YES  |     | NULL    | INVISIBLE |
| y     | int(11) | YES  |     | NULL    |           |
| z     | int(11) | NO   |     | 4       |           |
+-------+---------+------+-----+---------+-----------+

```

Creating a view from a table with hidden columns:

 
```
CREATE VIEW v1 AS SELECT * FROM t;

DESC v1;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| y     | int(11) | YES  |     | NULL    |       |
| z     | int(11) | NO   |     | 4       |       |
+-------+---------+------+-----+---------+-------+

CREATE VIEW v2 AS SELECT x,y,z FROM t;

DESC v2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| x     | int(11) | YES  |     | NULL    |       |
| y     | int(11) | YES  |     | NULL    |       |
| z     | int(11) | NO   |     | 4       |       |
+-------+---------+------+-----+---------+-------+

```

Adding a Surrogate Primary Key:

 
```
create table t1 (x bigint unsigned not null, y varchar(16), z text);

insert into t1 values (123, 'qq11', 'ipsum');

insert into t1 values (123, 'qq22', 'lorem');

alter table t1 add pkid serial primary key invisible first;

insert into t1 values (123, 'qq33', 'amet');

select * from t1;
+-----+------+-------+
| x   | y    | z     |
+-----+------+-------+
| 123 | qq11 | ipsum |
| 123 | qq22 | lorem |
| 123 | qq33 | amet  |
+-----+------+-------+

select pkid, z from t1;
+------+-------+
| pkid | z     |
+------+-------+
|    1 | ipsum |
|    2 | lorem |
|    3 | amet  |
+------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/invisible-columns/>

InnoDB Persistent Statistics
============================

    Before [MariaDB 10.0](../what-is-mariadb-100/index), InnoDB statistics were not stored on disk, meaning that on server restarts the statistics would need to be recalculated, which is both needless computation, as well as leading to inconsistent query plans.

 There are a number of variables that control persistent statistics:

 * [innodb\_stats\_persistent](../xtradbinnodb-server-system-variables/index#innodb_stats_persistent) - when set (the default) enables InnoDB persistent statistics.
* [innodb\_stats\_auto\_recalc](../xtradbinnodb-server-system-variables/index#innodb_stats_auto_recalc) - when set (the default), persistent statistics are automatically recalculated when the table changes significantly (more than 10% of the rows)
* [innodb\_stats\_persistent\_sample\_pages](../xtradbinnodb-server-system-variables/index#innodb_stats_persistent_sample_pages) - Number of index pages sampled (default 20) when estimating cardinality and statistics for indexed columns. Increasing this value will increases index statistics accuracy, but use more I/O resources when running [ANALYZE TABLE](../analyze-table/index).

 These settings can be overwritten on a per-table basis by use of the [STATS\_PERSISTENT](../create-table/index#stats_persistent), [STATS\_AUTO\_RECALC](../create-table/index#stats_auto_recalc) and [STATS\_SAMPLE\_PAGES](../create-table/index#stats_sample_pages) clauses in a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement.

 Details of the statistics are stored in two system tables in the [mysql database](the-mysql-database-table):

 * [innodb\_table\_stats](../mysqlinnodb_table_stats/index)
* [innodb\_index\_stats](../mysqlinnodb_index_stats/index)

 See Also
--------

 * [Index Statistics](../index-statistics/index)
* [Engine-independent Statistics](../engine-independent-table-statistics/index)
* [Histogram-based Statistics](../histogram-based-statistics/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-persistent-statistics/>

CREATE LOGFILE GROUP
====================

    
The `CREATE LOGFILE GROUP` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See [MDEV-19295](https://jira.mariadb.org/browse/MDEV-19295) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-logfile-group/>

CREATE PACKAGE
==============

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
CREATE
    [ OR REPLACE]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    PACKAGE [ IF NOT EXISTS ]
    [ db_name . ] package_name
    [ package_characteristic ... ]
{ AS | IS }
    [ package_specification_element ... ]
END [ package_name ]


package_characteristic:
    COMMENT 'string'
  | SQL SECURITY { DEFINER | INVOKER }


package_specification_element:
    FUNCTION_SYM package_specification_function ;
  | PROCEDURE_SYM package_specification_procedure ;


package_specification_function:
    func_name [ ( func_param [, func_param]... ) ]
    RETURNS func_return_type
    [ package_routine_characteristic... ]

package_specification_procedure:
    proc_name [ ( proc_param [, proc_param]... ) ]
    [ package_routine_characteristic... ]

func_return_type:
    type

func_param:
    param_name [ IN | OUT | INOUT | IN OUT ] type

proc_param:
    param_name [ IN | OUT | INOUT | IN OUT ] type

type:
    Any valid MariaDB explicit or anchored data type


package_routine_characteristic:
      COMMENT  'string'
    | LANGUAGE SQL
    | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
    | SQL SECURITY { DEFINER | INVOKER }

```
 Description
-----------

 The `CREATE PACKAGE` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 The `CREATE PACKAGE` creates the specification for a stored package (a collection of logically related stored objects). A stored package specification declares public routines (procedures and functions) of the package, but does not implement these routines.

 A package whose specification was created by the `CREATE PACKAGE` statement, should later be implemented using the [CREATE PACKAGE BODY](../create-package-body/index) statement.

 Function parameter quantifiers IN | OUT | INOUT | IN OUT
--------------------------------------------------------

 
**MariaDB starting with [10.8.0](https://mariadb.com/kb/en/mariadb-1080-release-notes/)**The function parameter quantifiers for `IN`, `OUT`, `INOUT`, and `IN OUT` where added in a 10.8.0 preview release. Prior to 10.8.0 quantifiers were supported only in procedures.

 
`OUT`, `INOUT` and its equivalent `IN OUT`, are only valid if called from `SET` and not `SELECT`. These quantifiers are especially useful for creating functions and procedures with more than one return value. This allows functions and procedures to be more complex and nested. 

 Examples
--------

 
```
SET sql_mode=ORACLE;
DELIMITER $$
CREATE OR REPLACE PACKAGE employee_tools AS
  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
  PROCEDURE raiseSalaryStd(eid INT);
  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END;
$$
DELIMITER ;

```

See Also
--------

 * [CREATE PACKAGE BODY](../create-package-body/index)
* [SHOW CREATE PACKAGE](../show-create-package/index)
* [DROP PACKAGE](../drop-package/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-package/>

CREATE PACKAGE BODY
===================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
CREATE [ OR REPLACE ]
    [DEFINER = { user | CURRENT_USER | role | CURRENT_ROLE }]
    PACKAGE BODY
    [ IF NOT EXISTS ]
    [ db_name . ] package_name
    [ package_characteristic... ]
{ AS | IS }
    package_implementation_declare_section
    package_implementation_executable_section
END [ package_name]


package_implementation_declare_section:
    package_implementation_item_declaration
      [ package_implementation_item_declaration... ]
      [ package_implementation_routine_definition... ]
  | package_implementation_routine_definition
      [ package_implementation_routine_definition...]

package_implementation_item_declaration:
    variable_declaration ;

variable_declaration:
    variable_name[,...] type [:= expr ]

package_implementation_routine_definition:
    FUNCTION package_specification_function
       [ package_implementation_function_body ] ;
  | PROCEDURE package_specification_procedure
       [ package_implementation_procedure_body ] ;


package_implementation_function_body:
    { AS | IS } package_routine_body [func_name]

package_implementation_procedure_body:
    { AS | IS } package_routine_body [proc_name]

package_routine_body:
    [ package_routine_declarations ]
    BEGIN
      statements [ EXCEPTION exception_handlers ]
    END


package_routine_declarations:
    package_routine_declaration ';' [package_routine_declaration ';']...


package_routine_declaration:
          variable_declaration
        | condition_name CONDITION FOR condition_value
        | user_exception_name EXCEPTION
        | CURSOR_SYM cursor_name
          [ ( cursor_formal_parameters ) ]
          IS select_statement
        ;


package_implementation_executable_section:
          END
        | BEGIN
            statement ; [statement ; ]...
          [EXCEPTION exception_handlers]
          END

exception_handlers:
           exception_handler [exception_handler...]

exception_handler:
          WHEN_SYM condition_value [, condition_value]...
            THEN_SYM statement ; [statement ;]...

condition_value:
          condition_name
        | user_exception_name
        | SQLWARNING
        | SQLEXCEPTION
        | NOT FOUND
        | OTHERS_SYM
        | SQLSTATE [VALUE] sqlstate_value
        | mariadb_error_code


```
 Description
-----------

 The `CREATE PACKAGE BODY` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 The `CREATE PACKAGE BODY` statement creates the package body for a stored package. The package specification must be previously created using the [CREATE PACKAGE](../create-package/index) statement.

 A package body provides implementations of the package public routines and can optionally have:

 * package-wide private variables
* package private routines
* forward declarations for private routines
* an executable initialization section

 Examples
--------

 
```
SET sql_mode=ORACLE;
DELIMITER $$
CREATE OR REPLACE PACKAGE employee_tools AS
  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2);
  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2));
  PROCEDURE raiseSalaryStd(eid INT);
  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2));
END;
$$
CREATE PACKAGE BODY employee_tools AS
  -- package body variables
  stdRaiseAmount DECIMAL(10,2):=500;

  -- private routines
  PROCEDURE log (eid INT, ecmnt TEXT) AS
  BEGIN
    INSERT INTO employee_log (id, cmnt) VALUES (eid, ecmnt);
  END;

  -- public routines
  PROCEDURE hire(ename TEXT, esalary DECIMAL(10,2)) AS
    eid INT;
  BEGIN
    INSERT INTO employee (name, salary) VALUES (ename, esalary);
    eid:= last_insert_id();
    log(eid, 'hire ' || ename);
  END;

  FUNCTION getSalary(eid INT) RETURN DECIMAL(10,2) AS
    nSalary DECIMAL(10,2);
  BEGIN
    SELECT salary INTO nSalary FROM employee WHERE id=eid;
    log(eid, 'getSalary id=' || eid || ' salary=' || nSalary);
    RETURN nSalary;
  END;

  PROCEDURE raiseSalary(eid INT, amount DECIMAL(10,2)) AS
  BEGIN
    UPDATE employee SET salary=salary+amount WHERE id=eid;
    log(eid, 'raiseSalary id=' || eid || ' amount=' || amount);
  END;

  PROCEDURE raiseSalaryStd(eid INT) AS
  BEGIN
    raiseSalary(eid, stdRaiseAmount);
    log(eid, 'raiseSalaryStd id=' || eid);
  END;

BEGIN
  -- This code is executed when the current session
  -- accesses any of the package routines for the first time
  log(0, 'Session ' || connection_id() || ' ' || current_user || ' started');
END;
$$

DELIMITER ;

```

See Also
--------

 * [CREATE PACKAGE](../create-package/index)
* [SHOW CREATE PACKAGE BODY](../show-create-package-body/index)
* [DROP PACKAGE BODY](../drop-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create-package-body/>

Silent Column Changes
=====================

    When a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) command is issued, MariaDB will silently change a column specification in the following cases:

 * [PRIMARY KEY](../getting-started-with-indexes/index#primary-key) columns are always NOT NULL.
* Any trailing spaces from [SET](../set-data-type/index) and [ENUM](../enum/index) values are discarded.
* [TIMESTAMP](../timestamp/index) columns are always NOT NULL, and display sizes are discarded
* A row-size limit of 65535 bytes applies
* If [strict SQL mode](../sql-mode/index#strict-mode) is not enabled (it is enabled by default from [MariaDB 10.2](../what-is-mariadb-102/index)), a [VARCHAR](../varchar/index) column longer than 65535 become [TEXT](../text/index), and a [VARBINARY](../varbinary/index) columns longer than 65535 becomes a [BLOB](../blob/index). If strict mode is enabled the silent changes will not be made, and an error will occur.
* If a USING clause specifies an index that's not permitted by the storage engine, the engine will instead use another available index type that can be applied without affecting results.
* If the CHARACTER SET binary attribute is specified, the column is created as the matching binary data type. A TEXT becomes a BLOB, CHAR a BINARY and VARCHAR a VARBINARY. ENUMs and SETs are created as defined.

 To ease imports from other RDBMSs, MariaDB will also silently map the following data types:

 


| Other Vendor Type | MariaDB Type |
| --- | --- |
| BOOL | [TINYINT](../tinyint/index) |
| BOOLEAN | [TINYINT](../tinyint/index) |
| CHARACTER VARYING(M) | [VARCHAR](../varchar/index)(M) |
| FIXED | [DECIMAL](../decimal/index) |
| FLOAT4 | [FLOAT](../float/index) |
| FLOAT8 | [DOUBLE](../double/index) |
| INT1 | [TINYINT](../tinyint/index) |
| INT2 | [SMALLINT](../smallint/index) |
| INT3 | [MEDIUMINT](../mediumint/index) |
| INT4 | [INT](../int/index) |
| INT8 | [BIGINT](../bigint/index) |
| LONG VARBINARY | [MEDIUMBLOB](../mediumblob/index) |
| LONG VARCHAR | [MEDIUMTEXT](../mediumtext/index) |
| LONG | [MEDIUMTEXT](../mediumtext/index) |
| MIDDLEINT | [MEDIUMINT](../mediumint/index) |
| NUMERIC | [DECIMAL](../decimal/index) |

 
Currently, all MySQL types are supported in MariaDB.

 For type mapping between Cassandra and MariaDB, see [Cassandra storage engine](../cassandra-storage-engine/index#datatypes).

 Example
-------

 Silent changes in action:

 
```
CREATE TABLE SilenceIsGolden
   (
    f1 TEXT CHARACTER SET binary,
    f2 VARCHAR(15) CHARACTER SET binary,
    f3 CHAR CHARACTER SET binary,
    f4 ENUM('x','y','z') CHARACTER SET binary,
    f5 VARCHAR (65536),
    f6 VARBINARY (65536),
    f7 INT1
   );
Query OK, 0 rows affected, 2 warnings (0.31 sec)

SHOW WARNINGS;
+-------+------+-----------------------------------------------+
| Level | Code | Message                                       |
+-------+------+-----------------------------------------------+
| Note  | 1246 | Converting column 'f5' from VARCHAR to TEXT   |
| Note  | 1246 | Converting column 'f6' from VARBINARY to BLOB |
+-------+------+-----------------------------------------------+

DESCRIBE SilenceIsGolden;
+-------+-------------------+------+-----+---------+-------+
| Field | Type              | Null | Key | Default | Extra |
+-------+-------------------+------+-----+---------+-------+
| f1    | blob              | YES  |     | NULL    |       |
| f2    | varbinary(15)     | YES  |     | NULL    |       |
| f3    | binary(1)         | YES  |     | NULL    |       |
| f4    | enum('x','y','z') | YES  |     | NULL    |       |
| f5    | mediumtext        | YES  |     | NULL    |       |
| f6    | mediumblob        | YES  |     | NULL    |       |
| f7    | tinyint(4)        | YES  |     | NULL    |       |
+-------+-------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/silent-column-changes/>

Performance Schema events\_stages\_current Table
================================================

    The `events_stages_current` table contains current stage events, with each row being a record of a thread and its most recent stage event.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if the event has not ended or timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if the event has not ended or timing is not collected. |
| `NESTING_EVENT_ID` | `EVENT_ID` of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. One of `transaction`, `statement`, `stage` or `wait`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 The related tables, [events\_stages\_history](../performance-schema-events_stages_history-table/index) and [events\_stages\_history\_long](../performance-schema-events_stages_history_long-table/index) derive their values from the current events.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_current-table/>

Performance Schema events\_stages\_history Table
================================================

    The `events_stages_history` table by default contains the ten most recent completed stage events per thread. This number can be adjusted by setting the [performance\_schema\_events\_stages\_history\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_size) system variable when the server starts up.

 The table structure is identical to the [events\_stage\_current](../performance-schema-events_stages_current-table/index) table structure, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if timing is not collected. |
| `NESTING_EVENT_ID` | `EVENT_ID` of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. One of `transaction`, `statement`, `stage` or `wait`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 [events\_stages\_current](../performance-schema-events_stages_current-table/index) and [events\_stages\_history\_long](../performance-schema-events_stages_history_long-table/index) are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_history-table/>

Performance Schema events\_stages\_history\_long Table
======================================================

    The `events_stages_history_long` table by default contains the ten thousand most recent completed stage events. This number can be adjusted by setting the [performance\_schema\_events\_stages\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_long_size) system variable when the server starts up.

 The table structure is identical to the `events_stage_current` table structure, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a NAME from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or NULL if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or NULL if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or NULL if timing is not collected. |
| `NESTING_EVENT_ID` | `EVENT_ID` of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. One of `transaction`, `statement`, `stage` or `wait`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 [events\_stages\_current](../performance-schema-events_stages_current-table/index) and [events\_stages\_history](../performance-schema-events_stages_history-table/index) are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_history_long-table/>

Performance Schema events\_statements\_current Table
====================================================

    The `events_statements_current` table contains current statement events, with each row being a record of a thread and its most recent statement event.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if the event has not ended or timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if the event has not ended or timing is not collected. |
| `LOCK_TIME` | Time in picoseconds spent waiting for locks. The time is calculated in microseconds but stored in picoseconds for compatibility with other timings. |
| `SQL_TEXT` | The SQL statement, or `NULL` if the command is not associated with an SQL statement. |
| `DIGEST` | [Statement digest](../performance-schema-digests/index). |
| `DIGEST_TEXT` | [Statement digest](../performance-schema-digests/index) text. |
| `CURRENT_SCHEMA` | Statement's default database for the statement, or `NULL` if there was none. |
| `OBJECT_SCHEMA` | Reserved, currently `NULL` |
| `OBJECT_NAME` | Reserved, currently `NULL` |
| `OBJECT_TYPE` | Reserved, currently `NULL` |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the statement object. |
| `MYSQL_ERRNO` | Error code. See [MariaDB Error Codes](../mariadb-error-codes/index) for a full list. |
| `RETURNED_SQLSTATE` | The [SQLSTATE](../sqlstate/index) value. |
| `MESSAGE_TEXT` | Statement error message. See [MariaDB Error Codes](../mariadb-error-codes/index). |
| `ERRORS` | `0` if `SQLSTATE` signifies completion (starting with 00) or warning (01), otherwise `1`. |
| `WARNINGS` | Number of warnings from the diagnostics area. |
| `ROWS_AFFECTED` | Number of rows affected the statement affected. |
| `ROWS_SENT` | Number of rows returned. |
| `ROWS_EXAMINED` | Number of rows read during the statement's execution. |
| `CREATED_TMP_DISK_TABLES` | Number of on-disk temp tables created by the statement. |
| `CREATED_TMP_TABLES` | Number of temp tables created by the statement. |
| `SELECT_FULL_JOIN` | Number of joins performed by the statement which did not use an index. |
| `SELECT_FULL_RANGE_JOIN` | Number of joins performed by the statement which used a range search of the first table. |
| `SELECT_RANGE` | Number of joins performed by the statement which used a range of the first table. |
| `SELECT_RANGE_CHECK` | Number of joins without keys performed by the statement that check for key usage after each row. |
| `SELECT_SCAN` | Number of joins performed by the statement which used a full scan of the first table. |
| `SORT_MERGE_PASSES` | Number of merge passes by the sort algorithm performed by the statement. If too high, you may need to increase the [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size). |
| `SORT_RANGE` | Number of sorts performed by the statement which used a range. |
| `SORT_ROWS` | Number of rows sorted by the statement. |
| `SORT_SCAN` | Number of sorts performed by the statement which used a full table scan. |
| `NO_INDEX_USED` | `0` if the statement performed a table scan with an index, `1` if without an index. |
| `NO_GOOD_INDEX_USED` | `0` if a good index was found for the statement, `1` if no good index was found. See the `Range checked for each record description` in the [EXPLAIN](../explain/index) article. |
| `NESTING_EVENT_ID` | Reserved, currently `NULL`. |
| `NESTING_EVENT_TYPE` | Reserved, currently `NULL`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 The related tables, [events\_statements\_history](../performance-schema-events_statements_history-table/index) and [events\_statements\_history\_long](../performance-schema-events_statements_history_long-table/index) derive their values from the current events table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_current-table/>

LOAD Data into Tables or Index
===============================

   Loading data quickly into MariaDB

  

| Title | Description |
| --- | --- |
|  [LOAD DATA INFILE](../load-data-infile/index) |  Read rows from a text file into a table.  |
|  [LOAD INDEX](../load-index/index) |  Loads one or more indexes from one or more MyISAM/Aria tables into a key buffer.  |
|  [LOAD XML](../load-xml/index) |  Load XML data into a table.  |
|  [LOAD\_FILE](../load_file/index) |  Returns file contents as a string.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/load-data-into-tables-or-index/>

DUAL
====

    Description
-----------

 You are allowed to specify `DUAL` as a dummy table name in situations where no tables are referenced, such as the following [SELECT](../select/index) statement:

 
```
SELECT 1 + 1 FROM DUAL;
+-------+
| 1 + 1 |
+-------+
|     2 |
+-------+

```

 `DUAL` is purely for the convenience of people who require that all `SELECT` statements should have `FROM` and possibly other clauses. MariaDB ignores the clauses. MariaDB does not require `FROM DUAL` if no tables are referenced.

 FROM DUAL could be used when you only SELECT computed values, but require a WHERE clause, perhaps to test that a script correctly handles empty resultsets:

 
```
SELECT 1 FROM DUAL WHERE FALSE;
Empty set (0.00 sec)

```

See Also
--------

 * [SELECT](../select/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dual/>

EXPLAIN ANALYZE
===============

    The syntax for the `EXPLAIN ANALYZE` feature was changed to `ANALYZE statement`, available since [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/). See [ANALYZE statement](../analyze-statement/index). 

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-analyze/>

JOIN Syntax
===========

    Description
-----------

 MariaDB supports the following `JOIN` syntaxes for the `table_references` part of `[SELECT](../select/index)` statements and multiple-table `[DELETE](../delete/index)` and `[UPDATE](../update/index)` statements:

 
```
table_references:
    table_reference [, table_reference] ...

table_reference:
    table_factor
  | join_table

table_factor:
    tbl_name [PARTITION (partition_list)]
        [query_system_time_period_specification] [[AS] alias] [index_hint_list]
  | table_subquery [query_system_time_period_specification] [AS] alias
  | ( table_references )
  | { ON table_reference LEFT OUTER JOIN table_reference
        ON conditional_expr }

join_table:
    table_reference [INNER | CROSS] JOIN table_factor [join_condition]
  | table_reference STRAIGHT_JOIN table_factor
  | table_reference STRAIGHT_JOIN table_factor ON conditional_expr
  | table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
  | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

join_condition:
    ON conditional_expr
  | USING (column_list)

query_system_time_period_specification:
    FOR SYSTEM_TIME AS OF point_in_time
  | FOR SYSTEM_TIME BETWEEN point_in_time AND point_in_time
  | FOR SYSTEM_TIME FROM point_in_time TO point_in_time
  | FOR SYSTEM_TIME ALL

point_in_time:
    [TIMESTAMP] expression
  | TRANSACTION expression

index_hint_list:
    index_hint [, index_hint] ...

index_hint:
    USE {INDEX|KEY}
      [{FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
  | IGNORE {INDEX|KEY}
      [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
  | FORCE {INDEX|KEY}
      [{FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

index_list:
    index_name [, index_name] ...

```

A table reference is also known as a join expression.

 Each table can also be specified as `db_name`.`tabl_name`. This allows to write queries which involve multiple databases. See [Identifier Qualifiers](../identifier-qualifiers/index) for syntax details.

 The syntax of `table_factor` is extended in comparison with the SQL Standard. The latter accepts only `table_reference`, not a list of them inside a pair of parentheses.

 This is a conservative extension if we consider each comma in a list of table\_reference items as equivalent to an inner join. For example:

 
```
SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

```

is equivalent to:

 
```
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

```

In MariaDB, `CROSS JOIN` is a syntactic equivalent to `INNER JOIN` (they can replace each other). In standard SQL, they are not equivalent. `INNER JOIN` is used with an `ON` clause, `CROSS JOIN` is used otherwise.

 In general, parentheses can be ignored in join expressions containing only inner join operations. MariaDB also supports nested joins (see <http://dev.mysql.com/doc/refman/5.1/en/nested-join-optimization.html>).

 See [System-versioned tables](../system-versioned-tables/index) for more information about `FOR SYSTEM_TIME` syntax.

 Index hints can be specified to affect how the MariaDB optimizer makes use of indexes. For more information, see [How to force query plans](../how-to-force-query-plans/index).

 Examples
--------

 
```
SELECT left_tbl.*
  FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
  WHERE right_tbl.id IS NULL;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/join-syntax/>

Performance Schema events\_statements\_history Table
====================================================

    The `events_statements_history` table by default contains the ten most recent completed statement events per thread. This number can be adjusted by setting the [performance\_schema\_events\_statements\_history\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_size) system variable when the server starts up.

 The table structure is identical to the [events\_statements\_current](../performance-schema-events_statements_current-table/index) table structure, and contains the following columns:

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if timing is not collected. |
| `LOCK_TIME` | Time in picoseconds spent waiting for locks. The time is calculated in microseconds but stored in picoseconds for compatibility with other timings. |
| `SQL_TEXT` | The SQL statement, or `NULL` if the command is not associated with an SQL statement. |
| `DIGEST` | [Statement digest](../performance-schema-digests/index). |
| `DIGEST_TEXT` | [Statement digest](../performance-schema-digests/index) text. |
| `CURRENT_SCHEMA` | Statement's default database for the statement, or `NULL` if there was none. |
| `OBJECT_SCHEMA` | Reserved, currently `NULL` |
| `OBJECT_NAME` | Reserved, currently `NULL` |
| `OBJECT_TYPE` | Reserved, currently `NULL` |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the statement object. |
| `MYSQL_ERRNO` | Error code. See [MariaDB Error Codes](../mariadb-error-codes/index) for a full list. |
| `RETURNED_SQLSTATE` | The [SQLSTATE](../sqlstate/index) value. |
| `MESSAGE_TEXT` | Statement error message. See [MariaDB Error Codes](../mariadb-error-codes/index). |
| `ERRORS` | `0` if `SQLSTATE` signifies completion (starting with 00) or warning (01), otherwise `1`. |
| `WARNINGS` | Number of warnings from the diagnostics area. |
| `ROWS_AFFECTED` | Number of rows affected the statement affected. |
| `ROWS_SENT` | Number of rows returned. |
| `ROWS_EXAMINED` | Number of rows read during the statement's execution. |
| `CREATED_TMP_DISK_TABLES` | Number of on-disk temp tables created by the statement. |
| `CREATED_TMP_TABLES` | Number of temp tables created by the statement. |
| `SELECT_FULL_JOIN` | Number of joins performed by the statement which did not use an index. |
| `SELECT_FULL_RANGE_JOIN` | Number of joins performed by the statement which used a range search of the first table. |
| `SELECT_RANGE` | Number of joins performed by the statement which used a range of the first table. |
| `SELECT_RANGE_CHECK` | Number of joins without keys performed by the statement that check for key usage after each row. |
| `SELECT_SCAN` | Number of joins performed by the statement which used a full scan of the first table. |
| `SORT_MERGE_PASSES` | Number of merge passes by the sort algorithm performed by the statement. If too high, you may need to increase the [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size). |
| `SORT_RANGE` | Number of sorts performed by the statement which used a range. |
| `SORT_ROWS` | Number of rows sorted by the statement. |
| `SORT_SCAN` | Number of sorts performed by the statement which used a full table scan. |
| `NO_INDEX_USED` | `0` if the statement performed a table scan with an index, `1` if without an index. |
| `NO_GOOD_INDEX_USED` | `0` if a good index was found for the statement, `1` if no good index was found. See the `Range checked for each record description` in the [EXPLAIN](../explain/index) article. |
| `NESTING_EVENT_ID` | Reserved, currently `NULL`. |
| `NESTING_EVENT_TYPE` | Reserved, currently `NULL`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 [events\_statements\_current](../performance-schema-events_statements_current-table/index) and [events\_statements\_history\_long](../performance-schema-events_statements_history_long-table/index) are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_history-table/>

ANALYZE FORMAT=JSON
===================

     `ANALYZE FORMAT=JSON` is a mix of the [EXPLAIN FORMAT=JSON](../explain-formatjson/index) and [ANALYZE](../analyze-statement/index) statement features. The `ANALYZE FORMAT=JSON $statement` will execute `$statement`, and then print the output of `EXPLAIN FORMAT=JSON`, amended with data from the query execution.

 Basic Execution Data
--------------------

 You can get the following also from tabular `ANALYZE` statement form:

 * **`r_rows`** is provided for any node that reads rows. It shows how many rows were read, on average
* **`r_filtered`** is provided whenever there is a condition that is checked. It shows the percentage of rows left after checking the condition.

 Advanced Execution Data
-----------------------

 The most important data not available in the regular tabula `ANALYZE` statement are:

 * **`r_loops`** field. This shows how many times the node was executed. Most query plan elements have this field.
* **`r_total_time_ms`** field. It shows how much time in total, in milliseconds, was spent executing this node. If the node has subnodes, their execution time is included.
* **`r_buffer_size`** field. Query plan nodes that make use of buffers report the size of buffer that was was used.

 SHOW ANALYZE FORMAT=JSON
------------------------

 
**MariaDB starting with [10.9](../what-is-mariadb-109/index)**`SHOW ANALYZE FORMAT=JSON for <connection_id>` extends `ANALYZE [FORMAT=JSON] <select>` to allow one to analyze a query currently running in another connection.

 
Data About Individual Query Plan Nodes
--------------------------------------

 * **`filesort`** node reports whether sorting was done with `LIMIT n` parameter, and how many rows were in the sort result.
* **`block-nl-join`** node has `r_loops` field, which allows to tell whether `Using join buffer` was efficient
* **`range-checked-for-each-record`** reports counters that show the result of the check.
* **`expression-cache`** is used for subqueries, and it reports how many times the cache was used, and what cache hit ratio was.
* **`union_result`** node has `r_rows` so one can see how many rows were produced after UNION operation
* and so forth

 Use Cases
---------

 See [Examples of ANALYZE FORMAT=JSON](../analyze-formatjson-examples/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/analyze-format-json/>

Using Buffer UPDATE Algorithm
=============================

    This article explains the [UPDATE](../update/index) statement's *Using Buffer* algorithm.

 Take the following table and query:

 


| Name | Salary |
| --- | --- |
| Babatunde | 1000 |
| Jolana | 1050 |
| Pankaja | 1300 |

 

```
UPDATE employees SET salary = salary+100 WHERE salary < 2000;

```

Suppose the *employees* table has an index on the *salary* column, and the optimizer decides to use a range scan on that index. 

 The optimizer starts a range scan on the *salary* index. We find the first record *Babatunde, 1000*. If we do an on-the-fly update, we immediately instruct the storage engine to change this record to be *Babatunde, 1000+100=1100*.

 Then we proceed to search for the next record, and find *Jolana, 1050*. We instruct the storage engine to update it to be *Jolana, 1050+100=1150*.

 Then we proceed to search for the next record ... and what happens next depends on the storage engine. In some storage engines, data changes are visible immediately, so we will find find the *Babatunde, 1100* record that we wrote at the first step, modifying it again, giving Babatunde an undeserved raise. Then we will see Babatunde again and again, looping continually.

 In order to prevent such situations, the optimizer checks whether the UPDATE statement is going to change key values for the keys it is using. In that case, it will use a different algorithm:

 1. Scan everyone with "salary<2000", remembering the rowids of the rows in a buffer.
2. Read the buffer and apply the updates.

 This way, each row will be updated only once.

 The `Using buffer` [EXPLAIN](../explain/index) output indicates that the buffer as described above will be used.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-buffer-update-algorithm/>

ANALYZE FORMAT=JSON Examples
============================

    Example #1
----------

 Customers who have ordered more than 1M goods.

 
```
ANALYZE FORMAT=JSON
SELECT COUNT(*)
FROM customer
WHERE
  (SELECT SUM(o_totalprice) FROM orders WHERE o_custkey=c_custkey) > 1000*1000;

```

The query takes 40 seconds over cold cache

 
```
EXPLAIN: {
  "query_block": {
    "select_id": 1,
    "r_loops": 1,
    "r_total_time_ms": 39872,
    "table": {
      "table_name": "customer",
      "access_type": "index",
      "key": "i_c_nationkey",
      "key_length": "5",
      "used_key_parts": ["c_nationkey"],
      "r_loops": 1,
      "rows": 150303,
      "r_rows": 150000,
      "r_total_time_ms": 270.3,
      "filtered": 100,
      "r_filtered": 60.691,
      "attached_condition": "((subquery#2) > <cache>((1000 * 1000)))",
      "using_index": true
    },
    "subqueries": [
      {
        "query_block": {
          "select_id": 2,
          "r_loops": 150000,
          "r_total_time_ms": 39531,
          "table": {
            "table_name": "orders",
            "access_type": "ref",
            "possible_keys": ["i_o_custkey"],
            "key": "i_o_custkey",
            "key_length": "5",
            "used_key_parts": ["o_custkey"],
            "ref": ["dbt3sf1.customer.c_custkey"],
            "r_loops": 150000,
            "rows": 7,
            "r_rows": 10,
            "r_total_time_ms": 39208,
            "filtered": 100,
            "r_filtered": 100
          }
        }
      }
    ]
  }
}
```

`ANALYZE` shows that 39.2 seconds were spent in the subquery, which was executed 150K times (for every row of outer table).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/analyze-formatjson-examples/>

EXPLAIN FORMAT=JSON
===================

    Synopsis
--------

 `EXPLAIN FORMAT=JSON` is a variant of [EXPLAIN](../explain/index) command that produces output in JSON form. The output always has one row which has only one column titled "`JSON`". The contents are a JSON representation of the query plan, formatted for readability:

 
```
EXPLAIN FORMAT=JSON SELECT * FROM t1 WHERE col1=1\G

```


```
*************************** 1. row ***************************
EXPLAIN: {
  "query_block": {
    "select_id": 1,
    "table": {
      "table_name": "t1",
      "access_type": "ALL",
      "rows": 1000,
      "filtered": 100,
      "attached_condition": "(t1.col1 = 1)"
    }
  }
}

```

Output is different from MySQL
------------------------------

 The output of MariaDB's `EXPLAIN FORMAT=JSON` is different from `EXPLAIN FORMAT=JSON` in MySQL.The reasons for that are:

 * MySQL's output has deficiencies. Some are listed here: [EXPLAIN FORMAT=JSON in MySQL](../explain-formatjson-in-mysql/index)
* The output of MySQL's `EXPLAIN FORMAT=JSON` is not defined. Even MySQL Workbench has trouble parsing it (see this [blog post](http://s.petrunia.net/blog/?p=93)).
* MariaDB has query optimizations that MySQL does not have. Ergo, MariaDB generates query plans that MySQL does not generate.

 A (as yet incomplete) list of how MariaDB's output is different from MySQL can be found here: [EXPLAIN FORMAT=JSON differences from MySQL](../explain-formatjson-differences-from-mysql/index). 

 Output Format
-------------

 TODO: MariaDB's output format description.

 See Also
--------

 * [ANALYZE FORMAT=JSON](../analyze-formatjson/index) produces output like `EXPLAIN FORMAT=JSON`, but amended with the data from query execution.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-format-json/>

Performance Schema events\_waits\_history Table
===============================================

    The `events_waits_history` table by default contains the ten most recent completed wait events per thread. This number can be adjusted by setting the [performance\_schema\_events\_waits\_history\_size](../performance-schema-system-variables/index#performance_schema_events_waits_history_size) system variable when the server starts up.

 The table structure is identical to the [events\_waits\_current](../performance-schema-events_waits_current-table/index) table structure, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if timing is not collected. |
| `SPINS` | Number of spin rounds for a mutex, or `NULL` if spin rounds are not used, or spinning is not instrumented. |
| `OBJECT_SCHEMA` | Name of the schema that contains the table for table I/O objects, otherwise `NULL` for file I/O and synchronization objects. |
| `OBJECT_NAME` | File name for file I/O objects, table name for table I/O objects, the socket's `IP:PORT` value for a socket object or `NULL` for a synchronization object. |
| `INDEX NAME` | Name of the index, `PRIMARY` for the primary key, or `NULL` for no index used. |
| `OBJECT_TYPE` | FILE for a file object, `TABLE` or `TEMPORARY TABLE` for a table object, or `NULL` for a synchronization object. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the object. |
| `NESTING_EVENT_ID` | EVENT\_ID of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. Either `statement`, `stage` or `wait`. |
| `OPERATION` | Operation type, for example read, write or lock |
| `NUMBER_OF_BYTES` | Number of bytes that the operation read or wrote, or `NULL` for table I/O waits. |
| `FLAGS` | Reserved for use in the future. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 [events\_waits\_current](../performance-schema-events_waits_current-table/index) and [events\_waits\_history\_long](../performance-schema-events_waits_history_long-table/index) are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_history-table/>

Performance Schema events\_waits\_current Table
===============================================

    The `events_waits_current` table contains the status of a thread's most recently monitored wait event, listing one event per thread. 

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if the event has not ended or timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if the event has not ended or timing is not collected. |
| `SPINS` | Number of spin rounds for a mutex, or `NULL` if spin rounds are not used, or spinning is not instrumented. |
| `OBJECT_SCHEMA` | Name of the schema that contains the table for table I/O objects, otherwise `NULL` for file I/O and synchronization objects. |
| `OBJECT_NAME` | File name for file I/O objects, table name for table I/O objects, the socket's `IP:PORT` value for a socket object or `NULL` for a synchronization object. |
| `INDEX NAME` | Name of the index, `PRIMARY` for the primary key, or `NULL` for no index used. |
| `OBJECT_TYPE` | FILE for a file object, `TABLE` or `TEMPORARY TABLE` for a table object, or `NULL` for a synchronization object. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the object. |
| `NESTING_EVENT_ID` | `EVENT_ID` of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. Either `statement`, `stage` or `wait`. |
| `OPERATION` | Operation type, for example read, write or lock |
| `NUMBER_OF_BYTES` | Number of bytes that the operation read or wrote, or `NULL` for table I/O waits. |
| `FLAGS` | Reserved for use in the future. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 The related tables, [events\_waits\_history](../performance-schema-events_waits_history-table/index) and [events\_waits\_history\_long](../performance-schema-events_waits_history_long-table/index) derive their values from the current events.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_current-table/>

Performance Schema events\_waits\_history\_long Table
=====================================================

    The `events_waits_history_long` table by default contains the ten thousand most recent completed wait events. This number can be adjusted by setting the [performance\_schema\_events\_waits\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_waits_history_long_size) system variable when the server starts up.

 The table structure is identical to the [events\_waits\_current](../performance-schema-events_waits_current-table/index) table structure, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with`THREAD_ID`uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a NAME from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if timing is not collected. |
| `SPINS` | Number of spin rounds for a mutex, or `NULL` if spin rounds are not used, or spinning is not instrumented. |
| `OBJECT_SCHEMA` | Name of the schema that contains the table for table I/O objects, otherwise `NULL` for file I/O and synchronization objects. |
| `OBJECT_NAME` | File name for file I/O objects, table name for table I/O objects, the socket's IP:PORT value for a socket object or `NULL` for a synchronization object. |
| `INDEX_NAME` | Name of the index, PRIMARY for the primary key, or `NULL` for no index used. |
| `OBJECT_TYPE` | FILE for a file object, `TABLE` or `TEMPORARY TABLE` for a table object, or `NULL` for a synchronization object. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the object. |
| `NESTING_EVENT_ID` | `EVENT_ID` of event within which this event nests. |
| `NESTING_EVENT_TYPE` | Nesting event type. Either `statement`, `stage` or `wait`. |
| `OPERATION` | Operation type, for example read, write or lock |
| `NUMBER_OF_BYTES` | Number of bytes that the operation read or wrote, or `NULL` for table I/O waits. |
| `FLAGS` | Reserved for use in the future. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 events\_waits\_current and events\_waits\_history are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_history_long-table/>

Performance Schema events\_statements\_history\_long Table
==========================================================

    The `events_statements_history_long` table by default contains the ten thousand most recent completed statement events. This number can be adjusted by setting the [performance\_schema\_events\_statements\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_long_size) system variable when the server starts up.

 The table structure is identical to the [events\_statements\_current](../performance-schema-events_statements_current-table/index) table structure, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_ID` uniquely identifies the row. |
| `EVENT_ID` | Thread's current event number at the start of the event. Together with `THREAD_ID` uniquely identifies the row. |
| `END_EVENT_ID` | `NULL` when the event starts, set to the thread's current event number at the end of the event. |
| `EVENT_NAME` | Event instrument name and a `NAME` from the `setup_instruments` table |
| `SOURCE` | Name and line number of the source file containing the instrumented code that produced the event. |
| `TIMER_START` | Value in picoseconds when the event timing started or `NULL` if timing is not collected. |
| `TIMER_END` | Value in picoseconds when the event timing ended, or `NULL` if timing is not collected. |
| `TIMER_WAIT` | Value in picoseconds of the event's duration or `NULL` if timing is not collected. |
| `LOCK_TIME` | Time in picoseconds spent waiting for locks. The time is calculated in microseconds but stored in picoseconds for compatibility with other timings. |
| `SQL_TEXT` | The SQL statement, or `NULL` if the command is not associated with an SQL statement. |
| `DIGEST` | [Statement digest](../performance-schema-digests/index). |
| `DIGEST_TEXT` | [Statement digest](../performance-schema-digests/index) text. |
| `CURRENT_SCHEMA` | Statement's default database for the statement, or `NULL` if there was none. |
| `OBJECT_SCHEMA` | Reserved, currently `NULL` |
| `OBJECT_NAME` | Reserved, currently `NULL` |
| `OBJECT_TYPE` | Reserved, currently `NULL` |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the statement object. |
| `MYSQL_ERRNO` | Error code. See [MariaDB Error Codes](../mariadb-error-codes/index) for a full list. |
| `RETURNED_SQLSTATE` | The [SQLSTATE](../sqlstate/index) value. |
| `MESSAGE_TEXT` | Statement error message. See [MariaDB Error Codes](../mariadb-error-codes/index). |
| `ERRORS` | `0` if `SQLSTATE` signifies completion (starting with 00) or warning (01), otherwise `1`. |
| `WARNINGS` | Number of warnings from the diagnostics area. |
| `ROWS_AFFECTED` | Number of rows affected the statement affected. |
| `ROWS_SENT` | Number of rows returned. |
| `ROWS_EXAMINED` | Number of rows read during the statement's execution. |
| `CREATED_TMP_DISK_TABLES` | Number of on-disk temp tables created by the statement. |
| `CREATED_TMP_TABLES` | Number of temp tables created by the statement. |
| `SELECT_FULL_JOIN` | Number of joins performed by the statement which did not use an index. |
| `SELECT_FULL_RANGE_JOIN` | Number of joins performed by the statement which used a range search of the first table. |
| `SELECT_RANGE` | Number of joins performed by the statement which used a range of the first table. |
| `SELECT_RANGE_CHECK` | Number of joins without keys performed by the statement that check for key usage after each row. |
| `SELECT_SCAN` | Number of joins performed by the statement which used a full scan of the first table. |
| `SORT_MERGE_PASSES` | Number of merge passes by the sort algorithm performed by the statement. If too high, you may need to increase the [sort\_buffer\_size](../server-system-variables/index#sort_buffer_size). |
| `SORT_RANGE` | Number of sorts performed by the statement which used a range. |
| `SORT_ROWS` | Number of rows sorted by the statement. |
| `SORT_SCAN` | Number of sorts performed by the statement which used a full table scan. |
| `NO_INDEX_USED` | `0` if the statement performed a table scan with an index, `1` if without an index. |
| `NO_GOOD_INDEX_USED` | `0` if a good index was found for the statement, `1` if no good index was found. See the `Range checked for each record description` in the [EXPLAIN](../explain/index) article. |
| `NESTING_EVENT_ID` | Reserved, currently `NULL`. |
| `NESTING_EVENT_TYPE` | Reserved, currently `NULL`. |

 
It is possible to empty this table with a `TRUNCATE TABLE` statement.

 [events\_statements\_current](../performance-schema-events_statements_current-table/index) and [events\_statements\_history](../performance-schema-events_statements_history-table/index) are related tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_history_long-table/>

Lateral Derived Optimization
============================

    MariaDB supports the Lateral Derived optimization, also referred to as "Split Grouping Optimization" or "Split Materialized Optimization" in some sources.

 Description
-----------

 The optimization's use case is 

 * The query uses a derived table (or a VIEW, or a non-recursive CTE)
* The derived table/View/CTE has a GROUP BY operation as its top-level operation
* The query only needs data from a few GROUP BY groups

 An example of this: consider a VIEW that computes totals for each customer in October:

 
```
create view OCT_TOTALS as
select
  customer_id,
  SUM(amount) as TOTAL_AMT
from orders
where
  order_date BETWEEN '2017-10-01' and '2017-10-31'
group by
  customer_id;

```

And a query that does a join with the customer table to get October totals for "Customer#1" and Customer#2:

 
```
select *
from
  customer, OCT_TOTALS
where
  customer.customer_id=OCT_TOTALS.customer_id and
  customer.customer_name IN ('Customer#1', 'Customer#2')

```

Before Lateral Derived optimization, MariaDB would execute the query as follows:

 1. Materialize the view OCT\_TOTALS. This essentially computes OCT\_TOTALS for all customers.
2. Join it with table customer.

 The EXPLAIN would look like so:

 
```
+------+-------------+------------+-------+---------------+-----------+---------+---------------------------+-------+--------------------------+
| id   | select_type | table      | type  | possible_keys | key       | key_len | ref                       | rows  | Extra                    |
+------+-------------+------------+-------+---------------+-----------+---------+---------------------------+-------+--------------------------+
|    1 | PRIMARY     | customer   | range | PRIMARY,name  | name      | 103     | NULL                      | 2     | Using where; Using index |
|    1 | PRIMARY     | <derived2> | ref   | key0          | key0      | 4       | test.customer.customer_id | 36    |                          |
|    2 | DERIVED     | orders     | index | NULL          | o_cust_id | 4       | NULL                      | 36738 | Using where              |
+------+-------------+------------+-------+---------------+-----------+---------+---------------------------+-------+--------------------------+

```

It is obvious that Step #1 is very inefficient: we compute totals for all customers in the database, while we will only need them for two customers. (If there are 1000 customers, we are doing 500x more work than needed here)

 Lateral Derived optimization addresses this case. It turns the computation of OCT\_TOTALS into what SQL Standard refers to as "LATERAL subquery": a subquery that may have dependencies on the outside tables. This allows pushing the equality `customer.customer_id=OCT_TOTALS.customer_id` down into the derived table/view, where it can be used to limit the computation to compute totals only for the customer of interest.

 The query plan will look as follows:

 1. Scan table `customer` and find `customer_id` for Customer#1 and Customer#2.
2. For each customer\_id, compute the October totals, for this specific customer.

 The EXPLAIN output will look like so:

 
```
+------+-----------------+------------+-------+---------------+-----------+---------+---------------------------+------+--------------------------+
| id   | select_type     | table      | type  | possible_keys | key       | key_len | ref                       | rows | Extra                    |
+------+-----------------+------------+-------+---------------+-----------+---------+---------------------------+------+--------------------------+
|    1 | PRIMARY         | customer   | range | PRIMARY,name  | name      | 103     | NULL                      | 2    | Using where; Using index |
|    1 | PRIMARY         | <derived2> | ref   | key0          | key0      | 4       | test.customer.customer_id | 2    |                          |
|    2 | LATERAL DERIVED | orders     | ref   | o_cust_id     | o_cust_id | 4       | test.customer.customer_id | 1    | Using where              |
+------+-----------------+------------+-------+---------------+-----------+---------+---------------------------+------+--------------------------+

```

Note the line with `id=2`: select\_type is `LATERAL DERIVED`. And table customer uses ref access referring to `customer.customer_id`, which is normally not allowed for derived tables.

 In `EXPLAIN FORMAT=JSON` output, the optimization is shown like so:

 
```
...
        "table": {
          "table_name": "<derived2>",
          "access_type": "ref",
...
          "materialized": {
            "lateral": 1,

```

Note the `"lateral": 1` member.

 Controlling the Optimization
----------------------------

 Lateral Derived is enabled by default, the optimizer will make a cost-based decision whether the optimization should be used.

 If you need to disable the optimization, it has an [optimizer\_switch](../optimizer-switch/index) flag. It can be disabled like so:

 
```
set optimizer_switch='split_materialized=off'

```

References
----------

 * Jira task: <https://jira.mariadb.org/browse/MDEV-13369>
* Commit: <https://github.com/MariaDB/server/commit/b14e2b044b>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/lateral-derived-optimization/>

SELECT ... OFFSET ... FETCH
===========================

    
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**`SELECT ... OFFSET ... FETCH` was introduced in [MariaDB 10.6](../what-is-mariadb-106/index).

 
Syntax
------

 
```
OFFSET start { ROW | ROWS }
FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }

```

Description
-----------

 The `OFFSET` clause allows one to return only those elements of a resultset that come after a specified offset. The `FETCH` clause specifies the number of rows to return, while `ONLY` or `WITH TIES` specifies whether or not to also return any further results that tie for last place according to the ordered resultset.

 Either the singular `ROW` or the plural `ROWS` can be used after the `OFFSET` and `FETCH` clauses; the choice has no impact on the results. 

 In the case of `WITH TIES`, an [ORDER BY](../order-by/index) clause is required, otherwise an ERROR will be returned.

 
```
SELECT i FROM t1 FETCH FIRST 2 ROWS WITH TIES;
ERROR 4180 (HY000): FETCH ... WITH TIES requires ORDER BY clause to be present

```

Examples
--------

 Given a table with 6 rows:

 
```
CREATE OR REPLACE TABLE t1 (i INT);
INSERT INTO t1 VALUES (1),(2),(3),(4), (4), (5);
SELECT i FROM t1 ORDER BY i ASC;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    4 |
|    5 |
+------+


```

`OFFSET 2` allows one to skip the first two results.

 
```
SELECT i FROM t1 ORDER BY i ASC OFFSET 2 ROWS;
+------+
| i    |
+------+
|    3 |
|    4 |
|    4 |
|    5 |
+------+

```

`FETCH FIRST 3 ROWS ONLY` limits the results to three rows only

 
```
SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS ONLY;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
+------+

```

The same outcome can also be achieved with the [LIMIT](../limit/index) clause:

 
```
SELECT i FROM t1 ORDER BY i ASC LIMIT 3 OFFSET 1;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
+------+

```

`WITH TIES` ensures the tied result `4` is also returned.

 
```
SELECT i FROM t1 ORDER BY i ASC OFFSET 1 ROWS FETCH FIRST 3 ROWS WITH TIES;
+------+
| i    |
+------+
|    2 |
|    3 |
|    4 |
|    4 |
+------+

```

See Also
--------

 * [ORDER BY](../order-by/index)
* [SELECT](../select/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select-offset-fetch/>

Joins & Subqueries
===================

   Documentation on the JOIN, UNION, EXCEPT and INTERSECT clauses, and on subqueries.

  

| Title | Description |
| --- | --- |
|  [Joins](../joins/index) |  Querying from multiple tables.  |
|  [Subqueries](../subqueries/index) |  Queries within queries.  |
|  [UNION](../union/index) |  Combine the results from multiple SELECT statements into a single result set.  |
|  [EXCEPT](../except/index) |  Subtraction of two result sets.  |
|  [INTERSECT](../intersect/index) |  Records that are present in both result sets will be included in the result of the operation.  |
|  [Precedence Control in Table Operations](../precedence-control-in-table-operations/index) |  Controlling order of execution in SELECT, UNION, EXCEPT, and INTERSECT.  |
|  [MINUS](../minus/index) |  Synonym for EXCEPT.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/joins-subqueries/>

PROCEDURE
=========

    The `PROCEDURE` clause of [SELECT](../select/index) passes the whole result set to a Procedure which will process it. These Procedures are not [Stored Procedures](../stored-procedures/index), and can only be written in the C language, so it is necessary to recompile the server.

 Currently, the only available procedure is [ANALYSE](../procedure-analyse/index), which examines the resultset and suggests the optimal datatypes for each column. It is defined in the `sql/sql_analyse.cc` file, and can be used as an example to create more Procedures.

 This clause cannot be used in a [view](../views/index)'s definition.

 See Also
--------

 * [SELECT](../select/index)
* [Stored Procedures](../stored-procedures/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/procedure/>

REPLACE...RETURNING
===================

    
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**REPLACE ... RETURNING was added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), and returns a resultset of the replaced rows.

 
Syntax
------

 
```
REPLACE [LOW_PRIORITY | DELAYED]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [PARTITION (partition_list)]
    SET col={expr | DEFAULT}, ...
[RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
    SELECT ...
[RETURNING select_expr 
      [, select_expr ...]]

```
 Description
-----------

 
`REPLACE ... RETURNING` returns a resultset of the replaced rows.

 This returns the listed columns for all the rows that are replaced, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.

 
Examples
--------

 Simple REPLACE statement

 
```
REPLACE INTO t2 VALUES (1,'Leopard'),(2,'Dog') RETURNING id2, id2+id2 
as Total ,id2|id2, id2&&id2;
+-----+-------+---------+----------+
| id2 | Total | id2|id2 | id2&&id2 |
+-----+-------+---------+----------+
|   1 |     2 |       1 |        1 |
|   2 |     4 |       2 |        1 |
+-----+-------+---------+----------+

```

Using stored functions in RETURNING

 
```
DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
    BEGIN
      RETURN (SELECT arg+arg);
    END|

DELIMITER ;
PREPARE stmt FROM "REPLACE INTO t2 SET id2=3, animal2='Fox' RETURNING f2(id2),
UPPER(animal2)";

EXECUTE stmt;
+---------+----------------+
| f2(id2) | UPPER(animal2) |
+---------+----------------+
|       6 | FOX            |
+---------+----------------+

```

Subqueries in the statement

 
```
REPLACE INTO t1 SELECT * FROM t2 RETURNING (SELECT id2 FROM t2 WHERE 
id2 IN (SELECT id2 FROM t2 WHERE id2=1)) AS new_id;
+--------+
| new_id |
+--------+
|      1 |
|      1 |
|      1 |
|      1 |
+--------+

```

Subqueries in the RETURNING clause that return more than one row or column cannot be used..

 Aggregate functions cannot be used in the RETURNING clause. Since aggregate functions work on a set of values and if the purpose is to get the row count, ROW\_COUNT() with SELECT can be used, or it can be used in REPLACE...SELECT...RETURNING if the table in the RETURNING clause is not the same as the REPLACE table.

 See Also
--------

 * [INSERT ... RETURNING](../insertreturning/index)
* [DELETE ... RETURNING](../delete/index#returning)
* [Returning clause](https://www.youtube.com/watch?v=n-LTdEBeAT4) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/replacereturning/>

Optimizer Hints
===============

    Optimizer hints
---------------

 There are some options available in [SELECT](../select/index) to affect the execution plan. These are known as optimizer hints.

 #### HIGH PRIORITY

 `HIGH_PRIORITY` gives the statement a higher priority. If the table is locked, high priority `SELECT`s will be executed as soon as the lock is released, even if other statements are queued. `HIGH_PRIORITY` applies only if the storage engine only supports table-level locking (`MyISAM`, `MEMORY`, `MERGE`). See [HIGH\_PRIORITY and LOW\_PRIORITY clauses](../high_priority-and-low_priority-clauses/index) for details.

 #### SQL\_CACHE / SQL\_NO\_CACHE

 If the [query\_cache\_type](../server-system-variables/index#query_cache_type) system variable is set to 2 or `DEMAND`, and the current statement is cacheable, `SQL_CACHE` causes the query to be cached and `SQL_NO_CACHE` causes the query not to be cached. For `UNION`s, `SQL_CACHE` or `SQL_NO_CACHE` should be specified for the first query. See also [The Query Cache](../the-query-cache/index) for more detail and a list of the types of statements that aren't cacheable.

 #### SQL\_BUFFER\_RESULT

 `SQL_BUFFER_RESULT` forces the optimizer to use a temporary table to process the result. This is useful to free locks as soon as possible.

 #### SQL\_SMALL\_RESULT / SQL\_BIG\_RESULT

 `SQL_SMALL_RESULT` and `SQL_BIG_RESULT` tell the optimizer whether the result is very big or not. Usually, `GROUP BY` and `DISTINCT` operations are performed using a temporary table. Only if the result is very big, using a temporary table is not convenient. The optimizer automatically knows if the result is too big, but you can force the optimizer to use a temporary table with `SQL_SMALL_RESULT`, or avoid the temporary table using `SQL_BIG_RESULT`.

 #### STRAIGHT\_JOIN

 `STRAIGHT_JOIN` applies to the [JOIN](../join/index) queries, and tells the optimizer that the tables must be read in the order they appear in the `SELECT`. For `const` and `system` table this options is sometimes ignored.

 #### SQL\_CALC\_FOUND\_ROWS

 `SQL_CALC_FOUND_ROWS` is only applied when using the `LIMIT` clause. If this option is used, MariaDB will count how many rows would match the query, without the `LIMIT` clause. That number can be retrieved in the next query, using [FOUND\_ROWS()](../found_rows/index).

 #### USE/FORCE/IGNORE INDEX

 `USE INDEX`, `FORCE INDEX` and `IGNORE INDEX` constrain the query planning to a specific index.

 For further information about some of these options, see [How to force query plans](../how-to-force-query-plans/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-hints/>

INSERT...RETURNING
==================

    
**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**INSERT ... RETURNING was added in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), and returns a resultset of the [inserted](../insert/index) rows.

 
Syntax
------

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
 [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
 [ ON DUPLICATE KEY UPDATE
   col=expr
     [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)]
    SET col={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```

Or:

 
```
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [PARTITION (partition_list)] [(col,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE
      col=expr
        [, col=expr] ... ] [RETURNING select_expr 
      [, select_expr ...]]

```
 Description
-----------

 
`INSERT ... RETURNING` returns a resultset of the [inserted](../insert/index) rows.

 This returns the listed columns for all the rows that are inserted, or alternatively, the specified SELECT expression. Any SQL expressions which can be calculated can be used in the select expression for the RETURNING clause, including virtual columns and aliases, expressions which use various operators such as bitwise, logical and arithmetic operators, string functions, date-time functions, numeric functions, control flow functions, secondary functions and stored functions. Along with this, statements which have subqueries and prepared statements can also be used.

 
Examples
--------

 Simple INSERT statements:

 
```
CREATE OR REPLACE TABLE t2 (id INT, animal VARCHAR(20), t TIMESTAMP);

INSERT INTO t2 (id) VALUES (2),(3) RETURNING id,t;
+------+---------------------+
| id   | t                   |
+------+---------------------+
|    2 | 2021-04-28 00:59:32 |
|    3 | 2021-04-28 00:59:32 |
+------+---------------------+

```


```
INSERT INTO t2(id,animal) VALUES (1,'Dog'),(2,'Lion'),(3,'Tiger'),(4,'Leopard')  
  RETURNING id,id+id,id&id,id||id;
+------+-------+-------+--------+
| id   | id+id | id&id | id||id |
+------+-------+-------+--------+
|    1 |     2 |     1 |      1 |
|    2 |     4 |     2 |      1 |
|    3 |     6 |     3 |      1 |
|    4 |     8 |     4 |      1 |
+------+-------+-------+--------+

```

Using stored functions in RETURNING

 
```
DELIMITER |
CREATE FUNCTION f(arg INT) RETURNS INT
    BEGIN
       RETURN (SELECT arg+arg);
    END|

DELIMITER ;

PREPARE stmt FROM "INSERT INTO t1 SET id1=1, animal1='Bear' RETURNING f(id1), UPPER(animal1)";

EXECUTE stmt;
+---------+----------------+
| f(id1)  | UPPER(animal1) |
+---------+----------------+
|       2 | BEAR           |
+---------+----------------+

```

Subqueries in the RETURNING clause that return more than one row or column cannot be used.

 Aggregate functions cannot be used in the RETURNING clause. Since aggregate functions work on a set of values, and if the purpose is to get the row count, ROW\_COUNT() with SELECT can be used or it can be used in INSERT...SELECT...RETURNING if the table in the RETURNING clause is not the same as the INSERT table.

 See Also
--------

 * [INSERT](../insert/index)
* [REPLACE ... RETURNING](../replacereturning/index)
* [DELETE ... RETURNING](../delete/index#returning)
* [Returning clause](https://www.youtube.com/watch?v=n-LTdEBeAT4) (video)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insertreturning/>

Relational Databases: Foreign Keys
==================================

    You already know that a relationship between two tables is created by assigning a common field to the two tables (see [Relational Databases: Table Keys](../relational-databases-table-keys/index)). This common field must be a primary key to one table. Consider a relationship between a *customer* table and a *sale* table. The relationship is not much good if instead of using the primary key, *customer\_code*, in the *sale* table, you use another field that is not unique, such as the customer's first name. You would be unlikely to know for sure which customer made the sale in that case. So, in the table below, *customer\_code* is called the *foreign\_key* in the *sale* table; in other words, it is the primary key in a foreign table.

 ![setting_foreign_keys]

 Foreign keys allow for something called *referential integrity*. What this means is that if a foreign key contains a value, this value refers to an existing record in the related table. For example, take a look at the tables below:

 ### Lecturer table

 


| Code | First Name | Surname |
| --- | --- | --- |
| 1 | Anne | Cohen |
| 2 | Leonard | Clark |
| 3 | Vusi | Cave |

 
### Course table

 


| Course Title | Lecturer Code |
| --- | --- |
| Introduction to Programming | 1 |
| Information Systems | 2 |
| Systems Software | 3 |

 
Referential integrity exists here, as all the lecturers in the *course* table exist in the *lecturer* table. However, let's assume Anne Cohen leaves the institution, and you remove her from the lecturer table. In a situation where referential integrity is not enforced, she would be removed from the lecturer table, but not from the course table, as shown below:

 ### Lecturer table

 


| Code | First Name | Surname |
| --- | --- | --- |
| 2 | Leonard | Clark |
| 3 | Vusi | Cave |

 
### Course table

 


| Course Title | Lecturer Code |
| --- | --- |
| Introduction to Programming | 1 |
| Information Systems | 2 |
| Systems Software | 3 |

 
Now, when you look up who lectures *Introduction to Programming*, you are sent to a non-existent record. This is called poor data intregrity.

 Foreign keys also allow *cascading* deletes and updates. For example, if Anne Cohen leaves, taking the Introduction to Programming Course with her, all trace of her can be removed from both the *lecturer* and *course* table using one statement. The delete *cascades* through the relevant tables, removing all relevant records.

 Foreign keys can also contain null values, indicating that no relationship exists.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/relational-databases-foreign-keys/>

SELECT WITH ROLLUP
==================

    Syntax
------

 See [SELECT](../select/index) for the full syntax.

 Description
-----------

 The `WITH ROLLUP` modifier adds extra rows to the resultset that represent super-aggregate summaries. The super-aggregated column is represented by a `NULL` value. Multiple aggregates over different columns will be added if there are multiple `GROUP BY` columns.

 The [LIMIT](../limit/index) clause can be used at the same time, and is applied after the `WITH ROLLUP` rows have been added.

 `WITH ROLLUP` cannot be used with [ORDER BY](../order-by/index). Some sorting is still possible by using `ASC` or `DESC` clauses with the `GROUP BY` column, although the super-aggregate rows will always be added last.

 Examples
--------

 These examples use the following sample table

 
```
CREATE TABLE booksales ( 
  country VARCHAR(35), genre ENUM('fiction','non-fiction'), year YEAR, sales INT);

INSERT INTO booksales VALUES
  ('Senegal','fiction',2014,12234), ('Senegal','fiction',2015,15647),
  ('Senegal','non-fiction',2014,64980), ('Senegal','non-fiction',2015,78901),
  ('Paraguay','fiction',2014,87970), ('Paraguay','fiction',2015,76940),
  ('Paraguay','non-fiction',2014,8760), ('Paraguay','non-fiction',2015,9030);

```

The addition of the `WITH ROLLUP` modifier in this example adds an extra row that aggregates both years:

 
```
SELECT year, SUM(sales) FROM booksales GROUP BY year;
+------+------------+
| year | SUM(sales) |
+------+------------+
| 2014 |     173944 |
| 2015 |     180518 |
+------+------------+
2 rows in set (0.08 sec)

SELECT year, SUM(sales) FROM booksales GROUP BY year WITH ROLLUP;
+------+------------+
| year | SUM(sales) |
+------+------------+
| 2014 |     173944 |
| 2015 |     180518 |
| NULL |     354462 |
+------+------------+

```

In the following example, each time the genre, the year or the country change, another super-aggregate row is added:

 
```
SELECT country, year, genre, SUM(sales) 
  FROM booksales GROUP BY country, year, genre;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
+----------+------+-------------+------------+

SELECT country, year, genre, SUM(sales) 
  FROM booksales GROUP BY country, year, genre WITH ROLLUP;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Paraguay | 2015 | NULL        |      85970 |
| Paraguay | NULL | NULL        |     182700 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2014 | NULL        |      77214 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
| Senegal  | 2015 | NULL        |      94548 |
| Senegal  | NULL | NULL        |     171762 |
| NULL     | NULL | NULL        |     354462 |
+----------+------+-------------+------------+

```

The LIMIT clause, applied after WITH ROLLUP:

 
```
SELECT country, year, genre, SUM(sales) 
  FROM booksales GROUP BY country, year, genre WITH ROLLUP LIMIT 4;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | 2015 | fiction     |      76940 |
+----------+------+-------------+------------+

```

Sorting by year descending:

 
```
SELECT country, year, genre, SUM(sales) 
  FROM booksales GROUP BY country, year DESC, genre WITH ROLLUP;
+----------+------+-------------+------------+
| country  | year | genre       | SUM(sales) |
+----------+------+-------------+------------+
| Paraguay | 2015 | fiction     |      76940 |
| Paraguay | 2015 | non-fiction |       9030 |
| Paraguay | 2015 | NULL        |      85970 |
| Paraguay | 2014 | fiction     |      87970 |
| Paraguay | 2014 | non-fiction |       8760 |
| Paraguay | 2014 | NULL        |      96730 |
| Paraguay | NULL | NULL        |     182700 |
| Senegal  | 2015 | fiction     |      15647 |
| Senegal  | 2015 | non-fiction |      78901 |
| Senegal  | 2015 | NULL        |      94548 |
| Senegal  | 2014 | fiction     |      12234 |
| Senegal  | 2014 | non-fiction |      64980 |
| Senegal  | 2014 | NULL        |      77214 |
| Senegal  | NULL | NULL        |     171762 |
| NULL     | NULL | NULL        |     354462 |
+----------+------+-------------+------------+

```

See Also
--------

 * [SELECT](../select/index)
* [Joins and Subqueries](../joins-subqueries/index)
* [LIMIT](../limit/index)
* [ORDER BY](../order-by/index)
* [GROUP BY](../group-by/index)
* [Common Table Expressions](../common-table-expressions/index)
* [SELECT INTO OUTFILE](../select-into-outfile/index)
* [SELECT INTO DUMPFILE](../select-into-dumpfile/index)
* [FOR UPDATE](../for-update/index)
* [LOCK IN SHARE MODE](../lock-in-share-mode/index)
* [Optimizer Hints](../optimizer-hints/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select-with-rollup/>

HIGH\_PRIORITY and LOW\_PRIORITY
================================

     The [InnoDB](../innodb/index) storage engine uses row-level locking to ensure data integrity. However some storage engines (such as [MEMORY](../memory-storage-engine/index), [MyISAM](../myisam/index), [Aria](../aria/index) and [MERGE](../merge/index)) lock the whole table to prevent conflicts. These storage engines use two separate queues to remember pending statements; one is for [SELECTs](../select/index) and the other one is for write statements ([INSERT](../insert/index), [DELETE](../delete/index), [UPDATE](../update/index)). By default, the latter has a higher priority.

 To give write operations a lower priority, the [low\_priority\_updates](../server-system-variables/index#low_priority_updates) server system variable can be set to `ON`. The option is available on both the global and session levels, and it can be set at startup or via the [SET](../set/index) statement.

 When too many table locks have been set by write statements, some pending SELECTs are executed. The maximum number of write locks that can be acquired before this happens is determined by the [max\_write\_lock\_count](../server-system-variables/index#max_write_lock_count) server system variable, which is dynamic.

 If write statements have a higher priority (default), the priority of individual write statements ([INSERT](../insert/index), [REPLACE](../replace/index), [UPDATE](../update/index), [DELETE](../delete/index)) can be changed via the `LOW_PRIORITY` attribute, and the priority of a `SELECT` statement can be raised via the `HIGH_PRIORITY` attribute. Also, [LOCK TABLES](../transactions-lock/index) supports a `LOW_PRIORITY` attribute for `WRITE` locks.

 If read statements have a higher priority, the priority of an `INSERT` can be changed via the `HIGH_PRIORITY` attribute. However, the priority of other write statements cannot be raised individually.

 The use of `LOW_PRIORITY` or `HIGH_PRIORITY` for an `INSERT` prevents [Concurrent Inserts](../concurrent-inserts/index) from being used.

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/high_priority-and-low_priority-clauses/>

INSERT - Default & Duplicate Values
===================================

    Default Values
--------------

 If the `[SQL\_MODE](../sql-mode/index)` contains `STRICT_TRANS_TABLES` and you are [inserting](../insert/index) into a transactional table (like InnoDB), or if the SQL\_MODE contains `STRICT_ALL_TABLES`, all `NOT NULL` columns which do not have a `DEFAULT` value (and are not [AUTO\_INCREMENT](../auto_increment/index)) must be explicitly referenced in `INSERT` statements. If not, an error like this is produced:

 
```
ERROR 1364 (HY000): Field 'col' doesn't have a default value

```

In all other cases, if a `NOT NULL` column without a `DEFAULT` value is not referenced, an empty value will be inserted (for example, 0 for `INTEGER` columns and '' for `CHAR` columns). See [NULL Values in MariaDB:Inserting](../null-values-in-mariadb/index#inserting) for examples.

 If a `NOT NULL` column having a `DEFAULT` value is not referenced, `NULL` will be inserted.

 If a `NULL` column having a `DEFAULT` value is not referenced, its default value will be inserted. It is also possible to explicitly assign the default value using the `DEFAULT` keyword or the `[DEFAULT()](../default/index)` function.

 If the `DEFAULT` keyword is used but the column does not have a `DEFAULT` value, an error like this is produced:

 
```
ERROR 1364 (HY000): Field 'col' doesn't have a default value

```

Duplicate Values
----------------

 By default, if you try to insert a duplicate row and there is a `UNIQUE` index, `INSERT` stops and an error like this is produced:

 
```
ERROR 1062 (23000): Duplicate entry 'dup_value' for key 'col'

```

To handle duplicates you can use the [IGNORE](../ignore/index) clause, [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) or the [REPLACE](../replace/index) statement. Note that the IGNORE and DELAYED options are ignored when you use [ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index).

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT IGNORE](../insert-ignore/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-default-duplicate-values/>

INSERT IGNORE
=============

    Ignoring Errors
---------------

 Normally [INSERT](../insert/index) stops and rolls back when it encounters an error.

 By using the [IGNORE](../ignore/index) keyword all errors are converted to warnings, which will not stop inserts of additional rows.

 Invalid values are changed to the closest valid value and inserted, with a warning produced.

 The IGNORE and DELAYED options are ignored when you use [ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index).

 Prior to MySQL and [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5528-release-notes/), no warnings were issued for duplicate key errors when using `IGNORE`. You can get the old behavior if you set [OLD\_MODE](../old_mode/index) to `NO_DUP_KEY_WARNINGS_WITH_IGNORE`.

 See [IGNORE](../ignore/index) for a full description of effects.

 Examples
--------

 
```
CREATE TABLE t1 (x INT UNIQUE);

INSERT INTO t1 VALUES(1),(2);

INSERT INTO t1 VALUES(2),(3);
ERROR 1062 (23000): Duplicate entry '2' for key 'x'
SELECT * FROM t1;
+------+
| x    |
+------+
|    1 |
|    2 |
+------+

INSERT IGNORE INTO t1 VALUES(2),(3);
Query OK, 1 row affected, 1 warning (0.04 sec)

SHOW WARNINGS;
+---------+------+---------------------------------+
| Level   | Code | Message                         |
+---------+------+---------------------------------+
| Warning | 1062 | Duplicate entry '2' for key 'x' |
+---------+------+---------------------------------+

SELECT * FROM t1;
+------+
| x    |
+------+
|    1 |
|    2 |
|    3 |
+------+

```

Converting values:

 
```
CREATE OR REPLACE TABLE t2(id INT, t VARCHAR(2) NOT NULL, n INT NOT NULL);

INSERT INTO t2(id) VALUES (1),(2);
ERROR 1364 (HY000): Field 't' doesn't have a default value

INSERT IGNORE INTO t2(id) VALUES (1),(2);
Query OK, 2 rows affected, 2 warnings (0.026 sec)
Records: 2  Duplicates: 0  Warnings: 2

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1364 | Field 't' doesn't have a default value |
| Warning | 1364 | Field 'n' doesn't have a default value |
+---------+------+----------------------------------------+

SELECT * FROM t2;
+------+---+---+
| id   | t | n |
+------+---+---+
|    1 |   | 0 |
|    2 |   | 0 |
+------+---+---+

```

See [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index) for further examples using that syntax.

 See Also
--------

 * [INSERT](../insert/index)
* [INSERT DELAYED](../insert-delayed/index)
* [INSERT SELECT](../insert-select/index)
* [HIGH\_PRIORITY and LOW\_PRIORITY](../high_priority-and-low_priority/index)
* [Concurrent Inserts](../concurrent-inserts/index)
* [INSERT - Default & Duplicate Values](../insert-default-duplicate-values/index)
* [INSERT ON DUPLICATE KEY UPDATE](../insert-on-duplicate-key-update/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/insert-ignore/>

TIME\_MS column in INFORMATION\_SCHEMA.PROCESSLIST
==================================================

    In MariaDB, an extra column `TIME_MS` has been added to the [INFORMATION\_SCHEMA.PROCESSLIST](../information-schema-processlist-table/index) table. This column shows the same information as the column '`TIME`', but in units of milliseconds with microsecond precision (the unit and precision of the `TIME` column is one second).

 For details about microseconds support in MariaDB, see [microseconds in MariaDB](../microseconds-in-mariadb/index).

 The value displayed in the `TIME` and `TIME_MS` columns is the period of time that the given thread has been in its current state. Thus it can be used to check for example how long a thread has been executing the current query, or for how long it has been idle.

 
```
select id, time, time_ms, command, state from
   information_schema.processlist, (select sleep(2)) t;
+----+------+----------+---------+-----------+
| id | time | time_ms  | command | state     |
+----+------+----------+---------+-----------+
| 37 |    2 | 2000.493 | Query   | executing |
+----+------+----------+---------+-----------+

```

Note that as a difference to MySQL, in MariaDB the `TIME` column (and also the `TIME_MS` column) are not affected by any setting of [@TIMESTAMP](../server-system-variables/index#timestamp). This means that it can be reliably used also for threads that change `@TIMESTAMP` (such as the [replication](../replication/index) SQL thread). See also [MySQL Bug #22047](http://bugs.mysql.com/bug.php?id=22047).

 As a consequence of this, the `TIME` column of `SHOW FULL PROCESSLIST` and `INFORMATION_SCHEMA.PROCESSLIST` can not be used to determine if a slave is lagging behind. For this, use instead the `Seconds_Behind_Master` column in the output of [SHOW SLAVE STATUS](../show-slave-status/index).

 The addition of the TIME\_MS column is based on the microsec\_process patch, developed by [Percona](http://www.percona.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/time_ms-column-in-information_schemaprocesslist/>

Information Schema INNODB\_SYS\_FOREIGN Table
=============================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_FOREIGN` table contains information about InnoDB [foreign keys](../foreign-keys/index).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `ID` | Database name and foreign key name. |
| `FOR_NAME` | Database and table name of the foreign key child. |
| `REF_NAME` | Database and table name of the foreign key parent. |
| `N_COLS` | Number of foreign key index columns. |
| `TYPE` | Bit flag providing information about the foreign key. |

 
The `TYPE` column provides a bit flag with information about the foreign key. This information is `OR`'ed together to read:

 


| Bit Flag | Description |
| --- | --- |
| `1` | `ON DELETE CASCADE` |
| `2` | `ON UPDATE SET NULL` |
| `4` | `ON UPDATE CASCADE` |
| `8` | `ON UPDATE SET NULL` |
| `16` | `ON DELETE NO ACTION` |
| `32` | `ON UPDATE NO ACTION` |

 
Example
-------

 
```
SELECT * FROM INNODB_SYS_FOREIGN\G
*************************** 1. row ***************************
      ID: mysql/innodb_index_stats_ibfk_1
FOR_NAME: mysql/innodb_index_stats
REF_NAME: mysql/innodb_table_stats
  N_COLS: 2
    TYPE: 0
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_foreign-table/>

Information Schema INNODB\_SYS\_FOREIGN\_COLS Table
===================================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_FOREIGN_COLS` table contains information about InnoDB [foreign key](../foreign-keys/index) columns.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `ID` | Foreign key index associated with this column, matching the [INNODB\_SYS\_FOREIGN.ID](../information-schema-innodb_sys_foreign-table/index) field. |
| `FOR_COL_NAME` | Child column name. |
| `REF_COL_NAME` | Parent column name. |
| `POS` | Ordinal position of the column in the table, starting from 0. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_foreign_cols-table/>

Fusion-io Introduction
======================

     Fusion-io develops PCIe based NAND flash memory cards and related software that can be used to speed up MariaDB databases.

 The ioDrive branded products can be used as block devices (super-fast disks) or to extend basic DRAM memory. ioDrive is deployed by installing it on an x86 server and then installing the card driver under the operating system. All main line 64-bit operating systems and hypervisors are supported: RHEL, CentOS, SuSe, Debian, OEL etc. and VMware, Microsoft Windows/Server etc. Drivers and their features are constantly developed further.

 ioDrive cards support software RAID and you can combine two or more physical cards into one logical drive. Through ioMemory SDK and its APIs, one can integrate and enable more thorough interworking between your own software and the cards - and cut latency.

 The key differentiator between a Fusion-io and a legacy SSD/HDD is the following: **A Fusion-io card is connected directly on the system bus (PCIe)**, this enables high data transfer throughput (1.5 GB/s, 3.0 GB/s or 6GB/s) and the fast direct memory access (DMA) method can be used to transfer data. The ATA/SATA protocol stack is omitted and therefore latency is cut short. Fusion-io performance is dependent on server speed: the faster processors and the newer PCIe-bus version you have, the better is the ioDrive performance. Fusion-io memory is non-volatile, in other words, data remains on the card even when the server is powered off.

 Use Cases
---------

 1. You can start by using ioDrive for database files that need heavy random access.
2. Whole database on ioDrive.
3. In some cases, Fusion-io devices allow for atomic writes, which allows the server to safely disable the [doublewrite buffer](../xtradbinnodb-doublewrite-buffer/index).
4. Use ioDrive as a write-through read cache. This is possible on server level with Fusion-io directCache software or in VMware environments using ioTurbine software or the ioCache bundle product. Reads happen from ioDrive and all writes go directly to your SAN or disk.
5. Highly Available shared storage with ION. Have two different hosts, Fusion-io cards in them and share/replicate data with Fusion-io's ION software.
6. The luxurious Platinum setup: [MariaDB Galera Cluster](http://kb.askmonty.org/en/what-is-mariadb-galera-cluster/) running on Fusion-io SLC cards on several hosts.

 Atomic Writes
-------------

 Starting with [MariaDB 5.5.31](https://mariadb.com/kb/en/mariadb-5531-release-notes/), MariaDB Server supports atomic writes on Fusion-io devices that use the NVMFS (formerly called DirectFS) file system. Unfortunately, NVMFS was never offered under ‘General Availability’, and SanDisk declared that NVMFS would reach end-of-life in December 2015. Therefore, NVMFS support is no longer offered by SanDisk.

 MariaDB Server does not currently support atomic writes on Fusion-io devices with any other file systems.

 See [atomic write support](../atomic-write-support/index) for more information about MariaDB Server's atomic write support.

 Future Suggested Development
----------------------------

 * Extend InnoDB disk cache to be stored on Fusion-io acting as extended memory.

 Settings For Best Performance
-----------------------------

 Fusion-io memory can be formatted with different sector size of either 512 or 4096 bytes. Bigger sectors are expected to be faster, but only if I/O is done in blocks of 4KB or multiples of that. Speaking of MariaDB: if only InnoDB data files are stored in Fusion-io memory, all I/O is done in blocks of 16K and thus 4K sector size can be used. If the InnoDB redo log (I/O block size: 512 bytes) goes to the same Fusion-io memory, then short sectors should be used.

 Note: XtraDB has the experimental feature of an increased InnoDB log block size of 4K. If this is enabled, then both redo log I/O and page I/O in InnoDB will match a sector size of 4K.

 As of file systems: currently XFS is expected to yield the best performance with MariaDB. However depending on the exact kernel version and version of XFS code in use, one might be affected by [a bug that severely limits XFS performance in concurrent environments](http://www.mysqlperformanceblog.com/2012/03/15/ext4-vs-xfs-on-ssd/comment-page-1/#comment-903938). This has [been fixed in kernel versions above 3.5](https://github.com/torvalds/linux/commit/507630b29f13a3d8689895618b12015308402e22) or [RHEL6 kernels kernel-2.6.32-358 or later](https://rhn.redhat.com/errata/RHSA-2013-0496.html) (because of [bug 807503 being fixed)](https://bugzilla.redhat.com/show_bug.cgi?id=807503).

 For the pitbull machine where I have run such tests, ext4 was faster than xfs for 32 or more threads:

 * up to 8 threads xfs was few percent faster (10% on average).
* at 16 threads it was a draw (2036 tps vs. 2070 tps).
* at 32 threads ext4 was 28% faster (2345 tps vs. 1829 tps).
* at 64 threads ext4 was even 47% faster (2362 tps vs. 1601 tps).
* at higher concurrency ext4 lost it’s bite, but was still constantly better than xfs.

 Those numbers are for spinning disks. I guess for Fusion-io memory the XFS numbers will be even worse.

 Example Configuration
---------------------

 ![GE-Fusionio-MariaDB]

 Card Models
-----------

 There are several card models. ioDrive is older generation, ioDrive2 is newer. SLC sustains more writes. MLC is good enough for normal use.

 1. ioDrive2, capacities per card 365GB, 785GB, 1.2TB with MLC. 400GB and 600GB with SLC, performance up to 535000 IOPS & 1.5GB/s bandwidth
2. ioDrive2 Duo, capacities per card 2.4TB MLC and 1.2TB SLC, performance up to 935000 IOPS & 3.0GB/s bandwidth
3. ioDrive, capacities per card 320GB, 640GB MLC and 160GB, 320GB SLC, performance up to 145000 IOPS & 790MB/s bandwidth
4. ioDrive Duo, capacities per card 640GB, 1.28TB MLC and 320GB, 640GB SLC, performance up to 285000 IOPS & 1.5GB/s bandwidth
5. ioDrive Octal, capacities per card 5TB and 10TB MLC, performance up to 1350000 IOPS & 6.7GB/s bandwidth
6. ioFX, a 420GB QDP MLC workstation product, 1.4GB/s bandwidth
7. ioCache, a 600GB MLC card with ioTurbine software bundle that can be used to speed up VMware based virtual hosts.
8. ioScale, 3.2TB card, building block to enable all-flash data center build out in hyperscale web and cloud environments. Product has been developed in co-operation with Facebook.

 Additional Software
-------------------

 * directCache - transforms ioDrive to work as a read cache in your server. Writes go directly to your SAN
* ioTurbine - read cache software for VMware
* ION - transforms ioDrive into a shareable storage
* ioSphere - software to manage and monitor several ioDrives

 See Also
--------

 * [FusionIO atomic-series devices](http://www.fusionio.com/products/atomic-series)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/fusion-io-introduction/>

InnoDB Recovery Modes
=====================

    The InnoDB recovery mode is a mode used for recovering from emergency situations. You should ensure you have a backup of your database before making changes in case you need to restore it. The [innodb\_force\_recovery](../innodb-system-variables/index#innodb_force_recovery) server system variable sets the recovery mode. A mode of 0 is normal use, while the higher the mode, the more stringent the restrictions. Higher modes incorporate all limitations of the lower modes.

 
The recovery mode should never be set to a value other than zero except in an emergency situation.

 

Please note that recovery mode does not repair corruptions. The corrupted files remain corrupted regardless of recovery mode. The sole purpose of recovery mode is to allow read access to the data, if at all possible.

 
Generally, it is best to start with a recovery mode of 1, and increase in single increments if needs be. With a recovery mode < 4, only corrupted pages should be lost. With 4, secondary indexes could be corrupted. With 5, results could be inconsistent and secondary indexes could be corrupted (even if they were not with 4). A value of 6 leaves pages in an obsolete state, which might cause more corruption.

 Until [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), mode `0` was the only mode permitting changes to the data. From [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), write transactions are permitted with mode `3` or less. 

 To recover the tables, you can execute [SELECTs](../select/index) to dump data, and [DROP TABLE](../drop-table/index) (when write transactions are permitted) to remove corrupted tables.

 The following modes are available:

 Recovery Modes
--------------

 Recovery mode behaviour differs per version (server/storage/innobase/include/srv0srv.h) 

 [MariaDB 10.4](../what-is-mariadb-104/index) and before:

 


| Mode | Description |
| --- | --- |
| 0 | The default mode while InnoDB is running normally. Until [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), it was the only mode permitting changes to the data. From [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), write transactions are permitted with innodb\_force\_recovery<=3. |
| 1 | (SRV\_FORCE\_IGNORE\_CORRUPT) allows the the server to keep running even if corrupt pages are detected. It does so by making redo log based recovery ignore certain errors, such as missing data files or corrupted data pages. Any redo log for affected files or pages will be skipped. You can facilitate dumping tables by getting the SELECT \* FROM table\_name statement to jump over corrupt indexes and pages. |
| 2 | (SRV\_FORCE\_NO\_BACKGROUND) stops the master thread from running, preventing a crash that occurs during a purge. No purge will be performed, so the undo logs will keep growing. |
| 3 | (SRV\_FORCE\_NO\_TRX\_UNDO) does not roll back transactions after the crash recovery. Does not affect rollback of currently active transactions. Starting with [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/), will also prevent some undo-generating background tasks from running. These tasks could hit a lock wait due to the recovered incomplete transactions whose rollback is being prevented. |
| 4 | (SRV\_FORCE\_NO\_IBUF\_MERGE) does not calculate tables statistics and prevents insert buffer merges. |
| 5 | (SRV\_FORCE\_NO\_UNDO\_LOG\_SCAN) treats incomplete transactions as committed, and does not look at the [undo logs](../undo-log/index) when starting. |
| 6 | (SRV\_FORCE\_NO\_LOG\_REDO) does not perform redo log roll-forward as part of recovery. Running queries that require indexes are likely to fail with this mode active. However, if a table dump still causes a crash, you can try using a `SELECT * FROM tab ORDER BY primary_key DESC` to dump all the data portion after the corrupted part. |

 
From [MariaDB 10.5](../what-is-mariadb-105/index) to [MariaDB 10.6.4](https://mariadb.com/kb/en/mariadb-1064-release-notes/):

 


| Mode | Description |
| --- | --- |
| 0 | The default mode while InnoDB is running normally. Write transactions are permitted with innodb\_force\_recovery<=4. |
| 1 | (SRV\_FORCE\_IGNORE\_CORRUPT) allows the the server to keep running even if corrupt pages are detected. It does so by making redo log based recovery ignore certain errors, such as missing data files or corrupted data pages. Any redo log for affected files or pages will be skipped. You can facilitate dumping tables by getting the SELECT \* FROM table\_name statement to jump over corrupt indexes and pages. |
| 2 | (SRV\_FORCE\_NO\_BACKGROUND) stops the master thread from running, preventing a crash that occurs during a purge. No purge will be performed, so the undo logs will keep growing. |
| 3 | (SRV\_FORCE\_NO\_TRX\_UNDO) does not roll back transactions after the crash recovery. Does not affect rollback of currently active transactions. Will also prevent some undo-generating background tasks from running. These tasks could hit a lock wait due to the recovered incomplete transactions whose rollback is being prevented. |
| 4 | (SRV\_FORCE\_NO\_IBUF\_MERGE) The same as 3. |
| 5 | (SRV\_FORCE\_NO\_UNDO\_LOG\_SCAN) treats incomplete transactions as committed, and does not look at the [undo logs](../undo-log/index) when starting. |
| 6 | (SRV\_FORCE\_NO\_LOG\_REDO) does not perform redo log roll-forward as part of recovery. Running queries that require indexes are likely to fail with this mode active. However, if a table dump still causes a crash, you can try using a `SELECT * FROM tab ORDER BY primary_key DESC` to dump all the data portion after the corrupted part. |

 
From [MariaDB 10.6.5](https://mariadb.com/kb/en/mariadb-1065-release-notes/)

 


| Mode | Description |
| --- | --- |
| 0 | The default mode while InnoDB is running normally. Write transactions are permitted with innodb\_force\_recovery<=4. |
| 1 | (SRV\_FORCE\_IGNORE\_CORRUPT) allows the the server to keep running even if corrupt pages are detected. It does so by making redo log based recovery ignore certain errors, such as missing data files or corrupted data pages. Any redo log for affected files or pages will be skipped. You can facilitate dumping tables by getting the SELECT \* FROM table\_name statement to jump over corrupt indexes and pages. |
| 2 | (SRV\_FORCE\_NO\_BACKGROUND) stops the master thread from running, preventing a crash that occurs during a purge. No purge will be performed, so the undo logs will keep growing. |
| 3 | (SRV\_FORCE\_NO\_TRX\_UNDO) does not roll back DML transactions after the crash recovery. Does not affect rollback of currently active DML transactions. Will also prevent some undo-generating background tasks from running. These tasks could hit a lock wait due to the recovered incomplete transactions whose rollback is being prevented. |
| 4 | (SRV\_FORCE\_NO\_DDL\_UNDO) does not roll back transactions after the crash recovery. Does not affect rollback of currently active transactions. Will also prevent some undo-generating background tasks from running. These tasks could hit a lock wait due to the recovered incomplete transactions whose rollback is being prevented. |
| 5 | (SRV\_FORCE\_NO\_UNDO\_LOG\_SCAN) treats incomplete transactions as committed, and does not look at the [undo logs](../undo-log/index) when starting. Any DDL log for InnoDB tables will be essentially ignored by InnoDB, but the server will start up |
| 6 | (SRV\_FORCE\_NO\_LOG\_REDO) does not perform redo log roll-forward as part of recovery. Running queries that require indexes are likely to fail with this mode active. However, if a table dump still causes a crash, you can try using a `SELECT * FROM tab ORDER BY primary_key DESC` to dump all the data portion after the corrupted part. |

 
Note also that XtraDB (<= [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/)) by default will crash the server when it detects corrupted data in a single-table tablespace. This behaviour can be changed - see the [innodb\_corrupt\_table\_action](../xtradbinnodb-server-system-variables/index#innodb_corrupt_table_action) system variable.

 Fixing Things
-------------

 Try to set innodb\_force\_recovery to 1 and start mariadb. If that fails, try a value of "2". If a value of 2 works, then there is a chance the only corruption you have experienced is within the innodb "undo logs". If that gets mariadb started, you should be able to dump your database with [mariadb-dump](../mariadb-dump/index). You can verify any other issues with any tables by running [mariadb-check --all-databases](../mariadb-check/index).

 If you were able to successfully dump your databases, or had previously known good backups, drop your database(s) from the mariadb command line like "[DROP DATABASE](../drop-database/index) yourdatabase". Stop mariadb. Go to /var/lib/mysql (or whereever your mysql data directory is located) and "rm -i ib\*". Start mariadb, create the database(s) you dropped ("[CREATE DATABASE](../create-database/index) yourdatabase"), and then import your most recent dumps: "mysql < mydatabasedump.sql"

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-recovery-modes/>

Information Schema INNODB\_TABLESPACES\_SCRUBBING Table
=======================================================

    
**MariaDB [10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) - [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**InnoDB and XtraDB data scrubbing was introduced in [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/). The table was removed in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) - see [MDEV-15528](https://jira.mariadb.org/browse/MDEV-15528).

  The [Information Schema](../information_schema/index) `INNODB_TABLESPACES_SCRUBBING` table contains [data scrubbing](../xtradb-innodb-data-scrubbing/index) information.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `SPACE` | InnoDB table space id number. |
| `NAME` | Path to the table space file, without the extension. |
| `COMPRESSED` | The compressed page size, or zero if uncompressed. |
| `LAST_SCRUB_COMPLETED` | Date and time when the last scrub was completed, or `NULL` if never been performed. |
| `CURRENT_SCRUB_STARTED` | Date and time when the current scrub started, or `NULL` if never been performed. |
| `CURRENT_SCRUB_ACTIVE_THREADS` | Number of threads currently scrubbing the tablespace. |
| `CURRENT_SCRUB_PAGE_NUMBER` | Page that the scrubbing thread is currently scrubbing, or `NULL` if not enabled. |
| `CURRENT_SCRUB_MAX_PAGE_NUMBER` | When a scrubbing starts rotating a table space, the field contains its current size. `NULL` if not enabled. |
| `ON_SSD` | The field contains `1` when MariaDB detects that the table space is on a SSD based storage. `0` if not SSD or it could not be determined (since [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/)) |

 
Example
-------

 
```
SELECT * FROM information_schema.INNODB_TABLESPACES_SCRUBBING LIMIT 1\G
*************************** 1. row ***************************
                        SPACE: 1
                         NAME: mysql/innodb_table_stats
                   COMPRESSED: 0
         LAST_SCRUB_COMPLETED: NULL
        CURRENT_SCRUB_STARTED: NULL
    CURRENT_SCRUB_PAGE_NUMBER: NULL
CURRENT_SCRUB_MAX_PAGE_NUMBER: 0
         ROTATING_OR_FLUSHING: 0
1 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_tablespaces_scrubbing-table/>

Information Schema INNODB\_CMP\_PER\_INDEX and INNODB\_CMP\_PER\_INDEX\_RESET Tables
====================================================================================

    The `INNODB_CMP_PER_INDEX` and `INNODB_CMP_PER_INDEX_RESET` tables contain status information on compression operations related to [compressed XtraDB/InnoDB tables](../innodb-storage-formats/index#compressed), grouped by individual indexes. These tables are only populated if the [innodb\_cmp\_per\_index\_enabled](../innodb-system-variables/index#innodb_cmp_per_index_enabled) system variable is set to `ON`.

 The [PROCESS](../grant/index#global-privileges) privilege is required to query this table.

 These tables contains the following columns:

 


| Column Name | Description |
| --- | --- |
| `DATABASE_NAME` | Database containing the index. |
| `TABLE_NAME` | Table containing the index. |
| `INDEX_NAME` | Other values are totals which refer to this index's compression. |
| `COMPRESS_OPS` | How many times a page of `INDEX_NAME` has been compressed. This happens when a new page is created because the compression log runs out of space. This value includes both successful operations and *compression failures*. |
| `COMPRESS_OPS_OK` | How many times a page of `INDEX_NAME` has been successfully compressed. This value should be as close as possible to `COMPRESS_OPS`. If it is notably lower, either avoid compressing some tables, or increase the KEY\_BLOCK\_SIZE for some compressed tables. |
| `COMPRESS_TIME` | Time (in seconds) spent to compress pages of the size `PAGE_SIZE`. This value includes time spent in *compression failures*. |
| `UNCOMPRESS_OPS` | How many times a page of `INDEX_NAME` has been uncompressed. This happens when an uncompressed version of a page is created in the buffer pool, or when a *compression failure* occurs. |
| `UNCOMPRESS_TIME` | Time (in seconds) spent to uncompress pages of `INDEX_NAME`. |

 
These tables can be used to measure the effectiveness of XtraDB/InnoDB compression, per table or per index. The values in these tables show which tables perform better with index compression, and which tables cause too many *compression failures* or perform too many compression/uncompression operations. When compression performs badly for a table, this might mean that you should change its `KEY_BLOCK_SIZE`, or that the table should not be compressed.

 `INNODB_CMP_PER_INDEX` and `INNODB_CMP_PER_INDEX_RESET` have the same columns and always contain the same values, but when `INNODB_CMP_PER_INDEX_RESET` is queried, both the tables are cleared. `INNODB_CMP_PER_INDEX_RESET` can be used, for example, if a script periodically logs the performances of compression in the last period of time. `INNODB_CMP_PER_INDEX` can be used to see the cumulated statistics.

 See Also
--------

 Other tables that can be used to monitor XtraDB/InnoDB compressed tables:

 * [INNODB\_CMP and INNODB\_CMP\_RESET](../information_schemainnodb_cmp-and-innodb_cmp_reset-tables/index)
* [INNODB\_CMPMEM and INNODB\_CMPMEM\_RESET](../information_schemainnodb_cmpmem-and-innodb_cmpmem_reset-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb-tables-information-schema-innodb_cmp_per_index-an/>

Information Schema INNODB\_FT\_INDEX\_TABLE Table
=================================================

    The [Information Schema](../information_schema/index) `INNODB_FT_INDEX_TABLE` table contains information about InnoDB [fulltext indexes](../full-text-indexes/index). To avoid re-organizing the fulltext index each time a change is made, which would be very expensive, new changes are stored separately and only integrated when an [OPTIMIZE TABLE](../optimize-table/index) is run. See the [INNODB\_FT\_INDEX\_CACHE](../information-schema-innodb_ft_index_cache-table/index) table.

 The `SUPER` [privilege](../grant/index) is required to view the table, and it also requires the [innodb\_ft\_aux\_table](../innodb-system-variables/index#innodb_ft_aux_table) system variable to be set.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `WORD` | Word from the text of a column with a fulltext index. Words can appear multiple times in the table, once per `DOC_ID` and `POSITION` combination. |
| `FIRST_DOC_ID` | First document ID where this word appears in the index. |
| `LAST_DOC_ID` | Last document ID where this word appears in the index. |
| `DOC_COUNT` | Number of rows containing this word in the index. |
| `DOC_ID` | Document ID of the newly added row, either an appropriate ID column or an internal InnoDB value. |
| `POSITION` | Position of this word instance within the `DOC_ID`, as an offset added to the previous `POSITION` instance. |

 
Note that for `OPTIMIZE TABLE` to process InnoDB fulltext index data, the [innodb\_optimize\_fulltext\_only](innodb-server-system-variables#innodb_optimize_fulltext_only) system variable needs to be set to `1`. When this is done, and an `OPTIMIZE TABLE` statement run, the [INNODB\_FT\_INDEX\_CACHE](../information-schema-innodb_ft_index_cache-table/index) table will be emptied, and the `INNODB_FT_INDEX_TABLE` table will be updated. 

 Examples
--------

 
```
SELECT * FROM INNODB_FT_INDEX_TABLE;
Empty set (0.00 sec)

SET GLOBAL innodb_optimize_fulltext_only =1;

OPTIMIZE TABLE test.ft_innodb;
+----------------+----------+----------+----------+
| Table          | Op       | Msg_type | Msg_text |
+----------------+----------+----------+----------+
| test.ft_innodb | optimize | status   | OK       |
+----------------+----------+----------+----------+

SELECT * FROM INNODB_FT_INDEX_TABLE;
+------------+--------------+-------------+-----------+--------+----------+
| WORD       | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------------+--------------+-------------+-----------+--------+----------+
| and        |            4 |           5 |         2 |      4 |        0 |
| and        |            4 |           5 |         2 |      5 |        0 |
| arrived    |            4 |           4 |         1 |      4 |       20 |
| ate        |            1 |           5 |         2 |      1 |        4 |
| ate        |            1 |           5 |         2 |      5 |        8 |
| everybody  |            1 |           1 |         1 |      1 |        8 |
| goldilocks |            4 |           4 |         1 |      4 |        9 |
| hungry     |            3 |           3 |         1 |      3 |        8 |
| pear       |            5 |           5 |         1 |      5 |       14 |
| she        |            5 |           5 |         1 |      5 |        4 |
| then       |            4 |           4 |         1 |      4 |        4 |
| wicked     |            2 |           2 |         1 |      2 |        4 |
| witch      |            2 |           2 |         1 |      2 |       11 |
+------------+--------------+-------------+-----------+--------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_index_table-table/>

Information Schema INNODB\_FT\_INDEX\_CACHE Table
=================================================

    The [Information Schema](../information_schema/index) `INNODB_FT_INDEX_CACHE` table contains information about rows that have recently been inserted into an InnoDB [fulltext index](../full-text-indexes/index). To avoid re-organizing the fulltext index each time a change is made, which would be very expensive, new changes are stored separately and only integrated when an [OPTIMIZE TABLE](../optimize-table/index) is run.

 The `SUPER` [privilege](../grant/index) is required to view the table, and it also requires the [innodb\_ft\_aux\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_aux_table) system variable to be set.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `WORD` | Word from the text of a newly added row. Words can appear multiple times in the table, once per `DOC_ID` and `POSITION` combination. |
| `FIRST_DOC_ID` | First document ID where this word appears in the index. |
| `LAST_DOC_ID` | Last document ID where this word appears in the index. |
| `DOC_COUNT` | Number of rows containing this word in the index. |
| `DOC_ID` | Document ID of the newly added row, either an appropriate ID column or an internal InnoDB value. |
| `POSITION` | Position of this word instance within the `DOC_ID`, as an offset added to the previous `POSITION` instance. |

 
Note that for `OPTIMIZE TABLE` to process InnoDB fulltext index data, the [innodb\_optimize\_fulltext\_only](../xtradbinnodb-server-system-variables/index#innodb_optimize_fulltext_only) system variable needs to be set to `1`. When this is done, and an `OPTIMIZE TABLE` statement run, the `INNODB_FT_INDEX_CACHE` table will be emptied, and the [INNODB\_FT\_INDEX\_TABLE](../information-schema-innodb_ft_index_table-table/index) table will be updated. 

 Examples
--------

 
```
SELECT * FROM INNODB_FT_INDEX_CACHE;
+------------+--------------+-------------+-----------+--------+----------+
| WORD       | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------------+--------------+-------------+-----------+--------+----------+
| and        |            4 |           4 |         1 |      4 |        0 |
| arrived    |            4 |           4 |         1 |      4 |       20 |
| ate        |            1 |           1 |         1 |      1 |        4 |
| everybody  |            1 |           1 |         1 |      1 |        8 |
| goldilocks |            4 |           4 |         1 |      4 |        9 |
| hungry     |            3 |           3 |         1 |      3 |        8 |
| then       |            4 |           4 |         1 |      4 |        4 |
| wicked     |            2 |           2 |         1 |      2 |        4 |
| witch      |            2 |           2 |         1 |      2 |       11 |
+------------+--------------+-------------+-----------+--------+----------+
9 rows in set (0.00 sec)

INSERT INTO test.ft_innodb VALUES(3,'And she ate a pear');

SELECT * FROM INNODB_FT_INDEX_CACHE;
+------------+--------------+-------------+-----------+--------+----------+
| WORD       | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------------+--------------+-------------+-----------+--------+----------+
| and        |            4 |           5 |         2 |      4 |        0 |
| and        |            4 |           5 |         2 |      5 |        0 |
| arrived    |            4 |           4 |         1 |      4 |       20 |
| ate        |            1 |           5 |         2 |      1 |        4 |
| ate        |            1 |           5 |         2 |      5 |        8 |
| everybody  |            1 |           1 |         1 |      1 |        8 |
| goldilocks |            4 |           4 |         1 |      4 |        9 |
| hungry     |            3 |           3 |         1 |      3 |        8 |
| pear       |            5 |           5 |         1 |      5 |       14 |
| she        |            5 |           5 |         1 |      5 |        4 |
| then       |            4 |           4 |         1 |      4 |        4 |
| wicked     |            2 |           2 |         1 |      2 |        4 |
| witch      |            2 |           2 |         1 |      2 |       11 |
+------------+--------------+-------------+-----------+--------+----------+

```


```
OPTIMIZE TABLE test.ft_innodb\G
*************************** 1. row ***************************
   Table: test.ft_innodb
      Op: optimize
Msg_type: note
Msg_text: Table does not support optimize, doing recreate + analyze instead
*************************** 2. row ***************************
   Table: test.ft_innodb
      Op: optimize
Msg_type: status
Msg_text: OK
2 rows in set (2.24 sec)

SELECT * FROM INNODB_FT_INDEX_CACHE;
+------------+--------------+-------------+-----------+--------+----------+
| WORD       | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION |
+------------+--------------+-------------+-----------+--------+----------+
| and        |            4 |           5 |         2 |      4 |        0 |
| and        |            4 |           5 |         2 |      5 |        0 |
| arrived    |            4 |           4 |         1 |      4 |       20 |
| ate        |            1 |           5 |         2 |      1 |        4 |
| ate        |            1 |           5 |         2 |      5 |        8 |
| everybody  |            1 |           1 |         1 |      1 |        8 |
| goldilocks |            4 |           4 |         1 |      4 |        9 |
| hungry     |            3 |           3 |         1 |      3 |        8 |
| pear       |            5 |           5 |         1 |      5 |       14 |
| she        |            5 |           5 |         1 |      5 |        4 |
| then       |            4 |           4 |         1 |      4 |        4 |
| wicked     |            2 |           2 |         1 |      2 |        4 |
| witch      |            2 |           2 |         1 |      2 |       11 |
+------------+--------------+-------------+-----------+--------+----------+
13 rows in set (0.00 sec)

```

The `OPTIMIZE TABLE` statement has no effect, because the [innodb\_optimize\_fulltext\_only](innodb-server-system-variables#innodb_optimize_fulltext_only) variable wasn't set:

 
```
SHOW VARIABLES LIKE 'innodb_optimize_fulltext_only';
+-------------------------------+-------+
| Variable_name                 | Value |
+-------------------------------+-------+
| innodb_optimize_fulltext_only | OFF   |
+-------------------------------+-------+

SET GLOBAL innodb_optimize_fulltext_only =1;

OPTIMIZE TABLE test.ft_innodb;
+----------------+----------+----------+----------+
| Table          | Op       | Msg_type | Msg_text |
+----------------+----------+----------+----------+
| test.ft_innodb | optimize | status   | OK       |
+----------------+----------+----------+----------+

SELECT * FROM INNODB_FT_INDEX_CACHE;
Empty set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_index_cache-table/>

Information Schema INNODB\_FT\_DELETED Table
============================================

    The [Information Schema](../information_schema/index) `INNODB_FT_DELETED` table contains rows that have been deleted from an InnoDB [fulltext index](../full-text-indexes/index). This information is then used to filter results on subsequent searches, removing the need to expensively reorganise the index each time a row is deleted.

 The fulltext index is then only reorganized when an [OPTIMIZE TABLE](../optimize-table/index) statement is underway. The related [INNODB\_FT\_BEING\_DELETED](../information-schema-innodb_ft_being_deleted-table/index) table contains rows being deleted while an `OPTIMIZE TABLE` is in the process of running.

 The `SUPER` [privilege](../grant/index) is required to view the table, and it also requires the [innodb\_ft\_aux\_table](../innodb-system-variables/index#innodb_ft_aux_table) system variable to be set.

 It has the following column:

 


| Column | Description |
| --- | --- |
| `DOC_ID` | Document ID of the deleted row deleted. Either an underlying ID value, or a sequence value generated by InnoDB if no usable option exists. |

 
Example
-------

 
```
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
+--------+
| DOC_ID |
+--------+
|      2 |
+--------+

DELETE FROM test.ft_innodb LIMIT 1;

SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
+--------+
| DOC_ID |
+--------+
|      2 |
|      3 |
+--------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_deleted-table/>

Information Schema INNODB\_FT\_BEING\_DELETED Table
===================================================

    The [Information Schema](../information_schema/index) `INNODB_FT_BEING_DELETED` table is only used while document ID's in the related [INNODB\_FT\_DELETED](../information-schema-innodb_ft_deleted-table/index) are being removed from an InnoDB [fulltext index](../full-text-indexes/index) while an [OPTIMIZE TABLE](../optimize-table/index) is underway. At all other times the table will be empty.

 The `SUPER` [privilege](../grant/index) is required to view the table, and it also requires the [innodb\_ft\_aux\_table](../innodb-system-variables/index#innodb_ft_aux_table) system variable to be set.

 It has the following column:

 


| Column | Description |
| --- | --- |
| `DOC_ID` | Document ID of the row being deleted. Either an underlying ID value, or a sequence value generated by InnoDB if no usable option exists. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_being_deleted-table/>

Information Schema INNODB\_CHANGED\_PAGES Table
===============================================

    The [Information Schema](../information_schema/index) `INNODB_CHANGED_PAGES` Table contains data about modified pages from the bitmap file. It is updated at checkpoints by the log tracking thread parsing the log, so does not contain real-time data.

 The number of records is limited by the value of the [innodb\_max\_changed\_pages](../xtradbinnodb-server-system-variables/index#innodb_max_changed_pages) system variable.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `SPACE_ID` | Modified page space id |
| `PAGE_ID` | Modified page id |
| `START_LSN` | Interval start after which page was changed (equal to checkpoint LSN) |
| `END_LSN` | Interval end before which page was changed (equal to checkpoint LSN) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_changed_pages-table/>

Information Schema INNODB\_METRICS Table
========================================

     The [Information Schema](../information_schema/index) `INNODB_METRICS` table contains a list of useful InnoDB performance metrics. Each row in the table represents an instrumented counter that can be stopped, started and reset, and which can be grouped together by module.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Unique counter name. |
| `SUBSYSTEM` | InnoDB subsystem. See below for the matching module to use to enable/disable monitoring this subsytem with the [innodb\_monitor\_enable](../innodb-system-variables/index#innodb_monitor_enable) and [innodb\_monitor\_disable](../innodb-system-variables/index#innodb_monitor_disable) system variables. |
| `COUNT` | Count since being enabled. |
| `MAX_COUNT` | Maximum value since being enabled. |
| `MIN_COUNT` | Minimum value since being enabled. |
| `AVG_COUNT` | Average value since being enabled. |
| `COUNT_RESET` | Count since last being reset. |
| `MAX_COUNT_RESET` | Maximum value since last being reset. |
| `MIN_COUNT_RESET` | Minimum value since last being reset. |
| `AVG_COUNT_RESET` | Average value since last being reset. |
| `TIME_ENABLED` | Time last enabled. |
| `TIME_DISABLED` | Time last disabled |
| `TIME_ELAPSED` | Time since enabled |
| `TIME_RESET` | Time last reset. |
| `STATUS` | Whether the counter is currently enabled to disabled. |
| `TYPE` | Item type; one of `counter`, `value`, `status_counter`, `set_owner`, `set_member`. |
| `COMMENT` | Counter description. |

 
Enabling and Disabling Counters
-------------------------------

 Most of the counters are disabled by default. To enable them, use the [innodb\_monitor\_enable](../innodb-system-variables/index#innodb_monitor_enable) system variable. You can either enable a variable by its name, for example:

 
```
SET GLOBAL innodb_monitor_enable = icp_match;

```

or enable a number of counters grouped by module. The `SUBSYSTEM` field indicates which counters are grouped together, but the following module names need to be used:

 


| Module Name | Subsytem Field |
| --- | --- |
| `module_metadata` | `metadata` |
| `module_lock` | `lock` |
| `module_buffer` | `buffer` |
| `module_buf_page` | `buffer_page_io` |
| `module_os` | `os` |
| `module_trx` | `transaction` |
| `module_purge` | `purge` |
| `module_compress` | `compression` |
| `module_file` | `file_system` |
| `module_index` | `index` |
| `module_adaptive_hash` | `adaptive_hash_index` From [MariaDB 10.6.2](https://mariadb.com/kb/en/mariadb-1062-release-notes/), if [innodb\_adaptive\_hash\_index](../innodb-system-variables/index#innodb_adaptive_hash_index) is disabled (the default), `adaptive_hash_index` will not be updated. |
| `module_ibuf_system` | `change_buffer` |
| `module_srv` | `server` |
| `module_ddl` | `ddl` |
| `module_dml` | `dml` |
| `module_log` | `recovery` |
| `module_icp` | `icp` |

 
There are four counters in the `icp` subsystem:

 
```
SELECT NAME, SUBSYSTEM FROM INNODB_METRICS WHERE SUBSYSTEM='icp';
+------------------+-----------+
| NAME             | SUBSYSTEM |
+------------------+-----------+
| icp_attempts     | icp       |
| icp_no_match     | icp       |
| icp_out_of_range | icp       |
| icp_match        | icp       |
+------------------+-----------+

```

To enable them all, use the associated module name from the table above, `module_icp`.

 
```
SET GLOBAL innodb_monitor_enable = module_icp;

```

The `%` wildcard, used to represent any number of characters, can also be used when naming counters, for example:

 
```
SET GLOBAL innodb_monitor_enable = 'buffer%'

```

To disable counters, use the [innodb\_monitor\_disable](../innodb-system-variables/index#innodb_monitor_disable) system variable, using the same naming rules as described above for enabling.

 Counter status is not persistent, and will be reset when the server restarts. It is possible to use the options on the command line, or the `innodb_monitor_enable` option only in a configuration file.

 Resetting Counters
------------------

 Counters can also be reset. Resetting sets all the `*_COUNT_RESET` values to zero, while leaving the `*_COUNT` values, which perform counts since the counter was enabled, untouched. Resetting is performed with the [innodb\_monitor\_reset](../innodb-system-variables/index#innodb_monitor_reset) (for individual counters) and [innodb\_monitor\_reset\_all](../innodb-system-variables/index#innodb_monitor_reset_all) (for all counters) system variables.

 Simplifying from [MariaDB 10.6](../what-is-mariadb-106/index)
-------------------------------------------------------------

 
**MariaDB starting with [10.6](../what-is-mariadb-106/index)**From [MariaDB 10.6](../what-is-mariadb-106/index), the interface was simplified by removing the following:

 * buffer\_LRU\_batches\_flush
* buffer\_LRU\_batch\_flush\_pages
* buffer\_LRU\_batches\_evict
* buffer\_LRU\_batch\_evict\_pages

 and by making the following reflect the status variables:

 * buffer\_LRU\_batch\_flush\_total\_pages: [innodb\_buffer\_pool\_pages\_LRU\_flushed](../innodb-status-variables/index#innodb_buffer_pool_pages_lru_flushed)
* buffer\_LRU\_batch\_evict\_total\_pages: [innodb\_buffer\_pool\_pages\_LRU\_freed](../innodb-status-variables/index#innodb_buffer_pool_pages_lru_freed)

 The intention is to eventually remove the interface entirely (see [MDEV-15706](https://jira.mariadb.org/browse/MDEV-15706)).

 
Examples
--------

 [MariaDB 10.8](../what-is-mariadb-108/index):

 
```
SELECT name,subsystem,type,comment FROM INFORMATION_SCHEMA.INNODB_METRICS\G
*************************** 1. row ***************************
     name: metadata_table_handles_opened
subsystem: metadata
     type: counter
  comment: Number of table handles opened
*************************** 2. row ***************************
     name: lock_deadlocks
subsystem: lock
     type: value
  comment: Number of deadlocks
*************************** 3. row ***************************
     name: lock_timeouts
subsystem: lock
     type: value
  comment: Number of lock timeouts
*************************** 4. row ***************************
     name: lock_rec_lock_waits
subsystem: lock
     type: counter
  comment: Number of times enqueued into record lock wait queue
*************************** 5. row ***************************
     name: lock_table_lock_waits
subsystem: lock
     type: counter
  comment: Number of times enqueued into table lock wait queue
*************************** 6. row ***************************
     name: lock_rec_lock_requests
subsystem: lock
     type: counter
  comment: Number of record locks requested
*************************** 7. row ***************************
     name: lock_rec_lock_created
subsystem: lock
     type: counter
  comment: Number of record locks created
*************************** 8. row ***************************
     name: lock_rec_lock_removed
subsystem: lock
     type: counter
  comment: Number of record locks removed from the lock queue
*************************** 9. row ***************************
     name: lock_rec_locks
subsystem: lock
     type: counter
  comment: Current number of record locks on tables
*************************** 10. row ***************************
     name: lock_table_lock_created
subsystem: lock
     type: counter
  comment: Number of table locks created

...

*************************** 207. row ***************************
     name: icp_attempts
subsystem: icp
     type: counter
  comment: Number of attempts for index push-down condition checks
*************************** 208. row ***************************
     name: icp_no_match
subsystem: icp
     type: counter
  comment: Index push-down condition does not match
*************************** 209. row ***************************
     name: icp_out_of_range
subsystem: icp
     type: counter
  comment: Index push-down condition out of range
*************************** 210. row ***************************
     name: icp_match
subsystem: icp
     type: counter
  comment: Index push-down condition matches

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_metrics-table/>

Information Schema XTRADB\_RSEG Table
=====================================

    
**MariaDB starting with [10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/)**The `XTRADB_RSEG` table was added in [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/).

 
The [Information Schema](../information_schema/index) `XTRADB_RSEG` table contains information about the XtraDB rollback segments.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `rseg_id` | Rollback segment id. |
| `space_id` | Space where the segment is placed. |
| `zip_size` | Size in bytes of the compressed page size, or zero if uncompressed. |
| `page_no` | Page number of the segment header. |
| `max_size` | Maximum size in pages. |
| `curr_size` | Current size in pages. |

 
The number of records will match the value set in the `[innodb\_undo\_logs](../xtradbinnodb-server-system-variables/index#innodb_undo_logs)` variable (by default 128).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-xtradb_rseg-table/>

Roles Overview
==============

    Description
-----------

 A role bundles a number of privileges together. It assists larger organizations where, typically, a number of users would have the same privileges, and, previously, the only way to change the privileges for a group of users was by changing each user's privileges individually. 

 Alternatively, multiple external users could have been assigned the same user, and there would have been no way to see which actual user was responsible for which action.

 With roles, managing this is easy. For example, there could be a number of users assigned to a journalist role, with identical privileges. Changing the privileges for all the journalists is a matter of simply changing the role's privileges, while the individual user is still linked with any changes that take place.

 Roles are created with the [CREATE ROLE](../create-role/index) statement, and dropped with the [DROP ROLE](../drop-role/index) statement. Roles are then assigned to a user with an extension to the [GRANT](../grant/index#roles) statement, while privileges are assigned to a role in the regular way with [GRANT](../grant/index). Similarly, the [REVOKE](../revoke/index) statement can be used to both revoke a role from a user, or revoke a privilege from a role.

 Once a user has connected, he can obtain all privileges associated with a role by **setting** a role with the [SET ROLE](../set-role/index) statement. The [CURRENT\_ROLE](../current_role/index) function returns the currently set role for the session, if any.

 Only roles granted directly to a user can be set, roles granted to other roles cannot. Instead the privileges granted to a role, which is, in turn, granted to another role (grantee), will be immediately available to any user who sets this second grantee role.

 The [SET DEFAULT ROLE](../set-default-role/index) statement allows one to set a default role for a user. A default role is automatically enabled when a user connects (an implicit SET ROLE statement is executed immediately after a connection is established).

 Roles were implemented as a GSoC 2013 project by Vicentiu Ciorbaru. 

 System Tables
-------------

 Information about roles and who they've been granted to can be found in the [Information Schema APPLICABLE\_ROLES table](../information-schema-applicable_roles-table/index) as well as the [mysql.ROLES\_MAPPING table](../mysqlroles_mapping-table/index).

 The [Information Schema ENABLED\_ROLES table](../information-schema-enabled_roles-table/index) shows the enabled roles for the current session.

 Examples
--------

 Creating a role and granting a privilege:

 
```
CREATE ROLE journalist;

GRANT SHOW DATABASES ON *.* TO journalist;

GRANT journalist to hulda;

```

Note, that hulda has no `SHOW DATABASES` privilege, even though she was granted the journalist role. She needs to **set** the role first:

 
```
SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SET ROLE journalist;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| journalist   |
+--------------+

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| ...                |
| information_schema |
| mysql              |
| performance_schema |
| test               |
| ...                |
+--------------------+

SET ROLE NONE;

```

Roles can be granted to roles:

 
```
CREATE ROLE writer;

GRANT SELECT ON data.* TO writer;

GRANT writer TO journalist;

```

But one does not need to set a role granted to a role. For example, hulda will automatically get all writer privileges when she sets the journalist role:

 
```
SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| NULL         |
+--------------+

SHOW TABLES FROM data;
Empty set (0.01 sec)

SET ROLE journalist;

SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| journalist   |
+--------------+

SHOW TABLES FROM data;
+------------------------------+
| Tables_in_data               |
+------------------------------+
| set1                         |
| ...                          |
+------------------------------+

```

Roles and Views (and Stored Routines)
-------------------------------------

 When a user sets a role, he, in a sense, has two identities with two associated sets of privileges. But a view (or a stored routine) can have only one definer. So, when a view (or a stored routine) is created with the `SQL SECURITY DEFINER`, one can specify whether the definer should be `CURRENT_USER` (and the view will have none of the privileges of the user's role) or `CURRENT_ROLE` (in this case, the view will use role's privileges, but none of the user's privileges). As a result, sometimes one can create a view that is impossible to use.

 
```
CREATE ROLE r1;

GRANT ALL ON db1.* TO r1;

GRANT r1 TO foo@localhost;

GRANT ALL ON db.* TO foo@localhost;

SELECT CURRENT_USER
+---------------+
| current_user  |
+---------------+
| foo@localhost |
+---------------+

SET ROLE r1;

CREATE TABLE db1.t1 (i int);

CREATE VIEW db.v1 AS SELECT * FROM db1.t1;

SHOW CREATE VIEW db.v1;
+------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View                                                                                                                              | character_set_client | collation_connection |
+------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| v1   | CREATE ALGORITHM=UNDEFINED DEFINER=`foo`@`localhost` SQL SECURITY DEFINER VIEW `db`.`v1` AS SELECT `db1`.`t1`.`i` AS `i` from `db1`.`t1` | utf8                 | utf8_general_ci      |
+------+------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+

CREATE DEFINER=CURRENT_ROLE VIEW db.v2 AS SELECT * FROM db1.t1;

SHOW CREATE VIEW db.b2;
+------+-----------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View | Create View                                                                                                                 | character_set_client | collation_connection |
+------+-----------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| v2   | CREATE ALGORITHM=UNDEFINED DEFINER=`r1` SQL SECURITY DEFINER VIEW `db`.`v2` AS select `db1`.`t1`.`a` AS `a` from `db1`.`t1` | utf8                 | utf8_general_ci      |
+------+-----------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+

```

Other Resources
---------------

 * [Roles Review](http://ocelot.ca/blog/blog/2014/01/12/roles-review/) by Peter Gulutzan

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/roles_overview/>

User and Group Mapping with PAM
===============================

    Even when using the `[pam](../authentication-plugin-pam/index)` authentication plugin, the authenticating PAM user account still needs to exist in MariaDB, and the account needs to have privileges in the database. Creating these MariaDB accounts and making sure the privileges are correct can be a lot of work. To decrease the amount of work involved, some users would like to be able to map a PAM user to a different MariaDB user. For example, let’s say that `alice` and `bob` are both DBAs. It would be nice if each of them could log into MariaDB with their own PAM username and password, while MariaDB sees both of them as the same `dba` user. That way, there is only one MariaDB account to keep track of.

 Although most PAM modules usually do not do things like this, PAM supports the ability to change the user name in the process of authentication.The MariaDB `pam` authentication plugin fully supports this feature of PAM. 

 The pam\_user\_map PAM Module
-----------------------------

 Rather than building user and group mapping into the `pam` authentication plugin, MariaDB thought that it would cover the most use cases and offer the most flexibility to offload this functionality to an external PAM module. The `pam_user_map` PAM module was implemented by MariaDB to facilitate this. This PAM module can be [configured in the PAM service](../authentication-plugin-pam/index#configuring-the-pam-service) used by the `pam` authentication plugin, just like other PAM modules. 

 ### Lack of Support for MySQL/Percona Group Mapping Syntax

 Unlike MariaDB, MySQL and Percona implemented group mapping in their PAM authentication plugins. If you've read through [MySQL's PAM authentication documentation on group mapping](https://dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html#pam-authentication-unix-with-proxy) or [Percona's PAM authentication documentation on group mapping](https://www.percona.com/doc/percona-server/8.0/management/pam_plugin.html#supplementary-groups-support), you've probably seen syntax where the group mappings are provided in the `[CREATE USER](../create-user/index)` statement like this:

 
```
CREATE USER ''@''
  IDENTIFIED WITH authentication_pam
  AS 'mysql, root=developer, users=data_entry';

```

Since MariaDB's user and group mapping is performed by an external PAM module, MariaDB's `pam` authentication plugin does not support this syntax. Instead, the user and group mappings for the `pam_user_map` PAM module are configured in an external configuration file. This is discussed in a later section. 

 Installing the pam\_user\_map PAM Module
----------------------------------------

 The `pam_user_map` PAM module gets installed as part of all our MariaDB server packages since [MariaDB 10.5](../what-is-mariadb-105/index), and was added since 10.2.31, 10.3.22, and 10.4.12 in previous MariaDB major releases where it was not present from the beginning.

 Some Linux distributions have not picked up this change in their own packages yet, so when e.g. installing MariaDB server from stock Ubuntu packages on Ubuntu 20.04LTS you still won't have the `pam_user_map` module installed even though the MariaDB server installed is more recent than [MariaDB 10.3.22](https://mariadb.com/kb/en/mariadb-10322-release-notes/).

 When using such an installation, and not being able to switch to our own MariaDB package repositories, it may be necessary to compile the PAM module from source as described in the next section, or to manually extract it from one of our server packages and copy it to the target system.

 ### Installing the pam\_user\_map PAM Module from Source

 #### Installing Compilation Dependencies

 Before the module can be compiled from source, you may need to install some dependencies.

 On RHEL, CentOS, and other similar Linux distributions that use [RPM packages](../rpm/index), you need to install `gcc`, `pam-devel` and `MariaDB-devel`. For example:

 
```
sudo yum install gcc pam-devel MariaDB-devel

```

On Debian, Ubuntu, and other similar Linux distributions that use [DEB packages](../installing-mariadb-deb-files/index), you need to install `gcc`, `libpam0g-dev`. For example:

 
```
sudo apt-get install gcc libpam0g-dev libmariadb-dev

```

#### Compiling and Installing the pam\_user\_map PAM Module

 The `pam_user_map` PAM module can be built by downloading `plugin/auth_pam/mapper/pam_user_map.c` file from the MariaDB source tree and compiling it after minor adjustments. Once it is built, it can be installed to the system's PAM module directory, which is typically `/lib64/security/`. 

 For example: (replace 10.4 in the URL with the actual server versions)

 
```
wget https://raw.githubusercontent.com/MariaDB/server/10.4/plugin/auth_pam/mapper/pam_user_map.c
sed -ie 's/config_auth_pam/plugin_auth_common/' pam_user_map.c
gcc -I/usr/include/mysql/ pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so
sudo install --mode=0755 pam_user_map.so /lib64/security/

```

You will also need to adjust the major version number in the URL on the first line to match your installed MariaDB version, and the #-I# include path argument on the `gcc` line, as depending on operating system and MariaDB server version the plugin\_auth\_common.h file may be installed in different directories than `/usr/include/mysql/`

 Configuring the pam\_user\_map PAM Module
-----------------------------------------

 The `pam_user_map` PAM module uses the configuration file at the path `/etc/security/user_map.conf` to determine its user and group mappings. The file's format is described below.

 To map a specific PAM user to a specific MariaDB user:

 
```
orig_pam_user_name: mapped_mariadb_user_name

```

Or to map any PAM user in a specific PAM group to a specific MariaDB user, the group name is prefixed with `@`:

 
```
@orig_pam_group_name: mapped_mariadb_user_name

```

For example, here is an example `/etc/security/user_map.conf`:

 
```
=========================================================
#comments and empty lines are ignored
john: jack
bob:  admin
top:  accounting
@group_ro: readonly

```

Configuring PAM
---------------

 With user and group mapping, configuring PAM is done similar to how it is [normally done with the `pam` authentication plugin](../authentication-plugin-pam/index#configuring-pam). However, when configuring the PAM service, you will have to add an `auth` line for the `pam_user_map` PAM module to the service's PAM configuration file. For example:

 
```
auth required pam_unix.so audit
auth required pam_user_map.so
account required pam_unix.so audit

```

Creating Users
--------------

 With user and group mapping, creating users is done similar to how it is [normally done with the `pam` authentication plugin](../authentication-plugin-pam/index#creating-users). However, one major difference is that you will need to `[GRANT](../grant/index)` the `[PROXY](../grant/index#proxy-privileges)` privilege on the mapped user to the original user.

 For example, if you have the following configured in `/etc/security/user_map.conf`:

 
```
foo: bar
@dba:dba

```

Then you could execute the following to grant the relevant privileges:

 
```
CREATE USER 'bar'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'bar'@'%' ;

CREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'%' ;

CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
GRANT PROXY ON 'bar'@'%' TO ''@'%';
GRANT PROXY ON 'dba'@'%' TO ''@'%';

```

Note that the `''@'%'` account is a special catch-all [anonymous account](../create-user/index#anonymous-accounts). Any login by a user that has no more specific account match in the system will be matched by this anonymous account.

 Also note that you might not be able to create the `''@'%'` anonymous account by default on some systems without doing some extra steps first. See [Fixing a Legacy Default Anonymous Account](../create-user/index#fixing-a-legacy-default-anonymous-account) for more information.

 Verifying that Mapping is Occurring
-----------------------------------

 In case any user mapping is performed, the original user name is returned by the SQL function `[USER()](../user/index)`, while the authenticated user name is returned by the SQL function `[CURRENT\_USER()](../current_user/index)`. The latter actually defines what privileges are available to a connected user.

 For example, if we have the following configured:

 
```
foo: bar

```

Then the following output would verify that it is working properly:

 
```
$ mysql -u foo -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 22
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+------------------------------------------------+----------------+
| USER()                                         | CURRENT_USER() |
+------------------------------------------------+----------------+
| foo@ip-172-30-0-198.us-west-2.compute.internal | bar@%          |
+------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `foo` PAM user was properly mapped to the `bar` MariaDB user by looking at the return value of `[CURRENT\_USER()](../current_user/index)`.

 Logging
-------

 By default, the `pam_user_map` PAM module does not perform any logging. However, if you want to enable debug logging, then you can add the `debug` module argument to the service's PAM configuration file. For example:

 
```
auth required pam_unix.so audit
auth required pam_user_map.so debug
account required pam_unix.so audit

```

When debug logging is enabled, the `pam_user_map` PAM module will write log entries to the [same syslog location](../authentication-plugin-pam/index#logging) as other PAM modules, which is typically `/var/log/secure` on many systems.

 For example, this debug log output can look like the following:

 
```
Jan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.
Jan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'alice'.
Jan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 2 groups [alice,dba].
Jan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': YES
Jan  9 05:42:13 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'dba'
Jan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.
Jan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'bob'.
Jan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 2 groups [bob,dba].
Jan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': YES
Jan  9 05:43:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'dba'
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Opening file '/etc/security/user_map.conf'.
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Incoming username 'foo'.
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User belongs to 1 group [foo].
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if user is in group 'dba': NO
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): Check if username 'foo': YES
Jan  9 06:08:36 ip-172-30-0-198 mysqld: pam_user_map(mariadb:auth): User mapped as 'bar'

```

Known Issues
------------

 ### PAM User with Same Name as Mapped MariaDB User Must Exist

 With user and group mapping, any PAM user or any PAM user in a given PAM group can be mapped to a specific MariaDB user account. However, due to the way PAM works, a PAM user with the same name as the mapped MariaDB user account must exist.

 For example, if the configuration file for the PAM service file contained the following:

 
```
auth required pam_sss.so
auth required pam_user_map.so debug
account sufficient pam_unix.so
account sufficient pam_sss.so

```

And if `/etc/security/user_map.conf` contained the following:

 
```
@dba: dba

```

Then any PAM user in the PAM group `dba` would be mapped to the MariaDB user account `dba`. But if a PAM user with the name `dba` did not also exist, then the `pam_user_map` PAM module's debug logging would write errors to the syslog like the following:

 
```
Sep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Opening file '/etc/security/user_map.conf'.
Sep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Incoming username 'alice'.
Sep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): User belongs to 4 groups [dba,mongod,mongodba,mysql].
Sep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): Check if user is in group 'mysql': YES
Sep 27 17:17:05 dbserver1 mysqld: pam_user_map(mysql:auth): User mapped as 'dba'
Sep 27 17:17:05 dbserver1 mysqld: pam_unix(mysql:account): could not identify user (from getpwnam(dba))
Sep 27 17:17:05 dbserver1 mysqld: pam_sss(mysql:account): Access denied for user dba: 10 (User not known to the underlying authentication module)
Sep 27 17:17:05 dbserver1 mysqld: 2018-09-27 17:17:05 72 [Warning] Access denied for user 'alice'@'localhost' (using password: NO)

```

In the above log snippet, notice that both the `pam_unix` and the `pam_sss` PAM modules are complaining that the `dba` PAM user does not appear to exist, and that these complaints cause the PAM authentication process to fail, which causes the MariaDB authentication process to fail as well.

 This can be fixed by creating a PAM user with the same name as the mapped MariaDB user account, which is `dba` in this case.

 You may also be able to work around this problem by essentially disabling PAM's account verification for the service with the `[pam\_permit](https://linux.die.net/man/8/pam_permit)` PAM module. For example, in the above case, that would be:

 
```
auth required pam_sss.so
auth required pam_user_map.so debug
account required pam_permit.so

```

See [MDEV-17315](https://jira.mariadb.org/browse/MDEV-17315) for more information.

 Tutorials
---------

 You may find the following PAM and user mapping-related tutorials helpful:

 * [Configuring PAM Authentication and User Mapping with Unix Authentication](../configuring-pam-authentication-and-user-mapping-with-unix-authentication/index)
* [Configuring PAM Authentication and User Mapping with LDAP Authentication](../configuring-pam-authentication-and-user-mapping-with-ldap-authentication/index)

 See Also
--------

 * [Configuring PAM Authentication and User Mapping with MariaDB](https://mariadb.com/resources/blog/configuring-pam-authentication-and-user-mapping-with-mariadb/)
* [Configuring PAM Group Mapping with MariaDB](https://mariadb.com/resources/blog/configuring-pam-group-mapping-with-mariadb/)
* [Configuring LDAP Authentication and Group Mapping With MariaDB](http://www.geoffmontee.com/configuring-ldap-authentication-and-group-mapping-with-mariadb/)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/user-and-group-mapping-with-pam/>

Installing and Using MariaDB via Docker
=======================================

     Sometimes we want to install a specific version of MariaDB, [MariaDB ColumnStore](../mariadb-columnstore/index), or [MaxScale](../mariadb-maxscale/index) on a certain system, but no packages are available. Or maybe, we simply want to isolate MariaDB from the rest of the system, to be sure that we won't cause any damage.

 A virtual machine would certainly serve the scope. However, this means installing a system on the top of another system. It requires a lot of resources.

 In many cases, the best solution is using containers. Docker is a framework that runs containers. A container is meant to run a specific daemon, and the software that is needed for that daemon to properly work. Docker does not virtualize a whole system; a container only includes the packages that are not included in the underlying system.

 Docker requires a very small amount of resources. It can run on a virtualized system. It is used both in development and in production environments. Docker is an open source project, released under the Apache License, version 2.

 Note that, while your package repositories could have a package called `docker`, it is probably not the Docker we are talking about. The Docker package could be called `docker.io` or `docker-engine`.

 For information about installing Docker, see [Get Docker](https://docs.docker.com/get-docker/) in Docker documentation.

 Installing Docker on Your System with the Universal Installation Script
-----------------------------------------------------------------------

 The script below will install the Docker repositories, required kernel modules and packages on the most common Linux distributions:

 
```
curl -sSL https://get.docker.com/ | sh

```

### Starting dockerd

 On some systems you may have to start the `dockerd daemon` yourself:

 
```
sudo systemctl start docker
sudo gpasswd -a "${USER}" docker

```

If you don't have `dockerd` running, you will get the following error for most `docker` commands: installing-and-using-mariadb-via-docker Cannot connect to the Docker daemon at unix:*/var/run/docker.sock. Is the docker daemon running? <</code>>*

 Using MariaDB Images
--------------------

 The easiest way to use MariaDB on Docker is choosing a MariaDB image and creating a container.

 ### Downloading an Image

 You can download a MariaDB image for Docker from the [Offical Docker MariaDB](https://hub.docker.com/_/mariadb/), or choose another image that better suits your needs. You can search Docker Hub (the official set of repositories) for an image with this command:

 
```
 docker search mariadb

```

Once you have found an image that you want to use, you can download it via Docker. Some layers including necessary dependencies will be downloaded too. Note that, once a layer is downloaded for a certain image, Docker will not need to download it again for another image.

 For example, if you want to install the default MariaDB image, you can type:

 
```
docker pull mariadb:10.4

```

This will install the 10.4 version. Versions 10.2, 10.3, 10.5 are also valid choices.

 You will see a list of necessary layers. For each layer, Docker will say if it is already present, or its download progress.

 To get a list of installed images:

 
```
docker images

```

### Creating a Container

 An image is not a running process; it is just the software needed to be launched. To run it, we must create a container first. The command needed to create a container can usually be found in the image documentation. For example, to create a container for the official MariaDB image:

 
```
docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d docker.io/library/mariadb:10.3

```

`mariadbtest` is the name we want to assign the container. If we don't specify a name, an id will be automatically generated.

 10.2 and 10.5 are also valid target versions:

 
```
docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d docker.io/library/mariadb:10.2

```


```
docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306  -d docker.io/library/mariadb:10.5

```

Optionally, after the image name, we can specify some [options for mysqld](../mysqld-options/index). For example:

 
```
docker run --name mariadbtest -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 -d mariadb:10.3 --log-bin --binlog-format=MIXED

```

Docker will respond with the container's id. But, just to be sure that the container has been created and is running, we can get a list of running containers in this way:

 
```
docker ps

```

We should get an output similar to this one:

 
```
CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS              PORTS               NAMES
819b786a8b48        mariadb                    "/docker-entrypoint.   4 minutes ago       Up 4 minutes        3306/tcp            mariadbtest        

```

### Running and Stopping the Container

 Docker allows us to restart a container with a single command:

 
```
docker restart mariadbtest

```

The container can also be stopped like this:

 
```
docker stop mariadbtest

```

The container will not be destroyed by this command. The data will still live inside the container, even if MariaDB is not running. To restart the container and see our data, we can issue:

 
```
docker start mariadbtest

```

With `docker stop`, the container will be gracefully terminated: a `SIGTERM` signal will be sent to the `mysqld` process, and Docker will wait for the process to shutdown before returning the control to the shell. However, it is also possible to set a timeout, after which the process will be immediately killed with a `SIGKILL`. Or it is possible to immediately kill the process, with no timeout.

 
```
docker stop --time=30 mariadbtest
docker kill mariadbtest

```

In case we want to destroy a container, perhaps because the image does not suit our needs, we can stop it and then run:

 
```
docker rm mariadbtest

```

Note that the command above does not destroy the data volume that Docker has created for /var/lib/mysql. If you want to destroy the volume as well, use:

 
```
docker rm -v mariadbtest

```

#### Automatic Restart

 When we start a container, we can use the `--restart` option to set an automatic restart policy. This is useful in production.

 Allowed values are:

 * `no`: No automatic restart.
* `on-failure`: The container restarts if it exits with a non-zero exit code.
* `unless-stopped`: Always restart the container, unless it was explicitly stopped as shown above.
* `always`: Similar to `unless-stopped`, but when Docker itself restarts, even containers that were explicitly stopped will restart.

 It is possible to change the restart policy of existing, possibly running containers:

 
```
docker update --restart always mariadb
# or, to change the restart policy of all containers:
docker update --restart always $(docker ps -q)

```

A use case for changing the restart policy of existing containers is performing maintenance in production. For example, before upgrading the Docker version, we may want to change all containers restart policy to `always`, so they will restart as soon as the new version is up and running. However, if some containers are stopped and not needed at the moment, we can change their restart policy to `unless-stopped`.

 #### Pausing Containers

 A container can also be frozen with the `pause` command. Docker will freeze the process using croups. MariaDB will not know that it is being frozen and, when we `unpause` it, MariaDB will resume its work as expected.

 Both `pause` and `unpause` accept one or more container names. So, if we are running a cluster, we can freeze and resume all nodes simultaneously:

 
```
docker pause node1 node2 node3
docker unpause node1 node2 node3

```

Pausing a container is very useful when we need to temporarily free our system's resources. If the container is not crucial at this moment (for example, it is performing some batch work), we can free it to allow other programs to run faster.

 ### Troubleshooting a Container

 If the container doesn't start, or is not working properly, we can investigate with the following command:

 
```
docker logs mariadbtest

```

This command shows what the daemon sent to the stdout since the last attempt of starting - the text that we typically see when we invoke `mysqld` from the command line.

 On some systems, commands such as `docker stop mariadbtest` and `docker restart mariadbtest` may fail with a permissions error. This can be caused by AppArmor, and even `sudo` won't allow you to execute the command. In this case, you will need to find out which profile is causing the problem and correct it, or disable it. **Disabling AppArmor altogether is not recommended, especially in production.**

 To check which operations were prevented by AppArmor, see [AppArmor Failures](https://gitlab.com/apparmor/apparmor/-/wikis/AppArmor_Failures) in AppArmor documentation.

 To disable a profile, create a symlink with the profile name (in this example, `mysqld`) to `etc/apparmor.d/disable`, and then reload profiles:

 
```
ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld

```

For more information, see [Policy Layout](https://gitlab.com/apparmor/apparmor/-/wikis/Policy_Layout) in AppArmor documentation.

 After disabling the profile, you may need to run:

 
```
sudo service docker restart
docker system prune --all --volumes

```

Restarting the system will then allow Docker to operate normally.

 ### Accessing the Container

 To access the container via Bash, we can run this command:

 
```
docker exec -it mariadbtest bash

```

Now we can use normal Linux commands like *cd*, *ls*, etc. We will have root privileges. We can even install our favorite file editor, for example:

 
```
apt-get update
apt-get install vim

```

In some images, no repository is configured by default, so we may need to add them.

 Note that if we run [mariadb-admin shutdown](../mariadb-admin/index#mariadb-admin-commands) or the [SHUTDOWN](../shutdown/index) command to stop the container, the container will be deactivated, and we will automatically exit to our system.

 ### Connecting to MariaDB from Outside the Container

 If we try to connect to the MariaDB server on `localhost`, the client will bypass networking and attempt to connect to the server using a socket file in the local filesystem. However, this doesn't work when MariaDB is running inside a container because the server's filesystem is isolated from the host. The client can't access the socket file which is inside the container, so it fails to connect.

 Therefore connections to the MariaDB server must be made using TCP, even when the client is running on the same machine as the server container.

 Find the IP address that has been assigned to the container:

 
```
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mariadbtest

```

You can now connect to the MariaDB server using a TCP connection to that IP address.

 #### Forcing a TCP Connection

 After enabling network connections in MariaDB as described above, we will be able to connect to the server from outside the container.

 On the host, run the client and set the server address ("-h") to the container's IP address that you found in the previous step:

 
```
mysql -h 172.17.0.2 -u root -p

```

This simple form of the connection should work in most situations. Depending on your configuration, it may also be necessary to specify the port for the server or to force TCP mode:

 
```
mysql -h 172.17.0.2 -P 3306 --protocol=TCP -u root -p

```

#### Port Configuration for Clustered Containers and Replication

 Multiple MariaDB servers running in separate Docker containers can connect to each other using TCP. This is useful for forming a Galera cluster or for replication.

 When running a cluster or a replication setup via Docker, we will want the containers to use different ports. The fastest way to achieve this is mapping the containers ports to different port on our system. We can do this when creating the containers (`docker run` command), by using the `-p` option, several times if necessary. For example, for Galera nodes we will use a mapping similar to this one:

 
```
-p 4306:3306 -p 5567:5567 -p 5444:5444 -p 5568:5568

```

Installing MariaDB on Another Image
-----------------------------------

 It is possible to download a Linux distribution image, and to install MariaDB on it. This is not much harder than installing MariaDB on a regular operating system (which is easy), but it is still the hardest option. Normally we will try existing images first. However, it is possible that no image is available for the exact version we want, or we want a custom installation, or perhaps we want to use a distribution for which no images are available. In these cases, we will install MariaDB in an operating system image.

 ### Daemonizing the Operating System

 First, we need the system image to run as a daemon. If we skip this step, MariaDB and all databases will be lost when the container stops.

 To demonize an image, we need to give it a command that never ends. In the following example, we will create a Debian Jessie daemon that constantly pings the 8.8.8.8 special address:

 
```
docker run --name debian -p 3306:3306 -d debian /bin/sh -c "while true; do ping 8.8.8.8; done"

```

### Installing MariaDB

 At this point, we can enter the shell and issue commands. First we will need to update the repositories, or no packages will be available. We can also update the packages, in case some of them are newer than the image. Then, we will need to install a text editor; we will need it to edit configuration files. For example:

 
```
# start an interactive Bash session in the container
docker exec -ti debian bash
apt-get -y update
apt-get -y upgrade
apt-get -y install vim

```

Now we are ready to [install MariaDB](../getting-installing-and-upgrading-mariadb/index) in the way we prefer.

 See Also
--------

 * [Official MariaDB Docker Images Webinar](https://go.mariadb.com/GLBL-WBN_2018-10-09-MariaDB_Containers.html).
* [Docker official site](https://www.docker.com/).
* [Docker Hub](https://hub.docker.com/).
* [Docker documentation](https://docs.docker.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-and-using-mariadb-via-docker/>

InnoDB Background Encryption Threads
====================================

    InnoDB performs some encryption and decryption operations with background encryption threads. The [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable controls the number of threads that the storage engine uses for encryption-related background operations, including encrypting and decrypting pages after key rotations or configuration changes, and [scrubbing](../innodb-data-scrubbing/index) data to permanently delete it.

 Background Operations
---------------------

 InnoDB performs the following encryption and decryption operations using background encryption threads:

 * When [rotating encryption keys](../encryption-key-management/index#key-rotation), InnoDB's background encryption threads re-encrypt pages that use key versions older than [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) to the new key version.
* When changing the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable to `FORCE`, InnoDB's background encryption threads encrypt the [system](../innodb-system-tablespaces/index) tablespace and any [file-per-table](../innodb-file-per-table-tablespaces/index) tablespaces that have the `[ENCRYPTED](../create-table/index#encrypted)` table option set to `DEFAULT`.
* When changing the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable to `OFF`, InnoDB's background encryption threads decrypt the [system](../innodb-system-tablespaces/index) tablespace and any [file-per-table](../innodb-file-per-table-tablespaces/index) tablespacs that have the `[ENCRYPTED](../create-table/index#encrypted)` table option set to `DEFAULT`.

 The [innodb\_encryption\_rotation\_iops](../innodb-system-variables/index#innodb_encryption_rotation_iops) system variable can be used to configure how many I/O operations you want to allow for the operations performed by InnoDB's background encryption threads.

 
Whenever you change the value on the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable, InnoDB's background encryption threads perform the necessary encryption or decryption operations. Because of this, you must have a non-zero value set for the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable. InnoDB also considers these operations to be key rotations internally. Because of this, you must have a non-zero value set for the [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable. For more information, see [disabling key rotations](#disabling-background-key-rotation-operations).

 
Non-background Operations
-------------------------

 InnoDB performs the following encryption and decryption operations **without** using background encryption threads:

 * When a [file-per-table](innodb-file-per-table-tablspaces) tablespaces and using [ALTER TABLE](../alter-table/index) to manually set the [ENCRYPTED](../create-table/index#encrypted) table option to `YES`, InnoDB does **not** use background threads to encrypt the tablespaces.
* Similarly, when using [file-per-table](innodb-file-per-table-tablspaces) tablespaces and using [ALTER TABLE](../alter-table/index) to manually set the [ENCRYPTED](../create-table/index#encrypted) table option to `NO`, InnoDB does **not** use background threads to decrypt the tablespaces.

 In these cases, InnoDB performs the encryption or decryption operation using the server thread for the client connection that executes the statement. This means that you can update encryption on [file-per-table](../innodb-file-per-table-tablespaces/index) tablespaces with an [ALTER TABLE](../alter-table/index) statement, even when the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) and/or the [innodb\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variables are set to `0`.

 
InnoDB does not permit manual encryption changes to tables in the [system](../innodb-system-tablespaces/index) tablespace using [ALTER TABLE](../alter-table/index). Encryption of the [system](../innodb-system-tablespaces/index) tablespace can only be configured by setting the value of the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable. This means that when you want to encrypt or decrypt the [system](../innodb-system-tablespaces/index) tablespace, you must also set a non-zero value for the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable, and you must also set the [innodb\_system\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable to `1` to ensure that the system tablespace is properly encrypted or decrypted by the background threads. See [MDEV-14398](https://jira.mariadb.org/browse/MDEV-14398) for more information.

 
Checking the Status of Background Operations
--------------------------------------------

 InnoDB records the status of background encryption operations in the [INNODB\_TABLESPACES\_ENCRYPTION](information-schema-innodb_tablespaces_encryption) table in the [information\_schema](../information-schema/index) database. 

 For example, to see which InnoDB tablespaces are currently being decrypted or encrypted on by background encryption, you can check which InnoDB tablespaces have the `ROTATING_OR_FLUSHING` column set to `1`:

 
```
SELECT SPACE, NAME
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE ROTATING_OR_FLUSHING = 1;

```

And to see how many InnoDB tablespaces are currently being decrypted or encrypted by background encryption threads, you can call the [COUNT()](../count/index) aggregate function.

 
```
SELECT COUNT(*) AS 'encrypting' 
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE ROTATING_OR_FLUSHING = 1;

```

And to see how many InnoDB tablespaces are currently being decrypted or encrypted by background encryption threads, while comparing that to the total number of InnoDB tablespaces and the total number of encrypted InnoDB tablespaces, you can join the table with the [INNODB\_SYS\_TABLESPACES](../information-schema-innodb_sys_tablespaces-table/index) table in the [information\_schema](../information-schema/index) database:

 
```
/* information_schema.INNODB_TABLESPACES_ENCRYPTION does not always have rows for all tablespaces,
  so let's join it with information_schema.INNODB_SYS_TABLESPACES */
WITH tablespace_ids AS (
   SELECT SPACE
   FROM information_schema.INNODB_SYS_TABLESPACES ist
   UNION
   /* information_schema.INNODB_SYS_TABLESPACES doesn't have a row for the system tablespace (MDEV-20802) */
   SELECT 0 AS SPACE
)
SELECT NOW() as 'time', 
   'tablespaces', COUNT(*) AS 'tablespaces', 
   'encrypted', SUM(IF(ite.ENCRYPTION_SCHEME IS NOT NULL, ite.ENCRYPTION_SCHEME, 0)) AS 'encrypted', 
   'encrypting', SUM(IF(ite.ROTATING_OR_FLUSHING IS NOT NULL, ite.ROTATING_OR_FLUSHING, 0)) AS 'encrypting'
FROM tablespace_ids
LEFT JOIN information_schema.INNODB_TABLESPACES_ENCRYPTION ite
   ON tablespace_ids.SPACE = ite.SPACE

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-background-encryption-threads/>

InnoDB Encryption Keys
======================

    InnoDB uses [encryption key management](../encryption-key-management/index) plugins to support the use of multiple [encryption keys](../encryption-key-management/index#using-multiple-encryption-keys).

 Encryption Keys
---------------

 Each encryption key has a 32-bit integer that serves as a key identifier.

 The default key is set using the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable.

 Encryption keys can also be specified with the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option for tables that use [file-per-table](../innodb-file-per-table-tablespaces/index) tablespaces.

 InnoDB encrypts the [temporary tablespace](../innodb-temporary-tablespaces/index) using the encryption key with the ID `1`.

 InnoDB encrypts the [Redo Log](../innodb-redo-log/index) using the encryption key with the ID `1`.

 ### Keys with Manually Encrypted Tablespaces

 With tables that use [manually](../innodb-enabling-encryption/index#enabling-encryption-for-manually-encrypted-tablespaces) enabled encryption, one way to set the specific encryption key for the table is to use the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option. For example:

 
```
CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=YES ENCRYPTION_KEY_ID=100;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

If the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option is not set for a table that uses [manually](../innodb-enabling-encryption/index#enabling-encryption-for-manually-encrypted-tablespaces) enabled encryption, then it will inherit the value from the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable. For example:

 
```
SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=YES;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

### Keys with Automatically Encrypted Tablespaces

 With tables that use [automatically](../innodb-enabling-encryption/index#enabling-encryption-for-automatically-encrypted-tablespaces) enabled encryption, one way to set the specific encryption key for the table is to use the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable. For example: 

 
```
SET GLOBAL innodb_encryption_threads=4;

SET GLOBAL innodb_encrypt_tables=ON;

SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
);

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

InnoDB tables that are part of the [system](../innodb-system-tablespaces/index) tablespace can only be encrypted using the encryption key set by the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable.

 If the table is in a [file-per-table](../innodb-file-per-table-tablespaces/index) tablespace, and if [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `ON` or `FORCE`, and if [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) is set to a value greater than `0`, then you can also set the specific encryption key for the table by using the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option. For example:

 
```
SET GLOBAL innodb_encryption_threads=4;

SET GLOBAL innodb_encrypt_tables=ON;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTION_KEY_ID=100;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
    -> FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
    -> WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

However, if [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `OFF` or if [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) is set to `0`, then this will not work. See [InnoDB Encryption Troubleshooting: Setting Encryption Key ID For an Unencrypted Table](../innodb-encryption-troubleshooting/index#setting-encryption-key-id-for-an-unencrypted-table) for more information.

 Key Rotation
------------

 Some [key management and encryption plugins](../encryption-key-management/index) allow you to automatically rotate and version your encryption keys. If a plugin support key rotation, and if it rotates the encryption keys, then InnoDB's [background encryption threads](../innodb-background-encryption-threads/index) can re-encrypt InnoDB pages that use the old key version with the new key version. 

 You can set the maximum age for an encryption key using the [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable. When this variable is set to a non-zero value, background encryption threads constantly check pages to determine if any page is encrypted with a key version that's too old. When the key version is too old, any page encrypted with the older version of the key is automatically re-encrypted in the background to use a more current version of the key. Bear in mind, this constant checking can sometimes result in high CPU usage.

 Key rotation for the InnoDB [Redo Log](../innodb-redo-log/index) is only supported in [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) and later. For more information, see [MDEV-12041](https://jira.mariadb.org/browse/MDEV-12041).

 
In order for key rotation to work, both the backend key management service (KMS) and the corresponding [key management and encryption plugin](../encryption-key-management/index) have to support key rotation. See [Encryption Key Management: Support for Key Rotation in Encryption Plugins](../encryption-key-management/index#support-for-key-rotation-in-encryption-plugins) to determine which plugins currently support key rotation.

 
### Disabling Background Key Rotation Operations

 In the event that you encounter issues with background key encryption, you can disable it by setting the [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable to `0`. You may find this useful when the constant key version checks lead to excessive CPU usage. It's also useful in cases where your encryption key management plugin does not support key rotation, (such as with the [file\_key\_management](../encryption-key-management/index#file-key-management-encryption-plugin) plugin). For more information, see [MDEV-14180](https://jira.mariadb.org/browse/MDEV-14180).

 There are, however, issues that can arise when the background key rotation is disabled. 

 #### Pending Encryption Operations

 Prior to [MariaDB 10.2.24](https://mariadb.com/kb/en/mariadb-10224-release-notes/), [MariaDB 10.3.15](https://mariadb.com/kb/en/mariadb-10315-release-notes/), and [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/), when you update the value on the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable InnoDB internally treats the subsequent [background operations](../innodb-background-encryption-threads/index#background-operations) to encrypt and decrypt tablespaces as background key rotations. See [MDEV-14398](https://jira.mariadb.org/browse/MDEV-14398) for more information.

 In older versions of MariaDB, if you have recently changed the value of the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable, then you must ensure that any pending background encryption or decryption operations are complete before disabling key rotation. You can check the status of background encryption operations by querying the [INNODB\_TABLESPACES\_ENCRYPTION](../information-schema-innodb_tablespaces_encryption-table/index) table in the [information\_schema](../information-schema/index) database.

 See [InnoDB Background Encryption Threads: Checking the Status of Background Operations](../innodb-background-encryption-threads/index#checking-the-status-of-background-operations) for some example queries.

 Otherwise, in older versions of MariaDB, if you disable key rotation while there are background encryption threads at work, it may result in unencrypted tables that you want encrypted or vice versa. 

 For more information, see [MDEV-14398](https://jira.mariadb.org/browse/MDEV-14398).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-encryption-keys/>

Checking MariaDB RPM Package Signatures
=======================================

    MariaDB RPM packages since [MariaDB 5.1.55](https://mariadb.com/kb/en/mariadb-5155-release-notes/) are signed.

 The key we use has an id of `1BB943DB` and the key fingerprint is:

 
```
1993 69E5 404B D5FC 7D2F E43B CBCB 082A 1BB9 43DB

```

To check the signature you first need to import the public part of the key like so:

 
```
gpg --keyserver hkp://pgp.mit.edu --recv-keys 1BB943DB

```

Next you need to let pgp know about the key like so:

 
```
gpg --export --armour 1BB943DB > mariadb-signing-key.asc
sudo rpm --import mariadb-signing-key.asc

```

You can check to see if the key was imported with:

 
```
rpm -qa gpg-pubkey*

```

Once the key is imported, you can check the signature of the MariaDB RPM files by running the something like the following in your download directory:

 
```
rpm --checksig $(find . -name '*.rpm')

```

The output of the above will look something like this (make sure gpg shows up on each OK line):

 
```
me@desktop:~$ rpm --checksig $(find . -name '*.rpm')
./kvm-rpm-centos5-amd64/rpms/MariaDB-test-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/rpms/MariaDB-server-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/rpms/MariaDB-client-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/rpms/MariaDB-shared-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/rpms/MariaDB-devel-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/rpms/MariaDB-debuginfo-5.1.55-98.el5.x86_64.rpm: (sha1) dsa sha1 md5 gpg OK
./kvm-rpm-centos5-amd64/srpms/MariaDB-5.1.55-98.el5.src.rpm: (sha1) dsa sha1 md5 gpg OK

```

See Also
--------

 * [Installing MariaDB RPM Files](../installing-mariadb-rpm-files/index)
* [Troubleshooting MariaDB Installs on RedHat/CentOS](../troubleshooting-mariadb-installs-on-redhatcentos/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/checking-mariadb-rpm-package-signatures/>

About the MariaDB RPM Files
===========================

    Available RPM Packages
----------------------

 The available RPM packages depend on the specific MariaDB release series.

 ### Available RPM Packages in [MariaDB 10.4](../what-is-mariadb-104/index)

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**From [MariaDB 10.4](../what-is-mariadb-104/index), the following RPMs are available:

 


| Package Name | Description |
| --- | --- |
| `galera-4` | The WSREP provider for [Galera](../galera/index) 4. |
| `MariaDB-backup` | [Mariabackup](../mariabackup/index) |
| `MariaDB-backup-debuginfo` | Debuginfo for [Mariabackup](../mariabackup/index) |
| `MariaDB-client` | Client tools like [mariadb CLI](../mariadb-client/index), [mariadb-dump](../mariadb-dump/index), and others. |
| `MariaDB-client-debuginfo` | Debuginfo for client tools like `mariadb` CLI, `mariadb-dump`, and others. |
| `MariaDB-common` | Character set files and `/etc/my.cnf` |
| `MariaDB-common-debuginfo` | Debuginfo for character set files and `/etc/my.cnf` |
| `MariaDB-compat` | Old shared client libraries, may be needed by old MariaDB or MySQL clients |
| `MariaDB-connect-engine` | The `[CONNECT](../connect/index)` storage engine. |
| `MariaDB-connect-engine-debuginfo` | Debuginfo for the `[CONNECT](../connect/index)` storage engine. |
| `MariaDB-cracklib-password-check` | The `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `MariaDB-cracklib-password-check` | Debuginfo for the `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `MariaDB-devel` | Development headers and static libraries. |
| `MariaDB-devel-debuginfo` | Debuginfo for development headers and static libraries. |
| `MariaDB-gssapi-server` | The `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `MariaDB-gssapi-server-debuginfo` | Debuginfo for the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `MariaDB-rocksdb-engine` | The [MyRocks](../myrocks/index) storage engine. |
| `MariaDB-rocksdb-engine-debuginfo` | Debuginfo for the [MyRocks](../myrocks/index) storage engine. |
| `MariaDB-server` | The server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `MariaDB-server-debuginfo` | Debuginfo for the server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `MariaDB-shared` | Dynamic client libraries. |
| `MariaDB-shared-debuginfo` | Debuginfo for dynamic client libraries. |
| `MariaDB-test` | `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `MariaDB-test-debuginfo` | Debuginfo for `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `MariaDB-tokudb-engine` | The [TokuDB](../tokudb/index) storage engine. |
| `MariaDB-tokudb-engine-debuginfo` | Debuginfo for the [TokuDB](../tokudb/index) storage engine. |

 

### Available RPM Packages in [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index)

 
**MariaDB starting with [10.2](../what-is-mariadb-102/index)**In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.3](../what-is-mariadb-103/index), the following RPMs are available:

 


| Package Name | Description |
| --- | --- |
| `galera` | The WSREP provider for [Galera](../galera/index) 3. |
| `MariaDB-backup` | [Mariabackup](../mariabackup/index) |
| `MariaDB-backup-debuginfo` | Debuginfo for [Mariabackup](../mariabackup/index) |
| `MariaDB-client` | Client tools like `mysql` CLI, `mysqldump`, and others. |
| `MariaDB-client-debuginfo` | Debuginfo for client tools like `mysql` CLI, `mariadb-dump`, and others. |
| `MariaDB-common` | Character set files and `/etc/my.cnf` |
| `MariaDB-common-debuginfo` | Debuginfo for character set files and `/etc/my.cnf` |
| `MariaDB-compat` | Old shared client libraries, may be needed by old MariaDB or MySQL clients |
| `MariaDB-connect-engine` | The `[CONNECT](../connect/index)` storage engine. |
| `MariaDB-connect-engine-debuginfo` | Debuginfo for the `[CONNECT](../connect/index)` storage engine. |
| `MariaDB-cracklib-password-check` | The `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `MariaDB-cracklib-password-check` | Debuginfo for the `[cracklib\_password\_check](../cracklib-password-check-plugin/index)` password validation plugin. |
| `MariaDB-devel` | Development headers and static libraries. |
| `MariaDB-devel-debuginfo` | Debuginfo for development headers and static libraries. |
| `MariaDB-gssapi-server` | The `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `MariaDB-gssapi-server-debuginfo` | Debuginfo for the `[gssapi](../authentication-plugin-gssapi/index)` authentication plugin. |
| `MariaDB-rocksdb-engine` | The [MyRocks](../myrocks/index) storage engine. |
| `MariaDB-rocksdb-engine-debuginfo` | Debuginfo for the [MyRocks](../myrocks/index) storage engine. |
| `MariaDB-server` | The server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `MariaDB-server-debuginfo` | Debuginfo for the server and server tools, like [myisamchk](../myisamchk/index) and [mariadb-hotcopy](../mariadb-hotcopy/index) are here. |
| `MariaDB-shared` | Dynamic client libraries. |
| `MariaDB-shared-debuginfo` | Debuginfo for dynamic client libraries. |
| `MariaDB-test` | `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `MariaDB-test-debuginfo` | Debuginfo for `mysql-client-test` executable, and **mysql-test** framework with the tests. |
| `MariaDB-tokudb-engine` | The [TokuDB](../tokudb/index) storage engine. |
| `MariaDB-tokudb-engine-debuginfo` | Debuginfo for the [TokuDB](../tokudb/index) storage engine. |

 

Installing RPM Packages
-----------------------

 Preferably, you should install MariaDB RPM packages using the package manager of your Linux distribution, for example **`yum`** or **`zypper`**. But you can also use the lower-level **`rpm`** tool.

 Actions Performed by RPM Packages
---------------------------------

 ### Users and Groups Created

 When the `MariaDB-server` RPM package is installed, it will create a user and group named `mysql`, if it does not already exist.

 See Also
--------

 * [Installing MariaDB with yum](../yum/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-the-mariadb-rpm-files/>

Installing MariaDB With the rpm Tool
====================================

    This article describes how to download the RPM files and install them using the `rpm` command.

 It is highly recommended to [Install MariaDB with yum](../yum/index) where possible.

 Navigate to <https://mariadb.org/download/> and choose the desired database version and then select the RPMs that match your Linux distribution and architecture.

 Clicking those links takes you to a local mirror. Choose the rpms link and download the desired packages. The packages will be similar to the following:

 
```
MariaDB-client-5.2.5-99.el5.x86_64.rpm
MariaDB-debuginfo-5.2.5-99.el5.x86_64.rpm
MariaDB-devel-5.2.5-99.el5.x86_64.rpm
MariaDB-server-5.2.5-99.el5.x86_64.rpm
MariaDB-shared-5.2.5-99.el5.x86_64.rpm
MariaDB-test-5.2.5-99.el5.x86_64.rpm

```

For a standard server installation you will need to download at least the *client*, *shared*, and *server* RPM files. See [About the MariaDB RPM Files](../about-the-mariadb-rpm-files/index) for more information about what is included in each RPM package.

 After downloading the MariaDB RPM files, you might want to check their signatures. See [Checking MariaDB RPM Package Signatures](../checking-mariadb-rpm-package-signatures/index) for more information about checking signatures.

 
```
rpm --checksig $(find . -name '*.rpm')

```

Prior to installing MariaDB, be aware that it will conflict with an existing installation of MySQL. To check whether MySQL is already installed, issue the command:

 
```
rpm -qa 'mysql*'

```

If necessary, you can remove found MySQL packages before installing MariaDB.

 To install MariaDB, use the command:

 
```
rpm -ivh MariaDB-*

```

You should see output such as the following:

 
```
Preparing...                ########################################### [100%]
   1:MariaDB-shared         ########################################### [ 14%]
   2:MariaDB-client         ########################################### [ 29%]
   3:MariaDB-client         ########################################### [ 43%]
   4:MariaDB-debuginfo      ########################################### [ 57%]
   5:MariaDB-devel          ########################################### [ 71%]
   6:MariaDB-server         ########################################### [ 86%]

PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
To do so, start the server, then issue the following commands:

/usr/bin/mariadb-admin -u root password 'new-password'
/usr/bin/mariadb-admin -u root -h hostname password 'new-password'

Alternatively you can run:
/usr/bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the MySQL manual for more instructions.

Please report any problems with the /usr/bin/mysqlbug script!

The latest information about MariaDB is available at http://www.askmonty.org/.
You can find additional information about the MySQL part at:
http://dev.mysql.com
Support MariaDB development by buying support/new features from
Monty Program Ab. You can contact us about this at sales@askmonty.org.
Alternatively consider joining our community based development effort:
http://askmonty.org/wiki/index.php/MariaDB#How_can_I_participate_in_the_development_of_MariaDB

Starting MySQL....[  OK  ]
Giving mysqld 2 seconds to start
   7:MariaDB-test           ########################################### [100%]

```

Be sure to follow the instructions given in the preceding output and create a password for the root user either by using [mariadb-admin](../mariadb-admin/index) or by running the /usr/bin/mysql\_secure\_installation script.

 Installing the MariaDB RPM files installs the MySQL tools in the `/usr/bin` directory. You can confirm that MariaDB has been installed by using the [mariadb](../mariadb-client/index) client program. Issuing the command `mariadb` should give you the MariaDB cursor.

 See Also
--------

 * [Installing MariaDB with yum](../installing-mariadb-with-yum/index)
* [Troubleshooting MariaDB Installs on RedHat/CentOS](../troubleshooting-mariadb-installs-on-redhatcentos/index)
* [Checking MariaDB RPM Package Signatures](../checking-mariadb-rpm-package-signatures/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-with-the-rpm-tool/>

MariaDB for DirectAdmin Using RPMs
==================================

    If you are using DirectAdmin and you encounter any issues with [Installing MariaDB with YUM](../installing-mariadb-with-yum/index), then the directions below may help. The process is very straightforward.

 
**Note:** Installing with YUM is preferable to installing the MariaDB RPM packages manually, so only do this if you are having issues such as:

 
```
Starting httpd:
  httpd:
    Syntax error on line 18 of /etc/httpd/conf/httpd.conf:
    Syntax error on line 1 of /etc/httpd/conf/extra/httpd-phpmodules.conf:
      Cannot load /usr/lib/apache/libphp5.so into server:
        libmysqlclient.so.18: cannot open shared object file: No such file or directory

```

Or:

 
```
Starting httpd:
  httpd:
    Syntax error on line 18 of /etc/httpd/conf/httpd.conf:
    Syntax error on line 1 of /etc/httpd/conf/extra/httpd-phpmodules.conf:
      Cannot load /usr/lib/apache/libphp5.so into server:
        /usr/lib/apache/libphp5.so: undefined symbol: client_errors

```


RPM Installation
----------------

 To install the RPMs, there is a quick and easy guide to [Installing MariaDB with the RPM Tool](../installing-mariadb-with-the-rpm-tool/index). Follow the instructions there.

 Necessary Edits
---------------

 We do not want DirectAdmin's custombuild to remove/overwrite our MariaDB installation whenever an update is performed. To rectify this, disable automatic MySQL installation.

 Edit `/usr/local/directadmin/custombuild/options.conf`

 Change:

 
```
mysql_inst=yes

```

To:

 
```
mysql_inst=no

```


**Note:** When MariaDB is installed manually (i.e. not using YUM), updates are not automatic. You will need to update the RPMs yourself.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-for-directadmin-using-rpms/>

Why Source RPMs (SRPMs) Aren't Packaged For Some Platforms
==========================================================

    MariaDB source RPMs (SRPMs) are not packaged on all platforms for which MariaDB RPMs are packaged.

 The reason is that MariaDB's build process relies heavily on `[cmake](https://cmake.org)` for a lot of things. In this specific case, MariaDB's build process relies on [CMake CPack Package Generators](https://gitlab.kitware.com/cmake/community/wikis/doc/cpack/PackageGenerators) to build RPMs. The specific package generator that it uses to build RPMs is called `[CPackRPM](https://cmake.org/cmake/help/v3.10/module/CPackRPM.html)`.

 Support for source RPMs in `[CPackRPM](https://cmake.org/cmake/help/v3.10/module/CPackRPM.html)` became usable with MariaDB's build system starting from around [cmake 3.10](https://cmake.org/cmake/help/v3.10/release/3.10.html). This means that we do not produce source RPMs on platforms where the installed `[cmake](https://cmake.org)` version is older than that.

 See also [Building MariaDB from a Source RPM](../building-mariadb-from-a-source-rpm/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/why-source-rpms-srpms-arent-packaged-for-some-platforms/>

Debugging a Running Server (on Linux)
=====================================

     Even if you don't have a server that is [compiled for debugging](../compiling-mariadb-for-debugging/index), there are still ways to get more information out from it if things go wrong.

 When things go wrong, it's always better to have a version of mysqld daemon that is not stripped.

 
```
shell> file /usr/sbin/mysqld

```

If this doesn't say 'stripped' then you are fine. If not, you should either [download a binary with debugging information](https://downloads.mariadb.org) or [compile it, without stripping the binary](../compiling-mariadb-for-debugging/index#building-with-debug-symbols).

 ### Debugging Memory Consumption With tcmalloc

 If you have a problem with a mysqld process that keeps on growing, you can use tcmalloc to find out what is allocating memory:

 Depending on the system you have to install the `tcmalloc` (OpenSuse) or the `google-perftools-lib` (RedHat, Centos) package.

 The following set of commands starts mysqld with memory profiling and if you kill it with SIGABRT, you will get a core dump that you can examine:

 
```
HEAPPROFILE=/tmp/mysqld.prof /usr/sbin/mysqld_safe --malloc-lib=tcmalloc --core-file-size=unlimited --core-file

```

or if you prefer to invoke mysqld directly:

 
```
ulimit -c unlimted
LD_PRELOAD=/usr/lib64/libtcmalloc.so.4 HEAPPROFILE=/tmp/mysqld.prof /usr/sbin/mysqld --core-file

```

You can of course add other [mysqld options](../mysqld-options/index) to the end of the above line.

 Now start your client/application that uses MariaDB. You can find where memory is allocated in the `/tmp/mysqld.prof` file. If you find any memory issues, please report this in the [MariaDB bug tracker](https://jira.mariadb.org/secure/Dashboard.jspa)!

 ### ptrace Protection and Attaching GDB to a mysqld Instance

 New Ubuntu releases do not allow one process to examine the memory of an arbitrary user's process. As a result, when trying to attach GDB to a running MariaDB (or any other process) instance, one gets the following error in GDB:

 
```
ptrace: Operation not permitted

```

More details are available in the [Ubuntu Wiki](https://wiki.ubuntu.com/SecurityTeam/Roadmap/KernelHardening#ptrace%20Protection).

 To allow GDB to attach, one needs to edit the value of the `/proc/sys/kernel/yama/ptrace_scope` sysctl value.

 * To change it temporarily, open a root shell and issue:
```
echo 0 > /proc/sys/kernel/yama/ptrace_scope

```
* To change it permanently, edit as root: 
```
/etc/sysctl.d/10-ptrace.conf

```
 and set the value to `0`.

 ### Debugging a Server That Hangs

 If your mysqld server hangs, you may want to debug it to know what happened.

 Preferably the server should be compiled for debugging, but it's not strictly necessary:

 
```
cmake -DCMAKE_BUILD_TYPE=Debug -DWITH_VALGRIND=ON .
make -j4

```

To know what the server is doing:

 * Find out the process number of mysqld

 
```
ps -edalf | grep mysqld

```

* Attach to the process and get a back trace:

 
```
gdb -p 'pid of mysqld' path-to-mysqld
set height 0
set logging file /tmp/mysqld.log
set logging on
thread apply all backtrace full

```

After the above, you have a full backtrace, including all local variables, in the `mysqld.log` file. Note that you will only get all variables if the server is not stripped.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/debugging-a-running-server-on-linux/>

MariaDB Installation (Version 10.1.21) via RPMs on CentOS 7
===========================================================

    Here are the detailed steps for installing MariaDB (version 10.1.21) via RPMs on CentOS 7.

 The RPM's needed for the installation are all available on the MariaDB website and are given below:

 * jemalloc-3.6.0-1.el7.x86\_64.rpm
* MariaDB-10.1.21-centos7-x86\_64-client.rpm
* MariaDB-10.1.21-centos7-x86\_64-compat.rpm
* galera-25.3.19-1.rhel7.el7.centos.x86\_64.rpm
* jemalloc-devel-3.6.0-1.el7.x86\_64.rpm
* MariaDB-10.1.21-centos7-x86\_64-common.rpm
* MariaDB-10.1.21-centos7-x86\_64-server.rpm

 Step by step installation:

 * 1) First install all of the dependencies needed. Its easy to do this via YUM packages: yum install rsync nmap lsof perl-DBI nc
* 2) rpm -ivh jemalloc-3.6.0-1.el7.x86\_64.rpm
* 3) rpm -ivh jemalloc-devel-3.6.0-1.el7.x86\_64.rpm
* 4) rpm -ivh MariaDB-10.1.21-centos7-x86\_64-common.rpm MariaDB-10.1.21-centos7-x86\_64-compat.rpm MariaDB-10.1.21-centos7-x86\_64-client.rpm galera-25.3.19-1.rhel7.el7.centos.x86\_64.rpm MariaDB-10.1.21-centos7-x86\_64-server.rpm

 While installing MariaDB-10.1.21-centos7-x86\_64-common.rpm there might be a conflict with older MariaDB packages. we need to remove them and install the original rpm again.

 Here is the error message for dependencies:

 
```
# rpm -ivh MariaDB-10.1.21-centos7-x86_64-common.rpm 
warning: MariaDB-10.1.21-centos7-x86_64-common.rpm: Header V4 DSA/SHA1 Signature, key ID 1bb943db: NOKEY
error: Failed dependencies:
	mariadb-libs < 1:10.1.21-1.el7.centos conflicts with MariaDB-common-10.1.21-1.el7.centos.x86_64

```

Solution: search for this package:

 
```
# rpm -qa | grep mariadb-libs
mariadb-libs-5.5.52-1.el7.x86_64

```

Remove this package:

 
```
# rpm -ev --nodeps mariadb-libs-5.5.52-1.el7.x86_64
Preparing packages...
mariadb-libs-1:5.5.52-1.el7.x86_64

```

While installing the Galera package there might be a conflict in installation for a dependency package. Here is the error message:

 
```
[root@centos-2 /]# rpm -ivh galera-25.3.19-1.rhel7.el7.centos.x86_64.rpm 
error: Failed dependencies:
	libboost_program_options.so.1.53.0()(64bit) is needed by galera-25.3.19-1.rhel7.el7.centos.x86_64

The dependencies for Galera package is: libboost_program_options.so.1.53.0

```

Solution:

 
```
yum install boost-devel.x86_64

```

Another warning message while installing Galera package is as shown below:

 
```
warning: galera-25.3.19-1.rhel7.el7.centos.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 1bb943db: NOKEY 

```

The solution for this is to import the key:

 
```
#rpm --import http://yum.mariadb.org/RPM-GPG-KEY-MariaDB

```

After step 4, the installation will be completed. The last step will be to run [mysql\_secure\_installation](../mysql_secure_installation/index) to secure the production server by dis allowing remote login for root, creating root password and removing the test database.

 * 5) mysql\_secure\_installation

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-installation-version-10121-via-rpms-on-centos-7/>

Enabling InnoDB Encryption
==========================

    In order to enable data-at-rest encryption for tables using the InnoDB storage engines, you first need to configure the Server to use an [Encryption Key Management](../encryption-key-management/index) plugin. Once this is done, you can enable encryption by setting the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable to encrypt the InnoDB [system](../innodb-system-tablespaces/index) and [file](../innodb-file-per-table-tablespaces/index) tablespaces and setting the [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) system variable to encrypt the InnoDB [Redo Log](../innodb-redo-log/index). 

 Setting these system variables enables the encryption feature for InnoDB tables on your server. To use the feature, you need to use the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option to set what encryption key you want to use and set the [ENCRYPTED](../create-table/index#encrypted) table option to enable encryption.

 
When encrypting any InnoDB tables, the best practice is also enable encryption for the Redo Log. If you have encrypted InnoDB tables and have not encrypted the Redo Log, data written to an encrypted table may be found unencrypted in the Redo Log. 

 
### Enabling Encryption for Automatically Encrypted Tablespaces

 The [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable controls the configuration of automatic encryption of InnoDB tables. It has the following possible values:

 


| Option | Description |
| --- | --- |
| `OFF` | Disables table encryption. |
| `ON` | Enables table encryption, but allows unencrypted tables to be created. |
| `FORCE` | Enables table encryption, and doesn't allow unencrypted tables to be created. Added in [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/). |

 
When [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `ON`, InnoDB tables are automatically encrypted by default. For example, the following statements create an encrypted table and confirm that it is encrypted:

 
```
SET GLOBAL innodb_encryption_threads=4;

SET GLOBAL innodb_encrypt_tables=ON;

SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
);

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

When [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `ON`, an unencrypted InnoDB table can be created by setting the [ENCRYPTED](../create-table/index#encrypted) table option to `NO` for the table. For example, the following statements create an unencrypted table and confirm that it is not encrypted:

 
```
SET GLOBAL innodb_encryption_threads=4;

SET GLOBAL innodb_encrypt_tables=ON;

SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=NO;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 0 |            100 |
+----------+-------------------+----------------+

```

When [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `FORCE`, InnoDB tables are automatically encrypted by default, and unencrypted InnoDB tables can **not** be created. In this scenario, if you set the [ENCRYPTED](../create-table/index#encrypted) table option to `NO` for a table, then you will encounter an error. For example:

 
```
SET GLOBAL innodb_encryption_threads=4;

SET GLOBAL innodb_encrypt_tables='FORCE';

SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=NO;
ERROR 1005 (HY000): Can't create table `db1`.`tab1` (errno: 140 "Wrong create options")

SHOW WARNINGS;
+---------+------+----------------------------------------------------------------------+
| Level   | Code | Message                                                              |
+---------+------+----------------------------------------------------------------------+
| Warning |  140 | InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1                     |
| Warning |  140 | InnoDB: ENCRYPTED=NO cannot be used with innodb_encrypt_tables=FORCE |
| Error   | 1005 | Can't create table `db1`.`tab1` (errno: 140 "Wrong create options")  |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB      |
+---------+------+----------------------------------------------------------------------+
4 rows in set (0.00 sec)

```


When [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) is set to `ON` or `FORCE`, then you must ensure that [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) is set to a non-zero value, so that InnoDB can perform any necessary encryption operations in the background. See [background operations](../innodb-background-encryption-threads/index#background-operations) for more information about that. [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) must also be set to a non-zero value for the initial encryption operations to happen in the background. See [disabling key rotations](../innodb-background-encryption-threads/index#disabling-background-key-rotation-operations) for more information about that.

 
### Enabling Encryption for Manually Encrypted Tablespaces

 If you do not want to automatically encrypt every InnoDB table, then it is possible to manually enable encryption for just the subset of InnoDB tables that you would like to encrypt. MariaDB provides the [ENCRYPTED](../create-table/index#encrypted) and [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table options that can be used to manually enable encryption for specific InnoDB tables. These table options can be used with [CREATE TABLE](../create-table/index) and [ALTER TABLE](../alter-table/index) statements. These table options can only be used with InnoDB tables that have their own [InnoDB's file-per-table tablespaces](../innodb-file-per-table-tablespaces/index), meaning that tables that were created with [innodb\_file\_per\_table=ON](../innodb-system-variables/index#innodb_file_per_table) set.

 


| Table Option | Value | Description |
| --- | --- | --- |
| `ENCRYPTED` | Boolean | Defines whether to encrypt the table |
| `ENCRYPTION_KEY_ID` | 32-bit integer | Defines the identifier for the encryption key to use |

 
You can manually enable or disable encryption for a table by using the [ENCRYPTED](../create-table/index#encrypted) table option. If you only need to protect a subset of InnoDB tables with encryption, then it can be a good idea to manually encrypt each table that needs the extra protection, rather than encrypting all InnoDB tables globally with [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables). This allows you to balance security with speed, as it means the encryption and decryption performance overhead only applies to those tables that require the additional security.

 
If a manually encrypted InnoDB table contains a [FULLTEXT INDEX](../full-text-indexes/index), then the internal table for the full-text index will not also be manually encrypted. To encrypt internal tables for InnoDB full-text indexes, you must [enable automatic InnoDB encryption](#enabling-encryption-for-automatically-encrypted-tablespaces) by setting [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) to `ON` or `FORCE`.

 
You can also manually specify a [encryption key](../encrypting-data-for-innodb-xtradb/index#encryption-keys) for a table by using the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option. This allows you to use different encryption keys for different tables. For example, you might create a table using a statement like this:

 
```
CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=YES ENCRYPTION_KEY_ID=100;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

If the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option is not specified, then the table will be encrypted with the key identified by the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable. For example, you might create a table using a statement like this:

 
```
SET SESSION innodb_default_encryption_key_id=100;

CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=YES;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

In the event that you have an existing table and you want to manually enable encryption for that table, then you can do the same with an [ALTER TABLE](../alter-table/index) statement. For example:

 
```
CREATE TABLE tab1 (
   id int PRIMARY KEY,
   str varchar(50)
) ENCRYPTED=NO;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 0 |            100 |
+----------+-------------------+----------------+

ALTER TABLE tab1
   ENCRYPTED=YES ENCRYPTION_KEY_ID=100;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```


InnoDB does not permit manual encryption changes to tables in the [system](../innodb-system-tablespaces/index) tablespace using [ALTER TABLE](../alter-table/index). Encryption of the [system](../innodb-system-tablespaces/index) tablespace can only be configured by setting the value of the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable. This means that when you want to encrypt or decrypt the [system](../innodb-system-tablespaces/index) tablespace, you must also set a non-zero value for the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable, and you must also set the [innodb\_system\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable to `1` to ensure that the system tablespace is properly encrypted or decrypted by the background threads. See [MDEV-14398](https://jira.mariadb.org/browse/MDEV-14398) for more information.

 
### Enabling Encryption for Temporary Tablespaces

 The [innodb\_encrypt\_temporary\_tables](../innodb-system-variables/index#innodb_encrypt_temporary_tables) system variable controls the configuration of encryption for the [temporary tablespace](../innodb-temporary-tablespaces/index). It has the following possible values:

 


| Option | Description |
| --- | --- |
| `OFF` | Disables temporary table encryption. |
| `ON` | Enables temporary table encryption. |

 
This system variable can be specified as a command-line argument to [mysqld](../mysqld-options/index) or it can be specified in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_encrypt_temporary_tables=ON

```

### Enabling Encryption for the Redo Log

 InnoDB uses the [Redo Log](../innodb-redo-log/index) in crash recovery. By default, these events are written to file in an unencrypted state. In configuring MariaDB for data-at-rest encryption, ensure that you also enable encryption for the Redo Log.

 To encrypt the Redo Log, first [stop](../starting-and-stopping-mariadb-automatically/index) the server process. Then, set the [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) to `ON` in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
innodb_encrypt_log = ON

```

Then, start MariaDB. When the server starts back up, it checks to recover InnoDB in the event of a crash. Once it is back online, it begins writing encrypted data to the Redo Log.

 
In [MariaDB 10.3](../what-is-mariadb-103/index) and before, InnoDB does not support key rotation for the Redo Log. Key rotation for the Redo Log is supported in [MariaDB 10.4](../what-is-mariadb-104/index) and later. See [InnoDB Encryption Keys: Key Rotation](../innodb-xtradb-encryption-keys/index#key-rotation) for more information.

 
### See Also

 * [Disabling InnoDB encryption](../disabling-innodb-encryption/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-enabling-encryption/>

MariaDB 5.5.33 Debian and Ubuntu Installation Issues
====================================================

    Shortly after the [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/) release we became aware of some installation issues with the Debian and Ubuntu repositories. These issues were fixed in [MariaDB 5.5.33a](https://mariadb.com/kb/en/mariadb-5533a-release-notes/), but due to how apt works, steps need to be taken to solve the broken dependencies before upgrading.

 We know of three scenarios when dependencies were broken. The steps to fix each of them are pretty much the same, only the list of broken dependencies and hence the list of packages to take care of them differs. The basic idea is to downgrade those certain packages to 5.5.32 temporarily before upgrading them to 5.5.33a.

 If you ran into issues when moving from [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5532-release-notes/) to [MariaDB 5.5.33](https://mariadb.com/kb/en/mariadb-5533-release-notes/), look through each of the three scenarios to see which one applies to you and then follow the steps to apply that fix.

 Applying the fix
----------------

 To get your system ready to apply the fix, do the following:

 * Comment out the standard [MariaDB 5.5](../what-is-mariadb-55/index) repo in the `/etc/apt/sources.list` or `/etc/apt/sources.list.d/mariadb.repo` file (or wherever you have the repositories configured).

 * Add a [MariaDB 5.5.32](https://mariadb.com/kb/en/mariadb-5532-release-notes/) repository to the `sources.list`. The easiest way is to add the following. Just replace '`{os}`' and '`{dist}`' with the appropriate values.

 
```
deb http://ftp.osuosl.org/pub/mariadb/mariadb-5.5.32/repo/{os} {dist} main

```



For example, on Debian Wheezy the line would be:

   
```
deb http://ftp.osuosl.org/pub/mariadb/mariadb-5.5.32/repo/debian wheezy main

```



And on Ubuntu Raring the line would be:

   
```
deb http://ftp.osuosl.org/pub/mariadb/mariadb-5.5.32/repo/ubuntu raring main

```

* Then run '`sudo apt-get update`'

 * Then '`sudo apt-get install`' the list of packages to downgrade as given in the applicable section below.

 * Next, modify our sources.list to remove the 5.5.32 repo and switch back to the normal 5.5 repo

 * Then '`sudo apt-get update`' to get things back to normal

 * As a final optional step, once your normal mirror has at least [MariaDB 5.5.33a](https://mariadb.com/kb/en/mariadb-5533a-release-notes/) you can '`sudo apt-get upgrade`' to upgrade. To check what version of MariaDB our mirror has, run the following command (after running '`sudo apt-get update`'):

 
```
apt-cache show mariadb-server | grep Version

```

5.5.32 server + 5.5.32 client upgraded to the initial (17 Sep 2013) release of 5.5.33
-------------------------------------------------------------------------------------

 In this first scenario, both client and server were partially upgraded to 5.5.33 before the process aborted. The problem looks like this:

 
```
You might want to run 'apt-get -f install' to correct these.
The following packages have unmet dependencies:
 libmariadbclient18 : Depends: libmysqlclient18 (= 5.5.32+maria-1~wheezy) but 5.5.33+maria-1~wheezy is installed
 libmysqlclient18 : Depends: libmariadbclient18 (= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-client-5.5 : Depends: libmariadbclient18 (>= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-client-core-5.5 : Depends: libmariadbclient18 (>= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-server : Depends: mariadb-server-5.5 (= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-server-core-5.5 : Depends: libmariadbclient18 (>= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed

```

To fix it, the following server and client packages need to be temporarily downgraded to 5.5.32 (replace '`wheezy`' with the name of whatever distribution you are using):

 
```
sudo apt-get install \
  libmysqlclient18=5.5.32+maria-1~wheezy \
  mariadb-client-5.5=5.5.32+maria-1~wheezy \
  mariadb-client-core-5.5=5.5.32+maria-1~wheezy \
  mariadb-server=5.5.32+maria-1~wheezy \
  mariadb-server-core-5.5=5.5.32+maria-1~wheezy

```

5.5.32 Galera server and 5.5.32 MariaDB client upgraded to 5.5.33
-----------------------------------------------------------------

 In this scenario, the client upgraded, but Galera-server did not. The problem looks like this:

 
```
The following packages have unmet dependencies:
 libmariadbclient18 : Depends: libmysqlclient18 (= 5.5.32+maria-1~wheezy) but 5.5.33+maria-1~wheezy is installed
 libmysqlclient18 : Depends: libmariadbclient18 (= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-client-5.5 : Depends: libmariadbclient18 (>= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed
 mariadb-client-core-5.5 : Depends: libmariadbclient18 (>= 5.5.33+maria-1~wheezy) but 5.5.32+maria-1~wheezy is installed

```

To fix it, only the client packages need to be temporarily downgraded to 5.5.32 (replace wheezy with whatever your distribution is):

 
```
sudo apt-get install \
  libmysqlclient18=5.5.32+maria-1~wheezy \
  mariadb-client-5.5=5.5.32+maria-1~wheezy \
  mariadb-client-core-5.5=5.5.32+maria-1~wheezy

```

5.3.12 server + 5.3.12 client + 5.5.32 libmariadbclient18 upgraded to 5.5.33
----------------------------------------------------------------------------

 In this scenario, only the library upgraded. The problem looks like this:

 
```
The following packages have unmet dependencies:
  libmariadbclient18: Depends: libmysqlclient18 (= 5.5.32+maria-1~lucid) but 5.5.33+maria-1~lucid is installed
  libmysqlclient18: Depends: libmariadbclient18 (= 5.5.33+maria-1~lucid) but 5.5.32+maria-1~lucid is installed

```

To fix it, the library needs to be downgraded to 5.5.32 (replace wheezy with your distribution):

 
```
sudo apt-get install \
  libmysqlclient=5.5.32+maria-1~wheezy \
  libmariadbclient=5.5.32+maria-1~wheezy

```

After switching back to the 5.5 repo, the libraries won't get upgraded, they will stay 5.5.32 until you upgrade the server to 5.5.33a.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-5533-debian-and-ubuntu-installation-issues/>

Moving from MySQL to MariaDB in Debian 9
========================================

    [MariaDB 10.1](../what-is-mariadb-101/index) is now the default mysql server in Debian 9 "Stretch". This page provides information on this change and instructions to help with upgrading your Debian 8 "Jessie" version of MySQL or MariaDB to [MariaDB 10.1](../what-is-mariadb-101/index) in Debian 9 "Stretch". 

 Background information
----------------------

 The version of MySQL in Debian 8 "Jessie" is 5.5. When installing, most users will install the `mysql-server` package, which depends on the `mysql-server-5.5 package`. In Debian 9 "Stretch" the `mysql-server` package depends on a new package called `default-mysql-server`. This package in turn depends on `mariadb-server-10.1`. There is no `default-mysql-server` package in Jessie.

 In both Jessie and Stretch there is also a `mariadb-server` package which is a MariaDB-specific analog to the `mysql-server` package. In Jessie this package depends on `mariadb-server-10.0` and in Stretch this package depends on `mariadb-server-10.1` (the same as the `default-mysql-server` package).

 So, the main repository difference in Debian 9 "Stretch" is that when you install the `mysql-server` package on Stretch you will get [MariaDB 10.1](../what-is-mariadb-101/index) instead of MySQL, like you would with previous versions of Debian. Note that `mysql-server` is just an empty transitional meta-package and users are encouraged to install MariaDB using the actual package `mariadb-server`.

 All apps and tools, such as the popular LAMP stack, in the repositories that depend on the `mysql-server` package will continue to work using MariaDB as the database. For new installs there is nothing different that needs to be done when installing the mysql-server or mariadb-server packages.

 Before you upgrade
------------------

 If you are currently running MySQL 5.5 on Debian 8 "Jessie" and are planning an upgrade to [MariaDB 10.1](../what-is-mariadb-101/index) on Debian 9 "Stretch", there are some things to keep in mind:

 ### Backup before you begin

 This is a major upgrade, and so complete database backups are strongly suggested before you begin. [MariaDB 10.1](../what-is-mariadb-101/index) is compatible on disk and wire with MySQL 5.5, and the MariaDB developer team has done extensive development and testing to make upgrades as painless and trouble-free as possible. Even so, it's always a good idea to do regular backups, especially before an upgrade. As the database has to shutdown anyway for the upgrade, this is a good opportunity to do a backup!

 ### Changed, renamed, and removed options

 Some default values have been changed, some have been renamed, and others have been removed between MySQL 5.5 and [MariaDB 10.1](../what-is-mariadb-101/index). The following sections detail them.

 #### Options with changed default values

 Most of the following options have increased a bit in value to give better performance. They should not use much additional memory, but some of them do use a bit more disk space. [[1](#_note-0)]

 


| Option | Old default value | New default value |
| --- | --- | --- |
| `[aria-sort-buffer-size](../aria-system-variables/index#aria_sort_buffer_size)` | `128M` | `256M` |
| `[back\_log](../server-system-variables/index#back_log)` | `50` | `150` |
| `[innodb-concurrency-tickets](../xtradbinnodb-server-system-variables/index#innodb_concurrency_tickets)` | `500` | `5000` |
| `[innodb-log-file-size](../xtradbinnodb-server-system-variables/index#innodb_log_file_size)` | `5M` | `48M` |
| `[innodb\_log\_compressed\_pages](../xtradbinnodb-server-system-variables/index#innodb_log_compressed_pages)` | `ON` | `OFF` |
| `[innodb-old-blocks-time](../xtradbinnodb-server-system-variables/index#innodb_old_blocks_time)` | `0` | `1000` |
| `[innodb-open-files](../xtradbinnodb-server-system-variables/index#innodb_open_files)` | `300` | `400` [[2]](#_note-1) |
| `[innodb-purge-batch-size](../xtradbinnodb-server-system-variables/index#innodb_purge_batch_size)` | `20` | `300` |
| `[innodb-undo-logs](../xtradbinnodb-server-system-variables/index#innodb_undo_logs)` | `ON` | `20` |
| `[join\_buffer\_size](../server-system-variables/index#join_buffer_size)` | `128K` | `256K` |
| `[max\_allowed\_packet](../server-system-variables/index#max_allowed_packet)` | `1M` | `4M` |
| `[max-connect-errors](../server-system-variables/index#max_connect_errors)` | `10` | `100` |
| `[max-relay-log-size](../server-system-variables/index#max_relay_log_size)` | `0` | `1024M` |
| `[myisam-sort-buffer-size](../myisam-server-system-variables/index#myisam_sort_buffer_size)` | `8M` | `128M` |
| `[optimizer-switch](../server-system-variables/index#optimizer_switch)` | ... | Added `extended_keys=on, exists_to_in=on` |
| `[query\_alloc\_block\_size](../server-system-variables/index#query_alloc_block_size)` | `8192` | `16384` |
| `[query\_cache\_size](../server-system-variables/index#query_cache_size)` | `0` | `1M` |
| `[query\_cache\_type](../server-system-variables/index#query_cache_type)` | `ON` | `OFF` |
| `[query\_prealloc\_size](../server-system-variables/index#query_prealloc_size)` | `8192` | `24576` |
| `[secure\_auth](../server-system-variables/index#secure_auth)` | `OFF` | `ON` |
| `[sql\_log\_bin](../replication-and-binary-log-server-system-variables/index#sql_log_bin)` |  | No longer affects replication of events in a Galera cluster. |
| `[sql\_mode](../server-system-variables/index#sql_mode)` | `empty` | `NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION` |
| `[sync\_master\_info](../replication-and-binary-log-server-system-variables/index#sync_master_info)` | `0` | `10000` |
| `[sync\_relay\_log](../replication-and-binary-log-server-system-variables/index#sync_relay_log)` | `0` | `10000` |
| `[sync\_relay\_log\_info](../replication-and-binary-log-server-system-variables/index#sync_relay_log_info)` | `0` | `10000` |
| `[table\_open\_cache](../server-system-variables/index#table_open_cache)` | `400` | `2000` |
| `[thread\_pool\_max\_threads](../server-system-variables/index#thread_pool_max_threads)` | `500` | `1000` |

 
#### Options that have been removed or renamed

 The following options should be removed or renamed if you use them in your config files:

 


| Option | Reason |
| --- | --- |
| `engine-condition-pushdown` | Replaced with `[set optimizer\_switch='engine\_condition\_pushdown=on'](../index-condition-pushdown/index)` |
| `innodb-adaptive-flushing-method` | Removed by [XtraDB](../xtradb/index) |
| `innodb-autoextend-increment` | Removed by [XtraDB](../xtradb/index) |
| `innodb-blocking-buffer-pool-restore` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages-blob` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages-index` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-restore-at-startup` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-shm-checksum` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-shm-key` | Removed by [XtraDB](../xtradb/index) |
| `innodb-checkpoint-age-target` | Removed by [XtraDB](../xtradb/index) |
| `innodb-dict-size-limit` | Removed by [XtraDB](../xtradb/index) |
| `innodb-doublewrite-file` | Removed by [XtraDB](../xtradb/index) |
| `innodb-fast-checksum` | Renamed to [innodb-checksum-algorithm](../xtradbinnodb-server-system-variables/index#innodb_checksum_algorithm) |
| `innodb-flush-neighbor-pages` | Renamed to [innodb-flush-neighbors](../xtradbinnodb-server-system-variables/index#innodb_flush_neighbors) |
| `innodb-ibuf-accel-rate` | Removed by [XtraDB](../xtradb/index) |
| `innodb-ibuf-active-contract` | Removed by [XtraDB](../xtradb/index) |
| `innodb-ibuf-max-size` | Removed by [XtraDB](../xtradb/index) |
| `innodb-import-table-from-xtrabackup` | Removed by [XtraDB](../xtradb/index) |
| `innodb-index-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-lazy-drop-table` | Removed by [XtraDB](../xtradb/index) |
| `innodb-merge-sort-block-size` | Removed by [XtraDB](../xtradb/index) |
| `innodb-persistent-stats-root-page` | Removed by [XtraDB](../xtradb/index) |
| `innodb-read-ahead` | Removed by [XtraDB](../xtradb/index) |
| `innodb-recovery-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-recovery-update-relay-log` | Removed by [XtraDB](../xtradb/index) |
| `innodb-stats-auto-update` | Renamed to `innodb-stats-auto-recalc` |
| `innodb-stats-update-need-lock` | Removed by [XtraDB](../xtradb/index) |
| `innodb-sys-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-table-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-thread-concurrency-timer-based` | Removed by [XtraDB](../xtradb/index) |
| `innodb-use-sys-stats-table` | Removed by [XtraDB](../xtradb/index) |
| `[rpl\_recovery\_rank](../server-system-variables/index#rpl_recovery_rank)` | Unused in 10.0+ |
| `xtradb-admin-command` | Removed by [XtraDB](../xtradb/index) |

 
### Suggested upgrade procedure for replication

 If you have a [master-slave setup](../standard-replication/index), the normal procedure is to first upgrade your slaves to MariaDB, then move one of your slaves to be the master and then upgrade your original master. In this scenario you can upgrade from MySQL to MariaDB or upgrade later to a new version of MariaDB without any downtime.

 ### Other resources to consult before beginning your upgrade

 It may also be useful to check out the [Upgrading MariaDB](../upgrading/index) section. It contains several articles on upgrading from MySQL to MariaDB and from one version of MariaDB to another. For upgrade purposes, MySQL 5.5 and [MariaDB 5.5](../what-is-mariadb-55/index) are very similar. In particular, see the [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index) and [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-mariadb-101/index) articles. 

 If you need help with upgrading or setting up replication, you can always [contact the MariaDB corporation](https://mariadb.com/contact) to find experts to help you with this.

 Upgrading to [MariaDB 10.1](../what-is-mariadb-101/index) from MySQL 5.5
------------------------------------------------------------------------

 The suggested upgrade procedure is:

 1. Set [innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown) to `0`. This is to ensure that if you make a backup as part of the upgrade, all data is written to the InnoDB data files, which simplifies any restore in the future.
2. Shutdown MySQL 5.5
3. Take a [backup](../backup-and-restore-overview/index)
	* when the server is shut down is the perfect time to take a backup of your databases
	* store a copy of the backup on external media or a different machine for safety
4. Perform the upgrade from Debian 8 to Debian 9
5. During the upgrade, the [mysql\_upgrade](../mysql_upgrade/index) script will be run automatically; this script does two things:
	1. Upgrades the permission tables in the `mysql` database with some new fields
	2. Does a very quick check of all tables and marks them as compatible with [MariaDB 10.1](../what-is-mariadb-101/index)
		* In most cases this should be a fast operation (depending of course on the number of tables)
6. Add new options to [my.cnf](../configuring-mariadb-with-mycnf/index) to enable features
	* If you change `my.cnf` then you need to restart `mysqld` with e.g. `sudo service mysql restart` or `sudo service mariadb restart`.

 Upgrading to [MariaDB 10.1](../what-is-mariadb-101/index) from an older version of MariaDB
------------------------------------------------------------------------------------------

 If you have installed [MariaDB 5.5](../what-is-mariadb-55/index) or [MariaDB 10.0](../what-is-mariadb-100/index) on your Debian 8 "Jessie" machine from the MariaDB repositories you will need to upgrade to [MariaDB 10.1](../what-is-mariadb-101/index) when upgrading to Debian 9 "Stretch". You can choose to continue using the MariaDB repositories or move to using the Debian repositories.

 If you want to continue using the MariaDB repositories edit the MariaDB entry in your sources.list and change every instance of 5.5 or 10.0 to 10.1. Then upgrade as suggested [above](#upgrading-to-mariadb-101-from-mysql-55).

 If you want to move to using [MariaDB 10.1](../what-is-mariadb-101/index) from the Debian repositories, delete or comment out the MariaDB entries in your sources.list file. Then upgrade as suggested [above](#upgrading-to-mariadb-101-from-mysql-55).

 If you are already using [MariaDB 10.1](../what-is-mariadb-101/index) on your Debian 8 "Jessie" machine, you can choose to continue to use the MariaDB repositories or move to using the Debian repositories as with [MariaDB 5.5](../what-is-mariadb-55/index) and 10.0. In either case, the upgrade will at most be just a minor upgrade from one version of [MariaDB 10.1](../what-is-mariadb-101/index) to a newer version. In the case that you are already on the current version of MariaDB that exists in the Debian repositories or a newer one) MariaDB will not be upgraded during the system upgrade but will be upgraded when future versions of MariaDB are released. 

 
You should always perform a compete backup of your data prior to performing any major system upgrade, even if MariaDB itself is not being upgraded!

 
MariaDB Galera Cluster
----------------------

 If you have been using MariaDB Galera Cluster 5.5 or 10.0 on Debian 8 "Jessie" it is worth mentioning that [Galera Cluster](../galera/index) is included by default in [MariaDB 10.1](../what-is-mariadb-101/index), there is no longer a need to install a separate `mariadb-galera-server` package.

 Configuration options for advanced database users
-------------------------------------------------

 To get better performance from MariaDB used in production environments, here are some suggested additions to [your configuration file](../configuring-mariadb-with-mycnf/index) which in Debian is at `/etc/mysql/mariadb.d/my.cnf`:

 
```
[[mysqld]]
# Cache for disk based temporary files
aria_pagecache_buffer_size=128M
# If you are not using MyISAM tables directly (most people are using InnoDB)
key_buffer_size=64K

```

The reason for the above change is that MariaDB is using the newer [Aria](../aria-storage-engine/index) storage engine for disk based temporary files instead of MyISAM. The main benefit of Aria is that it can cache both indexes and rows and thus gives better performance than MyISAM for large queries.

 Secure passwordless root accounts only on new installs
------------------------------------------------------

 Unlike the old MySQL packages in Debian, [MariaDB 10.0](../what-is-mariadb-100/index) onwards in Debian uses unix socket authentication on new installs to avoid root password management issues and thus be more secure and easier to use with provision systems of the cloud age.

 This only affects new installs. Upgrades from old versions will continue to use whatever authentication and user accounts already existed. This is however good to know, because it can affect upgrades of dependant systems, typically e.g. require users to rewrite their Ansible scripts and similar tasks. The new feature is much easier than the old, so adjusting for it requires little work.

 See also
--------

 * [Differences in MariaDB in Debian (and Ubuntu)](../differences-in-mariadb-in-debian-and-ubuntu/index)
* [Configuring MariaDB for optimal performance](../configuring-mariadb-for-optimal-performance/index)
* [New features in MariaDB you should considering using](../mariadb-vs-mysql-features/index)
* [What is MariaDB 10.1](../what-is-mariadb-101/index)
* [General instructions for upgrading from MySQL to MariaDB](../upgrading-from-mysql-to-mariadb/index)

 Comments and suggestions
------------------------

 If you have comments or suggestions on things we can add or change to improve this page. Please add them as comments below.

 Notes
-----

 1. [↑](#_ref-0) The `innodb-open-files` variable defaults to the value of `table-open-cache` (`400` is the default) if it is set to any value less than `10` so long as `innodb-file-per-table` is set to `1` or `TRUE` (the default). If `innodb_file_per_table` is set to `0` or `FALSE` **and** `innodb-open-files` is set to a value less than `10`, the default is `300`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/moving-from-mysql-to-mariadb-in-debian-9/>

apt-upgrade Fails, But the Database is Running
==============================================

    After running `apt-upgrade mariadb`, it's possible that apt shows a fail in trying to start the server, but in fact the database is up and running, which then provokes apt to remain in a non finished state.

 For example:

 
```
# apt-get upgrade
Reading package lists... Done
Building dependency tree
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
2 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n]
Setting up mariadb-server-10.1 (10.1.10+maria-1~trusty) ...
 * Stopping MariaDB database server mysqld
   ...done.
 * Starting MariaDB database server mysqld
   ...fail!
invoke-rc.d: initscript mysql, action "start" failed.
dpkg: error processing package mariadb-server-10.1 (--configure):
 subprocess installed post-installation script returned error exit status 1
dpkg: dependency problems prevent configuration of mariadb-server:
 mariadb-server depends on mariadb-server-10.1 (= 10.1.10+maria-1~trusty); however:
  Package mariadb-server-10.1 is not configured yet.
 
dpkg: error processing package mariadb-server (--configure):
 dependency problems - leaving unconfigured
No apport report written because the error message indicates its a followup error from a previous failure.
Errors were encountered while processing:
 mariadb-server-10.1
 mariadb-server
E: Sub-process /usr/bin/dpkg returned an error code (1)

```

This situation could occur if the timeout for the init script was too short. For example, see [MDEV-9382](https://jira.mariadb.org/browse/MDEV-9382), a situation where the timeout was 30 seconds, but the server was taking 48 seconds to start.

 To overcome this, the timeout needs to be increased. This can be achieved as follows:

 * **On systems where systemd is not enabled/supported:** The timeout can be increased by setting MYSQLD\_STARTUP\_TIMEOUT either directly in the script or via the command line. In [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) and later versions, the init script also sources /etc/default/mariadb, so it can also be used to set MYSQLD\_STARTUP\_TIMEOUT to persistently change the startup timeout. The default timeout has been increased from 30s to 60s in [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/).

 * **On systems that support systemd**: The startup timeout can be increased by setting [TimeoutStartSec systemd](../systemd/index) option.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/apt-upgrade-fails-but-the-database-is-running/>

Creating a Trace File
=====================

    If `mysqld` is crashing, creating a trace file is a good way to find the issue.

 A `mysqld` binary that has been compiled with debugging support can create trace files using the DBUG package created by Fred Fish. To find out if your `mysqld` binary has debugging support, run `mysqld -V` on the command line. If the version number ends in `-debug` then your `mysqld` binary was compiled with debugging support.

 See [Compiling MariaDB for debugging](../compiling-mariadb-for-debugging/index) for instructions on how to create your own `mysqld` binary with debugging enabled.

 To create the trace log, start `mysqld` like so:

 
```
mysqld --debug

```

Without options for --debug, the trace file will be named `/tmp/mysqld.trace` in MySQL and older versions of MariaDB before 10.5 and `/tmp/mariadbd.trace` starting from [MariaDB 10.5](../what-is-mariadb-105/index).

 On Windows, the debug `mysqld` is called `mysqld-debug` and you should also use the `--standalone` option. So the command on Windows will look like:

 
```
mysqld-debug --debug --standalone

```

Once the server is started, use the regular `mysql` command-line client (or another client) to connect and work with the server.

 After you are finished debugging, stop the server with:

 
```
mysqladmin shutdown

```

DBUG Options
------------

 Trace files can grow to a significant size. You can reduce their size by telling the server to only log certain items.

 The `--debug` flag can take extra options in the form of a colon (:) delimited string of options. Individual options can have comma-separated sub-options.

 For example:

 
```
mysqld --debug=d,info,error,query:o,/tmp/mariadbd.trace

```

The '`d`' option limits the output to the named DBUG\_<N> macros. In the above example, the `/tmp/mariadbd.trace` tracefile will contain output from the info, error, and query DBUG macros. A '`d`' by itself (with no sub-options) will select all DBUG\_<N> macros.

 The '`o`' option redirects the output to a file (`/tmp/mariadbd.trace` in the example above) and overwrites the file if it exists.

 See Also
--------

 * [Options for --debug](../mysql_debug/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-a-trace-file/>

Using Git
=========

    Just Getting the Source
-----------------------

 If you just want to get the latest source and you don't require the ability to push changes to the MariaDB repository, you can use the following command to check out the latest 10.5 branch:

 
```
git clone -b 10.5 https://github.com/MariaDB/server.git

```

Setup up git for MariaDB
------------------------

 * Set your name with git

 
```
git config --global user.name "Ivan Ivanov"
git config --global user.email "ivan@mariadb.com"

```

* Go to <https://github.com/settings/ssh> and add your public SSH key ([GitHub Help](https://help.github.com/articles/generating-ssh-keys/#step-3-add-your-ssh-key-to-github)).

 * Clone the repository

 
```
git clone git@github.com:MariaDB/server.git
cd server
git checkout 10.5

```

* Config repository pull and alias for fast forward:

 
```
git config pull.ff only
git config --global alias.ff "merge --ff-only"

```

Commit comments
---------------

 In git commit messages are normally formatted as

 
```
subject

body
more body
...

```

That is, the first line is considered a \*subject\*, much like email subject. Many git commands and pages on github only show the commit subject, not the complete comment. After the subject goes an empty line, then the detailed description of the comment. Please, structure your commit comments this way, don't forget the empty line.

 Branches
--------

 This is an important concept, and git branches do not have equivalents in bzr. 

 In Bazaar, we all used to have one shared repository, within which there were many branches. This seems to be impossible with git?

 In Git, each repository has only one branch that is currently checked out. 

 
```
git branch

```

### List Existing Branches

 To see which branches exists locally and remotely:

 
```
git branch --all

```

### To Move to Work on a Specific Branch

 
```
git checkout branch-name

```

Note that if the output from `git branch --all` is `remotes/origin/XXX` you should just use `XXX` as branch name.

 ### Making a Local Copy of a Branch (Like bzr clone)

 
```
branch clone old_directory new_directory
cd new_directory
git remote set-url origin git@github.com:MariaDB/server.git
git pull

```

### Remove Last Commit From a Branch

 
```
git reset --hard HEAD^ 

```

### Fetch a Branch Someone Has Done a Rebase on

 If you get the following error on pull:

 
```
shell>  git pull
X11 forwarding request failed on channel 0
fatal: Not possible to fast-forward, aborting.

```

Instead of removing your copy and then clone, you can do:

 
```
git reset --hard origin/##branch-name##

```

### Other Things About Branches

 * Note: branches whose names start with `bb-` are automatically put into the buildbot.

 Equivalents For Some bzr Commands
---------------------------------

 CAVEAT UTILITOR. Check the manual before running!

 * `bzr status` is `git status`
* `bzr diff` is `git diff`
* `bzr log` is `git log`
* `bzr revert` is `git reset --hard`
* `bzr revert filename` is `git checkout filename`
* `bzr parent` is `git remote -v` (but there are more detailed commands)
* `bzr parent to-default-mariadb-repo`  git remote set-url origin git@github.com:MariaDB/server.git
* `bzr push` is `git push REMOTENAME BRANCHNAME`. REMOTENAME is typically "origin", for example: `git push origin HEAD:10.3-new-feature`. The HEAD: stands for "from current branch".
* `bzr clean-tree --ignored` is `git clean -Xdf` (note the capital X!)
* `bzr root` is `git rev-parse --show-toplevel`
* `bzr missing --mine-only` is `git cherry -v origin` (kind-of).

 GUIs

 * `bzr gcommit` is `git citool`
* `bzr viz` is `gitk`
* `bzr gannotate` is `git gui blame`

 Commit Emails
-------------

 In the MariaDB project, it is a good idea (and a long tradition since MySQL Ab) to have all your commits sent to a commits@mariadb.org mailing list. It allows others to follow the progress, comment, etc.

 A script and instructions on how to setup commit triggers in Git are here: <http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/files/head:/git_template/> . Jira task for commit trigger was [MDEV-6278](https://jira.mariadb.org/browse/MDEV-6278).

 Attributing Code to Someone Else
--------------------------------

 If you add code on behalf of someone else, please attribute the code to the original author:

 * Run `git citool` and move changed files to staged.
* Don't `commit`, abort instead
* run `git commit --author="Original author name <email_address>"`

 The above is needed as `git citool` can't handle the `--author` option.

 Applying a Pull Request
-----------------------

 At the end of the pull request page there is a button "Merge pull request" and next to it a link "command line instructions". Click the link, you'll see something like

 
Step 1: From your project repository, check out a new branch and test the changes.

 
```
git checkout -b mariadb-server-joeuser-cool-feature 10.3
git pull https://github.com/joeuser/mariadb-server cool-feature

```

Step 2: Merge the changes and update on GitHub.

 
```
git checkout 10.3
git merge --no-ff mariadb-server-joeuser-cool-feature
git push origin 10.3

```


Note where to pull from — **https:/​/github.com/joeuser/mariadb-server cool-feature**.

 Now, checkout the branch you want to merge it to, say, bb-10.3-stage, and do the following

 
```
git fetch https://github.com/joeuser/mariadb-server cool-feature
git checkout FETCH_HEAD
git rebase @{-1}

```

Now's the time to compile the code, test it, fix, if necessary. Then

 
```
git checkout @{-1}
git ff @{-1}

```

If you want to do small changes to the pull request, do it in a separate commit, after `git rebase @{-1}` above. If you want to do *big* changes to the pull request, perhaps you shouldn't merge it in the first place, but ask the contributor to fix it?

 Examples
--------

 ### Diff For Last Commit

 
```
git show

```

### Applying New Code From Main Tree to a Branch

 You are working on a branch (`NEW_FEATURE`) and would like to have into that branch all changes from the main branch (`10.1`).

 
```
git checkout 10.1
git pull
git checkout NEW_FEATURE
git rebase 10.1

```

### Applying a Bugfix in the Main Branch

 You've just fixed and committed a bug in the main 10.1 branch and want to merge it with the latest 10.1. Often a rebase is better in this case. Assuming your current checked out branch is 10.1:

 
```
git fetch origin
git rebase origin/10.1

```

This will work even if you have done multiple commits in your local 10.1 tree.

 ### Dealing With Conflicts When One Tries to Push

 What to do when you have fixed a bug in the main tree but notices that someone has changed the tree since you pulled last time. This approach ensures that your patch is done in one block and not spread out over several change sets.

 
```
git clone 10.1  
cd 10.1
< fix a bug here>
git citool
git push
# ^ and the above fails, because someone has pushed to 10.1 in between
git branch tmp
# ^ copy our work to branch named 'tmp'
get checkout 10.1
git reset --hard HEAD^ 
# ^ remove our work from '10.1' local branch'
git pull 
# ^ get changes from remote
git checkout tmp
git rebase 10.1
# ^ switch to 'tmp' and try to rebase 'tmp' branch on top of 10.1 branch.
#   here you will be asked to merge if necessary
git checkout 10.1
git pull --ff . tmp
# ^ switch back to the '10.1' branch, and pull from 'tmp' branch. 
git branch -D tmp
#^ this removes the tmp. branch
git push

```

Finding in Which MariaDB Version a Commit Exists
------------------------------------------------

 
```
sh> git tag --contain e65f667bb60244610512efd7491fc77eccceb9db
mariadb-10.0.30
mariadb-10.1.22
mariadb-10.1.23
mariadb-10.2.5
mariadb-10.3.0
mariadb-galera-10.0.30

```

See Also
--------

 * <http://agateau.com/talks/2010/git-for-bzr-users_uds-natty/git-for-bzr-users.pdf>
* [Sergei's "Using GIT" presentation. Malaga Meeting, January 2015](https://mariadb.com/kb/en/usare-git/+attachment/using-git "Sergei's \"Using GIT\" presentation. Malaga Meeting, January 2015")

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-git/>

Compiling MariaDB with Vanilla XtraDB
=====================================

    Sometimes, one needs to have MariaDB compiled with Vanilla XtraDB. This page describes the process to do this. The process is rather crude, as my goal was just a once-off compile for testing (that is, not packaging or shipping) purposes.

 The process is applicable to [MariaDB 5.3.4](https://mariadb.com/kb/en/mariadb-534-release-notes/) and XtraDB from Percona Server 5.1.61.

 
```

wget http://s.petrunia.net/scratch/make-vanilla-xtradb-work-with-mariadb.diff

bzr branch /path/to/mariadb-5.3 5.3-vanilla-xtradb-r3

cd 5.3-vanilla-xtradb-r3/storage/
tar czf innodb_plugin.tgz innodb_plugin/
rm -rf innodb_plugin
tar czf xtradb.tgz xtradb/
rm -rf xtradb
cd ../../

tar zxvf ~/Percona-Server-5.1.61.tar.gz
cp -r Percona-Server-5.1.61/storage/innodb_plugin 5.3-vanilla-xtradb-r3/storage/
patch -p1 -d 5.3-vanilla-xtradb-r3/storage/innodb_plugin/ < make-vanilla-xtradb-work-with-mariadb.diff

cd 5.3-vanilla-xtradb-r3/

BUILD/autorun.sh
./configure --with-plugin-innodb_plugin
make

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-with-vanilla-xtradb/>

Compiling MariaDB with TCMalloc
===============================

    [TCMalloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html) is a malloc replacement library optimized for multi-threaded usage. It also features a built-in heap debugger and profiler.

 To build [MariaDB 5.5](../what-is-mariadb-55/index) with `TCMalloc`, you need to use the following command

 
```
cmake -DCMAKE_EXE_LINKER_FLAGS='-ltcmalloc'  -DWITH_SAFEMALLOC=OFF

```

Many other malloc replacement libraries (as well as heap debuggers and profilers) can be used with MariaDB in a similar fashion.

 You can also start a standard MariaDB server with `TCmalloc` with:

 
```
/usr/sbin/mysqld_safe --malloc-lib=tcmalloc

```

### See Also

 * [Debugging a running server on Linux](../debugging-a-running-server-on-linux/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/compiling-mariadb-with-tcmalloc/>

Buildbot Setup for Solaris x86
==============================

    The following steps were used to create a Solaris 10 x86 BuildSlave.

 I started with a default install of Solaris 10.

 First I added a new user with:

 
```
groupadd sudo
useradd -d /export/home/${username} -m -s /bin/bash -g staff -G sudo ${username}
passwd ${username}

```

I then logged in as the new user and setup an ssh key.

 Now to install software

 Prior to actually installing the software, I adjusted the global profile so that the /usr/local/ dirs were included in the various PATHs:

 
```
vi /etc/profile

# Add the following lines:

LD_LIBRARY_PATH=/opt/csw/lib:/usr/local/lib:/usr/sfw/lib:$LD_LIBRARY_PATH # Add required libraries
PYTHONPATH=/usr/local/lib/python2.5/site-packages:$PYTHONPATH
PATH=/usr/local/bin:/usr/bin:/usr/sbin:/etc:/usr/sfw/bin:$PATH # Puts "local" packages in your path
export LOGNAME PATH PYTHONPATH LD_LIBRARY_PATH

```

The extra software, I downloaded from sunfreeware:

 
```
cd /tmp
ftp ftp.sunfreeware.com
anonymous
none

bin
cd pub/freeware/intel/10/
mget python-2.5.1-sol10-x86-local.gz sudo-1.7.4p4-sol10-x86-local.gz libintl-3.4.0-sol10-x86-local.gz libgcc-3.4.6-sol10-x86-local.gz libiconv-1.13.1-sol10-x86-local.gz

mget automake-1.9-sol10-intel-local.gz autogen-5.9.8-sol10-x86-local.gz autoconf-2.68-sol10-x86-local.gz gcc-4.5.1-sol10-x86-local.gz

mget m4-1.4.15-sol10-x86-local.gz libtool-2.4-sol10-x86-local.gz gmp-4.2.1-sol10-x86-local.gz

mget md5-6142000-sol10-intel-local.gz openssl-1.0.0c-sol10-x86-local.gz libsigsegv-2.9-sol10-x86-local.gz tcl-8.5.9-sol10-x86-local.gz tk-8.5.9-sol10-x86-local.gz perl-5.12.2-sol10-x86-local.gz

mget libtool-2.4-sol10-x86-local.gz sed-4.2.1-sol10-x86-local.gz zlib-1.2.5-sol10-x86-local.gz binutils-2.21-sol10-x86-local.gz groff-1.21-sol10-x86-local.gz bzip2-1.0.6-sol10-x86-local.gz

mget make-3.82-sol10-x86-local.gz sed-4.2.1-sol10-x86-local.gz gdb-6.8-sol10-x86-local.gz coreutils-8.9-sol10-x86-local.gz cmake-2.6.0-sol10-x86-local.gz

quit

```

With all of the software downloaded, I next setup and configured sudo and python:

 
```
su
gunzip -v python-2.5.1-sol10-x86-local.gz 
pkgadd -d python-2.5.1-sol10-x86-local

gunzip -v libintl-3.4.0-sol10-x86-local.gz libgcc-3.4.6-sol10-x86-local.gz libiconv-1.13.1-sol10-x86-local.gz sudo-1.7.4p4-sol10-x86-local.gz

pkgadd -d libintl-3.4.0-sol10-x86-local
pkgadd -d libgcc-3.4.6-sol10-x86-local
pkgadd -d libiconv-1.13.1-sol10-x86-local
pkgadd -d sudo-1.7.4p4-sol10-x86-local

mkdir -p /usr/local/var/lib/
/usr/local/sbin/visudo

```

With sudo now working, I logged out and then back in. I then installed the other packages:

 
```
cd /tmp

gunzip -v *.gz

sudo pkgadd -d autoconf-2.68-sol10-x86-local
sudo pkgadd -d autogen-5.9.8-sol10-x86-local
sudo pkgadd -d automake-1.9-sol10-intel-local
sudo pkgadd -d binutils-2.21-sol10-x86-local
sudo pkgadd -d gcc-4.5.1-sol10-x86-local
sudo pkgadd -d groff-1.21-sol10-x86-local
sudo pkgadd -d libsigsegv-2.9-sol10-x86-local
sudo pkgadd -d make-3.82-sol10-x86-local
sudo pkgadd -d m4-1.4.15-sol10-x86-local
sudo pkgadd -d md5-6142000-sol10-intel-local
sudo pkgadd -d openssl-1.0.0c-sol10-x86-local
sudo pkgadd -d perl-5.12.2-sol10-x86-local
sudo pkgadd -d tcl-8.5.9-sol10-x86-local
sudo pkgadd -d tk-8.5.9-sol10-x86-local
sudo pkgadd -d zlib-1.2.5-sol10-x86-local
sudo pkgadd -d bzip2-1.0.6-sol10-x86-local
sudo pkgadd -d libtool-2.4-sol10-x86-local
sudo pkgadd -d sed-4.2.1-sol10-x86-local
sudo pkgadd -d gdb-6.8-sol10-x86-local
sudo pkgadd -d coreutils-8.9-sol10-x86-local
sudo pkgadd -d gmp-4.2.1-sol10-x86-local
sudo pkgadd -d cmake-2.6.0-sol10-x86-local

```

With those packages installed it was time to install the pieces of software which don't have pre-built packages:

 Install Zope Interface:

 
```
cd /tmp
wget http://www.zope.org/Products/ZopeInterface/3.3.0/zope.interface-3.3.0.tar.gz
gunzip -v zope.interface-3.3.0.tar.gz
gtar -xf zope.interface-3.3.0.tar
cd zope.interface-3.3.0/
python setup.py build
sudo python setup.py install

```

Install the latest Twisted framework:

 
```
cd /tmp
wget http://tmrc.mit.edu/mirror/twisted/Twisted/10.2/Twisted-10.2.0.tar.bz2
bunzip2 Twisted-10.2.0.tar.bz2 
gtar -xf Twisted-10.2.0.tar 
cd Twisted-10.2.0
sudo python setup.py install

```

Install Bazaar:

 
```
cd /tmp
wget http://launchpad.net/bzr/2.2/2.2.2/+download/bzr-2.2.2.tar.gz
gunzip -v bzr-2.2.2.tar.gz
gtar -xf bzr-2.2.2.tar
cd bzr-2.2.2
sudo python setup.py install

```

Install ccache:

 
```
cd /tmp
wget http://samba.org/ftp/ccache/ccache-3.1.4.tar.gz
gunzip ccache-3.1.4.tar.gz
gtar xvf ccache-3.1.4.tar
cd ccache-3.1.4
./configure --prefix /usr
make
sudo make install

```

Configure and start NTP:

 
```
sudo cp /etc/inet/ntp.server /etc/inet/ntp.conf
sudo vi /etc/inet/ntp.conf

#
# Comment out the following lines:
#server 127.127.XType.0
#fudge 127.127.XType.0 stratum 0
#broadcast 224.0.1.1 ttl 4
#
# Add in the following lines:

server 0.us.pool.ntp.org
server 1.us.pool.ntp.org
server 2.us.pool.ntp.org
server 3.us.pool.ntp.org

# save the file and quit back the the command prompt

sudo touch /var/ntp/ntp.drift
sudo ntpdate 0.us.pool.ntp.org
sudo svcadm enable svc:/network/ntp

```

Check out and make a test build of MariaDB:

 
```
cd
mkdir src
cd src/
bzr branch lp:maria trunk
cd trunk/
BUILD/compile-solaris-amd64

```

Add a user for buildbot:

 
```
sudo useradd -d /export/home/buildbot -m buildbot

```

Install Buildbot:

 
```
cd /tmp
wget http://buildbot.googlecode.com/files/buildbot-slave-0.8.3.tar.gz
gunzip -v buildbot-slave-0.8.3.tar.gz
gtar -xf buildbot-slave-0.8.3.tar
cd buildbot-slave-0.8.3/
sudo python setup.py install

```

Create the buildbot as the buildbot user:

 On the build master, add new entry to /etc/buildbot/maria-master-private.cfg

 Remember the ${slave-name} and ${password} configured above, they're used in the next step.

 Back on the solaris machine:

 
```
sudo su - buildbot
buildslave create-slave --usepty=0 /export/home/buildbot/maria-slave \
hasky.askmonty.org:9989 ${slavename} ${password}

echo '${contact-email-address}' > /export/home/buildbot/maria-slave/info/admin
echo 'A host running Solaris 10 x86.' > /export/home/buildbot/maria-slave/info/host

exit

```

Now start the slave:

 
```
sudo su - buildbot
buildslave start maria-slave

```

That's the basic process.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-solaris-x86/>

Limitations/Differences with a MariaDB Server Compiled for Debugging
====================================================================

    A MariaDB server configured with `--with-debug=full` has the following differences from a normal MariaDB server:

 * You can have maximum of 1000 tables locked at the same time in one statement. (Define `MAX_LOCKS` in mysys/thrlock.c). This is to detect loops in the used lists.
* You can have maximum of 1000 threads locking the same table. (Define `MAX_THREADS` in mysys/thrlock.c). This is to detect loops in the used lists.
* Deadlock detection of mutex will be done at runtime. If wrong mutex handling is found an error will be printed to the error log. (Define `SAFE_MUTEX`)
* Memory overrun/underrun and not freed memory will be reported to the error log (Define `SAFEMALLOC`)
* You can get a trace of what `mysqld` (and most other binaries) is doing by starting it with the `--debug` option. The trace is usually put in `/tmp` or `C:\`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/limitationsdifferences-with-a-mariadb-server-compiled-for-debugging/>

How to Use procmon to Trace mysqld.exe Filesystem Access
========================================================

    This article provides a walkthrough on using the Process Monitor on Windows, tracing file system access by mysqld.exe during the "install plugin" call.

 Download
--------

 Process Monitor is an advanced monitoring tool for Windows that shows real-time file system, registry and process/thread activity. It is a part of sysinternals suite developed by Mark Russinovich and Bryce Cogswell. Process Monitor can be directly downloaded from <http://download.sysinternals.com/files/ProcessMonitor.zip> . More description can be found at [https:*technet.microsoft.com/en-us/library/bb896645.aspx*](procmon%27s_microsoft_tecnet_page)

 Installation
------------

 There is no installation necessary; the single executable can be used after unpacking. I suggest putting procmon into some directory in the PATH [environment variable](../mariadb-environment-variables/index).

 Example of taking a mysqld.exe trace
------------------------------------

 The purpose of the following exercise is to learn how to use procmon to trace mysqld.exe calls to the filesystem.

 We assume that mysqld.exe is already started.

 1. Start procmon.exe . Dialog will pop up that offers to set filter. Use this dialog to set filter to "Process name" "is" "mysqld.exe", as shown in the screenshot below.

 ![Filter Setup]

 Click on "Add" button to mysqld.exe to include it in the filter, "Apply" and "OK".

 2. Capture events (Menu File=>Capture Events (Ctrl+E)

 3. Start mysql command line client and connect to the server.   
 Execute

 
```

mysql> install plugin blackhole soname 'ha_blackhole.dll';
Query OK, 0 rows affected (0.03 sec)

```
 4. Saving the trace

 Back to Process Monitor Windows, you should see the filesystem events initiated by the "INSTALL PLUGIN" operation

 ![Process Monitor Events](https://mariadb.com/kb/en/how-to-use-procmon-to-trace-mysqldexe-filesystem-access/+image/procmon_events "Process Monitor Events")

 To save it, choose File/Save.

 (Advanced) Seeing stack traces corresponding to events
------------------------------------------------------

 It is also possible to see stacktraces corresponding to the events. For this to work , symbols support needs to be configured. This needs to be only done once. 

 1. Install Debugging Tools for Windows (google on how to do that). 

 2. Switch to Process Monitor's menu Options => Configure symbols. 

 3. Add dbghelp.dll from your installation of Debugging Tools into "dbghelp.dll path" input field . On my system it is   
 C:\Program Files\Debugging Tools for Windows (x64)\dbghelp.dll

 4. In "symbol path" input field, add   
 srv\*C:\symbols\*[http://msdl.microsoft.com/download/symbols;<path\to\your\installation\bin](#)>   
 (substitute last last path element with real path to your installation)

 This is how it looks on my machine:

 ![Symbol Config]

 Once symbols are configured, you'll get a stack trace corresponding to a filesystem event by simply doubleclicking on the line corresponding to the event. This is what I see after clicking on the first event of my tracing session (corresponds to opening my.ini file)

 ![Callstack]

 It is also possible to save the the whole trace with callstacks as text (File/Save, choose XML, include callstack + resolve callstack).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-to-use-procmon-to-trace-mysqldexe-filesystem-access/>

How to match API version for php5\_mysql and mariadb client?
============================================================

    Hello! I have recent php5 and php5\_mysql installed from Ubuntu repos. When i'm running scripts connecting to DB i get "mysql\_connect(): Headers and client library minor version mismatch. Headers:50149 Library:50203".

 I suppose i could suppress errors but it isn't my way. But what is the correct way to fix it?

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installation-issues-with-php5/1079>

Buildbot Setup for Solaris Sparc
================================

    Setting up a BuildBot slave on Solaris
--------------------------------------

  **NOTE #1:** *It would probably make sense to create a seperate zone for the buildbot on your Solaris 10 system. That is left up to you!*

  **NOTE #2:** *You might need to install the Zope Interface package for some of the Python pieces to work properly. Do this after installing Python 2.5. You can find information on the Zope Interface on their [site](http://pypi.python.org/pypi/zope.interface).*

 ### Solaris 10 (SPARC)

 Unless you want to spend time optimizing the underlying Solaris 10 (SPARC) installation, it is strongly suggested that you choose the "Entire" Software Group during the installation process. Once you have your Solaris 10 (SPARC) system on the network and able to access the Internet you can use the following suggestions to setup your buildbot:

 1. By default Solaris 10 comes packages with Python 2.6.x. For compatibility reasons, you need to install Python 2.5.x. The author found it easiest to use Sunfreeware (ftp://ftp.sunfreeware.com/pub/freeware/sparc/5.10/):
```
$ cd /tmp
$ ftp ftp.sunfreeware.com
Name: anonymous
Password: (your email address)
ftp> bin
ftp> cd pub/freeware/sparc/5.10/
ftp> get python-2.5.4-sol10-sparc-local.gz
ftp> quit  
$ gunzip python-2.5.4-sol10-sparc-local.gz
$ pkgadd -d python-2.5.4-sol10-sparc-local

```
 *If you are unfamiliar with howto install packages from Sunfreeware please read their [howto](http://www.sunfreeware.com/indexsparc10.html).*
2. Setup your environment:
	* Create a user:
	```
	$ useradd -d /export/home/buildbot -m buildbot
	
	```
	 *It is imperative that you not use Bash as the buildbot user's shell. It could have been a dependency issue but I literally spent several days trying to solve why the buildbot wasn't checking out code with bzr only to discover that using the default Solaris shell fixed the problem. If someone comes up with a solution please let us know on the mailing list.*
	* Adjust the global profile (you could be more granular here but since I'm setting up a dedicated system I wasn't): 
	```
	$ vi /etc/profile
	LD_LIBRARY_PATH=/opt/csw/lib:/usr/local/lib:/usr/sfw/lib:$LD_LIBRARY_PATH # Add required libraries
	PYTHONPATH=/usr/local/lib/python2.5/site-packages:$PYTHONPATH # Makes Python 2.5 the default
	PATH=/usr/local/bin:/usr/bin:/usr/sbin:/etc:/usr/sfw/bin:$PATH # Puts "local" packages in your path
	export LOGNAME PATH PYTHONPATH LD_LIBRARY_PATH
	
	```
3. Install the latest Twisted: 
```
$ wget tmrc.mit.edu/mirror/twisted/Twisted/9.0/Twisted-9.0.0.tar.bz2
$ bunzip2 Twisted-9.0.0.tar.bz2
$ tar -xf Twisted-9.0.0.tar
$ cd Twisted-9.0.0
$ python setup.py build install

```
4. Install required packages from Sunfreeware:
```
automake, autoconf, gcc, m4, md5, openssl, libsigsegv, Tcl, Tk, perl,
libtool, sed, libgcc, gcc, libintl, libiconv, zlib, binutils, groff, cmake

```
5. Install the Bazaar DVCS:
	* You can find a package on [Google Code](http://code.google.com/p/bzrunix/downloads/list).
	* Install the latest Bazaar for Solaris 10. At the time of this writing it was 1.14.1: <http://bzrunix.googlecode.com/files/bzr-1.14.1-sol10-sparc-local.gz> .
6. Volunteer your buildbot to the Maria team. Follow the directions listed in the **Volunteering to run a build slave** section of the [About Buildbot](../about-buildbot/index) page.
7. Create the buildbot as the buildbot user:
```
buildbot create-slave --usepty=0 /export/home/buildbot/maria-slave
hasky.askmonty.org:9989 ${buildbotname} <passwd>

```
 *Replace ${buildbotname} with the buildbot name you received from the MariaDB developers. Replace <passwd> with the password they gave you. You can adjust these and other parameters anytime within the maria-slave/buildbot.tac file at anytime in the future.*
8. Create a shared Bazaar repository in the buildbot build directory:
```
HOME=/export/home/buildbot; bzr init-repo maria-slave/${buildbotname}

```
 *Replace ${buildbotname} like you did in **Step #7**.*
9. Attach the buildbot to the master (this assumes you are not logged in as buildbot): 
```
sudo su - buildbot -c "/usr/bin/buildbot start /export/home/buildbot/maria-slave"

```
  *OPTIONAL: You can create a proper service by following (and modifying as necessary) these [directions](http://wadofstuff.blogspot.com/2007/01/smf-manifest-for-buildbot.html)*
10. Please ask on the #maria [IRC](../irc/index) channel on irc.freenode.net if you have problems or questions setting up your buildbot. Or ask on the on the [maria-developers](http://launchpad.net/~maria-developers) mailing list.
11. Check the status of your buildbot through the [BuildBot buildslaves](http://buildbot.askmonty.org/buildbot/buildslaves) page.

 This howto was contributed by Adam Dutko. The original version is [here](http://littlehat.homelinux.org/tuts/MariaDB/buildbot/README-SOL10-SPARC).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-solaris-sparc/>

Debugging MariaDB
==================

   This section is for articles on debugging MariaDB.

  

| Title | Description |
| --- | --- |
|  [Compiling MariaDB for Debugging](../compiling-mariadb-for-debugging/index) |  Passing -DCMAKE\_BUILD\_TYPE=Debug to cmake to compile with debug information.  |
|  [Compile and Using MariaDB with Sanitizers (ASAN, UBSAN, TSAN, MSAN)](../compile-and-using-mariadb-with-sanitizers-asan-ubsan-tsan-msan/index) |  How to compile and use MariaDB with AddressSanitizer (ASAN).  |
|  [Limitations/Differences with a MariaDB Server Compiled for Debugging](../limitationsdifferences-with-a-mariadb-server-compiled-for-debugging/index) |  Differences in servers using the --with-debug=full option  |
|  [Debugging MariaDB With a Debugger](../debugging-mariadb-with-a-debugger/index) |  If MariaDB is compiled for debugging, you can both use it in a debugger, an...  |
|  [Debugging a Running Server (on Linux)](../debugging-a-running-server-on-linux/index) |  Debugging a production server on Linux.  |
|  [Creating a Trace File](../creating-a-trace-file/index) |  Creating a trace file is a good way to find mysqld crashing issues.  |
|  [How to Produce a Full Stack Trace for mysqld](../how-to-produce-a-full-stack-trace-for-mysqld/index) |  Producing a full stack trace and core file for mariadbd  |
|  [How to Use procmon to Trace mysqld.exe Filesystem Access](../how-to-use-procmon-to-trace-mysqldexe-filesystem-access/index) |  Walkthrough on using the Process Monitor on Windows  |
|  [MariaDB Community Bug Reporting](../reporting-bugs/index) |  Guidelines for reporting bugs in MariaDB software.  |
|  [MariaDB Security Bug Fixing Policy](../mariadb-security-bug-fixing-policy/index) |  Bug fixing policy and how security issues are handled.  |
|  [Enabling Core Dumps](../enabling-core-dumps/index) |  Steps to enable core dumps.  |
|  [Debugging Memory Usage](../debugging-memory-usage/index) |  How to debug MariaDB's memory usage.  |
|  [Optimizer Debugging With GDB](../optimizer-debugging-with-gdb/index) |  Useful things for debugging optimizer code with gdb.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/debugging-mariadb/>

How to Produce a Full Stack Trace for mysqld
============================================

    Partial Stack Traces in the Error Log
-------------------------------------

 When `mysqld` / `mariadbd` crashes, it will write a stack trace in the [error log](../error-log/index) by default. This is because the `[stack\_trace](../mysqld-options/index#-stack-trace)` option defaults to `ON`. With a normal release build, this stack trace in the [error log](../error-log/index) may look something like this:

 
```
2019-03-28 23:31:08 0x7ff4dc62d700  InnoDB: Assertion failure in file /home/buildbot/buildbot/build/mariadb-10.2.23/storage/innobase/rem/rem0rec.cc line 574
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to https://jira.mariadb.org/
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: https://mariadb.com/kb/en/library/innodb-recovery-modes/
InnoDB: about forcing recovery.
190328 23:31:08 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
 
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
 
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.
 
Server version: 10.2.23-MariaDB-10.2.23+maria~stretch
key_buffer_size=134217728
read_buffer_size=131072
max_used_connections=234
max_threads=752
thread_count=273
It is possible that mysqld could use up to 
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 1783435 K  bytes of memory
Hope that's ok; if not, decrease some variables in the equation.
 
Thread pointer: 0x7ff4d8001f28
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x7ff4dc62ccc8 thread_stack 0x49000
*** buffer overflow detected ***: /usr/sbin/mysqld terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7ffa09af5bfb]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7ffa09b7e437]
/lib/x86_64-linux-gnu/libc.so.6(+0xf7570)[0x7ffa09b7c570]
/lib/x86_64-linux-gnu/libc.so.6(+0xf93aa)[0x7ffa09b7e3aa]
/usr/sbin/mysqld(my_addr_resolve+0xe2)[0x55ca42284922]
/usr/sbin/mysqld(my_print_stacktrace+0x1bb)[0x55ca4226b1eb]
/usr/sbin/mysqld(handle_fatal_signal+0x41d)[0x55ca41d0a01d]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x110e0)[0x7ffa0b4180e0]
/lib/x86_64-linux-gnu/libc.so.6(gsignal+0xcf)[0x7ffa09ab7fff]
/lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7ffa09ab942a]
/usr/sbin/mysqld(+0x40f971)[0x55ca41ab8971]
/usr/sbin/mysqld(+0x887df6)[0x55ca41f30df6]
/usr/sbin/mysqld(+0x863673)[0x55ca41f0c673]
/usr/sbin/mysqld(+0x96648e)[0x55ca4200f48e]
/usr/sbin/mysqld(+0x89b559)[0x55ca41f44559]
/usr/sbin/mysqld(+0x8a15e4)[0x55ca41f4a5e4]
/usr/sbin/mysqld(+0x8a2187)[0x55ca41f4b187]
/usr/sbin/mysqld(+0x8b1a20)[0x55ca41f5aa20]
/usr/sbin/mysqld(+0x7f5c04)[0x55ca41e9ec04]
/usr/sbin/mysqld(_ZN7handler12ha_write_rowEPh+0x107)[0x55ca41d140d7]
/usr/sbin/mysqld(_Z12write_recordP3THDP5TABLEP12st_copy_info+0x72)[0x55ca41b4b992]
/usr/sbin/mysqld(_Z12mysql_insertP3THDP10TABLE_LISTR4ListI4ItemERS3_IS5_ES6_S6_15enum_duplicatesb+0x1206)[0x55ca41b560f6]
/usr/sbin/mysqld(_Z21mysql_execute_commandP3THD+0x3f68)[0x55ca41b6bee8]
/usr/sbin/mysqld(_Z11mysql_parseP3THDPcjP12Parser_statebb+0x28a)[0x55ca41b70e4a]
/usr/sbin/mysqld(+0x4c864f)[0x55ca41b7164f]
/usr/sbin/mysqld(_Z16dispatch_command19enum_server_commandP3THDPcjbb+0x1a7c)[0x55ca41b737fc]
/usr/sbin/mysqld(_Z10do_commandP3THD+0x176)[0x55ca41b748a6]
/usr/sbin/mysqld(_Z24do_handle_one_connectionP7CONNECT+0x25a)[0x55ca41c3ec0a]
/usr/sbin/mysqld(handle_one_connection+0x3d)[0x55ca41c3ed7d]
/usr/sbin/mysqld(+0xb75791)[0x55ca4221e791]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x74a4)[0x7ffa0b40e4a4]
/lib/x86_64-linux-gnu/libc.so.6(clone+0x3f)[0x7ffa09b6dd0f]

```

If you plan to [report a bug](../mariadb-community-bug-reporting/index) about the problem, then this information can be very useful for MariaDB's developers to track down the root cause. However, notice that some of the function names in the call stack are missing. In some cases, this partial stack trace may not be enough to find out exactly where the problem is.

 A full stack trace can only be produced if you have debugging symbols for your `mariadbd` binary. 

 Obtaining Debugging Symbols for Your `mariadbd` executable
----------------------------------------------------------

 Debug information is used by debugging tools to produce a meaningful stack trace. Importantly these packages do not replace any executables or any existing production executables or in any way interfere with the way the production server ran before these packages where installed.

 If you are obtaining a backtrace for a coredump, you can move the core dump to a difference server that has the identical mariadb-server and debug info packages, and perform the backtrace there with no loss of information.

 ### Installing Debug Info Packages on Linux

 On some Linux distributions, you may be able to install `debuginfo` packages that contain debugging symbols.

 Currently, `debuginfo` packages may not allow the server to print a nice stack trace in the error log. They also allow users to extract full stack traces from core dumps. See [MDEV-20738](https://jira.mariadb.org/browse/MDEV-20738) for more information.

 #### Installing Debug Info Packages with yum/dnf

 
**MariaDB starting with [5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/)**The MariaDB `yum` repository first added `[debuginfo](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Developer_Guide/intro.debuginfo.html)` packages in [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/).

 
On RHEL, CentOS, Fedora, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[yum](../yum/index)` or `[dnf](https://en.wikipedia.org/wiki/DNF_(software))`. Starting with RHEL 8 and Fedora 22, `yum` has been replaced by `dnf`, which is the next major version of `yum`. However, `yum` commands still work on many systems that use `dnf`. For example:

 
```
sudo yum install MariaDB-server-debuginfo

```

See [Installing MariaDB with yum/dnf: Installing Debug Info Packages with YUM](../yum/index#installing-debug-info-packages-with-yum) for more information.

 #### Installing Debug Info Packages with zypper

 
**MariaDB starting with [5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/)**The MariaDB `zypper` repository first added `[debuginfo](https://en.opensuse.org/openSUSE:Packaging_guidelines#Debuginfo)` packages in [MariaDB 5.5.64](https://mariadb.com/kb/en/mariadb-5564-release-notes/), [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), and [MariaDB 10.4.4](https://mariadb.com/kb/en/mariadb-1044-release-notes/).

 
On SLES, OpenSUSE, and other similar Linux distributions, it is highly recommended to install the relevant [RPM package](../rpm/index) from MariaDB's repository using `[zypper](../installing-mariadb-with-zypper/index)`. For example:

 
```
sudo zypper install MariaDB-server-debuginfo

```

See [Installing MariaDB with zypper: Installing Debug Info Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-debug-info-packages-with-zypp) for more information.

 #### Installing Debug Info Packages from MariaDB's Debian or Ubuntu repository

 These are for when you already installed MariaDB from a MariaDB mirror.

 For Ubuntu and additional repository step is needed:

 
```
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el,s390x]  https://ftp.osuosl.org/pub/mariadb/repo/10.5/ubuntu focal main/debug'

```

Adjust 10.5 to the major version you are debugging and focal to the required distribution.

 
```
apt-get update && apt-get install -y mariadb-server-core-10.5-dbgsym 

```

#### Installing Debug Info Packages packaged by Ubuntu or Debian

 If you used the MariaDB versions provided by Debian or Ubuntu see the following links.

 For Debian see <https://wiki.debian.org/AutomaticDebugPackages>

 For Ubuntu see <https://wiki.ubuntu.com/Debug%20Symbol%20Packages>

 ### Installing Debugging Symbols on Windows

 Debugging symbols are available to install on Windows.

 #### Installing Debugging Symbols with the MSI Installer on Windows

 Debugging symbols can be installed with the [MSI](../installing-mariadb-msi-packages-on-windows/index) installer. Debugging symbols are not installed by default. You must perform a custom installation and explicitly choose to install debugging symbols.

 The [MSI](../installing-mariadb-msi-packages-on-windows/index) installer can be downloaded from the [MariaDB downloads page](https://downloads.mariadb.org).

 #### Installing Debugging Symbols with the ZIP Package on Windows

 MariaDB also provides a [ZIP](../installing-mariadb-windows-zip-packages/index) package that contains debugging symbols on Windows.

 The [ZIP](../installing-mariadb-windows-zip-packages/index) package that contains debugging symbol can be downloaded from the [MariaDB downloads page](https://downloads.mariadb.org).

 Enabling Core Dumps
-------------------

 To enable core dumps, see [Enabling Core Dumps](../enabling-core-dumps/index) for details.

 Where is the Core File on Linux?
--------------------------------

 At the bottom of the error log there will be some text about the core location including:

 
```
Writing a core file...
Working directory at /var/lib/mariadb
Resource Limits:
Limit                     Soft Limit           Hard Limit           Units     
...
Max core file size        unlimited            unlimited            bytes     
...
Core pattern: |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h

Kernel version: Linux version 6.0.0-0.rc2.19.fc38.x86_64 (mockbuild@bkernel01.iad2.fedoraproject.org) (gcc (GCC) 12.2.1 20220819 (Red Hat 12.2.1-1), GNU ld version 2.39-2.fc38) #1 SMP PREEMPT_DYNAMIC Mon Aug 22 12:52:40 UTC 2022

```

If the was a core limit in the resource limits there may be limited or no core file information.

 If the core pattern begins with a **|**, then the following is the executable that handled the core file during the crash. The following show a few techniques to access the core depending on the pattern. If another program is used, look at its manual page to see how to get access to the core file.

 If a plain core filename is in the "Core pattern" there's a good chance it will be in the Working directory location. It might have a `.{process number}` suffix on the filename.

 ### Extracting a core file from a container

 If you are running MariaDB in a container, the locations where the core dump can be generated are limited. Looking at the container log, this will likely be where the error log information is. The "Core pattern" of a Linux system is currently a global fixed value. The consequence is if this core pattern refers to a program, that program isn't likely to be in the container and won't be executed on the crash.

 The system wide crash handler can be changed with `sysctl kernel.core_pattern=core` to set this back to a file based crash. With this, the crash should occur in the working directory, normally the `/var/lib/mysql` data directory of the container volume.

 ### Extracting a core file from systemd-coredump

 For `systemd-coredump`, there is a program `coredumpctl` to manage access.

 
```
coredumpctl list
TIME                            PID   UID   GID SIG     COREFILE EXE                                                                                        >
Fri 2022-09-09 14:16:37 AEST 213571  1000  1000 SIGSEGV present  /usr/sbin/mariadbd 

```

To access the program using `gdb`, `coredumpctl debug` (defaults to last crash), will load the core dump in gdb. The instructions in the [next section](#getting-backtraces-with-gdb-on-linux) for extracting information.

 See also: [extracting core dumps with systemd-coredump](../enabling-core-dumps/index#extracting-linux-core-dumps-with-systemd-coredump).

 ### Extract a core file from abrt

 A core pattern of `|/usr/libexec/abrt-hook-ccpp` indicates `abrt` system is used.

 `[abrt-cli](https://abrt.readthedocs.io/en/latest/usage.html)` is a command line user interface for access the core file.

 ### Extract a core file from apport

 A core pattern of `[|/usr/share/apport/apport` indicates `apport`.

 For more information see [Apport Project Wiki](https://wiki.ubuntu.com/Apport).

 `[apport-retrace](https://wiki.ubuntu.com/DebuggingProgramCrash#Using_apport-retrace)` allows you to "Examine Locally" and run a `gdb` session. One you have gdb started instructions in the [next section](#getting-backtraces-with-gdb-on-linux) can be used for extracting information.

 Analyzing a Core File with `gdb` on Linux
-----------------------------------------

 To analyze the core file on Linux, you can use `[gdb](https://www.gnu.org/software/gdb/documentation)`.

 For example, to open a core file with `[gdb](https://www.gnu.org/software/gdb/documentation)`, you could execute the following:

 
```
sudo gdb /usr/sbin/mariadbd  /var/lib/mysql/core.932

```

Be sure to replace `/usr/sbin/mariadbd` with the path to your `mariadbd` binary (might be `mysqld` on [MariaDB 10.4](../what-is-mariadb-104/index) and ealier) and to also replace `/var/lib/mysql/core.932` with the path to your core file.

 Once `[gdb](https://www.gnu.org/software/gdb/documentation)` has opened the core file, if you want to [log all output to a file](https://sourceware.org/gdb/current/onlinedocs/gdb/Logging-Output.html#Logging-Output), then you could execute the following commands:

 
```
set logging file /tmp/gdb_output.log
set logging on

```

If you do not execute `set logging file`, then the `set logging on` command creates a `gdb.txt` in your current working directory. Redirecting the output to a file is useful, because it can make it easier to analyze. It also makes it easier to send the information to a MariaDB developer, if that becomes necessary.

 Do any commands that you would like to do. For example, you could [get the backtraces](#getting-backtraces-with-gdb-on-linux).

 Once you are done, you can exit `[gdb](https://www.gnu.org/software/gdb/documentation)` by executing the `[quit](https://sourceware.org/gdb/current/onlinedocs/gdb/Quitting-GDB.html#Quitting-GDB)` command.

 Getting Backtraces with `gdb` on Linux
--------------------------------------

 On Linux, once you have debugging symbols for your `mariadbd` binary, you can use the `[gdb](https://www.gnu.org/software/gdb/documentation)` utility to get [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace), which are what `gdb` calls stack traces. Backtraces can be obtained from a core file or from a running `mariadbd` process.

 Full [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) are preferred and will contain function arguments, which can contain useful information such as query strings, so it can make the information easier to analyze.

 To get a **full** [backtrace](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) of the main thread, then you could execute the following:

 
```
bt -frame-arguments all full

```

If you want to get a **full** [backtrace](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) of **all** threads, then you could execute the following:

 
```
thread apply all bt -frame-arguments all full

```

If you want to get a full backtrace to a file to report a bug, the recommended way is to use gdb:

 
```
set logging on
set pagination off
set print frame-arguments all
thread apply all bt full
set logging off

```

This will write the full backtrace into the file `gdb.txt`.

 ### Getting Full Backtraces For All Threads From a Core File

 Sometimes it can be helpful to get **full** [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) for all threads. The full [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) will contain function arguments, which can contain useful information such as query strings, so it can make the information easier to analyze.

 To get **full** [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) for all threads from a `mariadbd` core file, execute a command like the following:

 
```
sudo gdb --batch --eval-command="set print frame-arguments all" --eval-command="thread apply all bt full" /usr/sbin/mariadbd /var/lib/mysql/core.932  > mariadbd_full_bt_all_threads.txt

```

Be sure to replace `/usr/sbin/mariadbd` with the path to your `mariadbd` binary and to also replace `/var/lib/mysql/core.932` with the path to your core dump.

 The [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) will be output to the file `mariadbd_full_bt_all_threads.txt`.

 ### Getting Full Backtraces For All Threads From a Running `mariadbd` Process

 Sometimes it can be helpful to get **full** [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) for all threads. The full backtraces will contain function arguments, which can contain useful information such as query strings, so it can make the information easier to analyze.

 To get **full** [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) for all threads from a running `mariadbd` process, execute a command like the following:

 
```
sudo gdb --batch --eval-command="set print frame-arguments all"  --eval-command="thread apply all bt full" /usr/sbin/mariadbd $(pgrep -xn mariadbd)  > mariadbd_full_bt_all_threads.txt

```

Be sure to replace `/usr/sbin/mariadbd` with the path to your `mariadbd` binary.

 The [backtraces](https://sourceware.org/gdb/current/onlinedocs/gdb/Backtrace.html#Backtrace) will be output to the file `mariadbd_full_bt_all_threads.txt`.

 Sometimes very busy systems are too busy to batch obtain the backtrace. If this is the case, `gcore $(pidof mariadbd)` can save the core and then obtain the backtrace out of the dumped core.

 Running a Copy of the Database Directory
----------------------------------------

 If you are concerned with debuggers running on your production database you can also copy the database to another location.

 This is useful when you know which statement crashed the server.

 Just start mariadbd with the options `--datadir=/copy-of-original-data-directory --core-file --stack-trace --socket=/tmp/mariadbd-alone.sock --skip-networking`

 Disabling Stack Traces in the Error Log
---------------------------------------

 In order to disable stack traces in the [error log](../error-log/index), you can configure the `[skip\_stack\_trace](../mysqld-options/index#-stack-trace)` option either on the command-line or in a relevant server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). For example:

 
```
[mariadb]
...
skip_stack_trace

```

Reporting the Problem
---------------------

 If you encounter some problem in MariaDB, then MariaDB's developers would appreciate if you would [report a bug](../mariadb-community-bug-reporting/index) at the [MariaDB JIRA bug tracker](https://jira.mariadb.org). Please include the following information:

 * Your full stack trace.
* Your [error log](../error-log/index).
* Your [option files](../configuring-mariadb-with-option-files/index).
* How to reproduce the problem.
* [SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index)
* [SHOW CREATE TABLE {table](../show-create-table/index) (for each table in query) and [EXPLAIN {query}](../explain/index) if a query related crash.

 A [MariaDB FTP server](../mariadb-ftp-server/index) is available for large and/or sensitive information. Please upload in `.tar.gz` or `.zip` archive.

 For very difficult or critical errors, you should consider uploading the following information to the [MariaDB FTP server](../mariadb-ftp-server/index) the following:

 * Your build of `mariadbd` (if you compiled it), otherwise version information on the mariadb-server package.
* Your core file.
* Your contact information.
* The associated [JIRA issue identifier](https://jira.mariadb.org) for the bug, if you [reported a bug](../mariadb-community-bug-reporting/index).

 This information will allow the MariaDB developers at the MariaDB Corporation to analyze it and try to create a fix.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/>

Debugging Memory Usage
======================

    Debugging memory usage on CentOS 7.

 This page describes how to debug MariaDB's memory usage. It uses CentOS 7 but can be applied to other systems as well.

 The idea is to employ Google PerfTools: <https://gperftools.github.io/gperftools/heapprofile.html>

 On CentOS :

 
```
sudo yum install gperftools 
service mariadb stop
systemctl edit mariadb

```

This will open an editor.

 Add this content and close the file:

 
```
[Service]
Environment="HEAPPROFILE=/tmp/heap-prof-1"
Environment="HEAP_PROFILE_ALLOCATION_INTERVAL=10737418240"
Environment="HEAP_PROFILE_INUSE_INTERVAL=1073741824"
Environment="LD_PRELOAD=/usr/lib64/libtcmalloc.so.4"

```

Then run 

 
```
service mariadb start

```

Then, run the workload. When memory consumption becomes large enough, ruh

 
```
ls -la /tmp/heap-prof-*

```

This should show several files. 

 Copy away the last one of them:

 
```
cp /tmp/heap-prof-1.0007.heap .

```

Then, run

 
```
pprof --dot /usr/sbin/mysqld heap-prof-1.0007.heap  > 7.dot

```

(Note: this produces a lot of statements like `/bin/addr2line: Dwarf Error: ...` . Is this because it cannot find locations from the plugin .so files in mariadbd? Anyhow, this is not a showstopper at the moment)

 Then, please send us the 7.dot file.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/debugging-memory-usage/>

Optimizer Debugging With GDB
============================

    Some useful things for debugging optimizer code with gdb.

 Useful Print Functions
----------------------

 * `dbug_print_item()` prints the contents of an `Item` object into a buffer and returns pointer to it.
* `dbug_print_sel_arg()` prints an individual `SEL_ARG` object (NOT the whole graph or tree) and returns pointer to the buffer holding the printout.
* `dbug_print_table_row` prints the current row buffer of the given table.
* There are more `dbug_print_XX` functions for various data structures

 Printing the Optimizer Trace
----------------------------

 The optimizer trace is collected as plain text. One can print the contents of the trace collected so far as follows:

 
```
printf "%s\n", thd->opt_trace->current_trace->current_json->output.str.Ptr

```

Printing Current Partial Join Prefix
------------------------------------

 `best_access_path()` is a function that adds another table to the join prefix.

 When in or around that function, the following can be useful:

 A macro to print the join prefix already constructed:

 
```
define bap_print_prefix
  set $i=0
  while ($i < idx)
    p join->positions[$i++].table->table->alias.Ptr
  end
end

```

Other Settings
--------------

 * May need to set [innodb\_fatal\_semaphore\_wait\_threshold](../innodb-system-variables/index#innodb_fatal_semaphore_wait_threshold) to be high enough?

 See Also
--------

 * [How to collect large optimizer traces](../how-to-collect-large-optimizer-traces/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-debugging-with-gdb/>

Puppet Overview for MariaDB Users
=================================

    Puppet is a tool to automate servers configuration management. It is produced by Puppet Inc, and released under the terms of the Apache License, version 2.

 It is entirely possible to use Ansible to automate MariaDB deployments and configuration. This page contains generic information for MariaDB users who want to learn, or evaluate, Puppet.

 Puppet modules can be searched using [Puppet Forge](https://forge.puppet.com/). Most of them are also published on GitHub with open source licenses. Puppet Forge allows filtering modules to only view the most reliable: supported by Puppet, supported by a Puppet partner, or approved.

 For information about installing Puppet, see [Installing and upgrading](https://puppet.com/docs/puppet/7.3/architecture.html) in Puppet documentation.

 Design Principles
-----------------

 With Puppet, you write **manifests** that describe the resources you need to run on certain servers and their **attributes**.

 Therefore manifests are **declarative**. You don't write the steps to achieve the desired result. Instead, you describe the desired result. When Puppet detects differences between your description and the current state of a server, it decides what to do to fix those differences.

 Manifests are also **idempotent**. You don't need to worry about the effects of applying a manifest twice. This may happen (see Architecture below) but it won't have any side effects.

 ### Defining Resources

 Here's an example of how to describe a resource in a manifest:

 
```
file { '/etc/motd':
  content => '',
  ensure => present,
}

```

This block describes a resource. The resource type is `file`, while the resource itself is `/etc/motd`. The description consists of a set of attributes. The most important is `ensure`, which in this case states that the file must exist. It is also common to use this resource to indicate that a file (probably created by a previous version of the manifest) doesn't exist.

 These classes of resource types exist:

 * **Built-in resources**, or **Puppet core resources**: Resources that are part of Puppet, maintained by the Puppet team.
* **Defined resources**: Resources that are defined as a combination of other resources. They are written in the Puppet domain-specific language.
* **Custom resources**: Resources that are written by users, in the Ruby language.

 To obtain information about resources:

 
```
# list existing resource types
puppet resource --types
# print information about the file resource type
puppet describe file

```

To group several resources in a reusable class:

 
```
class ssh_server {
  file { '/etc/motd':
    content => '',
    ensure => present,
  }
  file { '/etc/issue.net':
    content => '',
    ensure => present,
  }
}

```

There are several ways to include a class. For example:

 
```
include Class['ssh_server']

```

### Defining Nodes

 Puppet has a **main manifest** that could be a `site.pp` file or a directory containing `.pp` files. For simple infrastructures, we can define the nodes here. For more complex infrastructures, we may prefer to import other files that define the nodes.

 Nodes are defined in this way:

 
```
node 'maria-1.example.com' {
  include common
  include mariadb
}

```

The resource type is `node`. Then we specify a hostname that is used to match this node to an existing host. This can also be a list of hostnames, a regular expression that matches multiple nodes, or the `default` keyword that matches all hosts. To use a regular expression:

 
```
node /^(maria|mysql)-[1-3]\.example\.com$/ {
  include common
}

```

Concepts
--------

 The most important Puppet concepts are the following:

 * **Target**: A host whose configuration is managed via Puppet.
* **Group**: A logical group of targets. For example there may be a `mariadb` group, and several targets may be part of this group.
* **Facts**: Information collected from the targets, like the system name or system version. They're collected by a Ruby gem called [Facter](https://puppet.com/docs/puppet/latest/facter.html). They can be [core facts](https://puppet.com/docs/puppet/latest/core_facts.html) (collected by default) or [custom facts](https://puppet.com/docs/puppet/latest/custom_facts.html) (defined by the user).
* **Manifest**: A description that can be applied to a target.
* **Catalog**: A compiled manifest.
* **Apply**: Modifying the state of a target so that it reflects its description in a manifest.
* **Module**: A set of manifests.
* **Resource**: A minimal piece of description. A manifest consists of a piece of resources, which describe components of a system, like a file or a service.
* **Resource type**: Determines the class of a resource. For example there is a `file` resource type, and a manifest can contain any number of resources of this type, which describe different files.
* **Attribute**: It's a characteristic of a resource, like a file owner, or its mode.
* **Class**: A group of resources that can be reused in several manifests.

 Architecture
------------

 Depending on how the user decides to deploy changes, Puppet can use two different architectures:

 * An **Agent-master** architecture. This is the preferred way to use Puppet.
* A **standalone architecture**, that is similar to [Ansible architecture](../ansible-overview-for-mariadb-users/index#architecture).

 ### Agent-master Architecture

 A **Puppet master** stores a catalog for each target. There may be more than one Puppet master, for redundancy.

 Each target runs a **Puppet agent** in background. Each Puppet agent periodically connects to the Puppet master, sending its facts. The Puppet master compiles the relevant manifest using the facts it receives, and send back a catalog. Note that it is also possible to store the catalogs in PuppetDB instead.

 Once the Puppet agent receives the up-to-date catalog, it checks all resources and compares them with its current state. It applies the necessary changes to make sure that its state reflects the resources present in the catalog.

 ### Standalone Architecture

 With this architecture, the targets run **Puppet apply**. This application usually runs as a Linux cron job or a Windows scheduled task, but it can also be manually invoked by the user.

 When Puppet apply runs, it compiles the latest versions of manifests using the local facts. Then it checks every resource from the resulting catalogs and compares it to the state of the local system, applying changes where needed.

 Newly created or modified manifests are normally deployed to the targets, so Puppet apply can read them from the local host. However it is possible to use PuppetDB instead.

 ### PuppetDB

 PuppetDB is a Puppet node that runs a PostgreSQL database to store information that can be used by other nodes. PuppetDB can be used with both the Agent-master and the standalone architectures, but it is always optional. However it is necessary to use some advanced Puppet features.

 PuppetDB stored the following information:

 * The latest facts from each target.
* The latest catalogs, compiled by Puppet apply or a Puppet master.
* Optionally, the recent history of each node activities.

 ### External Node Classifiers

 With both architectures, it is possible to have a component called an External Node Classifier (ENC). This is a script or an executable written in any language that Puppet can call to determine the list of classes that should be applied to a certain target.

 An ENC received a node name in input, and should return a list of classes, parameters, etc, as a YAML hash.

 ### Bolt

 Bolt can be used in both architectures to run operations against a target or a set of targets. These operations can be commands passed manually to Bolt, scripts, Puppet tasks or plans. Bolt directly connects to targets via ssh and runs system commands.

 See [Bolt Examples](../bolt-examples/index) to get an idea of what you can do with Bolt.

 hiera
-----

 hiera is a hierarchical configuration system that allows us to:

 * Store configuration in separate files;
* Include the relevant configuration files for every server we automate with Puppet.

 See [Puppet hiera Configuration System](../puppet-hiera-configuration-system/index) for more information.

 Puppet Resources
----------------

 * [Puppet documentation](https://puppet.com/docs/).
* [forge.puppet.com](https://forge.puppet.com/).
* [Puppet on GitHub](https://github.com/puppetlabs/puppet).
* [Puppet on Wikipedia](https://en.wikipedia.org/wiki/Puppet_(company)).

 More information about the topics discussed in this page can be found in the Ansible documentation:

 * [Puppet Glossary](https://puppet.com/docs/puppet/latest/glossary.html) in Puppet documentation.
* [Overview of Puppet's architecture](https://puppet.com/docs/puppet/latest/architecture.html) in Puppet documentation.
* [PuppetDB documentation](https://puppet.com/docs/puppetdb/latest/index.html).
* [Classifying nodes](https://puppet.com/docs/puppet/latest/nodes_external.html) in Puppet documentation.
* [Hiera](https://puppet.com/docs/puppet/latest/hiera_intro.html) in Puppet documentation.
* [Bolt documentation](https://puppet.com/docs/bolt/latest/bolt.html).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/puppet-overview-for-mariadb-users/>

Bolt Examples
=============

     This page shows some examples of what we can do with Bolt to administer a set of MariaDB servers. Bolt is a tool that is part of the [Puppet](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index) ecosystem.

 For information about installing Bolt, see [Installing Bolt](https://puppet.com/docs/bolt/latest/bolt_installing.html) in Bolt documentation.

 Inventory Files
---------------

   
  
 The simplest way to call Bolt and instruct it to do something on some remote targets is the following:   
  


 
```
bolt ... --nodes 100.100.100.100,200.200.200.200,300,300,300,300

```

However, for non-trivial setups it is usually better to use an inventory file. An example:

 
```
targets:
  - uri: maria-1.example.com
    name: maria_1
    alias: mariadb_main
  ...

```

In this way, it will be possible to refer the target by name or alias.

 We can also define groups, followed by the group members. For example:

 
```
groups:
  - name: mariadb-staging
    targets:
        - uri: maria-1.example.com
        name: maria_1
        - uri: maria-2.example.com
        name: maria_2
  - name: mariadb-production
    targets:
      ...
...

```

With an inventory of this type, it will be possible to run Bolt actions against all the targets that are members of a group:

 
```
bolt ... --nodes mariadb-staging

```

In the examples in the rest of the page, the `--targets` parameter will be indicated in this way, for simplicity: `--targets <targets>`.

 Running Commands on Targets
---------------------------

 The simplest way to run a command remotely is the following:

 
```
bolt command run 'mariadb-admin start-all-slaves' --targets <targets>

```

Copying Files
-------------

 To copy a file or a whole directory to targets:

 
```
bolt file upload /path/to/source /path/to/destination --targets <targets>

```

To copy a file or a whole directory from the targets to the local host:

 
```
bolt file download /path/to/source /path/to/destination --targets <targets>

```

Running Scripts on Targets
--------------------------

 We can use Bolt to run a local script on remote targets. Bolt will temporarily copy the script to the targets, run it, and delete it from the targets. This is convenient for scripts that are meant to only run once.

 
```
bolt script run rotate_logs.sh --targets <targets>

```

Running Tasks on Targets
------------------------

 Puppet tasks are not always as powerful as custom scripts, but they are simpler and many of them are idempotent. The following task stops MariaDB replication:

 
```
bolt task run mysql::sql --targets <targets> sql="STOP REPLICA"

```

Applying Puppet Code on Targets
-------------------------------

 It is also possible to apply whole manifests or portions of Puppet code (resources) on the targets.

 To apply a manifest:

 
```
bolt apply manifests/server.pp  --targets <targets>

```

To apply a resource description:

 
```
bolt apply --execute "file { '/etc/mysql/my.cnf': ensure => present }" --targets <targets>

```

Bolt Resources and References
-----------------------------

 * [Bolt documentation](https://puppet.com/docs/bolt/latest/bolt.html).
* [Bolt on GitHub](https://github.com/puppetlabs/bolt).

 Further information about the concepts explained in this page can be found in Bolt documentation:

 * [Inventory Files](https://puppet.com/docs/bolt/latest/inventory_file_v2.html) in Bolt documentation.
* [Applying Puppet code](https://puppet.com/docs/bolt/latest/applying_manifest_blocks.html) in Bolt documentation.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/bolt-examples/>

Puppet hiera Configuration System
=================================

    hiera is part of [Puppet](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index). It is a hierarchical configuration system that allows us to:

 * Store configuration in separate files;
* Include the relevant configuration files for every server we automate with Puppet.

 hiera Configuration Files
-------------------------

 Each hierarchy allows to one choose the proper configuration file for a resource, based on certain criteria. For example criteria may include node names, node groups, operating systems, or datacenters. Hierarchies are defined in a `hiera.yaml` file, which also defines a path for the files in each hierarchy.

 Puppet facts are commonly used to select the proper files to use. For example, a path may be defined as `"os/%{facts.os.name}.yaml"`. In this case, each resource will use a file named after the operating system it uses, in the os directory. You may need to use custom facts, for example to check which microservices will use a MariaDB server, or in which datacenter it runs.

 We do not have to create a file for each possible value of a certain fact. We can define a default configuration file with settings that are reasonable for most resources. Other files, when included, will override some of the default settings.

 A hiera configuration file will look like this:

 
```
version: 5
defaults:
  datadir: global
  data_hash: yaml_data

hierarchy:
  - name: "Node data"
    path: "nodes/%{trusted.certname}.yaml"

  - name: "OS data"
    path: "os/%{facts.os.family}.yaml"

  - name: "Per-datacenter business group data" # Uses custom facts.
    path: "location/%{facts.whereami}/%{facts.group}.yaml"

```

This file would include the global files, the OS-specific files and the node-specific files. Each hierarchy will override settings from previous hierarchies.

 We can actually have several hiera configuration files. `hiera.yaml` is the global file. But we will typically have additional hiera configuration files for each environment. So we can include the configuration files that apply to production, staging, etc, plus global configuration files that should be included for every environment.

 Importantly, we can also have hiera configuration files for each module. So, for example, a separate `mariadb/hiera.yaml` file may defined the hierarchies for MariaDB servers. This allow us to define, for example, different configuration files for MariaDB and for MaxScale, as most of the needed settings are typically different.

 Configuration files
-------------------

 You probably noticed that, in the previous example, we defined `data_hash: yaml_data`, which indicates that configuration files are written in YAML. Other allowed formats are JSON and HOCON. The `data_hash` setting is defined in `defaults`, but it can be overridden by hierarchies.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/puppet-hiera-configuration-system/>

Deploying Docker Containers with Puppet
=======================================

    Puppet can also be used to manage Docker container upgrades and configuration changes. Docker has more specific tools for this purpose, but sometimes there are reasons to choose alternatives. See [Benefits of Managing Docker Containers with Automation Software](../benefits-of-managing-docker-containers-with-orchestration-software/index).

 In this page you will find out what managing Docker with Puppet looks like. All the snippets in this page use the `docker` resource type, supported by the Puppet company.

 How to Install, Upgrade or Uninstall Docker with Puppet
-------------------------------------------------------

 Installing or upgrading Docker is simple:

 
```
class { 'docker':
  use_upstream_package_source => false,
  version => '17.09.0~ce-0~debian',
}

```

In this example we are using our system's repositories instead of Docker official repositories, and we are specifying the desired version. To upgrade Docker later, all we need to do is to modify the version number. While specifying a version is not mandatory, it is a good idea because it makes our manifest more reproducible.

 To uninstall Docker:

 
```
class { 'docker':
  ensure => absent
}

```

Check the `docker` resource type documentation to find out how to use more features: for example you can use Docker Enterprise Edition, or bind the Docker daemon to a TCP port.

 How to Build or Pull Docker Images with Puppet
----------------------------------------------

 To pull an image from Dockerhub:

 
```
docker::image { 'mariadb:10.0': }

```

We specified the `10.0` tag to get the desired MariaDB version. If we don't, the image with the `latest` tag will be used. Note that this is not desirable in production, because it can lead to unexpected upgrades.

 You can also write a Dockerfile yourself, and then build it to create a Docker image. To do so, you need to instruct Puppet to copy the Dockerfile to the target and then build it::

 
```
file { '/path/to/remote/Dockerfile':
  ensure => file,
  source => 'puppet:///path/to/local/Dockerfile',
}

docker::image { 'image_name':
  docker_file => '/path/to/remote/Dockerfile'
}

```

It is also possible to subscribe to Dockerfile changes, and automatically rebuild the image whenever a new file is found:

 
```
docker::image { 'image_name':
  docker_file => '/path/to/remote/Dockerfile'
  subscribe => File['/path/to/remote/Dockerfile'],
}

```

To remove an image that was possibly built or pulled:

 
```
docker::image { 'mariadb':
  ensure => absent
}

```

How to Deploy Containers with Puppet
------------------------------------

 To run a container:

 
```
docker::run { 'mariadb-01':
    image   => 'mariadb:10.5',
    ports   => ['3306:6606']
}

```

`mariadb-01` is the contained name. We specified the optional `10.5` tag, and we mapped the guest port 3306 to the host port 6606. In production, you normally don't map ports because you don't need to connect MariaDB clients from the host system to MariaDB servers in the containers. Third-party tools can be installed as separate containers.

 References
----------

 * [docker resource type documentation](https://forge.puppet.com/modules/puppetlabs/docker), in Puppet documentation.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/deploying-docker-containers-with-puppet/>

Existing Puppet Modules for MariaDB
===================================

    This page contains links to Puppet modules that can be used to automate MariaDB deployment and configuration. The list is not meant to be exhaustive. Use it as a starting point, but then please do your own research.

 Puppet Forge
------------

 Puppet Forge is the website to search for Puppet modules, maintained by the Puppet company. Modules are searched by the technology that needs to be automated, and the target operating system.

 Search criteria include whether the modules are supported by Puppet or its partners, and whether a module is approved by Puppet. Approved modules are certified by Puppet based on their quality and maintenance standards.

 Acceptance Tests
----------------

 Some modules that support the Puppet Development Kit allow some types of acceptance tests.

 We can run a static analysis on a module's source code to find certain bad practices that are likely to be a source of bugs:

 
```
pdk validate

```

If a module's authors wrote unit tests, we can run them in this way:

 
```
pdk test unit

```

Supported Modules for MariaDB
-----------------------------

 At the time of writing, there are no supported or approved modules for MariaDB.

 However there is a [mysql module](https://forge.puppet.com/modules/puppetlabs/mysql) supported by Puppet, that supports the Puppet Development Kit. Though it doesn't support MariaDB-specific features, it works with MariaDB. Its documentation shows how to use the module to install MariaDB on certain operating systems.

 Several unsupported and not approved modules exist for MariaDB and MaxScale.

 Resources and References
------------------------

 * [Puppet Forge](https://forge.puppet.com/) website.
* [Puppet Development Kit](https://puppet.com/docs/pdk/1.x/pdk.html) documentation.
* [Modules overview](https://puppet.com/docs/puppet/7.1/modules_fundamentals.html) in Puppet documentation.
* [Beginner's guide to writing modules](https://puppet.com/docs/puppet/7.1/bgtm.html) in Puppet documentation.
* [Puppet Supported Modules](https://forge.puppet.com/supported) page in Puppet Forge.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/existing-puppet-modules-for-mariadb/>

Vagrant and MariaDB
====================

   Vagrant is an open source tool to quickly setup machines that can be used for development and testing. These machines can be local virtual machines, Docker containers, AWS EC2 instances, and so on. Vagrant allows one to easily and quickly setup test MariaDB servers.

  

| Title | Description |
| --- | --- |
|  [Vagrant Overview for MariaDB Users](../vagrant-overview-for-mariadb-users/index) |  Vagrant architecture, general concepts and basic usage.  |
|  [Creating a Vagrantfile](../creating-a-vagrantfile/index) |  How to create a new Vagrant box running MariaDB.  |
|  [Vagrant Security Concerns](../vagrant-security-concerns/index) |  Security matters related to Vagrant machines.  |
|  [Running MariaDB ColumnStore containers on Linux, Windows and MacOS](../running-mariadb-columnstore-containers-on-linux-windows-and-macos/index) |  The ColumnStore container allows for a simple setup of a ColumnStore single...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/vagrant-and-mariadb/>

Why to Automate MariaDB Deployments and Management
==================================================

    MariaDB includes a powerful [configuration system](../configuring-mariadb-with-option-files/index). This is enough when we need to deploy a single MariaDB instance, or a small number of instances. But many modern organisations have many database servers. Deploying and upgrading them manually could require too much time, and would be error-prone.

 Infrastructure as Code
----------------------

 Several tools exist to deploy and manage several servers automatically. These tools operate at a higher level, and execute tasks like installing MariaDB, running queries, or generating new configuration files based on a template. Instead of upgrading servers manually, users can launch a command to upgrade a group of servers, and the automation software will run the necessary tasks.

 Servers can be described in a code repository. This description can include MariaDB version, its configuration, users, backup jobs, and so on. This code is human-readable, and can serve as a documentation of which servers exist and how they are configured. The code is typically versioned in a repository, to allow collaborative development and track the changes that occurred over time. This is a paradigm called **Infrastructure as Code**.

 Automation code is high-level and one usually doesn’t care how operations are implemented. Their implementation is delegated to modules that handle specific components of the infrastructure. For example a module could equally work with apt and yum package managers. Other modules can implement operations for a specific cloud vendor, so we declare we want a snapshot to be done, but we don’t need to write the commands to make it happen. For special cases, it is of course possible to write Bash commands, or scripts in every language, and declare that they must be run.

 Manual interventions on the servers will still be possible. This is useful, for example, to investigate performance problems. But it is important to leave the servers in the state that is described by the code.

 This code is not something you write once and never touch again. It is periodically necessary to modify infrastructures to update some software, add new replicas, and so on. Once the base code is in place, making such changes is often trivial and potentially it can be done in minutes.

 Automated Failover
------------------

 Once [replication](../standard-replication/index) is in place, two important aspects to automate are load balancing and failover.

 Proxies can implement load balancing, redirecting the queries they receive to different server, trying to distribute the load equally. They can also monitor that MariaDB servers are running and in good health, thus avoiding sending queries to a server that is down or struggling.

 However, this does not solve the problem with replication: if a primary server crashes, its replicas should point to another server. Usually this means that an existing replica is promoted to a master. This kind of changes are possible thanks to MariaDB [GTID](../gtid/index).

 One can promote a replica to a primary by making change to existing automation code. This is typically simple and relatively quick to do for a human operator. But this operation takes time, and in the meanwhile the service could be down.

 Automating failover will minimise the time to recover. A way to do it is to use Orchestrator, a tool that can automatically promote a replica to a primary. The choice of the replica to promote is done in a smart way, keeping into account things like the servers versions and the [binary log](../binary-log/index) format.

 Resources
---------

 * [Continuous configuration automation on Wikipedia](https://en.wikipedia.org/wiki/Continuous_configuration_automation).
* [Infrastructure as code on Wikipedia](https://en.wikipedia.org/wiki/Infrastructure_as_code).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/why-to-automate-mariadb-deployments-and-management/>

A Comparison Between Automation Systems
=======================================

    This page compares the automation systems that are covered by this section of the MariaDB Knowledge Base. More information about these systems are presented in the relevant pages, and more systems may be added in the future.

 Code Structure Differences
--------------------------

 Different automation systems provide different ways to describe our infrastructure. Understanding how they work is the first step to evaluate them and choose one for our organization.

 ### Ansible Code Structure

 Ansible code consists of the following components:

 * An **inventory** determines which **hosts** Ansible should be able to deploy. Each host may belong to one or more **groups**. Groups may have **children**, forming a hierarchy. This is useful because it allows us to deploy on a group, or to assign variables to a group.
* A **role** describes the state that a host, or group of hosts, should reach after a deploy.
* A **play** associates hosts or groups to their roles. Each role/group can have more than one role.
* A role consists of a list of **tasks**. Despite its name a task is not necessarily something to do, but something that must exist in a certain state.
* Tasks can use **variables**. They can affect how a task is executed (for example a variable could be a file name), or even whether a task is executed or not. Variables exist at role, group or host level. Variables can also be passed by the user when a play is applied.
* **Playbooks** are the code that is used to define tasks and variables.
* **Facts** are data that Ansible retrieves from remote hosts before deploying. This is a very important step, because facts may determine which tasks are executed or how they are executed. Facts include, for example, the operating system family or its version. A playbook sees facts as pre-set variables.
* **Modules** implement **actions** that tasks can use. Action examples are **file** (to declare that files and directories must exist) or **mysql\_variables** (to declare MySQL/MariaDB variables that need to be set).

 See [Ansible Overview - concepts](../ansible-overview/index#concepts) for more details and an example.

 ### Puppet Code Structure

 Puppet code consists of the following components:

 * An **inventory file** defines a set of **groups** and their **targets** (the members of a group). **plugins** can be used to retrieve groups and target dynamically, so they are equivalent to Ansible dynamic inventories.
* A **manifest** is a file that describes a configuration.
* A **resource** is a component that should run on a server. For example, "file" and "service" are existing support types.
* An **attribute** relates to a resource and affects the way it is applied. For example, a resource of type "file" can have attributes like "owner" and "mode".
* A **class** groups resources and variables, describing a logical part of server configuration. A class can be associated to several servers. A class is part of a manifest.
* A **module** is a set of manifests and describes an infrastructure or a part of it.
* Classes can have typed **parameters** that affect how they are applied.
* **Properties** are variables that are read from the remote server, and cannot be arbitrarily assigned.
* **Facts** are pre-set variables collected by Puppet before applying or compiling a manifest.

 Architectural Differences
-------------------------

 The architecture of the various systems is different. Their architectures determine how a deploy physically works, and what is needed to be able to deploy.

 ### Ansible Architecture

 Ansible architecture is simple. Ansible can run from any host, and can apply its playbooks on remote hosts. To do this, it runs commands via SSH. In practice, in most cases the commands will be run as superuser via `sudo`, though this is not always necessary.

 Inventories can be dynamic. In this case, when we apply a playbook Ansible connects to remote services to discover hosts.

 Ansible playbooks are applied via the `ansible-playbook` binary. Changes to playbooks are only applied when we perform this operation.

 To recap, Ansible does not need to be installed on the server is administers. It needs an SSH access, and normally its user needs to be able to run `sudo`. It is also possible to configure a dynamic inventory, and a remote service to be used for this purpose.

 ### Puppet Architecture

 Puppet supports two types of architecture: agent-master or standalone. The agent-master architecture is recommended by Puppet Labs, and it is the most popular among Puppet users. For this reason, those who prefer a standalone architecture tend to prefer Ansible.

 #### Agent-Master Architecture

 When this architecture is chosen, manifests are sent to the **Puppet master**. There can be more than one master, for high availability reasons. All target hosts run a **Puppet agent**. Normally this is a service that automatically starts at system boot. The agent contacts a master at a given interval. It sends facts, and uses them to compile a **catalog** from the manifests. A catalog is a description of what exactly an individual server should run. The agent receives the catalog and checks if there are differences between its current configuration and the catalog. If differences are found, the agent applies the relevant parts of the catalog.

 An optional component is **PuppetDB**. This is a central place where some data are stored, including manifests, retrieved facts and logs. PuppetDB is based on PostgreSQL and there are no plans to support MariaDB or other DBMSs.

 If a manual change is made to a remove server, it will likely be overwritten the next time Puppet agent runs. To avoid this, the Puppet agent service can be stopped.

 #### Standalone Architecture

 As mentioned, this architecture is not recommended by Puppet Labs nor popular amongst Puppet users. It is similar to Ansible architecture.

 Users can apply manifests from any host with Puppet installed. This could be their laptop but, in order to emulate the behavior of an agent-master architecture, normally Puppet runs on a dedicated node as a cronjob. The **Puppet apply** application will require facts from remote hosts, it will compile a catalog for each host, will check which parts of it need to be applied, and will apply them remotely.

 If a manual change is made to a remove server, it will be overwritten the next time Puppet apply runs. To avoid this, comment out any cron job running Puppet apply, or comment out the target server in the inventory.

 #### Inventory

 As mentioned, Puppet supports plugins to retrieve the inventory dynamically from remote services. In an agent-master architecture, one has to make sure that each target host has access to these services. In a standalone architecture, one has to make sure that the hosts running Puppet apply have access to these services.

 Storing Secrets
---------------

 Often our automation repositories need to contain secrets, like MariaDB user passwords or private keys for SSH authentication.

 Both Ansible and Puppet support integration with secret stores, like Hashicorp Vault. For Puppet integration, see [Integrations with secret stores](https://puppet.com/docs/puppet/6.17/integrations_with_secret_stores.html).

 In the simplest case, Ansible allows encrypting secrets in playbooks and decrypting them during execution using [ansible-vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html). This implies a minimal effort to handle secrets. However, it is not the most secure way to store secrets. The passwords to disclose certain secrets need to be shared with the users who have the right to use them. Also, brute force attacks are possible.

 Ecosystems and Communities
--------------------------

 Automation software communities are very important, because they make available a wide variety of modules to handle specific software.

 ### Ansible Ecosystem

 Ansible is open source, released under the terms of the GNU GPL. It is produced by RedHat. RedHat has a page about [Red Hat Ansible Automation Platform Partners](https://www.ansible.com/partners), who can provide support and consulting.

 [Ansible Galaxy](https://galaxy.ansible.com/) is a big repository of Ansible roles produced by both the vendor and the community. Ansible comes with `ansible-galaxy`, a tool that can be used to create roles and upload them to Ansible Galaxy.

 At the time of this writing, Ansible does not have specific MariaDB official modules. MySQL official modules can be used. However, be careful not try to use features that only apply to MySQL. There are several community-maintained MariaDB roles.

 ### Puppet Ecosystem

 Puppet is open source, released under the GNU GPL. It is produced by a homonym company. The page [Puppet Partners](https://puppet.com/partners/) lists partners that can provide support and consulting about Puppet.

 [Puppet Forge](https://forge.puppet.com/) is a big repository of modules produced by the vendor and by the community, as well as how-to guides.

 Currently Puppet has many MariaDB modules.

 See Also
--------

 For more information about the systems mentioned in this page, from MariaDB users perspective:

 * [Ansible and MariaDB](../ansible-and-mariadb/index).
* [Puppet and MariaDB](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/a-comparison-between-automation-systems/>

MariaDB Containers
===================

   Containers are an OCI standard format for software images and their specified time all bundled up into a single distributable itme. They can be used for production, development or testing.

 Docker Inc. run a [Docker Official Images](https://docs.docker.com/docker-hub/official_images) program to provide users with an essential base implementation of MariaDB in a container and to exemplify best practices of a container.

 The containers are [available on Docker Hub](https://hub.docker.com/_/mariadb) as **docker.io/library/mariadb** though many container runtime implementation will fill in the **docker.io/library** where the host/path isn't specified.

 The containers are in a Open Container Initiative format that allows the containers to be interoperable with a number of container runtime implementations. Docker, or more fully Docker Engine, is just one of the many available runtimes.

 Many people use MariaDB Docker Official Image containers in CI systems like GitHub Actions, though its possible to use these in production environments like kubernetes.

 The MariaDB Server container images are available with a number of tags:

 * A full version, like 10.6.14
* A major version like 10.6
* The last stable GA version - **latest**
* The last stable LTS version - **lts**

 Versions that aren't stable will be suffixed with **-rc**, or **-alpha** to clearly show their release status, and enables [Renovatebot](https://github.com/grooverdan/mariadb-docker/commit/a9a98d720ddc5afe5c62449bbe737f4780aee0fe) and other that follow [semantic versioning](https://docs.renovatebot.com/modules/versioning/#semantic-versioning) to follow updates.

 For a consistent application between testing an production environment using the sha hash of the image is recommended like **docker.io/library/mariadb@sha256:29fe5062baf36bae8ec68f21a3dce4f0372dadc185e687624f1252fc49d91c67**. There is a list of mapping and history of tags to sha hash on the [Docker Library repository](https://github.com/docker-library/repo-info/tree/master/repos/mariadb/remote).

  

| Title | Description |
| --- | --- |
|  [Benefits of Managing MariaDB Containers with Orchestration Software](../benefits-of-managing-mariadb-containers-with-orchestration-software/index) |  Benefits of managing MariaDB Containers with Automation Software.  |
|  [Installing and Using MariaDB via Docker](../installing-and-using-mariadb-via-docker/index) |  Creating and managing a MariaDB Docker container.  |
|  [Running MariaDB ColumnStore containers on Linux, Windows and MacOS](../running-mariadb-columnstore-containers-on-linux-windows-and-macos/index) |  The ColumnStore container allows for a simple setup of a ColumnStore single...  |
|  [Creating a Custom Container Image](../creating-a-custom-container-image/index) |  How to write a Dockerfile to create custom images.  |
|  [Setting Up a LAMP Stack with Docker Compose](../setting-up-a-lamp-stack-with-docker-compose/index) |  How to use Docker Compose to set up containers running a LAMP stack.  |
|  [Docker Security Concerns](../docker-security-concerns/index) |  Security matters related to Docker containers.  |
|  [MariaDB Container Cheat Sheet](../mariadb-container-cheat-sheet/index) |  Get the images Images can be found on MariaDB Docker Hub. To get the list o...  |
|  [MariaDB Server Docker Official Image Environment Variables](../mariadb-server-docker-official-image-environment-variables/index) |  Environment variables can be passed on the docker run command line.  |
|  [Using Healthcheck.sh script](../using-healthcheck-sh-script/index) |  healtcheck.sh  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/docker-and-mariadb/>

Kubernetes and MariaDB
=======================

   General information and hints on how to deploy MariaDB Kubernetes containers.

 Kubernetes is an open source containers orchestration system. It automates deployments, horizontal scaling, configuration and operations. It is often referred to as K8s.

  

| Title | Description |
| --- | --- |
|  [Kubernetes Overview for MariaDB Users](../kubernetes-overview-for-mariadb-users/index) |  An overview of Kubernetes and how it works with MariaDB.  |
|  [Kubernetes Operators for MariaDB](../kubernetes-operators-for-mariadb/index) |  An overview of Kubernetes operators that can be used with MariaDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/kubernetes-and-mariadb/>

Automating Upgrades with MariaDB.Org Downloads REST API
=======================================================

    The MariaDB Foundation maintains a Downloads REST API. See the [Downloads API documentation](https://mariadb.org/downloads-rest-api/) to find out all the tasks that you can accomplish with this API. Generally speaking, we can say that it provides information about MariaDB products and available versions. This allows to easily automate upgrades for MariaDB and related products.

 The Downloads API exposes HTTPS endpoints that return information in JSON format. HTTP and JSON are extremely common standards that can be easily used with any programming language. All the information provided by the API is public, so no authentication is required.

 How to Use the API with a Unix Shell
------------------------------------

 Linux shells are great for writing simple scripts. They are compatible to each other to some extent, so simple scripts can be run on almost any Unix/Linux system. In the following examples we'll use Bash.

 On Linux, some programs you'll generally need to work with any REST API are:

 * [curl](https://curl.se/), to call HTTP URLs and get their output.
* [js](https://stedolan.github.io/jq/), to extract or transform information from a JSON document.

 ### Example: Check When a New Version Becomes GA

 A trivial use case is to write a script that checks the list of MariaDB GA major versions and, when something changes, send us an email. So we can test the newest GA version and eventually install it.

 The script in this example will be extremely simple. We'll do it this way:

 * Retrieve the JSON object describing all MariaDB versions.
* For each element of the array, only show the `release_id` and `release_status` properties, and concatenate them.
* Apply a filter, so we only select the rows containing 'stable' but not 'old' (so we exclude 'Old Stable').
* From the remaining rows, only show the first column (the version number).

 * If the results we obtained are different from the previously written file (see last point) send an email.
* Save the results into a file.

 This is something that we can easily do with a Unix shell:

 
```
#!/bin/bash

current_ga_versions=$(
    curl https://downloads.mariadb.org/rest-api/mariadb/ | \
    jq -r '.major_releases[] | .release_id + " " + .release_status' | \
    grep -i 'stable' | grep -vi 'old' | \
    cut -d ' ' -f 1
)

# create file if it doesn't exist, then compare version lists
touch ga_versions
previous_ga_versions=$( cat ga_versions )

echo "$current_ga_versions" > ga_versions

if [ "$current_ga_versions" != "$previous_ga_versions" ];
then
    mail -s 'NOTE: New MariaDB GA Versions' devops@example.com <<< 'There seems to be a new MariaDB GA version! Yay!'
fi

```

The only non-standard command here is jq. It is a great way to manipulate JSON documents, so if you don't know it you may want to take a look at [jq documentation](https://stedolan.github.io/jq/manual/).

 How to Use the API with a Python Script
---------------------------------------

 To use the API with Python, we need a module that is able to send HTTP requests and parse a JSON output. The `requests` module has both these features. It can be installed as follows:

 
```
pip install requests

```

The following script prints stable versions to the standard output:

 
```
#!/usr/bin/env python

import requests

response = requests.get('https://downloads.mariadb.org/rest-api/mariadb/').json()

for x in response['major_releases']:
    if x['release_status'] == 'Stable':
        print(x['release_id'])

```

`requests.get()` makes an HTTP call of type GET, and `requests.json()` returns a dictionary representing the previously obtained JSON document.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/automating-upgrades-with-mariadborg-downloads-rest-api/>

Upgrading from MySQL to MariaDB
===============================

     For [all practical purposes](../mariadb-vs-mysql-compatibility/index), you can view MariaDB as an upgrade of MySQL:

 * Before upgrading, please [check if there are any known incompatibilities](../mariadb-vs-mysql-compatibility/index) between your MySQL release and the MariaDB release you want to move to.
* In particular, note that the [JSON type](../json-data-type/index) in MariaDB is a LONGTEXT, while in MySQL it's a binary type. See [Making MariaDB understand MySQL JSON](https://mariadb.org/making-mariadb-understand-mysql-json/).
* If you are using MySQL 8.0 or above, you have to use [mysqldump](../mysqldump/index) to move your database to MariaDB.
* For upgrading from very old MySQL versions, see [Upgrading to MariaDB from MySQL 5.0 (or older version)](../upgrading-to-mariadb-from-mysql-50-or-older-version/index).
* Within the same base version (for example MySQL 5.5 -> [MariaDB 5.5](../what-is-mariadb-55/index), MySQL 5.6 -> [MariaDB 10.0](../what-is-mariadb-100/index) and MySQL 5.7 -> [MariaDB 10.2](../what-is-mariadb-102/index)) you can in most cases just uninstall MySQL and install MariaDB and you are good to go. There is no need to dump and restore databases. As with any upgrade, we recommend making a backup of your data beforehand.
* You should run [mariadb-upgrade](../mariadb-upgrade/index) (as you would with `mysql_upgrade` in MySQL) to finish the upgrade. This is needed to ensure that your mysql privilege and event tables are updated with the new fields MariaDB uses. Note that if you use a MariaDB package, `mariadb-upgrade` is usually run automatically.
* All your old clients and connectors (PHP, Perl, Python, Java, etc.) will work unchanged (no need to recompile). This works because MariaDB and MySQL use the same client protocol and the client libraries are binary compatible. You can also use your old MySQL connector packages with MariaDB if you want.

 [Upgrading on Windows](../upgrading-mariadb-on-windows/index)
-------------------------------------------------------------

 On Windows, you should not uninstall MySQL and install MariaDB, this would not work, the existing database will not be found.

 Thus On Windows, just install MariaDB and use the upgrade wizard which is part of installer package and is launched by MSI installer. Or, in case you prefer command line, use `mysql_upgrade_service <service_name>` on the command line.

 Upgrading my.cnf
----------------

 All the options in your original MySQL [`my.cnf` file](../mysqld-configuration-files-and-groups/index) should work fine for MariaDB.

 However as MariaDB has more features than MySQL, there is a few things that you should consider changing in your `my.cnf` file.

 * MariaDB uses by default the [Aria storage engine](../aria-storage-engine/index) for internal temporary files instead of MyISAM. If you have a lot of temporary files, you should add and set `[aria-pagecache-buffer-size](../aria-system-variables/index#aria_pagecache_buffer_size)` to the same value as you have for `[key-buffer-size](../myisam-system-variables/index#key_buffer_size)`.
* If you don't use MyISAM tables, you can set `[key-buffer-size](../myisam-system-variables/index#key_buffer_size)` to a very low value, like 64K.
* If using [MariaDB 10.1](../what-is-mariadb-101/index) or earlier, and your applications often connect and disconnect to MariaDB, you should set up `[thread-cache-size](../server-system-variables/index#thread_cache_size)` to the number of concurrent queries threads you are typically running. This is important in MariaDB as we are using the [jemalloc](http://www.canonware.com/jemalloc/) memory allocator. [jemalloc](http://www.canonware.com/jemalloc/) usually has better performance when running many threads compared to other memory allocators, except if you create and destroy a lot of threads, in which case it will spend a lot of resources trying to manage thread specific storage. Having a thread cache will fix this problem.
* If you have a LOT of connections (> 100) that mostly run short running queries, you should consider using the [thread pool](../threadpool-in-55/index). For example using : `[thread\_handling=pool-of-threads](../server-system-variables/index#thread_handling)` and `[thread\_pool\_size=128](../server-system-variables/index#thread_pool_size)` could give a notable performance boost in this case. Where the `thread_pool_size` should be about `2 * number of cores on your machine`.

 Other Things to Think About
---------------------------

 * Views with definition `ALGORITHM=MERGE` or `ALGORITHM=TEMPTABLE` got accidentally swapped between MariaDB and MySQL. You have to re-create views created with either of these definitions (see [MDEV-6916](https://jira.mariadb.org/browse/MDEV-6916)).
* MariaDB has LGPL versions of the [C connector](../client-library-for-c/index) and [Java Client](../mariadb-java-client/index). If you are shipping an application that supports MariaDB or MySQL, you should consider using these!
* You should consider trying out the [MyRocks storage engine](../myrocks/index) or some of the other [new storage engines](../mariadb-storage-engines/index) that MariaDB provides.

 See Also
--------

 * MariaDB has a lot of [new features](../mariadb-vs-mysql-features/index) that you should know about.
* [MariaDB versus MySQL - Compatibility](../mariadb-vs-mysql-compatibility/index)
* [Migrating to MariaDB](../migrating-to-mariadb/index)
* You can find general upgrading informations on the [MariaDB installation page](../getting-installing-and-upgrading-mariadb/index).
* There is a [Screencast for upgrading MySQL to MariaDB](../screencast-for-upgrading-mysql-to-mariadb/index).
* [Upgrading to MariaDB in Debian 9](../moving-from-mysql-to-mariadb-in-debian-9/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mysql-to-mariadb/>

Upgrading from MariaDB 10.1 to MariaDB 10.2
===========================================

    ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster](../upgrading-from-mariadb-101-to-mariadb-102-with-galera-cluster/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Mariabackup](../mariabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.2](../what-is-mariadb-102/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
	* This step is not necessary when upgrading to [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/) or later. Omitting it can make the upgrade process far faster. See [MDEV-12289](https://jira.mariadb.org/browse/MDEV-12289) for more information.
3. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
4. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
5. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
6. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
7. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
8. Run `[mysql\_upgrade](../mysql_upgrade/index)`.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.1 and 10.2

 On most servers upgrading from 10.1 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### InnoDB Instead of XtraDB

 [MariaDB 10.2](../what-is-mariadb-102/index) uses [InnoDB](../innodb/index) as the default storage engine, rather than XtraDB, used in [MariaDB 10.1](../what-is-mariadb-101/index) and before. See [Why does MariaDB 10.2 use InnoDB instead of XtraDB?](../why-does-mariadb-102-use-innodb-instead-of-xtradb/index) In most cases this should have minimal effect as the latest InnoDB has incorporated most of the improvements made in earlier versions of XtraDB. Note that certain [XtraDB system variables](../xtradbinnodb-server-system-variables/index) are now ignored (although they still exist so as to permit easy upgrading).

 #### Options That Have Changed Default Values

 In particular, take note of the changes to [innodb\_strict\_mode](../xtradbinnodb-server-system-variables/index#innodb_strict_mode), [sql\_mode](../server-system-variables/index#sql_mode), [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format), [binlog\_checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum) and [innodb\_checksum\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_checksum_algorithm).

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [aria\_recover(\_options)](../aria-system-variables/index#aria_recover_options) | NORMAL | BACKUP, QUICK |
| [binlog\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#binlog_annotate_row_events) | OFF | ON |
| [binlog\_checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum) | NONE | CRC32 |
| [binlog\_format](../replication-and-binary-log-server-system-variables/index#binlog_format) | STATEMENT | MIXED |
| [group\_concat\_max\_len](../server-system-variables/index#group_concat_max_len) | 1024 | 1048576 |
| [innodb\_autoinc\_lock\_mode](../xtradbinnodb-server-system-variables/index#innodb_autoinc_lock_mode) | 1 | 2 |
| [innodb\_buffer\_pool\_dump\_at\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_dump_at_shutdown) | OFF | ON |
| [innodb\_buffer\_pool\_dump\_pct](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_dump_pct) | 100 | 25 |
| [innodb\_buffer\_pool\_instances](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_instances) | 8 | Varies |
| [innodb\_buffer\_pool\_load\_at\_startup](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_load_at_startup) | OFF | ON |
| [innodb\_checksum\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_checksum_algorithm) | innodb | crc32 |
| [innodb\_file\_format](../xtradbinnodb-server-system-variables/index#innodb_file_format) | Antelope | Barracuda |
| [innodb\_large\_prefix](../xtradbinnodb-server-system-variables/index#innodb_large_prefix) | OFF | ON |
| [innodb\_lock\_schedule\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_lock_schedule_algorithm) | VATS | FCFS |
| [innodb\_log\_compressed\_pages](../xtradbinnodb-server-system-variables/index#innodb_log_compressed_pages) | OFF | ON |
| [innodb\_max\_dirty\_pages\_pct\_lwm](../xtradbinnodb-server-system-variables/index#innodb_max_dirty_pages_pct_lwm) | 0.001000 | 0 |
| [innodb\_max\_undo\_log\_size](../xtradbinnodb-server-system-variables/index#innodb_max_undo_log_size) | 1073741824 | 10485760 |
| [innodb\_purge\_threads](../xtradbinnodb-server-system-variables/index#innodb_purge_threads) | 1 | 4 |
| [innodb\_strict\_mode](../xtradbinnodb-server-system-variables/index#innodb_strict_mode) | OFF | ON |
| [innodb\_undo\_directory](../xtradbinnodb-server-system-variables/index#innodb_undo_directory) | . | NULL |
| [innodb\_use\_atomic\_writes](../xtradbinnodb-server-system-variables/index#innodb_use_atomic_writes) | OFF | ON |
| [innodb\_use\_trim](../xtradbinnodb-server-system-variables/index#innodb_use_trim) | OFF | ON |
| [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) | 31536000 | 86400 |
| [log\_slow\_admin\_statements](../server-system-variables/index#log_slow_admin_statements) | OFF | ON |
| [log\_slow\_slave\_statements](../replication-and-binary-log-server-system-variables/index#log_slow_slave_statements) | OFF | ON |
| [log\_warnings](../server-system-variables/index#log_warnings) | 1 | 2 |
| [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) | 4M | 16M |
| [max\_long\_data\_size](../server-system-variables/index#max_long_data_size) | 4M | 16M |
| [myisam\_recover\_options](../myisam-system-variables/index#myisam_recover_options) | NORMAL | BACKUP, QUICK |
| [optimizer\_switch](../server-system-variables/index#optimizer_switch) | See [Optimizer Switch](../optimizer_switch/index) for details. |
| [replicate\_annotate\_row\_events](../replication-and-binary-log-server-system-variables/index#replicate_annotate_row_events) | OFF | ON |
| [server\_id](../replication-and-binary-log-server-system-variables/index#server_id) | 0 | 1 |
| [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) | 3600 | 60 |
| [sql\_mode](../server-system-variables/index#sql_mode) | NO\_AUTO\_CREATE\_USER, NO\_ENGINE\_SUBSTITUTION | STRICT\_TRANS\_TABLES, ERROR\_FOR\_DIVISION\_BY\_ZERO, NO\_AUTO\_CREATE\_USER, NO\_ENGINE\_SUBSTITUTION |
| [thread\_cache\_size](../server-system-variables/index#thread_cache_size) | 0 | Auto |
| [thread\_pool\_max\_threads](../thread-pool-system-and-status-variables/index) | 1000 | 65536 |
| [thread\_stack](../server-system-variables/index#thread_stack) | 295936 | 299008 |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your [option files](../configuring-mariadb-with-option-files/index):

 


| Option | Reason |
| --- | --- |
| aria\_recover | Renamed to [aria\_recover\_options](../aria-system-variables/index#aria_recover_options) to match [myisam\_recover\_options](../myisam-system-variables/index#myisam_recover_options). |
| [innodb\_additional\_mem\_pool\_size](../xtradbinnodb-server-system-variables/index#innodb_additional_mem_pool_size) | Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index). |
| [innodb\_api\_bk\_commit\_interval](../xtradbinnodb-server-system-variables/index#innodb_api_bk_commit_interval) | Memcache never implemented in MariaDB. |
| [innodb\_api\_disable\_rowlock](../xtradbinnodb-server-system-variables/index#innodb_api_disable_rowlock) | Memcache never implemented in MariaDB. |
| [innodb\_api\_enable\_binlog](../xtradbinnodb-server-system-variables/index#innodb_api_enable_binlog) | Memcache never implemented in MariaDB. |
| [innodb\_api\_enable\_mdl](../xtradbinnodb-server-system-variables/index#innodb_api_enable_mdl) | Memcache never implemented in MariaDB. |
| [|innodb\_api\_trx\_level](../xtradbinnodb-server-system-variables/index#innodb_api_trx_level) | Memcache never implemented in MariaDB. |
| [innodb\_use\_sys\_malloc](../xtradbinnodb-server-system-variables/index#innodb_use_sys_malloc) | Deprecated in [MariaDB 10.0](../what-is-mariadb-100/index). |

 
#### Reserved Words

 New [reserved words](../reserved-words/index): OVER, RECURSIVE and ROWS. These can no longer be used as [identifiers](../identifier-names/index) without being quoted.

 #### TokuDB

 [TokuDB](../tokudb/index) has been split into a separate package, mariadb-plugin-tokudb.

 #### Replication

 [Replication](../standard-replication/index) from legacy MySQL servers may require setting [binlog\_checksum](../replication-and-binary-log-server-system-variables/index#binlog_checksum) to NONE. 

 #### SQL Mode

 [SQL\_MODE](../sql_mode/index) has been changed; in particular, NOT NULL fields with no default will no longer fall back to a dummy value for inserts which do not specify a value for that field.

 #### Auto\_increment

 [Auto\_increment](../auto_increment/index) columns are no longer permitted in [CHECK constraints](../constraint/index), [DEFAULT value expressions](../create-table/index#default) and [virtual columns](../virtual-computed-columns/index). They were permitted in earlier versions, but did not work correctly.

 #### TLS

 Starting with [MariaDB 10.2](../what-is-mariadb-102/index), when the user specifies the `--ssl` option with a [client or utility](../clients-utilities/index), the [client or utility](../clients-utilities/index) will not [verify the server certificate](../secure-connections-overview/index#server-certificate-verification) by default. In order to verify the server certificate, the user must specify the `--ssl-verify-server-cert` option to the [client or utility](../clients-utilities/index). For more information, see the [list of options](../mysql-command-line-client/index#options) for the `[mysql](../mysql-command-line-client/index)` client.

 ### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.2](../what-is-mariadb-102/index):

 * [Window Functions](../window-functions/index)
* [mysqlbinlog](../mysqlbinlog/index) now supports continuous binary log backups
* [Recursive Common Table Expressions](../recursive-common-table-expressions-overview/index)
* [JSON functions](../json-functions/index)
* See also [System Variables Added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index).

 ### See Also

 * [The features in MariaDB 10.2](../what-is-mariadb-102/index)
* [Upgrading from MariaDB 10.1 to MariaDB 10.2 with Galera Cluster](../upgrading-from-mariadb-101-to-mariadb-102-with-galera-cluster/index)
* [Upgrading from MariaDB 10.0 to MariaDB 10.1](../upgrading-from-mariadb-100-to-mariadb-101/index)
* [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-101-to-mariadb-102/>

Optimizer Trace
================

  

| Title | Description |
| --- | --- |
|  [Optimizer Trace Overview](../optimizer-trace-overview/index) |  Produces a JSON trace with decision info taken by the optimizer during the optimization phase.  |
|  [Optimizer Trace Guide](../optimizer-trace-guide/index) |  Guide to the structured log file showing what actions were taken by the query optimizer.  |
|  [Basic Optimizer Trace Example](../basic-optimizer-trace-example/index) |  MariaDB> set optimizer\_trace=’enabled=on’; MariaDB> select \* from t1 where a<10; MariaDB> s  |
|  [How to Collect Large Optimizer Traces](../how-to-collect-large-optimizer-traces/index) |  Steps for collecting large optimizer traces.  |
|  [Optimizer Trace for Developers](../optimizer-trace-for-developers/index) |  This article describes guidelines for what/how to write to Optimizer Trace ...  |
|  [Optimizer Trace Resources](../optimizer-trace-resources/index) |  Optimizer Trace Walkthrough talk at MariaDB Fest 2020: https://mariadb.org/...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-internals-documentation-optimizer-trace/>

Screencast for Upgrading MySQL to MariaDB
=========================================

    There is a [screencast](http://www.youtube.com/watch?v=rF7wChx0uzQ) for upgrading from MySQL 5.1.55 to MariaDB. Watch this example to see how easy this process is. It really is just a "drop in replacement" to MySQL.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/screencast-for-upgrading-mysql-to-mariadb/>

Upgrading from MySQL 5.7 to MariaDB 10.2
========================================

    Following compatibility report was done on 10.2.4 and may get some fixing in next minor releases 

 * MySQL unix socket plugin can be different. MariaDB can get similar usage via INSTALL PLUGIN unix\_socket SONAME 'auth\_socket.so'; you may have to enable this plugin in config files via load plugin.

 * When using data type JSON , one should convert type to TEXT, virtual generated column works the same after.

 * When using InnoDB FULLTEXT index one should not use innodb\_defragment

 * MySQL re-implemented partitioning in 5.7, thus you cannot perform in-place upgrades for partitioned tables. They will require mysqldump/import to work correctly in MariaDB.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mysql-57-to-mariadb-102/>

System Variables Added in MariaDB 10.8
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.8](../what-is-mariadb-108/index) series.

 


| Variable | Added |
| --- | --- |
| [binlog\_alter\_two\_phase](../replication-and-binary-log-system-variables/index#binlog_alter_two_phase) | [MariaDB 10.8.1](https://mariadb.com/kb/en/mariadb-1081-release-notes/) |
| [innodb\_log\_file\_buffering](../innodb-system-variables/index#innodb_log_file_buffering) | [MariaDB 10.8.4](https://mariadb.com/kb/en/mariadb-1084-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.6](../system-variables-added-in-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-10-8/>

Orchestrator Overview
=====================

    Orchestrator is a MySQL and MariaDB high availability and replication management tool. It is released by Shlomi Noach under the terms of the Apache License, version 2.0.

 Orchestrator provides automation for MariaDB replication in the following ways:

 * It can be used to perform certain operations, like repairing broken replication or moving a replica from one master to another. These operations can be requested using CLI commands, or via the GUI provided with Orchestrator. The actual commands sent to MariaDB are automated by Orchestrator, and the user doesn't have to worry about the details.
* Orchestrator can also automatically perform a failover in case a master crashes or is unreachable by its replicas. If that is the case, Orchestrator will promote one of the replicas to a master. The replica to promote is chosen based on several criteria, like the server versions, the [binary log](../binary-log/index) formats in use and the datacenters locations.

 Note that, if we don't want to use Orchestrator to automate operations, we can still use it as a dynamic inventory. Other tools can use it to obtain a list of existing MariaDB servers via its REST API or CLI commands.

 Orchestrator has several big users, listed in the documentation [Users](https://github.com/openark/orchestrator/blob/master/docs/users.md) page. It is also included in the PMM monitoring solution.

 To install Orchestrator, see:

 * The [install.md](https://github.com/openark/orchestrator/blob/master/docs/install.md) for a manual installation;
* The links in [README.md](https://github.com/openark/orchestrator/blob/master/README.md), to install Orchestrator using automation tools.

 Supported Topologies
--------------------

 Currently, Orchestrator fully supports MariaDB [GTID](../gtid/index), [replication](../replication/index), and [semi-synchronous replication](../semisynchronous-replication/index). While Orchestrator does not support Galera specific logic, it works with Galera clusters. For details, see [Supported Topologies and Versions](https://github.com/openark/orchestrator/blob/master/docs/supported-topologies-and-versions.md) in Orchestrator documentation.

 Architecture
------------

 Orchestrator consists of a single executable called `orchestrator`. This is a process that periodically connects to the target servers. It will run SQL queries against target servers, so it needs a user with proper permissions. When the process is running, a GUI is available via a web browser, at the URL '[https://localhost:3000'](#). It also exposes a REST API (see [Using the web API](https://github.com/openark/orchestrator/blob/master/docs/using-the-web-api.md) in the Orchestrator documentation).

 Orchestrator expects to find a JSON configuration file called `orchestrator.conf.json`, in `/etc`.

 A database is used to store the configuration and the state of the target servers. By default, this is done using built-in SQLite. However, it is possible to use an external MariaDB or MySQL server instance.

 If a cluster of Orchestrator instances is running, only one central database is used. One Orchestrator node is active, while the others are passive and are only used for failover. If the active node crashes or becomes unreachable, one of the other nodes becomes the active instance. The `active_node` table shows which node is active. Nodes communicate between them using the Raft protocol.

 CLI Examples
------------

 As mentioned, Orchestrator can be used from the command-line. Here you can find some examples.

 List clusters:

 
```
orchestrator -c clusters

```

Discover a specified instance and add it to the known topology:

 
```
orchestrator -c discover -i <host>:<port>

```

Forget about an instance:

 
```
orchestrator -c topology -i <host>:<port>

```

Move a replica to a different master:

 
```
orchestrator -c move-up -i <replica-host>:<replica-port> -d <master-host>:<master-port>

```

Move a replica up, so that it becomes a "sibling" of its master:

 
```
orchestrator -c move-up -i <replica-host>:<replica-port>

```

Move a replica down, so that it becomes a replica of its"sibling":

 
```
orchestrator -c move-below -i <replica-host>:<replica-port> -d <master-host>:<master-port>

```

Make a node read-only:

 
```
orchestrator -c set-read-only -i <host>:<port>

```

Make a node writeable:

 
```
orchestrator -c set-writeable -i <host>:<port>

```

The `--debug` and `--stack` options can be added to the above commands to make them more verbose.

 Orchestrator Resources and References
-------------------------------------

 * [Orchestrator on GitHub](https://github.com/openark/orchestrator).
* [Documentation](https://github.com/openark/orchestrator/tree/master/docs).
* [Raft consensus protocol website](https://raft.github.io/).

 The [README.md](https://github.com/openark/orchestrator/blob/master/README.md) file lists some related community projects, including modules to automate Orchestrator with [Puppet](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index) and other technologies.

 On GitHub you can also find links to projects that allow the use of automation software to deploy and manage Orchestrator.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/orchestrator-overview/>

HashiCorp Vault and MariaDB
===========================

    Vault is open source software for secret management provided by HashiCorp. It is designed to avoid sharing secrets of various types, like passwords and private keys. When building automation, Vault is a good solution to avoid storing secrets in plain text in a repository.

 MariaDB and Vault may relate to each other in several ways:

 * MariaDB has a [Hashicorp Key Management plugin](../hashicorp-key-management-plugin/index), to manage and rotate SSH keys.
* Users passwords can be stored in Vault.
* MariaDB (and MySQL) can be used as a secret engine, a component which stores, generates, or encrypts data.
* MariaDB (and MySQL) can be used as a backend storage, providing durability for Vault data.

 For information about how to install Vault, see [Install Vault](https://www.vaultproject.io/docs/install), as well as [MySQL/MariaDB Database Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/databases/mysql-maria).

 Vault Features
--------------

 Vault is used via an HTTP/HTTPS API.

 Vault is identity-based. Users login and Vault sends them a token that is valid for a certain amount of time, or until certain conditions occur. Users with a valid token may request to obtain secrets for which they have proper permissions.

 Vault encrypts the secrets it stores.

 Vault can optionally audit changes to secrets and secrets requests by the users.

 Vault Architecture
------------------

 Vault is a server. This allows decoupling the secrets management logic from the clients, which only need to login and keep a token until it expires.

 The sever can actually be a cluster of servers, to implement high availability.

 The main Vault components are:

 * **Storage Backed**: This is where the secrets are stored. Vault only send encrypted data to the backend storage.
* **HTTP API**: This API is used by the clients, and provides an access to Vault server.
* **Barrier**: Similarly to an actual barrier, it protects all inner Vault components. The HTTP API and the storage backend are outside of the barrier and could be accessed by anyone. All communications from and to these components have to pass through the barrier. The barrier verifies data and encrypts it. The barrier can have two states: *sealed* or *unsealed*. Data can only pass through when the barrier is unsealed. All the following components are located inside the barrier.
* **Auth Method**: Handles login attempts from clients. When a login succeeds, the auth method returns a list of security policies to Vault core.
* **Token Store**: Here the tokens generated as a result of a succeeded login are stored.
* **Secrets Engines**: These components manage secrets. They can have different levels of complexity. Some of them simply expect to receive a key, and return the corresponding secret. Others may generate secrets, including one-time-passwords.
* **Audit Devices**: These components log the requests received by Vault and the responses sent back to the clients.There may be multiple devices, in which case an **Audit Broker** sends the request or response to the proper device.

 Dev Mode
--------

 It is possible to start Vault in dev mode:

 
```
vault server -dev

```

Dev mode is useful for learning Vault, or running experiments on some particular features. It is extremely insecure, because dev mode is equivalent to starting Vault with several insecure options. This means that Vault should never run in production in dev mode. However, this also means that all the regular Vault features are available in dev mode.

 Dev mode simplifies all operations. Actually, no configuration is necessary to get Vault up and running in dev mode. It makes it possible to communicate with the Vault API from the shell without any authentication. Data is stored in memory by default. Vault is unsealed by default, and if explicitly sealed, it can be unsealed using only one key.

 For more details, see ["Dev" Server Mode](https://www.vaultproject.io/docs/concepts/dev-server) in Vault documentation.

 Vault Resources and References
------------------------------

 * [Documentation](https://www.vaultproject.io/docs).
* [MySQL/MariaDB Database Secrets Engine](https://www.vaultproject.io/docs/secrets/databases/mysql-maria).
* [MySQL Storage Backend](https://www.vaultproject.io/docs/configuration/storage/mysql).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hashicorp-vault-and-mariadb/>

System Variables Added in MariaDB 10.6
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.6](../what-is-mariadb-106/index) series. The list does not include variables that are not part of the default release.

 


| Variable | Added |
| --- | --- |
| [binlog\_expire\_logs\_seconds](../replication-and-binary-log-system-variables/index#binlog_expire_logs_seconds) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| [innodb\_deadlock\_report](../innodb-system-variables/index#innodb_deadlock_report) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| [innodb\_read\_only\_compressed](../innodb-system-variables/index#innodb_read_only_compressed) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| [wsrep\_mode](../galera-cluster-system-variables/index#wsrep_mode) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.6](../status-variables-added-in-mariadb-106/index)
* [System Variables Added in MariaDB 10.5](../system-variables-added-in-mariadb-104/index)
* [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-106/>

System Variables Added in MariaDB 10.4
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.4](../what-is-mariadb-104/index) series. The list does not include variables that are not part of the default release.

 


| Variable | Added |
| --- | --- |
| [analyze\_sample\_percentage](../server-system-variables/index#analyze_sample_percentage) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [disconnect\_on\_expired\_password](../server-system-variables/index#disconnect_on_expired_password) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [gtid\_cleanup\_batch\_size](../gtid/index#gtid_cleanup_batch_size) | [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/) |
| [innodb\_encrypt\_temporary\_ables](../xtradbinnodb-server-system-variables/index#innodb_encrypt_temporary_tables) | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) |
| [innodb\_instant\_alter\_column\_allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed) | [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/) |
| [max\_password\_errors](../server-system-variables/index#max_password_errors) | [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) |
| [optimizer\_trace](../server-system-variables/index#optimizer_trace) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [optimizer\_trace\_max\_mem\_size](../server-system-variables/index#optimizer_trace_max_mem_size) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [tcp\_nodelay](../server-system-variables/index#tcp_nodelay) | [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/) |
| [tls\_version](../ssltls-system-variables/index#tls_version) | [MariaDB 10.4.6](https://mariadb.com/kb/en/mariadb-1046-release-notes/) |
| [wsrep\_certification\_rules](../galera-cluster-system-variables/index#wsrep_certification_rules) | [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) |
| [wsrep\_trx\_fragment\_size](../galera-cluster-system-variables/index#wsrep_trx_fragment_size) | [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) |
| [wsrep\_trx\_fragment\_unit](../galera-cluster-system-variables/index#wsrep_trx_fragment_unit) | [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.4](../status-variables-added-in-mariadb-104/index)
* [System Variables Added in MariaDB 10.5](../system-variables-added-in-mariadb-105/index)
* [System Variables Added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index)
* [System Variables Added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-104/>

Percona XtraBackup Build Instructions
=====================================

    
In [MariaDB 10.1](../what-is-mariadb-101/index) and later, [Mariabackup](../mariabackup/index) is the recommended backup method to use instead of Percona XtraBackup.

 

In [MariaDB 10.3](../what-is-mariadb-103/index), Percona XtraBackup is **not supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 

In [MariaDB 10.2](../what-is-mariadb-102/index) and [MariaDB 10.1](../what-is-mariadb-101/index), Percona XtraBackup is only **partially supported**. See [Percona XtraBackup Overview: Compatibility with MariaDB](../percona-xtrabackup-overview/index#compatibility-with-mariadb) for more information.

 
 Build instructions for [Percona XtraBackup](../percona-xtrabackup/index).

 Solaris 10 (SunOS 5.10) notes:

 Edit utils/build.sh and add -lrt -m64 to CFLAGS and CXXFLAGS.

 Make sure that you're using GNU utils for building, including make, cmake, gcc, gawk, getopt, autotools, libtool, automake, autoconf and bazaar.

 If you want to change MySQL version which to build against with edit one of the following lines:

 MYSQL\_51\_VERSION=...

 MYSQL\_55\_VERSION=...

 PS\_51\_VERSION=...

 PS\_55\_VERSION=..

 When ready run one of the following depending on the MySQL version which you want to build with:

 AUTO\_DOWNLOAD="yes" ./utils/build.sh xtradb (build against XtraDB 5.1)

 AUTO\_DOWNLOAD="yes" ./utils/build.sh innodb51\_builtin (build against built-in InnoDB in MySQL 5.1)

 AUTO\_DOWNLOAD="yes" ./utils/build.sh xtradb55 (build against XtraDB 5.5)

 AUTO\_DOWNLOAD="yes" ./utils/build.sh innodb55 (build against InnoDB in MySQL 5.5)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/percona-xtrabackup-build-instructions/>

Installing MariaDB .deb Files with Ansible
==========================================

    This page refers to the operations described in [Installing MariaDB .deb Files](../installing-mariadb-deb-files/index). Refer to that page for a complete list and explanation of the tasks that should be performed.

 Here we discuss how to automate such tasks using Ansible. For example, here we show how to install a package or how to import a GPG key; but for an updated list of the necessary packages and for the keyserver to use, you should refer to [Installing MariaDB .deb Files](../installing-mariadb-deb-files/index).

 Adding apt Repositories
-----------------------

 To [add a repository](../installing-mariadb-deb-files/index#executing-add-apt-repository):

 
```
- name: Add specified repository into sources list
  ansible.builtin.apt_repository:
    repo: deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main
    state: present

```

If you prefer to keep the repository information in a [source list file](../installing-mariadb-deb-files/index#creating-a-source-list-file) in the Ansible repository, you can upload that file to the target hosts in this way:

 
```
- name: Create a symbolic link
  ansible.builtin.file:
    src: ./file/mariadb.list
    dest: /etc/apt/sources.list.d/
    owner: root
    group: root
    mod: 644
    state: file

```

Updating the Repository Cache
-----------------------------

 Both the Ansible modules [ansible.builtin.apt](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html) and [ansible.builtin.apt\_repository](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_repository_module.html) have an `update_cache` attribute. In ansible.builtin.apt it is set to "no" by default. Whenever a task sets it to 'yes', `apt-get update` is run on the target system. You have three ways to make sure that repositories are updated.

 The first is to use ansible.builtin.apt\_repository to add the desired repository, as shown above. So you only need to worry about updating repositories if you use the file method.

 The second is to make sure that `update_cache` is set to 'yes' when you install a repository:

 
```
- name: Install foo
  apt:
    name: foo
    update_cache: yes

```

But if you run certain tasks conditionally, this option may not be very convenient. So the third option is to update the repository cache explicitly as a separate task:

 
```
- name: Update repositories
  apt:
    - update_cache: yes

```

Importing MariaDB GPG Key
-------------------------

 To [import the GPG key](../installing-mariadb-deb-files/index#importing-the-mariadb-gpg-public-key) for MariaDB we can use the [ansible.builtin.apt\_key](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_key_module.html) Ansible module. For example:

 
```
- name: Add an apt key by id from a keyserver
  ansible.builtin.apt_key:
    keyserver: hkp://keyserver.ubuntu.com:80
    id: 0xF1656F24C74CD1D8

```

Installing Packages
-------------------

 To install Deb packages into a system:

 
```
- name: Install software-properties-common
  apt:
    name: software-properties-common
    state: present

```

To make sure that a specific version is installed, performing an upgrade or a downgrade if necessary:

 
```
- name: Install foo 1.0
  apt:
    name: foo=1.0

```

To install a package or upgrade it to the latest version, use: `state: latest`.

 To install multiple packages at once:

 
```
- name: Install the necessary packages
  apt:
    pkg:
    - pkg1
    - pkg2=1.0

```

If all your servers run on the same system, you will always use ansible.builtin.apt and the names and versions of the packages will be the same for all servers. But suppose you have some servers running systems from the Debian family, and others running systems from the Red Hat family. In this case, you may find convenient to use two different task files for two different types of systems. To include the proper file for the target host's system:

 
```
- include: mariadb-debian.yml
  when: "{{ ansible_facts['os_family'] }} == 'Debian'

```

The variables you can use to run the tasks related to the proper system are:

 * [ansible\_fact['distribution']](https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#ansible-facts-distribution)
* [ansible\_fact['distribution\_major\_version']](https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#ansible-facts-distribution-major-version)
* [ansible\_fact['os\_family']](https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html#ansible-facts-os-family)

 There is also a system-independent [package module](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html), but if the package names depend on the target system using it may be of very little benefit.

 See Also
--------

 * [Installing MariaDB .deb Files](../installing-mariadb-deb-files/index)

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-mariadb-deb-files-with-ansible/>

Upgrading from MariaDB 5.5 to MariaDB 10.0
==========================================

    What You Need to Know
---------------------

 There are no changes in table or index formats between [MariaDB 5.5](../what-is-mariadb-55/index) and [MariaDB 10.0](../what-is-mariadb-100/index), so on most servers the upgrade should be painless.

 ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0](../upgrading-from-mariadb-galera-cluster-55-to-mariadb-galera-cluster-100/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.0](../what-is-mariadb-100/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
3. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
4. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
5. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
6. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
7. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
8. Run `[mysql\_upgrade](../mysql_upgrade/index)`.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 5.5 and 10.0

 As mentioned previously, on most servers upgrading from 5.5 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Options That Have Changed Default Values

 Most of the following options have increased a bit in value to give better performance. They should not use much additional memory, but some of them a do use a bit more disk space. [[1](#_note-0)]

 


| Option | Old default value | New default value |
| --- | --- | --- |
| `[aria-sort-buffer-size](../aria-system-variables/index#aria_sort_buffer_size)` | `128M` | `256M` |
| `[back\_log](../server-system-variables/index#back_log)` | `50` | `150` |
| `[innodb-buffer-pool-instances](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_instances)` | `1` | `8` (except on 32-bit Windows) |
| `[innodb-concurrency-tickets](../xtradbinnodb-server-system-variables/index#innodb_concurrency_tickets)` | `500` | `5000` |
| `[innodb-log-file-size](../xtradbinnodb-server-system-variables/index#innodb_log_file_size)` | `5M` | `48M` |
| `[innodb-old-blocks-time](../xtradbinnodb-server-system-variables/index#innodb_old_blocks_time)` | `0` | `1000` |
| `[innodb-open-files](../xtradbinnodb-server-system-variables/index#innodb_open_files)` | `300` | `400` [[2]](#_note-1) |
| `[innodb-purge-batch-size](../xtradbinnodb-server-system-variables/index#innodb_purge_batch_size)` | `20` | `300` |
| `[innodb-undo-logs](../xtradbinnodb-server-system-variables/index#innodb_undo_logs)` | `ON` | `20` |
| `[max-connect-errors](../server-system-variables/index#max_connect_errors)` | `10` | `100` |
| `[max-relay-log-size](../server-system-variables/index#max_relay_log_size)` | `0` | `1024M` |
| `[myisam-sort-buffer-size](../myisam-server-system-variables/index#myisam_sort_buffer_size)` | `8M` | `128M` |
| `[optimizer-switch](../server-system-variables/index#optimizer_switch)` | ... | Added `extended_keys=on, exists_to_in=on` |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your config files:

 


| Option | Reason |
| --- | --- |
| `engine-condition-pushdown` | Replaced with `[set optimizer\_switch='engine\_condition\_pushdown=on'](../index-condition-pushdown/index)` |
| `innodb-adaptive-flushing-method` | Removed by [XtraDB](../xtradb/index) |
| `innodb-autoextend-increment` | Removed by [XtraDB](../xtradb/index) |
| `innodb-blocking-buffer-pool-restore` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages-blob` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-pages-index` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-restore-at-startup` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-shm-checksum` | Removed by [XtraDB](../xtradb/index) |
| `innodb-buffer-pool-shm-key` | Removed by [XtraDB](../xtradb/index) |
| `innodb-checkpoint-age-target` | Removed by [XtraDB](../xtradb/index) |
| `innodb-dict-size-limit` | Removed by [XtraDB](../xtradb/index) |
| `innodb-doublewrite-file` | Removed by [XtraDB](../xtradb/index) |
| `innodb-fast-checksum` | Renamed to [innodb-checksum-algorithm](../xtradbinnodb-server-system-variables/index#innodb_checksum_algorithm) |
| `innodb-flush-neighbor-pages` | Renamed to [innodb-flush-neighbors](../xtradbinnodb-server-system-variables/index#innodb_flush_neighbors) |
| `innodb-ibuf-accel-rate` | Removed by [XtraDB](../xtradb/index) |
| `innodb-ibuf-active-contract` | Removed by [XtraDB](../xtradb/index) |
| `innodb-ibuf-max-size` | Removed by [XtraDB](../xtradb/index) |
| `innodb-import-table-from-xtrabackup` | Removed by [XtraDB](../xtradb/index) |
| `innodb-index-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-lazy-drop-table` | Removed by [XtraDB](../xtradb/index) |
| `innodb-merge-sort-block-size` | Removed by [XtraDB](../xtradb/index) |
| `innodb-persistent-stats-root-page` | Removed by [XtraDB](../xtradb/index) |
| `innodb-read-ahead` | Removed by [XtraDB](../xtradb/index) |
| `innodb-recovery-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-recovery-update-relay-log` | Removed by [XtraDB](../xtradb/index) |
| `innodb-stats-auto-update` | Renamed to `innodb-stats-auto-recalc` |
| `innodb-stats-update-need-lock` | Removed by [XtraDB](../xtradb/index) |
| `innodb-sys-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-table-stats` | Removed by [XtraDB](../xtradb/index) |
| `innodb-thread-concurrency-timer-based` | Removed by [XtraDB](../xtradb/index) |
| `innodb-use-sys-stats-table` | Removed by [XtraDB](../xtradb/index) |
| `xtradb-admin-command` | Removed by [XtraDB](../xtradb/index) |

 
#### Reserved Words

 New reserved word: RETURNING. This can no longer be used as an identifier without being quoted.

 #### Other

 The `SET OPTION` syntax is deprecated in [MariaDB 10.0](../what-is-mariadb-100/index). Use `[SET](../set/index)` instead.

 ### New Major Features To Consider

 You should consider using the following new major features in [MariaDB 10.0](../what-is-mariadb-100/index):

 #### For Master / Slave Setups

 * [Global transaction id](../global-transaction-id/index) is enabled by default. This makes it easier to change a slave to a master.
* [MariaDB 10.0](../what-is-mariadb-100/index) supports [parallel applying of queries on slaves](../parallel-replication/index). You can enable this with [slave-parallel-threads=#](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads). Note that this works only if your master is [MariaDB 10.0](../what-is-mariadb-100/index) or later.
* [Multi source replication](../multi-source-replication/index)

 #### Galera

 See [Upgrading from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0](../upgrading-from-mariadb-galera-cluster-55-to-mariadb-galera-cluster-100/index) for more details on [Galera](../what-is-mariadb-galera-cluster/index) upgrades.

 #### Variables

 * [System Variables Added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index)
* [Status Variables Added in MariaDB 10.0](../status-variables-added-in-mariadb-100/index)

 Notes
-----

 1. [↑](#_ref-0) The `innodb-open-files` variable defaults to the value of `table-open-cache` (`400` is the default) if it is set to any value less than `10` so long as `innodb-file-per-table` is set to `1` or `TRUE` (the default). If `innodb_file_per_table` is set to `0` or `FALSE` **and** `innodb-open-files` is set to a value less than `10`, the default is `300`

 See Also
--------

 * [The features in MariaDB 10.0](../what-is-mariadb-100/index)
* [Upgrading from MariaDB Galera Cluster 5.5 to MariaDB Galera Cluster 10.0](../upgrading-from-mariadb-galera-cluster-55-to-mariadb-galera-cluster-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-55-to-mariadb-100/>

System Variables Added in MariaDB 10.5
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.5](../what-is-mariadb-105/index) series. The list does not include variables that are not part of the default release.

 


| Variable | Added |
| --- | --- |
| [binlog\_row\_metadata](../replication-and-binary-log-system-variables/index#binlog_row_metadata) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [innodb\_instant\_alter\_column\_allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed) | [MariaDB 10.5.3](https://mariadb.com/kb/en/mariadb-1053-release-notes/) |
| [innodb\_lru\_flush\_size](../innodb-system-variables/index#innodb_lru_flush_size) | [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) |
| [innodb\_max\_purge\_lag\_wait](../innodb-system-variables/index#innodb_max_purge_lag_wait) | [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/) |
| [optimizer\_max\_sel\_arg\_weight](../server-system-variables/index#optimizer_max_sel_arg_weight) | [MariaDB 10.5.9](https://mariadb.com/kb/en/mariadb-1059-release-notes/) |
| [performance\_schema\_events\_transactions\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_long_size) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_events\_transactions\_history\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_size) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_index\_stat](../performance-schema-system-variables/index#performance_schema_max_index_stat) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_memory\_classes](../performance-schema-system-variables/index#performance_schema_max_memory_classes) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_metadata\_locks](../performance-schema-system-variables/index#performance_schema_max_metadata_locks) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_prepared\_statement\_instances](../performance-schema-system-variables/index#performance_schema_max_prepared_statement_instances) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_program\_instances](../performance-schema-system-variables/index#performance_schema_max_program_instances) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_sql\_text\_length](../performance-schema-system-variables/index#performance_schema_max_sql_text_length) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_statement\_stack](../performance-schema-system-variables/index#performance_schema_max_statement_stack) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_max\_table\_lock\_stat](../performance-schema-system-variables/index#performance_schema_max_table_lock_stat) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [require\_secure\_transport](../server-system-variables/index#require_secure_transport) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [s3\_access\_key](../s3-storage-engine-system-variables/index#s3_access_key) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_block\_size](../s3-storage-engine-system-variables/index#s3_block_size) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_bucket](../s3-storage-engine-system-variables/index#s3_bucket) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_debug](../s3-storage-engine-system-variables/index#s3_debug) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_host\_name](../s3-storage-engine-system-variables/index#s3_host_name) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_pagecache\_age\_threshold](../s3-storage-engine-system-variables/index#s3_pagecache_age_threshold) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_pagecache\_buffer\_size](../s3-storage-engine-system-variables/index#s3_pagecache_buffer_size) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_pagecache\_division\_limit](../s3-storage-engine-system-variables/index#s3_pagecache_division_limit) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_pagecache\_file\_hash\_size](../s3-storage-engine-system-variables/index#s3_pagecache_file_hash_size) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_protocol\_version](../s3-storage-engine-system-variables/index#s3_protocol_version) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_region](../s3-storage-engine-system-variables/index#s3_region) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [s3\_secret\_key](../s3-storage-engine-system-variables/index#s3_secret_key) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [sql\_if\_exists](../server-system-variables/index#sql_if_exists) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [thread\_pool\_exact\_stats](../thread-pool-system-status-variables/index#thread_pool_exact_stats) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.5](../status-variables-added-in-mariadb-105/index)
* [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-104/index)
* [System Variables Added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-105/>

Understanding MariaDB Architecture
==================================

    MariaDB architecture is partly different from the architecture of traditional DBMSs, like SQL Server. Here we will examine the main components that a new MariaDB DBA needs to know. We will also discuss a bit of history, because this may help understand MariaDB philosophy and certain design choices.

 This section is an overview of the most important components. More information is included in specific sections of this migration guide, or in other pages of the MariaDB Knowledge Base (see the links scattered over the text).

 Storage Engines
---------------

 MariaDB was born from the source code of MySQL, in 2008. Therefore, its history begins with MySQL.

 MySQL was born at the beginning of the 90s. Back in the days, if compared to its existing competitors, MySQL was lightweight, simple to install, easy to learn. While it had a very limited set of features, it was also fast in certain common operations. And it was open source. These characteristics made it suitable to back the simple websites that existed at that time.

 The web evolved rapidly, and the same happened to MySQL. Being open source helped a lot in this respect, because the community needed functionalities that weren’t supported at that time.

 MySQL was probably the first database system to support a [pluggable storage engine architecture](../storage-engines/index). Basically, this means that MySQL knows very little about creating or populating a table, reading from it, building proper indexes and caches. It just delegated all these operations to a special plugin type called a storage engine.

 One of the first plugins developed by third parties was [InnoDB](index#innodb). It is very fast, and it adds two important features that are not otherwise supported: transactions and [foreign keys](../foreign-keys/index).

 Note that when MariaDB asks a storage engine to write or read a row, the storage engine could theoretically do anything. This led to the creation of very interesting alternative engines, like [BLACKHOLE](../blackhole/index) (which doesn’t write or read any data, acting like the /dev/null file in Linux), or [CONNECT](../connect/index) (which can read and write to files written in many different formats, or remote DBMSs, or some other special data sources).

 Nowadays InnoDB is the default MariaDB storage engine, and it is the best choice for most use cases. But for particular needs, sometimes using a different storage engine is desirable. In case of doubts about the best storage engine to use for a specific case, check the [Choosing the Right Storage Engine](../choosing-the-right-storage-engine/index) page.

 When we create a table, we specify its storage engine or use the default one. It is possible to convert an existing table to another storage engine, though this is a blocking operation which requires a complete table copy. Third-party storage engines can also be installed while MariaDB is running.

 Note that it is perfectly possible to use tables with different storage engines in the same transaction (even if some engines are not transactional). It is even possible to use different engines in the same query, for example with JOINs and subqueries.

 The default storage engine can be changed by changing the [default\_storage\_engine](../server-system-variables/index#default_storage_engine) variable. A different default can be specified for temporary tables by setting [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine). MariaDB uses [Aria](../aria-storage-engine/index) for system tables and temporary tables created internally to store the intermediate results of a query.

 ### InnoDB

 It is worth spending some more words here about [InnoDB](../innodb/index), the default storage engine.

 #### Primary Key and Indexes

 InnoDB primary keys are always the equivalent of SQL Server clustered indexes. In other words, an InnoDB table is always ordered by the primary key.

 If an InnoDB table doesn't have a user-defined primary key, the first `UNIQUE` index whose columns are all `NOT NULL` is used as a primary key. If there is no such index, the table will have a *clustered index*. The terminology here can be a bit confusing for SQL Server and other DBMS users. A clustered index in InnoDB is a 6 bytes value that is added to the table. This index and its values are completely invisible to the users. It's important to note that clustered indexes are governed by a global mutex that greatly reduces their scalability.

 Secondary indexes are ordered by the columns that are part of the index, and contain a reference to each entry's corresponding primary key value.

 Some consequences of these design choices are the following:

 * For performance reasons, a primary key value should be inserted in order. In other words, the last inserted value should be the highest. This order is normally followed when inserting values into an `AUTO_INCREMENT` primary key. The reason is that inserting values in the middle of an ordered data structure is slower, unless they fit into existing holes. If we insert primary key values randomly, InnoDB often has to rearrange pages to make some room for the new data.
* A big primary keys means that all secondary indexes are also big.
* A query by primary key will require a single search. A query on a secondary index that also reads columns not contained in the index will require one search on the index, plus one more search for each row that satisfies the index condition.
* We shouldn't explicitly include the primary key in a secondary index. If we do so, the primary key column will be duplicated in the index.

 #### Tablespaces

 For InnoDB, a *tablespace* is a file containing data (not a file group as in SQL Server). The types of tablespaces are:

 * [System tablespace](../innodb-system-tablespaces/index).
* [File-per-table tablespaces](../innodb-file-per-table-tablespaces/index).
* [Temporary tablespaces](../innodb-temporary-tablespaces/index).

 The system tablespace is stored in the file `ibdata`. It contains information used by InnoDB internally, like rollback segments, as well as some system tables. Historically, the system tablespace also contained all tables created by the user. In modern MariaDB versions, a table is created in the system tablespace only if the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable is set to 0 at the moment of the table creation. By default, innodb\_file\_per\_table is 1.

 Tables created while `innodb_file_per_table=1` are written into their own tablespace. These are `.ibd` files.

 Starting from [MariaDB 10.2](../what-is-mariadb-102/index), temporary tables are written into temporary tablespaces, which means `ibtmp*` files. Previously, they were created in the system tablespace or in file-per-table tablespaces according to the value of `innodb_file_per_table`, just like regular tables. Temporary tablespaces, if present, are deleted when MariaDB starts.

 **It is important to remember that tablespaces can never shrink**. If a file-per-table tablespace grows too much, deleting data won't recover space. Instead, a new table must be created and data needs to be copied. Finally, the old table will be deleted. If the system tablespace grows too much, the only solution is to move data into a new MariaDB installation.

 #### Transaction Logs

 In SQL Server, the transaction log contains both the undo log and the redo log. Usually we have only one transaction log.

 In MariaDB the undo log and the redo log are stored separately. By default, the [redo log](../innodb-redo-log/index) is written to two files, called `ib_logfile0` and `ib_logfile1`. The [undo log](../innodb-undo-log/index) by default is written to the *system tablespace*, which is in the `ibdata1` file. However, it is possible to write it in separate files in a specified directory.

 MariaDB provides no way to inspect the contents of the transaction logs. However, it is possible to inspect the [binary log](index#the-binary-log).

 InnoDB transaction logs are written in a circular fashion: their size is normally fixed, and when the end is reached, InnoDB continues to write from the beginning. However, if very long transactions are running, InnoDB cannot overwrite the oldest data, so it has to expand the log size instead.

 #### InnoDB Buffer Pool

 MariaDB doesn't have a central buffer pool. Each storage engine may or may not have a buffer pool. The [InnoDB buffer pool](../innodb-buffer-pool/index) is typically assigned a big amount of memory. See [MariaDB Memory Allocation](../mariadb-memory-allocation/index).

 MariaDB has no extension like the SQL Server buffer pool extension.

 A part of the buffer pool is called the [change buffer](../innodb-change-buffering/index). It contains dirty pages that have been modified in memory and not yet flushed.

 #### InnoDB Background Threads

 InnoDB has background threads that take care of flushing dirty pages from the change buffer to the tablespaces. They don't directly affect the latency of queries, but they are very important for performance.

 [SHOW ENGINE InnoDB STATUS](../show-engine-innodb-status/index) shows information about them in the `BACKGROUND THREAD` section. They can also be seen using the [threads](../performance-schema-threads-table/index) table, in the [performance\_schema](../performance-schema/index).

 InnoDB flushing is similar to *lazy writes* and *checkpoints* in SQL Server. It has no equivalent for *eager writing*.

 For more information, see [InnoDB Page Flushing](../innodb-page-flushing/index) and [InnoDB Purge](../innodb-purge/index).

 #### Checksums and Doublewrite Buffer

 InnoDB pages have checksums. After writing pages to disk, InnoDB verifies that the checksums match. The checksum algorithm is determined by [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm). Check the variable documentation for its consequences on performance, backward compatibility and encryption.

 In case of a system crash, hardware failure or power outage, a page could be half-written on disk. For some pages, this causes a disaster. Therefore, InnoDB writes essential pages to disk twice. A backup copy of the new page version is written first. Then, the old page is overwritten. The backup copies are written into a file called the *doublewrite buffer*.

 * If an event prevents the first page from being written, the old version of the page will still be available.
* If an event prevents the old page from being completely overwritten by its new version, the page can still be recovered using the doublewrite buffer.

 The doublewrite buffer can disabled using the [innodb\_doublewrite](../innodb-system-variables/index#innodb_doublewrite) variable, but this usually doesn't bring big performance benefits. The doublewrite buffer location can be changed with [innodb\_doublewrite\_file](../innodb-system-variables/index#innodb_doublewrite_file).

 ### Aria

 Even if we only create InnoDB tables, we use Aria indirectly, in two ways:

 * For system tables.
* For internal temporary tables.

 Aria is a non-transactional storage engine. By default it is crash-safe, meaning that all changes to data are written and fsynced to a write-ahead log and can always be recovered in case of a crash.

 Aria caches indexes into the pagecache. Data are not directly cached by Aria, so it's important that the underlying filesystem caches reads and writes.

 The pagecache size is determined by the [aria\_pagecache\_buffer\_size](../aria-system-variables/index#aria_pagecache_buffer_size) system variable. To know if it is big enough we can check the proportion of free pages (the ratio between [Aria\_pagecache\_blocks\_used](../aria-status-variables/index#aria_pagecache_blocks_used) and [Aria\_pagecache\_blocks\_unused](../aria-status-variables/index#aria_pagecache_blocks_unused)) and the proportion of cache misses (the ratio between [Aria\_pagecache\_read\_requests](../aria-status-variables/index#aria_pagecache_read_requests) and [Aria\_pagecache\_reads](../aria-status-variables/index#aria_pagecache_reads).

 The proportion of dirty pages is the ratio between [Aria\_pagecache\_blocks\_used](../aria-status-variables/index#aria_pagecache_blocks_used) and [Aria\_pagecache\_blocks\_not\_flushed](../aria-status-variables/index#aria_pagecache_blocks_not_flushed) tells us if the log file is big enough.

 The size of Aria log is determined by [aria\_log\_file\_size](../aria-system-variables/index#aria_pagecache_buffer_size).

 Databases
---------

 MariaDB does not support the concept of schema. In MariaDB SQL, *schema* and *schemas* are synonyms for *database* and *databases*.

 When a user connects to MariaDB, they don't connect to a specific database. Instead, they can access any table they have permissions for. There is however a concept of *default database*, see below.

 A database is a container for database objects like tables and views. A database serves the following purposes:

 * A database is a namespace.
* A database is a logical container to separate objects.
* A database has a default [character set](../character-sets/index) and collation, which are inherited by their tables.
* Permissions can be assigned on a whole database, to make permission maintenance simpler.
* Physical data files are stored in a directory which has the same name as the database to which they belong.

 ### System Databases

 MariaDB has the following system databases:

 * [mysql](../the-mysql-database-tables/index) is for internal use only, and should not be read or written directly.
* [information\_schema](../information-schema/index) contains all information that can be found in SQL Server's information\_schema and more. However, while SQL Server's `information_schema` is a schema containing information about the local database, MariaDB's `information_schema` is a database that contains information about all databases.
* [performance\_schema](../performance-schema/index) contains information about MariaDB runtime. It is disabled by default. Enabling it requires setting the [performance\_schema](../performance-schema-system-variables/index#performance_schema) system variable to 1 and restarting MariaDB.

 ### Default Database

 When a user connects to MariaDB, they can optionally specify a default database. A default database can also be specified or changed later, with the [USE](../use/index) command.

 Having a default database specified allows one to specify tables without specifying the name of the database where they are located. If no default database is specified, all table names must be fully qualified.

 For example, the two following snippets are equivalent:

 
```
SELECT * FROM my_database.my_table;

-- is equivalent to:
USE my_database;
SELECT * FROM my_table;

```

Even if a default database is specified, tables from other databases can be accessed by specifying their fully qualified names:

 
```
-- this query joins my_database.my_table to your_database.your_table
USE my_database;
SELECT m.*
    FROM my_table m
    JOIN your_database.your_table y
        ON m.xyz = y.xyz;

```

MariaDB has the [DATABASE()](../database/index) function to determine the current database:

 
```
SELECT DATABASE();

```

Stored procedures and triggers don't inherit a default database from the session, nor by a caller procedure. In that context, the default database is the database which contains the procedure. `USE` can be used to change it. The default database will only be valid for the rest of the procedure.

 The Binary Log
--------------

 Different tables can be built using different storage engines. It is important to note that not all engines are transactional, and that different engines implement the transaction logs in different ways. For this reason, MariaDB cannot replicate data from a primary to a replica using an equivalent of SQL Server transactional replication.

 Instead, it needs a global mechanism to log the changes that are applied to data. This mechanism is the [binary log](../binary-log/index), often abbreviated to binlog.

 The binary log can be written in the following formats:

 * STATEMENT logs SQL statements that modify data;
* ROW logs a reference to the rows that have been modified, if any (usually it’s the primary key), and the new values that have been added or modified, in a binary format.
* MIXED is a combination of the above formats. It means that ROW is used for statements that can safely be logged in this way (see below), and STATEMENT is used in other cases. This is the default format from [MariaDB 10.2](../what-is-mariadb-102/index).

 In most cases, STATEMENT is slower because the SQL statement needs to be re-executed by the replica, and because certain statements may produce a different result in the replica (think about queries that use LIMIT without ORDER BY, or the CURRENT\_TIMESTAMP() function). But there are exceptions, and besides, DDL statements are always logged as STATEMENT to avoid flooding the binary log. Therefore, the binary log may well contain both ROW and STATEMENT entries.

 See [Binary Log Formats](../binary-log-formats/index).

 The binary log allows:

 * replication, if enabled on the primary;
* promoting a replica to a primary, if enabled on that replica;
* incremental backups;
* seeing data as they were in a point of time in the past ([flashback](../flashback/index));
* restoring a backup and re-appling the binary log, with the exception of a data change which caused problems (human mistake, application bug, SQL injection);
* Capture Data Changes (CDC), by streaming the binary log to technologies like Apache Kafka.

 If you don't plan to use any of these features on a server, it is possible to [disable](../replication-and-binary-log-system-variables/index#log_bin) the binary log to slightly improve the performance.

 The binary log can be inspected using the [mariadb-binlog](../mariadb-binlog/index) utility, which comes with MariaDB. Enabling or disabling the binary log requires restarting MariaDB.

 See also [MariaDB Replication Overview for SQL Server Users](../mariadb-replication-overview-for-sql-server-users/index) and [MariaDB Backups Overview for SQL Server Users](../mariadb-backups-overview-for-sql-server-users/index) for a better understanding of how the binary log is used.

 Plugins
-------

 Storage engines are a special type of [plugin](../plugins/index). But others exist. For example, plugins can add authentication methods, new features, SQL syntax, functions, informative tables, and more.

 A plugin may add some server variables and some status variables. Server variables can be used to configure the plugin, and status variables can be used to monitor its activities and status. These variables generally use the plugin's name as a prefix. For example InnoDB has a server variable called innodb\_buffer\_pool\_size to configure the size of its buffer pool, and a status variable called Innodb\_pages\_read which indicates the number of memory pages read from the buffer pool. The category [system variables](../system-variables/index) of the MariaDB Knowledge Base has specific pages for system and status variables associated with various plugins.

 Many plugins are installed by default, or available but not installed by default. They can be installed or uninstalled at runtime with SQL statements, like `INSTALL PLUGIN`, `UNINSTALL PLUGIN` and others; see [Plugin SQL Statements](../plugin-sql-statements/index). 3rd party plugins can be made available for installation by simply copying them to the [plugin\_dir](../server-system-variables/index#plugin_dir).

 It is important to note that different plugins may have different maturity levels. It is possible to prevent the installation of plugins we don’t consider production-ready by setting the [plugin\_maturity](../server-system-variables/index#plugin_maturity) system variable. For plugins that are distributed with MariaDB, the maturity level is determined by the MariaDB team based on the bugs reported and fixed.

 Some plugins are developed by 3rd parties. Even some 3rd party plugins are included in MariaDB official distributions - the ones available on mariadb.org.

 In MariaDB every authorization method (including the default one) is provided by an [authentication plugin](../authentication-plugins/index). A user can be required to use a certain authentication plugin. This gives us much flexibility and control. Windows users may be interested in [gsapi](../authentication-plugin-gssapi/index) (which supports Windows authentication, Kerberos and NTLM) and [named\_pipe](../authentication-plugin-named-pipe/index) (which uses named pipe impersonation).

 Other plugins that can be very useful include [userstat](../user-statistics/index), which includes statistics about resources and table usage, and [METADATA\_LOCK\_INFO](../metadata_lock_info/index), which provides information about metadata locks.

 Thread Pool
-----------

 MariaDB supports [thread pool](../thread-pool/index). It works differently on UNIX and on Windows. On Windows, it is enabled by default and its implementation is quite similar to SQL Server. It uses the Windows native CreateThreadpool API.

 If we don't use the thread pool, MariaDB will use its traditional method to handle connections. It consists of using a dedicated thread for each client connection. Creating a new thread has a cost in terms of CPU time. To mitigate this cost, after a client disconnects, the thread may be preserved for a certain time in the [thread cache](../server-system-variables/index#thread_cache_size).

 Whichever connection method we use, MariaDB has a maximum number of simultaneous connections, which can be changed at runtime. When the limit is reached, if more clients try to connect they will receive an error. This prevents MariaDB from consuming all the server resources and freezing or crashing. See [Handling Too Many Connections](../handling-too-many-connections/index).

 Configuration
-------------

 MariaDB has many settings that control the server behavior. These can be set up when starting mysqld ([mysqld options](../mysqld-options/index)), and the vast majority are also accessible as [server system variables](../server-system-variables/index). These can be classified in these ways:

 * **Dynamic** or **static**;
* **Global**, **session**, or both.

 Note that server system variables are not to be confused with [user-defined variables](../user-defined-variables/index). The latter are not used for MariaDB configuration.

 ### Configuration Files

 MariaDB can use several [configuration files](../configuring-mariadb-with-option-files/index). Configuration files are searched in several locations, including in the user directory, and if present they all are read and used. They are read in a consistent order. These locations depend on the operating system; see [Default Option File Locations](../configuring-mariadb-with-option-files/index#default-option-file-locations). It is possible to tell MariaDB which files it should read; see [Global Options Related to Option Files](../configuring-mariadb-with-option-files/index#global-options-related-to-option-files).

 On Linux, by default the configuration files are called `my.cnf`. On Windows, by default the configuration files can be called `my.ini` or `my.cnf`. The former is more common.

 If a variable is mentioned multiple times in different files, the occurrence that is read last will overwrite the others. Similarly, if a variable is mentioned several times in a single file, the occurrence that is read last overwrites the others.

 The contents of each configuration file are organized by *option groups*. MariaDB Server and client programs read different groups. The read groups also depend on the MariaDB version. See [Option Groups](../configuring-mariadb-with-option-files/index#option-groups) for the details. Most commonly, the `[server]` or `[mysqld]` groups are used to contain all server configuration. The `[client-server]` group can be used for options that are shared by the server and the clients (like the port to use), to avoid repeating those variables multiple times.

 ### Dynamic and Static Variables

 Dynamic variables have a value that can be changed at runtime, using the [SET](../set/index) SQL statement. Static variables have a value that is decided at startup (see below) and cannot be changed without a restart.

 The [Server System Variables](../server-system-variables/index) page states if variables are dynamic or static.

 ### Scope

 A global system variable is one that affects the general behavior of MariaDB. For example [innodb\_buffer\_pool\_size](../innodb-system-variables/index#innodb_buffer_pool_size) determines the size of the InnoDB buffer pool, which is used by read and write operations, no matter which user issued them. A session system variable is one that affects MariaDB behavior for the current connection; changing it will not affect other connected users, or future connections from the current user.

 A variable could exist in both the global and session scopes. In this case, the session value is what affects the current connection. When a user connects, the current global value is copied to the session scope. Changing the global value afterward will not change existing connections.

 The [Server System Variables](../server-system-variables/index) page states the scope of each variable.

 Global variables and some session variables can only be modified by a user with the [SUPER](../grant/index#global-privileges) privilege (typically root).

 ### Syntax

 To see the value of a system variable:

 
```
-- global variables:
SELECT @@global.variable_name;
-- session variables:
SELECT @@session.variable_name;
-- or just use the shortcut:
SELECT @@variable_name;

```

A longer syntax, which is mostly useful to get multiple variables, makes use of the same pattern syntax that is used by the [LIKE](../like/index) operator:

 
```
-- global variables whose name starts with 'innodb':
SHOW GLOBAL VARIABLES LIKE 'innodb%';
-- session variables whose name starts with 'innodb':
SHOW SESSION VARIABLES LIKE 'innodb%';
SHOW VARIABLES LIKE 'innodb%';

```

To modify the global or session value of a dynamic variable:

 
```
SET @@global.variable_name = 'new 'value';
SET @@session.variable_name = 'new 'value';

```

Notice that if we modify a global variable in this way, the new value will be lost at server restart. For this reason we probably want to change the value in the configuration file too.

 For further information see:

 * The [SET](../set/index) statement.
* The [SHOW VARIABLES](../show-variables/index) statement.

 ### Setting System Variables with Startup Parameters

 System variables can be set at server startup without writing their values into a configuration file. This is useful if we want a value to be set once, until we change it or restart MariaDB. Values passed in this way override values written in the configuration files.

 The general rule is that every global variable can be passed as an argument of `mysqld` by prefixing its name with `--` and by replacing every occurrence of `_` with `-` in its name.

 For example, to pass `bind_address` as a startup argument:

 
```
mysqld --bind-address=127.0.0.1

```

### Debugging Configuration

 Mistyping a variable can prevent MariaDB from starting. We cannot set a variable that doesn't exist in the MariaDB version in use. In these cases, an error is written in the [error log](../error-log/index).

 Having several configuration files and configuration groups, as well as being able to pass variables as command-line arguments, brings a lot of flexibility but can sometimes be confusing. When we are unsure about which values will be used, we can run:

 
```
mysqld --print-defaults

```

Status Variables
----------------

 MariaDB status variables and some system tables allow external tools to monitor a server, building graphs on how they change over time, and allow the user to inspect what is happening inside the server.

 [Status variables](../server-status-variables/index) cannot be directly modified by the user. Their values indicate how MariaDB is operating. Their scope can be:

 * **Global**, meaning that the value is about some MariaDB activity.
* **Session**, meaning that the value measures activities taking place in the current session.

 Many status variables exist in both scopes. For example,[Cpu\_time](../server-status-variables/index#cpu_time) at global level indicates how much time the CPU was used by the MariaDB process (including all user sessions and all the background threads). At session level, it indicates how much time the CPU was used by the current session.

 The status variables created by a plugin, usually, use the plugin name as a prefix.

 The [SHOW STATUS](../show-status/index) statement prints the values of the status variables that match a certain pattern.

 
```
-- Show all InnoDB global status variables
SHOW GLOBAL STATUS LIKE 'innodb%';
-- Show all InnoDB session status variables
SHOW SESSION STATUS LIKE 'innodb%';
SHOW STATUS LIKE 'innodb%';
-- Show global variables that contain the "size" substring:
SHOW GLOBAL STATUS LIKE '%size%';

```

Some status variables values are reset when [FLUSH STATUS](../flush/index#flush-status) is executed. A possible use:

 
```
DELIMITER ||
BEGIN NOT ATOMIC
SET @i = 0;
WHILE @i < 60 DO
    SHOW GLOBAL STATUS LIKE 'Com_select';
    FLUSH STATUS;
    DO SLEEP(1);
    SET @i = @i + 1;
END WHILE;
END ||

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/understanding-mariadb-architecture/>

Upgrading from MariaDB 10.0 to MariaDB 10.1
===========================================

    What You Need to Know
---------------------

 There are no changes in table or index formats between [MariaDB 10.0](../what-is-mariadb-100/index) and [MariaDB 10.1](../what-is-mariadb-101/index), so on most servers the upgrade should be painless.

 ### How to Upgrade

 
For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.

 

For MariaDB Galera Cluster, see [Upgrading from MariaDB Galera Cluster 10.0 to MariaDB 10.1 with Galera Cluster](../upgrading-galera-cluster-upgrading-from-mariadb-galera-cluster-100-to-maria/index) instead.

 

Before you upgrade, it would be best to take a backup of your database. This is always a good idea to do before an upgrade. We would recommend [Percona XtraBackup](../backup-restore-and-import-clients-percona-xtrabackup/index).

  The suggested upgrade procedure is:

 1. Modify the repository configuration, so the system's package manager installs [MariaDB 10.1](../what-is-mariadb-101/index). For example,
	* On Debian, Ubuntu, and other similar Linux distributions, see [Updating the MariaDB APT repository to a New Major Release](../installing-mariadb-deb-files/index#updating-the-mariadb-apt-repository-to-a-new-major-release) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Updating the MariaDB YUM repository to a New Major Release](../yum/index#updating-the-mariadb-yum-repository-to-a-new-major-release) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Updating the MariaDB ZYpp repository to a New Major Release](../installing-mariadb-with-zypper/index#updating-the-mariadb-zypp-repository-to-a-new-major-release) for more information.
2. Set `[innodb\_fast\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_fast_shutdown)` to `0`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:   
 `SET GLOBAL innodb_fast_shutdown=0;`
3. [Stop MariaDB](../starting-and-stopping-mariadb-automatically/index).
4. Uninstall the old version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, execute the following:   
	 `sudo apt-get remove mariadb-server`
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, execute the following:   
	 `sudo yum remove MariaDB-server`
	* On SLES, OpenSUSE, and other similar Linux distributions, execute the following:   
	 `sudo zypper remove MariaDB-server`
5. Install the new version of MariaDB.
	* On Debian, Ubuntu, and other similar Linux distributions, see [Installing MariaDB Packages with APT](../installing-mariadb-deb-files/index#installing-mariadb-packages-with-apt) for more information.
	* On RHEL, CentOS, Fedora, and other similar Linux distributions, see [Installing MariaDB Packages with YUM](../yum/index#installing-mariadb-packages-with-yum) for more information.
	* On SLES, OpenSUSE, and other similar Linux distributions, see [Installing MariaDB Packages with ZYpp](../installing-mariadb-with-zypper/index#installing-mariadb-packages-with-zypp) for more information.
6. Make any desired changes to configuration options in [option files](../configuring-mariadb-with-option-files/index), such as `my.cnf`. This includes removing any options that are no longer supported.
7. [Start MariaDB](../starting-and-stopping-mariadb-automatically/index).
8. Run `[mysql\_upgrade](../mysql_upgrade/index)`.
	* `mysql_upgrade` does two things:
		1. Ensures that the system tables in the `[mysq](../the-mysql-database-tables/index)l` database are fully compatible with the new version.
		2. Does a very quick check of all tables and marks them as compatible with the new version of MariaDB .

 ### Incompatible Changes Between 10.0 and 10.1

 As mentioned previously, on most servers upgrading from 10.0 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### Storage Engines

 * The [ARCHIVE](../archive/index) storage engine is no longer enabled by default, and the plugin needs to be specifically enabled.
* The [BLACKHOLE](../blackhole/index) storage engine is no longer enabled by default, and the plugin needs to be specifically enabled.

 #### Replication

 * [MariaDB 10.1](../what-is-mariadb-101/index) introduces new, standards-compliant behavior for dealing with [primary keys over nullable columns](../primary-keys-with-nullable-columns/index). In certain edge cases this could cause replication issues when replicating from a [MariaDB 10.0](../what-is-mariadb-100/index) master to a [MariaDB 10.1](../what-is-mariadb-101/index) slave using [statement-based replication](../binary-log-formats/index#statement-based). See [MDEV-12248](https://jira.mariadb.org/browse/MDEV-12248).

 #### Options That Have Changed Default Values

 Most of the following options have increased in value to give better performance.

 


| Option | Old default value | New default value |
| --- | --- | --- |
| [innodb\_log\_compressed\_pages](../xtradbinnodb-server-system-variables/index#innodb_log_compressed_pages) | `ON` | `OFF` |
| [join\_buffer\_size](../server-system-variables/index#join_buffer_size) | `128K` | `256K` |
| [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) | `1M` | `4M` |
| [query\_alloc\_block\_size](../server-system-variables/index#query_alloc_block_size) | `8192` | `16384` |
| [query\_cache\_size](../server-system-variables/index#query_cache_size) | `0` | `1M` |
| [query\_cache\_type](../server-system-variables/index#query_cache_type) | `ON` | `OFF` |
| [sync\_master\_info](../replication-and-binary-log-server-system-variables/index#sync_master_info) | `0` | `10000` |
| [sync\_relay\_log](../replication-and-binary-log-server-system-variables/index#sync_relay_log) | `0` | `10000` |
| [sync\_relay\_log\_info](../replication-and-binary-log-server-system-variables/index#sync_relay_log_info) | `0` | `10000` |
| [query\_prealloc\_size](../server-system-variables/index#query_prealloc_size) | `8192` | `24576` |
| [secure\_auth](../server-system-variables/index#secure_auth) | `OFF` | `ON` |
| [sql\_log\_bin](../replication-and-binary-log-server-system-variables/index#sql_log_bin) |  | No longer affects replication of events in a Galera cluster. |
| [sql\_mode](../server-system-variables/index#sql_mode) | `empty` | `NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION` |
| [table\_open\_cache](../server-system-variables/index#table_open_cache) | `400` | `2000` |
| [thread\_pool\_max\_threads](../server-system-variables/index#thread_pool_max_threads) | `500` | `1000` |

 
#### Options That Have Been Removed or Renamed

 The following options should be removed or renamed if you use them in your config files:

 


| Option | Reason |
| --- | --- |
| [rpl\_recovery\_rank](../server-system-variables/index#rpl_recovery_rank) | Unused in 10.0 |

 
#### Other Issues

 Note that explicit or implicit casts from MAX(string) to INT, DOUBLE or DECIMAL now produce warnings ([MDEV-8852](https://jira.mariadb.org/browse/MDEV-8852)).

 ### Major New Features To Consider

 You might consider using the following major new features in [MariaDB 10.1](../what-is-mariadb-101/index):

 * [Galera Cluster](../galera/index) is now included by default.
* [Encryption](../data-at-rest-encryption/index)
* [InnoDB/XtraDB Page Compression](../compression/index)

 Notes
-----

 See Also
--------

 * [The features in MariaDB 10.1](../what-is-mariadb-101/index)
* [Upgrading from MariaDB Galera Cluster 10.0 to MariaDB 10.1 with Galera Cluster](../upgrading-galera-cluster-upgrading-from-mariadb-galera-cluster-100-to-maria/index)
* [Upgrading from MariaDB 10.1 to MariaDB 10.2](../upgrading-from-mariadb-101-to-mariadb-102/index)
* [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-100-to-mariadb-101/>

System Variables Added in MariaDB 10.3
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.3](../what-is-mariadb-103/index) series. The list does not include variables that are not part of the default release.

 


| Variable | Added |
| --- | --- |
| [alter\_algorithm](../server-system-variables/index#alter_algorithm) | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| [bind\_address](../server-system-variables/index#bind_address) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [binlog\_file\_cache\_size](../replication-and-binary-log-server-system-variables/index#binlog_file_cache_size) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [gtid\_pos\_auto\_engines](../gtid/index#gtid_pos_auto_engines) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [column\_compression\_threshold](../storage-engine-independent-column-compression/index#column_compression_threshold) | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) |
| [column\_compression\_zlib\_level](../storage-engine-independent-column-compression/index#column_compression_zlib_level) | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) |
| [column\_compression\_zlib\_strategy](../storage-engine-independent-column-compression/index#column_compression_zlib_strategy) | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) |
| [column\_compression\_zlib\_wrap](../storage-engine-independent-column-compression/index#column_compression_zlib_wrap) | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) |
| [idle\_readonly\_transaction\_timeout](../server-system-variables/index#idle_readonly_transaction_timeout) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [idle\_transaction\_timeout](../server-system-variables/index#idle_transaction_timeout) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [idle\_write\_transaction\_timeout](../server-system-variables/index#idle_write_transaction_timeout) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [in\_predicate\_conversion\_threshold](../server-system-variables/index#in_predicate_conversion_threshold) | [MariaDB 10.3.18](https://mariadb.com/kb/en/mariadb-10318-release-notes/) |
| [innodb\_encrypt\_temporary\_ables](../xtradbinnodb-server-system-variables/index#innodb_encrypt_temporary_tables) | [MariaDB 10.3.17](https://mariadb.com/kb/en/mariadb-10317-release-notes/) |
| [innodb\_instant\_alter\_column\_allowed](../innodb-system-variables/index#innodb_instant_alter_column_allowed) | [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/) |
| [log\_disabled\_statements](../server-system-variables/index#log_disabled_statements) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [log\_slow\_disabled\_statements](../server-system-variables/index#log_slow_disabled_statements) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [rpl\_semi\_sync\_\*](../semisynchronous-replication/index#system-variables) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [secure\_timestamp](../server-system-variables/index#secure_timestamp) | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| [slave\_transaction\_retry\_errors](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_errors) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [slave\_transaction\_retry\_interval](../replication-and-binary-log-server-system-variables/index#slave_transaction_retry_interval) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [system\_versioning\_alter\_history](../system-versioned-tables/index#system_versioning_alter_history) | [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) |
| [system\_versioning\_asof](../system-versioned-tables/index#system_versioning_asof) | [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) |
| [system\_versioning\_innodb\_algorithm\_simple](../system-versioned-tables/index#system_versioning_innodb_algorithm_simple) | [MariaDB 10.3.4](https://mariadb.com/kb/en/mariadb-1034-release-notes/) |
| [tcp\_keepalive\_interval](../server-system-variables/index#tcp_keepalive_interval) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [tcp\_keepalive\_probes](../server-system-variables/index#tcp_keepalive_probes) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [tcp\_keepalive\_time](../server-system-variables/index#tcp_keepalive_time) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [version\_source\_revision](../server-system-variables/index#version_source_revision) | [MariaDB 10.3.2](https://mariadb.com/kb/en/mariadb-1032-release-notes/) |
| [wsrep\_certification\_rules](../galera-cluster-system-variables/index#wsrep_certification_rules) | [MariaDB 10.3.13](https://mariadb.com/kb/en/mariadb-10313-release-notes/) |
| [wsrep\_reject\_queries](../galera-cluster-system-variables/index#wsrep_reject_queries) | [MariaDB 10.3.6](https://mariadb.com/kb/en/mariadb-1036-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.3](../status-variables-added-in-mariadb-103/index)
* [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-104/index)
* [System Variables Added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index)
* [System Variables Added in MariaDB 10.1](../system-variables-added-in-mariadb-101/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-103/>

Upgrading from MariaDB 5.3 to MariaDB 5.5
=========================================

    What you need to know
---------------------

 There are no changes in table or index formats between [MariaDB 5.3](../what-is-mariadb-53/index) and [MariaDB 5.5](../what-is-mariadb-55/index), so on most servers the upgrade should be painless.

 ### How to upgrade

 The suggested upgrade procedure is:

 1. For Windows, see [Upgrading MariaDB on Windows](../upgrading-mariadb-on-windows/index) instead.
2. Shutdown [MariaDB 5.3](../what-is-mariadb-53/index)
3. Take a backup (this is the perfect time to take a backup of your databases)
4. Uninstall [MariaDB 5.3](../what-is-mariadb-53/index)
5. Install [MariaDB 5.5](../what-is-mariadb-55/index) [[1](#_note-0)]
6. Run [mysql\_upgrade](../mysql_upgrade/index)
	* Ubuntu and Debian packages do this automatically when they are installed; Red Hat, CentOS, and Fedora packages do not
	* `mysql_upgrade` does two things:
		1. Upgrades the permission tables in the `mysql` database with some new fields
		2. Does a very quick check of all tables and marks them as compatible with [MariaDB 5.5](../what-is-mariadb-55/index)
	* In most cases this should be a fast operation (depending of course on the number of tables)
7. Add new options to [my.cnf](../configuring-mariadb-with-mycnf/index) to enable features
	* If you change `my.cnf` then you need to restart `mysqld`

 ### Incompatible changes between 5.3 and 5.5

 As mentioned previously, on most servers upgrading from 5.5 should be painless. However, there are some things that have changed which could affect an upgrade:

 #### XtraDB options that have changed default values

 


| Option | Old value | New value |
| --- | --- | --- |
| [innodb\_change\_buffering](../xtradbinnodb-server-system-variables/index#innodb_change_buffering) | inserts | all |
| [innodb\_flush\_neighbor\_pages](../xtradbinnodb-server-system-variables/index#innodb_flush_neighbor_pages) | 1 | area |

 
#### Options that have been removed or renamed

 Percona, the provider of [XtraDB](../xtradb-and-innodb/index), does not provide all earlier XtraDB features in the 5.5 code base. Because of that, [MariaDB 5.5](../what-is-mariadb-55/index) can't provide them either. The following options are not supported by XtraDB 5.5. If you are using them in any of your my.cnf files, you should remove them before upgrading to 5.5.

 * [innodb\_adaptive\_checkpoint](../xtradbinnodb-server-system-variables/index#innodb_adaptive_checkpoint); Use [innodb\_adaptive\_flushing\_method](../xtradbinnodb-server-system-variables/index#innodb_adaptive_flushing_method) instead.
* [innodb\_auto\_lru\_dump](../xtradbinnodb-server-system-variables/index#innodb_auto_lru_dump); Use [innodb\_buffer\_pool\_restore\_at\_startup](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_restore_at_startup) instead (and [innodb\_buffer\_pool\_load\_at\_startup](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_load_at_startup) in [MariaDB 10.0](../what-is-mariadb-100/index)).
* [innodb\_blocking\_lru\_restore](../xtradbinnodb-server-system-variables/index#innodb_blocking_lru_restore); Use [innodb\_blocking\_buffer\_pool\_restore](../xtradbinnodb-server-system-variables/index#innodb_blocking_buffer_pool_restore) instead.
* [innodb\_enable\_unsafe\_group\_commit](../xtradbinnodb-server-system-variables/index#innodb_enable_unsafe_group_commit)
* [innodb\_expand\_import](../xtradbinnodb-server-system-variables/index#innodb_expand_import); Use [innodb\_import\_table\_from\_xtrabackup](../xtradbinnodb-server-system-variables/index#innodb_import_table_from_xtrabackup) instead.
* [innodb\_extra\_rsegments](../xtradbinnodb-server-system-variables/index#innodb_extra_rsegments); Use [innodb\_rollback\_segments](../xtradbinnodb-server-system-variables/index#innodb_rollback_segments) instead.
* [innodb\_extra\_undoslots](../xtradbinnodb-server-system-variables/index#innodb_extra_undoslots)
* [innodb\_fast\_recovery](../xtradbinnodb-server-system-variables/index#innodb_fast_recovery)
* [innodb\_flush\_log\_at\_trx\_commit\_session](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit_session)
* [innodb\_overwrite\_relay\_log\_info](../xtradbinnodb-server-system-variables/index#innodb_overwrite_relay_log_info)
* [innodb\_pass\_corrupt\_table](../xtradbinnodb-server-system-variables/index#innodb_pass_corrupt_table); Use [innodb\_corrupt\_table\_action](../xtradbinnodb-server-system-variables/index#innodb_corrupt_table_action) instead.
* [innodb\_use\_purge\_thread](../xtradbinnodb-server-system-variables/index#innodb_use_purge_thread)
* [xtradb\_enhancements](../xtradbinnodb-server-system-variables/index#xtradb_enhancements)

 Notes
-----

 1. [↑](#_ref-0) If using a MariaDB `apt` or `yum` [repository](https://downloads.mariadb.org/mariadb/repositories/), it is often enough to replace instances of '5.3' with '5.5' and then run an update/upgrade. For example, in Ubuntu/Debian update the MariaDB `sources.list` entry from something that looks similar to this:
```
deb http://ftp.osuosl.org/pub/mariadb/repo/5.3/ubuntu trusty main

```
To something like this:
```
deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu trusty main

```
And then run 
```
apt-get update && apt-get upgrade

```
And in Red Hat, CentOS, and Fedora, change the `baseurl` line from something that looks like this:
```
baseurl = http://yum.mariadb.org/5.3/centos6-amd64

```
To something that looks like this:
```
baseurl = http://yum.mariadb.org/5.5/centos6-amd64

```
 And then run 
```
yum update

```

 See also
--------

 * [The features in MariaDB 5.5](../what-is-mariadb-55/index)
* [Perconas guide of how to upgrade to 5.5](http://www.percona.com/doc/percona-server/5.5/upgrading_guide_51_55.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/upgrading-from-mariadb-53-to-mariadb-55/>

SQL Server Features Not Available in MariaDB
============================================

    When planning a migration between different DBMSs, one of the most important aspects to consider is that the new database system will probably miss some features supported by the old one. This is not relevant for all users. The most widely used features are supported by most DBMSs. However, it is important to make a list of unsupported features and check which of them are currently used by applications. In most cases it is possible to implement such features on the application side, or simply stop using them.

 This page has a list of SQL Server features that are not supported in MariaDB. The list is not exhaustive.

 Introduced in SQL Server versions older than 2016
-------------------------------------------------

 * Full outer joins.
* `GROUP BY CUBE` syntax.
* `MERGE` statement.
* In MariaDB, indexes are always ascending. Defining them as `ASC` or `DESC` has no effect.
	+ For single-column indexes, the performance difference between an `ORDER BY ... ASC` and `DESC` is negligible.
	+ For multiple-column indexes, an index may be unusable for certain queries because `DESC` is not supported. In some cases, a [generated column](../generated-columns/index) can be used to invert the order of an index (for example, the expression `0 - price` can be indexed to index the prices in a descending order).
* The [WITH](../with/index) syntax is currently only supported for the `SELECT` statement.
* Filtered indexes (`CREATE INDEX ... WHERE`).
* Autonomous transactions.
* User-defined types.
* Rules.
* [Triggers](../triggers/index) don't support the following features:
	+ Triggers on DDL and login.
	+ `INSTEAD OF` triggers.
	+ The `DISABLE TRIGGER` syntax.
* [Cursors](../programmatic-compound-statements-cursors/index) advanced features.
	+ Global cursors.
	+ `DELETE ... CURRENT OF`, `UPDATE ... CURRENT OF` statements: MariaDB cursors are read-only.
	+ Specifying a direction (MariaDB cursors can only advance by one row).
* Synonyms.
* Table variables.
* Queues.
* XML indexes, XML schema collection, XQuery.
* User access to system functionalities, for example:
	+ Running system commands (`xp_cmdshell()`).
	+ Sending emails (`sp_send_dbmail()`).
	+ Sending HTTP requests.
* External languages, external libraries (MariaDB only supports procedural SQL and PL/SQL).
* Negative permissions (the `DENY` command).
* Snapshot replication. See [Provisioning a Slave](../mariadb-replication-overview-for-sql-server-users/index#provisioning-a-slave).

 Introduced in SQL Server 2016
-----------------------------

 * Native data masking
* PolyBase (however, [MariaDB 10.5](../what-is-mariadb-105/index) supports accessing Amazon S3 via the [S3 storage engine](../s3-storage-engine/index) and several DBMSs via [CONNECT](../connect/index))
* R and Python services
* ColumnStore indexes. MariaDB has a storage engine called [ColumnStore](../mariadb-columnstore/index), but this is a completely different feature.

 Introduced in SQL Server 2017
-----------------------------

 * Adaptive joins
* Graph SQL

 See Also
--------

 * [SQL Server Features Implemented Differently in MariaDB](../sql-server-features-implemented-differently-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-server-features-not-available-in-mariadb/>

SQL Server Features Implemented Differently in MariaDB
======================================================

    Modern DBMSs implement several advanced features. While an SQL standard exists, the complete feature list is different for every database system. Sometimes different features allow achieving the same purpose, but with a different logic and different limitations. This is something to take into account when planning a migration.

 Some features are implemented by different DBMSs, with a similar logic and similar syntax. But there could be important differences that users should be aware of.

 This page has a list of SQL Server features that MariaDB implements in a different way, and SQL Server features for which MariaDB has an alternative feature. Minor differences are not taken into account here. The list is not exhaustive.

 SQL
---

 * The list of supported [data types](../data-types/index) is different.
* There are relevant [differences in transaction isolation levels](../mariadb-transactions-and-isolation-levels-for-sql-server-users/index#isolation-levels-and-locks).
* `SNAPSHOT` isolation level is not supported. Instead, you can use `START TRANSACTION WITH CONSISTENT SNAPSHOT` to acquire a snapshot at the beginning of the transaction. This is compatible with all isolation levels. See [How Isolation Levels are Implemented in MariaDB](../mariadb-transactions-and-isolation-levels-for-sql-server-users/index#how-isolation-levels-are-implemented-in-mariadb).
* JSON support is [different](../sql-server-and-mariadb-types-comparison/index#json).

 Indexes and Performance
-----------------------

 * Clustered indexes. In MariaDB, the physical order of rows is delegated to the storage engine. InnoDB uses the primary key as a clustered index.
* Hash indexes. Only some storage engines support `HASH` indexes.
	+ The [InnoDB](../innodb/index) storage engine has a feature called adaptive hash index, enabled by default. It means that in InnoDB all indexes are created as `BTREE`, and depending on how they are used, InnoDB could convert them from BTree to hash indexes, or the other way around. This happens in the background.
	+ The [MEMORY](../memory-storage-engine/index) storage engine uses hash indexes by default, if we don't specify the `BTREE` keyword.
	+ See [Storage Engine Index Types](../storage-engine-index-types/index) for more information.
* Query store. MariaDB allows query performance analysis using the [slow log](../slow-query-log/index) and [performance\_schema](../performance-schema/index). Some open source or commercial 3rd party tools read that information to produce statistics and make it easy to identify slow queries.

 Tables
------

 * Computed columns are called [generated columns](../generated-columns/index) in MariaDB and are created with a different syntax. See also [Implementation Differences Compared to Microsoft SQL Server](../generated-columns/index#implementation-differences-compared-to-microsoft-sql-server).
* [Temporal tables](../temporal-data-tables/index) use a different (more standard) syntax on MariaDB. In MariaDB, the history is stored in the same table as current data (but optionally in different partitions). MariaDB supports both [SYSTEM\_TIME](../temporal-data-tables/index#creating-a-system-versioned-table) and [APPLICATION\_TIME](../temporal-data-tables/index#application-time-periods).
* Hidden columns are [Invisible columns](../invisible-columns/index) in MariaDB.
* [Temporary tables](../create-table/index#create-temporary-table) are implemented and used differently.

 High Availability
-----------------

 * `NOT FOR REPLICATION`
	+ MariaDB supports [replication filters](../replication-filters/index) to exclude some tables or databases from replication
	+ It is possible to keep a table empty in a slave (or in the master) by using the [BLACKHOLE storage engine](../blackhole/index).
	+ The master can have columns that are not present in a slave (the other way around is also supported). Before using this feature, carefully read the [Replication When the Master and Slave Have Different Table Definitions](../replication-when-the-master-and-slave-have-different-table-definitions/index#different-number-or-order-of-columns) page.
	+ With MariaDB it's possible to [prevent a trigger from running on slaves](../running-triggers-on-the-slave-for-row-based-events/index).
	+ It's possible to run [events](../event-scheduler/index) without replicating them. The same applies to some administrative statements.
	+ MariaDB superusers can run statements without replicating them, by using the [sql\_log\_bin](../set-sql_log_bin/index) system variable.
	+ Constraints and triggers cannot be disabled for replication, but it is possible to drop them on the slaves.
	+ The `IF EXISTS` syntax allows one to easily create a table on the master that already exists (possibly in a different version) on a slave.
* pollinginterval option. See [Delayed Replication](../delayed-replication/index).

 Security
--------

 * The list of [permissions](../grant/index#privilege-levels) is different.
* Security policies. MariaDB allows one to achieve the same results by assigning permissions on views and stored procedures. However, this is not a common practice and it's more complicated than defining security policies. See [Other Uses of Views](../creating-using-views/index#other-uses-of-views).
* MariaDB does not support an `OUTPUT` clause. Instead, we can use [DELETE RETURNING](../delete/index) and, since [MariaDB 10.5](../what-is-mariadb-105/index), [INSERT RETURNING](../insertreturning/index) and [REPLACE RETURNING](../replacereturning/index).

 Other Features
--------------

 * Linked servers. MariaDB supports storage engines to read from, and write to, remote tables. When using the [CONNECT](../connect/index) engine, those tables could be in different DBMSs, including SQL Server.
* Job scheduler: MariaDB uses an [event scheduler](../event-scheduler/index) to schedule events instead.

 See Also
--------

 * [SQL Server features not available in MariaDB](../sql-server-features-not-available-in-mariadb/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-server-features-implemented-differently-in-mariadb/>

MariaDB Features Not Available in SQL Server
============================================

     Some MariaDB features are not available in SQL Server.

 At first glance, it is not important to know about those features to migrate from SQL Server to MariaDB. However, this is not the case. Using MariaDB features that are not in SQL Server allows one to obtain more advantages from the migration, getting the most from MariaDB.

 This page has a list of MariaDB features that are not supported in SQL Server. The list is not exhaustive.

 Plugin Architecture
-------------------

 * [Storage engines](../storage-engines/index).
* [Authentication plugins](../authentication-plugins/index).
* [Encryption plugins](../key-management-and-encryption-plugins/index).
* [ColumnStore](../mariadb-columnstore/index) is a columnar storage engine designed to scale horizontally. It runs on a specific edition of MariaDB, so currently it cannot be used in combination with other engines.

 SQL
---

 * The [sql\_mode](../sql-mode/index) variable determines in which cases an SQL statement should fail with an error, and in which cases it should succeed with a warning even if it is not entirely correct. For example, when a statement tries to insert a string in a column which is not big enough to contain it, it could fail, or it could insert a truncated string and emit a warning. It is a tradeoff between reliability and flexibility.
	+ [SQL\_MODE=MSSQL](../sql_modemssql/index) allows one to use a small subset of SQL Server proprietary syntax.
* The [`CREATE ... IF EXISTS`, `CREATE OR REPLACE`, `DROP ... IF NOT EXISTS`](../syntax-differences-between-mariadb-and-sql-server/index#if-exists-if-not-exists-or-replace) options are supported for most [DDL statements](../data-definition/index).
* [SHOW](../syntax-differences-between-mariadb-and-sql-server/index#show-statements) statements.
* [SHOW CREATE](../syntax-differences-between-mariadb-and-sql-server/index#show-create-statements) statements.
* [SHOW PROCESSLIST](../show-processlist/index) and [PERFORMANCE\_SCHEMA THREAD table](../performance-schema-threads-table/index) provide much richer information, compared to SQL Server `sp_who()` and `sp_who2()` procedures.
* [CHECKSUM TABLE](../checksum-table/index) statement.
* [PL/SQL support](../sql_modeoracle-from-mariadb-103/index) (only for stored procedures and stored functions).
* Row constructors.
* `BEFORE` [triggers](../triggers/index).
* [HANDLER](../handler-commands/index) statements, to scroll table rows ordered by an index or in their physical order.
* [DO](../do/index) statement, to call functions without returning a result set.
* [BENCHMARK()](../benchmark/index) function, to measure the speed of an SQL expression.

 See also [Syntax Differences between MariaDB and SQL Server](../syntax-differences-between-mariadb-and-sql-server/index).

 Types
-----

 * [Character sets and collations](../character-sets/index) don't depend on column type. They can be set globally, or at database, table or column level.
* Columns may use non-constant expressions as the [DEFAULT](../create-table/index#default-column-option) value. [TIMESTAMP](../timestamp/index) columns may have a `DEFAULT` value.
* [UNSIGNED](../numeric-data-type-overview/index#signed-unsigned-and-zerofill) numeric types.
* [Dynamic columns](../dynamic-columns/index) (note that JSON is usually preferred to this feature).

 See also [SQL Server and MariaDB Types Comparison](../sql-server-and-mariadb-types-comparison/index).

 ### JSON

 For compatibility with some other database systems, MariaDB supports the [JSON](../json-data-type/index) pseudo-type. However, it is just an alias for:

 `LONGTEXT CHECK (JSON_VALID(column_name))`

 [JSON\_VALID()](../json_valid/index) is the MariaDB equivalent of SQL Server's `ISJSON()`.

 Features
--------

 * [Flashback](../flashback/index) functionality allows one to "undo" the changes that happened after a certain point in time.
* [Partitioned tables](../partitioning-tables/index) support the following features:
	+ Tables can be partitioned based on [multiple columns](../range-columns-and-list-columns-partitioning-types/index).
	+ Several [partitioning types](../partitioning-overview/index#partitioning-types) are available.
	+ Subpartitions.
* [Progress reporting](../progress-reporting/index) for some typically expensive statements.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-features-not-available-in-sql-server/>

Setting Up MariaDB for Testing for SQL Server Users
===================================================

    This page contains links and hints to setup MariaDB for testing. The page is designed for SQL Server users, assuming that they are mostly familiar with Windows and they are not familiar with MariaDB.

 Choosing a MariaDB Version
--------------------------

 As a general rule, for new installations it's better to choose the [latest Generally Available (GA) version](../download-latest-releases/index).

 If you need a feature that is only present in a version that is not yet production-ready, and the project will surely not go to production before that version is GA, it could make sense to use a non-GA version. In this case however, keep in mind that you are using a version that is only suitable for testing.

 If you need to work with an existing production instance, you should of course use the same version in testing. However, deprecated versions should not be used in production, because they could be exposed to vulnerabilities that will never be fixed. See [deprecation policies](../deprecation-policy/index) if you are not sure about the version you are using.

 Setting up MariaDB on Windows
-----------------------------

 There are two different ways to use MariaDB on Windows natively: using Zip packages or MSI packages.

 In both cases, 32-bit platforms are still supported.

 Check the page [Installation issues on Windows](../installation-issues-on-windows/index) to verify if current versions of MariaDB have troubles on Windows. More generally, it is a good idea to check the [Troubleshooting Installation Issues](../troubleshooting-installation-issues/index) category.

 ### ZIP Packages

 Windows users don't necessarily need to install MariaDB to use it. They can download ready-to-use ZIP packages to avoid any change in the system (except for downloading MariaDB and writing databases on the disk). This is very useful for testing without risking some undesired side effect on the machine in use. And it avoids the hassle of installing Docker or virtual machines.

 
**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Starting with [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/), it is necessary to run [mysql\_install\_db.exe](../mysql_install_dbexe/index) to install the data directory.

 
The drawback is that MariaDB will need to be started and stopped from the command line.

 See [Installing MariaDB Windows ZIP Packages](../installing-mariadb-windows-zip-packages/index).

 ### MSI Packages

 MSI packages provide a friendly graphical interface to install MariaDB. The installation process is easy but flexible. For example, the user can decide which components to install, whether to install it as a service or not, and if networking should be enabled. An interface to uninstall MariaDB is also provided.

 See [Installing MariaDB MSI Packages on Windows](../installing-mariadb-msi-packages-on-windows/index).

 Installing MariaDB on Docker
----------------------------

 Docker is a container platform that runs natively on Linux. A Docker image is a representation of a basic Linux system, which usually runs a single process - in our case, that process is MariaDB. A container is an instance of an image, which can be created or destroyed instantaneously. Once a container is started, it can be used just like a normal system.

 Docker runs on all major operating systems. On Windows and MacOS it runs on a Linux virtual machine, but this additional complexity is transparent for the end user.

 Docker's characteristics makes it optimal to test MariaDB functionalities without wasting time on installation and without making changes to the host system. However, it is not ideal to test MariaDB performance.

 See [Installing and Using MariaDB via Docker](../installing-and-using-mariadb-via-docker/index).

 Reinitializing MariaDB Data Directory
-------------------------------------

 While experimenting with MariaDB, you could end up with an unusable installation. This occurs for example if you deliberately delete files that you shouldn't delete. If it happens, there is no need to uninstall and reinstall MariaDB. Instead, you can simply delete the contents of the data directory and run [mariadb-install-db](../mariadb-install-db/index). The program will recreate your system tables and the essential files.

 To know where your data directory is, check the [datadir](../server-system-variables/index#datadir) system variable.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-up-mariadb-for-testing-for-sql-server-users/>

Syntax Differences between MariaDB and SQL Server
=================================================

    This article contains a non-exhaustive list of syntax differences between MariaDB and SQL Server, and is written for SQL Server users that are unfamiliar with MariaDB.

 Compatibility Features
----------------------

 Some features are meant to improve syntax and semantics compatibility between MariaDB versions, between MariaDB and MySQL, and between MariaDB and other DBMSs. This section focuses on compatibility between MariaDB and SQL Server.

 ### sql\_mode and old\_mode

 SQL semantics and syntax, in MariaDB, are affected by the [sql\_mode](../sql_mode/index) variable. Its value is a comma-separated list of flags, and each of them, if specified, affects a different aspect of SQL syntax and semantics.

 A particularly important flag for users familiar with SQL Server is [MSSQL](../sql_modemssql/index).

 sql\_mode can be changed locally, in which case it only affects the current session; or globally, in which case it will affect all new connections (but not the connections already established). sql\_mode must be assigned a comma-separated list of flags.

 A usage example:

 
```
# check the current global and local sql_mode values
SELECT @@global.sql_mode;
SELECT @@session.sql_mode;
# empty sql_mode for all usaers
SET GLOBAL sql_mode = '';
# add MSSQL flag to the sql_mode for the current session
SET SESSION sql_mode = CONCAT(sql_mode, ',MSSQL');

```

[old\_mode](../old-mode/index) is very similar to sql\_mode, but its purpose is to provide compatibility with older MariaDB versions. Its flags shouldn't affect compatibility with SQL Server (though it is theoretically possible that some of them do, as a side effect).

 ### Executable Comments

 MariaDB supports [executable comments](../comment-syntax/index#executable-comment-syntax). These are designed to write generic queries that are only executed by MariaDB, and optionally only certain versions.

 The following examples show how to insert SQL code that will be ignored by SQL Server but executed by MariaDB, or some of its versions.

 * Executed by MariaDB and MySQL (see below):

 
```
SELECT * FROM tab /*! FORCE INDEX (idx_a) */ WHERE a = 1 OR b = 2;

```

* Executed by MariaDB only:

 
```
SELECT * /*M! , @in_transaction */ FROM tab;

```

* Executed by MariaDB starting from version 10.0.5:

 
```
DELETE FROM user WHERE id = 100 /*!M100005 RETURNING email */;

```

As explained in the [Understanding MariaDB Architecture](../understanding-mariadb-architecture/index) page, MariaDB was initially forked from MySQL. At that time, executable comments were already supported by MySQL. This is why the `/*! ... */` syntax is supported by both MariaDB and MySQL. But because MariaDB also supports specific syntax not supported by MySQL, it added the `/*M! ... */` syntax.

 Generic Syntax
--------------

 Here we discuss some differences between MariaDB and SQL Server syntax that may affect any user, as well as some hints to make queries compatible with a reasonable amount of work.

 ### Delimiters

 SQL Server uses two different terminators:

 * The *batch terminator* is the `go` command. It tells Microsoft clients to send the text we typed to SQL Server.
* The *query terminator* is a semicolon (`;`) and it tells SQL Server where a query ends.

 It is rarely necessary to use `;` in SQL Server. It is required for certain common table expressions, for example.

 But the same doesn't apply to MariaDB. **Normally, with MariaDB you only use `;`.**

 However, MariaDB also has some situations where you want to use a `;` but you don't want the [mariadb](../mariadb-command-line-client/index) command-line client to send the query yet. This can be done in any situation, but it is particularly useful when creating [stored routines](../stored-routines/index) or using [BEGIN NOT ATOMIC](../begin-end/index).

 The reason is better explained with an example:

 
```
CREATE PROCEDURE p()
BEGIN
    SELECT * FROM t1;
    SELECT * FROM t2;
END;

```

If we enter this procedure in this way in the `mariadb` client, as soon as we type the first `;` (after the first `SELECT`) and press enter, the statement will be sent. MariaDB will try to parse it, and will return an error.

 To avoid this, `mariadb` implements the [DELIMITER](../delimiters/index) statement. This client statement is never sent to MariaDB. Instead, the client uses it to find out when the typed query should be sent. Let's correct the above example:

 
```
DELIMITER ||

CREATE PROCEDURE p()
BEGIN
    SELECT * FROM t1;
    SELECT * FROM t2;
END;

DELIMITER ;

```

### Names

 In MariaDB, most [names](../identifier-names/index) have a maximum length of 64 characters. When migrating an SQL Server database to MariaDB, check if some names exceed this limit (SQL Server maximum length is 128).

 By default, MariaDB names are case-sensitive if the operating system has case-sensitive file names (Linux), and case-insensitive if the operating system is case-insensitive (Windows). SQL Server is case-insensitive by default on all operating systems.

 When migrating a SQL Server database to MariaDB on Linux, to avoid problems you may want to set the [lower\_case\_table\_names](../server-system-variables/index#lower_case_table_names) system variable to 1, making table names, database names and aliases case-insensitive.

 Names can be quoted inside backtick characters (```). This character can be used in names, in which case it should be doubled. By default this is the only way to quote names.

 To also enable the use of double quotes (`"`), modify sql\_mode adding the `ANSI_QUOTES` flag. This is the equivalent of setting [QUOTED\_IDENTIFIER](https://docs.microsoft.com/en-us/sql/t-sql/statements/set-quoted-identifier-transact-sql?view=sql-server-ver15) ON in SQL Server.

 To also enable the use of SQL Server style quotes (`[` and `]`), modify sql\_mode adding the `MSSQL` flag.

 The case-sensitivity of stored procedures and functions is never a problem, as they are case-insensitive in SQL Server.

 ### Quoting Strings

 In SQL Server, by default strings can only be quoted with single-quotes (`'`), and to use a double quote in a string it should be doubled (`''`). This also works by default in MariaDB.

 SQL Server also allows to use double quotes (`"`) to quote strings. This works by default in MariaDB, but as mentioned before it won't work if sql\_mode contains the `ANSI_QUOTES` flag.

 ### NULL

 The default semantics of [NULL](../null-values/index) in SQL Server and MariaDB is the same, by default.

 However, SQL Server allows one to change it globally with [SET ANSI\_NULLS OFF](https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql), or at database level with [ALTER DATABASE](https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql).

 There is no way to achieve exactly the same result in MariaDB. To perform NULL-safe comparisons in MariaDB, one should replace the [=](../equal/index) operator with the [<=>](../null-safe-equal/index) operator.

 Also, note that MariaDB doesn't support the `UNKNOWN` pseudo-value. An expression like `NULL OR 0` returns `NULL` in MariaDB.

 ### LIKE

 In MariaDB, [LIKE](../like/index) expressions only have two characters with special meanings: `%` and `_`. These two characters have the same meanings they have in SQL Server.

 The additional characters recognized by SQL Server (`[`, `]` and `^`) are part of regular expressions. MariaDB supports the [REGEXP](../regexp/index) operator, that supports the full regular expressions syntax.

 Data Definition Language
------------------------

 Here we discuss some DDL differences that database administrators will want to be aware of.

 While this section is meant to highlight the most noticeable DDL differences between MariaDB and SQL Server, there are many others, both in the syntax and in the semantics. See the [ALTER](../alter/index) statement documentation.

 ### Altering Tables Online

 Altering tables online can be a problem, especially when the tables are big and we don't want to cause a disruption.

 MariaDB offers the following solutions to help:

 * The [ALTER TABLE ... ALGORITHM](../alter-table/index#algorithm) clause allows one to specify which algorithm should be used to run a certain operation. For example `INPLACE` tells MariaDB not to create a table copy (perhaps because we don't have enough disk space), and `INSTANT` tells MariaDB to execute the operation instantaneously. Not all algorithms are supported for certain operations. If the algorithm we've chosen cannot be used, the [ALTER TABLE](../alter-table/index) statement will fail with an error.
* The [ALTER TABLE ... LOCK](../alter-table/index#alock) clause allows one to specify which lock type should be used. For example `NONE` tells MariaDB to avoid any lock on the table, and `SHARED` only allows one to acquire a share lock. If the operation requires a lock that is more strict than the one we are requesting, the [ALTER TABLE](../alter-table/index) statement will fail with an error. Sometimes this happens because the `LOCK` level we want is not available for the specified `ALGORITHM`.

 To find out which operations require a table copy and which lock levels are necessary, see [InnoDB Online DDL Overview](../innodb-online-ddl-overview/index).

 An `ALTER TABLE` can be queued because a long-running statement (even a `SELECT`) required a [metadata lock](../metadata-locking/index). Since this may cause troubles, sometimes we want the operation to simply fail if the wait is too long. This can be achieved with the [WAIT and NOWAIT](../wait-and-nowait/index) clauses, whose syntax is a bit different from SQL Server.

 SQL Server `WITH ONLINE = ON` is equivalent to MariaDB `LOCK = NONE`. However, note that [most ALTER TABLE statements](../innodb-online-ddl-operations-with-the-instant-alter-algorithm/index) support `ALGORITHM = INSTANT`, which is non-blocking and much faster (almost instantaneous, as the syntax suggests).

 ### IF EXISTS, IF NOT EXISTS, OR REPLACE

 Most DDL statements, including [ALTER TABLE](../alter-table/index), support the following syntax:

 * `DROP IF EXISTS`: A warning (not an error) is produced if the object does not exist.
* `OR REPLACE`: If the object exists, it is dropped and recreated; otherwise it is created. This operation is atomic, so at no point in time does the object not exist.
* `CREATE IF NOT EXISTS`: If the object already exists, a warning (not an error) is produced. The object will not be replaced.

 These statements are functionally similar (but less verbose) than SQL Server snippets similar to the following:

 
```
IF NOT EXISTS (
        SELECT name
            FROM sysobjects
            WHERE name = 'my_table' AND xtype = 'U'
    )
    CREATE TABLE my_table (
        ...
    )
go

```

### Altering Columns

 With SQL Server, the only syntax to alter a table column is `ALTER TABLE ... ALTER COLUMN`. MariaDB provides more [ALTER TABLE](../alter-table/index) commands to obtain the same result:

 * [CHANGE COLUMN](../alter-table/index#change-column) allows one to perform any change by specifying a new column definition, including the name.
* [MODIFY COLUMN](../alter-table/index#modify-column) allows any change, except renaming the column. This is a slightly simpler syntax that we can use when we don't want to change a column name.
* [ALTER COLUMN](../alter-table/index#alter-column) allows one to change or drop the `DEFAULT` value.
* [RENAME COLUMN](../alter-table/index#rename-column) allows one to only change the column name.

 Using a more specific syntax is less error-prone. For example, by using `ALTER TABLE ... ALTER COLUMN` we will not accidentally change the data type.

 The word `COLUMN` is usually optional, except in the case of `RENAME COLUMN`.

 ### SHOW Statements

 MariaDB supports [SHOW](../show/index) statements to quickly list all objects of a certain type (tables, views, triggers...). Most `SHOW` statements support a `LIKE` clause to filter data. For example, to list the tables in the current database whose name begins with 'wp\_':

 
```
SHOW TABLES LIKE 'wp\_%';

```

This is the equivalent of this query, which would work on both MariaDB and SQL Server:

 
```
SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME LIKE 'wp\_';

```

### SHOW CREATE Statements

 In general, for each `CREATE` statement MariaDB also supports a `SHOW CREATE` statement. For example there is a [SHOW CREATE TABLE](../show-create-table/index) that returns the [CREATE TABLE](../create-table/index) statement that can be used to recreate a table.

 Though SQL Server has no way to show the DDL statement to recreate an object, `SHOW CREATE` statements are functionally similar to `sp_helptext()`.

 ### Database Comments

 MariaDB does not support extended properties. Instead, it supports a `COMMENT` clause for most [CREATE](../create/index) and [ALTER](../alter/index) statements.

 For example, to create and then change a table comment:

 
```
CREATE TABLE counter (
    c INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
)
    COMMENT 'Monotonic counter'
;
ALTER TABLE counter COMMENT
    'Counter. It can contain many values, we only care about the max';

```

Comments can be seen with `SHOW CREATE` statements, or by querying `information_schema` tables. For example:

 
```
SELECT TABLE_COMMENT
    FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 'counter';
+-----------------------------------------------------------------+
| TABLE_COMMENT                                                   |
+-----------------------------------------------------------------+
| Counter. It can contain many values, we only care about the max |
+-----------------------------------------------------------------+


```

### Error Handling

 MariaDB [SHOW ERRORS](../show-errors/index) and [SHOW WARNINGS](../show-warnings/index) statements can be used to show errors, or warning and errors. This is convenient for clients, but stored procedures cannot work with the output of these commands.

 Instead, inside stored procedures you can:

 * Use the [GET DIAGNOSTICS](../get-diagnostics/index) command to assign error properties to variables. This is the equivalent of using SQL Server functions like `ERROR_NUMBER()` or `ERROR_STATE()`.
* Add a [DECLARE HANDLER](../declare-handler/index) block to handle all errors, a class of errors, or a specific error. This is the equivalent of SQL Server `TRY ... CATCH`.
* An error or warning can be generated on purpose using [SIGNAL](../signal/index). Inside a `DECLARE HANDLER` block, [RESIGNAL](../resignal/index) can be used to issue the error again, and interrupt the execution of the block. These are the equivalents of SQL Server `RAISERROR()`.

 Administration
--------------

 Administration and maintenance commands in MariaDB use different syntax to SQL Server.

 * [OPTIMIZE TABLE](../optimize-table/index) rebuilds table data and indexes. It can be considered as the MariaDB equivalent of SQL Server's `ALTER INDEX REBUILD`. See [Defragmenting InnoDB Tablespaces](../defragmenting-innodb-tablespaces/index) for more information. This statement is always locking. It supports [WAIT and NOWAIT](../wait-and-nowait/index) syntax,
* MariaDB has an [ANALYZE TABLE](../analyze-table/index) command, which is an equivalent of `UPDATE STATISTICS`.

 BULK INSERT
-----------

 MariaDB has no `BULK INSERT` statement. Instead, it supports:

 * [LOAD DATA INFILE](../load-data-infile/index) to load data from files in CSV or similar formats;
* [LOAD XML INFILE](../load-xml/index) to load data from XML files.

 See also [How to Quickly Insert Data Into MariaDB](../how-to-quickly-insert-data-into-mariadb/index).

 See Also
--------

 * [SQL Server and MariaDB Types Comparison](../sql-server-and-mariadb-types-comparison/index)
* [MariaDB Transactions and Isolation Levels for SQL Server Users](../mariadb-transactions-and-isolation-levels-for-sql-server-users/index)
* [SQL\_MODE=MSSQL](../sql_modemssql/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/syntax-differences-between-mariadb-and-sql-server/>

SQL Server and MariaDB Types Comparison
=======================================

    This page helps to map each SQL Server type to the matching MariaDB type.

 Numbers
-------

 In MariaDB, numeric types can be declared as `SIGNED` or `UNSIGNED`. By default, numeric columns are `SIGNED`, so not specifying either will not break compatibility with SQL Server.

 When using `UNSIGNED` values, there is a potential problem with subtractions. When subtracting an `UNSIGNED` valued from another, the result is usually of an `UNSIGNED` type. But if the result is negative, this will cause an error. To solve this problem, we can enable the [NO\_UNSIGNED\_SUBTRACTION](../sql-mode/index#no_unsigned_subtraction) flag in sql\_mode.

 For more information see [Numeric Data Type Overview](../numeric-data-type-overview/index).

 ### Integer Numbers

 


| SQL Server Types | Size (bytes) | MariaDB Types | Size (bytes) | Notes |
| --- | --- | --- | --- | --- |
| `tinyint` | 1 | [TINYINT](../tinyint/index) | 1 |  |
| `smallint` | 2 | [SMALLINT](../smallint/index) | 2 |  |
|  |  | [MEDIUMINT](../mediumint/index) | 3 | Takes 3 bytes on disk, but 4 bytes in memory |
| `int` | 1 | [INT](../int/index) / [INTEGER](../integer/index) | 4 |  |
| `bigint` | 8 | [BIGINT](../bigint/index) | 8 |  |

 
### Real Numbers (approximated)

 


| SQL Server Types | Precision | Size | MariaDB Types | Size |
| --- | --- | --- | --- | --- |
| `float(1-24)` | 7 digits | 4 | [FLOAT(0-23)](../float/index) | 4 |
| `float(25-53)` | 15 digist | 8 | [FLOAT(24-53)](../float/index) | 8 |

 
MariaDB supports an alternative syntax: `FLOAT(M, D)`. M is the total number of digits, and D is the number of digits after the decimal point.

 See also: [Floating-point Accuracy](../floating-point-accuracy/index).

 #### Aliases

 In SQL Server `real` is an alias for `float(24)`.

 In MariaDB [DOUBLE](../double/index), and [DOUBLE PRECISION](../double-precision/index) are aliases for `FLOAT(24-53)`.

 Normally, `REAL` is also a synonym for `FLOAT(24-53)`. However, the [sql\_mode](../sql-mode/index) variable can be set with the `REAL_AS_FLOAT` flag to make `REAL` a synonym for `FLOAT(0-23)`.

 ### Real Numbers (Exact)

 


| SQL Server Types | Precision | Size (bytes) | MariaDB Types | Precision | Size (bytes) |
| --- | --- | --- | --- | --- | --- |
| `decimal` | 0 - 38 | Up to 17 | [DECIMAL](../decimal/index) | 0 - 38 | [See table](../data-type-storage-requirements/index#decimal) |

 
MariaDB supports this syntax: `DECIMAL(M, D)`. M and D are both optional. M is the total number of digits (10 by default), and D is the number of digits after the decimal point (0 by default). In SQL Server, defaults are 18 and 0, respectively. The reason for this difference is that SQL standard imposes a default of 0 for D, but it leaves the implementation free to choose any default for M.

 SQL Server `DECIMAL` is equivalent to MariaDB `DECIMAL(18)`.

 #### Aliases

 The following [aliases](../dec-numeric-fixed/index) for `DECIMAL` are recognized in both SQL Server and MariaDB: `DEC`, `NUMERIC`. MariaDB also allows one to use `FIXED`.

 ### Money

 SQL Server `money` and `smallmoney` types represent real numbers guaranteeing a very low level of approximation (five decimal digits are accurate), optionally associated with one of the supported currencies.

 MariaDB doesn't have monetary types. To represent amounts of money:

 * Store the currency in a separate column, if necessary. It's possible to use a foreign key to a currencies table, or the [ENUM](../enum/index) type.
* Use a non-approximated type:
	+ [DECIMAL](../decimal/index) is very convenient, as it allows one to store the number as-is. But calculations are potentially slower.
	+ An integer type is faster for calculations. It is possible to store, for example, the amount of money multiplied by 100.

 There is a small incompatibility that users should be aware about. `money` and `smallmoney` are accurate to about 4 decimal digits. This means that, if you use enough decimal digits, operations on these types may produce different results than the results they would produce on MariaDB types.

 ### Bits

 The [BIT](../bit/index) type is supported in MariaDB. Its maximum size is `BIT(64)`. The `BIT` type has a fixed length. If we insert a value which requires less bits than the ones that are allocated, zero-bits are padded on the left.

 In MariaDB, binary values can be written in one of the following ways:

 * `b'value'`
* `0value` where `value` is a sequence of 0 and 1 digits. Hexadecimal syntax can also be used. For more details, see [Binary Literals](../binary-literals/index) and [Hexadecimal Literals](../hexadecimal-literals/index).

 MariaDB and SQL Server have different sets of bitwise operators. See [Bit Functions and Operators](../bit-functions-and-operators/index).

 BOOLEAN Pseudo-Type
-------------------

 In SQL Server, it is common to use `bit` to represent boolean values. In MariaDB it is possible to do the same, but this is not a common practice.

 A column can also be defined as [BOOLEAN](../boolean/index) or `BOOL`, which is just a synonym for [TINYINT](../tinyint/index). `TRUE` and `FALSE` keywords also exist, but they are synonyms for 1 and 0. To understand what this implies, see [Boolean Literals](../sql-language-structure-boolean-literals/index).

 In MariaDB `'True'` and `'False'` are always strings.

 Date and Time
-------------

 


| SQL Server Types | Range | Precision | Size (bytes) | MariaDB Types | Range | Size (bytes) | Precision | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `date` | 0001-01-01 - 9999-12-31 | 3 | / | [DATE](../date/index) | 0001-01-01 - 9999-12-31 | 3 | / | They cover the same range |
| `datetime` | 1753-01-01 - 9999-12-31 | 8 | 0 to 3, rounded | [DATETIME](../datetime/index) | 001-01-01 - 9999-12-31 | 8 | 0 to 6 | MariaDB values are not approximated, see below. |
| `datetime2` | 001-01-01 - 9999-12-31 | 8 | 6 to 8 | [DATETIME](../datetime/index) | 001-01-01 - 9999-12-31 | 8 | 0 to 6 | MariaDB values are not approximated, see below. |
| `smalldatetime` |  |  |  | [DATETIME](../datetime/index) |  |  |  |  |
| `datetimeoffset` |  |  |  | [DATETIME](../datetime/index) |  |  |  |  |
| `time` |  |  |  | [TIME](../time/index) |  |  |  |  |

 
You may also consider the following MariaDB types:

 * [TIMESTAMP](../timestamp/index) has little to do with SQL Server's `timestamp`. In MariaDB it is the number of seconds elapsed since the beginning of 1970-01-01, with a decimal precision up to 6 digits (0 by default). The value can optionally be automatically set to the current timestamp on insert, on update, or both. It is not meant to be a unique row identifier.
* [YEAR](../year/index) is a 1-byte type representing years between 1901 and 2155, as well as 0000.

 ### Zero Values

 MariaDB allows a special value where all the parts of a date are zeroes: `'0000-00-00'`. This can be disallowed by setting [sql\_mode=NO\_ZERO\_DATE](../sql-mode/index#no_zero_date).

 It is also possible to use values where only some date parts are zeroes, for example `'1994-01-00'` or `'1994-00-00'`. These values can be disallowed by setting [sql\_mode=NO\_ZERO\_IN\_DATE](../sql-mode/index#no_zero_in_date). They are not affected by `NO_ZERO_DATE`.

 ### Syntax

 Several different date formats are understood. Typically used formats are `'YYYY-MM-DD'` and `YYYYMMDD`. Several separators are accepted.

 The syntax defined in standard SQL and ODBC are understood - for example, `DATE '1994-01-01'` and `{d '1994-01-01'}` . Using these eliminates possible ambiguities in contexts where a temporal value could be interpreted as a string or as an integer.

 See [Date and Time Literals](../date-and-time-literals/index) for the details.

 ### Precision

 For temporal types that include a day time, MariaDB allows a precision from 0 to 6 (microseconds), 0 being the default. The subsecond part is never approximated. It adds up to 3 bytes. See [Data Type Storage Requirements](../data-type-storage-requirements/index#microseconds) for the details.

 String and Binary
-----------------

 ### Binary Strings

 


| SQL Server Types | Size (bytes) | MariaDB Types | Notes |
| --- | --- | --- | --- |
| `binary` | 1 to 8000 | [VARBINARY](../varbinary/index) or [BLOB](../blob-and-text-data-types/index) | See below for `BLOB` types |
| `varbinary` | 1 to 8000 | [VARBINARY](../varbinary/index) or [BLOB](../blob-and-text-data-types/index) | See below for `BLOB` types |
| `image` | 2^31-1 | [VARBINARY](../varbinary/index) or [BLOB](../blob-and-text-data-types/index) | See below for `BLOB` types |

 
The `VARBINARY` type is similar to `VARCHAR`, but stores binary byte strings, just like SQL Server `binary` does.

 For large binary strings, MariaDB has four `BLOB` types, with different sizes. See [BLOB and TEXT Data Types](../blob-and-text-data-types/index) for more information.

 ### Character Strings

 One important difference between SQL Server and MariaDB is that **in MariaDB character sets do not depend on types and collations**. Character sets can be set at database, table or column level. If this is not done, the default character sets applies, which is specified by the [character\_set\_server](../server-system-variables/index#character_set_server) system variable.

 To create a MariaDB table that is identical to a SQL Server table, **it may be necessary to specify a character set for each string column**. However, in many cases using UTF-8 will work.

 


| SQL Server Types | Size (bytes) | MariaDB Types | Size (bytes) | Character set |
| --- | --- | --- | --- | --- |
| `char` | 1 to 8000 | [CHAR](../char/index) | 0 to 255 | `utf8mb4` (1, 4) |
| `varchar` | 1 to 8000 | [VARCHAR](../varchar/index) | 0 to 65,532 (2) | `utf8mb4` (1) |
| `text` | 2^31-1 | [TEXT](../blob-and-text-data-types/index) | 2^31-1 | `ucs2` |
| `nchar` | 2 to 8000 | [CHAR](../char/index) | 0 to 255 | `utf16` or `ucs2` (3, 4) |
| `nvarchar` | 2 to 8000 | [VARCHAR](../varchar/index) | 0 to 65,532 (2) (5) | `utf16` or `ucs2` (1) (3) |
| `ntext` | 2^30 - 1 | [TEXT](../blob-and-text-data-types/index) | 2^31-1 | `ucs2` |

 
**Notes:**

 1) If SQL Server uses a non-unicode collation, a subset of UTF-8 is used. So it is possible to use a smaller character set on MariaDB too.

 2) [InnoDB](../innodb/index) has a maximum row length of 65,535 bytes. [TEXT](../blob-and-text-data-types/index) columns do not contribute to the row size, because they are stored separately (except for the first 12 bytes).

 3) In SQL Server, UTF-16 is used if data contains Supplementary Characters, otherwise UCS-2 is used. If not sure, use `utf16` in MariaDB.

 4) In SQL Server, the value of `ANSI_PADDING` determines if `char` values should be padded with spaces to their maximum length. In MariaDB, this depends on the [PAD\_CHAR\_TO\_FULL\_LENGTH](../sql-mode/index#pad_char_to_full_length) sql\_mode flag.

 5) See JSON, below.

 SQL Server Special Types
------------------------

 ### rowversion

 MariaDB does not have the `rowversion` type.

 If the only purpose is to check if a row has been modified since its last read, a [TIMESTAMP](../timestamp/index) column can be used instead. Its default value should be `ON UPDATE CURRENT_TIMESTAMP`. In this way, the timestamp will be updated whenever the column is modified.

 A way to preserve much more information is to use a [temporal table](../temporal-data-tables/index). Past versions of the row will be preserved.

 ### sql\_variant

 MariaDB does not support the `sql_variant` type.

 MariaDB is quite flexible about implicit and explicit [type conversions](../type-conversion/index). Therefore, for most cases storing the values as a string should be equivalent to using `sql_variant`.

 Be aware that the maximum length of an `sql_variant` value is 8,000 bytes. In MariaDB, you may need to use `TINYBLOB`.

 ### uniqueidentifier

 While MariaDB does not support the `uniqueidentifier` type, the [UUID](../uuid-data-type/index) type can typically be used for the same purpose.

 `uniqueidentifier` columns contain 16-bit GUIDs. MariaDB UUID columns store UUIDv1 values (128 bits).

 The UUID type was implemented in [MariaDB 10.7](../what-is-mariadb-107/index). On older versions, you can generate unique values with the [UUID()](../uuid/index) or [UUID\_SHORT()](../uuid_short/index) functions, and store them in `BIT(128)` or `BIT(64)` columns, respectively.

 ### xml

 MariaDB does not support the `xml` type.

 XML data can be stored in string columns. MariaDB supports several XML functions.

 ### JSON

 With SQL Server, typically JSON documents are stored in `nvarchar` columns in a text form.

 MariaDB has a [JSON](../json-data-type/index) pseudo-type that maps to [LONGTEXT](../longtext/index). However, from [MariaDB 10.5](../what-is-mariadb-105/index) the `JSON` pseudo-type also checks that the value is valid a JSON document.

 MariaDB supports different JSON functions than SQL Server. MariaDB currently has more functions, and SQL Server syntax will not work. See [JSON functions](../json-functions/index) for more information.

 MariaDB Specific Types
----------------------

 The following types are supported by MariaDB and don't have a direct equivalent in SQL Server. If you are migrating your database to MariaDB, you can consider using these types.

 * [INET6](../inet6/index) - IPv6 addresses.
* [INET4](../inet4/index) - IPv4 addresses.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sql-server-and-mariadb-types-comparison/>

MariaDB Transactions and Isolation Levels for SQL Server Users
==============================================================

    This page explains how transactions work in MariaDB, and highlights the main differences between MariaDB and SQL Server transactions.

 Note that XA transactions are handled in a completely different way and are not covered in this page. See [XA Transactions](../xa-transactions/index).

 Missing Features
----------------

 These SQL Server features are not available in MariaDB:

 * Autonomous transactions;
* Distributed transactions.

 Transactions, Storage Engines and the Binary Log
------------------------------------------------

 In MariaDB, transactions are optionally implemented by [storage engines](../storage-engines/index). The default storage engine, [InnoDB](../innodb/index), fully supports transactions. Other transactional storage engines include [MyRocks](../myrocks/index) and [TokuDB](../tokudb/index). Most storage engines are not transactional, therefore they should not considered general purpose engines.

 Most of the information in this page refers to generic MariaDB server behaviors or InnoDB. For [MyRocks](../myrocks/index) and [TokuDB](../tokudb/index) please check the proper KnowledgeBase sections.

 Writing into a non-transactional table in a transaction can still be useful. The reason is that a [metadata lock](../metadata-locking/index) is acquired on the table for the duration of the transaction, so that [ALTER TABLEs](../alter-table/index) are queued.

 It is possible to write into transactional and non-transactional tables within a single transaction. It is important to remember that non-transactional engines will have the following limitations:

 * In case of rollback, changes to non-transactional engines won't be undone. We will receive a warning `1196` which reminds us of this.
* Data in transactional tables cannot be changed by other connections in the middle of a transaction, but data in non-transactional tables can.
* In case of a crash, committed data written into a transactional table can always be recovered, but this is not necessarily true for non-transactional tables.

 If the [binary log](../binary-log/index) is enabled, writing into different transactional storage engines in a single transaction, or writing into transactional and non-transactional engines inside the same transaction, implies some extra work for MariaDB. It needs to perform a two-phase commit to be sure that changes to different tables are logged in the correct order. This affects the performance.

 Transaction Syntax
------------------

 The first read or write to an InnoDB table starts a transaction. No data access is possible outside a transaction.

 By default [autocommit](../server-system-variables/index#autocommit) is on, which means that the transaction is committed automatically after each SQL statement. We can disable it, and manually commit transactions:

 
```
SET SESSION autocommit = 0;
SELECT ... ;
DELETE ... ;
COMMIT;

```

Whether autocommit is enabled or not, we can start transactions explicitly, and they will not be automatically committed:

 
```
START TRANSACTION;
SELECT ... ;
DELETE ... ;
COMMIT;

```

`BEGIN` can also be used to start a transaction, but does not work in stored procedures.

 Read-only transactions are also available using `START TRANSACTION READ ONLY`. This is a small performance optimization. MariaDB will issue an error when trying to write data in the middle of a read-only transaction.

 Only DML statements are transactional and can be rolled back. This may change in a future version, see [MDEV-17567](https://jira.mariadb.org/browse/MDEV-17567) - Atomic DDL and [MDEV-4259](https://jira.mariadb.org/browse/MDEV-4259) - transactional DDL.

 Changing autocommit and explicitly starting a transaction will implicitly commit the active transaction, if any. DDL statements, and several other statements, implicitly commit the active transaction. See [SQL statements That Cause an Implicit Commit](../sql-statements-that-cause-an-implicit-commit/index) for the complete list of these statements.

 A rollback can also be triggered implicitly, when certain errors occur.

 You can experiment with transactions to check in which cases they implicitly commit or rollback. The [in\_transaction](../server-system-variables/index#in_transaction) system variable can help: it is set to 1 when a transaction is in progress, or 0 when no transaction is in progress.

 This section only covers the basic syntax for transactions. Much more options are available. For more information, see [Transactions](../transactions/index).

 Constraint Checking
-------------------

 MariaDB supports the following [constraints](../constraint/index):

 * [Primary keys](../getting-started-with-indexes/index#primary-key)
* [UNIQUE](../getting-started-with-indexes/index#unique-index)
* [CHECK](../constraint/index#check-constraints)
* [Foreign keys](../foreign-keys/index)

 In some databases, constraints can temporarily be violated during a transaction, and their enforcement can be deferred to the commit time. SQL Server does not support this, and always validates data against constraints at the end of each statement.

 MariaDB does something different: it always checks constraints after each row change. There are cases this policy makes some statements fail with an error, even if those statements would work on SQL Server.

 For example, suppose you have an `id` column that is the primary key, and you need to increase its value for some reason:

 
```
SELECT id FROM customer;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
+----+

UPDATE customer SET id = id + 1;
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY'

```

The reason why this happens is that, as the first thing, MariaDB tries to change 1 to 2, but a value of 2 is already present in the primary key.

 A solution is to use this non-standard syntax:

 
```
UPDATE customer SET id = id + 1 ORDER BY id DESC;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5  Changed: 5  Warnings: 0

```

Changing the ids in reversed order won't duplicate any value.

 Similar problems can happen with `CHECK` constraints and foreign keys. To solve them, we can use a different approach:

 
```
SET SESSION check_constraint_checks = 0;
-- run some queries
-- that temporarily violate a CHECK clause
SET SESSION check_constraint_checks = 1;

SET SESSION foreign_key_checks = 0;
-- run some queries
-- that temporarily violate a foreign key
SET SESSION foreign_key_checks = 1;

```

The last solutions temporarily disable `CHECK` constraints and foreign keys. Note that, while this may solve practical problems, it is dangerous because:

 * This doesn't disable a single `CHECK` or foreign key, but also others, that you don't expect to violate.
* This doesn't defer the constraint checks, but it simply disables them for a while. This means that, if you insert some invalid values, they will not be detected.

 See [check\_constraint\_checks](../server-system-variables/index#check_constraint_checks) and [foreign\_key\_checks](../server-system-variables/index#foreign_key_checks) system variables.

 Isolation Levels and Locks
--------------------------

 For more information about MariaDB isolation levels see [SET TRANSACTION](../set-transaction/index).

 ### Locking Reads

 In MariaDB, the locks acquired by a read do not depend on the isolation level (with one exception noted below).

 As a general rule:

 * Plain [SELECTs](../select/index) are not locking, they acquire snapshots instead.
* To force a read to acquire a shared lock, use [SELECT ... LOCK IN SHARED MODE](../lock-in-share-mode/index).
* To force a read to acquire an exclusive lock, use [SELECT ... FOR UPDATE](../for-update/index).

 ### Changing the Isolation Level

 The default, the isolation level in MariaDB is `REPEATABLE READ`. This can be changed with the [tx\_isolation](../server-system-variables/index#tx_isolation) system variable.

 Applications developed for SQL Server and later ported to MariaDB may run with `READ COMMITTED` without problems. Using a stricter level would reduce scalability. To use `READ COMMITTED` by default, add the following line to the MariaDB configuration file:

 
```
tx_isolation = 'READ COMMITTED'

```

It is also possible to change the default isolation level for the current session:

 
```
SET SESSION tx_isolation = 'read-committed';

```

Or just for one transaction, by issuing the following statement before starting a transaction:

 
```
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

```

### How Isolation Levels are Implemented in MariaDB

 MariaDB supports the following isolation levels:

 * `READ UNCOMMITTED`
* `READ COMMITTED`
* `REPEATABLE READ`
* `SERIALIZABLE`

 MariaDB isolation levels differ from SQL Server in the following ways:

 * `REPEATABLE READ` does not acquire share locks on all read rows, nor a range lock on the missing values that match a `WHERE` clause.
* It is not possible to change the isolation level in the middle of a transaction.
* `SNAPSHOT` isolation level is not supported. Instead, you can use `START TRANSACTION WITH CONSISTENT SNAPSHOT` to acquire a snapshot at the beginning of the transaction. This is compatible with all isolation levels.

 Here is an example of `WITH CONSISTENT SNAPSHOT` usage:

 
```
-- session 1
SELECT * FROM t1;
+----+
| id |
+----+
|  1 |
+----+

SELECT * FROM t2;
+----+
| id |
+----+
|  1 |
+----+

START TRANSACTION WITH CONSISTENT SNAPSHOT;

-- session 2
INSERT INTO t1 VALUES (2);

-- session 1
SELECT * FROM t1;
+----+
| id |
+----+
|  1 |
+----+

-- session 2
INSERT INTO t2 VALUES (2);

-- session 1
SELECT * FROM t2;
+----+
| id |
+----+
|  1 |
+----+

```

As you can see, session 1 uses `WITH CONSISTENT SNAPSHOT`, thus it sees all tables as they were when the transaction begun.

 ### Avoiding Lock Waits

 When we try to read or modify a row that is exclusive-locked by another transaction, our transaction is queued until that lock is released. There could be more queued transactions waiting to acquire the same lock, in which case we will wait even more.

 There is a timeout for such waits, defined by the [innodb\_lock\_wait\_timeout](../innodb-system-variables/index#innodb_lock_wait_timeout) variable. If it is set to 0, statements that encounter a row lock will fail immediately. When the timeout is exceeded, MariaDB produces the following error:

 
```
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

```

It is important to note that this variable has two limitations (by design):

 * It only affects transactional statements, not statements like `ALTER TABLE` or `TRUNCATE TABLE`.
* It only concerns row locks. It does not put a timeout on metadata locks, or table locks acquired - for example - with the [LOCK TABLES](../lock-tables/index) statement.

 Note however that [lock\_wait\_timeout](../server-system-variables/index#lock_wait_timeout) can be used for metadata locks.

 There is a special syntax that can be used with `SELECT` and some non-transactional statements including `ALTER TABLE`: the [WAIT and NOWAIT](../wait-and-nowait/index) clauses. This syntax puts a timeout in seconds for all lock types, including row locks, table locks, and metadata locks. For example:

 
```
Session 1:
START TRANSACTION;
-- let's acquire a metadata lock
SELECT id FROM t WHERE 0;

Session 2:
DROP TABLE t WAIT 0;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

```

InnoDB Transactions
-------------------

 ### InnoDB Lock Types

 InnoDB locks are classified based on what exactly they lock, and which operations they lock.

 The first classification is the following:

 * Record Locks lock a row or, more precisely, an index entry.
* Gap Locks lock an interval between two index entries. Note that indexes have virtual values of -Infinum and Infinum, so a gap lock can cover the gap before the first or after the last index entry.
* Next-Key Locks lock an index entry and the gap between it and the next entry. They're a combination of record locks and gap locks.
* Insert Intention Locks are gap locks acquired before inserting a new row.

 Lock modes are the following:

 * Exclusive Locks (X) are generally acquired on writes, e.g. immediately before deleting a row. Only one exclusive lock can be acquired on a resource simultaneously.
* Shared Locks (S) can be acquired acquired on reads. Multiple shared locks can be acquired at the same time (because the rows are not supposed to change when shared-locked) but are incompatible with exclusive locks.
* Intention locks (IS, XS) are acquired when it is not possible to acquire an exclusive lock or a shared lock. When a lock on a row or gap is released, the oldest intention lock on that resource (if any) is converted to an X or S lock.

 For more information see [InnoDB Lock Modes](../innodb-lock-modes/index).

 ### Information Schema

 Querying the [information\_schema](../information-schema/index) is the best way to see which transactions have acquired some locks and which transactions are waiting for some locks to be released.

 In particular, check the following tables:

 * [INNODB\_LOCKS](../information-schema-innodb_locks-table/index): requests for locks not yet fulfilled, or that are blocking another transaction.
* [INNODB\_LOCK\_WAITS](../information-schema-innodb_lock_waits-table/index): queued requests to acquire a lock.
* [INNODB\_TRX](../information-schema-innodb_trx-table/index): information about all currently executing InnoDB transactions, including SQL queries that are running.

 Here is an example of their usage.

 
```
-- session 1
START TRANSACTION;
UPDATE t SET id = 15 WHERE id = 10;

-- session 2
DELETE FROM t WHERE id = 10;

-- session 1
USE information_schema;
SELECT l.*, t.*
    FROM information_schema.INNODB_LOCKS l
    JOIN information_schema.INNODB_TRX t
        ON l.lock_trx_id = t.trx_id
    WHERE trx_state = 'LOCK WAIT' \G
*************************** 1. row ***************************
                   lock_id: 840:40:3:2
               lock_trx_id: 840
                 lock_mode: X
                 lock_type: RECORD
                lock_table: `test`.`t`
                lock_index: PRIMARY
                lock_space: 40
                 lock_page: 3
                  lock_rec: 2
                 lock_data: 10
                    trx_id: 840
                 trx_state: LOCK WAIT
               trx_started: 2019-12-23 18:43:46
     trx_requested_lock_id: 840:40:3:2
          trx_wait_started: 2019-12-23 18:43:46
                trx_weight: 2
       trx_mysql_thread_id: 46
                 trx_query: DELETE FROM t WHERE id = 10
       trx_operation_state: starting index read
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
          trx_is_read_only: 0
trx_autocommit_non_locking: 0

```

### Deadlocks

 InnoDB detects deadlocks automatically. Since this consumes CPU time, some users prefer to disable this feature by setting the [innodb\_deadlock\_detect](../innodb-system-variables/index#innodb_deadlock_detect) variable to 0. If this is done, locked transactions will wait until the they exceed the [innodb\_lock\_wait\_timeout](../innodb-system-variables/index#innodb_lock_wait_timeout). Therefore it is important to set innodb\_lock\_wait\_timeout to a very low value, like 1.

 When InnoDB detects a deadlock, it kills the transaction that modified the least amount of data. The client will receive the following error:

 
```
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

```

The latest detected deadlock, and the killed transaction, can be viewed in the output of [SHOW ENGINE InnoDB STATUS](../show-engine-innodb-status/index). Here's an example:

 
```
------------------------
LATEST DETECTED DEADLOCK
------------------------
2019-12-23 18:55:18 0x7f51045e3700
*** (1) TRANSACTION:
TRANSACTION 847, ACTIVE 10 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 46, OS thread handle 139985942054656, query id 839 localhost root Updating
delete from t where id = 10
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 40 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 847 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
 0: len 4; hex 8000000a; asc     ;;
 1: len 6; hex 00000000034e; asc      N;;
 2: len 7; hex 760000019c0495; asc v      ;;

*** (2) TRANSACTION:
TRANSACTION 846, ACTIVE 25 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 39, OS thread handle 139985942361856, query id 840 localhost root Updating
delete from t where id = 11
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 40 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 846 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
 0: len 4; hex 8000000a; asc     ;;
 1: len 6; hex 00000000034e; asc      N;;
 2: len 7; hex 760000019c0495; asc v      ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 40 page no 3 n bits 80 index PRIMARY of table `test`.`t` trx id 846 lock_mode X locks rec but not gap waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
 0: len 4; hex 8000000b; asc     ;;
 1: len 6; hex 00000000034f; asc      O;;
 2: len 7; hex 770000019d031d; asc w      ;;

*** WE ROLL BACK TRANSACTION (2)

```

The latest detected deadlock never disappears from the output of `SHOW ENGINE InnoDB STATUS`. If you cannot see any, MariaDB hasn't detected any InnoDB deadlocks since the last restart.

 Another way to monitor deadlocks is to set [innodb\_print\_all\_deadlocks](../innodb-system-variables/index#innodb_print_all_deadlocks) to 1 (0 is the default). InnoDB will log all detected deadlocks into the [error log](../error-log/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-transactions-and-isolation-levels-for-sql-server-users/>

MariaDB Authorization and Permissions for SQL Server Users
==========================================================

    Understanding Accounts and Users
--------------------------------

 MariaDB authorizes access and check permissions on accounts, rather than users. Even if MariaDB supports standard SQL commands like [CREATE USER](../create-user/index) and [DROP USER](../drop-user/index), it is important to remember that it actually works with accounts.

 An account is specified in the format `'user'@'host'`. The quotes are optional and allow one to include special characters, like dots. The host part can actually be a pattern, which follows the same syntax used in `LIKE` comparisons. Patterns are often convenient because they can match several hostnames.

 Here are some examples.

 Omitting the host part indicates an account that can access from any host. So the following statements are equivalent:

 
```
CREATE USER viviana;
CREATE USER viviana@'%';

```

However, such accounts may be unable to connect from localhost if an anonymous user `''@'%'` is present. See [localhost and %](../troubleshooting-connection-issues/index#localhost-and) for the details.

 Accounts are not bound to a specific database. They are global. Once an account is created, it is possible to assign it permissions on any existing or non existing database.

 The [sql\_mode](../sql-mode/index) system variable has a [NO\_AUTO\_CREATE\_USER](../sql-mode/index#no_auto_create_user) flag. In recent MariaDB versions it is enabled by default. If it is not enabled, a [GRANT](../grant/index) statement specifying privileges for a non-existent account will automatically create that account.

 For more information: [Account Management SQL Commands](../account-management-sql-commands/index).

 ### Setting or Changing Passwords

 Accounts with the same username can have different passwords.

 By default, an account has no password. A password can be set, or changed, in the following way:

 * By specifying it in [CREATE USER](../create-user/index).
* By the user, with [SET PASSWORD](../set-password/index).
* By root, with `SET PASSWORD` or [ALTER USER](../alter-user/index).

  With all these statements (`CREATE USER`, `ALTER USER`, `SET PASSWORD`) it is possible to specify the password in plain or as a hash:

 
```
-- specifying plain passwords:
CREATE USER tom@'%.example.com' IDENTIFIED BY 'plain secret';
ALTER USER tom@'%.example.com' IDENTIFIED BY 'plain secret';
SET PASSWORD = 'plain secret';
-- specifying hashes:
CREATE USER tom@'%.example.com' IDENTIFIED BY PASSWORD 'secret hash';
ALTER USER tom@'%.example.com' IDENTIFIED BY PASSWORD 'secret hash';
SET PASSWORD = PASSWORD('secret hash');

```

The [PASSWORD()](../password/index) function uses the same algorithm used internally by MariaDB to generate hashes. Therefore it can be used to get a hash from a plain password. Note that this function should not be used by applications, as its output may depend on MariaDB version and configuration.

 `SET PASSWORD` applies to the current account, by default. Superusers can change other accounts passwords in this way:

 
```
SET PASSWORD FOR tom@'%.example.com' = PASSWORD 'secret hash';

```


**MariaDB starting with [10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/)**Passwords can have an expiry date, set by [default\_password\_lifetime](../server-system-variables/index#default_password_lifetime). To set a different date for a particular user:

 
```
CREATE USER 'tom'@'%.example.com' PASSWORD EXPIRE INTERVAL 365 DAY;

```

To set no expiry date for a particular user:

 
```
CREATE USER 'tom'@'%.example.com' PASSWORD EXPIRE NEVER;

```

For more details, see [User Password Expiry](../user-password-expiry/index).

 

**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**It is also possible to lock an account with immediate effect:

 
```
CREATE USER 'tom'@'%.example.com' ACCOUNT LOCK;

```

See [Account Locking](../account-locking/index) for more details.

 
Authentication Plugins
----------------------

 MariaDB supports [authentication plugins](../authentication-plugins/index). These plugins implement user's login and authorization before they can use MariaDB.

 Each user has one or more authentication plugins assigned. The default one is [mysql\_native\_password](../authentication-plugin-mysql_native_password/index). It is the traditional login using the username and password set in MariaDB, as described above.

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**On UNIX systems, root is also assigned the [unix\_socket](../authentication-plugin-unix-socket/index) plugin, which allows a user logged in the operating system to be recognized by MariaDB.

 
Windows users may be interested in the [named pipe](../authentication-plugin-named-pipe/index) and [GSSAPI](../authentication-plugin-gssapi/index) plugins. GSSAPI also requires the use of a plugin on the [client side](../authentication-plugin-gssapi/index#support-in-client-libraries).

 A plugin can be assigned to a user with `CREATE USER`, `ALTER USER` or `GRANT`, using the `IDENTIFIED VIA` syntax. For example:

 
```
CREATE USER username@hostname IDENTIFIED VIA gssapi;
GRANT SELECT ON db.* TO username@hostname IDENTIFIED VIA named_pipe;

```

TLS connections
---------------

 A particular user can be required to use TLS connections. Additional requirements can be set:

 * Having a valid X509 certificate.
* The certificate may be required to be issued by a particular authority.
* A particular certificate subject can be required.
* A particular certificate cipher suite can be required.

 These requirements can be set with `CREATE USER`, `ALTER USER` or `GRANT`. For the syntax, see [CREATE USER](../create-user/index#tls-options).

 MariaDB can be bundled with several cryptography libraries, depending on its version. For more information about the libraries, see [TLS and Cryptography Libraries Used by MariaDB](../tls-and-cryptography-libraries-used-by-mariadb/index).

 For more information about secure connections, see [Secure Connections Overview](../secure-connections-overview/index).

 Permissions
-----------

 Permissions can be granted to accounts. As mentioned before, the specified accounts can actually be patterns, and multiple accounts may match a pattern. For example, in this example we are creating three accounts, and we are assigning permissions to all of them:

 
```
CREATE USER 'tom'@'example.com';
CREATE USER 'tom'@'123.123.123.123;
CREATE USER 'tom'@'tomlaptop';
GRANT USAGE ON *.* TO tom@'%';

```

The following permission levels exist in MariaDB:

 * [Global privileges](../grant/index#global-privileges);
* [Database privileges](../grant/index#database-privileges);
* [Table privileges](../grant/index#table-privileges);
* [Column privileges](../grant/index#column-privileges);
* [Function](../grant/index#function-privileges) and [procedure privileges](../grant/index#procedure-privileges).

 Note that database and schema are synonymous in MariaDB.

 Permissions can be granted for non-existent objects that could exist in the future.

 The list of supported privileges can be found in the [GRANT](../grant/index) page. Some highlights can be useful for SQL Server users:

 * `USAGE` privilege has no effect. The `GRANT` command fails if we don't grant at least one privilege; but sometimes we want to run it for other purposes, for example to require a user to use TLS connections. In such cases, it is useful to grant `USAGE`.
* Normally we can obtain a list of all databases for which we have at least one permission. The `SHOW DATABASES` permission allows getting a list of all databases.
* There is no `SHOWPLAN` privilege in MariaDB. Instead, [EXPLAIN](../explain/index) requires the `SELECT` privilege for each accessed table and the `SHOW VIEW` privilege for each accessed view.
* The same permissions are needed to see a table structure (`SELECT`) or a view definition (`SHOW VIEW`).
* `REFERENCES` has no effect.

 MariaDB does not support negative permissions (the `DENY` command).

 Some differences concerning the SQL commands:

 * In MariaDB `GRANT` and `REVOKE` statements can only assign/revoke permissions to one user at a time.
* While we can assign/revoke privileges at column level, we have to run a `GRANT` or `REVOKE` statement for each column. The `table (column_list)` syntax is not recognized by MariaDB.
* In MariaDB it is not needed (or possible) to specify a class type.

 Roles
-----

 MariaDB supports [roles](../roles/index). Permissions can be assigned to roles, and roles can be assigned to accounts.

 An account may have zero or one default roles. A default role is a role that is automatically active for a user when they connect. To assign an account or remove a default role, these SQL statements can be used:

 
```
SET DEFAULT ROLE some_role FOR username@hostname;
SET DEFAULT ROLE NONE FOR username@hostname;

```

Normally a role is not a default role. If we assign a role in this way:

 
```
GRANT some_role TO username@hostname;

```

...the user will not have that role automatically enabled. They will have to enable it explicitly:

 
```
SET ROLE some_role;

```

MariaDB does not have predefined roles, like public.

 For an introduction to roles, see [Roles Overview](../roles_overview/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-authorization-and-permissions-for-sql-server-users/>

Repairing MariaDB Tables for SQL Server Users
=============================================

    Repairing tables in MariaDB is not similar to repairing tables in SQL Server.

 The first thing to understand is that every MariaDB table is handled by a [storage engine](../understanding-mariadb-architecture/index#storage-engines). Storage engines are plugins that know how to physically read and write a table, so each storage engine allows one to repair tables in different ways. The default storage engine is [InnoDB](../innodb/index).

 MariaDB provides specific SQL statements to deal with corrupted tables:

 * [CHECK TABLE](../check-table/index) checks if a table is corrupted;
* [REPAIR TABLE](../repair-table/index) repairs a table if it is corrupted.

 As a general rule, there is no reason why a table that is corrupted on a master should also be corrupted on the slaves. Therefore, `REPAIR` is generally used with the `NO_WRITE_TO_BINLOG` option, to avoid replicating it to the slaves.

 Partitioned Tables
------------------

 [Partitioned tables](../partitioning-tables/index) are normally split into multiple physical files (one per partition). Even if one of the partitions is corrupted, in most cases other partitions are healthy.

 For this reason, `CHECK TABLE` and `REPAIR TABLE` don't work on partitioned tables. Instead, use [ALTER TABLE](../alter-table/index) to check or repair a single partition.

 For example:

 
```
ALTER TABLE orders CHECK PARTITION p_2019, p_2020;
ALTER TABLE orders REPAIR PARTITION p_2019, p_2020;

```

Indexes
-------

 Indexes can get corrupted. However, as long as data is not corrupted, indexes can always be dropped and rebuilt with [ALTER TABLE](../alter-table/index):

 
```
ALTER TABLE customer DROP INDEX idx_email;
ALTER TABLE customer ADD INDEX idx_email (email);

```

Checking and Repairing Tables
-----------------------------

 Here we discuss how to repair tables, depending on the storage engine.

 ### InnoDB

 InnoDB follows the "fail fast" philosophy. If table corruption is detected, by default InnoDB deliberately causes MariaDB to crash to avoid corruption propagation, logging an error into the [error log](../error-log/index). This happens even if the corruption is found with a `CHECK TABLE` statement. This behavior can be changed with the [innodb\_corrupt\_table\_action](../innodb-system-variables/index#innodb_corrupt_table_action) server variable.

 To repair an InnoDB table after a crash:

 1. Restart MariaDB with the `[--innodb-force-recovery](../innodb-system-variables/index#innodb_force_recovery)` option set to a low but non-zero value.
2. If MariaDB fails to start, retry with a higher value. Repeat until you succeed.

 At this point, you can follow two different procedures, depending if you can use a backup or not. Provided that you have a usable backup, it is often the best option to bring the database up quickly. But if you want to reduce the data loss as much as possible, you prefer to follow the second method.

 Restoring a backup:

 1. Drop the whole database with [DROP DATABASE](../drop-database/index).
2. Restore a backup of the database. The exact procedure depends on the [type of backup](../mariadb-backups-overview-for-sql-server-users/index).

 Recovering existing data:

 1. Dump data from the corrupter table, ordered by primary key. MariaDB could crash when it finds damaged data. Repeat the process skipping damaged data.
2. Save somewhere the table structure with [SHOW CREATE TABLE](../show-create-table/index).
3. Restart MariaDB.
4. Drop the table with [DROP TABLE](../drop-table/index).
5. Recreate the table and restore the dump.

 For more details, see [InnoDB Recovery Modes](../innodb-recovery-modes/index).

 ### Aria and MyISAM

 [MyISAM](../myisam-storage-engine/index) is not crash-safe. In case of a MariaDB crash, the changes applied to MyISAM tables but not yet flushed to the disk are lost.

 [Aria](../aria/index) is crash-safe by default, which means that in case of a crash, after repairing any table that is damaged, no changes are lost. However, Aria tables are not crash-safe if created with `TRANSACTIONAL=0` or `ROW_FORMAT` set to `FIXED` or `DYNAMIC`.

 System tables use the Aria storage engine and they are crash-safe.

 To check if a MyISAM/Aria table is corrupted, we can use [CHECK TABLE](../check-table/index). To repair a MyISAM/Aria table, one can use [REPAIR TABLE](../repair-table/index). Before running `REPAIR TABLE` against big tables, consider increasing [myisam\_repair\_threads](../myisam-system-variables/index#myisam_repair_threads) or [aria\_repair\_threads](../aria-system-variables/index#aria_repair_threads).

 MyISAM and Aria tables can also be automatically repaired when corruption is detected. This is particularly useful for Aria, in case corrupted system tables prevent MariaDB from starting. See [myisam\_recover\_options](../myisam-system-variables/index#myisam_recover_options) and [aria\_recover\_options](../aria-system-variables/index#aria_recover_options). By default Aria runs the quickest repair type. Occasionally, to repair a system table, we may have to start MariaDB in this way:

 
```
mysqld --aria-recover-options=BACKUP,FORCE

```

It is also possible to stop MariaDB and repair MyISAM tables with [myisamchk](../myisamchk/index), and Aria tables with [aria\_chk](../aria_chk/index). With default values, a repair can be unnecessarily very slow. Before running these tools, be sure to check the [Memory and Disk Use With myisamchk](../memory-and-disk-use-with-myisamchk/index) page. 

 ### Other Storage Engines

 Notes on the different storage engines:

 * For [MyRocks](../myrocks/index), see [MyRocks and CHECK TABLE](../myrocks-and-check-table/index).
* With [ARCHIVE](../archive/index), `REPAIR TABLE` also improves the compression rate.
* For [CSV](../csv/index), see [Checking and Rpairing CSV Tables](../checking-and-repairing-csv-tables/index).
* Some special storage engines, like [MEMORY](../memory-storage-engine/index) or [BLACKHOLE](../blackhole/index), do not support any form of check and repair.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/repairing-mariadb-tables-for-sql-server-users/>

MariaDB Backups Overview for SQL Server Users
=============================================

    MariaDB has the following types of backups:

 * Logical backups (dumps).
* Hot backups with Mariabackup.
* Snapshots.
* Incremental backups.

 Logical Backups (Dumps)
-----------------------

 A *dump*, also called a *logical backup*, consists of the SQL statements needed to recreate MariaDB databases and their data into another server. A dump is the slowest form of backup to restore, because it implies executing all the SQL statements needed to recreate data. However it is also the most flexible, because restoring will work on any MariaDB version, because the SQL syntax is usually compatible. It is even possible to restore a dump into an older version, though the incompatible syntax (new features) will be ignored. Under certain conditions, MariaDB dumps may also be restored on other DBMSs, including SQL Server.

 The compatibility between different versions and technologies is achieved by using [executable comments](../comment-syntax/index), but we should be aware of how they work. If we use a feature introduced in version 11.1, for example, it will be included in the dump inside an executable comment. If we restore that backup on a server with [MariaDB 10.11](../what-is-mariadb-1011/index), the 11.1 feature will be ignored. This is the only way to restore backups in older MariaDB versions.

 ### mariadb-dump

 Logical backups are usually taken with [mariadb-dump](../mariadb-dump/index) (previously called mysqldump).

 mariadb-dump allows one to dump all databases, a single database, or a set of tables from a database. It is even possible to specify a `WHERE` clause, which under certain circumstances allows to obtain incremental dumps.

 For consistency reasons, when using the default storage engine [InnoDB](../understanding-mariadb-architecture/index#innodb), it is important to use the `--single-transaction` option. This will read all data in a single transaction. It's important however to understand that long transactions may have a big impact on performance.

 The `--master-data` option adds the statements to setup a slave to the dump.

 MariaDB also supports statements which make easy to write applications to obtain custom types of dumps. For most `CREATE <object_type>` statement, a corresponding `SHOW CREATE <object_type>` exists. For example, [SHOW CREATE TABLE](../show-create-table/index) returns the `CREATE TABLE` statement that can be used to recreate a certain table, without data.

 ### mydumper

 [mydumper](https://github.com/maxbube/mydumper) is a 3rd party tools to take dumps from MariaDB and MySQL databases. It is much faster than mariadb-dump because it takes backups with several parallel threads, usually one thread for each available CPU core. It produces several files, that can be used to restore a database using the related tool myloader.

 Since is it a 3rd party tool, it could be incompatible with some present or future MariaDB features.

 Hot Backups (mariabackup)
-------------------------

 Mariabackup is a tool for taking a backup of MariaDB files while MariaDB is working. A lock is only held for a small amount of time, so it is suitable to backup a server without causing disruptions. It works by taking corrupted backups and then bringing them to a consistent state by using the [InnoDB undo log](../innodb-undo-log/index). Mariabackup also properly backups [MyRocks](../myrocks/index) tables and non-transactional storage engines. 

 Cold Backups and Snapshots
--------------------------

 A copy of all MariaDB files is a working backup. Therefore, the easiest way to backup a dataset is to shutdown the server and copy all its files. It will be entirely possible to start another server with a copy of those files. This is often referred to as a *cold backup*. However, in most cases we don't want to do this, because it implies downtime for the server: it will not be working at least for the time necessary to copy the files.

 Snapshots are usually a better idea, as they are a consistent copy of the files at a given moment in time, taken without stopping the normal operations.

 A snapshot of the files can be taken at several levels: filesystem level, if the filesystem supports snapshots, for example zfs; Linux Logical Volume Manager (LVM) also supports snapshots; and virtual machines also allow one to take snapshots. Windows shadow copies are also snapshots, with a benefit: it is possible to restore a single file from a shadow copy. A snapshot is not an expensive operation, because it does not imply a copy of the files. The current files will not be modified anymore, and changes to them will be written in separate places.

 The problem with snapshots is that they behave like a logical copy of the files as they are in a given point in time. But database files are not guaranteed to be consistent in every moment, because contents can be buffered before being flushed to the disk. You can think a database snapshot like a database after an operating system crash.

 With non-transactional tables, some data is typically lost. Data changes that are present in a buffer before the snapshot, but not written on a disk, cannot be recovered in any way. Data changes in transactional tables, like InnoDB tables, can always be recovered after restoring a snapshot (or after a crash), as long as a commit was done. Tables will still need to be repaired, just like it happens after an SQL Server crash.

 Snapshots can be taken while MariaDB is running. To restore them, stop MariaDB first - or kill the process, because you don't really care of the consequences in this case. Then restore a snapshot and start MariaDB again.

 For more information about snapshots, check your filesystem, LVM or virtual machine documentation.

 Incremental Backups
-------------------

 The term incremental backup in MariaDB indicates what SQL Server calls a *[differential backup](https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/differential-backups-sql-server)*. An important difference is that in SQL Server such backups are based on the [transaction log](https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/transaction-log-backups-sql-server), which wouldn't be possible in MariaDB because transaction logs are handled at storage engine level.

 As mentioned [here](../understanding-mariadb-architecture/index#the-binary-log), MariaDB can use the [binary log](../binary-log/index) instead for backup purposes. Such incremental backups can be done manually. This means that:

 * The binary log files are copied just like any other regular file.
* To copy those files it is necessary to have the proper permissions at filesystem level, not in MariaDB.
* Backups do not expire until we delete the last needed complete backup.

 ### Replaying the Binary Log

 The page [Using mariadb-binlog](../using-mariadb-binlog/index) shows how to use the mariadb-binlog utility to replay a binary log file.

 The page also shows how to edit the binary log before replaying it. This allows one to undo an SQL statement that was executed by mistake, for example a `DROP TABLE` against a wrong table. The high level procedure is the following:

 * Restore a backup that is older than the SQL statement to undo.
* Use `mariadb-binlog` to generate a file with the SQL statements that were executed after the backup.
* Edit the SQL file, erasing the unwanted statement.
* Run the SQL file.

 ### Incremental Backups with mariabackup

 The simplest way to take an incremental backup is to use Mariabackup. This tool is able to take and restore incremental backups. For the complete procedure to use, see [Incremental Backup and Restore with Mariabackup](../incremental-backup-and-restore-with-mariabackup/index).

 Mariabackup can run on both Linux and Windows systems.

 ### Flashback

 [Flashback](../flashback/index) is a feature that allows one to bring all databases, some databases or some tables back to a certain point in time. This can only be done if the binary log is enabled. Flashback is not a proper backup, but it can be used to restore a certain set of data.

 ### Copying Individual Tables

 It is entirely possible to restore a single table from a physical backup, or to copy the table to another server.

 With the [MyISAM](../myisam/index) storage engine it was very easy to move tables between different servers, as long as the MySQL or MariaDB version was the same.

 [InnoDB](../innodb/index) is nowadays the default storage engine, and it is more complex, as it supports transactions for example. It still supports restoring a table from a physical file, this feature is called *transportable tablespaces*. There is a particular procedure to follow, and some limitations. This is basically the MariaDB equivalent of detaching and re-attaching tables in SQL Server.

 For more information, see [InnoDB File-Per-Table Tablespaces](../innodb-file-per-table-tablespaces/index).

 By default. all table files are located in the *data directory*, which is defined by the system variable [datadir](../server-system-variables/index#datadir). There may be exceptions, because a table's files can be located elsewhere using the [`DATA DIRECTORY` and `INDEX DIRECTORY`](../create-table/index#data-directoryindex-directory) options in `CREATE TABLE`.

 Regardless of the storage engine used, each table's structure is generally stored in a file with the `.frm` extension.

 The files used for [partitioned tables](../partitioning-tables/index) are different from the files used for non-partitioned tables. See [Partitions Files](../partitions-files/index) for details.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-backups-overview-for-sql-server-users/>

MariaDB Replication Overview for SQL Server Users
=================================================

    MariaDB supports the following types of replication:

 * Asynchronous replication.
* Semi-synchronous replication.
* Galera Cluster.

 
**MariaDB starting with [10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/)**Note: in the snippets in this page, several SQL statements use the keyword `SLAVE`. This word is considered inappropriate by some persons or cultures, so from [MariaDB 10.5](../what-is-mariadb-105/index) it is possible to use the `REPLICA` keyword, as a synonym.

 Similar synonyms will be created in the future for status variables and system variables. See [MDEV-18777](https://jira.mariadb.org/browse/MDEV-18777) to track the status of these changes.

 
Asynchronous Replication
------------------------

 The original MariaDB replication system is asynchronous primary-replica replication.

 A primary needs to have the [binary log](../binary-log/index) enabled. The primary logs all data changes in the binary log. Every *event* (a binary log entry) is sent to all the replicas.

 For a high-level description of the binary log for SQL Server users, see [Understanding MariaDB Architecture](../understanding-mariadb-architecture/index#the-binary-log).

 The events can be written in two formats: as an SQL statement (*statement-based replication*, or SBR), or as a binary representation of the change (*row-based replication*, or RBR). The former is generally slower, because the statement needs to be re-executed by the replicas. It is also less reliable, because some SQL statements are [not deterministic](../unsafe-statements-for-statement-based-replication/index), so they could produce different results on the replicas. On the other hand row-based replication could make the binary log much bigger, and require more network traffic. For this reason, DML statements are always logged in statement format.

 For more details on replication formats, see [binary log formats](../binary-log-formats/index).

 The replicas have an [I/O thread](../replication-threads/index#slave-io-thread) that receives the binary log events and writes them to the [relay log](../relay-log/index). These events are then read by the [SQL thread](../replication-threads/index#slave-sql-thread). This thread could directly apply the changes to the local databases, and this was the only option before [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/). If [parallel replication](#parallel-replication-and-group-commit) is enabled, the SQL thread hands the events to the worker thread, that apply them to the databases. The latter method is recommended for performance reasons.

 When a replica cannot apply an event to the local data, the SQL thread stops. This happens, for example, if the event is a row deletion but that row doesn't exist on the replica. There can be several reasons for this, for example non-deterministic statements, or a user deleted the row in the replica. To reduce the risk, it is recommended to set [read\_only](../server-system-variables/index#read_only) to 1 in the replicas.

 [SHOW SLAVE STATUS](../show-slave-status/index) has columns named `Slave_SQL_State` and `Slave_IO_State` that show, respectively, if the SQL thread and the IO thread are running. If they are not, the column `Last_IO_Errno` and `Last_IO_Error` (for the IO thread) or `Last_SQL_Errno` and `Last_SQL_Error` (for the SQL thread) show what the problem is.

 In a replication chain, every server must have a unique [server\_id](../replication-and-binary-log-system-variables/index#server_id).

 For more information on replication, see [standard replication](../standard-replication/index).

 ### Binary Log Coordinates, Relay Log Coordinates and GTID

 The binary log coordinates provide a way to identify a certain data change made by a server. Coordinates consist of a file name and the position of the latest event, expressed as an integer. The last event coordinates can be seen with the [SHOW MASTER STATUS](../show-master-status/index) columns `File` and `Position`. [mariadb-dump](../mariadb-dump/index) includes them in a dump if the `--master-data` option is used.

 A replica uses primary binary log coordinates to identify the last event it read. This can be seen with the [SHOW SLAVE STATUS](../show-slave-status/index) columns `Master_Log_File` and `Read_Master_Log_Pos`.

 The columns `Relay_Master_Log_File` and `Exec_Master_Log_Pos` identify the primary event that corresponds to the last event applied by the SQL thread.

 The replica relay log also has coordinates. The coordinates of the last applied event can be seen with the `SHOW SLAVE STATUS` columns `Relay_Log_File` and `Relay_Log_Pos`.

 To easily find out how far the replica is lagging behind the primary, we can look at `Seconds_Behind_Master`.

 Coordinates represented in this way have a problem: they are different on each server. Each server can use files with different (or the same) names, depending on its configuration. And files can be rotated at different times, including when a user runs [FLUSH LOGS](../flush/index). By enabling the GTID (global transaction id) an event will have the same id on the primary and on all the replicas.

 When [GTID](../gtid/index) is enabled, `SHOW SLAVE STATUS` shows two GTIDs: `Gtid_IO_Pos` is the last event written into the relay log, and `Gtid_Slave_Pos` is the last event applied by the SQL thread. There is no need for a column identifying the same event in the primary, because the id is the same.

 ### Provisioning a Replica

 MariaDB does not have an equivalent to SQL Server's snapshot replication.

 To setup a replica, it is necessary to manually provision it. It can be provisioned from the primary in this way:

 * A backup from the primary must be restored on the new replica;
* The binary log coordinates at the moment of the backup should be set as replication coordinates in the replica, via [CHANGE MASTER TO](../change-master-to/index).

 However, if there is at least one existing replica, it is better to use it to provision the new replica:

 * A backup from the existing replica must be restored in the new replica;
* The backup should include the system tables. In this way it will not be necessary to set the correct coordinates manually.

 For more information see [Setting Up Replication](../setting-up-replication/index) and [Setting up a Replica with Mariabackup](../setting-up-a-replica-with-mariabackup/index).

 ### Replication and Permissions

 A replica connects to a primary using its credentials. See [CHANGE MASTER TO](../change-master-to/index).

 The appropriate account must be created in the primary, and it needs to have the `REPLICATION SLAVE` permission.

 See [Setting Up Replication](../setting-up-replication/index) for more information.

 ### Parallel Replication and Group Commit

 MariaDB uses [group commit](../group-commit-for-the-binary-log/index), which means that a group of events are physically written in the binary log altogether. This reduces the number of IOPS (input/output operations per second). Group commit cannot be disabled, but it can be tuned with variables like [binlog\_commit\_wait\_count](../replication-and-binary-log-system-variables/index#binlog_commit_wait_count) and [binlog\_commit\_wait\_usec](../replication-and-binary-log-system-variables/index#binlog_commit_wait_usec).

 Replicas can apply the changes using multiple threads. This is known as [parallel replication](../parallel-replication/index). Before [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) only one thread was used to apply changes. Since a primary can use many threads to write data, mono-thread replication is a well-known bottleneck. Parallel replication is not enabled by default. To use it, set the [slave\_parallel\_threads](../replication-and-binary-log-system-variables/index#slave_parallel_threads) variable to a number greater than 1. If replication is running, the replica threads must be stopped in order to change this value:

 
```
STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_threads = 4;
START SLAVE SQL_THREAD;

```

There are different parallel replication styles available: in-order and out-of-order. The exact mode in use is determined by the [slave\_parallel\_mode](../replication-and-binary-log-system-variables/index#slave_parallel_mode) system variable. In parallel replication, the events are not replicated exactly in the same order as they occurred in the primary. But with an in-order replication mode the commit phase is always applied simultaneously. In this way data in the replica always reflect data as they have been in the primary at a certain point in time. Out-of-order replication is faster because there is less queuing, but it's not completely consistent with the primary. If two transactions modified different sets of rows in the primary, they could become visible in the replica in a different order.

 `conservative` relies on primary group commit: events in different groups are executed in a parallel way.

 `optimistic` does not try to find out which transaction can be executed in a parallel way - except for transactions that conflicted on the primary. Instead, it always tries to apply many events together, and rolls transactions back when there is a conflict.

 `aggressive` is similar to optimistic, but it does not take into account which transactions conflicted in the primary.

 `minimal` applies commits together, but all other events are applied in order.

 Out-of-order replication cannot be enabled automatically by changing a variable in the replica. Instead, it must be enabled by the applications that run transactions in the primary. They can do this if the GTID is enabled. They can set different values for the [gtid\_domain\_id](../replication-and-binary-log-system-variables/index#gtid_domain_id) variable in different transactions. This shifts a lot of responsibility to the application layer; however, if the application is aware of which transactions are not going to conflict and this information allows one to sensibly increase the parallelism, and using out-of-order replication can be a good idea.

 Even if out-of-order replication is not normally used, it can be a good idea to use it for long running transactions or [ALTER TABLEs](../alter-table/index), so they can be applied at the same time as normal operations that are not conflicting.

 The impact of the number of threads and mode on performance can be partly seen with [SHOW PROCESSLIST](../show-processlist/index), which shows the state of all threads. This includes the replication worker threads, and shows if they are blocking each other.

 ### Differences Between the Primary and the Replicas

 As a general rule, we want the primary and the replicas to contain exactly the same data. In this way, no conflicts are possible. Conflicts are the most likely cause of replication outages.

 To reduce the possible causes of conflicts, the following best practices are recommended:

 * Users must not change data in the replica directly. Set [read\_only](../server-system-variables/index#read_only) to 1. Note that this won't prevent root from making changes.
* Use the same table definitions in the primary and in the replica.
* Use `ROW` binary log format on the primary.

 Another cause of inconsistencies include MariaDB bugs and failover in case the primary crashes.

 An open source third party tool is available to check if the primary and a replica are consistent. It is called pt-table-checksum. Another tool, pt-table-sync, can be used to eliminate the differences. Both are part of Percona Toolkit. The advice is to run pt-table-checksum periodically, and use pt-table-sync if inconsistencies are found.

 If a replication outage occurs because an inconsistency is found, sometimes we want to quickly bring the replica up again as quickly as possible, and solve the core problem later. If GTID is not used, a way to do this is to run [SET GLOBAL SQL\_SLAVE\_SKIP\_COUNTER = 1](../set-global-sql_slave_skip_counter/index), which skips the problematic replication event.

 If GTID is used, the [gtid\_slave\_pos](../gtid/index#gtid_slave_pos) variable can be used instead. See the link for an explanation of how it works.

 There are ways to have different data on the replicas. For example:

 * Multi-source replication is possible. In this way, a replica will replicate data from multiple primaries. This feature is described below.
* [Replication filters](../replication-filters/index) are supported. This allows one to exclude or include in replication specific tables, entire databases, or tables whose name matches a certain pattern. This allows one to avoid replicating data that is present in the primary but can always be rebuilt.
* [Differences in table definitions](../replication-when-the-master-and-slave-have-different-table-definitions/index) are also possible. For example, a replica could have [more columns or less columns](../replication-when-the-master-and-slave-have-different-table-definitions/index#different-number-or-order-of-columns) compared to the primary. In this way we can avoid replicating columns whose values can be rebuilt. Or we can add columns for analytics purposes, without having them in the primary. Be sure to understand the limitations and risks of this technique.

 ### Delayed Replication

 MariaDB supports delayed replication. This is the equivalent of setting a `pollinginterval` in SQL Server.

 To delay replication in a MariaDB replica, use [CHANGE MASTER TO](../change-master-to/index) to specify a delay in seconds.

 For more information, see [Delayed Replication](../delayed-replication/index).

 ### Multi-Source Replication

 [Multi-source replication](../multi-source-replication/index) is an equivalent to peer-to-peer replication, available in SQL Server Enterprise Edition.

 A MariaDB replica can replicate from any number of primaries. It is very important that different primaries don't have the same tables. Otherwise there could be conflicts between data changes made on different primaries, and this will result in a replication outage.

 In multi-source replication different channels exist, one for each primary.

 This changed the way [SQL replication statements](../replication-commands/index) work. [SHOW PROCESSLIST](../show-processlist/index) returns a different row for each channel. Several statements, like [CHANGE MASTER TO](../change-master-to/index), [START SLAVE](../start-slave/index) or [STOP SLAVE](../stop-slave/index). accept a parameter which specifies which replication channel they should affect. For example, to stop a channel called `wp1`:

 
```
STOP SLAVE "wp1";

```

Furthermore, variables that affect parallel replication can be prefixed with a channel name. This allow one to only use parallel replication for certain channels, or to tune it differently for each channel. For example, to enable parallel replication on a channel called `wp1`:

 
```
SET GLOBAL wp1.slave_parallel_threads = 4;

```

### Dual Primary

 It is possible to configure two servers in a way that each of them acts as a primary for the other server.

 In this way, data could theoretically be inserted into any of these servers, and will then be replicated to the other server. However, in such a configuration conflicts are very likely. So it is impractical to use this technique to scale writes.

 A dual primary (or primary-primary) configuration however can be useful for failover. In this case we talk about an *active primary* that receives reads and writes from the clients, and a *passive primary* that is not used until the active primary crashes.

 Several problems should be considered in this scenario:

 * If the active primary crashes, it is very possible that the passive primary did not receive all events yet, because replication is asynchronous. If the primary data are lost (for example because the disk is damaged), some data are also lost.
* If data is not lost, when we bring the primary up again, the latest events will be replicated by the other server. There could be conflicts that will break replication.
* When is the active primary considered down? Even if a server cannot reach it, the active primary could be running and it could be able to communicate with the passive primary. Switching the clients to the passive primary could lead to unnecessary problems. It is a good idea to always check `SHOW SLAVE STATUS` to be sure that the two primary are not communicating.
* If we want to have more replicas, we should attach some of them to the active primary, and some of them to the passive primary. The reason is that when a server crashes, its replicas stop receiving any data. Failover is still possible, but it's better to have some servers that will not need any failover.

 A safe primary-primary configuration where both servers accept writes, however, is possible. This is the case is data never conflicts. For example, the two servers could accept writes on different databases. We will have to decide what should happens in case of a server crash:

 * Writes can be stopped until the server is up again. Reads can be sent to the other server, but keep in mind that the most recently written data could be missing.
* Both writes and reads can failover to the other server. All the problems mentioned above may apply to this situation.

 See Sveta Smirnova's slides at MariaDB Day 2020: "[How Safe is Asynchronous Master-Master Setup?](https://www.slideshare.net/SvetaSmirnova/how-safe-is-asynchronous-mastermaster-setup)".

 Semi-Synchronous Replication
----------------------------

 Semi-synchronous replication was initially implemented as a plugin, in MySQL. Two different plugins needed to be used, one on the primary and the other on the replicas. Starting from [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) it is built-in, which improved its performance.

 The problem with standard replication is that there is no guarantee that it will not lag, even by long amounts of time. [Semi-synchronous replication](../semisynchronous-replication/index) reduces this problem, at the cost of reducing the speed of the primary.

 In semi-synchronous replication, when a transaction is committed on the primary, the primary does not immediately return control to the client. Instead, it sends the event to the replicas. After one replica reported that the commit was executed with success, the primary reports success to the client.

 Semi-synchronous replication is useful for failover, therefore a dual primary setup is not needed in this case. If the primary crashes, the most up-to-date replica can be promoted to primary without losing any data.

 ### Enabling Semi-Synchronous Replication

 Semi-synchronous replication can be enabled at runtime in this way on the primary:

 
```
SET GLOBAL rpl_semi_sync_master_enabled = ON;

```

Semi-synchronous replication is not used until it has been enabled on the replicas also. If the replicas are already replicating, the io\_thread needs to be stopped and restarted. This can be done as follows:

 
```
SET GLOBAL rpl_semi_sync_slave_enabled = ON;
STOP SLAVE IO_THREAD;
START SLAVE IO_THREAD;

```

### Tuning the Wait Point and the Primary Timeout

 The most important aspects to tune are the wait point and the primary timeout.

 When the binary log is enabled, transactions must be committed both in the [storage engine](../understanding-mariadb-architecture/index#storage-engines) (usually [InnoDB](../innodb/index)) and in the [binary log](../understanding-mariadb-architecture/index#the-binary-log). Semi-synchronous replication requires that the transaction is also acknowledged by at least one replica before the primary can report success to the client.

 The wait point determines at which point the primary must stop and wait for a confirmation from a replica. This is an important decision from disaster recovery standpoint, in case the primary crashes when a transaction is not fully committed. The [rpl\_semi\_sync\_master\_wait\_point](../semisynchronous-replication/index#rpl_semi_sync_master_wait_point) is used to set the wait point, Its allowed values are:

 * `AFTER_SYNC`: After committing the transaction in the binary log, but before committing it to the storage engine. After a crash, a transaction may be present in the binary log even if it was not committed.
* `AFTER_COMMIT`. After committing a transaction both in the binary log and in the storage engine. In case of a crash, a transaction could possibly be committed in the primary but not replicated in the slaves. This is the default.

 Primary timeout is meant to avoid that a primary remains stuck for a long time, or virtually forever, because no replica acknowledges a transaction. If primary timeout is reached, the primary switches to asynchronous replication. Before doing that, the primary writes an error in the [error log](../error-log/index) and increments the [Rpl\_semi\_sync\_master\_no\_times](../semisynchronous-replication-plugin-status-variables/index#rpl_semi_sync_master_no_times) status variable.

 The timeout is set via the [rpl\_semi\_sync\_master\_timeout](../semisynchronous-replication/index#rpl_semi_sync_master_timeout) variable.

 Galera Cluster
--------------

 [Galera](../galera-cluster/index) is a technology that implements virtually synchronous, primary-primary replication for a cluster of MariaDB servers.

 ### Raft and the Primary Cluster

 Nodes of the cluster communicate using the Raft protocol. In case the cluster is partitioned or some nodes crash, a cluster knows that it's still the *primary cluster* if it has the *quorum*: half of the nodes + 1. Only the primary cluster accepts reads and writes.

 For this reason a cluster should consist of an odd number of nodes. Imagine for example that a cluster consists of two nodes: if one of them crashes of the connection between them is interrupted, there will be no primary cluster.

 ### Transaction Certification

 A transaction can be executed against any node. The node will use a 2-phase commit. After running the transaction locally, the node will ask other nodes to *certify* it. This means that other nodes will receive it, and will try to apply it, and will report success or a failure. The node that received the transaction will not wait for an answer from all the nodes. Once it succeeded on more than half of the nodes (the quorum) the node will run the final commit and data becomes visible.

 It is desirable to write data on only one node (unless it fails), or write different databases on different nodes. This will minimize the risk of conflicts.

 ### Galera Cache and SST

 Data changes applied are recorded for some time in the *Galera cache*. This is an on-disk cache, written in a circularly written file.

 The size of Galera cache can be tuned using the [wsrep\_provider\_options](../wsrep_provider_options/index) system variable, which contains many flags. We need to tune [gcache.size](../wsrep_provider_options/index#gcachesize). To tune it, add a line similar to the following to a configuration file:

 
```
wsrep_provider_options = 'gcache.size=2G';

```

If a single transaction is bigger than half of the Galera cache, it needs to be written in a separate file, as *on-demand pages*. On-demand pages are regularly replaced. Whether a new page replaces an old one depends on another wsrep\_provider\_options flag: `wsrep_provider_options#gcachekeep_pages_size|gcache.keep_pages_size`, which limits the total size of on-demand pages.

 When a node is restarted (after a crash or for maintenance reasons), it will need to receive all the changes that were written by other nodes since the moment it was unreachable. A node is therefore chosen as a donor, possibly using the [gcssync\_donor](../wsrep_provider_options/index#gcssync_donor) wsrep\_provider\_options flag.

 If possible, the donor will send all the recent changes, reading them from the Galera cache and on-demand pages. However, sometimes the Galera cache is not big enough to contain all the needed changes, or the on-demand pages have been overwritten because `gcache.keep_pages_size` is not big enough. In these cases, a [State Snapshot Transfer (SST)](../state-snapshot-transfers-ssts-in-galera-cluster/index) needs to be sent. This means that the donor will send the whole dataset to the restarted node. Most commonly, this happens using the [mariabackup method](../mariabackup-sst-method/index).

 ### Flow Control

 While transaction certification is synchronous, certified transactions are applied locally in asynchronous fashion. However, a node should never lag too much behind others. To avoid that, a node may occasionally trigger a mechanism called *flow control* to ask other nodes to stop replication until its situation improves. Several [wsrep\_provider\_options](../wsrep_provider_options/index) flags affect flow control.

 [gcs.fc\_master\_slave](../wsrep_provider_options/index#gcsfc_master_slave) should normally be set to 1 if all writes are sent to a single node.

 [gcs.fc\_limit](../wsrep_provider_options/index#gcsfc_limit) is tuned automatically, unless [gcs.fc\_master\_slave](../wsrep_provider_options/index#gcsfc_master_slave) is set to 0. The *receive queue* (the transactions received and not yet applied) should not exceed this limit. When this happens, flow control is triggered by the node to pause other node's replication.

 Once flow control is activated, [gcs.fc\_factor](../wsrep_provider_options/index#gcsfc_factor) determines when it is released. It is a number from 0 to 1, and it represents a fraction. When the receive queue is below this fraction, the flow control is released.

 Flow control and the receive queue can and should be monitored. The most useful metrics are:

 * [wsrep\_flow\_control\_paused](../galera-cluster-status-variables/index#wsrep_flow_control_paused) indicates how many times the replication has been paused as requested by other nodes, since the last `FLUSH STATUS`.
* [wsrep\_flow\_control\_sent](../galera-cluster-status-variables/index#wsrep_flow_control_sent) indicates how many times this node requested other nodes to pause replication.
* [wsrep\_local\_recv\_queue](../galera-cluster-status-variables/index#wsrep_local_recv_queue) is the size of the receive queue.

 ### Configuration

 Galera is implemented as a plugin. Starting from version 10.1, MariaDB comes with Galera pre-installed, but not in use by default. To enable it one has to set the [wsrep\_on](../galera-cluster-system-variables/index#wsrep_on) system variable.

 Like asynchronous replication, Galera uses the binary log. It also requires that data changes are logged in the `ROW` format.

 For other required settings, see [Mandatory Options](../configuring-mariadb-galera-cluster/index#mandatory-options).

 Galera Limitations
------------------

 Galera is not suitable for all databases and workloads.

 * Galera only replicates [InnoDB](../innodb/index) tables. Other storage engines should not be used.
* For performance reasons, it is highly desirable that all tables have a primary key.
* Long transactions will damage performance.
* Some applications use an integer [AUTO\_INCREMENT](../auto_increment/index) primary key. In case of failover from a crashed node to another, Galera does not guarantee that `AUTO_INCREMENT` follows a chronological order. Therere, applications should use [TIMESTAMP](../timestamp/index) columns for chronological order instead.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-replication-overview-for-sql-server-users/>

Moving Data Between SQL Server and MariaDB
==========================================

    There are several ways to move data between SQL Server and MariaDB. Here we will discuss them and we will highlight some caveats.

 Moving Data Definition from SQL Server to MariaDB
-------------------------------------------------

 To copy SQL Server data structures to MariaDB, one has to:

 1. Generate a CSV file from SQL Server data.
2. Modify the syntax so that it works in MariaDB.
3. Run the file in MariaDB.

 ### Variables That Affect DDL Statements

 DDL statements are affected by some server system variables.

 [sql\_mode](../sql-mode/index) determines the behavior of some SQL statements and expressions, including how strict error checking is, and some details regarding the syntax. Objects like [stored procedures](../stored-procedures/index), [stored functions](../stored-functions/index) [triggers](../triggers/index) and [views](../views/index), are always executed with the sql\_mode that was in effect during their creation. [sql\_mode='MSSQL'](../sql_modemssql/index) can be used to have MariaDB behaving as close to SQL Server as possible.

 [innodb\_strict\_mode](../innodb-system-variables/index#innodb_strict_mode) enables the so-called InnoDB strict mode. Normally some errors in the [CREATE TABLE](../create-table/index) options are ignored. When InnoDB strict mode is enabled, the creation of InnoDB tables will fail with an error when certain mistakes are made.

 [updatable\_views\_with\_limit](../server-system-variables/index#updatable_views_with_limit) determines whether view updates can be made with an [UPDATE](../update/index) or [DELETE](../delete/index) statement with a `LIMIT` clause if the view does not contain all primary or not null unique key columns from the underlying table.

 ### Dumps and sys.sql\_modules

 SQL Server Management Studio allows one to create a working SQL script to recreate a database - something that MariaDB users refer to as a *dump*. Several options allow fine-tuning the generated syntax. It could be necessary to adjust some of these options to make the output compatible with MariaDB. It is possible to export schemas, data or both. One can create a single global file, or one file for each exported object. Normally, producing a single file is more practical.

 Alternatively, the [sp\_helptext()](https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-helptext-transact-sql) procedure returns information about how to recreate a certain object. Similar information is also present in the [sql\_modules](https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-sql-modules-transact-sql) table (`definition` column), in the `sys` schema. Such information, however, is not a ready-to-use set of SQL statements.

 Remember however that [MariaDB does not support schemas](../understanding-mariadb-architecture/index#databases). An SQL Server schema is approximately a MariaDB database.

 To execute a dump, we can pass the file to [mariadb](../mariadb-command-line-client/index), the MariaDB command-line client.

 Provided that a dump file contains syntax that is valid in MariaDB, it can be executed in this way:

 
```
mariadb --show-warnings < dump.sql

```

`--show-warnings` tells MariaDB to output any warnings produced by the statements contained in the dump. Without this option, warnings will not appear on screen. Warnings don't stop the dump execution.

 Errors will appear on screen. Errors will stop the dump execution, unless the `--force` option (or just `-f`) is specified.

 For other `mariadb` options, see [mariadb Command-line Client Options](../mariadb-command-line-client/index#options).

 Another way to achieve the same purpose is to start the `mariadb` client in interactive mode first, and then run the `source` command. For example:

 
```
root@d5a54a082d1b:/# mariadb -uroot -psecret
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 22
Server version: 10.4.7-MariaDB-1:10.4.7+maria~bionic mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> \W
Show warnings enabled.
MariaDB [(none)]> source dump.sql

```

In this case, to show warnings we used the `\W` command, where "w" is uppercase. To hide warnings (which is the default), we can use `\w` (lowercase).

 For other `mariadb` commands, see [mariadb Commands](../mariadb-command-line-client/index#mariadb-commands).

 ### CSV Data

 If the table structures are already in MariaDB, we need only to import table data. While this can still be done as explained above, it may be more practical to export CSV files from SQL Server and import them into MariaDB.

 SQL Server Management Studio and several other Microsoft tools allow one to export CSV files.

 MariaDB allows importing CSV files with the [LOAD DATA INFILE](../load-data-infile/index) statement, which is essentially the MariaDB equivalent of `BULK INSERT`.

 It can happen that we don't want to import the whole data, but some filtered or transformed version of it. In that case, we may prefer to use the [CONNECT](../connect/index) storage engine to access CSV files and query them. The results of a query can be inserted into a table using [INSERT SELECT](../insert-select/index).

 Moving Data from MariaDB to SQL Server
--------------------------------------

 There are several ways to move data from MariaDB to SQL Server:

 * If the tables don't exist at all in SQL Server, we need to generate a dump first. The dump can include data or not.
* If the tables are already in SQL Server, we can use CSV files instead of dumps to move the rows. CSV files are the most concise format to move data between different technologies.
* With the tables already in SQL Server, another way to move data is to insert the rows into [CONNECT](../connect/index) tables that "point" to remote SQL Server tables.

 ### Using a Dump (Structure)

 [mariadb-dump](../mariadb-dump/index) can be used to generate dumps of all databases, a specified database, or a set of tables. It is even possible to only dump a set of rows by specifying the `WHERE` clause.

 By specifying the `--no-data` option we can dump the table structures without data.

 `--compatible=mssql` will produce an output that should be usable in SQL Server.

 ### Using a Dump (Data)

 mariadb-dump by default produces an output with both data and structure.

 `--no-create-info` can be used to skip the [CREATE TABLE](../create-table/index) statements.

 `--compatible=mssql` will produce an output that should be usable in SQL Server.

 `--single-transaction` should be specified to select the source data in a single transaction, so that a consistent dump is produced.

 `--quick` speeds up the dump process when dumping big tables.

 ### Using a CSV File

 CSV files can also be used to export data to SQL Server. There are several ways to produce CSV files from MariaDB:

 * The [SELECT INTO OUTFILE](../select-into-outfile/index) statement.
* The [CONNECT](../connect/index) storage engine, with the [CSV table type](../connect-csv-and-fmt-table-types/index).
* The [CSV](../csv/index) storage engine (note that it doesn't support `NULL` and indexes).

 ### Using CONNECT Tables

 The [CONNECT](../connect/index) storage engine allows one to access external data, in many forms:

 * [Data files](../connect-table-types-data-files/index) ([CSV](../connect-csv-and-fmt-table-types/index), [JSON](../connect-json-table-type/index), [XML](../connect-xml-table-type/index), HTML and more).
* Remote databases, using the [ODBC](../connect-odbc-table-type-accessing-tables-from-another-dbms/index) or [JDBC](../connect-jdbc-table-type-accessing-tables-from-another-dbms/index) standards, or [MariaDB/MySQL native protocol](../connect-mysql-table-type-accessing-mysqlmariadb-tables/index).
* Some [special data sources](../connect-table-types-special-virtual-tables/index).

 `CONNECT` was mentioned previously because it could allow one to read a CSV file and query it in SQL, filtering and transforming the data that we want to move into regular MariaDB tables.

 However, `CONNECT` can also access remote SQL Server tables. We can read data from it, or even write data.

 To enable `CONNECT` to work with SQL Server, we need to fulfill these requirements:

 * Install the ODBC driver, downloadable form [Microsoft](https://microsoft.com/) website. The driver is also available for Linux and MacOS.
* Install [unixODBC](http://www.unixodbc.org/).
* [Install `CONNECT`](../installing-the-connect-storage-engine/index) (unless it is already installed).

 Here is an example of a `CONNECT` table that points to a SQL Server table:

 
```
CREATE TABLE city (
    id INT PRIMARY KEY,
    city_name VARCHAR(100),
    province_id INT NOT NULL
)
    ENGINE=CONNECT,
    TABLE_TYPE=ODBC,
    TABNAME='city'
    CONNECTION='Driver=SQL Server Native Client 13.0;Server=sql-server-hostname;Database=world;UID=mariadb_connect;PWD=secret';

```

The key points here are:

 * `ENGINE=CONNECT` tells MariaDB that we want to create a `CONNECT` table.
* `TABLE_TYPE` must be 'ODBC', so `CONNECT` knows what type of data source it has to use.
* `CONNECTION` is the connection string to use, including server address, username and password.
* `TABNAME` tells `CONNECT` what the remote table is called. The local name could be different.

 `CONNECT` is able to query SQL Server to find out the remote table structure. We can use this feature to avoid specifying the column names and types:

 
```
CREATE TABLE city
    ENGINE=CONNECT,
    TABLE_TYPE=ODBC,
    TABNAME='city'
    CONNECTION='Driver=SQL Server Native Client 13.0;Server=sql-server-hostname;Database=world;UID=mariadb_connect;PWD=secret';

```

However, we may prefer to manually specify the MariaDB types, sizes and character sets to use.

 ### Linked Server

 Instead of using MariaDB `CONNECT`, it is possible to use SQL Server Linked Server functionality. This will allow one to read data from a remote MariaDB database and copy it into local SQL Server tables. However, note that `CONNECT` allows more control on [types and character sets](../sql-server-and-mariadb-types-comparison/index) mapping.

 Refer to [Linked Servers](https://docs.microsoft.com/en-us/sql/relational-databases/linked-servers/linked-servers-database-engine?view=sql-server-ver15) section in Microsoft documentation.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/moving-data-between-sql-server-and-mariadb/>

Oracle XE 11.2. and MariaDB 10.1 integration on Ubuntu 14.04 and Debian systems
===============================================================================

     1) Sign up for Oracle downloads and download Oracle Express at:

 <http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html>

 - Sign up (unless already) and log in. - Accept the license agreement. - Download Oracle Database Express Edition 11g Release 2 for Linux x64 (oracle-xe-11.2.0-1.0.x86\_64.rpm.zip, version numbers may change over time)

 2) Prepare apt-get on your system

 
```
sudo add-apt-repository ppa:webupd8team/java
<press Enter to accept>
sudo apt-get update
sudo apt-get install oracle-java8-installer

```

3) After Java installation, verify the version

 
```
java -version
java version "1.8.0_121"

```

4) Edit /etc/bash.bashrc

 Scroll to the bottom of the file and add the following lines.

 
```
export JAVA_HOME=/usr/lib/jvm/java-8-oracle
export PATH=$JAVA_HOME/bin:$PATH

```

Save and check:

 
```
source /etc/bash.bashrc
echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle

```

5) Additional packages are required, unless installed already. Run the command:

 
```
sudo apt-get install alien libaio1 unixodbc

```

6)

 
```
unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip
cd Disk1/
sudo alien --scripts -d oracle-xe-11.2.0-1.0.x86_64.rpm

```

This step might take some time. You may proceed steps 7)-11) in the meanwhile in another terminal window.

 7)

 Create a new file /sbin/chkconfig and add the following contents

 
```
#!/bin/bash
# Oracle 11gR2 XE installer chkconfig for Ubuntu
file=/etc/init.d/oracle-xe
if [[ ! `tail -n1 $file | grep INIT` ]]; then
echo >> $file
echo '### BEGIN INIT INFO' >> $file
echo '# Provides: OracleXE' >> $file
echo '# Required-Start: $remote_fs $syslog' >> $file
echo '# Required-Stop: $remote_fs $syslog' >> $file
echo '# Default-Start: 2 3 4 5' >> $file
echo '# Default-Stop: 0 1 6' >> $file
echo '# Short-Description: Oracle 11g Express Edition' >> $file
echo '### END INIT INFO' >> $file
fi
update-rc.d oracle-xe defaults 80 01
#EOF

```

8)

 
```
sudo chmod 755 /sbin/chkconfig

```

9)

 Create a new file /etc/sysctl.d/60-oracle.conf

 Copy and paste the following into the file. Kernel.shmmax is the maximum possible value of physical RAM in bytes. 536870912 / 1024 /1024 = 512 MB.

 
```
#Oracle 11g XE kernel parameters  
fs.file-max=6815744  
net.ipv4.ip_local_port_range=9000 65000  
kernel.sem=250 32000 100 128 
kernel.shmmax=536870912

```

10)

 
```
sudo service procps start
sudo sysctl -q fs.file-max

```

1. This method should return the following: fs.file-max = 6815744

 11) Some additional steps required

 
```
sudo ln -s /usr/bin/awk /bin/awk
mkdir /var/lock/subsys
touch /var/lock/subsys/listener

```

12) Install Oracle XE (should have been converted from .rpm to .deb by now)

 
```
sudo dpkg --install oracle-xe_11.2.0-2_amd64.deb

```

13)

 Execute the following to avoid getting a ORA-00845: MEMORY\_TARGET error. Note: replace "size=4096m" with the size of your (virtual) machine RAM in MBs.

 
```
sudo rm -rf /dev/shm
sudo mkdir /dev/shm
sudo mount -t tmpfs shmfs -o size=4096m /dev/shm

```

14) Create the file /etc/rc2.d/S01shm\_load

 NOTE: replace "size=4096m" with the size of your machine RAM in MBS.

 
```
#!/bin/sh
case "$1" in
start) mkdir /var/lock/subsys 2>/dev/null
touch /var/lock/subsys/listener
rm /dev/shm 2>/dev/null
mkdir /dev/shm 2>/dev/null
mount -t tmpfs shmfs -o size=4096m /dev/shm ;;
*) echo error
exit 1 ;;
esac

```


```
sudo chmod 755 /etc/rc2.d/S01shm_load

```

15) Configure Oracle 11g R2 Express Edition. Default answers are probably OK.

 
```
sudo /etc/init.d/oracle-xe configure

```

Specify the HTTP port that will be used for Oracle Application Express [8080]:

 Specify a port that will be used for the database listener [1521]:

 Specify a password to be used for database accounts. Note that the same password will be used for SYS and SYSTEM. Oracle recommends the use of different passwords for each database account. This can be done after initial configuration: 

 Do you want Oracle Database 11g Express Edition to be started on boot (y/n) [y]:

 16) Edit /etc/bash.bashrc. Add to the end of the file:

 
```
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe
export ORACLE_SID=XE
export NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh`
export ORACLE_BASE=/u01/app/oracle
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
export PATH=$ORACLE_HOME/bin:$PATH

```

Save.

 17) Run source command and check that the output makes sense

 
```
source /etc/bash.bashrc
echo $ORACLE_HOME
/u01/app/oracle/product/11.2.0/xe

```

18) Apply desktop icon changes and start Oracle:

 
```
sudo chmod a+x ~/Desktop/oraclexe-gettingstarted.desktop
sudo service oracle-xe start

```

19) Download SQL Developer package

 Download Oracle SQL Developer from the Oracle site. Select the Linux RPM package: <http://www.oracle.com/technetwork/developer-tools/sql-developer/downloads/index.html>

 Choose the Linux RPM package.

 20) Install SQL Developer

 
```
sudo alien --scripts -d sqldeveloper-4.1.5.21.78-1.noarch.rpm
sudo dpkg --install sqldeveloper_4.1.5.21.78-2_all.deb
mkdir ~/.sqldeveloper

```

21) Run sqldeveloper:

 
```
sudo /opt/sqldeveloper/sqldeveloper.sh

```

1. Tell sqldeveloper the correct Java path, if it asks for it:

 /usr/lib/jvm/java-8-oracle

 
```
- Click connections
- Add new connection
- Connection name: XE
- username: SYSTEM
- password: <your-password>

- Connection type: Basic Role: Default
- Hostname: localhost
- Port: 1521
- SID: xe

```

MariaDB
-------

 22) Install MariaDB

 <https://downloads.mariadb.org/mariadb/repositories/> Instructions are for Ubuntu, but choose the one that is appropriate: - Ubuntu - 14.04 LTS "trusty" - 10.1 [Stable] - choose a mirror

 Run the commands given for you. For example (DO NOT COPY PASTE BELOW, CHECK WHAT THE MariaDB PAGE TELLS YOU TO DO):

 
```
sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] http://mirror.netinch.com/pub/mariadb/repo/10.1/ubuntu trusty main'
sudo apt-get update

```

1. Install mariadb-server:

 
```
sudo apt-get install mariadb-server

```

23) Install ODBC driver

 <https://downloads.mariadb.org/connector-odbc/>

 1. MariaDB Connector/ODBC 2.0.13 Stable for Linux

 Download: mariadb-connector-[ODBC-2](https://jira.mariadb.org/browse/ODBC-2).0.13-ga-linux-x86\_64.tar.gz

 
```
tar xfz mariadb-connector-odbc-2.0.13-ga-linux-x86_64.tar.gz
sudo cp -p mariadb-connector-odbc-2.0.13-ga-linux-x86_64/lib/libmaodbc.so /lib
sudo ldconfig

```

24) Install unixodbc and mariadb-connect engine

 
```
apt-get install unixodbc-dev
apt-get install unixodbc-bin
apt-get install unixodbc
apt-get install libodbc1
apt-get install mariadb-connect-engine-10.1

```

25) Edit /etc/odbcinst.ini

 Add:

 
```
[Oracle ODBC driver for Oracle 11.2]
Description     = Oracle 11.2 ODBC driver
Driver          = /u01/app/oracle/product/11.2.0/xe/lib/libsqora.so.11.1

```

26) Edit /etc/odbc.ini

 Add (check your password):

 
```
[XE]
Driver          = Oracle ODBC driver for Oracle 11.2
ServerName      = //localhost:1521/xe
DSN             = XE
UserName        = SYSTEM
Password        = <your-password>

```

27) Test ODBC connection and add a table

 
```
isql -v XE SYSTEM <your-password>

create table t1 (i int);
insert into t1 (i) values (1);
insert into t1 (i) values (3);
insert into t1 (i) values (5);
insert into t1 (i) values (8);
select i from t1;

```

And you should see the rows. You can test the same with sqldeveloper, open XE connection and run select i from t1; in Worksheet.

 28) Edit /etc/init.d/mysql

 Add:

 
```
export JAVA_HOME=/usr/lib/jvm/java-8-oracle 
export PATH=$JAVA_HOME/bin:$PATH 
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/xe 
export CLIENT_HOME=$ORACLE_HOME 
export ORACLE_SID=XE 
export NLS_LANG=`$ORACLE_HOME/bin/nls_lang.sh` 
export ORACLE_BASE=/u01/app/oracle 
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH 
export PATH=$ORACLE_HOME/bin:$PATH 

```

Right after END INIT INFO. Otherwise mysqld will not find the Oracle ODBC driver.

 28) Restart MariaDB

 
```
sudo /etc/init.d/mysql restart

```

29)

 
```
mysql -uroot -p

CREATE DATABASE mdb;
USE mdb;
INSTALL SONAME 'ha_connect';
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC tabname='T1' CONNECTION='DSN=XE;UID=SYSTEM;PWD=<your-password>';

select I from t1;

```

You should see the previously inserted values 1,3,5 and 8. Using isql or sqldeveloper, add another rows with values 9 and 11. Remember to commit, if you are using Oracle sqldeveloper. You should now see the added values via MariaDB client (mysql-client) connection.

 To be examined: inserting values to the t1 table from mariadb connection does not work. It gives a precision error from Oracle side.

 Connect to MariaDB via JDBC
---------------------------

 Download MySQL Connector from <https://dev.mysql.com/downloads/connector/j/5.0.html>

 Select Version (for example 5.0.8)

 Platform independent. Download mysql-connector-java-5.0.8.tar.gz

 
```
tar xvfz mysql-connector-java-5.0.8.tar.gz
cd mysql-connector-java-5.0.8/
sudo cp -p mysql-connector-java-5.0.8-bin.jar /usr/lib/jvm/java-8-oracle/lib/mariadb/

sudo /opt/sqldeveloper/sqldeveloper.sh

```

In SQL Developer choose Tools -> Preferences

 Expand the "Database" option in the left hand tree

 Click on "Third Party JDBC Drivers"

 Click on "Add Entry..."

 Navigate to your third-party driver jar file and choose OK

 /usr/lib/jvm/java-8-oracle/lib/mariadb/mysql-connector-java-5.0.8-bin.jar

 Click Connections -> New connection.

 Add values. The following are examples:

 
```
Connection Name: MariaDB via MySQL Conn
Username: root
Password: ********
Save Password: [x]

Choose MySQL tab

Hostname: localhost
Port: 3306

Click "Test Connection". It should says Status: Success.
Click Save.
Click Connect.

```

You are connected. You may run commands in the Worksheet. For example:

 use mdb;

 show tables;

 You should see the tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/oracle-xe-112-and-mariadb-101-integration-on-ubuntu-1404-and-debian-systems/>

MIN/MAX optimization
====================

    Min/Max optimization without GROUP BY
-------------------------------------

 MariaDB and MySQL can optimize the [MIN()](../min/index) and [MAX()](../max/index) functions to be a single row lookup in the following cases:

 * There is only one table used in the `SELECT`.
* You only have constants, `MIN()` and `MAX()` in the `SELECT` part.
* The argument to `MIN()` and `MAX()` is a simple column reference that is part of a key.
* There is no `WHERE` clause or the `WHERE` is used with a constant for all prefix parts of the key before the argument to `MIN()`/`MAX()`.
* If the argument is used in the `WHERE` clause, it can be be compared to a constant with `<` or `<=` in case of `MAX()` and with `>` or `>=` in case of `MIN()`.

 Here are some examples to clarify this. In this case we assume there is an index on columns `(a,b,c)`

 
```
SELECT MIN(a),MAX(a) from t1
SELECT MIN(b) FROM t1 WHERE a=const
SELECT MIN(b),MAX(b) FROM t1 WHERE a=const
SELECT MAX(c) FROM t1 WHERE a=const AND b=const
SELECT MAX(b) FROM t1 WHERE a=const AND b<const
SELECT MIN(b) FROM t1 WHERE a=const AND b>const
SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const

```

* Instead of `a=const` the condition `a IS NULL` can be used.

 The above optimization also works for [subqueries](../subqueries/index):

 
```
SELECT x from t2 where y= (SELECT MIN(b) FROM t1 WHERE a=const)

```

Cross joins, where there is no join condition for a table, can also be optimized to a few key lookups:

 
```
select min(t1.key_part_1), max(t2.key_part_1) from t1, t2

```

Min/Max optimization with GROUP BY
----------------------------------

 MariaDB and MySQL support loose index scan, which can speed up certain `GROUP BY` queries. The basic idea is that when scanning a `BTREE` index (the most common index type for the MariaDB storage engines) we can jump over identical values for any prefix of a key and thus speed up the scan significantly.

 Loose scan is possible in the following cases:

 * The query uses only one table.
* The `GROUP BY` part only uses indexed columns in the same order as in the index.
* The only aggregated functions in the `SELECT` part are `MIN()` and `MAX()` functions and all of them using the same column which is the next index part after the used `GROUP BY` columns.
* Partial indexed columns cannot be used (like only indexing 10 characters of a `VARCHAR(20)` column).

 Loose scan will apply for your query if [`EXPLAIN`](../explain/index) shows `Using index for group-by` in the `Extra` column. In this case the optimizer will do only one extra row fetch to calculate the value for `MIN()` or `MAX()` for every unique key prefix.

 The following examples assume that the table `t1` has an index on `(a,b,c)`.

 
```
SELECT a, b, MIN(c),MAX(c) FROM t1 GROUP BY a,b

```

See also
--------

 * [MIN()](../min/index)
* [MAX()](../max/index)
* [MySQL manual on loose index scans](http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/minmax-optimization/>

Performance Schema threads Table
================================

    Each server thread is represented as a row in the `threads` table.

 The `threads` table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | A unique thread identifier. |
| `NAME` | Name associated with the server's thread instrumentation code, for example `thread/sql/main` for the server's `main()` function, and `thread/sql/one_connection` for a user connection. |
| `TYPE` | `FOREGROUND` or `BACKGROUND`, depending on the thread type. User connection threads are `FOREGROUND`, internal server threads are `BACKGROUND`. |
| `PROCESSLIST_ID` | The `PROCESSLIST.ID` value for threads displayed in the `INFORMATION_SCHEMA.PROCESSLIST` table, or `0` for background threads. Also corresponds with the `CONNECTION_ID()` return value for the thread. |
| `PROCESSLIST_USER` | Foreground thread user, or `NULL` for a background thread. |
| `PROCESSLIST_HOST` | Foreground thread host, or `NULL` for a background thread. |
| `PROCESSLIST_DB` | Thread's default database, or `NULL` if none exists. |
| `PROCESSLIST_COMMAND` | Type of command executed by the thread. These correspond to the the `COM_xxx` client/server protocol commands, and the `Com_xxx` [status variables](../server-status-variables/index). See [Thread Command Values](../thread-command-values/index). |
| `PROCESSLIST_TIME` | Time in seconds the thread has been in its current state. |
| `PROCESSLIST_STATE` | Action, event or state indicating what the thread is doing. |
| `PROCESSLIST_INFO` | Statement being executed by the thread, or `NULL` if a statement is not being executed. If a statement results in calling other statements, such as for a [stored procedure](../stored-procedures/index), the innermost statement from the stored procedure is shown here. |
| `PARENT_THREAD_ID` | `THREAD_ID` of the parent thread, if any. Subthreads can for example be spawned as a result of [INSERT DELAYED](../insert-delayed/index) statements. |
| `ROLE` | Unused. |
| `INSTRUMENTED` | `YES` or `NO` for Whether the thread is instrumented or not. For foreground threads, the initial value is determined by whether there's a user/host match in the [setup\_actors](../performance-schema-setup_actors-table/index) table. Subthreads are again matched, while for background threads, this will be set to `YES` by default. To monitor events that the thread executes, `INSTRUMENTED` must be `YES` and the thread\_instrumentation consumer in the [setup\_consumers](../performance-schema-setup_consumers-table/index) table must also be `YES`. |
| `HISTORY` | `YES` or `NO` for Whether to log historical events for the thread. For foreground threads, the initial value is determined by whether there's a user/host match in the [setup\_actors](../performance-schema-setup_actors-table/index) table. Subthreads are again matched, while for background threads, this will be set to `YES` by default. To monitor events that the thread executes, `INSTRUMENTED` must be `YES` and the thread\_instrumentation consumer in the [setup\_consumers](../performance-schema-setup_consumers-table/index) table must also be `YES`. Added in [MariaDB 10.5](../what-is-mariadb-105/index). |
| `CONNECTION_TYPE` | The protocol used to establish the connection. One of `TCP/IP`, `SSL/TLS`, `Socket`, `Named Pipe`, `Shared Memory`, or `NULL` for background threads. Added in [MariaDB 10.5](../what-is-mariadb-105/index). |
| `THREAD_OS_ID` | The thread or task identifier as defined by the underlying operating system, if there is one. Added in [MariaDB 10.5](../what-is-mariadb-105/index) |

 
Example
-------

 
```
SELECT * FROM performance_schema.threads\G;
*************************** 1. row ***************************
          THREAD_ID: 1
               NAME: thread/sql/main
               TYPE: BACKGROUND
     PROCESSLIST_ID: NULL
   PROCESSLIST_USER: NULL
   PROCESSLIST_HOST: NULL
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: NULL
   PROCESSLIST_TIME: 215859
  PROCESSLIST_STATE: Table lock
   PROCESSLIST_INFO: INTERNAL DDL LOG RECOVER IN PROGRESS
   PARENT_THREAD_ID: NULL
               ROLE: NULL
       INSTRUMENTED: YES
...
*************************** 21. row ***************************
          THREAD_ID: 64
               NAME: thread/sql/one_connection
               TYPE: FOREGROUND
     PROCESSLIST_ID: 44
   PROCESSLIST_USER: root
   PROCESSLIST_HOST: localhost
     PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: Query
   PROCESSLIST_TIME: 0
  PROCESSLIST_STATE: Sending data
   PROCESSLIST_INFO: SELECT * FROM performance_schema.threads
   PARENT_THREAD_ID: NULL
               ROLE: NULL
       INSTRUMENTED: YES


```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-threads-table/>

Quality
========

   This section collects articles related to MariaDB quality assurance efforts.

  

| Title | Description |
| --- | --- |
|  [mariadb-test](../mariadb-test/index) |  Testing utility  |
|  [Code Coverage](../code-coverage/index) |  Getting more MariaDB source code covered by the MTR test suite  |
|  [Code Coverage with dgcov](../dgcov/index) |  The dgcov tool helps you check the coverage for new code.  |
|  [QA Tests](../qa-tests/index) |  Various tests used for QA  |
|  [QA Metrics](../qa-metrics/index) |  Code Coverage and Bugs  |
|  [QA Datasets](../qa-datasets/index) |  Realistic datasets are essential for proper testing.  |
|  [QA Tools](../qa-tools/index) |  Tools used for quality assurance testing.  |
|  [Optimizer Quality](../optimizer-quality/index) |  Generating queries, validating results, and so on.  |
|  [QA - Aria Recovery](../qa-aria-recovery/index) |  General principles and tests used to ensure Aria recovery is solid.  |
|  [Benchmarks and Long Running Tests](../benchmarks-and-long-running-tests/index) |  Here you will find details about our automated benchmark runs and long runn...  |
|  [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index) |  The purpose of this template is to produce individual checklists for testi...  |
|  [InnoDB Upgrade Tests](../innodb-upgrade-tests/index) |  RQG-based upgrade tests with focus on InnoDB data live upgrade  |
|  [Random Query Generator Tests](../random-query-generator-tests/index) |  Automatic tests using the Random Query Generator.  |
|  [RQG Extensions for MariaDB](../rqg-extensions-for-mariadb/index) |  Extensions added to the random query generator for MariaDB testing.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/quality/>

General Development Information
================================

  

| Title | Description |
| --- | --- |
|  [MariaDB Releases](../mariadb-releases/index) |  List of releases of MariaDB software and what they contain.  |
|  [Plans](../development-plans/index) |  MariaDB Development Plans  |
|  [MariaDB Users & Developers](../resources/index) |  Connect and interact with other MariaDB users and developers.  |
|  [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index) |  How to contribute to the MariaDB project: code, documentation, feedback, etc.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/general-development-information/>

MariaDB Development Tools
==========================

   Tools for developing MariaDB.

  

| Title | Description |
| --- | --- |
|  [Using Git with MariaDB](../using-git-with-mariadb/index) |  How to use git to troubleshoot the source code or contribute code to MariaDB.  |
|  [Compiling MariaDB From Source](../compiling-mariadb-from-source/index) |  Articles on compiling MariaDB from source  |
|  [Buildbot](../buildbot/index) |  Pages about buildbot  |
|  [MariaDB FTP Server](../mariadb-ftp-server/index) |  Information on connecting to MariaDB's FTP server.  |
|  [IRC Chat Servers and Zulip Instance](../irc-chat-servers-and-zulip-instance/index) |  Chat servers for discussing MariaDB software.  |
|  [Worklog](../worklog/index) |  Worklog has been replaced by JIRA.  |
|  [JIRA - Project Planning and Tracking](../jira/index) |  JIRA is used for project planning and tracking in MariaDB development.  |
|  [Tools Available for Developing on the MariaDB Code](../tools-available-for-developing-on-the-mariadb-code/index) |  What Tools are Available for Developing the MariaDB Code.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/tools/>

MariaDB Internals Documentation
================================

   Documentation on the internal workings of MariaDB.

  

| Title | Description |
| --- | --- |
|  [Contributing Code](../contributing-code/index) |  Guidelines and procedures for contributing code to MariaDB.  |
|  [Writing Plugins for MariaDB](../development-writing-plugins-for-mariadb/index) |  Writing plugins for MariaDB.  |
|  [Pluggable Authentication Overview](../pluggable-authentication-overview/index) |  The authentication of users is delegated to plugins.  |
|  [Information Schema plugins: SHOW and FLUSH statements](../information-schema-plugins-show-and-flush-statements/index) |  Information Schema plugins can support SHOW and FLUSH statements.  |
|  [Query Optimizer](../mariadb-internals-documentation-query-optimizer/index) |  Articles about the MariaDB query optimizer  |
|  [Using MariaDB with Your Programs (API)](../using-mariadb-with-your-programs-api/index) |  Using MariaDB with your programs (API)  |
|  [Storage Engine Development](../storage-engines-storage-engine-development/index) |  Storage Engine Development.  |
|  [Merging into MariaDB](../mariadb-internals-documentation-merging-into-mariadb/index) |  How to merge various source trees into MariaDB  |
|  [MariaDB Source Code Internals](../mariadb-source-code-internals/index) |  Articles about MariaDB source code and related internals.  |
|  [Encryption Plugin API](../encryption-plugin-api/index) |  MariaDB uses plugins to handle key management and encryption of data.  |
|  [Password Validation Plugin API](../password-validation/index) |  Allows the creation of password validation plugins to check user passwords as they are set.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-internals-documentation/>

DBT3 Benchmark Queries
======================

    Known things about DBT-3 benchmark and its queries

 Q1
--

 A simple, one-table query.

 
```
select
        l_returnflag,
        l_linestatus,
        sum(l_quantity) as sum_qty,
        sum(l_extendedprice) as sum_base_price,
        sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
        sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
        avg(l_quantity) as avg_qty,
        avg(l_extendedprice) as avg_price,
        avg(l_discount) as avg_disc,
        count(*) as count_order
from
        lineitem
where
        l_shipdate <= date_sub('1998-12-01', interval 79 day)
group by
        l_returnflag,
        l_linestatus
order by
        l_returnflag,
        l_linestatus;

```

Query plan:

 
```
+------+-------------+----------+------+---------------+------+---------+------+----------+----------------------------------------------+
| id   | select_type | table    | type | possible_keys | key  | key_len | ref  | rows     | Extra                                        |
+------+-------------+----------+------+---------------+------+---------+------+----------+----------------------------------------------+
|    1 | SIMPLE      | lineitem | ALL  | i_l_shipdate  | NULL | NULL    | NULL | 59711977 | Using where; Using temporary; Using filesort |
+------+-------------+----------+------+---------------+------+---------+------+----------+----------------------------------------------+

```

* l\_shipdate < date\_sub('1998-12-01', interval 79 day) is satisifed by 59,334,576 rows.
* The table has 59,986,052 rows in total.
* There are a total of 4 different values of `(l_returnflag,l_linestatus)`. This means, sorting doesn't matter, and temporary table is a very small heap table.

 Q2
--

 plans starting with table "part" ... - 8sec on cold cache. scale=10 (scale=30 ETA 1min)

 Q3
--

 
```
select
       l_orderkey, sum(l_extendedprice*(1-l_discount)) as revenue,
       o_orderdate, o_shippriority
from 
      customer, 
      orders, 
      lineitem
where 
      c_mktsegment = 'BUILDING' and c_custkey = o_custkey
      and l_orderkey = o_orderkey and o_orderdate < date '1995-03-15'
      and l_shipdate > date '1995-03-15'
group by l_orderkey, o_orderdate, o_shippriority
order by revenue desc, o_orderdate
limit 10;

```

There seems to be an improvement in mysql-5.6: <http://jorgenloland.blogspot.ru/2013/02/dbt-3-q3-6-x-performance-in-mysql-5610.html>

 (speedup can be observed only when the query is in the form like the above (TODO: figure out where do different forms of queries come from?))

 EXPLAINs (scale=10):

 
```
+------+-------------+----------+--------+---------------------------------------------------------+---------+---------+----------------------------+----------+----------------------------------------------+
| id   | select_type | table    | type   | possible_keys                                           | key     | key_len | ref                        | rows     | Extra                                        |
+------+-------------+----------+--------+---------------------------------------------------------+---------+---------+----------------------------+----------+----------------------------------------------+
|    1 | SIMPLE      | orders   | ALL    | NULL                                                    | NULL    | NULL    | NULL                       | 15115145 | Using where; Using temporary; Using filesort |
|    1 | SIMPLE      | customer | eq_ref | PRIMARY                                                 | PRIMARY | 4       | dbt3sf10.orders.o_custkey  |        1 | Using where                                  |
|    1 | SIMPLE      | lineitem | ref    | PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity | PRIMARY | 4       | dbt3sf10.orders.o_orderkey |        2 | Using where                                  |
+------+-------------+----------+--------+---------------------------------------------------------+---------+---------+----------------------------+----------+----------------------------------------------+

```


```
+------+-------------+----------+--------+---------------------------------------------------------+----------------+---------+----------------------------+---------+---------------------------------------------------------------------+
| id   | select_type | table    | type   | possible_keys                                           | key            | key_len | ref                        | rows    | Extra                                                               |
+------+-------------+----------+--------+---------------------------------------------------------+----------------+---------+----------------------------+---------+---------------------------------------------------------------------+
|    1 | SIMPLE      | orders   | range  | PRIMARY,i_o_date_clerk                                  | i_o_date_clerk | 4       | NULL                       | 7557572 | Using index condition; Using where; Using temporary; Using filesort |
|    1 | SIMPLE      | customer | eq_ref | PRIMARY                                                 | PRIMARY        | 4       | dbt3sf10.orders.o_custkey  |       1 | Using where                                                         |
|    1 | SIMPLE      | lineitem | ref    | PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity | PRIMARY        | 4       | dbt3sf10.orders.o_orderkey |       2 | Using where                                                         |
+------+-------------+----------+--------+---------------------------------------------------------+----------------+---------+----------------------------+---------+---------------------------------------------------------------------+

```

With statistics on 'building': we get a plan of customer, orders, lineitem. It is 5% worse. There seems to be no other possibilities.

 Q5
--

 Nothing good so far. 

 watch the "c\_nationkey = s\_nationkey" condition. It is a "side" condition (ie it is not from the "natural" relationships between tables). It is not clear whether accounting for its selectivity will give anything)

 Q8
--

 
```
Timour is analyzing this query.

```

Q9
--

 
```
Timour is analyzing this query.

```


```
+------+-------------+----------+--------+----------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------+------+----------+---------------------------------------------------------------------------+
| id   | select_type | table    | type   | possible_keys                                                                          | key                 | key_len | ref                                              | rows | filtered | Extra                                                                     |
+------+-------------+----------+--------+----------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------+------+----------+---------------------------------------------------------------------------+
|    1 | SIMPLE      | nation   | ALL    | PRIMARY                                                                                | NULL                | NULL    | NULL                                             |   25 |   100.00 | Using temporary; Using filesort                                           |
|    1 | SIMPLE      | supplier | ref    | PRIMARY,i_s_nationkey                                                                  | i_s_nationkey       | 5       | dbt3.nation.n_nationkey                          | 4077 |   100.00 | Using index                                                               |
|    1 | SIMPLE      | partsupp | ref    | PRIMARY,i_ps_partkey,i_ps_suppkey                                                      | i_ps_suppkey        | 4       | dbt3.supplier.s_suppkey                          |   38 |   100.00 | Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan        |
|    1 | SIMPLE      | part     | eq_ref | PRIMARY                                                                                | PRIMARY             | 4       | dbt3.partsupp.ps_partkey                         |    1 |   100.00 | Using where; Using join buffer (incremental, BKA join); Key-ordered scan  |
|    1 | SIMPLE      | lineitem | ref    | PRIMARY,i_l_suppkey_partkey,i_l_partkey,i_l_suppkey,i_l_orderkey,i_l_orderkey_quantity | i_l_suppkey_partkey | 10      | dbt3.partsupp.ps_partkey,dbt3.supplier.s_suppkey |    3 |   100.00 | Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan |
|    1 | SIMPLE      | orders   | eq_ref | PRIMARY                                                                                | PRIMARY             | 4       | dbt3.lineitem.l_orderkey                         |    1 |   100.00 | Using join buffer (incremental, BKA join); Key-ordered scan               |
+------+-------------+----------+--------+----------------------------------------------------------------------------------------+---------------------+---------+--------------------------------------------------+------+----------+---------------------------------------------------------------------------+


```

Watch for "p\_name like ..." condition. What if we force table part to be the 1st.

 Q10
---

 Q13
---

 
```
SergeyP is analyzing this query.

```


```
select
	c_count,
	count(*) as custdist
from
	(
		select
			c_custkey,
			count(o_orderkey) as c_count
		from
			customer left outer join orders on
				c_custkey = o_custkey
				and o_comment not like '%express%requests%'
		group by
			c_custkey
	) as c_orders
group by
	c_count
order by
	custdist desc,
	c_count desc;

```

Q15
---

 
```
SergeyP is analyzing this query.

```

Q17
---

 
```
Timour is analyzing this query.

```

* Q17 cannot benefit from [MDEV-89](https://jira.mariadb.org/browse/MDEV-89) because the '<' predicate depends on both query tables. No matter what is the join order, the subquery has to be attached to the last table in the plan.

 * There are no sargable conditions for 'lineitem', and it is bigger than 'part', and selectivity(p\_brand = 'Brand#43' and p\_container = 'WRAP DRUM') = 0.1%. Therefore table part should be first in the join plan.

 * selectivity(p\_partkey = l\_partkey) << selectivity(l\_quantity < (select ...)), therefore the expensive subquery will be placed correctly after the cheap join condition.

 * One possible improvement for this query is to stop the execution of the subquery as soon as the selected expression becomes false. In this case stop when (l\_quantity >= 0.2 \* avg(l\_quantity)).

 
```
select sum(l_extendedprice) / 7.0 as avg_yearly
from lineitem, part
where
  p_partkey = l_partkey
  and p_brand = 'Brand#43'
  and p_container = 'WRAP DRUM'
  and l_quantity < (select 0.2 * avg(l_quantity) from lineitem where l_partkey = p_partkey);

```


```
+------+--------------------+----------+------+---------------------------------+---------------------+---------+---------------------+---------+----------+------------------------------------------------------------------------------------------------+
| id   | select_type        | table    | type | possible_keys                   | key                 | key_len | ref                 | rows    | filtered | Extra                                                                                          |
+------+--------------------+----------+------+---------------------------------+---------------------+---------+---------------------+---------+----------+------------------------------------------------------------------------------------------------+
|    1 | PRIMARY            | part     | ALL  | PRIMARY                         | NULL                | NULL    | NULL                | 6000000 |     1.39 | Using where                                                                                    |
|    1 | PRIMARY            | lineitem | ref  | i_l_suppkey_partkey,i_l_partkey | i_l_suppkey_partkey | 5       | dbt3.part.p_partkey |      29 |   100.00 | Using where; Subqueries: 2; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan |
|    2 | DEPENDENT SUBQUERY | lineitem | ref  | i_l_suppkey_partkey,i_l_partkey | i_l_suppkey_partkey | 5       | dbt3.part.p_partkey |      29 |   100.00 |                                                                                                |
+------+--------------------+----------+------+---------------------------------+---------------------+---------+---------------------+---------+----------+------------------------------------------------------------------------------------------------+

```

Q20
---

 * This query will benefit from [MWL#253](http://askmonty.org/worklog/?tid=253) (Exact index stats), and [MDEV-83](https://jira.mariadb.org/browse/MDEV-83) (Cost-based choice for the pushdown of subqueries to joined tables).

 
```
explain extended
select sql_calc_found_rows 
  s_name, s_address
from 
  supplier, nation
where s_suppkey in (select ps_suppkey from partsupp
                    where ps_partkey in (select p_partkey from part where p_name like 'g%')
                          and ps_availqty >
                              (select 0.5 * sum(l_quantity)
                               from lineitem
                               where l_partkey = ps_partkey and l_suppkey = ps_suppkey
                                     and l_shipdate >= date('1993-01-01') and l_shipdate < date('1993-01-01') + interval '1' year ))
and s_nationkey = n_nationkey
and n_name = 'UNITED STATES'
order by s_name
limit 10;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt3-benchmark-queries/>

EXPLAIN FORMAT=JSON in MySQL
============================

    There are some things that we in MariaDB are not happy with in MySQL/Oracle's implementation of EXPLAIN FORMAT=JSON.

 The most important issues are already fixed in MariaDB's [EXPLAIN FORMAT=JSON](../explain-format-json/index) implementation. See [EXPLAIN FORMAT=JSON Differences From MySQL](../explain-format-json-differences/index) for details.

 This page lists things are are not fixed yet.

 Higher priority
---------------

 * Better display for ORDER/GROUP BY ([MDEV-6995](https://jira.mariadb.org/browse/MDEV-6995))
* Better display for Batched Key Access plans (Plain join buffering is fixed already)

 Nice to have
------------

 ### Show ranges being scanned

 Currently, one can only find the ranges produced by the range optimizer by looking into optimizer\_trace. It would be nice if EXPLAIN showed them, too

 
```
MySQL [dbt3sf1]> explain format=json select * from customer where c_acctbal < -1000 \G
*************************** 1. row ***************************
EXPLAIN: {
  "query_block": {
    "select_id": 1,
    "table": {
      "table_name": "customer",
      "access_type": "range",
      "possible_keys": [
        "c_acctbal",
        "i_c_acctbal_nationkey"
      ],
      "key": "c_acctbal",
      "used_key_parts": [
        "c_acctbal"
      ],
      "key_length": "9",
      "rows": 1,
      "filtered": 100,
      "index_condition": "(`dbt3sf1`.`customer`.`c_acctbal` < -(1000))"
    }
  }
}

```

Low priority
------------

 ### Filesort/priority queue

 Neither version of EXPLAIN in 5.6 shows the "filesort with small limit" optimization. See [MDEV-6430](https://jira.mariadb.org/browse/MDEV-6430).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-formatjson-in-mysql/>

LevelDB Storage Engine MS1
==========================

    This page describes what will be implemented for milestone#1 of [LevelDB Storage Engine](../leveldb-storage-engine/index). *For development after MS1, see [LevelDB Storage Engine Development](../leveldb-storage-engine-development/index)*

 Feature Description
===================

 How the data is stored in LevelDB
---------------------------------

 ### One leveldb instance

 We will use one LevelDB instance for mysqld process. LevelDB keys will be prefixed with 'dbname.table\_name.PRIMARY' for the table itself, and 'dbname.table\_name.index\_name' for the secondary indexes. This allows to store arbitrary number of tables/indexes in one LevelDB instance.

 ### Data encoding

 We will rely on LevelDB's compression to make the storage compact. Data that goes into LevelDB's key will be stored in KeyTupleFormat (which allows mysql's lookup/index ordering functions to work). 

 Data that goes into LevelDB's value will be stored in table->record[0] format, except blobs. (Blobs will require special storage convention because they store a char\* pointer in table->record[0]). 

 We will need to support blobs because table `nodetable` has a `mediumtext` field.

 ### Secondary indexes

 Non-unique secondary indexes will be supported.

 LevelDB stores {KEY->VALUE} mappings. Non-unique index will need to have some unique values for KEY. This can be arranged by using this mapping:

 
```
KEY = {index_columns, primary_key_columns}.   
VALUE = {nothing}

```

Using primary key as suffix will make DB::Get() useless. Instead, we will have to do lookups with:

 
```
get(secondary_index_key_val)
{
  open cursor for (secondary_index_key_val)
  read the first record
  if (record > secondary_index_key_val)
    return NOT_FOUND;
  else
    return FOUND;
}

```

*TODO: we will not support unique secondary indexes in MS1. ALTER/CREATE TABLE statements attempting to add a unique index will fail. Is this ok?*

 Concurrency handling
--------------------

 We will use what was discussed in the "Pessimistic locking proposal".

 Basic idea is: LevelDB's operations do blind overwrites. In order to make sure we're not overwriting anything, we will use this pattern:

 
```
  acqure record lock;
  read;
  modify as necessary;
  write;
  release record lock;

```

record locks can be obtained for {table\_name, primary\_key}. Locks are exclusive, for a given record, only one lock can obtained at a time. A lock can be obtained when its record doesn't exist (see INSERT below)

 ### C1. UPDATE

 UPDATE will use the above scheme. It will get row locks for the keys it is reading in order to prevent concurrent updates.

 ### C.2 INSERT

 INSERT will use a row lock to make sure the record of interest does not exist.

 ### C.3 DELETE

 If a DELETE statement has a form of

 
```
DELETE FROM tbl WHERE tbl.primary_key=const

```

then it theoretically can be translated into a DB::Delete() call, that is, into a write-without-read. In other cases, we will need to do reads and put locks on the rows that we want to delete.

 MS1 will only implement the variant with locking DELETE.

 ### C.4 SELECT

 SELECT statements will use a read snapshot. They will not put (or check) whether there are any locks for records they are reading. This is similar to the definition of `read-committed` isolation level.

 We will also support `SELECT FOR UPDATE`. In this mode, the read records will be locked with a write lock until the end of the transaction.

 ### C.5 Locking mechanism

 As specified in previous sections, we will be employing locks on the values of {dbname, tablename, primary\_key\_value}. Locks will be exclusive: only one transaction can hold a lock at a time.

 Locks are acquired one-by-one, which allows for deadlocks. There will be no deadlock detection or deadlock prevention systems. Instead, lock waits will time out after @@leveldb\_lock\_wait\_timeout milliseconds. When @@leveldb\_lock\_wait\_timeout==0, lock system will not wait at all, attempt to acquire a lock that's occupied will result in an immediate transaction abort.

 Locks will be stored in a highly-concurrent hashtable. Current candidate for it is mysys/lf\_hash.

 ### C.6 Applying transaction changes

 The changes made by transaction will be accumulated as a LevelDB batch operation, and applied at transaction commit. This has a consequence: 

 **the transaction is unable to see its own changes until it commits** 

 We'll call the above CANT-SEE-OWN-CHANGES property. The property is contrary to the SQL's semantics. In SQL, one expects to see the changes they've made in preceding statements. However, the set of transactions we're targeting can live with CANT-SEE-OWN-CHANGES, so we'll live with the property for MS1.

 After MS1, LevelDB SE will make sure that CANT-SEE-OWN changes is not observed. It will use the following approach:

 * keep track of what records have been modified by this transaction in a buffer $R.
* If SQL layer makes a request to read a row, then
	+ Consult $R if the record was INSERTed. If yes, return what was inserted.
	+ Consult $R if the record was modified. if yes, return what was recorded to be the result of modification
	+ Consult $R if the record was deleted. If yes, return "record not found".
	+ Finally, try reading the row from the LevelDB.

 Table Access methods
--------------------

 MS1 will support:

 * Full table scan.
* index lookups and range scans over primary and secondary indexes.

 ### Optimizer statistics

 * Estimate of #records in the table will be obtained from DB::GetApproximateSizes() (see below for details)
* Estimate of #records-in-range will be obtained from DB::GetApproximateSizes()
* There is no acceptable estimate for #rec\_per\_key of secondary indexes (or for prefixes of the primary key). MS1 will perform some trivial guesswork.

 Note: DB::GetApproximateSizes() returns amount of disk space occupied by the data. The number cannot be directly translated to #rows, because

 * We do not always know average record length
* Disk data is compressed.

 Because of this, optimizer will have very imprecise input. It is expected to be still sufficient for MS1.

 Write-optimized INSERTs
-----------------------

 We will need to do fast bulk data loads. During the bulk load, writes-without-reads are ok: the user knows he's not overwriting data, he doesn't care about @@rows\_affected.

 These will be achieved as follows: 

 * there will be a thread-local @@leveldb\_bulk\_load variable.
* Its default value is FALSE.
* When it is set to true, INSERTS (which make ha\_leveldb::write() calls) will work in bulk-loading mode.

 Bulk-loading mode means:

 * INSERTs will be done in batches of @@leveldb\_bulk\_load\_size each
* INSERTs will take no locks, and do no-read-writes. In other words, they will silently overwrite data
* @@affected\_rows will return the value that will show that all records were successfully inserted.

 What will not be supported
--------------------------

 * Non-blocking schema changes will not be supported at all in the first milestone. All DDL-modifying operations will use pump all the data from the original table to the table with the new DDL.
* Binlog XA on the master will not be supported.
* Crash-proof slave will not be supported.
* Building server packages (\*.rpm, \*.deb, etc) will not be supported (leveldb dependency may be challenging).

 Other details
-------------

 * The patch will be against mysql-5.6
* *TODO: How to run DROP TABLE*  The only way we implement DROP TABLE is to delete record by record. The size of changes may become too big to be in RAM. If we split into multiple transactions, we'll have to handle crashes in the middle of DROP TABLE. *Q: can we avoid that for the first milestone?*
* *TODO: There is no efficient way to run TRUNCATE TABLE. Is this ok?*
* *TODO: In the above spec, nothing is said about max. transaction size. Is it ok not to have it for MS1?*

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/leveldb-storage-engine-ms1/>

HBase Storage Engine
====================

    Data mapping from HBase to SQL

 The Jira task for this is [MDEV-122](https://jira.mariadb.org/browse/MDEV-122)

 
Nobody is working on this feature ATM. See [Cassandra Storage Engine](../cassandra-storage-engine/index) for a related development that has reached the release stage.

 

This page describes a feature that's under development. The feature has not been released (even in beta), its interface and function may change, etc.

  Hbase data model and operations
-------------------------------

 ### 1.1 HBase data model

 * An HBase table consists of rows, which are identified by row key.
* Each row has an arbitrary (potentially, very large) number of columns.
* Columns are split into column groups, column groups define how the columns are stored (not reading some column groups is an optimization).
* Each (row, column) combination can have multiple versions of the data, identified by timestamp.

 ### 1.2 Hbase read operations

 HBase API defines two ways to read data:

 * Point lookup: get record for a given row\_key.

 * Point scan: read all records in [startRow, stopRow) range.

 Both kinds of scans allow to specify:

 * A column family we're interested in
* A particular column we're interested in

 The default behavior for versioned columns is to return only the most recent version. HBase API also allows to ask for 

 * versions of columns that were valid at some specific timestamp value;
* all versions that were valid within a specifed [minStamp, maxStamp) interval.
* N most recent versions We'll refer to the above as [VersionedDataConds].

 One can see two ways to map HBase tables to SQL tables:

 * Per-cell mapping
* Per-row mapping

 2. Per-cell mapping
-------------------

 HBase shell has 'scan' command, here's an example of its output:

 
```
hbase(main):007:0> scan 'testtable'
 ROW COLUMN+CELL
  myrow-1 column=colfam1:q1, timestamp=1297345476469, value=value-1
  myrow-2 column=colfam1:q2, timestamp=1297345495663, value=value-2
  myrow-2 column=colfam1:q3, timestamp=1297345508999, value=value-3

```

Here, one HBase row produces multiple rows in the query output. Each output row represents one (row\_id, column) combination, so rows with multiple columns (and multiple revisions of column data) can be easily represented.

 ### 2.1 Table definition

 Mapping could be defined as follows:

 
```
CREATE TABLE hbase_tbl_cells (
  row_id binary(MAX_HBASE_ROWID_LEN),
  column_family binary(MAX_HBASE_COLFAM_LEN),
  column_name binary(MAX_HBASE_NAME_LEN),
  timestamp TIMESTAMP,
  value BLOB,
  PRIMARY KEY (row_id, column_family, column_name, timestamp)
) ENGINE=hbase_cell;

```

There is no need for dynamic columns in this mapping.

 * NOTE: It is nice to have SQL table DDLs independent of the content of the backend hbase table. This saves us from the need to synchronize table DDLs between hbase and mysql (NDB cluster had to do this and they have ended up implementing a very complex system to do this).

 ### 2.2 Queries in per-cell mapping

 
```
# Point-select:
SELECT value 
FROM hbase_cell
WHERE 
  row_id='hbase_row_id' AND 
  column_family='hbase_column_family' AND column_name='hbase_column'
  ...

```


```
#  Range select:
#   (the example uses BETWEEN but we will support arbitrary predicates)
SELECT value 
FROM hbase_cell
WHERE 
  row_id BETWEEN 'hbase_row_id1' AND 'hbase_row_id2' AND 
  column_family='hbase_column_family' AND column_name='hbase_column'

```


```
# Update a value for {row, column}
UPDATE hbase_cell SET value='value' 
WHERE row_id='hbase_row' AND 
      column_family='col_family' AND column_name='col_name'

```


```
# Add a column into row
INSERT INTO hbase_cell values ('hbase_row', 'col_family','col_name','value');

```

Note that

 * accessing versioned data is easy: one can read some particular version, versions within a date range, etc
* it is also easy to select all columns from a certain column family.

 ### 2.3 Mapping of SQL statements

 #### Mapping for SELECT

 The table is defined as having a 

 
```
  PRIMARY KEY (row_id, column_family, column_name, timestamp)

```

which allows to make use of range optimizer to get ranges on

 * rowid
* rowid, column\_family
* rowid, column\_family, column\_name
* ...

 If a range specifies one row, we can read it with HTable.get(), otherwise we'll have to use HTable.getScanner() and make use of the obtained scanner.

 ##### Multiple non-equality conditions

 HBase API allows to scan a range of rows, retrieving only certain column name or certain column families. In our SQL mapping, this can be written as:

 
```
SELECT value
FROM hbase_cell
WHERE
  row_id BETWEEN 'hbase_row_id1' AND 'hbase_row_id2' AND
  column_family='hbase_column_family'                           (*)

```

If we feed this into the range optimizer, it will produce a range:

 
```
  ('hbase_row_id1', 'hbase_column_family') <= (row_id, column_family) <=
  ('hbase_row_id2', 'hbase_column_family')

```

which includes all column families for records which satisfy

 
```
  'hbase_row_id1' < rowid < 'hbase_row_id2'

```

This will cause extra data to be read.

 Possible solutions:

 * Extend multi-range-read interface to walk the 'SEL\_ARG graph' instead of list of ranges. This will allow to capture the exact form of conditions like (\*).
* Implement table condition pushdown and and perform independent condition analysis.
* Define more indexes, so that ranges are "dense".  what about (row\_id BETWEEN $X AND $Y) AND (timestamp BETWEEN $T1 AND $T2) ? No matter which index you define, the range list will not be identical to the WHERE clause.

 #### Mapping for INSERT

 INSERT will be translated into HTable.checkAndPut(..., value=NULL) call. That way, attempt to insert a {rowid, column} that already exists will fail.

 #### Mapping for DELETE

 MySQL/MariaDB's storage engine API handles DELETEs like this:

 * Use some way to read the record that should be deleted
* call handler->ha\_delete\_row(). It will delete the row that was last read.

 ha\_hbase\_cell can remember {rowid, column\_name} of the record, and then use HBase.checkAndDelete() call, so that we're sure we're deleting what we've read.

 If we get a statement in form of

 
```
DELETE FROM hbase_cell 
WHERE rowid='hbase_row_id' AND column_family='...' AND column_name='...';

```

then reading the record is redundant (we could just make one HBase.checkAndDelete() call). This will require some form of query pushdown, though.

 #### Mapping for UPDATE

 UPDATEs are similar to deletes as long as row\_id, column\_family, and column\_name fields are not changed (that is, only column\_value changes). Like with DELETEs:

 * HBase.checkAndPut() call can be used to make sure we're updating what we've read
* one-point UPDATEs may need a shortcut so that we don't have to read the value before we make an update.

 If UPDATE statement changes row\_id, column\_family, or column\_name field, it becomes totally different. HBase doesn't allow to change rowid of a record. We can only remove the record with old rowid, and insert a record with the new rowid. HBase doesn't support multi-row transactions, so we'll want to insert the new variant of the record before we have deleted the old one (I assume that data duplication is better than data loss).

 For first milestone, we could disallow UPDATEs that change row\_id, column\_family or column\_name.

 3. Per-row mapping
------------------

 Let each row in HBase table be mapped into a row from SQL point of view:

 
```
SELECT * FROM hbase_table;

row-id column1 column2  column3  column4  ...
------ ------- -------  -------  -------  
row1    data1   data2
row2                     data3    
row3    data4                      data5

```

The problem is that the set of columns in a HBase table is not fixed and is potentially is very large. The solution is to put all columns into one blob column and use Dynamic Columns (<http://kb.askmonty.org/en/dynamic-columns>) functions to pack/extract values of individual columns:

 
```
row-id dyn_columns
------ ------------------------------
row1   {column1=data1,column2=data2}
row2   {column3=data3}
row3   {column1=data4,column4=data5}

```

### 3.2 Mapping definition

 Table DDL could look like this:

 
```
CREATE TABLE hbase_tbl_rows (
  row_id BINARY(MAX_HBASE_ROWID_LEN),
  columns BLOB,  -- All columns/values packed in dynamic column format
  PRIMARY KEY (row_id)
) ENGINE=hbase_row;

```

(TODO: Does Hbase have MAX\_HBASE\_ROWID\_LEN limit? What is it? We can ignore this. Let the user define 'row\_id' column with whatever limit he desires; don't do operations with rows that have row\_id longer than the limit)

 Functions for reading data:

 
```
  COLUMN_GET(dynamic_column, column_nr as type)
  COLUMN_EXISTS(dynamic_column, column_nr);
  COLUMN_LIST(dynamic_column);

```

Functions for data modification:

 
```
  COLUMN_ADD(dynamic_column, column_nr,  value [as type], ...)
  COLUMN_DELETE(dynamic_column, column_nr, column_nr, ...);

```

### 3.2.1 Required improvements in Dynamic Columns

 Dynamic column functions cannot be used as-is:

 * **HBase columns have string names, Dynamic Columns have numbers** (see column\_nr parameter for the above functions). The set of column names in HBase is potentially very large, there is no way to get a list of all names: we won't be able to solve this with enum-style mapping, we'll need real support for string names.

 * **HBase has column families, Dynamic Columns do not** . Column family is not just a ':' in the column name. For example, HBase API allows to request "all columns from within a certain column family".

 * **HBase supports versioned data, Dynamic Columns do not**. A possible limited solution is to have global/session @@hbase\_timestamp variable which will globally specify the required data version.

 * (See also note below about efficient execution)

 Names for dynamic columns are covered in [MDEV-377](https://jira.mariadb.org/browse/MDEV-377)

 ### 3.3 Queries in per-row mapping

 
```
# Point-select, get value of one column
SELECT COLUMN_GET(hbase_tbl.columns, 'column_name' AS INTEGER)
FROM hbase_tbl
WHERE 
  row_id='hbase_row_id';

```


```
#  Range select:
#   (the example uses BETWEEN but we will support arbitrary predicates)
SELECT COLUMN_GET(hbase_tbl.columns, 'column_name' AS INTEGER)
FROM hbase_tbl
WHERE 
  row_id BETWEEN 'hbase_row_id1' AND 'hbase_row_id2';

```


```
# Update or add a column for a row
UPDATE hbase_tbl SET columns=COLUMN_ADD(columns, 'column_name', 'value') WHERE row_id='hbase_row_id1';

```

Use of COLUMN\_ADD like above will make no check whether column\_name=X already existed for that row. If it did, it will be silently overwritten.

 ATTENTION: There seems to be no easy way to do something that would be like SQL's INSERT statement, i.e. which would fail if the data you're changing already exists.

 One can write a convoluted IF(..., ....) expression will do the store-if-not-exist operation, but it's bad when basic operations require convoluted expressions.

 ATTENTION: One could also question whether a statement with semantics of "store this data irrespectively of what was there before" has any value for "remote" storage engine, where you're not the only one who's modifying the data.

 
```
# Set all columns at once, overwriting the content that was there
UPDATE hbase_tbl SET columns=... WHERE row_id='hbase_row_id1';

UPDATE hbase_tbl SET columns=COLUMN_CREATE('column1', 'foo') WHERE row_id='row1';

```

Note that the lsat statement will cause all columns except for 'column1' to be deleted for row 'row1'. This seems logical for SQL but there is no such operation in HBase.

 
```
# Insert a new row with column(s)
INSERT INTO hbase_tbl (row_id, columns) VALUES
  ('hbase_row_id', COLUMN_CREATE('column_name', 'column-value'));

```

Q: It's not clear how to access versioned data? Can we go without versioned data for the first milestone? (and then, use @@hbase\_timestamp for the second milestone?)

 Q: It's not clear how to select "all columns from column family X".

 ### 3.4 Efficient execution for per-row mapping

 #### 3.4.1 Predicate analysis

 The table declares:

 
```
  row_id BINARY(MAX_HBASE_ROWID_LEN),
  ...
  PRIMARY KEY (row_id)

```

which allows to use range/ref optimizer to extract ranges over the row\_id column. 

 One can also imagine a realistic query which uses conditions on hbase column names:

 
```
SELECT column_get(columns, 'some_data') FROM hbase_tbl 
WHERE 
  row_id BETWEEN 'first_interesting_row' and 'last_interesting_row' AND 
  column_get(columns, 'attribute' as string)='eligible';

```

Range optimizer is unable to catch conditions in form of

 
```
column_get(columns, 'attribute' as string)='eligible'

```

We'll need to either extend it, or create another condition analyzer.

 #### 3.4.2 Dynamic columns optimizations

 Currently, MariaDB works with Dynamic Columns with this scenario:

 1. When the record is read, the entire blob (=all columns) is read into memory
2. The query operates on the blob with Dynamic Columns Functions (reads and updates values for some columns, etc)
3. [If this is an UPDATE] the entire blob is written back to the table

 If we use this approach with HBase, we will cause a lot of overhead with reading/writing of unneeded data.

 #### Solution #1: on-demand reads

 * When table record is read, don't read any columns, return a blob handle.
* Dynamic Column functions will use the handle to read particular columns. The column is read from HBase only when its value is requested.

 This scheme ensures there are no redundant data reads, at the cost making extra mysqld<->HBase roundtrips (which are likely to be expensive)

 #### Solution #2: List of reads

 * Walk through the query and find all references to hbase\_table.columns.
* Collect the names of columns that are read, and retrieve only these columns.

 This may cause redundant data reads, for example for

 
```
  SELECT COLUMN_GET(hbase_tbl, 'column1' AS INTEGER) 
  FROM hbase_tbl
  WHERE 
    row_id BETWEEN 'hbase_row_id1' AND 'hbase_row_id2' AND 
    COLUMN_GET(hbase_tbl, 'column2' AS INTEGER)=1

```

column1 will be read for rows which have column2!=1. This still seems to be better than making extra roundtrips.

 There is a question of what should be done when the query has references like

 
```
  COLUMN_GET(hbase_tbl, {non-const-item} AS ...) 

```

where it is not possible to tell in advance which columns must be read. Possible approaches are

 * retrieve all columns
* fetch columns on demand
* stop the query with an error.

 ### 3.5 Mapping of SQL statements

 #### SELECT

 See above sections: we'll be able to analyze condition on row\_id, and a list of columns we need to read. That will give sufficient info to do either an HTable.get() call, or call HTable.getScanner() and use the scanner.

 #### INSERT

 INSERT should make sure it actually creates the row, it should not overwrite existing rows. This is not trivial in HBase. The closest we can get is to make a number of HTable.checkAndPut() calls, with the checks that we're not overwriting the data.

 This will cause INSERT ('row\_id', COLUMN\_CREATE('column1', 'data')) to succeed even if the table already had a row with ('row\_id', COLUMN\_CREATE('column2', 'data')).

 Another possible problem is that INSERT can fail mid-way (we will insert only some columns of the record).

 #### DELETE

 DELETE seems to be ok: we can delete all {rowid, column\_name} combinations for the given row\_id. I'm not sure, perhaps this will require multiple HBase calls.

 #### UPDATE

 Just like with per-cell mapping, UPDATEs that change the row\_id are actually deletions followed by inserts. We can disallow them in the first milestone.

 The most frequent form of UPDATE is expected to be one that changes the value of a column:

 
```
UPDATE hbase_tbl SET columns=COLUMN_ADD(columns, 'column_name', 'value') 
WHERE 
  row_id='hbase_row_id1' AND COLUMN_GET(columns, 'column_name')='foo';

```

For that one, we need modified Dynamic Column Functions that will represent \*changes\* in the set of columns (and not \*state\*), so that we can avoid reading columns and writing them back.

 4. Select-columns mapping
-------------------------

 This is a simplification of the per-row mapping. Suppose, the user is only interested in particular columns with names `column1` and `column2`. They create a table with this definition:

 
```
CREATE TABLE hbase_tbl_cells (
  row_id binary(MAX_HBASE_ROWID_LEN),
  column1  TYPE,
  column2  TYPE,
  PRIMARY KEY (row_id),
  KEY(column1),
  KEY(column2)
) ENGINE=hbase_columns;

```

and then access it. Access is done like in per-row mapping, but without use of dynamic columns. 

 This mapping imposes lots of restrictions: it is only possible to select a fixed set of columns, there is no way to specify version of the data, etc.

 5. Comparison of the mappings
-----------------------------

 If we select two columns from a certain row, per-cell mapping produces "vertical" result, while per-row mapping produces "horizontal" result.

 
```
# Per-cell:
SELECT column_name, value 
FROM hbase_cell
WHERE 
  row_id='hbase_row_id1' AND 
  column_family='col_fam' AND column_name IN ('column1','column2')
+-------------+-------+
| column_name | value |
+-------------+-------+
| column1     | val1  |
| column2     | val2  |
+-------------+-------+

```


```
# Per row:
SELECT 
  COLUMN_GET(columns, 'col_fam:column1') as column1,  
  COLUMN_GET(columns, 'col_fam:column2') as column2,
FROM hbase_row
WHERE 
  row_id='hbase_row_id1' 
+---------+---------+
| column1 | column2 |
+---------+---------+
| val1    | val2    |
+---------+---------+

```

Per-cell mapping:

 * Allows a finer control over selection of versioned data (easy to specify [range of] versions to select), column families, etc.
* Is more suitable for cases when one needs to select an arbitrarily-long list of columns.

 Per-row (or select-columns) mapping is easier when:

 * one is accessing a limited set of columns
* one needs to access multiple columns from multiple rows (in per-cell mapping this will require an [inefficient?] self-join).

 6. Interfacing with HBase
-------------------------

 HBase is in Java, and its native client API is a java library. We need to interface with it from C++ storage engine code. Possible options are:

 ### 6.1 Use Thrift

 This requires HBase installation to run a Thrift server

 ### 6.2 Re-implement HBase's network protocol

 * It seems to be a custom-made RPC protocol.
* There is an independent re-implementation here: <https://github.com/stumbleupon/asynchbase>. It is 10K lines of Java code, which gives an idea about HBase's protocol complexity
	+ It seems to support only a subset of features? I.e. I was unable to find mention of pushed down conditions support?
	+ Look in `HBaseRpc.java` for `"Unofficial Hadoop / HBase RPC protocol documentation"`

 ### 6.3 Use JNI+HBase client protocol

 * not sure how complex this is
* Mark has mentioned this has an unacceptable overhead?

 7. Consistency, transactions, etc
---------------------------------

 * HBase has single-record transactions. Does this mean that HBase storage engine will have MyISAM-like characteristics? e.g. if we fail in the middle of a multi-row UPDATE, there is no way to go back.

 * Q: Are the writes important at all? (e.g. if we've had the first version with provide read-only access, would that be useful?) A: Yes?

 8. Batching
-----------

 Q: will we need joins, i.e. do I need to implement Multi-Range-Read and support Batched Key Access right away?

 9. Results of discussion with Monty
-----------------------------------

 * Per-row mapping seems to be much more useful than per-cell mapping, because a lot of users have queries that retrieve lots of columns for lots of rows (is this so?)
* Dynamic column format will support string column names (see [MDEV-377](https://jira.mariadb.org/browse/MDEV-377))
* For the first milestone, forget about dynamic column concerns mentioned in "Efficient execution for per-row mapping". It is sufficient that all columns are returned as one blob that physically contains all columns.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/hbase-storage-engine/>

LevelDB Storage Engine Development
==================================

    Items that are considered for development of [LevelDB Storage Engine](../leveldb-storage-engine/index) after [Milestone #1](../leveldb-storage-engine-ms1/index) is complete.

 [DONE] AUTO\_INCREMENT
----------------------

 See [MDEV-4110](https://jira.mariadb.org/browse/MDEV-4110).

 [DONE] Use table/index numbers as prefixes
------------------------------------------

 (The Jira entry for this task is [MDEV-4122](https://jira.mariadb.org/browse/MDEV-4122))

 Currently, keys are prefixed with 

 
```
dbname.table_name$INDEX_NO\0

```

where INDEX\_NO is one byte with the number of index, counting from 1.

 With this:

 * Renaming a table is very slow. This is a problem, because ALTER TABLE assumes table rename is a fast, O(1) operation.
* DROP TABLE needs to delete every row, it is not possible to do the deletions later in the background. If one wants to run  `DROP TABLE t; CREATE TABLE t; ...` then CREATE TABLE will have to wait until DROP has truly finished.
* Dropping a table and creating another table with a different DDL causes deleted records of the first table to be compared with DDL of the second. This particular issue (but not others) can be avoided if we switch to keys that are compared with memcmp().

 ### Proposed solution

 LevelDB keys should look like this (for both table records and secondary indexes):

 
```
[indexnr] key_data

```

where `indexnr` is an index number, which is assigned sequentially, and is not a function of dbname.tablename.

 The "data dictionary" will need to have two mappings:

 
```
index2ddl
  index_no -> index_ddl_data

table2indexes
  dbname.tablename -> (index_no, index_no, ...)

```

index2ddl will be used to make comparisons when LevelDB requests them.

 table2indexes will tell us what to read when SQL layer requests to read (or write) records for dbname.tablename.

 DROP TABLE will remove table's entry from table2indexes. Actual record deletion can be done in the background. index2ddl entries can remain forever, so we will not face potential crashes when LevelDB tries to compare long-deleted records.

 RENAME TABLE will modify the entry in table2indexes. This is an O(1) operation.

 TRUNCATE TABLE will remove the entry in table2indexes and add another one, with different values of index\_no. Actual row deletion can be done in the background.

 memcmp'able keys
----------------

 Current way to compare keys (find the table DDL in the hash, then use ha\_key\_cmp()) is likely to be slow. 

 The advantages of current scheme are

 * It is possible to restore field values from index tuple, which means index-only scans are always possible.
* Keys are "packed" - for example, endspace is removed from CHAR(n) fields.

 *not that these matter much. In the benchmark of interest, most of indexed values are integers. There is a VARCHAR column with charset=latin1*.

 If we switched to keys that were comparable with memcmp(), one could expect comparisons to become faster.

 ### Making keys comparable

 #### Falcon SE

 Falcon did use memcmp() to compare index tuples. Looking into the source (it is available for download still), one can see the comparison being somewhere around:

 
```
void Index::makeKey(Field *field, Value *value, int segment, IndexKey *indexKey, bool highKey)
void Index::makeMultiSegmentKey(int count, Value **values, IndexKey *indexKey, bool highKey)
...
void IndexKey::appendNumber(double number)
^^ makes double numbers memcmp'able...

```

unfortunately, there is no single, isolated part of code that we could copy. (Or may be there is, but we were not able to find it yet).

 #### Field::make\_sort\_key

 Found this in the source:

 
```
  /**
    Writes a copy of the current value in the record buffer, suitable for
    sorting using byte-by-byte comparison. Integers are always in big-endian
    regardless of hardware architecture. At most length bytes are written
    into the buffer.

    @param buff The buffer, assumed to be at least length bytes.

    @param length Number of bytes to write.
  */
  virtual void make_sort_key(uchar *buff, uint length) = 0;

```

Looks like this is exactly what we needed?

 Fewer mutexes
-------------

 Current code initializes/uses a mutex for every row lock taken. According to Monty, having lots of mutexes that are spread out all over the memory will slow things down, and we should switch to fewer mutexes (this is a basic description).

 Maybe, it makes sense to use mutex/condition from waiter's struct st\_my\_thread\_var.

 Not included in MS2
-------------------

 ### Improve AUTO\_INCREMENT handling

 If there is no replication, then nothing is missing? The effect of

 
```
ALTER TABLE tbl AUTO_INCREMENT=nnn

```

does not survive the server restart for leveldb tables. But neither it does for InnoDB (at least, when replication is not in use).

 To our best knowledge, AUTO\_INCREMENT handling is adequate for non-replication use cases.

 ### Partial indexes

 Currently, leveldb doesn't support indexes that cover a part of the column, e.g.

 
```
CREATE TABLE t1 (
 pk int primary key,
 col1 varchar(100),
 INDEX i1 (col1(10))
);

```

Adding them is just a question of careful coding/testing.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/leveldb-storage-engine-development/>

LevelDB Storage Engine
======================

    Basic feature list
------------------

 * single-statement transactions
* secondary indexes
* HANDLER implementation with extensions to support atomic multi-put (kind of like multi-statement transactions)
* binlog XA on the master to be crash safe
* crash-proof slave replication state
* (almost) non blocking schema change
* full test coverage via mysql-test-run
* hot backup
* possible options are to have LevelDB instance per mysqld, per schema or per table

 Implementation overview
-----------------------

 ### One leveldb instance

 We consider using one LevelDB instance for mysqld process. LevelDB keys will be prefixed with 'dbname.table\_name', 'dbname.table\_name.index\_name' (or their shorter equivalents). This will allow to store arbitrary number of tables/indexes in one LevelDB instance.

 ### Transaction support

 LevelDB supports

 * read snapshots
* batch updates

 when you have just those, there is no easy way to support full transactional semantics in the way it is required from MySQL table engine.

 If we limit ourselves to single-statement transactions which touch limited numbers of rows, they could be implemented as follows:

 * updates done by the statement are accumulated in a batch
* if the statement is committed, the batch is applied. LevelDB guarantees this will be an atomic operation
* if the statement is rolled back, the batch is simply discarded.

 (Note: the "Test implementation" uses exactly this approach. It presents itself to MySQL as a non-transactional engine which is able to roll back a statement)

 (Note: According to Serg: Storage Engine API does not specify whether the changes made to table data should be immediately visible, or remain invisible until the end of the statement. Both kinds of behavior are allowed).

 *TODO: what if two transactions attempt to make conflicting changes? Will one of them get a conflict? A: NO, because LevelDB's operations cannot get in conflict. Delete() means "delete if exists" and Put() means "write, or overwrite". Therefore, no conflicts possible. TODO: is this ok? (more on this below)*

 ### Data formats

 LevelDB compresses data with something called SnappyCompressor. 

 We will rely on it to make the storage compact. Data that goes into LevelDB's key will be stored in KeyTupleFormat (which allows mysql's lookup/index ordering functions to work). Data that goes into LevelDB's value will be stored in table->record[0] format, except blobs. (Blobs will require special storage convention because they store a char\* pointer in table->record[0]). 

 (TODO: is it okay not to support blobs in the first milestone?)

 (note: datatypes in the provided benchmark are: composite primary/secondary keys, INTs and VARCHARs (are they latin1 or utf-8?)).

 ### Secondary Indexes

 #### Unique secondary indexes

 Unique secondary index is stored in a {KEY->VALUE} mapping in LevelDB, where index columns are used as KEY, and Primary Key columns are used as VALUE. This way,

 * "index-only" scans are possible
* non-"index-only" scan is a two step process (access the index, access the primary index).

 We need to support unique indexes, but not in the first milestone. 

 Note: unique indexes may prevent read-before-write optimization. There is a @@unique\_checks variable (used at least by InnoDB) which can be used to offer no-guarantees fast execution.

 #### Non-unique secondary indexes

 LevelDB stores {KEY->VALUE} mappings. Non-unique index will need to have some unique values for KEY. This is possible if we do 

 
```
KEY = {index_columns, primary_key_columns}.   
VALUE = {nothing}

```

(todo: check if leveldb allows zero-sized values).

 Using primary key as suffix will make DB::Get() useless. Instead, we will have to do lookups with:

 
```
get(secondary_index_key_val)
{
  open cursor for (secondary_index_key_val)
  read the first record
  if (record > secondary_index_key_val)
    return NOT_FOUND;
  else
    return FOUND;
}

```

### Non-blocking schema changes

 * There is a requirement that doing schema changes does not block other queries from running.

 * Reclaiming space immediately after some parts of data were dropped is not important.

 Possible approaches we could use:

 * Record format that support multiple versions. That way, adding/modifying/ dropping a non-indexed column may be instant. Note that this is applicable for records, not keys.

 * Background creation/dropping of indexes.

 ### Hot backup

 Hot backup will be made outside of this project. The idea is to hard-link the files so that they can't be deleted by compaction process, and then copy them over.

 SQL Command mapping for LevelDB
-------------------------------

 ### INSERT

 There will be two kinds of INSERTs

 1. No-reads INSERT-or-UPDATE, with semantics like in LevelDB's DB::Put() operation.
2. a "real" INSERT with SQL semantics

 #### INSERT-or-UPDATE (low priority)

 SergeiG has pointed out that SQL layer already has support for write-optimized INSERTs (it was implemented for NDB Cluster). 

 When the table has no triggers, REPLACE command will call handler->extra(HA\_EXTRA\_WRITE\_CAN\_REPLACE), after which handler->write\_row() calls are allowed to silently overwrite rows. 

 The number of affected rows returned by the statement is actually upper bound.

 (note: TokuDB documentation mentions they have something similar with INSERTs. They allow no-reads REPLACE and INSERT IGNORE, when the table has no triggers, there is no RBR binary logging, etc - the same conditions as we will have)

 ##### Batching

 It is possible to batch multi-line REPLACE commands. (TODO: Can no-read REPLACEs fail at all? If not, we can limit batch size and use multiple batches if necessary. If yes, we'll have to document that big REPLACEs may fail in the middle of a statement/ Q: is this OK?)

 #### Regular INSERT

 Regular INSERT will do a read before write and will use "gap locking" to make sure its DB::Put() call doesn't overwrite somebody's data.

 ### UPDATE

 UPDATE will do a read before write and will use record locking to make sure it's not overwriting somebody else's changes (or not updating a row that has just been deleted).

 *Note: mysql-5.6 has [WL#5906](http://askmonty.org/worklog/?tid=5906) (see link at the bottom)read before write removal (RBWR). It is not exactly what we need, but is similar (and ugly)*

 ### DELETE

 Currently, a DELETE statement has to do a read. Records are deleted through handler->delete\_row() call of the Storage Engine API, which has the meaning "delete the row that was just read". 

 There will be two kinds of DELETE statement:

 * Write-optimized DELETE IF\_EXISTS
* Regular DELETE

 #### DELETE IF\_EXISTS (low priority)

 This is a write-optimized version. It will have semantics close to LevelDB's DB::Delete() call. We will have to modify the SQL layer to support it.

 The syntax will be

 <<code lang='sql'> DELETE NO\_READ FROM tbl WHERE ... <</code>>

 the option NO\_READ will be supported only for single-table DELETEs, and will require that - the WHERE clause refers to primary key columns only - the WHERE clause allows to construct a list of primary keys to be deleted. - there ORDER BY clause

 if the above conditions are not met, the statement will fail with an error. if they are met, the statement translate into handler->delete\_row() calls, without any read calls.

 mysql\_affected\_rows() will return an upper bound of how many rows could be deleted.

 #### Regular DELETE

 Regular DELETE will have to use locking.

 ### SELECT

 #### Will use snapshot

 SELECTs will allocate/use a snapshot for reading data. This way, sql layer will not get non-repeatable reads within a statement.

 Q: is this needed? Using snapshots has some cost?

 #### Range scans

 * LevelDB cursors can be used for range scans.
* DB::GetApproximateSizes() can be used to implement handler::records\_in\_range()
* There is nothing for rec\_per\_key (index statistics)

 ### ALTER TABLE

 MySQL 5.6 should support online ALTER TABLE operations (as InnoDB now supports them).

 TODO: what does the storage engine needs to do to inform the SQL layer that it is running a long DDL change which does not prevent other selects/updates from running?

 Binlog XA on Master
-------------------

 This is about keeping binlog and LevelDB in sync on the master. MySQL does it as follows: 

 * prepare transaction in the storage engine
* write it into the binlog
* commit it in the engine

 If transactions are grouped, they are committed in the same order as they were written into the binary log.

 Recovery proceeds as follows:

 * Read the last binlog file and note XIDs of transactions that are there.
* for each storage engine,
	+ scan the committed transactions and compare their XIDs to those we've found in the binlog.
	+ If transaction is the binlog - commit, otherwise - roll it back)

 (note that the order the transactions are applied in is determined from the engine, not from the binlog)

 TODO: suggestions about how PREPARE/COMMIT/recovery should work for LevelDB. (got some ideas after discussion with Kristian, need to write them down)

 Crash-proof slave
-----------------

 MySQL 5.6 stores information that used to be in relay\_log.info in InnoDB. That way, InnoDB and relay\_log.info (aka binlog position) are always in sync.

 It seems, switching to storing relay\_log.info in a LevelDB table is sufficient for crash-proof slave. (note: this implies that semantics of operations over LevelDB table is sufficiently close to that of a regular MySQL storage engine, like innodb).

 Other details
-------------

 * The target version is MySQL 5.6 (good, because LevelDB API uses STL and 5.6-based versions support compiling with STL).
* It is ok to make changes to LevelDB itself

 * There is a "Test implementation" at <https://github.com/tbdingqi/tbleveldb>.

 * Task tracking for this is done here: [MDEV-3841](https://jira.mariadb.org/browse/MDEV-3841)

 * We may want to check out this: <http://dev.mysql.com/worklog/task/?id=5906>. It is pushed into 5.6

 Milestones
----------

 * Milestone #1 is described at [leveldb-storage-engine-ms1](../leveldb-storage-engine-ms1/index)
* Subsequent development is described at [leveldb-storage-engine-development](../leveldb-storage-engine-development/index)

 * Milestone #2 is described at [leveldb-storage-engine-ms2](../leveldb-storage-engine-ms2/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/leveldb/>

LevelDB Storage Engine MS2
==========================

    Remove the need for a second database
-------------------------------------

 MS1 code needs to use two databases, because

 * `leveldb` database uses type-aware key comparison. This means, one must have knowledge about types of values in indexes before the database can be opened.

 * `leveldb-ddl` stores information about
	+ datatypes used by various indexes.
	+ Mapping from `dbname.tablename.index_no` to `index_number`.

 The database itself uses default key comparison function, so one can open it without any knowledge.

 It is possible to switch to having one database, if the keys can use the default key comparison function, memcmp(). The database will store 

 * table/index data
* Mapping from `dbname.tablename.index_no` to `index_number`.

 It seems, it is possible to convert MySQL field values into values comparable with memcmp() by using Field::make\_sort\_key() function.

 ### Index-only scans

 Index-only scans require that it is possible to restore key value from its memcmp()'able form.

 In general, it is not possible. For some particular datatypes, it is possible. We want to target the following types:

 * `INT`, `BIGINT`, `TINYINT`, and their `UNSIGNED` variants (i.e., all INT-based types)
* `CHAR(n) COLLATE latin1_bin`, `VARCHAR(n) COLLATE latin1_bin`, possibly support `utf8_bin`.

 #### INT-based types

 For INT-based types, mem-comparable form is the integer stored in most-significant-bytes-first order. For SIGNED types, one needs to make negative values precede positive ones (memcmp() assumes all bytes are unsigned). This can be achieved by adding MAX\_VALUE/2 to the number.

 It is apparent that one can restore integer values back from their mem-comparable form.

 #### String-based types

 For string-based types, getting the value back from its mem-comparable form is harder.

 ##### Problem#1: case-insensitivity

 For case-insensitive collations, conversion to mem-comparable form is, roughly speaking, conversion of all characters to upper case (it's actually more complex, but that's the idea)

 For example, for column='foo' and column='FOO' the mem-comparable form is 'FOO', and there is no way to get the original case back.

 ##### Problem#2: VARCHAR and end-spaces

 Consider a [VAR]CHAR(n) type. The mem-comparable form must have the same length for all values. If some values have different length, we won't be able to support multi-part keys.

 In MySQL charset functions, mem-comparable form does have a fixed length. Fixed length is achieved by end-padding the value with spaces (more precisely, with mem-comparable images of spaces). This raises a question of, how do we get rid of these spaces when we're decoding the value back?

 For `CHAR(n)` fields, the problem doesn't exist, because MySQL strips all trailing spaces:

 
```
create table t10 (a char(10) primary key); 
insert into t10 values ('abc   ');
select a, length(a) from t10;
+-----+-----------+
| a   | length(a) |
+-----+-----------+
| abc |         3 |
+-----+-----------+

```

(@@sql\_mode has a PAD\_CHAR\_TO\_FULL\_LENGTH flag which will make MySQL to pad strings with as many spaces as possible instead of stripping. But either way, we don't have to care about how many end-spaces are in a CHAR(n) value).

 For VARCHAR fields, end-spaces are not removed:

 
```
create table t11 (a varchar(10) primary key);
insert into t11 values ('abc   ');
select a, length(a) from t11;
+--------+-----------+
| a      | length(a) |
+--------+-----------+
| abc    |         6 |
+--------+-----------+

```

When we try to decode a string from its mem-comparable form, we will not know how many end-spaces were in the original value. We need to store the length somewhere.

 ##### Solution for case-insensitivity

 We will avoid the problem of upper-casing by supporting index-only reads when used collations do not map two different characters to the same mem-comparable value. The following collations are ok:

 * `BINARY` - characters are not transformed
* `latin1_bin` - characters are not transformed
* `utf8_bin` - characters are transformed into 2-byte images with `my_utf8_uni()` and can be restored with `my_uni_utf8()`. The functions are stored in `cs->cset->mb_wc` and `cs->cset->wc_mb`.
* `utf8mb4_bin` - characters are transformed into 3-byte images with `my_mb_wc_utf8mb4()` and can be restored with `my_wc_mb_utf8mb4()`

 ##### Solution for end-spaces

 We need to store the original length of the value somewhere. There is no way we could put it into a mem-comparable form. If we put it there, we would have

 
```
memcmp(mem_comparable('abc'), mem_comparable('abc  '), len) != 0

```

which would make equal values be compared as non equal. 

 The solution is: don't store length in leveldb key. 

 * For PRIMARY KEY, length is stored in leveldb's Value (we have entire table->record[0] there, with special encoding for blobs).
* For secondary indexes, we will store length in the leveldb's Value (which is currently empty).

 Fix CANT-SEE-OWN-CHANGES
------------------------

 The property is described at [leveldb-storage-engine-ms1](../leveldb-storage-engine-ms1/index) page. A solution is also described there:

 
 After MS1, LevelDB SE will make sure that CANT-SEE-OWN changes is not observed. It will use the following approach:

 * keep track of what records have been modified by this transaction in a buffer $R.
* If SQL layer makes a request to read a row, then
	+ Consult $R if the record was INSERTed. If yes, return what was inserted.
	+ Consult $R if the record was modified. if yes, return what was recorded as the result of modification
	+ Consult $R if the record was deleted. If yes, return "record not found".
	+ Finally, try reading the row from the LevelDB.

  Note: this allows us to keep only the last update if the transaction has made multiple updates in the same row. (as long as we didn't use to store both transaction and statement's changes together. In that case, we need to keep both transaction's and statement's changes)

 More test coverage
------------------

 Adopt a storage-engine-independent testsuite to be used together with leveldb.

 Statement rollback inside a transaction
---------------------------------------

 A truly transactional MySQL engine needs to support two kinds of rollback

 1. Rollback a statement
2. Rollback a transaction

 If a statement fails inside a transaction, the engine will need to rollback the statement, but not the transaction. Currently, leveldb SE is unable to do so, because transaction's changes and statement's changes are stored in a single `leveldb::WriteBatch` object.

 The solution will be to keep transaction's changes and statement's changes separate, and put statement's changes into transaction's changes on statement end.

 Another way: when we maintain a hashtable of changes, remember query\_id of every change. If we need to roll back a statement, go through the changes and remove those that have query\_id equal to the last query (TODO: is statement the same as query here, or not?)

 Fix the build process
---------------------

 [MDEV-4154](https://jira.mariadb.org/browse/MDEV-4154): Currently, leveldb SE hardcodes paths to leveldb library. Lift this limitation.

 @@leveldb\_max\_row\_locks
--------------------------

 Transaction locks are held in memory. Hence, there is an idea: prevent transactions from getting too big - have a variable that explicitly limits how many locks a transaction can take. (there was a similar variable in BDB storage engine). If a transaction attempts to take more locks than allowed, an error will be returned.

 Tasks
-----

 ### Remove the need for a second database

 * Store mem-comparable values as keys (no index-only support)
* Switch rowlock table to use the same hash value?

 ### Index-only scans

 * Analyze index definition and set HA\_KEYREAD\_ONLY only when appropriate
* Unpack functions for integer columns
* Unpack function for CHAR(n)
* Storage an unpack for VARCHAR(n)

 ### Fix CANT-SEE-OWN-CHANGES

 * Maintain a hash table of changes made by the transaction
* Have read functions consult the hashtable before reading actual data

 ### Statement rollback inside a transaction

 * Maintain transaction's changes and last statement's changes separately.
	+ Roll back the right set of changes on statement/transaction abort.

 ### More test coverage

 * Adopt the engine-independent testsuite to be used with leveldb

 Misc
----

 * (from skype discussion)\_Currently max. auto\_increment value is loaded every time a TABLE is opened. Make it to be loaded only when TABLE\_SHARE is opened.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/leveldb-storage-engine-ms2/>

Stuff in MySQL 5.6
==================

    
This is SergeyP's list of patches in MySQL 5.6 that he has found interesting. It is not a full list of interesting features or anything like that

 
[WL#6071](http://askmonty.org/worklog/?tid=6071): Inline tmp tables into the nested loops algorithm. (Evgen, 2012-05-31) 

 [WL#4443](http://askmonty.org/worklog/?tid=4443) - Prune partition locks (public WL) (April 2012)

 [WL#4897](http://askmonty.org/worklog/?tid=4897): Add EXPLAIN INSERT/UPDATE/DELETE (2011)

 * EXPLAIN EXTENDED UPDATE doesn't print warnings...

 [WL#5906](http://askmonty.org/worklog/?tid=5906) read before write removal (RBWR) (2012-04)

 * used by NDB only. (Bug#37153 NDB Cluster reports affected rows incorrectly, etc)
* but the SQL layer still does reads before doing writes. This code is not suitable for update-without-reads.
* The main idea is that we do [deleted|updated]= table->file->end\_read\_removal(); at the end. This only counts #of affected rows.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/stuff-in-mysql-56/>

EXPLAIN FORMAT=JSON Differences From MySQL
==========================================

    [EXPLAIN FORMAT=JSON](../explain-formatjson/index) output in MySQL and MariaDB.

 MariaDB's EXPLAIN JSON output is different from MySQL's. Here's a list of differences. (Currently they come in no particular order).

 Attached Conditions are Prettier
--------------------------------

 MySQL prints conditions with too many quotes and braces. Also, subqueries are printed in full (despite that you also get a plan for this subquery). You see something like this:   
  
  


 
```
      "attached_condition": "((`test`.`t1`.`a` < (/* select#2 */ select min(`test`.`t10`.`b`) from `test`.`t10`)) or (`test`.`t1`.`a` > (/* select#3 */ select max(`test`.`t10`.`b`) from `test`.`t10`)))",

      "attached_condition": "((`test`.`t20`.`col1` > `test`.`t20`.`col2`) or (`test`.`t20`.`col3` = 4))"

```

in MariaDB, the same conditions are printed like this:

 
```
      "attached_condition": "((t1.a < (subquery#2)) or (t1.a > (subquery#3)))"

      "attached_condition": "((t20.col1 > t20.col2) or (t20.col3 = 4))"

```

JSON Pretty-printer is Smarter
------------------------------

 MySQL's JSON pretty-printer is pretty dumb:

 
```
      "possible_keys": [
        "a"
      ],
      "key": "a",
      "used_key_parts": [
        "a"
      ],

```

MariaDB's JSON pretty-printer is a bit smarter:

 
```
      "possible_keys": ["a"],
      "key": "a",
      "key_length": "5",
      "used_key_parts": ["a"],

```

Index Merge Shows used\_key\_parts
----------------------------------

 For multi-part keys, tabular EXPLAIN shows key\_length column and leaves the user to do column-size arithmetic to figure out how many key parts are used.

 MySQL's EXPLAIN=JSON may show used\_key\_parts member which shows which key parts are used. For range access, key\_length is also provided:

 
```
      "access_type": "range",
      "possible_keys": [
        "col1"
      ],
      "key": "col1",
      "used_key_parts": [
        "col1",
        "col2"
      ],
      "key_length": "10",

```

But if you are using index\_merge, you will still have to decode key\_length:

 
```
    "table": {
      "table_name": "t22",
      "access_type": "index_merge",
      "possible_keys": [
        "col1",
        "col3"
      ],
      "key": "sort_union(col1,col3)",
      "key_length": "10,5",
      "rows": 2398,

```

In MariaDB, you get used\_key\_parts for all parts of index\_merge:

 
```
      "table_name": "t22",
      "access_type": "index_merge",
      "possible_keys": ["col1", "col3"],
      "key_length": "10,5",
      "index_merge": {
        "sort_union": {
          "range": {
            "key": "col1",
            "used_key_parts": ["col1", "col2"]
          },
          "range": {
            "key": "col3",
            "used_key_parts": ["col3"]
          }
        }

```

Range Checked for Each Record
-----------------------------

 In MySQL, you need to decode hex index number bitmaps (like in the tabular form):

 
```
        "table": {
          "table_name": "t2",
          "access_type": "ALL",
          "possible_keys": [
            "key1",
            "key3"
          ],
          "rows": 1000,
          "filtered": 100,
          "range_checked_for_each_record": "index map: 0x5"
        }

```

In MariaDB, the keys are shown explicitly

 
```
    "range-checked-for-each-record": {
      "keys": ["key1", "key3"],
      "table": {
        "table_name": "t2",
        "access_type": "ALL",
        "possible_keys": ["key1", "key3"],
        "rows": 1000,
        "filtered": 100
      }

```

also, the structure of display ("range checked ..." embeds the table access) is closer to query plan's structure. (TODO: should we move "range-checked-for-each-record" inside the "table" ? )

 Full Scan on NULL Key
---------------------

 Tabular EXPLAIN shows "Full scan on NULL key" in the Extra column. MySQL has made a direct translation to JSON:

 
```
      "table": {
        "table_name": "t1",
        "access_type": "ref_or_null",
        ...
        ...
        "rows": 2,
        "filtered": 100,
        "using_index": true,
        "full_scan_on_NULL_key": true,
        ...
      }

```

This is not appropriate for MariaDB because it would like to have place for ANALYZE to show #loops for each construct. It is also illogical - some attribute at the end says "btw all of the above is not used in some cases". Because of that, MariaDB uses:

 
```
          "full-scan-on-null_key": {
            "table": {
              "table_name": "t1",
              "access_type": "ref_or_null",
              "possible_keys": ["a"],
              "key": "a",
              ...
            }


```

Join Buffer Plan is Shown in Greater Detail.
--------------------------------------------

 MySQL displays "using join buffer" as just another kind of table access. It doesn't separate reading from join buffer and writing to join buffer.

 
```
    "nested_loop": [
      {
        "table": {
          "table_name": "A",
          "access_type": "ALL",
          "rows": 10,
          "filtered": 100,
          "attached_condition": "(`test`.`A`.`b` = 3)"
        }
      },
      {
        "table": {
          "table_name": "B",
          "access_type": "ALL",
          "rows": 20,
          "filtered": 100,
          "using_join_buffer": "Block Nested Loop",
          "attached_condition": "((`test`.`B`.`b` = 4) and ((`test`.`A`.`a` + `test`.`B`.`a`) < 3))"
        }
      }

```

MariaDB shows what is really is going on:

 
```
    "table": {
      "table_name": "A",
      "access_type": "ALL",
      "rows": 10,
      "filtered": 100,
      "attached_condition": "(A.b = 3)"
    },                                                                                                                                                          
    "block-nl-join": {                                                                                                                                          
      "table": {                                                                                                                                                
        "table_name": "B",                                                                                                                                      
        "access_type": "ALL",                                                                                                                                   
        "rows": 10,                                                                                                                                             
        "filtered": 100,                                                                                                                                        
        "attached_condition": "(B.b = 4)"
      },
      "buffer_type": "flat",
      "buffer_size": "128Kb",
      "join_type": "BNL",
      "attached_condition": "((A.a + B.a) < 3)"
    }

```

TODO: other differences
-----------------------

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/explain-format-json-differences/>

Profiling with Linux perf tool
==============================

    Linux `perf` tool can be used to do non-intrusive profiling.

 Frequency Based Sampling
------------------------

 This mechanism can be used to answer the question, what is MariaDB doing on my CPU.

 ### Recording a sample

 Perf records at a high frequency, so only a short recording is sufficient to answer the question. If this is too short adjust the frequency at which perf does its recordings.

 
```
sudo perf record -p ${pidof mysqld} -g -o sample.perf -- sleep 5

```

The `-g` option here records the calling stack. Because seeing time in a mutex function isn't particularly interesting without knowing which mutex it is.

 ### Viewing a sample

 To view a recording, you need the debug symbols for your executable. See [this page](../how-to-produce-a-full-stack-trace-for-mysqld/index#obtaining-debugging-symbols-for-your-mysqld-binary) on getting the debug symbols available.

 Changing the ownership of the recording means you can run perf report without sudo.

 This shows where in the process MariaDB is spending most of its time at the top level. MariaDB uses threads per user connection so this will usually show a significant time in a `handle\_connection` function. There are background threads that also run, so this can quickly show if its connection related time or a background thread.

 
```
sudo chown $USER: sample.perf
perf report -i sample.perf -g

```

To see which low level functions are consuming the most time, `--no-children` means that each function listed include only the time that is being spend it this function and excluding the other functions it calls.

 
```
perf report -i sample.perf -g --no-children

```

Expanding out the function shows the complete call stack again. Multiple functions may have called the function you are looking at so there may be a different frequency breakdown.

 A more complete example of performance analysis using perf is on this [Percona community blog article](https://www.percona.com/community-blog/2020/02/05/finding-mysql-scaling-problems-using-perf/).

 Dynamic Tracepoints
-------------------

 ### Adding dynamic tracepoints

 One can add tracepoints at function entry/exit (and other locations too):

 
```
sudo perf probe -x /path/to/ha_rocksdb.so  --add rocksdb_prepare
sudo perf probe -x /path/to/ha_rocksdb.so  --add rocksdb_prepare%return

```

### Viewing the tracepoints

 
```
sudo perf probe -l 

```

### Running the profiler

 Something like:

 
```
perf record -e 'probe_ha_rocksdb:*' -a -- sleep 60

```

Note: `-a` means system-wide.

 There's also `-p $PID` option

 
```
perf record -e 'probe_ha_rocksdb:*' -p $(pidof mysqld) -- sleep 60

```

### Examining the trace

 
```
perf script

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/profiling-with-linux-perf-tool/>

Uploading Package to PPA
========================

    After creating a Launchpad account:

 #### Docker build, cloning the MariaDB repository and mapping it to the docker container

 1. mkdir mariadb-source

 2. cd mariadb-source

 3. vi Dockerfile

 4. Copy the following contents to Dockerfile:

 
```
# MariaDB 10.3 Ubuntu 17.10 build environment
# Published as mariadb-10-3-ubuntu-17.10-build-env
FROM ubuntu:17.10
RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y --no-install-recommends \
systemd \
devscripts \
build-essential \
lsb-release \
equivs \
git \
curl \
git-buildpackage \
nano \
vim \
pristine-tar

RUN curl -skO https://raw.githubusercontent.com/ottok/mariadb-10.1/ubuntu-17.10/debian/control

ENV GIT_SSL_NO_VERIFY true

RUN mk-build-deps -t 'apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends' -i control

ENV container docker
ENV DEBIAN_FRONTEND noninteractive
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

```

5. Run `docker build . -t ubuntu-17.10-packaging`

 6. Do git clone of the latest repository:

 `cd && mkdir debian-packaging && cd debian-packaging && git clone https://salsa.debian.org/mariadb-team/mariadb-10.1.git`

 #### Generate, publish and upload PGP key

 7. Generate OpenPGP key with the following command:

 `$ gpg --gen-key` 

 * select (1) RSA and RSA
* Keysize: accept 2048
* Valid for: accept 0
* Type name, email and comment (comment is optional)
* Type 0
* Type passphrase (twice)
* Follow instructions to help generate a random key
* Keep the Key ID and fingerprint text, they are needed in the next step

 Set generated key as default in `~/.bashrc`

 `$ nano ~/.bashrc` 

 [.. add this ..]

 `export GPGKEY=<key_id>`

 Restart GPG-agent and source '/.bashrc', or restart session

 8. Publish the key to the key server:

 `gpg --keyserver keyserver.ubuntu.com --send-keys 12345678` and substitute `12345678` with your key's id

 * If this gives timeout error, keep re-trying after a while

 9. Upload the key's fingerprint here: Upload <https://help.launchpad.net/YourAccount/ImportingYourPGPKey> fingerprint here <https://launchpad.net/~rsurve/+editpgpkeys>

 10. `gpg --export [your-key-id] > ~/debian-packaging/pub.key`

 11. `gpg --export-secret-key [your-key-id] > ~/debian-packaging/secret.key`

 `gpg -k`

 ^Should show the key

 12. How to upload: <https://github.com/exelearning/iteexe/wiki/How-to-upload-to-Launchpad-PPA-repository-(.deb-packages)>

 13. Open `/etc/devscripts.conf`

 And look for this line:

 `DEBSIGN_MAINT`

 Uncomment it and add your name there

 `export DEBEMAIL=[your-email-id]`

 #### From inside the container

 14. `docker run -v ~/debian-packaging/:/repo -it ubuntu-17.10-packaging bash`

 15. `apt-get install devscripts`

 16. `gpg --import pub.key`

 17. `gpg --import secret.key`

 18. `gpg -k`

 19. `cd /repo/mariadb-10.1 && git fetch && git checkout pristine-tar && git checkout ubuntu-17.10`

 20. `git clean -dffx && git reset --hard HEAD`

 21. `export DEB_BUILD_OPTIONS="parallel=10 nocheck"` or `export DEB_BUILD_OPTIONS="parallel=5 nocheck"`

 22. Go to `/repo` folder (Inside docker) and delete all the files except mariadb-10.1 folder:

 `rm *`

 23. `gbp buildpackage` 

 #### For re-running the set up container

 24. To generate an ID, run: `docker commit <container-id>` This will generate an ID.

 For restarting the same container again use this ID: `docker run -v ~/debian-packaging/:/repo -it <ID> bash`

 25. Last command for uploading package to PPA:

 `backportpackage -u <your-ppa-address> -d <ubuntu-version-to-backport-to> -S ~<a-version-suffix-name-for-this-package> <the-most-recent-dsc-file>`

 Example:

 `backportpackage -u ppa:cvicentiu/mariadb-10.0-dev2 -d bionic -S ~testtry mariadb-10.1_10.1.30-0ubuntu0.17.10.1.dsc`

 Run this command in the `/repo` folder, where the `.dsc` file is located It should ask for the gpg key password again

 * Docker tutorial available here: <https://docs.google.com/presentation/d/1euJrK7MJ9QRvwW33iwESIEo5Dyi7JWExIKFrISktFao/edit#slide=id.p4>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/uploading-package-to-ppa/>

NumInteriorRings
================

    A synonym for [ST\_NumInteriorRings](../st_numinteriorrings/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon-properties-numinteriorrings/>

ExteriorRing
============

    A synonym for [ST\_ExteriorRing](../st_exteriorring/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon-properties-exteriorring/>

AREA
====

    A synonym for [ST\_AREA](../st_area/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon-properties-area/>

DROP CATALOG
============

    Syntax
------

 
```
DROP CATALOG catalog_name

```

Description
-----------

 Deletes a [catalog](../catalogs/index). Can only be performed by a super user in the 'def' catalog. If the current catalog is dropped, the user is moved to the 'def' catalog. 'def' catalog cannot be dropped.

 Currently, there cannot be any databases in a catalog to be dropped. This will be fixed soon.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-catalog/>

Catalog Status Variables
========================

    When using a MariaDB Server with [catalogs](../catalogs/index) support, all status information is collected for the whole server, per catalog and per user.

 
```
SHOW SERVER STATUS;

```

shows the status for the whole server. Note that only the super user in the 'def' catalog has privileges for the above statement.

 
```
SHOW GLOBAL STATUS;
SHOW CATALOG STATUS;

```

Both commands show the status for the current catalog. The reason that `GLOBAL` shows catalog status is that because catalogs are 'multi-tenant', a catalog user should not be able to see the status from other users (for most things).

 
```
SHOW [SESSION] STATUS;

```

Shows the status for the current connection.

 The main "new thing" is that catalogs enable SAS providers to see the status for a single tenant (catalog user). This makes it much easier to find 'bad neighbors' (tenants that cause problems for other tenants) so that they can be moved to other servers.

 When the MariaDB server is not configured for catalogs, the following commands are equivalent:

 
```
SHOW GLOBAL STATUS
SHOW SERVER STATUS 
SHOW CATALOG STATUS

```

See Also
--------

 * [SHOW STATUS](../show-status/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/catalog-status-variables/>

USE CATALOG
===========

    Syntax
------

 
```
USE CATALOG catalog_name

```

Description
-----------

 Changes to another [catalog](../catalogs/index). Can only be done by a super user in the 'def' catalog. Changing catalog will update catalog status and reset all session status.

 A tenant (a user in any other catalog than 'def') cannot change to another catalog. However tenants can execute `USE CATALOG current_catalog`. This is to allow the user to import SQL scripts that use `USE CATALOG...`.

 See Also
--------

 * [USE database](../use/index). Changing database.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/use-catalog/>

AsBinary
========

    A synonym for [ST\_AsBinary()](../st_asbinary/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-asbinary/>

InteriorRingN
=============

    A synonym for [ST\_InteriorRingN](../st_interiorringn/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/polygon-properties-interiorringn/>

Well-Known Binary (WKB) Format
==============================

    WKB stands for Well-Known Binary, a format for representing geographical and geometrical data.

 WKB uses 1-byte unsigned integers, 4-byte unsigned integers, and 8-byte double-precision numbers.

 * The first byte indicates the byte order. 00 for big endian, or 01 for little endian.
* The next 4 bytes indicate the geometry type. Values from 1 to 7 indicate whether the type is Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, or GeometryCollection respectively.
* The 8-byte floats represent the co-ordinates.

 Take the following example, a sequence of 21 bytes each represented by two hex digits:

 
```
000000000140000000000000004010000000000000

```

* It's big endian
	+ 00**0000000140000000000000004010000000000000**
* It's a POINT
	+ 00**00000001**40000000000000004010000000000000
* The X co-ordinate is 2.0
	+ 0000000001**4000000000000000**4010000000000000
* The Y-co-ordinate is 4.0
	+ 00000000014000000000000000**4010000000000000**

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/well-known-binary-wkb-format/>

GeomFromWKB
===========

    A synonym for [ST\_GeomFromWKB](../st_geomfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-geomfromwkb/>

GeomCollFromWKB
===============

    A synonym for [ST\_GeomCollFromWKB](../st_geomcollfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-geomcollfromwkb/>

PointFromWKB
============

    A synonym for [ST\_PointFromWKB](../st_pointfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-pointfromwkb/>

LineFromWKB
===========

    A synonym for [ST\_LineFromWKB](../st_linefromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-linefromwkb/>

WKT Definition
==============

    Description
-----------

 The Well-Known Text (WKT) representation of Geometry is designed to exchange geometry data in ASCII form. Examples of the basic geometry types include:

 


| Geometry Types |
| --- |
| [POINT](../point/index) |
| [LINESTRING](../linestring/index) |
| [POLYGON](../polygon/index) |
| [MULTIPOINT](../multipoint/index) |
| [MULTILINESTRING](../multilinestring/index) |
| [MULTIPOLYGON](../multipolygon/index) |
| [GEOMETRYCOLLECTION](../geometrycollection/index) |
| [GEOMETRY](../geometry/index) |

 
See Also
--------

 * [Geometry Types](../geometry-types/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-definition/>

PolyFromWKB
===========

    A synonym for [ST\_PolyFromWKB](../st_polyfromwkb/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkb-polyfromwkb/>

AsText
======

    A synonym for [ST\_AsText()](../st_astext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-astext/>

AsWKT
=====

    A synonym for [ST\_AsText()](../st_astext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-aswkt/>

GeomCollFromText
================

    A synonym for [ST\_GeomCollFromText](../st_geomcollfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-geomcollfromtext/>

GeomFromText
============

    A synonym for [ST\_GeomFromText](../st_geomfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-geomfromtext/>

LineFromText
============

    A synonym for [ST\_LineFromText](../st_linefromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-linefromtext/>

PolyFromText
============

    A synonym for [ST\_PolyFromText](../st_polyfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-polyfromtext/>

PointFromText
=============

    A synonym for [ST\_PointFromText](../st_pointfromtext/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/wkt-pointfromtext/>

BOUNDARY
========

    A synonym for [ST\_BOUNDARY](../st_boundary/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-boundary/>

SRID
====

    A synonym for [ST\_SRID](../st_srid/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-srid/>

GeometryN
=========

    A synonym for [ST\_GeometryN](../st_geometryn/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-geometryn/>

ENVELOPE
========

    A synonym for [ST\_ENVELOPE](../st_envelope/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-envelope/>

GeometryType
============

    A synonym for [ST\_GeometryType](../st_geometrytype/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-geometrytype/>

Catalogs Overview
=================

    
Catalogs are an upcoming feature that will be included in a future release of MariaDB. The MariaDB catalogs will be a multi-tenancy feature where a single instance MariaDB server handles multiple independent tenants (customers), who have their own users, schemas etc. See [MDEV-31542](https://jira.mariadb.org/browse/MDEV-31542) "Add multi-tenancy catalogs to MariaDB" for details.

 
Background
----------

 For hosting providers, a common solution, to drive down cost, is to have one MariaDB server support several different customers by creating one named schema for each of them.

 This has however a lot of limitations:

 * The user cannot have exactly the same schema(s) on the cloud as they have on premise.
* The user cannot use multiple schemas.
* The user cannot take a backup of all their data (not even with [mariadb-dump](../mariadb-dump/index)). This is because the ‘mysql’ schema, which includes users, stored procedures etc. cannot be copied as its data is shared among all server users.
* The user cannot access the [general](../general-query-log/index) or [error log](../error-log/index).

 The suggested solution to solve all of the above and thus create a better multi-tenant database is to add support for catalogs to MariaDB.

 By each user having their own catalog, they will get very close to the same user experience as if they would have the MariaDB server for themselves.

 Catalogs make it possible for hosting providers to have 10-100x more 'not that active' database users on a server compared to having a container or MariaDB server per customer (which limits a 192G server to about 100 customers with a 1G InnoDB buffer each).

 User Experience With Catalogs
-----------------------------

 * Each user is assigned one catalog. The user can specify their catalog in their my.cnf file or as an argument to clients or when connecting to MariaDB server.
* Users can [mariadb-dump](../mariadb-dump/index) of all their tables (including the ‘mysql’ database) and apply it on their own on premise MariaDB or to another ‘MariaDB catalog’ to duplicate their setup.
* Each catalog has its own privilege system. This allows a MariaDB admin to create users independently in their catalog to users in any other catalog. This also implies that the catalog has to be part of the connect information as otherwise the server does not know which user table to use.
* If the user is using applications that don’t yet support catalogs, they can specify the catalog as part of the database when connecting to the server ('catalog.database') or by connecting to a specific port that is associated with a catalog.
* After logging in, a normal user can only see the objects (databases, tables, users etc) from their database. They cannot access other catalogs or change catalogs.
* A normal user cannot change the active catalog with a command. They need to logout from the current catalog and login to another.

 For the end user, the MariaDB server will act as a normal a standalone server, with the following differences:

 * When connecting to the server, a normal user must specify the catalog. If the connector software does not support catalogs, then the catalog should be specified in the database string. If the catalog is not specified, the 'def' catalog is assumed.
* [LOAD DATA INFILE](../load-data-infile/index) and [SELECT … INTO OUTFILE](../select-into-outfile/index) can be configured to only be used with the catalog directory or a directory in it.
* [SHUTDOWN](../shutdown/index) command is only for the 'catalog root users'
* Replication (MASTER and SLAVE commands) are only for 'catalog root users'
* Errors from background task (like write error) will be logged into the system error log, not the catalog error log.
* [SHOW STATUS](../show-status/index) will show status data for the whole server, not only for the active catalog.
* The server will handle legacy applications by extending the default database in the connection to contain the catalog in the form “catalog/database”. See Appendix for details.
* Tables that are only read from the ‘def.mysql’ schema:
	+ [plugin](../mysqlplugin-table/index)
	+ [help\_\*](../mysqlhelp_category-table/index) tables
	+ [time\_zone\*](../mysqltime_zone_name-table/index) tables
	+ [gtid\_slave\_pos](../mysqlgtid_slave_pos-table/index) (replication state)
	+ [innodb\_index\_stats](../mysqlinnodb_index_stats/index) (innodb internal)
	+ [servers](../mysqlservers-table/index) (federated)
	+ [transaction\_registry](../mysql-transaction_registry-table/index) (innodb internal)
	+ [func](../mysqlfunc-table/index) (udf)
	+ [performance\_schema](../performance-schema/index)

 New 'catalog root user'
-----------------------

 * The 'def' catalog is reserved to store permissions for 'catalog root users', which can access any catalog. \* These are meant for admin users that need to do tasks like shutdown, upgrade, create/drop catalogs, managing primaries and replicas etc.
* Only the ‘catalog root user’ can change to another catalog with ‘set catalog catalog\_name’.
* A normal user can do ‘set catalog current-catalog’. This will be needed to be able to execute a [mariadb-dump](../mariadb-dump/index) that includes this command.

 New Storage Layout
------------------

 MariaDB server will be able to run either on 'original mode', where the data layout is exactly as it was before, or on 'catalog' mode, with a new data layout:

 When running [mariadb-install-db](../mariadb-install-db/index) with --use-catalogs, it will create the following new data structure:

 * data\_directory/
	+ engine system data files
	+ system files
	+ replication files
	+ general.log
	+ error.log
	+ mariadb/
		- mysql/
		- privilege tables
	+ catalog1
	+ general.log
	+ error.log
	+ mysql/
		- privilege tables
	+ database1/
		- tables for database1
	+ database2/
		- tables for database2
	+ catalog2/
		- general.log
		- error.log
	+ mysql/
		- privilege tables
	+ database1/
		- tables for database1
	+ database2/
		- tables for database2

 The disk structure when not using catalogs is:

 * data\_directory/
	+ engine system data files
	+ system files
	+ replication files
	+ general.log
	+ error.log
	+ mysql/
		- privilege tables
	+ database1/
		- tables for database1
	+ database2/
		- tables for database2

 The above shows:

 * There is a 'mariadb' catalog that stores admin users that can access all catalogs, shutdown servers, create new catalogs etc. The 'system root' user uses this when connecting.
* Each catalog has their own users, privilege tables, databases, error log and general logs

 The MariaDB server will automatically start in catalog mode if it notices the new directory structure.

 Catalog SQL Commands/Functions
------------------------------

 * [USE CATALOG catalog\_name](../use-catalog/index);
* CREATE CATALOG
* [DROP CATALOG](../drop-catalog/index)
* ALTER CATALOG
* SHOW CATALOGS (and also information\_schema.catalogs)
* SHOW CREATE CATALOG catalog\_name;
* SELECT CATALOG();

 Changes Needed in MariaDB Codebase
----------------------------------

 Client changes:

 * Add --catalog option to all standard MariaDB clients
* Add support for looping over all existing catalogs to:
	+ [mariadb-dump](../mariadb-dump/index)
	+ [mariadb-backup](../mariadb-backup/index)
	+ [mariadb-upgrade](../mariadb-upgrade/index)

 Changes to [mariadb-install-db](../mariadb-install-db/index):

 * Allow one to create multiple catalogs at once: -–catalogs=”catalog1,catalog2”
* Init MariaDB with catalog support: —use-catalogs

 Changes to mariadb (mysql client):

 * Add support for 'USE CATALOG xxx’' (and later 'use database xxx').

 Changes to mysql-test-run:

 * Add support of running tests with catalogs (normal tests are run without catalogs)

  Changes to MariaDB server (See [MDEV-31542](https://jira.mariadb.org/browse/MDEV-31542)):

 * Add support for 'catalog' in the connection string. For old clients, the user can specify the catalog as part of the database. If catalog is not specified, the 'def' catalog (like now) is assumed.
* Add CATALOG() function that returns the current catalog.
* Add ‘USE CATALOG xxx’
* Add 'USE DATABASE xxx'
* Create a global CATALOG object to hold all information related to the catalog.
* Add the current catalog to the 'thd' object.
* Add catalog argument to all functions that take 'database' as an argument.
* Add SHOW CATALOGS and information\_schema.catalogs
* Move all relevant global variables (users, privileges, mdl-locks(?), open log files) to be stored in the CATALOG structure.
* Add 'catalog privilege', for ‘catalog super users’ to allow them to access data in any catalog.
* Add support for accessing tables with 'catalog.schema.table' (needed for catalog super users).
* For normal users, only show processes for the current catalog in 'show processlist'.
* Add loops over all catalogs for information schema for the 'catalog root user'.
* Update performance schema to take catalogs into account.

 * Work with external connectors to get them to support connecting with a catalog.
* Check/update all storage engines to ensure they work also with catalogs.

 Notes:

 * The storage handler calls will probably not be changed. The storage engine will get the catalog name as part of the database name (catalog/database).
* We don't need a 'catalog' column for tables in the 'mysql' schema (like mysql.proc) as these are stored per catalog.

 Some Implementation Ideas
-------------------------

 * Instead of sending a catalog string to function, use a pointer to the global catalog object. Do the same later for databases. This allows use to precompute things like 'filename' for catalogs and databases and we don't have to do this for every table open. It also allows us to later support logging information at a catalog and database level.
* Don't take a MDL lock for the catalog for each table. The metadata lock for the catalog will be taken when a user logs in or changes catalog.
* Add system variables ‘current\_catalog’ and ‘current\_database’ and allow users to change these.
* Add support for ‘catalog ports’ that are connected to catalog. This allows users to connect to a specific catalog from any client software.

 Limitations (in addition to limitations listed in “User experience with catalogs”)
----------------------------------------------------------------------------------

 * Database names cannot contain ‘.’ when connecting from clients without the new catalog connect option.
* One cannot refer to other catalogs in triggers, stored procedures, events etc. This is because a transaction cannot span catalogs.
* Only the catalog root user can use mariadb-backup. This is a normal restriction as one has to be system root to be able to use mariadb-backup.
* Events are global (to save resources). Catalog users can enable/disable events for their catalog.

 Stage 2 (not in first release)
------------------------------

 * Support usage statistics per catalog and whole server (the last for the ‘catalog root user’). This allows the DBA to see the number of queries, type of queries etc. Some ‘system’ and ‘global innodb’ statistics will only be shown globally (number of open files, number of sync calls etc).
* Support a my.cnf file in each catalog directory to handle catalog (customer) unique defaults.
* Add quotas per catalog for tables and temporary files.
* Add more support to limit users from overusing resources (cpu, tables, databases, number of connections etc)
* Support 'drop catalog'. (This is in Stage 2 as there may be some issues to drop already active CATALOG objects)
* Add optional catalog support to the S3 engine
* More things will be added later.

 Stage 3
-------

 * Allow users to manage their own replication stream (maybe?).
* Allow users to have different options for the S3 engine
* More things will be added later.

 Appendix

 Legacy Connector Support

 SQLALchemy test:

 
```
In [1]: from sqlalchemy.engine import make_url
In [2]: u = make_url('mariadb+mariadbconnector://app_user:Password123!@127.0.0.1:3306/catalog/company')
In [3]: u.database
Out[3]: 'catalog/company'

```

The following tests ensured that inside the server (mysql\_change\_db), the “catalog/test” was picked up as the database.

 PHP PDO test:

 
```
$ php -r '$db = new \PDO("mysql:host=localhost;user=dan;dbname=catalog/test;charset=utf8mb4;unix_socket=/tmp/build-mariadb-server-10.4.sock");'

```

PHP mysqli test:

 
```
php -r '$dbcon = mysqli_connect("localhost","dan","nopass","catalog/test",3306,"/tmp/build-mariadb-server-10.4.sock");'

```

Nodejs test:

 
```
var mysql = require('mysql')
var con = mysql.createConnection({
  socketPath: "/tmp/build-mariadb-server-10.4.sock",
  user: "dan",
  password: "yourpassword",
  database: "catalog/test",
})
con.connect(function(err) {
  if (err) throw err;
  console.log("Connected!");
})

```

(need to map out a few other connectors here to make sure it’s supported well in this form).

 Ref: [https://mariadb.com/kb/en/connection/#handshake-response-packet](../connection/index#handshake-response-packet)

 Migration of existing MariaDB original mode to the new catalog layout
---------------------------------------------------------------------

 As shared hosting services have a naming scheme from user/schema to database name in MariaDB, to provide a migration to the new catalog layout, the following steps will be required:

 * Use [mariadb-dump](../mariadb-dump/index) to dump the original data
* On the new server execute:
* [mariadb-install-db –catalogs=’catalog\_name’](../mariadb-install-db/index)
* mariadb –catalog catalog\_name < dump\_file

 This is needed as InnoDB needs to know where the new files are located.

 Migration of one catalog user to another MariaDB server
-------------------------------------------------------

 Create a migration tool set / procedure that does the following

 * Execute [FLUSH TABLES FOR EXPORT](../flush-tables-for-export/index) for all tables in a catalog.
* Take a copy of the catalog directory
* Copy the data to a new catalog directory to the new server
* Run [ALTER TABLE ... IMPORT TABLESPACE](../alter-table/index#import-tablespace) on each InnoDB table

 Note that for partitioned tables the process will be a bit more complex, see above link.

 This procedure will be a bit easier after an in-the-works patch for InnoDB related to IMPORT will be pushed. (Should happen before we start on the catalog project)

 Other Things
------------

 * Drizzle’s default catalog was called "local". MariaDB’s default will be called ‘def’, as this is what we already have as the default catalog in information\_schema, in current connectors and other places.
* CONNECT engine will need testing against catalogs and maybe a small code change to support them. It could also be a way to join from one catalog to another.

 See also
--------

 * [MDEV-31542](https://jira.mariadb.org/browse/MDEV-31542) Add multi-tenancy catalogs to MariaDB

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/catalogs-overview/>

IsEmpty
=======

    A synonym for [ST\_IsEmpty](../st_isempty/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-isempty/>

NumGeometries
=============

    A synonym for [ST\_NumGeometries](../st_numgeometries/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geometry-properties-numgeometries/>

Security Vulnerabilities Fixed in Oracle MySQL That Did Not Exist in MariaDB
============================================================================

    About
-----

 CVE stands for *"**C**ommon **V**ulnerabilities and **E**xposures"*. It is a publicly available and free to use database of known software vulnerabilities maintained at <https://cve.mitre.org/>

 CPU stands for *"**C**ritical **P**atch **U**pdate"*. Oracle publishes Critical Patch Update Advisories four times a year, [on the Tuesday closest to the 17th day of January, April, July and October](https://www.oracle.com/technetwork/topics/security/alerts-086861.html#CriticalPatchUpdates). MySQL vulnerabilities are included in these CPU Advisories.

 Some vulnerabilities found in MySQL apply to MariaDB as well, they are listed on the [Security](../security/index) page.

 Other vulnerabilities found in MySQL do not apply to MariaDB.

 This page lists all CVEs that were fixed in MySQL and mentioned in Oracle CPU Advisories, but that — to the best of our knowledge — were never present in MariaDB.

 Full List of CVEs Fixed in Oracle MySQL That Never Existed in MariaDB
---------------------------------------------------------------------

 ### [July 2023](https://www.oracle.com/security-alerts/cpujul2023.html#AppendixMSQL)

 * [CVE-2023-20862](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-20862)
* [CVE-2022-37865](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-37865)
* [CVE-2022-4899](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-4899)
* [CVE-2023-0361](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-0361)
* [CVE-2022-4899](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-4899)
* [CVE-2023-24998](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-24998)
* [CVE-2023-28709](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-28709)
* [CVE-2023-2650](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2650)
* [CVE-2022-4899](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-4899)
* [CVE-2023-2650](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-2650)
* [CVE-2023-28484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-28484)
* [CVE-2023-22053](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22053) \* [CVE-2023-22008](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22008)
* [CVE-2023-22046](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22046)
* [CVE-2023-22054](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22054)
* [CVE-2023-22056](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22056)
* [CVE-2023-21950](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21950)
* [CVE-2023-22007](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22007)
* [CVE-2023-22057](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22057) \* [CVE-2023-22033](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22033)
* [CVE-2023-22058](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22058)
* [CVE-2023-22005](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22005)
* [CVE-2023-22048](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22048)
* [CVE-2023-22038](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-22038)

 ### [April 2023](https://www.oracle.com/security-alerts/cpuapr2023.html#AppendixMSQL)

 * [CVE-2022-37434](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-37434)
* [CVE-2022-43548](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-43548)
* [CVE-2023-0215](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-0215)
* [CVE-2022-45143](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-45143)
* [CVE-2022-43551](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-43551)
* [CVE-2023-21912](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21912)
* [CVE-2023-21980](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21980)
* [CVE-2023-21946](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21946)
* [CVE-2022-31160](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-31160)
* [CVE-2023-21929](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21929)
* [CVE-2023-21971](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21971)
* [CVE-2023-21911](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21911)
* [CVE-2023-21962](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21962)
* [CVE-2023-21919](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21919)
* [CVE-2023-21933](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21933)
* [CVE-2023-21972](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21972)
* [CVE-2023-21966](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21966)
* [CVE-2023-21913](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21913)
* [CVE-2023-21917](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21917)
* [CVE-2023-21920](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21920)
* [CVE-2023-21935](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21935)
* [CVE-2023-21945](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21945)
* [CVE-2023-21976](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21976)
* [CVE-2023-21977](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21977)
* [CVE-2023-21982](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21982)
* [CVE-2023-21953](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21953)
* [CVE-2023-21955](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21955)
* [CVE-2023-21940](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21940)
* [CVE-2023-21947](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21947)
* [CVE-2023-21963](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21963)

 ### [January 2023](https://www.oracle.com/security-alerts/cpujan2023.html#AppendixMSQL)

 * [CVE-2022-31692](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-31692)
* [CVE-2022-32221](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32221)
* [CVE-2022-37434](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-37434)
* [CVE-2020-36242](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-36242)
* [CVE-2022-24407](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24407)
* [CVE-2022-24407](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24407)
* [CVE-2022-40304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-40304)
* [CVE-2022-3171](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3171)
* [CVE-2022-1941](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-1941)
* [CVE-2022-42252](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42252)
* [CVE-2020-10735](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735)
* [CVE-2022-22971](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22971)
* [CVE-2023-21868](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21868)
* [CVE-2023-21860](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21860)
* [CVE-2023-21875](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21875)
* [CVE-2023-21869](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21869)
* [CVE-2023-21877](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21877)
* [CVE-2023-21880](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21880)
* [CVE-2023-21872](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21872)
* [CVE-2023-21871](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21871)
* [CVE-2023-21836](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21836)
* [CVE-2023-21887](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21887)
* [CVE-2023-21863](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21863)
* [CVE-2023-21864](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21864)
* [CVE-2023-21865](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21865)
* [CVE-2023-21866](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21866)
* [CVE-2023-21867](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21867)
* [CVE-2023-21870](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21870)
* [CVE-2023-21873](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21873)
* [CVE-2023-21876](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21876)
* [CVE-2023-21878](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21878)
* [CVE-2023-21879](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21879)
* [CVE-2023-21881](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21881)
* [CVE-2023-21883](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21883)
* [CVE-2023-21840](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21840)
* [CVE-2023-21882](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21882)
* [CVE-2023-21874](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-21874)

 ### [October 2022](https://www.oracle.com/security-alerts/cpuoct2022.html#AppendixMSQL)

 * [CVE-2022-2097](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-2097)
* [CVE-2022-21594](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21594)
* [CVE-2022-21599](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21599)
* [CVE-2022-21600](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21600)
* [CVE-2022-21604](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21604)
* [CVE-2022-21605](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21605)
* [CVE-2022-21607](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21607)
* [CVE-2022-21608](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21608)
* [CVE-2022-21611](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21611)
* [CVE-2022-21617](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21617)
* [CVE-2022-21625](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21625)
* [CVE-2022-21632](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21632)
* [CVE-2022-21633](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21633)
* [CVE-2022-21635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21635)
* [CVE-2022-21637](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21637)
* [CVE-2022-21638](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21638)
* [CVE-2022-21640](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21640)
* [CVE-2022-21641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21641)
* [CVE-2022-29824](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-29824)
* [CVE-2022-31129](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-31129)
* [CVE-2022-32207](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-32207)
* [CVE-2022-34305](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-34305)
* [CVE-2022-35737](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-35737)
* [CVE-2022-39400](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39400)
* [CVE-2022-39402](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39402)
* [CVE-2022-39403](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39403)
* [CVE-2022-39404](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39404)
* [CVE-2022-39408](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39408)
* [CVE-2022-39410](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-39410)

 
Not a vulnerability:

 * [CVE-2022-21589](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21589) — [MDEV-29834](https://jira.mariadb.org/browse/MDEV-29834)
* [CVE-2022-21592](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21592) — [MDEV-9069](https://jira.mariadb.org/browse/MDEV-9069)

 
### [July 2022](https://www.oracle.com/security-alerts/cpujul2022.html#AppendixMSQL)

 * [CVE-2021-31805](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-31805)
* [CVE-2022-1292](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-1292)
* [CVE-2022-1292](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-1292)
* [CVE-2022-21824](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21824)
* [CVE-2022-27778](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-27778)
* [CVE-2021-22119](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22119)
* [CVE-2022-23308](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23308)
* [CVE-2020-26237](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26237)
* [CVE-2022-21556](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21556)
* [CVE-2022-21569](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21569)
* [CVE-2022-21550](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21550)
* [CVE-2022-21519](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21519)
* [CVE-2022-21527](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21527)
* [CVE-2022-21528](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21528)
* [CVE-2022-21509](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21509)
* [CVE-2022-22968](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22968)
* [CVE-2022-21539](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21539)
* [CVE-2022-21517](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21517)
* [CVE-2022-21537](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21537)
* [CVE-2022-21547](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21547)
* [CVE-2022-21525](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21525)
* [CVE-2022-21526](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21526)
* [CVE-2022-21529](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21529)
* [CVE-2022-21530](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21530)
* [CVE-2022-21531](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21531)
* [CVE-2022-21553](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21553)
* [CVE-2022-21515](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21515)
* [CVE-2022-21455](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21455)
* [CVE-2022-21534](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21534)
* [CVE-2022-21522](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21522)
* [CVE-2022-21555](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21555)
* [CVE-2022-21538](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21538)
* [CVE-2022-21535](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21535)

 ### [April 2022](https://www.oracle.com/security-alerts/cpuapr2022.html#AppendixMSQL)

 * [CVE-2021-22570](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22570)
* [CVE-2021-41184](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-41184)
* [CVE-2021-42340](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-42340)
* [CVE-2021-44832](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44832)
* [CVE-2022-21412](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21412)
* [CVE-2022-21413](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21413)
* [CVE-2022-21414](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21414)
* [CVE-2022-21415](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21415)
* [CVE-2022-21417](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21417)
* [CVE-2022-21418](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21418)
* [CVE-2022-21423](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21423)
* [CVE-2022-21425](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21425)
* [CVE-2022-21435](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21435)
* [CVE-2022-21436](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21436)
* [CVE-2022-21437](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21437)
* [CVE-2022-21438](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21438)
* [CVE-2022-21440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21440)
* [CVE-2022-21444](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21444)
* [CVE-2022-21452](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21452)
* [CVE-2022-21454](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21454)
* [CVE-2022-21457](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21457)
* [CVE-2022-21459](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21459)
* [CVE-2022-21460](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21460)
* [CVE-2022-21462](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21462)
* [CVE-2022-21478](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21478)
* [CVE-2022-21479](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21479)
* [CVE-2022-21482](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21482)
* [CVE-2022-21483](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21483)
* [CVE-2022-21484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21484)
* [CVE-2022-21485](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21485)
* [CVE-2022-21486](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21486)
* [CVE-2022-21489](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21489)
* [CVE-2022-21490](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21490)
* [CVE-2022-22965](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-22965)
* [CVE-2022-23181](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23181)
* [CVE-2022-23305](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23305)

 ### [January 2022](https://www.oracle.com/security-alerts/cpujan2022.html#AppendixMSQL)

 * [CVE-2021-22946](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22946)
* [CVE-2021-3712](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3712)
* [CVE-2022-21278](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21278)
* [CVE-2022-21351](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21351)
* [CVE-2022-21363](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21363)
* [CVE-2022-21358](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21358)
* [CVE-2021-3634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3634)
* [CVE-2022-21279](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21279)
* [CVE-2022-21280](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21280)
* [CVE-2022-21284](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21284)
* [CVE-2022-21285](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21285)
* [CVE-2022-21286](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21286)
* [CVE-2022-21287](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21287)
* [CVE-2022-21288](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21288)
* [CVE-2022-21289](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21289)
* [CVE-2022-21290](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21290)
* [CVE-2022-21307](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21307)
* [CVE-2022-21308](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21308)
* [CVE-2022-21309](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21309)
* [CVE-2022-21310](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21310)
* [CVE-2022-21314](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21314)
* [CVE-2022-21315](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21315)
* [CVE-2022-21316](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21316)
* [CVE-2022-21318](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21318)
* [CVE-2022-21320](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21320)
* [CVE-2022-21322](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21322)
* [CVE-2022-21326](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21326)
* [CVE-2022-21327](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21327)
* [CVE-2022-21328](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21328)
* [CVE-2022-21329](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21329)
* [CVE-2022-21330](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21330)
* [CVE-2022-21332](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21332)
* [CVE-2022-21334](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21334)
* [CVE-2022-21335](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21335)
* [CVE-2022-21336](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21336)
* [CVE-2022-21337](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21337)
* [CVE-2022-21356](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21356)
* [CVE-2022-21380](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21380)
* [CVE-2022-21352](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21352)
* [CVE-2022-21367](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21367)
* [CVE-2022-21301](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21301)
* [CVE-2022-21378](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21378)
* [CVE-2022-21302](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21302)
* [CVE-2022-21254](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21254)
* [CVE-2022-21348](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21348)
* [CVE-2022-21270](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21270)
* [CVE-2022-21256](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21256)
* [CVE-2022-21379](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21379)
* [CVE-2022-21362](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21362)
* [CVE-2022-21374](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21374)
* [CVE-2022-21253](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21253)
* [CVE-2022-21264](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21264)
* [CVE-2022-21297](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21297)
* [CVE-2022-21339](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21339)
* [CVE-2022-21342](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21342)
* [CVE-2022-21370](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21370)
* [CVE-2022-21304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21304)
* [CVE-2022-21344](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21344)
* [CVE-2022-21303](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21303)
* [CVE-2022-21368](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21368)
* [CVE-2022-21245](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21245)
* [CVE-2022-21265](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21265)
* [CVE-2022-21311](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21311)
* [CVE-2022-21312](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21312)
* [CVE-2022-21313](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21313)
* [CVE-2022-21317](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21317)
* [CVE-2022-21319](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21319)
* [CVE-2022-21321](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21321)
* [CVE-2022-21323](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21323)
* [CVE-2022-21324](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21324)
* [CVE-2022-21325](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21325)
* [CVE-2022-21331](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21331)
* [CVE-2022-21333](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21333)
* [CVE-2022-21355](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21355)
* [CVE-2022-21357](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21357)
* [CVE-2022-21249](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21249)
* [CVE-2022-21372](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21372)

 ### [October 2021](https://www.oracle.com/security-alerts/cpuoct2021.html#AppendixMSQL)

 * [CVE-2021-22931](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22931)
* [CVE-2021-3711](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3711)
* [CVE-2021-22112](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22112)
* [CVE-2021-3518](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3518)
* [CVE-2021-22118](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22118)
* [CVE-2021-22926](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22926)
* [CVE-2021-36222](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-36222)
* [CVE-2021-35583](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35583)
* [CVE-2021-3712](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3712)
* [CVE-2021-35610](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35610)
* [CVE-2021-35597](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35597)
* [CVE-2021-35607](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35607)
* [CVE-2021-2481](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2481)
* [CVE-2021-35590](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35590)
* [CVE-2021-35592](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35592)
* [CVE-2021-35593](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35593)
* [CVE-2021-35594](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35594)
* [CVE-2021-35598](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35598)
* [CVE-2021-35621](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35621)
* [CVE-2021-2471](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2471)
* [CVE-2021-35612](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35612)
* [CVE-2021-20227](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-20227)
* [CVE-2021-33037](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33037)
* [CVE-2021-29425](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-29425)
* [CVE-2021-35608](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35608)
* [CVE-2021-35602](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35602)
* [CVE-2021-35577](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35577)
* [CVE-2021-2478](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2478)
* [CVE-2021-2479](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2479)
* [CVE-2021-35537](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35537)
* [CVE-2021-35591](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35591)
* [CVE-2021-35596](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35596)
* [CVE-2021-35648](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35648)
* [CVE-2021-35631](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35631)
* [CVE-2021-35626](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35626)
* [CVE-2021-35627](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35627)
* [CVE-2021-35628](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35628)
* [CVE-2021-35629](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35629)
* [CVE-2021-35575](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35575)
* [CVE-2021-35634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35634)
* [CVE-2021-35635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35635)
* [CVE-2021-35636](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35636)
* [CVE-2021-35638](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35638)
* [CVE-2021-35641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35641)
* [CVE-2021-35642](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35642)
* [CVE-2021-35643](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35643)
* [CVE-2021-35644](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35644)
* [CVE-2021-35645](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35645)
* [CVE-2021-35646](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35646)
* [CVE-2021-35647](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35647)
* [CVE-2021-35630](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35630)
* [CVE-2021-35637](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35637)
* [CVE-2021-35546](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35546)
* [CVE-2021-35622](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35622)
* [CVE-2021-35624](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35624)
* [CVE-2021-35639](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35639)
* [CVE-2021-35632](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35632)
* [CVE-2021-35584](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35584)
* [CVE-2021-35613](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35613)
* [CVE-2021-35640](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35640)
* [CVE-2021-35633](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35633)
* [CVE-2021-35625](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35625)
* [CVE-2021-35623](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35623)
* [CVE-2021-35618](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-35618)

 ### [July 2021](https://www.oracle.com/security-alerts/cpujul2021.html#AppendixMSQL)

 * [CVE-2021-22884](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22884)
* [CVE-2021-22901](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-22901)
* [CVE-2021-25122](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-25122)
* [CVE-2019-17543](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17543)
* [CVE-2021-3450](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3450)
* [CVE-2021-2417](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2417)
* [CVE-2021-2390](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2390)
* [CVE-2021-2429](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2429)
* [CVE-2021-2356](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2356)
* [CVE-2021-2385](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2385)
* [CVE-2021-2339](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2339)
* [CVE-2021-2352](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2352)
* [CVE-2021-2399](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2399)
* [CVE-2021-2370](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2370)
* [CVE-2021-2440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2440)
* [CVE-2021-2354](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2354)
* [CVE-2021-2402](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2402)
* [CVE-2021-2342](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2342)
* [CVE-2021-2357](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2357)
* [CVE-2021-2367](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2367)
* [CVE-2021-2412](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2412)
* [CVE-2021-2383](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2383)
* [CVE-2021-2384](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2384)
* [CVE-2021-2387](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2387)
* [CVE-2021-2444](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2444)
* [CVE-2021-2410](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2410)
* [CVE-2021-2418](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2418)
* [CVE-2021-2425](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2425)
* [CVE-2021-2426](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2426)
* [CVE-2021-2427](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2427)
* [CVE-2021-2437](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2437)
* [CVE-2021-2441](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2441)
* [CVE-2021-2422](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2422)
* [CVE-2021-2424](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2424)
* [CVE-2021-2374](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2374)
* [CVE-2021-2411](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2411)
* [CVE-2021-2340](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2340)

 ### [Apr 2021](https://www.oracle.com/security-alerts/cpuapr2021.html#AppendixMSQL)

 * [CVE-2019-7317](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-7317)
* [CVE-2020-1971](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1971)
* [CVE-2020-8277](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8277)
* [CVE-2020-17527](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-17527)
* [CVE-2020-17530](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-17530)
* [CVE-2020-28196](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-28196)
* [CVE-2021-2146](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2146)
* [CVE-2021-2160](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2160)
* [CVE-2021-2162](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2162)
* [CVE-2021-2164](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2164)
* [CVE-2021-2169](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2169)
* [CVE-2021-2170](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2170)
* [CVE-2021-2171](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2171)
* [CVE-2021-2172](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2172)
* [CVE-2021-2178](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2178)
* [CVE-2021-2179](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2179)
* [CVE-2021-2193](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2193)
* [CVE-2021-2196](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2196)
* [CVE-2021-2201](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2201)
* [CVE-2021-2202](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2202)
* [CVE-2021-2203](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2203)
* [CVE-2021-2208](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2208)
* [CVE-2021-2212](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2212)
* [CVE-2021-2213](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2213)
* [CVE-2021-2215](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2215)
* [CVE-2021-2217](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2217)
* [CVE-2021-2226](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2226)
* [CVE-2021-2230](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2230)
* [CVE-2021-2232](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2232)
* [CVE-2021-2278](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2278)
* [CVE-2021-2293](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2293)
* [CVE-2021-2298](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2298)
* [CVE-2021-2299](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2299)
* [CVE-2021-2300](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2300)
* [CVE-2021-2301](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2301)
* [CVE-2021-2304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2304)
* [CVE-2021-2305](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2305)
* [CVE-2021-2307](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2307)
* [CVE-2021-2308](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2308)
* [CVE-2021-3449](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3449)
* [CVE-2021-3450](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3450)
* [CVE-2021-23841](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-23841)

 ### [Jan 2021](https://www.oracle.com/security-alerts/cpujan2021.html#AppendixMSQL)

 * [CVE-2019-10086](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10086)
* [CVE-2020-1971](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1971)
* [CVE-2020-5408](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5408)
* [CVE-2020-5421](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5421)
* [CVE-2020-13871](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-13871)
* [CVE-2021-1998](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-1998)
* [CVE-2021-2001](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2001)
* [CVE-2021-2002](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2002)
* [CVE-2021-2006](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2006)
* [CVE-2021-2009](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2009)
* [CVE-2021-2010](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2010)
* [CVE-2021-2012](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2012)
* [CVE-2021-2014](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2014)
* [CVE-2021-2016](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2016)
* [CVE-2021-2019](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2019)
* [CVE-2021-2020](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2020)
* [CVE-2021-2021](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2021)
* [CVE-2021-2024](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2024)
* [CVE-2021-2028](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2028)
* [CVE-2021-2030](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2030)
* [CVE-2021-2031](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2031)
* [CVE-2021-2036](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2036)
* [CVE-2021-2038](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2038)
* [CVE-2021-2042](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2042)
* [CVE-2021-2046](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2046)
* [CVE-2021-2048](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2048)
* [CVE-2021-2055](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2055)
* [CVE-2021-2056](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2056)
* [CVE-2021-2058](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2058)
* [CVE-2021-2060](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2060)
* [CVE-2021-2061](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2061)
* [CVE-2021-2065](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2065)
* [CVE-2021-2070](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2070)
* [CVE-2021-2072](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2072)
* [CVE-2021-2076](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2076)
* [CVE-2021-2081](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2081)
* [CVE-2021-2087](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2087)
* [CVE-2021-2088](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2088)
* [CVE-2021-2122](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-2122)

 ### [Oct 2020](https://www.oracle.com/security-alerts/cpuoct2020.html#AppendixMSQL)

 * [CVE-2020-1730](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1730)
* [CVE-2020-1967](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1967)
* [CVE-2020-8174](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8174)
* [CVE-2020-13935](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-13935)
* [CVE-2020-14672](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14672) 2f35c37bacf0
* [CVE-2020-14760](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14760)
* [CVE-2020-14769](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14769) 6a0e79b462e1
* [CVE-2020-14771](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14771)
* [CVE-2020-14773](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14773)
* [CVE-2020-14775](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14775)
* [CVE-2020-14777](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14777)
* [CVE-2020-14785](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14785)
* [CVE-2020-14786](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14786)
* [CVE-2020-14790](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14790)
* [CVE-2020-14791](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14791)
* [CVE-2020-14793](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14793) 9bb243a3fa25
* [CVE-2020-14794](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14794)
* [CVE-2020-14799](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14799)
* [CVE-2020-14800](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14800)
* [CVE-2020-14804](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14804)
* [CVE-2020-14809](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14809)
* [CVE-2020-14814](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14814)
* [CVE-2020-14821](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14821)
* [CVE-2020-14827](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14827)
* [CVE-2020-14828](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14828)
* [CVE-2020-14829](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14829)
* [CVE-2020-14830](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14830)
* [CVE-2020-14836](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14836)
* [CVE-2020-14837](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14837)
* [CVE-2020-14838](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14838)
* [CVE-2020-14839](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14839)
* [CVE-2020-14844](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14844)
* [CVE-2020-14845](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14845)
* [CVE-2020-14846](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14846)
* [CVE-2020-14848](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14848)
* [CVE-2020-14852](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14852)
* [CVE-2020-14853](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14853)
* [CVE-2020-14860](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14860)
* [CVE-2020-14861](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14861)
* [CVE-2020-14866](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14866)
* [CVE-2020-14867](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14867) 7e730bd604e1
* [CVE-2020-14868](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14868)
* [CVE-2020-14869](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14869)
* [CVE-2020-14870](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14870)
* [CVE-2020-14873](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14873)
* [CVE-2020-14878](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14878)
* [CVE-2020-14888](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14888)
* [CVE-2020-14891](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14891)
* [CVE-2020-14893](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14893)

 ### [Jul 2020](https://www.oracle.com/security-alerts/cpujul2020.html#AppendixMSQL)

 * [CVE-2019-1551](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1551)
* [CVE-2020-1938](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1938)
* [CVE-2020-1967](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1967)
* [CVE-2020-5258](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5258)
* [CVE-2020-5398](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-5398)
* [CVE-2020-14539](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14539)
* [CVE-2020-14540](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14540)
* [CVE-2020-14547](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14547)
* [CVE-2020-14553](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14553)
* [CVE-2020-14559](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14559)
* [CVE-2020-14567](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14567)
* [CVE-2020-14568](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14568)
* [CVE-2020-14575](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14575)
* [CVE-2020-14576](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14576)
* [CVE-2020-14586](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14586)
* [CVE-2020-14591](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14591)
* [CVE-2020-14597](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14597)
* [CVE-2020-14614](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14614)
* [CVE-2020-14619](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14619)
* [CVE-2020-14620](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14620)
* [CVE-2020-14623](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14623)
* [CVE-2020-14624](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14624)
* [CVE-2020-14631](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14631)
* [CVE-2020-14632](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14632)
* [CVE-2020-14633](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14633)
* [CVE-2020-14634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14634)
* [CVE-2020-14641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14641)
* [CVE-2020-14643](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14643)
* [CVE-2020-14651](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14651)
* [CVE-2020-14654](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14654)
* [CVE-2020-14656](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14656)
* [CVE-2020-14663](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14663)
* [CVE-2020-14678](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14678)
* [CVE-2020-14680](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14680)
* [CVE-2020-14697](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14697)
* [CVE-2020-14702](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14702)
* [CVE-2020-14725](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-14725)

 ### [Apr 2020](https://www.oracle.com/security-alerts/cpuapr2020.html#AppendixMSQL)

 * [CVE-2019-1547](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547)
* [CVE-2019-5482](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5482)
* [CVE-2019-14889](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14889)
* [CVE-2019-15601](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-15601)
* [CVE-2019-17563](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-17563)
* [CVE-2019-19646](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-19646)
* [CVE-2020-2759](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2759)
* [CVE-2020-2761](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2761)
* [CVE-2020-2762](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2762)
* [CVE-2020-2763](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2763)
* [CVE-2020-2765](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2765)
* [CVE-2020-2768](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2768)
* [CVE-2020-2770](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2770)
* [CVE-2020-2774](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2774)
* [CVE-2020-2779](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2779)
* [CVE-2020-2790](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2790)
* [CVE-2020-2804](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2804)
* [CVE-2020-2806](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2806)
* [CVE-2020-2853](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2853)
* [CVE-2020-2875](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2875)
* [CVE-2020-2892](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2892)
* [CVE-2020-2893](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2893)
* [CVE-2020-2895](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2895)
* [CVE-2020-2896](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2896)
* [CVE-2020-2897](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2897)
* [CVE-2020-2898](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2898)
* [CVE-2020-2901](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2901)
* [CVE-2020-2903](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2903)
* [CVE-2020-2904](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2904)
* [CVE-2020-2921](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2921)
* [CVE-2020-2923](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2923)
* [CVE-2020-2924](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2924)
* [CVE-2020-2925](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2925)
* [CVE-2020-2926](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2926)
* [CVE-2020-2928](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2928)
* [CVE-2020-2930](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2930)
* [CVE-2020-2933](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2933)
* [CVE-2020-2934](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2934)

 ### [Jan 2020](https://www.oracle.com/security-alerts/cpujan2020.html#AppendixMSQL)

 * [CVE-2019-1547](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547)
* [CVE-2019-1547](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1547)
* [CVE-2019-8457](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8457)
* [CVE-2019-16168](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16168)
* [CVE-2020-2570](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2570)
* [CVE-2020-2572](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2572)
* [CVE-2020-2573](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2573)
* [CVE-2020-2577](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2577)
* [CVE-2020-2579](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2579)
* [CVE-2020-2580](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2580)
* [CVE-2020-2584](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2584)
* [CVE-2020-2588](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2588)
* [CVE-2020-2589](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2589)
* [CVE-2020-2627](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2627)
* [CVE-2020-2660](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2660)
* [CVE-2020-2679](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2679)
* [CVE-2020-2686](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2686)
* [CVE-2020-2694](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2694)

 ### [Oct 2019](https://www.oracle.com/technetwork/security-advisory/cpuoct2019-5072832.html#AppendixMSQL)

 * [CVE-2019-1543](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1543)
* [CVE-2019-1549](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1549)
* [CVE-2019-2911](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2911)
* [CVE-2019-2914](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2914)
* [CVE-2019-2920](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2920)
* [CVE-2019-2946](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2946)
* [CVE-2019-2948](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2948)
* [CVE-2019-2950](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2950)
* [CVE-2019-2957](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2957)
* [CVE-2019-2960](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2960)
* [CVE-2019-2963](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2963)
* [CVE-2019-2966](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2966)
* [CVE-2019-2967](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2967)
* [CVE-2019-2968](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2968)
* [CVE-2019-2969](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2969)
* [CVE-2019-2982](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2982)
* [CVE-2019-2991](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2991)
* [CVE-2019-2993](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2993)
* [CVE-2019-2997](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2997)
* [CVE-2019-2998](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2998)
* [CVE-2019-3003](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3003)
* [CVE-2019-3004](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3004)
* [CVE-2019-3009](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3009)
* [CVE-2019-3011](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3011)
* [CVE-2019-3018](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3018)
* [CVE-2019-5443](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-5443)
* [CVE-2019-8457](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-8457)
* [CVE-2019-10072](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10072)

 ### [July 2019](https://www.oracle.com/technetwork/security-advisory/cpujul2019-5072835.html)

 * [CVE-2018-15756](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15756)
* [CVE-2019-1559](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1559)
* [CVE-2019-2730](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2730)
* [CVE-2019-2731](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2731)
* [CVE-2019-2738](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2738)
* [CVE-2019-2741](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2741)
* [CVE-2019-2743](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2743)
* [CVE-2019-2746](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2746)
* [CVE-2019-2747](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2747)
* [CVE-2019-2752](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2752)
* [CVE-2019-2755](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2755)
* [CVE-2019-2757](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2757)
* [CVE-2019-2774](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2774)
* [CVE-2019-2778](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2778)
* [CVE-2019-2780](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2780)
* [CVE-2019-2784](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2784)
* [CVE-2019-2785](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2785)
* [CVE-2019-2789](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2789)
* [CVE-2019-2791](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2791)
* [CVE-2019-2795](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2795)
* [CVE-2019-2796](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2796)
* [CVE-2019-2797](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2797)
* [CVE-2019-2798](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2798)
* [CVE-2019-2800](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2800)
* [CVE-2019-2801](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2801)
* [CVE-2019-2802](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2802)
* [CVE-2019-2803](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2803)
* [CVE-2019-2808](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2808)
* [CVE-2019-2810](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2810)
* [CVE-2019-2811](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2811)
* [CVE-2019-2812](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2812)
* [CVE-2019-2814](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2814)
* [CVE-2019-2815](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2815)
* [CVE-2019-2819](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2819)
* [CVE-2019-2822](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2822)
* [CVE-2019-2826](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2826)
* [CVE-2019-2830](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2830)
* [CVE-2019-2834](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2834)
* [CVE-2019-2879](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2879)
* [CVE-2019-3822](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3822)

 ### [April 2019](https://www.oracle.com/technetwork/security-advisory/cpuapr2019-5072813.html)

 * [CVE-2018-0734](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0734)
* [CVE-2018-3123](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3123)
* [CVE-2019-1559](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1559)
* [CVE-2019-1559](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-1559)
* [CVE-2019-2566](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2566)
* [CVE-2019-2580](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2580)
* [CVE-2019-2581](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2581)
* [CVE-2019-2584](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2584)
* [CVE-2019-2585](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2585)
* [CVE-2019-2587](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2587)
* [CVE-2019-2589](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2589)
* [CVE-2019-2592](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2592)
* [CVE-2019-2593](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2593)
* [CVE-2019-2596](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2596)
* [CVE-2019-2606](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2606)
* [CVE-2019-2607](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2607)
* [CVE-2019-2617](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2617)
* [CVE-2019-2620](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2620)
* [CVE-2019-2623](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2623)
* [CVE-2019-2624](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2624)
* [CVE-2019-2625](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2625)
* [CVE-2019-2626](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2626)
* [CVE-2019-2630](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2630)
* [CVE-2019-2631](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2631)
* [CVE-2019-2632](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2632)
* [CVE-2019-2634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2634)
* [CVE-2019-2635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2635)
* [CVE-2019-2636](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2636)
* [CVE-2019-2644](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2644)
* [CVE-2019-2681](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2681)
* [CVE-2019-2683](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2683)
* [CVE-2019-2685](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2685)
* [CVE-2019-2686](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2686)
* [CVE-2019-2687](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2687)
* [CVE-2019-2688](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2688)
* [CVE-2019-2689](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2689)
* [CVE-2019-2691](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2691)
* [CVE-2019-2692](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2692)
* [CVE-2019-2693](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2693)
* [CVE-2019-2694](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2694)
* [CVE-2019-2695](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2695)

 ### [January 2019](https://www.oracle.com/technetwork/security-advisory/cpujan2019-5072801.html)

 * [CVE-2018-0732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732)
* [CVE-2018-0732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0732)
* [CVE-2018-0734](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0734)
* [CVE-2018-10933](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-10933)
* [CVE-2019-2420](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2420)
* [CVE-2019-2434](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2434)
* [CVE-2019-2435](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2435)
* [CVE-2019-2436](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2436)
* [CVE-2019-2482](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2482)
* [CVE-2019-2486](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2486)
* [CVE-2019-2494](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2494)
* [CVE-2019-2495](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2495)
* [CVE-2019-2502](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2502)
* [CVE-2019-2507](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2507)
* [CVE-2019-2513](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2513)
* [CVE-2019-2528](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2528)
* [CVE-2019-2530](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2530)
* [CVE-2019-2531](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2531)
* [CVE-2019-2532](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2532)
* [CVE-2019-2533](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2533)
* [CVE-2019-2534](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2534)
* [CVE-2019-2535](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2535)
* [CVE-2019-2536](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2536)
* [CVE-2019-2539](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-2539)

 ### [October 2018](https://www.oracle.com/technetwork/security-advisory/cpuoct2018-4428296.html)

 * [CVE-2018-1258](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1258)
* [CVE-2018-3137](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3137)
* [CVE-2018-3144](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3144)
* [CVE-2018-3145](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3145)
* [CVE-2018-3155](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3155)
* [CVE-2018-3161](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3161)
* [CVE-2018-3170](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3170)
* [CVE-2018-3171](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3171)
* [CVE-2018-3182](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3182)
* [CVE-2018-3186](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3186)
* [CVE-2018-3187](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3187)
* [CVE-2018-3195](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3195)
* [CVE-2018-3203](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3203)
* [CVE-2018-3212](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3212)
* [CVE-2018-3247](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3247)
* [CVE-2018-3258](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3258)
* [CVE-2018-3276](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3276)
* [CVE-2018-3278](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3278)
* [CVE-2018-3279](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3279)
* [CVE-2018-3280](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3280)
* [CVE-2018-3283](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3283)
* [CVE-2018-3285](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3285)
* [CVE-2018-3286](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3286)
* [CVE-2018-8014](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8014)
* [CVE-2018-11776](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-11776)

 ### [July 2018](http://www.oracle.com/technetwork/security-advisory/cpujul2018-4258247.html)

 * [CVE-2017-0379](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0379)
* [CVE-2017-5645](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5645)
* [CVE-2018-0739](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-0739)
* [CVE-2018-2598](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2598)
* [CVE-2018-3054](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3054)
* [CVE-2018-3056](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3056)
* [CVE-2018-3061](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3061)
* [CVE-2018-3062](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3062)
* [CVE-2018-3065](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3065)
* [CVE-2018-3067](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3067)
* [CVE-2018-3070](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3070)
* [CVE-2018-3071](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3071)
* [CVE-2018-3073](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3073)
* [CVE-2018-3074](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3074)
* [CVE-2018-3075](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3075)
* [CVE-2018-3077](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3077)
* [CVE-2018-3078](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3078)
* [CVE-2018-3079](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3079)
* [CVE-2018-3080](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3080)
* [CVE-2018-3082](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3082)
* [CVE-2018-3084](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3084)

 ### [April 2018](http://www.oracle.com/technetwork/security-advisory/cpuapr2018-3678067.html)

 * [CVE-2016-9878](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-9878)
* [CVE-2017-3737](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3737)
* [CVE-2018-2758](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2758)
* [CVE-2018-2762](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2762)
* [CVE-2018-2769](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2769)
* [CVE-2018-2773](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2773) — See [MDEV-13402](https://jira.mariadb.org/browse/MDEV-13402)
* [CVE-2018-2775](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2775)
* [CVE-2018-2776](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2776)
* [CVE-2018-2778](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2778)
* [CVE-2018-2779](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2779)
* [CVE-2018-2780](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2780)
* [CVE-2018-2805](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2805)
* [CVE-2018-2812](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2812)
* [CVE-2018-2816](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2816)
* [CVE-2018-2818](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2818)
* [CVE-2018-2839](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2839)
* [CVE-2018-2846](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2846)
* [CVE-2018-2877](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2877)

 ### [January 2018](http://www.oracle.com/technetwork/security-advisory/cpujan2018-3236628.html)

 * [CVE-2017-3736](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3736)
* [CVE-2017-3736](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3736)
* [CVE-2017-3737](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3737)
* [CVE-2017-12617](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-12617)
* [CVE-2018-2565](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2565)
* [CVE-2018-2573](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2573)
* [CVE-2018-2576](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2576)
* [CVE-2018-2583](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2583)
* [CVE-2018-2585](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2585)
* [CVE-2018-2586](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2586)
* [CVE-2018-2590](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2590)
* [CVE-2018-2591](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2591)
* [CVE-2018-2600](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2600)
* [CVE-2018-2645](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2645)
* [CVE-2018-2646](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2646)
* [CVE-2018-2647](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2647)
* [CVE-2018-2667](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2667)
* [CVE-2018-2696](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2696)
* [CVE-2018-2703](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-2703)

 ### [October 2017](http://www.oracle.com/technetwork/security-advisory/cpuoct2017-3236626.html)

 * [CVE-2017-3731](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3731)
* [CVE-2017-5664](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5664)
* [CVE-2017-10155](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10155)
* [CVE-2017-10165](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10165)
* [CVE-2017-10167](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10167)
* [CVE-2017-10203](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10203)
* [CVE-2017-10227](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10227)
* [CVE-2017-10276](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10276)
* [CVE-2017-10277](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10277)
* [CVE-2017-10279](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10279)
* [CVE-2017-10283](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10283)
* [CVE-2017-10284](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10284)
* [CVE-2017-10294](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10294)
* [CVE-2017-10296](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10296)
* [CVE-2017-10311](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10311)
* [CVE-2017-10313](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10313)
* [CVE-2017-10314](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10314)
* [CVE-2017-10424](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-10424)

 ### [July 2017](http://www.oracle.com/technetwork/security-advisory/cpujul2017-3236622.html)

 * [CVE-2014-1912](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1912)
* [CVE-2016-4436](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-4436)
* [CVE-2017-3529](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3529)
* [CVE-2017-3633](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3633)
* [CVE-2017-3634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3634)
* [CVE-2017-3635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3635)
* [CVE-2017-3637](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3637)
* [CVE-2017-3638](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3638)
* [CVE-2017-3639](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3639)
* [CVE-2017-3640](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3640)
* [CVE-2017-3642](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3642)
* [CVE-2017-3643](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3643)
* [CVE-2017-3644](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3644)
* [CVE-2017-3645](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3645)
* [CVE-2017-3646](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3646)
* [CVE-2017-3647](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3647)
* [CVE-2017-3648](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3648)
* [CVE-2017-3649](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3649)
* [CVE-2017-3650](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3650)
* [CVE-2017-3652](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3652)
* [CVE-2017-3732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3732)
* [CVE-2017-3732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3732)
* [CVE-2017-3732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3732)
* [CVE-2017-5647](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5647)
* [CVE-2017-5651](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5651)

 ### [April 2017](http://www.oracle.com/technetwork/security-advisory/cpuapr2017-3236618.html)

 * [CVE-2016-2176](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2176)
* [CVE-2016-2176](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2176)
* [CVE-2016-3092](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3092)
* [CVE-2016-6303](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6303)
* [CVE-2017-3304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3304)
* [CVE-2017-3305](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3305)
* [CVE-2017-3306](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3306)
* [CVE-2017-3307](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3307)
* [CVE-2017-3329](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3329)
* [CVE-2017-3331](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3331)
* [CVE-2017-3450](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3450)
* [CVE-2017-3452](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3452)
* [CVE-2017-3454](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3454)
* [CVE-2017-3455](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3455)
* [CVE-2017-3457](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3457)
* [CVE-2017-3458](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3458)
* [CVE-2017-3459](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3459)
* [CVE-2017-3460](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3460)
* [CVE-2017-3461](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3461)
* [CVE-2017-3462](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3462)
* [CVE-2017-3463](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3463)
* [CVE-2017-3465](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3465)
* [CVE-2017-3467](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3467)
* [CVE-2017-3468](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3468)
* [CVE-2017-3469](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3469)
* [CVE-2017-3523](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3523)
* [CVE-2017-3586](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3586)
* [CVE-2017-3589](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3589)
* [CVE-2017-3590](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3590)
* [CVE-2017-3599](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3599)
* [CVE-2017-3731](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3731)
* [CVE-2017-3732](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3732)
* [CVE-2017-5638](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638)

 ### [January 2017](http://www.oracle.com/technetwork/security-advisory/cpujan2017-2881727.html)

 * [CVE-2015-7501](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7501)
* [CVE-2016-0635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0635)
* [CVE-2016-0714](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0714)
* [CVE-2016-5541](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5541)
* [CVE-2016-5590](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5590)
* [CVE-2016-6304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6304)
* [CVE-2016-8318](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8318)
* [CVE-2016-8327](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8327)
* [CVE-2017-3251](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3251)
* [CVE-2017-3256](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3256)
* [CVE-2017-3273](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3273)
* [CVE-2017-3319](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3319)
* [CVE-2017-3320](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3320)
* [CVE-2017-3321](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3321)
* [CVE-2017-3322](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3322)
* [CVE-2017-3323](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-3323)

 ### [October 2016](http://www.oracle.com/technetwork/security-advisory/cpuoct2016-2881722.html)

 * [CVE-2016-3495](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3495)
* [CVE-2016-5507](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5507)
* [CVE-2016-5598](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5598)
* [CVE-2016-5609](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5609)
* [CVE-2016-5617](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5617)
* [CVE-2016-5625](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5625)
* [CVE-2016-5627](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5627)
* [CVE-2016-5628](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5628)
* [CVE-2016-5631](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5631)
* [CVE-2016-5632](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5632)
* [CVE-2016-5633](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5633)
* [CVE-2016-5634](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5634)
* [CVE-2016-5635](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5635)
* [CVE-2016-6304](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-6304)
* [CVE-2016-8284](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8284)
* [CVE-2016-8286](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8286)
* [CVE-2016-8287](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8287)
* [CVE-2016-8288](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8288)
* [CVE-2016-8289](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8289)
* [CVE-2016-8290](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8290)

 ### [July 2016](http://www.oracle.com/technetwork/security-advisory/cpujul2016-2881720.html)

 * [CVE-2016-2105](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-2105)
* [CVE-2016-3424](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3424)
* [CVE-2016-3440](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3440)
* [CVE-2016-3486](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3486)
* [CVE-2016-3501](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3501)
* [CVE-2016-3518](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3518)
* [CVE-2016-3588](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3588)
* [CVE-2016-3614](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3614)
* [CVE-2016-5436](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5436)
* [CVE-2016-5437](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5437)
* [CVE-2016-5439](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5439)
* [CVE-2016-5441](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5441)
* [CVE-2016-5442](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5442)
* [CVE-2016-5443](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5443)

 ### [April 2016](http://www.oracle.com/technetwork/security-advisory/cpuapr2016v3-2985753.html)

 * [CVE-2015-3194](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3194)
* [CVE-2016-0639](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0639)
* [CVE-2016-0652](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0652)
* [CVE-2016-0653](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0653)
* [CVE-2016-0654](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0654)
* [CVE-2016-0656](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0656)
* [CVE-2016-0657](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0657)
* [CVE-2016-0658](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0658)
* [CVE-2016-0659](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0659)
* [CVE-2016-0661](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0661)
* [CVE-2016-0662](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0662)
* [CVE-2016-0663](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0663)
* [CVE-2016-0665](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0665)
* [CVE-2016-0667](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0667)
* [CVE-2016-0705](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0705)
* [CVE-2016-3461](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-3461)

 ### [January 2016](https://www.oracle.com/technetwork/topics/security/cpujan2016-2367955.html)

 * [CVE-2016-0503](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0503)
* [CVE-2016-0504](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0504)
* [CVE-2016-0594](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0594)
* [CVE-2016-0595](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0595)
* [CVE-2016-0599](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0599)
* [CVE-2016-0601](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0601)
* [CVE-2016-0605](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0605)
* [CVE-2016-0607](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0607)
* [CVE-2016-0611](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0611)

 ### [October 2015](https://www.oracle.com/technetwork/topics/security/cpuoct2015-2367953.html)

 * [CVE-2015-0286](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0286)
* [CVE-2015-1793](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1793)
* [CVE-2015-3144](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-3144)
* [CVE-2015-4730](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4730)
* [CVE-2015-4766](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4766)
* [CVE-2015-4791](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4791)
* [CVE-2015-4800](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4800)
* [CVE-2015-4833](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4833)
* [CVE-2015-4862](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4862)
* [CVE-2015-4890](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4890)
* [CVE-2015-4904](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4904)
* [CVE-2015-4905](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4905)
* [CVE-2015-4910](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4910)

 ### [July 2015](https://www.oracle.com/technetwork/topics/security/cpujul2015-2367936.html)

 * [CVE-2015-2611](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2611)
* [CVE-2015-2617](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2617)
* [CVE-2015-2639](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2639)
* [CVE-2015-2641](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2641)
* [CVE-2015-2661](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2661)
* [CVE-2015-4737](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4737)
* [CVE-2015-4756](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4756)
* [CVE-2015-4761](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4761)
* [CVE-2015-4767](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4767)
* [CVE-2015-4769](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4769)
* [CVE-2015-4771](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4771)
* [CVE-2015-4772](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4772)

 ### [April 2015](https://www.oracle.com/technetwork/topics/security/cpuapr2015-2365600.html)

 * [CVE-2014-0112](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0112)
* [CVE-2014-3569](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3569)
* [CVE-2014-7809](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-7809)
* [CVE-2015-0405](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0405)
* [CVE-2015-0423](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0423)
* [CVE-2015-0438](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0438)
* [CVE-2015-0439](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0439)
* [CVE-2015-0498](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0498)
* [CVE-2015-0500](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0500)
* [CVE-2015-0503](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0503)
* [CVE-2015-0506](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0506)
* [CVE-2015-0507](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0507)
* [CVE-2015-0508](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0508)
* [CVE-2015-0511](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0511)
* [CVE-2015-2566](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2566)
* [CVE-2015-2567](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2567)
* [CVE-2015-2575](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2575)
* [CVE-2015-2576](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-2576)

 ### [October 2015](https://www.oracle.com/technetwork/topics/security/cpujan2015-1972971.html)

 * [CVE-2015-0385](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0385)
* [CVE-2015-0409](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-0409)

 ### [July 2014](https://www.oracle.com/technetwork/topics/security/cpujul2014-1972956.html)

 * [CVE-2014-2484](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2484)
* [CVE-2014-4214](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4214)
* [CVE-2014-4233](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4233)
* [CVE-2014-4238](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4238)
* [CVE-2014-4240](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-4240)

 ### [April 2014](https://www.oracle.com/technetwork/topics/security/cpuapr2014-1972952.html)

 * [CVE-2014-2434](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2434)
* [CVE-2014-2435](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2435)
* [CVE-2014-2442](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2442)
* [CVE-2014-2444](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2444)
* [CVE-2014-2450](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2450)
* [CVE-2014-2451](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-2451)

 ### [January 2014](https://www.oracle.com/technetwork/topics/security/cpujan2014-1972949.html)

 * [CVE-2013-4316](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-4316)
* [CVE-2013-5860](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5860)
* [CVE-2013-5881](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5881)
* [CVE-2013-5882](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5882)
* [CVE-2013-5894](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5894)
* [CVE-2014-0427](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0427)
* [CVE-2014-0430](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0430)
* [CVE-2014-0431](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0431)
* [CVE-2014-0433](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0433)

 ### [October 2013](https://www.oracle.com/technetwork/topics/security/cpuoct2013-1899837.html)

 * [CVE-2013-2251](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2251)
* [CVE-2013-5767](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5767)
* [CVE-2013-5770](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5770)
* [CVE-2013-5786](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5786)
* [CVE-2013-5793](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5793)

 ### [July 2013](https://www.oracle.com/technetwork/topics/security/cpujuly2013-1899826.html)

 * [CVE-2013-3795](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3795)
* [CVE-2013-3796](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3796)
* [CVE-2013-3798](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3798)
* [CVE-2013-3806](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3806)
* [CVE-2013-3810](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3810)
* [CVE-2013-3811](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-3811)

 ### [April 2013](https://www.oracle.com/technetwork/topics/security/cpuapr2013-1899555.html)

 * [CVE-2013-1566](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1566)
* [CVE-2013-1567](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1567)
* [CVE-2013-1570](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1570)
* [CVE-2013-2381](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2381)
* [CVE-2013-2395](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2395)

 ### [October 2012](https://www.oracle.com/technetwork/topics/security/cpuoct2012-1515893.html)

 * [CVE-2012-3144](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3144)
* [CVE-2012-3147](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3147)
* [CVE-2012-3149](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3149)
* [CVE-2012-3156](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-3156)

 ### [April 2012](https://www.oracle.com/technetwork/topics/security/cpuapr2012-366314.html)

 * [CVE-2012-0583](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-0583)
* [CVE-2012-1696](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1696)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/security-vulnerabilities-in-oracle-mysql-that-did-not-exist-in-mariadb/>

NumPoints
=========

    A synonym for [ST\_NumPoints](../st_numpoints/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring-properties-numpoints/>

PointN
======

    A synonym for [ST\_PointN](../st_pointn/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring-properties-pointn/>

MBR Definition
==============

    Description
-----------

 The MBR (Minimum Bounding Rectangle), or Envelope is the bounding geometry, formed by the minimum and maximum (X,Y) coordinates:

 Examples
--------

 
```
((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mbr-definition/>

Regular Expressions Overview
============================

     Regular Expressions allow MariaDB to perform complex pattern matching on a string. In many cases, the simple pattern matching provided by [LIKE](../like/index) is sufficient. `LIKE` performs two kinds of matches:

 * `_` - the underscore, matching a single character
* `%` - the percentage sign, matching any number of characters.

 In other cases you may need more control over the returned matches, and will need to use regular expressions.

 
**MariaDB starting with [10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/)**Until [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/), MariaDB used the POSIX 1003.2 compliant regular expression library. The new PCRE library is mostly backwards compatible with what is described below - see the [PCRE Regular Expressions](../pcre-regular-expressions/index) article for the enhancements made in 10.0.5.

 
Regular expression matches are performed with the [REGEXP](../regexp/index) function. `RLIKE` is a synonym for `REGEXP`.

 
Comparisons are performed on the byte value, so characters that are treated as equivalent by a collation, but do not have the same byte-value, such as accented characters, could evaluate as unequal.

 
Without any special characters, a regular expression match is true if the characters match. The match is case-insensitive, except in the case of BINARY strings.

 
```
SELECT 'Maria' REGEXP 'Maria';
+------------------------+
| 'Maria' REGEXP 'Maria' |
+------------------------+
|                      1 |
+------------------------+

SELECT 'Maria' REGEXP 'maria';
+------------------------+
| 'Maria' REGEXP 'maria' |
+------------------------+
|                      1 |
+------------------------+

SELECT BINARY 'Maria' REGEXP 'maria';
+-------------------------------+
| BINARY 'Maria' REGEXP 'maria' |
+-------------------------------+
|                             0 |
+-------------------------------+

```

Note that the word being matched must match the whole pattern:

 
```
SELECT 'Maria' REGEXP 'Mari';
+-----------------------+
| 'Maria' REGEXP 'Mari' |
+-----------------------+
|                     1 |
+-----------------------+

SELECT 'Mari' REGEXP 'Maria';
+-----------------------+
| 'Mari' REGEXP 'Maria' |
+-----------------------+
|                     0 |
+-----------------------+

```

The first returns true because the pattern "Mari" exists in the expression "Maria". When the order is reversed, the result is false, as the pattern "Maria" does not exist in the expression "Mari"

 A match can be performed against more than one word with the `|` character. For example:

 
```
SELECT 'Maria' REGEXP 'Monty|Maria';
+------------------------------+
| 'Maria' REGEXP 'Monty|Maria' |
+------------------------------+
|                            1 |
+------------------------------+

```

Special Characters
------------------

 The above examples introduce the syntax, but are not very useful on their own. It's the special characters that give regular expressions their power.

 #### ^

 `^` matches the beginning of a string (inside square brackets it can also mean NOT - see below):

 
```
SELECT 'Maria' REGEXP '^Ma';
+----------------------+
| 'Maria' REGEXP '^Ma' |
+----------------------+
|                    1 |
+----------------------+

```

#### $

 `$` matches the end of a string:

 
```
SELECT 'Maria' REGEXP 'ia$';
+----------------------+
| 'Maria' REGEXP 'ia$' |
+----------------------+
|                    1 |
+----------------------+

```

#### .

 `.` matches any single character:

 
```
SELECT 'Maria' REGEXP 'Ma.ia';
+------------------------+
| 'Maria' REGEXP 'Ma.ia' |
+------------------------+
|                      1 |
+------------------------+

SELECT 'Maria' REGEXP 'Ma..ia';
+-------------------------+
| 'Maria' REGEXP 'Ma..ia' |
+-------------------------+
|                       0 |
+-------------------------+

```

#### \*

 `x*` matches zero or more of a character `x`. In the examples below, it's the `r` character.

 
```
SELECT 'Maria' REGEXP 'Mar*ia';
+-------------------------+
| 'Maria' REGEXP 'Mar*ia' |
+-------------------------+
|                       1 |
+-------------------------+

SELECT 'Maia' REGEXP 'Mar*ia';
+------------------------+
| 'Maia' REGEXP 'Mar*ia' |
+------------------------+
|                      1 |
+------------------------+

SELECT 'Marrria' REGEXP 'Mar*ia';
+---------------------------+
| 'Marrria' REGEXP 'Mar*ia' |
+---------------------------+
|                         1 |
+---------------------------+

```

#### +

 `x+` matches one or more of a character `x`. In the examples below, it's the `r` character.

 
```
SELECT 'Maria' REGEXP 'Mar+ia';
+-------------------------+
| 'Maria' REGEXP 'Mar+ia' |
+-------------------------+
|                       1 |
+-------------------------+

SELECT 'Maia' REGEXP 'Mar+ia';
+------------------------+
| 'Maia' REGEXP 'Mar+ia' |
+------------------------+
|                      0 |
+------------------------+

SELECT 'Marrria' REGEXP 'Mar+ia';
+---------------------------+
| 'Marrria' REGEXP 'Mar+ia' |
+---------------------------+
|                         1 |
+---------------------------+

```

#### ?

 `x?` matches zero or one of a character `x`. In the examples below, it's the `r` character.

 
```
SELECT 'Maria' REGEXP 'Mar?ia';
+-------------------------+
| 'Maria' REGEXP 'Mar?ia' |
+-------------------------+
|                       1 |
+-------------------------+

SELECT 'Maia' REGEXP 'Mar?ia';
+------------------------+
| 'Maia' REGEXP 'Mar?ia' |
+------------------------+
|                      1 |
+------------------------+

SELECT 'Marrria' REGEXP 'Mar?ia';
+---------------------------+
| 'Marrria' REGEXP 'Mar?ia' |
+---------------------------+
|                         0 |
+---------------------------+

```

#### ()

 `(xyz)` - combine a sequence, for example `(xyz)+` or `(xyz)*`

 
```
SELECT 'Maria' REGEXP '(ari)+';
+-------------------------+
| 'Maria' REGEXP '(ari)+' |
+-------------------------+
|                       1 |
+-------------------------+

```

#### {}

 `x{n}` and `x{m,n}` This notation is used to match many instances of the `x`. In the case of `x{n}` the match must be exactly that many times. In the case of `x{m,n}`, the match can occur from `m` to `n` times. For example, to match zero or one instance of the string `ari` (which is identical to `(ari)?`), the following can be used:

 
```
SELECT 'Maria' REGEXP '(ari){0,1}';
+-----------------------------+
| 'Maria' REGEXP '(ari){0,1}' |
+-----------------------------+
|                           1 |
+-----------------------------+

```

#### []

 `[xy]` groups characters for matching purposes. For example, to match either the `p` or the `r` character:

 
```
SELECT 'Maria' REGEXP 'Ma[pr]ia';
+---------------------------+
| 'Maria' REGEXP 'Ma[pr]ia' |
+---------------------------+
|                         1 |
+---------------------------+

```

The square brackets also permit a range match, for example, to match any character from a-z, `[a-z]` is used. Numeric ranges are also permitted.

 
```
SELECT 'Maria' REGEXP 'Ma[a-z]ia';
+----------------------------+
| 'Maria' REGEXP 'Ma[a-z]ia' |
+----------------------------+
|                          1 |
+----------------------------+

```

The following does not match, as `r` falls outside of the range `a-p`.

 
```
SELECT 'Maria' REGEXP 'Ma[a-p]ia';
+----------------------------+
| 'Maria' REGEXP 'Ma[a-p]ia' |
+----------------------------+
|                          0 |
+----------------------------+

```

##### ^

 The `^` character means does `NOT` match, for example:

 
```
SELECT 'Maria' REGEXP 'Ma[^p]ia';
+---------------------------+
| 'Maria' REGEXP 'Ma[^p]ia' |
+---------------------------+
|                         1 |
+---------------------------+

SELECT 'Maria' REGEXP 'Ma[^r]ia';
+---------------------------+
| 'Maria' REGEXP 'Ma[^r]ia' |
+---------------------------+
|                         0 |
+---------------------------+

```

The `[` and `]` characters on their own can be literally matched inside a `[]` block, without escaping, as long as they immediately match the opening bracket:

 
```
SELECT '[Maria' REGEXP '[[]';
+-----------------------+
| '[Maria' REGEXP '[[]' |
+-----------------------+
|                     1 |
+-----------------------+

SELECT '[Maria' REGEXP '[]]';
+-----------------------+
| '[Maria' REGEXP '[]]' |
+-----------------------+
|                     0 |
+-----------------------+

SELECT ']Maria' REGEXP '[]]';
+-----------------------+
| ']Maria' REGEXP '[]]' |
+-----------------------+
|                     1 |
+-----------------------+

SELECT ']Maria' REGEXP '[]a]';
+------------------------+
| ']Maria' REGEXP '[]a]' |
+------------------------+
|                      1 |
+------------------------+

```

Incorrect order, so no match:

 
```
SELECT ']Maria' REGEXP '[a]]';
+------------------------+
| ']Maria' REGEXP '[a]]' |
+------------------------+
|                      0 |
+------------------------+

```

The `-` character can also be matched in the same way:

 
```
SELECT '-Maria' REGEXP '[1-10]';
+--------------------------+
| '-Maria' REGEXP '[1-10]' |
+--------------------------+
|                        0 |
+--------------------------+

SELECT '-Maria' REGEXP '[-1-10]';
+---------------------------+
| '-Maria' REGEXP '[-1-10]' |
+---------------------------+
|                         1 |
+---------------------------+

```

#### Word boundaries

 The `[:<:](%3c%3a)` and `[:>:](%3e%3a)` patterns match the beginning and the end of a word respectively. For example:

 
```
SELECT 'How do I upgrade MariaDB?' REGEXP '[[:<:]]MariaDB[[:>:]]';
+------------------------------------------------------------+
| 'How do I upgrade MariaDB?' REGEXP '[[:<:]]MariaDB[[:>:]]' |
+------------------------------------------------------------+
|                                                          1 |
+------------------------------------------------------------+

SELECT 'How do I upgrade MariaDB?' REGEXP '[[:<:]]Maria[[:>:]]';
+----------------------------------------------------------+
| 'How do I upgrade MariaDB?' REGEXP '[[:<:]]Maria[[:>:]]' |
+----------------------------------------------------------+
|                                                        0 |
+----------------------------------------------------------+

```

#### Character Classes

 There are a number of shortcuts to match particular preset character classes. These are matched with the `[:character_class:]` pattern (inside a `[]` set). The following character classes exist:

 


| Character Class | Description |
| --- | --- |
| alnum | Alphanumeric |
| alpha | Alphabetic |
| blank | Whitespace |
| cntrl | Control characters |
| digit | Digits |
| graph | Graphic characters |
| lower | Lowercase alphabetic |
| print | Graphic or space characters |
| punct | Punctuation |
| space | Space, tab, newline, and carriage return |
| upper | Uppercase alphabetic |
| xdigit | Hexadecimal digit |

 
For example:

 
```
SELECT 'Maria' REGEXP 'Mar[[:alnum:]]*';
+--------------------------------+
| 'Maria' REGEXP 'Mar[:alnum:]*' |
+--------------------------------+
|                              1 |
+--------------------------------+

```

Remember that matches are by default case-insensitive, unless a binary string is used, so the following example, specifically looking for an uppercase, counter-intuitively matches a lowercase character:

 
```
SELECT 'Mari' REGEXP 'Mar[[:upper:]]+';
+---------------------------------+
| 'Mari' REGEXP 'Mar[[:upper:]]+' |
+---------------------------------+
|                               1 |
+---------------------------------+

SELECT BINARY 'Mari' REGEXP 'Mar[[:upper:]]+';
+----------------------------------------+
| BINARY 'Mari' REGEXP 'Mar[[:upper:]]+' |
+----------------------------------------+
|                                      0 |
+----------------------------------------+

```

#### Character Names

 There are also number of shortcuts to match particular preset character names. These are matched with the `[.character.]` pattern (inside a `[]` set). The following character classes exist:

 


| Name | Character |
| --- | --- |
| NUL | 0 |
| SOH | 001 |
| STX | 002 |
| ETX | 003 |
| EOT | 004 |
| ENQ | 005 |
| ACK | 006 |
| BEL | 007 |
| alert | 007 |
| BS | 010 |
| backspace | '\b' |
| HT | 011 |
| tab | '\t' |
| LF | 012 |
| newline | '\n' |
| VT | 013 |
| vertical-tab | '\v' |
| FF | 014 |
| form-feed | '\f' |
| CR | 015 |
| carriage-return | '\r' |
| SO | 016 |
| SI | 017 |
| DLE | 020 |
| DC1 | 021 |
| DC2 | 022 |
| DC3 | 023 |
| DC4 | 024 |
| NAK | 025 |
| SYN | 026 |
| ETB | 027 |
| CAN | 030 |
| EM | 031 |
| SUB | 032 |
| ESC | 033 |
| IS4 | 034 |
| FS | 034 |
| IS3 | 035 |
| GS | 035 |
| IS2 | 036 |
| RS | 036 |
| IS1 | 037 |
| US | 037 |
| space | ' ' |
| exclamation-mark | '!' |
| quotation-mark | '"' |
| number-sign | '#' |
| dollar-sign | '$' |
| percent-sign | '%' |
| ampersand | '&' |
| apostrophe | '\'' |
| left-parenthesis | '(' |
| right-parenthesis | ')' |
| asterisk | '\*' |
| plus-sign | '+' |
| comma | ',' |
| hyphen | '-' |
| hyphen-minus | '-' |
| period | '.' |
| full-stop | '.' |
| slash | '/' |
| solidus | '/' |
| zero | '0' |
| one | '1' |
| two | '2' |
| three | '3' |
| four | '4' |
| five | '5' |
| six | '6' |
| seven | '7' |
| eight | '8' |
| nine | '9' |
| colon | ':' |
| semicolon | ';' |
| less-than-sign | '<' |
| equals-sign | '=' |
| greater-than-sign | '>' |
| question-mark | '?' |
| commercial-at | '@' |
| left-square-bracket | '[' |
| backslash | '' |
| reverse-solidus | '' |
| right-square-bracket | ']' |
| circumflex | '^' |
| circumflex-accent | '^' |
| underscore | '\_' |
| low-line | '\_' |
| grave-accent | '`' |
| left-brace | '{' |
| left-curly-bracket | '{' |
| vertical-line | '|' |
| right-brace | '}' |
| right-curly-bracket | '}' |
| tilde | '' |
| DEL | 177 |

 
For example:

 
```
SELECT '|' REGEXP '[[.vertical-line.]]';
+----------------------------------+
| '|' REGEXP '[[.vertical-line.]]' |
+----------------------------------+
|                                1 |
+----------------------------------+

```

### Combining

 The true power of regular expressions is unleashed when the above is combined, to form more complex examples. Regular expression's reputation for complexity stems from the seeming complexity of multiple combined regular expressions, when in reality, it's simply a matter of understanding the characters and how they apply:

 The first example fails to match, as while the `Ma` matches, either `i` or `r` only matches once before the `ia` characters at the end. 

 
```
SELECT 'Maria' REGEXP 'Ma[ir]{2}ia';
+------------------------------+
| 'Maria' REGEXP 'Ma[ir]{2}ia' |
+------------------------------+
|                            0 |
+------------------------------+

```

This example matches, as either `i` or `r` match exactly twice after the `Ma`, in this case one `r` and one `i`.

 
```
SELECT 'Maria' REGEXP 'Ma[ir]{2}';
+----------------------------+
| 'Maria' REGEXP 'Ma[ir]{2}' |
+----------------------------+
|                          1 |
+----------------------------+

```

### Escaping

 With the large number of special characters, care needs to be taken to properly escape characters. Two backslash characters,  (one for the MariaDB parser, one for the regex library), are required to properly escape a character. For example:

 To match the literal `(Ma`:

 
```
SELECT '(Maria)' REGEXP '(Ma';
ERROR 1139 (42000): Got error 'parentheses not balanced' from regexp

SELECT '(Maria)' REGEXP '\(Ma';
ERROR 1139 (42000): Got error 'parentheses not balanced' from regexp

SELECT '(Maria)' REGEXP '\\(Ma';
+--------------------------+
| '(Maria)' REGEXP '\\(Ma' |
+--------------------------+
|                        1 |
+--------------------------+

```

To match `r+`: The first two examples are incorrect, as they match `r` one or more times, not `r+`:

 
```
SELECT 'Mar+ia' REGEXP 'r+';
+----------------------+
| 'Mar+ia' REGEXP 'r+' |
+----------------------+
|                    1 |
+----------------------+

SELECT 'Maria' REGEXP 'r+';
+---------------------+
| 'Maria' REGEXP 'r+' |
+---------------------+
|                   1 |
+---------------------+

SELECT 'Maria' REGEXP 'r\\+';
+-----------------------+
| 'Maria' REGEXP 'r\\+' |
+-----------------------+
|                     0 |
+-----------------------+

SELECT 'Maria' REGEXP 'r+';
+---------------------+
| 'Maria' REGEXP 'r+' |
+---------------------+
|                   1 |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/regular-expressions-overview/>

STARTPOINT
==========

    A synonym for [ST\_STARTPOINT](../st_startpoint/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring-properties-startpoint/>

ENDPOINT
========

    A synonym for [ST\_ENDPOINT](../st_endpoint/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/linestring-properties-endpoint/>

X
=

    A synonym for [ST\_X](../st_x/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/point-properties-x/>

Full-Text Index Overview
========================

     MariaDB has support for full-text indexing and searching:

 * A full-text index in MariaDB is an index of type FULLTEXT, and it allows more options when searching for portions of text from a field.
* Full-text indexes can be used only with [MyISAM](../myisam/index), [Aria](../aria/index), [InnoDB](../innodb/index) and [Mroonga](../mroonga/index) tables, and can be created only for [CHAR](../char/index), [VARCHAR](../varchar/index), or [TEXT](../text/index) columns.
* [Partitioned tables](../managing-mariadb-partitioning/index) cannot contain fulltext indexes, even if the storage engine supports them.
* A FULLTEXT index definition can be given in the [CREATE TABLE](../create-table/index) statement when a table is created, or added later using [ALTER TABLE](../alter-table/index) or [CREATE INDEX](../create-index/index).
* For large data sets, it is much faster to load your data into a table that has no FULLTEXT index and then create the index after that, than to load data into a table that has an existing FULLTEXT index.

 Full-text searching is performed using [MATCH() ... AGAINST](../match-against/index) syntax. MATCH() takes a comma-separated list that names the columns to be searched. AGAINST takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a literal string, not a variable or a column name.

 
```
MATCH (col1,col2,...) AGAINST (expr [search_modifier])

```

Excluded Results
----------------

 * Partial words are excluded.
* Words less than 4 (MyISAM) or 3 (InnoDB) characters in length will not be stored in the fulltext index. This value can be adjusted by changing the [ft\_min\_word\_length](../server-system-variables/index#ft_min_word_len) system variable (or, for [InnoDB](../innodb/index), [innodb\_ft\_min\_token\_size](../innodb-system-variables/index#innodb_ft_min_token_size)).
* Words longer than 84 characters in length will also not be stored in the fulltext index. This values can be adjusted by changing the [ft\_max\_word\_length](../server-system-variables/index#ft_max_word_len) system variable (or, for [InnoDB](../innodb/index), [innodb\_ft\_max\_token\_size](../xtradbinnodb-server-system-variables/index#innodb_ft_max_token_size)).
* Stopwords are a list of common words such as "once" or "then" that do not reflect in the search results unless IN BOOLEAN MODE is used. The stopword list for MyISAM/Aria tables and InnoDB tables can differ. See [stopwords](../stopwords/index) for details and a full list, as well as for details on how to change the default list.
* For MyISAM/Aria fulltext indexes only, if a word appears in more than half the rows, it is also excluded from the results of a fulltext search.
* For InnoDB indexes, only committed rows appear - modifications from the current transaction do not apply.

 Relevance
---------

 MariaDB calculates a relevance for each result, based on a number of factors, including the number of words in the index, the number of unique words in a row, the total number of words in both the index and the result, and the weight of the word. In English, 'cool' will be weighted less than 'dandy', at least at present! The relevance can be returned as part of a query simply by using the MATCH function in the field list.

 Types of Full-Text search
-------------------------

 ### IN NATURAL LANGUAGE MODE

 IN NATURAL LANGUAGE MODE is the default type of full-text search, and the keywords can be omitted. There are no special operators, and searches consist of one or more comma-separated keywords.

 Searches are returned in descending order of relevance.

 ### IN BOOLEAN MODE

 Boolean search permits the use of a number of special operators:

 


| Operator | Description |
| --- | --- |
| + | The word is mandatory in all rows returned. |
| - | The word cannot appear in any row returned. |
| < | The word that follows has a lower relevance than other words, although rows containing it will still match |
| > | The word that follows has a higher relevance than other words. |
| () | Used to group words into subexpressions. |
| ~ | The word following contributes negatively to the relevance of the row (which is different to the '-' operator, which specifically excludes the word, or the '<' operator, which still causes the word to contribute positively to the relevance of the row. |
| \* | The wildcard, indicating zero or more characters. It can only appear at the end of a word. |
| " | Anything enclosed in the double quotes is taken as a whole (so you can match phrases, for example). |

 
Searches are not returned in order of relevance, and nor does the 50% limit apply. Stopwords and word minimum and maximum lengths still apply as usual.

 ### WITH QUERY EXPANSION

 A query expansion search is a modification of a natural language search. The search string is used to perform a regular natural language search. Then, words from the most relevant rows returned by the search are added to the search string and the search is done again. The query returns the rows from the second search. The IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION or WITH QUERY EXPANSION modifier specifies a query expansion search. It can be useful when relying on implied knowledge within the data, for example that MariaDB is a database.

 Examples
--------

 Creating a table, and performing a basic search:

 
```
CREATE TABLE ft_myisam(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM;

INSERT INTO ft_myisam(copy) VALUES ('Once upon a time'),
  ('There was a wicked witch'), ('Who ate everybody up');

SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked');
+--------------------------+
| copy                     |
+--------------------------+
| There was a wicked witch |
+--------------------------+

```

Multiple words:

 
```
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked,witch');
+---------------------------------+
| copy                            |
+---------------------------------+
| There was a wicked witch        |
+---------------------------------+

```

Since 'Once' is a [stopword](../stopwords/index), no result is returned:

 
```
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('Once');
Empty set (0.00 sec)

```

Inserting the word 'wicked' into more than half the rows excludes it from the results:

 
```
INSERT INTO ft_myisam(copy) VALUES ('Once upon a wicked time'),
  ('There was a wicked wicked witch'), ('Who ate everybody wicked up');

SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked');
Empty set (0.00 sec)

```

Using IN BOOLEAN MODE to overcome the 50% limitation:

 
```
SELECT * FROM ft_myisam WHERE MATCH(copy) AGAINST('wicked' IN BOOLEAN MODE);
+---------------------------------+
| copy                            |
+---------------------------------+
| There was a wicked witch        |
| Once upon a wicked time         |
| There was a wicked wicked witch |
| Who ate everybody wicked up     |
+---------------------------------+

```

Returning the relevance:

 
```
SELECT copy,MATCH(copy) AGAINST('witch') AS relevance 
  FROM ft_myisam WHERE MATCH(copy) AGAINST('witch');
+---------------------------------+--------------------+
| copy                            | relevance          |
+---------------------------------+--------------------+
| There was a wicked witch        | 0.6775632500648499 |
| There was a wicked wicked witch | 0.5031757950782776 |
+---------------------------------+--------------------+

```

WITH QUERY EXPANSION. In the following example, 'MariaDB' is always associated with the word 'database', so it is returned when query expansion is used, even though not explicitly requested.

 
```
CREATE TABLE ft2(copy TEXT,FULLTEXT(copy)) ENGINE=MyISAM;

INSERT INTO ft2(copy) VALUES
 ('MySQL vs MariaDB database'),
 ('Oracle vs MariaDB database'), 
 ('PostgreSQL vs MariaDB database'),
 ('MariaDB overview'),
 ('Foreign keys'),
 ('Primary keys'),
 ('Indexes'),
 ('Transactions'),
 ('Triggers');

SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database');
+--------------------------------+
| copy                           |
+--------------------------------+
| MySQL vs MariaDB database      |
| Oracle vs MariaDB database     |
| PostgreSQL vs MariaDB database |
+--------------------------------+
3 rows in set (0.00 sec)

SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('database' WITH QUERY EXPANSION);
+--------------------------------+
| copy                           |
+--------------------------------+
| MySQL vs MariaDB database      |
| Oracle vs MariaDB database     |
| PostgreSQL vs MariaDB database |
| MariaDB overview               |
+--------------------------------+
4 rows in set (0.00 sec)

```

Partial word matching with IN BOOLEAN MODE:

 
```
SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('Maria*' IN BOOLEAN MODE);
+--------------------------------+
| copy                           |
+--------------------------------+
| MySQL vs MariaDB database      |
| Oracle vs MariaDB database     |
| PostgreSQL vs MariaDB database |
| MariaDB overview               |
+--------------------------------+

```

Using boolean operators

 
```
SELECT * FROM ft2 WHERE MATCH(copy) AGAINST('+MariaDB -database' 
  IN BOOLEAN MODE);
+------------------+
| copy             |
+------------------+
| MariaDB overview |
+------------------+

```

See Also
--------

 * For simpler searches of a substring in text columns, see the [LIKE](../like/index) operator.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/full-text-index-overview/>

Information Schema INNODB\_FT\_DEFAULT\_STOPWORD Table
======================================================

    The [Information Schema](../information_schema/index) `INNODB_FT_DEFAULT_STOPWORD` table contains a list of default [stopwords](../stopwords/index) used when creating an InnoDB [fulltext index](../full-text-indexes/index).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following column:

 


| Column | Description |
| --- | --- |
| `VALUE` | Default `[stopword](../stopwords/index)` for an InnoDB [fulltext index](../full-text-indexes/index). Setting either the [innodb\_ft\_server\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_server_stopword_table) or the [innodb\_ft\_user\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_user_stopword_table) system variable will override this. |

 
Example
-------

 
```
SELECT * FROM information_schema.INNODB_FT_DEFAULT_STOPWORD\G
*************************** 1. row ***************************
value: a
*************************** 2. row ***************************
value: about
*************************** 3. row ***************************
value: an
*************************** 4. row ***************************
value: are
...
*************************** 36. row ***************************
value: www

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_default_stopword-table/>

Performance Schema setup\_consumers Table
=========================================

    Lists the types of consumers for which event information is available.

 The `setup_consumers` table contains the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Consumer name |
| `ENABLED` | `YES` or `NO` for whether or not the consumer is enabled. You can modify this column to ensure that event information is added, or is not added. |

 
The table can be modified directly, or the server started with the option enabled, for example:

 
```
performance-schema-consumer-events-waits-history=ON

```

Example
-------

 
```
SELECT * FROM performance_schema.setup_consumers;

+--------------------------------+---------+
| NAME                           | ENABLED |
+--------------------------------+---------+
| events_stages_current          | NO      |
| events_stages_history          | NO      |
| events_stages_history_long     | NO      |
| events_statements_current      | YES     |
| events_statements_history      | NO      |
| events_statements_history_long | NO      |
| events_waits_current           | NO      |
| events_waits_history           | NO      |
| events_waits_history_long      | NO      |
| global_instrumentation         | YES     |
| thread_instrumentation         | YES     |
| statements_digest              | YES     |
+--------------------------------+---------+

```

See Also
--------

 * [Sys Schema ps\_is\_consumer\_enabled function](../ps_is_consumer_enabled/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-setup_consumers-table/>

Y
=

    A synonym for [ST\_Y](../st_y/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/point-properties-y/>

Performance Schema events\_transactions\_current Table
======================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_current table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_current` table contains current transaction events for each thread. 

 The table size cannot be figured, and always stores one row for each thread, showing the current status of the thread's most recent monitored transaction event.

 The table contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| THREAD\_ID | bigint(20) unsigned | The thread associated with the event. |
| EVENT\_ID | bigint(20) unsigned | The event id associated with the event. |
| END\_EVENT\_ID | bigint(20) unsigned | This column is set to NULL when the event starts and updated to the thread current event number when the event ends. |
| EVENT\_NAME | varchar(128) | The name of the instrument from which the event was collected. This is a NAME value from the setup\_instruments table. |
| STATE | enum('ACTIVE', 'COMMITTED', 'ROLLED BACK') | The current transaction state. The value is ACTIVE (after START TRANSACTION or BEGIN), COMMITTED (after COMMIT), or ROLLED BACK (after ROLLBACK). |
| TRX\_ID | bigint(20) unsigned | Unused. |
| GTID | varchar(64) | Transaction [GTID](../gtid/index), using the format DOMAIN-SERVER\_ID-SEQUENCE\_NO. |
| XID\_FORMAT\_ID | int(11) | XA transaction format ID for GTRID and BQUAL values. |
| XID\_GTRID | varchar(130) | XA global transaction ID. |
| XID\_BQUAL | varchar(130) | XA transaction branch qualifier. |
| XA\_STATE | varchar(64) | The state of the XA transaction. The value is ACTIVE (after XA START), IDLE (after XA END), PREPARED (after XA PREPARE), ROLLED BACK (after XA ROLLBACK), or COMMITTED (after XA COMMIT). |
| SOURCE | varchar(64) | The name of the source file containing the instrumented code that produced the event and the line number in the file at which the instrumentation occurs. |
| TIMER\_START | bigint(20) unsigned | The unit is picoseconds. When event timing started. NULL if event has no timing information. |
| TIMER\_END | bigint(20) unsigned | The unit is picoseconds. When event timing ended. NULL if event has no timing information. |
| TIMER\_WAIT | bigint(20) unsigned | The unit is picoseconds. Event duration. NULL if event has not timing information. |
| ACCESS\_MODE | enum('READ ONLY', 'READ WRITE') | Transaction access mode. |
| ISOLATION\_LEVEL | varchar(64) | Transaction isolation level. One of: REPEATABLE READ, READ COMMITTED, READ UNCOMMITTED, or SERIALIZABLE. |
| AUTOCOMMIT | enum('YES','NO') | Whether autcommit mode was enabled when the transaction started. |
| NUMBER\_OF\_SAVEPOINTS | bigint(20) unsigned | The number of SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_ROLLBACK\_TO\_SAVEPOINT | bigint(20) unsigned | The number of ROLLBACK\_TO\_SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_RELEASE\_SAVEPOINT | bigint(20) unsigned | The number of RELEASE\_SAVEPOINT statements issued during the transaction. |
| OBJECT\_INSTANCE\_BEGIN | bigint(20) unsigned | Unused. |
| NESTING\_EVENT\_ID | bigint(20) unsigned | The EVENT\_ID value of the event within which this event is nested. |
| NESTING\_EVENT\_TYPE | enum('TRANSACTION', 'STATEMENT', 'STAGE', 'WAIT') | The nesting event type. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_current-table/>

Sys Schema sys\_config Table
============================

    
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**The Sys Schema *sys\_config* table was added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). The *sys\_config* table is also backported to [MariaDB-10.5-enterprise](https://mariadb.com/docs/server/whats-new/prior-series/mariadb-enterprise-server-10-5/).

 
The *sys.sys\_config* table holds configuration options for the [Sys Schema](../sys-schema/index).

 This is a persistent table (using the [Aria](../aria/index) storage engine), with the configuration persisting across upgrades (new options are added with [INSERT IGNORE](../insert-ignore/index).

 The table also has two related triggers, which maintain the user that INSERTs or UPDATEs the configuration - sys\_config\_insert\_set\_user and sys\_config\_update\_set\_user respectively.

 Its structure is as follows:

 
```
+----------+--------------+------+-----+-------------------+-----------------------------+
| Field    | Type         | Null | Key | Default           | Extra                       |
+----------+--------------+------+-----+-------------------+-----------------------------+
| variable | varchar(128) | NO   | PRI | NULL              |                             |
| value    | varchar(128) | YES  |     | NULL              |                             |
| set_time | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| set_by   | varchar(128) | YES  |     | NULL              |                             |
+----------+--------------+------+-----+-------------------+-----------------------------+

```

Note, when functions check for configuration options, they first check whether a similar named user variable exists with a value, and if this is not set then pull the configuration option from this table in to that named user variable. This is done for performance reasons (to not continually SELECT from the table), however this comes with the side effect that once inited, the values last with the session, somewhat like how session variables are inited from global variables. If the values within this table are changed, they will not take effect until the user logs in again.

 ### Options Included

 


| Variable | Default Value | Description |
| --- | --- | --- |
| statement\_truncate\_len | 64 | Sets the size to truncate statements to, for the [format\_statement](../format_statement/index) function. |
| statement\_performance\_analyzer.limit | 100 | The maximum number of rows to include for the views that does not have a built-in limit (e.g. the 95th percentile view). If not set the limit is 100. |
| statement\_performance\_analyzer.view | NULL | Used together with the 'custom' view. If the value contains a space, it is considered a query, otherwise it must be an existing view querying the performance\_schema.events\_statements\_summary\_by\_digest table. |
| diagnostics.allow\_i\_s\_tables | OFF | Specifies whether it is allowed to do table scan queries on information\_schema.TABLES for the diagnostics procedure. |
| diagnostics.include\_raw | OFF | Set to 'ON' to include the raw data (e.g. the original output of "SELECT \* FROM sys.metrics") for the diagnostics procedure. |
| ps\_thread\_trx\_info.max\_length | 65535 | Sets the maximum output length for JSON object output by the ps\_thread\_trx\_info() function. |

 
### Notes

 Some early versions of *sys\_config* were stored in [InnoDB](../innodb/index) format.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys-schema-sys_config-table/>

Sys Schema Stored Functions
============================

   The following [stored functions](../stored-functions/index) are available in the [Sys Schema](../sys-schema/index).

  

| Title | Description |
| --- | --- |
|  [extract\_schema\_from\_file\_name](../extract_schema_from_file_name/index) |  Returns the schema (database) name.  |
|  [extract\_table\_from\_file\_name](../extract_table_from_file_name/index) |  Returns the table name from the provided path.  |
|  [format\_bytes](../format_bytes/index) |  Returns a string consisting of a value and the units in a human-readable format.  |
|  [format\_path](../format_path/index) |  Returns a modified path, replacing subpaths matching the values of various system variables.  |
|  [format\_statement](../format_statement/index) |  Returns a reduced length string.  |
|  [format\_time](../format_time/index) |  Given a time in picoseconds, returns a human-readable time and unit.  |
|  [list\_add](../list_add/index) |  Takes a list to be be modified and a value to be added to the list, returning the resulting value.  |
|  [list\_drop](../list_drop/index) |  Takes a list to be be modified and a value to be dropped, returning the resulting value.  |
|  [ps\_is\_account\_enabled](../ps_is_account_enabled/index) |  Whether or not Performance Schema instrumentation for a given account is enabled.  |
|  [ps\_is\_consumer\_enabled](../ps_is_consumer_enabled/index) |  Whether or not Performance Schema instrumentation for a given consumer is enabled.  |
|  [ps\_is\_instrument\_default\_enabled](../ps_is_instrument_default_enabled/index) |  Whether or not a Performance Schema instrument is enabled by default.  |
|  [ps\_is\_instrument\_default\_timed](../ps_is_instrument_default_timed/index) |  Whether or not a Performance Schema instrument is timed by default.  |
|  [ps\_is\_thread\_instrumented](../ps_is_thread_instrumented/index) |  Whether or not instrumentation for a given connection\_id is enabled.  |
|  [ps\_thread\_account](../ps_thread_account/index) |  Returns the account associated with the given thread\_id.  |
|  [ps\_thread\_id](../ps_thread_id/index) |  Returns the thread\_id associated with the given connection\_id.  |
|  [ps\_thread\_stack](../ps_thread_stack/index) |  Returns statements, stages, events within the Performance Schema for a given thread\_id.  |
|  [ps\_thread\_trx\_info](../ps_thread_trx_info/index) |  Returns a JSON object with information about the thread specified by the given thread\_id.  |
|  [quote\_identifier](../quote_identifier/index) |  Returns quoted, properly escaped identifier.  |
|  [sys\_get\_config](../sys_get_config/index) |  Returns a configuration option value from the sys\_config table.  |
|  [version\_major](../version_major/index) |  Returns the MariaDB Server major release version.  |
|  [version\_minor](../version_minor/index) |  Returns the MariaDB Server minor release version.  |
|  [version\_patch](../version_patch/index) |  MariaDB Server patch release version.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys-schema-stored-functions/>

HandlerSocket Client Libraries
==============================

    In order to make use of the [HandlerSocket](../handlersocket/index) plugin in your applications, you will need to use the appropriate client library. The following client libraries are available:

 * C++
	+ [libhsclient](https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL) *(included with the HandlerSocket plugin source)*
* Perl
	+ [perl-Net-HandlerSocket](https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL) *(included with the HandlerSocket plugin source)*
* PHP
	+ [Net\_HandlerSocket](https://github.com/openpear/Net_HandlerSocket)
	+ [HSPHP](http://github.com/tz-lom/HSPHP)
	+ [php-ext-handlersocketi](https://github.com/kjdev/php-ext-handlersocketi)
* Java
	+ [hs4j](http://code.google.com/p/hs4j/)
	+ [handlersocketforjava](http://code.google.com/p/handlersocketforjava/)
* Python
	+ [python-handler-socket](http://pypi.python.org/pypi/python-handler-socket)
	+ [pyhandlersocket](https://code.launchpad.net/~songofacandy/+junk/pyhandlersocket)
* Ruby
	+ [ruby-handlersocket](https://github.com/winebarrel/ruby-handlersocket)
	+ [handlersocket](https://github.com/miyucy/handlersocket)
* JavaScript
	+ [node-handlersocket](https://github.com/koichik/node-handlersocket)
* Scala
	+ [hs2client](https://github.com/fujohnwang/hs2client)
* Haskell
	+ <https://github.com/wuxb45/HandlerSocket-Haskell-Client>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handlersocket-client-libraries/>

Testing HandlerSocket in a Source Distribution
==============================================

    [MariaDB 5.5](../what-is-mariadb-55/index)
------------------------------------------

 In [MariaDB 5.5](../what-is-mariadb-55/index), which is built using `cmake`, `Makefile.PL` is not generated automatically. If you want to run the perl tests, you will need to create it manually from `Makefile.PL.in`. It is fairly easy to do by replacing `LIB` and `INC` values with the correct ones. Also, `libhsclient.so` is not built by default; `libhsclient.a` can be found in `plugin/handler_socket` folder. 

 [MariaDB 5.3](../what-is-mariadb-53/index)
------------------------------------------

 If you want to test or use handlersocket with a source installation of [MariaDB 5.3](../what-is-mariadb-53/index), here is one way to do this:

 1. Compile with one of the build scripts that has the `-max` option, like `BUILD/compile-pentium64-max` or `BUILD/compile-pentium64-debug-max`
2. Start mysqld with the test framework
```
cd mysql-test
LD_LIBRARY_PATH=../plugin/handler_socket/libhsclient/.libs \
MTR_VERSION=1 perl mysql-test-run.pl --start-and-exit 1st \
--mysqld=--plugin-dir=../plugin/handler_socket/handlersocket/.libs \
--mysqld=--loose-handlersocket_port=9998 \
--mysqld=--loose-handlersocket_port_wr=9999 \
--master_port=9306 --mysqld=--innodb

```
3. This will end with:
```
Servers started, exiting

```
4. Load handlersocket
```
client/mysql -uroot --protocol=tcp --port=9306 \
-e 'INSTALL PLUGIN handlersocket soname "handlersocket.so"'

```
5. Configure and compile the handlersocket perl module
```
cd plugin/handler_socket/perl-Net-HandlerSocket
perl Makefile.PL
make

```
6. If you would like to install the handlersocket perl module permanently, you should do:
```
make install

```
 If you do this, you don't have to set `PERL5LIB` below.
7. Run the handlersocket test suite
```
cd plugin/handler_socket/regtest/test_01_lib
MYHOST=127.0.0.1 MYPORT=9306 LD_LIBRARY_PATH=../../libhsclient/.libs/ \
PERL5LIB=../common:../../perl-Net-HandlerSocket/lib:../../perl-Net-HandlerSocket/blib/arch/auto/Net/HandlerSocket/ ./run.sh

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/testing-handlersocket-in-a-source-distribution/>

HandlerSocket Installation
==========================

    After MariaDB is installed, use the [INSTALL PLUGIN](../install-plugin/index) command (as the root user) to install the HandlerSocket plugin. This command only needs to be run once, like so:

 
```
INSTALL PLUGIN handlersocket SONAME 'handlersocket.so';

```

After installing the plugin, [SHOW PROCESSLIST](../show-processlist/index) you first need to configure some settings. All [HandlerSocket configuration options](../handlersocket-configuration-options/index) are placed in the [mysqld] section of your my.cnf file.

 At least the [handlersocket\_address](../handlersocket-configuration-options/index#handlersocket_address), [handlersocket\_port](../handlersocket-configuration-options/index#handlersocket_port) and [handlersocket\_port\_wr](../handlersocket-configuration-options/index#handlersocket_port_wr) options need to be set. For example:

 
```
handlersocket_address="127.0.0.1"
handlersocket_port="9998"
handlersocket_port_wr="9999"

```

After updating the configuration options, restart MariaDB.

 On the client side, to make use of the plugin you will need to install the appropriate client library (i.e. libhsclient for C++ applications and perl-Net-HandlerSocket for perl applications).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handlersocket-installation/>

Thread Pool in MariaDB 5.1 - 5.3
================================

     This article describes the old thread pool in [MariaDB 5.1](../what-is-mariadb-51/index) - 5.3.

 [MariaDB 5.5](../what-is-mariadb-55/index) and later use an improved thread pool - see [Thread pool in MariaDB](../thread-pool-in-mariadb/index).

 About pool of threads
---------------------

 This is an extended version of the pool-of-threads code from MySQL 6.0. This allows you to use a limited set of threads to handle all queries, instead of the old 'one-thread-per-connection' style. In recent times, its also been referred to as "thread pool" or "thread pooling" as this feature (in a different implementation) is available in Enterprise editions of MySQL (not in the Community edition).

 This can be a very big win if most of your queries are short running queries and there are few table/row locks in your system.

 Instructions
------------

 To enable pool-of-threads you must first run configure with the `--with-libevent` option. (This is automatically done if you use any 'max' scripts in the BUILD directory):

 
```
./configure --with-libevent

```

When starting mysqld with the pool of threads code you should use

 
```
mysqld --thread-handling=pool-of-threads --thread-pool-size=20

```

Default values are:

 
```
thread-handling=  one-thread-per-connection
thread-pool-size= 20

```

One issue with pool-of-threads is that if all worker threads are doing work (like running long queries) or are locked by a row/table lock no new connections can be established and you can't login and find out what's wrong or login and kill queries.

 To help this, we have introduced two new options for mysqld; [extra\_port](../thread-pool-system-and-status-variables/index#extra_port) and [extra\_max\_connections](../thread-pool-system-and-status-variables/index#extra_max_connections):

 
```
--extra-port=#             (Default 0)
--extra-max-connections=#  (Default 1)

```

If [extra-port](../thread-pool-system-and-status-variables/index#extra_port) is <> 0 then you can connect max\_connections number of normal threads + 1 extra SUPER user through the 'extra-port' TCP/IP port. These connections use the old one-thread-per-connection method.

 To connect with through the extra port, use:

 
```
mysql --port='number-of-extra-port' --protocol=tcp

```

This allows you to freely use, on connection bases, the optimal connection/thread model.

 See also
--------

 * [Thread-handling and thread-pool-size variables](../thread-pool-system-and-status-variables/index)
* [How MySQL Uses Threads for Client Connections](http://dev.mysql.com/doc/refman/5.6/en/connection-threads.html)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-pool-in-mariadb-51-53/>

HandlerSocket External Resources
================================

    Some resources and documentation about HandlerSocket.

 * The home of HandlerSocket is [here](https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL).
* The story of handlersocket can be found [here](http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html).
* Comparison of [HANDLER](../handler/index) and HandlerSocket can be found [here](http://varokism.blogspot.com/2010/12/using-mysql-as-nosql-story-for_27.html).
* [HandlerSocket plugin for MySQL](http://www.slideshare.net/akirahiguchi/handlersocket-20100629en-5698215) presentation by Akira Higuchi of DeNA - June 29 2010 - DeNA Technology Seminar
* [HandlerSocket plugin for MySQL](http://www.slideshare.net/akirahiguchi/handlersocket-plugin-for-mysql-4664154) presentation by Akira Higuchi of DeNA - June 29 2011 - in Japanese

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handlersocket-external-resources/>

Thread Groups in the Unix Implementation of the Thread Pool
===========================================================

    
This article does not apply to the thread pool implementation on Windows. On Windows, MariaDB uses a native thread pool created with the `[CreateThreadpool](https://docs.microsoft.com/en-us/windows/desktop/api/threadpoolapiset/nf-threadpoolapiset-createthreadpool)` APl, which has its own methods to distribute threads between CPUs.

  On Unix, the thread pool implementation uses objects called thread groups to divide up client connections into many independent sets of threads. The `[thread\_pool\_size](../thread-pool-system-status-variables/index#thread_pool_size)` system variable defines the number of thread groups on a system. Generally speaking, the goal of the thread group implementation is to have one running thread on each CPU on the system at a time. Therefore, the default value of the `[thread\_pool\_size](../thread-pool-system-status-variables/index#thread_pool_size)` system variable is auto-sized to the number of CPUs on the system.

 When setting the `[thread\_pool\_size](../thread-pool-system-status-variables/index#thread_pool_size)` system variable's value at system startup, the max value is `100000`. However, it is not a good idea to set it that high. When setting its value dynamically, the max value is either `128` or the value that was set at system startup--whichever value is higher. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL thread_pool_size=32;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
..
thread_handling=pool-of-threads
thread_pool_size=32

```

If you do not want MariaDB to use all CPUs on the system for some reason, then you can set it to a lower value than the number of CPUs. For example, this would make sense if the MariaDB Server process is limited to certain CPUs with the `[taskset](https://linux.die.net/man/1/taskset)` utility on Linux.

 If you set the value to the number of CPUs and if you find that the CPUs are still underutilized, then try increasing the value.

 The `[thread\_pool\_size](../thread-pool-system-status-variables/index#thread_pool_size)` system variable tends to have the most visible performance effect. It is roughly equivalent to the number of threads that can run at the same time. In this case, run means use CPU, rather than sleep or wait. If a client connection needs to sleep or wait for some reason, then it wakes up another client connection in the thread group before it does so.

 
One reason that CPU underutilization may occur in rare cases is that the thread pool is not always informed when a thread is going to wait. For example, some waits, such as a page fault or a miss in the OS buffer cache, cannot be detected by MariaDB. Prior to [MariaDB 10.0](../what-is-mariadb-100/index), network I/O related waits could also be missed.

 
Distributing Client Connections Between Thread Groups
-----------------------------------------------------

 When a new client connection is created, its thread group is determined using the following calculation:

 
```
thread_group_id = connection_id %  thread_pool_size

```

The `connection_id` value in the above calculation is the same monotonically increasing number that you can use to identify connections in `[SHOW PROCESSLIST](../show-processlist/index)` output or the `[information\_schema.PROCESSLIST](../information-schema-processlist-table/index)` table.

 This calculation should assign client connections to each thread group in a round-robin manner. In general, this should result in an even distribution of client connections among thread groups.

 Types of Threads
----------------

 ### Thread Group Threads

 Thread groups have two different kinds of threads: a **listener thread** and **worker threads**.

 * A thread group's **worker threads** actually perform work on behalf of client connections. A thread group can have many **worker threads**, but usually, only one will be actively running at a time. This is not always the case. For example, the thread group can become *oversubscribed* if the thread pool's **timer thread** detects that the thread group is *stalled*. This is explained more in the sections below.

 * A thread group's **listener thread** listens for I/O events and distributes work to the **worker threads**. If it detects that there is a request that needs to be worked on, then it can wake up a sleeping **worker thread** in the thread group, if any exist. If the **listener thread** is the only thread in the thread group, then it can also create a new **worker thread**. If there is only one request to handle, and if the `[thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener)` system variable is not enabled, then the **listener thread** can also become a **worker thread** and handle the request itself. This helps decrease the overhead that may be introduced by excessively waking up sleeping **worker threads** and excessively creating new **worker threads**.

 ### Global Threads

 The thread pool has one global thread: a **timer thread**. The **timer thread** performs tasks, such as:

 * Checks each thread group for stalls.
* Ensures that each thread group has a **listener thread**.

 Thread Creation
---------------

 A new thread is created in a thread group in the scenarios listed below.

 In all of the scenarios below, the thread pool implementation prefers to wake up a sleeping **worker thread** that already exists in the thread group, rather than to create a new thread.

 ### Worker Thread Creation by Listener Thread

 A thread group's **listener thread** can create a new **worker thread** when it has more client connection requests to distribute, but no pre-existing **worker threads** are available to work on the requests. This can help to ensure that the thread group always has enough threads to keep one **worker thread** active at a time.

 A thread group's **listener thread** creates a new **worker thread** if all of the following conditions are met:

 * The **listener thread** receives a client connection request that needs to be worked on.
* There are more client connection requests in the thread group's work queue that the **listener thread** still needs to distribute to **worker threads**, so the **listener thread** should not become a **worker thread**.
* There are no active **worker threads** in the thread group.
* There are no sleeping **worker threads** in the thread group that the **listener thread** can wake up.
* And one of the following conditions is also met:
	+ The entire thread pool has fewer than `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)`.
	+ There are fewer than two threads in the thread group. This is to guarantee that each thread group can have at least two threads, even if `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)` has already been reached or exceeded.

 ### Thread Creation by Worker Threads during Waits

 A thread group's **worker thread** can create a new **worker thread** when the thread has to wait on something, and the thread group has more client connection requests queued, but no pre-existing **worker threads** are available to work on them. This can help to ensure that the thread group always has enough threads to keep one **worker thread** active at a time. For most workloads, this tends to be the primary mechanism that creates new **worker threads**.

 A thread group's **worker thread** creates a new thread if all of the following conditions are met:

 * The **worker thread** has to wait on some request. For example, it might be waiting on disk I/O, or it might be waiting on a lock, or it might just be waiting for a query that called the `[SLEEP()](../sleep/index)` function to finish.
* There are no active **worker threads** in the thread group.
* There are no sleeping **worker threads** in the thread group that the **worker thread** can wake up.
* And one of the following conditions is also met:
	+ The entire thread pool has fewer than `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)`.
	+ There are fewer than two threads in the thread group. This is to guarantee that each thread group can have at least two threads, even if `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)` has already been reached or exceeded.
* And one of the following conditions is also met:
	+ There are more client connection requests in the thread group's work queue that the **listener thread** still needs to distribute to **worker threads**. In this case, the new thread is intended to be a **worker thread**.
	+ There is currently no **listener thread** in the thread group. For example, if the `[thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener)` system variable is not enabled, then the thread group's **listener thread** can became a **worker thread**, so that it could handle some client connection request. In this case, the new thread can become the thread group's **listener thread**.

 ### Listener Thread Creation by Timer Thread

 The thread pool's **timer thread** can create a new **listener thread** for a thread group when the thread group has more client connection requests that need to be distributed, but the thread group does not currently have a **listener thread** to distribute them. This can help to ensure that the thread group does not miss client connection requests because it has no **listener thread**.

 The thread pool's **timer thread** creates a new **listener thread** for a thread group if all of the following conditions are met:

 * The thread group has not handled any I/O events since the last check by the timer thread.
* There is currently no **listener thread** in the thread group. For example, if the `[thread\_pool\_dedicated\_listener](../thread-pool-system-status-variables/index#thread_pool_dedicated_listener)` system variable is not enabled, then the thread group's **listener thread** can became a **worker thread**, so that it could handle some client connection request. In this case, the new thread can become the thread group's **listener thread**.
* There are no sleeping **worker threads** in the thread group that the **timer thread** can wake up.
* And one of the following conditions is also met:
	+ The entire thread pool has fewer than `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)`.
	+ There are fewer than two threads in the thread group. This is to guarantee that each thread group can have at least two threads, even if `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)` has already been reached or exceeded.
* If the thread group already has active **worker threads**, then the following condition also needs to be met:
	+ A **worker thread** has not been created for the thread group within the *throttling interval*.

 ### Worker Thread Creation by Timer Thread during Stalls

 The thread pool's **timer thread** can create a new **worker thread** for a thread group when the thread group is stalled. This can help to ensure that a long query can't monopole its thread group.

 The thread pool's **timer thread** creates a new **worker thread** for a thread group if all of the following conditions are met:

 * The **timer thread** thinks that the thread group is stalled. This means that the following conditions have been met:
	+ There are more client connection requests in the thread group's work queue that the **listener thread** still needs to distribute to **worker threads**.
	+ No client connection requests have been allowed to be dequeued to run since the last stall check by the **timer thread**.
* There are no sleeping **worker threads** in the thread group that the **timer thread** can wake up.
* And one of the following conditions is also met:
	+ The entire thread pool has fewer than `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)`.
	+ There are fewer than two threads in the thread group. This is to guarantee that each thread group can have at least two threads, even if `[thread\_pool\_max\_threads](../thread-pool-system-status-variables/index#thread_pool_max_threads)` has already been reached or exceeded.
* A **worker thread** has not been created for the thread group within the *throttling interval*.

 ### Thread Creation Throttling

 In some of the scenarios listed above, a thread is only created within a thread group if no new threads have been created for the thread group within the *throttling interval*. The throttling interval depends on the number of threads that are already in the thread group.

 
**MariaDB starting with [10.5](../what-is-mariadb-105/index)**In [MariaDB 10.5](../what-is-mariadb-105/index) and later, thread creation is not throttled until a thread group has more than 1 + `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)` threads:

 


| Number of Threads in Thread Group | Throttling Interval (milliseconds) |
| --- | --- |
| 0-(1 + `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)`) | 0 |
| 4-7 | 50 \* `THROTTLING_FACTOR` |
| 8-15 | 100 \* `THROTTLING_FACTOR` |
| 16-65536 | 20 \* `THROTTLING_FACTOR` |

 
`THROTTLING_FACTOR = ([thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit) / MAX (500,[thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit)))`

 

**MariaDB until [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and before, thread creation is throttled when a thread group has more than 3 threads:

 


| Number of Threads in Thread Group | Throttling Interval (milliseconds) |
| --- | --- |
| 0-3 | 0 |
| 4-7 | 50 |
| 8-15 | 100 |
| 16-65536 | 200 |

 

Thread Group Stalls
-------------------

 The thread pool has a feature that allows it to detect if a client connection is executing a long-running query that may be monopolizing its thread group. If a client connection were to monopolize its thread group, then that could prevent other client connections in the thread group from running their queries. In other words, the thread group would appear to be *stalled*.

 This stall detection feature is implemented by creating a **timer thread** that periodically checks if any of the thread groups are stalled. There is only a single **timer thread** for the entire thread pool. The `[thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit)` system variable defines the number of milliseconds between each stall check performed by the timer thread. The default value is `500`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL thread_pool_stall_limit=300;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
..
thread_handling=pool-of-threads
thread_pool_size=32
thread_pool_stall_limit=300

```

The **timer thread** considers a thread group to be stalled if the following is true:

 * There are more client connection requests in the thread group's work queue that the **listener thread** still needs to distribute to **worker threads**.
* No client connection requests have been allowed to be dequeued to run since the last stall check by the **timer thread**.

 This indicates that the one or more client connections currently using the active **worker threads** may be monopolizing the thread group, and preventing the queued client connections from performing work. When the **timer thread** detects that a thread group is stalled, it wakes up a sleeping **worker thread** in the thread group, if one is available. If there isn't one, then it creates a new **worker thread** in the thread group. This temporarily allows several client connections in the thread group to run in parallel.

 
The `[thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit)` system variable essentially defines the limit for what a "fast query" is. If a query takes longer than `[thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit)`, then the thread pool is likely to think that it is too slow, and it will either wake up a sleeping worker thread or create a new worker thread to let another client connection in the thread group run a query in parallel.

 
In general, changing the value of the `[thread\_pool\_stall\_limit](../thread-pool-system-status-variables/index#thread_pool_stall_limit)` system variable has the following effect:

 * Setting it to **higher** values can help avoid starting too many parallel threads if you expect a lot of client connections to execute long-running queries.
* Setting it to **lower** values can help prevent deadlocks.

 ### Thread Group Oversubscription

 If the **timer thread** were to detect a stall in a thread group, then it would either wake up a sleeping **worker thread** or create a new **worker thread** in that thread group. At that point, the thread group would have multiple active **worker threads**. In other words, the thread group would be *oversubscribed*.

 You might expect that the thread pool would shutdown one of the **worker threads** when the stalled client connection finished what it was doing, so that the thread group would only have one active **worker thread** again. However, this does not always happen. Once a thread group is oversubscribed, the `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)` system variable defines the upper limit for when **worker threads** start shutting down after they finish work for client connections. The default value is `3`. It can be changed dynamically with `[SET GLOBAL](../set/index#global-session)`. For example:

 
```
SET GLOBAL thread_pool_oversubscribe=10;

```

It can also be set in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index) prior to starting up the server. For example:

 
```
[mariadb]
..
thread_handling=pool-of-threads
thread_pool_size=32
thread_pool_stall_limit=300
thread_pool_oversubscribe=10

```


To clarify, the `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)` system variable does not play any part in the creation of new **worker threads**. The `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)` system variable is only used to determine how many **worker threads** should remain active in a thread group, once a thread group is already oversubscribed due to stalls.

 
In general, the default value of `3` should be adequate for most users. Most users should not need to change the value of the `[thread\_pool\_oversubscribe](../thread-pool-system-status-variables/index#thread_pool_oversubscribe)` system variable.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/thread-groups-in-the-unix-implementation-of-the-thread-pool/>

Building Cassandra Storage Engine for Packaging
===============================================

    
THIS PAGE IS OBSOLETE, it describes how to build a branch of MariaDB-5.5 with Cassandra SE. Cassandra SE is a part of [MariaDB 10.0](../what-is-mariadb-100/index), which uses different approach to building.

 
These are instructions on how exactly we build Cassandra SE packages. 

 Getting into build environment
------------------------------

 See How\_to\_access\_buildbot\_VMs page on the internal wiki. The build VM to use is

 
```
ezvm  precise-amd64-build

```

Get into the VM and continue to next section.

 Set up Thrift
-------------

 
```
mkdir build
cd build
wget https://dist.apache.org/repos/dist/release/thrift/0.8.0/thrift-0.8.0.tar.gz

sudo apt-get install bzr
sudo apt-get install flex

tar zxvf thrift-0.8.0.tar.gz 
cd thrift-0.8.0/

./configure --prefix=/home/buildbot/build/thrift-inst --without-qt4 --without-c_glib --without-csharp --without-java --without-erlang --without-python --without-perl --without-php --without-php_extension --without-ruby --without-haskell --without-go --without-d
make
make install

# free some space
make clean
cd .. 

```

Get the bzr checkout
--------------------

 * Create another SSH connection to terrier, run the script suggested by motd.
* Press (C-a C-c) to create another window
* Copy the base bazaar repository into the VM:

 
```
scp /home/psergey/5.5-cassandra-base.tgz runvm:

```

Then, get back to the window with VM, and run in VM:

 
```
tar zxvf ../5.5-cassandra-base.tgz
rm -rf ../5.5-cassandra-base.tgz
cd 5.5-cassandra/
bzr pull lp:~maria-captains/maria/5.5-cassandra

```

Compile
-------

 
```
export LIBS="-lthrift"
export LDFLAGS=-L/home/buildbot/build/thrift-inst/lib

mkdir mkdist
cd mkdist
cmake ..
make dist

```


```
basename mariadb-*.tar.gz .tar.gz > ../distdirname.txt

cp mariadb-5.5.25.tar.gz ../
cd ..
tar zxf "mariadb-5.5.25.tar.gz"
mv "mariadb-5.5.25" build
cd build
mkdir mkbin
cd mkbin
cmake -DBUILD_CONFIG=mysql_release ..
make -j4 package

```

This should end with:

 
```
CPack: - package: /home/buildbot/build/5.5-cassandra/build/mkbin/mariadb-5.5.25-linux-x86_64.tar.gz generated.

```

Free up some disk space:

 
```
rm -fr ../../mkdist/

```


```
mv mariadb-5.5.25-linux-x86_64.tar.gz ../..
cd ../..
rm -rf build

```

Patch the tarball to include Thrift
-----------------------------------

 
```
mkdir fix-package
cd fix-package
tar zxvf ../mariadb-5.5.25-linux-x86_64.tar.gz 

```

Verify that mysqld was built with Cassandra SE:

 
```
ldd mariadb-5.5.25-linux-x86_64/bin/mysqld

```

This should point to libthrift-0.8.0.so.

 
```
cp /home/buildbot/build/thrift-inst/lib/libthrift* mariadb-5.5.25-linux-x86_64/lib/
tar czf mariadb-5.5.25-linux-x86_64.tar.gz mariadb-5.5.25-linux-x86_64/
cp mariadb-5.5.25-linux-x86_64.tar.gz ..

```

Copy the data out of VM
-----------------------

 In the second window (the one that's on terrier, but not in VM), run:

 
```
mkdir build-cassandra
cd build-cassandra
scp runvm:/home/buildbot/build/5.5-cassandra/mariadb-5.5.25.tar.gz .
scp runvm:/home/buildbot/build/5.5-cassandra/mariadb-5.5.25-linux-x86_64.tar.gz .

```

References
----------

 1. <http://buildbot.askmonty.org/buildbot/builders/kvm-tarbake-jaunty-x86/builds/2578>
2. <http://buildbot.askmonty.org/buildbot/builders/kvm-bintar-hardy-amd64/builds/1907>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-cassandra-storage-engine-for-packaging/>

Cassandra Storage Engine Overview
=================================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  Installing
----------

 
**MariaDB starting with [10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/)**Cassandra storage engine is a part of [MariaDB 10.0](../what-is-mariadb-100/index), starting from [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/). 

 
The Cassandra storage engine is included but is not installed/activated by default.

 If using the [YUM repositories](https://downloads.mariadb.org/mariadb/repositories/) on Fedora, Red Hat, or CentOS, first install the Cassandra storage engine package with:

 
```
yum install MariaDB-cassandra-engine

```

If using the Debian or Ubuntu repositories, the Cassandra plugin is in the main MariaDB server package.

 To install/activate the storage engine into MariaDB, issue the following command:

 
```
install soname 'ha_cassandra.so'; 

```

You can also activate the storage engine by using the `--plugin-load` command on server startup.

 
**MariaDB [5.5.27](https://mariadb.com/kb/en/mariadb-5527-release-notes/)**There was also a preview release based on [MariaDB 5.5](../what-is-mariadb-55/index) with a source tarball and x86\_64 binaries for Ubuntu 12.04 Precise Pangolin. It is available from here:

 * [Binary Tarball](http://downloads.mariadb.org/interstitial/mariadb-5.5.27/cassandra-preview/mariadb-5.5.25-linux-x86_64.tar.gz/from/http://ftp.osuosl.org/pub/mariadb),
* [Source Tarball](http://downloads.mariadb.org/interstitial/mariadb-5.5.27/cassandra-preview/mariadb-5.5.25.tar.gz/from/http://ftp.osuosl.org/pub/mariadb).

 The Cassandra storage engine is not included in any regular [MariaDB 5.5](../what-is-mariadb-55/index) release.

 
Introduction
------------

 The Cassandra Storage Engine allows access to data in a Cassandra cluster from MariaDB. The overall architecture is shown in the picture below and is similar to that of the NDB cluster storage engine.

 ![cassandra-se-overview]

 You can access the same Cassandra cluster from multiple MariaDB instances, provided each of them runs the Cassandra Storage Engine:

 ![mariadb-and-cassandra]

 The primary goal of Cassandra SE (Storage Engine) is data integration between the SQL and NoSQL worlds. Have you ever needed to:

 * grab some of Cassandra's data from your web frontend, or SQL query?
* insert a few records into Cassandra from some part of your app?

 Now, this is easily possible. Cassandra SE makes Cassandra's column family appear as a table in MariaDB that you can insert to, update, and select from. You can write joins against this table, it is possible to join data that's stored in MariaDB with data that's stored in Cassandra.

 ### Versions in MariaDB

 


| Cassandra SE Version | Introduced | Maturity |
| --- | --- | --- |
| Cassandra SE 1.8 | [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) | Experimental |

  ### What about CQL?

 The Cassandra Query Language (CQL) is the best way to work with Cassandra. It resembles SQL on first glance, however the resemblance is very shallow. CQL queries are tightly bound to the way Cassandra accesses its data internally. For example, you can't have even the smallest join. In fact, adding a mere `... AND non_indexed_column=1` into a `WHERE` clause is already invalid CQL.

 Our goal is to let one work in SQL instead of having to move between CQL and SQL all the time.

 ### Does this make Cassandra an SQL database?

 No. Cassandra SE is not suitable for running analytics-type queries that sift through huge amounts of data in a Cassandra cluster. That task is better handled by Hadoop-based tools like Apache Pig or Apache Hive. Cassandra SE is rather a "window" from an SQL environment into NoSQL.

 Data mapping
------------

 Let's get specific. In order to access Cassandra's data from MariaDB, one needs to create a table with `engine=cassandra`. The table will represent a view of a Column Family in Cassandra and its definition will look like so: 

 
```
set cassandra_default_thrift_host='192.168.0.10' -- Cassandra's address. It can also
                                                 -- be specified as startup parameter
                                                 -- or on per-table basis

create table cassandra_tbl      -- table name can be chosen at will
(
  rowkey  type PRIMARY KEY,     -- represents Column Family's rowkey. Primary key
                                -- must be defined over this column.

  column1 type,                 -- Cassandra's static columns can be mapped to 
  column2 type,                 -- regular SQL columns.

  dynamic_cols blob DYNAMIC_COLUMN_STORAGE=yes -- If you need to access Cassandra's
                                               -- dynamic columns, you can define
                                               -- a blob which will receive all of 
                                               -- them, packed as MariaDB's dynamic
                                               -- columns.
) engine=cassandra
  keyspace= 'cassandra_key_space'        -- Cassandra's keyspace.columnFamily we  
  column_family='column_family_name';    -- are accessing.

```

The name of the table can be arbitrary. However, primary key, column names, and types must "match" those of Cassandra. 

 ### Cassandra's rowkey

 The table must define a column that corresponds to the Column Family's rowkey.

 * If Cassandra's `rowkey` has an alias (or name), then MariaDB's column must have the same name.
	+ Otherwise, it must be named "rowkey".
* The type of MariaDB's column must match the validation\_class of Cassandra's rowkey (datatype matching is covered in more detail below).

 Note: Multi-column primary keys are currently not supported. Support may be added in a future version, depending on whether there is a demand for it.

 ### Cassandra's static columns

 Cassandra allows one to define a "static column family", where column metadata is defined in the Column Family header and is obeyed by all records.

 These "static" columns can be mapped to regular columns in MariaDB. A static column named 'foo' in Cassandra should have a counterpart named 'foo' in MariaDB. The types must also match, they are covered below.

 ### Cassandra's dynamic columns

 Cassandra also allows individual rows to have their own sets of columns. In other words, each row can have its own unique columns. 

 These columns can be accessed through MariaDB's [Dynamic Columns](../dynamic-columns/index) feature. To do so, one must define a column:

 * with an arbitrary name
* of type `blob`
* with the `DYNAMIC_COLUMN_STORAGE=yes` attribute

 Here is an example:

 
```
dynamic_cols blob DYNAMIC_COLUMN_STORAGE=yes

```

Once define, one can access individual columns with the [new variant](../dynamic-columns-in-mariadb-10/index) of the Dynamic Column functions, which now support string names (they used to support integers only).

 ### Super columns

 Cassandra's SuperColumns are not supported, there are currently no plans to support them. 

 ### Datatypes

 There is no direct 1-to-1 mapping between Cassandra's datatypes and MySQL/MariaDB datatypes. Also, Cassandra's size limitations are often more relaxed than MySQL/MariaDB's. For example, Cassandra's limit on rowkey length is about 2G, while MySQL limits unique key length to about 1.5Kb.

 The types must be mapped as follows:

 


| Cassandra | MariaDB |
| --- | --- |
| blob | BLOB, VARBINARY(n) |
| ascii | BLOB, VARCHAR(n), use charset=latin1 |
| text | BLOB, VARCHAR(n), use charset=utf8 |
| varint | VARBINARY(n) |
| int | INT |
| bigint | BIGINT, TINY, SHORT (pick the one that will fit the real data) |
| uuid | CHAR(36), the UUID will be represented in text form on the MariaDB side |
| timestamp | TIMESTAMP (second precision), TIMESTAMP(6) (microsecond precision), BIGINT (gets verbatim Cassandra's 64-bit milliseconds-since-epoch) |
| boolean | BOOL |
| float | FLOAT |
| double | DOUBLE |
| decimal | VARBINARY(n) |
| counter | BIGINT, only reading is supported |

 
For types like "`VARBINARY(n)`", `n` should be chosen sufficiently large to accommodate all the data that is encountered in the table.

 Command mapping
---------------

 ### INSERT

 Cassandra doesn't provide any practical way to make INSERT different from UPDATE. Therefore, INSERT works as INSERT-or-UPDATE, it will overwrite the data, if necessary.

 `INSERT ... SELECT` and multi-line INSERT will try to write data in batches. Batch size is controlled by the [cassandra\_insert\_batch\_size](../cassandra-system-variables/index#cassandra_insert_batch_size) system variable, which specifies the max. batch size in columns.

 The status variables [Cassandra\_row\_inserts](../cassandra-status-variables/index#cassandra_row_inserts) and [Cassandra\_row\_insert\_batches](../cassandra-status-variables/index#cassandra_row_insert_batches) allow one to see whether inserts are actually batched.

 ### UPDATE

 UPDATE works like one would expect SQL's UPDATE command to work (i.e. changing a primary key value will result in the old record being deleted and a new record being inserted)

 ### DELETE

 * `DELETE FROM cassandra_table` maps to the `truncate(column_family)` call.

 * The DELETE with WHERE clause will do per-row deletions.

 ### SELECT

 Generally, all SELECT statements work like one expects SQL to work. Conditions in the form `primary_key=...` allow the server to construct query plans which access Cassandra's rows with key lookups.

 #### Full table scan

 Full table scans are performed in a memory-efficient way. Cassandra SE performs a full table scan as a series of batches, each of which reads not more than [cassandra\_rnd\_batch\_size](../cassandra-system-variables/index#cassandra_rnd_batch_size) records.

 #### Batched Key Access support

 Cassandra supports Batched Key Access in no-association mode. This means that it requires the SQL layer to do hashing, which means the following settings are required:

 * optimizer\_switch='join\_cache\_hashed=on'
* join\_cache\_level=7|8

 Cassandra SE is currently unable to make use of space in the join buffer (the one whose size is controlled by [#join\_buffer\_size](../server-system-variables/index#join_buffer_size)). Instead, it will limit read batches to reading not more than [cassandra\_multiget\_batch\_size](../cassandra-system-variables/index#cassandra_multiget_batch_size) at a time, and memory will be allocated on the heap. 

 Note that the [#join\_buffer\_size](../server-system-variables/index#join_buffer_size) buffer is still needed by the SQL layer, so its value should still be increased if you want to read in big batches.

 It is possible to track the number of read batches, how many keys were looked-up, and how many results were produced with these status variables:

 


| Variable\_name | Value |
| --- | --- |
| [Cassandra\_multiget\_reads](../cassandra-status-variables/index#cassandra_multiget_reads) | `0` |
| [Cassandra\_multiget\_keys\_scanned](../cassandra-status-variables/index#cassandra_multiget_keys_scanned) | `0` |
| [Cassandra\_multiget\_rows\_read](../cassandra-status-variables/index#cassandra_multiget_rows_read) | `0` |

 
System and status variables
---------------------------

 The following [system variables](../cassandra-system-variables/index) are available:

 


| Variable name | Description |
| --- | --- |
| [cassandra\_default\_thrift\_host](../cassandra-system-variables/index#cassandra_default_thrift_host) | Host to connect to, if not specified on per-table basis |
| [cassandra\_failure\_retries](../cassandra-system-variables/index#cassandra_failure_retries) | Number of times to retry on timeout/unavailable failures |
| [cassandra\_insert\_batch\_size](../cassandra-system-variables/index#cassandra_insert_batch_size) | INSERT batch size |
| [cassandra\_multiget\_batch\_size](../cassandra-system-variables/index#cassandra_multiget_batch_size) | Batched Key Access batch size |
| [cassandra\_rnd\_batch\_size](../cassandra-system-variables/index#cassandra_rnd_batch_size) | Full table scan batch size |
| [cassandra\_read\_consistency](../cassandra-system-variables/index#cassandra_read_consistency) | Consistency to use for reading |
| [cassandra\_write\_consistency](../cassandra-system-variables/index#cassandra_write_consistency) | Consistency to use for writing |

 
The following [status variables](../cassandra-status-variables/index) are available:

 


| Variable name | Description |
| --- | --- |
| [Cassandra\_row\_inserts](../cassandra-status-variables/index#cassandra_row_inserts) | Number of rows inserted |
| [Cassandra\_row\_insert\_batches](../cassandra-status-variables/index#cassandra_row_insert_batches) | Number of insert batches performed |
| [Cassandra\_multiget\_reads](../cassandra-status-variables/index#cassandra_multiget_reads) | Number of read operations |
| [Cassandra\_multiget\_keys\_scanned](../cassandra-status-variables/index#cassandra_multiget_keys_scanned) | Number of keys we've made lookups for |
| [Cassandra\_multiget\_rows\_read](../cassandra-status-variables/index#cassandra_multiget_rows_read) | Number of rows actually read |
| [Cassandra\_timeout\_exceptions](../cassandra-status-variables/index#cassandra_timeout_exceptions) | Number of Timeout exceptions we got from Cassandra |
| [Cassandra\_unavailable\_exceptions](../cassandra-status-variables/index#cassandra_unavailable_exceptions) | Number of Unavailable exceptions we got from Cassandra |

 
A note about Cassandra 1.2
--------------------------

 Cassandra 1.2 has slightly changed its data model, as described at <http://www.datastax.com/dev/blog/thrift-to-cql3>. This has caused some of Thrift-based clients to no longer work (for example, here's a problem experienced by Pig: [CASSANDRA-5234](https://issues.apache.org/jira/browse/CASSANDRA-5234)).

 Currently, Cassandra SE is only able to access Cassandra 1.2's column families that were defined `WITH COMPACT STORAGE` attribute.

 See also
--------

 * Slides from talk at Percona Live 2013:[MariaDB Cassandra Interoperability](http://www.percona.com/live/mysql-conference-2013/sessions/mariadb-cassandra-interoperability)
* [MDEV-431](https://jira.mariadb.org/browse/MDEV-431) - JIRA task for Cassandra SE work
* [Instructions for creating binary tarball in MariaDB 5.5](../building-cassandra-storage-engine-for-packaging/index)
* [Cassandra Storage Engine - Future Plans](../cassandra-storage-engine-future-plans/index)
* [Cassandra Storage Engine - Use Example](../cassandra-storage-engine-use-example/index)
* [Cassandra Storage Engine - Issues](../cassandra-storage-engine-issues/index)
* [HBase Storage Engine](../hbase-storage-engine/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-storage-engine-overview/>

Aria Encryption Keys
====================

    As with other storage engines that support data-at-rest encryption, Aria relies on an [Encryption Key Management](../key-management-and-encryption-plugins/index) plugin to handle its encryption keys. Where the support is available, Aria can use [multiple keys](../encryption-key-management/index#using-multiple-encryption-keys). 

 Encryption Keys
---------------

 MariaDB keeps track of each encryption key internally using a 32-bit integer, which serves as the key identifier. Unlike [InnoDB](../innodb-encryption/index), Aria does not support the `[ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id)` table option (for more information, see [MDEV-18049](https://jira.mariadb.org/browse/MDEV-18049)), which allows the user to specify the encryption key to use. Instead, Aria defaults to specific encryption keys provided by the Encryption Key Management plugin.

 * When working with user-created tables, Aria encrypts them to disk using the ID 1 key.

 * When working with internal temporary tables written to disk, Aria encrypts them to disk using the ID 2 key, unless there is no ID 2 key, then it falls back on the ID 1 key.

 Key Rotation
------------

 Some [key management and encryption plugins](../encryption-key-management/index) allow you to automatically rotate and version your encryption keys. If a plugin support key rotation, and if it rotates the encryption keys, then InnoDB's [background encryption threads](../innodb-background-encryption-threads/index) can re-encrypt InnoDB pages that use the old key version with the new key version. However, Aria does **not** have a similar mechanism, which means that the tables remain encrypted with the older key version. For more information, see [MDEV-18971](https://jira.mariadb.org/browse/MDEV-18971).

 
In order for key rotation to work, both the backend key management service (KMS) and the corresponding [key management and encryption plugin](../encryption-key-management/index) have to support key rotation. See [Encryption Key Management: Support for Key Rotation in Encryption Plugins](../encryption-key-management/index#support-for-key-rotation-in-encryption-plugins) to determine which plugins currently support key rotation.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-encryption-keys/>

Cassandra Storage Engine Use Example
====================================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  This page is a short demo of what using [Cassandra Storage Engine](../cassandra-storage-engine/index) looks like.

 First, a keyspace and column family must be created in Cassandra:

 
```
cqlsh> CREATE KEYSPACE mariadbtest2
   ...   WITH strategy_class = 'org.apache.cassandra.locator.SimpleStrategy'
   ...   AND strategy_options:replication_factor='1';
cqlsh> USE mariadbtest2;
cqlsh:mariadbtest2> create columnfamily cf1 ( pk varchar primary key, data1 varchar, data2 bigint);
cqlsh:mariadbtest2> select * from cf1;
cqlsh:mariadbtest2> 


```

Now, let's try to connect an SQL table to it:

 
```
MariaDB [test]> create table t1 (
    ->   rowkey varchar(36) primary key, 
    ->   data1 varchar(60), data2 varchar(60)
    -> ) engine=cassandra    thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1';
ERROR 1928 (HY000): Internal error: 'Failed to map column data2 to datatype org.apache.cassandra.db.marshal.LongType'


```

We've used a wrong datatype. Let's try again:

 
```
MariaDB [test]> create table t1 (
    ->   rowkey varchar(36) primary key, 
    ->   data1 varchar(60), data2 bigint
    -> ) engine=cassandra  thrift_host='localhost' keyspace='mariadbtest2' column_family='cf1';
Query OK, 0 rows affected (0.04 sec)

```

Ok. Let's insert some data:

 
```
MariaDB [test]> insert into t1 values ('rowkey10', 'data1-value', 123456);
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> insert into t1 values ('rowkey11', 'data1-value2', 34543);
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into t1 values ('rowkey12', 'data1-value3', 454);
Query OK, 1 row affected (0.00 sec)

```

Let's select it back:

 
```
MariaDB [test]> select * from t1 where rowkey='rowkey11';
+----------+--------------+-------+
| rowkey   | data1        | data2 |
+----------+--------------+-------+
| rowkey11 | data1-value2 | 34543 |
+----------+--------------+-------+
1 row in set (0.00 sec)

```

Now, let's check if it can be seen in Cassandra:

 
```
cqlsh:mariadbtest2> select * from cf1;
 pk       | data1        | data2
----------+--------------+--------
 rowkey12 | data1-value3 |    454
 rowkey10 |  data1-value | 123456
 rowkey11 | data1-value2 |  34543

```

Or, in cassandra-cli:

 
```
[default@mariadbtest2] list cf1;
Using default limit of 100
Using default column limit of 100
-------------------
RowKey: rowkey12
=> (column=data1, value=data1-value3, timestamp=1345452471835)
=> (column=data2, value=454, timestamp=1345452471835)
-------------------
RowKey: rowkey10
=> (column=data1, value=data1-value, timestamp=1345452467728)
=> (column=data2, value=123456, timestamp=1345452467728)
-------------------
RowKey: rowkey11
=> (column=data1, value=data1-value2, timestamp=1345452471831)
=> (column=data2, value=34543, timestamp=1345452471831)

3 Rows Returned.
Elapsed time: 5 msec(s).

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-storage-engine-use-example/>

Cassandra Storage Engine Issues
===============================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  This page lists difficulties and peculiarities of [Cassandra Storage Engine](../cassandra-storage-engine/index). I'm not putting them into bug tracker because it is not clear whether these properties should be considered bugs.

 No way to get E(#rows in column family)
---------------------------------------

 There seems to be no way to get even a rough estimate of how many different keys are present in a column family. I'm using an arbitrary value of 1000 now, which causes

 * EXPLAIN will always show rows=1000 for full table scans. In the future, this may cause poor query plans.
* `DELETE FROM table` always prints "1000 rows affected", with no regards how many records were actually there in the table.

 
```
MariaDB [j1]> delete from t1;
Query OK, 1000 rows affected (0.14 sec)

```

We could use the new [engine-independent-table-statistics](../engine-independent-table-statistics/index) feature to get some data statistics.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-storage-engine-issues/>

Cassandra Storage Engine Future Plans
=====================================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  These are possible future directions for [Cassandra Storage Engine](../cassandra-storage-engine/index). **This is mostly brainstorming, nobody has committed to implementing this**.

 Unlike MySQL/MariaDB, Cassandra is not suitable for transaction processing. (the only limited scenario that they handle well is append-only databases)

 Instead, they focus on ability to deliver real-time analytics. This is achieved via the following combination:

 1. Insert/update operations are reduced to inserting a newer version, their implementation (SSTree) allows to make lots of updates at a low cost

 1. The data model is targeted at denormalized data, cassandra docs and user stories all mention the practice of creating/populating a dedicated column family (=table) for each type of query you're going to run.

 In other words, Cassandra encourages creation/use of materialized VIEWs. Having lots of materialized VIEWs makes updates expensive, but their low cost and non-conflicting nature should offset that.

 How does one use Cassandra together with an SQL database? I can think of these use cases:

 use case 1
----------

 1. The "OLTP as in SQL" is kept in the SQL database.
2. Data that's too big for SQL database (such as web views, or clicks) is stored in Cassandra, but can also be accessed from SQL.

 As an example, one can think of a web shop, which provides real-time peeks into analytics data, like amazon's "people who looked at this item, also looked at ..." , or "\*today\*'s best sellers in this category are ...", etc

  Generally, CQL (Cassandra Query Language) allows to query Cassandra's data in an SQL-like fashion. 

 Access through a storage engine will additionally allow:

 1. to get all of the data from one point, instead of rwo
2. joins betwen SQL and Cassandra's data \*might\* be more efficent due to Batched Key Access (this remains to be seen)
3. ??

 use case 2
----------

 Suppose, all of the system's data is actually stored in an OLTP SQL database. 

 Cassandra is only used as an accelerator for analytical queries. Cassandra won't allow arbitrary, ad-hoc dss-type queries, it will require the DBA to create and maintain appropriate column families (however, it is supposed to give a nearly-instant answers to analytics-type questions).

 Tasks that currently have no apparent solutions:

 1. There is no way to replicate data from MySQL/MariaDB into Cassandra. It would be nice if one could update data in MySQL and that would cause appropriate inserts made into all relevant column families in Cassandra.
2. ...

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/cassandra-storage-engine-future-plans/>

Handling Joins With Cassandra
=============================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  Joins with data stored in a Cassandra database are only possible on the MariaDB side. That is, if we want to compute a join between two tables, we will:

 1. Read the relevant data for the first table.
2. Based on data we got in #1, read the matching records from the second table.

 Either of the tables can be an InnoDB table, or a Cassandra table. In case the second table is a Cassandra table, the Cassandra Storage Engine allows to read matching records in an efficient way.

 Some general info
-----------------

 All this is targeted at running joins which touch small fraction of the tables. The expected typical use-case looks like this:

 * The primary data is stored in MariaDB (ie. in InnoDB)
* There is also some extra data stored in Cassandra (e.g. hit counters)
* The user accesses data in MariaDB (think of a website and a query like:

 
```
select * from user_accounts where username='joe')

```

Cassandra SE allows to grab some Cassandra data, as well. One can write things like this:

 
```
select 
  user_accounts.*, 
  cassandra_table.some_more_fields
from 
  user_accounts, cassandra_data 
where 
  user_accounts.username='joe' and
  user_accounts.user_id= cassandra_table.user_id

```

which is much easier to do than to use Thrift API.

 If the user wants to run huge joins that touch a big fraction of table's data, for example:

  "What are top 10 countries that my website had visitors from in the last month"?

  or 

  "Go through last month's orders and give me top 10 selling items"

 then Cassandra Storage engine is not a good answer. Queries like this are answered in two ways:

 1. Design their schema in Cassandra in such a way that allows to get this data in one small select. No kidding. This is what Cassandra is targeted at, they explicitly recommend that Cassandra schema design starts with the queries.
2. If the query doesn't match Cassandra's schema, they need to run Hive (or Pig), which have some kind of distributed join support. Hive/Pig compile queries to Map/reduce job which are ran across the whole cluster, so they will certainly beat Cassandra Storage Engine which runs on one mysqld node (you can have multiple mysqld nodes of course, but they will not cooperate with one another).

 It is possible to run Hive/Pig on Cassandra.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handling-joins-with-cassandra/>

Virtual Machine to Test the Cassandra Storage Engine
====================================================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  Julien Duponchelle has made a virtual machine available for testing the Cassandra storage engine. Find out more at [Cassandra MariaDB VirtualBox](http://julien.duponchelle.info/Cassandra-MariaDB-Virtual-Box.html).

 The virtual machine is based on:

 * Ubuntu 12.04
* DataStax Cassandra
* [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5527-release-notes/) + Cassandra

 [Vagrant](http://www.vagrantup.com/) is used for setup. Full [instructions](http://julien.duponchelle.info/Cassandra-MariaDB-Virtual-Box.html) are at Julien's website.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/virtual-machine-to-test-the-cassandra-storage-engine/>

Building Cassandra Storage Engine
=================================

    
THIS PAGE IS OBSOLETE, it describes how to build a branch of MariaDB-5.5 with Cassandra SE. Cassandra SE is a part of [MariaDB 10.0](../what-is-mariadb-100/index), which uses different approach to building.

 
This page describes how to build the [Cassandra Storage Engine](../cassandra-storage-engine/index).

 Getting the source code
-----------------------

 The code is in bazaar branch at [lp:~maria-captains/maria/5.5-cassandra](https://code.launchpad.net/~maria-captains/maria/5.5-cassandra).

 Alternatively, you can download a tarball from <http://ftp.osuosl.org/pub/mariadb/mariadb-5.5.27/cassandra-preview/>

 Building
--------

 The build process is not fully streamlined yet. It is

 * known to work on Fedora 15 and OpenSUSE
* known not to work on Ubuntu Oneiric Ocelot (see [MDEV-501](https://jira.mariadb.org/browse/MDEV-501)).
* known to work on Ubuntu Precise Pangolin

 The build process is as follows

 * Install Cassandra (we tried 1.1.3 ... 1.1.5, 1.2 beta versions should work but haven't been tested)
* Install the Thrift library (we used 0.8.0 and [0.9.0-trunk](https://dist.apache.org/repos/dist/release/thrift/0.9.0/thrift-0.9.0.tar.gz)), only the C++ backend is needed.
	+ we have installed it by compiling the source tarball downloaded from [thrift.apache.org](http://thrift.apache.org/)
* edit `storage/cassandra/CMakeLists.txt` and modify the `INCLUDE_DIRECTORIES` directive to point to Thrift's include directory.
* `export LIBS="-lthrift"`, on another machine it was "-lthrift -ldl"
* `export LDFLAGS=-L/path/to/thrift/libs`
* Build the server
	+ we used BUILD/compile-pentium-max script (the name is for historic reasons. It will actually build an optimized amd64 binary)

 Running the server
------------------

 Cassandra storage engine is linked into the server (ie, it is not a plugin). All you need to do is to make sure Thrift's libthrift.so can be found by the loader. This may require adjusting the LD\_LIBRARY\_PATH variable.

 Running tests
-------------

 There is a basic testsuite. In order to run it, one needs

 * Start Cassandra on localhost
* Set PATH so that `cqlsh` and `cassandra-cli` binaries can be found
* From the build directory, run

 
```
cd mysql-test
./mysql-test-run t/cassandra.test

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-cassandra-storage-engine/>

About PBXT
==========

     [PBXT](http://www.primebase.org) was a storage engine that was included in the MariaDB source and binaries by default until [MariaDB 5.3](../what-is-mariadb-53/index).

 Since [MariaDB 5.5](../what-is-mariadb-55/index), the PBXT storage engine has been disabled by default and must be [explicitly built](../how-to-build-pbxt/index) to use it. The reason is that PBXT is not actively maintained anymore. It has a few bugs that are not fixed and it's not actively used.

 The PBXT versions in various releases are:

 * version 1.0.11 in [MariaDB 5.1.47](http://askmonty.org/wiki/MariaDB:Download:MariaDB_5.1.47)
* version 1.0.08d in [MariaDB 5.1.44b](http://askmonty.org/wiki/MariaDB:Download:MariaDB_5.1.44b)

 PBXT is a general purpose transactional storage engine. PBXT is fully "ACID" compliant, which means it can be used as an alternative to other MariaDB transactional engines (such as XtraDB or InnoDB).

 PBXT features include the following:

 * **MVCC Support:** MVCC stands for Multi-version Concurrency Control. MVCC allows reading the database without locking.
* **Fully ACID compliant:** This means that all transactions are: atomic, consistent, isolated and durable.
* **Row-level locking:** When updating, PBXT uses row-level locking. Row-level locking is also used during SELECT FOR UPDATE.
* **Fast Rollback and Recovery:** PBXT uses a specialized method to identify garbage which makes "undo" unnecessary. This make both rollback of transactions and recovery after restart very fast.
* **Deadlock Detection:** PBXT identifies all kinds of deadlocks immediately.
* **Write-once:** PBXT uses a log-based storage which makes it possible to write transactional data directly to the database, without first being writen to the transaction log.
* **Referential Integrity:** PBXT supports [foreign key](../foreign-keys/index) definitions, including cascaded updates and deletes.
* **BLOB streaming:** In combination with the [BLOB Streaming engine](http://www.blobstreaming.org) PBXT can stream binary and media directly in and out of the database.

 PBXT will not take any resources (disk space or CPU processing) until you create your first PBXT table.

 xtstat
------

 The included `xtstat` program can be used to monitor all internal activity of PBXT. See [xtstat](../xtstat/index) for more information.

 More information
----------------

 Further documentation for PBXT can be found here: <http://www.primebase.org/documentation>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-pbxt/>

Building PBXT
=============

    As of [MariaDB 5.5](../what-is-mariadb-55/index) PBXT is not built by default any longer.

 The commands to use for building the [MariaDB 5.5 source](../compiling-mariadb-from-source/index) with PBXT:

 
```
cmake -DWITH_PBXT_STORAGE_ENGINE=1 .
make
make install

```

It should be noted that MariaDB still ships the engine, it just does not build it by default.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/building-pbxt/>

File Organization in PBXT
=========================

    A short description of the files used by PBXT.

 If you do the following create:

 
```
create table test.t9 (a int) engine=pbxt'.

```

You will find the following files in your database directory.

 
```
(/my/data) ls -Rl pbxt
pbxt:
total 32
-rw-rw---- 1 monty my    7 Nov  4 16:41 location
-rw-rw---- 1 monty my 8672 Nov  4 16:41 location.frm
-rw-rw---- 1 monty my 8687 Nov  4 16:41 statistics.frm
drwxrwxr-x 2 monty my 4096 Nov  4 16:41 system

pbxt/system:
total 32776
-rw-rw---- 1 monty my        9 Nov  4 16:41 ilog-1.xt
-rw-rw---- 1 monty my       44 Nov  4 16:41 restart-1.xt
-rw-rw---- 1 monty my 33554432 Nov  4 16:41 xlog-1.xt

(/my/data) ls -l test/t9*
-rw-rw---- 1 monty my    4 Nov  4 16:41 test/t9-1.xtr
-rw-rw---- 1 monty my 8554 Nov  4 16:41 test/t9.frm
-rw-rw---- 1 monty my  155 Nov  4 16:41 test/t9.xtd
-rw-rw---- 1 monty my 4096 Nov  4 16:41 test/t9.xti

```

TODO: Fill in a description of what the above files are used for.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/file-organization-in-pbxt/>

Performance Schema setup\_actors Table
======================================

    The `setup_actors` table contains information for determining whether monitoring should be enabled for new client connection threads.

 The default size is 100 rows, which can be changed by modifying the `[performance\_schema\_setup\_actors\_size](../performance-schema-system-variables/index#performance_schema_setup_actors_size)` system variable at server startup.

 If a row in the table matches a new foreground thread's client and host, the matching `INSTRUMENTED` column in the [threads](../performance-schema-threads-table/index) table is set to either `YES` or `NO`, which allows selective application of instrumenting by host, by user, or combination thereof.

 


| Column | Description |
| --- | --- |
| `HOST` | Host name, either a literal, or the `%` wildcard representing any host. |
| `USER` | User name, either a literal or the `%` wildcard representing any name. |
| `ROLE` | Unused |

 
Initially, any user and host is matched:

 
```
SELECT * FROM performance_schema.setup_actors;
+------+------+------+
| HOST | USER | ROLE |
+------+------+------+
| %    | %    | %    |
+------+------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-setup_actors-table/>

Performance Schema hosts Table
==============================

    Description
-----------

 The `hosts` table contains a row for each host used by clients to connect to the server, containing current and total connections. 

 The size is determined by the [performance\_schema\_hosts\_size](../performance-schema-system-variables/index#performance_schema_hosts_size) system variable, which, if set to zero, will disable connection statistics in the hosts table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `HOST` | Host name used by the client to connect, `NULL` for internal threads or user sessions that failed to authenticate. |
| `CURRENT_CONNECTIONS` | Current number of the host's connections. |
| `TOTAL_CONNECTIONS` | Total number of the host's connections |

 
Example
-------

 
```
SELECT * FROM hosts;
+-----------+---------------------+-------------------+
| HOST      | CURRENT_CONNECTIONS | TOTAL_CONNECTIONS |
+-----------+---------------------+-------------------+
| localhost |                   1 |                45 |
| NULL      |                  20 |                23 |
+-----------+---------------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-hosts-table/>

Performance Schema accounts Table
=================================

    Description
-----------

 Each account that connects to the server is stored as a row in the accounts table, along with current and total connections.

 The table size is determined at startup by the value of the [performance\_schema\_accounts\_size](../performance-schema-system-variables/index#performance_schema_accounts_size) system variable. If this is set to 0, account statistics will be disabled.

 


| Column | Description |
| --- | --- |
| `USER` | The connection's client user name for the connection, or NULL if an internal thread. |
| `HOST` | The connection client's host name, or NULL if an internal thread. |
| `CURRENT_CONNECTIONS` | Current connections for the account. |
| `TOTAL_CONNECTIONS` | Total connections for the account. |

 
The `USER` and `HOST` values shown here are the username and host used for user connections, not the patterns used to check permissions.

 Example
-------

 
```
SELECT * FROM performance_schema.accounts;
+------------------+-----------+---------------------+-------------------+
| USER             | HOST      | CURRENT_CONNECTIONS | TOTAL_CONNECTIONS |
+------------------+-----------+---------------------+-------------------+
| root             | localhost |                   1 |                 2 |
| NULL             | NULL      |                  20 |                23 |
| debian-sys-maint | localhost |                   0 |                35 |
+------------------+-----------+---------------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-accounts-table/>

Performance Schema metadata\_locks Table
========================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The metadata\_locks table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `metadata_locks` table contains [metadata lock](../metadata-locking/index) information.

 To enable metadata lock instrumention, at runtime:

 
```
UPDATE performance_schema.setup_instruments SET enabled='YES', timed='YES' 
  WHERE name LIKE 'wait/lock/metadata%';

```

or in the [configuration file](../configuring-mariadb-with-option-files/index):

 
```
performance-schema-instrument='wait/lock/metadata/sql/mdl=ON'

```

The table is by default autosized, but the size can be configured with the [performance\_schema\_max\_metadata\_locks](../performance-schema-system-variables/index#performance_schema_max_metadata_locks) system variabe.

 The table is read-only, and [TRUNCATE TABLE](../truncate-table/index) cannot be used to empty the table.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| OBJECT\_TYPE | varchar(64) | NO | NULL | Object type. One of `BACKUP`, `COMMIT`, `EVENT`, `FUNCTION`, `GLOBAL`, `LOCKING SERVICE`, `PROCEDURE`, `SCHEMA`, `TABLE`, `TABLESPACE`, `TRIGGER` (unused) or `USER LEVEL LOCK`. |
| OBJECT\_SCHEMA | varchar(64) | YES | NULL | Object schema. |
| OBJECT\_NAME | varchar(64) | YES | NULL | Object name. |
| OBJECT\_INSTANCE\_BEGIN | bigint(20) unsigned | NO | NULL | Address in memory of the instrumented object. |
| LOCK\_TYPE | varchar(32) | NO | NULL | Lock type. One of `BACKUP_FTWRL1`, `BACKUP_START`, `BACKUP_TRANS_DML`, `EXCLUSIVE`, `INTENTION_EXCLUSIVE`, `SHARED`, `SHARED_HIGH_PRIO`, `SHARED_NO_READ_WRITE`, `SHARED_NO_WRITE`, `SHARED_READ`, `SHARED_UPGRADABLE` or `SHARED_WRITE`. |
| LOCK\_DURATION | varchar(32) | NO | NULL | Lock duration. One of `EXPLICIT` (locks released by explicit action, for example a global lock acquired with [FLUSH TABLES WITH READ LOCK](../flush/index)) , `STATEMENT` (locks implicitly released at statement end) or `TRANSACTION` (locks implicitly released at transaction end). |
| LOCK\_STATUS | varchar(32) | NO | NULL | Lock status. One of `GRANTED`, `KILLED`, `PENDING`, `POST_RELEASE_NOTIFY`, `PRE_ACQUIRE_NOTIFY`, `TIMEOUT` or `VICTIM`. |
| SOURCE | varchar(64) | YES | NULL | Source file containing the instrumented code that produced the event, as well as the line number where the instrumentation occurred. This allows one to examine the source code involved. |
| OWNER\_THREAD\_ID | bigint(20) unsigned | YES | NULL | Thread that requested the lock. |
| OWNER\_EVENT\_ID | bigint(20) unsigned | YES | NULL | Event that requested the lock. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-metadata_locks-table/>

Configuring PAM Authentication and User Mapping with Unix Authentication
========================================================================

    In this article, we will walk through the configuration of PAM authentication using the `[pam](../authentication-plugin-pam/index)` authentication plugin and user and group mapping with the `[pam\_user\_map](../user-and-group-mapping-with-pam/index)` PAM module. The primary authentication will be handled by the `[pam\_unix](https://linux.die.net/man/8/pam_unix)` PAM module, which performs standard Unix password authentication.

 Hypothetical Requirements
-------------------------

 In this walkthrough, we are going to assume the following hypothetical requirements:

 * The Unix user `foo` should be mapped to the MariaDB user `bar`. (`foo: bar`)
* Any Unix user in the Unix group `dba` should be mapped to the MariaDB user `dba`. (`@dba: dba`)

 Creating Our Unix Users and Groups
----------------------------------

 Let's go ahead and create the Unix users and groups that we are using for this hypothetical scenario.

 First, let's create the the `foo` user and a couple users to go into the `dba` group. Note that each of these users needs a password.

 
```
sudo useradd foo
sudo passwd foo
sudo useradd alice
sudo passwd alice
sudo useradd bob
sudo passwd bob

```

And then let's create our `dba` group and add our two users to it:

 
```
sudo groupadd dba
sudo usermod -a -G dba alice 
sudo usermod -a -G dba bob 

```

We also need to create Unix users with the same name as the `bar` and `dba` MariaDB users. See [here](../user-and-group-mapping-with-pam/index#pam-user-with-same-name-as-mapped-mariadb-user-must-exist) to read more about why. No one will be logging in as these users, so they do not need passwords.

 
```
sudo useradd bar
sudo useradd dba -g dba

```

Installing the pam\_user\_map PAM Module
----------------------------------------

 Next, let's [install the pam\_user\_map PAM module](../user-and-group-mapping-with-pam/index#installing-the-pam_user_map-pam-module).

 Before the module can be compiled from source, we may need to install some dependencies.

 On RHEL, CentOS, and other similar Linux distributions that use [RPM packages](../rpm/index), we need to install `gcc` and `pam-devel`:

 
```
sudo yum install gcc pam-devel

```

On Debian, Ubuntu, and other similar Linux distributions that use [DEB packages](../installing-mariadb-deb-files/index), we need to install `gcc` and `libpam0g-dev`:

 
```
sudo apt-get install gcc libpam0g-dev

```

And then we can build and install the library with the following:

 
```
wget https://raw.githubusercontent.com/MariaDB/server/10.4/plugin/auth_pam/mapper/pam_user_map.c 
gcc pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so 
sudo install --mode=0755 pam_user_map.so /lib64/security/ 

```

Configuring the pam\_user\_map PAM Module
-----------------------------------------

 Next, let's [configure the pam\_user\_map PAM module](../user-and-group-mapping-with-pam/index#configuring-the-pam_user_map-pam-module) based on our hypothetical requirements.

 The configuration file for the `pam_user_map` PAM module is `/etc/security/user_map.conf`. Based on our hypothetical requirements, ours would look like:

 
```
foo: bar
@dba:dba

```

Installing the PAM Authentication Plugin
----------------------------------------

 Next, let's [install the `pam` authentication plugin](../authentication-plugin-pam/index#installing-the-plugin).

 Log into the MariaDB Server and execute the following:

 
```
INSTALL SONAME 'auth_pam';

```

Configuring the PAM Service
---------------------------

 Next, let's [configure the PAM service](../authentication-plugin-pam/index#configuring-the-pam-service). We will call our service `mariadb`, so our PAM service configuration file will be located at `/etc/pam.d/mariadb` on most systems.

 Since we are only doing Unix authentication with the `pam_unix` PAM module and group mapping with the `pam_user_map` PAM module, our configuration file would look like this:

 
```
auth required pam_unix.so audit
auth required pam_user_map.so
account required pam_unix.so audit

```

Configuring the pam\_unix PAM Module
------------------------------------

 The `pam_unix` PAM module adds [some additional configuration steps](../authentication-plugin-pam/index#configuring-the-pam-service) on a lot of systems. We basically have to give the user that runs `mysqld` access to `/etc/shadow`.

 If the `mysql` user is running `mysqld`, then we can do that by executing the following:

 
```
sudo groupadd shadow
sudo usermod -a -G shadow mysql
sudo chown root:shadow /etc/shadow
sudo chmod g+r /etc/shadow

```

The [server needs to be restarted](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) for this change to take affect.

 Creating MariaDB Users
----------------------

 Next, let's [create the MariaDB users](../authentication-plugin-pam/index#creating-users). Remember that our PAM service is called `mariadb`.

 First, let's create the MariaDB user for the user mapping: `foo: bar`

 That means that we need to create a `bar` user:

 
```
CREATE USER 'bar'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'bar'@'%' ;

```

And then let's create the MariaDB user for the group mapping: `@dba: dba`

 That means that we need to create a `dba` user:

 
```
CREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'%' ;

```

And then to allow for the user and group mapping, we need to [create an anonymous user that authenticates with the `pam` authentication plugin](../user-and-group-mapping-with-pam/index#creating-users) that is also able to `PROXY` as the `bar` and `dba` users. Before we can create the proxy user, we might need to [clean up some defaults](../create-user/index#fixing-a-legacy-default-anonymous-account):

 
```
DELETE FROM mysql.db WHERE User='' AND Host='%';
FLUSH PRIVILEGES;

```

And then let's create the anonymous proxy user:

 
```
CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
GRANT PROXY ON 'bar'@'%' TO ''@'%';
GRANT PROXY ON 'dba'@'%' TO ''@'%';

```

Testing our Configuration
-------------------------

 Next, let's test out our configuration by [verifying that mapping is occurring](../user-and-group-mapping-with-pam/index#verifying-that-mapping-is-occurring). We can verify this by logging in as each of our users and comparing the return value of `[USER()](../user/index)`, which is the original user name and the return value of `[CURRENT\_USER()](../current_user/index)`, which is the authenticated user name.

 First, let's test out our `foo` user:

 
```
$ mysql -u foo -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 22
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+------------------------------------------------+----------------+
| USER()                                         | CURRENT_USER() |
+------------------------------------------------+----------------+
| foo@ip-172-30-0-198.us-west-2.compute.internal | bar@%          |
+------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `foo` Unix user was properly mapped to the `bar` MariaDB user by looking at the return value of `[CURRENT\_USER()](../current_user/index)`.

 Then let's test out our `alice` user in the `dba` group:

 
```
$ mysql -u alice -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+--------------------------------------------------+----------------+
| USER()                                           | CURRENT_USER() |
+--------------------------------------------------+----------------+
| alice@ip-172-30-0-198.us-west-2.compute.internal | dba@%          |
+--------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

And then let's test out our `bob` user in the `dba` group:

 
```
$ mysql -u bob -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 20
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+------------------------------------------------+----------------+
| USER()                                         | CURRENT_USER() |
+------------------------------------------------+----------------+
| bob@ip-172-30-0-198.us-west-2.compute.internal | dba@%          |
+------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `alice` and `bob` Unix users in the `dba` Unix group were properly mapped to the `dba` MariaDB user by looking at the return values of `[CURRENT\_USER()](../current_user/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-pam-authentication-and-user-mapping-with-unix-authentication/>

System Variables Added in MariaDB 11.1
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 11.1](../what-is-mariadb-111/index) series.

 


| Variable | Added |
| --- | --- |
| [transaction\_isolation](../server-system-variables/index#transaction_isolation) | [MariaDB 11.1.0](https://mariadb.com/kb/en/mariadb-11-1-0-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 11.0](../system-variables-added-in-mariadb-11-0/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-11-1/>

Configuring PAM Authentication and User Mapping with LDAP Authentication
========================================================================

    In this article, we will walk through the configuration of PAM authentication using the `[pam](../authentication-plugin-pam/index)` authentication plugin and user and group mapping with the `[pam\_user\_map](../user-and-group-mapping-with-pam/index)` PAM module. The primary authentication will be handled by the `[pam\_ldap](https://linux.die.net/man/5/pam_ldap)` PAM module, which performs LDAP authentication. We will also set up an OpenLDAP server.

 Hypothetical Requirements
-------------------------

 In this walkthrough, we are going to assume the following hypothetical requirements:

 * The LDAP user `foo` should be mapped to the MariaDB user `bar`. (`foo: bar`)
* Any LDAP user in the LDAP group `dba` should be mapped to the MariaDB user `dba`. (`@dba: dba`)

 Setting up the OpenLDAP Server
------------------------------

 Before we can use LDAP authentication, we first need to set up our OpenLDAP Server. This is usually done on a server that is completely separate from the database server.

 ### Installing the OpenLDAP Server and Client Components

 On the server acting as the OpenLDAP Server, first, we need to install the OpenLDAP components.

 On RHEL, CentOS, and other similar Linux distributions that use [RPM packages](../rpm/index), that would go like this:

 
```
sudo yum install openldap openldap-servers openldap-clients nss-pam-ldapd

```

### Configuring the OpenLDAP Server

 Next, let's to configure the OpenLDAP Server. The easiest way to do that is to copy the template configuration file that is included with the installation. In many installations, that will be at `/usr/share/openldap-servers/DB_CONFIG.example`. For example:

 
```
sudo cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
sudo chown ldap. /var/lib/ldap/DB_CONFIG

```

#### Configuring the OpenLDAP Port

 Sometimes it is useful to change the port used by OpenLDAP. For example, some cloud environments block well-known authentication services, so they block the default LDAP port.

 On some systems, the port can be changed by setting `SLAPD_URLS` in `/etc/sysconfig/slapd`:

 
```
SLAPD_URLS="ldapi:/// ldap://0.0.0.0:3306/"

```

I used `3306` because that is the port that is usually used by `mysqld`, so I know that it is not blocked.

 ### Starting the OpenLDAP Server

 Next, let's start the OpenLDAP Server and configure it to start on reboot. On `[systemd](../systemd/index)` systems, that would go like this:

 
```
sudo systemctl start slapd
sudo systemctl enable slapd

```

### Installing the Standard LDAP objectClasses

 In order to use LDAP for authentication, we also need to install some standard `objectClasses`, such as `posixAccount` and `posixGroup`. In LDAP, things like `objectClasses` are defined in `[LDIF](https://www.digitalocean.com/community/tutorials/how-to-use-ldif-files-to-make-changes-to-an-openldap-system)` files. In many installations, these specific `objectClasses` are defined in `/etc/openldap/schema/nis.ldif`. `nis.ldif` also depends on `core.ldif` and `cosine.ldif`. However, `core.ldif` is usually installed by default.

 We can install them with `[ldapmodify](http://www.openldap.org/software/man.cgi?query=ldapmodify&sektion=1&apropos=0&manpath=OpenLDAP+2.4-Release)`:

 
```
sudo ldapmodify -a -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
sudo ldapmodify -a -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif

```

### Creating the LDAP Directory Manager User

 Next, let’s create a directory manager user. We can do this by using OpenLDAP's [olc](https://www.openldap.org/doc/admin24/slapdconf2.html) configuration system to change the `[olcRootDN](https://www.openldap.org/doc/admin24/slapdconf2.html#olcRootDN:%20%3CDN%3E)` directive to the DN of the directory manager user, which means that the user will be a privileged LDAP user that is not subject to access controls. We will also set the root password for the user by changing the `[olcRootPW](https://www.openldap.org/doc/admin24/slapdconf2.html#olcRootPW:%20%3Cpassword%3E)` directive.

 We will also set the DN suffix for our backend LDAP database by changing the `[olcSuffix](https://www.openldap.org/doc/admin24/slapdconf2.html#olcSuffix:%20%3Cdn%20suffix%3E)` directive.

 Let’s use the `[slappasswd](http://www.openldap.org/software/man.cgi?query=slappasswd&apropos=0&sektion=8&manpath=OpenLDAP+2.4-Release&format=html)` utility to generate a password hash from a clear-text password. Simply execute:

 
```
slappasswd

```

This utility should provide a password hash that looks kind of like this: `{SSHA}AwT4jrvmokeCkbDrFAnGvzzjCMb7bvEl`

 OpenLDAP's [olc](https://www.openldap.org/doc/admin24/slapdconf2.html) configuration system also uses `[LDIF](https://www.digitalocean.com/community/tutorials/how-to-use-ldif-files-to-make-changes-to-an-openldap-system)` files. Now that we have the password hash, let’s create an `LDIF` file to create the directory manager user:

 
```
tee ~/setupDirectoryManager.ldif <<EOF
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * 
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read 
    by dn.base="cn=Manager,dc=support,dc=mariadb,dc=com" read 
    by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=support,dc=mariadb,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=support,dc=mariadb,dc=com

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}AwT4jrvmokeCkbDrFAnGvzzjCMb7bvEl

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange 
    by   dn="cn=Manager,dc=support,dc=mariadb,dc=com" write 
    by anonymous auth 
    by self write 
    by * none
olcAccess: {1}to dn.base="" 
    by * read
olcAccess: {2}to * 
    by dn="cn=Manager,dc=support,dc=mariadb,dc=com" write 
    by * read
EOF

```

Note that I am using the `dc=support,dc=mariadb,dc=com` domain for my directory. You can change this to whatever is relevant to you.

 Now let’s run the ldif file with `[ldapmodify](http://www.openldap.org/software/man.cgi?query=ldapmodify&sektion=1&apropos=0&manpath=OpenLDAP+2.4-Release)`:

 
```
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ~/setupDirectoryManager.ldif

```

We will use the new directory manager user to make changes to the LDAP directory after this step.

 ### Creating the Structure of the Directory

 Next, let's create the structure of the directory by creating parts of our tree.

 
```
tee ~/setupDirectoryStructure.ldif <<EOF
dn: dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: MariaDB Support Team
dc: support

dn: cn=Manager,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People

dn: ou=Groups,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Groups

dn: ou=System Users,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: organizationalUnit
ou: System Users
EOF

```

Now let’s use our new directory manager user and run the `[LDIF](https://www.digitalocean.com/community/tutorials/how-to-use-ldif-files-to-make-changes-to-an-openldap-system)` file with `[ldapmodify](http://www.openldap.org/software/man.cgi?query=ldapmodify&sektion=1&apropos=0&manpath=OpenLDAP+2.4-Release)`:

 
```
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/setupDirectoryStructure.ldif

```

### Creating the LDAP Users and Groups

 Let's go ahead and create the LDAP users and groups that we are using for this hypothetical scenario.

 First, let's create the the `foo` user:

 
```
tee ~/createFooUser.ldif <<EOF
dn: uid=foo,ou=People,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: foo
uid: foo
uidNumber: 16859
gidNumber: 100
homeDirectory: /home/foo
loginShell: /bin/bash
gecos: foo
userPassword: {crypt}x
shadowLastChange: -1
shadowMax: -1
shadowWarning: 0
EOF
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/createFooUser.ldif

```

Then let's create a couple users to go into the `dba` group:

 
```
tee ~/createDbaUsers.ldif <<EOF
dn: uid=gmontee,ou=People,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: gmontee
uid: gmontee
uidNumber: 16860
gidNumber: 100
homeDirectory: /home/gmontee
loginShell: /bin/bash
gecos: gmontee
userPassword: {crypt}x
shadowLastChange: -1
shadowMax: -1
shadowWarning: 0

dn: uid=bstillman,ou=People,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: bstillman
uid: bstillman
uidNumber: 16861
gidNumber: 100
homeDirectory: /home/bstillman
loginShell: /bin/bash
gecos: bstillman
userPassword: {crypt}x
shadowLastChange: -1
shadowMax: -1
shadowWarning: 0
EOF
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/createDbaUsers.ldif

```

Note that each of these users needs a password, so we can set it for each user with `[ldappasswd](http://www.openldap.org/software/man.cgi?query=ldappasswd&apropos=0&sektion=1&manpath=OpenLDAP+2.4-Release&format=html)`:

 
```
ldappasswd -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -S uid=foo,ou=People,dc=support,dc=mariadb,dc=com
ldappasswd -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -S uid=gmontee,ou=People,dc=support,dc=mariadb,dc=com
ldappasswd -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -S uid=bstillman,ou=People,dc=support,dc=mariadb,dc=com

```

And then let's create our `dba` group 

 
```
tee ~/createDbaGroup.ldif <<EOF
dn: cn=dba,ou=Groups,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: posixGroup
gidNumber: 678
EOF
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/createDbaGroup.ldif

```

And then let's add our two users to it:

 
```
tee ~/addUsersToDbaGroup.ldif <<EOF
dn: cn=dba,ou=Groups,dc=support,dc=mariadb,dc=com
changetype: modify
add: memberuid
memberuid: gmontee

dn: cn=dba,ou=Groups,dc=support,dc=mariadb,dc=com
changetype: modify
add: memberuid
memberuid: bstillman
EOF
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/addUsersToDbaGroup.ldif

```

We also need to create LDAP users with the same name as the `bar` and `dba` MariaDB users. See [here](../user-and-group-mapping-with-pam/index#pam-user-with-same-name-as-mapped-mariadb-user-must-exist) to read more about why. No one will be logging in as these users, so they do not need passwords. Instead of the `People` `organizationalUnit`, we will create them in the `System Users` `organizationalUnit`.

 
```
tee ~/createSystemUsers.ldif <<EOF
dn: uid=bar,ou=System Users,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: bar
uid: bar
uidNumber: 16862
gidNumber: 100
homeDirectory: /home/bar
loginShell: /bin/bash
gecos: bar
userPassword: {crypt}x
shadowLastChange: -1
shadowMax: -1
shadowWarning: 0

dn: uid=dba,ou=System Users,dc=support,dc=mariadb,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
cn: dba
uid: dba
uidNumber: 16863
gidNumber: 100
homeDirectory: /home/dba
loginShell: /bin/bash
gecos: dba
userPassword: {crypt}x
shadowLastChange: -1
shadowMax: -1
shadowWarning: 0
EOF
ldapmodify -a -x -D cn=Manager,dc=support,dc=mariadb,dc=com -W -f ~/createSystemUsers.ldif

```

Setting up the MariaDB Server
-----------------------------

 At this point, we can move onto setting up the MariaDB Server.

 ### Installing LDAP and PAM Libraries

 First, we need to make sure that the LDAP and PAM libraries are installed.

 On RHEL, CentOS, and other similar Linux distributions that use [RPM packages](../rpm/index), we need to install the following packages:

 
```
sudo yum install openldap-clients nss-pam-ldapd pam pam-devel

```

### Configuring LDAP

 Next, let's configure LDAP on the system. We can use `[authconfig](https://linux.die.net/man/8/authconfig)` for this:

 
```
sudo authconfig --enableldap \
   --enableldapauth \
   --ldapserver="ldap://172.30.0.238:3306" \
   --ldapbasedn="dc=support,dc=mariadb,dc=com" \
   --enablemkhomedir \
   --update

```

Be sure to replace `-–ldapserver` and `-–ldapbasedn` with values that are relevant for your environment.

 ### Installing the pam\_user\_map PAM Module

 The following steps apply to MariaDB Server in versions 10.2.32.7, 10.3.23., 10.4.13.6, 10.5.2 and earlier. In later releases, the pam\_user\_map PAM module is now included in the base install.

 Next, let's [install the pam\_user\_map PAM module](../user-and-group-mapping-with-pam/index#installing-the-pam_user_map-pam-module).

 Before the module can be compiled from source, we may need to install some dependencies.

 On RHEL, CentOS, and other similar Linux distributions that use [RPM packages](../rpm/index), we need to install `gcc` and `pam-devel`:

 
```
sudo yum install gcc pam-devel

```

On Debian, Ubuntu, and other similar Linux distributions that use [DEB packages](../installing-mariadb-deb-files/index), we need to install `gcc` and `libpam0g-dev`:

 
```
sudo apt-get install gcc libpam0g-dev

```

And then we can build and install the library with the following:

 
```
wget https://raw.githubusercontent.com/MariaDB/server/10.4/plugin/auth_pam/mapper/pam_user_map.c 
gcc pam_user_map.c -shared -lpam -fPIC -o pam_user_map.so 
sudo install --mode=0755 pam_user_map.so /lib64/security/ 

```

### Configuring the pam\_user\_map PAM Module

 Next, let's [configure the pam\_user\_map PAM module](../user-and-group-mapping-with-pam/index#configuring-the-pam_user_map-pam-module) based on our hypothetical requirements.

 The configuration file for the `pam_user_map` PAM module is `/etc/security/user_map.conf`. Based on our hypothetical requirements, ours would look like:

 
```
foo: bar
@dba:dba

```

### Installing the PAM Authentication Plugin

 Next, let's [install the `pam` authentication plugin](../authentication-plugin-pam/index#installing-the-plugin).

 Log into the MariaDB Server and execute the following:

 
```
INSTALL SONAME 'auth_pam';

```

### Configuring the PAM Service

 Next, let's [configure the PAM service](../authentication-plugin-pam/index#configuring-the-pam-service). We will call our service `mariadb`, so our PAM service configuration file will be located at `/etc/pam.d/mariadb` on most systems.

 #### Configuring PAM to Allow Only LDAP Authentication

 Since we are only doing LDAP authentication with the `[pam\_ldap](https://linux.die.net/man/5/pam_ldap)` PAM module and group mapping with the `pam_user_map` PAM module, our configuration file would look like this:

 
```
auth required pam_ldap.so
auth required pam_user_map.so
account required pam_ldap.so

```

#### Configuring PAM to Allow LDAP and Local Unix Authentication

 If we want to allow authentication from LDAP users **and** from local Unix users through `[pam\_unix](https://linux.die.net/man/8/pam_unix)`, while giving priority to the local users, then we could do this instead:

 
```
auth [success=1 new_authtok_reqd=1 default=ignore] pam_unix.so audit
auth required pam_ldap.so try_first_pass
auth required pam_user_map.so
account sufficient pam_unix.so audit
account required pam_ldap.so

```

##### Configuring the pam\_unix PAM Module

 If you also want to allow authentication from local Unix users, the `pam_unix` PAM module adds [some additional configuration steps](../authentication-plugin-pam/index#configuring-the-pam-service) on a lot of systems. We basically have to give the user that runs `mysqld` access to `/etc/shadow`.

 If the `mysql` user is running `mysqld`, then we can do that by executing the following:

 
```
sudo groupadd shadow
sudo usermod -a -G shadow mysql
sudo chown root:shadow /etc/shadow
sudo chmod g+r /etc/shadow

```

The [server needs to be restarted](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) for this change to take affect.

 Creating MariaDB Users
----------------------

 Next, let's [create the MariaDB users](../authentication-plugin-pam/index#creating-users). Remember that our PAM service is called `mariadb`.

 First, let's create the MariaDB user for the user mapping: `foo: bar`

 That means that we need to create a `bar` user:

 
```
CREATE USER 'bar'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'bar'@'%' ;

```

And then let's create the MariaDB user for the group mapping: `@dba: dba`

 That means that we need to create a `dba` user:

 
```
CREATE USER 'dba'@'%' IDENTIFIED BY 'strongpassword';
GRANT ALL PRIVILEGES ON *.* TO 'dba'@'%' ;

```

And then to allow for the user and group mapping, we need to [create an anonymous user that authenticates with the `pam` authentication plugin](../user-and-group-mapping-with-pam/index#creating-users) that is also able to `PROXY` as the `bar` and `dba` users. Before we can create the proxy user, we might need to [clean up some defaults](../create-user/index#fixing-a-legacy-default-anonymous-account):

 
```
DELETE FROM mysql.db WHERE User='' AND Host='%';
FLUSH PRIVILEGES;

```

And then let's create the anonymous proxy user:

 
```
CREATE USER ''@'%' IDENTIFIED VIA pam USING 'mariadb';
GRANT PROXY ON 'bar'@'%' TO ''@'%';
GRANT PROXY ON 'dba'@'%' TO ''@'%';

```

Testing our Configuration
-------------------------

 Next, let's test out our configuration by [verifying that mapping is occurring](../user-and-group-mapping-with-pam/index#verifying-that-mapping-is-occurring). We can verify this by logging in as each of our users and comparing the return value of `[USER()](../user/index)`, which is the original user name and the return value of `[CURRENT\_USER()](../current_user/index)`, which is the authenticated user name.

 ### Testing LDAP Authentication

 First, let's test out our `foo` user:

 
```
$ mysql -u foo -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 134
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+------------------------------------------------+----------------+
| USER()                                         | CURRENT_USER() |
+------------------------------------------------+----------------+
| foo@ip-172-30-0-198.us-west-2.compute.internal | bar@%          |
+------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `foo` LDAP user was properly mapped to the `bar` MariaDB user by looking at the return value of `[CURRENT\_USER()](../current_user/index)`.

 Then let's test out our `gmontee` user in the `dba` group:

 
```
$ mysql -u gmontee -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 135
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+----------------------------------------------------+----------------+
| USER()                                             | CURRENT_USER() |
+----------------------------------------------------+----------------+
| gmontee@ip-172-30-0-198.us-west-2.compute.internal | dba@%          |
+----------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

And then let's test out our `bstillman` user in the `dba` group:

 
```
$ mysql -u bstillman -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 136
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+------------------------------------------------------+----------------+
| USER()                                               | CURRENT_USER() |
+------------------------------------------------------+----------------+
| bstillman@ip-172-30-0-198.us-west-2.compute.internal | dba@%          |
+------------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `gmontee` and `bstillman` LDAP users in the `dba` LDAP group were properly mapped to the `dba` MariaDB user by looking at the return values of `[CURRENT\_USER()](../current_user/index)`.

 ### Testing Local Unix Authentication

 If you chose the option that also allowed local Unix authentication, then let's test that out. Let's create a Unix user and give the user a password real quick:

 
```
sudo useradd alice
sudo passwd alice

```

And let's also map this user to `dba`:

 
```
@dba:dba
foo: bar
alice: dba

```

And we know that the existing anonymous user already has the `PROXY` privilege granted to the `dba` user, so this should just work without any other configuration. Let's test it out:

 
```
$ mysql -u alice -h 172.30.0.198
[mariadb] Password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 141
Server version: 10.3.10-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> SELECT USER(), CURRENT_USER();
+--------------------------------------------------+----------------+
| USER()                                           | CURRENT_USER() |
+--------------------------------------------------+----------------+
| alice@ip-172-30-0-198.us-west-2.compute.internal | dba@%          |
+--------------------------------------------------+----------------+
1 row in set (0.000 sec)

```

We can verify that our `alice` Unix user was properly mapped to the `dba` MariaDB user by looking at the return values of `[CURRENT\_USER()](../current_user/index)`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-pam-authentication-and-user-mapping-with-ldap-authentication/>

Performance Schema table\_handles Table
=======================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `table_handles` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `table_handles` table contains table lock information. It uses the `wait/lock/table/sql/handler` instrument, which is enabled by default. 

 Information includes which table handles are open, which sessions are holding the locks, and how they are locked.

 The table is read-only, and [TRUNCATE TABLE](../truncate-table/index) cannot be performed on the table.

 The maximum number of opened table objects is determined by the [performance\_schema\_max\_table\_handles](../performance-schema-system-variables/index#performance_schema_max_table_handles) system variable.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| OBJECT\_TYPE | The table opened by a table handle. |
| OBJECT\_SCHEMA | The schema that contains the object. |
| OBJECT\_NAME | The name of the instrumented object. |
| OBJECT\_INSTANCE\_BEGIN | The table handle address in memory. |
| OWNER\_THREAD\_ID | The thread owning the table handle. |
| OWNER\_EVENT\_ID | The event which caused the table handle to be opened. |
| INTERNAL\_LOCK | The table lock used at the SQL level. |
| EXTERNAL\_LOCK | The table lock used at the storage engine level. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-table_handles-table/>

System Variables Added in MariaDB 11.0
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 11.0](../what-is-mariadb-110/index) series.

 


| Variable | Added |
| --- | --- |
| [innodb\_data\_file\_buffering](../innodb-system-variables/index#innodb_data_file_buffering) | [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/) |
| [innodb\_data\_file\_write\_through](../innodb-system-variables/index#innodb_data_file_write_through) | [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/) |
| [innodb\_log\_file\_write\_through](../innodb-system-variables/index#innodb_log_file_write_through) | [MariaDB 11.0.1](https://mariadb.com/kb/en/mariadb-11-0-1-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.11](../system-variables-added-in-mariadb-10-11/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-11-0/>

Performance Schema events\_transactions\_history\_long Table
============================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_history\_long table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_history_long` table contains the most recent completed transaction events that have ended globally, across all threads. 

 The number of records stored in the table is determined by the [performance\_schema\_events\_transactions\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_long_size) system variable, which is autosized on startup.

 If adding a completed transaction would cause the table to exceed this limit, the oldest row, regardless of thread, is discarded.

 The table contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| THREAD\_ID | bigint(20) unsigned | The thread associated with the event. |
| EVENT\_ID | bigint(20) unsigned | The event id associated with the event. |
| END\_EVENT\_ID | bigint(20) unsigned | This column is set to NULL when the event starts and updated to the thread current event number when the event ends. |
| EVENT\_NAME | varchar(128) | The name of the instrument from which the event was collected. This is a NAME value from the setup\_instruments table. |
| STATE | enum('ACTIVE', 'COMMITTED',' ROLLED BACK') | The current transaction state. The value is ACTIVE (after START TRANSACTION or BEGIN), COMMITTED (after COMMIT), or ROLLED BACK (after ROLLBACK). |
| TRX\_ID | bigint(20) unsigned | Unused. |
| GTID | varchar(64) | Transaction [GTID](../gtid/index), using the format DOMAIN-SERVER\_ID-SEQUENCE\_NO. |
| XID\_FORMAT\_ID | int(11) | XA transaction format ID for GTRID and BQUAL values. |
| XID\_GTRID | varchar(130) | XA global transaction ID. |
| XID\_BQUAL | varchar(130) | XA transaction branch qualifier. |
| XA\_STATE | varchar(64) | The state of the XA transaction. The value is ACTIVE (after XA START), IDLE (after XA END), PREPARED (after XA PREPARE), ROLLED BACK (after XA ROLLBACK), or COMMITTED (after XA COMMIT). |
| SOURCE | varchar(64) | The name of the source file containing the instrumented code that produced the event and the line number in the file at which the instrumentation occurs. |
| TIMER\_START | bigint(20) unsigned | The unit is picoseconds. When event timing started. NULL if event has no timing information. |
| TIMER\_END | bigint(20) unsigned | The unit is picoseconds. When event timing ended. NULL if event has no timing information. |
| TIMER\_WAIT | bigint(20) unsigned | The unit is picoseconds. Event duration. NULL if event has not timing information. |
| ACCESS\_MODE | enum('READ ONLY', 'READ WRITE') | Transaction access mode. |
| ISOLATION\_LEVEL | varchar(64) | Transaction isolation level. One of: REPEATABLE READ, READ COMMITTED, READ UNCOMMITTED, or SERIALIZABLE. |
| AUTOCOMMIT | enum('YES', 'NO') | NO |
| NUMBER\_OF\_SAVEPOINTS | bigint(20) unsigned | The number of SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_ROLLBACK\_TO\_SAVEPOINT | bigint(20) unsigned | The number of ROLLBACK\_TO\_SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_RELEASE\_SAVEPOINT | bigint(20) unsigned | The number of RELEASE\_SAVEPOINT statements issued during the transaction. |
| OBJECT\_INSTANCE\_BEGIN | bigint(20) unsigned | Unused. |
| NESTING\_EVENT\_ID | bigint(20) unsigned | The EVENT\_ID value of the event within which this event is nested. |
| NESTING\_EVENT\_TYPE | enum('TRANSACTION',' STATEMENT', 'STAGE', 'WAIT') | The nesting event type. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_history_long-table/>

Performance Schema users Table
==============================

    Description
-----------

 Each user that connects to the server is stored as a row in the `users` table, along with current and total connections.

 The table size is determined at startup by the value of the [performance\_schema\_users\_size](../performance-schema-system-variables/index#performance_schema_users_size) system variable. If this is set to `0`, user statistics will be disabled.

 


| Column | Description |
| --- | --- |
| `USER` | The connection's client user name for the connection, or `NULL` if an internal thread. |
| `CURRENT_CONNECTIONS` | Current connections for the user. |
| `TOTAL_CONNECTIONS` | Total connections for the user. |

 
Example
-------

 
```
SELECT * FROM performance_schema.users;
+------------------+---------------------+-------------------+
| USER             | CURRENT_CONNECTIONS | TOTAL_CONNECTIONS |
+------------------+---------------------+-------------------+
| debian-sys-maint |                   0 |                35 |
| NULL             |                  20 |                23 |
| root             |                   1 |                 2 |
+------------------+---------------------+-------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-users-table/>

Performance Schema setup\_objects Table
=======================================

    Description
-----------

 The `setup_objects` table determines whether objects are monitored by the performance schema or not. By default limited to 100 rows, this can be changed by setting the [performance\_schema\_setup\_objects\_size](../performance-schema-system-variables/index#performance_schema_setup_objects_size) system variable when the server starts.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `OBJECT_TYPE` | Type of object to instrument, currently only . Currently, only `TABLE'`, for base table. |
| `OBJECT_SCHEMA` | Schema containing the object, either the literal or `%` for any schema. |
| `OBJECT_NAME` | Name of the instrumented object, either the literal or `%` for any object. |
| `ENABLED` | Whether the object's events are instrumented or not. Can be disabled, in which case monitoring is not enabled for those objects. |
| `TIMED` | Whether the object's events are timed or not. Can be modified. |

 
When the Performance Schema looks for matches in the `setup_objects`, there may be more than one row matching, with different `ENABLED` and `TIMED` values. It looks for the most specific matches first, that is, it will first look for the specific database and table name combination, then the specific database, only then falling back to a wildcard for both.

 Rows can be added or removed from the table, while for existing rows, only the `TIMED` and `ENABLED` columns can be updated. By default, all tables except those in the `performance_schema`, `information_schema` and `mysql` databases are instrumented.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-setup_objects-table/>

Performance Schema events\_statements\_summary\_by\_digest Table
================================================================

    The [Performance Schema digest](../performance-schema-digests/index) is a hashed, normalized form of a statement with the specific data values removed. It allows statistics to be gathered for similar kinds of statements.

 The [Performance Schema](../performance-schema/index) `events_statements_summary_by_digest` table records statement events summarized by schema and digest. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `SCHEMA NAME` | Database name. Records are summarised together with `DIGEST`. |
| `DIGEST` | [Performance Schema digest](../performance-schema-digests/index). Records are summarised together with `SCHEMA NAME`. |
| `DIGEST TEXT` | The unhashed form of the digest. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_current` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |
| `FIRST_SEEN` | Time at which the digest was first seen. |
| `LAST_SEEN` | Time at which the digest was most recently seen. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 The `events_statements_summary_by_digest` table is limited in size by the [performance\_schema\_digests\_size](../performance-schema-system-variables/index#performance_schema_digests_size) system variable. Once the limit has been reached and the table is full, all entries are aggregated in a row with a `NULL` digest. The `COUNT_STAR` value of this `NULL` row indicates how many digests are recorded in the row and therefore gives an indication of whether `performance_schema_digests_size` should be increased to provide more accurate statistics.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_digest-table/>

System Variables Added in MariaDB 11.2
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 11.2](../what-is-mariadb-112/index) series.

 


| Variable | Added |
| --- | --- |
| [binlog\_do\_db](../replication-and-binary-log-system-variables/index#binlog_do_db) | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [binlog\_ignore\_db](../replication-and-binary-log-system-variables/index#binlog_ignore_db) | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [binlog\_row\_event\_max\_size](../replication-and-binary-log-system-variables/index#binlog_row_event_max_size) | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |
| [block\_encryption\_mode](../server-system-variables/index#block_encryption_mode) | [MariaDB 11.2.0](https://mariadb.com/kb/en/mariadb-11-2-0-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 11.1](../system-variables-added-in-mariadb-11-1/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-11-2/>

Performance Schema events\_transactions\_history Table
======================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_history table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_history` table contains the most recent completed transaction events for each thread. 

 The number of records stored per thread in the table is determined by the [performance\_schema\_events\_transactions\_history\_size](../performance-schema-system-variables/index#performance_schema_events_transactions_history_size) system variable, which is autosized on startup.

 If adding a completed transaction event would cause the table to exceed this limit, the oldest thread row is discarded.

 All of a thread's rows are discarded when the thread ends.

 The table contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| THREAD\_ID | bigint(20) unsigned | The thread associated with the event. |
| EVENT\_ID | bigint(20) unsigned | The event id associated with the event. |
| END\_EVENT\_ID | bigint(20) unsigned | This column is set to NULL when the event starts and updated to the thread current event number when the event ends. |
| EVENT\_NAME | varchar(128) | The name of the instrument from which the event was collected. This is a NAME value from the setup\_instruments table. |
| STATE | enum('ACTIVE', 'COMMITTED',' ROLLED BACK') | The current transaction state. The value is ACTIVE (after START TRANSACTION or BEGIN), COMMITTED (after COMMIT), or ROLLED BACK (after ROLLBACK). |
| TRX\_ID | bigint(20) unsigned | Unused. |
| GTID | varchar(64) | Transaction [GTID](../gtid/index), using the format DOMAIN-SERVER\_ID-SEQUENCE\_NO. |
| XID\_FORMAT\_ID | int(11) | XA transaction format ID for GTRID and BQUAL values. |
| XID\_GTRID | varchar(130) | XA global transaction ID. |
| XID\_BQUAL | varchar(130) | XA transaction branch qualifier. |
| XA\_STATE | varchar(64) | The state of the XA transaction. The value is ACTIVE (after XA START), IDLE (after XA END), PREPARED (after XA PREPARE), ROLLED BACK (after XA ROLLBACK), or COMMITTED (after XA COMMIT). |
| SOURCE | varchar(64) | The name of the source file containing the instrumented code that produced the event and the line number in the file at which the instrumentation occurs. |
| TIMER\_START | bigint(20) unsigned | The unit is picoseconds. When event timing started. NULL if event has no timing information. |
| TIMER\_END | bigint(20) unsigned | The unit is picoseconds. When event timing ended. NULL if event has no timing information. |
| TIMER\_WAIT | bigint(20) unsigned | The unit is picoseconds. Event duration. NULL if event has not timing information. |
| ACCESS\_MODE | enum('READ ONLY', 'READ WRITE') | Transaction access mode. |
| ISOLATION\_LEVEL | varchar(64) | Transaction isolation level. One of: REPEATABLE READ, READ COMMITTED, READ UNCOMMITTED, or SERIALIZABLE. |
| AUTOCOMMIT | enum('YES', 'NO') | NO |
| NUMBER\_OF\_SAVEPOINTS | bigint(20) unsigned | The number of SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_ROLLBACK\_TO\_SAVEPOINT | bigint(20) unsigned | The number of ROLLBACK\_TO\_SAVEPOINT statements issued during the transaction. |
| NUMBER\_OF\_RELEASE\_SAVEPOINT | bigint(20) unsigned | The number of RELEASE\_SAVEPOINT statements issued during the transaction. |
| OBJECT\_INSTANCE\_BEGIN | bigint(20) unsigned | Unused. |
| NESTING\_EVENT\_ID | bigint(20) unsigned | The EVENT\_ID value of the event within which this event is nested. |
| NESTING\_EVENT\_TYPE | enum('TRANSACTION',' STATEMENT', 'STAGE', 'WAIT') | The nesting event type. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_history-table/>

System Variables Added in MariaDB 10.10
=======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.10](../what-is-mariadb-1010/index) series.

 


| Variable | Added |
| --- | --- |
| [optimizer\_extra\_pruning\_depth](../server-system-variables/index#optimizer_extra_pruning_depth) | [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10-10-1-release-notes/) |
| [skip\_grant\_tables](../server-system-variables/index#skip_grant_tables) | [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10-10-1-release-notes/) |
| [wsrep\_allowlist](../galera-cluster-system-variables/index#wsrep_allowlist) | [MariaDB 10.10.1](https://mariadb.com/kb/en/mariadb-10-10-1-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.9](../system-variables-added-in-mariadb-109/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-10-10/>

System Variables Added in MariaDB 10.11
=======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.11](../what-is-mariadb-1011/index) series.

 


| Variable | Added |
| --- | --- |
| [log\_slow\_min\_examined\_row\_limit](../server-system-variables/index#log_slow_min_examined_row_limit) | [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) |
| [log\_slow\_query](../server-system-variables/index#log_slow_query) | [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) |
| [log\_slow\_query\_file](../server-system-variables/index#log_slow_query_file) | [MariaDB 10.11.1](https://mariadb.com/kb/en/mariadb-10-11-1-release-notes/) |
| [log\_slow\_query\_time](../server-system-variables/index#log_slow_query_time) | [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) |
| [replicate\_rewrite\_db](../replication-and-binary-log-system-variables/index#replicate_rewrite_db) | [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) |
| [system\_versioning\_insert\_history](../system-versioned-tables/index#system_versioning_insert_history) | [MariaDB 10.11.0](https://mariadb.com/kb/en/mariadb-10-11-0-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.9](../system-variables-added-in-mariadb-109/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-10-11/>

Status Variables Added in MariaDB 10.5
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.5](../what-is-mariadb-105/index) series.

 


| Variable | Added |
| --- | --- |
| [Innodb\_adaptive\_hash\_hash\_searches](../innodb-status-variables/index#innodb_adaptive_hash_hash_searches) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_adaptive\_hash\_non\_hash\_searches](../innodb-status-variables/index#innodb_adaptive_hash_non_hash_searches) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_background\_log\_sync](../innodb-status-variables/index#innodb_background_log_sync) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_buffer\_pool\_pages\_made\_not\_young](../innodb-status-variables/index#innodb_buffer_pool_pages_made_not_young) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_buffer\_pool\_pages\_made\_young](../innodb-status-variables/index#innodb_buffer_pool_pages_made_young) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_buffer\_pool\_pages\_old](../innodb-status-variables/index#innodb_buffer_pool_pages_old) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_buffer\_pool\_pages\_LRU\_flushed](../innodb-status-variables/index#innodb_buffer_pool_pages_LRU_flushed) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_buffered\_aio\_submitted](../innodb-status-variables/index#innodb_buffered_aio_submitted) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_checkpoint\_age](../innodb-status-variables/index#innodb_checkpoint_age) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_checkpoint\_max\_age](../innodb-status-variables/index#innodb_checkpoint_max_age) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_deadlocks](../innodb-status-variables/index#innodb_deadlocks) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_discarded\_delete\_marks](../innodb-status-variables/index#innodb_ibuf_discarded_delete_marks) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_discarded\_deletes](../innodb-status-variables/index#innodb_ibuf_discarded_deletes) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_discarded\_inserts](../innodb-status-variables/index#innodb_ibuf_discarded_inserts) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_free\_list](../innodb-status-variables/index#innodb_ibuf_free_list) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_merged\_delete\_marks](../innodb-status-variables/index#innodb_ibuf_merged_delete_marks) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_merged\_deletes](../innodb-status-variables/index#innodb_ibuf_merged_deletes) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_merged\_inserts](../innodb-status-variables/index#innodb_ibuf_merged_inserts) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_merges](../innodb-status-variables/index#innodb_ibuf_merges) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_segment\_size](../innodb-status-variables/index#innodb_ibuf_segment_size) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_ibuf\_size](../innodb-status-variables/index#innodb_ibuf_size) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_lsn\_current](../innodb-status-variables/index#innodb_lsn_current) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_lsn\_flushed](../innodb-status-variables/index#innodb_lsn_flushed) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_lsn\_last\_checkpoint](../innodb-status-variables/index#innodb_lsn_last_checkpoint) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_master\_thread\_active\_loops](../innodb-status-variables/index#innodb_master_thread_active_loops) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_master\_thread\_idle\_loops](../innodb-status-variables/index#innodb_master_thread_idle_loops) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_max\_trx\_id](../innodb-status-variables/index#innodb_max_trx_id) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_mem\_adaptive\_hash](../innodb-status-variables/index#innodb_mem_adaptive_hash) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [Innodb\_mem\_dictionary](../innodb-status-variables/index#innodb_mem_dictionary) | [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/) |
| [performance\_schema\_index\_stat\_lost](../performance-schema-status-variables/index#performance_schema_index_stat_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_memory\_classes\_lost](../performance-schema-status-variables/index#performance_schema_memory_classes_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_metadata\_lock\_lost](../performance-schema-status-variables/index#performance_schema_metadata_lock_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_nested\_statement\_lost](../performance-schema-status-variables/index#performance_schema_nested_statement_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_prepared\_statements\_lost](../performance-schema-status-variables/index#performance_schema_prepared_statements_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_program\_lost](../performance-schema-status-variables/index#performance_schema_program_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [performance\_schema\_table\_lock\_stat\_lost](../performance-schema-status-variables/index#performance_schema_table_lock_stat_lost) | [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/) |
| [S3\_pagecache\_blocks\_not\_flushed](../s3-storage-engine-status-variables/index#S3_pagecache_blocks_not_flushed) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [S3\_pagecache\_blocks\_unused](../s3-storage-engine-status-variables/index#S3_pagecache_blocks_unused) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [S3\_pagecache\_blocks\_used](../s3-storage-engine-status-variables/index#S3_pagecache_blocks_used) | [MariaDB 10.5](../what-is-mariadb-105/index) |
| [S3\_pagecache\_reads](../s3-storage-engine-status-variables/index#S3_pagecache_reads) | [MariaDB 10.5](../what-is-mariadb-105/index) |

 
See Also
--------

 * [System variables added in MariaDB 10.5](../system-variables-added-in-mariadb-105/index)
* [Status variables added in MariaDB 10.4](../status-variables-added-in-mariadb-104/index)
* [Status variables added in MariaDB 10.3](../status-variables-added-in-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-105/>

System Variables Added in MariaDB 10.9
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.9](../what-is-mariadb-109/index) series.

 


| Variable | Added |
| --- | --- |
| [rocksdb\_log\_dir](../myrocks-system-variables/index#rocksdb_log_dir) | [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/) |
| [wsrep\_status\_file](../galera-cluster-system-variables/index#wsrep_status_file) | [MariaDB 10.9.1](https://mariadb.com/kb/en/mariadb-1091-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.8](../system-variables-added-in-mariadb-10-8/index)
* [System Variables Added in MariaDB 10.6](../system-variables-added-in-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-10-9/>

Status Variables Added in MariaDB 10.4
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.4](../what-is-mariadb-104/index) series.

 


| Variable | Added |
| --- | --- |
| [Aborted\_connects\_preauth](../server-status-variables/index#aborted_connects_preauth) | [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) |
| [Com\_backup](../server-status-variables/index#com_backup) | [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/) |
| [Com\_backup\_lock](../server-status-variables/index#com_backup_lock) | [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/) |
| [Feature\_application\_time\_periods](../server-status-variables/index#feature_application_time_periods) | [MariaDB 10.4.5](https://mariadb.com/kb/en/mariadb-1045-release-notes/) |
| [wsrep\_applier\_thread\_count](../galera-cluster-status-variables/index#wsrep_applier_thread_count) | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) |
| [wsrep\_rollbacker\_thread\_count](../galera-cluster-status-variables/index#wsrep_rollbacker_thread_count) | [MariaDB 10.4.7](https://mariadb.com/kb/en/mariadb-1047-release-notes/) |

 
See Also
--------

 * [System Variables Added in MariaDB 10.4](../system-variables-added-in-mariadb-104/index)
* [Status Variables Added in MariaDB 10.5](../status-variables-added-in-mariadb-105/index)
* [Status Variables Added in MariaDB 10.3](../status-variables-added-in-mariadb-103/index)
* [Status Variables Added in MariaDB 10.2](../status-variables-added-in-mariadb-102/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-104/>

Status Variables Added in MariaDB 10.6
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.6](../what-is-mariadb-106/index) series.

 


| Variable | Added |
| --- | --- |
| [Innodb\_buffer\_pool\_pages\_lru\_freed](../innodb-status-variables/index#innodb_buffer_pool_pages_lru_freed) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |
| [resultset\_metadata\_skipped](../server-status-variables/index#resultset_metadata_skipped) | [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/) |

 
See Also
--------

 * [System variables added in MariaDB 10.6](../system-variables-added-in-mariadb-106/index)
* [Status variables added in MariaDB 10.5](../status-variables-added-in-mariadb-105/index)
* [Status variables added in MariaDB 10.4](../status-variables-added-in-mariadb-104/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-106/>

System and Status Variables Added By Major Unmaintained Release
================================================================

  

| Title | Description |
| --- | --- |
|  [Status Variables Added in MariaDB 10.3](../status-variables-added-in-mariadb-103/index) |  List of status variables that were added in the MariaDB 10.3 series.  |
|  [System Variables Added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index) |  List of system variables that were added in the MariaDB 10.3 series.  |
|  [Status Variables Added in MariaDB 10.2](../status-variables-added-in-mariadb-102/index) |  List of status variables that were added in the MariaDB 10.2 series.  |
|  [System Variables Added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index) |  List of system variables that were added in the MariaDB 10.2 series.  |
|  [Status Variables Added in MariaDB 10.1](../status-variables-added-in-mariadb-101/index) |  List of status variables that were added in the MariaDB 10.1 series.  |
|  [System Variables Added in MariaDB 10.1](../system-variables-added-in-mariadb-101/index) |  List of system variables that were added in the MariaDB 10.1 series.  |
|  [Status Variables Added in MariaDB 10.0](../status-variables-added-in-mariadb-100/index) |  List of status variables that were added in the MariaDB 10.0 series  |
|  [System Variables Added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index) |  List of system variables that were added in the MariaDB 10.0 series.  |
|  [System Variables Added in MariaDB 5.5](../system-variables-added-in-mariadb-55/index) |  List of system variables that were added in the MariaDB 5.5 series  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-and-status-variables-added-by-major-unmaintained-release/>

mysql.host Table
================

    ### Usage

 Until [MariaDB 5.5](../what-is-mariadb-55/index), the `mysql.host` table contained information about hosts and their related privileges. When determining permissions, if a matching record in the [mysql.db table](../mysqldb-table/index) had a blank host value, the mysql.host table would be examined. 

 This table is not affected by any [GRANT](../grant/index) statements, and had to be updated manually.

 Since [MariaDB 10.0](../what-is-mariadb-100/index), this table is no longer used.

 See [privileges](../grant/index) for a more complete view of the MariaDB privilege system.

 
**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table was created the [MyISAM](../myisam-storage-engine/index) storage engine.

 

**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table is no longer created. However if the table is created it will be used.

 
### Table fields

 The `mysql.host` table contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| `Host` | `char(60)` | NO | PRI |  | Host (together with `Db` makes up the unique identifier for this record. |
| `Db` | `char(64)` | NO | PRI |  | Database (together with `Host` makes up the unique identifier for this record. |
| `Select_priv` | `enum('N','Y')` | NO |  | N | Can perform [SELECT](../select/index) statements. |
| `Insert_priv` | `enum('N','Y')` | NO |  | N | Can perform [INSERT](../insert/index) statements. |
| `Update_priv` | `enum('N','Y')` | NO |  | N | Can perform [UPDATE](../update/index) statements. |
| `Delete_priv` | `enum('N','Y')` | NO |  | N | Can perform [DELETE](../delete/index) statements. |
| `Create_priv` | `enum('N','Y')` | NO |  | N | Can [CREATE TABLEs](../create-table/index). |
| `Drop_priv` | `enum('N','Y')` | NO |  | N | Can [DROP DATABASEs](../drop-database/index) or [DROP TABLEs](../drop-table/index). |
| `Grant_priv` | `enum('N','Y')` | NO |  | N | User can [grant](../grant/index) privileges they possess. |
| `References_priv` | `enum('N','Y')` | NO |  | N | Unused |
| `Index_priv` | `enum('N','Y')` | NO |  | N | Can create an index on a table using the [CREATE INDEX](../create-index/index) statement. Without the `INDEX` privilege, user can still create indexes when creating a table using the [CREATE TABLE](../create-table/index) statement if the user has have the `CREATE` privilege, and user can create indexes using the [ALTER TABLE](../alter-table/index) statement if they have the `ALTER` privilege. |
| `Alter_priv` | `enum('N','Y')` | NO |  | N | Can perform [ALTER TABLE](../alter-table/index) statements. |
| `Create_tmp_table_priv` | `enum('N','Y')` | NO |  | N | Can create temporary tables with the [CREATE TEMPORARY TABLE](../create-table/index) statement. |
| `Lock_tables_priv` | `enum('N','Y')` | NO |  | N | Acquire explicit locks using the [LOCK TABLES](../transactions-lock/index) statement; user also needs to have the `SELECT` privilege on a table in order to lock it. |
| `Create_view_priv` | `enum('N','Y')` | NO |  | N | Can create a view using the [CREATE\_VIEW](../create-view/index) statement. |
| `Show_view_priv` | `enum('N','Y')` | NO |  | N | Can show the [CREATE VIEW](../create-view/index) statement to create a view using the [SHOW CREATE VIEW](../show-create-view/index) statement. |
| `Create_routine_priv` | `enum('N','Y')` | NO |  | N | Can create stored programs using the [CREATE PROCEDURE](../create-procedure/index) and [CREATE FUNCTION](../create-function/index) statements. |
| `Alter_routine_priv` | `enum('N','Y')` | NO |  | N | Can change the characteristics of a stored function using the [ALTER FUNCTION](../alter-function/index) statement. |
| `Execute_priv` | `enum('N','Y')` | NO |  | N | Can execute [stored procedure](../stored-procedures/index) or functions. |
| `Trigger_priv` | `enum('N','Y')` | NO |  | N | Can execute [triggers](../triggers/index) associated with tables the user updates, execute the [CREATE TRIGGER](../create-trigger/index) and [DROP TRIGGER](../drop-trigger/index) statements. |

 ### How to Create

 If you need the functionality to only allow access to your database from a given set of hosts, you can create the host table with the following command:

 
```
CREATE TABLE IF NOT EXISTS mysql.host (Host char(60) binary DEFAULT '' NOT NULL,
Db char(64) binary DEFAULT '' NOT NULL,
Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
PRIMARY KEY /*Host*/ (Host,Db) )
engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin
comment='Host privileges;  Merged with database privileges';

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlhost-table/>

DROP LOGFILE GROUP
==================

    
The `DROP LOGFILE GROUP` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. See [MDEV-19295](https://jira.mariadb.org/browse/MDEV-19295) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-logfile-group/>

DROP PACKAGE
============

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
DROP PACKAGE [IF EXISTS]  [ db_name . ] package_name

```
 Description
-----------

 The `DROP PACKAGE` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 The `DROP PACKAGE` statement drops a stored package entirely:

 * Drops the package specification (earlier created using the [CREATE PACKAGE](../create-package/index) statement).
* Drops the package implementation, if the implementation was already created using the [CREATE PACKAGE BODY](../create-package-body/index) statement.

 See Also
--------

 * [SHOW CREATE PACKAGE](../show-create-package/index)
* [CREATE PACKAGE](../create-package/index)
* [CREATE PACKAGE BODY](../create-package-body/index)
* [DROP PACKAGE BODY](../drop-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-package/>

DROP PACKAGE BODY
=================

    
**MariaDB starting with [10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/)**Oracle-style packages were introduced in [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/).

 
Syntax
------

 
```
DROP PACKAGE BODY [IF EXISTS]  [ db_name . ] package_name

```
 Description
-----------

 The `DROP PACKAGE BODY` statement can be used when [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index) is set.

 The `DROP PACKAGE BODY` statement drops the package body (i.e the implementation), previously created using the [CREATE PACKAGE BODY](../create-package-body/index) statement.

 Note, `DROP PACKAGE BODY` drops only the package implementation, but does not drop the package specification. Use [DROP PACKAGE](../drop-package/index) to drop the package entirely (i.e. both implementation and specification).

 See also
--------

 * [CREATE PACKAGE](../create-package/index)
* [SHOW CREATE PACKAGE](../show-create-package/index)
* [DROP PACKAGE](../drop-package/index)
* [CREATE PACKAGE BODY](../create-package-body/index)
* [SHOW CREATE PACKAGE BODY](../show-create-package-body/index)
* [Oracle SQL\_MODE](../sql_modeoracle-from-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-package-body/>

DROP TABLESPACE
===============

    
The `DROP TABLESPACE` statement is not supported by MariaDB. It was originally inherited from MySQL NDB Cluster. In MySQL 5.7 and later, the statement is also supported for InnoDB. However, MariaDB has chosen not to include that specific feature. See [MDEV-19294](https://jira.mariadb.org/browse/MDEV-19294) for more information.

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/drop-tablespace/>

HANDLER for MEMORY Tables
=========================

    This article explains how to use [HANDLER commands](../handler-commands/index) efficiently with [MEMORY/HEAP](../memory-storage-engine/index) tables.

 If you want to scan a table for over different key values, not just search for exact key values, you should create your keys with 'USING BTREE':

 
```
CREATE TABLE t1 (a INT, b INT, KEY(a), KEY b USING BTREE (b)) engine=memory;

```

In the above table, `a` is a [HASH](../storage-engine-index-types/index#hash-indexes) key that only supports exact matches (=) while `b` is a [BTREE](../storage-engine-index-types/index#b-tree-indexes) key that you can use to scan the table in key order, starting from start or from a given key value.

 The limitations for HANDLER READ with Memory|HEAP tables are:

 Limitations for HASH keys
-------------------------

 * You must use all key parts when searching for a row.
* You can't do a key scan of all values. You can only find all rows with the same key value.
* READ NEXT gives error 1031 if the tables changed since last read.

 Limitations for BTREE keys
--------------------------

 * READ NEXT gives error 1031 if the tables changed since last read. This limitation can be lifted in the future.

 Limitations for table scans
---------------------------

 * READ NEXT gives error 1031 if the table was truncated since last READ call.

 See also
--------

 See also the the limitations listed in [HANDLER commands](../handler-commands/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/handler-for-memory-tables/>

Using MariaDB with Your Programs (API)
=======================================

  

| Title | Description |
| --- | --- |
|  [Error Codes](../error-codes/index) |  MariaDB error codes and SQLSTATE codes  |
|  [libMariaDB](../libmariadb/index) |  |
|  [libmysqld](../libmysqld/index) |  The Embedded, Stand-Alone MariaDB Server.  |
|  [Non-Blocking Client Library](../non-blocking-client-library/index) |  Non-blocking client library documentation.  |
|  [Progress Reporting](../progress-reporting/index) |  Progress reporting for long running commands.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-mariadb-with-your-programs-api/>

Subquery Optimizations Map
==========================

    Below is a map showing all types of subqueries allowed in the SQL language, and the optimizer strategies available to handle them.

 * Uncolored areas represent different kinds of subqueries, for example:
	+ Subqueries that have form `x IN (SELECT ...)`
	+ Subqueries that are in the `FROM` clause
	+ .. and so forth
* The size of each uncolored area roughly corresponds to how important (i.e. frequently used) that kind of subquery is. For example, `x IN (SELECT ...)` queries are the most important, and `EXISTS (SELECT ...)` are relatively unimportant.
* Colored areas represent optimizations/execution strategies that are applied to handle various kinds of subqueries.
* The color of optimization indicates which version of MySQL/MariaDB it was available in (see legend below)

 ![subquery-map-2013]

 Some things are not on the map:

 * MariaDB doesn't evaluate expensive subqueries when doing optimization (this means, EXPLAIN is always fast). MySQL 5.6 has made a progress in this regard but its optimizer will still evaluate certain kinds of subqueries (for example, scalar-context subqueries used in range predicates)

 Links to pages about individual optimizations:
----------------------------------------------

 * [IN->EXISTS](../non-semi-join-subquery-optimizations/index#the-in-to-exists-transformation)
* [Subquery Caching](../subquery-cache/index)

 * [Semi-join optimizations](../semi-join-subquery-optimizations/index)
	+ [Table pullout](../table-pullout-optimization/index)
	+ [FirstMatch](../firstmatch-strategy/index)
	+ [Materialization, +scan, +lookup](../semi-join-materialization-strategy/index)
	+ [LooseScan](../loosescan-strategy/index)
	+ [DuplicateWeedout execution strategy](../duplicateweedout-strategy/index)

 * Non-semi-join [Materialization](../non-semi-join-subquery-optimizations/index#materialization-for-non-correlated-in-subqueries) (including NULL-aware and partial matching)

 * Derived table optimizations
	+ [Derived table merge](../derived-table-merge-optimization/index)
	+ [Derived table with keys](../derived-table-with-key-optimization/index)

 See also
--------

 * [Subquery optimizations in MariaDB 5.3](../what-is-mariadb-53/index#subquery-optimizations)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subquery-optimizations-map/>

Query Optimizer
================

   Articles about the MariaDB query optimizer

  

| Title | Description |
| --- | --- |
|  [Optimization Strategies](../optimization-strategies/index) |  Various optimization strategies used by the query optimizer.  |
|  [Optimizations for Derived Tables](../optimizations-for-derived-tables/index) |  Optimizations for derived tables, or subqueries in the FROM clause  |
|  [Optimizer Trace](../mariadb-internals-documentation-optimizer-trace/index) |  Produces a JSON trace with decision info taken by the optimizer during the optimization phase.  |
|  [Statistics for Optimizing Queries](../statistics-for-optimizing-queries/index) |  Different statistics provided by MariaDB to help you optimize your queries  |
|  [Table Elimination](../table-elimination/index) |  Resolving queries without accessing some of the tables the query refers to  |
|  [Block-Based Join Algorithms](../block-based-join-algorithms/index) |  Algorithms that employ a join buffer for the first join before starting to look in the second.  |
|  [Condition Selectivity Computation Internals](../condition-selectivity-computation-internals/index) |  How the MariaDB optimizer computes condition selectivities.  |
|  [Extended Keys](../extended-keys/index) |  Optimization using InnoDB key components to generate more efficient execution plans.  |
|  [MIN/MAX optimization](../minmax-optimization/index) |  How MIN and MAX are optimized  |
|  [Optimizer Debugging With GDB](../optimizer-debugging-with-gdb/index) |  Useful things for debugging optimizer code with gdb.  |
|  [Rowid Filtering Optimization](../rowid-filtering-optimization/index) |  Rowid filtering is an optimization available from MariaDB 10.4.  |
|  [The Optimizer Cost Model from MariaDB 11.0](../the-optimizer-cost-model-from-mariadb-11-0/index) |  The optimizer cost model in MariaDB 11.0.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-internals-documentation-query-optimizer/>

Merging into MariaDB
=====================

   This category explains how we merge various source trees into MariaDB

  

| Title | Description |
| --- | --- |
|  [Merging with a Merge Tree](../merging-with-a-merge-tree/index) |  Applies to XtraDB, InnoDB-5.6, Performance Schema 5.6, SphinxSE, PCRE  |
|  [Creating a New Merge Tree](../creating-a-new-merge-tree/index) |  Obsolete article on creating a new merge tree in bzr  |
|  [Merging from MySQL (obsolete)](../merging-from-mysql-obsolete/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [Merging TokuDB (obsolete)](../merging-tokudb-obsolete/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [Merging New XtraDB Releases (obsolete)](../merging-new-xtradb-releases-obsolete/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-internals-documentation-merging-into-mariadb/>

MariaDB Source Code Internals
==============================

   Articles about MariaDB source code and related internals.

  

| Title | Description |
| --- | --- |
|  [MariaDB Memory Usage](../mariadb-memory-usage/index) |  How MariaDB uses memory.  |
|  [Stored Procedure Internals](../stored-procedure-internals/index) |  Internal implementation of MariaDB stored procedures.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-source-code-internals/>

Information Schema INNODB\_MUTEXES Table
========================================

    The `INNODB_MUTEXES` table monitors mutex and rw locks waits. It has the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Name of the lock, as it appears in the source code. |
| `CREATE_FILE` | File name of the mutex implementation. |
| `CREATE_LINE` | Line number of the mutex implementation. |
| `OS_WAITS` | How many times the mutex occurred. |

 
The `CREATE_FILE` and `CREATE_LINE` columns depend on the InnoDB/XtraDB version.

 Note that since [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/), the table has only been providing information about rw\_lock\_t, not any mutexes. From [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) until [MariaDB 10.2.32](https://mariadb.com/kb/en/mariadb-10232-release-notes/), [MariaDB 10.3.23](https://mariadb.com/kb/en/mariadb-10323-release-notes/), [MariaDB 10.4.13](https://mariadb.com/kb/en/mariadb-10413-release-notes/) and [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/), the `NAME` column was not populated ([MDEV-21636](https://jira.mariadb.org/browse/MDEV-21636)).

 The [SHOW ENGINE INNODB STATUS](../show-engine/index#show-engine-innodb-mutex) statement provides similar information.

 Examples
--------

 
```
SELECT * FROM INNODB_MUTEXES;
+------------------------------+---------------------+-------------+----------+
| NAME                         | CREATE_FILE         | CREATE_LINE | OS_WAITS |
+------------------------------+---------------------+-------------+----------+
| &dict_sys->mutex             | dict0dict.cc        |         989 |        2 |
| &buf_pool->flush_state_mutex | buf0buf.cc          |        1388 |        1 |
| &log_sys->checkpoint_lock    | log0log.cc          |        1014 |        2 |
| &block->lock                 | combined buf0buf.cc |        1120 |        1 |
+------------------------------+---------------------+-------------+----------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_mutexes-table/>

Condition Pushdown Into IN subqueries
=====================================

    This article describes Condition Pushdown into IN subqueries as implemented in [MDEV-12387](https://jira.mariadb.org/browse/MDEV-12387).

 [optimizer\_switch](../optimizer-switch/index) flag name: `condition_pushdown_for_subquery`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/condition-pushdown-into-in-subqueries/>

Table Pullout Optimization
==========================

    Table pullout is an optimization for [Semi-join subqueries](../semi-join-subquery-optimizations/index).

 The idea of Table Pullout
-------------------------

 Sometimes, a subquery can be re-written as a join. For example:   
  


 
```
select *
from City 
where City.Country in (select Country.Code
                       from Country 
                       where Country.Population < 100*1000);

```

If we know that there can be, at most, one country with with a given value of `Country.Code` (we can tell that if we see that table Country has a primary key or unique index over that column), we can re-write this query as:

 
```
select City.* 
from 
  City, Country 
where
 City.Country=Country.Code AND Country.Population < 100*1000;

```

Table pullout in action
-----------------------

 If one runs [EXPLAIN](../explain/index) for the above query in MySQL 5.1-5.6 or [MariaDB 5.1](../what-is-mariadb-51/index)-5.2, they'll get this plan:

 
```
MySQL [world]> explain select * from City where City.Country in (select Country.Code from Country where Country.Population < 100*1000);
+----+--------------------+---------+-----------------+--------------------+---------+---------+------+------+-------------+
| id | select_type        | table   | type            | possible_keys      | key     | key_len | ref  | rows | Extra       |
+----+--------------------+---------+-----------------+--------------------+---------+---------+------+------+-------------+
|  1 | PRIMARY            | City    | ALL             | NULL               | NULL    | NULL    | NULL | 4079 | Using where |
|  2 | DEPENDENT SUBQUERY | Country | unique_subquery | PRIMARY,Population | PRIMARY | 3       | func |    1 | Using where |
+----+--------------------+---------+-----------------+--------------------+---------+---------+------+------+-------------+
2 rows in set (0.00 sec)

```

It shows that the optimizer is going to do a full scan on table `City`, and for each city it will do a lookup in table `Country`.

 If one runs the same query in [MariaDB 5.3](../what-is-mariadb-53/index), they will get this plan:

 
```
MariaDB [world]> explain select * from City where City.Country in (select Country.Code from Country where Country.Population < 100*1000);
+----+-------------+---------+-------+--------------------+------------+---------+--------------------+------+-----------------------+
| id | select_type | table   | type  | possible_keys      | key        | key_len | ref                | rows | Extra                 |
+----+-------------+---------+-------+--------------------+------------+---------+--------------------+------+-----------------------+
|  1 | PRIMARY     | Country | range | PRIMARY,Population | Population | 4       | NULL               |   37 | Using index condition |
|  1 | PRIMARY     | City    | ref   | Country            | Country    | 3       | world.Country.Code |   18 |                       |
+----+-------------+---------+-------+--------------------+------------+---------+--------------------+------+-----------------------+
2 rows in set (0.00 sec)

```

The interesting parts are:

 * Both tables have `select_type=PRIMARY`, and `id=1` as if they were in one join.
* The `Country` table is first, followed by the `City` table.

 Indeed, if one runs EXPLAIN EXTENDED; SHOW WARNINGS, they will see that the subquery is gone and it was replaced with a join:

 
```
MariaDB [world]> show warnings\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: select `world`.`City`.`ID` AS `ID`,`world`.`City`.`Name` AS 
`Name`,`world`.`City`.`Country` AS `Country`,`world`.`City`.`Population` AS 
`Population` 

  
   from `world`.`City` join `world`.`Country` where 


((`world`.`City`.`Country` = `world`.`Country`.`Code`) and (`world`.`Country`.
`Population` < (100 * 1000)))
1 row in set (0.00 sec)

```

Changing the subquery into a join allows feeding the join to the join optimizer, which can make a choice between two possible join orders:

 1. City -> Country
2. Country -> City

 as opposed to the single choice of 

 1. City->Country

 which we had before the optimization.

 In the above example, the choice produces a better query plan. Without pullout, the query plan with a subquery would read `(4079 + 1*4079)=8158` table records. With table pullout, the join plan would read `(37 + 37 * 18) = 703` rows. Not all row reads are equal, but generally, reading `10` times fewer table records is faster.

 Table pullout fact sheet
------------------------

 * Table pullout is possible only in semi-join subqueries.
* Table pullout is based on `UNIQUE`/`PRIMARY` key definitions.
* Doing table pullout does not cut off any possible query plans, so MariaDB will always try to pull out as much as possible.
* Table pullout is able to pull individual tables out of subqueries to their parent selects. If all tables in a subquery have been pulled out, the subquery (i.e. its semi-join) is removed completely.
* One common bit of advice for optimizing MySQL has been "If possible, rewrite your subqueries as joins". Table pullout does exactly that, so manual rewrites are no longer necessary.

 Controlling table pullout
-------------------------

 There is no separate @@optimizer\_switch flag for table pullout. Table pullout can be disabled by switching off all semi-join optimizations with `SET @@optimizer_switch='semijoin=off'` command.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-pullout-optimization/>

Optimizing GROUP BY and DISTINCT Clauses in Subqueries
======================================================

    A DISTINCT clause and a GROUP BY without a corresponding HAVING clause have no meaning in IN/ALL/ANY/SOME/EXISTS subqueries. The reason is that IN/ALL/ANY/SOME/EXISTS only check if an outer row satisfies some condition with respect to all or any row in the subquery result. Therefore is doesn't matter if the subquery has duplicate result rows or not - if some condition is true for some row of the subquery, this condition will be true for all duplicates of this row. Notice that GROUP BY without a corresponding HAVING clause is equivalent to a DISTINCT.

 [MariaDB 5.3](../what-is-mariadb-53/index) and later versions automatically remove DISTINCT and GROUP BY without HAVING if these clauses appear in an IN/ALL/ANY/SOME/EXISTS subquery. For instance:

 
```
select * from t1
where t1.a > ALL(select distinct b from t2 where t2.c > 100)

```

is transformed to:

 
```
select * from t1
where t1.a > ALL(select b from t2 where t2.c > 100)

```

Removing these unnecessary clauses allows the optimizer to find more efficient query plans because it doesn't need to take care of post-processing the subquery result to satisfy DISTINCT / GROUP BY.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizing-group-by/>

Threadpool Benchmarks
=====================

     Here are some benchmarks of some development threadpool code (the [5.5 threadpool](../thread-pool-in-mariadb/index)).

 The benchmarks were run on three machines:

 * facebook-maria1 (Linux, 16 cores)
* pitbull (Linux, 24 cores)
* windows (Windows, 8 cores)

 Sysbench 0.4 was used to run some "unit" OLTP tests (point-select and update-nokey), as well as the "classic" OLTP-readonly and OLTP-readwrite. All tests were run with the number of concurrent clients ranging from 16 to 4096, with warm cache, with the sysbench table having 1M records.

 The results are quite different on all of the machines tested (the machines are very different, in terms of cores, IO etc), yet threadpool has a positive effect on all 3 machines, and the positive effect seems to grow with the number of cores.

 Some notes on how the benchmarks were run:

 1. The benchmark client and server used different CPUs - ('taskset' (Linux), or 'start /affinity' (Windows) were used to run the benchmark client on `#CPUs/4`, the rest of CPUs were used by the server). On the Linux boxes, `--thread_pool_size=<N>` (where N is number of cores dedicated to the server) was used.
2. `innodb_flush_log_at_trx_commit=0` and `innodb_flush_method=ALL_O_DIRECT` was used to avoid extensive fsyncing, which is ok for the purposes of the testing for this.
3. Every "write" benchmark (`oltp_rw` and `update_nokey`) started with a new server (i.e. kill mysqld, remove innodb files, and restart mysqld for each test). Every "read" benchmark, on the other hand, reused the same running server instance. Starting afresh with a new server on write benchmarks is done mainly to eliminate the effects of the purge lag.
4. The results are in queries-per-second (QPS).

 OLTP\_RO
--------

 ### OLTP\_RO facebook-maria1

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 3944 | 4725 | 4878 | 4863 | 4732 | 4554 | 4345 | 4103 | 1670 |
| threadpool | 3822 | 4955 | 4991 | 5017 | 4908 | 4716 | 4610 | 4307 | 2962 |

 
![oltp-ro-facebook-maria1]

 ### OLTP\_RO pitbull

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 6754 | 7905 | 8152 | 7948 | 7924 | 7587 | 5313 | 3827 | 208 |
| threadpool | 6566 | 7725 | 8108 | 8079 | 7976 | 7793 | 7429 | 6523 | 4456 |

 
![oltp_ro-pitbull]

 ### OLTP\_RO Windows

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 1822 | 1831 | 1825 | 1829 | 1816 | 1879 | 1866 | 1783 | 987 |
| threadpool | 2019 | 2049 | 2024 | 1992 | 1924 | 1897 | 1855 | 1825 | 1403 |

 
![oltp_ro-windows]

 OLTP\_RW
--------

 ### OLTP\_RW facebook-maria1

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 2833 | 3510 | 3545 | 3420 | 3259 | 2818 | 1788 | 820 | 113 |
| threadpool | 3163 | 3590 | 3498 | 3459 | 3354 | 3117 | 2190 | 1064 | 506 |

 
![oltp_rw-facebook-maria1]

 ### OLTP\_RW pitbull

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 4561 | 5316 | 5332 | 3512 | 2874 | 2476 | 1380 | 265 | 53 |
| threadpool | 4504 | 5382 | 5694 | 5567 | 5302 | 4514 | 2548 | 1186 | 484 |

 
![oltp_rw-pitbull]

 ### OLTP\_RW Windows

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 1480 | 1498 | 1472 | 1477 | 1456 | 1371 | 731 | 328 | 82 |
| threadpool | 1449 | 1523 | 1527 | 1492 | 1443 | 1409 | 1365 | 1240 | 862 |

 
![oltp_rw-windows]

 POINT\_SELECT
-------------

 ### POINT\_SELECT facebook-maria1

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 91322 | 113116 | 115418 | 114484 | 111169 | 104612 | 26902 | 12843 | 5038 |
| threadpool | 100359 | 115618 | 118115 | 120136 | 119165 | 113931 | 110787 | 109970 | 104985 |

 
![point_select-facebook-maria1]

 ### POINT\_SELECT pitbull

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 148673 | 161547 | 169747 | 172083 | 69036 | 42041 | 21775 | 4368 | 282 |
| threadpool | 143222 | 167069 | 167270 | 165977 | 164983 | 158410 | 148690 | 147107 | 143934 |

 
![point_select-pitbull]

 ### POINT\_SELECT Windows

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 39734 | 42885 | 44448 | 44478 | 41720 | 38196 | 36844 | 35404 | 23306 |
| threadpool | 42143 | 45679 | 47066 | 47753 | 46720 | 44215 | 43677 | 43093 | 44364 |

 
![point_select-windows]

 UPDATE\_NOKEY
-------------

 ### UPDATE\_NOKEY facebook-maria1

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 60165 | 65761 | 67727 | 57232 | 47612 | 26341 | 8981 | 3265 | 389 |
| threadpool | 65092 | 68683 | 67053 | 64141 | 64815 | 63047 | 63346 | 63638 | 62843 |

 
![update_nokey-facebook-maria1]

 ### UPDATE\_NOKEY pitbull

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 65213 | 71680 | 19418 | 13008 | 11155 | 8742 | 5645 | 635 | 332 |
| threadpool | 64902 | 70236 | 70037 | 68926 | 69930 | 69929 | 67099 | 62376 | 17766 |

 
![update_nokey-pitbull]

 ### UPDATE\_NOKEY Windows

 


| concurrent clients | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| thread per connection | 24790 | 25634 | 25639 | 25309 | 24754 | 19420 | 5249 | 2361 | 824 |
| threadpool | 25251 | 25259 | 25406 | 25327 | 24850 | 23818 | 23137 | 23003 | 22047 |

 
![update_nokey-windows]

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/threadpool-benchmarks/>

Information Schema INNODB\_BUFFER\_POOL\_STATS Table
====================================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_POOL_STATS` table contains information about pages in the [buffer pool](../xtradbinnodb-memory-buffer/index), similar to what is returned with the `[SHOW ENGINE INNODB STATUS](../show-engine-innodb-status/index)` statement.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `POOL_ID` | Buffer Pool identifier. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) returns a value of 0, since multiple InnoDB buffer pool instances has been removed. |
| `POOL_SIZE` | Size in pages of the buffer pool. |
| `FREE_BUFFERS` | Number of free pages in the buffer pool. |
| `DATABASE_PAGES` | Total number of pages in the buffer pool. |
| `OLD_DATABASE_PAGES` | Number of pages in the *old* sublist. |
| `MODIFIED_DATABASE_PAGES` | Number of dirty pages. |
| `PENDING_DECOMPRESS` | Number of pages pending decompression. |
| `PENDING_READS` | Pending buffer pool level reads. |
| `PENDING_FLUSH_LRU` | Number of pages in the LRU pending flush. |
| `PENDING_FLUSH_LIST` | Number of pages in the flush list pending flush. |
| `PAGES_MADE_YOUNG` | Pages moved from the *old* sublist to the *new* sublist. |
| `PAGES_NOT_MADE_YOUNG` | Pages that have remained in the *old* sublist without moving to the *new* sublist. |
| `PAGES_MADE_YOUNG_RATE` | Hits that cause blocks to move to the top of the *new* sublist. |
| `PAGES_MADE_NOT_YOUNG_RATE` | Hits that do not cause blocks to move to the top of the *new* sublist due to the `[innodb\_old\_blocks](../xtradbinnodb-server-system-variables/index#innodb_old_blocks_time)` delay not being met. |
| `NUMBER_PAGES_READ` | Number of pages read. |
| `NUMBER_PAGES_CREATED` | Number of pages created. |
| `NUMBER_PAGES_WRITTEN` | Number of pages written. |
| `PAGES_READ_RATE` | Number of pages read since the last printout divided by the time elapsed, giving pages read per second. |
| `PAGES_CREATE_RATE` | Number of pages created since the last printout divided by the time elapsed, giving pages created per second. |
| `PAGES_WRITTEN_RATE` | Number of pages written since the last printout divided by the time elapsed, giving pages written per second. |
| `NUMBER_PAGES_GET` | Number of logical read requests. |
| `HIT_RATE` | Buffer pool hit rate. |
| `YOUNG_MAKE_PER_THOUSAND_GETS` | For every 1000 gets, the number of pages made young. |
| `NOT_YOUNG_MAKE_PER_THOUSAND_GETS` | For every 1000 gets, the number of pages not made young. |
| `NUMBER_PAGES_READ_AHEAD` | Number of pages read ahead. |
| `NUMBER_READ_AHEAD_EVICTED` | Number of pages read ahead by the read-ahead thread that were later evicted without being accessed by any queries. |
| `READ_AHEAD_RATE` | Pages read ahead since the last printout divided by the time elapsed, giving read-ahead rate per second. |
| `READ_AHEAD_EVICTED_RATE` | Read-ahead pages not accessed since the last printout divided by time elapsed, giving the number of read-ahead pages evicted without access per second. |
| `LRU_IO_TOTAL` | Total least-recently used I/O. |
| `LRU_IO_CURRENT` | Least-recently used I/O for the current interval. |
| `UNCOMPRESS_TOTAL` | Total number of pages decompressed. |
| `UNCOMPRESS_CURRENT` | Number of pages decompressed in the current interval |

 
Examples
--------

 
```
DESC information_schema.innodb_buffer_pool_stats;
+----------------------------------+---------------------+------+-----+---------+-------+
| Field                            | Type                | Null | Key | Default | Extra |
+----------------------------------+---------------------+------+-----+---------+-------+
| POOL_ID                          | bigint(21) unsigned | NO   |     | 0       |       |
| POOL_SIZE                        | bigint(21) unsigned | NO   |     | 0       |       |
| FREE_BUFFERS                     | bigint(21) unsigned | NO   |     | 0       |       |
| DATABASE_PAGES                   | bigint(21) unsigned | NO   |     | 0       |       |
| OLD_DATABASE_PAGES               | bigint(21) unsigned | NO   |     | 0       |       |
| MODIFIED_DATABASE_PAGES          | bigint(21) unsigned | NO   |     | 0       |       |
| PENDING_DECOMPRESS               | bigint(21) unsigned | NO   |     | 0       |       |
| PENDING_READS                    | bigint(21) unsigned | NO   |     | 0       |       |
| PENDING_FLUSH_LRU                | bigint(21) unsigned | NO   |     | 0       |       |
| PENDING_FLUSH_LIST               | bigint(21) unsigned | NO   |     | 0       |       |
| PAGES_MADE_YOUNG                 | bigint(21) unsigned | NO   |     | 0       |       |
| PAGES_NOT_MADE_YOUNG             | bigint(21) unsigned | NO   |     | 0       |       |
| PAGES_MADE_YOUNG_RATE            | double              | NO   |     | 0       |       |
| PAGES_MADE_NOT_YOUNG_RATE        | double              | NO   |     | 0       |       |
| NUMBER_PAGES_READ                | bigint(21) unsigned | NO   |     | 0       |       |
| NUMBER_PAGES_CREATED             | bigint(21) unsigned | NO   |     | 0       |       |
| NUMBER_PAGES_WRITTEN             | bigint(21) unsigned | NO   |     | 0       |       |
| PAGES_READ_RATE                  | double              | NO   |     | 0       |       |
| PAGES_CREATE_RATE                | double              | NO   |     | 0       |       |
| PAGES_WRITTEN_RATE               | double              | NO   |     | 0       |       |
| NUMBER_PAGES_GET                 | bigint(21) unsigned | NO   |     | 0       |       |
| HIT_RATE                         | bigint(21) unsigned | NO   |     | 0       |       |
| YOUNG_MAKE_PER_THOUSAND_GETS     | bigint(21) unsigned | NO   |     | 0       |       |
| NOT_YOUNG_MAKE_PER_THOUSAND_GETS | bigint(21) unsigned | NO   |     | 0       |       |
| NUMBER_PAGES_READ_AHEAD          | bigint(21) unsigned | NO   |     | 0       |       |
| NUMBER_READ_AHEAD_EVICTED        | bigint(21) unsigned | NO   |     | 0       |       |
| READ_AHEAD_RATE                  | double              | NO   |     | 0       |       |
| READ_AHEAD_EVICTED_RATE          | double              | NO   |     | 0       |       |
| LRU_IO_TOTAL                     | bigint(21) unsigned | NO   |     | 0       |       |
| LRU_IO_CURRENT                   | bigint(21) unsigned | NO   |     | 0       |       |
| UNCOMPRESS_TOTAL                 | bigint(21) unsigned | NO   |     | 0       |       |
| UNCOMPRESS_CURRENT               | bigint(21) unsigned | NO   |     | 0       |       |
+----------------------------------+---------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_pool_stats-table/>

Segmented Key Cache Performance
===============================

    Testing method for segmented key cache performance
--------------------------------------------------

 We used [SysBench v0.5](https://launchpad.net/sysbench) from Launchpad to test the [segmented key cache](../segmented-key-cache/index) performance for the MyISAM storage engine of [MariaDB 5.2.2](https://mariadb.com/kb/en/mariadb-522-release-notes/)-gamma.

 As wrapper scripts for automated running of SysBench we used the `sysbench/` directory from [MariaDB Tools](https://launchpad.net/mariadb-tools).

 To test that splitting the key cache's global mutex into several mutex helps under multi user load, we wrote a new SysBench test called `select_random_points.lua`. We used one big table and selected random points with increasing number of concurrent users.

 Main testing outcomes
---------------------

 We see up to 250% performance gain depending on the amount of concurrent users.

 Detailed testing outcomes
-------------------------

 ### On our machine pitbull

 #### On pitbull with --random-points=10

 ![pitbull_rp10]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)             -3%    53%    122%    155%    226%    269%    237%
(64/off)             -6%    55%    130%    162%    234%    270%    253%

select_random_points.lua --random-points=10

```

#### On pitbull with --random-points=50

 ![pitbull_rp50]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)             -3%    53%    113%    154%    232%    254%    231%
(64/off)             -1%    55%    121%    161%    235%    268%    244%

select_random_points.lua --random-points=50

```

#### On pitbull with --random-points=100

 ![pitbull_rp100]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)             -3%    54%    121%    160%    209%    246%    219%
(64/off)             -6%    56%    129%    167%    219%    260%    241%

select_random_points.lua --random-points=100

```

#### Detailed numbers of all runs on pitbull

 You can find the absolute and relative numbers in our OpenOffice.org spread sheet here: [SysBench v0.5 select\_random\_points on pitbull](http://askmonty.org/w/images/4/47/Sysbench_v0.5_select_random_points_10_50_100_pitbull.ods)

 ### On our machine perro

 #### On perro with --random-points=10

 ![perro_rp10]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)              1%     2%     17%     45%     73%     70%     71%
(64/off)             -0.3%   6%     19%     46%     72%     74%     80%

select_random_points.lua --random-points=10

```

#### On perro with --random-points=50

 ![perro_rp50]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)              1%    10%     26%     69%    105%    122%    114%
(64/off)             -1%     8%     27%     75%    111%    120%    131%

select_random_points.lua --random-points=50

```

#### On perro with --random-points=100

 ![perro_rp100]

 In relative numbers:

 
```
Threads	               1      4      8      16      32      64      128
(32/off)            -0.2%    1%     22%	    73%    114%    114%    126%
(64/off)            -0.1%    4%     22%     75%    112%    125%    135%

select_random_points.lua --random-points=100

```

#### Detailed numbers of all runs on perro

 You can find the absolute and relative numbers in our OpenOffice.org spread sheet here: [SysBench v0.5 select\_random\_points on perro](http://askmonty.org/w/images/f/fb/Sysbench_v0.5_select_random_points_10_50_100_perro.ods)

 Table and query used
--------------------

 Table definition:

 
```
CREATE TABLE sbtest (
  id  int unsigned NOT NULL AUTO_INCREMENT,
  k   int unsigned NOT NULL DEFAULT '0',
  c   char(120) NOT NULL DEFAULT '',
  pad char(60) NOT NULL DEFAULT '',
  PRIMARY KEY (id),
  KEY k (k)
) ENGINE=MyISAM 

```

Query used:

 
```
SELECT id, k, c, pad
    FROM sbtest
    WHERE k IN (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

```

The `?` parameters were replaced by random numbers when running the SysBench test. We used 10, 50, and 100 random points in our tests.

 We inserted 20 million rows using random data, which gave us a data and index file size of:

 
```
3.6G    sbtest.MYD
313M    sbtest.MYI

```

We chose our key buffer size to be big enough to hold the index file.

 Testing environment
-------------------

 ### MariaDB sources

 We used [MariaDB 5.2.2](https://mariadb.com/kb/en/mariadb-522-release-notes/)-gamma with following revision from our launchpad repository [Revision #2878](http://bazaar.launchpad.net/%7Emaria-captains/maria/5.2/revision/2878)

 
```
revno: 2878
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: 5.2
timestamp: Tue 2010-10-26 07:37:44 +0200
message:
  fixes for windows

```

### Compiling MariaDB

 We compiled MariaDB using this line:

 
```
BUILD/compile-amd64-max

```

### MariaDB runtime options

 We used following configuration for running MariaDB

 
```
MYSQLD_OPTIONS="--no-defaults \
  --datadir=$DATA_DIR \
  --language=./sql/share/english \
  --log-error \
  --key_buffer_size=512M \
  --max_connections=256 \
  --query_cache_size=0 \
  --query_cache_type=0 \
  --skip-grant-tables \
  --socket=$MY_SOCKET \
  --table_open_cache=512 \
  --thread_cache=512 \
  --key_cache_segments=0 \ # 0 | 32 | 64
  --tmpdir=$TEMP_DIR"

```

### SysBench v0.5 select\_random\_points.lua options

 We run the SysBench v0.5 select\_random\_points.lua test with following options:

 
```
# 20 million rows.
TABLE_SIZE=20000000

SYSBENCH_OPTIONS="--oltp-table-size=$TABLE_SIZE \
  --max-requests=0 \
  --mysql-table-engine=MyISAM \
  --mysql-user=root \
  --mysql-engine-trx=no \
  --myisam-max-rows=50000000 \
  --rand-seed=303"

```

We tested with increasing number of concurrent users with a warm up time of 8 minutes and a run time of 20 minutes:

 
```
NUM_THREADS="1 4 8 16 32 64 128"
...
  --num-threads=$THREADS

```

We also tested an increasing number of random points:

 
```
# Default option is --random-points=10.
SYSBENCH_TESTS[0]="select_random_points.lua"
SYSBENCH_TESTS[1]="select_random_points.lua --random-points=50"
SYSBENCH_TESTS[2]="select_random_points.lua --random-points=100"

```

### Kernel parameters

 #### IO scheduler

 For optimal IO performance running a database we are using the noop scheduler. You can check your scheduler setting with:

 
```
cat /sys/block/${DEVICE}/queue/scheduler

```

For instance, it should look like this output:

 
```
cat /sys/block/sda/queue/scheduler
[noop] deadline cfq

```

You can find detailed notes about Linux schedulers here: [Linux schedulers in TPCC like benchmark](http://www.mysqlperformanceblog.com/2009/01/30/linux-schedulers-in-tpcc-like-benchmark/).

 #### Open file limits

 Having a lot of concurrent connections can hit the open file limit on your system. On most Linux systems the open file limit is at 1024, which can be not enough. Please set your open file limit higher by editing

 
```
$EDITOR /etc/security/limits.conf

```

and adding a line like

 
```
#ftp             hard    nproc           0
#@student        -       maxlogins       4
*                -       nofile          16384

# End of file

```

Your `ulimit -a` output should look like this afterwards:

 
```
ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15975
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) 1744200
open files                      (-n) 16384

```

### Machines used for testing

 #### perro

 
```
# OS: openSUSE 11.1 (x86_64)
# Platform: x86_64
# CPU: Quad-core Intel @ 3.20GHz: 4 CPUs
# RAM: 2GB
# Disk(s): 2 x ST31000528AS S-ATA as software RAID 0

```

#### pitbull

 
```
# OS: Ubuntu 10.10
# Platform: x86_64
# CPU: Two-socket x hexa-core Intel Xeon X5660 @ 2.80GHz. With hyperthreading: 24CPUs
# RAM: 28GB
# Disk(s): 1 x ST3500320NS S-ATA

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/segmented-key-cache-performance/>

Performance Schema memory\_summary\_by\_account\_by\_event\_name Table
======================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The memory\_summary\_by\_account\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
There are five memory summary tables in the Performance Schema that share a number of fields in common. These include:

 * memory\_summary\_by\_account\_by\_event\_name
* [memory\_summary\_by\_host\_by\_event\_name](../performance-schema-memory_summary_by_host_by_event_name-table/index)
* [memory\_summary\_by\_thread\_by\_event\_name](../performance-schema-memory_summary_by_thread_by_event_name-table/index)
* [memory\_summary\_by\_user\_by\_event\_name](../performance-schema-memory_summary_by_user_by_event_name-table/index)
* [memory\_global\_by\_event\_name](../performance-schema-memory_global_by_event_name-table/index)

 The `memory_summary_by_account_by_event_name` table contains memory usage statistics aggregated by account and event.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| USER | char(32) | YES | NULL | User portion of the account. |
| HOST | char(60) | YES | NULL | Host portion of the account. |
| EVENT\_NAME | varchar(128) | NO | NULL | Event name. |
| COUNT\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of allocations to memory. |
| COUNT\_FREE | bigint(20) unsigned | NO | NULL | Total number of attempts to free the allocated memory. |
| SUM\_NUMBER\_OF\_BYTES\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of bytes allocated. |
| SUM\_NUMBER\_OF\_BYTES\_FREE | bigint(20) unsigned | NO | NULL | Total number of bytes freed |
| LOW\_COUNT\_USED | bigint(20) | NO | NULL | Lowest number of allocated blocks (lowest value of CURRENT\_COUNT\_USED). |
| CURRENT\_COUNT\_USED | bigint(20) | NO | NULL | Currently allocated blocks that have not been freed (COUNT\_ALLOC minus COUNT\_FREE). |
| HIGH\_COUNT\_USED | bigint(20) | NO | NULL | Highest number of allocated blocks (highest value of CURRENT\_COUNT\_USED). |
| LOW\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Lowest number of bytes used. |
| CURRENT\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Current number of bytes used (total allocated minus total freed). |
| HIGH\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Highest number of bytes used. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-memory_summary_by_account_by_event_name-table/>

List of Performance Schema Tables
=================================

    Below is a list of all [Performance Schema](../performance-schema/index) tables as well as a brief description of each of them.

 


| Table | Description |
| --- | --- |
| `[accounts](../performance-schema-accounts-table/index)` | Client account connection statistics. |
| `[cond\_instances](../performance-schema-cond_instances-table/index)` | Synchronization object instances. |
| `[events\_stages\_current](../performance-schema-events_stages_current-table/index)` | Current stage events. |
| `[events\_stages\_history](../performance-schema-events_stages_history-table/index)` | Ten most recent stage events per thread. |
| `[events\_stages\_history\_long](../performance-schema-events_stages_history_long-table/index)` | Ten thousand most recent stage events. |
| `[events\_stages\_summary\_by\_account\_by\_event\_name](../performance-schema-events_stages_summary_by_account_by_event_name-table/index)` | Summarized stage events per account and event name. |
| `[events\_stages\_summary\_by\_host\_by\_event\_name](../performance-schema-events_stages_summary_by_host_by_event_name-table/index)` | Summarized stage events per host and event name. |
| `[events\_stages\_summary\_by\_thread\_by\_event\_name](../performance-schema-events_stages_summary_by_thread_by_event_name-table/index)` | Summarized stage events per thread and event name. |
| `[events\_stages\_summary\_by\_user\_by\_event\_name](../performance-schema-events_stages_summary_by_user_by_event_name-table/index)` | Summarized stage events per user name and event name. |
| `[events\_stages\_summary\_global\_by\_event\_name](../performance-schema-events_stages_summary_global_by_event_name-table/index)` | Summarized stage events per event name. |
| `[events\_statements\_current](../performance-schema-events_statements_current-table/index)` | Current statement events. |
| `[events\_statements\_history](../performance-schema-events_statements_history-table/index)` | Ten most recent events per thread. |
| `[events\_statements\_history\_long](../performance-schema-events_statements_history_long-table/index)` | Ten thousand most recent stage events. |
| `[events\_statements\_summary\_by\_account\_by\_event\_name](../performance-schema-events_statements_summary_by_account_by_event_name-table/index)` | Summarized statement events per account and event name. |
| `[events\_statements\_summary\_by\_digest](../performance-schema-events_statements_summary_by_digest-table/index)` | Summarized statement events by scheme and digest. |
| `[events\_statements\_summary\_by\_host\_by\_event\_name](../performance-schema-events_statements_summary_by_host_by_event_name-table/index)` | Summarized statement events by host and event name. |
| `[events\_statements\_summary\_by\_program](../performance-schema-events_statements_summary_by_program-table/index)` | Events for a particular stored program. |
| `[events\_statements\_summary\_by\_thread\_by\_event\_name](../performance-schema-events_statements_summary_by_thread_by_event_name-table/index)` | Summarized statement events by thread and event name. |
| `[events\_statements\_summary\_by\_user\_by\_event\_name](../performance-schema-events_statements_summary_by_user_by_event_name-table/index)` | Summarized statement events by user and event name. |
| `[events\_statements\_summary\_global\_by\_event\_name](../performance-schema-events_statements_summary_global_by_event_name-table/index)` | Summarized statement events by event name. |
| `[events\_transactions\_current](../performance-schema-events_transactions_current-table/index)` | Current transaction events for each thread. |
| `[events\_transactions\_history](../performance-schema-events_transactions_history-table/index)` | Most recent completed transaction events for each thread. |
| `[events\_transactions\_history\_long](../performance-schema-events_transactions_history_long-table/index)` | Most recent completed transaction events that have ended globally. |
| `[events\_transactions\_summary\_by\_account\_by\_event\_name](../performance-schema-tables-performance-schema-events_transactions_summary_by/index)` | Transaction events aggregated by account and event. |
| `[events\_transactions\_summary\_by\_host\_by\_event\_name](../performance-schema-events_transactions_summary_by_host_by_event_name-table/index)` | Transaction events aggregated by host and event.. |
| `[events\_transactions\_summary\_by\_thread\_by\_event\_name](../performance-schema-events_transactions_summary_by_thread_by_event_name-tabl/index)` | Transaction events aggregated by thread and event.. |
| `[events\_transactions\_summary\_by\_user\_by\_event\_name](../performance-schema-events_transactions_summary_by_user_by_event_name-table/index)` | Transaction events aggregated by user and event.. |
| `[events\_transactions\_summary\_global\_by\_event\_name](../performance-schema-events_transactions_summary_global_by_event_name-table/index)` | Transaction events aggregated by event name. |
| `[events\_waits\_current](../performance-schema-events_waits_current-table/index)` | Current wait events. |
| `[events\_waits\_history](../performance-schema-events_waits_history-table/index)` | Ten most recent wait events per thread. |
| `[events\_waits\_history\_long](../performance-schema-events_waits_history_long-table/index)` | Ten thousand most recent wait events per thread. |
| `[events\_waits\_summary\_by\_account\_by\_event\_name](../performance-schema-events_waits_summary_by_account_by_event_name-table/index)` | Summarized wait events by account and event name. |
| `[events\_waits\_summary\_by\_host\_by\_event\_name](../performance-schema-events_waits_summary_by_host_by_event_name-table/index)` | Summarized wait events by host and event name. |
| `[events\_waits\_summary\_by\_instance](../performance-schema-events_waits_summary_by_instance-table/index)` | Summarized wait events by instance. |
| `[events\_waits\_summary\_by\_thread\_by\_event\_name](../performance-schema-events_waits_summary_by_thread_by_event_name-table/index)` | Summarized wait events by thread and event name. |
| `[events\_waits\_summary\_by\_user\_by\_event\_name](../performance-schema-events_waits_summary_by_user_by_event_name-table/index)` | Summarized wait events by user and event name. |
| `[events\_waits\_summary\_global\_by\_event\_name](../performance-schema-events_waits_summary_global_by_event_name-table/index)` | Summarized wait events by event name. |
| `[file\_instances](../performance-schema-file_instances-table/index)` | Seen files. |
| `[file\_summary\_by\_event\_name](../performance-schema-file_summary_by_event_name-table/index)` | File events summarized by event name. |
| `[file\_summary\_by\_instance](../performance-schema-file_summary_by_instance-table/index)` | File events summarized by instance. |
| `[global\_status](../performance-schema-global_status-table/index)` | Global status variables and values. |
| `[host\_cache](../performance-schema-host_cache-table/index)` | Host and IP information. |
| `[hosts](../performance-schema-hosts-table/index)` | Connections by host. |
| `[memory\_summary\_by\_account\_by\_event\_name](../performance-schema-memory_summary_by_account_by_event_name-table/index)` | Memory usage statistics aggregated by account and event. |
| `[memory\_summary\_by\_host\_by\_event\_name](../performance-schema-memory_summary_by_host_by_event_name-table/index)` | Memory usage statistics aggregated by host. and event. |
| `[memory\_summary\_by\_thread\_by\_event\_name](../performance-schema-memory_summary_by_thread_by_event_name-table/index)` | Memory usage statistics aggregated by thread and event.. |
| `[memory\_summary\_by\_user\_by\_event\_name](../performance-schema-memory_summary_by_user_by_event_name-table/index)` | Memory usage statistics aggregated by user and event.. |
| `[memory\_summary\_global\_by\_event\_name](../performance-schema-memory_global_by_event_name-table/index)` | Memory usage statistics aggregated by event. |
| `[metadata\_locks](../performance-schema-metadata_locks-table/index)` | [Metadata locks](../metadata-locking/index). |
| `[mutex\_instances](../performance-schema-mutex_instances-table/index)` | Seen mutexes. |
| `[objects\_summary\_global\_by\_type](../performance-schema-objects_summary_global_by_type-table/index)` | Object wait events. |
| `[performance\_timers](../performance-schema-performance_timers-table/index)` | Available event timers. |
| `[prepared\_statements\_instances](../performance-schema-prepared_statements_instances-table/index)` | Aggregate statistics of prepared statements. |
| `[replication\_applier\_configuration](../performance-schema-replication_applier_configuration-table/index)` | Configuration settings affecting replica transactions. |
| `[replication\_applier\_status](../performance-schema-replication_applier_status-table/index)` | General transaction execution status on the replica. |
| `[replication\_applier\_status\_by\_coordinator](../performance-schema-replication_applier_status_by_coordinator-table/index)` | Coordinator thread specific information. |
| `[replication\_applier\_status\_by\_worker](../performance-schema-replication_applier_status_by_worker-table/index)` | Replica worker thread specific information. |
| `[replication\_connection\_configuration](../performance-schema-replication_connection_configuration-table/index)` | Rreplica's configuration settings used for connecting to the primary. |
| `[rwlock\_instances](../performance-schema-rwlock_instances-table/index)` | Seen read-write locks. |
| `[session\_account\_connect\_attrs](../performance-schema-session_account_connect_attrs-table/index)` | Current session connection attributes. |
| `[session\_connect\_attrs](../performance-schema-session_connect_attrs-table/index)` | All session connection attributes. |
| `[session\_status](../performance-schema-session_status-table/index)` | Session status variables and values. |
| `[setup\_actors](../performance-schema-setup_actors-table/index)` | Details on foreground thread monitoring. |
| `[setup\_consumers](../performance-schema-setup_consumers-table/index)` | Consumers for which event information is stored. |
| `[setup\_instruments](../performance-schema-setup_instruments-table/index)` | Instrumented objects for which events are collected. |
| `[setup\_objects](../performance-schema-setup_objects-table/index)` | Objects to be monitored. |
| `[setup\_timers](../performance-schema-setup_timers-table/index)` | Currently selected event timers. |
| `[socket\_instances](../performance-schema-socket_instances-table/index)` | Active connections. |
| `[socket\_summary\_by\_event\_name](../performance-schema-socket_summary_by_event_name-table/index)` | Timer and byte count statistics by socket instrument. |
| `[socket\_summary\_by\_instance](../performance-schema-socket_summary_by_instance-table/index)` | Timer and byte count statistics by socket instance. |
| `[status\_by\_account](../performance-schema-status_by_account-table/index)` | Status variable info by host/user account. |
| `[status\_by\_host](../performance-schema-status_by_host-table/index)` | Status variable info by host. |
| `[status\_by\_thread](../performance-schema-status_by_thread-table/index)` | Status variable info about active foreground threads. |
| `[status\_by\_user](../performance-schema-status_by_user-table/index)` | Status variable info by user. |
| `[table\_handles](../performance-schema-table_handles-table/index)` | Table lock information. |
| `[table\_io\_waits\_summary\_by\_index\_usage](../performance-schema-table_io_waits_summary_by_index_usage-table/index)` | Aggregate table I/O wait events by index. |
| `[table\_io\_waits\_summary\_by\_table](../performance-schema-table_io_waits_summary_by_table-table/index)` | Aggregate table I/O wait events by table. |
| `[table\_lock\_waits\_summary\_by\_table](../performance-schema-table_lock_waits_summary_by_table-table/index)` | Aggregate table lock wait events by table. |
| `[threads](../performance-schema-threads-table/index)` | Server thread information. |
| `[user\_variables\_by\_thread](../performance-schema-user_variables_by_thread-table/index)` | [User-defined variables](../user-defined-variables/index) by thread. |
| `[users](../performance-schema-users-table/index)` | Connection statistics by user. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/list-of-performance-schema-tables/>

Performance Schema cond\_instances Table
========================================

    Description
-----------

 The `cond_instances` table lists all conditions while the server is executing. A condition, or instrumented condition object, is an internal code mechanism used for signalling that a specific event has occurred so that any threads waiting for this condition can continue.

 The maximum number of conditions stored in the performance schema is determined by the [performance\_schema\_max\_cond\_instances](../performance-schema-system-variables/index#performance_schema_max_cond_instances) system variable.

 


| Column | Description |
| --- | --- |
| `NAME` | Client user name for the connection, or `NULL` if an internal thread. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the instrumented condition. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-cond_instances-table/>

Performance Schema events\_stages\_summary\_by\_account\_by\_event\_name Table
==============================================================================

    The table lists stage events, summarized by account and event name.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `HOST` and `EVENT_NAME` for grouping events. |
| `HOST` | Host. Used together with `USER` and `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` and `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events, which includes all timed and untimed events. |
| `SUM_TIMER_WAIT` | Total wait time of the timed summarized events. |
| `MIN_TIMER_WAIT` | Minimum wait time of the timed summarized events. |
| `AVG_TIMER_WAIT` | Average wait time of the timed summarized events. |
| `MAX_TIMER_WAIT` | Maximum wait time of the timed summarized events. |

 
Example
-------

 
```
SELECT * FROM events_stages_summary_by_account_by_event_name\G
...
*************************** 325. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: stage/sql/Waiting for event metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 326. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: stage/sql/Waiting for commit lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 327. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: stage/aria/Waiting for a resource
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_summary_by_account_by_event_name-table/>

Performance Schema events\_stages\_summary\_by\_host\_by\_event\_name Table
===========================================================================

    The table lists stage events, summarized by host and event name.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `HOST` | Host. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events, which includes all timed and untimed events. |
| `SUM_TIMER_WAIT` | Total wait time of the timed summarized events. |
| `MIN_TIMER_WAIT` | Minimum wait time of the timed summarized events. |
| `AVG_TIMER_WAIT` | Average wait time of the timed summarized events. |
| `MAX_TIMER_WAIT` | Maximum wait time of the timed summarized events. |

 
Example
-------

 
```
SELECT * FROM events_stages_summary_by_host_by_event_name\G
...
*************************** 216. row ***************************
          HOST: NULL
    EVENT_NAME: stage/sql/Waiting for event metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 217. row ***************************
          HOST: NULL
    EVENT_NAME: stage/sql/Waiting for commit lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 218. row ***************************
          HOST: NULL
    EVENT_NAME: stage/aria/Waiting for a resource
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_summary_by_host_by_event_name-table/>

Performance Schema events\_stages\_summary\_by\_thread\_by\_event\_name Table
=============================================================================

    The table lists stage events, summarized by thread and event name.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_NAME` uniquely identifies the row. |
| `EVENT_NAME` | Event name. Used together with `THREAD_ID` for grouping events. |
| `COUNT_STAR` | Number of summarized events, which includes all timed and untimed events. |
| `SUM_TIMER_WAIT` | Total wait time of the timed summarized events. |
| `MIN_TIMER_WAIT` | Minimum wait time of the timed summarized events. |
| `AVG_TIMER_WAIT` | Average wait time of the timed summarized events. |
| `MAX_TIMER_WAIT` | Maximum wait time of the timed summarized events. |

 
Example
-------

 
```
SELECT * FROM events_stages_summary_by_thread_by_event_name\G
...
*************************** 2287. row ***************************
     THREAD_ID: 64
    EVENT_NAME: stage/sql/Waiting for event metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 2288. row ***************************
     THREAD_ID: 64
    EVENT_NAME: stage/sql/Waiting for commit lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 2289. row ***************************
     THREAD_ID: 64
    EVENT_NAME: stage/aria/Waiting for a resource
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_summary_by_thread_by_event_name-table/>

Performance Schema events\_stages\_summary\_by\_user\_by\_event\_name Table
===========================================================================

    The table lists stage events, summarized by user and event name.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` for grouping events. |
| `COUNT_STAR` | Number of summarized events, which includes all timed and untimed events. |
| `SUM_TIMER_WAIT` | Total wait time of the timed summarized events. |
| `MIN_TIMER_WAIT` | Minimum wait time of the timed summarized events. |
| `AVG_TIMER_WAIT` | Average wait time of the timed summarized events. |
| `MAX_TIMER_WAIT` | Maximum wait time of the timed summarized events. |

 
Example
-------

 
```
SELECT * FROM events_stages_summary_by_user_by_event_name\G
...
*************************** 325. row ***************************
          USER: NULL
    EVENT_NAME: stage/sql/Waiting for event metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 326. row ***************************
          USER: NULL
    EVENT_NAME: stage/sql/Waiting for commit lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 327. row ***************************
          USER: NULL
    EVENT_NAME: stage/aria/Waiting for a resource
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_summary_by_user_by_event_name-table/>

Performance Schema events\_stages\_summary\_global\_by\_event\_name Table
=========================================================================

    The table lists stage events, summarized by thread and event name.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Event name. |
| `COUNT_STAR` | Number of summarized events, which includes all timed and untimed events. |
| `SUM_TIMER_WAIT` | Total wait time of the timed summarized events. |
| `MIN_TIMER_WAIT` | Minimum wait time of the timed summarized events. |
| `AVG_TIMER_WAIT` | Average wait time of the timed summarized events. |
| `MAX_TIMER_WAIT` | Maximum wait time of the timed summarized events. |

 
Example
-------

 
```
SELECT * FROM events_stages_summary_global_by_event_name\G
...
*************************** 106. row ***************************
    EVENT_NAME: stage/sql/Waiting for trigger metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 107. row ***************************
    EVENT_NAME: stage/sql/Waiting for event metadata lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 108. row ***************************
    EVENT_NAME: stage/sql/Waiting for commit lock
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 109. row ***************************
    EVENT_NAME: stage/aria/Waiting for a resource
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_stages_summary_global_by_event_name-table/>

Performance Schema events\_statements\_summary\_by\_account\_by\_event\_name Table
==================================================================================

    The [Performance Schema](../performance-schema/index) events\_statements\_summary\_by\_account\_by\_event\_name table contains statement events summarized by account and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `HOST` and `EVENT_NAME` for grouping events. |
| `HOST` | Host. Used together with `USER` and `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` and `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_current` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_statements_summary_by_account_by_event_name\G
...
*************************** 521. row ***************************
                       USER: NULL
                       HOST: NULL
                 EVENT_NAME: statement/com/Error
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0
*************************** 522. row ***************************
                       USER: NULL
                       HOST: NULL
                 EVENT_NAME: statement/com/
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_account_by_event_name-table/>

Performance Schema events\_statements\_summary\_by\_host\_by\_event\_name Table
===============================================================================

    The [Performance Schema](../performance-schema/index) events\_statements\_summary\_by\_host\_by\_event\_name table contains statement events summarized by host and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `HOST` | Host. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_currentd` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOINW` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_statements_summary_by_host_by_event_name\G
...
*************************** 347. row ***************************
                       HOST: NULL
                 EVENT_NAME: statement/com/Error
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0
*************************** 348. row ***************************
                       HOST: NULL
                 EVENT_NAME: statement/com/
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_host_by_event_name-table/>

Performance Schema events\_statements\_summary\_by\_program Table
=================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `events_statements_summary_by_program` table, along with many other new [Performance Schema tables](../list-of-performance-schema-tables/index), was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
Each row in the the [Performance Schema](../performance-schema/index) events\_statements\_summary\_by\_program table summarizes events for a particular stored program (stored procedure, stored function, trigger or event). 

 It contains the following fields.

 


| Column | Type | Null | Description |
| --- | --- | --- | --- |
| OBJECT\_TYPE | enum('EVENT', 'FUNCTION', 'PROCEDURE', 'TABLE', 'TRIGGER') | YES | Object type for which the summary is generated. |
| OBJECT\_SCHEMA | varchar(64) | NO | The schema of the object for which the summary is generated. |
| OBJECT\_NAME | varchar(64) | NO | The name of the object for which the summary is generated. |
| COUNT\_STAR | bigint(20) unsigned | NO | The number of summarized events (from events\_statements\_current). This value includes all events, whether timed or nontimed. |
| SUM\_TIMER\_WAIT | bigint(20) unsigned | NO | The number of summarized events (from events\_statements\_current). This value includes all events, whether timed or nontimed. |
| MIN\_TIMER\_WAIT | bigint(20) unsigned | NO | The minimum wait time of the summarized timed events. |
| AVG\_TIMER\_WAIT | bigint(20) unsigned | NO | The average wait time of the summarized timed events. |
| MAX\_TIMER\_WAIT | bigint(20) unsigned | NO | The maximum wait time of the summarized timed events. |
| COUNT\_STATEMENTS | bigint(20) unsigned | NO | Total number of nested statements invoked during stored program execution. |
| SUM\_STATEMENTS\_WAIT | bigint(20) unsigned | NO | The total wait time of the summarized timed statements. This value is calculated only for timed statements because nontimed statements have a wait time of NULL. The same is true for the other xxx\_STATEMENT\_WAIT values. |
| MIN\_STATEMENTS\_WAIT | bigint(20) unsigned | NO | The minimum wait time of the summarized timed statements. |
| AVG\_STATEMENTS\_WAIT | bigint(20) unsigned | NO | The average wait time of the summarized timed statements. |
| MAX\_STATEMENTS\_WAIT | bigint(20) unsigned | NO | The maximum wait time of the summarized timed statements. |
| SUM\_LOCK\_TIME | bigint(20) unsigned | NO | The total time spent (in picoseconds) waiting for table locks for the summarized statements. |
| SUM\_ERRORS | bigint(20) unsigned | NO | The total number of errors that occurend for the summarized statements. |
| SUM\_WARNINGS | bigint(20) unsigned | NO | The total number of warnings that occurend for the summarized statements. |
| SUM\_ROWS\_AFFECTED | bigint(20) unsigned | NO | The total number of affected rows by the summarized statements. |
| SUM\_ROWS\_SENT | bigint(20) unsigned | NO | The total number of rows returned by the summarized statements. |
| SUM\_ROWS\_EXAMINED | bigint(20) unsigned | NO | The total number of rows examined by the summarized statements.The total number of affected rows by the summarized statements. |
| SUM\_CREATED\_TMP\_DISK\_TABLES | bigint(20) unsigned | NO | The total number of on-disk temporary tables created by the summarized statements. |
| SUM\_CREATED\_TMP\_TABLES | bigint(20) unsigned | NO | The total number of in-memory temporary tables created by the summarized statements. |
| SUM\_SELECT\_FULL\_JOIN | bigint(20) unsigned | NO | The total number of full joins executed by the summarized statements. |
| SUM\_SELECT\_FULL\_RANGE\_JOIN | bigint(20) unsigned | NO | The total number of range search joins executed by the summarized statements. |
| SUM\_SELECT\_RANGE | bigint(20) unsigned | NO | The total number of joins that used ranges on the first table executed by the summarized statements. |
| SUM\_SELECT\_RANGE\_CHECK | bigint(20) unsigned | NO | The total number of joins that check for key usage after each row executed by the summarized statements. |
| SUM\_SELECT\_SCAN | bigint(20) unsigned | NO | The total number of joins that did a full scan of the first table executed by the summarized statements. |
| SUM\_SORT\_MERGE\_PASSES | bigint(20) unsigned | NO | The total number of merge passes that the sort algorithm has had to do for the summarized statements. |
| SUM\_SORT\_RANGE | bigint(20) unsigned | NO | The total number of sorts that were done using ranges for the summarized statements. |
| SUM\_SORT\_ROWS | bigint(20) unsigned | NO | The total number of sorted rows that were sorted by the summarized statements. |
| SUM\_SORT\_SCAN | bigint(20) unsigned | NO | The total number of sorts that were done by scanning the table by the summarized statements. |
| SUM\_NO\_INDEX\_USED | bigint(20) unsigned | NO | The total number of statements that performed a table scan without using an index. |
| SUM\_NO\_GOOD\_INDEX\_USED | bigint(20) unsigned | NO | The total number of statements where no good index was found. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_program-table/>

Performance Schema events\_statements\_summary\_by\_thread\_by\_event\_name Table
=================================================================================

    The [Performance Schema](../performance-schema/index) `events_statements_summary_by_thread_by_event_name` table contains statement events summarized by thread and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_NAME` uniquely identifies the row. |
| `EVENT_NAME` | Event name. Used together with `THREAD_ID` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_current` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_statements_summary_by_thread_by_event_name\G
...
*************************** 3653. row ***************************
                  THREAD_ID: 64
                 EVENT_NAME: statement/com/Error
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0
*************************** 3654. row ***************************
                  THREAD_ID: 64
                 EVENT_NAME: statement/com/
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_thread_by_event_name-table/>

Performance Schema events\_statements\_summary\_by\_user\_by\_event\_name Table
===============================================================================

    The [Performance Schema](../performance-schema/index) `events_statements_summary_by_user_by_event_name` table contains statement events summarized by user and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_current` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_statements_summary_by_user_by_event_name\G
...
*************************** 521. row ***************************
                       USER: NULL
                 EVENT_NAME: statement/com/Error
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0
*************************** 522. row ***************************
                       USER: NULL
                 EVENT_NAME: statement/com/
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_by_user_by_event_name-table/>

Performance Schema events\_statements\_summary\_global\_by\_event\_name Table
=============================================================================

    The [Performance Schema](../performance-schema/index) `events_statements_summary_global_by_event_name` table contains statement events summarized by event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Event name. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `SUM_LOCK_TIME` | Sum of the `LOCK_TIME` column in the `events_statements_current` table. |
| `SUM_ERRORS` | Sum of the `ERRORS` column in the `events_statements_current` table. |
| `SUM_WARNINGS` | Sum of the `WARNINGS` column in the `events_statements_current` table. |
| `SUM_ROWS_AFFECTED` | Sum of the `ROWS_AFFECTED` column in the `events_statements_current` table. |
| `SUM_ROWS_SENT` | Sum of the `ROWS_SENT` column in the `events_statements_current` table. |
| `SUM_ROWS_EXAMINED` | Sum of the `ROWS_EXAMINED` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_DISK_TABLES` | Sum of the `CREATED_TMP_DISK_TABLES` column in the `events_statements_current` table. |
| `SUM_CREATED_TMP_TABLES` | Sum of the `CREATED_TMP_TABLES` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_JOIN` | Sum of the `SELECT_FULL_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_FULL_RANGE_JOIN` | Sum of the `SELECT_FULL_RANGE_JOIN` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE` | Sum of the `SELECT_RANGE` column in the `events_statements_current` table. |
| `SUM_SELECT_RANGE_CHECK` | Sum of the `SELECT_RANGE_CHECK` column in the `events_statements_current` table. |
| `SUM_SELECT_SCAN` | Sum of the `SELECT_SCAN` column in the `events_statements_current` table. |
| `SUM_SORT_MERGE_PASSES` | Sum of the `SORT_MERGE_PASSES` column in the `events_statements_current` table. |
| `SUM_SORT_RANGE` | Sum of the `SORT_RANGE` column in the `events_statements_current` table. |
| `SUM_SORT_ROWS` | Sum of the `SORT_ROWS` column in the `events_statements_current` table. |
| `SUM_SORT_SCAN` | Sum of the `SORT_SCAN` column in the `events_statements_current` table. |
| `SUM_NO_INDEX_USED` | Sum of the `NO_INDEX_USED` column in the `events_statements_current` table. |
| `SUM_NO_GOOD_INDEX_USED` | Sum of the `NO_GOOD_INDEX_USED` column in the `events_statements_current` table. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_statements_summary_global_by_event_name\G
...
*************************** 173. row ***************************
                 EVENT_NAME: statement/com/Error
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0
*************************** 174. row ***************************
                 EVENT_NAME: statement/com/
                 COUNT_STAR: 0
             SUM_TIMER_WAIT: 0
             MIN_TIMER_WAIT: 0
             AVG_TIMER_WAIT: 0
             MAX_TIMER_WAIT: 0
              SUM_LOCK_TIME: 0
                 SUM_ERRORS: 0
               SUM_WARNINGS: 0
          SUM_ROWS_AFFECTED: 0
              SUM_ROWS_SENT: 0
          SUM_ROWS_EXAMINED: 0
SUM_CREATED_TMP_DISK_TABLES: 0
     SUM_CREATED_TMP_TABLES: 0
       SUM_SELECT_FULL_JOIN: 0
 SUM_SELECT_FULL_RANGE_JOIN: 0
           SUM_SELECT_RANGE: 0
     SUM_SELECT_RANGE_CHECK: 0
            SUM_SELECT_SCAN: 0
      SUM_SORT_MERGE_PASSES: 0
             SUM_SORT_RANGE: 0
              SUM_SORT_ROWS: 0
              SUM_SORT_SCAN: 0
          SUM_NO_INDEX_USED: 0
     SUM_NO_GOOD_INDEX_USED: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_statements_summary_global_by_event_name-table/>

Performance Schema events\_transactions\_summary\_by\_account\_by\_event\_name Table
====================================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_summary\_by\_account\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_summary_by_account_by_event_name` table contains information on transaction events aggregated by account and event name.

 The table contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| USER | char(32) | User for which summary is generated. |
| HOST | char(60) | Host for which summary is generated. |
| EVENT\_NAME | varchar(128) | Event name for which summary is generated. |
| COUNT\_STAR | bigint(20) unsigned | The number of summarized events. This value includes all events, whether timed or nontimed. |
| SUM\_TIMER\_WAIT | bigint(20) unsigned | The total wait time of the summarized timed events. This value is calculated only for timed events because nontimed events have a wait time of NULL. The same is true for the other xxx\_TIMER\_WAIT values. |
| MIN\_TIMER\_WAIT | bigint(20) unsigned | The minimum wait time of the summarized timed events. |
| AVG\_TIMER\_WAIT | bigint(20) unsigned | The average wait time of the summarized timed events. |
| MAX\_TIMER\_WAIT | bigint(20) unsigned | The maximum wait time of the summarized timed events. |
| COUNT\_READ\_WRITE | bigint(20) unsigned | The total number of only READ/WRITE transaction events. |
| SUM\_TIMER\_READ\_WRITE | bigint(20) unsigned | The total wait time of only READ/WRITE transaction events. |
| MIN\_TIMER\_READ\_WRITE | bigint(20) unsigned | The minimum wait time of only READ/WRITE transaction events. |
| AVG\_TIMER\_READ\_WRITE | bigint(20) unsigned | The average wait time of only READ/WRITE transaction events. |
| MAX\_TIMER\_READ\_WRITE | bigint(20) unsigned | The maximum wait time of only READ/WRITE transaction events. |
| COUNT\_READ\_ONLY | bigint(20) unsigned | The total number of only READ ONLY transaction events. |
| SUM\_TIMER\_READ\_ONLY | bigint(20) unsigned | The total wait time of only READ ONLY transaction events. |
| MIN\_TIMER\_READ\_ONLY | bigint(20) unsigned | The minimum wait time of only READ ONLY transaction events. |
| AVG\_TIMER\_READ\_ONLY | bigint(20) unsigned | The average wait time of only READ ONLY transaction events. |
| MAX\_TIMER\_READ\_ONLY | bigint(20) unsigned | The maximum wait time of only READ ONLY transaction events. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-tables-performance-schema-events_transactions_summary_by/>

Performance Schema events\_waits\_summary\_by\_account\_by\_event\_name Table
=============================================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_by_account_by_event_name` table contains wait events summarized by account and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `HOST` and `EVENT_NAME` for grouping events. |
| `HOST` | Host. Used together with `USER` and `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` and `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_by_account_by_event_name\G
...
*************************** 915. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 916. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: wait/io/socket/sql/server_unix_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 917. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: wait/io/socket/sql/client_connection
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 918. row ***************************
          USER: NULL
          HOST: NULL
    EVENT_NAME: idle
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_by_account_by_event_name-table/>

Performance Schema events\_transactions\_summary\_by\_user\_by\_event\_name Table
=================================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_summary\_by\_user\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_summary_by_user_by_event_name` table contains information on transaction events aggregated by user and event name.

 The table contains the following columns:

 
```
+----------------------+---------------------+------+-----+---------+-------+
| Field                | Type                | Null | Key | Default | Extra |
+----------------------+---------------------+------+-----+---------+-------+
| USER                 | char(32)            | YES  |     | NULL    |       |
| EVENT_NAME           | varchar(128)        | NO   |     | NULL    |       |
| COUNT_STAR           | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_WRITE     | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_ONLY      | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
+----------------------+---------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_summary_by_user_by_event_name-table/>

Performance Schema events\_waits\_summary\_by\_thread\_by\_event\_name Table
============================================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_by_thread_by_event_name` table contains wait events summarized by thread and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | Thread associated with the event. Together with `EVENT_NAME` uniquely identifies the row. |
| `EVENT_NAME` | Event name. Used together with `THREAD_ID` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_by_thread_by_event_name\G
...
*************************** 6424. row ***************************
     THREAD_ID: 64
    EVENT_NAME: wait/io/socket/sql/server_unix_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 6425. row ***************************
     THREAD_ID: 64
    EVENT_NAME: wait/io/socket/sql/client_connection
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 6426. row ***************************
     THREAD_ID: 64
    EVENT_NAME: idle
    COUNT_STAR: 73
SUM_TIMER_WAIT: 22005252162000000
MIN_TIMER_WAIT: 3000000
AVG_TIMER_WAIT: 301441810000000
MAX_TIMER_WAIT: 4912417573000000

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_by_thread_by_event_name-table/>

Performance Schema events\_waits\_summary\_global\_by\_event\_name Table
========================================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_global_by_event_name` table contains wait events summarized by event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Event name. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_global_by_event_name\G
...
*************************** 303. row ***************************
    EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 304. row ***************************
    EVENT_NAME: wait/io/socket/sql/server_unix_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 305. row ***************************
    EVENT_NAME: wait/io/socket/sql/client_connection
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 306. row ***************************
    EVENT_NAME: idle
    COUNT_STAR: 265
SUM_TIMER_WAIT: 46861125181000000
MIN_TIMER_WAIT: 1000000
AVG_TIMER_WAIT: 176834434000000
MAX_TIMER_WAIT: 4912417573000000

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_global_by_event_name-table/>

Performance Schema file\_instances Table
========================================

    Description
-----------

 The `file_instances` table lists instances of instruments seen by the Performance Schema when executing file I/O instrumentation, and the associated files. Only files that have been opened, and that have not been deleted, will be listed in the table.

 The [performance\_schema\_max\_file\_instances](../performance-schema-system-variables/index#performance_schema_max_file_instances) system variable specifies the maximum number of instrumented file objects. 

 


| Column | Description |
| --- | --- |
| `FILE_NAME` | File name. |
| `EVENT_NAME` | Instrument name associated with the file. |
| `OPEN_COUNT` | Open handles on the file. A value of greater than zero means that the file is currently open. |

 
Example
-------

 
```
SELECT * FROM performance_schema.file_instances WHERE OPEN_COUNT>0;
+----------------------------------------------------+--------------------------------------+------------+
| FILE_NAME                                          | EVENT_NAME                           | OPEN_COUNT |
+----------------------------------------------------+--------------------------------------+------------+
| /var/log/mysql/mariadb-bin.index                   | wait/io/file/sql/binlog_index        |          1 |
| /var/lib/mysql/ibdata1                             | wait/io/file/innodb/innodb_data_file |          2 |
| /var/lib/mysql/ib_logfile0                         | wait/io/file/innodb/innodb_log_file  |          2 |
| /var/lib/mysql/ib_logfile1                         | wait/io/file/innodb/innodb_log_file  |          2 |
| /var/lib/mysql/mysql/gtid_slave_pos.ibd            | wait/io/file/innodb/innodb_data_file |          3 |
| /var/lib/mysql/mysql/innodb_index_stats.ibd        | wait/io/file/innodb/innodb_data_file |          3 |
| /var/lib/mysql/mysql/innodb_table_stats.ibd        | wait/io/file/innodb/innodb_data_file |          3 |
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-file_instances-table/>

Performance Schema events\_waits\_summary\_by\_user\_by\_event\_name Table
==========================================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_by_user_by_event_name` table contains wait events summarized by user and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `USER` | User. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_by_user_by_event_name\G
...
*************************** 916. row ***************************
          USER: NULL
    EVENT_NAME: wait/io/socket/sql/server_unix_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 917. row ***************************
          USER: NULL
    EVENT_NAME: wait/io/socket/sql/client_connection
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 918. row ***************************
          USER: NULL
    EVENT_NAME: idle
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_by_user_by_event_name-table/>

Performance Schema events\_waits\_summary\_by\_instance Table
=============================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_by_instance` table contains wait events summarized by instance. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Event name. Used together with `OBJECT_INSTANCE_BEGIN` for grouping events. |
| `OBJECT_INSTANCE_BEGIN` | If an instrument creates multiple instances, each instance has a unique `OBJECT_INSTANCE_BEGIN` value to allow for grouping by instance. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_by_instance\G
...
*************************** 202. row ***************************
           EVENT_NAME: wait/io/file/sql/binlog
OBJECT_INSTANCE_BEGIN: 140578961969856
           COUNT_STAR: 6
       SUM_TIMER_WAIT: 90478331960
       MIN_TIMER_WAIT: 263344
       AVG_TIMER_WAIT: 15079721848
       MAX_TIMER_WAIT: 67760576376
*************************** 203. row ***************************
           EVENT_NAME: wait/io/file/sql/dbopt
OBJECT_INSTANCE_BEGIN: 140578961970560
           COUNT_STAR: 6
       SUM_TIMER_WAIT: 39891428472
       MIN_TIMER_WAIT: 387168
       AVG_TIMER_WAIT: 6648571412
       MAX_TIMER_WAIT: 24503293304
*************************** 204. row ***************************
           EVENT_NAME: wait/io/file/sql/dbopt
OBJECT_INSTANCE_BEGIN: 140578961971264
           COUNT_STAR: 6
       SUM_TIMER_WAIT: 39902495024
       MIN_TIMER_WAIT: 177888
       AVG_TIMER_WAIT: 6650415692
       MAX_TIMER_WAIT: 21026400404

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_by_instance-table/>

Performance Schema events\_waits\_summary\_by\_host\_by\_event\_name Table
==========================================================================

    The [Performance Schema](../performance-schema/index) `events_waits_summary_by_host_by_event_name` table contains wait events summarized by host and event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `HOST` | Host. Used together with `EVENT_NAME` for grouping events. |
| `EVENT_NAME` | Event name. Used together with `USER` and `HOST` for grouping events. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
The `*_TIMER_WAIT` columns only calculate results for timed events, as non-timed events have a `NULL` wait time. 

 Example
-------

 
```
SELECT * FROM events_waits_summary_by_host_by_event_name\G
...
*************************** 610. row ***************************
          HOST: NULL
    EVENT_NAME: wait/io/socket/sql/server_unix_socket
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 611. row ***************************
          HOST: NULL
    EVENT_NAME: wait/io/socket/sql/client_connection
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 612. row ***************************
          HOST: NULL
    EVENT_NAME: idle
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_waits_summary_by_host_by_event_name-table/>

Performance Schema file\_summary\_by\_instance Table
====================================================

    The [Performance Schema](../performance-schema/index) `file_summary_by_instance` table contains file events summarized by instance. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `FILE_NAME` | File name. |
| `EVENT_NAME` | Event name. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory. Together with `FILE_NAME` and `EVENT_NAME` uniquely identifies a row. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, including `FGETS`, `FGETC`, `FREAD`, and `READ`. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `SUM_NUMBER_OF_BYTES_READ` | Bytes read by read operations. |
| `COUNT_WRITE` | Number of all write operations, including `FPUTS`, `FPUTC`, `FPRINTF`, `VFPRINTF`, `FWRITE`, and `PWRITE`. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `SUM_NUMBER_OF_BYTES_WRITE` | Bytes written by write operations. |
| `COUNT_MISC` | Number of all miscellaneous operations not counted above, including `CREATE`, `DELETE`, `OPEN`, `CLOSE`, `STREAM_OPEN`, `STREAM_CLOSE`, `SEEK`, `TELL`, `FLUSH`, `STAT`, `FSTAT`, `CHSIZE`, `RENAME`, and `SYNC`. |
| `SUM_TIMER_MISC` | Total wait time of all miscellaneous operations that are timed. |
| `MIN_TIMER_MISC` | Minimum wait time of all miscellaneous operations that are timed. |
| `AVG_TIMER_MISC` | Average wait time of all miscellaneous operations that are timed. |
| `MAX_TIMER_MISC` | Maximum wait time of all miscellaneous operations that are timed. |

 
I/O operations can be avoided by caching, in which case they will not be recorded in this table.

 You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

 Example
-------

 
```
SELECT * FROM file_summary_by_instance\G
...
*************************** 204. row ***************************
                FILE_NAME: /var/lib/mysql/test/db.opt
               EVENT_NAME: wait/io/file/sql/dbopt
    OBJECT_INSTANCE_BEGIN: 140578961971264
               COUNT_STAR: 6
           SUM_TIMER_WAIT: 39902495024
           MIN_TIMER_WAIT: 177888
           AVG_TIMER_WAIT: 6650415692
           MAX_TIMER_WAIT: 21026400404
               COUNT_READ: 1
           SUM_TIMER_READ: 21026400404
           MIN_TIMER_READ: 21026400404
           AVG_TIMER_READ: 21026400404
           MAX_TIMER_READ: 21026400404
 SUM_NUMBER_OF_BYTES_READ: 65
              COUNT_WRITE: 0
          SUM_TIMER_WRITE: 0
          MIN_TIMER_WRITE: 0
          AVG_TIMER_WRITE: 0
          MAX_TIMER_WRITE: 0
SUM_NUMBER_OF_BYTES_WRITE: 0
               COUNT_MISC: 5
           SUM_TIMER_MISC: 18876094620
           MIN_TIMER_MISC: 177888
           AVG_TIMER_MISC: 3775218924
           MAX_TIMER_MISC: 18864558060
*************************** 205. row ***************************
                FILE_NAME: /var/log/mysql/mariadb-bin.000157
               EVENT_NAME: wait/io/file/sql/binlog
    OBJECT_INSTANCE_BEGIN: 140578961971968
               COUNT_STAR: 6
           SUM_TIMER_WAIT: 73985877680
           MIN_TIMER_WAIT: 251136
           AVG_TIMER_WAIT: 12330979468
           MAX_TIMER_WAIT: 73846656340
               COUNT_READ: 0
           SUM_TIMER_READ: 0
           MIN_TIMER_READ: 0
           AVG_TIMER_READ: 0
           MAX_TIMER_READ: 0
 SUM_NUMBER_OF_BYTES_READ: 0
              COUNT_WRITE: 2
          SUM_TIMER_WRITE: 62583004
          MIN_TIMER_WRITE: 27630192
          AVG_TIMER_WRITE: 31291284
          MAX_TIMER_WRITE: 34952812
SUM_NUMBER_OF_BYTES_WRITE: 369
               COUNT_MISC: 4
           SUM_TIMER_MISC: 73923294676
           MIN_TIMER_MISC: 251136
           AVG_TIMER_MISC: 18480823560
           MAX_TIMER_MISC: 73846656340

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-file_summary_by_instance-table/>

Performance Schema events\_transactions\_summary\_by\_host\_by\_event\_name Table
=================================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_summary\_by\_host\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_summary_by_host_by_event_name` table contains information on transaction events aggregated by host and event name.

 The table contains the following columns:

 


| Column | Type | Description |
| --- | --- | --- |
| HOST | char(60) | Host for which summary is generated. |
| EVENT\_NAME | varchar(128) | Event name for which summary is generated. |
| COUNT\_STAR | bigint(20) unsigned | The number of summarized events. This value includes all events, whether timed or nontimed. |
| SUM\_TIMER\_WAIT | bigint(20) unsigned | The total wait time of the summarized timed events. This value is calculated only for timed events because nontimed events have a wait time of NULL. The same is true for the other xxx\_TIMER\_WAIT values. |
| MIN\_TIMER\_WAIT | bigint(20) unsigned | The minimum wait time of the summarized timed events. |
| AVG\_TIMER\_WAIT | bigint(20) unsigned | The average wait time of the summarized timed events. |
| MAX\_TIMER\_WAIT | bigint(20) unsigned | The maximum wait time of the summarized timed events. |
| COUNT\_READ\_WRITE | bigint(20) unsigned | The total number of only READ/WRITE transaction events. |
| SUM\_TIMER\_READ\_WRITE | bigint(20) unsigned | The total wait time of only READ/WRITE transaction events. |
| MIN\_TIMER\_READ\_WRITE | bigint(20) unsigned | The minimum wait time of only READ/WRITE transaction events. |
| AVG\_TIMER\_READ\_WRITE | bigint(20) unsigned | The average wait time of only READ/WRITE transaction events. |
| MAX\_TIMER\_READ\_WRITE | bigint(20) unsigned | The maximum wait time of only READ/WRITE transaction events. |
| COUNT\_READ\_ONLY | bigint(20) unsigned | The total number of only READ ONLY transaction events. |
| SUM\_TIMER\_READ\_ONLY | bigint(20) unsigned | The total wait time of only READ ONLY transaction events. |
| MIN\_TIMER\_READ\_ONLY | bigint(20) unsigned | The minimum wait time of only READ ONLY transaction events. |
| AVG\_TIMER\_READ\_ONLY | bigint(20) unsigned | The average wait time of only READ ONLY transaction events. |
| MAX\_TIMER\_READ\_ONLY | bigint(20) unsigned | The maximum wait time of only READ ONLY transaction events. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_summary_by_host_by_event_name-table/>

Performance Schema events\_transactions\_summary\_global\_by\_event\_name Table
===============================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_summary\_global\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_summary_global_by_event_name` table contains information on transaction events aggregated by event name.

 The table contains the following columns:

 
```
+----------------------+---------------------+------+-----+---------+-------+
| Field                | Type                | Null | Key | Default | Extra |
+----------------------+---------------------+------+-----+---------+-------+
| EVENT_NAME           | varchar(128)        | NO   |     | NULL    |       |
| COUNT_STAR           | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_WRITE     | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_ONLY      | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
+----------------------+---------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_summary_global_by_event_name-table/>

Performance Schema events\_transactions\_summary\_by\_thread\_by\_event\_name Table
===================================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The events\_transactions\_summary\_by\_thread\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `events_transactions_summary_by_thread_by_event_name` table contains information on transaction events aggregated by thread and event name.

 The table contains the following columns:

 
```
+----------------------+---------------------+------+-----+---------+-------+
| Field                | Type                | Null | Key | Default | Extra |
+----------------------+---------------------+------+-----+---------+-------+
| THREAD_ID            | bigint(20) unsigned | NO   |     | NULL    |       |
| EVENT_NAME           | varchar(128)        | NO   |     | NULL    |       |
| COUNT_STAR           | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_WAIT       | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_WRITE     | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_WRITE | bigint(20) unsigned | NO   |     | NULL    |       |
| COUNT_READ_ONLY      | bigint(20) unsigned | NO   |     | NULL    |       |
| SUM_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MIN_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| AVG_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
| MAX_TIMER_READ_ONLY  | bigint(20) unsigned | NO   |     | NULL    |       |
+----------------------+---------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-events_transactions_summary_by_thread_by_event_name-tabl/>

Performance Schema global\_status Table
=======================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `global_status` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `global_status` table contains a list of status variables and their global values. The table only stores status variable statistics for threads which are instrumented, and does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | The global status variable name. |
| `VARIABLE_VALUE` | The global status variable value. |

 
[TRUNCATE TABLE](../truncate-table/index) resets global status variables, including thread, account, host, and user status, but not those that are never reset by the server.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-global_status-table/>

Performance Schema file\_summary\_by\_event\_name Table
=======================================================

    The [Performance Schema](../performance-schema/index) `file_summary_by_event_name` table contains file events summarized by event name. It contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Event name. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, including `FGETS`, `FGETC`, `FREAD`, and `READ`. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `SUM_NUMBER_OF_BYTES_READ` | Bytes read by read operations. |
| `COUNT_WRITE` | Number of all write operations, including `FPUTS`, `FPUTC`, `FPRINTF`, `VFPRINTF`, `FWRITE`, and `PWRITE`. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `SUM_NUMBER_OF_BYTES_WRITE` | Bytes written by write operations. |
| `COUNT_MISC` | Number of all miscellaneous operations not counted above, including `CREATE`, `DELETE`, `OPEN`, `CLOSE`, `STREAM_OPEN`, `STREAM_CLOSE`, `SEEK`, `TELL`, `FLUSH`, `STAT`, `FSTAT`, `CHSIZE`, `RENAME`, and `SYNC`. |
| `SUM_TIMER_MISC` | Total wait time of all miscellaneous operations that are timed. |
| `MIN_TIMER_MISC` | Minimum wait time of all miscellaneous operations that are timed. |
| `AVG_TIMER_MISC` | Average wait time of all miscellaneous operations that are timed. |
| `MAX_TIMER_MISC` | Maximum wait time of all miscellaneous operations that are timed. |

 
I/O operations can be avoided by caching, in which case they will not be recorded in this table.

 You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

 Example
-------

 
```
SELECT * FROM file_summary_by_event_name\G
...
*************************** 49. row ***************************
               EVENT_NAME: wait/io/file/aria/MAD
               COUNT_STAR: 60
           SUM_TIMER_WAIT: 397234368
           MIN_TIMER_WAIT: 0
           AVG_TIMER_WAIT: 6620224
           MAX_TIMER_WAIT: 16808672
               COUNT_READ: 0
           SUM_TIMER_READ: 0
           MIN_TIMER_READ: 0
           AVG_TIMER_READ: 0
           MAX_TIMER_READ: 0
 SUM_NUMBER_OF_BYTES_READ: 0
              COUNT_WRITE: 0
          SUM_TIMER_WRITE: 0
          MIN_TIMER_WRITE: 0
          AVG_TIMER_WRITE: 0
          MAX_TIMER_WRITE: 0
SUM_NUMBER_OF_BYTES_WRITE: 0
               COUNT_MISC: 60
           SUM_TIMER_MISC: 397234368
           MIN_TIMER_MISC: 0
           AVG_TIMER_MISC: 6620224
           MAX_TIMER_MISC: 16808672
*************************** 50. row ***************************
               EVENT_NAME: wait/io/file/aria/control
               COUNT_STAR: 3
           SUM_TIMER_WAIT: 24055778544
           MIN_TIMER_WAIT: 0
           AVG_TIMER_WAIT: 8018592848
           MAX_TIMER_WAIT: 24027262400
               COUNT_READ: 1
           SUM_TIMER_READ: 24027262400
           MIN_TIMER_READ: 0
           AVG_TIMER_READ: 24027262400
           MAX_TIMER_READ: 24027262400
 SUM_NUMBER_OF_BYTES_READ: 52
              COUNT_WRITE: 0
          SUM_TIMER_WRITE: 0
          MIN_TIMER_WRITE: 0
          AVG_TIMER_WRITE: 0
          MAX_TIMER_WRITE: 0
SUM_NUMBER_OF_BYTES_WRITE: 0
               COUNT_MISC: 2
           SUM_TIMER_MISC: 28516144
           MIN_TIMER_MISC: 0
           AVG_TIMER_MISC: 14258072
           MAX_TIMER_MISC: 27262208

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-file_summary_by_event_name-table/>

Performance Schema mutex\_instances Table
=========================================

    Description
-----------

 The `mutex_instances` table lists all mutexes that the Performance Schema seeing while the server is executing.

 A mutex is a code mechanism for ensuring that threads can only access resources one at a time. A second thread attempting to access a resource will find it protected by a mutex, and will wait for it to be unlocked.

 The [performance\_schema\_max\_mutex\_instances](../performance-schema-system-variables/index#performance_schema_max_mutex_instances) system variable specifies the maximum number of instrumented mutex instances. 

 


| Column | Description |
| --- | --- |
| `NAME` | Instrument name associated with the mutex. |
| `OBJECT_INSTANCE_BEGIN` | Memory address of the instrumented mutex. |
| `LOCKED_BY_THREAD_ID` | The `THREAD_ID` of the locking thread if a thread has a mutex locked, otherwise `NULL`. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-mutex_instances-table/>

Performance Schema objects\_summary\_global\_by\_type Table
===========================================================

    It aggregates object wait events, and contains the following columns:

 


| Column | Description |
| --- | --- |
| `OBJECT_TYPE` | Groups records together with `OBJECT_SCHEMA` and `OBJECT_NAME`. |
| `OBJECT_SCHEMA` | Groups records together with `OBJECT_TYPE` and `OBJECT_NAME`. |
| `OBJECT_NAME` | Groups records together with `OBJECT_SCHEMA` and `OBJECT_TYPE`. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |

 
You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

 Example
-------

 
```
SELECT * FROM objects_summary_global_by_type\G
...
*************************** 101. row ***************************
   OBJECT_TYPE: TABLE
 OBJECT_SCHEMA: test
   OBJECT_NAME: v
    COUNT_STAR: 0
SUM_TIMER_WAIT: 0
MIN_TIMER_WAIT: 0
AVG_TIMER_WAIT: 0
MAX_TIMER_WAIT: 0
*************************** 102. row ***************************
   OBJECT_TYPE: TABLE
 OBJECT_SCHEMA: test
   OBJECT_NAME: xx2
    COUNT_STAR: 2
SUM_TIMER_WAIT: 1621920
MIN_TIMER_WAIT: 481344
AVG_TIMER_WAIT: 810960
MAX_TIMER_WAIT: 1140576

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-objects_summary_global_by_type-table/>

Performance Schema memory\_summary\_by\_host\_by\_event\_name Table
===================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The memory\_summary\_by\_host\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
There are five memory summary tables in the Performance Schema that share a number of fields in common. These include:

 * [memory\_summary\_by\_account\_by\_event\_name](../performance-schema-memory_summary_by_account_by_event_name-table/index)
* memory\_summary\_by\_host\_by\_event\_name
* [memory\_summary\_by\_thread\_by\_event\_name](../performance-schema-memory_summary_by_thread_by_event_name-table/index)
* [memory\_summary\_by\_user\_by\_event\_name](../performance-schema-memory_summary_by_user_by_event_name-table/index)
* [memory\_global\_by\_event\_name](../performance-schema-memory_global_by_event_name-table/index)

 The `memory_summary_by_host_by_event_name` table contains memory usage statistics aggregated by host and event.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| HOST | char(60) | YES | NULL | Host portion of the account. |
| EVENT\_NAME | varchar(128) | NO | NULL | Event name. |
| COUNT\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of allocations to memory. |
| COUNT\_FREE | bigint(20) unsigned | NO | NULL | Total number of attempts to free the allocated memory. |
| SUM\_NUMBER\_OF\_BYTES\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of bytes allocated. |
| SUM\_NUMBER\_OF\_BYTES\_FREE | bigint(20) unsigned | NO | NULL | Total number of bytes freed |
| LOW\_COUNT\_USED | bigint(20) | NO | NULL | Lowest number of allocated blocks (lowest value of CURRENT\_COUNT\_USED). |
| CURRENT\_COUNT\_USED | bigint(20) | NO | NULL | Currently allocated blocks that have not been freed (COUNT\_ALLOC minus COUNT\_FREE). |
| HIGH\_COUNT\_USED | bigint(20) | NO | NULL | Highest number of allocated blocks (highest value of CURRENT\_COUNT\_USED). |
| LOW\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Lowest number of bytes used. |
| CURRENT\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Current number of bytes used (total allocated minus total freed). |
| HIGH\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Highest number of bytes used. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-memory_summary_by_host_by_event_name-table/>

Performance Schema memory\_summary\_by\_thread\_by\_event\_name Table
=====================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The memory\_summary\_by\_thread\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
There are five memory summary tables in the Performance Schema that share a number of fields in common. These include:

 * [memory\_summary\_by\_account\_by\_event\_name](../performance-schema-memory_summary_by_account_by_event_name-table/index)
* [memory\_summary\_by\_host\_by\_event\_name](../performance-schema-memory_summary_by_host_by_event_name-table/index)
* memory\_summary\_by\_thread\_by\_event\_name
* [memory\_summary\_by\_user\_by\_event\_name](../performance-schema-memory_summary_by_user_by_event_name-table/index)
* [memory\_global\_by\_event\_name](../performance-schema-memory_global_by_event_name-table/index)

 The `memory_summary_by_thread_by_event_name` table contains memory usage statistics aggregated by thread and event.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| THREAD\_ID | bigint(20) unsigned | NO | NULL | Thread id. |
| EVENT\_NAME | varchar(128) | NO | NULL | Event name. |
| COUNT\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of allocations to memory. |
| COUNT\_FREE | bigint(20) unsigned | NO | NULL | Total number of attempts to free the allocated memory. |
| SUM\_NUMBER\_OF\_BYTES\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of bytes allocated. |
| SUM\_NUMBER\_OF\_BYTES\_FREE | bigint(20) unsigned | NO | NULL | Total number of bytes freed |
| LOW\_COUNT\_USED | bigint(20) | NO | NULL | Lowest number of allocated blocks (lowest value of CURRENT\_COUNT\_USED). |
| CURRENT\_COUNT\_USED | bigint(20) | NO | NULL | Currently allocated blocks that have not been freed (COUNT\_ALLOC minus COUNT\_FREE). |
| HIGH\_COUNT\_USED | bigint(20) | NO | NULL | Highest number of allocated blocks (highest value of CURRENT\_COUNT\_USED). |
| LOW\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Lowest number of bytes used. |
| CURRENT\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Current number of bytes used (total allocated minus total freed). |
| HIGH\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Highest number of bytes used. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-memory_summary_by_thread_by_event_name-table/>

Performance Schema replication\_applier\_configuration Table
============================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `replication_applier_configuration` table, along with many other new [Performance Schema tables](../list-of-performance-schema-tables/index), was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The [Performance Schema](../performance-schema/index) replication\_applier\_configuration table contains configuration settings affecting replica transactions.

 It contains the following fields.

 


| Field | Type | Null | Description |
| --- | --- | --- | --- |
| CHANNEL\_NAME | char(64) | NO | Replication channel name. |
| DESIRED\_DELAY | int(11) | NO | Target number of seconds the replica should be delayed to the master. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-replication_applier_configuration-table/>

Performance Schema performance\_timers Table
============================================

    Description
-----------

 The `performance_timers` table lists available event timers. 

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TIMER_NAME` | Time name, used in the [setup\_timers](../performance-schema-setup_timers-table/index) table. |
| `TIMER_FREQUENCY` | Number of timer units per second. Dependent on the processor speed. |
| `TIMER_RESOLUTION` | Number of timer units by which timed values increase each time. |
| `TIMER_OVERHEAD` | Minimum timer overhead, determined during initialization by calling the timer 20 times and selecting the smallest value. Total overhead will be at least double this, as the timer is called at the beginning and end of each timed event. |

 
Any `NULL` values indicate that that particular timer is not available on your platform, Any timer names with a non-NULL value can be used in the [setup\_timers](../performance-schema-setup_timers-table/index) table.

 Example
-------

 
```
SELECT * FROM performance_timers;
+-------------+-----------------+------------------+---------------------+
| TIMER_NAME  | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD      |
+-------------+-----------------+------------------+---------------------+
| CYCLE       |      2293651741 |                1 |                  28 |
| NANOSECOND  |      1000000000 |                1 |                  48 |
| MICROSECOND |         1000000 |                1 |                  52 |
| MILLISECOND |            1000 |             1000 | 9223372036854775807 |
| TICK        |             106 |                1 |                 496 |
+-------------+-----------------+------------------+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-performance_timers-table/>

Performance Schema memory\_summary\_by\_user\_by\_event\_name Table
===================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The memory\_summary\_by\_user\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
There are five memory summary tables in the Performance Schema that share a number of fields in common. These include:

 * [memory\_summary\_by\_account\_by\_event\_name](../performance-schema-memory_summary_by_account_by_event_name-table/index)
* [memory\_summary\_by\_host\_by\_event\_name](../performance-schema-memory_summary_by_host_by_event_name-table/index)
* [memory\_summary\_by\_thread\_by\_event\_name](../performance-schema-memory_summary_by_thread_by_event_name-table/index)
* memory\_summary\_by\_user\_by\_event\_name
* [memory\_global\_by\_event\_name](../performance-schema-memory_global_by_event_name-table/index)

 The `memory_summary_by_user_by_event_name` table contains memory usage statistics aggregated by user and event.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| USER | char(32) | YES | NULL | User portion of the account. |
| EVENT\_NAME | varchar(128) | NO | NULL | Event name. |
| COUNT\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of allocations to memory. |
| COUNT\_FREE | bigint(20) unsigned | NO | NULL | Total number of attempts to free the allocated memory. |
| SUM\_NUMBER\_OF\_BYTES\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of bytes allocated. |
| SUM\_NUMBER\_OF\_BYTES\_FREE | bigint(20) unsigned | NO | NULL | Total number of bytes freed |
| LOW\_COUNT\_USED | bigint(20) | NO | NULL | Lowest number of allocated blocks (lowest value of CURRENT\_COUNT\_USED). |
| CURRENT\_COUNT\_USED | bigint(20) | NO | NULL | Currently allocated blocks that have not been freed (COUNT\_ALLOC minus COUNT\_FREE). |
| HIGH\_COUNT\_USED | bigint(20) | NO | NULL | Highest number of allocated blocks (highest value of CURRENT\_COUNT\_USED). |
| LOW\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Lowest number of bytes used. |
| CURRENT\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Current number of bytes used (total allocated minus total freed). |
| HIGH\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Highest number of bytes used. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-memory_summary_by_user_by_event_name-table/>

Performance Schema prepared\_statements\_instances Table
========================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The prepared\_statements\_instances table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `prepared_statements_instances` table contains aggregated statistics of prepared statements.

 The maximum number of rows in the table is determined by the [performance\_schema\_max\_prepared\_statement\_instances](../performance-schema-system-variables/index#performance_schema_max_prepared_statement_instances) system variable, which is by default autosized on startup.

 The table contains the following columns:

 
```
+-----------------------------+--------------------------------------------------------+------+-----+---------+-------+
| Field                       | Type                                                   | Null | Key | Default | Extra |
+-----------------------------+--------------------------------------------------------+------+-----+---------+-------+
| OBJECT_INSTANCE_BEGIN       | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| STATEMENT_ID                | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| STATEMENT_NAME              | varchar(64)                                            | YES  |     | NULL    |       |
| SQL_TEXT                    | longtext                                               | NO   |     | NULL    |       |
| OWNER_THREAD_ID             | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| OWNER_EVENT_ID              | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| OWNER_OBJECT_TYPE           | enum('EVENT','FUNCTION','PROCEDURE','TABLE','TRIGGER') | YES  |     | NULL    |       |
| OWNER_OBJECT_SCHEMA         | varchar(64)                                            | YES  |     | NULL    |       |
| OWNER_OBJECT_NAME           | varchar(64)                                            | YES  |     | NULL    |       |
| TIMER_PREPARE               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| COUNT_REPREPARE             | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| COUNT_EXECUTE               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_TIMER_EXECUTE           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| MIN_TIMER_EXECUTE           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| AVG_TIMER_EXECUTE           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| MAX_TIMER_EXECUTE           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_LOCK_TIME               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_ERRORS                  | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_WARNINGS                | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_ROWS_AFFECTED           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_ROWS_SENT               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_ROWS_EXAMINED           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_CREATED_TMP_DISK_TABLES | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_CREATED_TMP_TABLES      | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SELECT_FULL_JOIN        | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SELECT_FULL_RANGE_JOIN  | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SELECT_RANGE            | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SELECT_RANGE_CHECK      | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SELECT_SCAN             | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SORT_MERGE_PASSES       | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SORT_RANGE              | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SORT_ROWS               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_SORT_SCAN               | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_NO_INDEX_USED           | bigint(20) unsigned                                    | NO   |     | NULL    |       |
| SUM_NO_GOOD_INDEX_USED      | bigint(20) unsigned                                    | NO   |     | NULL    |       |
+-----------------------------+--------------------------------------------------------+------+-----+---------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-prepared_statements_instances-table/>

Performance Schema memory\_summary\_global\_by\_event\_name Table
=================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The memory\_summary\_global\_by\_event\_name table was introduced in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
There are five memory summary tables in the Performance Schema that share a number of fields in common. These include:

 * [memory\_summary\_by\_account\_by\_event\_name](../performance-schema-memory_summary_by_account_by_event_name-table/index)
* [memory\_summary\_by\_host\_by\_event\_name](../performance-schema-memory_summary_by_host_by_event_name-table/index)
* [memory\_summary\_by\_thread\_by\_event\_name](../performance-schema-memory_summary_by_thread_by_event_name-table/index)
* [memory\_summary\_by\_user\_by\_event\_name](../performance-schema-memory_summary_by_user_by_event_name-table/index)
* memory\_global\_by\_event\_name

 The `memory_summary_global_by_event_name` table contains memory usage statistics aggregated by event and event.

 The table contains the following columns:

 


| Field | Type | Null | Default | Description |
| --- | --- | --- | --- | --- |
| EVENT\_NAME | varchar(128) | NO | NULL | Event name. |
| COUNT\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of allocations to memory. |
| COUNT\_FREE | bigint(20) unsigned | NO | NULL | Total number of attempts to free the allocated memory. |
| SUM\_NUMBER\_OF\_BYTES\_ALLOC | bigint(20) unsigned | NO | NULL | Total number of bytes allocated. |
| SUM\_NUMBER\_OF\_BYTES\_FREE | bigint(20) unsigned | NO | NULL | Total number of bytes freed |
| LOW\_COUNT\_USED | bigint(20) | NO | NULL | Lowest number of allocated blocks (lowest value of CURRENT\_COUNT\_USED). |
| CURRENT\_COUNT\_USED | bigint(20) | NO | NULL | Currently allocated blocks that have not been freed (COUNT\_ALLOC minus COUNT\_FREE). |
| HIGH\_COUNT\_USED | bigint(20) | NO | NULL | Highest number of allocated blocks (highest value of CURRENT\_COUNT\_USED). |
| LOW\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Lowest number of bytes used. |
| CURRENT\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Current number of bytes used (total allocated minus total freed). |
| HIGH\_NUMBER\_OF\_BYTES\_USED | bigint(20) | NO | NULL | Highest number of bytes used. |

 
Example
-------

 Seeing what memory was most often allocated for:

 
```
SELECT * FROM memory_summary_global_by_event_name 
  ORDER BY count_alloc DESC LIMIT 1\G
*************************** 1. row ***************************
                  EVENT_NAME: memory/sql/QUICK_RANGE_SELECT::alloc
                 COUNT_ALLOC: 147976
                  COUNT_FREE: 147976
   SUM_NUMBER_OF_BYTES_ALLOC: 600190656
    SUM_NUMBER_OF_BYTES_FREE: 600190656
              LOW_COUNT_USED: 0
          CURRENT_COUNT_USED: 0
             HIGH_COUNT_USED: 68
    LOW_NUMBER_OF_BYTES_USED: 0
CURRENT_NUMBER_OF_BYTES_USED: 0
   HIGH_NUMBER_OF_BYTES_USED: 275808

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-memory_summary_global_by_event_name-table/>

Performance Schema session\_account\_connect\_attrs Table
=========================================================

    Description
-----------

 The `session_account_connect_attrs` table shows connection attributes for the current session.

 Applications can pass key/value connection attributes to the server when a connection is made. The [session\_connect\_attrs](../performance-schema-session_connect_attrs-table/index) and `session_account_connect_attrs` tables provide access to this information, for all sessions and the current session respectively.

 The C API functions [mysql\_options()](../mysql_options/index) and [mysql\_optionsv()](../mysql_optionsv/index) are used for passing connection attributes to the server.

 `session_account_connect_attrs` contains the following columns:

 


| Column | Description |
| --- | --- |
| `PROCESSLIST_ID` | Session connection identifier. |
| `ATTR_NAME` | Attribute name. |
| `ATTR_VALUE` | Attribute value. |
| `ORDINAL_POSITION` | Order in which attribute was added to the connection attributes. |

 
Example
-------

 
```
SELECT * FROM performance_schema.session_account_connect_attrs;
+----------------+-----------------+------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE       | ORDINAL_POSITION |
+----------------+-----------------+------------------+------------------+
|             45 | _os             | debian-linux-gnu |                0 |
|             45 | _client_name    | libmysql         |                1 |
|             45 | _pid            | 7711             |                2 |
|             45 | _client_version | 10.0.5           |                3 |
|             45 | _platform       | x86_64           |                4 |
|             45 | program_name    | mysql            |                5 |
+----------------+-----------------+------------------+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-session_account_connect_attrs-table/>

Performance Schema rwlock\_instances Table
==========================================

    The `rwlock_instances` table lists all read write lock (rwlock) instances that the Performance Schema sees while the server is executing. A read write is a mechanism for ensuring threads can either share access to common resources, or have exclusive access.

 The [performance\_schema\_max\_rwlock\_instances](../performance-schema-system-variables/index#performance_schema_max_rwlock_instances) system variable specifies the maximum number of instrumented rwlock objects. 

 The `rwlock_instances` table contains the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Instrument name associated with the read write lock |
| `OBJECT_INSTANCE_BEGIN` | Address in memory of the instrumented lock |
| `WRITE_LOCKED_BY_THREAD_ID` | `THREAD_ID` of the locking thread if locked in write (exclusive) mode, otherwise `NULL`. |
| `READ_LOCKED_BY_COUNT` | Count of current read locks held |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-rwlock_instances-table/>

Performance Schema replication\_applier\_status Table
=====================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `replication_applier_status` table, along with many other new [Performance Schema tables](../list-of-performance-schema-tables/index), was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The [Performance Schema](../performance-schema/index) replication\_applier\_status table contains information about the general transaction execution status on the replica.

 It contains the following fields.

 


| Field | Type | Null | Description |
| --- | --- | --- | --- |
| CHANNEL\_NAME | char(64) | NO | The replication channel name. |
| SERVICE\_STATE | enum('ON','OFF') | NO | Shows ON when the replication channel's applier threads are active or idle, OFF means that the applier threads are not active. |
| REMAINING\_DELAY | int(10) unsigned | YES | Seconds the replica needs to wait to reach the desired delay from master. |
| COUNT\_TRANSACTIONS\_RETRIES | bigint(20) unsigned | NO | The number of retries that were made because the replication SQL thread failed to apply a transaction. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-replication_applier_status-table/>

Performance Schema replication\_applier\_status\_by\_worker Table
=================================================================

    
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**The `replication_applier_status_by_worker` table was added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).

 
The [Performance Schema](../performance-schema/index) replication\_applier\_status\_by\_worker table displays replica worker thread specific information.

 It contains the following fields.

 


| Column | Description |
| --- | --- |
| CHANNEL\_NAME | Name of replication channel through which the transaction is received. |
| THREAD\_ID | Thread\_Id as displayed in the [performance\_schema.threads](../performance-schema-threads-table/index) table for thread with name 'thread/sql/rpl\_parallel\_thread'. THREAD\_ID will be NULL when worker threads are stopped due to error/force stop. |
| SERVICE\_STATE | Whether or not the thread is running. |
| LAST\_SEEN\_TRANSACTION | Last GTID executed by worker |
| LAST\_ERROR\_NUMBER | Last Error that occurred on a particular worker. |
| LAST\_ERROR\_MESSAGE | Last error specific message. |
| LAST\_ERROR\_TIMESTAMP | Time stamp of last error. |
| WORKER\_IDLE\_TIME | Total idle time in seconds that the worker thread has spent waiting for work from SQL thread. |
| LAST\_TRANS\_RETRY\_COUNT | Total number of retries attempted by last transaction. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-replication_applier_status_by_worker-table/>

Performance Schema replication\_applier\_status\_by\_coordinator Table
======================================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `replication_applier_status_by_coordinator` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The [Performance Schema](../performance-schema/index) replication\_applier\_status\_by\_coordinator table displays the status of the coordinator thread used in multi-threaded replicas to manage multiple worker threads.

 It contains the following fields.

 


| Column | Type | Null | Description |
| --- | --- | --- | --- |
| CHANNEL\_NAME | varchar(256) | NO | Replication channel name. |
| THREAD\_ID | bigint(20) unsigned | YES | The SQL/coordinator thread ID. |
| SERVICE\_STATE | enum('ON','OFF') | NO | ON (thread exists and is active or idle) or OFF (thread no longer exists). |
| LAST\_ERROR\_NUMBER | int(11) | NO | Last error number that caused the SQL/coordinator thread to stop. |
| LAST\_ERROR\_MESSAGE | varchar(1024) | NO | Last error message that caused the SQL/coordinator thread to stop. |
| LAST\_ERROR\_TIMESTAMP | timestamp | NO | Timestamp that shows when the most recent SQL/coordinator error occured. |
| LAST\_SEEN\_TRANSACTION | char(57) | NO | The transaction the worker has last seen. |
| LAST\_TRANS\_RETRY\_COUNT | int(11) | NO | Total number of retries attempted by last transaction. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-replication_applier_status_by_coordinator-table/>

Performance Schema session\_connect\_attrs Table
================================================

    Description
-----------

 `session_connect_attrs` is a [Performance Schema](../performance-schema/index) table that shows connection attributes for all sessions. The Performance Schema needs to be enabled for the table to be populated.

 Applications can pass key/value connection attributes to the server when a connection is made. The `session_connect_attrs` and [session\_account\_connect\_attrs](../performance-schema-session_account_connect_attrs-table/index) tables provide access to this information, for all sessions and the current session respectively.

 The C API functions [mysql\_options()](../mysql_options/index) and [mysql\_optionsv()](../mysql_optionsv/index) are used for passing connection attributes to the server.

 `session_connect_attrs` contains the following columns:

 


| Column | Description |
| --- | --- |
| `PROCESSLIST_ID` | Session connection identifier. |
| `ATTR_NAME` | Attribute name. |
| `ATTR_VALUE` | Attribute value. |
| `ORDINAL_POSITION` | Order in which attribute was added to the connection attributes. |

 
Example
-------

 Returning the current connection's attributes:

 
```
SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id=CONNECTION_ID();
+----------------+-----------------+------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE       | ORDINAL_POSITION |
+----------------+-----------------+------------------+------------------+
|             45 | _os             | debian-linux-gnu |                0 |
|             45 | _client_name    | libmysql         |                1 |
|             45 | _pid            | 7711             |                2 |
|             45 | _client_version | 10.0.5           |                3 |
|             45 | _platform       | x86_64           |                4 |
|             45 | program_name    | mysql            |                5 |
+----------------+-----------------+------------------+------------------+

```

Using Other Connectors
----------------------

 ### JDBC

 Connection attributes values are set using the option [connectionAttributes](../about-mariadb-connector-j/index#infrequently-used-parameters). 

 Example using connection string `jdbc:mariadb://localhost/?connectionAttributes=test:test1,test2:test2Val,test3`

 
```
SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id=17;
+----------------+-----------------+---------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE          | ORDINAL_POSITION |
+----------------+-----------------+---------------------+------------------+
|             17 | _client_name    | MariaDB Connector/J |                0 |
|             17 | _client_version | 3.1.3               |                1 |
|             17 | _server_host    | localhost           |                2 |
|             17 | _os             | Windows 11          |                3 |
|             17 | _thread         | 1                   |                4 |
|             17 | _java_vendor    | Oracle Corporation  |                5 |
|             17 | _java_version   | 19.0.2              |                6 |
|             17 | test            | test1               |                7 |
|             17 | test2           | test2Val            |                8 |
|             17 | test3           | NULL                |                9 |
+----------------+-----------------+---------------------+------------------+

```

### Node.js

 Connection attributes values are set using the option [connectAttributes](../nodejs-connection-options/index#other-options)

 Example using connection 

 
```
 const conn = await mariadb.createConnection({
  host: 'localhost',
  user: 'root',
  connectAttributes: { test: 'test1', test2: 'test2Val', test3: 'f' }
 });

```


```
SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id=30;
+----------------+-----------------+------------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE             | ORDINAL_POSITION |
+----------------+-----------------+------------------------+------------------+
|             30 | _client_name    | MariaDB connector/Node |                0 |
|             30 | _client_version | 3.1.1                  |                1 |
|             30 | _server_host    | ::1                    |                2 |
|             30 | _os             | win32                  |                3 |
|             30 | _client_host    | NOSTROMO               |                4 |
|             30 | _node_version   | 18.15.0                |                5 |
|             30 | test            | test1                  |                6 |
|             30 | test2           | test2Val               |                7 |
|             30 | test3           | f                      |                8 |
+----------------+-----------------+------------------------+------------------+

```

### R2DBC

 Connection attributes values are set using the option [connectionAttributes](https://github.com/mariadb-corporation/mariadb-connector-r2dbc#connection-options). 

 Example using connection string `jdbc:mariadb://localhost/?connectionAttributes=test:test1,test2:test2Val,test3`

 
```
    TreeMap<String, String> connectionAttributes = new TreeMap<>();
    connectionAttributes.put("entry1", "val1");
    connectionAttributes.put("entry2", "val2");

     MariadbConnectionConfiguration conf = MariadbConnectionConfiguration.builder()
             .host("localhost")
             .port(3306) 
             .username("root")
             .connectionAttributes(connectionAttributes)
             .database("test")
             .build();
     MariadbConnectionFactory connFactory = new MariadbConnectionFactory(conf);
     MariadbConnection connection = connFactory.create().block();

```


```
SELECT * FROM performance_schema.session_connect_attrs WHERE processlist_id=34;
+----------------+-----------------+--------------------+------------------+
| PROCESSLIST_ID | ATTR_NAME       | ATTR_VALUE         | ORDINAL_POSITION |
+----------------+-----------------+--------------------+------------------+
|             34 | _client_name    | mariadb            |                0 |
|             34 | _client_version | 1.1.4              |                1 |
|             34 | _server_host    | localhost          |                2 |
|             34 | _os             | Windows 11         |                3 |
|             34 | _thread         | 49                 |                4 |
|             34 | _java_vendor    | Oracle Corporation |                5 |
|             34 | _java_version   | 19.0.2             |                6 |
|             34 | entry1          | val1               |                7 |
|             34 | entry2          | val2               |                8 |
+----------------+-----------------+--------------------+------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-session_connect_attrs-table/>

Performance Schema replication\_connection\_configuration Table
===============================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `replication_connection_configuration` table was added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).

 
The [Performance Schema](../performance-schema/index) replication\_connection\_configuration table displays replica's configuration settings used for connecting to the primary.

 It contains the following fields.

 


| Column | Type | Null | Description |
| --- | --- | --- | --- |
| CHANNEL\_NAME | varchar(256) | NO | The replication channel used. |
| HOST | char(60) | NO | The host name of the source that the replica is connected to. |
| PORT | int(11) | NO | The port used to connect to the source. |
| USER | char(32) | NO | The user name of the replication user account used to connect to the source. |
| USING\_GTID | enum('NO', 'CURRENT\_POS', 'SLAVE\_POS') | NO | Whether replication is using GTIDs or not. |
| SSL\_ALLOWED | enum('YES', 'NO', 'IGNORED') | NO | Whether SSL is allowed for the replica connection. |
| SSL\_CA\_FILE | varchar(512) | NO | Path to the file that contains one or more certificates for trusted Certificate Authorities (CA) to use for TLS. |
| SSL\_CA\_PATH | varchar(512) | NO | Path to a directory that contains one or more PEM files that contain X509 certificates for a trusted Certificate Authority (CA) to use for TLS. |
| SSL\_CERTIFICATE | varchar(512) | NO | Path to the certificate used to authenticate the master. |
| SSL\_CIPHER | varchar(512) | NO | Which cipher is used for encription. |
| SSL\_KEY | varchar(512) | NO | Path to the private key used for TLS. |
| SSL\_VERIFY\_SERVER\_CERTIFICATE | enum('YES','NO') | NO | Whether the server certificate is verified as part of the SSL connection. |
| SSL\_CRL\_FILE | varchar(255) | NO | Path to the PEM file containing one or more revoked X.509 certificates. |
| SSL\_CRL\_PATH | varchar(255) | NO | PATH to a folder containing PEM files containing one or more revoked X.509 certificates. |
| CONNECTION\_RETRY\_INTERVAL | int(11) | NO | The number of seconds between connect retries. |
| CONNECTION\_RETRY\_COUNT | bigint(20) unsigned | NO | The number of times the replica can attempt to reconnect to the source in the event of a lost connection. |
| HEARTBEAT\_INTERVAL | double(10,3) unsigned | NO | Number of seconds after which a heartbeat will be sent. |
| IGNORE\_SERVER\_IDS | longtext | NO | Binary log events from servers (ids) to ignore. |
| REPL\_DO\_DOMAIN\_IDS | longtext | NO | Only apply binary logs from these domain ids. |
| REPL\_IGNORE\_DOMAIN\_IDS | longtext | NO | Binary log events from domains to ignore. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-replication_connection_configuration-table/>

Performance Schema setup\_timers Table
======================================

    Description
-----------

 The `setup_timers` table shows the currently selected event timers.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Type of instrument the timer is used for. |
| `TIMER_NAME` | Timer applying to the instrument type. Can be modified. |

 
The `TIMER_NAME` value can be changed to choose a different timer, and can be any non-NULL value in the [performance\_timers.TIMER\_NAME](../performance-schema-performance_timers-table/index) column.

 If you modify the table, monitoring is immediately affected, and currently monitored events would use a combination of old and new timers, which is probably undesirable. It is best to reset the Performance Schema statistics if you make changes to this table. 

 Example
-------

 
```
SELECT * FROM setup_timers;
+-----------+-------------+
| NAME      | TIMER_NAME  |
+-----------+-------------+
| idle      | MICROSECOND |
| wait      | CYCLE       |
| stage     | NANOSECOND  |
| statement | NANOSECOND  |
+-----------+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-setup_timers-table/>

Performance Schema socket\_summary\_by\_event\_name Table
=========================================================

    It aggregates timer and byte count statistics for all socket I/O operations by socket instrument.

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Socket instrument. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, including `RECV`, `RECVFROM`, and `RECVMSG`. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `SUM_NUMBER_OF_BYTES_READ` | Bytes read by read operations. |
| `COUNT_WRITE` | Number of all write operations, including `SEND`, `SENDTO`, and `SENDMSG`. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `SUM_NUMBER_OF_BYTES_WRITE` | Bytes written by write operations. |
| `COUNT_MISC` | Number of all miscellaneous operations not counted above, including `CONNECT`, `LISTEN`, `ACCEPT`, `CLOSE`, and `SHUTDOWN`. |
| `SUM_TIMER_MISC` | Total wait time of all miscellaneous operations that are timed. |
| `MIN_TIMER_MISC` | Minimum wait time of all miscellaneous operations that are timed. |
| `AVG_TIMER_MISC` | Average wait time of all miscellaneous operations that are timed. |
| `MAX_TIMER_MISC` | Maximum wait time of all miscellaneous operations that are timed. |

 
You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

 Example
-------

 
```
SELECT * FROM socket_summary_by_event_name\G
*************************** 1. row ***************************
               EVENT_NAME: wait/io/socket/sql/server_tcpip_socket
               COUNT_STAR: 0
           SUM_TIMER_WAIT: 0
           MIN_TIMER_WAIT: 0
           AVG_TIMER_WAIT: 0
           MAX_TIMER_WAIT: 0
               COUNT_READ: 0
           SUM_TIMER_READ: 0
           MIN_TIMER_READ: 0
           AVG_TIMER_READ: 0
           MAX_TIMER_READ: 0
 SUM_NUMBER_OF_BYTES_READ: 0
              COUNT_WRITE: 0
          SUM_TIMER_WRITE: 0
          MIN_TIMER_WRITE: 0
          AVG_TIMER_WRITE: 0
          MAX_TIMER_WRITE: 0
SUM_NUMBER_OF_BYTES_WRITE: 0
               COUNT_MISC: 0
           SUM_TIMER_MISC: 0
           MIN_TIMER_MISC: 0
           AVG_TIMER_MISC: 0
           MAX_TIMER_MISC: 0
*************************** 2. row ***************************
               EVENT_NAME: wait/io/socket/sql/server_unix_socket
               COUNT_STAR: 0
           SUM_TIMER_WAIT: 0
           MIN_TIMER_WAIT: 0
           AVG_TIMER_WAIT: 0
           MAX_TIMER_WAIT: 0
               COUNT_READ: 0
           SUM_TIMER_READ: 0
           MIN_TIMER_READ: 0
           AVG_TIMER_READ: 0
           MAX_TIMER_READ: 0
 SUM_NUMBER_OF_BYTES_READ: 0
              COUNT_WRITE: 0
          SUM_TIMER_WRITE: 0
          MIN_TIMER_WRITE: 0
          AVG_TIMER_WRITE: 0
          MAX_TIMER_WRITE: 0
SUM_NUMBER_OF_BYTES_WRITE: 0
               COUNT_MISC: 0
           SUM_TIMER_MISC: 0
           MIN_TIMER_MISC: 0
           AVG_TIMER_MISC: 0
           MAX_TIMER_MISC: 0
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-socket_summary_by_event_name-table/>

Performance Schema socket\_instances Table
==========================================

    The `socket_instances` table lists active server connections, with each record being a Unix socket file or TCP/IP connection.

 The `socket_instances` table contains the following columns:

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | `NAME` from the `setup_instruments` table, and the name of the `wait/io/socket/*` instrument that produced the event. |
| `OBJECT_INSTANCE_BEGIN` | Memory address of the object. |
| `THREAD_ID` | Thread identifier that the server assigns to each socket. |
| `SOCKET_ID` | The socket's internal file handle. |
| `IP` | Client IP address. Blank for Unix socket file, otherwise an IPv4 or IPv6 address. Together with the PORT identifies the connection. |
| `PORT` | TCP/IP port number, from 0 to 65535. Together with the IP identifies the connection. |
| `STATE` | Socket status, either `IDLE` if waiting to receive a request from a client, or `ACTIVE` |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-socket_instances-table/>

Performance Schema session\_status Table
========================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `session_status` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `session_status` table contains a list of status variables for the current session. The table only stores status variable statistics for threads which are instrumented, and does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `VARIABLE_NAME` | The session status variable name. |
| `VARIABLE_VALUE` | The session status variable value. |

 
It is not possible to empty this table with a `TRUNCATE TABLE` statement.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-session_status-table/>

Performance Schema socket\_summary\_by\_instance Table
======================================================

    It aggregates timer and byte count statistics for all socket I/O operations by socket instance.

 


| Column | Description |
| --- | --- |
| `EVENT_NAME` | Socket instrument. |
| `OBJECT_INSTANCE_BEGIN` | Address in memory. |
| `COUNT_STAR` | Number of summarized events |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, including `RECV`, `RECVFROM`, and `RECVMSG`. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `SUM_NUMBER_OF_BYTES_READ` | Bytes read by read operations. |
| `COUNT_WRITE` | Number of all write operations, including `SEND`, `SENDTO`, and `SENDMSG`. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `SUM_NUMBER_OF_BYTES_WRITE` | Bytes written by write operations. |
| `COUNT_MISC` | Number of all miscellaneous operations not counted above, including `CONNECT`, `LISTEN`, `ACCEPT`, `CLOSE`, and `SHUTDOWN`. |
| `SUM_TIMER_MISC` | Total wait time of all miscellaneous operations that are timed. |
| `MIN_TIMER_MISC` | Minimum wait time of all miscellaneous operations that are timed. |
| `AVG_TIMER_MISC` | Average wait time of all miscellaneous operations that are timed. |
| `MAX_TIMER_MISC` | Maximum wait time of all miscellaneous operations that are timed. |

 
The corresponding row in the table is deleted when a connection terminates.

 You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-socket_summary_by_instance-table/>

Performance Schema table\_io\_waits\_summary\_by\_index\_usage Table
====================================================================

    The `table_io_waits_summary_by_index_usage` table records table I/O waits by index.

 


| Column | Description |
| --- | --- |
| `OBJECT_TYPE` | `TABLE` in the case of all indexes. |
| `OBJECT_SCHEMA` | Schema name. |
| `OBJECT_NAME` | Table name. |
| `INDEX_NAME` | Index name, or `PRIMARY` for the primary index, `NULL` for no index (inserts are counted in this case). |
| `COUNT_STAR` | Number of summarized events and the sum of the `x_READ` and `x_WRITE` columns. |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, and the sum of the equivalent `x_FETCH` columns. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `COUNT_WRITE` | Number of all write operations, and the sum of the equivalent `x_INSERT`, `x_UPDATE` and `x_DELETE` columns. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `COUNT_FETCH` | Number of all fetch operations. |
| `SUM_TIMER_FETCH` | Total wait time of all fetch operations that are timed. |
| `MIN_TIMER_FETCH` | Minimum wait time of all fetch operations that are timed. |
| `AVG_TIMER_FETCH` | Average wait time of all fetch operations that are timed. |
| `MAX_TIMER_FETCH` | Maximum wait time of all fetch operations that are timed. |
| `COUNT_INSERT` | Number of all insert operations. |
| `SUM_TIMER_INSERT` | Total wait time of all insert operations that are timed. |
| `MIN_TIMER_INSERT` | Minimum wait time of all insert operations that are timed. |
| `AVG_TIMER_INSERT` | Average wait time of all insert operations that are timed. |
| `MAX_TIMER_INSERT` | Maximum wait time of all insert operations that are timed. |
| `COUNT_UPDATE` | Number of all update operations. |
| `SUM_TIMER_UPDATE` | Total wait time of all update operations that are timed. |
| `MIN_TIMER_UPDATE` | Minimum wait time of all update operations that are timed. |
| `AVG_TIMER_UPDATE` | Average wait time of all update operations that are timed. |
| `MAX_TIMER_UPDATE` | Maximum wait time of all update operations that are timed. |
| `COUNT_DELETE` | Number of all delete operations. |
| `SUM_TIMER_DELETE` | Total wait time of all delete operations that are timed. |
| `MIN_TIMER_DELETE` | Minimum wait time of all delete operations that are timed. |
| `AVG_TIMER_DELETE` | Average wait time of all delete operations that are timed. |
| `MAX_TIMER_DELETE` | Maximum wait time of all delete operations that are timed. |

 
You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero. The table is also truncated if the [table\_io\_waits\_summary\_by\_table](../performance-schema-table_io_waits_summary_by_table-table/index) table is truncated.

 If a table's index structure is changed, index statistics recorded in this table may also be reset.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-table_io_waits_summary_by_index_usage-table/>

Performance Schema setup\_instruments Table
===========================================

    The `setup_instruments` table contains a list of instrumented object classes for which it is possible to collect events. There is one row for each instrument in the source code. When an instrument is enabled and executed, instances are created which are then stored in the [cond\_instances](../performance-schema-cond_instances-table/index), [file\_instances](../performance-schema-file_instances-table/index), [mutex\_instances](../performance-schema-mutex_instances-table/index), [rwlock\_instances](../performance-schema-rwlock_instances-table/index) or [socket\_instance](../performance-schema-socket_instances-table/index) tables.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `NAME` | Instrument name |
| `ENABLED` | Whether or not the instrument is enabled. It can be disabled, and the instrument will produce no events. |
| `TIMED` | Whether or not the instrument is timed. It can be set, but if disabled, events produced by the instrument will have `NULL` values for the corresponding `TIMER_START`, `TIMER_END`, and `TIMER_WAIT` values. |

 
Example
-------

 From [MariaDB 10.5.7](https://mariadb.com/kb/en/mariadb-1057-release-notes/), default settings with the Performance Schema enabled:

 
```
SELECT * FROM setup_instruments ORDER BY name;
+--------------------------------------------------------------------------------+---------+-------+
| NAME                                                                           | ENABLED | TIMED |
+--------------------------------------------------------------------------------+---------+-------+
| idle                                                                           | YES     | YES   |
| memory/csv/blobroot                                                            | NO      | NO    |
| memory/csv/row                                                                 | NO      | NO    |
| memory/csv/tina_set                                                            | NO      | NO    |
| memory/csv/TINA_SHARE                                                          | NO      | NO    |
| memory/csv/Transparent_file                                                    | NO      | NO    |
| memory/innodb/adaptive hash index                                              | NO      | NO    |
| memory/innodb/btr0btr                                                          | NO      | NO    |
| memory/innodb/btr0buf                                                          | NO      | NO    |
| memory/innodb/btr0bulk                                                         | NO      | NO    |
| memory/innodb/btr0cur                                                          | NO      | NO    |
| memory/innodb/btr0pcur                                                         | NO      | NO    |
| memory/innodb/btr0sea                                                          | NO      | NO    |
| memory/innodb/buf0buf                                                          | NO      | NO    |
| memory/innodb/buf0dblwr                                                        | NO      | NO    |
| memory/innodb/buf0dump                                                         | NO      | NO    |
| memory/innodb/buf_buf_pool                                                     | NO      | NO    |
| memory/innodb/dict0dict                                                        | NO      | NO    |
| memory/innodb/dict0mem                                                         | NO      | NO    |
| memory/innodb/dict0stats                                                       | NO      | NO    |
| memory/innodb/dict_stats_bg_recalc_pool_t                                      | NO      | NO    |
| memory/innodb/dict_stats_index_map_t                                           | NO      | NO    |
| memory/innodb/dict_stats_n_diff_on_level                                       | NO      | NO    |
| memory/innodb/eval0eval                                                        | NO      | NO    |
| memory/innodb/fil0crypt                                                        | NO      | NO    |
| memory/innodb/fil0fil                                                          | NO      | NO    |
| memory/innodb/fsp0file                                                         | NO      | NO    |
| memory/innodb/fts0ast                                                          | NO      | NO    |
| memory/innodb/fts0blex                                                         | NO      | NO    |
| memory/innodb/fts0config                                                       | NO      | NO    |
| memory/innodb/fts0file                                                         | NO      | NO    |
| memory/innodb/fts0fts                                                          | NO      | NO    |
| memory/innodb/fts0opt                                                          | NO      | NO    |
| memory/innodb/fts0pars                                                         | NO      | NO    |
| memory/innodb/fts0que                                                          | NO      | NO    |
| memory/innodb/fts0sql                                                          | NO      | NO    |
| memory/innodb/fts0tlex                                                         | NO      | NO    |
| memory/innodb/gis0sea                                                          | NO      | NO    |
| memory/innodb/handler0alter                                                    | NO      | NO    |
| memory/innodb/hash0hash                                                        | NO      | NO    |
| memory/innodb/ha_innodb                                                        | NO      | NO    |
| memory/innodb/i_s                                                              | NO      | NO    |
| memory/innodb/lexyy                                                            | NO      | NO    |
| memory/innodb/lock0lock                                                        | NO      | NO    |
| memory/innodb/mem0mem                                                          | NO      | NO    |
| memory/innodb/os0event                                                         | NO      | NO    |
| memory/innodb/os0file                                                          | NO      | NO    |
| memory/innodb/other                                                            | NO      | NO    |
| memory/innodb/pars0lex                                                         | NO      | NO    |
| memory/innodb/rem0rec                                                          | NO      | NO    |
| memory/innodb/row0ftsort                                                       | NO      | NO    |
| memory/innodb/row0import                                                       | NO      | NO    |
| memory/innodb/row0log                                                          | NO      | NO    |
| memory/innodb/row0merge                                                        | NO      | NO    |
| memory/innodb/row0mysql                                                        | NO      | NO    |
| memory/innodb/row0sel                                                          | NO      | NO    |
| memory/innodb/row_log_buf                                                      | NO      | NO    |
| memory/innodb/row_merge_sort                                                   | NO      | NO    |
| memory/innodb/srv0start                                                        | NO      | NO    |
| memory/innodb/std                                                              | NO      | NO    |
| memory/innodb/sync0arr                                                         | NO      | NO    |
| memory/innodb/sync0debug                                                       | NO      | NO    |
| memory/innodb/sync0rw                                                          | NO      | NO    |
| memory/innodb/sync0start                                                       | NO      | NO    |
| memory/innodb/sync0types                                                       | NO      | NO    |
| memory/innodb/trx0i_s                                                          | NO      | NO    |
| memory/innodb/trx0roll                                                         | NO      | NO    |
| memory/innodb/trx0rseg                                                         | NO      | NO    |
| memory/innodb/trx0seg                                                          | NO      | NO    |
| memory/innodb/trx0trx                                                          | NO      | NO    |
| memory/innodb/trx0undo                                                         | NO      | NO    |
| memory/innodb/ut0list                                                          | NO      | NO    |
| memory/innodb/ut0mem                                                           | NO      | NO    |
| memory/innodb/ut0new                                                           | NO      | NO    |
| memory/innodb/ut0pool                                                          | NO      | NO    |
| memory/innodb/ut0rbt                                                           | NO      | NO    |
| memory/innodb/ut0wqueue                                                        | NO      | NO    |
| memory/innodb/xtrabackup                                                       | NO      | NO    |
| memory/memory/HP_INFO                                                          | NO      | NO    |
| memory/memory/HP_KEYDEF                                                        | NO      | NO    |
| memory/memory/HP_PTRS                                                          | NO      | NO    |
| memory/memory/HP_SHARE                                                         | NO      | NO    |
| memory/myisam/filecopy                                                         | NO      | NO    |
| memory/myisam/FTB                                                              | NO      | NO    |
| memory/myisam/FTPARSER_PARAM                                                   | NO      | NO    |
| memory/myisam/FT_INFO                                                          | NO      | NO    |
| memory/myisam/ft_memroot                                                       | NO      | NO    |
| memory/myisam/ft_stopwords                                                     | NO      | NO    |
| memory/myisam/keycache_thread_var                                              | NO      | NO    |
| memory/myisam/MI_DECODE_TREE                                                   | NO      | NO    |
| memory/myisam/MI_INFO                                                          | NO      | NO    |
| memory/myisam/MI_INFO::bulk_insert                                             | NO      | NO    |
| memory/myisam/MI_INFO::ft1_to_ft2                                              | NO      | NO    |
| memory/myisam/MI_SORT_PARAM                                                    | NO      | NO    |
| memory/myisam/MI_SORT_PARAM::wordroot                                          | NO      | NO    |
| memory/myisam/MYISAM_SHARE                                                     | NO      | NO    |
| memory/myisam/MYISAM_SHARE::decode_tables                                      | NO      | NO    |
| memory/myisam/preload_buffer                                                   | NO      | NO    |
| memory/myisam/record_buffer                                                    | NO      | NO    |
| memory/myisam/SORT_FT_BUF                                                      | NO      | NO    |
| memory/myisam/SORT_INFO::buffer                                                | NO      | NO    |
| memory/myisam/SORT_KEY_BLOCKS                                                  | NO      | NO    |
| memory/myisam/stPageList::pages                                                | NO      | NO    |
| memory/myisammrg/children                                                      | NO      | NO    |
| memory/myisammrg/MYRG_INFO                                                     | NO      | NO    |
| memory/partition/ha_partition::file                                            | NO      | NO    |
| memory/partition/ha_partition::part_ids                                        | NO      | NO    |
| memory/partition/Partition_admin                                               | NO      | NO    |
| memory/partition/Partition_share                                               | NO      | NO    |
| memory/partition/partition_sort_buffer                                         | NO      | NO    |
| memory/performance_schema/accounts                                             | YES     | NO    |
| memory/performance_schema/cond_class                                           | YES     | NO    |
| memory/performance_schema/cond_instances                                       | YES     | NO    |
| memory/performance_schema/events_stages_history                                | YES     | NO    |
| memory/performance_schema/events_stages_history_long                           | YES     | NO    |
| memory/performance_schema/events_stages_summary_by_account_by_event_name       | YES     | NO    |
| memory/performance_schema/events_stages_summary_by_host_by_event_name          | YES     | NO    |
| memory/performance_schema/events_stages_summary_by_thread_by_event_name        | YES     | NO    |
| memory/performance_schema/events_stages_summary_by_user_by_event_name          | YES     | NO    |
| memory/performance_schema/events_stages_summary_global_by_event_name           | YES     | NO    |
| memory/performance_schema/events_statements_current                            | YES     | NO    |
| memory/performance_schema/events_statements_current.sqltext                    | YES     | NO    |
| memory/performance_schema/events_statements_current.tokens                     | YES     | NO    |
| memory/performance_schema/events_statements_history                            | YES     | NO    |
| memory/performance_schema/events_statements_history.sqltext                    | YES     | NO    |
| memory/performance_schema/events_statements_history.tokens                     | YES     | NO    |
| memory/performance_schema/events_statements_history_long                       | YES     | NO    |
| memory/performance_schema/events_statements_history_long.sqltext               | YES     | NO    |
| memory/performance_schema/events_statements_history_long.tokens                | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_account_by_event_name   | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_digest                  | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_digest.tokens           | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_host_by_event_name      | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_program                 | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name    | YES     | NO    |
| memory/performance_schema/events_statements_summary_by_user_by_event_name      | YES     | NO    |
| memory/performance_schema/events_statements_summary_global_by_event_name       | YES     | NO    |
| memory/performance_schema/events_transactions_history                          | YES     | NO    |
| memory/performance_schema/events_transactions_history_long                     | YES     | NO    |
| memory/performance_schema/events_transactions_summary_by_account_by_event_name | YES     | NO    |
| memory/performance_schema/events_transactions_summary_by_host_by_event_name    | YES     | NO    |
| memory/performance_schema/events_transactions_summary_by_thread_by_event_name  | YES     | NO    |
| memory/performance_schema/events_transactions_summary_by_user_by_event_name    | YES     | NO    |
| memory/performance_schema/events_waits_history                                 | YES     | NO    |
| memory/performance_schema/events_waits_history_long                            | YES     | NO    |
| memory/performance_schema/events_waits_summary_by_account_by_event_name        | YES     | NO    |
| memory/performance_schema/events_waits_summary_by_host_by_event_name           | YES     | NO    |
| memory/performance_schema/events_waits_summary_by_thread_by_event_name         | YES     | NO    |
| memory/performance_schema/events_waits_summary_by_user_by_event_name           | YES     | NO    |
| memory/performance_schema/file_class                                           | YES     | NO    |
| memory/performance_schema/file_handle                                          | YES     | NO    |
| memory/performance_schema/file_instances                                       | YES     | NO    |
| memory/performance_schema/hosts                                                | YES     | NO    |
| memory/performance_schema/memory_class                                         | YES     | NO    |
| memory/performance_schema/memory_summary_by_account_by_event_name              | YES     | NO    |
| memory/performance_schema/memory_summary_by_host_by_event_name                 | YES     | NO    |
| memory/performance_schema/memory_summary_by_thread_by_event_name               | YES     | NO    |
| memory/performance_schema/memory_summary_by_user_by_event_name                 | YES     | NO    |
| memory/performance_schema/memory_summary_global_by_event_name                  | YES     | NO    |
| memory/performance_schema/metadata_locks                                       | YES     | NO    |
| memory/performance_schema/mutex_class                                          | YES     | NO    |
| memory/performance_schema/mutex_instances                                      | YES     | NO    |
| memory/performance_schema/prepared_statements_instances                        | YES     | NO    |
| memory/performance_schema/rwlock_class                                         | YES     | NO    |
| memory/performance_schema/rwlock_instances                                     | YES     | NO    |
| memory/performance_schema/scalable_buffer                                      | YES     | NO    |
| memory/performance_schema/session_connect_attrs                                | YES     | NO    |
| memory/performance_schema/setup_actors                                         | YES     | NO    |
| memory/performance_schema/setup_objects                                        | YES     | NO    |
| memory/performance_schema/socket_class                                         | YES     | NO    |
| memory/performance_schema/socket_instances                                     | YES     | NO    |
| memory/performance_schema/stage_class                                          | YES     | NO    |
| memory/performance_schema/statement_class                                      | YES     | NO    |
| memory/performance_schema/table_handles                                        | YES     | NO    |
| memory/performance_schema/table_io_waits_summary_by_index_usage                | YES     | NO    |
| memory/performance_schema/table_lock_waits_summary_by_table                    | YES     | NO    |
| memory/performance_schema/table_shares                                         | YES     | NO    |
| memory/performance_schema/threads                                              | YES     | NO    |
| memory/performance_schema/thread_class                                         | YES     | NO    |
| memory/performance_schema/users                                                | YES     | NO    |
| memory/sql/acl_cache                                                           | NO      | NO    |
| memory/sql/binlog_cache_mngr                                                   | NO      | NO    |
| memory/sql/binlog_pos                                                          | NO      | NO    |
| memory/sql/binlog_statement_buffer                                             | NO      | NO    |
| memory/sql/binlog_ver_1_event                                                  | NO      | NO    |
| memory/sql/bison_stack                                                         | NO      | NO    |
| memory/sql/Blob_mem_storage::storage                                           | NO      | NO    |
| memory/sql/DATE_TIME_FORMAT                                                    | NO      | NO    |
| memory/sql/dboptions_hash                                                      | NO      | NO    |
| memory/sql/DDL_LOG_MEMORY_ENTRY                                                | NO      | NO    |
| memory/sql/display_table_locks                                                 | NO      | NO    |
| memory/sql/errmsgs                                                             | NO      | NO    |
| memory/sql/Event_basic::mem_root                                               | NO      | NO    |
| memory/sql/Event_queue_element_for_exec::names                                 | NO      | NO    |
| memory/sql/Event_scheduler::scheduler_param                                    | NO      | NO    |
| memory/sql/Filesort_info::merge                                                | NO      | NO    |
| memory/sql/Filesort_info::record_pointers                                      | NO      | NO    |
| memory/sql/frm::string                                                         | NO      | NO    |
| memory/sql/gdl                                                                 | NO      | NO    |
| memory/sql/Gis_read_stream::err_msg                                            | NO      | NO    |
| memory/sql/global_system_variables                                             | NO      | NO    |
| memory/sql/handler::errmsgs                                                    | NO      | NO    |
| memory/sql/handlerton                                                          | NO      | NO    |
| memory/sql/hash_index_key_buffer                                               | NO      | NO    |
| memory/sql/host_cache::hostname                                                | NO      | NO    |
| memory/sql/ignored_db                                                          | NO      | NO    |
| memory/sql/JOIN_CACHE                                                          | NO      | NO    |
| memory/sql/load_env_plugins                                                    | NO      | NO    |
| memory/sql/Locked_tables_list::m_locked_tables_root                            | NO      | NO    |
| memory/sql/MDL_context::acquire_locks                                          | NO      | NO    |
| memory/sql/MPVIO_EXT::auth_info                                                | NO      | NO    |
| memory/sql/MYSQL_BIN_LOG::basename                                             | NO      | NO    |
| memory/sql/MYSQL_BIN_LOG::index                                                | NO      | NO    |
| memory/sql/MYSQL_BIN_LOG::recover                                              | NO      | NO    |
| memory/sql/MYSQL_LOCK                                                          | NO      | NO    |
| memory/sql/MYSQL_LOG::name                                                     | NO      | NO    |
| memory/sql/mysql_plugin                                                        | NO      | NO    |
| memory/sql/mysql_plugin_dl                                                     | NO      | NO    |
| memory/sql/MYSQL_RELAY_LOG::basename                                           | NO      | NO    |
| memory/sql/MYSQL_RELAY_LOG::index                                              | NO      | NO    |
| memory/sql/my_str_malloc                                                       | NO      | NO    |
| memory/sql/NAMED_ILINK::name                                                   | NO      | NO    |
| memory/sql/native_functions                                                    | NO      | NO    |
| memory/sql/plugin_bookmark                                                     | NO      | NO    |
| memory/sql/plugin_int_mem_root                                                 | NO      | NO    |
| memory/sql/plugin_mem_root                                                     | NO      | NO    |
| memory/sql/Prepared_statement::main_mem_root                                   | NO      | NO    |
| memory/sql/Prepared_statement_map                                              | NO      | NO    |
| memory/sql/PROFILE                                                             | NO      | NO    |
| memory/sql/Query_cache                                                         | NO      | NO    |
| memory/sql/Queue::queue_item                                                   | NO      | NO    |
| memory/sql/QUICK_RANGE_SELECT::alloc                                           | NO      | NO    |
| memory/sql/QUICK_RANGE_SELECT::mrr_buf_desc                                    | NO      | NO    |
| memory/sql/Relay_log_info::group_relay_log_name                                | NO      | NO    |
| memory/sql/root                                                                | NO      | NO    |
| memory/sql/Row_data_memory::memory                                             | NO      | NO    |
| memory/sql/rpl_filter memory                                                   | NO      | NO    |
| memory/sql/Rpl_info_file::buffer                                               | NO      | NO    |
| memory/sql/servers_cache                                                       | NO      | NO    |
| memory/sql/SLAVE_INFO                                                          | NO      | NO    |
| memory/sql/Sort_param::tmp_buffer                                              | NO      | NO    |
| memory/sql/sp_head::call_mem_root                                              | NO      | NO    |
| memory/sql/sp_head::execute_mem_root                                           | NO      | NO    |
| memory/sql/sp_head::main_mem_root                                              | NO      | NO    |
| memory/sql/sql_acl_mem                                                         | NO      | NO    |
| memory/sql/sql_acl_memex                                                       | NO      | NO    |
| memory/sql/String::value                                                       | NO      | NO    |
| memory/sql/ST_SCHEMA_TABLE                                                     | NO      | NO    |
| memory/sql/Sys_var_charptr::value                                              | NO      | NO    |
| memory/sql/TABLE                                                               | NO      | NO    |
| memory/sql/table_mapping::m_mem_root                                           | NO      | NO    |
| memory/sql/TABLE_RULE_ENT                                                      | NO      | NO    |
| memory/sql/TABLE_SHARE::mem_root                                               | NO      | NO    |
| memory/sql/Table_triggers_list                                                 | NO      | NO    |
| memory/sql/Table_trigger_dispatcher::m_mem_root                                | NO      | NO    |
| memory/sql/TC_LOG_MMAP::pages                                                  | NO      | NO    |
| memory/sql/THD::db                                                             | NO      | NO    |
| memory/sql/THD::handler_tables_hash                                            | NO      | NO    |
| memory/sql/thd::main_mem_root                                                  | NO      | NO    |
| memory/sql/THD::sp_cache                                                       | NO      | NO    |
| memory/sql/THD::transactions::mem_root                                         | NO      | NO    |
| memory/sql/THD::variables                                                      | NO      | NO    |
| memory/sql/tz_storage                                                          | NO      | NO    |
| memory/sql/udf_mem                                                             | NO      | NO    |
| memory/sql/Unique::merge_buffer                                                | NO      | NO    |
| memory/sql/Unique::sort_buffer                                                 | NO      | NO    |
| memory/sql/user_conn                                                           | NO      | NO    |
| memory/sql/User_level_lock                                                     | NO      | NO    |
| memory/sql/user_var_entry                                                      | NO      | NO    |
| memory/sql/user_var_entry::value                                               | NO      | NO    |
| memory/sql/XID                                                                 | NO      | NO    |
| stage/aria/Waiting for a resource                                              | NO      | NO    |
| stage/innodb/alter table (end)                                                 | YES     | YES   |
| stage/innodb/alter table (insert)                                              | YES     | YES   |
| stage/innodb/alter table (log apply index)                                     | YES     | YES   |
| stage/innodb/alter table (log apply table)                                     | YES     | YES   |
| stage/innodb/alter table (merge sort)                                          | YES     | YES   |
| stage/innodb/alter table (read PK and internal sort)                           | YES     | YES   |
| stage/innodb/buffer pool load                                                  | YES     | YES   |
| stage/mysys/Waiting for table level lock                                       | NO      | NO    |
| stage/sql/After apply log event                                                | NO      | NO    |
| stage/sql/After create                                                         | NO      | NO    |
| stage/sql/After opening tables                                                 | NO      | NO    |
| stage/sql/After table lock                                                     | NO      | NO    |
| stage/sql/Allocating local table                                               | NO      | NO    |
| stage/sql/altering table                                                       | NO      | NO    |
| stage/sql/Apply log event                                                      | NO      | NO    |
| stage/sql/Changing master                                                      | NO      | NO    |
| stage/sql/Checking master version                                              | NO      | NO    |
| stage/sql/checking permissions                                                 | NO      | NO    |
| stage/sql/checking privileges on cached query                                  | NO      | NO    |
| stage/sql/Checking query cache for query                                       | NO      | NO    |
| stage/sql/closing tables                                                       | NO      | NO    |
| stage/sql/Commit                                                               | NO      | NO    |
| stage/sql/Commit implicit                                                      | NO      | NO    |
| stage/sql/Committing alter table to storage engine                             | NO      | NO    |
| stage/sql/Connecting to master                                                 | NO      | NO    |
| stage/sql/Converting HEAP to Aria                                              | NO      | NO    |
| stage/sql/copy to tmp table                                                    | YES     | YES   |
| stage/sql/Copying to group table                                               | NO      | NO    |
| stage/sql/Copying to tmp table                                                 | NO      | NO    |
| stage/sql/Creating delayed handler                                             | NO      | NO    |
| stage/sql/Creating sort index                                                  | NO      | NO    |
| stage/sql/creating table                                                       | NO      | NO    |
| stage/sql/Creating tmp table                                                   | NO      | NO    |
| stage/sql/Deleting from main table                                             | NO      | NO    |
| stage/sql/Deleting from reference tables                                       | NO      | NO    |
| stage/sql/Discard_or_import_tablespace                                         | NO      | NO    |
| stage/sql/Enabling keys                                                        | NO      | NO    |
| stage/sql/End of update loop                                                   | NO      | NO    |
| stage/sql/Executing                                                            | NO      | NO    |
| stage/sql/Execution of init_command                                            | NO      | NO    |
| stage/sql/Explaining                                                           | NO      | NO    |
| stage/sql/Filling schema table                                                 | NO      | NO    |
| stage/sql/Finding key cache                                                    | NO      | NO    |
| stage/sql/Finished reading one binlog; switching to next binlog                | NO      | NO    |
| stage/sql/Flushing relay log and master info repository.                       | NO      | NO    |
| stage/sql/Flushing relay-log info file.                                        | NO      | NO    |
| stage/sql/Freeing items                                                        | NO      | NO    |
| stage/sql/Fulltext initialization                                              | NO      | NO    |
| stage/sql/Got handler lock                                                     | NO      | NO    |
| stage/sql/Got old table                                                        | NO      | NO    |
| stage/sql/init                                                                 | NO      | NO    |
| stage/sql/init for update                                                      | NO      | NO    |
| stage/sql/Insert                                                               | NO      | NO    |
| stage/sql/Invalidating query cache entries (table list)                        | NO      | NO    |
| stage/sql/Invalidating query cache entries (table)                             | NO      | NO    |
| stage/sql/Killing slave                                                        | NO      | NO    |
| stage/sql/Logging slow query                                                   | NO      | NO    |
| stage/sql/Making temporary file (append) before replaying LOAD DATA INFILE     | NO      | NO    |
| stage/sql/Making temporary file (create) before replaying LOAD DATA INFILE     | NO      | NO    |
| stage/sql/Manage keys                                                          | NO      | NO    |
| stage/sql/Master has sent all binlog to slave; waiting for more updates        | NO      | NO    |
| stage/sql/Opening tables                                                       | NO      | NO    |
| stage/sql/Optimizing                                                           | NO      | NO    |
| stage/sql/Preparing                                                            | NO      | NO    |
| stage/sql/preparing for alter table                                            | NO      | NO    |
| stage/sql/Processing binlog checkpoint notification                            | NO      | NO    |
| stage/sql/Processing requests                                                  | NO      | NO    |
| stage/sql/Purging old relay logs                                               | NO      | NO    |
| stage/sql/Query end                                                            | NO      | NO    |
| stage/sql/Queueing master event to the relay log                               | NO      | NO    |
| stage/sql/Reading event from the relay log                                     | NO      | NO    |
| stage/sql/Reading semi-sync ACK from slave                                     | NO      | NO    |
| stage/sql/Recreating table                                                     | NO      | NO    |
| stage/sql/Registering slave on master                                          | NO      | NO    |
| stage/sql/Removing duplicates                                                  | NO      | NO    |
| stage/sql/Removing tmp table                                                   | NO      | NO    |
| stage/sql/Rename                                                               | NO      | NO    |
| stage/sql/Rename result table                                                  | NO      | NO    |
| stage/sql/Requesting binlog dump                                               | NO      | NO    |
| stage/sql/Reschedule                                                           | NO      | NO    |
| stage/sql/Reset for next command                                               | NO      | NO    |
| stage/sql/Rollback                                                             | NO      | NO    |
| stage/sql/Rollback_implicit                                                    | NO      | NO    |
| stage/sql/Searching rows for update                                            | NO      | NO    |
| stage/sql/Sending binlog event to slave                                        | NO      | NO    |
| stage/sql/Sending cached result to client                                      | NO      | NO    |
| stage/sql/Sending data                                                         | NO      | NO    |
| stage/sql/setup                                                                | NO      | NO    |
| stage/sql/Show explain                                                         | NO      | NO    |
| stage/sql/Slave has read all relay log; waiting for more updates               | NO      | NO    |
| stage/sql/Sorting                                                              | NO      | NO    |
| stage/sql/Sorting for group                                                    | NO      | NO    |
| stage/sql/Sorting for order                                                    | NO      | NO    |
| stage/sql/Sorting result                                                       | NO      | NO    |
| stage/sql/starting                                                             | NO      | NO    |
| stage/sql/Starting cleanup                                                     | NO      | NO    |
| stage/sql/Statistics                                                           | NO      | NO    |
| stage/sql/Stopping binlog background thread                                    | NO      | NO    |
| stage/sql/Storing result in query cache                                        | NO      | NO    |
| stage/sql/Storing row into queue                                               | NO      | NO    |
| stage/sql/System lock                                                          | NO      | NO    |
| stage/sql/table lock                                                           | NO      | NO    |
| stage/sql/Unlocking tables                                                     | NO      | NO    |
| stage/sql/Update                                                               | NO      | NO    |
| stage/sql/Updating                                                             | NO      | NO    |
| stage/sql/Updating main table                                                  | NO      | NO    |
| stage/sql/Updating reference tables                                            | NO      | NO    |
| stage/sql/Upgrading lock                                                       | NO      | NO    |
| stage/sql/User lock                                                            | NO      | NO    |
| stage/sql/User sleep                                                           | NO      | NO    |
| stage/sql/Verifying table                                                      | NO      | NO    |
| stage/sql/Waiting for background binlog tasks                                  | NO      | NO    |
| stage/sql/Waiting for backup lock                                              | NO      | NO    |
| stage/sql/Waiting for delay_list                                               | NO      | NO    |
| stage/sql/Waiting for event metadata lock                                      | NO      | NO    |
| stage/sql/Waiting for GTID to be written to binary log                         | NO      | NO    |
| stage/sql/Waiting for handler insert                                           | NO      | NO    |
| stage/sql/Waiting for handler lock                                             | NO      | NO    |
| stage/sql/Waiting for handler open                                             | NO      | NO    |
| stage/sql/Waiting for INSERT                                                   | NO      | NO    |
| stage/sql/Waiting for master to send event                                     | NO      | NO    |
| stage/sql/Waiting for master update                                            | NO      | NO    |
| stage/sql/Waiting for next activation                                          | NO      | NO    |
| stage/sql/Waiting for other master connection to process the same GTID         | NO      | NO    |
| stage/sql/Waiting for parallel replication deadlock handling to complete       | NO      | NO    |
| stage/sql/Waiting for prior transaction to commit                              | NO      | NO    |
| stage/sql/Waiting for prior transaction to start commit                        | NO      | NO    |
| stage/sql/Waiting for query cache lock                                         | NO      | NO    |
| stage/sql/Waiting for requests                                                 | NO      | NO    |
| stage/sql/Waiting for room in worker thread event queue                        | NO      | NO    |
| stage/sql/Waiting for schema metadata lock                                     | NO      | NO    |
| stage/sql/Waiting for semi-sync ACK from slave                                 | NO      | NO    |
| stage/sql/Waiting for semi-sync slave connection                               | NO      | NO    |
| stage/sql/Waiting for slave mutex on exit                                      | NO      | NO    |
| stage/sql/Waiting for slave thread to start                                    | NO      | NO    |
| stage/sql/Waiting for stored function metadata lock                            | NO      | NO    |
| stage/sql/Waiting for stored package body metadata lock                        | NO      | NO    |
| stage/sql/Waiting for stored procedure metadata lock                           | NO      | NO    |
| stage/sql/Waiting for table flush                                              | NO      | NO    |
| stage/sql/Waiting for table metadata lock                                      | NO      | NO    |
| stage/sql/Waiting for the next event in relay log                              | NO      | NO    |
| stage/sql/Waiting for the scheduler to stop                                    | NO      | NO    |
| stage/sql/Waiting for the slave SQL thread to advance position                 | NO      | NO    |
| stage/sql/Waiting for the slave SQL thread to free enough relay log space      | NO      | NO    |
| stage/sql/Waiting for trigger metadata lock                                    | NO      | NO    |
| stage/sql/Waiting for work from SQL thread                                     | NO      | NO    |
| stage/sql/Waiting in MASTER_GTID_WAIT()                                        | NO      | NO    |
| stage/sql/Waiting in MASTER_GTID_WAIT() (primary waiter)                       | NO      | NO    |
| stage/sql/Waiting on empty queue                                               | NO      | NO    |
| stage/sql/Waiting to finalize termination                                      | NO      | NO    |
| stage/sql/Waiting until MASTER_DELAY seconds after master executed event       | NO      | NO    |
| stage/sql/Writing to binlog                                                    | NO      | NO    |
| statement/abstract/new_packet                                                  | YES     | YES   |
| statement/abstract/Query                                                       | YES     | YES   |
| statement/abstract/relay_log                                                   | YES     | YES   |
| statement/com/Binlog Dump                                                      | YES     | YES   |
| statement/com/Bulk_execute                                                     | YES     | YES   |
| statement/com/Change user                                                      | YES     | YES   |
| statement/com/Close stmt                                                       | YES     | YES   |
| statement/com/Com_multi                                                        | YES     | YES   |
| statement/com/Connect                                                          | YES     | YES   |
| statement/com/Connect Out                                                      | YES     | YES   |
| statement/com/Create DB                                                        | YES     | YES   |
| statement/com/Daemon                                                           | YES     | YES   |
| statement/com/Debug                                                            | YES     | YES   |
| statement/com/Delayed insert                                                   | YES     | YES   |
| statement/com/Drop DB                                                          | YES     | YES   |
| statement/com/Error                                                            | YES     | YES   |
| statement/com/Execute                                                          | YES     | YES   |
| statement/com/Fetch                                                            | YES     | YES   |
| statement/com/Field List                                                       | YES     | YES   |
| statement/com/Init DB                                                          | YES     | YES   |
| statement/com/Kill                                                             | YES     | YES   |
| statement/com/Long Data                                                        | YES     | YES   |
| statement/com/Ping                                                             | YES     | YES   |
| statement/com/Prepare                                                          | YES     | YES   |
| statement/com/Processlist                                                      | YES     | YES   |
| statement/com/Quit                                                             | YES     | YES   |
| statement/com/Refresh                                                          | YES     | YES   |
| statement/com/Register Slave                                                   | YES     | YES   |
| statement/com/Reset connection                                                 | YES     | YES   |
| statement/com/Reset stmt                                                       | YES     | YES   |
| statement/com/Set option                                                       | YES     | YES   |
| statement/com/Shutdown                                                         | YES     | YES   |
| statement/com/Slave_IO                                                         | YES     | YES   |
| statement/com/Slave_SQL                                                        | YES     | YES   |
| statement/com/Slave_worker                                                     | YES     | YES   |
| statement/com/Sleep                                                            | YES     | YES   |
| statement/com/Statistics                                                       | YES     | YES   |
| statement/com/Table Dump                                                       | YES     | YES   |
| statement/com/Time                                                             | YES     | YES   |
| statement/com/Unimpl get tid                                                   | YES     | YES   |
| statement/scheduler/event                                                      | YES     | YES   |
| statement/sp/agg_cfetch                                                        | YES     | YES   |
| statement/sp/cclose                                                            | YES     | YES   |
| statement/sp/cfetch                                                            | YES     | YES   |
| statement/sp/copen                                                             | YES     | YES   |
| statement/sp/cpop                                                              | YES     | YES   |
| statement/sp/cpush                                                             | YES     | YES   |
| statement/sp/cursor_copy_struct                                                | YES     | YES   |
| statement/sp/error                                                             | YES     | YES   |
| statement/sp/freturn                                                           | YES     | YES   |
| statement/sp/hpop                                                              | YES     | YES   |
| statement/sp/hpush_jump                                                        | YES     | YES   |
| statement/sp/hreturn                                                           | YES     | YES   |
| statement/sp/jump                                                              | YES     | YES   |
| statement/sp/jump_if_not                                                       | YES     | YES   |
| statement/sp/preturn                                                           | YES     | YES   |
| statement/sp/set                                                               | YES     | YES   |
| statement/sp/set_case_expr                                                     | YES     | YES   |
| statement/sp/set_trigger_field                                                 | YES     | YES   |
| statement/sp/stmt                                                              | YES     | YES   |
| statement/sql/                                                                 | YES     | YES   |
| statement/sql/alter_db                                                         | YES     | YES   |
| statement/sql/alter_db_upgrade                                                 | YES     | YES   |
| statement/sql/alter_event                                                      | YES     | YES   |
| statement/sql/alter_function                                                   | YES     | YES   |
| statement/sql/alter_procedure                                                  | YES     | YES   |
| statement/sql/alter_sequence                                                   | YES     | YES   |
| statement/sql/alter_server                                                     | YES     | YES   |
| statement/sql/alter_table                                                      | YES     | YES   |
| statement/sql/alter_tablespace                                                 | YES     | YES   |
| statement/sql/alter_user                                                       | YES     | YES   |
| statement/sql/analyze                                                          | YES     | YES   |
| statement/sql/assign_to_keycache                                               | YES     | YES   |
| statement/sql/backup                                                           | YES     | YES   |
| statement/sql/backup_lock                                                      | YES     | YES   |
| statement/sql/begin                                                            | YES     | YES   |
| statement/sql/binlog                                                           | YES     | YES   |
| statement/sql/call_procedure                                                   | YES     | YES   |
| statement/sql/change_db                                                        | YES     | YES   |
| statement/sql/change_master                                                    | YES     | YES   |
| statement/sql/check                                                            | YES     | YES   |
| statement/sql/checksum                                                         | YES     | YES   |
| statement/sql/commit                                                           | YES     | YES   |
| statement/sql/compound_sql                                                     | YES     | YES   |
| statement/sql/create_db                                                        | YES     | YES   |
| statement/sql/create_event                                                     | YES     | YES   |
| statement/sql/create_function                                                  | YES     | YES   |
| statement/sql/create_index                                                     | YES     | YES   |
| statement/sql/create_package                                                   | YES     | YES   |
| statement/sql/create_package_body                                              | YES     | YES   |
| statement/sql/create_procedure                                                 | YES     | YES   |
| statement/sql/create_role                                                      | YES     | YES   |
| statement/sql/create_sequence                                                  | YES     | YES   |
| statement/sql/create_server                                                    | YES     | YES   |
| statement/sql/create_table                                                     | YES     | YES   |
| statement/sql/create_trigger                                                   | YES     | YES   |
| statement/sql/create_udf                                                       | YES     | YES   |
| statement/sql/create_user                                                      | YES     | YES   |
| statement/sql/create_view                                                      | YES     | YES   |
| statement/sql/dealloc_sql                                                      | YES     | YES   |
| statement/sql/delete                                                           | YES     | YES   |
| statement/sql/delete_multi                                                     | YES     | YES   |
| statement/sql/do                                                               | YES     | YES   |
| statement/sql/drop_db                                                          | YES     | YES   |
| statement/sql/drop_event                                                       | YES     | YES   |
| statement/sql/drop_function                                                    | YES     | YES   |
| statement/sql/drop_index                                                       | YES     | YES   |
| statement/sql/drop_package                                                     | YES     | YES   |
| statement/sql/drop_package_body                                                | YES     | YES   |
| statement/sql/drop_procedure                                                   | YES     | YES   |
| statement/sql/drop_role                                                        | YES     | YES   |
| statement/sql/drop_sequence                                                    | YES     | YES   |
| statement/sql/drop_server                                                      | YES     | YES   |
| statement/sql/drop_table                                                       | YES     | YES   |
| statement/sql/drop_trigger                                                     | YES     | YES   |
| statement/sql/drop_user                                                        | YES     | YES   |
| statement/sql/drop_view                                                        | YES     | YES   |
| statement/sql/empty_query                                                      | YES     | YES   |
| statement/sql/error                                                            | YES     | YES   |
| statement/sql/execute_immediate                                                | YES     | YES   |
| statement/sql/execute_sql                                                      | YES     | YES   |
| statement/sql/flush                                                            | YES     | YES   |
| statement/sql/get_diagnostics                                                  | YES     | YES   |
| statement/sql/grant                                                            | YES     | YES   |
| statement/sql/grant_role                                                       | YES     | YES   |
| statement/sql/ha_close                                                         | YES     | YES   |
| statement/sql/ha_open                                                          | YES     | YES   |
| statement/sql/ha_read                                                          | YES     | YES   |
| statement/sql/help                                                             | YES     | YES   |
| statement/sql/insert                                                           | YES     | YES   |
| statement/sql/insert_select                                                    | YES     | YES   |
| statement/sql/install_plugin                                                   | YES     | YES   |
| statement/sql/kill                                                             | YES     | YES   |
| statement/sql/load                                                             | YES     | YES   |
| statement/sql/lock_tables                                                      | YES     | YES   |
| statement/sql/optimize                                                         | YES     | YES   |
| statement/sql/preload_keys                                                     | YES     | YES   |
| statement/sql/prepare_sql                                                      | YES     | YES   |
| statement/sql/purge                                                            | YES     | YES   |
| statement/sql/purge_before_date                                                | YES     | YES   |
| statement/sql/release_savepoint                                                | YES     | YES   |
| statement/sql/rename_table                                                     | YES     | YES   |
| statement/sql/rename_user                                                      | YES     | YES   |
| statement/sql/repair                                                           | YES     | YES   |
| statement/sql/replace                                                          | YES     | YES   |
| statement/sql/replace_select                                                   | YES     | YES   |
| statement/sql/reset                                                            | YES     | YES   |
| statement/sql/resignal                                                         | YES     | YES   |
| statement/sql/revoke                                                           | YES     | YES   |
| statement/sql/revoke_all                                                       | YES     | YES   |
| statement/sql/revoke_role                                                      | YES     | YES   |
| statement/sql/rollback                                                         | YES     | YES   |
| statement/sql/rollback_to_savepoint                                            | YES     | YES   |
| statement/sql/savepoint                                                        | YES     | YES   |
| statement/sql/select                                                           | YES     | YES   |
| statement/sql/set_option                                                       | YES     | YES   |
| statement/sql/show_authors                                                     | YES     | YES   |
| statement/sql/show_binlogs                                                     | YES     | YES   |
| statement/sql/show_binlog_events                                               | YES     | YES   |
| statement/sql/show_binlog_status                                               | YES     | YES   |
| statement/sql/show_charsets                                                    | YES     | YES   |
| statement/sql/show_collations                                                  | YES     | YES   |
| statement/sql/show_contributors                                                | YES     | YES   |
| statement/sql/show_create_db                                                   | YES     | YES   |
| statement/sql/show_create_event                                                | YES     | YES   |
| statement/sql/show_create_func                                                 | YES     | YES   |
| statement/sql/show_create_package                                              | YES     | YES   |
| statement/sql/show_create_package_body                                         | YES     | YES   |
| statement/sql/show_create_proc                                                 | YES     | YES   |
| statement/sql/show_create_table                                                | YES     | YES   |
| statement/sql/show_create_trigger                                              | YES     | YES   |
| statement/sql/show_create_user                                                 | YES     | YES   |
| statement/sql/show_databases                                                   | YES     | YES   |
| statement/sql/show_engine_logs                                                 | YES     | YES   |
| statement/sql/show_engine_mutex                                                | YES     | YES   |
| statement/sql/show_engine_status                                               | YES     | YES   |
| statement/sql/show_errors                                                      | YES     | YES   |
| statement/sql/show_events                                                      | YES     | YES   |
| statement/sql/show_explain                                                     | YES     | YES   |
| statement/sql/show_fields                                                      | YES     | YES   |
| statement/sql/show_function_status                                             | YES     | YES   |
| statement/sql/show_generic                                                     | YES     | YES   |
| statement/sql/show_grants                                                      | YES     | YES   |
| statement/sql/show_keys                                                        | YES     | YES   |
| statement/sql/show_open_tables                                                 | YES     | YES   |
| statement/sql/show_package_body_status                                         | YES     | YES   |
| statement/sql/show_package_status                                              | YES     | YES   |
| statement/sql/show_plugins                                                     | YES     | YES   |
| statement/sql/show_privileges                                                  | YES     | YES   |
| statement/sql/show_procedure_status                                            | YES     | YES   |
| statement/sql/show_processlist                                                 | YES     | YES   |
| statement/sql/show_profile                                                     | YES     | YES   |
| statement/sql/show_profiles                                                    | YES     | YES   |
| statement/sql/show_relaylog_events                                             | YES     | YES   |
| statement/sql/show_slave_hosts                                                 | YES     | YES   |
| statement/sql/show_slave_status                                                | YES     | YES   |
| statement/sql/show_status                                                      | YES     | YES   |
| statement/sql/show_storage_engines                                             | YES     | YES   |
| statement/sql/show_tables                                                      | YES     | YES   |
| statement/sql/show_table_status                                                | YES     | YES   |
| statement/sql/show_triggers                                                    | YES     | YES   |
| statement/sql/show_variables                                                   | YES     | YES   |
| statement/sql/show_warnings                                                    | YES     | YES   |
| statement/sql/shutdown                                                         | YES     | YES   |
| statement/sql/signal                                                           | YES     | YES   |
| statement/sql/start_all_slaves                                                 | YES     | YES   |
| statement/sql/start_slave                                                      | YES     | YES   |
| statement/sql/stop_all_slaves                                                  | YES     | YES   |
| statement/sql/stop_slave                                                       | YES     | YES   |
| statement/sql/truncate                                                         | YES     | YES   |
| statement/sql/uninstall_plugin                                                 | YES     | YES   |
| statement/sql/unlock_tables                                                    | YES     | YES   |
| statement/sql/update                                                           | YES     | YES   |
| statement/sql/update_multi                                                     | YES     | YES   |
| statement/sql/xa_commit                                                        | YES     | YES   |
| statement/sql/xa_end                                                           | YES     | YES   |
| statement/sql/xa_prepare                                                       | YES     | YES   |
| statement/sql/xa_recover                                                       | YES     | YES   |
| statement/sql/xa_rollback                                                      | YES     | YES   |
| statement/sql/xa_start                                                         | YES     | YES   |
| transaction                                                                    | NO      | NO    |
| wait/io/file/aria/control                                                      | YES     | YES   |
| wait/io/file/aria/MAD                                                          | YES     | YES   |
| wait/io/file/aria/MAI                                                          | YES     | YES   |
| wait/io/file/aria/translog                                                     | YES     | YES   |
| wait/io/file/csv/data                                                          | YES     | YES   |
| wait/io/file/csv/metadata                                                      | YES     | YES   |
| wait/io/file/csv/update                                                        | YES     | YES   |
| wait/io/file/innodb/innodb_data_file                                           | YES     | YES   |
| wait/io/file/innodb/innodb_log_file                                            | YES     | YES   |
| wait/io/file/innodb/innodb_temp_file                                           | YES     | YES   |
| wait/io/file/myisam/data_tmp                                                   | YES     | YES   |
| wait/io/file/myisam/dfile                                                      | YES     | YES   |
| wait/io/file/myisam/kfile                                                      | YES     | YES   |
| wait/io/file/myisam/log                                                        | YES     | YES   |
| wait/io/file/myisammrg/MRG                                                     | YES     | YES   |
| wait/io/file/mysys/charset                                                     | YES     | YES   |
| wait/io/file/mysys/cnf                                                         | YES     | YES   |
| wait/io/file/partition/ha_partition::parfile                                   | YES     | YES   |
| wait/io/file/sql/binlog                                                        | YES     | YES   |
| wait/io/file/sql/binlog_cache                                                  | YES     | YES   |
| wait/io/file/sql/binlog_index                                                  | YES     | YES   |
| wait/io/file/sql/binlog_index_cache                                            | YES     | YES   |
| wait/io/file/sql/binlog_state                                                  | YES     | YES   |
| wait/io/file/sql/casetest                                                      | YES     | YES   |
| wait/io/file/sql/dbopt                                                         | YES     | YES   |
| wait/io/file/sql/des_key_file                                                  | YES     | YES   |
| wait/io/file/sql/ERRMSG                                                        | YES     | YES   |
| wait/io/file/sql/file_parser                                                   | YES     | YES   |
| wait/io/file/sql/FRM                                                           | YES     | YES   |
| wait/io/file/sql/global_ddl_log                                                | YES     | YES   |
| wait/io/file/sql/init                                                          | YES     | YES   |
| wait/io/file/sql/io_cache                                                      | YES     | YES   |
| wait/io/file/sql/load                                                          | YES     | YES   |
| wait/io/file/sql/LOAD_FILE                                                     | YES     | YES   |
| wait/io/file/sql/log_event_data                                                | YES     | YES   |
| wait/io/file/sql/log_event_info                                                | YES     | YES   |
| wait/io/file/sql/map                                                           | YES     | YES   |
| wait/io/file/sql/master_info                                                   | YES     | YES   |
| wait/io/file/sql/misc                                                          | YES     | YES   |
| wait/io/file/sql/partition_ddl_log                                             | YES     | YES   |
| wait/io/file/sql/pid                                                           | YES     | YES   |
| wait/io/file/sql/query_log                                                     | YES     | YES   |
| wait/io/file/sql/relaylog                                                      | YES     | YES   |
| wait/io/file/sql/relaylog_cache                                                | YES     | YES   |
| wait/io/file/sql/relaylog_index                                                | YES     | YES   |
| wait/io/file/sql/relaylog_index_cache                                          | YES     | YES   |
| wait/io/file/sql/relay_log_info                                                | YES     | YES   |
| wait/io/file/sql/select_to_file                                                | YES     | YES   |
| wait/io/file/sql/send_file                                                     | YES     | YES   |
| wait/io/file/sql/slow_log                                                      | YES     | YES   |
| wait/io/file/sql/tclog                                                         | YES     | YES   |
| wait/io/file/sql/trigger                                                       | YES     | YES   |
| wait/io/file/sql/trigger_name                                                  | YES     | YES   |
| wait/io/file/sql/wsrep_gra_log                                                 | YES     | YES   |
| wait/io/socket/sql/client_connection                                           | NO      | NO    |
| wait/io/socket/sql/server_tcpip_socket                                         | NO      | NO    |
| wait/io/socket/sql/server_unix_socket                                          | NO      | NO    |
| wait/io/table/sql/handler                                                      | YES     | YES   |
| wait/lock/metadata/sql/mdl                                                     | NO      | NO    |
| wait/lock/table/sql/handler                                                    | YES     | YES   |
| wait/synch/cond/aria/BITMAP::bitmap_cond                                       | NO      | NO    |
| wait/synch/cond/aria/COND_soft_sync                                            | NO      | NO    |
| wait/synch/cond/aria/SERVICE_THREAD_CONTROL::COND_control                      | NO      | NO    |
| wait/synch/cond/aria/SHARE::key_del_cond                                       | NO      | NO    |
| wait/synch/cond/aria/SORT_INFO::cond                                           | NO      | NO    |
| wait/synch/cond/aria/TRANSLOG_BUFFER::prev_sent_to_disk_cond                   | NO      | NO    |
| wait/synch/cond/aria/TRANSLOG_BUFFER::waiting_filling_buffer                   | NO      | NO    |
| wait/synch/cond/aria/TRANSLOG_DESCRIPTOR::log_flush_cond                       | NO      | NO    |
| wait/synch/cond/aria/TRANSLOG_DESCRIPTOR::new_goal_cond                        | NO      | NO    |
| wait/synch/cond/innodb/commit_cond                                             | NO      | NO    |
| wait/synch/cond/myisam/MI_SORT_INFO::cond                                      | NO      | NO    |
| wait/synch/cond/mysys/COND_alarm                                               | NO      | NO    |
| wait/synch/cond/mysys/COND_timer                                               | NO      | NO    |
| wait/synch/cond/mysys/IO_CACHE_SHARE::cond                                     | NO      | NO    |
| wait/synch/cond/mysys/IO_CACHE_SHARE::cond_writer                              | NO      | NO    |
| wait/synch/cond/mysys/my_thread_var::suspend                                   | NO      | NO    |
| wait/synch/cond/mysys/THR_COND_threads                                         | NO      | NO    |
| wait/synch/cond/mysys/WT_RESOURCE::cond                                        | NO      | NO    |
| wait/synch/cond/sql/Ack_receiver::cond                                         | NO      | NO    |
| wait/synch/cond/sql/COND_binlog_send                                           | NO      | NO    |
| wait/synch/cond/sql/COND_flush_thread_cache                                    | NO      | NO    |
| wait/synch/cond/sql/COND_group_commit_orderer                                  | NO      | NO    |
| wait/synch/cond/sql/COND_gtid_ignore_duplicates                                | NO      | NO    |
| wait/synch/cond/sql/COND_manager                                               | NO      | NO    |
| wait/synch/cond/sql/COND_parallel_entry                                        | NO      | NO    |
| wait/synch/cond/sql/COND_prepare_ordered                                       | NO      | NO    |
| wait/synch/cond/sql/COND_queue_state                                           | NO      | NO    |
| wait/synch/cond/sql/COND_rpl_thread                                            | NO      | NO    |
| wait/synch/cond/sql/COND_rpl_thread_pool                                       | NO      | NO    |
| wait/synch/cond/sql/COND_rpl_thread_queue                                      | NO      | NO    |
| wait/synch/cond/sql/COND_rpl_thread_stop                                       | NO      | NO    |
| wait/synch/cond/sql/COND_server_started                                        | NO      | NO    |
| wait/synch/cond/sql/COND_slave_background                                      | NO      | NO    |
| wait/synch/cond/sql/COND_start_thread                                          | NO      | NO    |
| wait/synch/cond/sql/COND_thread_cache                                          | NO      | NO    |
| wait/synch/cond/sql/COND_wait_gtid                                             | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_donor_monitor                                   | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_gtid_wait_upto                                  | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_joiner_monitor                                  | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_ready                                           | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_replaying                                       | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_sst                                             | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_sst_init                                        | NO      | NO    |
| wait/synch/cond/sql/COND_wsrep_wsrep_slave_threads                             | NO      | NO    |
| wait/synch/cond/sql/Delayed_insert::cond                                       | NO      | NO    |
| wait/synch/cond/sql/Delayed_insert::cond_client                                | NO      | NO    |
| wait/synch/cond/sql/Event_scheduler::COND_state                                | NO      | NO    |
| wait/synch/cond/sql/Item_func_sleep::cond                                      | NO      | NO    |
| wait/synch/cond/sql/Master_info::data_cond                                     | NO      | NO    |
| wait/synch/cond/sql/Master_info::sleep_cond                                    | NO      | NO    |
| wait/synch/cond/sql/Master_info::start_cond                                    | NO      | NO    |
| wait/synch/cond/sql/Master_info::stop_cond                                     | NO      | NO    |
| wait/synch/cond/sql/MDL_context::COND_wait_status                              | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_binlog_background_thread               | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_binlog_background_thread_end           | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_bin_log_updated                        | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_queue_busy                             | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_relay_log_updated                      | NO      | NO    |
| wait/synch/cond/sql/MYSQL_BIN_LOG::COND_xid_list                               | NO      | NO    |
| wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_bin_log_updated                      | NO      | NO    |
| wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_queue_busy                           | NO      | NO    |
| wait/synch/cond/sql/MYSQL_RELAY_LOG::COND_relay_log_updated                    | NO      | NO    |
| wait/synch/cond/sql/PAGE::cond                                                 | NO      | NO    |
| wait/synch/cond/sql/Query_cache::COND_cache_status_changed                     | NO      | NO    |
| wait/synch/cond/sql/Relay_log_info::data_cond                                  | NO      | NO    |
| wait/synch/cond/sql/Relay_log_info::log_space_cond                             | NO      | NO    |
| wait/synch/cond/sql/Relay_log_info::start_cond                                 | NO      | NO    |
| wait/synch/cond/sql/Relay_log_info::stop_cond                                  | NO      | NO    |
| wait/synch/cond/sql/Rpl_group_info::sleep_cond                                 | NO      | NO    |
| wait/synch/cond/sql/show_explain                                               | NO      | NO    |
| wait/synch/cond/sql/TABLE_SHARE::cond                                          | NO      | NO    |
| wait/synch/cond/sql/TABLE_SHARE::COND_rotation                                 | NO      | NO    |
| wait/synch/cond/sql/TABLE_SHARE::tdc.COND_release                              | NO      | NO    |
| wait/synch/cond/sql/TC_LOG_MMAP::COND_active                                   | NO      | NO    |
| wait/synch/cond/sql/TC_LOG_MMAP::COND_pool                                     | NO      | NO    |
| wait/synch/cond/sql/TC_LOG_MMAP::COND_queue_busy                               | NO      | NO    |
| wait/synch/cond/sql/THD::COND_wakeup_ready                                     | NO      | NO    |
| wait/synch/cond/sql/THD::COND_wsrep_thd                                        | NO      | NO    |
| wait/synch/cond/sql/User_level_lock::cond                                      | NO      | NO    |
| wait/synch/cond/sql/wait_for_commit::COND_wait_commit                          | NO      | NO    |
| wait/synch/cond/sql/wsrep_sst_thread                                           | NO      | NO    |
| wait/synch/mutex/aria/LOCK_soft_sync                                           | NO      | NO    |
| wait/synch/mutex/aria/LOCK_trn_list                                            | NO      | NO    |
| wait/synch/mutex/aria/PAGECACHE::cache_lock                                    | NO      | NO    |
| wait/synch/mutex/aria/SERVICE_THREAD_CONTROL::LOCK_control                     | NO      | NO    |
| wait/synch/mutex/aria/SHARE::bitmap::bitmap_lock                               | NO      | NO    |
| wait/synch/mutex/aria/SHARE::close_lock                                        | NO      | NO    |
| wait/synch/mutex/aria/SHARE::intern_lock                                       | NO      | NO    |
| wait/synch/mutex/aria/SHARE::key_del_lock                                      | NO      | NO    |
| wait/synch/mutex/aria/SORT_INFO::mutex                                         | NO      | NO    |
| wait/synch/mutex/aria/THR_LOCK_maria                                           | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_BUFFER::mutex                                   | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::dirty_buffer_mask_lock              | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::file_header_lock                    | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::log_flush_lock                      | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::purger_lock                         | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::sent_to_disk_lock                   | NO      | NO    |
| wait/synch/mutex/aria/TRANSLOG_DESCRIPTOR::unfinished_files_lock               | NO      | NO    |
| wait/synch/mutex/aria/TRN::state_lock                                          | NO      | NO    |
| wait/synch/mutex/csv/tina                                                      | NO      | NO    |
| wait/synch/mutex/csv/TINA_SHARE::mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/buf_dblwr_mutex                                        | NO      | NO    |
| wait/synch/mutex/innodb/buf_pool_mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/commit_cond_mutex                                      | NO      | NO    |
| wait/synch/mutex/innodb/dict_foreign_err_mutex                                 | NO      | NO    |
| wait/synch/mutex/innodb/dict_sys_mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/fil_system_mutex                                       | NO      | NO    |
| wait/synch/mutex/innodb/flush_list_mutex                                       | NO      | NO    |
| wait/synch/mutex/innodb/fts_delete_mutex                                       | NO      | NO    |
| wait/synch/mutex/innodb/fts_doc_id_mutex                                       | NO      | NO    |
| wait/synch/mutex/innodb/ibuf_bitmap_mutex                                      | NO      | NO    |
| wait/synch/mutex/innodb/ibuf_mutex                                             | NO      | NO    |
| wait/synch/mutex/innodb/ibuf_pessimistic_insert_mutex                          | NO      | NO    |
| wait/synch/mutex/innodb/lock_mutex                                             | NO      | NO    |
| wait/synch/mutex/innodb/lock_wait_mutex                                        | NO      | NO    |
| wait/synch/mutex/innodb/log_flush_order_mutex                                  | NO      | NO    |
| wait/synch/mutex/innodb/log_sys_mutex                                          | NO      | NO    |
| wait/synch/mutex/innodb/noredo_rseg_mutex                                      | NO      | NO    |
| wait/synch/mutex/innodb/page_zip_stat_per_index_mutex                          | NO      | NO    |
| wait/synch/mutex/innodb/pending_checkpoint_mutex                               | NO      | NO    |
| wait/synch/mutex/innodb/purge_sys_pq_mutex                                     | NO      | NO    |
| wait/synch/mutex/innodb/recalc_pool_mutex                                      | NO      | NO    |
| wait/synch/mutex/innodb/recv_sys_mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/redo_rseg_mutex                                        | NO      | NO    |
| wait/synch/mutex/innodb/rtr_active_mutex                                       | NO      | NO    |
| wait/synch/mutex/innodb/rtr_match_mutex                                        | NO      | NO    |
| wait/synch/mutex/innodb/rtr_path_mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/rw_lock_list_mutex                                     | NO      | NO    |
| wait/synch/mutex/innodb/srv_innodb_monitor_mutex                               | NO      | NO    |
| wait/synch/mutex/innodb/srv_misc_tmpfile_mutex                                 | NO      | NO    |
| wait/synch/mutex/innodb/srv_monitor_file_mutex                                 | NO      | NO    |
| wait/synch/mutex/innodb/srv_threads_mutex                                      | NO      | NO    |
| wait/synch/mutex/innodb/trx_mutex                                              | NO      | NO    |
| wait/synch/mutex/innodb/trx_pool_manager_mutex                                 | NO      | NO    |
| wait/synch/mutex/innodb/trx_pool_mutex                                         | NO      | NO    |
| wait/synch/mutex/innodb/trx_sys_mutex                                          | NO      | NO    |
| wait/synch/mutex/myisam/MI_CHECK::print_msg                                    | NO      | NO    |
| wait/synch/mutex/myisam/MI_SORT_INFO::mutex                                    | NO      | NO    |
| wait/synch/mutex/myisam/MYISAM_SHARE::intern_lock                              | NO      | NO    |
| wait/synch/mutex/myisammrg/MYRG_INFO::mutex                                    | NO      | NO    |
| wait/synch/mutex/mysys/BITMAP::mutex                                           | NO      | NO    |
| wait/synch/mutex/mysys/IO_CACHE::append_buffer_lock                            | NO      | NO    |
| wait/synch/mutex/mysys/IO_CACHE::SHARE_mutex                                   | NO      | NO    |
| wait/synch/mutex/mysys/KEY_CACHE::cache_lock                                   | NO      | NO    |
| wait/synch/mutex/mysys/LOCK_alarm                                              | NO      | NO    |
| wait/synch/mutex/mysys/LOCK_timer                                              | NO      | NO    |
| wait/synch/mutex/mysys/LOCK_uuid_generator                                     | NO      | NO    |
| wait/synch/mutex/mysys/my_thread_var::mutex                                    | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK::mutex                                         | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_charset                                        | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_heap                                           | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_lock                                           | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_malloc                                         | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_myisam                                         | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_myisam_mmap                                    | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_net                                            | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_open                                           | NO      | NO    |
| wait/synch/mutex/mysys/THR_LOCK_threads                                        | NO      | NO    |
| wait/synch/mutex/mysys/TMPDIR_mutex                                            | NO      | NO    |
| wait/synch/mutex/partition/Partition_share::auto_inc_mutex                     | NO      | NO    |
| wait/synch/mutex/sql/Ack_receiver::mutex                                       | NO      | NO    |
| wait/synch/mutex/sql/Cversion_lock                                             | NO      | NO    |
| wait/synch/mutex/sql/Delayed_insert::mutex                                     | NO      | NO    |
| wait/synch/mutex/sql/Event_scheduler::LOCK_scheduler_state                     | NO      | NO    |
| wait/synch/mutex/sql/gtid_waiting::LOCK_gtid_waiting                           | NO      | NO    |
| wait/synch/mutex/sql/hash_filo::lock                                           | NO      | NO    |
| wait/synch/mutex/sql/HA_DATA_PARTITION::LOCK_auto_inc                          | NO      | NO    |
| wait/synch/mutex/sql/LOCK_active_mi                                            | NO      | NO    |
| wait/synch/mutex/sql/LOCK_after_binlog_sync                                    | NO      | NO    |
| wait/synch/mutex/sql/LOCK_audit_mask                                           | NO      | NO    |
| wait/synch/mutex/sql/LOCK_binlog                                               | NO      | NO    |
| wait/synch/mutex/sql/LOCK_binlog_state                                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_commit_ordered                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_crypt                                                | NO      | NO    |
| wait/synch/mutex/sql/LOCK_delayed_create                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_delayed_insert                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_delayed_status                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_des_key_file                                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_error_log                                            | NO      | NO    |
| wait/synch/mutex/sql/LOCK_error_messages                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_event_queue                                          | NO      | NO    |
| wait/synch/mutex/sql/LOCK_gdl                                                  | NO      | NO    |
| wait/synch/mutex/sql/LOCK_global_index_stats                                   | NO      | NO    |
| wait/synch/mutex/sql/LOCK_global_system_variables                              | NO      | NO    |
| wait/synch/mutex/sql/LOCK_global_table_stats                                   | NO      | NO    |
| wait/synch/mutex/sql/LOCK_global_user_client_stats                             | NO      | NO    |
| wait/synch/mutex/sql/LOCK_item_func_sleep                                      | NO      | NO    |
| wait/synch/mutex/sql/LOCK_load_client_plugin                                   | NO      | NO    |
| wait/synch/mutex/sql/LOCK_manager                                              | NO      | NO    |
| wait/synch/mutex/sql/LOCK_parallel_entry                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_plugin                                               | NO      | NO    |
| wait/synch/mutex/sql/LOCK_prepared_stmt_count                                  | NO      | NO    |
| wait/synch/mutex/sql/LOCK_prepare_ordered                                      | NO      | NO    |
| wait/synch/mutex/sql/LOCK_rpl_semi_sync_master_enabled                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_rpl_status                                           | NO      | NO    |
| wait/synch/mutex/sql/LOCK_rpl_thread                                           | NO      | NO    |
| wait/synch/mutex/sql/LOCK_rpl_thread_pool                                      | NO      | NO    |
| wait/synch/mutex/sql/LOCK_server_started                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_slave_background                                     | NO      | NO    |
| wait/synch/mutex/sql/LOCK_slave_state                                          | NO      | NO    |
| wait/synch/mutex/sql/LOCK_start_thread                                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_stats                                                | NO      | NO    |
| wait/synch/mutex/sql/LOCK_status                                               | NO      | NO    |
| wait/synch/mutex/sql/LOCK_system_variables_hash                                | NO      | NO    |
| wait/synch/mutex/sql/LOCK_table_cache                                          | NO      | NO    |
| wait/synch/mutex/sql/LOCK_thread_cache                                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_thread_id                                            | NO      | NO    |
| wait/synch/mutex/sql/LOCK_unused_shares                                        | NO      | NO    |
| wait/synch/mutex/sql/LOCK_user_conn                                            | NO      | NO    |
| wait/synch/mutex/sql/LOCK_uuid_short_generator                                 | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_cluster_config                                 | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_config_state                                   | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_desync                                         | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_donor_monitor                                  | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_group_commit                                   | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_gtid_wait_upto                                 | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_joiner_monitor                                 | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_ready                                          | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_replaying                                      | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_slave_threads                                  | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_SR_pool                                        | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_SR_store                                       | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_sst                                            | NO      | NO    |
| wait/synch/mutex/sql/LOCK_wsrep_sst_init                                       | NO      | NO    |
| wait/synch/mutex/sql/LOG::LOCK_log                                             | NO      | NO    |
| wait/synch/mutex/sql/Master_info::data_lock                                    | NO      | NO    |
| wait/synch/mutex/sql/Master_info::run_lock                                     | NO      | NO    |
| wait/synch/mutex/sql/Master_info::sleep_lock                                   | NO      | NO    |
| wait/synch/mutex/sql/Master_info::start_stop_lock                              | NO      | NO    |
| wait/synch/mutex/sql/MDL_wait::LOCK_wait_status                                | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_background_thread              | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_binlog_end_pos                        | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_index                                 | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_BIN_LOG::LOCK_xid_list                              | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_binlog_end_pos                      | NO      | NO    |
| wait/synch/mutex/sql/MYSQL_RELAY_LOG::LOCK_index                               | NO      | NO    |
| wait/synch/mutex/sql/PAGE::lock                                                | NO      | NO    |
| wait/synch/mutex/sql/Query_cache::structure_guard_mutex                        | NO      | NO    |
| wait/synch/mutex/sql/Relay_log_info::data_lock                                 | NO      | NO    |
| wait/synch/mutex/sql/Relay_log_info::log_space_lock                            | NO      | NO    |
| wait/synch/mutex/sql/Relay_log_info::run_lock                                  | NO      | NO    |
| wait/synch/mutex/sql/Rpl_group_info::sleep_lock                                | NO      | NO    |
| wait/synch/mutex/sql/Slave_reporting_capability::err_lock                      | NO      | NO    |
| wait/synch/mutex/sql/TABLE_SHARE::LOCK_ha_data                                 | NO      | NO    |
| wait/synch/mutex/sql/TABLE_SHARE::LOCK_rotation                                | NO      | NO    |
| wait/synch/mutex/sql/TABLE_SHARE::LOCK_share                                   | NO      | NO    |
| wait/synch/mutex/sql/TABLE_SHARE::tdc.LOCK_table_share                         | NO      | NO    |
| wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_active                                  | NO      | NO    |
| wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_pending_checkpoint                      | NO      | NO    |
| wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_pool                                    | NO      | NO    |
| wait/synch/mutex/sql/TC_LOG_MMAP::LOCK_sync                                    | NO      | NO    |
| wait/synch/mutex/sql/THD::LOCK_thd_data                                        | NO      | NO    |
| wait/synch/mutex/sql/THD::LOCK_thd_kill                                        | NO      | NO    |
| wait/synch/mutex/sql/THD::LOCK_wakeup_ready                                    | NO      | NO    |
| wait/synch/mutex/sql/tz_LOCK                                                   | NO      | NO    |
| wait/synch/mutex/sql/wait_for_commit::LOCK_wait_commit                         | NO      | NO    |
| wait/synch/mutex/sql/wsrep_sst_thread                                          | NO      | NO    |
| wait/synch/rwlock/aria/KEYINFO::root_lock                                      | NO      | NO    |
| wait/synch/rwlock/aria/SHARE::mmap_lock                                        | NO      | NO    |
| wait/synch/rwlock/aria/TRANSLOG_DESCRIPTOR::open_files_lock                    | NO      | NO    |
| wait/synch/rwlock/myisam/MYISAM_SHARE::key_root_lock                           | NO      | NO    |
| wait/synch/rwlock/myisam/MYISAM_SHARE::mmap_lock                               | NO      | NO    |
| wait/synch/rwlock/mysys/SAFE_HASH::mutex                                       | NO      | NO    |
| wait/synch/rwlock/proxy_proto/rwlock                                           | NO      | NO    |
| wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock                               | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_all_status_vars                                     | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_dboptions                                           | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_grant                                               | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_SEQUENCE                                            | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_ssl_refresh                                         | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_system_variables_hash                               | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_sys_init_connect                                    | NO      | NO    |
| wait/synch/rwlock/sql/LOCK_sys_init_slave                                      | NO      | NO    |
| wait/synch/rwlock/sql/LOGGER::LOCK_logger                                      | NO      | NO    |
| wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for                            | NO      | NO    |
| wait/synch/rwlock/sql/MDL_lock::rwlock                                         | NO      | NO    |
| wait/synch/rwlock/sql/Query_cache_query::lock                                  | NO      | NO    |
| wait/synch/rwlock/sql/TABLE_SHARE::LOCK_stat_serial                            | NO      | NO    |
| wait/synch/rwlock/sql/THD_list::lock                                           | NO      | NO    |
| wait/synch/rwlock/sql/THR_LOCK_servers                                         | NO      | NO    |
| wait/synch/rwlock/sql/THR_LOCK_udf                                             | NO      | NO    |
| wait/synch/rwlock/sql/Vers_field_stats::lock                                   | NO      | NO    |
| wait/synch/sxlock/innodb/btr_search_latch                                      | NO      | NO    |
| wait/synch/sxlock/innodb/dict_operation_lock                                   | NO      | NO    |
| wait/synch/sxlock/innodb/fil_space_latch                                       | NO      | NO    |
| wait/synch/sxlock/innodb/fts_cache_init_rw_lock                                | NO      | NO    |
| wait/synch/sxlock/innodb/fts_cache_rw_lock                                     | NO      | NO    |
| wait/synch/sxlock/innodb/index_online_log                                      | NO      | NO    |
| wait/synch/sxlock/innodb/index_tree_rw_lock                                    | NO      | NO    |
| wait/synch/sxlock/innodb/trx_i_s_cache_lock                                    | NO      | NO    |
| wait/synch/sxlock/innodb/trx_purge_latch                                       | NO      | NO    |
+--------------------------------------------------------------------------------+---------+-------+
996 rows in set (0.005 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-setup_instruments-table/>

Performance Schema status\_by\_account Table
============================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `status_by_account` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `status_by_account` table contains status variable information by user/host account. The table does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| USER | User for which the status variable is reported. |
| HOST | Host for which the status variable is reported. |
| VARIABLE\_NAME | Status variable name. |
| VARIABLE\_VALUE | Aggregated status variable value |

 
If [TRUNCATE TABLE](../truncate-table/index) is run, will aggregate the status from terminated sessions to user and host status, then reset the account status. 

 If [FLUSH STATUS](flush-status) is run, session status from all active sessions are added to the global status variables, the status of all active sessions are reset, and values aggregated from disconnected sessions are reset.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-status_by_account-table/>

Performance Schema table\_lock\_waits\_summary\_by\_table Table
===============================================================

    The `table_lock_waits_summary_by_table` table records table lock waits by table.

 


| Column | Description |
| --- | --- |
| `OBJECT_TYPE` | Since this table records waits by table, always set to `TABLE`. |
| `OBJECT_SCHEMA` | Schema name. |
| `OBJECT_NAME` | Table name. |
| `COUNT_STAR` | Number of summarized events and the sum of the `x_READ` and `x_WRITE` columns. |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, and the sum of the equivalent `x_READ_NORMAL`, `x_READ_WITH_SHARED_LOCKS`, `x_READ_HIGH_PRIORITY` and `x_READ_NO_INSERT` columns. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `COUNT_WRITE` | Number of all write operations, and the sum of the equivalent `x_WRITE_ALLOW_WRITE`, `x_WRITE_CONCURRENT_INSERT`, `x_WRITE_DELAYED`, `x_WRITE_LOW_PRIORITY` and `x_WRITE_NORMAL` columns. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `COUNT_READ_NORMAL` | Number of all internal read normal locks. |
| `SUM_TIMER_READ_NORMAL` | Total wait time of all internal read normal locks that are timed. |
| `MIN_TIMER_READ_NORMAL` | Minimum wait time of all internal read normal locks that are timed. |
| `AVG_TIMER_READ_NORMAL` | Average wait time of all internal read normal locks that are timed. |
| `MAX_TIMER_READ_NORMAL` | Maximum wait time of all internal read normal locks that are timed. |
| `COUNT_READ_WITH_SHARED_LOCKS` | Number of all internal read with shared locks. |
| `SUM_TIMER_READ_WITH_SHARED_LOCKS` | Total wait time of all internal read with shared locks that are timed. |
| `MIN_TIMER_READ_WITH_SHARED_LOCKS` | Minimum wait time of all internal read with shared locks that are timed. |
| `AVG_TIMER_READ_WITH_SHARED_LOCKS` | Average wait time of all internal read with shared locks that are timed. |
| `MAX_TIMER_READ_WITH_SHARED_LOCKS` | Maximum wait time of all internal read with shared locks that are timed. |
| `COUNT_READ_HIGH_PRIORITY` | Number of all internal read high priority locks. |
| `SUM_TIMER_READ_HIGH_PRIORITY` | Total wait time of all internal read high priority locks that are timed. |
| `MIN_TIMER_READ_HIGH_PRIORITY` | Minimum wait time of all internal read high priority locks that are timed. |
| `AVG_TIMER_READ_HIGH_PRIORITY` | Average wait time of all internal read high priority locks that are timed. |
| `MAX_TIMER_READ_HIGH_PRIORITY` | Maximum wait time of all internal read high priority locks that are timed. |
| `COUNT_READ_NO_INSERT` | Number of all internal read no insert locks. |
| `SUM_TIMER_READ_NO_INSERT` | Total wait time of all internal read no insert locks that are timed. |
| `MIN_TIMER_READ_NO_INSERT` | Minimum wait time of all internal read no insert locks that are timed. |
| `AVG_TIMER_READ_NO_INSERT` | Average wait time of all internal read no insert locks that are timed. |
| `MAX_TIMER_READ_NO_INSERT` | Maximum wait time of all internal read no insert locks that are timed. |
| `COUNT_READ_EXTERNAL` | Number of all external read locks. |
| `SUM_TIMER_READ_EXTERNAL` | Total wait time of all external read locks that are timed. |
| `MIN_TIMER_READ_EXTERNAL` | Minimum wait time of all external read locks that are timed. |
| `AVG_TIMER_READ_EXTERNAL` | Average wait time of all external read locks that are timed. |
| `MAX_TIMER_READ_EXTERNAL` | Maximum wait time of all external read locks that are timed. |
| `COUNT_WRITE_ALLOW_WRITE` | Number of all internal read normal locks. |
| `SUM_TIMER_WRITE_ALLOW_WRITE` | Total wait time of all internal write allow write locks that are timed. |
| `MIN_TIMER_WRITE_ALLOW_WRITE` | Minimum wait time of all internal write allow write locks that are timed. |
| `AVG_TIMER_WRITE_ALLOW_WRITE` | Average wait time of all internal write allow write locks that are timed. |
| `MAX_TIMER_WRITE_ALLOW_WRITE` | Maximum wait time of all internal write allow write locks that are timed. |
| `COUNT_WRITE_CONCURRENT_INSERT` | Number of all internal concurrent insert write locks. |
| `SUM_TIMER_WRITE_CONCURRENT_INSERT` | Total wait time of all internal concurrent insert write locks that are timed. |
| `MIN_TIMER_WRITE_CONCURRENT_INSERT` | Minimum wait time of all internal concurrent insert write locks that are timed. |
| `AVG_TIMER_WRITE_CONCURRENT_INSERT` | Average wait time of all internal concurrent insert write locks that are timed. |
| `MAX_TIMER_WRITE_CONCURRENT_INSERT` | Maximum wait time of all internal concurrent insert write locks that are timed. |
| `COUNT_WRITE_DELAYED` | Number of all internal write delayed locks. |
| `SUM_TIMER_WRITE_DELAYED` | Total wait time of all internal write delayed locks that are timed. |
| `MIN_TIMER_WRITE_DELAYED` | Minimum wait time of all internal write delayed locks that are timed. |
| `AVG_TIMER_WRITE_DELAYED` | Average wait time of all internal write delayed locks that are timed. |
| `MAX_TIMER_WRITE_DELAYED` | Maximum wait time of all internal write delayed locks that are timed. |
| `COUNT_WRITE_LOW_PRIORITY` | Number of all internal write low priority locks. |
| `SUM_TIMER_WRITE_LOW_PRIORITY` | Total wait time of all internal write low priority locks that are timed. |
| `MIN_TIMER_WRITE_LOW_PRIORITY` | Minimum wait time of all internal write low priority locks that are timed. |
| `AVG_TIMER_WRITE_LOW_PRIORITY` | Average wait time of all internal write low priority locks that are timed. |
| `MAX_TIMER_WRITE_LOW_PRIORITY` | Maximum wait time of all internal write low priority locks that are timed. |
| `COUNT_WRITE_NORMAL` | Number of all internal write normal locks. |
| `SUM_TIMER_WRITE_NORMAL` | Total wait time of all internal write normal locks that are timed. |
| `MIN_TIMER_WRITE_NORMAL` | Minimum wait time of all internal write normal locks that are timed. |
| `AVG_TIMER_WRITE_NORMAL` | Average wait time of all internal write normal locks that are timed. |
| `MAX_TIMER_WRITE_NORMAL` | Maximum wait time of all internal write normal locks that are timed. |
| `COUNT_WRITE_EXTERNAL` | Number of all external write locks. |
| `SUM_TIMER_WRITE_EXTERNAL` | Total wait time of all external write locks that are timed. |
| `MIN_TIMER_WRITE_EXTERNAL` | Minimum wait time of all external write locks that are timed. |
| `AVG_TIMER_WRITE_EXTERNAL` | Average wait time of all external write locks that are timed. |
| `MAX_TIMER_WRITE_EXTERNAL` | Maximum wait time of all external write locks that are timed. |

 
You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-table_lock_waits_summary_by_table-table/>

Performance Schema table\_io\_waits\_summary\_by\_table Table
=============================================================

    The `table_io_waits_summary_by_table` table records table I/O waits by table.

 


| Column | Description |
| --- | --- |
| `OBJECT_TYPE` | Since this table records waits by table, always set to `TABLE`. |
| `OBJECT_SCHEMA` | Schema name. |
| `OBJECT_NAME` | Table name. |
| `COUNT_STAR` | Number of summarized events and the sum of the `x_READ` and `x_WRITE` columns. |
| `SUM_TIMER_WAIT` | Total wait time of the summarized events that are timed. |
| `MIN_TIMER_WAIT` | Minimum wait time of the summarized events that are timed. |
| `AVG_TIMER_WAIT` | Average wait time of the summarized events that are timed. |
| `MAX_TIMER_WAIT` | Maximum wait time of the summarized events that are timed. |
| `COUNT_READ` | Number of all read operations, and the sum of the equivalent `x_FETCH` columns. |
| `SUM_TIMER_READ` | Total wait time of all read operations that are timed. |
| `MIN_TIMER_READ` | Minimum wait time of all read operations that are timed. |
| `AVG_TIMER_READ` | Average wait time of all read operations that are timed. |
| `MAX_TIMER_READ` | Maximum wait time of all read operations that are timed. |
| `COUNT_WRITE` | Number of all write operations, and the sum of the equivalent `x_INSERT`, `x_UPDATE` and `x_DELETE` columns. |
| `SUM_TIMER_WRITE` | Total wait time of all write operations that are timed. |
| `MIN_TIMER_WRITE` | Minimum wait time of all write operations that are timed. |
| `AVG_TIMER_WRITE` | Average wait time of all write operations that are timed. |
| `MAX_TIMER_WRITE` | Maximum wait time of all write operations that are timed. |
| `COUNT_FETCH` | Number of all fetch operations. |
| `SUM_TIMER_FETCH` | Total wait time of all fetch operations that are timed. |
| `MIN_TIMER_FETCH` | Minimum wait time of all fetch operations that are timed. |
| `AVG_TIMER_FETCH` | Average wait time of all fetch operations that are timed. |
| `MAX_TIMER_FETCH` | Maximum wait time of all fetch operations that are timed. |
| `COUNT_INSERT` | Number of all insert operations. |
| `SUM_TIMER_INSERT` | Total wait time of all insert operations that are timed. |
| `MIN_TIMER_INSERT` | Minimum wait time of all insert operations that are timed. |
| `AVG_TIMER_INSERT` | Average wait time of all insert operations that are timed. |
| `MAX_TIMER_INSERT` | Maximum wait time of all insert operations that are timed. |
| `COUNT_UPDATE` | Number of all update operations. |
| `SUM_TIMER_UPDATE` | Total wait time of all update operations that are timed. |
| `MIN_TIMER_UPDATE` | Minimum wait time of all update operations that are timed. |
| `AVG_TIMER_UPDATE` | Average wait time of all update operations that are timed. |
| `MAX_TIMER_UPDATE` | Maximum wait time of all update operations that are timed. |
| `COUNT_DELETE` | Number of all delete operations. |
| `SUM_TIMER_DELETE` | Total wait time of all delete operations that are timed. |
| `MIN_TIMER_DELETE` | Minimum wait time of all delete operations that are timed. |
| `AVG_TIMER_DELETE` | Average wait time of all delete operations that are timed. |
| `MAX_TIMER_DELETE` | Maximum wait time of all delete operations that are timed. |

 
You can [TRUNCATE](../truncate-table/index) the table, which will reset all counters to zero. Truncating this table will also truncate the [table\_io\_waits\_summary\_by\_index\_usage](../performance-schema-table_io_waits_summary_by_index_usage-table/index) table.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-table_io_waits_summary_by_table-table/>

Performance Schema status\_by\_thread Table
===========================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `session_status` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `status_by_thread` table contains status variable information about active foreground threads. The table does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| `THREAD_ID` | The thread identifier of the session in which the status variable is defined. |
| `VARIABLE_NAME` | Status variable name. |
| `VARIABLE_VALUE` | Aggregated status variable value. |

 
If [TRUNCATE TABLE](../truncate-table/index) is run, will aggregate the status for all threads to the global status and account status, then reset the thread status. If account statistics are not collected but host and user status are, the session status is added to host and user status.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-status_by_thread-table/>

Performance Schema status\_by\_host Table
=========================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `status_by_host` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `status_by_host` table contains status variable information by host. The table does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| HOST | Host for which the status variable is reported. |
| VARIABLE\_NAME | Status variable name. |
| VARIABLE\_VALUE | Aggregated status variable value |

 
If [TRUNCATE TABLE](../truncate-table/index) is run, will reset the aggregated host status from terminated sessions. 

 If [FLUSH STATUS](flush-status) is run, session status from all active sessions are added to the global status variables, the status of all active sessions are reset, and values aggregated from disconnected sessions are reset.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-status_by_host-table/>

Performance Schema status\_by\_user Table
=========================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `status_by_account` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `status_by_account` table contains status variable information by user. The table does not collect statistics for `Com_xxx` variables.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| USER | User for which the status variable is reported. |
| VARIABLE\_NAME | Status variable name. |
| VARIABLE\_VALUE | Aggregated status variable value |

 
If [TRUNCATE TABLE](../truncate-table/index) is run, will reset the aggregated user status from terminated sessions. 

 If [FLUSH STATUS](flush-status) is run, session status from all active sessions are added to the global status variables, the status of all active sessions are reset, and values aggregated from disconnected sessions are reset.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-status_by_user-table/>

Condition Selectivity Computation Internals
===========================================

    This page describes how the MariaDB optimizer computes condition selectivities.

 calculate\_cond\_selectivity\_for\_table(T)
-------------------------------------------

 This function computes selectivity of the restrictions on a certain table T. (TODO: name in the optimizer trace) 

 Selectivity is computed from 

 * selectivities of restrictions on different columns ( [histogram data](../histogram-based-statistics/index))
* selectivities of potential range accesses.

 Restrictions on different columns, as well as disjoint sets of columns, are considered independent, so their selectivities are multiplied. 

 ### Data From Potential Range Accesses

 First, we take into account the selectivities of potential range accesses.

 If range accesses on indexes IDX1 and IDX2 do not use the same table column (either the indexes do not have common columns, or they do but range accesses do not use them), then they are considered independent, and their selectivities can be multiplied.

 However, in general, range accesses on different indexes may use restrictions on the same column and so cannot be considered independent.

 In this case, the following approach is used:

 We start with selectivity=1, an empty set of range accesses, and an empty set of columns for which we have taken the selectivity into account.

 Then, we add range accesses one by one, updating the selectivity value and noting which columns we have taken into account.

 Range accesses that use more key parts are added first.

 If we are adding a range access $R whose columns do not overlap with the ones already added, we can just multiply the total selectivity by $R's selectivity.

 If $R's columns overlap with columns we've got selectivity data for, the process is as follows:

 Find the prefix of columns whose selectivity hasn't been taken into account yet. Then, take the selectivity of the whole range access and multiply it by

 
```
  rec_per_key[i-1]/rec_per_key[i]

```

(TODO: and this logic is not clear. More, one can produce table->cond\_selectivity>1 this way. See [MDEV-20740](https://jira.mariadb.org/browse/MDEV-20740))

 ### Data From Histograms

 Then, we want to take into account selectivity data from [histograms](../histogram-based-statistics/index). Each histogram covers one single column.

 If the selectivity of a column hasn't been taken into account on the previous step, we take it into account now by multiplying the selectivity by it. Otherwise, we assume that range access has fully taken the column selectivity into account and do nothing.

 The third step is sampling-based selectivity data which is out of the scope of this document.

 table\_cond\_selectivity()
--------------------------

 This function computes selectivity of restrictions that can be applied after table T has been joined with the join prefix `{T1, ..., Tk}`.

 There are two cases:

 * Table T uses ref access. In this case, the returned rows match the equalities ref\_access is constructed from. Restrictions on just table T are not checked, yet.
* Table T uses ALL/index/quick select. In this case, restrictions on table T have been applied but cross-table restrictions were not.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/condition-selectivity-computation-internals/>

WITH
====

    
**MariaDB starting with [10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/)**Common Table Expressions were introduced in [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/).

 
### Syntax

 
```
WITH [RECURSIVE] table_reference [(columns_list)] AS  (
  SELECT ...
)
[CYCLE cycle_column_list RESTRICT]
SELECT ...

```
 ### Description

 The `WITH` keyword signifies a [Common Table Expression](../common-table-expressions/index) (CTE). It allows you to refer to a subquery expression many times in a query, as if having a temporary table that only exists for the duration of a query.

 There are two kinds of CTEs:

 * [Non-Recursive](../non-recursive-common-table-expressions-overview/index)
* [Recursive](../recursive-common-table-expressions-overview/index) (signified by the `RECURSIVE` keyword, supported since [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/))

 You can use `table_reference` as any normal table in the external `SELECT` part. You can also use `WITH` in subqueries, as well as with [EXPLAIN](../explain/index) and [SELECT](../select/index).

 Poorly-formed recursive CTEs can in theory cause infinite loops. The [max\_recursive\_iterations](../server-system-variables/index#max_recursive_iterations) system variable limits the number of recursions.

 #### CYCLE ... RESTRICT

 
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The CYCLE clause enables CTE cycle detection, avoiding excessive or infinite loops, MariaDB supports a relaxed, non-standard grammar.

 The SQL Standard permits a CYCLE clause, as follows:

 
```
WITH RECURSIVE ... (
  ...
)
CYCLE <cycle column list>
SET <cycle mark column> TO <cycle mark value> DEFAULT <non-cycle mark value>
USING <path column>

```

where all clauses are mandatory. 

 MariaDB does not support this, but from 10.5.2 permits a non-standard relaxed grammar, as follows:

 
```
WITH RECURSIVE ... (
  ...
)
CYCLE <cycle column list> RESTRICT

```

With the use of `CYCLE ... RESTRICT` it makes no difference whether the CTE uses `UNION ALL` or `UNION DISTINCT` anymore. `UNION ALL` means "all rows, but without cycles", which is exactly what the `CYCLE` clause enables. And `UNION DISTINCT` means all rows should be different, which, again, is what will happen — as uniqueness is enforced over a subset of columns, complete rows will automatically all be different.

 
### Examples

 Below is an example with the `WITH` at the top level:

 
```
WITH t AS (SELECT a FROM t1 WHERE b >= 'c') 
  SELECT * FROM t2, t WHERE t2.c = t.a;

```

The example below uses `WITH` in a subquery:

 
```
SELECT t1.a, t1.b FROM t1, t2
  WHERE t1.a > t2.c 
     AND t2.c IN(WITH t AS (SELECT * FROM t1 WHERE t1.a < 5)
                SELECT t2.c FROM t2, t WHERE t2.c = t.a);

```

Below is an example of a Recursive CTE:

 
```
WITH RECURSIVE ancestors AS 
 ( SELECT * FROM folks
   WHERE name="Alex"
   UNION
   SELECT f.*
   FROM folks AS f, ancestors AS a
   WHERE f.id = a.father OR f.id = a.mother )
SELECT * FROM ancestors;

```

Take the following structure, and data,

 
```
CREATE TABLE t1 (from_ int, to_ int);
INSERT INTO t1 VALUES (1,2), (1,100), (2,3), (3,4), (4,1);
SELECT * FROM t1;
+-------+------+
| from_ | to_  |
+-------+------+
|     1 |    2 |
|     1 |  100 |
|     2 |    3 |
|     3 |    4 |
|     4 |    1 |
+-------+------+

```

Given the above, the following query would theoretically result in an infinite loop due to the last record in t1 (note that [max\_recursive\_iterations](../server-system-variables/index#max_recursive_iterations) is set to 10 for the purposes of this example, to avoid the excessive number of cycles):

 
```
SET max_recursive_iterations=10;

WITH RECURSIVE cte (depth, from_, to_) AS ( 
  SELECT 0,1,1 UNION DISTINCT SELECT depth+1, t1.from_, t1.to_ 
    FROM t1, cte  WHERE t1.from_ = cte.to_ 
) 
SELECT * FROM cte;
+-------+-------+------+
| depth | from_ | to_  |
+-------+-------+------+
|     0 |     1 |    1 |
|     1 |     1 |    2 |
|     1 |     1 |  100 |
|     2 |     2 |    3 |
|     3 |     3 |    4 |
|     4 |     4 |    1 |
|     5 |     1 |    2 |
|     5 |     1 |  100 |
|     6 |     2 |    3 |
|     7 |     3 |    4 |
|     8 |     4 |    1 |
|     9 |     1 |    2 |
|     9 |     1 |  100 |
|    10 |     2 |    3 |
+-------+-------+------+

```

However, the CYCLE ... RESTRICT clause (from [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)) can overcome this:

 
```
WITH RECURSIVE cte (depth, from_, to_) AS ( 
  SELECT 0,1,1 UNION SELECT depth+1, t1.from_, t1.to_ 
    FROM t1, cte WHERE t1.from_ = cte.to_ 
) 
CYCLE from_, to_ RESTRICT 
SELECT * FROM cte;
+-------+-------+------+
| depth | from_ | to_  |
+-------+-------+------+
|     0 |     1 |    1 |
|     1 |     1 |    2 |
|     1 |     1 |  100 |
|     2 |     2 |    3 |
|     3 |     3 |    4 |
|     4 |     4 |    1 |
+-------+-------+------+

```

### See Also

 * [Non-Recursive Common Table Expressions Overview](../non-recursive-common-table-expressions-overview/index)
* [Recursive Common Table Expressions Overview](../recursive-common-table-expressions-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/with/>

Performance Schema user\_variables\_by\_thread Table
====================================================

    
**MariaDB starting with [10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/)**The `user_variables_by_thread` table was added in [MariaDB 10.5.2](https://mariadb.com/kb/en/mariadb-1052-release-notes/).

 
The `user_variables_by_thread` table contains information about [user-defined variables](../user-defined-variables/index) and the threads that defined them.

 [TRUNCATE TABLE](../truncate-table/index) cannot be performed on the table.

 The table contains the following columns:

 


| Column | Description |
| --- | --- |
| THREAD\_ID | The thread identifier of the session in which the variable is defined. |
| VARIABLE\_NAME | The variable name, without the leading @ character. |
| VARIABLE\_VALUE | The variable value |

 
Example
-------

 
```
SET @var = 0;

SELECT * FROM user_variables_by_thread;
+-----------+---------------+----------------+
| THREAD_ID | VARIABLE_NAME | VARIABLE_VALUE |
+-----------+---------------+----------------+
|        11 | var           | 0              |
+-----------+---------------+----------------+

```

See Also
--------

 * [User-defined variables](../user-defined-variables/index)
* [Information Schema USER\_VARIABLES Table](../information-schema-user_variables-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/performance-schema-user_variables_by_thread-table/>

Information Schema INNODB\_TABLESPACES\_ENCRYPTION Table
========================================================

    The [Information Schema](../information_schema/index) `INNODB_TABLESPACES_ENCRYPTION` table contains metadata about [encrypted InnoDB tablespaces](../encrypting-data-for-innodb-xtradb/index). When you [enable encryption for an InnoDB tablespace](../encrypting-data-for-innodb-xtradb/index#enabling-encryption), an entry for the tablespace is added to this table. If you later [disable encryption for the InnoDB tablespace](../encrypting-data-for-innodb-xtradb/index#disabling-encryption), then the row still remains in this table, but the `ENCRYPTION_SCHEME` and `CURRENT_KEY_VERSION` columns will be set to `0`.

 Viewing this table requires the [PROCESS](../grant/index#global-privileges) privilege, although a bug in versions before [MariaDB 10.1.46](https://mariadb.com/kb/en/mariadb-10146-release-notes/), [10.2.33](https://mariadb.com/kb/en/mariadb-10233-release-notes/), [10.3.24](https://mariadb.com/kb/en/mariadb-10324-release-notes/), [10.4.14](https://mariadb.com/kb/en/mariadb-10414-release-notes/) and [10.5.5](https://mariadb.com/kb/en/mariadb-1055-release-notes/) mean the [SUPER](../grant/index#global-privileges) privilege was required ([MDEV-23003](https://jira.mariadb.org/browse/MDEV-23003)).

 It has the following columns:

 


| Column | Description | Added |
| --- | --- | --- |
| `SPACE` | InnoDB tablespace ID. |  |
| `NAME` | Path to the InnoDB tablespace file, without the extension. |  |
| `ENCRYPTION_SCHEME` | Key derivation algorithm. Only `1` is currently used to represent an algorithm. If this value is `0`, then the tablespace is unencrypted. |  |
| `KEYSERVER_REQUESTS` | Number of times InnoDB has had to request a key from the [encryption key management plugin](../encryption-key-management/index). The three most recent keys are cached internally. |  |
| `MIN_KEY_VERSION` | Minimum key version used to encrypt a page in the tablespace. Different pages may be encrypted with different key versions. |  |
| `CURRENT_KEY_VERSION` | Key version that will be used to encrypt pages. If this value is `0`, then the tablespace is unencrypted. |  |
| `KEY_ROTATION_PAGE_NUMBER` | Page that a [background encryption thread](../encrypting-data-for-innodb-xtradb/index#background-encryption-threads) is currently rotating. If key rotation is not enabled, then the value will be `NULL`. |  |
| `KEY_ROTATION_MAX_PAGE_NUMBER` | When a [background encryption thread](../encrypting-data-for-innodb-xtradb/index#background-encryption-threads) starts rotating a tablespace, the field contains its current size. If key rotation is not enabled, then the value will be `NULL`. |  |
| `CURRENT_KEY_ID` | Key ID for the encryption key currently in use. | [MariaDB 10.1.13](https://mariadb.com/kb/en/mariadb-10113-release-notes/) |
| `ROTATING_OR_FLUSHING` | Current key rotation status. If this value is `1`, then the [background encryption threads](../encrypting-data-for-innodb-xtradb/index#background-encryption-threads) are working on the tablespace. See [MDEV-11738](https://jira.mariadb.org/browse/MDEV-11738). | [MariaDB 10.2.5](https://mariadb.com/kb/en/mariadb-1025-release-notes/), [MariaDB 10.1.23](https://mariadb.com/kb/en/mariadb-10123-release-notes/) |

 
When the [InnoDB system tablespace](../innodb-system-tablespaces/index) is encrypted, it is represented in this table with the special name: `innodb_system`.

 Example
-------

 
```
SELECT * FROM information_schema.INNODB_TABLESPACES_ENCRYPTION 
WHERE NAME LIKE 'db_encrypt%';
+-------+----------------------------------------------+-------------------+--------------------+-----------------+---------------------+--------------------------+------------------------------+
| SPACE | NAME                                         | ENCRYPTION_SCHEME | KEYSERVER_REQUESTS | MIN_KEY_VERSION | CURRENT_KEY_VERSION | KEY_ROTATION_PAGE_NUMBER | KEY_ROTATION_MAX_PAGE_NUMBER |
+-------+----------------------------------------------+-------------------+--------------------+-----------------+---------------------+--------------------------+------------------------------+
|    18 | db_encrypt/t_encrypted_existing_key          |                 1 |                  1 |               1 |                   1 |                     NULL |                         NULL |
|    19 | db_encrypt/t_not_encrypted_existing_key      |                 1 |                  0 |               1 |                   1 |                     NULL |                         NULL |
|    20 | db_encrypt/t_not_encrypted_non_existing_key  |                 1 |                  0 |      4294967295 |          4294967295 |                     NULL |                         NULL |
|    21 | db_encrypt/t_default_encryption_existing_key |                 1 |                  1 |               1 |                   1 |                     NULL |                         NULL |
|    22 | db_encrypt/t_encrypted_default_key           |                 1 |                  1 |               1 |                   1 |                     NULL |                         NULL |
|    23 | db_encrypt/t_not_encrypted_default_key       |                 1 |                  0 |               1 |                   1 |                     NULL |                         NULL |
|    24 | db_encrypt/t_defaults                        |                 1 |                  1 |               1 |                   1 |                     NULL |                         NULL |
+-------+----------------------------------------------+-------------------+--------------------+-----------------+---------------------+--------------------------+------------------------------+
7 rows in set (0.00 sec)

```

See Also
--------

 * [Encrypting Data for InnoDB / XtraDB](../encrypting-data-for-innodb-xtradb/index)
* [Data at Rest Encryption](../data-at-rest-encryption/index)
* [Why Encrypt MariaDB Data?](../why-encrypt-mariadb-data/index)
* [Encryption Key Management](../encryption-key-management/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_tablespaces_encryption-table/>

Condition Pushdown into Derived Table Optimization
==================================================

     If a query uses a derived table (or a view), the first action that the query optimizer will attempt is to apply the [derived-table-merge-optimization](../derived-table-merge-optimization/index) and merge the derived table into its parent select. However, that optimization is only applicable when the select inside the derived table has a join as the top-level operation. If it has a [GROUP-BY](../group-by/index), [DISTINCT](../select/index#distinct), or uses [window functions](../window-functions/index), then [derived-table-merge-optimization](../derived-table-merge-optimization/index) is not applicable. 

 In that case, the Condition Pushdown optimization is applicable.

 Introduction to Condition Pushdown
----------------------------------

 Consider an example

 
```
create view OCT_TOTALS as
select
  customer_id,
  SUM(amount) as TOTAL_AMT
from orders
where  order_date BETWEEN '2017-10-01' and '2017-10-31'
group by customer_id;

select * from OCT_TOTALS where customer_id=1

```

The naive way to execute the above is to

 1. Compute the OCT\_TOTALS contents (for all customers).
2. The, select the line with customer\_id=1

 This is obviously inefficient, if there are 1000 customers, then one will be doing up to 1000 times more work than necessary.

 However, the optimizer can take the condition `customer_id=1` and push it down into the OCT\_TOTALS view.

 (TODO: elaborate here)

 Condition Pushdown Properties
-----------------------------

 * Condition Pushdown has been available since [MariaDB 10.2](../what-is-mariadb-102/index).
* The Jira task for it was [MDEV-9197](https://jira.mariadb.org/browse/MDEV-9197).
* The optimization is enabled by default. One can disable it by setting `@@optimizer_switch` flag `condition_pushdown_for_derived` to OFF.

 See Also
--------

 * Condition Pushdown through Window Functions (since [MariaDB 10.3](../what-is-mariadb-103/index))
* [Condition Pushdown into IN Subqueries](../condition-pushdown-into-in-subqueries/index) (since [MariaDB 10.4](../what-is-mariadb-104/index))

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/condition-pushdown-into-derived-table-optimization/>

Non-Recursive Common Table Expressions Overview
===============================================

     Common Table Expressions (CTEs) are a standard SQL feature, and are essentially temporary named result sets. There are two kinds of CTEs: Non-Recursive, which this article covers; and [Recursive](../recursive-common-table-expressions-overview/index).

 Non-Recursive CTEs
------------------

 The [WITH](../with/index) keyword signifies a CTE. It is given a name, followed by a body (the main query) as follows: ![cte_syntax]

 CTEs are similar to derived tables. For example

 
```
WITH engineers AS 
   ( SELECT * FROM employees
     WHERE dept = 'Engineering' )

SELECT * FROM engineers
WHERE ...

```


```
SELECT * FROM
   ( SELECT * FROM employees
     WHERE dept = 'Engineering' ) AS engineers
WHERE
...

```

A non-recursive CTE is basically a query-local [VIEW](../views/index). There are several advantages and caveats to them. The syntax is more readable than nested `FROM (SELECT ...)`. A CTE can refer to another and it can be referenced from multiple places.

 ### A CTE referencing Another CTE

 Using this format makes for a more readable SQL than a nested `FROM(SELECT ...)` clause. Below is an example of this:

 
```
WITH engineers AS (
SELECT * FROM employees
WHERE dept IN('Development','Support') ),
eu_engineers AS ( SELECT * FROM engineers WHERE country IN('NL',...) )
SELECT
...
FROM eu_engineers;

```

### Multiple Uses of a CTE

 This can be an 'anti-self join', for example:

 
```
WITH engineers AS (
SELECT * FROM employees
WHERE dept IN('Development','Support') )

SELECT * FROM engineers E1
WHERE NOT EXISTS
   (SELECT 1 FROM engineers E2
    WHERE E2.country=E1.country
    AND E2.name <> E1.name );

```

Or, for year-over-year comparisons, for example:

 
```
WITH sales_product_year AS (
SELECT product, YEAR(ship_date) AS year,
SUM(price) AS total_amt
FROM item_sales
GROUP BY product, year )

SELECT *
FROM sales_product_year CUR,
sales_product_year PREV,
WHERE CUR.product=PREV.product 
AND  CUR.year=PREV.year + 1 
AND CUR.total_amt > PREV.total_amt

```

Another use is to compare individuals against their group. Below is an example of how this might be executed:

 
```
WITH sales_product_year AS (
SELECT product,
YEAR(ship_date) AS year,
SUM(price) AS total_amt
FROM item_sales
GROUP BY product, year
)

SELECT * 
FROM sales_product_year S1
WHERE
total_amt > 
    (SELECT 0.1 * SUM(total_amt)
     FROM sales_product_year S2
     WHERE S2.year = S1.year)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/non-recursive-common-table-expressions-overview/>

The Optimizer Cost Model from MariaDB 11.0
==========================================

    Background
----------

 Before [MariaDB 11.0](../what-is-mariadb-110/index), the MariaDB Query optimizer used a 'basic cost' of 1 for:

 * One disk access
* Fetching a key
* Fetching a row based on the rowid (= unique row identifier) from the key

 There were some smaller costs:

 * filter lookup: 0.01
* Examining a where clause: 0.20
* Comparing two keys: 0.05
* Fetching a row through an index from a temporary memory table: 0.05

 The above costs are reasonable for finding out the best index to use. However, they where not good for finding out if we should use a table scan, index scan or range lookup. The cost for the different engines were not properly calibrated.

 New Cost Model
--------------

 In [MariaDB 11.0](../what-is-mariadb-110/index) we have fixed the above shortcomings by changing the basic cost for 'storage engine operations' to be 1 millisecond. This means that for most queries the query cost (`LAST_QUERY_COST`) should be close (or at least proportional) to the time the server is spending in the storage engine + join\_cache + sorting.

 Note that the user level costs are in **microseconds** (as milliseconds would have so many zero's that it makes it hard to compare values).

 The engine costs have also been separated into smaller parts to make things more accurate.

 The "disk"-read cost now assumes a mid level SSD disk with 400MB/second. This can be changed by the end user by modifying `OPTIMIZER_DISK_READ_COST`.

 All engine specific costs are visible in `information_schema.optimizer_costs`.

 For example:

 The "default" cost for an engine can be found with:

 
```
 select * from information_schema.optimizer_costs where engine="default"\G
*************************** 1. row ***************************
                         ENGINE: default
       OPTIMIZER_DISK_READ_COST: 10.240000
OPTIMIZER_INDEX_BLOCK_COPY_COST: 0.035600
     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_DISK_READ_RATIO: 0.020000
        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

```

The above costs are the default (base) for all engines and should be reasonable for engines that does not have a clustered index (like [MyISAM](../myisam/index), [Aria](../aria/index) etc). The default costs can be changed by specifying just the cost as an argument, like `mariadbd --optimizer-disk-read-cost=20` or from SQL: `set global optimizer_disk_read_cost=20`. An engine specific cost can be tuned by prefixing the cost with the engine name, like `set global innodb.optimizer_disk_read_cost=20`. 

 An engine can tune some or all of the above cost in the storage engine interface. Here follows the cost for the [InnoDB storage engine](../innodb/index).

 
```
select * from information_schema.optimizer_costs where engine="innodb"\G
*************************** 1. row ***************************
                         ENGINE: InnoDB
       OPTIMIZER_DISK_READ_COST: 10.240000
OPTIMIZER_INDEX_BLOCK_COPY_COST: 0.035600
     OPTIMIZER_KEY_COMPARE_COST: 0.011361
        OPTIMIZER_KEY_COPY_COST: 0.015685
      OPTIMIZER_KEY_LOOKUP_COST: 0.791120
   OPTIMIZER_KEY_NEXT_FIND_COST: 0.099000
      OPTIMIZER_DISK_READ_RATIO: 0.020000
        OPTIMIZER_ROW_COPY_COST: 0.060870
      OPTIMIZER_ROW_LOOKUP_COST: 0.765970
   OPTIMIZER_ROW_NEXT_FIND_COST: 0.070130
   OPTIMIZER_ROWID_COMPARE_COST: 0.002653
      OPTIMIZER_ROWID_COPY_COST: 0.002653

```

As can be seen, the `ROW_LOOKUP_COST` is close to the `KEY_LOOKUP_COST`, which is because InnoDB has clustered primary key indexes and is using it to find the row from a secondary index.

 Some engines, like `HEAP`/`MEMORY` implement their own cost functions as different indexes in the same engine can have different costs. This is why some of the cost numbers for these engines are 0.

 There are also some SQL level costs that are independent of the storage engine:

 
```
select * from information_schema.global_variables where variable_name like "%where%cost%" or variable_name like "%scan%cost%";
+---------------------------+----------------+
| VARIABLE_NAME             | VARIABLE_VALUE |
+---------------------------+----------------+
| OPTIMIZER_SCAN_SETUP_COST | 10.000000      |
| OPTIMIZER_WHERE_COST      | 0.032000       |
+---------------------------+----------------+

```

Description of the Different Cost Variables
-------------------------------------------

 Time and cost are quite interchangeable in the new cost model. Below we will use cost for most things, except for `OPTIMIZER_DISK_READ_COST` as one should use published/tested timings for the SSD/harddisk if one wants to change the value..

 


| Variable | Type | Description |
| --- | --- | --- |
| `OPTIMIZER_DISK_READ_COST` | Engine | Time in microseconds to read a 4K block from a disk/SSD. The default is set for a 400MB/second SSD |
| `OPTIMIZER_INDEX_BLOCK_COPY_COST` | Engine | Cost to lock and a copy a block from the global cache to a local cache. This cost is added for every block accessed, independent of whether they are cached or not |
| `OPTIMIZER_KEY_COMPARE_COST` | Engine | Cost to compare two keys |
| `OPTIMIZER_KEY_COPY_COST` | Engine | Cost to copy a key from the index to a local buffer as part of searching for a key |
| `OPTIMIZER_KEY_LOOKUP_COST` | Engine | Cost to find a key entry in the index (index read) |
| `OPTIMIZER_KEY_NEXT_FIND_COST` | Engine | Cost to find the next key in the index (index next) |
| `OPTIMIZER_DISK_READ_RATIO` | Engine | The ratio of BLOCK\_NOT\_IN\_CACHE/CACHE\_READS. The cost of disk usage is calculated as `estimated_blocks` \* `OPTIMIZER_DISK_READ_RATIO` \* ``OPTIMIZER_DISK_READ_COST``. A value of 0 means that all blocks are always in the cache. A value of 1 means that a block is never in the cache |
| `OPTIMIZER_ROW_COPY_COST` | Engine | Cost of copying a row to a local buffer. Should be slightly more than `OPTIMIZER_KEY_COPY_COST` |
| `OPTIMIZER_ROW_LOOKUP_COST` | Engine | Cost to find a row based on the rowid (Rowid is stored in the index together with the key) |
| `OPTIMIZER_ROW_NEXT_FIND_COST` | Engine | Cost of finding the next row |
| `OPTIMIZER_ROWID_COMPARE_COST` | Engine | Cost of comparing two rowids |
|  `OPTIMIZER_ROWID_COPY_COST` | Engine | Cost of copying a rowid from the index |
|  `OPTIMIZER_SCAN_SETUP_COST` | Session | Cost of starting a table or index scan. This has a low value to encourage the optimizer to use index lookup also tables with very few rows |
| `OPTIMIZER_WHERE_COST` | Session | Cost to execute the `WHERE` clause for every found row. Increasing this variable will encourage the optimizer to find plans which read fewer rows |

 
More information of the costs and how they were calculated can be found in the `Docs/optimizer_costs.txt` file in the [MariaDB Source distributions](../getting-the-mariadb-source-code/index).

 Other Optimizer Cost Changes
----------------------------

 * When counting disk accesses, we assume that all rows and index data are cached for the duration of the query. This is to avoid the following problem:
	+ table t1 with 1 million\_rows is scanned
		- For each row we do a lookup in table t2, which has only 10 rows

 If we would count all lookups in t2, there would be 1 million lookups. If this would be the case, the optimizer would choose to use a join cache on the rows in t1 and do a table scan over t2.

 * The cost of sorting (filesort) is now more accurate, which allows the optimizer to better choose between index scan and filesort for `ORDER BY/GROUP BY` queries.

 A lot of rule-based cost has been changed to be cost-based:

 * The decision to use an index (and which index) for resolving `ORDER BY/GROUP BY` were only partly cost-based before.
* The old optimizer would limit the number of ‘expected key lookups’ to 10% of the number of rows. This would cause the optimizer to use an index to scan a big part of a table when a full table scan would be much faster. This code is now removed.
* InnoDB would limit the number of rows in a range to 50% of the total rows, which would confuse the optimizer for big ranges. The cap is now removed.
* If there was a usable filter for an index, it was sometimes used without checking the complete cost of the filter.
* ‘Aggregate distinct optimization with indexes’ is now cost-based. This will change many queries from "Using index for group-by (scanning)” to “Using index for group-by”.

 Other Notable Plan Changes
--------------------------

 * Indexes can now be used for `ORDER BY/GROUP BY` in sub queries (instead of filesort)
* Derived tables and queries with `UNION` can now create a distinct key (instead of a key with duplicates) to speed up key accesses.
* Indexes with more used key parts are preferred if the number of resulting rows is the same:
	+ `WHERE key\_part\_1 = 1 and key\_part\_2 < 10`
	+ This will now use a `RANGE` over both key parts instead of using lookups on key\_part\_1.
* For very small tables, index lookup is preferred over table scan.
* `EXPLAIN` does not report "Using index" for scans using a clustered primary key as technically this a table scan.

 When the Optimizer Changes Matter
---------------------------------

 The new, improved optimizer should be able to find a better plan

 * If you are using queries with more than two tables.
* If you have indexes with a lot of identical values.
* If you are using ranges that cover more than 10% of a table.
	+ `WHERE key between 1 and 1000 -- Table has values 1-2000`
* If you have complex queries when not all used columns are or can be indexed.
	+ In which case you may need to depend on selectivity to get the right plan.
* If you are using queries mixing different storage engines.
	+ Like using tables from both InnoDB and Memory in the same query.
* If you have had to use `FORCE INDEX` to get a good plan.
* If using [ANALYZE TABLE](../analyze-table/index) made your plans worse (or not good enough).
* If your queries have lots of derived tables (subselects).
* You are using `ORDER BY / GROUP BY` that could be resolved via indexes.

 Changing Costs
--------------

 All engine and “SQL level” cost variables can be changed via MariaDB startup options, in configuration files or dynamically using SQL.

 ### In Configuration Files (and Command Line)

 
```
[mariadbd]
# Archive is using a hard disk (typical seek is 8-10 ms)
archive.OPTIMIZER_DISK_READ_COST=8000
# All other engines are using an SSD.
OPTIMIZER_DISK_READ_COST=10.240000

```

### From SQL

 
```
# Tell optimizer to find a plan with as few accepted rows as possible
SET SESSION OPTIMIZER_WHERE_COST=1.0;
# Inform the optimizer that InnoDB buffer pool has a 80% hit rate
SET GLOBAL innodb.OPTIMIZER_DISK_READ_RATIO=0.20;

```

* Note engine costs are `GLOBAL` while other costs can also be `SESSION`.
* To keep things fast, engine-specific costs are stored in the table definition (TABLE\_SHARE). One effect of this is that if one changes the cost for an engine, it will only take effect when new, not previously cached tables are accessed. You can use [FLUSH TABLES](../flush/index) to force the table to use the new costs at next access.

 ### Examples of Changing Costs

 * `OPTIMIZER_WHERE_COST` is added as a cost for for all 'accepted rows'. Increasing this variable will cause the optimizer to choose plans with less estimated rows.
* One can specify the kind of disk used by the system by changing `OPTIMIZER_DISK_READ_COST`. This should be the time to do a random read of a 4096 byte block.
* The cost of a potential disk read is calculated as `OPTIMIZER_DISK_READ_COST * OPTIMIZER_DISK_READ_RATIO`. Increasing `OPTIMIZER_DISK_READ_RATIO` will inform the optimizer that not all data is cached.
* `OPTIMIZER_SCAN_SETUP_COST` will increase the cost of a table scan. One can increase this to avoid using table scans.

 For Storage Engine Developers
-----------------------------

 The costs for an engine are set the following way when the engine plugin is loaded/initialized:

 * Copy the "default" storage engine costs to the plugin engine costs.
	+ #handlerton->costs `points to the engine specific cost data.`
* Call `handlerton->update_optimizer_costs()` to let the storage engine update the costs.
* Apply all user specific engine costs (from configuration files/startup) to the engine costs structure.
* When a TABLE\_SHARE is created, the costs are copied from `handlerton->costs` to `TABLE_SHARE.optimizer_costs` . `handler::update_optimizer_costs()` is called to allow the engine to tune the cost for this specific table instance. This is done to avoid having to take any "cost" mutex while running queries.
* User changes to engine costs are stored in the data pointed to by `handlerton->costs`. This is why [FLUSH TABLES](../flush/index) is needed to activate new engine costs.
* To speed up cost access for the optimizer, `handler::set_optimizer_costs()` is called for each query to copy `OPTIMIZER_WHERE_COST` and `OPTIMIZER_SCAN_SETUP_COST` to the engine cost structure.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/the-optimizer-cost-model-from-mariadb-11-0/>

Aria Disabling Encryption
=========================

    The process involved in safely disabling data-at-rest encryption for your Aria tables is very similar to that of enabling encryption. To disable, you need to set the relevant system variables and then rebuild each table into an unencrypted state.

 
Don't remove the [Encryption Key Management](key-management-encryption-plugins) plugin from your configuration file until you have unencrypted all tables in your database. MariaDB cannot read encrypted tables without the relevant encryption key.

 
Disabling Encryption on User-created Tables
-------------------------------------------

 With tables that the user creates, you can disable encryption by setting the `[aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables)` system variable to `OFF`. Once this is set, MariaDB no longer encrypts new tables created with the Aria storage engine. 

 
```
SET GLOBAL aria_encrypt_tables = OFF;

```

Unlike [InnoDB](../innodb-encryption/index), Aria does not currently use background encryption threads. Before removing the [Encryption Key Management](key-management-encryption-plugins) plugin from the configuration file, you first need to manually rebuild each table to an unencrypted state.

 To find the encrypted tables, query the Information Schema, filtering the `[TABLES](information_schema-tables-table)` table for those that use the Aria storage engine and the `PAGE` `[ROW\_FORMAT](../create-table/index#row_format)`. 

 
```
SELECT TABLE_SCHEMA, TABLE_NAME
FROM information_schema.TABLES
WHERE ENGINE = 'Aria'
  AND ROW_FORMAT = 'PAGE'
  AND TABLE_SCHEMA != 'information_schema';

```

Each table in the result-set was potentially written to disk in an encrypted state. Before removing the configuration for the encryption keys, you need to rebuild each of these to an unencrypted state. This can be done with an `[ALTER TABLE](../alter-table/index)` statement.

 
```
ALTER TABLE test.aria_table ENGINE = Aria ROW_FORMAT = PAGE;

```

Once all of the Aria tables are rebuilt, they're safely unencrypted.

 Disabling Encryption for Internal On-disk Temporary Tables
----------------------------------------------------------

 MariaDB routinely creates internal temporary tables. When these temporary tables are written to disk and the `[aria\_used\_for\_temp\_tables](../aria-system-variables/index#aria_used_for_temp_tables)` system variable is set to `ON`, MariaDB uses the Aria storage engine.

 To decrypt these tables, set the `[encrypt\_tmp\_disk\_tables](../server-system-variables/index#encrypt_tmp_disk_tables)` to `OFF`. Once set, all internal temporary tables that are created from that point on are written unencrypted to disk.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-disabling-encryption/>

optimizer\_switch Helper Functions
==================================

    Syntax
------

 
```
optimizer_switch_on()
optimizer_switch_off()
optimizer_switch_choice("on" | "off")

```
 Description
-----------

 The above procedures can be used to check which [optimizer\_switch](../optimizer_switch/index) options are `on` or `off`. The result set is sorted according to [optimizer\_switch](../optimizer_switch/index) option name.

 Example
-------

 
```
select @@optimizer_switch\G
*************************** 1. row ***************************
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,
index_merge_sort_intersection=off,engine_condition_pushdown=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

call sys.optimizer_switch_on();
+---------------------------------+------+
| option                          | opt  |
+---------------------------------+------+
| condition_pushdown_for_derived  | on   |
| condition_pushdown_for_subquery | on   |
| condition_pushdown_from_having  | on   |
| derived_merge                   | on   |
| derived_with_keys               | on   |
| exists_to_in                    | on   |
| extended_keys                   | on   |
| firstmatch                      | on   |
| index_condition_pushdown        | on   |
| index_merge                     | on   |
| index_merge_intersection        | on   |
| index_merge_sort_union          | on   |
| index_merge_union               | on   |
| in_to_exists                    | on   |
| join_cache_bka                  | on   |
| join_cache_hashed               | on   |
| join_cache_incremental          | on   |
| loosescan                       | on   |
| materialization                 | on   |
| optimize_join_buffer_size       | on   |
| orderby_uses_equalities         | on   |
| outer_join_with_cache           | on   |
| partial_match_rowid_merge       | on   |
| partial_match_table_scan        | on   |
| rowid_filter                    | on   |
| semijoin                        | on   |
| semijoin_with_cache             | on   |
| split_materialized              | on   |
| subquery_cache                  | on   |
| table_elimination               | on   |
+---------------------------------+------+


call sys.optimizer_switch_off();
+-------------------------------+------+
| option                        | opt  |
+-------------------------------+------+
| engine_condition_pushdown     | off  |
| index_merge_sort_intersection | off  |
| mrr                           | off  |
| mrr_cost_based                | off  |
| mrr_sort_keys                 | off  |
| not_null_range_scan           | off  |
+-------------------------------+------+

```

Notes
-----

 `sys.optimizer_switch_on()` is a shortcut for `sys.optimizer_switch_choice("on")`; `sys.optimizer_switch_off()` is a shortcut for `sys.optimizer_switch_choice("off")`;

 See Also
--------

 * [optimizer-switch](../optimizer-switch/index) Documentation for optimizer\_switch

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer_switch-helper-functions/>

DuplicateWeedout Strategy
=========================

    `DuplicateWeedout` is an execution strategy for [Semi-join subqueries](../semi-join-subquery-optimizations/index).

 The idea
--------

 The idea is to run the semi-join (a query with uses `WHERE X IN (SELECT Y FROM ...)`) as if it were a regular inner join, and then eliminate the duplicate record combinations using a temporary table.

 Suppose, you have a query where you're looking for countries which have more than 33% percent of their population in one big city:

 
```
select * 
from Country 
where 
   Country.code IN (select City.Country
                    from City 
                    where 
                      City.Population > 0.33 * Country.Population and 
                      City.Population > 1*1000*1000);

```

First, we run a regular inner join between the `City` and `Country` tables:

 ![duplicate-weedout-inner-join]

 The Inner join produces duplicates. We have Germany three times, because it has three big cities. Now, lets put `DuplicateWeedout` into the picture:

 ![duplicate-weedout-diagram]

 Here one can see that a temporary table with a primary key was used to avoid producing multiple records with 'Germany'.

 DuplicateWeedout in action
--------------------------

 The `Start temporary` and `End temporary` from the last diagram are shown in the `EXPLAIN` output:

 
```
explain select * from Country where Country.code IN 
  (select City.Country from City where City.Population > 0.33 * Country.Population 
   and City.Population > 1*1000*1000)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: City
         type: range
possible_keys: Population,Country
          key: Population
      key_len: 4
          ref: NULL
         rows: 238
        Extra: Using index condition; Start temporary
*************************** 2. row ***************************
           id: 1
  select_type: PRIMARY
        table: Country
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 3
          ref: world.City.Country
         rows: 1
        Extra: Using where; End temporary
2 rows in set (0.00 sec)

```

This query will read 238 rows from the `City` table, and for each of them will make a primary key lookup in the `Country` table, which gives another 238 rows. This gives a total of 476 rows, and you need to add 238 lookups in the temporary table (which are typically \*much\* cheaper since the temporary table is in-memory).

 If we run the same EXPLAIN in MySQL, we'll get:

 
```
explain select * from Country where Country.code IN 
  (select City.Country from City where City.Population > 0.33 * Country.Population 
    and City.Population > 1*1000*1000)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: Country
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 239
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: City
         type: index_subquery
possible_keys: Population,Country
          key: Country
      key_len: 3
          ref: func
         rows: 18
        Extra: Using where
2 rows in set (0.00 sec)

```

This plan will read `(239 + 239*18) = 4541` rows, which is much slower.

 Factsheet
---------

 * `DuplicateWeedout` is shown as "Start temporary/End temporary" in `EXPLAIN`.
* The strategy can handle correlated subqueries.
* But it cannot be applied if the subquery has meaningful `GROUP BY` and/or aggregate functions.
* `DuplicateWeedout` allows the optimizer to freely mix a subquery's tables and the parent select's tables.
* There is no separate @@optimizer\_switch flag for `DuplicateWeedout`. The strategy can be disabled by switching off all semi-join optimizations with `SET @@optimizer_switch='optimizer_semijoin=off'` command.

 See Also
--------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)
* [Subquery Optimizations Map](../subquery-optimizations-map/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/duplicateweedout-strategy/>

Table Elimination in MariaDB
============================

    The first thing the MariaDB optimizer does is to merge the `VIEW` definition into the query to obtain:

 
```
select ACRAT_rating
from
  ac_anchor
  left join ac_name on ac_anchor.AC_ID=ac_name.AC_ID
  left join ac_dob on ac_anchor.AC_ID=ac_dob.AC_ID
  left join ac_rating on (ac_anchor.AC_ID=ac_rating.AC_ID and
                          ac_rating.ACRAT_fromdate = 
                            (select max(sub.ACRAT_fromdate)
                             from ac_rating sub where sub.AC_ID = ac_rating.AC_ID))
where
 ACNAM_name='Gary Oldman'

```

It's important to realize that the obtained query has a useless part:

 * `left join ac_dob on ac_dob.AC_ID=...` will produce exactly one matching record:
	+ `primary key(ac_dob.AC_ID)` guarantees that there will be at most one match for any value of `ac_anchor.AC_ID`,
	+ and if there won't be a match, `LEFT JOIN` will generate a NULL-complemented “row”
* and we don't care what the matching record is, as table `ac_dob` is not used anywhere else in the query.

 This means that the `left join ac_dob on ...` part can be removed from the query and this is what Table Elimination module does. The detection logic is rather smart, for example it would be able to remove the `left join ac_rating on ...` part as well, together with the subquery (in the above example it won't be removed because ac\_rating used in the selection list of the query). The Table Elimination module can also handle nested outer joins and multi-table outer joins.

 See Also
--------

 * This page is based on the following blog post about table elimination: <http://s.petrunia.net/blog/?p=58>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-elimination-in-mariadb/>

Table Elimination in Other Databases
====================================

    In addition to MariaDB, Table Elimination is found in both Microsoft SQL Server 2005/2008 and Oracle 11g. Of the two, Microsoft SQL Server 2005/2008 seems to have the most advanced implementation. Oracle 11g has been confirmed to use table elimination but not to the same extent.

 To compare the two, we will look at the following query:

 
```
select
 A.colA
from
 tableA A
left outer join
 tableB B
on
 B.id = A.id;

```

When using A as the left table we ensure that the query will return at least as many rows as there are in that table. For rows where the join condition (B.id = A.id) is not met the selected column (A.colA) will still contain its original value. The not seen B.\* row would contain all NULL:s.

 However, the result set could actually contain more rows than what is found in tableA if there are duplicates of the column B.id in tableB. If A contains a row [1, "val1"] and B the rows [1, "other1a"],[1, "other1b"] then two rows will match in the join condition. The only way to know what the result will look like is to actually touch both tables during execution.

 Instead, let's say tableB contains rows that make it possible to place a unique constraint on the column B.id, for example, which is often the case with a primary key. In this situation we know that we will get exactly as many rows as there are in tableA, since joining with tableB cannot introduce any duplicates. Furthermore, as in the example query, if we do not select any columns from tableB, touching that table during execution is unnecessary. We can remove the whole join operation from the execution plan.

 Both SQL Server 2005/2008 and Oracle 11g deploy table elimination in the case described above. Let us look at a more advanced query, where Oracle fails.

 
```
select
 A.colA
from
 tableA A
left outer join
 tableB B
on
 B.id = A.id
and
 B.fromDate = (
   select
     max(sub.fromDate)
   from
     tableB sub
   where
     sub.id = A.id
 );

```

In this example we have added another join condition, which ensures that we only pick the matching row from tableB having the latest fromDate. In this case tableB will contain duplicates of the column B.id, so in order to ensure uniqueness the primary key has to contain the fromDate column as well. In other words the primary key of tableB is (B.id, B.fromDate).

 Furthermore, since the subselect ensures that we only pick the latest B.fromDate for a given B.id we know that at most one row will match the join condition. We will again have the situation where joining with tableB cannot affect the number of rows in the result set. Since we do not select any columns from tableB, the whole join operation can be eliminated from the execution plan.

 SQL Server 2005/2008 will deploy table elimination in this situation as well. We have not found a way to make Oracle 11g use it for this type of query. Queries like these arise in two situations. Either when you have a denormalized model consisting of a fact table with several related dimension tables, or when you have a highly normalized model where each attribute is stored in its own table. The example with the subselect is common whenever you store historized/versioned data.

 See Also
--------

 * This page is based on the following blog post about table elimination: <http://s.petrunia.net/blog/?p=58>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-elimination-in-other-databases/>

What is Table Elimination?
==========================

    The basic idea behind table elimination is that sometimes it is possible to resolve a query without even accessing some of the tables that the query refers to. One can invent many kinds of such cases, but in Table Elimination we targeted only a certain class of SQL constructs that one ends up writing when they are querying [highly-normalized](../database-normalization/index) data.

 The sample queries were drawn from “Anchor Modeling”, a database modeling technique which takes normalization to the extreme. The [slides](http://www.anchormodeling.com/tiedostot/SU_KTH_Course_Presentation.pdf) at the [anchor modeling website](http://www.anchormodeling.com) have an in-depth explanation of Anchor modeling and its merits, but the part that's important for table elimination can be shown with an example.

 Suppose the database stores information about actors, together with their names, birthdays, and ratings, where ratings can change over time:

 ![actor-attrs]

 According to anchor modeling, each attribute should go into its own table:

 * the 'anchor' table which only has a synthetic primary key:

 
```
create table  ac_anchor(AC_ID int primary key);

```

* a table for the 'name' attribute:

 
```
create table ac_name(AC_ID int, ACNAM_name char(N),
                     primary key(AC_ID));

```

* a table for the 'birthdate' attribute:

 
```
create table ac_dob(AC_ID int,
                    ACDOB_birthdate date,
                    primary key(AC_ID));

```

* a table for the ‘rating’ attribute, which is historized:

 
```
create table ac_rating(AC_ID int,
                       ACRAT_rating int,
                       ACRAT_fromdate date,
                       primary key(AC_ID, ACRAT_fromdate));

```

With this approach it becomes easy to add/change/remove attributes, but this comes at a cost of added complexity in querying the data: in order to answer the simplest, select-star question of displaying actors and their current ratings one has to write outer joins:

 Display actors, with their names and current ratings: 

 
```
select
  ac_anchor.AC_ID, ACNAM_Name, ACDOB_birthdate, ACRAT_rating
from
  ac_anchor
  left join ac_name on ac_anchor.AC_ID=ac_name.AC_ID
  left join ac_dob on ac_anchor.AC_ID=ac_dob.AC_ID
  left join ac_rating on (ac_anchor.AC_ID=ac_rating.AC_ID and
                          ac_rating.ACRAT_fromdate = 
                            (select max(sub.ACRAT_fromdate)
                             from ac_rating sub where sub.AC_ID = ac_rating.AC_ID))

```

We don't want to write the joins every time we need to access an actor's properties, so we’ll create a view:

 
```
create view actors as
  select  ac_anchor.AC_ID, ACNAM_Name,  ACDOB_birthdate, ACRAT_rating
  from <see the select above>

```

This will allow us to access the data as if it was stored in a regular way:

 
```
select ACRAT_rating from actors where ACNAM_name='Gary Oldman'

```

And this is where table elimination will be needed.

 See Also
--------

 * This page is based on the following blog post about table elimination: <http://s.petrunia.net/blog/?p=58>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/what-is-table-elimination/>

Table Elimination External Resources
====================================

    * [an example of how to do this in MariaDB](http://www.anchormodeling.com/?page_id=303)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table-elimination-external-resources/>

Non-Blocking Client Library
============================

   MariaDB client library (starting with version 5.5.21) and MySQL Connector/C (starting with version 2.1.0) supports *non-blocking* operations.

  

| Title | Description |
| --- | --- |
|  [About Non-blocking Operation in the Client Library](../about-non-blocking-operation-in-the-client-library/index) |  An introduction to the non-blocking features of the client library.  |
|  [Using the Non-blocking Library](../using-the-non-blocking-library/index) |  How to use the non-blocking client library  |
|  [Non-blocking API Reference](../non-blocking-api-reference/index) |  A list of all functions in the non-blocking client API, and their parameters  |
|  [JavaScript - mariasql for node.js](../javascript-mariasql-for-nodejs/index) |  Using mariasql, a node.js to Bind to Non-Blocking MariaDB Client Library.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/non-blocking-client-library/>

libMariaDB
===========

  

| Title | Description |
| --- | --- |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/libmariadb/>

libmysqld
==========

   Articles about libmysqld.so, the embedded MariaDB server.

  

| Title | Description |
| --- | --- |
|  [Embedded MariaDB Interface](../embedded-mariadb-interface/index) |  Embedded MariaDB interface.  |
|  [mariadb-test and mariadb-test-embedded](../mariadb-test-and-mariadb-test-embedded/index) |  Runs a test case against a MariaDB server, optionally comparing the output with a result file.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/libmysqld/>

Aria Enabling Encryption
========================

    In order to enable data-at-rest encryption for tables using the [Aria](../aria/index) storage engine, you first need to configure the server to use an [Encryption Key Management](../encryption-key-management/index) plugin. Once this is done, you can enable encryption by setting the relevant system variables. 

 Encrypting User-created Tables
------------------------------

  With tables that the user creates, you can enable encryption by setting the `[aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables)` system variable to `ON`, then restart the Server. Once this is set, Aria automatically enables encryption on all tables you create after with the `[ROW\_FORMAT](../create-table/index#row_format)` table option set to `PAGE`.

 Currently, Aria does not support encryption on tables where the `[ROW\_FORMAT](../create-table/index#row_format)` table option is set to the `FIXED` or `DYNAMIC` values.

 Unlike InnoDB, Aria does not support the `[ENCRYPTED](../create-table/index#encrypted)` table option (see [MDEV-18049](https://jira.mariadb.org/browse/MDEV-18049) about that). Encryption for Aria can only be enabled globally using the `[aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables)` system variable.

 ### Encrypting Existing Tables

 In cases where you have existing Aria tables that you would like to encrypt, the process is a little more complicated. Unlike InnoDB, Aria does not utilize [background encryption threads](../innodb-background-encryption-threads/index) to automatically perform encryption changes (see [MDEV-18971](https://jira.mariadb.org/browse/MDEV-18971) about that). Therefore, to encrypt existing tables, you need to identify each table that needs to be encrypted, and then you need to manually rebuild each table.

 First, set the `[aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables)` system variable to encrypt new tables.

 
```
SET GLOBAL aria_encrypt_tables=ON;

```

Identify Aria tables that have the `[ROW\_FORMAT](../create-table/index#row_format)` table option set to `PAGE`.

 
```
SELECT TABLE_SCHEMA, TABLE_NAME 
FROM information_schema.TABLES 
WHERE ENGINE='Aria' 
  AND ROW_FORMAT='PAGE'
  AND TABLE_SCHEMA != 'information_schema';

```

For each table in the result-set, issue an `[ALTER TABLE](../alter-table/index)` statement to rebuild the table.

 
```
ALTER TABLE test.aria_table ENGINE=Aria ROW_FORMAT=PAGE;

```

This statement causes Aria to rebuild the table using the `[ROW\_FORMAT](../create-table/index#row_format)` table option. In the process, with the new default setting, it encrypts the table when it writes to disk. 

 Encrypting Internal On-disk Temporary Tables
--------------------------------------------

 During the execution of queries, MariaDB routinely creates internal temporary tables. These internal temporary tables initially use the [MEMORY](../memory-storage-engine/index) storage engine, which is entirely stored in memory. When the table size exceeds the allocation defined by the `[max\_heap\_table\_size](../server-system-variables/index#max_heap_table_size)` system variable, MariaDB writes the data to disk using another storage engine. If you have the `[aria\_used\_for\_temp\_tables](../aria-system-variables/index#aria_used_for_temp_tables)` set to `ON`, MariaDB uses Aria in writing the internal temporary tables to disk.

 Encryption for internal temporary tables is handled separately from encryption for user-created tables. To enable encryption for these tables, set the `[encrypt\_tmp\_disk\_tables](../server-system-variables/index#encrypt_tmp_disk_tables)` system variable to `ON`. Once set, all internal temporary tables that are written to disk using Aria are automatically encrypted.

 Manually Encrypting Tables
--------------------------

 Currently, Aria does not support manually encrypting tables through the `[ENCRYPTED](../create-table/index#encrypted)` and `[ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id)` table options. For more information, see [MDEV-18049](https://jira.mariadb.org/browse/MDEV-18049).

 In cases where you want to encrypt tables manually or set the specific encryption key, use [InnoDB](../innodb-encryption/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/aria-enabling-encryption/>

Optimizer Trace Guide
=====================

       
  
  
 Optimizer trace uses the JSON format. It is basically a structured log file showing what actions were taken by the query optimizer.   
  


 A Basic Example
---------------

   
  
 Let's take a simple query:  
  


 
```
MariaDB> explain select * from t1 where a<10;
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
| id   | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                 |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+
|    1 | SIMPLE      | t1    | range | a             | a    | 5       | NULL | 10   | Using index condition |
+------+-------------+-------+-------+---------------+------+---------+------+------+-----------------------+

```

One can see the full trace [here](../basic-optimizer-trace-example/index). Taking only the component names, one gets:

 
```
MariaDB> select * from information_schema.optimizer_trace limit 1\G
*************************** 1. row ***************************
                            QUERY: select * from t1 where a<10
                            TRACE: 
{
  "steps": [
    {
      "join_preparation": { ... }
    },
    {
      "join_optimization": {
        "select_id": 1,
        "steps": [
          { "condition_processing": { ... } },
          { "table_dependencies": [ ... ] },
          { "ref_optimizer_key_uses": [ ... ] },
          { "rows_estimation": [
              {
                "range_analysis": {
                   "analyzing_range_alternatives" : { ... },
                  "chosen_range_access_summary": { ... },
                },
                "selectivity_for_indexes" : { ... },
                "selectivity_for_columns" : { ... }
              }
            ]
          },
          { "considered_execution_plans": [ ... ] },
          { "attaching_conditions_to_tables": { ... } }
         ]
      }
    },
    {
      "join_execution": { ... }
    }
  ]
}

```

Trace Structure
---------------

 For each SELECT, there are two "Steps": 

 * `join_preparation`
* `join_optimization`

 Join preparation shows early query rewrites. `join_optmization` is where most of the query optimizations are done. They are:

 * `condition_processing` - basic rewrites in WHERE/ON conditions.
* `ref_optimizer_key_uses` - Construction of possible ways to do ref and eq\_ref accesses.
* `rows_estimation` - Consideration of range and index\_merge accesses.
* `considered_execution_plans` - Join optimization itself, that is, choice of the join order.
* `attaching_conditions_to_tables` - Once the join order is fixed, parts of the WHERE clause are "attached" to tables to filter out rows as early as possible.

 The above steps are for just one SELECT. If the query has subqueries, each SELECT will have these steps, and there will be extra steps/rewrites to handle the subquery construct itself.

 Extracting Trace Components
---------------------------

 If you are interested in some particular part of the trace, MariaDB has two functions that come in handy: 

 * [JSON\_EXTRACT](../json_extract/index) extracts a part of JSON document
* [JSON\_DETAILED](../json_detailed/index) presents it in a user-readable way.

 For example, the contents of the `analyzing_range_alternatives` node can be extracted like so:

 
```
MariaDB> select JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) 
   ->   from INFORMATION_SCHEMA.OPTIMIZER_TRACE\G
*************************** 1. row ***************************
JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')): [
    {
        "range_scan_alternatives": 
        [
            {
                "index": "a_b_c",
                "ranges": 
                [
                    "(1) <= (a,b) < (4,50)"
                ],
                "rowid_ordered": false,
                "using_mrr": false,
                "index_only": false,
                "rows": 4,
                "cost": 6.2509,
                "chosen": true
            }
        ],
        "analyzing_roworder_intersect": 
        {
            "cause": "too few roworder scans"
        },
        "analyzing_index_merge_union": []
    }
]

```

Examples of Various Information in the Trace
--------------------------------------------

 ### Basic Rewrites

 A lot of applications construct database query text on the fly, which sometimes means that the query has constructs that are repetitive or redundant. In most cases, the optimizer will be able to remove them. One can check the trace to be sure:

 
```
explain select * from t1 where not (col1 >= 3);

```

Optimizer trace will show:

 
```
"steps": [
  {
    "join_preparation": {
      "select_id": 1,
      "steps": [
        {
          "expanded_query": "select t1.a AS a,t1.b AS b,t1.col1 AS col1 from t1 where t1.col1 < 3"
        }

```

Here, one can see that `NOT` was removed.

 Similarly, one can also see that `IN(...)` with one element is the same as equality:

 
```
explain select * from t1 where col1  in (1);

```

will show

 
```
  "join_preparation": {
    "select_id": 1,
    "steps": [
      {
        "expanded_query": "select t1.a AS a,t1.b AS b,t1.col1 AS col1 from t1 where t1.col1 = 1"

```

On the other hand, converting an UTF-8 column to UTF-8 is not removed:

 
```
explain select * from t1 where convert(utf8_col using utf8) = 'hello';

```

will show 

 
```
  "join_preparation": {
    "select_id": 1,
    "steps": [
      {
        "expanded_query": "select t1.a AS a,t1.b AS b,t1.col1 AS col1,t1.utf8_col AS utf8_col from t1 where convert(t1.utf8_col using utf8) = 'hello'"
          }

```

so redundant `CONVERT` calls should be used with caution.

 ### VIEW Processing

 MariaDB has two algorithms to handle VIEWs: merging and materialization. If you run a query that uses a VIEW, the trace will have either

 
```
            "view": {
              "table": "view1",
              "select_id": 2,
              "algorithm": "merged"
            }

```

or

 
```
          {
            "view": {
              "table": "view2",
              "select_id": 2,
              "algorithm": "materialized"
            }
          },

```

depending on which algorithm was used.

 ### Range Optimizer - What Ranges Will Be Scanned

 The MariaDB optimizer has a complex part called the Range Optimizer. This is a module that examines WHERE (and ON) clauses and constructs index ranges that need to be scanned to answer the query. The rules for constructing the ranges are quite complex.

 An example: Consider a table

 
```
create table some_events ( 
  start_date date, 
  end_date date, 
  ...
  key (start_date, end_date)
);

```

and a query:

 
```
explain select * from some_events where start_date >= '2019-09-10' and end_date <= '2019-09-14';
+------+-------------+-------------+------+---------------+------+---------+------+------+-------------+
| id   | select_type | table       | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+------+-------------+-------------+------+---------------+------+---------+------+------+-------------+
|    1 | SIMPLE      | some_events | ALL  | start_date    | NULL | NULL    | NULL | 1000 | Using where |
+------+-------------+-------------+------+---------------+------+---------+------+------+-------------+

```

One might think that the optimizer would be able to use the restrictions on both *start\_date* and *end\_date* to construct a narrow range to be scanned. But this is not so, one of the restrictions creates a left-endpoint range and the other one creates a right-endpoint range, hence they cannot be combined.

 
```
select 
   JSON_DETAILED(JSON_EXTRACT(trace, '$**.analyzing_range_alternatives')) as trace 
from information_schema.optimizer_trace\G
*************************** 1. row ***************************
trace: [
    {
        "range_scan_alternatives": 
        [
            {
                "index": "start_date",
                "ranges": 
                [
                    "(2019-09-10,NULL) < (start_date,end_date)"
                ],
...

```

the potential range only uses one of the bounds.

 ### Ref Access Options

 Index-based Nested-loops joins are called "ref access" in the MariaDB optimizer.

 The optimizer analyzes the WHERE/ON conditions and collects all equality conditions that can be used by ref access using some index. 

 The list of conditions can be found in the `ref_optimizer_key_uses` node. (TODO example)

 ### Join Optimization

 The join optimizer's node is named `considered_execution_plans`.

 The optimizer constructs the join orders in a left-to-right fashion. That is, if the query is a join of three tables:

 
```
select * from t1, t2, t3 where ...

```

then the optimizer will

 * Pick the first table (say, it is t1),
* consider adding another table (say, t2), and construct a prefix "t1, t2"
* consider adding the third table (t3), and constructing a prefix "t1, t2, t3", which is a complete join plan Other join orders will be considered as well.

 The basic operation here is: "given a join prefix of tables A,B,C ..., try adding table X to it". In JSON, it looks like this:

 
```
      {
        "plan_prefix": ["t1", "t2"],
        "table": "t3",
        "best_access_path": {
          "considered_access_paths": [
            {
              ...
            }
          ]
        }
      }

```

(search for `plan_prefix` followed by `table`).

 If you are interested in how the join order of #t1,t2,t3# was constructed (or not constructed), you need to search for these patterns:

 * `"plan_prefix":[], "table":"t1"`
* `"plan_prefix":["t1"], "table":"t2"`
* `"plan_prefix":["t1", "t2"], "table":"t3"`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-trace-guide/>

Basic Optimizer Trace Example
=============================

    
```
MariaDB> set optimizer_trace=’enabled=on’;

MariaDB> select * from t1 where a<10;

MariaDB> select * from information_schema.optimizer_trace limit 1\G
*************************** 1. row ***************************
                            QUERY: select * from t1 where a<10
                            TRACE: {
  "steps": [
    {
      "join_preparation": {
        "select_id": 1,
        "steps": [
          {
            "expanded_query": "select t1.a AS a,t1.b AS b,t1.c AS c from t1 where t1.a < 10"
          }
        ]
      }
    },
    {
      "join_optimization": {
        "select_id": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "t1.a < 10",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "t1.a < 10"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "t1.a < 10"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "t1.a < 10"
                }
              ]
            }
          },
          {
            "table_dependencies": [
              {
                "table": "t1",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": []
              }
            ]
          },
          {
            "ref_optimizer_key_uses": []
          },
          {
            "rows_estimation": [
              {
                "table": "t1",
                "range_analysis": {
                  "table_scan": {
                    "rows": 1000,
                    "cost": 206.1
                  },
                  "potential_range_indexes": [
                    {
                      "index": "a",
                      "usable": true,
                      "key_parts": ["a"]
                    },
                    {
                      "index": "b",
                      "usable": false,
                      "cause": "not applicable"
                    }
                  ],
                  "setup_range_conditions": [],
                  "group_index_range": {
                    "chosen": false,
                    "cause": "no group by or distinct"
                  },
                  "analyzing_range_alternatives": {
                    "range_scan_alternatives": [
                      {
                        "index": "a",
                        "ranges": ["(NULL) < (a) < (10)"],
                        "rowid_ordered": false,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 10,
                        "cost": 13.751,
                        "chosen": true
                      }
                    ],
                    "analyzing_roworder_intersect": {
                      "cause": "too few roworder scans"
                    },
                    "analyzing_index_merge_union": []
                  },
                  "chosen_range_access_summary": {
                    "range_access_plan": {
                      "type": "range_scan",
                      "index": "a",
                      "rows": 10,
                      "ranges": ["(NULL) < (a) < (10)"]
                    },
                    "rows_for_plan": 10,
                    "cost_for_plan": 13.751,
                    "chosen": true
                  }
                }
              },
              {
                "selectivity_for_indexes": [
                  {
                    "index_name": "a",
                    "selectivity_from_index": 0.01
                  }
                ],
                "selectivity_for_columns": [],
                "cond_selectivity": 0.01
              }
            ]
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [],
                "table": "t1",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "access_type": "range",
                      "resulting_rows": 10,
                      "cost": 13.751,
                      "chosen": true
                    }
                  ]
                }
              }
            ]
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "t1.a < 10",
              "attached_conditions_computation": [],
              "attached_conditions_summary": [
                {
                  "table": "t1",
                  "attached": "t1.a < 10"
                }
              ]
            }
          }
        ]
      }
    },
    {
      "join_execution": {
        "select_id": 1,
        "steps": []
      }
    }
  ]
}
MISSING_BYTES_BEYOND_MAX_MEM_SIZE: 0
          INSUFFICIENT_PRIVILEGES: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/basic-optimizer-trace-example/>

Optimizer Trace Resources
=========================

    * Optimizer Trace Walkthrough talk at MariaDB Fest 2020: <https://mariadb.org/fest2020/optimizer-trace/>
* A tool for processing Optimizer Trace: <https://github.com/ogrovlen/opttrace> . Doesn't work with MariaDB at the moment but everyone is welcome to make it work.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-trace-resources/>

Exploring Early Database Models
===============================

    Before the advent of databases, the only way to store data was from unrelated files. Programmers had to go to great lengths to extract the data, and their programs had to perform complex parsing and relating.

 Languages such as Perl, with its powerful regular expressions ideal for processing text, have made the job a lot easier than before; however, accessing the data from files is still a challenging task. Without a standard way to access data, systems are more prone to errors, are slower to develop, and are more difficult to maintain. Data redundancy (where data is duplicated unnecessarily) and poor data integrity (where data is not changed in all locations, leading to wrong or outdated data being supplied) are frequent consequences of the file access method of data storage. For these reasons, database management systems (DBMSs) were developed to provide a standard and reliable way to access and update data. They provide an intermediary layer between the application and the data, and the programmer is able to concentrate on developing the application, rather than worrying about data access issues.

 A *database model* is a logical model concerned with how the data is represented. Instead of database designers worrying about the physical storage of data, the database model allows them to look at a higher, more conceptual level, reducing the gap between the real-world problem for which the application is being developed and the technical implementation.

 There are a number of database models. The next two articles cover two common models; the [hierarchical database model](../understanding-the-hierarchical-database-model/index) and the [network database model](../understanding-the-network-database-model/index). After that comes the one MariaDB, along with most modern DBMSs uses, the relational model.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/exploring-early-database-models/>

mysql.spider\_link\_mon\_servers Table
======================================

    The `mysql.spider_link_mon_servers` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO | PRI |  |  |
| table\_name | char(199) | NO | PRI |  |  |
| link\_id | char(64) | NO | PRI |  |  |
| sid | int(10) unsigned | NO | PRI | 0 |  |
| server | char(64) | YES |  | NULL |  |
| scheme | char(64) | YES |  | NULL |  |
| host | char(64) | YES |  | NULL |  |
| port | char(5) | YES |  | NULL |  |
| socket | text | YES |  | NULL |  |
| username | char(64) | YES |  | NULL |  |
| password | char(64) | YES |  | NULL |  |
| ssl\_ca | text | YES |  | NULL |  |
| ssl\_capath | text | YES |  | NULL |  |
| ssl\_cert | text | YES |  | NULL |  |
| ssl\_cipher | char(64) | YES |  | NULL |  |
| ssl\_key | text | YES |  | NULL |  |
| ssl\_verify\_server\_cert | tinyint(4) | NO |  | 0 |  |
| default\_file | text | YES |  | NULL |  |
| default\_group | char(64) | YES |  | NULL |  |
| dsn | char(64) | YES |  | NULL |  |
| filedsn | text | YES |  | NULL |  |
| driver | char(64) | YES |  | NULL |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_link_mon_servers-table/>

mysql.spider\_link\_failed\_log Table
=====================================

    The `mysql.spider_link_failed_log` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO |  |  |  |
| table\_name | char(199) | NO |  |  |  |
| link\_id | char(64) | NO |  |  |  |
| failed\_time | timestamp | NO |  | current\_timestamp() |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_link_failed_log-table/>

Optimizer Trace for Developers
==============================

    This article describes guidelines for what/how to write to Optimizer Trace when doing server development.

 Basic considerations
--------------------

 The trace is a "structured log" of what was done by the optimizer. Prefer to do tracing as soon as a rewrite/decision is made (instead of having a separate trace\_something() function).

 (TODO other considerations)

 Making sure the trace is valid
------------------------------

 `Json_writer_object` and `Json_writer_array` classes use RAII idiom and ensure that JSON objects and arrays are "closed" in the reverse order they were started.

 However, they do not ensure these constraints:

 * JSON objects must have named members.
* JSON arrays must have unnamed members.

 Tracing code has runtime checks for these. Attempt to write invalid JSON will cause assertion failure.

 Test coverage
-------------

 It is possible to run `mysql-test-run` with this argument

 
```
 --mysqld=--optimizer_trace=enabled=on

```

This will run all tests with tracing on. As mentioned earlier, debug build will perform checks that we are not producing invalid trace. 

 The BuildBot instance at <http://buildbot.askmonty.org/> also runs tests with this argument, see `mtr_opttrace` pass in kvm-fulltest and kvm-fulltest2.

 Debugging
---------

 In newer MariaDB versions, there is 

 
```
const char *dbug_print_opt_trace();

```

function which one can use to print the trace produced so far.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-trace-for-developers/>

mysql.spider\_xa\_failed\_log Table
===================================

    The `mysql.spider_xa_failed_log` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| format\_id | int(11) | NO |  | 0 |  |
| gtrid\_length | int(11) | NO |  | 0 |  |
| bqual\_length | int(11) | NO |  | 0 |  |
| data | binary(128) | NO | MUL |  |  |
| scheme | char(64) | NO |  |  |  |
| host | char(64) | NO |  |  |  |
| port | char(5) | NO |  |  |  |
| socket | text | NO |  | NULL |  |
| username | char(64) | NO |  |  |  |
| password | char(64) | NO |  |  |  |
| ssl\_ca | text | YES |  | NULL |  |
| ssl\_capath | text | YES |  | NULL |  |
| ssl\_cert | text | YES |  | NULL |  |
| ssl\_cipher | char(64) | YES |  | NULL |  |
| ssl\_key | text | YES |  | NULL |  |
| ssl\_verify\_server\_cert | tinyint(4) | NO |  | 0 |  |
| default\_file | text | YES |  | NULL |  |
| default\_group | char(64) | YES |  | NULL |  |
| dsn | char(64) | YES |  | NULL |  |
| filedsn | text | YES |  | NULL |  |
| driver | char(64) | YES |  | NULL |  |
| thread\_id | int(11) | YES |  | NULL |  |
| status | char(8) | NO |  |  |  |
| failed\_time | timestamp | NO |  | current\_timestamp() |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_xa_failed_log-table/>

Introduction to Relational Databases
====================================

    What is a Database?
-------------------

 The easiest way to understand a database is as a collection of related files. Imagine a file (either paper or digital) of sales orders in a shop. Then there's another file of products, containing stock records. To fulfil an order, you'd need to look up the product in the order file and then look up and adjust the stock levels for that particular product in the product file. A database and the software that controls the database, called a *database management system* (DBMS), helps with this kind of task.

 Most databases today are *relational* databases, named such because they deal with tables of data related by a common field. For example, Table 1 below shows the product table, and Table 2 shows the invoice table. As you can see, the relation between the two tables is based on the common field `product_code`. Any two tables can relate to each other simply by having a field in common.

 ### Table 1

 


| *Product\_code* | Description | Price |
| --- | --- | --- |
| A416 | Nails, box | $0.14 |
| C923 | Drawing pins, box | $0.08 |

 
### Table 2

 


| Invoice\_code | Invoice\_line | *Product\_code* | Quantity |
| --- | --- | --- | --- |
| 3804 | 1 | A416 | 10 |
| 3804 | 2 | C923 | 15 |

 
Database Terminology
--------------------

 Let's take a closer look at the previous two tables to see how they are organized:

 * Each table consists of many *rows* and *columns*.
* Each new row contains data about one single *entity* (such as one product or one order line). This is called a *record*. For example, the first row in Table 1 is a record; it describes the A416 product, which is a box of nails that costs fourteen cents. The terms *row* and *record* are interchangeable.
* Each column (also called an *attribute*) contains one piece of data that relates to the record, called a *tuple*. Examples of attributes are the quantity of an item sold or the price of a product. An attribute, when referring to a database table, is called a *field*. For example, the data in the *Description* column in Table 1 are fields. The terms *attribute* and *field* are interchangeable.

 Given this kind of structure, the database gives you a way to manipulate this data: SQL. SQL (structured query language) is a powerful way to search for records or make changes. Almost all DBMSs use SQL, although many have added their own enhancements to it. This means that when you learn SQL while using MariaDB, almost all of it is not specific to MariaDB and can be used with other relational databases as well, such as PostgreSQL, MySQL, Oracle and SQL Server. MariaDB was originally-created as a drop-in replacement to MySQL, so MariaDB and MySQL are particularly close.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/introduction-to-relational-databases/>

mysql.spider\_xa\_member Table
==============================

    The `mysql.spider_xa_member` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| format\_id | int(11) | NO |  | 0 |  |
| gtrid\_length | int(11) | NO |  | 0 |  |
| bqual\_length | int(11) | NO |  | 0 |  |
| data | binary(128) | NO | MUL |  |  |
| scheme | char(64) | NO |  |  |  |
| host | char(64) | NO |  |  |  |
| port | char(5) | NO |  |  |  |
| socket | text | NO |  | NULL |  |
| username | char(64) | NO |  |  |  |
| password | char(64) | NO |  |  |  |
| ssl\_ca | text | YES |  | NULL |  |
| ssl\_capath | text | YES |  | NULL |  |
| ssl\_cert | text | YES |  | NULL |  |
| ssl\_cipher | char(64) | YES |  | NULL |  |
| ssl\_key | text | YES |  | NULL |  |
| ssl\_verify\_server\_cert | tinyint(4) | NO |  | 0 |  |
| default\_file | text | YES |  | NULL |  |
| default\_group | char(64) | YES |  | NULL |  |
| dsn | char(64) | YES |  | NULL |  |
| filedsn | text | YES |  | NULL |  |
| driver | char(64) | YES |  | NULL |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_xa_member-table/>

Storage Snapshots and BACKUP STAGE Commands
===========================================

    
**MariaDB starting with [10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/)**The `BACKUP STAGE` commands were introduced in [MariaDB 10.4.1](https://mariadb.com/kb/en/mariadb-1041-release-notes/).

  The [BACKUP STAGE](../backup-stage/index) commands are a set of commands to make it possible to make an efficient external backup tool. These commands could even be used by tools that perform backups by taking a snapshot of a file system, SAN, or some other kind of storage device.

 Generic Backup Process with Storage Snapshots
---------------------------------------------

 A tool that backs up MariaDB by taking a snapshot of a file system, SAN, or some other kind of storage device could use each `BACKUP STAGE` command in the following way:

 * First, execute the following:

 
```
BACKUP STAGE START
BACKUP STAGE BLOCK_COMMIT

```

* Then, take the snapshot.

 * Then, execute the following:

 
```
BACKUP STAGE END

```

The above ensures that all non-transactional tables are properly flushed to disk before the snapshot is done. Using `BACKUP STAGE` commands is also more efficient than using the [FLUSH TABLES WITH READ LOCK](../flush/index) command as the above set of commands will not block or be blocked by write operations to transactional tables.

 Note that when the backup is completed, one should delete all files with the "#sql" prefix, as these are files used by concurrent running `ALTER TABLE`. Note that InnoDB will on server restart automatically delete any tables with the "#sql" prefix.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-snapshots-and-backup-stage-commands/>

mysql.spider\_table\_crd Table
==============================

    The `mysql.spider_table_crd` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO | PRI |  |  |
| table\_name | char(199) | NO | PRI |  |  |
| key\_seq | int(10) unsigned | NO | PRI | 0 |  |
| cardinality | bigint(20) | NO |  | 0 |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_table_crd-table/>

mysql.spider\_xa Table
======================

    The `mysql.spider_xa` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| format\_id | int(11) | NO | PRI | 0 |  |
| gtrid\_length | int(11) | NO | PRI | 0 |  |
| bqual\_length | int(11) | NO |  | 0 |  |
| data | binary(128) | NO | PRI |  |  |
| status | char(8) | NO | MUL |  |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_xa-table/>

mysql.spider\_table\_position\_for\_recovery Table
==================================================

    The `mysql.spider_table_position_for_recovery` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO | PRI |  |  |
| table\_name | char(199) | NO | PRI |  |  |
| failed\_link\_id | int(11) | NO | PRI | 0 |  |
| source\_link\_id | int(11) | NO | PRI | 0 |  |
| file | text | YES |  | NULL |  |
| position | text | YES |  | NULL |  |
| gtid | text | YES |  | NULL |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_table_position_for_recovery-table/>

mysql.spider\_tables Table
==========================

    The `mysql.spider_tables` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO | PRI |  |  |
| table\_name | char(199) | NO | PRI |  |  |
| link\_id | int(11) | NO | PRI | 0 |  |
| priority | bigint(20) | NO | MUL | 0 |  |
| server | char(64) | YES |  | NULL |  |
| scheme | char(64) | YES |  | NULL |  |
| host | char(64) | YES |  | NULL |  |
| port | char(5) | YES |  | NULL |  |
| socket | text | YES |  | NULL |  |
| username | char(64) | YES |  | NULL |  |
| password | char(64) | YES |  | NULL |  |
| ssl\_ca | text | YES |  | NULL |  |
| ssl\_capath | text | YES |  | NULL |  |
| ssl\_cert | text | YES |  | NULL |  |
| ssl\_cipher | char(64) | YES |  | NULL |  |
| ssl\_key | text | YES |  | NULL |  |
| ssl\_verify\_server\_cert | tinyint(4) | NO |  | 0 |  |
| monitoring\_binlog\_pos\_at\_failing | tinyint(4) | NO |  | 0 |  |
| default\_file | text | YES |  | NULL |  |
| default\_group | char(64) | YES |  | NULL |  |
| dsn | char(64) | YES |  | NULL |  |
| filedsn | text | YES |  | NULL |  |
| driver | char(64) | YES |  | NULL |  |
| tgt\_db\_name | char(64) | YES |  | NULL |  |
| tgt\_table\_name | char(64) | YES |  | NULL |  |
| link\_status | tinyint(4) | NO |  | 1 |  |
| block\_status | tinyint(4) | NO |  | 0 |  |
| static\_link\_id | char(64) | YES |  | NULL |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_tables-table/>

mysql.spider\_table\_sts Table
==============================

    The `mysql.spider_table_sts` table is installed by the [Spider storage engine](../spider/index).

 
**MariaDB starting with [10.4](../what-is-mariadb-104/index)**In [MariaDB 10.4](../what-is-mariadb-104/index) and later, this table uses the [Aria](../aria/index) storage engine.

 

**MariaDB until [10.3](../what-is-mariadb-103/index)**In [MariaDB 10.3](../what-is-mariadb-103/index) and before, this table uses the [MyISAM](../myisam-storage-engine/index) storage engine.

 
It contains the following fields:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| db\_name | char(64) | NO | PRI |  |  |
| table\_name | char(199) | NO | PRI |  |  |
| data\_file\_length | bigint(20) unsigned | NO |  | 0 |  |
| max\_data\_file\_length | bigint(20) unsigned | NO |  | 0 |  |
| index\_file\_length | bigint(20) unsigned | NO |  | 0 |  |
| records | bigint(20) unsigned | NO |  | 0 |  |
| mean\_rec\_length | bigint(20) unsigned | NO |  | 0 |  |
| check\_time | datetime | NO |  | 0000-00-00 00:00:00 |  |
| create\_time | datetime | NO |  | 0000-00-00 00:00:00 |  |
| update\_time | datetime | NO |  | 0000-00-00 00:00:00 |  |
| checksum | bigint(20) unsigned | YES |  | NULL |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlspider_table_sts-table/>

BACKUP LOCK
===========

    
**MariaDB starting with [10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/)**The BACKUP LOCK command was introduced in [MariaDB 10.4.2](https://mariadb.com/kb/en/mariadb-1042-release-notes/).

  BACKUP LOCK blocks a table from DDL statements. This is mainly intended to be used by tools like [mariabackup](../mariabackup/index) that need to ensure there are no DDLs on a table while the table files are opened. For example, for an Aria table that stores data in 3 files with extensions .frm, .MAI and .MAD. Normal read/write operations can continue as normal.

 Syntax
------

 To lock a table:

 
```
BACKUP LOCK table_name

```

To unlock a table:

 
```
BACKUP UNLOCK

```

Usage in a Backup Tool
----------------------

 
```
BACKUP LOCK [database.]table_name;
 - Open all files related to a table (for example, t.frm, t.MAI and t.MYD)
BACKUP UNLOCK;
- Copy data
- Close files

```

This ensures that all files are from the same generation, that is created at the same time by the MariaDB server. This works, because the open files will point to the original table files which will not be affected if there is any ALTER TABLE while copying the files.

 Privileges
----------

 BACKUP LOCK requires the [RELOAD](../grant/index) privilege.

 Notes
-----

 * The idea is that the `BACKUP LOCK` should be held for as short a time as possible by the backup tool. The time to take an uncontested lock is very short! One can easily do 50,000 locks/unlocks per second on low end hardware.
* One should use different connections for [BACKUP STAGE](../backup-stage/index) commands and `BACKUP LOCK`.

 Implementation
--------------

 * Internally, BACKUP LOCK is implemented by taking an `MDLSHARED_HIGH_PRIO` MDL lock on the table object, which protects the table from any DDL operations.

 See Also
--------

 * [BACKUP STAGE](../backup-stage/index)
* [MDEV-17309](https://jira.mariadb.org/browse/MDEV-17309) - BACKUP LOCK: DDL locking of tables during backup

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/backup-lock/>

How to Collect Large Optimizer Traces
=====================================

    [Optimizer traces](../mariadb-internals-documentation-optimizer-trace/index) can be large for some queries.

 In order to collect a large trace, you need to perform the following steps (using 128 MB as an example):

 
```
set global max_allowed_packet=128*1024*1024;

```

Reconnect specifying `--max-allowed-packet=128000000` for the client as well.

 
```
set optimizer_trace=1;
set optimizer_trace_max_mem_size=127*1024*1024;

```

Now, one can run the query and save the large trace.

 See Also
--------

 * [optimizer\_trace](../server-system-variables/index#optimizer_trace) system variable
* [optimizer\_trace\_max\_mem\_size](../server-system-variables/index#optimizer_trace_max_mem_size) system variable
* [max\_allowed\_packet](../server-system-variables/index#max_allowed_packet) system variable

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-to-collect-large-optimizer-traces/>

Understanding the Network Database Model
========================================

    The network database model was a progression from the [hierarchical database model](../understanding-the-hierarchical-database-model/index) and was designed to solve some of that model's problems, specifically the lack of flexibility. Instead of only allowing each child to have one parent, this model allows each child to have multiple parents (it calls the children *members* and the parents *owners*). It addresses the need to model more complex relationships such as the orders/parts many-to-many relationship mentioned in the [hierarchical article](../understanding-the-hierarchical-database-model/index). As you can see in the figure below, *A1* has two members, *B1* and *B2*. *B1.* is the owner of *C1*, *C2*, *C3* and *C4*. However, in this model, *C4* has two owners, *B1* and *B2*.

 ![network_model]

 Of course, this model has its problems, or everyone would still be using it. It is more difficult to implement and maintain, and, although more flexible than the hierarchical model, it still has flexibility problems, Not all relations can be satisfied by assigning another owner, and the programmer still has to understand the data structure well in order to make the model efficient.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/understanding-the-network-database-model/>

Understanding the Hierarchical Database Model
=============================================

    The earliest model was the hierarchical database model, resembling an upside-down tree. Files are related in a parent-child manner, with each parent capable of relating to more than one child, but each child only being related to one parent. Most of you will be familiar with this kind of structure—it’s the way most file systems work. There is usually a root, or top-level, directory that contains various other directories and files. Each subdirectory can then contain more files and directories, and so on. Each file or directory can only exist in one directory itself—it only has one parent. As you can see in the image below *A1* is the root directory, and its children are *B1* and *B2*. *B1* is a parent to *C1*, *C2*, and *C3*, which in turn has children of its own.

 ![hierarchical_model2]

 This model, although being a vast improvement on dealing with unrelated files, has some serious disadvantages. It represents one-to-many relationships well (one parent has many children; for example, one company branch has many employees), but it has problems with many-to-many relationships. Relationships such as that between a product file and an orders file are difficult to implement in a hierarchical model. Specifically, an order can contain many products, and a product can appear in many orders. Also, the hierarchical model is not flexible because adding new relationships can result in wholesale changes to the existing structure, which in turn means all existing applications need to change as well. This is not fun when someone has forgotten a table and wants it added to the system shortly before the project is due to launch! And developing the applications is complex because the programmer needs to know the data structure well in order to traverse the model to access the needed data. As you’ve seen in the earlier chapters, when accessing data from two related tables, you only need to know the fields you require from those two tables. In the hierarchical model, you’d need to know the entire chain between the two. For example, to relate data from *A1* and *D4*, you’d need to take the route: *A1*, *B1*, *C3* and *D4*.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/understanding-the-hierarchical-database-model/>

Understanding the Relational Database Model
===========================================

    The relational database model was a huge leap forward from the [network database model](../understanding-the-network-database-model/index). Instead of relying on a parent-child or owner-member relationship, the relational model allows any file to be related to any other by means of a common field. Suddenly, the complexity of the design was greatly reduced because changes could be made to the database schema without affecting the system's ability to access data. And because access was not by means of paths to and from files, but from a direct relationship between files, new relations between these files could easily be added.

 In 1970, when E.F. Codd developed the model, it was thought to be impractical. The increased ease of use comes at a large performance penalty, and the hardware in those days was not able to implement the model. Since then, of course, hardware has taken huge strides to where today, even the simplest computers can run sophisticated relational database management systems.

 Relational databases go hand-in-hand with the development of SQL. The simplicity of SQL - where even a novice can learn to perform basic queries in a short period of time - is a large part of the reason for the popularity of the relational model.

 The two tables below relate to each other through the *product\_code* field. Any two tables can relate to each other simply by creating a field they have in common.

 ### Table 1

 


| *Product\_code* | Description | Price |
| --- | --- | --- |
| A416 | Nails, box | $0.14 |
| C923 | Drawing pins, box | $0.08 |

 
### Table 2

 


| Invoice\_code | Invoice\_line | *Product\_code* | Quantity |
| --- | --- | --- | --- |
| 3804 | 1 | A416 | 10 |
| 3804 | 2 | C923 | 15 |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/understanding-the-relational-database-model/>

Relational Databases: Basic Terms
=================================

    The relational database model uses certain terms to describe its components:

 * *Data* are the values kept in the database. On their own, the data means very little. `CA 684-213` is an example of data in a DMV (Division of Motor Vehicles) database.
* *Information* is processed data. For example, `CA 684-213` is the car registration number of a car belonging to Lyndon Manson, in a DMV database.
* A *database* is a collection of *tables*, also called *entities*.
* Each table is made up of *records* (the horizontal rows in the table, also called *tuples*). Each record should be unique, and can be stored in any order in the table.
* Each record is made up of *fields* (which are the vertical columns of the table, also called *attributes*). Basically, a record is one fact (for example, one customer or one sale).
* These fields can be of various *types*. MariaDB has many types (see [Data Types](../data-types/index) for a list), but generally types fall into three kinds: character, numeric, and date. For example, a customer name is a character field, a customer's birthday is a date field, and a customer's number of children is a numeric field.
* The range of allowed values for a field is called the *domain* (also called a *field specification*). For example, a credit card field may be limited to only the values `Mastercard`, `Visa` and `Amex`.
* A field is said to contain a *null* value when it contains nothing at all. Null fields can create complexities in calculations and have consequences for data accuracy. For this reason, many fields are specifically set not to contain null values.
* A *key* accesses specific records in a table.
* An *index* is a mechanism to improve the performance of a database. Indexes are often confused with keys. Indexes are, strictly speaking, part of the physical structure, and keys are part of the logical structure. You'll often see the terms used interchangeably, however, including throughout this Knowledge Base.
* A *view* is a virtual table made up of a subset of the actual tables.
* A *one-to-one* (1:1) relationship is where for each instance of the first table in a relationship, only one instance of the second table exists, An example of this would be a case where a chain of stores carries a vending machine. Each vending machine can only be in one store, and each store carries only one vending machine. ![one_to_one_relationship]
* A *one-to-many* (1:N) relationship is where for each instance of the first table in a relationship, many instances of the second table exist. This is a common kind of relationship. An example is the relationship between a sculptor and their sculptures. Each sculptor may have created many sculptures, but each sculpture has been created by only one sculptor. ![one_to_many_relationship]
* A *many-to-many* (M:N) relationship occurs where, for each instance of the first table, there are many instances of the second table, and for each instance of the second table, there are many instances of the first. For example, a student can have many lecturers, and a lecturer can have many students. ![many_to_many_relationship]
* A *mandatory* relationship exists where for each instance of the first table in a relationship, one or more instances of the second *must* exist. For example, for a music group to exist, there must exist at least one musician in that group.
* An *optional* relationship is where for each instance of the first table in a relationship, there *may* exist instances of the second. For example, if an author can be listed in the database without having written a book (in other words, a prospective author), that relationship is optional. The reverse isn't necessarily true though. For example, for a book to be listed, it must have an author.
* *Data integrity* refers to the condition where data is accurate, valid, and consistent. An example of poor integrity would be if a customer telephone number is stored differently in two different locations. Another is where a course record contains a reference to a lecturer who is no longer present at the school. [Database normalization](../database-normalization/index) is a technique that assists you to minimize the risk of these sorts of problems.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/relational-databases-basic-terms/>

Relational Databases: Table Keys
================================

    A *key*, or *index*, as the term itself indicates, unlocks access to the tables. If you know the key, you know how to identify specific records and the relationships between the tables.

 Each key consists of one or more fields, or field prefix. The order of columns in an index is significant. Each key has a name.

 A *candidate key* is a field, or combination of fields, that uniquely identifies a record. It cannot contain a null value, and its value must be unique. (With duplicates, you would no longer be identifying a unique record).

 A *primary key* (PK) is a candidate key that has been designated to identify unique records in the table throughout the database structure.

 A *surrogate key* is a primary key that contains unique values automatically generated by the database system - usually, integer numbers. A surrogate key has no meaning, except uniquely identifying a record. This is the most common type of primary key.

 For example, see the following table:

 


| Customer\_code | First\_name | Surname | Telephone\_number |
| --- | --- | --- | --- |
| 1 | Ariane | Edison | 448-2143 |
| 2 | Georgei | Edison | 448-2142 |
| 3 | Abbas | Edison | 9231-5312 |

 
At first glance, there are two possible candidate keys for this table. Either *customer\_code* or a combination of *first\_name*, *surname* and *telephone\_number* would suffice. It is always better to choose the candidate key with the least number of fields for the primary key, so you would choose *customer\_code* in this example (note that it is a surrogate key). Upon reflection, there is also the possibility of the second combination not being unique. The combination of *first\_name*, *surname* and *telephone\_number* could in theory be duplicated, such as where a father has a son of the same name who is contactable at the same telephone number. This system would have to expressly exclude this possibility for these three fields to be considered for the status of primary key.

 There may be many Ariane Edisons, but you avoid confusion by assigning each a unique number. Once a primary key has been created, the remaining candidates are labeled as *alternate keys*.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/relational-databases-table-keys/>

Relational Databases: Views
===========================

    Views are virtual tables. They are only a structure, and contain no data. Their purpose is to allow a user to see a subset of the actual data. A view can consist of a subset of one table. For example, the *student view*, below, is a subset of the *student table*.

 


| Student View |
| --- |
| First name |
| Surname |
| Grade |

 



| Student Table |
| --- |
| Student\_id |
| First name |
| Surname |
| Grade |
| Address |
| Telephone |

 
This view could be used to allow other students to see their fellow student's marks but not allow them access to personal information. 

 Alternatively, a view could be a combination of a number of tables, such as the view below:

 


| Student View |
| --- |
| First name |
| Surname |
| Grade |

 



| Student Table |
| --- |
| Student\_id |
| First name |
| Surname |
| Address |
| Telephone |

 



| Course Table |
| --- |
| Course\_id |
| Course description |

 



| Grade Table |
| --- |
| Student\_id |
| Course\_id |
| Grade |

 
Views are also useful for security. In larger organizations, where many developers may be working on a project, views allow developers to access only the data they need. What they don't need, even if it is in the same table, is hidden from them, safe from being seen or manipulated. It also allows queries to be simplified for developers. For example, without the view, a developer would have to retrieve the fields in the view with the following sort of query

 
```
SELECT first_name, surname, course_description, grade FROM student, grade, course 
  WHERE grade.student_id = student.student_id AND grade.course_id = course.course_id

```

With the view, a developer could do the same with the following:

 
```
SELECT first_name, surname, course_description, grade FROM student_grade_view

```

Much simpler for a junior developer who hasn't yet learned to do joins, and it's just less hassle for a senior developer too!

 For more use cases, see the [Views Tutorial](../views-tutorial/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/relational-databases-views/>

Database Design
================

   Articles about the database design process

  

| Title | Description |
| --- | --- |
|  [Database Design: Overview](../database-design-overview/index) |  Databases exist because of the need to change data into information  |
|  [Database Lifecycle](../database-lifecycle/index) |  Like everything else, databases have a finite lifespan  |
|  [Database Design Phase 1: Analysis](../database-design-phase-1-analysis/index) |  Defining problems, possibilities, constraints, objectives and agreeing on the scope  |
|  [Database Design Phase 2: Conceptual Design](../database-design-phase-2-conceptual-design/index) |  Requirements identified in the previous phase are used as the basis to develop the new system  |
|  [Database Design Phase 2: Logical and Physical Design](../database-design-phase-2-logical-and-physical-design/index) |  After conceptual design, it's time to convert to the logical and physical design  |
|  [Database Design Phase 3: Implementation](../database-design-phase-3-implementation/index) |  Install the DBMS and load the data  |
|  [Database Design Phase 4: Testing](../database-design-phase-4-testing/index) |  Testing performance, security, and integrity of the data  |
|  [Database Design Phase 5: Operation](../database-design-phase-5-operation/index) |  Rolling out for everyday use  |
|  [Database Design Phase 6: Maintenance](../database-design-phase-6-maintenance/index) |  Maintaining indexes, optimizing tables, adding and removing users, changing passwords  |
|  [Database Design Example Phase 1: Analysis](../database-design-example-phase-1-analysis/index) |  Walking through the database design process with a step-by-step example  |
|  [Database Design Example Phase 2: Design](../database-design-example-phase-2-design/index) |  Poet Circle logical design and identifying the initial entities  |
|  [Database Design Example Phase 3: Implementation](../database-design-example-phase-3-implementation/index) |  Creating the Poet's Circle tables  |
|  [Database Design Example Phases 4-6: Testing, Operation and Maintenance](../database-design-example-phases-4-6-testing-operation-and-maintenance/index) |  Testing, rolling out and maintenance of the Poet's Circle database.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design/>

Slave SQL Thread States
=======================

    This article documents thread states that are related to [replication](../replication/index) slave SQL threads. These correspond to the `Slave_SQL_State` shown by [SHOW SLAVE STATUS](../show-slave-status/index) as well as the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement and the [Information Schema PROCESSLIST](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| Apply log event | Log event is being applied. |
| Making temp file | Creating a temporary file containing the row data as part of a [LOAD DATA INFILE](../load-data-infile/index) statement. |
| Reading event from the relay log | Reading an event from the [relay log](../relay-log/index) in order to process the event. |
| Slave has read all relay log; waiting for the slave I/O thread to update it | All [relay log](../relay-log/index) events have been processed, now waiting for the I/O thread to write new events to the relay log. |
| Waiting for work from SQL thread |  In parallel replication the worker thread is waiting for more things from the SQL thread. |
| Waiting for prior transaction to start commit before starting next transaction | In parallel replication the worker thread is waiting for conflicting things to end before starting executing. |
| Waiting for worker threads to be idle |  Happens in parallel replication when moving to a new binary log after a master restart. All slave temporary files are deleted and worker threads are restarted. |
| Waiting due to global read lock | In parallel replication when worker threads are waiting for a global read lock to be released. |
| Waiting for worker threads to pause for global read lock | [FLUSH TABLES WITH READ LOCK](../flush/index) is waiting for worker threads to finish what they are doing. |
| Waiting while replication worker thread pool is busy | Happens in parallel replication during a [FLUSH TABLES WITH READ LOCK](../flush/index) or when changing number of parallel workers. |
| Waiting for other master connection to process GTID received on multiple master connections |  A worker thread noticed that there is already another thread executing the same GTID from another connection and it's waiting for the other to complete. |
| Waiting for slave mutex on exit | Thread is stopping. Only occurs very briefly. |
| Waiting for the next event in relay log | State before reading next event from the [relay log](../relay-log/index). |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slave-sql-thread-states/>

Slave I/O Thread States
=======================

    This article documents thread states that are related to [replication](../replication/index) slave I/O threads. These correspond to the `Slave_IO_State` shown by [SHOW SLAVE STATUS](../show-slave-status/index) and the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| Checking master version | Checking the master's version, which only occurs very briefly after establishing a connection with the master. |
| Connecting to master | Attempting to connect to master. |
| Queueing master event to the relay log | Event is being copied to the [relay log](../relay-log/index) after being read, where it can be processed by the SQL thread. |
| Reconnecting after a failed binlog dump request | Attempting to reconnect to the master after a previously failed binary log dump request. |
| Reconnecting after a failed master event read | Attempting to reconnect to the master after a previously failed request. After successfully connecting, the state will change to `Waiting for master to send event`. |
| Registering slave on master | Registering the slave on the master, which only occurs very briefly after establishing a connection with the master. |
| Requesting binlog dump | Requesting the contents of the binary logs from the given log file name and position. Only occurs very briefly after establishing a connection with the master. |
| Waiting for master to send event | Waiting for [binary log](../binary-log/index) events to arrive after successfully connecting. If there are no new events on the master, this state can persist for as many seconds as specified by the [slave\_net\_timeout](../replication-and-binary-log-server-system-variables/index#slave_net_timeout) system variable, after which the thread will reconnect. |
| Waiting for slave mutex on exit | Waiting for slave mutex while the thread is stopping. Only occurs very briefly. |
| Waiting for the slave SQL thread to free enough relay log space. | [Relay log](../relay-log/index) has reached its maximum size, determined by [relay\_log\_space\_limit](../replication-and-binary-log-server-system-variables/index#relay_log_space_limit) (no limit by default), so waiting for the SQL thread to free up space by processing enough relay log events. |
| Waiting for master update | State before connecting to master. |
| Waiting to reconnect after a failed binlog dump request | Waiting to reconnect after a binary log dump request has failed due to disconnection. The length of time in this state is determined by the `MASTER_CONNECT_RETRY` clause of the [CHANGE MASTER TO](../change-master-to/index) statement. |
| Waiting to reconnect after a failed master event read | Sleeping while waiting to reconnect after a disconnection error. The time in seconds is determined by the `MASTER_CONNECT_RETRY` clause of the [CHANGE MASTER TO](../change-master-to/index) statement. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slave-io-thread-states/>

Delayed Insert Connection Thread States
=======================================

    This article documents thread states that are related to the connection thread that processes [INSERT DELAYED](../insert-delayed/index) statements.

 These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| allocating local table | Preparing to allocate rows to the delayed-insert handler thread. Follows from the `got handler lock` state. |
| Creating delayed handler | Creating a handler for the delayed-inserts. |
| got handler lock | Lock to access the delayed-insert handler thread has been received. Follows from the `waiting for handler lock` state and before the `allocating local table` state. |
| got old table | The initialization phase is over. Follows from the `waiting for handler open` state. |
| storing row into queue | Adding new row to the list of rows to be inserted by the delayed-insert handler thread. |
| waiting for delay\_list | Initializing (trying to find the delayed-insert handler thread). |
| waiting for handler insert | Waiting for new inserts, as all inserts have been processed. |
| waiting for handler lock | Waiting for delayed insert-handler lock to access the delayed-insert handler thread. |
| waiting for handler open | Waiting for the delayed-insert handler thread to initialize. Follows from the `Creating delayed handler` state and before the `got old table` state. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/delayed-insert-connection-thread-states/>

Delayed Insert Handler Thread States
====================================

    This article documents thread states that are related to the handler thread that inserts the results of [INSERT DELAYED](../insert-delayed/index) statements.

 These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| insert | About to insert rows into the table. |
| reschedule | Sleeping in order to let other threads function, after inserting a number of rows into the table. |
| upgrading lock | Attempting to get lock on the table in order to insert rows. |
| Waiting for INSERT | Waiting for the delayed-insert connection thread to add rows to the queue. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/delayed-insert-handler-thread-states/>

Event Scheduler Thread States
=============================

    This article documents thread states that are related to [event](../events/index) scheduling and execution. These include the Event Scheduler thread, threads that terminate the Event Scheduler, and threads for executing events.

 These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index)

 


| Value | Description |
| --- | --- |
| Clearing | Thread is terminating. |
| Initialized | Thread has be initialized. |
| Waiting for next activation | The event queue contains items, but the next activation is at some time in the future. |
| Waiting for scheduler to stop | Waiting for the event scheduler to stop after issuing `SET GLOBAL event_scheduler=OFF`. |
| Waiting on empty queue | Sleeping, as the event scheduler's queue is empty. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/event-scheduler-thread-states/>

General Thread States
=====================

    This article documents the major general thread states. More specific lists related to [delayed inserts](../insert-delayed/index), [replication](../replication/index), the [query cache](../query-cache/index) and the [event scheduler](../events/index) are listed in:

 * [Event Scheduler Thread States](../event-scheduler-thread-states/index)
* [Query Cache Thread States](../query-cache-thread-states/index)
* [Master Thread States](../master-thread-states/index)
* [Slave Connection Thread States](../slave-connection-thread-states/index)
* [Slave I/O Thread States](../slave-io-thread-states/index)
* [Slave SQL Thread States](../slave-sql-thread-states/index)

 These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index)

 


| Value | Description |
| --- | --- |
| After create | The function that created (or tried to create) a table (temporary or non-temporary) has just ended. |
| Analyzing | Calculating table key distributions, such as when running an [ANALYZE TABLE](../analyze-table/index) statement. |
| checking permissions | Checking to see whether the permissions are adequate to perform the statement. |
| Checking table | [Checking](../sql-commands-check-table/index) the table. |
| cleaning up | Preparing to reset state variables and free memory after executing a command. |
| closing tables | Flushing the changes to disk and closing the table. This state will only persist if the disk is full or under extremely high load. |
| converting HEAP to Aria | Converting an internal [MEMORY](../memory-storage-engine/index) temporary table into an on-disk [Aria](../aria/index) temporary table. |
| converting HEAP to MyISAM | Converting an internal [MEMORY](../memory-storage-engine/index) temporary table into an on-disk [MyISAM](../myisam/index) temporary table. |
| copy to tmp table | A new table has been created as part of an [ALTER TABLE](../alter-table/index) statement, and rows are about to be copied into it. |
| Copying to group table | Sorting the rows by group and copying to a temporary table, which occurs when a statement has different [GROUP BY](../select/index#group-by) and [ORDER BY](../select/index#order-by) criteria. |
| Copying to tmp table | Copying to a temporary table in memory. |
| Copying to tmp table on disk | Copying to a temporary table on disk, as the resultset is too large to fit into memory. |
| Creating index | Processing an [ALTER TABLE ... ENABLE KEYS](../alter-table/index) for an [Aria](../aria/index) or [MyISAM](../myisam/index) table. |
| Creating sort index | Processing a [SELECT](../select/index) statement resolved using an internal temporary table. |
| creating table | Creating a table (temporary or non-temporary). |
| Creating tmp table | Creating a temporary table (in memory or on-disk). |
| deleting from main table | Deleting from the first table in a multi-table [delete](../delete/index), saving columns and offsets for use in deleting from the other tables. |
| deleting from reference tables | Deleting matched rows from secondary reference tables as part of a multi-table [delete](../delete/index). |
| discard\_or\_import\_tablespace | Processing an [ALTER TABLE ... IMPORT TABLESPACE](../alter-table/index) or [ALTER TABLE ... DISCARD TABLESPACE](../alter-table/index) statement. |
| end | State before the final cleanup of an [ALTER TABLE](../alter-table/index), [CREATE VIEW](../create-view/index), [DELETE](../delete/index), [INSERT](../insert/index), [SELECT](../select/index), or [UPDATE](../update/index) statement. |
| executing | Executing a statement. |
| Execution of init\_command | Executing statements specified by the `--init_command` [mariadb client](../mariadb-command-line-client/index) option. |
| filling schema table | A table in the `[information\_schema](../information-schema/index)` database is being built. |
| freeing items | Freeing items from the [query cache](../query-cache/index) after executing a command. Usually followed by the `cleaning up` state. |
| Flushing tables | Executing a [FLUSH TABLES](../flush/index) statement and waiting for other threads to close their tables. |
| FULLTEXT initialization | Preparing to run a [full-text](../full-text-indexes/index) search |
| init | About to initialize an [ALTER TABLE](../alter-table/index), [DELETE](../delete/index), [INSERT](../insert/index), [SELECT](../select/index), or [UPDATE](../update/index) statement. Could be performaing [query cache](../query-cache/index) cleanup, or flushing the [binary log](../binary-log/index) or InnoDB log. |
| Killed | Thread will abort next time it checks the kill flag. Requires waiting for any locks to be released. |
| Locked | Query has been locked by another query. |
| logging slow query | Writing statement to the [slow query log](../slow-query-log/index). |
| NULL | State used for [SHOW PROCESSLIST](../show-processlist/index). |
| login | Connection thread has not yet been authenticated. |
| manage keys | Enabling or disabling a table index. |
| Opening table[s] | Trying to open a table. Usually very quick unless the limit set by [table\_open\_cache](../server-system-variables/index#table_open_cache) has been reached, or an [ALTER TABLE](../alter-table/index) or [LOCK TABLE](../lock-tables-and-unlock-tables/index) is in progress. |
| optimizing | Server is performing initial optimizations in for a query. |
| preparing | State occurring during query optimization. |
| Purging old relay logs | Relay logs that are no longer needed are being removed. |
| query end | Query has finished being processed, but items have not yet been freed (the `freeing items` state. |
| Reading file | Server is reading the file (for example during [LOAD DATA INFILE](../load-data-infile/index)). |
| Reading from net | Server is reading a network packet. |
| Removing duplicates | Duplicated rows being removed before sending to the client. This happens when `SELECT DISTINCT` is used in a way that the distinct operation could not be optimized at an earlier point. |
| removing tmp table | Removing an internal temporary table after processing a [SELECT](../select/index) statement. |
| rename | Renaming a table. |
| rename result table | Renaming a table that results from an [ALTER TABLE](../alter-table/index) statement having created a new table. |
| Reopen tables | Table is being re-opened after thread obtained a lock but the underlying table structure had changed, so the lock was released. |
| Repair by sorting | Indexes are being created with the use of a sort. Much faster than the related `Repair with keycache`. |
| Repair done | Multi-threaded repair has been completed. |
| Repair with keycache | Indexes are being created through the key cache, one-by-one. Much slower than the related `Repair by sorting`. |
| Rolling back | A transaction is being rolled back. |
| Saving state | New table state is being saved. For example, after, analyzing a [MyISAM](../myisam/index) table, the key distributions, rowcount etc. are saved to the .MYI file. |
| Searching rows for update | Finding matching rows before performing an [UPDATE](../update/index), which is needed when the UPDATE would change the index used for the UPDATE |
| Sending data | Sending data to the client as part of processing a [SELECT](../select/index) statement. Often the longest-occurring state due to the relatively slow disk accesses that may be required. |
| setup | Setting up an [ALTER TABLE](../alter-table/index) operation. |
| Sorting for group | Sorting as part of a [GROUP BY](../select/index#group-by) |
| Sorting for order | Sorting as part of an [ORDER BY](../select/index#order-by) |
| Sorting index | Sorting index pages as part of a table optimization operation. |
| Sorting result | Processing a [SELECT](../select/index) statement using a non-temporary table. |
| statistics | Calculating statistics as part of deciding on a query execution plan. Usually a brief state unless the server is disk-bound. |
| System lock | Requesting or waiting for an *external* lock for a specific table. The [storage engine](../storage-engines/index) determines what kind of *external* lock to use. For example, the [MyISAM](../myisam-storage-engine/index) storage engine uses file-based locks. However, MyISAM's *external* locks are disabled by default, due to the default value of the `[skip\_external\_locking](../server-system-variables/index#skip_external_locking)` system variable. Transactional storage engines such as [InnoDB](../innodb/index) also register the transaction or statement with MariaDB's [transaction coordinator](../transaction-coordinator-log/index) while in this thread state. See [MDEV-19391](https://jira.mariadb.org/browse/MDEV-19391) for more information about that. |
| Table lock | About to request a table's *internal* lock after acquiring the table's *external* lock. This thread state occurs after the *System lock* thread state. |
| update | About to start updating table. |
| Updating | Searching for and updating rows in a table. |
| updating main table | Updating the first table in a multi-table update, and saving columns and offsets for use in the other tables. |
| updating reference tables | Updating the secondary (reference) tables in a multi-table update |
| updating status | This state occurs after a query's execution is complete. If the query's execution time exceeds `[long\_query\_time](../server-system-variables/index#long_query_time)`, then `[Slow\_queries](../server-status-variables/index#slow_queries)` is incremented, and if the [slow query log](../slow-query-log/index) is enabled, then the query is logged. If the `[SERVER\_AUDIT](../mariadb-audit-plugin/index)` plugin is enabled, then the query is also logged into the audit log at this stage. If the `[userstats](../user-statistics/index)` plugin is enabled, then CPU statistics are also updated at this stage. |
| User lock | About to request or waiting for an advisory lock from a [GET LOCK()](../get_lock/index) call. For [SHOW PROFILE](../show-profile/index), means requesting a lock only. |
| User sleep | A [SLEEP()](../sleep/index) call has been invoked. |
| Waiting for commit lock | [FLUSH TABLES WITH READ LOCK](../flush/index) is waiting for a commit lock, or a statement resulting in an explicit or implicit commit is waiting for a read lock to be released. This state was called `Waiting for all running commits to finish`  in earlier versions. |
| Waiting for global read lock | Waiting for a global read lock. |
| Waiting for table level lock | External lock acquired,and internal lock about to be requested. Occurs after the `System lock` state. In earlier versions, this was called `Table lock`. |
| Waiting for *xx* lock | Waiting to obtain a lock of type `xx`. |
| Waiting on cond | Waiting for an unspecified condition to occur. |
| Writing to net | Writing a packet to the network. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/general-thread-states/>

Master Thread States
====================

    This article documents thread states that are related to [replication](../replication/index) master threads. These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| Finished reading one binlog; switching to next binlog | After completing one [binary log](../binary-log/index), the next is being opened for sending to the slave. |
| Master has sent all binlog to slave; waiting for binlog to be updated | All events have been read from the binary logs and sent to the slave. Now waiting for the binary log to be updated with new events. |
| Sending binlog event to slave | An event has been read from the [binary log](../binary-log/index), and is now being sent to the slave. |
| Waiting to finalize termination | State that only occurs very briefly while the thread is terminating. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/master-thread-states/>

InnoDB Data Dictionary Troubleshooting
======================================

    Can't Open File
---------------

 If InnoDB returns something like the following error:

 
```
ERROR 1016: Can't open file: 'x.ibd'. (errno: 1)

```

it may be that an orphan `.frm` file exists. Something like the following may also appear in the [error log](../error-log/index):

 
```
InnoDB: Cannot find table test/x from the internal data dictionary
InnoDB: of InnoDB though the .frm file for the table exists. Maybe you
InnoDB: have deleted and recreated InnoDB data files but have forgotten
InnoDB: to delete the corresponding .frm files of InnoDB tables?

```

If this is the case, as the text describes, delete the orphan `.frm` file on the filesystem.

 Removing Orphan Intermediate Tables
-----------------------------------

 An orphan intermediate table may prevent you from dropping the tablespace even if it is otherwise empty, and generally takes up unnecessary space.

 It may come about if MariaDB exits in the middle of an [ALTER TABLE ... ALGORITHM=INPLACE](../alter-table/index#algorithm) operation. They will be listed in the [INFORMATION\_SCHEMA.INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index) table, and always start with an `#sql-ib` prefix. The accompanying `.frm` file also begins with `#sql-`, but has a different name.

 To identify orphan tables, run:

 
```
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';

```

When [innodb\_file\_per\_table](../xtradbinnodb-server-system-variables/index#innodb_file_per_table) is set, the `#sql-*.ibd` file will also be visible in the database directory.

 To remove an orphan intermediate table:

 * Rename the `#sql-*.frm` file (in the database directory) to match the base name of the orphan intermediate table, for example:

 
```
mv #sql-36ab_2.frm #sql-ib87-856498050.frm

```

* Drop the table, for example:

 
```
DROP TABLE `#mysql50##sql-ib87-856498050`;

```

See Also
--------

 * [InnoDB Troubleshooting Overview](../innodb-troubleshooting-overview/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-data-dictionary-troubleshooting/>

Slave Connection Thread States
==============================

    This article documents thread states that are related to connection threads that occur on a [replication](../replication/index) slave. These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| Changing master | Processing a [CHANGE MASTER TO](../change-master-to/index) statement. |
| Killing slave | Processing a [STOP SLAVE](../stop-slave/index) statement. |
| Opening master dump table | A table has been created from a master dump and is now being opened. |
| Reading master dump table data | After the table created by a master dump (the `Opening master dump table` state) the table is now being read. |
| Rebuilding the index on master dump table | After the table created by a master dump has been opened and read (the `Reading master dump table data` state), the index is built. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/slave-connection-thread-states/>

Deploying Docker Containers with Ansible
========================================

    Ansible can be used to manage Docker container upgrades and configuration changes. Docker has native ways to do this, namely [Dockerfiles](../creating-a-custom-docker-image/index) and [Docker Compose](../setting-up-a-lamp-stack-with-docker-compose/index). But sometimes there are reasons to start basic containers from an image and then manage configuration with Ansible or similar software. See [Benefits of Managing Docker Containers with Automation Software](../benefits-of-managing-docker-containers-with-orchestration-software/index).

 In this page we'll discuss how to use Ansible to manage Docker containers.

 How to Deploy a Container with Ansible
--------------------------------------

 Ansible has modules to manage the Docker server, Docker containers, and Docker Compose. These modules are maintained by the community.

 A dynamic inventory plugin for Docker exists. It retrieves the list of existing containers from Docker.

 Docker modules and the Docker inventory plugin communicate with Docker using its API. The connection to the API can use a TSL connection and supports key authenticity verification.

 To communicate with Docker API, Ansible needs a proper Python module installed on the Ansible node (`docker` or `docker-py`).

 Several roles exist to deploy Docker and configure it. They can be found in Ansible Galaxy.

 References
----------

 Further information can be found in Ansible documentation.

 * [Docker Guide](https://docs.ansible.com/ansible/latest/scenario_guides/guide_docker.html).
* [docker\_container](https://docs.ansible.com/ansible/latest/collections/community/general/docker_container_module.html) module.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/deploying-docker-containers-with-ansible/>

Query Cache Thread States
=========================

    This article documents thread states that are related to the [Query Cache](../query-cache/index). These correspond to the `STATE` values listed by the [SHOW PROCESSLIST](../show-processlist/index) statement or in the [Information Schema PROCESSLIST Table](../information-schema-processlist-table/index) as well as the `PROCESSLIST_STATE` value listed in the [Performance Schema threads Table](../performance-schema-threads-table/index). 

 


| Value | Description |
| --- | --- |
| checking privileges on cached query | Checking whether the user has permission to access a result in the query cache. |
| checking query cache for query | Checking whether the current query exists in the query cache. |
| invalidating query cache entries | Marking query cache entries as invalid as the underlying tables have changed. |
| sending cached result to client | A result found in the query cache is being sent to the client. |
| storing result in query cache | Saving the the result of a query into the query cache. |
| Waiting for query cache lock | Waiting to take a query cache lock. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/query-cache-thread-states/>

Information Schema INNODB\_SYS\_TABLES Table
============================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_TABLES` table contains information about InnoDB tables.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| TABLE\_ID | bigint(21) unsigned | NO |  | 0 | Unique InnoDB table identifier. |
| NAME | varchar(655) | NO |  |  | Database and table name, or the uppercase InnoDB system table name. |
| FLAG | int(11) | NO |  | 0 | See [Flag](#flag) below |
| N\_COLS | int(11) unsigned (>= [MariaDB 10.5](../what-is-mariadb-105/index)) int(11) (<= [MariaDB 10.4](../what-is-mariadb-104/index)) | NO |  | 0 | Number of columns in the table. The count includes two or three hidden InnoDB system columns, appended to the end of the column list: DB\_ROW\_ID (if there is no primary key or unique index on NOT NULL columns), DB\_TRX\_ID, DB\_ROLL\_PTR. |
| SPACE | int(11) unsigned (>= [MariaDB 10.5](../what-is-mariadb-105/index)) int(11) (<= [MariaDB 10.4](../what-is-mariadb-104/index)) | NO |  | 0 | Tablespace identifier where the index resides. `0` represents the InnoDB system tablespace, while any other value represents a table created in file-per-table mode (see the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable). Remains unchanged after a [TRUNCATE TABLE](../truncate-table/index) statement. |
| FILE\_FORMAT | varchar(10) | YES |  | NULL | [InnoDB file format](../innodb-file-format/index) (Antelope or Barracuda). Removed in [MariaDB 10.3](../what-is-mariadb-103/index). |
| ROW\_FORMAT | enum('Redundant', 'Compact', 'Compressed', 'Dynamic') (>= [MariaDB 10.5](../what-is-mariadb-105/index))varchar(12) (<= [MariaDB 10.4](../what-is-mariadb-104/index)) | YES |  | NULL | [InnoDB storage format](../innodb-storage-formats/index) (Compact, Redundant, Dynamic, or Compressed). |
| ZIP\_PAGE\_SIZE | int(11) unsigned | NO |  | 0 | For Compressed tables, the zipped page size. |
| SPACE\_TYPE | enum('Single','System') (>= [MariaDB 10.5](../what-is-mariadb-105/index))varchar(10) (<= [MariaDB 10.4](../what-is-mariadb-104/index)) | YES |  | NULL |  |

 
Flag
----

 The flag field returns the dict\_table\_t::flags that correspond to the data dictionary record.

 


| Bit | Description |
| --- | --- |
| `0` | Set if ROW\_FORMAT is not REDUNDANT. |
| `1` to `4` | `0`, except for ROW\_FORMAT=COMPRESSED, where they will determine the KEY\_BLOCK\_SIZE (the compressed page size). |
| `5` | Set for ROW\_FORMAT=DYNAMIC or ROW\_FORMAT=COMPRESSED. |
| `6` | Set if the DATA DIRECTORY attribute was present when the table was originally created. |
| `7` | Set if the page\_compressed attribute is present. |
| `8` to `11` | Determine the page\_compression\_level. |
| `12` `13` | Normally `00`, but `11` for "no-rollback tables" ([MariaDB 10.3](../what-is-mariadb-103/index) CREATE SEQUENCE). In [MariaDB 10.1](../what-is-mariadb-101/index), these bits could be `01` or `10` for ATOMIC\_WRITES=ON or ATOMIC\_WRITES=OFF. |

 
Note that the table flags returned here are not the same as tablespace flags (FSP\_SPACE\_FLAGS). 

 Example
-------

 
```
SELECT * FROM information_schema.INNODB_SYS_TABLES LIMIT 2\G
*************************** 1. row ***************************
     TABLE_ID: 14
         NAME: SYS_DATAFILES
         FLAG: 0
       N_COLS: 5
        SPACE: 0
   ROW_FORMAT: Redundant
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: System
*************************** 2. row ***************************
     TABLE_ID: 11
         NAME: SYS_FOREIGN
         FLAG: 0
       N_COLS: 7
        SPACE: 0
   ROW_FORMAT: Redundant
ZIP_PAGE_SIZE: 0
   SPACE_TYPE: System
2 rows in set (0.00 sec)

```

See Also
--------

 * [InnoDB Data Dictionary Troubleshooting](../innodb-data-dictionary-troubleshooting/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_tables-table/>

Ansible Overview for MariaDB Users
==================================

    Ansible is a tool to automate servers configuration management. It is produced by Red Hat and it is open source software released under the terms of the GNU GPL.

 It is entirely possible to use Ansible to automate MariaDB deployments and configuration. This page contains generic information for MariaDB users who want to learn, or evaluate, Ansible.

 For information about how to install Ansible, see [Installing Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) in Ansible documentation.

 Automation Hubs
---------------

 Normally, Ansible can run from any computer that has access to the target hosts to be automated. It is not uncommon that all members of a team has Ansible installed on their own laptop, and use it to deploy.

 Red Hat offers a commercial version of Ansible called [Ansible Tower](https://docs.ansible.com/ansible/latest/reference_appendices/tower.html). It consists of a REST API and a web-based interface that work as a hub that handles all normal Ansible operations.

 An alternative is [AWX](https://github.com/ansible/awx). AWX is the open source upstream project from which many Ansible Tower features are originally developed. AWX is released under the terms of the Apache License 2.0. However, Red Hat does not recommend to run AWX in production.

 AWX development is fast. It has several features that may or may not end up in Ansible Tower. Ansible Tower is more focused on making AWS features more robust, providing a stable tool to automate production environments.

 Design Principles
-----------------

 Ansible allows us to write **playbooks** that describe how our servers should be configured. Playbooks are lists of **tasks**.

 Tasks are usually **declarative**. You don't explain *how* to do something, you declare *what* should be done.

 Playbooks are **idempotent**. When you apply a playbook, tasks are only run if necessary.

 Here is a task example:

 
```
- name: Install Perl
  package:
    name: perl
    state: present

```

"Install Perl" is just a description that will appear on screen when the task is applied. Then we use the `package` module to declare that a package called "perl" should be installed. When we apply the playbook, if Perl is already installed nothing happens. Otherwise, Ansible installs it.

 When we apply a playbook, the last information that appears on the screen is a recap like the following:

 
```
PLAY RECAP ***************************************************************************************************
mariadb-01        : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

```

This means that six tasks were already applied (so no action was taken), and two tasks were applied.

 As the above example shows, Ansible playbooks are written in YAML.

 Modules (like `package`) can be written in any language, as long as they are able to process a JSON input and produce a JSON output. However the Ansible community prefers to write them in Python, which is the language Ansible is written in.

 Concepts
--------

 A piece of Ansible code that can be applied to a server is called a **playbook**.

 A **task** is the smallest brick of code in a playbook. The name is a bit misleading, though, because an Ansible task should not be seen as "something to do". Instead, it is a minimal description of a component of a server. In the example above, we can see a task.

 A task uses a single **module**, which is an interface that Ansible uses to interact with a specific system component. In the example, the module is "package".

 A task also has attributes, that describe what should be done with that module, and how. In the example above, "name" and "state" are both attributes. The `state` attribute exists for every module, by convention (though there may be exceptions). Typically, it has at least the "present" and "absent" state, to indicate if an object should exist or not.

 Other important code concepts are:

 * An **inventory** determines which **hosts** Ansible should be able to deploy. Each host may belong to one or more **groups**. Groups may have **children**, forming a hierarchy. This is useful because it allows us to deploy on a group, or to assign variables to a group.
* A **role** describes the state that a host, or group of hosts, should reach after a deploy.
* A **play** associates hosts or groups to their roles. Each role/group can have more than one role.
* A role is a playbook that describes how certain servers should be configured, based on the logical role they have in the infrastructure. Servers can have multiple roles, for example the same server could have both the "mariadb" and the "mydumper" role, meaning that they run MariaDB and they have mydumper installed (as shown later).
* Tasks can use **variables**. They can affect how a task is executed (for example a variable could be a file name), or even whether a task is executed or not. Variables exist at role, group or host level. Variables can also be passed by the user when a play is applied.
* **Facts** are data that Ansible retrieves from remote hosts before deploying. This is a very important step, because facts may determine which tasks are executed or how they are executed. Facts include, for example, the operating system family or its version. A playbook sees facts as pre-set variables.
* **Modules** implement **actions** that tasks can use. Action examples are **file** (to declare that files and directories must exist) or **mysql\_variables** (to declare MySQL/MariaDB variables that need to be set).

 #### Example

 Let's describe a hypothetical infrastructure to find out how these concepts can apply to MariaDB.

 The **inventory** could define the following groups:

 * "db-main" for the cluster used by our website. All nodes belong to this group.
* "db-analytics" for our replicas used by data analysts.
* "dump" for one or more servers that take dumps from the replicas.
* "proxysql" for one or more hosts that run ProxySQL.

 Then we'll need the following nodes:

 * "mariadb-node" for the nodes in "db-main". This role describes how to setup nodes of a cluster using Galera.
* "mariadb-replica" for the members of "db-analytics". It describes a running replica, and it includes the tasks that are necessary to provision the node if the data directory is empty when the playbook is applied. The hostname of the primary server is defined in a variable.
* "mariadb". The aforementioned "mariadb-node" and "mariadb-replica" can be children of this group. They have many things in common (filesystem for the data directory, some basic MariaDB configuration, some installed tools...), so it could make sense to avoid duplication and describe the common traits in a super-role.
* A "mariabackup" role to take backups with [Mariabackup](../mariabackup/index), running jobs during the night. We can associate this role to the "db-main" group, or we could create a child group for servers that will take the backups.
* "mariadb-dump" for the server that takes dumps with [mariadb-dump](../mysqldump/index). Note that we may decide to take dumps on a replica, so the same host may belong to "db-analytics" and "mariadb-dump".
* "proxysql" for the namesake group.

 Architecture
------------

 Ansible architecture is extremely simple. Ansible can run on any host. To apply playbooks, it connects to the target hosts and runs system commands. By default the connection happens via ssh, though it is possible to develop connection plugins to use different methods. Applying playbooks locally without establishing a connection is also possible.

 Modules can be written in any language, though Python is the most common choice in the Ansible community. Modules receive JSON "requests" and facts from Ansible core, they are supposed to run useful commands on a target host, and then they should return information in JSON. Their output informs Ansible whether something has changed on the remote server and if the operations succeeded.

 Ansible is not centralized. It can run on any host, and it is common for a team to run it from several laptops. However, to simplify things and improve security, it may be desirable to run it from a dedicated host. Users will connect to that host, and apply Ansible playbooks.

 Ansible Resources and References
--------------------------------

 * [Ansible.com](https://www.ansible.com/)
* [AWX](https://github.com/ansible/awx)
* [Ansible Tower](https://docs.ansible.com/ansible/latest/reference_appendices/tower.html)
* [Ansible Galaxy](https://galaxy.ansible.com/)
* [Ansible on Wikipedia](https://en.wikipedia.org/wiki/Ansible_(software))
* [Ansible Automation Platform](https://www.youtube.com/c/AnsibleAutomation/videos) YouTube channel
* [Ansible: Getting Started](https://www.ansible.com/resources/get-started)
* [MariaDB Deployment and Management with Ansible](https://youtu.be/CV8-56Fgjc0) (video)

 Further information about the concepts discussed in this page can be found in Ansible documentation:

 * [Basic Concepts](https://docs.ansible.com/ansible/latest/network/getting_started/basic_concepts.html).
* [Glossary](https://docs.ansible.com/ansible/latest/reference_appendices/glossary.html).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ansible-overview-for-mariadb-users/>

Deploying to Remote Servers with Ansible
========================================

    If we manage several remote servers, running commands on them manually can be frustrating and time consuming. Ansible allows one to run commands on a whole group of servers.

 This page shows some examples of ansible-playbook invocations. We'll see how to deploy roles or parts of them to remote servers. Then we'll see how to run commands on remote hosts, and possibly to get information from them. Make sure to read [Ansible Overview](../ansible-overview/index) first, to understand Ansible general concepts.

 Pinging Remote Servers
----------------------

 Let's start with the simplest example: we just want our local Ansible to ping remote servers to see if they are reachable. Here's how to do it:

 
```
ansible -i production-mariadb all -m ping

```

Before proceeding with more useful examples, let's discuss this syntax.

 * **ansible** is the executable we can call to run a command from remote servers.
* **-i production-mariadb** means that the servers must be read from an inventory called production-mariadb.
* **all** means that the command must be executed against all servers from the above inventory.
* **-m ping** specifies that we want to run the ping module. This is not the ping Linux command. It tells us if Ansible is able to connect a remote server and run a simple commands on them.

 To run ping on a specific group or host, we can just replace "all" with a group name or host name from the inventory:

 
```
ansible -i production-mariadb main_cluster -m ping

```

Running Commands on Remote Servers
----------------------------------

 The previous examples show how to run an Ansible module on remote servers. But it's also possible to run custom commands over SSH. Here's how:

 
```
ansible -i production-mariadb all -a 'echo $PATH'

```

This command shows the value of `$PATH` on all servers in the inventory "production-mariadb".

 We can also run commands as root by adding the `-b` (or `--become`) option:

 
```
# print a MariaDB variable
ansible -i production-mariadb all -b -a 'mysql -e "SHOW GLOBAL VARIABLES LIKE \'innodb_buffer_pool_size\';"'

# reboot servers
ansible -i production-mariadb all -b -a 'reboot'

```

Applying Roles to Remote Servers
--------------------------------

 We saw how to run commands on remote hosts. Applying roles to remote hosts is not much harder, we just need to add some information. An example:

 
```
ansible-playbook -i production-mariadb production-mariadb.yml

```

Let's see what changed:

 * **ansible-playbook** is the executable file that we need to call to apply playbooks and roles.
* **production-mariadb.yml** is the play that associates the servers listed in the inventory to their roles.

 If we call ansible-playbook with no additional arguments, we will apply all applicable roles to all the servers mentioned in the play.

 To only apply roles to certain servers, we can use the `-l` parameter to specify a group, an individual host, or a pattern:

 
```
# Apply to the mariadb-main role role
ansible-playbook -i production-mariadb -l mariadb-main production-mariadb.yml

# Apply to the mariadb-main-01 host
ansible-playbook -i production-mariadb -l mariadb-main-01 production-mariadb.yml

# Apply to multiple hosts whose name starts with "mariadb-main-"
ansible-playbook -i production-mariadb -l mariadb-main-* production-mariadb.yml

```

We can also apply tasks from roles selectively. Tasks may optionally have tags, and each tag corresponds to an operation that we may want to run on our remote hosts. For example, a "mariadb" role could have the "timezone-update" tag, to update the contents of the [timezone tables](../time-zones/index#mysql-time-zone-tables). To only apply the tasks with the "timezone-update" tag, we can use this command:

 
```
ansible-playbook -i production-mariadb --tag timezone-update production-mariadb.yml

```

Using tags is especially useful for database servers. While most of the technologies typically managed by Ansible are stateless (web servers, load balancers, etc.) database servers are not. We must pay special attention not to run tasks that could cause a database server outage, for example destroying its data directory or restarting the service when it is not necessary.

 ### Check mode

 We should always test our playbooks and roles on test servers before applying them to production. However, if test servers and production servers are not exactly in the same state (which means, some facts may differ) it is still possible that applying roles will fail. If it fails in the initial stage, Ansible will not touch the remote hosts at all. But there are cases where Ansible could successfully apply some tasks, and fail to apply another task. After the first failure, ansible-playbook will show errors and exit. But this could leave a host in an inconsistent state.

 Ansible has a *check mode* that is meant to greatly reduce the chances of a failure. When run in check mode, ansible-playbook will read the inventory, the play and roles; it will figure out which tasks need to be applied; then it will connect to target hosts, read facts, and value all the relevant variables. If all these steps succeed, it is unlikely that running ansible-playbook without check mode will fail.

 To run ansible-playbook in check mode, just add the `--check` (or `-C`) parameter.

 References
----------

 Further documentation can be found in the Ansible website:

 * [ansible](https://docs.ansible.com/ansible/latest/cli/ansible.html) tool.
* [ansible-playbook](https://docs.ansible.com/ansible/latest/cli/ansible-playbook.html) tool.
* [Validating tasks: check mode and diff mode](https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/deploying-to-remote-servers-with-ansible/>

Existing Ansible Modules and Roles for MariaDB
==============================================

    This page contains links to Ansible modules and roles that can be used to automate MariaDB deployment and configuration. The list is not meant to be exhaustive. Use it as a starting point, but then please do your own research.

 Modules
-------

 At the time time of writing, there are no MariaDB-specific modules in Ansible Galaxy. MySQL modules can be used. Trying to use MySQL-specific features may result in errors or unexpected behavior. However, the same applies when trying to use a feature not supported by the MySQL version in use.

 Currently, the [MySQL collection](https://galaxy.ansible.com/community/mysql?extIdCarryOver=true&sc_cid=701f2000001OH7YAAW) in Ansible Galaxy contains at least the following modules:

 * **[mysql\_db](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_db_module.html)**: manages MySQL databases.
* **[mysql\_info](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_info_module.html)**: gathers information about a MySQL server.
* **[mysql\_query](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_query_module.html)**: runs SQL queries against MySQL.
* **[mysql\_replication](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_replication_module.html)**: configures and operates asynchronous replication.
* **[mysql\_user](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_user_module.html)**: creates, modifies and deletes MySQL users.
* **[mysql\_variables](https://docs.ansible.com/ansible/latest/collections/community/mysql/mysql_variables_module.html)**: manages MySQL configuration.

 Note that some modules only exist as shortcuts, and it is possible to use mysql\_query instead. However, it is important to notice that mysql\_query is not idempotent. Ansible does not understand MySQL queries, therefore it cannot check whether a query needs to be run or not.

 To install this collection locally:

 
```
ansible-galaxy collection install community.mysql

```

MariaDB Corporation maintains a [ColumnStore playbook](https://github.com/mariadb-corporation/columnstore-ansible) on GitHub.

 ### Other Useful Modules

 Let's see some other modules that are useful to manage MariaDB servers.

 #### shell and command

 Modules like [shell](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html#ansible-collections-ansible-builtin-command-module) and [command](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/command_module.html#ansible-collections-ansible-builtin-command-module) allow one to run system commands.

 To deploy on Windows, [win\_shell](https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_shell_module.html#ansible-collections-ansible-windows-win-shell-module) and [win\_command](https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_command_module.html#ansible-collections-ansible-windows-win-command-module) can be used.

 Among other things, it is possible to use one of these modules to run MariaDB queries:

 
```
- name: Make the server read-only
  # become root to log into MariaDB with UNIX_SOCKET plugin
  become: yes
  shell: $( which mysql ) -e "SET GLOBAL read_only = 1;"

```

The main disadvantage with these modules is that they are not idempotent, because they're meant to run arbitrary system commands that Ansible can't understand. They are still useful in a variety of cases:

 * To run queries, because mysql\_query is also not idempotent.
* In cases when other modules do not allow us to use the exact arguments we need to use, we can achieve our goals by writing shell commands ourselves.
* To run custom scripts that implement non-trivial logic. Implementing complex logic in Ansible tasks is possible, but it can be tricky and inefficient.
* To call [command-line tools](../clients-utilities/index). There may be specific roles for some of the most common tools, but most of the times using them is an unnecessary complication.

 #### copy and template

 An important part of configuration management is copying [configuration files](../configuring-mariadb-with-option-files/index) to remote servers.

 The [copy module](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html) allows us to copy files to target hosts. This is convenient for static files that we want to copy exactly as they are. An example task:

 
```
- name: Copy my.cnf
  copy:
    src: ./files/my.cnf.1
    dest: /etc/mysql/my.cnf

```

As you can see, the local name and the name on remote host don't need to match. This is convenient, because it makes it easy to use different configuration files with different servers. By default, files to copy are located in a `files` subdirectory in the role.

 However, typically the content of a configuration file should vary based on the target host, the group and various variables. To do this, we can use the [template](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html) module, which compiles and copies templates written in [Jinja](https://jinja.palletsprojects.com/en/2.11.x/).

 A simple template task:

 
```
- name: Compile and copy my.cnf
  copy:
    src: ./templates/my.cnf.j2
    dest: /etc/mysql/my.cnf

```

Again, the local and the remote names don't have to match. By default, Jinja templates are located in a `templates` subdirectory in the role, and by convention they have the `.j2` extension. This is because Ansible uses Jinja version 2 for templating, at the time writing.

 A simple template example:

 
```
## WARNING: DO NOT EDIT THIS FILE MANUALLY !!
## IF YOU DO, THIS FILE WILL BE OVERWRITTEN BY ANSIBLE

[mysqld]
innodb_buffer_pool_size = {{ innodb_buffer_pool_size }}

{% if use_connect sameas true %}
connect_work_size = {{ connect_work_size }}
{% endif %}

```

#### Other Common Modules

 The following modules are also often used for database servers:

 * [package](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html), [apt](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html) or [yum](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/yum_module.html). Package is package manager-agnostic. Use them to install, uninstall and upgrade packages.
* [user](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/user_module.html), useful to create the system user and group that run MariaDB binary.
* [file](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html) can be used to make sure that MariaDB directories (like the data directory) exist and have proper permissions. It can also be used to upload static files.
* [template](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html) allows to create configuration files (like my.cnf) more dynamically, using the [Jinja](https://jinja.palletsprojects.com/en/3.0.x/) template language.
* [service](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/service_module.html) is useful after installing MariaDB as a service, to start it, restart it or stop it.

 Roles
-----

 Specific roles exist for MariaDB in Ansible Galaxy. Using them for MariaDB is generally preferable, to be sure to avoid [incompatibilities](../mariadb-vs-mysql-compatibility/index) and to probably be able to use some MariaDB specific [features](../mariadb-vs-mysql-features/index). However, using MySQL or Percona Server roles is also possible. This probably makes sense for users who also administer MySQL and Percona Server instances.

 To find roles that suits you, check [Ansible Galaxy search page](https://galaxy.ansible.com/search?deprecated=false&keywords=&order_by=-relevance). Most roles are also available on GitHub.

 You can also search roles using the [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) tool:

 
```
ansible-galaxy search mariadb

```

See Also
--------

 * [MariaDB Deployment and Management with Ansible](https://youtu.be/CV8-56Fgjc0) (video)

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/existing-ansible-modules-and-roles-for-mariadb/>

Running mariadb-tzinfo-to-sql with Ansible
==========================================

    For documentation about the `mariadb-tzinfo-to-sql` utility, see [mysql\_tzinfo\_to\_sql](../mysql_tzinfo_to_sql/index). This page is about running it using Ansible.

 Installing or Upgrading the Package
-----------------------------------

 First, we should install `mariadb-tzinfo-to-sql` if it is available on our system. For example, to install it on Ubuntu, we can use this task. For other systems, use the proper module and package name.

 
```
- name: Update timezone info
  tags: [ timezone-update ]
  apt:
    name: tzdata
    state: latest
    install_recommends: no
  register: timezone_info

```

This task installs the latest version of the `tzdata`, unless it is already installed and up to date. We register the `timezone_info` variables, so we can only run the next task if the package was installed or updated.

 We also specify a `timezone-update` tag, so we can apply the role to only update the timezone tables.

 Running the Script
------------------

 The next task runs `mariadb-tzinfo-to-sql`.

 
```
- name: Move system timezone info into MariaDB
  tags: [ timezone-update ]
  shell: >
    mysql_tzinfo_to_sql /usr/share/zoneinfo \
      | grep -v "^Warning" \
      | mysql --database=mysql
  when: timezone_info.changed

```

We use the `shell` module to run the command. Running a command in this way is not idempotent, so we specify `when: timezone_info.changed` to only run it when necessary. Some warnings may be generated, so we pipe the output of `mysql_tzinfo_to_sql` to `grep` to filter warnings out.

 Using Galera
------------

 If we're using [MariaDB Galera Cluster](../galera-cluster/index) we'll want to only update the timezone tables in one node, because the other nodes will replicate the changes. For our convenience, we can run this operation on the first node. If the nodes hostnames are defined in a list called `cluster_hosts`, we can check if the current node is the first in this way:

 
```
  when: timezone_info.changed and inventory_hostname == cluster_hosts[0].hostname

```



---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-mariadb-tzinfo-to-sql-with-ansible/>

Managing Secrets in Ansible
===========================

    An Ansible role often runs commands that require certain privileges, so it must perform some forms of login, using passwords or key pairs. In the context of database automation, we normally talk about: SSH access, sudo access, and access to MariaDB. If we write these secrets (passwords or private keys) in clear text in an Ansible repository, anyone who has access to the repository can access them, and this is not what we want.

 Let's see how we can manage secrets.

 The SSH Password or Keys
------------------------

 Most of the times, Ansible connects to the target hosts via SSH. It is common to use the system username and the SSH keys installed in `/.ssh`, which is the SSH clients default. In this case, nothing has to be done on the clients to be able to allow Ansible to use SSH, as long as they are already able to connect to the target hosts.

 It is also possible to specify a different username as `[ANSIBLE\_REMOTE\_USER](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_REMOTE_USER)` and an SSH configuration file as `[ANSIBLE\_NETCONF\_SSH\_CONFIG](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_NETCONF_SSH_CONFIG)`. These settings can be specified in Ansible configuration file or as environment variables.

 `[ANSIBLE\_ASK\_PASS](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_ASK_PASS)` can be specified. If this is the case, Ansible will prompt the user asking to type an SSH password.

 Avoiding Sharing Secrets
------------------------

 As a general rule, any configuration that implies communicating sensible information to the persons who will connects to a system implies some degree of risk. Therefore, the most common choice is to allow users to login into remote systems with their local usernames, using SSH keys.

 Once Ansible is able to connect remote hosts, it can also be used to install the public keys of some users to grant them access. Sharing these keys implies no risk. Sharing private keys is never necessary, and must be avoided.

 MariaDB has a [UNIX\_SOCKET](../authentication-plugin-unix-socket/index) plugin that can be used to let some users avoid entering a password, as far as they're logged in the operating system. This authentication method is used by default for the root user. This is a good way to avoid having one more password and possibly writing to a `.my.cnf` file so that the user doesn't have to type it.

 Even for users who connect remotely, it is normally not necessary to insert passwords in an Ansible file. When we create a user with a password, a hash of the original password is stored in MariaDB. That hash can be found in the [mysql.user table](../mysqluser-table/index). To know the hash of a password without even creating a user, we can use the [PASSWORD()](../password/index) function:

 
```
SELECT PASSWORD('my_password12') AS hash;

```

When we create a user, we can actually specify a hash instead of the password the user will have to type:

 
```
CREATE USER user@host IDENTIFIED BY PASSWORD '*54958E764CE10E50764C2EECBB71D01F08549980';

```

ansible-vault
-------------

 Even if you try to avoid sharing secrets, it's likely you'll have to keep some in Ansible. For example, MariaDB users that connect remotely have passwords, and if we want Ansible to create and manage those users, the hashes must be placed somewhere in our Ansible repository. While a hash cannot be converted back to a password, treating hashes as secrets is usually a good idea. Ansible provides a native way to handle secrets: [ansible-vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html).

 In the simplest case, we can manage all our passwords with a single ansible-vault password. When we add or change a new password in some file (typically a file in `host_vars` or `group_vars`) we'll use ansible-vault to crypt this password. While doing so, we'll be asked to insert our ansible-vault password. When we apply a role and Ansible needs to decrypt this password, it will ask us to enter again our ansible-vault password.

 ansible-vault can use more than one password. Each password can manage a different set of secrets. So, for example, some users may have the password to manage regular MariaDB users passwords, and only one may have the password that is needed to manage the root user.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/managing-secrets-in-ansible/>

InnoDB Troubleshooting Overview
===============================

    As with most errors, first take a look at the contents of the [MariaDB error log](../error-log/index). If dealing with a deadlock, setting the [innodb\_print\_all\_deadlocks](../xtradbinnodb-server-system-variables/index#innodb_print_all_deadlocks) option (off by default) will output details of all deadlocks to the error log.

 It can also help to enable the various [InnoDB Monitors](../xtradb-innodb-monitors/index) relating to the problem you are experiencing. There are four types: the standard InnoDB monitor, the InnoDB Lock Monitor, InnoDB Tablespace Monitor and the InnoDB Table Monitor.

 Running [CHECK TABLE](../check-table/index) will help determine whether there are errors in the table.

 For problems with the InnoDB Data Dictionary, see [InnoDB Data Dictionary Troubleshooting](../innodb-data-dictionary-troubleshooting/index).

 See Also
--------

 * [InnoDB Data Dictionary Troubleshooting](../innodb-data-dictionary-troubleshooting/index)
* [InnoDB Recovery Modes](../xtradbinnodb-recovery-modes/index)
* [Error Codes](../error-codes/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-troubleshooting-overview/>

Using InnoDB Instead of XtraDB
==============================

    By default [MariaDB 10.1](../what-is-mariadb-101/index) and earlier releases come compiled with [XtraDB](../about-xtradb/index) as the default InnoDB replacement. From [MariaDB 10.2](../what-is-mariadb-102/index), InnoDB is the default.

 
**MariaDB starting with [5.5](../what-is-mariadb-55/index)**Starting from [MariaDB 5.5](../what-is-mariadb-55/index), all standard MariaDB distributions also includes InnoDB as a plugin.

 To use the InnoDB plugin instead of XtraDB you can add to your [my.cnf](../mysqld-startup-options/index) file:

 
```
[mysqld]
ignore_builtin_innodb
plugin_load=ha_innodb.so
# The following should not be needed if you are using a mariadb package:
plugin_dir=/usr/local/mysql/lib/mysql/plugin

```



**MariaDB until [5.3](../what-is-mariadb-53/index)**For [MariaDB 5.3](../what-is-mariadb-53/index) and below, the name of the library is `ha_innodb_plugin.so`

 
The reasons you may want to use InnoDB instead of XtraDB are:

 * You want to benchmark the difference between InnoDB/XtraDB
* You hit a bug in XtraDB
* You got a table space crash in XtraDB and recovery doesn't work. In some cases InnoDB may do a better job to recover data.

 See Also
--------

 * [Compiling with the InnoDB plugin from Oracle](../compiling-with-the-innodb-plugin-from-oracle/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-innodb-instead-of-xtradb/>

Information Schema INNODB\_BUFFER\_PAGE Table
=============================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_PAGE` table contains information about pages in the [buffer pool](../xtradbinnodb-memory-buffer/index).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `POOL_ID` | Buffer Pool identifier. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) returns a value of 0, since multiple InnoDB buffer pool instances has been removed. |
| `BLOCK_ID` | Buffer Pool Block identifier. |
| `SPACE` | Tablespace identifier. Matches the `SPACE` value in the `[INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index)` table. |
| `PAGE_NUMBER` | Buffer pool page number. |
| `PAGE_TYPE` | Page type; one of `allocated` (newly-allocated page), `index` (B-tree node), `undo_log` (undo log page), `inode` (index node), `ibuf_free_list` (insert buffer free list), `ibuf_bitmap` (insert buffer bitmap), `system` (system page), `trx_system` (transaction system data), `file_space_header` (file space header), `extent_descriptor` (extent descriptor page), `blob` (uncompressed blob page), `compressed_blob` (first compressed blob page), `compressed_blob2` (subsequent compressed blob page) or `unknown`. |
| `FLUSH_TYPE` | Flush type. |
| `FIX_COUNT` | Count of the threads using this block in the buffer pool. When it is zero, the block can be evicted from the buffer pool. |
| `IS_HASHED` | Whether or not a hash index has been built on this page. |
| `NEWEST_MODIFICATION` | Most recent modification's Log Sequence Number. |
| `OLDEST_MODIFICATION` | Oldest modification's Log Sequence Number. |
| `ACCESS_TIME` | Abstract number representing the time the page was first accessed. |
| `TABLE_NAME` | Table that the page belongs to. |
| `INDEX_NAME` | Index that the page belongs to, either a clustered index or a secondary index. |
| `NUMBER_RECORDS` | Number of records the page contains. |
| `DATA_SIZE` | Size in bytes of all the records contained in the page. |
| `COMPRESSED_SIZE` | Compressed size in bytes of the page, or `NULL` for pages that aren't compressed. |
| `PAGE_STATE` | Page state; one of `FILE_PAGE` (page from a file) or `MEMORY` (page from an in-memory object) for valid data, or one of `NULL`, `READY_FOR_USE`, `NOT_USED`, `REMOVE_HASH`. |
| `IO_FIX` | Whether there is I/O pending for the page; one of `IO_NONE` (no pending I/O), `IO_READ` (read pending), `IO_WRITE` (write pending). |
| `IS_OLD` | Whether the page is old or not. |
| `FREE_PAGE_CLOCK` | Freed\_page\_clock counter, which tracks the number of blocks removed from the end of the least recently used (LRU) list, at the time the block was last placed at the head of the list. |

 
The related [INFORMATION\_SCHEMA.INNODB\_BUFFER\_PAGE\_LRU](../information-schema-innodb_buffer_page_lru-table/index) table contains the same information, but with an LRU (least recently used) position rather than block id.

 Examples
--------

 
```
DESC information_schema.innodb_buffer_page;
+---------------------+---------------------+------+-----+---------+-------+
| Field               | Type                | Null | Key | Default | Extra |
+---------------------+---------------------+------+-----+---------+-------+
| POOL_ID             | bigint(21) unsigned | NO   |     | 0       |       |
| BLOCK_ID            | bigint(21) unsigned | NO   |     | 0       |       |
| SPACE               | bigint(21) unsigned | NO   |     | 0       |       |
| PAGE_NUMBER         | bigint(21) unsigned | NO   |     | 0       |       |
| PAGE_TYPE           | varchar(64)         | YES  |     | NULL    |       |
| FLUSH_TYPE          | bigint(21) unsigned | NO   |     | 0       |       |
| FIX_COUNT           | bigint(21) unsigned | NO   |     | 0       |       |
| IS_HASHED           | varchar(3)          | YES  |     | NULL    |       |
| NEWEST_MODIFICATION | bigint(21) unsigned | NO   |     | 0       |       |
| OLDEST_MODIFICATION | bigint(21) unsigned | NO   |     | 0       |       |
| ACCESS_TIME         | bigint(21) unsigned | NO   |     | 0       |       |
| TABLE_NAME          | varchar(1024)       | YES  |     | NULL    |       |
| INDEX_NAME          | varchar(1024)       | YES  |     | NULL    |       |
| NUMBER_RECORDS      | bigint(21) unsigned | NO   |     | 0       |       |
| DATA_SIZE           | bigint(21) unsigned | NO   |     | 0       |       |
| COMPRESSED_SIZE     | bigint(21) unsigned | NO   |     | 0       |       |
| PAGE_STATE          | varchar(64)         | YES  |     | NULL    |       |
| IO_FIX              | varchar(64)         | YES  |     | NULL    |       |
| IS_OLD              | varchar(3)          | YES  |     | NULL    |       |
| FREE_PAGE_CLOCK     | bigint(21) unsigned | NO   |     | 0       |       |
+---------------------+---------------------+------+-----+---------+-------+

```


```
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE\G
...
*************************** 6. row ***************************
            POOL_ID: 0
           BLOCK_ID: 5
              SPACE: 0
        PAGE_NUMBER: 11
          PAGE_TYPE: INDEX
         FLUSH_TYPE: 1
          FIX_COUNT: 0
          IS_HASHED: NO
NEWEST_MODIFICATION: 2046835
OLDEST_MODIFICATION: 0
        ACCESS_TIME: 2585566280
         TABLE_NAME: `SYS_INDEXES`
         INDEX_NAME: CLUST_IND
     NUMBER_RECORDS: 57
          DATA_SIZE: 4016
    COMPRESSED_SIZE: 0
         PAGE_STATE: FILE_PAGE
             IO_FIX: IO_NONE
             IS_OLD: NO
    FREE_PAGE_CLOCK: 0
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_page-table/>

Information Schema INNODB\_BUFFER\_PAGE\_LRU Table
==================================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_PAGE_LRU` table contains information about pages in the [buffer pool](../xtradbinnodb-memory-buffer/index) and how they are ordered for eviction purposes.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `POOL_ID` | Buffer Pool identifier. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) returns a value of 0, since multiple InnoDB buffer pool instances has been removed. |
| `LRU_POSITION` | LRU (Least recently-used), for determining eviction order from the buffer pool. |
| `SPACE` | Tablespace identifier. Matches the `SPACE` value on the `[INNODB\_SYS\_TABLES](../information-schema-innodb_sys_tables-table/index)` table. |
| `PAGE_NUMBER` | Buffer pool page number. |
| `PAGE_TYPE` | Page type; one of `allocated` (newly-allocated page), `index` (B-tree node), `undo_log` (undo log page), `inode` (index node), `ibuf_free_list` (insert buffer free list), `ibuf_bitmap` (insert buffer bitmap), `system` (system page), `trx_system` (transaction system data), `file_space_header` (file space header), `extent_descriptor` (extent descriptor page), `blob` (uncompressed blob page), `compressed_blob` (first compressed blob page), `compressed_blob2` (subsequent compressed blob page) or `unknown`. |
| `FLUSH_TYPE` | Flush type. |
| `FIX_COUNT` | Count of the threads using this block in the buffer pool. When it is zero, the block can be evicted from the buffer pool. |
| `IS_HASHED` | Whether or not a hash index has been built on this page. |
| `NEWEST_MODIFICATION` | Most recent modification's Log Sequence Number. |
| `OLDEST_MODIFICATION` | Oldest modification's Log Sequence Number. |
| `ACCESS_TIME` | Abstract number representing the time the page was first accessed. |
| `TABLE_NAME` | Table that the page belongs to. |
| `INDEX_NAME` | Index that the page belongs to, either a clustered index or a secondary index. |
| `NUMBER_RECORDS` | Number of records the page contains. |
| `DATA_SIZE` | Size in bytes of all the records contained in the page. |
| `COMPRESSED_SIZE` | Compressed size in bytes of the page, or `NULL` for pages that aren't compressed. |
| `PAGE_STATE` | Page state; one of `FILE_PAGE` (page from a file) or `MEMORY` (page from an in-memory object) for valid data, or one of `NULL`, `READY_FOR_USE`, `NOT_USED`, `REMOVE_HASH`. |
| `IO_FIX` | Whether there is I/O pending for the page; one of `IO_NONE` (no pending I/O), `IO_READ` (read pending), `IO_WRITE` (write pending). |
| `IS_OLD` | Whether the page is old or not. |
| `FREE_PAGE_CLOCK` | Freed\_page\_clock counter, which tracks the number of blocks removed from the end of the LRU list, at the time the block was last placed at the head of the list. |

 
The related [INFORMATION\_SCHEMA.INNODB\_BUFFER\_PAGE](../information-schema-innodb_buffer_page/index) table contains the same information, but with a block id rather than LRU position.

 Example
-------

 
```
DESC information_schema.innodb_buffer_page_lru;
+---------------------+---------------------+------+-----+---------+-------+
| Field               | Type                | Null | Key | Default | Extra |
+---------------------+---------------------+------+-----+---------+-------+
| POOL_ID             | bigint(21) unsigned | NO   |     | 0       |       |
| LRU_POSITION        | bigint(21) unsigned | NO   |     | 0       |       |
| SPACE               | bigint(21) unsigned | NO   |     | 0       |       |
| PAGE_NUMBER         | bigint(21) unsigned | NO   |     | 0       |       |
| PAGE_TYPE           | varchar(64)         | YES  |     | NULL    |       |
| FLUSH_TYPE          | bigint(21) unsigned | NO   |     | 0       |       |
| FIX_COUNT           | bigint(21) unsigned | NO   |     | 0       |       |
| IS_HASHED           | varchar(3)          | YES  |     | NULL    |       |
| NEWEST_MODIFICATION | bigint(21) unsigned | NO   |     | 0       |       |
| OLDEST_MODIFICATION | bigint(21) unsigned | NO   |     | 0       |       |
| ACCESS_TIME         | bigint(21) unsigned | NO   |     | 0       |       |
| TABLE_NAME          | varchar(1024)       | YES  |     | NULL    |       |
| INDEX_NAME          | varchar(1024)       | YES  |     | NULL    |       |
| NUMBER_RECORDS      | bigint(21) unsigned | NO   |     | 0       |       |
| DATA_SIZE           | bigint(21) unsigned | NO   |     | 0       |       |
| COMPRESSED_SIZE     | bigint(21) unsigned | NO   |     | 0       |       |
| COMPRESSED          | varchar(3)          | YES  |     | NULL    |       |
| IO_FIX              | varchar(64)         | YES  |     | NULL    |       |
| IS_OLD              | varchar(3)          | YES  |     | NULL    |       |
| FREE_PAGE_CLOCK     | bigint(21) unsigned | NO   |     | 0       |       |
+---------------------+---------------------+------+-----+---------+-------+

```


```
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU\G
...
*************************** 6. row ***************************
            POOL_ID: 0
       LRU_POSITION: 5
              SPACE: 0
        PAGE_NUMBER: 11
          PAGE_TYPE: INDEX
         FLUSH_TYPE: 1
          FIX_COUNT: 0
          IS_HASHED: NO
NEWEST_MODIFICATION: 2046835
OLDEST_MODIFICATION: 0
        ACCESS_TIME: 2585566280
         TABLE_NAME: `SYS_INDEXES`
         INDEX_NAME: CLUST_IND
     NUMBER_RECORDS: 57
          DATA_SIZE: 4016
    COMPRESSED_SIZE: 0
         COMPRESSED: NO
             IO_FIX: IO_NONE
             IS_OLD: NO
    FREE_PAGE_CLOCK: 0
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_page_lru-table/>

Information Schema INNODB\_BUFFER\_POOL\_PAGES Table
====================================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_POOL_PAGES` table is a Percona enhancement, and is only available for XtraDB, not InnoDB (see [XtraDB and InnoDB](../xtradb-and-innodb/index)). It contains a record for each page in the [buffer pool](../xtradbinnodb-memory-buffer/index).

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `PAGE_TYPE` | Type of page; one of `index`, `undo_log`, `inode`, `ibuf_free_list`, `allocated, bitmap`, `sys`, `trx_sys`, `fsp_hdr`, `xdes`, `blob`, `zblob`, `zblob2` and `unknown`. |
| `SPACE_ID` | Tablespace ID. |
| `PAGE_NO` | Page offset within tablespace. |
| `LRU_POSITION` | Page position in the LRU (least-recently-used) list. |
| `FIX_COUNT` | Page reference count, incremented each time the page is accessed. `0` if the page is not currently being accessed. |
| `FLUSH_TYPE` | Flush type of the most recent flush.`0` (LRU), `2` (flush\_list) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_pool_pages-table/>

Information Schema INNODB\_BUFFER\_POOL\_PAGES\_BLOB Table
==========================================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_POOL_PAGES_BLOB` table is a Percona enchancement, and is only available for XtraDB, not InnoDB (see [XtraDB and InnoDB](../xtradb-and-innodb/index)). It contains information about [buffer pool](../xtradbinnodb-memory-buffer/index) blob pages.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `SPACE_ID` | Tablespace ID. |
| `PAGE_NO` | Page offset within tablespace. |
| `COMPRESSED` | `1` if the blob contains compressed data, `0` if not. |
| `PART_LEN` | Page data length. |
| `NEXT_PAGE_NO` | Next page number. |
| `LRU_POSITION` | Page position in the LRU (least-recently-used) list. |
| `FIX_COUNT` | Page reference count, incremented each time the page is accessed. `0` if the page is not currently being accessed. |
| `FLUSH_TYPE` | Flush type of the most recent flush.`0` (LRU), `2` (flush\_list) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_pool_pages_blob-table/>

Information Schema INNODB\_BUFFER\_POOL\_PAGES\_INDEX Table
===========================================================

    The [Information Schema](../information_schema/index) `INNODB_BUFFER_POOL_PAGES` table is a Percona enhancement, and is only available for XtraDB, not InnoDB (see [XtraDB and InnoDB](../xtradb-and-innodb/index)). It contains information about [buffer pool](../xtradbinnodb-memory-buffer/index) index pages.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `INDEX_ID` | Index name |
| `SPACE_ID` | Tablespace ID |
| `PAGE_NO` | Page offset within tablespace. |
| `N_RECS` | Number of user records on the page. |
| `DATA_SIZE` | Total data size in bytes of records in the page. |
| `HASHED` | `1` if the block is in the adaptive hash index, `0` if not. |
| `ACCESS_TIME` | Page's last access time. |
| `MODIFIED` | `1` if the page has been modified since being loaded, `0` if not. |
| `DIRTY` | `1` if the page has been modified since it was last flushed, `0` if not |
| `OLD` | `1` if the page in the in the *old* blocks of the LRU (least-recently-used) list, `0` if not. |
| `LRU_POSITION` | Position in the LRU (least-recently-used) list. |
| `FIX_COUNT` | Page reference count, incremented each time the page is accessed. `0` if the page is not currently being accessed. |
| `FLUSH_TYPE` | Flush type of the most recent flush.`0` (LRU), `2` (flush\_list) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_buffer_pool_pages_index-table/>

Information Schema INNODB\_CMP and INNODB\_CMP\_RESET Tables
============================================================

    The `INNODB_CMP` and `INNODB_CMP_RESET` tables contain status information on compression operations related to [compressed XtraDB/InnoDB tables](../innodb-storage-formats/index#compressed).

 The `[PROCESS](../grant/index#global-privileges)` privilege is required to query this table.

 These tables contain the following columns:

 


| Column Name | Description |
| --- | --- |
| `PAGE_SIZE` | Compressed page size, in bytes. This value is unique in the table; other values are totals which refer to pages of this size. |
| `COMPRESS_OPS` | How many times a page of the size `PAGE_SIZE` has been compressed. This happens when a new page is created because the compression log runs out of space. This value includes both successful operations and *compression failures*. |
| `COMPRESS_OPS_OK` | How many times a page of the size `PAGE_SIZE` has been successfully compressed. This value should be as close as possible to `COMPRESS_OPS`. If it is notably lower, either avoid compressing some tables, or increase the `KEY_BLOCK_SIZE` for some compressed tables. |
| `COMPRESS_TIME` | Time (in seconds) spent to compress pages of the size `PAGE_SIZE`. This value includes time spent in *compression failures*. |
| `UNCOMPRESS_OPS` | How many times a page of the size `PAGE_SIZE` has been uncompressed. This happens when an uncompressed version of a page is created in the buffer pool, or when a *compression failure* occurs. |
| `UNCOMPRESS_TIME` | Time (in seconds) spent to uncompress pages of the size `PAGE_SIZE`. |

 
These tables can be used to measure the effectiveness of XtraDB/InnoDB table compression. When you have to decide a value for `KEY_BLOCK_SIZE`, you can create more than one version of the table (one for each candidate value) and run a realistic workload on them. Then, these tables can be used to see how the operations performed with different page sizes.

 `INNODB_CMP` and `INNODB_CMP_RESET` have the same columns and always contain the same values, but when `INNODB_CMP_RESET` is queried, both the tables are cleared. `INNODB_CMP_RESET` can be used, for example, if a script periodically logs the performances of compression in the last period of time. `INNODB_CMP` can be used to see the cumulated statistics.

 Examples
--------

 
```
SELECT * FROM information_schema.INNODB_CMP\G
**************************** 1. row *****************************
      page_size: 1024
   compress_ops: 0
compress_ops_ok: 0
  compress_time: 0
 uncompress_ops: 0
uncompress_time: 0
...

```

See Also
--------

 Other tables that can be used to monitor XtraDB/InnoDB compressed tables:

 * [INNODB\_CMP\_PER\_INDEX and INNODB\_CMP\_PER\_INDEX\_RESET](../information_schemainnodb_cmp_per_index-and-innodb_cmp_per_index_reset-table/index)
* [INNODB\_CMPMEM and INNODB\_CMPMEM\_RESET](../information_schemainnodb_cmpmem-and-innodb_cmpmem_reset-tables/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_cmp-and-innodb_cmp_reset-tables/>

Information Schema INNODB\_CMPMEM and INNODB\_CMPMEM\_RESET Tables
==================================================================

    The `INNODB_CMPMEM` and `INNODB_CMPMEM_RESET` tables contain status information on compressed pages in the [buffer pool](../innodb-buffer-pool/index) (see InnoDB [COMPRESSED](../innodb-storage-formats/index#compressed) format).

 The [PROCESS](../grant/index#global-privileges) privilege is required to query this table.

 These tables contain the following columns:

 


| Column Name | Description |
| --- | --- |
| `PAGE_SIZE` | Compressed page size, in bytes. This value is unique in the table; other values are totals which refer to pages of this size. |
| `BUFFER_POOL_INSTANCE` | Buffer Pool identifier. From [MariaDB 10.5.1](https://mariadb.com/kb/en/mariadb-1051-release-notes/) returns a value of 0, since multiple InnoDB buffer pool instances has been removed. |
| `PAGES_USED` | Number of pages of the size `PAGE_SIZE` which are currently in the buffer pool. |
| `PAGES_FREE` | Number of pages of the size `PAGE_SIZE` which are currently free, and thus are available for allocation. This value represents the buffer pool's fragmentation. A totally unfragmented buffer pool has at most 1 free page. |
| `RELOCATION_OPS` | How many times a page of the size `PAGE_SIZE` has been relocated. This happens when data exceeds a page (because a row must be copied into a new page) and when two pages are merged (because their data shrunk and can now be contained in one page). |
| `RELOCATION_TIME` | Time (in seconds) spent in relocation operations for pages of the size `PAGE_SIZE`. This column is reset when the `INNODB_CMPMEM_RESET` table is queried. |

 
These tables can be used to measure the effectiveness of InnoDB table compression. When you have to decide a value for `KEY_BLOCK_SIZE`, you can create more than one version of the table (one for each candidate value) and run a realistic workload on them. Then, these tables can be used to see how the operations performed with different page sizes.

 `INNODB_CMPMEM` and `INNODB_CMPMEM_RESET` have the same columns and always contain the same values, but when `INNODB_CMPMEM_RESET` is queried, the `RELOCATION_TIME` column from both the tables are cleared. `INNODB_CMPMEM_RESET` can be used, for example, if a script periodically logs the performances of compression in the last period of time. `INNODB_CMPMEM` can be used to see the cumulated statistics.

 Example
-------

 
```
SELECT * FROM information_schema.INNODB_CMPMEM\G
********************** 1. row **********************
            page_size: 1024
 buffer_pool_instance: 0
           pages_used: 0
           pages_free: 0
      reloacation_ops: 0
      relocation_time: 0

```

See Also
--------

 Other tables that can be used to monitor InnoDB compressed tables:

 * [INNODB\_CMP and INNODB\_CMP\_RESET](../information_schemainnodb_cmp-and-innodb_cmp_reset-tables/index)
* [INNODB\_CMP\_PER\_INDEX and INNODB\_CMP\_PER\_INDEX\_RESET](../information_schemainnodb_cmp_per_index-and-innodb_cmp_per_index_reset-table/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_cmpmem-and-innodb_cmpmem_reset-tables/>

Information Schema INNODB\_FT\_CONFIG Table
===========================================

    The [Information Schema](../information_schema/index) `INNODB_FT_CONFIG` table contains InnoDB [fulltext index](../full-text-indexes/index) metadata.

 The `SUPER` [privilege](../grant/index) is required to view the table, and it also requires the [innodb\_ft\_aux\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_aux_table) system variable to be set.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `KEY` | Metadata item name. |
| `VALUE` | Associated value. |

 
Example
-------

 
```
SELECT * FROM INNODB_FT_CONFIG;
+---------------------------+-------+
| KEY                       | VALUE |
+---------------------------+-------+
| optimize_checkpoint_limit | 180   |
| synced_doc_id             | 6     |
| last_optimized_word       |       |
| deleted_doc_count         | 0     |
| total_word_count          |       |
| optimize_start_time       |       |
| optimize_end_time         |       |
| stopword_table_name       |       |
| use_stopword              | 1     |
| table_state               | 0     |
+---------------------------+-------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_ft_config-table/>

Information Schema INNODB\_SYS\_FIELDS Table
============================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_FIELDS` table contains information about fields that are part of an InnoDB index.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `INDEX_ID` | Index identifier, matching the value from [INNODB\_SYS\_INDEXES.INDEX\_ID](../information-schema-innodb_sys_indexes-table/index). |
| `NAME` | Field name, matching the value from [INNODB\_SYS\_COLUMNS.NAME](../information-schema-innodb_sys_columns-table/index). |
| `POS` | Ordinal position of the field within the index, starting from `0`. This is adjusted as columns are removed. |

 
Example
-------

 
```
SELECT * FROM information_schema.INNODB_SYS_FIELDS LIMIT 3\G
*************************** 1. row ***************************
INDEX_ID: 11
    NAME: ID
     POS: 0
*************************** 2. row ***************************
INDEX_ID: 12
    NAME: FOR_NAME 
     POS: 0
*************************** 3. row ***************************
INDEX_ID: 13
    NAME: REF_NAME 
     POS: 0
3 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_fields-table/>

Information Schema INNODB\_SYS\_TABLESTATS Table
================================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_TABLESTATS` table contains InnoDB status information. It can be used for developing new performance-related extensions, or high-level performance monitoring. 

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 Note that the MySQL InnoDB and Percona XtraDB versions of the tables differ (see [XtraDB and InnoDB](../xtradb-and-innodb/index)).

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_ID` | Table ID, matching the [INNODB\_SYS\_TABLES.TABLE\_ID](../information-schema-innodb_sys_tables-table/index) value. |
| `SCHEMA` | Database name (XtraDB only). |
| `NAME` | Table name, matching the [INNODB\_SYS\_TABLES.NAME](../information-schema-innodb_sys_tables-table/index) value. |
| `STATS_INITIALIZED` | `Initialized` if statistics have already been collected, otherwise `Uninitialized`. |
| `NUM_ROWS` | Estimated number of rows currently in the table. Updated after each statement modifying the data, but uncommited transactions mean it may not be accurate. |
| `CLUST_INDEX_SIZE` | Number of pages on disk storing the clustered index, holding InnoDB table data in primary key order, or `NULL` if not statistics yet collected. |
| `OTHER_INDEX_SIZE` | Number of pages on disk storing secondary indexes for the table, or `NULL` if not statistics yet collected. |
| `MODIFIED_COUNTER` | Number of rows modified by statements modifying data. |
| `AUTOINC` | [Auto\_increment](../auto_increment/index) value. |
| `REF_COUNT` | Countdown to zero, when table metadata can be removed from the table cache. (InnoDB only) |
| `MYSQL_HANDLES_OPENED` | (XtraDB only). |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_tablestats-table/>

Information Schema INNODB\_SYS\_DATAFILES Table
===============================================

    
**MariaDB until [10.5](../what-is-mariadb-105/index)**The `INNODB_SYS_DATAFILES` table was added in [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/), and removed in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/).

 
The [Information Schema](../information_schema/index) `INNODB_SYS_DATAFILES` table contains information about InnoDB datafile paths. It was intended to provide metadata for tablespaces inside InnoDB tables, which was never implemented in MariaDB and was removed in [MariaDB 10.6](../what-is-mariadb-106/index). The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `SPACE` | Numeric tablespace. Matches the [INNODB\_SYS\_TABLES.SPACE](../information-schema-innodb_sys_tables-table/index) value. |
| `PATH` | Tablespace datafile path. |

 
Example
-------

 
```
SELECT * FROM INNODB_SYS_DATAFILES;
+-------+--------------------------------+
| SPACE | PATH                           |
+-------+--------------------------------+
|    19 | ./test/t2.ibd                  |
|    20 | ./test/t3.ibd                  |
...
|    68 | ./test/animals.ibd             |
|    69 | ./test/animal_count.ibd        |
|    70 | ./test/t.ibd                   |
+-------+--------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_datafiles-table/>

Information Schema INNODB\_SYS\_SEMAPHORE\_WAITS Table
======================================================

    The [Information Schema](../information_schema/index) INNODB\_SYS\_SEMAPHORE\_WAITS table is meant to contain information about current semaphore waits. At present it is not correctly populated. See [MDEV-21330](https://jira.mariadb.org/browse/MDEV-21330).

 The [PROCESS privilege](../grant/index#process) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| THREAD\_ID | Thread id waiting for semaphore |
| OBJECT\_NAME | Semaphore name |
| FILE | File name where semaphore was requested |
| LINE | Line number on above file |
| WAIT\_TIME | Wait time |
| WAIT\_OBJECT |  |
| WAIT\_TYPE | Object type (mutex, rw-lock) |
| HOLDER\_THREAD\_ID | Holder thread id |
| HOLDER\_FILE | File name where semaphore was acquired |
| HOLDER\_LINE | Line number for above |
| CREATED\_FILE | Creation file name |
| CREATED\_LINE | Line number for above |
| WRITER\_THREAD | Last write request thread id |
| RESERVATION\_MODE | Reservation mode (shared, exclusive) |
| READERS | Number of readers if only shared mode |
| WAITERS\_FLAG | Flags |
| LOCK\_WORD | Lock word (for developers) |
| LAST\_READER\_FILE | Removed |
| LAST\_READER\_LINE | Removed |
| LAST\_WRITER\_FILE | Last writer file name |
| LAST\_WRITER\_LINE | Above line number |
| OS\_WAIT\_COUNT | Wait count |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_semaphore_waits-table/>

Information Schema INNODB\_SYS\_TABLESPACES Table
=================================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_TABLESPACES` table contains information about InnoDB tablespaces. Until [MariaDB 10.5](../what-is-mariadb-105/index) it was based on the internal `SYS_TABLESPACES` table. This internal table was removed in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), so this Information Schema table has been repurposed to directly reflect the filesystem (fil\_system.space\_list).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `SPACE` | Unique InnoDB tablespace identifier. |
| `NAME` | Database and table name separated by a backslash, or the uppercase InnoDB system table name. |
| `FLAG` | `1` if a `DATA DIRECTORY` option has been specified in `[CREATE TABLE](../create-table/index)`, otherwise `0`. |
| `FILE_FORMAT` | [InnoDB file format](../innodb-file-format/index). Removed in [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| `ROW_FORMAT` | [InnoDB storage format](../innodb-storage-formats/index) used for this tablespace. If the [Antelope](../innodb-file-format/index#antelope) file format is used, this value is always `Compact or Redundant`. |
| `PAGE_SIZE` | Page size in bytes for this tablespace. Until [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/), this was the value of the [innodb\_page\_size](../innodb-system-variables/index#innodb_page_size) variable. From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), contains the physical page size of a page (previously `ZIP_PAGE_SIZE`). |
| `ZIP_PAGE_SIZE` | Zip page size for this tablespace. Removed in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). |
| `SPACE_TYPE` | Tablespace type. Can be `General` for general tablespaces or `Single` for file-per-table tablespaces. Introduced [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/). Removed [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). |
| `FS_BLOCK_SIZE` | File system block size. Introduced [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/). |
| `FILE_SIZE` | Maximum size of the file, uncompressed. Introduced [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/). |
| `ALLOCATED_SIZE` | Actual size of the file as per space allocated on disk. Introduced [MariaDB 10.2.1](https://mariadb.com/kb/en/mariadb-1021-release-notes/). |
| `FILENAME` | Tablespace datafile path, previously part of the [INNODB\_SYS\_DATAFILES table](../information-schema-innodb_sys_datafiles-table/index). Added in [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/). |

 
Examples
--------

 [MariaDB 10.4](../what-is-mariadb-104/index):

 
```
DESC information_schema.innodb_sys_tablespaces;
+----------------+---------------------+------+-----+---------+-------+
| Field          | Type                | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+-------+
| SPACE          | int(11) unsigned    | NO   |     | 0       |       |
| NAME           | varchar(655)        | NO   |     |         |       |
| FLAG           | int(11) unsigned    | NO   |     | 0       |       |
| ROW_FORMAT     | varchar(22)         | YES  |     | NULL    |       |
| PAGE_SIZE      | int(11) unsigned    | NO   |     | 0       |       |
| ZIP_PAGE_SIZE  | int(11) unsigned    | NO   |     | 0       |       |
| SPACE_TYPE     | varchar(10)         | YES  |     | NULL    |       |
| FS_BLOCK_SIZE  | int(11) unsigned    | NO   |     | 0       |       |
| FILE_SIZE      | bigint(21) unsigned | NO   |     | 0       |       |
| ALLOCATED_SIZE | bigint(21) unsigned | NO   |     | 0       |       |
+----------------+---------------------+------+-----+---------+-------+

```

From [MariaDB 10.4](../what-is-mariadb-104/index):

 
```
SELECT * FROM information_schema.INNODB_SYS_TABLESPACES LIMIT 2\G
*************************** 1. row ***************************
         SPACE: 2
          NAME: mysql/innodb_table_stats
          FLAG: 33
    ROW_FORMAT: Dynamic
     PAGE_SIZE: 16384
 ZIP_PAGE_SIZE: 0
    SPACE_TYPE: Single
 FS_BLOCK_SIZE: 4096
     FILE_SIZE: 98304
ALLOCATED_SIZE: 98304
*************************** 2. row ***************************
         SPACE: 3
          NAME: mysql/innodb_index_stats
          FLAG: 33
    ROW_FORMAT: Dynamic
     PAGE_SIZE: 16384
 ZIP_PAGE_SIZE: 0
    SPACE_TYPE: Single
 FS_BLOCK_SIZE: 4096
     FILE_SIZE: 98304
ALLOCATED_SIZE: 98304

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_tablespaces-table/>

Information Schema INNODB\_LOCKS Table
======================================

    The [Information Schema](../information_schema/index) `INNODB_LOCKS` table stores information about locks that InnoDB transactions have requested but not yet acquired, or that are blocking another transaction.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `LOCK_ID` | Lock ID number - the format is not fixed, so do not rely upon the number for information. |
| `LOCK_TRX_ID` | Lock's transaction ID. Matches the [INNODB\_TRX.TRX\_ID](../information-schema-innodb_trx-table/index) column. |
| `LOCK_MODE` | [Lock mode](../xtradbinnodb-lock-modes/index). One of `S` (shared), `X` (exclusive), `IS` (intention shared), `IX` (intention exclusive row lock), `S_GAP` (shared gap lock), `X_GAP` (exclusive gap lock), `IS_GAP` (intention shared gap lock), `IX_GAP` (intention exclusive gap lock) or `AUTO_INC` ([auto-increment table level lock](../auto_increment-handling-in-xtradbinnodb/index)). |
| `LOCK_TYPE` | Whether the lock is `RECORD` (row level) or `TABLE` level. |
| `LOCK_TABLE` | Name of the locked table,or table containing locked rows. |
| `LOCK_INDEX` | Index name if a `RECORD` `LOCK_TYPE`, or `NULL` if not. |
| `LOCK_SPACE` | Tablespace ID if a `RECORD` `LOCK_TYPE`, or `NULL` if not. |
| `LOCK_PAGE` | Locked record page number if a `RECORD` `LOCK_TYPE`, or `NULL` if not. |
| `LOCK_REC` | Locked record heap number if a `RECORD` `LOCK_TYPE`, or `NULL` if not. |
| `LOCK_DATA` | Locked record primary key as an SQL string if a `RECORD` `LOCK_TYPE`, or `NULL` if not. If no primary key exists, the internal InnoDB row\_id number is instead used. To avoid unnecessary IO, also `NULL` if the locked record page is not in the [buffer pool](../xtradbinnodb-buffer-pool/index) |

 
The table is often used in conjunction with the [INNODB\_LOCK\_WAITS](../information-schema-innodb_lock_waits-table/index) and [INNODB\_TRX](../information-schema-innodb_trx-table/index) tables to diagnose problematic locks and transactions

 Example
-------

 
```
-- session 1
START TRANSACTION;
UPDATE t SET id = 15 WHERE id = 10;

-- session 2
DELETE FROM t WHERE id = 10;

-- session 1
USE information_schema;
SELECT l.*, t.*
    FROM information_schema.INNODB_LOCKS l
    JOIN information_schema.INNODB_TRX t
        ON l.lock_trx_id = t.trx_id
    WHERE trx_state = 'LOCK WAIT' \G
*************************** 1. row ***************************
                   lock_id: 840:40:3:2
               lock_trx_id: 840
                 lock_mode: X
                 lock_type: RECORD
                lock_table: `test`.`t`
                lock_index: PRIMARY
                lock_space: 40
                 lock_page: 3
                  lock_rec: 2
                 lock_data: 10
                    trx_id: 840
                 trx_state: LOCK WAIT
               trx_started: 2019-12-23 18:43:46
     trx_requested_lock_id: 840:40:3:2
          trx_wait_started: 2019-12-23 18:43:46
                trx_weight: 2
       trx_mysql_thread_id: 46
                 trx_query: DELETE FROM t WHERE id = 10
       trx_operation_state: starting index read
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
          trx_is_read_only: 0
trx_autocommit_non_locking: 0

```

.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_locks-table/>

Information Schema TEMP\_TABLES\_INFO Table
===========================================

    
**MariaDB [10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) - [10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/)**The `TEMP_TABLES_INFO` table was introduced in [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) and was removed in [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/). See [MDEV-12459](https://jira.mariadb.org/browse/MDEV-12459) progress on an alternative.

 
The [Information Schema](../information_schema/index) `TEMP_TABLES_INFO` table contains information about active InnoDB temporary tables. All user and system-created temporary tables are reported when querying this table, with the exception of optimized internal temporary tables. The data is stored in memory.

 Previously, InnoDB temp table metadata was rather stored in InnoDB system tables.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_ID` | Table ID. |
| `NAME` | Table name. |
| `N_COLS` | Number of columns in the temporary table, including three hidden columns that InnoDB creates (`DB_ROW_ID`, `DB_TRX_ID`, and `DB_ROLL_PTR`). |
| `SPACE` | Numerical identifier for the tablespace identifier holding the temporary table. Compressed temporary tables are stored by default in separate per-table tablespaces in the temporary file directory. For non-compressed tables, the shared temporary table is named `ibtmp1`, found in the data directory. Always a non-zero value, and regenerated on server restart. |
| `PER_TABLE_TABLESPACE` | If `TRUE`, the temporary table resides in a separate per-table tablespace. If `FALSE`, it resides in the shared temporary tablespace. |
| `IS_COMPRESSED` | `TRUE` if the table is compressed. |

 
The `PROCESS` [privilege](../grant/index) is required to view the table.

 Examples
--------

 
```
CREATE TEMPORARY TABLE t (i INT) ENGINE=INNODB;

SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO;
+----------+--------------+--------+-------+----------------------+---------------+
| TABLE_ID | NAME         | N_COLS | SPACE | PER_TABLE_TABLESPACE | IS_COMPRESSED |
+----------+--------------+--------+-------+----------------------+---------------+
|       39 | #sql1c93_3_1 |      4 |    64 | FALSE                | FALSE         |
+----------+--------------+--------+-------+----------------------+---------------+

```

Adding a compressed table:

 
```
SET GLOBAL innodb_file_format="Barracuda";

CREATE TEMPORARY TABLE t2 (i INT) ROW_FORMAT=COMPRESSED ENGINE=INNODB;

SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO;
+----------+--------------+--------+-------+----------------------+---------------+
| TABLE_ID | NAME         | N_COLS | SPACE | PER_TABLE_TABLESPACE | IS_COMPRESSED |
+----------+--------------+--------+-------+----------------------+---------------+
|       40 | #sql1c93_3_3 |      4 |    65 | TRUE                 | TRUE          |
|       39 | #sql1c93_3_1 |      4 |    64 | FALSE                | FALSE         |
+----------+--------------+--------+-------+----------------------+---------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-temp_tables_info-table/>

InnoDB Encryption Troubleshooting
=================================

       


 ### Wrong Create Options

 With InnoDB tables using encryption, there are several cases where a [CREATE TABLE](../create-table/index) or [ALTER TABLE](../alter-table/index) statement can throw Error 1005, due to the InnoDB error 140, `Wrong create options`. For instance,   
  


 
```
CREATE TABLE `test`.`table1` ( `id` int(4) primary key , `name` varchar(50));
ERROR 1005 (HY000): Can't create table `test`.`table1` (errno: 140 "Wrong create options")

```

When this occurs, you can usually get more information about the cause of the error by following it with a [SHOW WARNINGS](../show-warnings/index) statement.

 This error is known to occur in the following cases:

 * Encrypting a table by setting the [ENCRYPTED](../create-table/index#encrypted) table option to `YES` when the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) is set to `OFF`.In this case, [SHOW WARNINGS](../show-warnings/index) would return the following:

 
```
SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------+
| Level   | Code | Message                                                             |
+---------+------+---------------------------------------------------------------------+
| Warning |  140 | InnoDB: ENCRYPTED requires innodb_file_per_table                    |
| Error   | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB     |
+---------+------+---------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

* Encrypting a table by setting the [ENCRYPTED](../create-table/index#encrypted) table option to `YES`, and the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable or the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option refers to a non-existent key identifier. In this case, [SHOW WARNINGS](../show-warnings/index) would return the following:

 
```
SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------+
| Level   | Code | Message                                                             |
+---------+------+---------------------------------------------------------------------+
| Warning |  140 | InnoDB: ENCRYPTION_KEY_ID 500 not available                         |
| Error   | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB     |
+---------+------+---------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

* In some versions, this could happen while creating a table with the [ENCRYPTED](../create-table/index#encrypted) table option set to `DEFAULT` while the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable is set to `OFF`, and the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable or the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option are **not** set to `1`. In this case, [SHOW WARNINGS](../show-warnings/index) would return the following:

 
```
SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------+
| Level   | Code | Message                                                             |
+---------+------+---------------------------------------------------------------------+
| Warning |  140 | InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1   |
| Error   | 1005 | Can't create table `db1`.`tab3` (errno: 140 "Wrong create options") |
| Warning | 1030 | Got error 140 "Wrong create options" from storage engine InnoDB     |
+---------+------+---------------------------------------------------------------------+
3 rows in set (0.00 sec)

```

Starting in [MariaDB 10.1.39](https://mariadb.com/kb/en/mariadb-10139-release-notes/), [MariaDB 10.2.23](https://mariadb.com/kb/en/mariadb-10223-release-notes/), and [MariaDB 10.3.14](https://mariadb.com/kb/en/mariadb-10314-release-notes/), creating a table with the [ENCRYPTED](../create-table/index#encrypted) table option set to `DEFAULT` while the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable is set to `OFF`, and the [innodb\_default\_encryption\_key\_id](../innodb-system-variables/index#innodb_default_encryption_key_id) system variable or the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option are **not** set to `1` will no longer fail, and it will no longer throw a warning.

 For more information, see [MDEV-18601](https://jira.mariadb.org/browse/MDEV-18601).

 ### Setting Encryption Key ID For an Unencrypted Table

 If you set the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option for a table that is unencrypted because the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable is set to `OFF` and the [ENCRYPTED](../create-table/index#encrypted) table option set to `DEFAULT`, then this encryption key ID will be saved in the table's `.frm` file, but the encryption key will not be saved to the table's `.ibd` file.

 As a side effect, with the current encryption design, if the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable is later set to `ON`, and InnoDB goes to encrypt the table, then the [InnoDB background encryption threads](../innodb-background-encryption-threads/index) will not read this encryption key ID from the `.frm` file. Instead, the threads may encrypt the table with the encryption key with ID `1`, which is internally considered the default encryption key when no key is specified. For example:

 
```
SET GLOBAL innodb_encrypt_tables=OFF;

CREATE TABLE tab1 (
   id INT PRIMARY KEY,
   str VARCHAR(50)
) ENCRYPTION_KEY_ID=100;

SET GLOBAL innodb_encrypt_tables=ON;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |              1 |
+----------+-------------------+----------------+

```

A similar problem is that, if you set the [ENCRYPTION\_KEY\_ID](../create-table/index#encryption_key_id) table option for a table that is unencrypted because the [ENCRYPTED](../create-table/index#encrypted) table option is set to `NO`, then this encryption key ID will be saved in the table's `.frm` file, but the encryption key will not be saved to the table's `.ibd` file.

 Recent versions of MariaDB will throw warnings in the case where the [ENCRYPTED](../create-table/index#encrypted) table option is set to `NO`, but they will allow the operation to succeed. For example:

 
```
CREATE TABLE tab1 (
   id INT PRIMARY KEY,
   str VARCHAR(50)
) ENCRYPTED=NO ENCRYPTION_KEY_ID=100;
Query OK, 0 rows affected, 1 warning (0.01 sec)

SHOW WARNINGS;
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning |  140 | InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 |
+---------+------+--------------------------------------------------+
1 row in set (0.00 sec)

```

However, in this case, if you change the [ENCRYPTED](../create-table/index#encrypted) table option to `YES` or `DEFAULT` with [ALTER TABLE](../alter-table/index), then it will actually use the proper key. For example:

 
```
SET GLOBAL innodb_encrypt_tables=ON;

ALTER TABLE tab1 ENCRYPTED=DEFAULT;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME = 'db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

```

For more information, see [MDEV-17230](https://jira.mariadb.org/browse/MDEV-17230), [MDEV-18601](https://jira.mariadb.org/browse/MDEV-18601), and [MDEV-19086](https://jira.mariadb.org/browse/MDEV-19086).

 ### Tablespaces Created on MySQL 5.1.47 or Earlier

 MariaDB's data-at-rest encryption implementation re-used previously unused fields in InnoDB's buffer pool pages to identify the encryption key version and the post-encryption checksum. Prior to MySQL 5.1.48, these unused fields were not initialized in memory due to performance concerns. These fields still had zero values most of the time, but since they were not explicitly initialized, that means that these fields could have occasionally had non-zero values that could have been written into InnoDB's tablespace files. If MariaDB were to encounter an unencrypted page from a tablespace file that was created on an early version of MySQL that also had non-zero values in these fields, then it would mistakenly think that the page was encrypted.

 The fix for [MDEV-12112](https://jira.mariadb.org/browse/MDEV-12112) that was included in [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/), [MariaDB 10.2.20](https://mariadb.com/kb/en/mariadb-10220-release-notes/), and [MariaDB 10.3.12](https://mariadb.com/kb/en/mariadb-10312-release-notes/) changed the way that MariaDB distinguishes between encrypted and unencrypted pages, so that it is less likely to mistake an unencrypted page for an encrypted page.

 In [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) and later, if [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) is set to `full_crc32` or `strict_full_crc32`, and if the table does not use [ROW\_FORMAT=COMPRESSED](../innodb-storage-formats/index), then data files will be guaranteed to be zero-initialized.

 For more information, see [MDEV-18097](https://jira.mariadb.org/browse/MDEV-18097).

 ### Spatial Indexes

 [MariaDB 10.4.3](https://mariadb.com/kb/en/mariadb-1043-release-notes/) introduces support for encrypting [spatial indexes](../spatial-index/index). To enable, set the [innodb\_checksum\_algorithm](../innodb-system-variables/index#innodb_checksum_algorithm) to `full_crc32` or to `strict_full_crc32`. Note that MariaDB only encrypts spatial indexes when the [ROW\_FORMAT](../create-table/index#row_format) table option is **not** set to [COMPRESSED](../innodb-storage-formats/index#compressed).

 In older versions of MariaDB, spatial index encryption is unsupported. Tables that contain spatial indexes store them unencrypted. 

 For more information, see [MDEV-12026](https://jira.mariadb.org/browse/MDEV-12026).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-encryption-troubleshooting/>

Information Schema INNODB\_SYS\_INDEXES Table
=============================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_INDEXES` table contains information about InnoDB indexes.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Field | Type | Null | Key | Default | Description |
| --- | --- | --- | --- | --- | --- |
| INDEX\_ID | bigint(21) unsigned | NO |  | 0 | A unique index identifier. |
| NAME | varchar(64) | NO |  |  | Index name, lowercase for all user-created indexes, or uppercase for implicitly-created indexes; `PRIMARY` (primary key), `GEN_CLUST_INDEX` (index representing primary key where there isn't one), `ID_IND`, `FOR_IND` (validating foreign key constraint) , `REF_IND`. |
| TABLE\_ID | bigint(21) unsigned | NO |  | 0 | Table identifier, matching the value from [INNODB\_SYS\_TABLES.TABLE\_ID](../information-schema-innodb_sys_tables-table/index). |
| TYPE | int(11) | NO |  | 0 | Numeric type identifier; one of `0` (secondary index), `1` (clustered index), `2` (unique index), `3` (primary index), `32` ([full-text index](../full-text-indexes/index)). |
| N\_FIELDS | int(11) | NO |  | 0 | Number of columns in the index. GEN\_CLUST\_INDEX's have a value of 0 as the index is not based on an actual column in the table. |
| PAGE\_NO | int(11) | NO |  | 0 | Index B-tree's root page number. `-1` (unused) for full-text indexes, as they are laid out over several auxiliary tables. |
| SPACE | int(11) | NO |  | 0 | Tablespace identifier where the index resides. `0` represents the InnoDB system tablespace, while any other value represents a table created in file-per-table mode (see the [innodb\_file\_per\_table](../innodb-system-variables/index#innodb_file_per_table) system variable). Remains unchanged after a [TRUNCATE TABLE](../truncate-table/index) statement, and not necessarily unique. |
| MERGE\_THRESHOLD | int(11) | NO |  | 0 |  |

 
Example
-------

 
```
SELECT * FROM information_schema.INNODB_SYS_INDEXES LIMIT 3\G
*************************** 1. row ***************************
       INDEX_ID: 11
           NAME: ID_IND
       TABLE_ID: 11
           TYPE: 3
       N_FIELDS: 1
        PAGE_NO: 302
          SPACE: 0
MERGE_THRESHOLD: 50
*************************** 2. row ***************************
       INDEX_ID: 12
           NAME: FOR_IND
       TABLE_ID: 11
           TYPE: 0
       N_FIELDS: 1
        PAGE_NO: 303
          SPACE: 0
MERGE_THRESHOLD: 50
*************************** 3. row ***************************
       INDEX_ID: 13
           NAME: REF_IND
       TABLE_ID: 11
           TYPE: 3
       N_FIELDS: 1
        PAGE_NO: 304
          SPACE: 0
MERGE_THRESHOLD: 50
3 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_indexes-table/>

Information Schema INNODB\_SYS\_VIRTUAL Table
=============================================

    
**MariaDB starting with [10.2](../what-is-mariadb-102/index)**The `INNODB_SYS_VIRTUAL` table was added in [MariaDB 10.2](../what-is-mariadb-102/index).

 
The [Information Schema](../information_schema/index) `INNODB_SYS_VIRTUAL` table contains information about base columns of [virtual columns](../generated-columns/index). The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
| Field | Type | Null | Key | Default | Description |
| TABLE\_ID | bigint(21) unsigned | NO |  | 0 |  |
| POS | int(11) unsigned | NO |  | 0 |  |
| BASE\_POS | int(11) unsigned | NO |  | 0 |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_virtual-table/>

Information Schema INNODB\_LOCK\_WAITS Table
============================================

    The [Information Schema](../information_schema/index) `INNODB_LOCK_WAITS` table contains information about blocked InnoDB transactions. The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `REQUESTING_TRX_ID` | Requesting transaction ID from the [INNODB\_TRX](../information-schema-innodb_trx-table/index) table. |
| `REQUESTED_LOCK_ID` | Lock ID from the [INNODB.LOCKS](../information-schema-innodb_locks-table/index) table for the waiting transaction. |
| `BLOCKING_TRX_ID` | Blocking transaction ID from the [INNODB\_TRX](../information-schema-innodb_trx-table/index) table. |
| `BLOCKING_LOCK_ID` | Lock ID from the [INNODB.LOCKS](../information-schema-innodb_locks-table/index) table of a lock held by a transaction that is blocking another transaction. |

 
The table is often used in conjunction with the [INNODB\_LOCKS](../information-schema-innodb_locks-table/index) and [INNODB\_TRX](../information-schema-innodb_trx-table/index) tables to diagnose problematic locks and transactions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_lock_waits-table/>

Information Schema INNODB\_SYS\_COLUMNS Table
=============================================

    The [Information Schema](../information_schema/index) `INNODB_SYS_COLUMNS` table contains information about InnoDB fields.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_ID` | Table identifier, matching the value from [INNODB\_SYS\_TABLES.TABLE\_ID](../information-schema-innodb_sys_tables-table/index). |
| `NAME` | Column name. |
| `POS` | Ordinal position of the column in the table, starting from `0`. This value is adjusted when columns are added or removed. |
| `MTYPE` | Numeric column type identifier, (see the table below for an explanation of its values). |
| `PRTYPE` | Binary value of the InnoDB precise type, representing the data type, character set code and nullability. |
| `LEN` | Column length. For multi-byte character sets, represents the length in bytes. |

 
The column `MTYPE` uses a numeric column type identifier, which has the following values:

 


| Column Type Identifier | Description |
| --- | --- |
| `1` | `[VARCHAR](../varchar/index)` |
| `2` | `[CHAR](../char/index)` |
| `3` | `FIXBINARY` |
| `4` | `[BINARY](../binary/index)` |
| `5` | `[BLOB](../blob/index)` |
| `6` | `[INT](../int/index)` |
| `7` | `SYS_CHILD` |
| `8` | `SYS` |
| `9` | `[FLOAT](../float/index)` |
| `10` | `[DOUBLE](../double/index)` |
| `11` | `[DECIMAL](../decimal/index)` |
| `12` | `VARMYSQL` |
| `13` | `MYSQL` |

 
Example
-------

 
```
SELECT * FROM information_schema.INNODB_SYS_COLUMNS LIMIT 3\G
*************************** 1. row ***************************
TABLE_ID: 11
    NAME: ID
     POS: 0
   MTYPE: 1
  PRTYPE: 524292
     LEN: 0
*************************** 2. row ***************************
TABLE_ID: 11
    NAME: FOR_NAME 
     POS: 0
   MTYPE: 1
  PRTYPE: 524292
    LEN: 0
*************************** 3. row ***************************
TABLE_ID: 11
    NAME: REF_NAME 
     POS: 0
   MTYPE: 1
  PRTYPE: 524292
     LEN: 0
3 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_sys_columns-table/>

Information Schema INNODB\_TRX Table
====================================

    The [Information Schema](../information_schema/index) `INNODB_TRX` table stores information about all currently executing InnoDB transactions.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TRX_ID` | Unique transaction ID number. |
| `TRX_STATE` | Transaction execution state; one of `RUNNING`, `LOCK WAIT`, `ROLLING BACK` or `COMMITTING`. |
| `TRX_STARTED` | Time that the transaction started. |
| `TRX_REQUESTED_LOCK_ID` | If `TRX_STATE` is `LOCK_WAIT`, the `[INNODB\_LOCKS.LOCK\_ID](../information-schema-innodb_locks-table/index)` value of the lock being waited on. `NULL` if any other state. |
| `TRX_WAIT_STARTED` | If `TRX_STATE` is `LOCK_WAIT`, the time the transaction started waiting for the lock, otherwise `NULL`. |
| `TRX_WEIGHT` | Transaction weight, based on the number of locked rows and the number of altered rows. To resolve deadlocks, lower weighted transactions are rolled back first. Transactions that have affected non-transactional tables are always treated as having a heavier weight. |
| `TRX_MYSQL_THREAD_ID` | Thread ID from the `[PROCESSLIST](../information-schema-processlist-table/index)` table (note that the locking and transaction information schema tables use a different snapshot from the processlist, so records may appear in one but not the other). |
| `TRX_QUERY` | SQL that the transaction is currently running. |
| `TRX_OPERATION_STATE` | Transaction's current state, or `NULL`. |
| `TRX_TABLES_IN_USE` | Number of InnoDB tables currently being used for processing the current SQL statement. |
| `TRX_TABLES_LOCKED` | Number of InnoDB tables that that have row locks held by the current SQL statement. |
| `TRX_LOCK_STRUCTS` | Number of locks reserved by the transaction. |
| `TRX_LOCK_MEMORY_BYTES` | Total size in bytes of the memory used to hold the lock structures for the current transaction in memory. |
| `TRX_ROWS_LOCKED` | Number of rows the current transaction has locked. locked by this transaction. An approximation, and may include rows not visible to the current transaction that are delete-marked but physically present. |
| `TRX_ROWS_MODIFIED` | Number of rows added or changed in the current transaction. |
| `TRX_CONCURRENCY_TICKETS` | Indicates how much work the current transaction can do before being swapped out, see the `[innodb\_concurrency\_tickets](../xtradbinnodb-server-system-variables/index#innodb_concurrency_tickets)` system variable. |
| `TRX_ISOLATION_LEVEL` | [Isolation level](../set-transaction/index#isolation-levels) of the current transaction. |
| `TRX_UNIQUE_CHECKS` | Whether unique checks are `on` or `off` for the current transaction. Bulk data are a case where unique checks would be off. |
| `TRX_FOREIGN_KEY_CHECKS` | Whether foreign key checks are `on` or `off` for the current transaction. Bulk data are a case where foreign keys checks would be off. |
| `TRX_LAST_FOREIGN_KEY_ERROR` | Error message for the most recent foreign key error, or `NULL` if none. |
| `TRX_ADAPTIVE_HASH_LATCHED` | Whether the adaptive hash index is locked by the current transaction or not. One transaction at a time can change the adaptive hash index. |
| `TRX_ADAPTIVE_HASH_TIMEOUT` | Whether the adaptive hash index search latch shoild be relinquished immediately or reserved across all MariaDB calls. `0` if there is no contention on the adaptive hash index, in which case the latch is reserved until completion, otherwise counts down to zero and the latch is released after each row lookup. |
| `TRX_IS_READ_ONLY` | `1` if a read-only transaction, otherwise `0`. |
| `TRX_AUTOCOMMIT_NON_LOCKING` | `1` if the transaction only contains this one statement, that is, a `[SELECT](../select/index)` statement not using `FOR UPDATE` or `LOCK IN SHARED MODE`, and with autocommit on. If this and `TRX_IS_READ_ONLY` are both 1, the transaction can be optimized by the storrage engine to reduce some overheads |

 
The table is often used in conjunction with the [INNODB\_LOCKS](../information-schema-innodb_locks-table/index) and [INNODB\_LOCK\_WAITS](../information-schema-innodb_lock_waits-table/index) tables to diagnose problematic locks and transactions.

 [XA transactions](../xa-transactions/index) are not stored in this table. To see them, `XA RECOVER` can be used.

 Example
-------

 
```
-- session 1
START TRANSACTION;
UPDATE t SET id = 15 WHERE id = 10;

-- session 2
DELETE FROM t WHERE id = 10;

-- session 1
USE information_schema;
SELECT l.*, t.*
    FROM information_schema.INNODB_LOCKS l
    JOIN information_schema.INNODB_TRX t
        ON l.lock_trx_id = t.trx_id
    WHERE trx_state = 'LOCK WAIT' \G
*************************** 1. row ***************************
                   lock_id: 840:40:3:2
               lock_trx_id: 840
                 lock_mode: X
                 lock_type: RECORD
                lock_table: `test`.`t`
                lock_index: PRIMARY
                lock_space: 40
                 lock_page: 3
                  lock_rec: 2
                 lock_data: 10
                    trx_id: 840
                 trx_state: LOCK WAIT
               trx_started: 2019-12-23 18:43:46
     trx_requested_lock_id: 840:40:3:2
          trx_wait_started: 2019-12-23 18:43:46
                trx_weight: 2
       trx_mysql_thread_id: 46
                 trx_query: DELETE FROM t WHERE id = 10
       trx_operation_state: starting index read
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 1
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
          trx_is_read_only: 0
trx_autocommit_non_locking: 0

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_trx-table/>

sysbench v0.5 - Single Five Minute Runs on T500 Laptop
======================================================

    MariDB/MySQL sysbench benchmark comparison in %

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete             92.42   82.60   88.05   89.85   94.68   98.75   97.77
  insert            100.70   99.90  103.21   89.51   85.16  105.39  108.51
  oltp_complex_ro   101.09  101.83  100.32  103.78  102.10  101.29  102.92
  oltp_complex_rw    95.04   90.22   91.84   88.78  100.98  101.96  101.60
  oltp_simple       100.29   99.90  101.69  102.22  102.61  102.18  101.49
  select            101.57  101.73  100.26  102.15  101.99  102.39  102.09
  update_index       96.01  103.06  105.89  108.35  108.13  104.36  101.61
  update_non_index   99.85  102.05  110.76  119.51  119.69  118.25  122.77

(MariaDB q/s / MySQL q/s * 100)

```

Run on Lenovo ThinkPad T500 with dual core 2.80GHz and 4GB RAM

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2818 timestamp: Wed 2010-02-17 21:10:02 +0100

```

MySQL revision was:

 
```
revno: 3360 [merge] timestamp: Wed 2010-02-17 18:48:40 +0100

```

sysbench was run with these parameters:

 
```
--oltp-table-size=2000000 \
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=InnoDB \
--mysql-user=root \
--mysql-engine-trx=yes

```

and this variable part of parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariDB and MySQL:

 
```
--no-defaults \
--skip-grant-tables \
--language=./sql/share/english \
--datadir=$DATA_DIR \
--tmpdir=$TEMP_DIR \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--query_cache_size=0 \
--query_cache_type=0 \
--innodb_data_home_dir=$DATA_DIR \
--innodb_data_file_path=ibdata1:128M:autoextend \
--innodb_log_group_home_dir=$DATA_DIR \
--innodb_buffer_pool_size=1024M \
--innodb_additional_mem_pool_size=32M \
--innodb_log_file_size=256M \
--innodb_log_buffer_size=16M \
--innodb_flush_log_at_trx_commit=1 \
--innodb_lock_wait_timeout=50 \
--innodb_doublewrite=0 \
--innodb_flush_method=O_DIRECT \
--innodb_thread_concurrency=0 \
--innodb_max_dirty_pages_pct=80"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1643/>

sysbench v0.5 - Three Times Five Minutes Runs on work with 5.1.42
=================================================================

    MariDB/MySQL sysbench benchmark comparison in %

 Each test was run for 5 minutes 3 times

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete             98.99   86.56   97.42  102.60  101.25   98.91   99.99
  insert             99.20   97.52   98.18   99.01   99.32   99.76   99.36
  oltp_complex_ro   100.34   99.60   98.97  100.34   99.37   99.98  100.25
  oltp_complex_rw   115.90  101.87  101.93  100.78  100.45   95.67  105.08
  oltp_simple       100.09   99.82   99.73   99.57   99.57  101.48  100.59
  select             99.72   99.83   98.85   99.92  101.29   99.34  100.11
  update_index      112.62  101.40   99.31  100.21   98.15   99.12   99.98
  update_non_index   99.36   99.28  100.20   87.68   97.09  102.04   99.91

(MariaDB q/s / MySQL q/s * 100)

```

Benchmark was run on work: Linux openSUSE 11.1 (x86\_64), daul socket quad-core Intel 3.0GHz. with 6MB L2 cache, 8 GB RAM, data\_dir on single disk.

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
-rtag:5.1.42

```

MySQL revision was:

 
```
-rtag:5.1.42

```

sysbench was run with these parameters:

 
```
--oltp-table-size=2000000 \
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=InnoDB \
--mysql-user=root \
--mysql-engine-trx=yes

```

and this variable part of parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariaDB and MySQL:

 
```
--no-defaults \
--skip-grant-tables \
--language=./sql/share/english \
--datadir=$DATA_DIR \
--tmpdir=$TEMP_DIR \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--query_cache_size=0 \
--query_cache_type=0 \
--innodb_data_home_dir=$DATA_DIR \
--innodb_data_file_path=ibdata1:128M:autoextend \
--innodb_log_group_home_dir=$DATA_DIR \
--innodb_buffer_pool_size=1024M \
--innodb_additional_mem_pool_size=32M \
--innodb_log_file_size=256M \
--innodb_log_buffer_size=16M \
--innodb_flush_log_at_trx_commit=1 \
--innodb_lock_wait_timeout=50 \
--innodb_doublewrite=0 \
--innodb_flush_method=O_DIRECT \
--innodb_thread_concurrency=0 \
--innodb_max_dirty_pages_pct=80"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1646/>

sysbench v0.5 - Single Five Minute Runs on perro
================================================

    MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete            103.72  101.84  106.56  102.80   94.19   86.23   65.13
  insert            102.01   95.04   97.44   89.00   82.42   81.82   85.63
  oltp_complex_ro   104.21  104.98  105.30  102.67  102.69  102.95  101.10
  oltp_complex_rw   105.08  104.34  103.60  102.90  100.76   98.41   89.94
  oltp_simple       100.66  100.44  102.82  104.23  103.08  100.55   95.90
  select            102.93  101.56  103.70  104.18  102.25  100.65   97.33
  update_index      101.74   92.33  101.69   93.09   76.45   73.67   72.88
  update_non_index  101.58   98.13   98.91   92.32   84.00   76.75   74.19

(MariaDB q/s / MySQL q/s * 100)

```

Benchmark was run on perro: Linux openSUSE 11.1 (x86\_64), single socket dual-core Intel 3.2GHz. with 1MB L2 cache, 2GB RAM, data\_dir on 2 disk software RAID 0

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2821
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: maria-5.1
timestamp: Tue 2010-02-23 13:04:58 +0100
message:
fix for a possible DoS in the my_net_skip_rest()

```

MySQL revision was:

 
```
revno: 3360 [merge]
author: hery.ramilison@sun.com
committer: MySQL Build Team <build@mysql.com>
branch nick: mysql-5.1
timestamp: Wed 2010-02-17 18:48:40 +0100
message:
Merge from mysql-5.1.44-release

```

sysbench was run with these parameters:

 
```
--oltp-table-size=2000000 \
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=InnoDB \
--mysql-user=root \
--mysql-engine-trx=yes

```

and this variable part of parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariDB and MySQL:

 
```
--no-defaults \
--skip-grant-tables \
--language=./sql/share/english \
--datadir=$DATA_DIR \
--tmpdir=$TEMP_DIR \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--query_cache_size=0 \
--query_cache_type=0 \
--innodb_data_home_dir=$DATA_DIR \
--innodb_data_file_path=ibdata1:128M:autoextend \
--innodb_log_group_home_dir=$DATA_DIR \
--innodb_buffer_pool_size=1024M \
--innodb_additional_mem_pool_size=32M \
--innodb_log_file_size=256M \
--innodb_log_buffer_size=16M \
--innodb_flush_log_at_trx_commit=1 \
--innodb_lock_wait_timeout=50 \
--innodb_doublewrite=0 \
--innodb_flush_method=O_DIRECT \
--innodb_thread_concurrency=0 \
--innodb_max_dirty_pages_pct=80"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysbench-v05-single-five-minute-runs-on-perro/>

sysbench v0.5 - Single Five Minute Runs on work
===============================================

    MariDB/MySQL sysbench benchmark comparison in %

 Each test was run for 5 minutes.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete            121.52  144.77  117.70  115.15  100.48   75.39   66.56
  insert            114.89  181.50  118.06  136.00  125.53  141.83  113.88
  oltp_complex_ro   103.13  100.99   94.65  104.14   97.87   90.18   79.93
  oltp_complex_rw   131.65  149.90  120.88  128.58  116.71   89.92   80.63
  oltp_simple       102.32  102.57   97.33   96.34   93.99   78.81   59.71
  select            102.12  102.05   96.64   97.28   93.55   81.53   59.83
  update_index      114.08  103.98  115.59  124.90  123.51  104.38   99.11
  update_non_index  134.04  147.94  150.91  150.04  152.12  108.34   89.24

insert/4 is a glitch

(MariaDB q/s / MySQL q/s * 100)

```

Benchmark was run on work: Linux openSUSE 11.1 (x86\_64), daul socket quad-core Intel 3.0GHz. with 6MB L2 cache, 8 GB RAM, data\_dir on single disk.

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2821
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: maria-5.1
timestamp: Tue 2010-02-23 13:04:58 +0100
message:
fix for a possible DoS in the my_net_skip_rest()

```

MySQL revision was:

 
```
revno: 2929
committer: Alexander Nozdrin <alik@sun.com>
branch nick: mysql-trunk
timestamp: Sat 2010-02-20 12:26:22 +0300
message:
Fix default.conf.

```

sysbench was run with these parameters:

 
```
--oltp-table-size=2000000 \
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=InnoDB \
--mysql-user=root \
--mysql-engine-trx=yes

```

and this variable part of parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariaDB and MySQL:

 
```
--no-defaults \
--skip-grant-tables \
--language=./sql/share/english \
--datadir=$DATA_DIR \
--tmpdir=$TEMP_DIR \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--query_cache_size=0 \
--query_cache_type=0 \
--innodb_data_home_dir=$DATA_DIR \
--innodb_data_file_path=ibdata1:128M:autoextend \
--innodb_log_group_home_dir=$DATA_DIR \
--innodb_buffer_pool_size=1024M \
--innodb_additional_mem_pool_size=32M \
--innodb_log_file_size=256M \
--innodb_log_buffer_size=16M \
--innodb_flush_log_at_trx_commit=1 \
--innodb_lock_wait_timeout=50 \
--innodb_doublewrite=0 \
--innodb_flush_method=O_DIRECT \
--innodb_thread_concurrency=0 \
--innodb_max_dirty_pages_pct=80"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysbench-v05-single-five-minute-runs-on-work/>

sysbench v0.5 - 3x Five Minute Runs on work with 5.2-wl86
=========================================================

    3x Five Minute Runs on work with 5.2-wl86 key cache partitions on and off

 MariDB 5.2-wl86 sysbench benchmark comparison with key\_cache\_partitions off and 7 in %

 Each test was run three times for 5 minutes.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete            -18.36  -20.66  -11.32    5.42   -2.91  -14.62   -3.47
  insert             -2.38  -30.11   -1.64   -0.98   -1.19    0.12   -2.37
  oltp_complex_ro     0.16    2.61    4.03    2.99    3.10    5.73   20.95
  oltp_complex_rw   Dup key errors (due to sysbench)
  oltp_simple        -1.24    1.86   11.14   10.69   16.11   17.16   14.31
  select             -0.22    2.00   11.42   10.31   15.58   17.10   14.31
  update_index       -9.34   15.75   -0.36  -10.33    1.94    2.44   41.44
  update_non_index    0.73    1.04   11.12   17.32    5.30   -0.24   -9.55

 (MariaDB 5.2-wl86 key_cache_partitions off q/s /
  MariaDB 5.2-wl86 key_cache_partitions=7 q/s * 100)

key_buffer_size = 32M

```

Benchmark was run on work: Linux openSUSE 11.1 (x86\_64), daul socket quad-core Intel 3.0GHz. with 6MB L2 cache, 8 GB RAM, data\_dir on single disk.

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
lp:~maria-captains/maria/maria-5.2-wl86

revno: 2742
committer: Igor Babaev <igor@askmonty.org>
branch nick: maria-5.2-keycache
timestamp: Tue 2010-02-16 08:41:11 -0800
message:
  WL#86: Partitioned key cache for MyISAM.
  This is the base patch for the task.

```

sysbench was run with the following parameters:

 
```
--oltp-table-size=20000000 \  # 20 mio rows
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=MyISAM \
--mysql-user=root \
--mysql-engine-trx=no \
--myisam-max-rows=50000000"

```

and this variable part of parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariDB:

 
```
--no-defaults \
--datadir=$DATA_DIR \
--language=./sql/share/english \
--key_buffer_size=32M \
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
--skip-grant-tables \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--tmpdir=$TEMP_DIR"
#  --key_cache_partitions=7 \

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1647/>

Benchmarks and Long Running Tests
==================================

   Here you will find details about our automated benchmark runs and long running tests. Feel free to suggest other benchmarks and tests. You can also send us your findings about benchmarks and tests, which you have run.

  

| Title | Description |
| --- | --- |

 ###   [Benchmarks](../benchmarks/index)

 

| Title | Description |
| --- | --- |
|  [mariadb-tools](../mariadb-tools/index) |  Helper and wrapper scripts.  |
|  [Recommended Settings for Benchmarks](../recommended-settings-for-benchmarks/index) |  Best known settings and recommendations for benchmarks.  |
|  [Benchmarking Aria](../benchmarking-aria/index) |  Aria benchmarks  |
|  [DBT-3 Dataset](../dbt-3-dataset/index) |  This page describes our setup for DBT-3 tests. A very cogent resource on th...  |
|  [DBT3 Automation Scripts](../dbt3-automation-scripts/index) |  DBT-3 (OSDL Database Test 3) is a workload tool for the Linux kernel that ...  |
|  [Segmented Key Cache Performance](../segmented-key-cache-performance/index) |  Testing method for segmented key cache performance We used SysBench v0.5 f...  |
|  [run-sql-bench.pl](../run-sql-benchpl/index) |  run-sql-bench.pl is a perl script for automating runs of sql-bench (You can...  |
|  [sysbench Benchmark Setup](../sysbench-benchmark-setup/index) |  Basic parameters and configuration for sysbench  |
|  [MariaDB 5.3 - Asynchronous I/O on Windows with InnoDB](../mariadb-53-asynchronous-io-on-windows-with-innodb/index) |  MariaDB 5.3 - Asynchronous I/O on Windows with InnoDB  |
|  [MariaDB 5.3/MySQL 5.5 Windows performance patches](../mariadb-53mysql-55-windows-performance-patches/index) |  I just backported Windows performance patches I've done for 5.5 back to Mar...  |
|  [Aria LIMIT clause performance](../aria-limit-clause-performance/index) |  Does MariaDB / Aria storage engine improve upon the poor performance of MyS...  |
|  [SHARE PERFORMANCE ACROSS 2 SERVERS](../share-performance-across-2-servers/index) |  Good morning in very l 'équipe of monty , sorry for my english, i am french...  |
|  [Benchmark Builds](../benchmark-builds/index) |  how to build with cmake and consistent settings (CFLAGS etc)  |
|  [DBT3 Benchmark Results InnoDB](../dbt3-benchmark-results-innodb/index) |  Results for DBT3 benchmarking with MariaDB 5.3 InnoDB  |
|  [DBT3 Benchmark Results MyISAM](../dbt3-benchmark-results-myisam/index) |  Results for DBT3 benchmarking with MariaDB 5.3/5/5 MyISAM  |
|  [DBT3 Example Preparation Time](../dbt3-example-preparation-time/index) |  Database preparation and creation times discovered while working on the DBT3 Automation Scripts  |
|  [Performance of MEMORY Tables](../performance-of-memory-tables/index) |  Up to 60% better performance with MariaDB 5.5.22 for inserting rows into MEMORY tables  |
|  [RQG Performance Comparisons](../rqg-performance-comparisons/index) |  Performance testing The performance/perfrun.pl executes each query against ...  |

 ###   [Benchmark Results](../benchmark-results/index)

 

| Title | Description |
| --- | --- |
|  [Threadpool Benchmarks](../threadpool-benchmarks/index) |  Here are some benchmarks of some development threadpool code (the 5.5 thre...  |
|  [Sysbench Results](../sysbench-results/index) |  Results from various Sysbench runs. The data is in OpenDocument Spreadsheet...  |
|  [sysbench v0.5 - Single Five Minute Runs on T500 Laptop](../1643/index) |  MariDB/MySQL sysbench benchmark comparison in % Number of threads  |
|  [sysbench v0.5 - Single Five Minute Runs on perro](../sysbench-v05-single-five-minute-runs-on-perro/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes.  |
|  [sysbench v0.5 - Single Five Minute Runs on work](../sysbench-v05-single-five-minute-runs-on-work/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes.  |
|  [sysbench v0.5 - Three Times Five Minutes Runs on work with 5.1.42](../1646/index) |  MariDB/MySQL sysbench benchmark comparison in % Each test was run for 5 minutes 3 times  |
|  [sysbench v0.5 - 3x Five Minute Runs on work with 5.2-wl86](../1647/index) |  3x Five Minute Runs on work with 5.2-wl86 key cache partitions on and off M...  |
|  [sysbench v0.5 - 3x Five Minute Runs on work with 5.1 vs. 5.2-wl86](../1648/index) |  3x Five Minute Runs on work with 5.1 vs. 5.2-wl86 key cache partitions off ...  |
|  [sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 a](../1649/index) |  sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 key cache partitio...  |
|  [sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 b](../1650/index) |  3x 15 Minute Runs on perro with 5.2-wl86 key cache partitions off, 8, and 3...  |
|  [Select Random Ranges and Select Random Point](../select-random-ranges-and-select-random-point/index) |  select\_random\_ranges (select 10 ranges with a delta as parameter) select\_ra...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmarks-and-long-running-tests/>

sysbench v0.5 - 3x Five Minute Runs on work with 5.1 vs. 5.2-wl86
=================================================================

    3x Five Minute Runs on work with 5.1 vs. 5.2-wl86 key cache partitions off

 [MariaDB 5.1](../what-is-mariadb-51/index) vs. 5.2-wl86 sysbench benchmark comparison in %

 Each test was run three times for 5 minutes.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  delete            107.28   94.70   98.10  107.12   93.59   89.24   86.89
  insert            103.15  105.13  101.75  102.78  101.52  100.29  100.89
  oltp_complex_ro   101.31  101.77  100.41   98.72   98.53  101.59  100.44
  oltp_complex_rw   Dup key errors (due to sysbench)
  oltp_simple       102.28  100.76  102.70  100.94  101.05  101.81  102.06
  select            100.88  101.05  100.48  101.61  101.48  101.87  101.44
  update_index       97.57   96.81   93.58  102.43   89.19  107.63   88.29
  update_non_index  101.58   83.24  110.46   94.52  106.33  103.87  115.22

(MariaDB 5.1 key_cache_partitions off q/s /
 MariaDB 5.2-wl86 key_cache_partitions off q/s * 100)

key_buffer_size = 512M

```

Benchmark was run on work: Linux openSUSE 11.1 (x86\_64), daul socket quad-core Intel 3.0GHz. with 6MB L2 cache, 8 GB RAM, data\_dir on single disk.

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

[MariaDB 5.1](../what-is-mariadb-51/index) revision was:

 
```
revno: 2821
committer: Sergei Golubchik <sergii@pisem.net>
branch nick: maria-5.1
timestamp: Tue 2010-02-23 13:04:58 +0100
message:
  fix for a possible DoS in the my_net_skip_rest()

```

[MariaDB 5.2](../what-is-mariadb-52/index)-wl86 revision was:

 
```
lp:~maria-captains/maria/maria-5.2-wl86

revno: 2742
committer: Igor Babaev <igor@askmonty.org>
branch nick: maria-5.2-keycache
timestamp: Tue 2010-02-16 08:41:11 -0800
message:
  WL#86: Partitioned key cache for MyISAM.
  This is the base patch for the task.

```

sysbench was run with the following parameters:

 
```
--oltp-table-size=20000000 \  # 20 mio rows
--max-time=300 \
--max-requests=0 \
--mysql-table-engine=MyISAM \
--mysql-user=root \
--mysql-engine-trx=no \
--myisam-max-rows=50000000"

```

and this variable part of the parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariaDB:

 
```
--no-defaults \
--datadir=$DATA_DIR \
--language=./sql/share/english \
--key_buffer_size=512M \
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
--skip-grant-tables \
--socket=$MY_SOCKET \
--table_open_cache=512 \
--thread_cache=512 \
--tmpdir=$TEMP_DIR"
#  --key_cache_partitions=7 \

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1648/>

sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 a
==========================================================

    sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 key cache partitions off, 8, and 32 and key buffer size 400

 MariDB sysbench benchmark comparison for key\_cache\_partitions in % with key\_buffer\_size = 400MB

 Each test was run 3 times for 15 minutes with 3 minutes warmup.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  oltp_complex_ro
      8 / off        -0.78   -0.42   -0.18   -0.49   -1.03   -0.64    1.08
     32 / off        -0.38   -0.30    0.55   -0.39   -0.75   -0.05    2.49
  oltp_simple
      8 / off        -1.19   -2.20   -0.74   -2.74   -1.54    0.28   -1.46
     32 / off        -1.24   -1.22    0.33   -0.13    0.11    2.09   -1.34
  select
      8 / off        -0.71   -1.68   -1.48   -2.05    0.94   -2.93   -0.18
     32 / off        -0.71   -1.33   -2.11   -0.63   -0.40  -19.68* -11.45*
  update_index
      8 / off        -1.30    4.37  -14.69*  -2.56   17.69*  -1.14    2.82
     32 / off        -1.47    7.03*   0.71   -0.72   15.61*   1.61    0.33

 ( 8/off*100)-100
 (32/off*100)-100

 * means due to unusual high STDEV (see OO.org spreadsheet for details)

 off means key_cache_partitions off
   8 means key_cache_partitions = 8
  32 means key_cache_partitions = 32

```

Benchmark was run on perro: Linux openSUSE 11.1 (x86\_64), single socket dual-core Intel 3.2GHz. with 1MB L2 cache, 2GB RAM, data\_dir on 2 disk software RAID 0

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2742
committer: Igor Babaev <igor@askmonty.org>
branch nick: maria-5.2-keycache
timestamp: Tue 2010-02-16 08:41:11 -0800
message:
  WL#86: Partitioned key cache for MyISAM.
  This is the base patch for the task.

```

sysbench was run with the following parameters:

 
```
--oltp-table-size=20000000 \       # 20 million rows.
--max-requests=0 \
--mysql-table-engine=MyISAM \
--mysql-user=root \
--mysql-engine-trx=no \
--myisam-max-rows=50000000 \
--rand-seed=303

```

and these variable parameters:

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariaDB:

 
```
--no-defaults \
--datadir=/mnt/data/sysbench/data \
--language=./sql/share/english \
--key_buffer_size=400M \
--key_cache_partitions=32 \        # Off | 8 | 32
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
--skip-grant-tables \
--socket=/tmp/mysql.sock \
--table_open_cache=512 \
--thread_cache=512 \
--tmpdir=/mnt/data/sysbench

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1649/>

sysbench v0.5 - 3x 15 Minute Runs on perro with 5.2-wl86 b
==========================================================

    3x 15 Minute Runs on perro with 5.2-wl86 key cache partitions off, 8, and 32 and key buffer size 75

 MariDB sysbench benchmark comparison for key\_cache\_partitions in % with key\_buffer\_size = 75MB

 Each test was run 3 times for 15 minutes with 3 minutes warmup.

 
```
                   Number of threads
                     1       4       8       16      32      64      128
 sysbench test
  oltp_complex_ro
      8 / off        3.05   -0.10    0.57    1.00   -0.05    0.15    2.50
     32 / off        3.04  -26.61*   0.89   -0.02    1.03    0.44    2.94
  oltp_simple
      8 / off       -0.95   -1.10   -1.17    1.36   -2.65   -0.59   -1.01
     32 / off        0.76   -0.02    0.66    2.75    1.96    3.05   -0.86
  select
      8 / off       -1.45   -0.68   -2.31  -27.61*  -0.52   -3.97   -0.24
     32 / off       -0.87   -1.63   -1.15   -2.10    0.44    1.12    1.39
  update_index
      8 / off       -2.55    8.29*   3.14    4.16    1.13    1.95    1.29
     32 / off       -2.27    9.46*  -0.12    2.64    0.69   -7.26*  -0.24
 
 ( 8/off*100)-100
 (32/off*100)-100
 
 * means unusually high STDEV

 off means key_cache_partitions off
   8 means key_cache_partitions = 8
  32 means key_cache_partitions = 32

```

Benchmark was run on perro: Linux openSUSE 11.1 (x86\_64), single socket dual-core Intel 3.2GHz. with 1MB L2 cache, 2GB RAM, data\_dir on 2 disk software RAID 0

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2742
committer: Igor Babaev <igor@askmonty.org>
branch nick: maria-5.2-keycache
timestamp: Tue 2010-02-16 08:41:11 -0800
message:
  WL#86: Partitioned key cache for MyISAM.
  This is the base patch for the task.

```

sysbench was run with the following parameters:

 
```
--oltp-table-size=20000000 \       # 20 million rows.
--max-requests=0 \
--mysql-table-engine=MyISAM \
--mysql-user=root \
--mysql-engine-trx=no \
--myisam-max-rows=50000000 \
--rand-seed=303

```

and the following variable parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariDB:

 
```
--no-defaults \
--datadir=/mnt/data/sysbench/data \
--language=./sql/share/english \
--key_buffer_size=75M \
--key_cache_partitions=32 \        # Off | 8 | 32
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
--skip-grant-tables \
--socket=/tmp/mysql.sock \
--table_open_cache=512 \
--thread_cache=512 \
--tmpdir=/mnt/data/sysbench

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1650/>

Select Random Ranges and Select Random Point
============================================

    * `select_random_ranges` (select 10 ranges with a delta as parameter)
* `select_random_points` (select 100 random points)

 Findings:
---------

 `select_random_ranges`

 * A delta of 100 for the ranges gives 3 - 6% performance gain
* A delta of 50 for the ranges gives 3 - 15% performance gain
* A delta of 5 for the ranges gives up to 70% performance gain
* A delta of 1 million shows no difference at all.

 `select_random_points`

 * We see up to 150% performance gain fetching index only
* We see up to 50% performance gain fetching index and data

 The absolute numbers are highly RAM depended

 * We see an up to 250% performance difference on a 2GB system compared to a 4GB system.

 MariaDB and MySQL were compiled with

 
```
BUILD/compile-amd64-max

```

MariaDB revision was:

 
```
revno: 2742
committer: Igor Babaev <igor@askmonty.org>
branch nick: maria-5.2-keycache
timestamp: Tue 2010-02-16 08:41:11 -0800
message:
  WL#86: Partitioned key cache for MyISAM.
  This is the base patch for the task.

```

sysbench was run with the following parameters:

 
```
--oltp-table-size=20000000 \       # 20 million rows.
--max-requests=0 \
--mysql-table-engine=MyISAM \
--mysql-user=root \
--mysql-engine-trx=no \
--myisam-max-rows=50000000 \
--rand-seed=303

```

and the following variable parameters

 
```
--num-threads=$THREADS --test=${TEST_DIR}/${SYSBENCH_TEST}

```

Configuration used for MariDB:

 
```
--no-defaults \
--datadir=/mnt/data/sysbench/data \
--language=./sql/share/english \
--key_buffer_size=512M \
--key_cache_partitions=32 \        # Off | 32 | 64
--max_connections=256 \
--query_cache_size=0 \
--query_cache_type=0 \
--skip-grant-tables \
--socket=/tmp/mysql.sock \
--table_open_cache=512 \
--thread_cache=512 \
--tmpdir=/mnt/data/sysbench

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/select-random-ranges-and-select-random-point/>

Benchmarks
===========

   Articles about the performance of MariaDB.

  

| Title | Description |
| --- | --- |
|  [mariadb-tools](../mariadb-tools/index) |  Helper and wrapper scripts.  |
|  [Recommended Settings for Benchmarks](../recommended-settings-for-benchmarks/index) |  Best known settings and recommendations for benchmarks.  |
|  [Benchmarking Aria](../benchmarking-aria/index) |  Aria benchmarks  |
|  [DBT-3 Dataset](../dbt-3-dataset/index) |  This page describes our setup for DBT-3 tests. A very cogent resource on th...  |
|  [DBT3 Automation Scripts](../dbt3-automation-scripts/index) |  DBT-3 (OSDL Database Test 3) is a workload tool for the Linux kernel that ...  |
|  [Segmented Key Cache Performance](../segmented-key-cache-performance/index) |  Testing method for segmented key cache performance We used SysBench v0.5 f...  |
|  [run-sql-bench.pl](../run-sql-benchpl/index) |  run-sql-bench.pl is a perl script for automating runs of sql-bench (You can...  |
|  [sysbench Benchmark Setup](../sysbench-benchmark-setup/index) |  Basic parameters and configuration for sysbench  |
|  [MariaDB 5.3 - Asynchronous I/O on Windows with InnoDB](../mariadb-53-asynchronous-io-on-windows-with-innodb/index) |  MariaDB 5.3 - Asynchronous I/O on Windows with InnoDB  |
|  [MariaDB 5.3/MySQL 5.5 Windows performance patches](../mariadb-53mysql-55-windows-performance-patches/index) |  I just backported Windows performance patches I've done for 5.5 back to Mar...  |
|  [Benchmark Builds](../benchmark-builds/index) |  how to build with cmake and consistent settings (CFLAGS etc)  |
|  [DBT3 Benchmark Results InnoDB](../dbt3-benchmark-results-innodb/index) |  Results for DBT3 benchmarking with MariaDB 5.3 InnoDB  |
|  [DBT3 Benchmark Results MyISAM](../dbt3-benchmark-results-myisam/index) |  Results for DBT3 benchmarking with MariaDB 5.3/5/5 MyISAM  |
|  [DBT3 Example Preparation Time](../dbt3-example-preparation-time/index) |  Database preparation and creation times discovered while working on the DBT3 Automation Scripts  |
|  [Performance of MEMORY Tables](../performance-of-memory-tables/index) |  Up to 60% better performance with MariaDB 5.5.22 for inserting rows into MEMORY tables  |
|  [RQG Performance Comparisons](../rqg-performance-comparisons/index) |  Performance testing The performance/perfrun.pl executes each query against ...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmarks/>

Sys Schema Stored Procedures
=============================

   
This article is currently incomplete.

 
 The following [stored procedures](../stored-procedures/index) are available in the [Sys Schema](../sys-schema/index).

  

| Title | Description |
| --- | --- |
|  [create\_synonym\_db](../create_synonym_db/index) |  Takes a source db and create a synonym db with views that point to all of t...  |
|  [optimizer\_switch Helper Functions](../optimizer_switch-helper-functions/index) |  Syntax optimizer\_switch\_on() optimizer\_switch\_off() optimizer\_switch\_choice...  |
|  [ps\_trace\_thread](../ps_trace_thread/index) |  Dumps all Performance Schema data for an instrumented thread to a .dot formatted graph file.  |
|  [ps\_truncate\_all\_tables](../ps_truncate_all_tables/index) |  Resets all aggregated instrumentation.  |
|  [statement\_performance\_analyzer](../statement_performance_analyzer/index) |  Returns a report on running statements.  |
|  [table\_exists](../table_exists/index) |  Given a database and table name, returns the table type.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sys-schema-stored-procedures/>

DBT-3 Dataset
=============

    This page describes our setup for DBT-3 tests. A very cogent resource on the [DBT3 Benchmark](../dbt3-automation-scripts/index) is also available. See also [dbt-3-queries](../dbt-3-queries/index)

 Get and compile DBT3
--------------------

 * Get [DBT3](http://osdldbt.sourceforge.net/)
* Make sure that you have pg\_ctl and createdb of PostgreSQL installed. On Ubuntu look for postgresql and postgresql-client and make sure that pg\_ctl is in your PATH, for instance: 
```
PATH=/usr/lib/postgresql/8.4/bin:$PATH

```
* Compile DBT3
```
gunzip -c dbt3-1.9.tar.gz | tar xvf -
cd dbt3-1.9
./configure
make
cd src/dbgen
make

```
* Generate data:
```
./dbgen -s30

```

 DDL
---

 Substitute `${ENGINE}` with the storage engine you want to use:

 
```
CREATE TABLE supplier (
  s_suppkey  INTEGER PRIMARY KEY,
  s_name CHAR(25),
  s_address VARCHAR(40),
  s_nationkey INTEGER,
  s_phone CHAR(15),
  s_acctbal REAL,
  s_comment VARCHAR(101)) Engine ${ENGINE};

CREATE TABLE part (
  p_partkey INTEGER PRIMARY KEY,
  p_name VARCHAR(55),
  p_mfgr CHAR(25),
  p_brand CHAR(10),
  p_type VARCHAR(25),
  p_size INTEGER,
  p_container CHAR(10),
  p_retailprice REAL,
  p_comment VARCHAR(23)) Engine ${ENGINE};

CREATE TABLE partsupp (
  ps_partkey INTEGER,
  ps_suppkey INTEGER,
  ps_availqty INTEGER,
  ps_supplycost REAL,
  ps_comment VARCHAR(199),
  PRIMARY KEY (ps_partkey, ps_suppkey)) Engine ${ENGINE};

CREATE TABLE customer (
  c_custkey INTEGER primary key,
  c_name VARCHAR(25),
  c_address VARCHAR(40),
  c_nationkey INTEGER,
  c_phone CHAR(15),
  c_acctbal REAL,
  c_mktsegment CHAR(10),
  c_comment VARCHAR(117))  Engine ${ENGINE};

CREATE TABLE orders (
  o_orderkey INTEGER primary key,
  o_custkey INTEGER,
  o_orderstatus CHAR(1),
  o_totalprice REAL,
  o_orderDATE DATE,
  o_orderpriority CHAR(15),
  o_clerk CHAR(15),
  o_shippriority INTEGER,
  o_comment VARCHAR(79))  Engine ${ENGINE};

CREATE TABLE lineitem (
  l_orderkey INTEGER,
  l_partkey INTEGER,
  l_suppkey INTEGER,
  l_linenumber INTEGER,
  l_quantity REAL,
  l_extendedprice REAL,
  l_discount REAL,
  l_tax REAL,
  l_returnflag CHAR(1),
  l_linestatus CHAR(1),
  l_shipDATE DATE,
  l_commitDATE DATE,
  l_receiptDATE DATE,
  l_shipinstruct CHAR(25),
  l_shipmode CHAR(10),
  l_comment VARCHAR(44),
  PRIMARY KEY (l_orderkey, l_linenumber)) Engine ${ENGINE};

CREATE TABLE nation (
  n_nationkey INTEGER primary key,
  n_name CHAR(25),
  n_regionkey INTEGER,
  n_comment VARCHAR(152)) Engine ${ENGINE};

CREATE TABLE region (
  r_regionkey INTEGER primary key,
  r_name CHAR(25),
  r_comment VARCHAR(152)) Engine ${ENGINE};

CREATE TABLE time_statistics (
  task_name VARCHAR(40),
  s_time TIMESTAMP,
  e_time TIMESTAMP,
  int_time INTEGER)  Engine ${ENGINE};

```

Load data
---------

 Substitute `${DATA\_DIR}` with the path to your generated data.

 
```
  LOAD DATA LOCAL INFILE '${DATA_DIR}/supplier.tbl' into table supplier fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/part.tbl' into table part fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/partsupp.tbl' into table partsupp fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/customer.tbl' into table customer fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/orders.tbl' into table orders fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/lineitem.tbl' into table lineitem fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/nation.tbl' into table nation fields terminated by '|';
  LOAD DATA LOCAL INFILE '${DATA_DIR}/region.tbl' into table region fields terminated by '|';

```

Indexes we need
---------------

 
```
ALTER TABLE lineitem 
  ADD INDEX i_l_shipdate(l_shipdate),
  ADD INDEX i_l_suppkey_partkey (l_partkey, l_suppkey),
  ADD INDEX i_l_partkey (l_partkey),
  ADD INDEX i_l_suppkey (l_suppkey),
  ADD INDEX i_l_receiptdate (l_receiptdate),
  ADD INDEX i_l_orderkey (l_orderkey),
  ADD INDEX i_l_orderkey_quantity (l_orderkey, l_quantity),
  ADD INDEX i_l_commitdate (l_commitdate);

CREATE INDEX i_c_nationkey ON customer (c_nationkey);

ALTER TABLE orders
  ADD INDEX i_o_orderdate (o_orderdate),
  ADD INDEX i_o_custkey (o_custkey);

CREATE INDEX i_s_nationkey ON supplier (s_nationkey);

ALTER TABLE partsupp 
  ADD INDEX i_ps_partkey (ps_partkey),
  ADD INDEX i_ps_suppkey (ps_suppkey);

CREATE INDEX i_n_regionkey ON nation (n_regionkey);

```

Analyze tables
--------------

 
```
ANALYZE TABLE supplier;
ANALYZE TABLE part;
ANALYZE TABLE partsupp;
ANALYZE TABLE customer;
ANALYZE TABLE orders;
ANALYZE TABLE lineitem;
ANALYZE TABLE nation;
ANALYZE TABLE region;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt-3-dataset/>

Sysbench Results
================

    Results from various Sysbench runs. The data is in OpenDocument Spreadsheet format (.ods).

 For reference, the "perro" and "work" systems were configured as follows:

 


|  |  |
| --- | --- |
| perro | Linux openSUSE 11.1 (x86\_64), single socket dual-core Intel 3.2GHz. with 1MB L2 cache, 2GB RAM, data\_dir on 2 disk software RAID 0 |
| work | Linux openSUSE 11.1 (x86\_64), dual socket quad-core Intel 3.0GHz. with 6MB L2 cache, 8 GB RAM, data\_dir on single disk. |

 
sysbench v0.5 results
---------------------

 * Single Five Minutes Runs on T500 Laptop, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb\_mysql\_t500.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb_mysql_t500.ods)

 * Single Five Minutes Runs on perro, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb\_mysql\_perro.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb_mysql_perro.ods)

 * Single Five Minutes Runs on work, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb\_mysql\_work.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb_mysql_work.ods)

 * Three Times Five Minutes Runs on work with 5.1.42, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb\_mysql\_work\_5.1.42.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb_mysql_work_5.1.42.ods)

 * Three Times Five Minutes Runs on work with 5.2-wl86 key\_cache\_partitions on and off, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb-5.2-wl86\_key\_cache\_partitions\_on\_off\_work.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb-5.2-wl86_key_cache_partitions_on_off_work.ods)

 * Three Times Five Minutes Runs on work with 5.1 vs. 5.2-wl86 key\_cache\_partitions off, OO.org spreadsheet: [Sysbench\_five\_minutes\_mariadb-5.2-wl86\_key\_cache\_partitions\_on\_off\_work.ods](http://askmonty.org/sysbench-results/Sysbench_five_minutes_mariadb-5.1_5.2-wl86_key_cache_partitions_off_work.ods)

 * Three Times Fifteen Minutes Runs on perro with 5.2-wl86 key\_cache\_partitions off, 8, and 32 and key\_buffer\_size 400, OO.org spreadsheet: [Sysbench\_fifteen\_minutes\_mariadb-5.2-wl86\_key\_cache\_partitions\_off\_8\_32\_kbs\_400.ods](http://askmonty.org/sysbench-results/Sysbench_fifteen_minutes_mariadb-5.2-wl86_key_cache_partitions_off_8_32_kbs_400.ods)

 * Three Times Fifteen Minutes Runs on perro with 5.2-wl86 key\_cache\_partitions off, 8, and 32 and key\_buffer\_size 75, OO.org spreadsheet: [Sysbench\_fifteen\_minutes\_mariadb-5.2-wl86\_key\_cache\_partitions\_off\_8\_32\_kbs\_75.ods](http://askmonty.org/sysbench-results/Sysbench_fifteen_minutes_mariadb-5.2-wl86_key_cache_partitions_off_8_32_kbs_75.ods)

 * select\_random\_ranges and select\_random\_points, OO.org spreadsheet: [Sysbench\_select\_random\_ranges\_points.ods](http://askmonty.org/sysbench-results/Sysbench_select_random_ranges_points.ods)

 * select\_100\_random\_points.lua result on perro with key\_cache\_partitions off and 32, OO.org spreadsheet: [Sysbench\_v0.5\_select\_100\_random\_points.ods](http://askmonty.org/sysbench-results/Sysbench_v0.5_select_100_random_points.ods)

 * `select_random_points.lua --random-points=50` result on perro with key\_cache\_partitions off and 32, OO.org spreadsheet: [Sysbench\_v0.5\_select\_50\_random\_points.ods](http://askmonty.org/sysbench-results/Sysbench_v0.5_select_50_random_points.ods)

 * `select_random_points.lua --random-points=10` result on perro with key\_cache\_partitions off and 32, OO.org spreadsheet: [Sysbench\_v0.5\_select\_10\_random\_points.ods](http://askmonty.org/sysbench-results/Sysbench_v0.5_select_10_random_points.ods)

 * `select_random_points.lua --random-points=10, 50, and 100` results on perro with key\_cache\_segments off, 32, and 64 OO.org spreadsheet: [Sysbench\_v0.5\_select\_random\_points\_10\_50\_100\_perro.ods](http://askmonty.org/sysbench-results/Sysbench_v0.5_select_random_points_10_50_100_perro.ods)

 * `select_random_points.lua --random-points=10, 50, and 100` results on pitbull with key\_cache\_segments off, 32, and 64 OO.org spreadsheet: [Sysbench\_v0.5\_select\_random\_points\_10\_50\_100\_pitbull.ods](http://askmonty.org/sysbench-results/Sysbench_v0.5_select_random_points_10_50_100_pitbull.ods)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysbench-results/>

mariadb-tools
=============

    All of the helper and wrapper scripts we use for benchmarks and tests are available in the [mariadb.org-tools project on GitHub](https://github.com/MariaDB/mariadb.org-tools).

 The MariaDB Server Tools package from the MariaDB Corporation is available for download [from the Downloads page](https://mariadb.com/downloads/tools/server-tools/) while the source is available from: [on GitHub](https://github.com/mariadb-corporation/mariadb-tools). Official documentation is viewable on the [GitHub Pages site from the source](https://mariadb-corporation.github.io/mariadb-tools/index.html).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-tools/>

sysbench Benchmark Setup
========================

     For our automated MariaDB/MySQL sysbench benchmark tests, we use sysbench from `lp:sysbench`. This page describes the basic parameters and configuration we use.

 You can find the automation wrapper scripts we use for running sysbench in [lp:mariadb-tools](../mariadb-tools/index)

 Current general parameters
--------------------------

 
```
table_open_cache = 512
thread_cache = 512
query_cache_size = 0
query_cache_type = 0

```

Current InnoDB parameters
-------------------------

 
```
innodb_data_home_dir = /data/mysql/
innodb_data_file_path = ibdata1:128M:autoextend
innodb_log_group_home_dir = /data/mysql/
innodb_buffer_pool_size = 1024M
innodb_additional_mem_pool_size = 32M
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_doublewrite = 0
innodb_flush_method = O_DIRECT
innodb_thread_concurrency = 0
innodb_max_dirty_pages_pct = 80

```

Compile
-------

 Install MariaDB or MySQL to /usr/local and make a symlink to /usr/local/mysql. Please use non-debug version! On Mac OS X we currently need automake1.10.

 
```
./autogen.sh
./configure \
  --without-drizzle \
  --with-mysql-includes=/usr/local/mysql/include/mysql \
  --with-mysql-libs=/usr/local/mysql/lib/mysql
make
optionally: make install

```

Start and prepare database to use
---------------------------------

 
```
mysqladmin -uroot drop sbtest
mysqladmin -uroot create sbtest

```

### Tests

 We use the latest sysbench with Lua scripting support. Therefore the test names differ from sysbench <= 0.4. To get reasonable results we use a run time of 5 minutes.

 We run the tests with 1, 4, 8, 16, 32, 64, and 128 threads.

 
```
NUM_THREADS="1 4 8 16 32 64 128"
SYSBENCH_TESTS="delete.lua \
  insert.lua \
  oltp_complex_ro.lua \
  oltp_complex_rw.lua \
  oltp_simple.lua \
  select.lua \
  update_index.lua \
  update_non_index.lua"

NUM_THREADS=1
TEST_DIR=${HOME}/work/monty_program/sysbench/sysbench/tests/db

./sysbench \
  --test=${TEST_DIR}/oltp_simple.lua \
  --oltp-table-size=2000000 \
  --max-time=300 \
  --max-requests=0 \
  --mysql-table-engine=InnoDB \
  --mysql-user=root \
  --mysql-engine-trx=yes \
  --num-threads=$NUM_THREADS \
  prepare

./sysbench \
  --test=${TEST_DIR}/oltp_simple.lua \
  --oltp-table-size=2000000 \
  --max-time=300 \
  --max-requests=0 \
  --mysql-table-engine=InnoDB \
  --mysql-user=root \
  --mysql-engine-trx=yes \
  --num-threads=$NUM_THREADS \
  run

```

Custom added tests
------------------

 We created a couple of custom tests for SysBench:

 * select\_random\_ranges.lua
* select\_random\_points.lua

 Both of these have been added to the latest SysBench v0.5 repository.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/sysbench-benchmark-setup/>

MariaDB 5.3 - Asynchronous I/O on Windows with InnoDB
=====================================================

    Consider 2 pseudo-code implementation of event handling loop handling IO completion on Windows.

 * Using Windows events

 
```
void io_thread() {
    HANDLE handles = new HANDLE[32];
    ...
    for (;;) {
       DWORD index = WaitForMultipleObjects(handles,32, FALSE);
       DWORD num_bytes;
       // Find file and overlapped structure for the index,
       GetOverlappedResult(file, overlapped, &num_bytes, TRUE);
       // handle io represented by overlapped
   }

```

* I/O Completion port based

 
```
  void io_thread() {
    for (;;) {
       DWORD num_bytes;
       ULONG_PTR key;
       OVERLAPPED *overlapped;
       if (GetQueuedCompletionStatus(io_completion_port, &num_bytes,
            &key, &overlapped, INFINITE)) {
          // handle io represented by overlapped
      }
   }

```

Which one is more efficient ? The right answer is - I/O completion port based. This is because:

 1. the number of outstanding events a thread can handle is not restricted by a constant like in the WaitForMultipleObject() case.
2. if there several io\_handler() threads running, they load-balance since every I/O can be "dequeued" by GetQueuedCompletionStatus in any io handler thread. With WaitForMultipleObjects(), the thread that will dequeue the I/O result is predetermined for each I/O.

 InnoDB has used asynchronous file I/O on Windows since the dawn of time, probably since NT3.1 . On some reason unknown to me (I can only speculate that Microsoft documentation was not good enough back then), InnoDB has always used method with events, and this lead to relatively complicated designs - if you're seeing "segment" mentioning in os0file.c or fil0fil.c , this is mostly due to the fact that number of events WaitForMultipleObjects() can handle is fixed.

 I changed async IO handling for XtraDB in MariaDB5.3 to use completion ports, rather than wait\_multiple technique. The results of a synthetic benchmark are good.

 The test that I run was sysbench 0.4 "update\_no\_key"

 
```
                        4       16      64      256     1024
mariadb-5.2             17812   22378   23436   7882    6043
mariadb-5.2-fix         19217   24302   25499   25986   25925
mysql-5.5.13            12961   20445   16393   14407   5343

```

I do understand, sysbench it does not resemble anything that real-life load, and I'm ready to admit cheating with durability for this specific benchmark, but this is an equal-opportunity cheating, all 3 versions ran with the same parameters.

 What do I refer to as durability cheating:

 1. using [innodb\_flush\_log\_at\_trx\_commit=0](../xtradbinnodb-server-system-variables/index#innodb_flush_log_at_trx_commit) , which, for me , is ok for many scenarios
2. "Switch off Windows disk flushing" setting, which has the effect of not flushing data in the disk controller (file system caching is not used here anyway). This setting is only recommended for battery backed disks, my own desktop does not have it, of course.

 However, if I have not done the above, then I would be measuring the latency of a FlushFileBuffers() in my benchmark, which was not what I wanted. I wanted to stress the asynchronous IO.

 And here is the obligatory graph:

 ![mariadbasynciowindowsinnodb]

 Notes
-----

 This is taken from an original Facebook note from Vladislav Vaintroub, and it can be found: <https://www.facebook.com/note.php?note_id=238687382817625>

 It is also worth noting a note from Vlad about the graph: "The graph is given for 5.2, because I developed that patch for 5.2. I pushed it into 5.3 though :)"

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-53-asynchronous-io-on-windows-with-innodb/>

Disabling InnoDB Encryption
===========================

    The process involved in safely disabling encryption for your InnoDB tables is a little more complicated than that of [enabling encryption](../enabling-innodb-encryption/index). Turning off the relevant system variables doesn't decrypt the tables. If you turn it off and remove the encryption key management plugin, it'll render the encrypted data inaccessible. 

 In order to safely disable encryption, you first need to decrypt the tablespaces and the Redo Log, then turn off the system variables. The specifics of this process depends on whether you are using automatic or manual encryption of the InnoDB tablespaces.

 ### Disabling Encryption for Automatically Encrypted Tablespaces

 When an InnoDB tablespace has the [ENCRYPTED](../create-table/index#encrypted) table option set to `DEFAULT` and the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable is set to `ON` or `FORCE`, the tablespace's encryption is automatically managed by the background encryption threads. When you want to disable encryption for these tablespaces, you must ensure that the background encryption threads decrypt the tablespaces before removing the encryption keys. Otherwise, the tablespace remains encrypted and becomes inaccessible once you've removed the keys.

 To safely decrypt the tablespaces, first, set the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable to `OFF`:

 
```
SET GLOBAL innodb_encrypt_tables = OFF;

```

Next, set the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable to a non-zero value:

 
```
SET GLOBAL innodb_encryption_threads = 4;

```

Then, set the [innodb\_encryption\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable to `1`:

 
```
SET GLOBAL innodb_encryption_rotate_key_age = 1;

```

Once set, any InnoDB tablespaces that have the [ENCRYPTED](../create-table/index#encrypted) table option set to `DEFAULT` will be [decrypted](../innodb-background-encryption-threads/index#background-operations) in the background by the InnoDB [background encryption threads](../innodb-background-encryption-threads/index#background-encryption-threads). 

 #### Decryption Status

 You can [check the status](../innodb-background-encryption-threads/index#checking-the-status-of-background-operations) of the decryption process using the [INNODB\_TABLESPACES\_ENCRYPTION](../information-schema-innodb_tablespaces_encryption-table/index) table in the [information\_schema](../information-schema/index) database. 

 
```
SELECT COUNT(*) AS "Number of Encrypted Tablespaces"
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE ENCRYPTION_SCHEME != 0
   OR ROTATING_OR_FLUSHING != 0; 

```

This query shows the number of InnoDB tablespaces that currently using background encryption threads. Once the count reaches 0, then all of your InnoDB tablespaces are unencrypted. Be sure to also remove encryption on the [Redo Log](#disabling-encryption-for-the-redo-log) and the [Aria](../aria-encryption/index) storage engine before removing the encryption key management settings from your configuration file.

 ### Disabling Encryption for Manually Encrypted Tablespaces

 In the case of manually encrypted InnoDB tablespaces, (that is, those where the [ENCRYPTED](../create-table/index#encrypted) table option is set to `YES`), you must issue an [ALTER TABLE](../alter-table/index) statement to decrypt each tablespace before removing the encryption keys. Otherwise, the tablespace remains encrypted and becomes inaccessible without the keys.

 First, query the Information Schema [TABLES](../information-schema-tables-table/index) table to find the encrypted tables. This can be done with a `WHERE` clause filtering the `CREATE_OPTIONS` column.

 
```
SELECT TABLE_SCHEMA AS "Database", TABLE_NAME AS "Table"
FROM information_schema.TABLES
WHERE ENGINE='InnoDB' 
      AND CREATE_OPTIONS LIKE '%`ENCRYPTED`=YES%';

```

For each table in the result-set, issue an [ALTER TABLE](../alter-table/index) statement, setting the [ENCRYPTED](../create-table/index#encrypted) table option to `NO`. 

 
```
SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 1 |            100 |
+----------+-------------------+----------------+

ALTER TABLE tab1
   ENCRYPTED=NO;

SELECT NAME, ENCRYPTION_SCHEME, CURRENT_KEY_ID
FROM information_schema.INNODB_TABLESPACES_ENCRYPTION
WHERE NAME='db1/tab1';
+----------+-------------------+----------------+
| NAME     | ENCRYPTION_SCHEME | CURRENT_KEY_ID |
+----------+-------------------+----------------+
| db1/tab1 |                 0 |            100 |
+----------+-------------------+----------------+

```

Once you have removed encryption from all the tables, your InnoDB deployment is unencrypted. Be sure to also remove encryption from the [Redo Log](#disabling-encryption-for-the-redo-log) as well as [Aria](../aria-encryption/index) and any other storage engines that support encryption before removing the encryption key management settings from your configuration file. 

 
InnoDB does not permit manual encryption changes to tables in the [system](../innodb-system-tablespaces/index) tablespace using [ALTER TABLE](../alter-table/index). Encryption of the [system](../innodb-system-tablespaces/index) tablespace can only be configured by setting the value of the [innodb\_encrypt\_tables](../innodb-system-variables/index#innodb_encrypt_tables) system variable. This means that when you want to encrypt or decrypt the [system](../innodb-system-tablespaces/index) tablespace, you must also set a non-zero value for the [innodb\_encryption\_threads](../innodb-system-variables/index#innodb_encryption_threads) system variable, and you must also set the [innodb\_system\_rotate\_key\_age](../innodb-system-variables/index#innodb_encryption_rotate_key_age) system variable to `1` to ensure that the system tablespace is properly encrypted or decrypted by the background threads. See [MDEV-14398](https://jira.mariadb.org/browse/MDEV-14398) for more information.

 
### Disabling Encryption for Temporary Tablespaces

 The [innodb\_encrypt\_temporary\_tables](../innodb-system-variables/index#innodb_encrypt_temporary_tables) system variable controls the configuration of encryption for the [temporary tablespace](../innodb-temporary-tablespaces/index). To disable it, remove the system variable from your server's [option file](../configuring-mariadb-with-option-files/index), and then restart the server.

 ### Disabling Encryption for the Redo Log

 InnoDB uses the [Redo Log](../innodb-redo-log/index) in crash recovery. By default, these events are written to file in an unencrypted state. In removing data-at-rest encryption for InnoDB, be sure to also disable encryption for the Redo Log before removing encryption key settings. Otherwise the Redo Log can become inaccessible without the encryption keys.

 First, check the value of the [innodb\_fast\_shutdown](../innodb-system-variables/index#innodb_fast_shutdown) system variable with the [SHOW VARIABLES](../show-variables/index) statement. For example:

 
```
SHOW VARIABLES LIKE 'innodb_fast_shutdown';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_fast_shutdown |     2 |
+----------------------+-------+

```

When the value is set to `2`, InnoDB performs an unclean shutdown, so it will need the [Redo Log](../innodb-redo-log/index) at the next server startup. Ensure that the variable is set to `0`, `1`, or `3`. For performance reasons, `1` is usually the best option. It can be changed dynamically with [SET GLOBAL](../set/index#global-session). For example:

 
```
SET GLOBAL innodb_fast_shutdown = 1;

```

Then, set the [innodb\_encrypt\_log](../innodb-system-variables/index#innodb_encrypt_log) system variable to `OFF` in a server [option group](../configuring-mariadb-with-option-files/index#option-groups) in an [option file](../configuring-mariadb-with-option-files/index). Once this is done, [restart](../starting-and-stopping-mariadb-starting-and-stopping-mariadb/index) the MariaDB Server. When the Server comes back online, it begins writing unencrypted data to the Redo Log.

 ### See Also

 * [Enabling InnoDB encryption](../enabling-innodb-encryption/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/disabling-innodb-encryption/>

Recommended Settings for Benchmarks
===================================

    Running benchmarks requires a lot of different settings. In this article we collect our best known settings and recommendations.

 Hardware and BIOS Settings
--------------------------

 We have had good experiences with Intel's hyperthreading on newer Xeon CPUs. Please turn on hyperthreading in your BIOS.

 NUMA
----

 The NUMA architecture attaches resources (most important: memory) to individual NUMA nodes (typically: NUMA node = cpu socket). This results in a performance penalty when a cpu core from one NUMA node accesses memory from another NUMA node.

 The NUMA topology can be checked with the *numactl* command:

 
```
~ $numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 12 13 14 15 16 17
node 0 size: 12278 MB
node 0 free: 11624 MB
node 1 cpus: 6 7 8 9 10 11 18 19 20 21 22 23
node 1 size: 12288 MB
node 1 free: 11778 MB
node distances:
node   0   1 
  0:  10  21 
  1:  21  10 

```

The Linux kernel uses ACPI tables from BIOS to detect if the hardware is NUMA. On NUMA hardware extra optimizations kick in:

 * if a task has been scheduled on a certain NUMA node, the scheduler tries to put it on the same node again in the future

 * if a task running on a certain NUMA node allocates memory, the kernel tries hard to map physical memory from the same NUMA node

 This results in all kinds of weird behavior when you run one big process (mysqld) that consumes most of the memory. In such cases it is recommended to either turn off NUMA (BIOS or kernel command line) or prefix such problem processes with *numactl --interleave all*. You can enable this by running [mysqld\_safe](../mysqld_safe/index) with the `--numa-interleave` option.

 [More details can be found here](http://blog.jcole.us/2010/09/28/mysql-swap-insanity-and-the-numa-architecture/).

 Linux Kernel Settings
---------------------

 See [configuring Linux for MariaDB](../configuring-linux-for-mariadb/index).

 InnoDB Settings
---------------

 [innodb\_buffer\_pool\_size](../server-system-variables/index#innodb_buffer_pool_size) to about 80% of RAM or leaving <5G RAM free (on large RAM systems). Less if lots of connections are used.

 [innodb\_log\_file\_size](../server-system-variables/index#innodb_log_file_size) to be larger than the amount of writes in the test run or sufficient to cover several minutes of the test run at least.

 MyISAM Settings
---------------

 General Settings
----------------

 [threads\_cache\_size](../server-system-variables/index#threads_cache_size) should be the same as [max\_connections](../server-system-variables/index#max_connections) (unless using thread pools).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/recommended-settings-for-benchmarks/>

run-sql-bench.pl
================

    `run-sql-bench.pl` is a perl script for automating runs of sql-bench (You can find sql-bench in the [MariaDB source code](../getting-the-mariadb-source-code/index).)

 `run-sql-bench.pl` can be found in the [mariadb-tools](../mariadb-tools/index) project on Launchpad. Once you have a copy of mariadb-tools, you'll find the script, and its configuration directories, in the `sql-bench` directory. For the purposes of this article, wherever you located your local branch of `mariadb-tools` will be called `${BASE_DIR}`.

 The `run-sql-bench.pl` script is located at '`${BASE_DIR}/sql-bench/run-sql-bench.pl`'.

 Example configuration scripts used for different runs can be found in the various subdirectories of `${BASE_DIR}/sql-bench/`.

 To run the `run-sql-bench.pl` script, do the following:

 1. [Branch a MariaDB or MySQL tree](../getting-the-mariadb-source-code/index)
2. Optionally do some code changes in that tree and commit your changes
3. Edit `run-sql-bench.pl` to set internal options, especially the "`my $path`" variable.
4. Create a `${BASE_DIR}/sql-bench/conf/host.cnf` file for your system. An easy way to do this is by duplicating one of the example `host.cnf` files:
```
cp -avi ${BASE_DIR}/sql-bench/conf/pitbull.cnf ${BASE_DIR}/sql-bench/conf/${HOSTNAME}.cnf

```
Edit the file to customize it for your system.
5. Create `${HOSTNAME}.cnf` files under the `${BASE_DIR}/sql-bench/basic`, `${BASE_DIR}/sql-bench/debug`, `${BASE_DIR}/sql-bench/debug-full`, and `${BASE_DIR}/sql-bench/O2` directories, depending on which automated tests you want to run. Use the example files as a base and customize them for your system.
6. Run the `run-sql-bench.pl` script:
```
cd ${BASE_DIR}/sql-bench/; ./run-sql-bench.pl --repository=[/path/to/bzr/repository] --sql-bench-options=[additional sql-bench-options] --debug=[yes|no]

```

	* *``--`repository`* is the MariaDB tree to use and compile, the script will also look here for sql-bench.
	* *``--`sql-bench-options`* is mostly used in testing and debugging cases where we want to have short run times. For instance, using ``--`small-test` or ``--`small-table`.
	* You can separate several sql-bench options with spaces like so:
	```
	--sql-bench-options="--small-test --small-table"
	
	```

 The results
-----------

 Results are stored at the location specified by the `$sql\_bench\_results` variable in the `${BASE_DIR}/sql-bench/conf/hostname.cnf` file for your host. Results are organized in sub directories with the following schema:

 
```
sql-bench-results-dir/${HOSTNAME}/YYYY-MM-DD

```

Future plans
------------

 * Crash and error detection and reporting.
* One should be able to specify a test name for each file (`run-all-tests` ``--`suffix='_xxxx'`)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/run-sql-benchpl/>

Benchmark Builds
================

    When you build for benchmarks, it's important to use consistent compile time settings across different versions and even products (i.e. when comparing MySQL and MariaDB).

 MariaDB and MySQL are now built using *cmake*. This makes it hard to fine tune settings because when you chose a predefined build configuration (recommended: *RelWithDebInfo*) then other settings like *CFLAGS* are overwritten by those from the *CMakefile*. 

 There are more pain points with cmake:

 * cmake uses a different install layout than autotools builds
* the OQGraph engine is included by default, but fails often due to mismatching boost libraries
* make install tries to create directories in system locations (/etc/my.cnf.d etc.) which fails as ordinary user
* CMakefiles for different products sometimes use different CFLAGS

 So here is my build script that fixes all those things.

 
```
#!/bin/bash

INSTDIR=${1:?usage: $0 install-dir}

CFLAGS="-O3 -g -fno-omit-frame-pointer -fno-strict-aliasing -DNDEBUG -DDBUG_OFF"
CXXFLAGS="$CFLAGS -felide-constructors"

CMAKE_LAYOUT_OPTS="-DINSTALL_LAYOUT=RPM -DINSTALL_SCRIPTDIR=bin \
-DINSTALL_MYSQLDATADIR=var -DINSTALL_SBINDIR=libexec \
-DINSTALL_SUPPORTFILESDIR=share -DINSTALL_SYSCONFDIR=etc \
-DINSTALL_SYSCONF2DIR=etc/my.cnf.d -DCMAKE_INSTALL_PREFIX=$INSTDIR \
-DMYSQL_DATADIR=$INSTDIR/var"

CMAKE_FEATURE_OPTS="-DWITH_READLINE=1 -DWITHOUT_OQGRAPH_STORAGE_ENGINE=1"

CMAKE_BUILD_OPTS="-DCMAKE_BUILD_TYPE=RelWithDebInfo"

cmake .. $CMAKE_BUILD_OPTS $CMAKE_LAYOUT_OPTS $CMAKE_FEATURE_OPTS \
-DCMAKE_C_FLAGS_RELWITHDEBINFO="$CFLAGS" \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="$CXXFLAGS"

make && make install

```

The script shall be run from a subdir of a source tree. i.e.

 
```
tar xfz mariadb-10.0.7.tar.gz
cd mariadb-10.0.7
mkdir build
cd build
#... run the build script above

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benchmark-builds/>

DBT3 Benchmark Results InnoDB
=============================

    Introduction
------------

 This page shows the results for benchmarking the following configuration:

 * [MariaDB 5.3.1](https://mariadb.com/kb/en/mariadb-531-release-notes/) Beta + XtraDB with all optimizations (optimizater\_switch) set to `ON`
* [MariaDB 5.3.1](https://mariadb.com/kb/en/mariadb-531-release-notes/) Beta + XtraDB with Igor's suggested optimizations
* MySQL 5.5.13 + InnoDB
* MySQL 5.6.2 + InnoDB

 The test is performed using the automation script under `/mariadb-tools/dbt3_benchmark`.

 Details about this automation script could be found in [DBT3 automation scripts](../dbt3-automation-scripts/index)

 Hardware
--------

 The tests were performed on pitbull.askmonty.org. It has the following parameters: 

 * **CPU:** Two socket X hexacore Intel Xeon X5660 = 12 CPUs with hyperthreading on: 24 virtual CPUs
* **Memory:** 23GB
* **Logical disk:** HDD 500.1 GB as software RAID1
	+ device size with M = 1000\*1000: 500107 MBytes (500 GB)
	+ cache/buffer size = 16384 KBytes
	+ Nominal Media Rotation Rate: 7200
* **Operating System:** Ubuntu 10.10 (x86\_64)

 Scale factor 10
---------------

 This test is performed with the following parameters:

 * **Scale factor:** 10
* **Query timeout:** 600 sec.
* **Cluster size:** 3
* **Total DB size on disk:** about 24GB

 ### Steps to reproduce

 Follow the instructions in [DBT3 automation scripts](../dbt3-automation-scripts/index) to prepare the environment for the test.

 Before you run the test, reassure that the settings into the test configuration files match your prepared environment. For more details on the test configuration, please, refer to the [test configuration parameters](../dbt3-automation-scripts/index#test-configuration).

 For that test you should set the SCALE\_FACTOR parameter to 10 for the following files before the test:

 * mariadb\_innodb\_igor\_s1.pm
* mariadb\_innodb\_s1.pm
* mysql\_5\_5\_15\_innodb\_s1.pm
* mysql\_5\_6\_2\_innodb\_s1.pm

 **NOTE:** In future versions the scale factor will be passed in as an input parameter to `launcher.pl` instead of being test configuration parameter.

 After the environment is prepared, the following command should be executed in the shell:

 
```
perl launcher.pl --test={PROJECT_HOME}/mariadb-tools/dbt3_benchmark/tests/mariadb_myisam_s1.pm \
 --test={PROJECT_HOME}/mariadb-tools/dbt3_benchmark/tests/mysql_5_5_15_myisam_s1.pm \
 --test={PROJECT_HOME}/mariadb-tools/dbt3_benchmark/tests/mysql_5_6_2_myisam_s1.pm
 --results-output-dir=path/to/results/output/dir

```

### Results

 Here is the graphics of the results:

 ![innodb-test-scale-10-timeout-600](https://mariadb.com/kb/en/dbt3-benchmark-results-innodb/+image/innodb-test-scale-10-timeout-600 "innodb-test-scale-10-timeout-600")

 **NOTE:** Queries that are cut off by the graphics have timed out the period of 600 seconds for that test.

 Here are the actual results:

 


| Configuration | 1.sql | 2.sql | 3.sql | 4.sql | 5.sql | 6.sql | 7.sql | 8.sql | 9.sql | 10.sql | 11.sql | 12.sql | 13.sql | 14.sql | 15.sql | 16.sql | 17.sql | 18.sql | 19.sql | 20.sql | 21.sql | 22.sql |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| [MariaDB 5.3.1](https://mariadb.com/kb/en/mariadb-531-release-notes/) + XtraDB with all optimizations to ON | 165 | n/a | 424.333 | n/a | n/a | 114.333 | n/a | n/a | n/a | n/a | 536 | 173 | n/a | n/a | n/a | 52 | 452 | n/a | n/a | n/a | n/a | 8 |
| [MariaDB 5.3.1](https://mariadb.com/kb/en/mariadb-531-release-notes/) + XtraDB with Igor's suggestions for optimization | 163.667 | n/a | n/a | n/a | n/a | 114 | n/a | n/a | n/a | n/a | 538 | 280.667 | n/a | 257 | n/a | 60 | 456 | n/a | n/a | n/a | n/a | 8 |
| MySQL 5.5.15 + InnoDB | 104 | n/a | n/a | n/a | n/a | 103 | n/a | n/a | n/a | n/a | 534.667 | 177 | n/a | n/a | n/a | n/a | 476 | n/a | n/a | n/a | n/a | 6 |
| MySQL 5.6.2 + InnoDB | 103 | n/a | n/a | n/a | n/a | 104 | n/a | n/a | n/a | n/a | 531 | 168 | n/a | n/a | n/a | 55 | 460.667 | n/a | n/a | n/a | n/a | 6 |

 
The archived folder with all the results and details for that benchmark can be downloaded from: <http://askmonty.org/wiki/Image:Res_myisam_timeout_120_s10_2011-09-15_190613.zip>

 From the graphics we can see that for the first query MySQL has performed better than MariaDB with about 37%.

 For the third query on the other hand MariaDB with all optimizations set to ON is the only one query that returned results before the timeout exceeded. This means that it has at least 30% better performance. Also there is some option that could optimize Igor's set of settings even more for that query. For the particular numbers, the same test should be performed with longer timeouts.

 For query #6 it turns out that both MySQL 5.5.15 and 5.6.2 are faster than MariaDB with about 10%.

 For query #12 Igor's settings could be readjusted, so that the query execution time could fall with 38%.

 Igor's settings turned out to be the only one that could finish query #14 before the timeout exceeded.

 From query #16 we can see that MySQL have made a great performance improvement from version 5.5.15 to 5.6.2 to make the query finish at least ten times faster.

 For all the other queries the results are either statistically the same, or the queries have timed out for all configurations and the test should be repeated with longer timeout limit.

 Summary
-------

 Most of the queries have timed out for the given period of 10 minutes per query and until a new test with longer timeout is performed, no correct comparison summary could be made.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt3-benchmark-results-innodb/>

DBT3 Example Preparation Time
=============================

    This page contains database preparation and creation times that were discovered while working on the [DBT3 Automation Scripts](../dbt3-automation-scripts/index).

 Database creation times
-----------------------

 


| Setup | Time | Size on Disk |
| --- | --- | --- |
| Postgre s30 on pitbull | 758 min = 12 h 38 min. | 75 GB |
| MariaDB + MyISAM s10 on 4CPU 4GB RAM developer machine | 96 m 22s = 1h 36m 22s | 17 GB |
| MariaDB + MyISAM s100 on facebook-maria2: | 424m 4s = 7h 4m 4s. | 162 GB |
| MariaDB + InnoDB s100 on facebook-maria2: | 577m 42s = 9h 37m 42s. |  |
| [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) + InnoDB s30 on facebook-maria1 | 122m39.753s = 2h 2m 40s. | 71 GB |
| [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + InnoDB s30 on facebook-maria1 | 150m46.218s = 2h 30m 46s. | 71 GB |
| MySQL 5.6.4 + InnoDB s30 on facebook-maria1: | 140m18.272s = 2h 20m 18s. | 71 GB |
| MariaDB + MyISAM s30 on pitbull with pre\_create\_PK | > 3h 30m (with limited RAM to 11 GB) |  |
| MariaDB + MyISAM s30 on facebook-maria1: | 99m 8s = 1h 39m 8s. | 49 GB |
| MySQL 5.6.4 + MyISAM s30 on facebook-maria1 | 114m 17s. | 49 GB |

 
Dataload creation time
----------------------

 


| Setup | Time | Size on Disk |
| --- | --- | --- |
| Scale 10 on 4CPU 4GB RAM developer machine | 8 min 44 sec. | 10.4 GB |
| Scale 30 on pitbull.askmonty.org | 20 min 28 sec. | 32 GB (with limited RAM to 11 GB) |
| Scale 100 on facebook-maria2 | 78 min 27.601s. | 106 GB |
| Scale 30 on facebook-maria1 | 23 min 40 sec. |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt3-example-preparation-time/>

DBT3 Automation Scripts
=======================

     DBT-3 (OSDL Database Test 3) is a workload tool for the Linux kernel that OSDL (Open Source Development Labs, inc) developed based on TPC-H which is provided by the Transaction Performance Processing Council (TPC).

 DBT-3, like TPC-H, simulates an actual decision-making support system and models complex business analysis applications that perform data processing jobs for making better business decisions. By running the workload that DBT-3 simulates, it is possible to verify and measure the performances of the Linux kernel in an actual decision-making support system.

 DBT-3 uses the "scale factor (SF)" as a stress indicator of the system. By varying the SF, it becomes possible to make the size of a database the SF times its size.

 The tests performed by DBT-3 comprise the three tests listed below. DBT-3 obtains the execution times of these three tests as well as the system status information and database statistics information.

 1. **Load test**
	* Enters the data to be used for the Power and Throughput tests into the database. Makes a bulk insert of the huge CSV data corresponding to the scale factor into the database.

 2. **Power test**
	* Performs 22 complex queries.

 3. **Throughput test**
	* Performs the same 22 queries as in the Power test simultaneously in more than one process.

 For the purpose of this task, only the Power test is performed over preliminary prepared database with various Scale factors. The time for each query execution will be measured and stored into a database. Later the results of one whole test with all 22 queries will be rendered into a histogram graphics comparing it to different configurations.

 Benchmark environment preparation
---------------------------------

 ### sudo rights

 The user that will run the benchmark must have sudo rights on the machine.

 For clearing the system caches between query runs, the automation script uses the following command:

 
```
sudo /sbin/sysctl vm.drop_caches=3

```

This command must be run with superuser rights. Even if a user supplies a password to sudo, this password expires after some timeout. In order for this command to be run without requiring password, the following line should be added to the sudoers file (edit it with the `"sudo visudo"` command):

 
```
'your_username' ALL=NOPASSWD:/sbin/sysctl

```

...where `'your_username'` is the user that will run the benchmark.

 ### Required software

 The automated DBT3 benchmark requires the following software:

 * **[Perl](http://www.perl.org/)**
	+ **Project home:** <http://www.perl.org/>

 * **[mariadb-tools](https://launchpad.net/mariadb-tools)**
	+ **Project home:** <https://launchpad.net/mariadb-tools>
	+ The project folder is called "`dbt3_benchmark`" and is under `mariadb-tools`.

 * **[dbt3-1.9](http://sourceforge.net/projects/osdldbt/files/dbt3/)**
	+ **Download location:** <http://sourceforge.net/projects/osdldbt/files/dbt3/>

 * **[Gnuplot 4.4](http://www.gnuplot.info/)** — graphics output program.
	+ **Project home:** <http://www.gnuplot.info/>

 * **[Config::Auto](http://search.cpan.org/~simon/Config-Auto-0.03/Auto.pm)** — a Perl module that reads configuration files. To install it use the following command:
```
sudo cpan Config::Auto

```

 * **[DBD::mysql](http://search.cpan.org/~capttofu/DBD-mysql-4.020/lib/DBD/mysql.pm)** — a Perl module to connect to MariaDB/MySQL and PostgreSQL. To install it use the following command:
```
sudo cpan DBD::mysql

```

 **NOTE:** You may receive an error saying that CPAN could not find `mysql_config`. In this case you have to install the mysql client development library. In OpenSuse the command is: 



```
sudo zypper install libmysqlclient-devel

```
 Alternatively this module can be installed manually by following these steps:

 1. Download DBD-mysql-4.020.tar.gz from <http://search.cpan.org/~capttofu/DBD-mysql-4.020/lib/DBD/mysql.pm> and unpack it

 2. Run the perl script PerlMake.pl under the unzipped dir:
```
perl Makefile.PL --mysql_config=/path/to/some/mysql_binary_distribution/bin/mysql_config

```

 3. Run `make` to compile `DBD::mysql`:
```
make

```

 4. Add the necessary paths in order to run `DBD::mysql`:
```
export PERL5LIB="/path/to/unzipped_DBD_mysql/DBD-mysql-4.020/lib"
export LD_LIBRARY_PATH="/path/to/unzipped_DBD_mysql/DBD-mysql-4.020/blib/arch/auto/DBD/mysql/:/path/to/some/mysql_binary_distribution/lib/"

```

 ### Tested DBMS

 * **[MySQL 5.5.x](http://dev.mysql.com/downloads/mysql/#downloads)**
	+ **Download location:** <http://dev.mysql.com/downloads/mysql/#downloads> → Generally Available (GA) Releases → Linux - Generic 2.6 (x86, 64-bit), Compressed TAR Archive - downloads mysql-5.5.x-linux2.6-x86\_64.tar.gz - gzipped tar file for Linux x86

 * **[MySQL 5.6.x](http://dev.mysql.com/downloads/mysql/#downloads)**
	+ **Download location:** <http://dev.mysql.com/downloads/mysql/#downloads> → Development Releases → Linux - Generic 2.6 (x86, 64-bit), Compressed TAR Archive - downloads mysql-5.6.x-m5-linux2.6-x86\_64.tar.gz - gzipped tar file for Linux x86

 * **[MariaDB 5.3.x](https://launchpad.net/maria/5.3)**
	+ **Download location:** <https://launchpad.net/maria/5.3> , downloaded with Bazaar: 
	```
	bzr branch lp:maria/5.3
	
	```

 * **[MariaDB 5.5.x](https://launchpad.net/maria/5.3)**
	+ **Download location:** <https://launchpad.net/maria/5.5> , downloaded with Bazaar: 
	```
	bzr branch lp:maria/5.5
	
	```

 * **[PostgreSQL](http://www.postgresql.org/ftp/source/v9.1rc1/)**
	+ **Download location:** <http://www.postgresql.org/ftp/source/v9.1rc1/>

 **NOTE:** The DBT3 benchmark requires a lot of disk space (for example MySQL 5.5.x + MyISAM database with scale factor 30 takes about 50 GB). Also some queries require the utilization of temp tables under the directory set by the `--tmpdir` startup parameter passed to `mysqld`. In the prepared configuration files the temp directory is pointed to the `mysql` system directory of the binary distribution, but one should reassure that there is enough free space available for the temp directory.

 Installation instructions
-------------------------

 **NOTE:** The directory where all the files will be downloaded or installed will be referred as `$PROJECT_HOME`. This could be for example `~/benchmark/dbt3`.

 ### Download **[mariadb-tools](https://launchpad.net/mariadb-tools)**

 1. Go to your project folder
```
cd $PROJECT_HOME

```
2. Get the latest branch from LaunchPad with Bazaar:
```
bzr branch lp:mariadb-tools

```

 Now the project for the dbt3 benchmark test will be in the following dir:

 
```
$PROJECT_HOME/mariadb-tools/dbt3_benchmark/

```

The project `dbt3_benchmark` has the following directories and files:

 * **config** — a folder where the configuration files for MariaDB, MySQL and PostgreSQL are stored. They are divided into subfolders named '`sXX`', where `XX` is the scale factor.
* **dbt3\_mysql** — a folder with all the necessary files for preparing DBT3 databases and queries for the tests with MySQL and MariaDB
* **tests** — a folder where the different test configurations are stored. It contains the following directories:
	+ **db\_conf** — here are stored the database configuration files
	+ **queries\_conf** — here are stored the different queries configuration files
	+ **results\_db\_conf** — here is stored the configuration of the results database
	+ **test\_conf** — here are the test configurations
	+ **launcher.pl** — a perl script that automates the test. Details about calling and functionality of this file are listed later on this page.

 ### Prepare benchmark workload and queries

 For the purpose of the benchmark from [DBT3-1.9](http://sourceforge.net/projects/osdldbt/files/dbt3/) we will only need **DBGEN** and **QGEN**. DBGEN is a tool that generates a workload for the test and QGEN is a tool that generates the queries used for the test.

 1. Go to <http://sourceforge.net/projects/osdldbt/files/dbt3/>

 2. Download the archive for DBT3 1.9 into your project folder $PROJECT\_HOME

 3. Unzip the archive into your project folder
```
cd $PROJECT_HOME
tar -zxf dbt3-1.9.tar.gz

```

 4. Copy the file tpcd.h into the dbt3 folder. This step includes the necessary labels for MySQL/MariaDB when building queries.
```
cp $PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/tpcd.h $PROJECT_HOME/dbt3-1.9/src/dbgen/

```

 5. Copy the file Makefile under `$PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/` into the dbt3 folder

 * **NOTE:** This step is executed only if you want to overwrite the default behavior of PostgreSQL settings. After copying this Makefile and building the project, QGEN will be set to generate queries for MariaDB/MySQL. If you skip this step, QGEN will generate queries for PostgreSQL by default.
```
cp $PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/Makefile $PROJECT_HOME/dbt3-1.9/src/dbgen/

```

 6. Go to $PROJECT\_HOME/dbt3-1.9/src/dbgen and build the project
```
cd $PROJECT_HOME/dbt3-1.9/src/dbgen
make

```

 7. Set the variable DSS\_QUERY to the folder with template queries for MariaDB/MySQL or for PostgreSQL
	1. If you want to build the queries that fit MariaDB/MySQL dialect execute the following command:
	```
	export DSS_QUERY=$PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/mysql_queries/
	
	```
	2. If you want to use the default PostgreSQL templates, execute the following command:
	```
	export DSS_QUERY=$PROJECT_HOME/dbt3-1.9/queries/pgsql/
	
	```

 8. Create a directory to store the generated queries in
```
mkdir $PROJECT_HOME/gen_query

```

 9. Generate the queries

 
 **NOTE:** The examples use scale factor 30. If you want different scale, change the value of `-s` parameter

  * ```
cd $PROJECT_HOME/dbt3-1.9/src/dbgen
./qgen -s 30 1 > $PROJECT_HOME/gen_query/s30-m/1.sql
./qgen -s 30 2 > $PROJECT_HOME/gen_query/s30-m/2.sql
./qgen -s 30 3 > $PROJECT_HOME/gen_query/s30-m/3.sql
./qgen -s 30 4 > $PROJECT_HOME/gen_query/s30-m/4.sql
./qgen -s 30 5 > $PROJECT_HOME/gen_query/s30-m/5.sql
./qgen -s 30 6 > $PROJECT_HOME/gen_query/s30-m/6.sql
./qgen -s 30 7 > $PROJECT_HOME/gen_query/s30-m/7.sql
./qgen -s 30 8 > $PROJECT_HOME/gen_query/s30-m/8.sql
./qgen -s 30 9 > $PROJECT_HOME/gen_query/s30-m/9.sql
./qgen -s 30 10 > $PROJECT_HOME/gen_query/s30-m/10.sql
./qgen -s 30 11 > $PROJECT_HOME/gen_query/s30-m/11.sql
./qgen -s 30 12 > $PROJECT_HOME/gen_query/s30-m/12.sql
./qgen -s 30 13 > $PROJECT_HOME/gen_query/s30-m/13.sql
./qgen -s 30 14 > $PROJECT_HOME/gen_query/s30-m/14.sql
./qgen -s 30 15 > $PROJECT_HOME/gen_query/s30-m/15.sql
./qgen -s 30 16 > $PROJECT_HOME/gen_query/s30-m/16.sql
./qgen -s 30 17 > $PROJECT_HOME/gen_query/s30-m/17.sql
./qgen -s 30 18 > $PROJECT_HOME/gen_query/s30-m/18.sql
./qgen -s 30 19 > $PROJECT_HOME/gen_query/s30-m/19.sql
./qgen -s 30 20 > $PROJECT_HOME/gen_query/s30-m/20.sql
./qgen -s 30 21 > $PROJECT_HOME/gen_query/s30-m/21.sql
./qgen -s 30 22 > $PROJECT_HOME/gen_query/s30-m/22.sql

```

 10. Generate the explain queries
```
./qgen -s 30 -x 1 > $PROJECT_HOME/gen_query/s30-m/1_explain.sql
./qgen -s 30 -x 2 > $PROJECT_HOME/gen_query/s30-m/2_explain.sql
./qgen -s 30 -x 3 > $PROJECT_HOME/gen_query/s30-m/3_explain.sql
./qgen -s 30 -x 4 > $PROJECT_HOME/gen_query/s30-m/4_explain.sql
./qgen -s 30 -x 5 > $PROJECT_HOME/gen_query/s30-m/5_explain.sql
./qgen -s 30 -x 6 > $PROJECT_HOME/gen_query/s30-m/6_explain.sql
./qgen -s 30 -x 7 > $PROJECT_HOME/gen_query/s30-m/7_explain.sql
./qgen -s 30 -x 8 > $PROJECT_HOME/gen_query/s30-m/8_explain.sql
./qgen -s 30 -x 9 > $PROJECT_HOME/gen_query/s30-m/9_explain.sql
./qgen -s 30 -x 10 > $PROJECT_HOME/gen_query/s30-m/10_explain.sql
./qgen -s 30 -x 11 > $PROJECT_HOME/gen_query/s30-m/11_explain.sql
./qgen -s 30 -x 12 > $PROJECT_HOME/gen_query/s30-m/12_explain.sql
./qgen -s 30 -x 13 > $PROJECT_HOME/gen_query/s30-m/13_explain.sql
./qgen -s 30 -x 14 > $PROJECT_HOME/gen_query/s30-m/14_explain.sql
./qgen -s 30 -x 15 > $PROJECT_HOME/gen_query/s30-m/15_explain.sql
./qgen -s 30 -x 16 > $PROJECT_HOME/gen_query/s30-m/16_explain.sql
./qgen -s 30 -x 17 > $PROJECT_HOME/gen_query/s30-m/17_explain.sql
./qgen -s 30 -x 18 > $PROJECT_HOME/gen_query/s30-m/18_explain.sql
./qgen -s 30 -x 19 > $PROJECT_HOME/gen_query/s30-m/19_explain.sql
./qgen -s 30 -x 20 > $PROJECT_HOME/gen_query/s30-m/20_explain.sql
./qgen -s 30 -x 21 > $PROJECT_HOME/gen_query/s30-m/21_explain.sql
./qgen -s 30 -x 22 > $PROJECT_HOME/gen_query/s30-m/22_explain.sql

```

 Now the generated queries for MariaDB/MySQL test are ready and are stored into the folder `$PROJECT_HOME/gen_query/s30-m/` (-m is for MariaDB/MySQL).

 Additional reorganization of directories is up to the user.

 11. Create a directory for the generated workload
```
mkdir $PROJECT_HOME/gen_data/s30

```

 12. Set the variable DSS\_PATH to the folder with the generated table data. The generated workload for the test will be generated there.
```
export DSS_PATH=$PROJECT_HOME/gen_data/s30/

```

 13. Generate the table data

 * **NOTE:** The example uses scale factor = `30`. If you want to change it, you should change the parameter `-s`.
```
./dbgen -vfF -s 30

```

 * Now the generated data load is stored into the folder set in `$DSS_PATH = $PROJECT_HOME/gen_data/`

 For the purpose of this benchmark these steps have been performed for scale factor 30 and are stored on facebook-maria1 in the following locations:

 * `/benchmark/dbt3/gen_data/s30` — the data load for scale factor 30
* `/benchmark/dbt3/gen_query/s30-m` — generated queries for MariaDB/MySQL with scale factor 30
* `/benchmark/dbt3/gen_query/s30-p` — generated queries for PostgreSQL with scale factor 30

 See [DBT3 example preparation time](../dbt3-example-preparation-time/index) to see how long it would take you to prepare the databases for the test.

 ### Download **[MySQL 5.5.x](http://dev.mysql.com/downloads/mysql/#downloads)**

 1. Download the tar.gz file into your project folder `$PROJECT_HOME/bin/` for example

 2. Unzip the archive with the following command:
```
gunzip < mysql-5.5.x-linux2.6-x86_64.tar.gz |tar xf -

```

 Now the server could be started with the following command:



```
$PROJECT_HOME/bin/mysql-5.5.x-linux2.6-x86_64/bin/mysqld_safe --datadir=some/data/dir &

```
 ### Download **[MySQL 5.6.x](http://dev.mysql.com/downloads/mysql/#downloads)**

 1. Download the tar.gz file into your project folder `$PROJECT_HOME/bin/` for example

 2. Unzip the archive with the following command:
```
gunzip < mysql-5.6.x-m5-linux2.6-x86_64.tar.gz |tar xf -

```

 Now the server could be started with the following command:

 
```
$PROJECT_HOME/bin/mysql-5.6.x-m5-linux2.6-x86_64/bin/mysqld_safe --datadir=some/data/dir &

```

### Download and build [MariaDB 5.3](../what-is-mariadb-53/index).x / [MariaDB 5.5](../what-is-mariadb-55/index).x

 **NOTE:** These steps are the same for [MariaDB 5.5](../what-is-mariadb-55/index).x with properly replaced version numbers

 1. Download with Bazaar the [mariadb 5.3](../what-is-mariadb-53/index) project
```
bzr branch lp:maria/5.3
mv 5.3/ mariadb-5.3

```

 2. Build MariaDB
```
cd mariadb-5.3/
./BUILD/compile-amd64-max

```

 3. Build a binary distribution tar.gz file
```
./scripts/make_binary_distribution

```

 4. Move the generated tar.gz file and unzip it to $PROJECT\_HOME/bin from where it will be used by the automation script
```
mv mariadb-5.3.x-beta-linux-x86_64.tar.gz $PROJECT_HOME/bin/
cd $PROJECT_HOME/bin/
tar -xf mariadb-5.3.x-beta-linux-x86_64.tar.gz

```

 Now the server could be started with the following command:



```
$PROJECT_HOME/bin/mariadb-5.3.x-beta-linux-x86_64/bin/mysqld_safe --datadir=some/data/dir &

```
 ### Prepare the databases for the benchmark

 **NOTE:** These instructions are the same for MariaDB, MySQL 5.5.x and MySQL 5.6.x with changing only the database home folders, noted here as $DB\_HOME (for example for MySQL 5.5.x $DB\_HOME is `$PROJECT_HOME/bin/mysql-5.5.x-linux2.6-x86_64`). Also you can prepare InnoDB storage engine test databases. Instructions for preparing PostgreSQL could be found in the section for downloading, building and preparing PostgreSQL later on this page.

 1. Open the file `$PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/make-dbt3-db_innodb.sql` and edit the values for the call of the sql commands that look like this one:
```
LOAD DATA INFILE '/some/path/to/gen_data/nation.tbl' into table nation fields terminated by '|';

```

 * They all look the same but operate with different tables.

 * Replace "/some/path/to/gen\_data/" with the proper directory where the generated data load is stored. At the end the same command could look like this:
```
LOAD DATA INFILE '~/benchmark/dbt3/gen_data/s30/nation.tbl' into table nation fields terminated by '|';

```

 2. Create an empty MySQL database into a folder that will be used for the benchmark
```
cd $DB_HOME
./scripts/mysql_install_db --defaults-file=$PROJECT_HOME/mariadb-tools/dbt3_benchmark/config/s30/load_mysql_myisam_my.cnf --basedir=$DB_HOME --datadir=$PROJECT_HOME/db_data/myisam-s30/

```

 * **NOTE:** For InnoDB change the defaults-file to `load_mysql_innodb_my.cnf`.

 3. Start the mysqld process`./bin/mysqld_safe --defaults-file=$PROJECT_HOME/mariadb-tools/dbt3_benchmark/config/s30/load_mysql_myisam_my.cnf --tmpdir=$PROJECT_HOME/temp/ --socket=$PROJECT_HOME/temp/mysql.sock --datadir=$PROJECT_HOME/db_data/myisam-s30/ &`

 * **NOTE:** For InnoDB change the defaults-file to `load_mysql_innodb_my.cnf`. Also make sure that you have enough space in the directory set by the parameter `--tmpdir`, since loading the database could take a lot of temporary space.

 4. Load the data into the database by executing the file `make-dbt3-db_pre_create_PK.sql` (for InnoDB) or `make-dbt3-db_post_create_PK.sql` (for MyISAM)`./bin/mysql -u root -S $PROJECT_HOME/temp/mysql.sock < $PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/make-dbt3-db_post_create_PK.sql`

 * **NOTE:** For faster creation, it is recommended to use `make-dbt3-db_pre_create_PK.sql` for loading InnoDB and `make-dbt3-db_post_create_PK.sql` for loading MyISAM databases.

 5. Shutdown the database server:
```
./bin/mysqladmin --user=root --socket=$PROJECT_HOME/temp/mysql.sock shutdown 0

```

 Now you have a database loaded with scale 30. Its datadir is `$PROJECT_HOME/db_data/myisam-s30/`

 The same steps can be reproduced for different scale factors and for different storage engines.

 ### Download, build and prepare **[PostgreSQL](http://www.postgresql.org/ftp/source/v9.1rc1/)**

 1. Go to <http://www.postgresql.org/ftp/source/v9.1rc1/>

 2. Download the file under the link postgresql-9.1rc1.tar.gz

 3. Unzip the archive to your project folder
```
gunzip < postgresql-9.1rc1.tar.gz |tar xf -

```

 4. Execute the following commnads into the shell to install PostgreSQL:
```
mkdir $PROJECT_HOME/PostgreSQL_bin
cd $PROJECT_HOME/postgresql-9.1rc1 
./configure --prefix=$PROJECT_HOME/bin/PostgreSQL_bin 
make
make install

```

 * **NOTE:** Configure script may not find the following libraries: readline and zlib. In that case you can run configure without these libraries by adding the following parameters to the command line: `--without-readline --without-zlib`

 5. Prepare the database to test with:
```
mkdir $PROJECT_HOME/db_data/postgre_s30
cd $PROJECT_HOME/bin/PostgreSQL_bin
./bin/initdb -D $PROJECT_HOME/db_data/postgre_s30

```

 6. Start the server:
```
./bin/postgres -D $PROJECT_HOME/db_data/postgre_s30 -p 54322 &

```

 7. Load the dataload into the DB
```
./bin/createdb -O {YOUR_USERNAME} dbt3 -p 54322
./bin/psql -p 54322 -d dbt3 -f $PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/make-dbt3-db_pg.sql

```

 * **NOTE:** Here under `{YOUR_USERNAME}` you should put the database owner.

 8. Stop the server:

 
```
./bin/pg_ctl -D $PROJECT_HOME/db_data/postgre_s30/ -p 54322 stop

```

The steps for preparing the workload for the benchmark on facebook-maria1 are already made for MariaDB, MySQL and PostgreSQL. Here are the directories for the different DBMS, storage engines and scale factors that are prepared on facebook-maria1:

 * `~/benchmark/dbt3/db_data/myisam_s30` — datadir for MariaDB/MySQL + MyISAM with scale factor 30

 * `~/benchmark/dbt3/db_data/innodb_mariadb_s30` — datadir for MariaDB + InnoDB with scale factor 30 (TODO)

 * `~/benchmark/dbt3/db_data/innodb_mysql_s30` — datadir for MySQL + InnoDB with scale factor 30 (TODO)

 * `~/benchmark/dbt3/db_data/postgre_s30` — datadir for PostgreSQL with scale factor 30 (TODO)

 ### Prepare the results database

 The results of the benchmark will be stored in a separate database that will be run by [MariaDB 5.3](../what-is-mariadb-53/index).x.

 **NOTE:** The results database will be a subject to change in future versions of the DBT3 benchmarking project. 

 The database is created by the file `$PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/make-results-db.sql`. In that file you can find details about every table and column in the database.

 To prepare the database for work follow these steps:

 1. Go to [MariaDB 5.3](../what-is-mariadb-53/index).x installation directory
```
cd $PROJECT_HOME/bin/mariadb-5.3.x-beta-linux-x86_64

```

 2. Install the system database tables into the datadir for the results (for example `$PROJECT_HOME/db_data/dbt3_results_db`)
```
./scripts/mysql_install_db --datadir=$PROJECT_HOME/db_data/dbt3_results_db

```

 3. Start mysqld for results db
```
./bin/mysqld_safe --defaults-file=$PROJECT_HOME/mariadb-tools/dbt3_benchmark/config/results_mariadb_my.cnf --port=12340 --socket=$PROJECT_HOME/temp/mysql_results.sock  --datadir=$PROJECT_HOME/db_data/dbt3_results_db/ &

```

 4. Install the database
```
./bin/mysql -u root -P 12340 -S $PROJECT_HOME/temp/mysql_results.sock < $PROJECT_HOME/mariadb-tools/dbt3_benchmark/dbt3_mysql/make-results-db.sql

```

 5. Shutdown the results db server:
```
./bin/mysqladmin --user=root --port=12340 --socket=$PROJECT_HOME/temp/mysql_results.sock shutdown 0

```

 Automation script
-----------------

 ### Configuring and running a benchmark

 In order to run a benchmark, one should have:

 * 5 configuration files:
	1. **DBMS** server configuration (see <#dbms-server-configuration>)
	2. **Test** configuration (see <#test-configuration>)
	3. **Queries** configuration (see <#queries-configuration>)
	4. **Results database** configuration (see <#results-database-configuration>)
	5. **Top-level** configuration file that combines all of the above (see <#top-level-configuration>)
* an **automation script `launcher.pl`** that could be found under `mariadb-tools/dbt3_benchmark/`
* **startup parameters** that should be passed to the automation script (see <#script-startup-parameters>).

 Details about each of these is given in the following sections.

 Each benchmark is configured by a set of configuration files. One can find example (default) configuration files under the directory 'mariadb-tools/dbt3\_benchmark/tests'. Each configuration file has an 'ini' configuration syntax and is parsed by the perl automation script with the CPAN module [Config::Auto](http://search.cpan.org/~simon/Config-Auto-0.03/Auto.pm)

 #### Configuration keywords

 Every configuration file could contain keywords that will be replaced by the script with particular values. They are used for convenience when you want to make your configuration files more common to the environment that you have prepared for the benchmark. These keywords are:

 * `$PROJECT_HOME` — used as the directory where the project '`mariadb-tools`' is located or as a base path for the whole project (e.g. "`DBMS_HOME = $PROJECT_HOME/bin/mariadb-5.3.x-beta-linux-x86_64`"). It is replaced by the value set with the startup parameter **'project-home**' passed to **launcher.pl**,

 * `$DATADIR_HOME` — used as the directory where the datadir folders are located for the benchmark (e.g. "`$DATADIR_HOME/myisam-s30`"). It is replaced by the value set with the startup parameter **'datadir-home'** passed to **launcher.pl**.

 * `$QUERIES_HOME` — used as the directory where the queries are located (e.g. "`$QUERIES_HOME/s30-m`" — queries for MariaDB/MySQL for scale factor 30). It is replaced by the value set with the startup parameter **'queries-home'** passed to **launcher.pl**.

 * `$SCALE_FACTOR` — the scale factor that will be used. It is usually a part of the name of the datadir directory (e.g. "`$DATADIR_HOME/myisam-s$SCALE_FACTOR`"), the queries directory (e.g. "`$QUERIES_HOME/s$SCALE_FACTOR-m`") or the database configuration directory (e.g. `$PROJECT_HOME/mariadb-tools/dbt3_benchmark/config/s$SCALE_FACTOR`). It is replaced by the value set with the startup parameter **'scale-factor'** passed to **launcher.pl**.

 Note that if any of the configuration files contains such keyword, the corresponding startup parameter passed to **launcher.pl** will become required.

 #### Top-level configuration

 A top-level configuration file provides paths to the **Test, DBMS, Queries** and **Results database** configurations files

 There are default configuration files in the directory `mariadb-tools/dbt3_benchmark/tests/` and contain the following settings:

 


| Parameter | Description |
| --- | --- |
| `RESULTS_DB_CONFIG` | The configuration file for results DB settings |
| `TEST_CONFIG` | The configuration file for the test settings |
| `QUERIES_CONFIG` | The configuration file for the queries settings |
| `DB_CONFIG` | The configuration file for the DBMS server settigns |

 
This file has the following format:

 
```
[common]
RESULTS_DB_CONFIG  = $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/results_db_conf/results_db.conf
TEST_CONFIG        = $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/test_conf/test_myisam.conf

[mariadb_5_3]
QUERIES_CONFIG 	= $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/queries_conf/queries.conf
DB_CONFIG 	= $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/db_conf/db_mariadb_5_3_myisam.conf

[mysql_5_5]
QUERIES_CONFIG 	= $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/queries_conf/queries_mysql.conf
DB_CONFIG 	= $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/db_conf/db_mysql_5_5_myisam.conf
...

```

**NOTE:** The settings `RESULTS_DB_CONFIG` and `TEST_CONFIG` should be set under the `[common]` section. They are common for the whole test (although some settings from `TEST_CONFIG` could be overridden in the `QUERIES_CONFIG` file). All settings that combine `QUERIES_CONFIG` and `DB_CONFIG` should be in a separate section (e.g. `[mariadb_5_3]`).

 A test configuration is passed as an input parameter to the automation script with the parameter `--test=/path/to/some_test_configuration.conf` (see <#script-startup-parameters>)

 #### DBMS server configuration

 These configuration files contain settings that describe the benchmarked DBMS. They are usually contained into the folder `mariadb-tools/dbt3_benchmark/tests/db_conf`.

 Here is the list of parameters that could be set into this configuration file:

 


| Parameter | Description |
| --- | --- |
| `DBMS_HOME` | Where the instalation folder of MariaDB / MySQL / PostgreSQL is located.**NOTE:** The automation script uses "`./bin/mysqld_safe`" to start the `mysqld` process. So the versions of MariaDB and MySQL should be a "binary distribution" ones. |
| `DBMS_USER` | The database user that will be used. |
| `CONFIG_FILE` | The config file that mysqld or postgres will use when starting |
| `SOCKET` | The socket that will be used to start the server |
| `PORT` | The port that the server will be started on |
| `HOST` | The host where the server is located |
| `DATADIR` | Where the datadir for mysqld or postgres is located |
| `TMPDIR` | Where the temp tables will be created while sorting and grouping. |
| `DBNAME` | The database (schema) name where the benchmark tables are located. |
| `KEYWORD` | This text will be stored into the results database as a keyword. Also will be used as a name for a subfolder with results and statistics. |
| `DBMS` | Database Management System that will be used. Possible values: "MySQL", "MariaDB" and "PostgreSQL" |
| `STORAGE_ENGINE` | The storage engine that was used (MyISAM, InnoDB, etc.) |
| `STARTUP_PARAMS` | Any startup parameters that will be used while starting the mysqld process or postgres process. Same format as given on the command line. |
| `GRAPH_HEADING` | The heading of the graphic for that particular test. |
| `MYSQL_SYSTEM_DIR` | See *"`MYSQL_SYSTEM_DIR` note"*, below. |
| `READ_ONLY` | If set to 1, mysqld process will be started with '`--read-only`' startup parameter |
| `PRE_RUN_SQL` | SQL commands that are run prior each query run |
| `POST_RUN_SQL` | SQL commands that are run after each query run |
| `PRE_TEST_SQL` | SQL commands that are run prior the whole test with that database settings |
| `POST_TEST_SQL` | SQL commands that are run after the whole test with that database settings |

 

**`MYSQL_SYSTEM_DIR` note:**  
  


 This option is added for convenience when you want to save time and disk space for generating databases for different DBMS (and different versions) and use a single data directory for all of them. When running different versions of MariaDB/MySQL over a single datadir, one should run [mysql-upgrade](http://dev.mysql.com/doc/refman/5.5/en/mysql-upgrade.html) in order to fix the system tables. So in one data directory, you could prepare the following directories for different MariaDB/MySQL system directories:   
  


 * `mysql_mysql_5_5` — a copy of the system directory '`mysql`' upgraded by MySQL 5.5.x
* `mysql_mariadb_5_3` — a copy of the system directory '`mysql`' upgraded by [MariaDB 5.3](../what-is-mariadb-53/index).x
* `mysql_mariadb_5_5` — a copy of the system directory '`mysql`' upgraded by [MariaDB 5.5](../what-is-mariadb-55/index).x

 If `MYSQL_SYSTEM_DIR` is set to one of these directories, the automation script will unlink the current system directory 'mysql' and make a new symbolic link with that name to the one in the setting.  
  


 Here is an example command that will be executed:   


 
```
unlink /path/to/datadir/mysql
ln -s /path/to/value/in/MYSQL_SYSTEM_DIR/mysql_mariadb_5_3 /path/to/datadir/mysql

```

  
 **NOTE:** This approach is suitable for MyISAM tests.

 
The configuration file looks like this:

 
```
[db_settings]
DBMS_HOME	= $PROJECT_HOME/bin/mariadb-5.3.2-beta-linux-x86_64
DBMS_USER	= root
...

```

Note that the section `[db_settings]` is required for the file to be properly parsed by the automation script.

 #### Test configuration

 These configuration files contain settings describing the test. They are usually contained into the folder **mariadb-tools/dbt3\_benchmark/tests/test\_conf**. 

 Here is the list of parameters that could be set into this configuration file:

 


| Parameter | Description |
| --- | --- |
| `QUERIES_AT_ONCE` | If set to `1`, then all the queries are executed sequentially without restarting the server or clearing the caches between queries. |
| `CLEAR_CACHES` | If set to `1`, the disk caches will be cleared before each query test. |
| `WARMUP` | Perform a warm-up runs before running the query. |
| `EXPLAIN` | Run an Explain command prior the run of the query. The explain results will be stored in a file under the results output directory. |
| `RUN` | Perform the actual test |
| `ANALYZE_EXPLAIN` | A result extraction mechanism where only the best execution plan (results from `EXPLAIN` select) will be measured. It is designed to be used when benchmarking InnoDB storage engine where execution plan is changing between server restarts (see <#results-extraction-mechanisms>). |
| `MIN_MAX_OUT_OF_N` | A result extraction mechanism where the minimal and maximal values out of `N` (set by the parameter `NUM_TESTS`) tests are taken as a result. This could be used when InnoDB storage engine is tested (see <#results-extraction-mechanisms>). |
| `SIMPLE_AVERAGE` | A result extraction mechanism where the final result is the average time taken for the tests. The number of tests is per query is set by the NUM\_TESTS parameter. Note that if even one test has timed out, the result is 'time-out'. This is used when testing MyISAM storage engine since there the execution plan is constant (see <#results-extraction-mechanisms>). |
| `NUM_TESTS` | How many tests should be performed for each query. When ANALYZE\_EXPLAIN is set, this value could be set to 0, meaning that the tests will continue until enough results are extracted (see setting `CLUSTER_SIZE`). This parameter is very important when `MIN_MAX_OUT_OF_N` or `SIMPLE_AVERAGE` is selected. |
| `MAX_SKIPPED_TESTS` | When ANALYZE\_EXPLAIN is set and an execution plan that is slower is selected, the execution of the query is skipped and the server is restarted in order to change the execution plan. If the server is restarted more than `MAX_SKIPPED_TESTS`, there are obviously no more different execution plans and the script continues to the next query benchmark. |
| `WARMUPS_COUNT` | How many warmup runs will be performed prior the actual benchmark run. |
| `CLUSTER_SIZE` | How big a cluster with results for a query should be in order to extract the final result. It is used when `ANALYZE_EXPLAIN` is selected as a result extraction method. |
| `MAX_QUERY_TIME` | The maximum time that one query will be tested. Currently it is applicable only when `ANALYZE_EXPLAIN` is selected. |
| `TIMEOUT` | The maximum time that one query could run. Currently timeout is applicable only for MySQL and MariaDB. |
| `OS_STATS_INTERVAL` | What is the time interval between extraction of OS statistics for CPU, memory, etc. |
| `PRE_RUN_OS` | OS commands that should be executed prior each query run |
| `POST_RUN_OS` | OS commands that should be executed after each query run |
| `PRE_TEST_OS` | OS commands that should be executed prior the whole test |
| `POST_TEST_OS` | OS commands that should be executed after the whole test is complete |

 
The configuration file looks like this:

 
```
QUERIES_AT_ONCE = 0
CLEAR_CACHES	= 1
WARMUP		= 0
...

```

#### Queries configuration

 These configuration files contain the list of all the queries that will be benchmarked against each database. Some settings from `DBMS server configuration` and `Test configuration` could be overridden into the `Queries configuration` files. The folder that contains such configurations is `mariadb-tools/dbt3_benchmark/tests/queries_conf`.

 Here is the list of parameters that could be set into this configuration file:

 


| Parameter | Description |
| --- | --- |
| `QUERIES_HOME` | Where the queries are located on disk. This value is concatenated to the `QUERY` setting and this makes the path to the particular query. **NOTE:** This setting should be set under the section `[queries_settings]`. |
| `CONFIG_FILE` | This overrides the startup setting `CONFIG_FILE` from **DMBS server** configuration file and sets the database configuration file that is used. It could be used if some configuration file without any optimizations should be set for this particular queries configuration file.**NOTE:** This setting should be set under the section `[queries_settings]`. |
| `QUERY` | The name of the query located into `QUERIES_HOME` folder. E.g. "1.sql" |
| `EXPLAIN_QUERY` | The name of the explain query into `QUERIES_HOME` folder. E.g. "1\_explain.sql" |
| `TMPDIR` | This overrides the setting TMPDIR from the `DMBS server` configuration. |
| `STARTUP_PARAMS` | This overrides the setting `STARTUP_PARAMS` from the `DMBS server` configuration. Using this setting one could change the particular startup parameters (like optimizations and buffers) for the DB server. |
| `PRE_RUN_SQL` | This overrides the setting `PRE_RUN_SQL` from the **DMBS server** configuration. |
| `POST_RUN_SQL` | This overrides the setting `POST_RUN_SQL` from the **DMBS server** configuration. |
| `RUN` | This overrides the setting `RUN` from the **test** configuration. |
| `EXPLAIN` | This overrides the setting `EXPLAIN` from the **test** configuration. |
| `TIMEOUT` | This overrides the setting `TIMEOUT` from the **test** configuration. |
| `NUM_TESTS` | This overrides the setting `NUM_TESTS` from the **test** configuration. |
| `MAX_SKIPPED_TESTS` | This overrides the setting `MAX_SKIPPED_TESTS` from the **test** configuration. |
| `WARMUP` | This overrides the setting `WARMUP` from the **test** configuration. |
| `WARMUPS_COUNT` | This overrides the setting `WARMUPS_COUNT` from the **test** configuration. |
| `MAX_QUERY_TIME` | This overrides the setting `MAX_QUERY_TIME` from the **test** configuration. |
| `CLUSTER_SIZE` | This overrides the setting `CLUSTER_SIZE` from the **test** configuration. |
| `PRE_RUN_OS` | This overrides the setting `PRE_RUN_OS` from the **test** configuration. |
| `POST_RUN_OS` | This overrides the setting `POST_RUN_OS` from the **test** configuration. |
| `OS_STATS_INTERVAL` | This overrides the setting `OS_STATS_INTERVAL` from the **test** configuration. |

 
The queries configuration file could look like this:

 
```
[queries_settings]
QUERIES_HOME = /path/to/queries

[query1]
QUERY=1.sql
EXPLAIN_QUERY=1_explain.sql
STARTUP_PARAMS=

[query2]
QUERY=2.sql
EXPLAIN_QUERY=2_explain.sql
STARTUP_PARAMS=--optimizer_switch='mrr=on' --mrr_buffer_size=8M --some_startup_parmas
...

```

...where "`QUERIES_HOME = /path/to/queries`" could be replaced with "`QUERIES_HOME = $QUERIES_HOME/s$SCALE_FACTOR-m`" for example and thus `$QUERIES_HOME` and $SCALE\_FACTOR will be replaced by the script startup parameters passed to `launcher.pl` (see <#script-startup-parameters>)

 **NOTE:** The section `[queries_settings]` is required for the configuration file to be parsed correctly. Also each query settings should be set under an uniquely named configuration section (e.g. `[query1]` or `[1.sql]`)

 #### Results database configuration

 These configuration files contain settings about the database where the results will be stored. They are usually contained into the folder `mariadb-tools/dbt3_benchmark/tests/results_db_conf`.

 Here is the list of parameters that could be set into this configuration file:

 


| Parameter | Description |
| --- | --- |
| `DBMS_HOME` | Where the database directory is located. E.g. "`$PROJECT_HOME/mariadb-5.3.x-beta-linux-x86_64`". This should be a binary distribution of MariaDB or MySQL. |
| `DBMS_USER` | The user that will be used by the DBMS |
| `DATADIR` | Where the data directory is located for the results database |
| `CONFIG_FILE` | What the configuration file used by the database is. |
| `SOCKET` | The socket that will be used by the results database. This should be different socket than the one provided for the testing databases. |
| `PORT` | The port that the results database will use. This should be different port than the one provided for the testing databases. |
| `STARTUP_PARAMS` | Any startup parameters that should be set to start the server. |
| `DBNAME` | The database name to use. |
| `HOST` | The host where the results database is. |

 
The results database configuration could look like this:

 
```
DBMS_HOME	= $PROJECT_HOME/mariadb-5.3.x-beta-linux-x86_64
DBMS_USER	= root
...

```

#### Script startup parameters

 `launcher.pl` could accept startup parameters called in the manner "`--some-param`". Note that these startup parameters are case-sensitive. The ones that are with upper-case are used when overriding a setting in some of the configuration files.

 Here is a list of the startup parameters:

 


| Parameter | Description |
| --- | --- |
| `test` | The top-level benchmark configuration file that will be run. This is a **required** startup parameter. |
| `results-output-dir` | Where the results of the benchmark will be stored. A timestamp is automatically attached to the directory name so that it keeps track of time and date of the benchmark. This is a **required** parameter. |
| `dry-run` | If set, no benchmark will be performed. Instead only messages will be displayed for the actions that were intended to be done. |
| `project-home` | Required if any configuration file uses the variable '`$PROJECT_HOME`'. If all configuration files use absolute paths, not used. |
| `datadir-home` | The value in this parameter will replace any occurrences of the string '`$DATADIR_HOME`' into the configuration files. If there are no such occurances, it is not a required parameter. |
| `queries-home` | The value in this parameter will replace any occurrences of the string '`$QUERIES_HOME`' into the configuration files. If there are no such occurances, it is not a required parameter. |
| `scale-factor` | The value in this parameter will replace any occurrences of the string '`$SCALE_FACTOR`' into the configuration files. If there are no such occurances, it is not a required parameter. |
| `CLEAR_CACHES` | If set. this overrides the default setting set into the **test** configuration file. |
| `QUERIES_AT_ONCE` | If set. this overrides the default setting set into the **test** configuration file. |
| `RUN` | If set. this overrides the default setting set into the **test** configuration file. |
| `EXPLAIN` | If set. this overrides the default setting set into the **test** configuration file. |
| `TIMEOUT` | If set. this overrides the default setting set into the **test** configuration file. |
| `NUM_TESTS` | If set. this overrides the default setting set into the **test** configuration file. |
| `MAX_SKIPPED_TESTS` | If set. this overrides the default setting set into the **test** configuration file. |
| `WARMUP` | If set. this overrides the default setting set into the **test** configuration file. |
| `WARMUPS_COUNT` | If set. this overrides the default setting set into the **test** configuration file. |
| `MAX_QUERY_TIME` | If set. this overrides the default setting set into the **test** configuration file. |
| `CLUSTER_SIZE` | If set. this overrides the default setting set into the **test** configuration file. |
| `PRE_RUN_OS` | If set. this overrides the default setting set into the **test** configuration file. |
| `POST_RUN_OS` | If set. this overrides the default setting set into the **test** configuration file. |
| `OS_STATS_INTERVAL` | If set. this overrides the default setting set into the **test** configuration file. |

 
### Results extraction mechanisms

 There are three possible result extraction mechanisms. They are set by the parameters set into the test configuration file:

 * `ANALYZE_EXPLAIN`
* `MIN_MAX_OUT_OF_N`
* `SIMPLE_AVERAGE`

 Only one of these should be set to true (1). 

 **`ANALYZE_EXPLAIN`** is used for benchmarking InnoDB storage engine where the execution plan could change for the same query when the server is restarted. It is designed to run the query only with the fastest execution plan. This means that the server is restarted if the current execution plan is proven slower than the other. As a final result is taken the result for the query plan that turns out to be fastest and there are at least `CLUSTER_SIZE` tests with it for that query. By setting the configuration parameter `NUM_TESTS` you can set a maximum test runs that when reached will get the best cluster's average time (even if it is less than `CLUSTER_SIZE`). Also when a timeout for that query (`MAX_QUERY_TIME`) is reached, the scoring mechanism will return the best available cluster result.

 **`MIN_MAX_OUT_OF_N`** is also used for benchmarking InnoDB storage engine. As a result are stored the values for the fastest and the slowest run. It is assumed that when the execution plan has changed it has different execution plan and we are interested only in the min and max time.

 **`SIMPLE_AVERAGE`** is used for benchmarking storage engines that do not change the execution plan between restarts like MyISAM. The final result is the average execution time from all the test runs for the query.

 ### Results graphics

 After each query test run, the result is stored into a file named **results.dat** located into `{RESULTS_OUTPUT_DIR}`. This file is designed to be easy to be read by the plotting program Gnuplot 4.4. It is divided into blocks, separated by several new lines. Each block starts with a comment line containing details for the current block of results.

 Queries that have timed out have a value of `100000` so that they run out of the graphics and are cut off. Other queries have their real times (in seconds) starting from `0`. The graphics is cut off on the y-axis on the longest time for `completed test + 20%`. For example if the longest time is `100` seconds, the graphics is cut-off to `120` seconds. Thus the timed out queries will be truncated by this limitation and will seem as really timed out.

 During the test run, a gnuplot script file is generated with the necessary parameters for the graphics to be generated automatically. After each query test run is complete, the graphic is regenerated, so that the user can see the current results before the whole benchmark is complete. This file is called `gnuplot_script.txt` and is located into `{RESULTS_OUTPUT_DIR}`. The user can edit it to fine-tune the parameters or headings after the test is complete so that one could get the look and feel he/she wants for the final result.

 ### Script output

 #### Benchmark output

 In the directory set by the parameter {RESULTS\_OUTPUT\_DIR} (example: `/benchmark/dbt3/results/myisam_test_2011-12-08_191427/`) there are the following files/directories:

 * A directory for each test, named as the parameter {KEYWORD} from the test configuration (example: `mariadb-5-3-2`)
* **cpu\_info.txt** — the output of "`/bin/cat /proc/cpuinfo`" OS command
* **uname.txt** — the output of "`uname -a`" OS command
* **results.dat** — the results of each query execution in one file. This file will be used as a datafile for the gnuplot script. It also contains the ratio between the current test and the first one.
* **gnuplot\_script.txt** — the Gnuplot script that renders the graphics.
* **graphics.jpeg** — the output graphics
* A **benchmark** configuration file (example: `myisam_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf`) copied from `mariadb-tools/dbt3_benchmark/tests/`
* A **results database** configuration file (example: `results_db.conf`) copied from `mariadb-tools/dbt3_benchmark/tests/results_db_conf/`
* A **test** configuration file (example: `test_myisam.conf`) copied from `mariadb-tools/dbt3_benchmark/tests/test_conf/`

 #### Test output

 In the subdirectory for the particular test, set by the parameter {KEYWORD} (example: `/benchmark/dbt3/results/myisam_test_2011-12-08_191427/mariadb-5-3-2/`), there are the following files:

 * **pre\_test\_os\_resutls.txt** - the output of the OS commands (if any) executed before the first query run for that test
* **pre\_test\_sql\_resutls.txt** - the output of the SQL commands (if any) executed before the first query run for that test
* **post\_test\_os\_resutls.txt** - the output of the OS commands (if any) executed after the last query run for that test
* **post\_test\_sql\_resutls.txt** - the output of the SQL commands (if any) executed after the last query run for that test
* **all\_explains.txt** - a file containing all the explain queries, their startup parameters for the benchmark and the explain result
* The **config file** (my.cnf) that was passed to mysqld or postgres (example: `mariadb_myisam_my.cnf`) copied from `mariadb-tools/dbt3_benchmark/config/s$SCALE_FACTOR/`
* The **queries** configuration file (example: ''queries-mariadb.conf'') copied from `mariadb-tools/dbt3_benchmark/tests/queries_conf/`
* The **database** configuration file (example: ''db\_mariadb\_5\_3\_myisam.conf'') copied from `mariadb-tools/dbt3_benchmark/tests/db_conf/`

 #### Query output

 For each query execution there are several files that are outputted by the automation script. They are all saved under the subdirectory set by the parameters `{KEYWORD}`:

 * Explain result - a file named '**{query\_name}\_{number\_of\_query\_run}\_results.txt**' (example: '**1\_explain.sql\_1\_results.txt**' — first test for 1\_explain.sql)
* Pre-run OS commands - OS commands, executed before the actual query run. Output is a file named '**pre\_run\_os\_q\_{query\_name}\_no\_{number\_of\_query\_run}\_results.txt**' (example: '**pre\_run\_os\_q\_1.sql\_no\_2\_results.txt**' — second test for query 1.sql)
* Pre-run SQL commands - SQL commands executed before the actual query run. Output is a file named '**pre\_run\_sql\_q\_{query\_name}\_no\_{number\_of\_query\_run}\_results.txt**'.
* Post-run OS commands - OS commands, executed after the actual query run. Output is a file named '**post\_run\_os\_q\_{query\_name}\_no\_{number\_of\_query\_run}\_results.txt**'.
* Post-run SQL commands - SQL commands executed after the actual query run. Output is a file named '**post\_run\_sql\_q\_{query\_name}\_no\_{number\_of\_query\_run}\_results.txt**'.
* CPU utilization statistics: '**{query\_name}\_no\_{number\_of\_query\_run}\_sar\_u.txt**'
* I/O and transfer rate statistics: '**{query\_name}\_no\_{number\_of\_query\_run}\_sar\_b.txt**'
* Memory utilization statistics: '**{query\_name}\_no\_{number\_of\_query\_run}\_sar\_r.txt**'

 ### Hooks

 The automation script provides hooks that allow the user to add both SQL and OS commands prior and after each test. Here is a list of all possible hooks:

 * Pre-test SQL hook: it is set with the parameter `PRE_TEST_SQL`. Contains SQL commands that are run once for the whole test configuration before the first run. (Example: "`use dbt3; select version(); show variables; show engines; show table status;`")
* Post-test SQL hook: it is set with the parameter `POST_TEST_SQL`. Contains SQL commands that are run once for the whole test configuration after the last run.
* Pre-test OS hook: it is set with the parameter `PRE_TEST_OS`. Contains OS commands that are run once for the whole test configuration before the first run.
* Post-test OS hook: it is set with the parameter `POST_TEST_OS`. Contains OS commands that are run once for the whole test configuration after the last run.
* Pre-run SQL hook: it is set with the parameter `PRE_RUN_SQL`. Contains SQL commands that are run prior each query run. (Example: "`flush status; set global userstat=on;`")
* Post-run SQL hook: it is set with the parameter `POST_RUN_SQL`. Contains SQL commands that are run after each query run. (Example: "`show status; select \* from information\_schema.TABLE\_STATISTICS;`")
* Pre-run OS hook: it is set with the parameter `PRE_RUN_OS`. Contains OS commands that are run once prior each query run.
* Post-run OS hook: it is set with the parameter `POST_RUN_OS`. Contains OS commands that are run once after each query run.

 The results of these commands is stored into the `{RESULTS_OUTPUT_DIR}/{KEYWORD}` folder (see <#script-output>)

 ### Activities

 Here are the main activities that this script does:

 1. Parse the configuration files and check the input parameters - if any of the required parameters is missing, the script will stop resulting an error.
2. Collect hardware information - collecting information about the hardware of the machine that the benchmark is run. Currently it collects `cpuinfo` and `uname`. Results of these commands are stored into the results output directory set as an input parameter
3. Loop through the passed test configurations  
  
For each passed in test configuration the script does the following:
	1. Start the results database server. The results of the test are stored into that database.
	2. Clears the caches on the server  
	  
	Clearing the caches is done with the following command:
	```
	sudo /sbin/sysctl vm.drop_caches=3
	
	```
	
		* **NOTE:** In order to clear the caches, the user is required to have sudo rights and the following line should be added to the `sudoers` file (edit it with "`sudo vusudo`" command):
		```
		{your_username} ALL=NOPASSWD:/sbin/sysctl
		
		```
	3. Start the database server
	4. Perform pre-test SQL commands. The results are stored under `results_output_dir/{KEYWORD}` folder and are called `pre_test_sql_results.txt`. `{KEYWORD}` is a unique keyword for the current database configuration.
	5. Perform pre-test OS commands. The results are stored under `results_output_dir/{KEYWORD}` folder and are called `pre_test_os_results.txt`.
		* **NOTE:** If in the test configuration the setting QUERIES\_AT\_ONCE is set to 0, then the server is restarted between each query run. Thus the steps 3.2, 3.3, 3.4 and 3.5 are executed only once right before step 3.6.2.
	6. Read all query configurations and execute the following for each of them:
		1. Check the test configuration parameters. If something is wrong with some required parameter, the program will exit resulting an error.
		2. Get the server version if that's the first run of the query
		3. Perform pre-run OS commands in shell. The results of these queries are stored into a file named `pre_run_os_q_{QUERY}_no_{RUN_NO}_results.txt` under `results_output_dir/{KEYWORD}` where `{QUERY}` is the query name (ex: `1.sql`), `{RUN_NO}` is the sequential run number and `{KEYWORD}` is a unique keyword for the particular test configuration.
		4. Perform pre-run SQL queries. The results of these queries are stored into a file named `pre_run_sql_q_{QUERY}_no_{RUN_NO}_results.txt` under `results_output_dir/{KEYWORD}` where `{QUERY}` is the query name (ex: `1.sql`), `{RUN_NO}` is the sequential run number and `{KEYWORD}` is a unique keyword for the particular test configuration.
		5. Perform warm-up runs if set into the test configuration file
		6. Perform actual test run and measure time.
			* During this step, a new child process is created in order to measure the statistics of the OS. Currently the statistics being collected are:
				+ CPU utilization statistics. The command for this is:
				```
				sar -u 0 2>null
				
				```
				+ I/O and transfer rate statistics. The command for this is:
				```
				sar -b 0 2>null
				
				```
				+ Memory utilization statistics. The command for this is:
				```
				sar -r 0 2>null
				
				```
			* These statistics are measured every N seconds, where `N` is set with the `OS_STATS_INTERVAL` test configuration parameter.
			* The test run for MariaDB and MySQL has an implemented mechanism for cut-off when timeout exceeds. It is controlled with the `TIMEOUT` test parameter. Currently for PostgreSQL there is no such functionality and should be implemented in future versions.
		7. Execute the "explain" statement for that query.
			* **NOTE:** Running `EXPLAIN` queries with MySQL prior version 5.6.3 could result in long running queries since MySQL has to execute the whole query when there are nested selects in it. For MariaDB and PostgreSQL there is no such problem. The long-running explain queries are for queries #7, 8, 9, 13 and 15. For that reason in MySQL prior version 5.6.3 for these queries no `EXPLAIN` selects should be executed.
		8. Perform post-run SQL queries
		9. Perform post-run OS commands in shell
		10. Log the results into the results database
		11. A graphics with the current results is generated using Gnuplot
	7. Shutdown the database server.
	8. Perform post-test SQL commands. The results are stored under `results_output_dir/{KEYWORD}` folder and are called `post_test_sql_results.txt`.
	9. Perform post-test OS commands. The results are stored under `results_output_dir/{KEYWORD}` folder and are called `post_test_os_results.txt`.
	10. Stop the results database server

 ### Script calling examples

 * Example call for MyISAM test for scale factor 30 and timeout 10 minutes:
```
perl launcher.pl \
--project-home=/path/to/project/home/ \
--results-output-dir=/path/to/project/home/results/myisam_test \
--datadir=/path/to/project/home/db_data/ \
--test=/path/to/project/home/mariadb-tools/dbt3_benchmark/tests/myisam_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf \
--queries-home=/path/to/project/home/gen_query/ \
--scale-factor=30 \
--TIMEOUT=600

```

 ...where `/path/to/project/home` is where the `mariadb-tools` project is located. This will replace all occurrences of the string "$PROJECT\_HOME" in the configuration files (example: "`TMPDIR = $PROJECT_HOME/temp/`" will become "`TMPDIR = /path/to/project/home/temp/`").

 `--TIMEOUT` overrides the timeout setting into the test configuration file to 10 minutes.

 * Example for InnoDB test for scale factor 30 with 2 hours timeout per query and 3 runs for each query:
```
perl launcher.pl \
--project-home=/path/to/project/home/ \
--results-output-dir=/path/to/project/home/results/innodb_test \
--datadir=/path/to/project/home/db_data/ \
--test=/path/to/project/home/mariadb-tools/dbt3_benchmark/tests/innodb_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf \
--queries-home=/path/to/project/home/gen_query/ \
--scale-factor=30 \
--TIMEOUT=7200 \
--NUM_TESTS=3

```

 * If a newer version of [MariaDB 5.5](../what-is-mariadb-55/index) is available:
	+ copy or edit the **DMBS server** configuration file `mariadb-tools/dbt3_benchmark/tests/db_conf/db_mariadb_5_5_myisam.conf` and change the parameter `DBMS_HOME` to the new binary distribution. You can also edit `KEYWORD` and `GRAPH_HEADING`

 * If you want to add additional test in the MyISAM benchmark for [MariaDB 5.3](../what-is-mariadb-53/index), but with another defaults-file (my.cnf):
	+ copy or edit the **DMBS server** configuration file `mariadb-tools/dbt3_benchmark/tests/db_conf/db_mariadb_5_3_myisam.conf` and change the parameter CONFIG\_FILE to the new my.cnf
	+ copy or edit the **test** configuration file `mariadb-tools/dbt3_benchmark/tests/myisam_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf` and add the new configuration settings:
	```
	[mariadb_5_3_new_configuration]
	QUERIES_CONFIG = $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/queries_conf/queries-mariadb.conf
	DB_CONFIG 	= $PROJECT_HOME/mariadb-tools/dbt3_benchmark/tests/db_conf/db_mariadb_5_3_myisam_new_configuration.conf
	
	```

 * If you want to add additional startup parameters for query 6 for MariaDB for example:
	+ copy or edit the file `mariadb-tools/dbt3_benchmark/tests/queries_conf/queries-mariadb.conf` and add a parameter "`STARTUP_PARAMS=--optimizer_switch='mrr=on' --mrr_buffer_size=96M`" for example for the section for query 6.
	+ copy or edit the **test** configuration file `mariadb-tools/dbt3_benchmark/tests/myisam_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf` to include the new **queries** configuration file

 Results
-------

 ### MyISAM test

 DBT3 benchmark for the following configuration:

 * [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) Beta + MyISAM
* [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + MyISAM
* MySQL 5.5.19 + MyISAM
* MySQL 5.6.4 + MyISAM

 Results page: [DBT3 benchmark results MyISAM](../dbt3-benchmark-results-myisam/index)

 ### InnoDB test

 DBT3 benchmark for the following configuration:

 * [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) Beta + XtraDB
* [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + XtraDB
* MySQL 5.5.19 + InnoDB
* MySQL 5.6.4 + InnoDB

 Results page: [DBT3 benchmark results InnoDB](../dbt3-benchmark-results-innodb/index)

 ### PostgreSQL test

 DBT3 benchmark for the following configuration:

 * [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) Beta + XtraDB
* MySQL 5.6.4 + InnoDB
* PostgreSQL

 Results page: (TODO)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt3-automation-scripts/>

MariaDB 5.3/MySQL 5.5 Windows performance patches
=================================================

    I just backported Windows performance patches I've done for 5.5 back to [MariaDB 5.3](../what-is-mariadb-53/index). There will be a bit more in Maria that in MySQL 5.5, but more on this later.

 First, I feel Windows performance improvements in 5.5 were never adequately described, so here is the redux. For those familiar with Windows systems programming, MySQL code used to offer of low-hanging performance fruits. I picked some of them those back in my days in MySQL/Sun. The result benchmark curve became really nice: look at [Calvin's blog entry](http://blogs.innodb.com/wp/2010/09/mysql-5-5-innodb-performance-improvements-on-windows/). 

 If graphs in this blog looks familiar to you, it is because it was often used by Oracle marketing as proof of big-O's positive influence on MySQL code :)

 There were 3 Windows performance related patches. I comment on the bugs history a little bit, too.

 * [Bug#24509](http://bugs.mysql.com/bug.php?id=24509). The fix removed the limit of 2048 open MyISAM files, and as a nice side-effect allowed for much bigger table cache. When mysqld starts, it checks the maximum open files value, and corrects the value of table cache, if max\_open\_files is low or max\_connection is high. This is what also happened during benchmarks. If you look at the read-only benchmark graph in the Calvin's blog above, you'll notice a drop around 64 concurrent users. No wonder, mysql server recalculated table cache size, setting it to the absolute minimum, that is to 64.

  The fix was to create an own sort-of C runtime library on top of pure Win32, which is capable of handling more than 2048 open files (16K default). Some other things are also done nicer than in Microsofts C runtime, e.g there are no locks, and there is an acceptable pread()/pwrite() implementation. The main advantage as I said is being able to have a large table cache - for this, rewriting C runtime is likely an overkill, but I did not come up with anything better.

 * [Bug#52102](http://bugs.mysql.com/bug.php?id=52102). This bug was fixing a lot of questionable places in InnoDB that were written probably back in the NT3.1 days .

 First it is importantto understand how innodb "mutex" structure is acquired. Details on it are hairy, mutex is a composite structure which has a real os mutex( known under Windows as CRITICAL\_SECTION) plus innodb event (known under Windows as event). There are a couple of variations on the implementation - mutex can be an interlocked (aka atomic for my Unix friends) variable, under Unix event is represented as condition variable.

 Acquisition is done in 2 steps - first, trylock on os mutex is performed , possibly several times with in a loop, if unsuccessfull, event is reserved in a global table of events known as "sync array", event is entering a waiting state. mutex unlock would wakeup the waiters if there are any. Do not ask me why the implementation is so complicated, it is so :) Maybe, this design helps to find deadlocks.

 Variation of this implementation - instead of trylock on mutex, there might be a compare\_exchange instruction on interlocked(atomic) variable.

 Back to Windows, the implementation of the above exposed a couple of interesting self-compensating bugs.

 1. First, I fixed os\_mutex\_trylock() to be what it really means . The implementation was EnterCriticalSection, which is "try very hard", and actually acquire the lock. A more conscious trylock would be TryEnterCriticalSection. When I fixed that, contrary to my expectation, this made mysqld really slow. When trylock() failed, innodb started to enter code paths it has never seen before. for example, reserving space in the mentioned "sync array". Access to sync array is protected by so-called "slow lock" and this showed up very often in the profiler. The next step was fixing the "slow lock"
2. "slow Innodb mutex" was implemented as kernel object aka Windows mutex (for my Unix friends this is sort of SysV semaphore). It can be used to synchronize processes but is an absolute overkill for synchronization of threads inside the same process. It was a "really slow mutex". Changing this to CRITICAL\_SECTION made it faster however...
3. When all of the above was fixed, found out that Windows events (mentioned events) did not really scale well in many-threads scenarios. On newer Windows (Vista+), there is a CONDITION\_VARIABLE that is documented to scale better, and measuring also showed that it scaled really well. So I used condition variables when possible, which is ironic, because InnoDB events were really modeled after Windows events.
4. Reenabled implementation of fast mutexes as atomic variables. Prior to the patch, precompiler flags to enable atomics were commented out with "Windows atomics do not work well" in CMakeLists.txt. Great comment, given that unlike software developers, atomic instructions have no preferences for the OSes they are being used on :)

 So, the story about "atomics did not work well on Windows" was a cumulative effect of different things.

 Prior to that patch . Once atomics were enabled, implementation of fast mutexes did not use CRITICAL\_SECTION, but compare\_exchange instruction. Ingenious "trylock\_veryhard" as we have seen at the step 1. above is not used anymore, instead it is a quite correct "try" lock . Once try\_lock() began to fail with many concurrent threads, overhead of sync array guard implemented as Windows kernel object that we have seen in 2. became apparent, and less-then inefficient Windows events mentioned in 3. finished that picture.

 * [Bug#56585](http://bugs.mysql.com/bug.php?id=56585)

 This patch was merely to compensate for negative effects of the 5.5 metadata lock on MyISAM bechmarks, and fix was using native Vista performance primitives. The patch per se is not interesting, and repeats a lot of what was done for Innodb. What was great, was a discussion prior to the patch between myself, Davi, Dmitry on different implementations of reader writer locks, including 2 homebacked ones, and one by [Vance Morrison](http://blogs.msdn.com/b/vancem/archive/2006/03/28/563180.aspx). 

 Without doubt, the discussions around that was a highlight in my very short stint at Oracle. Also, if you want to get a MySQL-classic-style code review with 17 things to fix, of which at least 10 would be marked with "Coding Style" (yes, both words capitalized) , try to get Dmitry Lenev as a reviewer, he's great - this is the proof <http://lists.mysql.org/commits/118295> Anyway, the patch improves MyISAM throughput by 10-20% , which I think is quite ok. Somehow those percents were subsequently eaten by MDL though :)

 Notes
-----

 Taken from a note on Facebook: <https://www.facebook.com/note.php?note_id=238505812835782> by Vladislav Vaintroub.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-53mysql-55-windows-performance-patches/>

DBT3 Benchmark Results MyISAM
=============================

    Introduction
------------

 This page shows the results for benchmarking the following configuration:

 * [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) + MyISAM
* [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + MyISAM
* MySQL 5.5.19 + MyISAM
* MySQL 5.6.4 + MyISAM

 The test is performed using the automation script `/mariadb-tools/dbt3_benchmark/launcher.pl`.

 Details about this automation script can be found on the [DBT3 automation scripts](../dbt3-automation-scripts/index) page.

 Hardware
--------

 The tests were performed on our `facebook-maria1` machine. It has the following parameters:

 * **CPU:** 16 Intel® Xeon® CPU L5520 @ 2.27GHz
* **Memory:** Limited to 16 GB out of 72 by adding 'mem=16G' parameter to /boot/grub/menu.lst
* **Logical disk:** HDD 2 TB
* **Operating system:**

 Scale factor 30
---------------

 This test was performed with the following parameters:

 * **Scale factor:** 30
* **Query timeout:** 2 hours
* **Number of tests per query:** 1
* **Total DB size on disk:** about 50GB
* **Available memory:** 16 GB

 **NOTE:** The available memory is controlled by a parameter `mem=16G` added to the file `/boot/grub/menu.lst`

 ### Steps to reproduce

 Follow the instructions in [DBT3 automation scripts](../dbt3-automation-scripts/index) to prepare the environment for the test.

 Before you run the test, ensure that the settings in the test configuration files match your prepared environment. For more details on the test configuration, please, refer to the [Test configuration parameters](../dbt3-automation-scripts/index#test-configuration).

 After the environment is prepared, the following command should be executed in the shell:

 
```
perl launcher.pl \
--results-output-dir=/home/mariadb/benchmark/dbt3/results/myisam_test \
--project-home=/home/mariadb/benchmark/dbt3/ \
--datadir=/home/mariadb/benchmark/dbt3/db_data/ \
--test=./tests/myisam_test_mariadb_5_3_mysql_5_5_mysql_5_6.conf \
--queries-home=/home/mariadb/benchmark/dbt3/gen_query/ --scale-factor=30 \
--TIMEOUT=7200

```

### Compared configurations

 The following configurations have been compared in this test:

 #### Case 1: [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) + MyISAM

 Here are the common options that the mysqld server was started with:

 
```
net_read_timeout = 300
net_write_timeout = 600
key_buffer_size = 3G
skip-external-locking
key_buffer = 16M
max_allowed_packet = 16M
table_open_cache = 1024
thread_cache = 512
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
max_connections = 256
query_cache_size = 0
query_cache_type = 0
sql-mode = NO_ENGINE_SUBSTITUTION

#Per-test optimizations
optimizer_switch='index_merge=on'
optimizer_switch='index_merge_union=on'
optimizer_switch='index_merge_sort_union=on'
optimizer_switch='index_merge_intersection=on'
optimizer_switch='index_merge_sort_intersection=off'
optimizer_switch='index_condition_pushdown=on'
optimizer_switch='derived_merge=on'
optimizer_switch='derived_with_keys=on'
optimizer_switch='firstmatch=off'
optimizer_switch='loosescan=off'
optimizer_switch='materialization=on'
optimizer_switch='in_to_exists=on'
optimizer_switch='semijoin=on'
optimizer_switch='partial_match_rowid_merge=on'
optimizer_switch='partial_match_table_scan=on'
optimizer_switch='subquery_cache=off'
optimizer_switch='mrr=on'
optimizer_switch='mrr_cost_based=off'
optimizer_switch='mrr_sort_keys=on'
optimizer_switch='outer_join_with_cache=on'
optimizer_switch='semijoin_with_cache=off'
optimizer_switch='join_cache_incremental=on'
optimizer_switch='join_cache_hashed=on'
optimizer_switch='join_cache_bka=on'
optimizer_switch='optimize_join_buffer_size=on'
optimizer_switch='table_elimination=on'

join_buffer_space_limit = 3072M
join_buffer_size = 1536M
join_cache_level = 6
mrr_buffer_size = 96M
tmp_table_size = 96M
max_heap_table_size = 96M

```

#### Case 2: [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + MyISAM

 Uses the same configuration file as [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) in Case 1.

 #### Case 3: MySQL 5.5.19 + MyISAM

 Here are the common options that the mysqld server was started with:

 
```
net_read_timeout = 300
net_write_timeout = 600
key_buffer_size = 3G
skip-external-locking
key_buffer = 16M
max_allowed_packet = 16M
table_open_cache = 1024
thread_cache = 512
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
myisam_sort_buffer_size = 8M
max_connections = 256
query_cache_size = 0
query_cache_type = 0
sql-mode = NO_ENGINE_SUBSTITUTION

join_buffer_size = 1536M
tmp_table_size = 96M
max_heap_table_size = 96M
read_rnd_buffer_size = 96M

```

#### Case 4: MySQL 5.6.4 + MyISAM

 Here are the common options that the mysqld server was started with:

 
```
net_read_timeout = 300
net_write_timeout = 600
key_buffer_size = 3G
skip-external-locking
key_buffer = 16M
max_allowed_packet = 16M
table_open_cache = 1024
thread_cache = 512
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
myisam_sort_buffer_size = 8M
max_connections = 256
query_cache_size = 0
query_cache_type = 0
sql-mode = NO_ENGINE_SUBSTITUTION

optimizer_switch='mrr=on'
optimizer_switch='mrr_cost_based=off'
optimizer_switch='batched_key_access=on'
optimizer_switch='index_condition_pushdown=on'

join_buffer_size = 1536M
tmp_table_size = 96M
max_heap_table_size = 96M
read_rnd_buffer_size = 96M

```

The server has been restarted between each query run and the caches have been cleared between each query run.

 ### Results (without q20)

 Here is the graphics of the results:

 (Smaller bars are better)

 ![dbt3-myisam-s30-hdd](https://mariadb.com/kb/en/dbt3-benchmark-results-myisam/+image/dbt3-myisam-s30-hdd "dbt3-myisam-s30-hdd")

 **NOTE:** Queries that are cut off by the graphics have timed out the period of 2 hours.

 Here are the actual results in seconds (smaller is better):

 


|  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Configuration | [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) + MyISAM | *Ratio* | [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + MyISAM | *Ratio* | MySQL 5.5.19 + MyISAM | *Ratio* | MySQL 5.6.4 + MyISAM | *Ratio* |
| 1.sql | 261 | *1.00* | 308 | *1.18* | 259 | *0.99* | 277 | *1.06* |
| 2.sql | 47 | *1.00* | 48 | *1.02* | 499 | *10.62* | 49 | *1.04* |
| 2-opt.sql | 46 | *1.00* | 48 | *1.04* | - | - | - | - |
| 3.sql | 243 | *1.00* | 246 | *1.01* | >7200 | - | 1360 | *5.60* |
| 4.sql | 137 | *1.00* | 135 | *0.99* | 4117 | *30.05* | 137 | *1.00* |
| 5.sql | 181 | *1.00* | 187 | *1.03* | 6164 | *34.06* | 1254 | *6.93* |
| 6.sql | 198 | *1.00* | 205 | *1.04* | >7200 | - | 194 | *0.98* |
| 7.sql | 779 | *1.00* | 896 | *1.15* | 814 | *1.04* | 777 | *1.00* |
| 8.sql | 270 | *1.00* | 287 | *1.06* | 749 | *2.77* | 1512 | *5.60* |
| 9.sql | 252 | *1.00* | 254 | *1.01* | >7200 | - | 298 | *1.18* |
| 10.sql | 782 | *1.00* | 854 | *1.09* | >7200 | - | 1881 | *2.41* |
| 11.sql | 45 | *1.00* | 36 | *0.80* | 357 | *7.93* | 49 | *1.09* |
| 12.sql | 211 | *1.00* | 217 | *1.03* | >7200 | - | 213 | *1.01* |
| 13.sql | 251 | *1.00* | 236 | *0.94* | 1590 | *6.33* | 244 | *0.97* |
| 14.sql | 88 | *1.00* | 91 | *1.03* | 1590 | *18.07* | 94 | *1.07* |
| 15.sql | 162 | *1.00* | 164 | *1.01* | 4580 | *28.27* | 165 | *1.02* |
| 16.sql | 154 | *1.00* | 152 | *0.99* | 174 | *1.13* | 173 | *1.12* |
| 17.sql | 1493 | *1.00* | 1495 | *1.00* | 865 | *0.58* | 794 | *0.53* |
| 17-opt1.sql | 795 | *1.00* | 794 | *1.00* | 862 | *1.08* | 794 | *1.00* |
| 17-opt2.sql | 1482 | *1.00* | 1458 | *0.98* | 2167 | *1.46* | 1937 | *1.31* |
| 18.sql | 971 | *1.00* | 931 | *0.96* | >7200 | - | >7200 | - |
| 18-opt.sql | 121 | *1.00* | 125 | *1.03* | - | - | - | - |
| 19.sql | 212 | *1.00* | 212 | *1.00* | 2004 | *9.45* | 61 | *0.29* |
| 19-opt1.sql | 59 | *1.00* | 59 | *1.00* | 1999 | *33.88* | 61 | *1.03* |
| 19-opt2.sql | 260 | *1.00* | 216 | *0.83* | 443 | *1.70* | 236 | *0.91* |
| 20.sql | - | - | - | - | - | - | - | - |
| 21.sql | 173 | *1.00* | 179 | *1.03* | >7200 | - | 183 | *1.06* |
| 22.sql | 13 | *1.00* | 14 | *1.08* | 10 | *0.77* | 13 | *1.00* |
| Version | 5.3.2-MariaDB-beta |  | 5.5.18-MariaDB |  | 5.5.19 |  | 5.6.4-m7 |  |
| Query and explain details | [Explain details](http://askmonty.org/w/images/5/56/DBT3_MyISAM_HDD_s30_mariadb_5_3_2.txt) |  | [Explain details](http://askmonty.org/w/images/9/9e/DBT3_MyISAM_HDD_s30_mariadb_5_5_18.txt) |  | [Explain details](http://askmonty.org/w/images/c/cc/Explain_DBT3_MyISAM_HDD_s30_mysql_5_5_19.txt) |  | [Explain details](http://askmonty.org/w/images/d/d1/Explain_MyISAM_HDD_s30_mysql_5_6_4_.txt) |  |

 
**NOTE:** The columns named "*Ratio*" are calculated values of the ratio between the current value compared to the value in the first test configuration. The formula for it is `(current_value/value_in_first_row)`. For example if [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) (the first column) handles a query for 100 seconds and MySQL 5.6.4 (the last configuration) handles the same query for 120 seconds, the ratio will be `120/100 = 1.20`. This means that it takes MySQL 5.6.4 20% more time to handle the same query.

 The archived folder with all the results and details for that benchmark can be downloaded from here: [MyISAM s30 on facebook-maria1](http://askmonty.org/w/images/e/e1/Myisam_test_2011-12-01_203150.tar.bz2)

 ### Notes

 Queries 2-opt.sql and 18-opt.sql are tested only for [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) and [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/)

 * Additional startup parameters for 2\_opt:
```
--optimizer_switch='mrr_sort_keys=off'

```

 * Additional startup parameters for 18\_opt:
```
--optimizer_switch='semijoin=off' --optimizer_switch='index_condition_pushdown=on'

```

 * Additional modifications for 17-opt1:
```
select
sum(l_extendedprice) / 7.0 as avg_yearly
from
  part straight_join lineitem
where
p_partkey = l_partkey
...

```

 * Additional modifications for 17-opt2:
```
select
 	sum(l_extendedprice) / 7.0 as avg_yearly
from
 	lineitem straight_join part
where
 	p_partkey = l_partkey
...

```

 * Additional modifications for 19-opt1:
```
select
 	sum(l_extendedprice* (1 - l_discount)) as revenue
from
 	part straight_join lineitem
where
 	(
 		p_partkey = l_partkey
...

```

 * Additional modifications for 19-opt2:
```
select
 	sum(l_extendedprice* (1 - l_discount)) as revenue
from
 	lineitem straight_join part
where
 	(
 		p_partkey = l_partkey
...

```

 ### Benchmark for q20

 This benchmarked only q20 with the same settings as described above for the other queries. The only difference is the timeout that was used: 30000 seconds (8 hours and 20 min).

 #### Compared cases

 The benchmark for q20 compares the following cases:

 * q20.sql - the original query is run with the IN-TO-EXISTS strategy for all servers. The following optimizer switches were used for MariaDB:
```
--optimizer_switch='in_to_exists=on,materialization=off,semijoin=off';

```

 * q20-opt0.sql - the original query is changed so that the same join order is chosen as for the two subsequent variants that test materialization where this order is optimal. The join order is:
```
select s_name, s_address
 from supplier, nation
 where s_suppkey in (select distinct (ps_suppkey)
                     from '''part straight_join partsupp'''
                     where ps_partkey = p_partkey ...

```

 * Since the IN-TO-EXISTS strategy is essentially the same for both MariaDB and MySQL, this query was tested for MySQL only.

 * q20-opt1.sql - modifies the original query in two ways:
	+ enforces the MATERIALIZATION strategy, and
	+ enforces an optimal JOIN order via straight\_join as follows:
	```
	select s_name, s_address
	 from supplier, nation
	 where s_suppkey in (select distinct (ps_suppkey)
	                     from '''part straight_join partsupp'''
	                     where ps_partkey = p_partkey ...
	
	```

 q20-opt1.sql uses the following optimizer switches for MariaDB:



```
--optimizer_switch='in_to_exists=off,materialization=on,semijoin=off';

```
 * q20-opt2.sql - the same as q20-opt1.sql but allows the optimizer to choose the subquery strategy via the following switch:
```
--optimizer_switch='in_to_exists=on,materialization=on,semijoin=on';

```

 * This switch results in the choice of SJ-MATERIALIZATION.

 **NOTE:** For MySQL there are no such *optimizer-switch* parameters, and the tests were started without any additional startup parameters. The default algorithm in MySQL is *in\_to\_exists*.

 #### Results for q20

 Here is the graphics of the results of the benchmarked q20: (Smaller bars are better)

 ![dbt3-q20-myisam-s30-hdd]

 **NOTE:** Queries that are cut off by the graphics have timed out the period of 30000 seconds.

 Here are the actual results in seconds (smaller is better):

 


| Configuration | 20.sql | 20-opt0.sql | 20-opt1.sql | 20-opt2.sql | Version | Query and explain details |
| --- | --- | --- | --- | --- | --- | --- |
| [MariaDB 5.3.2](https://mariadb.com/kb/en/mariadb-532-release-notes/) + MyISAM | 20070 | - | 5560 | 5615 | 5.3.2-MariaDB-beta | [Explain details](http://askmonty.org/w/images/9/9a/DBT3_MyISAM_HDD_s30_q20_mariadb_5_3_2.txt) |
| [MariaDB 5.5.18](https://mariadb.com/kb/en/mariadb-5518-release-notes/) + MyISAM | 19922 | - | 5529 | 5572 | 5.5.18-MariaDB | [Explain details](http://askmonty.org/w/images/e/e8/DBT3_MyISAM_HDD_s30_q20_mariadb_5_5_18.txt) |
| MySQL 5.5.19 + MyISAM | 17832 | >30000 | - | - | 5.5.19 | [Explain details](http://askmonty.org/w/images/a/ae/DBT3_MyISAM_HDD_s30_q20_mysql_5_5_19.txt) |
| MYSQL 5.6.4 + MyISAM | 19845 | >30000 | - | - | 5.6.4-m7 | [Explain details](http://askmonty.org/w/images/c/cc/DBT3_MyISAM_HDD_s30_q20_mysql_5_6_4.txt) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt3-benchmark-results-myisam/>

RQG Performance Comparisons
===========================

    Performance testing
-------------------

 The `performance/perfrun.pl` executes each query against a set of tw servers and reports the outcome.

 
```
perl performance/perfrun.pl --input-directory=... --dsn1=... --dsn2=... --output-file=... --filter=...

```

* `--input-directory` contains the queries to be run, one query per file. Alternative sources for queries will be made available in the future;
* `--dsn1` and `--dsn2` specify the locations of the two servers being compared in the Perl DBI URL format. If the queries are not fully qualified, the DSNs must contain the database name. The username and the password are also provided via the DSN. For example:

 
```
--dsn1=dbi:mysql:host=127.0.0.1:port=19300:user=root:database=test \
--dsn2=dbi:mysql:host=127.0.0.1:port=19302:user=root:database=test

```

* `--output-file=...` specifies a file where matching queries will be dumped in a form suitable for follow-up filtering with `perfreport`
* if no `--filter` is specified, all queries from the input will be reported;

 Performance reporting
---------------------

 The `performance/perfreport.pl` script takes an ouput file created by `perfrun` and prints out its contents, possibly applying a filter in the process:

 
```
perl performance/perfreport.pl --input-file=... --filter=...

```

If no `--filter` is specified, all queries present in the input file are printed.

 Filters
-------

 The queries reported by the system can be filtered out using perl-based filtering expressions. A filter can be applied during data collection, at which point it determines what information is stored in the output file and at 

 If you do not specify a filter, it is assumed that you want to output all queries.

 The following variables can participate in filter expressions:

 * Variables from `SHOW SESSION STATUS`, except:
	+ variables that are not reset at the start of the query, which includes `Com_*`, `Uptime`, `Opened_files` and the like;
	+ variables that relate to the operation of SSL encryption or the query cache;
* Variables from `SHOW GLOBAL STATUS LIKE 'Innodb_%'`

 For each MySQL status variable, 4 Perl variables are provided — the value of the MySQL variable from each server, their absolute difference and their ratio. For example, for the `Innodb_rows_read` MySQL variable, you can use `Innodb_rows_read1`, `Innodb_rows_read2` , `Innodb_rows_read_delta` and `Innodb_rows_read_ratio` in your Perl filter expressions.

 In addition to the MySQL status variables, the framework provides the following additional variables:

 * `$Execution_time{1|2|delta|ratio}` reports the time the query took to run from start to end in seconds. The value is truncated at milliseconds in order to prevent exorbitant performance ratios from being reported on very fast queries;
* `$Temperature` can either be `cold` or `warm` depending on whether the first execution of the query is being processed, or the second.
* `$Query` contains the text of the query, in order to enable filtering such as `$Query !~ m{l_receiptDATE}`

 For example, the following command-line option:

 
```
--filter='($Execution_time1 > 0.1 || $Execution_time2 > 0.1) && $Temperature eq "warm"'

```

Will only process or report queries that took more than 0.1 sec to execute on a warm server.

 On-screen Reporting Format
--------------------------

 The ASCII on-screen reporting format is as follows:

 
```
Query: SELECT  l_linenumber FROM lineitem  WHERE l_suppkey  IN ( 10 , 1 ) AND l_shipdate NOT IN ( '1993-06-06' , '1998-02-04' , '1992-01-08' ) AND l_linenumber NOT IN ( 8 , 7 ) AND l_quantity <> 3 AND ( l_orderkey NOT IN ( 1298 , 93 ) OR l_suppkey = 10 ) AND ( l_suppkey BETWEEN 4 AND 10 + 4 OR l_linenumber = 2 AND l_commitDATE BETWEEN '1993-06-27' AND '1993-09-05' AND l_linenumber BETWEEN 3 AND 9 + 9 );
Cache: warm
                                    5.3.0-MariaDB-     5.2.6-MariaDB-          Delta              Ratio
-------------------------------------------------------------------------------------------------------
Execution time                               0.011s            0.004s           -0.007s            0.36
Innodb_buffer_pool_read_requests          2171              1836              -335                 0.85
Handler_read_rnd                           583                 0              -583
Handler_read_next                          583               602                19                 1.03
Innodb_rows_read                          1166               602              -564                 0.52

```

Only variables whose values are different between the two servers are reported. In this particular example, the query ran slower on `5.3.0-MariaDB` with warm cache and caused twice as many `Innodb_rows_read`.

 On-disk Data Storage Format
---------------------------

 The on-disk storage format is `Data::Dumper` objects, wrapped in `<![CDATA[ ... ]]>` tags, without the file being a full-blown XML. The serialized representation is created by `GenTest::QueryPerformanceDelta::serialize()` and is read by using `eval()` in `performance/perfreport.pl`

 See also:
---------

 * [RQG Documentation](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](../qa-tools/index)
* [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rqg-performance-comparisons/>

ST\_AsGeoJSON
=============

    Syntax
------

 
```
ST_AsGeoJSON(g[, max_decimals[, options]])

```

Description
-----------

 Returns the given geometry *g* as a GeoJSON element. The optional *max\_decimals* limits the maximum number of decimals displayed.

 The optional *options* flag can be set to `1` to add a bounding box to the output.

 Examples
--------

 
```
SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(5.3 7.2)'));
+-------------------------------------------------+
| ST_AsGeoJSON(ST_GeomFromText('POINT(5.3 7.2)')) |
+-------------------------------------------------+
| {"type": "Point", "coordinates": [5.3, 7.2]}    |
+-------------------------------------------------+

```

See also
--------

 * [ST\_GeomFromGeoJSON](../st_geomfromgeojson/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/geojson-st_asgeojson/>

ST\_GeomFromGeoJSON
===================

    
**MariaDB starting with [10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)**ST\_GeomFromGeoJSON was added in [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/)

 
Syntax
------

 
```
ST_GeomFromGeoJSON(g[, option])

```

Description
-----------

 Given a GeoJSON input *g*, returns a geometry object. The *option* specifies what to do if *g* contains geometries with coordinate dimensions higher than 2.

 


| Option | Description |
| --- | --- |
| 1 | Return an error (the default) |
| 2 - 4 | The document is accepted, but the coordinates for higher coordinate dimensions are stripped off. |

 
Note that this function did not work correctly before [MariaDB 10.2.8](https://mariadb.com/kb/en/mariadb-1028-release-notes/) - see [MDEV-12180](https://jira.mariadb.org/browse/MDEV-12180).

 Examples
--------

 
```
SET @j = '{ "type": "Point", "coordinates": [5.3, 15.0]}';

SELECT ST_AsText(ST_GeomFromGeoJSON(@j));
+-----------------------------------+
| ST_AsText(ST_GeomFromGeoJSON(@j)) |
+-----------------------------------+
| POINT(5.3 15)                     |
+-----------------------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/st_geomfromgeojson/>

MariaDB Development Meeting - Lisbon
=====================================

   11-13 Mar 2011 - Notes and Plans from the Lisbon Developer meeting.

  

| Title | Description |
| --- | --- |
|  [Plans for 5.6](../plans-for-56/index) |  The information on this page is obsolete. Current information can be found...  |
|  [MariaDB Plans - GIS](../mariadb-plans-gis/index) |  Old GIS plans  |
|  [MariaDB Plans - Online Operations](../mariadb-plans-online-operations/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB Plans - Replication](../mariadb-plans-replication/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB Plans - Statistics and Monitoring](../mariadb-plans-statistics-and-monitoring/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-development-meeting-lisbon/>

Information Schema INNODB\_UNDO\_LOGS Table
===========================================

    
**MariaDB [5.5.27](https://mariadb.com/kb/en/mariadb-5527-release-notes/) - [10.0](../what-is-mariadb-100/index)**The `INNODB_UNDO_LOGS` are a Percona enhancement, introduced in version [MariaDB 5.5.27](https://mariadb.com/kb/en/mariadb-5527-release-notes/) and removed in 10.0.

 
The [Information Schema](../information_schema/index) `INNODB_UNDO_LOGS` table is a Percona enchancement, and is only available for XtraDB, not InnoDB (see [XtraDB and InnoDB](../xtradb-and-innodb/index)). It contains information about the the InnoDB [undo log](../undo-log/index), with each record being an undo log segment. It was removed in [MariaDB 10.0](../what-is-mariadb-100/index).

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `TRX_ID` | Unique transaction ID number, matching the value from the [information\_schema.INNODB\_TRX](../information-schema-innodb_trx-table/index) table. |
| `RSEG_ID` | Rollback segment ID, matching the value from the `information_schema.INNODB_RSEG` table. |
| `USEG_ID` | Undo segment ID. |
| `SEGMENT_TYPE` | Indicates the operation type, for example `INSERT` or `UPDATE`. |
| `STATE` | Segment state; one of `ACTIVE` (contains active transaction undo log), `CACHED`, `TO_FREE` (insert undo segment can be freed), `TO_PURGE` (update undo segment won't be re-used and can be purged when all undo data is removed) or `PREPARED` (segment of a prepared transaction). |
| `SIZE` | Size in pages of the segment. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-innodb_undo_logs-table/>

Information Schema XTRADB\_INTERNAL\_HASH\_TABLES Table
=======================================================

    
**MariaDB starting with [10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/)**The `XTRADB_INTERNAL_HASH_TABLES` table was added in [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/).

 
The [Information Schema](../information_schema/index) `XTRADB_INTERNAL_HASH_TABLES` table contains InnoDB/XtraDB hash table memory usage information.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `INTERNAL_HASH_TABLE_NAME` | Hash table name |
| `TOTAL_MEMORY` | Total memory |
| `CONSTANT_MEMORY` | Constant memory |
| `VARIABLE_MEMORY` | Variable memory |

 
Example
-------

 
```
SELECT * FROM information_schema.XTRADB_INTERNAL_HASH_TABLES;
+--------------------------------+--------------+-----------------+-----------------+
| INTERNAL_HASH_TABLE_NAME       | TOTAL_MEMORY | CONSTANT_MEMORY | VARIABLE_MEMORY |
+--------------------------------+--------------+-----------------+-----------------+
| Adaptive hash index            |      2217568 |         2213368 |            4200 |
| Page hash (buffer pool 0 only) |       139112 |          139112 |               0 |
| Dictionary Cache               |       613423 |          554768 |           58655 |
| File system                    |       816368 |          812272 |            4096 |
| Lock System                    |       332872 |          332872 |               0 |
| Recovery System                |            0 |               0 |               0 |
+--------------------------------+--------------+-----------------+-----------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-xtradb_internal_hash_tables-table/>

Information Schema XTRADB\_READ\_VIEW Table
===========================================

    
**MariaDB starting with [10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/)**The `XTRADB_READ_VIEW` table was added in [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/).

 
The [Information Schema](../information_schema/index) `XTRADB_READ_VIEW` table contains information about the oldest active transaction in the system.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It has the following columns:

 


| Column | Description |
| --- | --- |
| `READ_VIEW_UNDO_NUMBER` |  |
| `READ_VIEW_LOW_LIMIT_TRX_NUMBER` | Highest transaction number at the time the view was created. |
| `READ_VIEW_UPPER_LIMIT_TRX_ID` | Highest transaction ID at the time the view was created. Should not see newer transactions with IDs equal to or greater than the value. |
| `READ_VIEW_LOW_LIMIT_TRX_ID` | Latest committed transaction ID at the time the oldest view was created. Should see all transactions with IDs equal to or less than the value. |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-xtradb_read_view-table/>

Creating Mroonga User-Defined Functions
=======================================

    The [Mroonga storage engine](../mroonga/index) includes a number of [user-defined functions](../user-defined-functions/index) that need to be created before they can be used. If these are not created already during Mroonga setup, you will need to do so yourself. The full list of available functions and the statements to create them are found in `share/mroonga/install.sql`, for example, as of Mroonga 7.07 ([MariaDB 10.2.11](https://mariadb.com/kb/en/mariadb-10211-release-notes/) and [MariaDB 10.1.29](https://mariadb.com/kb/en/mariadb-10129-release-notes/)) running on Linux:

 
```
DROP FUNCTION IF EXISTS last_insert_grn_id;
CREATE FUNCTION last_insert_grn_id RETURNS INTEGER
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_snippet;
CREATE FUNCTION mroonga_snippet RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_command;
CREATE FUNCTION mroonga_command RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_escape;
CREATE FUNCTION mroonga_escape RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_snippet_html;
CREATE FUNCTION mroonga_snippet_html RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_normalize;
CREATE FUNCTION mroonga_normalize RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_highlight_html;
CREATE FUNCTION mroonga_highlight_html RETURNS STRING
  SONAME 'ha_mroonga.so';

DROP FUNCTION IF EXISTS mroonga_query_expand;
CREATE FUNCTION mroonga_query_expand RETURNS STRING
  SONAME 'ha_mroonga.so';

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-mroonga-user-defined-functions/>

mroonga\_escape
===============

    Syntax
------

 
```
mroonga_escape (string [,special_characters])

```

* `string` - required parameter specifying the text you want to escape
* `special_characters` - optional parameter specifying the characters to escape

 Description
-----------

 `mroonga_escape` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index), used for escaping a string. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 If no `special_characters` parameter is provided, by default `+-<>*()":` are escaped.

 Returns the escaped string.

 Example
-------

 
```
SELECT mroonga_escape("+-<>~*()\"\:");
'\\+\\-\\<\\>\\~\\*\\(\\)\\"\\:

```

See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_escape/>

mroonga\_snippet\_html
======================

    Description
-----------

 `mroonga_snippet_html` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It provides a keyword with surrounding text, or the keyword in context. It is still considered experimental. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)
* [mroonga\_snippet](../mroonga_snippet/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_snippet_html/>

mroonga\_snippet
================

    Syntax
------

 
```
mroonga_snippet document,
                max_length,
                max_count,
                encoding,
                skip_leading_spaces,
                html_escape,
                snippet_prefix,
                snippet_suffix,
                word1, word1_prefix, word1_suffix
                ...
                [wordN wordN_prefix wordN_suffix]

```
 Description
-----------

 `mroonga_snippet` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It provides a keyword with surrounding text, or the keyword in context. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 The required parameters include:

 * `document` - Column name or string value.
* `max_length` - Maximum length of the snippet, in bytes.
* `max_count` - Maximum snippet elements (N word).
* `encoding` - Encoding of the document, for example `cp932_japanese_ci`
* `skip_leading_spaces` - `1` to skip leading spaces, `0` to not skip.
* `html_escape` = `1` to enable HTML espape, `0` to disable.
* `prefix` - Snippet start text.
* `suffix` - Snippet end text.

 The optional parameters include:

 * `wordN` - A word.
* `wordN_prefix` - wordN start text.
* `wordN_suffix` - wordN end text

 It can be used in both storage and wrapper mode.

 Returns the snippet string. 

 Example
-------


See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_snippet/>

last\_insert\_grn\_id
=====================

    Syntax
------

 
```
last_insert_grn_id()

```
 Description
-----------

 `last_insert_grn_id` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It returns the unique Groonga id of the last-inserted record. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 Examples
--------

 
```
SELECT last_insert_grn_id();
+----------------------+
| last_insert_grn_id() |
+----------------------+
|                    3 |
+----------------------+

```

See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/last_insert_grn_id/>

mroonga\_command
================

    Syntax
------

 
```
mroonga_command (command)

```

Description
-----------

 `mroonga_command` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It passes a command to Groonga for execution. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 * `command` - string, required parameter specifying the command to pass that will be executed by Groonga. See [the Groonga reference](http://groonga.org/docs/reference/command.html) for a list of commands.

 Returns the result of the Groonga command. 

 Example
-------

 
```
SELECT mroonga_command('status');
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mroonga_command('status')                                                                                                                                                                                      |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {"alloc_count":593,"starttime":1512022368,"start_time":1512022368,"uptime":13510,"version":"7.0.7","n_queries":0,"cache_hit_rate":0.0,"command_version":1,"default_command_version":1,"max_command_version":3} |

```

See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_command/>

mroonga\_highlight\_html
========================

    Syntax
------

 
```
mroonga_highlight_html(text[[, query AS query]])

mroonga_highlight_html(text[[, keyword1, ..., keywordN]])

```
 Description
-----------

 `mroonga_highlight_html` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It highlights the specified keywords in the target text. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 The optional parameter can either be one or more *keywords*, or a Groonga *query*.

 The function highlights the specified keywords in the target text by surrounding each keyword with `<span class="keyword">...</span>`, and escaping special HTML characters such as `<` and `>`. 

 Returns highlighted HTML.

 Examples
--------

 
```
SELECT mroonga_highlight_html('<p>MariaDB includes the Mroonga storage engine</p>.') 
  AS highlighted_html;
+-----------------------------------------------------------------+
| highlighted_html                                                |
+-----------------------------------------------------------------+
| &lt;p&gt;MariaDB includes the Mroonga storage engine&lt;/p&gt;. |
+-----------------------------------------------------------------+

```

Highlighting the words `MariaDB` and `Mroonga` in a given text:

 
```
SELECT mroonga_highlight_html('MariaDB includes the Mroonga storage engine.', 'MariaDB', 'Mroonga') 
  AS highlighted_html;
+--------------------------------------------------------------------------------------------------------+
| highlighted_html                                                                                       |
+--------------------------------------------------------------------------------------------------------+
| <span class="keyword">MariaDB</span> includes the <span class="keyword">Mroonga</span> storage engine. |
+--------------------------------------------------------------------------------------------------------+

```

The same outcome, formulated as a Groonga query:

 
```
SELECT mroonga_highlight_html('MariaDB includes the Mroonga storage engine.', 'MariaDB OR Mroonga' 
  AS query) AS highlighted_text;
+--------------------------------------------------------------------------------------------------------+
| highlighted_text                                                                                       |
+--------------------------------------------------------------------------------------------------------+
| <span class="keyword">MariaDB</span> includes the <span class="keyword">Mroonga</span> storage engine. |
+--------------------------------------------------------------------------------------------------------+

```

See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_highlight_html/>

Information Schema ROCKSDB\_PERF\_CONTEXT\_GLOBAL Table
=======================================================

    The [Information Schema](../information_schema/index) `ROCKSDB_PERF_CONTEXT_GLOBAL` table is included as part of the [MyRocks](../myrocks/index) storage engine and includes global counter information.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `STAT_TYPE` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_perf_context_global-table/>

Information Schema ROCKSDB\_CF\_OPTIONS Table
=============================================

    The [Information Schema](../information_schema/index) `ROCKSDB_CF_OPTIONS` table is included as part of the [MyRocks](../myrocks/index) storage engine, and contains infomation about MyRocks [column families](../myrocks-column-families/index).

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CF_NAME` | [Column family](../myrocks-column-families/index) name. |
| `OPTION_TYPE` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_cf_options-table/>

Information Schema ROCKSDB\_CFSTATS Table
=========================================

    The [Information Schema](../information_schema/index) `ROCKSDB_CFSTATS` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CF_NAME` |  |
| `STAT_TYPE` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_cfstats-table/>

mroonga\_normalize
==================

    Syntax
------

 
```
mroonga_normalize(string[, normalizer_name])

```
 Description
-----------

 `mroonga_normalize` is a [user-defined function](../user-defined-functions/index) (UDF) included with the [Mroonga storage engine](../mroonga/index). It uses Groonga's normalizer to normalize text. See [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index) for details on creating this UDF if required.

 Given a string, returns the normalized text.

 See the [Groonga Normalizer Reference](http://groonga.org/docs/reference/normalizers.html) for details on the Groonga normalizers. The default if no normalizer is provided is `NormalizerAuto`.

 Examples
--------

 
```
SELECT mroonga_normalize("ABぃ㍑");
+-------------------------------+
| mroonga_normalize("ABぃ㍑")   |
+-------------------------------+
| abぃリットル                  |
+-------------------------------+

```

See Also
--------

 * [Creating Mroonga User-Defined Functions](../creating-mroonga-user-defined-functions/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mroonga_normalize/>

Information Schema ROCKSDB\_PERF\_CONTEXT Table
===============================================

    The [Information Schema](../information_schema/index) `ROCKSDB_PERF_CONTEXT` table is included as part of the [MyRocks](../myrocks/index) storage engine and includes per-table/partition counters .

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_SCHEMA` |  |
| `TABLE_NAME` |  |
| `PARTITION_NAME` |  |
| `STAT_TYPE` |  |
| `VALUE` |  |

 
Note: for multi-table queries, all counter increments are "billed" to the first table in the query: <https://github.com/facebook/mysql-5.6/issues/1018>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_perf_context-table/>

Information Schema ROCKSDB\_COMPACTION\_STATS Table
===================================================

    The [Information Schema](../information_schema/index) `ROCKSDB_COMPACTION_STATS` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `CF_NAME` |  |
| `LEVEL` |  |
| `TYPE` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_compaction_stats-table/>

Information Schema ROCKSDB\_DBSTATS Table
=========================================

    The [Information Schema](../information_schema/index) `ROCKSDB_DBSTATS` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `STAT_TYPE` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_dbstats-table/>

Information Schema ROCKSDB\_DEADLOCK Table
==========================================

    The [Information Schema](../information_schema/index) `ROCKSDB_DEADLOCK` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `DEADLOCK_ID` |  |
| `TIMESTAMP` |  |
| `TRANSACTION_ID` |  |
| `CF_NAME` |  |
| `WAITING_KEY` |  |
| `LOCK_TYPE` |  |
| `INDEX_NAME` |  |
| `TABLE_NAME` |  |
| `ROLLED_BACK` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_deadlock-table/>

Information Schema ROCKSDB\_GLOBAL\_INFO Table
==============================================

    The [Information Schema](../information_schema/index) `ROCKSDB_GLOBAL_INFO` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TYPE` |  |
| `NAME` |  |
| `VALUE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_global_info-table/>

Information Schema ROCKSDB\_TRX Table
=====================================

    The [Information Schema](../information_schema/index) `ROCKSDB_TRX` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TRANSACTION_ID` |  |
| `STATE` |  |
| `NAME` |  |
| `WRITE_COUNT` |  |
| `LOCK_COUNT` |  |
| `TIMEOUT_SEC` |  |
| `WAITING_KEY` |  |
| `WAITING_COLUMN_FAMILY_ID` |  |
| `IS_REPLICATION` |  |
| `SKIP_TRX_API` |  |
| `READ_ONLY` |  |
| `HAS_DEADLOCK_DETECTION` |  |
| `NUM_ONGOING_BULKLOAD` |  |
| `THREAD_ID` |  |
| `QUERY` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_trx-table/>

Information Schema ROCKSDB\_INDEX\_FILE\_MAP Table
==================================================

    The [Information Schema](../information_schema/index) `ROCKSDB_INDEX_FILE_MAP` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `COLUMN_FAMILY` |  |
| `INDEX_NUMBER` |  |
| `SST_NAME` |  |
| `NUM_ROWS` |  |
| `DATA_SIZE` |  |
| `ENTRY_DELETES` |  |
| `ENTRY_SINGLEDELETES` |  |
| `ENTRY_MERGES` |  |
| `ENTRY_OTHERS` |  |
| `DISTINCT_KEYS_PREFIX` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_index_file_map-table/>

Information Schema ROCKSDB\_SST\_PROPS Table
============================================

    The [Information Schema](../information_schema/index) `ROCKSDB_SST_PROPS` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `SST_NAME` |  |
| `COLUMN_FAMILY` |  |
| `DATA_BLOCKS` |  |
| `ENTRIES` |  |
| `RAW_KEY_SIZE` |  |
| `RAW_VALUE_SIZE` |  |
| `DATA_BLOCK_SIZE` |  |
| `INDEX_BLOCK_SIZE` |  |
| `INDEX_PARTITIONS` |  |
| `TOP_LEVEL_INDEX_SIZE` |  |
| `FILTER_BLOCK_SIZE` |  |
| `COMPRESSION_ALGO` |  |
| `CREATION_TIME` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_sst_props-table/>

Information Schema ROCKSDB\_DDL Table
=====================================

    The [Information Schema](../information_schema/index) `ROCKSDB_DDL` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `TABLE_SCHEMA` |  |
| `TABLE_NAME` |  |
| `PARTITION_NAME` |  |
| `INDEX_NAME` |  |
| `COLUMN_FAMILY` |  |
| `INDEX_NUMBER` |  |
| `INDEX_TYPE` |  |
| `KV_FORMAT_VERSION` |  |
| `TTL_DURATION` |  |
| `INDEX_FLAGS` |  |
| `CF` |  |
| `AUTO_INCREMENT` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_ddl-table/>

Information Schema ROCKSDB\_LOCKS Table
=======================================

    The [Information Schema](../information_schema/index) `ROCKSDB_LOCKS` table is included as part of the [MyRocks](../myrocks/index) storage engine.

 The `PROCESS` [privilege](../grant/index) is required to view the table.

 It contains the following columns:

 


| Column | Description |
| --- | --- |
| `COLUMN_FAMILY_ID` |  |
| `TRANSACTION_ID` |  |
| `KEY` |  |
| `MODE` |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/information-schema-rocksdb_locks-table/>

JIRA - Project Planning and Tracking
====================================

    JIRA is the tool that is used for [bug reporting](../mariadb-community-bug-reporting/index), project planning and tracking in MariaDB development. It replaced the previous tool called [WorkLog](../worklog/index). JIRA is also where you can find the [MariaDB roadmap](https://jira.mariadb.org).

 The MariaDB JIRA is located at <https://jira.mariadb.org>

 Everyone is welcome to sign up for a free account and submit issues, post new tasks or ideas, or to comment on existing issues. The sign up can be found next to the log in boxes on the front page or directly through [this link](https://jira.mariadb.org/secure/Signup!default.jspa).

 After filling out the sign up form you can log in.

 ### Links to JIRA Tasks

 You can easily create links to JIRA tasks in the Knowledge Base using their "mdev" number. For example, the text '`mdev-191`', when entered into the Knowledge Base becomes: [MDEV-191](https://jira.mariadb.org/browse/MDEV-191).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/jira/>

Subqueries and ALL
==================

     [Subqueries](../subqueries/index) using the ALL keyword will return `true` if the comparison returns `true` for each row returned by the subquery, or the subquery returns no rows.

 Syntax
------

 
```
scalar_expression comparison_operator ALL <Table subquery>

```

* `scalar_expression` may be any expression that evaluates to a single value
* `comparison_operator` may be any one of: `=`, `>`, `<`, `>=`, `<=`, `<>` or `!=`

 `ALL` returns:

 * `NULL` if the comparison operator returns `NULL` for at least one row returned by the Table subquery or scalar\_expression returns `NULL`.
* `FALSE` if the comparison operator returns `FALSE` for at least one row returned by the Table subquery.
* `TRUE` if the comparison operator returns `TRUE` for all rows returned by the Table subquery, or if Table subquery returns no rows.

 `NOT IN` is an alias for `<> ALL`.

 Examples
--------

 
```
CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(60);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```

Since `100` > all of `40`,`50` and `60`, the evaluation is true and the row is returned

 Adding a second row to sq1, where the evaluation for that record is false:

 
```
INSERT INTO sq1 VALUES(30);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```

Adding a new row to sq2, causing all evaluations to be false:

 
```
INSERT INTO sq2 VALUES(120);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);
Empty set (0.00 sec)

```

When the subquery returns no results, the evaluation is still true:

 
```
SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2 WHERE num2 > 300);
+------+
| num  |
+------+
|  100 |
|   30 |
+------+

```

Evaluating against a NULL will cause the result to be unknown, or not true, and therefore return no rows:

 
```
INSERT INTO sq2 VALUES (NULL);

SELECT * FROM sq1 WHERE num > ALL (SELECT * FROM sq2);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-and-all/>

Row Subqueries
==============

    A row subquery is a [subquery](../subqueries/index) returning a single row, as opposed to a [scalar subquery](../subqueries-scalar-subqueries/index), which returns a single column from a row, or a literal.

 Examples
--------

 
```
CREATE TABLE staff (name VARCHAR(10), age TINYINT);

CREATE TABLE customer (name VARCHAR(10), age TINYINT);

INSERT INTO staff VALUES ('Bilhah',37), ('Valerius',61), ('Maia',25);

INSERT INTO customer VALUES ('Thanasis',48), ('Valerius',61), ('Brion',51);

SELECT * FROM staff WHERE (name,age) = (SELECT name,age FROM customer WHERE name='Valerius');
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

```

Finding all rows in one table also in another:

 
```
SELECT name,age FROM staff WHERE (name,age) IN (SELECT name,age FROM customer);
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-row-subqueries/>

MariaDB Memory Usage
=====================

   How MariaDB uses memory.

  

| Title | Description |
| --- | --- |
|  [Connect Memory Usage](../connect-memory-usage/index) |  When creating a connection, a THD object is created for that connection.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-memory-usage/>

Subqueries in a FROM Clause
===========================

    Although [subqueries](../subqueries/index) are more commonly placed in a WHERE clause, they can also form part of the FROM clause. Such subqueries are commonly called derived tables.

 If a subquery is used in this way, you must also use an AS clause to name the result of the subquery.

 ORACLE mode
-----------

 
**MariaDB starting with [10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/)**From [MariaDB 10.6.0](https://mariadb.com/kb/en/mariadb-1060-release-notes/), [anonymous subqueries in a FROM clause](../sql_modeoracle/index#simple-syntax-compatibility) (no AS clause) are permitted in [ORACLE mode](../sql_modeoracle-from-mariadb-103/index).

 
Examples
--------

 
```
CREATE TABLE student (name CHAR(10), test CHAR(10), score TINYINT); 

INSERT INTO student VALUES 
  ('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), 
  ('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), 
  ('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), 
  ('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83);

```

Assume that, given the data above, you want to return the average total for all students. In other words, the average of Chun's 148 (75+73), Esben's 74 (43+31), etc.

 You cannot do the following:

 
```
SELECT AVG(SUM(score)) FROM student GROUP BY name;
ERROR 1111 (HY000): Invalid use of group function

```

A subquery in the FROM clause is however permitted:

 
```
SELECT AVG(sq_sum) FROM (SELECT SUM(score) AS sq_sum FROM student GROUP BY name) AS t;
+-------------+
| AVG(sq_sum) |
+-------------+
|    134.0000 |
+-------------+

```

From [MariaDB 10.6](../what-is-mariadb-106/index) in [ORACLE mode](../sql_modeoracle-from-mariadb-103/index), the following is permitted:

 
```
SELECT * FROM (SELECT 1 FROM DUAL), (SELECT 2 FROM DUAL);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-in-a-from-clause/>

Subqueries and ANY
==================

     [Subqueries](../subqueries/index) using the ANY keyword will return `true` if the comparison returns `true` for at least one row returned by the subquery.

 Syntax
------

 The required syntax for an `ANY` or `SOME` quantified comparison is:

 
```
scalar_expression comparison_operator ANY <Table subquery>

```

Or:

 
```
scalar_expression comparison_operator SOME <Table subquery>

```

* `scalar_expression` may be any expression that evaluates to a single value.
* `comparison_operator` may be any one of `=`, `>`, `<`, `>=`, `<=`, `<>` or `!=`.

 `ANY` returns:

 * `TRUE` if the comparison operator returns `TRUE` for at least one row returned by the Table subquery.
* `FALSE` if the comparison operator returns `FALSE` for all rows returned by the Table subquery, or Table subquery has zero rows.
* `NULL` if the comparison operator returns `NULL` for at least one row returned by the Table subquery and doesn't returns `TRUE` for any of them, or if scalar\_expression returns `NULL`.

 `SOME` is a synmonym for `ANY`, and `IN` is a synonym for `= ANY`

 Examples
--------

 
```
CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(120);

SELECT * FROM sq1 WHERE num > ANY (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```

`100` is greater than two of the three values, and so the expression evaluates as true.

 SOME is a synonym for ANY:

 
```
SELECT * FROM sq1 WHERE num < SOME (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```

`IN` is a synonym for `= ANY`, and here there are no matches, so no results are returned:

 
```
SELECT * FROM sq1 WHERE num IN (SELECT * FROM sq2);
Empty set (0.00 sec)

```


```
INSERT INTO sq2 VALUES(100);
Query OK, 1 row affected (0.05 sec)

SELECT * FROM sq1 WHERE num <> ANY (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```

Reading this query, the results may be counter-intuitive. It may seem to read as "SELECT \* FROM sq1 WHERE num does not match any results in sq2. Since it does match 100, it could seem that the results are incorrect. However, the query returns a result if the match does not match any *of* sq2. Since `100` already does not match `40`, the expression evaluates to true immediately, regardless of the 100's matching. It may be more easily readable to use SOME in a case such as this:

 
```
SELECT * FROM sq1 WHERE num <> SOME (SELECT * FROM sq2);
+------+
| num  |
+------+
|  100 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-and-any/>

Subqueries and EXISTS
=====================

    Syntax
------

 
```
SELECT ... WHERE EXISTS <Table subquery>

```

Description
-----------

 [Subqueries](../subqueries/index) using the `EXISTS` keyword will return `true` if the subquery returns any rows. Conversely, subqueries using `NOT EXISTS` will return `true` only if the subquery returns no rows from the table.

 EXISTS subqueries ignore the columns specified by the [SELECT](../select/index) of the subquery, since they're not relevant. For example, 

 
```
SELECT col1 FROM t1 WHERE EXISTS (SELECT * FROM t2); 

```

and 

 
```
SELECT col1 FROM t1 WHERE EXISTS (SELECT col2 FROM t2); 

```

produce identical results.

 Examples
--------

 
```
CREATE TABLE sq1 (num TINYINT);

CREATE TABLE sq2 (num2 TINYINT);

INSERT INTO sq1 VALUES(100);

INSERT INTO sq2 VALUES(40),(50),(60);

SELECT * FROM sq1 WHERE EXISTS (SELECT * FROM sq2 WHERE num2>50);
+------+
| num  |
+------+
|  100 |
+------+

SELECT * FROM sq1 WHERE NOT EXISTS (SELECT * FROM sq2 GROUP BY num2 HAVING MIN(num2)=40);
Empty set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-and-exists/>

Subqueries and JOINs
====================

    A [subquery](../subqueries/index) can quite often, but not in all cases, be rewritten as a [JOIN](../join/index).

 Rewriting Subqueries as JOINS
-----------------------------

 A subquery using `IN` can be rewritten with the `DISTINCT` keyword, for example:

 
```
SELECT * FROM table1 WHERE col1 IN (SELECT col1 FROM table2);

```

can be rewritten as:

 
```
SELECT DISTINCT table1.* FROM table1, table2 WHERE table1.col1=table2.col1;

```

`NOT IN` or `NOT EXISTS` queries can also be rewritten. For example, these two queries returns the same result:

 
```
SELECT * FROM table1 WHERE col1 NOT IN (SELECT col1 FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT col1 FROM table2 WHERE table1.col1=table2.col1);

```

and both can be rewritten as:

 
```
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;

```

Subqueries that can be rewritten as a LEFT JOIN are sometimes more efficient.

 Using Subqueries instead of JOINS
---------------------------------

 There are some scenarios, though, which call for subqueries rather than joins:

 * When you want duplicates, but not false duplicates. Suppose `Table_1` has three rows — {`1`,`1`,`2`} — and `Table_2` has two rows — {`1`,`2`,`2`}. If you need to list the rows in `Table_1` which are also in `Table_2`, only this subquery-based `SELECT` statement will give the right answer (`1`,`1`,`2`):

 
```
SELECT Table_1.column_1 
FROM   Table_1 
WHERE  Table_1.column_1 IN 
  (SELECT Table_2.column_1 
    FROM   Table_2);

```

* This SQL statement won't work:

 
```
SELECT Table_1.column_1 
FROM   Table_1,Table_2 
WHERE  Table_1.column_1 = Table_2.column_1;

```

* because the result will be {`1`,`1`,`2`,`2`} — and the duplication of 2 is an error. This SQL statement won't work either:

 
```
SELECT DISTINCT Table_1.column_1 
FROM   Table_1,Table_2 
WHERE  Table_1.column_1 = Table_2.column_1;

```

* because the result will be {`1`,`2`} — and the removal of the duplicated 1 is an error too.

 * When the outermost statement is not a query. The SQL statement:

 
```
UPDATE Table_1 SET column_1 = (SELECT column_1 FROM Table_2);

```

* can't be expressed using a join unless some rare SQL3 features are used.

 * When the join is over an expression. The SQL statement:

 
```
SELECT * FROM Table_1 
WHERE column_1 + 5 =
  (SELECT MAX(column_1) FROM Table_2);

```

* is hard to express with a join. In fact, the only way we can think of is this SQL statement:

 
```
SELECT Table_1.*
FROM   Table_1, 
      (SELECT MAX(column_1) AS max_column_1 FROM Table_2) AS Table_2
WHERE  Table_1.column_1 + 5 = Table_2.max_column_1;

```

* which still involves a parenthesized query, so nothing is gained from the transformation.

 * When you want to see the exception. For example, suppose the question is: what books are longer than Das Kapital? These two queries are effectively almost the same:

 
```
SELECT DISTINCT Bookcolumn_1.*                     
FROM   Books AS Bookcolumn_1 JOIN Books AS Bookcolumn_2 USING(page_count) 
WHERE  title = 'Das Kapital';

SELECT DISTINCT Bookcolumn_1.* 
FROM   Books AS Bookcolumn_1 
WHERE  Bookcolumn_1.page_count > 
  (SELECT DISTINCT page_count 
  FROM   Books AS Bookcolumn_2 
  WHERE  title = 'Das Kapital');

```

* The difference is between these two SQL statements is, if there are two editions of *Das Kapital* (with different page counts), then the self-join example will return the books which are longer than the shortest edition of *Das Kapital*. That might be the wrong answer, since the original question didn't ask for "... longer than `ANY` book named *Das Kapital*" (it seems to contain a false assumption that there's only one edition).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subqueries-and-joins/>

Subquery Limitations
====================

       
  
 There are a number of limitations regarding [subqueries](../subqueries/index), which are discussed below.   
  
 The following tables and data will be used in the examples that follow:   
  
  


 
```
CREATE TABLE staff(name VARCHAR(10),age TINYINT);

CREATE TABLE customer(name VARCHAR(10),age TINYINT);

```


```
INSERT INTO staff VALUES 
('Bilhah',37), ('Valerius',61), ('Maia',25);

INSERT INTO customer VALUES 
('Thanasis',48), ('Valerius',61), ('Brion',51);

```

### ORDER BY and LIMIT

 To use [ORDER BY](../order-by/index) or limit [LIMIT](../limit/index) in [subqueries](../subqueries/index) both must be used.. For example:

 
```
SELECT * FROM staff WHERE name IN (SELECT name FROM customer ORDER BY name);
+----------+------+
| name     | age  |
+----------+------+
| Valerius |   61 |
+----------+------+

```

is valid, but 

 
```
SELECT * FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name LIMIT 1);
ERROR 1235 (42000): This version of MariaDB doesn't 
  yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

```

is not.

 ### Modifying and Selecting from the Same Table

 It's not possible to both modify and select from the same table in a subquery. For example:

 
```
DELETE FROM staff WHERE name = (SELECT name FROM staff WHERE age=61);
ERROR 1093 (HY000): Table 'staff' is specified twice, both 
  as a target for 'DELETE' and as a separate source for data

```

### Row Comparison Operations

 There is only partial support for row comparison operations. The expression in

 
```
expr op {ALL|ANY|SOME} subquery,

```

must be scalar and the subquery can only return a single column.

 However, because of the way `IN` is implemented (it is rewritten as a sequence of `=` comparisons and `AND`), the expression in 

 
```
expression [NOT] IN subquery

```

is permitted to be an n-tuple and the subquery can return rows of n-tuples. 

 For example:

 
```
SELECT * FROM staff WHERE (name,age) NOT IN (
  SELECT name,age FROM customer WHERE age >=51]
);
+--------+------+
| name   | age  |
+--------+------+
| Bilhah |   37 |
| Maia   |   25 |
+--------+------+

```

is permitted, but 

 
```
SELECT * FROM staff WHERE (name,age) = ALL (
  SELECT name,age FROM customer WHERE age >=51
);
ERROR 1241 (21000): Operand should contain 1 column(s)

```

is not.

 ### Correlated Subqueries

 Subqueries in the FROM clause cannot be correlated subqueries. They cannot be evaluated for each row of the outer query since they are evaluated to produce a result set during when the query is executed.

 ### Stored Functions

 A subquery can refer to a [stored function](../stored-functions/index) which modifies data. This is an extension to the SQL standard, but can result in indeterminate outcomes. For example, take:

 
```
SELECT ... WHERE x IN (SELECT f() ...);

```

where *f()* inserts rows. The function *f()* could be executed a different number of times depending on how the optimizer chooses to handle the query.

 This sort of construct is therefore not safe to use in replication that is not [row-based](../binary-log-formats/index), as there could be different results on the master and the slave.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/subquery-limitations/>

Embedded MariaDB Interface
==========================

    The embedded MariaDB server, `libmysqld` has the identical interface as the [C client library](../client-library-for-c/index)`libmysqclient`.

 The normal usage of the embedded server is to use the normal `mysql.h` include file in your application and link with `libmysqld` instead of `libmysqlclient`.

 The intention is that one should be able to move from a server/client version of MariaDB to a single server version of MariaDB by just changing which library you link with.

 This means that the embedded C client API only changes when the normal C API changes, usually only between major releases.

 The only major change required in your application if you are going to use the embedded server is that you have to call the following functions from your application:

 
```
int mysql_library_init(int argc, char **argv, char **groups)
void mysql_library_end(void);

```

This is also safe to do when using the standard C library.

 Notes
-----

 * libmysqld.so has many more exported symbols than the C library to allow one to expose and use more parts of MariaDB. In normal applications one should not use them, as they may change between every release.
* Before [MariaDB 5.5.60](https://mariadb.com/kb/en/mariadb-5560-release-notes/) ([MariaDB 10.0.35](https://mariadb.com/kb/en/mariadb-10035-release-notes/), [MariaDB 10.1.33](https://mariadb.com/kb/en/mariadb-10133-release-notes/), [MariaDB 10.2.15](https://mariadb.com/kb/en/mariadb-10215-release-notes/), [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/)), the embedded server library did not support SSL when it was used to connect to remote servers.
* Starting with [MariaDB 10.5](../what-is-mariadb-105/index) the embedded server library and related test binaries are no longer part of binary tarball release archives.

 See Also
--------

 * [mysql\_library\_init](../mysql_library_init/index)
* [mysql\_library\_init](http://dev.mysql.com/doc/refman/5.6/en/mysql-library-init.html) in the MySQL documentation.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/embedded-mariadb-interface/>

Code Coverage
=============

    We are working on getting more of the MariaDB source covered by our mysql-test-run (MTR) test suite. This is an ongoing (and slow) task as there is still a lot of old code with not very good coverage.

 Goals for new code
------------------

 For new code in MariaDB, we aim much higher:

 The goals are:

 1. All new lines of code should ideally be tested by MTR.
2. Code which cannot reasonably be tested by MTR needs to be tested by another tool and those code lines marked with /\* purecov: tested \*/.
	* In this case the tool used for testing should be documented in the [worklog](../worklog/index) entry for the code or in the commit message.
3. Code that can't reasonably be tested (such as error conditions) should be marked with '/\* purecov: inspected \*/' so that a reviewer of the code can easily spot this code.
4. Code that is suspected to be deadcode should have a 'DBUG\_ASSERT(0)' or be marked with '/\* purecov: deadcode \*/' so that we have a chance to notice if the code is ever executed.

 The reason we are using 'purecov' to mark lines is an attribution to the [purecov](ftp://ftp.software.ibm.com/software/rational/docs/v2002/dev_tools/purecov/html/ht_intro_pc.htm) tool we originally used for code coverage in the early years of MySQL.

 Markers
-------

 The recommended markers are:

 `/\* purecov: tested \*/`

 * For code lines that are tested by something *other* than mysql-test-run:

 `/\* purecov: inspected \*/`

 * For code lines that are hard to test but for which one has read the line multiple times to ensure it is correct. A code reviewer should also inspect these lines with care as they have not been properly tested.

 `/\* purecov: deadcode \*/`

 * For code lines that one suspects will never be called. Having this marker allows us to generate a warning during mysql-test-run code coverage if this line is executed.

 The comment must be placed on the line/lines that are affected.

 For code blocks larger than 1 line one can use the block syntax:

 
```
/* purecov: begin tested */
....
/* purecov: end */

```

Running mysql-test-run with gcov
--------------------------------

 ### Prerequisites

 1. First make sure that gcov 4.9 is installed.Older versions of the gocv library (lgcov) can't handle running several instances of a program in parallel. This causes the generated .gov files to not contain all executed lines when running mysql-test-run with the --parallel option or running test that starts several mysqld servers, like replication or spider tests.
2. Compile MariaDB with BUILD/compile-pentium64-gcov (if your machine does not have a pentium CPU, hack this script, or just live with the pentium-specific stuff)

 ### Running mysql-test-run

 To be able to see the level of coverage within the current test suite, do the following:

 1. In the mysql-test directory, run this command: `./mysql-test-run -gcov`
2. To see which lines are not yet covered, look at `source_file_name.gcov` in the source tree. In [MariaDB 10.1](../what-is-mariadb-101/index) or below it's in the CMakeFiles directory where the object files are stored. In [MariaDB 10.2](../what-is-mariadb-102/index) it's stored together with the source files.
3. Think hard about a test case which will cover those lines that are not tested, and write one.

 Tools
-----

 * You can use the [code-coverage-with-dgcov/dgcov tool](code-coverage-with-dgcov/dgcov_tool) to check the coverage for the new code. This is especially written and maintained for MariaDB.
* For code coverage you also use the [lcov](http://fedora13.selfip.org/lcov/) tool.

 Code coverage in buildbot
-------------------------

 [buildbot](../buildbot/index), the MariaDB build system, is doing [automatic coverage testing for each push](http://buildbot.askmonty.org/buildbot/builders/kvm-dgcov-jaunty-i386).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/code-coverage/>

QA Metrics
==========

    Code coverage
-------------

 The gcov/lcov reports are run by BuildBot and can be viewed [here](http://i7.askmonty.org/lcov/). The tests that are run to obtain the coverage percentage are listed under the f\_gcov Factory in the BuildBot configuration file.

 Bugs
----

 The list of MariaDB bugs is available on [JIRA](https://jira.mariadb.org).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/qa-metrics/>

QA Datasets
============

   Realistic datasets are essential for proper testing.

  

| Title | Description |
| --- | --- |
|  [DBT-3 Dataset](../dbt-3-dataset/index) |  This page describes our setup for DBT-3 tests. A very cogent resource on th...  |
|  [OpenStreetMap Dataset](../openstreetmap-dataset/index) |  This page describes how to use the OpenStreetMap dataset in testing. Databa...  |
|  [osmdb06.sql](../osmdb06sql/index) |  Below is the schema described in the OpenStreetMap Dataset Use article. To ...  |
|  [DBT-3 Queries](../dbt-3-queries/index) |  Q1 See MDEV-4309 (just speeding up temptable-based GROUP BY execution). Opt...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/qa-datasets/>

QA Tools
========

    Tools used for quality assurance testing:

 * [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index) a template for creating a checklist for testing individual features or WorkLogs
* [MTR/mysqltest reference](http://dev.mysql.com/doc/mysqltest/2.0/en/mysqltest-reference.html)
* [The Random Query Generator](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator)
* [BuildBot Manual](http://buildbot.net/buildbot/docs/latest/)

 See also:
---------

 * [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/qa-tools/>

QA Tests
========

    Optimizer and the Random Query Generator
----------------------------------------

 The RQG is used to test various Optimizer features. See the [Optimizer Quality](../optimizer-quality/index) article for more information.

 Aria Engine Recovery
--------------------

 The [QA - Aria Recovery](../qa-aria-recovery/index) page contains a plan on how to test it.

 Upgrade and Installer Testing
-----------------------------

 * Upgrades using .deb and RPM packages are tested using very simple tests in BuildBot by the various `bld_kvm*` builders.

 ### TODO:

 * More complex tests around .deb, RPM and tarballs;
* Decide on specific upgrade/downgrade paths (e.g. MySQL 5.5 to [MariaDB 2.2](../what-is-mariadb-22/index)?) and methods (mysqldump, mysql\_upgrade) that we support and test each individually;
* Test the Windows installer and service NSIS allows for scripted unattended installs by providing an `/SD` argument to functions such as `MessageBox`.
* Test the contents of the Windows package, e.g. if HELP, .test, etc. files are properly placed and runnable;

 Linking Testing
---------------

 The purpose of those tests is to check that various applications that use `libmysql` can be compiled, linked and run with MariaDB. They are run by the `compile-connectors` builder in BuildBot

 * Perl DBD::mysql
	+ We configure and compile the Perl DBI MySQL driver. Then we run the test suite provided with it.
* PHP
	+ We configure and compile both the `mysql` and `mysqli` PHP drivers without mysql-nd. For each, we run those tests from the PHP test suite that are known to be good (other tests fail for both MySQL and MariaDB).

 ### TODO:

 * Perl and PHP with the embedded library

 Connectors Testing
------------------

 The purpose of those tests is to check that the libraries that implement the MySQL protocol can work with MariaDB.

 * The `libmysql` library/connector is tested both by the MTR test suite (since `mysqltest` links with it)

 ### TODO:

 * PHP with the mysql-nd driver
* Connector C++
* JDBC

 Replication Testing
-------------------

 Individual applications:

 * group commit:
```
perl runall.pl \
  --engine=InnoDB \
  --grammar=conf/replication/rpl_transactions.yy \
  --gendata=conf/replication/rpl_transactions.zz \
  --mysqld=--sync_binlog=1 \
  --mysqld=--innodb-flush_log_at_trx_commit=1 \
  --mysqld=--binlog-dbug_fsync_sleep=100000 \
  --mysqld=--default-storage-engine=InnoDB \
  --threads=15 \
  --queries=1M \
  --duration=600 \
  --validator=None 

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/qa-tests/>

Random Query Generator Tests
============================

    [PQuery](https://github.com/mariadb-corporation/mariadb-qa/tree/master/pquery) is currently in development that does random query generation.

 The documentation for the Random Query Generator is available [here](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator).

 The latest RQG used by MariaDB can be found at:

 * <https://github.com/elenst/rqg/tree/master>
* <https://github.com/MariaDB/randgen/tree/master>

 The list of automatic tests is located in the `buildbot.conf` file in the `[mariadb.org-tools](../mariadb-tools/index)` repository.

 See Also
--------

 * [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](../qa-tools/index)
* [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/random-query-generator-tests/>

Optimizer Quality
=================

    Generating the Queries
----------------------

 As of Nov 2010, there are 5 primary SQL grammars available for testing the Optimizer:

 * `optimizer_nosubquery.yy` generates random queries with no subselects, with up to 3-way join and with various SQL clauses such as aggregates, GROUP BY , HAVING, LIMIT;
* `optimizer_subquery.yy` generates queries with subselects with up to 2 levels of nesting. Subqueries are placed in various locations, such as in the `SELECT` list, in the `ON` clause, etc. Aggregates, LIMIT, HAVING, etc. are used if allowed by the server;
* `optimizer_subquery.yy` generates outer joins of various depths;
* `range_optimizer.yy` tests the range optimizer by joinging several tables and generating various conditions on which range optimization is likely to be applied;
* `range_optimizer2.yy` tests the range optimizer by generating single-table queries that contain a lot of range-optimizable clauses. Avoiding joins allows the single table to be arbitrarily large, this allowing for more interesting range overlaps;

 Validating the Results
----------------------

 As of Nov 2010, the RQG has two primary modes for validating the results:

 * by using a reference implementation. This can be a PostgreSQL, JavaDB or another version or flavor of MySQL/Maria/Drizzle. Testing this way requires trusting external software that is not under our control. Also, it is sometimes difficult to determine which implementation has returned the correct result. Technically, 3 implementations can "vote" as to which is the correct result, but this is not reliable if the implementations all derive from one another.
* by executing the generated query using a different execution plan. This is usually achieved by disabling particular optimizations and thus "downgrading" the plan to a more basic, presumed stable one. It is assumed that a nested-loop-join that takes no advantage of indexes would always provide the correct result. The advantage of this approach is that there is no need for a reference implementation and the source of the wrong result can be obtained by diffing the original and the downgraded execution plan.

 In addition to result set validation, there is a module which executes each generated `SELECT` in various contexts, such as as part of a union, stored procedure, trigger, etc. and makes sure that the query returns a correct result. This is most often used for testing subselects.

 Running a Complete Test Cycle
-----------------------------

 A test cycle is described in a configuration file called the CC file. The CC file contains a list of mysqld options to use, the list of grammars to use and other settings (e.g. Engines, table sizes, etc.). The testing framework will then take a random permutation from the settings described in the file and run them as a RQG test for a predefined time, such as 10 minutes. This is repeated up to 100 times, each with a different random permutation. The PRNG seed for each run will also be different, so different queries will be generated for each run, in addition to using different mysqld options, engine, etc.

 By default, all cycles include MyISAM, Aria and InnoDB, and some percentage are run under Valgrind. Cycles run with both NULL and NOT NULL fields and with and without simple views.

 ### Configuration for Join Cache Testing

 `outer_join_with_cache` is always ON. ``--`join_cache_level` varies from 0 to 8. ``--`join_buffer_size` varies between 1, 100, 1K, 10K and 100K. The `optimizer_no_subquery.yy`, `outer_join.yy` and `range_access.yy` grammars are used. Once semijoin is stable, join\_cache + semijoin will be tested with `optimizer_subquery.yy`.

 ### Configuration for MRR/ICP/DS-MRR-CPK Testing

 ``--`optimizer_use_mrr` is ON, `mrr_sort_keys` is both ON and OFF, `index_condition_pushdown` is both ON and OFF, `join_cache_level` is between 0 and 8, `join_buffer_size` and `mrr_buffer_size` are 1, 100, 1K, 10K and 100K. `optimizer_no_subquery.yy`, `outer_join.yy`, `range_access.yy` and `range_access2.yy` grammars are used.

 ### Configuration for Subquery Testing

 The `optimizer_no_subquery.yy` grammar is used. Each individual `optimizer_switch` related to subquery optimization may be disabled so that the "second best" plan is generated.

 #### Testing [MWL#89](http://askmonty.org/worklog/?tid=89)

 When testing [MWL#89](http://askmonty.org/worklog/?tid=89), the following `optimizer_switch` are used: `in_to_exists=ON,materialization=OFF`, `in_to_exists=OFF,materialization=ON` and `in_to_exists=ON,materialization=ON`. In addition `semijoin` is always OFF to force more queries to use materialization/in\_to\_exists. `subquery_cache` is OFF to prevent subquery cache bugs from showing up during the test.

 See Also
--------

 * [RQG Documentation](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator)
* [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [QA Tools](../qa-tools/index)
* [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/optimizer-quality/>

InnoDB Upgrade Tests
=====================

   RQG-based upgrade tests with focus on InnoDB data live upgrade.

  

| Title | Description |
| --- | --- |
|  [10.3.10 Release Upgrade Tests](../10310-release-upgrade-tests/index) |  Failed with known bug MDEV-13094  |
|  [10.3.9 Release Upgrade Tests](../1039-release-upgrade-tests/index) |  Failed with known bug MDEV-13094  |
|  [10.3.6-gamma Release Upgrade Tests](../1036-gamma-release-upgrade-tests/index) |  Failed with bugs MDEV-15912, MDEV-13103, MDEV-13094  |
|  [10.3.5-gamma Release Upgrade Tests](../1035-gamma-release-upgrade-tests/index) |  Failed with known bugs MDEV-13103, MDEV-13094  |
|  [10.3.4-beta Release Upgrade Tests](../1034-beta-release-upgrade-tests/index) |  Numerous tests failed with MDEV-14990. Also known bugs MDEV-13103, MDEV-13094  |
|  [10.3.3-beta Release Upgrade Tests](../1033-beta-release-upgrade-tests/index) |  20 tests failed (crash upgrade from 10.3.2 is not supported)  |
|  [10.2.18 Release Upgrade Tests](../10218-release-upgrade-tests/index) |  PASSED (several unrelated failures)  |
|  [10.2.17 Release Upgrade Tests](../10217-release-upgrade-tests/index) |  Failed with known bug MDEV-13094  |
|  [10.2.14 Release Upgrade Tests](../10214-release-upgrade-tests/index) |  Failed with known bugs MDEV-13103, MDEV-13094  |
|  [10.2.13 Release Upgrade Tests](../10213-release-upgrade-tests/index) |  Failed with known bugs MDEV-13103, MDEV-13094  |
|  [10.2.12 Release Upgrade Tests](../10212-release-upgrade-tests/index) |  Failed with known bugs MDEV-13103, MDEV-13094.  |
|  [10.2.7 Release Upgrade Tests](../1027-release-upgrade-tests/index) |  FAILED: Upgrade from 10.2, crash recovery; PASSED: Upgrade from 10.0, 10.1, MySQL 5.6, MySQL 5.7  |
|  [10.2.5 Pre-release Upgrade Tests](../1025-pre-release-upgrade-tests/index) |  FAILED: Upgrade from 10.1; PASSED: Upgrade from 10.0, MySQL 5.6, MySQL 5.7  |
|  [10.1.36 Release Upgrade Tests](../10136-release-upgrade-tests/index) |  PASSED  |
|  [10.1.32 Release Upgrade Tests](../10132-release-upgrade-tests/index) |  Failed with a known bug MDEV-13112  |
|  [10.1.30 Release Upgrade Tests](../10130-release-upgrade-tests/index) |  1 test failed (one-time failure upon undo upgrade from 10.1.10)  |
|  [10.1.26 Release Upgrade Tests](../10126-release-upgrade-tests/index) |  FAILED: Upgrade from 10.1, crash recovery; PASSED: Upgrade from 10.0, MySQL 5.6  |
|  [10.1.25 Release Upgrade Tests](../10125-release-upgrade-tests/index) |  FAILED: Upgrade from 10.1, crash recovery; PASSED: Upgrade from 10.0, MySQL 5.6  |
|  [10.1.22 Pre-release Upgrade Tests](../10122-pre-release-upgrade-tests/index) |  FAILED: Upgrade from 10.1; PASSED: Upgrade from 10.0, MySQL 5.6  |
|  [10.0.36 Release Upgrade Tests](../10036-release-upgrade-tests/index) |  PASSED (two failures are unrelated)  |
|  [10.0.34 Release Upgrade Tests](../10034-release-upgrade-tests/index) |  PASSED  |
|  [10.0.32 Release Upgrade Tests](../10032-release-upgrade-tests/index) |  PASSED  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/innodb-upgrade-tests/>

QA - Aria Recovery
==================

    General Principles
------------------

 Recovery is tested via the [RQG](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator), which provides a random workload against the server, and then uses kill -9 to kill the process. After that, recovery is attempted both by using `maria_read_log` and by restarting the `mysqld` process. Once the server has started up, the tables are verified in various ways, including `ALTER|OPTIMIZE|ANALYZE|REPAIR TABLE` as well `SELECT` queries that read the table back and forth using various access methods.

 A combinations `.CC` file named `lp:randgen/conf/engines/maria/maria_recovery.cc` is used to define various `mysql` options and RQG parameters that are relavant to recovery. Then, RQG's `combinations.pl` script is used to run hundreds of individual test runs. Each run uses a random permutation from the settings in the `.CC` file in order to generate a unique workload that is then validated via the `Recovery` RQG Reporter.

 Individual tests
----------------

 The following are the individual tests or test runs that must be completed or created in order to ensure that Aria recovery is solid.

 ### Standard kill -9 testing

 **Done 2011-02-28** The standard `conf/engines/maria/maria_recovery.cc` passes with no failures when run with hundreds of trials.

 ### Testing with small block sizes

 On hold pending 2 bug fixes related to --maria-block-size=1K and --maria-block-size=2K

 ### Testing with small page cache size

 **Done 2011-03-04** Completed 400 rounds with 

 
```
'--mysqld=--maria-block-size=4K --mysqld=--maria-pagecache-buffer-size=128K',
'--mysqld=--maria-block-size=16K --mysqld=--maria-pagecache-buffer-size=256K',
'--mysqld=--maria-block-size=32K --mysqld=--maria-pagecache-buffer-size=512K'

```

two pre-recovery crashes were filed, no recovery issues.

 ### Killing and restarting the recovery process itself

 **In Progress**

 The AriaDoubleRecovery reporter currently attempts doble recovery via maria\_read\_log. The first invocation of maria\_read\_log is killed halfway through the process and the second invocation is left to complete the recovery.

 Future testing will involve doing the same with the mysqld server in place of maria\_read\_log.

 ### Another realistic workload

 The usefullness of the SMF workload, derived from the SimpleMachines forum application means that another such workload is required in order to make sure no residual recovery bugs remain. Hopefully something can be cooked up using Wikipedia so that longer fields and blobs are exercised.

 ### Transactional consistency

 A transactional grammar that simulates transactions using LOCK TABLEs is required. The RecoveryConsistency Reporter can then be used to validate that no partial transactions appear in the database after recovery.

 See also
--------

 * [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](../qa-tools/index)
* [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/qa-aria-recovery/>

Worklog Quality Checklist Template
==================================

     The purpose of this template is to produce individual checklists for testing individual Worklogs. Using a checklist ensures that all WLs are treated equally and that all important points are addressed and tested, or at least considered when clearing the WL for merging into a stable release.

 Inputs
------

  *This section lists all sources of information which can be used as inputs to the testing process. The goal is to gather comprehensive information before creating a testing plan*

 ### Usage scenario

  *Summarize here the intended use for the feature*

 ### Design, architecture and specification

 * **WorkLog number and title:**
	+ *If there is no Worklog, create one or ask one to be created*
* **Are HLS and LLS present?**
	+ *If the HLS or LLS sections are missing, add them or ask that they are created*
* **Reviewer name:**
	+ *Testing suggestions and concerns should be obtained by the reviewer*
* **Customer requirements:**
	+ *Make yourself familiar with any requirements or documents supplied by the customer*
* **Other implementations:**
	+ *Make yourself familiar with other implementations of the feature in other database products or flavors of MySQL*

 ### Testability and observability

 * **Does the feature have an on/off switch?**
	+ *An on/off switch is required in at least the following situations:*
		- *A RQG comparison test will be performed in order to validate the feature;*
		- *The feature may cause a performance degradation for certain queries or usage scenarios;*
		- *The feature is experimental or of interest to a small number of users;*
* **Is the operation of the feature observable?**
	+ *Does the feature leave any traces in SHOW STATUS or EXPLAIN, or in the logs?*

 ### The patch

 * **List of modified files:**
	+ *Obtain a list of all modified files from the version control system, to serve as a starting point for identifying areas of risk within the server or potential interactions with other features. A larger number of modified files may indicate larger risk of unforseen interactions;*
* **Review comments:**
	+ *Paste a link to the review and read it for any concerns that the reviewer may have raised*
* **MTR tests:**
	+ *Does the patch include enough MTR tests?*
* **DGCov output:**
	+ *Generate a report or obtain it from a developer and make sure it is acceptable for all parties*

 ### Feedback from interested parties

 * **Feedback from developer:**
	+ *Paste here any useful information provided by the developer in informal discussions, emails or chat*
	+ *Make sure any concerns raised by the developer are recorded in this document*
* **Feedback from reviewer:**
	+ *Paste here any discussions with the reviewer related to concerns, risks or testing, if not included in the formal review comments for the patch itself*
* **Feedback from customer:**
	+ *Summarize here any relevant discussions with the customer*

 ### Query Patterns

  *If the feature relates to the optimization of a particular set of queries, provide here examples that were extracted from the sources of information listed above, in particular the Worklog and any MTR test cases provided with the patch*

 Risks
-----

   *This section lists any risks inherent to the Worklog, as identified by reviewing the inputs mentioned* 

 ### Refactoring

 * **Areas that have been refactored:**
	+ *List areas that have been refactored in order to accommodate the new functionality*

 ### Interactions

 * **Areas of potential interaction:**
	+ *List areas in the server that may have an interaction with the feature*
* **Does the feature contain engine-specific code, hooks or hacks?**
	+ *List any engine-specific considerations there may be*
* **Does the feature define a new API?**
* **Does the feature relate to transactions or transactional integrity?**
	+ *If yes, is testing required on all storage engines, or using cross-engine transactions or binlog involvement?*
* **Does the feature relate to any of the core server features?**
	+ *Do we need to test with views, triggers, stored procedures, functions, events, partitions, foreign keys, time zones*

 ### Upgrade/Downgrade

 * **Does the feature change any on-disk formats?**
	+ *If yes, testing would be required that upgrading to the new format works properly*
* **Does the feature change the format of the system tables in the `mysql` database?**
	+ *If yes, testing would be required to make sure that any upgrade/downgrade scripts are able to handle the change gracefully*
* **Does the feature change or retire or deprecate any mysqld configuration options?**
	+ *List options here*
* **Is downgrade to be supported?**
	+ *If using the new feature makes the database non-downgradable, this must be a conscious design decision*

 ### User-visible changes

 * **Does the feature change the mysql protocol?**
	+ *If yes, full connectors testing is required to make sure the change is compatible*
* **Does the feature change any result formatting or data types?**
	+ *If yes, testing via the `mysql` client is required to verify that the new format or data type properly arrives at the client*
* **Does the feature change the syntax or the output of a `SHOW` command?**
	+ *If yes, clients, connectors and tools that issue that `SHOW` command and process its output should be tested*
* **Does the feature change anything with respect to `INFORMATION_SCHEMA` and `PERFORMANCE_SCHEMA` ?**

 ### Performance and Optimizer

 * **Does the feature have any performance implications?**
	+ *Is the feature expected to deliver any performance improvement?*
	+ *Is the feature feared to have a performance impact?*
* **Does the feature interact with the Optimizer or indexes?**
	+ *Does the feature change anything related to indexes or data stored in them?*
	+ *Does the feature change anything with respect to any optimizations?*

 ### Replication

 *Does the feature generate or transmit data that may be sent or processed by the slave or tools such as `mysqlbinlog`?*

 * **Which binary log formats should be tested?**
	+ *Certain optimizations or scenarios may only trigger for a particular binary log mode*
* **Are existing replication RQG grammars sufficient to trigger the new code?**
* **Do we need to test DDL in replication, log rotation and such?**
* **Does the change affect the master as well, or just the slave? Is a transactional integrity test indicated?**
* **Do we need to simulate replication failures, server restarts and such?**
* **Do we need to test cloning new slaves from scratch, binary log replay and other replication maintenance activities?**
* **Do we need to cover exotic data types, overly large records, statements that are only safe in a particular binlog mode, etc?**

 ### Extreme conditions and corner case

 * **Does the feature deal with extreme conditions and corner cases?**
	+ *e.g. huge values, huge tables, huge row lengths, blobs, high concurrencies*
* **Is any form of stress testing indicated for the feature?**
	+ *Does the feature have any thread interactions, locking or concurrency mechanisms?*

 Testing Plan
------------

  *This section identifies the testing that will be performed based on the risks identified above*

 ### Additional MTR tests

  *Describe any MTR tests that will be implemented in addition to the ones already present in the patch*

 ### RQG tests

 * **Are new Random Query Generator grammars required?**
	+ *If existing grammars do not cover the new feature*
* **Are new Validators or Reporters required?**
	+ *If the existing RQG validation code can not verify the proper operation of the feature*
* **RQG tests lines to run:**
	+ *provide actual RQG command lines, along with a description of the desired effect*

 ### Manual testing

  *Describe any manual testing that will be performed involving connectors, clients or installers*

 ### Benchmarks and stress tests

  *Describe any benchmarks and stress tests that will be performed. Include the exact parameters and command lines that will be used*

 Hand-off
--------

  *This section identifies final checks to be performed on the test content when it is delivered*

 ### Requirements for MTR tests

 * Are all new mysqld options, SHOW STATUS variables, I\_S tables and such covered with an MTR test?
* Are all new error messages covered with a test?
* Is code coverage acceptable to all parties involved?

 ### Requirements for Random Query Generator tests

 * Has the proper set of RQG grammars been chosen or created?
* Do we have a .CC file listing all interesting mysqld options and RQG variants, in order to run a combinations test? Was the CC file pushed into RQG's LP repository?
* Has an at least 24-hour combination test been run?
* Was code coverage run on the RQG test?
* Were all new grammars and Perl modules pushed into the RQG LP repository?
* Were the RQG tests prepared to be buildbot-ready, as opposed to manually-monitored?
* Does the test include any safeguards against false negatives?
	+ *e.g. all queries generated are bad, which causes no actual replication, which is still reported as test success*
* Are the tests running stably and green in the feature tree's BuildBot?
* Are any bug reports missing reproducible test cases, core files, RQG command lines and the like?

 ### Requirements for Code Coverage

  *This makes it much faster to review code as one knows what it tested and what one needs to review more carefully*

 * Ideally all code should be tested by MTR;
* If code can only be reproduced by an RQG test or other external test, sufficient information must be provided in the Worklog for the test to be reproducible;
* All code should either be tested or reviewed and marked with `/\* purecov inspected \*/`
* Code that is suspected to be unreachable should have an DBUG\_ASSERT(0) and be marked with /\* purecov: deadcode \*/.
* Was an MTR code coverage report for the feature tree generated by i7.stoev.org/lcov?
* Has the dgcov coverage tool been run?
* Are there any notable regressions in the code coverage?
* Was code coverage run on the RQG tests alone, along with an effort to increase it?
* Is the code covered by comments?

 ### Requirements for the code trees

 * Was the stable tree merged **into** the feature tree recently?
* Were all RQG tests pushed into lp:randgen and documented on the RQG manual pages?
* Were all RQG or other automatable tests installed in BuildBot?
* Is the feature tree BuildBot green?

 ### Requirements for closing the Worklog as complete

 * Was the Worklog updated with information on the testing performed?
* Was the QA check box in the Worklog ticked?
* Were all related bugs on Launchpad closed? This includes A) bugs that were tagged to belong to the feature tree, B) bugs assigned to the developer regardless of tree, C) bugs assigned to the tester and D) and orphan bugs just hanging around the same theme or time frame;
* Did the WL complete the entire review procedure, including any back-and-forth emails?
* Has the new feature been documented?

 See also
--------

 * [RQG Documentation](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator)
* [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [RQG Extensions for MariaDB Features](../rqg-extensions-for-mariadb-features/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](../qa-tools/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/worklog-quality-checklist-template/>

Joins
======

   Articles about joins in MariaDB.

  

| Title | Description |
| --- | --- |
|  [Joining Tables with JOIN Clauses](../joining-tables-with-join-clauses/index) |  An introductory tutorial on using the JOIN clause.  |
|  [More Advanced Joins](../more-advanced-joins/index) |  A more advanced tutorial on JOINs.  |
|  [JOIN Syntax](../join-syntax/index) |  Description MariaDB supports the following JOIN syntaxes for the table\_refe...  |
|  [Comma vs JOIN](../comma-vs-join/index) |  A query to grab the list of phone numbers for clients who ordered in the la...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/joins/>

mysql.ndb\_binlog\_index Table
==============================

    The `mysql.ndb_binlog_index` table is not used by MariaDB. It was kept for MySQL compatibility reasons, and is used there for MySQL Cluster. It was removed in [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/).

 For MariaDB clustering, see [Galera](../galera/index).

 The table contains the following fields:

 


| Field | Type | Null | Key | Default |
| --- | --- | --- | --- | --- |
| `Position` | `bigint(20) unsigned` | NO |  | `NULL` |
| `File` | `varchar(255)` | NO |  | `NULL` |
| `epoch` | `bigint(20) unsigned` | NO | PRI | `NULL` |
| `inserts` | `bigint(20) unsigned` | NO |  | `NULL` |
| `updates` | `bigint(20) unsigned` | NO |  | `NULL` |
| `deletes` | `bigint(20) unsigned` | NO |  | `NULL` |
| `schemaops` | `bigint(20) unsigned` | NO |  | `NULL` |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mysqlndb_binlog_index-table/>

INTERSECT
=========

    
**MariaDB starting with [10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/)**INTERSECT was introduced in [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/).

 
The result of an intersect is the intersection of right and left `SELECT` results, i.e. only records that are present in both result sets will be included in the result of the operation.

 Syntax
------

 
```
SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) SELECT ...]
[ORDER BY [column [, column ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

```
 Description
-----------

 MariaDB has supported `INTERSECT` (as well as [EXCEPT](../except/index)) in addition to [UNION](../union/index) since [MariaDB 10.3](../what-is-mariadb-103/index).

 All behavior for naming columns, `ORDER BY` and `LIMIT` is the same as for [UNION](../union/index).

 `INTERSECT` implicitly supposes a `DISTINCT` operation.

 The result of an intersect is the intersection of right and left `SELECT` results, i.e. only records that are present in both result sets will be included in the result of the operation.

 `INTERSECT` has higher precedence than `UNION` and `EXCEPT` (unless running [running in Oracle mode](../sql_modeoracle/index), in which case all three have the same precedence). If possible it will be executed linearly but if not it will be translated to a subquery in the `FROM` clause:

 
```
(select a,b from t1)
union
(select c,d from t2)
intersect
(select e,f from t3)
union
(select 4,4);

```

will be translated to:

 
```
(select a,b from t1)
union
select c,d from
  ((select c,d from t2)
   intersect
   (select e,f from t3)) dummy_subselect
union
(select 4,4)

```

  
   


 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**### Parentheses

 From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), parentheses can be used to specify precedence. Before this, a syntax error would be returned.

 

**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**### ALL/DISTINCT

 `INTERSECT ALL` and `INTERSECT DISTINCT` were introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). The `ALL` operator leaves duplicates intact, while the `DISTINCT` operator removes duplicates. `DISTINCT` is the default behavior if neither operator is supplied, and the only behavior prior to [MariaDB 10.5](../what-is-mariadb-105/index). 

 
Examples
--------

 Show customers which are employees:

 
```
(SELECT e_name AS name, email FROM employees)
INTERSECT
(SELECT c_name AS name, email FROM customers);

```

Difference between [UNION](../union/index), [EXCEPT](../except/index) and INTERSECT. `INTERSECT ALL` and `EXCEPT ALL` are available from [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
```
CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

```

Parentheses for specifying precedence, from [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)

 
```
CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) INTERSECT (SELECT c FROM t3);
+------+
| a    |
+------+
|    1 |
|    6 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) INTERSECT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    6 |
+------+

```

See Also
--------

 * [UNION](../union/index)
* [EXCEPT](../except/index)
* [Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL](https://www.youtube.com/watch?v=UNi-fVSpRm0) (video tutorial)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/intersect/>

Database Normalization Overview
===============================

    Developed in the 1970's by E.F. Codd, database normalization is standard requirement of many database designs. Normalization is a technique that can help you avoid data anomalies and other problems with managing your data. It consists of transforming a table through various stages: *1st normal form*, *2nd normal form*, *3rd normal form*, and beyond.

 It aims to:

 * Eliminate data redundancies (and therefore use less space)
* Make it easier to make changes to data, and avoid anomalies when doing so
* Make referential integrity constraints easier to enforce
* Produce an easily comprehensible structure that closely resembles the situation the data represents, and allows for growth

 Let's begin by creating a sample set of data. You'll walk through the process of normalization first without worrying about the theory, to get an understanding of the reasons you'd want to normalize. Once you've done that, we'll introduce the theory and the various stages of normalization, which will make the whole process described below much simpler the next time you do it.

 Imagine you are working on a system that records plants placed in certain locations, and the soil descriptions associated with them.

 The location:

 * Location Code: 11
* Location name: Kirstenbosch Gardens

 contains the following three plants:

 * Plant code: 431
* Plant name: Leucadendron
* Soil category: A
* Soil description: Sandstone

 * Plant code: 446
* Plant name: Protea
* Soil category: B
* Soil description: Sandstone/Limestone

 * Plant code: 482
* Plant name: Erica
* Soil category: C
* Soil description: Limestone

 The location:

 * Location Code: 12
* Location name: Karbonkelberg Mountains

 contains the following two plants:

 * Plant code: 431
* Plant name: Leucadendron
* Soil category: A
* Soil description: Sandstone

 * Plant code: 449
* Plant name: Restio
* Soil category: B
* Soil description: Sandstone/Limestone

 Tables in a relational database are in a grid, or table format (MariaDB, like most modern DBMSs is a relational database), so let's rearrange this data in the form of a tabular report:

 ### Plant data displayed as a tabular report

 


| Location code | Location name | Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- | --- | --- |
| 11 | Kirstenbosch Gardens | 431 | Leaucadendron | A | Sandstone |
|  |  | 446 | Protea | B | Sandstone/limestone |
|  |  | 482 | Erica | C | Limestone |
| 12 | Karbonkelberg Mountains | 431 | Leucadendron | A | Sandstone |
|  |  | 449 | Restio | B | Sandstone/limestone |

 
How are you to enter this data into a table in the database? You could try to copy the layout you see above, resulting in a table something like the below. The null fields reflect the fields where no data was entered.

 ### Trying to create a table with plant data

 


| Location code | Location name | Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- | --- | --- |
| 11 | Kirstenbosch Gardens | 431 | Leucadendron | A | Sandstone |
| NULL | NULL | 446 | Protea | B | Sandstone/limestone |
| NULL | NULL | 482 | Erica | C | Limestone |
| 1 2 | Karbonkelberg Mountains | 431 | Leucadendron | A | Sandstone |
| NULL | NULL | 449 | Restio | B | Sandstone/limestone |

 
This table is not much use, though. The first three rows are actually a group, all belonging to the same location. If you take the third row by itself, the data is incomplete, as you cannot tell the location the Erica is to be found. Also, with the table as it stands, you cannot use the location code, or any other fields, as a primary key (remember, a primary key is a field, or list of fields, that uniquely identify one record). There is not much use in having a table if you can't uniquely identify each record in it.

 So, the solution is to make sure each table row can stand alone, and is not part of a group, or set. To achieve this, remove the groups, or sets of data, and make each row a complete record in its own right, which results in the table below.

 ### Each record stands alone

 


| Location code | Location name | Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- | --- | --- |
| 11 | Kirstenbosch Gardens | 431 | Leucadendron | A | Sandstone |
| 11 | Kirstenbosch Gardens | 446 | Protea | B | Sandstone/limestone |
| 11 | Kirstenbosch Gardens | 482 | Erica | C | Limestone |
| 12 | Karbonkelberg Mountains | 431 | Leucadendron | A | Sandstone |
| 12 | Karbonkelberg Mountains | 449 | Restio | B | Sandstone/limestone |

 
Notice that the location code cannot be a primary key on its own. It does not uniquely identify a row of data. So, the primary key must be a combination of *location code* and *plant code*. Together these two fields uniquely identify a row of data. Think about it. You would never add the same plant type more than once to a particular location. Once you have the fact that it occurs in that location, that's enough. If you want to record quantities of plants at a location - for this example, you're just interested in the spread of plants - you don't need to add an entire new record for each plant; rather, just add a quantity field. If for some reason you would be adding more than one instance of a plant/location combination, you'd need to add something else to the key to make it unique.

 So, now the data can go in table format, but there are still problems with it. The table stores the information that code *11* refers to *Kirstenbosch Gardens* three times! Besides the waste of space, there is another serious problem. Look carefully at the data below.

 ### Data anomaly

 


| Location code | Location name | Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- | --- | --- |
| 11 | Kirstenbosch Gardens | 431 | Leucadendron | A | Sandstone |
| 11 | Kirstenbosh Gardens | 446 | Protea | B | Sandstone/limestone |
| 11 | Kirstenbosch Gardens | 482 | Erica | C | Limestone |
| 12 | Karbonkelberg Mountains | 431 | Leucadendron | A | Sandstone |
| 12 | Karbonkelberg Mountains | 449 | Restio | B | Sandstone/limestone |

 
Did you notice anything strange? Congratulations if you did! *Kirstenbosch* is misspelled in the second record. Now imagine trying to spot this error in a table with thousands of records! By using the structure in the table above, the chances of data anomalies increases dramatically.

 The solution is simple. You remove the duplication. What you are doing is looking for partial dependencies - in other words, fields that are dependent on a part of a key and not the entire key. Because both the location code and the plant code make up the key, you look for fields that are dependent only on location code or on plant name.

 There are quite a few fields where this is the case. Location name is dependent on location code (plant code is irrelevant in determining project name), and plant name, soil code, and soil name are all dependent on plant number. So, take out all these fields, as shown in the table below:

 ### Removing the fields not dependent on the entire key

 


| Location code | Plant code |
| --- | --- |
| 11 | 431 |
| 11 | 446 |
| 11 | 482 |
| 12 | 431 |
| 12 | 449 |

 
Clearly you can't remove the data and leave it out of your database completely. You take it out, and put it into a new table, consisting of the fields that have the partial dependency and the fields on which they are dependent. For each of the *key* fields in the partial dependency, you create a new table (in this case, both are already part of the primary key, but this doesn't always have to be the case). So, you identified *plant name*, *soil description* and *soil category* as being dependent on *plant code*. The new table will consist of *plant code*, as a key, as well as plant name, soil category and soil description, as shown below:

 ### Creating a new table with location data

 


| Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- |
| 431 | Leucadendron | A | Sandstone |
| 446 | Protea | B | Sandstone/limestone |
| 482 | Erica | C | Limestone |
| 431 | Leucadendron | A | Sandstone |
| 449 | Restio | B | Sandstone/limestone |

 
You do the same process with the location data, shown below:

 ### Creating a new table with location data

 


| Location code | Location name |
| --- | --- |
| 11 | Kirstenbosch Gardens |
| 12 | Karbonkelberg Mountains |

 
See how these tables remove the earlier duplication problem? There is only one record that contains *Kirstenbosch Gardens*, so the chances of noticing a misspelling are much higher. And you aren't wasting space storing the name in many different records. Notice that the location code and plant code fields are repeated in two tables. These are the fields that create the relation, allowing you to associate the various plants with the various locations. Obviously there is no way to remove the duplication of these fields without losing the relation altogether, but it is far more efficient storing a small code repeatedly than a large piece of text.

 But the table is still not perfect. There is still a chance for anomalies to slip in. Examine the table below carefully:

 ### Another anomaly

 


| Plant code | Plant name | Soil category | Soil description |
| --- | --- | --- | --- |
| 431 | Leucadendron | A | Sandstone |
| 446 | Protea | B | Sandstone/limestone |
| 482 | Erica | C | Limestone |
| 431 | Leucadendron | A | Sandstone |
| 449 | Restio | B | Sandstone |

 
The problem in the table above is that the Restio has been associated with Sandstone, when in fact, having a soil category of B, it should be a mix of sandstone and limestone (the soil category determines the soil description in this example). Once again you're storing data redundantly. The *soil category* to *soil description* relationship is being stored in its entirety for each plant. As before, the solution is to take out this excess data and place it in its own table. What you are in fact doing at this stage is looking for transitive relationships, or relationships where a nonkey field is dependent on another nonkey field. *Soil description*, although in one sense dependent on plant code (it did seem to be a partial dependency when we looked at it in the previous step), is actually dependent on *soil category*. So, *soil description* must be removed. Once again, take it out and place it in a new table, along with its actual key (*soil category*) as shown in the tables below:

 ### Plant data after removing the soil description

 


| Plant code | Plant name | Soil category |
| --- | --- | --- |
| 431 | Leucadendron | A |
| 446 | Protea | B |
| 482 | Erica | C |
| 449 | Restio | B |

 
### Creating a new table with the soil description

 


| Soil category | Soil description |
| --- | --- |
| A | Sandstone |
| B | Sandstone/limestone |
| C | Limestone |

 
You've cut down on the chances of anomalies once again. It is now impossible to mistakenly assume soil category B is associated with anything but a mix of sandstone and limestone. The soil description to soil category relationships are stored in only one place - the new *soil* table, where you can be much more certain they are accurate.

 Often, when you're designing a system you don't yet have a complete set of test data available, and it's not necessary if you understand how the data relates. This article has used the tables and their data to demonstrate the consequences of storing data in tables that were not normalized, but without them you have to rely on dependencies between fields, which is the key to database normalization.

 The following articles will describe the process more formally, starting with moving from unnormalized data (or zero normal form) to first normal form.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-overview/>

Comma vs JOIN
=============

    A query to grab the list of phone numbers for clients who ordered in the last two weeks might be written in a couple of ways. Here are two:

 
```
SELECT *
FROM
  clients,
  orders,
  phoneNumbers
WHERE
  clients.id = orders.clientId
  AND clients.id = phoneNumbers.clientId
  AND orderPlaced >= NOW() - INTERVAL 2 WEEK;

```


```
SELECT *
FROM
  clients
  INNER JOIN orders ON clients.id = orders.clientId
  INNER JOIN phoneNumbers ON clients.id = phoneNumbers.clientId
WHERE
  orderPlaced >= NOW() - INTERVAL 2 WEEK;

```

Does it make a difference? Not much as written. But you should use the second form. Why?

 * **Readability.** Once the WHERE clause contains more than two conditions, it becomes tedious to pick out the difference between business logic (only dates in the last two weeks) and relational logic (which fields relate clients to orders). Using the JOIN syntax with an ON clause makes the WHERE list shorter, and makes it very easy to see how tables relate to each other.

 * **Flexibility.** Let's say we need to see all clients even if they don't have a phone number in the system. With the second version, it's easy; just change `INNER JOIN phoneNumbers` to `LEFT JOIN phoneNumbers`. Try that with the first version, and MySQL version 5.0.12+ will issue a syntax error because of the change in precedence between the comma operator and the JOIN keyword. The solution is to rearrange the FROM clause or add parentheses to override the precedence, and that quickly becomes frustrating.

 * **Portability.** The changes in 5.0.12 were made to align with SQL:2003. If your queries use standard syntax, you will have an easier time switching to a different database should the need ever arise.

 See Also
--------

 * ["MySQL joins: ON vs. USING vs. Theta-style"](http://code.openark.org/blog/mysql/mysql-joins-on-vs-using-vs-theta-style) — An interesting blog entry regarding this topic.

 
*The initial version of this article was copied, with permission, from <http://hashmysql.org/wiki/Comma_vs_JOIN> on 2012-10-05.*

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/comma-vs-join/>

Database Normalization: 1st Normal Form
=======================================

    
This article follows on from the [Database Normalization Overview](../database-normalization-overview/index).

 
At first, the data structure was as follows:

 * Location code
* Location name
* 1-n plant numbers (1-n is a shorthand for saying there are many occurrences of this field. In other words, it is a repeating group).
* 1-n plant names
* 1-n soil categories
* 1-n soil descriptions

 This is a completely unnormalized structure - in other words, it is in *zero normal form* So, to begin the normalization process, you start by moving from zero normal form to 1st normal form.

 Tables are in 1st normal form if they follow these rules:

 * There are no repeating groups.
* All the key attributes are defined.
* All attributes are dependent on the primary key.

 What this means is that data must be able to fit into a tabular format, where each field contains one value. This is also the stage where the primary key is defined. Some sources claim that defining the primary key is not necessary for a table to be in first normal form, but usually it's done at this stage and is necessary before we can progress to the next stage. Theoretical debates aside, you'll have to define your primary keys at this point.

 
Although not always seen as part of the definition of 1st normal form, the principle of atomicity is usually applied at this stage as well. This means that all columns must contain their smallest parts, or be indivisible. A common example of this is where someone creates a *name* field, rather than *first name* and *surname* fields. They usually regret it later.

 
So far, the plant example has no keys, and there are repeating groups. To get it into 1st normal form, you'll need to define a primary key and change the structure so that there are no repeating groups; in other words, each row / column intersection contains one, and only one, value. Without this, you cannot put the data into the ordinary two-dimensional table that most databases require. You define location code and plant code as the primary key together (neither on its own can uniquely identify a record), and replace the repeating groups with a single-value attribute. After doing this, you are left with the structure shown in the table below (the primary key is in italics):

 


| Plant location table |
| --- |
| *Location code* |
| Location name |
| *Plant code* |
| Plant name |
| Soil category |
| Soil description |

 
This table is now in 1st normal formal. The process for turning a table into 2nd normal form is continued in the next article.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-1st-normal-form/>

Database Normalization: 2nd Normal Form
=======================================

    
This article follows on from [Database Normalization: 1st Normal Form](../database-normalization-1st-normal-form/index).

 
After converting to first normal form, the following table structure was achieved:

 


| Plant location table |
| --- |
| *Location code* |
| Location name |
| *Plant code* |
| Plant name |
| Soil category |
| Soil description |

 
Is this in 2nd normal form?

 A table is in 2nd normal form if:

 * it is in 1st normal form
* it includes no partial dependencies (where an attribute is only dependent on part of a primary key)

 
For an attribute to be only dependent on part of the primary key, the primary key must consist of more than one field. If the primary key contains only one field, the table is automatically in 2nd normal form if it is in 1st normal form

 
Let's examine all the fields. *Location name* is only dependent on *location code*. *Plant name*, *soil category*, and *soil description* are only dependent on *plant code* (this assumes that each plant only occurs in one soil type, which is the case in this example). So you remove each of these fields and place them in a separate table, with the key being that part of the original key on which they are dependent. For example, with *plant name*, the key is *plant code*. This leaves you with the tables below:

 ### Plant location table with partial dependencies removed

 


| Plant location table |
| --- |
| *Plant code* |
| *Location code* |

 
### Table resulting from fields dependent on plant code

 


| Plant table |
| --- |
| *Plant code* |
| Plant name |
| Soil category |
| Soil description |

 
### Table resulting from fields dependent on location code

 


| Location table |
| --- |
| *Location code* |
| Location name |

 
The resulting tables are now in 2nd normal form. The process for turning a table into 3rd normal form is continued in the next article.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-2nd-normal-form/>

RQG Extensions for MariaDB
==========================

    All recent reasonably stable changes can be found in [our Github repository](https://github.com/MariaDB/randgen). The link points to the master branch; there are other branches created for more specific cases. 

 While all described changes were made in order to test MariaDB code, many of them are applicable to other MySQL flavors as well.

 Galera Mode
-----------

 A set of changes to support running RQG tests with multi-master Galera replication, implemented to test [MariaDB Galera cluster](../galera/index). 

 The top-level script `runall-new.pl` got a new option --galera, which takes a string value. The string can be a combination of 'm' or 's', where each symbol represents a Galera node. 'm' stands for 'master', and 's' stands for 'slave'. 

 The new module `GaleraMySQLd.pm` implements cluster initialization and startup. It is only interested in the number of nodes. 

 Internals are adapted to the multi-master or mixed mode:

 * instead of executing data generation on each started server, it is only executed on the first 'master';
* test flow is executed on each 'master' (but not on 'slaves');
* no result comparison is performed after each query, the flow runs independently, but at the end, if no other errors were encountered, `runall-new.pl` performs dump comparison in the usual manner.

 Also, a sample grammar and data template are provided in `conf/galera`, they are slightly modified versions of conf/engines/engine\_stress.yy and engine\_stress.zz, adapted for Galera taking into account its limitations (e.g. no `LOCK`).

 *Note: `GaleraMySQLd.pm` has defaults for everything mandatory but `wsrep_provider`. If you run the test with more than 1 node, you need to provide the value on the command line in the usual manner (`--mysqld=--wsrep-provider=...`), otherwise the test fail with the corresponding error message.* 

 So, if you provide 

 
```
--galera=mms --mysqld=--wsrep-provider=<path to Galera library>

```

3 nodes will be started, and Galera replication will be set up between them; the data will be generated on the first node; the test flow will be executed on the first and second nodes; at the end of the test, data dump from each node will be taken and compared; node vardirs will be placed under `<vardir>/node0`, `<vardir>/node1`, `<vardir>/node2`.

 CheckFieldValue Validator
-------------------------

 A grammar can set requirements on results of a query through a specifically formatted comment. If the validator finds a comment which matches the template, it performs the requested check. The validation is defined in the comment itself: it says which field in which row in the result set should be checked, and provides the condition (currently simple numeric comparisons: `=`, `<`, `>`, `<=`, `>=`). 

 It allows to do simple verification without implementing a special validator. 

 Example:

 A query in the grammar file

 
```
  SELECT COUNT(*), MAX(`pk`) FROM _table /* Validate 2 > 10 for row all*/;

```

The comment means "Check that the value in field 2 is greater than 10 for all rows" (for this query "all rows" is overkill, it could just as well be "row 1").

 Assuming that there is a table with not more than 10 rows, the validator will produce the error:

 
```
ERROR: For query 'SELECT COUNT(*), MAX(`pk`) FROM `BB` /* Validate 2 > 10 for row 1*/' on row 1 result 10 does not meet the condition > 10
Full row: [1] : 1; [2] : 10;

```

The exit code for this failure is `STATUS_REQUIREMENT_UNMET`.

 *Usage example: investigation of the sporadic failure [MDEV-4578](https://jira.mariadb.org/browse/MDEV-4578)*

 MariadbGtidCrashSafety Reporter
-------------------------------

 The reporter was created to test slave crash-safety with [MariaDB implementation of GTID](../global-transaction-id/index). It is similar to [SlaveCrashRecovery reporter](#slavecrashrecovery-reporter), but is adjusted to check GTID-specific aspects:

 * it restarts the slave with --skip-slave-start, and executes

 
```
CHANGE MASTER .. MASTER_USE_GTID=current_pos;
STOP SLAVE;

```

So, regardless how the replication was set up initially, after the first crash/restart it will start using GTID for sure;

 * while the slave is running, and also before a crash and after restart the reporter checks `gtid*` variables and the contents of the system table `mysql.gtid_slave_pos` and verifies basic consistency of the data, e.g. watches that GTID seq\_no constantly grows.

 SlaveCrashRecovery Reporter
---------------------------

 The reporter can be used to test crash-safety of replication. 

 It is a periodic reporter, every 30 seconds it kills the slave server using `SIGKILL`, and immediately restarts it on the old data directory, with the same parameters as before. On server restart, the reporter checks that the server and the replication started all right. 

 The reporter itself does not check consistency of the data, but it can be used together with `ReplicationConsistency` reporter.

 It is supposed to be used with `runall-new.pl`, so that the server is started without MTR involvement. 

 *Usage example: testing of [GTID in MariaDB 10.0](../global-transaction-id/index)*

 BinlogConsistency Reporter
--------------------------

 The reporter checks that the contents of the binary log correctly reflects the contents of the server. 

 After the main test flow is finished, the reporter creates a data dump of the server, stores its binary logs, shuts down the server, starts a new one with the same parameters, but on a clean data directory, replays the binary logs into it, creates a dump of the new server, and compares two dumps. 

 It is to be used with `runall-new.pl`.

 *Usage example: testing of binlog changes in [MariaDB 10.0](../what-is-mariadb-100/index) (e.g. [MDEV-181](https://jira.mariadb.org/browse/MDEV-181), [MDEV-232](https://jira.mariadb.org/browse/MDEV-232))*

 CrashRecovery Reporter
----------------------

 The idea is very much the same as in the old Recovery reporter: crash the server at the end of the test, restart it and make sure it started all right, and the data is not corrupted. The main difference is that the old reporter restarts the server in a hardcoded pre-defined manner, which limits its use. Instead, CrashRecovery reporter starts the server with the same set of options as the initial one, which imitates a more realistic scenario, and also allows to use it on non-default InnoDB configurations. 

 It is to be used with `runall-new.pl`

 LimitRowsExamined Transformer
-----------------------------

 The transformer was developed for testing new [LIMIT ROWS EXAMINED](../limit-rows-examined/index) functionality added in [MariaDB 5.5](../what-is-mariadb-55/index). It can be used in the usual way, by providing its name in the `--transformers` list. 

 The transformer checks whether the original query already contains a `ROWS EXAMINED` clause. If it does not, it adds the clause either after the `LIMIT` clause, or at the end of the query. In any case (even if `ROWS EXAMINED` was already there), the transformer returns the following sequence of statements:

 * `FLUSH STATUS`
* <the query with `ROWS EXAMINED`>
* <a query which sums up status variables related to examined rows>

 The result of the main query is checked to be a subset of the original query's result set. The sum of status variables is checked to be not greater than the limit provided in the `ROWS EXAMINED` clause, plus a margin. The margin is configured in the transformer. 

 If the result of the transformed query appears not to be a subset of the original result set, `STATUS_LENGTH_MISMATCH` is returned. 

 If the sum of status variables is greater than the maximum allowed value, `STATUS_REQUIREMENT_UNMET` is returned. 

 Note: Status values `STATUS_REQUIREMENT_UNMET` and `STATUS_REQUIREMENT_UNMET_SELECT` were added to `Constants.pm`.

 ShowExplain Validator
---------------------

 The validator was developed for testing the new functionality [SHOW EXPLAIN](../show-explain/index) introduced in [MariaDB 10.0](../what-is-mariadb-100/index). 

 The validator checks that the output of `SHOW EXPLAIN` correlates with the output of traditional `EXPLAIN` executed for the same query. It also tries to filter out known expected mismatches between the produced plans.

 Comparison of VIEW Algorithms
-----------------------------

 RQG already provided `--views[=<view type>]` option, which means that in addition to the normal data generation, views of the requested types will be added and used in the test flow. However, you could only create views of the same type on servers that you were comparing. Now there are `--views1` and `--views2` options, which work the same way as `--basedir1`/`--basedir2`, `--mysqld1`/`--mysqld2`, etc. The backward compatibility is preserved, so you can still use `--views` which will be applied to both servers unless there is `--views1` or `--views2` to override it.

 The change was made in `gentest.pl` and both `runall.pl` and `runall-new.pl`.

 *Usage example: testing of MERGE view extension in [MariaDB 10.0](../what-is-mariadb-100/index) ([MDEV-3862](https://jira.mariadb.org/browse/MDEV-3862))*

 Multiple Redefining Grammars
----------------------------

 RQG allows to provide `--redefine=<grammar file>` option to override or add rules to the main grammar. Sometimes you have a redefining grammar for a feature, and another redefining grammar for an engine, and yet another redefining grammar for a specific version, and combining them makes the number of grammars to grow uncontrollably. The simple change has been made to allow providing several redefining grammars at once, e.g.:

 
```
runall.pl ... --redefine=memory_engine_redefine.yy --redefine=binlog_format_stmt_redefine.yy --redefine=legacy_version_redefine.yy

```

*Warning: It is better not to allow them to override each other, since the result can be unexpected (that is, they should define different sets of rules)*

 The change was made in `gentest.pl` and both `runall.pl` and `runall-new.pl`.

 New Grammar Keywords \_basetable and \_view
-------------------------------------------

 The RQG keyword \_table means any table or view from the test dataset. Often it's good enough, but sometimes it badly increases the number of erroneous statements. Now tables and views can be differentiated in a grammar depending on what the goal is: \_table can still be used for both tables and views, while \_basetable will only pick tables, and \_view will only pick views.

 Example: 

 If you create the following rule in your grammar 

 
```
alter:
        ALTER TABLE _table ENGINE=MyISAM;

```

and you are running the test with views, you will be getting lots of `ER_WRONG_OBJECT` errors ("is not BASE TABLE"). It is hardly the goal, so you can improve the grammar by changing it to 

 
```
alter:
        ALTER TABLE _basetable ENGINE=MyISAM;

```

This way the rule will only pick "real" tables. Of course, if you still want to pick views sometimes, as a sanity check that there is no crash or anything, you can make the rule a bit more complicated, but much better tuned than it was, e.g.

 
```
alter:
        ALTER TABLE alter_object ENGINE=MyISAM;

alter_object:
        _basetable | _basetable | _basetable | _basetable | _basetable | _view ;

```

See Also
--------

 * [RQG Documentation](http://github.com/RQG/RQG-Documentation/wiki/Category:RandomQueryGenerator)
* [RQG Performance Comparisons](../rqg-performance-comparisons/index)
* [Optimizer Quality](../optimizer-quality/index)
* [QA Tools](../qa-tools/index)
* [Worklog Quality Checklist Template](../worklog-quality-checklist-template/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/rqg-extensions-for-mariadb/>

Database Normalization: 3rd Normal Form
=======================================

    
This article follows on from [Database Normalization: 2nd Normal Form](../database-normalization-2nd-normal-form/index).

 
After converting to second normal form, the following table structure was achieved:

 


| Plant location table |
| --- |
| *Plant code* |
| *Location code* |

 



| Plant table |
| --- |
| *Plant code* |
| Plant name |
| Soil category |
| Soil description |

 



| Location table |
| --- |
| *Location code* |
| Location name |

 
Are these tables in 3rd normal form?

 A table is in 3rd normal form if:

 * it is in 2nd normal form
* it contains no transitive dependencies (where a non-key attribute is dependent on the primary key through another non-key attribute)

 
If a table only contains one non-key attribute, it is obviously impossible for a non-key attribute to be dependent on another non-key attribute. Any tables where this is the case that are in 2nd normal form are then therefore also in 3rd normal form.

 
As only the plant table has more than one non-key attribute, you can ignore the others because they are in 3rd normal form already. All fields are dependent on the primary key in some way, since the tables are in second normal form. But is this dependency on another non-key field? *Plant name* is not dependent on either *soil category* or *soil description*. Nor is *soil category* dependent on either *soil description* or *plant name*.

 However, *soil description* is dependent on *soil category*. You use the same procedure as before, removing it, and placing it in its own table with the attribute that it was dependent on as the key. You are left with the tables below:

 ### Plant location table remains unchanged

 


| Plant location table |
| --- |
| *Plant code* |
| *Location code* |

 
### Plant table with soil description removed

 


| Plant table |
| --- |
| *Plant code* |
| Plant name |
| Soil category |

 
### The new soil table

 


| Soil table |
| --- |
| *Soil category* |
| Soil description |

 
### Location table remains unchanged

 


| Location table |
| --- |
| *Location code* |
| Location name |

 
All of these tables are now in 3rd normal form. 3rd normal form is usually sufficient for most tables because it avoids the most common kind of data anomalies. It's suggested getting most tables you work with to 3rd normal form before you implement them, as this will achieve the aims of normalization listed in [Database Normalization Overview](../database-normalization-overview/index) in the vast majority of cases.

 The normal forms beyond this, such as Boyce-Codd normal form and 4th normal form, are rarely useful for business applications. In most cases, tables in 3rd normal form are already in these normal forms anyway. But any skilful database practitioner should know the exceptions, and be able to normalize to the higher levels when required.

 The next article covers Boyce-Codd normal form.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-3rd-normal-form/>

Database Normalization: Boyce-Codd Normal Form
==============================================

    
This article follows on from [Database Normalization: 3rd Normal Form](../database-normalization-3rd-normal-form/index)

 
E.F. Codd and R.F. Boyce, two of the people instrumental in the development of the database model, have been honored by the name of this normal form. E.F. Codd developed and expanded the relational model, and also developed normalization for relational models in 1970, while R.F. Boyce was one of the creators of Structured Query Language (then called SEQUEL).

 In spite of some resources stating the contrary, Boyce-Codd normal form is not the same as 4th normal form. Let's look at an example of data anomalies, which are presented in 3rd normal form and solved by transforming into Boyce-Codd normal form, before defining it.

 ### Table containing data about the student, course, and instructor relationship

 


| Student Course Instructor table |
| --- |
| Student |
| Course |
| Instructor |

 
Assume that the following is true for the table above:

 * Each instructor takes only one course
* Each course can have one or more instructors
* Each student only has one instructor per course
* Each student can take one or more courses

 What would the key be? None of the fields on their own would be sufficient to uniquely identify a records, so you have to use two fields. Which two should you use?

 Perhaps *student* and *instructor* seem like the best choice, as that would allow you to determine the *course*. Or you could use *student* and *course*, which would determine the *instructor*. For now, let's use *student* and *course* as the key:

 ### Using student and course as the key

 


| Student Course Instructor table |
| --- |
| *Student* |
| *Course* |
| Instructor |

 
What normal form is this table in? It's in [1st normal form](../database-normalization-1st-normal-form/index), as it has a key and no repeating groups. It's also in [2nd normal form](../database-normalization-2nd-normal-form/index), as the instructor is dependent on both other fields (students have many courses, and therefore instructors, and courses have many instructors). Finally, it's also in [3rd normal form](../database-normalization-3rd-normal-form/index), as there is only one non-key attribute.

 But there are still some data anomalies. Look at the data sample below:

 ### More data anomalies

 


| Student | Course | Instructor |
| --- | --- | --- |
| Conrad Pienaar | Biology | Nkosizana Asmal |
| Dingaan Fortune | Mathematics | Kader Dlamini |
| Gerrie Jantjies | Science | Helen Ginwala |
| Mark Thobela | Biology | Nkosizana Asmal |
| Conrad Pienaar | Science | Peter Leon |
| Alicia Ncita | Science | Peter Leon |
| Quinton Andrews | Mathematics | Kader Dlamini |

 
The fact that Peter Leon teaches science is stored redundantly, as are Kader Dlamini with mathematics and Nkosizana Asmal with biology. The problem is that the *instructor* determines the *course*. Or put another, *course* is determined by *instructor*. The table conforms to [3rd normal form](../database-normalization-3rd-normal-form/index) rules because no non-key attribute is dependent upon a non-key attribute! Again, you use the familiar method of removing this field and placing it into another table, along with its key:

 ### Student Instructor table after removing Course

 


| Student Course Instructor table |
| --- |
| *Student* |
| *Instructor* |

 
After removing the *course* field, the primary key needs to include both remaining fields to uniquely identify a record.

 ### Resulting Instructor table

 


| Student Course Instructor table |
| --- |
| *Instructor* |
| Course |

 
Although we had chosen course as part of the primary key in the original table, the instructor determines the course, which is why we make it the primary key in this table. As you can see, the redundancy problem has been solved.

 Thus, a table is in Boyce-Codd normal form if:

 * it is in 3rd normal form
* each determinant is a candidate key

 That sounds scary! For most people new to database design, these are new terms. If you followed along with the example above, however, the terms will soon become clear:

 * a *determinant* is an attribute that determines the value of another attribute.
* a *candidate key* is either the key or an alternate key (in other words, the attribute could be a key for that table)

 In the initial table, *instructor* is not a candidate key (alone it cannot uniquely identify the record), yet it determines the course, so the table is not in Boyce-Codd normal form.

 Let's look at the example again, and see what happens if you chose student and instructor as the key. What normal form is the table in this time?

 ### Using student and instructor as the key

 


| Student Course Instructor table |
| --- |
| *Student* |
| *Instructor* |
| Course |

 
Once again it's in 1st normal form because there is a primary key and there are no repeating groups. This time, though, it's not in 2nd normal form because *course* is determined by only part of the key: the instructor. By removing *course* and its key, instructor, you get the structure shown below:

 ### Removing course

 


| Student Instructor table |
| --- |
| *Student* |
| *Instructor* |

 
### Creating a new table with course

 


| Student Course Instructor table |
| --- |
| *Instructor* |
| Course |

 
Either way you do it, by making sure the tables are normalized into Boyce-Codd normal form, you get the same two resulting tables. It's usually the case that when there are alternate fields to choose as a key, it doesn't matter which ones you choose initially because after normalizing you get the same results either way.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-boyce-codd-normal-form/>

Precedence Control in Table Operations
======================================

    
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**Beginning in [MariaDB 10.4](../what-is-mariadb-104/index), you can control the ordering of execution on table operations using parentheses.

 
Syntax
------

 
```
(  expression )
[ORDER BY [column[, column...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

```
 Description
-----------

 Using parentheses in your SQL allows you to control the order of execution for `[SELECT](../select/index)` statements and [Table Value Constructor](../table-value-constructors/index), including `[UNION](../union/index)`, `[EXCEPT](../except/index)`, and `[INTERSECT](../intersect/index)` operations. MariaDB executes the parenthetical expression before the rest of the statement. You can then use `[ORDER BY](../order-by/index)` and `[LIMIT](../limit/index)` clauses the further organize the result-set.

 
**Note**: In practice, the Optimizer may rearrange the exact order in which MariaDB executes different parts of the statement. When it calculates the result-set, however, it returns values as though the parenthetical expression were executed first.

 
Example
-------

 
```
CREATE TABLE test.t1 (num INT);

INSERT INTO test.t1 VALUES (1),(2),(3);

(SELECT * FROM test.t1 
 UNION 
 VALUES (10)) 
INTERSECT 
VALUES (1),(3),(10),(11);
+------+
| num  |
+------+
|    1 |
|    3 |
|   10 |
+------+

((SELECT * FROM test.t1 
  UNION 
  VALUES (10)) 
 INTERSECT 
 VALUES (1),(3),(10),(11)) 
ORDER BY 1 DESC;
+------+
| num  |
+------+
|   10 |
|    3 |
|    1 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/precedence-control-in-table-operations/>

Database Normalization: 5th Normal Form and Beyond
==================================================

    
This article follows on from the [4th normal form](../database-normalization-4th-normal-form/index) article.

 
There are normal forms beyond 4th that are mainly of academic interest, as the problems they exist to solve rarely appear in practice. This series won't discuss then in detail, but for those interested, the following example provides a taste.

 ### The sales rep example

 


| Sales rep | Company | Product |
| --- | --- | --- |
| Felicia Powers | Exclusive | Books |
| Afzal Ignesund | Wordsworth | Magazines |
| Felicia Powers | Exclusive | Magazines |

 
Usually you would store this data in one table, as you need all three records to see which combinations are valid. *Afzal Ignesund* sells magazines for *Wordsworth*, but not necessarily books. *Felicia Powers* happens to sell both books and magazines for *Exclusive*. However, let's add another condition. If a sales rep sells a certain product, and they sell it for a particular company, then they must sell that product for that company.

 Let's look at a larger data set adhering to this condition:

 ### Looking at a larger set of data

 


| Sales rep | Company | Product |
| --- | --- | --- |
| Felicia Powers | Exclusive | Books |
| Felicia Powers | Exclusive | Magazines |
| Afzal Ignesund | Wordsworth | Books |
| Felicia Powers | Wordsworth | Books |
| Felicia Powers | Wordsworth | Magazines |

 
Now, with this extra dependency, you could normalize the table above into three separate tables without losing any facts, as shown below:

 ### Creating a table with Sales rep and Product

 


| Sales rep | Product |
| --- | --- |
| Felicia Powers | Books |
| Felicia Powers | Magazines |
| Afzal Ignesund | Books |

 
### Creating a table with Sales rep and Company

 


| Sales rep | Company |
| --- | --- |
| Felicia Powers | Exclusive |
| Felicia Powers | Wordsworth |
| Afzal Ignesund | Wordsworth |

 
### Creating a table with Company and Product

 


| Company | Product |
| --- | --- |
| Exclusive | Books |
| Exclusive | Magazines |
| Wordsworth | Books |
| Wordsworth | Magazines |

 
Basically, a table is in 5th normal form if it cannot be made into any smaller tables with different keys (most tables can obviously be made into smaller tables with the same key!).

 Beyond 5th normal form you enter the heady realms of domain key normal form, a kind of theoretical ideal. Its practical use to a database designer os similar to that of infinity to a bookkeeper - i.e. it exists in theory but is not going to be used in practice. Even the most demanding owner is not going to expect that of the bookkeeper!

 For those interested in pursuing this academic and highly theoretical topic further, I suggest obtaining a copy of *An Introduction to Database Systems* by C.J. Date, at the time of writing in its 8th edition, or *Relational Theory for Computer Professionals* by the same author.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-5th-normal-form-and-beyond/>

Database Normalization: 4th Normal Form
=======================================

    
This article is intended to be read after the [Boyce-Codd normal form](../database-normalization-boyce-codd-normal-form/index) article.

 
Let's look at the situation where redundancies can creep in even though a table is in [Boyce-Codd normal form](../database-normalization-boyce-codd-normal-form/index). Let's take the student / instructor / course example used in that article, but change one of the initial assumptions.

 Assume that the following is true for the tables below:

 * Each instructor takes only one course
* Each course can have one or more instructors
* Each student can have several instructors per course (this is different to the previous example)
* Each student can take one or more courses

 ### Student Course Instructor data, with several instructors per course

 ### More data anomalies

 


| Student | Course | Instructor |
| --- | --- | --- |
| Conrad Pienaar | Biology | Nkosizana Asmal |
| Dingaan Fortune | Mathematics | Kader Dlamini |
| Gerrie Jantjies | Science | Helen Ginwala |
| Mark Thobela | Biology | Nkosizana Asmal |
| Conrad Pienaar | Science | Peter Leon |
| Alicia Ncita | Science | Peter Leon |
| Quinton Andrews | Mathematics | Kader Dlamini |
| Dingaan Fortune | Mathematics | Helen Ginwala |

 
The data is the same as before, except that Helen Ginwala is teaching science to Gerrie Jantjies as well as mathematics to Dingaan Fortune, and Dingaan Fortune is being taught by both Helen Ginwala and Kader Dlamini for mathematics.

 The only possible key is a combination of all three attributes, as shown below. No other combination will uniquely identify a particular record.

 ### Three attributes as key

 


| Student Course Instructor table |
| --- |
| *Student* |
| *Instructor* |
| *Course* |

 
But this still has some potentially anomalous behavior. The fact that Kader Dlamini teaches mathematics is still stored more than once, as is the fact that Dingaan Thobela takes mathematics. The real problem is that the table stores more than one kind of fact: that of student-to-course relationship, as well as that of a student-to-instructor relationship. You can avoid this, as always, by separating the data into two tables, as shown below:

 ### Creating a table for the student to instructor relationship

 


| Student Instructor table |
| --- |
| *Student* |
| *Instructor* |

 
### Creating a table for the student to course relationship

 


| Student Instructor table |
| --- |
| *Student* |
| *Course* |

 
This situation exists when you have multiple multivalued dependencies. A multivalued dependency exists between two attributes when, for each value of the first attribute, there are one or more associated values of the second attribute. For each value of *student*, there were many values of *course*. This is the first multivalued dependency. Then, for each value of *student*, there are one or more associated values of *instructor*. This is the second multivalued dependency.

 Thus, a table is in 4th normal form if:

 * it is in Boyce-Codd normal form
* it does not contain more than one multivalued dependency

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-normalization-4th-normal-form/>

EXCEPT
======

    The result of `EXCEPT` is all records of the left `SELECT` result set except records which are in right `SELECT` result set, i.e. it is subtraction of two result sets. From [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/), `MINUS` is a synonym when [SQL\_MODE=ORACLE](../sql_modeoracle/index) is set.

 Syntax
======

 
```
SELECT ...
(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) 
  SELECT ...
[(INTERSECT [ALL | DISTINCT] | EXCEPT [ALL | DISTINCT] | UNION [ALL | DISTINCT]) 
  SELECT ...]
[ORDER BY [{col_name | expr | position} [ASC | DESC] 
  [, {col_name | expr | position} [ASC | DESC] ...]]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}
| OFFSET start { ROW | ROWS }
| FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ]

```
 Please note:

 * Brackets for explicit operation precedence are not supported; use a subquery in the `FROM` clause as a workaround).

 Description
-----------

 MariaDB has supported `EXCEPT` and [INTERSECT](../intersect/index) in addition to [UNION](../union/index) since [MariaDB 10.3](../what-is-mariadb-103/index).

 The queries before and after `EXCEPT` must be [SELECT](../select/index) or [VALUES](../table-value-constructors/index) statements.

 All behavior for naming columns, `ORDER BY` and `LIMIT` is the same as for [`UNION`](../union/index). Note that the alternative [SELECT ... OFFSET ... FETCH](../select-offset-fetch/index) syntax is only supported. This allows us to use the `WITH TIES` clause.

 `EXCEPT` implicitly supposes a `DISTINCT` operation.

 The result of `EXCEPT` is all records of the left `SELECT` result except records which are in right `SELECT` result set, i.e. it is subtraction of two result sets.

 `EXCEPT` and `UNION` have the same operation precedence and `INTERSECT` has a higher precedence, unless [running in Oracle mode](../sql_modeoracle/index), in which case all three have the same precedence.   
   


 
**MariaDB starting with [10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)**### Parentheses

 From [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/), parentheses can be used to specify precedence. Before this, a syntax error would be returned.

 

**MariaDB starting with [10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/)**### ALL/DISTINCT

 `EXCEPT ALL` and `EXCEPT DISTINCT` were introduced in [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/). The `ALL` operator leaves duplicates intact, while the `DISTINCT` operator removes duplicates. `DISTINCT` is the default behavior if neither operator is supplied, and the only behavior prior to [MariaDB 10.5](../what-is-mariadb-105/index). 

 
Examples
--------

 Show customers which are not employees:

 
```
(SELECT e_name AS name, email FROM customers)
EXCEPT
(SELECT c_name AS name, email FROM employees);

```

Difference between [UNION](../union/index), EXCEPT and [INTERSECT](../intersect/index). `INTERSECT ALL` and `EXCEPT ALL` are available from [MariaDB 10.5.0](https://mariadb.com/kb/en/mariadb-1050-release-notes/).

 
```
CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SELECT i FROM seqs WHERE i <= 3 UNION SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 UNION ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    3 |
|    4 |
|    5 |
|    6 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 EXCEPT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
|    2 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
+------+

SELECT i FROM seqs WHERE i <= 3 INTERSECT ALL SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    3 |
|    3 |
+------+

```

Parentheses for specifying precedence, from [MariaDB 10.4.0](https://mariadb.com/kb/en/mariadb-1040-release-notes/)

 
```
CREATE OR REPLACE TABLE t1 (a INT);
CREATE OR REPLACE TABLE t2 (b INT);
CREATE OR REPLACE TABLE t3 (c INT);

INSERT INTO t1 VALUES (1),(2),(3),(4);
INSERT INTO t2 VALUES (5),(6);
INSERT INTO t3 VALUES (1),(6);

((SELECT a FROM t1) UNION (SELECT b FROM t2)) EXCEPT (SELECT c FROM t3);
+------+
| a    |
+------+
|    2 |
|    3 |
|    4 |
|    5 |
+------+

(SELECT a FROM t1) UNION ((SELECT b FROM t2) EXCEPT (SELECT c FROM t3));
+------+
| a    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

```

Here is an example that makes use of the [SEQUENCE](../sequence-storage-engine/index) storage engine and the [VALUES](../table-value-constructors/index) statement, to generate a numeric sequence and remove some arbitrary numbers from it:

 
```
(SELECT seq FROM seq_1_to_10) EXCEPT VALUES (2), (3), (4);
+-----+
| seq |
+-----+
|   1 |
|   5 |
|   6 |
|   7 |
|   8 |
|   9 |
|  10 |
+-----+

```

See Also
--------

 * [UNION](../union/index)
* [INTERSECT](../intersect/index)
* [Get Set for Set Theory: UNION, INTERSECT and EXCEPT in SQL](https://www.youtube.com/watch?v=UNi-fVSpRm0) (video tutorial)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/except/>

MINUS
=====

    
**MariaDB starting with [10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/)**`MINUS` was introduced as a synonym for [EXCEPT](../except/index) from [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) when [SQL\_MODE=ORACLE](../sql_modeoracle/index) is set.

 

```
CREATE TABLE seqs (i INT);
INSERT INTO seqs VALUES (1),(2),(2),(3),(3),(4),(5),(6);

SET SQL_MODE='ORACLE';

SELECT i FROM seqs WHERE i <= 3 MINUS SELECT i FROM seqs WHERE i>=3;
+------+
| i    |
+------+
|    1 |
|    2 |
+------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/minus/>

Understanding Denormalization
=============================

    *Denormalization* is the process of reversing the transformations made during [normalization](../database-normalization/index) for performance reasons. It's a topic that stirs controversy among database experts; there are those who claim the cost is too high and never denormalize, and there are those that tout its benefits and routinely denormalize.

 For proponents of denormalization, the thinking is as follows: normalization creates more tables as you proceed towards higher normal forms, but more tables mean there are more joins to be made when data is retrieved, which in turn slows down your queries. For that reason, to improve the performance of certain queries, you can override the advantages to data integrity and return the data structure to a lower normal form.

 A practical approach makes sense, taking into account the limitations of SQL and MariaDB in particular, but being cautious not to needless denormalize. Here are some suggestions:

 * if your performance with a normalized structure is acceptable, you should not denormalize.
* if your performance is unacceptable, make sure normalizing will cause it to become acceptable. There are very likely to be other alternatives, such as better hardware, load balancing, etc. It's hard to undo structural changes later.
* be sure you are willing to trade decreased data integrity for the increase in performance.
* consider possible future scenario, where applications may place different requirements on the data. Denormalizing to enhance performance of a specific application makes your data structure dependent on that application, when in an ideal situation it will be application-independent.

 The table below introduces a common structure where it may not be in your best interests to denormalize. Which normal form is it in?

 


| Customer table |
| --- |
| *ID* |
| First name |
| Surname |
| Address line 1 |
| Address line 2 |
| Town |
| Zip code |

 
It must be in [1st normal form](../database-normalization-1st-normal-form/index) because it has a primary key and there are no repeating groups. It must be in [2nd normal form](../database-normalization-2nd-normal-form/index) because there's only one key, so there cannot be any partial dependencies. And [3rd normal form](../database-normalization-3rd-normal-form/index)? Are there any transitive dependencies? It looks like it. *Zip Code* is probably determined by the town attribute. To transform it into [3rd normal form](../database-normalization-3rd-normal-form/index), you should take out *Zi..p code*, putting it in a separate table with town as the key. In most cases, though, this is not worth doing. So although this table is not in 3rd normal form, separating the table is not worth the trouble. The more tables you have, the more joins you need to do, which slows the system down. The reason you normalize at all is to reduce the size of the tables by removing redundant data, and doing do can often speed up the system. 

 But you also need to look at how your tables are used. *Town* and *Zip code* would almost always be returned together, as part of the address. In most cases, the small amount of space you save by removing the duplicate town/zip code combinations would not offset the slowing down of the system because of the extra joins. In some situations, this may be useful, perhaps where you need to sort addresses according to zip codes or towns for many thousands of customers, and the distribution of data means that a query to the new, smaller table can return the results substantially quicker. In the end, experienced database designers can go beyond rigidly following the steps, as they understand how the data will be used. And that is something only experience can teach you. Normalization is just a helpful set of steps that most often produces an efficient table structure, and not a rule for database design.

 
There are some scary database designs out there, almost always because of not normalizing rather than too much normalization. So if you're unsure, normalize!

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/understanding-denormalization/>

Benefits of Managing MariaDB Containers with Orchestration Software
===================================================================

    In this page we'll discuss why automating [containers](../docker-and-mariadb/index) with software like [Ansible](../ansible-and-mariadb/index) or [Puppet](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index) may be desirable in some cases. To talk about this, we'll first need to discuss why containers are defined *ephemeral*, and how this applies to containerized database servers (particularly MariaDB).

 During the discussion, we should keep in mind that Docker Engine, CRI-I, containerd, Mirantis Container Runtime, Podman and other OCI container runtimes can be used to setup production and/or development environments. These use cases are very different from a database perspective: a production database may be big, and typically contains data that we don't want to lose. Development environments usually contain small sample data that can be rebuilt relatively quickly. This page focuses on the latter case.

 Container Ephemeral Nature
--------------------------

 Images are an [OCI](https://github.com/opencontainers/image-spec/blob/main/spec.md) specified format that can be compiled from Dockerfiles as one of the ways. Containers are the [OCI runtime specified](https://github.com/opencontainers/runtime-spec/blob/main/spec.md) way of creating a runtime version of an images. Normally, a container is not modified from the moment it is created. In other words, containers are usually designed to be **ephemeral**, meaning that they can be destroyed and replaced with new containers at any time. Provided that there is proper redundancy (for example, there are several web servers running the same services) destroying one container and starting a new one of the same type won't cause any damage.

 We will discuss a bit later how this applies to MariaDB, and more generally to database servers.

 When something should change, for example some software version or configuration, normally Dockerfiles are updated and containers are recreated from the latest image versions. For this reason, containers shouldn't contain anything that shouldn't be lost, and recreating them should be an extremely cheap operation. **Docker Compose** or the **Swarm mode** are used to declare which containers form a certain environment, and how they communicate with each other.

 On the contrary, Ansible and Puppet are mainly built to manage the configuration of existing servers. It doesn't recreate servers, it changes their configuration. So Docker and Ansible have very different approaches. For this reason, Ansible and Puppet are not frequently used to deploy containers to production. However, using them together can bring some benefits, especially for development environments.

 More on this later in the page. First, we need to understand how these concepts apply to database servers.

 Stateful Technologies
---------------------

 Using ephemeral containers works very well for *stateless* technologies, like web servers and proxies. These technologies virtually only need binaries, configuration and small amounts of data (web pages). If some data need to be restored after a container creation, it will be a fast operation.

 In the case of a database, the problem is that data can be large and need to be written somewhere. We don't want all databases to disappear when we destroy a container. Even if we had an up-to-date backup, restoring it would take time.

 However, OCI Containers has features called **volumes**. A volume is a directory in the host system mapped to a directory in one or more containers. Volumes are not destroyed when containers are destroyed. They can be used to share data between any number of containers and the host system. Therefore, they are also a good way to persist data.

 Suppose a MariaDB container called `mariadb-main-01` uses a volume that is mapped to `/var/docker/volumes/mariadb-main`. At some point we want to use a more recent MariaDB version. As explained earlier, the container way to do this is to destroy the container and create a new one that uses a more recent version of the MariaDB image.

 So, we will destroy `mariadb-main-01`. The volume is still there. Then we create a new container with the same name, but based on a newer image. We make sure to link the volume to the new container too, so it will be able to use `/var/docker/volumes/mariadb-main` again. At this point we may want to run [mariadb-upgrade](../mariadb-upgrade/index), but apart from that, everything should *just work*.

 The container runtime implementations also provide the opportunity to create a volume with an explicit name and this is also persistent. The actual location on the filesystem is managed by the runtime.

 The above described steps are simple, but running them manually is time consuming and error-prone. Automating them with some automation software like Ansible or Puppet is often desirable.

 Ways to Deploy Containers
-------------------------

 Containers can be deployed in the following ways:

 * Manually. See [Installing and Using MariaDB via Docker](../installing-and-using-mariadb-via-docker/index). This is not recommended for production, or for complex environments. However, it can easily be done for the simplest cases. If we want to make changes to our [custom images](../creating-a-custom-docker-image/index), we'll need to modify the Dockerfiles, destroy the containers and recreate them.
* With Docker Compose. See [Setting Up a LAMP Stack with Docker Compose](../setting-up-a-lamp-stack-with-docker-compose/index) for a simple example. When we modify a Dockerfile, we'll need to destroy the containers and recreate them, which is usually as simple as running `docker-compose down` followed by `docker-compose-up`. After changing `docker-cmpose.yml` (maybe to add a container or a network) we'll simply need to run `docker-compose-up` again, because it is idempotent.
* Using Ansible, Puppet or other automation software, as mentioned before. We can use Ansible or Puppet to create the containers, and run them again every time we want to apply some change to the containers. This means that the containers are potentially created once and modified any number of times.

 In all these cases, it is entirely possible to add [Vagrant](../vagrant-and-mariadb/index) to the picture. Vagrant is a way to deploy or provision several hosts, including virtual machines (the most common case), and containers. It is agnostic in regarding the underlying technology, so it can deploy to a virtual machine, a container, or even a remote server in the same way. Containers can work with Vagrant in two ways:

 * As a [provisioner](../creating-a-vagrantfile/index#provisioners). In this case Vagrant will most commonly deploy a virtual machine, and will use Docker to setup the applications that need to run in it, as containers. This guarantees a higher level of isolation, compared to running the containers in the local host. Especially if you have different environments to deploy locally, because you can have them on different virtual machines.
* As a [provider](../creating-a-vagrantfile/index#providers). Vagrant will deploy one or more containers locally. Once each container is up, Vagrant can optionally use a provisioner on it, to make sure that the container runs the proper software with proper configuration. In this case, Ansible, Puppet or other automation software can be used as a provisioner. But again, this is optional: it is possible to make changes to the Dockerfiles and recreate the containers every time.

 Benefits of Managing Containers with Automation Software
--------------------------------------------------------

 Containers can be entirely managed with Docker Compose or the Swarm mode. This is often a good idea.

 However, choosing to use automation software like Ansible or Puppet has some benefits too. Benefits include:

 * Containers allow working without modifying the host system, and their creation is very fast. Much faster than virtual machines. This makes containers desirable for development environments.
* As explained, making all containers ephemeral and using volumes to store important data is possible. But this means adding some complexity to adapt an ephemeral philosophy to technologies that are not ephemeral by nature (databases). Also, many database professionals don't like this approach. Using automation software allows easily triggering upgrades and configuration changes in the containers, treating them as non-ephemeral systems.
* Sometimes containers are only used in development environments. If production databases are managed via Ansible, Puppet, or other automation software, this could lead to some code duplication. Dealing with configuration changes using the same procedures will reduce the cost of maintenance.
* While recreating containers is fast, being able to apply small changes with Ansible or Puppet can be more convenient in some cases: particularly if we write files into the container itself, or if recreating a container bootstrap involves some lengthy procedure.
* Trying to do something non-standard with Dockerfiles can be tricky. For example, running two processes in a container is possible but can be problematic, as containers are designed to run single main process per container. However there are situations when this is desirable. For example PMM containers run several different processes. Launching additional processes with Ansible or Puppet may be easier than doing it with a Dockerfile.

 With all this in mind, let's see some examples of cases when managing containers with Ansible, Puppet or other automation software is preferable, rather than destroying containers every time we want to make a change:

 * We use Ansible or Puppet in production, and we try to keep development environments as similar as possible to production. By using Ansible/Puppet in development too, we can reuse part of the code.
* We make changes to the containers often, and recreating containers is not as fast as it should be (for example because a MariaDB [dump](../mysqldump/index) needs to be restored).
* Creating a container implies some complex logic that does not easily fit a Dockerfile or Docker Compose (including, but not limited to, running multiple processes per container).

 That said, every case is different. There are environments where these advantages do not apply, or bring a very small benefit. In those cases, the cost of adding some automation with Ansible, Puppet or similar software is probably not justified.

 How to Deploy to Container from Orchestration Software
------------------------------------------------------

 Suppose you want to manage containers configuration with Ansible.

 **At a first glance**, the simplest way is to run Ansible in the host system. It will need to connect to the containers via SSH, so they need to expose the 22 port. But we have multiple containers, so we'll need to map the 22 port of each container to a different port in the host. This is hard to maintain and potentially insecure: in production you want to avoid exposing any container port to the host.

 A better solution is to run Ansible itself in a container. The playbooks will be in a container volume, so we can access them from the host system to manage them more easily. The Ansible container will communicate with other containers using a container network, using the standard 22 port (or another port of your choice) for all containers.

 See Also
--------

 See these pages on how to manage containers with different automation technologies:

 * [Deploying Containers with Ansible](../deploying-docker-containers-with-ansible/index).
* [Deploying Containers with Puppet](../deploying-docker-containers-with-puppet/index).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/benefits-of-managing-mariadb-containers-with-orchestration-software/>

Running MariaDB ColumnStore containers on Linux, Windows and MacOS
==================================================================

    Introduction
============

 The ColumnStore container allows for a simple and lightweight setup of a MariaDB ColumnStore single server instance for evaluation purposes. The configuration is designed for simplified developer / evaluation setup rather than production use. It allows to evaluate ColumnStore on a Windows or MacOS system, setting up a Linux system in a container. The image uses a base OS of RockyLinux.

 Windows Linux Subsystem
=======================

 If you have Windows 10 Creators update installed, then you can install the Ubuntu installation into the Bash console. Please follow the Ubuntu instructions in getting started. If you have recently upgraded and had Bash installed previously, ensure you uninstall and reinstall Bash first to have a clean Ubuntu installation. Note that ColumnStore will be terminated should you terminate the Bash console.

 MariaDB Containers
==================

 [MariaDB Containers](../docker-and-mariadb/index) manages lightweight containers that allows for creation of lightweight and reproducible containers with a dedicated function. On Windows and MacOS systems, Docker Engine transparently runs on a Linux virtual machine.

 Since MariaDB ColumnStore relies on a Syslog daemon, the container must start both ColumnStore and rsyslogd and the runit utility is used to achieve this.

 A single node image can be found at [MariaDB on Docker Hub](https://hub.docker.com/r/mariadb/columnstore/). 

 
```
docker run -d  --name mcs mariadb/columnstore
docker exec -it mcs bash

```

A ColumnStore cluster can be brought up using a compose file provided in the ColumnStore github repository:

 
```
git clone https://github.com/mariadb-corporation/mariadb-columnstore-docker.git
cd mariadb-columnstore-docker/columnstore
docker-compose up -d

```

For more information about how to manage containers, see [Installing and Using MariaDB via Docker](../installing-and-using-mariadb-via-docker/index).

 To test an application that uses ColumnStore, it is desirable to setup several containers that will communicate with each other. To do this, we can use Docker Compose. See [Setting Up a LAMP Stack with Docker Compose](../setting-up-a-lamp-stack-with-docker-compose/index) for more information.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/running-mariadb-columnstore-containers-on-linux-windows-and-macos/>

Creating a Custom Container Image
=================================

    OCI containers, frequently and incorrectly called Docker containers, are created from OCI images. An image contains software that can be launched, including the underlying system. A container is an instance of that software.

 When we want to automate MariaDB, creating an image with MariaDB and the desired configuration, we may want to create an image by ourselves, which fulfils our needs.

 Images Architecture
-------------------

 One "source code" of an image is a Dockerfile. A Dockerfile is written in Docker specific language, and can be compiled into an image by the `docker` binary, using the `docker build` command. It can also be compiled by `[buildah](https://buildah.io/)` using `buildah bud`.

 Most images are based on another image. The base image is specified at the beginning of the Dockerfile, with the `FROM` directive. If the base image is not present in the local system, it is downloaded from the repository specified, or if not specified, from the default repository of the build program. This is often Docker Hub. For example, we can build a `mariadb-rocksdb:10.5` image starting from the `debian:13` image. In this way, we'll have all the software included in a standard Debian image, and we'll add MariaDB and its configuration upon that image.

 All the following Dockerfile directives are compiled into a new Docker image, identified by an SHA256 string. Each of these images is based on the image compiled from the previous directive. A physical compiled image can serve as a base for any number of images. This mechanism saves a lot of disk space, download time and build time.

 The following diagram shows the relationship between Dockerfiles, images and containers:

 ![dockerfiles-images-containers]

 Dockerfile Syntax
-----------------

 Here's a simple Dockerfile example:

 
```
FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install -y mariadb-server

EXPOSE 3306

LABEL version="1.0"
LABEL description="MariaDB Server"

HEALTHCHECK --start-period=5m \
  CMD mariadb -e 'SELECT @@datadir;' || exit 1

CMD ["mariadbd"]

```

This example is not very good for practical purposes, but it shows what a Dockerfile looks like.

 First, we declare that the base image to use is `ubuntu:20.04`.

 Then we run some commands to install MariaDB from the Ubuntu default repositories and stop the MariaDB service.

 We define some metadata about the image with `LABEL`. Any label is valid.

 We declare that the port 3306 (MariaDB default port) should be exposed. However, this has no effect if the port is not exposed at container creation.

 We also define a healthcheck. This is a command that is run to check if the container is healthy. If the return code is 0 the healthcheck succeeds, if it's 1 it fails. In the MariaDB specific case, we want to check that it's running and able to answer a simple query. This is better than just checking that MariaDB process is running, because MariaDB could be running but unable to respond, for example because [max\_connections](../server-system-variables/index#max_connections) was reached or data si corrupted. We read a system variable, because we should not assume that any user-created table exists. We also specify `--start-period` to allow some time for MariaDB to start, keeping in mind that restarting it may take some time if some data is corrupted. Note that there can be only one healthcheck: if the command is specified multiple times, only the last occurrence will take effect.

 Finally, we start the container command: [mariadbd](../mariadbd-options/index). This command is run when a container based on this image starts. When the process stops or crashes, the container will immediately stop.

 Note that, in a container, we normally run mariadbd directly or in an entrypoint script `exec mariadbd`, rather than running [mysqld\_safe](../mysqld_safe/index) or running MariaDB as a service. Containers restart can be handled by the container service. See [automatic restart](../installing-and-using-mariadb-via-docker/index#automatic-restart).

 See the documentation links below to learn the syntax allowed in a Dockerfile.

 ### Using Variables

 It is possible to use variables in a Dockerfile. This allows us, for example, to install different packages, install different versions of a package, or configure software differently depending on how variables are set, without modifying the Dockerfile itself.

 To use a variable, we can do something like this:

 
```
FROM ubuntu:20.04

ARG MARIADB_CONFIG_FILE

...

ENTRYPOINT mariadbd --defaults-file=$MARIADB_CONFIG_FILE

```

Here `ARG` is used after the `FROM` directive, thus the variable cannot be used in `FROM`. It is also possible to declare a variable before `FROM`, so we can use a variable to select the base image to use or its tag, but in this case the variable cannot be used after the `FROM` directive, unless `ARG` is re-declared after the `FROM`. Here is an example:

 
```
ARG UBUNTU_VERSION
FROM ubuntu:$UBUNTU_VERSION

# Uncomment for the build error to be avoided
# ARG UBUNTU_VERSION

# But this will cause a build error:
RUN echo 'Ubuntu version: $UBUNTU_VERSION' > /var/build_log

```

We'll have to assign variables a value when we build the Dockerfile, in this way:

 
```
docker build --build-arg UBUNTU_VERSION=20.04 .

```

Note that Dockerfile variables are just placeholders for values. Dockerfiles do not support assignment, conditionals or loops.

 Versioning and Deploying Images
-------------------------------

 Dockerfiles are normally versioned, as well as the files that are copied to the images.

 Once an image is built, it can be pushed to a container registry. Whenever an image is needed on a host to start containers from it, it is pulled from the registry.

 ### Container registries

 A default container registry for OCI images is Docker Hub. It contains Docker Official Images maintained by the Docker Library team and the community. Any individual or organization can open an account and push images to Docker Hub. Most Docker images are open source: the Dockerfiles and the needed files to build the images are usually on GitHub.

 It is also possible to setup a self-hosted registry. Images can be pushed to that registry and pulled from it, instead of using Docker Hub. If the registry is not publicly accessible, it can be used to store images used by the organization without making them publicly available.

 But a self-hosted registry can also be useful for open source images: if an image is available on Docker Hub and also on a self-hosted registry, in case Docker Hub is down or not reachable, it will still be possible to pull images.

 ### Choosing Image Names and Tags

 The names of images developed by the community follow this schema:

 
```
repository/maintainer/technology

```

It doesn't matter if the maintainer is an individual or an organization. For images available on Docker Hub, the maintainer is the name of a Docker Hub account.

 Official images maintained by the Docker Library maintainers have the implicit name of `library` filled in by the container fetching tool. For example, the official MariaDB image is called `mariadb` which is an alias for `docker.io/library/mariadb`.

 All images have a tag, which identifies the version or the variant of an image. For example, all MariaDB versions available on Docker are used as image tags. [MariaDB 10.11](../what-is-mariadb-1011/index) is called `mariadb:10.11`.

 By conversion, tags form a hierarchy. So for example, there is a `10.1.1` tag whose meaning will not change over time. `10.5` will always identify the latest stable version in the 10.5 branch. For some time it was `10.5.1`, then it became `10.5.2`, and so on.

 When we pull an image without specifying a tag (ie, `docker pull mariadb`), we are implicitly requiring the image with the `latest` tag. This is even more mutable: at different periods of time, it pointed to the latest `10.0` version, to the latest `10.1` version, and so on.

 In production, it is always better to know for sure which version we are installing. Therefore it is better to specify a tag whose meaning won't change over time, like `10.5.21`. To keep to a latest LTS version, the `lts` can be used.

 ### Pushing and Pulling Images

 To pull an image from Docker Hub or a self-hosted registry, we use the `docker pull` command. For example:

 
```
docker pull mariadb:10.5

```

This command downloads the specified image if it is not already present in the system, or if the local version is not up to date.

 After modifying a Dockerfile, we can build an image in this way:

 
```
docker build .

```

This step can be automated by services like Docker Hub and GitHub. Check those service's documentation to find out how this feature works.

 Once an image is created, it can be pushed to a registry. We can do it in this way:

 
```
docker push <image_name>:<tag>

```

### Docker Content Trust

 Docker has a feature called Docker Content Trust (DCT). It is a system used to digitally sign images, based on PEM keys. For environments where security is a major concern, it is important to sign images before pushing them. This can be done with both Docker Hub and self-hosted registries.

 Good Practices and Caveats
--------------------------

 As mentioned, a Dockerfile is built by creating a new image for each directive that follows `FROM`. This leads to some considerations.

 * Sometimes it can be a good idea to run several shell commands in a single `RUN` directive to avoid creating images that are not useful.
* Modifying a directive means that all subsequent directives also need to be rebuilt. When possible, directives that are expected to change often should follow directives that will change seldom.
* Directives like `LABEL` or `EXPOSE` should be placed close to the end of Dockerfiles. In this way they will be rebuilt often, but this operation is cheap. On the other side, changing a label should not trigger a long rebuild process.
* Variables should be used to avoid Dockerfiles proliferation. But if a variable is used, changing its value should be tested. So, be sure not to use variables without a good reason.
* Writing logic into a Dockerfile is impossible or very hard. Call shell scripts instead, and write your logic into them. For example, in a shell script it is easy to perform a certain operation only if a variable is set to a certain value.
* If you need MariaDB containers with different configurations or different sets of plugins, use the method explained above. Do not create several Dockerfiles, with different tags, for each desired configuration or plugin set. This may lead to undesired code duplication and increased maintenance costs.

 References
----------

 More details can be found in the Docker documentation:

 * [Dockerfile reference](https://docs.docker.com/engine/reference/builder/).
* [docker build](https://docs.docker.com/engine/reference/commandline/build/).
* [Repositories](https://docs.docker.com/docker-hub/repos/).
* [Deploy a registry server](https://docs.docker.com/registry/deploying/).
* [Content trust in Docker](https://docs.docker.com/engine/security/trust/).

 See also:

 * [Privacy-Enhanced Mail](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail) on Wikipedia.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-a-custom-container-image/>

Setting Up a LAMP Stack with Docker Compose
===========================================

    Docker Compose is a tool that allows one to declare which Docker containers should run, and which relationships should exist between them. It follows the **infrastructure as code** approach, just like most automation software and Docker itself.

 For information about installing Docker Compose, see [Install Docker Compose](https://docs.docker.com/compose/install/) in Docker documentation.

 The `docker-compose.yml` File
-----------------------------

 When using Docker Compose, the Docker infrastructure must be described in a YAML file called `docker-compose.yml`.

 Let's see an example:

 
```
version: "3"

services:
  web:
    image: "apache:${PHP_VERSION}"
    restart: 'always'
    depends_on:
      - mariadb
    restart: 'always'
    ports:
      - '8080:80'
    links:
      - mariadb
  mariadb:
    image: "mariadb:${MARIADB_VERSION}"
    restart: 'always'
    volumes: 
      - "/var/lib/mysql/data:${MARIADB_DATA_DIR}"
      - "/var/lib/mysql/logs:${MARIADB_LOG_DIR}"
      - /var/docker/mariadb/conf:/etc/mysql
    environment:
      MYSQL_ROOT_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
      MYSQL_DATABASE: "${MYSQL_DATABASE}"
      MYSQL_USER: "${MYSQL_USER}"
      MYSQL_PASSWORD: "${MYSQL_PASSWORD}"

```

In the first line we declare that we are using version 3 of the Docker compose language.

 Then we have the list of services, namely the `web` and the `mariadb` services.

 Let's see the properties of the services:

 * `port` maps the 8080 container port to the 80 host system port. This is very useful for a development environment, but not in production, because it allows us to connect our browser to the containerized web server. Normally there is no need to connect to MariaDB from the host system.
* `links` declares that this container must be able to connect `mariadb`. The hostname is the container name.
* `depends_on` declares that `mariadb` needs to start before `web`. This is because we cannot do anything with our application until MariaDB is ready to accept connections.
* `restart: always` declares that the containers must restart if they crash.
* `volumes` creates volumes for the container if it is set in a service definition, or a volume that can be used by any container if it is set globally, at the same level as `services`. Volumes are directories in the host system that can be accessed by any number of containers. This allows destroying a container without losing data.
* `environment` sets environment variables inside the container. This is important because in setting these variables we set the MariaDB root credentials for the container.

 ### About Volumes

 It is good practice to create volumes for:

 * The [data directory](../server-system-variables/index#datadir), so we don't lose data when a container is created or replaced, perhaps to upgrade MariaDB.
* The directory where we put all the logs, if it is not the datadir.
* The directory containing all configuration files (for development environments), so we can edit those files with the editor installed in the host system. Normally no editor is installed in containers. In production we don't need to do this, because we can copy files from a repository located in the host system to the containers.

 Note that Docker Compose variables are just placeholders for values. Compose does not support assignment, conditionals or loops.

 ### Using Variables

 In the above example you can see several variables, like `${MARIADB_VERSION}`. Before executing the file, Docker Compose will replace this syntax with the `MARIADB_VERSION` variable.

 Variables allow making Docker Compose files more re-usable: in this case, we can use any MariaDB image version without modifying the Docker Compose file.

 The most common way to pass variables is to write them into a file. This has the benefit of allowing us to version the variable file along with the Docker Compose file. It uses the same syntax you would use in BASH:

 
```
PHP_VERSION=8.0
MARIADB_VERSION=10.5
...

```

For bigger setups, it could make sense to use different environment files for different services. To do so, we need to specify the file to use in the Compose file:

 
```
services:
  web:
    env_file:
      - web-variables.env
...

```

Docker Compose Commands
-----------------------

 Docker Compose is operated using `docker-compose`. Here we'll see the most common commands. For more commands and for more information about the commands mentioned here, see the documentation.

 Docker Compose assumes that the Composer file is located in the current directory and it's called `docker-compose.yml`. To use a different file, the `-f <filename>` parameter must be specified.

 To pull the necessary images:

 
```
docker-compose pull

```

Containers described in the Compose file can be created in several ways.

 To create them only if they do not exist:

 
```
docker-compose up --no-recreate

```

To create them if they do not exist and recreate them if their image or configuration have changed:

 
```
docker-compose up

```

To recreate containers in all cases:

 
```
docker-compose up --force-recreate

```

Normally `docker-compose up` starts the containers. To create them without starting them, add the `--no-start` option.

 To restart containers without recreating them:

 
```
docker-compose restart

```

To kill a container by sending it a `SIGKILL`:

 
```
docker-compose kill <service>

```

To instantly remove a running container:

 
```
docker-compose rm -f <serice>

```

To tear down all containers created by the current Compose file:

 
```
docker-compose down

```

Docker Compose Resources and References
---------------------------------------

 * [Overview of Docker Compose](https://docs.docker.com/compose/) in the Docker documentation.
* [Compose file](https://docs.docker.com/compose/compose-file/) in the Docker documentation.
* [Docker Compose](https://github.com/docker/compose) on GitHub.

 Further information about the concepts explained in this page can be found in Docker documentation:

 * [Environment variables in Compose](https://docs.docker.com/compose/environment-variables/).
* [Overview of docker-compose CLI](https://docs.docker.com/compose/reference/overview/).
* [Compose command-line reference](https://docs.docker.com/compose/reference/).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/setting-up-a-lamp-stack-with-docker-compose/>

Docker Security Concerns
========================

    When using Docker containers in production, it is important to be aware of Docker security concerns.

 Host System Security
--------------------

 All Docker containers are built upon the host system's kernel. If the host system's kernel has security bugs, those bugs are also present in the containers.

 In particular, Docker leverages two Linux features:

 * Namespaces, to isolate containers from each other and make sure that a container can't establish unauthorized connections to another container.
* cgroups, to limit the resources (CPU, memory, IO) that each container can consume.

 The administrators of a system running Docker should be particularly careful to upgrade the kernel whenever security bugs to these features are fixed.

 Docker, like most container technologies, uses the runC open source library. runC security bugs are likely to affect Docker.

 Finally, Docker's own security bugs potentially affect all containers.

 It is important to note that when we upgrade the kernel, runC or Docker itself we cause downtime for all the containers running on the system.

 Images Security
---------------

 Docker containers are built from images. If security is a major concern, you should make sure that the images you use are secure.

 If you want to be sure that you are pulling authentic images, you should only pull images signed with [Docker Content Trust](../creating-a-custom-docker-image/index#docker-content-trust).

 The images should create and use a system user with less privileges than root. For example, the MariaDB daemon usually runs as a user called `mysql`, who belongs the `mysql` group. There is no need to run it as root (and by default it will refuse to start as root). Containers should not run it as root. Using an unprivileged user will reduce the chances that a bug in Docker or in the kernel will allow the user to gain access to the host system.

 Updated images should be used. An image usually downloads packages information at build time. If the image is not recently built, a newly created container will have old packages. Updating the packages on container creation and regularly re-updating them will ensure that the container uses packages with the most recent versions. Rebuilding an image often will reduce the time necessary to update the packages the first time.

 Security bugs are usually important for a database server, so you don't want your version of MariaDB to contain known security bugs. But suppose you also have a bug in Docker, in runC, or in the kernel. A bug in a user-facing application may allow an attacker to exploit a bug in those lower level technologies. So, after gaining access to the container, an attacker may gain access to the host system. This is why system administrators should keep both the host system and the software running in the containers updated.

 References
----------

 For more information, see the following links:

 * [Docker security](https://docs.docker.com/engine/security/) on Docker documentation.
* [Linux namespaces](https://en.wikipedia.org/wiki/Linux_namespaces) on Wikipedia.
* [cgroups](https://en.wikipedia.org/wiki/Cgroups) on Wikipedia.
* [runC repository](https://github.com/opencontainers/runc).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/docker-security-concerns/>

MariaDB Container Cheat Sheet
=============================

    * Get the images  
 Images can be found on [MariaDB Docker Hub](https://hub.docker.com/_/mariadb).  
 To get the list of images run

 
```
$ docker images -a

```

* Create the network

 
```
$ docker network create mynetwork

```

It is good practice to create the Docker network and attach the container to the network.

 * Start the container with server options  
 To start the container in the background with the MariaDB server image run:

 
```
$ docker run --rm --detach \
--env MARIADB_ROOT_PASSWORD=sosecret \
--network mynetwork \
--name mariadb-server \
mariadb:latest

```

Additionally [environment variables](https://hub.docker.com/_/mariadb) are also provided.

 * Get the list of running containers (specify the flag **-a** in case you want to see all containers)

 
```
$ docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS      NAMES
ad374ec8a272   mariadb:latest   "docker-entrypoint.s…"   3 seconds ago    Up 1 second     3306/tcp   mariadb-server

```

* Start the client from the container

 To start the *mariadb* client inside the created container and run specific commands, run the following:

 
```
$ docker exec -it mariadb-server mariadb -psosecret -e "SHOW PLUGINS"

```

* Inspect logs from the container

 
```
$ docker logs mariadb-server

```

In the logs you can find status information about the server, plugins, generated passwords, errors and so on.

 * Restart the container

 
```
$ docker restart mariadb-server

```

* Run commands within the container

 
```
$ docker exec -it mariadb-server bash

```

* Use a volume to specify configuration options

 
```
$ docker run --detach --env MARIADB_USER=anel \
  --env MARIADB_PASSWORD=anel \
  --env MARIADB_DATABASE=my_db \
  --env MARIADB_RANDOM_ROOT_PASSWORD=1 \
  --volume $PWD/my_container_config:/etc/mysql/conf.d:z \
  --network mynetwork \
  --name mariadb-server1 \
   mariadb:latest 

```

One can specify custom [configuration files](../configuring-mariadb-with-option-files/index) through the **/etc/mysql/conf.d** volume during container startup.

 * Use a volume to specify grants during container start

 
```
$ docker run --detach --env MARIADB_USER=anel\
  --env MARIADB_PASSWORD=anel \
  --env MARIADB_DATABASE=my_db \
  --env MARIADB_RANDOM_ROOT_PASSWORD=1 \
  --volume $PWD/my_init_db:/docker-entrypoint-initdb.d \
  --network mynetwork \
  --name mariadb-server1 \
   mariadb:latest 

```

User created with the environment variables has full grants only to the *MARIADB\_DATABASE*. In order to override those grants, one can specify grants to a user, or execute any SQL statements from host file to **docker-entrypoint-initdb.d**. In the *local\_init\_dir* directory we can find the file, created like this:

 
```
$ echo "GRANT ALL PRIVILEGES ON *.* TO anel;" > my_init_db/my_grants.sql

```

See Also
--------

 * [Installing and using MariaDB via Docker](../installing-and-using-mariadb-via-docker/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-container-cheat-sheet/>

MariaDB Server Docker Official Image Environment Variables
==========================================================

     When you start the %%IMAGE%% image, you can adjust the initialization of the MariaDB Server instance by passing one or more environment variables on the docker run command line. Do note that none of the variables below will have any effect if you start the container with a data directory that already contains a database: any pre-existing database will always be left untouched on container startup.

 From tag 10.2.38, 10.3.29, 10.4.19, 10.5.10 onwards, and all 10.6 and later tags, the MARIADB\_\* equivalent variables are provided. MARIADB\_\* variants will always be used in preference to MYSQL\_\* variants.

 One of MARIADB\_ROOT\_PASSWORD\_HASH, MARIADB\_ROOT\_PASSWORD, MARIADB\_ALLOW\_EMPTY\_ROOT\_PASSWORD, or MARIADB\_RANDOM\_ROOT\_PASSWORD (or equivalents, including \*\_FILE), is required. The other environment variables are optional.

 ### MARIADB\_ROOT\_PASSWORD\_HASH / MARIADB\_ROOT\_PASSWORD / MYSQL\_ROOT\_PASSWORD

 This specifies the password that will be set for the MariaDB root superuser account.

 ### MARIADB\_ALLOW\_EMPTY\_ROOT\_PASSWORD / MYSQL\_ALLOW\_EMPTY\_PASSWORD

 Set to a non-empty value, like `1`, to allow the container to be started with a blank password for the root user. NOTE: Setting this variable to yes is not recommended unless you really know what you are doing, since this will leave your MariaDB instance completely unprotected, allowing anyone to gain complete superuser access.

 ### MARIADB\_RANDOM\_ROOT\_PASSWORD / MYSQL\_RANDOM\_ROOT\_PASSWORD

 Set to a non-empty value, like yes, to generate a random initial password for the root user. The generated root password will be printed to stdout (GENERATED ROOT PASSWORD: .....).

 ### MARIADB\_ROOT\_HOST / MYSQL\_ROOT\_HOST

 This is the hostname part of the root user created. By default this is %, however it can be set to any default MariaDB allowed hostname component. Setting this to localhost will prevent any root user being accessible except via the unix socket.

 ### MARIADB\_DATABASE / MYSQL\_DATABASE

 This variable allows you to specify the name of a database to be created on image startup.

 ### MARIADB\_USER / MYSQL\_USER, MARIADB\_PASSWORD\_HASH / MARIADB\_PASSWORD / MYSQL\_PASSWORD

 Both user and password variables, along with a database, are required for a user to be created. This user will be granted all access (corresponding to GRANT ALL) to the MARIADB\_DATABASE database.

 Do not use this mechanism to create the root superuser, that user gets created by default with the password specified by the MARIADB\_ROOT\_PASSWORD / MYSQL\_ROOT\_PASSWORD variable.

 ### MARIADB\_MYSQL\_LOCALHOST\_USER / MARIADB\_MYSQL\_LOCALHOST\_GRANTS

 Set MARIADB\_MYSQL\_LOCALHOST\_USER to a non-empty value to create the mysql@locahost database user. This user is especially useful for a variety of health checks and backup scripts.

 The mysql@localhost user gets `[USAGE](../grant/index#usage)` privileges by default. If more access is required, additional global privileges in the form of a comma separated list can be provided. If you are sharing a volume containing MariaDB's unix socket (/var/run/mysqld by default), privileges beyond `[USAGE](../grant/index#usage)` can result in confidentiality, integrity and availability risks, so use a minimal set. Its also possible to use for [Mariadb-backup](../mariabackup/index). The [healthcheck.sh](../using-healthcheck-sh-script/index) script also documents the required privileges for each health check test.

 ### MARIADB\_HEALTHCHECK\_GRANTS

 Set MARIADB\_HEALTHCHECK\_GRANTS to the grants required to be given to the `healtcheck@localhost`, `healtcheck@127.0.0.1`, `healtcheck@::1`, users. When not specified the default grant is `[USAGE](../grant/index#usage)`.

 The main value used here will be `[REPLICA MONITOR](../grant/index#replica-monitor) for the [healthcheck --replication](../using-healthcheck-sh-script/index#-replication) test.`

 ### MARIADB\_INITDB\_SKIP\_TZINFO / MYSQL\_INITDB\_SKIP\_TZINFO

 By default, the entrypoint script automatically loads the timezone data needed for the CONVERT\_TZ() function. If it is not needed, any non-empty value disables timezone loading.

 ### MARIADB\_AUTO\_UPGRADE / MARIADB\_DISABLE\_UPGRADE\_BACKUP

 Set MARIADB\_AUTO\_UPGRADE to a non-empty value to have the entrypoint check whether [mariadb-upgrade](../mariadb-upgrade/index) needs to run, and if so, run the upgrade before starting the MariaDB server.

 Before the upgrade, a backup of the system database is created in the top of the datadir with the name system\_mysql\_backup\_\*.sql.zst. This backup process can be disabled with by setting MARIADB\_DISABLE\_UPGRADE\_BACKUP to a non-empty value.

 ### MARIADB\_MASTER\_HOST

 When specified, the container will connect to this host and replicate from it.

 ### MARIADB\_REPLICATION\_USER / MARIADB\_REPLICATION\_PASSWORD\_HASH / MARIADB\_REPLICATION\_PASSWORD

 When MARIADB\_MASTER\_HOST is specified, MARIADB\_REPLICATION\_USER and MARIADB\_REPLICATION\_PASSWORD will be used to connect to the master.

 When not specified, the MARIADB\_REPLICATION\_USER will be created with the REPLICATION REPLICA grants required to a client to start replication.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-server-docker-official-image-environment-variables/>

Buildbot Setup for MacOSX
=========================

    Setting up a Buildbot slave on Mac OS X
---------------------------------------

 Install buildbot-slave using [macports](http://www.macports.org/) or buildbot from [fink](http://www.finkproject.org/) (if you use old version of buildbot/buildbot-slave you should use buildbot command instead of buildslave-2.6 in following instructions).

 Add user buildbot:

 Make sure that you do not have a buildbot user and group on your system

 
```
# Check for group with id 101
id -g -nr 101

# Check for user with id 101
id -u -nr 101

```

If you do not have the group and user buildbot, then create the group and the user buildbot

 
```
# Create group buildbot with group id 101
GROUP="buildbot"
dscl . create /groups/$GROUP
dscl . create /groups/$GROUP name $GROUP
dscl . create /groups/$GROUP passwd "*"
dscl . create /groups/$GROUP gid 101

# Create user buildbot with id 101
BUILDSLAVE_HOME=/var/lib/buildslave
USER=buildbot
mkdir -p $BUILDSLAVE_HOME
dscl . -create /Users/$USER
dscl . -create /Users/$USER RealName "Buildbot slave"
dscl . -create /Users/$USER NFSHomeDirectory $BUILDSLAVE_HOME
dscl . -create /Users/$USER UserShell /bin/bash
dscl . -create /Users/$USER UniqueID 101
dscl . -create /Users/$USER PrimaryGroupID 101
chown 101:101 $BUILDSLAVE_HOME

```

To hide the user use:

 
```
defaults write /Library/Preferences/com.apple.loginwindow HiddenUsersList -array-add buildbot

```

Prepare environment:

 
```
sudo -i -u buildbot
buildslave-2.6 create-slave --usepty=0 maria-slave hasky.askmonty.org:9989 <slavename> <passwd>
bzr init-repo maria-slave/<slavedirectory>
$EDITOR maria-slave/info/admin
$EDITOR maria-slave/info/host
logout

```

Buildbot can be started/stopped manually with these commands (it's a good idea to start and stop it to see if it is set up correctly):

 If you installed buildbot from [fink](http://www.finkproject.org/), please make sure that the buildbot user is using the environment settings. Your .profile should contain follwing line:

 
```
sudo - buildbot
more .profile
test -r /sw/bin/init.sh && . /sw/bin/init.sh

```


```
sudo -i -u buildbot
buildslave-2.6 start maria-slave
buildslave-2.6 stop maria-slave
logout

```

In order to make buildbot start on system boot, you'll need to create /Library/LaunchDaemons/net.sourceforge.buildbot.plist file with the following contents (modified example from buildbot wiki):

 
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
 	<key>StandardOutPath</key>
 	<string>twistd.log</string>
 	<key>StandardErrorPath</key>
 	<string>twistd-err.log</string>
 	<key>EnvironmentVariables</key>
 	<dict>
 		<key>PATH</key>
 		<string>/opt/local/bin:/sbin:/usr/sbin:/bin:/usr/bin</string>
 		<key>PYTHONPATH</key>
 		<string>/opt/local/lib/python2.5/site-packages</string>
 	</dict>
 	<key>GroupName</key>
 	<string>daemon</string>
 	<key>KeepAlive</key>
 	<dict>
 		<key>SuccessfulExit</key>
 		<false/>
 	</dict>
 	<key>Label</key>
 	<string>net.sourceforge.buildbot.slave.test</string>
 	<key>ProgramArguments</key>
 	<array>
 		<string>/opt/local/bin/buildslave-2.6</string>
 		<string>start</string>
 		<string>--nodaemon</string>
 		<string>maria-slave</string>
 	</array>
 	<key>RunAtLoad</key>
 	<true/>
 	<key>UserName</key>
 	<string>buildbot</string>
 	<key>WorkingDirectory</key>
 	<string>/var/lib/buildslave/</string>
    </dict>
</plist>

```

If you installed buildbot from [fink](http://www.finkproject.org/), then you can edit and copy the plist file

 
```
$EDITOR /sw/share/doc/buildbot-py26/contrib/os-x/net.sourceforge.buildbot.slave.plist

```

Your plist file should similar to this one after editing:

 
```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd 
">
<plist version="1.0">
<dict>
         <key>Label</key>
         <string>net.sourceforge.buildbot.slave</string>

         <!-- Change this to the user you want to run buildbot as -->
         <key>UserName</key>
         <string>buildbot</string>

         <!-- Change this to your buildbot working directory -->
         <key>WorkingDirectory</key>
         <string>/Volumes/MiniHD2/ServiceData/buildslave/maria-slave</string>
        
         <key>EnvironmentVariables</key>
         <dict>
                 <key>PATH</key>
                 <string>/sw/bin:/sw/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
         </dict>

         <key>ProgramArguments</key>
         <array>
                 <string>/sw/bin/twistd</string>
                 <string>--nodaemon</string>
                 <string>--python=buildbot.tac</string>
                 <string>--logfile=buildbot.log</string>
                 <string>--prefix=slave</string>
         </array>

         <key>KeepAlive</key>
         <dict>
                 <key>SuccessfulExit</key>
                 <false/>
         </dict>

         <key>RunAtLoad</key>
         <true/>

</dict>
</plist>

```


```
sudo cp /sw/share/doc/buildbot-py26/contrib/os-x/net.sourceforge.buildbot.slave.plist /Library/LaunchDaemons/

```

Note: you have to start your buildslave via launchd, otherwise you will run into several problems. For further details, please refer to [Using Launchd](http://buildbot.net/trac/wiki/UsingLaunchd)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-buildbot-setup-for-macosx/>

Buildbot Setup for Windows
==========================

    This is the recipe for setting up a MariaDB Buildbot slave on Windows:

 1. Prepare the [development environment](../building_mariadb_on_windows/index)
2. Install [Python](http://www.python.org/download/), 32 bit. Twisted does not work on 64 bit and builtbot hasn't been tested properly with Python version 3.  
 *Note: As of June 2016, there is no fresh Twistd for 32-bit Python, so a 64-bit version has to be installed. Installed 2.7.11 64-bit, it seems to work.*
3. Install [pywin32](http://sourceforge.net/projects/pywin32/files). Make sure the version matches your Python version perfectly, and get the .exe file, not the zip file.  
 *Note: As of June 2016, used `pywin32-220.win-amd64-py2.7.exe`, it seems to work.*
4. Install [Twisted](http://twistedmatrix.com/trac/wiki/Downloads)  
 *Note: As of June 2016, used `Twisted 16.2.0 for Python 2.7 64 bits`*
5. Install [buildbot](http://buildbot.net): Get the zip file and unpack it. In an administrator shell, cd to the buildbot dir and run "python setup.py install". After that, the unpacked buildbot directory is no longer needed.  
 *Note: As of June 2016, used `buildbot 0.8.12`.*

 When this has been done, you run these commands:

 
```
cd <somewhere>
mkdir buildbot
cd buildbot
bzr init-repo .
C:\buildbot\buildbot-slave-0.8.3\build\scripts-2.7\buildslave.bat create-slave --usepty=0 <slavedir> hasky.askmonty.org:9989 <slavename> <passwd>

```

Adjust paths in the last command according to the location of your unpacked buildbot.

 You get <slavename> and <passwd> from one of the MariaDB Corporation or MariaDB Foundation people handling the buildbot system. <slavedir> can be whatever you want - <slavename> is a good choice.

 Please edit the files <slavedir>\info\admin and <slavedir>\info\host with your information. The host information should include your Windows version, 32 or 64 bit, and your Visual Studio version.

 You can test the buildbot slave with this command:

 
```
C:\buildbot\buildbot-slave-0.8.3\build\scripts-2.7\buildslave.bat start <somewhere>\buildbot\<slavedir>

```

When buildbot starts, you should confgure it as a service instead of manually. See the instructions [here](http://buildbot.net/trac/wiki/RunningBuildbotOnWindows). It's under the section "Windows Buildbot service setup". This document also has the generic Windows Buildbot installation documentation.

 Why buildbot should run as service
----------------------------------

 When buildbot is running in user session, and application that is started by buildbot crashes, you'll get a crash popup. There are popups that are generated by post-mortem debugging and there are popups that are generated by Windows Error reporting. It is hard (or impossible for those who did not try this before) to get rid of all popups. Thus, do run buildbot as service. There are no popups in services.

 Common Windows Buildbot Failures
--------------------------------

 ### Test hangs after trying to call cdb to print a backtrace.

 MTR attempts to call `cdb` via the Perl backticks operator, when mysqld.exe crashes. On the first run, cdb is downloading public Windows symbols from msdl.microsoft.com/download/symbols. The symbols are cached in C:\cdb\_symbols, and following runs will be faster, however crashdump analysis on very first crash will typically take some time. 

 If you find this bothering, start the test with `--mysqld=--gdb` which will cause no crashdump files to be created and thus will prevent `cdb` from being called.

 ### Buildbot exception `The process cannot access the file because it is being used by another process`

 This is due to the fact that buildbot does not clean up any processes left over from a previous run, and those processes may hold locks on files that are needed for a new build to start. Current workaround is to use windows job objects that allow to terminate entire process trees. We use special "process launcher" utility called "`dojob` . This will also require changing buildbot configuration for the builder.

 Download [dojob.cpp](http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/view/head:/buildbot/dojob.cpp), and compile it with 

 
```
  cl dojob.cpp

```

Then, put dojob.exe into a directory in the PATH [environment variable](../mariadb-environment-variables/index). Then, change buildbot configuration to use "dojob" for every command, as a replacement for "cmd /c", e.g

 
```
factory.addStep(Compile(
        name = "cmake",
        command=["dojob", WithProperties("cd c:\\buildbot\\%(buildername)s\\build && cmake .")]
));


```

### Buildbot exception `ShellCommand.failed: command failed: SIGKILL failed to kill process`

 (Seen very seldom?). This usually happens after retrying multiple failing tests multiple times. It appears that MTR's `--retries=` option is not safe to use on Windows. The solution is to run the test with no `--retries`.

 ### Buildbot exception `Connection to the other side was lost in a non-clean fashion.`

 This is a sympthom of intermittent network issues, which cause Buildbot to abort the current build altogether. The following workarounds are possible:

 * In your `buildbot.tac` file, specify a higher `keepalive` value, such as 60000.  
 *Note: For the current versions (as of June 2016), the opposite solution worked: keepalive = 60. KeepAliveTime in the Windows registry has been set to 60000 as suggested below, but there is no proof it made any difference.*
* If you are running the Windows host inside VMWare, substitute the `e1000` network adapter with `vmxnet3`
* If your build host is behind a firewall, makes sure that the firewall does not time out any idle connections quickly. Configure at least a 24-hour timeout.
* If your build host is behind a firewall, consider disabling the built-in Windows Firewall in order to avoid one potential point of failure.
* Modify the Windows `KeepAliveTime` registry setting to a lower value, such as 60000 (equal to 60 seconds). For more information, see [TechNet](http://technet.microsoft.com/en-us/library/cc957549.aspx)
* Make sure the buildbot master does not experience prolonged bouts of 100% CPU activity, as this may prevent keepalives from working. If the buildbot master `twisted.log` says that data is frequently being loaded from on-disk pickles, increase the `buildCacheSize` in the master configuration file to be more than the number of builds per builder that the log file reports are being loaded.

 Alternative Windows Buildbot setup (experimental)
=================================================

 In case the default Windows buildbot setup is not sufficiently reliable due to "connection lost in a non-clean fashion" errors, the following setup can be used instead. It runs the buildbot deamon on a linux host while doing the builds on Windows, thus working around Twisted issues on Windows.

 **Note that the procedure below \_significantly\_ degrades the overall security of your Windows host. It is strongly recommended that a properly-firewalled, standalone virtual machine is used.**

 * Set the Windows server to auto-login with the user the builds will run as. This will prevent any issues relating to running things as a service and the privilege considerations associated with services;

 * Install FreeSSHd on Windows. The OpenSSHd/Cygwin combo is not likely to work.
	+ Do not run FreeSSHd it as a service, but rather as a startup console application for the user you are running the builds under. This allows FreeSSHd UI to properly operate;
	+ Generate a private/public key pair using PuTTYGen and place the public part in a properly named file in the key directory specified in the FreeSSHd GUI
	+ Using the FreeSSHd GUI, create a new user and set it to use key authentication;
	+ Set the SFTP home path to the directory where builds will take place.

 * Disable UAC (User Access Control) (or set to lowest level) by using the Users Control Panel. Add your buildbot user to the Administrators group.

 * Export the private key from PuTTYGen and copy it to a Linux host.

 * Install buildbot on the Linux host

 * The buildbot configuration file will then look something like:

 
```
f_win2008r2_i386_release.addStep(ShellCommand(
        command=["ssh", "-i", "/home/buildbot/keys/id_rsa", "buildbot@win2008r2-build", "cmd", "/C", "whoami"]
));

```

The following buildbot considerations apply under this setup:

 * buildbot will not perform a proper cleanup of the build directory on the Windows host before each build (it will only clean up things on the linux side). So, a directory cleanup via rmdir must be placed as as an explicit first step in the build sequence;
* Bzr() can not be used to check out BZR trees, as it expects that the bzr checkout command will run locally. Instead, an explicit call to bzr checkout via a SSH command must be used;

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-buildbot-setup-for-windows/>

Using Git with MariaDB
=======================

   Tricks and tips on how to use Git, the source control system MariaDB uses.

  

| Title | Description |
| --- | --- |
|  [MariaDB Source Code](../getting-the-mariadb-source-code/index) |  How to get the source code for MariaDB from GitHub.  |
|  [Using Git](../using-git/index) |  Working with the git repository for the source code of MariaDB on GitHub.  |
|  [Configuring Git to Send Commit Notices](../configuring-git-to-send-commit-notices/index) |  Configuring git to send emails when committing changes.  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-git-with-mariadb/>

Buildbot Setup Notes
====================

    General setup instructions are available in the [BuildBot manual](http://docs.buildbot.net/current/manual/index.html), specifically in the section on [Setting up a build slave](http://docs.buildbot.net/current/manual/installation/worker.html).

 In addition to installing BuildBot on the slave host, it is also necessary to install all the tools needed to branch MariaDB from Launchpad and compile it. It is a good idea to first manually branch the code from Launchpad and successfully build it, as otherwise a lot of time may be needed fixing things one at a time as new builds are started and fail in one way or the other.

 Unfortunately, bzr is memory hungry, so at least 1 Gigabyte of memory is recommended (you may be able to squeeze through with less, but bzr is a real memory hog). A few Gigabytes of disk space are also needed to hold the build directory.

 Here are some detailed instructions for various systems:

 * [Buildbot Setup for Ubuntu-Debian](../buildbot_setup_for_ubuntu-debian/index)
* [Buildbot Setup for MacOSX](../buildbot_setup_for_macosx/index)
* [Buildbot Setup for Solaris](../buildbot_setup_for_solaris/index)
* [Buildbot Setup for Windows](../buildbot_setup_for_windows/index)

 See the [Buildbot TODO](../buildbot-todo/index) for plans and ideas on improving Buildbot.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-buildbot-setup-notes/>

Buildbot
=========

   Pages about buildbot.

 As an example, you can see what's happening with 10.1 [here](http://buildbot.askmonty.org/buildbot/waterfall?branch=10.1).

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup](../buildbot-setup/index) |  Pages about buildbot setup  |
|  [About Buildbot](../about-buildbot/index) |  Overview, where to find the running builds, setting up a buildbot etc.  |
|  [Branch Protection Using Buildbot](../branch-protection-using-buildbot/index) |  MariaDB uses branch protection. ensuring pushes to the repo can't be made w...  |
|  [Buildbot Database Schema](../buildbot-buildbot-database-schema/index) |  This page describes the database schema used by Buildbot to save results fr...  |
|  [Buildbot Development](../buildbot-buildbot-development/index) |  Developing on the Buildbot code Buildbot has all of the right ideas for sol...  |
|  [Buildbot runvm](../runvm/index) |  One type of build we do in BuildBot is to build and test MariaDB binary pac...  |
|  [Buildbot ToDo](../buildbot-todo/index) |  Buildbot development ToDo list.  |
|  [Package Testing with Buildbot and KVM](../package-testing-with-buildbot-and-kvm/index) |  Buildbot testing of binary MariaDB packages This part of the Buildbot setu...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot/>

Buildbot Setup
===============

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup Notes](../buildbot-setup-buildbot-setup-notes/index) |  Setting up Buildbot  |
|  [How do I setup a Buildbot build slave?](../how-do-i-setup-a-buildbot-build-slave/index) |  These build instructions should in general be platform agnostic. It is base...  |
|  [Buildbot Setup for VM host](../buildbot-setup-for-vm-host/index) |  This page documents the general setup process for a server that is acting a...  |
|  [Buildbot Setup for Virtual Machines](../buildbot-setup-for-virtual-machines/index) |  This section documents the exact steps used to set up each virtual machine ...  |
|  [Buildbot Setup for MacOSX](../buildbot-setup-buildbot-setup-for-macosx/index) |  Setting up a Buildbot slave on Mac OS X  |
|  [Buildbot Setup for Solaris Sparc](../buildbot-setup-for-solaris-sparc/index) |  Setting up a BuildBot slave on Solaris NOTE #1: It would probably make se...  |
|  [Buildbot Setup for Solaris x86](../buildbot-setup-for-solaris-x86/index) |  The following steps were used to create a Solaris 10 x86 BuildSlave. I star...  |
|  [Buildbot Setup for Ubuntu-Debian](../buildbot-setup-for-ubuntu-debian/index) |  Instructions for setting up a buildbot slave on Ubuntu and Debian  |
|  [Buildbot Setup for Windows](../buildbot-setup-buildbot-setup-for-windows/index) |  Recipe for setting up a MariaDB Buildbot slave on Windows  |
|  [Buildbot Setup for BSD](../buildbot-setup-for-bsd/index) |  Here are the steps I did when installing and configuring a buildbot slave o...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup/>

Configuring Git to Send Commit Notices
======================================

    Commit emails for MariaDB are sent to `[commits@mariab.org](http://lists.askmonty.org/cgi-bin/mailman/listinfo/commits)`. You can find the archive [here](http://lists.askmonty.org/pipermail/commits).

 To allow others to see what you are working on in your MariaDB tree, you should:

 1. [subscribe](http://lists.askmonty.org/cgi-bin/mailman/listinfo/commits) to the email list
2. configure git to send your commits to `[commits@mariab.org](http://lists.askmonty.org/cgi-bin/mailman/listinfo/commits)`.

 Download the [post-commit git trigger](http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/view/head:/git_template/hooks/post-commit) script. Configure as

 
```
git config --global hooks.postcommitrecipients "commits@mariadb.org"
git config --global hooks.postcommitbranches "*"

```

Also you might want to check the [README](http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/view/head:/git_template/README) for the post-commit trigger.

 The post-commit git trigger uses *sendmail* for sending emails. Some platforms don't have *sendmail* and then you'll need to modify to make use of something that is supported.

 Also, the post-commit trigger is just one approach. You can also use git-email on at least Debian and Fedora to send commit emails to the MariaDB commits email list.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/configuring-git-to-send-commit-notices/>

Buildbot Setup for BSD
======================

    Here are the steps I did when installing and configuring a buildbot slave on a PC-BSD 9 box.

 Add buildbot user:

 
```
sudo adduser
  buildbot
  /bin/sh

```

Python was already installed.

 Bazaar was already installed.

 NTP was already installed.

 Install Zope3

 
```
cd /usr/ports/www/zope3
sudo make install clean
  # accepted default options
cd /usr/ports/devel/py-zope.interface
sudo make install clean

```

Install Twisted

 
```
cd /usr/ports/devel/py-twisted
sudo make install clean
  # accepted default options

```

Install ccache

 
```
cd /usr/ports/devel/ccache
sudo make install clean
  # accepted default options

```

Run a test compile of MariaDB

 
```
cd
cd src/maria/build
BUILD/compile-pentium64-max
  # test compile appeared to work

```

Install buildbot

 
```
cd /usr/ports/devel/buildbot
sudo make install clean
  # accepted default options

```

Create the buildbot slave

 On the build master, add new entry to /etc/buildbot/maria-master-private.cfg

 
```
    slave-name=bsd9

```

Remember the ${slave-name} and ${password} configured above, they're used in the next step.

 Back on bsd9

 
```
sudo su - buildbot
buildslave create-slave --usepty=0 /home/buildbot/maria-slave \
hasky.askmonty.org:9989 ${slave-name} ${password}

echo '${contact-email-address}' > /home/buildbot/maria-slave/info/admin
echo 'A host running PC-BSD 9.' > /home/buildbot/maria-slave/info/host

bzr init-repo maria-slave/bsd9

exit

```

Start the buildslave

 
```
sudo su - buildbot
buildslave start maria-slave

```

Make the archive dir

 
```
sudo su - buildbot
mkdir archive
exit
sudo ln -s /home/buildbot/archive /archive

```

Install Apache

 
```
cd /usr/ports/www/apache22
sudo make install clean
  # accepted default options

```

Configure apache:

 
```
sudo su -s
echo 'apache22_enable="YES"' >> /etc/rc.conf
echo 'alias /archive "/archive"\
<Directory "/archive">\
  Options All Multiviews\
  AllowOverride All\
  Order allow,deny\
  Allow from all\
</Directory>' >> /usr/local/etc/apache22/httpd.conf

sudo /usr/local/etc/rc.d/apache22 start

```

Install md5sum

 
```
md5sum already installed at /compat/linux/usr/bin/md5sum
edited /home/buildbot/.profile and added that dir to the path
  # That didn't work, so did the following:
cd /usr/local/bin/
sudo ln -s /compat/linux/usr/bin/md5sum md5sum

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-bsd/>

Buildbot Setup for VM host
==========================

    This page documents the general setup process for a server that is acting as virtual machine host, like those documented in the [Buildbot Setup for Virtual Machines](../buildbot-setup-for-virtual-machines/index) section.

 1. Provision hardware with most recent Ubuntu LTS release

 2. Add host to DNS

 3. Apply updates (replace `<host>` with hostname)

 
```
ssh <host>.mariadb.net
sudo apt-get update
sudo apt-get dist-upgrade

```

4. install some favorite packages (these aren't necessarily required, but I like them)

 
```
sudo apt-get install tree renameutils vim-nox

```

5. a buildbot admin needs to add the new host to the allowed list of rsync clients on the VM master (whichever host is the *official* host of VM files) The VM master changes periodically, so check to make sure you have the correct one.

 
```
vi /etc/rsyncd.conf 

```

6. make a `/kvm/` dir and rsync it with the VM master above. The dir often resides at `/home/kvm/` (or wherever the storage drive is) and is then linked to `/kvm/`. The VMs rely on the `/kvm/vms/` path, so the `/kvm/` location is required.

 
```
vm_master="hostname"      # ask for this from a buildbot admin
mkdir /home/kvm
ln -sv /home/kvm /kvm
rsync --dry-run --delete --exclude=deprecated \\
  --exclude=iso --exclude=lost+found -avPL ${vm_master}::kvm/ /home/kvm/
# assuming the dry-run looks good, start the "real" rsync in a screen session
screen
rsync --delete --exclude=deprecated --exclude=iso --exclude=lost+found -avPL ${vm_master}::kvm/ /home/kvm/

```

7. detatch from screen session with `Ctrl+a d`

 8. Configure vim.basic as the default editor (optional)

 
```
update-alternatives --config editor

```

9. install buildbot-slave, bzr, and kvm

 
```
sudo apt-get install bzr git buildbot-slave qemu kvm 
sudo apt-get install libsdl2-2.0-0 

```

10. add a default user, and then add the user to the appropriate groups

 
```
username="mydefaultusername"
sudo adduser ${username}
for group in sudo tty kvm;do
  sudo adduser ${username} ${group}
done

```

11. logout then back in as the default user and change the password

 13. set up the `/.ssh/authorized_keys` file so you can login that way

 14. create other standard users and set up their ssh keys (optional)

 15. turn off password login (WARNING: be sure to have your ssh key setup before doing this!) and disallow all root logins and password logins (it is safer to only allow logins using ssh keys with regular users):

 
```
sudo perl -i -pe "s/#PasswordAuthentication yes/PasswordAuthentication no/" /etc/ssh/sshd_config
sudo perl -i -pe "s/PermitRootLogin yes/PermitRootLogin no/" /etc/ssh/sshd_config
sudo /etc/init.d/ssh restart

```

16. checkout mariadb-tools

 
```
mkdir ~/src
cd ~/src/
bzr branch lp:mariadb-tools

```

17. put runvm in the right place

 
```
sudo cp -v ~/src/mariadb-tools/buildbot/runvm /usr/local/bin/
ls -l /usr/local/bin/

```

18. add the buildbot user to the kvm and tty groups

 
```
sudo adduser buildbot kvm
sudo adduser buildbot tty

```

19. A buildbot admin will need to add this builder to the `maria-master-private.cfg` file on the `${buildmaster}` and also add it to the `c['slaves']` array in `maria-master.cfg` then create the buildslave using the hostname and whatever `${password}` was agreed upon by you and the buildbot admin:

 
```
sudo buildslave create-slave /var/lib/buildbot/slaves/maria buildbot.askmonty.org ${host} ${password}

```

20. add the following to `/etc/default/buildslave` (replace `${hostname}` with the name of the host)

 
```
HOME=/var/lib/buildbot
SLAVE_ENABLED[1]=1
SLAVE_NAME[1]="${hostname} maria slave"
SLAVE_USER[1]="buildbot"
SLAVE_BASEDIR[1]="$HOME/slaves/maria"
SLAVE_OPTIONS[1]=""
SLAVE_PREFIXCMD[1]=""

```

21. edit the admin and host files and add contact information and details on the builder:

 
```
sudo vi /var/lib/buildbot/slaves/maria/info/*

```

22. copy over the buildbot .ssh dir from terrier:

 
```
scp terrier.askmonty.org:buildbot-ssh.tar.gz .

cd /var/lib/buildbot
sudo tar -zxvf ~/buildbot-ssh.tar.gz
sudo chown -Rv buildbot: .ssh
sudo chmod -v 700 .ssh
sudo chmod -Rv go-r .ssh

```

23. Edit /etc/passwd and change the buildbot user's shell from `/bin/false` to `/bin/bash`

 24. su to the buildbot user and copy in the `/etc/skel` files

 
```
sudo su - buildbot
cp -v /etc/skel/.bash* .
cp -v /etc/skel/.profile .
exit

```

25. change ownership of the `buildbot/slaves` dir to `buildbot:buildbot`

 
```
sudo chown -Rv buildbot:buildbot ~buildbot/slaves

```

26. move the `/var/lib/buildbot` directory to `/home` (or whatever location you want to use to store things) and then link it back

 
```
sudo mv -vi /var/lib/buildbot /home/;cd /var/lib/;sudo ln -sv /home/buildbot ./

```

27. update `/etc/default/locale` and change it to: `LANG=en_US.UTF-8`

 
```
sudo vi /etc/default/locale
sudo locale-gen

```

28. monitor the rsync, wait for it to finish

 29. once the rsync is finished, test the runvm script

 
```
sudo su - buildbot
for i in '/kvm/vms/vm-xenial-amd64-serial.qcow2 6666 qemu64' '/kvm/vms/vm-xenial-i386-serial.qcow2 6666 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/testtest/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils unixodbc libxml2 libjudydebian1" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

30. Remove the "testtest" VMs we created above

 
```
rm -v /kvm/vms/*testtest*

```

31. Start the buildslave

 
```
sudo /etc/init.d/buildslave start

tail -f ~buildbot/slaves/maria/twistd.log

```

32. ssh to `${buildmaster}` and add this new host to `kvm_slaves` in the `maria-master.cfg` file

 
```
sudo vi /etc/buildbot/maria-master.cfg

```

33. still on `${buildmaster}`, test and then reload buildbot

 
```
cd /etc/buildbot
sudo -u buildbot PYTHONPATH=/usr/local/buildbot/lib/python python -c 'exec open("maria-master.cfg", "r")'
sudo /etc/init.d/buildmaster reload
sudo tail -f /var/lib/buildbot/maria/twistd.log

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-vm-host/>

Buildbot Setup for Ubuntu-Debian
================================

    Setting up a Buildbot slave on Ubuntu and Debian
------------------------------------------------

 One great way to contribute to MariaDB development is to run a buildbot builder. These builders are used for running automated builds and tests of MariaDB. The instructions on this page should help you get a builder set up on Ubuntu and Debian.

 ### Setting up your MariaDB build environment

 For Ubuntu and Debian, a quick way to install much of what you need is:

 
```
sudo apt-get build-dep mariadb-server

```

If you're running a version of Debian or Ubuntu that doesn't have MariaDB, then do the following:

 
```
sudo apt-get build-dep mysql-server

```

After running one (or both) of the above, run the following to catch things that they may have missed:

 
```
sudo apt-get install devscripts fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.11 dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev bzr scons check libboost-all-dev openssl epm libjudy-dev libjemalloc-dev libcrack2-dev git libkrb5-dev libcurl4-openssl-dev thrift-compiler libsystemd-dev dh-systemd libssl1.0.2 openjdk-8-jdk uuid-dev libnuma-dev gdb libarchive-dev libasio-dev dh-exec

```

After setting up the build environment do a test build to confirm that things are working. First get the source code using the **git** instructions on the [Getting the MariaDB Source Code](../getting-the-mariadb-source-code/index) page, then follow the steps on the [Generic Build Instructions](../generic-build-instructions/index) page for building MariaDB using **cmake**. If your build succeeds, you're ready to move on to the next step of installing and configuring buildbot.

 Do not hesitate to ask for help on the [maria-developers](https://launchpad.net/~maria-developers) mailing list or on [IRC](../irc/index).

 ### Buildbot installation and setup

 #### Using APT

 The easiest way to install buildbot on Ubuntu and Debian is to install the buildbot-slave package, like so:

 
```
sudo apt-get install buildbot-slave

```

#### Using Pip

 Another way to install buildbot is using the Python **pip** package manager. Pip can be installed with: 

 
```
sudo apt-get install python-pip

```

Next install twisted and the buildbot-slave package using pip:

 
```
sudo pip install twisted==11.0.0
sudo pip install buildbot-slave==0.8.9

```

#### Creating the Buildbot builder

 After the buildbot-slave package is installed (either via apt or pip), you need to create the builder using the `buildslave create-slave` command. As part of this command you will need to specify a name for your buildslave and a password. Both need to be given to the MariaDB Buildbot maintainers so that they can add your builder to the build pool. Ask on the [maria-developers](https://launchpad.net/~maria-developers) mailing list or on [IRC](../irc/index) for who these people are.

 An example command for creating the slave is:

 
```
sudo buildslave create-slave /var/lib/buildbot/slaves/maria buildbot.askmonty.org slavename password

```

If you installed buildbot using pip, the convention is to create a buildbot user and then, as that user, create the buildslave in the home directory like so:

 
```
sudo buildslave create-slave ~/maria-slave buildbot.askmonty.org slavename password

```

Put some appropriate info in info/admin and info/host files that are created, this will display on the information screen about your builder. See here for example: [bb01](http://buildbot.askmonty.org/buildbot/buildslaves/bb01)

 Submit your builder information to the MariaDB Buildbot admins. Also let them know if your machine can run multiple builds at the same time (and how many). After adding your builder's information to the main buildbot configuration, all that's left is for you to do is to start your builder.

 ### Starting and stopping your builder

 If you installed your builder using apt, then you can start and stop it with:

 
```
sudo /etc/init.d/buildslave start
sudo /etc/init.d/buildslave stop

```

If you installed your buildslave using pip, then do the following as the buildbot user in their home directory:

 
```
buildslave start maria-slave
buildslave stop maria-slave

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-ubuntu-debian/>

Using Healthcheck.sh script
===========================

    The healthcheck.sh script is part of the Docker Official Images of MariaDB Server. The script is part of the [respository of the Docker Official Image of MariaDB Server](https://github.com/MariaDB/mariadb-docker/blob/master/healthcheck.sh).

 The script processes a number of argument and tests, together, in strict order. Arguments pertaining to a test must occur before the test name. If a test fails, no further processing is performed. Both arguments and tests begin with a double-hyphen.

 By default, (since 2023-06-27), official images will create healthcheck@localhost, healthcheck@127.0.0.1, healthcheck@::1 users with a random password and USAGE privileges. `[MARIADB\_HEALTHCHECK\_GRANTS](../mariadb-server-docker-official-image-environment-variables/index#mariadb_healthcheck_grants)` can be used for `--replication` where additional grants are required. This is stored in .my-healthcheck.cnf in the datadir of the container and passed as the `--defaults-extra-file` to the healthcheck.sh script if it exists. The `.my-healthcheck.cnf` also sets `protocol=tcp` for the `mariadb` so `--connect` is effectively there on all tests.

 The `[MARIADB\_MYSQL\_LOCALHOST\_USER=1, MARIADB\_MYSQL\_LOCALHOST\_GRANTS](../mariadb-server-docker-official-image-environment-variables/index#mariadb_mysql_localhost_user-mariadb_mysql_localhost_grants)` environment variables can also be used, but with the creation of the healthcheck user, these are backwards compatible. 

 Tests
=====

 --connect
---------

 This is active when a external user can connect to the TCP port of MariaDB Server. This strictly tests just the TCP connection and not if any authentication works.

 --innodb\_initialized
---------------------

 This test is true when InnoDB has completed initializing. This includes any rollback or crash recovery that may be occurring in the background as MariaDB is starting.

 The connecting user must have [USAGE](../grant/index#the-usage-privilege) privileges to perform this test.

 --innodb\_buffer\_pool\_loaded
------------------------------

 This indicates that the buffer pool dump previously saved has been completed loaded into the InnoDB Buffer Pool and as such the server has a hot cache ready for use. This checks the [innodb\_buffer\_pool\_load\_status](../innodb-status-variables/index#innodb_buffer_pool_load_status) for a "complete" indicator.

 This test doesn't check if [innodb-system-variables/#innodb\_buffer\_pool\_load\_at\_startupinnodb\_buffer\_pool\_load\_at\_startup](../innodb-system-variables/index#innodb_buffer_pool_load_at_startupinnodb_buffer_pool_load_at_startup) is set at startup.

 The connecting user must have [USAGE](../grant/index#the-usage-privilege) privileges to perform this test.

 --galera\_online
----------------

 This indicates that the galera node is online by the [wsrep\_local\_state](https://galeracluster.com/library/documentation/node-states.html#node-state-changes) variable. This includes states like "joining" and "donor" where it cannot serve SQL queries.

 The connecting user must have [USAGE](../grant/index#the-usage-privilege) privileges to perform this test.

 --replication
-------------

 This tests a replica based on the `--replication_*` parameters. The replica test must pass all of the subtests to be true. The subtests are:

 * io - the IO thread is running
* sql - the sql thread is running
* seconds\_behind\_master - the replica is less than X seconds behind the master.
* sql\_remaining\_delay - the delayed replica is less than X seconds behind the master's execution of the same SQL.

 These are tested for all connections, if `--replication_all` is set (default), or `--replication_name`.

 The connecting user must have [REPLICATION\_CLIENT](../grant/index#replication-client) if using a version less than [MariaDB 10.5](../what-is-mariadb-105/index), or [REPLICA MONITOR](../grant/index#replica-monitor) for [MariaDB 10.5](../what-is-mariadb-105/index) or later.

 --mariadbupgrade
----------------

 This healthcheck indicates that the mariadb is upgrade to the current version.

 Parameters
==========

 --replication\_all
------------------

 Checks all replication sources

 --replication\_name=n
---------------------

 Sets the multisource connection name tested. Unsets `--replication_all`.

 --replication\_io
-----------------

 IO thread is running

 --replication\_sql
------------------

 SQL thread is running

 --replication\_seconds\_behind\_master=n
----------------------------------------

 Less than or equal this seconds of delay

 --replication\_sql\_remaining\_delay=n
--------------------------------------

 Less than or equal this seconds of remaining delay

 --su=n
------

 Change to this user. Can only be done once as the root user is default for healthchecks.

 --su-mysql
----------

 Change to the `mysql` unix user. Like `--su` this respawns the script so will reset all parameters. Should be the first argument. The `[MARIADB\_MYSQL\_LOCALHOST\_USER=1](../mariadb-server-docker-official-image-environment-variables/index#mariadb_mysql_localhost_user-mariadb_mysql_localhost_grants)` environment variable is designed around usage here.

 --datadir=n
-----------

 For the `--mariadbupgrade` test where the upgrade file is located.

 --no-defaults --defaults-file --defaults-extra-file --defaults-group-suffix
---------------------------------------------------------------------------

 These are passed to [mariadb shell](../mariadb-client/index) for all tests except `--mariadbupgrade`

 Examples
========

 
```
healtcheck.sh --su-mysql --connect --innodb_initialized

```

Switch to `mysql` user, and check if can connect and the innodb is initialized.

 
```
healtcheck.sh --su-mysql --connect --replication_io --replication_sql --replication_seconds_behind_master=600  --replication_sql_remaining_delay=30 ----replication_name=archive --replication --replication_seconds_behind_master=10  --replication_name=channel1 --replication

```

Switch to `mysql` user, check if connections can be made, for the replication channel "archive", ensure io and sql threads are running and the seconds behind master < 600 seconds and the sql remaining delay < 30 seconds. For the "channel1", the seconds behind master is limit to 10 seconds maximum.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-healthcheck-sh-script/>

How do I setup a Buildbot build slave?
======================================

    These build instructions should in general be platform agnostic. It is based on a post by Adam M. Dutko on maria-discuss. See the [list archive](https://lists.launchpad.net/maria-discuss/msg00372.html).

 To setup a build slave, the basic outline is:

 1. Install Python (2.4 or later)
2. Install Twisted (twistedmatrix.com 8.0.x or later) - need Core, Mail, Web and Words (possibly Conch too)
3. Install ZopeInterface (<http://www.zope.org/Products/ZopeInterface>)
4. Install all the necessary compiler/build components.
5. Install Buildbot
6. Install [Git](../using-git/index) and make sure you can clone from the main project
7. Get a username/login and password from the buildmaster (dbart on [Libera.Chat](../irc/index))
8. Verify your buildbot can talk to the buildbot master instance and can run builds.

 The following links will also help:

 1. <http://docs.buildbot.net/>
2. [buildbot-setup-buildbot-setup-notes](../buildbot-setup-buildbot-setup-notes/index)
3. [about-buildbot](../about-buildbot/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/how-do-i-setup-a-buildbot-build-slave/>

Buildbot Setup for Virtual Machines
====================================

   This section documents the exact steps used to set up each virtual machine used in the MariaDB Buildbot for building packages and testing. There are lots of boring details, but the information here should be useful for reference, and as a help when installing new virtual images for additional distros and versions.

 The articles here document how the virtual machine images were actually set up, not the most efficient way to recreate all of them. Thus, some historical artifacts remain, reflecting the order they were initially added and lessons learned along the way.

 For example, the steps for the earliest VMs are somewhat overly enthusiastic about using the `qemu-img create -b` option to make one vm a copy-on-write copy on top of another image. This makes it harder to modify the images afterwards, since if the base image is modified, any copy-on-write vm on top of it needs to be re-created.

 The descriptions do not go into painful detail about the installation procedure. Generally the .iso for the distro was downloaded, and the default, non-graphical installer started. Installing Linux these days is quite easy, and generally just defaults were picked. With respect to harddisk partitioning, generally an 8Gb image was configured, of which 1/2 Gb was reserved for swap and the rest for a single root partition "/".

 For details on setting up a host server to run these VMs, see [Buildbot Setup for VM host](../buildbot-setup-for-vm-host/index).

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) |  The installations are kept minimal, picking mostly default options. This h...  |

 ###   [Buildbot Setup for Virtual Machines - Ubuntu](../buildbot-setup-for-virtual-machines-ubuntu/index)

 

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Ubuntu 14.04 "trusty"](../buildbot-setup-for-virtual-machines-ubuntu-1404-trusty/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-trusty-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 13.10 "saucy"](../buildbot-setup-for-virtual-machines-ubuntu-1310-saucy/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-saucy-amd64-seria  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 13.04 "raring"](../buildbot-setup-for-virtual-machines-ubuntu-1304-raring/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-raring-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 12.10 "quantal"](../buildbot-setup-for-virtual-machines-ubuntu-1210-quantal/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-quantal-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 12.04 "precise"](../buildbot-setup-for-virtual-machines-ubuntu-1204-precise/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-precise-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 11.10 "oneiric"](../buildbot-setup-for-virtual-machines-ubuntu-1110-oneiric/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-oneiric-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 11.04 "natty"](../buildbot-setup-for-virtual-machines-ubuntu-1104-natty/index) |  Base install qemu-img create -f qcow2 vm-natty-amd64-serial.qcow2 8G  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 10.10 "maverick"](../buildbot-setup-for-virtual-machines-ubuntu-1010-maverick/index) |  Base install qemu-img create -f qcow2 vm-maverick-amd64-serial.qcow2  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 10.04 (alpha), i386 and amd64](../buildbot-setup-for-virtual-machines-ubuntu-1004-alpha-i386-and-amd64/index) |  Base install qemu-img create -f qcow2 vm-lucid-amd64-serial.qcow2 8G  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 9.04 i386](../buildbot-setup-for-virtual-machines-ubuntu-904-i386/index) |  This vm is used to build source tarball and for Ubuntu 9.04 32-bit .deb. Fi...  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 9.04 amd64](../buildbot-setup-for-virtual-machines-ubuntu-904-amd64/index) |  Base install qemu-img create -f qcow2 vm-jaunty-amd64-serial.qcow2 8  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 8.04, 8.10, and 9.10](../buildbot-setup-for-virtual-machines-ubuntu-804-810-and-910/index) |  These 6 platforms were installed together (i386 and amd64). Base installs U...  |

 ###   [Buildbot Setup for Virtual Machines - Debian](../buildbot-setup-for-virtual-machines-debian/index)

 

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Debian 7 "wheezy"](../buildbot-setup-for-virtual-machines-debian-7-wheezy/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-wheezy-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Debian 6 amd64](../buildbot-setup-for-virtual-machines-debian-6-amd64/index) |  Create the VM: cd /kvm/vms qemu-img create -f qcow2 vm-debian6-amd64  |
|  [Buildbot Setup for Virtual Machines - Debian 6 i386](../buildbot-setup-for-virtual-machines-debian-6-i386/index) |  Base Install cd /kvm/vms qemu-img create -f qcow2 vm-debian6-i386-se  |
|  [Buildbot Setup for Virtual Machines - Debian 5 amd64](../buildbot-setup-for-virtual-machines-debian-5-amd64/index) |  Download netinst CD image debian-503-amd64-netinst.iso cd /kvm/vms q  |
|  [Buildbot Setup for Virtual Machines - Debian 5 i386](../buildbot-setup-for-virtual-machines-debian-5-i386/index) |  Base install Download netinst CD image debian-503-i386-netinst.iso and inst...  |
|  [Buildbot Setup for Virtual Machines - Debian 4 i386](../buildbot-setup-for-virtual-machines-debian-4-i386/index) |  Create the VM: cd /kvm/vms qemu-img create -f qcow2 vm-debian4-i386-  |
|  [Buildbot Setup for Virtual Machines - Debian 4 amd64](../buildbot-setup-for-virtual-machines-debian-4-amd64/index) |  cd /kvm/vms qemu-img create -f qcow2 vm-debian4-amd64-serial.qcow2 8  |

 ###   [Buildbot Setup for Virtual Machines - Red Hat](../buildbot-setup-for-virtual-machines-red-hat/index)

 

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Fedora 20](../buildbot-setup-for-virtual-machines-fedora-20/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora20-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 19](../buildbot-setup-for-virtual-machines-fedora-19/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora19-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 18](../buildbot-setup-for-virtual-machines-fedora-18/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora18-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 17](../buildbot-setup-for-virtual-machines-fedora-17/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora17-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 16](../buildbot-setup-for-virtual-machines-fedora-16/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora16-i386-ser  |
|  [Buildbot Setup for Virtual Machines - CentOS 6.2](../buildbot-setup-for-virtual-machines-centos-62/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-centos6-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Red Hat 6 x86](../buildbot-setup-for-virtual-machines-red-hat-6-x86/index) |  The following steps were used to create a Red Hat 6 x86 buildslave. Initial Setup cd vms q  |
|  [Buildbot Setup for Virtual Machines - CentOS 5 i386](../buildbot-setup-for-virtual-machines-centos-5-i386/index) |  Base install cd /kvm qemu-img create -f qcow2 vms/vm-centos5-i386-ba  |
|  [Buildbot Setup for Virtual Machines - Centos 5 amd64](../buildbot-setup-for-virtual-machines-centos-5-amd64/index) |  Base install cd /kvm wget http://ftp.klid.dk/ftp/centos/5.3/isos/x86  |

 ###   [Buildbot Setup for Virtual Machines - Additional Steps](../buildbot-setup-for-virtual-machines-additional-steps/index)

 

| Title | Description |
| --- | --- |
|  [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index) |  The OQGraph storage engine needs a newer version of Boost that what is avai...  |
|  [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index) |  This step creates virtual machine images used to do an important additional...  |
|  [Install Cassandra on Fulltest VMs](../install-cassandra-on-fulltest-vms/index) |  CassandraSE is no longer actively being developed and has been removed in M...  |
|  [Install cmake on build VMs](../install-cmake-on-build-vms/index) |  MariaDB 5.5 Requires cmake. Install cmake on all -build VMs (and other Unix...  |
|  [Installing correct libraries for PAM and readline](../installing-correct-libraries-for-pam-and-readline/index) |  Some additional/alternative libraries needs to be installed to handle readl...  |
|  [Resizing a Virtual Machine Image](../resizing-a-virtual-machine-image/index) |  Some KVM images end up not having enough space on them. In such cases, it i...  |
|  [Update Debian 4 mirrors for Buildbot VMs](../update-debian-4-mirrors-for-buildbot-vms/index) |  Debian 4 has become so old that the apt repository has been moved out of th...  |

 ### Other Buildbot Setup for Virtual Machines Articles

 

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - FreeBSD 9.2](../buildbot-setup-for-virtual-machines-freebsd-92/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-freebsd92-amd64-s  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines/>

Vagrant Overview for MariaDB Users
==================================

    Vagrant is a tool to create and manage development machines (Vagrant *boxes*). They are usually virtual machines on the localhost system, but they could also be Docker containers or remote machines. Vagrant is open source software maintained by HashiCorp and released under the MIT license.

 Vagrant benefits include simplicity, and a system to create test boxes that is mostly independent from the technology used.

 For information about installing Vagrant, see [Installation](https://www.vagrantup.com/docs/installation) in Vagrant documentation.

 In this page we discuss basic Vagrant concepts.

 Vagrant Concepts
----------------

 A **Vagrant machine** is compiled from a box. It can be a virtual machine, a container or a remote server from a cloud service.

 A **box** is a package that can be used to create Vagrant machines. We can download boxes from app.vagrantup.com, or we can build a new box from a Vagrantfile. A box can be used as a base for another box. The base boxes are usually operating system boxes downloaded from app.vagrantup.com.

 A **provider** is responsible for providing the virtualization technology that will run our machine.

 A **provisioner** is responsible for installing and configuring the necessary software on a newly created Vagrant machine.

 ### Example

 The above concepts are probably easier to understand with an example.

 We can use an Ubuntu box as a base to build a Vagrant machine with MariaDB. So we write a Vagrantfile for this purpose. In the Vagrantfile we specify VirtualBox as a provider. And we use the Ansible provisioner to install and configure MariaDB. Once we finish this Vagrantfile, we can run a Vagrant command to start a Vagrant machine, which is actually a VirtualBox VM running MariaDB on Ubuntu.

 The following diagram should make the example clear:

 ![vagrant-virtalbox-ansible]

 ### Vagrantfiles

 A Vagrantfile is a file that describes how to create one or more Vagrant machines. Vagrantfiles use the Ruby language, as well as objects provided by Vagrant itself.

 A Vagrantfile is often based on a box, which is usually an operating system in which we are going to install our software. For example, one can create a MariaDB Vagrantfile based on the `ubuntu/trusty64` box. A Vagrantfile can describe a box with a single server, like MariaDB, but it can also contain a whole environment, like LAMP. For most practical use cases, having the whole environment in a single box is more convenient.

 Boxes can be searched in [Vagrant Cloud](https://app.vagrantup.com/boxes/search). Most of their Vagrantfiles are available on GitHub. Searches can be made, among other things, by keyword to find a specific technology, and by provider.

 ### Providers

 A provider adds support for creating a specific type of machines. Vagrant comes with several providers, for example:

 * `VirtualBox` allows one to create virtual machines with VirtualBox.
* `Microsoft-Hyper-V` allows one to create virtual machines with Microsoft Hyper-V.
* [Docker](../docker-and-mariadb/index) allows one to create Docker containers. On non-Linux systems, Vagrant will create a VM to run Docker.

 Alternative providers are maintained by third parties or sold by HashiCorp. They allow one to create different types of machines, for example using VMWare.

 Some examples of useful providers, recognized by the community:

 * [Vagrant AWS Provider](https://github.com/mitchellh/vagrant-aws).
* [Vagrant Google Compute Engine (GCE) Provider](https://github.com/mitchellh/vagrant-google).
* [Vagrant Azure Provider](https://github.com/Azure/vagrant-azure).
* [OpenVZ](https://app.vagrantup.com/OpenVZ).
* [vagrant-lxc](https://github.com/fgrehm/vagrant-lxc).

 If you need to create machines with different technologies, or deploy them to unsupported cloud platforms, you can develop a custom provider in Ruby language. To find out how, see [Plugin Development: Providers](https://www.vagrantup.com/docs/plugins/providers) in Vagrant documentation. The [Vagrant AWS](https://github.com/mitchellh/vagrant-aws) Provider was initially written as an example provider.

 ### Provisioners

 A provisioner is a technology used to deploy software to the newly created machines.

 The simplest provisioner is `shell`, which runs a shell file inside the Vagrant machine. `powershell` is also available.

 Other providers use automation software to provision the machine. There are provisioners that allow one to use [Ansible](../ansible-and-mariadb/index), [Puppet](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index), Chef or Salt. Where relevant, there are different provisioners allowing the use of these technologies in a distributed way (for example, using Puppet apply) or in a centralized way (for example, using a Puppet server).

 It is interesting to note that there is both a Docker provider and a Docker provisioner. This means that a Vagrant machine can be a Docker container, thanks to the `docker` provisioner. Or it could be any virtualisation technology with Docker running in it, thanks to the `docker` provisioner. In this case, Docker pulls images and starts containers to run the software that should be running in the Vagrant machine.

 If you need to use an unsupported provisioning method, you can develop a custom provisioner in Ruby language. See [Plugin Development: Provisioners](https://www.vagrantup.com/docs/plugins/provisioners) in Vagrant documentation.

 ### Plugins

 It is possible to install a plugin with this command:

 
```
vagrant plugin install <plugin_name>

```

A Vagrantfile can require that a plugin is installed in this way:

 
```
require 'plugin_name'

```

A plugin can be a Vagrant plugin or a Ruby gem installable from [rubygems.org](https://rubygems.org/). It is possible to install a plugin that only exists locally by specifying its path.

 ### Changes in Vagrant 3.0

 HashiCorp published an article that describes its [plans for Vagrant 3.0](https://www.hashicorp.com/blog/toward-vagrant-3-0).

 Vagrant will switch to a client-server architecture. Most of the logic will be stored in the server, while the development machines will run a thin client that communicates with the server. It will be possible to store the configuration in a central database.

 Another notable change is that Vagrant is switching from Ruby to Go. For some time, it will still be possible to use Vagrantfiles and plugins written in Ruby. However, in the future Vagrantfiles and plugins should be written in one of the languages that support [gRPC](https://grpc.io/) (not necessarily Go). Vagrantfiles can also be written in [HCL](https://github.com/hashicorp/hcl), HashiCorp Configuration Language.

 Vagrant Commands
----------------

 This is a list of the most common Vagrant commands. For a complete list, see [Command-Line Interface](https://www.vagrantup.com/docs/cli) in Vagrant documentation.

 To list the available machines:

 
```
vagrant box list

```

To start a machine from a box:

 
```
cd /box/directory
vagrant up

```

To connect to a machine:

 
```
vagrant ssh

```

To see all machines status and their id:

 
```
vagrant global-status

```

To destroy a machine:

 
```
vagrant destroy <id>

```

Vagrant Resources and References
--------------------------------

 Here are some valuable websites and pages for Vagrant users.

 * [Vagrant Up](https://www.vagrantup.com/).
* [app.vagrantup.com](https://app.vagrantup.com/).
* [Vagrant Community](https://www.vagrantup.com/community).
* [Vagrant on Wikipedia](https://en.wikipedia.org/wiki/Vagrant_(software)).
* [Vagrant on HashiCorp Learn](https://learn.hashicorp.com/vagrant).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/vagrant-overview-for-mariadb-users/>

Creating a Vagrantfile
======================

    In this page we discuss how to create a Vagrantfile, which you can use to create new boxes or machines. This content is specifically written to address the needs of MariaDB users.

 A Basic Vagrantfile
-------------------

 A Vagrantfile is a Ruby file that instructs Vagrant to create, depending on how it is executed, new Vagrant machines or boxes. You can see a box as a compiled Vagrantfile. It describes a type of Vagrant machines. From a box, we can create new Vagrant machines. However, while a box is easy to distribute to a team or to a wider public, a Vagrantfile can also directly create one or more Vagrant machines, without generating any box.

 Here is a simple Vagrantfile example:

 
```
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
  config.vm.provider "virtualbox"
  config.vm.provision :shell, path: "bootstrap.sh"
end

```

`Vagrant.configure("2")` returns the Vagrant configuration object for the new box. In the block, we'll use the `config` alias to refer this object. We are going to use version 2 of Vagrant API.

 `vm.box` is the base box that we are going to use. It is Ubuntu BionicBeaver (18.04 LTS), 64-bit version, provided by HashiCorp. The schema for box names is simple: the maintainer account in [Vagrant Cloud](https://app.vagrantup.com/boxes/search) followed by the box name.

 We use `vm.provision` to specify the name of the file that is going to be executed at the machine creation, to provision the machine. `bootstrap.sh` is the conventional name used in most cases.

 To create new Vagrant machines from the Vagrantfile, move to the directory that contains the Vagrant project and run:

 
```
vagrant up

```

To compile the Vagrantfile into a box:

 
```
vagrant package

```

These operations can take time. To preventively check if the Vagrantfile contains syntax errors or certain types of bugs:

 
```
vagrant validate

```

Providers
---------

 A provider allows Vagrant to create a Vagrant machine using a certain technology. Different providers may enable a virtual machine manager ([VirtualBox](https://www.vagrantup.com/docs/providers/virtualbox), [VMWare](https://www.vagrantup.com/docs/providers/vmware), [Hyper-V](https://www.vagrantup.com/docs/providers/hyperv)...), a container manager ([Docker](https://www.vagrantup.com/docs/providers/docker)), or remote cloud hosts ([AWS](https://github.com/mitchellh/vagrant-aws), [Google Compute Engine](https://github.com/mitchellh/vagrant-google)...).

 Some providers are developed by third parties. [app.vagrant.com](https://app.vagrantup.com/) supports search for boxes that support the most important third parties providers. To find out how to develop a new provider, see [Plugin Development: Providers](https://www.vagrantup.com/docs/plugins/providers).

 Provider options can be specified. Options affect the type of Vagrant machine that is created, like the number of virtual CPUs. Different providers support different options.

 It is possible to specify multiple providers. In this case, Vagrant will try to use them in the order they appear in the Vagrantfile. It will try the first provider; if it is not available it will try the second; and so on.

 Here is an example of providers usage:

 
```
Vagrant.configure("2") do |config|
    config.vm.box = "hashicorp/bionic64"
    config.vm.provider "virtualbox" do |vb|
        vb.customize ["modifyvm", :id, "--memory", 1024 * 4]
    end
    config.vm.provider "vmware_fusion"
end

```

In this example, we try to use VirtualBox to create a virtual machine. We specify that this machine must have 4G of RAM (1024M \* 4). If VirtualBox is not available, Vagrant will try to use VMWare.

 This mechanism is useful for at least a couple of reasons:

 * Different users may use different systems, and maybe they don't have the same virtualization technologies installed.
* We can gradually move from one provider to another. For a period of time, some users will have the new virtualization technology installed, and they will use it; other users will only have the old technology installed, but they will still be able to create machines with Vagrant.

 Provisioners
------------

 We can use different methods for provisioning. The simplest provisioner is `shell`, that allows one to run a Bash file to provision a machine. Other provisioners allow setting up the machines using automation software, including Ansible, Puppet, Chef and Salt.

 To find out how to develop a new provisioner, see [Plugin Development: Provisioners](https://www.vagrantup.com/docs/plugins/provisioners).

 ### The `shell` Provisioner

 In the example above, the [shell](https://www.vagrantup.com/docs/provisioning/shell) provisioner runs boostrap.sh inside the Vagrant machine to provision it. A simple bootstrap.sh may look like the following:

 
```
#!/bin/bash

apt-get update
apt-get install -y 

```

To find out the steps to install MariaDB on your system of choice, see the [Getting, Installing, and Upgrading MariaDB](../getting-installing-and-upgrading-mariadb/index) section.

 You may also want to restore a database backup in the new Vagrant machine. In this way, you can have the database needed by the application you are developing. To find out how to do it, see [Backup and Restore Overview](../backup-and-restore-overview/index). The most flexible type of backup (meaning that it works between different MariaDB versions, and in some cases even between MariaDB and different DBMSs) is a [dump](../mysqldump/index).

 On Linux machines, the `shell` provisioner uses the default shell. On Windows machines, it uses PowerShell.

 ### Uploading Files

 If we use the `shell` provisioner, we need a way to upload files to the new machine when it is created. We could use the `file` provisioner, but it works by connecting the machine via ssh, and the default user doesn't have permissions for any directory except for the synced folders. We could change the target directory owner, or we could add the default user to a group with the necessary privileges, but these are not considered good practices.

 Instead, we can just put the file we need to upload somewhere in the synced folder, and then copy it with a shell command:

 
```
cp ./files/my.cnf /etc/mysql/conf.d/

```

### Provisioning Vagrant with Ansible

 Here is an example of how to provision a Vagrant machine or box by running Ansible:

 
```
Vagrant.configure("2") do |config|
  ...
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "vagrant.yml"
  end
end

```

With the [Ansible provisioner](https://www.vagrantup.com/docs/provisioning/ansible), Ansible runs in the host system and applies a playbook in the guest system. In this example, it runs a playbook called `vagrant.yml`. The [Ansible Local provisioner](https://www.vagrantup.com/docs/provisioning/ansible_local) runs the playbook in the vagrant machine.

 For more information, see [Using Vagrant and Ansible](https://docs.ansible.com/ansible/2.3/guide_vagrant.html) in the Ansible documentation. For an introduction to Ansible for MariaDB users, see [Ansible and MariaDB](../ansible-and-mariadb/index).

 ### Provisioning Vagrant with Puppet

 To provision a Vagrant machine or box by running Puppet:

 
```
Vagrant.configure("2") do |config|
  ...
  config.vm.provision "puppet" do |puppet|
    puppet.manifests_path = "manifests"
    puppet.manifest_file = "default.pp"
  end
end

```

In this example, Puppet Apply runs in the host system and no Puppet Server is needed. Puppet expects to find a `manifests` directory in the project directory. It expects it to contain `default.pp`, which will be used as an entry point. Note that `puppet.manifests_path` and `puppet.manifest_file` are set to their default values.

 Puppet needs to be installed in the guest machine.

 To use a Puppet server, the `puppet_server` provisioner can be used:

 
```
Vagrant.configure("2") do |config|
  ...
  config.vm.provision "puppet_server" do |puppet|
    puppet.puppet_server = "puppet.example.com"
  end
end

```

See the [Puppet Apply provisioner](https://www.vagrantup.com/docs/provisioning/puppet_apply) and the [Puppet Agent Provisioner](https://www.vagrantup.com/docs/provisioning/puppet_agent).

 For an introduction to Puppet for MariaDB users, see [Puppet and MariaDB](../automated-mariadb-deployment-and-administration-puppet-and-mariadb/index).

 Sharing Files Between the Host and a Guest System
-------------------------------------------------

 To restore a backup into MariaDB, in most cases we need to be able to copy it from the host system to the box. We may also want to occasionally copy MariaDB logs from the box to the host system, to be able to investigate problems.

 The project directory (the one that contains the Vagrantfile) by default is shared with the virtual machine and mapped to the `/vagrant` directory (the synced folder). It is a good practice to put there all files that should be shared with the box when it is started. Those files should normally be versioned.

 The synced folder can be changed. In the above example, we could simply add one line:

 
```
config.vm.synced_folder "/host/path", "/guest/path"

```

The synced folder can also be disabled:

 
```
config.vm.synced_folder '.', '/vagrant', disabled: true

```

Note that multiple Vagrant machines may have synced folders that point to the same directory on the host system. This can be useful in some cases, if you prefer to test some functionalities quickly, rather that replicating production environment as faithfully as possible. For example, to test if you're able to take a backup from one machine and restore it to another, you can store the backup in a common directory.

 Network Communications
----------------------

 It is often desirable for a machine to be able to communicate with "the outside". This can be done in several ways:

 * Private networks;
* Public networks;
* Exposing ports to the host.

 Remembers that Vagrant doesn't create machines, but it asks a provisioner to create machines. Some provisioners support all of these communication methods, others may support some of them, or even none of them. When you create a Vagrantfile that starts machines using one of these features, it is implicit that this can only happen if the provisioner you are using supports the features you need. Check your provisioner documentation to find out which features it supports.

 The default provisioner, VirtualBox, supports all these communication methods, including multiple networks.

 ### Private Networks

 A private network is a networks that can only be accesses by machines that run on the same host. Usually this also means that the machines must run on the same provisioner (for example, they all must be VirtualBox virtual machines).

 Some provisioners support multiple private networks. This means that every network has a different name and can be accessed by different machines.

 The following line shows how to create or join a private network called "example", where this machine's IP is assigned by the provisioner via DHCP:

 
```
config.vm.network 'private_network', name: 'example', type: 'dhcp'

```

While this is very convenient to avoid IP conflicts, sometimes you prefer to assign some IP's manually, in this way:

 
```
config.vm.network 'private_network', name: 'example', ip: '111.222.111.222'

```

### Public Networks

 As explained above, public networks are networks that can be accessed by machines that don't run on the same host with the same provider.

 To let a machine join a public network:

 
```
# use provisioner DHCP:
config.vm.network "public_network", use_dhcp_assigned_default_route: true

# assign ip manually:
config.vm.network "public_network", ip: "111.222.111.222"

```

To improve security, you may want to configure a gateway:

 
```
config.vm.provision "shell", run: "always", inline: "route add default gw 111.222.111.222"

```

### Exposing Ports

 Vagrant allows us to map a TCP or UDP port in a guest system to a TCP or UDP port in the host system. For example, you can map a virtual machine port 3306 to the host port 12345. Then you can connect MariaDB in this way:

 
```
mariadb -hlocalhost -P12345 -u<user> -p<password>

```

You are not required to map a port to a port with a different number. In the above example, if the port 3306 in your host is not in use, you are free to map the guest port 3306 to the host port 3306.

 There are a couple of caveats:

 * You can't map a single host port to multiple guest ports. If you want to expose the port 3306 from multiple Vagrant machines, you'll have to map them to different host ports. When running many machines this can be hard to maintain.
* Ports with numbers below 1024 are privileged ports. Mapping privileged ports requires root privileges.

 To expose a port:

 
```
config.vm.network 'forwarded_port', guest: 3306, host: 3306

```

### Use Cases

 Suppose you run MariaDB and an application server in two separate Vagrant machines. It's usually best to let them communicate via a private network, because this greatly increases your security. The application server will still need to expose ports to the host, so the application can be tested with a web browser.

 Suppose you have multiple environments of the same type, like the one described above. They run different applications that don't communicate with each other. In this case, if your provisioner supports this, you will run multiple private networks. You will need to expose the applications servers ports, mapping them to different host ports.

 You may even want to implement different private networks to create an environment that reflects production complexity. Maybe in production you have [a cluster](../galera-cluster/index) of three MariaDB servers, and the application servers communicate with them via a proxy layer (ProxySQL, HAProxy, or [MaxScale](../maxscale/index)). So the applications can communicate with the proxies, but have no way to reach MariaDB directly. So there is a private network called "database" that can be accessed by the MariaDB servers and the proxy servers, and another private network called "application" that can be accessed by the proxy servers and the application servers. This requires that your provisioner supports multiple private networks.

 Using public networks instead of private one will allow VMs that run on different hosts to be part of your topology. In general this is considered as an insecure practice, so you should probably ask yourself if you really need to do this.

 References
----------

 The [vagrant-mariadb-examples](https://github.com/Vettabase/vagrant-mariadb-examples) repository is an example of a Vagrantfile that creates a box containing MariaDB and some useful tools for developers.

 Further information can be found in Vagrant documentation.

 * [Vagrantfile](https://www.vagrantup.com/docs/vagrantfile).
* [Providers](https://www.vagrantup.com/docs/providers).
* [Synced Folders](https://www.vagrantup.com/docs/synced-folders).
* [Ansible Provisioner](https://www.vagrantup.com/docs/provisioning/ansible).
* [Puppet Apply Provisioner](https://www.vagrantup.com/docs/provisioning/puppet_apply).
* [Puppet Agent Provisioner](https://www.vagrantup.com/docs/provisioning/puppet_agent).

 See also [Ruby documentation](http://www.ruby-lang.org/en/documentation/).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-a-vagrantfile/>

Vagrant Security Concerns
=========================

    Databases typically contain information to which access should be restricted. For this reason, it's worth discussing some security concerns that Vagrant users should be aware of.

 Access to the Vagrant Machine
-----------------------------

 By default, Vagrant machines are only accessible from the localhost. SSH access uses randomly generated key pairs, and therefore it is secure.

 The password for `root` and `vagrant` is "vagrant" by default. Consider changing it.

 Synced Folders
--------------

 By default, the project folder in the host system is shared with the machine, which sees it as `/vagrant`. This means that whoever has access to the project folder also has read and write access to the synced folder. If this is a problem, make sure to properly restrict the access to the synced folder.

 If we need to exchange files between the host system and the Vagrant machine, it is not advisable to disable the synced folder. This is because the only alternative is to use the `file` provider, which works by copying files to the machine via ssh. The problem is that the default ssh user does not have permissions to write to any directory by default, and changing this would be less secure than using a synced folder.

 When a machine is provisioned, it should read the needed files from the synced folder or copy them to other places. Files in the synced folder should not be accessed by the Vagrant machine during its normal activities. For example, it is fine to load a dump from the synced folder during provisioning; and it is fine to copy configuration files from the synced folder to directories in `/etc` during provisioning. But it is a bad practice to let MariaDB use table files located in the synced folder.

 Reporting Security Bugs
-----------------------

 Note that security bugs are not reported as normal bugs. Information about security bugs are not public. See [Security at HashiCorp](https://www.hashicorp.com/security) for details.

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/vagrant-security-concerns/>

Kubernetes Overview for MariaDB Users
=====================================

    Kubernetes, or K8s, is software to orchestrate containers. It is released under the terms of an open source license, Apache License 2.0.

 Kubernetes was originally developed by Google. Currently it is maintained by the Cloud Native Computing Foundation (CNCF), with the status of Graduated Project.

 For information about how to setup a learning environment or a production environment, see [Getting started](https://kubernetes.io/docs/setup/) in Kubernetes documentation.

 Architecture
------------

 Kubernetes runs in a **cluster**. A cluster runs a **workload**: a set of servers that are meant to work together (web servers, database servers, etc).

 A Kubernetes cluster consists of the following components:

 * **Nodes** run containers with the servers needed by our applications.
* **Controllers**constantly check the cluster nodes current state, and compare it with the desired state.
* A **Control Plane** is a set of different components that store the cluster desired state and take decisions about the nodes. The Control Plane provides an API that is used by the controllers.

 For more information on Kubernetes architecture, see [Concepts](https://kubernetes.io/docs/concepts/) and [Kubernetes Components](https://kubernetes.io/docs/concepts/overview/components/) in Kubernetes documentation.

 ### Nodes

 A node is a system that is responsible to run one or more pods. A pod is a set of containers that run a Kubernetes workload or part of it. All containers that run in the same pod are also located on the same node. Usually identical pods run on different nodes for fault tolerance.

 For more details, see [Nodes](https://kubernetes.io/docs/concepts/architecture/nodes/) in the Kubernetes documentation.

 Every node must necessarily have the following components:

 * **kubelet**
* **kube-proxy**
* A **container runtime**

 #### kubelet

 kubelet has a set of **PodSpecs** which describe the desired state of pods. It checks that the current state of the pods matches the desired state. It especially takes care that containers don't crash.

 #### kube-proxy

 In a typical Kubernetes cluster, several containers located in different pods need to connect to other containers, located in the same pods (for performance and fault tolerance reasons). Therefore, when we develop and deploy an application, we can't know in advance the IPs of the containers to which it will have to connect. For example, an application server may need to connect to MariaDB, but the MariaDB IP will be different for every pod.

 The main purpose of kube-proxy is to implement the concept of Kubernetes **services**. When an application needs to connect to MariaDB, it will connect to the MariaDB service. kube-proxy will receive the request and will redirect it to a running MariaDB container in the same pod.

 #### Container Runtime

 Kubernetes manages the containers in a pod via a container runtime, or container manager, that supports the Kubernetes Container Runtime Interface (CRI). Container runtimes that meet this requisite are listed in the [Container runtimes](https://kubernetes.io/docs/setup/production-environment/container-runtimes/) page in the Kubernetes documentation. More information about the Container Runtime Interface can be found [on GitHub](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/container-runtime-interface.md).

 Originally, Kubernetes used Docker as a container runtime. This was later deprecated, but Docker images can still be used using any container runtime.

 ### Controllers

 Controllers constantly check if there are differences between the pod's current state and their desired state. When differences are found, controllers try to fix them. Each node type controls one or more resource types. Several types of controllers are needed to run a cluster.

 Most of the actions taken by the controllers user the API server in the Control Plane. However, this is not necessarily true for custom controllers. Also, some actions cannot be performed via the Control Plane. For example, if some nodes crashed, adding new nodes involves taking actions outside of the Kubernetes cluster, and controllers will have to do this themselves.

 It is possible to write custom controllers to perform checks that require knowledge about a specific technology. For example, a MariaDB custom controller may want to check if [replication](../standard-replication/index) is working by issuing [SHOW REPLICA STATUS](../show-replica-status/index) commands. This logic is specific to the way MariaDB works, and can only be implemented in a customer controller. Custom controllers are usually part of operators.

 For more information, see [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/) in the Kubernetes documentation.

 ### Control Plane

 The control plane consists of the following components.

 For more information about the control plane, see [Control Plane Components](https://kubernetes.io/docs/concepts/overview/components/) in Kubernetes documentation.

 #### API Server

 An API Server exposes API functions both internally and externally. It is essential to coordinate Kubernetes components so that they react to node's change of state, and it allows the user to send commands.

 The default implementation of the API Server is kube-apiserver. It is able to scale horizontally and to balance the load between its instances.

 #### kube-controller-manager

 Most controllers run in this component.

 #### etcd

 etcd contains all data used by a Kubernetes cluster. It is a good idea to take regular backups of etcd data.

 #### kube-scheduler

 When a new pod is created, kube-scheduler decides which node should host it. The decision is made based on several criteria, like the resource requirements for the pod.

 #### cloud-controller-manager

 cloud-controller-manager implements the logic and API of a cloud provider. It receives requests from the API Server and performs specific actions, like creating an instance in AWS. It also runs controllers that are specific to a cloud vendor.

 ### Clients and Tools

 Kubernetes comes with a set of tools that allow us to communicate with the API server and test a cluster.

 #### kubectl

 kubectl allows communication with the API server and run commands on a Kubernetes cluster.

 #### kubeadm

 kubeadm allows creating a Kubernetes cluster that is ready to receive commands from kubectl.

 #### kind and minikube

 These tools are meant to create and manage test clusters on a personal machine. They work on Linux, MacOS and Windows. kind creates a cluster that consists of Docker containers, therefore it requires Docker to be installed. minikube runs a single-node cluster on the local machine.

 Kubernetes Resources and References
-----------------------------------

 * [Kubernetes website](https://kubernetes.io/).
* [Kubernetes](https://en.wikipedia.org/wiki/Kubernetes) on Wikipedia.
* [Kubernetes organization](https://github.com/kubernetes) on GitHub.
* [OperatorHub.io](https://operatorhub.io/)
* [Kubernetes Community Forums](https://discuss.kubernetes.io/).
* (video) [MariaDB database clusters on Kubernetes](https://mariadb.org/fest2020/kubernetes/), by Pengfei Ma, at MariaDB Server Fest 2020.
* Series of posts by Anel Husakovic on the MariaDB Foundation blog:
	+ [Start MariaDB in K8s](https://mariadb.org/start-mariadb-in-k8s/)
	+ [MariaDB & K8s: Communication between containers/Deployments](https://mariadb.org/mariadb-k8s-communication-between-containers-deployments/)
	+ [MariaDB & K8s: Create a Secret and use it in MariaDB deployment](https://mariadb.org/mariadb-k8s-create-a-secret-and-use-it-in-mariadb-deployment/)
	+ [MariaDB & K8s: Deploy MariaDB and WordPress using Persistent Volumes](https://mariadb.org/mariadb-k8s-deploy-mariadb-and-wordpress-using-persistent-volumes/)
	+ [Create statefulset MariaDB application in K8s](https://mariadb.org/create-statefulset-mariadb-application-in-k8s/)
	+ [MariaDB replication using containers](https://mariadb.org/mariadb-replication-using-containers/)
	+ [MariaDB & K8s: How to replicate MariaDB in K8s](https://mariadb.org/mariadb-k8s-how-to-replicate-mariadb-in-k8s/)

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/kubernetes-overview-for-mariadb-users/>

Kubernetes Operators for MariaDB
================================

    Operators basically instruct Kubernetes about how to manage a certain technology. Kubernetes comes with some default operators, but it is possible to create custom operators. Operators created by the community can be found on [OperatorHub.io](https://operatorhub.io/).

 Custom Operators
----------------

 Kubernetes provides a declarative API. To support a specific (i.e. MariaDB) technology or implement a desired behavior (i.e. provisioning a [replica](../standard-replication/index)), we extend Kubernetes API. This involves creating two main components:

 * A custom resource.
* A custom controller.

 A custom resource adds an API endpoint, so the resource can be managed via the API server. It includes functionality to get information about the resource, like a list of the existing servers.

 A custom controller implements the checks that must be performed against the resource to check if its state should be corrected using the API. In the case of MariaDB, some reasonable checks would be verifying that it accepts connections, replication is running, and a server is (or is not) read only.

 MariaDB Operator
----------------

 [mariadb-operator](https://github.com/mariadb-operator/mariadb-operator) is a Kubernetes operator that allows you to run and operate MariaDB in a cloud native way. It aims for declaratively managing your MariaDB using Kubernetes CRDs rather than imperative commands.

 It's available in both [Artifact Hub](https://artifacthub.io/packages/helm/mariadb-operator/mariadb-operator) and [Operator Hub](https://operatorhub.io/operator/mariadb-operator) and supports the following features:

 * Provisioning highly configurable MariaDB servers
* Multi-master HA via Galera. Automatic Galera cluster recovery
* Single master HA via SemiSync replication. Primary switchover. Automatic primary failover
* Take and restore backups. Scheduled backups. Backup rotation
* PVCs and Kubernetes volumes (i.e. NFS) backup storage
* Bootstrap new instances from backups and volumes (i.e NFS)
* Manage users, grants and logical databases
* Configure connections for your applications
* Orchestrate and schedule sql scripts
* Prometheus metrics
* Validation webhooks to provide CRD inmutability
* Additional printer columns to report the current CRD status
* CRDs designed according to the Kubernetes API conventions
* GitOps friendly
* Multi-arch distroless based image
* Install it using kubectl, helm or OLM

 This operator is open source and released under the terms of the MIT license. The source code is available on [GitHub](https://github.com/mariadb-operator/mariadb-operator).

 Other Operators
---------------

 If you know about other MariaDB operators, feel free to add them to this page (see [Writing and Editing Knowledge Base Articles](../writing-and-editing-knowledge-base-articles/index)).

 MySQL and Percona Server operators should work as well, though some changes may be necessary to fix [incompatibilities](../mariadb-vs-mysql-compatibility/index) or take advantage of certain [MariaDB features](../mariadb-vs-mysql-features/index).

 

---

 Content initially contributed by [Vettabase Ltd](https://vettabase.com/).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/kubernetes-operators-for-mariadb/>

System Variables Added in MariaDB 10.2
======================================

    This is a list of [system variables](../server-system-variables/index) that have been added in the [MariaDB 10.2](../what-is-mariadb-102/index) series. The list does not include variables that are not part of the default release.

 


| Variable | Added |
| --- | --- |
| [aria\_recover\_options](../aria-system-variables/index#aria_recover_options) | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| [eq\_range\_index\_dive\_limit](../server-system-variables/index#eq_range_index_dive_limit) | [MariaDB 10.2.18](https://mariadb.com/kb/en/mariadb-10218-release-notes/) |
| [innodb\_adaptive\_hash\_index\_parts](../xtradbinnodb-server-system-variables/index#innodb_adaptive_hash_index_parts) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_deadlock\_detect](../xtradbinnodb-server-system-variables/index#innodb_deadlock_detect) | [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) |
| [innodb\_default\_row\_format](../xtradbinnodb-server-system-variables/index#innodb_default_row_format) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_encrypt\_temporary\_ables](../xtradbinnodb-server-system-variables/index#innodb_encrypt_temporary_tables) | [MariaDB 10.2.26](https://mariadb.com/kb/en/mariadb-10226-release-notes/) |
| [innodb\_fill\_factor](../xtradbinnodb-server-system-variables/index#innodb_fill_factor) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_flush\_sync](../xtradbinnodb-server-system-variables/index#innodb_flush_sync) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_lock\_schedule\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_lock_schedule_algorithm) | [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) |
| [innodb\_log\_checksums](../xtradbinnodb-server-system-variables/index#innodb_log_checksums) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_log\_optimize\_ddl](../xtradbinnodb-server-system-variables/index#innodb_log_optimize_ddl) | [MariaDB 10.2.17](https://mariadb.com/kb/en/mariadb-10217-release-notes/) |
| [innodb\_log\_write\_ahead\_size](../xtradbinnodb-server-system-variables/index#innodb_log_write_ahead_size) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_max\_undo\_log\_size](../xtradbinnodb-server-system-variables/index#innodb_max_undo_log_size) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_page\_cleaners](../xtradbinnodb-server-system-variables/index#innodb_page_cleaners) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_purge\_rseg\_truncate\_frequency](../xtradbinnodb-server-system-variables/index#innodb_purge_rseg_truncate_frequency) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [innodb\_safe\_truncate](../xtradbinnodb-server-system-variables/index#innodb_safe_truncate) | [MariaDB 10.2.19](https://mariadb.com/kb/en/mariadb-10219-release-notes/) |
| [innodb\_stats\_include\_delete\_marked](../xtradbinnodb-server-system-variables/index#innodb_stats_include_delete_marked) | [MariaDB 10.2.6](https://mariadb.com/kb/en/mariadb-1026-release-notes/) |
| [innodb\_temp\_data\_file\_path](../xtradbinnodb-server-system-variables/index#innodb_temp_data_file_path) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [max\_recursive\_iterations](../server-system-variables/index#max_recursive_iterations) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [read\_binlog\_speed\_limit](../replication-and-binary-log-server-system-variables/index#read_binlog_speed_limit) | [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) |
| [session\_track\_schema](../server-system-variables/index#session_track_schema) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [session\_track\_state\_change](../server-system-variables/index#session_track_state_change) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [session\_track\_system\_variables](../server-system-variables/index#session_track_system_variables) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [session\_track\_transaction\_info](../server-system-variables/index#session_track_transaction_info) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [slave\_parallel\_workers](../replication-and-binary-log-server-system-variables/index#slave_parallel_workers) | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| [table\_open\_cache\_instances](../server-system-variables/index#table_open_cache_instances) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [thread\_pool\_prio\_kickup\_timer](../thread-pool-system-and-status-variables/index#thread_pool_prio_kickup_timer) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [thread\_pool\_priority](../thread-pool-system-and-status-variables/index#thread_pool_priority) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [tmp\_disk\_table\_size](../server-system-variables/index#tmp_disk_table_size) | [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/) |
| [tmp\_memory\_table\_size](../server-system-variables/index#tmp_memory_table_size) | [MariaDB 10.2.7](https://mariadb.com/kb/en/mariadb-1027-release-notes/) |
| [wsrep\_certification\_rules](../galera-cluster-system-variables/index#wsrep_certification_rules) | [MariaDB 10.2.22](https://mariadb.com/kb/en/mariadb-10222-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.2](../status-variables-added-in-mariadb-102/index)
* [System Variables Added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index)
* [System Variables Added in MariaDB 10.1](../system-variables-added-in-mariadb-101/index)
* [System Variables Added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-102/>

Status Variables Added in MariaDB 10.2
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.2](../what-is-mariadb-102/index) series.

 


| Variable | Added |
| --- | --- |
| [Com\_alter\_user](../server-status-variables/index#com_alter_user) | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| [Com\_execute\_immediate](../server-status-variables/index#com_execute_immediate) | [MariaDB 10.2.3](https://mariadb.com/kb/en/mariadb-1023-release-notes/) |
| [Com\_multi](../server-status-variables/index#com_multi) | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| [Com\_show\_create\_user](../server-status-variables/index#com_show_create_user) | [MariaDB 10.2.0](https://mariadb.com/kb/en/mariadb-1020-release-notes/) |
| [Innodb\_buffer\_pool\_resize\_status](../xtradbinnodb-server-status-variables/index#innodb_buffer_pool_resize_status) | [MariaDB 10.2.2](https://mariadb.com/kb/en/mariadb-1022-release-notes/) |
| [Innodb\_encryption\_num\_key\_requests](../xtradbinnodb-server-status-variables/index#innodb_encryption_num_key_requests) | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |
| [Innodb\_have\_punch\_hole](../xtradbinnodb-server-status-variables/index#innodb_have_punch_hole) | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |
| [Innodb\_pages0read](../xtradbinnodb-server-status-variables/index#innodb_pages0_read) | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |
| [Innodb\_scrub\_log](../xtradbinnodb-server-status-variables/index#innodb_scrub_log) | [MariaDB 10.2.4](https://mariadb.com/kb/en/mariadb-1024-release-notes/) |

 
See Also
--------

 * [System variables added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index)
* [Status variables added in MariaDB 10.3](../status-variables-added-in-mariadb-103/index)
* [Status variables added in MariaDB 10.1](../status-variables-added-in-mariadb-101/index)
* [Status variables added in MariaDB 10.0](../status-variables-added-in-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-102/>

Status Variables Added in MariaDB 10.3
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.3](../what-is-mariadb-103/index) series.

 


| Variable | Added |
| --- | --- |
| [Acl\_package\_body\_grants](../server-status-variables/index#acl_package_body_grants) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Acl\_package\_spec\_grants](../server-status-variables/index#acl_package_spec_grants) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_alter\_sequence](../server-status-variables/index#com_alter_sequence) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [Com\_create\_package](../server-status-variables/index#com_create_package) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_create\_package\_body](../server-status-variables/index#com_create_package_body) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_create\_sequence](../server-status-variables/index#com_create_sequence) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [Com\_drop\_package](../server-status-variables/index#com_drop_package) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_drop\_package\_body](../server-status-variables/index#com_drop_package_body) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_drop\_sequence](../server-status-variables/index#com_drop_sequence) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [Com\_show\_create\_package](../server-status-variables/index#com_show_create_package) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_show\_create\_package\_body](../server-status-variables/index#com_show_create_package_body) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_show\_package\_status](../server-status-variables/index#com_show_package_status) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Com\_show\_package\_body\_status](../server-status-variables/index#com_show_package_body_status) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Feature\_json](../server-status-variables/index#feature_json) | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| [Feature\_system\_versioning](../server-status-variables/index#feature_system_versioning) | [MariaDB 10.3.7](https://mariadb.com/kb/en/mariadb-1037-release-notes/) |
| [Handler\_tmp\_delete](../server-status-variables/index#handler_tmp_delete) | [MariaDB 10.3.0](https://mariadb.com/kb/en/mariadb-1030-release-notes/) |
| [Innodb\_buffer\_pool\_load\_incomplete](../xtradbinnodb-server-status-variables/index#innodb_buffer_pool_load_incomplete) | [MariaDB 10.3.5](https://mariadb.com/kb/en/mariadb-1035-release-notes/) |
| [Memory\_used\_initial](../server-status-variables/index#memory_used_initial) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Rpl\_semi\_sync\*](../semisynchronous-replication-plugin-status-variables/index) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Rpl\_transactions\_multi\_engine](../replication-and-binary-log-status-variables/index#rpl_transactions_multi_engine) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [Table\_open\_cache\_active\_instances](../server-status-variables/index#table_open_cache_active_instances) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Table\_open\_cache\_hits](../server-status-variables/index#table_open_cache_hits) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Table\_open\_cache\_misses](../server-status-variables/index#table_open_cache_misses) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Table\_open\_cache\_overflows](../server-status-variables/index#table_open_cache_overflows) | [MariaDB 10.3.3](https://mariadb.com/kb/en/mariadb-1033-release-notes/) |
| [Transactions\_gtid\_foreign\_engine](../replication-and-binary-log-server-status-variables/index#transactions_gtid_foreign_engine) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |
| [Transactions\_multi\_engine](../replication-and-binary-log-server-status-variables/index#transactions_multi_engine) | [MariaDB 10.3.1](https://mariadb.com/kb/en/mariadb-1031-release-notes/) |

 
See Also
--------

 * [System variables added in MariaDB 10.3](../system-variables-added-in-mariadb-103/index)
* [Status variables added in MariaDB 10.4](../status-variables-added-in-mariadb-104/index)
* [Status variables added in MariaDB 10.2](../status-variables-added-in-mariadb-102/index)
* [Status variables added in MariaDB 10.1](../status-variables-added-in-mariadb-101/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-103/>

System Variables Added in MariaDB 5.5
=====================================

    This is a list of [system variables](../server-system-variables/index) that were added in the [MariaDB 5.5](../what-is-mariadb-55/index) series.

 The list excludes variables related to non-default storage engines and plugins that can be added to [MariaDB 5.5](../what-is-mariadb-55/index):

 


| Variable | Added |
| --- | --- |
| [innodb\_adaptive\_flushing\_method](../xtradbinnodb-server-system-variables/index#innodb_adaptive_flushing_method) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_adaptive\_hash\_index\_partitions](../xtradbinnodb-server-system-variables/index#innodb_adaptive_hash_index_partitions) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_blocking\_buffer\_pool\_restore](../xtradbinnodb-server-system-variables/index#innodb_blocking_buffer_pool_restore) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_buffer\_pool\_instances](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_instances) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [nnodb\_buffer\_pool\_restore\_at\_startup](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_restore_at_startup) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_change\_buffering\_debug](../xtradbinnodb-server-system-variables/index#innodb_change_buffering_debug) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_corrupt\_table\_action](../xtradbinnodb-server-system-variables/index#innodb_corrupt_table_action) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_flush\_checkpoint\_debug](../xtradbinnodb-server-system-variables/index#innodb_flush_checkpoint_debug) |
| [innodb\_force\_load\_corrupted](../xtradbinnodb-server-system-variables/index#innodb_force_load_corrupted) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_import\_table\_from\_xtrabackup](../xtradbinnodb-server-system-variables/index#innodb_import_table_from_xtrabackup) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_large\_prefix](../xtradbinnodb-server-system-variables/index#innodb_large_prefix) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_purge\_batch\_size](../xtradbinnodb-server-system-variables/index#innodb_purge_batch_size) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_purge\_threads](../xtradbinnodb-server-system-variables/index#innodb_purge_threads) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_recovery\_update\_relay\_log](../xtradbinnodb-server-system-variables/index#innodb_recovery_update_relay_log) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_rollback\_segments](../xtradbinnodb-server-system-variables/index#innodb_rollback_segments) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_use\_global\_flush\_log\_at\_trx\_commit](../xtradbinnodb-server-system-variables/index#innodb_use_global_flush_log_at_trx_commit) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |
| [innodb\_use\_native\_aio](../xtradbinnodb-server-system-variables/index#innodb_use_native_aio) | [MariaDB 5.5.20](https://mariadb.com/kb/en/mariadb-5520-release-notes/) |

 
See also
--------

 * [System Variables Added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index)
* [Upgrading from MariaDB 5.3 to MariaDB 5.5](../upgrading-from-mariadb-55-to-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-55/>

Status Variables Added in MariaDB 10.0
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.0](../what-is-mariadb-100/index) series.

 The list excludes status related to the following storage engines included in [MariaDB 10.0](../what-is-mariadb-100/index):

 * [Galera Status Variables](../galera-cluster-status-variables/index)
* [Mroonga Status Variables](../mroonga-status-variables/index)
* [Spider Status Variables](../spider-server-status-variables/index)

 


| Variable | Added |
| --- | --- |
| [Binlog\_group\_commit\_trigger\_count](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_count) | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) |
| [Binlog\_group\_commit\_trigger\_timeout](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_timeout) | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) |
| [Binlog\_group\_commit\_trigger\_lock\_wait](../replication-and-binary-log-status-variables/index#binlog_group_commit_trigger_lock_wait) | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) |
| [Com\_create\_role](../server-status-variables/index#com_create_role) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [Com\_drop\_role](../server-status-variables/index#com_drop_role) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [Com\_get\_diagnostics](../server-status-variables/index#com_get_diagnostics) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Com\_grant\_role](../server-status-variables/index#com_grant_role) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [Com\_revoke\_grant](../server-status-variables/index#com_revoke_grant) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [Com\_show\_explain](../server-status-variables/index#com_show_explain) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Com\_start\_all\_slaves](../replication-and-binary-log-status-variables/index#com_start_all_slaves) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Com\_start\_slave](../replication-and-binary-log-status-variables/index#com_start_slave) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Com\_stop\_all\_slaves](../replication-and-binary-log-status-variables/index#com_stop_all_slaves) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Com\_stop\_slave](../replication-and-binary-log-status-variables/index#com_stop_slave) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Connection\_errors\_accept](../server-status-variables/index#connection_errors_accept) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Connection\_errors\_internal](../server-status-variables/index#connection_errors_internal) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Connection\_errors\_max\_connections](../server-status-variables/index#connection_errors_max_connections) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Connection\_errors\_peer\_address](../server-status-variables/index#connection_errors_peer_address) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Connection\_errors\_select](../server-status-variables/index#connection_errors_select) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Connection\_errors\_tcpwrap](../server-status-variables/index#connection_errors_tcpwrap) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [Delete\_scan](../server-status-variables/index#delete_scan) | [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/) |
| [Feature\_delay\_key\_write](../server-status-variables/index#feature_delay_key_write) | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| [Handler\_external\_lock](../server-status-variables/index#handler_external_lock) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Handler\_read\_retry](../server-status-variables/index#handler_read_retry) | [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/) |
| [Innodb\_buffer\_pool\_dump\_status](../xtradbinnodb-server-status-variables/index#innodb_buffer_pool_dump_status) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Innodb\_buffer\_pool\_load\_status](../xtradbinnodb-server-status-variables/index#innodb_buffer_pool_load_status) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Innodb\_master\_thread\_active\_loops](../xtradbinnodb-server-status-variables/index#innodb_master_thread_active_loops) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [Innodb\_master\_thread\_idle\_loops](../xtradbinnodb-server-status-variables/index#innodb_master_thread_idle_loops) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [Innodb\_num\_open\_files](../xtradbinnodb-server-status-variables/index#innodb_num_open_files) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Innodb\_system\_rows\_deleted](../xtradbinnodb-server-status-variables/index#innodb_system_rows_deleted) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| [Innodb\_system\_rows\_inserted](../xtradbinnodb-server-status-variables/index#innodb_system_rows_inserted) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| [Innodb\_system\_rows\_read](../xtradbinnodb-server-status-variables/index#innodb_system_rows_read) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| [Innodb\_system\_rows\_updated](../xtradbinnodb-server-status-variables/index#innodb_system_rows_updated) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| [Memory\_used](../server-status-variables/index#memory_used) | [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) |
| [Oqgraph\_boost\_version](../server-status-variables/index#oqgraph_boost_version) | [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) |
| [Performance\_schema\_accounts\_lost](../server-status-variables/index#performance_schema_accounts_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Performance\_schema\_hosts\_lost](../server-status-variables/index#performance_schema_hosts_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Performance\_schema\_socket\_classes\_lost](../server-status-variables/index#performance_schema_socket_classes_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Performance\_schema\_socket\_instances\_lost](../server-status-variables/index#performance_schema_socket_instances_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Performance\_schema\_stage\_classes\_lost](../server-status-variables/index#performance_schema_stage_classes_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Performance\_schema\_statement\_classes\_lost](../server-status-variables/index#performance_schema_statement_classes_lost) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [Slave\_skipped\_errors](../replication-and-binary-log-status-variables/index#slave_skipped_errors) | [MariaDB 10.0.18](https://mariadb.com/kb/en/mariadb-10018-release-notes/) |
| [Sort\_priority\_queue\_sorts](../server-status-variables/index#sort_priority_queue_sorts) | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| [Update\_scan](../server-status-variables/index#update_scan) | [MariaDB 10.0.27](https://mariadb.com/kb/en/mariadb-10027-release-notes/) |

 
See also
--------

 * [System variables added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index)
* [Status variables added in MariaDB 10.1](../status-variables-added-in-mariadb-101/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-100/>

Plans
======

   MariaDB Development Plans

  

| Title | Description |
| --- | --- |
|  [MariaDB Server Roadmap](../mariadb-server-roadmap/index) |  Describes the MariaDB Server roadmap and how it is determined.  |
|  [Plans for MariaDB 11.3](../plans-for-mariadb-11-3/index) |  Roadmap for MariaDB 11.3.  |
|  [Plans for MariaDB 11.2](../plans-for-mariadb-11-2/index) |  Roadmap for MariaDB 11.2.  |
|  [Plans for MariaDB 11.1](../plans-for-mariadb-11-1/index) |  Roadmap for MariaDB 11.1.  |
|  [Old Plans](../old-plans/index) |  Inactive plans for older and current versions of MariaDB  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/development-plans/>

Worklog
=======

    
 **Worklog has been replaced, please refer to [JIRA - project planning and tracking](../jira-project-planning-and-tracking/index) for further information** .

 
[Worklog](http://askmonty.org/worklog/index.pl) is the tool used to track all development of [MariaDB](../mariadb/index).

 The MariaDB Worklog is open to everyone at <http://askmonty.org/worklog/index.pl> (a free account on [the developer wiki](http://askmonty.org/wiki) is required to suggest new tasks and add comments, votes, donations etc.). The account signup page for the wiki is [here](http://askmonty.org/w/index.php?title=Special:Userlogin&type=signup).

 If you find something in the worklog that you really would like to have done, you can commit to donate some money to the developer when this is done. (Search after "Make offer" on the worklog item you would like to sponsor).

 If there is something in worklog which you would like to develop, you can contact us at 'maria-developers (at) lists.launchpad.com' or 'community (at) askmonty.org'. If you deliver a working solutions that is [accepted into the MariaDB source tree](http://kb.askmonty.org/v/community-contributing-to-the-mariadb-project#expectations-for-developers), you will get 60 % of the so far committed money. The rest of the money is kept by MariaDB Corporation Ab for help managing the project, code reviews, bug fixes, testing, maintenance, updates and merges to future MariaDB versions.

 You can also add a link in the MariaDB worklog to tasks to the [MySQL worklog](http://forge.mysql.com/worklog/). Just refer to the MySQL task as #WL<task number>

 Source Code for Worklog
-----------------------

 The source code for the Worklog application is hosted on [Launchpad](https://launchpad.net/worklog). The license is GPL.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/worklog/>

Status Variables Added in MariaDB 10.1
======================================

    This is a list of [status variables](../server-status-variables/index) that were added in the [MariaDB 10.1](../what-is-mariadb-101/index) series.

 The list excludes status related to the following storage engines included in [MariaDB 10.1](../what-is-mariadb-101/index):

 * [Galera Status Variables](../galera-cluster-status-variables/index)

 


| Variable | Added |
| --- | --- |
| [Acl\_column\_grants](../server-status-variables/index#acl_column_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_database\_grants](../server-status-variables/index#acl_database_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_function\_grants](../server-status-variables/index#acl_function_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_procedure\_grants](../server-status-variables/index#acl_procedure_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_proxy\_users](../server-status-variables/index#acl_proxy_users) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_role\_grants](../server-status-variables/index#acl_role_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_roles](../server-status-variables/index#acl_roles) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_table\_grants](../server-status-variables/index#acl_table_grants) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Acl\_users](../server-status-variables/index#acl_users) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Master\_gtid\_wait\_count](../replication-and-binary-log-status-variables/index#master_gtid_wait_count) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Com\_compound\_sql](../server-status-variables/index#com_compound_sql) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Com\_create\_temporary\_table](../server-status-variables/index#com_create_temporary_table) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [Com\_create\_drop\_table](../server-status-variables/index#com_create_drop_table) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [Com\_show\_generic](../server-status-variables/index#com_show_generic) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_defragment\_compression\_failures](../xtradbinnodb-server-status-variables/index#innodb_defragment_compression_failures) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_defragment\_count](../xtradbinnodb-server-status-variables/index#innodb_defragment_count) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_defragment\_failures](../xtradbinnodb-server-status-variables/index#innodb_defragment_failures) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_encryption\_rotation\_estimated\_iops](../xtradbinnodb-server-status-variables/index#innodb_encryption_rotation_estimated_iops) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_encryption\_rotation\_pages\_flushed](../xtradbinnodb-server-status-variables/index#innodb_encryption_rotation_pages_flushed) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_encryption\_rotation\_pages\_modified](../xtradbinnodb-server-status-variables/index#innodb_encryption_rotation_pages_modified) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_encryption\_rotation\_pages\_read\_from\_cache](../xtradbinnodb-server-status-variables/index#innodb_encryption_rotation_pages_read_from_cache) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_encryption\_rotation\_pages\_read\_from\_disk](../xtradbinnodb-server-status-variables/index#innodb_encryption_rotation_pages_read_from_disk) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_have\_bzip2](../xtradbinnodb-server-status-variables/index#innodb_have_bzip2) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_have\_lz4](../xtradbinnodb-server-status-variables/index#innodb_have_lz4) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_have\_lzma](../xtradbinnodb-server-status-variables/index#innodb_have_lzma) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_have\_lzo](../xtradbinnodb-server-status-variables/index#innodb_have_lzo) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_have\_snappy](../xtradbinnodb-server-status-variables/index#innodb_have_snappy) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_num\_index\_pages\_written](../xtradbinnodb-server-status-variables/index#innodb_num_index_pages_written) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_num\_non\_index\_pages\_written](../xtradbinnodb-server-status-variables/index#innodb_num_non_index_pages_written) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_onlineddl\_pct\_progress](../xtradbinnodb-server-status-variables/index#innodb_onlineddl_pct_progress) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_onlineddl\_rowlog\_pct\_used](../xtradbinnodb-server-status-variables/index#innodb_onlineddl_rowlog_pct_used) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_onlineddl\_rowlog\_rows](../xtradbinnodb-server-status-variables/index#innodb_onlineddl_rowlog_rows) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [Innodb\_num\_page\_compressed\_trim\_op](../xtradbinnodb-server-status-variables/index#innodb_num_page_compressed_trim_op) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_num\_page\_compressed\_trim\_op\_saved](../xtradbinnodb-server-status-variables/index#innodb_num_page_compressed_trim_op_saved) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_num\_pages\_page\_compressed](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_compressed) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_num\_pages\_page\_compression\_error](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_compression_error) | [MariaDB 10.1](../what-is-mariadb-101/index) |
| [Innodb\_num\_pages\_page\_decompressed](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_decompressed) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_num\_pages\_page\_decrypted](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_decrypted) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_num\_pages\_page\_encrypted](../xtradbinnodb-server-status-variables/index#innodb_num_pages_page_encrypted) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [Innodb\_page\_compression\_saved](../xtradbinnodb-server-status-variables/index#innodb_page_compression_saved) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect512](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect512) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect1024](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect1024) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect2048](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect2048) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect4096](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect4096) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect8192](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect8192) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect16384](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect16384) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_page\_compression\_trim\_sect32768](../xtradbinnodb-server-status-variables/index#innodb_page_compression_trim_sect32768) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_secondary\_index\_triggered\_cluster\_reads](../xtradbinnodb-server-status-variables/index#innodb_secondary_index_triggered_cluster_reads) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Innodb\_secondary\_index\_triggered\_cluster\_reads\_avoided](../xtradbinnodb-server-status-variables/index#innodb_secondary_index_triggered_cluster_reads_avoided) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [Master\_gtid\_wait\_count](../replication-and-binary-log-status-variables/index#master_gtid_wait_count) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Master\_gtid\_wait\_time](../replication-and-binary-log-status-variables/index#master_gtid_wait_time) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Master\_gtid\_wait\_timeouts](../replication-and-binary-log-status-variables/index#master_gtid_wait_timeouts) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [Max\_statement\_time\_exceeded](../server-status-variables/index#max_statement_time_exceeded) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |

 
See Also
--------

 * [System variables added in MariaDB 10.1](../system-variables-added-in-mariadb-101/index)
* [Status variables added in MariaDB 10.2](../status-variables-added-in-mariadb-102/index)
* [Status variables added in MariaDB 10.0](../status-variables-added-in-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/status-variables-added-in-mariadb-101/>

System Variables Added in MariaDB 10.1
======================================

    This is a list of [system variables](../server-system-variables/index) that were added in the [MariaDB 10.1](../what-is-mariadb-101/index) series.

 The list excludes the following variables, related to storage engines and plugins included in [MariaDB 10.1](../what-is-mariadb-101/index):

 * [Spider System Variables](../spider-server-system-variables/index)

 


| Variable | Added |
| --- | --- |
| [aria\_encrypt\_tables](../aria-system-variables/index#aria_encrypt_tables) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [default\_tmp\_storage\_engine](../server-system-variables/index#default_tmp_storage_engine) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [encrypt\_binlog](../server-system-variables/index#encrypt_binlog) | [MariaDB 10.1.7](https://mariadb.com/kb/en/mariadb-1017-release-notes/) |
| [encrypt\_tmp\_disk\_tables](../server-system-variables/index#encrypt_tmp_disk_tables) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [encrypt\_tmp\_files](../server-system-variables/index#encrypt_tmp_files) | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/) |
| [enforce\_storage\_engine](../server-system-variables/index#enforce_storage_engine) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [explicit\_defaults\_for\_timestamp](../server-system-variables/index#explicit_defaults_for_timestamp) | [MariaDB 10.1.8](https://mariadb.com/kb/en/mariadb-1018-release-notes/) |
| [innodb\_background\_scrub\_data\_check\_interval](../xtradbinnodb-server-system-variables/index#innodb_background_scrub_data_check_interval) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_background\_scrub\_data\_compressed](../xtradbinnodb-server-system-variables/index#innodb_background_scrub_data_compressed) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_background\_scrub\_data\_interval](../xtradbinnodb-server-system-variables/index#innodb_background_scrub_data_interval) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_background\_scrub\_data\_uncompressed](../xtradbinnodb-server-system-variables/index#innodb_background_scrub_data_uncompressed) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_buf\_dump\_status\_frequency](../xtradbinnodb-server-system-variables/index#innodb_buf_dump_status_frequency) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [innodb\_compression\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_compression_algorithm) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [innodb\_default\_encryption\_key\_id](../xtradbinnodb-server-system-variables/index#innodb_default_page_encryption_key) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [innodb\_default\_row\_format](../xtradbinnodb-server-system-variables/index#innodb_default_row_format) | [MariaDB 10.1.32](https://mariadb.com/kb/en/mariadb-10132-release-notes/) |
| [innodb\_defragment](../xtradbinnodb-server-system-variables/index#innodb_defragment) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_defragment\_fill\_factor](../xtradbinnodb-server-system-variables/index#innodb_defragment_fill_factor) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_defragment\_fill\_factor\_n\_recs](../xtradbinnodb-server-system-variables/index#innodb_defragment_fill_factor_n_recs) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_defragment\_frequency](../xtradbinnodb-server-system-variables/index#innodb_defragment_frequency) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_defragment\_n\_pages](../xtradbinnodb-server-system-variables/index#innodb_defragment_n_pages) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_defragment\_stats\_accuracy](../xtradbinnodb-server-system-variables/index#innodb_defragment_stats_accuracy) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [innodb\_disallow\_writes](../xtradbinnodb-server-system-variables/index#innodb_disallow_writes) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_encrypt\_log](../xtradbinnodb-server-system-variables/index#innodb_encrypt_log) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_encrypt\_tables](../xtradbinnodb-server-system-variables/index#innodb_encrypt_tables) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_encryption\_rotate\_key\_age](../xtradbinnodb-server-system-variables/index#innodb_encryption_rotate_key_age) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_encryption\_rotation\_iops](../xtradbinnodb-server-system-variables/index#innodb_encryption_rotation_iops) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_encryption\_threads](../xtradbinnodb-server-system-variables/index#innodb_encryption_threads) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_fatal\_semaphore\_wait\_threshold](../xtradbinnodb-server-system-variables/index#innodb_fatal_semaphore_wait_threshold) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [innodb\_force\_primary\_key](../xtradbinnodb-server-system-variables/index#innodb_force_primary_key) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [innodb\_idle\_flush\_pct](../xtradbinnodb-server-system-variables/index#innodb_idle_flush_pct) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [innodb\_immediate\_scrub\_data\_uncompressed](../xtradbinnodb-server-system-variables/index#innodb_immediate_scrub_data_uncompressed) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_instrument\_semaphores](../xtradbinnodb-server-system-variables/index#innodb_instrument_semaphores) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_mtflush\_threads](../xtradbinnodb-server-system-variables/index#innodb_mtflush_threads) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [innodb\_prefix\_index\_cluster\_optimization](../xtradbinnodb-server-system-variables/index#innodb_prefix_index_cluster_optimization) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [innodb\_scrub\_log](../xtradbinnodb-server-system-variables/index#innodb_scrub_log) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [innodb\_scrub\_log\_speed](../xtradbinnodb-server-system-variables/index#innodb_scrub_log_speed) | [MariaDB 10.1.4](https://mariadb.com/kb/en/mariadb-1014-release-notes/) |
| [innodb\_use\_mtflush](../xtradbinnodb-server-system-variables/index#innodb_use_mtflush) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [innodb\_use\_trim](../xtradbinnodb-server-system-variables/index#innodb_use_trim) | [MariaDB 10.1.0](https://mariadb.com/kb/en/mariadb-1010-release-notes/) |
| [log\_bin\_basename](../replication-and-binary-log-server-system-variables/index#log_bin_basename) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [log\_bin\_index](../replication-and-binary-log-server-system-variables/index#log_bin_index) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [log\_tc\_size](../server-system-variables/index#log_tc_size) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [max\_digest\_length](../server-system-variables/index#max_digest_length) | [MariaDB 10.1.5](https://mariadb.com/kb/en/mariadb-1015-release-notes/) |
| [max\_session\_mem\_used](../server-system-variables/index#max_session_mem_used) | [MariaDB 10.1.21](https://mariadb.com/kb/en/mariadb-10121-release-notes/) |
| [max\_statement\_time](../server-system-variables/index#max_statement_time) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [mysql56\_temporal\_format](../server-system-variables/index#mysql56_temporal_format) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [relay\_log\_basename](../replication-and-binary-log-server-system-variables/index#relay_log_basename) | [MariaDB 10.1.6](https://mariadb.com/kb/en/mariadb-1016-release-notes/) |
| [strict\_password\_validation](../server-system-variables/index#strict_password_validation) | [MariaDB 10.1.2](https://mariadb.com/kb/en/mariadb-1012-release-notes/) |
| [skip\_parallel\_replication](../replication-and-binary-log-server-system-variables/index#skip_parallel_replication) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [slave\_parallel\_mode](../replication-and-binary-log-server-system-variables/index#slave_parallel_mode) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [slave\_run\_triggers\_for\_rbr](../replication-and-binary-log-server-system-variables/index#slave_run_triggers_for_rbr) | [MariaDB 10.1.1](https://mariadb.com/kb/en/mariadb-1011-release-notes/) |
| [version\_ssl\_library](../ssl-system-variables/index#version_ssl_library) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |
| [wsrep\_certification\_rules](../galera-cluster-system-variables/index#wsrep_certification_rules) | [MariaDB 10.1.38](https://mariadb.com/kb/en/mariadb-10138-release-notes/) |
| [wsrep\_dirty\_reads](../galera-cluster-system-variables/index#wsrep_dirty_reads) | [MariaDB 10.1.3](https://mariadb.com/kb/en/mariadb-1013-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.1](../status-variables-added-in-mariadb-101/index)
* [System Variables Added in MariaDB 10.2](../system-variables-added-in-mariadb-102/index)
* [System Variables Added in MariaDB 10.0](../system-variables-added-in-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-101/>

About Buildbot
==============

    Overview
--------

 The goal of MariaDB Foundation Buildbot is to ensure that the MariaDB Server is being thoroughly tested on all supported platforms and environments. We are currently running 100 different configurations for the following platforms:

 * x64 and x86
* aarch64
* ppc64le
* s390x

 and operating systems:

 * Debian 9, 10, 11 and Sid
* Ubuntu 16.04, 18.04, 20.04 and 21.04
* Fedora 33 and 34
* CentOS 7 and 8
* RHEL 7 and 8
* SLES 12 and 15
* OpenSUSE 15 and 42
* Windows
* AIX-7.2

 Moreover, we run other ecosystem tests for:

 * PHP
* DBdeployer
* MySqlJS
* PyMySQL

 Packages built by buildbot can be downloaded from [here](https://ci.mariadb.org/).

 What is Buildbot?
-----------------

 The MariaDB Foundation uses Buildbot, a continuous integration and testing framework to test and create MariaDB Server packages. It is hosted on <https://buildbot.mariadb.org/> and ensures that each push to the MariaDB Server GitHub repository is properly tested.

 Who uses Buildbot?
------------------

 Buildbot should be used by each MariaDB developer to ensure that the new changes that are made are properly tested on all supported platforms and environments. In order to enforce this, Buildbot is used for [branch protection](../branch-protection-using-buildbot/index). However, even though branch protection is enabled, **only a selected few** builders are part of it. So, it is the developer's responsibility to monitor all the builders and make sure that everything is fine before making the final push to the main MariaDB branch.

 Buildbot keywords
-----------------

 * Changes/Repository - Any change that occurs in the source code (commit)
* Build Master - The main process that runs on a dedicated machine. It checks for changes in the source code and is in charge of scheduling builds
* Build - The actual configuration that is tested. It consists of a sequence of steps that define the actual test (e.g. get source code, compile, run tests, etc)
* Buildbot Worker - The process which waits for commands from the Build Master in order to run a build

 How does the Buildbot work?
---------------------------

 ![Buildbot overview](https://mariadb.com/kb/en/about-buildbot/+image/buildbot_schematic "Buildbot overview")

 As it comes to the Buildbot Master, we use a multi-master configuration. This means that we have multiple running master processes. So, we have a dedicated master for the user interface and several other that deal with looking for changes and scheduling builds.

 Each time a push is made to the MariaDB Server Repository, it is detected by the buildbot master which schedules all the builds. Each build defines a different test configuration. We mainly use Docker Latent Workers which means that for each build, the master starts a Docker container on a remote machine. The container is configured to run the buildbot-worker process on startup. This process can now receive instructions from the master. In this way, by using latent workers there isn’t a buildbot-worker process continuously running on the worker machine. Instead, for each build a separate container is started.

 Below, you can find a detailed step by step overview of what happens after a push is made to the MariaDB Server repository:

 * Step 1: Detect a new change in the MariaDB Server repository
	+ Trigger source tarball creation
* Step 2: Tarball creation
	+ Clone the repository and create a source tarball corresponding to the latest changes
	+ Trigger bintar builds
* Step 3: Bintar builds
	+ Fetch the source tarball previously created
	+ Compile
	+ Test (mysql-test-run)
	+ Save bintar
	+ Trigger package creation builds
	+ Trigger ecosystem builds
* Step 4.1: Package creation
	+ Fetch source
	+ Create packages
	+ Save packages
	+ Trigger installation builds
* Step 4.2: Ecosystem tests
* Step 5: Installation builds
	+ Fetch packages
	+ Test if they install successfully
	+ Trigger upgrade builds
* Step 6: Upgrade builds
	+ Test if the previously MariaDB Server version can be successfully upgraded to the current one

 
The information below refers to the old Buildbot (<http://buildbot.askmonty.org/>), and not the new Buildbot (<https://buildbot.mariadb.org/>). The information is old, outdated, or otherwise currently incorrect.

  Overview
--------

 The current state of the MariaDB trees with respect to build or test failures is always available from the [Buildbot setup](http://buildbot.askmonty.org/buildbot/) page.

 * [MariaDB-5.5 waterfall status page.](http://buildbot.askmonty.org/buildbot/waterfall?branch=5.5)
* [MariaDB-10.0 waterfall status page.](http://buildbot.askmonty.org/buildbot/waterfall?branch=10.0)
* [MariaDB-10.1 waterfall status page.](http://buildbot.askmonty.org/buildbot/waterfall?branch=10.1)

 The BuildBot setup polls the Launchpad trees every 5 minutes for changes. Whenever a new push is found in one of our trees, the new code is compiled and run through the test suite.

 If all platforms are green after this, everything is good. If not, it means there is a problem with the push, and someone needs to look into it ASAP. If it was your push, then the someone who needs to look at it is you!

 BuildBot is a generic, GPL'ed program providing a continuous integration test framework. For more information on BuildBot, see the [the BuildBot project homepage](http://buildbot.net/trac).

 Volunteering to Run a Build Slave
---------------------------------

 Many of our build hosts are run by [community](../community/index) members, and we are always looking for additional volunteers to help us cover additional platforms or build options in BuildBot.

 If you are able to provide a spare machine for this purpose, your help is greatly appreciated! This is a good way to get involved without having to spend a lot of time on it. Get started by writing an email to 'developers (at) lists.mariadb.org' with an offer to run a BuildBot slave.

 Setting up the Slave BuildBot
-----------------------------

 See [buildbot-setup](../buildbot-setup/index).

 ### Pausing mysql-test-run.pl

 Sometimes you need to work when your computer is busy running tests for buildbot. We've added a new feature to the mysql-test-run.pl script which allows you to stop it temporarily so you can use your computer and then restart the tests when you're ready.

 To do this, define the environment variable "MTR\_STOP\_FILE". Whenever the file specified by this environment variable exists, the mysql-test-run.pl script will stop as soon as it is able to do so (i.e. it won't stop immediately). When the file is removed, the mysql-test-run.pl script will continue from where it left off.

 If you plan on using this feature you should also set the "MTR\_STOP\_KEEP\_ALIVE" environment variable with a value of 120. This will make the script print messages to buildbot every 2 minutes which will prevent a timeout.

 Database with Test Results
--------------------------

 Buildbot saves the results of test runs in a database, to be used for enhanced reporting on web pages without need to change the Buildbot code, and for data mining when investigating test failures.

 The database schema is documented under [Buildbot Database Schema](../buildbot_database_schema/index). The schema is likely to evolve as we gradually add more kinds of information.

 For now, the data is not externally available. But the plan is to set up a slave database to replicate the data, and provide access (eg. remote database accounts) to members of the community with interesting ideas about how to present or mine this data, or who are just curious to play with it. If anyone has an interest in this, or wants to volunteer a slave host for this purpose, please send a mail to [developers@lists.mariadb.org](mailto:developers@lists.mariadb.org). The more people show interest in this, the faster it is likely to happen!

 Reports
-------

 We are developing new reports fed off the test results in the database. These reports will be located [here](http://buildbot.askmonty.org/buildbot/reports/). The first report is the [Cross Reference](http://buildbot.askmonty.org/buildbot/reports/cross_reference) report. This report allows all test failures to be searched.

 Buildbot Maintenance
--------------------

 Here is some information on how our Buildbot installation is set up and maintained:

 * The configuration file is included in the [Tools for MariaDB](https://github.com/MariaDB/mariadb.org-tools) repository.
* The building and testing of binary packages is documented on the [package-testing-with-buildbot-and-kvm](../package-testing-with-buildbot-and-kvm/index) page.
* We developed a small tool, [runvm](../buildbot_runvm/index), which is used to do some of the builds inside a virtual machine, mostly to test builds of binary packages.
* The [BuildBot Development](../buildbot_development/index) page describes how we developed some of the enhancements to BuildBot that we use and have contributed upstream.

 See Also
--------

 * The [Buildbot ToDo](../buildbot-todo/index) page

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-buildbot/>

Merging with a Merge Tree
=========================

    If you have a [merge tree](../creating-a-new-merge-tree/index), you merge into MariaDB as follows:

 1. MariaDB merge trees are in the [mergetrees](https://github.com/MariaDB/mergetrees) repository. Add it as a new remote: 
```
git remote add merge https://github.com/MariaDB/mergetrees
```
2. Check out the branch you want to update and merge, for example: 
```
git checkout merge-innodb-5.6
```
3. delete everything in the branch
4. download the latest released source tarball, unpack it, copy files into the repository:
	* for **InnoDB-5.6**: use the content of the `storage/innobase/` of the latest MySQL 5.6 source release tarball.
	* for **performance schema 5.6**: use `storage/perfschema`, `include/mysql/psi`, `mysql-test/suite/perfschema`, and `mysql-test/suite/perfschema_stress` from the latest MySQL 5.6 source release tarball.
	* for **SphinxSE**: use `mysqlse/` subdirectory from the latest Sphinx source release tarball.
	* for **XtraDB**: use the content of the `storage/innobase/` of the latest Percona-Server source release tarball (5.5 or 5.6 as appropriate).
	* for **pcre**: simply unpack the latest pcre release source tarball into the repository, rename `pcre-X-XX/` to `pcre`.
5. Now `git add .`, `git commit` (use the tarball version as a comment), `git push`
6. merge this branch into MariaDB
7. Sometimes after a merge, some changes may be needed:
	* for **performance schema 5.6**: update `storage/perfschema/ha_perfschema.cc`, plugin version under `maria_declare_plugin`.
	* for **InnoDB-5.6**: update `storage/innobase/include/univ.i`, setting `INNODB_VERSION_MAJOR`, `INNODB_VERSION_MINOR`, `INNODB_VERSION_BUGFIX` to whatever MySQL version you were merging from.
	* for **XtraDB-5.5**: update `storage/xtradb/include/univ.i`, setting `PERCONA_INNODB_VERSION`, `INNODB_VERSION_STR` to whatever Percona-Server version you were merging from.
	* for **XtraDB-5.6**: update `storage/xtradb/include/univ.i`, setting `PERCONA_INNODB_VERSION`, `INNODB_VERSION_MAJOR`, `INNODB_VERSION_MINOR`, `INNODB_VERSION_BUGFIX` to whatever Percona-Server version you were merging from.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/merging-with-a-merge-tree/>

Creating a New Merge Tree
=========================

    
This article is obsolete. We don't use bzr anymore. This howto needs to be rewritten to explain how to create a merge tree in git.

 
**Merge tree** in the context of this HOWTO is a tree created specifically to simplify merges of third-party packages into MariaDB. WIth a merge tree there's a clear separation between upstream changes and our changes and in most cases bzr can do the merges automatically.

 Here's how I created a merge tree for pcre:

 * prerequisites: we already have pcre in the MariaDB tree, together with our changes (otherwise one can trivially create a bzr repository out of source pcre tarball).
* create an empty repository:

 
```
mkdir pcre
cd pcre
bzr init

```

* download pcre source tarball of the same version that we have in the tree — `pcre-8.34.tar.bz2`
* unpack it in the same place where the files are in the source tree:

 
```
tar xf ~/pcre-8.34.tar.bz2
mv pcre-8.34 pcre

```

* Add files to the repository **with the same file-ids as in the MariaDB tree!**

 
```
bzr add --file-ids-from ~/Abk/mysql/10.0

```

* All done. Commit and push

 
```
bzr commit -m pcre-8.34
bzr push --remember lp:~maria-captains/maria/pcre-mergetree

```

* Now null-merge that into your MariaDB tree. Note, that for the initial merge you need to specify the revision range `0..1`

 
```
cd ~/Abk/mysql/10.0
bzr merge -r 0..1 ~/mergetrees/pcre/

```

* Remove pcre files that shouldn't be in MariaDB tree, revert all changes that came from pcre (remember — it's a null-merge, pcre-8.34 is already in MariaDB tree), rename files in place as needed, resolve conflicts:

 
```
bzr rm `bzr added`
bzr revert --no-backup `bzr modified`
bzr resolve pcre

```

* Verify that the tree is unchanged and commit:

 
```
bzr status
bzr commit -m 'pcre-8.34 mergetree initial merge'

```

* Congratulations, your new merge tree is ready!

 Now see [Merging with a merge tree](../merging-with-a-merge-tree/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/creating-a-new-merge-tree/>

Merging from MySQL (obsolete)
=============================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Merging from MySQL into MariaDB
-------------------------------

 ### Merging code changes from MySQL bzr repository

 We generally merge only released versions of MySQL into MariaDB trunk. This is to be able to release a well-working release of MariaDB at any time, without having to worry about including half-finished changes from MySQL. Merges of MySQL revisions in-between MySQL releases can still be done (eg. to reduce the merge task to smaller pieces), but should then be pushed to the maria-5.1-merge branch, not to the main lp:maria branch.

 The merge command should thus generally be of this form:

 
```
bzr merge -rtag:mysql-<MYSQL-VERSION> lp:mysql-server/5.1

```

As a general rule, when the MySQL and MariaDB side has changes with the same meaning but differing text, pick the MySQL variant when resolving this conflict. This will help reduce the number of conflicts in subsequent merges.

 ### Buildbot testing

 To assist in understanding test failures that arise during the merge, we pull the same revision to be merged into the lp:maria-captains/maria/mysql-5.1-testing tree for buildbot test. This allows to check easily if any failures introduced are also present in the vanilla MySQL tree being merged.

 ### Helpful tags and diffs

 To help keep track of merges, we tag the result of a merge:

 
```
mariadb-merge-mysql-<MYSQL-VERSION>

```

For example, when merging MySQL 5.1.39, the commit of the merge would be tagged like this:

 
```
mariadb-merge-mysql-5.1.39

```

The right-hand parent of tag:mariadb-merge-mysql-5.1.39 will be the revision tag:mysql-5.1.39. The left-hand parent will be a revision on the MariaDB trunk.

 When merging, these tags and associated revisions can be used to generate some diffs, which are useful when resolving conflicts. Here is a diagram of the history in a merge:

 
```
B----maria------A0-------A1
 \              /       /
  \            /       /
   ---mysql---Y0------Y1

```

Here,

 * `'B'` is the base revision when MariaDB was originally branched from MySQL.
* `'A0'` is the result of the last MySQL merge, eg. `tag:mariadb-merge-mysql-5.1.38`.
* `'Y0'` is the MySQL revision that was last merged, eg. `tag:mysql-5.1.38`.
* `'Y1'` is the MySQL revision to be merged in the new merge, eg. `tag:mysql-5.1.39`.
* `'A1'` is the result of committing the new merge, to be tagged as eg. `tag:mariadb-merge-mysql-5.1.39`.

 Then, these diffs can be useful:

 * `'bzr diff -rY0..before:A1'` - this is the MariaDB side of changes to be merged.
* `'bzr diff -rY0..Y1'` - this is the MySQL side of changes to be merged.
* `'bzr diff -rA0..before:A1'` - these are the new changes on the MariaDB side to be merged; this can be useful do separate them from other MariaDB-specific changes that have already been resolved against conflicting MySQL changes.

 ### Merging documentation from MySQL source tarballs

 The documentation for MySQL is not maintained in the MySQL source bzr repository. Therefore changes to MySQL documentation needs to be merged separately.

 Only some of the MySQL documentation is available under the GPL (man pages, help tables, installation instructions). Notably the MySQL manual is not available under the GPL, and so is not included in MariaDB in any form.

 The man pages, help tables, and installation instruction READMEs are obtained from MySQL source tarballs and manually merged into the MariaDB source trees. The procedure for this is as follows:

 There is a tree on Launchpad used for tracking merges:

 
```
lp:~maria-captains/maria/mysql-docs-merge-base

```

(At the time of writing, this procedure only exists for the 5.1 series of MySQL and MariaDB. Additional merge base trees will be needed for other release series.)

 This tree must **only** be used to import new documentation files from new MySQL upstream source tarballs. The procedure to import a new set of files when a new MySQL release happens is as follows:

 * Download the new MySQL source tarball and unpack it, say to mysql-5.1.38
* run these commands:

 
```
T=../mysql-5.1.38
bzr branch lp:~maria-captains/maria/mysql-docs-merge-base
cd mysql-docs-merge-base
for i in Docs/INSTALL-BINARY INSTALL-SOURCE INSTALL-WIN-SOURCE support-files/MacOSX/ReadMe.txt scripts/fill_help_tables.sql $(cd "$T" && find man -type f | grep '\.[0-9]$' | grep -v '^man/ndb_' | grep -v '^man/mysqlman.1$') ; do cp "$T/$i" $i; bzr add $i ; done
bzr commit -m"Imported MySQL documentation files from $T"
bzr push lp:~maria-captains/maria/mysql-docs-merge-base

```

* Now do a normal merge from `lp:maria-captains/maria/mysql-docs-merge-base` into `lp:maria`

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/merging-from-mysql-obsolete/>

Merging TokuDB (obsolete)
=========================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  We merge TokuDB from Tokutek **git** repositories on GutHub:

 * <https://github.com/Tokutek/tokudb-engine>
* <https://github.com/Tokutek/ft-index>

 Just merge normally at release points (use tag names) and don't forget to update `storage/tokudb/CMakeLists.txt`, setting `TOKUDB_VERSION` correctly.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/merging-tokudb-obsolete/>

Merging New XtraDB Releases (obsolete)
======================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  ### Background

 Percona used to maintain XtraDB as a patch series against the InnoDB plugin. This affected how we started merging XtraDB in.

 Now Percona maintains a normal source repository on launchpad (`lp:percona-server`). But we continue to merge the old way to preserve the history of our changes.

 ### Merging

 There used to be a `lp:percona-xtradb` tree, that we were merging from as:

 
```
bzr merge lp:percona-xtradb

```

Now we have to maintain our own XtraDB-5.5 repository to merge from. It is `lp:~maria-captains/maria/xtradb-mergetree-5.5`. Follow the procedures as described in [Merging with a merge tree](../merging-with-a-merge-tree/index) to merge from it.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/merging-new-xtradb-releases-obsolete/>

About Non-blocking Operation in the Client Library
==================================================

    MariaDB, starting with version 5.5.21 supports *non-blocking* operations in the client-library. This allows an application to start a query or other operation against the database, and then continue to do other work (in the same thread) while the request is sent over the network, the query is processed in the server, and the result travels back. As parts of the result become ready, the application can — at its leisure — call back into the library to continue processing, repeating this until the operation is completed.

 Non-blocking operation is implemented entirely within the client library. This means no special server support is necessary and non-blocking operation works with any version of the MariaDB or MySQL server, the same as the normal blocking API. It also means that it is not possible to have two queries running at the same time on the same connection (this is a protocol limitation). But a single thread can have any number of non-blocking queries running at the same time, each using its own MYSQL connection object.

 Non-blocking operation is useful when an application needs to run a number of independent queries in parallel at the same time, to speed up operation compared to running them sequentially one after the other. This could be multiple queries against a single server (to better utilize multiple CPU cores and/or a high-capacity I/O system on the server), or it could be queries against multiple servers (e.g. `[SHOW STATUS](../show-status/index)` against all running servers for monitoring, or a map/reduce-like operation against a big sharded database).

 Non-blocking operation is also very useful in applications that are already written in a non-blocking style, for example using a framework like [libevent](http://libevent.org/), or, for example, a GUI-application using an event loop. Using the non-blocking client library allows the integrations of database queries into such applications, without the risk of long-running queries "hanging" the user interface or stalling the event loop, and without having to manually spawn separate threads to run the queries and re-synchronize with the threads to get the results back.

 In this context, "blocking" means the situation where communication on the network socket to the server has to wait while processing the query. Waiting can be necessary because the server has not yet had time to process the query, or because the data needs to travel over the network from the server, or even because the first part of a large request needs to be sent out on the network before local socket buffers can accept the last part. Whenever such a wait is necessary, control returns to the application. The application will then run `select()` or `poll()` (or something similar) to detect when any wait condition is satisfied, and then call back into the library to continue processing.

 An example program is available in the MariaDB source tree:

 
```
tests/async_queries.c

```

It uses `libevent` to run a set of queries in parallel from within a single thread / event loop. This is a good example of how to integrate non-blocking query processing into an event-based framework.

 The non-blocking API in the client library is entirely optional. The new library is completely ABI- and source-compatible with existing applications. Also, applications not using non-blocking operations are not affected, nor is there any significant performance penalty for having support for non-blocking operations in the library for applications which do not use them.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/about-non-blocking-operation-in-the-client-library/>

System Variables Added in MariaDB 10.0
======================================

    This is a list of [system variables](../server-system-variables/index) that were added in the [MariaDB 10.0](../what-is-mariadb-100/index) series.

 The list excludes the following variables, related to storage engines and plugins included in [MariaDB 10.0](../what-is-mariadb-100/index):

 * [Connect System Variables](../connect-system-variables/index)
* [Galera System Variables](../galera-cluster-system-variables/index)
* [Mroonga System Variables](../mroonga-system-variables/index)
* [Query Response Time Plugin Variables](../query_response_time-plugin/index)
* [Spider System Variables](../spider-server-system-variables/index)

 


| Variable | Added |
| --- | --- |
| [aria\_pagecache\_file\_hash\_size](../aria-system-variables/index#aria_pagecache_file_hash_size) | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| [binlog\_commit\_wait\_count](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_count) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [binlog\_commit\_wait\_usec](../replication-and-binary-log-server-system-variables/index#binlog_commit_wait_usec) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [default\_master\_connection](../replication-and-binary-log-server-system-variables/index#default_master_connection) | [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) |
| [default\_regex\_flags](../server-system-variables/index#default_regex_flags) | [MariaDB 10.0.11](https://mariadb.com/kb/en/mariadb-10011-release-notes/) |
| [gtid\_binlog\_pos](../global-transaction-id/index#gtid_binlog_pos) | [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/) |
| [gtid\_binlog\_state](../global-transaction-id/index#gtid_binlog_state) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [gtid\_current\_pos](../global-transaction-id/index#gtid_current_pos) | [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/) |
| [gtid\_domain\_id](../global-transaction-id/index#gtid_domain_id) | [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) |
| [gtid\_ignore\_duplicates](../global-transaction-id/index#gtid_ignore_duplicates) | [MariaDB 10.0.10](https://mariadb.com/kb/en/mariadb-10010-release-notes/) |
| [gtid\_seq\_no](../global-transaction-id/index#gtid_seq_no) | [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) |
| [gtid\_slave\_pos](../global-transaction-id/index#gtid_slave_pos) | [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/) |
| [gtid\_strict\_mode](../global-transaction-id/index#gtid_strict_mode) | [MariaDB 10.0.3](https://mariadb.com/kb/en/mariadb-1003-release-notes/) |
| [histogram\_size](../server-system-variables/index#histogram_size) | [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) |
| [histogram\_type](../server-system-variables/index#histogram_type) | [MariaDB 10.0.2](https://mariadb.com/kb/en/mariadb-1002-release-notes/) |
| [innodb\_adaptive\_flushing\_lwm](../xtradbinnodb-server-system-variables/index#innodb_adaptive_flushing_lwm) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_adaptive\_max\_sleep\_delay](../xtradbinnodb-server-system-variables/index#innodb_adaptive_max_sleep_delay) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_api\_bk\_commit\_interval](../xtradbinnodb-server-system-variables/index#innodb_api_bk_commit_interval) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_api\_disable\_rowlock](../xtradbinnodb-server-system-variables/index#innodb_api_disable_rowlock) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_api\_enable\_binlog](../xtradbinnodb-server-system-variables/index#innodb_api_enable_binlog) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_api\_enable\_mdl](../xtradbinnodb-server-system-variables/index#innodb_api_enable_mdl) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_api\_trx\_level](../xtradbinnodb-server-system-variables/index#innodb_api_trx_level) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_dump\_at\_shutdown](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_dump_at_shutdown) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_dump\_now](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_dump_now) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_filename](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_filename) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_load\_abort](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_load_abort) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_load\_at\_startup](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_load_at_startup) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_buffer\_pool\_load\_now](../xtradbinnodb-server-system-variables/index#innodb_buffer_pool_load_now) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_change\_buffer\_max\_size](../xtradbinnodb-server-system-variables/index#innodb_change_buffer_max_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_checksum\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_checksum_algorithm) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_cleaner\_lsn\_age\_factor](../xtradbinnodb-server-system-variables/index#innodb_cleaner_lsn_age_factor) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_cmp\_per\_index\_enabled](../xtradbinnodb-server-system-variables/index#innodb_cmp_per_index_enabled) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_compression\_failure\_threshold\_pct](../xtradbinnodb-server-system-variables/index#innodb_compression_failure_threshold_pct) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_compression\_level](../xtradbinnodb-server-system-variables/index#innodb_compression_level) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_compression\_pad\_pct\_max](../xtradbinnodb-server-system-variables/index#innodb_compression_pad_pct_max) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_disable\_sort\_file\_cache](../xtradbinnodb-server-system-variables/index#innodb_disable_sort_file_cachex) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_empty\_free\_list\_algorithm](../xtradbinnodb-server-system-variables/index#innodb_empty_free_list_algorithm) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_flush\_neighbors](../xtradbinnodb-server-system-variables/index#innodb_flush_neighbors) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_foreground\_preflush](../xtradbinnodb-server-system-variables/index#innodb_foreground_preflush) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_ft\_aux\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_aux_table) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_cache\_size](../xtradbinnodb-server-system-variables/index#innodb_ft_cache_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_enable\_diag\_print](../xtradbinnodb-server-system-variables/index#innodb_ft_enable_diag_print) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_enable\_stopword](../xtradbinnodb-server-system-variables/index#innodb_ft_enable_stopword) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_max\_token\_size](../xtradbinnodb-server-system-variables/index#innodb_ft_max_token_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_min\_token\_size](../xtradbinnodb-server-system-variables/index#innodb_ft_min_token_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_num\_word\_optimize](../xtradbinnodb-server-system-variables/index#innodb_ft_num_word_optimize) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_result\_cache\_limit](../xtradbinnodb-server-system-variables/index#innodb_ft_result_cache_limit) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_ft\_server\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_server_stopword_table) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_sort\_pll\_degree](../xtradbinnodb-server-system-variables/index#innodb_ft_sort_pll_degree) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_ft\_total\_cache\_size](../xtradbinnodb-server-system-variables/index#innodb_ft_total_cache_size) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_ft\_user\_stopword\_table](../xtradbinnodb-server-system-variables/index#innodb_ft_user_stopword_table) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_io\_capacity\_max](../xtradbinnodb-server-system-variables/index#innodb_io_capacity_max) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_log\_arch\_dir](../xtradbinnodb-server-system-variables/index#innodb_log_arch_dir) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_log\_arch\_expire\_sec](../xtradbinnodb-server-system-variables/index#innodb_log_arch_expire_sec) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_log\_archive](../xtradbinnodb-server-system-variables/index#innodb_log_archive) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_log\_compressed\_pages](../xtradbinnodb-server-system-variables/index#innodb_log_compressed_pages) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_max\_dirty\_pages\_pct\_lwm](../xtradbinnodb-server-system-variables/index#innodb_max_dirty_pages_pct_lwm) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_max\_purge\_lag\_delay](../xtradbinnodb-server-system-variables/index#innodb_max_purge_lag_delay) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_monitor\_disable](../xtradbinnodb-server-system-variables/index#innodb_monitor_disable) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_monitor\_enable](../xtradbinnodb-server-system-variables/index#innodb_monitor_enable) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_monitor\_reset](../xtradbinnodb-server-system-variables/index#innodb_monitor_reset) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_monitor\_reset\_all](../xtradbinnodb-server-system-variables/index#innodb_monitor_reset_all) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_online\_alter\_log\_max\_size](../xtradbinnodb-server-system-variables/index#innodb_online_alter_log_max_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_optimize\_fulltext\_only](../xtradbinnodb-server-system-variables/index#innodb_optimize_fulltext_only) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_random\_read\_ahead](../xtradbinnodb-server-system-variables/index#innodb_random_read_ahead) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_read\_only](../xtradbinnodb-server-system-variables/index#innodb_read_only) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_recovery\_stats](../xtradbinnodb-server-system-variables/index#innodb_recovery_stats) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_sched\_priority\_cleaner](../xtradbinnodb-server-system-variables/index#innodb_sched_priority_cleaner) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [innodb\_simulate\_comp\_failures](../xtradbinnodb-server-system-variables/index#innodb_simulate_comp_failures) | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) |
| [innodb\_sort\_buffer\_size](../xtradbinnodb-server-system-variables/index#innodb_sort_buffer_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_stats\_auto\_recalc](../xtradbinnodb-server-system-variables/index#innodb_stats_auto_recalc) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_stats\_modified\_counter](../xtradbinnodb-server-system-variables/index#innodb_stats_modified_counter) | [MariaDB 10.0.15](https://mariadb.com/kb/en/mariadb-10015-release-notes/) |
| [innodb\_stats\_persistent](../xtradbinnodb-server-system-variables/index#innodb_stats_persistent) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_stats\_persistent\_sample\_pages](../xtradbinnodb-server-system-variables/index#innodb_stats_persistent_sample_pages) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_stats\_traditional](../xtradbinnodb-server-system-variables/index#innodb_stats_traditional) | [MariaDB 10.0.16](https://mariadb.com/kb/en/mariadb-10016-release-notes/) |
| [innodb\_stats\_transient\_sample\_pages](../xtradbinnodb-server-system-variables/index#innodb_stats_transient_sample_pages) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_status\_output](../xtradbinnodb-server-system-variables/index#innodb_status_output) | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) |
| [innodb\_status\_output\_locks](../xtradbinnodb-server-system-variables/index#innodb_status_output_locks) | [MariaDB 10.0.14](https://mariadb.com/kb/en/mariadb-10014-release-notes/) |
| [innodb\_sync\_array\_size](../xtradbinnodb-server-system-variables/index#innodb_sync_array_size) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_undo\_directory](../xtradbinnodb-server-system-variables/index#innodb_undo_directory) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_undo\_logs](../xtradbinnodb-server-system-variables/index#innodb_undo_logs) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [innodb\_undo\_tablespaces](../xtradbinnodb-server-system-variables/index#innodb_undo_tablespaces) | [MariaDB 10.0](../what-is-mariadb-100/index) |
| [key\_cache\_file\_hash\_size](../myisam-system-variables/index#key_cache_file_hash_size) | [MariaDB 10.0.13](https://mariadb.com/kb/en/mariadb-10013-release-notes/) |
| [last\_gtid](../global-transaction-id/index#last_gtid) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [oqgraph\_allow\_create\_integer\_latch](../server-system-variables/index#oqgraph_allow_create_integer_latch) | [MariaDB 10.0.7](https://mariadb.com/kb/en/mariadb-1007-release-notes/) |
| [performance\_schema\_accounts\_size](../performance-schema-system-variables/index#performance_schema_accounts_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_digests\_size](../performance-schema-system-variables/index#performance_schema_digests_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_events\_stages\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_long_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_events\_stages\_history\_size](../performance-schema-system-variables/index#performance_schema_events_stages_history_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_events\_statements\_history\_long\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_long_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_events\_statements\_history\_size](../performance-schema-system-variables/index#performance_schema_events_statements_history_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_hosts\_size](../performance-schema-system-variables/index#performance_schema_hosts_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_max\_digest\_length](../performance-schema-system-variables/index#performance_schema_max_digest_length) | [MariaDB 10.0.21](https://mariadb.com/kb/en/mariadb-10021-release-notes/) |
| [performance\_schema\_max\_socket\_classes](../performance-schema-system-variables/index#performance_schema_max_socket_classes) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_max\_socket\_instances](../performance-schema-system-variables/index#performance_schema_max_socket_instances) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_max\_stage\_classes](../performance-schema-system-variables/index#performance_schema_max_stage_classes) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_max\_statement\_classes](../performance-schema-system-variables/index#performance_schema_max_statement_classes) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_session\_connect\_attrs\_size](../performance-schema-system-variables/index#performance_schema_session_connect_attrs_size) | [MariaDB 10.0.4](https://mariadb.com/kb/en/mariadb-1004-release-notes/) |
| [performance\_schema\_setup\_actors\_size](../performance-schema-system-variables/index#performance_schema_setup_actors_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_setup\_objects\_size](../performance-schema-system-variables/index#performance_schema_setup_objects_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [performance\_schema\_users\_size](../performance-schema-system-variables/index#performance_schema_users_size) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [slave\_ddl\_exec\_mode](../replication-and-binary-log-server-system-variables/index#slave_ddl_exec_mode) | [MariaDB 10.0.8](https://mariadb.com/kb/en/mariadb-1008-release-notes/) |
| [slave\_domain\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_domain_parallel_threads) | [MariaDB 10.0.9](https://mariadb.com/kb/en/mariadb-1009-release-notes/) |
| [slave\_parallel\_max\_queued](../replication-and-binary-log-server-system-variables/index#slave_parallel_max_queued) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [slave\_parallel\_threads](../replication-and-binary-log-server-system-variables/index#slave_parallel_threads) | [MariaDB 10.0.5](https://mariadb.com/kb/en/mariadb-1005-release-notes/) |
| [ssl\_crl](../ssl-system-variables/index#ssl_crl) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [ssl\_crlpath](../ssl-system-variables/index#ssl_crlpath) | [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/) |
| [use\_stat\_tables](../server-system-variables/index#use_stat_tables) | [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) |
| [version\_malloc\_library](../server-system-variables/index#version_malloc_library) | [MariaDB 10.0.1](https://mariadb.com/kb/en/mariadb-1001-release-notes/) |

 
See Also
--------

 * [Status Variables Added in MariaDB 10.0](../status-variables-added-in-mariadb-100/index)
* [System Variables Added in MariaDB 10.1](../system-variables-added-in-mariadb-101/index)
* [Upgrading from MariaDB 5.5 to MariaDB 10.0](../upgrading-from-mariadb-55-to-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/system-variables-added-in-mariadb-100/>

Using the Non-blocking Library
==============================

    The MariaDB non-blocking client API is modelled after the normal blocking library calls. This makes it easy to learn and remember. It makes it easier to translate code from using the blocking API to using the non-blocking API (or vice versa). And it also makes it simple to mix blocking and non-blocking calls in the same code path.

 For every library call that may block on socket I/O, such as '`int mysql_real_query(MYSQL, query, query_length)`', two additional non-blocking calls are introduced:

 
```
int mysql_real_query_start(&status, MYSQL, query, query_length)
int mysql_real_query_cont(&status, MYSQL, wait_status)

```

To do non-blocking operation, an application first calls `mysql_real_query_start()` instead of `mysql_real_query()`, passing the same parameters.

 If `mysql_real_query_start()` returns zero, then the operation completed without blocking, and 'status' is set to the value that would normally be returned from `mysql_real_query()`.

 Else, the return value from `mysql_real_query_start()` is a bitmask of events that the library is waiting on. This can be `MYSQL_WAIT_READ`, `MYSQL_WAIT_WRITE`, or `MYSQL_WAIT_EXCEPT`, corresponding to the similar flags for `select()` or `poll()`; and it can include `MYSQL_WAIT_TIMEOUT` when waiting for a timeout to occur (e.g. a connection timeout).

 In this case, the application continues other processing and eventually checks for the appropriate condition(s) to occur on the socket (or for timeout). When this occurs, the application can resume the operation by calling `mysql_real_query_cont()`, passing in 'wait\_status' a bitmask of the events which actually occurred.

 Just like `mysql_real_query_start()`, `mysql_real_query_cont()` returns zero when done, or a bitmask of events it needs to wait on. Thus the application continues to repeatedly call `mysql_real_query_cont()`, intermixed with other processing of its choice; until zero is returned, after which the result of the operation is stored in 'status'.

 Some calls, like `mysql_option()`, do not do any socket I/O, and so can never block. For these, there are no separate `_start()` or `_cont()` calls. See the "[Non-blocking API reference](../non-blocking-api-reference/index)" page for a full list of what functions can and can not block.

 The checking for events on the socket / timeout can be done with `select()` or `poll()` or a similar mechanism. Though often it will be done using a higher-level framework (such as libevent), which supplies facilities for registering and acting on such conditions.

 The descriptor of the socket on which to check for events can be obtained by calling `mysql_get_socket()`. The duration of any timeout can be obtained from `mysql_get_timeout_value()`.

 Here is a trivial (but full) example of running a query with the non-blocking API. The example is found in the MariaDB source tree as `client/async_example.c`. (A larger, more realistic example using libevent is found as `tests/async_queries.c` in the source):

 
```
static void run_query(const char *host, const char *user, const char *password) {
  int err, status;
  MYSQL mysql, *ret;
  MYSQL_RES *res;
  MYSQL_ROW row;

  mysql_init(&mysql);
  mysql_options(&mysql, MYSQL_OPT_NONBLOCK, 0);

  status = mysql_real_connect_start(&ret, &mysql, host, user, password, NULL, 0, NULL, 0);
  while (status) {
    status = wait_for_mysql(&mysql, status);
    status = mysql_real_connect_cont(&ret, &mysql, status);
  }

  if (!ret)
    fatal(&mysql, "Failed to mysql_real_connect()");

  status = mysql_real_query_start(&err, &mysql, SL("SHOW STATUS"));
  while (status) {
    status = wait_for_mysql(&mysql, status);
    status = mysql_real_query_cont(&err, &mysql, status);
  }
  if (err)
    fatal(&mysql, "mysql_real_query() returns error");

  /* This method cannot block. */
  res= mysql_use_result(&mysql);
  if (!res)
    fatal(&mysql, "mysql_use_result() returns error");

  for (;;) {
    status= mysql_fetch_row_start(&row, res);
    while (status) {
      status= wait_for_mysql(&mysql, status);
      status= mysql_fetch_row_cont(&row, res, status);
    }
    if (!row)
      break;
    printf("%s: %s\n", row[0], row[1]);
  }
  if (mysql_errno(&mysql))
    fatal(&mysql, "Got error while retrieving rows");
  mysql_free_result(res);
  mysql_close(&mysql);
}

/* Helper function to do the waiting for events on the socket. */
static int wait_for_mysql(MYSQL *mysql, int status) {
  struct pollfd pfd;
  int timeout, res;

  pfd.fd = mysql_get_socket(mysql);
  pfd.events =
    (status & MYSQL_WAIT_READ ? POLLIN : 0) |
    (status & MYSQL_WAIT_WRITE ? POLLOUT : 0) |
    (status & MYSQL_WAIT_EXCEPT ? POLLPRI : 0);
  if (status & MYSQL_WAIT_TIMEOUT)
    timeout = 1000*mysql_get_timeout_value(mysql);
  else
    timeout = -1;
  res = poll(&pfd, 1, timeout);
  if (res == 0)
    return MYSQL_WAIT_TIMEOUT;
  else if (res < 0)
    return MYSQL_WAIT_TIMEOUT;
  else {
    int status = 0;
    if (pfd.revents & POLLIN) status |= MYSQL_WAIT_READ;
    if (pfd.revents & POLLOUT) status |= MYSQL_WAIT_WRITE;
    if (pfd.revents & POLLPRI) status |= MYSQL_WAIT_EXCEPT;
    return status;
  }
}

```

Setting MYSQL\_OPT\_NONBLOCK
----------------------------

 Before using any non-blocking operation, it is necessary to enable it first by setting the `MYSQL_OPT_NONBLOCK` option:

 
```
mysql_options(&mysql, MYSQL_OPT_NONBLOCK, 0);

```

This call can be made at any time — typically it will be done at the start, before `mysql_real_connect()`, but it can be done at any time to start using non-blocking operations.

 If a non-blocking operation is attempted without setting the `MYSQL_OPT_NONBLOCK` option, the program will typically crash with a `NULL` pointer exception.

 The argument for `MYSQL_OPT_NONBLOCK` is the size of the stack used to save the state of a non-blocking operation while it is waiting for I/O and the application is doing other processing. Normally, applications will not have to change this, and it can be passed as zero to use the default value.

 Mixing blocking and non-blocking operation
------------------------------------------

 It is possible to freely mix blocking and non-blocking calls on the same `MYSQL` connection.

 Thus, an application can do a normal blocking `mysql_real_connect()` and subsequently do a non-blocking `mysql_real_query_start()`. Or vice versa, do a non-blocking `mysql_real_connect_start()`, and later do a blocking `mysql_real_query()` on the resulting connection.

 Mixing can be useful to allow code to use the simpler blocking API in parts of the program where waiting is not a problem. For example establishing the connection(s) at program startup, or doing small quick queries between large, long-running ones.

 The only restriction is that any previous non-blocking operation must have finished before starting a new blocking (or non-blocking) operation, see the next section: "Terminating a non-blocking operation early" below.

 Terminating a non-blocking operation early
------------------------------------------

 When a non-blocking operation is started with `mysql_real_query_start()` or another `_start()` function, it must be allowed to finish before starting a new operation. Thus, the application must continue calling `mysql_real_query_cont()` until zero is returned, indicating that the operation is completed. It is not allowed to leave one operation "hanging" in the middle of processing and then start a new one on top of it.

 It is, however, permissible to terminate the connection completely with `mysql_close()` in the middle of processing a non-blocking call. A new connection must then be initiated with `mysql_real_connect` before new queries can be run, either with a new `MYSQL` object or re-using the old one.

 In the future, we may implement an abort facility to force an on-going operation to terminate as quickly as possible (but it will still be necessary to call `mysql_real_query_cont()` one last time after abort, allowing it to clean up the operation and return immediately with an appropriate error code).

 Restrictions
------------

 ### DNS

 When `mysql_real_connect_start()` is passed a hostname (as opposed to a local unix socket or an IP address, it may need to look up the hostname in DNS, depending on local host configuration (e.g. if the name is not in `/etc/hosts` or cached). Such DNS lookups do **not** happen in a non-blocking way. This means that `mysql_real_connect_start()` will not return control to the application while waiting for the DNS response. Thus the application may "hang" for some time if DNS is slow or non-functional.

 If this is a problem, the application can pass an IP address to `mysql_real_connect_start()` instead of a hostname, which avoids the problem. The IP address can be obtained by the application with whatever non-blocking DNS loopup operation is available to it from the operating system or event framework used. Alternatively, a simple solution may be to just add the hostname to the local host lookup file (`/etc/hosts` on Posix/Unix/Linux machines).

 ### Windows Named Pipes and Shared Memory connections

 There is no support in the non-blocking API for connections using Windows named pipes or shared memory

 Named pipes and shared memory can still be used, using either the blocking or the non-blocking API. However, operations that need to wait on I/O on the named pipe will not return control to the application; instead they will "hang" waiting for the operation to complete, just like the normal blocking API calls.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/using-the-non-blocking-library/>

table\_exists
=============

    Syntax
------

 
```
table_exists(in_db_name,in_table_name, out_table_type)

# in_db_name VARCHAR(64)
# in_table_name VARCHAR(64)
# out_table_type ENUM('', 'BASE TABLE', 'VIEW', 'TEMPORARY')

```

Description
-----------

 `table_exists` is a [stored procedure](../stored-procedures/index) available with the [Sys Schema](../sys-schema/index).

 Given a database *in\_db\_name* and table name *in\_table\_name*, returns the table type in the OUT parameter *out\_table\_type*. The return value is an ENUM field containing one of:

 * '' - the table does not exist
* 'BASE TABLE' - a regular table
* 'VIEW' - a view
* 'TEMPORARY' - a temporary table

 Examples
--------

 
```
CALL sys.table_exists('mysql', 'time_zone', @table_type); SELECT @table_type;
+-------------+
| @table_type |
+-------------+
| BASE TABLE  |
+-------------+

CALL sys.table_exists('mysql', 'user', @table_type); SELECT @table_type;
+-------------+
| @table_type |
+-------------+
| VIEW        |
+-------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/table_exists/>

statement\_performance\_analyzer
================================

    Syntax
------

 
```
statement_performance_analyzer(in_action,in_table, in_views)

# in_action ENUM('snapshot', 'overall', 'delta', 'create_tmp', 
                 'create_table', 'save', 'cleanup')
# in_table VARCHAR(129)
# in_views SET ('with_runtimes_in_95th_percentile', 'analysis', 
                'with_errors_or_warnings', 'with_full_table_scans', 
                'with_sorting', 'with_temp_tables', 'custom')

```

Description
-----------

 `statement_performance_analyzer` is a [stored procedure](../stored-procedures/index) available with the [Sys Schema](../sys-schema/index) which returns a report on running statements.

 The following options from the [sys\_config](../sys-schema-sys_config-table/index) table impact the output:

 * statement\_performance\_analyzer.limit - maximum number of rows (default 100) returned for views that have no built-in limit.
* statement\_performance\_analyzer.view - custom query/view to be used (default NULL). If the statement\_performance\_analyzer.limit configuration option is greater than 0, there can't be a LIMIT clause in the query/view definition

 If the debug option is set (default OFF), the procedure will also produce debugging output.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/statement_performance_analyzer/>

ps\_truncate\_all\_tables
=========================

    Syntax
------

 
```
ps_truncate_all_tables(bool display)

```

Description
-----------

 `ps_truncate_all_tables` is a [stored procedure](../stored-procedures/index) available with the [Sys Schema](../sys-schema/index).

 The procedure resets all aggregated instrumentation as a snapshot, producing a result set indicating the number of truncated tables. The boolean parameter *display* specifies whether to display each [TRUNCATE TABLE](../truncate-table/index) statement before execution.

 Examples
--------

 
```
CALL sys.ps_truncate_all_tables(false);
+---------------------+
| summary             |
+---------------------+
| Truncated 44 tables |
+---------------------+

```


```
CALL sys.ps_truncate_all_tables(true);
+------------------------------------------------------------------+
| status                                                           |
+------------------------------------------------------------------+
| Running: TRUNCATE TABLE performance_schema.events_stages_history |
+------------------------------------------------------------------+

...

+------------------------------------------------------------------------------+
| status                                                                       |
+------------------------------------------------------------------------------+
| Running: TRUNCATE TABLE performance_schema.table_lock_waits_summary_by_table |
+------------------------------------------------------------------------------+

+---------------------+
| summary             |
+---------------------+
| Truncated 44 tables |
+---------------------+

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_truncate_all_tables/>

create\_synonym\_db
===================

    Syntax
------

 
```
create_synonym_db(db_name,synonym)

# db_name (VARCHAR(64))
# synonym (VARCHAR(64))

```

Description
-----------

 `create_synonym_db` is a [stored procedure](../stored-procedures/index) available with the [Sys Schema](../sys-schema/index).

 Takes a source database name *db\_name* and *synonym* name and creates a synonym database with views that point to all of the tables within the source database. Useful for example for creating a synonym for the [performance\_schema](../performance-schema/index) or [information\_schema](../information-schema/index) databases.

 Returns an error if the source database doesn't exist, or the synonym already exists.

 Example
-------

 
```
SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+

CALL sys.create_synonym_db('performance_schema', 'perf');
+-----------------------------------------+
| summary                                 |
+-----------------------------------------+
| Created 81 views in the `perf` database |
+-----------------------------------------+

SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| perf               |
| performance_schema |
| sys                |
| test               |
+--------------------+

SHOW FULL TABLES FROM perf;
+------------------------------------------------------+------------+
| Tables_in_perf                                       | Table_type |
+------------------------------------------------------+------------+
| accounts                                             | VIEW       |
| cond_instances                                       | VIEW       |
| events_stages_current                                | VIEW       |
| events_stages_history                                | VIEW       |
| events_stages_history_long                           | VIEW       |
...

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/create_synonym_db/>

ps\_trace\_thread
=================

    Syntax
------

 
```
ps_trace_thread(thread_id, outfile, max_runtime, interval, start_fresh, auto_setup, debug) 

```

Description
-----------

 `ps_trace_thread` is a [stored procedure](../stored-procedures/index) available with the [Sys Schema](../sys-schema/index).

 Parameters:

 * thread\_id INT: The thread to trace.
* outfile VARCHAR(255): Name of the .dot file to be create.
* max\_runtime DECIMAL(20,2): Maximum time in seconds to collect data. Fractional seconds can be used, and NULL results in data being collected for the default sixty seconds.
* interval DECIMAL(20,2): Time in seconds to sleep between data collection. Fractional seconds can be used, and NULL results in the sleep being the default one second.
* start\_fresh BOOLEAN: Whether to reset all Performance Schema data before tracing.
* auto\_setup BOOLEAN: Whether to disable all other threads, enable all instruments and consumers, and reset the settings at the end of the run.
* debug BOOLEAN: Whether to include file:lineno information in the graph.

 Dumps all Performance Schema data for an instrumented thread to a .dot formatted graph file (for use with the [DOT graph description language](https://en.wikipedia.org/wiki/DOT_%28graph_description_language%29)). All returned result sets should be used for a complete graph.

 Session [binary logging](../binary-log/index) is disabled during execution, by adjusting the [sql\_log\_bin](../replication-and-binary-log-system-variables/index#sql_log_bin) session value (note the permissions required).

 Examples
--------

 
```
CALL sys.ps_trace_thread(25, CONCAT('/tmp/stack-', REPLACE(NOW(), ' ', '-'), '.dot'), 
  NULL, NULL, TRUE, TRUE, TRUE);

--------------------+
| summary            |
+--------------------+
| Disabled 0 threads |
+--------------------+

+---------------------------------------------+
| Info                                        |
+---------------------------------------------+
| Data collection starting for THREAD_ID = 25 |
+---------------------------------------------+

+-----------------------------------------------------------+
| Info                                                      |
+-----------------------------------------------------------+
| Stack trace written to /tmp/stack-2023-04-05-19:06:29.dot |
+-----------------------------------------------------------+

+-------------------------------------------------------------------+
| Convert to PDF                                                    |
+-------------------------------------------------------------------+
| dot -Tpdf -o /tmp/stack_25.pdf /tmp/stack-2023-04-05-19:06:29.dot |
+-------------------------------------------------------------------+

+-------------------------------------------------------------------+
| Convert to PNG                                                    |
+-------------------------------------------------------------------+
| dot -Tpng -o /tmp/stack_25.png /tmp/stack-2023-04-05-19:06:29.dot |
+-------------------------------------------------------------------+


```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/ps_trace_thread/>

Database Design: Overview
=========================

    Databases exist because of the need to change data into information. Data are the raw and unprocessed facts. Information is obtained by processing the data into something useful. For example, millions of names and telephone numbers in a phone book are data. Information is the telephone number of the fire department when your house is burning down.

 A database is a large repository of facts, designed in such a way that processing the facts into information is easy. If the phone book was structured in a less convenient way, such as with names and numbers placed in chronological order according to when the numbers were issued, converting the data into information would be much more difficult. Not knowing when the fire department was issued their latest number, you could search for days, and by the time you find the number your house would be a charred pile of ash. So, it's a good thing the phone book was designed as it was.

 A database is much more flexible; a similar set of data to what's in a phone book could be ordered by MariaDB according to name, telephone number, address as well as chronologically. But databases are of course more complex, containing many different kinds of information. People, job titles and a company's products can all mingle to provide complex information. But this complexity makes the design of databases more complex as well. Poor design could make for slow queries, or it could even make certain kinds of information impossible to reach. This section of the Knowledge Base features articles about good database design, specifically:

 * The database lifecycle
* Entity-relationship modeling
* Common mistakes in database design
* Real-world example: creating a publishing tracking system
* Concurrency control with transactions

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-overview/>

Database Lifecycle
==================

    
This article follows on from [Database Design: Overview](../database-design-overview/index).

 
Like everything else, databases have a finite lifespan. They are born in a flush of optimism and make their way through life achieving fame, fortune, and peaceful anonymity, or notoriety as the case may be, before fading out once more. Even the most successful database at some time is replaced by another, more flexible and up-to-date structure, and so begins life anew. Although exact definitions differ, there are generally six stages of the database lifecycle.

 #### Analysis

 The analysis phase is where the stakeholders are interviewed and any existing system is examined to identify problems, possibilities and constraints. The objectives and scope of the new system are determined.

 #### Design

 The design phase is where a conceptual design is created from the previously determined requirements, and a logical and physical design are created that will ready the database for implementation.

 #### Implementation

 The implementation phase is where the database management system (DBMS) is installed, the databases are created, and the data are loaded or imported.

 #### Testing

 The testing phase is where the database is tested and fine-tuned, usually in conjunction with the associated applications.

 #### Operation

 The operation phase is where the database is working normally, producing information for its users.

 #### Maintenance

 The maintenance phase is where changes are made to the database in response to new requirements or changed operating conditions (such as heavier load).

 Database development is not independent of systems development, often being one component of the greater systems development process. The stages of systems development basically mirror the stages of a database lifecycle but are a superset. Whereas database design deals with designing the system to store the data, systems design is also concerned with the processes that will impact on the data.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-lifecycle/>

Database Design Phase 1: Analysis
=================================

    
This article follows on from [Database Lifecycle](../database-lifecycle/index).

 
Your existing system can no longer cope. It's time to move on. Perhaps the existing paper system is generating too many errors, or the old Perl script based on flat files can no longer handle the load. Or perhaps an existing news database is struggling under its own popularity and needs an upgrade. This is the stage where the existing system is reviewed.

 Depending on the size of the project, the designer may be an individual, responsible for the database implementation and coding, or may be a whole team of analysts. For now, the term *designer* will represent all these possibilities.

 The following are the steps in the Analysis Phase.

 1. Analyze the organization
2. Define any problems, possibilities or constraints
3. Define the objectives
4. Agree on the scope

 When reviewing a system, the designer needs to look at the bigger picture - not just the hardware or existing table structures, but the whole situation of the organization calling for the redesign. For example, a large bank with centralized management would have a different structure and a different way of operating from a decentralized media organization, where anyone can post news onto a website. This may seem trivial, but understanding the organization you're building the database for is vital. to designing a good database for it. The same demands in the bank and media organizations should lead to different designs because the organizations are different. In other words, a solution that was constructed for the bank cannot be unthinkingly implemented for the media organization, even when the situation seems similar. A culture of central control at the bank may mean that news posted on the bank website has to be moderated and authorized by central management, or may require the designer to keep detailed audit trails of who modified what and when. On the flip-side, the media organization may be more laissez-faire and will be happy with news being modified by any authorized editor. 

 Understanding an organization's culture helps the designers ask the right questions. The bank may not ask for an audit trail, it may simply expect it; and when the time comes to roll out the implementation, the audit trail would need to be patched on, requiring more time and resources.

 Once you understand the organization structure, you can question the users of any existing system as to what their problems and needs are, as well as what constraints will exist then. You need to question different role players, as each can add new understanding as to what the database may need. For example, the media organization's marketing department may need detailed statistics about the times of day certain articles are read. You may also be alerted to possible future requirements. Perhaps the editorial department is planning to expand the website, which will give them the staff to cross-link web articles. Keeping this future requirement in mind could make it easier to add the cross-linking feature when the time comes.

 Constraints can include hardware ("We have to use our existing database server") or people ("We only have one data capturer on shift at any one time"). Constraints also refer to the limitations on values. For example, a student's grade in a university database may not be able to go beyond 100 percent, or the three categories of seats in a theatre database are small, medium and large.

 It is rarely sufficient to rely on one level of management, or an individual, to supply objectives and current problems, except in the smallest of organizations. Top management may be paying for the database design, but lower levels will need to use it, and their input is probably even more important for a successful design.

 Of course, although anything is possible given infinite time and money, this is (usually) never forthcoming. Determining scope, and formalizing it, is an important part of the project. If the budget is for one month's work but the ideal solution requires three, the designer must make clear these constraints and agree with the project owners on which facets are not going to be implemented.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-1-analysis/>

Database Design Phase 2: Conceptual Design
==========================================

    
This article follows on from [Database Design Phase 1: Analysis](../database-design-phase-1-analysis/index).

 
 The design phase is where the requirements identified in the previous phase are used as the basis to develop the new system. Another way of putting it is that the business understanding of the data structures is converted to a technical understanding. The *what* questions ("What data are required? What are the problems to be solved?") are replaced by the *how* questions ("How will the data be structured? How is the data to be accessed?")

 This phase consists of three parts: the conceptual design, the logical design and the physical design. Some methodologies merge the logical design phase into the other two phases. This section is not aimed at being a definitive discussion of database design methodologies (there are whole books written on that!); rather it aims to introduce you to the topic.

 Conceptual design
-----------------

 The purpose of the conceptual design phase is to build a conceptual model based upon the previously identified requirements, but closer to the final physical model. A commonly-used conceptual model is called an *entity-relationship* model.

 ### Entities and attributes

 *Entities* are basically people, places, or things you want to keep information about. For example, a library system may have the *book*, *library* and *borrower* entities. Learning to identify what should be an entity, what should be a number of entities, and what should be an *attribute* of an entity takes practice, but there are some good rules of thumb. The following questions can help to identify whether something is an entity:

 * Can it vary in number independently of other entities? For example, *person height* is probably not an entity, as it cannot vary in number independently of *person*. It is not fundamental, so it cannot be an entity in this case.
* Is it important enough to warrant the effort of maintaining. For example *customer* may not be important for a small grocery store and will not be an entity in that case, but it will be important for a video store, and will be an entity in that case.
* Is it its own thing that cannot be separated into subcategories? For example, a car-rental agency may have different criteria and storage requirements for different kinds of vehicles. *Vehicle* may not be an entity, as it can be broken up into *car* and *boat*, which are the entities.
* Does it list a type of thing, not an instance? The video game *blow-em-up 6* is not an entity, rather an instance of the *game* entity.
* Does it have many associated facts? If it only contains one attribute, it is unlikely to be an entity. For example, *city* may be an entity in some cases, but if it contains only one attribute, *city name*, it is more likely to be an attribute of another entity, such as *customer*.

 The following are examples of entities involving a university with possible attributes in parentheses.

 * **Course** (name, code, course prerequisites)
* **Student** (first\_name, surname, address, age)
* **Book** (title, ISBN, price, quantity in stock)

 An instance of an entity is one particular occurrence of that entity. For example, the student Rudolf Sono is one instance of the student entity. There will probably be many instances. If there is only one instance, consider whether the entity is warranted. The top level usually does not warrant an entity. For example, if the system is being developed for a particular university, *university* will not be an entity because the whole system is for that one university. However, if the system was developed to track legislation at all universities in the country, then *university* would be a valid entity.

 ### Relationships

 Entities are related in certain ways. For example, a borrower may belong to a library and can take out books. A book can be found in a particular library. Understanding what you are storing data about, and how the data relate, leads you a large part of the way to a physical implementation in the database.

 There are a number of possible relationships:

 #### Mandatory

 For each instance of entity A, there must exist one or more instances of entity B. This does not necessarily mean that for each instance of entity B, there must exist one or more instances of entity A. Relationships are optional or mandatory in one direction only, so the A-to-B relationship can be optional, while the B-to-A relationship is mandatory.

 #### Optional

 For each instance of entity A, there may or may not exist instances of entity B.

 #### One-to-one (1:1)

 This is where for each instance of entity A, there exists one instance of entity B, and vice-versa. If the relationship is optional, there can exist zero or one instances, and if the relationship is mandatory, there exists one and only one instance of the associated entity.

 #### One-to-many (1:M)

 For each instance of entity A, many instances of entity B can exist, which for each instance of entity B, only one instance of entity A exists. Again, these can be optional or mandatory relationships.

 #### Many-to-many (M:N)

 For each instance of entity A, many instances of entity B can exist, and vice versa. These can be optional or mandatory relationships.

 There are numerous ways of showing these relationships. The image below shows *student* and *course* entities. In this case, each student must have registered for at least one course, but a course does not necessarily have to have students registered. The student-to-course relationship is mandatory, and the course-to-student relationship is optional.

 ![many-to-many]

 The image below shows *invoice\_line* and *product* entities. Each invoice line must have at least one product (but no more than one); however each product can appear on many invoice lines, or none at all. The *invoice\_line-to-product* relationship is mandatory, while the *product-to-invoice\_line* relationship is optional.

 ![one_to_many]

 The figure below shows husband and wife entities. In this system (others are of course possible), each husband must have one and only one wife, and each wife must have one, and only one, husband. Both relationships are mandatory.

 ![one-to-one]

 An entity can also have a relationship with itself. Such an entity is called a *recursive entity*. Take a *person* entity. If you're interested in storing data about which people are brothers, you wlll have an "is brother to" relationship. In this case, the relationship is an M:N relationship.

 Conversely, a *weak entity* is an entity that cannot exist without another entity. For example, in a school, the *scholar* entity is related to the weak entity *parent/guardian*. Without the scholar, the parent or guardian cannot exist in the system. Weak entities usually derive their primary key, in part or in totality, from the associated entity. *parent/guardian* could take the primary key from the scholar table as part of its primary key (or the entire key if the system only stored one parent/guardian per scholar).

 The term *connectivity* refers to the relationship classification.

 The term *cardinality* refers to the specific number of instances possible for a relationship. *Cardinality limits* list the minimum and maximum possible occurrences of the associated entity. In the husband and wife example, the cardinality limit is (1,1), and in the case of a student who can take between one and eight courses, the cardinality limits would be represented as (1,8).

 ### Developing an entity-relationship diagram

 An entity-relationship diagram models how the entities relate to each other. It's made up of multiple relationships, the kind shown in the examples above. In general, these entities go on to become the database tables.

 The first step in developing the diagram is to identify all the entities in the system. In the initial stage, it is not necessary to identify the attributes, but this may help to clarify matters if the designer is unsure about some of the entities. Once the entities are listed, relationships between these entities are identified and modeled according to their type: one-to-many, optional and so on. There are many software packages that can assist in drawing an entity-relationship diagram, but any graphical package should suffice.

 Once the initial entity-relationship diagram has been drawn, it is often shown to the stakeholders. Entity-relationship diagrams are easy for non-technical people to understand, especially when guided through the process. This can help identify any errors that have crept in. Part of the reason for modeling is that models are much easier to understand than pages of text, and they are much more likely to be viewed by stakeholders, which reduces the chances of errors slipping through to the next stage, when they may be more difficult to fix.

 
It is important to remember that there is no one right or wrong answer. The more complex the situation, the more possible designs that will work. Database design is an acquired skill, though, and more experienced designers will have a good idea of what works and of possible problems at a later stage, having gone through the process before.

 
Once the diagram has been approved, the next stage is to replace many-to-many relationships with two one-to-many relationships. A DBMS cannot directly implement many-to-many relationships, so they are decomposed into two smaller relationships. To achieve this, you have to create an *intersection*, or *composite* entity type. Because intersection entities are less "real-world" than ordinary entities, they are sometimes difficult to name. In this case, you can name them according to the two entities being intersected. For example, you can intersect the many-to-many relationship between *student* and *course* by a *student-course* entity.

 ![student-course]

 The same applies even if the entity is recursive. The person entity that has an M:N relationship "is brother to" also needs an intersection entity. You can come up with a good name for the intersection entity in this case: *brother*. This entity would contain two fields, one for each person of the brother relationship — in other words, the primary key of the first brother and the primary key of the other brother.

 ![brother-intersection]

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-2-conceptual-design/>

Non-blocking API Reference
==========================

     Here is a list of all functions in the non-blocking client API and their parameters. Apart from operating in a non-blocking way, they all work exactly the same as their blocking counterparts, so their exact semantics can be obtained from the documentation of the normal client API.

 The API also contains the following three functions which are used to get the socket `fd` and `timeout` values when waiting for events to occur:

 
```
my_socket mysql_get_socket(const MYSQL *mysql)

```


 Return the descriptor of the socket used for the connection.

  
```
unsigned int STDCALL mysql_get_timeout_value(const MYSQL *mysql)

```


 This should only be called when a `_start()` or `_cont()` function returns a value with the `MYSQL_WAIT_TIMEOUT` flag set. In this case, it returns the value, in seconds, after which a timeout has occured and the application should call the appropriate `_cont()` function passing `MYSQL_WAIT_TIMEOUT` as the event that occured.

  
 This is used to handle connection and read timeouts.

  
```
unsigned int STDCALL mysql_get_timeout_value_ms(const MYSQL *mysql)

```


 This function is available starting from [MariaDB 5.5.28](https://mariadb.com/kb/en/mariadb-5528-release-notes/) and [MariaDB 10.0.0](https://mariadb.com/kb/en/mariadb-1000-release-notes/).

  
 Like mysql\_get\_timeout\_value(), this should only be called when a \_start() or \_cont() function returns a value with the MYSQL\_WAIT\_TIMEOUT flag set. In this case, it returns the value, in millisecondsseconds, after which a timeout has occured and the application should call the appropriate \_cont() function passing MYSQL\_WAIT\_TIMEOUT as the event that occured.

  
 The difference to mysql\_get\_timeout\_value() is that this provides millisecond resolution for timeouts, rather than just whole seconds. In [MariaDB 10.0](../what-is-mariadb-100/index), internal timeouts can now be in milliseconds, while in 5.5 and below it was only whole seconds.

  
 This milliseconds version is provided also in [MariaDB 5.5](../what-is-mariadb-55/index) (from 5.5.28 onwards) to make it easier for applications to work with either library version. However, in 5.5 it always returns a multiple of 1000 milliseconds.

  [At the end](#client-api-functions-which-never-block) is a list of all functions from the normal API which can be used safely in a non-blocking program, since they never need to block.

 
```
int mysql_real_connect_start(MYSQL **ret, MYSQL *mysql, const char *host,
                         const char *user, const char *passwd, const char *db,
                         unsigned int port, const char *unix_socket,
                         unsigned long client_flags)

```


```
int mysql_real_connect_cont(MYSQL **ret, MYSQL *mysql, int ready_status)

```


 `mysql_real_connect_start()` initiates a non-blocking connection request to a server.

  
 When `mysql_real_connect_start()` or `mysql_real_connect_cont()` returns zero, a copy of the passed '`mysql`' argument is stored in `*ret`.

  
```
int mysql_real_query_start(int *ret, MYSQL *mysql, const char *stmt_str,
unsigned long length)
int mysql_real_query_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_fetch_row_start(MYSQL_ROW *ret, MYSQL_RES *result)
int mysql_fetch_row_cont(MYSQL_ROW *ret, MYSQL_RES *result, int ready_status)

```


 Initiate fetch of another row from a `SELECT` query.

  
 If the `MYSQL_RES` was obtained from `mysql_use_result()`, then this function allows stream processing, where initial rows are returned to the application while the server is still sending subsequent rows. When no more data is available on the socket, `mysql_fetch_row_start()` or `mysql_fetch_row_cont()` will return `MYSQL_WAIT_READ` (or possibly `MYSQL_WAIT_WRITE` if using TLS and TLS re-negotiation is needed; also `MYSQL_WAIT_TIMEOUT` may be set if read timeout is enabled). When data becomes available, more rows can be fetched with `mysql_fetch_row_cont()`.

  
 If the `MYSQL_RES` was obtained from `mysql_store_result()` / `mysql_store_result_start()` / `mysql_store_result_cont()`, then this function cannot block — `mysql_fetch_row_start()` will always return 0 (and if desired, `plain mysql_fetch_row()` may be used instead with equivalent effect).

  
```
int mysql_set_character_set_start(int *ret, MYSQL *mysql, const char *csname)
int mysql_set_character_set_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
mysql_select_db_start(int *ret, MYSQL *mysql, const char *db)
int mysql_select_db_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_send_query_start(int *ret, MYSQL *mysql, const char *q, unsigned long length)
int mysql_send_query_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_store_result_start(MYSQL_RES **ret, MYSQL *mysql)
int mysql_store_result_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_free_result_start(MYSQL_RES *result)
int mysql_free_result_cont(MYSQL_RES *result, int ready_status)

```


 This function can need to wait if not all rows were fetched before it was called (then it needs to consume any pending rows sent from the server so they do not interfere with any subsequent queries sent).

  
 If all rows were already fetched, then this function will not need to wait. `mysql_free_result_start()` will return zero (or if so desired, plain `mysql_free_result()` may be used instead).

  
 Note that `mysql_free_result()` returns no value, so there is no extra '`ret`' parameter for `mysql_free_result_start()` or `mysql_free_result_cont()`.

  
```
int mysql_close_start(MYSQL *sock)
int mysql_close_cont(MYSQL *sock, int ready_status)

```


 `mysql_close()` sends a `COM_QUIT` request to the server, though it does not wait for any reply.

  
 Thus teoretically it can block (if the socket buffer is full), though in practise it is probably unlikely to occur frequently.

  
 The non-blocking version of `mysql_close()` is provided for completeness; for many applications using the normal `mysql_close()` is probably sufficient (and may be simpler).

  
 Note that `mysql_close()` returns no value, so there is no extra '`ret`' parameter for `mysql_close_start()` or `mysql_close_cont()`.

  
```
int mysql_change_user_start(my_bool *ret, MYSQL *mysql, const char *user, const
                            char *passwd, const char *db)
int mysql_change_user_cont(my_bool *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_query_start(int *ret, MYSQL *mysql, const char *q)
int mysql_query_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_shutdown_start(int *ret, MYSQL *mysql, enum mysql_enum_shutdown_level
                        shutdown_level)
int mysql_shutdown_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_dump_debug_info_start(int *ret, MYSQL *mysql)
int mysql_dump_debug_info_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_refresh_start(int *ret, MYSQL *mysql, unsigned int refresh_options)
int mysql_refresh_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_kill_start(int *ret, MYSQL *mysql, unsigned long pid)
int mysql_kill_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_set_server_option_start(int *ret, MYSQL *mysql,
                              enum enum_mysql_set_option option)
int mysql_set_server_option_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_ping_start(int *ret, MYSQL *mysql)
int mysql_ping_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_stat_start(const char **ret, MYSQL *mysql)
int mysql_stat_cont(const char **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_list_dbs_start(MYSQL_RES **ret, MYSQL *mysql, const char *wild)
int mysql_list_dbs_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_list_tables_start(MYSQL_RES **ret, MYSQL *mysql, const char *wild)
int mysql_list_tables_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_list_processes_start(MYSQL_RES **ret, MYSQL *mysql)
int mysql_list_processes_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_list_fields_start(MYSQL_RES **ret, MYSQL *mysql, const char *table,
                        const char *wild)
int mysql_list_fields_cont(MYSQL_RES **ret, MYSQL *mysql, int ready_status)

```


```
int mysql_read_query_result_start(my_bool *ret, MYSQL *mysql)
int mysql_read_query_result_cont(my_bool *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_stmt_prepare_start(int *ret, MYSQL_STMT *stmt, const char *query,
                         unsigned long length)
int mysql_stmt_prepare_cont(int *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_execute_start(int *ret, MYSQL_STMT *stmt)
int mysql_stmt_execute_cont(int *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_fetch_start(int *ret, MYSQL_STMT *stmt)
int mysql_stmt_fetch_cont(int *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_store_result_start(int *ret, MYSQL_STMT *stmt)
int mysql_stmt_store_result_cont(int *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_close_start(my_bool *ret, MYSQL_STMT *stmt)
int mysql_stmt_close_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_reset_start(my_bool *ret, MYSQL_STMT *stmt)
int mysql_stmt_reset_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_free_result_start(my_bool *ret, MYSQL_STMT *stmt)
int mysql_stmt_free_result_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_stmt_send_long_data_start(my_bool *ret, MYSQL_STMT *stmt,
                                unsigned int param_number,
                                const char *data, unsigned long length)
int mysql_stmt_send_long_data_cont(my_bool *ret, MYSQL_STMT *stmt, int ready_status)

```


```
int mysql_commit_start(my_bool *ret, MYSQL *mysql)
int mysql_commit_cont(my_bool *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_rollback_start(my_bool *ret, MYSQL *mysql)
int mysql_rollback_cont(my_bool *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_autocommit_start(my_bool *ret, MYSQL *mysql, my_bool auto_mode)
int mysql_autocommit_cont(my_bool *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_next_result_start(int *ret, MYSQL *mysql)
int mysql_next_result_cont(int *ret, MYSQL *mysql, int ready_status)

```


```
int mysql_stmt_next_result_start(int *ret, MYSQL_STMT *stmt)
int mysql_stmt_next_result_cont(int *ret, MYSQL_STMT *stmt, int ready_status)

```

Client API functions which never block
--------------------------------------

 The following client API functions never need to do I/O and thus can never block. Therefore, they can be used as normal in programs using non-blocking operations; no need to call any special `_start()` variant. (Even if a `_start()` variant was available, it would always return zero, so no `_cont()` call would ever be needed).

 * [mysql\_num\_rows()](../mysql_num_rows/index)
* [mysql\_num\_fields()](../mysql_num_fields/index)
* mysql\_eof()
* [mysql\_fetch\_field\_direct()](../mysql_fetch_field_direct/index)
* [mysql\_fetch\_fields()](../mysql_fetch_fields/index)
* [mysql\_row\_tell](../mysql_row_tell/index)
* [mysql\_field\_tell()](../mysql_field_tell/index)
* [mysql\_field\_count()](../mysql_field_count/index)
* [mysql\_affected\_rows()](../mysql_affected_rows/index)
* [mysql\_insert\_id()](../mysql_insert_id/index)
* [mysql\_errno()](../mysql_errno/index)
* [mysql\_error()](../mysql_error/index)
* [mysql\_sqlstate()](../mysql_sqlstate/index)
* [mysql\_warning\_count()](../mysql_warning_count/index)
* [mysql\_info()](../mysql_info/index)
* [mysql\_thread\_id()](../mysql_thread_id/index)
* [mysql\_character\_set\_name()](../mysql_character_set_name/index)
* [mysql\_init()](../mysql_init/index)
* [mysql\_ssl\_set()](../mysql_ssl_set/index)
* [mysql\_get\_ssl\_cipher()](../mysql_get_ssl_cipher/index)
* [mysql\_use\_result()](../mysql_use_result/index)
* [mysql\_get\_character\_set\_info()](../mysql_get_character_set_info/index)
* mysql\_set\_local\_infile\_handler()
* mysql\_set\_local\_infile\_default()
* [mysql\_get\_server\_info()](../mysql_get_server_info/index)
* mysql\_get\_server\_name()
* [mysql\_get\_client\_info()](../mysql_get_client_info/index)
* [mysql\_get\_client\_version()](../mysql_get_client_version/index)
* [mysql\_get\_host\_info()](../mysql_get_host_info/index)
* [mysql\_get\_server\_version()](../mysql_get_server_version/index)
* [mysql\_get\_proto\_info()](../mysql_get_proto_info/index)
* [mysql\_options()](../mysql_options/index)
* [mysql\_data\_seek()](../mysql_data_seek/index)
* [mysql\_row\_seek()](../mysql_row_seek/index)
* [mysql\_field\_seek()](../mysql_field_seek/index)
* [mysql\_fetch\_lengths()](../mysql_fetch_lengths/index)
* [mysql\_fetch\_field()](../mysql_fetch_field/index)
* [mysql\_escape\_string()](../mysql_escape_string/index)
* [mysql\_hex\_string()](../mysql_hex_string/index)
* [mysql\_real\_escape\_string()](../mysql_real_escape_string/index)
* [mysql\_debug()](../mysql_debug/index)
* myodbc\_remove\_escape()
* mysql\_thread\_safe()
* mysql\_embedded()
* mariadb\_connection()
* [mysql\_stmt\_init()](../mysql_stmt_init/index)
* [mysql\_stmt\_fetch\_column()](../mysql_stmt_fetch_column/index)
* [mysql\_stmt\_param\_count()](../mysql_stmt_param_count/index)
* [mysql\_stmt\_attr\_set()](../mysql_stmt_attr_set/index)
* [mysql\_stmt\_attr\_get()](../mysql_stmt_attr_get/index)
* [mysql\_stmt\_bind\_param()](../mysql_stmt_bind_param/index)
* [mysql\_stmt\_bind\_result()](../mysql_stmt_bind_result/index)
* [mysql\_stmt\_result\_metadata()](../mysql_stmt_result_metadata/index)
* [mysql\_stmt\_param\_metadata()](../mysql_stmt_param_metadata/index)
* [mysql\_stmt\_errno()](../mysql_stmt_errno/index)
* [mysql\_stmt\_error()](../mysql_stmt_error/index)
* [mysql\_stmt\_sqlstate()](../mysql_stmt_sqlstate/index)
* [mysql\_stmt\_row\_seek()](../mysql_stmt_row_seek/index)
* [mysql\_stmt\_row\_tell()](../mysql_stmt_row_tell/index)
* [mysql\_stmt\_data\_seek()](../mysql_stmt_data_seek/index)
* [mysql\_stmt\_num\_rows()](../mysql_stmt_num_rows/index)
* [mysql\_stmt\_affected\_rows()](../mysql_stmt_affected_rows/index)
* [mysql\_stmt\_insert\_id()](../mysql_stmt_insert_id/index)
* [mysql\_stmt\_field\_count()](../mysql_stmt_field_count/index)
* [mysql\_more\_results()](../mysql_more_results/index)
* mysql\_get\_socket()
* mysql\_get\_timeout\_value
* mysql\_get\_timeout\_value\_ms

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/non-blocking-api-reference/>

Database Design Phase 2: Logical and Physical Design
====================================================

    
This article follows on from [Database Design Phase 2: Conceptual Design](../database-design-phase-2-conceptual-design/index).

  Overview
--------

 Once the conceptual design is finalized, it's time to convert this to the logical and physical design. Usually, the DBMS is chosen at this stage, depending on the requirements and complexity of the data structures. Strictly speaking, the logical design and the physical design are two separate stages, but are often merged into one. They overlap because most current DBMSs (including MariaDB) match logical records to physical records on disk on a 1:1 basis.

 Each entity will become a database table, and each attribute will become a field of this table. Foreign keys can be created if the DBMS supports them and the designer decides to implement them. If the relationship is mandatory, the foreign key must be defined as *NOT NULL*, and if it's optional, the foreign key can allow nulls. For example, because of the invoice line-to-product relationship in the previous example, the product code field is a foreign key in the invoice to line table. Because the invoice line must contain a product, the field must be defined as *NOT NULL*. The default MariaDB storage engine, [XtraDB](../innodb/index), does support foreign key constraints, but some storage engines, such as [MyISAM](../myisam/index) do not. The *ON DELETE CASCADE* and *ON DELETE RESTRICT* clauses are used to support foreign keys. *ON DELETE RESTRICT* means that records cannot be deleted unless all records associated with the foreign key are also deleted. In the invoice line-to-product case, *ON DELETE RESTRICT* in the invoice line table means that if a product is deleted, the deletion will not take place unless all associated invoice lines with that product are deleted as well. This avoids the possibility of an invoice line existing that points to a non-existent product. *ON DELETE CASCADE* achieves a similar effect, but more automatically (and more dangerously!). If the foreign key was declared with *ON CASCADE DELETE*, associated invoice lines would automatically be deleted if a product was deleted. *ON UPDATE CASCADE* is similar to *ON DELETE CASCADE* in that all foreign key references to a primary key are updated when the primary key is updated.

 [Normalizing](../database-normalization/index) your tables is an important step when designing the database. This process helps avoid data redundancy and improves your data integrity.

 Novice database designers usually make a number of common errors. If you've carefully identified entities and attributes and you've normalized your data, you'll probably avoid these errors.

 Common errors
-------------

 * Keep unrelated data in different tables. People who are used to using spreadsheets often make this mistake because they are used to seeing all their data in one two-dimensional table. A relational database is much more powerful; don't 'hamstring' it in this way.
* Don't store values you can calculate. Let's say you're interested three numbers: /A, B and the product of A and B (A\*B). Don't store the product. It wastes space and can easily be calculated if you need it. And it makes your database more difficult to maintain: If you change A, you also have to change all of the products as well. Why waste your database's efforts on something you can calculate when you need it?
* Does your design cater to all the conditions you've analyzed? In the heady rush of creating an entity-relationship diagram, you can easily overlook a condition. Entity-relationship diagrams are usually better at getting stakeholders to spot an incorrect rule than spot a missing one. The business logic is as important as the database logic and is more likely to be overlooked. For example, it's easy to spot that you cannot have a sale without an associated customer, but have you built in that the customer cannot be approved for a sale of less than $500 if another approved customer has not recommended them?
* Are your attributes, which are about to become field names, well chosen? Fields should be clearly named. For example, if you use *f1* and *f2* instead of *surname* and *first\_name*, the time saved in less typing will be lost in looking up the correct spelling of the field, or in mistakes where a developer thought *f1* was the first name, and *f2* the surname. Similarly, try to avoid the same names for different fields. If six tables have a primary key of *code*, you're making life unnecessarily difficult. Rather, use more descriptive terms, such as *sales\_code* or *customer\_code*.
* Don't create too many relationships. Almost every table in a system can be related by some stretch of the imagination, but there's no need to do this. For example, a tennis player belongs to a sports club. A sports club belongs to a region. The tennis players then also belong to a region, but this relationship can be derived through the sports club, so there's no need to add another foreign key (except to achieve performance benefits for certain kinds of queries). Normalizing can help you avoid this sort of problem (and even when you're trying to optimize for speed, it's usually better to normalize and then consciously denormalize rather than not normalize at all).
* Conversely, have you catered to all relations? Do all relations from your entity-relationship diagram appear as common fields in your table structures? Have you covered all relations? Are all many-to-many relationships broken up into two one-to-many relationships, with an intersection entity?
* Have you listed all constraints? Constraints include a gender that can only be *m* or *f*, ages of schoolchildren that cannot exceed twenty, or email addresses that need to have an *@* sign and at least one period (*.*; don't take these limits for granted. At some stage the system you will need to implement them, and you're either going to forget to do so, or have to go back and gather more data if you don't list these up front.
* Are you planning to store too much data? Should a customer be asked to supply their eye color, favorite kind of fish, and names of their grandparents if they are simply trying to register for an online newsletter? Sometimes stakeholders want too much information from their customers. If the user is outside the organization, they may not have a voice in the design process, but they should always be thought of foremost. Consider also the difficulty and time taken to capture all the data. If a telephone operator needs to take all this information down before making a sale, imagine how much slower they will be. Also consider the impact data has on database speed. Larger tables are generally slower to access, and unnecessary [BLOB](../blob/index), [TEXT](../text/index) and [VARCHAR](../varchar/index) fields lead to record and table fragmentation.
* Have you combined fields that should be separate? Combining first name and surname into one field is a common beginner mistake. Later you'll realise that sorting names alphabetically is tricky if you've stored them as *John Ellis* and *Alfred Ntombela*. Keep distinct data discrete.
* Has every table got a primary key? There had better be a good reason for leaving out a primary key. How else are you going to identify a unique record quickly? Consider that an index speeds up access time tremendously, and when kept small it adds very little overhead. Also, it's usually better to create a new field for the primary key rather than take existing fields. First name and surname may be unique in your current database, but they may not always be. Creating a system-defined primary key ensures it will always be unique.
* Give some thought to your other indexes. What fields are likely to be used in this condition to access the table? You can always create more fields later when you test the system, but add any you think you need at this stage.
* Are your foreign keys correctly placed? In a one-to-many relationship, the foreign key appears in the *many* table, and the associated primary key in the *one* table. Mixing these up can cause errors.
* Do you ensure referential integrity? Foreign keys should not relate to a primary key in another table that no longer exists.
* Have you covered all character sets you may need? German letters, for example, have an expanded character set, and if the database is to cater for German users it will have to take this into account. Similarly, dates and currency formats should be carefully considered if the system is to be international
* Is your security sufficient? Remember to assign the minimum permissions you can. Do not allow anyone to view a table if they do not need to do so. Allowing malicious users view data, even if they cannot change it, is often the first step in for an attacker.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-2-logical-and-physical-design/>

Database Design Phase 3: Implementation
=======================================

    
This article follows on from [Database Design Phase 2: Logical and Physical Design](../database-design-phase-2-logical-and-physical-design/index).

 
The implementation phase is where you install the DBMS on the required hardware, optimize the database to run best on that hardware and software platform, and create the database and load the data. The initial data could be either new data captured directly or existing data imported from a MariaDB database or another DBMS. You also establish database security in this phase and give the various users that you've identified access applicable to their requirements. Finally, you also initiate backup plans in this phase.

 The following are steps in the implementation phase:

 1. Install the DBMS.
2. Tune the setup variables according to the hardware, software and usage conditions.
3. Create the database and tables.
4. Load the data.
5. Set up the users and security.
6. Implement the backup regime.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-3-implementation/>

Database Design Phase 4: Testing
================================

    
This article follows on from [Database Design Phase 3: Implementation](../database-design-phase-3-implementation/index).

 
The testing phase is where the performance, security, and integrity of the data are tested. Usually this will occur in conjunctions with the applications that have been developed. You test the performance under various loads conditions to see how the database handles multiple concurrent connections or high volumes of updating and reading. Are the reports generated quickly enough? For example, an application designed with the old [MyISAM](../myisam/index) storage engine may prove to be too slow because the impact of the updates was underestimated. The storage engine may have to be changed to [XtraDB](../innodb/index) in response.

 Data integrity also needs to be tested, as the application may have logical flaws that result in transactions being lost or other inaccuracies. Further, security needs to be tested to ensure that users can access and change only the data they should.

 The logical or physical designs may have to be modified. Perhaps new indexes are required (which the tester may discover after careful use of MariaDB's [EXPLAIN](../explain/index) statement, for example).

 The testing and fine-tuning process is an iterative one, with multiple tests performed and changes implemented.

 The following are the steps in the testing phase:

 1. Test the performance
2. Test the security
3. Test the data integrity
4. Fine-tune the parameters or modify the logical or physical designs in response to the tests.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-4-testing/>

Database Design Phase 5: Operation
==================================

    
This article follows on from [Database Design Phase 4: Testing](../database-design-phase-4-testing/index).

 
The operation phase takes place when the testing is complete and the database is ready to be rolled out for everyday use. The users of the system begin to operate the system, load data, read reports and so on. Inevitably, problems come to light. The designers need to carefully manage the database's scope at this stage, as users may expect all their desires to be pandered to. Poor database designers may find themselves extending the project well beyond their initial time estimate, and the situation may also become unpleasant if the scope has not been clearly defined and agreed upon. Project owners will feel wronged if their needs are not met, and the database designers will feel overworked and underpaid. Even when scope has been well managed, there will always be new requirements, These then lead to the next stage.

 There are numerous strategies for implementing a rollout. The low-key approach often works well, where the relatively low number of users in the early stage make bug fixing easy. Hugely publicized rollouts often end with egg on the stakeholder's faces, as the best testers of all, the users, invariably find unforeseen bugs, which is best done away from the spotlight. Alternatively, rollouts can occur in a distributed manner, where a pilot branch or office is selected, and when the system has proven its stability, it's rolled out to the remaining branches.

 The following are the steps in the operation phase:

 1. Hand over operation of the database to the users.
2. Make any final changes based on the problems discovered by users.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-5-operation/>

Database Design Phase 6: Maintenance
=====================================

    
This article follows on from [Database Design Phase 5: Operation](https://mariadb.com/database-design-phase-5-operation).

 
The database maintenance phase incorporates general maintenance, such as maintaining the indexes, optimizing the tables, adding and removing users, and changing passwords, as well as backups and restoration of backups in case of a failure. New requirements also start to be requested, and this may result in new fields, or new tables, being created.

 As the new system and organization changes, the existing database becomes less and less sufficient to meet the organization's needs. For example, the media organization may be amalgamated with media bodies from other countries, requiring integration of many data sources, or the volumes and staff may expand (or reduce) dramatically. Eventually, there comes a time, whether it's 10 months after completion or 10 years, when the database system needs to be replaced. The maintenance of the existing database begins to drain more and more resources, and the effort to create a new design is matched by the current maintenance effort. As this point, the database is coming to the end of its life, and a new project begins life in the Analysis phase.

 The following are the steps in the maintenance phase:

 1. Maintain the indexes
2. Maintain the tables
3. Maintain the users
4. Change passwords
5. Backup
6. Restore backups
7. Change the design to meet new requirements

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-phase-6-maintenance/>

Database Design Example Phase 1: Analysis
=========================================

    
This article follows on from [Database Design Phase 6: Maintenance](../database-design-phase-6-maintenance/index).

 
Real-world example: creating a publishing tracking system
---------------------------------------------------------

 Now let's walk through the database design process with a step-by-step example. The Poet's Circle is a publisher that publishes poetry and poetry anthologies. It is keen to develop a new system that tracks poets, poems, anthologies and sales. The following sections show the steps taken from the initial analysis to the final, working database.

 ### Poet's circle database phase 1: analysis

 The following information is gleaned from speaking to the various stakeholders at Poet's Circle. They want to develop a database system to track the poets they have recorded, the poems they write, the publications they appear in, as well as the sales to customers that these publications make.

 The designer asks various questions to get more detailed information, such as "What is a poet, as far as the system goes? Does Poet's Circle keep track of poets even if they haven't written or published poems? Are publications recorded even before there are any associated poems? Does a publication consist of one poem, or many? Are potential customer's details recorded?" The following summarizes the responses in our example:

 * Poet's Circle is a publisher that bases its choices of publications on an active poetry community on its website. If enough of the community wants a poem published, Poet's Circle will do so.
* A poet can be anybody who wants to be a poet, not necessarily someone who has a poem captured in the system or someone who has even written a poem.
* Poems can be submitted through a web interface, by email or on paper.
* All captured poems are written by an associated poet, whose details are already in the system. There can be no poems submitted and stored without a full set of details of the poet.
* A publication can be a single poem, a poetry anthology, or a work of literary criticism.
* Customers can sign up through a web interface and may order publications at that point in time, or express interest in receiving updates for possible later purchases.
* Sales of publications are made to customers whose details are stored in the system. There are no anonymous sales.
* A single sale can be for one publication, but many publications can also be purchased at the same time. If more than one customer is involved in this sale, Poet's Circle treats it as more than one sale. Each customer has their own sale.
* Not all publications make sales — some may be special editions, and others simply never sell any copies.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-example-phase-1-analysis/>

Database Design Example Phase 2: Design
=======================================

    
This article follows on from [Database Design Example Phase 1: Analysis](../database-design-example-phase-1-analysis/index).

 
Based on the provided information, you can begin your logical design and should be able to identify the initial entities:

 * Poet
* Poem
* Publication
* Sale
* Customer

 The Poet's Circle is not an entity, or even of instance an a *publisher* entity. Only if the system were developed for many publishers would *publisher* be a valid entity.

 Neither *website* nor *poetry community* are entities. There is only one website, and anyway, a website is merely a means of producing data to populate the database. There is also only one poetry community as far as this system is concerned, and there is not much you'd want to store about it.

 Next, you need to determine the relationship between these entities. You can identify the following:

 * A poet can write many poems. The analysis identified the fact that a poet can be stored in the system even if there are no associated poems. Poems may be captured at a later point in time, or the poet may still be a potential poet. Conversely, many poets could conceivably write a poem, though the poem must have been written by at least one poet.
* A publication may contain many poems (an anthology) or just one. It can also contain no poems (poetry criticism for example). A poem may or may not appear in a publication.
* A sale must be for at least one publication, but it may be for many. A publication may or may not have made any sales.
* A customer may be made for many sales, or none at all. A sale is only made for one and only one customer.

 You can identify the following attributes:

 * **Poet**: first name, surname, address, email address
* **Poem**: poem title, poem contents
* **Publication**: title, price
* **Sales**: date, amount
* **Customer**: first name, surname, address, email address

 Based on these entities and relationships, you can construct the entity-relationship diagram shown below:

 ![poets-circle-erd1]

 There are two many-to-many relationships in the figure above. These need to be converted into one-to-many relationships before you can implement them in a DBMS. After doing so, the intersection entities *poem-publication* and *sale-publication* are created.

 ![poets-circle-erd2]

 Now, to begin the logical and physical design, you need to add attributes that can create the relationship between the entities and specify primary keys. You do what's usually best, and create new, unique, primary keys. The following tables show the structures for the tables created from each of the entities:

 #### Poet table

 


| Field | Definition |
| --- | --- |
| poet code | primary key, integer |
| first name | character (30) |
| surname | character (40) |
| address | character (100) |
| postcode | character (20) |
| email address | character (254) |

 
#### Poem table

 


| Field | Definition |
| --- | --- |
| poem code | primary key, integer |
| poem title | character(50) |
| poem contents | text |
| poet code | foreign key, integer |

 
#### Poem-publication table

 


| Field | Definition |
| --- | --- |
| poem code | joint primary key, foreign key, integer |
| publication code | joint primary key, foreign key, integer |

 
#### Publication table

 


| Field | Definition |
| --- | --- |
| publication code | primary key, integer |
| title | character(100) |
| price | numeric(5.2) |

 
#### Sale-publication table

 


| Field | Definition |
| --- | --- |
| sale code | joint primary key, foreign key, integer |
| publication code | joint primary key, foreign key, integer |

 
#### Sale table

 


| Field | Definition |
| --- | --- |
| sale code | primary key, integer |
| date | date |
| amount | numeric(10.2) |
| customer code | foreign key, integer |

 
#### Customer table

 


| Field | Definition |
| --- | --- |
| customer code | primary key, integer |
| first name | character (30) |
| surname | character (40) |
| address | character (100) |
| postcode | character (20) |
| email address | character (254) |

 
MariaDB will have no problem with this, and is selected as the DBMS. Existing hardware and operating system platforms are also selected. The following section looks at the implementation and the SQL statements used to create the MariaDB tables.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-example-phase-2-design/>

Database Design Example Phase 3: Implementation
===============================================

    
This article follows on from [Database Design Example Phase 2: Design](../database-design-example-phase-2-design/index).

 
With the design complete, it's time to [install MariaDB](../getting-installing-and-upgrading-mariadb/index) and run the [CREATE](../create/index) statements, as follows:

 
```
CREATE DATABASE poets_circle;

CREATE TABLE poet (
  poet_code INT NOT NULL, 
  first_name VARCHAR(30),
  surname VARCHAR(40), 
  address VARCHAR(100), 
  postcode VARCHAR(20),
  email VARCHAR(254), 
  PRIMARY KEY(poet_code)
);

CREATE TABLE poem(
  poem_code INT NOT NULL, 
  title VARCHAR(50),
  contents TEXT, 
  poet_code INT NOT NULL, 
  PRIMARY KEY(poem_code),
  INDEX(poet_code), 
  FOREIGN KEY(poet_code) REFERENCES poet(poet_code) 
);

CREATE TABLE publication(
  publication_code INT NOT NULL,
  title VARCHAR(100),
  price MEDIUMINT UNSIGNED,
  PRIMARY KEY(publication_code)
);

CREATE TABLE poem_publication(
  poem_code INT NOT NULL,
  publication_code INT NOT NULL, 
  PRIMARY KEY(poem_code, publication_code), 
  INDEX(publication_code),
  FOREIGN KEY(poem_code) REFERENCES poem(poem_code),
  FOREIGN KEY(publication_code) REFERENCES publication(publication_code)
);

CREATE TABLE sales_publication(
  sales_code INT NOT NULL,
  publication_code INT NOT NULL,
  PRIMARY KEY(sales_code, publication_code)
); 

CREATE TABLE customer(
  customer_code INT NOT NULL, 
  first_name VARCHAR(30), 
  surname VARCHAR(40), 
  address VARCHAR(100), 
  postcode VARCHAR(20), 
  email VARCHAR(254), 
  PRIMARY KEY(customer_code)
);

CREATE TABLE sale(
  sale_code INT NOT NULL, 
  sale_date DATE,
  amount INT UNSIGNED, 
  customer_code INT NOT NULL, 
  PRIMARY KEY(sale_code), 
  INDEX(customer_code), 
  FOREIGN KEY(customer_code) REFERENCES customer(customer_code)
);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-example-phase-3-implementation/>

Database Design Example Phases 4-6: Testing, Operation and Maintenance
======================================================================

    
This article follows on from [Database Design Example Phase 3: Implementation](../database-design-example-phase-3-implementation/index).

 
Once the database is ready the application programs have been rolled out, it's time for the testing to begin. While the other phases of the database lifecycle can occur reasonably independently of the systems development process, part of the testing phase is how all the components run together.

 Load testing may indicate that MariaDB has not been set up to handle the expected 600 concurrent connections, and the configuration file needs to be changed. Other tests may indicate that in certain circumstances, duplicate key errors are received, as the locking mechanism is not uniformly implemented, and the application does not handle locking correctly. The application needs to be fixed. Backups also need to be tested, as well as the ability to smoothly restore from backup with a minimum of downtime.

 
Testing is one of the most neglected and critical phases. A designer or manager who does not properly account for testing is simply incompetent. No matter how tiny your system, make sure you allocate time for thorough testing, and time for fixing the inevitable bugs.

 
Once testing is complete, the system can be rolled out. You decide on a low-key rollout and give a few selected poets access to the website to upload their poems. You discover other problems. Some poets upload poems using [character sets](../data-types-character-sets-and-collations/index) you haven't catered for, and you need to make a few tweaks to ensure these are handled correctly.

 Soon enough, the system is rolled out completely. Maintenance, though, is a never-ending task, and with the immense popularity of the system, and with large numbers of updates and deletes, the system tends to become fragmented. The administrator regularly needs to take care of this, and, of course, the inevitable disk failure leads to an all-night restore session, and much thankfulness for the ease of use of [mariadb-dump](../mariadb-dump/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/database-design-example-phases-4-6-testing-operation-and-maintenance/>

SHARE PERFORMANCE ACROSS 2 SERVERS
==================================

    Good morning in very l 'équipe of monty , sorry for my english, i am french.

 To ameliorate a problem of performance d 'une database. That this has 200 tables, therefore 2 very very hard soliciting. What for consequences l 'effet with dominoes. 

 J 'explique if I solicit the performance of these from 198 small tables is good. But if all at once I solicit 2 big tables of numerous times, the solicitation of the 198 small tables becomes slow.

 I look for, a solution like

 SET @SERVER1='root@mypassword/192.0.1.128:3306'; SET @SERVER2='root2@mypasswordx/192.0.1.129:3306';

 SELECT T1,T2 FROM SERVER1.DATABASE.ARTICLE , SERVER2.DATABASE.TAX WERE SERVER1.DATABASE.ARTICLE.S1KEYUNIK=SERVER2.DATABASE.TAX.S1KEYUNIK;

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/share-performance-across-2-servers/>

DBT-3 Queries
=============

    Q1
--

 See [MDEV-4309](https://jira.mariadb.org/browse/MDEV-4309) (just speeding up temptable-based GROUP BY execution). Optimizer seems to make a good choice here.

 
```
select
        l_returnflag,
        l_linestatus,
        sum(l_quantity) as sum_qty,
        sum(l_extendedprice) as sum_base_price,
        sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
        sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
        avg(l_quantity) as avg_qty,
        avg(l_extendedprice) as avg_price,
        avg(l_discount) as avg_disc,
        count(*) as count_order
from
        lineitem
where
        l_shipdate <= date_sub('1998-12-01', interval 63 day)
group by
        l_returnflag,
        l_linestatus
order by
        l_returnflag,
        l_linestatus

```

Q4
--

 See [MDEV-6015](https://jira.mariadb.org/browse/MDEV-6015).

 Applicable optimizations:

 * subquery cache brings no benefit because subquery refers to outer\_table.pk, which is different for each row
* EXISTS-to-IN is applicable
	+ After that, BKA brings slight speedup

 Comments on query plan choice

 * It seems, we're using the best possible query plan here.

 
```
select
	o_orderpriority,
	count(*) as order_count
from
	orders
where
	o_orderdate >= '1995-06-06'
	and o_orderdate < date_add('1995-06-06', interval 3 month)
	and exists (
		select
			*
		from
			lineitem
		where
			l_orderkey = o_orderkey
			and l_commitdate < l_receiptdate
	)
group by
	o_orderpriority
order by
	o_orderpriority;

```

.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/dbt-3-queries/>

OpenStreetMap Dataset
=====================

    This page describes how to use the OpenStreetMap dataset in testing.

 Database Schema
---------------

 The database schema is available [here](../osmdb06sql/index). To import:

 
```
mysqladmin create osm
cat osmdb06.sql | mysql osm

```

By default, this schema uses a mixture of InnoDB and MyISAM tables. To convert all tables to Aria:

 
```
sed -i -e 's/InnoDB/Aria/gi' osmdb06.sql
sed -i -e 's/MyISAM/Aria/gi' osmdb06.sql

```

30 tables are created.

 Data
----

 The data is provided in the form of XML files (.OSM files) that require the Java-based [Osmosis](http://wiki.openstreetmap.org/wiki/Osmosis) tool to load into MariaDB. The tool is available from [dev.openstreetmap.org](http://dev.openstreetmap.org/~bretth/osmosis-build/osmosis-latest.tgz). Version 0.36 is known to work.

 Various .OSM files are available, including the [entire world](http://wiki.openstreetmap.org/wiki/Planet.osm) (>200Gb unzipped) and [individual countries](http://download.geofabrik.de/osm/).

 Data is loaded with the following command-line (in the example, we're using the bulgaria.osm file, replace with the file you choose):

 
```
chmod +x bin/osmosis
bin/osmosis --read-xml file=bulgaria.osm --write-apidb dbType="mysql" host="localhost:port" validateSchemaVersion=no database="osm" user="root" password="<password-goes-here>"

```

Data is inserted into 19 tables, as follows:

 
```
MariaDB [(none)]> use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [information_schema]> select TABLE_NAME, TABLE_ROWS from TABLES
    -> where TABLE_ROWS > 0
    -> AND
    -> TABLE_SCHEMA='osm'
    -> ORDER BY TABLE_ROWS DESC;
+--------------------------+------------+
| TABLE_NAME               | TABLE_ROWS |
+--------------------------+------------+
| current_way_nodes        |    1559099 |
| way_nodes                |    1559099 |
| current_nodes            |    1477247 |
| nodes                    |    1477247 |
| node_tags                |     311751 |
| way_tags                 |     287585 |
| ways                     |     100007 |
| current_ways             |     100007 |
| changeset_tags           |      18738 |
| current_relation_members |      14560 |
| relation_members         |      14560 |
| changesets               |       9369 |
| relation_tags            |       3948 |
| current_relations        |        937 |
| relations                |        937 |
| users                    |        537 |
+--------------------------+------------+
16 rows in set (0.00 sec)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/openstreetmap-dataset/>

osmdb06.sql
===========

    Below is the schema described in the [OpenStreetMap Dataset Use](../openstreetmap-dataset-use/index) article. To use, copy everything in the box below into a file called '`osmdb06.sql`', then continue with the instructions.

 
```
-- phpMyAdmin SQL Dump
-- version 2.11.9.3
-- http://www.phpmyadmin.net
--
-- Хост: mysql.leonenko.info
-- Час стварэньня: 16 Сак 2009, 15:12
-- Вэрсія сэрвэра: 5.0.67
-- Вэрсія PHP: 5.2.6

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- База дадзеных: `osmapper_belarus`
--

-- --------------------------------------------------------

--
-- Структура табліцы `changesets`
--

DROP TABLE IF EXISTS `changesets`;
CREATE TABLE IF NOT EXISTS `changesets` (
  `id` bigint(20) NOT NULL auto_increment,
  `user_id` bigint(20) NOT NULL,
  `created_at` datetime NOT NULL,
  `min_lat` int(11) default NULL,
  `max_lat` int(11) default NULL,
  `min_lon` int(11) default NULL,
  `max_lon` int(11) default NULL,
  `closed_at` datetime NOT NULL,
  `num_changes` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=20103 ;

-- --------------------------------------------------------

--
-- Структура табліцы `changeset_tags`
--

DROP TABLE IF EXISTS `changeset_tags`;
CREATE TABLE IF NOT EXISTS `changeset_tags` (
  `id` bigint(64) NOT NULL,
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  KEY `changeset_tags_id_idx` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `current_nodes`
--

DROP TABLE IF EXISTS `current_nodes`;
CREATE TABLE IF NOT EXISTS `current_nodes` (
  `id` bigint(64) NOT NULL auto_increment,
  `latitude` int(11) NOT NULL,
  `longitude` int(11) NOT NULL,
  `changeset_id` bigint(20) NOT NULL,
  `visible` tinyint(1) NOT NULL,
  `timestamp` datetime NOT NULL,
  `tile` int(10) unsigned NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `current_nodes_timestamp_idx` (`timestamp`),
  KEY `current_nodes_tile_idx` (`tile`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=348816842 ;

-- --------------------------------------------------------

--
-- Структура табліцы `current_node_tags`
--

DROP TABLE IF EXISTS `current_node_tags`;
CREATE TABLE IF NOT EXISTS `current_node_tags` (
  `id` bigint(64) NOT NULL,
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `current_relations`
--

DROP TABLE IF EXISTS `current_relations`;
CREATE TABLE IF NOT EXISTS `current_relations` (
  `id` bigint(64) NOT NULL auto_increment,
  `changeset_id` bigint(20) NOT NULL,
  `timestamp` datetime NOT NULL,
  `visible` tinyint(1) NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `current_relations_timestamp_idx` (`timestamp`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=80283 ;

-- --------------------------------------------------------

--
-- Структура табліцы `current_relation_members`
--

DROP TABLE IF EXISTS `current_relation_members`;
CREATE TABLE IF NOT EXISTS `current_relation_members` (
  `id` bigint(64) NOT NULL,
  `member_type` enum('node','way','relation') NOT NULL default 'node',
  `member_id` bigint(11) NOT NULL,
  `member_role` varchar(255) NOT NULL default '',
  `sequence_id` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`,`member_type`,`member_id`,`member_role`,`sequence_id`),
  KEY `current_relation_members_member_idx` (`member_type`,`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `current_relation_tags`
--

DROP TABLE IF EXISTS `current_relation_tags`;
CREATE TABLE IF NOT EXISTS `current_relation_tags` (
  `id` bigint(64) NOT NULL,
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `current_ways`
--

DROP TABLE IF EXISTS `current_ways`;
CREATE TABLE IF NOT EXISTS `current_ways` (
  `id` bigint(64) NOT NULL auto_increment,
  `changeset_id` bigint(20) NOT NULL,
  `timestamp` datetime NOT NULL,
  `visible` tinyint(1) NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `current_ways_timestamp_idx` (`timestamp`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=31336923 ;

-- --------------------------------------------------------

--
-- Структура табліцы `current_way_nodes`
--

DROP TABLE IF EXISTS `current_way_nodes`;
CREATE TABLE IF NOT EXISTS `current_way_nodes` (
  `id` bigint(64) NOT NULL,
  `node_id` bigint(64) NOT NULL,
  `sequence_id` bigint(11) NOT NULL,
  PRIMARY KEY  (`id`,`sequence_id`),
  KEY `current_way_nodes_node_idx` (`node_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `current_way_tags`
--

DROP TABLE IF EXISTS `current_way_tags`;
CREATE TABLE IF NOT EXISTS `current_way_tags` (
  `id` bigint(64) NOT NULL,
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `diary_comments`
--

DROP TABLE IF EXISTS `diary_comments`;
CREATE TABLE IF NOT EXISTS `diary_comments` (
  `id` bigint(20) NOT NULL auto_increment,
  `diary_entry_id` bigint(20) NOT NULL,
  `user_id` bigint(20) NOT NULL,
  `body` text NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `diary_comments_entry_id_idx` (`diary_entry_id`,`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `diary_entries`
--

DROP TABLE IF EXISTS `diary_entries`;
CREATE TABLE IF NOT EXISTS `diary_entries` (
  `id` bigint(20) NOT NULL auto_increment,
  `user_id` bigint(20) NOT NULL,
  `title` varchar(255) NOT NULL,
  `body` text NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `latitude` double default NULL,
  `longitude` double default NULL,
  `language` varchar(3) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `friends`
--

DROP TABLE IF EXISTS `friends`;
CREATE TABLE IF NOT EXISTS `friends` (
  `id` bigint(20) NOT NULL auto_increment,
  `user_id` bigint(20) NOT NULL,
  `friend_user_id` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `user_id_idx` (`friend_user_id`),
  KEY `friends_user_id_idx` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `gps_points`
--

DROP TABLE IF EXISTS `gps_points`;
CREATE TABLE IF NOT EXISTS `gps_points` (
  `altitude` float default NULL,
  `trackid` int(11) NOT NULL,
  `latitude` int(11) NOT NULL,
  `longitude` int(11) NOT NULL,
  `gpx_id` bigint(64) NOT NULL,
  `timestamp` datetime default NULL,
  `tile` int(10) unsigned NOT NULL,
  KEY `points_gpxid_idx` (`gpx_id`),
  KEY `points_tile_idx` (`tile`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `gpx_files`
--

DROP TABLE IF EXISTS `gpx_files`;
CREATE TABLE IF NOT EXISTS `gpx_files` (
  `id` bigint(64) NOT NULL auto_increment,
  `user_id` bigint(20) NOT NULL,
  `visible` tinyint(1) NOT NULL default '1',
  `name` varchar(255) NOT NULL default '',
  `size` bigint(20) default NULL,
  `latitude` double default NULL,
  `longitude` double default NULL,
  `timestamp` datetime NOT NULL,
  `public` tinyint(1) NOT NULL default '1',
  `description` varchar(255) NOT NULL default '',
  `inserted` tinyint(1) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `gpx_files_timestamp_idx` (`timestamp`),
  KEY `gpx_files_visible_public_idx` (`visible`,`public`),
  KEY `gpx_files_user_id_idx` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `gpx_file_tags`
--

DROP TABLE IF EXISTS `gpx_file_tags`;
CREATE TABLE IF NOT EXISTS `gpx_file_tags` (
  `gpx_id` bigint(64) NOT NULL default '0',
  `tag` varchar(255) NOT NULL,
  `id` bigint(20) NOT NULL auto_increment,
  PRIMARY KEY  (`id`),
  KEY `gpx_file_tags_gpxid_idx` (`gpx_id`),
  KEY `gpx_file_tags_tag_idx` (`tag`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `messages`
--

DROP TABLE IF EXISTS `messages`;
CREATE TABLE IF NOT EXISTS `messages` (
  `id` bigint(20) NOT NULL auto_increment,
  `from_user_id` bigint(20) NOT NULL,
  `title` varchar(255) NOT NULL,
  `body` text NOT NULL,
  `sent_on` datetime NOT NULL,
  `message_read` tinyint(1) NOT NULL default '0',
  `to_user_id` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `messages_to_user_id_idx` (`to_user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `nodes`
--

DROP TABLE IF EXISTS `nodes`;
CREATE TABLE IF NOT EXISTS `nodes` (
  `id` bigint(64) NOT NULL,
  `latitude` int(11) NOT NULL,
  `longitude` int(11) NOT NULL,
  `changeset_id` bigint(20) NOT NULL,
  `visible` tinyint(1) NOT NULL,
  `timestamp` datetime NOT NULL,
  `tile` int(10) unsigned NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`,`version`),
  KEY `nodes_timestamp_idx` (`timestamp`),
  KEY `nodes_tile_idx` (`tile`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `node_tags`
--

DROP TABLE IF EXISTS `node_tags`;
CREATE TABLE IF NOT EXISTS `node_tags` (
  `id` bigint(64) NOT NULL,
  `version` bigint(20) NOT NULL,
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  PRIMARY KEY  (`id`,`version`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `relations`
--

DROP TABLE IF EXISTS `relations`;
CREATE TABLE IF NOT EXISTS `relations` (
  `id` bigint(64) NOT NULL default '0',
  `changeset_id` bigint(20) NOT NULL,
  `timestamp` datetime NOT NULL,
  `version` bigint(20) NOT NULL,
  `visible` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`id`,`version`),
  KEY `relations_timestamp_idx` (`timestamp`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `relation_members`
--

DROP TABLE IF EXISTS `relation_members`;
CREATE TABLE IF NOT EXISTS `relation_members` (
  `id` bigint(64) NOT NULL default '0',
  `member_type` enum('node','way','relation') NOT NULL default 'node',
  `member_id` bigint(11) NOT NULL,
  `member_role` varchar(255) NOT NULL default '',
  `version` bigint(20) NOT NULL default '0',
  `sequence_id` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`,`version`,`member_type`,`member_id`,`member_role`,`sequence_id`),
  KEY `relation_members_member_idx` (`member_type`,`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `relation_tags`
--

DROP TABLE IF EXISTS `relation_tags`;
CREATE TABLE IF NOT EXISTS `relation_tags` (
  `id` bigint(64) NOT NULL default '0',
  `k` varchar(255) NOT NULL default '',
  `v` varchar(255) NOT NULL default '',
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`,`version`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `schema_migrations`
--

DROP TABLE IF EXISTS `schema_migrations`;
CREATE TABLE IF NOT EXISTS `schema_migrations` (
  `version` varchar(255) NOT NULL,
  UNIQUE KEY `unique_schema_migrations` (`version`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `sessions`
--

DROP TABLE IF EXISTS `sessions`;
CREATE TABLE IF NOT EXISTS `sessions` (
  `id` int(11) NOT NULL auto_increment,
  `session_id` varchar(255) default NULL,
  `data` text,
  `created_at` datetime default NULL,
  `updated_at` datetime default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `sessions_session_id_idx` (`session_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

-- --------------------------------------------------------

--
-- Структура табліцы `users`
--

DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `email` varchar(255) NOT NULL,
  `id` bigint(20) NOT NULL auto_increment,
  `active` int(11) NOT NULL default '0',
  `pass_crypt` varchar(255) NOT NULL,
  `creation_time` datetime NOT NULL,
  `display_name` varchar(255) NOT NULL default '',
  `data_public` tinyint(1) NOT NULL default '0',
  `description` text NOT NULL,
  `home_lat` double default NULL,
  `home_lon` double default NULL,
  `home_zoom` smallint(6) default '3',
  `nearby` int(11) default '50',
  `pass_salt` varchar(255) default NULL,
  `image` text,
  `administrator` tinyint(1) NOT NULL default '0',
  `email_valid` tinyint(1) NOT NULL default '0',
  `new_email` varchar(255) default NULL,
  `visible` tinyint(1) NOT NULL default '1',
  `creation_ip` varchar(255) default NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `users_email_idx` (`email`),
  UNIQUE KEY `users_display_name_idx` (`display_name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=101442 ;

-- --------------------------------------------------------

--
-- Структура табліцы `user_preferences`
--

DROP TABLE IF EXISTS `user_preferences`;
CREATE TABLE IF NOT EXISTS `user_preferences` (
  `user_id` bigint(20) NOT NULL,
  `k` varchar(255) NOT NULL,
  `v` varchar(255) NOT NULL,
  PRIMARY KEY  (`user_id`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `user_tokens`
--

DROP TABLE IF EXISTS `user_tokens`;
CREATE TABLE IF NOT EXISTS `user_tokens` (
  `id` bigint(20) NOT NULL auto_increment,
  `user_id` bigint(20) NOT NULL,
  `token` varchar(255) NOT NULL,
  `expiry` datetime NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `user_tokens_token_idx` (`token`),
  KEY `user_tokens_user_id_idx` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

-- --------------------------------------------------------

--
-- Структура табліцы `ways`
--

DROP TABLE IF EXISTS `ways`;
CREATE TABLE IF NOT EXISTS `ways` (
  `id` bigint(64) NOT NULL default '0',
  `changeset_id` bigint(20) NOT NULL,
  `timestamp` datetime NOT NULL,
  `version` bigint(20) NOT NULL,
  `visible` tinyint(1) NOT NULL default '1',
  PRIMARY KEY  (`id`,`version`),
  KEY `ways_timestamp_idx` (`timestamp`),
  KEY `changeset_id` (`changeset_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `way_nodes`
--

DROP TABLE IF EXISTS `way_nodes`;
CREATE TABLE IF NOT EXISTS `way_nodes` (
  `id` bigint(64) NOT NULL,
  `node_id` bigint(64) NOT NULL,
  `version` bigint(20) NOT NULL,
  `sequence_id` bigint(11) NOT NULL,
  PRIMARY KEY  (`id`,`version`,`sequence_id`),
  KEY `way_nodes_node_idx` (`node_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Структура табліцы `way_tags`
--

DROP TABLE IF EXISTS `way_tags`;
CREATE TABLE IF NOT EXISTS `way_tags` (
  `id` bigint(64) NOT NULL default '0',
  `k` varchar(255) NOT NULL,
  `v` varchar(255) NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY  (`id`,`version`,`k`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Абмежаваньні для экспартаваных табліц
--

--
-- Абмежаваньні для табліцы `current_nodes`
--
ALTER TABLE `current_nodes`
  ADD CONSTRAINT `current_nodes_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `current_node_tags`
--
ALTER TABLE `current_node_tags`
  ADD CONSTRAINT `current_node_tags_ibfk_1` FOREIGN KEY (`id`) REFERENCES `current_nodes` (`id`);

--
-- Абмежаваньні для табліцы `current_relations`
--
ALTER TABLE `current_relations`
  ADD CONSTRAINT `current_relations_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `current_relation_members`
--
ALTER TABLE `current_relation_members`
  ADD CONSTRAINT `current_relation_members_ibfk_1` FOREIGN KEY (`id`) REFERENCES `current_relations` (`id`);

--
-- Абмежаваньні для табліцы `current_relation_tags`
--
ALTER TABLE `current_relation_tags`
  ADD CONSTRAINT `current_relation_tags_ibfk_1` FOREIGN KEY (`id`) REFERENCES `current_relations` (`id`);

--
-- Абмежаваньні для табліцы `current_ways`
--
ALTER TABLE `current_ways`
  ADD CONSTRAINT `current_ways_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `current_way_nodes`
--
ALTER TABLE `current_way_nodes`
  ADD CONSTRAINT `current_way_nodes_ibfk_2` FOREIGN KEY (`node_id`) REFERENCES `current_nodes` (`id`),
  ADD CONSTRAINT `current_way_nodes_ibfk_1` FOREIGN KEY (`id`) REFERENCES `current_ways` (`id`);

--
-- Абмежаваньні для табліцы `current_way_tags`
--
ALTER TABLE `current_way_tags`
  ADD CONSTRAINT `current_way_tags_ibfk_1` FOREIGN KEY (`id`) REFERENCES `current_ways` (`id`);

--
-- Абмежаваньні для табліцы `nodes`
--
ALTER TABLE `nodes`
  ADD CONSTRAINT `nodes_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `node_tags`
--
ALTER TABLE `node_tags`
  ADD CONSTRAINT `node_tags_ibfk_1` FOREIGN KEY (`id`, `version`) REFERENCES `nodes` (`id`, `version`);

--
-- Абмежаваньні для табліцы `relations`
--
ALTER TABLE `relations`
  ADD CONSTRAINT `relations_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `relation_members`
--
ALTER TABLE `relation_members`
  ADD CONSTRAINT `relation_members_ibfk_1` FOREIGN KEY (`id`, `version`) REFERENCES `relations` (`id`, `version`);

--
-- Абмежаваньні для табліцы `relation_tags`
--
ALTER TABLE `relation_tags`
  ADD CONSTRAINT `relation_tags_ibfk_1` FOREIGN KEY (`id`, `version`) REFERENCES `relations` (`id`, `version`);

--
-- Абмежаваньні для табліцы `ways`
--
ALTER TABLE `ways`
  ADD CONSTRAINT `ways_ibfk_1` FOREIGN KEY (`changeset_id`) REFERENCES `changesets` (`id`);

--
-- Абмежаваньні для табліцы `way_nodes`
--
ALTER TABLE `way_nodes`
  ADD CONSTRAINT `way_nodes_ibfk_1` FOREIGN KEY (`id`, `version`) REFERENCES `ways` (`id`, `version`);

--
-- Абмежаваньні для табліцы `way_tags`
--
ALTER TABLE `way_tags`
  ADD CONSTRAINT `way_tags_ibfk_1` FOREIGN KEY (`id`, `version`) REFERENCES `ways` (`id`, `version`);

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/osmdb06sql/>

Old Plans
==========

   This category contains plans that are no longer in active use, for older and current versions of MariaDB. For future plans, see [Plans](../development-plans/index).

  

| Title | Description |
| --- | --- |
|  [Plans for MariaDB 11.0](../plans-for-mariadb-11-0/index) |  Roadmap for MariaDB 11.0.  |
|  [Plans for MariaDB 10.11](../plans-for-mariadb-10-11/index) |  Roadmap for MariaDB 10.11.  |
|  [Plans for MariaDB 10.10](../plans-for-mariadb-10-10/index) |  Roadmap for MariaDB 10.10.  |
|  [Plans for MariaDB 10.9](../plans-for-mariadb-10-9/index) |  Roadmap for MariaDB 10.9.  |
|  [Plans for MariaDB 10.8](../plans-for-mariadb-108/index) |  Roadmap for MariaDB 10.8.  |
|  [Plans for MariaDB 10.7](../plans-for-mariadb-107/index) |  Roadmap for MariaDB 10.7.  |
|  [Plans for MariaDB 10.6](../plans-for-mariadb-106/index) |  Roadmap for MariaDB 10.6.  |
|  [Plans for MariaDB 10.5](../plans-for-mariadb-105/index) |  Roadmap for MariaDB 10.5.  |
|  [Plans for MariaDB 10.4](../plans-for-mariadb-104/index) |  Roadmap for MariaDB 10.4.  |
|  [Plans for 10.3](../plans-for-103/index) |  Plans for MariaDB 10.3.  |
|  [Plans for 10.1](../plans-for-101/index) |  Plans for MariaDB 10.1  |
|  [Plans for 5.6](../plans-for-56/index) |  The information on this page is obsolete. Current information can be found...  |
|  [MariaDB 5.3 TODO not](../mariadb-53-todo-not/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB 5.3 TODO](../mariadb-53-todo/index) |  Older version of this page can be found at mariadb-53-todo-not. Shortly b...  |
|  [MariaDB 5.2 TODO](../mariadb-52-todo/index) |  MariaDB 5.2 is an old release, and is no longer unsupported.  |
|  [MariaDB Developer Meeting - Athens](../mariadb-developer-meeting-athens/index) |  11-13 Nov 2011 - Notes and Plans from the Athens Developer meeting.  |
|  [Plugins & Storage Engines Summit for MySQL/MariaDB/Drizzle 2011](../plugins-storage-engines-summit-for-mysqlmariadbdrizzle-2011/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB Development Meeting - Lisbon](../mariadb-development-meeting-lisbon/index) |  11-13 Mar 2011 - Notes and Plans from the Lisbon Developer meeting.  |
|  [MariaDB Feature Backport](../mariadb-feature-backport/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB Online Backup](../mariadb-online-backup/index) |  MariaDB Online Backup  |
|  [Storage Engine Summit 2010](../storage-engine-summit-2010/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/old-plans/>

MariaDB Plans - Statistics and Monitoring
=========================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Notes from the Statistics and Monitoring group:

 * Strategic direction: Enterprise monitoring
	+ graphing and data aggregation tools, server monitoring, etc.
	+ customer has reported that Merlin is inadequate, should we enter into this market?

 * QA request: better EXPLAIN:
	+ required in order to debug performance issues in queries without knowing the query or the data;
	+ the customer will only provide EXPLAIN and SHOW output, we need to debug based on that;

 * QA request: PERSISTENT TABLE STATISTICS
	+ required to ensure repeatable query execution for InnoDB;
	+ may allow various statistics to be reported by the server regardless of engine;

 * U/C at Oracle: OPTIMIZER tracing spetrunia: report actual estimates, and all decisions of the optimizer, including why an index was \*not\* picked, etc.

 * Developed by Serg for [MariaDB 5.3](../what-is-mariadb-53/index): Phone Home todo: make a web page on mariadb.org showing the results from the data being collected; pstoev: do we need to allow people to run their own reporting servers;

 * Present in MySQL 5.5: Performance Schema
	+ what do we want to do with it, embrace it, extend it?
	+ or it is better to have more SHOW commands and INFORMATION\_SCHEMA tables?
	+ are going to use Facebook's user stats/index stats patch or create a PERFORMANCE\_SCHEMA-based solution?

 * FB request: log all SQL errors
	+ serg: possible via AUDIT plugin, must back-port audit infrastructure from MySQL 5.5

 * FB request: more options for controlling the slow query log
	+ sample one out of every N queries or transactions ; with N ~ 99
	+ filter queries based on rows examined, I/O performed, total lock wait time;

 * idea: collect statistics per query text, or normalized query text and report;

 * FB request: EXPLAIN the \*actual\* plan on a \*running\* statement; no progress indicators and numbers are needed;

 * request by community: progress bar for queries such as LOAD DATA and SELECT;
	+ something like SHOW PROGRESS PROCESSLIST ; SHOW QUERY PROGRESS;
	+ what numbers are to be reported? time to elapsed, time to completion, number of rows processed?
	+ how to estimate the total runing time of the query;

 * FB request: limit total temptable size on the server; Already available per-query, but per-server needed;

 * FB patch: Admission Control
	+ limit number of concurrently running queries per user;
	+ if all user queries are blocked, allow a few more queries to join;

 * Kurt: Integration with log watching tools
	+ alter log formats to make them compatible with tools;
	+ include logwatch mysql-specific config file in packages/distributions;

 * FB request: Better monitoring for replication:
	+ seconds\_behind\_master computation is incorrect, sometimes is zero
	+ a counter for the total number of bytes read by I/O thread that does not rotate on log rotation;
	+ "seconds behind real master" to report the actual time the slave I/O thread is behind;

 * community request: prevent full scans from running at all above a certain table size;
	+ is existing max-join-size variable sufficient or more granula control is needed?

 * FB patch: report the time spent in individual phases of query processing

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-plans-statistics-and-monitoring/>

MariaDB Feature Backport
========================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Some background
---------------

 If case you didn't know: 

 ### What features were in 6.0

 Features that were in 6.0 and that we can rescue from there and provide value for the users:

 * MRR+BKA
	+ There are known bugs in the implementation of MRR/InnoDB (but not in MRR/Maria or MRR/MyISAM) which has caused Oracle to request a patch that disables MRR/InnoDB, which SergeyP has given them this May.
	+ BKA itself was used by a customer with a proprietary engine, and also by NDB, so can be assumed tested.

  *note: unless said otherwise, by MRR we mean MRR and ICP, everywhere*

 * The first two batches of subquery optimizations:
* [MySQL Worklog #2980](https://dev.mysql.com/worklog/task/?id=2980): Subquery optimization: Semijoin
	+ [MySQL Worklog #3740](https://dev.mysql.com/worklog/task/?id=3740): Subquery optimization: Semijoin: Pull-out of inner tables
	+ [MySQL Worklog #3741](https://dev.mysql.com/worklog/task/?id=3741): Subquery optimization: Semijoin: Duplicate elimination strategy
	+ [MySQL Worklog #3750](https://dev.mysql.com/worklog/task/?id=3750): Subquery optimization: Semijoin: First-match strategy
	+ [MySQL Worklog #3751](https://dev.mysql.com/worklog/task/?id=3751): Subquery optimization: Semijoin: Inside-out strategy
* [MySQL Worklog #1110](https://dev.mysql.com/worklog/task/?id=1110): Subquery optimization: Materialization
* [MySQL Worklog #3985](https://dev.mysql.com/worklog/task/?id=3985): Subquery optimization: smart choice between semi-join and materialization

 * Semi-join optimizations, including semi-join materialization has issues:
	+ The "outer join and semi-join problem"
	+ The different-datatypes-comparison problem

 * Subquery optimizations rely on the following WLs to be present in the tree:
	+ [MySQL Worklog #4165](https://dev.mysql.com/worklog/task/?id=4165) Prepared statements: validation
	+ [MySQL Worklog #4166](https://dev.mysql.com/worklog/task/?id=4166) Prepared statements: automatic re-prepare

 ### Related unfinished 6.x tasks

 There are also unfinished tasks, in various degrees of public availability and readyness:

 * [MySQL Worklog #3485](https://dev.mysql.com/worklog/task/?id=3485): Subquery optimization: FROM (SELECT) (Evgen)
* [MySQL Worklog #4389](https://dev.mysql.com/worklog/task/?id=4389): Subquery optimizations: Make IN optimizations also handle EXISTS (Roy Lyseng)
* [MySQL Worklog #3830](https://dev.mysql.com/worklog/task/?id=3830): Subquery optimization: Materialization: Partial matching of tuples with NULL components (Timour)

 * [MySQL Worklog #4800](https://dev.mysql.com/worklog/task/?id=4800): Optimizer trace/debugger
* : (this is an utitlity task that might be useful for implementation of some of the other WLs. SergeyP has already ported it to MariaDB for such utility purposes, but its code is not ready for being pushed yet.

 ### Directions for improvement

 Some (but not all) of the following might be needed to make a well-rounded release:

 * [No WL]: Single table "UPDATE/DELETE one\_table WHERE subquery\_predicate"<br/>such query will not be executed by semi-join runtime. Ironically, multi-table UPDATE/DELETEs will be, so not multi-table UPDATEs may work faster than single-table.
* [MySQL Worklog #3341](https://dev.mysql.com/worklog/task/?id=3341): Subquery optimization: Shortcut the evaluation as soon as there is a match
* [MySQL Worklog #1117](https://dev.mysql.com/worklog/task/?id=1117): Subquery optimization: Avoid recalculating subquery if external fields have not changed
* [MySQL Worklog #4614](https://dev.mysql.com/worklog/task/?id=4614): Subquery optimization: Materialization: avoid double subquery materialization
* [MySQL Worklog #3490](https://dev.mysql.com/worklog/task/?id=3490): Subquery optimization: Subqueries and multiple columns comparison with ALL
* [MySQL Worklog #4690](https://dev.mysql.com/worklog/task/?id=4690): Insideout order for materialized non-semijoin subqueries at top-level of the WHERE
* [MySQL Worklog #3808](https://dev.mysql.com/worklog/task/?id=3808): Subquery optimization: Materialize and use as ranges for MRR scan of outer tables
* [MySQL Worklog #4245](https://dev.mysql.com/worklog/task/?id=4245): Subquery optimization: FirstMatch strategy for anti-semi-join
* [MySQL Worklog #3489](https://dev.mysql.com/worklog/task/?id=3489): Subquery optimization: Subquery and loose index scan
* [MySQL Worklog #4691](https://dev.mysql.com/worklog/task/?id=4691): Subqueries: No-startup-cost execution for SJ-Materialization-Scan
* [No WL#]: Support ORDER BY .. LIMIT clause within a subquery (a quite common user request).

 * [No WL]: Make the join optimizer take BKA into account

 Feature-wise plan for 5.4
-------------------------

 The following is the "Igor's list":

 
```
 1. MRR/ICP
 ---------------
 WL#2474: Batched range read handler functions
 WL#2475: Batched range read functions for MyISAM/InnoDB
 2. BKA
 ---------
 WL #2771: Usage of multi_read_range in nested loop join
 3. Metadata integrity
 -------------------------
 WL #4284 (bug #989): Transactional DDL locking
 WL#4165: Prepared statements: validation
 WL#4166: Prepared statements: automatic re-prepare
 4. Subqueries
 -----------------
 4.1 Materialization of non-correlated IN subqueries
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 WL #1110: Materialization
 WL #4614: Materialization: avoid double subquery materialization
 WL #4690: Insideout order for materialized non-semijoin subqueries at top-level  of the WHERE
 4.2. Semi-joins
 ~~~~~~~~~~~
 WL #3740: Subquery optimization: Semijoin: Pull-out of inner tables
 WL #3741: Subquery optimization: Semijoin: Duplicate elimination strategy
 WL #3750: Subquery optimization: Semijoin: Duplicate elimination strategy
 WL #3751: Subquery optimization: Semijoin: Inside-out strategy
 4.3. Smart choice between materialization and semi-join
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 WL #3985: Subquery optimization: smart choice between semi-join and
 materialization
 4.4. Derived tables
 ~~~~~~~~~~~~~~
 WL #3485: Subquery optimization: FROM (SELECT) 
 4.5. EXISTs convertible to IN
 ~~~~~~~~~~~~~~~~~~~~~~
 WL #4389: Make IN optimizations also handle EXISTS
 4.6. Materialization for non-correlated NOT IN subqueries
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 WL #3830: Materialization: Partial matching of tuples with NULL components
 
 4.7. Direct evaluation of subqueries with caching
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 WL #3341: Shortcut the evaluation as soon as there is a match
 WL #1117: Avoid recalculating subquery if external fields have not changed

```

[MySQL Worklog #4614](https://dev.mysql.com/worklog/task/?id=4614) and [MySQL Worklog #4690](https://dev.mysql.com/worklog/task/?id=4690) are considered droppable.

 Plan for action (committed)
---------------------------

 ### General considerations

 It seems to be infeasible to take mysql-6.0 and fix it until it has release quality. We'll have to do it other way around: start from mariadb-5.2 codebase and pull features to there, one by one. This process will be called "backport".

 ### Backport MRR/BKA (SergeyP)

 MRR/BKA has been there for longer time than other features and so is more stable and so is a natural candidate for the first step.

 Needed actions:

 * Backport MRR/BKA code
	+ According to Igor, code at SQL layer should be easy to move
	+ Code inside MyISAM and Maria should be easily movable
	+ TODO what to do about MRR/NDB? We need to get it to compile at least.
	+ The trickest engine is InnoDB/XtraDB
		- will need to take changes that we've made to InnoDB and apply them to XtraDB (TODO will Percona accept that? Or we'll have to maintain patches-to-patches?)
* We'll also need to fix the known MRR/InnoDB bugs

 After MRR has been pushed, it received a number of code cleanups, bugfixes, and interface adjustments (motivated by BKA and NDB/Falcon implementations). This means that there is no single MRR patch, instead one should go through revisions and cherry-pick MRR-related patches (one of the ways to narrow down the number of revisions: most (all?) MRR fixes were made by sergefp@mysql.com,

 with exception of this fix:

 
```
 2726 Guilhem Bichot    2009-03-13
      Fix for multiple symptoms sharing the same cause:
      BUG#42297 Maria: crash in multi-range-read code
      BUG#42298 Maria: SELECT with join returns no rows
      ...

```

In addition to backport, we need the following adjustments:

 * Let DS-MRR support clustered primary keys (needed when using BKA).
* ~~Remove conditions used for key access from the condition pushed to index (We sometimes get "Using index condition" where there was no "Using where")~~ Considered done as we're unable to find any examples for this.
* ~~Introduce a separate @@optimizer\_switch flag for turning on/out ICP.~~ DONE.
* Rename multi\_range\_read\_info\_const() to look like it is not a part of MRR interface

 All of the above is filed as [MWL#67](http://askmonty.org/worklog/?tid=67): <http://askmonty.org/worklog/Server-Sprint/index.pl?tid=67>

 #### Milestone BKA-1: BKA backported

 After the above is done, BKA will work in [MariaDB 5.2](../what-is-mariadb-52/index) codebase in the same way as it worked in MySQL 6.0, but without MRR/InnoDB bugs.

 ### Subquery optimization: Efficient NOT IN execution with NULL (Timour)

 Implement <http://askmonty.org/worklog/Server-Sprint/index.pl?tid=68>

 Plan for action (planned)
-------------------------

 ### Step: Take BKA into account in join optimizer (SergeyP or Igor)

 Implement this item

 * [No WL]: Make the join optimizer account for BKA.

 According to Igor:

 Within this milestone, assume a certain join\_cache\_level setting (it is likely the estimates will be so rough that it won't matter)

 TODO: clarify if this includes making the choice between doing MRR scan and then filesorting vs doing non-MRR scan but not having to sort.

 #### Milestone BKA-2: BKA with cost-based optimization

 After the above is done, we'll have MRR/BKA with cost-based optimization.

 ### Step: Subqueries, start: backport and bugfixing

 This step includes backporting all pushed 6.0's subquery optimizations and fixing open wrong-result or crash bugs, including addressing of these problems:

 * Semi-join optimizations, including semi-join materialization has issues:
	+ The "outer join and semi-join problem"
	+ The different-datatypes-comparison problem

 At the moment it seems the preferred course of action is to first fix the bugs and then backport.

 #### Milestone SUBQ-GET-ON-TRACK

 After the above is done, we'll be able to assume that we "got on track" with subquery development and will be able to proceed further in many directions.

 NOTE: it is not fully known what we'll discover when this milestone is reacheed. Perhaps, we'll discover that subquery cost model needs some adjustments (but there's always a way out, penalize all non-5.1 plans so that the 5.1 plan wins in near competitions and thus there are no regressions).

 ### Step: FROM subqueries

 After the semi-join subqueries are done, the biggest and most annoying gap in subquery optimizations will be poor FROM subquery handling. Thus, the next item is to take the available code for

 * [MySQL Worklog #3485](https://dev.mysql.com/worklog/task/?id=3485): Subquery optimization: FROM (SELECT)

 and finish that.

 #### Milestone SUBQ-FROM-SUBQUERIES

 * This milestone adds [MySQL Worklog #3485](https://dev.mysql.com/worklog/task/?id=3485).

 (is there really sense to have a linear plan that extends further than this? Let's reach this point and release?)

 ### Step: More subqueries 1

 This is a step that has high ROI, can be done more-or-less indepdendently of the other work, and doesn't require in-depth knowlege of new subquery code/features:

 * [MySQL Worklog #1117](https://dev.mysql.com/worklog/task/?id=1117): Subquery optimization: Avoid recalculating subquery if external fields have not changed

 this can be passed over to somebody who haven't worked with subquery code before.

 (note: this task has a natural extension: create and use a cache of external\_field\_values->subquery\_result mappings.

 Btw, certain nose-trunk databases do not seem to handle this case.

 ### Step: More subqueries 2

 Another separate, high-ROI item:

 * [MySQL Worklog #3341](https://dev.mysql.com/worklog/task/?id=3341): Subquery optimization: Shortcut the evaluation as soon as there is a match

 (TODO check if that's really that WL entry).

 (note: after "More subqueries #1/#2 we'll also need [MySQL Worklog #3830](https://dev.mysql.com/worklog/task/?id=3830) before we could count non-WHERE clause subqueries as covered).

 ### Step: Backport Metadata integrity code (Timour)

 Backport the following:

 
```
 WL #2771: Usage of multi_read_range in nested loop join
 3. Metadata integrity
 -------------------------
 WL #4284 (bug #989): Transactional DDL locking
 WL#4165: Prepared statements: validation
 WL#4166: Prepared statements: automatic re-prepare

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-feature-backport/>

Plans for 5.6
=============

    
The information on this page is obsolete. Current information can be found on the **[Plans for 10x](../plans-for-10x/index)** page.

 Also see the following blog posts:

 * <http://blog.mariadb.org/what-comes-in-between-mariadb-now-and-mysql-5-6/>

 * <http://blog.mariadb.org/explanation-on-mariadb-10-0/>

  The following is a list of features considered for 5.6.

 As soon as 5.3/5.5 is declared gamma we have to decode who will work on what features for 5.6. All features that has a designed developer who agrees to get the thing done in a given timeline will be considered as a 5.6 feature. Then we will also create a new kb page with the to-be-done features.

 The items below that have a name after them are already allocated to a developer.

 If you want to be part of developing any of these features, get [an account](http://kb.askmonty.org/v/about) and add your name after the feature you are interested in. You can also add new features to this list or to the [worklog](../worklog/index).

 [MariaDB 5.3](../what-is-mariadb-53/index)
------------------------------------------

 Features which will be in [MariaDB 5.3](../what-is-mariadb-53/index) (instead of waiting until 5.6 to add them).

 * Storage independent test suite (add to 5.3)
* OpenGIS: create required tables: GeometryColumns, related views. (Holyfoot) (move to 5.3)
* OpenGIS: stored procedure AddGeometryColumn (Holyfoot) (move to 5.3)

 [MariaDB 5.5](../what-is-mariadb-55/index)
------------------------------------------

 Features which will be in [MariaDB 5.5](../what-is-mariadb-55/index) (instead of waiting until 5.6 to add them).

 * Present in MySQL 5.5: Performance Schema
	+ what do we want to do with it, embrace it, extend it?
	+ or it is better to have more SHOW commands and INFORMATION\_SCHEMA tables?
	+ are going to use Facebook's user stats/index stats patch or create a PERFORMANCE\_SCHEMA-based solution? (MP + Percona)
	+ Not much we can do to improve it for 5.6

 * FB request: log all SQL errors (Holyfoot to do in 5.5); [MWL#177](http://askmonty.org/worklog/?tid=177)
* FB request: EXPLAIN the \*actual\* plan on a \*running\* statement; no progress indicators and numbers are needed; [MWL#182](http://askmonty.org/worklog/?tid=182) (In Progress) (spetrunia)
* Thread pool (Wlad) (5.5)
* Memory tables: VARCHAR and BLOB support (Have sponsor; Will be implemented for 5.5) (monty)
* Plugins by Sergey: INSTALL PLUGIN \* ([MWL#77](http://askmonty.org/worklog/?tid=77)) (done but not pushed) (will be in 5.5) (sergey)
* LGPL/BSD client library (MP) (done in 5.5)
	+ Need to build it outside the tree as a separate package that people can use

 
[MariaDB 5.6](../what-is-mariadb-56/index) Definite
----------------------------------------------------

 Features which will definitely be in [MariaDB 5.6](../what-is-mariadb-56/index)

 * FB request: Better monitoring for replication (FB has patch; MP will add) (kristian) (for 5.5 or 5.6)
* Aria: Concurrent UPDATE & DELETE. [MWL#235](http://askmonty.org/worklog/?tid=235) (Have partial sponsor) (monty) (will do before April)
* Aria: Segmented key cache for Aria (igor) (definitely before 5.7)
* Aria: Fast next not same (monty) (will be done for 5.6)
* From MySQL 5.6: Global transaction ID, so the slave state becomes recoverable, and facilitate automatic moving a slave to a new master across multi-level hierarchies.

 
[MariaDB 5.6](../what-is-mariadb-56/index) High Probability
------------------------------------------------------------

 Features which have a high probability of being in [MariaDB 5.6](../what-is-mariadb-56/index)

 * Performance: More scalable query cache under higher concurrency (Sanja) (maybe)
	+ Allow stale data (Sanja) (maybe)

 
[MariaDB 5.6](../what-is-mariadb-56/index) Rolling
---------------------------------------------------

 Features which will be added when they are ready.

 * Parameterized Views
* Percona patches (Monty & Sanja) (rolling feature)

 Will skip for 5.6
-----------------

 Features which will not be added to [MariaDB 5.6](../what-is-mariadb-56/index).

 * Community Request: prevent full scans from running at all above a certain table size;
	+ is existing `max-join-size` variable sufficient or more granula control is needed?
* Optimizer: Implement UNION ALL without usage of a temporary table (nice to have) (wait for sponsor)
* Federated: Generic query pushdown
* Federated: Apply it to federated
* Federated: Timour's old list of tasks (Timour)
* Table functions (Timour) (after 5.6)
* Refactoring: do\_select refactoring to remove if's and make each code group (like end\_select) smaller (small speedup and cleaner code)

 Uncategorized
-------------

 Features which have not been categorized into the above categories.

 ### OpenGIS compliance

 * OpenGIS: prefill the spatial\_ref\_sys table. (Holyfoot)
* OpenGIS: Add possible III-rd coordinate (Altitude). (Holyfoot)
* OpenGIS: Distance3D, related optimization.
* OpenGIS: Precise math coordinates instead of DOUBLE-s.

 ### GIS-Optimizer

 * optimize simple queries with Intersects(), Within, Distance()<X
* add Distance\_sphere() and the related optimization.

 ### Online operations

 * Extension to bigger datatype (var)char(n) (n+x)
* Online extension of any NUMERIC datatype ; Like ALTER tinyint -> smallint
* Extend ENUM done need more visibility
* Alter comment (Monty)
* Online Add and drop index (Drop is easy to implement MyISAM/ARIA)
* Online OPTIMIZE
* Online ANALYSE
* Add ALTER ONLINE TABLE (Done by Monty: Syntax added in 5.3; When ONLINE is used, one gets an error if the ALTER TABLE can't be done online)
* Look at patch for online backport sent to maria-developers

 ### COMPATIBILITY & USABILITY

 * Date & time embedded timezone (Need sponsor)
* IPV6 native type
	+ Functions ; Functions exists in public patch (MP)
	+ Datatype ;Old patch exists
* Extended timestamp > 2038
* 1M tables Information schema (MP will investigate)
* 1M users requirements
	+ Roles
* mysql.\* in any engine
* LOG tables in a log\_schema schema
* User Ldap Authentification like Drizzle
* Make openssl hash functions available for user. (Bank will sponsor)
* Query logging and summary per query [MWL#179](http://askmonty.org/worklog/?tid=179)
* Auditing for specific user (to general log)
* Flush and reload variables from my.cnf

 ### Replication

 * Replication filters, like `--replicate-do-db` and friends, need to be possible to change dynamically, without having to restart the server. Having to stop the slave should ideally also not be needed, but is less of a problem.
* Transactional storage of slave state, rather than file-based master.info and relay-log.info . So the slave can recover consistently after a crash.
* Support in global transaction ID for master\_pos\_wait()
* Hooks around rotation of the binlog, so user can configure shell commands when a new log is started and when it is ended. The command must be run asynchroneously, and get the old and new log file name as arguments.
* Reduce fsyncs from 3 to 1 in group commit with binary log ([MWL#164](http://askmonty.org/worklog/?tid=164))
* Parallel applying of binary log in slave ([MWL#169](http://askmonty.org/worklog/?tid=169))
* Replication APIs, as per [MWL#107](http://askmonty.org/worklog/?tid=107) (Needs sponsor)
	+ Most important [MWL#120](http://askmonty.org/worklog/?tid=120) and [MWL#133](http://askmonty.org/worklog/?tid=133), for obtaining and applying events.
	+ Then a mechanism for prioritizing transactions.
* Multi source (Slave can have multiple masters). [MWL#201](http://askmonty.org/worklog/?tid=201). There is a partial sponsorship for this already. (Monty and Kristian)

 ### Statistics and monitoring

 * Strategic direction: Enterprise monitoring
	+ graphing and data aggregation tools, server monitoring, etc.
	+ customer has reported that Merlin is inadequate, should we enter into this market? (MonYog, SkySQL, Percona, Oli Sennhauser, Open Query etc is doing tools)

 * QA request: better EXPLAIN (HIGH priority; MP; Spetrunia)
	+ required in order to debug performance issues in queries without knowing the query or the data;
	+ the customer will only provide EXPLAIN and SHOW output, we need to debug based on that; (need examples)
	+ Perhaps optimizer trace is what we need

 * QA request: engine independent PERSISTENT TABLE STATISTICS (Igor)
	+ required to ensure repeatable query execution for InnoDB;
	+ may allow various statistics to be reported by the server regardless of engine;
	+ able to simulate different sized tables

 * U/C at Oracle: OPTIMIZER tracing spetrunia: report actual estimates, and all decisions of the optimizer, including why an index was \*not\* picked, etc.
	+ want to change for 5.7

 * FB request: more options for controlling the slow query log [MWL#181](http://askmonty.org/worklog/?tid=181) (Holyfoot will check)
	+ sample one out of every N queries or transactions ; with N ~ 99 (Patch by FB; Will be changed to use AUDIT)
* idea: collect statistics per query text, or normalized query text and report;

 * request by community: progress bar for SELECT;
	+ how to estimate the total running time of the query;
	+ Percona has [support for this](http://www.mysqlperformanceblog.com/2011/03/13/percona-server-and-xtrabackup-weekly-news-march-12th)
	+ 5.3 has progress reporting for SHOW PROGRESS PROCESSLIST; SHOW QUERY PROGRESS; and LOAD DATA .
* FB request: limit total temptable size on the server (MP) [MWL#183](http://askmonty.org/worklog/?tid=183)

 * FB patch: Admission Control (MP) (seriously considered to be done) (wlad)
	+ limit number of concurrently running queries per user;
	+ if all user queries are blocked, allow a few more queries to join;

 * Integration with log watching tools
	+ alter log formats to make them compatible with tools;
	+ include logwatch mysql-specific config file in packages/distributions;

  **a counter for the total number of bytes read by I/O thread that does not rotate on log rotation;**  "seconds behind real master" to report the actual time the slave I/O thread is behind (MP will look into this)

 * FB patch: report the time spent in individual phases of query processing (MP)

 ### Optimizer

 * Put cost related constants into variables (will be done) (timour)
	+ Automatic tuning of cost constants for specific setup (SSD / TAPE)
* Make optimizer switch more user friendly (Sanja and Spetrunia) (will be done)
* Cost model cleanup (Don't assume things are B-trees) (timour)
	+ Consistent cost interface trough handler methods

 * Persistent data statistics (Igor)
* Grace HASH join (Need sponsor)
* Sort merge join (Need sponsor)
* Better item\_equal (Igor & Monty)
	+ missing item\_equal for ORDER BY and GROUP BY
* Less fetches of data pages.
	+ can use whenever you have many-to-many relationships between two tables
	+ use to try to minimize data access
	+ it's like INDEX INTERSECTION

 ### Performance:

 * Performance: Better multi CPU performance above 16 cores (Work with Intel)
* Performance: Predictive parser to replace yacc based ; 5 % speedup for simpler queries
* Performance: Faster WHERE (a,b) in ((1,2),(2,3)...huge list...) (customer request)
* Performance: Faster VIEW (Not open frm & parse query for every access); Speed up simple view handling 2x

 ### Aria

 * MIN/MAX indexes
* Index withing key pages to speed up lookup on compressed key pages.

 ### User friendly features

 * Better/safer upgrade (?)
* Better option files in distributions.
* UNIQUE CONSTRAINT for BLOB ([MWL#139](http://askmonty.org/worklog/?tid=139)) (medium)

 ### Other things

 * Enhance RQG to test for query correctness and performance on production workloads during upgrade ([MWL#178](http://askmonty.org/worklog/?tid=178)) (prototype done, need to get outside users to verify the code)

 ### Plugins by Sergey

 * Plugins by Sergey: query rewrite ([MWL#144](http://askmonty.org/worklog/?tid=144))
* Plugins by Sergey: full-text search engine plugin ([MWL#143](http://askmonty.org/worklog/?tid=143))
* Plugins by Sergey: Plugin Loader ([MWL#162](http://askmonty.org/worklog/?tid=162))
* Plugins by Sergey: smaller, nice to have, tasks:
	+ show plugins soname ... ([MWL#80](http://askmonty.org/worklog/?tid=80))
	+ mutex/condition service ([WL#83](http://askmonty.org/worklog/?tid=83))
	+ duplicate plugin names ([MWL#79](http://askmonty.org/worklog/?tid=79))
	+ create a charset service ([MWL#81](http://askmonty.org/worklog/?tid=81))

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-56/>

MariaDB Plans - Online Operations
=================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Notes from the Online Operations team.

 Extention to bigger datatype

 (var)char(n) (n+x)

 numerique (datatype >)

 Extend ENUM done need more visibility

 Alter comment

 Add and drop index

 OPTIMIZE

 ANALYSE

 COMPATIBILITY & USABILITY

 Date & time embeded timezone

 IPV6

 Fonctions

 Datatype

 Extended timestamp > 2038

 1M tables Information schema

 mysql.\* in any engine

 1M users requirements

 LOG tables in a log\_schema schema

 User Ldap Authentification like Drizzle

 Link against openssl

 Query logging tracking per user

 flush and reload variables from my.cnf

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-plans-online-operations/>

Plans for MariaDB 11.0
======================

    [MariaDB 11.0](../what-is-mariadb-11-0/index) is stable, so no new features will be added. See [Plans for MariaDB 10.11](../plans-for-mariadb-11-1/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2811.0%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 11.0. It shows all tasks with the **Fix-Version** being 11.0. Not all these tasks will really end up in 11.0 but tasks with the "red" priorities have a much higher chance of being done in time for 11.0. Practically, you can think of these tasks as "features that **will** be in 11.0". Tasks with the "green" priorities probably won't be in 11.0. Think of them as "bonus features that would be **nice to have** in 11.0".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 11.0](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.0)%20ORDER%20BY%20priority%20DESC)
* [11.0 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.0)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 11.0?](../what-is-mariadb-11-0/index)
* [What is MariaDB 10.11?](../what-is-mariadb-10-11/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-11-0/>

MariaDB Plans - Replication
===========================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  We are discussing points for the replication part of the MariaDB roadmap.

 So far discussed:

 * ~~Replication filters, like --replicate-do-db and friends, need to be possible to change dynamically, without having to restart the server. Having to stop the slave should ideally also not be needed, but is less of a problem.~~ (complete)

 * ~~Transactional storage of slave state, rather than file-based master.info and relay-log.info . So the slave can recover consistently after a crash.~~ (complete)

 * ~~Global transaction ID, so the slave state becomes recoverable, and facilitate automatic moving a slave to a new master across multi-level hierarchies.~~ (complete)

 * ~~Support in global transaction ID for master\_pos\_wait()~~ (complete)

 * Hooks around rotation of the binlog, so user can configure shell commands when a new log is started and when it is ended. The command must be run asynchroneously, and get the old and new log file name as arguments.

 * Sending of heartbeats from master to slaves, so slaves starting up can know in finite time where the master is.

 * Replication APIs, as per [MWL#107](http://askmonty.org/worklog/?tid=107)
	+ Most important [MWL#120](http://askmonty.org/worklog/?tid=120) and [MWL#133](http://askmonty.org/worklog/?tid=133), for obtaining and applying events.
	+ Then a mechanism for prioritising transactions.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-plans-replication/>

Plans for MariaDB 10.8
======================

    [MariaDB 10.8](../what-is-mariadb-108/index) is stable, so no new features will be added. See [Plans for MariaDB 10.9](../plans-for-mariadb-109/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.7%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.8. It shows all tasks with the **Fix-Version** being 10.8. Not all these tasks will really end up in 10.8 but tasks with the "red" priorities have a much higher chance of being done in time for 10.8. Practically, you can think of these tasks as "features that **will** be in 10.8". Tasks with the "green" priorities probably won't be in 10.8. Think of them as "bonus features that would be **nice to have** in 10.8".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.8](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.8)%20ORDER%20BY%20priority%20DESC)
* [10.8 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.8)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.7?](../what-is-mariadb-107/index)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-108/>

Plans for MariaDB 10.5
======================

    [MariaDB 10.5](../what-is-mariadb-105/index) is stable, so no new features will be added. See [Plans for MariaDB 10.6](../plans-for-mariadb-106/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.5%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.5. It shows all tasks with the **Fix-Version** being 10.5. Not all these tasks will really end up in 10.5, but tasks with the "red" priorities have a much higher chance of being done in time for 10.5. Practically, you can think of these tasks as "features that **will** be in 10.5". Tasks with the "green" priorities probably won't be in 10.5. Think of them as "bonus features that would be **nice to have** in 10.5".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.5](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.5)%20ORDER%20BY%20priority%20DESC)
* [10.5 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.5)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.5?](../what-is-mariadb-105/index)
* [What is MariaDB 10.4?](../what-is-mariadb-104/index)
* [What is MariaDB 10.3?](../what-is-mariadb-103/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-105/>

Plugins & Storage Engines Summit for MySQL/MariaDB/Drizzle 2011
===============================================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Continuing the tradition of having a storage engine summit (see notes from [2010](../storage-engine-summit-2010/index)) after the [O'Reilly MySQL Conference](http://en.oreilly.com/mysql2011), this year it has been decided that the focus of the summit to be expanded. 

 Location
========

 The Facebook Campus, 1601 S. California Ave. Palo Alto, CA 94304.

 For directions, use Google Maps. However, if you're at the O'Reilly MySQL Conference, you can take the light rail from the conference center to Mountain View and then Caltrain from Mountain View to the California Ave exit and then walk 1 mile to the Facebook campus.

 Date and Time
=============

 April 15 2011, from 10am - 4pm. Lunch will be served, courtesy of Facebook.

 Target Audience
===============

 Developers who are writing storage engines and plugins, knowing the plugin architecture of either MySQL, the extensions in MariaDB as well as the differences in Drizzle. User defined function (UDF) writers are welcome too.

 Its expanded from just an invited audience of MySQL storage engine vendors this year.

 Seats are limited to **twenty-four (24)** attendees.

 Who's Attending
===============

 If you're attending, **this is the signup form!** Please fill up your name, email address, company, and any other contact information you may have (like Facebook, Twitter). You will need to login to the Knowledgebase (OpenID login is available).

 1. Michael "Monty" Widenius, monty at askmonty dot org, Monty Program Ab
2. Sergei Golubchik, serg at askmonty dot org, Monty Program Ab
3. Colin Charles, colin at montyprogram dot com, Monty Program Ab, [@bytebot](http://twitter.com/bytebot), [fb:bytebot](http://www.facebook.com/bytebot)
4. Zardosht Kasheff, zardosht at gmail dot com, Tokutek
5. Mark Callaghan, mdcallag at gmail dot com, Facebook
6. Paul McCullagh, paul dot mccullagh at primebase dot org, PrimeBase
7. Konstantin Osipov, kostja dot osipov at gmail dot com, Mail.Ru
8. Oleksandr "Sanja" Byelkin, sanja at askmonty dot org, Monty Program Ab
9. Bradley C. Kuszmaul, bradley@tokutek.com, Tokutek
10. Felix Schupp, felix.schupp@softmethod.de, BlackRay Data Engine, [fb:fschupp](http://facebook.com/fschupp)
11. Hartmut Holzgraefe, hartmut@php,net
12. Timour Katchaounov, timour at askmonty dot org, Monty Program Ab
13. praburam upendran, ramu@scaledb.com, scaledb
14. Rich Kelm, richard at sphinxsearch dot com, Sphinx Search
15. Antony T Curtis, atcurtis at gmail dot com, [Blizzard Entertainment](http://blizzard.com/) and [Open Query](http://openquery.com).
16. Daijiro MORI, morita at razil dot jp, Brazil Inc.
17. Tasuku SUENAGA, a at razil dot jp, Brazil Inc.
18. Kentoku SHIBA, kentokushiba at gmail dot com, WildGrowth
19. Peter Zaitsev, peter at percona dot com, Percona
20. Vadim Tkachenko, vadim at percona dot com, Percona
21. Louis Fahrberger, louis.fahrberger at infobright dot com, Infobright
22. Sergey Petrunya, psergey at askmonty.org, Monty Program Ab
23. Serge Frezefond
24. Igor Babaev, igor at askmonty.org Monty Program Ab
25. Volker Oboda, PrimeBase
26. Jeff Rothschild, Facebook
27. Rasmus Johansson, Monty Program Ab
28. Moshe Shadmon, ScaleDB
29. Chip Turner, Facebook
30. Domas Mituzas, Facebook/Wikipedia

 Notes
=====

 Linking with the Storage Engine Advisory Board at Oracle
========================================================

 Volker Odoba - member of the storage engine advisory board at Oracle

 * an explanation from Oracle as to why/if/when Oracle will take patches to extend the storage engine layer from the community
* its been mentioned that you might have to pay to be on the advisory board (i.e. you must be a customer)
* next meeting is at Oracle OpenWorld in October
* Schooner, Primebase, InnoDB, Infobright, Kickfire was there (now no longer since they do not exist)

 Topics
======

 * HBase storage engine layer to work with dynamic columns
* Discovery (Shared metadata)
* Materialised views
* Online ALTER TABLE
* Parallel replication (not SE, but a related topic)
* Group commit
* Parallel execution
* Fulltext search for every storage engine
* Cross-engine Online Backup
* Finish off server definition interface for FederatedX. Make it generic enough so that Spider can also use it.
* Pluggable data types
* Indexing/Dynamic Functions
* Fast load

 HBase by Chip Turner
--------------------

 Distributed key value store. Single index on a given table. Distributed servers each serving a row, multiple rows. Lexicographically sorted. No C API, there's a proxy API and Chip is fixing that now. Current protocol is serialized Java. Eventually each HBase server will speak Thrift. See <http://wiki.apache.org/hadoop/Hbase/ThriftApi> and <http://incubator.apache.org/thrift/>

 Index Condition Pushdown and MRR are useful here.

 Messages is a HBase application.

 Index Condition Pushdown
------------------------

 * idx\_cond\_push()
* opt\_index\_condition\_pushdown.cc
* EXPLAIN will say Using index condition
* Don't copy HA\_NDBCLUSTER::COND\_PUSH() since it is not done in a seinsble way. Much smarter implementations are possible with easy code - psergey
* This will be continued in discussion via email (sphinx, infobright, tokutek, spider, oqgraph)
	+ TODO: Timour will create a Worklog entry and involve appropriate attendees

 Discovery
---------

 Cluster with many MySQL servers connected to it. It was originally designed for MySQL Cluster. 

 * TODO: Serg to write an explanation here. Session led by him.

 Loadable Indexes
----------------

 * TODO: Paul, Kentoku, Richard, and Serg to discuss further
* Fulltext search
* Dynamic indexing method to existing storage engines are required. Do you want to store the data and index in the engine? It is not necessary (Kentoku). Want to implement just an index, not a storage engine. Storage format might be completely different.
* Practical use of having indexes for all engines? GIS.

 Parallel Execution
------------------

 * Read in two threads, will that be a problem for the storage engine? Two handlers within the same transaction ID calling in. Could just be a switch for the storage engine. Same THD in two different threads.

 Online Backup
-------------

 * Status hasn't changed since last year after Oracle cancelled it. No work has been done on this.
* Needs about 6 months sponsorship of one person's salary to get such a feature enabled
* Mark doesn't like running hot backup in the server and thinks its not generally a good idea. He prefers using xtrabackup, a separate process from the server. xtrabackup is a transactional log reader (Domas has joined us and is now enlightening everyone on xtrabackup features).
	+ Replication team and this meeting are the only folk that ask for this
* MyISAM has implemented backups twice now, and it has never made it outside
* Focus on what will gain you traction. Look on Percona Server. It just focuses on what customers want.

 Pluggable/abstract data types
-----------------------------

 * UUID, IPv4/IPv6 address, complex numbers, etc.

 Online ALTER
------------

 * Zardosht has an example from MySQL Cluster. He likes the implementation in MySQL Cluster 7.1. They have a different alter table API, and they've ported this to TokuDB with support for MySQL 5.1 and [MariaDB 5.1](../what-is-mariadb-51/index)/5.2.
* Wait and see the work that Oracle is doing?
* Old 6.0.3 - online alter and metadata alter - serg checked
* Zardosht's patch will work with [MariaDB 5.3](../what-is-mariadb-53/index), but once there's [MariaDB 5.5](../what-is-mariadb-55/index) based on MySQL 5.5 he's terribly worried about porting

 Group commit
------------

 * See slides for Monty+Kristian's talk

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plugins-storage-engines-summit-for-mysqlmariadbdrizzle-2011/>

Plans for 10.1
==============

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  We manage our development plans in Jira. [This search](https://mariadb.atlassian.net/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.1.0%2C+10.1%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.1. It shows all tasks with the **Fix-Version** being 10.1. Not all these tasks will really end up in 10.1, but tasks with the "red" priorities (![jira-priority-blocker] probably won't be in 10.1. Think of them as "bonus features that would be **nice to have** in 10.1". Although, as you can see, some of these tasks are already Closed, that is, they are already in 10.1.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-101/>

Plans for MariaDB 10.11
=======================

    [MariaDB 10.11](../what-is-mariadb-1011/index) is stable, so no new features will be added. See [Plans for MariaDB 11.1](../plans-for-mariadb-11-1/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.11%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.11. It shows all tasks with the **Fix-Version** being 10.11. Not all these tasks will really end up in 10.11 but tasks with the "red" priorities have a much higher chance of being done in time for 10.11. Practically, you can think of these tasks as "features that **will** be in 10.11". Tasks with the "green" priorities probably won't be in 10.11. Think of them as "bonus features that would be **nice to have** in 10.11".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.11](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.11)%20ORDER%20BY%20priority%20DESC)
* [10.11 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.11)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.11?](../what-is-mariadb-1011/index)
* [What is MariaDB 10.10?](../what-is-mariadb-1010/index)
* [What is MariaDB 10.9?](../what-is-mariadb-109/index)
* [What is MariaDB 10.8?](../what-is-mariadb-108/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-10-11/>

Plans for MariaDB 10.10
=======================

    [MariaDB 10.10](../what-is-mariadb-1010/index) is stable, so no new features will be added. See [Plans for MariaDB 10.11](../plans-for-mariadb-1011/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.10%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.10. It shows all tasks with the **Fix-Version** being 10.10. Not all these tasks will really end up in 10.10 but tasks with the "red" priorities have a much higher chance of being done in time for 10.10. Practically, you can think of these tasks as "features that **will** be in 10.10". Tasks with the "green" priorities probably won't be in 10.10. Think of them as "bonus features that would be **nice to have** in 10.10".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.10](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.10)%20ORDER%20BY%20priority%20DESC)
* [10.10 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.10)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.10?](../what-is-mariadb-1010/index)
* [What is MariaDB 10.9?](../what-is-mariadb-109/index)
* [What is MariaDB 10.8?](../what-is-mariadb-108/index)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-10-10/>

Plans for MariaDB 10.9
======================

    [MariaDB 10.9](../what-is-mariadb-109/index) is stable, so no new features will be added. See [Plans for MariaDB 10.11](../plans-for-mariadb-1011/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.9%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.9. It shows all tasks with the **Fix-Version** being 10.9. Not all these tasks will really end up in 10.9 but tasks with the "red" priorities have a much higher chance of being done in time for 10.9. Practically, you can think of these tasks as "features that **will** be in 10.9". Tasks with the "green" priorities probably won't be in 10.9. Think of them as "bonus features that would be **nice to have** in 10.9".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.9](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.9)%20ORDER%20BY%20priority%20DESC)
* [10.9 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.9)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.9?](../what-is-mariadb-109/index)
* [What is MariaDB 10.8?](../what-is-mariadb-108/index)
* [What is MariaDB 10.7?](../what-is-mariadb-107/index)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-10-9/>

Plans for MariaDB 10.7
======================

    [MariaDB 10.7](../what-is-mariadb-107/index) is stable, so no new features will be added. See [Plans for MariaDB 10.8](../plans-for-mariadb-108/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.7%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.7. It shows all tasks with the **Fix-Version** being 10.7. Not all these tasks will really end up in 10.7 but tasks with the "red" priorities have a much higher chance of being done in time for 10.7. Practically, you can think of these tasks as "features that **will** be in 10.7". Tasks with the "green" priorities probably won't be in 10.7. Think of them as "bonus features that would be **nice to have** in 10.7".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.7](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.7)%20ORDER%20BY%20priority%20DESC)
* [10.7 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.7)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.7?](../what-is-mariadb-107/index)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)
* [What is MariaDB 10.5?](../what-is-mariadb-105/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-107/>

Plans for MariaDB 10.6
======================

    [MariaDB 10.6](../what-is-mariadb-106/index) is stable, so no new features will be added. See [Plans for MariaDB 10.7](../plans-for-mariadb-107/index) instead.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.6%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.6. It shows all tasks with the **Fix-Version** being 10.6. Not all these tasks will really end up in 10.6 but tasks with the "red" priorities have a much higher chance of being done in time for 10.6. Practically, you can think of these tasks as "features that **will** be in 10.6". Tasks with the "green" priorities probably won't be in 10.5. Think of them as "bonus features that would be **nice to have** in 10.6".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 10.6](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.6)%20ORDER%20BY%20priority%20DESC)
* [10.6 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.6)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.6?](../what-is-mariadb-106/index)
* [What is MariaDB 10.5?](../what-is-mariadb-105/index)
* [What is MariaDB 10.4?](../what-is-mariadb-104/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-106/>

Plans for MariaDB 10.4
======================

    
"[What is MariaDB 10.4](../what-is-mariadb-104/index)" shows all features already implemented for 10.4.

 
[MariaDB 10.4](../what-is-mariadb-104/index) is stable, so no new features will be added to 10.4. See [Plans for MariaDB 10.5](../plans-for-mariadb-105/index) instead.

 Planning for 10.4 began at the 2017 MariaDB Developer's Unconference in Shenzhen, and further discussions were held at the 2018 Developers Unconference in New York. The features below were considered for inclusion in [MariaDB 10.4](../what-is-mariadb-104/index).

 Very Likely
-----------

 ### Better Security

 * Automatic DOS attacks detection - MariaDB Corporation
* Automatic password crack detection - MariaDB Corporation
* Encryption on client side - MariaDB Corporation
* Password expiration - MariaDB Foundation
* Multiple authentication plugins per user - MariaDB Foundation
* Socket authentication by default ([MDEV-12484](https://jira.mariadb.org/browse/MDEV-12484)) - MariaDB Foundation
* Encryption plugin (Tencent Cloud)
* Column encryption (Tencent Cloud)

 ### Compatibility

 * Oracle stage 2 ([MDEV-10872](https://jira.mariadb.org/browse/MDEV-10872))
* CONNECT BY - Alibaba Cloud, MariaDB Corporation & MariaDB Foundation
* MSSQL (?)

 ### Spider

 * Spider (10.4 patches) - Kentoku & MariaDB Corporation
* Tencent Spider patches (10 patches)
* Vertical partitioning - Kentoku

 ### Distributed Storage Engine (stage 1 of 4)

 * Write scaling
* Planning to be done in November-December

 ### InnoDB

 * Instant drop column etc. ([MDEV-15562](https://jira.mariadb.org/browse/MDEV-15562)) - MariaDB Corporation
* Better redo log ([MDEV-14425](https://jira.mariadb.org/browse/MDEV-14425)) - MariaDB Corporation & Tencent Cloud

 ### Performance

 * Micro optimization ([MDEV-7941](https://jira.mariadb.org/browse/MDEV-7941)) - MariaDB Foundation (Svoj)
* Scalability issues - MariaDB Foundation (Svoj) & IBM
* Moving blocks without using any L? cache (Svoj and Monty)
* [MDEV-7487](https://jira.mariadb.org/browse/MDEV-7487) - semi-join optimisations - (MariaDB Corporation)
* Aggregation on the server (Tencent Cloud)
* GROUP INSERT (Alibaba Cloud)

 ### Re-Entrant Items

 * Building block for parallel query and be able to share stored procedures between threads (Stored procedure cache)
* Reading and updating my.cnf from server - MariaDB Corporation

 ### Other

 * Galera 4 - Codership
* MySQL syntax for multi source (CHANNEL) - Alibaba Cloud
* Updates to MyRocks - MariaDB Corporation & Facebook
* Reverse privileges - MariaDB Foundation
* BLOB & optimized VARCHAR for memory tables - MariaDB Corporation (Greatly reduces memory for internal temporary tables)

 Rolling Features
----------------

 ### Backup

 * Backup from the server through storage engine API, patch for mariabackup (MariaDB Corporation and Alibaba)

 ### Columnstore

 * Columnstore integration (MariaDB Corporation)

 ### Replication

 * GTID in OK Packet ([MDEV-11956](https://jira.mariadb.org/browse/MDEV-11956)) - MariaDB Corporation

 ### Optimizer

 * Better ORDER BY LIMIT Optimization ([MDEV-8306](https://jira.mariadb.org/browse/MDEV-8306)) - MariaDB Corporation
* Optimizer trace ([MDEV-6111](https://jira.mariadb.org/browse/MDEV-6111)) - MariaDB Corporation
* Better histograms ([MDEV-12313](https://jira.mariadb.org/browse/MDEV-12313)) - [Google Summer of Code project](../google-summer-of-code-2018/index)
* Prefiltering - MariaDB Corporation (Igor)
* Better telemetry ???
* Improve single-thread CPU performance ???

 ### Other

 * Virtual host in protocol - Microsoft(?)
* Index on expression - MariaDB Corporation
* Pattern matching for keys
* Downscaling memory on demand/request - MariaDB Corporation (?)
	+ Closing not used connections
	+ Reducing buffer-pool and key caches
	+ Flush all internal caches
* Parallel replication of one table - Tencent Cloud
	+ Depending on benchmark results
* TIMESTAMP with timezone support ([MDEV-7928](https://jira.mariadb.org/browse/MDEV-7928)) - Seth(?)
* Implement all window function features - [MDEV-12987](https://jira.mariadb.org/browse/MDEV-12987), [MDEV-6115](https://jira.mariadb.org/browse/MDEV-6115)
* Remove the need to use comments for configuration (MariaDB Corporation)
* Remotely provision slaves (?)

 Other Activities Overlapping with 10.4 Release
----------------------------------------------

 * Allow community builds - MariaDB Foundation (Vicentiu)
* Docker - MariaDB Foundation (Vicentiu)
* Staging trees - MariaDB Foundation (Vicentiu)
* Python Connector - MariaDB Foundation (Vicentiu)
* Query characteristics being returned to Connector (MariaDB Corporation)
* Reduce the number of open MDEVs (?)

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.4%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.4. It shows all tasks with the **Fix-Version** being 10.4. Not all these tasks will really end up in 10.4, but tasks with the "red" priorities have a much higher chance of being done in time for 10.4. Practically, you can think of these tasks as "features that **will** be in 10.4". Tasks with the "green" priorities probably won't be in 10.4. Think of them as "bonus features that would be **nice to have** in 10.4". 

 See Also
--------

 * [Current tasks for 10.4](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.4)%20ORDER%20BY%20priority%20DESC)
* [10.4 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.4)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 10.4?](../what-is-mariadb-104/index)
* [What is MariaDB 10.3?](../what-is-mariadb-103/index)
* [What is MariaDB 10.2?](../what-is-mariadb-102/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-104/>

Plans for 10.3
==============

    
No new features will be added to [MariaDB 10.3](../what-is-mariadb-103/index). If you wish to contribute new features to the latest development release, see [Plans for MariaDB 10.5](../plans-for-mariadb-105/index).

 
"[What is MariaDB 10.3](../what-is-mariadb-103/index)" shows all features implemented for 10.3.

 [MariaDB 10.3](../what-is-mariadb-103/index)
--------------------------------------------

 The following features were discussed at the 2016 MariaDB Developer's Meeting for consideration in [MariaDB 10.3](../what-is-mariadb-103/index). See [Thoughts on MariaDB Server 10.3 from MariaDB Developers Meeting in Amsterdam, part 1](https://mariadb.org/thoughts-mariadb-server-10-3-mariadb-developers-meeting-amsterdam-part-1/).

 * Hidden Columns
* Long unique constraints
* SQL based CREATE AGGREGATE FUNCTION
* Now it looks like one step ahead has been made with the implementation of a Pluggable Data Type API. It still exists in a separate branch, but it is now planned for inclusion in MariaDB Server 10.3. On top of the API the idea is to build User Defined Types according to the SQL Standard.
* Better support for CJK (Chinese, Japanese, and Korean) languages. The idea is to include the ngram full-text parser and MeCab full-text parser plugins. Also the GB 18030 standard for Chinese charsets is on the radar for 10.3.
* On the storage engine side MyRocks will be included in 10.2, which will open MyRocks to a wider audience. It’s obvious that it will need work during 10.3 timeframe to grow in maturity. Another interesting storage engine discussed during the last few years is Spider, an engine that provides a sharding solution for databases. Although Spider already exists in MariaDB Server, there is a set of patches that needs to be incorporated on the server side to improve functionality and performance. These patches can be found in [MDEV-7698](https://jira.mariadb.org/browse/MDEV-7698).

 ### InnoDB

 * In MySQL 8.0 there are a couple of interesting new features for InnoDB that are interesting for MariaDB as well. The timelines of 10.3 and 8.0 will partially determine whether these will be in 10.3.
* InnoDB deadlock detect
* The new information schema table.
* Lock wait policy
* Persistent autoincrement

 ### Compatibility

 * Support for SEQUENCE
* Addition of a PL/SQL parser
* Support for INTERSECT
* Support for EXCEPT

 ### JIRA

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2810.3.0%2C+10.3%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 10.3. It shows all tasks with the **Fix-Version** being 10.3. Not all these tasks will really end up in 10.3, but tasks with the "red" priorities have a much higher chance of being done in time for 10.3. Practically, you can think of these tasks as "features that **will** be in 10.3". Tasks with the "green" priorities probably won't be in 10.3. Think of them as "bonus features that would be **nice to have** in 10.3". 

 See Also
--------

 * [Current tasks for 10.3](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(10.3.0%2C%2010.3)%20ORDER%20BY%20priority%20DESC)
* [10.3 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20fixVersion%20%3D%2010.3%20ORDER%20BY%20votes%20DESC)
* [What is MariaDB 10.3?](../what-is-mariadb-103/index)
* [What is MariaDB 10.2?](../what-is-mariadb-102/index)
* [What is MariaDB 10.1?](../what-is-mariadb-101/index)
* [What is MariaDB 10.0?](../what-is-mariadb-100/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-103/>

MariaDB 5.3 TODO not
====================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  This page lists things that were in plans for [MariaDB 5.3](../what-is-mariadb-53/index) but were not included after all. For the actual list of things that are still needed before 5.3 release, see [mariadb-53-todo](../mariadb-53-todo/index)

 Specific goals
==============

 Top-level worklog for all tasks: [MWL#91](http://askmonty.org/worklog/?tid=91)

 TODO per person before 5.3 can go beta
======================================

 Sergey Petrunya
---------------

 In priority order:

 Timour Katchaounov
------------------

 ### Optional tasks

 * Possibly: MWL#?? Remove double materialization in materialized subqueries ;In 5.5
* New tasks (moved from [MWL#89](http://askmonty.org/worklog/?tid=89)):
	+ implement robust expensive predicate handling (is\_expensive), possibly in a separate task
* performance tuning for all WL

 Michael "Monty" Widenius
------------------------

 * mwl#?? VARCHAR and BLOB for HEAP tables (from ebay).
	+ Waiting for ok from Ebay to use their code to start working on this.

 Igor Babaev
-----------

 ### 
[MWL#128](http://askmonty.org/worklog/?tid=128): Implement Block Nested Loop Hash Join

  **hash join over attributes with non-binary collation (not started, 1-2 weeks) (not critical)**

 ### MWL#?? (new)

 * Cost-based choice for join buffers (not started, 2 weeks, including review)

 ### 
[MWL#106](http://askmonty.org/worklog/?tid=106): Backport optimizations for derived tables and views

 The goal of this task is to backport the implementation of the late materialization of derived tables and views and the additional optimizations for derived tables/views from MySQL 6.0 code line to [MariaDB 5.3](../what-is-mariadb-53/index).

 * Done in a separate tree, probable requires refactoring.
* Probable problems of merging with other tasks. (1 week)
* Philip should start testing; Timour+Igor to define when bugs should be reported (not to be reported if bugs is also a subquery bug)

 Oleksandr "Sanja" Byelkin
-------------------------

 ### mwl#??

 * Bitmap in tmp table keys ; 1-3 days

 Sergei Golubchik
----------------

 * review query rewrite plugin contribution
* review Kristian's replication tasks
* [MWL#113](http://askmonty.org/worklog/?tid=113): many clustered keys (not only primary)
* [MWL#114](http://askmonty.org/worklog/?tid=114): insert ignore ha\_extra hint
* [MWL#151](http://askmonty.org/worklog/?tid=151): Phone home (done, just needs to be pushed)

 Kristian Nielsen
----------------

 Tasks which should go in 5.3:

 * [MWL#116](http://askmonty.org/worklog/?tid=116): Group commit framework and implementation
	+ Code complete, waiting for code review.
	+ After review+fixes, need to supply info for documentation.
* [MWL#136](http://askmonty.org/worklog/?tid=136): Cross-engine consistency for START TRANSACTION WITH CONSISTENT SNAPSHOT
	+ Code complete, waiting for code review.
	+ After review+fixes, need to supply info for documentation.
* [MWL#163](http://askmonty.org/worklog/?tid=163): release of row locks in InnoDB during prepare
	+ Code complete, waiting for code review.
	+ After review+fixes, need to supply info for documentation.

 Tasks which are not critical for 5.3, but could go there:

 * PBXT part of [MWL#116](http://askmonty.org/worklog/?tid=116).
	+ Waiting for response from Paul McCullagh.
* [MWL#132](http://askmonty.org/worklog/?tid=132): TC plugin
	+ Waiting for code review.

 Rolling features
================

 * [MWL#92](http://askmonty.org/worklog/?tid=92): Subqueries backport: fix known semi-join subquery bugs
* Consolidate the range query apis (need more info)
* [MWL#115](http://askmonty.org/worklog/?tid=115): innodb statistics in the slow log
* Tasks in [worklog](http://askmonty.org/worklog/index.pl?virtual=version:Server-5.3)
* mwl#?? Optimized versions of users statistics (from google/facebook).
	+ responsible: Monty
	+ status: will do if Monty has time after VARCHAR and BLOB task
	+ todo: review, change, possibly reimplement, est: 7 days work

 Testing
=======

 * Still a lot of open bugs at [Launchpad](https://bugs.launchpad.net/maria).
* More testing to be decided later

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-53-todo-not/>

MariaDB 5.3 TODO
================

    Older version of this page can be found at [mariadb-53-todo-not](../mariadb-53-todo-not/index).

 *Shortly before a 5.3 release, this page lists the remaining TODO items before the release. Currently, it is empty.*

 See Also:
---------

 * [What is MariaDB 5.3](../what-is-mariadb-53/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-53-todo/>

MariaDB 5.2 TODO
================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  See the [Summary page](../what-is-mariadb-52/index), Release Notes and Changelog pages for details of what is in each 5.2 release:

 ### [MariaDB 5.2 Release Notes](../release-notes/index)

 This section includes a summary of all important features in [MariaDB 5.2](../what-is-mariadb-52/index).

 * [MariaDB 5.2.0-beta Release Notes](https://mariadb.com/kb/en/mariadb-520-release-notes/) (5.2.0-beta released 10 Apr 2010)
* [MariaDB 5.2.1-beta Release Notes](https://mariadb.com/kb/en/mariadb-521-release-notes/) (5.2.1-beta released 18 Jun 2010)
* [MariaDB 5.2.2](https://mariadb.com/kb/en/mariadb-522-release-notes/) Release Notes (in development)

 ### [MariaDB 5.2 Changelogs](../changelogs/index)

 * [MariaDB 5.2.0-beta Changelog](https://mariadb.com/kb/en/mariadb-520-changelog/) (5.2.0-beta released 10 Apr 2010)
* [MariaDB 5.2.1-beta Changelog](https://mariadb.com/kb/en/mariadb-521-changelog/) (5.2.1-beta released 18 Jun 2010)
* [MariaDB 5.2.2](https://mariadb.com/kb/en/mariadb-522-release-notes/) Changelog (in development)

 As stated above, all non-completed todo items have been moved to [MariaDB 5.3](../what-is-mariadb-53/index), see [MariaDB 5.3 TODO](../mariadb-53-todo/index).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-52-todo/>

MariaDB Developer Meeting - Athens
===================================

   11-13 Nov 2011 - Notes and Plans from the Athens Developer meeting. 

  

| Title | Description |
| --- | --- |
|  [MariaDB Developer Meeting - Athens - Friday, 11 Nov 2011](../mariadb-developer-meeting-athens-friday-11-nov-2011/index) |  Agenda and notes from day 1 of the MariaDB Developer Meeting in Athens, Gre...  |
|  [MariaDB Developer Meeting - Athens - Saturday, 12 Nov 2011](../mariadb-developer-meeting-athens-saturday-12-nov-2011/index) |  Agenda and notes from day 2 of the MariaDB Developer Meeting in Athens, Gre...  |
|  [MariaDB Developer Meeting - Athens - Sunday, 13 Nov 2011](../mariadb-developer-meeting-athens-sunday-13-nov-2011/index) |  Agenda and notes from day 3 of the MariaDB Developer Meeting in Athens, Gre...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-developer-meeting-athens/>

MariaDB Online Backup
=====================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Rumours have it that MySQL/Sun/Oracle are going to drop the MySQL online backup project, which was originally scheduled for MySQL 6.0.

 Given this, it makes sense to consider resurrecting the project for MariaDB. This page collects various resources related to this.

 Documentation
-------------

 * [MySQL Forge project page](http://forge.mysql.com/wiki/OnlineBackup) for Online Backup
* [Online Backup reference manual](http://dev.mysql.com/doc/mysql-backup/en/index.html)
* [tarball](http://hasky.askmonty.org/download/onlinebackup/backup-manual.tar.gz) containing self-contained copy of the Online Backup reference manual (the license allows to copy/distribute the manual together with the source tarball, but not to modify it).

 Source code
-----------

 * [mysql-6.0-backup branch](https://code.launchpad.net/~mysql/mysql-server/mysql-6.0-backup) on Launchpad
* [mysql-6.0 branch](https://code.launchpad.net/~mysql/mysql-server/mysql-6.0) on Launchpad
* [Source tarball](http://hasky.askmonty.org/download/onlinebackup/mysql-6.0.14-alpha.tar.gz) of mysql-6.0-backup

 Notes
-----

 ### Extracting a patch for merging

 It may not be trivial to extract a patch of MySQL Online Backup that can be used as a basis for merging into MariaDB. The problem is that we do not have a feature tree that contains only the backup feature over some base/parent tree.

 There was work done at MySQL to merge online backup into MySQL 5.5 using such a feature tree, but this tree is not public, and requests to make it public have not been answered positively so far.

 It may still be possible to extract the code, but it may be necessary to do it manually, by extracting relevant parts of the code from 6.0 without including other stuff that is not related to backup.

 It might also be useful to search the [bugs.mysql.com](http://bugs.mysql.com/) MySQL bug tracker for recently fixed online backup bugs, since recent fixes are not included in the publicly available trees on Launchpad.

 ### Comments on the code

 From looking at the documentation of Online Backup, it seems geared more towards an optimised mysqldump facility than towards an easy-to-use facility to back up a complete MySQL server:

 * The `BACKUP` command only allows to backup selected (or all) databases/schemas.
* There seems to be no facility to backup the binary log
* There seems to be no facility to backup `GRANT`s or other server-global configuration, using [mysqldump](../mysqldump/index) on the "mysql" schema/database is suggested
* Restoring a new server from scratch seems to involve setting up a new server, including running [mysql\_install\_db](../mysql_install_db/index) and adding `GRANT`s, and only then restoring tables and other schema objects

 Compared to something like XtraBackup, full backup and restore seems to be somewhat more involved. It may be necessary to add extra facilities or wrapper scripts to enable to backup/restore a full database server.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-online-backup/>

Storage Engine Summit 2010
==========================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Storage Engine Summit is a traditional yearly one-day meeting of Storage Engine vendors, typically held right after the MySQL User Conference.

 In 2010 it was organized by [Monty Program Ab](http://montyprogram.com).

 Location
--------

 The [Network Meeting Center](http://www.networkmeetingcenter.com/) - across the street from the Convention Center. ([map](http://goo.gl/D0ru))

 Date and Time
-------------

 Friday April 16, 2010 - 9:00 a.m. to 6:30 p.m.

 Audience
--------

 Invited were all MySQL/MariaDB Storage Engine vendors and anyone interested in the MySQL/MariaDB Storage Engine API.

 There were about 25 participants from MariaDB, Oracle, and eight storage engine vendors.

 Meeting Minutes
---------------

 ### Presenting Monty Program Ab 1

 
Unlike Drizzle, MariaDB will stay fully compatible with MySQL (for a while) MariaDB is GPL only 
**Monty:** But we want to evolve the interface. 
**Mikael:** It is a bad idea for MariaDB to compete on new APIs as there is a need for a single standard rather than competing APIs. 
**Sergei:** Totally agree, we want to improve the API, but stay compatible MariaDB 5.2 released, good progress with MariaDB 5.3 We do NRE  ### Upcoming changes in the Storage Engine API 2

 
CREATE TABLE extensions in MariaDB 5.2.0 3
 
**Question:** Are there per-partition attributes? 
**Sergei:** No, it's a bug, we will add them in 5.2.1 Performance Schema in MySQL 5.5 4,5
 
**Mikael:** InnoDB has added probes for this in MySQL 5.5.4 Transactional LOCK TABLES 
**Question:** What if the engine does not support it? 
**Sergei:** No problem, it's an optional feature, if not supported MySQL will use old style table locks Multi Read Range (MRR) and how it is used in Batch Key Access (BKA) 6
 
**Question:** Isn't it in MySQL 5.1? 
**Igor Babaev:** No, the interface in MariaDB 5.3 is different, more generic Server Services for Plugins 7
 
**Paul McCullah:** Plugins need some "magic autoconf code" to detect whether libservices should be used (to support both MariaDB 5.1 and 5.2) Query Fragment Pushdown 8
 
**Mikael:** It is in MySQL in a working tree 
**Sergei:** Yes, but it's we are talking about a much more general approach here  ### Discussion: What Storage Engine needs

 
Query Fragment Pushdown: Sub-problems:  * Abstract Query Tree (AQT) or query and database model ([MySQL Worklog #4533](https://dev.mysql.com/worklog/task/?id=4533))
* Storage Engine Pushdown API ([MySQL Worklog #4535](https://dev.mysql.com/worklog/task/?id=4535))
* Virtual Tables ([MySQL Worklog #4537](https://dev.mysql.com/worklog/task/?id=4537))
* Query decomposition and optimization for query fragments ([MySQL Worklog #4536](https://dev.mysql.com/worklog/task/?id=4536))
* Cost mode calibration ([MySQL Worklog #4553](https://dev.mysql.com/worklog/task/?id=4553))

 

**Question:** Some engines has extra knowledge, like for example some materialised views. Would it be possible to make these available as extra tables for the MySQL optimiser? 
**Kostja:** *You can already do this today, similar to how the merge tables work*
 
**Jonas:** *We thought about it when designing for NDB. It is much easier to implement, but the "real" solution is much better.*
 
**Timour:** *The basic framework is only 30% of the full problem. The main part is the query optimisation, and that can be developed incrementally once the rest of the framework is in place.*
 
**Comment:** *Storage engines do not want to have to implement their own optimiser inside the engine.*
 
**Sergei:** *But if there is one, it should be possible to use it.*
 
**Timour:** *We are trying to implement a general solution that makes multiple engines happy. The optimiser should be cost based rather than rule based to cover a general set of cases well.*
 
**Comment:** *It should be simple by engines such as Spider, Federated to re-construct an SQL query from the proposed representation.*
 Majority feels that Query re-write is not realistic to work on due to dependency on highly complex internal data structures. Range Pushdown for all columns 
**Sergei:** *These can be derived from a query pushdown*
 
**Comment:** *As a separate feature it's much easier to implement and to use*9
 Online Backup Engines want it Perhaps backport it from MySQL 6.0 ? Table discovery enhancements 
**Sergei:** *There was a patch from Google Summer of Code that included enhanced discovery. MySQL now works on that feature, using the patch as a starting point.*
 Parallel query execution across multiple cores 
**Sergei:** *Parallel query execution is a general feature, and although it would be nice to have it, it is not directly relevant to this storage engine summit discussion.*
 Support in the optimiser for clustering non-primary keys HA\_EXTRA\_WRITE\_CAN\_IGNORE hint Consolidate the range query apis Make sure the range boundaries are always sent to the engine (in order by desc, JT\_REF, rnd\_\*, etc) Transactional DDL 
**Comment:** *We do not really need full transactions, just crash recovery.*
 
**Monty:** *For partial DDL, what we can do is log DDL changes, to be able to recover things after a crash.*
 
**Mikael:** *There is this already in 5.1 for partitions. But it is only for partitions, not for the tables.*
 Monty is willing to write specs for crash-safe DDL Smarter "ALTER TABLE" 
**Comment:** *Need to fix ALTER TABLE to fully support online operations.*
 
**Jonas:** *This is already implemented, but currently only in the -telco cluster trees.*
 Antony is willing to look into backporting new ALTER TABLE to MariaDB Fast, engine-specific LOAD DATA Certain engines are so fast for bulk inserts that server adds too much overhead Faster export (SELECT ... OUTFILE) Same as with LOAD DATA Can be done with a special Protocol class or select\_result class ? Engine-provided SQL commands. EXECUTE COMMAND maybe? 
**Comment:** *Want to be able to make/extend SHOW ENGINE xxx STATUS*
 
**Sergei:** *No need, create an INFORMATION\_SCHEMA table instead.*
 InnoDB statistics in the slow log Perhaps, audit api can be used for that ? Engine independent test suite 
**Sergei:** *This was presented by Sun on the Storage Engine Summit last year, but no trace has been seen of it ever since*
 Paul described how it is done in Drizzle, an engine can override a .result file An author of the Spider engine started recently a new project [Engine Independent Test for MySQL](https://launchpad.net/engineindependenttestformysql) - we all can collaborate and extend it 
**Comment:** *What about unit tests for the storage engine API?*
 Need a unit test that loads a storage engine plugin and exercises every call in it. 
**Sergei:** *this is also something that Sun tried to do10*
  ### Conclusions

 Few simple feature requests we can do straight away:

 * many clustered keys (not only primary) - [MWL#113](http://askmonty.org/worklog/?tid=113)
* insert ignore ha\_extra hint - [MWL#114](http://askmonty.org/worklog/?tid=114)
* consolidating the range query apis
* innodb statistics in the slow log - [MWL#115](http://askmonty.org/worklog/?tid=115)

 We will work together to create an engine independent test suite - all engines will benefit from it.

 More complex features are open. Monty Program will be happy to do them as NREs or discuss alternative ways of collaborating on having them implemented.

 ### References

 
1. **MariaDB, Monty Program, Collaboration** by Henrik Ingo ([slides, odp](http://askmonty.org/w/images/3/3a/MP_intro_SE_summit.odp))
2. **Storage Engine API: Beyond 5.1** by Sergei Golubchik ([slides, zipped html](http://askmonty.org/w/images/b/b8/SE_API_Beyond_5.1.maff))
3. CREATE TABLE extension [manual](../extending-create-table/index)
4. Performance Schema [manual](http://dev.mysql.com/doc/performance-schema/en/index.html)
5. Marc Alff's [MySQL University session](http://forge.mysql.com/wiki/Performance_Schema:_Instrumenting_Code) about the instrumentation.
6. See slides 10-18 from the Sergey Petrunya's [MySQL UC2010 talk](http://en.oreilly.com/mysql2010/public/schedule/detail/13509)
7. Server Services in the [MySQL manual](http://dev.mysql.com/doc/refman/5.5/en/plugin-services.html)
8. **Query Fragment Pushdown Design** by Timour Katchaounov ([slides, pdf](http://askmonty.org/w/images/4/47/Qfpd-query-model-design.pdf))
9. post-conference, a quick patch was made for this functionality: <https://lists.launchpad.net/maria-developers/msg02961.html>
10. <http://forge.mysql.com/wiki/Storage_Engine_API_Testing_Framework>

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/storage-engine-summit-2010/>

Connect Memory Usage
====================

    When creating a connection, a THD object is created for that connection. This contains all connection information and also caches to speed up queries and avoid frequent malloc() calls.

 When creating a new connection, the following malloc() calls are done for the THD:

 The following information is the state in [MariaDB 10.6.1](https://mariadb.com/kb/en/mariadb-1061-release-notes/) when compiled without debugging.

 Local Thread Memory
-------------------

 This is part of `select memory\_used from information\_schema.processlist`.

 


| Amount allocated | Where allocated |  Description |
| --- | --- | --- |
| 26646 | THD::THD | Allocation of THD object |
| 256 | Statement\_map::Statement\_map(), my\_hash\_init(key\_memory\_prepared\_statement\_map, &st\_hash | Prepared statements |
| 256 | my\_hash\_init(key\_memory\_prepared\_statement\_map, &names\_hash | Names of used prepared statements |
| 128 | wsrep\_wfc(), Opt\_trace\_context(), dynamic\_array() |  |
| 1024 | Diagnostics\_area::init(),init\_sql\_alloc(PSI\_INSTRUMENT\_ME, &m\_warn\_root |  |
| 120 | Session\_sysvars\_tracker, global\_system\_variables.session\_track\_system\_variables | Tracking of changed session variables |
| 280 | THD::THD,my\_hash\_init(key\_memory\_user\_var\_entry,&user\_vars |  |
| 280 | THD::THD,my\_hash\_init(PSI\_INSTRUMENT\_ME, &sequences | Cache of used sequences |
| 1048 | THD::THD, m\_token\_array= my\_malloc(PSI\_INSTRUMENT\_ME, max\_digest\_length |  |
| 16416 | CONNECT::create\_thd(), my\_net\_init(), net\_allocate\_new\_packet() | This is for reading data from the connected user |
| 16416 | check\_connection(), thd->packet.alloc() | This is for sending data to connected user |

 
Objects Stored in THD->memroot During Connect
---------------------------------------------

 


| Amount allocated | Where allocated | Description |
| --- | --- | --- |
| 72 | send\_server\_handshake\_packet, mpvio->cached\_server\_packet.pkt= |  |
| 64 | parse\_client\_handshake\_packet, thd->copy\_with\_error(...db,db\_len) |  |
| 32 | parse\_client\_handshake\_packet, sctx->user= |  |
| 368 | ACL\_USER::copy(), root= | Allocation of ACL\_USER object |
| 56 | ACL\_USER::copy(), dst->user= safe\_lexcstrdup\_root(root, user) |  |
| 56 | ACL\_USER::copy() | Allocation of other connect attributes |
| 56 | ACL\_USER::copy() |  |
| 64 | ACL\_USER::copy() |  |
| 64 | ACL\_USER::copy() |  |
| 32 | mysql\_change\_db() | Store current db in THD |
| 48 | dbname\_cache->insert(db\_name) | Store db name in db name cache |
| 40 | mysql\_change\_db(), my\_register\_filename(db.opt) | Store filename db.opt |
| 8216 | load\_db\_opt(), init\_io\_cache() | Disk cache for reading db.opt |
| 1112 | load\_db\_opts(), put\_dbopts() | Cache default database parameters |

 
State at First Call to mysql\_execute\_command
----------------------------------------------

 
```
(gdb) p thd->status_var.local_memory_used
$24 = 75496
(gdb) p thd->status_var.global_memory_used
$25 = 17544
(gdb) p thd->variables.query_prealloc_size
$30 = 24576
(gdb) p thd->variables.trans_prealloc_size
$37 = 4096

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/connect-memory-usage/>

10.3.10 Release Upgrade Tests
=============================

    ### Tested revision

 bad2f1569da57c4a81cc84ec2f4a79924df9c8d6

 ### Test date

 2018-10-04 23:04:05

 ### Summary

 Known bug [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 4 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 8 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 16 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.10 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.10 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.10 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.10 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.10 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.10 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.10 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10310-release-upgrade-tests/>

10.3.9 Release Upgrade Tests
============================

    ### Tested revision

 ca26f91bcaa21933147974c823852a2e1c2e2bd7

 ### Test date

 2018-08-30 07:09:44

 ### Summary

 Known bug [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 4 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 8 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 16 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.9 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.9 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.9 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.9 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.8 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.8 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.8 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.8 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.9 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.9 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.9 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.9 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.3.9 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1039-release-upgrade-tests/>

10.1.30 Release Upgrade Tests
=============================

    ### Tested revision

 461cf3e5a3c2d346d75b1407b285f8daf9d01f67

 ### Test date

 2017-12-23

 ### Summary

 Some tests failed with known bug [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112).  
 Undo upgrade from 10.0.18 failed because the old server hang on shutdown (a known problem with old servers).   
 Crash upgrade from 10.1.10 (4K, zlib, XtraDB, Barracuda) failed ([MDEV-14759](https://jira.mariadb.org/browse/MDEV-14759)).  


 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(52) |
| recovery | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(59) |
| recovery | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(20) |
| recovery | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(71) |
| recovery | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(17) |
| crash | 4 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(43) |
| crash | 32 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(36) |
| crash | 32 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(47) |
| crash | 8 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(60) |
| crash | 16 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.29 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.29 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.29 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.29 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(33) |
| crash | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(19) |
| crash | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(44) |
| crash | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(29) |
| crash | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(66) |
| crash | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.30 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.30 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.30 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.30 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.1.30 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10130-release-upgrade-tests/>

10.2.12 Release Upgrade Tests
=============================

    ### Tested revision

 d361401bc26f49480daec8b0307afff6edae2ecc

 ### Test date

 2018-01-07 07:34:24

 ### Summary

 Some tests failed due to [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094) as usual. Crash recovery with encryption also fails due to [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103).

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.12 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.12 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.12 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.12 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| crash | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| crash | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.2.12 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10212-release-upgrade-tests/>

10.1.32 Release Upgrade Tests
=============================

    ### Tested revision

 4d83b01537e3f1eb257a8e9a6416938e03adea59

 ### Test date

 2018-04-17 01:44:10

 ### Summary

 Known bug [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(70) |
| recovery | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(60) |
| recovery | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(28) |
| recovery | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(38) |
| recovery | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(76) |
| recovery | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(54) |
| crash | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(41) |
| crash | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(50) |
| crash | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(35) |
| crash | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(43) |
| crash | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(23) |
| crash | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(52) |
| crash | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(33) |
| crash | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(21) |
| crash | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(49) |
| crash | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.1.32 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.1.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.1.32 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.1.32 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.1.32 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10132-release-upgrade-tests/>

10.1.36 Release Upgrade Tests
=============================

    ### Tested revision

 38e5dc0f772daecca1d2681885d3d85414eb6826

 ### Test date

 2018-10-03 11:54:43

 ### Summary

 Tests passed

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.1.36 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.1.36 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.1.36 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.1.36 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| crash | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.1.36 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10136-release-upgrade-tests/>

10.3.5-gamma Release Upgrade Tests
==================================

    ### Tested revision

 583eb96c2492adb87e88a014b24eb0724fb00257

 ### Test date

 2018-03-11 12:40:20

 ### Summary

 Known bugs [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 4 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 32 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 64 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 8 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 16 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.5 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.5 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.5 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.5 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.5 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1035-gamma-release-upgrade-tests/>

10.2.13 Release Upgrade Tests
=============================

    ### Tested revision

 00f0c039d2f4213ccf0a0202349ecb162a799989

 ### Test date

 2018-02-15 22:17:40

 ### Summary

 Some tests failed due to [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094) as usual.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.31 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.13 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.13 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.13 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.13 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| crash | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| crash | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.13 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10213-release-upgrade-tests/>

10.3.6-gamma Release Upgrade Tests
==================================

    ### Tested revision

 560743198604caf677c543db9719cef871df09ce

 ### Test date

 2018-04-17 10:50:21

 ### Summary

 One new (previously unknown) bug [MDEV-15912](https://jira.mariadb.org/browse/MDEV-15912). Known bugs [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). One failure identified as a deadlock of yet unknown origin, could be a side-effect of known bugs. A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 4 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 32 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 64 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 8 | 10.3.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 16 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.5 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.5 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.5 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.5 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | SERVER\_DEADLOCKED |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.6 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.6 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.6 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.6 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.6 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1036-gamma-release-upgrade-tests/>

10.3.4-beta Release Upgrade Tests
=================================

    ### Tested revision

 8f102b584d4e8f02da924f9be094014136eb453f

 ### Test date

 2018-01-19 17:39:10

 ### Summary

 All major upgrades fail with [MDEV-14990](https://jira.mariadb.org/browse/MDEV-14990) (non-InnoDB issue, general server). Also known bugs [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.4 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.4 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 4 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 32 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 64 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.4 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 16 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.4 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.12 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.4 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.4 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.4 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.4 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.3.4 (inbuilt) |  | - | - | - | **FAIL** | UPGRADE\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1034-beta-release-upgrade-tests/>

10.3.3-beta Release Upgrade Tests
=================================

    ### Tested revision

 52c40b406d5a68bf774a75dc6fa9ef1c166b22b1

 ### Test date

 2017-12-24

 ### Summary

 Some tests failed due to the known bug [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103).   
 Crash upgrade from 10.3.2 fails due to an incompatible change (removal of MLOG\_UNDO\* record types), allowed for Alpha=>Beta transition.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.3.3 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.3.3 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 4 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 32 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 64 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 8 | 10.3.3 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| undo-recovery | 16 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.3.3 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 16 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 4 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 32 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 64 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | UPGRADE\_FAILURE |
| crash | 8 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| undo | 16 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.3.2 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.3.2 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.3.2 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.3.2 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.11 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.30 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.3.3 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.3.3 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.3.3 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.3.3 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.20 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.38 (inbuilt) |  | - | - | => | 10.3.3 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1033-beta-release-upgrade-tests/>

10.2.7 Release Upgrade Tests
============================

    Upgrade from 10.0
-----------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 07:11:04

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 2 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 3 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 4 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 5 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 6 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 7 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 8 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 9 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 10 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 11 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 12 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |

 
Upgrade from 10.1
-----------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 07:29:38

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 64 | 10.1.24 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 2 | normal | 64 | 10.1.24 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 3 | normal | 64 | 10.1.24 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 4 | normal | 64 | 10.1.24 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 5 | normal | 64 | 10.1.24 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 6 | normal | 64 | 10.1.24 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 7 | normal | 64 | 10.1.24 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 8 | normal | 64 | 10.1.24 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 9 | normal | 8 | 10.1.24 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 10 | normal | 8 | 10.1.24 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 11 | normal | 8 | 10.1.24 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 12 | normal | 8 | 10.1.24 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 13 | normal | 8 | 10.1.24 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 14 | normal | 8 | 10.1.24 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 15 | normal | 8 | 10.1.24 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 16 | normal | 8 | 10.1.24 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 17 | normal | 16 | 10.1.24 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 18 | normal | 16 | 10.1.24 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 19 | normal | 16 | 10.1.24 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 20 | normal | 16 | 10.1.24 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 21 | normal | 16 | 10.1.24 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 22 | normal | 16 | 10.1.24 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 23 | normal | 16 | 10.1.24 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 24 | normal | 16 | 10.1.24 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 25 | normal | 32 | 10.1.24 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 26 | normal | 32 | 10.1.24 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 27 | normal | 32 | 10.1.24 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 28 | normal | 32 | 10.1.24 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 29 | normal | 32 | 10.1.24 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 30 | normal | 32 | 10.1.24 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 31 | normal | 32 | 10.1.24 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 32 | normal | 32 | 10.1.24 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 33 | normal | 4 | 10.1.24 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 34 | normal | 4 | 10.1.24 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 35 | normal | 4 | 10.1.24 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 36 | normal | 4 | 10.1.24 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 37 | normal | 4 | 10.1.24 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 38 | normal | 4 | 10.1.24 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 39 | normal | 4 | 10.1.24 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 40 | normal | 4 | 10.1.24 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 41 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 42 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 43 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 44 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 45 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 46 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 47 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 48 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 49 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 50 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 51 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 52 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 53 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 54 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 55 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 56 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 57 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 58 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 59 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 60 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 61 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 62 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 63 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 64 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 65 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 66 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 67 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 68 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 69 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 70 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 71 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 72 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 73 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 74 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 75 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 76 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 77 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 78 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 79 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 80 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |

 
Upgrade from 10.2
-----------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 09:34:15

 ### Summary (FAIL)

 [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094), [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 64 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 2 | crash | 64 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 3 | crash | 64 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 4 | crash | 64 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 5 | crash | 8 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 6 | crash | 8 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 7 | crash | 8 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 8 | crash | 8 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 9 | crash | 16 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 10 | crash | 16 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 11 | crash | 16 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 12 | crash | 16 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 13 | crash | 32 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 14 | crash | 32 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 15 | crash | 32 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 16 | crash | 32 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 17 | crash | 4 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 18 | crash | 4 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 19 | crash | 4 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 20 | crash | 4 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 21 | normal | 32 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 22 | normal | 32 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 23 | normal | 32 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 24 | normal | 32 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 25 | normal | 4 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 26 | normal | 4 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 27 | normal | 4 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 28 | normal | 4 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 29 | normal | 16 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 30 | normal | 16 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 31 | normal | 16 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 32 | normal | 16 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 33 | normal | 64 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 34 | normal | 64 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 35 | normal | 64 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 36 | normal | 64 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 37 | normal | 8 | 10.2.6 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | OK |  |
| 38 | normal | 8 | 10.2.6 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | OK |  |
| 39 | normal | 8 | 10.2.6 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 40 | normal | 8 | 10.2.6 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 10:34:00

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 2 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 3 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 4 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 5 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 6 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 7 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 8 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 9 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 10 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 11 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 12 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |

 
Upgrade from MySQL 5.7
----------------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 10:52:42

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 64 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 2 | crash | 64 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 3 | crash | 8 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 4 | crash | 8 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 5 | crash | 16 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 6 | crash | 16 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 7 | crash | 32 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 8 | crash | 32 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 9 | crash | 4 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 10 | crash | 4 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 11 | normal | 16 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 12 | normal | 16 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 13 | normal | 32 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 14 | normal | 32 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 15 | normal | 64 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 16 | normal | 64 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 17 | normal | 8 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 18 | normal | 8 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |
| 19 | normal | 4 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | OK |  |
| 20 | normal | 4 | 5.7.17 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | on | - | - | OK |  |

 
Crash recovery
--------------

 ### Tested revision

 5ff2db7f67401511b30dbd3fc69a1ea87d7e8cc4

 ### Test date

 2017-07-10 11:23:26

 ### Summary (FAIL)

 [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094), [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.2.7 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 2 | crash | 16 | 10.2.7 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(3) |
| 3 | crash | 16 | 10.2.7 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 4 | crash | 16 | 10.2.7 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 5 | crash | 4 | 10.2.7 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 6 | crash | 4 | 10.2.7 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(3) |
| 7 | crash | 4 | 10.2.7 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 8 | crash | 4 | 10.2.7 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 9 | crash | 32 | 10.2.7 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 10 | crash | 32 | 10.2.7 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 11 | crash | 32 | 10.2.7 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 12 | crash | 32 | 10.2.7 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 13 | crash | 64 | 10.2.7 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 14 | crash | 64 | 10.2.7 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| 15 | crash | 64 | 10.2.7 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 16 | crash | 64 | 10.2.7 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 17 | crash | 8 | 10.2.7 (inbuilt) |  | - | zlib | => | 10.2.7 (inbuilt) |  | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 18 | crash | 8 | 10.2.7 (inbuilt) |  | on | zlib | => | 10.2.7 (inbuilt) |  | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| 19 | crash | 8 | 10.2.7 (inbuilt) |  | - | - | => | 10.2.7 (inbuilt) |  | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |
| 20 | crash | 8 | 10.2.7 (inbuilt) |  | on | - | => | 10.2.7 (inbuilt) |  | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(2) |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1027-release-upgrade-tests/>

10.1.26 Release Upgrade Tests
=============================

    Upgrade from 10.0
-----------------

 ### Tested revision

 535910ae5f20e36405631030e9c0eb22fe40a7c4

 ### Test date

 2017-08-09 14:16:17

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | crash | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | crash | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 4 | crash | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 5 | crash | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 6 | crash | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 7 | crash | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 8 | crash | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 9 | crash | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 10 | crash | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 11 | crash | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 12 | crash | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 13 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 14 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 15 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 16 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 17 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 18 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 19 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 20 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 21 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 22 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 23 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 24 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |

 
Upgrade from 10.1
-----------------

 ### Tested revision

 535910ae5f20e36405631030e9c0eb22fe40a7c4

 ### Test date

 2017-08-09 15:06:34

 ### Summary (FAIL)

 [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112), [MDEV-13165](https://jira.mariadb.org/browse/MDEV-13165)

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 64 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 2 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 3 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(49) |
| 4 | crash | 64 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 5 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 6 | crash | 64 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 7 | crash | 64 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 8 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 9 | crash | 8 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 10 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 11 | crash | 8 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 12 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(14) |
| 13 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 14 | crash | 8 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 15 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 16 | crash | 8 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 17 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 18 | crash | 16 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 19 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(37) |
| 20 | crash | 16 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 21 | crash | 16 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 22 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 23 | crash | 16 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 24 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 25 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 26 | crash | 32 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 27 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 28 | crash | 32 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 29 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(29) |
| 30 | crash | 32 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 31 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 32 | crash | 32 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 33 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(43) |
| 34 | crash | 4 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 35 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE [MDEV-13165](https://jira.mariadb.org/browse/MDEV-13165) |
| 36 | crash | 4 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 37 | crash | 4 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 38 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 39 | crash | 4 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 40 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 41 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 42 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 43 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 44 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 45 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 46 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 47 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 48 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 49 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 50 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 51 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 52 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 53 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 54 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 55 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 56 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 57 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 58 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 59 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 60 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 61 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 62 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 63 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 64 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 65 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 66 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 67 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 68 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 69 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 70 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 71 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 72 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 73 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 74 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 75 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 76 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 77 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 78 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 79 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 80 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 535910ae5f20e36405631030e9c0eb22fe40a7c4

 ### Test date

 2017-08-09 18:24:38

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 4 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 5 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 6 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 7 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 8 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 9 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 10 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 11 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 12 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |

 
Crash Recovery
--------------

 ### Tested revision

 535910ae5f20e36405631030e9c0eb22fe40a7c4

 ### Test date

 2017-08-09 18:52:03

 ### Summary (FAIL)

 [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.1.26 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 2 | crash | 16 | 10.1.26 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 3 | crash | 16 | 10.1.26 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 4 | crash | 16 | 10.1.26 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 5 | crash | 16 | 10.1.26 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 6 | crash | 16 | 10.1.26 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(54) |
| 7 | crash | 16 | 10.1.26 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 8 | crash | 16 | 10.1.26 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 9 | crash | 4 | 10.1.26 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 10 | crash | 4 | 10.1.26 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 11 | crash | 4 | 10.1.26 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 12 | crash | 4 | 10.1.26 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 13 | crash | 4 | 10.1.26 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(48) |
| 14 | crash | 4 | 10.1.26 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 15 | crash | 4 | 10.1.26 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 16 | crash | 4 | 10.1.26 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 17 | crash | 32 | 10.1.26 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 18 | crash | 32 | 10.1.26 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(16) |
| 19 | crash | 32 | 10.1.26 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 20 | crash | 32 | 10.1.26 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 21 | crash | 32 | 10.1.26 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 22 | crash | 32 | 10.1.26 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 23 | crash | 32 | 10.1.26 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 24 | crash | 32 | 10.1.26 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 25 | crash | 64 | 10.1.26 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |
| 26 | crash | 64 | 10.1.26 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 27 | crash | 64 | 10.1.26 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 28 | crash | 64 | 10.1.26 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 29 | crash | 64 | 10.1.26 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(21) |
| 30 | crash | 64 | 10.1.26 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 31 | crash | 64 | 10.1.26 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 32 | crash | 64 | 10.1.26 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 33 | crash | 8 | 10.1.26 (inbuilt) | Barracuda | on | zlib | => | 10.1.26 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(18) |
| 34 | crash | 8 | 10.1.26 (inbuilt) | Antelope | on | zlib | => | 10.1.26 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 35 | crash | 8 | 10.1.26 (inbuilt) | Antelope | - | zlib | => | 10.1.26 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 36 | crash | 8 | 10.1.26 (inbuilt) | Barracuda | - | zlib | => | 10.1.26 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 37 | crash | 8 | 10.1.26 (inbuilt) | Antelope | on | - | => | 10.1.26 (inbuilt) | Antelope | on | - | - | OK |  |
| 38 | crash | 8 | 10.1.26 (inbuilt) | Barracuda | on | - | => | 10.1.26 (inbuilt) | Barracuda | on | - | - | OK |  |
| 39 | crash | 8 | 10.1.26 (inbuilt) | Barracuda | - | - | => | 10.1.26 (inbuilt) | Barracuda | - | - | - | OK |  |
| 40 | crash | 8 | 10.1.26 (inbuilt) | Antelope | - | - | => | 10.1.26 (inbuilt) | Antelope | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10126-release-upgrade-tests/>

10.0.36 Release Upgrade Tests
=============================

    ### Tested revision

 e023f9a4d5a620b54d7f7132567150d80b630692

 ### Test date

 2018-08-05 19:08:18

 ### Summary

 Two tests failed due to problems in previous versions (unrelated to the release)

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| undo-recovery | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo-recovery | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo-recovery | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| recovery | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| recovery | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| recovery | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.35 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| crash | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.0.36 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.35 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10036-release-upgrade-tests/>

10.2.18 Release Upgrade Tests
=============================

    ### Tested revision

 2dfb4a8abe3af501f8a6780ed782a2eee5e6f6d5

 ### Test date

 2018-10-03 13:37:05

 ### Summary

 Few unrelated failures due to bugs in previous versions

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 4 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 8 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 16 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.2.18 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.2.18 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.18 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.18 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.36 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.18 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.18 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.18 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.18 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| crash | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| crash | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.18 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10218-release-upgrade-tests/>

10.2.17 Release Upgrade Tests
=============================

    ### Tested revision

 5553d3f1f691a374124686946bd1f1cc4ef9fb45

 ### Test date

 2018-08-30 01:21:02

 ### Summary

 Known bug [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| recovery | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.2.17 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.2.17 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.17 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.17 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 16 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.16 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.16 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.16 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.16 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.35 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.17 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.17 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.17 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.17 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.36 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| crash | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| crash | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.23 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 16 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.41 (inbuilt) |  | - | - | => | 10.2.17 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10217-release-upgrade-tests/>

10.2.14 Release Upgrade Tests
=============================

    ### Tested revision

 b3cdafcb93da2e57d49f26f0846dc957458ee72c

 ### Test date

 2018-04-17 05:25:43

 ### Summary

 Known bugs [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103), [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094). A few upgrades from MySQL and old MariaDB fail because the old versions hang on shutdown.

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| recovery | 16 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 16 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 4 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 4 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 32 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 64 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 8 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| recovery | 8 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| recovery | 16 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 16 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 4 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 4 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 32 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 64 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| recovery | 8 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| recovery | 8 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 16 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 4 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 32 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 64 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 8 | 10.2.14 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo-recovery | 16 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 4 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 32 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 64 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 8 | 10.2.14 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo-recovery | 16 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 4 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 32 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 64 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 8 | 10.2.14 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | TEST\_FAILURE |
| undo-recovery | 16 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 4 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 32 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 64 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo-recovery | 8 | 10.2.14 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.13 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| normal | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13094](https://jira.mariadb.org/browse/MDEV-13094)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | KNOWN\_BUGS [MDEV-13103](https://jira.mariadb.org/browse/MDEV-13103)(1) |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| crash | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.2.6 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.32 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 16 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 4 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 32 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 64 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| normal | 8 | 10.1.13 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 16 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 4 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 32 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 64 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| normal | 8 | 10.1.10 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | - | => | 10.2.14 (inbuilt) | Barracuda | on | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | - | => | 10.2.14 (inbuilt) | Barracuda | - | - | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | on | zlib | => | 10.2.14 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| undo | 16 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 4 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 32 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 64 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| undo | 8 | 10.1.22 (inbuilt) | Barracuda | - | zlib | => | 10.2.14 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| crash | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| crash | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| crash | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| crash | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| crash | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 32 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 64 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.7.21 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | **FAIL** | TEST\_FAILURE |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | on | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.2.14 (inbuilt) |  | - | - | - | **FAIL** | TEST\_FAILURE |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10214-release-upgrade-tests/>

10.2.5 Pre-release Upgrade Tests
================================

    Upgrade from 10.0
-----------------

 ### Tested revision

 b56262f69677fdb158b3d19dd8848e5802b2dd27

 ### Test date

 2017-03-27 02:05:09

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 2 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 3 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 4 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 5 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 6 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 7 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 8 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 9 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 10 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 11 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 12 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |

 
Upgrade from 10.1
-----------------

 ### Tested revision

 b56262f69677fdb158b3d19dd8848e5802b2dd27

 ### Test date

 2017-03-27 02:31:34

 ### Summary (FAIL)

 One test failed: [MDEV-12388](https://jira.mariadb.org/browse/MDEV-12388)

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 2 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 3 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 4 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 5 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 6 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 7 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 8 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 9 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 10 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 11 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 12 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 13 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 14 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 15 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 16 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 17 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 18 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 19 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 20 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 21 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 22 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 23 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 24 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 25 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 26 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 27 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 28 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 29 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 30 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 31 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 32 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 33 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 34 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 35 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 36 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 37 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 38 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 39 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 40 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 41 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 42 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 43 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 44 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 45 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 46 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 47 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 48 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 49 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 50 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 51 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 52 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 53 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 54 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 55 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 56 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 57 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 58 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 59 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 60 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 61 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 62 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 63 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 64 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 65 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 66 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 67 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 68 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 69 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 70 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 71 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-12388](https://jira.mariadb.org/browse/MDEV-12388) |
| 72 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 73 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 74 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 75 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 76 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 77 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 78 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 79 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 80 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 81 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 82 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 83 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 84 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 85 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 86 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 87 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 88 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 89 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 90 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 91 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 92 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 93 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 94 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 95 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 96 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 97 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 98 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 99 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 100 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 101 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 102 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 103 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 104 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 105 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 106 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 107 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 108 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 109 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 110 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 111 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 112 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 113 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 114 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 115 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 116 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 117 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 118 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 119 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 120 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 121 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 122 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 123 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 124 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 125 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 126 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 127 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 128 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 129 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 130 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 131 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 132 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 133 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 134 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 135 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 136 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 137 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 138 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 139 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 140 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 141 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 142 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 143 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 144 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 145 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 146 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 147 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 148 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 149 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 150 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 151 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 152 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 153 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 154 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 155 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 156 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 157 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 158 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |
| 159 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | - | zlib | - | OK |  |
| 160 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.2.5 (inbuilt) | on | zlib | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 b56262f69677fdb158b3d19dd8848e5802b2dd27

 ### Test date

 2017-03-28 14:00:57

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 2 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 3 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 4 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 5 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 6 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |

 
Upgrade from MySQL 5.7
----------------------

 ### Tested revision

 b56262f69677fdb158b3d19dd8848e5802b2dd27

 ### Test date

 2017-03-28 23:04:16

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 2 | normal | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 3 | normal | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 4 | normal | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 5 | normal | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 6 | normal | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 7 | normal | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 8 | normal | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 9 | normal | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 10 | normal | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 11 | crash | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 12 | crash | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 13 | crash | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 14 | crash | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 15 | crash | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 16 | crash | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 17 | crash | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 18 | crash | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 19 | crash | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 20 | crash | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 21 | normal | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 22 | normal | 32 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 23 | normal | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 24 | normal | 4 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 25 | normal | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 26 | normal | 16 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 27 | normal | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |
| 28 | normal | 64 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 29 | normal | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | - | - | - | OK |  |
| 30 | normal | 8 | 5.7.17 (inbuilt) | - | - | => | 10.2.5 (inbuilt) | on | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/1025-pre-release-upgrade-tests/>

10.1.25 Release Upgrade Tests
=============================

    Upgrade from 10.0
-----------------

 ### Tested revision

 da7604a2943f633df3b193e26ee20110bae9fa7a

 ### Test date

 2017-07-04 18:46:27

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | crash | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | crash | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 4 | crash | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 5 | crash | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 6 | crash | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 7 | crash | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 8 | crash | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 9 | crash | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 10 | crash | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 11 | crash | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 12 | crash | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 13 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 14 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 15 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 16 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 17 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 18 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 19 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 20 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 21 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 22 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 23 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 24 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |

 
Upgrade from 10.1
-----------------

 ### Tested revision

 da7604a2943f633df3b193e26ee20110bae9fa7a

 ### Test date

 2017-07-04 19:37:09

 ### Summary (FAIL)

 [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112), [MDEV-13113](https://jira.mariadb.org/browse/MDEV-13113), one unknown failure

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 64 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 2 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 3 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(31) |
| 4 | crash | 64 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 5 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 6 | crash | 64 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 7 | crash | 64 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 8 | crash | 64 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 9 | crash | 8 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 10 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 11 | crash | 8 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 12 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(14) |
| 13 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 14 | crash | 8 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 15 | crash | 8 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 16 | crash | 8 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 17 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | [MDEV-13113](https://jira.mariadb.org/browse/MDEV-13113) |
| 18 | crash | 16 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 19 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13113](https://jira.mariadb.org/browse/MDEV-13113) |
| 20 | crash | 16 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 21 | crash | 16 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 22 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | **FAIL** | [MDEV-13113](https://jira.mariadb.org/browse/MDEV-13113) |
| 23 | crash | 16 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 24 | crash | 16 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | **FAIL** | [MDEV-13113](https://jira.mariadb.org/browse/MDEV-13113) |
| 25 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 26 | crash | 32 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 27 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 28 | crash | 32 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 29 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(23) |
| 30 | crash | 32 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 31 | crash | 32 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 32 | crash | 32 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 33 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(7) |
| 34 | crash | 4 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 35 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | **FAIL** | UPGRADE\_FAILURE |
| 36 | crash | 4 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 37 | crash | 4 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 38 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 39 | crash | 4 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 40 | crash | 4 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 41 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 42 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 43 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 44 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 45 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 46 | normal | 8 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 47 | normal | 8 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 48 | normal | 8 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 49 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 50 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 51 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 52 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 53 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 54 | normal | 64 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 55 | normal | 64 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 56 | normal | 64 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 57 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 58 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 59 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 60 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 61 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 62 | normal | 32 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 63 | normal | 32 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 64 | normal | 32 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 65 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 66 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 67 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 68 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 69 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 70 | normal | 16 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 71 | normal | 16 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 72 | normal | 16 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 73 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 74 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 75 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 76 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 77 | normal | 4 | 10.1.20 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 78 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | OK |  |
| 79 | normal | 4 | 10.1.20 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 80 | normal | 4 | 10.1.20 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 da7604a2943f633df3b193e26ee20110bae9fa7a

 ### Test date

 2017-07-04 22:22:10

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 4 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 5 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 6 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 7 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 8 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 9 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 10 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 11 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 12 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |

 
Crash recovery
--------------

 ### Tested revision

 da7604a2943f633df3b193e26ee20110bae9fa7a

 ### Test date

 2017-07-04 22:47:13

 ### Summary (FAIL)

 [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.1.25 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 2 | crash | 16 | 10.1.25 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 3 | crash | 16 | 10.1.25 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 4 | crash | 16 | 10.1.25 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 5 | crash | 16 | 10.1.25 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 6 | crash | 16 | 10.1.25 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(39) |
| 7 | crash | 16 | 10.1.25 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 8 | crash | 16 | 10.1.25 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 9 | crash | 4 | 10.1.25 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 10 | crash | 4 | 10.1.25 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 11 | crash | 4 | 10.1.25 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 12 | crash | 4 | 10.1.25 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 13 | crash | 4 | 10.1.25 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(54) |
| 14 | crash | 4 | 10.1.25 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 15 | crash | 4 | 10.1.25 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 16 | crash | 4 | 10.1.25 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 17 | crash | 32 | 10.1.25 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 18 | crash | 32 | 10.1.25 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(36) |
| 19 | crash | 32 | 10.1.25 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 20 | crash | 32 | 10.1.25 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 21 | crash | 32 | 10.1.25 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 22 | crash | 32 | 10.1.25 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 23 | crash | 32 | 10.1.25 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 24 | crash | 32 | 10.1.25 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 25 | crash | 64 | 10.1.25 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |
| 26 | crash | 64 | 10.1.25 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 27 | crash | 64 | 10.1.25 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 28 | crash | 64 | 10.1.25 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 29 | crash | 64 | 10.1.25 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(21) |
| 30 | crash | 64 | 10.1.25 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 31 | crash | 64 | 10.1.25 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 32 | crash | 64 | 10.1.25 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 33 | crash | 8 | 10.1.25 (inbuilt) | Barracuda | on | zlib | => | 10.1.25 (inbuilt) | Barracuda | on | zlib | - | **FAIL** | [MDEV-13112](https://jira.mariadb.org/browse/MDEV-13112)(97) |
| 34 | crash | 8 | 10.1.25 (inbuilt) | Antelope | on | zlib | => | 10.1.25 (inbuilt) | Antelope | on | zlib | - | OK |  |
| 35 | crash | 8 | 10.1.25 (inbuilt) | Antelope | - | zlib | => | 10.1.25 (inbuilt) | Antelope | - | zlib | - | OK |  |
| 36 | crash | 8 | 10.1.25 (inbuilt) | Barracuda | - | zlib | => | 10.1.25 (inbuilt) | Barracuda | - | zlib | - | OK |  |
| 37 | crash | 8 | 10.1.25 (inbuilt) | Antelope | on | - | => | 10.1.25 (inbuilt) | Antelope | on | - | - | OK |  |
| 38 | crash | 8 | 10.1.25 (inbuilt) | Barracuda | on | - | => | 10.1.25 (inbuilt) | Barracuda | on | - | - | OK |  |
| 39 | crash | 8 | 10.1.25 (inbuilt) | Barracuda | - | - | => | 10.1.25 (inbuilt) | Barracuda | - | - | - | OK |  |
| 40 | crash | 8 | 10.1.25 (inbuilt) | Antelope | - | - | => | 10.1.25 (inbuilt) | Antelope | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10125-release-upgrade-tests/>

10.0.34 Release Upgrade Tests
=============================

    ### Tested revision

 d01dbe66a8bf9cb6031f95159c49100f9299a768

 ### Test date

 2018-02-01 07:13:41

 ### Summary

 All tests passed

 ### Details

 


| type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| undo-recovery | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo-recovery | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo-recovery | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| recovery | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| recovery | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| recovery | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.33 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 10.0.14 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 10.0.18 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| normal | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 16 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 4 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| undo | 8 | 5.6.39 (inbuilt) |  | - | - | => | 10.0.34 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.33 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| crash-downgrade | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 16 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 4 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |
| downgrade | 8 | 10.0.34 (inbuilt) |  | - | - | => | 10.0.14 (inbuilt) |  | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10034-release-upgrade-tests/>

10.0.32 Release Upgrade Tests
=============================

    Upgrade from 10.0
-----------------

 ### Tested revision

 d85d6c9c416aab85f1ded344a5b870d4cc56f9f6

 ### Test date

 2017-08-03 19:25:53

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | crash | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | crash | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 4 | crash | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 5 | crash | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 6 | crash | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 7 | normal | 4 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 8 | normal | 4 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 9 | normal | 8 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 10 | normal | 8 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 11 | normal | 16 | 10.0.28 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 12 | normal | 16 | 10.0.28 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 d85d6c9c416aab85f1ded344a5b870d4cc56f9f6

 ### Test date

 2017-08-03 19:45:21

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | normal | 16 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | normal | 16 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | normal | 4 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 4 | normal | 4 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 5 | normal | 8 | 5.6.35 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 6 | normal | 8 | 5.6.35 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |

 
Crash Recovery
--------------

 ### Tested revision

 d85d6c9c416aab85f1ded344a5b870d4cc56f9f6

 ### Test date

 2017-08-03 19:55:23

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | file format | encrypted | compressed |  | NEW version | file format | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.0.32 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 2 | crash | 16 | 10.0.32 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 3 | crash | 4 | 10.0.32 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |
| 4 | crash | 4 | 10.0.32 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 5 | crash | 8 | 10.0.32 (inbuilt) | Antelope | - | - | => | 10.0.32 (inbuilt) | Antelope | - | - | - | OK |  |
| 6 | crash | 8 | 10.0.32 (inbuilt) | Barracuda | - | - | => | 10.0.32 (inbuilt) | Barracuda | - | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10032-release-upgrade-tests/>

10.1.22 Pre-release Upgrade Tests
=================================

    Upgrade from 10.0
-----------------

 ### Tested revision

 dbd1d7ea8e96a2b4cff89ec889494700d634b3a3

 ### Test date

 2017-03-07 13:42:18

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 2 | crash | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 3 | crash | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 4 | crash | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 5 | crash | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 6 | crash | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 7 | crash | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 8 | crash | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 9 | crash | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 10 | crash | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 11 | crash | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 12 | crash | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 13 | crash | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 14 | crash | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 15 | crash | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 16 | crash | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 17 | crash | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 18 | crash | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 19 | crash | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 20 | crash | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 21 | crash | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 22 | crash | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 23 | crash | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 24 | crash | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 25 | crash | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 26 | crash | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 27 | crash | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 28 | crash | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 29 | crash | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 30 | crash | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 31 | crash | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 32 | crash | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 33 | crash | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 34 | crash | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 35 | crash | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 36 | crash | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 37 | crash | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 38 | crash | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 39 | crash | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 40 | crash | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 41 | crash | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 42 | crash | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 43 | crash | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 44 | crash | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 45 | crash | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 46 | crash | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 47 | crash | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 48 | crash | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 49 | normal | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 50 | normal | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 51 | normal | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 52 | normal | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 53 | normal | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 54 | normal | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 55 | normal | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 56 | normal | 4 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 57 | normal | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 58 | normal | 16 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 59 | normal | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 60 | normal | 8 | 10.0.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 61 | normal | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 62 | normal | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 63 | normal | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 64 | normal | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 65 | normal | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 66 | normal | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 67 | normal | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 68 | normal | 16 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 69 | normal | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 70 | normal | 4 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 71 | normal | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 72 | normal | 8 | 10.0.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 73 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 74 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 75 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 76 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 77 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 78 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 79 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 80 | normal | 4 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 81 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 82 | normal | 16 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 83 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 84 | normal | 8 | 10.0.29 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 85 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 86 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 87 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 88 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 89 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 90 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 91 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 92 | normal | 4 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 93 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 94 | normal | 16 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 95 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 96 | normal | 8 | 10.0.29 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |

 
Upgrade from 10.1
-----------------

 ### Tested revision

 adc91387e3add6d9c850b7c2a44760deaceb3638

 ### Test date

 2017-03-05 18:09:10

 ### Summary (FAIL)

 34 failures out of 1280 combinations, all associated with [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) (crash-upgrade from 10.1.10 with encryption enabled)

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 2 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 3 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 4 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 5 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 6 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 7 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 8 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 9 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 10 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 11 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 12 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 13 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 14 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 15 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 16 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 17 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 18 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 19 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 20 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 21 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 22 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 23 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 24 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 25 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 26 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 27 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 28 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 29 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 30 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 31 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 32 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 33 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 34 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 35 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 36 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 37 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 38 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 39 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 40 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 41 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 42 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 43 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 44 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 45 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 46 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 47 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 48 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 49 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 50 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 51 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 52 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 53 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 54 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 55 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 56 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 57 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 58 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 59 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 60 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 61 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 62 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 63 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 64 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 65 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 66 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 67 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 68 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 69 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 70 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 71 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 72 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 73 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 74 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 75 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 76 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 77 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 78 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 79 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 80 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 81 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 82 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 83 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 84 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 85 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 86 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 87 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 88 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 89 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 90 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 91 | crash | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 92 | crash | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 93 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 94 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 95 | crash | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 96 | crash | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 97 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 98 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 99 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 100 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 101 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 102 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 103 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 104 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 105 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 106 | crash | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 107 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 108 | crash | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 109 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 110 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 111 | crash | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 112 | crash | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 113 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 114 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 115 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 116 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 117 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 118 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 119 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 120 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 121 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 122 | crash | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 123 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 124 | crash | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 125 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 126 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 127 | crash | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 128 | crash | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 129 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 130 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 131 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 132 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 133 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 134 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 135 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 136 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 137 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 138 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 139 | crash | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 140 | crash | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 141 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 142 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 143 | crash | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 144 | crash | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 145 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 146 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 147 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 148 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 149 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 150 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 151 | crash | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 152 | crash | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 153 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 154 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 155 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 156 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 157 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 158 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 159 | crash | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 160 | crash | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 161 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 162 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 163 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 164 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 165 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 166 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 167 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 168 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 169 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 170 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 171 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 172 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 173 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 174 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 175 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 176 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 177 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 178 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 179 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 180 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 181 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 182 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 183 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 184 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 185 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 186 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 187 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 188 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 189 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 190 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 191 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 192 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 193 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 194 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 195 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 196 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 197 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 198 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 199 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 200 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 201 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 202 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 203 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 204 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 205 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 206 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 207 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 208 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 209 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 210 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 211 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 212 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 213 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 214 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 215 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 216 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 217 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 218 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 219 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 220 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 221 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 222 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 223 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 224 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 225 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 226 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 227 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 228 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 229 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 230 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 231 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 232 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 233 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 234 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 235 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 236 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 237 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 238 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 239 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 240 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 241 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 242 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 243 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 244 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 245 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 246 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 247 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 248 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 249 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 250 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 251 | crash | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 252 | crash | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 253 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 254 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 255 | crash | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 256 | crash | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 257 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 258 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 259 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 260 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 261 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 262 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 263 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 264 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 265 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 266 | crash | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 267 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 268 | crash | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 269 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 270 | crash | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 271 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 272 | crash | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 273 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 274 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 275 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 276 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 277 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 278 | crash | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 279 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 280 | crash | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 281 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 282 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 283 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 284 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 285 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 286 | crash | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 287 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 288 | crash | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 289 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 290 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 291 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 292 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 293 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 294 | crash | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 295 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 296 | crash | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 297 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 298 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 299 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 300 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 301 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 302 | crash | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 303 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 304 | crash | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 305 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 306 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 307 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 308 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 309 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 310 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 311 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 312 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 313 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 314 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 315 | crash | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 316 | crash | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 317 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 318 | crash | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 319 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 320 | crash | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 321 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 322 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 323 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 324 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 325 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 326 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 327 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 328 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 329 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 330 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 331 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 332 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 333 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 334 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 335 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 336 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 337 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 338 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 339 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 340 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 341 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 342 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 343 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 344 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 345 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 346 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 347 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 348 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 349 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 350 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 351 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 352 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 353 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 354 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 355 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 356 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 357 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 358 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 359 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 360 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 361 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 362 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 363 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 364 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 365 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 366 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 367 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 368 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 369 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 370 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 371 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 372 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 373 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 374 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 375 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 376 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 377 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 378 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 379 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 380 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 381 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 382 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 383 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 384 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 385 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 386 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 387 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 388 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 389 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 390 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 391 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 392 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 393 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 394 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 395 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 396 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 397 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 398 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 399 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 400 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 401 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 402 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 403 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 404 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 405 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 406 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 407 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 408 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 409 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 410 | crash | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 411 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 412 | crash | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 413 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 414 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 415 | crash | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 416 | crash | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 417 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 418 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 419 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 420 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 421 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 422 | crash | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 423 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 424 | crash | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 425 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 426 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 427 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 428 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 429 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 430 | crash | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 431 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 432 | crash | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 433 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 434 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 435 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 436 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 437 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 438 | crash | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 439 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 440 | crash | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 441 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 442 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 443 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 444 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 445 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 446 | crash | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 447 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 448 | crash | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 449 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 450 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 451 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 452 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 453 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 454 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | **FAIL** | [MDEV-9422](https://jira.mariadb.org/browse/MDEV-9422) |
| 455 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 456 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 457 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 458 | crash | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 459 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 460 | crash | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 461 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 462 | crash | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 463 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 464 | crash | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 465 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 466 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 467 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 468 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 469 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 470 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 471 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 472 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 473 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 474 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 475 | crash | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 476 | crash | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 477 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 478 | crash | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 479 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 480 | crash | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 481 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 482 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 483 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 484 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 485 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 486 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 487 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 488 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 489 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 490 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 491 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 492 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 493 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 494 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 495 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 496 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 497 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 498 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 499 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 500 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 501 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 502 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 503 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 504 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 505 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 506 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 507 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 508 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 509 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 510 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 511 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 512 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 513 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 514 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 515 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 516 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 517 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 518 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 519 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 520 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 521 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 522 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 523 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 524 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 525 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 526 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 527 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 528 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 529 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 530 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 531 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 532 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 533 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 534 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 535 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 536 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 537 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 538 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 539 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 540 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 541 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 542 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 543 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 544 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 545 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 546 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 547 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 548 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 549 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 550 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 551 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 552 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 553 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 554 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 555 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 556 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 557 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 558 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 559 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 560 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 561 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 562 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 563 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 564 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 565 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 566 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 567 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 568 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 569 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 570 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 571 | crash | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 572 | crash | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 573 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 574 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 575 | crash | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 576 | crash | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 577 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 578 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 579 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 580 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 581 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 582 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 583 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 584 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 585 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 586 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 587 | crash | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 588 | crash | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 589 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 590 | crash | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 591 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 592 | crash | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 593 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 594 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 595 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 596 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 597 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 598 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 599 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 600 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 601 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 602 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 603 | crash | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 604 | crash | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 605 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 606 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 607 | crash | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 608 | crash | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 609 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 610 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 611 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 612 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 613 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 614 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 615 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 616 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 617 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 618 | crash | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 619 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 620 | crash | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 621 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 622 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 623 | crash | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 624 | crash | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 625 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 626 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 627 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 628 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 629 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 630 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 631 | crash | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 632 | crash | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 633 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 634 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 635 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 636 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 637 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 638 | crash | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 639 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 640 | crash | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 641 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 642 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 643 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 644 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 645 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 646 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 647 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 648 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 649 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 650 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 651 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 652 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 653 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 654 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 655 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 656 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 657 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 658 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 659 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 660 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 661 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 662 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 663 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 664 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 665 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 666 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 667 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 668 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 669 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 670 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 671 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 672 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 673 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 674 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 675 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 676 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 677 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 678 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 679 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 680 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 681 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 682 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 683 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 684 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 685 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 686 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 687 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 688 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 689 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 690 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 691 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 692 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 693 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 694 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 695 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 696 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 697 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 698 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 699 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 700 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 701 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 702 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 703 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 704 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 705 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 706 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 707 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 708 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 709 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 710 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 711 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 712 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 713 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 714 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 715 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 716 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 717 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 718 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 719 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 720 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 721 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 722 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 723 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 724 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 725 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 726 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 727 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 728 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 729 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 730 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 731 | normal | 64 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 732 | normal | 64 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 733 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 734 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 735 | normal | 64 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 736 | normal | 64 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 737 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 738 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 739 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 740 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 741 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 742 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 743 | normal | 4 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 744 | normal | 4 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 745 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 746 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 747 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 748 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 749 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 750 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 751 | normal | 4 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 752 | normal | 4 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 753 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 754 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 755 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 756 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 757 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 758 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 759 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 760 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 761 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 762 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 763 | normal | 8 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 764 | normal | 8 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 765 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 766 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 767 | normal | 8 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 768 | normal | 8 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 769 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 770 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 771 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 772 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 773 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 774 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 775 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 776 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 777 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 778 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 779 | normal | 16 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 780 | normal | 16 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 781 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 782 | normal | 16 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 783 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 784 | normal | 16 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 785 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 786 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 787 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 788 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 789 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 790 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 791 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 792 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 793 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 794 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 795 | normal | 32 | 10.1.10 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 796 | normal | 32 | 10.1.10 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 797 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 798 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 799 | normal | 32 | 10.1.10 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 800 | normal | 32 | 10.1.10 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 801 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 802 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 803 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 804 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 805 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 806 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 807 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 808 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 809 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 810 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 811 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 812 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 813 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 814 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 815 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 816 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 817 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 818 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 819 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 820 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 821 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 822 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 823 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 824 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 825 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 826 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 827 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 828 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 829 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 830 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 831 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 832 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 833 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 834 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 835 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 836 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 837 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 838 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 839 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 840 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 841 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 842 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 843 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 844 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 845 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 846 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 847 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 848 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 849 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 850 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 851 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 852 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 853 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 854 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 855 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 856 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 857 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 858 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 859 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 860 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 861 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 862 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 863 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 864 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 865 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 866 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 867 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 868 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 869 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 870 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 871 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 872 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 873 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 874 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 875 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 876 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 877 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 878 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 879 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 880 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 881 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 882 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 883 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 884 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 885 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 886 | normal | 8 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 887 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 888 | normal | 8 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 889 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 890 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 891 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 892 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 893 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 894 | normal | 8 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 895 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 896 | normal | 8 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 897 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 898 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 899 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 900 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 901 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 902 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 903 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 904 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 905 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 906 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 907 | normal | 32 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 908 | normal | 32 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 909 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 910 | normal | 32 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 911 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 912 | normal | 32 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 913 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 914 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 915 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 916 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 917 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 918 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 919 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 920 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 921 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 922 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 923 | normal | 64 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 924 | normal | 64 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 925 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 926 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 927 | normal | 64 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 928 | normal | 64 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 929 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 930 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 931 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 932 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 933 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 934 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 935 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 936 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 937 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 938 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 939 | normal | 16 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 940 | normal | 16 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 941 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 942 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 943 | normal | 16 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 944 | normal | 16 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 945 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 946 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 947 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 948 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 949 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 950 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 951 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 952 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 953 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 954 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 955 | normal | 4 | 10.1.10 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 956 | normal | 4 | 10.1.10 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 957 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 958 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 959 | normal | 4 | 10.1.10 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 960 | normal | 4 | 10.1.10 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 961 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 962 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 963 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 964 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 965 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 966 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 967 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 968 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 969 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 970 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 971 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 972 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 973 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 974 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 975 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 976 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 977 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 978 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 979 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 980 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 981 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 982 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 983 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 984 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 985 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 986 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 987 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 988 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 989 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 990 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 991 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 992 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 993 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 994 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 995 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 996 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 997 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 998 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 999 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1000 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1001 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1002 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1003 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1004 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1005 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1006 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1007 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1008 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1009 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1010 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1011 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1012 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1013 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1014 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1015 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1016 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1017 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1018 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1019 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1020 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1021 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1022 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1023 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1024 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1025 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1026 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1027 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1028 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1029 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1030 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1031 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1032 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1033 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1034 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1035 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1036 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1037 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1038 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1039 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1040 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1041 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1042 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1043 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1044 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1045 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1046 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1047 | normal | 64 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1048 | normal | 64 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1049 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1050 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1051 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1052 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1053 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1054 | normal | 64 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1055 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1056 | normal | 64 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1057 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1058 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1059 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1060 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1061 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1062 | normal | 32 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1063 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1064 | normal | 32 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1065 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1066 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1067 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1068 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1069 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1070 | normal | 32 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1071 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1072 | normal | 32 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1073 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1074 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1075 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1076 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1077 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1078 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1079 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1080 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1081 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1082 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1083 | normal | 8 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1084 | normal | 8 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1085 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1086 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1087 | normal | 8 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1088 | normal | 8 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1089 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1090 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1091 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1092 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1093 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1094 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1095 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1096 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1097 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1098 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1099 | normal | 4 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1100 | normal | 4 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1101 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1102 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1103 | normal | 4 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1104 | normal | 4 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1105 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1106 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1107 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1108 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1109 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1110 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1111 | normal | 16 | 10.1.20 (InnoDB plugin) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1112 | normal | 16 | 10.1.20 (InnoDB plugin) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1113 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1114 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1115 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1116 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1117 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1118 | normal | 16 | 10.1.20 (InnoDB plugin) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1119 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1120 | normal | 16 | 10.1.20 (InnoDB plugin) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1121 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1122 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1123 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1124 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1125 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1126 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1127 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1128 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1129 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1130 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1131 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1132 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1133 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1134 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1135 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1136 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1137 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1138 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1139 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1140 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1141 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1142 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1143 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1144 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1145 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1146 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1147 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1148 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1149 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1150 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1151 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1152 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1153 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1154 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1155 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1156 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1157 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1158 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1159 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1160 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1161 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1162 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1163 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1164 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1165 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1166 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1167 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1168 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1169 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1170 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1171 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1172 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1173 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1174 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1175 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1176 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1177 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1178 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1179 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1180 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1181 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1182 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1183 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1184 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1185 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1186 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1187 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1188 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1189 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1190 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1191 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | zlib | - | OK |  |
| 1192 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | zlib | - | OK |  |
| 1193 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1194 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1195 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1196 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1197 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1198 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1199 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 1200 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 1201 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1202 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1203 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1204 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1205 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1206 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1207 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1208 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1209 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1210 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1211 | normal | 8 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1212 | normal | 8 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1213 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1214 | normal | 8 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1215 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1216 | normal | 8 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1217 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1218 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1219 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1220 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1221 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1222 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1223 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1224 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1225 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1226 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1227 | normal | 32 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1228 | normal | 32 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1229 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1230 | normal | 32 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1231 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1232 | normal | 32 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1233 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1234 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1235 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1236 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1237 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1238 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1239 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1240 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1241 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1242 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1243 | normal | 4 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1244 | normal | 4 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1245 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1246 | normal | 4 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1247 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1248 | normal | 4 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1249 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1250 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1251 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1252 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1253 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1254 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1255 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1256 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1257 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1258 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1259 | normal | 16 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1260 | normal | 16 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1261 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1262 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1263 | normal | 16 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1264 | normal | 16 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1265 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1266 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1267 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1268 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1269 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1270 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1271 | normal | 64 | 10.1.20 (inbuilt) | - | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1272 | normal | 64 | 10.1.20 (inbuilt) | on | zlib | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1273 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1274 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 1275 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1276 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 1277 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1278 | normal | 64 | 10.1.20 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |
| 1279 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | - | zlib | - | OK |  |
| 1280 | normal | 64 | 10.1.20 (inbuilt) | on | - | => | 10.1.22 (inbuilt) | on | zlib | - | OK |  |

 
Upgrade from MySQL 5.6
----------------------

 ### Tested revision

 dbd1d7ea8e96a2b4cff89ec889494700d634b3a3

 ### Test date

 2017-03-07 18:37:29

 ### Summary (PASS)

 All tests passed

 ### Details

 


| # | type | pagesize | OLD version | encrypted | compressed |  | NEW version | encrypted | compressed | readonly | result | notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | crash | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 2 | crash | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 3 | crash | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 4 | crash | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 5 | crash | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 6 | crash | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 7 | crash | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 8 | crash | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 9 | crash | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 10 | crash | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 11 | crash | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 12 | crash | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 13 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 14 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 15 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 16 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 17 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | - | - | - | OK |  |
| 18 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (InnoDB plugin) | on | - | - | OK |  |
| 19 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 20 | normal | 8 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 21 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 22 | normal | 4 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |
| 23 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | - | - | - | OK |  |
| 24 | normal | 16 | 5.6.35 (inbuilt) | - | - | => | 10.1.22 (inbuilt) | on | - | - | OK |  |

     Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/10122-pre-release-upgrade-tests/>

Installing MariaDB ColumnStore from the Development Buildbot Package Repositories
=================================================================================

    NOTE: Document for internal use only

 Introduction
============

 Installing Latest MariaDB ColumnStore developer built packages can be done from the yum, apt-get, and zypper Repositories based on the OS. These are the latest builds from the develop-1.1 branch for the 1.1.x build. 

 MariaDB ColumnStore packages which consist of:

 * MariaDB ColumnStore Platform
* MariaDB ColumnStore API (Bulk Write SDK)
* MariaDB ColumnStore Data-Adapters
* MariaDB ColumnStore Tools

 You can install MariaDB ColumnStore Packages from the Repositories for Single-Server installs and for Multi-Server installs utilizing the Non-Distributed feature where the packages are installed on all the servers in the cluster before the configuration and setup is performed.

 MariaDB ColumnStore Packages
============================

 Before install, make sure you go through the preparation guide to complete the system setup before installs the packages

 [https://mariadb.com/kb/en/library/preparing-for-columnstore-installation-11x/](../library/preparing-for-columnstore-installation-11x/index)

 CentOS 6
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/6/mariadb-columnstore-1.1.4-1-centos6.x86_64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/6/mariadb-columnstore-1.1.4-1-centos6.x86_64.rpm.tar.gz

```

### Adding the MariaDB ColumnStore YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore.repo

 
```
[mariadb-columnstore]
name=MariaDB ColumnStore
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore/yum/centos/6/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo yum --enablerepo=mariadb-columnstore clean metadata
sudo yum groups mark remove "MariaDB ColumnStore"
sudo yum groupinstall "MariaDB ColumnStore"

```

You can also install this way:

 
```
sudo yum --enablerepo=mariadb-columnstore clean metadata
sudo yum install mariadb-columnstore*

```

Install binary package:

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/6/mariadb-columnstore-1.1.4-1-centos6.x86_64.bin.tar.gz

```

CentOS 7
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/7/mariadb-columnstore-1.1.4-1-centos7.x86_64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/7/mariadb-columnstore-1.1.4-1-centos7.x86_64.rpm.tar.gz

```

### Adding the MariaDB ColumnStore YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore.repo

 
```
[mariadb-columnstore]
name=MariaDB ColumnStore
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore/yum/centos/7/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo yum --enablerepo=mariadb-columnstore clean metadata
sudo yum groups mark remove "MariaDB ColumnStore"
sudo yum groupinstall "MariaDB ColumnStore"

```

You can also install this way:

 
```
sudo yum --enablerepo=mariadb-columnstore clean metadata
sudo yum install mariadb-columnstore*

```

Install binary package:

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/centos/x86_64/7/mariadb-columnstore-1.1.4-1-centos7.x86_64.bin.tar.gz

```

SUSE 12
-------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/suse/x86_64/12//mariadb-columnstore-1.1.4-1-sles12.x86_64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/suse/x86_64/12//mariadb-columnstore-1.1.4-1-sles12.x86_64.rpm.tar.gz

```

### Adding the MariaDB ColumnStore ZYPPER repository

 Add new file with repository information, /etc/zypp/repos.d/mariadb-columnstore.repo

 
```
[mariadb-columnstore]
name=mariadb-columnstore
enabled=1
autorefresh=0
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore/yum/sles/12/x86_64
type=rpm-md

```

Download the MariaDB ColumnStore key

 
```
rpm --import http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo zypper refresh
sudo zypper install mariadb-columnstore*

```

Install binary package:

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/suse/x86_64/12/mariadb-columnstore-1.1.4-1-sles12.x86_64.bin.tar.gz

```

Debian 8
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/jessie/main/binary_amd64/mariadb-columnstore-1.1.4-1-jessie.amd64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/jessie/main/binary_amd64/mariadb-columnstore-1.1.4-1-jessie.amd64.deb.tar.gz

```

### Adding the MariaDB ColumnStore APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore/repo/debian8 jessie main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore*

```

Install binary package:

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/jessie/main/binary_adm64/mariadb-columnstore-1.1.4-1-jessie.amd64.bin.tar.gz

```

Debian 9
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/stretch/main/binary_amd64/mariadb-columnstore-1.1.4-1-stretch.amd64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/stretch/main/binary_amd64/mariadb-columnstore-1.1.4-1-stretch.amd64.deb.tar.gz

```

### Adding the MariaDB ColumnStore APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore/repo/debian9 stretch main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore*

```

Install binary package:

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/debian/dists/stretch/main/binary_adm64/mariadb-columnstore-1.1.4-1-stretch.amd64.bin.tar.gz

```

Ubuntu 16
---------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore/ubuntu/dists/xenial/main/binary_amd64/mariadb-columnstore-1.1.4-1-xenial.amd64.bin.tar.gz
wget http://18.232.251.159/repos/latest/mariadb-columnstore/ubuntu/dists/xenial/main/binary_amd64/mariadb-columnstore-1.1.4-1-xenial.amd64.deb.tar.gz

```

### Adding the MariaDB ColumnStore APT-GET repository

 Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore/repo/ubuntu16 xenial main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore*

```

After installation
------------------

 After the installation completes, follow the configuration and startup steps in the Single-Node and Multi-Node Installation guides using the [Non-Distributed Install feature](../library/installing-and-configuring-a-multi-server-columnstore-system-11x/index#non-distributed-install).

 MariaDB ColumnStore API (Bulk Write SDK) Package
================================================

 Additional information on the ColumnStore API (Bulk Write SDK):

 [https://mariadb.com/kb/en/library/columnstore-bulk-write-sdk/](../library/columnstore-bulk-write-sdk/index)

 CentOS 7
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-api/yum/centos/7/x86_64/mariadb-columnstore-api-1.1.4-1-x86_64-centos7.rpm

```

### Adding the MariaDB ColumnStore API YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore-api.repo

 
```
[mariadb-columnstore-api]
name=MariaDB ColumnStore API
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore-api/yum/centos/7/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore API

 With the repo file in place you can now install MariaDB ColumnStore API like so:

 
```
sudo yum --enablerepo=mariadb-columnstore-api clean metadata
sudo yum install mariadb-columnstore-api

```

Debian 8
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/debian8/pool/main/m/mariadb-columnstore-api/mariadb-columnstore-api_1.1.4_amd64.deb

```

### Adding the MariaDB ColumnStore API APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-api.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/debian8 jessie main
```

<</code>>

 Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore API

 With the repo file in place you can now install MariaDB ColumnStore API like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-api

```

Debian 9
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/debian9/pool/main/m/mariadb-columnstore-api/mariadb-columnstore-api_1.1.4_amd64.deb

```

### Adding the MariaDB ColumnStore API APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-api.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/debian9 stretch main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore API

 With the repo file in place you can now install MariaDB ColumnStore API like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-api

```

Ubuntu 16
---------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/ubuntu16/pool/main/m/mariadb-columnstore-api/mariadb-columnstore-api_1.1.4_amd64.deb

```

### Adding the MariaDB ColumnStore API APT-GET repository

 Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-api.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-api/repo/ubuntu16 xenial main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore API

 With the repo file in place you can now install MariaDB ColumnStore API like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-api

```

MariaDB ColumnStore Tools Package
=================================

 Additional information on the Backup and Restore Tool:

 [https://mariadb.com/kb/en/library/backup-and-restore-for-mariadb-columnstore-110-onwards/](../library/backup-and-restore-for-mariadb-columnstore-110-onwards/index)

 CentOS 6
--------

 ### Adding the MariaDB ColumnStore Tools YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore-tools.repo

 
```
[mariadb-columnstore-tools]
name=MariaDB ColumnStore Tools
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore-tools/yum/centos/6/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore Tools

 With the repo file in place you can now install MariaDB ColumnStore Tools like so:

 
```
sudo yum --enablerepo=mariadb-columnstore-tools clean metadata
sudo yum install mariadb-columnstore-tools

```

CentOS 7
--------

 ### Adding the MariaDB ColumnStore Tools YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore-tools.repo

 
```
[mariadb-columnstore-tools]
name=MariaDB ColumnStore Tools
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore-tools/yum/centos/7/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore Tools

 With the repo file in place you can now install MariaDB ColumnStore Tools like so:

 
```
sudo yum --enablerepo=mariadb-columnstore-tools clean metadata
sudo yum install mariadb-columnstore-tools

```

SUSE 12
-------

 ### Adding the MariaDB ColumnStore Tools ZYPPER repository

 Add new file with repository information, /etc/zypp/repos.d/mariadb-columnstore-tools.repo

 
```
[mariadb-columnstore-tools]
name=mariadb-columnstore-tools
enabled=1
autorefresh=0
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore-tools/yum/sles/12/x86_64
type=rpm-md

```

Download the MariaDB ColumnStore key

 
```
rpm --import http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore

```

### Installing MariaDB ColumnStore

 With the repo file in place you can now install MariaDB ColumnStore like so:

 
```
sudo zypper refresh
sudo zypper install mariadb-columnstore-tools

```

Debian 8
--------

 ### Adding the MariaDB ColumnStore Tools APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-tools.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-tools/repo/debian8 jessie main
```

<</code>>

 Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Tools

 With the repo file in place you can now install MariaDB ColumnStore Tools like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-tools

```

Debian 9
--------

 ### Adding the MariaDB ColumnStore Tools APT-GET repository

 Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-tools.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-tools/repo/debian9 stretch main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Tools

 With the repo file in place you can now install MariaDB ColumnStore Tools like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-tools

```

Ubuntu 16
---------

 ### Adding the MariaDB ColumnStore Tools APT-GET repository

 Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-tools.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-tools/repo/ubuntu16 xenial main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Tools

 With the repo file in place you can now install MariaDB ColumnStore Tools like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-tools

```

MariaDB ColumnStore Data Adapters Packages
==========================================

 Additional information on the Data Adapters:

 [https://mariadb.com/kb/en/library/columnstore-streaming-data-adapters/](../library/columnstore-streaming-data-adapters/index)

 NOTE: MaxScale CDC Connector requires the MariaDB MaxScale package be installed first.

 The MariaDB ColumnStore Data Adapters Packages are:

 * Kafka Adapters
* Maxscale CDC Adapters

 Kafka install package dependencies:

 * N/A

 Maxscale CDC install package dependencies::

 * MaxScale CDC Connector
* MariaDB ColumnStore API
* MariaDB MaxScale

 CentOS 7
--------

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/yum/centos/7/x86_64/mariadb-columnstore-kafka-adapters-1.1.4-1-x86_64-centos7.rpm
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/yum/centos/7/x86_64/mariadb-columnstore-maxscale-cdc-adapters-1.1.4-1-x86_64-centos7.rpm

```

### Adding the MariaDB ColumnStore Data Adapters YUM repository

 Add new file with repository information, /etc/yum.repos.d/mariadb-columnstore-data-adapters.repo

 
```
[mariadb-columnstore-data-adapters]
name=MariaDB ColumnStore Data Adapters
baseurl=http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/yum/centos/7/x86_64/
gpgkey=http://18.232.251.159/repos/RPM-GPG-KEY-MariaDB-ColumnStore
gpgcheck=1

```

### Installing MariaDB ColumnStore Data Adapters

 With the repo file in place you can now install MariaDB ColumnStore Maxscale CDC Data Adapters like so:

 
```
sudo yum --enablerepo=mariadb-columnstore-data-adapters clean metadata
sudo yum install mariadb-columnstore-maxscale-cdc-adapters

```

With the repo file in place you can now install MariaDB ColumnStore Kafka Data Adapters like so:

 
```
sudo yum --enablerepo=mariadb-columnstore-data-adapters clean metadata
sudo yum install mariadb-columnstore-kafka-adapters

```

Debian 8
--------

 ### Adding the MariaDB ColumnStore Data Adapters APT-GET repository

 ### Using wget to retrieve packages

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian8/pool/main/m/mariadb-columnstore-kafka-adapters/mariadb-columnstore-kafka-adapters_1.1.4_amd64.deb
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian8/pool/main/m/mariadb-columnstore-maxscale-cdc-adapters/mariadb-columnstore-maxscale-cdc-adapters_1.1.4_amd64.deb

```

Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-data-adapters.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian8 jessie main
```

<</code>>

 Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Data Adapters

 With the repo file in place you can now install MariaDB ColumnStore Maxscale CDC Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-maxscale-cdc-adapters

```

With the repo file in place you can now install MariaDB ColumnStore Kafka Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-kafka-adapters

```

Debian 9
--------

 ### Adding the MariaDB ColumnStore Data Adapters APT-GET repository

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian9/pool/main/m/mariadb-columnstore-kafka-adapters/mariadb-columnstore-kafka-adapters_1.1.4_amd64.deb
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian9/pool/main/m/mariadb-columnstore-maxscale-cdc-adapters/mariadb-columnstore-maxscale-cdc-adapters_1.1.4_amd64.deb

```

Install package:

 
```
sudo apt-get install apt-transport-https

```

Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-data-adapters.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/debian9 stretch main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/latest/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Data Adapters

 With the repo file in place you can now install MariaDB ColumnStores Maxscale CDC Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-maxscale-cdc-adapters

```

With the repo file in place you can now install MariaDB ColumnStores Kafka Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-kafka-adapters

```

Ubuntu 16
---------

 
```
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/ubuntu16/pool/main/m/mariadb-columnstore-kafka-adapters/mariadb-columnstore-kafka-adapters_1.1.4_amd64.deb
wget http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/ubuntu16/pool/main/m/mariadb-columnstore-maxscale-cdc-adapters/mariadb-columnstore-maxscale-cdc-adapters_1.1.4_amd64.deb

```

### Adding the MariaDB ColumnStore Data Adapters APT-GET repository

 Add new file with repository information, /etc/apt/sources.list.d/mariab-columnstore-data-adapters.list

 
```
deb http://18.232.251.159/repos/latest/mariadb-columnstore-data-adapters/repo/ubuntu16 xenial main

```

Download the MariaDB ColumnStore key

 
```
wget -qO - http://18.232.251.159/repos/MariaDB-ColumnStore.gpg.key | sudo apt-key add -

```

### Installing MariaDB ColumnStore Data Adapters

 With the repo file in place you can now install MariaDB ColumnStore Maxscale CDC Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-maxscale-cdc-adapters

```

With the repo file in place you can now install MariaDB ColumnStore Kafka Data Adapters like so:

 
```
sudo apt-get update
sudo apt-get install mariadb-columnstore-kafka-adapters

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/7758/>

Buildbot Development
====================

    Developing on the Buildbot code
-------------------------------

 Buildbot has all of the right ideas for solving the problem of maintaining a complex codebase like MariaDB at a high level of quality. However, there are some smaller fixes and extensions we need to develop on the Buildbot code.

 Here I describe how I set up an environment for hacking on the buildbot code. Readers beware, I am a Perl guy, so this may not reflect how a Python person would choose to do things.

 First I installed the virtualenv Python package:

 
```
tar zxf virtualenv-1.3.3.tar.gz 
cd virtualenv-1.3.3/
mkdir -p /home/knielsen/python/lib/python/
PYTHONPATH="$HOME/python/lib/python" python setup.py install --home="$HOME/python"
cd ..
PYTHONPATH="$HOME/python/lib/python" ~/python/bin/virtualenv sandbox

```

Then I cloned the latest BuildBot tree from the Git repository:

 
```
git clone git://github.com/djmitche/buildbot.git
cd buildbot/

```

Install the BuildBot code in the virtualenv sandbox in development mode and run the test suite.

 (The virtualenv stuff has a script sandbox/bin/activate that is the recommended way to use things. However, I really dislike keeping that kind of state in the shell, since it means shell commands (for example copy-pasted from history) will behave differently depending on when and where they are run. That is the reason for passing the PYTHONPATH directly on the command line.)

 
```
PYTHONPATH="$HOME/python/lib/python" ~/devel/buildbot/sandbox/bin/python setup.py develop
PYTHONPATH="$HOME/python/lib/python" ~/devel/buildbot/sandbox/bin/python /usr/bin/trial buildbot.test

```

 *[I get the error "error: Could not find suitable distribution for Requirement.parse('Twisted==2.5.0')" on the first of these commands, but things seem to work ok anyway (I installed all buildbot dependencies via Ubuntu apt-get packages).]*

 Once that works, one can install a master and a slave and start them running each in their own terminal window for easy access to log:

 
```
cd ..
PYTHONPATH="$HOME/python/lib/python" sandbox/bin/buildbot create-master master
cp buildbot/contrib/bzr_buildbot.py master/
# Edit master/master.cfg as appropriate
cd master
PYTHONPATH="$HOME/python/lib/python" ../sandbox/bin/python /usr/bin/twistd --nodaemon --no_save -y buildbot.tac

cd ..
PYTHONPATH="$HOME/python/lib/python" sandbox/bin/buildbot create-slave slave localhost:9989 test testpass
# Edit slave/info/* as appropriate
cd slave
PYTHONPATH="$HOME/python/lib/python" ../sandbox/bin/python /usr/bin/twistd --nodaemon --no_save -y buildbot.tac


```

With this I was able to hack away at the code and just restart the master and slave to test stuff. The web status pages will be on <http://localhost:8010/>

 See also
--------

 * [BuildBot ToDo](../buildbot-todo/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-buildbot-development/>

Buildbot Database Schema
========================

    This page describes the database schema used by Buildbot to save results from test runs.

 The idea is to be able to use this data from outside of Buildbot for things like additional web pages presenting test results, or search/data mining facilities for searching for test failures.

 Accessing the database
----------------------

 The plan is to make remote database connections available to community members. For this, we need to set up a slave host replicating the master Buildbot database (which would in any case be good to isolate the running Buildbot from possibly high load from queries).

 However, for now the database access is only available locally on the machine (hasky) running the buildbot master.

 Schema
------

 The most current information about the schema used is available in the file `buildbot/process/mtrlogobserver.py` in the Buildbot sources. As the code evolves and more kinds of information is made available in the database, the schema might be extended, but the schema description in the source code should always be up-to-date.

 ### The `test_run` table

 This table has one row for every test run that Buildbot does. Thus, each row corresponds to one cell in the [<http://askmonty.org/buildbot/waterfall> Waterfall display]. The format of the table is as follows:

 
```
CREATE TABLE test_run(
    id INT PRIMARY KEY AUTO_INCREMENT,
    branch VARCHAR(100),
    revision VARCHAR(32) NOT NULL,
    platform VARCHAR(100) NOT NULL,
    dt TIMESTAMP NOT NULL,
    bbnum INT NOT NULL,
    typ VARCHAR(32) NOT NULL,
    info VARCHAR(255),
    KEY (branch, revision),
    KEY (dt),
    KEY (platform, bbnum)
) ENGINE=innodb

```

* **id:** Primary key, just an auto\_increment id.
* **branch:** This is the name of the bzr branch of the test run.
* **revision:** The Bzr revision number tested.
* **platform:** The name of the builder that ran the test.
* **dt:** Date when the buildbot run was started.
* **bbnum:** The Buildbot '''build number''' which together with `platform` uniquely identifies a build within Buildbot.
* **typ:** Concise abbreviation describing the kind of test. For example `pr` for --ps-protocol with row based replication, or `nm` for normal run with mixed-mode replication.
* **info:** Short textual description of the kind of test run.

 ### The `test_failure` table

 This table has one row for every test failure encountered:

 
```
CREATE TABLE test_failure(
    test_run_id INT NOT NULL,
    test_name VARCHAR(100) NOT NULL,
    test_variant VARCHAR(16) NOT NULL,
    info_text VARCHAR(255),
    failure_text TEXT,
    PRIMARY KEY (test_run_id, test_name, test_variant)
) ENGINE=innodb

```

* **test\_run\_id:** This identifies the test run in which the test failure occured (eg. it is a foreign key to `id` in table `test_run`).
* **test\_name:** The name of the test that failed, eg. `main.information_schema`.
* **test\_variant:** Some tests are run multiple times in different variants. Ie. many replication tests are run under both statement-based, mixed-mode, and row-based replication. The variant will be 'stmt', 'mix', or 'row' accordingly. For tests that do not have multiple variants, the value will be the empty string (ie. not a **NULL** value).
* **info\_text:** This is a short description that mysql-test-run.pl sometimes gives for some kinds of test failures (for example "timeout").
* **failure\_text:** This is the entire output from mysql-test-run.pl concerning this test failure. It usually contains the diff against the result file, a stacktrace for a crash, etc. This is useful to run `LIKE` queries against when searching for test failures similar to one being investigated.

 ### The `test_warnings` table

 This table holds information about test problems that were detected after a test case ran, during server restart (typically by finding an error or warning message in the server error log files). A typical example of this is a memory leak or a crash during server shutdown.

 Such a failure can not be attributed to a specific test case, as it could be caused by any of the tests run against the server since last restart, or could even be a general problem not caused by any test case. Instead, for each occurence, this table provides a list of names of the tests that were run by the server prior to detecting the error or warning.

 
```
CREATE TABLE test_warnings(
    test_run_id INT NOT NULL,
    list_id INT NOT NULL,
    list_idx INT NOT NULL,
    test_name VARCHAR(100) NOT NULL,
    PRIMARY KEY (test_run_id, list_id, list_idx)
) ENGINE=innodb

```

* **test\_run\_id:** Identifies the corresponding row in table <code>test\_run</code>.
* **list\_id:** This is a counter for occurences of warnings within each test run (ie. it starts over from 0 again for each different value of <code>test\_run\_id</code>).
* **list\_idx:** This is a counter for each test name (ie. it starts over from 0 again for each different value of <code>test\_run\_id</code> ''and'' <code>list\_id</code>).
* **test\_name:** The name of the test run by the server prior to seeing the warning.

 Sample queries
--------------

 Show all platforms that failed for a particular revision of a particular branch:

 
```
select platform
  from test_run r
where branch = 'mysql-6.0-testing2'
  and revision = '2819'
  and (exists (select * from test_failure f where f.test_run_id = r.id)
    or exists (select * from test_warnings w where w.test_run_id = r.id));

```

Find failures similar to a given failure being investigated:

 
```
select branch, revision, platform, test_name, test_variant, failure_text
  from  test_failure f
  inner join test_run r on (f.test_run_id = r.id)
  where failure_text LIKE "%--protocol=TCP' failed%";

```

Check which branches a specific kind of failure has occured in:

 
```
select branch, count(*)
  from test_failure f
  inner join test_run r on (f.test_run_id = r.id)
  where failure_text LIKE "%--protocol=TCP' failed%"
  group by branch;

```

Find all test runs where a given test was run against a server that later had warnings in the error log, and also count the number of occurences of this event in each run:

 
```
select branch, revision, platform, count(*)
  from test_warnings w
  inner join test_run r on (w.test_run_id = r.id)
  where test_name = 'rpl.rpl_plugin_load'
  group by r.id;

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-buildbot-database-schema/>

Buildbot ToDo
=============

    High-priority, High-ROI items
-----------------------------

 * Ability on the web pages to mark certain builds of high priority, so they will be processed before others as build slaves become available. It must be possible to mark pending builds so not only individually, but also by branch, as well as by (branch,revision). The feature should probably interact in a meaningful way with the existing "nextBuild" ability to prioritise builds (<http://buildbot.net/buildbot/docs/0.8.4/full.html#Prioritizing-Builds>). Eg. it could set appropriate properties somewhere that would be available to the nextBuild function.
* We need a way to kill all running builds, and remove all pending builds, for a given combination of branch and revision. It is possible to manually cancel a pending or running build, but this becomes extremely inconvenient when there are many builders.
	+ Comments from buildbot mailing list: "There is already a button (hidden on the change page) for stopping all builds associated to a change. Unfortunately, the only way to get to this page seems to be through the waterfall." "Note that currently, the button on the change page only cancels still-pending builds, it does not stop builds in progress."
* Fix problem when pushing multiple bzr revisions at one time:
	+ Buildbot should wait a few moments before starting a build, and then start building the latest (currently it seems to build the first revision immedeately, and even often seems to not build the latest revision at all, getting confused about the order)
	+ When pushing a change that changes revision numbers, the grid display can get really confused, would be nice to fix this somehow.
* Any failure other than compile/test failure should mean a re-run. Failures like buildslave reboot or loss of connection or timeout of bazaar operation should be interpreted as if the build has never happened, and the system should re-try building.
* In the bzr source step, retry the checkout a couple of times if it fails (to be more robust against temporary Launchpad problems, which we see a number of). Could maybe be done as a general Buildbot optional feature for all revision control systems supported, or maybe specific for the bzr depending on what can work.
* Get PBXT test suite fixed in `--valgrind`; once that is done include it in the list of main suites so that it is tested on all platforms (and remove the special extra pbxt test steps in some Buildbot builds, as they will no longer be needed).
* Load statistics. We need it to be able to see if adding another tree will starve the buildbot:
	+ Percentage of busy time for available slaves
	+ Median/Max response time (How much time do I have to wait after I've pushed for test run to complete)
* Fix that mysql-test-run uses `--skip-ssl` by default.
* Fix that `mysql-test-run.pl --mem` doesn't properly clean up `/dev/shm/var*` (so that we can use `--mem` and `--parallel` option to speed up the more powerful machines).
* For triggered builds (ie. one builder makes a source tarball which another builder consumes), make it so that the pushed changesets are also transfered, so the blamelist on the build page works (currently the blame list is empty).
* Upgrade to Buildbot 0.8 on the master. Then use the facility to use a MariaDB server as backend for both speedup (hopefully) and more flexible querying of buildbot history.

 Lower priority items
--------------------

 * It should be easier to setup for a new user. Ideally, there should be one tarball that one can download, unpack and run. Within the tarball there should be a script and/or config files which allow to add the buildslave into automatic startup. The following should not be there:
	+ Dependence of buildslave on a load of python libraries. Ship them.
	+ Same for bzr
	+ Same for mysqld itself. Dl/make/make-install everything we need in the buildbot directory.

 If the above is not done, we'll never get much participation from old or unusual machines. The owners of such machines do not have the latest libraries, installing them requires some manual effort, which simply sets the bar too high.

 * Check archivist observation/bug that build slave `uname` info disappears when slave is disconnected.
* Self refresh at a time interval (ajax maybe to reduce transfer) so users can know when to fire up a slave.
* In the waterfall page, second line from top is "current activity". When displaying a particular branch ("?branch=5.1"), the "current activity" for hosts that are currently building another branch could also display the name of the branch (as a link to waterfall page for that branch) to avoid confusion that it is active on the current branch.
* Run with `--valgrind-mysqld` instead of `--valgrind`. Little point in Valgrinding mysqltest when we in any case ignore any errors in that program.
* Show pending builds for a slave on the 'builders' page, eg. <http://askmonty.org/buildbot/builders/hardy-x86-rtai>
* Show dates in local time of the client. One way is with Javascript: <http://articles.techrepublic.com.com/5100-10878_11-6016329.html> (would be nice if some dates were still shown when javascript is not available).
* Check if InnoDB is fixed sufficiently to have no Valgrind leaks with `innodb_use_sys_malloc`; if so remove hack in `mysql-test-run.pl` to disable this in valgrind case.
* Fix problem that illegal regexp causes build exception (example: <https://buildbot.askmonty.org/buildbot/builders/sol-sparc-32/builds/157/steps/compile/logs/err.text>). The problem is that Buildbot grabs regexps from the suppression file in the MariaDB tree and tries to compile them; if this throws exception, then the exception should be caught (and possibly warned about), not crash the whole build.

 Improve binary package build and test
-------------------------------------

 * Add `apt-get source mariadb-server` checking in buildbot (for package testing).
* Add testing of bintar package with real start of server [mysqld\_safe](../mysqld_safe/index) and also test on different distro/version than what was built (eg hardy<->jaunty).
* In package build, sign .debs with dummy key, to more accurately test the real build process.
* Switch to build the bintar packages on centos 5, to work with older glibc versions? Or maybe even Debian 4 which is older I think? But do the install test in Buildbot also on other/newer distros (should probably test on several in each build).
* Add a test step for .deb that tests upgrading from an earlier version of MariaDB (currently we only check upgrade from MySQL).
* Add a 'follow log' feature to runvm (which does `ssh guest tail -f log > log`). Use this in the Buildbot packaging step that runs mysql-test-run.pl, so that we can get mysqld.X.err.Y server logs available like for the non-kvm builds.
* For runvm: add the options "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" to the ssh command used to login to the guest vm, so we do not get a login failure due to different host keys in different guests.

 Staging trees
-------------

 Idea is to set it up so that each developer/group has a stating tree. Any push to this tree will first get a full round of testing in Buildbot. If all results are green after this, it will automatically be pushed to the main tree. If another push gets in first, it will automatically merge the new stuff and re-try a full Buildbot test. If there is a problem (test failure or merge conflict), it will send mail with details.

 * Get something working, simple initially.
* Staging tree per-captain
* `mysqltest --require` not-staging to speed up Valgrind

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-todo/>

Branch Protection Using Buildbot
================================

     MariaDB uses branch protection to ensure that pushes to the MariaDB Server git repository cannot be made without first passing a series of tests. This page aims to describe what a developer should do in order to ensure that their changes get pushed to the main repository.

 The current protected branches are the main branches **10.X** and release branches **bb-10.X-release\***

 ### Protected Branches Flow

 1. Rebase your work on top of the latest main branch. `git rebase 10.2`
2. Push to bb-\* branch
3. Wait for all the checks to run
4. If all checks are successful you can push to the main branch to be the same as bb-\* branch
5. If not (failed checks), check the build status, make changes accordingly and repeat this flow

 ### Protected Branches Builders

 The following are the **only** required builders at this point:

 1. amd64-centos-7
2. amd64-debian-10
3. amd64-fedora-35
4. amd64-ubuntu-2004-clang11
5. amd64-windows
6. amd64-windows-packages

 The protected branches builders run a subset of tests in order to avoid sporadic failures. The list is defined by:

 
```
--suite=main --skip-test="^stack_crash$|^float$|^derived_split_innodb$|^mysql_client_test$|^kill$|^processlist_not_embedded$|^sp-big$"

```

All other checks are not required in order to make the push. However, please take a look at all the builders and look for failures.

 #### Disabled Protected Branches

 1. ppc64le-rhel-8 (temporarily disabled, pending network bottleneck fix)
2. aarch64-debian-10 (temporarily disabled, till more compute power)

 ### Viewing Build Status

 The build status can be seen directly from GitHub near the commit message. Below, you can find an example (please note the **yellow dot** near the commit message):

 ![Commit example]

 If you click on the **yellow dot**, you can find the list of checks performed and their status, as shown below:

 ![Build status]

 By clicking on **Details** you will be redirected to the buildbot page showing all the build details.

 Alternatively, you can look for the builds on the [buildbot Grid View](https://buildbot.mariadb.org/#/grid). This allows filtering by branch, so to only see changes for one particular branch you can use <https://buildbot.mariadb.org/#/grid?branch=10.5>.

 ### Status and Action Items

 * Yellow dot - specifies that one or more of checks are not yet completed.
	+ Action item: Wait for all the checks to finish
* Green tick - all checks were successful
	+ Action item: No specific action is needed. The push can go through!
* Red X - one or more checks have failed
	+ Action item: Look at the status of failing builds and fix potential issues

 Note: Only buildbot and not external CI tests (Travis, AppVeyor, etc) are currently in the protected branches criteria. Please take note of other failures, and if they are acceptable and explainable, then merge.

 ### Re-trigger Checks

 In some cases it might be useful to re-trigger one or more checks. This can easily be done from the <https://buildbot.mariadb.org> interface. The steps are:

 1. Login to <https://buildbot.mariadb.org> using the GitHub credentials: Hit the "Anonymous" button from the upper right corner and then "Login with GitHub" as shown below:
	* ![Login]
2. Open the build details of the build you want to re-trigger
3. Hit the "Rebuild" button from the upper right corner

 **Note**: If you want to re-trigger all checks, the easiest approach is to make a new push. Alternatively, you can follow the above steps for all the checks

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/branch-protection-using-buildbot/>

Buildbot runvm
==============

    One type of build we do in BuildBot is to build and test [MariaDB](../mariadb/index) binary packages for the platforms we release on. We build and test packages for Debian (4 and 5), Ubuntu (8.04 to 10.04), Centos 5, and generic Linux; amd64 and i386 architectures. This testing is done with virtual machines run in [KVM](http://www.linux-kvm.org/page/Main_Page).

 To better control the startup and shutdown of the virtual machines we use a small wrapper around KVM we developed called **runvm**. The purpose of this tool is to make it easy to boot up a virtual machine, run some build commands inside it, and shut it down cleanly. 

 This wrapper encapsulates the steps needed to boot up a virtual machine, run a series of commands inside it, and shut it down gracefully afterwards. Some special care is taken in the script to ensure that the virtual machine is always shut down after use (gracefully if possible), even in case of various failures or the loss of the parent process or controlling TTY. And if a conflicting virtual machine somehow manages to escape shutdown, runvm automatically attempts to terminate it before starting a new one. This extra robustness is important for fully automated testing as in our [Buildbot](../buildbot/index) setup, to ensure that the system can run unattended for longer periods of time. 

 Essentially, instead of a normal Buildbot session which would do something like this on the slave:

 
```
./configure && make

```

We instead use *runvm* to do the same inside a virtual machine running as a KVM guest with the build slave as host:

 
```
runvm image.qcow2 "./configure" "make"

```

See the **runvm Usage Examples** or **runvm --help** sections below for more detailed examples, but this is the basic idea.

 runvm Usage Examples
--------------------

 ### Usage Example One

 Here is an example command you could use to run a build inside a virtual machine using runvm: 

 
```
runvm --port=2222 ubuntu-hardy-i386.qcow2 \
  "= scp -P 2222 mariadb-5.1.41-rc.tar.gz localhost:" \
  "tar zxf mariadb-5.1.41-rc.tar.gz" \
  "cd mariadb-5.1.41-rc && ./configure" \
  "cd mariadb-5.1.41-rc && make"

```

In this example, `ubuntu-hardy-amd64.qcow2` is a KVM image already installed with compilers and set up for password-less ssh access (using public key authentication). Port 2222 on the host side is forwarded to the ssh service (port 22) on the guest side (so by specifying different `--port` options it is easy to run multiple `runvm` invocations in parallel; in our Buildbot setup we run 3 builds in parallel this way).

 Note the use of the `scp` command, prefixed with an equals sign "`=`" Commands prefixed in this way are run on the host side rather than the guest side; this is a convenient way to copy data in or results out of the virtual machine while the `runvm` session is running.

 Using `runvm` in this way we are able to easily and flexibly manage a large number of virtual machines for automated builds with very little overhead and complexity. In fact we have around 70 distinct virtual machines! The only resource they take is a little disk space (around 37 GByte). And the virtual machines images are also simple to set up, requiring only a minimal install; no need to set up networking bridges or IP addresses, or to install a Buildbot client. All the complex logic runs on the host system, which only needs to be installed once.

 By keeping the virtual images simple, builds and tests run in a minimal environment, which is useful to detect any missing dependencies or other problems that do not show themselves on normal developer machines with a full desktop install (we even do install testing on a separate virtual machine from the one used to build, with compilers etc. not installed on the one used to test installation).

 ### Usage Example Two

 A further refinement of **example one** (above) is to create a new temporary virtual machine image before each step as a copy of a reference image, run the build, and throw away the temporary image after the build. This avoids any possibility of a previous build influencing a following build in any way (and thus also simplifies the build setup, as we can install stuff freely without any need to do cleanup). It also avoids having to fix a broken image, like needing to manually run `fsck` after a crash or similar issue. We use this technique for most of our binary package builds in Buildbot. 

 To use this copy-and-discard technique with runvm, the --base-image option is useful:

 
```
runvm --port=2222 --base-image=ubuntu-hardy-i386.qcow2 tmp.qcow2 \
  "= scp -P 2222 mariadb-5.1.41-rc.tar.gz localhost:" \
  "tar zxf mariadb-5.1.41-rc.tar.gz" \
  "cd mariadb-5.1.41-rc && ./configure" \
  "cd mariadb-5.1.41-rc && make"

```

This will run the build in a temporary copy `tmp.qcow2` of the reference image `ubuntu-hardy-i386.qcow2`, without modifying the reference image in any way. This uses the copy-on-write feature of the qcow2 image format (see `qemu-img(1)`), so it even takes only very little time (fraction of a second) and minimal space (only changed blocks are written to the new image). 

 ### Additional Usage Examples

 The above two examples show basically how the package testing in our Buildbot setup is done. There are some further details of course, like more options for the build commmands and extra care to get logfiles out to debug problems; the full details are available in our [Buildbot configuration file](http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/annotate/head%3A/buildbot/maria-master.cfg). But the basic principle is just a number of `runvm` commands like the examples above. 

 Getting runvm
-------------

 The `runvm` tool is available under GPL on Lauchpad in the project [Tools for MariaDB](https://launchpad.net/mariadb-tools). In the bzr repository it is found as [buildbot/runvm](http://bazaar.launchpad.net/~maria-captains/mariadb-tools/trunk/annotate/head%3A/buildbot/runvm). If someone finds it useful or has suggestions for improvements, please drop us a line on the [maria-developers](https://launchpad.net/~maria-developers) mailing list. 

 runvm --help
------------

 Since it might be useful, here is the output from **runvm --help** (check the latest version of the tool for up-to-date output):

 
```
Usage: ./runvm <options> image.qcow2 [command ...]

Boot the given KVM virtual machine image and wait for it to come up.
Run the list of commands one at a time, aborting on receiving an error.
When all commands are run (or one of them failed), shutdown the virtual
machine and exit.

Commands are by default run inside the virtual machine using ssh(1). By
prefixing a command with an equals sign '=', it will instead be run on the
host system (for example to copy files into or out of the virtual machine
using scp(1)).

Some care is taken to ensure that the virtual machine is shutdown
gracefully and not left running even in case the controlling tty is
closed or the parent process killed. If a previous virtual machine is
already running on a conflicting port, an attempt is made to shut it
down first. For this purpose, a PID file is created in $HOME/.runvm/

Available options:

  -p, --port=N        Forward this port on the host side to the ssh port (port
                      22) on the guest side. Must be different for each runvm
                      instance running in parallel to avoid conflicts. The
                      default is 2222.
                      To copy files in/out of the guest use a command prefixed
                      with '=' calling scp(1) with the -P option using the port
                      specified here, like this:
                          runvm img.qcow2 "=scp -P 2222 file.txt localhost:"
  -u, --user=USER     Name of the account to ssh into in the guest. Defaults to
                      the name of the user invoking runvm on the host.
  -m, --memory=N      Amount of memory (in megabytes) to allocate to the guest.
                      Defaults to 2047.
  --smp=N             Number of CPU cores to allocate to the guest.
                      Defaults to 2.
  -c, --cpu=NAME      Type of CPU to emulate for KVM, see qemu(1) for details.
                      For example:
                          --cpu=qemu64      For 64-bit amd64 emulation
                          --cpu=qemu32      For 32-bit x86 emulation
                          --cpu=qemu32,-nx  32-bit and disable "no-execute"
                      The default is qemu32,-nx
  --netdev=NAME       Network device to emulate. The 'virtio' device has good
                      performance but may not have driver support in all
                      operating systems, if so another can be specified.
                      The default is virtio.
  --kvm=OPT           Pass additional option OPT to kvm. Specify multiple times
                      to pass more than one option. For example
                          runvm --kvm=-cdrom --kvm=mycd.iso img.qcow2 ...
  --initial-sleep=SECS
                      Wait this many seconds before starting to poll the guest
                      ssh port for it to be up. Default 15.
  --startup-timeout=SECS
                      Wait at most this many seconds for the guest OS to respond
                      to ssh. If this time is exceeded assume it has failed to
                      boot correctly. Default 300.
  --shutdown-timeout=SECS
                      Wait at most this many seconds for the guest OS to
                      shutdown gracefully after sending a shutdown command. If
                      this time is exceeded, assume the guest has failed to
                      shutdown gracefully and kill it forcibly. Default 120.
  --kvm-retries=N     If the guest fails to come up, retry the boot this many
                      times before giving up. This helps if the virtual machine
                      sometimes crashes during boot. Default 3.
  -l, --logfile=FILE  File to redirect the output from kvm into. This includes
                      any (error) messages from kvm, and also includes anything
                      the guest writes to the kvm emulated serial port (it can
                      be useful to set the guest to send boot loader and kernel
                      messages to the serial console and log them with this
                      option). Default is to not log this output anywhere.
  -b, --base-image=IMG
                      Instead of booting an existing image, create a new
                      copy-on-write image based on IMG. This uses the -b option
                      of qemu-img(1). IMG is not modified in any way. This way,
                      the booted image can be discarded after use, so that each
                      use of IMG is using the same reference image with no risk
                      of "polution" between different invocations.
                      Note that this DELETES any existing image of the same
                      name as the one specified on the command line to boot! It
                      will be replaced with the image created as a copy of IMG,
                      with any modifications done during the runvm session.

```

 *This page is based on a [blog post](http://kristiannielsen.livejournal.com/11007.html) by Kristian Nielsen, the primary developer of* `runvm`.

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/runvm/>

Package Testing with Buildbot and KVM
=====================================

    Buildbot testing of binary MariaDB packages
-------------------------------------------

 This part of the Buildbot setup uses KVM virtual machines to build packages on a wide range of Linux distributions and test the different packages in various ways.

 The builds run on a single host, which has an Intel Core i7 860 @ 2.80GHz CPU, 8 GByte of RAM, and a 500GByte disk. The build host is installed with Ubuntu 9.04 Server 64-bit. The current box is capable of running up to 3 builds in parallel. The entire set of 19 builds take around 3.5 hours to complete.

 The build host has no virtual machines that are kept running when idle. Instead each build boots up and shuts down virtual machines on the fly as needed, using the [runvm](../runvm/index) tool.

 The details of the setup (installation) of the virtual machines are [here](../buildbot-setup/index).

 ### Builds

 (Please check the Buildbot configuration for details, in case this information becomes out of date).

 At the time of writing, the builds done are these:

 * Source tarball build (on a 32-bit Ubuntu 9.04 VM)
* Binary tarballs, i386 and amd64, on Ubuntu 8.04 VMs.
* Ubuntu, i386 and amd64: 8.04, 8.10, 9.04, 9.10, 10.04 (alpha).
* Debian, i386 and amd64, Debian 4 and Debian 5.
* Centos 5, i386 and amd64.

 The builds use the packaging scripts from [OurDelta](https://launchpad.net/ourdelta).

 In all builds (except for source tarball), the binary package is built, and subsequently attempted installed. The build is done on a virtual machine with compilers and other necessary build tools installed. The virtual machines are cloned from a reference image before each build (using the --base-image option to runvm). This way, the original images are not modified in any way, so there is no risk of "pollution" from previous builds, and no need to carefully clean up after a build or test.

 The source tarball build is done in a virtual machine that is not reset after every build. This is to preserve the bzr shared repository setup inside the virtual machine. This way it is only necessary in each build to download new changes from Launchpad, which saves significant amounts of time (and Launchpad bandwidth). Since this particular build only works inside the source checkout directory, the risk of cross-build pollution is minimal.

 The source tarball build is the only one that is triggered by bzr commits. After it has successfully built a source tarball, the tarball is uploaded to the Buildbot master, and all of the other builders are triggered to start building. Each will download the source tarball from the master and build from that rather than from a bzr checkout (this is the correct way, as we want to ensure that users building from the source tarball themselves get the same results as the packages built by us).

 Since we use the OurDelta scripts, which use a "bakery" for the build scripts similar to a source tarball, there is a bakery tarball similarly generated from bzr and uploaded to the master.

 Because of this triggering, it is not possible to manually force a Buildbot run on "latest bzr version" on the non-tarball builders. Instead to force a build, it is necessary to set the build properties for source tarball and bakery manually to the files one wants to tests. But it is often easier just to pick an existing build (with correct tarball) and use the "resubmit build" feature instead. Another option is to force build on the tarball build only; it will then in turn trigger all of the other builds.

 ### Basic install test

 On all builds (except source tarball), after the build a test is performed where the resulting package is installed in a virtual machine and basic testing is done.

 The install test is done in a separate virtual machine from the one in which it was built, with no build tools and a very minimal install (to check that we have no hidden dependencies). The install test is currently *very* basic, basically just create a table and insert a row (it would be a nice ToDo to extend this testing to a more complete "smoke test").

 Note that for .deb (Debian and Ubuntu), we set up a small fake local apt repository, so that we can properly test that ''apt-get install'' is able to pull in any extra dependencies without anything special needed on the part of the user.

 ### Upgrade tests for .deb packages

 On .deb builders (Debian and Ubuntu), we do three additional upgrade tests. 

 Two of them install the newly built MariaDB packages on top of an already installed MySQL package (the default MySQL package on that particular distro version), as well as on top of an earlier version of the MariaDB packages. For this, separate virtual machine images are used, based on the one used in the install test, but in addition with MySQL/MariaDB pre-installed. 

 The third test is performed on a clean image without any pre-installed MySQL or MariaDB packages. The test installs the latest available release of the same major version from MariaDB public repo, and then runs dist-upgrade using the local repo as a source of the new packages. The main goal of this test is to check that regular system upgrades performed via dist-upgrade work as expected in regard to MariaDB server. 

 In all tests, some very basic test data is also created in the installation, so we can test that replacing the old server installation with our new MariaDB package does not nuke the user's existing data! The test is also useful to check that the upgrade runs correctly with respect to dependencies etc, something that is quite complex to get right with the .deb packaging.

 ### Upgrade tests for .rpm packages

 On .rpm builders (CentOS, Fedora, RHEL, SLES, openSUSE) we have numerous upgrade tests, although only a small portion of them is run for every branch.

 All tests upgrade an already existing installation to the new MariaDB packages. The variables are: - what kind of existing installation is being upgraded: MariaDB server, MariaDB Galera, MySQL, Percona server, or mysql/mariadb installations provided by distributions; - which command is used for upgrade: it can either be performed via upgrade/update (depending on the package manager), or install, or dist-upgrade; - which packages are installed and upgraded: it can be a minimal set, server + client (plus whatever dependencies they bring), or a full set of packages.

 In some cases, the tests can also set additional command-line options or environment variables for the package manager. It is normally done when the default installation does not work, and the package manager suggests using a different set of parameters. 

 Each test uses a clean VM image, installs an initial set of packages, and then uses one of the commands to upgrade the installation. It further checks that the server is upgraded, restarted and is reachable. 

 ### mysql-test-run.pl test

 On the .deb builders (Debian and Ubuntu), we additionally do a full mysql-test-run.pl test run. This is done using the package *mariadb-test*.

 Note that currently, due to [Bug #491349](https://bugs.launchpad.net/bugs/491349), on newer Ubuntus the default apparmor profile prevents running mysql-test-run.pl. Until this is fixed, the tests need to uninstall apparmor before running the test suite.

 See also
--------

 * [Buildbot Setup for Virtual Machines](../buildbot-setup-for-virtual-machines/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/package-testing-with-buildbot-and-kvm/>

Buildbot Setup for Virtual Machines - General Principles
========================================================

     The installations are kept minimal, picking mostly default options. This helps ensure our stuff works on default installs, and also saves effort during the creation of the virtual machines.

 Since most of the logic happens in the Buildbot slave on a host machine, and inside the Buildbot master, there is no need to install Buildbot or other similar complex stuff inside the VMs.

 ssh
---

 The virtual machines are configured with ssh access. An account called 'buildbot' is created, with passwordless login (using ssh public key authentication), and with passwordless sudo access (needed for automated scripting). The public key for user buildbot is installed in every VM, and the private key is added to the account running the Buildbot master on the host machine.

 To generate the ssh keys:

 
```
ssh-keygen -t dsa

```

Leave the passphrase empty. Run this as the user running the Buildbot slave on the KVM host machine. The resulting /.ssh/id\_dsa.pub will be needed below for each virtual machine install.

 Serial port
-----------

 The vms are configured to use the (emulated) serial port as the console. When running KVM on the host, the console then maps to the stdin/stdout. This is useful to get kernel log messages available to easier debug any problems. The bootloader Grub is similarly configured to use the serial port.

 The vms are also set up to give a login prompt on the serial port (running getty). In retrospect this has proven not really needed, as if needing to manually log in and investigate things, it is often as easy to just run KVM in graphics mode. It may be useful in cases where the host machine is remote though (in this case graphics mode does still work but can be a bit slow).

 To configure for serial console, the following two files are referenced below, and should be prepared in advance:

 ### `ttyS0`

 
```
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc2
start on stopped rc3
start on stopped rc4
start on stopped rc5

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6

respawn
exec /sbin/getty 115200 ttyS0

```

### `ttyS0.conf`

 
```
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -L 115200 ttyS0 vt102

```

Unattended MariaDB install on Debian/Ubuntu
-------------------------------------------

 ### my.seed

 The MariaDB (and MySQL) package on Debian and Ubuntu prompts the user about the root password to set. We want to test this important step, but we do not want the prompt of course. To do this we use the following configuration file for defaults for debconf. This file is needed in the steps below under the name "my.seed" (be careful to preserve it exactly as here, including trailing space and tab characters!)

 
```
    mariadb-server-5.1	mysql-server/root_password_again	password	rootpass
    mariadb-server-5.1	mysql-server/root_password	password	rootpass
    mariadb-server-5.1	mysql-server/error_setting_password	error	
    mariadb-server-5.1	mysql-server-5.1/nis_warning	note	
    mariadb-server-5.1	mysql-server-5.1/really_downgrade	boolean	false
    mariadb-server-5.1	mysql-server-5.1/start_on_boot	boolean	true
    mariadb-server-5.1	mysql-server-5.1/postrm_remove_databases	boolean	false
    mariadb-server-5.1	mysql-server/password_mismatch	error	
    mariadb-server-5.1	mysql-server/no_upgrade_when_using_ndb	error	

```

For some background see [here](http://blog.hjksolutions.com/articles/2007/07/27/unattended-package-installation-with-debian-and-ubuntu). The file my.seed can be generated from an existing install using debconf-get-selections.

 ### sources.append

 For Debian/Ubuntu, we add a local repository to the list of apt source to be able to test `apt-get install`. For this, the following file "sources.append" must be prepared:

 
```
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/

```

Emulation options
-----------------

 The default network card emulated by KVM has poor performance. To solve this we instead use the "virtio" network device, using the KVM options "-net nic,model=virtio -net user". Except on Debian 4, which has an old kernel without support for virtio. Background info [here](http://episteme.arstechnica.com/eve/forums/a/tpc/f/96509133/m/303006642931).

 A detail is that some 32-bit vms crashed during boot with default options. This was fixed by using the kvm "-cpu qemu32,-nx" option. Some background information [here](https://bugs.launchpad.net/ubuntu/+source/kvm/+bug/396219).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-general-principles/>

Buildbot Setup for Virtual Machines - Ubuntu
=============================================

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Ubuntu 14.04 "trusty"](../buildbot-setup-for-virtual-machines-ubuntu-1404-trusty/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-trusty-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 13.10 "saucy"](../buildbot-setup-for-virtual-machines-ubuntu-1310-saucy/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-saucy-amd64-seria  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 13.04 "raring"](../buildbot-setup-for-virtual-machines-ubuntu-1304-raring/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-raring-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 12.10 "quantal"](../buildbot-setup-for-virtual-machines-ubuntu-1210-quantal/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-quantal-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 12.04 "precise"](../buildbot-setup-for-virtual-machines-ubuntu-1204-precise/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-precise-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 11.10 "oneiric"](../buildbot-setup-for-virtual-machines-ubuntu-1110-oneiric/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-oneiric-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 11.04 "natty"](../buildbot-setup-for-virtual-machines-ubuntu-1104-natty/index) |  Base install qemu-img create -f qcow2 vm-natty-amd64-serial.qcow2 8G  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 10.10 "maverick"](../buildbot-setup-for-virtual-machines-ubuntu-1010-maverick/index) |  Base install qemu-img create -f qcow2 vm-maverick-amd64-serial.qcow2  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 10.04 (alpha), i386 and amd64](../buildbot-setup-for-virtual-machines-ubuntu-1004-alpha-i386-and-amd64/index) |  Base install qemu-img create -f qcow2 vm-lucid-amd64-serial.qcow2 8G  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 9.04 i386](../buildbot-setup-for-virtual-machines-ubuntu-904-i386/index) |  This vm is used to build source tarball and for Ubuntu 9.04 32-bit .deb. Fi...  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 9.04 amd64](../buildbot-setup-for-virtual-machines-ubuntu-904-amd64/index) |  Base install qemu-img create -f qcow2 vm-jaunty-amd64-serial.qcow2 8  |
|  [Buildbot Setup for Virtual Machines - Ubuntu 8.04, 8.10, and 9.10](../buildbot-setup-for-virtual-machines-ubuntu-804-810-and-910/index) |  These 6 platforms were installed together (i386 and amd64). Base installs U...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu/>

Buildbot Setup for Virtual Machines - Ubuntu 14.04 "trusty"
===========================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-trusty-amd64-serial.qcow2 20G
qemu-img create -f qcow2 /kvm/vms/vm-trusty-i386-serial.qcow2 20G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-trusty-amd64-serial.qcow2 \
  -cdrom /kvm/iso/ubuntu/trusty-server-amd64.iso \
  -boot d -smp 2 -cpu qemu64 \
  -net nic,model=virtio \
  -net user,hostfwd=tcp:127.0.0.1:2293-:22

kvm -m 2048 -hda /kvm/vms/vm-trusty-i386-serial.qcow2 \
  -cdrom /kvm/iso/ubuntu/trusty-server-i386.iso \
  -boot d -smp 2 -cpu qemu64 \
  -net nic,model=virtio \
  -net user,hostfwd=tcp:127.0.0.1:2294-:22

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote_host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Ubuntu has just resized the vnc screen. Simply reconnect.

 During the install, pick default options for the most part, with the following notes:

 * Set the hostname to `ubuntu-trusty-amd64` or `ubuntu-trusty-i386` (depending on which architecture we're installing)
* **do not** encrypt the home directory
* When prompted if the timezone is correct, answer "No" and when the list comes up, scroll to the bottom and choose "UTC"
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
* No automatic updates
* Choose software to install: OpenSSH server

 Reboot when prompted. It will fail, so just kill the kvm process with `^Ctrl+C`.

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
qemu-system-x86_64 -m 2048 -hda /kvm/vms/vm-trusty-amd64-serial.qcow2 \
  -boot c -smp 2 -cpu qemu64 \
  -net nic,model=virtio \
  -net user,hostfwd=tcp:127.0.0.1:2293-:22 \
  -nographic

qemu-system-x86_64 -m 2048 -hda /kvm/vms/vm-trusty-i386-serial.qcow2 \
  -boot c -smp 2 -cpu qemu64 \
  -net nic,model=virtio \
  -net user,hostfwd=tcp:127.0.0.1:2294-:22 \
  -nographic

```

* set `vim` as the preferred editor

 
```
ssh -t -p 2293 localhost sudo update-alternatives --config editor
ssh -t -p 2294 localhost sudo update-alternatives --config editor

```

* Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

* edit /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
GRUB_HIDDEN_TIMEOUT_QUIET=false
GRUB_TIMEOUT=0
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub
# exit back to the host server

```

* create the `.ssh` directory and the `sudo` group

 
```
ssh -t -p 2293 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 2294 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

```

* copy the `authorized_keys` file up to the VMs

 
```
scp -P 2293 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2294 /kvm/vms/authorized_keys localhost:.ssh/

```

* create the buildbot user on the amd64 VM

 
```
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2293 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

* create the buildbot user on the x86 VM

 
```
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2294 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

* copy the ttyS0 file to the VMs

 
```
scp -i -P 2293 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -i -P 2294 /kvm/vms/ttyS0.conf buildbot@localhost:

```

* Apply all OS updates

 
```
ssh -t -i -p 2293 buildbot@localhost \
  'sudo apt-get update && sudo apt-get -y dist-upgrade;'

ssh -t -i -p 2294 buildbot@localhost \
  'sudo apt-get update && sudo apt-get -y dist-upgrade;'

```

* copy the ttyS0 file to its proper location and shut down the VM

 
```
ssh -t -i -p 2293 buildbot@localhost \
  'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

ssh -t -i -p 2294 buildbot@localhost \
  'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-trusty-amd64-serial.qcow2 2293 qemu64' '/kvm/vms/vm-trusty-i386-serial.qcow2 2294 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev bzr scons check libboost-all-dev openssl epm libjudy-dev libjemalloc-dev" \
    "bzr co --lightweight lp:mariadb-native-client" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
    "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" ; \
done


```

VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-trusty-amd64-serial.qcow2 2293 qemu64' '/kvm/vms/vm-trusty-i386-serial.qcow2 2294 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils unixodbc libxml2 libjudydebian1 libjemalloc1" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-trusty-amd64-serial.qcow2 2293 qemu64' '/kvm/vms/vm-trusty-i386-serial.qcow2 2294 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.5 libjemalloc1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-trusty-amd64-serial.qcow2 2293 qemu64' '/kvm/vms/vm-trusty-i386-serial.qcow2 2294 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "= scp -P $2 /kvm/vms/mariadb-trusty.list buildbot@localhost:/tmp/tmp.list" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    'sudo mv -vi /tmp/tmp.list /etc/apt/sources.list.d/' \
    'sudo apt-key adv --recv-keys --keyserver pgp.mit.edu 0xcbcb082a1bb943db' \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server libjemalloc1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/apt/sources.list.d/tmp.list' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get update' \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each kvm host server (terrier, terrier2, i7, etc...) to add the VMs to known\_hosts.

 
```
# trusty-amd64
cp -avi /kvm/vms/vm-trusty-amd64-install.qcow2 /kvm/vms/vm-trusty-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-trusty-amd64-test.qcow2 -redir tcp:2293::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2293 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-trusty-amd64-test.qcow2

# trusty-i386
cp -avi /kvm/vms/vm-trusty-i386-install.qcow2 /kvm/vms/vm-trusty-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-trusty-i386-test.qcow2 -redir tcp:2294::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2294 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-trusty-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1404-trusty/>

Buildbot Setup for Virtual Machines - Ubuntu 13.10 "saucy"
==========================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-saucy-amd64-serial.qcow2 20G
qemu-img create -f qcow2 /kvm/vms/vm-saucy-i386-serial.qcow2 20G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-saucy-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.10-server-amd64.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2287-:22
kvm -m 2048 -hda /kvm/vms/vm-saucy-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.10-server-i386.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2288-:22

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote_host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Ubuntu has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the hostname to ubuntu-saucy-amd64 or ubuntu-saucy-i386
* **do not** encrypt the home directory
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
* No automatic updates
* Choose software to install: OpenSSH server

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 2048 -hda /kvm/vms/vm-saucy-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.10-server-amd64.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2287-:22 -nographic
kvm -m 2048 -hda /kvm/vms/vm-saucy-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.10-server-i386.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2288-:22 -nographic

ssh -p 2287 localhost
sudo update-alternatives --config editor
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 2288 localhost
sudo update-alternatives --config editor
# edit /boot/grub/menu.lst and visudo, see below


ssh -t -p 2287 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 2288 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

scp -P 2287 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2288 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 2287 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2288 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 2287 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 2288 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 2287 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'
ssh -p 2288 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'

ssh -p 2287 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 2288 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
GRUB_HIDDEN_TIMEOUT_QUIET=false
GRUB_TIMEOUT=0
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub
# exit back to the host server

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-saucy-amd64-serial.qcow2 2287 qemu64' '/kvm/vms/vm-saucy-i386-serial.qcow2 2288 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev bzr scons check libboost-all-dev openssl epm" \
    "bzr co --lightweight lp:mariadb-native-client" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
    "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" ; \
done


```

VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-saucy-amd64-serial.qcow2 2287 qemu64' '/kvm/vms/vm-saucy-i386-serial.qcow2 2288 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils unixodbc libxml2" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-saucy-amd64-serial.qcow2 2287 qemu64' '/kvm/vms/vm-saucy-i386-serial.qcow2 2288 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-saucy-amd64-serial.qcow2 2287 qemu64' '/kvm/vms/vm-saucy-i386-serial.qcow2 2288 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "= scp -P $2 /kvm/vms/mariadb-saucy.list buildbot@localhost:/tmp/tmp.list" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    'sudo mv -vi /tmp/tmp.list /etc/apt/sources.list.d/' \
    'sudo apt-key adv --recv-keys --keyserver pgp.mit.edu 0xcbcb082a1bb943db' \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/apt/sources.list.d/tmp.list' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get update' \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each kvm host server (terrier, terrier2, i7, etc...) to add the VMs to known\_hosts.

 
```
# saucy-amd64
cp -avi /kvm/vms/vm-saucy-amd64-install.qcow2 /kvm/vms/vm-saucy-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-saucy-amd64-test.qcow2 -redir tcp:2287::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2287 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-saucy-amd64-test.qcow2

# saucy-i386
cp -avi /kvm/vms/vm-saucy-i386-install.qcow2 /kvm/vms/vm-saucy-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-saucy-i386-test.qcow2 -redir tcp:2288::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2288 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-saucy-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1310-saucy/>

Buildbot Setup for Virtual Machines - Ubuntu 13.04 "raring"
============================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-raring-amd64-serial.qcow2 15G
qemu-img create -f qcow2 /kvm/vms/vm-raring-i386-serial.qcow2 15G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-raring-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.04-server-amd64.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2279-:22
kvm -m 2048 -hda /kvm/vms/vm-raring-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.04-server-i386.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2280-:22

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Ubuntu has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the hostname to ubuntu-raring-amd64 or ubuntu-raring-i386
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
* No automatic updates
* Choose software to install: OpenSSH server

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 2048 -hda /kvm/vms/vm-raring-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.04-server-amd64.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2279-:22 -nographic
kvm -m 2048 -hda /kvm/vms/vm-raring-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-13.04-server-i386.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2280-:22 -nographic

ssh -p 2279 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 2280 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2279 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 2280 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

scp -P 2279 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2280 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 2279 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2280 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 2279 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 2280 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 2279 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'
ssh -p 2280 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'

ssh -p 2279 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 2280 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
GRUB_HIDDEN_TIMEOUT_QUIET=false
GRUB_TIMEOUT=0
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub
# exit back to the host server

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-raring-amd64-serial.qcow2 2279 qemu64' '/kvm/vms/vm-raring-i386-serial.qcow2 2280 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev bzr" \
    "bzr co --lightweight lp:mariadb-native-client" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
    "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/boost_1_49_0.tar.gz;cd /usr/local/include/;sudo ln -vs ../src/boost_1_49_0/boost ." ; \
done


```

VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-raring-amd64-serial.qcow2 2279 qemu64' '/kvm/vms/vm-raring-i386-serial.qcow2 2280 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-raring-amd64-serial.qcow2 2279 qemu64' '/kvm/vms/vm-raring-i386-serial.qcow2 2280 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
 *The steps below are based on the Natty steps on [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index).*

 

```
for i in '/kvm/vms/vm-raring-amd64-serial.qcow2 2279 qemu64' '/kvm/vms/vm-raring-i386-serial.qcow2 2280 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "= scp -P $2 /kvm/vms/mariadb-raring.list buildbot@localhost:/tmp/tmp.list" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    'sudo mv -vi /tmp/tmp.list /etc/apt/sources.list.d/' \
    'sudo apt-key adv --recv-keys --keyserver pgp.mit.edu 0xcbcb082a1bb943db' \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-server-5.5 mariadb-client mariadb-client-5.5 mariadb-test libmariadbclient-dev mysql-common=5.5.30-mariadb1~quantal libmysqlclient18=5.5.30-mariadb1~quantal' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/apt/sources.list.d/tmp.list' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get update' \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each kvm host server (terrier, terrier2, i7, etc...) to add the VMs to known\_hosts.

 
```
# raring-amd64
cp -avi /kvm/vms/vm-raring-amd64-install.qcow2 /kvm/vms/vm-raring-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-raring-amd64-test.qcow2 -redir tcp:2279::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2279 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-raring-amd64-test.qcow2

# raring-i386
cp -avi /kvm/vms/vm-raring-i386-install.qcow2 /kvm/vms/vm-raring-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-raring-i386-test.qcow2 -redir tcp:2280::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2280 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-raring-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1304-raring/>

Buildbot Setup for Virtual Machines - Ubuntu 12.10 "quantal"
============================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-quantal-amd64-serial.qcow2 10G
qemu-img create -f qcow2 /kvm/vms/vm-quantal-i386-serial.qcow2 10G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-quantal-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.10-server-amd64.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2275-:22
kvm -m 2048 -hda /kvm/vms/vm-quantal-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.10-server-i386.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2276-:22

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Ubuntu has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the hostname to ubuntu-quantal-amd64 or ubuntu-quantal-i386
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
* No automatic updates
* Choose software to install: OpenSSH server

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 2048 -hda /kvm/vms/vm-quantal-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.10-server-amd64.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2275-:22 -nographic
kvm -m 2048 -hda /kvm/vms/vm-quantal-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.10-server-i386.iso -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2276-:22 -nographic

ssh -p 2275 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 2276 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2275 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 2276 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

scp -P 2275 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2276 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 2275 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2276 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir -v ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 2275 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 2276 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 2275 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'
ssh -p 2276 buildbot@localhost 'sudo apt-get update && sudo apt-get -y dist-upgrade;'

ssh -p 2275 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 2276 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub
# exit back to the host server

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-quantal-amd64-serial.qcow2 2275 qemu64' '/kvm/vms/vm-quantal-i386-serial.qcow2 2276 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 defoma dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern psfontmgr texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
    "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/boost_1_49_0.tar.gz;cd /usr/local/include/;sudo ln -vs ../src/boost_1_49_0/boost ." ; \
done


```

VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-quantal-amd64-serial.qcow2 2275 qemu64' '/kvm/vms/vm-quantal-i386-serial.qcow2 2276 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-quantal-amd64-serial.qcow2 2275 qemu64' '/kvm/vms/vm-quantal-i386-serial.qcow2 2276 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
 *The steps below are based on the Natty steps on [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index).*

 

```
for i in '/kvm/vms/vm-quantal-amd64-serial.qcow2 2275 qemu64' '/kvm/vms/vm-quantal-i386-serial.qcow2 2276 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "= scp -P $2 /kvm/vms/my55.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "= scp -P $2 /kvm/vms/mariadb-quantal.list buildbot@localhost:/tmp/tmp.list" \
    "sudo debconf-set-selections /tmp/my55.seed" \
    'sudo mv -vi /tmp/tmp.list /etc/apt/sources.list.d/' \
    'sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db' \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-server-5.5 mariadb-client mariadb-client-5.5 mariadb-test libmariadbclient-dev' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/apt/sources.list.d/tmp.list' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get update' \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each kvm host server (terrier, terrier2, i7, etc...) to add the VMs to known\_hosts.

 
```
# quantal-amd64
cp -avi /kvm/vms/vm-quantal-amd64-install.qcow2 /kvm/vms/vm-quantal-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-quantal-amd64-test.qcow2 -redir tcp:2275::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2275 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-quantal-amd64-test.qcow2

# quantal-i386
cp -avi /kvm/vms/vm-quantal-i386-install.qcow2 /kvm/vms/vm-quantal-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-quantal-i386-test.qcow2 -redir tcp:2276::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2276 buildbot@localhost sudo shutdown -h now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-quantal-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1210-quantal/>

Buildbot Setup for Virtual Machines - Ubuntu 12.04 "precise"
============================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-precise-amd64-serial.qcow2 8G
qemu-img create -f qcow2 /kvm/vms/vm-precise-i386-serial.qcow2 8G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 1024 -hda /kvm/vms/vm-precise-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.04-server-amd64.iso -redir tcp:22255::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-precise-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.04-server-i386.iso -redir tcp:22256::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Ubuntu has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the hostname to ubuntu-precise
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
* No automatic updates
* Choose software to install: OpenSSH server

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 1024 -hda /kvm/vms/vm-precise-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.04-server-amd64.iso -redir tcp:22255::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-precise-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu/ubuntu-12.04-server-i386.iso -redir tcp:22256::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

ssh -p 22255 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 22256 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 22255 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 22256 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

scp -P 22255 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 22256 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 22255 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 22256 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 22255 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 22256 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 22255 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 22256 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-precise-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-precise-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 defoma dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern psfontmgr texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils" ; \
done


```

Also:

 * [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index)

 VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-precise-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-precise-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils" \
    "= scp -P $2 /kvm/vms/my.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-precise-amd64-install.qcow2 22255 qemu64' '/kvm/vms/vm-precise-i386-install.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1 mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
*The steps below are based on the Natty steps on [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index).*

 
64-bit Ubuntu precise:

 
```
qemu-img create -b vm-precise-amd64-install.qcow2 -f qcow2 vm-precise-amd64-upgrade2.qcow2
kvm -m 512 -hda vm-precise-amd64-upgrade2.qcow2 -redir 'tcp:22200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 22200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu oneiric main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu oneiric main

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1BB943DB
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
sudo apt-get -f install
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
sudo shutdown -h now

```

32-bit Ubuntu precise:

 
```
qemu-img create -b vm-precise-i386-install.qcow2 -f qcow2 vm-precise-i386-upgrade2.qcow2
kvm -m 512 -hda vm-precise-i386-upgrade2.qcow2 -redir 'tcp:22200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 22200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu oneiric main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu oneiric main

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1BB943DB
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
sudo apt-get -f install
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
sudo shutdown -h now

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1204-precise/>

Buildbot Setup for Virtual Machines - Ubuntu 11.10 "oneiric"
============================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-oneiric-amd64-serial.qcow2 8G
qemu-img create -f qcow2 /kvm/vms/vm-oneiric-i386-serial.qcow2 8G

# Start each VM booting from the server install iso one at a time and perform
# the following install steps:
kvm -m 1024 -hda /kvm/vms/vm-oneiric-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.10-server-amd64.iso -redir tcp:2255::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-oneiric-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.10-server-i386.iso -redir tcp:2256::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

# Once running you can connect to the VNC server from your local host with:
#
#    vncviewer -via ${remote-host} localhost
#
# (replace ${remote-host} with the host the vm is running on)

# Install, picking default options mostly, with the following notes:
# * Set the hostname to ubuntu-oneiric
# * When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
# * No automatic updates
# * Choose software to install: OpenSSH server


# Now that the VM is installed, it's time to configure it.
# If you have the memory you can do the following simultaneously:
kvm -m 1024 -hda /kvm/vms/vm-oneiric-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.10-server-amd64.iso -redir tcp:2255::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-oneiric-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.10-server-i386.iso -redir tcp:2256::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

ssh -p 2255 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 2256 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2255 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"
ssh -t -p 2256 localhost "mkdir -v .ssh; sudo addgroup $USER sudo"

scp -P 2255 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2256 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 2255 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2256 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 2255 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 2256 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 2255 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 2256 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-oneiric-amd64-serial.qcow2 2255 qemu64' '/kvm/vms/vm-oneiric-i386-serial.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.1" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline6-dev" ; \
done


```

Install cmake (required for [MariaDB 5.5](../what-is-mariadb-55/index)) with:

 
```

kvm -m 1024 -hda ${vm} -redir tcp:22565::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

ssh -o IdentityFile=.ssh/buildbot.id_dsa -p 22565 buildbot@localhost

wget http://www.cmake.org/files/v2.8/cmake-2.8.6.tar.gz
tar -zxvf cmake-2.8.6.tar.gz
cd cmake-2.8.6;./configure
make
sudo make install

sudo /sbin/shutdown -h now

```

Also:

 * [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index)

 VMs for install testing.
------------------------

 See above for how to obtain my.seed and sources.append.

 
```
for i in '/kvm/vms/vm-oneiric-amd64-serial.qcow2 2255 qemu64' '/kvm/vms/vm-oneiric-i386-serial.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y debconf-utils" \
    "= scp -P $2 /kvm/vms/my.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-oneiric-amd64-install.qcow2 2255 qemu64' '/kvm/vms/vm-oneiric-i386-install.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
*The steps below are based on the Natty steps on [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index).*

 
64-bit Ubuntu oneiric:

 
```
qemu-img create -b vm-oneiric-amd64-install.qcow2 -f qcow2 vm-oneiric-amd64-upgrade2.qcow2
kvm -m 512 -hda vm-oneiric-amd64-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.2/ubuntu natty main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.2/ubuntu natty main

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1BB943DB
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
sudo rm /etc/apparmor.d/usr.sbin.mysqld
sudo /etc/init.d/apparmor restart
sudo apt-get -f install
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
sudo shutdown -h now

```

32-bit Ubuntu oneiric:

 
```
qemu-img create -b vm-oneiric-i386-install.qcow2 -f qcow2 vm-oneiric-i386-upgrade2.qcow2
kvm -m 512 -hda vm-oneiric-i386-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.2/ubuntu natty main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.2/ubuntu natty main

sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1BB943DB
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
sudo rm /etc/apparmor.d/usr.sbin.mysqld
sudo /etc/init.d/apparmor restart
sudo apt-get -f install
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y
sudo shutdown -h now

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1110-oneiric/>

Buildbot Setup for Virtual Machines - Ubuntu 11.04 "natty"
==========================================================

    Base install
------------

 
```
qemu-img create -f qcow2 vm-natty-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-natty-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.04-server-amd64.iso -redir tcp:2255::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

# Install, picking default options mostly, only adding openssh server.

kvm -m 1024 -hda vm-natty-amd64-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.04-server-amd64.iso -redir tcp:2255::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2255 localhost

# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2255 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2255 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2255 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2255 ttyS0.conf buildbot@localhost:
ssh -p 2255 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```


```
qemu-img create -f qcow2 vm-natty-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-natty-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.04-server-i386.iso -redir tcp:2256::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

# Install, picking default options mostly, only adding openssh server.

kvm -m 1024 -hda vm-natty-i386-serial.qcow2 -cdrom /kvm/iso/ubuntu-11.04-server-i386.iso -redir tcp:2256::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2256 localhost

# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2256 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2256 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2256 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2256 ttyS0.conf buildbot@localhost:
ssh -p 2256 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in 'vm-natty-amd64-serial.qcow2 2255 qemu64' 'vm-natty-i386-serial.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.1" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline6-dev" ; \
done

```

VMs for install testing.
------------------------

 See above for how to obtain my.seed and sources.append.

 
```
for i in 'vm-natty-amd64-serial.qcow2 2255 qemu64' 'vm-natty-i386-serial.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y debconf-utils" \
    "= scp -P $2 my.seed sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for upgrade testing
-----------------------

 
```
for i in 'vm-natty-amd64-install.qcow2 2255 qemu64' 'vm-natty-i386-install.qcow2 2256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1104-natty/>

Buildbot Setup for Virtual Machines - Ubuntu 10.10 "maverick"
=============================================================

    Base install
------------

 
```
qemu-img create -f qcow2 vm-maverick-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-maverick-amd64-serial.qcow2 -cdrom /kvm/ubuntu-10.10-server-amd64.iso -redir tcp:2246::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-maverick-amd64-serial.qcow2 -cdrom /kvm/ubuntu-10.10-server-amd64.iso -redir tcp:2246::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2246 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2246 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2246 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2246 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2246 ttyS0.conf buildbot@localhost:
ssh -p 2246 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```


```
qemu-img create -f qcow2 vm-maverick-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-maverick-i386-serial.qcow2 -cdrom /kvm/ubuntu-10.10-server-i386.iso -redir tcp:2247::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-maverick-i386-serial.qcow2 -cdrom /kvm/ubuntu-10.10-server-i386.iso -redir tcp:2247::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
ssh -p 2247 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2247 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2247 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2247 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2247 ttyS0.conf buildbot@localhost:
ssh -p 2247 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# Add line at end: `%sudo ALL=NOPASSWD: ALL'

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in 'vm-maverick-amd64-serial.qcow2 2246 qemu64' 'vm-maverick-i386-serial.qcow2 2247 qemu32,-nx' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.1" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline6-dev" ; \
done

```

VMs for install testing.
------------------------

 See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' and '`sources.append`' files.

 
```
cat >sources.append <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

```


```
for i in 'vm-maverick-amd64-serial.qcow2 2246 qemu64' 'vm-maverick-i386-serial.qcow2 2247 qemu32,-nx' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y debconf-utils" \
    "= scp -P $2 my.seed sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for upgrade testing
-----------------------

 
```
for i in 'vm-maverick-amd64-install.qcow2 2246 qemu64' 'vm-maverick-i386-install.qcow2 2247 qemu32,-nx' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1010-maverick/>

Buildbot Setup for Virtual Machines - Ubuntu 10.04 (alpha), i386 and amd64
==========================================================================

    Base install
------------

 
```
qemu-img create -f qcow2 vm-lucid-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-lucid-amd64-serial.qcow2 -cdrom /kvm/lucid-server-amd64.iso -redir tcp:2238::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-lucid-amd64-serial.qcow2 -cdrom /kvm/lucid-server-amd64.iso -redir tcp:2238::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2238 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2238 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2238 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2238 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2238 ttyS0.conf buildbot@localhost:
ssh -p 2238 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```


```
qemu-img create -f qcow2 vm-lucid-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-lucid-i386-serial.qcow2 -cdrom /kvm/lucid-server-i386.iso -redir tcp:2239::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-lucid-i386-serial.qcow2 -cdrom /kvm/lucid-server-i386.iso -redir tcp:2239::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
ssh -p 2239 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2239 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2239 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2239 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2239 ttyS0.conf buildbot@localhost:
ssh -p 2239 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
sudo VISUAL=vi visudo
# uncomment `%sudo ALL=NOPASSWD: ALL' line in `visudo`, and move to end.

```

Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in 'vm-lucid-amd64-serial.qcow2 2238 qemu64' 'vm-lucid-i386-serial.qcow2 2239 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.1" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline5-dev" ; \
done

```

VMs for install testing.
------------------------

 See above for how to obtain my.seed and sources.append.

 
```
cat >sources.append <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

for i in 'vm-lucid-amd64-serial.qcow2 2238 qemu64' 'vm-lucid-i386-serial.qcow2 2239 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y debconf-utils" \
    "= scp -P $2 my.seed sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for upgrade testing
-----------------------

 
```
for i in 'vm-lucid-amd64-install.qcow2 2238 qemu64' 'vm-lucid-i386-install.qcow2 2239 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-1004-alpha-i386-and-amd64/>

Buildbot Setup for Virtual Machines - Ubuntu 9.04 i386
======================================================

    This vm is used to build source tarball and for Ubuntu 9.04 32-bit .deb.

 First create and install image:

 
```
qemu-img create -f qcow2 vm-jaunty-i386-base.qcow2 8G
kvm -m 2047 -hda vm-jaunty-i386-base.qcow2 -cdrom ubuntu-9.04-server-i386.iso -redir tcp:2222::22 -boot d -cpu qemu32,-nx
# Install

```

Create a vm, based on the first one, which is configured for serial port.

 
```
qemu-img create -b vm-jaunty-i386-base.qcow2 -f qcow2 vm-jaunty-i386-serial.qcow2
kvm -m 2047 -hda vm-jaunty-i386-base.qcow2 -redir tcp:2222::22 -boot c -cpu qemu32,-nx

```

To configure kernel and grub for serial console, add the following to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Create /etc/event.d/ttyS0:

 
```
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc2
start on stopped rc3
start on stopped rc4
start on stopped rc5

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6

respawn
exec /sbin/getty 115200 ttyS0

```

Add an account:

 
```
sudo adduser --disabled-password buildbot

```

Copy public ssh key into /.ssh/authorized\_keys

 Enable passwordless sudo:

 
```
sudo adduser buildbot sudo
# uncomment `%sudo ALL=NOPASSWD: ALL' line in `visudo`, and move to end.

```

Create a new vm for building source tarballs:

 
```
qemu-img create -b vm-jaunty-i386-serial.qcow2 -f qcow2 vm-jaunty-i386-deb-tarbake.qcow2

```

Install compilers:

 
```
sudo apt-get build-dep mysql-5.1-server
sudo apt-get install devscripts hardening-wrapper bzr

```

Copy in an existing bzr shared repository to buildbot/.bzr (or run bzr init-repo and bzr branch --no-tree lp:maria).

 Create a new vm for building .debs:

 
```
qemu-img create -b vm-jaunty-i386-serial.qcow2 -f qcow2 vm-jaunty-i386-deb-build.qcow2

```

Install compilers:

 
```
sudo apt-get build-dep mysql-5.1-server
sudo apt-get install devscripts hardening-wrapper

```

Create a new VM for testing .deb installs:

 
```
qemu-img create -b vm-jaunty-i386-serial.qcow2 -f qcow2 vm-jaunty-i386-deb-install.qcow2

```

Install tools and local apt repository.

 
```
sudo apt-get install debconf-utils
cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

```

Setup default package config for debconf to enable unattended install. Copy in my.seed (see above) to vm.

 
```
sudo debconf-set-selections /tmp/my.seed

```

Create a new VM for testing upgrades:

 
```
qemu-img create -b vm-jaunty-i386-deb-install.qcow2 -f qcow2 vm-jaunty-i386-deb-upgrade.qcow2

```

Prepare initial MySQL install with some test data.

 
```
sudo apt-get install mysql-server-5.1
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-904-i386/>

Buildbot Setup for Virtual Machines - Ubuntu 9.04 amd64
=======================================================

    Base install
------------

 
```
qemu-img create -f qcow2 vm-jaunty-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-jaunty-amd64-serial.qcow2 -cdrom /kvm/ubuntu-9.04-server-amd64.iso -redir tcp:2227::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Serial port and passwordless login/sudo
---------------------------------------

 
```
kvm -m 1024 -hda vm-jaunty-amd64-serial.qcow2 -cdrom /kvm/ubuntu-9.04-server-amd64.iso -redir tcp:2227::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

sudo apt-get install emacs22-nox

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Create /etc/event.d/ttyS0:

 
```
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc2
start on stopped rc3
start on stopped rc4
start on stopped rc5

stop on runlevel 0
stop on runlevel 1
stop on runlevel 6

respawn
exec /sbin/getty 115200 ttyS0

```

Add account and allow passwordless sudo:

 
```
sudo adduser --disabled-password buildbot
sudo adduser buildbot sudo
sudo EDITOR=emacs visudo
# uncomment `%sudo ALL=NOPASSWD: ALL' line in `visudo`, and move to end.

sudo su -s /bin/bash - buildbot
mkdir .ssh
cat >.ssh/authorized_keys
# Paste public key for buildbot user on host system.
chmod -R go-rwx .ssh
# Do manual login from host to guest once, to make sure .ssh/known_hosts is updated.

```

VM for .deb building
--------------------

 
```
qemu-img create -b vm-jaunty-amd64-serial.qcow2 -f qcow2 vm-jaunty-amd64-build.qcow2
kvm -m 1024 -hda vm-jaunty-amd64-build.qcow2 -cdrom /kvm/ubuntu-9.04-server-amd64.iso -redir tcp:2227::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get build-dep mysql-server-5.1

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-jaunty-amd64-serial.qcow2 -f qcow2 vm-jaunty-amd64-install.qcow2
kvm -m 1024 -hda vm-jaunty-amd64-install.qcow2 -cdrom /kvm/ubuntu-9.04-server-amd64.iso -redir tcp:2227::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo adduser --system --group mysql

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-904-amd64/>

Buildbot Setup for Virtual Machines - Ubuntu 8.04, 8.10, and 9.10
=================================================================

    These 6 platforms were installed together (i386 and amd64).

 Base installs
-------------

 Ubuntu 8.04 "Hardy" amd64:

 
```
qemu-img create -f qcow2 vm-hardy-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-hardy-amd64-serial.qcow2 -cdrom /kvm/ubuntu-8.04.3-server-amd64.iso -redir tcp:2228::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-hardy-amd64-serial.qcow2 -cdrom /kvm/ubuntu-8.04.3-server-amd64.iso -redir tcp:2228::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2228 localhost
# edit /boot/grub/menu.lst and visudo, see below
sudo /sbin/shutdown -h now
kvm -m 1024 -hda vm-hardy-amd64-serial.qcow2 -cdrom /kvm/ubuntu-8.04.3-server-amd64.iso -redir tcp:2228::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -t -p 2228 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2228 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2228 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2228 ttyS0 buildbot@localhost:
ssh -p 2228 buildbot@localhost 'sudo cp ttyS0 /etc/event.d; rm ttyS0; sudo shutdown -h now'

```

Ubuntu 8.04 "Hardy" i386:

 
```
qemu-img create -f qcow2 vm-hardy-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-hardy-i386-serial.qcow2 -cdrom /kvm/ubuntu-8.04.3-server-i386.iso -redir tcp:2229::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-hardy-i386-serial.qcow2 -cdrom /kvm/ubuntu-8.04.3-server-i386.iso -redir tcp:2229::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
ssh -p 2229 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2229 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2229 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2229 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2229 ttyS0 buildbot@localhost:
ssh -p 2229 buildbot@localhost 'sudo cp ttyS0 /etc/event.d; rm ttyS0; sudo shutdown -h now'

```

Ubuntu 8.10 "Intrepid" amd64:

 
```
qemu-img create -f qcow2 vm-intrepid-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-intrepid-amd64-serial.qcow2 -cdrom /kvm/ubuntu-8.10-server-amd64.iso -redir tcp:2230::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-intrepid-amd64-serial.qcow2 -cdrom /kvm/ubuntu-8.10-server-amd64.iso -redir tcp:2230::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2230 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2230 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2230 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2230 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2230 ttyS0 buildbot@localhost:
ssh -p 2230 buildbot@localhost 'sudo cp ttyS0 /etc/event.d; rm ttyS0; sudo shutdown -h now'

```

Ubuntu 8.10 "Intrepid" i386:

 
```
qemu-img create -f qcow2 vm-intrepid-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-intrepid-i386-serial.qcow2 -cdrom /kvm/ubuntu-8.10-server-i386.iso -redir tcp:2231::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-intrepid-i386-serial.qcow2 -cdrom /kvm/ubuntu-8.10-server-i386.iso -redir tcp:2231::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
ssh -p 2231 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2231 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2231 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2231 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2231 ttyS0 buildbot@localhost:
ssh -p 2231 buildbot@localhost 'sudo cp ttyS0 /etc/event.d; rm ttyS0; sudo shutdown -h now'

```

Ubuntu 9.10 "Karmic" amd64:

 
```
qemu-img create -f qcow2 vm-karmic-amd64-serial.qcow2 8G
kvm -m 1024 -hda vm-karmic-amd64-serial.qcow2 -cdrom /kvm/ubuntu-9.10-server-amd64.iso -redir tcp:2232::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-karmic-amd64-serial.qcow2 -cdrom /kvm/ubuntu-9.10-server-amd64.iso -redir tcp:2232::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2232 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2232 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2232 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2232 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2232 ttyS0.conf buildbot@localhost:
ssh -p 2232 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```

Ubuntu 9.10 "Karmic" i386:

 
```
qemu-img create -f qcow2 vm-karmic-i386-serial.qcow2 8G
kvm -m 1024 -hda vm-karmic-i386-serial.qcow2 -cdrom /kvm/ubuntu-9.10-server-i386.iso -redir tcp:2233::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
# Install, picking default options mostly, only adding openssh server.
kvm -m 1024 -hda vm-karmic-i386-serial.qcow2 -cdrom /kvm/ubuntu-9.10-server-i386.iso -redir tcp:2233::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
ssh -p 2233 localhost
# edit /boot/grub/menu.lst and visudo, see below
ssh -t -p 2233 localhost "mkdir .ssh; sudo addgroup $USER sudo"
scp -P 2233 authorized_keys localhost:.ssh/
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2233 localhost 'chmod -R go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -R buildbot:buildbot ~buildbot/.ssh; sudo chmod -R go-rwx ~buildbot/.ssh'
scp -P 2233 ttyS0.conf buildbot@localhost:
ssh -p 2233 buildbot@localhost 'sudo cp ttyS0.conf /etc/init/; rm ttyS0.conf; sudo shutdown -h now'

```

For visudo to enable passwordless sudo:

 
```
sudo VISUAL=vi visudo

# uncomment `%sudo ALL=NOPASSWD: ALL' line in `visudo`, and move to end.

```

For 8.04/8.10/9.04, /boot/grub/menu.lst is edited as follows:

 
```
sudo vi /boot/grub/menu.lst

# Add this:
  serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
  terminal --timeout=3 serial console

# Also add in menu.lst to kernel line (after removing `quiet splash'):
  console=tty0 console=ttyS0,115200n8

```

For 9.10, /boot/grub/menu.lst is edited as follows:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

VMs for building .debs
----------------------

 
```
for i in 'vm-hardy-amd64-serial.qcow2 2228 qemu64' 'vm-hardy-i386-serial.qcow2 2229 qemu32,-nx' 'vm-intrepid-amd64-serial.qcow2 2230 qemu64' 'vm-intrepid-i386-serial.qcow2 2231 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get build-dep -y mysql-server-5.0" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline5-dev" ; \
done

for i in 'vm-karmic-amd64-serial.qcow2 2232 qemu64' 'vm-karmic-i386-serial.qcow2 2233 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.1" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline5-dev" ; \
done

```

VMs for install testing
-----------------------

 See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' and '`sources.append`' files.

 
```
for i in 'vm-hardy-amd64-serial.qcow2 2228 qemu64' 'vm-hardy-i386-serial.qcow2 2229 qemu32,-nx' 'vm-intrepid-amd64-serial.qcow2 2230 qemu64' 'vm-intrepid-i386-serial.qcow2 2231 qemu32,-nx' 'vm-karmic-amd64-serial.qcow2 2232 qemu64' 'vm-karmic-i386-serial.qcow2 2233 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
	  "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
	  "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y debconf-utils" \
	  "= scp -P $2 my.seed sources.append buildbot@localhost:/tmp/" \
	  "sudo debconf-set-selections /tmp/my.seed" \
	  "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for upgrade testing
-----------------------

 
```
for i in 'vm-hardy-amd64-install.qcow2 2228 qemu64' 'vm-hardy-i386-install.qcow2 2229 qemu32,-nx' 'vm-intrepid-amd64-install.qcow2 2230 qemu64' 'vm-intrepid-i386-install.qcow2 2231 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
  'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.0'
  'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ; \
done

for i in 'vm-karmic-amd64-install.qcow2 2232 qemu64' 'vm-karmic-i386-install.qcow2 2233 qemu32,-nx' ; do \
  set $i; \
  runvm --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server-5.1' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ; \
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-ubuntu-804-810-and-910/>

Buildbot Setup for Virtual Machines - Debian
=============================================

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Debian 7 "wheezy"](../buildbot-setup-for-virtual-machines-debian-7-wheezy/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-wheezy-amd64-seri  |
|  [Buildbot Setup for Virtual Machines - Debian 6 amd64](../buildbot-setup-for-virtual-machines-debian-6-amd64/index) |  Create the VM: cd /kvm/vms qemu-img create -f qcow2 vm-debian6-amd64  |
|  [Buildbot Setup for Virtual Machines - Debian 6 i386](../buildbot-setup-for-virtual-machines-debian-6-i386/index) |  Base Install cd /kvm/vms qemu-img create -f qcow2 vm-debian6-i386-se  |
|  [Buildbot Setup for Virtual Machines - Debian 5 amd64](../buildbot-setup-for-virtual-machines-debian-5-amd64/index) |  Download netinst CD image debian-503-amd64-netinst.iso cd /kvm/vms q  |
|  [Buildbot Setup for Virtual Machines - Debian 5 i386](../buildbot-setup-for-virtual-machines-debian-5-i386/index) |  Base install Download netinst CD image debian-503-i386-netinst.iso and inst...  |
|  [Buildbot Setup for Virtual Machines - Debian 4 i386](../buildbot-setup-for-virtual-machines-debian-4-i386/index) |  Create the VM: cd /kvm/vms qemu-img create -f qcow2 vm-debian4-i386-  |
|  [Buildbot Setup for Virtual Machines - Debian 4 amd64](../buildbot-setup-for-virtual-machines-debian-4-amd64/index) |  cd /kvm/vms qemu-img create -f qcow2 vm-debian4-amd64-serial.qcow2 8  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian/>

Buildbot Setup for Virtual Machines - CentOS 6.2
================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-centos6-amd64-serial.qcow2 8G
qemu-img create -f qcow2 /kvm/vms/vm-centos6-i386-serial.qcow2 8G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 1024 -hda /kvm/vms/vm-centos6-amd64-serial.qcow2 -cdrom /kvm/iso/centos/CentOS-6.2-x86_64-bin-DVD1.iso -redir tcp:22255::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-centos6-i386-serial.qcow2 -cdrom /kvm/iso/centos/CentOS-6.2-i386-bin-DVD1.iso -redir tcp:22256::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The CentOS installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * The Installer will throw up a "Storage Device Warning", choose "Yes, discard any data"
* Set the hostname to centos6-amd64 (or centos6-i386)
* Click the "Configure Network" button on the Hostname screen.
	+ Edit System eth0 to "connect automatically"
	+ Apply and then close the "Network Connections" window
* Set Timezone to Europe/Helsinki (keep "System clock uses UTC" checked)
* When partitioning disks, choose "Use All Space"
	+ **do not** check the "Encrypt system" checkbox
	+ **do** check the "Review and modify partitioning layout" checkbox
	+ Delete the LVM stuff and leaving the sda1 partition alone, repartition the physical volume as follows

 


| Device | Size(MB) | Mount Point | Type | Format |
| --- | --- | --- | --- | --- |
| sda2 | 5672 | / | ext4 | yes |
| sda3 | (max allowable) | (n/a) | swap | yes |

 
* Minimal install
* Customize Later

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM (after the reboot fails) and start it up again:

 
```
kvm -m 1024 -hda /kvm/vms/vm-centos6-amd64-serial.qcow2 -redir tcp:22255::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

kvm -m 1024 -hda /kvm/vms/vm-centos6-i386-serial.qcow2 -redir tcp:22256::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

You may connect via VNC as before, but ssh is probably preferred. Login as root.

 Now that the VM is installed, it's time to configure it.

 
```
ssh -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost
ssh -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost

```

After logging in as root, create a local user

 
```
adduser ${username}
usermod -a -G wheel ${username}
passwd ${username}

```

Enable password-less sudo and serial console:

 
```
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Still logged in as root, add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing 'quiet'):

 
```
console=tty0 console=ttyS0,115200n8

```

Add login prompt on serial console:

 
```

cat >>/etc/inittab <<END

# Serial console.
S0:2345:respawn:/sbin/agetty -h -L ttyS0 19200 vt100
END

```
 Logout as root, and then, from the VM host server:

 Install proper ssh:

 
```
ssh -t -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "sudo yum install openssh-server openssh-clients"
ssh -t -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "sudo yum install openssh-server openssh-clients"

```

Create a .ssh folder:

 
```
ssh -t -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"
ssh -t -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

Upload the ttyS0.conf file and put it where it goes:

 
```
scp -P 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf;'
ssh -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf;'

```

Update the VM:

 
```
ssh -p 22255 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 22256 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum update

```

After updating, shut down the VM:

 
```
sudo shutdown -h now

```

VMs for building .rpms
----------------------

 
```
for i in '/kvm/vms/vm-centos6-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-centos6-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo yum -y groupinstall 'Development Tools'" \
    "sudo yum -y install wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel libxml2 libxml2-devel unixODBC-devel bzr perl perl\(DBI\)" \
    "sudo yum -y remove systemtap-sdt-dev" \
    "bzr co --lightweight lp:mariadb-native-client" \
    "sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS" \
    "wget http://www.cmake.org/files/v2.8/cmake-2.8.8.tar.gz;tar -zxvf cmake-2.8.8.tar.gz;cd cmake-2.8.8;./configure;make;sudo make install"; \
done

```

Also:

 * [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index)

 VMs for install testing.
------------------------

 `MariaDB.local.repo` points at a local directory on the VM. `MariaDB.repo` points at the real MariaDB YUM repository.

 
```
for i in '/kvm/vms/vm-centos6-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-centos6-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch libaio perl perl-Time-HiRes perl-DBI libtool-ltdl unixODBC" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    "sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-centos6-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-centos6-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo yum -y update" \
    'sudo yum -y install mysql-server libtool-ltdl unixODBC' \
    'sudo /etc/init.d/mysqld start' \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    "sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/"; \
done

```


The MariaDB upgrade testing VMs were not built. There is currently an error with installing MariaDB from the YUM repo.

 VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-centos6-amd64-serial.qcow2 22255 qemu64' '/kvm/vms/vm-centos6-i386-serial.qcow2 22256 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.repo buildbot@localhost:/tmp/" \
    'sudo rpm --verbose --import http://downloads.mariadb.org/repo/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch postfix' \
    'sudo /etc/init.d/mysqld start' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-centos-62/>

Buildbot Setup for Virtual Machines - Red Hat 6 x86
===================================================

     The following steps were used to create a Red Hat 6 x86 buildslave.

 Initial Setup
-------------

 
```
cd vms
qemu-img create -f qcow2 vm-rhel6-x86-base.qcow2 8G
kvm -m 1024 -hda vm-rhel6-x86-base.qcow2 -cdrom ../iso/red-hat/rhel-server-6.0-i386-dvd.iso -redir 'tcp:22275::22' -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

When the VM boots. Go through the prompts.

 Re-initialize the drive, when prompted.

 Set the Hostname to "rhel6-x86".

 Configure Network, set eth0 to "Connect Automatically"

 Set the root password.

 Set partitioning type to: Use All Space

 Don't encrypt the partitions (just adds overhead).

 Select "Write Changes to Disk" on the popup that appears.

 Set the software set to "Virtual Host".

 After clicking next on the install-type page, the installation will finally start.

 After installation completes, click reboot. Then shutdown the VM.

 Serial Console Setup
--------------------

 
```
cd vms
qemu-img create -b vm-rhel6-x86-base.qcow2 -f qcow2 vm-rhel6-x86-serial.qcow2
kvm -m 1024 -hda vm-rhel6-x86-serial.qcow2 -redir 'tcp:22275::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

Login as root.

 Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing 'quiet'):

 
```
console=tty0 console=ttyS0,115200n8

```

Add login prompt on serial console:

 
```

cat >>/etc/inittab <<END

# Serial console.
S0:2345:respawn:/sbin/agetty -h -L ttyS0 19200 vt100
END

```
 Create buildbot account
-----------------------

 With the network up and running, it's time to add a user so that we don't have to login as root all the time.

 
```
useradd buildbot
# Password is disabled by default in Centos5.
usermod -a -G wheel buildbot
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

# Put in public ssh key for own account and host buildbot account.
# Note that Centos5 seems to require .ssh/authorized_keys chmod go-rwx.
su - buildbot
mkdir .ssh
chmod go-rwx .ssh

# scp the key from the vm host over to .ssh/authorized_keys

chmod go-rwx .ssh/authorized_keys

```

Now logout and then ssh to the VM as the buildbot user. On my local box I added the following to my /.ssh/config file to make logging in easier:

 
```
Host rhel6-x86
HostName localhost
  User buildbot
  IdentityFile ~/.ssh/id_rsa
  Port 2225

```

With the above in place I can simply type:

 
```
ssh rhel6-x86

```

...to connect to the vm.

 RHN and Updates
---------------

 Register the system with RHN:

 
```
sudo rhn_register

```

Choose defaults when registering. After the process is complete:

 
```
sudo yum update

```

The first time you update you'll be prompted to import some GPG keys from Red Hat. The updating process may take a while, depending on the number of updates and the speed of your Internet connection.

 After updating shutdown so we can make more copies.

 
```
sudo shutdown -h now

```

Image for RPM Build
-------------------

 
```
qemu-img create -b vm-rhel6-x86-serial.qcow2 -f qcow2 vm-rhel6-x86-build.qcow2
kvm -m 1024 -hda vm-rhel6-x86-build.qcow2 -redir 'tcp:22275::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Wait for the system to boot.

 Install compilers etc:

 
```
sudo yum groupinstall "Development Tools"
sudo yum install libaio-devel openssl-devel

```

If the "Development Tools" group is not available, the following lines will install the packages from it:

 
```
# Mandatory Packages:
sudo yum install autoconf automake binutils bison flex gcc gcc-c++ gettext
sudo yum install libtool make patch pkgconfig redhat-rpm-config rpm-build

# Default Packages:
sudo yum install byacc cscope ctags cvs diffstat doxygen elfutils gcc-gfortran
sudo yum install git indent intltool patchutils rcs subversion swig systemtap

# Optional Packages:
sudo yum install ElectricFence ant babel bzr chrpath cmake compat-gcc-34
sudo yum install compat-gcc-34-c++ compat-gcc-34-g77 dejagnu expect gcc-gnat
sudo yum install gcc-java gcc-objc gcc-objc++ imake jpackage-utils libstdc++-docs
sudo yum install mercurial mod_dav_svn nasm perltidy python-docs rpmdevtools
sudo yum install rpmlint systemtap-sdt-devel systemtap-server

```

Other packages to install:

 
```
sudo yum install gperf readline-devel ncurses-devel zlib-devel perl perl\(DBI\)

```

Create rpm directories and download 5.0 rpm for shared-compat:

 
```
sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS
sudo mkdir -vp /srv/shared/yum/CentOS/5/i386/RPMS/
cd /srv/shared/yum/CentOS/5/i386/RPMS/
sudo wget http://mirror.ourdelta.org/yum/CentOS/5/i386/RPMS/MySQL-OurDelta-shared-5.0.87.d10-65.el5.i386.rpm

```

Image for install/test
----------------------

 
```
qemu-img create -b vm-rhel6-x86-serial.qcow2 -f qcow2 vm-rhel6-x86-install.qcow2
kvm -m 1024 -hda vm-rhel6-x86-install.qcow2 -redir 'tcp:22275::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Install extra dependencies:

 
```
sudo yum install perl perl\(DBI\)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-red-hat-6-x86/>

Buildbot Setup for Virtual Machines - Debian 5 i386
===================================================

    Base install
------------

 Download netinst CD image debian-503-i386-netinst.iso and install:

 
```
cd /kvm
qemu-img create -f qcow2 vms/vm-debian5-i386-base.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian5-i386-base.qcow2 -cdrom /kvm/debian-503-i386-netinst.iso -redir 'tcp:2226::22' -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

Serial port console
-------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
qemu-img create -b vm-debian5-i386-base.qcow2 -f qcow2 vm-debian5-i386-serial.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-i386-serial.qcow2 -redir 'tcp:2226::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic
su
apt-get install sudo openssh-server emacs22-nox
visudo
# uncomment %sudo ALL=NOPASSWD: ALL
# add user account to group sudo.
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/agetty -h -L ttyS0 19200 vt100

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Add user buildbot, with disabled password. Add as sudo, and add ssh key.

 
```
sudo adduser --disabled-password buildbot
sudo adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Paste all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

Image for .deb build
--------------------

 
```
qemu-img create -b vm-debian5-i386-serial.qcow2 -f qcow2 vm-debian5-i386-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-i386-build.qcow2 -redir 'tcp:2226::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

sudo apt-get build-dep mysql-server-5.0
sudo apt-get install devscripts hardening-wrapper doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline5-dev

```

Image for install testing
-------------------------

 
```
qemu-img create -b vm-debian5-i386-serial.qcow2 -f qcow2 vm-debian5-i386-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-i386-install.qcow2 -redir 'tcp:2226::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article how to obtain the `my.seed` file.

 Image for upgrade testing
-------------------------

 
```
qemu-img create -b vm-debian5-i386-install.qcow2 -f qcow2 vm-debian5-i386-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-i386-upgrade.qcow2 -redir 'tcp:2226::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

sudo apt-get install mysql-server-5.0
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-5-i386/>

Buildbot Setup for Virtual Machines - Debian 5 amd64
=====================================================

    Download netinst CD image debian-503-amd64-netinst.iso

 
```
cd /kvm/vms
qemu-img create -f qcow2 vm-debian5-amd64-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian5-amd64-serial.qcow2 -cdrom /kvm/debian-503-amd64-netinst.iso -redir 'tcp:2234::22' -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Serial console and account setup
--------------------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
kvm -m 2047 -hda /kvm/vms/vm-debian5-amd64-serial.qcow2 -redir 'tcp:2234::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

su
apt-get install sudo openssh-server
visudo
# uncomment %sudo ALL=NOPASSWD: ALL
# add user account to group sudo `addgroup <USER> sudo`.
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/getty -L ttyS0 19200 vt100

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Add user buildbot, with disabled password. Add as sudo, and add ssh key.

 
```
sudo adduser --disabled-password buildbot
sudo adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Add all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

VM for building .deb
--------------------

 
```
qemu-img create -b vm-debian5-amd64-serial.qcow2 -f qcow2 vm-debian5-amd64-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-amd64-build.qcow2 -redir 'tcp:2234::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get build-dep mysql-server-5.0
sudo apt-get install devscripts hardening-wrapper doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline5-dev

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-debian5-amd64-serial.qcow2 -f qcow2 vm-debian5-amd64-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-amd64-install.qcow2 -redir 'tcp:2234::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' file.

 VM for upgrade testing
----------------------

 
```
qemu-img create -b vm-debian5-amd64-install.qcow2 -f qcow2 vm-debian5-amd64-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian5-amd64-upgrade.qcow2 -redir 'tcp:2234::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get install mysql-server-5.0
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-5-amd64/>

Buildbot Setup for Virtual Machines - CentOS 5 i386
===================================================

    Base install
------------

 
```
cd /kvm
qemu-img create -f qcow2 vms/vm-centos5-i386-base.qcow2 8G
# ISO (dvd) install:
kvm -m 2047 -hda /kvm/vms/vm-centos5-i386-base.qcow2 -cdrom CentOS-5.3-i386-bin-DVD.iso -redir 'tcp:2225::22' -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user

```

Configure for serial console
----------------------------

 
```
(cd vms && qemu-img create -b vm-centos5-i386-base.qcow2 -f qcow2 vm-centos5-i386-serial.qcow2)
kvm -m 2047 -hda /kvm/vms/vm-centos5-i386-serial.qcow2 -cdrom CentOS-5.3-i386-bin-DVD.iso -redir 'tcp:2225::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Add login prompt on serial console:

 
```
cat >>/etc/inittab <<END

# Serial console.
S0:2345:respawn:/sbin/agetty -h -L ttyS0 19200 vt100
END

```

Create account.

 
```
useradd buildbot
# Password is disabled by default in Centos5.
usermod -a -G wheel buildbot
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

# Put in public ssh key for own account and host buildbot account.
# Note that Centos5 seems to require .ssh/authorized_keys chmod go-rwx.
su - buildbot
mkdir .ssh
chmod go-rwx .ssh
cat >.ssh/authorized_keys
# Paste the id_dsa.pub key, see above.
chmod go-rwx .ssh/authorized_keys

```

Image for rpm build
-------------------

 
```
qemu-img create -b vm-centos5-i386-serial.qcow2 -f qcow2 vm-centos5-i386-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-centos5-i386-build.qcow2 -cdrom /kvm/CentOS-5.3-i386-bin-DVD.iso -redir 'tcp:2225::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Install compilers etc:

 
```
sudo yum groupinstall "Development Tools"
sudo yum install gperf readline-devel ncurses-devel zlib-devel libaio-devel openssl-devel perl perl\(DBI\)

```

Download 5.0 rpm for shared-compat:

 
```
sudo mkdir -p /srv/shared/yum/CentOS/5/i386/RPMS/
cd /srv/shared/yum/CentOS/5/i386/RPMS/
sudo wget http://mirror.ourdelta.org/yum/CentOS/5/i386/RPMS/MySQL-OurDelta-shared-5.0.87.d10-65.el5.i386.rpm

```

Image for install/test
----------------------

 
```
qemu-img create -b vm-centos5-i386-serial.qcow2 -f qcow2 vm-centos5-i386-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-centos5-i386-install.qcow2 -cdrom /kvm/CentOS-5.3-i386-bin-DVD.iso -redir 'tcp:2225::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Install extra dependencies:

 
```
sudo yum install perl perl\(DBI\)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-centos-5-i386/>

Buildbot Setup for Virtual Machines - Centos 5 amd64
====================================================

    Base install
------------

 
```
cd /kvm
wget http://ftp.klid.dk/ftp/centos/5.3/isos/x86_64/CentOS-5.3-x86_64-bin-DVD.iso
qemu-img create -f qcow2 vms/vm-centos5-amd64-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-centos5-amd64-serial.qcow2 -cdrom CentOS-5.3-x86_64-bin-DVD.iso -redir 'tcp:2237::22' -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Serial port and account setup
-----------------------------

 
```
kvm -m 2047 -hda /kvm/vms/vm-centos5-amd64-serial.qcow2 -cdrom CentOS-5.3-i386-bin-DVD.iso -redir 'tcp:2237::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line (after removing `quiet splash'):

 
```
console=tty0 console=ttyS0,115200n8

```

Run these commands:

 
```
cat >>/etc/inittab <<END
 
# Serial console.
S0:2345:respawn:/sbin/agetty -h -L ttyS0 19200 vt100
END

```


```
useradd buildbot

# Password is disabled by default in Centos5.

usermod -a -G wheel buildbot
visudo

# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

# Put in public ssh key for own account and host buildbot account.
# Note that Centos5 seems to require .ssh/authorized_keys chmod go-rwx.

su - buildbot
mkdir .ssh
chmod go-rwx .ssh
cat >.ssh/authorized_keys
chmod go-rwx .ssh/authorized_keys

```

Image for rpm build
-------------------

 
```
qemu-img create -b vm-centos5-amd64-serial.qcow2 -f qcow2 vm-centos5-amd64-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-centos5-amd64-build.qcow2 -cdrom /kvm/CentOS-5.3-x86_64-bin-DVD.iso -redir 'tcp:2237::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Install compilers etc:

 
```
sudo yum groupinstall "Development Tools"
sudo yum install gperf readline-devel ncurses-devel libaio-devel openssl-devel zlib-devel perl perl\(DBI\)

```

Download 5.0 rpm for shared-compat:

 
```
sudo mkdir -p /srv/shared/yum/CentOS/5/x86_64/RPMS/
cd /srv/shared/yum/CentOS/5/x86_64/RPMS/
sudo wget http://mirror.ourdelta.org/yum/CentOS/5/x86_64/RPMS/MySQL-OurDelta-shared-5.0.87.d10-65.el5.x86_64.rpm

```

Image for install/test
----------------------

 
```
qemu-img create -b vm-centos5-amd64-serial.qcow2 -f qcow2 vm-centos5-amd64-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-centos5-amd64-install.qcow2 -cdrom /kvm/CentOS-5.3-x86_64-bin-DVD.iso -redir 'tcp:2237::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Install extra dependencies:

 
```
sudo yum install perl perl\(DBI\)

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-centos-5-amd64/>

Buildbot Setup for Virtual Machines - Debian 4 i386
===================================================

    Create the VM:

 
```
cd /kvm/vms
qemu-img create -f qcow2 vm-debian4-i386-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian4-i386-serial.qcow2 -cdrom /kvm/debian-40r8-i386-netinst.iso -redir 'tcp:2241::22' -boot d -smp 2 -cpu qemu32,-nx -net nic,model=e1000 -net user

```

Serial console and account setup
--------------------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
kvm -m 2047 -hda /kvm/vms/vm-debian4-i386-serial.qcow2 -cdrom /kvm/debian-40r8-i386-netinst.iso -redir 'tcp:2241::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=e1000 -net user

su
apt-get install sudo openssh-server
VISUAL=vi visudo

# Add at the end:t %sudo ALL=NOPASSWD: ALL

# Add account <USER> to group sudo
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/getty -L ttyS0 19200 vt100

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line:

 
```
console=tty0 console=ttyS0,115200n8

```

Do these steps:

 
```
# Add user buildbot, with disabled password. Add as sudo, and add ssh key.
sudo /usr/sbin/adduser --disabled-password buildbot
sudo /usr/sbin/adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Add all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

VM for build
------------

 
```
qemu-img create -b vm-debian4-i386-serial.qcow2 -f qcow2 vm-debian4-i386-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-i386-build.qcow2 -cdrom /kvm/debian-40r8-i386-netinst.iso -redir 'tcp:2241::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=e1000 -net user -nographic

sudo apt-get build-dep mysql-server-5.0
# Some latex packages fail to install because they complain that the
# source is more than 5 years old! I solved by setting back the clock a
# couple of years temporarily ...
sudo apt-get install devscripts doxygen texlive-latex-base gs lsb-release fakeroot libevent-dev libssl-dev zlib1g-dev libreadline5-dev

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-debian4-i386-serial.qcow2 -f qcow2 vm-debian4-i386-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-i386-install.qcow2 -cdrom /kvm/debian-40r8-i386-netinst.iso -redir 'tcp:2241::22' -boot c -smp 2 -cpu qemu32,-nx -net nic,model=e1000 -net user -nographic

```

See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' file.

 
```
# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

VM for upgrade testing
----------------------

 
```
qemu-img create -b vm-debian4-i386-install.qcow2 -f qcow2 vm-debian4-i386-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-i386-upgrade.qcow2 -cdrom /kvm/debian-40r8-i386-netinst.iso -redir 'tcp:2241::22' -boot c -smp 2 -cpu qemu64 -net nic,model=e1000 -net user -nographic

sudo apt-get install mysql-server-5.0
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-4-i386/>

Buildbot Setup for Virtual Machines - Debian 6 amd64
====================================================

    Create the VM:

 
```
cd /kvm/vms
qemu-img create -f qcow2 vm-debian6-amd64-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian6-amd64-serial.qcow2 -cdrom /kvm/debian-6a1-amd64-netinst.iso -redir 'tcp:2244::22' -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Serial console and account setup
--------------------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
kvm -m 2047 -hda /kvm/vms/vm-debian6-amd64-serial.qcow2 -redir 'tcp:2244::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

su
apt-get install sudo openssh-server
visudo

# Add: %sudo ALL=NOPASSWD: ALL
# add user account to group sudo `addgroup <USER> sudo`.
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/getty -L ttyS0 19200 vt100

```

Editing /etc/default/grub:

 
```
sudo vi /etc/default/grub
# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

Add user buildbot, with disabled password. Add as sudo, and add ssh key.

 
```
sudo adduser --disabled-password buildbot
sudo adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Add all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

VM for building .deb
--------------------

 
```
qemu-img create -b vm-debian6-amd64-serial.qcow2 -f qcow2 vm-debian6-amd64-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-amd64-build.qcow2 -redir 'tcp:2244::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get build-dep mysql-server-5.1
sudo apt-get install devscripts hardening-wrapper doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline-dev

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-debian6-amd64-serial.qcow2 -f qcow2 vm-debian6-amd64-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-amd64-install.qcow2 -redir 'tcp:2244::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' file.

 
```
# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

VM for upgrade testing
----------------------

 
```
qemu-img create -b vm-debian6-amd64-install.qcow2 -f qcow2 vm-debian6-amd64-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-amd64-upgrade.qcow2 -redir 'tcp:2244::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get install mysql-server-5.1
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-6-amd64/>

Buildbot Setup for Virtual Machines - Fedora 17
===============================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-fedora17-i386-serial.qcow2 10G
qemu-img create -f qcow2 /kvm/vms/vm-fedora17-amd64-serial.qcow2 10G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora17-i386-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-17-i386-DVD.iso -redir tcp:2265::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-fedora17-amd64-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-17-x86_64-DVD.iso -redir tcp:2266::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The Fedora installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * The Installer will throw up a "Storage Device Warning", choose "Yes, discard any data"
* Set the hostname to fedora17-amd64 (or fedora17-i386)
* Click the "Configure Network" button on the Hostname screen.
	+ Edit System eth0 to "connect automatically"
	+ Apply and then close the "Network Connections" window
* When partitioning disks, choose "Use All Space"
	+ **uncheck** the "Use LVM" checkbox
	+ **do not** check the "Encrypt system" checkbox
* Minimal install
* Customize Later

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM (after the reboot fails) and start it up again:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora17-i386-serial.qcow2 -redir tcp:2265::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-fedora17-amd64-serial.qcow2 -redir tcp:2266::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Until the extra user is installed you must connect via VNC as before. SSH is preferred, so that's what we'll do first. Login as root.

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost

```

After logging in as root, install proper ssh and then create a local user:

 
```
/sbin/chkconfig --level 35 network on
ifup eth0
yum install openssh-server openssh-clients
adduser ${username}
usermod -a -G wheel ${username}
passwd ${username}

```

Enable password-less sudo and serial console:

 
```
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Still logged in as root, add to /boot/grub/menu.lst:

 Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

grub2-mkconfig -o /boot/grub2/grub.cfg

```

Logout as root, and then, from the VM host server:

 Create a .ssh folder:

 
```
ssh -t -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"
ssh -t -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

su to the local buildbot user and ssh to the vm to put the key in known\_hosts:

 For i386:

 
```
sudo su - buildbot
ssh -p 2265 buildbot@localhost
# exit, then exit again

```

For amd64:

 
```
sudo su - buildbot
ssh -p 2266 buildbot@localhost
# exit, then exit again

```

Upload the ttyS0 file and put it where it goes:

 
```
scp -P 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:
scp -P 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:

ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'

```

Update the VM:

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum update

```

After updating, shut down the VM:

 
```
sudo shutdown -h now

```

VMs for building .rpms
----------------------

 On the VM host server:

 
```
qemu-img create -b /kvm/vms/vm-fedora17-i386-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-i386-build.qcow2
qemu-img create -b /kvm/vms/vm-fedora17-amd64-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-amd64-build.qcow2

```

Boot the VMs with:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora17-i386-build.qcow2 -redir tcp:2265::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-fedora17-amd64-build.qcow2 -redir tcp:2266::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Copy over the boost tar file:

 
```
scp -P 2265 -i /kvm/vms/ssh-keys/id_dsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/
scp -P 2266 -i /kvm/vms/ssh-keys/id_dsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/

```

Login to the VMs:

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum -y groupinstall 'Development Tools'
sudo yum -y install tar wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel perl perl\(DBI\)
sudo yum -y remove systemtap-sdt-dev
sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS

# cmake
wget http://www.cmake.org/files/v2.8/cmake-2.8.8.tar.gz;tar -zxvf cmake-2.8.8.tar.gz;cd cmake-2.8.8;./configure;make;sudo make install

# boost
cd /usr/local/src;sudo tar zxf /dev/shm/boost_1_49_0.tar.gz;cd /usr/local/include/;sudo ln -s ../src/boost_1_49_0/boost .

# shutdown the VM
sudo shutdown -h now

```

VMs for install testing.
------------------------

 On the VM host server:

 
```
qemu-img create -b /kvm/vms/vm-fedora17-i386-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-i386-install.qcow2
qemu-img create -b /kvm/vms/vm-fedora17-amd64-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-amd64-install.qcow2

```

Boot the VMs with:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora17-i386-install.qcow2 -redir tcp:2265::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-fedora17-amd64-install.qcow2 -redir tcp:2266::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Login to the VMs:

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum -y update
sudo yum -y install patch tar libaio perl perl-Time-HiRes perl-DBI

# shutdown the VM
sudo shutdown -h now

```

VMs for MySQL upgrade testing
-----------------------------

 On the VM host server:

 
```
qemu-img create -b /kvm/vms/vm-fedora17-i386-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-i386-upgrade.qcow2
qemu-img create -b /kvm/vms/vm-fedora17-amd64-serial.qcow2 -f qcow2 /kvm/vms/vm-fedora17-amd64-upgrade.qcow2

```

Boot the VMs with:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora17-i386-upgrade.qcow2 -redir tcp:2265::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-fedora17-amd64-upgrade.qcow2 -redir tcp:2266::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

Login to the VMs:

 
```
ssh -p 2265 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2266 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum -y update
sudo yum -y install tar mysql-server
sudo systemctl enable mysqld.service
sudo systemctl start mysqld.service
mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

# shutdown the VM
sudo shutdown -h now

```


The MariaDB upgrade testing VMs were not built. Once we have MariaDB Fedora 17 RPMs, then I will attempt building this VM. For now, the placeholder text below is copied from the [Buildbot Setup for Virtual Machines - CentOS 6.2](../buildbot-setup-for-virtual-machines-centos-62/index) page.

 VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-fedora17-amd64-serial.qcow2 2266 qemu64' '/kvm/vms/vm-fedora17-i386-serial.qcow2 2265 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.repo buildbot@localhost:/tmp/" \
    'sudo rpm --verbose --import http://downloads.mariadb.org/repo/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch postfix' \
    'sudo /etc/init.d/mysqld start' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-fedora-17/>

Buildbot Setup for Virtual Machines - Fedora 18
===============================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-fedora18-i386-serial.qcow2 10G
qemu-img create -f qcow2 /kvm/vms/vm-fedora18-amd64-serial.qcow2 10G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora18-i386-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-18-i386-DVD.iso -redir tcp:2277::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora18-amd64-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-18-x86_64-DVD.iso -redir tcp:2278::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The Fedora installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Under "Network Configuration" set the hostnames to fedora18-amd64 and fedora18-i386
* Change "Software Selection" to "Minimal Install" (default is "Gnome Desktop")
* For "Installation Destination" select the disk then click continue.
* **do not** check the encryption checkbox
* On "Installation Options" screen, expand the "Partition scheme configuration" box and select a "Partition type" of "Standard Partition"
* While installing, set the root password

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM (after the reboot fails) and start it up again:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora18-i386-serial.qcow2 -redir tcp:2277::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora18-amd64-serial.qcow2 -redir tcp:2278::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Until a non-root user is installed you must connect as root. SSH is preferred, so that's what we'll do first. Login as root.

 
```
ssh -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost
ssh -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost

```

After logging in as root, install proper ssh and then create a local user:

 
```
adduser ${username}
usermod -a -G wheel ${username}
passwd ${username}

```

Enable password-less sudo and serial console:

 
```
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Still logged in as root, add to /boot/grub/menu.lst:

 Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

grub2-mkconfig -o /boot/grub2/grub.cfg

```

Logout as root, and then, from the VM host server:

 Create a .ssh folder:

 
```
ssh -t -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"
ssh -t -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

su to the local buildbot user and ssh to the vm to put the key in known\_hosts:

 For i386:

 
```
sudo su - buildbot
ssh -p 2277 buildbot@localhost
# exit, then exit again

```

For amd64:

 
```
sudo su - buildbot
ssh -p 2278 buildbot@localhost
# exit, then exit again

```

Upload the ttyS0 file and put it where it goes:

 
```
scp -P 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:
scp -P 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:

ssh -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'
ssh -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'

```

Update the VM:

 
```
ssh -p 2277 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2278 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum update

```

After updating, shut down the VM:

 
```
sudo shutdown -h now

```

VMs for building .rpms
----------------------

 
```
for i in '/kvm/vms/vm-fedora18-i386-serial.qcow2 2277 qemu64' '/kvm/vms/vm-fedora18-amd64-serial.qcow2 2278 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
  "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/" \
  "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
  "sudo yum -y groupinstall 'Development Tools'" \
  "sudo yum -y install cmake tar wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel libxml2 libxml2-devel unixODBC-devel bzr perl perl\(DBI\)" \
  "sudo yum -y remove systemtap-sdt-dev" \
  "bzr co --lightweight lp:mariadb-native-client" \
  "sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS" \
  "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
  "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" \
  "cd /usr/local/src;sudo tar zxf /dev/shm/boost_1_49_0.tar.gz;cd /usr/local/include/;sudo ln -vs ../src/boost_1_49_0/boost ." ; \
done

```

VMs for install testing.
------------------------

 
```
for i in '/kvm/vms/vm-fedora18-i386-serial.qcow2 2277 qemu64' '/kvm/vms/vm-fedora18-amd64-serial.qcow2 2278 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar libaio perl perl-Time-HiRes perl-DBI" ; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-fedora18-i386-serial.qcow2 2277 qemu64' '/kvm/vms/vm-fedora18-amd64-serial.qcow2 2278 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar mysql-server libtool-ltdl unixODBC" \
    "sudo systemctl enable mysqld.service" \
    "sudo systemctl start mysqld.service" \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ; \
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-fedora18-amd64-serial.qcow2 2278 qemu64' '/kvm/vms/vm-fedora18-i386-serial.qcow2 2277 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB-${2}.repo buildbot@localhost:/tmp/MariaDB.repo" \
    'sudo rpm --verbose --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test libtool-ltdl unixODBC' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch postfix patch tar' \
    'sudo /etc/init.d/mysqld start' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-fedora-18/>

Buildbot Setup for Virtual Machines - Fedora 19
===============================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-fedora19-i386-serial.qcow2 20G
qemu-img create -f qcow2 /kvm/vms/vm-fedora19-amd64-serial.qcow2 20G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora19-i386-serial.qcow2 -cdrom /ds413/iso/fedora/Fedora-19-i386-DVD.iso -redir tcp:2289::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora19-amd64-serial.qcow2 -cdrom /ds413/iso/fedora/Fedora-19-x86_64-DVD.iso -redir tcp:2290::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The Fedora installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Under "Network Configuration" set the hostnames to fedora19-amd64 and fedora19-i386
* Change "Software Selection" to "Minimal Install" (default is "Gnome Desktop")
* For "Installation Destination" select the disk then click continue.
* **do not** check the encryption checkbox
* On "Installation Options" screen, expand the "Partition scheme configuration" box and select a "Partition type" of "Standard Partition"
* While installing, set the root password and an initial user

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM (after the reboot fails) and start it up again:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora19-i386-serial.qcow2 -redir tcp:2289::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora19-amd64-serial.qcow2 -redir tcp:2290::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Log in using the initial user created during the install:

 
```
ssh -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost
ssh -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost

```

After logging in, add the initial user to the "wheel" group.

 
```
usermod -a -G wheel ${username}

```

Enable password-less sudo for the "wheel" group and serial console sudo:

 
```
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Edit /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

grub2-mkconfig -o /boot/grub2/grub.cfg

```

Logout as root, and then, from the VM host server:

 Create a .ssh folder:

 
```
ssh -t -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"
ssh -t -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

su to the local buildbot user and ssh to the vm to put the key in known\_hosts:

 For i386:

 
```
sudo su - buildbot
ssh -p 2289 buildbot@localhost
# exit, then exit again

```

For amd64:

 
```
sudo su - buildbot
ssh -p 2290 buildbot@localhost
# exit, then exit again

```

Upload the ttyS0 file and put it where it goes:

 
```
scp -P 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:
scp -P 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:

ssh -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'
ssh -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'

```

Update the VM:

 
```
ssh -p 2289 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2290 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum update

```

Change selinux policy to `permissive`:

 
```
sudo vi /etc/selinux/config 
# change:
SELINUX=enforcing
# to:
SELINUX=permissive

```

After updating, shut down the VM:

 
```
sudo shutdown -h now

```

VMs for building .rpms
----------------------

 
```
for i in '/kvm/vms/vm-fedora19-i386-serial.qcow2 2289 qemu64' '/kvm/vms/vm-fedora19-amd64-serial.qcow2 2290 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
  "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
  "sudo yum -y groupinstall 'Development Tools'" \
  "sudo yum -y install yum-utils" \
  "sudo yum-builddep -y mariadb" \
  "sudo yum -y install automake libtool flex pkgconfig gcc-c++ libevent-devel python-devel ruby-devel rpm-build" \
  "sudo yum -y install cmake tar wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel" \
  "sudo yum -y install libxml2 libxml2-devel bison bison-devel boost-devel unixODBC-devel bzr perl perl\(DBI\)" \
  "sudo yum -y remove systemtap-sdt-dev" \
  "bzr co --lightweight lp:mariadb-native-client" \
  "sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS" \
  "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
  "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" ; \
done

```

VMs for install testing.
------------------------

 
```
for i in '/kvm/vms/vm-fedora19-i386-serial.qcow2 2289 qemu64' '/kvm/vms/vm-fedora19-amd64-serial.qcow2 2290 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar libaio perl perl-Time-HiRes perl-DBI unixODBC" ; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-fedora19-i386-serial.qcow2 2289 qemu64' '/kvm/vms/vm-fedora19-amd64-serial.qcow2 2290 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar mysql-server libtool-ltdl unixODBC" \
    "sudo systemctl enable mysqld.service" \
    "sudo systemctl start mysqld.service" \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ; \
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-fedora19-amd64-serial.qcow2 2290 qemu64' '/kvm/vms/vm-fedora19-i386-serial.qcow2 2289 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB-${2}.repo buildbot@localhost:/tmp/MariaDB.repo" \
    'sudo rpm --verbose --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test libtool-ltdl unixODBC' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch patch tar' \
    'sudo /etc/init.d/mysql start' \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-fedora-19/>

Buildbot Setup for Virtual Machines - Fedora 16
===============================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-fedora16-i386-serial.qcow2 10G
qemu-img create -f qcow2 /kvm/vms/vm-fedora16-amd64-serial.qcow2 10G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora16-i386-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-16-i386-DVD.iso -redir tcp:2263::22 -boot d -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-fedora16-amd64-serial.qcow2 -cdrom /kvm/iso/fedora/Fedora-16-x86_64-DVD.iso -redir tcp:2264::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The Fedora installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * The Installer will throw up a "Storage Device Warning", choose "Yes, discard any data"
* Set the hostname to fedora16-amd64 (or fedora16-i386)
* Click the "Configure Network" button on the Hostname screen.
	+ Edit System eth0 to "connect automatically"
	+ Apply and then close the "Network Connections" window
* When partitioning disks, choose "Use All Space"
	+ **uncheck** the "Use LVM" checkbox
	+ **do not** check the "Encrypt system" checkbox
* Minimal install
* Customize Later

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM (after the reboot fails) and start it up again:

 
```
kvm -m 1024 -hda /kvm/vms/vm-fedora16-i386-serial.qcow2 -redir tcp:2263::22 -boot c -smp 2 -cpu qemu32,-nx -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-fedora16-amd64-serial.qcow2 -redir tcp:2264::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Until the extra user is installed you must connect via VNC as before. SSH is preferred, so that's what we'll do first. Login as root.

 
```
ssh -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost
ssh -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa root@localhost

```

After logging in as root, install proper ssh and then create a local user:

 
```
/sbin/chkconfig --level 35 network on
ifup eth0
yum install openssh-server openssh-clients
adduser ${username}
usermod -a -G wheel ${username}
passwd ${username}

```

Enable password-less sudo and serial console:

 
```
visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Still logged in as root, add to /boot/grub/menu.lst:

 Editing /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

grub2-mkconfig -o /boot/grub2/grub.cfg

```

Logout as root, and then, from the VM host server:

 Create a .ssh folder:

 
```
ssh -t -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"
ssh -t -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -R go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -R go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

su to the local buildbot user and ssh to the vm to put the key in known\_hosts:

 For i386:

 
```
sudo su - buildbot
ssh -p 2263 buildbot@localhost
# exit, then exit again

```

For amd64:

 
```
sudo su - buildbot
ssh -p 2264 buildbot@localhost
# exit, then exit again

```

Upload the ttyS0 file and put it where it goes:

 
```
scp -P 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:
scp -P 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:

ssh -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mv -vi ttyS0 /etc/event.d/;'
ssh -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mv -vi ttyS0 /etc/event.d/;'

```

Update the VM:

 
```
ssh -p 2263 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -p 2264 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum update

```

After updating, shut down the VM:

 
```
sudo shutdown -h now

```

VMs for building .rpms
----------------------

 
```
for i in '/kvm/vms/vm-fedora16-amd64-serial.qcow2 2264 qemu64' '/kvm/vms/vm-fedora16-i386-serial.qcow2 2263 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "sudo yum -y groupinstall 'Development Tools'" \
    "sudo yum -y install wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel perl perl\(DBI\)" \
    "sudo yum -y remove systemtap-sdt-dev" \
    "sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS" \
    "wget http://www.cmake.org/files/v2.8/cmake-2.8.8.tar.gz;tar -zxvf cmake-2.8.8.tar.gz;cd cmake-2.8.8;./configure;make;sudo make install"; \
done

```

Also:

 * [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index)

 VMs for install testing.
------------------------

 `MariaDB.local.repo` points at a local directory on the VM. `MariaDB.repo` points at the real MariaDB YUM repository.

 
```
for i in '/kvm/vms/vm-fedora16-amd64-serial.qcow2 2264 qemu64' '/kvm/vms/vm-fedora16-i386-serial.qcow2 2263 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo yum -y update" \
    "sudo yum -y install libaio perl perl-Time-HiRes perl-DBI" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    "sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-fedora16-amd64-serial.qcow2 2264 qemu64' '/kvm/vms/vm-fedora16-i386-serial.qcow2 2263 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo yum -y update" \
    'sudo yum -y install mysql-server' \
    'sudo systemctl enable mysqld.service' \
    'sudo systemctl start mysqld.service' \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    "sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/"; \
done

```


The MariaDB upgrade testing VMs were not built. Once we have MariaDB Fedora 16 RPMs, then I will attempt building this VM. For now, the placeholder text below is copied from the [Buildbot Setup for Virtual Machines - CentOS 6.2](../buildbot-setup-for-virtual-machines-centos-62/index) page.

 VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-fedora16-amd64-serial.qcow2 2264 qemu64' '/kvm/vms/vm-fedora16-i386-serial.qcow2 2263 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.repo buildbot@localhost:/tmp/" \
    'sudo rpm --verbose --import http://downloads.mariadb.org/repo/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch postfix' \
    'sudo /etc/init.d/mysqld start' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-fedora-16/>

Buildbot Setup for Virtual Machines - Fedora 20
===============================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-fedora20-i386-serial.qcow2 20G
qemu-img create -f qcow2 /kvm/vms/vm-fedora20-amd64-serial.qcow2 20G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora20-i386-serial.qcow2 -cdrom /ds413/iso/fedora/Fedora-20-i386-DVD.iso -redir tcp:2291::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora20-amd64-serial.qcow2 -cdrom /ds413/iso/fedora/Fedora-20-x86_64-DVD.iso -redir tcp:2292::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. The Fedora installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the language to English(US)
* Set the timezone to Etc/Greenwich Mean Time timezone
* Change "Software Selection" to "Minimal Install" (default is "Gnome Desktop")
* Under "Network Configuration" set the hostnames to fedora20-amd64 and fedora20-i386
* For "Installation Destination" select the disk then click continue.
	+ On "Installation Options" screen, select the "Partition scheme" drop-down menu and select "Standard Partition". We **do not** want LVM.
	+ **do not** check the encryption checkbox
* Select the "Begin installation" button to start the install
* While installing, set the root password and an initial user.
	+ Be sure the initial user is an administrator

 When the install is finished, you will be prompted to reboot. Go ahead and do so, but it will fail. Kill the VM after the reboot fails and start it up again with:

 
```
kvm -m 2048 -hda /kvm/vms/vm-fedora20-i386-serial.qcow2 -redir tcp:2291::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 2048 -hda /kvm/vms/vm-fedora20-amd64-serial.qcow2 -redir tcp:2292::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Log in using the initial user created during the install:

 
```
ssh -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost
ssh -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost

```

After logging in, add the initial user to the "wheel" group.

 
```
sudo usermod -a -G wheel ${username}

```

Enable password-less sudo for the "wheel" group and serial console sudo:

 
```
sudo visudo
# Uncomment the line "%wheel        ALL=(ALL)       NOPASSWD: ALL"
# Comment out this line:
# Defaults    requiretty

```

Edit /boot/grub/menu.lst:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL="serial"
GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

```

Logout and then, from the VM host server:

 Create a .ssh folder:

 
```
ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "mkdir -v .ssh"

```

Copy over the authorized keys file:

 
```
scp -P 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/authorized_keys localhost:.ssh/

```

Set permissions on the .ssh folder correctly:

 
```
ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -vR go-rwx .ssh"
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa localhost "chmod -vR go-rwx .ssh"

```

Create the buildbot user:

 
```
ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -vR go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no localhost 'chmod -vR go-rwx .ssh; sudo adduser buildbot; sudo usermod -a -G wheel buildbot; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

```

su to the local buildbot user and ssh to the vm to put the key in known\_hosts:

 For i386:

 
```
sudo su - buildbot
ssh -p 2291 buildbot@localhost
# exit, then exit again

```

For amd64:

 
```
sudo su - buildbot
ssh -p 2292 buildbot@localhost
# exit, then exit again

```

Upload the ttyS0 file and put it where it goes:

 
```
scp -P 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:
scp -P 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/ttyS0 buildbot@localhost:

ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo mkdir -v /etc/event.d;sudo mv -vi ttyS0 /etc/event.d/;'

```

Update the VM:

 
```
ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

```

Once logged in:

 
```
sudo yum -y update

```

Change selinux policy to `permissive`:

 
```
sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

```

After updating, exit, then shut down the VM:

 
```
exit

```


```
ssh -t -p 2291 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo shutdown -h now;exit'
ssh -t -p 2292 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost 'sudo shutdown -h now;exit'

```

VMs for building .rpms
----------------------

 
```
for i in '/kvm/vms/vm-fedora20-i386-serial.qcow2 2291 qemu64' '/kvm/vms/vm-fedora20-amd64-serial.qcow2 2292 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_build_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
  "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/thrift-0.9.0.tar.gz buildbot@localhost:/dev/shm/" \
  "sudo yum -y groupinstall 'Development Tools'" \
  "sudo yum -y install yum-utils" \
  "sudo yum-builddep -y mariadb" \
  "sudo yum -y install automake libtool flex pkgconfig gcc-c++ libevent-devel python-devel ruby-devel rpm-build Judy-devel" \
  "sudo yum -y install cmake tar wget tree gperf readline-devel ncurses-devel zlib-devel pam-devel libaio-devel openssl-devel" \
  "sudo yum -y install libxml2 libxml2-devel bison bison-devel boost-devel unixODBC-devel bzr perl perl\(DBI\)" \
  "sudo yum -y remove systemtap-sdt-dev" \
  "bzr co --lightweight lp:mariadb-native-client" \
  "sudo mkdir -vp /usr/src/redhat/SOURCES /usr/src/redhat/SPECS /usr/src/redhat/RPMS /usr/src/redhat/SRPMS" \
  "cd /usr/local/src;sudo tar zxf /dev/shm/thrift-0.9.0.tar.gz;pwd;ls" \
  "cd /usr/local/src/thrift-0.9.0;echo;pwd;sudo ./configure --prefix=/usr --enable-shared=no --enable-static=yes CXXFLAGS=-fPIC CFLAGS=-fPIC && echo && echo 'now making' && echo && sleep 3 && sudo make && echo && echo 'now installing' && echo && sleep 3 && sudo make install" ; \
done

```

VMs for install testing.
------------------------

 
```
for i in '/kvm/vms/vm-fedora20-i386-serial.qcow2 2291 qemu64' '/kvm/vms/vm-fedora20-amd64-serial.qcow2 2292 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_install_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar libaio perl perl-Time-HiRes perl-DBI unixODBC Judy" ; \
done

```

VMs for MariaDB upgrade testing (Fedora repo)
---------------------------------------------

 
```
for i in '/kvm/vms/vm-fedora20-i386-serial.qcow2 2291 qemu64' '/kvm/vms/vm-fedora20-amd64-serial.qcow2 2292 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_upgrade_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo yum -y update" \
    "sudo yum -y install patch tar mariadb-server libtool-ltdl unixODBC Judy" \
    "sudo systemctl enable mariadb.service" \
    "sudo systemctl start mariadb.service" \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ; \
done

```

VMs for MariaDB upgrade testing (MariaDB repo)
----------------------------------------------

 
```
for i in '/kvm/vms/vm-fedora20-amd64-serial.qcow2 2292 qemu64' '/kvm/vms/vm-fedora20-i386-serial.qcow2 2291 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_upgrade2_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB-${2}.repo buildbot@localhost:/tmp/MariaDB.repo" \
    'sudo rpm --verbose --import https://yum.mariadb.org/RPM-GPG-KEY-MariaDB' \
    'sudo mv -vi /tmp/MariaDB.repo /etc/yum.repos.d/' \
    'sudo yum -y remove mysql-libs' \
    'sudo yum -y install MariaDB-server MariaDB-client MariaDB-test libtool-ltdl unixODBC Judy' \
    'sudo yum -y install cronie cronie-anacron crontabs.noarch patch tar' \
    'sudo /etc/init.d/mysql start' \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/yum.repos.d/MariaDB.repo' \
    'sudo yum -y update' \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/MariaDB.local.repo buildbot@localhost:/tmp/" \
    'sudo mv -vi /tmp/MariaDB.local.repo /etc/yum.repos.d/'; \
done

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-fedora-20/>

Buildbot Setup for Virtual Machines - Red Hat
==============================================

   This category contains articles documenting how the MariaDB Red Hat-based buildbot build and test VMs were created.

  

| Title | Description |
| --- | --- |
|  [Buildbot Setup for Virtual Machines - Fedora 20](../buildbot-setup-for-virtual-machines-fedora-20/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora20-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 19](../buildbot-setup-for-virtual-machines-fedora-19/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora19-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 18](../buildbot-setup-for-virtual-machines-fedora-18/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora18-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 17](../buildbot-setup-for-virtual-machines-fedora-17/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora17-i386-ser  |
|  [Buildbot Setup for Virtual Machines - Fedora 16](../buildbot-setup-for-virtual-machines-fedora-16/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-fedora16-i386-ser  |
|  [Buildbot Setup for Virtual Machines - CentOS 6.2](../buildbot-setup-for-virtual-machines-centos-62/index) |  Base install qemu-img create -f qcow2 /kvm/vms/vm-centos6-amd64-ser  |
|  [Buildbot Setup for Virtual Machines - Red Hat 6 x86](../buildbot-setup-for-virtual-machines-red-hat-6-x86/index) |  The following steps were used to create a Red Hat 6 x86 buildslave. Initial Setup cd vms q  |
|  [Buildbot Setup for Virtual Machines - CentOS 5 i386](../buildbot-setup-for-virtual-machines-centos-5-i386/index) |  Base install cd /kvm qemu-img create -f qcow2 vms/vm-centos5-i386-ba  |
|  [Buildbot Setup for Virtual Machines - Centos 5 amd64](../buildbot-setup-for-virtual-machines-centos-5-amd64/index) |  Base install cd /kvm wget http://ftp.klid.dk/ftp/centos/5.3/isos/x86  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-red-hat/>

Buildbot Setup for Virtual Machines - Debian 7 "wheezy"
=======================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-wheezy-amd64-serial.qcow2 10G
qemu-img create -f qcow2 /kvm/vms/vm-wheezy-i386-serial.qcow2 10G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 1024 -hda /kvm/vms/vm-wheezy-amd64-serial.qcow2 -cdrom /kvm/iso/debian-testing-amd64-CD-1.iso -redir tcp:2269::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user
kvm -m 1024 -hda /kvm/vms/vm-wheezy-i386-serial.qcow2  -cdrom /kvm/iso/debian-testing-i386-CD-1.iso  -redir tcp:2270::22 -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote-host} localhost

```

Replace ${remote-host} with the host the vm is running on.

 **Note:** When you activate the install, vncviewer may disconnect with a complaint about the rect being too large. This is fine. Debian has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Set the hostname to debian7-wheezy-amd64 or debian7-wheezy-i386
* When partitioning disks, choose "Guided - use entire disk" (we do not want LVM)
	+ Partitioning Scheme: All files one partition
* No additional CDs
* Set up network mirror
* Software Selection Screen
	+ Uncheck "Debian desktop environment"
	+ Uncheck "Print server"
	+ Keep "SSH server" and "Standard system utilities"

 When the install is finished the installer will attempt to reboot and then fail. This is OK, just kill the kvm process on the host server.

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 1024 -hda /kvm/vms/vm-wheezy-amd64-serial.qcow2 -redir tcp:2269::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
kvm -m 1024 -hda /kvm/vms/vm-wheezy-i386-serial.qcow2 -redir tcp:2270::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

ssh -p 2269 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -p 2270 localhost
# edit /boot/grub/menu.lst and visudo, see below

ssh -t -p 2269 localhost "mkdir -v .ssh"
ssh -t -p 2270 localhost "mkdir -v .ssh"

scp -P 2269 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2270 /kvm/vms/authorized_keys localhost:.ssh/

echo $'Buildbot\n\n\n\n\ny' | ssh -p 2269 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'
echo $'Buildbot\n\n\n\n\ny' | ssh -p 2270 localhost 'chmod -vR go-rwx .ssh; sudo adduser --disabled-password buildbot; sudo addgroup buildbot sudo; sudo mkdir ~buildbot/.ssh; sudo cp -vi .ssh/authorized_keys ~buildbot/.ssh/; sudo chown -vR buildbot:buildbot ~buildbot/.ssh; sudo chmod -vR go-rwx ~buildbot/.ssh'

scp -P 2269 /kvm/vms/ttyS0.conf buildbot@localhost:
scp -P 2270 /kvm/vms/ttyS0.conf buildbot@localhost:

ssh -p 2269 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'
ssh -p 2270 buildbot@localhost 'sudo cp -vi ttyS0.conf /etc/init/; rm -v ttyS0.conf; sudo shutdown -h now'

```

Enabling passwordless sudo:

 
```
su -
vi /etc/apt/sources.list #comment out the deb cdrom line
apt-get update
apt-get install sudo vim tree
update-alternatives --config editor # select vim.basic
visudo # comment out existing %sudo line and add: %sudo ALL=NOPASSWD: ALL
usermod -a -G sudo ${username}

```

Editing /boot/grub/menu.lst:

 
```
vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

update-grub
# exit back to the host server

```

VMs for building .debs
----------------------

 
```
for i in '/kvm/vms/vm-wheezy-amd64-serial.qcow2 2269 qemu64' '/kvm/vms/vm-wheezy-i386-serial.qcow2 2270 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get -y build-dep mysql-server-5.5" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y devscripts hardening-wrapper fakeroot doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libpam0g-dev libreadline-gplv2-dev autoconf automake automake1.9 dpatch ghostscript-x libfontenc1 libjpeg62 libltdl-dev libltdl7 libmail-sendmail-perl libxfont1 lmodern texlive-latex-base-doc ttf-dejavu ttf-dejavu-extra libaio-dev xfonts-encodings xfonts-utils libxml2-dev unixodbc-dev" \
    "cd /usr/local/src;sudo tar zxf /dev/shm/boost_1_49_0.tar.gz;cd /usr/local/include/;sudo ln -vs ../src/boost_1_49_0/boost ." ; \
done


```

VMs for install testing.
------------------------

 See [Buildbot Setup for Virtual Machines - General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) for how to obtain `my.seed` and `sources.append`.

 
```
for i in '/kvm/vms/vm-wheezy-amd64-serial.qcow2 2269 qemu64' '/kvm/vms/vm-wheezy-i386-serial.qcow2 2270 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils unixodbc libxml2" \
    "= scp -P $2 /kvm/vms/my.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 2013-12-05 recreated the upgrade VMs, this time based off of the serial VM (which is better, maintenance-wise).

 
```
for i in '/kvm/vms/vm-wheezy-amd64-serial.qcow2 2269 qemu64' '/kvm/vms/vm-wheezy-i386-serial.qcow2 2270 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get update" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y patch libaio1 debconf-utils unixodbc libxml2" \
    "= scp -P $2 /kvm/vms/my.seed /kvm/vms/sources.append buildbot@localhost:/tmp/" \
    "sudo debconf-set-selections /tmp/my.seed" \
    "sudo sh -c 'cat /tmp/sources.append >> /etc/apt/sources.list'" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1 mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

This was how the original upgrade VMs were created:

 
```
for i in '/kvm/vms/vm-wheezy-amd64-install.qcow2 2269 qemu64' '/kvm/vms/vm-wheezy-i386-install.qcow2 2270 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/install/upgrade/')" \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1 mysql-server-5.5' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

  *The steps below are based on the Natty steps on [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index).*

 
```
for i in '/kvm/vms/vm-wheezy-amd64-serial.qcow2 2269 qemu64' '/kvm/vms/vm-wheezy-i386-serial.qcow2 2270 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "= scp -P $2 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/vms/mariadb-wheezy.list buildbot@localhost:/tmp/tmp.list" \
    'sudo mv -vi /tmp/tmp.list /etc/apt/sources.list.d/' \
    'sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1BB943DB' \
    'sudo apt-get update' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-server-5.5 mariadb-client mariadb-client-5.5 mariadb-test libmariadbclient-dev' \
    'sudo apt-get -f install' \
    'sudo mysqladmin -u root password "rootpass"' \
    'sudo /etc/init.d/mysql restart' \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    'sudo rm -v /etc/apt/sources.list.d/tmp.list' \
    'sudo apt-get update' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libaio1' \
    'sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each build host server to add the VMs to known\_hosts.

 
```
# wheezy-amd64
cp -avi /kvm/vms/vm-wheezy-amd64-install.qcow2 /kvm/vms/vm-wheezy-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-wheezy-amd64-test.qcow2 -redir tcp:2269::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2269 buildbot@localhost sudo shutdown -h now
rm -v /kvm/vms/vm-wheezy-amd64-test.qcow2

# wheezy-i386
cp -avi /kvm/vms/vm-wheezy-i386-install.qcow2 /kvm/vms/vm-wheezy-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-wheezy-i386-test.qcow2 -redir tcp:2270::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2270 buildbot@localhost sudo shutdown -h now
rm -v /kvm/vms/vm-wheezy-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-7-wheezy/>

Buildbot Setup for Virtual Machines - Debian 4 amd64
====================================================

    
```
cd /kvm/vms
qemu-img create -f qcow2 vm-debian4-amd64-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian4-amd64-serial.qcow2 -cdrom /kvm/debian-40r8-amd64-netinst.iso -redir 'tcp:2240::22' -boot d -smp 2 -cpu qemu64 -net nic,model=e1000 -net user

```

Serial console and account setup
--------------------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
kvm -m 2047 -hda /kvm/vms/vm-debian4-amd64-serial.qcow2 -cdrom /kvm/debian-40r8-amd64-netinst.iso -redir 'tcp:2240::22' -boot c -smp 2 -cpu qemu64 -net nic,model=e1000 -net user

su
apt-get install sudo openssh-server
VISUAL=vi visudo
# Add at the end:t %sudo ALL=NOPASSWD: ALL

# Add account <USER> to group sudo
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/getty -L ttyS0 19200 vt100

```

Add to /boot/grub/menu.lst:

 
```
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=3 serial console

```

also add in menu.lst to kernel line:

 
```
console=tty0 console=ttyS0,115200n8

# Add user buildbot, with disabled password. Add as sudo, and add ssh key.
sudo /usr/sbin/adduser --disabled-password buildbot
sudo /usr/sbin/adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Add all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

VM for build
------------

 
```
qemu-img create -b vm-debian4-amd64-serial.qcow2 -f qcow2 vm-debian4-amd64-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-amd64-build.qcow2 -cdrom /kvm/debian-40r8-amd64-netinst.iso -redir 'tcp:2240::22' -boot c -smp 2 -cpu qemu64 -net nic,model=e1000 -net user -nographic

sudo apt-get build-dep mysql-server-5.0
# Some latex packages fail to install because they complain that the
# source is more than 5 years old! I solved by setting back the clock a
# couple of years temporarily ...
sudo apt-get install devscripts doxygen texlive-latex-base gs lsb-release fakeroot libevent-dev libssl-dev zlib1g-dev libreadline5-dev

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-debian4-amd64-serial.qcow2 -f qcow2 vm-debian4-amd64-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-amd64-install.qcow2 -cdrom /kvm/debian-40r8-amd64-netinst.iso -redir 'tcp:2240::22' -boot c -smp 2 -cpu qemu64 -net nic,model=e1000 -net user -nographic

```

See the [General Principles](../buildbot-setup-for-virtual-machines-general-principles/index) article for how to make the '`my.seed`' file.

 
```
# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

VM for upgrade testing
----------------------

 
```
qemu-img create -b vm-debian4-amd64-install.qcow2 -f qcow2 vm-debian4-amd64-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian4-amd64-upgrade.qcow2 -cdrom /kvm/debian-40r8-amd64-netinst.iso -redir 'tcp:2240::22' -boot c -smp 2 -cpu qemu64 -net nic,model=e1000 -net user -nographic

sudo apt-get install mysql-server-5.0
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-4-amd64/>

Buildbot Setup for Virtual Machines - Debian 6 i386
===================================================

    Base Install
------------

 
```
cd /kvm/vms
qemu-img create -f qcow2 vm-debian6-i386-serial.qcow2 8G
kvm -m 2047 -hda /kvm/vms/vm-debian6-i386-serial.qcow2 -cdrom /kvm/debian-6a1-i386-netinst.iso -redir 'tcp:2245::22' -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user

```

Serial console and account setup
--------------------------------

 From base install, setup for serial port, and setup accounts for passwordless ssh login and sudo:

 
```
kvm -m 2047 -hda /kvm/vms/vm-debian6-i386-serial.qcow2 -redir 'tcp:2245::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user

su
apt-get install sudo openssh-server
visudo
# Add: %sudo ALL=NOPASSWD: ALL
# add user account to group sudo `addgroup <USER> sudo`.
# Copy in public ssh key.

# Add in /etc/inittab:
S0:2345:respawn:/sbin/getty -L ttyS0 19200 vt100

```

Editing /etc/default/grub:

 
```
sudo vi /etc/default/grub

# Add/edit these entries:
    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL="serial"
    GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"

sudo update-grub

```

Add user buildbot, with disabled password. Add as sudo, and add ssh key.

 
```
sudo adduser --disabled-password buildbot
sudo adduser buildbot sudo
sudo su - buildbot
mkdir .ssh
# Add all necessary keys.
cat >.ssh/authorized_keys
chmod -R go-rwx .ssh

```

VM for building .deb
--------------------

 
```
qemu-img create -b vm-debian6-i386-serial.qcow2 -f qcow2 vm-debian6-i386-build.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-i386-build.qcow2 -redir 'tcp:2245::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get build-dep mysql-server-5.1
sudo apt-get install devscripts hardening-wrapper doxygen texlive-latex-base ghostscript libevent-dev libssl-dev zlib1g-dev libreadline-dev

```

VM for install testing
----------------------

 
```
qemu-img create -b vm-debian6-i386-serial.qcow2 -f qcow2 vm-debian6-i386-install.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-i386-install.qcow2 -redir 'tcp:2245::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

```

See above for how to obtain my.seed

 
```
# No packages mostly!
sudo apt-get install debconf-utils

cat >>/etc/apt/sources.list <<END
deb file:///home/buildbot/buildbot/debs binary/
deb-src file:///home/buildbot/buildbot/debs source/
END

sudo debconf-set-selections /tmp/my.seed

```

VM for upgrade testing
----------------------

 
```
qemu-img create -b vm-debian6-i386-install.qcow2 -f qcow2 vm-debian6-i386-upgrade.qcow2
kvm -m 2047 -hda /kvm/vms/vm-debian6-i386-upgrade.qcow2 -redir 'tcp:2245::22' -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic

sudo apt-get install mysql-server-5.1
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-debian-6-i386/>

Installing the Boost library needed for the OQGraph storage engine
==================================================================

    The OQGraph storage engine needs a newer version of Boost that what is available on (most) distributions. The version installed is 1.42.0, available from <http://www.boost.org/>.

 The boost library is installed in all the builder virtual machine images with the following single command:

 
```
for i in "vm-hardy-amd64-build qemu64" "vm-hardy-i386-build qemu32,-nx" \
        "vm-intrepid-amd64-build qemu64" "vm-intrepid-i386-build qemu32,-nx" \
        "vm-karmic-amd64-build qemu64" "vm-karmic-i386-build qemu32,-nx" \
        "vm-jaunty-amd64-build qemu64" "vm-jaunty-i386-deb-build qemu32,-nx" \
        "vm-lucid-amd64-build qemu64" "vm-lucid-i386-build qemu32,-nx" \
        "vm-maverick-amd64-build qemu64" "vm-maverick-i386-build qemu32,-nx" \
        "vm-natty-amd64-build qemu64" "vm-natty-i386-build qemu64" \
        "vm-oneiric-amd64-build qemu64" "vm-oneiric-i386-build qemu64" \
        "vm-debian5-amd64-build qemu64" "vm-debian5-i386-build qemu32,-nx" \
        "vm-debian4-amd64-build qemu64 --netdev=e1000" "vm-debian4-i386-build qemu32,-nx --netdev=e1000" \
        "vm-centos5-i386-build qemu32,-nx" "vm-centos5-amd64-build qemu64" \
        "vm-hardy-amd64-build qemu64" "vm-hardy-i386-build qemu32,-nx" \
        "vm-jaunty-i386-deb-tarbake qemu32,-nx" ; do \
  set $i; \
  runvm -m 512 --smp=1 --port=2200 --user=buildbot --cpu=$2 $3 $1.qcow2 \
    "= scp -P 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no /kvm/boost_1_42_0.tar.gz buildbot@localhost:/dev/shm/" \
    "sudo mkdir -p /usr/local/src /usr/local/include" \
    "cd /usr/local/src && sudo tar zxf /dev/shm/boost_1_42_0.tar.gz" \
    "cd /usr/local/include && sudo ln -s ../src/boost_1_42_0/boost ." ; \
done

```

Upgrade Boost to 1.49
---------------------

 To upgrade boost on the VMs to 1.49 I performed the following steps:

 
*I initially tried to upgrade the VMs using a script like the one at the top of the page which was used to install boost 1.42, but I ran into issues with getting it to work on all of the VMs (it worked on some, but not on others). So I ended up using the steps below.*

 
1. Copy the VM (keeping the original as a backup, in case something goes wrong):
```
oldvm="vm-debian6-i386-build.qcow2"
newvm="vm-debian6-i386-build.upd.qcow2"
cp -avi ${oldvm} ${newvm}

```
2. Start the VM:
```
kvm -m 1024 -hda /kvm/vms/${newvm} -redir 'tcp:22775::22' -boot c   -smp 1   -cpu qemu64   -net nic,model=virtio   -net user   -nographic

```
3. Copy the boost tar.gz file over to the VM:
```
scp -i /kvm/vms/ssh-keys/id_dsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 22775 /kvm/boost_1_49_0.tar.gz buildbot@localhost:/dev/shm/

```
4. ssh into the VM:
```
ssh -i /kvm/vms/ssh-keys/id_dsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22775 buildbot@localhost

```
5. once inside the VM, perform the following steps:
```
cd /usr/local/src
sudo tar zxf /dev/shm/boost_1_49_0.tar.gz 
cd /usr/local/include/
sudo rm boost
sudo ln -s ../src/boost_1_49_0/boost .
sudo /sbin/shutdown -h now

```

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-the-boost-library-needed-for-the-oqgraph-storage-engine/>

Buildbot Setup for Virtual Machines - Additional Steps
=======================================================

   This section documents some additions that have been made after the initial setup.

  

| Title | Description |
| --- | --- |
|  [Installing the Boost library needed for the OQGraph storage engine](../installing-the-boost-library-needed-for-the-oqgraph-storage-engine/index) |  The OQGraph storage engine needs a newer version of Boost that what is avai...  |
|  [Installing VM images for testing .deb upgrade between versions](../installing-vm-images-for-testing-deb-upgrade-between-versions/index) |  This step creates virtual machine images used to do an important additional...  |
|  [Install Cassandra on Fulltest VMs](../install-cassandra-on-fulltest-vms/index) |  CassandraSE is no longer actively being developed and has been removed in M...  |
|  [Install cmake on build VMs](../install-cmake-on-build-vms/index) |  MariaDB 5.5 Requires cmake. Install cmake on all -build VMs (and other Unix...  |
|  [Installing correct libraries for PAM and readline](../installing-correct-libraries-for-pam-and-readline/index) |  Some additional/alternative libraries needs to be installed to handle readl...  |
|  [Resizing a Virtual Machine Image](../resizing-a-virtual-machine-image/index) |  Some KVM images end up not having enough space on them. In such cases, it i...  |
|  [Update Debian 4 mirrors for Buildbot VMs](../update-debian-4-mirrors-for-buildbot-vms/index) |  Debian 4 has become so old that the apt repository has been moved out of th...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-additional-steps/>

Installing correct libraries for PAM and readline
=================================================

    Some additional/alternative libraries needs to be installed to handle readline and PAM correctly.

 The newer libreadline is GPLv3 and so not compatible with the MariaDB/MySQL GPLv2 license. The PAM libraries are needed for the PAM plugin.

 On the Centos and RHEL -build VMs, install the pam-devel package:

 
```
    sudo yum install pam-devel

```

On all the Debian/Ubuntu -build virtual machines, install libpam0g-dev:

 
```
    sudo apt-get install libpam0g-dev

```

On debian6/maverick/natty, install libreadline5-dev (replacing any libreadline6-dev already there):

 
```
    sudo apt-get install libreadline5-dev

```

On oneiric (and any newer, eg. Debian 7 or Ubuntu 12.04), the package is called libreadline-gplv2-dev:

 
```
    sudo apt-get install libreadline-gplv2-dev

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-correct-libraries-for-pam-and-readline/>

Install cmake on build VMs
==========================

    [MariaDB 5.5](../what-is-mariadb-55/index) Requires cmake. Install cmake on all -build VMs (and other Unix-like machines) with:

 
```
wget http://www.cmake.org/files/v2.8/cmake-2.8.8.tar.gz
tar -zxvf cmake-2.8.8.tar.gz
cd cmake-2.8.8;./configure
make
sudo make install  

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/install-cmake-on-build-vms/>

Installing VM images for testing .deb upgrade between versions
==============================================================

    This step creates virtual machine images used to do an important additional upgrade test for .debs. Each virtual machine is pre-installed with an older version of MariaDB, and the test tries upgrading this version to the newly build one (to check that dependencies etc. work out correctly).

 This step may not be easily possible to replicate exactly for new or updated images. For example, when we add a new platform/distro, we will not have the same old version of MariaDB available for installation on the new planform. Or if needing to re-create an image in the future, the original old .debs used before may no longer be available. However, this is not a big problem, as we can just use whatever version of MariaDB is available. In fact, while we cannot reasonably test every possible upgrade combination between MariaDB versions, it is still useful to test upgrades from different versions on different platforms, to increase coverage a bit.

 The bulk of the images were installed with the following two loops, using packages from the OurDelta repository for [MariaDB 5.1.42](https://mariadb.com/kb/en/mariadb-5142-release-notes/), which was the one available from there at the time of installation.

 
```
for i in "vm-hardy-amd64-install qemu64 hardy" "vm-hardy-i386-install qemu32,-nx hardy" \
          "vm-intrepid-amd64-install qemu64 intrepid" "vm-intrepid-i386-install qemu32,-nx intrepid" \
          "vm-karmic-amd64-install qemu64 karmic" "vm-karmic-i386-install qemu32,-nx karmic" \
          "vm-jaunty-amd64-install qemu64 jaunty" "vm-jaunty-i386-deb-install qemu32,-nx jaunty" \
          "vm-debian5-amd64-install qemu64 lenny" "vm-debian5-i386-install qemu32,-nx lenny" ; do \
  set $i; \
  runvm -b  $1.qcow2 -m 512 --smp=1 --port=2200 --user=buildbot --cpu=$2 $(echo $1 | sed -e 's/-install/-upgrade2/').qcow2 \
    "wget -O- http://ourdelta.org/deb/ourdelta.gpg | sudo apt-key add -" \
    "sudo sh -c \"echo 'deb http://mirror.ourdelta.org/deb $3 mariadb-ourdelta' > /etc/apt/sources.list.d/ourdelta.list\"" \
    "sudo apt-get update || true" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-test libmariadbclient-dev || true" \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    "sudo rm /etc/apt/sources.list.d/ourdelta.list" \
    "sudo apt-get update || true" \
    "sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y || true" ; \
done

```


```
for i in "vm-debian4-amd64-install qemu64 etch /kvm/debian-40r8-amd64-netinst.iso" "vm-debian4-i386-install qemu32,-nx etch /kvm/debian-40r8-i386-netinst.iso" ; do \
  set $i; \
  runvm -b  $1.qcow2 -m 512 --smp=1 --port=2200 --user=buildbot --cpu=$2 --netdev=e1000 --kvm=-cdrom --kvm=$4 $(echo $1 | sed -e 's/-install/-upgrade2/').qcow2 \
    "wget -O- http://ourdelta.org/deb/ourdelta.gpg | sudo apt-key add -" \
    "sudo sh -c \"echo 'deb http://mirror.ourdelta.org/deb $3 mariadb-ourdelta' > /etc/apt/sources.list.d/ourdelta.list\"" \
    "sudo apt-get update || true" \
    "sudo sh -c 'DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server mariadb-test libmariadbclient-dev' || true" \
    'mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' \
    "sudo rm /etc/apt/sources.list.d/ourdelta.list" \
    "sudo apt-get update || true" \
    "sudo sh -c 'DEBIAN_FRONTEND=noninteractive apt-get upgrade -y' || true" ; \
done

```

The Ubuntu 10.04 "lucid" images were installed manually (as no packages for lucid were available from OurDelta at the time of installation):

 Create and boot 64-bit lucid upgrade image:

 
```
qemu-img create -b vm-lucid-amd64-install.qcow2 -f qcow2 vm-lucid-amd64-upgrade2.qcow2 
kvm -m 512 -hda vm-lucid-amd64-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic 

```

Create directory inside the image:

 
```
mkdir buildbot

```

Copy in packages to be installed from outside:

 
```
scp -P 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r /archive/pack/mariadb-5.1-knielsen/build-277/kvm-deb-lucid-amd64/debs buildbot@localhost:buildbot/

```

Install the MariaDB packages, remove package dir, and upgrade to latest security fixes:

 
```
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
rm -Rf buildbot
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

Now the same, but for 32-bit lucid:

 
```
qemu-img create -b vm-lucid-i386-install.qcow2 -f qcow2 vm-lucid-i386-upgrade2.qcow2 
kvm -m 512 -hda vm-lucid-i386-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

```

Create directory inside the image:

 
```
mkdir buildbot

```

Copy in packages to be installed from outside:

 
```
scp -P 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r /archive/pack/mariadb-5.1-knielsen/build-277/kvm-deb-lucid-x86/debs buildbot@localhost:buildbot/

```

Install the MariaDB packages, remove package dir, and upgrade to latest security fixes:

 
```
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
rm -Rf buildbot
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

The Ubuntu 10.10 "maverick" images were likewise installed manually:

 Create and boot 64-bit maverick upgrade image:

 
```
qemu-img create -b vm-maverick-amd64-install.qcow2 -f qcow2 vm-maverick-amd64-upgrade2.qcow2
kvm -m 512 -hda vm-maverick-amd64-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic

ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost mkdir buildbot
scp -P 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r /archive/pack/mariadb-5.1-knielsen/build-619/kvm-deb-maverick-amd64/debs buildbot@localhost:buildbot/
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
rm -Rf buildbot
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

Same for 32-bit maverick:

 
```
qemu-img create -b vm-maverick-i386-install.qcow2 -f qcow2 vm-maverick-i386-upgrade2.qcow2
kvm -m 512 -hda vm-maverick-i386-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu32,-nx -net nic,model=virtio -net user -nographic

ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost mkdir buildbot
scp -P 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -r /archive/pack/mariadb-5.1-knielsen/build-619/kvm-deb-maverick-x86/debs buildbot@localhost:buildbot/
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
rm -Rf buildbot
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

For Ubuntu 11.04 "natty", mariadb packages were installed from the repository for the previous version.

 64-bit Ubuntu natty:

 
```
qemu-img create -b vm-natty-amd64-install.qcow2 -f qcow2 vm-natty-amd64-upgrade2.qcow2
kvm -m 512 -hda vm-natty-amd64-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.1/ubuntu maverick main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.1/ubuntu maverick main

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

32-bit Ubuntu natty:

 
```
qemu-img create -b vm-natty-i386-install.qcow2 -f qcow2 vm-natty-i386-upgrade2.qcow2
kvm -m 512 -hda vm-natty-i386-upgrade2.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=virtio -net user -nographic
ssh -p 2200 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no buildbot@localhost

sudo sh -c 'cat > /etc/apt/sources.list.d/tmp.list'
deb http://ftp.osuosl.org/pub/mariadb/repo/5.1/ubuntu maverick main
deb-src http://ftp.osuosl.org/pub/mariadb/repo/5.1/ubuntu maverick main

sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --allow-unauthenticated mariadb-server mariadb-test libmariadbclient-dev
mysql -uroot -prootpass -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"
sudo rm /etc/apt/sources.list.d/tmp.list
sudo apt-get update
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y

```

For Ubuntu 11.10 "oneiric". The steps performed are listed at: [Buildbot Setup for Virtual Machines - Ubuntu 11.10 "oneiric"](../buildbot-setup-for-virtual-machines-ubuntu-1110-oneiric/index) (in the VMs for Upgrade Testing section)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/installing-vm-images-for-testing-deb-upgrade-between-versions/>

Resizing a Virtual Machine Image
================================

    Some KVM images end up not having enough space on them. In such cases, it is preferable to increase the size of the VM rather than to just delete an image and rebuild it from scratch. The steps outlined below document what was done to increase the size of the Red Hat 5 x86 VM and should be able to be easily adapted to other VMs, should they need the same treatment in the future.

 1. Make a copy of the VM to work on (we don't want to change the original):

 
```
cp -avi vm-rhel5-x86-build.qcow2 vm-rhel5-x86-build-new.qcow2

```

2. Using the `qemu-img` command, resize the image:

 
```
qemu-img info vm-rhel5-x86-build-new.qcow2
qemu-img resize vm-rhel5-x86-build-new.qcow2 +10G
qemu-img info vm-rhel5-x86-build-new.qcow2
rsync -avP vm-rhel5-x86-build-new.qcow2 terrier:/kvm/vms/

```


 Not all versions of `qemu-img` can resize VMs.

  3. Boot the newly resized image with gparted:

 
```
vm=vm-rhel5-x86-build-new.qcow2
kvm -m 2048 -hda /kvm/vms/${vm} -cdrom /kvm/iso/gparted-live-0.14.1-6-i486.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:22666-:22

```

4. Connect to the VM using VNC from your local machine:

 
```
vncviewer -via <vmhost> localhost

```


 Midway through booting you'll have to reconnect

  5. Use gparted to either expand the existing primary partition or, especially on VMs with LVM, add a new partition (since GParted can't change LVM partitions). Exit when finished and shutdown the VM.

 6. Boot the VM again, this time without a VNC server:

 
```
kvm -m 2048 -hda /kvm/vms/${vm} -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:22666-:22 -nographic

```

7. login to the VM:

 
```
ssh -t -p 22666 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/buildbot.id_dsa buildbot@localhost

```

8. if expanded an existing partition: verify the new size

 9. else if you created a new partition:
	* mount the new partition to tmp location
	```
	sudo mount /dev/hda3 /mnt
	
	```
	* rsync contents of /home/ to the new partition
	```
	sudo rsync -avP /home/ /mnt/
	
	```
	* edit fstab to mount new partition to /home
	```
	sudo vi /etc/fstab
	
	```
	* mv `/home` to `/home-old`, create `/home` dir, mount `/home`
	```
	sudo mv -vi /home /home-old;sudo mkdir -v /home;sudo mount /home
	
	```
	* (optional) unmount `/mnt`
	```
	sudo umount /mnt
	
	```
	* reboot and verify that things look good
	```
	sudo /sbin/shutdown -h now
	
	```
	* if things do look good (new drive mounted OK, accounts work, etc...), delete `/home-old`

 10. Move the old VM to `-old` and the `-new` VM to what the old VM used to be named

 
```
sudo mv -vi /kvm/vms/vm-rhel5-x86-build.qcow2 vm-rhel5-x86-build-old.qcow2; sudo mv -vi /kvm/vms/vm-rhel5-x86-build-new.qcow2 /kvm/vms/vm-rhel5-x86-build.qcow2

```

11. on other VM hosts, make a copy of the old file then rsync over the updated files (the copy helps speed up the rsync):

 
```
sudo cp -avi /kvm/vms/vm-rhel5-x86-build.qcow2 /kvm/vms/vm-rhel5-x86-build-old.qcow2
sudo rsync -avP terrier.askmonty.org::kvm/vms/vm-rhel5-x86-build* /kvm/vms/

```

12. Test the new VM with a build to make sure it works

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/resizing-a-virtual-machine-image/>

Update Debian 4 mirrors for Buildbot VMs
========================================

    Debian 4 has become so old that the apt repository has been moved out of the main Debian 4 mirror servers, and into the archive of old versions. This needs to be fixed by pointing the Debian 4 images to a different mirror:

 64-bit:

 
```
kvm -m 512 -hda vm-debian4-amd64-install.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=e1000 -net user -nographic

sudo vi /etc/apt/sources.list
# replace http://ftp.dk.debian.org/debian/ with http://ftp.de.debian.org/archive/debian/

```

32-bit:

 
```
kvm -m 512 -hda vm-debian4-i386-install.qcow2 -redir 'tcp:2200::22' -boot c -smp 1 -cpu qemu64 -net nic,model=e1000 -net user -nographic

sudo vi /etc/apt/sources.list
# replace http://ftp.dk.debian.org/debian/ with http://ftp.de.debian.org/archive/debian/

```

After that, it is necessary to re-do from scratch the -update and -update2 debian4 images (as these are built on top of the -install images).

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/update-debian-4-mirrors-for-buildbot-vms/>

Buildbot Setup for Virtual Machines - FreeBSD 9.2
=================================================

    Base install
------------

 
```
qemu-img create -f qcow2 /kvm/vms/vm-freebsd92-amd64-serial.qcow2 15G
qemu-img create -f qcow2 /kvm/vms/vm-freebsd92-i386-serial.qcow2 15G

```

Start each VM booting from the server install iso one at a time and perform the following install steps:

 
```
kvm -m 2048 -hda /kvm/vms/vm-freebsd92-amd64-serial.qcow2 -cdrom /kvm/iso/freebsd/9.2/FreeBSD-9.2-RELEASE-amd64-dvd1.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2283-:22
kvm -m 2048 -hda /kvm/vms/vm-freebsd92-i386-serial.qcow2 -cdrom /kvm/iso/freebsd/9.2/FreeBSD-9.2-RELEASE-i386-dvd1.iso -boot d -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2284-:22

```

Once running you can connect to the VNC server from your local host with:

 
```
vncviewer -via ${remote_host} localhost

```

Replace `${remote\_host}` with the host the vm is running on.

 **Note:** When you activate the install, vncviewer will disconnect after a bit with a complaint about the rect being too large. This is fine. The installer has just resized the vnc screen. Simply reconnect.

 Install, picking default options mostly, with the following notes:

 * Keymap Selection: Do not set non-default key mapping
* Hostname: to freebsd-92-amd64 or freebsd-92-i386
* Distribution Select: deselect "games", leave "ports" selected
* Partitioning: Guided and use the entire disk
	+ Accept the default partitioning (Finish then Commit)
* Archive Extraction: *...wait while installer installs the OS...*
* Network Configuration: choose `vtnet0`
	+ configure ipv4 w/ DHCP
	+ do not configure ipv6
* System Configuration: leave sshd selected, don't select the others
* Dumpdev Configuration: do not enable crash dumps
* add a buildbot user
	+ add user to 'wheel' group
* Final Configuration: Apply configuration and exit
* Manual Configuration: yes to opening a shell
	+ `echo 'console="comconsole"' >> /boot/loader.conf`
	+ Edit /etc/ttys and change off to on and dialup to vt100 for the ttyu0 entry.
	+ `shutdown -p now`

 Now that the VM is installed, it's time to configure it. If you have the memory you can do the following simultaneously:

 
```
kvm -m 2048 -hda /kvm/vms/vm-freebsd92-amd64-serial.qcow2 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2283-:22 -nographic
kvm -m 2048 -hda /kvm/vms/vm-freebsd92-i386-serial.qcow2 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:2284-:22 -nographic

ssh -p 2283 localhost
ssh -p 2284 localhost

su -

cd /usr/ports/security/sudo; make install clean # accept defaults
visudo # uncomment the '# %wheel ALL=(ALL) NOPASSWD: ALL' line
exit

cd /usr/ports/ports-mgmt/portmaster; sudo make install clean # select both autocomplete options

ssh hasky.askmonty.org
exit
sudo su buildbot -
ssh hasky.askmonty.org
exit
exit
exit

scp -P 2283 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2283 /kvm/vms/authorized_keys buildbot@localhost:.ssh/

scp -P 2284 /kvm/vms/authorized_keys localhost:.ssh/
scp -P 2284 /kvm/vms/authorized_keys buildbot@localhost:.ssh/

ssh -p 2283 localhost
ssh -p 2284 localhost

sudo portsnap fetch extract
sudo portsnap fetch update
sudo portmaster -Da

sudo shutdown -p now


```

VMs for building BSD bintars
----------------------------

 
```
for i in '/kvm/vms/vm-freebsd92-amd64-serial.qcow2 2283 qemu64' '/kvm/vms/vm-freebsd92-i386-serial.qcow2 2284 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/build/')" \
    "cd /usr/ports/devel/libevent;     sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/boost-all;    sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/cmake;        sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/thrift/;      sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/bzr/;         sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/bison/;       sudo make install clean BATCH=yes" \
    "cd /usr/ports/databases/unixODBC; sudo make install clean BATCH=yes" \
    "cd /usr/ports/devel/doxygen;      sudo make install clean BATCH=yes"; \
done

```

VMs for install testing.
------------------------

 
```
qemu-img create -b /kvm/vms/vm-freebsd92-amd64-serial.qcow2 -f qcow2 /kvm/vms/vm-freebsd92-amd64-install.qcow2
qemu-img create -b /kvm/vms/vm-freebsd92-i386-serial.qcow2 -f qcow2 /kvm/vms/vm-freebsd92-i386-install.qcow2

for i in '/kvm/vms/vm-freebsd92-amd64-serial.qcow2 2283 qemu64' '/kvm/vms/vm-freebsd92-i386-serial.qcow2 2284 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/install/')" \
    "sudo portsnap cron update"; \
done

```

VMs for MySQL upgrade testing
-----------------------------

 
```
for i in '/kvm/vms/vm-freebsd92-amd64-serial.qcow2 2283 qemu64' '/kvm/vms/vm-freebsd92-i386-serial.qcow2 2284 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade/')" \
    "cd /usr/ports/databases/mysql55-server;    sudo make install clean BATCH=yes" \
    "sudo /usr/local/etc/rc.d/mysql-server onestart" \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"' ;\
done

```

VMs for MariaDB upgrade testing
-------------------------------

 
```
for i in '/kvm/vms/vm-freebsd92-amd64-serial.qcow2 2283 qemu64' '/kvm/vms/vm-freebsd92-i386-serial.qcow2 2284 qemu64' ; do \
  set $i; \
  runvm --user=buildbot --logfile=kernel_$2.log --base-image=$1 --port=$2 --cpu=$3 "$(echo $1 | sed -e 's/serial/upgrade2/')" \
    "cd /usr/ports/databases/mariadb55-server;    sudo make install clean BATCH=yes" \
    "sudo /usr/local/etc/rc.d/mysql-server onestart" \
    'mysql -uroot -e "create database mytest; use mytest; create table t(a int primary key); insert into t values (1); select * from t"'; \
done

```

Add Key to known\_hosts
-----------------------

 Do the following on each kvm host server (terrier, terrier2, i7, etc...) to add the VMs to known\_hosts.

 
```
# freebsd92-amd64
cp -avi /kvm/vms/vm-freebsd92-amd64-install.qcow2 /kvm/vms/vm-freebsd92-amd64-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-freebsd92-amd64-test.qcow2 -redir tcp:2283::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2283 buildbot@localhost sudo shutdown -p now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-freebsd92-amd64-test.qcow2

# freebsd92-i386
cp -avi /kvm/vms/vm-freebsd92-i386-install.qcow2 /kvm/vms/vm-freebsd92-i386-test.qcow2
kvm -m 1024 -hda /kvm/vms/vm-freebsd92-i386-test.qcow2 -redir tcp:2284::22 -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user -nographic
sudo su - buildbot
ssh -p 2284 buildbot@localhost sudo shutdown -p now
# answer "yes" when prompted
exit # the buildbot user
rm -v /kvm/vms/vm-freebsd92-i386-test.qcow2

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/buildbot-setup-for-virtual-machines-freebsd-92/>

MariaDB Server Roadmap
======================

    
This page talks in general about the MariaDB Server roadmap, and how it is formed.  
The roadmap it describes is located in our [JIRA](../jira/index) issue tracker: **[jira.mariadb.org](http://jira.mariadb.org)**

  MariaDB was designed as a drop-in replacement of MySQL with more features, new storage engines, fewer bugs, and better performance. We aim to make upgrading from MySQL to MariaDB extremely easy.

 The roadmap for MariaDB Server is formed by its engineers and product managers, with input from the community.

 MariaDB Server developers work with several [storage engine](../storage-engines/index) vendors and developers to get the best storage engines into MariaDB Server.

 The collected information is then turned into specific tasks which are then prioritized and added to the roadmap in the [JIRA](../jira/index) issue tracker at **[jira.mariadb.org](https://jira.mariadb.org)**

 Goals and Quality Standards
---------------------------

 The primary goal of MariaDB Server is for it to be a practical database developed in the direction users and developers want it to be developed. Each feature should ideally be developed by or for users who want to test and put the feature into production ASAP — this helps ensure we don't implement features no one wants or needs.

 We are also putting a lot of effort into speeding up MariaDB Server, and to keep it stable and easy to use!

 The MariaDB Server source tree is maintained by MariaDB the company and its developers. They are the primary contributors to the MariaDB Server project and the ones who are ultimately responsible for the quality of the code.

 MariaDB Server 5.1, MariaDB Server 5.2, and MariaDB Server 5.3 were built off of [MySQL 5.1](../mariadb-versus-mysql/index).

 MariaDB Server 5.5 was a combination of MariaDB Server 5.3 and MySQL 5.5.

 MariaDB Server 10.0, and later build off of the previous MariaDB Server releases with backported features from MySQL and entirely new features not found anywhere else.

 Short descriptions of the various MariaDB Server releases and their main new features can be found on the [MariaDB Server Releases](../mariadb-releases/index) page. 

 See Also
--------

 * [Plans for MariaDB 11.2](../plans-for-mariadb-11-2/index)
* [Plans for MariaDB 11.1](../plans-for-mariadb-11-1/index)
* [Plans for MariaDB 11.0](../plans-for-mariadb-11-0/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-server-roadmap/>

Plans for MariaDB 11.3
======================

    [MariaDB 11.3](../what-is-mariadb-11-3/index) is an upcoming major development release.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2811.3%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 11.3. It shows all tasks with the **Fix-Version** being 11.3. Not all these tasks will really end up in 11.3 but tasks with the "red" priorities have a much higher chance of being done in time for 11.3. Practically, you can think of these tasks as "features that **will** be in 11.3". Tasks with the "green" priorities probably won't be in 11.3. Think of them as "bonus features that would be **nice to have** in 11.3".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 11.3](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.3)%20ORDER%20BY%20priority%20DESC)
* [11.3 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.3)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 11.3?](../what-is-mariadb-11-3/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-11-3/>

Plans for MariaDB 11.2
======================

    [MariaDB 11.2](../what-is-mariadb-11-2/index) is a current major development release.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2811.2%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 11.2. It shows all tasks with the **Fix-Version** being 11.2. Not all these tasks will really end up in 11.2 but tasks with the "red" priorities have a much higher chance of being done in time for 11.2. Practically, you can think of these tasks as "features that **will** be in 11.2". Tasks with the "green" priorities probably won't be in 11.2. Think of them as "bonus features that would be **nice to have** in 11.2".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 11.2](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.2)%20ORDER%20BY%20priority%20DESC)
* [11.2 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.2)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 11.2?](../what-is-mariadb-11-2/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-11-2/>

Plans for MariaDB 11.1
======================

    [MariaDB 11.1](../what-is-mariadb-11-1/index) is a current major development release.

 JIRA
----

 We manage our development plans in JIRA, so the definitive list will be there. [This search](https://jira.mariadb.org/issues/?jql=project+%3D+MDEV+AND+issuetype+%3D+Task+AND+fixVersion+in+%2811.1%29+ORDER+BY+priority+DESC) shows what we **currently** plan for 11.1. It shows all tasks with the **Fix-Version** being 11.1. Not all these tasks will really end up in 11.1 but tasks with the "red" priorities have a much higher chance of being done in time for 11.1. Practically, you can think of these tasks as "features that **will** be in 11.1". Tasks with the "green" priorities probably won't be in 11.1. Think of them as "bonus features that would be **nice to have** in 11.1".

 Contributing
------------

 If you want to be part of developing any of these features, see [Contributing to the MariaDB Project](../contributing-to-the-mariadb-project/index). You can also add new features to this list or to [JIRA](../jira-project-planning-and-tracking/index).

 See Also
--------

 * [Current tasks for 11.1](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.1)%20ORDER%20BY%20priority%20DESC)
* [11.1 Features/fixes by vote](https://jira.mariadb.org/issues/?jql=project%20%3D%20MDEV%20AND%20issuetype%20%3D%20Task%20AND%20fixVersion%20in%20(11.1)%20ORDER%20BY%20votes%20DESC%2C%20priority%20DESC)
* [What is MariaDB 11.0?](../what-is-mariadb-11-0/index)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/plans-for-mariadb-11-1/>

Install Cassandra on Fulltest VMs
=================================

    
CassandraSE is no longer actively being developed and has been removed in [MariaDB 10.6](../what-is-mariadb-106/index). See [MDEV-23024](https://jira.mariadb.org/browse/MDEV-23024).

  Here are the steps I took to install Cassandra on the Fulltest VMs.

 1. backed up the fulltest VMs with:

 
```
rsync -avP /kvm/vms/*fulltest* host:/destination/path/

```

2. boot the amd64 fulltest VM:

 
```
vm=vm-precise-amd64-fulltest.qcow2
kvm -m 2048 -hda /kvm/vms/${vm} -boot c -smp 2 -cpu qemu64 -net nic,model=virtio -net user,hostfwd=tcp:127.0.0.1:22666-:22 -nographic

```

3. login to the VM:

 
```
ssh -t -p 22666 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i /kvm/vms/ssh-keys/id_dsa dbart@localhost

```

4. in the VM, install Cassandra:

 
```
sudo vi /etc/apt/sources.list.d/cassandra.list

# paste in the following two lines:
deb http://www.apache.org/dist/cassandra/debian 11x main
deb-src http://www.apache.org/dist/cassandra/debian 11x main

gpg --keyserver pgp.mit.edu --recv-keys F758CE318D77295D
gpg --export --armor F758CE318D77295D | sudo apt-key add -

gpg --keyserver pgp.mit.edu --recv-keys 2B5C1B00
gpg --export --armor 2B5C1B00 | sudo apt-key add -

sudo apt-get update
sudo apt-get install cassandra

```

5. in the VM, launch the `cassandra-cli` program and test the Cassandra installation:

 
```
create keyspace DEMO; 
use DEMO; 

create column family Users 
with key_validation_class = 'UTF8Type' 
and comparator = 'UTF8Type' 
and default_validation_class = 'UTF8Type'; 

set Users[1234][name] = scott; 
set Users[1234][password] = tiger; 
get Users[1234]; 
quit; 

```

* Output of the above:

 
```
dbart@ubuntu-precise-amd64:~$
 cassandra-cli

Connected to: "Test Cluster" on 127.0.0.1/9160
Welcome to Cassandra CLI version 1.1.9

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

[default@unknown]
 create keyspace DEMO;

622a672f-dd03-37bf-bf78-f3e99a8f18a6
Waiting for schema agreement...
... schemas agree across the cluster
[default@unknown]
 use DEMO;

Authenticated to keyspace: DEMO
[default@DEMO]
 create column family Users

...    
 with key_validation_class = 'UTF8Type'

...    
 and comparator = 'UTF8Type'

...    
 and default_validation_class = 'UTF8Type';

605eea14-d3e5-3d1d-ab1d-f4863c814538
Waiting for schema agreement...
... schemas agree across the cluster
[default@DEMO]
 set Users[1234][name] = scott;

Value inserted.
Elapsed time: 46 msec(s).
[default@DEMO]
 set Users[1234][password] = tiger;

Value inserted.
Elapsed time: 2.77 msec(s).
[default@DEMO]
 get Users[1234];

=> (column=name, value=scott, timestamp=1361818884084000)
=> (column=password, value=tiger, timestamp=1361818887944000)
Returned 2 results.
Elapsed time: 53 msec(s).
[default@DEMO]
 quit;


```

6. in the VM, shut it down:

 
```
sudo shutdown -h now

```

7. Do steps 2-6 for `vm-precise-i386-fulltest.qcow2`. The output of the testing step was:

 
```
dbart@ubuntu-precise-i386:~$
 cassandra-cli

Connected to: "Test Cluster" on 127.0.0.1/9160
Welcome to Cassandra CLI version 1.1.9

Type 'help;' or '?' for help.
Type 'quit;' or 'exit;' to quit.

[default@unknown]
 create keyspace DEMO;

5eafc25e-71b6-3585-9db1-891b3348790c
Waiting for schema agreement...
... schemas agree across the cluster
[default@unknown]
 use DEMO;

Authenticated to keyspace: DEMO
[default@DEMO]
 create column family Users

...    
 with key_validation_class = 'UTF8Type'

...    
 and comparator = 'UTF8Type'

...    
 and default_validation_class = 'UTF8Type';

9c2ad7bc-8dc0-35ce-8067-4dc4577319f1
Waiting for schema agreement...
... schemas agree across the cluster
[default@DEMO]
 set Users[1234][name] = scott;

Value inserted.
Elapsed time: 51 msec(s).
[default@DEMO]
 set Users[1234][password] = tiger;

Value inserted.
Elapsed time: 2.44 msec(s).
[default@DEMO]
 get Users[1234];

=> (column=name, value=scott, timestamp=1361819341068000)
=> (column=password, value=tiger, timestamp=1361819345337000)
Returned 2 results.
Elapsed time: 57 msec(s).
[default@DEMO]
 quit;


```

8. on the other build hosts, rsync the files over:

 
```
rsync -avP host::kvm/vms/*fulltest* /kvm/vms/

```
    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/install-cassandra-on-fulltest-vms/>

MariaDB Developer Meeting - Athens - Friday, 11 Nov 2011
=========================================================

   Agenda and notes from day 1 of the MariaDB Developer Meeting in Athens, Greece.

 Agenda
------

 


| Time | Main Track |
| --- | --- |
| 09:00‑10:00 | Email & Hacking time (Public) |
| 10:00‑10:15 | Welcome session (Public) |
| 10:15‑11:00 | MariaDB Development Procedures (should we try to adopt more Agile techniques?) (Public) |
| 11:00‑11:15 | Small break |
| 11:15‑12:30 | MariaDB Quality (Philip) (Public) |
| 12:30‑13:30 | Lunch |
| 13:30‑15:15 | Plans for [MariaDB 5.6](../what-is-mariadb-56/index) (Public) |
| 15:15‑15:45 | Coffee break |
| 15:45‑17:00 | [MariaDB 5.6](../what-is-mariadb-56/index) Merge Planning (Public) |
| 17:00‑17:45 | [MariaDB 5.6](../what-is-mariadb-56/index) Merge Planning (Public) |

 [Printed Schedule](http://askmonty.org/blog/wp-content/uploads/2011/11/MariaDB-%CE%B5%CF%86%CE%B7%CE%BC%CE%B5%CF%81%CE%AF%CE%B4%CE%B1-11-Nov-2011.pdf) (pdf)

 
Notes
-----

  

| Title | Description |
| --- | --- |
|  [Plans for 5.6](../plans-for-56/index) |  The information on this page is obsolete. Current information can be found...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-developer-meeting-athens-friday-11-nov-2011/>

MariaDB Developer Meeting - Athens - Sunday, 13 Nov 2011
=========================================================

   Agenda and notes from day 3 of the MariaDB Developer Meeting in Athens, Greece.

 Agenda
------

 


| Time | Main Track | Side Track |
| --- | --- | --- |
| 09:00‑10:00 | Email & Hacking time (Public) |  |
| 10:00‑11:00 | Project Tracking tool discussion (Public) |  |
| 11:00‑11:15 | Small break |  |
| 11:15‑12:30 | State of SkySQL (Public) |  |
| 12:30‑13:30 | Lunch |  |
| 13:30‑14:00 | Unconference (Public) | MariaDB Benchmarking (An overview of benchmarking scripts Vlado has developed, future plans for those, etc. Show us degree of automation: we come up with a query over DBT-3 dataset and let's see if we could re-run it and get performance tables/charts.) (Public) |
| 14:00‑15:15 | Unconference (Public) | Website Consolidation and Re‑Design (Public) |
| 15:15‑15:45 | Coffee break |  |
| 15:45‑17:30 | Monty Program Company Meeting (Private) |  |

 [Printed Schedule](http://askmonty.org/blog/wp-content/uploads/2011/11/MariaDB-%CE%B5%CF%86%CE%B7%CE%BC%CE%B5%CF%81%CE%AF%CE%B4%CE%B1-13-Nov-2011.pdf) (pdf)

 
Notes
-----

  

| Title | Description |
| --- | --- |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-developer-meeting-athens-sunday-13-nov-2011/>

MariaDB Developer Meeting - Athens - Saturday, 12 Nov 2011
===========================================================

   Agenda and notes from day 2 of the MariaDB Developer Meeting in Athens, Greece.

 Agenda
------

 


| Time | Main Track | Side Track |
| --- | --- | --- |
| 09:00‑10:00 | Email & Hacking time (Public) |  |
| 10:00-11:00 | GIS in MariaDB: Current status, upcoming milestones. (Public) |  |
| 11:00‑11:15 | Small break |  |
| 11:15-12:30 | Replication in MariaDB (Public) |  |
| 12:30‑13:30 | Lunch |  |
| 13:30‑14:00 | Email and hacking time. |  |
| 14:00‑15:15 | Xentio Presentation (Public) |  |
| 15:15‑15:45 | Coffee break |  |
| 15:45-16:30 | [MariaDB 5.3](../what-is-mariadb-53/index): Technical Status (Public) |  |
| 16:30-17:30 | [MariaDB 5.5](../what-is-mariadb-55/index): Planning (features, release theme, release dates, etc...) (Public) |  |

 [Printed Schedule](http://askmonty.org/blog/wp-content/uploads/2011/11/MariaDB-%CE%B5%CF%86%CE%B7%CE%BC%CE%B5%CF%81%CE%AF%CE%B4%CE%B1-12-Nov-2011.pdf) (pdf)

 
Notes
-----

  

| Title | Description |
| --- | --- |
|  [Athens - Replication in MariaDB - notes](../athens-replication-in-mariadb-notes/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [MariaDB Replication](../standard-replication/index) |  Documentation on standard primary and replica replication.  |
|  [Athens - Xentio Presentation - notes](../athens-xentio-presentation-notes/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |
|  [Athens - MariaDB 5.3: Technical Status - notes](../athens-mariadb-53-technical-status-notes/index) |  Note: This page is obsolete. The information is old, outdated, or otherwise...  |

  Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/mariadb-developer-meeting-athens-saturday-12-nov-2011/>

Athens - MariaDB 5.3: Technical Status - notes
==============================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Pictures from this session:

 * <https://plus.google.com/b/102059736934609902389/102059736934609902389/posts/HCxA2J4gw5k>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/athens-mariadb-53-technical-status-notes/>

Athens - Xentio Presentation - notes
====================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Xentio works in the field of Business Intelligence.

 Their product is Swarm Cluster (SC)

 A Data Warehouse in the TB range costs a lot. SC can do it for a lot less.

 SC is a Shared-nothing distributed OLAP (Online Analytical Processing) server. It is optimized for running analytical workloads. It runs on clusters of commodity hardware. Apache Hadoop distributes the workload and MariaDB/MySQL powers node-local processing. It seamlessly integrates with your favorite reporting tool (anything which can process SQL or XML/A).

 Xentio's website: <http://xentio.com>

 Photos from the presentation:

 * <https://plus.google.com/b/102059736934609902389/102059736934609902389/posts/ddmfNy8KSjF>
* <https://plus.google.com/b/102059736934609902389/102059736934609902389/posts/4FdXbFyu2DF>
* <https://plus.google.com/b/102059736934609902389/102059736934609902389/posts/8mm6BNT8rfB>

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/athens-xentio-presentation-notes/>

Athens - Replication in MariaDB - notes
=======================================

    
**Note:** This page is obsolete. The information is old, outdated, or otherwise currently incorrect. We are keeping the page for historical reasons only. **Do not** rely on the information in this article.

  Overview of Replication in MariaDB: [Replication](../replication/index)

 In [MariaDB 5.3](../what-is-mariadb-53/index):
----------------------------------------------

 * Group Commit for the binary log.
	+ [Mark Callaghan from Facebook did some benchmarks:](http://www.facebook.com/note.php?note_id=10150211546215933)
	+ The Facebook patch and the implementation in [MariaDB 5.3](../what-is-mariadb-53/index) are two different solutions to the same problem. The latest Facebook patch is close to the performance in MariaDB, but MariaDB is still faster.
	+ [Benchmarking thread scheduling in group commit, part 2](http://kristiannielsen.livejournal.com/15739.html)

 * Enhancements for START TRANSACTION WITH CONSISTENT SNAPSHOT
	+ Is actually consistent now ...
	+ non-blocking slave privisioning

 * Annotation of row-based replication events with the original SQL statement
	+ A separate, but very similar, implementation is in 5.6

 * Row-based replication for tables with no primary key

 * PBXT consistent commit ordering

 * Binlog Event Checksums (backport from MySQL 5.6

 To be in [MariaDB 5.5](../what-is-mariadb-55/index)
---------------------------------------------------

 * `@@do_not_replicate`

 Additional:
-----------

 * Fixing `rpl_transaction_enabled` in case we crash and rollback during XA

 Misc:
-----

 * This preview also includes a small change to make mysqlbinlog omit redundatn use statements around BEGIN, SACEPOINT, COMMIT, and ROLLBACK events when reading MySQL 5.0 binlogs.
* The preview included a feature `--innodb-release-locks-early`. However we decided to omit this feature from future MariaDB releases because of a fundamental design bug, [Bug #798213](https://bugs.launchpad.net/bugs/798213)

    Content reproduced on this site is the property of its respective owners, and this content is not reviewed in advance by MariaDB. The views, information and opinions expressed by this content do not necessarily represent those of MariaDB or any other party.  

 © 2023 MariaDB  
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.  

<https://mariadb.com/kb/en/athens-replication-in-mariadb-notes/>

mariadb